diff --git a/apps/website/app/layout.tsx b/apps/website/app/layout.tsx index 4053b3cd..23cec686 100644 --- a/apps/website/app/layout.tsx +++ b/apps/website/app/layout.tsx @@ -70,7 +70,7 @@ export default function RootLayout({ the dim layer, but remove backdrop filtering: re-blurring a live WebGL canvas throughout the sheet animation is prohibitively expensive on mobile GPUs. */ - "[&_[data-slot=sheet-overlay]]:backdrop-filter-none", + "**:data-[slot=sheet-overlay]:backdrop-filter-none", )} > {/* `href` + `precedence` is what gets React to hoist this into
. diff --git a/apps/website/components/Nav.tsx b/apps/website/components/Nav.tsx index 8847755e..28331cf3 100644 --- a/apps/website/components/Nav.tsx +++ b/apps/website/components/Nav.tsx @@ -12,9 +12,12 @@ import { useMemo, useRef, useState, + useSyncExternalStore, } from "react"; import { useParams } from "next/navigation"; import { createSerializer, parseAsString, useQueryStates } from "nuqs"; +import { type Options, useHotkeys } from "react-hotkeys-hook"; +import { useEventListener, useIsClient } from "usehooks-ts"; import { ChevronLeftIcon, ListFilterIcon, @@ -84,6 +87,24 @@ const filterParsers = { survives the client navigation into an example. */ const serializeFilters = createSerializer(filterParsers); +/* `data-nav-collapsed` is put on before first paint by the inline + script in `app/layout.tsx` — the only way a statically exported page can + weigh `localStorage`, the `?nav=` override and the current route that early. + React reads the verdict back through `useSyncExternalStore` rather than from + a mount effect: the value is already there at hydration, and the server + snapshot is what keeps the first render agreeing with the prerendered HTML. + + The read is cached because React hands the attribute back as soon as the + panel is its own (see the effect below); a later read would report a rail + that is open no matter how the page was painted. */ +let paintedCollapsed: boolean | undefined; + +const subscribeToPaintedCollapsed = () => () => {}; +const getPaintedCollapsed = () => + (paintedCollapsed ??= + document.documentElement.hasAttribute("data-nav-collapsed")); +const getPaintedCollapsedOnServer = () => false; + /** * Keep the list itself complete for links, roving focus and stable scroll * geometry, but only mount expensive thumbnail/tag subtrees near the visible @@ -98,28 +119,20 @@ function useNearbyExamples( const [nearby, setNearby] = useState