@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.
Files changed (117) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +21 -0
  3. package/README.md +55 -0
  4. package/android/build.gradle +24 -0
  5. package/android/src/main/AndroidManifest.xml +1 -0
  6. package/android/src/main/java/com/unrulysystems/nativemotion/GestureExclusionModule.kt +55 -0
  7. package/android/src/main/java/com/unrulysystems/nativemotion/NativeMotionPackage.kt +27 -0
  8. package/package.json +57 -0
  9. package/react-native.config.js +14 -0
  10. package/src/native/driver/instantWindow.ts +31 -0
  11. package/src/native/driver/strictModeReplay.ts +20 -0
  12. package/src/native/driver/uiLayoutEngine.ts +845 -0
  13. package/src/native/driver/uiLayoutGraph.ts +338 -0
  14. package/src/native/driver/uiValueChannel.ts +4640 -0
  15. package/src/native/driver/workletDriver.ts +3860 -0
  16. package/src/native/motion/AnimatePresence.tsx +1605 -0
  17. package/src/native/motion/LayoutGroup.tsx +163 -0
  18. package/src/native/motion/MotionConfig.tsx +400 -0
  19. package/src/native/motion/MotionRoot.tsx +250 -0
  20. package/src/native/motion/MotionView.tsx +6761 -0
  21. package/src/native/motion/addScaleCorrector.ts +97 -0
  22. package/src/native/motion/colorEndpointUiFeed.ts +32 -0
  23. package/src/native/motion/colorProjection.ts +39 -0
  24. package/src/native/motion/composeTransform.ts +271 -0
  25. package/src/native/motion/constraintMeasure.ts +157 -0
  26. package/src/native/motion/deferredPendingSnapshots.ts +25 -0
  27. package/src/native/motion/discreteProjection.ts +36 -0
  28. package/src/native/motion/dragAncestorPanContext.ts +28 -0
  29. package/src/native/motion/dragControls.ts +152 -0
  30. package/src/native/motion/dragGestureWiring.ts +1168 -0
  31. package/src/native/motion/dragHandoffBinding.ts +179 -0
  32. package/src/native/motion/dragHubStream.ts +756 -0
  33. package/src/native/motion/dragPropagationLock.ts +57 -0
  34. package/src/native/motion/driverValueChannel.ts +3288 -0
  35. package/src/native/motion/externalDragDriver.ts +214 -0
  36. package/src/native/motion/frameData.ts +31 -0
  37. package/src/native/motion/gestureBinding.ts +107 -0
  38. package/src/native/motion/gestureStateGate.ts +563 -0
  39. package/src/native/motion/gestureStateResolver.ts +286 -0
  40. package/src/native/motion/identityValueChannelControllerAdapter.ts +2043 -0
  41. package/src/native/motion/identityValueChannelControllerReconciliation.ts +176 -0
  42. package/src/native/motion/identityValueChannelLaneMarker.ts +14 -0
  43. package/src/native/motion/imperativeAnimate.ts +816 -0
  44. package/src/native/motion/keyframeTiming.ts +7 -0
  45. package/src/native/motion/layoutIdBinding.ts +261 -0
  46. package/src/native/motion/layoutIdFlightConfig.ts +51 -0
  47. package/src/native/motion/layoutProjection.ts +89 -0
  48. package/src/native/motion/layoutScroll.ts +204 -0
  49. package/src/native/motion/layoutTransition.ts +1302 -0
  50. package/src/native/motion/lengthLayoutContext.tsx +100 -0
  51. package/src/native/motion/lengthLayoutHost.ts +44 -0
  52. package/src/native/motion/mappedKeys.ts +184 -0
  53. package/src/native/motion/motionViewController.ts +3180 -0
  54. package/src/native/motion/nativeHostMarker.ts +22 -0
  55. package/src/native/motion/panSessionWiring.ts +127 -0
  56. package/src/native/motion/pathTransition.ts +101 -0
  57. package/src/native/motion/popLayout.ts +176 -0
  58. package/src/native/motion/presenceBinding.ts +382 -0
  59. package/src/native/motion/scaleCorrectorRegistry.ts +123 -0
  60. package/src/native/motion/scrollValues.ts +260 -0
  61. package/src/native/motion/serializablePayload.ts +151 -0
  62. package/src/native/motion/severity.ts +16 -0
  63. package/src/native/motion/shippedSurface.ts +843 -0
  64. package/src/native/motion/staticLengthGate.ts +86 -0
  65. package/src/native/motion/styleBaseGate.ts +72 -0
  66. package/src/native/motion/styleValueBinding.ts +657 -0
  67. package/src/native/motion/systemGestureExclusion.ts +61 -0
  68. package/src/native/motion/tapGestureWiring.ts +215 -0
  69. package/src/native/motion/transformOrder.ts +38 -0
  70. package/src/native/motion/transformStringBinding.ts +200 -0
  71. package/src/native/motion/transformTemplateGate.ts +45 -0
  72. package/src/native/motion/transitionGate.ts +435 -0
  73. package/src/native/motion/useAnimate.ts +52 -0
  74. package/src/native/motion/useCycle.ts +44 -0
  75. package/src/native/motion/useInstantTransition.ts +68 -0
  76. package/src/native/motion/useReducedMotion.ts +58 -0
  77. package/src/native/motion/useScroll.ts +162 -0
  78. package/src/native/motion/useViewportScroll.ts +29 -0
  79. package/src/native/motion/valueChannel.ts +7121 -0
  80. package/src/native/motion/valueHooks.ts +901 -0
  81. package/src/native/motion/variantChildRegistry.ts +67 -0
  82. package/src/native/motion/variantContext.tsx +172 -0
  83. package/src/native/motion/variantProps.ts +598 -0
  84. package/src/native.ts +159 -0
  85. package/src/verification/harnessMetrics.ts +78 -0
  86. package/src/verification/probe/LayoutIdentityWorkletProbe.tsx +251 -0
  87. package/src/verification/probe/WorkletParityProbe.tsx +162 -0
  88. package/src/verification/probe/layoutIdentityProbeEngine.ts +429 -0
  89. package/src/verification/screens/ArcPathChecksScreen.tsx +273 -0
  90. package/src/verification/screens/BooleanAnimateChecksScreen.tsx +358 -0
  91. package/src/verification/screens/ChoreographyGalleryScreen.tsx +1010 -0
  92. package/src/verification/screens/ColorBindingChecksScreen.tsx +568 -0
  93. package/src/verification/screens/CompletionChecksScreen.tsx +294 -0
  94. package/src/verification/screens/ConformanceScreen.tsx +573 -0
  95. package/src/verification/screens/ContentionProbeScreen.tsx +224 -0
  96. package/src/verification/screens/DriverSmokeScreen.tsx +99 -0
  97. package/src/verification/screens/DurationOnlyTweenChecksScreen.tsx +294 -0
  98. package/src/verification/screens/DynamicDragConfigChecksScreen.tsx +237 -0
  99. package/src/verification/screens/FrameDataChecksScreen.tsx +252 -0
  100. package/src/verification/screens/GestureChecksScreen.tsx +685 -0
  101. package/src/verification/screens/InstantTransitionChecksScreen.tsx +839 -0
  102. package/src/verification/screens/LayoutAnimationStartChecksScreen.tsx +648 -0
  103. package/src/verification/screens/LayoutChecksScreen.tsx +822 -0
  104. package/src/verification/screens/LayoutCommitSpikeScreen.tsx +142 -0
  105. package/src/verification/screens/MotionViewChecksScreen.tsx +930 -0
  106. package/src/verification/screens/PresenceChecksScreen.tsx +614 -0
  107. package/src/verification/screens/ReducedMotionChecksScreen.tsx +614 -0
  108. package/src/verification/screens/RestThresholdChecksScreen.tsx +634 -0
  109. package/src/verification/screens/ScaleCorrectorChecksScreen.tsx +425 -0
  110. package/src/verification/screens/SharedLayoutContinuityChecksScreen.tsx +338 -0
  111. package/src/verification/screens/SharedLayoutCrossfadeChecksScreen.tsx +425 -0
  112. package/src/verification/screens/TransitionDefaultSelectionChecksScreen.tsx +514 -0
  113. package/src/verification/screens/ViewportScrollAliasChecksScreen.tsx +303 -0
  114. package/src/verification/screens/conformanceBanner.ts +21 -0
  115. package/src/verification/screens/proofConsoleTap.ts +18 -0
  116. package/src/verification.ts +47 -0
  117. package/src/web.ts +98 -0
@@ -0,0 +1,86 @@
1
+ // U6 (REQ-VALUETYPE-013(f)) — the ONE static-style boundary for positional length strings RN
2
+ // cannot express. A static `calc(…)` (simple binary) or vw/vh string on a layout length key
3
+ // (left/right/top/bottom/width/height) resolves to px through the EXISTING core
4
+ // resolveLengthToPx against the host's length layout context (the viewport context is seeded
5
+ // at mount, so a viewport-dependent static seed lays out correctly on first mount). Strings RN
6
+ // expresses natively (%/auto) and numbers pass through UNTOUCHED. Resolution refusals are
7
+ // COLLECTED, never thrown here: the component routes them through the severity law and STRIPS
8
+ // the key from the host style (the staticTransformGate strip precedent) — never a silent Yoga
9
+ // drop. A malformed unclosed `calc(` is intercepted by isCalc's prefix match and refused, never
10
+ // passed through.
11
+
12
+ import {
13
+ isCalc,
14
+ isLengthTarget,
15
+ parseLengthTarget,
16
+ resolveLengthToPx,
17
+ type LengthLayoutContext,
18
+ } from '@unrulysystems/native-motion-core'
19
+
20
+ // The layout length keys the static boundary resolves (REQ-VALUETYPE-013(f)). Static x/y
21
+ // transform strings stay with staticTransformGate; margins/padding/gap stay passthrough (no
22
+ // catalog demand). The literal const is the single authority the public MotionViewStyle union
23
+ // and this gate both derive from (the mappedKeys.ts pattern).
24
+ export const STATIC_LENGTH_STYLE_KEYS = [
25
+ 'left',
26
+ 'right',
27
+ 'top',
28
+ 'bottom',
29
+ 'width',
30
+ 'height',
31
+ ] as const
32
+
33
+ /** The layout length keys whose static grammar strings the public MotionViewStyle admits (U6). */
34
+ export type StaticLengthStyleKey = (typeof STATIC_LENGTH_STYLE_KEYS)[number]
35
+
36
+ /** The REQ-VALUETYPE-013 static grammar strings RN cannot express (resolved to px at the boundary). */
37
+ export type StaticLengthGrammarString = `calc(${string})` | `${number}vw` | `${number}vh`
38
+
39
+ /** One severity-routed refusal: the key to strip and the typed core error that refused it. */
40
+ export type StaticLengthStyleRefusal = {
41
+ readonly key: StaticLengthStyleKey
42
+ readonly error: Error
43
+ }
44
+
45
+ /** U6 gate result: resolved px replacements vs severity-refused keys to strip. */
46
+ export type StaticLengthStyleGate = {
47
+ readonly resolved: Readonly<Record<string, number>>
48
+ readonly refusals: readonly StaticLengthStyleRefusal[]
49
+ }
50
+
51
+ // A bare vw/vh unit number (the REQ-VALUETYPE-002 grammar). isLengthTarget is the total
52
+ // predicate, so the throwing parse cannot fault here — never bare try/catch over
53
+ // parseLengthTarget for classification.
54
+ function isViewportUnitLength(raw: string): boolean {
55
+ if (!isLengthTarget(raw)) return false
56
+ const parsed = parseLengthTarget(raw)
57
+ return parsed.kind === 'vw' || parsed.kind === 'vh'
58
+ }
59
+
60
+ /**
61
+ * Classify every authored layout length key on a flattened static style bag. Numbers and
62
+ * strings RN expresses natively (%/auto) pass through untouched; calc(…) (isCalc's prefix
63
+ * catches malformed unclosed forms too) and vw/vh resolve through the existing
64
+ * resolveLengthToPx. A resolution refusal (out-of-grammar calc, missing context, non-finite)
65
+ * is collected for the component's severity lane, which strips the key.
66
+ */
67
+ export function gateStaticLengthStyle(
68
+ style: Readonly<Record<string, unknown>>,
69
+ ctx: LengthLayoutContext,
70
+ ): StaticLengthStyleGate {
71
+ const resolved: Record<string, number> = {}
72
+ const refusals: StaticLengthStyleRefusal[] = []
73
+ for (let i = 0; i < STATIC_LENGTH_STYLE_KEYS.length; i++) {
74
+ const key = STATIC_LENGTH_STYLE_KEYS[i]!
75
+ if (!Object.prototype.hasOwnProperty.call(style, key)) continue
76
+ const value = style[key]
77
+ if (typeof value !== 'string') continue
78
+ if (!isCalc(value) && !isViewportUnitLength(value)) continue
79
+ try {
80
+ resolved[key] = resolveLengthToPx(value, key, ctx)
81
+ } catch (error) {
82
+ refusals.push({ key, error: error instanceof Error ? error : new Error(String(error)) })
83
+ }
84
+ }
85
+ return { resolved, refusals }
86
+ }
@@ -0,0 +1,72 @@
1
+ // The animated-key style-base gate (r14 major 10, REQ-API-010/011; R13 value-breadth amend):
2
+ // R4 mapped the layout-prop class, whose RN style types admit non-numeric bases ('50%', 'auto').
3
+ // Measure-resolved length forms are accepted through the ONE key-aware executable matrix
4
+ // (review 91d41675d511): positional keys only, auto for width/height only — the controller
5
+ // resolves them to px via layout context before seeding. Unsupported string bases still refuse
6
+ // under the severity law. Non-animated string bases never enter the gate.
7
+
8
+ import {
9
+ describeValue,
10
+ isDiscreteKeyword,
11
+ isLengthTarget,
12
+ parseValue,
13
+ } from '@unrulysystems/native-motion-core'
14
+ import { executableLengthValueRefusal } from '@unrulysystems/native-motion-core/internal-driver'
15
+ import { nativeMountTargetValueKind } from './shippedSurface'
16
+ import type { StyleValueGate } from './styleValueBinding'
17
+
18
+ function isSeedableLengthBase(key: string, base: string): boolean {
19
+ // Total recognition — named refusals are false; unexpected faults do not hide here. The matrix
20
+ // owns the key law (positional axes, auto for width/height only).
21
+ return isLengthTarget(base) && executableLengthValueRefusal(key, base) === null
22
+ }
23
+
24
+ const THROW_GATE: StyleValueGate = {
25
+ severity: 'development',
26
+ report: () => {},
27
+ componentId: '<Motion.View>',
28
+ }
29
+
30
+ /**
31
+ * Refuse every animated key whose static base the numeric lanes cannot seed. `rgbaKeys` names
32
+ * the keys the color-progress lane owns (string bases are ITS contract). Returns the refused
33
+ * keys so the production path can drop them from the mount set.
34
+ */
35
+ export function gateAnimatedStyleBases(
36
+ animatedKeys: readonly string[],
37
+ statics: Readonly<Record<string, unknown>>,
38
+ gate: StyleValueGate = THROW_GATE,
39
+ rgbaKeys: readonly string[] = [],
40
+ ): string[] {
41
+ const refused: string[] = []
42
+ for (const key of animatedKeys) {
43
+ const base = statics[key]
44
+ if (base === undefined || typeof base === 'number') continue
45
+ if (rgbaKeys.includes(key)) continue
46
+ // T23 B2b: a discrete-typed key's keyword-string base is the discrete lane's own contract
47
+ // (the rgba mirror) — derived from the ONE classification source, validated as the family.
48
+ if (
49
+ nativeMountTargetValueKind(key) === 'discrete' &&
50
+ typeof base === 'string' &&
51
+ isDiscreteKeyword(base) &&
52
+ parseValue(base).kind === 'discrete'
53
+ ) {
54
+ continue
55
+ }
56
+ // REQ-VALUETYPE-013: only executable measure-resolved strings seed — positional keys, auto
57
+ // for width/height only. opacity/"auto" and x:"auto" must not slip through as length bases.
58
+ if (typeof base === 'string' && isSeedableLengthBase(key, base)) {
59
+ continue
60
+ }
61
+ const error = new Error(
62
+ `${gate.componentId}: '${key}' is animated but its authored style base is ` +
63
+ `${describeValue(base)} — not a seedable numeric base for this key ` +
64
+ '(REQ-API-010/011, REQ-VALUETYPE-013; measure-resolved length strings only on ' +
65
+ 'width/height/inset/x/y).',
66
+ )
67
+ if (gate.severity === 'development') throw error
68
+ gate.report(error)
69
+ refused.push(key)
70
+ }
71
+ return refused
72
+ }