@expokit/cli 0.4.3 → 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 +313 -4
- 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/flip-calendar.json +106 -0
- 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/paywall.json +144 -0
- 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/ruler-time-picker.json +147 -0
- 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 +462 -12
- package/registry/accordion.json +1 -0
- package/registry/action-sheet/files/src/components/ui/action-sheet.tsx +50 -58
- package/registry/action-sheet/files/src/lib/kit.tsx +462 -12
- package/registry/action-sheet.json +1 -0
- package/registry/alert/files/src/components/ui/alert.tsx +20 -13
- package/registry/alert/files/src/lib/kit.tsx +462 -12
- package/registry/alert.json +3 -4
- package/registry/assistant-app.json +1 -0
- package/registry/avatar/files/src/components/ui/avatar.tsx +89 -74
- package/registry/avatar/files/src/lib/kit.tsx +462 -12
- package/registry/avatar.json +1 -0
- package/registry/badge/files/src/components/ui/badge.tsx +36 -36
- package/registry/badge/files/src/lib/kit.tsx +462 -12
- package/registry/badge.json +1 -0
- package/registry/bottom-nav/files/src/components/ui/bottom-nav.tsx +39 -44
- package/registry/bottom-nav/files/src/lib/kit.tsx +462 -12
- package/registry/bottom-nav.json +5 -0
- package/registry/bottom-sheet/files/src/components/ui/bottom-sheet.tsx +357 -300
- package/registry/bottom-sheet/files/src/lib/kit.tsx +462 -12
- package/registry/bottom-sheet.json +5 -1
- package/registry/bullet.json +1 -0
- package/registry/button/files/src/components/ui/button.tsx +23 -34
- package/registry/button/files/src/lib/kit.tsx +462 -12
- package/registry/button-3d/files/src/components/ui/button-3d.tsx +6 -9
- package/registry/button-3d/files/src/lib/kit.tsx +462 -12
- package/registry/button-3d.json +1 -0
- package/registry/button.json +1 -0
- package/registry/calendar/files/src/components/ui/calendar.tsx +77 -79
- package/registry/calendar/files/src/lib/kit.tsx +462 -12
- package/registry/calendar.json +1 -0
- package/registry/card/files/src/components/ui/card.tsx +7 -6
- package/registry/card/files/src/lib/kit.tsx +462 -12
- 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 +462 -12
- package/registry/checkbox.json +1 -0
- package/registry/checkout.json +1 -0
- package/registry/chip-group/files/src/components/ui/chip-group.tsx +24 -24
- package/registry/chip-group/files/src/lib/kit.tsx +462 -12
- 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 +47 -52
- package/registry/coupon/files/src/components/ui/flip-card.tsx +9 -14
- package/registry/coupon/files/src/components/ui/tilt-card.tsx +80 -101
- package/registry/coupon/files/src/lib/kit.tsx +462 -12
- 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 +77 -79
- package/registry/date-picker/files/src/components/ui/date-picker.tsx +64 -71
- package/registry/date-picker/files/src/lib/kit.tsx +462 -12
- package/registry/date-picker.json +1 -0
- package/registry/dialog/files/src/components/ui/dialog.tsx +66 -68
- package/registry/dialog/files/src/lib/kit.tsx +462 -12
- package/registry/dialog.json +1 -0
- package/registry/donut-shop.json +1 -0
- package/registry/drawer/files/src/components/ui/drawer.tsx +76 -88
- package/registry/drawer/files/src/lib/kit.tsx +462 -12
- 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 +632 -0
- package/registry/flip-calendar/files/src/lib/kit.tsx +672 -0
- package/registry/flip-calendar.json +24 -0
- package/registry/flip-card/files/src/components/ui/flip-card.tsx +9 -14
- package/registry/flip-card/files/src/lib/kit.tsx +462 -12
- 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 +462 -12
- 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 +462 -12
- 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 +29 -16
- package/registry/liquidglass-tab/files/src/components/TabScreen.tsx +33 -19
- 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 +43 -43
- package/registry/list-item/files/src/lib/kit.tsx +462 -12
- 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 +49 -30
- package/registry/otp-input/files/src/lib/kit.tsx +462 -12
- 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 +462 -12
- package/registry/password-input.json +1 -0
- package/registry/payment-card/files/src/components/ui/flip-card.tsx +9 -14
- package/registry/payment-card/files/src/components/ui/payment-card.tsx +26 -20
- package/registry/payment-card/files/src/components/ui/tilt-card.tsx +80 -101
- package/registry/payment-card/files/src/lib/kit.tsx +462 -12
- package/registry/payment-card.json +1 -0
- package/registry/paywall.json +23 -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 +31 -29
- package/registry/progress/files/src/lib/kit.tsx +462 -12
- package/registry/progress-steps/files/src/components/ui/progress-steps.tsx +21 -21
- package/registry/progress-steps/files/src/lib/kit.tsx +462 -12
- 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 +462 -12
- 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 +832 -0
- package/registry/ruler-time-picker/files/src/lib/kit.tsx +672 -0
- package/registry/ruler-time-picker.json +26 -0
- package/registry/scratch-card.json +1 -0
- package/registry/search-bar/files/src/components/ui/search-bar.tsx +28 -28
- package/registry/search-bar/files/src/lib/kit.tsx +462 -12
- 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 +11 -17
- package/registry/segmented-control/files/src/lib/kit.tsx +462 -12
- package/registry/segmented-control.json +1 -0
- package/registry/select/files/src/components/ui/select.tsx +107 -104
- package/registry/select/files/src/lib/kit.tsx +462 -12
- 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 +462 -12
- package/registry/skeleton.json +1 -0
- package/registry/slide-to-confirm.json +1 -0
- package/registry/slider/files/src/components/ui/slider.tsx +106 -108
- package/registry/slider/files/src/lib/kit.tsx +462 -12
- 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 +462 -12
- 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 +462 -12
- package/registry/stateful-button.json +5 -0
- package/registry/stepper/files/src/components/ui/stepper.tsx +40 -38
- package/registry/stepper/files/src/lib/kit.tsx +462 -12
- 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 +41 -47
- package/registry/switch/files/src/lib/kit.tsx +462 -12
- package/registry/switch.json +1 -0
- package/registry/tabs/files/src/components/ui/tabs.tsx +61 -64
- package/registry/tabs/files/src/lib/kit.tsx +462 -12
- 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 +462 -12
- 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 +462 -12
- package/registry/textarea.json +1 -0
- package/registry/ticket-card.json +1 -0
- package/registry/ticket-shape/files/src/lib/kit.tsx +462 -12
- 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 +80 -101
- package/registry/tilt-card/files/src/lib/kit.tsx +462 -12
- package/registry/tilt-card.json +1 -0
- package/registry/time-picker/files/src/components/ui/time-picker.tsx +136 -131
- package/registry/time-picker/files/src/lib/kit.tsx +462 -12
- package/registry/time-picker.json +1 -0
- package/registry/timeline/files/src/components/ui/avatar.tsx +89 -74
- package/registry/timeline/files/src/components/ui/timeline.tsx +49 -57
- package/registry/timeline/files/src/lib/kit.tsx +462 -12
- package/registry/timeline-chart.json +1 -0
- package/registry/timeline.json +1 -0
- package/registry/toast/files/src/components/ui/toast.tsx +543 -465
- package/registry/toast/files/src/lib/kit.tsx +462 -12
- 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 -303
- package/registry/confetti/files/src/lib/kit.tsx +0 -222
- package/registry/grain/files/src/lib/kit.tsx +0 -222
- package/registry/toast/files/src/components/ui/button.tsx +0 -303
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Haptics from 'expo-haptics';
|
|
2
|
-
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type ComponentRef } from 'react';
|
|
2
|
+
import React, { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, type ComponentRef } from 'react';
|
|
3
3
|
import {
|
|
4
4
|
AccessibilityInfo,
|
|
5
5
|
Animated,
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
Easing,
|
|
8
8
|
Image,
|
|
9
9
|
Modal,
|
|
10
|
-
PanResponder,
|
|
11
10
|
Platform,
|
|
12
11
|
Pressable,
|
|
13
12
|
ScrollView,
|
|
@@ -23,7 +22,7 @@ import {
|
|
|
23
22
|
} from 'react-native';
|
|
24
23
|
import Svg, { Path } from 'react-native-svg';
|
|
25
24
|
|
|
26
|
-
import { alpha, motion, useKit } from '@/lib/kit';
|
|
25
|
+
import { alpha, motion, useKit, usePanResponder } from '@/lib/kit';
|
|
27
26
|
|
|
28
27
|
export type DrawerSide = 'left' | 'right';
|
|
29
28
|
/**
|
|
@@ -135,11 +134,12 @@ export function Drawer({
|
|
|
135
134
|
haptics = true,
|
|
136
135
|
topInset,
|
|
137
136
|
bottomInset,
|
|
138
|
-
accessibilityLabel
|
|
137
|
+
accessibilityLabel: accessibilityLabelProp,
|
|
139
138
|
style,
|
|
140
139
|
panelStyle,
|
|
141
140
|
}: DrawerProps) {
|
|
142
|
-
const { colors, dark, radius } = useKit();
|
|
141
|
+
const { colors, dark, radius, labels } = useKit();
|
|
142
|
+
const accessibilityLabel = accessibilityLabelProp ?? labels.navigationDrawer;
|
|
143
143
|
const reduceMotion = useReduceMotion();
|
|
144
144
|
const win = useWindowDimensions();
|
|
145
145
|
const inline = children !== undefined;
|
|
@@ -159,13 +159,17 @@ export function Drawer({
|
|
|
159
159
|
const [inner, setInner] = useState(defaultOpen);
|
|
160
160
|
const isOpen = open ?? inner;
|
|
161
161
|
const [mounted, setMounted] = useState(isOpen); // Modal mode only
|
|
162
|
+
// Mount as soon as it opens (state adjusted during render); unmounted after the exit animation.
|
|
163
|
+
if (isOpen && !inline && !mounted) setMounted(true);
|
|
162
164
|
// Progress 0 (closed) → 1 (open), native-driven; every transform and opacity reads from it.
|
|
163
|
-
const p =
|
|
165
|
+
const [p] = useState(() => new Animated.Value(isOpen ? 1 : 0));
|
|
164
166
|
// Same progress on the JS driver, for the screen's corner radius and edge colour (separate view).
|
|
165
|
-
const r =
|
|
167
|
+
const [r] = useState(() => new Animated.Value(isOpen ? 1 : 0));
|
|
166
168
|
|
|
167
169
|
const live = useRef({ open: isOpen, w: W, box, reduce: reduceMotion, haptics, movesScreen, edgeSwipe, edgeWidth, dismissible });
|
|
168
|
-
|
|
170
|
+
useLayoutEffect(() => {
|
|
171
|
+
live.current = { open: isOpen, w: W, box, reduce: reduceMotion, haptics, movesScreen, edgeSwipe, edgeWidth, dismissible };
|
|
172
|
+
});
|
|
169
173
|
|
|
170
174
|
const setOpen = useCallback(
|
|
171
175
|
(next: boolean) => {
|
|
@@ -175,7 +179,9 @@ export function Drawer({
|
|
|
175
179
|
[open, onOpenChange],
|
|
176
180
|
);
|
|
177
181
|
const setOpenRef = useRef(setOpen);
|
|
178
|
-
|
|
182
|
+
useLayoutEffect(() => {
|
|
183
|
+
setOpenRef.current = setOpen;
|
|
184
|
+
});
|
|
179
185
|
|
|
180
186
|
const target = useRef<0 | 1>(isOpen ? 1 : 0);
|
|
181
187
|
const settle = useCallback(
|
|
@@ -203,7 +209,6 @@ export function Drawer({
|
|
|
203
209
|
);
|
|
204
210
|
|
|
205
211
|
useEffect(() => {
|
|
206
|
-
if (isOpen && !inline) setMounted(true);
|
|
207
212
|
// Skip when a drag release already started a velocity spring towards this state.
|
|
208
213
|
if (target.current !== (isOpen ? 1 : 0)) settle(isOpen ? 1 : 0);
|
|
209
214
|
}, [isOpen, settle, inline]);
|
|
@@ -242,50 +247,47 @@ export function Drawer({
|
|
|
242
247
|
// zone (so taps there still reach the screen), `drag` captures horizontal drags on the open
|
|
243
248
|
// panel / scrim (so vertical scrolling and taps inside the panel keep working).
|
|
244
249
|
const start = useRef(0);
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
});
|
|
287
|
-
return { edge, drag };
|
|
288
|
-
}, [p, r, side, settle, inline]);
|
|
250
|
+
const toward = (dx: number) => (side === 'left' ? dx : -dx); // + means "more open"
|
|
251
|
+
const horizontal = (g: PanResponderGestureState) => Math.abs(g.dx) > 10 && Math.abs(g.dx) > Math.abs(g.dy) * 1.5;
|
|
252
|
+
const base = {
|
|
253
|
+
onPanResponderTerminationRequest: () => false,
|
|
254
|
+
onPanResponderGrant: () => {
|
|
255
|
+
p.stopAnimation((v) => (start.current = v));
|
|
256
|
+
r.stopAnimation();
|
|
257
|
+
if (!live.current.open && !inline) setMounted(true);
|
|
258
|
+
},
|
|
259
|
+
onPanResponderMove: (_: unknown, g: PanResponderGestureState) => {
|
|
260
|
+
const w = live.current.w || 1;
|
|
261
|
+
let next = start.current + toward(g.dx) / w;
|
|
262
|
+
if (next > 1) next = 1 + rubber((next - 1) * w, EXTRA) / w;
|
|
263
|
+
if (next < 0) next = 0;
|
|
264
|
+
p.setValue(next);
|
|
265
|
+
if (live.current.movesScreen) r.setValue(Math.min(1, next));
|
|
266
|
+
},
|
|
267
|
+
onPanResponderRelease: (_: unknown, g: PanResponderGestureState) => {
|
|
268
|
+
const w = live.current.w || 1;
|
|
269
|
+
const v = toward(g.vx); // px/ms, + means opening
|
|
270
|
+
const projected = start.current + toward(g.dx) / w + (v * 200) / w;
|
|
271
|
+
let to: 0 | 1 = projected > 0.5 ? 1 : 0;
|
|
272
|
+
if (Math.abs(v) > 0.35) to = v > 0 ? 1 : 0; // a flick decides on its own
|
|
273
|
+
settle(to, (v * 1000) / w);
|
|
274
|
+
if ((to === 1) !== live.current.open) setOpenRef.current(to === 1);
|
|
275
|
+
},
|
|
276
|
+
onPanResponderTerminate: () => settle(live.current.open ? 1 : 0),
|
|
277
|
+
};
|
|
278
|
+
const edgePan = usePanResponder({
|
|
279
|
+
...base,
|
|
280
|
+
onMoveShouldSetPanResponderCapture: (_, g) => {
|
|
281
|
+
const l = live.current;
|
|
282
|
+
if (!l.edgeSwipe || l.open || !horizontal(g) || toward(g.dx) <= 0) return false;
|
|
283
|
+
const x = g.x0 - rootX.current;
|
|
284
|
+
return side === 'left' ? x <= l.edgeWidth : x >= l.box - l.edgeWidth;
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
const dragPan = usePanResponder({
|
|
288
|
+
...base,
|
|
289
|
+
onMoveShouldSetPanResponderCapture: (_, g) => live.current.dismissible && live.current.open && horizontal(g),
|
|
290
|
+
});
|
|
289
291
|
|
|
290
292
|
const ctx = useMemo(
|
|
291
293
|
() => ({ open: isOpen, setOpen, toggle: () => setOpen(!isOpen), close: () => setOpen(false) }),
|
|
@@ -328,7 +330,7 @@ export function Drawer({
|
|
|
328
330
|
|
|
329
331
|
const panel = (
|
|
330
332
|
<Animated.View
|
|
331
|
-
{...(dismissible ?
|
|
333
|
+
{...(dismissible ? dragPan : null)}
|
|
332
334
|
accessibilityViewIsModal={isOpen}
|
|
333
335
|
accessibilityLabel={accessibilityLabel}
|
|
334
336
|
importantForAccessibility={isOpen ? 'yes' : 'no-hide-descendants'}
|
|
@@ -337,13 +339,6 @@ export function Drawer({
|
|
|
337
339
|
styles.panel,
|
|
338
340
|
side === 'left' ? { left: -EXTRA } : { right: -EXTRA },
|
|
339
341
|
{ width: W + EXTRA, opacity: panelOpacity, transform: [{ translateX: panelX }] },
|
|
340
|
-
!push && {
|
|
341
|
-
shadowColor: '#000',
|
|
342
|
-
shadowOpacity: dark ? 0.45 : 0.12,
|
|
343
|
-
shadowRadius: 28,
|
|
344
|
-
shadowOffset: { width: -dir * 8, height: 0 },
|
|
345
|
-
elevation: 24,
|
|
346
|
-
},
|
|
347
342
|
panelStyle,
|
|
348
343
|
]}
|
|
349
344
|
>
|
|
@@ -353,10 +348,8 @@ export function Drawer({
|
|
|
353
348
|
round,
|
|
354
349
|
!push && {
|
|
355
350
|
backgroundColor: surface,
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
shadowRadius: 4,
|
|
359
|
-
shadowOffset: { width: -dir * 1, height: 0 },
|
|
351
|
+
// Ambient + contact shadow as boxShadow: the same on iOS, Android and web.
|
|
352
|
+
boxShadow: `${-dir * 8}px 0px 56px rgba(0,0,0,${dark ? 0.45 : 0.12}), ${-dir}px 0px 8px rgba(0,0,0,${dark ? 0.3 : 0.06})`,
|
|
360
353
|
},
|
|
361
354
|
]}
|
|
362
355
|
>
|
|
@@ -402,7 +395,7 @@ export function Drawer({
|
|
|
402
395
|
|
|
403
396
|
const scrim = (
|
|
404
397
|
<Animated.View
|
|
405
|
-
{...(dismissible ?
|
|
398
|
+
{...(dismissible ? dragPan : null)}
|
|
406
399
|
pointerEvents={isOpen ? 'auto' : 'none'}
|
|
407
400
|
style={[StyleSheet.absoluteFill, { backgroundColor: colors.overlay, opacity: scrimOpacity }]}
|
|
408
401
|
>
|
|
@@ -410,7 +403,7 @@ export function Drawer({
|
|
|
410
403
|
style={StyleSheet.absoluteFill}
|
|
411
404
|
onPress={() => dismissible && setOpen(false)}
|
|
412
405
|
accessibilityRole="button"
|
|
413
|
-
accessibilityLabel=
|
|
406
|
+
accessibilityLabel={labels.closeDrawer}
|
|
414
407
|
/>
|
|
415
408
|
</Animated.View>
|
|
416
409
|
);
|
|
@@ -430,7 +423,7 @@ export function Drawer({
|
|
|
430
423
|
<DrawerContext.Provider value={ctx}>
|
|
431
424
|
<View
|
|
432
425
|
ref={rootRef}
|
|
433
|
-
{...
|
|
426
|
+
{...edgePan}
|
|
434
427
|
onTouchStart={measure}
|
|
435
428
|
onLayout={(e: LayoutChangeEvent) => {
|
|
436
429
|
setBox(e.nativeEvent.layout.width);
|
|
@@ -444,13 +437,6 @@ export function Drawer({
|
|
|
444
437
|
style={[
|
|
445
438
|
StyleSheet.absoluteFill,
|
|
446
439
|
screenTransform && { transform: screenTransform },
|
|
447
|
-
push &&
|
|
448
|
-
Platform.OS === 'ios' && {
|
|
449
|
-
shadowColor: '#000',
|
|
450
|
-
shadowOpacity: dark ? 0.5 : 0.16,
|
|
451
|
-
shadowRadius: 24,
|
|
452
|
-
shadowOffset: { width: dir * 6, height: 8 },
|
|
453
|
-
},
|
|
454
440
|
]}
|
|
455
441
|
>
|
|
456
442
|
<Animated.View
|
|
@@ -462,8 +448,8 @@ export function Drawer({
|
|
|
462
448
|
borderWidth: StyleSheet.hairlineWidth,
|
|
463
449
|
borderColor: screenEdge,
|
|
464
450
|
overflow: 'hidden',
|
|
465
|
-
elevation: push ? 16 : 0,
|
|
466
451
|
},
|
|
452
|
+
push && { boxShadow: `${dir * 6}px 8px 48px rgba(0,0,0,${dark ? 0.5 : 0.16})` },
|
|
467
453
|
]}
|
|
468
454
|
>
|
|
469
455
|
{children}
|
|
@@ -490,13 +476,15 @@ export interface DrawerHeaderProps {
|
|
|
490
476
|
/** Shows a close control on the trailing edge (default false). */
|
|
491
477
|
showClose?: boolean;
|
|
492
478
|
onClose?: () => void;
|
|
479
|
+
/** Screen-reader name of the close button (default: the kit's `labels.closeMenu`). */
|
|
480
|
+
closeLabel?: string;
|
|
493
481
|
children?: React.ReactNode;
|
|
494
482
|
style?: StyleProp<ViewStyle>;
|
|
495
483
|
}
|
|
496
484
|
|
|
497
485
|
/** Title block with optional leading node and close button — drop into `header`. */
|
|
498
|
-
export function DrawerHeader({ title, subtitle, leading, showClose = false, onClose, children, style }: DrawerHeaderProps) {
|
|
499
|
-
const { colors, radius, dark, font } = useKit();
|
|
486
|
+
export function DrawerHeader({ title, subtitle, leading, showClose = false, onClose, closeLabel, children, style }: DrawerHeaderProps) {
|
|
487
|
+
const { colors, radius, dark, font, labels } = useKit();
|
|
500
488
|
const ff = font.family ? { fontFamily: font.family } : null;
|
|
501
489
|
const drawerCtx = useContext(DrawerContext);
|
|
502
490
|
const close = onClose ?? (() => drawerCtx?.close());
|
|
@@ -521,7 +509,7 @@ export function DrawerHeader({ title, subtitle, leading, showClose = false, onCl
|
|
|
521
509
|
<Pressable
|
|
522
510
|
onPress={close}
|
|
523
511
|
accessibilityRole="button"
|
|
524
|
-
accessibilityLabel=
|
|
512
|
+
accessibilityLabel={closeLabel ?? labels.closeMenu}
|
|
525
513
|
hitSlop={8}
|
|
526
514
|
style={({ pressed }) => [
|
|
527
515
|
styles.closeBtn,
|
|
@@ -574,9 +562,9 @@ export function DrawerProfile({
|
|
|
574
562
|
accessibilityHint,
|
|
575
563
|
style,
|
|
576
564
|
}: DrawerProfileProps) {
|
|
577
|
-
const { colors, radius, dark, font } = useKit();
|
|
565
|
+
const { colors, radius, dark, font, labels } = useKit();
|
|
578
566
|
const ff = font.family ? { fontFamily: font.family } : null;
|
|
579
|
-
const press =
|
|
567
|
+
const [press] = useState(() => new Animated.Value(0));
|
|
580
568
|
const stacked = layout === 'stacked';
|
|
581
569
|
const trailing =
|
|
582
570
|
accessory !== undefined ? (
|
|
@@ -613,7 +601,7 @@ export function DrawerProfile({
|
|
|
613
601
|
onPressOut={() => spring(0)}
|
|
614
602
|
accessibilityRole={onPress ? 'button' : undefined}
|
|
615
603
|
accessibilityLabel={email ? `${name}, ${email}` : name}
|
|
616
|
-
accessibilityHint={accessibilityHint ?? (onPress ?
|
|
604
|
+
accessibilityHint={accessibilityHint ?? (onPress ? labels.switchAccount : undefined)}
|
|
617
605
|
style={({ pressed }) => [
|
|
618
606
|
stacked ? styles.profileStacked : styles.profileRow,
|
|
619
607
|
{
|
|
@@ -642,7 +630,7 @@ export function DrawerProfile({
|
|
|
642
630
|
);
|
|
643
631
|
}
|
|
644
632
|
|
|
645
|
-
function ProfileAvatar({ name, src, size, status }: { name: string; src?: string; size: number; status?: DrawerPresence }) {
|
|
633
|
+
function ProfileAvatar({ name, src, size, status }: { name: string; src?: string | undefined; size: number; status?: DrawerPresence | undefined }) {
|
|
646
634
|
const { colors, radius, dark, font } = useKit();
|
|
647
635
|
const ff = font.family ? { fontFamily: font.family } : null;
|
|
648
636
|
const ring = useContext(SurfaceContext) ?? colors.card;
|
|
@@ -827,10 +815,10 @@ export function DrawerItem({
|
|
|
827
815
|
const ink = dark ? tint : mix(tint, colors.foreground, 0.22);
|
|
828
816
|
|
|
829
817
|
// Native-driven: pill presence, icon pop, badge pop, press scale — each on its own value.
|
|
830
|
-
const on =
|
|
831
|
-
const pop =
|
|
832
|
-
const badgePop =
|
|
833
|
-
const press =
|
|
818
|
+
const [on] = useState(() => new Animated.Value(active ? 1 : 0));
|
|
819
|
+
const [pop] = useState(() => new Animated.Value(1));
|
|
820
|
+
const [badgePop] = useState(() => new Animated.Value(1));
|
|
821
|
+
const [press] = useState(() => new Animated.Value(0));
|
|
834
822
|
const first = useRef(true);
|
|
835
823
|
const firstBadge = useRef(true);
|
|
836
824
|
|