@onlynative/inertia 0.0.1-alpha.7 → 0.0.1-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +1 -1
  2. package/dist/gestureLayer/index.d.mts +119 -0
  3. package/dist/gestureLayer/index.d.ts +119 -0
  4. package/dist/gestureLayer/index.js +346 -0
  5. package/dist/gestureLayer/index.js.map +1 -0
  6. package/dist/gestureLayer/index.mjs +344 -0
  7. package/dist/gestureLayer/index.mjs.map +1 -0
  8. package/dist/index.d.mts +114 -74
  9. package/dist/index.d.ts +114 -74
  10. package/dist/index.js +388 -1542
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +388 -1545
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/motion/Image.d.mts +1 -1
  15. package/dist/motion/Image.d.ts +1 -1
  16. package/dist/motion/Image.js +244 -1462
  17. package/dist/motion/Image.js.map +1 -1
  18. package/dist/motion/Image.mjs +247 -1465
  19. package/dist/motion/Image.mjs.map +1 -1
  20. package/dist/motion/Pressable.d.mts +1 -1
  21. package/dist/motion/Pressable.d.ts +1 -1
  22. package/dist/motion/Pressable.js +244 -1462
  23. package/dist/motion/Pressable.js.map +1 -1
  24. package/dist/motion/Pressable.mjs +247 -1465
  25. package/dist/motion/Pressable.mjs.map +1 -1
  26. package/dist/motion/ScrollView.d.mts +1 -1
  27. package/dist/motion/ScrollView.d.ts +1 -1
  28. package/dist/motion/ScrollView.js +244 -1462
  29. package/dist/motion/ScrollView.js.map +1 -1
  30. package/dist/motion/ScrollView.mjs +247 -1465
  31. package/dist/motion/ScrollView.mjs.map +1 -1
  32. package/dist/motion/Text.d.mts +1 -1
  33. package/dist/motion/Text.d.ts +1 -1
  34. package/dist/motion/Text.js +244 -1462
  35. package/dist/motion/Text.js.map +1 -1
  36. package/dist/motion/Text.mjs +247 -1465
  37. package/dist/motion/Text.mjs.map +1 -1
  38. package/dist/motion/View.d.mts +1 -1
  39. package/dist/motion/View.d.ts +1 -1
  40. package/dist/motion/View.js +244 -1462
  41. package/dist/motion/View.js.map +1 -1
  42. package/dist/motion/View.mjs +247 -1465
  43. package/dist/motion/View.mjs.map +1 -1
  44. package/dist/touch/index.d.mts +146 -0
  45. package/dist/touch/index.d.ts +146 -0
  46. package/dist/touch/index.js +166 -0
  47. package/dist/touch/index.js.map +1 -0
  48. package/dist/touch/index.mjs +164 -0
  49. package/dist/touch/index.mjs.map +1 -0
  50. package/dist/{types-NmNeJjo1.d.mts → types-cU43dEmH.d.mts} +64 -17
  51. package/dist/{types-NmNeJjo1.d.ts → types-cU43dEmH.d.ts} +64 -17
  52. package/dist/useGesture-B7A_1DVg.d.ts +84 -0
  53. package/dist/useGesture-cimMrzC1.d.mts +84 -0
  54. package/jest-setup.js +4 -0
  55. package/llms.txt +12 -3
  56. package/package.json +22 -2
  57. package/src/__type-tests__/variants.test-d.tsx +67 -0
  58. package/src/gestureLayer/index.ts +21 -0
  59. package/src/gestureLayer/useGestureLayer.ts +285 -0
  60. package/src/index.ts +7 -0
  61. package/src/layout/index.ts +15 -0
  62. package/src/layout/sharedRegistry.ts +111 -0
  63. package/src/layout/useSharedLayout.ts +289 -0
  64. package/src/motion/createMotionComponent.tsx +123 -37
  65. package/src/motion/installCheck.ts +7 -11
  66. package/src/touch/index.ts +18 -0
  67. package/src/touch/useTouchDrag.ts +289 -0
  68. package/src/types.ts +79 -20
  69. package/src/values/index.ts +11 -0
  70. package/src/values/useBooleanSpring.ts +33 -0
  71. package/src/values/useColorTransition.ts +72 -0
  72. package/src/values/useShadow.ts +116 -0
package/dist/index.d.mts CHANGED
@@ -2,9 +2,10 @@ import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
3
  import * as react_native from 'react-native';
4
4
  import { NativeSyntheticEvent, NativeScrollEvent } from 'react-native';
5
- import { M as MotionComponent, A as AnimatableValue, T as TransitionConfig, E as EasingInput, G as GestureLayerTransitions, S as SpringTransition, V as VariantController } from './types-NmNeJjo1.mjs';
6
- export { a as AnimateStyle, b as AnimationCallbackInfo, D as DecayTransition, c as GestureSubStates, d as MotionProps, N as NoAnimationTransition, P as PerPropertyTransition, R as RepeatConfig, e as SequenceStep, f as TimingTransition, g as Transition, h as VariantsMap } from './types-NmNeJjo1.mjs';
7
- import { SharedValue } from 'react-native-reanimated';
5
+ import { M as MotionComponent, A as AnimatableValue, T as TransitionConfig, E as EasingInput, S as SpringTransition, V as VariantController } from './types-cU43dEmH.mjs';
6
+ export { a as AnimateStyle, b as AnimationCallbackInfo, D as DecayTransition, G as GestureSubStates, c as MotionProps, N as NoAnimationTransition, P as PerPropertyTransition, R as RepeatConfig, d as SequenceStep, e as TimingTransition, f as Transition, g as VariantsMap } from './types-cU43dEmH.mjs';
7
+ import { SharedValue, useAnimatedStyle } from 'react-native-reanimated';
8
+ export { U as UseGestureHandlers, a as UseGestureResult, u as useGesture } from './useGesture-cimMrzC1.mjs';
8
9
  export { MotionImage } from './motion/Image.mjs';
9
10
  export { MotionPressable } from './motion/Pressable.mjs';
10
11
  export { MotionScrollView } from './motion/ScrollView.mjs';
@@ -243,84 +244,68 @@ declare function buildReleaseAnimation(transition: TransitionConfig, toValue: nu
243
244
  declare function useAnimation(target: number, transition?: TransitionConfig): SharedValue<number>;
244
245
 
245
246
  /**
246
- * Handler bag returned by `useGesture`. Spread on a `Pressable` to drive the
247
- * shared values returned alongside.
247
+ * Toggle a 0↔1 progress value with a spring whenever `active` flips.
248
248
  *
249
- * Hover handlers use `Pressable`'s own `onHoverIn` / `onHoverOut` names (web
250
- * only no-ops on native). `onFocus` consults `isFocusVisible()` before
251
- * raising the keyboard-only `focusVisible` layer; `focused` always raises.
249
+ * This is the recurring shape behind checkbox checks, accordion expansions,
250
+ * drawer open/closed states, focus rings, and every other binary UI flip
251
+ * that wants spring physics rather than a hard cut. The returned shared
252
+ * value sits at `0` when `active` is `false` and animates toward `1` when
253
+ * `active` flips to `true` (and back again on the reverse flip). Feed it to
254
+ * a `useTransform`, `useShadow`, or a hand-rolled `useAnimatedStyle` to
255
+ * drive whatever the boolean controls visually.
256
+ *
257
+ * ```tsx
258
+ * const progress = useBooleanSpring(isChecked)
259
+ * const indicatorStyle = useAnimatedStyle(() => ({
260
+ * opacity: progress.value,
261
+ * transform: [{ scale: progress.value }],
262
+ * }))
263
+ * ```
264
+ *
265
+ * The spring config follows the same react-spring vocabulary as the rest of
266
+ * the library (`tension` / `friction` / `mass`); omit it to take the
267
+ * library's defaults.
252
268
  */
253
- interface UseGestureHandlers {
254
- onPressIn: () => void;
255
- onPressOut: () => void;
256
- onHoverIn: () => void;
257
- onHoverOut: () => void;
258
- onFocus: () => void;
259
- onBlur: () => void;
260
- }
261
- interface UseGestureResult {
262
- /** 0↔1 progress for the pressed layer. */
263
- pressed: SharedValue<number>;
264
- /** 0↔1 progress for the focused layer (any focus modality). */
265
- focused: SharedValue<number>;
266
- /** 0↔1 progress for the focusVisible layer (keyboard focus only). */
267
- focusVisible: SharedValue<number>;
268
- /** 0↔1 progress for the hovered layer (web only — stays at 0 on native). */
269
- hovered: SharedValue<number>;
270
- /** Handlers to spread on the receiving `Pressable`. */
271
- handlers: UseGestureHandlers;
269
+ declare function useBooleanSpring(active: boolean, springConfig?: SpringTransition): SharedValue<number>;
270
+
271
+ /**
272
+ * Color style keys understood by React Native that this hook can target.
273
+ * Sticks to the keys that exist on the v0.1 animatable surface so the
274
+ * returned style fragment is always a legal RN style.
275
+ */
276
+ type ColorStyleKey = 'backgroundColor' | 'color' | 'borderColor' | 'borderTopColor' | 'borderRightColor' | 'borderBottomColor' | 'borderLeftColor' | 'tintColor' | 'shadowColor';
277
+ interface UseColorTransitionOptions {
278
+ /**
279
+ * Which style slot the interpolated color is emitted under. Defaults to
280
+ * `backgroundColor` the dominant case for state-layer haloes, card
281
+ * fills, and chip surfaces. Override for ring colors (`borderColor`),
282
+ * text colors (`color`), image tints (`tintColor`), etc.
283
+ */
284
+ key?: ColorStyleKey;
272
285
  }
273
286
  /**
274
- * Build a gesture-layer controller. The hook-form of the `gesture` prop
275
- * reach for it when you need to drive multiple animated views from the same
276
- * gesture state (a focus ring + state-layer halo + content tint all on one
277
- * Pressable), which the prop-form's "animate the receiver's own style" model
278
- * can't express.
279
- *
280
- * Returns four 0↔1 shared values (one per layer) and a handler bag to spread
281
- * on a `Pressable`. The shared values are stable across renders — feed them
282
- * into any number of `useAnimatedStyle` blocks anywhere in the tree.
283
- *
284
- * Transitions follow the same shape as the `gesture` prop's accompanying
285
- * `transition`: pass a single `TransitionConfig` to use for every layer, or a
286
- * `GestureLayerTransitions` map to give each layer its own. Layers without an
287
- * explicit transition fall back to the library default spring.
287
+ * Interpolate a single color channel between `from` and `to` as `progress`
288
+ * moves 0→1, returning an animated style fragment that can be spread onto
289
+ * any Reanimated-aware view.
288
290
  *
289
- * Reduced motion (via `<MotionConfig reducedMotion>`) collapses every
290
- * transition to `no-animation` so state changes snap instead of interpolating
291
- * — same behaviour the gesture prop applies.
292
- *
293
- * @example
294
291
  * ```tsx
295
- * import { useAnimatedStyle } from 'react-native-reanimated'
296
- * import { useGesture } from '@onlynative/inertia'
297
- *
298
- * function Card() {
299
- * const { pressed, focused, hovered, handlers } = useGesture({
300
- * pressed: { type: 'timing', duration: 100 },
301
- * hovered: { type: 'timing', duration: 150 },
302
- * focused: { type: 'timing', duration: 200 },
303
- * })
304
- *
305
- * const ringStyle = useAnimatedStyle(() => ({ opacity: focused.value }))
306
- * const haloStyle = useAnimatedStyle(() => ({
307
- * opacity: Math.max(
308
- * hovered.value * 0.08,
309
- * focused.value * 0.10,
310
- * pressed.value * 0.10,
311
- * ),
312
- * }))
313
- *
314
- * return (
315
- * <Pressable {...handlers}>
316
- * <Animated.View style={ringStyle} />
317
- * <Animated.View style={haloStyle} />
318
- * </Pressable>
319
- * )
320
- * }
292
+ * const progress = useBooleanSpring(isPressed)
293
+ * const fillStyle = useColorTransition(progress, [colors.surface, colors.pressed])
294
+ * const ringStyle = useColorTransition(progress, [colors.outline, colors.primary], {
295
+ * key: 'borderColor',
296
+ * })
297
+ *
298
+ * return <Motion.View style={[styles.chip, fillStyle, ringStyle]} />
321
299
  * ```
300
+ *
301
+ * This is a pure interpolator: it does not animate on its own. Drive
302
+ * `progress` upstream with a `useSpring`, `useBooleanSpring`, gesture
303
+ * progress, or scroll-derived `useTransform`. Values outside `[0, 1]`
304
+ * clamp. For a raw `SharedValue<string>` (e.g. to feed a gradient or
305
+ * compose into a hand-rolled `useAnimatedStyle`), use `useTransform`
306
+ * directly with a color output range.
322
307
  */
323
- declare function useGesture(transition?: TransitionConfig | GestureLayerTransitions): UseGestureResult;
308
+ declare function useColorTransition(progress: SharedValue<number>, range: readonly [string, string], options?: UseColorTransitionOptions): ReturnType<typeof useAnimatedStyle>;
324
309
 
325
310
  /**
326
311
  * Create an animatable value owned by JS but readable from worklets.
@@ -450,6 +435,61 @@ interface UseScrollResult {
450
435
  */
451
436
  declare function useScroll(): UseScrollResult;
452
437
 
438
+ /**
439
+ * Shape accepted on either end of a `useShadow` tween. Every field is
440
+ * optional — only keys present on at least one side participate in the
441
+ * output style. Mirrors the flat shadow keys on `Motion.View`'s `animate`
442
+ * surface, plus the nested `shadowOffset` source.
443
+ */
444
+ interface ShadowConfig {
445
+ shadowOpacity?: number;
446
+ shadowRadius?: number;
447
+ shadowOffset?: {
448
+ width?: number;
449
+ height?: number;
450
+ };
451
+ /** Android elevation. iOS shadow consumers can leave this off. */
452
+ elevation?: number;
453
+ shadowColor?: string;
454
+ }
455
+ interface UseShadowOptions {
456
+ /** Shadow state at `progress === 0`. */
457
+ from: ShadowConfig;
458
+ /** Shadow state at `progress === 1`. */
459
+ to: ShadowConfig;
460
+ /**
461
+ * Driver — typically 0→1. Whatever produces it (a `useSpring`, a gesture
462
+ * progress value, a scroll-derived `useTransform`) is the caller's
463
+ * concern. The hook is a pure interpolator; it does not animate on its
464
+ * own. Values outside `[0, 1]` clamp.
465
+ */
466
+ progress: SharedValue<number>;
467
+ }
468
+ /**
469
+ * Interpolate between two shadow configs as `progress` moves 0→1, returning
470
+ * an animated style fragment that can be spread onto any Reanimated-aware
471
+ * view (including `Motion.*` primitives and a hand-rolled `Animated.View`).
472
+ *
473
+ * ```tsx
474
+ * const progress = useSpring(isElevated ? 1 : 0)
475
+ * const shadowStyle = useShadow({
476
+ * from: { shadowOpacity: 0.08, shadowRadius: 2, shadowOffset: { width: 0, height: 1 }, elevation: 1 },
477
+ * to: { shadowOpacity: 0.24, shadowRadius: 12, shadowOffset: { width: 0, height: 8 }, elevation: 8 },
478
+ * progress,
479
+ * })
480
+ *
481
+ * return <Motion.View style={[styles.card, shadowStyle]} />
482
+ * ```
483
+ *
484
+ * Only keys present on either `from` or `to` are emitted. A key present on
485
+ * one side and absent on the other tweens from the present value to the
486
+ * absent side's natural zero (`0` for numbers, `'transparent'` for
487
+ * `shadowColor`, `{ width: 0, height: 0 }` for `shadowOffset`). This is a
488
+ * pure interpolator — to "animate" the shadow, drive `progress` with a
489
+ * spring, timing, or gesture upstream.
490
+ */
491
+ declare function useShadow({ from, to, progress, }: UseShadowOptions): ReturnType<typeof useAnimatedStyle>;
492
+
453
493
  /**
454
494
  * Build a controller for a variants map. The controller is the imperative
455
495
  * escape hatch — pass it to a Motion primitive via `controller={...}` and
@@ -463,4 +503,4 @@ declare function useScroll(): UseScrollResult;
463
503
  */
464
504
  declare function useVariants<V extends Readonly<Record<string, object>>>(variants: V, initial?: keyof V & string): VariantController<keyof V & string>;
465
505
 
466
- export { AnimatableValue, type ExtrapolationMode, Motion, MotionComponent, MotionConfig, type MotionConfigValue, Presence, type PresenceContextValue, type ReducedMotion, SpringTransition, TransitionConfig, type UseGestureHandlers, type UseGestureResult, type UseScrollResult, type UseTransformOptions, VariantController, buildReleaseAnimation, createMotionComponent, ensureWorkletEasing, resolveAnimatableValue, resolveTransition, useAnimation, useGesture, useMotionConfig, useMotionValue, usePresence, useScroll, useShouldReduceMotion, useSpring, useTransform, useVariants };
506
+ export { AnimatableValue, type ColorStyleKey, type ExtrapolationMode, Motion, MotionComponent, MotionConfig, type MotionConfigValue, Presence, type PresenceContextValue, type ReducedMotion, type ShadowConfig, SpringTransition, TransitionConfig, type UseColorTransitionOptions, type UseScrollResult, type UseShadowOptions, type UseTransformOptions, VariantController, buildReleaseAnimation, createMotionComponent, ensureWorkletEasing, resolveAnimatableValue, resolveTransition, useAnimation, useBooleanSpring, useColorTransition, useMotionConfig, useMotionValue, usePresence, useScroll, useShadow, useShouldReduceMotion, useSpring, useTransform, useVariants };
package/dist/index.d.ts CHANGED
@@ -2,9 +2,10 @@ import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
3
  import * as react_native from 'react-native';
4
4
  import { NativeSyntheticEvent, NativeScrollEvent } from 'react-native';
5
- import { M as MotionComponent, A as AnimatableValue, T as TransitionConfig, E as EasingInput, G as GestureLayerTransitions, S as SpringTransition, V as VariantController } from './types-NmNeJjo1.js';
6
- export { a as AnimateStyle, b as AnimationCallbackInfo, D as DecayTransition, c as GestureSubStates, d as MotionProps, N as NoAnimationTransition, P as PerPropertyTransition, R as RepeatConfig, e as SequenceStep, f as TimingTransition, g as Transition, h as VariantsMap } from './types-NmNeJjo1.js';
7
- import { SharedValue } from 'react-native-reanimated';
5
+ import { M as MotionComponent, A as AnimatableValue, T as TransitionConfig, E as EasingInput, S as SpringTransition, V as VariantController } from './types-cU43dEmH.js';
6
+ export { a as AnimateStyle, b as AnimationCallbackInfo, D as DecayTransition, G as GestureSubStates, c as MotionProps, N as NoAnimationTransition, P as PerPropertyTransition, R as RepeatConfig, d as SequenceStep, e as TimingTransition, f as Transition, g as VariantsMap } from './types-cU43dEmH.js';
7
+ import { SharedValue, useAnimatedStyle } from 'react-native-reanimated';
8
+ export { U as UseGestureHandlers, a as UseGestureResult, u as useGesture } from './useGesture-B7A_1DVg.js';
8
9
  export { MotionImage } from './motion/Image.js';
9
10
  export { MotionPressable } from './motion/Pressable.js';
10
11
  export { MotionScrollView } from './motion/ScrollView.js';
@@ -243,84 +244,68 @@ declare function buildReleaseAnimation(transition: TransitionConfig, toValue: nu
243
244
  declare function useAnimation(target: number, transition?: TransitionConfig): SharedValue<number>;
244
245
 
245
246
  /**
246
- * Handler bag returned by `useGesture`. Spread on a `Pressable` to drive the
247
- * shared values returned alongside.
247
+ * Toggle a 0↔1 progress value with a spring whenever `active` flips.
248
248
  *
249
- * Hover handlers use `Pressable`'s own `onHoverIn` / `onHoverOut` names (web
250
- * only no-ops on native). `onFocus` consults `isFocusVisible()` before
251
- * raising the keyboard-only `focusVisible` layer; `focused` always raises.
249
+ * This is the recurring shape behind checkbox checks, accordion expansions,
250
+ * drawer open/closed states, focus rings, and every other binary UI flip
251
+ * that wants spring physics rather than a hard cut. The returned shared
252
+ * value sits at `0` when `active` is `false` and animates toward `1` when
253
+ * `active` flips to `true` (and back again on the reverse flip). Feed it to
254
+ * a `useTransform`, `useShadow`, or a hand-rolled `useAnimatedStyle` to
255
+ * drive whatever the boolean controls visually.
256
+ *
257
+ * ```tsx
258
+ * const progress = useBooleanSpring(isChecked)
259
+ * const indicatorStyle = useAnimatedStyle(() => ({
260
+ * opacity: progress.value,
261
+ * transform: [{ scale: progress.value }],
262
+ * }))
263
+ * ```
264
+ *
265
+ * The spring config follows the same react-spring vocabulary as the rest of
266
+ * the library (`tension` / `friction` / `mass`); omit it to take the
267
+ * library's defaults.
252
268
  */
253
- interface UseGestureHandlers {
254
- onPressIn: () => void;
255
- onPressOut: () => void;
256
- onHoverIn: () => void;
257
- onHoverOut: () => void;
258
- onFocus: () => void;
259
- onBlur: () => void;
260
- }
261
- interface UseGestureResult {
262
- /** 0↔1 progress for the pressed layer. */
263
- pressed: SharedValue<number>;
264
- /** 0↔1 progress for the focused layer (any focus modality). */
265
- focused: SharedValue<number>;
266
- /** 0↔1 progress for the focusVisible layer (keyboard focus only). */
267
- focusVisible: SharedValue<number>;
268
- /** 0↔1 progress for the hovered layer (web only — stays at 0 on native). */
269
- hovered: SharedValue<number>;
270
- /** Handlers to spread on the receiving `Pressable`. */
271
- handlers: UseGestureHandlers;
269
+ declare function useBooleanSpring(active: boolean, springConfig?: SpringTransition): SharedValue<number>;
270
+
271
+ /**
272
+ * Color style keys understood by React Native that this hook can target.
273
+ * Sticks to the keys that exist on the v0.1 animatable surface so the
274
+ * returned style fragment is always a legal RN style.
275
+ */
276
+ type ColorStyleKey = 'backgroundColor' | 'color' | 'borderColor' | 'borderTopColor' | 'borderRightColor' | 'borderBottomColor' | 'borderLeftColor' | 'tintColor' | 'shadowColor';
277
+ interface UseColorTransitionOptions {
278
+ /**
279
+ * Which style slot the interpolated color is emitted under. Defaults to
280
+ * `backgroundColor` the dominant case for state-layer haloes, card
281
+ * fills, and chip surfaces. Override for ring colors (`borderColor`),
282
+ * text colors (`color`), image tints (`tintColor`), etc.
283
+ */
284
+ key?: ColorStyleKey;
272
285
  }
273
286
  /**
274
- * Build a gesture-layer controller. The hook-form of the `gesture` prop
275
- * reach for it when you need to drive multiple animated views from the same
276
- * gesture state (a focus ring + state-layer halo + content tint all on one
277
- * Pressable), which the prop-form's "animate the receiver's own style" model
278
- * can't express.
279
- *
280
- * Returns four 0↔1 shared values (one per layer) and a handler bag to spread
281
- * on a `Pressable`. The shared values are stable across renders — feed them
282
- * into any number of `useAnimatedStyle` blocks anywhere in the tree.
283
- *
284
- * Transitions follow the same shape as the `gesture` prop's accompanying
285
- * `transition`: pass a single `TransitionConfig` to use for every layer, or a
286
- * `GestureLayerTransitions` map to give each layer its own. Layers without an
287
- * explicit transition fall back to the library default spring.
287
+ * Interpolate a single color channel between `from` and `to` as `progress`
288
+ * moves 0→1, returning an animated style fragment that can be spread onto
289
+ * any Reanimated-aware view.
288
290
  *
289
- * Reduced motion (via `<MotionConfig reducedMotion>`) collapses every
290
- * transition to `no-animation` so state changes snap instead of interpolating
291
- * — same behaviour the gesture prop applies.
292
- *
293
- * @example
294
291
  * ```tsx
295
- * import { useAnimatedStyle } from 'react-native-reanimated'
296
- * import { useGesture } from '@onlynative/inertia'
297
- *
298
- * function Card() {
299
- * const { pressed, focused, hovered, handlers } = useGesture({
300
- * pressed: { type: 'timing', duration: 100 },
301
- * hovered: { type: 'timing', duration: 150 },
302
- * focused: { type: 'timing', duration: 200 },
303
- * })
304
- *
305
- * const ringStyle = useAnimatedStyle(() => ({ opacity: focused.value }))
306
- * const haloStyle = useAnimatedStyle(() => ({
307
- * opacity: Math.max(
308
- * hovered.value * 0.08,
309
- * focused.value * 0.10,
310
- * pressed.value * 0.10,
311
- * ),
312
- * }))
313
- *
314
- * return (
315
- * <Pressable {...handlers}>
316
- * <Animated.View style={ringStyle} />
317
- * <Animated.View style={haloStyle} />
318
- * </Pressable>
319
- * )
320
- * }
292
+ * const progress = useBooleanSpring(isPressed)
293
+ * const fillStyle = useColorTransition(progress, [colors.surface, colors.pressed])
294
+ * const ringStyle = useColorTransition(progress, [colors.outline, colors.primary], {
295
+ * key: 'borderColor',
296
+ * })
297
+ *
298
+ * return <Motion.View style={[styles.chip, fillStyle, ringStyle]} />
321
299
  * ```
300
+ *
301
+ * This is a pure interpolator: it does not animate on its own. Drive
302
+ * `progress` upstream with a `useSpring`, `useBooleanSpring`, gesture
303
+ * progress, or scroll-derived `useTransform`. Values outside `[0, 1]`
304
+ * clamp. For a raw `SharedValue<string>` (e.g. to feed a gradient or
305
+ * compose into a hand-rolled `useAnimatedStyle`), use `useTransform`
306
+ * directly with a color output range.
322
307
  */
323
- declare function useGesture(transition?: TransitionConfig | GestureLayerTransitions): UseGestureResult;
308
+ declare function useColorTransition(progress: SharedValue<number>, range: readonly [string, string], options?: UseColorTransitionOptions): ReturnType<typeof useAnimatedStyle>;
324
309
 
325
310
  /**
326
311
  * Create an animatable value owned by JS but readable from worklets.
@@ -450,6 +435,61 @@ interface UseScrollResult {
450
435
  */
451
436
  declare function useScroll(): UseScrollResult;
452
437
 
438
+ /**
439
+ * Shape accepted on either end of a `useShadow` tween. Every field is
440
+ * optional — only keys present on at least one side participate in the
441
+ * output style. Mirrors the flat shadow keys on `Motion.View`'s `animate`
442
+ * surface, plus the nested `shadowOffset` source.
443
+ */
444
+ interface ShadowConfig {
445
+ shadowOpacity?: number;
446
+ shadowRadius?: number;
447
+ shadowOffset?: {
448
+ width?: number;
449
+ height?: number;
450
+ };
451
+ /** Android elevation. iOS shadow consumers can leave this off. */
452
+ elevation?: number;
453
+ shadowColor?: string;
454
+ }
455
+ interface UseShadowOptions {
456
+ /** Shadow state at `progress === 0`. */
457
+ from: ShadowConfig;
458
+ /** Shadow state at `progress === 1`. */
459
+ to: ShadowConfig;
460
+ /**
461
+ * Driver — typically 0→1. Whatever produces it (a `useSpring`, a gesture
462
+ * progress value, a scroll-derived `useTransform`) is the caller's
463
+ * concern. The hook is a pure interpolator; it does not animate on its
464
+ * own. Values outside `[0, 1]` clamp.
465
+ */
466
+ progress: SharedValue<number>;
467
+ }
468
+ /**
469
+ * Interpolate between two shadow configs as `progress` moves 0→1, returning
470
+ * an animated style fragment that can be spread onto any Reanimated-aware
471
+ * view (including `Motion.*` primitives and a hand-rolled `Animated.View`).
472
+ *
473
+ * ```tsx
474
+ * const progress = useSpring(isElevated ? 1 : 0)
475
+ * const shadowStyle = useShadow({
476
+ * from: { shadowOpacity: 0.08, shadowRadius: 2, shadowOffset: { width: 0, height: 1 }, elevation: 1 },
477
+ * to: { shadowOpacity: 0.24, shadowRadius: 12, shadowOffset: { width: 0, height: 8 }, elevation: 8 },
478
+ * progress,
479
+ * })
480
+ *
481
+ * return <Motion.View style={[styles.card, shadowStyle]} />
482
+ * ```
483
+ *
484
+ * Only keys present on either `from` or `to` are emitted. A key present on
485
+ * one side and absent on the other tweens from the present value to the
486
+ * absent side's natural zero (`0` for numbers, `'transparent'` for
487
+ * `shadowColor`, `{ width: 0, height: 0 }` for `shadowOffset`). This is a
488
+ * pure interpolator — to "animate" the shadow, drive `progress` with a
489
+ * spring, timing, or gesture upstream.
490
+ */
491
+ declare function useShadow({ from, to, progress, }: UseShadowOptions): ReturnType<typeof useAnimatedStyle>;
492
+
453
493
  /**
454
494
  * Build a controller for a variants map. The controller is the imperative
455
495
  * escape hatch — pass it to a Motion primitive via `controller={...}` and
@@ -463,4 +503,4 @@ declare function useScroll(): UseScrollResult;
463
503
  */
464
504
  declare function useVariants<V extends Readonly<Record<string, object>>>(variants: V, initial?: keyof V & string): VariantController<keyof V & string>;
465
505
 
466
- export { AnimatableValue, type ExtrapolationMode, Motion, MotionComponent, MotionConfig, type MotionConfigValue, Presence, type PresenceContextValue, type ReducedMotion, SpringTransition, TransitionConfig, type UseGestureHandlers, type UseGestureResult, type UseScrollResult, type UseTransformOptions, VariantController, buildReleaseAnimation, createMotionComponent, ensureWorkletEasing, resolveAnimatableValue, resolveTransition, useAnimation, useGesture, useMotionConfig, useMotionValue, usePresence, useScroll, useShouldReduceMotion, useSpring, useTransform, useVariants };
506
+ export { AnimatableValue, type ColorStyleKey, type ExtrapolationMode, Motion, MotionComponent, MotionConfig, type MotionConfigValue, Presence, type PresenceContextValue, type ReducedMotion, type ShadowConfig, SpringTransition, TransitionConfig, type UseColorTransitionOptions, type UseScrollResult, type UseShadowOptions, type UseTransformOptions, VariantController, buildReleaseAnimation, createMotionComponent, ensureWorkletEasing, resolveAnimatableValue, resolveTransition, useAnimation, useBooleanSpring, useColorTransition, useMotionConfig, useMotionValue, usePresence, useScroll, useShadow, useShouldReduceMotion, useSpring, useTransform, useVariants };