TZUU UI
26 React components built on one spring-physics engine. Every motion in the library — press squash, magnetic pull, drag momentum, shape morphing — comes from the same set of primitives rather than per-component animation code.
SquishButton
The library's base button. Press it and the surface compresses into the page, then springs back past its rest size before settling.
<SquishButton
variant="solid"
size="md"
intensity="normal"
spring="smooth"
extrude={4}
>
Press me
</SquishButton>PushToggle
Press it and the key travels down until it bottoms out, then stays there. Press again and it pops back up.
<PushToggle
size={72}
travel={10}
intensity="normal"
spring="smooth"
label="Mute"
>
<MinusIcon />
</PushToggle>StickerButton
Drag the tile away from its recess and release it. A slow release settles home; a fast flick tumbles past centre before coming to rest.
<StickerButton
size={72}
peelDistance={26}
maxRotation={18}
intensity="normal"
spring="smooth"
aria-label="Add"
>
<PlusIcon size={24} />
</StickerButton>Counter
A quantity stepper. The value rolls in the direction of travel — up when incrementing, down when decrementing.
<Counter
defaultValue={1}
size="md"
intensity="normal"
spring="smooth"
circle
min={0}
max={10}
step={1}
/>FollowButton
A follow/following toggle. The badge first grows into the button's left cap, then sweeps right to fill it, carrying the new icon and label in behind its edge.
<FollowButton
size="md"
intensity="normal"
spring="smooth"
label="Follow"
activeLabel="Following"
/>RollButton
A two-state pill — follow/following is the usual case. Toggling it rolls the face over: the new label arrives from above carrying its own fill, and the old one leaves out of the bottom.
<RollButton
size="md"
intensity="normal"
spring="smooth"
label="Follow back"
activeLabel="Following"
/>Tabs
A segmented control. The indicator's edges are pulled outward as it launches, and the container itself gives way where the indicator slams into it.
<Tabs
size="md"
spring="bouncy"
intensity="normal"
items={[
{ value: "A", label: "A" },
{ value: "B", label: "B" },
]}
/>Checkbox
A binary control. The unchecked state is a flat white shape, and checking it grows the fill outward from the centre with a small spring overshoot and the tick drawing on behind it.
<Checkbox
size={26}
circle
extrude={0}
intensity="normal"
spring="smooth"
>Remember me</Checkbox>SelectBox
A dropdown. Options cascade in one after another, the highlight slides to whichever option you point at, and committing rolls the trigger's label in the direction the selection moved.
<SelectBox
defaultValue="c1"
spring="smooth"
stagger={26}
options={[
{ value: "c1", label: "Category 1" },
{ value: "c2", label: "Category 2" },
]}
/>ViewToggle
Cycles through layout modes. The icon's bars slide and resize into their new arrangement instead of cross-fading.
<ViewToggle
size="md"
spring="smooth"
/>BrowserTabs
A browser-style tab bar. Tabs can be added and closed, and the active tab merges seamlessly into the panel below it.
<BrowserTabs
radius={12}
addable
closable
defaultTabs={[
{ id: "a", title: "Overview" },
{ id: "b", title: "Details" },
]}
/>Switch
A binary on/off control. The knob stretches under the throw, slams into the far end of the track and shoves it outward, and latching on flings a small burst of sparks.
<Switch
size="md"
intensity="normal"
spring="bouncy"
label="Notifications"
/>WipeToggle
A switch between two labelled modes — an input-method toggle is the canonical case. The fill sweeps on and off behind an arc, the shell gives where the arc lands, and the active glyph takes the emphasis.
<WipeToggle
size="md"
intensity="normal"
spring="bouncy"
label="Input mode"
options={[
{ value: "latin", label: "A" },
{ value: "kana", label: "あ" },
]}
/>Pagination
Pages are domes sitting on a shared ground line. Selecting one extrudes it upward while the previous one sinks back.
<Pagination
count={4}
restHeight={26}
activeHeight={58}
archWidth={44}
intensity="normal"
spring="smooth"
/>Stepper
A step indicator. The fill travels between nodes and fuses with them on arrival, forming a meniscus at the join.
<Stepper
steps={3}
gap={56}
nodeRadius={9}
trackWidth={4}
intensity="normal"
spring="smooth"
/>DateCarousel
A horizontal picker. Tap a date, drag it, flick it, or use the arrow keys. The highlight resists being moved and stretches wide on the way.
<DateCarousel
defaultIndex={4}
itemWidth={96}
height={120}
momentum={0.18}
stickiness={0.7}
spring="smooth"
items={days.map((d) => ({
key: String(d),
primary: d,
suffix: "日",
}))}
/>Tooltip
Hover or focus the trigger. The circle behind the icon is the tooltip: it lifts out from behind the icon, then widens from its centre into the label.
<Tooltip
content="Helpful hint"
placement="top"
delay={120}
gap={0}
spring="smooth"
>
<button aria-label="Help">?</button>
</Tooltip>AttachmentButton
A file-attach affordance. Press the circle and it grows into a rounded panel while the clip icon shrinks and slides into the corner, turning into a close button as a dashed drop zone fades in beneath it.
<AttachmentButton
panelSize={240}
spring="smooth"
/>HoverRevealLink
A grey link chip. Hover or focus lifts the link icon clear of the chip, then a white pill unrolls to the right of it with the URL the link points at.
<HoverRevealLink
href="https://example.com/portfolio"
label="Hover me"
lift={60}
intensity="normal"
spring="smooth"
/>SunriseToggle
Starts dark with a moon. Press it and a white circle climbs in from the middle of the bottom edge, uncovering a sun as it goes.
<SunriseToggle
size={72}
spring="smooth"
disabled={false}
/>DownloadButton
Press it and the arrow drops, the tray flexes under the impact, then the arrow re-enters from above.
<DownloadButton
size="md"
dropDistance={7}
trayFlex={2.6}
intensity="normal"
spring="smooth"
/>PipToggle
The inner pane shrinks into the corner of the frame, morphing rather than swapping between two icons.
<PipToggle
size="md"
spring="smooth"
/>ExpandToggle
An expand/collapse affordance. The disc fills as the glyph turns a quarter turn and the second stroke grows out of the first.
<ExpandToggle
size={56}
intensity="normal"
spring="smooth"
/>Card
The frame used throughout this site to present a demo. Optionally magnetic, so a grid of cards subtly tracks the pointer.
<Card
variant="default"
magnetic
magneticRadius={220}
hoverScale={1.02}
spring="smooth"
label="Card label"
>
Card body
</Card>