panelui-native 0.76.0 → 0.78.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/ai-input/index.js +23 -7
- package/lib/module/components/ai-input/index.js.map +1 -1
- package/lib/module/components/area-chart/index.js +32 -25
- package/lib/module/components/area-chart/index.js.map +1 -1
- package/lib/module/components/bottom-sheet/index.js +98 -15
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/button/index.js +7 -1
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/funnel-chart/index.js +15 -2
- package/lib/module/components/funnel-chart/index.js.map +1 -1
- package/lib/module/components/heatmap-chart/index.js +19 -27
- package/lib/module/components/heatmap-chart/index.js.map +1 -1
- package/lib/module/components/hex-chart/index.js +2 -0
- package/lib/module/components/hex-chart/index.js.map +1 -1
- package/lib/module/components/line-chart/index.js +38 -31
- package/lib/module/components/line-chart/index.js.map +1 -1
- package/lib/module/components/marquee/index.js +91 -5
- package/lib/module/components/marquee/index.js.map +1 -1
- package/lib/module/components/pie-chart/index.js +15 -2
- package/lib/module/components/pie-chart/index.js.map +1 -1
- package/lib/module/components/plot/index.js +42 -44
- package/lib/module/components/plot/index.js.map +1 -1
- package/lib/module/components/progress-button/index.js +390 -0
- package/lib/module/components/progress-button/index.js.map +1 -0
- package/lib/module/components/progress-button/progress-button-hold.js +57 -0
- package/lib/module/components/progress-button/progress-button-hold.js.map +1 -0
- package/lib/module/components/scatter-chart/index.js +6 -25
- package/lib/module/components/scatter-chart/index.js.map +1 -1
- package/lib/module/components/section-rail/index.js +40 -17
- package/lib/module/components/section-rail/index.js.map +1 -1
- package/lib/module/components/select/index.js +1 -0
- package/lib/module/components/select/index.js.map +1 -1
- package/lib/module/components/slider/index.js +1 -0
- package/lib/module/components/slider/index.js.map +1 -1
- package/lib/module/components/split-view/index.js +54 -10
- package/lib/module/components/split-view/index.js.map +1 -1
- package/lib/module/components/switch/index.js +1 -0
- package/lib/module/components/switch/index.js.map +1 -1
- package/lib/module/components/timeline/index.js +145 -14
- package/lib/module/components/timeline/index.js.map +1 -1
- package/lib/module/components/toast/index.js +45 -11
- package/lib/module/components/toast/index.js.map +1 -1
- package/lib/module/components/treemap-chart/index.js +63 -6
- package/lib/module/components/treemap-chart/index.js.map +1 -1
- package/lib/module/components/waterfall-chart/index.js +20 -4
- package/lib/module/components/waterfall-chart/index.js.map +1 -1
- package/lib/module/hooks/index.js +1 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/use-scroll-sections.js +44 -2
- package/lib/module/hooks/use-scroll-sections.js.map +1 -1
- package/lib/module/hooks/use-skeleton-handoff.js +58 -0
- package/lib/module/hooks/use-skeleton-handoff.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/native/index.js.map +1 -1
- package/lib/typescript/src/components/ai-input/index.d.ts +24 -5
- package/lib/typescript/src/components/ai-input/index.d.ts.map +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts +15 -0
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/funnel-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts +55 -2
- package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
- package/lib/typescript/src/components/pie-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/plot/index.d.ts +1 -3
- package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
- package/lib/typescript/src/components/progress-button/index.d.ts +295 -0
- package/lib/typescript/src/components/progress-button/index.d.ts.map +1 -0
- package/lib/typescript/src/components/progress-button/progress-button-hold.d.ts +40 -0
- package/lib/typescript/src/components/progress-button/progress-button-hold.d.ts.map +1 -0
- package/lib/typescript/src/components/scatter-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/scatter-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/section-rail/index.d.ts.map +1 -1
- package/lib/typescript/src/components/split-view/index.d.ts +10 -1
- package/lib/typescript/src/components/split-view/index.d.ts.map +1 -1
- package/lib/typescript/src/components/timeline/index.d.ts +7 -0
- package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
- package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
- package/lib/typescript/src/components/treemap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/waterfall-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/index.d.ts +1 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-scroll-sections.d.ts +1 -0
- package/lib/typescript/src/hooks/use-scroll-sections.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-skeleton-handoff.d.ts +11 -0
- package/lib/typescript/src/hooks/use-skeleton-handoff.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native/index.d.ts +17 -0
- package/lib/typescript/src/native/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ai-input/index.tsx +46 -12
- package/src/components/area-chart/index.tsx +49 -37
- package/src/components/bottom-sheet/index.tsx +110 -12
- package/src/components/button/index.tsx +20 -1
- package/src/components/funnel-chart/index.tsx +10 -2
- package/src/components/heatmap-chart/index.tsx +27 -22
- package/src/components/hex-chart/index.tsx +22 -6
- package/src/components/line-chart/index.tsx +57 -43
- package/src/components/marquee/index.tsx +129 -6
- package/src/components/pie-chart/index.tsx +10 -2
- package/src/components/plot/index.tsx +66 -50
- package/src/components/progress-button/index.tsx +465 -0
- package/src/components/progress-button/progress-button-hold.ts +57 -0
- package/src/components/scatter-chart/index.tsx +4 -25
- package/src/components/section-rail/index.tsx +39 -19
- package/src/components/select/index.tsx +1 -1
- package/src/components/slider/index.tsx +1 -1
- package/src/components/split-view/index.tsx +53 -8
- package/src/components/switch/index.tsx +1 -1
- package/src/components/timeline/index.tsx +143 -17
- package/src/components/toast/index.tsx +60 -11
- package/src/components/treemap-chart/index.tsx +65 -8
- package/src/components/waterfall-chart/index.tsx +14 -4
- package/src/hooks/index.ts +5 -0
- package/src/hooks/use-scroll-sections.ts +52 -3
- package/src/hooks/use-skeleton-handoff.ts +69 -0
- package/src/index.ts +10 -0
- package/src/native/index.ts +17 -0
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ProgressButton — press and hold to confirm, with the wait drawn on the button.
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* <ProgressButton onComplete={wipe}>
|
|
8
|
+
* <ProgressButton.Label>Hold to erase</ProgressButton.Label>
|
|
9
|
+
* </ProgressButton>
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* For the action a confirmation dialog exists to slow down. A dialog asks the
|
|
13
|
+
* question somewhere else and takes the answer as a tap — which is two taps,
|
|
14
|
+
* and two taps in a row is a rhythm a hand falls into. A hold cannot be
|
|
15
|
+
* completed by accident and cannot be completed by habit: it has to be
|
|
16
|
+
* sustained, and the fill says for how much longer.
|
|
17
|
+
*
|
|
18
|
+
* ## The fill is the promise
|
|
19
|
+
*
|
|
20
|
+
* Nothing fires until the fill reaches the end. There is no tolerance near the
|
|
21
|
+
* top, because a tolerance means the button sometimes commits after the reader
|
|
22
|
+
* has deliberately let go — which is the one failure a confirmation control
|
|
23
|
+
* cannot have. Released early, the fill drains back, in proportion to how far
|
|
24
|
+
* it got.
|
|
25
|
+
*
|
|
26
|
+
* ## How it is drawn
|
|
27
|
+
*
|
|
28
|
+
* The fill is a clipped copy of the button in inverted colours, growing from
|
|
29
|
+
* the leading edge. That is what keeps the label legible across the boundary:
|
|
30
|
+
* a single label under a translucent wash goes muddy in the middle of the
|
|
31
|
+
* wipe, exactly where the eye is. Two labels, each at full contrast on its own
|
|
32
|
+
* ground, never do.
|
|
33
|
+
*
|
|
34
|
+
* The clip is a view under `overflow: 'hidden'`, and its width is animated.
|
|
35
|
+
* Animating a width is normally a layout pass per frame; this view is
|
|
36
|
+
* absolutely positioned over the button and its copy of the label is pinned to
|
|
37
|
+
* the button's own width, so nothing it contains reflows as it grows.
|
|
38
|
+
*
|
|
39
|
+
* ## Reduced motion
|
|
40
|
+
*
|
|
41
|
+
* The wipe is replaced by a stepped fill that advances in fifths. The hold
|
|
42
|
+
* still has to be legible — a control that asks you to wait and shows nothing
|
|
43
|
+
* is a broken button — so this is a coarser indicator, not the absence of one.
|
|
44
|
+
*/
|
|
45
|
+
import { createContext, forwardRef, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
46
|
+
import { Pressable, View } from 'react-native';
|
|
47
|
+
import Animated, { Easing, cancelAnimation, runOnJS, useAnimatedReaction, useAnimatedStyle, useReducedMotion, useSharedValue, withTiming } from 'react-native-reanimated';
|
|
48
|
+
import { tv } from 'tailwind-variants';
|
|
49
|
+
import { Text, textChildren } from "../../primitives/text.js";
|
|
50
|
+
import { impactKnock, selectionTick } from "../../utils/haptics.js";
|
|
51
|
+
import { DEFAULT_AUTO_RESET_DELAY, DEFAULT_RELEASE_DURATION, releaseDuration, resolveHoldDuration } from "./progress-button-hold.js";
|
|
52
|
+
|
|
53
|
+
/** How many steps the reduced-motion fill advances in. */
|
|
54
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
55
|
+
const REDUCED_STEPS = 5;
|
|
56
|
+
const progressButtonVariants = tv({
|
|
57
|
+
slots: {
|
|
58
|
+
/*
|
|
59
|
+
* A pill, not the `rounded-lg` the other buttons take.
|
|
60
|
+
*
|
|
61
|
+
* The fill is clipped by this radius, so the shape of the button is also
|
|
62
|
+
* the shape of the wipe's leading edge as it comes out of the corner. On a
|
|
63
|
+
* small radius that edge emerges square from a rounded box, which reads as
|
|
64
|
+
* a rectangle sliding out from under the button rather than as the button
|
|
65
|
+
* filling up.
|
|
66
|
+
*/
|
|
67
|
+
root: 'relative overflow-hidden rounded-full border',
|
|
68
|
+
/*
|
|
69
|
+
* The row inside the button. It is separate from `root` because the fill
|
|
70
|
+
* has to sit over the whole button including its padding — a wipe that
|
|
71
|
+
* stops at the text's own box leaves an unfilled margin down each side and
|
|
72
|
+
* reads as a progress bar someone put inside a button.
|
|
73
|
+
*/
|
|
74
|
+
content: 'flex-row items-center justify-center gap-2',
|
|
75
|
+
label: 'min-w-0 shrink text-center font-medium',
|
|
76
|
+
/** The inverted copy, drawn on the filled ground. */
|
|
77
|
+
fill: '',
|
|
78
|
+
fillLabel: 'min-w-0 shrink text-center font-medium'
|
|
79
|
+
},
|
|
80
|
+
variants: {
|
|
81
|
+
variant: {
|
|
82
|
+
primary: {
|
|
83
|
+
root: 'border-primary bg-transparent',
|
|
84
|
+
label: 'text-primary',
|
|
85
|
+
fill: 'bg-primary',
|
|
86
|
+
fillLabel: 'text-primary-foreground'
|
|
87
|
+
},
|
|
88
|
+
secondary: {
|
|
89
|
+
root: 'border-transparent bg-secondary',
|
|
90
|
+
label: 'text-secondary-foreground',
|
|
91
|
+
fill: 'bg-foreground',
|
|
92
|
+
fillLabel: 'text-background'
|
|
93
|
+
},
|
|
94
|
+
destructive: {
|
|
95
|
+
root: 'border-destructive bg-transparent',
|
|
96
|
+
label: 'text-destructive',
|
|
97
|
+
fill: 'bg-destructive',
|
|
98
|
+
fillLabel: 'text-destructive-solid-foreground'
|
|
99
|
+
},
|
|
100
|
+
success: {
|
|
101
|
+
root: 'border-success bg-transparent',
|
|
102
|
+
label: 'text-success',
|
|
103
|
+
fill: 'bg-success',
|
|
104
|
+
fillLabel: 'text-success-solid-foreground'
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
size: {
|
|
108
|
+
// Matched to Button's boxes, and `min-h-*` for the same reason: the
|
|
109
|
+
// label's glyphs grow with the system text size and the box has to grow
|
|
110
|
+
// with them.
|
|
111
|
+
// Wider than the equivalent Button, because the corner is a half-circle
|
|
112
|
+
// rather than a small radius: the curve eats into the side padding, and
|
|
113
|
+
// at Button's values the first and last glyphs sit against it.
|
|
114
|
+
sm: {
|
|
115
|
+
root: 'min-h-9',
|
|
116
|
+
content: 'min-h-9 gap-1.5 px-3.5 py-2',
|
|
117
|
+
label: 'text-[14px]',
|
|
118
|
+
fillLabel: 'text-[14px]'
|
|
119
|
+
},
|
|
120
|
+
md: {
|
|
121
|
+
root: 'min-h-11',
|
|
122
|
+
content: 'min-h-11 px-5 py-2.5',
|
|
123
|
+
label: 'text-[16px]',
|
|
124
|
+
fillLabel: 'text-[16px]'
|
|
125
|
+
},
|
|
126
|
+
lg: {
|
|
127
|
+
root: 'min-h-12',
|
|
128
|
+
content: 'min-h-12 px-7 py-2.5',
|
|
129
|
+
label: 'text-[18px]',
|
|
130
|
+
fillLabel: 'text-[18px]'
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
fullWidth: {
|
|
134
|
+
true: {
|
|
135
|
+
root: 'w-full'
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
disabled: {
|
|
139
|
+
true: {
|
|
140
|
+
root: 'opacity-[0.64]'
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
defaultVariants: {
|
|
145
|
+
variant: 'primary',
|
|
146
|
+
size: 'md'
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
/** How a progress button looks. */
|
|
151
|
+
|
|
152
|
+
/** How big a progress button is. */
|
|
153
|
+
|
|
154
|
+
const ProgressButtonContext = /*#__PURE__*/createContext(null);
|
|
155
|
+
function useProgressButtonContext(component) {
|
|
156
|
+
const context = useContext(ProgressButtonContext);
|
|
157
|
+
if (!context) throw new Error(`${component} must be used within a <ProgressButton>`);
|
|
158
|
+
return context;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** How far through the hold this button is, for something rendered inside it. */
|
|
162
|
+
export function useProgressButton() {
|
|
163
|
+
const {
|
|
164
|
+
progress,
|
|
165
|
+
completed
|
|
166
|
+
} = useProgressButtonContext('useProgressButton');
|
|
167
|
+
return {
|
|
168
|
+
progress,
|
|
169
|
+
completed
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const ProgressButtonRoot = /*#__PURE__*/forwardRef(function ProgressButtonRoot({
|
|
173
|
+
className,
|
|
174
|
+
variant = 'primary',
|
|
175
|
+
size = 'md',
|
|
176
|
+
fullWidth,
|
|
177
|
+
holdDuration,
|
|
178
|
+
onComplete,
|
|
179
|
+
onCompletedChange,
|
|
180
|
+
completed: completedProp,
|
|
181
|
+
autoReset = false,
|
|
182
|
+
autoResetDelay = DEFAULT_AUTO_RESET_DELAY,
|
|
183
|
+
disabled = false,
|
|
184
|
+
haptics = false,
|
|
185
|
+
accessibilityState,
|
|
186
|
+
children,
|
|
187
|
+
...props
|
|
188
|
+
}, ref) {
|
|
189
|
+
const slots = progressButtonVariants({
|
|
190
|
+
variant,
|
|
191
|
+
size,
|
|
192
|
+
fullWidth,
|
|
193
|
+
disabled
|
|
194
|
+
});
|
|
195
|
+
const duration = resolveHoldDuration(holdDuration);
|
|
196
|
+
const reducedMotion = useReducedMotion();
|
|
197
|
+
const progress = useSharedValue(0);
|
|
198
|
+
const [width, setWidth] = useState(0);
|
|
199
|
+
const [internalCompleted, setInternalCompleted] = useState(false);
|
|
200
|
+
const resetTimer = useRef(null);
|
|
201
|
+
const isControlled = completedProp !== undefined;
|
|
202
|
+
const completed = isControlled ? completedProp : internalCompleted;
|
|
203
|
+
const finish = useCallback(() => {
|
|
204
|
+
if (!isControlled) setInternalCompleted(true);
|
|
205
|
+
onCompletedChange?.(true);
|
|
206
|
+
onComplete?.();
|
|
207
|
+
if (haptics) impactKnock();
|
|
208
|
+
}, [isControlled, onComplete, onCompletedChange, haptics]);
|
|
209
|
+
|
|
210
|
+
/*
|
|
211
|
+
* Completion is read off the animation rather than timed alongside it.
|
|
212
|
+
*
|
|
213
|
+
* A `setTimeout` for `holdDuration` and a fill for `holdDuration` are two
|
|
214
|
+
* clocks that agree only while the app is idle: the moment the JS thread is
|
|
215
|
+
* busy the button fires before the fill arrives, or the fill sits full while
|
|
216
|
+
* nothing happens. The reaction fires on the frame the value actually
|
|
217
|
+
* reaches the end, which is the frame the reader saw it get there.
|
|
218
|
+
*/
|
|
219
|
+
useAnimatedReaction(() => progress.value >= 1, (full, was) => {
|
|
220
|
+
if (full && !was) runOnJS(finish)();
|
|
221
|
+
});
|
|
222
|
+
const begin = useCallback(() => {
|
|
223
|
+
if (disabled || completed) return;
|
|
224
|
+
if (haptics) selectionTick();
|
|
225
|
+
cancelAnimation(progress);
|
|
226
|
+
if (reducedMotion) {
|
|
227
|
+
/*
|
|
228
|
+
* Stepped rather than smooth, and still a real indicator. What reduced
|
|
229
|
+
* motion is about is continuous movement, not the button telling you how
|
|
230
|
+
* much longer to wait — take that away and the control asks for a hold
|
|
231
|
+
* with nothing on screen to say why.
|
|
232
|
+
*/
|
|
233
|
+
progress.value = withTiming(1, {
|
|
234
|
+
duration,
|
|
235
|
+
easing: Easing.steps(REDUCED_STEPS, true)
|
|
236
|
+
});
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
// Linear. A fill is constant motion, and an eased one misreports the wait:
|
|
240
|
+
// it races the first half and crawls the second, or the reverse.
|
|
241
|
+
progress.value = withTiming(1, {
|
|
242
|
+
duration,
|
|
243
|
+
easing: Easing.linear
|
|
244
|
+
});
|
|
245
|
+
}, [disabled, completed, haptics, progress, reducedMotion, duration]);
|
|
246
|
+
const abandon = useCallback(() => {
|
|
247
|
+
cancelAnimation(progress);
|
|
248
|
+
if (progress.value <= 0) return;
|
|
249
|
+
progress.value = withTiming(0, {
|
|
250
|
+
// Proportional to how far it got. A fixed release makes a hold abandoned
|
|
251
|
+
// after a moment feel sticky, which reads as the button resisting.
|
|
252
|
+
duration: releaseDuration(progress.value, DEFAULT_RELEASE_DURATION),
|
|
253
|
+
easing: Easing.out(Easing.cubic)
|
|
254
|
+
});
|
|
255
|
+
}, [progress]);
|
|
256
|
+
const reset = useCallback(() => {
|
|
257
|
+
cancelAnimation(progress);
|
|
258
|
+
progress.value = 0;
|
|
259
|
+
if (!isControlled) setInternalCompleted(false);
|
|
260
|
+
onCompletedChange?.(false);
|
|
261
|
+
}, [progress, isControlled, onCompletedChange]);
|
|
262
|
+
useEffect(() => {
|
|
263
|
+
if (!completed || !autoReset) return;
|
|
264
|
+
resetTimer.current = setTimeout(reset, autoResetDelay);
|
|
265
|
+
return () => {
|
|
266
|
+
if (resetTimer.current) clearTimeout(resetTimer.current);
|
|
267
|
+
resetTimer.current = null;
|
|
268
|
+
};
|
|
269
|
+
}, [completed, autoReset, autoResetDelay, reset]);
|
|
270
|
+
|
|
271
|
+
// A controlled button told it is no longer complete has to empty its fill,
|
|
272
|
+
// or the next hold starts from a bar that is already full.
|
|
273
|
+
useEffect(() => {
|
|
274
|
+
if (!completed) return;
|
|
275
|
+
progress.value = 1;
|
|
276
|
+
}, [completed, progress]);
|
|
277
|
+
useEffect(() => () => {
|
|
278
|
+
cancelAnimation(progress);
|
|
279
|
+
if (resetTimer.current) clearTimeout(resetTimer.current);
|
|
280
|
+
}, [progress]);
|
|
281
|
+
const onLayout = event => {
|
|
282
|
+
const next = Math.round(event.nativeEvent.layout.width);
|
|
283
|
+
setWidth(current => current === next ? current : next);
|
|
284
|
+
props.onLayout?.(event);
|
|
285
|
+
};
|
|
286
|
+
const context = useMemo(() => ({
|
|
287
|
+
progress,
|
|
288
|
+
width,
|
|
289
|
+
completed,
|
|
290
|
+
variant,
|
|
291
|
+
size,
|
|
292
|
+
slots
|
|
293
|
+
}), [progress, width, completed, variant, size, slots]);
|
|
294
|
+
const body = children ?? /*#__PURE__*/_jsx(_Fragment, {
|
|
295
|
+
children: /*#__PURE__*/_jsx(ProgressButtonLabel, {
|
|
296
|
+
children: "Hold to confirm"
|
|
297
|
+
})
|
|
298
|
+
});
|
|
299
|
+
return /*#__PURE__*/_jsx(ProgressButtonContext.Provider, {
|
|
300
|
+
value: context,
|
|
301
|
+
children: /*#__PURE__*/_jsx(Pressable, {
|
|
302
|
+
ref: ref,
|
|
303
|
+
accessibilityRole: "button"
|
|
304
|
+
/*
|
|
305
|
+
* Spoken as what it is. A button whose label says "Hold to confirm"
|
|
306
|
+
* still announces as an ordinary button to anyone who cannot see the
|
|
307
|
+
* fill, and a single activation does nothing — so the hint carries the
|
|
308
|
+
* instruction and the state carries the outcome.
|
|
309
|
+
*/,
|
|
310
|
+
accessibilityHint: "Press and hold to confirm",
|
|
311
|
+
accessibilityState: {
|
|
312
|
+
...accessibilityState,
|
|
313
|
+
disabled,
|
|
314
|
+
checked: completed
|
|
315
|
+
},
|
|
316
|
+
disabled: disabled,
|
|
317
|
+
onPressIn: begin,
|
|
318
|
+
onPressOut: abandon
|
|
319
|
+
// A few points of drift should not abandon a hold the reader is
|
|
320
|
+
// still making. Fingers move.
|
|
321
|
+
,
|
|
322
|
+
pressRetentionOffset: 16,
|
|
323
|
+
...props,
|
|
324
|
+
onLayout: onLayout,
|
|
325
|
+
className: slots.root({
|
|
326
|
+
className
|
|
327
|
+
}),
|
|
328
|
+
children: body
|
|
329
|
+
})
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
/**
|
|
333
|
+
* What the button says, drawn twice.
|
|
334
|
+
*
|
|
335
|
+
* The second copy is the one inside the fill, in the inverted colour, pinned to
|
|
336
|
+
* the button's own width and clipped to however far the hold has got. Both are
|
|
337
|
+
* the same text at the same position, so the boundary between them falls in the
|
|
338
|
+
* middle of a glyph rather than between two differently laid-out lines.
|
|
339
|
+
*/
|
|
340
|
+
function ProgressButtonLabel({
|
|
341
|
+
className,
|
|
342
|
+
children,
|
|
343
|
+
...props
|
|
344
|
+
}) {
|
|
345
|
+
const {
|
|
346
|
+
progress,
|
|
347
|
+
width,
|
|
348
|
+
slots
|
|
349
|
+
} = useProgressButtonContext('ProgressButton.Label');
|
|
350
|
+
const fillStyle = useAnimatedStyle(() => ({
|
|
351
|
+
width: width * progress.value
|
|
352
|
+
}));
|
|
353
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
354
|
+
...props,
|
|
355
|
+
className: slots.content({
|
|
356
|
+
className
|
|
357
|
+
}),
|
|
358
|
+
children: [textChildren(children, text => /*#__PURE__*/_jsx(Text, {
|
|
359
|
+
className: slots.label(),
|
|
360
|
+
children: text
|
|
361
|
+
})), /*#__PURE__*/_jsx(Animated.View, {
|
|
362
|
+
pointerEvents: "none",
|
|
363
|
+
style: [{
|
|
364
|
+
position: 'absolute',
|
|
365
|
+
top: 0,
|
|
366
|
+
bottom: 0,
|
|
367
|
+
left: 0,
|
|
368
|
+
overflow: 'hidden'
|
|
369
|
+
}, fillStyle],
|
|
370
|
+
className: slots.fill(),
|
|
371
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
372
|
+
style: {
|
|
373
|
+
width
|
|
374
|
+
},
|
|
375
|
+
className: slots.content(),
|
|
376
|
+
children: textChildren(children, text => /*#__PURE__*/_jsx(Text, {
|
|
377
|
+
className: slots.fillLabel(),
|
|
378
|
+
children: text
|
|
379
|
+
}))
|
|
380
|
+
})
|
|
381
|
+
})]
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
ProgressButtonLabel.displayName = 'ProgressButton.Label';
|
|
385
|
+
ProgressButtonRoot.displayName = 'ProgressButton';
|
|
386
|
+
export const ProgressButton = Object.assign(ProgressButtonRoot, {
|
|
387
|
+
Label: ProgressButtonLabel
|
|
388
|
+
});
|
|
389
|
+
export { DEFAULT_AUTO_RESET_DELAY, DEFAULT_HOLD_DURATION, DEFAULT_RELEASE_DURATION, isComplete, releaseDuration, resolveHoldDuration } from "./progress-button-hold.js";
|
|
390
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createContext","forwardRef","useCallback","useContext","useEffect","useMemo","useRef","useState","Pressable","View","Animated","Easing","cancelAnimation","runOnJS","useAnimatedReaction","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","tv","Text","textChildren","impactKnock","selectionTick","DEFAULT_AUTO_RESET_DELAY","DEFAULT_RELEASE_DURATION","releaseDuration","resolveHoldDuration","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","REDUCED_STEPS","progressButtonVariants","slots","root","content","label","fill","fillLabel","variants","variant","primary","secondary","destructive","success","size","sm","md","lg","fullWidth","true","disabled","defaultVariants","ProgressButtonContext","useProgressButtonContext","component","context","Error","useProgressButton","progress","completed","ProgressButtonRoot","className","holdDuration","onComplete","onCompletedChange","completedProp","autoReset","autoResetDelay","haptics","accessibilityState","children","props","ref","duration","reducedMotion","width","setWidth","internalCompleted","setInternalCompleted","resetTimer","isControlled","undefined","finish","value","full","was","begin","easing","steps","linear","abandon","out","cubic","reset","current","setTimeout","clearTimeout","onLayout","event","next","Math","round","nativeEvent","layout","body","ProgressButtonLabel","Provider","accessibilityRole","accessibilityHint","checked","onPressIn","onPressOut","pressRetentionOffset","fillStyle","text","pointerEvents","style","position","top","bottom","left","overflow","displayName","ProgressButton","Object","assign","Label","DEFAULT_HOLD_DURATION","isComplete"],"sourceRoot":"../../../../src","sources":["components/progress-button/index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The arithmetic behind a hold, kept out of the component so it can be tested
|
|
5
|
+
* without a renderer — the same split `splitter-math` and `ai-input-growth` use.
|
|
6
|
+
*
|
|
7
|
+
* None of it is worklet-only, so the component can call it from either runtime.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Milliseconds a hold has to be sustained before it counts. */
|
|
11
|
+
export const DEFAULT_HOLD_DURATION = 2000;
|
|
12
|
+
|
|
13
|
+
/** Milliseconds the fill takes to drain when a hold is abandoned. */
|
|
14
|
+
export const DEFAULT_RELEASE_DURATION = 240;
|
|
15
|
+
|
|
16
|
+
/** Milliseconds before an `autoReset` button offers itself again. */
|
|
17
|
+
export const DEFAULT_AUTO_RESET_DELAY = 1000;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A hold duration that cannot produce a broken animation.
|
|
21
|
+
*
|
|
22
|
+
* Zero would complete on touch-down, which defeats the point of the control:
|
|
23
|
+
* a hold-to-confirm that confirms on a tap is a button with extra steps. A
|
|
24
|
+
* floor rather than a rejection, because the caller asking for `0` wants it
|
|
25
|
+
* fast, not broken.
|
|
26
|
+
*/
|
|
27
|
+
export function resolveHoldDuration(duration) {
|
|
28
|
+
if (duration === undefined) return DEFAULT_HOLD_DURATION;
|
|
29
|
+
if (!Number.isFinite(duration)) return DEFAULT_HOLD_DURATION;
|
|
30
|
+
return Math.max(200, duration);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* How long the fill should take to drain from where it is.
|
|
35
|
+
*
|
|
36
|
+
* Proportional to how far it got, so abandoning a hold at a tenth of the way
|
|
37
|
+
* does not take the same quarter-second as abandoning it at nine tenths. A
|
|
38
|
+
* fixed release makes a barely-started hold feel sticky, which reads as the
|
|
39
|
+
* control resisting being let go.
|
|
40
|
+
*/
|
|
41
|
+
export function releaseDuration(progress, full = DEFAULT_RELEASE_DURATION) {
|
|
42
|
+
const travelled = Math.min(1, Math.max(0, progress));
|
|
43
|
+
return Math.max(80, full * travelled);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Whether a hold that has been released should still be honoured.
|
|
48
|
+
*
|
|
49
|
+
* The fill is the promise, so anything short of the end is not a confirmation —
|
|
50
|
+
* there is no "close enough" here. It exists as a named function because the
|
|
51
|
+
* tempting version of this rule is a tolerance, and a tolerance means the
|
|
52
|
+
* button sometimes fires when the reader let go early on purpose.
|
|
53
|
+
*/
|
|
54
|
+
export function isComplete(progress) {
|
|
55
|
+
return progress >= 1;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=progress-button-hold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DEFAULT_HOLD_DURATION","DEFAULT_RELEASE_DURATION","DEFAULT_AUTO_RESET_DELAY","resolveHoldDuration","duration","undefined","Number","isFinite","Math","max","releaseDuration","progress","full","travelled","min","isComplete"],"sourceRoot":"../../../../src","sources":["components/progress-button/progress-button-hold.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO,MAAMA,qBAAqB,GAAG,IAAI;;AAEzC;AACA,OAAO,MAAMC,wBAAwB,GAAG,GAAG;;AAE3C;AACA,OAAO,MAAMC,wBAAwB,GAAG,IAAI;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CAACC,QAA4B,EAAU;EACxE,IAAIA,QAAQ,KAAKC,SAAS,EAAE,OAAOL,qBAAqB;EACxD,IAAI,CAACM,MAAM,CAACC,QAAQ,CAACH,QAAQ,CAAC,EAAE,OAAOJ,qBAAqB;EAC5D,OAAOQ,IAAI,CAACC,GAAG,CAAC,GAAG,EAAEL,QAAQ,CAAC;AAChC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASM,eAAeA,CAC7BC,QAAgB,EAChBC,IAAY,GAAGX,wBAAwB,EAC/B;EACR,MAAMY,SAAS,GAAGL,IAAI,CAACM,GAAG,CAAC,CAAC,EAAEN,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEE,QAAQ,CAAC,CAAC;EACpD,OAAOH,IAAI,CAACC,GAAG,CAAC,EAAE,EAAEG,IAAI,GAAGC,SAAS,CAAC;AACvC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,UAAUA,CAACJ,QAAgB,EAAW;EACpD,OAAOA,QAAQ,IAAI,CAAC;AACtB","ignoreList":[]}
|
|
@@ -50,6 +50,7 @@ import { Text } from "../../primitives/text.js";
|
|
|
50
50
|
import { ChartAccessibilityData } from "../../primitives/chart-accessibility.js";
|
|
51
51
|
import { compactNumber, useSeriesColor, xAt, yOf } from "../../utils/chart.js";
|
|
52
52
|
import { cn } from "../../utils/cn.js";
|
|
53
|
+
import { useSkeletonHandoff } from "../../hooks/use-skeleton-handoff.js";
|
|
53
54
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
54
55
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
|
55
56
|
const AnimatedG = Animated.createAnimatedComponent(G);
|
|
@@ -61,9 +62,6 @@ const AnimatedG = Animated.createAnimatedComponent(G);
|
|
|
61
62
|
*/
|
|
62
63
|
const STAGGER = 0.4;
|
|
63
64
|
|
|
64
|
-
/** Milliseconds for the placeholder field to dissolve once the data arrives. */
|
|
65
|
-
const SKELETON_FADE = 220;
|
|
66
|
-
|
|
67
65
|
/** Milliseconds for a point to swell as it is selected, and settle as it is not. */
|
|
68
66
|
const SELECT_DURATION = 140;
|
|
69
67
|
|
|
@@ -153,7 +151,7 @@ const ScatterChartRoot = /*#__PURE__*/forwardRef(function ScatterChartRoot({
|
|
|
153
151
|
xDataKey = 'x',
|
|
154
152
|
status = 'ready',
|
|
155
153
|
aspectRatio = 1,
|
|
156
|
-
animationDuration =
|
|
154
|
+
animationDuration = 650,
|
|
157
155
|
domainDuration = 500,
|
|
158
156
|
xDomain,
|
|
159
157
|
yDomain,
|
|
@@ -678,27 +676,10 @@ function ScatterChartSkeleton({
|
|
|
678
676
|
} = useChart('ScatterChart.Skeleton');
|
|
679
677
|
const token = useCSSVariable('--color-skeleton');
|
|
680
678
|
const fill = color ?? (typeof token === 'string' ? token : 'rgba(128,128,128,0.2)');
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
const [mounted, setMounted] = useState(loading);
|
|
686
|
-
useEffect(() => {
|
|
687
|
-
if (loading) {
|
|
688
|
-
fade.value = 1;
|
|
689
|
-
setMounted(true);
|
|
690
|
-
return;
|
|
691
|
-
}
|
|
692
|
-
if (reducedMotion) {
|
|
693
|
-
setMounted(false);
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
fade.value = withTiming(0, {
|
|
697
|
-
duration: SKELETON_FADE
|
|
698
|
-
}, finished => {
|
|
699
|
-
if (finished) runOnJS(setMounted)(false);
|
|
700
|
-
});
|
|
701
|
-
}, [loading, reducedMotion, fade]);
|
|
679
|
+
const {
|
|
680
|
+
mounted,
|
|
681
|
+
opacity: fade
|
|
682
|
+
} = useSkeletonHandoff(status === 'loading');
|
|
702
683
|
const dots = useMemo(() => {
|
|
703
684
|
// A cheap deterministic scatter: two irrational-ish strides that do not
|
|
704
685
|
// share a factor, so the points spread instead of falling into a lattice.
|