PushToggle
Press it and the key travels down until it bottoms out, then stays there. Press again and it pops back up.
Usage
<PushToggle
size={72}
travel={10}
intensity="normal"
spring="smooth"
label="Mute"
>
<MinusIcon />
</PushToggle>How the motion works
The deformation is the library's standard press — Y compresses while X widens — and the extruded bottom edge is a hard shadow, so the same transform squashes the shadow along with the face instead of sliding a separate slab around underneath. The widening is read from the spring's velocity rather than its position: a latching key holds its down state indefinitely, and a position-driven flare would park it permanently wider than it started, so the key flares only while travelling and is back to its original width by the time it settles at either end. What separates this from SquishButton is where the edge ends up: a momentary key spends three quarters of its extrude and keeps the rest, so it still reads as raised while held, whereas this one spends all of it. At full press the offset reaches zero and the face covers the shadow exactly, leaving a silhouette with no edge at all. Nothing fades — the key runs out of extrude to show, and that absence is what makes the down state read as pressed rather than as a recoloured button. The two directions do not share a spring config: a real key is pushed down against its spring and thrown back up by it, so the descent runs slow and heavy — slow enough to watch the squash — while the release stays snappy. The overshoot is asymmetric for the same reason: past 0 the key rings above rest and stretches on the rebound; past 1 it can neither sink nor shorten further, so the extra force goes into squash, which is both how the descent lands and the jolt you get from pressing a key that is already down.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| pressed | boolean | — | Controlled latch state. Omit for uncontrolled use. |
| defaultPressed | boolean | false | Initial uncontrolled state. |
| onChange | (pressed: boolean) => void | — | Fires on every toggle. |
| size | number | 72 | Edge length of the key face in px. |
| travel | number | 10 | Height of the extruded bottom edge in px; also how far the key sinks. |
| intensity | "subtle" | "normal" | "strong" | "normal" | Scales how hard the surface squashes. |
| spring | SpringLike | "bouncy" | Spring for the pop back up. |
| pressSpring | SpringLike | { stiffness: 140, damping: 19, mass: 1.25 } | Spring for the push down. Slower than the release, as on a real key. |
| label | string | — | Accessible name when the key has only an icon. |
