@streamplace/components 0.7.27 → 0.7.29
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 +2 -2
- package/dist/components/chat/chat.js +1 -1
- package/dist/components/mobile-player/ui/autoplay-button.js +1 -0
- package/dist/components/mobile-player/ui/viewer-context-menu.js +1 -1
- package/dist/components/mobile-player/ui/viewer-loading-overlay.js +2 -2
- package/dist/components/mobile-player/use-webrtc.js +30 -0
- package/dist/components/ui/button.js +107 -155
- package/dist/components/ui/dialog.js +83 -116
- package/dist/components/ui/dropdown.js +41 -18
- package/dist/components/ui/input.js +53 -128
- package/dist/components/ui/primitives/button.js +0 -2
- package/dist/components/ui/primitives/modal.js +2 -2
- package/dist/components/ui/primitives/text.js +48 -8
- package/dist/components/ui/text.js +37 -66
- package/dist/components/ui/toast.js +78 -40
- package/dist/components/ui/view.js +28 -41
- package/dist/lib/theme/index.js +1 -2
- package/dist/lib/theme/theme.js +106 -54
- package/dist/lib/theme/tokens.js +94 -1
- package/dist/ui/index.js +2 -3
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/package.json +3 -2
- package/src/components/chat/chat-box.tsx +6 -3
- package/src/components/chat/chat.tsx +1 -0
- package/src/components/mobile-player/ui/autoplay-button.tsx +1 -0
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +2 -2
- package/src/components/mobile-player/ui/viewer-loading-overlay.tsx +2 -2
- package/src/components/mobile-player/use-webrtc.tsx +31 -0
- package/src/components/ui/button.tsx +110 -172
- package/src/components/ui/dialog.tsx +96 -138
- package/src/components/ui/dropdown.tsx +60 -22
- package/src/components/ui/input.tsx +57 -144
- package/src/components/ui/primitives/button.tsx +0 -2
- package/src/components/ui/primitives/modal.tsx +0 -2
- package/src/components/ui/primitives/text.tsx +51 -8
- package/src/components/ui/text.tsx +42 -67
- package/src/components/ui/toast.tsx +108 -90
- package/src/components/ui/view.tsx +27 -41
- package/src/lib/theme/index.ts +0 -2
- package/src/lib/theme/theme.tsx +179 -72
- package/src/lib/theme/tokens.ts +97 -0
- package/src/ui/index.ts +0 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -19,9 +19,7 @@ import {
|
|
|
19
19
|
} from "react-native";
|
|
20
20
|
import {
|
|
21
21
|
a,
|
|
22
|
-
bg,
|
|
23
22
|
borderRadius,
|
|
24
|
-
colors,
|
|
25
23
|
fontSize,
|
|
26
24
|
gap,
|
|
27
25
|
layout,
|
|
@@ -35,8 +33,8 @@ import {
|
|
|
35
33
|
px,
|
|
36
34
|
py,
|
|
37
35
|
right,
|
|
38
|
-
textColors,
|
|
39
36
|
} from "../../lib/theme/atoms";
|
|
37
|
+
import { useTheme } from "../../ui";
|
|
40
38
|
import {
|
|
41
39
|
objectFromObjects,
|
|
42
40
|
TextContext as TextClassContext,
|
|
@@ -60,6 +58,7 @@ export const DropdownMenuBottomSheet = forwardRef<
|
|
|
60
58
|
) {
|
|
61
59
|
// Use the primitives' context to know if open
|
|
62
60
|
const { open, onOpenChange } = DropdownMenuPrimitive.useRootContext();
|
|
61
|
+
const { zero: zt } = useTheme();
|
|
63
62
|
const snapPoints = useMemo(() => ["25%", "50%", "80%"], []);
|
|
64
63
|
const sheetRef = useRef<BottomSheet>(null);
|
|
65
64
|
|
|
@@ -81,11 +80,11 @@ export const DropdownMenuBottomSheet = forwardRef<
|
|
|
81
80
|
)}
|
|
82
81
|
onClose={() => onOpenChange?.(false)}
|
|
83
82
|
style={[overlayStyle]}
|
|
84
|
-
backgroundStyle={[bg.
|
|
83
|
+
backgroundStyle={[zt.bg.popover, a.radius.all.md, a.shadows.md, p[1]]}
|
|
85
84
|
handleIndicatorStyle={[
|
|
86
85
|
a.sizes.width[12],
|
|
87
86
|
a.sizes.height[1],
|
|
88
|
-
bg.
|
|
87
|
+
zt.bg.mutedForeground,
|
|
89
88
|
]}
|
|
90
89
|
>
|
|
91
90
|
<BottomSheetView style={[px[2]]}>
|
|
@@ -108,6 +107,7 @@ export const DropdownMenuSubTrigger = forwardRef<
|
|
|
108
107
|
}
|
|
109
108
|
>(({ inset, children, ...props }, ref) => {
|
|
110
109
|
const { open } = DropdownMenuPrimitive.useSubContext();
|
|
110
|
+
const { icons } = useTheme();
|
|
111
111
|
const Icon =
|
|
112
112
|
Platform.OS === "web" ? ChevronRight : open ? ChevronUp : ChevronDown;
|
|
113
113
|
return (
|
|
@@ -130,7 +130,7 @@ export const DropdownMenuSubTrigger = forwardRef<
|
|
|
130
130
|
>
|
|
131
131
|
{children}
|
|
132
132
|
<View style={[a.layout.position.absolute, a.position.right[1]]}>
|
|
133
|
-
<Icon size={18} color={
|
|
133
|
+
<Icon size={18} color={icons.color.muted} />
|
|
134
134
|
</View>
|
|
135
135
|
</View>
|
|
136
136
|
</DropdownMenuPrimitive.SubTrigger>
|
|
@@ -142,6 +142,7 @@ export const DropdownMenuSubContent = forwardRef<
|
|
|
142
142
|
any,
|
|
143
143
|
DropdownMenuPrimitive.SubContentProps
|
|
144
144
|
>((props, ref) => {
|
|
145
|
+
const { zero: zt } = useTheme();
|
|
145
146
|
return (
|
|
146
147
|
<DropdownMenuPrimitive.SubContent
|
|
147
148
|
ref={ref}
|
|
@@ -151,9 +152,9 @@ export const DropdownMenuSubContent = forwardRef<
|
|
|
151
152
|
a.overflow.hidden,
|
|
152
153
|
a.radius.all.md,
|
|
153
154
|
a.borders.width.thin,
|
|
154
|
-
|
|
155
|
+
zt.border.default,
|
|
155
156
|
mt[1],
|
|
156
|
-
bg.
|
|
157
|
+
zt.bg.popover,
|
|
157
158
|
p[1],
|
|
158
159
|
a.shadows.md,
|
|
159
160
|
]}
|
|
@@ -169,6 +170,7 @@ export const DropdownMenuContent = forwardRef<
|
|
|
169
170
|
portalHost?: string;
|
|
170
171
|
}
|
|
171
172
|
>(({ overlayStyle, portalHost, ...props }, ref) => {
|
|
173
|
+
const { zero: zt } = useTheme();
|
|
172
174
|
return (
|
|
173
175
|
<DropdownMenuPrimitive.Portal hostName={portalHost}>
|
|
174
176
|
<DropdownMenuPrimitive.Overlay
|
|
@@ -187,8 +189,8 @@ export const DropdownMenuContent = forwardRef<
|
|
|
187
189
|
a.overflow.hidden,
|
|
188
190
|
a.radius.all.md,
|
|
189
191
|
a.borders.width.thin,
|
|
190
|
-
|
|
191
|
-
bg.
|
|
192
|
+
zt.border.default,
|
|
193
|
+
zt.bg.popover,
|
|
192
194
|
p[2],
|
|
193
195
|
a.shadows.md,
|
|
194
196
|
] as any
|
|
@@ -206,6 +208,7 @@ export const DropdownMenuContentWithoutPortal = forwardRef<
|
|
|
206
208
|
overlayStyle?: any;
|
|
207
209
|
}
|
|
208
210
|
>(({ overlayStyle, ...props }, ref) => {
|
|
211
|
+
const { theme } = useTheme();
|
|
209
212
|
return (
|
|
210
213
|
<DropdownMenuPrimitive.Overlay
|
|
211
214
|
style={[
|
|
@@ -223,8 +226,8 @@ export const DropdownMenuContentWithoutPortal = forwardRef<
|
|
|
223
226
|
a.overflow.hidden,
|
|
224
227
|
a.radius.all.md,
|
|
225
228
|
a.borders.width.thin,
|
|
226
|
-
|
|
227
|
-
|
|
229
|
+
{ borderColor: theme.colors.border },
|
|
230
|
+
{ backgroundColor: theme.colors.popover },
|
|
228
231
|
p[2],
|
|
229
232
|
a.shadows.md,
|
|
230
233
|
] as any
|
|
@@ -263,10 +266,14 @@ export const DropdownMenuItem = forwardRef<
|
|
|
263
266
|
any,
|
|
264
267
|
DropdownMenuPrimitive.ItemProps & { inset?: boolean; disabled?: boolean }
|
|
265
268
|
>(({ inset, disabled, style, children, ...props }, ref) => {
|
|
269
|
+
const { theme } = useTheme();
|
|
266
270
|
return (
|
|
267
271
|
<Pressable {...props}>
|
|
268
272
|
<TextClassContext.Provider
|
|
269
|
-
value={objectFromObjects([
|
|
273
|
+
value={objectFromObjects([
|
|
274
|
+
{ color: theme.colors.popoverForeground },
|
|
275
|
+
a.fontSize.base,
|
|
276
|
+
])}
|
|
270
277
|
>
|
|
271
278
|
<View
|
|
272
279
|
style={[
|
|
@@ -294,6 +301,7 @@ export const DropdownMenuCheckboxItem = forwardRef<
|
|
|
294
301
|
children?: React.ReactNode;
|
|
295
302
|
}
|
|
296
303
|
>(({ children, checked, ...props }, ref) => {
|
|
304
|
+
const { theme } = useTheme();
|
|
297
305
|
return (
|
|
298
306
|
<DropdownMenuPrimitive.CheckboxItem
|
|
299
307
|
ref={ref}
|
|
@@ -315,9 +323,17 @@ export const DropdownMenuCheckboxItem = forwardRef<
|
|
|
315
323
|
{children}
|
|
316
324
|
<View style={[pl[1], layout.position.absolute, right[1]]}>
|
|
317
325
|
{checked ? (
|
|
318
|
-
<CheckCircle
|
|
326
|
+
<CheckCircle
|
|
327
|
+
size={14}
|
|
328
|
+
strokeWidth={3}
|
|
329
|
+
color={theme.colors.foreground}
|
|
330
|
+
/>
|
|
319
331
|
) : (
|
|
320
|
-
<Circle
|
|
332
|
+
<Circle
|
|
333
|
+
size={14}
|
|
334
|
+
strokeWidth={3}
|
|
335
|
+
color={theme.colors.mutedForeground}
|
|
336
|
+
/>
|
|
321
337
|
)}
|
|
322
338
|
</View>
|
|
323
339
|
</View>
|
|
@@ -332,6 +348,7 @@ export const DropdownMenuRadioItem = forwardRef<
|
|
|
332
348
|
children?: React.ReactNode;
|
|
333
349
|
}
|
|
334
350
|
>(({ children, ...props }, ref) => {
|
|
351
|
+
const { theme } = useTheme();
|
|
335
352
|
return (
|
|
336
353
|
<DropdownMenuPrimitive.RadioItem
|
|
337
354
|
ref={ref}
|
|
@@ -350,7 +367,7 @@ export const DropdownMenuRadioItem = forwardRef<
|
|
|
350
367
|
>
|
|
351
368
|
<View style={[pl[1], layout.position.absolute, right[1]]}>
|
|
352
369
|
<DropdownMenuPrimitive.ItemIndicator>
|
|
353
|
-
<Check size={14} strokeWidth={3} color=
|
|
370
|
+
<Check size={14} strokeWidth={3} color={theme.colors.foreground} />
|
|
354
371
|
</DropdownMenuPrimitive.ItemIndicator>
|
|
355
372
|
</View>
|
|
356
373
|
{children}
|
|
@@ -363,13 +380,14 @@ export const DropdownMenuLabel = forwardRef<
|
|
|
363
380
|
any,
|
|
364
381
|
DropdownMenuPrimitive.LabelProps & { inset?: boolean }
|
|
365
382
|
>(({ inset, ...props }, ref) => {
|
|
383
|
+
const { theme } = useTheme();
|
|
366
384
|
return (
|
|
367
385
|
<Text
|
|
368
386
|
ref={ref}
|
|
369
387
|
style={[
|
|
370
388
|
px[2],
|
|
371
389
|
py[2],
|
|
372
|
-
|
|
390
|
+
{ color: theme.colors.textMuted },
|
|
373
391
|
a.fontSize.base,
|
|
374
392
|
inset && gap[2],
|
|
375
393
|
]}
|
|
@@ -382,15 +400,23 @@ export const DropdownMenuSeparator = forwardRef<
|
|
|
382
400
|
any,
|
|
383
401
|
DropdownMenuPrimitive.SeparatorProps
|
|
384
402
|
>((props, ref) => {
|
|
385
|
-
|
|
403
|
+
const { theme } = useTheme();
|
|
404
|
+
return (
|
|
405
|
+
<View
|
|
406
|
+
ref={ref}
|
|
407
|
+
style={[{ height: 0.5 }, { backgroundColor: theme.colors.border }]}
|
|
408
|
+
{...props}
|
|
409
|
+
/>
|
|
410
|
+
);
|
|
386
411
|
});
|
|
387
412
|
|
|
388
413
|
export function DropdownMenuShortcut(props: any) {
|
|
414
|
+
const { theme } = useTheme();
|
|
389
415
|
return (
|
|
390
416
|
<Text
|
|
391
417
|
style={[
|
|
392
418
|
ml.auto,
|
|
393
|
-
|
|
419
|
+
{ color: theme.colors.textMuted },
|
|
394
420
|
a.fontSize.sm,
|
|
395
421
|
a.letterSpacing.widest,
|
|
396
422
|
]}
|
|
@@ -403,15 +429,18 @@ export const DropdownMenuGroup = forwardRef<
|
|
|
403
429
|
any,
|
|
404
430
|
{ inset?: boolean; title?: string; children: ReactNode }
|
|
405
431
|
>((props, ref) => {
|
|
432
|
+
const { theme } = useTheme();
|
|
406
433
|
const { inset, title, children, ...rest } = props;
|
|
407
434
|
return (
|
|
408
435
|
<View style={[pt[2], inset && gap[2]]} ref={ref} {...rest}>
|
|
409
436
|
{title && (
|
|
410
|
-
<Text style={[
|
|
437
|
+
<Text style={[{ color: theme.colors.textMuted }, pb[1], pl[2]]}>
|
|
438
|
+
{title}
|
|
439
|
+
</Text>
|
|
411
440
|
)}
|
|
412
441
|
<View
|
|
413
442
|
style={[
|
|
414
|
-
|
|
443
|
+
{ backgroundColor: theme.colors.muted },
|
|
415
444
|
Platform.OS === "web" ? [px[2], py[1]] : p[2],
|
|
416
445
|
gap.all[1],
|
|
417
446
|
{ borderRadius: borderRadius.lg },
|
|
@@ -425,8 +454,17 @@ export const DropdownMenuGroup = forwardRef<
|
|
|
425
454
|
|
|
426
455
|
export const DropdownMenuInfo = forwardRef<any, any>(
|
|
427
456
|
({ description, ...props }, ref) => {
|
|
457
|
+
const { theme } = useTheme();
|
|
428
458
|
return (
|
|
429
|
-
<Text
|
|
459
|
+
<Text
|
|
460
|
+
style={[
|
|
461
|
+
{ color: theme.colors.textMuted },
|
|
462
|
+
pt[1],
|
|
463
|
+
pl[2],
|
|
464
|
+
pb[2],
|
|
465
|
+
fontSize.sm,
|
|
466
|
+
]}
|
|
467
|
+
>
|
|
430
468
|
{description}
|
|
431
469
|
</Text>
|
|
432
470
|
);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
2
|
import React, { forwardRef } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { TouchableWithoutFeedback } from "react-native";
|
|
4
4
|
import { useTheme } from "../../lib/theme/theme";
|
|
5
|
+
import * as zero from "../../ui";
|
|
5
6
|
import { InputPrimitive, InputPrimitiveProps } from "./primitives/input";
|
|
6
7
|
|
|
7
8
|
const inputVariants = cva("", {
|
|
@@ -54,26 +55,66 @@ export const Input = forwardRef<any, InputProps>(
|
|
|
54
55
|
},
|
|
55
56
|
ref,
|
|
56
57
|
) => {
|
|
57
|
-
const { theme } = useTheme();
|
|
58
|
+
const { zero: zt, theme } = useTheme();
|
|
58
59
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
59
60
|
const inputRef = React.useRef<any>(null);
|
|
60
61
|
|
|
61
|
-
//
|
|
62
|
-
const styles = React.useMemo(() => createStyles(theme), [theme]);
|
|
63
|
-
|
|
64
|
-
// Get variant and size styles
|
|
62
|
+
// Get variant and size styles using theme.zero
|
|
65
63
|
const containerStyles = React.useMemo(() => {
|
|
66
|
-
const variantStyle =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
const variantStyle = (() => {
|
|
65
|
+
switch (variant) {
|
|
66
|
+
case "filled":
|
|
67
|
+
return [zt.bg.muted];
|
|
68
|
+
case "underlined":
|
|
69
|
+
return [
|
|
70
|
+
zt.bg.transparent,
|
|
71
|
+
zt.border.bottom.default,
|
|
72
|
+
{ borderRadius: 0, paddingHorizontal: 0 },
|
|
73
|
+
];
|
|
74
|
+
default:
|
|
75
|
+
return [zt.bg.background, zt.border.default];
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
|
|
79
|
+
const sizeStyle = (() => {
|
|
80
|
+
switch (size) {
|
|
81
|
+
case "sm":
|
|
82
|
+
return [
|
|
83
|
+
zero.px[3],
|
|
84
|
+
zero.py[2],
|
|
85
|
+
{ borderRadius: zero.borderRadius.md },
|
|
86
|
+
];
|
|
87
|
+
case "lg":
|
|
88
|
+
return [
|
|
89
|
+
zero.px[4],
|
|
90
|
+
zero.py[3],
|
|
91
|
+
{ borderRadius: zero.borderRadius.md },
|
|
92
|
+
];
|
|
93
|
+
default:
|
|
94
|
+
return [
|
|
95
|
+
zero.px[3],
|
|
96
|
+
zero.py[2],
|
|
97
|
+
{ borderRadius: zero.borderRadius.md },
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
})();
|
|
101
|
+
|
|
102
|
+
const focusStyle = isFocused ? zt.border.primary : null;
|
|
103
|
+
return [variantStyle, sizeStyle, focusStyle].filter(Boolean);
|
|
104
|
+
}, [variant, size, zt, isFocused]);
|
|
71
105
|
|
|
72
106
|
const textStyles = React.useMemo(() => {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
107
|
+
const baseTextStyle = [zt.text.foreground, zt.bg.transparent];
|
|
108
|
+
|
|
109
|
+
switch (size) {
|
|
110
|
+
case "sm":
|
|
111
|
+
return [...baseTextStyle, zt.text.sm];
|
|
112
|
+
case "lg":
|
|
113
|
+
return [...baseTextStyle, zt.text.lg];
|
|
114
|
+
default:
|
|
115
|
+
return [...baseTextStyle, zt.text.md];
|
|
116
|
+
}
|
|
117
|
+
}, [size, zt]);
|
|
77
118
|
|
|
78
119
|
const handleFocus = React.useCallback(
|
|
79
120
|
(event: any) => {
|
|
@@ -144,12 +185,7 @@ export const Input = forwardRef<any, InputProps>(
|
|
|
144
185
|
error={!!error}
|
|
145
186
|
onFocus={handleFocus}
|
|
146
187
|
onBlur={handleBlur}
|
|
147
|
-
style={[
|
|
148
|
-
textStyles,
|
|
149
|
-
styles.inputInContainer,
|
|
150
|
-
inputStyle,
|
|
151
|
-
{ outline: "none" },
|
|
152
|
-
]}
|
|
188
|
+
style={[textStyles, inputStyle, { outline: "none" }]}
|
|
153
189
|
placeholderTextColor={
|
|
154
190
|
disabled ? theme.colors.textDisabled : theme.colors.textMuted
|
|
155
191
|
}
|
|
@@ -223,128 +259,5 @@ export const Input = forwardRef<any, InputProps>(
|
|
|
223
259
|
|
|
224
260
|
Input.displayName = "Input";
|
|
225
261
|
|
|
226
|
-
// Create theme-aware styles
|
|
227
|
-
function createStyles(theme: any) {
|
|
228
|
-
return StyleSheet.create({
|
|
229
|
-
// Variant styles for containers
|
|
230
|
-
defaultContainer: {
|
|
231
|
-
backgroundColor: theme.colors.background,
|
|
232
|
-
borderWidth: 1,
|
|
233
|
-
borderColor: theme.colors.border,
|
|
234
|
-
borderRadius: theme.borderRadius.md,
|
|
235
|
-
},
|
|
236
|
-
|
|
237
|
-
filledContainer: {
|
|
238
|
-
backgroundColor: theme.colors.muted,
|
|
239
|
-
borderWidth: 0,
|
|
240
|
-
borderRadius: theme.borderRadius.md,
|
|
241
|
-
},
|
|
242
|
-
|
|
243
|
-
underlinedContainer: {
|
|
244
|
-
backgroundColor: "transparent",
|
|
245
|
-
borderWidth: 0,
|
|
246
|
-
borderBottomWidth: 1,
|
|
247
|
-
borderBottomColor: theme.colors.border,
|
|
248
|
-
borderRadius: 0,
|
|
249
|
-
paddingHorizontal: 0,
|
|
250
|
-
},
|
|
251
|
-
|
|
252
|
-
// Variant styles for inputs
|
|
253
|
-
defaultInput: {
|
|
254
|
-
color: theme.colors.text,
|
|
255
|
-
backgroundColor: "transparent",
|
|
256
|
-
},
|
|
257
|
-
|
|
258
|
-
filledInput: {
|
|
259
|
-
color: theme.colors.text,
|
|
260
|
-
backgroundColor: "transparent",
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
underlinedInput: {
|
|
264
|
-
color: theme.colors.text,
|
|
265
|
-
backgroundColor: "transparent",
|
|
266
|
-
},
|
|
267
|
-
|
|
268
|
-
// Size styles for containers
|
|
269
|
-
smContainer: {
|
|
270
|
-
paddingHorizontal: theme.spacing[3],
|
|
271
|
-
paddingVertical: theme.spacing[2],
|
|
272
|
-
minHeight: theme.touchTargets.minimum - 8,
|
|
273
|
-
},
|
|
274
|
-
|
|
275
|
-
mdContainer: {
|
|
276
|
-
paddingHorizontal: theme.spacing[3],
|
|
277
|
-
paddingVertical: theme.spacing[3],
|
|
278
|
-
minHeight: theme.touchTargets.minimum,
|
|
279
|
-
},
|
|
280
|
-
|
|
281
|
-
lgContainer: {
|
|
282
|
-
paddingHorizontal: theme.spacing[4],
|
|
283
|
-
paddingVertical: theme.spacing[4],
|
|
284
|
-
minHeight: theme.touchTargets.comfortable,
|
|
285
|
-
},
|
|
286
|
-
|
|
287
|
-
// Size styles for inputs
|
|
288
|
-
smInput: {
|
|
289
|
-
fontSize: 14,
|
|
290
|
-
lineHeight: 18,
|
|
291
|
-
...Platform.select({
|
|
292
|
-
ios: {
|
|
293
|
-
paddingVertical: 0,
|
|
294
|
-
},
|
|
295
|
-
android: {
|
|
296
|
-
paddingVertical: 0,
|
|
297
|
-
textAlignVertical: "center",
|
|
298
|
-
},
|
|
299
|
-
}),
|
|
300
|
-
},
|
|
301
|
-
|
|
302
|
-
mdInput: {
|
|
303
|
-
fontSize: 16,
|
|
304
|
-
lineHeight: 20,
|
|
305
|
-
...Platform.select({
|
|
306
|
-
ios: {
|
|
307
|
-
paddingVertical: 0,
|
|
308
|
-
},
|
|
309
|
-
android: {
|
|
310
|
-
paddingVertical: 0,
|
|
311
|
-
textAlignVertical: "center",
|
|
312
|
-
},
|
|
313
|
-
}),
|
|
314
|
-
},
|
|
315
|
-
|
|
316
|
-
lgInput: {
|
|
317
|
-
fontSize: 18,
|
|
318
|
-
lineHeight: 22,
|
|
319
|
-
...Platform.select({
|
|
320
|
-
ios: {
|
|
321
|
-
paddingVertical: 0,
|
|
322
|
-
},
|
|
323
|
-
android: {
|
|
324
|
-
paddingVertical: 0,
|
|
325
|
-
textAlignVertical: "center",
|
|
326
|
-
},
|
|
327
|
-
}),
|
|
328
|
-
},
|
|
329
|
-
|
|
330
|
-
// Special style for inputs inside containers
|
|
331
|
-
inputInContainer: {
|
|
332
|
-
flex: 1,
|
|
333
|
-
paddingHorizontal: 0,
|
|
334
|
-
paddingVertical: 0,
|
|
335
|
-
borderWidth: 0,
|
|
336
|
-
backgroundColor: "transparent",
|
|
337
|
-
minHeight: "auto",
|
|
338
|
-
borderRadius: 0,
|
|
339
|
-
},
|
|
340
|
-
|
|
341
|
-
// Focus styles
|
|
342
|
-
focusedContainer: {
|
|
343
|
-
borderColor: theme.colors.primary,
|
|
344
|
-
borderWidth: 1,
|
|
345
|
-
},
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
|
|
349
262
|
// Export input variants for external use
|
|
350
263
|
export { inputVariants };
|
|
@@ -245,7 +245,6 @@ const primitiveStyles = StyleSheet.create({
|
|
|
245
245
|
alignItems: "center",
|
|
246
246
|
justifyContent: "center",
|
|
247
247
|
minHeight: 44, // iOS minimum touch target
|
|
248
|
-
minWidth: 44,
|
|
249
248
|
},
|
|
250
249
|
disabled: {
|
|
251
250
|
opacity: 0.5,
|
|
@@ -254,7 +253,6 @@ const primitiveStyles = StyleSheet.create({
|
|
|
254
253
|
flexDirection: "row",
|
|
255
254
|
alignItems: "center",
|
|
256
255
|
justifyContent: "center",
|
|
257
|
-
flex: 1,
|
|
258
256
|
},
|
|
259
257
|
text: {
|
|
260
258
|
textAlign: "center" as const,
|
|
@@ -33,7 +33,6 @@ export const ModalRoot = forwardRef<View, ModalPrimitiveProps>(
|
|
|
33
33
|
onRequestClose,
|
|
34
34
|
animationType = "fade",
|
|
35
35
|
presentationStyle = Platform.OS === "ios" ? "pageSheet" : "fullScreen",
|
|
36
|
-
transparent = true,
|
|
37
36
|
statusBarTranslucent = Platform.OS === "android",
|
|
38
37
|
...props
|
|
39
38
|
},
|
|
@@ -57,7 +56,6 @@ export const ModalRoot = forwardRef<View, ModalPrimitiveProps>(
|
|
|
57
56
|
onRequestClose={handleRequestClose}
|
|
58
57
|
animationType={animationType}
|
|
59
58
|
presentationStyle={presentationStyle}
|
|
60
|
-
transparent={transparent}
|
|
61
59
|
statusBarTranslucent={statusBarTranslucent}
|
|
62
60
|
{...props}
|
|
63
61
|
>
|
|
@@ -129,6 +129,18 @@ const sizeMap = {
|
|
|
129
129
|
"4xl": 36,
|
|
130
130
|
} as const;
|
|
131
131
|
|
|
132
|
+
// Size-specific line height mapping (provides better default line heights for each size)
|
|
133
|
+
const sizeLineHeightMap = {
|
|
134
|
+
xs: 16, // 12px * 1.33 = tight but readable
|
|
135
|
+
sm: 20, // 14px * 1.43 = good for small text
|
|
136
|
+
base: 24, // 16px * 1.5 = standard body text
|
|
137
|
+
lg: 28, // 18px * 1.56 = comfortable for larger text
|
|
138
|
+
xl: 30, // 20px * 1.5 = balanced
|
|
139
|
+
"2xl": 32, // 24px * 1.33 = tighter for headings
|
|
140
|
+
"3xl": 36, // 30px * 1.2 = tight for large headings
|
|
141
|
+
"4xl": 40, // 36px * 1.11 = very tight for display text
|
|
142
|
+
} as const;
|
|
143
|
+
|
|
132
144
|
// Weight mapping
|
|
133
145
|
const weightMap = {
|
|
134
146
|
thin: "100",
|
|
@@ -199,12 +211,12 @@ const getVariantStyles = () => {
|
|
|
199
211
|
};
|
|
200
212
|
} else if (typographicPlatform === "android") {
|
|
201
213
|
return {
|
|
202
|
-
h1: platformTypography.
|
|
203
|
-
h2: platformTypography.
|
|
204
|
-
h3: platformTypography.
|
|
205
|
-
h4: platformTypography.
|
|
206
|
-
h5: platformTypography.
|
|
207
|
-
h6: platformTypography.
|
|
214
|
+
h1: platformTypography.headline4, // 34px instead of 96px
|
|
215
|
+
h2: platformTypography.headline5, // 24px instead of 60px
|
|
216
|
+
h3: platformTypography.headline6, // 20px instead of 48px
|
|
217
|
+
h4: platformTypography.subtitle1, // 16px instead of 34px
|
|
218
|
+
h5: platformTypography.subtitle2, // 14px instead of 24px
|
|
219
|
+
h6: platformTypography.subtitle2, // 14px - consistent with h5
|
|
208
220
|
subtitle1: platformTypography.subtitle1,
|
|
209
221
|
subtitle2: platformTypography.subtitle2,
|
|
210
222
|
body1: platformTypography.body1,
|
|
@@ -286,9 +298,16 @@ export const TextRoot = forwardRef<RNText, TextPrimitiveProps>(
|
|
|
286
298
|
|
|
287
299
|
// Apply explicit prop styles (these should override inherited and variant)
|
|
288
300
|
|
|
289
|
-
// Apply size
|
|
301
|
+
// Apply size (with corresponding line height if not explicitly set)
|
|
290
302
|
...(size && {
|
|
291
303
|
fontSize: typeof size === "number" ? size : sizeMap[size],
|
|
304
|
+
// Apply size-specific line height only if leading is not explicitly set
|
|
305
|
+
...(leading === undefined && {
|
|
306
|
+
lineHeight:
|
|
307
|
+
typeof size === "number"
|
|
308
|
+
? size // Auto line height for numeric sizes
|
|
309
|
+
: sizeLineHeightMap[size],
|
|
310
|
+
}),
|
|
292
311
|
}),
|
|
293
312
|
|
|
294
313
|
// Apply weight
|
|
@@ -360,6 +379,23 @@ export const TextRoot = forwardRef<RNText, TextPrimitiveProps>(
|
|
|
360
379
|
finalStyles.color = finalStyles.color as ColorValue;
|
|
361
380
|
|
|
362
381
|
// Create context value for children
|
|
382
|
+
// Process custom styles to auto-add line height for fontSize
|
|
383
|
+
const processedStyle = Array.isArray(style)
|
|
384
|
+
? style
|
|
385
|
+
: [style].filter(Boolean);
|
|
386
|
+
const enhancedStyles = processedStyle.map((styleObj) => {
|
|
387
|
+
if (styleObj && typeof styleObj === "object" && "fontSize" in styleObj) {
|
|
388
|
+
const fontSize = styleObj.fontSize;
|
|
389
|
+
if (typeof fontSize === "number" && !styleObj.lineHeight && !leading) {
|
|
390
|
+
return {
|
|
391
|
+
...styleObj,
|
|
392
|
+
lineHeight: fontSize * 1.2,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return styleObj;
|
|
397
|
+
});
|
|
398
|
+
|
|
363
399
|
const contextValue: TextContextValue = {
|
|
364
400
|
fontSize:
|
|
365
401
|
typeof finalStyles.fontSize === "number"
|
|
@@ -386,7 +422,7 @@ export const TextRoot = forwardRef<RNText, TextPrimitiveProps>(
|
|
|
386
422
|
|
|
387
423
|
return (
|
|
388
424
|
<TextContext.Provider value={contextValue}>
|
|
389
|
-
<RNText ref={ref} style={[finalStyles,
|
|
425
|
+
<RNText ref={ref} style={[finalStyles, ...enhancedStyles]} {...props}>
|
|
390
426
|
{children}
|
|
391
427
|
</RNText>
|
|
392
428
|
</TextContext.Provider>
|
|
@@ -438,6 +474,13 @@ export function createTextStyle(
|
|
|
438
474
|
if (props.size) {
|
|
439
475
|
style.fontSize =
|
|
440
476
|
typeof props.size === "number" ? props.size : sizeMap[props.size];
|
|
477
|
+
// Apply size-specific line height only if leading is not explicitly set
|
|
478
|
+
if (props.leading === undefined) {
|
|
479
|
+
style.lineHeight =
|
|
480
|
+
typeof props.size === "number"
|
|
481
|
+
? props.size * 1.2 // Auto line height for numeric sizes
|
|
482
|
+
: sizeLineHeightMap[props.size];
|
|
483
|
+
}
|
|
441
484
|
}
|
|
442
485
|
|
|
443
486
|
if (props.weight) {
|