Encapsulate styleguide styles

Summary: Prevent leaking Flipper styles and antd styles into the website by embedding the styleguide into an iframe.

Reviewed By: nikoant

Differential Revision: D34522771

fbshipit-source-id: a05bf1e7f54fe172fb012a0a02296b3a4e0100f1
This commit is contained in:
Andrey Goncharov
2022-02-28 09:54:03 -08:00
committed by Facebook GitHub Bot
parent 8ee788239b
commit e26ba0d945
4 changed files with 72 additions and 9 deletions

View File

@@ -0,0 +1,23 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React, {useState, useEffect} from 'react';
import {createPortal} from 'react-dom';
// https://stackoverflow.com/a/34744946
export const IFrame = ({children, ...props}) => {
const [contentRef, setContentRef] = useState(null);
const mountNode = contentRef?.contentWindow?.document?.body;
return (
<iframe {...props} ref={setContentRef}>
{mountNode && createPortal(children, mountNode)}
</iframe>
);
};

View File

@@ -7,7 +7,7 @@
* @format
*/
import React from 'react';
import React, {useState, useLayoutEffect} from 'react';
import {
Typography,
Button,
@@ -32,9 +32,7 @@ import {
} from 'flipper-plugin';
import {css} from '@emotion/css';
import reactElementToJSXString from 'react-element-to-jsx-string';
import '../../flipper-themes/flipper-theme.css';
import 'antd/dist/antd.css';
import {IFrame} from './IFrame';
const {Title, Text, Link} = Typography;
@@ -551,9 +549,30 @@ const DesignComponentDemos = () => (
</Layout.Container>
);
export default function SandyDesignSystem() {
function SandyDesignSystem() {
const [root, setRoot] = useState(null);
useLayoutEffect(() => {
if (root) {
const iframe = window.parent.document.getElementById('styleguide');
iframe.style.height = `${root.scrollHeight}px`;
const observer = new MutationObserver(() => {
iframe.style.height = `${root.scrollHeight}px`;
});
observer.observe(root, {
subtree: true,
childList: true,
attributes: true,
characterData: true,
});
return () => observer.disconnect();
}
}, [root]);
return (
<Layout.Container className={reset} gap="large">
<Layout.Container className={reset} gap="large" ref={setRoot}>
<Card title="Flipper Design System" bordered={false}>
<p>
Welcome to the Flipper Design System. The Flipper design system is
@@ -674,6 +693,16 @@ export default function SandyDesignSystem() {
);
}
export default function DesignSystemFramed() {
return (
<IFrame className={iframe} id="styleguide">
<link rel="stylesheet" href="/css/style-guide.css" />
<style>{innerCss}</style>
<SandyDesignSystem />
</IFrame>
);
}
function ColorPreview({name}) {
return (
<List.Item>
@@ -707,3 +736,13 @@ const reset = css`
background: transparent;
}
`;
const iframe = css`
width: 100%;
`;
const innerCss = `
body {
overflow: hidden;
}
`;