@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,142 @@
|
|
|
1
|
+
// L3 spike probe 1 (specs/L3-BUILD-PACKET.md §A): does a UI-thread frame callback observe the
|
|
2
|
+
// COMMITTED layout in the same frame that paints it? The toggling box is the M2.5 smoke's (same
|
|
3
|
+
// layout change, NO correction applied — this probe only observes). A worklet-driven MAGENTA
|
|
4
|
+
// indicator bar encodes what `measure()` returned THIS frame into the painted frame itself
|
|
5
|
+
// (translateX = measured pageX), so the frame-stepped scan can compare, per rendered frame, the
|
|
6
|
+
// box's painted position against the measurement the frame callback saw while producing that
|
|
7
|
+
// frame. Same-frame ordering holds iff the indicator jumps in the SAME rendered frame as the
|
|
8
|
+
// box — that is the entire empirical question of spike A; a correction applied at that point in
|
|
9
|
+
// the callback would land before paint. No core code crosses here; the probe is pure Reanimated
|
|
10
|
+
// (measure + useFrameCallback + shared values).
|
|
11
|
+
|
|
12
|
+
import { useEffect, useState } from 'react'
|
|
13
|
+
import { StyleSheet, Text, View } from 'react-native'
|
|
14
|
+
import { createNoFlashLayoutTransition } from '../../native/motion/layoutTransition'
|
|
15
|
+
import Animated, {
|
|
16
|
+
Easing,
|
|
17
|
+
measure,
|
|
18
|
+
useAnimatedRef,
|
|
19
|
+
useAnimatedStyle,
|
|
20
|
+
useFrameCallback,
|
|
21
|
+
useSharedValue,
|
|
22
|
+
withTiming,
|
|
23
|
+
type LayoutAnimationFunction,
|
|
24
|
+
} from 'react-native-reanimated'
|
|
25
|
+
|
|
26
|
+
const TOGGLE_MS = 2200
|
|
27
|
+
|
|
28
|
+
// Which probe this build runs (compile-time, like App.tsx SCREEN):
|
|
29
|
+
// 1 = same-frame measure ordering (no correction; DISPROVEN — packet Findings 2026-07-07).
|
|
30
|
+
// 2 = commit-time initialValues via a CUSTOM layout transition (path B): if the first painted
|
|
31
|
+
// frame after a layout change shows the box at its OLD rect, the commit hook applies
|
|
32
|
+
// initialValues BEFORE paint — zero wrong frames by construction. Linear 800 ms timing makes
|
|
33
|
+
// the trace unambiguous (a smooth ramp, never a >1-frame jump). Distinct from the forbidden
|
|
34
|
+
// sharedTransitionTag machinery; probe-level Reanimated animators only. PROVEN.
|
|
35
|
+
// 3 = the REAL L3 path: `createNoFlashLayoutTransition` — core springs stepping every channel
|
|
36
|
+
// (the rung's shipping mechanism). The zero-flash re-verification runs against THIS probe.
|
|
37
|
+
const PROBE: 1 | 2 | 3 = 3
|
|
38
|
+
|
|
39
|
+
const realNoFlashTransition = createNoFlashLayoutTransition()!
|
|
40
|
+
|
|
41
|
+
const flipProbeTransition: LayoutAnimationFunction = (values) => {
|
|
42
|
+
'worklet'
|
|
43
|
+
return {
|
|
44
|
+
initialValues: {
|
|
45
|
+
originX: values.currentOriginX,
|
|
46
|
+
originY: values.currentOriginY,
|
|
47
|
+
width: values.currentWidth,
|
|
48
|
+
height: values.currentHeight,
|
|
49
|
+
},
|
|
50
|
+
animations: {
|
|
51
|
+
originX: withTiming(values.targetOriginX, { duration: 800, easing: Easing.linear }),
|
|
52
|
+
originY: withTiming(values.targetOriginY, { duration: 800, easing: Easing.linear }),
|
|
53
|
+
width: withTiming(values.targetWidth, { duration: 800, easing: Easing.linear }),
|
|
54
|
+
height: withTiming(values.targetHeight, { duration: 800, easing: Easing.linear }),
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function LayoutCommitSpikeScreen() {
|
|
60
|
+
const [flipped, setFlipped] = useState(false)
|
|
61
|
+
const boxRef = useAnimatedRef<Animated.View>()
|
|
62
|
+
// What measure() saw this frame, painted INTO the frame via the indicator bar.
|
|
63
|
+
const measuredX = useSharedValue(0)
|
|
64
|
+
const measuredW = useSharedValue(0)
|
|
65
|
+
|
|
66
|
+
useFrameCallback(() => {
|
|
67
|
+
'worklet'
|
|
68
|
+
const m = measure(boxRef)
|
|
69
|
+
if (m === null) return // unmeasured this frame — fail-closed, indicator holds
|
|
70
|
+
measuredX.value = m.pageX
|
|
71
|
+
measuredW.value = m.width
|
|
72
|
+
}, true)
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const timer = setInterval(() => setFlipped((f) => !f), TOGGLE_MS)
|
|
76
|
+
return () => clearInterval(timer)
|
|
77
|
+
}, [])
|
|
78
|
+
|
|
79
|
+
const indicatorStyle = useAnimatedStyle(() => ({
|
|
80
|
+
transform: [{ translateX: measuredX.value }],
|
|
81
|
+
width: measuredW.value,
|
|
82
|
+
}))
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<View style={styles.container}>
|
|
86
|
+
<Text style={styles.title}>Native Motion</Text>
|
|
87
|
+
<Text style={styles.subtitle}>
|
|
88
|
+
L3 spike probe {PROBE}:{' '}
|
|
89
|
+
{PROBE === 1 ? 'same-frame measure ordering' : 'commit-time initialValues (path B)'} —
|
|
90
|
+
alignSelf {flipped ? 'end' : 'start'} + width {flipped ? 128 : 64}
|
|
91
|
+
</Text>
|
|
92
|
+
<View style={styles.arena}>
|
|
93
|
+
<Animated.View
|
|
94
|
+
ref={boxRef}
|
|
95
|
+
{...(PROBE === 2
|
|
96
|
+
? { layout: flipProbeTransition }
|
|
97
|
+
: PROBE === 3
|
|
98
|
+
? { layout: realNoFlashTransition }
|
|
99
|
+
: {})}
|
|
100
|
+
style={[styles.box, flipped ? styles.boxFlipped : styles.boxHome]}
|
|
101
|
+
/>
|
|
102
|
+
</View>
|
|
103
|
+
{/* The measurement indicator: absolute at screen left, translated by measured pageX and
|
|
104
|
+
sized to measured width — the frame callback's view of the layout, painted into the
|
|
105
|
+
same frame. Magenta for the scan (the box is green). */}
|
|
106
|
+
<Animated.View style={[styles.indicator, indicatorStyle]} />
|
|
107
|
+
<Text style={styles.mode}>
|
|
108
|
+
magenta bar = measure() seen by THIS frame's callback ·{' '}
|
|
109
|
+
{PROBE === 1
|
|
110
|
+
? 'no correction applied · probe only'
|
|
111
|
+
: PROBE === 2
|
|
112
|
+
? 'linear initialValues transition · probe only'
|
|
113
|
+
: 'REAL no-flash transition (core springs) · the shipping path'}
|
|
114
|
+
</Text>
|
|
115
|
+
</View>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const styles = StyleSheet.create({
|
|
120
|
+
container: {
|
|
121
|
+
flex: 1,
|
|
122
|
+
backgroundColor: '#0b0b12',
|
|
123
|
+
alignItems: 'center',
|
|
124
|
+
justifyContent: 'center',
|
|
125
|
+
paddingHorizontal: 24,
|
|
126
|
+
},
|
|
127
|
+
title: { color: '#fff', fontSize: 28, fontWeight: '700' },
|
|
128
|
+
subtitle: { color: '#8a8aa0', fontSize: 13, marginTop: 6, marginBottom: 40, textAlign: 'center' },
|
|
129
|
+
arena: { alignSelf: 'stretch', height: 160, justifyContent: 'center' },
|
|
130
|
+
box: { height: 64, borderRadius: 16, backgroundColor: '#58c47a' },
|
|
131
|
+
boxHome: { alignSelf: 'flex-start', width: 64 },
|
|
132
|
+
boxFlipped: { alignSelf: 'flex-end', width: 128 },
|
|
133
|
+
indicator: {
|
|
134
|
+
position: 'absolute',
|
|
135
|
+
left: 0,
|
|
136
|
+
bottom: 120,
|
|
137
|
+
height: 10,
|
|
138
|
+
borderRadius: 3,
|
|
139
|
+
backgroundColor: '#e040fb',
|
|
140
|
+
},
|
|
141
|
+
mode: { color: '#6f6f85', fontSize: 11, marginTop: 24, textAlign: 'center' },
|
|
142
|
+
})
|