Skip to content

Commit

Permalink
code review, fix the rest of the regressions
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari committed Nov 6, 2022
1 parent 061d16f commit 6e049cd
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 107 deletions.
8 changes: 4 additions & 4 deletions docs/data/material/components/app-bar/app-bar-pt.md
Expand Up @@ -36,7 +36,7 @@ Uma barra de pesquisa lateral

## Responsive App bar with Drawer

{{"demo": "DrawerAppBar.js", "bg": true,"iframe": true}}
{{"demo": "DrawerAppBar.js", "bg": true, "iframe": true, "disableLiveEdit": true}}

## App bar with a primary search field

Expand Down Expand Up @@ -103,19 +103,19 @@ You can use the `useScrollTrigger()` hook to respond to user scroll actions.

The app bar hides on scroll down to leave more space for reading.

{{"demo": "HideAppBar.js", "iframe": true}}
{{"demo": "HideAppBar.js", "iframe": true, "disableLiveEdit": true}}

### Elevate App bar

The app bar elevates on scroll to communicate that the user is not at the top of the page.

{{"demo": "ElevateAppBar.js", "iframe": true}}
{{"demo": "ElevateAppBar.js", "iframe": true, "disableLiveEdit": true}}

### Voltar ao topo

A floating action buttons appears on scroll to make it easy to get back to the top of the page.

{{"demo": "BackToTop.js", "iframe": true}}
{{"demo": "BackToTop.js", "iframe": true, "disableLiveEdit": true}}

### `useScrollTrigger([options]) => trigger`

Expand Down
8 changes: 4 additions & 4 deletions docs/data/material/components/app-bar/app-bar-zh.md
Expand Up @@ -36,7 +36,7 @@ materialDesign: https://m2.material.io/components/app-bars-top

## 带有抽屉的响应式应用栏

{{"demo": "DrawerAppBar.js", "bg": true,"iframe": true}}
{{"demo": "DrawerAppBar.js", "bg": true, "iframe": true, "disableLiveEdit": true}}

## 带有主搜索输入框的应用栏

Expand Down Expand Up @@ -103,19 +103,19 @@ function App() {

向下滚动隐藏应用栏,从而为阅读提供更多空间。

{{"demo": "HideAppBar.js", "iframe": true}}
{{"demo": "HideAppBar.js", "iframe": true, "disableLiveEdit": true}}

### 提升应用栏

应用栏会在滚动时提升,以表明用户还未到页面的顶部。

{{"demo": "ElevateAppBar.js", "iframe": true}}
{{"demo": "ElevateAppBar.js", "iframe": true, "disableLiveEdit": true}}

### 回到顶部

滚动时出现一个浮动操作按钮,以便返回页面的顶部。

{{"demo": "BackToTop.js", "iframe": true}}
{{"demo": "BackToTop.js", "iframe": true, "disableLiveEdit": true}}

### `useScrollTrigger([options]) => trigger`

Expand Down
6 changes: 3 additions & 3 deletions docs/data/material/components/app-bar/app-bar.md
Expand Up @@ -103,19 +103,19 @@ You can use the `useScrollTrigger()` hook to respond to user scroll actions.

The app bar hides on scroll down to leave more space for reading.

{{"demo": "HideAppBar.js", "iframe": true}}
{{"demo": "HideAppBar.js", "iframe": true, "disableLiveEdit": true}}

### Elevate App bar

The app bar elevates on scroll to communicate that the user is not at the top of the page.

{{"demo": "ElevateAppBar.js", "iframe": true}}
{{"demo": "ElevateAppBar.js", "iframe": true, "disableLiveEdit": true}}

### Back to top

A floating action button appears on scroll to make it easy to get back to the top of the page.

{{"demo": "BackToTop.js", "iframe": true}}
{{"demo": "BackToTop.js", "iframe": true, "disableLiveEdit": true}}

### `useScrollTrigger([options]) => trigger`

Expand Down
4 changes: 2 additions & 2 deletions docs/data/material/components/drawers/drawers-pt.md
Expand Up @@ -50,7 +50,7 @@ Você pode configurar a propriedade `SwipeableDrawer` para visualizar uma borda

Se você estiver em uma área de trabalho, poderá alternar o drawer com o botão "OPEN". Se estiver pelo celular, abra a demonstração no CodeSandbox (ícone "editar") e deslizar.

{{"demo": "SwipeableEdgeDrawer.js", "iframe": true, "height": 400, "maxWidth": 300}}
{{"demo": "SwipeableEdgeDrawer.js", "iframe": true, "disableLiveEdit": true, "height": 400, "maxWidth": 300}}

### Navegação em altura total

Expand All @@ -71,7 +71,7 @@ More details in the [Modal performance section](/material-ui/react-modal/#perfor

You can use the `temporary` variant to display a drawer for small screens and `permanent` for a drawer for wider screens.

{{"demo": "ResponsiveDrawer.js", "iframe": true}}
{{"demo": "ResponsiveDrawer.js", "iframe": true, "disableLiveEdit": true}}

## Drawer persistente

Expand Down
4 changes: 2 additions & 2 deletions docs/data/material/components/drawers/drawers-zh.md
Expand Up @@ -50,7 +50,7 @@ const iOS =

如果你使用的是桌面设备,那么可以点击 "OPEN" 按钮来切换抽屉的显示。 如果你使用的设备是手机,那么可以在 CodeSandbox(“编辑”图标)中打开该演示,并尝试滑动抽屉。

{{"demo": "SwipeableEdgeDrawer.js", "iframe": true, "height": 400, "maxWidth": 300}}
{{"demo": "SwipeableEdgeDrawer.js", "iframe": true, "disableLiveEdit": true, "height": 400, "maxWidth": 300}}

### 全高导航栏

Expand All @@ -71,7 +71,7 @@ More details in the [Modal performance section](/material-ui/react-modal/#perfor

You can use the `temporary` variant to display a drawer for small screens and `permanent` for a drawer for wider screens.

{{"demo": "ResponsiveDrawer.js", "iframe": true}}
{{"demo": "ResponsiveDrawer.js", "iframe": true, "disableLiveEdit": true}}

## 持久的抽屉

Expand Down
4 changes: 2 additions & 2 deletions docs/data/material/components/drawers/drawers.md
Expand Up @@ -57,7 +57,7 @@ You can configure the `SwipeableDrawer` to have a visible edge when closed.
If you are on a desktop, you can toggle the drawer with the "OPEN" button.
If you are on mobile, you can open the demo in CodeSandbox ("edit" icon) and swipe.

{{"demo": "SwipeableEdgeDrawer.js", "iframe": true, "height": 400, "maxWidth": 300}}
{{"demo": "SwipeableEdgeDrawer.js", "iframe": true, "disableLiveEdit": true, "height": 400, "maxWidth": 300}}

### Keep mounted

Expand All @@ -78,7 +78,7 @@ More details in the [Modal performance section](/material-ui/react-modal/#perfor

You can use the `temporary` variant to display a drawer for small screens and `permanent` for a drawer for wider screens.

{{"demo": "ResponsiveDrawer.js", "iframe": true}}
{{"demo": "ResponsiveDrawer.js", "iframe": true, "disableLiveEdit": true}}

## Persistent drawer

Expand Down
182 changes: 104 additions & 78 deletions docs/src/modules/components/Demo.js
Expand Up @@ -8,6 +8,7 @@ import { unstable_useId as useId } from '@mui/utils';
import IconButton from '@mui/material/IconButton';
import Collapse from '@mui/material/Collapse';
import NoSsr from '@mui/material/NoSsr';
import HighlightedCode from 'docs/src/modules/components/HighlightedCode';
import DemoSandbox from 'docs/src/modules/components/DemoSandbox';
import ReactRunner from 'docs/src/modules/components/ReactRunner';
import DemoEditor from 'docs/src/modules/components/DemoEditor';
Expand All @@ -28,12 +29,6 @@ function trimLeadingSpaces(input = '') {
return input.replace(/^\s+/gm, '');
}

// Used to forward props injected with cloneElement
function ForwardProps(props) {
const { children, ...forwardProps } = props;
return children(forwardProps);
}

const DemoToolbar = React.lazy(() => import('./DemoToolbar'));
// Sync with styles from DemoToolbar
// Importing the styles results in no bundle size reduction
Expand Down Expand Up @@ -99,53 +94,51 @@ function useDemoData(codeVariant, demo, githubLocation) {
}, [canonicalAs, codeVariant, demo, githubLocation, userLanguage]);
}

function useDemoElement({ demoOptions, demoData, usePreview, code, debouncedSetError }) {
function useDemoElement({
demoOptions,
demoData,
editorCode,
initialEditorCode,
setDebouncedError,
}) {
const debouncedSetError = React.useMemo(
() => debounce(setDebouncedError, 300),
[setDebouncedError],
);

React.useEffect(() => {
return () => {
debouncedSetError.clear();
};
}, [debouncedSetError]);

// Memoize to avoid rendering the demo more than it needs to be.
// For example, avoid a render when the demo is hovered.
return React.useMemo(() => {
// No need for a live environment if the toolbar is hidden.
if (demoOptions.hideToolbar) {
if (
// No need for a live environment if the code matches with the component rendered server-side.
editorCode.value === initialEditorCode ||
// A limitation from https://github.com/nihgwu/react-runner, we can inject the `window` of the iframe
demoOptions.disableLiveEdit
) {
return <demoData.Component />;
}

const codeToRun = usePreview
? trimLeadingSpaces(demoData.raw).replace(trimLeadingSpaces(demoData.jsxPreview), code)
: code;

// In production mode, it's better to hydrate the demo as soon as possible (`fallback`).
// Later on, we can accept live edits.
if (process.env.NODE_ENV === 'production') {
return (
<ForwardProps>
{(forwardProps) => (
<NoSsr fallback={<demoData.Component />}>
<ReactRunner
code={codeToRun}
scope={demoData.scope}
onError={debouncedSetError}
forwardProps={forwardProps}
/>
</NoSsr>
)}
</ForwardProps>
);
}

// In development mode, it's better to have a single render of the demos.
// It's hard to follow the console.log otherwise.
return (
<ForwardProps>
{(forwardProps) => (
<ReactRunner
code={codeToRun}
scope={demoData.scope}
onError={debouncedSetError}
forwardProps={forwardProps}
/>
)}
</ForwardProps>
<ReactRunner
scope={demoData.scope}
onError={debouncedSetError}
code={
editorCode.isPreview
? trimLeadingSpaces(demoData.raw).replace(
trimLeadingSpaces(demoData.jsxPreview),
editorCode.value,
)
: editorCode.value
}
/>
);
}, [demoOptions.hideToolbar, demoData, usePreview, code, debouncedSetError]);
}, [demoData, demoOptions.disableLiveEdit, editorCode, initialEditorCode, debouncedSetError]);
}

const Root = styled('div')(({ theme }) => ({
Expand Down Expand Up @@ -278,6 +271,13 @@ const DemoRootJoy = joyStyled('div', {
}),
}));

const DemoCodeViewer = styled(HighlightedCode)({
'& pre': {
margin: '0 auto',
maxHeight: 'min(68vh, 1000px)',
},
});

const AnchorLink = styled('div')({
marginTop: -64, // height of toolbar
position: 'absolute',
Expand Down Expand Up @@ -361,35 +361,44 @@ export default function Demo(props) {
const [showAd, setShowAd] = React.useState(false);
const adVisibility = showAd && !disableAd && !demoOptions.disableAd;

const usePreview = showPreview && !codeOpen;
const initialCode = usePreview ? demoData.jsxPreview : demoData.raw;
const [code, setCode] = React.useState(initialCode);
const DemoRoot = demoData.product === 'joy-ui' ? DemoRootJoy : DemoRootMaterial;
const Wrapper = demoData.product === 'joy-ui' ? BrandingProvider : React.Fragment;

const isPreview = !codeOpen && showPreview;
const initialEditorCode = isPreview
? demoData.jsxPreview
: // Prettier remove all the leading lines except for the last one, remove it as we don't
// need it in the live edit view.
demoData.raw.replace(/\n$/, '');

const [editorCode, setEditorCode] = React.useState({
value: initialEditorCode,
isPreview,
});

const resetDemo = () => {
setCode(initialCode);
setEditorCode({
value: initialEditorCode,
isPreview,
});
setDemoKey();
};

React.useEffect(() => {
setCode(initialCode);
}, [initialCode]);
setEditorCode({
value: initialEditorCode,
isPreview,
});
}, [initialEditorCode, isPreview]);

const [debouncedError, setError] = React.useState(null);
const debouncedSetError = React.useMemo(() => debounce(setError, 300), []);
React.useEffect(() => {
return () => {
debouncedSetError.clear();
};
}, [debouncedSetError]);

const DemoRoot = demoData.product === 'joy-ui' ? DemoRootJoy : DemoRootMaterial;
const Wrapper = demoData.product === 'joy-ui' ? BrandingProvider : React.Fragment;
const [debouncedError, setDebouncedError] = React.useState(null);

const demoElement = useDemoElement({
demoOptions,
demoData,
usePreview,
code,
debouncedSetError,
editorCode,
initialEditorCode,
setDebouncedError,
});

return (
Expand Down Expand Up @@ -448,20 +457,37 @@ export default function Demo(props) {
</NoSsr>
)}
<Collapse in={openDemoSource} unmountOnExit>
<DemoEditor
key={demoKey}
id={demoSourceId}
value={code}
onChange={setCode}
language={demoData.sourceLanguage}
copyButtonProps={{
'data-ga-event-category': codeOpen ? 'demo-expand' : 'demo',
'data-ga-event-label': demoOptions.demo,
'data-ga-event-action': 'copy-click',
}}
>
{debouncedError ? <DemoEditorError>{debouncedError}</DemoEditorError> : null}
</DemoEditor>
{demoOptions.disableLiveEdit ? (
<DemoCodeViewer
code={editorCode.value}
id={demoSourceId}
language={demoData.sourceLanguage}
copyButtonProps={{
'data-ga-event-category': codeOpen ? 'demo-expand' : 'demo',
'data-ga-event-label': demoOptions.demo,
'data-ga-event-action': 'copy-click',
}}
/>
) : (
<DemoEditor
value={editorCode.value}
onChange={(value) => {
setEditorCode({
...editorCode,
value,
});
}}
id={demoSourceId}
language={demoData.sourceLanguage}
copyButtonProps={{
'data-ga-event-category': codeOpen ? 'demo-expand' : 'demo',
'data-ga-event-label': demoOptions.demo,
'data-ga-event-action': 'copy-click',
}}
>
<DemoEditorError>{debouncedError}</DemoEditorError>
</DemoEditor>
)}
</Collapse>
{adVisibility ? <AdCarbonInline /> : null}
</Wrapper>
Expand Down

0 comments on commit 6e049cd

Please sign in to comment.