@expokit/cli 0.4.4 → 0.5.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/README.md +30 -3
- package/bin/expo-kit.js +749 -288
- package/bin/lib.mjs +310 -3
- package/package.json +1 -1
- package/registry/_docs/action-sheet.json +1 -1
- package/registry/_docs/alert.json +6 -0
- package/registry/_docs/bottom-sheet.json +6 -0
- package/registry/_docs/bullet.json +6 -0
- package/registry/_docs/dialog.json +1 -1
- package/registry/_docs/drawer.json +3 -3
- package/registry/_docs/glass-search-bar.json +1 -1
- package/registry/_docs/grain.json +6 -1
- package/registry/_docs/isometric-bar.json +6 -0
- package/registry/_docs/liquidglass-tab.json +1 -1
- package/registry/_docs/password-input.json +1 -1
- package/registry/_docs/pixel-bar.json +6 -0
- package/registry/_docs/polar-area.json +6 -0
- package/registry/_docs/qr-code-button.json +9 -3
- package/registry/_docs/scratch-card.json +7 -1
- package/registry/_docs/search-bar.json +1 -1
- package/registry/_docs/select.json +2 -2
- package/registry/_docs/slide-to-confirm.json +2 -2
- package/registry/_docs/spinner.json +1 -1
- package/registry/_docs/stateful-button.json +2 -2
- package/registry/_docs/swipe-deck.json +1 -1
- package/registry/_docs/time-picker.json +2 -2
- package/registry/_docs/timeline-chart.json +6 -0
- package/registry/_docs/toast.json +15 -3
- package/registry/_docs/treemap.json +6 -0
- package/registry/_docs/waterfall.json +6 -0
- package/registry/accordion/files/src/components/ui/accordion.tsx +6 -4
- package/registry/accordion/files/src/lib/kit.tsx +363 -11
- package/registry/accordion.json +1 -0
- package/registry/action-sheet/files/src/components/ui/action-sheet.tsx +43 -48
- package/registry/action-sheet/files/src/lib/kit.tsx +363 -11
- package/registry/action-sheet.json +1 -0
- package/registry/alert/files/src/components/ui/alert.tsx +19 -12
- package/registry/alert/files/src/lib/kit.tsx +363 -11
- package/registry/alert.json +3 -4
- package/registry/assistant-app.json +1 -0
- package/registry/avatar/files/src/components/ui/avatar.tsx +84 -66
- package/registry/avatar/files/src/lib/kit.tsx +363 -11
- package/registry/avatar.json +1 -0
- package/registry/badge/files/src/components/ui/badge.tsx +34 -34
- package/registry/badge/files/src/lib/kit.tsx +363 -11
- package/registry/badge.json +1 -0
- package/registry/bottom-nav/files/src/components/ui/bottom-nav.tsx +28 -27
- package/registry/bottom-nav/files/src/lib/kit.tsx +363 -11
- package/registry/bottom-nav.json +5 -0
- package/registry/bottom-sheet/files/src/components/ui/bottom-sheet.tsx +353 -289
- package/registry/bottom-sheet/files/src/lib/kit.tsx +363 -11
- package/registry/bottom-sheet.json +5 -1
- package/registry/bullet.json +1 -0
- package/registry/button/files/src/components/ui/button.tsx +18 -16
- package/registry/button/files/src/lib/kit.tsx +363 -11
- package/registry/button-3d/files/src/components/ui/button-3d.tsx +2 -2
- package/registry/button-3d/files/src/lib/kit.tsx +363 -11
- package/registry/button-3d.json +1 -0
- package/registry/button.json +1 -0
- package/registry/calendar/files/src/components/ui/calendar.tsx +74 -76
- package/registry/calendar/files/src/lib/kit.tsx +363 -11
- package/registry/calendar.json +1 -0
- package/registry/card/files/src/components/ui/card.tsx +3 -3
- package/registry/card/files/src/lib/kit.tsx +363 -11
- package/registry/card-stack.json +1 -0
- package/registry/card.json +1 -0
- package/registry/carousel.json +1 -0
- package/registry/chat.json +7 -0
- package/registry/checkbox/files/src/components/ui/checkbox.tsx +4 -4
- package/registry/checkbox/files/src/lib/kit.tsx +363 -11
- package/registry/checkbox.json +1 -0
- package/registry/checkout.json +1 -0
- package/registry/chip-group/files/src/components/ui/chip-group.tsx +22 -22
- package/registry/chip-group/files/src/lib/kit.tsx +363 -11
- package/registry/chip-group.json +1 -0
- package/registry/confetti/files/src/components/ui/confetti.tsx +15 -14
- package/registry/confetti.json +3 -6
- package/registry/coupon/files/src/components/ui/coupon.tsx +42 -42
- package/registry/coupon/files/src/components/ui/flip-card.tsx +6 -5
- package/registry/coupon/files/src/components/ui/tilt-card.tsx +76 -91
- package/registry/coupon/files/src/lib/kit.tsx +363 -11
- package/registry/coupon/files/src/lib/ticket-shape.tsx +54 -44
- package/registry/coupon.json +1 -0
- package/registry/cube-pager.json +1 -0
- package/registry/dashboard.json +1 -0
- package/registry/date-picker/files/src/components/ui/calendar.tsx +74 -76
- package/registry/date-picker/files/src/components/ui/date-picker.tsx +55 -56
- package/registry/date-picker/files/src/lib/kit.tsx +363 -11
- package/registry/date-picker.json +1 -0
- package/registry/dialog/files/src/components/ui/dialog.tsx +60 -56
- package/registry/dialog/files/src/lib/kit.tsx +363 -11
- package/registry/dialog.json +1 -0
- package/registry/donut-shop.json +1 -0
- package/registry/drawer/files/src/components/ui/drawer.tsx +73 -69
- package/registry/drawer/files/src/lib/kit.tsx +363 -11
- package/registry/drawer.json +1 -0
- package/registry/fab.json +1 -0
- package/registry/fintech-app.json +1 -0
- package/registry/flip-calendar/files/src/components/ui/flip-calendar.tsx +92 -86
- package/registry/flip-calendar/files/src/lib/kit.tsx +363 -11
- package/registry/flip-calendar.json +7 -0
- package/registry/flip-card/files/src/components/ui/flip-card.tsx +6 -5
- package/registry/flip-card/files/src/lib/kit.tsx +363 -11
- package/registry/flip-card.json +1 -0
- package/registry/floating-input/files/src/components/ui/floating-input.tsx +33 -33
- package/registry/floating-input/files/src/lib/kit.tsx +363 -11
- package/registry/floating-input.json +1 -0
- package/registry/food-app.json +1 -0
- package/registry/gift-card.json +1 -0
- package/registry/glass-button.json +5 -0
- package/registry/glass-nav-bar.json +1 -0
- package/registry/glass-search-bar.json +1 -0
- package/registry/glass-segmented.json +1 -0
- package/registry/glass-sheet.json +1 -0
- package/registry/glass-tab-bar.json +5 -0
- package/registry/glass.json +1 -0
- package/registry/grain/files/src/components/ui/grain.tsx +16 -14
- package/registry/grain.json +8 -6
- package/registry/inbox.json +1 -0
- package/registry/isometric-bar.json +1 -0
- package/registry/kit/files/src/lib/kit.tsx +363 -11
- package/registry/kit.json +1 -0
- package/registry/liquidglass-tab/files/src/app/_layout.tsx +0 -1
- package/registry/liquidglass-tab/files/src/components/GlassTabBar.tsx +23 -9
- package/registry/liquidglass-tab/files/src/components/TabScreen.tsx +2 -2
- package/registry/liquidglass-tab/files/src/lib/tab-icons.ts +1 -1
- package/registry/liquidglass-tab.json +1 -0
- package/registry/list-item/files/src/components/ui/list-item.tsx +42 -42
- package/registry/list-item/files/src/lib/kit.tsx +363 -11
- package/registry/list-item.json +1 -0
- package/registry/loyalty-card.json +1 -0
- package/registry/morphing-button-group.json +1 -0
- package/registry/number-ticker.json +1 -0
- package/registry/offers.json +1 -0
- package/registry/onboarding.json +1 -0
- package/registry/orb-reveal.json +1 -0
- package/registry/otp-input/files/src/components/ui/otp-input.tsx +48 -29
- package/registry/otp-input/files/src/lib/kit.tsx +363 -11
- package/registry/otp-input.json +1 -0
- package/registry/parallax-layers.json +1 -0
- package/registry/parallax-scroll.json +1 -0
- package/registry/password-input/files/src/components/ui/floating-input.tsx +33 -33
- package/registry/password-input/files/src/components/ui/password-input.tsx +29 -25
- package/registry/password-input/files/src/lib/kit.tsx +363 -11
- package/registry/password-input.json +1 -0
- package/registry/payment-card/files/src/components/ui/flip-card.tsx +6 -5
- package/registry/payment-card/files/src/components/ui/payment-card.tsx +17 -17
- package/registry/payment-card/files/src/components/ui/tilt-card.tsx +76 -91
- package/registry/payment-card/files/src/lib/kit.tsx +363 -11
- package/registry/payment-card.json +1 -0
- package/registry/paywall.json +1 -0
- package/registry/pixel-bar.json +1 -0
- package/registry/polar-area.json +1 -0
- package/registry/profile.json +1 -0
- package/registry/progress/files/src/components/ui/progress.tsx +29 -29
- package/registry/progress/files/src/lib/kit.tsx +363 -11
- package/registry/progress-steps/files/src/components/ui/progress-steps.tsx +20 -20
- package/registry/progress-steps/files/src/lib/kit.tsx +363 -11
- package/registry/progress-steps.json +1 -0
- package/registry/progress.json +1 -0
- package/registry/qr-code-button.json +1 -0
- package/registry/radio-group/files/src/components/ui/radio-group.tsx +19 -19
- package/registry/radio-group/files/src/lib/kit.tsx +363 -11
- package/registry/radio-group.json +1 -0
- package/registry/rating.json +1 -0
- package/registry/ring-carousel.json +1 -0
- package/registry/ruler-time-picker/files/src/components/ui/ruler-time-picker.tsx +98 -82
- package/registry/ruler-time-picker/files/src/lib/kit.tsx +363 -11
- package/registry/ruler-time-picker.json +7 -0
- package/registry/scratch-card.json +1 -0
- package/registry/search-bar/files/src/components/ui/search-bar.tsx +25 -21
- package/registry/search-bar/files/src/lib/kit.tsx +363 -11
- package/registry/search-bar.json +1 -0
- package/registry/search-results.json +4 -0
- package/registry/segmented-control/files/src/components/ui/segmented-control.tsx +8 -7
- package/registry/segmented-control/files/src/lib/kit.tsx +363 -11
- package/registry/segmented-control.json +1 -0
- package/registry/select/files/src/components/ui/select.tsx +93 -88
- package/registry/select/files/src/lib/kit.tsx +363 -11
- package/registry/select.json +6 -0
- package/registry/settings.json +1 -0
- package/registry/sign-in.json +1 -0
- package/registry/skeleton/files/src/components/ui/skeleton.tsx +149 -80
- package/registry/skeleton/files/src/lib/kit.tsx +363 -11
- package/registry/skeleton.json +1 -0
- package/registry/slide-to-confirm.json +1 -0
- package/registry/slider/files/src/components/ui/slider.tsx +103 -96
- package/registry/slider/files/src/lib/kit.tsx +363 -11
- package/registry/slider.json +5 -0
- package/registry/spin-wheel.json +1 -0
- package/registry/spinner/files/src/components/ui/spinner.tsx +39 -29
- package/registry/spinner/files/src/lib/kit.tsx +363 -11
- package/registry/spinner.json +6 -0
- package/registry/stateful-button/files/src/components/ui/stateful-button.tsx +39 -32
- package/registry/stateful-button/files/src/lib/kit.tsx +363 -11
- package/registry/stateful-button.json +5 -0
- package/registry/stepper/files/src/components/ui/stepper.tsx +38 -36
- package/registry/stepper/files/src/lib/kit.tsx +363 -11
- package/registry/stepper.json +1 -0
- package/registry/swipe-deck.json +1 -0
- package/registry/swipeable-row.json +4 -0
- package/registry/switch/files/src/components/ui/switch.tsx +39 -42
- package/registry/switch/files/src/lib/kit.tsx +363 -11
- package/registry/switch.json +1 -0
- package/registry/tabs/files/src/components/ui/tabs.tsx +59 -62
- package/registry/tabs/files/src/lib/kit.tsx +363 -11
- package/registry/tabs.json +1 -0
- package/registry/text-animation/files/src/components/ui/text-animation.tsx +55 -42
- package/registry/text-animation/files/src/lib/kit.tsx +363 -11
- package/registry/text-animation.json +7 -0
- package/registry/textarea/files/src/components/ui/textarea.tsx +10 -10
- package/registry/textarea/files/src/lib/kit.tsx +363 -11
- package/registry/textarea.json +1 -0
- package/registry/ticket-card.json +1 -0
- package/registry/ticket-shape/files/src/lib/kit.tsx +363 -11
- package/registry/ticket-shape/files/src/lib/ticket-shape.tsx +54 -44
- package/registry/ticket-shape.json +1 -0
- package/registry/tilt-card/files/src/components/ui/tilt-card.tsx +76 -91
- package/registry/tilt-card/files/src/lib/kit.tsx +363 -11
- package/registry/tilt-card.json +1 -0
- package/registry/time-picker/files/src/components/ui/time-picker.tsx +122 -119
- package/registry/time-picker/files/src/lib/kit.tsx +363 -11
- package/registry/time-picker.json +1 -0
- package/registry/timeline/files/src/components/ui/avatar.tsx +84 -66
- package/registry/timeline/files/src/components/ui/timeline.tsx +44 -41
- package/registry/timeline/files/src/lib/kit.tsx +363 -11
- package/registry/timeline-chart.json +1 -0
- package/registry/timeline.json +1 -0
- package/registry/toast/files/src/components/ui/toast.tsx +541 -463
- package/registry/toast/files/src/lib/kit.tsx +363 -11
- package/registry/toast.json +7 -5
- package/registry/treemap.json +1 -0
- package/registry/waterfall.json +1 -0
- package/registry/wheel-list.json +1 -0
- package/schema/components.schema.json +1 -0
- package/registry/alert/files/src/components/ui/button.tsx +0 -290
- package/registry/confetti/files/src/lib/kit.tsx +0 -320
- package/registry/grain/files/src/lib/kit.tsx +0 -320
- package/registry/toast/files/src/components/ui/button.tsx +0 -290
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
AccessibilityInfo,
|
|
5
5
|
Animated,
|
|
6
6
|
Easing,
|
|
7
|
-
PanResponder,
|
|
8
7
|
Platform,
|
|
9
8
|
StyleSheet,
|
|
10
9
|
Text,
|
|
@@ -14,7 +13,7 @@ import {
|
|
|
14
13
|
type ViewStyle,
|
|
15
14
|
} from 'react-native';
|
|
16
15
|
|
|
17
|
-
import { motion, readableOn, shadowFor, useKit } from '@/lib/kit';
|
|
16
|
+
import { motion, readableOn, shadowFor, useKit, usePanResponder, type Labels } from '@/lib/kit';
|
|
18
17
|
|
|
19
18
|
export interface FlipCalendarProps {
|
|
20
19
|
/** Controlled date (its time of day is kept on every change). */
|
|
@@ -171,28 +170,30 @@ export function FlipCalendar({
|
|
|
171
170
|
accessibilityLabel,
|
|
172
171
|
style,
|
|
173
172
|
}: FlipCalendarProps) {
|
|
174
|
-
const { colors, radius, dark } = useKit();
|
|
173
|
+
const { colors, radius, dark, labels } = useKit();
|
|
175
174
|
const reduce = useReduceMotion();
|
|
176
175
|
const tint = accent ?? colors.accent;
|
|
177
176
|
|
|
178
|
-
const start =
|
|
177
|
+
const [start] = useState(() => value ?? defaultValue ?? new Date());
|
|
179
178
|
const clock = useRef({ h: start.getHours(), min: start.getMinutes() });
|
|
180
179
|
const [day, setDay] = useState(() => dayOf(start));
|
|
181
180
|
|
|
182
181
|
// Animated values per page, keyed by its date. A page keeps its angle when its role changes, so a
|
|
183
182
|
// page turned over (180) is already yesterday's page, and the one under it is already lying flat.
|
|
184
|
-
const pages =
|
|
183
|
+
const [pages] = useState(() => new Map<number, PageValues>());
|
|
185
184
|
const valuesFor = (t: Day, flipped: boolean) => {
|
|
186
185
|
const k = utc(t);
|
|
187
|
-
let v = pages.
|
|
188
|
-
if (!v) pages.
|
|
186
|
+
let v = pages.get(k);
|
|
187
|
+
if (!v) pages.set(k, (v = { flip: new Animated.Value(flipped ? 180 : 0), nudge: new Animated.Value(0) }));
|
|
189
188
|
return v;
|
|
190
189
|
};
|
|
191
190
|
|
|
192
191
|
const minKey = minDate ? utc(dayOf(minDate)) : -Infinity;
|
|
193
192
|
const maxKey = maxDate ? utc(dayOf(maxDate)) : Infinity;
|
|
194
193
|
const live = useRef({ day, onChange, haptics, reduce, minKey, maxKey });
|
|
195
|
-
|
|
194
|
+
useLayoutEffect(() => {
|
|
195
|
+
live.current = { day, onChange, haptics, reduce, minKey, maxKey };
|
|
196
|
+
});
|
|
196
197
|
const canNext = () => utc(addDays(live.current.day, 1)) <= live.current.maxKey;
|
|
197
198
|
const canPrev = () => utc(addDays(live.current.day, -1)) >= live.current.minKey;
|
|
198
199
|
|
|
@@ -239,14 +240,16 @@ export function FlipCalendar({
|
|
|
239
240
|
});
|
|
240
241
|
}
|
|
241
242
|
const actions = useRef({ flipOver, flipBack });
|
|
242
|
-
|
|
243
|
+
useLayoutEffect(() => {
|
|
244
|
+
actions.current = { flipOver, flipBack };
|
|
245
|
+
});
|
|
243
246
|
|
|
244
247
|
// After a page change: forget pages that left the pad, then keep turning if a fling asked.
|
|
245
248
|
useLayoutEffect(() => {
|
|
246
249
|
if (!pending.current) return;
|
|
247
250
|
pending.current = false;
|
|
248
251
|
const keep = new Set([-1, 0, 1].map((n) => utc(addDays(day, n))));
|
|
249
|
-
for (const k of pages.
|
|
252
|
+
for (const k of pages.keys()) if (!keep.has(k)) pages.delete(k);
|
|
250
253
|
busy.current = false;
|
|
251
254
|
if (chain.current !== 0) {
|
|
252
255
|
const forward = chain.current > 0;
|
|
@@ -266,7 +269,7 @@ export function FlipCalendar({
|
|
|
266
269
|
clock.current = { h: value.getHours(), min: value.getMinutes() };
|
|
267
270
|
chain.current = 0;
|
|
268
271
|
busy.current = false;
|
|
269
|
-
pages.
|
|
272
|
+
pages.clear();
|
|
270
273
|
setDay(dayOf(value));
|
|
271
274
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
272
275
|
}, [external]);
|
|
@@ -287,76 +290,77 @@ export function FlipCalendar({
|
|
|
287
290
|
r: 1,
|
|
288
291
|
over: false,
|
|
289
292
|
});
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
} else
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
},
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
293
|
+
const spring = (v: Animated.Value, to: number) => Animated.spring(v, { toValue: to, useNativeDriver: true, ...motion.snappy }).start();
|
|
294
|
+
const pan = usePanResponder({
|
|
295
|
+
onMoveShouldSetPanResponder: (_, g) => !busy.current && Math.abs(g.dy) > 6 && Math.abs(g.dy) > Math.abs(g.dx),
|
|
296
|
+
onPanResponderTerminationRequest: () => false,
|
|
297
|
+
onPanResponderGrant: (e, g) => {
|
|
298
|
+
const g0 = grip.current;
|
|
299
|
+
chain.current = 0;
|
|
300
|
+
g0.started = false;
|
|
301
|
+
g0.page = null;
|
|
302
|
+
// Where the touch came down, in the pad.
|
|
303
|
+
g0.y0 = e.nativeEvent.locationY - g.dy;
|
|
304
|
+
},
|
|
305
|
+
onPanResponderMove: (_, g) => {
|
|
306
|
+
const g0 = grip.current;
|
|
307
|
+
if (!g0.started) {
|
|
308
|
+
if (Math.abs(g.dy) < 3) return;
|
|
309
|
+
g0.started = true;
|
|
310
|
+
// Lifting turns today's page; pulling down brings yesterday's back (which starts over the top).
|
|
311
|
+
g0.back = g.dy > 0;
|
|
312
|
+
g0.over = g0.back;
|
|
313
|
+
g0.page = g0.back ? (canPrev() ? valuesFor(addDays(live.current.day, -1), true) : null) : valuesFor(live.current.day, false);
|
|
314
|
+
// The point of the paper under the finger: where you grabbed today's page (at least halfway
|
|
315
|
+
// down, so a grab near the rings still turns it), or near the free end of yesterday's.
|
|
316
|
+
g0.r = g0.back ? H * 0.9 : clamp(g0.y0 - PAGE_TOP, H * 0.55, H);
|
|
317
|
+
g0.y = curlPoint(g0.r, g0.back ? 1 : 0, H, curlRadius(H)).y;
|
|
318
|
+
}
|
|
319
|
+
const top = valuesFor(live.current.day, false);
|
|
320
|
+
if (!g0.page) {
|
|
321
|
+
// Nothing earlier to bring back: today's page only gives a little.
|
|
322
|
+
top.nudge.setValue(Math.max(0, g.dy) * 0.18);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const angle = progressUnderFinger(g0.r, g0.y + g.dy, H, curlRadius(H)) * 180;
|
|
326
|
+
// At the last day the page only lifts a little.
|
|
327
|
+
g0.page.flip.setValue(!g0.back && !canNext() ? Math.min(angle * 0.25, 24) : angle);
|
|
328
|
+
const over = angle > 90;
|
|
329
|
+
if (over !== g0.over) {
|
|
330
|
+
g0.over = over;
|
|
331
|
+
if (live.current.haptics) Haptics.selectionAsync().catch(() => {});
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
onPanResponderRelease: (_, g) => {
|
|
335
|
+
const top = valuesFor(live.current.day, false);
|
|
336
|
+
spring(top.nudge, 0);
|
|
337
|
+
const g0 = grip.current;
|
|
338
|
+
const page = g0.page;
|
|
339
|
+
if (!page) return;
|
|
340
|
+
if (g0.back) {
|
|
341
|
+
// Past upright, or flicked down: it lands; a hard flick brings back a few more.
|
|
342
|
+
if (!g0.over || g.vy > 0.5) {
|
|
343
|
+
chain.current = -clamp(Math.floor((g.vy - 1.2) * 3), 0, MAX_CHAIN);
|
|
344
|
+
actions.current.flipBack();
|
|
345
|
+
} else spring(page.flip, 180);
|
|
346
|
+
} else if (canNext() && (g0.over || g.vy < -0.5)) {
|
|
347
|
+
chain.current = clamp(Math.floor((-g.vy - 1.2) * 3), 0, MAX_CHAIN);
|
|
348
|
+
actions.current.flipOver();
|
|
349
|
+
} else spring(page.flip, 0);
|
|
350
|
+
},
|
|
351
|
+
onPanResponderTerminate: () => {
|
|
352
|
+
spring(valuesFor(live.current.day, false).nudge, 0);
|
|
353
|
+
const g0 = grip.current;
|
|
354
|
+
if (g0.page) spring(g0.page.flip, g0.back ? 180 : 0);
|
|
355
|
+
},
|
|
356
|
+
});
|
|
353
357
|
|
|
354
358
|
const names = namesFor(locale);
|
|
355
359
|
const spoken = (t: Day) => `${names.days[new Date(utc(t)).getUTCDay()]}, ${t.d} ${names.months[t.m]} ${t.y}`;
|
|
356
360
|
const prevDay = addDays(day, -1);
|
|
357
361
|
const nextDay = addDays(day, 1);
|
|
358
362
|
const corner = radius.scale(14);
|
|
359
|
-
const pageProps = { W, H, tint, names, colors, corner };
|
|
363
|
+
const pageProps = { W, H, tint, names, labels, colors, corner };
|
|
360
364
|
const top = valuesFor(day, false);
|
|
361
365
|
|
|
362
366
|
return (
|
|
@@ -364,15 +368,15 @@ export function FlipCalendar({
|
|
|
364
368
|
onLayout={(e: LayoutChangeEvent) => setWidth(Math.round(e.nativeEvent.layout.width))}
|
|
365
369
|
accessible
|
|
366
370
|
accessibilityRole="adjustable"
|
|
367
|
-
accessibilityLabel={accessibilityLabel ??
|
|
371
|
+
accessibilityLabel={accessibilityLabel ?? labels.date}
|
|
368
372
|
accessibilityValue={{ text: spoken(day) }}
|
|
369
|
-
accessibilityHint=
|
|
373
|
+
accessibilityHint={labels.flipCalendarHint}
|
|
370
374
|
accessibilityActions={[{ name: 'increment' }, { name: 'decrement' }]}
|
|
371
375
|
onAccessibilityAction={(e) => (e.nativeEvent.actionName === 'increment' ? flipOver() : flipBack())}
|
|
372
376
|
style={[styles.root, style]}
|
|
373
377
|
>
|
|
374
378
|
{W > 0 ? (
|
|
375
|
-
<View style={[styles.pad, styles.grab, { width: W, height: H + PAGE_TOP + 14 }]} {...pan
|
|
379
|
+
<View style={[styles.pad, styles.grab, { width: W, height: H + PAGE_TOP + 14 }]} {...pan}>
|
|
376
380
|
{/* The board the pages hang from, and page edges stacked under them for thickness. */}
|
|
377
381
|
<View style={[styles.board, { backgroundColor: colors.foreground, borderRadius: radius.scale(8) }]} />
|
|
378
382
|
{[2, 1].map((n) => (
|
|
@@ -391,7 +395,7 @@ export function FlipCalendar({
|
|
|
391
395
|
<Animated.View style={{ transform: [{ translateY: top.nudge }] }}>
|
|
392
396
|
<Page key={utc(day)} day={day} values={top} {...pageProps} />
|
|
393
397
|
</Animated.View>
|
|
394
|
-
{
|
|
398
|
+
{utc(prevDay) >= minKey ? <Page key={utc(prevDay)} day={prevDay} values={valuesFor(prevDay, true)} {...pageProps} /> : null}
|
|
395
399
|
</View>
|
|
396
400
|
<Rings width={W} color={colors.mutedForeground} hole={colors.foreground} />
|
|
397
401
|
</View>
|
|
@@ -411,6 +415,7 @@ interface PageProps {
|
|
|
411
415
|
H: number;
|
|
412
416
|
tint: string;
|
|
413
417
|
names: Names;
|
|
418
|
+
labels: Labels;
|
|
414
419
|
colors: ReturnType<typeof useKit>['colors'];
|
|
415
420
|
corner: number;
|
|
416
421
|
}
|
|
@@ -458,7 +463,7 @@ function stripTracks(H: number): StripTrack[] {
|
|
|
458
463
|
* near the fold roll toward you and darken or catch the light as they turn, and past the fold the
|
|
459
464
|
* plain back comes up over the top.
|
|
460
465
|
*/
|
|
461
|
-
const Page = React.memo(function Page({ day, values, under, shadowFrom, W, H, tint, names, colors, corner }: PageProps) {
|
|
466
|
+
const Page = React.memo(function Page({ day, values, under, shadowFrom, W, H, tint, names, labels, colors, corner }: PageProps) {
|
|
462
467
|
const { flip } = values;
|
|
463
468
|
const h = H / STRIPS;
|
|
464
469
|
const strips = useMemo(() => {
|
|
@@ -487,7 +492,7 @@ const Page = React.memo(function Page({ day, values, under, shadowFrom, W, H, ti
|
|
|
487
492
|
);
|
|
488
493
|
|
|
489
494
|
const sheet = { width: W, height: H, backgroundColor: colors.card, borderColor: colors.border, borderRadius: corner };
|
|
490
|
-
const face = <Face day={day} W={W} tint={tint} names={names} colors={colors} sheet={sheet} />;
|
|
495
|
+
const face = <Face day={day} W={W} tint={tint} names={names} labels={labels} colors={colors} sheet={sheet} />;
|
|
491
496
|
|
|
492
497
|
if (under || !strips) {
|
|
493
498
|
return (
|
|
@@ -537,12 +542,13 @@ interface FaceProps {
|
|
|
537
542
|
W: number;
|
|
538
543
|
tint: string;
|
|
539
544
|
names: Names;
|
|
545
|
+
labels: Labels;
|
|
540
546
|
colors: ReturnType<typeof useKit>['colors'];
|
|
541
547
|
sheet: ViewStyle;
|
|
542
548
|
}
|
|
543
549
|
|
|
544
550
|
/** The printed side of a page: perforation, month band, the day, weekday and a footer. */
|
|
545
|
-
const Face = React.memo(function Face({ day, W, tint, names, colors, sheet }: FaceProps) {
|
|
551
|
+
const Face = React.memo(function Face({ day, W, tint, names, labels, colors, sheet }: FaceProps) {
|
|
546
552
|
const wd = new Date(utc(day)).getUTCDay();
|
|
547
553
|
const ink = wd === 0 ? tint : colors.foreground;
|
|
548
554
|
const band = readableOn(tint);
|
|
@@ -551,18 +557,18 @@ const Face = React.memo(function Face({ day, W, tint, names, colors, sheet }: Fa
|
|
|
551
557
|
<View style={[styles.face, sheet]}>
|
|
552
558
|
<View style={[styles.perforation, { borderBottomColor: colors.border }]} />
|
|
553
559
|
<View style={[styles.band, { backgroundColor: tint }]}>
|
|
554
|
-
<Text numberOfLines={1} style={[styles.month, { color: band }]}>{names.months[day.m].toUpperCase()}</Text>
|
|
560
|
+
<Text numberOfLines={1} style={[styles.month, { color: band }]}>{(names.months[day.m] ?? '').toUpperCase()}</Text>
|
|
555
561
|
<Text style={[styles.year, { color: band }]}>{day.y}</Text>
|
|
556
562
|
</View>
|
|
557
563
|
<View style={styles.body}>
|
|
558
564
|
<Text numberOfLines={1} adjustsFontSizeToFit style={[styles.day, { color: ink, fontSize: W * 0.5, lineHeight: W * 0.56 }]}>
|
|
559
565
|
{day.d}
|
|
560
566
|
</Text>
|
|
561
|
-
<Text numberOfLines={1} style={[styles.weekday, { color: ink }]}>{names.days[wd].toUpperCase()}</Text>
|
|
567
|
+
<Text numberOfLines={1} style={[styles.weekday, { color: ink }]}>{(names.days[wd] ?? '').toUpperCase()}</Text>
|
|
562
568
|
</View>
|
|
563
569
|
<View style={[styles.footer, { borderTopColor: colors.border }]}>
|
|
564
|
-
<Text style={[styles.meta, { color: colors.mutedForeground }]}>
|
|
565
|
-
<Text style={[styles.meta, { color: colors.mutedForeground }]}>{left}
|
|
570
|
+
<Text style={[styles.meta, { color: colors.mutedForeground }]}>{labels.dayAndWeek(dayOfYear(day), isoWeek(day))}</Text>
|
|
571
|
+
<Text style={[styles.meta, { color: colors.mutedForeground }]}>{labels.daysLeft(left)}</Text>
|
|
566
572
|
</View>
|
|
567
573
|
</View>
|
|
568
574
|
);
|