Skip to content

Commit

Permalink
chore(website): Fixes for Concurrent Rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
mlaursen committed Nov 27, 2021
1 parent ba96bb6 commit 5946bd9
Show file tree
Hide file tree
Showing 15 changed files with 146 additions and 92 deletions.
Expand Up @@ -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));
}
@@ -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;
Expand Down Expand Up @@ -49,7 +48,7 @@ export default function CodePreview({
}, [content]);

if (loading) {
return <CircularProgress id="loading-code" />;
return <LoadingCode offset={offset} />;
}

if (!content) {
Expand Down
@@ -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));
}
21 changes: 21 additions & 0 deletions 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 (
<div
className={cn(styles.container, {
[styles.offset]: offset,
})}
>
<CircularProgress id="loading-code" />
</div>
);
}
31 changes: 12 additions & 19 deletions 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";
Expand All @@ -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<void> {
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 };
}
Expand Up @@ -25,9 +25,11 @@ function UpdatingMessagePriority(): ReactElement {
const queue = useQueue<ExampleMessage>();
const [running, setRunning] = useState(false);

if (running && !queue.length) {
setRunning(false);
}
useEffect(() => {
if (running && !queue.length) {
setRunning(false);
}
}, [running, queue]);

const exampleNextFlow = useCallback(() => {
addMessage({
Expand Down
@@ -1,4 +1,4 @@
import { ReactElement, useState } from "react";
import { ReactElement, useEffect, useState } from "react";
import cn from "classnames";
import {
CSSTransitionClassNames,
Expand All @@ -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);

Expand Down
@@ -1,4 +1,4 @@
import { ReactElement, useRef, useState } from "react";
import { ReactElement, useEffect, useState } from "react";
import { Button } from "@react-md/button";
import {
Dialog,
Expand All @@ -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);
Expand Down
@@ -1,4 +1,4 @@
import { ReactElement } from "react";
import { ReactElement, useEffect } from "react";
import {
Checkbox,
Fieldset,
Expand Down Expand Up @@ -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 (
<TextFieldThemeConfig
Expand All @@ -77,7 +79,9 @@ export default function NativeSelectExample(): ReactElement {
>
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
{label && <option key="label" value="" disabled hidden />}
{!optgroup && <States states={states} readOnly={readOnly} />}
{!optgroup && (
<States key="optgroup" states={states} readOnly={readOnly} />
)}
{optgroup &&
Object.entries(grouped).map(([letter, states]) => (
<optgroup key={letter} label={letter}>
Expand Down
@@ -1,4 +1,4 @@
import { ReactElement, useRef } from "react";
import { ReactElement, useEffect, useRef } from "react";
import {
Slider,
SliderRequiredProps,
Expand Down Expand Up @@ -43,15 +43,17 @@ export default function ColorSlider({
// with it, need to also update the slider number value
const prevValue = useRef(value);
const prevNumberValue = useRef(numberValue);
if (prevValue.current !== value && prevNumberValue.current !== value) {
prevValue.current = value;
prevNumberValue.current = value;
setNumber(value);
} else if (prevNumberValue.current !== numberValue) {
prevValue.current = numberValue;
prevNumberValue.current = numberValue;
setValue(numberValue);
}
useEffect(() => {
if (prevValue.current !== value && prevNumberValue.current !== value) {
prevValue.current = value;
prevNumberValue.current = value;
setNumber(value);
} else if (prevNumberValue.current !== numberValue) {
prevValue.current = numberValue;
prevNumberValue.current = numberValue;
setValue(numberValue);
}
}, [value, numberValue, setNumber, setValue]);

return (
<Slider
Expand Down
@@ -1,4 +1,4 @@
import { ReactElement, ReactNode } from "react";
import { ReactElement, ReactNode, useEffect } from "react";
import {
Checkbox,
Fieldset,
Expand Down Expand Up @@ -76,21 +76,34 @@ export default function TextFieldThemeConfig({
}
);
const isUnstyled = currentTheme === "none";
if (disabled && error) {
setError(false);
}
useEffect(() => {
if (disabled && error) {
setError(false);
}

if (disabled && readOnly) {
setReadOnly(false);
}
if (disabled && readOnly) {
setReadOnly(false);
}

if (disableDense && dense) {
setDense(false);
}
if (disableDense && dense) {
setDense(false);
}
}, [
disabled,
error,
readOnly,
dense,
disableDense,
setError,
setReadOnly,
setDense,
]);

if (disableRightIcon && useRight) {
setRightIcon(false);
}
useEffect(() => {
if (disableRightIcon && useRight) {
setRightIcon(false);
}
}, [disableRightIcon, setRightIcon, useRight]);

return (
<Form className={styles.container}>
Expand Down
@@ -1,4 +1,4 @@
import { ReactElement } from "react";
import { ReactElement, useEffect } from "react";
import {
Checkbox,
Fieldset,
Expand All @@ -21,10 +21,12 @@ export default function TextAreaExample(): ReactElement {
const [maxRows, handleMaxRowChange, setMaxRows] = useChoice<string>("-1");
const rowsInt = parseInt(rows, 10);
const maxRowsInt = parseInt(maxRows, 10);
if (maxRowsInt !== -1 && maxRowsInt < rowsInt) {
const i = MAX_ROWS.find((value) => value >= rowsInt) || -1;
setMaxRows(`${i}`);
}
useEffect(() => {
if (maxRowsInt !== -1 && maxRowsInt < rowsInt) {
const i = MAX_ROWS.find((value) => value >= rowsInt) || -1;
setMaxRows(`${i}`);
}
}, [maxRowsInt, rowsInt, setMaxRows]);

return (
<TextFieldThemeConfig
Expand Down
@@ -1,4 +1,4 @@
import { ReactElement, useState } from "react";
import { ReactElement, useEffect, useState } from "react";
import { upperFirst } from "lodash";
import { Checkbox, Select, useChecked } from "@react-md/form";
import { ArrowDropDownSVGIcon } from "@react-md/material-icons";
Expand Down Expand Up @@ -80,9 +80,11 @@ export default function MenuPositioning(): ReactElement {
);
const [equalWidth, handleChange, setEqualWidth] = useChecked(false);
const anchor = anchors[anchorIndex];
if (anchor.x !== "center" && equalWidth) {
setEqualWidth(false);
}
useEffect(() => {
if (anchor.x !== "center" && equalWidth) {
setEqualWidth(false);
}
}, [anchor.x, equalWidth, setEqualWidth]);

return (
<>
Expand Down
@@ -1,4 +1,4 @@
import { ReactElement, useState } from "react";
import { ReactElement, useEffect, useState } from "react";
import { AppBar, AppBarAction } from "@react-md/app-bar";
import { Button } from "@react-md/button";
import { DialogContent } from "@react-md/dialog";
Expand Down Expand Up @@ -42,9 +42,11 @@ export default function SheetSizing(): ReactElement {
const [emulate, setEmulate] = useState(false);
const { isDesktop } = useAppSize();

if (emulate && !isDesktop) {
setEmulate(false);
}
useEffect(() => {
if (emulate && !isDesktop) {
setEmulate(false);
}
}, [emulate, isDesktop]);

return (
<Form>
Expand Down

0 comments on commit 5946bd9

Please sign in to comment.