@cdx-ui/components 0.1.5 → 0.1.7
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/coverage.svg +1 -1
- package/lib/commonjs/components/Alert/index.js.map +1 -1
- package/lib/commonjs/components/Avatar/index.js +6 -4
- package/lib/commonjs/components/Avatar/index.js.map +1 -1
- package/lib/commonjs/components/Badge/index.js.map +1 -1
- package/lib/commonjs/components/Badge/styles.js +2 -2
- package/lib/commonjs/components/BottomSheet/index.js +106 -91
- package/lib/commonjs/components/BottomSheet/index.js.map +1 -1
- package/lib/commonjs/components/BottomSheet/styles.js +1 -12
- package/lib/commonjs/components/BottomSheet/styles.js.map +1 -1
- package/lib/commonjs/components/Button/index.js.map +1 -1
- package/lib/commonjs/components/Card/index.js.map +1 -1
- package/lib/commonjs/components/Dialog/index.js.map +1 -1
- package/lib/commonjs/components/Divider/index.js.map +1 -1
- package/lib/commonjs/components/Form/styles.js +1 -1
- package/lib/commonjs/components/Form/styles.js.map +1 -1
- package/lib/commonjs/components/FullScreenDialog/animation.js +46 -0
- package/lib/commonjs/components/FullScreenDialog/animation.js.map +1 -0
- package/lib/commonjs/components/FullScreenDialog/index.js +343 -0
- package/lib/commonjs/components/FullScreenDialog/index.js.map +1 -0
- package/lib/commonjs/components/FullScreenDialog/styles.js +14 -0
- package/lib/commonjs/components/FullScreenDialog/styles.js.map +1 -0
- package/lib/commonjs/components/IconButton/styles.js +7 -5
- package/lib/commonjs/components/IconButton/styles.js.map +1 -1
- package/lib/commonjs/components/InsuranceDisclosure/index.js.map +1 -1
- package/lib/commonjs/components/Link/index.js.map +1 -1
- package/lib/commonjs/components/ListItem/index.js +2 -0
- package/lib/commonjs/components/ListItem/index.js.map +1 -1
- package/lib/commonjs/components/ListItem/styles.js +6 -0
- package/lib/commonjs/components/ListItem/styles.js.map +1 -1
- package/lib/commonjs/components/ProgressSegmented/index.js.map +1 -1
- package/lib/commonjs/components/Radio/index.js.map +1 -1
- package/lib/commonjs/components/ScopedTheme/index.js +11 -3
- package/lib/commonjs/components/ScopedTheme/index.js.map +1 -1
- package/lib/commonjs/components/Skeleton/index.js.map +1 -1
- package/lib/commonjs/components/Stack/HStack.js.map +1 -1
- package/lib/commonjs/components/Stack/VStack.js.map +1 -1
- package/lib/commonjs/components/Textarea/index.js.map +1 -1
- package/lib/commonjs/components/Tile/index.js.map +1 -1
- package/lib/commonjs/components/Toast/index.js +40 -12
- package/lib/commonjs/components/Toast/index.js.map +1 -1
- package/lib/commonjs/components/Toast/styles.js +15 -4
- package/lib/commonjs/components/Toast/styles.js.map +1 -1
- package/lib/commonjs/components/ToggleButton/index.js +249 -0
- package/lib/commonjs/components/ToggleButton/index.js.map +1 -0
- package/lib/commonjs/components/ToggleButton/styles.js +155 -0
- package/lib/commonjs/components/ToggleButton/styles.js.map +1 -0
- package/lib/commonjs/components/index.js +24 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/components/picker/styles.js +6 -2
- package/lib/commonjs/components/picker/styles.js.map +1 -1
- package/lib/commonjs/components/sheet-header/index.js +97 -0
- package/lib/commonjs/components/sheet-header/index.js.map +1 -0
- package/lib/commonjs/components/sheet-header/styles.js +28 -0
- package/lib/commonjs/components/sheet-header/styles.js.map +1 -0
- package/lib/commonjs/figma/BottomSheet.figma.js +1 -1
- package/lib/commonjs/providers/toast/provider.js +44 -11
- package/lib/commonjs/providers/toast/provider.js.map +1 -1
- package/lib/module/components/Alert/index.js.map +1 -1
- package/lib/module/components/Avatar/index.js +6 -4
- package/lib/module/components/Avatar/index.js.map +1 -1
- package/lib/module/components/Badge/index.js.map +1 -1
- package/lib/module/components/Badge/styles.js +2 -2
- package/lib/module/components/BottomSheet/index.js +110 -95
- package/lib/module/components/BottomSheet/index.js.map +1 -1
- package/lib/module/components/BottomSheet/styles.js +0 -11
- package/lib/module/components/BottomSheet/styles.js.map +1 -1
- package/lib/module/components/Button/index.js.map +1 -1
- package/lib/module/components/Card/index.js.map +1 -1
- package/lib/module/components/Dialog/index.js.map +1 -1
- package/lib/module/components/Divider/index.js.map +1 -1
- package/lib/module/components/Form/styles.js +1 -1
- package/lib/module/components/Form/styles.js.map +1 -1
- package/lib/module/components/FullScreenDialog/animation.js +41 -0
- package/lib/module/components/FullScreenDialog/animation.js.map +1 -0
- package/lib/module/components/FullScreenDialog/index.js +338 -0
- package/lib/module/components/FullScreenDialog/index.js.map +1 -0
- package/lib/module/components/FullScreenDialog/styles.js +10 -0
- package/lib/module/components/FullScreenDialog/styles.js.map +1 -0
- package/lib/module/components/IconButton/styles.js +7 -4
- package/lib/module/components/IconButton/styles.js.map +1 -1
- package/lib/module/components/InsuranceDisclosure/index.js.map +1 -1
- package/lib/module/components/Link/index.js.map +1 -1
- package/lib/module/components/ListItem/index.js +2 -0
- package/lib/module/components/ListItem/index.js.map +1 -1
- package/lib/module/components/ListItem/styles.js +6 -0
- package/lib/module/components/ListItem/styles.js.map +1 -1
- package/lib/module/components/ProgressSegmented/index.js.map +1 -1
- package/lib/module/components/Radio/index.js.map +1 -1
- package/lib/module/components/ScopedTheme/index.js +11 -3
- package/lib/module/components/ScopedTheme/index.js.map +1 -1
- package/lib/module/components/Skeleton/index.js.map +1 -1
- package/lib/module/components/Stack/HStack.js.map +1 -1
- package/lib/module/components/Stack/VStack.js.map +1 -1
- package/lib/module/components/Textarea/index.js.map +1 -1
- package/lib/module/components/Tile/index.js.map +1 -1
- package/lib/module/components/Toast/index.js +43 -15
- package/lib/module/components/Toast/index.js.map +1 -1
- package/lib/module/components/Toast/styles.js +14 -3
- package/lib/module/components/Toast/styles.js.map +1 -1
- package/lib/module/components/ToggleButton/index.js +245 -0
- package/lib/module/components/ToggleButton/index.js.map +1 -0
- package/lib/module/components/ToggleButton/styles.js +152 -0
- package/lib/module/components/ToggleButton/styles.js.map +1 -0
- package/lib/module/components/index.js +2 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/components/picker/styles.js +6 -2
- package/lib/module/components/picker/styles.js.map +1 -1
- package/lib/module/components/sheet-header/index.js +94 -0
- package/lib/module/components/sheet-header/index.js.map +1 -0
- package/lib/module/components/sheet-header/styles.js +25 -0
- package/lib/module/components/sheet-header/styles.js.map +1 -0
- package/lib/module/figma/BottomSheet.figma.js +1 -1
- package/lib/module/providers/toast/provider.js +44 -11
- package/lib/module/providers/toast/provider.js.map +1 -1
- package/lib/typescript/components/Alert/index.d.ts +4 -1
- package/lib/typescript/components/Alert/index.d.ts.map +1 -1
- package/lib/typescript/components/Avatar/index.d.ts +10 -4
- package/lib/typescript/components/Avatar/index.d.ts.map +1 -1
- package/lib/typescript/components/Badge/index.d.ts +34 -0
- package/lib/typescript/components/Badge/index.d.ts.map +1 -1
- package/lib/typescript/components/BottomSheet/index.d.ts +12 -1
- package/lib/typescript/components/BottomSheet/index.d.ts.map +1 -1
- package/lib/typescript/components/BottomSheet/styles.d.ts +0 -5
- package/lib/typescript/components/BottomSheet/styles.d.ts.map +1 -1
- package/lib/typescript/components/Button/index.d.ts +9 -1
- package/lib/typescript/components/Button/index.d.ts.map +1 -1
- package/lib/typescript/components/Card/index.d.ts +14 -0
- package/lib/typescript/components/Card/index.d.ts.map +1 -1
- package/lib/typescript/components/Chip/index.d.ts +1 -1
- package/lib/typescript/components/CurrencyInput/index.d.ts +2 -2
- package/lib/typescript/components/CurrencyInput/index.d.ts.map +1 -1
- package/lib/typescript/components/Dialog/index.d.ts +10 -0
- package/lib/typescript/components/Dialog/index.d.ts.map +1 -1
- package/lib/typescript/components/Dialog/styles.d.ts +1 -0
- package/lib/typescript/components/Dialog/styles.d.ts.map +1 -1
- package/lib/typescript/components/Divider/index.d.ts +5 -0
- package/lib/typescript/components/Divider/index.d.ts.map +1 -1
- package/lib/typescript/components/Drawer/styles.d.ts +1 -1
- package/lib/typescript/components/Form/styles.d.ts.map +1 -1
- package/lib/typescript/components/FullScreenDialog/animation.d.ts +9 -0
- package/lib/typescript/components/FullScreenDialog/animation.d.ts.map +1 -0
- package/lib/typescript/components/FullScreenDialog/index.d.ts +85 -0
- package/lib/typescript/components/FullScreenDialog/index.d.ts.map +1 -0
- package/lib/typescript/components/FullScreenDialog/styles.d.ts +6 -0
- package/lib/typescript/components/FullScreenDialog/styles.d.ts.map +1 -0
- package/lib/typescript/components/IconButton/styles.d.ts +5 -0
- package/lib/typescript/components/IconButton/styles.d.ts.map +1 -1
- package/lib/typescript/components/Input/index.d.ts +1 -1
- package/lib/typescript/components/InsuranceDisclosure/index.d.ts +1 -0
- package/lib/typescript/components/InsuranceDisclosure/index.d.ts.map +1 -1
- package/lib/typescript/components/Link/index.d.ts +2 -0
- package/lib/typescript/components/Link/index.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/index.d.ts +43 -4
- package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/styles.d.ts +2 -0
- package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
- package/lib/typescript/components/ProgressSegmented/index.d.ts +10 -3
- package/lib/typescript/components/ProgressSegmented/index.d.ts.map +1 -1
- package/lib/typescript/components/Radio/index.d.ts +1 -0
- package/lib/typescript/components/Radio/index.d.ts.map +1 -1
- package/lib/typescript/components/ScopedTheme/index.d.ts +11 -3
- package/lib/typescript/components/ScopedTheme/index.d.ts.map +1 -1
- package/lib/typescript/components/Skeleton/index.d.ts +5 -1
- package/lib/typescript/components/Skeleton/index.d.ts.map +1 -1
- package/lib/typescript/components/Stack/HStack.d.ts +6 -0
- package/lib/typescript/components/Stack/HStack.d.ts.map +1 -1
- package/lib/typescript/components/Stack/VStack.d.ts +6 -0
- package/lib/typescript/components/Stack/VStack.d.ts.map +1 -1
- package/lib/typescript/components/Switch/index.d.ts +1 -1
- package/lib/typescript/components/Tabs/index.d.ts +2 -2
- package/lib/typescript/components/Textarea/index.d.ts +1 -0
- package/lib/typescript/components/Textarea/index.d.ts.map +1 -1
- package/lib/typescript/components/Tile/index.d.ts +49 -0
- package/lib/typescript/components/Tile/index.d.ts.map +1 -1
- package/lib/typescript/components/Toast/index.d.ts +15 -0
- package/lib/typescript/components/Toast/index.d.ts.map +1 -1
- package/lib/typescript/components/Toast/styles.d.ts +10 -0
- package/lib/typescript/components/Toast/styles.d.ts.map +1 -1
- package/lib/typescript/components/Toast/types.d.ts +9 -0
- package/lib/typescript/components/Toast/types.d.ts.map +1 -1
- package/lib/typescript/components/ToggleButton/index.d.ts +78 -0
- package/lib/typescript/components/ToggleButton/index.d.ts.map +1 -0
- package/lib/typescript/components/ToggleButton/styles.d.ts +30 -0
- package/lib/typescript/components/ToggleButton/styles.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +2 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/components/picker/styles.d.ts +5 -2
- package/lib/typescript/components/picker/styles.d.ts.map +1 -1
- package/lib/typescript/components/sheet-header/index.d.ts +24 -0
- package/lib/typescript/components/sheet-header/index.d.ts.map +1 -0
- package/lib/typescript/components/sheet-header/styles.d.ts +12 -0
- package/lib/typescript/components/sheet-header/styles.d.ts.map +1 -0
- package/lib/typescript/providers/toast/provider.d.ts +1 -1
- package/lib/typescript/providers/toast/provider.d.ts.map +1 -1
- package/lib/typescript/providers/toast/types.d.ts +16 -4
- package/lib/typescript/providers/toast/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/components/Alert/index.tsx +4 -1
- package/src/components/Avatar/index.tsx +10 -4
- package/src/components/Badge/index.tsx +34 -0
- package/src/components/Badge/styles.ts +2 -2
- package/src/components/BottomSheet/index.tsx +156 -125
- package/src/components/BottomSheet/styles.ts +1 -22
- package/src/components/Button/index.tsx +9 -1
- package/src/components/Card/index.tsx +14 -0
- package/src/components/Chip/index.tsx +1 -1
- package/src/components/CurrencyInput/index.tsx +2 -2
- package/src/components/Dialog/index.tsx +10 -0
- package/src/components/Dialog/styles.ts +1 -0
- package/src/components/Divider/index.tsx +5 -0
- package/src/components/Form/styles.ts +1 -1
- package/src/components/FullScreenDialog/animation.ts +22 -0
- package/src/components/FullScreenDialog/index.tsx +484 -0
- package/src/components/FullScreenDialog/styles.ts +23 -0
- package/src/components/IconButton/styles.ts +7 -4
- package/src/components/Input/index.tsx +1 -1
- package/src/components/InsuranceDisclosure/index.tsx +1 -0
- package/src/components/Link/index.tsx +2 -0
- package/src/components/ListItem/index.tsx +48 -4
- package/src/components/ListItem/styles.ts +7 -0
- package/src/components/ProgressSegmented/index.tsx +10 -3
- package/src/components/Radio/index.tsx +1 -0
- package/src/components/ScopedTheme/index.tsx +11 -3
- package/src/components/Skeleton/index.tsx +5 -1
- package/src/components/Stack/HStack.tsx +6 -0
- package/src/components/Stack/VStack.tsx +6 -0
- package/src/components/Switch/index.tsx +1 -1
- package/src/components/Tabs/index.tsx +2 -2
- package/src/components/Textarea/index.tsx +1 -0
- package/src/components/Tile/index.tsx +49 -0
- package/src/components/Toast/index.tsx +55 -9
- package/src/components/Toast/styles.ts +14 -3
- package/src/components/Toast/types.ts +9 -0
- package/src/components/ToggleButton/index.tsx +346 -0
- package/src/components/ToggleButton/styles.ts +191 -0
- package/src/components/index.ts +2 -0
- package/src/components/picker/styles.ts +6 -2
- package/src/components/sheet-header/index.tsx +148 -0
- package/src/components/sheet-header/styles.ts +28 -0
- package/src/providers/toast/provider.tsx +47 -13
- package/src/providers/toast/types.ts +16 -4
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useCallback,
|
|
4
|
+
useContext,
|
|
5
|
+
useEffect,
|
|
6
|
+
useId,
|
|
7
|
+
useImperativeHandle,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
type ReactNode,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import { BackHandler, Dimensions, Platform, View, ViewStyle } from 'react-native';
|
|
3
13
|
import { SafeAreaInsetsContext, type EdgeInsets } from 'react-native-safe-area-context';
|
|
4
14
|
import { useResolveClassNames } from 'uniwind';
|
|
5
15
|
import {
|
|
@@ -14,16 +24,13 @@ import {
|
|
|
14
24
|
type BottomSheetFooterProps as GorhomBottomSheetFooterProps,
|
|
15
25
|
type BottomSheetModalProps as GorhomBottomSheetModalProps,
|
|
16
26
|
} from '@gorhom/bottom-sheet';
|
|
27
|
+
import { useEscapeKey, useOverlayStackRegistration } from '@cdx-ui/primitives';
|
|
17
28
|
import { cn } from '@cdx-ui/utils';
|
|
18
|
-
import {
|
|
19
|
-
import { Heading } from '../Heading';
|
|
20
|
-
import { IconButton } from '../IconButton';
|
|
21
|
-
import { Text } from '../Text';
|
|
29
|
+
import { SheetHeader } from '../sheet-header';
|
|
22
30
|
import {
|
|
23
31
|
bottomSheetBackgroundClassName,
|
|
24
32
|
bottomSheetContentVariants,
|
|
25
33
|
bottomSheetFooterVariants,
|
|
26
|
-
bottomSheetHeaderVariants,
|
|
27
34
|
bottomSheetModalContainerClassName,
|
|
28
35
|
} from './styles';
|
|
29
36
|
|
|
@@ -37,131 +44,52 @@ function useSafeInsets(): EdgeInsets {
|
|
|
37
44
|
export type BottomSheetModalRef = React.ComponentRef<typeof BottomSheetModal>;
|
|
38
45
|
|
|
39
46
|
export interface BottomSheetHeaderProps {
|
|
47
|
+
/** Title text. Ignored when `children` is set. */
|
|
40
48
|
title?: string;
|
|
49
|
+
/** Secondary line under the title. Has no effect without `title`, or when `children` is set. */
|
|
41
50
|
subtitle?: string;
|
|
51
|
+
/** Custom header content. Replaces `title` and `subtitle`. */
|
|
42
52
|
children?: ReactNode;
|
|
43
53
|
className?: string;
|
|
54
|
+
/** Shows the close button when set. */
|
|
44
55
|
onClose?: () => void;
|
|
56
|
+
/** Accessible name for the close button. @default Close */
|
|
45
57
|
closeAccessibilityLabel?: string;
|
|
58
|
+
/** Shows the back button when set. */
|
|
46
59
|
onBack?: () => void;
|
|
60
|
+
/** Accessible name for the back button. @default Go back */
|
|
47
61
|
backAccessibilityLabel?: string;
|
|
48
62
|
}
|
|
49
63
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
<BottomSheetBackButton
|
|
69
|
-
className={cn(!onBack && 'opacity-0')}
|
|
70
|
-
onPress={onBack}
|
|
71
|
-
{...(backAccessibilityLabel !== undefined && {
|
|
72
|
-
accessibilityLabel: backAccessibilityLabel,
|
|
73
|
-
})}
|
|
74
|
-
/>
|
|
75
|
-
<View className="flex-1">
|
|
76
|
-
{children ??
|
|
77
|
-
(hasTitle ? (
|
|
78
|
-
<View>
|
|
79
|
-
<Heading size="sm" className="text-center">
|
|
80
|
-
{title}
|
|
81
|
-
</Heading>
|
|
82
|
-
{subtitle ? (
|
|
83
|
-
<Text size="sm" className="text-center text-content-secondary">
|
|
84
|
-
{subtitle}
|
|
85
|
-
</Text>
|
|
86
|
-
) : null}
|
|
87
|
-
</View>
|
|
88
|
-
) : null)}
|
|
89
|
-
</View>
|
|
90
|
-
<BottomSheetCloseButton
|
|
91
|
-
className={cn(!onClose && 'opacity-0')}
|
|
92
|
-
onPress={onClose}
|
|
93
|
-
{...(closeAccessibilityLabel !== undefined && {
|
|
94
|
-
accessibilityLabel: closeAccessibilityLabel,
|
|
95
|
-
})}
|
|
96
|
-
/>
|
|
97
|
-
</View>
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
BottomSheetHeaderComponent.displayName = 'BottomSheet.Header';
|
|
102
|
-
|
|
103
|
-
const BottomSheetHeader = forwardRef<View, BottomSheetHeaderProps>(BottomSheetHeaderComponent);
|
|
104
|
-
BottomSheetHeader.displayName = 'BottomSheet.Header';
|
|
105
|
-
|
|
106
|
-
// =============================================================================
|
|
107
|
-
// BACKBUTTON
|
|
108
|
-
// =============================================================================
|
|
109
|
-
interface BottomSheetBackButtonProps {
|
|
110
|
-
onPress?: () => void;
|
|
111
|
-
className?: string;
|
|
112
|
-
accessibilityLabel?: string;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function BottomSheetBackButton({
|
|
116
|
-
onPress,
|
|
117
|
-
className,
|
|
118
|
-
accessibilityLabel = 'Go back',
|
|
119
|
-
}: Readonly<BottomSheetBackButtonProps>) {
|
|
120
|
-
return (
|
|
121
|
-
<IconButton
|
|
122
|
-
as={ArrowBack}
|
|
123
|
-
variant="solid"
|
|
124
|
-
color="neutral"
|
|
125
|
-
size="default"
|
|
126
|
-
onPress={onPress}
|
|
127
|
-
hitSlop={12}
|
|
128
|
-
accessibilityLabel={accessibilityLabel}
|
|
129
|
-
className={className}
|
|
130
|
-
/>
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
BottomSheetBackButton.displayName = 'BottomSheet.BackButton';
|
|
135
|
-
|
|
136
|
-
// =============================================================================
|
|
137
|
-
// CLOSEBUTTON
|
|
138
|
-
// =============================================================================
|
|
139
|
-
interface BottomSheetCloseButtonProps {
|
|
140
|
-
onPress?: () => void;
|
|
141
|
-
className?: string;
|
|
142
|
-
accessibilityLabel?: string;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function BottomSheetCloseButton({
|
|
146
|
-
onPress,
|
|
147
|
-
className,
|
|
148
|
-
accessibilityLabel = 'Close',
|
|
149
|
-
}: Readonly<BottomSheetCloseButtonProps>) {
|
|
150
|
-
return (
|
|
151
|
-
<IconButton
|
|
152
|
-
as={Close}
|
|
153
|
-
variant="solid"
|
|
154
|
-
color="neutral"
|
|
155
|
-
size="default"
|
|
156
|
-
onPress={onPress}
|
|
157
|
-
hitSlop={12}
|
|
158
|
-
accessibilityLabel={accessibilityLabel}
|
|
64
|
+
const BottomSheetHeader = forwardRef<View, BottomSheetHeaderProps>(
|
|
65
|
+
(
|
|
66
|
+
{
|
|
67
|
+
title,
|
|
68
|
+
subtitle,
|
|
69
|
+
children,
|
|
70
|
+
className,
|
|
71
|
+
onClose,
|
|
72
|
+
closeAccessibilityLabel,
|
|
73
|
+
onBack,
|
|
74
|
+
backAccessibilityLabel,
|
|
75
|
+
},
|
|
76
|
+
ref,
|
|
77
|
+
) => (
|
|
78
|
+
<SheetHeader
|
|
79
|
+
ref={ref}
|
|
80
|
+
title={title}
|
|
81
|
+
subtitle={subtitle}
|
|
159
82
|
className={className}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
83
|
+
onClose={onClose}
|
|
84
|
+
closeAccessibilityLabel={closeAccessibilityLabel}
|
|
85
|
+
onBack={onBack}
|
|
86
|
+
backAccessibilityLabel={backAccessibilityLabel}
|
|
87
|
+
>
|
|
88
|
+
{children}
|
|
89
|
+
</SheetHeader>
|
|
90
|
+
),
|
|
91
|
+
);
|
|
92
|
+
BottomSheetHeader.displayName = 'BottomSheet.Header';
|
|
165
93
|
|
|
166
94
|
// =============================================================================
|
|
167
95
|
// CONTENT
|
|
@@ -170,6 +98,7 @@ BottomSheetCloseButton.displayName = 'BottomSheet.CloseButton';
|
|
|
170
98
|
export interface BottomSheetContentProps {
|
|
171
99
|
children?: ReactNode;
|
|
172
100
|
className?: string;
|
|
101
|
+
/** Adds bottom padding equal to the safe-area inset. */
|
|
173
102
|
hasSafeAreaInset?: boolean;
|
|
174
103
|
style?: ViewStyle;
|
|
175
104
|
}
|
|
@@ -228,7 +157,10 @@ BottomSheetFooter.displayName = 'BottomSheet.Footer';
|
|
|
228
157
|
export interface BottomSheetModalProps extends GorhomBottomSheetModalProps {
|
|
229
158
|
/** Show the drag handle indicator. When false, `handleComponent` is set to null. @default true */
|
|
230
159
|
handleVisible?: boolean;
|
|
231
|
-
/**
|
|
160
|
+
/**
|
|
161
|
+
* Footer content rendered via gorhom's BottomSheetFooter for animated positioning and safe-area handling.
|
|
162
|
+
* Pass it through this prop; a footer placed as a child does not animate with the sheet.
|
|
163
|
+
*/
|
|
232
164
|
footer?: ReactNode;
|
|
233
165
|
}
|
|
234
166
|
|
|
@@ -253,7 +185,7 @@ const CustomBackground = (props: React.ComponentPropsWithoutRef<typeof View>) =>
|
|
|
253
185
|
const BottomSheetModalStyled = forwardRef<
|
|
254
186
|
React.ComponentRef<typeof BottomSheetModal>,
|
|
255
187
|
BottomSheetModalProps
|
|
256
|
-
>(({ handleVisible = true, footer, onDismiss, onChange, ...rest }, ref) => {
|
|
188
|
+
>(({ handleVisible = true, footer, onDismiss, onChange, onAnimate, ...rest }, ref) => {
|
|
257
189
|
const renderFooter = useCallback(
|
|
258
190
|
(props: GorhomBottomSheetFooterProps) => (
|
|
259
191
|
<GorhomBottomSheetFooter {...props}>{footer}</GorhomBottomSheetFooter>
|
|
@@ -261,9 +193,67 @@ const BottomSheetModalStyled = forwardRef<
|
|
|
261
193
|
[footer],
|
|
262
194
|
);
|
|
263
195
|
|
|
196
|
+
const modalRef = useRef<BottomSheetModalRef | null>(null);
|
|
264
197
|
const dismissedRef = useRef(false);
|
|
198
|
+
const sheetMountedRef = useRef(false);
|
|
199
|
+
const mountPendingRef = useRef(false);
|
|
200
|
+
const pendingDismissRef = useRef<Parameters<BottomSheetModalRef['dismiss']> | null>(null);
|
|
201
|
+
const [presented, setPresented] = useState(false);
|
|
202
|
+
|
|
203
|
+
// Must stay a callback ref: gorhom hands this ref to its modal provider, which
|
|
204
|
+
// reads `.current` to minimize and restore stacked sheets. A ref object would
|
|
205
|
+
// switch that stacking on.
|
|
206
|
+
const setModalRef = useCallback((instance: BottomSheetModalRef | null) => {
|
|
207
|
+
modalRef.current = instance;
|
|
208
|
+
}, []);
|
|
209
|
+
|
|
210
|
+
// gorhom mounts the sheet a frame after `present()` and silently drops a
|
|
211
|
+
// `dismiss()` that arrives before then, never reporting `onDismiss`. Holding
|
|
212
|
+
// it until the sheet mounts keeps the early Escape/back claim releasable.
|
|
213
|
+
const dismissSheet = useCallback((...args: Parameters<BottomSheetModalRef['dismiss']>) => {
|
|
214
|
+
if (mountPendingRef.current) {
|
|
215
|
+
pendingDismissRef.current = args;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
modalRef.current?.dismiss(...args);
|
|
219
|
+
}, []);
|
|
220
|
+
|
|
221
|
+
const markSheetMounted = useCallback(() => {
|
|
222
|
+
sheetMountedRef.current = true;
|
|
223
|
+
if (!mountPendingRef.current) return;
|
|
224
|
+
mountPendingRef.current = false;
|
|
225
|
+
const pendingDismiss = pendingDismissRef.current;
|
|
226
|
+
pendingDismissRef.current = null;
|
|
227
|
+
if (pendingDismiss) modalRef.current?.dismiss(...pendingDismiss);
|
|
228
|
+
}, []);
|
|
229
|
+
|
|
230
|
+
// `present()` claims Escape and back immediately; waiting for the first
|
|
231
|
+
// `onChange` would leave the overlay beneath in charge for the whole open animation.
|
|
232
|
+
useImperativeHandle(
|
|
233
|
+
ref,
|
|
234
|
+
(): BottomSheetModalRef => ({
|
|
235
|
+
present: (...args) => {
|
|
236
|
+
dismissedRef.current = false;
|
|
237
|
+
if (!sheetMountedRef.current) mountPendingRef.current = true;
|
|
238
|
+
setPresented(true);
|
|
239
|
+
modalRef.current?.present(...args);
|
|
240
|
+
},
|
|
241
|
+
dismiss: dismissSheet,
|
|
242
|
+
snapToIndex: (...args) => modalRef.current?.snapToIndex(...args),
|
|
243
|
+
snapToPosition: (...args) => modalRef.current?.snapToPosition(...args),
|
|
244
|
+
expand: (...args) => modalRef.current?.expand(...args),
|
|
245
|
+
collapse: (...args) => modalRef.current?.collapse(...args),
|
|
246
|
+
close: (...args) => modalRef.current?.close(...args),
|
|
247
|
+
forceClose: (...args) => modalRef.current?.forceClose(...args),
|
|
248
|
+
}),
|
|
249
|
+
[dismissSheet],
|
|
250
|
+
);
|
|
265
251
|
|
|
266
252
|
const handleDismiss = useCallback(() => {
|
|
253
|
+
sheetMountedRef.current = false;
|
|
254
|
+
mountPendingRef.current = false;
|
|
255
|
+
pendingDismissRef.current = null;
|
|
256
|
+
setPresented(false);
|
|
267
257
|
if (dismissedRef.current) return;
|
|
268
258
|
dismissedRef.current = true;
|
|
269
259
|
onDismiss?.();
|
|
@@ -272,11 +262,51 @@ const BottomSheetModalStyled = forwardRef<
|
|
|
272
262
|
const handleChange = useCallback(
|
|
273
263
|
(...args: Parameters<NonNullable<BottomSheetModalProps['onChange']>>) => {
|
|
274
264
|
dismissedRef.current = false;
|
|
265
|
+
setPresented(args[0] >= 0);
|
|
266
|
+
if (args[0] >= 0) markSheetMounted();
|
|
275
267
|
onChange?.(...args);
|
|
276
268
|
},
|
|
277
|
-
[onChange],
|
|
269
|
+
[markSheetMounted, onChange],
|
|
278
270
|
);
|
|
279
271
|
|
|
272
|
+
const handleAnimate = useCallback(
|
|
273
|
+
(...args: Parameters<NonNullable<BottomSheetModalProps['onAnimate']>>) => {
|
|
274
|
+
if (args[1] >= 0) markSheetMounted();
|
|
275
|
+
onAnimate?.(...args);
|
|
276
|
+
},
|
|
277
|
+
[markSheetMounted, onAnimate],
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
const id = useId();
|
|
281
|
+
const overlayId = `bottom-sheet-${id}`;
|
|
282
|
+
useEscapeKey(presented, dismissSheet, {
|
|
283
|
+
id: overlayId,
|
|
284
|
+
groupId: overlayId,
|
|
285
|
+
layer: 'modal',
|
|
286
|
+
});
|
|
287
|
+
const { isTopmost } = useOverlayStackRegistration({
|
|
288
|
+
active: presented && Platform.OS !== 'web',
|
|
289
|
+
capabilities: ['back'],
|
|
290
|
+
id: overlayId,
|
|
291
|
+
groupId: overlayId,
|
|
292
|
+
layer: 'modal',
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
useEffect(() => {
|
|
296
|
+
// BackHandler is native-only; react-native-web warns on every subscription.
|
|
297
|
+
if (!presented || Platform.OS === 'web') return;
|
|
298
|
+
|
|
299
|
+
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
|
|
300
|
+
if (!isTopmost('back')) return false;
|
|
301
|
+
dismissSheet();
|
|
302
|
+
return true;
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
return () => {
|
|
306
|
+
backHandler.remove();
|
|
307
|
+
};
|
|
308
|
+
}, [dismissSheet, isTopmost, presented]);
|
|
309
|
+
|
|
280
310
|
const sheetContainerStyle = useResolveClassNames(bottomSheetModalContainerClassName);
|
|
281
311
|
const handleIndicatorStyle = useResolveClassNames(
|
|
282
312
|
'bg-surface-neutral-subtle w-9 h-[5px] rounded-full',
|
|
@@ -284,7 +314,7 @@ const BottomSheetModalStyled = forwardRef<
|
|
|
284
314
|
|
|
285
315
|
return (
|
|
286
316
|
<BottomSheetModal
|
|
287
|
-
ref={
|
|
317
|
+
ref={setModalRef}
|
|
288
318
|
enableDynamicSizing
|
|
289
319
|
maxDynamicContentSize={MAX_DYNAMIC_CONTENT_SIZE}
|
|
290
320
|
style={sheetContainerStyle}
|
|
@@ -295,6 +325,7 @@ const BottomSheetModalStyled = forwardRef<
|
|
|
295
325
|
{...rest}
|
|
296
326
|
onDismiss={handleDismiss}
|
|
297
327
|
onChange={handleChange}
|
|
328
|
+
onAnimate={handleAnimate}
|
|
298
329
|
{...(footer != null && { footerComponent: renderFooter })}
|
|
299
330
|
/>
|
|
300
331
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cva
|
|
1
|
+
import { cva } from '@cdx-ui/utils';
|
|
2
2
|
|
|
3
3
|
/** Keep gorhom's animated container unclipped so web transforms can settle correctly. */
|
|
4
4
|
export const bottomSheetModalContainerClassName = 'rounded-t-4xl';
|
|
@@ -6,27 +6,6 @@ export const bottomSheetModalContainerClassName = 'rounded-t-4xl';
|
|
|
6
6
|
/** Clip the static background for rounded corners without clipping the animated sheet. */
|
|
7
7
|
export const bottomSheetBackgroundClassName = `${bottomSheetModalContainerClassName} overflow-hidden bg-surface-primary`;
|
|
8
8
|
|
|
9
|
-
export const bottomSheetHeaderVariants = cva(
|
|
10
|
-
[
|
|
11
|
-
'flex-row items-center justify-between min-h-11 px-4 pt-3 pb-2.5',
|
|
12
|
-
'bg-surface-primary',
|
|
13
|
-
'text-content-primary',
|
|
14
|
-
],
|
|
15
|
-
{
|
|
16
|
-
variants: {
|
|
17
|
-
hasTitle: {
|
|
18
|
-
true: '',
|
|
19
|
-
false: 'justify-end',
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
defaultVariants: {
|
|
23
|
-
hasTitle: true,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
);
|
|
27
|
-
|
|
28
9
|
export const bottomSheetContentVariants = cva(['bg-surface-primary', 'px-5 pb-5 gap-3']);
|
|
29
10
|
|
|
30
11
|
export const bottomSheetFooterVariants = cva(['px-5 pb-5 gap-2', 'bg-surface-primary']);
|
|
31
|
-
|
|
32
|
-
export type BottomSheetHeaderVariants = VariantProps<typeof bottomSheetHeaderVariants>;
|
|
@@ -342,7 +342,10 @@ export interface ButtonSpinnerProps extends ActivityIndicatorProps {
|
|
|
342
342
|
asChild?: boolean;
|
|
343
343
|
/** Additional Uniwind/Tailwind classes for the spinner container. */
|
|
344
344
|
className?: string;
|
|
345
|
-
/**
|
|
345
|
+
/**
|
|
346
|
+
* Uniwind `accent-*` color class override for the spinner.
|
|
347
|
+
* When omitted, the color is derived from the parent button's `variant` and `color`.
|
|
348
|
+
*/
|
|
346
349
|
colorClassName?: string;
|
|
347
350
|
/**
|
|
348
351
|
* Position hint that emits `data-icon="inline-start"` or `data-icon="inline-end"`.
|
|
@@ -350,6 +353,11 @@ export interface ButtonSpinnerProps extends ActivityIndicatorProps {
|
|
|
350
353
|
* Omit to apply the symmetric baseline gap.
|
|
351
354
|
*/
|
|
352
355
|
position?: IconSlotPosition;
|
|
356
|
+
/**
|
|
357
|
+
* Screen reader label for the spinner.
|
|
358
|
+
* @default 'Loading'
|
|
359
|
+
*/
|
|
360
|
+
accessibilityLabel?: string;
|
|
353
361
|
}
|
|
354
362
|
|
|
355
363
|
const ButtonSpinner = forwardRef<ActivityIndicator, ButtonSpinnerProps>(
|
|
@@ -22,6 +22,11 @@ const SCOPE = 'CARD';
|
|
|
22
22
|
const useCardStyleContext = () => useStyleContext(SCOPE) as CardVariantProps;
|
|
23
23
|
|
|
24
24
|
export interface CardProps extends ViewProps, CardVariantProps {
|
|
25
|
+
/**
|
|
26
|
+
* When `true`, `Card.Content` drops its padding and `Card.Footer` uses standalone
|
|
27
|
+
* padding. Both inherit this unless they set their own `fullBleed`.
|
|
28
|
+
*/
|
|
29
|
+
fullBleed?: CardVariantProps['fullBleed'];
|
|
25
30
|
asChild?: boolean;
|
|
26
31
|
className?: string;
|
|
27
32
|
children?: ReactNode;
|
|
@@ -117,6 +122,10 @@ CardHeader.displayName = 'Card.Header';
|
|
|
117
122
|
// =============================================================================
|
|
118
123
|
|
|
119
124
|
export interface CardContentProps extends ViewProps, CardContentVariantProps {
|
|
125
|
+
/**
|
|
126
|
+
* Removes this region's padding. Inherits the parent `Card`'s `fullBleed` when omitted.
|
|
127
|
+
*/
|
|
128
|
+
fullBleed?: CardContentVariantProps['fullBleed'];
|
|
120
129
|
asChild?: boolean;
|
|
121
130
|
className?: string;
|
|
122
131
|
children?: ReactNode;
|
|
@@ -152,6 +161,11 @@ CardContent.displayName = 'Card.Content';
|
|
|
152
161
|
// =============================================================================
|
|
153
162
|
|
|
154
163
|
export interface CardFooterProps extends ViewProps, CardFooterVariantProps {
|
|
164
|
+
/**
|
|
165
|
+
* Uses standalone padding instead of flush-top padding. Inherits the parent
|
|
166
|
+
* `Card`'s `fullBleed` when omitted.
|
|
167
|
+
*/
|
|
168
|
+
fullBleed?: CardFooterVariantProps['fullBleed'];
|
|
155
169
|
asChild?: boolean;
|
|
156
170
|
className?: string;
|
|
157
171
|
children?: ReactNode;
|
|
@@ -42,7 +42,7 @@ let hasWarnedChipDefaultColor = false;
|
|
|
42
42
|
|
|
43
43
|
export interface ChipProps extends IChipProps, Omit<ChipVariantProps, 'variant' | 'color'> {
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
45
|
+
* Filled subtle surface (`subtle`) or transparent with a border (`outline`).
|
|
46
46
|
* @default 'subtle'
|
|
47
47
|
*/
|
|
48
48
|
variant?:
|
|
@@ -40,9 +40,9 @@ export interface CurrencyInputProps
|
|
|
40
40
|
TextInputProps,
|
|
41
41
|
'accessibilityLabel' | 'accessibilityHint' | 'testID' | 'onFocus' | 'onBlur' | 'returnKeyType'
|
|
42
42
|
> {
|
|
43
|
-
/** Current
|
|
43
|
+
/** Current amount in major currency units, not cents. Renders a formatted zero when omitted or null. */
|
|
44
44
|
value?: number;
|
|
45
|
-
/** Called with the parsed
|
|
45
|
+
/** Called with the parsed amount in major currency units, not cents, when the user edits the field. */
|
|
46
46
|
onChangeValue?: (value: number) => void;
|
|
47
47
|
/** Currency symbol rendered as an inline prefix. Defaults to `"$"`. */
|
|
48
48
|
currencySymbol?: string;
|
|
@@ -95,6 +95,7 @@ const AnimatedOverlay = Animated.createAnimatedComponent(DialogOverlayPrimitive)
|
|
|
95
95
|
export interface DialogRootProps
|
|
96
96
|
extends Omit<ViewProps, 'children' | 'role'>, IDialogRootProps, DialogVariantProps {
|
|
97
97
|
className?: string;
|
|
98
|
+
/** Pass `'disable-all'` to turn off enter/exit and swipe animations for the popup and overlay. */
|
|
98
99
|
animation?: AnimationRootDisableAll;
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -174,7 +175,16 @@ export interface DialogPopupProps
|
|
|
174
175
|
extends Omit<IDialogContentProps, 'asChild'>, Pick<DialogVariantProps, 'size'> {
|
|
175
176
|
className?: string;
|
|
176
177
|
children?: ReactNode;
|
|
178
|
+
/**
|
|
179
|
+
* On iOS, render in a plain `View` instead of `FullWindowOverlay`. Re-enables
|
|
180
|
+
* the element inspector, but the popup no longer layers above native modals.
|
|
181
|
+
* @default false
|
|
182
|
+
*/
|
|
177
183
|
disableFullWindowOverlay?: boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Allow swipe-down to dismiss. Native only; no effect on web.
|
|
186
|
+
* @default true
|
|
187
|
+
*/
|
|
178
188
|
isSwipeable?: boolean;
|
|
179
189
|
/**
|
|
180
190
|
* Stacking order for the portal overlay layer (backdrop + popup panel).
|
|
@@ -141,6 +141,7 @@ export const dialogCloseIconVariants = cva(['size-5 text-content-tertiary']);
|
|
|
141
141
|
// ── Exported types ──────────────────────────────────────────
|
|
142
142
|
|
|
143
143
|
export type DialogVariantProps = VariantProps<typeof dialogPopupVariants> & {
|
|
144
|
+
/** Removes horizontal padding from `Dialog.Content`. @default false */
|
|
144
145
|
fullBleed?: boolean;
|
|
145
146
|
};
|
|
146
147
|
|
|
@@ -15,10 +15,15 @@ export interface DividerProps extends ViewProps {
|
|
|
15
15
|
className?: string;
|
|
16
16
|
/** Renders a vertical divider instead of the default horizontal orientation. */
|
|
17
17
|
vertical?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* When present, splits the divider into line, content, line.
|
|
20
|
+
* Use `Divider.Label` so the label receives the correct typography and accessibility treatment.
|
|
21
|
+
*/
|
|
18
22
|
children?: ReactNode;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
export interface DividerLabelProps extends TextProps {
|
|
26
|
+
/** Renders the consumer's child element in place of the default `Text` host. */
|
|
22
27
|
asChild?: boolean;
|
|
23
28
|
className?: string;
|
|
24
29
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Easing, Keyframe } from 'react-native-reanimated';
|
|
2
|
+
|
|
3
|
+
export const FULL_SCREEN_DIALOG_ENTER_MS = 300;
|
|
4
|
+
export const FULL_SCREEN_DIALOG_EXIT_MS = 220;
|
|
5
|
+
export const WEB_TRANSITION_SAFETY_MS = FULL_SCREEN_DIALOG_ENTER_MS + 100;
|
|
6
|
+
|
|
7
|
+
const ENTER_EASING = Easing.bezier(0.32, 0.72, 0, 1);
|
|
8
|
+
const EXIT_EASING = Easing.bezier(0.4, 0, 1, 1);
|
|
9
|
+
|
|
10
|
+
/** Native slide-up surface motion. `offscreen` is the distance below the viewport to start from. */
|
|
11
|
+
export function getFullScreenDialogSurfaceMotion(offscreen: number) {
|
|
12
|
+
return {
|
|
13
|
+
entering: new Keyframe({
|
|
14
|
+
0: { transform: [{ translateY: offscreen }] },
|
|
15
|
+
100: { transform: [{ translateY: 0 }], easing: ENTER_EASING },
|
|
16
|
+
}).duration(FULL_SCREEN_DIALOG_ENTER_MS),
|
|
17
|
+
exiting: new Keyframe({
|
|
18
|
+
0: { transform: [{ translateY: 0 }] },
|
|
19
|
+
100: { transform: [{ translateY: offscreen }], easing: EXIT_EASING },
|
|
20
|
+
}).duration(FULL_SCREEN_DIALOG_EXIT_MS),
|
|
21
|
+
};
|
|
22
|
+
}
|