@streamplace/components 0.0.1 → 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.
Files changed (169) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +35 -0
  3. package/dist/components/chat/chat-box.js +109 -0
  4. package/dist/components/chat/chat-message.js +76 -0
  5. package/dist/components/chat/chat.js +56 -0
  6. package/dist/components/chat/mention-suggestions.js +39 -0
  7. package/dist/components/chat/mod-view.js +33 -0
  8. package/dist/components/mobile-player/fullscreen.js +69 -0
  9. package/dist/components/mobile-player/fullscreen.native.js +151 -0
  10. package/dist/components/mobile-player/player.js +103 -0
  11. package/dist/components/mobile-player/props.js +1 -0
  12. package/dist/components/mobile-player/shared.js +51 -0
  13. package/dist/components/mobile-player/ui/countdown.js +79 -0
  14. package/dist/components/mobile-player/ui/index.js +5 -0
  15. package/dist/components/mobile-player/ui/input.js +38 -0
  16. package/dist/components/mobile-player/ui/metrics.js +40 -0
  17. package/dist/components/mobile-player/ui/streamer-context-menu.js +4 -0
  18. package/dist/components/mobile-player/ui/viewer-context-menu.js +20 -0
  19. package/dist/components/mobile-player/use-webrtc.js +232 -0
  20. package/dist/components/mobile-player/video.js +375 -0
  21. package/dist/components/mobile-player/video.native.js +238 -0
  22. package/dist/components/mobile-player/webrtc-diagnostics.js +106 -0
  23. package/dist/components/mobile-player/webrtc-primitives.js +25 -0
  24. package/dist/components/mobile-player/webrtc-primitives.native.js +1 -0
  25. package/dist/components/ui/button.js +220 -0
  26. package/dist/components/ui/dialog.js +203 -0
  27. package/dist/components/ui/dropdown.js +148 -0
  28. package/dist/components/ui/icons.js +22 -0
  29. package/dist/components/ui/index.js +22 -0
  30. package/dist/components/ui/input.js +202 -0
  31. package/dist/components/ui/loader.js +7 -0
  32. package/dist/components/ui/primitives/button.js +121 -0
  33. package/dist/components/ui/primitives/input.js +202 -0
  34. package/dist/components/ui/primitives/modal.js +203 -0
  35. package/dist/components/ui/primitives/text.js +286 -0
  36. package/dist/components/ui/resizeable.js +101 -0
  37. package/dist/components/ui/text.js +175 -0
  38. package/dist/components/ui/textarea.js +17 -0
  39. package/dist/components/ui/toast.js +129 -0
  40. package/dist/components/ui/view.js +250 -0
  41. package/dist/hooks/index.js +9 -0
  42. package/dist/hooks/useAvatars.js +32 -0
  43. package/dist/hooks/useCameraToggle.js +9 -0
  44. package/dist/hooks/useKeyboard.js +33 -0
  45. package/dist/hooks/useKeyboardSlide.js +11 -0
  46. package/dist/hooks/useLivestreamInfo.js +62 -0
  47. package/dist/hooks/useOuterAndInnerDimensions.js +27 -0
  48. package/dist/hooks/usePlayerDimensions.js +19 -0
  49. package/dist/hooks/useSegmentTiming.js +62 -0
  50. package/dist/index.js +16 -0
  51. package/dist/lib/facet.js +88 -0
  52. package/dist/lib/theme/atoms.js +620 -0
  53. package/dist/lib/theme/atoms.types.js +5 -0
  54. package/dist/lib/theme/index.js +9 -0
  55. package/dist/lib/theme/theme.js +248 -0
  56. package/dist/lib/theme/tokens.js +383 -0
  57. package/dist/lib/utils.js +94 -0
  58. package/dist/livestream-provider/index.js +25 -0
  59. package/dist/livestream-provider/websocket.js +41 -0
  60. package/dist/livestream-store/chat.js +186 -0
  61. package/dist/livestream-store/context.js +2 -0
  62. package/dist/livestream-store/index.js +4 -0
  63. package/dist/livestream-store/livestream-state.js +1 -0
  64. package/dist/livestream-store/livestream-store.js +42 -0
  65. package/dist/livestream-store/stream-key.js +115 -0
  66. package/dist/livestream-store/websocket-consumer.js +55 -0
  67. package/dist/player-store/context.js +2 -0
  68. package/dist/player-store/index.js +6 -0
  69. package/dist/player-store/player-provider.js +52 -0
  70. package/dist/player-store/player-state.js +22 -0
  71. package/dist/player-store/player-store.js +159 -0
  72. package/dist/player-store/single-player-provider.js +109 -0
  73. package/dist/streamplace-provider/context.js +2 -0
  74. package/dist/streamplace-provider/index.js +16 -0
  75. package/dist/streamplace-provider/poller.js +46 -0
  76. package/dist/streamplace-provider/xrpc.js +0 -0
  77. package/dist/streamplace-store/block.js +23 -0
  78. package/dist/streamplace-store/index.js +3 -0
  79. package/dist/streamplace-store/stream.js +193 -0
  80. package/dist/streamplace-store/streamplace-store.js +37 -0
  81. package/dist/streamplace-store/user.js +47 -0
  82. package/dist/streamplace-store/xrpc.js +12 -0
  83. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
  84. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/56540125 +0 -0
  85. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/67b1eb60 +0 -0
  86. package/node-compile-cache/v22.15.0-x64-efe9a9df-0/7c275f90 +0 -0
  87. package/package.json +50 -8
  88. package/src/components/chat/chat-box.tsx +195 -0
  89. package/src/components/chat/chat-message.tsx +192 -0
  90. package/src/components/chat/chat.tsx +128 -0
  91. package/src/components/chat/mention-suggestions.tsx +71 -0
  92. package/src/components/chat/mod-view.tsx +118 -0
  93. package/src/components/mobile-player/fullscreen.native.tsx +193 -0
  94. package/src/components/mobile-player/fullscreen.tsx +79 -0
  95. package/src/components/mobile-player/player.tsx +134 -0
  96. package/src/components/mobile-player/props.tsx +11 -0
  97. package/src/components/mobile-player/shared.tsx +56 -0
  98. package/src/components/mobile-player/ui/countdown.tsx +119 -0
  99. package/src/components/mobile-player/ui/index.ts +5 -0
  100. package/src/components/mobile-player/ui/input.tsx +85 -0
  101. package/src/components/mobile-player/ui/metrics.tsx +69 -0
  102. package/src/components/mobile-player/ui/streamer-context-menu.tsx +3 -0
  103. package/src/components/mobile-player/ui/viewer-context-menu.tsx +70 -0
  104. package/src/components/mobile-player/use-webrtc.tsx +282 -0
  105. package/src/components/mobile-player/video.native.tsx +360 -0
  106. package/src/components/mobile-player/video.tsx +557 -0
  107. package/src/components/mobile-player/webrtc-diagnostics.tsx +149 -0
  108. package/src/components/mobile-player/webrtc-primitives.native.tsx +6 -0
  109. package/src/components/mobile-player/webrtc-primitives.tsx +33 -0
  110. package/src/components/ui/button.tsx +309 -0
  111. package/src/components/ui/dialog.tsx +376 -0
  112. package/src/components/ui/dropdown.tsx +399 -0
  113. package/src/components/ui/icons.tsx +50 -0
  114. package/src/components/ui/index.ts +33 -0
  115. package/src/components/ui/input.tsx +350 -0
  116. package/src/components/ui/loader.tsx +9 -0
  117. package/src/components/ui/primitives/button.tsx +292 -0
  118. package/src/components/ui/primitives/input.tsx +422 -0
  119. package/src/components/ui/primitives/modal.tsx +421 -0
  120. package/src/components/ui/primitives/text.tsx +499 -0
  121. package/src/components/ui/resizeable.tsx +169 -0
  122. package/src/components/ui/text.tsx +330 -0
  123. package/src/components/ui/textarea.tsx +34 -0
  124. package/src/components/ui/toast.tsx +203 -0
  125. package/src/components/ui/view.tsx +344 -0
  126. package/src/hooks/index.ts +9 -0
  127. package/src/hooks/useAvatars.tsx +44 -0
  128. package/src/hooks/useCameraToggle.ts +12 -0
  129. package/src/hooks/useKeyboard.tsx +41 -0
  130. package/src/hooks/useKeyboardSlide.ts +12 -0
  131. package/src/hooks/useLivestreamInfo.ts +67 -0
  132. package/src/hooks/useOuterAndInnerDimensions.tsx +32 -0
  133. package/src/hooks/usePlayerDimensions.ts +23 -0
  134. package/src/hooks/useSegmentTiming.tsx +88 -0
  135. package/src/index.tsx +27 -0
  136. package/src/lib/facet.ts +131 -0
  137. package/src/lib/theme/atoms.ts +760 -0
  138. package/src/lib/theme/atoms.types.ts +258 -0
  139. package/src/lib/theme/index.ts +48 -0
  140. package/src/lib/theme/theme.tsx +436 -0
  141. package/src/lib/theme/tokens.ts +409 -0
  142. package/src/lib/utils.ts +132 -0
  143. package/src/livestream-provider/index.tsx +48 -0
  144. package/src/livestream-provider/websocket.tsx +47 -0
  145. package/src/livestream-store/chat.tsx +261 -0
  146. package/src/livestream-store/context.tsx +10 -0
  147. package/src/livestream-store/index.tsx +4 -0
  148. package/src/livestream-store/livestream-state.tsx +21 -0
  149. package/src/livestream-store/livestream-store.tsx +59 -0
  150. package/src/livestream-store/stream-key.tsx +124 -0
  151. package/src/livestream-store/websocket-consumer.tsx +62 -0
  152. package/src/player-store/context.tsx +11 -0
  153. package/src/player-store/index.tsx +6 -0
  154. package/src/player-store/player-provider.tsx +89 -0
  155. package/src/player-store/player-state.tsx +187 -0
  156. package/src/player-store/player-store.tsx +239 -0
  157. package/src/player-store/single-player-provider.tsx +181 -0
  158. package/src/streamplace-provider/context.tsx +10 -0
  159. package/src/streamplace-provider/index.tsx +32 -0
  160. package/src/streamplace-provider/poller.tsx +55 -0
  161. package/src/streamplace-provider/xrpc.tsx +0 -0
  162. package/src/streamplace-store/block.tsx +29 -0
  163. package/src/streamplace-store/index.tsx +3 -0
  164. package/src/streamplace-store/stream.tsx +262 -0
  165. package/src/streamplace-store/streamplace-store.tsx +89 -0
  166. package/src/streamplace-store/user.tsx +57 -0
  167. package/src/streamplace-store/xrpc.tsx +15 -0
  168. package/tsconfig.json +9 -0
  169. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,422 @@
1
+ import React, { forwardRef } from "react";
2
+ import {
3
+ NativeSyntheticEvent,
4
+ Platform,
5
+ StyleSheet,
6
+ Text,
7
+ TextInput,
8
+ TextInputFocusEventData,
9
+ TextInputProps,
10
+ TextProps,
11
+ TouchableOpacity,
12
+ View,
13
+ ViewProps,
14
+ } from "react-native";
15
+
16
+ // Base input primitive interface
17
+ export interface InputPrimitiveProps extends Omit<TextInputProps, "onChange"> {
18
+ error?: boolean;
19
+ disabled?: boolean;
20
+ loading?: boolean;
21
+ onChange?: (text: string) => void;
22
+ onFocus?: (event: NativeSyntheticEvent<TextInputFocusEventData>) => void;
23
+ onBlur?: (event: NativeSyntheticEvent<TextInputFocusEventData>) => void;
24
+ }
25
+
26
+ // Input root primitive - the main TextInput component
27
+ export const InputRoot = forwardRef<TextInput, InputPrimitiveProps>(
28
+ (
29
+ {
30
+ value,
31
+ onChangeText,
32
+ onChange,
33
+ onFocus,
34
+ onBlur,
35
+ error = false,
36
+ disabled = false,
37
+ loading = false,
38
+ editable,
39
+ style,
40
+ placeholderTextColor = "#9ca3af",
41
+ ...props
42
+ },
43
+ ref,
44
+ ) => {
45
+ const [isFocused, setIsFocused] = React.useState(false);
46
+
47
+ const handleChangeText = React.useCallback(
48
+ (text: string) => {
49
+ if (onChangeText) {
50
+ onChangeText(text);
51
+ }
52
+ if (onChange) {
53
+ onChange(text);
54
+ }
55
+ },
56
+ [onChangeText, onChange],
57
+ );
58
+
59
+ const handleFocus = React.useCallback(
60
+ (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
61
+ setIsFocused(true);
62
+ if (onFocus) {
63
+ onFocus(event);
64
+ }
65
+ },
66
+ [onFocus],
67
+ );
68
+
69
+ const handleBlur = React.useCallback(
70
+ (event: NativeSyntheticEvent<TextInputFocusEventData>) => {
71
+ setIsFocused(false);
72
+ if (onBlur) {
73
+ onBlur(event);
74
+ }
75
+ },
76
+ [onBlur],
77
+ );
78
+
79
+ return (
80
+ <TextInput
81
+ ref={ref}
82
+ value={value}
83
+ onChangeText={handleChangeText}
84
+ onFocus={handleFocus}
85
+ onBlur={handleBlur}
86
+ editable={!disabled && !loading && editable}
87
+ placeholderTextColor={placeholderTextColor}
88
+ style={[
89
+ primitiveStyles.input,
90
+ style,
91
+ error && primitiveStyles.inputError,
92
+ disabled && primitiveStyles.inputDisabled,
93
+ loading && primitiveStyles.inputLoading,
94
+ ]}
95
+ {...props}
96
+ />
97
+ );
98
+ },
99
+ );
100
+
101
+ InputRoot.displayName = "InputRoot";
102
+
103
+ // Input container primitive - wraps input with additional elements
104
+ export interface InputContainerProps extends ViewProps {
105
+ focused?: boolean;
106
+ error?: boolean;
107
+ disabled?: boolean;
108
+ }
109
+
110
+ export const InputContainer = forwardRef<View, InputContainerProps>(
111
+ (
112
+ {
113
+ children,
114
+ focused = false,
115
+ error = false,
116
+ disabled = false,
117
+ style,
118
+ ...props
119
+ },
120
+ ref,
121
+ ) => {
122
+ return (
123
+ <View
124
+ ref={ref}
125
+ style={[
126
+ primitiveStyles.container,
127
+ style,
128
+ focused && primitiveStyles.containerFocused,
129
+ error && primitiveStyles.containerError,
130
+ disabled && primitiveStyles.containerDisabled,
131
+ ]}
132
+ {...props}
133
+ >
134
+ {children}
135
+ </View>
136
+ );
137
+ },
138
+ );
139
+
140
+ InputContainer.displayName = "InputContainer";
141
+
142
+ // Input label primitive
143
+ export interface InputLabelProps extends TextProps {
144
+ required?: boolean;
145
+ disabled?: boolean;
146
+ error?: boolean;
147
+ }
148
+
149
+ export const InputLabel = forwardRef<Text, InputLabelProps>(
150
+ (
151
+ {
152
+ children,
153
+ required = false,
154
+ disabled = false,
155
+ error = false,
156
+ style,
157
+ ...props
158
+ },
159
+ ref,
160
+ ) => {
161
+ return (
162
+ <Text
163
+ ref={ref}
164
+ style={[
165
+ primitiveStyles.label,
166
+ style,
167
+ error && primitiveStyles.labelError,
168
+ disabled && primitiveStyles.labelDisabled,
169
+ ]}
170
+ {...props}
171
+ >
172
+ {children}
173
+ {required && <Text style={primitiveStyles.required}> *</Text>}
174
+ </Text>
175
+ );
176
+ },
177
+ );
178
+
179
+ InputLabel.displayName = "InputLabel";
180
+
181
+ // Input description/helper text primitive
182
+ export interface InputDescriptionProps extends TextProps {
183
+ error?: boolean;
184
+ disabled?: boolean;
185
+ }
186
+
187
+ export const InputDescription = forwardRef<Text, InputDescriptionProps>(
188
+ ({ children, error = false, disabled = false, style, ...props }, ref) => {
189
+ return (
190
+ <Text
191
+ ref={ref}
192
+ style={[
193
+ primitiveStyles.description,
194
+ style,
195
+ error && primitiveStyles.descriptionError,
196
+ disabled && primitiveStyles.descriptionDisabled,
197
+ ]}
198
+ {...props}
199
+ >
200
+ {children}
201
+ </Text>
202
+ );
203
+ },
204
+ );
205
+
206
+ InputDescription.displayName = "InputDescription";
207
+
208
+ // Input error message primitive
209
+ export interface InputErrorProps extends TextProps {
210
+ visible?: boolean;
211
+ }
212
+
213
+ export const InputError = forwardRef<Text, InputErrorProps>(
214
+ ({ children, visible = true, style, ...props }, ref) => {
215
+ if (!visible || !children) return null;
216
+
217
+ return (
218
+ <Text ref={ref} style={[primitiveStyles.error, style]} {...props}>
219
+ {children}
220
+ </Text>
221
+ );
222
+ },
223
+ );
224
+
225
+ InputError.displayName = "InputError";
226
+
227
+ // Input addon primitive (for icons, buttons, etc.)
228
+ export interface InputAddonProps extends ViewProps {
229
+ position?: "left" | "right";
230
+ touchable?: boolean;
231
+ onPress?: () => void;
232
+ }
233
+
234
+ export const InputAddon = forwardRef<
235
+ React.ComponentRef<typeof View> | React.ComponentRef<typeof TouchableOpacity>,
236
+ InputAddonProps
237
+ >(
238
+ (
239
+ {
240
+ children,
241
+ position = "left",
242
+ touchable = false,
243
+ onPress,
244
+ style,
245
+ ...props
246
+ },
247
+ ref,
248
+ ) => {
249
+ const addonStyle = [
250
+ primitiveStyles.addon,
251
+ primitiveStyles[
252
+ `addon${position.charAt(0).toUpperCase() + position.slice(1)}` as keyof typeof primitiveStyles
253
+ ],
254
+ style,
255
+ ];
256
+
257
+ if (touchable && onPress) {
258
+ return (
259
+ <TouchableOpacity
260
+ ref={ref as React.Ref<React.ComponentRef<typeof TouchableOpacity>>}
261
+ style={addonStyle as any}
262
+ onPress={onPress}
263
+ {...props}
264
+ >
265
+ {children}
266
+ </TouchableOpacity>
267
+ );
268
+ }
269
+
270
+ return (
271
+ <View
272
+ ref={ref as React.Ref<React.ComponentRef<typeof View>>}
273
+ style={addonStyle as any}
274
+ {...props}
275
+ >
276
+ {children}
277
+ </View>
278
+ );
279
+ },
280
+ );
281
+
282
+ InputAddon.displayName = "InputAddon";
283
+
284
+ // Input group primitive - groups label, input, description, error
285
+ export interface InputGroupProps extends ViewProps {
286
+ spacing?: number;
287
+ }
288
+
289
+ export const InputGroup = forwardRef<View, InputGroupProps>(
290
+ ({ children, spacing = 8, style, ...props }, ref) => {
291
+ return (
292
+ <View
293
+ ref={ref}
294
+ style={[primitiveStyles.group, { gap: spacing }, style]}
295
+ {...props}
296
+ >
297
+ {children}
298
+ </View>
299
+ );
300
+ },
301
+ );
302
+
303
+ InputGroup.displayName = "InputGroup";
304
+
305
+ // Primitive styles (minimal, unstyled)
306
+ const primitiveStyles = StyleSheet.create({
307
+ input: {
308
+ minHeight: 44, // iOS minimum touch target
309
+ paddingHorizontal: 12,
310
+ paddingVertical: 8,
311
+ fontSize: 16,
312
+ borderWidth: 1,
313
+ borderColor: "#d1d5db",
314
+ borderRadius: 8,
315
+ backgroundColor: "white",
316
+ ...Platform.select({
317
+ ios: {
318
+ paddingVertical: 12,
319
+ },
320
+ android: {
321
+ paddingVertical: 8,
322
+ textAlignVertical: "center",
323
+ },
324
+ }),
325
+ },
326
+ inputFocused: {
327
+ // No focus styles for the actual input
328
+ },
329
+ inputError: {
330
+ borderColor: "#ef4444",
331
+ borderWidth: 1,
332
+ },
333
+ inputDisabled: {
334
+ backgroundColor: "#f3f4f6",
335
+ borderColor: "#e5e7eb",
336
+ opacity: 0.6,
337
+ },
338
+ inputLoading: {
339
+ opacity: 0.7,
340
+ },
341
+ container: {
342
+ flexDirection: "row",
343
+ alignItems: "center",
344
+ borderWidth: 1,
345
+ borderColor: "#d1d5db",
346
+ borderRadius: 8,
347
+ backgroundColor: "white",
348
+ paddingHorizontal: 12,
349
+ minHeight: 44,
350
+ },
351
+ containerFocused: {
352
+ borderColor: "#3b82f6",
353
+ borderWidth: 1,
354
+ },
355
+ containerError: {
356
+ borderColor: "#ef4444",
357
+ borderWidth: 1,
358
+ },
359
+ containerDisabled: {
360
+ backgroundColor: "#f3f4f6",
361
+ borderColor: "#e5e7eb",
362
+ opacity: 0.6,
363
+ },
364
+ label: {
365
+ fontSize: 14,
366
+ fontWeight: "500",
367
+ color: "#374151",
368
+ marginBottom: 4,
369
+ },
370
+ labelError: {
371
+ color: "#ef4444",
372
+ },
373
+ labelDisabled: {
374
+ color: "#9ca3af",
375
+ opacity: 0.6,
376
+ },
377
+ required: {
378
+ color: "#ef4444",
379
+ },
380
+ description: {
381
+ fontSize: 12,
382
+ color: "#6b7280",
383
+ marginTop: 4,
384
+ },
385
+ descriptionError: {
386
+ color: "#ef4444",
387
+ },
388
+ descriptionDisabled: {
389
+ color: "#9ca3af",
390
+ opacity: 0.6,
391
+ },
392
+ error: {
393
+ fontSize: 12,
394
+ color: "#ef4444",
395
+ marginTop: 4,
396
+ },
397
+ addon: {
398
+ alignItems: "center",
399
+ justifyContent: "center",
400
+ paddingHorizontal: 8,
401
+ },
402
+ addonLeft: {
403
+ marginRight: 8,
404
+ },
405
+ addonRight: {
406
+ marginLeft: 8,
407
+ },
408
+ group: {
409
+ flexDirection: "column",
410
+ },
411
+ });
412
+
413
+ // Export primitive collection
414
+ export const InputPrimitive = {
415
+ Root: InputRoot,
416
+ Container: InputContainer,
417
+ Label: InputLabel,
418
+ Description: InputDescription,
419
+ Error: InputError,
420
+ Addon: InputAddon,
421
+ Group: InputGroup,
422
+ };