cineview 0.0.1-beta

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 (128) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +102 -0
  3. package/README.zh-CN.md +102 -0
  4. package/dist/animations/animationParser.d.ts +24 -0
  5. package/dist/animations/composer.d.ts +13 -0
  6. package/dist/animations/presets/blink.d.ts +18 -0
  7. package/dist/animations/presets/blur.d.ts +18 -0
  8. package/dist/animations/presets/bounce.d.ts +18 -0
  9. package/dist/animations/presets/elastic.d.ts +23 -0
  10. package/dist/animations/presets/fade.d.ts +18 -0
  11. package/dist/animations/presets/flip.d.ts +18 -0
  12. package/dist/animations/presets/index.d.ts +38 -0
  13. package/dist/animations/presets/rotate.d.ts +23 -0
  14. package/dist/animations/presets/shake.d.ts +28 -0
  15. package/dist/animations/presets/slide.d.ts +23 -0
  16. package/dist/animations/presets/special.d.ts +38 -0
  17. package/dist/animations/presets/zoom.d.ts +23 -0
  18. package/dist/animations/registry.d.ts +51 -0
  19. package/dist/artifacts.json +40 -0
  20. package/dist/blink-BGmsrTwW.mjs +81 -0
  21. package/dist/blur-CQoB_VWp.mjs +52 -0
  22. package/dist/bounce-B_QJxgOq.mjs +64 -0
  23. package/dist/cineview-dev.css +2 -0
  24. package/dist/cineview-dev.es.mjs +2 -0
  25. package/dist/cineview-drag.umd.js +2 -0
  26. package/dist/cineview-scroll.umd.js +2 -0
  27. package/dist/cineview.es.mjs +2 -0
  28. package/dist/cineview.umd.js +2 -0
  29. package/dist/components/Animate/Animate.d.ts +67 -0
  30. package/dist/components/Animate/AnimateRenderBridge.d.ts +16 -0
  31. package/dist/components/Animate/AnimateVideo.d.ts +59 -0
  32. package/dist/components/Animate/StaggerContainer.d.ts +35 -0
  33. package/dist/components/Animate/__fixtures__/animate-media-public-path.fixture.d.ts +1 -0
  34. package/dist/components/Animate/animateInterpolation.d.ts +41 -0
  35. package/dist/components/Animate/animateRenderState.d.ts +23 -0
  36. package/dist/components/Animate/animateSemantics.d.ts +38 -0
  37. package/dist/components/Animate/animateTimeline.d.ts +14 -0
  38. package/dist/components/Animate/dragVisualState.d.ts +26 -0
  39. package/dist/components/Animate/index.d.ts +6 -0
  40. package/dist/components/Animate/useAnimateArrival.d.ts +35 -0
  41. package/dist/components/Animate/useAnimateDrag.d.ts +34 -0
  42. package/dist/components/Animate/useAnimatePublicTimeline.d.ts +16 -0
  43. package/dist/components/Animate/useAnimateScroll.d.ts +83 -0
  44. package/dist/components/Animate/useAnimatedPropertyLanes.d.ts +30 -0
  45. package/dist/components/Animate/visibilityScheduler.d.ts +12 -0
  46. package/dist/components/Cineview/Cineview.d.ts +46 -0
  47. package/dist/components/Cineview/CineviewDispatch.d.ts +2 -0
  48. package/dist/components/Cineview/DirectScrollCineview.d.ts +8 -0
  49. package/dist/components/Cineview/DragSceneStack.d.ts +55 -0
  50. package/dist/components/Cineview/ScrollSceneSlot.d.ts +42 -0
  51. package/dist/components/Cineview/ScrollSceneStack.d.ts +13 -0
  52. package/dist/components/Cineview/ScrollbarOverlay.d.ts +24 -0
  53. package/dist/components/Cineview/directScrollHelpers.d.ts +77 -0
  54. package/dist/components/Cineview/index.d.ts +5 -0
  55. package/dist/components/Cineview/preloadTargets.d.ts +18 -0
  56. package/dist/components/Cineview/regroupCallbacks.d.ts +10 -0
  57. package/dist/components/Cineview/useCineviewImperativeApi.d.ts +21 -0
  58. package/dist/components/Cineview/useNativeScrollController.d.ts +38 -0
  59. package/dist/components/Cineview/useScrollInputBindings.d.ts +9 -0
  60. package/dist/components/Cineview/useScrollSceneLayout.d.ts +24 -0
  61. package/dist/components/Cineview/useScrollSceneSnapshots.d.ts +32 -0
  62. package/dist/components/Cineview/useScrollViewport.d.ts +20 -0
  63. package/dist/components/Cineview/useScrollZoneRegistry.d.ts +35 -0
  64. package/dist/components/Container/Container.d.ts +2 -0
  65. package/dist/components/Container/index.d.ts +1 -0
  66. package/dist/components/Image/Image.d.ts +12 -0
  67. package/dist/components/Image/index.d.ts +2 -0
  68. package/dist/components/Position/Position.d.ts +13 -0
  69. package/dist/components/Position/index.d.ts +1 -0
  70. package/dist/components/Scene/Scene.d.ts +10 -0
  71. package/dist/components/Scene/SceneFixedLayer.d.ts +14 -0
  72. package/dist/components/Scene/__fixtures__/scene-grouped-public-path.fixture.d.ts +1 -0
  73. package/dist/components/Scene/dragPreparedState.d.ts +49 -0
  74. package/dist/components/Scene/helpers.d.ts +101 -0
  75. package/dist/components/Scene/index.d.ts +1 -0
  76. package/dist/components/Scene/sceneScrollBudget.d.ts +38 -0
  77. package/dist/components/Scene/sceneScrollRuntime.d.ts +65 -0
  78. package/dist/components/Scene/types.d.ts +189 -0
  79. package/dist/components/Scene/useDragSceneEngine.d.ts +67 -0
  80. package/dist/components/Scene/useElementTrack.d.ts +82 -0
  81. package/dist/components/Scene/useNativePointerDrag.d.ts +25 -0
  82. package/dist/components/Scene/useSceneAnimationRegistry.d.ts +56 -0
  83. package/dist/components/Scene/useScenePointerInput.d.ts +28 -0
  84. package/dist/components/Scene/useSceneRuntimeState.d.ts +17 -0
  85. package/dist/components/Scene/useSceneScrollTakeover.d.ts +13 -0
  86. package/dist/components/Scene/useScrollSceneEngine.d.ts +28 -0
  87. package/dist/components/runtime/runtimeContext.d.ts +14 -0
  88. package/dist/components/runtime/scrollExternalStore.d.ts +13 -0
  89. package/dist/components/runtime/scrollSceneFrameStore.d.ts +29 -0
  90. package/dist/context/CineviewContext.d.ts +25 -0
  91. package/dist/dev/PerfPanel.d.ts +16 -0
  92. package/dist/dev/index.d.ts +14 -0
  93. package/dist/dev/usePerfMonitor.d.ts +9 -0
  94. package/dist/drag-scene-engine-y8Wj9ivV.mjs +270 -0
  95. package/dist/elastic-CBP_FdRv.mjs +129 -0
  96. package/dist/element-track-Du10P12_.mjs +316 -0
  97. package/dist/entry-drag.d.ts +14 -0
  98. package/dist/entry-scroll.d.ts +14 -0
  99. package/dist/fade-DXxFsgxR.mjs +22 -0
  100. package/dist/flip-CrCoNIws.mjs +49 -0
  101. package/dist/hooks/imagePreloadCache.d.ts +4 -0
  102. package/dist/hooks/mediaPreloadCache.d.ts +31 -0
  103. package/dist/hooks/useFirstSceneEnter.d.ts +65 -0
  104. package/dist/hooks/useImagePreloader.d.ts +31 -0
  105. package/dist/hooks/usePrefersReducedMotion.d.ts +12 -0
  106. package/dist/hooks/useSceneManager.d.ts +79 -0
  107. package/dist/index.d.ts +17 -0
  108. package/dist/media/VideoFrameRenderer.d.ts +48 -0
  109. package/dist/media/videoPlaybackOwnership.d.ts +63 -0
  110. package/dist/performance-monitor-AlOOwzY_.mjs +73 -0
  111. package/dist/public-api.d.ts +12 -0
  112. package/dist/rotate-BMEBKDk5.mjs +69 -0
  113. package/dist/scene-animation-registry-8b0m_IaZ.mjs +422 -0
  114. package/dist/shake-BV6SdR9O.mjs +171 -0
  115. package/dist/slide-DWmVtj0L.mjs +63 -0
  116. package/dist/special-DDz8BopB.mjs +224 -0
  117. package/dist/types/index.d.ts +552 -0
  118. package/dist/utils/animationHelpers.d.ts +15 -0
  119. package/dist/utils/debounce.d.ts +18 -0
  120. package/dist/utils/devLog.d.ts +16 -0
  121. package/dist/utils/dragTimelineMapping.d.ts +30 -0
  122. package/dist/utils/gestureDetector.d.ts +67 -0
  123. package/dist/utils/performanceMonitor.d.ts +66 -0
  124. package/dist/utils/styleConvert.d.ts +7 -0
  125. package/dist/utils/useIsomorphicLayoutEffect.d.ts +22 -0
  126. package/dist/utils/useStructurallyStableValue.d.ts +5 -0
  127. package/dist/zoom-CuAthpqd.mjs +63 -0
  128. package/package.json +171 -0
@@ -0,0 +1,552 @@
1
+ import { HTMLAttributes, ReactElement, ReactNode } from 'react';
2
+ import { MotionValue } from 'framer-motion';
3
+ export type SlideDirection = 'x' | 'y';
4
+ export type ScrollMode = 'drag' | 'scroll';
5
+ /**
6
+ * Scene timeline phase for scroll-mode scenes. `hold` is the steady middle
7
+ * phase between enter and exit; it is NOT a virtual scroll-track coordinate.
8
+ */
9
+ export type SceneTimelinePhase = 'before' | 'enter' | 'hold' | 'exit' | 'after';
10
+ export type SceneAnchor = 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
11
+ export type SceneStackMode = 'replace' | 'cover';
12
+ export interface DragThresholdConfig {
13
+ minVelocity?: number;
14
+ maxVelocity?: number;
15
+ minRatio?: number;
16
+ maxRatio?: number;
17
+ }
18
+ export type DragTimelineUnit = 'time' | 'percent';
19
+ export interface SceneDragConfig {
20
+ /** Whether this Scene may become the target of a user drag. Defaults to true. */
21
+ enabled?: boolean;
22
+ /** Drag-distance mapping unit. Defaults to `time`. */
23
+ unit?: DragTimelineUnit;
24
+ /**
25
+ * Per-drag-percent scale. `time` means milliseconds; `percent` means percent of
26
+ * this Scene's compiled element timeline. Defaults to 10 / 1 respectively.
27
+ */
28
+ scale?: number;
29
+ }
30
+ export interface DragModeConfig {
31
+ direction?: SlideDirection;
32
+ transitionDuration?: number;
33
+ threshold?: DragThresholdConfig;
34
+ /** Root default mapping unit for Scene element timelines. */
35
+ unit?: DragTimelineUnit;
36
+ /** Root default mapping scale; interpreted according to `unit`. */
37
+ scale?: number;
38
+ firstSceneTimeout?: number;
39
+ }
40
+ export interface ScrollModeConfig {
41
+ direction?: SlideDirection;
42
+ sceneSizing?: 'content' | 'screen';
43
+ enterMargin?: number;
44
+ exitMargin?: number;
45
+ }
46
+ /**
47
+ * Accessibility configuration.
48
+ *
49
+ * Only one field exists because the other three accessibility behaviors have no
50
+ * configurable space: hiding inactive scenes from assistive technology, announcing
51
+ * scene changes via `aria-live`, and drag keyboard navigation are compliance
52
+ * requirements, not preferences. "Reduce motion" reads from system settings and
53
+ * similarly accepts no component-level override.
54
+ */
55
+ export interface A11yConfig {
56
+ /**
57
+ * Accessible name for the drag root container (`aria-label`). Defaults to `'Scenes'`.
58
+ * When multiple Cineview instances exist on one page, each must have a unique label
59
+ * so they can be distinguished in screen reader landmark lists.
60
+ */
61
+ label?: string;
62
+ }
63
+ export interface ScrollbarConfig {
64
+ enabled?: boolean;
65
+ ariaLabel?: string;
66
+ width?: number;
67
+ radius?: number;
68
+ inset?: number;
69
+ trackColor?: string;
70
+ thumbColor?: string;
71
+ /** Thumb fill on pointer hover. Defaults to `thumbColor`; does not add a border. */
72
+ thumbHoverColor?: string;
73
+ autoHide?: boolean;
74
+ }
75
+ export interface SceneChangeDetail {
76
+ fromIndex: number;
77
+ toIndex: number;
78
+ direction?: 'forward' | 'backward' | null;
79
+ }
80
+ /**
81
+ * Error codes emitted by the framework at runtime. Consumers can switch on `code`
82
+ * in `onError` to get autocomplete and exhaustiveness checking (no longer a bare string).
83
+ *
84
+ * - `EMPTY_SCENES`: Cineview has no Scene children (`context.scope` is default),
85
+ * or a Scene has no children (`context.scope === 'scene'`, includes `sceneIndex`).
86
+ * - `IMAGE_LOAD_FAILED`: Image preload failed.
87
+ * - `FIRST_SCENE_TIMEOUT`: First-screen priority resource wait timed out (recoverable, includes preventDefault).
88
+ * - `INVALID_ANIMATION`: An animation dependency, control, or scroll phase is invalid.
89
+ * - `CIRCULAR_DEPENDENCY`: Animate's after chain contains a cycle.
90
+ * - `INVALID_COMPONENT_HIERARCHY`: Duplicate animateId or authored scroll zone identity in component tree.
91
+ * - `INVALID_DRAG_CONFIG`: Drag unit / scale / enabled config is invalid (recoverable).
92
+ * - `ANIMATION_ASSET_LOAD_FAILED`: Animation preset asset load failed (retryable).
93
+ */
94
+ export type CineviewErrorCode = 'EMPTY_SCENES' | 'IMAGE_LOAD_FAILED' | 'FIRST_SCENE_TIMEOUT' | 'INVALID_ANIMATION' | 'CIRCULAR_DEPENDENCY' | 'INVALID_COMPONENT_HIERARCHY' | 'INVALID_DRAG_CONFIG' | 'ANIMATION_ASSET_LOAD_FAILED';
95
+ export interface CineviewErrorDetail {
96
+ code: CineviewErrorCode;
97
+ message: string;
98
+ context?: Record<string, unknown>;
99
+ preventDefault?: () => void;
100
+ }
101
+ export interface DragDetail {
102
+ sceneIndex: number;
103
+ progress: number;
104
+ direction?: 'forward' | 'backward' | null;
105
+ }
106
+ export interface DragStartDetail extends Omit<DragDetail, 'direction'> {
107
+ direction: 'forward' | 'backward';
108
+ }
109
+ export interface DragBlockedDetail {
110
+ fromIndex: number;
111
+ targetSceneIndex: number;
112
+ direction: 'forward' | 'backward';
113
+ }
114
+ export interface DragEndDetail extends DragDetail {
115
+ targetSceneIndex: number;
116
+ elapsedMs: number;
117
+ timelineDurationMs: number;
118
+ }
119
+ export interface ZoneDetail {
120
+ zoneId: string;
121
+ sceneIndex: number;
122
+ }
123
+ export interface ZoneProgressDetail extends ZoneDetail {
124
+ progress: number;
125
+ }
126
+ export interface SceneVisibilityDetail {
127
+ sceneIndex?: number;
128
+ visible: boolean;
129
+ progress: number;
130
+ }
131
+ export interface CineviewCommonCallbacks {
132
+ onReady?: (api: CineviewRef) => void;
133
+ onLoadProgress?: (progress: number) => void;
134
+ onSceneEnter?: (detail: SceneChangeDetail) => void;
135
+ onSceneLeave?: (detail: SceneChangeDetail) => void;
136
+ onError?: (detail: CineviewErrorDetail) => void;
137
+ }
138
+ export interface CineviewDragCallbacks {
139
+ /** Fires only after the first direction-qualified move acquires drag ownership. */
140
+ onDragStart?: (detail: DragStartDetail) => void;
141
+ onDragProgress?: (detail: DragDetail) => void;
142
+ onDragBlocked?: (detail: DragBlockedDetail) => void;
143
+ onDragEnd?: (detail: DragEndDetail) => void;
144
+ onDragCancel?: (detail: DragDetail) => void;
145
+ }
146
+ export interface CineviewScrollCallbacks {
147
+ onZoneEnter?: (detail: ZoneDetail) => void;
148
+ onZoneLeave?: (detail: ZoneDetail) => void;
149
+ onZoneProgress?: (detail: ZoneProgressDetail) => void;
150
+ onSceneVisibilityChange?: (detail: SceneVisibilityDetail) => void;
151
+ }
152
+ /**
153
+ * Flat callbacks accepted in drag mode (mode="drag" or omitted).
154
+ *
155
+ * The `[K in keyof CineviewScrollCallbacks]?: never` cross-exclusion closes a
156
+ * discrimination hole: without it, TS's excess-property check only rejects
157
+ * wrong-mode callbacks written as an INLINE object literal. A caller who first
158
+ * extracts callbacks into a variable that mixes a valid drag callback with a
159
+ * scroll-only one (e.g. `{ onDragEnd, onZoneProgress }`) would slip past the
160
+ * check, because a variable is not subject to excess-property checking and the
161
+ * weak-type check is satisfied by the shared valid key. Marking every scroll-only
162
+ * key as optional-`never` makes assigning a real function to it a type error on
163
+ * both the inline and the extracted-variable paths.
164
+ */
165
+ export type DragModeCallbacks = CineviewCommonCallbacks & CineviewDragCallbacks & {
166
+ [K in keyof CineviewScrollCallbacks]?: never;
167
+ };
168
+ /** Flat callbacks accepted in scroll mode (mode="scroll"). Mirror cross-exclusion of drag-only keys — see DragModeCallbacks. */
169
+ export type ScrollModeCallbacks = CineviewCommonCallbacks & CineviewScrollCallbacks & {
170
+ [K in keyof CineviewDragCallbacks]?: never;
171
+ };
172
+ /**
173
+ * Back-compat alias. The shape changed from the old nested
174
+ * `{ common, drag, scroll }` to the flat per-mode union, so this is a breaking
175
+ * change at the value level, but the NAME is preserved to avoid breaking
176
+ * type-only imports.
177
+ */
178
+ export type CineviewCallbacks = DragModeCallbacks | ScrollModeCallbacks;
179
+ export type PresetAnimation = 'fade' | 'fade-in' | 'fade-out' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'zoom-in' | 'zoom-out' | 'scale-up' | 'scale-down' | 'rotate' | 'rotate-in' | 'rotate-out' | 'spin' | 'flip' | 'flip-x' | 'flip-y' | 'bounce' | 'bounce-in' | 'bounce-out' | 'blink' | 'flash' | 'pulse' | 'shake' | 'shake-x' | 'shake-y' | 'vibrate' | 'jello' | 'blur-in' | 'blur-out' | 'focus-in' | 'elastic' | 'rubber-band' | 'wobble' | 'swing' | 'heartbeat' | 'tada' | 'wave' | 'roll-in' | 'roll-out' | 'hinge' | 'jack-in-the-box';
180
+ export interface ParsedAnimationVariant {
181
+ initial: Record<string, unknown>;
182
+ animate: Record<string, unknown>;
183
+ exit: Record<string, unknown>;
184
+ }
185
+ export interface CustomAnimation {
186
+ initial?: Record<string, unknown>;
187
+ animate?: Record<string, unknown>;
188
+ exit?: Record<string, unknown>;
189
+ }
190
+ export interface ComposedAnimation {
191
+ animations: (PresetAnimation | CustomAnimation)[];
192
+ mode: 'sequential' | 'parallel';
193
+ delays?: number[];
194
+ }
195
+ export type AnimationType = PresetAnimation | CustomAnimation | ComposedAnimation;
196
+ /**
197
+ * Shared Cineview props, independent of `mode`. Mode-specific fields are added
198
+ * by the per-mode branches below; the `mode`/`callbacks` pair closes the
199
+ * discriminated union so both the callback surface and the mode-specific config
200
+ * fields are constrained by the active mode.
201
+ */
202
+ export interface CineviewBaseProps {
203
+ /**
204
+ * Design viewport width baseline (design px). The single site-wide conversion
205
+ * ruler: `scale = viewportWidth / designWidth`. All design lengths (Position
206
+ * coordinates, Container box model, etc.) are multiplied by the same `scale`
207
+ * (width-only, never distorted). Scroll takeover time budget is still settled
208
+ * at `1ms = 1px`; scene absolute spans fall back to measured DOM, without
209
+ * introducing a second height ruler.
210
+ *
211
+ * Aligns with common Figma / design file standards: set to the design file
212
+ * width (default 750, standard mobile viewport), then all design px values
213
+ * are scaled to any viewport from this baseline. No separate height baseline —
214
+ * vertical overflow is left to natural document flow / scroll extension.
215
+ */
216
+ designWidth?: number;
217
+ scrollbar?: false | ScrollbarConfig;
218
+ monitor?: boolean;
219
+ /** Expose scroll layout diagnostics. Use `monitor` to sample performance and render `PerfPanel` explicitly. */
220
+ debug?: boolean;
221
+ a11y?: A11yConfig;
222
+ children: ReactNode;
223
+ }
224
+ /** Drag-branch-only config keys cannot appear on scroll root (and vice versa) — same cross-exclusion as callbacks. */
225
+ type ScrollOnlyConfigKeys = 'sceneSizing' | 'enterMargin' | 'exitMargin';
226
+ type DragOnlyConfigKeys = 'transitionDuration' | 'threshold' | 'unit' | 'scale' | 'firstSceneTimeout';
227
+ /**
228
+ * Cineview drag branch Props: `mode` defaults to drag. Mode-specific fields are
229
+ * flattened at root level (no `modes.drag` wrapper); scroll-specific fields are
230
+ * excluded as `never`.
231
+ */
232
+ export type CineviewDragModeProps = CineviewBaseProps & DragModeConfig & {
233
+ mode?: 'drag';
234
+ callbacks?: DragModeCallbacks;
235
+ } & {
236
+ [K in ScrollOnlyConfigKeys]?: never;
237
+ };
238
+ /**
239
+ * Cineview scroll branch Props: scroll-specific fields are flattened at root
240
+ * level (no `modes.scroll` wrapper); drag-specific fields are excluded as `never`.
241
+ */
242
+ export type CineviewScrollModeProps = CineviewBaseProps & ScrollModeConfig & {
243
+ mode: 'scroll';
244
+ callbacks?: ScrollModeCallbacks;
245
+ } & {
246
+ [K in DragOnlyConfigKeys]?: never;
247
+ };
248
+ /**
249
+ * Cineview component Props — discriminated on `mode`. Drag mode (the default when
250
+ * `mode` is omitted) accepts common + drag callbacks and flat drag config
251
+ * fields; scroll mode accepts common + scroll callbacks and flat scroll config
252
+ * fields. Passing a callback or config field from the wrong mode is a type
253
+ * error (TS excess-property check on the flat objects).
254
+ */
255
+ export type CineviewProps = CineviewDragModeProps | CineviewScrollModeProps;
256
+ /**
257
+ * Performance metrics for monitoring runtime behavior.
258
+ */
259
+ export interface PerformanceMetrics {
260
+ fps: number;
261
+ avgFrameTime: number;
262
+ memoryUsage?: number;
263
+ bundleSize: number;
264
+ }
265
+ /**
266
+ * Scene asset preload target.
267
+ * - number: zero-based scene index
268
+ * - string: Scene.sceneId; in scroll mode it can also match Scene.scroll.zoneId
269
+ */
270
+ export type CineviewPreloadTarget = number | string;
271
+ /**
272
+ * Cineview Ref methods.
273
+ *
274
+ * These 5 methods exist in both drag and scroll modes, so they are required —
275
+ * call sites no longer need `ref.current?.refreshLayout?.()` per-method null checks.
276
+ * `goToZone` is scroll-mode-only (drag mode has no zone concept), so it remains optional;
277
+ * scroll consumers can switch to {@link CineviewScrollRef} for a view with `goToZone` required.
278
+ */
279
+ export interface CineviewRef {
280
+ goToScene: (index: number, animated?: boolean) => void;
281
+ refreshLayout: () => void;
282
+ preload: (targets?: CineviewPreloadTarget[]) => Promise<void>;
283
+ getCurrentIndex: () => number;
284
+ getPerformanceMetrics: () => PerformanceMetrics;
285
+ /** Scroll mode only: jump to specified zone. Not available in drag mode. */
286
+ goToZone?: (zoneId: string, options?: {
287
+ animated?: boolean;
288
+ }) => void;
289
+ }
290
+ /**
291
+ * Cineview Ref in scroll mode — `goToZone` is required here.
292
+ * Usage: `const ref = useRef<CineviewScrollRef>(null)`, with `mode="scroll"`.
293
+ */
294
+ export interface CineviewScrollRef extends CineviewRef {
295
+ goToZone: (zoneId: string, options?: {
296
+ animated?: boolean;
297
+ }) => void;
298
+ }
299
+ /**
300
+ * Scene component Props
301
+ */
302
+ export interface SceneProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
303
+ sceneId?: string;
304
+ layout?: {
305
+ width?: number | string;
306
+ /** Content-box CSS height; drag navigation remains fixed at one viewport. */
307
+ height?: number | string;
308
+ anchor?: SceneAnchor;
309
+ overflow?: 'hidden' | 'visible' | 'clip';
310
+ /**
311
+ * Stacking strategy (formerly `stack.mode`): which scene acts as background
312
+ * when this scene and adjacent scenes share the screen.
313
+ * Defaults to 'replace' in drag mode, 'cover' in scroll mode.
314
+ */
315
+ overlap?: SceneStackMode;
316
+ /** Stacking z-order (formerly `stack.zIndex`). */
317
+ zIndex?: number;
318
+ };
319
+ transition?: {
320
+ enterAnimation?: AnimationType;
321
+ exitAnimation?: AnimationType;
322
+ exitDuration?: number;
323
+ };
324
+ assets?: {
325
+ preloadImages?: string[];
326
+ };
327
+ drag?: SceneDragConfig;
328
+ scroll?: {
329
+ zoneId?: string;
330
+ };
331
+ callbacks?: {
332
+ onVisibilityChange?: (detail: SceneVisibilityDetail) => void;
333
+ };
334
+ children: ReactNode;
335
+ }
336
+ /**
337
+ * Animate component Props
338
+ */
339
+ interface AnimateBaseProps {
340
+ animateId?: string;
341
+ exitAnimation?: AnimationType;
342
+ duration?: {
343
+ enter?: number;
344
+ exit?: number;
345
+ };
346
+ timeline?: {
347
+ /**
348
+ * Timeline driver. Defaults to `'scene'` (graceful inference):
349
+ *
350
+ * - **`'scene'` + inside a `Scene` with `scroll` takeover config (inherits zoneId)** → driven by
351
+ * that zone's real scroll budget (progressPx), works with `phase` (scroll takeover).
352
+ * - **`'scene'` + scroll mode but not inside a zone** → gracefully degrades to visibility gate,
353
+ * triggered by element entering/exiting viewport.
354
+ * - **`'scene'` + drag mode** → driven by Scene's shared element timeline.
355
+ * - **`'clock'` + scroll mode** → forces independent visibility gate, not taken over by zone even when inside one.
356
+ * - **`'clock'` + drag mode** → after Scene officially arrives, plays independently on real clock;
357
+ * does not participate in Scene registry, `after`, or `T_self`, and ignores `exitAnimation`.
358
+ */
359
+ driver?: 'scene' | 'clock';
360
+ delay?: number;
361
+ /** Start after the referenced animateId finishes entering, then apply delay. */
362
+ after?: string;
363
+ phase?: {
364
+ start?: number;
365
+ end?: number;
366
+ };
367
+ };
368
+ visibility?: {
369
+ /** Whether to replay enter animation when element re-enters (formerly `replay`, defaults to true). */
370
+ replay?: boolean;
371
+ enterMargin?: number;
372
+ exitMargin?: number;
373
+ };
374
+ /**
375
+ * Exposes enter trigger function for manual enter timing control (e.g., show content
376
+ * immediately on async event success).
377
+ *
378
+ * **Behavior rules:**
379
+ * - **Calling `enterRef.current()`**: plays enter animation immediately, interrupting any pending `after`/`delay`.
380
+ * - **Passed `enterRef` + passed `timeline.after/delay`**: if user doesn't call ref, framework will
381
+ * **fallback trigger** enter after `after`/`delay` completes.
382
+ * - **Passed `enterRef`, but no `after/delay`**: never auto-triggers, must manually call `enterRef.current()` to enter.
383
+ *
384
+ * **Typical use:** Show content immediately on API success, rely on `delay` fallback on failure.
385
+ *
386
+ * @example
387
+ * ```tsx
388
+ * const contentEnterRef = useRef<(() => void) | null>(null);
389
+ *
390
+ * useEffect(() => {
391
+ * fetch('/api/data')
392
+ * .then(data => {
393
+ * setContent(data);
394
+ * contentEnterRef.current?.(); // success → show immediately
395
+ * })
396
+ * .catch(() => {
397
+ * // failure → don't call ref, wait 3s fallback trigger
398
+ * });
399
+ * }, []);
400
+ *
401
+ * <Animate
402
+ * enterRef={contentEnterRef}
403
+ * timeline={{ delay: 3000 }} // fallback: show after 3s regardless
404
+ * enterAnimation="fade-in"
405
+ * >
406
+ * {content || <EmptyState />}
407
+ * </Animate>
408
+ * ```
409
+ */
410
+ enterRef?: React.MutableRefObject<(() => void) | null>;
411
+ /**
412
+ * Exposes exit trigger function for manual exit timing control.
413
+ *
414
+ * **Behavior rules:**
415
+ * - **Passed `exitRef`**: disables framework's auto-exit mechanism (scroll leaving zone / drag switching scene),
416
+ * must manually call `exitRef.current()` to exit.
417
+ * - **Calling `exitRef.current()`**: plays exit animation immediately, interrupting any pending enter (if any).
418
+ *
419
+ * **Note:** `exitRef` does not support `timeline.delay` fallback mechanism (exit has no "timeout then auto-exit" semantics).
420
+ *
421
+ * @example
422
+ * ```tsx
423
+ * const modalExitRef = useRef<(() => void) | null>(null);
424
+ *
425
+ * <Animate
426
+ * exitRef={modalExitRef}
427
+ * enterAnimation="fade-in"
428
+ * exitAnimation="fade-out"
429
+ * >
430
+ * <Modal onClose={() => modalExitRef.current?.()} />
431
+ * </Animate>
432
+ * ```
433
+ */
434
+ exitRef?: React.MutableRefObject<(() => void) | null>;
435
+ }
436
+ export interface AnimateStaggerConfig {
437
+ each?: number;
438
+ from?: 'first' | 'last' | 'center';
439
+ }
440
+ type EnterAnimationRequired = {
441
+ enterAnimation: AnimationType;
442
+ loopAnimation?: AnimationType;
443
+ };
444
+ type LoopOnly = {
445
+ enterAnimation?: never;
446
+ loopAnimation: AnimationType;
447
+ };
448
+ export type AnimateProps = (AnimateBaseProps & EnterAnimationRequired & {
449
+ /**
450
+ * Staggered enter choreography for child elements. When set, each **direct child**
451
+ * of `children` is revealed sequentially by framer's native `staggerChildren`,
452
+ * using `enterAnimation`'s variants (bypasses enter/exit's 10-property whitelist,
453
+ * can animate any framer-animatable property like `clipPath`/`width`).
454
+ *
455
+ * Time-driven, does not scrub with scroll/drag (for scrub-based per-element reveal,
456
+ * use render-prop `enterProgress` instead). Used for visibility enter: typewriter,
457
+ * list cascade, letter wave, etc.
458
+ */
459
+ stagger: AnimateStaggerConfig;
460
+ children: ReactElement;
461
+ }) | (AnimateBaseProps & (EnterAnimationRequired | LoopOnly) & {
462
+ stagger?: never;
463
+ children: ReactNode | ((state: AnimateRenderState) => ReactNode);
464
+ });
465
+ /**
466
+ * Render-prop children receives animation state. Progress naturally follows
467
+ * current timeline source: visibility advances by time, scroll/drag scrubs
468
+ * with scroll/drag.
469
+ */
470
+ export interface AnimateRenderState {
471
+ enterProgress: number;
472
+ phase: 'idle' | 'waiting' | 'entering' | 'entered' | 'exiting' | 'exited';
473
+ }
474
+ export type AnimatePhase = AnimateRenderState['phase'];
475
+ export type AnimateTimelineLane = 'drag' | 'scroll' | 'visibility';
476
+ export type AnimateTimelineSource = 'idle' | 'gesture' | 'continuation' | 'programmatic' | 'scroll' | 'visibility';
477
+ export interface AnimateTimelineFrame {
478
+ progress: number;
479
+ signedProgress: number;
480
+ phase: AnimatePhase;
481
+ source: AnimateTimelineSource;
482
+ }
483
+ /**
484
+ * Stable, read-only zero-render view of the nearest Animate timeline.
485
+ * MotionValue updates bypass React rendering; the object exposes no writer.
486
+ */
487
+ export interface AnimateTimeline {
488
+ readonly mode: ScrollMode;
489
+ /** Public-side timeline.driver normalized to runtime lane ('drag' | 'scroll' | 'visibility'). */
490
+ readonly lane: AnimateTimelineLane;
491
+ readonly progress: MotionValue<number>;
492
+ readonly signedProgress: MotionValue<number>;
493
+ readonly phase: MotionValue<AnimatePhase>;
494
+ /** Atomic progress/phase/ownership snapshot for imperative consumers. */
495
+ readonly frame: MotionValue<AnimateTimelineFrame>;
496
+ }
497
+ export interface ScrollTimelineState {
498
+ phase: SceneTimelinePhase;
499
+ enterProgress: number;
500
+ exitProgress: number;
501
+ sceneProgress: number;
502
+ rangeStart: number;
503
+ rangeEnd: number;
504
+ rangeLength: number;
505
+ enterLength: number;
506
+ exitLength: number;
507
+ }
508
+ /**
509
+ * Position component Props
510
+ */
511
+ export interface PositionProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'style' | 'className'> {
512
+ at?: {
513
+ x?: number;
514
+ y?: number;
515
+ offsetX?: number;
516
+ offsetY?: number;
517
+ /**
518
+ * Centering anchor. When set, element centers relative to viewport without
519
+ * manually writing `translate(-50%)`:
520
+ * - `'center'`: horizontal + vertical centering
521
+ * - `'center-x'`: horizontal centering only (`y` remains absolute design coordinate)
522
+ * - `'center-y'`: vertical centering only (`x` remains absolute design coordinate)
523
+ *
524
+ * After centering, `x` / `y` become "offset from center" (design px, converted via
525
+ * single-ruler `scale`): e.g. `anchor: 'center', x: 0, y: -100` means horizontally
526
+ * centered, vertically centered then moved up 100. The centered axis ignores
527
+ * `offsetX` / `offsetY` relative positioning chain.
528
+ */
529
+ anchor?: 'center' | 'center-x' | 'center-y';
530
+ };
531
+ /** Scene-scoped fixed layer mount (former `layer: { fixed: true }` wrapper removed). */
532
+ fixed?: boolean;
533
+ children: ReactNode;
534
+ style?: React.CSSProperties;
535
+ className?: string;
536
+ }
537
+ /**
538
+ * Container component Props — px2vw box model conversion container.
539
+ * width/height and all length values inside style (padding/margin/gap/borderRadius/fontSize/...)
540
+ * are converted from design px via single-ruler `convert`.
541
+ */
542
+ export interface ContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'style' | 'className'> {
543
+ width?: number;
544
+ height?: number;
545
+ children: ReactNode;
546
+ style?: React.CSSProperties;
547
+ className?: string;
548
+ }
549
+ export type GestureType = 'swipe-up' | 'swipe-down' | 'swipe-left' | 'swipe-right' | 'none';
550
+ export declare const DEFAULT_SLIDE_DURATION = 800;
551
+ export declare const DEFAULT_ANIMATION_DURATION = 600;
552
+ export {};
@@ -0,0 +1,15 @@
1
+ import { CineviewErrorCode, ParsedAnimationVariant, CustomAnimation, ComposedAnimation } from '../types';
2
+ import { PresetAnimation } from '../animations/presets';
3
+ export interface AnimationParseFailure {
4
+ code: Extract<CineviewErrorCode, 'INVALID_ANIMATION' | 'ANIMATION_ASSET_LOAD_FAILED'>;
5
+ message: string;
6
+ context: Record<string, unknown>;
7
+ }
8
+ /**
9
+ * Parse animation with error handling
10
+ */
11
+ export declare function parseAnimationSafely(animation: string | CustomAnimation | ComposedAnimation | undefined, componentId: string, animationType: 'enter' | 'exit' | 'loop', onFailure?: (failure: AnimationParseFailure) => void): Promise<ParsedAnimationVariant | PresetAnimation | null>;
12
+ /**
13
+ * Interpolate between two animation variants based on progress
14
+ */
15
+ export declare function interpolateVariant(start: Record<string, unknown>, end: Record<string, unknown>, progress: number): Record<string, unknown>;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Debounce function
3
+ * Executes the function only after no further calls within the specified time
4
+ * @param fn - Function to debounce
5
+ * @param delay - Delay time in milliseconds
6
+ * @returns Debounced function
7
+ */
8
+ export declare function debounce<T extends (...args: never[]) => unknown>(fn: T, delay: number): (...args: Parameters<T>) => void;
9
+ /**
10
+ * Cancelable debounce function
11
+ * @param fn - Function to debounce
12
+ * @param delay - Delay time in milliseconds
13
+ * @returns Object containing the debounced function and cancel function
14
+ */
15
+ export declare function debounceCancelable<T extends (...args: never[]) => unknown>(fn: T, delay: number): {
16
+ debounced: (...args: Parameters<T>) => void;
17
+ cancel: () => void;
18
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Development logging utility: outputs only when `NODE_ENV === 'development'`, silent in production.
3
+ *
4
+ * Background: the animations layer historically had raw `console.warn/error` calls scattered throughout
5
+ * (no NODE_ENV guard). While `esbuild.drop:['console']` removes console calls from production bundles,
6
+ * dev builds and SSR scenarios that depend on the library source still log. This utility centralizes
7
+ * the gate, aligning with existing guard patterns in context/Scene modules.
8
+ *
9
+ * Uniform prefix `[Cineview]` for consistency with other developer-facing diagnostic messages.
10
+ */
11
+ export declare function devWarn(...args: unknown[]): void;
12
+ export declare function devError(...args: unknown[]): void;
13
+ /** Cross-instance deduplicated devWarn: warns once per key across the entire session, replacing per-module once flags. */
14
+ export declare function devWarnOnce(key: string, ...args: unknown[]): void;
15
+ /** Cross-instance deduplicated devError: same semantics as devWarnOnce. */
16
+ export declare function devErrorOnce(key: string, ...args: unknown[]): void;
@@ -0,0 +1,30 @@
1
+ import { DragModeConfig, DragTimelineUnit, SceneDragConfig } from '../types';
2
+ export declare const DEFAULT_DRAG_TIMELINE_UNIT: DragTimelineUnit;
3
+ export declare const DEFAULT_DRAG_TIMELINE_SCALE: {
4
+ readonly time: 10;
5
+ readonly percent: 1;
6
+ };
7
+ export declare const DEFAULT_DRAG_TIMELINE_CONFIG: ResolvedDragTimelineConfig;
8
+ export interface ResolvedDragTimelineConfig {
9
+ unit: DragTimelineUnit;
10
+ scale: number;
11
+ }
12
+ export type InvalidDragTimelineField = 'unit' | 'scale';
13
+ export interface InvalidDragTimelineConfig {
14
+ field: InvalidDragTimelineField;
15
+ value: unknown;
16
+ }
17
+ export interface ResolvedDragTimelineMapping extends ResolvedDragTimelineConfig {
18
+ msPerDragPercent: number;
19
+ map: (dragPercent: number) => number;
20
+ }
21
+ /**
22
+ * Resolves the authored root/Scene mapping as one group. A Scene that provides
23
+ * either `unit` or `scale` stops inheriting the root mapping; its omitted field
24
+ * falls back to the framework default for the resolved unit.
25
+ */
26
+ export declare function resolveDragTimelineConfig(root: Pick<DragModeConfig, 'unit' | 'scale'> | undefined, scene?: SceneDragConfig, onInvalid?: (issue: InvalidDragTimelineConfig) => void): ResolvedDragTimelineConfig;
27
+ /** Allocation-free authoritative drag-percent → element-elapsed conversion. */
28
+ export declare function mapDragPercentToElapsed(config: ResolvedDragTimelineConfig, timelineDurationMs: number, dragPercent: number): number;
29
+ /** Creates the diagnostic/readable mapping object outside animation hot paths. */
30
+ export declare function createDragTimelineMapping(config: ResolvedDragTimelineConfig, timelineDurationMs: number): ResolvedDragTimelineMapping;