@xaui/native 0.0.2 → 0.0.3
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 +90 -68
- package/dist/button/index.d.cts +3 -4
- package/dist/button/index.d.ts +3 -4
- package/dist/button/index.js +76 -67
- package/dist/checkbox/index.cjs +416 -0
- package/dist/checkbox/index.d.cts +75 -0
- package/dist/checkbox/index.d.ts +75 -0
- package/dist/checkbox/index.js +364 -0
- package/dist/{chunk-6ITFLLAM.js → chunk-52PIZF2Z.js} +1 -1
- package/dist/{chunk-SHT66VET.js → chunk-DNJWBME5.js} +17 -2
- package/dist/core/index.js +1 -1
- package/dist/{theme-qvIXI4kF.d.cts → index-BDSvmsTU.d.cts} +2 -1
- package/dist/{theme-qvIXI4kF.d.ts → index-BDSvmsTU.d.ts} +2 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/indicator/index.d.cts +1 -1
- package/dist/indicator/index.d.ts +1 -1
- package/dist/indicator/index.js +2 -2
- package/dist/progress/index.d.cts +1 -1
- package/dist/progress/index.d.ts +1 -1
- package/dist/progress/index.js +1 -1
- package/package.json +21 -12
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useXUITheme
|
|
3
|
+
} from "../chunk-DNJWBME5.js";
|
|
4
|
+
|
|
5
|
+
// src/components/checkbox/checkbox.tsx
|
|
6
|
+
import React2, { useEffect as useEffect2, useRef as useRef2, useState } from "react";
|
|
7
|
+
import { Animated as Animated2, Pressable, Text, View } from "react-native";
|
|
8
|
+
|
|
9
|
+
// src/components/checkbox/checkbox-icon.tsx
|
|
10
|
+
import React, { useEffect, useRef } from "react";
|
|
11
|
+
import { Animated } from "react-native";
|
|
12
|
+
import Svg, { Polyline, Line } from "react-native-svg";
|
|
13
|
+
var AnimatedSvg = Animated.createAnimatedComponent(Svg);
|
|
14
|
+
var AnimatedPolyline = Animated.createAnimatedComponent(Polyline);
|
|
15
|
+
function CheckIcon({ isChecked, color, size }) {
|
|
16
|
+
const opacity = useRef(new Animated.Value(0)).current;
|
|
17
|
+
const strokeDashoffset = useRef(new Animated.Value(66)).current;
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (isChecked) {
|
|
20
|
+
Animated.parallel([
|
|
21
|
+
Animated.timing(opacity, {
|
|
22
|
+
toValue: 1,
|
|
23
|
+
duration: 200,
|
|
24
|
+
useNativeDriver: false
|
|
25
|
+
}),
|
|
26
|
+
Animated.timing(strokeDashoffset, {
|
|
27
|
+
toValue: 44,
|
|
28
|
+
duration: 250,
|
|
29
|
+
useNativeDriver: false
|
|
30
|
+
})
|
|
31
|
+
]).start();
|
|
32
|
+
} else {
|
|
33
|
+
Animated.parallel([
|
|
34
|
+
Animated.timing(opacity, {
|
|
35
|
+
toValue: 0,
|
|
36
|
+
duration: 200,
|
|
37
|
+
useNativeDriver: false
|
|
38
|
+
}),
|
|
39
|
+
Animated.timing(strokeDashoffset, {
|
|
40
|
+
toValue: 66,
|
|
41
|
+
duration: 250,
|
|
42
|
+
useNativeDriver: false
|
|
43
|
+
})
|
|
44
|
+
]).start();
|
|
45
|
+
}
|
|
46
|
+
}, [isChecked, opacity, strokeDashoffset]);
|
|
47
|
+
return /* @__PURE__ */ React.createElement(AnimatedSvg, { width: size, height: size, viewBox: "0 0 17 18", fill: "none", opacity }, /* @__PURE__ */ React.createElement(
|
|
48
|
+
AnimatedPolyline,
|
|
49
|
+
{
|
|
50
|
+
points: "1 9 7 14 15 4",
|
|
51
|
+
stroke: color,
|
|
52
|
+
strokeWidth: 2,
|
|
53
|
+
strokeLinecap: "round",
|
|
54
|
+
strokeLinejoin: "round",
|
|
55
|
+
strokeDasharray: "22",
|
|
56
|
+
strokeDashoffset
|
|
57
|
+
}
|
|
58
|
+
));
|
|
59
|
+
}
|
|
60
|
+
function IndeterminateIcon({
|
|
61
|
+
color,
|
|
62
|
+
size
|
|
63
|
+
}) {
|
|
64
|
+
return /* @__PURE__ */ React.createElement(Svg, { width: size, height: size, viewBox: "0 0 24 24" }, /* @__PURE__ */ React.createElement(Line, { x1: "21", y1: "12", x2: "3", y2: "12", stroke: color, strokeWidth: 3 }));
|
|
65
|
+
}
|
|
66
|
+
function CheckboxIcon({ isIndeterminate, ...props }) {
|
|
67
|
+
const BaseIcon = isIndeterminate ? IndeterminateIcon : CheckIcon;
|
|
68
|
+
return /* @__PURE__ */ React.createElement(BaseIcon, { ...props });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/components/checkbox/checkbox.hook.ts
|
|
72
|
+
import { useMemo } from "react";
|
|
73
|
+
import { getSafeThemeColor } from "@xaui/core";
|
|
74
|
+
var useCheckboxStyles = (themeColor, variant, size, radius, labelAlignment, isActive) => {
|
|
75
|
+
const theme = useXUITheme();
|
|
76
|
+
const safeThemeColor = getSafeThemeColor(themeColor);
|
|
77
|
+
const colorScheme = theme.colors[safeThemeColor];
|
|
78
|
+
const sizeStyles = useMemo(() => {
|
|
79
|
+
const sizes = {
|
|
80
|
+
sm: {
|
|
81
|
+
checkboxSize: 18,
|
|
82
|
+
fontSize: theme.fontSizes.sm,
|
|
83
|
+
iconSize: variant === "light" ? 14 : 12
|
|
84
|
+
},
|
|
85
|
+
md: {
|
|
86
|
+
checkboxSize: 22,
|
|
87
|
+
fontSize: theme.fontSizes.md,
|
|
88
|
+
iconSize: variant === "light" ? 18 : 14
|
|
89
|
+
},
|
|
90
|
+
lg: {
|
|
91
|
+
checkboxSize: 26,
|
|
92
|
+
fontSize: theme.fontSizes.lg,
|
|
93
|
+
iconSize: variant === "light" ? 22 : 16
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
return sizes[size];
|
|
97
|
+
}, [size, theme, variant]);
|
|
98
|
+
const radiusStyles = useMemo(() => {
|
|
99
|
+
const radii = {
|
|
100
|
+
none: theme.borderRadius.none,
|
|
101
|
+
sm: theme.borderRadius.sm,
|
|
102
|
+
md: theme.borderRadius.md,
|
|
103
|
+
lg: theme.borderRadius.lg,
|
|
104
|
+
full: theme.borderRadius.full
|
|
105
|
+
};
|
|
106
|
+
return { borderRadius: radii[radius] };
|
|
107
|
+
}, [radius, theme]);
|
|
108
|
+
const checkboxStyles = useMemo(() => {
|
|
109
|
+
const baseStyle = {
|
|
110
|
+
width: sizeStyles.checkboxSize,
|
|
111
|
+
height: sizeStyles.checkboxSize,
|
|
112
|
+
...radiusStyles
|
|
113
|
+
};
|
|
114
|
+
if (variant === "filled") {
|
|
115
|
+
return {
|
|
116
|
+
...baseStyle,
|
|
117
|
+
backgroundColor: "transparent",
|
|
118
|
+
borderWidth: isActive ? 0 : theme.borderWidth.md,
|
|
119
|
+
borderColor: isActive ? "transparent" : colorScheme.main
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
...baseStyle,
|
|
124
|
+
backgroundColor: "transparent",
|
|
125
|
+
borderWidth: 0,
|
|
126
|
+
borderColor: "transparent"
|
|
127
|
+
};
|
|
128
|
+
}, [variant, isActive, colorScheme, sizeStyles, radiusStyles, theme]);
|
|
129
|
+
const checkmarkColor = useMemo(() => {
|
|
130
|
+
if (variant === "filled") {
|
|
131
|
+
return colorScheme.foreground;
|
|
132
|
+
}
|
|
133
|
+
if (isActive) {
|
|
134
|
+
return colorScheme.main;
|
|
135
|
+
}
|
|
136
|
+
if (themeColor !== "default") {
|
|
137
|
+
return colorScheme.background;
|
|
138
|
+
}
|
|
139
|
+
return theme.colors.foreground;
|
|
140
|
+
}, [variant, colorScheme, isActive, themeColor, theme.colors.foreground]);
|
|
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 {
|
|
149
|
+
colorScheme,
|
|
150
|
+
sizeStyles,
|
|
151
|
+
radiusStyles,
|
|
152
|
+
checkboxStyles,
|
|
153
|
+
checkmarkColor,
|
|
154
|
+
containerStyles
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// src/components/checkbox/checkbox.style.ts
|
|
159
|
+
import { StyleSheet } from "react-native";
|
|
160
|
+
var styles = StyleSheet.create({
|
|
161
|
+
container: {
|
|
162
|
+
flexDirection: "row",
|
|
163
|
+
alignItems: "center",
|
|
164
|
+
gap: 10
|
|
165
|
+
},
|
|
166
|
+
fullWidth: {
|
|
167
|
+
width: "100%"
|
|
168
|
+
},
|
|
169
|
+
checkbox: {
|
|
170
|
+
alignItems: "center",
|
|
171
|
+
justifyContent: "center",
|
|
172
|
+
overflow: "hidden",
|
|
173
|
+
position: "relative"
|
|
174
|
+
},
|
|
175
|
+
background: {
|
|
176
|
+
position: "absolute",
|
|
177
|
+
width: "100%",
|
|
178
|
+
height: "100%"
|
|
179
|
+
},
|
|
180
|
+
checkmarkContainer: {
|
|
181
|
+
alignItems: "center",
|
|
182
|
+
justifyContent: "center",
|
|
183
|
+
zIndex: 10
|
|
184
|
+
},
|
|
185
|
+
label: {
|
|
186
|
+
fontWeight: "400"
|
|
187
|
+
},
|
|
188
|
+
disabled: {
|
|
189
|
+
opacity: 0.5
|
|
190
|
+
},
|
|
191
|
+
disabledText: {
|
|
192
|
+
opacity: 0.7
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// src/components/checkbox/checkbox.tsx
|
|
197
|
+
var Checkbox = ({
|
|
198
|
+
label,
|
|
199
|
+
labelAlignment = "right",
|
|
200
|
+
themeColor = "default",
|
|
201
|
+
variant = "filled",
|
|
202
|
+
size = "md",
|
|
203
|
+
radius = "sm",
|
|
204
|
+
fullWidth = false,
|
|
205
|
+
isChecked: isCheckedProp,
|
|
206
|
+
isIndeterminate = false,
|
|
207
|
+
isDisabled = false,
|
|
208
|
+
labelStyle,
|
|
209
|
+
style,
|
|
210
|
+
onValueChange
|
|
211
|
+
}) => {
|
|
212
|
+
const theme = useXUITheme();
|
|
213
|
+
const isControlled = typeof isCheckedProp === "boolean";
|
|
214
|
+
const [internalChecked, setInternalChecked] = useState(isCheckedProp ?? false);
|
|
215
|
+
const isChecked = isControlled ? isCheckedProp : internalChecked;
|
|
216
|
+
const scale = useRef2(new Animated2.Value(1)).current;
|
|
217
|
+
const backgroundScale = useRef2(new Animated2.Value(0.5)).current;
|
|
218
|
+
const backgroundOpacity = useRef2(new Animated2.Value(0)).current;
|
|
219
|
+
const isActive = isChecked || isIndeterminate;
|
|
220
|
+
const {
|
|
221
|
+
colorScheme,
|
|
222
|
+
sizeStyles,
|
|
223
|
+
radiusStyles,
|
|
224
|
+
checkboxStyles,
|
|
225
|
+
checkmarkColor,
|
|
226
|
+
containerStyles
|
|
227
|
+
} = useCheckboxStyles(
|
|
228
|
+
themeColor,
|
|
229
|
+
variant,
|
|
230
|
+
size,
|
|
231
|
+
radius,
|
|
232
|
+
labelAlignment,
|
|
233
|
+
isActive
|
|
234
|
+
);
|
|
235
|
+
useEffect2(() => {
|
|
236
|
+
if (variant !== "filled") return;
|
|
237
|
+
if (isActive) {
|
|
238
|
+
Animated2.parallel([
|
|
239
|
+
Animated2.timing(backgroundScale, {
|
|
240
|
+
toValue: 1,
|
|
241
|
+
duration: 200,
|
|
242
|
+
useNativeDriver: true
|
|
243
|
+
}),
|
|
244
|
+
Animated2.timing(backgroundOpacity, {
|
|
245
|
+
toValue: 1,
|
|
246
|
+
duration: 200,
|
|
247
|
+
useNativeDriver: true
|
|
248
|
+
})
|
|
249
|
+
]).start();
|
|
250
|
+
} else {
|
|
251
|
+
Animated2.parallel([
|
|
252
|
+
Animated2.timing(backgroundScale, {
|
|
253
|
+
toValue: 0.5,
|
|
254
|
+
duration: 200,
|
|
255
|
+
useNativeDriver: true
|
|
256
|
+
}),
|
|
257
|
+
Animated2.timing(backgroundOpacity, {
|
|
258
|
+
toValue: 0,
|
|
259
|
+
duration: 200,
|
|
260
|
+
useNativeDriver: true
|
|
261
|
+
})
|
|
262
|
+
]).start();
|
|
263
|
+
}
|
|
264
|
+
}, [isActive, variant, backgroundScale, backgroundOpacity]);
|
|
265
|
+
const handlePress = () => {
|
|
266
|
+
if (!isDisabled) {
|
|
267
|
+
const nextValue = isIndeterminate ? true : !isChecked;
|
|
268
|
+
onValueChange?.(nextValue);
|
|
269
|
+
if (!isControlled) {
|
|
270
|
+
setInternalChecked(nextValue);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
const handlePressIn = () => {
|
|
275
|
+
if (!isDisabled) {
|
|
276
|
+
Animated2.spring(scale, {
|
|
277
|
+
toValue: 0.95,
|
|
278
|
+
useNativeDriver: true
|
|
279
|
+
}).start();
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
const handlePressOut = () => {
|
|
283
|
+
if (!isDisabled) {
|
|
284
|
+
Animated2.spring(scale, {
|
|
285
|
+
toValue: 1,
|
|
286
|
+
useNativeDriver: true
|
|
287
|
+
}).start();
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
const accessibilityChecked = isIndeterminate ? "mixed" : isChecked;
|
|
291
|
+
return /* @__PURE__ */ React2.createElement(
|
|
292
|
+
Pressable,
|
|
293
|
+
{
|
|
294
|
+
onPress: handlePress,
|
|
295
|
+
onPressIn: handlePressIn,
|
|
296
|
+
onPressOut: handlePressOut,
|
|
297
|
+
disabled: isDisabled,
|
|
298
|
+
accessible: true,
|
|
299
|
+
accessibilityRole: "checkbox",
|
|
300
|
+
accessibilityLabel: label,
|
|
301
|
+
accessibilityState: {
|
|
302
|
+
disabled: isDisabled,
|
|
303
|
+
checked: accessibilityChecked
|
|
304
|
+
},
|
|
305
|
+
style: [
|
|
306
|
+
styles.container,
|
|
307
|
+
containerStyles,
|
|
308
|
+
fullWidth && styles.fullWidth,
|
|
309
|
+
isDisabled && styles.disabled,
|
|
310
|
+
style
|
|
311
|
+
]
|
|
312
|
+
},
|
|
313
|
+
/* @__PURE__ */ React2.createElement(
|
|
314
|
+
Animated2.View,
|
|
315
|
+
{
|
|
316
|
+
style: [
|
|
317
|
+
styles.checkbox,
|
|
318
|
+
checkboxStyles,
|
|
319
|
+
{
|
|
320
|
+
transform: [{ scale }]
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
},
|
|
324
|
+
variant === "filled" && /* @__PURE__ */ React2.createElement(
|
|
325
|
+
Animated2.View,
|
|
326
|
+
{
|
|
327
|
+
style: [
|
|
328
|
+
styles.background,
|
|
329
|
+
radiusStyles,
|
|
330
|
+
{
|
|
331
|
+
backgroundColor: colorScheme.main,
|
|
332
|
+
transform: [{ scale: backgroundScale }],
|
|
333
|
+
opacity: backgroundOpacity
|
|
334
|
+
}
|
|
335
|
+
]
|
|
336
|
+
}
|
|
337
|
+
),
|
|
338
|
+
/* @__PURE__ */ React2.createElement(View, { style: styles.checkmarkContainer }, /* @__PURE__ */ React2.createElement(
|
|
339
|
+
CheckboxIcon,
|
|
340
|
+
{
|
|
341
|
+
isChecked: isActive,
|
|
342
|
+
isIndeterminate,
|
|
343
|
+
color: checkmarkColor,
|
|
344
|
+
size: sizeStyles.iconSize
|
|
345
|
+
}
|
|
346
|
+
))
|
|
347
|
+
),
|
|
348
|
+
label && /* @__PURE__ */ React2.createElement(
|
|
349
|
+
Text,
|
|
350
|
+
{
|
|
351
|
+
style: [
|
|
352
|
+
styles.label,
|
|
353
|
+
{ fontSize: sizeStyles.fontSize, color: theme.colors.foreground },
|
|
354
|
+
isDisabled && styles.disabledText,
|
|
355
|
+
labelStyle
|
|
356
|
+
]
|
|
357
|
+
},
|
|
358
|
+
label
|
|
359
|
+
)
|
|
360
|
+
);
|
|
361
|
+
};
|
|
362
|
+
export {
|
|
363
|
+
Checkbox
|
|
364
|
+
};
|
|
@@ -34,7 +34,7 @@ function XUIProvider({
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// src/core/theme-hooks.ts
|
|
37
|
-
import { useContext } from "react";
|
|
37
|
+
import { useContext, useMemo } from "react";
|
|
38
38
|
import { useColorScheme as useColorScheme2 } from "react-native";
|
|
39
39
|
function useColorMode() {
|
|
40
40
|
const nativeScheme = useColorScheme2();
|
|
@@ -51,10 +51,25 @@ function useXUIColors() {
|
|
|
51
51
|
const theme = useXUITheme();
|
|
52
52
|
return theme.colors;
|
|
53
53
|
}
|
|
54
|
+
function useBorderRadiusStyles(radius) {
|
|
55
|
+
const theme = useXUITheme();
|
|
56
|
+
const borderRadius = useMemo(() => {
|
|
57
|
+
const radiusMap = {
|
|
58
|
+
none: theme.borderRadius.none,
|
|
59
|
+
sm: theme.borderRadius.sm,
|
|
60
|
+
md: theme.borderRadius.md,
|
|
61
|
+
lg: theme.borderRadius.lg,
|
|
62
|
+
full: theme.borderRadius.full
|
|
63
|
+
};
|
|
64
|
+
return { borderRadius: radiusMap[radius] };
|
|
65
|
+
}, [radius, theme]);
|
|
66
|
+
return borderRadius;
|
|
67
|
+
}
|
|
54
68
|
|
|
55
69
|
export {
|
|
56
70
|
XUIProvider,
|
|
57
71
|
useColorMode,
|
|
58
72
|
useXUITheme,
|
|
59
|
-
useXUIColors
|
|
73
|
+
useXUIColors,
|
|
74
|
+
useBorderRadiusStyles
|
|
60
75
|
};
|
package/dist/core/index.js
CHANGED
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/indicator/index.js
CHANGED
package/dist/progress/index.d.ts
CHANGED
package/dist/progress/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xaui/native",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Flutter-inspired React Native UI components with native animations powered by React Native Reanimated",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
7
7
|
"mobile",
|
|
8
|
+
"native",
|
|
8
9
|
"ui",
|
|
9
10
|
"components",
|
|
11
|
+
"flutter",
|
|
12
|
+
"reanimated",
|
|
13
|
+
"animations",
|
|
10
14
|
"xaui"
|
|
11
15
|
],
|
|
12
16
|
"type": "module",
|
|
@@ -28,6 +32,11 @@
|
|
|
28
32
|
"import": "./dist/button/index.js",
|
|
29
33
|
"require": "./dist/button/index.js"
|
|
30
34
|
},
|
|
35
|
+
"./checkbox": {
|
|
36
|
+
"types": "./dist/checkbox/index.d.ts",
|
|
37
|
+
"import": "./dist/checkbox/index.js",
|
|
38
|
+
"require": "./dist/checkbox/index.js"
|
|
39
|
+
},
|
|
31
40
|
"./progress": {
|
|
32
41
|
"types": "./dist/progress/index.d.ts",
|
|
33
42
|
"import": "./dist/progress/index.js",
|
|
@@ -46,17 +55,10 @@
|
|
|
46
55
|
"repository": {
|
|
47
56
|
"type": "git",
|
|
48
57
|
"url": "git+https://github.com/rygrams/xaui.git",
|
|
49
|
-
"directory": "packages/
|
|
50
|
-
},
|
|
51
|
-
"scripts": {
|
|
52
|
-
"build": "tsup --config tsup.config.ts",
|
|
53
|
-
"dev": "tsup --config tsup.config.ts --watch",
|
|
54
|
-
"test": "vitest",
|
|
55
|
-
"lint": "eslint src/",
|
|
56
|
-
"type-check": "tsc --noEmit"
|
|
58
|
+
"directory": "packages/native"
|
|
57
59
|
},
|
|
58
60
|
"dependencies": {
|
|
59
|
-
"@xaui/core": "
|
|
61
|
+
"@xaui/core": "0.1.6"
|
|
60
62
|
},
|
|
61
63
|
"peerDependencies": {
|
|
62
64
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -76,5 +78,12 @@
|
|
|
76
78
|
},
|
|
77
79
|
"publishConfig": {
|
|
78
80
|
"access": "public"
|
|
81
|
+
},
|
|
82
|
+
"scripts": {
|
|
83
|
+
"build": "tsup --config tsup.config.ts",
|
|
84
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
85
|
+
"test": "vitest",
|
|
86
|
+
"lint": "eslint src/",
|
|
87
|
+
"type-check": "tsc --noEmit"
|
|
79
88
|
}
|
|
80
|
-
}
|
|
89
|
+
}
|