Fix style guide generation

Summary:
The website generation fails on newer versions of `flipper-plugin` as it contains an import-time side effect. This leads to this error during build time:

```
[ERROR] Docusaurus server-side rendering could not render static page with path /docs/extending/style-guide/.
[INFO] It looks like you are using code that should run on the client-side only.
To get around it, try using `<BrowserOnly>` (https://docusaurus.io/docs/docusaurus-core/#browseronly) or `ExecutionEnvironment` (https://docusaurus.io/doc
s/docusaurus-core/#executionenvironment).
It might also require to wrap your client code in `useEffect` hook and/or import a third-party library dynamically (if any).
```

This ain't pretty but by wrapping the entire file in a single function that conditionally imports the `flipper-plugin` if we are indeed in a browser environment fixes the problem.

Reviewed By: antonk52

Differential Revision: D43773298

fbshipit-source-id: 8e1099249626ca9fe745ce51014491fe9674a5a4
This commit is contained in:
Pascal Hartig
2023-03-03 11:04:13 -08:00
committed by Facebook GitHub Bot
parent a46b7c2e78
commit 13f9fa64ff

View File

@@ -20,7 +20,22 @@ import {
Table,
} from 'antd';
import {CodeOutlined} from '@ant-design/icons';
import {
import {css} from '@emotion/css';
import reactElementToJSXString from 'react-element-to-jsx-string';
import {IFrame} from './IFrame';
import useBaseUrl from '@docusaurus/useBaseUrl';
import useIsBrowser from '@docusaurus/useIsBrowser';
const {Title, Text, Link} = Typography;
export default function StyleGuide() {
// We need a browser environment to access the window object and import flipper-plugin.
const isBrowser = useIsBrowser();
if (!isBrowser) {
return <>The Style Guide is only available in a browser environment.</>;
}
const {
Layout,
NUX,
Panel,
@@ -29,13 +44,7 @@ import {
TrackingScope,
Tabs,
Tab,
} from 'flipper-plugin';
import {css} from '@emotion/css';
import reactElementToJSXString from 'react-element-to-jsx-string';
import {IFrame} from './IFrame';
import useBaseUrl from '@docusaurus/useBaseUrl';
const {Title, Text, Link} = Typography;
} = require('flipper-plugin');
const demoStyle = {
square: {
@@ -54,7 +63,9 @@ const largeChild = (
</div>
);
const aButton = <Button>A button</Button>;
const aBox = <div style={{...demoStyle.square, width: 100}}>A fixed child</div>;
const aBox = (
<div style={{...demoStyle.square, width: 100}}>A fixed child</div>
);
const aFixedWidthBox = (
<div style={{background: theme.primaryColor, width: 150, color: 'white'}}>
Fixed width box
@@ -67,8 +78,7 @@ const aFixedHeightBox = (
height: 40,
lineHeight: '40px',
color: 'white',
}}
>
}}>
Fixed height box
</div>
);
@@ -125,16 +135,14 @@ const demos = [
style={{
height: 50,
background: theme.successColor,
}}
></Layout.Container>
}}></Layout.Container>
),
'bordered pad rounded': (
<Layout.Container
bordered
pad
rounded
style={{background: theme.backgroundDefault, width: 200}}
>
style={{background: theme.backgroundDefault, width: 200}}>
<div style={demoStyle.square}>child</div>
</Layout.Container>
),
@@ -215,8 +223,7 @@ const demos = [
height: 100,
width: 100,
border: `2px solid ${theme.primaryColor}`,
}}
>
}}>
<Layout.Container>
<Text ellipsis>
This text is truncated because it is too long and scroll is
@@ -351,8 +358,7 @@ const demos = [
title="Panel 3 (not collapsible, pad, gap)"
collapsible={false}
pad
gap
>
gap>
{aFixedHeightBox}
{aFixedHeightBox}
</Panel>
@@ -460,7 +466,11 @@ const demos = [
description:
'Describes more precisely the place in the UI for all underlying Tracked elements. Multiple Tracking scopes are automatically nested. Use the `withTrackingScope` HoC to automatically wrap a component definition in a tracking scope',
props: [
['scope', 'string', 'The name of the scope. For example "Login Dialog"'],
[
'scope',
'string',
'The name of the scope. For example "Login Dialog"',
],
],
demos: {
'Basic example': (
@@ -490,8 +500,7 @@ function ComponentPreview({title, demos, description, props}) {
style={{
background: theme.backgroundWash,
width: '100%',
}}
>
}}>
{children}
</div>
</Tab>
@@ -501,8 +510,7 @@ function ComponentPreview({title, demos, description, props}) {
background: theme.backgroundWash,
width: '100%',
padding: theme.space.medium,
}}
>
}}>
<pre>{reactElementToJSXString(children)}</pre>
</div>
</Tab>
@@ -556,7 +564,14 @@ function SandyDesignSystem() {
// Whenever layout happens, or if the size of root changes, measure it and send a message to the parent frame.
useLayoutEffect(() => {
if (root.current) {
const sendUpdate = () => window.postMessage({name: 'setStyleGuideHeight', value: `${root.current.scrollHeight}px`}, '*');
const sendUpdate = () =>
window.postMessage(
{
name: 'setStyleGuideHeight',
value: `${root.current.scrollHeight}px`,
},
'*',
);
const observer = new ResizeObserver(() => {
sendUpdate();
});
@@ -574,9 +589,11 @@ function SandyDesignSystem() {
<p>
Welcome to the Flipper Design System. The Flipper design system is
based on{' '}
<Link href="https://ant.design/components/overview/">Ant Design</Link>
. Any component found in the ANT documentation can be used. This page
demonstrates the usage of:
<Link href="https://ant.design/components/overview/">
Ant Design
</Link>
. Any component found in the ANT documentation can be used. This
page demonstrates the usage of:
</p>
<ul>
<li>Colors</li>
@@ -606,17 +623,17 @@ function SandyDesignSystem() {
<li>
In general, components that have a <code>grow</code> property will
grow to use the full height of their <em>parents</em> if{' '}
<code>true</code>. In contrast, if grow is set to <code>false</code>{' '}
components will use their natural size, based on their{' '}
<em>children</em>.
<code>true</code>. In contrast, if grow is set to{' '}
<code>false</code> components will use their natural size, based
on their <em>children</em>.
</li>
<li>
The other important property here is <em>scrollable</em>. If an
element supports this property, setting it will imply{' '}
<code>grow</code>, and the element will show a scrollbar if needed.
Setting <code>scrollabe</code> to <code>false</code> causes the
element to always use its natural size, growing or shrinking based
on the contents rather than the parent.
<code>grow</code>, and the element will show a scrollbar if
needed. Setting <code>scrollabe</code> to <code>false</code>{' '}
causes the element to always use its natural size, growing or
shrinking based on the contents rather than the parent.
</li>
</ul>
</Card>
@@ -644,8 +661,8 @@ function SandyDesignSystem() {
<>
Common Ant components, with modifiers applied. The{' '}
<code>Title</code>, <code>Text</code> and <code>Link</code>{' '}
components can be found by importing the <code>Typography</code>{' '}
namespace from Ant.
components can be found by importing the{' '}
<code>Typography</code> namespace from Ant.
</>
}
type="info"
@@ -690,27 +707,6 @@ function SandyDesignSystem() {
);
}
export default function DesignSystemFramed() {
// We're displaying the style guide in an iframe to isolate it's styles.
// But we don't know how big it is, so don't know how high to make the iframe to avoid a double scroll bar.
// So lets get the js inside the frame measure itself and post a message to this frame, where we'll then
// adjust the size of the iframe to match.
useEffect(() => {
window.addEventListener("message", (event) => {
if (event.data.name === 'setStyleGuideHeight') {
document.getElementById('styleguide').style.height = event.data.value;
}
})
}, [])
return (
<IFrame className={iframe} id="styleguide">
<link id="styleguidestylesheet" rel="stylesheet" href={useBaseUrl("/css/style-guide.css")} />
<style>{innerCss}</style>
<SandyDesignSystem />
</IFrame>
);
}
function ColorPreview({name}) {
return (
<List.Item>
@@ -754,3 +750,27 @@ const innerCss = `
overflow: hidden;
}
`;
// We're displaying the style guide in an iframe to isolate it's styles.
// But we don't know how big it is, so don't know how high to make the iframe to avoid a double scroll bar.
// So lets get the js inside the frame measure itself and post a message to this frame, where we'll then
// adjust the size of the iframe to match.
useEffect(() => {
window.addEventListener('message', event => {
if (event.data.name === 'setStyleGuideHeight') {
document.getElementById('styleguide').style.height = event.data.value;
}
});
}, []);
return (
<IFrame className={iframe} id="styleguide">
<link
id="styleguidestylesheet"
rel="stylesheet"
href={useBaseUrl('/css/style-guide.css')}
/>
<style>{innerCss}</style>
<SandyDesignSystem />
</IFrame>
);
}