v1.1.0 — motion system
The motion system. 25 issues across motion values, gestures, animations, and
the cross-platform primitives that consume them. Every package ships at 1.1.0.
Merged via #74.
Install
yarn add usemotif@1.1.0 @usemotif/tokens@1.1.0import { Box, useMotionValue, useTransform, useDrag, useScroll, useSpring } from 'usemotif';Added
Motion values
useMotionValue/useTransform/MotionValue. Imperative numeric
channels that bypass React renders. Writes commit directly to the DOM on web
or route through the active motion driver on native. The two non-obvious
contracts that matter:.set()bypassestransition, and updates do not
trigger re-renders. (#27)useTransformreal interpolation. Colors interpolate in sRGB by default;
unit-matched length strings ('8px' ↔ '16px') strip the unit, lerp, re-append.
Mixed shapes step at boundaries (the v1 fallback). (#36)- Perceptual color spaces. New
{ colorSpace: 'srgb' | 'oklab' | 'oklch' }
option onuseTransform.oklabandoklchkeep saturated hue rotations
vivid instead of muddying through grey;oklchinterpolates hue along the
shortest arc. Extended parsers handlehsl()/hsla(),oklab(),oklch(),
and the 148 CSS named colors. (#53) - Theme-aware token outputs.
useTransformresolves$colors.brand.red-style
references against the active theme at hook setup; the resolved literals
flow into the existing interpolation path. (#52) - Style-prop widening.
opacity, sizing, position,borderRadius,fontSize,
zIndex,transform— and the new transform shorthand axes (x,y,z,
rotate*,scale*,skew*) — accept aMotionValue<number>directly on<Box>.
Transform shorthand props
x,y,z,rotate,scale,skewand axis variants on<Box>.
Multiple shorthand props on the same element compose into one canonical-order
transformdeclaration (translate → rotate → scale → skew). Web emits a CSS
transformstring; native emits an RN transform array. Motion values bound
to multiple axes recompose per frame instead of clobbering each other.
(#35)
Spring physics
useSpring. Returns aMotionValue<number>whose.set(target)springs
from the current value over the spring's natural duration. Config takes a
literalSpringConfigor a theme-token name ('$animations.bouncy').
(#34)- Driver-routed spring on native.
useSpringroutes through
Animated.springon the default driver orwithSpringon the Reanimated
driver — the spring math runs off the JS thread when the driver supports it.
Falls back to the JS-thread integrator for drivers that don't implement
useSpringBacking. (#48)
Drag
useDrag. Pointer-event-driven on web, PanResponder on native. Returns
x,ymotion values for the drag offset plus adragPropsbag to spread
on the target. Lifecycle callbacks (onDragStart,onDrag,onDragEnd)
receive offset + velocity snapshots. (#25)dragElastic,dragMomentum,dragTransition. Rubber-band overshoot
past constraints; velocity-projected momentum + spring-settle on release;
tunable settle spring. (#58,
#59)dragprop on<Box>. Declarative wrapper that runsuseDragand
binds itsx/ymotion values to the transform shorthand. Mirrored on
both renderers; pointer handler composes with consumer-suppliedonPointerDown.
(#60)- UI-thread native drag. New
MotionDriver.useDragBackingseam. The
Reanimated driver implements it whenreact-native-reanimatedand
react-native-gesture-handlerare both installed:Gesture.Pan()on the UI
thread, bridge back viarunOnJS. (#61)
Scroll
useScroll. Window scroll (web), container scroll (both), or
target-relative progress with framer-motion-compatible offset anchors
('start end','end start', percentages, fractions). Web reads the
element rect viagetBoundingClientRect+ResizeObserver; native pairs
the ScrollView publisher with a layout snapshot viauseScrollTarget.
(#26,
#46)
Imperative animate
useAnimate(web).Element.animate()under the hood — animations run
off the main thread where the browser supports it. Returns
[scope, animate]; targets are ref or selector. (#28)useAnimate(native). Driver-routed via the new
MotionDriver.useImperativeAnimatemethod. The defaultanimatedDriver
drives anAnimated.Valueper property and writes per-frame via
setNativeProps. Ref-only targets on native; selector strings resolve to
a no-op. (#56)
Layout animation
useLayoutAnimation+<Box layout>. FLIP-style layout transitions —
web readsgetBoundingClientRectinuseLayoutEffectand applies an
inverse transform; native pairsonLayoutwith fourAnimated.Values
drivingtranslate+scaleviaAnimated.parallel. The declarative
<Box layout>prop wires the hook for the common case. (#24)
Primitives
<Path pathLength>. SVG stroke-drawing animation. Cross-platform; both
renderers emitpathLength="1"+strokeDasharray="1 1"+ astrokeDashoffset
that walks1 → 0. Accepts a literal number or aMotionValue<number>.
(#29)<Stack stagger>. Per-child entry-animation delay. Web reads
prefers-reduced-motionsynchronously and collapses stagger to 0 when on;
native plumbs a newdelayMsfield through the driver'suseEntryAnimation.
(#55)
Style props
- Text flow props —
whiteSpace,wordBreak,overflowWrap,hyphens,
textOverflow. The canonical single-line ellipsis triplet now flows through
the resolver. (#30) background-*family —background,backgroundImage,backgroundPosition,
backgroundRepeat,backgroundSize,backgroundOrigin,backgroundClip,
backgroundAttachment,backgroundBlendMode. Gradient fills work without
thestyle={{ … }}escape hatch. (#33)lineson<Text>— line-clamping via-webkit-line-clampon web and
numberOfLineson native. (#31)
Changed
- UI-thread worklet compose for transform shorthand. Reanimated driver's
useMotionValueBackingcomposes the RN transform array inside the worklet
instead of pre-composing on the JS thread. (#50) - Bundle floor. Worst-case
dist/index.jsgzip grew ~70% on@usemotif/core,
@usemotif/react, and@usemotif/react-nativeto fit the new surface. Apps
that only use<Box>+ a theme still tree-shake to ~10 KB gz; consumers
paying for the motion primitives see ~17 KB gz web / ~20 KB gz native.
Fixed
- Pseudo-state cascade.
_disabled={{ boxShadow: 'none' }}over a base
boxShadownow actually wins. Previously inline style (specificity 1,0,0,0)
always beat the pseudo.class:staterule (0,1,1) — silent onbg/color
where values look the same, biting hard on shadows / gradients.
(#39) - Flex / grid props without
display. Dev-only warning when a<Box>has
flex- or grid-only props (flexDirection,alignItems,gap, …) without
an explicitdisplay="flex"/inline-flex/grid. Tree-shakes in prod.
(#32)
Docs
- New
/reference/motion-values
and/recipes/motion-values
pages covering the full motion-value API + canonical patterns.
(#37)
Migration
No breaking changes. v1.0.2 → v1.1.0 is purely additive — existing call
sites compile and behave unchanged. Adopt the motion primitives incrementally;
the surface tree-shakes cleanly, so apps that don't use them pay nothing.