panelui-native 0.68.0 → 0.73.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 (206) hide show
  1. package/README.md +13 -2
  2. package/lib/module/components/accordion/index.js +38 -13
  3. package/lib/module/components/accordion/index.js.map +1 -1
  4. package/lib/module/components/area-chart/index.js +1 -0
  5. package/lib/module/components/area-chart/index.js.map +1 -1
  6. package/lib/module/components/breadcrumb/index.js +2 -1
  7. package/lib/module/components/breadcrumb/index.js.map +1 -1
  8. package/lib/module/components/button/index.js +21 -12
  9. package/lib/module/components/button/index.js.map +1 -1
  10. package/lib/module/components/carousel/index.js +1 -1
  11. package/lib/module/components/carousel/index.js.map +1 -1
  12. package/lib/module/components/chip/index.js +2 -2
  13. package/lib/module/components/chip/index.js.map +1 -1
  14. package/lib/module/components/code-block/index.js.map +1 -1
  15. package/lib/module/components/collapsible/index.js +284 -0
  16. package/lib/module/components/collapsible/index.js.map +1 -0
  17. package/lib/module/components/color-picker/index.js.map +1 -1
  18. package/lib/module/components/fab/index.js +7 -6
  19. package/lib/module/components/fab/index.js.map +1 -1
  20. package/lib/module/components/flow/index.js +67 -4
  21. package/lib/module/components/flow/index.js.map +1 -1
  22. package/lib/module/components/frame/index.js +2 -2
  23. package/lib/module/components/frame/index.js.map +1 -1
  24. package/lib/module/components/grid-item/index.js +2 -2
  25. package/lib/module/components/grid-item/index.js.map +1 -1
  26. package/lib/module/components/heatmap-chart/index.js +1 -0
  27. package/lib/module/components/heatmap-chart/index.js.map +1 -1
  28. package/lib/module/components/hex-chart/index.js +1 -0
  29. package/lib/module/components/hex-chart/index.js.map +1 -1
  30. package/lib/module/components/input-group/index.js +7 -2
  31. package/lib/module/components/input-group/index.js.map +1 -1
  32. package/lib/module/components/item/index.js +2 -2
  33. package/lib/module/components/item/index.js.map +1 -1
  34. package/lib/module/components/line-chart/index.js +1 -0
  35. package/lib/module/components/line-chart/index.js.map +1 -1
  36. package/lib/module/components/live-line-chart/index.js +103 -9
  37. package/lib/module/components/live-line-chart/index.js.map +1 -1
  38. package/lib/module/components/live-line-chart/live-line-accessibility.js +47 -0
  39. package/lib/module/components/live-line-chart/live-line-accessibility.js.map +1 -0
  40. package/lib/module/components/live-line-chart/live-line-lifecycle.js +33 -0
  41. package/lib/module/components/live-line-chart/live-line-lifecycle.js.map +1 -0
  42. package/lib/module/components/marker/index.js +2 -2
  43. package/lib/module/components/marker/index.js.map +1 -1
  44. package/lib/module/components/marquee/index.js +191 -0
  45. package/lib/module/components/marquee/index.js.map +1 -0
  46. package/lib/module/components/marquee/marquee-math.js +39 -0
  47. package/lib/module/components/marquee/marquee-math.js.map +1 -0
  48. package/lib/module/components/menu/index.js +11 -3
  49. package/lib/module/components/menu/index.js.map +1 -1
  50. package/lib/module/components/meter/index.js +38 -20
  51. package/lib/module/components/meter/index.js.map +1 -1
  52. package/lib/module/components/meter/meter-scale.js +62 -8
  53. package/lib/module/components/meter/meter-scale.js.map +1 -1
  54. package/lib/module/components/pagination/index.js +27 -11
  55. package/lib/module/components/pagination/index.js.map +1 -1
  56. package/lib/module/components/panelside/index.js +7 -2
  57. package/lib/module/components/panelside/index.js.map +1 -1
  58. package/lib/module/components/planner/index.js +159 -64
  59. package/lib/module/components/planner/index.js.map +1 -1
  60. package/lib/module/components/planner/planner-announcement.js +30 -0
  61. package/lib/module/components/planner/planner-announcement.js.map +1 -0
  62. package/lib/module/components/planner/planner-entries.js +15 -7
  63. package/lib/module/components/planner/planner-entries.js.map +1 -1
  64. package/lib/module/components/planner/planner-grid-navigation.js +33 -0
  65. package/lib/module/components/planner/planner-grid-navigation.js.map +1 -0
  66. package/lib/module/components/planner/planner-lifecycle.js +45 -0
  67. package/lib/module/components/planner/planner-lifecycle.js.map +1 -0
  68. package/lib/module/components/plot/index.js +105 -42
  69. package/lib/module/components/plot/index.js.map +1 -1
  70. package/lib/module/components/popover/index.js +2 -2
  71. package/lib/module/components/popover/index.js.map +1 -1
  72. package/lib/module/components/post/index.js +4 -4
  73. package/lib/module/components/post/index.js.map +1 -1
  74. package/lib/module/components/search-bar/index.js +331 -0
  75. package/lib/module/components/search-bar/index.js.map +1 -0
  76. package/lib/module/components/table/index.js +3 -4
  77. package/lib/module/components/table/index.js.map +1 -1
  78. package/lib/module/components/timeline/index.js +288 -39
  79. package/lib/module/components/timeline/index.js.map +1 -1
  80. package/lib/module/components/toggle-button/index.js +1 -1
  81. package/lib/module/components/toggle-button/index.js.map +1 -1
  82. package/lib/module/components/tree/index.js +13 -8
  83. package/lib/module/components/tree/index.js.map +1 -1
  84. package/lib/module/hooks/use-keyboard-avoidance.js.map +1 -1
  85. package/lib/module/index.js +3 -0
  86. package/lib/module/index.js.map +1 -1
  87. package/lib/module/primitives/focus-restoration-store.js +52 -0
  88. package/lib/module/primitives/focus-restoration-store.js.map +1 -0
  89. package/lib/module/primitives/portal.js +36 -2
  90. package/lib/module/primitives/portal.js.map +1 -1
  91. package/lib/module/utils/chart.js +50 -7
  92. package/lib/module/utils/chart.js.map +1 -1
  93. package/lib/typescript/src/components/accordion/index.d.ts +6 -2
  94. package/lib/typescript/src/components/accordion/index.d.ts.map +1 -1
  95. package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
  96. package/lib/typescript/src/components/breadcrumb/index.d.ts.map +1 -1
  97. package/lib/typescript/src/components/button/index.d.ts.map +1 -1
  98. package/lib/typescript/src/components/code-block/index.d.ts +3 -3
  99. package/lib/typescript/src/components/code-block/index.d.ts.map +1 -1
  100. package/lib/typescript/src/components/collapsible/index.d.ts +76 -0
  101. package/lib/typescript/src/components/collapsible/index.d.ts.map +1 -0
  102. package/lib/typescript/src/components/color-picker/index.d.ts.map +1 -1
  103. package/lib/typescript/src/components/fab/index.d.ts +4 -2
  104. package/lib/typescript/src/components/fab/index.d.ts.map +1 -1
  105. package/lib/typescript/src/components/flow/index.d.ts +7 -1
  106. package/lib/typescript/src/components/flow/index.d.ts.map +1 -1
  107. package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
  108. package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -1
  109. package/lib/typescript/src/components/input-group/index.d.ts.map +1 -1
  110. package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
  111. package/lib/typescript/src/components/live-line-chart/index.d.ts +21 -7
  112. package/lib/typescript/src/components/live-line-chart/index.d.ts.map +1 -1
  113. package/lib/typescript/src/components/live-line-chart/live-line-accessibility.d.ts +22 -0
  114. package/lib/typescript/src/components/live-line-chart/live-line-accessibility.d.ts.map +1 -0
  115. package/lib/typescript/src/components/live-line-chart/live-line-lifecycle.d.ts +23 -0
  116. package/lib/typescript/src/components/live-line-chart/live-line-lifecycle.d.ts.map +1 -0
  117. package/lib/typescript/src/components/marquee/index.d.ts +73 -0
  118. package/lib/typescript/src/components/marquee/index.d.ts.map +1 -0
  119. package/lib/typescript/src/components/marquee/marquee-math.d.ts +21 -0
  120. package/lib/typescript/src/components/marquee/marquee-math.d.ts.map +1 -0
  121. package/lib/typescript/src/components/menu/index.d.ts +1 -1
  122. package/lib/typescript/src/components/menu/index.d.ts.map +1 -1
  123. package/lib/typescript/src/components/meter/index.d.ts +7 -4
  124. package/lib/typescript/src/components/meter/index.d.ts.map +1 -1
  125. package/lib/typescript/src/components/meter/meter-scale.d.ts +39 -0
  126. package/lib/typescript/src/components/meter/meter-scale.d.ts.map +1 -1
  127. package/lib/typescript/src/components/pagination/index.d.ts.map +1 -1
  128. package/lib/typescript/src/components/panelside/index.d.ts +1 -1
  129. package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
  130. package/lib/typescript/src/components/plan/index.d.ts +2 -2
  131. package/lib/typescript/src/components/planner/index.d.ts.map +1 -1
  132. package/lib/typescript/src/components/planner/planner-announcement.d.ts +15 -0
  133. package/lib/typescript/src/components/planner/planner-announcement.d.ts.map +1 -0
  134. package/lib/typescript/src/components/planner/planner-entries.d.ts +1 -1
  135. package/lib/typescript/src/components/planner/planner-entries.d.ts.map +1 -1
  136. package/lib/typescript/src/components/planner/planner-grid-navigation.d.ts +4 -0
  137. package/lib/typescript/src/components/planner/planner-grid-navigation.d.ts.map +1 -0
  138. package/lib/typescript/src/components/planner/planner-lifecycle.d.ts +20 -0
  139. package/lib/typescript/src/components/planner/planner-lifecycle.d.ts.map +1 -0
  140. package/lib/typescript/src/components/plot/index.d.ts +59 -5
  141. package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
  142. package/lib/typescript/src/components/search-bar/index.d.ts +216 -0
  143. package/lib/typescript/src/components/search-bar/index.d.ts.map +1 -0
  144. package/lib/typescript/src/components/timeline/index.d.ts +35 -2
  145. package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
  146. package/lib/typescript/src/components/tree/index.d.ts +3 -4
  147. package/lib/typescript/src/components/tree/index.d.ts.map +1 -1
  148. package/lib/typescript/src/hooks/use-keyboard-avoidance.d.ts +2 -2
  149. package/lib/typescript/src/hooks/use-keyboard-avoidance.d.ts.map +1 -1
  150. package/lib/typescript/src/index.d.ts +4 -1
  151. package/lib/typescript/src/index.d.ts.map +1 -1
  152. package/lib/typescript/src/primitives/focus-restoration-store.d.ts +24 -0
  153. package/lib/typescript/src/primitives/focus-restoration-store.d.ts.map +1 -0
  154. package/lib/typescript/src/primitives/portal.d.ts +4 -0
  155. package/lib/typescript/src/primitives/portal.d.ts.map +1 -1
  156. package/lib/typescript/src/utils/chart.d.ts +28 -3
  157. package/lib/typescript/src/utils/chart.d.ts.map +1 -1
  158. package/package.json +36 -3
  159. package/src/components/accordion/index.tsx +48 -15
  160. package/src/components/area-chart/index.tsx +8 -0
  161. package/src/components/breadcrumb/index.tsx +2 -1
  162. package/src/components/button/index.tsx +14 -6
  163. package/src/components/carousel/index.tsx +1 -1
  164. package/src/components/chip/index.tsx +2 -2
  165. package/src/components/code-block/index.tsx +3 -3
  166. package/src/components/collapsible/index.tsx +287 -0
  167. package/src/components/color-picker/index.tsx +3 -2
  168. package/src/components/fab/index.tsx +21 -11
  169. package/src/components/flow/index.tsx +94 -15
  170. package/src/components/frame/index.tsx +2 -2
  171. package/src/components/grid-item/index.tsx +2 -2
  172. package/src/components/heatmap-chart/index.tsx +7 -1
  173. package/src/components/hex-chart/index.tsx +7 -1
  174. package/src/components/input-group/index.tsx +7 -2
  175. package/src/components/item/index.tsx +2 -2
  176. package/src/components/line-chart/index.tsx +9 -0
  177. package/src/components/live-line-chart/index.tsx +130 -13
  178. package/src/components/live-line-chart/live-line-accessibility.ts +61 -0
  179. package/src/components/live-line-chart/live-line-lifecycle.ts +63 -0
  180. package/src/components/marker/index.tsx +2 -2
  181. package/src/components/marquee/index.tsx +234 -0
  182. package/src/components/marquee/marquee-math.ts +37 -0
  183. package/src/components/menu/index.tsx +11 -3
  184. package/src/components/meter/index.tsx +49 -26
  185. package/src/components/meter/meter-scale.ts +84 -8
  186. package/src/components/pagination/index.tsx +26 -13
  187. package/src/components/panelside/index.tsx +7 -2
  188. package/src/components/plan/index.tsx +2 -2
  189. package/src/components/planner/index.tsx +202 -76
  190. package/src/components/planner/planner-announcement.ts +37 -0
  191. package/src/components/planner/planner-entries.ts +16 -7
  192. package/src/components/planner/planner-grid-navigation.ts +45 -0
  193. package/src/components/planner/planner-lifecycle.ts +76 -0
  194. package/src/components/plot/index.tsx +183 -39
  195. package/src/components/popover/index.tsx +3 -3
  196. package/src/components/post/index.tsx +4 -4
  197. package/src/components/search-bar/index.tsx +436 -0
  198. package/src/components/table/index.tsx +2 -2
  199. package/src/components/timeline/index.tsx +335 -39
  200. package/src/components/toggle-button/index.tsx +1 -1
  201. package/src/components/tree/index.tsx +17 -12
  202. package/src/hooks/use-keyboard-avoidance.ts +7 -2
  203. package/src/index.ts +15 -0
  204. package/src/primitives/focus-restoration-store.ts +70 -0
  205. package/src/primitives/portal.tsx +34 -2
  206. package/src/utils/chart.ts +66 -7
@@ -71,6 +71,7 @@ import {
71
71
  View,
72
72
  type AccessibilityActionEvent,
73
73
  type LayoutChangeEvent,
74
+ type ViewStyle,
74
75
  } from 'react-native';
75
76
  import MaskedView from '@react-native-masked-view/masked-view';
76
77
  import { LinearGradient } from 'expo-linear-gradient';
@@ -663,8 +664,8 @@ interface ChannelTrackProps {
663
664
  /** What fills the track — a hue ramp, or a masked translucency ramp. */
664
665
  children: ReactNode;
665
666
  gesture: ReturnType<typeof Gesture.Race>;
666
- thumbStyle: ReturnType<typeof useAnimatedStyle>;
667
- thumbFillStyle: ReturnType<typeof useAnimatedStyle>;
667
+ thumbStyle: ReturnType<typeof useAnimatedStyle<ViewStyle>>;
668
+ thumbFillStyle: ReturnType<typeof useAnimatedStyle<ViewStyle>>;
668
669
  onLayout: (event: LayoutChangeEvent) => void;
669
670
  size: ColorPickerSize;
670
671
  className?: string;
@@ -85,7 +85,10 @@ import { tv, type VariantProps } from 'tailwind-variants';
85
85
  import { useCSSVariable } from 'uniwind';
86
86
  import { IconColorProvider } from '../../icons';
87
87
  import { useBackHandler } from '../../hooks/use-back-handler';
88
- import { AnimatedPressable } from '../../primitives/animated-pressable';
88
+ import {
89
+ AnimatedPressable,
90
+ type AnimatedPressableProps,
91
+ } from '../../primitives/animated-pressable';
89
92
  import { Scrim } from '../../primitives/scrim';
90
93
  import { Text } from '../../primitives/text';
91
94
  import { cn } from '../../utils/cn';
@@ -180,7 +183,9 @@ function anchor(placement: FabPlacement, offset: number) {
180
183
  * Fab
181
184
  * -------------------------------------------------------------------------- */
182
185
 
183
- export interface FabProps extends Omit<ViewProps, 'children'>, FabVariantProps {
186
+ export interface FabProps
187
+ extends Omit<AnimatedPressableProps, 'children' | 'style' | 'disabled'>,
188
+ Omit<FabVariantProps, 'disabled'> {
184
189
  className?: string;
185
190
  /** The glyph. Sized by you — this is the one thing that should not guess. */
186
191
  icon?: ReactNode;
@@ -201,7 +206,8 @@ export interface FabProps extends Omit<ViewProps, 'children'>, FabVariantProps {
201
206
  placement?: FabPlacement;
202
207
  /** Distance from the edges when `placement` is set, in points. */
203
208
  offset?: number;
204
- onPress?: () => void;
209
+ /** Placement-aware view style. Press-state styling belongs in `className`. */
210
+ style?: ViewProps['style'];
205
211
  disabled?: boolean;
206
212
  /**
207
213
  * A tick on press. Off by default — needs the optional `expo-haptics`, and
@@ -231,33 +237,37 @@ const FabRoot = forwardRef<View, FabProps>(
231
237
  },
232
238
  ref
233
239
  ) => {
240
+ const isDisabled = Boolean(disabled);
234
241
  const { root, label } = fabVariants({
235
242
  size,
236
243
  variant,
237
244
  extended: extended && !!children,
238
- disabled,
245
+ disabled: isDisabled,
239
246
  });
240
247
 
241
248
  const themed = useCSSVariable(CONTENT_COLOR_VAR[variant ?? 'primary']);
242
249
  const contentColor =
243
250
  typeof themed === 'string' ? themed : undefined;
244
251
 
245
- const handlePress = useCallback(() => {
246
- if (haptics) selectionTick();
247
- onPress?.();
248
- }, [haptics, onPress]);
252
+ const handlePress = useCallback<NonNullable<AnimatedPressableProps['onPress']>>(
253
+ (event) => {
254
+ if (haptics) selectionTick();
255
+ onPress?.(event);
256
+ },
257
+ [haptics, onPress]
258
+ );
249
259
 
250
260
  return (
251
261
  <IconColorProvider color={contentColor}>
252
262
  <AnimatedPressable
253
263
  ref={ref}
264
+ {...props}
254
265
  accessibilityRole="button"
255
- accessibilityState={{ disabled }}
256
- disabled={disabled}
266
+ accessibilityState={{ disabled: isDisabled }}
267
+ disabled={isDisabled}
257
268
  onPress={handlePress}
258
269
  className={root({ className })}
259
270
  style={[placement ? anchor(placement, offset) : null, style]}
260
- {...props}
261
271
  >
262
272
  {icon}
263
273
  {extended && children ? (
@@ -31,6 +31,10 @@
31
31
  * the edges are ordinary elements and cost a render per drag frame. That is a
32
32
  * real cost and it is the right trade.
33
33
  *
34
+ * An `animated` edge keeps that arrangement and animates the one property the
35
+ * geometry does not own: the dash offset. Its `d` still arrives by re-render,
36
+ * so a dragged node reshapes the edge while the dashes keep marching.
37
+ *
34
38
  * JavaScript is told a drag has finished through `onNodeDragEnd`. Positions
35
39
  * are otherwise yours to leave alone: pass `position` once and the canvas
36
40
  * takes it from there, or keep it in state and pass it back to drive nodes
@@ -65,10 +69,12 @@ import {
65
69
  import { useCSSVariable } from 'uniwind';
66
70
  import { Gesture, GestureDetector } from 'react-native-gesture-handler';
67
71
  import Animated, {
72
+ cancelAnimation,
68
73
  runOnJS,
69
74
  useAnimatedProps,
70
75
  useAnimatedStyle,
71
76
  useDerivedValue,
77
+ useReducedMotion,
72
78
  useSharedValue,
73
79
  withRepeat,
74
80
  withTiming,
@@ -159,6 +165,15 @@ const CONNECT_RADIUS = 44;
159
165
  */
160
166
  const GROUP_EDGE_STANDOFF = 5;
161
167
 
168
+ /** Dash and gap length for a broken edge, in graph points. */
169
+ const EDGE_DASH = 6;
170
+
171
+ /**
172
+ * How long an animated edge takes to travel one dash-and-gap. Slow enough to
173
+ * read as flow rather than flicker, fast enough to look live.
174
+ */
175
+ const EDGE_MARCH_DURATION = 600;
176
+
162
177
  export type FlowEdgeVariant = 'bezier' | 'smoothstep' | 'step' | 'straight';
163
178
 
164
179
  export interface FlowViewport {
@@ -1239,6 +1254,7 @@ function FlowNode({
1239
1254
  <FlowNodeContext.Provider value={id}>
1240
1255
  <GestureDetector gesture={gesture}>
1241
1256
  <Animated.View
1257
+ {...props}
1242
1258
  collapsable={false}
1243
1259
  onLayout={onLayout}
1244
1260
  style={[{ position: 'absolute', top: 0, left: 0 }, style]}
@@ -1252,7 +1268,6 @@ function FlowNode({
1252
1268
  accessibilityState={{ selected }}
1253
1269
  accessibilityActions={nodeActions}
1254
1270
  onAccessibilityAction={handleAccessibilityAction}
1255
- {...props}
1256
1271
  >
1257
1272
  {textChildren(children)}
1258
1273
  </Animated.View>
@@ -1496,7 +1511,9 @@ export interface FlowEdgeProps {
1496
1511
  variant?: FlowEdgeVariant;
1497
1512
  /**
1498
1513
  * Mark the edge as carrying something — a request, a build, a dependency
1499
- * that is live rather than declared. Draws it dashed.
1514
+ * that is live rather than declared. Draws it dashed and marches the dashes
1515
+ * from source to target. Falls back to a still dashed edge when the
1516
+ * operating system is set to reduce motion.
1500
1517
  */
1501
1518
  animated?: boolean;
1502
1519
  /** Draw it broken rather than solid. */
@@ -1551,6 +1568,63 @@ function FlowEdge(props: FlowEdgeProps) {
1551
1568
  return null;
1552
1569
  }
1553
1570
 
1571
+ /**
1572
+ * A dashed edge whose dashes travel from source to target.
1573
+ *
1574
+ * The dash offset is the only animated property here, and the geometry is
1575
+ * deliberately not one: `d` arrives as an ordinary prop and changes by
1576
+ * re-render when a node moves. A path in React Native draws reliably when one
1577
+ * property animates and the rest are plain, so splitting them this way lets a
1578
+ * dragged node reshape the edge without ever interrupting the march.
1579
+ *
1580
+ * One dash and one gap of travel per cycle, which is why the loop is seamless:
1581
+ * the end state is the start state shifted by exactly one period.
1582
+ */
1583
+ function FlowMarchingEdge({
1584
+ d,
1585
+ stroke,
1586
+ width,
1587
+ }: {
1588
+ d: string;
1589
+ stroke: string;
1590
+ width: number;
1591
+ }) {
1592
+ const offset = useSharedValue(0);
1593
+ const reducedMotion = useReducedMotion();
1594
+
1595
+ useEffect(() => {
1596
+ if (reducedMotion) {
1597
+ offset.value = 0;
1598
+ return undefined;
1599
+ }
1600
+ // Negative, so the dashes run the way the path was drawn: source to target.
1601
+ offset.value = withRepeat(
1602
+ withTiming(-EDGE_DASH * 2, {
1603
+ duration: EDGE_MARCH_DURATION,
1604
+ easing: Easing.linear,
1605
+ }),
1606
+ -1,
1607
+ false
1608
+ );
1609
+ return () => cancelAnimation(offset);
1610
+ }, [offset, reducedMotion]);
1611
+
1612
+ const dashProps = useAnimatedProps(() => ({ strokeDashoffset: offset.value }));
1613
+
1614
+ return (
1615
+ <AnimatedPath
1616
+ animatedProps={dashProps}
1617
+ d={d}
1618
+ fill="none"
1619
+ stroke={stroke}
1620
+ strokeWidth={width}
1621
+ strokeLinecap="round"
1622
+ strokeLinejoin="round"
1623
+ strokeDasharray={`${EDGE_DASH} ${EDGE_DASH}`}
1624
+ />
1625
+ );
1626
+ }
1627
+
1554
1628
  /** The part that actually draws an edge, inside the canvas's one `<Svg>`. */
1555
1629
  function FlowEdgePath({
1556
1630
  from,
@@ -1612,7 +1686,7 @@ function FlowEdgePath({
1612
1686
  const b = { x: outB.x + origin.x, y: outB.y + origin.y };
1613
1687
 
1614
1688
  const d = edgePath(variant, a, sideA, b, sideB, curvature, radius, gap);
1615
- const dash = dashed || animated ? 6 : 0;
1689
+ const dash = dashed || animated ? EDGE_DASH : 0;
1616
1690
  const stroke = color ?? tint;
1617
1691
 
1618
1692
  const head = arrow
@@ -1624,15 +1698,19 @@ function FlowEdgePath({
1624
1698
 
1625
1699
  return (
1626
1700
  <>
1627
- <Path
1628
- d={d}
1629
- fill="none"
1630
- stroke={stroke}
1631
- strokeWidth={width}
1632
- strokeLinecap="round"
1633
- strokeLinejoin="round"
1634
- strokeDasharray={dash ? `${dash} ${dash}` : undefined}
1635
- />
1701
+ {animated ? (
1702
+ <FlowMarchingEdge d={d} stroke={stroke} width={width} />
1703
+ ) : (
1704
+ <Path
1705
+ d={d}
1706
+ fill="none"
1707
+ stroke={stroke}
1708
+ strokeWidth={width}
1709
+ strokeLinecap="round"
1710
+ strokeLinejoin="round"
1711
+ strokeDasharray={dash ? `${dash} ${dash}` : undefined}
1712
+ />
1713
+ )}
1636
1714
  {head ? <Path d={head} fill={stroke} /> : null}
1637
1715
  </>
1638
1716
  );
@@ -1703,9 +1781,10 @@ function FlowEdgeLayer() {
1703
1781
  origin={origin}
1704
1782
  />
1705
1783
  ))}
1706
- {/* The connection line is the one path that does animate, because it
1707
- follows a finger and has nothing else to follow. It animates `d` and
1708
- only `d`, which is the one thing that works. */}
1784
+ {/* The connection line follows a finger, so it is the path that animates
1785
+ `d` — and only `d`, which is the one thing that works while the
1786
+ geometry is what moves. An animated edge inverts the split: static
1787
+ `d`, animated dash offset. Either is fine; both at once is not. */}
1709
1788
  <AnimatedPath
1710
1789
  animatedProps={lineProps}
1711
1790
  fill="none"
@@ -398,7 +398,7 @@ const FrameRow = forwardRef<View, FrameRowProps>(
398
398
 
399
399
  if (!onPress) {
400
400
  return (
401
- <View ref={ref} className={classes} {...(props as ViewProps)}>
401
+ <View ref={ref} {...(props as ViewProps)} className={classes}>
402
402
  {body}
403
403
  </View>
404
404
  );
@@ -407,10 +407,10 @@ const FrameRow = forwardRef<View, FrameRowProps>(
407
407
  return (
408
408
  <Pressable
409
409
  ref={ref}
410
+ {...props}
410
411
  accessibilityRole="button"
411
412
  onPress={onPress}
412
413
  className={classes}
413
- {...props}
414
414
  >
415
415
  {body}
416
416
  </Pressable>
@@ -334,9 +334,9 @@ const GridItemRoot = forwardRef<View, GridItemProps>(
334
334
  return (
335
335
  <View
336
336
  ref={ref}
337
+ {...(props as ViewProps)}
337
338
  accessibilityState={{ disabled: !!disabled }}
338
339
  className={root({ className })}
339
- {...(props as ViewProps)}
340
340
  >
341
341
  {textChildren(children)}
342
342
  </View>
@@ -346,12 +346,12 @@ const GridItemRoot = forwardRef<View, GridItemProps>(
346
346
  return (
347
347
  <AnimatedPressable
348
348
  ref={ref}
349
+ {...props}
349
350
  accessibilityRole="button"
350
351
  accessibilityState={{ disabled: !!disabled }}
351
352
  disabled={disabled}
352
353
  onPress={onPress}
353
354
  className={root({ className })}
354
- {...props}
355
355
  >
356
356
  {textChildren(children)}
357
357
  </AnimatedPressable>
@@ -628,7 +628,13 @@ const HeatmapChartRoot = forwardRef<View, HeatmapChartProps>(function HeatmapCha
628
628
  <Svg width={grid.width} height={grid.height} style={StyleSheet.absoluteFill}>
629
629
  <Defs>
630
630
  <ClipPath id={clipId}>
631
- <AnimatedRect x={0} y={0} height={grid.height} animatedProps={clipProps} />
631
+ <AnimatedRect
632
+ x={0}
633
+ y={0}
634
+ width={grid.width}
635
+ height={grid.height}
636
+ animatedProps={clipProps}
637
+ />
632
638
  </ClipPath>
633
639
  </Defs>
634
640
  <G clipPath={`url(#${clipId})`}>
@@ -534,7 +534,13 @@ const HexChartRoot = forwardRef<HexChartHandle, HexChartProps>(function HexChart
534
534
  animatedProps={ellipseProps}
535
535
  />
536
536
  ) : (
537
- <AnimatedRect x={0} y={0} height={height} animatedProps={rectProps} />
537
+ <AnimatedRect
538
+ x={0}
539
+ y={0}
540
+ width={width}
541
+ height={height}
542
+ animatedProps={rectProps}
543
+ />
538
544
  )}
539
545
  </ClipPath>
540
546
  </Defs>
@@ -146,8 +146,13 @@ const InputGroupInput = forwardRef<TextInput, InputGroupInputProps>(
146
146
  style={[
147
147
  // Only override padding on the side that actually has a decorator —
148
148
  // a 0 here would wipe out the field's default horizontal padding.
149
- group?.prefixWidth ? { paddingLeft: group.prefixWidth } : null,
150
- group?.suffixWidth ? { paddingRight: group.suffixWidth } : null,
149
+ //
150
+ // `paddingStart`/`paddingEnd`, not left/right: the decorators are
151
+ // inset with `start-0`/`end-0`, so under `Direction dir="rtl"` Yoga
152
+ // moves them to the other edge. Physical padding stays where it was
153
+ // written and leaves the value running underneath them.
154
+ group?.prefixWidth ? { paddingStart: group.prefixWidth } : null,
155
+ group?.suffixWidth ? { paddingEnd: group.suffixWidth } : null,
151
156
  style,
152
157
  ]}
153
158
  {...props}
@@ -148,21 +148,21 @@ const ItemRoot = forwardRef<View, ItemProps>(
148
148
  const body = !onPress ? (
149
149
  <View
150
150
  ref={ref}
151
+ {...(props as ViewProps)}
151
152
  accessibilityState={{ disabled: !!disabled }}
152
153
  className={root({ className })}
153
- {...(props as ViewProps)}
154
154
  >
155
155
  {textChildren(children)}
156
156
  </View>
157
157
  ) : (
158
158
  <AnimatedPressable
159
159
  ref={ref}
160
+ {...props}
160
161
  accessibilityRole="button"
161
162
  accessibilityState={{ disabled: !!disabled }}
162
163
  disabled={disabled}
163
164
  onPress={onPress}
164
165
  className={root({ className })}
165
- {...props}
166
166
  >
167
167
  {textChildren(children)}
168
168
  </AnimatedPressable>
@@ -477,11 +477,20 @@ const LineChartRoot = forwardRef<LineChartHandle, LineChartProps>(function LineC
477
477
  * One clip for everything in the plot. Sharing it is what
478
478
  * makes the reveal read as the chart arriving, rather than as
479
479
  * three separate things animating in at once.
480
+ *
481
+ * `width` is set statically as well as animated, and it has
482
+ * to be. Animated props on an element inside `Defs` do not
483
+ * reach the native clip on every platform, and with the width
484
+ * coming only from the animation there is no width at all
485
+ * when they do not — an empty clip, and a chart whose marks
486
+ * are all invisible while its axes draw normally. Declared,
487
+ * the worst case is the reveal not playing.
480
488
  */}
481
489
  <ClipPath id={clipId}>
482
490
  <AnimatedRect
483
491
  x={plot.left}
484
492
  y={0}
493
+ width={plot.width}
485
494
  height={size.height}
486
495
  animatedProps={clipProps}
487
496
  />