@particle-network/ui-native 0.4.2-beta.2 → 0.4.2-beta.21
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/UXButton/button.js +2 -1
- package/dist/components/UXButton/button.styles.js +19 -6
- package/dist/components/UXButton/button.types.d.ts +6 -3
- package/dist/components/UXTabSwitch/index.d.ts +1 -4
- package/dist/components/UXTabSwitch/index.js +2 -4
- package/dist/components/UXTabs/styles.d.ts +2 -2
- package/dist/components/UXTabs/styles.js +8 -9
- package/dist/components/date-picker/date-picker.js +1 -1
- package/dist/components/date-picker/date-range-picker.js +1 -1
- package/dist/components/input/input.js +14 -3
- package/dist/components/input/number-input.js +44 -34
- package/dist/components/input/styles.js +5 -2
- package/dist/components/input/types.d.ts +1 -0
- package/dist/config/config.default.js +4 -2
- package/dist/config/config.street.js +4 -2
- package/dist/locales/en.d.ts +5 -0
- package/dist/locales/en.js +5 -0
- package/dist/locales/index.d.ts +15 -0
- package/dist/locales/zh.js +5 -0
- package/dist/types/theme.d.ts +2 -0
- package/package.json +15 -14
|
@@ -7,7 +7,7 @@ import { UXPressable } from "../UXPressable/index.js";
|
|
|
7
7
|
import { UXSpinner } from "../UXSpinner/index.js";
|
|
8
8
|
import { useStyles } from "./button.styles.js";
|
|
9
9
|
const UXButton = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
10
|
-
const { style, size, radius, color, variant, onPress, isDisabled, isLoading, startContent, endContent, fullWidth, width, gap, w, h, ph, isIconOnly, children, ...restProps } = props;
|
|
10
|
+
const { style, size, radius, color, variant, onPress, isDisabled, isLoading, isSelected, startContent, endContent, fullWidth, width, gap, w, h, ph, isIconOnly, children, ...restProps } = props;
|
|
11
11
|
const handlePress = (e)=>{
|
|
12
12
|
Keyboard.dismiss();
|
|
13
13
|
triggerHapticFeedback();
|
|
@@ -20,6 +20,7 @@ const UXButton = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
20
20
|
variant,
|
|
21
21
|
isDisabled,
|
|
22
22
|
isLoading,
|
|
23
|
+
isSelected,
|
|
23
24
|
fullWidth,
|
|
24
25
|
isIconOnly,
|
|
25
26
|
width,
|
|
@@ -4,7 +4,7 @@ import { useColors, useComponentConfig, useMs, useRadius, useSpacing } from "../
|
|
|
4
4
|
import { disabledOpacity } from "../../theme/index.js";
|
|
5
5
|
const useStyles = (props)=>{
|
|
6
6
|
const { button: buttonConfig } = useComponentConfig();
|
|
7
|
-
const { size = 'md', radius = buttonConfig.defaultProps?.radius, color = 'default', variant = 'solid', isDisabled, isLoading, width, gap, w, h, ph, fullWidth, isIconOnly } = props;
|
|
7
|
+
const { size = 'md', radius = buttonConfig.defaultProps?.radius, color = 'default', variant = 'solid', isDisabled, isLoading, isSelected, width, gap, w, h, ph, fullWidth, isIconOnly } = props;
|
|
8
8
|
const { getColor } = useColors();
|
|
9
9
|
const { getRadius } = useRadius();
|
|
10
10
|
const { getSpacing } = useSpacing();
|
|
@@ -14,6 +14,7 @@ const useStyles = (props)=>{
|
|
|
14
14
|
sm: ms(buttonConfig.size.sm),
|
|
15
15
|
md: ms(buttonConfig.size.md),
|
|
16
16
|
lg: ms(buttonConfig.size.lg),
|
|
17
|
+
xl: ms(buttonConfig.size.xl),
|
|
17
18
|
auto: void 0
|
|
18
19
|
}), [
|
|
19
20
|
buttonConfig?.size,
|
|
@@ -24,6 +25,7 @@ const useStyles = (props)=>{
|
|
|
24
25
|
sm: ms(buttonConfig.fontSize.sm),
|
|
25
26
|
md: ms(buttonConfig.fontSize.md),
|
|
26
27
|
lg: ms(buttonConfig.fontSize.lg),
|
|
28
|
+
xl: ms(buttonConfig.fontSize.xl),
|
|
27
29
|
auto: ms(buttonConfig.fontSize.md)
|
|
28
30
|
}), [
|
|
29
31
|
ms,
|
|
@@ -33,7 +35,8 @@ const useStyles = (props)=>{
|
|
|
33
35
|
xs: ms(14),
|
|
34
36
|
sm: ms(16),
|
|
35
37
|
md: ms(18),
|
|
36
|
-
lg: ms(
|
|
38
|
+
lg: ms(20),
|
|
39
|
+
xl: ms(24),
|
|
37
40
|
auto: ms(16)
|
|
38
41
|
}), [
|
|
39
42
|
ms
|
|
@@ -42,14 +45,16 @@ const useStyles = (props)=>{
|
|
|
42
45
|
xs: 'xs',
|
|
43
46
|
sm: 'sm',
|
|
44
47
|
md: 'sm',
|
|
45
|
-
lg:
|
|
48
|
+
lg: 8,
|
|
49
|
+
xl: 'md',
|
|
46
50
|
auto: 'sm'
|
|
47
51
|
};
|
|
48
52
|
const paddingMap = useMemo(()=>({
|
|
49
53
|
xs: ms(10),
|
|
50
54
|
sm: ms(14),
|
|
51
55
|
md: ms(14),
|
|
52
|
-
lg: ms(14)
|
|
56
|
+
lg: ms(14),
|
|
57
|
+
xl: ms(14)
|
|
53
58
|
}), [
|
|
54
59
|
ms
|
|
55
60
|
]);
|
|
@@ -102,6 +107,9 @@ const useStyles = (props)=>{
|
|
|
102
107
|
]);
|
|
103
108
|
const textColor = useMemo(()=>{
|
|
104
109
|
const customColorConfig = buttonConfig?.color?.[color];
|
|
110
|
+
if (isSelected) {
|
|
111
|
+
if ('secondary' === color) return 'foreground';
|
|
112
|
+
}
|
|
105
113
|
if ('solid' === variant) {
|
|
106
114
|
if (customColorConfig) return customColorConfig.text;
|
|
107
115
|
if ('contrast' === color) return 'bg-default';
|
|
@@ -111,7 +119,8 @@ const useStyles = (props)=>{
|
|
|
111
119
|
}, [
|
|
112
120
|
color,
|
|
113
121
|
variant,
|
|
114
|
-
buttonConfig?.color
|
|
122
|
+
buttonConfig?.color,
|
|
123
|
+
isSelected
|
|
115
124
|
]);
|
|
116
125
|
const textActualColor = useMemo(()=>getColor(textColor), [
|
|
117
126
|
textColor,
|
|
@@ -119,6 +128,9 @@ const useStyles = (props)=>{
|
|
|
119
128
|
]);
|
|
120
129
|
const backgroundColor = useMemo(()=>{
|
|
121
130
|
const customColorConfig = buttonConfig?.color?.[color];
|
|
131
|
+
if (isSelected) {
|
|
132
|
+
if ('secondary' === color && 'solid' === variant) return getColor('tertiary');
|
|
133
|
+
}
|
|
122
134
|
if ('solid' === variant) {
|
|
123
135
|
if (customColorConfig) return getColor(customColorConfig.background);
|
|
124
136
|
if ('contrast' === color) return getColor('foreground');
|
|
@@ -142,7 +154,8 @@ const useStyles = (props)=>{
|
|
|
142
154
|
color,
|
|
143
155
|
getColor,
|
|
144
156
|
variant,
|
|
145
|
-
buttonConfig?.color
|
|
157
|
+
buttonConfig?.color,
|
|
158
|
+
isSelected
|
|
146
159
|
]);
|
|
147
160
|
const borderColor = useMemo(()=>{
|
|
148
161
|
if ('bordered' === variant) {
|
|
@@ -13,7 +13,8 @@ export interface UXButtonProps extends Omit<UXPressableProps, 'style' | 'disable
|
|
|
13
13
|
* | xs | 20 | 36 |
|
|
14
14
|
* | sm | 24 | 40 |
|
|
15
15
|
* | md | 30 | 44 |
|
|
16
|
-
* | lg |
|
|
16
|
+
* | lg | 36 | 46 |
|
|
17
|
+
* | xl | 44 | 48 |
|
|
17
18
|
*
|
|
18
19
|
* fontSize
|
|
19
20
|
* | size | ux | street |
|
|
@@ -21,12 +22,14 @@ export interface UXButtonProps extends Omit<UXPressableProps, 'style' | 'disable
|
|
|
21
22
|
* | xs | 11 | 12 |
|
|
22
23
|
* | sm | 10 | 14 |
|
|
23
24
|
* | md | 12 | 16 |
|
|
24
|
-
* | lg |
|
|
25
|
+
* | lg | 14 | 16 |
|
|
26
|
+
* | xl | 16 | 18 |
|
|
25
27
|
*/
|
|
26
|
-
size?: 'xs' | 'sm' | 'md' | 'lg' | 'auto';
|
|
28
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'auto';
|
|
27
29
|
variant?: 'solid' | 'bordered' | 'flat' | 'text' | 'light';
|
|
28
30
|
radius?: UXRadius;
|
|
29
31
|
isDisabled?: boolean;
|
|
32
|
+
isSelected?: boolean;
|
|
30
33
|
isLoading?: boolean;
|
|
31
34
|
startContent?: React.ReactNode;
|
|
32
35
|
endContent?: React.ReactNode;
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type UXTabsProps } from '../UXTabs';
|
|
3
|
-
interface UXTabSwitchProps {
|
|
4
|
-
size?: UXTabsProps['size'];
|
|
5
|
-
color?: UXTabsProps['color'];
|
|
3
|
+
interface UXTabSwitchProps extends Omit<UXTabsProps, 'variant' | 'selectedKey' | 'onSelectionChange'> {
|
|
6
4
|
onTitle?: string;
|
|
7
5
|
onIcon?: React.ReactNode;
|
|
8
6
|
offTitle?: string;
|
|
9
7
|
offIcon?: React.ReactNode;
|
|
10
8
|
isSelected?: boolean;
|
|
11
|
-
isDisabled?: boolean;
|
|
12
9
|
onValueChange?: (isSelected: boolean) => void;
|
|
13
10
|
}
|
|
14
11
|
export declare const UXTabSwitch: React.FC<UXTabSwitchProps>;
|
|
@@ -3,17 +3,15 @@ import "react";
|
|
|
3
3
|
import { useI18n } from "../../hooks/useI18n.js";
|
|
4
4
|
import { UXTab, UXTabs } from "../UXTabs/index.js";
|
|
5
5
|
const UXTabSwitch = (props)=>{
|
|
6
|
-
const {
|
|
6
|
+
const { onTitle, onIcon, offTitle, offIcon, isSelected = false, onValueChange, ...restProps } = props;
|
|
7
7
|
const i18n = useI18n();
|
|
8
8
|
return /*#__PURE__*/ jsxs(UXTabs, {
|
|
9
|
-
size: size,
|
|
10
9
|
variant: "switch",
|
|
11
|
-
color: color,
|
|
12
|
-
isDisabled: isDisabled,
|
|
13
10
|
selectedKey: isSelected.toString(),
|
|
14
11
|
onSelectionChange: (key)=>{
|
|
15
12
|
onValueChange?.('true' === key);
|
|
16
13
|
},
|
|
14
|
+
...restProps,
|
|
17
15
|
children: [
|
|
18
16
|
/*#__PURE__*/ jsx(UXTab, {
|
|
19
17
|
title: offTitle || i18n.switch.off,
|
|
@@ -5,7 +5,7 @@ export declare const useStyles: (props: Partial<UXTabsProps> & {
|
|
|
5
5
|
tabsWrapper: {
|
|
6
6
|
backgroundColor: string | undefined;
|
|
7
7
|
gap: import("@particle-network/ui-shared").SpacingType;
|
|
8
|
-
flex: number;
|
|
8
|
+
flex: number | undefined;
|
|
9
9
|
justifyContent: "flex-start" | "space-between";
|
|
10
10
|
borderRadius: number | undefined;
|
|
11
11
|
height: number;
|
|
@@ -14,7 +14,7 @@ export declare const useStyles: (props: Partial<UXTabsProps> & {
|
|
|
14
14
|
};
|
|
15
15
|
tab: {
|
|
16
16
|
flexDirection: "column";
|
|
17
|
-
|
|
17
|
+
flex: number | undefined;
|
|
18
18
|
height: "100%";
|
|
19
19
|
alignItems: "center";
|
|
20
20
|
justifyContent: "center";
|
|
@@ -81,7 +81,7 @@ const useStyles = (props)=>{
|
|
|
81
81
|
]);
|
|
82
82
|
const wrapperBackgroundColor = useMemo(()=>{
|
|
83
83
|
if ('switch' === variant) return getColor('bg-200');
|
|
84
|
-
if ('solid' === variant) return getColor('bg-
|
|
84
|
+
if ('solid' === variant) return getColor('bg-200');
|
|
85
85
|
return 'transparent';
|
|
86
86
|
}, [
|
|
87
87
|
variant,
|
|
@@ -125,8 +125,8 @@ const useStyles = (props)=>{
|
|
|
125
125
|
if (!isSelected) return 'transparent';
|
|
126
126
|
if ('text' === variant || 'underlined' === variant) return 'transparent';
|
|
127
127
|
if ('default' === color) {
|
|
128
|
-
if ('
|
|
129
|
-
return getColor('
|
|
128
|
+
if ('light' === variant) return getColor('bg-200');
|
|
129
|
+
return getColor('tertiary');
|
|
130
130
|
}
|
|
131
131
|
return getColor(color);
|
|
132
132
|
}, [
|
|
@@ -153,7 +153,7 @@ const useStyles = (props)=>{
|
|
|
153
153
|
tabsWrapper: {
|
|
154
154
|
backgroundColor: wrapperBackgroundColor,
|
|
155
155
|
gap: gapValue,
|
|
156
|
-
flex: fullWidth || w ? 1 : 0,
|
|
156
|
+
flex: fullWidth || w ? 1 : void 0,
|
|
157
157
|
justifyContent: fullWidth || w ? 'space-between' : 'flex-start',
|
|
158
158
|
borderRadius: wrapperBorderRadius,
|
|
159
159
|
height,
|
|
@@ -162,11 +162,10 @@ const useStyles = (props)=>{
|
|
|
162
162
|
},
|
|
163
163
|
tab: {
|
|
164
164
|
flexDirection: 'column',
|
|
165
|
-
|
|
166
|
-
'
|
|
167
|
-
'
|
|
168
|
-
|
|
169
|
-
].includes(variant) ? 0 : 1,
|
|
165
|
+
flex: [
|
|
166
|
+
'solid',
|
|
167
|
+
'switch'
|
|
168
|
+
].includes(variant) ? 1 : void 0,
|
|
170
169
|
height: '100%',
|
|
171
170
|
alignItems: 'center',
|
|
172
171
|
justifyContent: 'center',
|
|
@@ -70,7 +70,7 @@ const UXDatePicker = ({ title, value, defaultValue, defaultInternalValue, onChan
|
|
|
70
70
|
footer: /*#__PURE__*/ jsx(UXButton, {
|
|
71
71
|
fullWidth: true,
|
|
72
72
|
color: "primary",
|
|
73
|
-
size: "
|
|
73
|
+
size: "xl",
|
|
74
74
|
onPress: handleConfirm,
|
|
75
75
|
children: i18n.datePicker.confirm
|
|
76
76
|
}),
|
|
@@ -122,7 +122,7 @@ const UXDateRangePicker = ({ title, value, defaultValue, defaultInternalValue, o
|
|
|
122
122
|
/*#__PURE__*/ jsx(UXButton, {
|
|
123
123
|
fullWidth: true,
|
|
124
124
|
color: "primary",
|
|
125
|
-
size: "
|
|
125
|
+
size: "xl",
|
|
126
126
|
onPress: handleConfirm,
|
|
127
127
|
children: i18n.datePicker.confirm
|
|
128
128
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { TextInput } from "react-native";
|
|
4
|
-
import { useColors, useKeyboard } from "../../hooks/index.js";
|
|
4
|
+
import { useColors, useI18n, useKeyboard } from "../../hooks/index.js";
|
|
5
5
|
import { Icon } from "../../icons/index.js";
|
|
6
6
|
import { HStack } from "../layout/HStack.js";
|
|
7
7
|
import { VStack } from "../layout/VStack.js";
|
|
@@ -16,6 +16,7 @@ const UXInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
16
16
|
const [isFocused, setIsFocused] = useState(false);
|
|
17
17
|
const [isInvalid, setIsInvalid] = useState(isInvalidProp);
|
|
18
18
|
const { isKeyboardVisible } = useKeyboard();
|
|
19
|
+
const i18n = useI18n();
|
|
19
20
|
useEffect(()=>{
|
|
20
21
|
if (!isKeyboardVisible && blurOnKeyboardHide) inputRef.current?.blur();
|
|
21
22
|
}, [
|
|
@@ -43,6 +44,15 @@ const UXInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
43
44
|
isInvalid,
|
|
44
45
|
isFocused
|
|
45
46
|
});
|
|
47
|
+
useEffect(()=>{
|
|
48
|
+
if (inputRef.current) inputRef.current.setNativeProps({
|
|
49
|
+
style: {
|
|
50
|
+
color: styles.input.color
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}, [
|
|
54
|
+
styles.input.color
|
|
55
|
+
]);
|
|
46
56
|
useEffect(()=>{
|
|
47
57
|
if (void 0 !== controlledValue) setInternalValue(controlledValue);
|
|
48
58
|
else if (void 0 !== defaultValue) setInternalValue(defaultValue);
|
|
@@ -78,7 +88,7 @@ const UXInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
78
88
|
setIsInvalid(true);
|
|
79
89
|
return {
|
|
80
90
|
isValid: false,
|
|
81
|
-
errorMessage:
|
|
91
|
+
errorMessage: i18n.validation.required
|
|
82
92
|
};
|
|
83
93
|
}
|
|
84
94
|
setIsInvalid(false);
|
|
@@ -87,7 +97,8 @@ const UXInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
87
97
|
};
|
|
88
98
|
}, [
|
|
89
99
|
internalValue,
|
|
90
|
-
isRequired
|
|
100
|
+
isRequired,
|
|
101
|
+
i18n
|
|
91
102
|
]);
|
|
92
103
|
const renderError = useMemo(()=>{
|
|
93
104
|
if (isInvalidProp && errorMessage) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { Platform, TextInput } from "react-native";
|
|
4
|
-
import { useColors, useKeyboard } from "../../hooks/index.js";
|
|
4
|
+
import { useColors, useI18n, useKeyboard } from "../../hooks/index.js";
|
|
5
5
|
import { Icon } from "../../icons/index.js";
|
|
6
6
|
import { HStack } from "../layout/HStack.js";
|
|
7
7
|
import { VStack } from "../layout/VStack.js";
|
|
@@ -9,14 +9,25 @@ import { Text } from "../Text/index.js";
|
|
|
9
9
|
import { UXPressable } from "../UXPressable/index.js";
|
|
10
10
|
import { useStyles } from "./styles.js";
|
|
11
11
|
const UXNumberInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
12
|
-
const { containerStyle, wrapperStyle, inputStyle, value: controlledValue, defaultValue, errorMessage, minValue, maxValue,
|
|
12
|
+
const { containerStyle, wrapperStyle, inputStyle, value: controlledValue, defaultValue, errorMessage, minValue, maxValue, startContent, endContent, isRequired, isReadOnly, isDisabled, isClearable, isInvalid: isInvalidProp, autoErrorMessage, allowNegative, label, onChangeText, onValueChange, onFocus, onBlur, blurOnKeyboardHide = true, ...restProps } = props;
|
|
13
13
|
const { getColor } = useColors();
|
|
14
14
|
const inputRef = useRef(null);
|
|
15
15
|
const [internalValue, setInternalValue] = useState(defaultValue ?? NaN);
|
|
16
16
|
const [displayText, setDisplayText] = useState(defaultValue?.toString() ?? '');
|
|
17
17
|
const [isFocused, setIsFocused] = useState(false);
|
|
18
18
|
const [isInvalid, setIsInvalid] = useState(isInvalidProp);
|
|
19
|
+
const i18n = useI18n();
|
|
19
20
|
const { isKeyboardVisible } = useKeyboard();
|
|
21
|
+
const formatOptions = useMemo(()=>{
|
|
22
|
+
const restFormatOptions = {
|
|
23
|
+
maximumFractionDigits: 3,
|
|
24
|
+
...restProps.formatOptions ?? {}
|
|
25
|
+
};
|
|
26
|
+
delete restFormatOptions.signDisplay;
|
|
27
|
+
return restFormatOptions;
|
|
28
|
+
}, [
|
|
29
|
+
restProps.formatOptions
|
|
30
|
+
]);
|
|
20
31
|
useEffect(()=>{
|
|
21
32
|
if (!isKeyboardVisible && blurOnKeyboardHide) inputRef.current?.blur();
|
|
22
33
|
}, [
|
|
@@ -46,6 +57,15 @@ const UXNumberInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
46
57
|
isInvalid,
|
|
47
58
|
isFocused
|
|
48
59
|
});
|
|
60
|
+
useEffect(()=>{
|
|
61
|
+
if (inputRef.current) inputRef.current.setNativeProps({
|
|
62
|
+
style: {
|
|
63
|
+
color: styles.input.color
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}, [
|
|
67
|
+
styles.input.color
|
|
68
|
+
]);
|
|
49
69
|
useEffect(()=>{
|
|
50
70
|
if (void 0 !== controlledValue) {
|
|
51
71
|
setInternalValue(controlledValue);
|
|
@@ -58,24 +78,21 @@ const UXNumberInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
58
78
|
defaultValue,
|
|
59
79
|
controlledValue
|
|
60
80
|
]);
|
|
61
|
-
const numberFormatter = useMemo(()=>
|
|
62
|
-
if (formatOptions) return new Intl.NumberFormat(void 0, formatOptions);
|
|
63
|
-
return null;
|
|
64
|
-
}, [
|
|
81
|
+
const numberFormatter = useMemo(()=>new Intl.NumberFormat(void 0, formatOptions), [
|
|
65
82
|
formatOptions
|
|
66
83
|
]);
|
|
67
84
|
const validationResult = useMemo(()=>{
|
|
68
85
|
if (isNaN(internalValue) && isRequired) return {
|
|
69
86
|
isValid: false,
|
|
70
|
-
errorMessage:
|
|
87
|
+
errorMessage: i18n.validation.required
|
|
71
88
|
};
|
|
72
89
|
if (void 0 !== minValue && internalValue < minValue) return {
|
|
73
90
|
isValid: false,
|
|
74
|
-
errorMessage:
|
|
91
|
+
errorMessage: i18n.validation.min.replace('{min}', minValue.toString())
|
|
75
92
|
};
|
|
76
93
|
if (void 0 !== maxValue && internalValue > maxValue) return {
|
|
77
94
|
isValid: false,
|
|
78
|
-
errorMessage:
|
|
95
|
+
errorMessage: i18n.validation.max.replace('{max}', maxValue.toString())
|
|
79
96
|
};
|
|
80
97
|
setIsInvalid(false);
|
|
81
98
|
return {
|
|
@@ -85,22 +102,19 @@ const UXNumberInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
85
102
|
internalValue,
|
|
86
103
|
isRequired,
|
|
87
104
|
minValue,
|
|
88
|
-
maxValue
|
|
105
|
+
maxValue,
|
|
106
|
+
i18n
|
|
89
107
|
]);
|
|
90
108
|
const adjustValueToRange = useCallback((num)=>{
|
|
91
|
-
|
|
92
|
-
if (void 0 !== minValue &&
|
|
93
|
-
if (void 0 !== maxValue &&
|
|
94
|
-
return
|
|
109
|
+
if (isNaN(num)) return NaN;
|
|
110
|
+
if (void 0 !== minValue && num < minValue) return minValue;
|
|
111
|
+
if (void 0 !== maxValue && num > maxValue) return maxValue;
|
|
112
|
+
return num;
|
|
95
113
|
}, [
|
|
96
114
|
minValue,
|
|
97
115
|
maxValue
|
|
98
116
|
]);
|
|
99
|
-
const adjustValueToFractionDigits = useCallback((numValue)=>
|
|
100
|
-
if (formatOptions?.minimumFractionDigits !== void 0 || formatOptions?.maximumFractionDigits !== void 0) return Number(numberFormatter?.format(numValue).replaceAll(',', ''));
|
|
101
|
-
return numValue;
|
|
102
|
-
}, [
|
|
103
|
-
formatOptions,
|
|
117
|
+
const adjustValueToFractionDigits = useCallback((numValue)=>Number(numberFormatter?.format(numValue).replaceAll(',', '')), [
|
|
104
118
|
numberFormatter
|
|
105
119
|
]);
|
|
106
120
|
const handleChangeText = useCallback((text)=>{
|
|
@@ -111,17 +125,11 @@ const UXNumberInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
111
125
|
if (cleanedText.includes('-') && !cleanedText.startsWith('-')) return;
|
|
112
126
|
setDisplayText(cleanedText);
|
|
113
127
|
onChangeText?.(cleanedText);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
onValueChange?.(NaN);
|
|
118
|
-
} else {
|
|
119
|
-
setInternalValue(numValue);
|
|
120
|
-
onValueChange?.(numValue);
|
|
121
|
-
}
|
|
128
|
+
if ('' === cleanedText || '-' === cleanedText) return void setInternalValue(NaN);
|
|
129
|
+
const numValue = Number(cleanedText);
|
|
130
|
+
isNaN(numValue) ? setInternalValue(NaN) : setInternalValue(numValue);
|
|
122
131
|
}, [
|
|
123
|
-
onChangeText
|
|
124
|
-
onValueChange
|
|
132
|
+
onChangeText
|
|
125
133
|
]);
|
|
126
134
|
const handleFocus = useCallback((e)=>{
|
|
127
135
|
setIsFocused(true);
|
|
@@ -131,8 +139,9 @@ const UXNumberInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
131
139
|
]);
|
|
132
140
|
const handleBlur = useCallback((e)=>{
|
|
133
141
|
setIsFocused(false);
|
|
134
|
-
|
|
135
|
-
|
|
142
|
+
if (isNaN(internalValue)) onValueChange?.(NaN);
|
|
143
|
+
else {
|
|
144
|
+
const adjustedValue = adjustValueToFractionDigits(adjustValueToRange(internalValue));
|
|
136
145
|
const adjustedText = adjustedValue?.toString();
|
|
137
146
|
setDisplayText(adjustedText);
|
|
138
147
|
setInternalValue(adjustedValue);
|
|
@@ -165,10 +174,11 @@ const UXNumberInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
165
174
|
if (isNaN(internalValue)) return '';
|
|
166
175
|
if (numberFormatter) {
|
|
167
176
|
const formattedValue = numberFormatter.format(internalValue);
|
|
168
|
-
|
|
177
|
+
const signDisplay = restProps.formatOptions?.signDisplay;
|
|
178
|
+
if ('exceptZero' === signDisplay || 'always' === signDisplay) {
|
|
169
179
|
if (internalValue > 0) return `+${formattedValue}`;
|
|
170
180
|
else if (internalValue < 0) ;
|
|
171
|
-
else if ('always' ===
|
|
181
|
+
else if ('always' === signDisplay) return `+${formattedValue}`;
|
|
172
182
|
}
|
|
173
183
|
return formattedValue;
|
|
174
184
|
}
|
|
@@ -178,7 +188,7 @@ const UXNumberInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
178
188
|
displayText,
|
|
179
189
|
numberFormatter,
|
|
180
190
|
isFocused,
|
|
181
|
-
formatOptions
|
|
191
|
+
restProps.formatOptions
|
|
182
192
|
]);
|
|
183
193
|
const renderError = useMemo(()=>{
|
|
184
194
|
if (isInvalidProp && errorMessage) {
|
|
@@ -4,7 +4,7 @@ import { useColors, useComponentConfig, useMs, useRadius } from "../../hooks/ind
|
|
|
4
4
|
import { disabledOpacity } from "../../theme/index.js";
|
|
5
5
|
const useStyles = (props)=>{
|
|
6
6
|
const { input: inputConfig } = useComponentConfig();
|
|
7
|
-
const { isInvalid, isDisabled, fullWidth, isFocused, color = 'default', size = 'md', variant = 'flat', multiline, radius = multiline ? void 0 : inputConfig.defaultProps?.radius, width: widthProp, textAlign = 'left' } = props;
|
|
7
|
+
const { isInvalid, isDisabled, fullWidth, isFocused, color = 'default', isColorText = false, size = 'md', variant = 'flat', multiline, radius = multiline ? void 0 : inputConfig.defaultProps?.radius, width: widthProp, textAlign = 'left' } = props;
|
|
8
8
|
const { getColor } = useColors();
|
|
9
9
|
const { getRadius } = useRadius();
|
|
10
10
|
const { ms } = useMs();
|
|
@@ -52,10 +52,13 @@ const useStyles = (props)=>{
|
|
|
52
52
|
]);
|
|
53
53
|
const inputTextColor = useMemo(()=>{
|
|
54
54
|
if (isInvalid) return getColor('danger');
|
|
55
|
+
if (isColorText) return getColor(color);
|
|
55
56
|
return getColor('foreground');
|
|
56
57
|
}, [
|
|
57
58
|
isInvalid,
|
|
58
|
-
getColor
|
|
59
|
+
getColor,
|
|
60
|
+
isColorText,
|
|
61
|
+
color
|
|
59
62
|
]);
|
|
60
63
|
const backgroundColor = useMemo(()=>getColor('bg-200'), [
|
|
61
64
|
getColor
|
|
@@ -36,6 +36,7 @@ export interface UXInputCommonProps extends Omit<TextInputProps, 'style' | 'valu
|
|
|
36
36
|
isReadOnly?: boolean;
|
|
37
37
|
isDisabled?: boolean;
|
|
38
38
|
isInvalid?: boolean;
|
|
39
|
+
isColorText?: boolean;
|
|
39
40
|
label?: string;
|
|
40
41
|
textAlign?: 'left' | 'center' | 'right';
|
|
41
42
|
autoErrorMessage?: boolean;
|
package/dist/locales/en.d.ts
CHANGED
package/dist/locales/en.js
CHANGED
package/dist/locales/index.d.ts
CHANGED
|
@@ -45,6 +45,11 @@ export declare const locales: {
|
|
|
45
45
|
on: string;
|
|
46
46
|
off: string;
|
|
47
47
|
};
|
|
48
|
+
validation: {
|
|
49
|
+
required: string;
|
|
50
|
+
min: string;
|
|
51
|
+
max: string;
|
|
52
|
+
};
|
|
48
53
|
};
|
|
49
54
|
zh: {
|
|
50
55
|
datePicker: {
|
|
@@ -89,6 +94,11 @@ export declare const locales: {
|
|
|
89
94
|
on: string;
|
|
90
95
|
off: string;
|
|
91
96
|
};
|
|
97
|
+
validation: {
|
|
98
|
+
required: string;
|
|
99
|
+
min: string;
|
|
100
|
+
max: string;
|
|
101
|
+
};
|
|
92
102
|
};
|
|
93
103
|
};
|
|
94
104
|
export declare function getLocaleText(locale: Locale): {
|
|
@@ -134,4 +144,9 @@ export declare function getLocaleText(locale: Locale): {
|
|
|
134
144
|
on: string;
|
|
135
145
|
off: string;
|
|
136
146
|
};
|
|
147
|
+
validation: {
|
|
148
|
+
required: string;
|
|
149
|
+
min: string;
|
|
150
|
+
max: string;
|
|
151
|
+
};
|
|
137
152
|
};
|
package/dist/locales/zh.js
CHANGED
package/dist/types/theme.d.ts
CHANGED
|
@@ -10,12 +10,14 @@ export interface CommonComponentConfig {
|
|
|
10
10
|
sm: number;
|
|
11
11
|
md: number;
|
|
12
12
|
lg: number;
|
|
13
|
+
xl?: number;
|
|
13
14
|
};
|
|
14
15
|
fontSize: {
|
|
15
16
|
xs?: number;
|
|
16
17
|
sm: number;
|
|
17
18
|
md: number;
|
|
18
19
|
lg: number;
|
|
20
|
+
xl?: number;
|
|
19
21
|
};
|
|
20
22
|
color: Record<string, {
|
|
21
23
|
background: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@particle-network/ui-native",
|
|
3
|
-
"version": "0.4.2-beta.
|
|
3
|
+
"version": "0.4.2-beta.21",
|
|
4
4
|
"main": "./entry.js",
|
|
5
5
|
"react-native": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -44,8 +44,9 @@
|
|
|
44
44
|
"react-native-paper": "^5.14.5",
|
|
45
45
|
"react-native-size-matters": "^0.4.2",
|
|
46
46
|
"react-native-toast-message": "^2.3.3",
|
|
47
|
-
"
|
|
48
|
-
"@particle-network/
|
|
47
|
+
"react-native-worklets": "0.5.1",
|
|
48
|
+
"@particle-network/icons": "0.4.2-beta.7",
|
|
49
|
+
"@particle-network/ui-shared": "0.3.2-beta.3"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@babel/core": "^7.24.0",
|
|
@@ -59,13 +60,13 @@
|
|
|
59
60
|
"@rsbuild/core": "^1.5.0",
|
|
60
61
|
"@rsbuild/plugin-react": "^1.3.5",
|
|
61
62
|
"@rslib/core": "^0.12.2",
|
|
62
|
-
"@storybook/addon-docs": "^
|
|
63
|
-
"@storybook/addon-ondevice-actions": "^
|
|
64
|
-
"@storybook/addon-ondevice-backgrounds": "^
|
|
65
|
-
"@storybook/addon-ondevice-controls": "^
|
|
66
|
-
"@storybook/addon-ondevice-notes": "^
|
|
67
|
-
"@storybook/react-native": "^
|
|
68
|
-
"@storybook/react-native-web-vite": "^
|
|
63
|
+
"@storybook/addon-docs": "^10.0.0",
|
|
64
|
+
"@storybook/addon-ondevice-actions": "^10.0.0",
|
|
65
|
+
"@storybook/addon-ondevice-backgrounds": "^10.0.0",
|
|
66
|
+
"@storybook/addon-ondevice-controls": "^10.0.0",
|
|
67
|
+
"@storybook/addon-ondevice-notes": "^10.0.0",
|
|
68
|
+
"@storybook/react-native": "^10.0.0",
|
|
69
|
+
"@storybook/react-native-web-vite": "^10.0.0",
|
|
69
70
|
"@types/react": "^19.1.10",
|
|
70
71
|
"babel-plugin-module-resolver": "^5.0.2",
|
|
71
72
|
"babel-plugin-react-docgen-typescript": "^1.5.1",
|
|
@@ -79,18 +80,18 @@
|
|
|
79
80
|
"react-dom": "19.1.0",
|
|
80
81
|
"react-native": "0.81.5",
|
|
81
82
|
"react-native-gesture-handler": "~2.28.0",
|
|
82
|
-
"react-native-reanimated": "
|
|
83
|
+
"react-native-reanimated": "4.1.6",
|
|
83
84
|
"react-native-safe-area-context": "5.6.1",
|
|
84
85
|
"react-native-svg": "15.12.1",
|
|
85
86
|
"react-native-web": "^0.21.1",
|
|
86
87
|
"serve": "^14.2.5",
|
|
87
|
-
"storybook": "^
|
|
88
|
+
"storybook": "^10.0.0",
|
|
88
89
|
"unfetch": "^4.2.0",
|
|
89
90
|
"vite": "^6.3.5",
|
|
90
91
|
"zustand": "^5.0.8",
|
|
91
92
|
"@particle-network/eslint-config": "0.3.0",
|
|
92
|
-
"@particle-network/
|
|
93
|
-
"@particle-network/
|
|
93
|
+
"@particle-network/icons": "0.4.2-beta.7",
|
|
94
|
+
"@particle-network/lintstaged-config": "0.1.0"
|
|
94
95
|
},
|
|
95
96
|
"overrides": {
|
|
96
97
|
"react-docgen-typescript": "2.2.2",
|