panelui-native 0.73.0 → 0.75.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 (192) hide show
  1. package/README.md +3 -1
  2. package/lib/module/components/avatar/avatar-group.js +64 -0
  3. package/lib/module/components/avatar/avatar-group.js.map +1 -0
  4. package/lib/module/components/avatar/index.js +84 -2
  5. package/lib/module/components/avatar/index.js.map +1 -1
  6. package/lib/module/components/color-picker/color-picker-accessibility.js +12 -0
  7. package/lib/module/components/color-picker/color-picker-accessibility.js.map +1 -0
  8. package/lib/module/components/color-picker/index.js +9 -5
  9. package/lib/module/components/color-picker/index.js.map +1 -1
  10. package/lib/module/components/date-time-picker/index.js +11 -3
  11. package/lib/module/components/date-time-picker/index.js.map +1 -1
  12. package/lib/module/components/drawer/index.js +58 -13
  13. package/lib/module/components/drawer/index.js.map +1 -1
  14. package/lib/module/components/input/index.js +7 -4
  15. package/lib/module/components/input/index.js.map +1 -1
  16. package/lib/module/components/input/input-content-padding.js +6 -0
  17. package/lib/module/components/input/input-content-padding.js.map +1 -0
  18. package/lib/module/components/input-group/index.js +14 -9
  19. package/lib/module/components/input-group/index.js.map +1 -1
  20. package/lib/module/components/input-group/input-group-measurements.js +60 -0
  21. package/lib/module/components/input-group/input-group-measurements.js.map +1 -0
  22. package/lib/module/components/otp-input/index.js +3 -1
  23. package/lib/module/components/otp-input/index.js.map +1 -1
  24. package/lib/module/components/otp-input/otp-input-state.js +7 -0
  25. package/lib/module/components/otp-input/otp-input-state.js.map +1 -0
  26. package/lib/module/components/planner/index.js +20 -6
  27. package/lib/module/components/planner/index.js.map +1 -1
  28. package/lib/module/components/planner/planner-today.js +8 -0
  29. package/lib/module/components/planner/planner-today.js.map +1 -0
  30. package/lib/module/components/plot/index.js +8 -11
  31. package/lib/module/components/plot/index.js.map +1 -1
  32. package/lib/module/components/plot/plot-series-registry.js +32 -0
  33. package/lib/module/components/plot/plot-series-registry.js.map +1 -0
  34. package/lib/module/components/radio-group/index.js +2 -1
  35. package/lib/module/components/radio-group/index.js.map +1 -1
  36. package/lib/module/components/radio-group/radio-group-value.js +8 -0
  37. package/lib/module/components/radio-group/radio-group-value.js.map +1 -0
  38. package/lib/module/components/rating/index.js +7 -4
  39. package/lib/module/components/rating/index.js.map +1 -1
  40. package/lib/module/components/rating/rating-inputs.js +15 -0
  41. package/lib/module/components/rating/rating-inputs.js.map +1 -0
  42. package/lib/module/components/search-bar/index.js +7 -7
  43. package/lib/module/components/search-bar/index.js.map +1 -1
  44. package/lib/module/components/search-bar/search-bar-debounce.js +23 -0
  45. package/lib/module/components/search-bar/search-bar-debounce.js.map +1 -0
  46. package/lib/module/components/select/index.js +9 -1
  47. package/lib/module/components/select/index.js.map +1 -1
  48. package/lib/module/components/select/native-select-contract.js +11 -0
  49. package/lib/module/components/select/native-select-contract.js.map +1 -0
  50. package/lib/module/components/split-view/index.js +439 -0
  51. package/lib/module/components/split-view/index.js.map +1 -0
  52. package/lib/module/components/split-view/split-view-math.js +132 -0
  53. package/lib/module/components/split-view/split-view-math.js.map +1 -0
  54. package/lib/module/components/splitter/index.js +433 -0
  55. package/lib/module/components/splitter/index.js.map +1 -0
  56. package/lib/module/components/splitter/splitter-math.js +206 -0
  57. package/lib/module/components/splitter/splitter-math.js.map +1 -0
  58. package/lib/module/components/steps/index.js +16 -5
  59. package/lib/module/components/steps/index.js.map +1 -1
  60. package/lib/module/components/steps/steps-trigger.js +6 -0
  61. package/lib/module/components/steps/steps-trigger.js.map +1 -0
  62. package/lib/module/components/tag-input/index.js +15 -10
  63. package/lib/module/components/tag-input/index.js.map +1 -1
  64. package/lib/module/components/tag-input/tag-input-state.js +14 -0
  65. package/lib/module/components/tag-input/tag-input-state.js.map +1 -0
  66. package/lib/module/components/textarea/index.js +9 -4
  67. package/lib/module/components/textarea/index.js.map +1 -1
  68. package/lib/module/components/textarea/textarea-disabled.js +6 -0
  69. package/lib/module/components/textarea/textarea-disabled.js.map +1 -0
  70. package/lib/module/components/timeline/index.js +83 -27
  71. package/lib/module/components/timeline/index.js.map +1 -1
  72. package/lib/module/components/timeline/timeline-geometry.js +11 -0
  73. package/lib/module/components/timeline/timeline-geometry.js.map +1 -0
  74. package/lib/module/components/toast/index.js +18 -1
  75. package/lib/module/components/toast/index.js.map +1 -1
  76. package/lib/module/components/toast/toast-store.js +36 -4
  77. package/lib/module/components/toast/toast-store.js.map +1 -1
  78. package/lib/module/components/tour/index.js +4 -2
  79. package/lib/module/components/tour/index.js.map +1 -1
  80. package/lib/module/components/tour/tour-card-measurement.js +24 -0
  81. package/lib/module/components/tour/tour-card-measurement.js.map +1 -0
  82. package/lib/module/index.js +2 -0
  83. package/lib/module/index.js.map +1 -1
  84. package/lib/typescript/src/components/avatar/avatar-group.d.ts +46 -0
  85. package/lib/typescript/src/components/avatar/avatar-group.d.ts.map +1 -0
  86. package/lib/typescript/src/components/avatar/index.d.ts +23 -1
  87. package/lib/typescript/src/components/avatar/index.d.ts.map +1 -1
  88. package/lib/typescript/src/components/color-picker/color-picker-accessibility.d.ts +8 -0
  89. package/lib/typescript/src/components/color-picker/color-picker-accessibility.d.ts.map +1 -0
  90. package/lib/typescript/src/components/color-picker/index.d.ts.map +1 -1
  91. package/lib/typescript/src/components/date-time-picker/index.d.ts.map +1 -1
  92. package/lib/typescript/src/components/drawer/index.d.ts.map +1 -1
  93. package/lib/typescript/src/components/input/index.d.ts.map +1 -1
  94. package/lib/typescript/src/components/input/input-content-padding.d.ts +2 -0
  95. package/lib/typescript/src/components/input/input-content-padding.d.ts.map +1 -0
  96. package/lib/typescript/src/components/input-group/index.d.ts.map +1 -1
  97. package/lib/typescript/src/components/input-group/input-group-measurements.d.ts +16 -0
  98. package/lib/typescript/src/components/input-group/input-group-measurements.d.ts.map +1 -0
  99. package/lib/typescript/src/components/otp-input/index.d.ts.map +1 -1
  100. package/lib/typescript/src/components/otp-input/otp-input-state.d.ts +3 -0
  101. package/lib/typescript/src/components/otp-input/otp-input-state.d.ts.map +1 -0
  102. package/lib/typescript/src/components/planner/index.d.ts.map +1 -1
  103. package/lib/typescript/src/components/planner/planner-today.d.ts +2 -0
  104. package/lib/typescript/src/components/planner/planner-today.d.ts.map +1 -0
  105. package/lib/typescript/src/components/plot/index.d.ts +1 -1
  106. package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
  107. package/lib/typescript/src/components/plot/plot-series-registry.d.ts +8 -0
  108. package/lib/typescript/src/components/plot/plot-series-registry.d.ts.map +1 -0
  109. package/lib/typescript/src/components/radio-group/index.d.ts.map +1 -1
  110. package/lib/typescript/src/components/radio-group/radio-group-value.d.ts +2 -0
  111. package/lib/typescript/src/components/radio-group/radio-group-value.d.ts.map +1 -0
  112. package/lib/typescript/src/components/rating/index.d.ts.map +1 -1
  113. package/lib/typescript/src/components/rating/rating-inputs.d.ts +4 -0
  114. package/lib/typescript/src/components/rating/rating-inputs.d.ts.map +1 -0
  115. package/lib/typescript/src/components/search-bar/index.d.ts.map +1 -1
  116. package/lib/typescript/src/components/search-bar/search-bar-debounce.d.ts +7 -0
  117. package/lib/typescript/src/components/search-bar/search-bar-debounce.d.ts.map +1 -0
  118. package/lib/typescript/src/components/select/index.d.ts.map +1 -1
  119. package/lib/typescript/src/components/select/native-select-contract.d.ts +11 -0
  120. package/lib/typescript/src/components/select/native-select-contract.d.ts.map +1 -0
  121. package/lib/typescript/src/components/split-view/index.d.ts +159 -0
  122. package/lib/typescript/src/components/split-view/index.d.ts.map +1 -0
  123. package/lib/typescript/src/components/split-view/split-view-math.d.ts +54 -0
  124. package/lib/typescript/src/components/split-view/split-view-math.d.ts.map +1 -0
  125. package/lib/typescript/src/components/splitter/index.d.ts +78 -0
  126. package/lib/typescript/src/components/splitter/index.d.ts.map +1 -0
  127. package/lib/typescript/src/components/splitter/splitter-math.d.ts +67 -0
  128. package/lib/typescript/src/components/splitter/splitter-math.d.ts.map +1 -0
  129. package/lib/typescript/src/components/steps/index.d.ts +2 -2
  130. package/lib/typescript/src/components/steps/index.d.ts.map +1 -1
  131. package/lib/typescript/src/components/steps/steps-trigger.d.ts +2 -0
  132. package/lib/typescript/src/components/steps/steps-trigger.d.ts.map +1 -0
  133. package/lib/typescript/src/components/tag-input/index.d.ts.map +1 -1
  134. package/lib/typescript/src/components/tag-input/tag-input-state.d.ts +12 -0
  135. package/lib/typescript/src/components/tag-input/tag-input-state.d.ts.map +1 -0
  136. package/lib/typescript/src/components/textarea/index.d.ts.map +1 -1
  137. package/lib/typescript/src/components/textarea/textarea-disabled.d.ts +2 -0
  138. package/lib/typescript/src/components/textarea/textarea-disabled.d.ts.map +1 -0
  139. package/lib/typescript/src/components/timeline/index.d.ts +1 -0
  140. package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
  141. package/lib/typescript/src/components/timeline/timeline-geometry.d.ts +4 -0
  142. package/lib/typescript/src/components/timeline/timeline-geometry.d.ts.map +1 -0
  143. package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
  144. package/lib/typescript/src/components/toast/toast-store.d.ts +7 -2
  145. package/lib/typescript/src/components/toast/toast-store.d.ts.map +1 -1
  146. package/lib/typescript/src/components/tour/index.d.ts.map +1 -1
  147. package/lib/typescript/src/components/tour/tour-card-measurement.d.ts +14 -0
  148. package/lib/typescript/src/components/tour/tour-card-measurement.d.ts.map +1 -0
  149. package/lib/typescript/src/index.d.ts +3 -1
  150. package/lib/typescript/src/index.d.ts.map +1 -1
  151. package/package.json +1 -1
  152. package/src/components/avatar/avatar-group.ts +78 -0
  153. package/src/components/avatar/index.tsx +121 -1
  154. package/src/components/color-picker/color-picker-accessibility.ts +12 -0
  155. package/src/components/color-picker/index.tsx +27 -8
  156. package/src/components/date-time-picker/index.tsx +11 -3
  157. package/src/components/drawer/index.tsx +42 -14
  158. package/src/components/input/index.tsx +6 -2
  159. package/src/components/input/input-content-padding.ts +3 -0
  160. package/src/components/input-group/index.tsx +38 -10
  161. package/src/components/input-group/input-group-measurements.ts +98 -0
  162. package/src/components/otp-input/index.tsx +3 -1
  163. package/src/components/otp-input/otp-input-state.ts +7 -0
  164. package/src/components/planner/index.tsx +24 -6
  165. package/src/components/planner/planner-today.ts +5 -0
  166. package/src/components/plot/index.tsx +16 -12
  167. package/src/components/plot/plot-series-registry.ts +41 -0
  168. package/src/components/radio-group/index.tsx +4 -1
  169. package/src/components/radio-group/radio-group-value.ts +9 -0
  170. package/src/components/rating/index.tsx +11 -4
  171. package/src/components/rating/rating-inputs.ts +19 -0
  172. package/src/components/search-bar/index.tsx +12 -7
  173. package/src/components/search-bar/search-bar-debounce.ts +35 -0
  174. package/src/components/select/index.tsx +10 -1
  175. package/src/components/select/native-select-contract.ts +12 -0
  176. package/src/components/split-view/index.tsx +565 -0
  177. package/src/components/split-view/split-view-math.ts +146 -0
  178. package/src/components/splitter/index.tsx +589 -0
  179. package/src/components/splitter/splitter-math.ts +244 -0
  180. package/src/components/steps/index.tsx +35 -9
  181. package/src/components/steps/steps-trigger.ts +6 -0
  182. package/src/components/tag-input/index.tsx +13 -11
  183. package/src/components/tag-input/tag-input-state.ts +18 -0
  184. package/src/components/textarea/index.tsx +8 -4
  185. package/src/components/textarea/textarea-disabled.ts +6 -0
  186. package/src/components/timeline/index.tsx +89 -26
  187. package/src/components/timeline/timeline-geometry.ts +9 -0
  188. package/src/components/toast/index.tsx +26 -1
  189. package/src/components/toast/toast-store.ts +43 -8
  190. package/src/components/tour/index.tsx +11 -3
  191. package/src/components/tour/tour-card-measurement.ts +29 -0
  192. package/src/index.ts +17 -0
@@ -0,0 +1,439 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * SplitView — two stacked panes whose seam settles on one of a few named
5
+ * heights rather than wherever the finger stopped.
6
+ *
7
+ * ```tsx
8
+ * <SplitView className="h-96" snapPoints={[0.25, 0.6]} minHeight={80}>
9
+ * <SplitView.Top>{map}</SplitView.Top>
10
+ * <SplitView.DragArea>
11
+ * <SplitView.Handle />
12
+ * </SplitView.DragArea>
13
+ * <SplitView.Bottom>{list}</SplitView.Bottom>
14
+ * </SplitView>
15
+ * ```
16
+ *
17
+ * The snapping is the difference between this and a free-resize split. A layout
18
+ * with a few right answers — a map over a list, a preview over an editor — is
19
+ * better served by a control that lands on one of them than by one that lets
20
+ * the reader stop three points short of it and live with the result.
21
+ *
22
+ * Snap points are ratios of the room the two panes share, so they mean the same
23
+ * thing on any screen and a rotation costs no re-measuring. That room is the
24
+ * container minus the drag area, which takes real layout height: half means
25
+ * half of what is actually divisible rather than half of a number the seam then
26
+ * eats into.
27
+ *
28
+ * The split view has no height of its own — give it one, or put it in something
29
+ * that has one, or it collapses and takes its panes with it.
30
+ *
31
+ * Dragging runs on the UI thread. `onSnap` fires once the pane has settled
32
+ * rather than on every frame, because a layout that round-trips through React
33
+ * sixty times a second is the one thing that makes this feel slow.
34
+ */
35
+ import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
36
+ import { View } from 'react-native';
37
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
38
+ import Animated, { runOnJS, useAnimatedStyle, useReducedMotion, useSharedValue, withSpring } from 'react-native-reanimated';
39
+ import { tv } from 'tailwind-variants';
40
+ import { selectionTick } from "../../utils/haptics.js";
41
+ import { DEFAULT_MIN_HEIGHT, clamp, nearestSnapIndex, normalizeSnapIndex, resolveLength, resolveSnapPoints } from "./split-view-math.js";
42
+
43
+ /** Settles the pane onto a snap point without overshooting past its limits. */
44
+ import { jsx as _jsx } from "react/jsx-runtime";
45
+ const SPRING = {
46
+ damping: 25,
47
+ stiffness: 300,
48
+ mass: 0.8,
49
+ overshootClamping: false,
50
+ restDisplacementThreshold: 0.01,
51
+ restSpeedThreshold: 0.01
52
+ };
53
+
54
+ /** How much the grip grows while it is being dragged. */
55
+ const GRIP_SPRING = {
56
+ damping: 18,
57
+ stiffness: 300,
58
+ mass: 0.8
59
+ };
60
+ const splitViewVariants = tv({
61
+ slots: {
62
+ root: 'w-full flex-col overflow-hidden',
63
+ top: 'w-full overflow-hidden',
64
+ bottom: 'w-full flex-1 overflow-hidden',
65
+ dragArea: 'w-full items-center justify-center py-2',
66
+ handle: 'h-1 w-10 rounded-full bg-muted-foreground/30'
67
+ }
68
+ });
69
+ const SplitViewContext = /*#__PURE__*/createContext(null);
70
+ function useSplitViewContext(component) {
71
+ const context = useContext(SplitViewContext);
72
+ if (!context) throw new Error(`${component} must be used within a <SplitView>`);
73
+ return context;
74
+ }
75
+
76
+ /**
77
+ * Reads the live layout from inside a split view, and moves the seam.
78
+ *
79
+ * `topHeight` is a shared value on the UI thread — read it in a worklet, not in
80
+ * render, where it is only ever the number the last commit happened to see.
81
+ */
82
+ export function useSplitView() {
83
+ return useSplitViewContext('useSplitView');
84
+ }
85
+ function SplitViewRoot({
86
+ className,
87
+ snapPoints,
88
+ minHeight,
89
+ maxHeight,
90
+ defaultSnapIndex = 1,
91
+ snapIndex: snapIndexProp,
92
+ onSnapIndexChange,
93
+ onSnap,
94
+ disabled = false,
95
+ animateOnMount = false,
96
+ children,
97
+ onLayout,
98
+ ...props
99
+ }) {
100
+ const {
101
+ root
102
+ } = splitViewVariants();
103
+ const reducedMotion = useReducedMotion();
104
+ const animate = !reducedMotion;
105
+ const [container, setContainer] = useState(0);
106
+ const [dragAreaHeight, setDragAreaHeight] = useState(0);
107
+ const topHeight = useSharedValue(0);
108
+ const dragging = useSharedValue(false);
109
+ const settled = useRef(false);
110
+ const room = Math.max(container - dragAreaHeight, 0);
111
+ const minPx = clamp(resolveLength(minHeight, room, DEFAULT_MIN_HEIGHT), 0, room);
112
+ const maxPx = clamp(resolveLength(maxHeight, room, room), minPx, room);
113
+ const pointsKey = JSON.stringify([snapPoints ?? null, room, minPx, maxPx]);
114
+ const points = useMemo(() => room > 0 ? resolveSnapPoints(snapPoints, room, minPx, maxPx) : [],
115
+ // eslint-disable-next-line react-hooks/exhaustive-deps
116
+ [pointsKey]);
117
+ const controlled = snapIndexProp !== undefined;
118
+ const [internalIndex, setInternalIndex] = useState(() => normalizeSnapIndex(defaultSnapIndex, 1));
119
+ const snapIndex = normalizeSnapIndex(controlled ? snapIndexProp : internalIndex, points.length || 1);
120
+ const onSnapRef = useRef(onSnap);
121
+ onSnapRef.current = onSnap;
122
+
123
+ /** Reports a settled pane once, from the spring's own completion. */
124
+ const report = useCallback((index, height) => {
125
+ onSnapRef.current?.(index, height);
126
+ }, []);
127
+
128
+ /*
129
+ * Moving the seam is one function whether a drag, a press or a screen reader
130
+ * asked for it — the alternative is three places that each have to remember
131
+ * to spring, to report, and to leave a controlled caller's index alone.
132
+ */
133
+ const moveTo = useCallback((index, options) => {
134
+ const target = points[index];
135
+ if (target === undefined) return;
136
+ if (!controlled) setInternalIndex(index);
137
+ onSnapIndexChange?.(index);
138
+ const finish = () => report(index, target);
139
+ if (options?.animated === false || !animate) {
140
+ topHeight.value = target;
141
+ finish();
142
+ return;
143
+ }
144
+ topHeight.value = withSpring(target, SPRING, finished => {
145
+ 'worklet';
146
+
147
+ if (finished) runOnJS(finish)();
148
+ });
149
+ }, [animate, controlled, onSnapIndexChange, points, report, topHeight]);
150
+ const snapTo = useCallback(index => moveTo(index), [moveTo]);
151
+
152
+ /*
153
+ * The first frame with a measurement is the only one that may place the pane
154
+ * without animating: there is nothing on screen yet to animate from, and a
155
+ * spring out of zero reads as the layout arriving broken and correcting
156
+ * itself. `animateOnMount` is for when that arrival is the point.
157
+ */
158
+ useEffect(() => {
159
+ const target = points[snapIndex];
160
+ if (target === undefined) return;
161
+ if (!settled.current) {
162
+ settled.current = true;
163
+ if (!animateOnMount) {
164
+ topHeight.value = target;
165
+ report(snapIndex, target);
166
+ return;
167
+ }
168
+ }
169
+ if (dragging.value) return;
170
+ if (!animate) {
171
+ topHeight.value = target;
172
+ report(snapIndex, target);
173
+ return;
174
+ }
175
+ topHeight.value = withSpring(target, SPRING);
176
+ // Only when the resolved layout moves — a re-render that changes nothing
177
+ // must not restart a spring the reader is watching.
178
+ // eslint-disable-next-line react-hooks/exhaustive-deps
179
+ }, [points, snapIndex, animate, animateOnMount]);
180
+ const handleLayout = useCallback(event => {
181
+ setContainer(event.nativeEvent.layout.height);
182
+ onLayout?.(event);
183
+ }, [onLayout]);
184
+ const measureDragArea = useCallback(height => {
185
+ setDragAreaHeight(current => Math.abs(current - height) < 0.5 ? current : height);
186
+ }, []);
187
+ const context = useMemo(() => ({
188
+ topHeight,
189
+ dragging,
190
+ points,
191
+ minPx,
192
+ maxPx,
193
+ room,
194
+ measured: room > 0,
195
+ disabled,
196
+ snapIndex,
197
+ animate,
198
+ snapTo,
199
+ measureDragArea,
200
+ dragAreaHeight
201
+ }), [topHeight, dragging, points, minPx, maxPx, room, disabled, snapIndex, animate, snapTo, measureDragArea, dragAreaHeight]);
202
+ return /*#__PURE__*/_jsx(SplitViewContext.Provider, {
203
+ value: context,
204
+ children: /*#__PURE__*/_jsx(View, {
205
+ className: root({
206
+ className
207
+ }),
208
+ onLayout: handleLayout,
209
+ ...props,
210
+ children: children
211
+ })
212
+ });
213
+ }
214
+ /**
215
+ * The upper pane.
216
+ *
217
+ * It clips what is inside it, so a pane dragged short hides its content rather
218
+ * than pushing it through the seam. Content that outgrows it is the caller's to
219
+ * scroll — put a `ScrollView` in here and it behaves like any other scroller in
220
+ * a box whose height changes.
221
+ */
222
+ function SplitViewTop({
223
+ className,
224
+ children,
225
+ style,
226
+ ...props
227
+ }) {
228
+ const context = useSplitViewContext('SplitView.Top');
229
+ const {
230
+ top
231
+ } = splitViewVariants();
232
+ const animatedStyle = useAnimatedStyle(() => ({
233
+ height: context.topHeight.value
234
+ }));
235
+
236
+ /*
237
+ * Before the container is measured there is no height to give, and a pane
238
+ * sized from a container of zero is a pane nobody can see. A flex basis of
239
+ * zero and a grow of one carries the first frame instead, so the pane is
240
+ * already the shape it will be when the measurement lands.
241
+ */
242
+ const unmeasured = {
243
+ flexGrow: 1,
244
+ flexBasis: 0,
245
+ flexShrink: 1
246
+ };
247
+ return /*#__PURE__*/_jsx(Animated.View, {
248
+ className: top({
249
+ className
250
+ }),
251
+ style: [context.measured ? null : unmeasured, style, animatedStyle],
252
+ ...props,
253
+ children: children
254
+ });
255
+ }
256
+
257
+ /**
258
+ * The lower pane. It takes exactly the room the upper one gave up, with no
259
+ * second measurement — which is what keeps the two adding to the container on
260
+ * every frame of a drag rather than only at rest.
261
+ */
262
+ function SplitViewBottom({
263
+ className,
264
+ children,
265
+ ...props
266
+ }) {
267
+ useSplitViewContext('SplitView.Bottom');
268
+ const {
269
+ bottom
270
+ } = splitViewVariants();
271
+ return /*#__PURE__*/_jsx(View, {
272
+ className: bottom({
273
+ className
274
+ }),
275
+ ...props,
276
+ children: children
277
+ });
278
+ }
279
+ /**
280
+ * The seam, and the target for the drag.
281
+ *
282
+ * It takes real layout height rather than floating over the panes, because that
283
+ * height is what the snap points are fractions of: a finger-sized target that
284
+ * did not take room would make `0.5` mean half of a number the seam then ate
285
+ * into. Give it padding to make the target larger — the room it takes is
286
+ * measured, so the arithmetic follows.
287
+ */
288
+ function SplitViewDragArea({
289
+ className,
290
+ accessibilityLabel = 'Resize panes',
291
+ children,
292
+ onLayout,
293
+ ...props
294
+ }) {
295
+ const context = useSplitViewContext('SplitView.DragArea');
296
+ const {
297
+ dragArea
298
+ } = splitViewVariants();
299
+ const {
300
+ topHeight,
301
+ dragging,
302
+ points,
303
+ minPx,
304
+ maxPx,
305
+ room,
306
+ disabled,
307
+ snapTo
308
+ } = context;
309
+ const start = useSharedValue(0);
310
+ const landed = useSharedValue(-1);
311
+ const settle = useCallback(index => snapTo(index), [snapTo]);
312
+ const pan = useMemo(() => Gesture.Pan().enabled(!disabled && points.length > 0)
313
+ // The seam only answers to the axis it moves on, so a split view inside
314
+ // a scroller leaves the scroll alone.
315
+ .activeOffsetY([-8, 8]).failOffsetX([-16, 16]).onBegin(() => {
316
+ start.value = topHeight.value;
317
+ dragging.value = true;
318
+ landed.value = -1;
319
+ }).onUpdate(event => {
320
+ if (room <= 0) return;
321
+ topHeight.value = clamp(start.value + event.translationY, minPx, maxPx);
322
+
323
+ // The moment worth feeling: passing the point the pane would settle
324
+ // at if the finger let go now. It is the only feedback that says a
325
+ // drag has a destination rather than a position.
326
+ const next = nearestSnapIndex(topHeight.value, points, 0, room);
327
+ if (next !== landed.value) {
328
+ landed.value = next;
329
+ runOnJS(selectionTick)();
330
+ }
331
+ }).onFinalize(event => {
332
+ dragging.value = false;
333
+ if (room <= 0) return;
334
+ const index = nearestSnapIndex(topHeight.value, points, event.velocityY ?? 0, room);
335
+ runOnJS(settle)(index);
336
+ }), [disabled, dragging, landed, maxPx, minPx, points, room, settle, start, topHeight]);
337
+ const handleLayout = useCallback(event => {
338
+ context.measureDragArea(event.nativeEvent.layout.height);
339
+ onLayout?.(event);
340
+ }, [context, onLayout]);
341
+
342
+ /*
343
+ * A step moves to the next snap point rather than by a distance, because the
344
+ * snap points are the positions this control has. Announcing a percentage
345
+ * somebody cannot stop at would be describing a different control.
346
+ */
347
+ const step = useCallback(direction => {
348
+ const next = clamp(context.snapIndex + direction, 0, points.length - 1);
349
+ if (next !== context.snapIndex) snapTo(next);
350
+ }, [context.snapIndex, points.length, snapTo]);
351
+ return /*#__PURE__*/_jsx(GestureDetector, {
352
+ gesture: pan,
353
+ children: /*#__PURE__*/_jsx(View, {
354
+ accessible: true,
355
+ accessibilityRole: "adjustable",
356
+ accessibilityLabel: accessibilityLabel,
357
+ accessibilityState: {
358
+ disabled
359
+ },
360
+ accessibilityValue: {
361
+ min: 0,
362
+ max: Math.max(points.length - 1, 0),
363
+ now: context.snapIndex
364
+ },
365
+ accessibilityActions: disabled ? undefined : [{
366
+ name: 'increment'
367
+ }, {
368
+ name: 'decrement'
369
+ }],
370
+ onAccessibilityAction: disabled ? undefined : event => {
371
+ if (event.nativeEvent.actionName === 'increment') step(1);else if (event.nativeEvent.actionName === 'decrement') step(-1);
372
+ },
373
+ className: dragArea({
374
+ className
375
+ }),
376
+ onLayout: handleLayout,
377
+ ...props,
378
+ children: children
379
+ })
380
+ });
381
+ }
382
+ /**
383
+ * The grip inside the drag area. It grows a little while the seam is moving,
384
+ * which is the only thing on screen saying the gesture was received before the
385
+ * panes have moved far enough to say it themselves.
386
+ */
387
+ function SplitViewHandle({
388
+ className,
389
+ children,
390
+ style,
391
+ ...props
392
+ }) {
393
+ const context = useSplitViewContext('SplitView.Handle');
394
+ const {
395
+ handle
396
+ } = splitViewVariants();
397
+ const {
398
+ animate
399
+ } = context;
400
+ const animatedStyle = useAnimatedStyle(() => {
401
+ if (!animate) return {
402
+ transform: [{
403
+ scaleX: 1
404
+ }]
405
+ };
406
+ return {
407
+ transform: [{
408
+ scaleX: withSpring(context.dragging.value ? 1.15 : 1, GRIP_SPRING)
409
+ }]
410
+ };
411
+ });
412
+ if (children) {
413
+ return /*#__PURE__*/_jsx(Animated.View, {
414
+ style: [style, animatedStyle],
415
+ ...props,
416
+ children: children
417
+ });
418
+ }
419
+ return /*#__PURE__*/_jsx(Animated.View, {
420
+ className: handle({
421
+ className
422
+ }),
423
+ style: [style, animatedStyle],
424
+ ...props
425
+ });
426
+ }
427
+ SplitViewRoot.displayName = 'SplitView';
428
+ SplitViewTop.displayName = 'SplitView.Top';
429
+ SplitViewBottom.displayName = 'SplitView.Bottom';
430
+ SplitViewDragArea.displayName = 'SplitView.DragArea';
431
+ SplitViewHandle.displayName = 'SplitView.Handle';
432
+ export const SplitView = Object.assign(SplitViewRoot, {
433
+ Top: SplitViewTop,
434
+ Bottom: SplitViewBottom,
435
+ DragArea: SplitViewDragArea,
436
+ Handle: SplitViewHandle
437
+ });
438
+ export { DEFAULT_MIN_HEIGHT, DEFAULT_SNAP_POINTS, nearestSnapIndex, normalizeSnapIndex, resolveLength, resolveSnapPoints } from "./split-view-math.js";
439
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","View","Gesture","GestureDetector","Animated","runOnJS","useAnimatedStyle","useReducedMotion","useSharedValue","withSpring","tv","selectionTick","DEFAULT_MIN_HEIGHT","clamp","nearestSnapIndex","normalizeSnapIndex","resolveLength","resolveSnapPoints","jsx","_jsx","SPRING","damping","stiffness","mass","overshootClamping","restDisplacementThreshold","restSpeedThreshold","GRIP_SPRING","splitViewVariants","slots","root","top","bottom","dragArea","handle","SplitViewContext","useSplitViewContext","component","context","Error","useSplitView","SplitViewRoot","className","snapPoints","minHeight","maxHeight","defaultSnapIndex","snapIndex","snapIndexProp","onSnapIndexChange","onSnap","disabled","animateOnMount","children","onLayout","props","reducedMotion","animate","container","setContainer","dragAreaHeight","setDragAreaHeight","topHeight","dragging","settled","room","Math","max","minPx","maxPx","pointsKey","JSON","stringify","points","controlled","undefined","internalIndex","setInternalIndex","length","onSnapRef","current","report","index","height","moveTo","options","target","finish","animated","value","finished","snapTo","handleLayout","event","nativeEvent","layout","measureDragArea","abs","measured","Provider","SplitViewTop","style","animatedStyle","unmeasured","flexGrow","flexBasis","flexShrink","SplitViewBottom","SplitViewDragArea","accessibilityLabel","start","landed","settle","pan","Pan","enabled","activeOffsetY","failOffsetX","onBegin","onUpdate","translationY","next","onFinalize","velocityY","step","direction","gesture","accessible","accessibilityRole","accessibilityState","accessibilityValue","min","now","accessibilityActions","name","onAccessibilityAction","actionName","SplitViewHandle","transform","scaleX","displayName","SplitView","Object","assign","Top","Bottom","DragArea","Handle","DEFAULT_SNAP_POINTS"],"sourceRoot":"../../../../src","sources":["components/split-view/index.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The arithmetic a split view runs while its seam is under a finger.
5
+ *
6
+ * A split view differs from a free-resize splitter in one way that decides the
7
+ * whole of this file: it does not stop wherever the finger stopped. It settles
8
+ * on one of a few heights the caller named, so the numbers a drag produces are
9
+ * only ever on the way to one of those — and picking which one, from a position
10
+ * and the speed it arrived at, is the part with the edge cases.
11
+ *
12
+ * It lives apart from the component because it runs on the UI thread, where a
13
+ * wrong answer is a pane that sticks rather than an exception anybody sees.
14
+ */
15
+
16
+ /** Smallest top pane, in points, when the caller names none. */
17
+ export const DEFAULT_MIN_HEIGHT = 100;
18
+
19
+ /** Where the panes sit when the caller names no snap points, as ratios. */
20
+ export const DEFAULT_SNAP_POINTS = [0.2, 0.5, 0.8];
21
+
22
+ /**
23
+ * How much of a flick counts toward the next snap point, in points per point of
24
+ * velocity. A release is at the height the finger left *plus* where the throw
25
+ * was going, so a fast flick carries past a midpoint the finger never crossed —
26
+ * which is the difference between a control that follows a gesture and one that
27
+ * merely records where it ended.
28
+ */
29
+ const VELOCITY_REACH = 0.12;
30
+
31
+ /** How far a flick may reach on its own, as a fraction of the room available. */
32
+ const VELOCITY_CEILING = 0.4;
33
+
34
+ /** The nearest entry to a height, by index. */
35
+ function closestIndex(height, points) {
36
+ 'worklet';
37
+
38
+ let best = 0;
39
+ let bestDistance = Math.abs(points[0] - height);
40
+ for (let index = 1; index < points.length; index += 1) {
41
+ const distance = Math.abs(points[index] - height);
42
+ if (distance < bestDistance) {
43
+ best = index;
44
+ bestDistance = distance;
45
+ }
46
+ }
47
+ return best;
48
+ }
49
+ export function clamp(value, low, high) {
50
+ 'worklet';
51
+
52
+ return Math.min(Math.max(value, low), high);
53
+ }
54
+
55
+ /**
56
+ * One length, in points, from the two ways of writing it.
57
+ *
58
+ * A number at or below 1 is a fraction of the room the panes share, which is
59
+ * what survives a rotation: half is half at any screen size. Anything larger is
60
+ * already points. A negative number is measured back from the far edge, for the
61
+ * case that is always written as a subtraction — "everything but the last 80".
62
+ */
63
+ export function resolveLength(value, room, fallback) {
64
+ 'worklet';
65
+
66
+ if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;
67
+ if (value < 0) return room + value;
68
+ return value <= 1 ? value * room : value;
69
+ }
70
+
71
+ /**
72
+ * The heights a seam may settle at, in points, in order and without repeats.
73
+ *
74
+ * Every point is clamped into the range the panes are allowed, which is what
75
+ * lets a caller name ratios without also checking them against a minimum they
76
+ * did not choose. Two points that clamp onto each other become one, because a
77
+ * list with the same height twice makes a flick land on a snap that looks like
78
+ * it did nothing.
79
+ */
80
+ export function resolveSnapPoints(points, room, minPx, maxPx) {
81
+ 'worklet';
82
+
83
+ const source = points && points.length > 0 ? points : DEFAULT_SNAP_POINTS;
84
+ const resolved = [];
85
+ for (let index = 0; index < source.length; index += 1) {
86
+ const raw = source[index];
87
+ if (!Number.isFinite(raw)) continue;
88
+ const height = clamp(resolveLength(raw, room, minPx), minPx, maxPx);
89
+ let seen = false;
90
+ for (let other = 0; other < resolved.length; other += 1) {
91
+ if (Math.abs(resolved[other] - height) < 0.5) seen = true;
92
+ }
93
+ if (!seen) resolved.push(height);
94
+ }
95
+ if (resolved.length === 0) resolved.push(clamp(minPx, minPx, maxPx));
96
+ resolved.sort((a, b) => a - b);
97
+ return resolved;
98
+ }
99
+
100
+ /**
101
+ * Which snap point a release belongs to.
102
+ *
103
+ * The height it is measured against is where the pane is plus where the throw
104
+ * was going, so a fast flick carries past a midpoint the finger never crossed —
105
+ * the difference between a control that follows a gesture and one that merely
106
+ * records where it ended.
107
+ *
108
+ * The result is then held to one point either side of where the pane actually
109
+ * is. Capping the distance is not enough on its own: the same throw skips two
110
+ * points in a list packed close together and none in a list spread wide, so the
111
+ * guarantee has to be made in points rather than in pixels. A release that
112
+ * lands two snaps from where it was aimed reads as the control guessing.
113
+ */
114
+ export function nearestSnapIndex(height, points, velocity, room) {
115
+ 'worklet';
116
+
117
+ if (points.length === 0) return 0;
118
+ const reach = clamp(velocity * VELOCITY_REACH, -room * VELOCITY_CEILING, room * VELOCITY_CEILING);
119
+ const resting = closestIndex(height, points);
120
+ const thrown = closestIndex(height + reach, points);
121
+ return clamp(thrown, resting - 1, resting + 1);
122
+ }
123
+
124
+ /** The index a caller asked to start at, kept inside the list that exists. */
125
+ export function normalizeSnapIndex(index, length) {
126
+ 'worklet';
127
+
128
+ if (length === 0) return 0;
129
+ if (typeof index !== 'number' || !Number.isFinite(index)) return 0;
130
+ return clamp(Math.round(index), 0, length - 1);
131
+ }
132
+ //# sourceMappingURL=split-view-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULT_MIN_HEIGHT","DEFAULT_SNAP_POINTS","VELOCITY_REACH","VELOCITY_CEILING","closestIndex","height","points","best","bestDistance","Math","abs","index","length","distance","clamp","value","low","high","min","max","resolveLength","room","fallback","Number","isFinite","resolveSnapPoints","minPx","maxPx","source","resolved","raw","seen","other","push","sort","a","b","nearestSnapIndex","velocity","reach","resting","thrown","normalizeSnapIndex","round"],"sourceRoot":"../../../../src","sources":["components/split-view/split-view-math.ts"],"mappings":"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","ignoreList":[]}