@mui/internal-docs-infra
Version:
MUI Infra - internal documentation creation tools.
86 lines (81 loc) • 2.91 kB
JavaScript
'use client';
import * as React from 'react';
import { useCoordinatedSwap } from "./useCoordinatedSwap.mjs";
import { CoordinatedFallbackContext } from "./CoordinatedFallbackContext.mjs";
import { CoordinatedContentContext } from "./CoordinatedContentContext.mjs";
/**
* Show `fallback` until `ready` (and the page-coordinated swap conditions) are
* met, then swap to `content`. The fallback is force-mounted once so its
* `useCoordinatedFallback` hoist runs even when the content is precomputed; the
* hoisted data is handed down to `content` via `useCoordinatedContent`.
*
* Generalizes the state-driven fallback<->content swap from
* `CodeHighlighterClient`. Advanced consumers that need to fold the hoisted data
* into their own `ready` computation should use {@link useCoordinatedSwap}
* directly instead of this component.
*/
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
export function CoordinatedLazy(props) {
const {
content,
fallback,
ready,
defer,
holdGate,
skipFallback,
requireHoist,
awaitContent,
gate,
data,
preload
} = props;
const {
showFallback,
fallbackContext,
hoisted,
reportContentReady
} = useCoordinatedSwap({
ready,
defer,
holdGate,
hasFallback: fallback != null,
skipFallback,
requireHoist,
awaitContent,
gate,
data,
preload
});
// Forward `fallback` so a code-split `content` (e.g. `LazyContent`) can show
// the same placeholder via `useCoordinatedContent().fallback` while its
// dynamic import resolves - no empty flash on the content-side swap. In
// `awaitContent` mode the fallback is already rendered alongside the content,
// so the content must stay null while loading (no duplicate placeholder).
const contentContext = React.useMemo(() => ({
hoisted,
reportReady: reportContentReady,
fallback: awaitContent ? undefined : fallback
}), [hoisted, reportContentReady, fallback, awaitContent]);
const contentNode = /*#__PURE__*/_jsx(CoordinatedContentContext.Provider, {
value: contentContext,
children: content
});
const fallbackNode = showFallback ? /*#__PURE__*/_jsx(CoordinatedFallbackContext.Provider, {
value: fallbackContext,
children: fallback
}) : null;
// awaitContent: mount the content behind the fallback so a code-split content
// (e.g. `LazyContent`) loads in the background and reveals once it reports
// ready. The content returns `null` until then, so only the fallback shows.
if (awaitContent) {
return /*#__PURE__*/_jsxs(React.Fragment, {
children: [fallbackNode, contentNode]
});
}
// Default: show the fallback OR the content (the content only mounts once the
// swap commits to it).
return showFallback ? /*#__PURE__*/_jsx(CoordinatedFallbackContext.Provider, {
value: fallbackContext,
children: fallback
}) : contentNode;
}