@streamplace/components 0.7.18 → 0.7.21

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 (122) hide show
  1. package/dist/assets/emoji-data.json +19371 -0
  2. package/dist/components/chat/chat-box.js +319 -0
  3. package/dist/components/chat/chat-message.js +87 -0
  4. package/dist/components/chat/chat.js +150 -0
  5. package/dist/components/chat/emoji-suggestions.js +35 -0
  6. package/dist/components/chat/mention-suggestions.js +42 -0
  7. package/dist/components/chat/mod-view.js +112 -0
  8. package/dist/components/chat/system-message.js +19 -0
  9. package/dist/components/dashboard/chat-panel.js +38 -0
  10. package/dist/components/dashboard/header.js +80 -0
  11. package/dist/components/dashboard/index.js +14 -0
  12. package/dist/components/dashboard/information-widget.js +234 -0
  13. package/dist/components/dashboard/mod-actions.js +71 -0
  14. package/dist/components/dashboard/problems.js +74 -0
  15. package/dist/components/icons/bluesky-icon.js +9 -0
  16. package/dist/components/keep-awake.js +7 -0
  17. package/dist/components/keep-awake.native.js +16 -0
  18. package/dist/components/mobile-player/fullscreen.js +76 -0
  19. package/dist/components/mobile-player/fullscreen.native.js +141 -0
  20. package/dist/components/mobile-player/player.js +94 -0
  21. package/dist/components/mobile-player/props.js +2 -0
  22. package/dist/components/mobile-player/shared.js +54 -0
  23. package/dist/components/mobile-player/ui/autoplay-button.js +68 -0
  24. package/dist/components/mobile-player/ui/countdown.js +83 -0
  25. package/dist/components/mobile-player/ui/index.js +12 -0
  26. package/dist/components/mobile-player/ui/input.js +42 -0
  27. package/dist/components/mobile-player/ui/metrics.js +44 -0
  28. package/dist/components/mobile-player/ui/report-modal.js +90 -0
  29. package/dist/components/mobile-player/ui/streamer-context-menu.js +7 -0
  30. package/dist/components/mobile-player/ui/streamer-loading-overlay.js +104 -0
  31. package/dist/components/mobile-player/ui/viewer-context-menu.js +51 -0
  32. package/dist/components/mobile-player/ui/viewer-loading-overlay.js +49 -0
  33. package/dist/components/mobile-player/ui/viewers.js +23 -0
  34. package/dist/components/mobile-player/use-webrtc.js +243 -0
  35. package/dist/components/mobile-player/video-async.native.js +276 -0
  36. package/dist/components/mobile-player/video-retry.js +29 -0
  37. package/dist/components/mobile-player/video.js +475 -0
  38. package/dist/components/mobile-player/video.native.js +56 -0
  39. package/dist/components/mobile-player/webrtc-diagnostics.js +110 -0
  40. package/dist/components/mobile-player/webrtc-primitives.js +27 -0
  41. package/dist/components/mobile-player/webrtc-primitives.native.js +8 -0
  42. package/dist/components/share/sharesheet.js +91 -0
  43. package/dist/components/ui/button.js +223 -0
  44. package/dist/components/ui/dialog.js +206 -0
  45. package/dist/components/ui/dropdown.js +172 -0
  46. package/dist/components/ui/icons.js +25 -0
  47. package/dist/components/ui/index.js +34 -0
  48. package/dist/components/ui/info-box.js +31 -0
  49. package/dist/components/ui/info-row.js +23 -0
  50. package/dist/components/ui/input.js +205 -0
  51. package/dist/components/ui/loader.js +10 -0
  52. package/dist/components/ui/primitives/button.js +125 -0
  53. package/dist/components/ui/primitives/input.js +206 -0
  54. package/dist/components/ui/primitives/modal.js +206 -0
  55. package/dist/components/ui/primitives/text.js +292 -0
  56. package/dist/components/ui/resizeable.js +121 -0
  57. package/dist/components/ui/slider.js +5 -0
  58. package/dist/components/ui/text.js +177 -0
  59. package/dist/components/ui/textarea.js +19 -0
  60. package/dist/components/ui/toast.js +175 -0
  61. package/dist/components/ui/view.js +252 -0
  62. package/dist/hooks/index.js +14 -0
  63. package/dist/hooks/useAvatars.js +35 -0
  64. package/dist/hooks/useCameraToggle.js +12 -0
  65. package/dist/hooks/useKeyboard.js +36 -0
  66. package/dist/hooks/useKeyboardSlide.js +14 -0
  67. package/dist/hooks/useLivestreamInfo.js +69 -0
  68. package/dist/hooks/useOuterAndInnerDimensions.js +30 -0
  69. package/dist/hooks/usePlayerDimensions.js +22 -0
  70. package/dist/hooks/usePointerDevice.js +71 -0
  71. package/dist/hooks/useSegmentDimensions.js +17 -0
  72. package/dist/hooks/useSegmentTiming.js +65 -0
  73. package/dist/index.js +34 -0
  74. package/dist/lib/browser.js +35 -0
  75. package/dist/lib/facet.js +92 -0
  76. package/dist/lib/system-messages.js +101 -0
  77. package/dist/lib/theme/atoms.js +646 -0
  78. package/dist/lib/theme/atoms.types.js +6 -0
  79. package/dist/lib/theme/index.js +35 -0
  80. package/dist/lib/theme/theme.js +256 -0
  81. package/dist/lib/theme/tokens.js +659 -0
  82. package/dist/lib/utils.js +105 -0
  83. package/dist/livestream-provider/index.js +30 -0
  84. package/dist/livestream-provider/websocket.js +45 -0
  85. package/dist/livestream-store/chat.js +308 -0
  86. package/dist/livestream-store/context.js +5 -0
  87. package/dist/livestream-store/index.js +7 -0
  88. package/dist/livestream-store/livestream-state.js +2 -0
  89. package/dist/livestream-store/livestream-store.js +58 -0
  90. package/dist/livestream-store/problems.js +76 -0
  91. package/dist/livestream-store/stream-key.js +88 -0
  92. package/dist/livestream-store/websocket-consumer.js +94 -0
  93. package/dist/player-store/context.js +5 -0
  94. package/dist/player-store/index.js +9 -0
  95. package/dist/player-store/player-provider.js +58 -0
  96. package/dist/player-store/player-state.js +25 -0
  97. package/dist/player-store/player-store.js +201 -0
  98. package/dist/player-store/single-player-provider.js +121 -0
  99. package/dist/streamplace-provider/context.js +5 -0
  100. package/dist/streamplace-provider/index.js +20 -0
  101. package/dist/streamplace-provider/poller.js +49 -0
  102. package/dist/streamplace-provider/xrpc.js +0 -0
  103. package/dist/streamplace-store/block.js +65 -0
  104. package/dist/streamplace-store/index.js +6 -0
  105. package/dist/streamplace-store/stream.js +247 -0
  106. package/dist/streamplace-store/streamplace-store.js +47 -0
  107. package/dist/streamplace-store/user.js +52 -0
  108. package/dist/streamplace-store/xrpc.js +15 -0
  109. package/dist/ui/index.js +79 -0
  110. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
  111. package/package.json +5 -4
  112. package/src/components/chat/chat-box.tsx +3 -0
  113. package/src/components/chat/mod-view.tsx +39 -5
  114. package/src/components/mobile-player/fullscreen.tsx +2 -0
  115. package/src/components/mobile-player/ui/autoplay-button.tsx +86 -0
  116. package/src/components/mobile-player/ui/index.ts +1 -0
  117. package/src/components/mobile-player/video.tsx +11 -1
  118. package/src/livestream-store/chat.tsx +22 -0
  119. package/src/player-store/player-provider.tsx +2 -1
  120. package/src/player-store/player-state.tsx +6 -0
  121. package/src/player-store/player-store.tsx +4 -0
  122. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ShareSheet = ShareSheet;
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");
9
+ const livestream_store_1 = require("../../livestream-store");
10
+ const streamplace_store_1 = require("../../streamplace-store");
11
+ const bluesky_icon_1 = require("../icons/bluesky-icon");
12
+ const ui_1 = require("../ui");
13
+ function ShareSheet({ onShare } = {}) {
14
+ const profile = (0, livestream_store_1.useLivestreamStore)((x) => x.profile);
15
+ const [isCopying, setIsCopying] = (0, react_1.useState)(false);
16
+ const url = (0, streamplace_store_1.useUrl)();
17
+ // Get the current stream URL
18
+ const getStreamUrl = (0, react_1.useCallback)(() => {
19
+ return url + (profile ? `/@${profile.handle}` : "");
20
+ }, [profile]);
21
+ // Get the embed URL
22
+ const getEmbedUrl = (0, react_1.useCallback)(() => {
23
+ return url + (profile ? `/embed/${profile.handle}` : "");
24
+ }, [profile]);
25
+ // Get embed code
26
+ const getEmbedCode = (0, react_1.useCallback)(() => {
27
+ const embedUrl = getEmbedUrl();
28
+ return `<iframe src="${embedUrl}" width="640" height="360" frameborder="0" allowfullscreen></iframe>`;
29
+ }, [getEmbedUrl]);
30
+ // Copy to clipboard handler
31
+ const copyToClipboard = (0, react_1.useCallback)(async (text, label) => {
32
+ setIsCopying(true);
33
+ try {
34
+ if (react_native_1.Platform.OS === "web") {
35
+ await navigator.clipboard.writeText(text);
36
+ }
37
+ else {
38
+ react_native_1.Clipboard.setString(text);
39
+ }
40
+ onShare?.(`copy_${label.toLowerCase().replace(/\s+/g, "_")}`, true);
41
+ }
42
+ catch (error) {
43
+ onShare?.(`copy_${label.toLowerCase().replace(/\s+/g, "_")}`, false);
44
+ }
45
+ finally {
46
+ setIsCopying(false);
47
+ }
48
+ }, [onShare]);
49
+ // Share to Bluesky
50
+ const shareToBluesky = (0, react_1.useCallback)(() => {
51
+ const streamUrl = getStreamUrl();
52
+ const text = profile
53
+ ? `Check out @${profile.handle} live on Streamplace! ${streamUrl}`
54
+ : `Check out this stream on Streamplace! ${streamUrl}`;
55
+ const blueskyUrl = `https://bsky.app/intent/compose?text=${encodeURIComponent(text)}`;
56
+ react_native_1.Linking.openURL(blueskyUrl);
57
+ onShare?.("share_bluesky", true);
58
+ }, [profile, getStreamUrl, onShare]);
59
+ // Share to Twitter/X
60
+ const shareToTwitter = (0, react_1.useCallback)(() => {
61
+ const streamUrl = getStreamUrl();
62
+ const text = profile
63
+ ? `Check out @${profile.handle} live on Streamplace!`
64
+ : `Check out this stream on Streamplace!`;
65
+ const twitterUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(streamUrl)}`;
66
+ react_native_1.Linking.openURL(twitterUrl);
67
+ onShare?.("share_twitter", true);
68
+ }, [profile, getStreamUrl, onShare]);
69
+ // Native share (mobile)
70
+ const nativeShare = (0, react_1.useCallback)(async () => {
71
+ const streamUrl = getStreamUrl();
72
+ const text = profile
73
+ ? `Check out @${profile.handle} live on Streamplace!`
74
+ : `Check out this stream on Streamplace!`;
75
+ if (react_native_1.Platform.OS === "web" && navigator.share) {
76
+ try {
77
+ await navigator.share({
78
+ title: "Streamplace",
79
+ text: text,
80
+ url: streamUrl,
81
+ });
82
+ onShare?.("share_native", true);
83
+ }
84
+ catch (error) {
85
+ // User cancelled or error occurred
86
+ onShare?.("share_native", false);
87
+ }
88
+ }
89
+ }, [profile, getStreamUrl, onShare]);
90
+ return ((0, jsx_runtime_1.jsxs)(ui_1.DropdownMenu, { children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuTrigger, { children: (0, jsx_runtime_1.jsx)(lucide_react_native_1.Share2, { color: theme_1.colors.gray[200] }) }), (0, jsx_runtime_1.jsxs)(ui_1.ResponsiveDropdownMenuContent, { children: [(0, jsx_runtime_1.jsxs)(ui_1.DropdownMenuGroup, { title: "Share", children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: shareToBluesky, closeOnPress: true, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(bluesky_icon_1.BlueskyIcon, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Share to Bluesky" })] }) }), react_native_1.Platform.OS !== "web" || (navigator && navigator.share) ? ((0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: nativeShare, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Share2, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "More Options..." })] }) })) : null] }), (0, jsx_runtime_1.jsxs)(ui_1.DropdownMenuGroup, { title: "Copy", children: [(0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: () => copyToClipboard(getStreamUrl(), "Stream link"), disabled: isCopying, closeOnPress: true, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Link2, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Copy Link" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuSeparator, {}), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { onPress: () => copyToClipboard(getEmbedCode(), "Embed code"), disabled: isCopying, closeOnPress: true, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Code, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Copy Embed Code" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuSeparator, {}), (0, jsx_runtime_1.jsx)(ui_1.DropdownMenuItem, { closeOnPress: true, onPress: () => copyToClipboard(getEmbedUrl(), "Embed URL"), disabled: isCopying, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [(0, jsx_runtime_1.jsx)(lucide_react_native_1.Copy, { size: 20, color: theme_1.colors.gray[400] }), (0, jsx_runtime_1.jsx)(ui_1.Text, { children: "Copy Embed URL" })] }) })] })] })] }));
91
+ }
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buttonVariants = exports.Button = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const class_variance_authority_1 = require("class-variance-authority");
7
+ const react_1 = tslib_1.__importStar(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const theme_1 = require("../../lib/theme/theme");
10
+ const tokens = tslib_1.__importStar(require("../../lib/theme/tokens"));
11
+ const button_1 = require("./primitives/button");
12
+ const text_1 = require("./primitives/text");
13
+ // Button variants using class-variance-authority pattern
14
+ const buttonVariants = (0, class_variance_authority_1.cva)("", {
15
+ variants: {
16
+ variant: {
17
+ primary: "primary",
18
+ secondary: "secondary",
19
+ outline: "outline",
20
+ ghost: "ghost",
21
+ destructive: "destructive",
22
+ success: "success",
23
+ },
24
+ size: {
25
+ sm: "sm",
26
+ md: "md",
27
+ lg: "lg",
28
+ xl: "xl",
29
+ pill: "pill",
30
+ },
31
+ },
32
+ defaultVariants: {
33
+ variant: "primary",
34
+ size: "md",
35
+ },
36
+ });
37
+ exports.buttonVariants = buttonVariants;
38
+ exports.Button = (0, react_1.forwardRef)(({ variant = "primary", size = "md", children, leftIcon, rightIcon, loading = false, loadingText, disabled, style, ...props }, ref) => {
39
+ const { theme } = (0, theme_1.useTheme)();
40
+ // Create dynamic styles based on theme
41
+ const styles = (0, react_1.useMemo)(() => createStyles(theme), [theme]);
42
+ // Get variant styles
43
+ const buttonStyle = (0, react_1.useMemo)(() => {
44
+ const variantStyle = styles[`${variant}Button`];
45
+ const sizeStyle = styles[`${size}Button`];
46
+ return [variantStyle, sizeStyle];
47
+ }, [variant, size, styles]);
48
+ // Get inner styles for button content
49
+ const buttonInnerStyle = (0, react_1.useMemo)(() => {
50
+ const sizeInnerStyle = styles[`${size}ButtonInner`];
51
+ return sizeInnerStyle;
52
+ }, [size, styles]);
53
+ const textStyle = react_1.default.useMemo(() => {
54
+ const variantTextStyle = styles[`${variant}Text`];
55
+ const sizeTextStyle = styles[`${size}Text`];
56
+ return [variantTextStyle, sizeTextStyle];
57
+ }, [variant, size, styles]);
58
+ const iconSize = react_1.default.useMemo(() => {
59
+ switch (size) {
60
+ case "sm":
61
+ return 16;
62
+ case "lg":
63
+ return 20;
64
+ case "xl":
65
+ return 24;
66
+ case "md":
67
+ default:
68
+ return 18;
69
+ }
70
+ }, [size]);
71
+ const spinnerSize = (0, react_1.useMemo)(() => {
72
+ switch (size) {
73
+ case "sm":
74
+ return "small";
75
+ case "lg":
76
+ case "xl":
77
+ return "large";
78
+ case "md":
79
+ default:
80
+ return "small";
81
+ }
82
+ }, [size]);
83
+ const spinnerColor = (0, react_1.useMemo)(() => {
84
+ switch (variant) {
85
+ case "outline":
86
+ case "ghost":
87
+ return theme.colors.primary;
88
+ case "secondary":
89
+ return theme.colors.secondaryForeground;
90
+ case "destructive":
91
+ return theme.colors.destructiveForeground;
92
+ default:
93
+ return theme.colors.primaryForeground;
94
+ }
95
+ }, [variant, theme.colors]);
96
+ return ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Root, { ref: ref, disabled: disabled || loading, style: [buttonStyle, style], ...props, children: (0, jsx_runtime_1.jsxs)(button_1.ButtonPrimitive.Content, { style: buttonInnerStyle, children: [loading && !leftIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "left", children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: spinnerSize, color: spinnerColor }) })) : leftIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "left", style: { width: iconSize, height: iconSize }, children: leftIcon })) : null, (0, jsx_runtime_1.jsx)(text_1.TextPrimitive.Root, { style: textStyle, children: loading && loadingText ? loadingText : children }), loading && rightIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "right", children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: spinnerSize, color: spinnerColor }) })) : rightIcon ? ((0, jsx_runtime_1.jsx)(button_1.ButtonPrimitive.Icon, { position: "right", style: { width: iconSize, height: iconSize }, children: rightIcon })) : null] }) }));
97
+ });
98
+ exports.Button.displayName = "Button";
99
+ // Create theme-based styles
100
+ function createStyles(theme) {
101
+ return react_native_1.StyleSheet.create({
102
+ // Variant styles
103
+ primaryButton: {
104
+ backgroundColor: theme.colors.primary,
105
+ borderWidth: 0,
106
+ ...theme.shadows.sm,
107
+ },
108
+ primaryText: {
109
+ color: theme.colors.primaryForeground,
110
+ fontWeight: "600",
111
+ },
112
+ secondaryButton: {
113
+ backgroundColor: theme.colors.secondary,
114
+ borderWidth: 0,
115
+ },
116
+ secondaryText: {
117
+ color: theme.colors.secondaryForeground,
118
+ fontWeight: "500",
119
+ },
120
+ outlineButton: {
121
+ backgroundColor: "transparent",
122
+ borderWidth: 1,
123
+ borderColor: theme.colors.border,
124
+ },
125
+ outlineText: {
126
+ color: theme.colors.foreground,
127
+ fontWeight: "500",
128
+ },
129
+ ghostButton: {
130
+ backgroundColor: "transparent",
131
+ borderWidth: 0,
132
+ },
133
+ ghostText: {
134
+ color: theme.colors.foreground,
135
+ fontWeight: "500",
136
+ },
137
+ destructiveButton: {
138
+ backgroundColor: theme.colors.destructive,
139
+ borderWidth: 0,
140
+ ...theme.shadows.sm,
141
+ },
142
+ destructiveText: {
143
+ color: theme.colors.destructiveForeground,
144
+ fontWeight: "600",
145
+ },
146
+ successButton: {
147
+ backgroundColor: theme.colors.success,
148
+ borderWidth: 0,
149
+ ...theme.shadows.sm,
150
+ },
151
+ successText: {
152
+ color: theme.colors.successForeground,
153
+ fontWeight: "600",
154
+ },
155
+ pillButton: {
156
+ paddingHorizontal: theme.spacing[2],
157
+ paddingVertical: theme.spacing[1],
158
+ borderRadius: tokens.borderRadius.full,
159
+ minHeight: tokens.touchTargets.minimum / 2,
160
+ },
161
+ pillText: {
162
+ color: theme.colors.primaryForeground,
163
+ fontWeight: "400",
164
+ },
165
+ // Size styles
166
+ smButton: {
167
+ paddingHorizontal: theme.spacing[3],
168
+ paddingVertical: theme.spacing[2],
169
+ borderRadius: tokens.borderRadius.md,
170
+ minHeight: tokens.touchTargets.minimum,
171
+ gap: theme.spacing[1],
172
+ },
173
+ smButtonInner: {
174
+ gap: theme.spacing[1],
175
+ },
176
+ smText: {
177
+ fontSize: 14,
178
+ lineHeight: 16,
179
+ },
180
+ mdButton: {
181
+ paddingHorizontal: theme.spacing[4],
182
+ paddingVertical: theme.spacing[3],
183
+ borderRadius: tokens.borderRadius.md,
184
+ minHeight: tokens.touchTargets.minimum,
185
+ gap: theme.spacing[2],
186
+ },
187
+ mdButtonInner: {
188
+ gap: theme.spacing[2],
189
+ },
190
+ mdText: {
191
+ fontSize: 16,
192
+ lineHeight: 18,
193
+ },
194
+ lgButton: {
195
+ paddingHorizontal: theme.spacing[6],
196
+ paddingVertical: theme.spacing[4],
197
+ borderRadius: tokens.borderRadius.md,
198
+ minHeight: tokens.touchTargets.comfortable,
199
+ gap: theme.spacing[3],
200
+ },
201
+ lgButtonInner: {
202
+ gap: theme.spacing[3],
203
+ },
204
+ lgText: {
205
+ fontSize: 18,
206
+ lineHeight: 20,
207
+ },
208
+ xlButton: {
209
+ paddingHorizontal: theme.spacing[8],
210
+ paddingVertical: theme.spacing[5],
211
+ borderRadius: tokens.borderRadius.lg,
212
+ minHeight: tokens.touchTargets.large,
213
+ gap: theme.spacing[4],
214
+ },
215
+ xlButtonInner: {
216
+ gap: theme.spacing[4],
217
+ },
218
+ xlText: {
219
+ fontSize: 20,
220
+ lineHeight: 24,
221
+ },
222
+ });
223
+ }
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dialogVariants = exports.DialogFooter = exports.DialogDescription = exports.DialogTitle = exports.Dialog = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const class_variance_authority_1 = require("class-variance-authority");
7
+ const lucide_react_native_1 = require("lucide-react-native");
8
+ const react_1 = tslib_1.__importStar(require("react"));
9
+ const react_native_1 = require("react-native");
10
+ const theme_1 = require("../../lib/theme/theme");
11
+ const icons_1 = require("./icons");
12
+ const modal_1 = require("./primitives/modal");
13
+ const ThemedX = (0, icons_1.createThemedIcon)(lucide_react_native_1.X);
14
+ // Dialog variants using class-variance-authority pattern
15
+ const dialogVariants = (0, class_variance_authority_1.cva)("", {
16
+ variants: {
17
+ variant: {
18
+ default: "default",
19
+ sheet: "sheet",
20
+ fullscreen: "fullscreen",
21
+ },
22
+ size: {
23
+ sm: "sm",
24
+ md: "md",
25
+ lg: "lg",
26
+ xl: "xl",
27
+ full: "full",
28
+ },
29
+ position: {
30
+ center: "center",
31
+ top: "top",
32
+ bottom: "bottom",
33
+ left: "left",
34
+ right: "right",
35
+ },
36
+ },
37
+ defaultVariants: {
38
+ variant: "default",
39
+ size: "md",
40
+ position: "center",
41
+ },
42
+ });
43
+ exports.dialogVariants = dialogVariants;
44
+ 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) => {
45
+ const { theme } = (0, theme_1.useTheme)();
46
+ // Create dynamic styles based on theme
47
+ const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
48
+ const handleClose = react_1.default.useCallback(() => {
49
+ if (onClose) {
50
+ onClose();
51
+ }
52
+ if (onOpenChange) {
53
+ onOpenChange(false);
54
+ }
55
+ }, [onClose, onOpenChange]);
56
+ const presentationStyle = react_1.default.useMemo(() => {
57
+ if (variant === "sheet" && react_native_1.Platform.OS === "ios") {
58
+ return "pageSheet";
59
+ }
60
+ if (variant === "fullscreen") {
61
+ return "fullScreen";
62
+ }
63
+ return react_native_1.Platform.OS === "ios"
64
+ ? "pageSheet"
65
+ : "fullScreen";
66
+ }, [variant]);
67
+ const animationType = react_1.default.useMemo(() => {
68
+ if (variant === "sheet") {
69
+ return "slide";
70
+ }
71
+ return "fade";
72
+ }, [variant]);
73
+ 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 || "left", size: size || "md", style: [
74
+ styles.content,
75
+ styles[`${variant}Content`],
76
+ styles[`${size}Content`],
77
+ ], 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] })] }) }) }));
78
+ });
79
+ exports.Dialog.displayName = "Dialog";
80
+ exports.DialogTitle = (0, react_1.forwardRef)(({ children, style, ...props }, ref) => {
81
+ const { theme } = (0, theme_1.useTheme)();
82
+ const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
83
+ if (!children)
84
+ return null;
85
+ return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { ref: ref, style: [styles.title, style], ...props, children: children }));
86
+ });
87
+ exports.DialogTitle.displayName = "DialogTitle";
88
+ exports.DialogDescription = (0, react_1.forwardRef)(({ children, style, ...props }, ref) => {
89
+ const { theme } = (0, theme_1.useTheme)();
90
+ const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
91
+ if (!children)
92
+ return null;
93
+ return ((0, jsx_runtime_1.jsx)(react_native_1.Text, { ref: ref, style: [styles.description, style], ...props, children: children }));
94
+ });
95
+ exports.DialogDescription.displayName = "DialogDescription";
96
+ exports.DialogFooter = (0, react_1.forwardRef)(({ children, direction = "row", justify = "flex-end", withBorder = true, style, ...props }, ref) => {
97
+ const { theme } = (0, theme_1.useTheme)();
98
+ const styles = react_1.default.useMemo(() => createStyles(theme), [theme]);
99
+ if (!children)
100
+ return null;
101
+ 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 }));
102
+ });
103
+ exports.DialogFooter.displayName = "DialogFooter";
104
+ // Dialog Close Icon component (Lucide X)
105
+ const DialogCloseIcon = () => {
106
+ return (0, jsx_runtime_1.jsx)(ThemedX, { size: "md", variant: "default" });
107
+ };
108
+ // Create theme-aware styles
109
+ function createStyles(theme) {
110
+ return react_native_1.StyleSheet.create({
111
+ overlay: {
112
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
113
+ },
114
+ content: {
115
+ backgroundColor: theme.colors.card,
116
+ borderRadius: theme.borderRadius.lg,
117
+ ...theme.shadows.lg,
118
+ maxHeight: "90%",
119
+ maxWidth: "90%",
120
+ },
121
+ // Variant styles
122
+ defaultContent: {
123
+ // Default styles already applied in content
124
+ },
125
+ sheetContent: {
126
+ borderTopLeftRadius: theme.borderRadius.xl,
127
+ borderTopRightRadius: theme.borderRadius.xl,
128
+ borderBottomLeftRadius: 0,
129
+ borderBottomRightRadius: 0,
130
+ marginTop: "auto",
131
+ marginBottom: 0,
132
+ maxHeight: "80%",
133
+ width: "100%",
134
+ maxWidth: "100%",
135
+ },
136
+ fullscreenContent: {
137
+ width: "100%",
138
+ height: "100%",
139
+ maxWidth: "100%",
140
+ maxHeight: "100%",
141
+ borderRadius: 0,
142
+ margin: 0,
143
+ },
144
+ // Size styles
145
+ smContent: {
146
+ minWidth: 300,
147
+ minHeight: 200,
148
+ },
149
+ mdContent: {
150
+ minWidth: 400,
151
+ minHeight: 300,
152
+ },
153
+ lgContent: {
154
+ minWidth: 500,
155
+ minHeight: 400,
156
+ },
157
+ xlContent: {
158
+ minWidth: 600,
159
+ minHeight: 500,
160
+ },
161
+ fullContent: {
162
+ width: "95%",
163
+ height: "95%",
164
+ maxWidth: "95%",
165
+ maxHeight: "95%",
166
+ },
167
+ header: {
168
+ paddingHorizontal: theme.spacing[6],
169
+ paddingVertical: theme.spacing[4],
170
+ flexDirection: "row",
171
+ alignItems: "center",
172
+ justifyContent: "space-between",
173
+ },
174
+ body: {
175
+ paddingHorizontal: theme.spacing[6],
176
+ paddingBottom: theme.spacing[6],
177
+ flex: 1,
178
+ },
179
+ footer: {
180
+ paddingHorizontal: theme.spacing[6],
181
+ paddingVertical: theme.spacing[4],
182
+ gap: theme.spacing[2],
183
+ },
184
+ title: {
185
+ fontSize: 20,
186
+ fontWeight: "600",
187
+ color: theme.colors.text,
188
+ flex: 1,
189
+ lineHeight: 24,
190
+ },
191
+ description: {
192
+ fontSize: 16,
193
+ color: theme.colors.textMuted,
194
+ lineHeight: 22,
195
+ marginBottom: theme.spacing[4],
196
+ },
197
+ closeButton: {
198
+ width: theme.touchTargets.minimum,
199
+ height: theme.touchTargets.minimum,
200
+ alignItems: "center",
201
+ justifyContent: "center",
202
+ borderRadius: theme.borderRadius.sm,
203
+ marginLeft: theme.spacing[2],
204
+ },
205
+ });
206
+ }