@streamplace/components 0.6.37 → 0.7.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/chat/chat-box.js +109 -0
- package/dist/components/chat/chat-message.js +76 -0
- package/dist/components/chat/chat.js +56 -0
- package/dist/components/chat/mention-suggestions.js +39 -0
- package/dist/components/chat/mod-view.js +33 -0
- package/dist/components/mobile-player/fullscreen.js +69 -0
- package/dist/components/mobile-player/fullscreen.native.js +151 -0
- package/dist/components/mobile-player/player.js +103 -0
- package/dist/components/mobile-player/props.js +1 -0
- package/dist/components/mobile-player/shared.js +51 -0
- package/dist/components/mobile-player/ui/countdown.js +79 -0
- package/dist/components/mobile-player/ui/index.js +5 -0
- package/dist/components/mobile-player/ui/input.js +38 -0
- package/dist/components/mobile-player/ui/metrics.js +40 -0
- package/dist/components/mobile-player/ui/streamer-context-menu.js +4 -0
- package/dist/components/mobile-player/ui/viewer-context-menu.js +20 -0
- package/dist/components/mobile-player/use-webrtc.js +232 -0
- package/dist/components/mobile-player/video.js +375 -0
- package/dist/components/mobile-player/video.native.js +238 -0
- package/dist/components/mobile-player/webrtc-diagnostics.js +106 -0
- package/dist/components/mobile-player/webrtc-primitives.js +25 -0
- package/dist/components/mobile-player/webrtc-primitives.native.js +1 -0
- package/dist/components/ui/button.js +220 -0
- package/dist/components/ui/dialog.js +203 -0
- package/dist/components/ui/dropdown.js +148 -0
- package/dist/components/ui/icons.js +22 -0
- package/dist/components/ui/index.js +22 -0
- package/dist/components/ui/input.js +202 -0
- package/dist/components/ui/loader.js +7 -0
- package/dist/components/ui/primitives/button.js +121 -0
- package/dist/components/ui/primitives/input.js +202 -0
- package/dist/components/ui/primitives/modal.js +203 -0
- package/dist/components/ui/primitives/text.js +286 -0
- package/dist/components/ui/resizeable.js +101 -0
- package/dist/components/ui/text.js +175 -0
- package/dist/components/ui/textarea.js +17 -0
- package/dist/components/ui/toast.js +129 -0
- package/dist/components/ui/view.js +250 -0
- package/dist/hooks/index.js +9 -0
- package/dist/hooks/useAvatars.js +32 -0
- package/dist/hooks/useCameraToggle.js +9 -0
- package/dist/hooks/useKeyboard.js +33 -0
- package/dist/hooks/useKeyboardSlide.js +11 -0
- package/dist/hooks/useLivestreamInfo.js +62 -0
- package/dist/hooks/useOuterAndInnerDimensions.js +27 -0
- package/dist/hooks/usePlayerDimensions.js +19 -0
- package/dist/hooks/useSegmentTiming.js +62 -0
- package/dist/index.js +10 -0
- package/dist/lib/facet.js +88 -0
- package/dist/lib/theme/atoms.js +620 -0
- package/dist/lib/theme/atoms.types.js +5 -0
- package/dist/lib/theme/index.js +9 -0
- package/dist/lib/theme/theme.js +248 -0
- package/dist/lib/theme/tokens.js +383 -0
- package/dist/lib/utils.js +94 -0
- package/dist/livestream-provider/index.js +8 -3
- package/dist/livestream-store/chat.js +89 -65
- package/dist/livestream-store/index.js +1 -0
- package/dist/livestream-store/livestream-store.js +3 -0
- package/dist/livestream-store/stream-key.js +115 -0
- package/dist/player-store/player-provider.js +0 -1
- package/dist/player-store/player-store.js +13 -0
- package/dist/streamplace-store/block.js +23 -0
- package/dist/streamplace-store/index.js +1 -0
- package/dist/streamplace-store/stream.js +193 -0
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/56540125 +0 -0
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/67b1eb60 +0 -0
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/7c275f90 +0 -0
- package/package.json +20 -4
- package/src/components/chat/chat-box.tsx +195 -0
- package/src/components/chat/chat-message.tsx +192 -0
- package/src/components/chat/chat.tsx +128 -0
- package/src/components/chat/mention-suggestions.tsx +71 -0
- package/src/components/chat/mod-view.tsx +118 -0
- package/src/components/mobile-player/fullscreen.native.tsx +193 -0
- package/src/components/mobile-player/fullscreen.tsx +79 -0
- package/src/components/mobile-player/player.tsx +134 -0
- package/src/components/mobile-player/props.tsx +11 -0
- package/src/components/mobile-player/shared.tsx +56 -0
- package/src/components/mobile-player/ui/countdown.tsx +119 -0
- package/src/components/mobile-player/ui/index.ts +5 -0
- package/src/components/mobile-player/ui/input.tsx +85 -0
- package/src/components/mobile-player/ui/metrics.tsx +69 -0
- package/src/components/mobile-player/ui/streamer-context-menu.tsx +3 -0
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +70 -0
- package/src/components/mobile-player/use-webrtc.tsx +282 -0
- package/src/components/mobile-player/video.native.tsx +360 -0
- package/src/components/mobile-player/video.tsx +557 -0
- package/src/components/mobile-player/webrtc-diagnostics.tsx +149 -0
- package/src/components/mobile-player/webrtc-primitives.native.tsx +6 -0
- package/src/components/mobile-player/webrtc-primitives.tsx +33 -0
- package/src/components/ui/button.tsx +309 -0
- package/src/components/ui/dialog.tsx +376 -0
- package/src/components/ui/dropdown.tsx +399 -0
- package/src/components/ui/icons.tsx +50 -0
- package/src/components/ui/index.ts +33 -0
- package/src/components/ui/input.tsx +350 -0
- package/src/components/ui/loader.tsx +9 -0
- package/src/components/ui/primitives/button.tsx +292 -0
- package/src/components/ui/primitives/input.tsx +422 -0
- package/src/components/ui/primitives/modal.tsx +421 -0
- package/src/components/ui/primitives/text.tsx +499 -0
- package/src/components/ui/resizeable.tsx +169 -0
- package/src/components/ui/text.tsx +330 -0
- package/src/components/ui/textarea.tsx +34 -0
- package/src/components/ui/toast.tsx +203 -0
- package/src/components/ui/view.tsx +344 -0
- package/src/hooks/index.ts +9 -0
- package/src/hooks/useAvatars.tsx +44 -0
- package/src/hooks/useCameraToggle.ts +12 -0
- package/src/hooks/useKeyboard.tsx +41 -0
- package/src/hooks/useKeyboardSlide.ts +12 -0
- package/src/hooks/useLivestreamInfo.ts +67 -0
- package/src/hooks/useOuterAndInnerDimensions.tsx +32 -0
- package/src/hooks/usePlayerDimensions.ts +23 -0
- package/src/hooks/useSegmentTiming.tsx +88 -0
- package/src/index.tsx +21 -0
- package/src/lib/facet.ts +131 -0
- package/src/lib/theme/atoms.ts +760 -0
- package/src/lib/theme/atoms.types.ts +258 -0
- package/src/lib/theme/index.ts +48 -0
- package/src/lib/theme/theme.tsx +436 -0
- package/src/lib/theme/tokens.ts +409 -0
- package/src/lib/utils.ts +132 -0
- package/src/livestream-provider/index.tsx +13 -2
- package/src/livestream-store/chat.tsx +115 -78
- package/src/livestream-store/index.tsx +1 -0
- package/src/livestream-store/livestream-state.tsx +3 -0
- package/src/livestream-store/livestream-store.tsx +3 -0
- package/src/livestream-store/stream-key.tsx +124 -0
- package/src/player-store/player-provider.tsx +0 -1
- package/src/player-store/player-state.tsx +28 -0
- package/src/player-store/player-store.tsx +22 -0
- package/src/streamplace-store/block.tsx +29 -0
- package/src/streamplace-store/index.tsx +1 -0
- package/src/streamplace-store/stream.tsx +262 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PortalHost } from "@rn-primitives/portal";
|
|
3
|
+
import { createContext, useContext, useMemo, useState, } from "react";
|
|
4
|
+
import { Platform, useColorScheme } from "react-native";
|
|
5
|
+
import { animations, borderRadius, colors, shadows, spacing, touchTargets, typography, } from "./tokens";
|
|
6
|
+
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
|
7
|
+
// Create theme colors based on dark mode
|
|
8
|
+
const createThemeColors = (isDark) => ({
|
|
9
|
+
background: isDark ? colors.gray[950] : colors.white,
|
|
10
|
+
foreground: isDark ? colors.gray[50] : colors.gray[950],
|
|
11
|
+
card: isDark ? colors.gray[900] : colors.white,
|
|
12
|
+
cardForeground: isDark ? colors.gray[50] : colors.gray[950],
|
|
13
|
+
popover: isDark ? colors.gray[900] : colors.white,
|
|
14
|
+
popoverForeground: isDark ? colors.gray[50] : colors.gray[950],
|
|
15
|
+
primary: Platform.OS === "ios" ? colors.ios.systemBlue : colors.primary[500],
|
|
16
|
+
primaryForeground: colors.white,
|
|
17
|
+
secondary: isDark ? colors.gray[800] : colors.gray[100],
|
|
18
|
+
secondaryForeground: isDark ? colors.gray[50] : colors.gray[900],
|
|
19
|
+
muted: isDark ? colors.gray[800] : colors.gray[100],
|
|
20
|
+
mutedForeground: isDark ? colors.gray[400] : colors.gray[500],
|
|
21
|
+
accent: isDark ? colors.gray[800] : colors.gray[100],
|
|
22
|
+
accentForeground: isDark ? colors.gray[50] : colors.gray[900],
|
|
23
|
+
destructive: Platform.OS === "ios" ? colors.ios.systemRed : colors.destructive[500],
|
|
24
|
+
destructiveForeground: colors.white,
|
|
25
|
+
success: Platform.OS === "ios" ? colors.ios.systemGreen : colors.success[500],
|
|
26
|
+
successForeground: colors.white,
|
|
27
|
+
warning: Platform.OS === "ios" ? colors.ios.systemOrange : colors.warning[500],
|
|
28
|
+
warningForeground: colors.white,
|
|
29
|
+
border: isDark ? colors.gray[500] + "30" : colors.gray[200] + "30",
|
|
30
|
+
input: isDark ? colors.gray[800] : colors.gray[200],
|
|
31
|
+
ring: Platform.OS === "ios" ? colors.ios.systemBlue : colors.primary[500],
|
|
32
|
+
text: isDark ? colors.gray[50] : colors.gray[950],
|
|
33
|
+
textMuted: isDark ? colors.gray[400] : colors.gray[500],
|
|
34
|
+
textDisabled: isDark ? colors.gray[600] : colors.gray[400],
|
|
35
|
+
});
|
|
36
|
+
// Create theme styles based on colors
|
|
37
|
+
const createThemeStyles = (themeColors) => ({
|
|
38
|
+
shadow: {
|
|
39
|
+
sm: shadows.sm,
|
|
40
|
+
md: shadows.md,
|
|
41
|
+
lg: shadows.lg,
|
|
42
|
+
xl: shadows.xl,
|
|
43
|
+
},
|
|
44
|
+
button: {
|
|
45
|
+
primary: {
|
|
46
|
+
backgroundColor: themeColors.primary,
|
|
47
|
+
borderWidth: 0,
|
|
48
|
+
...shadows.sm,
|
|
49
|
+
},
|
|
50
|
+
secondary: {
|
|
51
|
+
backgroundColor: themeColors.secondary,
|
|
52
|
+
borderWidth: 0,
|
|
53
|
+
},
|
|
54
|
+
outline: {
|
|
55
|
+
backgroundColor: "transparent",
|
|
56
|
+
borderWidth: 1,
|
|
57
|
+
borderColor: themeColors.border,
|
|
58
|
+
},
|
|
59
|
+
ghost: {
|
|
60
|
+
backgroundColor: "transparent",
|
|
61
|
+
borderWidth: 0,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
text: {
|
|
65
|
+
primary: {
|
|
66
|
+
color: themeColors.text,
|
|
67
|
+
},
|
|
68
|
+
muted: {
|
|
69
|
+
color: themeColors.textMuted,
|
|
70
|
+
},
|
|
71
|
+
disabled: {
|
|
72
|
+
color: themeColors.textDisabled,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
input: {
|
|
76
|
+
base: {
|
|
77
|
+
backgroundColor: themeColors.background,
|
|
78
|
+
borderWidth: 1,
|
|
79
|
+
borderColor: themeColors.border,
|
|
80
|
+
borderRadius: borderRadius.md,
|
|
81
|
+
paddingHorizontal: spacing[3],
|
|
82
|
+
paddingVertical: spacing[3],
|
|
83
|
+
minHeight: touchTargets.minimum,
|
|
84
|
+
},
|
|
85
|
+
focused: {
|
|
86
|
+
borderColor: themeColors.ring,
|
|
87
|
+
borderWidth: 2,
|
|
88
|
+
},
|
|
89
|
+
error: {
|
|
90
|
+
borderColor: themeColors.destructive,
|
|
91
|
+
borderWidth: 2,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
card: {
|
|
95
|
+
base: {
|
|
96
|
+
backgroundColor: themeColors.card,
|
|
97
|
+
borderRadius: borderRadius.lg,
|
|
98
|
+
...shadows.sm,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
// Create theme icons based on colors
|
|
103
|
+
const createThemeIcons = (themeColors) => ({
|
|
104
|
+
color: {
|
|
105
|
+
default: themeColors.text,
|
|
106
|
+
muted: themeColors.textMuted,
|
|
107
|
+
primary: themeColors.primary,
|
|
108
|
+
secondary: themeColors.secondary,
|
|
109
|
+
destructive: themeColors.destructive,
|
|
110
|
+
success: themeColors.success,
|
|
111
|
+
warning: themeColors.warning,
|
|
112
|
+
},
|
|
113
|
+
size: {
|
|
114
|
+
sm: 16,
|
|
115
|
+
md: 20,
|
|
116
|
+
lg: 24,
|
|
117
|
+
xl: 32,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
// Create the theme context
|
|
121
|
+
const ThemeContext = createContext(null);
|
|
122
|
+
// Theme provider component
|
|
123
|
+
export function ThemeProvider({ children, defaultTheme = "system", forcedTheme, }) {
|
|
124
|
+
const systemColorScheme = useColorScheme();
|
|
125
|
+
const [currentTheme, setCurrentTheme] = useState(defaultTheme);
|
|
126
|
+
// Determine if dark mode should be active
|
|
127
|
+
const isDark = useMemo(() => {
|
|
128
|
+
if (forcedTheme === "light")
|
|
129
|
+
return false;
|
|
130
|
+
if (forcedTheme === "dark")
|
|
131
|
+
return true;
|
|
132
|
+
if (currentTheme === "light")
|
|
133
|
+
return false;
|
|
134
|
+
if (currentTheme === "dark")
|
|
135
|
+
return true;
|
|
136
|
+
if (currentTheme === "system")
|
|
137
|
+
return systemColorScheme === "dark";
|
|
138
|
+
return systemColorScheme === "dark";
|
|
139
|
+
}, [forcedTheme, currentTheme, systemColorScheme]);
|
|
140
|
+
// Create theme based on dark mode
|
|
141
|
+
const theme = useMemo(() => {
|
|
142
|
+
const themeColors = createThemeColors(isDark);
|
|
143
|
+
return {
|
|
144
|
+
colors: themeColors,
|
|
145
|
+
spacing,
|
|
146
|
+
borderRadius,
|
|
147
|
+
typography,
|
|
148
|
+
shadows,
|
|
149
|
+
touchTargets,
|
|
150
|
+
animations,
|
|
151
|
+
};
|
|
152
|
+
}, [isDark]);
|
|
153
|
+
// Create utility styles
|
|
154
|
+
const styles = useMemo(() => {
|
|
155
|
+
return createThemeStyles(theme.colors);
|
|
156
|
+
}, [theme.colors]);
|
|
157
|
+
// Create icon utilities
|
|
158
|
+
const icons = useMemo(() => {
|
|
159
|
+
return createThemeIcons(theme.colors);
|
|
160
|
+
}, [theme.colors]);
|
|
161
|
+
// Theme controls
|
|
162
|
+
const setTheme = (newTheme) => {
|
|
163
|
+
if (!forcedTheme) {
|
|
164
|
+
setCurrentTheme(newTheme);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const toggleTheme = () => {
|
|
168
|
+
if (!forcedTheme) {
|
|
169
|
+
setCurrentTheme((prev) => {
|
|
170
|
+
if (prev === "light")
|
|
171
|
+
return "dark";
|
|
172
|
+
if (prev === "dark")
|
|
173
|
+
return "system";
|
|
174
|
+
return "light";
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const value = useMemo(() => ({
|
|
179
|
+
theme,
|
|
180
|
+
styles,
|
|
181
|
+
icons,
|
|
182
|
+
isDark,
|
|
183
|
+
currentTheme: forcedTheme || currentTheme,
|
|
184
|
+
systemTheme: systemColorScheme || "light",
|
|
185
|
+
setTheme,
|
|
186
|
+
toggleTheme,
|
|
187
|
+
}), [
|
|
188
|
+
theme,
|
|
189
|
+
styles,
|
|
190
|
+
icons,
|
|
191
|
+
isDark,
|
|
192
|
+
forcedTheme,
|
|
193
|
+
currentTheme,
|
|
194
|
+
systemColorScheme,
|
|
195
|
+
setTheme,
|
|
196
|
+
toggleTheme,
|
|
197
|
+
]);
|
|
198
|
+
return (_jsx(ThemeContext.Provider, { value: value, children: _jsxs(GestureHandlerRootView, { children: [children, _jsx(PortalHost, {})] }) }));
|
|
199
|
+
}
|
|
200
|
+
// Hook to use theme
|
|
201
|
+
export function useTheme() {
|
|
202
|
+
const context = useContext(ThemeContext);
|
|
203
|
+
if (!context) {
|
|
204
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
205
|
+
}
|
|
206
|
+
return context;
|
|
207
|
+
}
|
|
208
|
+
// Hook to get current platform's typography
|
|
209
|
+
export function usePlatformTypography() {
|
|
210
|
+
const { theme } = useTheme();
|
|
211
|
+
return useMemo(() => {
|
|
212
|
+
if (Platform.OS === "ios") {
|
|
213
|
+
return theme.typography.ios;
|
|
214
|
+
}
|
|
215
|
+
else if (Platform.OS === "android") {
|
|
216
|
+
return theme.typography.android;
|
|
217
|
+
}
|
|
218
|
+
return theme.typography.universal;
|
|
219
|
+
}, [theme.typography]);
|
|
220
|
+
}
|
|
221
|
+
// Utility function to create theme-aware styles
|
|
222
|
+
export function createThemedStyles(styleCreator) {
|
|
223
|
+
return function useThemedStyles() {
|
|
224
|
+
const { theme, styles, icons } = useTheme();
|
|
225
|
+
return useMemo(() => styleCreator(theme, styles, icons), [theme, styles, icons]);
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
// Create light and dark theme instances for external use
|
|
229
|
+
export const lightTheme = {
|
|
230
|
+
colors: createThemeColors(false),
|
|
231
|
+
spacing,
|
|
232
|
+
borderRadius,
|
|
233
|
+
typography,
|
|
234
|
+
shadows,
|
|
235
|
+
touchTargets,
|
|
236
|
+
animations,
|
|
237
|
+
};
|
|
238
|
+
export const darkTheme = {
|
|
239
|
+
colors: createThemeColors(true),
|
|
240
|
+
spacing,
|
|
241
|
+
borderRadius,
|
|
242
|
+
typography,
|
|
243
|
+
shadows,
|
|
244
|
+
touchTargets,
|
|
245
|
+
animations,
|
|
246
|
+
};
|
|
247
|
+
// Export individual theme utilities for convenience
|
|
248
|
+
export { createThemeColors, createThemeIcons, createThemeStyles };
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens for React Native components
|
|
3
|
+
* Inspired by shadcn/ui but adapted for React Native styling
|
|
4
|
+
*/
|
|
5
|
+
export const colors = {
|
|
6
|
+
// Primary colors
|
|
7
|
+
primary: {
|
|
8
|
+
50: "#eff6ff",
|
|
9
|
+
100: "#dbeafe",
|
|
10
|
+
200: "#bfdbfe",
|
|
11
|
+
300: "#93c5fd",
|
|
12
|
+
400: "#60a5fa",
|
|
13
|
+
500: "#3b82f6",
|
|
14
|
+
600: "#2563eb",
|
|
15
|
+
700: "#1d4ed8",
|
|
16
|
+
800: "#1e40af",
|
|
17
|
+
900: "#1e3a8a",
|
|
18
|
+
950: "#172554",
|
|
19
|
+
},
|
|
20
|
+
// Grayscale
|
|
21
|
+
gray: {
|
|
22
|
+
50: "#fafafa",
|
|
23
|
+
100: "#f5f5f5",
|
|
24
|
+
200: "#e5e5e5",
|
|
25
|
+
300: "#d4d4d4",
|
|
26
|
+
400: "#a3a3a3",
|
|
27
|
+
500: "#737373",
|
|
28
|
+
600: "#525252",
|
|
29
|
+
700: "#404040",
|
|
30
|
+
800: "#262626",
|
|
31
|
+
900: "#171717",
|
|
32
|
+
950: "#0d0d0d",
|
|
33
|
+
},
|
|
34
|
+
// Semantic colors
|
|
35
|
+
destructive: {
|
|
36
|
+
50: "#fef2f2",
|
|
37
|
+
100: "#fee2e2",
|
|
38
|
+
200: "#fecaca",
|
|
39
|
+
300: "#fca5a5",
|
|
40
|
+
400: "#f87171",
|
|
41
|
+
500: "#ef4444",
|
|
42
|
+
600: "#dc2626",
|
|
43
|
+
700: "#b91c1c",
|
|
44
|
+
800: "#991b1b",
|
|
45
|
+
900: "#7f1d1d",
|
|
46
|
+
950: "#450a0a",
|
|
47
|
+
},
|
|
48
|
+
success: {
|
|
49
|
+
50: "#f0fdf4",
|
|
50
|
+
100: "#dcfce7",
|
|
51
|
+
200: "#bbf7d0",
|
|
52
|
+
300: "#86efac",
|
|
53
|
+
400: "#4ade80",
|
|
54
|
+
500: "#22c55e",
|
|
55
|
+
600: "#16a34a",
|
|
56
|
+
700: "#15803d",
|
|
57
|
+
800: "#166534",
|
|
58
|
+
900: "#14532d",
|
|
59
|
+
950: "#052e16",
|
|
60
|
+
},
|
|
61
|
+
warning: {
|
|
62
|
+
50: "#fffbeb",
|
|
63
|
+
100: "#fef3c7",
|
|
64
|
+
200: "#fde68a",
|
|
65
|
+
300: "#fcd34d",
|
|
66
|
+
400: "#fbbf24",
|
|
67
|
+
500: "#f59e0b",
|
|
68
|
+
600: "#d97706",
|
|
69
|
+
700: "#b45309",
|
|
70
|
+
800: "#92400e",
|
|
71
|
+
900: "#78350f",
|
|
72
|
+
950: "#451a03",
|
|
73
|
+
},
|
|
74
|
+
// iOS system colors (adaptive)
|
|
75
|
+
ios: {
|
|
76
|
+
systemBlue: "#007AFF",
|
|
77
|
+
systemGreen: "#34C759",
|
|
78
|
+
systemRed: "#FF3B30",
|
|
79
|
+
systemOrange: "#FF9500",
|
|
80
|
+
systemYellow: "#FFCC00",
|
|
81
|
+
systemPurple: "#AF52DE",
|
|
82
|
+
systemPink: "#FF2D92",
|
|
83
|
+
systemTeal: "#5AC8FA",
|
|
84
|
+
systemIndigo: "#5856D6",
|
|
85
|
+
systemGray: "#8E8E93",
|
|
86
|
+
systemGray2: "#AEAEB2",
|
|
87
|
+
systemGray3: "#C7C7CC",
|
|
88
|
+
systemGray4: "#D1D1D6",
|
|
89
|
+
systemGray5: "#E5E5EA",
|
|
90
|
+
systemGray6: "#F2F2F7",
|
|
91
|
+
},
|
|
92
|
+
// Android Material colors
|
|
93
|
+
android: {
|
|
94
|
+
primary: "#6200EE",
|
|
95
|
+
primaryVariant: "#3700B3",
|
|
96
|
+
secondary: "#03DAC6",
|
|
97
|
+
secondaryVariant: "#018786",
|
|
98
|
+
background: "#FFFFFF",
|
|
99
|
+
surface: "#FFFFFF",
|
|
100
|
+
error: "#B00020",
|
|
101
|
+
onPrimary: "#FFFFFF",
|
|
102
|
+
onSecondary: "#000000",
|
|
103
|
+
onBackground: "#000000",
|
|
104
|
+
onSurface: "#000000",
|
|
105
|
+
onError: "#FFFFFF",
|
|
106
|
+
},
|
|
107
|
+
// Transparent colors
|
|
108
|
+
transparent: "transparent",
|
|
109
|
+
black: "#000000",
|
|
110
|
+
white: "#FFFFFF",
|
|
111
|
+
};
|
|
112
|
+
export const spacing = {
|
|
113
|
+
0: 0,
|
|
114
|
+
1: 4,
|
|
115
|
+
2: 8,
|
|
116
|
+
3: 12,
|
|
117
|
+
4: 16,
|
|
118
|
+
5: 20,
|
|
119
|
+
6: 24,
|
|
120
|
+
7: 28,
|
|
121
|
+
8: 32,
|
|
122
|
+
9: 36,
|
|
123
|
+
10: 40,
|
|
124
|
+
11: 44,
|
|
125
|
+
12: 48,
|
|
126
|
+
14: 56,
|
|
127
|
+
16: 64,
|
|
128
|
+
20: 80,
|
|
129
|
+
24: 96,
|
|
130
|
+
28: 112,
|
|
131
|
+
32: 128,
|
|
132
|
+
36: 144,
|
|
133
|
+
40: 160,
|
|
134
|
+
44: 176,
|
|
135
|
+
48: 192,
|
|
136
|
+
52: 208,
|
|
137
|
+
56: 224,
|
|
138
|
+
60: 240,
|
|
139
|
+
64: 256,
|
|
140
|
+
72: 288,
|
|
141
|
+
80: 320,
|
|
142
|
+
96: 384,
|
|
143
|
+
auto: "auto",
|
|
144
|
+
};
|
|
145
|
+
export const borderRadius = {
|
|
146
|
+
none: 0,
|
|
147
|
+
sm: 4,
|
|
148
|
+
md: 8,
|
|
149
|
+
lg: 12,
|
|
150
|
+
xl: 16,
|
|
151
|
+
"2xl": 20,
|
|
152
|
+
"3xl": 24,
|
|
153
|
+
full: 999,
|
|
154
|
+
};
|
|
155
|
+
export const typography = {
|
|
156
|
+
// iOS system font sizes
|
|
157
|
+
ios: {
|
|
158
|
+
largeTitle: {
|
|
159
|
+
fontSize: 34,
|
|
160
|
+
lineHeight: 41,
|
|
161
|
+
fontWeight: "700",
|
|
162
|
+
},
|
|
163
|
+
title1: {
|
|
164
|
+
fontSize: 28,
|
|
165
|
+
lineHeight: 34,
|
|
166
|
+
fontWeight: "700",
|
|
167
|
+
},
|
|
168
|
+
title2: {
|
|
169
|
+
fontSize: 22,
|
|
170
|
+
lineHeight: 28,
|
|
171
|
+
fontWeight: "700",
|
|
172
|
+
},
|
|
173
|
+
title3: {
|
|
174
|
+
fontSize: 20,
|
|
175
|
+
lineHeight: 25,
|
|
176
|
+
fontWeight: "600",
|
|
177
|
+
},
|
|
178
|
+
headline: {
|
|
179
|
+
fontSize: 17,
|
|
180
|
+
lineHeight: 22,
|
|
181
|
+
fontWeight: "600",
|
|
182
|
+
},
|
|
183
|
+
body: {
|
|
184
|
+
fontSize: 17,
|
|
185
|
+
lineHeight: 22,
|
|
186
|
+
fontWeight: "400",
|
|
187
|
+
},
|
|
188
|
+
callout: {
|
|
189
|
+
fontSize: 16,
|
|
190
|
+
lineHeight: 21,
|
|
191
|
+
fontWeight: "400",
|
|
192
|
+
},
|
|
193
|
+
subhead: {
|
|
194
|
+
fontSize: 15,
|
|
195
|
+
lineHeight: 20,
|
|
196
|
+
fontWeight: "400",
|
|
197
|
+
},
|
|
198
|
+
footnote: {
|
|
199
|
+
fontSize: 13,
|
|
200
|
+
lineHeight: 18,
|
|
201
|
+
fontWeight: "400",
|
|
202
|
+
},
|
|
203
|
+
caption1: {
|
|
204
|
+
fontSize: 12,
|
|
205
|
+
lineHeight: 16,
|
|
206
|
+
fontWeight: "400",
|
|
207
|
+
},
|
|
208
|
+
caption2: {
|
|
209
|
+
fontSize: 11,
|
|
210
|
+
lineHeight: 13,
|
|
211
|
+
fontWeight: "400",
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
// Android Material typography
|
|
215
|
+
android: {
|
|
216
|
+
headline1: {
|
|
217
|
+
fontSize: 96,
|
|
218
|
+
lineHeight: 112,
|
|
219
|
+
fontWeight: "300",
|
|
220
|
+
},
|
|
221
|
+
headline2: {
|
|
222
|
+
fontSize: 60,
|
|
223
|
+
lineHeight: 72,
|
|
224
|
+
fontWeight: "300",
|
|
225
|
+
},
|
|
226
|
+
headline3: {
|
|
227
|
+
fontSize: 48,
|
|
228
|
+
lineHeight: 56,
|
|
229
|
+
fontWeight: "400",
|
|
230
|
+
},
|
|
231
|
+
headline4: {
|
|
232
|
+
fontSize: 34,
|
|
233
|
+
lineHeight: 42,
|
|
234
|
+
fontWeight: "400",
|
|
235
|
+
},
|
|
236
|
+
headline5: {
|
|
237
|
+
fontSize: 24,
|
|
238
|
+
lineHeight: 32,
|
|
239
|
+
fontWeight: "400",
|
|
240
|
+
},
|
|
241
|
+
headline6: {
|
|
242
|
+
fontSize: 20,
|
|
243
|
+
lineHeight: 28,
|
|
244
|
+
fontWeight: "500",
|
|
245
|
+
},
|
|
246
|
+
subtitle1: {
|
|
247
|
+
fontSize: 16,
|
|
248
|
+
lineHeight: 24,
|
|
249
|
+
fontWeight: "400",
|
|
250
|
+
},
|
|
251
|
+
subtitle2: {
|
|
252
|
+
fontSize: 14,
|
|
253
|
+
lineHeight: 22,
|
|
254
|
+
fontWeight: "500",
|
|
255
|
+
},
|
|
256
|
+
body1: {
|
|
257
|
+
fontSize: 16,
|
|
258
|
+
lineHeight: 24,
|
|
259
|
+
fontWeight: "400",
|
|
260
|
+
},
|
|
261
|
+
body2: {
|
|
262
|
+
fontSize: 14,
|
|
263
|
+
lineHeight: 20,
|
|
264
|
+
fontWeight: "400",
|
|
265
|
+
},
|
|
266
|
+
button: {
|
|
267
|
+
fontSize: 14,
|
|
268
|
+
lineHeight: 16,
|
|
269
|
+
fontWeight: "500",
|
|
270
|
+
},
|
|
271
|
+
caption: {
|
|
272
|
+
fontSize: 12,
|
|
273
|
+
lineHeight: 16,
|
|
274
|
+
fontWeight: "400",
|
|
275
|
+
},
|
|
276
|
+
overline: {
|
|
277
|
+
fontSize: 10,
|
|
278
|
+
lineHeight: 16,
|
|
279
|
+
fontWeight: "400",
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
// Universal typography scale
|
|
283
|
+
universal: {
|
|
284
|
+
xs: {
|
|
285
|
+
fontSize: 12,
|
|
286
|
+
lineHeight: 16,
|
|
287
|
+
fontWeight: "400",
|
|
288
|
+
},
|
|
289
|
+
sm: {
|
|
290
|
+
fontSize: 14,
|
|
291
|
+
lineHeight: 20,
|
|
292
|
+
fontWeight: "400",
|
|
293
|
+
},
|
|
294
|
+
base: {
|
|
295
|
+
fontSize: 16,
|
|
296
|
+
lineHeight: 24,
|
|
297
|
+
fontWeight: "400",
|
|
298
|
+
},
|
|
299
|
+
lg: {
|
|
300
|
+
fontSize: 18,
|
|
301
|
+
lineHeight: 28,
|
|
302
|
+
fontWeight: "400",
|
|
303
|
+
},
|
|
304
|
+
xl: {
|
|
305
|
+
fontSize: 20,
|
|
306
|
+
lineHeight: 28,
|
|
307
|
+
fontWeight: "500",
|
|
308
|
+
},
|
|
309
|
+
"2xl": {
|
|
310
|
+
fontSize: 24,
|
|
311
|
+
lineHeight: 32,
|
|
312
|
+
fontWeight: "600",
|
|
313
|
+
},
|
|
314
|
+
"3xl": {
|
|
315
|
+
fontSize: 30,
|
|
316
|
+
lineHeight: 36,
|
|
317
|
+
fontWeight: "700",
|
|
318
|
+
},
|
|
319
|
+
"4xl": {
|
|
320
|
+
fontSize: 36,
|
|
321
|
+
lineHeight: 40,
|
|
322
|
+
fontWeight: "700",
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
export const shadows = {
|
|
327
|
+
none: {
|
|
328
|
+
shadowColor: "transparent",
|
|
329
|
+
shadowOffset: { width: 0, height: 0 },
|
|
330
|
+
shadowOpacity: 0,
|
|
331
|
+
shadowRadius: 0,
|
|
332
|
+
elevation: 0,
|
|
333
|
+
},
|
|
334
|
+
sm: {
|
|
335
|
+
shadowColor: colors.black,
|
|
336
|
+
shadowOffset: { width: 0, height: 1 },
|
|
337
|
+
shadowOpacity: 0.05,
|
|
338
|
+
shadowRadius: 2,
|
|
339
|
+
elevation: 2,
|
|
340
|
+
},
|
|
341
|
+
md: {
|
|
342
|
+
shadowColor: colors.black,
|
|
343
|
+
shadowOffset: { width: 0, height: 2 },
|
|
344
|
+
shadowOpacity: 0.1,
|
|
345
|
+
shadowRadius: 4,
|
|
346
|
+
elevation: 4,
|
|
347
|
+
},
|
|
348
|
+
lg: {
|
|
349
|
+
shadowColor: colors.black,
|
|
350
|
+
shadowOffset: { width: 0, height: 4 },
|
|
351
|
+
shadowOpacity: 0.15,
|
|
352
|
+
shadowRadius: 8,
|
|
353
|
+
elevation: 8,
|
|
354
|
+
},
|
|
355
|
+
xl: {
|
|
356
|
+
shadowColor: colors.black,
|
|
357
|
+
shadowOffset: { width: 0, height: 8 },
|
|
358
|
+
shadowOpacity: 0.2,
|
|
359
|
+
shadowRadius: 16,
|
|
360
|
+
elevation: 16,
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
// Touch targets (iOS Human Interface Guidelines)
|
|
364
|
+
export const touchTargets = {
|
|
365
|
+
minimum: 44, // Minimum touch target size
|
|
366
|
+
comfortable: 48, // Comfortable touch target size
|
|
367
|
+
large: 56, // Large touch target size
|
|
368
|
+
};
|
|
369
|
+
// Animation durations
|
|
370
|
+
export const animations = {
|
|
371
|
+
fast: 150,
|
|
372
|
+
normal: 200,
|
|
373
|
+
slow: 300,
|
|
374
|
+
slower: 500,
|
|
375
|
+
};
|
|
376
|
+
// Breakpoints for responsive design
|
|
377
|
+
export const breakpoints = {
|
|
378
|
+
sm: 640,
|
|
379
|
+
md: 768,
|
|
380
|
+
lg: 1024,
|
|
381
|
+
xl: 1280,
|
|
382
|
+
"2xl": 1536,
|
|
383
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
/**
|
|
3
|
+
* Merges React Native styles similar to how cn() merges CSS classes
|
|
4
|
+
* Handles arrays, objects, and falsy values
|
|
5
|
+
*/
|
|
6
|
+
export function mergeStyles(...styles) {
|
|
7
|
+
const validStyles = styles.filter(Boolean).flat();
|
|
8
|
+
return StyleSheet.flatten(validStyles) || {};
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Creates a style merger function that includes base styles
|
|
12
|
+
* Useful for component variants
|
|
13
|
+
*/
|
|
14
|
+
export function createStyleMerger(baseStyle) {
|
|
15
|
+
return (...styles) => {
|
|
16
|
+
return mergeStyles(baseStyle, ...styles);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Conditionally applies styles based on boolean conditions
|
|
21
|
+
*/
|
|
22
|
+
export function conditionalStyle(condition, trueStyle, falseStyle) {
|
|
23
|
+
return condition ? trueStyle : falseStyle;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates responsive values based on screen dimensions
|
|
27
|
+
*/
|
|
28
|
+
export function responsiveValue(values, screenWidth) {
|
|
29
|
+
if (screenWidth >= 1280 && values.xl !== undefined)
|
|
30
|
+
return values.xl;
|
|
31
|
+
if (screenWidth >= 1024 && values.lg !== undefined)
|
|
32
|
+
return values.lg;
|
|
33
|
+
if (screenWidth >= 768 && values.md !== undefined)
|
|
34
|
+
return values.md;
|
|
35
|
+
if (screenWidth >= 640 && values.sm !== undefined)
|
|
36
|
+
return values.sm;
|
|
37
|
+
return values.default;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Creates platform-specific styles
|
|
41
|
+
*/
|
|
42
|
+
export function platformStyle(styles) {
|
|
43
|
+
const Platform = require("react-native").Platform;
|
|
44
|
+
if (Platform.OS === "ios" && styles.ios)
|
|
45
|
+
return styles.ios;
|
|
46
|
+
if (Platform.OS === "android" && styles.android)
|
|
47
|
+
return styles.android;
|
|
48
|
+
if (Platform.OS === "web" && styles.web)
|
|
49
|
+
return styles.web;
|
|
50
|
+
return styles.default || {};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Converts hex color to rgba
|
|
54
|
+
*/
|
|
55
|
+
export function hexToRgba(hex, alpha = 1) {
|
|
56
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
57
|
+
if (!result)
|
|
58
|
+
return hex;
|
|
59
|
+
const r = parseInt(result[1], 16);
|
|
60
|
+
const g = parseInt(result[2], 16);
|
|
61
|
+
const b = parseInt(result[3], 16);
|
|
62
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Creates a debounced function for performance
|
|
66
|
+
*/
|
|
67
|
+
export function debounce(func, delay) {
|
|
68
|
+
let timeoutId;
|
|
69
|
+
return (...args) => {
|
|
70
|
+
clearTimeout(timeoutId);
|
|
71
|
+
timeoutId = setTimeout(() => func(...args), delay);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Creates a throttled function for performance
|
|
76
|
+
*/
|
|
77
|
+
export function throttle(func, delay) {
|
|
78
|
+
let lastCall = 0;
|
|
79
|
+
return (...args) => {
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
if (now - lastCall >= delay) {
|
|
82
|
+
lastCall = now;
|
|
83
|
+
func(...args);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Type-safe component prop forwarding
|
|
89
|
+
*/
|
|
90
|
+
export function forwardProps(props, omit) {
|
|
91
|
+
const result = { ...props };
|
|
92
|
+
omit.forEach((key) => delete result[key]);
|
|
93
|
+
return result;
|
|
94
|
+
}
|