@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.
@@ -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
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useXUITheme
3
- } from "./chunk-SHT66VET.js";
3
+ } from "./chunk-DNJWBME5.js";
4
4
 
5
5
  // src/components/indicator/indicator.tsx
6
6
  import React3 from "react";
@@ -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
  };
@@ -3,7 +3,7 @@ import {
3
3
  useColorMode,
4
4
  useXUIColors,
5
5
  useXUITheme
6
- } from "../chunk-SHT66VET.js";
6
+ } from "../chunk-DNJWBME5.js";
7
7
  export {
8
8
  XUIProvider,
9
9
  useColorMode,
@@ -1,3 +1,4 @@
1
1
  type ThemeColor = 'primary' | 'secondary' | 'tertiary' | 'danger' | 'warning' | 'success' | 'default';
2
+ type Size = 'xs' | 'sm' | 'md' | 'lg';
2
3
 
3
- export type { ThemeColor as T };
4
+ export type { Size as S, ThemeColor as T };
@@ -1,3 +1,4 @@
1
1
  type ThemeColor = 'primary' | 'secondary' | 'tertiary' | 'danger' | 'warning' | 'success' | 'default';
2
+ type Size = 'xs' | 'sm' | 'md' | 'lg';
2
3
 
3
- export type { ThemeColor as T };
4
+ export type { Size as S, ThemeColor as T };
package/dist/index.d.cts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { ActivityIndicator } from './indicator/index.cjs';
2
2
  import 'react';
3
- import './theme-qvIXI4kF.cjs';
3
+ import './index-BDSvmsTU.cjs';
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { ActivityIndicator } from './indicator/index.js';
2
2
  import 'react';
3
- import './theme-qvIXI4kF.js';
3
+ import './index-BDSvmsTU.js';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ActivityIndicator
3
- } from "./chunk-6ITFLLAM.js";
4
- import "./chunk-SHT66VET.js";
3
+ } from "./chunk-52PIZF2Z.js";
4
+ import "./chunk-DNJWBME5.js";
5
5
  export {
6
6
  ActivityIndicator
7
7
  };
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as ThemeColor } from '../theme-qvIXI4kF.cjs';
2
+ import { T as ThemeColor } from '../index-BDSvmsTU.cjs';
3
3
 
4
4
  type ActivityIndicatorVariant = 'linear' | 'circular';
5
5
  type ActivityIndicatorProps = {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as ThemeColor } from '../theme-qvIXI4kF.js';
2
+ import { T as ThemeColor } from '../index-BDSvmsTU.js';
3
3
 
4
4
  type ActivityIndicatorVariant = 'linear' | 'circular';
5
5
  type ActivityIndicatorProps = {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ActivityIndicator
3
- } from "../chunk-6ITFLLAM.js";
4
- import "../chunk-SHT66VET.js";
3
+ } from "../chunk-52PIZF2Z.js";
4
+ import "../chunk-DNJWBME5.js";
5
5
  export {
6
6
  ActivityIndicator
7
7
  };
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as ThemeColor } from '../theme-qvIXI4kF.cjs';
2
+ import { T as ThemeColor } from '../index-BDSvmsTU.cjs';
3
3
 
4
4
  type ProgressVariant = 'linear' | 'circular';
5
5
  type ProgressIndicatorProps = {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as ThemeColor } from '../theme-qvIXI4kF.js';
2
+ import { T as ThemeColor } from '../index-BDSvmsTU.js';
3
3
 
4
4
  type ProgressVariant = 'linear' | 'circular';
5
5
  type ProgressIndicatorProps = {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useXUITheme
3
- } from "../chunk-SHT66VET.js";
3
+ } from "../chunk-DNJWBME5.js";
4
4
 
5
5
  // src/components/progress/progress.tsx
6
6
  import React3 from "react";
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@xaui/native",
3
- "version": "0.0.2",
4
- "description": "Mobile UI components for XUI",
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/mobile"
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": "workspace:*"
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
+ }