KQ-1236 · FOLD/PHONE

Fold Phone

A book-style foldable phone frame: folded it is a tall cover screen, and a sideways drag anywhere on it swings the front half round its hinge in real CSS perspective, the half's free edge following the finger 1:1 (the angle is solved from the finger's position) while its face darkens as it turns edge-on and its shadow falls across the other half, into a wide inner screen whose crease catches the light as the halves pass 150°. The hinge is a free-stop: a slow release rests where it is unless an end is near, a flick commits the way it was thrown, closing snaps shut on springs.snap with its overshoot reflected off the other half and a thock, and opening runs to the flat stop on springs.glide with the release velocity; the content re-flows between the cover's narrow size container and the wide one. The hinge is a slider in degrees whose arrows turn it 30°, Page keys 90°, Home folds, End opens flat and Enter toggles, and the Unfold button under the phone does the same.

KQ-1236 · FOLD/PHONE

Notes

Drag the phone sideways to open or close it. Arrow keys turn the hinge 30 degrees, Page keys 90, Home folds it, End opens it flat, and Enter opens or folds it all the way.

folded · cover screen · notes list

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/fold-phone

Props

children
React.ReactNode
default —
The screen, laid out in a size container: narrow on the cover, wide inside, so container queries re-flow it. It takes input when the phone is folded or open flat; while it moves or rests part-open it is drawn more than once as a picture, so keep it presentational.
label
string
default "Foldable phone"
The phone's accessible name.
time
string
default "10:24"
The clock in both screens' status bars.
fold / defaultFold
number
default 0
The posture, 0 folded shut to 1 open flat, anything between a hinge angle (controlled / initial). A new value from the host moves the hinge there silently.
onFoldChange
(fold: number) => void
default —
Fires from the drag, key or button that moved the hinge, with the posture it comes to rest at (three decimals).
finish
"ink" | "cream" | "sage"
default "ink"
The frame and hinge, fixed pigments that read the same in either theme.
crease
boolean
default true
A crease down the inner screen: a hairline, and a highlight that peaks as the halves pass 150° and fades to a faint line when flat. Off, the inner screen is seamless.
sound
boolean
default false
Play a thock as the halves clap shut (and a soft second one if they bounce) and a lighter one at the flat stop, only for the visitor's own drag, key or press.
disabled
boolean
default false
The hinge, button and drag stop answering and the screens are inert.
className
string
default —
Classes for the root, a column of the phone's 100:114 stage and the Unfold button; the phone is sized from the root's width.