@adrienlcp/react
Generic React helpers: a context that names its missing provider, and an element that finishes its exit transition before unmounting
Works with
- React
- TypeScript
Install
pnpm add @adrienlcp/reactExports
Grouped by the section of the documentation that explains them. A row leads to its section.
Leaving without being cut short: Animate2 exports
AnimateMounts and unmounts an element without cutting its exit short.ComponentstaggerStyleHands an item its place in a list to its stylesheet, which turns it into a delay:calc(var(--stagger-index) * var(--transition-fast))on the way in,calc((var(--stagger-count) - 1 - var(--stagger-index)) * var(--transition-fast))to leave in reverse.Function
Documented in the source only2 exports
Documentation
The README and the documents beside it, as written in the repository.
OverviewREADME.md
Generic React helpers, kept in one version across apps. No dependencies; React 19 is a peer.
pnpm add @adrienlcp/reactA context that names its missing providerREADME.md
import { createSafeContext } from '@adrienlcp/react'
export const [PlayerContext, usePlayer, useOptionalPlayer] =
createSafeContext<Player>('PlayerContext')
<PlayerContext value={player}>…</PlayerContext>usePlayer() returns the value, or throws
PlayerContext was read outside of its provider when no provider is mounted
above: a whole class of undefined bugs becomes one loud error naming what to
mount. useOptionalPlayer() answers undefined there instead, for a component
that also works on its own. The name doubles as the context's displayName in
the React DevTools.
The react-aria helpers live in
@adrienlcp/react-aria.
Leaving without being cut short: AnimateREADME.md
import { Animate, staggerStyle } from '@adrienlcp/react'
<Animate as="aside" className="toast" isVisible={isOpen} onExited={forget}>
{message}
</Animate>.toast
opacity: 1
transition: opacity var(--transition-base)
@starting-style
opacity: 0
&[data-exiting]
opacity: 0React unmounts at once, so an exit transition never plays. Animate keeps
the element rendered with data-exiting once isVisible turns false, until
every transition and animation in it has ended, then unmounts it and calls
onExited. The motion is entirely the stylesheet's, through the hooks a
react-aria overlay offers (@starting-style for the entry, [data-exiting]
for the exit): no duration to repeat in JavaScript, and a reduced-motion
0ms leaves at once. keepMounted hides the element (hidden) instead of
removing it, for state a remount would lose.
A list enters one item after the other with staggerStyle(index, count),
which hands each item --stagger-index and --stagger-count. Take the step
from a duration token, so reduced motion zeroes the delays along with the
durations:
.item
transition-delay: calc(var(--stagger-index) * var(--transition-fast))
&[data-exiting]
transition-delay: calc((var(--stagger-count) - 1 - var(--stagger-index)) * var(--transition-fast))A page change, or a state change that is a transition, animates with React's
<ViewTransition> instead: Animate is for the element that comes and goes
while the rest of the page stays interactive.