Skip to content
This repository has been archived by the owner on Sep 26, 2024. It is now read-only.

Commit

Permalink
fix moc 90 (#97)
Browse files Browse the repository at this point in the history
* only apply our styles to the shadowdom

* add iframewrapper

* apply iframe only to PopUp children
  • Loading branch information
elg0nz authored Jul 23, 2024
1 parent 6ae20aa commit d38e4ad
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 2 deletions.
11 changes: 9 additions & 2 deletions apps/mocksi-lite/common/Popup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useState } from "react";
import Draggable, { type DraggableEventHandler } from "react-draggable";
import { MOCKSI_POPUP_LOCATION } from "../../consts";
import IframeWrapper from "../../content/IframeWrapper";
import Divider from "../Divider";
import Footer from "./Footer";
import Header from "./Header";
Expand Down Expand Up @@ -59,6 +60,13 @@ const Popup = ({
}, []);

const isFooterVisible = shouldDisplayFooter && email && onLogout && onChat;
const iframeStyle = {
position: "absolute", // Fixed positioning relative to the viewport
top: "100px",
width: "100%",
height: "100%",
zIndex: 9999999,
};

return (
<Draggable handle=".drag-handle" position={position} onStop={onDragStop}>
Expand All @@ -69,8 +77,7 @@ const Popup = ({
onSettings={onSettings}
onGoBack={onGoBack}
/>

{children}
<IframeWrapper style={iframeStyle}>{children}</IframeWrapper>

{/* FOOTER */}
{isFooterVisible && (
Expand Down
90 changes: 90 additions & 0 deletions apps/mocksi-lite/content/IframeWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// biome-ignore lint/style/useImportType: types are messy
import { ReactNode, useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";

interface IframeWrapperProps {
children: ReactNode;
styles?: string;
scripts?: string[];
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
[x: string]: any;
}

const extractStyles = (): string => {
let styles = "";
const styleSheets = Array.from(document.styleSheets) as CSSStyleSheet[];

for (const sheet of styleSheets) {
try {
if (sheet.cssRules) {
const cssRules = Array.from(sheet.cssRules) as CSSRule[];
for (const rule of cssRules) {
styles += rule.cssText;
}
}
} catch (e) {
console.error("Error accessing stylesheet:", e);
}
}

return styles;
};

const IframeWrapper = ({
children,
styles,
scripts,
...props
}: IframeWrapperProps) => {
const iframeRef = useRef<HTMLIFrameElement>(null); // Explicitly type the ref
const [iframeBody, setIframeBody] = useState<HTMLElement | null>(null);

useEffect(() => {
const iframe = iframeRef.current;
if (!iframe) {
console.error("Iframe is null");
return;
}
const iframeDocument = iframe.contentWindow?.document;
if (!iframeDocument) {
console.error("Iframe document is null");
return;
}

let baseStyles = extractStyles();
// Append component styles
if (styles) {
baseStyles += styles;
}
const styleElement = iframeDocument.createElement("style");
if (styleElement && baseStyles) {
styleElement.textContent = baseStyles;
iframeDocument.head.appendChild(styleElement);
}

// Inject scripts
if (scripts) {
for (const script of scripts) {
const scriptElement = iframeDocument.createElement("script");
scriptElement.src = script;
iframeDocument.head.appendChild(scriptElement);
}
}

if (iframeDocument.body) {
iframeDocument.body.style.setProperty(
"background-color",
"rgba(0, 0, 0, 0.0)",
);
setIframeBody(iframeDocument.body);
}
}, [styles, scripts]);

return (
<iframe ref={iframeRef} {...props} allowFullScreen>
{iframeBody && ReactDOM.createPortal(children, iframeBody)}
</iframe>
);
};

export default IframeWrapper;

0 comments on commit d38e4ad

Please sign in to comment.