@streamplace/components 0.7.34 → 0.8.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/dist/components/content-metadata/content-metadata-form.js +404 -0
- package/dist/components/content-metadata/content-rights.js +78 -0
- package/dist/components/content-metadata/content-warnings.js +68 -0
- package/dist/components/content-metadata/index.js +11 -0
- package/dist/components/dashboard/header.js +16 -2
- package/dist/components/dashboard/problems.js +29 -28
- package/dist/components/mobile-player/player.js +4 -0
- package/dist/components/mobile-player/ui/report-modal.js +3 -2
- package/dist/components/mobile-player/ui/viewer-context-menu.js +44 -1
- package/dist/components/ui/button.js +9 -9
- package/dist/components/ui/checkbox.js +87 -0
- package/dist/components/ui/dialog.js +188 -83
- package/dist/components/ui/dropdown.js +15 -10
- package/dist/components/ui/icons.js +6 -0
- package/dist/components/ui/primitives/button.js +0 -7
- package/dist/components/ui/primitives/input.js +13 -1
- package/dist/components/ui/primitives/modal.js +2 -2
- package/dist/components/ui/select.js +89 -0
- package/dist/components/ui/textarea.js +23 -4
- package/dist/components/ui/toast.js +464 -114
- package/dist/components/ui/tooltip.js +103 -0
- package/dist/index.js +2 -0
- package/dist/lib/metadata-constants.js +157 -0
- package/dist/lib/theme/theme.js +5 -3
- package/dist/lib/theme/tokens.js +9 -0
- package/dist/streamplace-provider/index.js +14 -4
- package/dist/streamplace-store/content-metadata-actions.js +118 -0
- package/dist/streamplace-store/graph.js +195 -0
- package/dist/streamplace-store/streamplace-store.js +18 -5
- package/dist/streamplace-store/user.js +67 -7
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/package.json +3 -3
- package/src/components/content-metadata/content-metadata-form.tsx +761 -0
- package/src/components/content-metadata/content-rights.tsx +104 -0
- package/src/components/content-metadata/content-warnings.tsx +100 -0
- package/src/components/content-metadata/index.tsx +18 -0
- package/src/components/dashboard/header.tsx +37 -3
- package/src/components/dashboard/index.tsx +1 -1
- package/src/components/dashboard/problems.tsx +57 -46
- package/src/components/mobile-player/player.tsx +5 -0
- package/src/components/mobile-player/ui/report-modal.tsx +13 -7
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +100 -1
- package/src/components/ui/button.tsx +10 -13
- package/src/components/ui/checkbox.tsx +147 -0
- package/src/components/ui/dialog.tsx +319 -99
- package/src/components/ui/dropdown.tsx +27 -13
- package/src/components/ui/icons.tsx +14 -0
- package/src/components/ui/primitives/button.tsx +0 -7
- package/src/components/ui/primitives/input.tsx +19 -2
- package/src/components/ui/primitives/modal.tsx +4 -2
- package/src/components/ui/select.tsx +175 -0
- package/src/components/ui/textarea.tsx +47 -29
- package/src/components/ui/toast.tsx +785 -179
- package/src/components/ui/tooltip.tsx +131 -0
- package/src/index.tsx +3 -0
- package/src/lib/metadata-constants.ts +180 -0
- package/src/lib/theme/theme.tsx +10 -6
- package/src/lib/theme/tokens.ts +9 -0
- package/src/streamplace-provider/index.tsx +20 -2
- package/src/streamplace-store/content-metadata-actions.tsx +142 -0
- package/src/streamplace-store/graph.tsx +232 -0
- package/src/streamplace-store/streamplace-store.tsx +30 -4
- package/src/streamplace-store/user.tsx +71 -7
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
import BottomSheet, { BottomSheetScrollView } from "@gorhom/bottom-sheet";
|
|
2
|
+
// to get the portal
|
|
3
|
+
import * as Portal from "@rn-primitives/portal";
|
|
1
4
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
5
|
import { X } from "lucide-react-native";
|
|
3
|
-
import React, { forwardRef } from "react";
|
|
4
|
-
import {
|
|
6
|
+
import React, { forwardRef, useRef } from "react";
|
|
7
|
+
import {
|
|
8
|
+
Platform,
|
|
9
|
+
Pressable,
|
|
10
|
+
StyleSheet,
|
|
11
|
+
useWindowDimensions,
|
|
12
|
+
View,
|
|
13
|
+
} from "react-native";
|
|
14
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
5
15
|
import { useTheme } from "../../lib/theme/theme";
|
|
6
|
-
import * as zero from "../../ui";
|
|
7
16
|
import { createThemedIcon } from "./icons";
|
|
8
17
|
import { ModalPrimitive, ModalPrimitiveProps } from "./primitives/modal";
|
|
18
|
+
import { Text } from "./text";
|
|
9
19
|
|
|
10
20
|
const ThemedX = createThemedIcon(X);
|
|
11
21
|
|
|
@@ -50,10 +60,138 @@ export interface DialogProps
|
|
|
50
60
|
onClose?: () => void;
|
|
51
61
|
}
|
|
52
62
|
|
|
63
|
+
// Bottom Sheet Dialog Component
|
|
64
|
+
const DialogBottomSheet = forwardRef<
|
|
65
|
+
any,
|
|
66
|
+
DialogProps & {
|
|
67
|
+
overlayStyle?: any;
|
|
68
|
+
portalHost?: string;
|
|
69
|
+
}
|
|
70
|
+
>(function DialogBottomSheet(
|
|
71
|
+
{
|
|
72
|
+
overlayStyle,
|
|
73
|
+
portalHost,
|
|
74
|
+
children,
|
|
75
|
+
title,
|
|
76
|
+
description,
|
|
77
|
+
showCloseButton = true,
|
|
78
|
+
onClose,
|
|
79
|
+
open = false,
|
|
80
|
+
onOpenChange,
|
|
81
|
+
...props
|
|
82
|
+
},
|
|
83
|
+
_ref,
|
|
84
|
+
) {
|
|
85
|
+
const { theme } = useTheme();
|
|
86
|
+
const sheetRef = useRef<BottomSheet>(null);
|
|
87
|
+
const { top } = useSafeAreaInsets();
|
|
88
|
+
const dims = useWindowDimensions();
|
|
89
|
+
|
|
90
|
+
const handleClose = React.useCallback(() => {
|
|
91
|
+
if (onClose) {
|
|
92
|
+
onClose();
|
|
93
|
+
}
|
|
94
|
+
if (onOpenChange) {
|
|
95
|
+
onOpenChange(false);
|
|
96
|
+
}
|
|
97
|
+
}, [onClose, onOpenChange]);
|
|
98
|
+
|
|
99
|
+
if (!open) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Portal.Portal name="dialog">
|
|
105
|
+
<BottomSheet
|
|
106
|
+
ref={sheetRef}
|
|
107
|
+
index={open ? 0 : -1}
|
|
108
|
+
enablePanDownToClose
|
|
109
|
+
enableDynamicSizing={true}
|
|
110
|
+
maxDynamicContentSize={dims.height - top}
|
|
111
|
+
keyboardBehavior="interactive"
|
|
112
|
+
keyboardBlurBehavior="restore"
|
|
113
|
+
enableContentPanningGesture={false}
|
|
114
|
+
backdropComponent={({ style }) => (
|
|
115
|
+
<Pressable
|
|
116
|
+
style={[style, StyleSheet.absoluteFill]}
|
|
117
|
+
onPress={handleClose}
|
|
118
|
+
/>
|
|
119
|
+
)}
|
|
120
|
+
onClose={handleClose}
|
|
121
|
+
style={[overlayStyle]}
|
|
122
|
+
backgroundStyle={{
|
|
123
|
+
backgroundColor: theme.colors.card,
|
|
124
|
+
borderRadius: theme.borderRadius.lg,
|
|
125
|
+
...theme.shadows.lg,
|
|
126
|
+
}}
|
|
127
|
+
handleIndicatorStyle={{
|
|
128
|
+
width: 48,
|
|
129
|
+
height: 4,
|
|
130
|
+
backgroundColor: theme.colors.textMuted,
|
|
131
|
+
}}
|
|
132
|
+
>
|
|
133
|
+
<BottomSheetScrollView
|
|
134
|
+
style={{
|
|
135
|
+
flex: 1,
|
|
136
|
+
width: "100%",
|
|
137
|
+
}}
|
|
138
|
+
contentContainerStyle={{ flexGrow: 1 }}
|
|
139
|
+
>
|
|
140
|
+
{/* Header */}
|
|
141
|
+
{(title || showCloseButton) && (
|
|
142
|
+
<View
|
|
143
|
+
style={{
|
|
144
|
+
paddingHorizontal: theme.spacing[4],
|
|
145
|
+
paddingVertical: theme.spacing[4],
|
|
146
|
+
flexDirection: "row",
|
|
147
|
+
alignItems: "center",
|
|
148
|
+
justifyContent: "space-between",
|
|
149
|
+
width: "100%",
|
|
150
|
+
}}
|
|
151
|
+
>
|
|
152
|
+
{title && <DialogTitle>{title}</DialogTitle>}
|
|
153
|
+
{showCloseButton && (
|
|
154
|
+
<Pressable
|
|
155
|
+
onPress={handleClose}
|
|
156
|
+
style={{
|
|
157
|
+
width: theme.touchTargets.minimum,
|
|
158
|
+
height: theme.touchTargets.minimum,
|
|
159
|
+
alignItems: "center",
|
|
160
|
+
justifyContent: "center",
|
|
161
|
+
borderRadius: theme.borderRadius.sm,
|
|
162
|
+
marginLeft: theme.spacing[2],
|
|
163
|
+
}}
|
|
164
|
+
>
|
|
165
|
+
<DialogCloseIcon />
|
|
166
|
+
</Pressable>
|
|
167
|
+
)}
|
|
168
|
+
</View>
|
|
169
|
+
)}
|
|
170
|
+
|
|
171
|
+
{/* Scrollable Content */}
|
|
172
|
+
<View
|
|
173
|
+
style={{
|
|
174
|
+
paddingHorizontal: theme.spacing[4],
|
|
175
|
+
paddingBottom: theme.spacing[6],
|
|
176
|
+
flex: 1,
|
|
177
|
+
width: "100%",
|
|
178
|
+
}}
|
|
179
|
+
>
|
|
180
|
+
{description && (
|
|
181
|
+
<DialogDescription>{description}</DialogDescription>
|
|
182
|
+
)}
|
|
183
|
+
{children}
|
|
184
|
+
</View>
|
|
185
|
+
</BottomSheetScrollView>
|
|
186
|
+
</BottomSheet>
|
|
187
|
+
</Portal.Portal>
|
|
188
|
+
);
|
|
189
|
+
});
|
|
190
|
+
|
|
53
191
|
export const Dialog = forwardRef<any, DialogProps>(
|
|
54
192
|
(
|
|
55
193
|
{
|
|
56
|
-
variant = "
|
|
194
|
+
variant = "default",
|
|
57
195
|
size = "md",
|
|
58
196
|
position = "center",
|
|
59
197
|
children,
|
|
@@ -68,70 +206,10 @@ export const Dialog = forwardRef<any, DialogProps>(
|
|
|
68
206
|
},
|
|
69
207
|
ref,
|
|
70
208
|
) => {
|
|
71
|
-
const {
|
|
72
|
-
|
|
73
|
-
//
|
|
74
|
-
const
|
|
75
|
-
const baseStyle = [
|
|
76
|
-
zt.bg.card,
|
|
77
|
-
zero.r.lg,
|
|
78
|
-
zero.shadows.lg,
|
|
79
|
-
{ maxHeight: "90%", maxWidth: "90%" },
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
const variantStyle = (() => {
|
|
83
|
-
switch (variant) {
|
|
84
|
-
case "sheet":
|
|
85
|
-
return [
|
|
86
|
-
{ borderRadius: zero.borderRadius.xl },
|
|
87
|
-
{
|
|
88
|
-
borderBottomLeftRadius: 0,
|
|
89
|
-
borderBottomRightRadius: 0,
|
|
90
|
-
marginTop: "auto",
|
|
91
|
-
marginBottom: 0,
|
|
92
|
-
maxHeight: "80%",
|
|
93
|
-
width: "100%",
|
|
94
|
-
maxWidth: "100%",
|
|
95
|
-
},
|
|
96
|
-
];
|
|
97
|
-
case "fullscreen":
|
|
98
|
-
return [
|
|
99
|
-
{
|
|
100
|
-
width: "100%",
|
|
101
|
-
height: "100%",
|
|
102
|
-
maxWidth: "100%",
|
|
103
|
-
maxHeight: "100%",
|
|
104
|
-
borderRadius: 0,
|
|
105
|
-
margin: 0,
|
|
106
|
-
},
|
|
107
|
-
];
|
|
108
|
-
default:
|
|
109
|
-
return [];
|
|
110
|
-
}
|
|
111
|
-
})();
|
|
112
|
-
|
|
113
|
-
const sizeStyle = (() => {
|
|
114
|
-
switch (size) {
|
|
115
|
-
case "sm":
|
|
116
|
-
return { minWidth: 300, minHeight: 200 };
|
|
117
|
-
case "lg":
|
|
118
|
-
return { minWidth: 500, minHeight: 400 };
|
|
119
|
-
case "xl":
|
|
120
|
-
return { minWidth: 600, minHeight: 500 };
|
|
121
|
-
case "full":
|
|
122
|
-
return {
|
|
123
|
-
width: "95%",
|
|
124
|
-
height: "95%",
|
|
125
|
-
maxWidth: "95%",
|
|
126
|
-
maxHeight: "95%",
|
|
127
|
-
};
|
|
128
|
-
default:
|
|
129
|
-
return { minWidth: 400, minHeight: 300 };
|
|
130
|
-
}
|
|
131
|
-
})();
|
|
132
|
-
|
|
133
|
-
return [baseStyle, variantStyle, sizeStyle].flat();
|
|
134
|
-
}, [variant, size, zero]);
|
|
209
|
+
const { theme } = useTheme();
|
|
210
|
+
|
|
211
|
+
// Create dynamic styles based on theme
|
|
212
|
+
const styles = React.useMemo(() => createStyles(theme), [theme]);
|
|
135
213
|
|
|
136
214
|
const handleClose = React.useCallback(() => {
|
|
137
215
|
if (onClose) {
|
|
@@ -173,38 +251,32 @@ export const Dialog = forwardRef<any, DialogProps>(
|
|
|
173
251
|
<ModalPrimitive.Overlay
|
|
174
252
|
dismissible={dismissible}
|
|
175
253
|
onDismiss={handleClose}
|
|
176
|
-
style={
|
|
254
|
+
style={styles.overlay}
|
|
177
255
|
>
|
|
178
256
|
<ModalPrimitive.Content
|
|
179
|
-
position={position || "
|
|
257
|
+
position={position || "center"}
|
|
180
258
|
size={size || "md"}
|
|
181
|
-
style={
|
|
259
|
+
style={[
|
|
260
|
+
styles.content,
|
|
261
|
+
variant === "sheet" && styles.sheetContent,
|
|
262
|
+
variant === "fullscreen" && styles.fullscreenContent,
|
|
263
|
+
size === "sm" && styles.smContent,
|
|
264
|
+
size === "md" && styles.mdContent,
|
|
265
|
+
size === "lg" && styles.lgContent,
|
|
266
|
+
size === "xl" && styles.xlContent,
|
|
267
|
+
size === "full" && styles.fullContent,
|
|
268
|
+
]}
|
|
182
269
|
>
|
|
183
270
|
{(title || showCloseButton) && (
|
|
184
271
|
<ModalPrimitive.Header
|
|
185
272
|
withBorder={variant !== "sheet"}
|
|
186
|
-
style={
|
|
187
|
-
zero.p[4],
|
|
188
|
-
{
|
|
189
|
-
flexDirection: "row",
|
|
190
|
-
alignItems: "center",
|
|
191
|
-
justifyContent: "space-between",
|
|
192
|
-
},
|
|
193
|
-
]}
|
|
273
|
+
style={styles.header}
|
|
194
274
|
>
|
|
195
275
|
<DialogTitle>{title}</DialogTitle>
|
|
196
276
|
{showCloseButton && (
|
|
197
277
|
<ModalPrimitive.Close
|
|
198
278
|
onClose={handleClose}
|
|
199
|
-
style={
|
|
200
|
-
zero.p[2],
|
|
201
|
-
{
|
|
202
|
-
width: 44,
|
|
203
|
-
height: 44,
|
|
204
|
-
alignItems: "center",
|
|
205
|
-
justifyContent: "center",
|
|
206
|
-
},
|
|
207
|
-
]}
|
|
279
|
+
style={styles.closeButton}
|
|
208
280
|
>
|
|
209
281
|
<DialogCloseIcon />
|
|
210
282
|
</ModalPrimitive.Close>
|
|
@@ -214,7 +286,7 @@ export const Dialog = forwardRef<any, DialogProps>(
|
|
|
214
286
|
|
|
215
287
|
<ModalPrimitive.Body
|
|
216
288
|
scrollable={variant !== "fullscreen"}
|
|
217
|
-
style={
|
|
289
|
+
style={styles.body}
|
|
218
290
|
>
|
|
219
291
|
{description && (
|
|
220
292
|
<DialogDescription>{description}</DialogDescription>
|
|
@@ -230,6 +302,43 @@ export const Dialog = forwardRef<any, DialogProps>(
|
|
|
230
302
|
|
|
231
303
|
Dialog.displayName = "Dialog";
|
|
232
304
|
|
|
305
|
+
/// Responsive Dialog Component. On mobile this will render a *bottom sheet*.
|
|
306
|
+
/// Prefer this over the regular Dialog component for better mobile UX.
|
|
307
|
+
export const ResponsiveDialog = forwardRef<any, DialogProps>(
|
|
308
|
+
({ children, size, ...props }, ref) => {
|
|
309
|
+
const { width } = useWindowDimensions();
|
|
310
|
+
|
|
311
|
+
// On web, you might want to always use the normal dialog
|
|
312
|
+
// On mobile (width < 800), use the bottom sheet
|
|
313
|
+
const isBottomSheet = Platform.OS !== "web" && width < 800;
|
|
314
|
+
|
|
315
|
+
if (isBottomSheet) {
|
|
316
|
+
return (
|
|
317
|
+
<DialogBottomSheet
|
|
318
|
+
ref={ref}
|
|
319
|
+
{...props}
|
|
320
|
+
size={"full"}
|
|
321
|
+
showCloseButton={false}
|
|
322
|
+
variant="fullscreen"
|
|
323
|
+
>
|
|
324
|
+
{children}
|
|
325
|
+
</DialogBottomSheet>
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Use larger default size for regular dialogs to give more room
|
|
330
|
+
const dialogSize = size || "lg";
|
|
331
|
+
|
|
332
|
+
return (
|
|
333
|
+
<Dialog ref={ref} size={dialogSize} {...props}>
|
|
334
|
+
{children}
|
|
335
|
+
</Dialog>
|
|
336
|
+
);
|
|
337
|
+
},
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
ResponsiveDialog.displayName = "ResponsiveDialog";
|
|
341
|
+
|
|
233
342
|
// Dialog Title component
|
|
234
343
|
export interface DialogTitleProps {
|
|
235
344
|
children?: React.ReactNode;
|
|
@@ -238,16 +347,13 @@ export interface DialogTitleProps {
|
|
|
238
347
|
|
|
239
348
|
export const DialogTitle = forwardRef<any, DialogTitleProps>(
|
|
240
349
|
({ children, style, ...props }, ref) => {
|
|
241
|
-
const {
|
|
350
|
+
const { theme } = useTheme();
|
|
351
|
+
const styles = React.useMemo(() => createStyles(theme), [theme]);
|
|
242
352
|
|
|
243
353
|
if (!children) return null;
|
|
244
354
|
|
|
245
355
|
return (
|
|
246
|
-
<Text
|
|
247
|
-
ref={ref}
|
|
248
|
-
style={[zt.text.xl, { fontWeight: "600", flex: 1 }, style]}
|
|
249
|
-
{...props}
|
|
250
|
-
>
|
|
356
|
+
<Text ref={ref} style={[styles.title, style]} {...props}>
|
|
251
357
|
{children}
|
|
252
358
|
</Text>
|
|
253
359
|
);
|
|
@@ -264,12 +370,13 @@ export interface DialogDescriptionProps {
|
|
|
264
370
|
|
|
265
371
|
export const DialogDescription = forwardRef<any, DialogDescriptionProps>(
|
|
266
372
|
({ children, style, ...props }, ref) => {
|
|
267
|
-
const {
|
|
373
|
+
const { theme } = useTheme();
|
|
374
|
+
const styles = React.useMemo(() => createStyles(theme), [theme]);
|
|
268
375
|
|
|
269
376
|
if (!children) return null;
|
|
270
377
|
|
|
271
378
|
return (
|
|
272
|
-
<Text ref={ref} style={[
|
|
379
|
+
<Text ref={ref} style={[styles.description, style]} {...props}>
|
|
273
380
|
{children}
|
|
274
381
|
</Text>
|
|
275
382
|
);
|
|
@@ -304,7 +411,8 @@ export const DialogFooter = forwardRef<any, DialogFooterProps>(
|
|
|
304
411
|
},
|
|
305
412
|
ref,
|
|
306
413
|
) => {
|
|
307
|
-
const {
|
|
414
|
+
const { theme } = useTheme();
|
|
415
|
+
const styles = React.useMemo(() => createStyles(theme), [theme]);
|
|
308
416
|
|
|
309
417
|
if (!children) return null;
|
|
310
418
|
|
|
@@ -314,7 +422,7 @@ export const DialogFooter = forwardRef<any, DialogFooterProps>(
|
|
|
314
422
|
withBorder={withBorder}
|
|
315
423
|
direction={direction}
|
|
316
424
|
justify={justify}
|
|
317
|
-
style={[
|
|
425
|
+
style={[styles.footer, style]}
|
|
318
426
|
{...props}
|
|
319
427
|
>
|
|
320
428
|
{children}
|
|
@@ -330,5 +438,117 @@ const DialogCloseIcon = () => {
|
|
|
330
438
|
return <ThemedX size="md" variant="default" />;
|
|
331
439
|
};
|
|
332
440
|
|
|
441
|
+
// Create theme-aware styles
|
|
442
|
+
function createStyles(theme: any) {
|
|
443
|
+
return StyleSheet.create({
|
|
444
|
+
overlay: {
|
|
445
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
446
|
+
},
|
|
447
|
+
|
|
448
|
+
content: {
|
|
449
|
+
backgroundColor: theme.colors.card,
|
|
450
|
+
borderRadius: theme.borderRadius.lg,
|
|
451
|
+
...theme.shadows.lg,
|
|
452
|
+
maxHeight: "90%",
|
|
453
|
+
maxWidth: "90%",
|
|
454
|
+
},
|
|
455
|
+
|
|
456
|
+
// Variant styles
|
|
457
|
+
sheetContent: {
|
|
458
|
+
borderTopLeftRadius: theme.borderRadius.xl,
|
|
459
|
+
borderTopRightRadius: theme.borderRadius.xl,
|
|
460
|
+
borderBottomLeftRadius: 0,
|
|
461
|
+
borderBottomRightRadius: 0,
|
|
462
|
+
marginTop: "auto",
|
|
463
|
+
marginBottom: 0,
|
|
464
|
+
maxHeight: "80%",
|
|
465
|
+
width: "100%",
|
|
466
|
+
maxWidth: "100%",
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
fullscreenContent: {
|
|
470
|
+
width: "100%",
|
|
471
|
+
height: "100%",
|
|
472
|
+
maxWidth: "100%",
|
|
473
|
+
maxHeight: "100%",
|
|
474
|
+
borderRadius: 0,
|
|
475
|
+
margin: 0,
|
|
476
|
+
},
|
|
477
|
+
|
|
478
|
+
// Size styles
|
|
479
|
+
smContent: {
|
|
480
|
+
minWidth: 300,
|
|
481
|
+
minHeight: 200,
|
|
482
|
+
},
|
|
483
|
+
|
|
484
|
+
mdContent: {
|
|
485
|
+
minWidth: 400,
|
|
486
|
+
minHeight: 300,
|
|
487
|
+
},
|
|
488
|
+
|
|
489
|
+
lgContent: {
|
|
490
|
+
minWidth: 500,
|
|
491
|
+
minHeight: 400,
|
|
492
|
+
},
|
|
493
|
+
|
|
494
|
+
xlContent: {
|
|
495
|
+
minWidth: 600,
|
|
496
|
+
minHeight: 500,
|
|
497
|
+
},
|
|
498
|
+
|
|
499
|
+
fullContent: {
|
|
500
|
+
width: "95%",
|
|
501
|
+
height: "95%",
|
|
502
|
+
maxWidth: "95%",
|
|
503
|
+
maxHeight: "95%",
|
|
504
|
+
},
|
|
505
|
+
|
|
506
|
+
header: {
|
|
507
|
+
paddingHorizontal: theme.spacing[6],
|
|
508
|
+
paddingVertical: theme.spacing[4],
|
|
509
|
+
flexDirection: "row",
|
|
510
|
+
alignItems: "center",
|
|
511
|
+
justifyContent: "space-between",
|
|
512
|
+
},
|
|
513
|
+
|
|
514
|
+
body: {
|
|
515
|
+
paddingHorizontal: theme.spacing[6],
|
|
516
|
+
paddingBottom: theme.spacing[6],
|
|
517
|
+
flex: 1,
|
|
518
|
+
},
|
|
519
|
+
|
|
520
|
+
footer: {
|
|
521
|
+
paddingHorizontal: theme.spacing[6],
|
|
522
|
+
paddingVertical: theme.spacing[4],
|
|
523
|
+
gap: theme.spacing[2],
|
|
524
|
+
width: "100%",
|
|
525
|
+
},
|
|
526
|
+
|
|
527
|
+
title: {
|
|
528
|
+
fontSize: 20,
|
|
529
|
+
fontWeight: "600",
|
|
530
|
+
color: theme.colors.text,
|
|
531
|
+
flex: 1,
|
|
532
|
+
lineHeight: 24,
|
|
533
|
+
},
|
|
534
|
+
|
|
535
|
+
description: {
|
|
536
|
+
fontSize: 16,
|
|
537
|
+
color: theme.colors.textMuted,
|
|
538
|
+
lineHeight: 22,
|
|
539
|
+
marginVertical: theme.spacing[4],
|
|
540
|
+
},
|
|
541
|
+
|
|
542
|
+
closeButton: {
|
|
543
|
+
width: theme.touchTargets.minimum,
|
|
544
|
+
height: theme.touchTargets.minimum,
|
|
545
|
+
alignItems: "center",
|
|
546
|
+
justifyContent: "center",
|
|
547
|
+
borderRadius: theme.borderRadius.sm,
|
|
548
|
+
marginLeft: theme.spacing[2],
|
|
549
|
+
},
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
|
|
333
553
|
// Export dialog variants for external use
|
|
334
554
|
export { dialogVariants };
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
Platform,
|
|
14
14
|
Pressable,
|
|
15
15
|
StyleSheet,
|
|
16
|
-
Text,
|
|
17
16
|
useWindowDimensions,
|
|
18
17
|
View,
|
|
19
18
|
} from "react-native";
|
|
@@ -39,6 +38,7 @@ import {
|
|
|
39
38
|
objectFromObjects,
|
|
40
39
|
TextContext as TextClassContext,
|
|
41
40
|
} from "./primitives/text";
|
|
41
|
+
import { Text } from "./text";
|
|
42
42
|
|
|
43
43
|
export const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
44
44
|
export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
@@ -87,7 +87,7 @@ export const DropdownMenuBottomSheet = forwardRef<
|
|
|
87
87
|
zt.bg.mutedForeground,
|
|
88
88
|
]}
|
|
89
89
|
>
|
|
90
|
-
<BottomSheetView style={[px[
|
|
90
|
+
<BottomSheetView style={[px[4]]}>
|
|
91
91
|
{typeof children === "function"
|
|
92
92
|
? children({ pressed: true })
|
|
93
93
|
: children}
|
|
@@ -285,9 +285,15 @@ export const DropdownMenuItem = forwardRef<
|
|
|
285
285
|
pr[2],
|
|
286
286
|
]}
|
|
287
287
|
>
|
|
288
|
-
{typeof children === "function"
|
|
289
|
-
|
|
290
|
-
|
|
288
|
+
{typeof children === "function" ? (
|
|
289
|
+
children({ pressed: true })
|
|
290
|
+
) : typeof children === "string" ? (
|
|
291
|
+
<Text style={[inset && gap[2], disabled && { opacity: 0.5 }]}>
|
|
292
|
+
{children}
|
|
293
|
+
</Text>
|
|
294
|
+
) : (
|
|
295
|
+
children
|
|
296
|
+
)}
|
|
291
297
|
</View>
|
|
292
298
|
</TextClassContext.Provider>
|
|
293
299
|
</Pressable>
|
|
@@ -384,13 +390,15 @@ export const DropdownMenuLabel = forwardRef<
|
|
|
384
390
|
return (
|
|
385
391
|
<Text
|
|
386
392
|
ref={ref}
|
|
387
|
-
style={
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
393
|
+
style={
|
|
394
|
+
[
|
|
395
|
+
px[2],
|
|
396
|
+
py[2],
|
|
397
|
+
{ color: theme.colors.textMuted },
|
|
398
|
+
a.fontSize.base,
|
|
399
|
+
(inset && gap[2]) as any,
|
|
400
|
+
] as any
|
|
401
|
+
}
|
|
394
402
|
{...props}
|
|
395
403
|
/>
|
|
396
404
|
);
|
|
@@ -404,7 +412,13 @@ export const DropdownMenuSeparator = forwardRef<
|
|
|
404
412
|
return (
|
|
405
413
|
<View
|
|
406
414
|
ref={ref}
|
|
407
|
-
style={[
|
|
415
|
+
style={[
|
|
416
|
+
{
|
|
417
|
+
borderBottomWidth: 1,
|
|
418
|
+
borderBottomColor: theme.colors.border,
|
|
419
|
+
marginVertical: -0.5,
|
|
420
|
+
},
|
|
421
|
+
]}
|
|
408
422
|
{...props}
|
|
409
423
|
/>
|
|
410
424
|
);
|
|
@@ -48,3 +48,17 @@ export function createThemedIcon(
|
|
|
48
48
|
);
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
// usage of createThemedIcon
|
|
53
|
+
export function Icon({
|
|
54
|
+
icon,
|
|
55
|
+
variant = "default",
|
|
56
|
+
size = "md",
|
|
57
|
+
color,
|
|
58
|
+
...restProps
|
|
59
|
+
}: { icon: React.ComponentType<LucideProps> } & IconProps) {
|
|
60
|
+
const ThemedIcon = createThemedIcon(icon);
|
|
61
|
+
return (
|
|
62
|
+
<ThemedIcon variant={variant} size={size} color={color} {...restProps} />
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -244,7 +244,6 @@ const primitiveStyles = StyleSheet.create({
|
|
|
244
244
|
flexDirection: "row",
|
|
245
245
|
alignItems: "center",
|
|
246
246
|
justifyContent: "center",
|
|
247
|
-
minHeight: 44, // iOS minimum touch target
|
|
248
247
|
},
|
|
249
248
|
disabled: {
|
|
250
249
|
opacity: 0.5,
|
|
@@ -264,12 +263,6 @@ const primitiveStyles = StyleSheet.create({
|
|
|
264
263
|
alignItems: "center",
|
|
265
264
|
justifyContent: "center",
|
|
266
265
|
},
|
|
267
|
-
iconLeft: {
|
|
268
|
-
marginRight: 8,
|
|
269
|
-
},
|
|
270
|
-
iconRight: {
|
|
271
|
-
marginLeft: 8,
|
|
272
|
-
},
|
|
273
266
|
iconDisabled: {
|
|
274
267
|
opacity: 0.5,
|
|
275
268
|
},
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BottomSheetTextInput,
|
|
3
|
+
useBottomSheetInternal,
|
|
4
|
+
} from "@gorhom/bottom-sheet";
|
|
1
5
|
import React, { forwardRef } from "react";
|
|
2
6
|
import {
|
|
3
7
|
NativeSyntheticEvent,
|
|
@@ -24,7 +28,7 @@ export interface InputPrimitiveProps extends Omit<TextInputProps, "onChange"> {
|
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
// Input root primitive - the main TextInput component
|
|
27
|
-
export const InputRoot = forwardRef<
|
|
31
|
+
export const InputRoot = forwardRef<any, InputPrimitiveProps>(
|
|
28
32
|
(
|
|
29
33
|
{
|
|
30
34
|
value,
|
|
@@ -44,6 +48,19 @@ export const InputRoot = forwardRef<TextInput, InputPrimitiveProps>(
|
|
|
44
48
|
) => {
|
|
45
49
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
46
50
|
|
|
51
|
+
let isInBottomSheet = false;
|
|
52
|
+
try {
|
|
53
|
+
useBottomSheetInternal();
|
|
54
|
+
isInBottomSheet = true;
|
|
55
|
+
} catch {
|
|
56
|
+
isInBottomSheet = false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const InputComponent =
|
|
60
|
+
isInBottomSheet && Platform.OS !== "web"
|
|
61
|
+
? BottomSheetTextInput
|
|
62
|
+
: TextInput;
|
|
63
|
+
|
|
47
64
|
const handleChangeText = React.useCallback(
|
|
48
65
|
(text: string) => {
|
|
49
66
|
if (onChangeText) {
|
|
@@ -77,7 +94,7 @@ export const InputRoot = forwardRef<TextInput, InputPrimitiveProps>(
|
|
|
77
94
|
);
|
|
78
95
|
|
|
79
96
|
return (
|
|
80
|
-
<
|
|
97
|
+
<InputComponent
|
|
81
98
|
ref={ref}
|
|
82
99
|
value={value}
|
|
83
100
|
onChangeText={handleChangeText}
|
|
@@ -32,8 +32,9 @@ export const ModalRoot = forwardRef<View, ModalPrimitiveProps>(
|
|
|
32
32
|
children,
|
|
33
33
|
onRequestClose,
|
|
34
34
|
animationType = "fade",
|
|
35
|
-
presentationStyle = Platform.OS === "ios" ? "pageSheet" : "
|
|
36
|
-
statusBarTranslucent = Platform.OS
|
|
35
|
+
presentationStyle = Platform.OS === "ios" ? "pageSheet" : "formSheet",
|
|
36
|
+
statusBarTranslucent = Platform.OS !== "ios",
|
|
37
|
+
transparent = true,
|
|
37
38
|
...props
|
|
38
39
|
},
|
|
39
40
|
ref,
|
|
@@ -57,6 +58,7 @@ export const ModalRoot = forwardRef<View, ModalPrimitiveProps>(
|
|
|
57
58
|
animationType={animationType}
|
|
58
59
|
presentationStyle={presentationStyle}
|
|
59
60
|
statusBarTranslucent={statusBarTranslucent}
|
|
61
|
+
transparent={transparent}
|
|
60
62
|
{...props}
|
|
61
63
|
>
|
|
62
64
|
<View ref={ref} style={primitiveStyles.container}>
|