panelui-native 0.88.2 → 0.90.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 (39) hide show
  1. package/lib/module/components/animated-badge/index.js +10 -2
  2. package/lib/module/components/animated-badge/index.js.map +1 -1
  3. package/lib/module/components/avatar/index.js +10 -1
  4. package/lib/module/components/avatar/index.js.map +1 -1
  5. package/lib/module/components/search-bar/index.js +35 -7
  6. package/lib/module/components/search-bar/index.js.map +1 -1
  7. package/lib/module/components/section-progress/index.js +637 -0
  8. package/lib/module/components/section-progress/index.js.map +1 -0
  9. package/lib/module/components/selection-mode/index.js +33 -3
  10. package/lib/module/components/selection-mode/index.js.map +1 -1
  11. package/lib/module/hooks/index.js.map +1 -1
  12. package/lib/module/hooks/use-scroll-sections.js +58 -4
  13. package/lib/module/hooks/use-scroll-sections.js.map +1 -1
  14. package/lib/module/index.js +1 -0
  15. package/lib/module/index.js.map +1 -1
  16. package/lib/typescript/src/components/animated-badge/index.d.ts +19 -0
  17. package/lib/typescript/src/components/animated-badge/index.d.ts.map +1 -1
  18. package/lib/typescript/src/components/avatar/index.d.ts.map +1 -1
  19. package/lib/typescript/src/components/search-bar/index.d.ts +4 -1
  20. package/lib/typescript/src/components/search-bar/index.d.ts.map +1 -1
  21. package/lib/typescript/src/components/section-progress/index.d.ts +156 -0
  22. package/lib/typescript/src/components/section-progress/index.d.ts.map +1 -0
  23. package/lib/typescript/src/components/selection-mode/index.d.ts +63 -0
  24. package/lib/typescript/src/components/selection-mode/index.d.ts.map +1 -1
  25. package/lib/typescript/src/hooks/index.d.ts +1 -1
  26. package/lib/typescript/src/hooks/index.d.ts.map +1 -1
  27. package/lib/typescript/src/hooks/use-scroll-sections.d.ts +24 -0
  28. package/lib/typescript/src/hooks/use-scroll-sections.d.ts.map +1 -1
  29. package/lib/typescript/src/index.d.ts +1 -0
  30. package/lib/typescript/src/index.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/src/components/animated-badge/index.tsx +24 -2
  33. package/src/components/avatar/index.tsx +10 -1
  34. package/src/components/search-bar/index.tsx +33 -8
  35. package/src/components/section-progress/index.tsx +813 -0
  36. package/src/components/selection-mode/index.tsx +30 -3
  37. package/src/hooks/index.ts +1 -0
  38. package/src/hooks/use-scroll-sections.ts +84 -5
  39. package/src/index.ts +8 -0
@@ -0,0 +1,637 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * SectionProgress — a floating pill saying how far through a screen you are,
5
+ * and which part of it you are in.
6
+ *
7
+ * A ring filled to the scroll position, and beside it the title of the section
8
+ * being read. Pressed, it opens into the list of sections and jumps to any of
9
+ * them.
10
+ *
11
+ * ```tsx
12
+ * const sections = useScrollSections({ ids: SECTIONS.map((s) => s.id) });
13
+ *
14
+ * <SectionProgress
15
+ * scroll={sections.scroll}
16
+ * value={sections.active}
17
+ * onValueChange={sections.scrollTo}
18
+ * >
19
+ * <SectionProgress.Item value="intro">Introduction</SectionProgress.Item>
20
+ * <SectionProgress.Item value="setup">Setup</SectionProgress.Item>
21
+ * </SectionProgress>
22
+ * ```
23
+ *
24
+ * ## Two readings, one control
25
+ *
26
+ * The ring is continuous and the label is not, and that is the point: a
27
+ * percentage says how much is left, a section name says what is being read.
28
+ * Either on its own leaves the other question open — a bar at 60% of an
29
+ * unfamiliar page means nothing in particular, and a heading with no sense of
30
+ * depth is a position without a scale.
31
+ *
32
+ * ## It arrives, and then it stays
33
+ *
34
+ * Nothing is drawn on the first screen. Past `revealAt` the pill fades in and
35
+ * remains for the rest of the scroll — it does not hide again on the way back
36
+ * up. A label that comes and goes with the scroll direction is one the reader
37
+ * has to catch rather than read.
38
+ *
39
+ * ## One surface, not a card above a button
40
+ *
41
+ * Open, the list and the pill are a single bordered box: the pill's row is the
42
+ * end of the card rather than a control sitting under a panel of its own. Two
43
+ * boxes would draw two outlines a few points apart, and the pill would read as
44
+ * something the list had landed on top of rather than as the thing it grew
45
+ * out of.
46
+ *
47
+ * The card is the only thing carrying a border, a background and a shadow.
48
+ * Everything inside it is a row.
49
+ *
50
+ * ## The section, and the colour it brings
51
+ *
52
+ * An `Item` may carry a `color`, and the active one's colour is taken by the
53
+ * ring, the label and a wash across the pill, crossfading as the reader moves
54
+ * between sections. It turns the pill into a second, peripheral signal — the
55
+ * part of the page you are in, readable without the words.
56
+ */
57
+ import { Children, createContext, isValidElement, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
58
+ import { Pressable, ScrollView, StyleSheet, View } from 'react-native';
59
+ import Animated, { FadeIn, interpolate, interpolateColor, runOnJS, useAnimatedProps, useAnimatedReaction, useAnimatedStyle, useReducedMotion, useSharedValue, withTiming } from 'react-native-reanimated';
60
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
61
+ import Svg, { Circle, G } from 'react-native-svg';
62
+ import { useCSSVariable } from 'uniwind';
63
+ import { useBackHandler } from "../../hooks/use-back-handler.js";
64
+ import { useScrollProgress } from "../../primitives/scroll-progress.js";
65
+ import { Text, textChildren } from "../../primitives/text.js";
66
+ import { cn } from "../../utils/cn.js";
67
+ import { selectionTick } from "../../utils/haptics.js";
68
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
69
+ const AnimatedCircle = Animated.createAnimatedComponent(Circle);
70
+
71
+ /** Diameter of the ring, and the weight of its stroke. */
72
+ const RING_SIZE = 22;
73
+ const RING_STROKE = 2.5;
74
+ /**
75
+ * How long the ring takes to reach a new scroll position.
76
+ *
77
+ * The position arrives from a scroll handler on the JavaScript thread, so it
78
+ * comes in steps rather than continuously. Easing towards each step turns that
79
+ * back into a glide — and because the easing itself runs on the UI thread, a
80
+ * busy JavaScript thread costs the ring some lag rather than the whole motion.
81
+ */
82
+ const PROGRESS_EASE = 160;
83
+ /** How long the pill takes to arrive, and to take on a new section's colour. */
84
+ const REVEAL_DURATION = 200;
85
+ const TINT_DURATION = 240;
86
+ /** How far the pill rises as it appears. */
87
+ const REVEAL_RISE = 10;
88
+ /**
89
+ * How long a jump from the panel is given to arrive before section changes
90
+ * start being felt again. Only reached when the scroll had nowhere to go.
91
+ */
92
+ const JUMP_TIMEOUT = 900;
93
+ /** List width: a floor so one short section still reads, and a cap so long
94
+ titles wrap instead of pushing the card across the screen. */
95
+ const LIST_MIN_WIDTH = 180;
96
+ const LIST_MAX_WIDTH = '86%';
97
+ /**
98
+ * How tall the list may grow before it scrolls: about six rows.
99
+ *
100
+ * A cap, and a `flexGrow: 0` beside it, because a `ScrollView` carries
101
+ * `flexGrow: 1` in its own base style — inside a card whose height comes from
102
+ * its contents, that is a list which fills every point the screen will give it
103
+ * and a card stretched from edge to edge behind six rows.
104
+ */
105
+ const LIST_MAX_HEIGHT = 260;
106
+ /**
107
+ * The collapsed pill's height, from what it is built out of: the ring and the
108
+ * padding either side of it.
109
+ *
110
+ * Halved, it is the closed corner radius — and it is a number rather than a
111
+ * `rounded-full` because a radius of 9999 on a bordered shape draws a border
112
+ * that thickens through the curve at each end and thins along the straight
113
+ * top and bottom. A radius that is exactly half the height curves once.
114
+ */
115
+ const PILL_HEIGHT = RING_SIZE + 12;
116
+ /** The card's radius once it has opened into a list. */
117
+ const CARD_RADIUS = 20;
118
+ /** How long the corner takes to round off into a card, and the list to arrive. */
119
+ const EXPAND_DURATION = 220;
120
+ const LIST_FADE = 160;
121
+ /** The border the card draws, and the radius the wash inside it takes. */
122
+ const CARD_BORDER = 1;
123
+
124
+ /** The colour an `Item` can bring with it. */
125
+
126
+ /** Which side of the pill's row the content sits on, per placement. */
127
+ const ALIGNMENT = {
128
+ 'top-left': 'items-start',
129
+ 'top-center': 'items-center',
130
+ 'top-right': 'items-end',
131
+ 'bottom-left': 'items-start',
132
+ 'bottom-center': 'items-center',
133
+ 'bottom-right': 'items-end'
134
+ };
135
+
136
+ /**
137
+ * The tokens, read in one call, and where each colour name sits in the result.
138
+ *
139
+ * One array call rather than one hook per name: an `Item`'s colour is a prop
140
+ * on a child element, and a hook cannot be run per child without the number of
141
+ * hooks changing with the number of sections.
142
+ */
143
+ const COLOR_TOKENS = ['--color-foreground', '--color-primary', '--color-success', '--color-warning', '--color-destructive', '--color-info', '--color-muted'];
144
+ const COLOR_INDEX = {
145
+ foreground: 0,
146
+ primary: 1,
147
+ success: 2,
148
+ warning: 3,
149
+ danger: 4,
150
+ info: 5
151
+ };
152
+ /** Where the track colour sits in the same result. */
153
+ const TRACK_INDEX = 6;
154
+ /** Drawn if a token cannot be resolved — a theme that has not loaded yet. */
155
+ const COLOR_FALLBACK = '#f5f5f5';
156
+ const TRACK_FALLBACK = '#3f3f46';
157
+
158
+ /**
159
+ * Where the scroller is.
160
+ *
161
+ * Three values rather than one fraction, because the fraction is not the only
162
+ * thing that is wanted: the reveal threshold is a distance in points, and a
163
+ * distance cannot be recovered from a percentage.
164
+ *
165
+ * Both `useScrollSections().scroll` and the `ScrollProgress` primitive's
166
+ * context satisfy this shape.
167
+ */
168
+
169
+ const SectionProgressContext = /*#__PURE__*/createContext(null);
170
+ function useSectionProgress(component) {
171
+ const context = useContext(SectionProgressContext);
172
+ if (!context) {
173
+ throw new Error(`${component} must be used within a <SectionProgress>`);
174
+ }
175
+ return context;
176
+ }
177
+ function SectionProgressRoot({
178
+ className,
179
+ scroll,
180
+ progress,
181
+ value: valueProp,
182
+ defaultValue,
183
+ onValueChange,
184
+ open: openProp,
185
+ defaultOpen = false,
186
+ onOpenChange,
187
+ placement = 'bottom-center',
188
+ offset = 16,
189
+ revealAt = 64,
190
+ haptics = false,
191
+ label = 'Sections',
192
+ children,
193
+ ...props
194
+ }) {
195
+ const insets = useSafeAreaInsets();
196
+ const reduceMotion = useReducedMotion();
197
+ const [internalValue, setInternalValue] = useState(defaultValue);
198
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
199
+ const isControlled = valueProp !== undefined;
200
+ const value = isControlled ? valueProp : internalValue;
201
+ const isOpenControlled = openProp !== undefined;
202
+ const open = isOpenControlled ? openProp : internalOpen;
203
+ const setOpen = useCallback(next => {
204
+ if (!isOpenControlled) setInternalOpen(next);
205
+ onOpenChange?.(next);
206
+ }, [isOpenControlled, onOpenChange]);
207
+ const close = useCallback(() => setOpen(false), [setOpen]);
208
+
209
+ // The panel owns the back button while it is up — back should put the list
210
+ // away, not leave the screen behind it.
211
+ useBackHandler(open, close);
212
+
213
+ /*
214
+ * The sections, read straight off the children.
215
+ *
216
+ * The pill has to draw the active section's own label and colour while the
217
+ * panel that holds the rows is closed and unmounted. Reading the elements is
218
+ * synchronous, so the first frame is already right — a registration effect
219
+ * would leave the pill blank until after mount, which is the frame the
220
+ * reveal animation is playing on.
221
+ */
222
+ const items = useMemo(() => {
223
+ const found = [];
224
+ Children.forEach(children, child => {
225
+ if (! /*#__PURE__*/isValidElement(child) || child.type !== SectionProgressItem) return;
226
+ const itemProps = child.props;
227
+ if (typeof itemProps.value !== 'string') return;
228
+ found.push({
229
+ value: itemProps.value,
230
+ label: itemProps.children,
231
+ color: itemProps.color
232
+ });
233
+ });
234
+ return found;
235
+ }, [children]);
236
+ const active = items.find(item => item.value === value) ?? items[0];
237
+
238
+ // Narrowed on the way out because `useCSSVariable` resolves to a number for
239
+ // any token that happens to be one.
240
+ const tokens = useCSSVariable(COLOR_TOKENS);
241
+ const resolved = tokens[COLOR_INDEX[active?.color ?? 'foreground']];
242
+ const tint = typeof resolved === 'string' ? resolved : COLOR_FALLBACK;
243
+ const trackToken = tokens[TRACK_INDEX];
244
+ const track = typeof trackToken === 'string' ? trackToken : TRACK_FALLBACK;
245
+
246
+ /* ------------------------------------------------------------------ *
247
+ * The ring
248
+ * ------------------------------------------------------------------ */
249
+
250
+ // Called unconditionally, used only as a fallback: a hook cannot sit behind
251
+ // a `??`, and the context returns null outside a provider anyway.
252
+ const inherited = useScrollProgress();
253
+ const source = scroll ?? inherited;
254
+ const filled = useSharedValue(0);
255
+ useAnimatedReaction(() => {
256
+ if (typeof progress === 'number') return progress;
257
+ if (progress) return progress.value;
258
+ if (!source) return 0;
259
+ const span = source.content.value - source.viewport.value;
260
+ return span > 0 ? source.offset.value / span : 0;
261
+ }, next => {
262
+ const clamped = next < 0 ? 0 : next > 1 ? 1 : next;
263
+ filled.value = withTiming(clamped, {
264
+ duration: PROGRESS_EASE
265
+ });
266
+ }, [progress, source]);
267
+ const radius = (RING_SIZE - RING_STROKE) / 2;
268
+ const circumference = 2 * Math.PI * radius;
269
+ const centre = RING_SIZE / 2;
270
+
271
+ /*
272
+ * A circle's stroke starts at three o'clock, so it is turned back a quarter
273
+ * to start at twelve. An arc that begins at three reads as a gauge already
274
+ * part-way along.
275
+ */
276
+ const rotate = `rotate(-90 ${centre} ${centre})`;
277
+
278
+ /* ------------------------------------------------------------------ *
279
+ * The reveal
280
+ * ------------------------------------------------------------------ */
281
+
282
+ /*
283
+ * A React state, not only a shared value: the pill has to stop taking
284
+ * touches while it is invisible, and `pointerEvents` is not a style. The
285
+ * reaction fires when the threshold is crossed rather than every frame, so
286
+ * this costs one hop to the JavaScript thread per scroll, not per event.
287
+ */
288
+ const [revealed, setRevealed] = useState(revealAt <= 0);
289
+ useAnimatedReaction(() => source ? source.offset.value >= revealAt : true, (next, previous) => {
290
+ if (next !== previous) runOnJS(setRevealed)(next);
291
+ }, [revealAt, source]);
292
+ const shown = useSharedValue(revealAt <= 0 ? 1 : 0);
293
+ useEffect(() => {
294
+ const to = revealed ? 1 : 0;
295
+ shown.value = reduceMotion ? to : withTiming(to, {
296
+ duration: REVEAL_DURATION
297
+ });
298
+ }, [revealed, reduceMotion, shown]);
299
+ const revealStyle = useAnimatedStyle(() => ({
300
+ opacity: shown.value,
301
+ transform: [{
302
+ translateY: interpolate(shown.value, [0, 1], [placement.startsWith('top') ? -REVEAL_RISE : REVEAL_RISE, 0])
303
+ }]
304
+ }));
305
+
306
+ /* ------------------------------------------------------------------ *
307
+ * The colour the section brings
308
+ * ------------------------------------------------------------------ */
309
+
310
+ /*
311
+ * Two colours and a scalar between them, rather than one colour swapped: a
312
+ * section change is a change of state the reader did not ask for, and one
313
+ * that lands instantly reads as a flicker rather than as a transition.
314
+ */
315
+ const [fade, setFade] = useState({
316
+ from: tint,
317
+ to: tint
318
+ });
319
+ const crossfade = useSharedValue(1);
320
+ useEffect(() => {
321
+ setFade(current => current.to === tint ? current : {
322
+ from: current.to,
323
+ to: tint
324
+ });
325
+ }, [tint]);
326
+ useEffect(() => {
327
+ if (fade.from === fade.to) return;
328
+ crossfade.value = 0;
329
+ crossfade.value = reduceMotion ? 1 : withTiming(1, {
330
+ duration: TINT_DURATION
331
+ });
332
+ }, [fade, crossfade, reduceMotion]);
333
+ const ringProps = useAnimatedProps(() => ({
334
+ strokeDasharray: [circumference * filled.value, circumference],
335
+ stroke: interpolateColor(crossfade.value, [0, 1], [fade.from, fade.to])
336
+ }));
337
+ const tintStyle = useAnimatedStyle(() => ({
338
+ color: interpolateColor(crossfade.value, [0, 1], [fade.from, fade.to])
339
+ }));
340
+ /*
341
+ * The corner, from a pill to a card.
342
+ *
343
+ * A number rather than `rounded-full`, because a radius far larger than the
344
+ * shape draws a border that thickens through each curved end and thins along
345
+ * the straight edges between them. Exactly half the height curves once, and
346
+ * the hairline stays one weight the whole way round.
347
+ */
348
+ const expanded = useSharedValue(open ? 1 : 0);
349
+ useEffect(() => {
350
+ const to = open ? 1 : 0;
351
+ expanded.value = reduceMotion ? to : withTiming(to, {
352
+ duration: EXPAND_DURATION
353
+ });
354
+ }, [open, reduceMotion, expanded]);
355
+ const cardStyle = useAnimatedStyle(() => ({
356
+ borderRadius: interpolate(expanded.value, [0, 1], [PILL_HEIGHT / 2, CARD_RADIUS])
357
+ }));
358
+ const washStyle = useAnimatedStyle(() => ({
359
+ backgroundColor: interpolateColor(crossfade.value, [0, 1], [fade.from, fade.to]),
360
+ // One point tighter than the card's, since it sits inside the border.
361
+ borderRadius: interpolate(expanded.value, [0, 1], [PILL_HEIGHT / 2, CARD_RADIUS]) - CARD_BORDER
362
+ }));
363
+
364
+ /* ------------------------------------------------------------------ *
365
+ * Choosing a section, and feeling the ones scrolled past
366
+ * ------------------------------------------------------------------ */
367
+
368
+ /*
369
+ * The section a tap asked for, while the screen is still travelling to it.
370
+ * A jump passes every section in between, and each of those arrives here as
371
+ * a change of section — one tap, three ticks, none of them a place the
372
+ * reader went.
373
+ */
374
+ const jumpTo = useRef(null);
375
+ const jumpTimer = useRef(null);
376
+ const endJump = useCallback(() => {
377
+ jumpTo.current = null;
378
+ if (jumpTimer.current) {
379
+ clearTimeout(jumpTimer.current);
380
+ jumpTimer.current = null;
381
+ }
382
+ }, []);
383
+ useEffect(() => () => endJump(), [endJump]);
384
+ const handleValueChange = useCallback(next => {
385
+ jumpTo.current = next;
386
+ if (jumpTimer.current) clearTimeout(jumpTimer.current);
387
+ // A backstop, not the usual way out: a jump to a section the scroller
388
+ // cannot reach never arrives, and without this nothing would tick again.
389
+ jumpTimer.current = setTimeout(endJump, JUMP_TIMEOUT);
390
+ if (!isControlled) setInternalValue(next);
391
+ onValueChange?.(next);
392
+ setOpen(false);
393
+ }, [isControlled, onValueChange, setOpen, endJump]);
394
+
395
+ /*
396
+ * Fired from the resolved value rather than from the handler, so a section
397
+ * arrived at by scrolling is felt as well as one that was tapped. The ref
398
+ * skips the first run — mounting is not a change of section.
399
+ */
400
+ const ticked = useRef(false);
401
+ useEffect(() => {
402
+ if (!ticked.current) {
403
+ ticked.current = true;
404
+ return;
405
+ }
406
+ if (jumpTo.current !== null) {
407
+ if (value !== jumpTo.current) return;
408
+ endJump();
409
+ }
410
+ if (haptics) selectionTick();
411
+ }, [value, haptics, endJump]);
412
+
413
+ /* ------------------------------------------------------------------ *
414
+ * What a screen reader is told
415
+ * ------------------------------------------------------------------ */
416
+
417
+ /*
418
+ * Rounded to five, and pushed across only when it changes: the ring is a
419
+ * continuous value and an announcement is not, so the number is coarse on
420
+ * purpose rather than accurate to a percent nobody can act on.
421
+ */
422
+ const [percent, setPercent] = useState(0);
423
+ useAnimatedReaction(() => Math.round(filled.value * 20) * 5, (next, previous) => {
424
+ if (next !== previous) runOnJS(setPercent)(next);
425
+ });
426
+ const activeLabel = typeof active?.label === 'string' ? active.label : undefined;
427
+ const context = useMemo(() => ({
428
+ value: active?.value,
429
+ onValueChange: handleValueChange,
430
+ close,
431
+ tint
432
+ }), [active?.value, handleValueChange, close, tint]);
433
+
434
+ /*
435
+ * Where the card sits, as padding on a full-screen overlay rather than as a
436
+ * position on the card itself.
437
+ *
438
+ * The overlay is what the dismiss layer needs: a press anywhere outside the
439
+ * card has to put the list away, and "anywhere" is the whole screen. It
440
+ * takes no touches of its own, so everything under it still scrolls.
441
+ */
442
+ const atTop = placement.startsWith('top');
443
+ return /*#__PURE__*/_jsx(SectionProgressContext.Provider, {
444
+ value: context,
445
+ children: /*#__PURE__*/_jsxs(View, {
446
+ pointerEvents: revealed ? 'box-none' : 'none',
447
+ style: [StyleSheet.absoluteFill, {
448
+ paddingTop: insets.top + offset,
449
+ paddingBottom: insets.bottom + offset,
450
+ paddingLeft: insets.left + offset,
451
+ paddingRight: insets.right + offset,
452
+ justifyContent: atTop ? 'flex-start' : 'flex-end'
453
+ }],
454
+ className: cn(ALIGNMENT[placement], className),
455
+ ...props,
456
+ children: [open ? /*#__PURE__*/_jsx(Pressable, {
457
+ accessibilityRole: "button",
458
+ accessibilityLabel: "Close",
459
+ onPress: close
460
+ /* Outside the card's padding, so it covers the screen rather than
461
+ the space left inside the insets. */,
462
+ style: {
463
+ position: 'absolute',
464
+ top: -(insets.top + offset),
465
+ bottom: -(insets.bottom + offset),
466
+ left: -(insets.left + offset),
467
+ right: -(insets.right + offset)
468
+ }
469
+ }) : null, /*#__PURE__*/_jsxs(Animated.View, {
470
+ /*
471
+ * No layout animation on this box, deliberately.
472
+ *
473
+ * A layout animation here animates every change of its size, and the
474
+ * size changes on every change of section: the label is a different
475
+ * word and the pill is a different width. What that draws is the
476
+ * surface arriving at the old width and closing in on the new word
477
+ * over a few hundred milliseconds — a band of empty card down each
478
+ * side of the label, once per section, on a control whose entire job
479
+ * is to be glanced at.
480
+ *
481
+ * The width belongs to the word, so it changes with the word. Only
482
+ * the opening is animated, and it is animated by the parts that
483
+ * open: the corner rounds off through `cardStyle`, and the list
484
+ * fades in over it.
485
+ */
486
+ style: [revealStyle, cardStyle, {
487
+ borderWidth: CARD_BORDER,
488
+ minWidth: open ? LIST_MIN_WIDTH : undefined,
489
+ maxWidth: LIST_MAX_WIDTH
490
+ }],
491
+ className: "border-border bg-popover shadow-lg",
492
+ children: [/*#__PURE__*/_jsx(Animated.View, {
493
+ pointerEvents: "none",
494
+ style: [washStyle, StyleSheet.absoluteFill, {
495
+ opacity: 0.09
496
+ }]
497
+ }), open && !atTop ? /*#__PURE__*/_jsx(SectionProgressList, {
498
+ reduceMotion: reduceMotion,
499
+ children: children
500
+ }) : null, /*#__PURE__*/_jsxs(Pressable, {
501
+ accessibilityRole: "button",
502
+ accessibilityLabel: activeLabel ? `${label}. ${activeLabel}. ${percent}% read.` : label,
503
+ accessibilityState: {
504
+ expanded: open
505
+ },
506
+ onPress: () => setOpen(!open),
507
+ className: "flex-row items-center gap-2.5 py-1.5 pe-4 ps-2",
508
+ children: [/*#__PURE__*/_jsx(View, {
509
+ accessibilityElementsHidden: true,
510
+ importantForAccessibility: "no-hide-descendants",
511
+ children: /*#__PURE__*/_jsx(Svg, {
512
+ width: RING_SIZE,
513
+ height: RING_SIZE,
514
+ children: /*#__PURE__*/_jsxs(G, {
515
+ children: [/*#__PURE__*/_jsx(Circle, {
516
+ cx: centre,
517
+ cy: centre,
518
+ r: radius,
519
+ stroke: track,
520
+ strokeWidth: RING_STROKE,
521
+ fill: "none"
522
+ }), /*#__PURE__*/_jsx(AnimatedCircle, {
523
+ animatedProps: ringProps,
524
+ cx: centre,
525
+ cy: centre,
526
+ r: radius,
527
+ strokeWidth: RING_STROKE,
528
+ strokeLinecap: "round",
529
+ fill: "none",
530
+ transform: rotate
531
+ })]
532
+ })
533
+ })
534
+ }), /*#__PURE__*/_jsx(Animated.Text, {
535
+ accessibilityElementsHidden: true,
536
+ importantForAccessibility: "no-hide-descendants",
537
+ style: tintStyle
538
+ // No `flex-1`: the card is sized by its contents, and a flex
539
+ // child inside an auto-width row takes a basis of zero — which
540
+ // is a label of no width at all.
541
+ ,
542
+ className: "text-sm font-medium",
543
+ numberOfLines: 1,
544
+ children: active?.label
545
+ })]
546
+ }), open && atTop ? /*#__PURE__*/_jsx(SectionProgressList, {
547
+ reduceMotion: reduceMotion,
548
+ children: children
549
+ }) : null]
550
+ })]
551
+ })
552
+ });
553
+ }
554
+
555
+ /**
556
+ * The sections.
557
+ *
558
+ * No rule between the list and the pill's row. The rows are already separated
559
+ * from the row below by their own gap and by the fill on the active one, and a
560
+ * hairline across a card this small draws a second edge a few points inside
561
+ * the one the card already has.
562
+ *
563
+ * It fades in and is gone on close, with no exit animation. An exiting
564
+ * animation keeps the view mounted as a snapshot while the card re-lays-out
565
+ * around it — the card shrinks to the pill under a list that is still on
566
+ * screen, so the control shifts and settles back over the following frames.
567
+ * Closing is one change, in one frame.
568
+ */
569
+ function SectionProgressList({
570
+ children,
571
+ reduceMotion
572
+ }) {
573
+ return /*#__PURE__*/_jsx(Animated.View, {
574
+ entering: reduceMotion ? undefined : FadeIn.duration(LIST_FADE),
575
+ accessibilityRole: "menu",
576
+ children: /*#__PURE__*/_jsx(ScrollView, {
577
+ bounces: false,
578
+ showsVerticalScrollIndicator: false
579
+ // The list is as tall as its rows, up to six of them. Both halves are
580
+ // needed: `flexGrow: 0` to undo the ScrollView's own base style, and
581
+ // the cap so a screen with twenty sections still opens a list rather
582
+ // than a full-height column.
583
+ ,
584
+ style: {
585
+ flexGrow: 0,
586
+ maxHeight: LIST_MAX_HEIGHT
587
+ },
588
+ contentContainerClassName: "gap-0.5 p-1.5",
589
+ children: textChildren(children)
590
+ })
591
+ });
592
+ }
593
+ /**
594
+ * One section: a row in the panel, and the label the pill shows while that
595
+ * section is the one being read.
596
+ */
597
+ function SectionProgressItem({
598
+ className,
599
+ value,
600
+ children
601
+ }) {
602
+ const {
603
+ value: active,
604
+ onValueChange,
605
+ tint
606
+ } = useSectionProgress('SectionProgress.Item');
607
+ const selected = active === value;
608
+ return /*#__PURE__*/_jsxs(Pressable, {
609
+ accessibilityRole: "menuitem",
610
+ accessibilityState: {
611
+ selected
612
+ },
613
+ onPress: () => onValueChange(value),
614
+ className: cn('flex-row items-center gap-3 rounded-xl px-3 py-2 active:bg-accent', selected && 'bg-accent', className),
615
+ children: [/*#__PURE__*/_jsx(View, {
616
+ style: selected ? {
617
+ backgroundColor: tint
618
+ } : undefined,
619
+ className: cn('h-1.5 w-1.5 rounded-full', !selected && 'bg-muted-foreground/40')
620
+ }), /*#__PURE__*/_jsx(Text, {
621
+ size: "sm",
622
+ weight: selected ? 'medium' : 'normal',
623
+ className: selected ? 'text-foreground' : 'text-muted-foreground'
624
+ // Two lines rather than one: an ellipsis in a navigator hides the very
625
+ // word that says which section the row would jump to.
626
+ ,
627
+ numberOfLines: 2,
628
+ children: children
629
+ })]
630
+ });
631
+ }
632
+ SectionProgressRoot.displayName = 'SectionProgress';
633
+ SectionProgressItem.displayName = 'SectionProgress.Item';
634
+ export const SectionProgress = Object.assign(SectionProgressRoot, {
635
+ Item: SectionProgressItem
636
+ });
637
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Children","createContext","isValidElement","useCallback","useContext","useEffect","useMemo","useRef","useState","Pressable","ScrollView","StyleSheet","View","Animated","FadeIn","interpolate","interpolateColor","runOnJS","useAnimatedProps","useAnimatedReaction","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","useSafeAreaInsets","Svg","Circle","G","useCSSVariable","useBackHandler","useScrollProgress","Text","textChildren","cn","selectionTick","jsx","_jsx","jsxs","_jsxs","AnimatedCircle","createAnimatedComponent","RING_SIZE","RING_STROKE","PROGRESS_EASE","REVEAL_DURATION","TINT_DURATION","REVEAL_RISE","JUMP_TIMEOUT","LIST_MIN_WIDTH","LIST_MAX_WIDTH","LIST_MAX_HEIGHT","PILL_HEIGHT","CARD_RADIUS","EXPAND_DURATION","LIST_FADE","CARD_BORDER","ALIGNMENT","COLOR_TOKENS","COLOR_INDEX","foreground","primary","success","warning","danger","info","TRACK_INDEX","COLOR_FALLBACK","TRACK_FALLBACK","SectionProgressContext","useSectionProgress","component","context","Error","SectionProgressRoot","className","scroll","progress","value","valueProp","defaultValue","onValueChange","open","openProp","defaultOpen","onOpenChange","placement","offset","revealAt","haptics","label","children","props","insets","reduceMotion","internalValue","setInternalValue","internalOpen","setInternalOpen","isControlled","undefined","isOpenControlled","setOpen","next","close","items","found","forEach","child","type","SectionProgressItem","itemProps","push","color","active","find","item","tokens","resolved","tint","trackToken","track","inherited","source","filled","span","content","viewport","clamped","duration","radius","circumference","Math","PI","centre","rotate","revealed","setRevealed","previous","shown","to","revealStyle","opacity","transform","translateY","startsWith","fade","setFade","from","crossfade","current","ringProps","strokeDasharray","stroke","tintStyle","expanded","cardStyle","borderRadius","washStyle","backgroundColor","jumpTo","jumpTimer","endJump","clearTimeout","handleValueChange","setTimeout","ticked","percent","setPercent","round","activeLabel","atTop","Provider","pointerEvents","style","absoluteFill","paddingTop","top","paddingBottom","bottom","paddingLeft","left","paddingRight","right","justifyContent","accessibilityRole","accessibilityLabel","onPress","position","borderWidth","minWidth","maxWidth","SectionProgressList","accessibilityState","accessibilityElementsHidden","importantForAccessibility","width","height","cx","cy","r","strokeWidth","fill","animatedProps","strokeLinecap","numberOfLines","entering","bounces","showsVerticalScrollIndicator","flexGrow","maxHeight","contentContainerClassName","selected","size","weight","displayName","SectionProgress","Object","assign","Item"],"sourceRoot":"../../../../src","sources":["components/section-progress/index.tsx"],"mappings":"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","ignoreList":[]}