use Scrim
Reads a store's status and readiness, and re-renders when they change.
Usage
The config moves the nodes. When a component has to react to the scrim, it reads the store with useScrim.
tsx
const { status, isReady } = useScrim(scrimRouteConfig);isReady
The title in this site's scrim uses a custom font, so I show it only once until has waited for the fonts.
tsx
// features/scrim/scrim_route.tsx
export const ScrimRoute = () => {
const { isReady } = useScrim(scrimRouteConfig);
return (
<div ref={scrimRouteConfig.node(SCRIM_NODE_CURTAIN)} aria-hidden className="fixed inset-0 z-9999 bg-main">
<h1 className={cn("font-secondary transition-opacity duration-300", !isReady && "opacity-0")}>{title}</h1>
</div>
);
};status
status reports the ends too: covered once the scrim has covered, and idle once it has left. Here a hero animates in with Motion when the scrim is gone.
tsx
export const Hero = () => {
const { status } = useScrim(scrimRouteConfig);
return (
<motion.h1 initial={{ opacity: 0 }} animate={{ opacity: status === "idle" ? 1 : 0 }}>
{title}
</motion.h1>
);
};And here the page scrolls back to the top while nobody can see it.
tsx
const { status } = useScrim(scrimRouteConfig);
useEffect(() => {
if (status === "covered") window.scrollTo(0, 0);
}, [status]);On the server
On the server the store never moves: status is initial and isReady is false. Hydration reads the same values, then the component follows the store.
Reference
Returns
| prop | type | default | |
|---|---|---|---|
status | "idle" | "entering" | "covered" | "leaving" | — | where the scrim is |
isReady | boolean | — | true once until has resolved |