From 5946bd911a0188348afbdc83ee5760f74d573e97 Mon Sep 17 00:00:00 2001 From: Mikkel Laursen Date: Fri, 26 Nov 2021 11:00:56 -0700 Subject: [PATCH] chore(website): Fixes for Concurrent Rendering --- .../DemoSandbox/CodePreview.module.scss | 7 +--- .../components/DemoSandbox/CodePreview.tsx | 7 ++-- .../DemoSandbox/LoadingCode.module.scss | 17 ++++++++ .../components/DemoSandbox/LoadingCode.tsx | 21 ++++++++++ .../src/components/DemoSandbox/useSandbox.ts | 31 ++++++--------- .../Demos/Alert/UpdatingMessagePriority.tsx | 8 ++-- .../Demos/Chip/ActionChips/Blinds.tsx | 10 +++-- .../Demos/Form/FileInputs/ErrorModal.tsx | 20 +++++----- .../Form/SelectFields/NativeSelectExample.tsx | 14 ++++--- .../Demos/Form/Sliders/ColorSlider.tsx | 22 ++++++----- .../Demos/Form/TextFieldThemeConfig.tsx | 39 ++++++++++++------- .../Demos/Form/TextFields/TextAreaExample.tsx | 12 +++--- .../components/Demos/Menu/MenuPositioning.tsx | 10 +++-- .../components/Demos/Sheet/SheetSizing.tsx | 10 +++-- .../ConfigurableTabs/useConfiguration.tsx | 10 +++-- 15 files changed, 146 insertions(+), 92 deletions(-) create mode 100644 packages/documentation/src/components/DemoSandbox/LoadingCode.module.scss create mode 100644 packages/documentation/src/components/DemoSandbox/LoadingCode.tsx diff --git a/packages/documentation/src/components/DemoSandbox/CodePreview.module.scss b/packages/documentation/src/components/DemoSandbox/CodePreview.module.scss index c7715398b5..7391b00f25 100644 --- a/packages/documentation/src/components/DemoSandbox/CodePreview.module.scss +++ b/packages/documentation/src/components/DemoSandbox/CodePreview.module.scss @@ -16,10 +16,5 @@ } .offset { - @include rmd-sheet-theme(margin-left, static-width); - @include rmd-utils-rtl { - @include rmd-sheet-theme(margin-right, static-width); - - margin-left: auto; - } + @include rmd-utils-rtl-auto(margin-left, rmd-sheet-theme-var(static-width)); } diff --git a/packages/documentation/src/components/DemoSandbox/CodePreview.tsx b/packages/documentation/src/components/DemoSandbox/CodePreview.tsx index 5184296216..4596d748ad 100644 --- a/packages/documentation/src/components/DemoSandbox/CodePreview.tsx +++ b/packages/documentation/src/components/DemoSandbox/CodePreview.tsx @@ -1,13 +1,12 @@ import { ReactElement, useEffect, useRef } from "react"; import cn from "classnames"; import { IFiles } from "codesandbox-import-utils/lib/api/define"; -import { CircularProgress } from "@react-md/progress"; import CodeBlock from "components/CodeBlock"; -import FileNotFound from "./FileNotFound"; - import styles from "./CodePreview.module.scss"; +import FileNotFound from "./FileNotFound"; +import { LoadingCode } from "./LoadingCode"; export interface CodePreviewProps { loading: boolean; @@ -49,7 +48,7 @@ export default function CodePreview({ }, [content]); if (loading) { - return ; + return ; } if (!content) { diff --git a/packages/documentation/src/components/DemoSandbox/LoadingCode.module.scss b/packages/documentation/src/components/DemoSandbox/LoadingCode.module.scss new file mode 100644 index 0000000000..d56e453c19 --- /dev/null +++ b/packages/documentation/src/components/DemoSandbox/LoadingCode.module.scss @@ -0,0 +1,17 @@ +@use 'react-md' as *; + +.container { + @include rmd-app-bar-theme(top, prominent-dense-height); + + align-items: center; + bottom: 0; + display: flex; + left: 0; + position: fixed; + right: 0; + z-index: 1; +} + +.offset { + @include rmd-utils-rtl-auto(left, rmd-sheet-theme-var(static-width)); +} diff --git a/packages/documentation/src/components/DemoSandbox/LoadingCode.tsx b/packages/documentation/src/components/DemoSandbox/LoadingCode.tsx new file mode 100644 index 0000000000..621980ddbc --- /dev/null +++ b/packages/documentation/src/components/DemoSandbox/LoadingCode.tsx @@ -0,0 +1,21 @@ +import type { ReactElement } from "react"; +import cn from "classnames"; +import { CircularProgress } from "@react-md/progress"; + +import styles from "./LoadingCode.module.scss"; + +export interface LoadingCodeProps { + offset: boolean; +} + +export function LoadingCode({ offset }: LoadingCodeProps): ReactElement { + return ( +
+ +
+ ); +} diff --git a/packages/documentation/src/components/DemoSandbox/useSandbox.ts b/packages/documentation/src/components/DemoSandbox/useSandbox.ts index c7bb289136..48008d566a 100644 --- a/packages/documentation/src/components/DemoSandbox/useSandbox.ts +++ b/packages/documentation/src/components/DemoSandbox/useSandbox.ts @@ -1,5 +1,4 @@ import { useEffect, useState, useRef } from "react"; -import { useToggle } from "@react-md/utils"; import { IFiles } from "codesandbox-import-utils/lib/api/define"; import { ThemeMode } from "components/Theme"; import { getSandboxByQuery } from "utils/getSandbox"; @@ -21,43 +20,37 @@ export default function useSandbox( { js, pkg, name, theme, pathname }: SandboxQuery ): ReturnValue { const [sandbox, setSandbox] = useState(defaultSandbox); - const [loading, startLoading, stopLoading] = useToggle(!sandbox); + const [isLoading, setLoading] = useState(!sandbox); const prevJs = useRef(js); - if (prevJs.current !== js) { - prevJs.current = js; - startLoading(); - } + const loading = isLoading || prevJs.current !== js; useEffect(() => { - if (defaultSandbox && !loading) { + if (prevJs.current === js) { return; } + prevJs.current = js; if (!pkg || !name || !pathname.startsWith("/sandbox")) { - stopLoading(); - if (sandbox) { - setSandbox(null); - } + setSandbox(null); + setLoading(false); return; } let cancelled = false; - (async function load() { - startLoading(); + setLoading(true); + async function load(): Promise { const sandbox = await getSandboxByQuery({ js, pkg, name, theme }); if (!cancelled) { + setLoading(false); setSandbox(sandbox); - stopLoading(); } - })(); + } + load(); return () => { cancelled = true; - stopLoading(); }; - // only want to run when these dependencies change - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [pkg, name, pathname, js, theme]); + }, [js, pkg, name, theme, pathname]); return { sandbox, loading }; } diff --git a/packages/documentation/src/components/Demos/Alert/UpdatingMessagePriority.tsx b/packages/documentation/src/components/Demos/Alert/UpdatingMessagePriority.tsx index 16f8066d1d..e18209e16b 100644 --- a/packages/documentation/src/components/Demos/Alert/UpdatingMessagePriority.tsx +++ b/packages/documentation/src/components/Demos/Alert/UpdatingMessagePriority.tsx @@ -25,9 +25,11 @@ function UpdatingMessagePriority(): ReactElement { const queue = useQueue(); const [running, setRunning] = useState(false); - if (running && !queue.length) { - setRunning(false); - } + useEffect(() => { + if (running && !queue.length) { + setRunning(false); + } + }, [running, queue]); const exampleNextFlow = useCallback(() => { addMessage({ diff --git a/packages/documentation/src/components/Demos/Chip/ActionChips/Blinds.tsx b/packages/documentation/src/components/Demos/Chip/ActionChips/Blinds.tsx index 37ae5947dc..c50f4024bb 100644 --- a/packages/documentation/src/components/Demos/Chip/ActionChips/Blinds.tsx +++ b/packages/documentation/src/components/Demos/Chip/ActionChips/Blinds.tsx @@ -1,4 +1,4 @@ -import { ReactElement, useState } from "react"; +import { ReactElement, useEffect, useState } from "react"; import cn from "classnames"; import { CSSTransitionClassNames, @@ -21,9 +21,11 @@ const CLASSNAMES: CSSTransitionClassNames = { export default function Blinds({ visible }: BlindsProps): ReactElement | null { const [exited, setExited] = useState(true); - if (visible && exited) { - setExited(false); - } + useEffect(() => { + if (visible && exited) { + setExited(false); + } + }, [visible, exited]); const hide = (): void => setExited(true); diff --git a/packages/documentation/src/components/Demos/Form/FileInputs/ErrorModal.tsx b/packages/documentation/src/components/Demos/Form/FileInputs/ErrorModal.tsx index 21fed9d569..11c2c53599 100644 --- a/packages/documentation/src/components/Demos/Form/FileInputs/ErrorModal.tsx +++ b/packages/documentation/src/components/Demos/Form/FileInputs/ErrorModal.tsx @@ -1,4 +1,4 @@ -import { ReactElement, useRef, useState } from "react"; +import { ReactElement, useEffect, useState } from "react"; import { Button } from "@react-md/button"; import { Dialog, @@ -20,17 +20,15 @@ export default function ErrorModal({ errors, clearErrors, }: ErrorModalProps): ReactElement { + // Having the visibility being derived on the `errors.length > 0` would make + // it so the errors are cleared during the exit animation. To fix this, keep a + // separate `visible` state and set it to `true` whenever a new error is + // added. When the modal is closed, set the `visible` state to false and wait + // until the modal has closed before clearing the errors. const [visible, setVisible] = useState(false); - const prevErrors = useRef(errors); - - // why? - // makes it so the errors don't disappear during the exit animation - if (errors !== prevErrors.current) { - prevErrors.current = errors; - if (!visible && errors.length) { - setVisible(true); - } - } + useEffect(() => { + setVisible(errors.length > 0); + }, [errors]); const onRequestClose = (): void => { setVisible(false); diff --git a/packages/documentation/src/components/Demos/Form/SelectFields/NativeSelectExample.tsx b/packages/documentation/src/components/Demos/Form/SelectFields/NativeSelectExample.tsx index d2c8d8ed22..473a5b2f2b 100644 --- a/packages/documentation/src/components/Demos/Form/SelectFields/NativeSelectExample.tsx +++ b/packages/documentation/src/components/Demos/Form/SelectFields/NativeSelectExample.tsx @@ -1,4 +1,4 @@ -import { ReactElement } from "react"; +import { ReactElement, useEffect } from "react"; import { Checkbox, Fieldset, @@ -50,9 +50,11 @@ export default function NativeSelectExample(): ReactElement { const [size, handleSizeChange] = useChoice("4"); const [multiple, handleMultipleChange] = useChecked(false); const [optgroup, handleOptgroupChange] = useChecked(false); - if (multiple && icon) { - setIcon(false); - } + useEffect(() => { + if (multiple && icon) { + setIcon(false); + } + }, [multiple, icon, setIcon]); return ( {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */} {label &&