From 45486ec16794f8ec7b0a5b077331029cd6878032 Mon Sep 17 00:00:00 2001 From: Kyle Awayan Date: Sat, 16 Mar 2024 23:23:08 -0700 Subject: [PATCH] Full screen iFrame (#113) * full screen iframe * adjustable position, always primary button * changeset --- .changeset/six-feet-sleep.md | 6 + .../src/stories/FullScreenIFrame.stories.tsx | 31 +++++ .../src/FullScreenIFrame/FullScreenIFrame.tsx | 110 ++++++++++++++++++ packages/core/src/index.tsx | 1 + 4 files changed, 148 insertions(+) create mode 100644 .changeset/six-feet-sleep.md create mode 100644 apps/czb-ui-storybook/src/stories/FullScreenIFrame.stories.tsx create mode 100644 packages/core/src/FullScreenIFrame/FullScreenIFrame.tsx diff --git a/.changeset/six-feet-sleep.md b/.changeset/six-feet-sleep.md new file mode 100644 index 00000000..106b8b90 --- /dev/null +++ b/.changeset/six-feet-sleep.md @@ -0,0 +1,6 @@ +--- +"czb-ui-storybook": minor +"@czb-ui/core": minor +--- + +Add FullScreenIFrame diff --git a/apps/czb-ui-storybook/src/stories/FullScreenIFrame.stories.tsx b/apps/czb-ui-storybook/src/stories/FullScreenIFrame.stories.tsx new file mode 100644 index 00000000..94e2f579 --- /dev/null +++ b/apps/czb-ui-storybook/src/stories/FullScreenIFrame.stories.tsx @@ -0,0 +1,31 @@ +import { + FullScreenIFrame as CZBUIFullScreenIFrame, + FullScreenIFrameProps, +} from "@czb-ui/core"; + +export default { + title: "Full Screen Iframe", + component: CZBUIFullScreenIFrame, + parameters: { + layout: "fullscreen", + }, + argTypes: { + fullScreenButtonLocation: { + options: ["topleft", "topright", "bottomleft", "bottomright"], + control: { type: "radio" }, + }, + }, +}; + +const Template = (args: FullScreenIFrameProps) => ( +
+ +
+); + +export const FullScreenIframe = Template.bind({}); +FullScreenIframe.args = { + src: "https://onclass-dash-development.ds.czbiohub.org/onclass", + fullScreenButtonLocation: "topright", + fullScreenButtonMargin: "20px", +}; diff --git a/packages/core/src/FullScreenIFrame/FullScreenIFrame.tsx b/packages/core/src/FullScreenIFrame/FullScreenIFrame.tsx new file mode 100644 index 00000000..52f0419c --- /dev/null +++ b/packages/core/src/FullScreenIFrame/FullScreenIFrame.tsx @@ -0,0 +1,110 @@ +import { Box } from "@mui/material"; +import { OpenInFull, CloseFullscreen } from "@mui/icons-material"; +import { Button } from "czifui"; +import React, { useRef, useState, useEffect } from "react"; + +export interface FullScreenIFrameProps + extends Omit< + React.DetailedHTMLProps< + React.IframeHTMLAttributes, + HTMLIFrameElement + >, + "width" | "height" | "style" + > { + fullScreenButton?: boolean; + fullScreenButtonLocation?: + | "topleft" + | "topright" + | "bottomleft" + | "bottomright"; + fullScreenButtonMargin?: string | number; +} + +export const FullScreenIFrame = ({ + fullScreenButtonLocation = "topright", + fullScreenButtonMargin = "10px", + ...props +}: FullScreenIFrameProps) => { + const boxRef = useRef(null); + const [isFullScreen, setIsFullScreen] = useState(false); + + const handleFullScreen = () => { + if (boxRef.current) { + if (!isFullScreen) { + if (boxRef.current.requestFullscreen) { + boxRef.current.requestFullscreen(); + } else if ((boxRef.current as any).mozRequestFullScreen) { + /* Firefox */ + (boxRef.current as any).mozRequestFullScreen(); + } else if ((boxRef.current as any).webkitRequestFullscreen) { + /* Chrome, Safari and Opera */ + (boxRef.current as any).webkitRequestFullscreen(); + } else if ((boxRef.current as any).msRequestFullscreen) { + /* IE/Edge */ + (boxRef.current as any).msRequestFullscreen(); + } + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if ((document as any).mozCancelFullScreen) { + /* Firefox */ + (document as any).mozCancelFullScreen(); + } else if ((document as any).webkitExitFullscreen) { + /* Chrome, Safari and Opera */ + (document as any).webkitExitFullscreen(); + } else if ((document as any).msExitFullscreen) { + /* IE/Edge */ + (document as any).msExitFullscreen(); + } + } + } + }; + + useEffect(() => { + const changeHandler = () => { + setIsFullScreen(!!document.fullscreenElement); + }; + + document.addEventListener("fullscreenchange", changeHandler); + return () => { + document.removeEventListener("fullscreenchange", changeHandler); + }; + }, []); + + const buttonPosition = { + topleft: { top: fullScreenButtonMargin, left: fullScreenButtonMargin }, + topright: { top: fullScreenButtonMargin, right: fullScreenButtonMargin }, + bottomleft: { + bottom: fullScreenButtonMargin, + left: fullScreenButtonMargin, + }, + bottomright: { + bottom: fullScreenButtonMargin, + right: fullScreenButtonMargin, + }, + }[fullScreenButtonLocation]; + + return ( + + + + +