@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.
Files changed (64) hide show
  1. package/dist/components/content-metadata/content-metadata-form.js +404 -0
  2. package/dist/components/content-metadata/content-rights.js +78 -0
  3. package/dist/components/content-metadata/content-warnings.js +68 -0
  4. package/dist/components/content-metadata/index.js +11 -0
  5. package/dist/components/dashboard/header.js +16 -2
  6. package/dist/components/dashboard/problems.js +29 -28
  7. package/dist/components/mobile-player/player.js +4 -0
  8. package/dist/components/mobile-player/ui/report-modal.js +3 -2
  9. package/dist/components/mobile-player/ui/viewer-context-menu.js +44 -1
  10. package/dist/components/ui/button.js +9 -9
  11. package/dist/components/ui/checkbox.js +87 -0
  12. package/dist/components/ui/dialog.js +188 -83
  13. package/dist/components/ui/dropdown.js +15 -10
  14. package/dist/components/ui/icons.js +6 -0
  15. package/dist/components/ui/primitives/button.js +0 -7
  16. package/dist/components/ui/primitives/input.js +13 -1
  17. package/dist/components/ui/primitives/modal.js +2 -2
  18. package/dist/components/ui/select.js +89 -0
  19. package/dist/components/ui/textarea.js +23 -4
  20. package/dist/components/ui/toast.js +464 -114
  21. package/dist/components/ui/tooltip.js +103 -0
  22. package/dist/index.js +2 -0
  23. package/dist/lib/metadata-constants.js +157 -0
  24. package/dist/lib/theme/theme.js +5 -3
  25. package/dist/lib/theme/tokens.js +9 -0
  26. package/dist/streamplace-provider/index.js +14 -4
  27. package/dist/streamplace-store/content-metadata-actions.js +118 -0
  28. package/dist/streamplace-store/graph.js +195 -0
  29. package/dist/streamplace-store/streamplace-store.js +18 -5
  30. package/dist/streamplace-store/user.js +67 -7
  31. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
  32. package/package.json +3 -3
  33. package/src/components/content-metadata/content-metadata-form.tsx +761 -0
  34. package/src/components/content-metadata/content-rights.tsx +104 -0
  35. package/src/components/content-metadata/content-warnings.tsx +100 -0
  36. package/src/components/content-metadata/index.tsx +18 -0
  37. package/src/components/dashboard/header.tsx +37 -3
  38. package/src/components/dashboard/index.tsx +1 -1
  39. package/src/components/dashboard/problems.tsx +57 -46
  40. package/src/components/mobile-player/player.tsx +5 -0
  41. package/src/components/mobile-player/ui/report-modal.tsx +13 -7
  42. package/src/components/mobile-player/ui/viewer-context-menu.tsx +100 -1
  43. package/src/components/ui/button.tsx +10 -13
  44. package/src/components/ui/checkbox.tsx +147 -0
  45. package/src/components/ui/dialog.tsx +319 -99
  46. package/src/components/ui/dropdown.tsx +27 -13
  47. package/src/components/ui/icons.tsx +14 -0
  48. package/src/components/ui/primitives/button.tsx +0 -7
  49. package/src/components/ui/primitives/input.tsx +19 -2
  50. package/src/components/ui/primitives/modal.tsx +4 -2
  51. package/src/components/ui/select.tsx +175 -0
  52. package/src/components/ui/textarea.tsx +47 -29
  53. package/src/components/ui/toast.tsx +785 -179
  54. package/src/components/ui/tooltip.tsx +131 -0
  55. package/src/index.tsx +3 -0
  56. package/src/lib/metadata-constants.ts +180 -0
  57. package/src/lib/theme/theme.tsx +10 -6
  58. package/src/lib/theme/tokens.ts +9 -0
  59. package/src/streamplace-provider/index.tsx +20 -2
  60. package/src/streamplace-store/content-metadata-actions.tsx +142 -0
  61. package/src/streamplace-store/graph.tsx +232 -0
  62. package/src/streamplace-store/streamplace-store.tsx +30 -4
  63. package/src/streamplace-store/user.tsx +71 -7
  64. package/tsconfig.tsbuildinfo +1 -1
@@ -1,16 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.dialogVariants = exports.DialogFooter = exports.DialogDescription = exports.DialogTitle = exports.Dialog = void 0;
3
+ exports.dialogVariants = exports.DialogFooter = exports.DialogDescription = exports.DialogTitle = exports.ResponsiveDialog = exports.Dialog = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const bottom_sheet_1 = tslib_1.__importStar(require("@gorhom/bottom-sheet"));
7
+ // to get the portal
8
+ const Portal = tslib_1.__importStar(require("@rn-primitives/portal"));
6
9
  const class_variance_authority_1 = require("class-variance-authority");
7
10
  const lucide_react_native_1 = require("lucide-react-native");
8
11
  const react_1 = tslib_1.__importStar(require("react"));
9
12
  const react_native_1 = require("react-native");
13
+ const react_native_safe_area_context_1 = require("react-native-safe-area-context");
10
14
  const theme_1 = require("../../lib/theme/theme");
11
- const zero = tslib_1.__importStar(require("../../ui"));
12
15
  const icons_1 = require("./icons");
13
16
  const modal_1 = require("./primitives/modal");
17
+ const text_1 = require("./text");
14
18
  const ThemedX = (0, icons_1.createThemedIcon)(lucide_react_native_1.X);
15
19
  // Dialog variants using class-variance-authority pattern
16
20
  const dialogVariants = (0, class_variance_authority_1.cva)("", {
@@ -42,67 +46,59 @@ const dialogVariants = (0, class_variance_authority_1.cva)("", {
42
46
  },
43
47
  });
44
48
  exports.dialogVariants = dialogVariants;
45
- exports.Dialog = (0, react_1.forwardRef)(({ variant = "left", size = "md", position = "center", children, title, description, dismissible = true, showCloseButton = true, onClose, open = false, onOpenChange, ...props }, ref) => {
46
- const { zero: zt, theme } = (0, theme_1.useTheme)();
47
- // Content styles using theme.zero
48
- const contentStyles = react_1.default.useMemo(() => {
49
- const baseStyle = [
50
- zt.bg.card,
51
- zero.r.lg,
52
- zero.shadows.lg,
53
- { maxHeight: "90%", maxWidth: "90%" },
54
- ];
55
- const variantStyle = (() => {
56
- switch (variant) {
57
- case "sheet":
58
- return [
59
- { borderRadius: zero.borderRadius.xl },
60
- {
61
- borderBottomLeftRadius: 0,
62
- borderBottomRightRadius: 0,
63
- marginTop: "auto",
64
- marginBottom: 0,
65
- maxHeight: "80%",
49
+ // Bottom Sheet Dialog Component
50
+ const DialogBottomSheet = (0, react_1.forwardRef)(function DialogBottomSheet({ overlayStyle, portalHost, children, title, description, showCloseButton = true, onClose, open = false, onOpenChange, ...props }, _ref) {
51
+ const { theme } = (0, theme_1.useTheme)();
52
+ const sheetRef = (0, react_1.useRef)(null);
53
+ const { top } = (0, react_native_safe_area_context_1.useSafeAreaInsets)();
54
+ const dims = (0, react_native_1.useWindowDimensions)();
55
+ const handleClose = react_1.default.useCallback(() => {
56
+ if (onClose) {
57
+ onClose();
58
+ }
59
+ if (onOpenChange) {
60
+ onOpenChange(false);
61
+ }
62
+ }, [onClose, onOpenChange]);
63
+ if (!open) {
64
+ return null;
65
+ }
66
+ return ((0, jsx_runtime_1.jsx)(Portal.Portal, { name: "dialog", children: (0, jsx_runtime_1.jsx)(bottom_sheet_1.default, { ref: sheetRef, index: open ? 0 : -1, enablePanDownToClose: true, enableDynamicSizing: true, maxDynamicContentSize: dims.height - top, keyboardBehavior: "interactive", keyboardBlurBehavior: "restore", enableContentPanningGesture: false, backdropComponent: ({ style }) => ((0, jsx_runtime_1.jsx)(react_native_1.Pressable, { style: [style, react_native_1.StyleSheet.absoluteFill], onPress: handleClose })), onClose: handleClose, style: [overlayStyle], backgroundStyle: {
67
+ backgroundColor: theme.colors.card,
68
+ borderRadius: theme.borderRadius.lg,
69
+ ...theme.shadows.lg,
70
+ }, handleIndicatorStyle: {
71
+ width: 48,
72
+ height: 4,
73
+ backgroundColor: theme.colors.textMuted,
74
+ }, children: (0, jsx_runtime_1.jsxs)(bottom_sheet_1.BottomSheetScrollView, { style: {
75
+ flex: 1,
76
+ width: "100%",
77
+ }, contentContainerStyle: { flexGrow: 1 }, children: [(title || showCloseButton) && ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: {
78
+ paddingHorizontal: theme.spacing[4],
79
+ paddingVertical: theme.spacing[4],
80
+ flexDirection: "row",
81
+ alignItems: "center",
82
+ justifyContent: "space-between",
66
83
  width: "100%",
67
- maxWidth: "100%",
68
- },
69
- ];
70
- case "fullscreen":
71
- return [
72
- {
84
+ }, children: [title && (0, jsx_runtime_1.jsx)(exports.DialogTitle, { children: title }), showCloseButton && ((0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: handleClose, style: {
85
+ width: theme.touchTargets.minimum,
86
+ height: theme.touchTargets.minimum,
87
+ alignItems: "center",
88
+ justifyContent: "center",
89
+ borderRadius: theme.borderRadius.sm,
90
+ marginLeft: theme.spacing[2],
91
+ }, children: (0, jsx_runtime_1.jsx)(DialogCloseIcon, {}) }))] })), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: {
92
+ paddingHorizontal: theme.spacing[4],
93
+ paddingBottom: theme.spacing[6],
94
+ flex: 1,
73
95
  width: "100%",
74
- height: "100%",
75
- maxWidth: "100%",
76
- maxHeight: "100%",
77
- borderRadius: 0,
78
- margin: 0,
79
- },
80
- ];
81
- default:
82
- return [];
83
- }
84
- })();
85
- const sizeStyle = (() => {
86
- switch (size) {
87
- case "sm":
88
- return { minWidth: 300, minHeight: 200 };
89
- case "lg":
90
- return { minWidth: 500, minHeight: 400 };
91
- case "xl":
92
- return { minWidth: 600, minHeight: 500 };
93
- case "full":
94
- return {
95
- width: "95%",
96
- height: "95%",
97
- maxWidth: "95%",
98
- maxHeight: "95%",
99
- };
100
- default:
101
- return { minWidth: 400, minHeight: 300 };
102
- }
103
- })();
104
- return [baseStyle, variantStyle, sizeStyle].flat();
105
- }, [variant, size, zero]);
96
+ }, children: [description && ((0, jsx_runtime_1.jsx)(exports.DialogDescription, { children: description })), children] })] }) }) }));
97
+ });
98
+ exports.Dialog = (0, react_1.forwardRef)(({ variant = "default", size = "md", position = "center", children, title, description, dismissible = true, showCloseButton = true, onClose, open = false, onOpenChange, ...props }, ref) => {
99
+ const { theme } = (0, theme_1.useTheme)();
100
+ // Create dynamic styles based on theme
101
+ const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
106
102
  const handleClose = react_1.default.useCallback(() => {
107
103
  if (onClose) {
108
104
  onClose();
@@ -128,46 +124,155 @@ exports.Dialog = (0, react_1.forwardRef)(({ variant = "left", size = "md", posit
128
124
  }
129
125
  return "fade";
130
126
  }, [variant]);
131
- return ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Root, { ref: ref, open: open, onOpenChange: onOpenChange, presentationStyle: presentationStyle, animationType: animationType, ...props, children: (0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Overlay, { dismissible: dismissible, onDismiss: handleClose, style: zt.bg.overlay, children: (0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Content, { position: position || "left", size: size || "md", style: contentStyles, children: [(title || showCloseButton) && ((0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Header, { withBorder: variant !== "sheet", style: [
132
- zero.p[4],
133
- {
134
- flexDirection: "row",
135
- alignItems: "center",
136
- justifyContent: "space-between",
137
- },
138
- ], children: [(0, jsx_runtime_1.jsx)(exports.DialogTitle, { children: title }), showCloseButton && ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Close, { onClose: handleClose, style: [
139
- zero.p[2],
140
- {
141
- width: 44,
142
- height: 44,
143
- alignItems: "center",
144
- justifyContent: "center",
145
- },
146
- ], children: (0, jsx_runtime_1.jsx)(DialogCloseIcon, {}) }))] })), (0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Body, { scrollable: variant !== "fullscreen", style: [zero.p[6], { paddingTop: 0, flex: 1 }], children: [description && ((0, jsx_runtime_1.jsx)(exports.DialogDescription, { children: description })), children] })] }) }) }));
127
+ return ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Root, { ref: ref, open: open, onOpenChange: onOpenChange, presentationStyle: presentationStyle, animationType: animationType, ...props, children: (0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Overlay, { dismissible: dismissible, onDismiss: handleClose, style: styles.overlay, children: (0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Content, { position: position || "center", size: size || "md", style: [
128
+ styles.content,
129
+ variant === "sheet" && styles.sheetContent,
130
+ variant === "fullscreen" && styles.fullscreenContent,
131
+ size === "sm" && styles.smContent,
132
+ size === "md" && styles.mdContent,
133
+ size === "lg" && styles.lgContent,
134
+ size === "xl" && styles.xlContent,
135
+ size === "full" && styles.fullContent,
136
+ ], children: [(title || showCloseButton) && ((0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Header, { withBorder: variant !== "sheet", style: styles.header, children: [(0, jsx_runtime_1.jsx)(exports.DialogTitle, { children: title }), showCloseButton && ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Close, { onClose: handleClose, style: styles.closeButton, children: (0, jsx_runtime_1.jsx)(DialogCloseIcon, {}) }))] })), (0, jsx_runtime_1.jsxs)(modal_1.ModalPrimitive.Body, { scrollable: variant !== "fullscreen", style: styles.body, children: [description && ((0, jsx_runtime_1.jsx)(exports.DialogDescription, { children: description })), children] })] }) }) }));
147
137
  });
148
138
  exports.Dialog.displayName = "Dialog";
139
+ /// Responsive Dialog Component. On mobile this will render a *bottom sheet*.
140
+ /// Prefer this over the regular Dialog component for better mobile UX.
141
+ exports.ResponsiveDialog = (0, react_1.forwardRef)(({ children, size, ...props }, ref) => {
142
+ const { width } = (0, react_native_1.useWindowDimensions)();
143
+ // On web, you might want to always use the normal dialog
144
+ // On mobile (width < 800), use the bottom sheet
145
+ const isBottomSheet = react_native_1.Platform.OS !== "web" && width < 800;
146
+ if (isBottomSheet) {
147
+ return ((0, jsx_runtime_1.jsx)(DialogBottomSheet, { ref: ref, ...props, size: "full", showCloseButton: false, variant: "fullscreen", children: children }));
148
+ }
149
+ // Use larger default size for regular dialogs to give more room
150
+ const dialogSize = size || "lg";
151
+ return ((0, jsx_runtime_1.jsx)(exports.Dialog, { ref: ref, size: dialogSize, ...props, children: children }));
152
+ });
153
+ exports.ResponsiveDialog.displayName = "ResponsiveDialog";
149
154
  exports.DialogTitle = (0, react_1.forwardRef)(({ children, style, ...props }, ref) => {
150
- const { zero: zt } = (0, theme_1.useTheme)();
155
+ const { theme } = (0, theme_1.useTheme)();
156
+ const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
151
157
  if (!children)
152
158
  return null;
153
- return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { ref: ref, style: [zt.text.xl, { fontWeight: "600", flex: 1 }, style], ...props, children: children }));
159
+ return ((0, jsx_runtime_1.jsx)(text_1.Text, { ref: ref, style: [styles.title, style], ...props, children: children }));
154
160
  });
155
161
  exports.DialogTitle.displayName = "DialogTitle";
156
162
  exports.DialogDescription = (0, react_1.forwardRef)(({ children, style, ...props }, ref) => {
157
- const { zero: zt } = (0, theme_1.useTheme)();
163
+ const { theme } = (0, theme_1.useTheme)();
164
+ const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
158
165
  if (!children)
159
166
  return null;
160
- return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { ref: ref, style: [zt.text.muted, zero.mb[4], style], ...props, children: children }));
167
+ return ((0, jsx_runtime_1.jsx)(text_1.Text, { ref: ref, style: [styles.description, style], ...props, children: children }));
161
168
  });
162
169
  exports.DialogDescription.displayName = "DialogDescription";
163
170
  exports.DialogFooter = (0, react_1.forwardRef)(({ children, direction = "row", justify = "flex-end", withBorder = true, style, ...props }, ref) => {
164
- const { zero: zt } = (0, theme_1.useTheme)();
171
+ const { theme } = (0, theme_1.useTheme)();
172
+ const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
165
173
  if (!children)
166
174
  return null;
167
- return ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Footer, { ref: ref, withBorder: withBorder, direction: direction, justify: justify, style: [zero.p[6], { gap: 8 }, style], ...props, children: children }));
175
+ return ((0, jsx_runtime_1.jsx)(modal_1.ModalPrimitive.Footer, { ref: ref, withBorder: withBorder, direction: direction, justify: justify, style: [styles.footer, style], ...props, children: children }));
168
176
  });
169
177
  exports.DialogFooter.displayName = "DialogFooter";
170
178
  // Dialog Close Icon component (Lucide X)
171
179
  const DialogCloseIcon = () => {
172
180
  return (0, jsx_runtime_1.jsx)(ThemedX, { size: "md", variant: "default" });
173
181
  };
182
+ // Create theme-aware styles
183
+ function createStyles(theme) {
184
+ return react_native_1.StyleSheet.create({
185
+ overlay: {
186
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
187
+ },
188
+ content: {
189
+ backgroundColor: theme.colors.card,
190
+ borderRadius: theme.borderRadius.lg,
191
+ ...theme.shadows.lg,
192
+ maxHeight: "90%",
193
+ maxWidth: "90%",
194
+ },
195
+ // Variant styles
196
+ sheetContent: {
197
+ borderTopLeftRadius: theme.borderRadius.xl,
198
+ borderTopRightRadius: theme.borderRadius.xl,
199
+ borderBottomLeftRadius: 0,
200
+ borderBottomRightRadius: 0,
201
+ marginTop: "auto",
202
+ marginBottom: 0,
203
+ maxHeight: "80%",
204
+ width: "100%",
205
+ maxWidth: "100%",
206
+ },
207
+ fullscreenContent: {
208
+ width: "100%",
209
+ height: "100%",
210
+ maxWidth: "100%",
211
+ maxHeight: "100%",
212
+ borderRadius: 0,
213
+ margin: 0,
214
+ },
215
+ // Size styles
216
+ smContent: {
217
+ minWidth: 300,
218
+ minHeight: 200,
219
+ },
220
+ mdContent: {
221
+ minWidth: 400,
222
+ minHeight: 300,
223
+ },
224
+ lgContent: {
225
+ minWidth: 500,
226
+ minHeight: 400,
227
+ },
228
+ xlContent: {
229
+ minWidth: 600,
230
+ minHeight: 500,
231
+ },
232
+ fullContent: {
233
+ width: "95%",
234
+ height: "95%",
235
+ maxWidth: "95%",
236
+ maxHeight: "95%",
237
+ },
238
+ header: {
239
+ paddingHorizontal: theme.spacing[6],
240
+ paddingVertical: theme.spacing[4],
241
+ flexDirection: "row",
242
+ alignItems: "center",
243
+ justifyContent: "space-between",
244
+ },
245
+ body: {
246
+ paddingHorizontal: theme.spacing[6],
247
+ paddingBottom: theme.spacing[6],
248
+ flex: 1,
249
+ },
250
+ footer: {
251
+ paddingHorizontal: theme.spacing[6],
252
+ paddingVertical: theme.spacing[4],
253
+ gap: theme.spacing[2],
254
+ width: "100%",
255
+ },
256
+ title: {
257
+ fontSize: 20,
258
+ fontWeight: "600",
259
+ color: theme.colors.text,
260
+ flex: 1,
261
+ lineHeight: 24,
262
+ },
263
+ description: {
264
+ fontSize: 16,
265
+ color: theme.colors.textMuted,
266
+ lineHeight: 22,
267
+ marginVertical: theme.spacing[4],
268
+ },
269
+ closeButton: {
270
+ width: theme.touchTargets.minimum,
271
+ height: theme.touchTargets.minimum,
272
+ alignItems: "center",
273
+ justifyContent: "center",
274
+ borderRadius: theme.borderRadius.sm,
275
+ marginLeft: theme.spacing[2],
276
+ },
277
+ });
278
+ }
@@ -12,6 +12,7 @@ const react_native_1 = require("react-native");
12
12
  const atoms_1 = require("../../lib/theme/atoms");
13
13
  const ui_1 = require("../../ui");
14
14
  const text_1 = require("./primitives/text");
15
+ const text_2 = require("./text");
15
16
  exports.DropdownMenu = DropdownMenuPrimitive.Root;
16
17
  exports.DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
17
18
  exports.DropdownMenuPortal = DropdownMenuPrimitive.Portal;
@@ -29,7 +30,7 @@ exports.DropdownMenuBottomSheet = (0, react_1.forwardRef)(function DropdownMenuB
29
30
  atoms_1.a.sizes.width[12],
30
31
  atoms_1.a.sizes.height[1],
31
32
  zt.bg.mutedForeground,
32
- ], children: (0, jsx_runtime_1.jsx)(bottom_sheet_1.BottomSheetView, { style: [atoms_1.px[2]], children: typeof children === "function"
33
+ ], children: (0, jsx_runtime_1.jsx)(bottom_sheet_1.BottomSheetView, { style: [atoms_1.px[4]], children: typeof children === "function"
33
34
  ? children({ pressed: true })
34
35
  : children }) }) }));
35
36
  });
@@ -123,9 +124,7 @@ exports.DropdownMenuItem = (0, react_1.forwardRef)(({ inset, disabled, style, ch
123
124
  atoms_1.py[1],
124
125
  atoms_1.pl[2],
125
126
  atoms_1.pr[2],
126
- ], children: typeof children === "function"
127
- ? children({ pressed: true })
128
- : children }) }) }));
127
+ ], children: typeof children === "function" ? (children({ pressed: true })) : typeof children === "string" ? ((0, jsx_runtime_1.jsx)(text_2.Text, { style: [inset && atoms_1.gap[2], disabled && { opacity: 0.5 }], children: children })) : (children) }) }) }));
129
128
  });
130
129
  exports.DropdownMenuCheckboxItem = (0, react_1.forwardRef)(({ children, checked, ...props }, ref) => {
131
130
  const { theme } = (0, ui_1.useTheme)();
@@ -152,21 +151,27 @@ exports.DropdownMenuRadioItem = (0, react_1.forwardRef)(({ children, ...props },
152
151
  });
153
152
  exports.DropdownMenuLabel = (0, react_1.forwardRef)(({ inset, ...props }, ref) => {
154
153
  const { theme } = (0, ui_1.useTheme)();
155
- return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { ref: ref, style: [
154
+ return ((0, jsx_runtime_1.jsx)(text_2.Text, { ref: ref, style: [
156
155
  atoms_1.px[2],
157
156
  atoms_1.py[2],
158
157
  { color: theme.colors.textMuted },
159
158
  atoms_1.a.fontSize.base,
160
- inset && atoms_1.gap[2],
159
+ (inset && atoms_1.gap[2]),
161
160
  ], ...props }));
162
161
  });
163
162
  exports.DropdownMenuSeparator = (0, react_1.forwardRef)((props, ref) => {
164
163
  const { theme } = (0, ui_1.useTheme)();
165
- return ((0, jsx_runtime_1.jsx)(react_native_1.View, { ref: ref, style: [{ height: 0.5 }, { backgroundColor: theme.colors.border }], ...props }));
164
+ return ((0, jsx_runtime_1.jsx)(react_native_1.View, { ref: ref, style: [
165
+ {
166
+ borderBottomWidth: 1,
167
+ borderBottomColor: theme.colors.border,
168
+ marginVertical: -0.5,
169
+ },
170
+ ], ...props }));
166
171
  });
167
172
  function DropdownMenuShortcut(props) {
168
173
  const { theme } = (0, ui_1.useTheme)();
169
- return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
174
+ return ((0, jsx_runtime_1.jsx)(text_2.Text, { style: [
170
175
  atoms_1.ml.auto,
171
176
  { color: theme.colors.textMuted },
172
177
  atoms_1.a.fontSize.sm,
@@ -176,7 +181,7 @@ function DropdownMenuShortcut(props) {
176
181
  exports.DropdownMenuGroup = (0, react_1.forwardRef)((props, ref) => {
177
182
  const { theme } = (0, ui_1.useTheme)();
178
183
  const { inset, title, children, ...rest } = props;
179
- return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [atoms_1.pt[2], inset && atoms_1.gap[2]], ref: ref, ...rest, children: [title && ((0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [{ color: theme.colors.textMuted }, atoms_1.pb[1], atoms_1.pl[2]], children: title })), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
184
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [atoms_1.pt[2], inset && atoms_1.gap[2]], ref: ref, ...rest, children: [title && ((0, jsx_runtime_1.jsx)(text_2.Text, { style: [{ color: theme.colors.textMuted }, atoms_1.pb[1], atoms_1.pl[2]], children: title })), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
180
185
  { backgroundColor: theme.colors.muted },
181
186
  react_native_1.Platform.OS === "web" ? [atoms_1.px[2], atoms_1.py[1]] : atoms_1.p[2],
182
187
  atoms_1.gap.all[1],
@@ -185,7 +190,7 @@ exports.DropdownMenuGroup = (0, react_1.forwardRef)((props, ref) => {
185
190
  });
186
191
  exports.DropdownMenuInfo = (0, react_1.forwardRef)(({ description, ...props }, ref) => {
187
192
  const { theme } = (0, ui_1.useTheme)();
188
- return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [
193
+ return ((0, jsx_runtime_1.jsx)(text_2.Text, { style: [
189
194
  { color: theme.colors.textMuted },
190
195
  atoms_1.pt[1],
191
196
  atoms_1.pl[2],
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createThemedIcon = createThemedIcon;
4
+ exports.Icon = Icon;
4
5
  const jsx_runtime_1 = require("react/jsx-runtime");
5
6
  const theme_1 = require("../../lib/theme");
6
7
  // Size mapping
@@ -23,3 +24,8 @@ function createThemedIcon(IconComponent) {
23
24
  return ((0, jsx_runtime_1.jsx)(IconComponent, { size: iconSize, color: iconColor, ...restProps }));
24
25
  };
25
26
  }
27
+ // usage of createThemedIcon
28
+ function Icon({ icon, variant = "default", size = "md", color, ...restProps }) {
29
+ const ThemedIcon = createThemedIcon(icon);
30
+ return ((0, jsx_runtime_1.jsx)(ThemedIcon, { variant: variant, size: size, color: color, ...restProps }));
31
+ }
@@ -78,7 +78,6 @@ const primitiveStyles = react_native_1.StyleSheet.create({
78
78
  flexDirection: "row",
79
79
  alignItems: "center",
80
80
  justifyContent: "center",
81
- minHeight: 44, // iOS minimum touch target
82
81
  },
83
82
  disabled: {
84
83
  opacity: 0.5,
@@ -98,12 +97,6 @@ const primitiveStyles = react_native_1.StyleSheet.create({
98
97
  alignItems: "center",
99
98
  justifyContent: "center",
100
99
  },
101
- iconLeft: {
102
- marginRight: 8,
103
- },
104
- iconRight: {
105
- marginLeft: 8,
106
- },
107
100
  iconDisabled: {
108
101
  opacity: 0.5,
109
102
  },
@@ -3,11 +3,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InputPrimitive = exports.InputGroup = exports.InputAddon = exports.InputError = exports.InputDescription = exports.InputLabel = exports.InputContainer = exports.InputRoot = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const bottom_sheet_1 = require("@gorhom/bottom-sheet");
6
7
  const react_1 = tslib_1.__importStar(require("react"));
7
8
  const react_native_1 = require("react-native");
8
9
  // Input root primitive - the main TextInput component
9
10
  exports.InputRoot = (0, react_1.forwardRef)(({ value, onChangeText, onChange, onFocus, onBlur, error = false, disabled = false, loading = false, editable, style, placeholderTextColor = "#9ca3af", ...props }, ref) => {
10
11
  const [isFocused, setIsFocused] = react_1.default.useState(false);
12
+ let isInBottomSheet = false;
13
+ try {
14
+ (0, bottom_sheet_1.useBottomSheetInternal)();
15
+ isInBottomSheet = true;
16
+ }
17
+ catch {
18
+ isInBottomSheet = false;
19
+ }
20
+ const InputComponent = isInBottomSheet && react_native_1.Platform.OS !== "web"
21
+ ? bottom_sheet_1.BottomSheetTextInput
22
+ : react_native_1.TextInput;
11
23
  const handleChangeText = react_1.default.useCallback((text) => {
12
24
  if (onChangeText) {
13
25
  onChangeText(text);
@@ -28,7 +40,7 @@ exports.InputRoot = (0, react_1.forwardRef)(({ value, onChangeText, onChange, on
28
40
  onBlur(event);
29
41
  }
30
42
  }, [onBlur]);
31
- return ((0, jsx_runtime_1.jsx)(react_native_1.TextInput, { ref: ref, value: value, onChangeText: handleChangeText, onFocus: handleFocus, onBlur: handleBlur, editable: !disabled && !loading && editable, placeholderTextColor: placeholderTextColor, style: [
43
+ return ((0, jsx_runtime_1.jsx)(InputComponent, { ref: ref, value: value, onChangeText: handleChangeText, onFocus: handleFocus, onBlur: handleBlur, editable: !disabled && !loading && editable, placeholderTextColor: placeholderTextColor, style: [
32
44
  primitiveStyles.input,
33
45
  style,
34
46
  error && primitiveStyles.inputError,
@@ -7,7 +7,7 @@ const react_1 = tslib_1.__importStar(require("react"));
7
7
  const react_native_1 = require("react-native");
8
8
  const { width: screenWidth, height: screenHeight } = react_native_1.Dimensions.get("window");
9
9
  // Modal root primitive - handles the native Modal component
10
- exports.ModalRoot = (0, react_1.forwardRef)(({ open = false, onOpenChange, children, onRequestClose, animationType = "fade", presentationStyle = react_native_1.Platform.OS === "ios" ? "pageSheet" : "fullScreen", statusBarTranslucent = react_native_1.Platform.OS === "android", ...props }, ref) => {
10
+ exports.ModalRoot = (0, react_1.forwardRef)(({ open = false, onOpenChange, children, onRequestClose, animationType = "fade", presentationStyle = react_native_1.Platform.OS === "ios" ? "pageSheet" : "formSheet", statusBarTranslucent = react_native_1.Platform.OS !== "ios", transparent = true, ...props }, ref) => {
11
11
  const handleRequestClose = react_1.default.useCallback((e) => {
12
12
  if (onOpenChange) {
13
13
  onOpenChange(false);
@@ -16,7 +16,7 @@ exports.ModalRoot = (0, react_1.forwardRef)(({ open = false, onOpenChange, child
16
16
  onRequestClose(e);
17
17
  }
18
18
  }, [onOpenChange, onRequestClose]);
19
- return ((0, jsx_runtime_1.jsx)(react_native_1.Modal, { visible: open, onRequestClose: handleRequestClose, animationType: animationType, presentationStyle: presentationStyle, statusBarTranslucent: statusBarTranslucent, ...props, children: (0, jsx_runtime_1.jsx)(react_native_1.View, { ref: ref, style: primitiveStyles.container, children: children }) }));
19
+ return ((0, jsx_runtime_1.jsx)(react_native_1.Modal, { visible: open, onRequestClose: handleRequestClose, animationType: animationType, presentationStyle: presentationStyle, statusBarTranslucent: statusBarTranslucent, transparent: transparent, ...props, children: (0, jsx_runtime_1.jsx)(react_native_1.View, { ref: ref, style: primitiveStyles.container, children: children }) }));
20
20
  });
21
21
  exports.ModalRoot.displayName = "ModalRoot";
22
22
  exports.ModalOverlay = (0, react_1.forwardRef)(({ dismissible = true, onDismiss, onPress, style, children, activeOpacity = 1, ...props }, ref) => {
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Select = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const lucide_react_native_1 = require("lucide-react-native");
6
+ const react_1 = require("react");
7
+ const react_native_1 = require("react-native");
8
+ const theme_1 = require("../../lib/theme/theme");
9
+ const text_1 = require("./text");
10
+ exports.Select = (0, react_1.forwardRef)(({ value, onValueChange, placeholder = "Select...", items, disabled = false, style, }, ref) => {
11
+ const { theme } = (0, theme_1.useTheme)();
12
+ const [isOpen, setIsOpen] = (0, react_1.useState)(false);
13
+ const selectedItem = items.find((item) => item.value === value);
14
+ const handleSelect = (itemValue) => {
15
+ onValueChange(itemValue);
16
+ setIsOpen(false);
17
+ };
18
+ const styles = createStyles(theme, disabled);
19
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_native_1.TouchableOpacity, { ref: ref, style: [styles.container, style], onPress: () => !disabled && setIsOpen(true), disabled: disabled, children: [(0, jsx_runtime_1.jsx)(text_1.Text, { style: styles.value, children: selectedItem?.label || placeholder }), (0, jsx_runtime_1.jsx)(lucide_react_native_1.ChevronDown, { size: 16, color: theme.colors.textMuted })] }), (0, jsx_runtime_1.jsx)(react_native_1.Modal, { visible: isOpen, transparent: true, animationType: "fade", onRequestClose: () => setIsOpen(false), children: (0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { style: styles.overlay, activeOpacity: 1, onPress: () => setIsOpen(false), children: (0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.dropdown, children: (0, jsx_runtime_1.jsx)(react_native_1.FlatList, { data: items, keyExtractor: (item) => item.value, renderItem: ({ item }) => ((0, jsx_runtime_1.jsxs)(react_native_1.TouchableOpacity, { style: [
20
+ styles.item,
21
+ item.value === value && styles.selectedItem,
22
+ ], onPress: () => handleSelect(item.value), children: [(0, jsx_runtime_1.jsx)(text_1.Text, { style: [
23
+ styles.itemText,
24
+ item.value === value ? styles.selectedItemText : {},
25
+ ], children: item.label }), item.description && ((0, jsx_runtime_1.jsx)(text_1.Text, { style: styles.itemDescription, children: item.description }))] })), style: styles.list }) }) }) })] }));
26
+ });
27
+ exports.Select.displayName = "Select";
28
+ function createStyles(theme, disabled) {
29
+ return react_native_1.StyleSheet.create({
30
+ container: {
31
+ flexDirection: "row",
32
+ alignItems: "center",
33
+ justifyContent: "space-between",
34
+ paddingHorizontal: theme.spacing[3],
35
+ paddingVertical: theme.spacing[3],
36
+ borderWidth: 1,
37
+ borderColor: theme.colors.border,
38
+ borderRadius: theme.borderRadius.md,
39
+ backgroundColor: disabled ? theme.colors.muted : theme.colors.card,
40
+ minHeight: theme.touchTargets.minimum,
41
+ },
42
+ value: {
43
+ fontSize: 16,
44
+ color: disabled ? theme.colors.textDisabled : theme.colors.text,
45
+ flex: 1,
46
+ },
47
+ overlay: {
48
+ flex: 1,
49
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
50
+ justifyContent: "center",
51
+ alignItems: "center",
52
+ },
53
+ dropdown: {
54
+ backgroundColor: theme.colors.background,
55
+ borderRadius: theme.borderRadius.md,
56
+ borderWidth: 1,
57
+ borderColor: theme.colors.border,
58
+ maxHeight: 300,
59
+ width: "90%",
60
+ maxWidth: 400,
61
+ ...theme.shadows.lg,
62
+ },
63
+ list: {
64
+ maxHeight: 300,
65
+ },
66
+ item: {
67
+ paddingHorizontal: theme.spacing[4],
68
+ paddingVertical: theme.spacing[3],
69
+ borderBottomWidth: 1,
70
+ borderBottomColor: theme.colors.border,
71
+ },
72
+ selectedItem: {
73
+ backgroundColor: theme.colors.primary,
74
+ },
75
+ itemText: {
76
+ fontSize: 16,
77
+ color: theme.colors.text,
78
+ },
79
+ selectedItemText: {
80
+ color: theme.colors.primaryForeground,
81
+ fontWeight: "500",
82
+ },
83
+ itemDescription: {
84
+ fontSize: 14,
85
+ color: theme.colors.textMuted,
86
+ marginTop: theme.spacing[1],
87
+ },
88
+ });
89
+ }
@@ -1,11 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Textarea = Textarea;
3
+ exports.Textarea = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const bottom_sheet_1 = require("@gorhom/bottom-sheet");
7
+ const React = tslib_1.__importStar(require("react"));
5
8
  const react_native_1 = require("react-native");
6
9
  const atoms_1 = require("../../lib/theme/atoms");
7
- function Textarea({ style, multiline = true, numberOfLines = 4, ...props }) {
8
- return ((0, jsx_runtime_1.jsx)(react_native_1.TextInput, { style: [
10
+ const Textarea = React.forwardRef(({ style, multiline = true, numberOfLines = 4, ...props }, ref) => {
11
+ // Detect if we're inside a bottom sheet
12
+ let isInBottomSheet = false;
13
+ try {
14
+ (0, bottom_sheet_1.useBottomSheetInternal)();
15
+ isInBottomSheet = true;
16
+ }
17
+ catch {
18
+ // Not in a bottom sheet context
19
+ isInBottomSheet = false;
20
+ }
21
+ // Use BottomSheetTextInput when inside a bottom sheet, regular TextInput otherwise
22
+ const InputComponent = isInBottomSheet && react_native_1.Platform.OS !== "web"
23
+ ? bottom_sheet_1.BottomSheetTextInput
24
+ : react_native_1.TextInput;
25
+ return ((0, jsx_runtime_1.jsx)(InputComponent, { ref: ref, style: [
9
26
  atoms_1.flex.values[1],
10
27
  atoms_1.borders.width.thin,
11
28
  atoms_1.borders.color.gray[400],
@@ -16,4 +33,6 @@ function Textarea({ style, multiline = true, numberOfLines = 4, ...props }) {
16
33
  { borderRadius: 10 },
17
34
  style,
18
35
  ], multiline: multiline, numberOfLines: numberOfLines, textAlignVertical: "top", ...props }));
19
- }
36
+ });
37
+ exports.Textarea = Textarea;
38
+ Textarea.displayName = "Textarea";