@mrmeg/expo-ui 0.1.5 → 0.1.7
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/LLM_USAGE.md +28 -0
- package/README.md +34 -17
- package/dist/components/Accordion.js +19 -16
- package/dist/components/Badge.js +5 -4
- package/dist/components/Button.js +84 -51
- package/dist/components/Card.js +4 -3
- package/dist/components/Checkbox.js +6 -4
- package/dist/components/Collapsible.js +15 -14
- package/dist/components/Dialog.js +6 -6
- package/dist/components/Drawer.js +5 -5
- package/dist/components/DropdownMenu.js +119 -112
- package/dist/components/EmptyState.js +5 -3
- package/dist/components/InputOTP.js +3 -3
- package/dist/components/Label.js +5 -2
- package/dist/components/Notification.js +3 -3
- package/dist/components/Popover.js +2 -2
- package/dist/components/RadioGroup.js +6 -4
- package/dist/components/Select.js +35 -25
- package/dist/components/Slider.js +34 -24
- package/dist/components/StyledText.d.ts +13 -2
- package/dist/components/StyledText.js +28 -7
- package/dist/components/Switch.js +28 -28
- package/dist/components/Tabs.js +6 -3
- package/dist/components/TextInput.js +8 -10
- package/dist/components/Toggle.js +4 -2
- package/dist/components/ToggleGroup.js +3 -2
- package/dist/components/Tooltip.js +4 -4
- package/dist/constants/colors.d.ts +4 -0
- package/dist/constants/colors.js +9 -1
- package/dist/constants/spacing.d.ts +2 -1
- package/dist/constants/spacing.js +2 -1
- package/dist/hooks/useTheme.d.ts +9 -6
- package/dist/hooks/useTheme.js +99 -22
- package/package.json +6 -7
|
@@ -21,14 +21,14 @@ function DialogRoot({ children, ...props }) {
|
|
|
21
21
|
}
|
|
22
22
|
function DialogContent({ portalHost, style, children, ...props }) {
|
|
23
23
|
const { theme, getShadowStyle, getContrastingColor } = useTheme();
|
|
24
|
-
const textColor = getContrastingColor(theme.colors.
|
|
24
|
+
const textColor = getContrastingColor(theme.colors.popover, palette.white, palette.black);
|
|
25
25
|
return (_jsx(DialogPrimitive.Portal, { hostName: portalHost, children: _jsx(FullWindowOverlay, { children: _jsx(DialogPrimitive.Overlay, { style: StyleSheet.flatten([
|
|
26
26
|
StyleSheet.absoluteFill,
|
|
27
27
|
{ backgroundColor: theme.colors.overlay },
|
|
28
28
|
Platform.OS === "web" && { zIndex: 50 },
|
|
29
29
|
]), children: _jsx(AnimatedView, { type: "fade", enterDuration: 200, children: _jsx(View, { style: overlayStyles.centeredContainer, children: _jsx(AnimatedView, { type: "scale", enterDuration: 250, children: _jsx(TextColorContext.Provider, { value: textColor, children: _jsx(TextClassContext.Provider, { value: "", children: _jsx(DialogPrimitive.Content, { style: StyleSheet.flatten([
|
|
30
30
|
{
|
|
31
|
-
backgroundColor: theme.colors.
|
|
31
|
+
backgroundColor: theme.colors.popover,
|
|
32
32
|
borderColor: theme.colors.border,
|
|
33
33
|
borderWidth: 1,
|
|
34
34
|
borderRadius: spacing.radiusLg,
|
|
@@ -61,7 +61,7 @@ function DialogTitle({ children, style, ...props }) {
|
|
|
61
61
|
{
|
|
62
62
|
fontSize: 18,
|
|
63
63
|
lineHeight: 24,
|
|
64
|
-
letterSpacing:
|
|
64
|
+
letterSpacing: 0,
|
|
65
65
|
color: theme.colors.text,
|
|
66
66
|
},
|
|
67
67
|
style,
|
|
@@ -98,14 +98,14 @@ function AlertDialogRoot({ children, ...props }) {
|
|
|
98
98
|
}
|
|
99
99
|
function AlertDialogContent({ portalHost, style, children, ...props }) {
|
|
100
100
|
const { theme, getShadowStyle, getContrastingColor } = useTheme();
|
|
101
|
-
const textColor = getContrastingColor(theme.colors.
|
|
101
|
+
const textColor = getContrastingColor(theme.colors.popover, palette.white, palette.black);
|
|
102
102
|
return (_jsx(AlertDialogPrimitive.Portal, { hostName: portalHost, children: _jsx(FullWindowOverlay, { children: _jsx(AlertDialogPrimitive.Overlay, { style: StyleSheet.flatten([
|
|
103
103
|
StyleSheet.absoluteFill,
|
|
104
104
|
{ backgroundColor: theme.colors.overlay },
|
|
105
105
|
Platform.OS === "web" && { zIndex: 52 },
|
|
106
106
|
]), children: _jsx(AnimatedView, { type: "fade", enterDuration: 200, children: _jsx(View, { style: overlayStyles.centeredContainer, children: _jsx(AnimatedView, { type: "scale", enterDuration: 250, children: _jsx(TextColorContext.Provider, { value: textColor, children: _jsx(TextClassContext.Provider, { value: "", children: _jsx(AlertDialogPrimitive.Content, { style: StyleSheet.flatten([
|
|
107
107
|
{
|
|
108
|
-
backgroundColor: theme.colors.
|
|
108
|
+
backgroundColor: theme.colors.popover,
|
|
109
109
|
borderColor: theme.colors.border,
|
|
110
110
|
borderWidth: 1,
|
|
111
111
|
borderRadius: spacing.radiusLg,
|
|
@@ -124,7 +124,7 @@ function AlertDialogTitle({ children, style, ...props }) {
|
|
|
124
124
|
{
|
|
125
125
|
fontSize: 18,
|
|
126
126
|
lineHeight: 24,
|
|
127
|
-
letterSpacing:
|
|
127
|
+
letterSpacing: 0,
|
|
128
128
|
color: theme.colors.text,
|
|
129
129
|
},
|
|
130
130
|
style,
|
|
@@ -70,9 +70,9 @@ function parseWidth(width) {
|
|
|
70
70
|
}
|
|
71
71
|
function drawerReducer(state, action) {
|
|
72
72
|
switch (action.type) {
|
|
73
|
-
case
|
|
74
|
-
case
|
|
75
|
-
case
|
|
73
|
+
case "OPEN": return true;
|
|
74
|
+
case "CLOSE": return false;
|
|
75
|
+
case "TOGGLE": return !state; // Always uses current state!
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
// ============================================================================
|
|
@@ -91,7 +91,7 @@ function DrawerRoot({ open: controlledOpen, onOpenChange: controlledOnOpenChange
|
|
|
91
91
|
controlledOnOpenChange?.(!controlledOpen);
|
|
92
92
|
}
|
|
93
93
|
else {
|
|
94
|
-
dispatch({ type:
|
|
94
|
+
dispatch({ type: "TOGGLE" });
|
|
95
95
|
}
|
|
96
96
|
};
|
|
97
97
|
// Handler for explicit open/close actions
|
|
@@ -100,7 +100,7 @@ function DrawerRoot({ open: controlledOpen, onOpenChange: controlledOnOpenChange
|
|
|
100
100
|
controlledOnOpenChange?.(newOpen);
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
|
-
dispatch({ type: newOpen ?
|
|
103
|
+
dispatch({ type: newOpen ? "OPEN" : "CLOSE" });
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
106
|
const parsedWidth = parseWidth(width);
|
|
@@ -3,7 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import { Platform, StyleSheet, Text, View } from "react-native";
|
|
4
4
|
import { Icon } from "./Icon.js";
|
|
5
5
|
import { AnimatedView } from "./AnimatedView.js";
|
|
6
|
-
import { TextClassContext } from "./StyledText.js";
|
|
6
|
+
import { TextClassContext, TextSelectabilityContext } from "./StyledText.js";
|
|
7
7
|
import { useTheme } from "../hooks/useTheme.js";
|
|
8
8
|
import { spacing } from "../constants/spacing.js";
|
|
9
9
|
import * as DropdownMenuPrimitive from "@rn-primitives/dropdown-menu";
|
|
@@ -22,28 +22,29 @@ function DropdownMenuSubTrigger({ inset = false, children, style: styleOverride,
|
|
|
22
22
|
const { theme } = useTheme();
|
|
23
23
|
const { open } = DropdownMenuPrimitive.useSubContext();
|
|
24
24
|
const iconName = Platform.OS === "web" ? "chevron-right" : open ? "chevron-up" : "chevron-down";
|
|
25
|
-
return (_jsx(TextClassContext.Provider, { value: "", children: _jsxs(DropdownMenuPrimitive.SubTrigger, { ...props, style: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
25
|
+
return (_jsx(TextClassContext.Provider, { value: "", children: _jsx(TextSelectabilityContext.Provider, { value: false, children: _jsxs(DropdownMenuPrimitive.SubTrigger, { ...props, style: {
|
|
26
|
+
flexDirection: "row",
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
borderRadius: spacing.radiusSm,
|
|
29
|
+
paddingHorizontal: spacing.sm,
|
|
30
|
+
paddingVertical: Platform.select({ web: spacing.xs, default: spacing.sm }),
|
|
31
|
+
backgroundColor: open ? theme.colors.muted : "transparent",
|
|
32
|
+
...(Platform.OS === "web" && {
|
|
33
|
+
cursor: "pointer",
|
|
34
|
+
outlineStyle: "none",
|
|
35
|
+
userSelect: "none",
|
|
36
|
+
}),
|
|
37
|
+
...(inset && { paddingLeft: spacing.xl }),
|
|
38
|
+
...(styleOverride && typeof styleOverride !== "function"
|
|
39
|
+
? StyleSheet.flatten(styleOverride)
|
|
40
|
+
: {}),
|
|
41
|
+
}, children: [typeof children === "function" ? null : children, _jsx(View, { style: { marginLeft: "auto" }, children: _jsx(Icon, { name: iconName, size: 16, color: theme.colors.text }) })] }) }) }));
|
|
41
42
|
}
|
|
42
43
|
function DropdownMenuSubContent({ style: styleOverride, ...props }) {
|
|
43
44
|
const { theme, getShadowStyle } = useTheme();
|
|
44
45
|
const shadowStyle = StyleSheet.flatten(getShadowStyle("soft"));
|
|
45
46
|
return (_jsx(AnimatedView, { type: "fade", children: _jsx(DropdownMenuPrimitive.SubContent, { ...props, style: {
|
|
46
|
-
backgroundColor: theme.colors.
|
|
47
|
+
backgroundColor: theme.colors.popover,
|
|
47
48
|
borderWidth: 1,
|
|
48
49
|
borderColor: theme.colors.border,
|
|
49
50
|
borderRadius: spacing.radiusMd,
|
|
@@ -66,108 +67,112 @@ function DropdownMenuContent({ side, align = "start", sideOffset = 4, portalHost
|
|
|
66
67
|
return (_jsx(DropdownMenuPrimitive.Portal, { hostName: portalHost, children: _jsx(FullWindowOverlay, { children: _jsx(DropdownMenuPrimitive.Overlay, { style: Platform.select({
|
|
67
68
|
native: StyleSheet.absoluteFill,
|
|
68
69
|
default: undefined,
|
|
69
|
-
}), children: _jsx(AnimatedView, { type: "fade", children: _jsx(TextClassContext.Provider, { value: "", children: _jsx(DropdownMenuPrimitive.Content, { side: side, align: align, sideOffset: sideOffset, insets: insets, avoidCollisions: true, ...props, style: {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
70
|
+
}), children: _jsx(AnimatedView, { type: "fade", children: _jsx(TextClassContext.Provider, { value: "", children: _jsx(TextSelectabilityContext.Provider, { value: false, children: _jsx(DropdownMenuPrimitive.Content, { side: side, align: align, sideOffset: sideOffset, insets: insets, avoidCollisions: true, ...props, style: {
|
|
71
|
+
backgroundColor: theme.colors.popover,
|
|
72
|
+
borderWidth: 1,
|
|
73
|
+
borderColor: theme.colors.border,
|
|
74
|
+
borderRadius: spacing.radiusSm,
|
|
75
|
+
padding: spacing.xs,
|
|
76
|
+
minWidth: 128,
|
|
77
|
+
overflow: "hidden",
|
|
78
|
+
...shadowStyle,
|
|
79
|
+
...(Platform.OS === "web" && {
|
|
80
|
+
zIndex: 50,
|
|
81
|
+
cursor: "default",
|
|
82
|
+
userSelect: "none",
|
|
83
|
+
}),
|
|
84
|
+
...(styleOverride && typeof styleOverride !== "function"
|
|
85
|
+
? StyleSheet.flatten(styleOverride)
|
|
86
|
+
: {}),
|
|
87
|
+
} }) }) }) }) }) }) }));
|
|
86
88
|
}
|
|
87
89
|
function DropdownMenuItem({ inset = false, variant = "default", style: styleOverride, ...props }) {
|
|
88
90
|
const { theme } = useTheme();
|
|
89
|
-
return (_jsx(TextClassContext.Provider, { value: "", children: _jsx(DropdownMenuPrimitive.Item, { ...props, style: {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
91
|
+
return (_jsx(TextClassContext.Provider, { value: "", children: _jsx(TextSelectabilityContext.Provider, { value: false, children: _jsx(DropdownMenuPrimitive.Item, { ...props, style: {
|
|
92
|
+
position: "relative",
|
|
93
|
+
flexDirection: "row",
|
|
94
|
+
alignItems: "center",
|
|
95
|
+
gap: spacing.sm,
|
|
96
|
+
borderRadius: spacing.radiusSm,
|
|
97
|
+
paddingHorizontal: spacing.sm,
|
|
98
|
+
paddingVertical: Platform.select({ web: spacing.xs, default: spacing.sm }),
|
|
99
|
+
backgroundColor: "transparent",
|
|
100
|
+
...(Platform.OS === "web" && {
|
|
101
|
+
cursor: props.disabled ? "not-allowed" : "pointer",
|
|
102
|
+
outlineStyle: "none",
|
|
103
|
+
userSelect: "none",
|
|
104
|
+
}),
|
|
105
|
+
...(props.disabled && { opacity: 0.5 }),
|
|
106
|
+
...(inset && { paddingLeft: spacing.xl }),
|
|
107
|
+
...(styleOverride && typeof styleOverride !== "function"
|
|
108
|
+
? StyleSheet.flatten(styleOverride)
|
|
109
|
+
: {}),
|
|
110
|
+
} }) }) }));
|
|
108
111
|
}
|
|
109
112
|
function DropdownMenuCheckboxItem({ children, style: styleOverride, ...props }) {
|
|
110
113
|
const { theme } = useTheme();
|
|
111
|
-
return (_jsx(TextClassContext.Provider, { value: "", children: _jsxs(DropdownMenuPrimitive.CheckboxItem, { ...props, style: {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
114
|
+
return (_jsx(TextClassContext.Provider, { value: "", children: _jsx(TextSelectabilityContext.Provider, { value: false, children: _jsxs(DropdownMenuPrimitive.CheckboxItem, { ...props, style: {
|
|
115
|
+
position: "relative",
|
|
116
|
+
flexDirection: "row",
|
|
117
|
+
alignItems: "center",
|
|
118
|
+
gap: spacing.sm,
|
|
119
|
+
borderRadius: spacing.radiusSm,
|
|
120
|
+
paddingVertical: Platform.select({ web: spacing.xs, default: spacing.sm }),
|
|
121
|
+
paddingLeft: spacing.xl,
|
|
122
|
+
paddingRight: spacing.sm,
|
|
123
|
+
backgroundColor: "transparent",
|
|
124
|
+
...(Platform.OS === "web" && {
|
|
125
|
+
cursor: props.disabled ? "not-allowed" : "pointer",
|
|
126
|
+
outlineStyle: "none",
|
|
127
|
+
userSelect: "none",
|
|
128
|
+
}),
|
|
129
|
+
...(props.disabled && { opacity: 0.5 }),
|
|
130
|
+
...(styleOverride && typeof styleOverride !== "function"
|
|
131
|
+
? StyleSheet.flatten(styleOverride)
|
|
132
|
+
: {}),
|
|
133
|
+
}, children: [_jsx(View, { style: {
|
|
134
|
+
position: "absolute",
|
|
135
|
+
left: spacing.sm,
|
|
136
|
+
height: 14,
|
|
137
|
+
width: 14,
|
|
138
|
+
alignItems: "center",
|
|
139
|
+
justifyContent: "center",
|
|
140
|
+
}, children: _jsx(DropdownMenuPrimitive.ItemIndicator, { children: _jsx(Icon, { name: "check", size: 16, color: theme.colors.text, ...(Platform.OS === "web" && { style: { pointerEvents: "none" } }) }) }) }), typeof children === "function" ? null : children] }) }) }));
|
|
137
141
|
}
|
|
138
142
|
function DropdownMenuRadioItem({ children, style: styleOverride, ...props }) {
|
|
139
143
|
const { theme } = useTheme();
|
|
140
|
-
return (_jsx(TextClassContext.Provider, { value: "", children: _jsxs(DropdownMenuPrimitive.RadioItem, { ...props, style: {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
144
|
+
return (_jsx(TextClassContext.Provider, { value: "", children: _jsx(TextSelectabilityContext.Provider, { value: false, children: _jsxs(DropdownMenuPrimitive.RadioItem, { ...props, style: {
|
|
145
|
+
position: "relative",
|
|
146
|
+
flexDirection: "row",
|
|
147
|
+
alignItems: "center",
|
|
148
|
+
gap: spacing.sm,
|
|
149
|
+
borderRadius: spacing.radiusSm,
|
|
150
|
+
paddingVertical: Platform.select({ web: spacing.xs, default: spacing.sm }),
|
|
151
|
+
paddingLeft: spacing.xl,
|
|
152
|
+
paddingRight: spacing.sm,
|
|
153
|
+
backgroundColor: "transparent",
|
|
154
|
+
...(Platform.OS === "web" && {
|
|
155
|
+
cursor: props.disabled ? "not-allowed" : "pointer",
|
|
156
|
+
outlineStyle: "none",
|
|
157
|
+
userSelect: "none",
|
|
158
|
+
}),
|
|
159
|
+
...(props.disabled && { opacity: 0.5 }),
|
|
160
|
+
...(styleOverride && typeof styleOverride !== "function"
|
|
161
|
+
? StyleSheet.flatten(styleOverride)
|
|
162
|
+
: {}),
|
|
163
|
+
}, children: [_jsx(View, { style: {
|
|
164
|
+
position: "absolute",
|
|
165
|
+
left: spacing.sm,
|
|
166
|
+
height: 14,
|
|
167
|
+
width: 14,
|
|
168
|
+
alignItems: "center",
|
|
169
|
+
justifyContent: "center",
|
|
170
|
+
}, children: _jsx(DropdownMenuPrimitive.ItemIndicator, { children: _jsx(View, { style: {
|
|
171
|
+
backgroundColor: theme.colors.text,
|
|
172
|
+
height: 8,
|
|
173
|
+
width: 8,
|
|
174
|
+
borderRadius: 4,
|
|
175
|
+
} }) }) }), typeof children === "function" ? null : children] }) }) }));
|
|
171
176
|
}
|
|
172
177
|
function DropdownMenuLabel({ inset = false, style: styleOverride, ...props }) {
|
|
173
178
|
const { theme } = useTheme();
|
|
@@ -177,6 +182,7 @@ function DropdownMenuLabel({ inset = false, style: styleOverride, ...props }) {
|
|
|
177
182
|
fontSize: 14,
|
|
178
183
|
fontWeight: "500",
|
|
179
184
|
color: theme.colors.text,
|
|
185
|
+
userSelect: "none",
|
|
180
186
|
...(inset && { paddingLeft: spacing.xl }),
|
|
181
187
|
...(styleOverride && typeof styleOverride !== "function"
|
|
182
188
|
? StyleSheet.flatten(styleOverride)
|
|
@@ -201,9 +207,10 @@ function DropdownMenuShortcut({ style: styleOverride, ...props }) {
|
|
|
201
207
|
{
|
|
202
208
|
marginLeft: "auto",
|
|
203
209
|
fontSize: 12,
|
|
204
|
-
letterSpacing:
|
|
210
|
+
letterSpacing: 0,
|
|
205
211
|
color: theme.colors.text,
|
|
206
212
|
opacity: 0.6,
|
|
213
|
+
userSelect: "none",
|
|
207
214
|
},
|
|
208
215
|
styleOverride,
|
|
209
216
|
] }));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
2
3
|
import { View, StyleSheet } from "react-native";
|
|
3
4
|
import { SansSerifBoldText, SansSerifText } from "./StyledText.js";
|
|
4
5
|
import { Button } from "./Button.js";
|
|
@@ -24,8 +25,8 @@ import { spacing } from "../constants/spacing.js";
|
|
|
24
25
|
*/
|
|
25
26
|
export function EmptyState({ icon, iconSize = 48, title, description, actionLabel, onAction, actionPreset = "default", style, children, }) {
|
|
26
27
|
const { theme } = useTheme();
|
|
27
|
-
const styles = createStyles(theme);
|
|
28
|
-
return (_jsxs(View, { style: [styles.container, style], children: [!!icon && (_jsx(View, { style: styles.iconWrapper, children: _jsx(Icon, { name: icon, size: iconSize, color: theme.colors.mutedForeground }) })), _jsx(SansSerifBoldText, { style: styles.title, children: title }), !!description && (_jsx(SansSerifText, { style: styles.description, children: description })), children, !!actionLabel && onAction && (_jsx(Button, { preset: actionPreset, onPress: onAction, style: styles.action, children: actionLabel }))] }));
|
|
28
|
+
const styles = useMemo(() => createStyles(theme), [theme]);
|
|
29
|
+
return (_jsxs(View, { style: [styles.container, style], children: [!!icon && (_jsx(View, { style: styles.iconWrapper, children: _jsx(Icon, { name: icon, size: iconSize, color: theme.colors.mutedForeground }) })), _jsx(SansSerifBoldText, { selectable: false, style: styles.title, children: title }), !!description && (_jsx(SansSerifText, { selectable: false, style: styles.description, children: description })), children, !!actionLabel && onAction && (_jsx(Button, { preset: actionPreset, onPress: onAction, style: styles.action, children: actionLabel }))] }));
|
|
29
30
|
}
|
|
30
31
|
const createStyles = (theme) => StyleSheet.create({
|
|
31
32
|
container: {
|
|
@@ -42,7 +43,7 @@ const createStyles = (theme) => StyleSheet.create({
|
|
|
42
43
|
lineHeight: 24,
|
|
43
44
|
color: theme.colors.foreground,
|
|
44
45
|
textAlign: "center",
|
|
45
|
-
letterSpacing:
|
|
46
|
+
letterSpacing: 0,
|
|
46
47
|
},
|
|
47
48
|
description: {
|
|
48
49
|
fontSize: 14,
|
|
@@ -54,5 +55,6 @@ const createStyles = (theme) => StyleSheet.create({
|
|
|
54
55
|
},
|
|
55
56
|
action: {
|
|
56
57
|
marginTop: spacing.lg,
|
|
58
|
+
alignSelf: "center",
|
|
57
59
|
},
|
|
58
60
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useRef, useState, useCallback } from "react";
|
|
2
|
+
import React, { useMemo, useRef, useState, useCallback } from "react";
|
|
3
3
|
import { View, TextInput as RNTextInput, Pressable, StyleSheet, Platform, } from "react-native";
|
|
4
4
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, useReducedMotion, } from "react-native-reanimated";
|
|
5
5
|
import { useTheme } from "../hooks/useTheme.js";
|
|
@@ -33,7 +33,7 @@ function InputOTP({ length = 6, value = "", onChangeText, onComplete, error = fa
|
|
|
33
33
|
const reduceMotion = useReducedMotion();
|
|
34
34
|
const inputRef = useRef(null);
|
|
35
35
|
const [focused, setFocused] = useState(false);
|
|
36
|
-
const styles = createStyles(theme);
|
|
36
|
+
const styles = useMemo(() => createStyles(theme), [theme]);
|
|
37
37
|
const hasError = error || !!errorText;
|
|
38
38
|
// Active cell index: next empty cell, or last cell when full
|
|
39
39
|
const activeIndex = Math.min(value.length, length - 1);
|
|
@@ -121,7 +121,7 @@ function OTPCell({ index, total, char, isActive, hasError, disabled, theme, redu
|
|
|
121
121
|
opacity: disabled ? 0.5 : 1,
|
|
122
122
|
},
|
|
123
123
|
animatedStyle,
|
|
124
|
-
], children: _jsx(StyledText, { style: {
|
|
124
|
+
], children: _jsx(StyledText, { selectable: false, style: {
|
|
125
125
|
fontSize: CELL_FONT_SIZE,
|
|
126
126
|
fontWeight: CELL_FONT_WEIGHT,
|
|
127
127
|
fontFamily: fontFamilies.sansSerif.regular,
|
package/dist/components/Label.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
2
3
|
import { StyleSheet, Platform } from "react-native";
|
|
3
4
|
import * as LabelPrimitive from "@rn-primitives/label";
|
|
4
5
|
import { useTheme } from "../hooks/useTheme.js";
|
|
@@ -36,7 +37,7 @@ const SIZE_CONFIGS = {
|
|
|
36
37
|
*/
|
|
37
38
|
export function Label({ children, nativeID, required, size = "md", error, disabled, style, onPress, }) {
|
|
38
39
|
const { theme } = useTheme();
|
|
39
|
-
const styles = createStyles(theme);
|
|
40
|
+
const styles = useMemo(() => createStyles(theme), [theme]);
|
|
40
41
|
const sizeConfig = SIZE_CONFIGS[size];
|
|
41
42
|
const textStyle = StyleSheet.flatten([
|
|
42
43
|
styles.label,
|
|
@@ -48,7 +49,7 @@ export function Label({ children, nativeID, required, size = "md", error, disabl
|
|
|
48
49
|
return (_jsx(LabelPrimitive.Root, { nativeID: nativeID, onPress: onPress, style: {
|
|
49
50
|
...styles.root,
|
|
50
51
|
...(Platform.OS === "web" && onPress && { cursor: "pointer" }),
|
|
51
|
-
}, children: _jsxs(LabelPrimitive.Text, { style: textStyle, children: [children, required && _jsx(StyledText, { style: styles.required, children: " *" })] }) }));
|
|
52
|
+
}, children: _jsxs(LabelPrimitive.Text, { style: textStyle, children: [children, required && _jsx(StyledText, { selectable: false, style: styles.required, children: " *" })] }) }));
|
|
52
53
|
}
|
|
53
54
|
const createStyles = (theme) => StyleSheet.create({
|
|
54
55
|
root: {
|
|
@@ -58,10 +59,12 @@ const createStyles = (theme) => StyleSheet.create({
|
|
|
58
59
|
fontFamily: fontFamilies.sansSerif.regular,
|
|
59
60
|
fontWeight: "500",
|
|
60
61
|
color: theme.colors.text,
|
|
62
|
+
userSelect: "none",
|
|
61
63
|
},
|
|
62
64
|
required: {
|
|
63
65
|
color: theme.colors.destructive,
|
|
64
66
|
fontFamily: fontFamilies.sansSerif.bold,
|
|
67
|
+
userSelect: "none",
|
|
65
68
|
},
|
|
66
69
|
errorLabel: {
|
|
67
70
|
color: theme.colors.destructive,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useContext, useEffect, useRef } from "react";
|
|
2
|
+
import { useMemo, useCallback, useContext, useEffect, useRef } from "react";
|
|
3
3
|
import { StyleSheet, View, ActivityIndicator, Pressable, Platform } from "react-native";
|
|
4
4
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, runOnJS, useReducedMotion, Easing, } from "react-native-reanimated";
|
|
5
5
|
import { SafeAreaInsetsContext } from "react-native-safe-area-context";
|
|
@@ -40,7 +40,7 @@ export const Notification = () => {
|
|
|
40
40
|
const reduceMotion = useReducedMotion();
|
|
41
41
|
const insets = useContext(SafeAreaInsetsContext);
|
|
42
42
|
const { alert, hide } = globalUIStore();
|
|
43
|
-
const styles = createStyles(theme);
|
|
43
|
+
const styles = useMemo(() => createStyles(theme), [theme]);
|
|
44
44
|
const position = alert?.position ?? "top";
|
|
45
45
|
const isBottom = position === "bottom";
|
|
46
46
|
// Just opacity + translateY — no scale (scale = bouncy feel)
|
|
@@ -164,7 +164,7 @@ export const Notification = () => {
|
|
|
164
164
|
styles.alert,
|
|
165
165
|
isBottom && styles.alertBottom,
|
|
166
166
|
getShadowStyle("base"),
|
|
167
|
-
], children: [_jsx(View, { style: [styles.iconBadge, { backgroundColor: iconBgColor }], children: alert?.loading ? (_jsx(ActivityIndicator, { size: "small", color: iconColor })) : (_jsx(Icon, { name: icon, size: 18, color: iconColor })) }), _jsxs(View, { style: styles.alertContent, children: [!!title && (_jsx(StyledText, { style: [styles.alertTitle, { color: theme.colors.foreground }], numberOfLines: 1, children: title })), hasMessage && (_jsx(StyledText, { style: [styles.alertDescription, { color: theme.colors.mutedForeground }], numberOfLines: 2, children: alert.messages[0] }))] }), _jsx(Pressable, { style: styles.closeButton, hitSlop: spacing.sm, onPress: animateOut, accessibilityLabel: "Dismiss notification", accessibilityRole: "button", children: _jsx(Icon, { name: "x", size: 16, color: theme.colors.mutedForeground }) })] }) }));
|
|
167
|
+
], children: [_jsx(View, { style: [styles.iconBadge, { backgroundColor: iconBgColor }], children: alert?.loading ? (_jsx(ActivityIndicator, { size: "small", color: iconColor })) : (_jsx(Icon, { name: icon, size: 18, color: iconColor })) }), _jsxs(View, { style: styles.alertContent, children: [!!title && (_jsx(StyledText, { selectable: false, style: [styles.alertTitle, { color: theme.colors.foreground }], numberOfLines: 1, children: title })), hasMessage && (_jsx(StyledText, { selectable: false, style: [styles.alertDescription, { color: theme.colors.mutedForeground }], numberOfLines: 2, children: alert.messages[0] }))] }), _jsx(Pressable, { style: styles.closeButton, hitSlop: spacing.sm, onPress: animateOut, accessibilityLabel: "Dismiss notification", accessibilityRole: "button", children: _jsx(Icon, { name: "x", size: 16, color: theme.colors.mutedForeground }) })] }) }));
|
|
168
168
|
};
|
|
169
169
|
const createStyles = (theme) => StyleSheet.create({
|
|
170
170
|
container: {
|
|
@@ -26,10 +26,10 @@ const FullWindowOverlay = Platform.OS === "ios" ? RNFullWindowOverlay : React.Fr
|
|
|
26
26
|
function PopoverContent({ side, align = "center", sideOffset = 4, portalHost, ...props }) {
|
|
27
27
|
const { theme, getShadowStyle, getContrastingColor } = useTheme();
|
|
28
28
|
// Calculate text color for popover content based on background
|
|
29
|
-
const textColor = getContrastingColor(theme.colors.
|
|
29
|
+
const textColor = getContrastingColor(theme.colors.popover, palette.white, palette.black);
|
|
30
30
|
const contentStyle = StyleSheet.flatten([
|
|
31
31
|
{
|
|
32
|
-
backgroundColor: theme.colors.
|
|
32
|
+
backgroundColor: theme.colors.popover,
|
|
33
33
|
borderColor: theme.colors.border,
|
|
34
34
|
borderWidth: 1,
|
|
35
35
|
borderRadius: spacing.radiusMd,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useContext, useEffect } from "react";
|
|
3
|
-
import { View, StyleSheet, Pressable } from "react-native";
|
|
3
|
+
import { View, StyleSheet, Pressable, Platform } from "react-native";
|
|
4
4
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, useReducedMotion, } from "react-native-reanimated";
|
|
5
5
|
import { StyledText } from "./StyledText.js";
|
|
6
6
|
import { useTheme } from "../hooks/useTheme.js";
|
|
@@ -78,7 +78,7 @@ function RadioGroupItem({ label, required = false, style: styleOverride, labelSt
|
|
|
78
78
|
const flattenedStyle = styleOverride ? StyleSheet.flatten(styleOverride) : undefined;
|
|
79
79
|
const radioElement = (_jsx(RadioGroupPrimitive.Item, { ...props, value: itemValue, disabled: disabled, onPress: handlePress, style: {
|
|
80
80
|
borderColor,
|
|
81
|
-
backgroundColor:
|
|
81
|
+
backgroundColor: theme.colors.background,
|
|
82
82
|
borderRadius: sizeConfig.outer / 2,
|
|
83
83
|
borderWidth: sizeConfig.borderWidth,
|
|
84
84
|
width: sizeConfig.outer,
|
|
@@ -86,6 +86,7 @@ function RadioGroupItem({ label, required = false, style: styleOverride, labelSt
|
|
|
86
86
|
justifyContent: "center",
|
|
87
87
|
alignItems: "center",
|
|
88
88
|
opacity: disabled ? 0.5 : 1,
|
|
89
|
+
...(Platform.OS === "web" && { cursor: disabled ? "not-allowed" : "pointer" }),
|
|
89
90
|
...(flattenedStyle || {}),
|
|
90
91
|
}, hitSlop: DEFAULT_HIT_SLOP, accessibilityLabel: label, children: _jsx(Animated.View, { style: [
|
|
91
92
|
dotStyle,
|
|
@@ -109,18 +110,19 @@ function RadioGroupItem({ label, required = false, style: styleOverride, labelSt
|
|
|
109
110
|
}, style: [styles.container, labelStyle], disabled: disabled, accessibilityRole: "radio", accessibilityState: {
|
|
110
111
|
checked: isChecked,
|
|
111
112
|
disabled: !!disabled,
|
|
112
|
-
}, accessibilityLabel: label, children: [radioElement, _jsx(View, { style: styles.labelContainer, children: _jsxs(StyledText, { style: [
|
|
113
|
+
}, accessibilityLabel: label, children: [radioElement, _jsx(View, { style: styles.labelContainer, children: _jsxs(StyledText, { selectable: false, style: [
|
|
113
114
|
styles.label,
|
|
114
115
|
{ color: theme.colors.text },
|
|
115
116
|
disabled && styles.disabledLabel,
|
|
116
117
|
error && { color: theme.colors.destructive },
|
|
117
|
-
], children: [label, required && (_jsx(StyledText, { style: [styles.required, { color: theme.colors.destructive }], children: " *" }))] }) })] }));
|
|
118
|
+
], children: [label, required && (_jsx(StyledText, { selectable: false, style: [styles.required, { color: theme.colors.destructive }], children: " *" }))] }) })] }));
|
|
118
119
|
}
|
|
119
120
|
const styles = StyleSheet.create({
|
|
120
121
|
container: {
|
|
121
122
|
flexDirection: "row",
|
|
122
123
|
alignItems: "center",
|
|
123
124
|
gap: spacing.sm,
|
|
125
|
+
minHeight: spacing.touchTarget,
|
|
124
126
|
},
|
|
125
127
|
labelContainer: {
|
|
126
128
|
flex: 1,
|