Skip to content

Commit

Permalink
Full screen iFrame (#113)
Browse files Browse the repository at this point in the history
* full screen iframe

* adjustable position, always primary button

* changeset
  • Loading branch information
kyleawayan authored Mar 17, 2024
1 parent 9d6747a commit 45486ec
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/six-feet-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"czb-ui-storybook": minor
"@czb-ui/core": minor
---

Add FullScreenIFrame
31 changes: 31 additions & 0 deletions apps/czb-ui-storybook/src/stories/FullScreenIFrame.stories.tsx
Original file line number Diff line number Diff line change
@@ -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) => (
<div style={{ height: "100vh" }}>
<CZBUIFullScreenIFrame {...args} />
</div>
);

export const FullScreenIframe = Template.bind({});
FullScreenIframe.args = {
src: "https://onclass-dash-development.ds.czbiohub.org/onclass",
fullScreenButtonLocation: "topright",
fullScreenButtonMargin: "20px",
};
110 changes: 110 additions & 0 deletions packages/core/src/FullScreenIFrame/FullScreenIFrame.tsx
Original file line number Diff line number Diff line change
@@ -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>,
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<HTMLDivElement>(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 (
<Box ref={boxRef} width="100%" height="100%">
<Box sx={{ position: "absolute", ...buttonPosition }}>
<Button
sdsStyle="square"
sdsType="primary"
startIcon={isFullScreen ? <CloseFullscreen /> : <OpenInFull />}
onClick={handleFullScreen}
>
{isFullScreen ? "Exit Full Screen" : "Full Screen"}
</Button>
</Box>
<iframe
{...props}
style={{
border: 0,
width: "100%",
height: "100%",
backgroundColor: "white",
}}
/>
</Box>
);
};
1 change: 1 addition & 0 deletions packages/core/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export * from "./ImageButton/ImageButton";
export * from "./InfoBox/InfoBox";
export * from "./LegacyInfoBox/LegacyInfoBox";
export * from "./HeadingSeparator/HeadingSeparator";
export * from "./FullScreenIFrame/FullScreenIFrame";

export * from "./theme";

0 comments on commit 45486ec

Please sign in to comment.