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.
- package/lib/module/components/animated-badge/index.js +10 -2
- package/lib/module/components/animated-badge/index.js.map +1 -1
- package/lib/module/components/avatar/index.js +10 -1
- package/lib/module/components/avatar/index.js.map +1 -1
- package/lib/module/components/search-bar/index.js +35 -7
- package/lib/module/components/search-bar/index.js.map +1 -1
- package/lib/module/components/section-progress/index.js +637 -0
- package/lib/module/components/section-progress/index.js.map +1 -0
- package/lib/module/components/selection-mode/index.js +33 -3
- package/lib/module/components/selection-mode/index.js.map +1 -1
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/use-scroll-sections.js +58 -4
- package/lib/module/hooks/use-scroll-sections.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/components/animated-badge/index.d.ts +19 -0
- package/lib/typescript/src/components/animated-badge/index.d.ts.map +1 -1
- package/lib/typescript/src/components/avatar/index.d.ts.map +1 -1
- package/lib/typescript/src/components/search-bar/index.d.ts +4 -1
- package/lib/typescript/src/components/search-bar/index.d.ts.map +1 -1
- package/lib/typescript/src/components/section-progress/index.d.ts +156 -0
- package/lib/typescript/src/components/section-progress/index.d.ts.map +1 -0
- package/lib/typescript/src/components/selection-mode/index.d.ts +63 -0
- package/lib/typescript/src/components/selection-mode/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/index.d.ts +1 -1
- package/lib/typescript/src/hooks/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-scroll-sections.d.ts +24 -0
- package/lib/typescript/src/hooks/use-scroll-sections.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/animated-badge/index.tsx +24 -2
- package/src/components/avatar/index.tsx +10 -1
- package/src/components/search-bar/index.tsx +33 -8
- package/src/components/section-progress/index.tsx +813 -0
- package/src/components/selection-mode/index.tsx +30 -3
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-scroll-sections.ts +84 -5
- 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":[]}
|