@xaui/native 0.0.6 → 0.0.8
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/button/index.cjs +1 -1
- package/dist/button/index.js +1 -1
- package/dist/checkbox/index.cjs +1 -1
- package/dist/checkbox/index.js +1 -1
- package/dist/switch/index.cjs +413 -0
- package/dist/switch/index.d.cts +28 -0
- package/dist/switch/index.d.ts +28 -0
- package/dist/switch/index.js +357 -0
- package/dist/view/index.cjs +960 -0
- package/dist/view/index.d.cts +517 -0
- package/dist/view/index.d.ts +517 -0
- package/dist/view/index.js +917 -0
- package/package.json +11 -1
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useXUITheme
|
|
3
|
+
} from "../chunk-ORMNMNOK.js";
|
|
4
|
+
|
|
5
|
+
// src/components/switch/switch.tsx
|
|
6
|
+
import React, { useEffect, useMemo as useMemo2, useRef, useState } from "react";
|
|
7
|
+
import { Animated as Animated2, Pressable, Text, View } from "react-native";
|
|
8
|
+
|
|
9
|
+
// src/components/switch/switch.hook.ts
|
|
10
|
+
import { useMemo } from "react";
|
|
11
|
+
import { getSafeThemeColor } from "@xaui/core";
|
|
12
|
+
var useSwitchColorScheme = (themeColor) => {
|
|
13
|
+
const theme = useXUITheme();
|
|
14
|
+
const safeThemeColor = getSafeThemeColor(themeColor);
|
|
15
|
+
return theme.colors[safeThemeColor];
|
|
16
|
+
};
|
|
17
|
+
var useSwitchSizeStyles = (variant, size) => {
|
|
18
|
+
const theme = useXUITheme();
|
|
19
|
+
const sizeStyles = useMemo(() => {
|
|
20
|
+
if (variant === "overlap") {
|
|
21
|
+
const sizes2 = {
|
|
22
|
+
sm: {
|
|
23
|
+
trackWidth: 40,
|
|
24
|
+
trackHeight: 16,
|
|
25
|
+
thumbSize: 22,
|
|
26
|
+
fontSize: theme.fontSizes.sm,
|
|
27
|
+
padding: 0
|
|
28
|
+
},
|
|
29
|
+
md: {
|
|
30
|
+
trackWidth: 48,
|
|
31
|
+
trackHeight: 18,
|
|
32
|
+
thumbSize: 26,
|
|
33
|
+
fontSize: theme.fontSizes.md,
|
|
34
|
+
padding: 0
|
|
35
|
+
},
|
|
36
|
+
lg: {
|
|
37
|
+
trackWidth: 56,
|
|
38
|
+
trackHeight: 20,
|
|
39
|
+
thumbSize: 30,
|
|
40
|
+
fontSize: theme.fontSizes.lg,
|
|
41
|
+
padding: 0
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return sizes2[size];
|
|
45
|
+
}
|
|
46
|
+
const sizes = {
|
|
47
|
+
sm: {
|
|
48
|
+
trackWidth: 40,
|
|
49
|
+
trackHeight: 24,
|
|
50
|
+
thumbSize: 18,
|
|
51
|
+
fontSize: theme.fontSizes.sm,
|
|
52
|
+
padding: 3
|
|
53
|
+
},
|
|
54
|
+
md: {
|
|
55
|
+
trackWidth: 48,
|
|
56
|
+
trackHeight: 28,
|
|
57
|
+
thumbSize: 22,
|
|
58
|
+
fontSize: theme.fontSizes.md,
|
|
59
|
+
padding: 3
|
|
60
|
+
},
|
|
61
|
+
lg: {
|
|
62
|
+
trackWidth: 56,
|
|
63
|
+
trackHeight: 32,
|
|
64
|
+
thumbSize: 26,
|
|
65
|
+
fontSize: theme.fontSizes.lg,
|
|
66
|
+
padding: 3
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
return sizes[size];
|
|
70
|
+
}, [size, theme, variant]);
|
|
71
|
+
return sizeStyles;
|
|
72
|
+
};
|
|
73
|
+
var useSwitchRadiusStyles = (radius) => {
|
|
74
|
+
const theme = useXUITheme();
|
|
75
|
+
const radiusStyles = useMemo(() => {
|
|
76
|
+
const radii = {
|
|
77
|
+
none: theme.borderRadius.none,
|
|
78
|
+
sm: theme.borderRadius.sm,
|
|
79
|
+
md: theme.borderRadius.md,
|
|
80
|
+
lg: theme.borderRadius.lg,
|
|
81
|
+
full: theme.borderRadius.full
|
|
82
|
+
};
|
|
83
|
+
return { borderRadius: radii[radius] };
|
|
84
|
+
}, [radius, theme]);
|
|
85
|
+
const thumbRadius = useMemo(() => {
|
|
86
|
+
const radii = {
|
|
87
|
+
none: theme.borderRadius.none,
|
|
88
|
+
sm: theme.borderRadius.sm,
|
|
89
|
+
md: theme.borderRadius.md,
|
|
90
|
+
lg: theme.borderRadius.lg,
|
|
91
|
+
full: theme.borderRadius.full
|
|
92
|
+
};
|
|
93
|
+
return radii[radius];
|
|
94
|
+
}, [radius, theme]);
|
|
95
|
+
return { radiusStyles, thumbRadius };
|
|
96
|
+
};
|
|
97
|
+
var useSwitchTrackStyles = ({
|
|
98
|
+
colorScheme,
|
|
99
|
+
isSelected,
|
|
100
|
+
variant,
|
|
101
|
+
sizeStyles,
|
|
102
|
+
radiusStyles
|
|
103
|
+
}) => {
|
|
104
|
+
const theme = useXUITheme();
|
|
105
|
+
const trackStyles = useMemo(() => {
|
|
106
|
+
const backgroundColor = isSelected ? variant === "overlap" ? colorScheme.background : colorScheme.main : theme.colors.default.background;
|
|
107
|
+
return {
|
|
108
|
+
width: sizeStyles.trackWidth,
|
|
109
|
+
height: sizeStyles.trackHeight,
|
|
110
|
+
backgroundColor,
|
|
111
|
+
paddingHorizontal: sizeStyles.padding,
|
|
112
|
+
...radiusStyles
|
|
113
|
+
};
|
|
114
|
+
}, [colorScheme, isSelected, radiusStyles, sizeStyles, theme, variant]);
|
|
115
|
+
return trackStyles;
|
|
116
|
+
};
|
|
117
|
+
var useSwitchThumbStyles = ({
|
|
118
|
+
colorScheme,
|
|
119
|
+
isSelected,
|
|
120
|
+
variant,
|
|
121
|
+
sizeStyles,
|
|
122
|
+
thumbRadius
|
|
123
|
+
}) => {
|
|
124
|
+
const theme = useXUITheme();
|
|
125
|
+
const thumbStyles = useMemo(() => {
|
|
126
|
+
const baseStyle = {
|
|
127
|
+
width: sizeStyles.thumbSize,
|
|
128
|
+
height: sizeStyles.thumbSize,
|
|
129
|
+
borderRadius: thumbRadius,
|
|
130
|
+
backgroundColor: variant === "overlap" && isSelected ? colorScheme.main : theme.colors.background
|
|
131
|
+
};
|
|
132
|
+
if (variant !== "overlap") return baseStyle;
|
|
133
|
+
return {
|
|
134
|
+
...baseStyle,
|
|
135
|
+
...theme.shadows.sm
|
|
136
|
+
};
|
|
137
|
+
}, [colorScheme, isSelected, sizeStyles, theme, thumbRadius, variant]);
|
|
138
|
+
return thumbStyles;
|
|
139
|
+
};
|
|
140
|
+
var useSwitchContainerStyles = (labelAlignment) => {
|
|
141
|
+
const containerStyles = useMemo(() => {
|
|
142
|
+
const isJustified = labelAlignment === "justify-left" || labelAlignment === "justify-right";
|
|
143
|
+
return {
|
|
144
|
+
flexDirection: labelAlignment === "left" || labelAlignment === "justify-left" ? "row-reverse" : "row",
|
|
145
|
+
justifyContent: isJustified ? "space-between" : "flex-start"
|
|
146
|
+
};
|
|
147
|
+
}, [labelAlignment]);
|
|
148
|
+
return containerStyles;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// src/components/switch/switch.animation.ts
|
|
152
|
+
import { Animated } from "react-native";
|
|
153
|
+
var runThumbPositionAnimation = (thumbPosition, isSelected) => {
|
|
154
|
+
Animated.spring(thumbPosition, {
|
|
155
|
+
toValue: isSelected ? 1 : 0,
|
|
156
|
+
useNativeDriver: true,
|
|
157
|
+
damping: 15,
|
|
158
|
+
stiffness: 150
|
|
159
|
+
}).start();
|
|
160
|
+
};
|
|
161
|
+
var runSwitchPressInAnimation = (animatedScale, animatedThumbScale, isOverlap) => {
|
|
162
|
+
Animated.parallel([
|
|
163
|
+
Animated.spring(animatedScale, {
|
|
164
|
+
toValue: 0.95,
|
|
165
|
+
useNativeDriver: true
|
|
166
|
+
}),
|
|
167
|
+
Animated.spring(animatedThumbScale, {
|
|
168
|
+
toValue: isOverlap ? 1.1 : 1.2,
|
|
169
|
+
useNativeDriver: true
|
|
170
|
+
})
|
|
171
|
+
]).start();
|
|
172
|
+
};
|
|
173
|
+
var runSwitchPressOutAnimation = (animatedScale, animatedThumbScale) => {
|
|
174
|
+
Animated.parallel([
|
|
175
|
+
Animated.spring(animatedScale, {
|
|
176
|
+
toValue: 1,
|
|
177
|
+
useNativeDriver: true
|
|
178
|
+
}),
|
|
179
|
+
Animated.spring(animatedThumbScale, {
|
|
180
|
+
toValue: 1,
|
|
181
|
+
useNativeDriver: true
|
|
182
|
+
})
|
|
183
|
+
]).start();
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// src/components/switch/switch.style.ts
|
|
187
|
+
import { StyleSheet } from "react-native";
|
|
188
|
+
var styles = StyleSheet.create({
|
|
189
|
+
container: {
|
|
190
|
+
flexDirection: "row",
|
|
191
|
+
alignItems: "center",
|
|
192
|
+
gap: 8
|
|
193
|
+
},
|
|
194
|
+
fullWidth: {
|
|
195
|
+
width: "100%"
|
|
196
|
+
},
|
|
197
|
+
track: {
|
|
198
|
+
justifyContent: "center",
|
|
199
|
+
position: "relative"
|
|
200
|
+
},
|
|
201
|
+
thumbContainer: {
|
|
202
|
+
position: "relative",
|
|
203
|
+
width: "100%",
|
|
204
|
+
height: "100%",
|
|
205
|
+
alignItems: "center",
|
|
206
|
+
justifyContent: "center"
|
|
207
|
+
},
|
|
208
|
+
thumb: {
|
|
209
|
+
position: "absolute",
|
|
210
|
+
left: 0
|
|
211
|
+
},
|
|
212
|
+
label: {
|
|
213
|
+
fontWeight: "400"
|
|
214
|
+
},
|
|
215
|
+
disabled: {
|
|
216
|
+
opacity: 0.5
|
|
217
|
+
},
|
|
218
|
+
disabledText: {
|
|
219
|
+
opacity: 0.7
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// src/components/switch/switch.tsx
|
|
224
|
+
var Switch = ({
|
|
225
|
+
label,
|
|
226
|
+
labelAlignment = "right",
|
|
227
|
+
themeColor = "primary",
|
|
228
|
+
variant = "inside",
|
|
229
|
+
size = "md",
|
|
230
|
+
radius = "full",
|
|
231
|
+
fullWidth = false,
|
|
232
|
+
isSelected: isSelectedProp,
|
|
233
|
+
isDisabled = false,
|
|
234
|
+
labelStyle,
|
|
235
|
+
style,
|
|
236
|
+
onValueChange
|
|
237
|
+
}) => {
|
|
238
|
+
const theme = useXUITheme();
|
|
239
|
+
const isControlled = typeof isSelectedProp === "boolean";
|
|
240
|
+
const [internalSelected, setInternalSelected] = useState(isSelectedProp ?? false);
|
|
241
|
+
const isSelected = isControlled ? isSelectedProp : internalSelected;
|
|
242
|
+
const scale = useRef(new Animated2.Value(1)).current;
|
|
243
|
+
const thumbPosition = useRef(new Animated2.Value(isSelected ? 1 : 0)).current;
|
|
244
|
+
const thumbScale = useRef(new Animated2.Value(1)).current;
|
|
245
|
+
const colorScheme = useSwitchColorScheme(themeColor);
|
|
246
|
+
const sizeStyles = useSwitchSizeStyles(variant, size);
|
|
247
|
+
const { radiusStyles, thumbRadius } = useSwitchRadiusStyles(radius);
|
|
248
|
+
const trackStyles = useSwitchTrackStyles({
|
|
249
|
+
colorScheme,
|
|
250
|
+
isSelected,
|
|
251
|
+
variant,
|
|
252
|
+
sizeStyles,
|
|
253
|
+
radiusStyles
|
|
254
|
+
});
|
|
255
|
+
const thumbStyles = useSwitchThumbStyles({
|
|
256
|
+
colorScheme,
|
|
257
|
+
isSelected,
|
|
258
|
+
variant,
|
|
259
|
+
sizeStyles,
|
|
260
|
+
thumbRadius
|
|
261
|
+
});
|
|
262
|
+
const containerStyles = useSwitchContainerStyles(labelAlignment);
|
|
263
|
+
const maxTranslateX = useMemo2(() => {
|
|
264
|
+
if (variant === "overlap") {
|
|
265
|
+
return sizeStyles.trackWidth - sizeStyles.thumbSize;
|
|
266
|
+
}
|
|
267
|
+
return sizeStyles.trackWidth - sizeStyles.thumbSize - sizeStyles.padding * 2;
|
|
268
|
+
}, [sizeStyles, variant]);
|
|
269
|
+
const translateX = useMemo2(
|
|
270
|
+
() => thumbPosition.interpolate({
|
|
271
|
+
inputRange: [0, 1],
|
|
272
|
+
outputRange: [0, maxTranslateX]
|
|
273
|
+
}),
|
|
274
|
+
[maxTranslateX, thumbPosition]
|
|
275
|
+
);
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
runThumbPositionAnimation(thumbPosition, isSelected);
|
|
278
|
+
}, [isSelected, thumbPosition]);
|
|
279
|
+
const handlePress = () => {
|
|
280
|
+
if (isDisabled) return;
|
|
281
|
+
const nextValue = !isSelected;
|
|
282
|
+
onValueChange?.(nextValue);
|
|
283
|
+
if (!isControlled) {
|
|
284
|
+
setInternalSelected(nextValue);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
const handlePressIn = () => {
|
|
288
|
+
if (isDisabled) return;
|
|
289
|
+
runSwitchPressInAnimation(scale, thumbScale, variant === "overlap");
|
|
290
|
+
};
|
|
291
|
+
const handlePressOut = () => {
|
|
292
|
+
if (isDisabled) return;
|
|
293
|
+
runSwitchPressOutAnimation(scale, thumbScale);
|
|
294
|
+
};
|
|
295
|
+
return /* @__PURE__ */ React.createElement(
|
|
296
|
+
Pressable,
|
|
297
|
+
{
|
|
298
|
+
onPress: handlePress,
|
|
299
|
+
onPressIn: handlePressIn,
|
|
300
|
+
onPressOut: handlePressOut,
|
|
301
|
+
disabled: isDisabled,
|
|
302
|
+
accessible: true,
|
|
303
|
+
accessibilityRole: "switch",
|
|
304
|
+
accessibilityLabel: label,
|
|
305
|
+
accessibilityState: {
|
|
306
|
+
disabled: isDisabled,
|
|
307
|
+
checked: isSelected
|
|
308
|
+
},
|
|
309
|
+
style: [
|
|
310
|
+
styles.container,
|
|
311
|
+
containerStyles,
|
|
312
|
+
fullWidth && styles.fullWidth,
|
|
313
|
+
isDisabled && styles.disabled,
|
|
314
|
+
style
|
|
315
|
+
]
|
|
316
|
+
},
|
|
317
|
+
/* @__PURE__ */ React.createElement(
|
|
318
|
+
Animated2.View,
|
|
319
|
+
{
|
|
320
|
+
style: [
|
|
321
|
+
styles.track,
|
|
322
|
+
trackStyles,
|
|
323
|
+
{
|
|
324
|
+
transform: [{ scale }]
|
|
325
|
+
}
|
|
326
|
+
]
|
|
327
|
+
},
|
|
328
|
+
/* @__PURE__ */ React.createElement(View, { style: styles.thumbContainer }, /* @__PURE__ */ React.createElement(
|
|
329
|
+
Animated2.View,
|
|
330
|
+
{
|
|
331
|
+
style: [
|
|
332
|
+
styles.thumb,
|
|
333
|
+
thumbStyles,
|
|
334
|
+
{
|
|
335
|
+
transform: [{ translateX }, { scale: thumbScale }]
|
|
336
|
+
}
|
|
337
|
+
]
|
|
338
|
+
}
|
|
339
|
+
))
|
|
340
|
+
),
|
|
341
|
+
label && /* @__PURE__ */ React.createElement(
|
|
342
|
+
Text,
|
|
343
|
+
{
|
|
344
|
+
style: [
|
|
345
|
+
styles.label,
|
|
346
|
+
{ fontSize: sizeStyles.fontSize, color: theme.colors.foreground },
|
|
347
|
+
isDisabled && styles.disabledText,
|
|
348
|
+
labelStyle
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
label
|
|
352
|
+
)
|
|
353
|
+
);
|
|
354
|
+
};
|
|
355
|
+
export {
|
|
356
|
+
Switch
|
|
357
|
+
};
|