panelui-native 0.100.0 → 0.101.1

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 (43) hide show
  1. package/README.md +2 -0
  2. package/lib/module/components/card/index.js +1 -1
  3. package/lib/module/components/card/index.js.map +1 -1
  4. package/lib/module/components/compare/index.js +576 -0
  5. package/lib/module/components/compare/index.js.map +1 -0
  6. package/lib/module/components/planner/index.js +8 -1
  7. package/lib/module/components/planner/index.js.map +1 -1
  8. package/lib/module/components/sankey-chart/index.js +933 -0
  9. package/lib/module/components/sankey-chart/index.js.map +1 -0
  10. package/lib/module/components/sankey-chart/sankey-layout.js +530 -0
  11. package/lib/module/components/sankey-chart/sankey-layout.js.map +1 -0
  12. package/lib/module/components/typography/index.js +10 -2
  13. package/lib/module/components/typography/index.js.map +1 -1
  14. package/lib/module/icons/index.js +15 -3
  15. package/lib/module/icons/index.js.map +1 -1
  16. package/lib/module/index.js +2 -0
  17. package/lib/module/index.js.map +1 -1
  18. package/lib/module/utils/chart.js +31 -0
  19. package/lib/module/utils/chart.js.map +1 -1
  20. package/lib/typescript/src/components/compare/index.d.ts +183 -0
  21. package/lib/typescript/src/components/compare/index.d.ts.map +1 -0
  22. package/lib/typescript/src/components/planner/index.d.ts.map +1 -1
  23. package/lib/typescript/src/components/sankey-chart/index.d.ts +307 -0
  24. package/lib/typescript/src/components/sankey-chart/index.d.ts.map +1 -0
  25. package/lib/typescript/src/components/sankey-chart/sankey-layout.d.ts +107 -0
  26. package/lib/typescript/src/components/sankey-chart/sankey-layout.d.ts.map +1 -0
  27. package/lib/typescript/src/components/typography/index.d.ts +0 -3
  28. package/lib/typescript/src/components/typography/index.d.ts.map +1 -1
  29. package/lib/typescript/src/icons/index.d.ts.map +1 -1
  30. package/lib/typescript/src/index.d.ts +2 -0
  31. package/lib/typescript/src/index.d.ts.map +1 -1
  32. package/lib/typescript/src/utils/chart.d.ts +17 -0
  33. package/lib/typescript/src/utils/chart.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/src/components/card/index.tsx +1 -1
  36. package/src/components/compare/index.tsx +650 -0
  37. package/src/components/planner/index.tsx +8 -1
  38. package/src/components/sankey-chart/index.tsx +1165 -0
  39. package/src/components/sankey-chart/sankey-layout.ts +645 -0
  40. package/src/components/typography/index.tsx +10 -2
  41. package/src/icons/index.tsx +20 -6
  42. package/src/index.ts +25 -0
  43. package/src/utils/chart.ts +46 -0
package/README.md CHANGED
@@ -227,6 +227,7 @@ memory pressure the OS can end the process with nothing in the terminal to expla
227
227
  | `Collapsible` | One section of content, shown and hidden by its own header |
228
228
  | `ColorPicker` | A colour chosen by dragging — a saturation square, a hue scale, and opacity |
229
229
  | `Combobox` | A text field that filters a list of options as you type |
230
+ | `Compare` | Two versions of one picture, with a seam you drag across it |
230
231
  | `ContextMenu` | Actions for a piece of content, opened by holding it |
231
232
  | `DatePicker` | A calendar behind a button |
232
233
  | `DateTimePicker` | A day and a time of day, picked in one panel |
@@ -280,6 +281,7 @@ memory pressure the OS can end the process with nothing in the terminal to expla
280
281
  | `Reasoning` | An agent’s thinking, collapsed until you want it |
281
282
  | `Response` | Streamed markdown rendered as native components |
282
283
  | `RingChart` | Concentric arcs, each measured against its own target |
284
+ | `SankeyChart` | Where a quantity came from and where it ended up |
283
285
  | `ScatterChart` | Two quantities against each other, to show how they relate |
284
286
  | `ScrollCanvas` | Image frame whose contents move as you scroll |
285
287
  | `ScrollFade` | Fades the edges of a scroll container |
@@ -75,7 +75,7 @@ const CardTitle = /*#__PURE__*/forwardRef(({
75
75
  ref: ref,
76
76
  size: "lg",
77
77
  weight: "semibold",
78
- className: cn('leading-none text-card-foreground', className),
78
+ className: cn('leading-tight text-card-foreground', className),
79
79
  ...props
80
80
  }));
81
81
  CardTitle.displayName = 'Card.Title';
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","View","tv","cn","Text","jsx","_jsx","footerVariants","base","variants","variant","plain","panel","defaultVariants","CardRoot","className","props","ref","displayName","CardHeader","CardTitle","size","weight","CardDescription","muted","CardContent","CardFooter","Card","Object","assign","Header","Title","Description","Content","Footer"],"sourceRoot":"../../../../src","sources":["components/card/index.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","View","tv","cn","Text","jsx","_jsx","footerVariants","base","variants","variant","plain","panel","defaultVariants","CardRoot","className","props","ref","displayName","CardHeader","CardTitle","size","weight","CardDescription","muted","CardContent","CardFooter","Card","Object","assign","Header","Title","Description","Content","Footer"],"sourceRoot":"../../../../src","sources":["components/card/index.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,576 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Compare — two versions of one picture, with a seam the reader drags across
5
+ * it.
6
+ *
7
+ * ```tsx
8
+ * <Compare height={260}>
9
+ * <Compare.After>
10
+ * <Image source={retouched} style={{ width: '100%', height: '100%' }} />
11
+ * </Compare.After>
12
+ * <Compare.Before>
13
+ * <Image source={original} style={{ width: '100%', height: '100%' }} />
14
+ * </Compare.Before>
15
+ * <Compare.Handle />
16
+ * </Compare>
17
+ * ```
18
+ *
19
+ * ## What it is for
20
+ *
21
+ * Showing that two images differ, when they differ in a way a pair of
22
+ * thumbnails side by side will not carry. Retouching, a filter, a render at two
23
+ * quality settings, a map at two dates: the change is spread across the frame
24
+ * rather than gathered in one place, and the eye cannot hold one image well
25
+ * enough to spot it in the other.
26
+ *
27
+ * The seam works because both versions are in the same place on the screen at
28
+ * the same scale. Every pixel the reader is comparing is a pixel that was just
29
+ * under the one beside it, so the difference arrives as movement rather than as
30
+ * something to be remembered.
31
+ *
32
+ * ## It clips, it does not resize
33
+ *
34
+ * The revealed side is a window onto a full-size copy of its content, not a
35
+ * copy of the content squeezed into the window. That distinction is the whole
36
+ * implementation: a view whose width is animated will lay its children out
37
+ * again at every new width, so an image inside one is an image being squashed
38
+ * and stretched as the seam moves, and the two halves stop lining up — which
39
+ * is the one thing this component exists to guarantee.
40
+ *
41
+ * It follows that the content has to be told how big to be, and the only thing
42
+ * that knows is the container once it has been measured. So nothing is drawn
43
+ * until the first layout pass has run, and `Compare.Before` sizes its child to
44
+ * the measured box rather than to itself.
45
+ *
46
+ * ## It needs a height
47
+ *
48
+ * Everything inside is positioned absolutely, so the box has no height of its
49
+ * own to take from its content. `height` is what gives it one. An image told to
50
+ * fill the box will fill whatever height is set here, and cropping is
51
+ * `resizeMode` on the image rather than anything this component does.
52
+ *
53
+ * ## Dragging, and the two ways round it
54
+ *
55
+ * The whole frame is the drag target, not just the knob — a knob is a small
56
+ * thing to hit on a phone and the reader's finger is already over the picture.
57
+ * The gesture only claims horizontal movement, so a Compare inside a scrolling
58
+ * page still scrolls.
59
+ *
60
+ * A drag is not available to everyone, so the seam is also `adjustable`: a
61
+ * screen reader moves it a `step` at a time without one, and `value` drives it
62
+ * from anywhere else — a button that snaps to the ends, an animation, a slider
63
+ * somewhere else on the screen.
64
+ */
65
+ import { Children, createContext, isValidElement, useCallback, useContext, useEffect, useMemo, useState } from 'react';
66
+ import { View } from 'react-native';
67
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
68
+ import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, useDerivedValue, useSharedValue } from 'react-native-reanimated';
69
+ import { tv } from 'tailwind-variants';
70
+ import { Text } from "../../primitives/text.js";
71
+ import { cn } from "../../utils/cn.js";
72
+ import { selectionTick } from "../../utils/haptics.js";
73
+ import { useDirectionSign } from "../../hooks/use-direction.js";
74
+
75
+ /** How tall the frame is when the caller does not say. */
76
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
77
+ const DEFAULT_HEIGHT = 240;
78
+
79
+ /** The knob's diameter, and so the width of the column the seam lives in. */
80
+ const KNOB = 36;
81
+
82
+ /** How far a screen reader's increment moves the seam, as a share of the box. */
83
+ const DEFAULT_STEP = 0.05;
84
+
85
+ /** Where the seam starts: the middle, so both sides are equally on show. */
86
+ const DEFAULT_VALUE = 0.5;
87
+
88
+ /** Movement along the axis before the drag is the gesture's rather than a scroll's. */
89
+ const CLAIM = 8;
90
+
91
+ /** And movement across it that hands the gesture back. */
92
+ const YIELD = 16;
93
+ const compareVariants = tv({
94
+ slots: {
95
+ root: 'w-full overflow-hidden rounded-xl bg-muted',
96
+ seam: 'absolute items-center justify-center',
97
+ line: 'absolute bg-background',
98
+ knob: 'items-center justify-center rounded-full border border-border bg-background shadow-md',
99
+ grip: 'rounded-full bg-foreground/60'
100
+ },
101
+ variants: {
102
+ orientation: {
103
+ horizontal: {
104
+ seam: 'bottom-0 top-0',
105
+ line: 'h-full w-0.5',
106
+ grip: 'h-3.5 w-1'
107
+ },
108
+ vertical: {
109
+ seam: 'left-0 right-0',
110
+ line: 'h-0.5 w-full',
111
+ grip: 'h-1 w-3.5'
112
+ }
113
+ }
114
+ },
115
+ defaultVariants: {
116
+ orientation: 'horizontal'
117
+ }
118
+ });
119
+ const CompareContext = /*#__PURE__*/createContext(null);
120
+ function useCompare(component) {
121
+ const context = useContext(CompareContext);
122
+ if (!context) {
123
+ throw new Error(`${component} must be used within a <Compare>`);
124
+ }
125
+ return context;
126
+ }
127
+ function clamp(value) {
128
+ 'worklet';
129
+
130
+ return value < 0 ? 0 : value > 1 ? 1 : value;
131
+ }
132
+ function CompareRoot({
133
+ className,
134
+ height = DEFAULT_HEIGHT,
135
+ value,
136
+ defaultValue = DEFAULT_VALUE,
137
+ onValueChange,
138
+ onValueCommit,
139
+ orientation = 'horizontal',
140
+ disabled = false,
141
+ step = DEFAULT_STEP,
142
+ haptics = true,
143
+ children,
144
+ ...props
145
+ }) {
146
+ const [box, setBox] = useState({
147
+ width: 0,
148
+ height: 0
149
+ });
150
+ const [internal, setInternal] = useState(defaultValue);
151
+ const sign = useDirectionSign();
152
+ const mirrored = sign === -1;
153
+ const controlled = value !== undefined;
154
+ const current = controlled ? value : internal;
155
+ const ratio = useSharedValue(clamp(current));
156
+ /** True between the finger landing and it lifting, so the prop can stand back. */
157
+ const dragging = useSharedValue(false);
158
+
159
+ /*
160
+ * A controlled `value` owns the seam except while a finger is on it. The
161
+ * drag writes the shared value directly and reports afterwards, so pushing
162
+ * the prop back in during the drag would fight it for the same number.
163
+ */
164
+ const settled = clamp(current);
165
+ useEffect(() => {
166
+ if (controlled && !dragging.value) ratio.value = settled;
167
+ }, [controlled, settled, ratio, dragging]);
168
+ const commit = useCallback(next => {
169
+ if (!controlled) setInternal(next);
170
+ onValueChange?.(next);
171
+ }, [controlled, onValueChange]);
172
+ const finish = useCallback(next => {
173
+ if (!controlled) setInternal(next);
174
+ onValueCommit?.(next);
175
+ }, [controlled, onValueCommit]);
176
+
177
+ /*
178
+ * Reported a whole percent at a time rather than every frame. The seam itself
179
+ * never needs the JS thread — it is drawn from the shared value — so a
180
+ * callback per frame would be sixty re-renders a second spent on a number
181
+ * nobody can read that fast.
182
+ */
183
+ const reported = useSharedValue(-1);
184
+ const report = useCallback(next => {
185
+ onValueChange?.(next);
186
+ }, [onValueChange]);
187
+ const nudge = useCallback(delta => {
188
+ const next = clamp(ratio.value + delta);
189
+ ratio.value = next;
190
+ commit(next);
191
+ onValueCommit?.(next);
192
+ }, [ratio, commit, onValueCommit]);
193
+ const horizontal = orientation === 'horizontal';
194
+ const extent = horizontal ? box.width : box.height;
195
+ const start = useSharedValue(0);
196
+ const edge = useSharedValue(false);
197
+ const pan = useMemo(() => {
198
+ const gesture = Gesture.Pan().enabled(!disabled).onBegin(() => {
199
+ start.value = ratio.value;
200
+ dragging.value = true;
201
+ edge.value = ratio.value <= 0 || ratio.value >= 1;
202
+ }).onUpdate(event => {
203
+ if (extent <= 0) return;
204
+ /*
205
+ * Under a right-to-left layout the leading edge is the right-hand one,
206
+ * so a drag towards it has to move the seam the other way for "towards
207
+ * the start" to keep meaning the same thing. Only the horizontal seam
208
+ * has a leading edge; down is down in both directions.
209
+ */
210
+ const travelled = horizontal ? event.translationX * sign : event.translationY;
211
+ const next = clamp(start.value + travelled / extent);
212
+ ratio.value = next;
213
+
214
+ // The one moment in this drag worth feeling: arriving at an end, where
215
+ // the seam stops following the finger. Without it the stall reads as
216
+ // the gesture having been dropped.
217
+ const ended = next <= 0 || next >= 1;
218
+ if (ended !== edge.value) {
219
+ edge.value = ended;
220
+ if (ended && haptics) runOnJS(selectionTick)();
221
+ }
222
+ const percent = Math.round(next * 100);
223
+ if (percent !== reported.value) {
224
+ reported.value = percent;
225
+ runOnJS(report)(next);
226
+ }
227
+ }).onFinalize(() => {
228
+ dragging.value = false;
229
+ reported.value = -1;
230
+ runOnJS(finish)(ratio.value);
231
+ });
232
+
233
+ /*
234
+ * The seam only answers to the axis it moves on. Without that it claims any
235
+ * movement at all, which is a Compare inside a scrolling page eating the
236
+ * scroll the moment a finger lands on the picture.
237
+ */
238
+ return horizontal ? gesture.activeOffsetX([-CLAIM, CLAIM]).failOffsetY([-YIELD, YIELD]) : gesture.activeOffsetY([-CLAIM, CLAIM]).failOffsetX([-YIELD, YIELD]);
239
+ }, [disabled, extent, horizontal, sign, haptics, ratio, start, edge, dragging, reported, report, finish]);
240
+ const onLayout = event => {
241
+ const {
242
+ width: w,
243
+ height: h
244
+ } = event.nativeEvent.layout;
245
+ const next = {
246
+ width: Math.round(w),
247
+ height: Math.round(h)
248
+ };
249
+ if (next.width !== box.width || next.height !== box.height) setBox(next);
250
+ props.onLayout?.(event);
251
+ };
252
+ const context = useMemo(() => ({
253
+ ratio,
254
+ width: box.width,
255
+ height: box.height,
256
+ orientation,
257
+ mirrored,
258
+ disabled,
259
+ step,
260
+ nudge
261
+ }), [ratio, box.width, box.height, orientation, mirrored, disabled, step, nudge]);
262
+ const {
263
+ root
264
+ } = compareVariants({
265
+ orientation
266
+ });
267
+
268
+ /*
269
+ * The background side is drawn first whatever order the caller wrote the
270
+ * children in, because the revealed side is a window laid over it — reversed,
271
+ * the window would be underneath and nothing would show through.
272
+ */
273
+ const layers = {
274
+ base: [],
275
+ clip: [],
276
+ over: []
277
+ };
278
+ Children.forEach(children, (child, index) => {
279
+ if (! /*#__PURE__*/isValidElement(child)) return;
280
+ const layer = child.type.layer ?? 'over';
281
+ layers[layer in layers ? layer : 'over'].push(/*#__PURE__*/_jsx(ChildSlot, {
282
+ children: child
283
+ }, index));
284
+ });
285
+ return /*#__PURE__*/_jsx(CompareContext.Provider, {
286
+ value: context,
287
+ children: /*#__PURE__*/_jsx(GestureDetector, {
288
+ gesture: pan,
289
+ children: /*#__PURE__*/_jsx(View, {
290
+ ...props,
291
+ onLayout: onLayout,
292
+ style: [{
293
+ height
294
+ }, props.style],
295
+ className: cn(root(), className),
296
+ children: box.width > 0 && box.height > 0 ? /*#__PURE__*/_jsxs(_Fragment, {
297
+ children: [layers.base, layers.clip, layers.over]
298
+ }) : null
299
+ })
300
+ })
301
+ });
302
+ }
303
+ function ChildSlot({
304
+ children
305
+ }) {
306
+ return /*#__PURE__*/_jsx(_Fragment, {
307
+ children: children
308
+ });
309
+ }
310
+ /**
311
+ * The side the seam uncovers as it travels: the whole frame, underneath.
312
+ *
313
+ * It is drawn at full size and never clipped, so it is the one that decides
314
+ * what the frame looks like at either end of the travel.
315
+ */
316
+ function CompareAfter({
317
+ className,
318
+ children,
319
+ ...props
320
+ }) {
321
+ const {
322
+ width,
323
+ height
324
+ } = useCompare('Compare.After');
325
+ return /*#__PURE__*/_jsx(View, {
326
+ ...props,
327
+ pointerEvents: "none",
328
+ style: [{
329
+ position: 'absolute',
330
+ left: 0,
331
+ top: 0,
332
+ width,
333
+ height
334
+ }, props.style],
335
+ className: cn(className),
336
+ children: children
337
+ });
338
+ }
339
+ CompareAfter.displayName = 'Compare.After';
340
+ CompareAfter.layer = 'base';
341
+ /**
342
+ * The side on the near edge of the seam: a window onto the content, sized to
343
+ * the frame.
344
+ *
345
+ * The child is given the frame's measured size in points rather than a
346
+ * percentage. A percentage would be a percentage *of the window*, which shrinks
347
+ * as the seam closes — so the image would slide and scale under the seam
348
+ * instead of standing still behind it, and the two halves would no longer be
349
+ * the same picture in the same place.
350
+ */
351
+ function CompareBefore({
352
+ className,
353
+ children,
354
+ ...props
355
+ }) {
356
+ const {
357
+ ratio,
358
+ width,
359
+ height,
360
+ orientation,
361
+ mirrored
362
+ } = useCompare('Compare.Before');
363
+ const horizontal = orientation === 'horizontal';
364
+ /*
365
+ * A horizontal window opens from the edge the line starts at, which is the
366
+ * right-hand one under a right-to-left layout. Both the window and the copy
367
+ * inside it are pinned to that same edge — pinning only the window would
368
+ * slide the content along under the seam, which is the one thing the clip
369
+ * exists to prevent. Vertical is unaffected: down is down in both directions.
370
+ */
371
+ const anchor = horizontal && mirrored ? 'right' : 'left';
372
+ const clip = useAnimatedStyle(() => horizontal ? {
373
+ width: ratio.value * width,
374
+ height
375
+ } : {
376
+ width,
377
+ height: ratio.value * height
378
+ });
379
+ return /*#__PURE__*/_jsx(Animated.View, {
380
+ pointerEvents: "none",
381
+ style: [{
382
+ position: 'absolute',
383
+ [anchor]: 0,
384
+ top: 0,
385
+ overflow: 'hidden'
386
+ }, clip],
387
+ children: /*#__PURE__*/_jsx(View, {
388
+ ...props,
389
+ style: [{
390
+ position: 'absolute',
391
+ [anchor]: 0,
392
+ top: 0,
393
+ width,
394
+ height
395
+ }, props.style],
396
+ className: cn(className),
397
+ children: children
398
+ })
399
+ });
400
+ }
401
+ CompareBefore.displayName = 'Compare.Before';
402
+ CompareBefore.layer = 'clip';
403
+ /**
404
+ * The seam: a line across the frame with a knob on it.
405
+ *
406
+ * The knob is a marker rather than the target — the drag is on the whole frame,
407
+ * and a 36-point circle is not something to ask a thumb to find. What it is
408
+ * for is saying where the seam is and that it is the thing that moves, which a
409
+ * bare line does not.
410
+ *
411
+ * It carries the accessibility wiring for the same reason a splitter's handle
412
+ * does: it is the one part of this that is a control, so it is the part that is
413
+ * `adjustable` and takes the increment and decrement a screen reader sends
414
+ * instead of a drag.
415
+ */
416
+ function CompareHandle({
417
+ className,
418
+ withGrip = true,
419
+ accessibilityLabel = 'Compare',
420
+ children,
421
+ style,
422
+ ...props
423
+ }) {
424
+ const {
425
+ ratio,
426
+ width,
427
+ height,
428
+ orientation,
429
+ mirrored,
430
+ disabled,
431
+ step,
432
+ nudge
433
+ } = useCompare('Compare.Handle');
434
+ const horizontal = orientation === 'horizontal';
435
+ const {
436
+ seam,
437
+ line,
438
+ knob,
439
+ grip
440
+ } = compareVariants({
441
+ orientation
442
+ });
443
+ // Pinned to the same edge the window opens from, and travelling away from it.
444
+ const anchor = horizontal && mirrored ? 'right' : 'left';
445
+ const towards = horizontal && mirrored ? -1 : 1;
446
+ const offset = useDerivedValue(() => horizontal ? ratio.value * width : ratio.value * height);
447
+ const animatedStyle = useAnimatedStyle(() => horizontal ? {
448
+ transform: [{
449
+ translateX: (offset.value - KNOB / 2) * towards
450
+ }]
451
+ } : {
452
+ transform: [{
453
+ translateY: offset.value - KNOB / 2
454
+ }]
455
+ });
456
+ const [now, setNow] = useState(() => Math.round(ratio.value * 100));
457
+ // The spoken value only has to be right when a screen reader reads it, so it
458
+ // is pulled back to the JS thread a percent at a time rather than every frame
459
+ // of a drag.
460
+ useAnimatedReaction(() => Math.round(ratio.value * 100), (percent, previous) => {
461
+ if (percent !== previous) runOnJS(setNow)(percent);
462
+ });
463
+ const onAccessibilityAction = useCallback(event => {
464
+ if (event.nativeEvent.actionName === 'increment') nudge(step);else if (event.nativeEvent.actionName === 'decrement') nudge(-step);
465
+ }, [nudge, step]);
466
+ return /*#__PURE__*/_jsxs(Animated.View, {
467
+ ...props,
468
+ accessible: true,
469
+ accessibilityRole: "adjustable",
470
+ accessibilityLabel: accessibilityLabel,
471
+ accessibilityState: {
472
+ disabled
473
+ },
474
+ accessibilityValue: {
475
+ min: 0,
476
+ max: 100,
477
+ now
478
+ },
479
+ accessibilityActions: disabled ? undefined : [{
480
+ name: 'increment'
481
+ }, {
482
+ name: 'decrement'
483
+ }],
484
+ onAccessibilityAction: disabled ? undefined : onAccessibilityAction,
485
+ pointerEvents: "box-none",
486
+ style: [horizontal ? {
487
+ width: KNOB,
488
+ [anchor]: 0
489
+ } : {
490
+ height: KNOB,
491
+ top: 0
492
+ }, style, animatedStyle],
493
+ className: seam(),
494
+ children: [/*#__PURE__*/_jsx(View, {
495
+ className: line(),
496
+ pointerEvents: "none"
497
+ }), children ?? /*#__PURE__*/_jsx(View, {
498
+ style: {
499
+ width: KNOB,
500
+ height: KNOB
501
+ },
502
+ className: knob(),
503
+ pointerEvents: "none",
504
+ children: withGrip ? /*#__PURE__*/_jsxs(View, {
505
+ className: horizontal ? 'flex-row gap-1' : 'gap-1',
506
+ children: [/*#__PURE__*/_jsx(View, {
507
+ className: grip()
508
+ }), /*#__PURE__*/_jsx(View, {
509
+ className: grip()
510
+ })]
511
+ }) : null
512
+ })]
513
+ });
514
+ }
515
+ CompareHandle.displayName = 'Compare.Handle';
516
+ CompareHandle.layer = 'over';
517
+ /**
518
+ * A caption pinned to one corner, for saying which side is which.
519
+ *
520
+ * Worth adding wherever the two versions are not obviously an original and an
521
+ * edit — two dates, two settings, two models. Where they are, it is one more
522
+ * thing over the picture and the picture is the point.
523
+ */
524
+ function CompareLabel({
525
+ className,
526
+ side = 'start',
527
+ children,
528
+ ...props
529
+ }) {
530
+ const {
531
+ orientation,
532
+ mirrored
533
+ } = useCompare('Compare.Label');
534
+ const horizontal = orientation === 'horizontal';
535
+ // `start` is the edge the line begins at, which the layout direction decides.
536
+ const start = horizontal && mirrored ? side !== 'start' : side === 'start';
537
+ return /*#__PURE__*/_jsx(View, {
538
+ ...props,
539
+ pointerEvents: "none",
540
+ style: [{
541
+ position: 'absolute',
542
+ ...(horizontal ? {
543
+ top: 8,
544
+ ...(start ? {
545
+ left: 8
546
+ } : {
547
+ right: 8
548
+ })
549
+ } : {
550
+ left: 8,
551
+ ...(start ? {
552
+ top: 8
553
+ } : {
554
+ bottom: 8
555
+ })
556
+ })
557
+ }, props.style],
558
+ className: cn('rounded-md bg-background/80 px-2 py-1', className),
559
+ children: typeof children === 'string' ? /*#__PURE__*/_jsx(Text, {
560
+ size: "xs",
561
+ weight: "medium",
562
+ numberOfLines: 1,
563
+ children: children
564
+ }) : children
565
+ });
566
+ }
567
+ CompareLabel.displayName = 'Compare.Label';
568
+ CompareLabel.layer = 'over';
569
+ CompareRoot.displayName = 'Compare';
570
+ export const Compare = Object.assign(CompareRoot, {
571
+ Before: CompareBefore,
572
+ After: CompareAfter,
573
+ Handle: CompareHandle,
574
+ Label: CompareLabel
575
+ });
576
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Children","createContext","isValidElement","useCallback","useContext","useEffect","useMemo","useState","View","Gesture","GestureDetector","Animated","runOnJS","useAnimatedReaction","useAnimatedStyle","useDerivedValue","useSharedValue","tv","Text","cn","selectionTick","useDirectionSign","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","DEFAULT_HEIGHT","KNOB","DEFAULT_STEP","DEFAULT_VALUE","CLAIM","YIELD","compareVariants","slots","root","seam","line","knob","grip","variants","orientation","horizontal","vertical","defaultVariants","CompareContext","useCompare","component","context","Error","clamp","value","CompareRoot","className","height","defaultValue","onValueChange","onValueCommit","disabled","step","haptics","children","props","box","setBox","width","internal","setInternal","sign","mirrored","controlled","undefined","current","ratio","dragging","settled","commit","next","finish","reported","report","nudge","delta","extent","start","edge","pan","gesture","Pan","enabled","onBegin","onUpdate","event","travelled","translationX","translationY","ended","percent","Math","round","onFinalize","activeOffsetX","failOffsetY","activeOffsetY","failOffsetX","onLayout","w","h","nativeEvent","layout","layers","base","clip","over","forEach","child","index","layer","type","push","ChildSlot","Provider","style","CompareAfter","pointerEvents","position","left","top","displayName","CompareBefore","anchor","overflow","CompareHandle","withGrip","accessibilityLabel","towards","offset","animatedStyle","transform","translateX","translateY","now","setNow","previous","onAccessibilityAction","actionName","accessible","accessibilityRole","accessibilityState","accessibilityValue","min","max","accessibilityActions","name","CompareLabel","side","right","bottom","size","weight","numberOfLines","Compare","Object","assign","Before","After","Handle","Label"],"sourceRoot":"../../../../src","sources":["components/compare/index.tsx"],"mappings":"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","ignoreList":[]}
@@ -160,6 +160,13 @@ const dayVariants = tv({
160
160
  * point; the variants below only colour it.
161
161
  */
162
162
  cell: 'mx-0.5 h-14 flex-1 rounded-xl border border-transparent px-1.5 pt-1.5',
163
+ /*
164
+ * `leading-none` is safe here and only here: these slots hold a day
165
+ * number, `•••` or `+3`, and none of those has anything below the
166
+ * baseline for Android to clip. Anywhere the caller's own words can
167
+ * appear it has to be `leading-tight` — a line height equal to the font
168
+ * size loses the tail of every `g` and `y` on that platform.
169
+ */
163
170
  number: 'text-xs leading-none',
164
171
  marker: 'absolute right-1.5 top-1.5 h-1.5 w-1.5 rounded-full',
165
172
  body: 'flex-1 flex-row items-center justify-center gap-0.5 pb-1',
@@ -935,7 +942,7 @@ function PlannerChip({
935
942
  children: /*#__PURE__*/_jsx(Text, {
936
943
  size: "xs",
937
944
  numberOfLines: 1,
938
- className: cn('leading-none', !color && 'text-foreground'),
945
+ className: cn('leading-tight', !color && 'text-foreground'),
939
946
  style: color ? {
940
947
  color: '#ffffff'
941
948
  } : undefined,