@unrulysystems/native-motion 0.1.0-alpha.0
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.
- package/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +55 -0
- package/android/build.gradle +24 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/com/unrulysystems/nativemotion/GestureExclusionModule.kt +55 -0
- package/android/src/main/java/com/unrulysystems/nativemotion/NativeMotionPackage.kt +27 -0
- package/package.json +57 -0
- package/react-native.config.js +14 -0
- package/src/native/driver/instantWindow.ts +31 -0
- package/src/native/driver/strictModeReplay.ts +20 -0
- package/src/native/driver/uiLayoutEngine.ts +845 -0
- package/src/native/driver/uiLayoutGraph.ts +338 -0
- package/src/native/driver/uiValueChannel.ts +4640 -0
- package/src/native/driver/workletDriver.ts +3860 -0
- package/src/native/motion/AnimatePresence.tsx +1605 -0
- package/src/native/motion/LayoutGroup.tsx +163 -0
- package/src/native/motion/MotionConfig.tsx +400 -0
- package/src/native/motion/MotionRoot.tsx +250 -0
- package/src/native/motion/MotionView.tsx +6761 -0
- package/src/native/motion/addScaleCorrector.ts +97 -0
- package/src/native/motion/colorEndpointUiFeed.ts +32 -0
- package/src/native/motion/colorProjection.ts +39 -0
- package/src/native/motion/composeTransform.ts +271 -0
- package/src/native/motion/constraintMeasure.ts +157 -0
- package/src/native/motion/deferredPendingSnapshots.ts +25 -0
- package/src/native/motion/discreteProjection.ts +36 -0
- package/src/native/motion/dragAncestorPanContext.ts +28 -0
- package/src/native/motion/dragControls.ts +152 -0
- package/src/native/motion/dragGestureWiring.ts +1168 -0
- package/src/native/motion/dragHandoffBinding.ts +179 -0
- package/src/native/motion/dragHubStream.ts +756 -0
- package/src/native/motion/dragPropagationLock.ts +57 -0
- package/src/native/motion/driverValueChannel.ts +3288 -0
- package/src/native/motion/externalDragDriver.ts +214 -0
- package/src/native/motion/frameData.ts +31 -0
- package/src/native/motion/gestureBinding.ts +107 -0
- package/src/native/motion/gestureStateGate.ts +563 -0
- package/src/native/motion/gestureStateResolver.ts +286 -0
- package/src/native/motion/identityValueChannelControllerAdapter.ts +2043 -0
- package/src/native/motion/identityValueChannelControllerReconciliation.ts +176 -0
- package/src/native/motion/identityValueChannelLaneMarker.ts +14 -0
- package/src/native/motion/imperativeAnimate.ts +816 -0
- package/src/native/motion/keyframeTiming.ts +7 -0
- package/src/native/motion/layoutIdBinding.ts +261 -0
- package/src/native/motion/layoutIdFlightConfig.ts +51 -0
- package/src/native/motion/layoutProjection.ts +89 -0
- package/src/native/motion/layoutScroll.ts +204 -0
- package/src/native/motion/layoutTransition.ts +1302 -0
- package/src/native/motion/lengthLayoutContext.tsx +100 -0
- package/src/native/motion/lengthLayoutHost.ts +44 -0
- package/src/native/motion/mappedKeys.ts +184 -0
- package/src/native/motion/motionViewController.ts +3180 -0
- package/src/native/motion/nativeHostMarker.ts +22 -0
- package/src/native/motion/panSessionWiring.ts +127 -0
- package/src/native/motion/pathTransition.ts +101 -0
- package/src/native/motion/popLayout.ts +176 -0
- package/src/native/motion/presenceBinding.ts +382 -0
- package/src/native/motion/scaleCorrectorRegistry.ts +123 -0
- package/src/native/motion/scrollValues.ts +260 -0
- package/src/native/motion/serializablePayload.ts +151 -0
- package/src/native/motion/severity.ts +16 -0
- package/src/native/motion/shippedSurface.ts +843 -0
- package/src/native/motion/staticLengthGate.ts +86 -0
- package/src/native/motion/styleBaseGate.ts +72 -0
- package/src/native/motion/styleValueBinding.ts +657 -0
- package/src/native/motion/systemGestureExclusion.ts +61 -0
- package/src/native/motion/tapGestureWiring.ts +215 -0
- package/src/native/motion/transformOrder.ts +38 -0
- package/src/native/motion/transformStringBinding.ts +200 -0
- package/src/native/motion/transformTemplateGate.ts +45 -0
- package/src/native/motion/transitionGate.ts +435 -0
- package/src/native/motion/useAnimate.ts +52 -0
- package/src/native/motion/useCycle.ts +44 -0
- package/src/native/motion/useInstantTransition.ts +68 -0
- package/src/native/motion/useReducedMotion.ts +58 -0
- package/src/native/motion/useScroll.ts +162 -0
- package/src/native/motion/useViewportScroll.ts +29 -0
- package/src/native/motion/valueChannel.ts +7121 -0
- package/src/native/motion/valueHooks.ts +901 -0
- package/src/native/motion/variantChildRegistry.ts +67 -0
- package/src/native/motion/variantContext.tsx +172 -0
- package/src/native/motion/variantProps.ts +598 -0
- package/src/native.ts +159 -0
- package/src/verification/harnessMetrics.ts +78 -0
- package/src/verification/probe/LayoutIdentityWorkletProbe.tsx +251 -0
- package/src/verification/probe/WorkletParityProbe.tsx +162 -0
- package/src/verification/probe/layoutIdentityProbeEngine.ts +429 -0
- package/src/verification/screens/ArcPathChecksScreen.tsx +273 -0
- package/src/verification/screens/BooleanAnimateChecksScreen.tsx +358 -0
- package/src/verification/screens/ChoreographyGalleryScreen.tsx +1010 -0
- package/src/verification/screens/ColorBindingChecksScreen.tsx +568 -0
- package/src/verification/screens/CompletionChecksScreen.tsx +294 -0
- package/src/verification/screens/ConformanceScreen.tsx +573 -0
- package/src/verification/screens/ContentionProbeScreen.tsx +224 -0
- package/src/verification/screens/DriverSmokeScreen.tsx +99 -0
- package/src/verification/screens/DurationOnlyTweenChecksScreen.tsx +294 -0
- package/src/verification/screens/DynamicDragConfigChecksScreen.tsx +237 -0
- package/src/verification/screens/FrameDataChecksScreen.tsx +252 -0
- package/src/verification/screens/GestureChecksScreen.tsx +685 -0
- package/src/verification/screens/InstantTransitionChecksScreen.tsx +839 -0
- package/src/verification/screens/LayoutAnimationStartChecksScreen.tsx +648 -0
- package/src/verification/screens/LayoutChecksScreen.tsx +822 -0
- package/src/verification/screens/LayoutCommitSpikeScreen.tsx +142 -0
- package/src/verification/screens/MotionViewChecksScreen.tsx +930 -0
- package/src/verification/screens/PresenceChecksScreen.tsx +614 -0
- package/src/verification/screens/ReducedMotionChecksScreen.tsx +614 -0
- package/src/verification/screens/RestThresholdChecksScreen.tsx +634 -0
- package/src/verification/screens/ScaleCorrectorChecksScreen.tsx +425 -0
- package/src/verification/screens/SharedLayoutContinuityChecksScreen.tsx +338 -0
- package/src/verification/screens/SharedLayoutCrossfadeChecksScreen.tsx +425 -0
- package/src/verification/screens/TransitionDefaultSelectionChecksScreen.tsx +514 -0
- package/src/verification/screens/ViewportScrollAliasChecksScreen.tsx +303 -0
- package/src/verification/screens/conformanceBanner.ts +21 -0
- package/src/verification/screens/proofConsoleTap.ts +18 -0
- package/src/verification.ts +47 -0
- package/src/web.ts +98 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// REQ-GESTURE-024 / REQ-API-041 (R15 D1, reviews 4af62c2d1b77 + round-9 + round-10) — the
|
|
2
|
+
// drag-ancestor pan channel. Each drag-carrying MotionView provides its Pan recognizer, its
|
|
3
|
+
// own dragPropagation flag, and its drag axes to descendants; the nearest child composes
|
|
4
|
+
// `simultaneousWithExternalGesture` against the ancestor's pan whenever both recognizers must
|
|
5
|
+
// be able to activate on one stream: either side propagates (the carrier skips the lock for
|
|
6
|
+
// itself — parent or child), OR the nested pair's axis sets are DISJOINT (the pin's per-axis
|
|
7
|
+
// lock permits an orthogonal pair concurrently, and RNGH's competing-arbitration must not
|
|
8
|
+
// cancel one side before the JS lock policy runs — review round-10 major). A same-axis
|
|
9
|
+
// default pair stays competing: the per-axis lock arbitrates it. Non-drag hosts pass the
|
|
10
|
+
// inherited value through unchanged.
|
|
11
|
+
|
|
12
|
+
import { createContext, useContext } from 'react'
|
|
13
|
+
import type { PanGesture } from 'react-native-gesture-handler'
|
|
14
|
+
import type { DragAxis } from '@unrulysystems/native-motion-core'
|
|
15
|
+
|
|
16
|
+
export interface DragAncestorPanEntry {
|
|
17
|
+
readonly pan: PanGesture
|
|
18
|
+
readonly propagation: boolean
|
|
19
|
+
readonly axes: readonly DragAxis[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DragAncestorPanContext = createContext<DragAncestorPanEntry | null>(null)
|
|
23
|
+
|
|
24
|
+
export function useDragAncestorPan(): DragAncestorPanEntry | null {
|
|
25
|
+
return useContext(DragAncestorPanContext)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const DragAncestorPanProvider = DragAncestorPanContext.Provider
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// REQ-GESTURE-026 / REQ-API-043 (R15 D3) — the imperative DragControls hub.
|
|
2
|
+
// Pin: motion/packages/framer-motion/src/gestures/drag/use-drag-controls.ts
|
|
3
|
+
//
|
|
4
|
+
// A hub fans out start/cancel/stop to every subscribed draggable (the pin's Set broadcast).
|
|
5
|
+
// Each subscriber is the element-local session controller; the hub never owns motion values.
|
|
6
|
+
// Native Finding 8 maps the pin's per-element window PanSession to ONE MotionRoot stream:
|
|
7
|
+
// concurrent multi-subscriber hub start is last-writer-wins on that stream (documented;
|
|
8
|
+
// product rows use one draggable per hub). Cancel/stop still fan out to every subscriber.
|
|
9
|
+
// `useDragControls` returns a lifetime-constant hub instance (pin useConstant).
|
|
10
|
+
//
|
|
11
|
+
// start(event, options) semantics (pin VisualElementDragControls.start):
|
|
12
|
+
// - snapToCursor (default false): re-seat each axis so the grab point is the element center
|
|
13
|
+
// (sanctioned G-INV-2 jump at start-invocation only)
|
|
14
|
+
// - distanceThreshold (default 3): movement gate before the session activates (PanSession)
|
|
15
|
+
//
|
|
16
|
+
// cancel() maps to REQ-GESTURE-018 (pre-grab return). The pin's bare cancel leaves the value
|
|
17
|
+
// unsettled — native-motion applies settle-totality (G-INV-7) via the handoff cancel path; a
|
|
18
|
+
// settle-totality divergence is recorded if product walks ever require pin-identical bare cancel.
|
|
19
|
+
// stop() = cancel + release animation from the latest event/info when args are omitted.
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
validateDragControlOptions,
|
|
23
|
+
type DragControlOptions as CoreDragControlOptions,
|
|
24
|
+
} from '@unrulysystems/native-motion-core'
|
|
25
|
+
import { useRef } from 'react'
|
|
26
|
+
|
|
27
|
+
/** Options accepted by `DragControls.start` (pin DragControlOptions). */
|
|
28
|
+
export type DragControlOptions = CoreDragControlOptions
|
|
29
|
+
|
|
30
|
+
/** Re-export shared start-options validator (G-INV-8; seal review r6/r7; core single-source). */
|
|
31
|
+
export { validateDragControlOptions }
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The element-local session controller a View registers with a hub.
|
|
35
|
+
* Implemented by the drag wiring / MotionView subscription — never by product code.
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export interface DragControlsSubscriber {
|
|
39
|
+
start(event: unknown, options?: DragControlOptions): void
|
|
40
|
+
cancel(): void
|
|
41
|
+
stop(): void
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Imperative drag hub — start/cancel/stop every subscribed drag-enabled View.
|
|
46
|
+
*
|
|
47
|
+
* ```tsx
|
|
48
|
+
* const dragControls = useDragControls()
|
|
49
|
+
* function startDrag(event: unknown) {
|
|
50
|
+
* dragControls.start(event, { snapToCursor: true })
|
|
51
|
+
* }
|
|
52
|
+
* return (
|
|
53
|
+
* <>
|
|
54
|
+
* <Pressable onPressIn={startDrag} />
|
|
55
|
+
* <View drag="x" dragControls={dragControls} dragListener={false} />
|
|
56
|
+
* </>
|
|
57
|
+
* )
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
export class DragControls {
|
|
63
|
+
private readonly subscribers = new Set<DragControlsSubscriber>()
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Subscribe a component's internal session controller. Returns the unsubscribe.
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
subscribe(controls: DragControlsSubscriber): () => void {
|
|
70
|
+
this.subscribers.add(controls)
|
|
71
|
+
return () => {
|
|
72
|
+
this.subscribers.delete(controls)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Start a drag on every subscribed View using the originating event's pointer position.
|
|
78
|
+
* Fail-loud when no View is subscribed — a silent no-op would drop a product start
|
|
79
|
+
* (REQ-GESTURE-026; G-INV-8). Development throws; production reports via console.
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
start(event: unknown, options?: DragControlOptions): void {
|
|
83
|
+
// Validate before fan-out so a malformed option never silently changes threshold/snap
|
|
84
|
+
// behavior at the stream (seal review r6 minor; G-INV-8).
|
|
85
|
+
let validated: DragControlOptions | undefined
|
|
86
|
+
try {
|
|
87
|
+
validated = validateDragControlOptions(options)
|
|
88
|
+
} catch (error) {
|
|
89
|
+
// Mirror the component boundary: development throws, production reports.
|
|
90
|
+
// eslint-disable-next-line no-undef -- RN/metro __DEV__ global
|
|
91
|
+
if (typeof __DEV__ !== 'undefined' ? __DEV__ : process.env.NODE_ENV !== 'production') {
|
|
92
|
+
throw error
|
|
93
|
+
}
|
|
94
|
+
console.error(error)
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
if (this.subscribers.size === 0) {
|
|
98
|
+
const error = new Error(
|
|
99
|
+
'DragControls.start: no subscribed drag View — attach dragControls={hub} on a ' +
|
|
100
|
+
'drag-enabled View before start (REQ-GESTURE-026; G-INV-8).',
|
|
101
|
+
)
|
|
102
|
+
// Mirror the component boundary: development throws, production reports.
|
|
103
|
+
// eslint-disable-next-line no-undef -- RN/metro __DEV__ global
|
|
104
|
+
if (typeof __DEV__ !== 'undefined' ? __DEV__ : process.env.NODE_ENV !== 'production') {
|
|
105
|
+
throw error
|
|
106
|
+
}
|
|
107
|
+
// Production: report once; never silent.
|
|
108
|
+
console.error(error)
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
for (const controls of this.subscribers) {
|
|
112
|
+
controls.start(event, validated)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Cancel active sessions on every subscriber (REQ-GESTURE-018 pre-grab return).
|
|
118
|
+
* @public
|
|
119
|
+
*/
|
|
120
|
+
cancel(): void {
|
|
121
|
+
for (const controls of this.subscribers) {
|
|
122
|
+
controls.cancel()
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Stop active sessions and run the release animation (pin-shaped zero-arg public API).
|
|
128
|
+
* @public
|
|
129
|
+
*/
|
|
130
|
+
stop(): void {
|
|
131
|
+
for (const controls of this.subscribers) {
|
|
132
|
+
controls.stop()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** @internal test/debug surface */
|
|
137
|
+
get subscriberCount(): number {
|
|
138
|
+
return this.subscribers.size
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Lifetime-constant DragControls hub (pin useConstant).
|
|
144
|
+
* @public
|
|
145
|
+
*/
|
|
146
|
+
export function useDragControls(): DragControls {
|
|
147
|
+
const ref = useRef<DragControls | null>(null)
|
|
148
|
+
if (ref.current === null) {
|
|
149
|
+
ref.current = new DragControls()
|
|
150
|
+
}
|
|
151
|
+
return ref.current
|
|
152
|
+
}
|