@particle-network/ui-native 0.1.4-beta.1 → 0.1.4-beta.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.
@@ -1,13 +1,13 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useState } from "react";
3
3
  import { useMs } from "../../hooks/index.js";
4
- import { Icon } from "../../icons/index.js";
5
4
  import { disabledOpacity } from "../../theme/index.js";
6
5
  import { Flex } from "../layout/Flex/index.js";
7
6
  import { Text } from "../Text/index.js";
8
7
  import { UXPressable } from "../UXPressable/index.js";
9
8
  import { useCheckboxGroup } from "./context.js";
10
- const UXCheckbox = ({ size, color, defaultSelected = false, isSelected, children, value, onValueChange, isDisabled, ...props })=>{
9
+ import { CheckboxOffIcon, CheckboxOnIcon } from "./icons.js";
10
+ const UXCheckbox = ({ size, color, defaultSelected = false, isSelected, children, value, onValueChange, isDisabled, labelPlacement = 'right', ...props })=>{
11
11
  const { ms } = useMs();
12
12
  const [internalSelected, setInternalSelected] = useState(defaultSelected ?? isSelected);
13
13
  const groupContext = useCheckboxGroup();
@@ -21,6 +21,19 @@ const UXCheckbox = ({ size, color, defaultSelected = false, isSelected, children
21
21
  defaultSelected
22
22
  ]);
23
23
  const checkboxColor = color || groupContext?.color || 'primary';
24
+ const displayLabelPlacement = labelPlacement || groupContext?.labelPlacement || 'right';
25
+ const bgColor = useMemo(()=>{
26
+ if ('secondary' === checkboxColor) return 'tertiary';
27
+ return checkboxColor;
28
+ }, [
29
+ checkboxColor
30
+ ]);
31
+ const foregroundColor = useMemo(()=>{
32
+ if ('secondary' === checkboxColor) return 'foreground';
33
+ return 'white';
34
+ }, [
35
+ checkboxColor
36
+ ]);
24
37
  const checkboxIsDisabled = isDisabled || groupContext?.isDisabled;
25
38
  const checkboxSize = size || groupContext?.size || 'md';
26
39
  const handleSelectChange = ()=>{
@@ -32,23 +45,24 @@ const UXCheckbox = ({ size, color, defaultSelected = false, isSelected, children
32
45
  };
33
46
  const iconSize = useMemo(()=>{
34
47
  if ('sm' === checkboxSize) return ms(14);
35
- if ('lg' === checkboxSize) return ms(20);
48
+ if ('lg' === checkboxSize) return ms(18);
36
49
  return ms(16);
37
50
  }, [
38
- checkboxSize
51
+ checkboxSize,
52
+ ms
39
53
  ]);
40
54
  const labelVariant = useMemo(()=>{
41
- if ('sm' === checkboxSize) return 'body3Bold';
42
- if ('lg' === checkboxSize) return 'body1Bold';
43
- return 'body2Bold';
55
+ if ('sm' === checkboxSize) return 'body3';
56
+ if ('lg' === checkboxSize) return 'body1';
57
+ return 'body2';
44
58
  }, [
45
59
  checkboxSize
46
60
  ]);
47
- const gap = useMemo(()=>{
48
- if ('sm' === checkboxSize) return 6;
49
- return 8;
61
+ const flexDirection = useMemo(()=>{
62
+ if ('left' === displayLabelPlacement) return 'row-reverse';
63
+ return 'row';
50
64
  }, [
51
- checkboxSize
65
+ displayLabelPlacement
52
66
  ]);
53
67
  return /*#__PURE__*/ jsx(UXPressable, {
54
68
  disabled: checkboxIsDisabled,
@@ -57,16 +71,16 @@ const UXCheckbox = ({ size, color, defaultSelected = false, isSelected, children
57
71
  },
58
72
  onPress: handleSelectChange,
59
73
  children: /*#__PURE__*/ jsxs(Flex, {
60
- gap: gap,
74
+ direction: flexDirection,
75
+ gap: 8,
61
76
  items: "center",
62
77
  ...props,
63
78
  children: [
64
- internalSelected ? /*#__PURE__*/ jsx(Icon, {
65
- name: "checkboxOn",
66
- color: checkboxColor,
79
+ internalSelected ? /*#__PURE__*/ jsx(CheckboxOnIcon, {
80
+ color1: bgColor,
81
+ color2: foregroundColor,
67
82
  size: iconSize
68
- }) : /*#__PURE__*/ jsx(Icon, {
69
- name: "checkboxOff",
83
+ }) : /*#__PURE__*/ jsx(CheckboxOffIcon, {
70
84
  color: "secondary",
71
85
  size: iconSize
72
86
  }),
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import type { UXColor } from '@particle-network/ui-shared';
3
+ interface CheckboxOnIconProps {
4
+ size?: number;
5
+ color1?: UXColor;
6
+ color2?: UXColor;
7
+ }
8
+ interface CheckboxOffIconProps {
9
+ size?: number;
10
+ color?: UXColor;
11
+ }
12
+ export declare const CheckboxOnIcon: ({ size, color1, color2 }: CheckboxOnIconProps) => React.JSX.Element;
13
+ export declare const CheckboxOffIcon: ({ size, color }: CheckboxOffIconProps) => React.JSX.Element;
14
+ export {};
@@ -0,0 +1,41 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import "react";
3
+ import react_native_svg, { Path } from "react-native-svg";
4
+ import { useColors } from "../../hooks/index.js";
5
+ const CheckboxOnIcon = ({ size = 16, color1 = 'default', color2 = 'white' })=>{
6
+ const { getColor } = useColors();
7
+ const color1Value = getColor(color1);
8
+ const color2Value = getColor(color2);
9
+ return /*#__PURE__*/ jsxs(react_native_svg, {
10
+ fill: "none",
11
+ viewBox: "0 0 16 16",
12
+ width: size,
13
+ height: size,
14
+ children: [
15
+ /*#__PURE__*/ jsx(Path, {
16
+ d: "M2.46154 16H13.5385C14.8979 16 16 14.8979 16 13.5385V2.46154C16 1.10207 14.8979 0 13.5385 0H2.46154C1.10207 0 0 1.10207 0 2.46154V13.5385C0 14.8979 1.10207 16 2.46154 16Z",
17
+ fill: color1Value
18
+ }),
19
+ /*#__PURE__*/ jsx(Path, {
20
+ d: "M6.75547 9.24601L4.84436 7.3349C4.68139 7.17193 4.47399 7.09045 4.22214 7.09045C3.97028 7.09045 3.76288 7.17193 3.59991 7.3349C3.43695 7.49786 3.35547 7.70527 3.35547 7.95712C3.35547 8.20897 3.43695 8.41638 3.59991 8.57934L6.13325 11.1127C6.31102 11.2905 6.51843 11.3793 6.75547 11.3793C6.99251 11.3793 7.19991 11.2905 7.37769 11.1127L12.3999 6.09045C12.5629 5.92749 12.6444 5.72008 12.6444 5.46823C12.6444 5.21638 12.5629 5.00897 12.3999 4.84601C12.237 4.68304 12.0295 4.60156 11.7777 4.60156C11.5258 4.60156 11.3184 4.68304 11.1555 4.84601L6.75547 9.24601Z",
21
+ fill: color2Value
22
+ })
23
+ ]
24
+ });
25
+ };
26
+ const CheckboxOffIcon = ({ size = 16, color = 'default' })=>{
27
+ const { getColor } = useColors();
28
+ const colorValue = getColor(color);
29
+ return /*#__PURE__*/ jsx(react_native_svg, {
30
+ fill: "none",
31
+ viewBox: "0 0 16 16",
32
+ width: size,
33
+ height: size,
34
+ children: /*#__PURE__*/ jsx(Path, {
35
+ d: "M2.46191 0.615234H13.5381C14.5577 0.615234 15.3848 1.44231 15.3848 2.46191V13.5381C15.3848 14.5577 14.5577 15.3848 13.5381 15.3848H2.46191C1.44231 15.3848 0.615234 14.5577 0.615234 13.5381V2.46191C0.615234 1.44231 1.44231 0.615234 2.46191 0.615234Z",
36
+ stroke: colorValue,
37
+ strokeWidth: 1.23077
38
+ })
39
+ });
40
+ };
41
+ export { CheckboxOffIcon, CheckboxOnIcon };
@@ -1,6 +1,6 @@
1
- import type { UXForegroundColor } from '@particle-network/ui-shared';
2
1
  export interface UXCheckboxCommonProps {
3
- color?: UXForegroundColor;
2
+ color?: 'secondary' | 'primary' | 'success' | 'danger' | 'alert' | 'warning' | 'gold' | 'bullish' | 'bearish';
4
3
  size?: 'sm' | 'md' | 'lg';
5
4
  isDisabled?: boolean;
5
+ labelPlacement?: 'left' | 'right';
6
6
  }
@@ -11,27 +11,31 @@ import { UXPressable } from "../UXPressable/index.js";
11
11
  import date_button from "./date-button.js";
12
12
  import { DateWheelPicker } from "./date-wheel-picker.js";
13
13
  import { TimeWheelPicker } from "./time-wheel-picker.js";
14
- import { hasTimeInFormat } from "./utils.js";
15
- const UXDatePicker = ({ value, defaultValue, onConfirm = ()=>null, format = 'YYYY/MM/DD', minDate, maxDate, placeholder, isDisabled = false, isReadOnly = false, ...uxPressableProps })=>{
14
+ import useFormat from "./useFormat.js";
15
+ import { hasTimeOnly } from "./utils.js";
16
+ const UXDatePicker = ({ title, value, defaultValue, onConfirm = ()=>null, format = 'YYYY/MM/DD', minDate, maxDate, placeholder, isDisabled = false, isReadOnly = false, ...uxPressableProps })=>{
16
17
  const [isOpen, setIsOpen] = useState(false);
17
18
  const [pickerType, setPickerType] = useState('date');
18
19
  const [internalValue, setInternalValue] = useState(value || defaultValue || new Date());
19
20
  const i18n = useI18n();
20
- const [dateFormat, timeFormat] = format.split(' ');
21
- const showTimePicker = hasTimeInFormat(format);
22
21
  const displayPlaceholder = placeholder ?? format;
22
+ const { dateFormat, timeFormat, displayTitle } = useFormat({
23
+ format,
24
+ title
25
+ });
23
26
  useEffect(()=>{
24
27
  if (void 0 !== value) setInternalValue(value);
25
28
  }, [
26
29
  value
27
30
  ]);
28
- const handleOpenModal = useCallback((picker)=>{
31
+ const handleOpenModal = useCallback(()=>{
29
32
  if (isDisabled || isReadOnly) return;
30
- setPickerType(picker);
33
+ setPickerType(hasTimeOnly(format) ? 'time' : 'date');
31
34
  setIsOpen(true);
32
35
  }, [
33
36
  isDisabled,
34
- isReadOnly
37
+ isReadOnly,
38
+ format
35
39
  ]);
36
40
  const handleConfirm = useCallback(()=>{
37
41
  onConfirm(internalValue);
@@ -46,7 +50,7 @@ const UXDatePicker = ({ value, defaultValue, onConfirm = ()=>null, format = 'YYY
46
50
  return /*#__PURE__*/ jsxs(Fragment, {
47
51
  children: [
48
52
  /*#__PURE__*/ jsx(UXPressable, {
49
- onPress: ()=>handleOpenModal('date'),
53
+ onPress: ()=>handleOpenModal(),
50
54
  ...uxPressableProps,
51
55
  children: /*#__PURE__*/ jsx(UXInput, {
52
56
  containerStyle: {
@@ -57,7 +61,7 @@ const UXDatePicker = ({ value, defaultValue, onConfirm = ()=>null, format = 'YYY
57
61
  isReadOnly: isReadOnly,
58
62
  placeholder: displayPlaceholder,
59
63
  pointerEvents: "none",
60
- value: value ? dayjs(value).format(format) : format
64
+ value: value ? dayjs(value).format(format) : void 0
61
65
  })
62
66
  }),
63
67
  /*#__PURE__*/ jsx(UXModal, {
@@ -74,7 +78,7 @@ const UXDatePicker = ({ value, defaultValue, onConfirm = ()=>null, format = 'YYY
74
78
  scrollViewProps: {
75
79
  scrollEnabled: false
76
80
  },
77
- title: i18n.datePicker.confirm,
81
+ title: displayTitle,
78
82
  onClose: handleClose,
79
83
  children: /*#__PURE__*/ jsxs(VStack, {
80
84
  fullWidth: true,
@@ -85,12 +89,12 @@ const UXDatePicker = ({ value, defaultValue, onConfirm = ()=>null, format = 'YYY
85
89
  items: "center",
86
90
  gap: 8,
87
91
  children: [
88
- /*#__PURE__*/ jsx(date_button, {
92
+ dateFormat && /*#__PURE__*/ jsx(date_button, {
89
93
  isSelected: 'date' === pickerType,
90
94
  text: dayjs(internalValue).format(dateFormat),
91
95
  onPress: ()=>setPickerType('date')
92
96
  }),
93
- showTimePicker && /*#__PURE__*/ jsx(date_button, {
97
+ timeFormat && /*#__PURE__*/ jsx(date_button, {
94
98
  isSelected: 'time' === pickerType,
95
99
  text: dayjs(internalValue).format(timeFormat),
96
100
  onPress: ()=>setPickerType('time')
@@ -13,8 +13,9 @@ import { UXPressable } from "../UXPressable/index.js";
13
13
  import date_button from "./date-button.js";
14
14
  import { DateWheelPicker } from "./date-wheel-picker.js";
15
15
  import { TimeWheelPicker } from "./time-wheel-picker.js";
16
- import { hasTimeInFormat } from "./utils.js";
17
- const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format = 'YYYY/MM/DD', minDate, maxDate, startPlaceholder, endPlaceholder, isDisabled = false, isReadOnly = false, ...hStackProps })=>{
16
+ import useFormat from "./useFormat.js";
17
+ import { hasTimeOnly } from "./utils.js";
18
+ const UXDateRangePicker = ({ title, value, defaultValue, onConfirm = ()=>null, format = 'YYYY/MM/DD', minDate, maxDate, startPlaceholder, endPlaceholder, isDisabled = false, isReadOnly = false, ...hStackProps })=>{
18
19
  const [isOpen, setIsOpen] = useState(false);
19
20
  const [currentEditType, setCurrentEditType] = useState('start');
20
21
  const [pickerType, setPickerType] = useState('date');
@@ -22,10 +23,13 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
22
23
  const [internalEnd, setInternalEnd] = useState(value?.end || defaultValue?.end || new Date());
23
24
  const [error, setError] = useState('');
24
25
  const i18n = useI18n();
25
- const [dateFormat, timeFormat] = format.split(' ');
26
- const showTimePicker = hasTimeInFormat(format);
27
26
  const displayStartPlaceholder = startPlaceholder ?? format;
28
27
  const displayEndPlaceholder = endPlaceholder ?? format;
28
+ const { dateFormat, timeFormat, displayTitle } = useFormat({
29
+ format,
30
+ title,
31
+ rangeMode: true
32
+ });
29
33
  useEffect(()=>{
30
34
  if (value?.start !== void 0) setInternalStart(value?.start);
31
35
  if (value?.end !== void 0) setInternalEnd(value?.end);
@@ -35,12 +39,13 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
35
39
  const handleOpenModal = useCallback((type, picker)=>{
36
40
  if (isDisabled || isReadOnly) return;
37
41
  setCurrentEditType(type);
38
- setPickerType(picker);
42
+ setPickerType(picker || (hasTimeOnly(format) ? 'time' : 'date'));
39
43
  setError('');
40
44
  setIsOpen(true);
41
45
  }, [
42
46
  isDisabled,
43
- isReadOnly
47
+ isReadOnly,
48
+ format
44
49
  ]);
45
50
  const handleConfirm = useCallback(()=>{
46
51
  if (!internalStart || !internalEnd) return void setError(i18n.datePicker.errorBothRequired);
@@ -68,7 +73,7 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
68
73
  children: [
69
74
  /*#__PURE__*/ jsx(UXPressable, {
70
75
  fill: true,
71
- onPress: ()=>handleOpenModal('start', 'date'),
76
+ onPress: ()=>handleOpenModal('start'),
72
77
  children: /*#__PURE__*/ jsx(UXInput, {
73
78
  containerStyle: {
74
79
  flex: 1
@@ -78,7 +83,7 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
78
83
  isReadOnly: isReadOnly,
79
84
  placeholder: displayStartPlaceholder,
80
85
  pointerEvents: "none",
81
- value: value?.start ? dayjs(value?.start).format(format) : format
86
+ value: value?.start ? dayjs(value?.start).format(format) : void 0
82
87
  })
83
88
  }),
84
89
  /*#__PURE__*/ jsx(Icon, {
@@ -88,7 +93,7 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
88
93
  }),
89
94
  /*#__PURE__*/ jsx(UXPressable, {
90
95
  fill: true,
91
- onPress: ()=>handleOpenModal('end', 'date'),
96
+ onPress: ()=>handleOpenModal('end'),
92
97
  children: /*#__PURE__*/ jsx(UXInput, {
93
98
  containerStyle: {
94
99
  flex: 1
@@ -98,7 +103,7 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
98
103
  isReadOnly: isReadOnly,
99
104
  placeholder: displayEndPlaceholder,
100
105
  pointerEvents: "none",
101
- value: value?.end ? dayjs(value?.end).format(format) : format
106
+ value: value?.end ? dayjs(value?.end).format(format) : void 0
102
107
  })
103
108
  })
104
109
  ]
@@ -127,7 +132,7 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
127
132
  scrollViewProps: {
128
133
  scrollEnabled: false
129
134
  },
130
- title: "Time Range",
135
+ title: displayTitle,
131
136
  onClose: handleClose,
132
137
  children: /*#__PURE__*/ jsxs(VStack, {
133
138
  fullWidth: true,
@@ -138,12 +143,12 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
138
143
  items: "center",
139
144
  gap: 8,
140
145
  children: [
141
- /*#__PURE__*/ jsx(date_button, {
146
+ dateFormat && /*#__PURE__*/ jsx(date_button, {
142
147
  isSelected: 'start' === currentEditType && 'date' === pickerType,
143
148
  text: dayjs(internalStart).format(dateFormat),
144
149
  onPress: ()=>handleOpenModal('start', 'date')
145
150
  }),
146
- showTimePicker && /*#__PURE__*/ jsx(date_button, {
151
+ timeFormat && /*#__PURE__*/ jsx(date_button, {
147
152
  isSelected: 'start' === currentEditType && 'time' === pickerType,
148
153
  text: dayjs(internalStart).format(timeFormat),
149
154
  onPress: ()=>handleOpenModal('start', 'time')
@@ -153,12 +158,12 @@ const UXDateRangePicker = ({ value, defaultValue, onConfirm = ()=>null, format =
153
158
  color: "tertiary",
154
159
  size: 16
155
160
  }),
156
- /*#__PURE__*/ jsx(date_button, {
161
+ dateFormat && /*#__PURE__*/ jsx(date_button, {
157
162
  isSelected: 'end' === currentEditType && 'date' === pickerType,
158
163
  text: dayjs(internalEnd).format(dateFormat),
159
164
  onPress: ()=>handleOpenModal('end', 'date')
160
165
  }),
161
- showTimePicker && /*#__PURE__*/ jsx(date_button, {
166
+ timeFormat && /*#__PURE__*/ jsx(date_button, {
162
167
  isSelected: 'end' === currentEditType && 'time' === pickerType,
163
168
  text: dayjs(internalEnd).format(timeFormat),
164
169
  onPress: ()=>handleOpenModal('end', 'time')
@@ -37,6 +37,10 @@ export interface UXDatePickerProps extends Omit<UXPressableProps, 'children'> {
37
37
  * 是否只读
38
38
  */
39
39
  isReadOnly?: boolean;
40
+ /**
41
+ * 弹窗标题
42
+ */
43
+ title?: string;
40
44
  }
41
45
  export interface UXDateRangePickerProps extends Omit<HStackProps, 'children'> {
42
46
  /**
@@ -79,6 +83,10 @@ export interface UXDateRangePickerProps extends Omit<HStackProps, 'children'> {
79
83
  * 是否只读
80
84
  */
81
85
  isReadOnly?: boolean;
86
+ /**
87
+ * 弹窗标题
88
+ */
89
+ title?: string;
82
90
  }
83
91
  export interface DateRangeValue {
84
92
  start?: Date;
@@ -0,0 +1,10 @@
1
+ declare const useFormat: ({ format, title, rangeMode }: {
2
+ format: string;
3
+ title?: string;
4
+ rangeMode?: boolean;
5
+ }) => {
6
+ dateFormat: string | null;
7
+ timeFormat: string | null;
8
+ displayTitle: string;
9
+ };
10
+ export default useFormat;
@@ -0,0 +1,26 @@
1
+ import { useMemo } from "react";
2
+ import { useI18n } from "../../hooks/index.js";
3
+ import { getDateFormat, getTimeFormat, hasDateOnly, hasTimeOnly } from "./utils.js";
4
+ const useFormat = ({ format, title, rangeMode = false })=>{
5
+ const i18n = useI18n();
6
+ const dateFormat = getDateFormat(format);
7
+ const timeFormat = getTimeFormat(format);
8
+ const displayTitle = useMemo(()=>{
9
+ if (title) return title;
10
+ if (hasDateOnly(format)) return rangeMode ? i18n.datePicker.selectDateRange : i18n.datePicker.selectDate;
11
+ if (hasTimeOnly(format)) return rangeMode ? i18n.datePicker.selectTimeRange : i18n.datePicker.selectTime;
12
+ return rangeMode ? i18n.datePicker.selectDateAndTimeRange : i18n.datePicker.selectDateAndTime;
13
+ }, [
14
+ format,
15
+ title,
16
+ i18n,
17
+ rangeMode
18
+ ]);
19
+ return {
20
+ dateFormat,
21
+ timeFormat,
22
+ displayTitle
23
+ };
24
+ };
25
+ const date_picker_useFormat = useFormat;
26
+ export { date_picker_useFormat as default };
@@ -1,6 +1,36 @@
1
+ /**
2
+ * 判断格式字符串是否包含日期部分
3
+ * @param {string} format - 时间格式字符串
4
+ * @returns {boolean} - 是否包含日期
5
+ */
6
+ export declare function hasDateInFormat(format: string): boolean;
1
7
  /**
2
8
  * 判断格式字符串是否包含时间部分
3
- * @param format 格式字符串
4
- * @returns 是否包含时间
9
+ * @param {string} format - 时间格式字符串
10
+ * @returns {boolean} - 是否包含时间
11
+ */
12
+ export declare function hasTimeInFormat(format: string): boolean;
13
+ /**
14
+ * 判断格式字符串是否只包含日期(不含时间)
15
+ * @param {string} format - 时间格式字符串
16
+ * @returns {boolean} - 是否只有日期
17
+ */
18
+ export declare function hasDateOnly(format: string): boolean;
19
+ /**
20
+ * 判断格式字符串是否只包含时间(不含日期)
21
+ * @param {string} format - 时间格式字符串
22
+ * @returns {boolean} - 是否只有时间
23
+ */
24
+ export declare function hasTimeOnly(format: string): boolean;
25
+ /**
26
+ * 提取格式字符串中的日期部分
27
+ * @param {string} format - 时间格式字符串
28
+ * @returns {string|null} - 日期格式字符串,如果不包含日期则返回 null
29
+ */
30
+ export declare function getDateFormat(format: string): string | null;
31
+ /**
32
+ * 提取格式字符串中的时间部分
33
+ * @param {string} format - 时间格式字符串
34
+ * @returns {string|null} - 时间格式字符串,如果不包含时间则返回 null
5
35
  */
6
- export declare const hasTimeInFormat: (format: string) => boolean;
36
+ export declare function getTimeFormat(format: string): string | null;
@@ -1,2 +1,77 @@
1
- const hasTimeInFormat = (format)=>/[HhmsAa]/.test(format);
2
- export { hasTimeInFormat };
1
+ function hasDateInFormat(format) {
2
+ const datePatterns = [
3
+ /Y{2,4}/,
4
+ /M{1,2}/,
5
+ /D{1,2}/
6
+ ];
7
+ return datePatterns.some((pattern)=>pattern.test(format));
8
+ }
9
+ function hasTimeInFormat(format) {
10
+ const timePatterns = [
11
+ /H{1,2}/,
12
+ /h{1,2}/,
13
+ /m{1,2}/,
14
+ /s{1,2}/,
15
+ /A/i
16
+ ];
17
+ return timePatterns.some((pattern)=>pattern.test(format));
18
+ }
19
+ function hasDateOnly(format) {
20
+ return hasDateInFormat(format) && !hasTimeInFormat(format);
21
+ }
22
+ function hasTimeOnly(format) {
23
+ return hasTimeInFormat(format) && !hasDateInFormat(format);
24
+ }
25
+ function getDateFormat(format) {
26
+ if (!hasDateInFormat(format)) return null;
27
+ if (hasDateOnly(format)) return format.trim();
28
+ const separators = [
29
+ ' ',
30
+ 'T',
31
+ ',',
32
+ '\t'
33
+ ];
34
+ for (const sep of separators)if (format.includes(sep)) {
35
+ const parts = format.split(sep);
36
+ for (const part of parts)if (hasDateInFormat(part) && !hasTimeInFormat(part)) return part.trim();
37
+ }
38
+ const datePatterns = [
39
+ /Y{2,4}[/-]M{1,2}[/-]D{1,2}/,
40
+ /Y{2,4}M{1,2}D{1,2}/,
41
+ /D{1,2}[/-]M{1,2}[/-]Y{2,4}/,
42
+ /M{1,2}[/-]D{1,2}[/-]Y{2,4}/
43
+ ];
44
+ for (const pattern of datePatterns){
45
+ const match = format.match(pattern);
46
+ if (match) return match[0];
47
+ }
48
+ return format.trim();
49
+ }
50
+ function getTimeFormat(format) {
51
+ if (!hasTimeInFormat(format)) return null;
52
+ if (hasTimeOnly(format)) return format.trim();
53
+ const separators = [
54
+ ' ',
55
+ 'T',
56
+ ',',
57
+ '\t'
58
+ ];
59
+ for (const sep of separators)if (format.includes(sep)) {
60
+ const parts = format.split(sep);
61
+ const timeParts = [];
62
+ for (const part of parts)if (hasTimeInFormat(part) || /AM|PM|am|pm/i.test(part)) timeParts.push(part.trim());
63
+ if (timeParts.length > 0) return timeParts.join(' ');
64
+ }
65
+ const timePatterns = [
66
+ /[Hh]{1,2}:[m]{1,2}:[s]{1,2}\s*(?:AM|PM|am|pm)?/,
67
+ /[Hh]{1,2}:[m]{1,2}\s*(?:AM|PM|am|pm)?/,
68
+ /[Hh]{1,2}[m]{1,2}[s]{1,2}\s*(?:AM|PM|am|pm)?/,
69
+ /[Hh]{1,2}[m]{1,2}\s*(?:AM|PM|am|pm)?/
70
+ ];
71
+ for (const pattern of timePatterns){
72
+ const match = format.match(pattern);
73
+ if (match) return match[0].trim();
74
+ }
75
+ return format.trim();
76
+ }
77
+ export { getDateFormat, getTimeFormat, hasDateInFormat, hasDateOnly, hasTimeInFormat, hasTimeOnly };
@@ -6,37 +6,6 @@ const Icon = ({ name, size = 16, color = 'default', ...props })=>{
6
6
  const { getColor } = useColors();
7
7
  const colorValue = getColor(color);
8
8
  switch(name){
9
- case 'checkboxOff':
10
- return /*#__PURE__*/ jsx(react_native_svg, {
11
- fill: "none",
12
- height: size,
13
- viewBox: "0 0 16 16",
14
- width: size,
15
- ...props,
16
- children: /*#__PURE__*/ jsx(Path, {
17
- d: "M2.46191 0.615234H13.5381C14.5577 0.615234 15.3848 1.44231 15.3848 2.46191V13.5381C15.3848 14.5577 14.5577 15.3848 13.5381 15.3848H2.46191C1.44231 15.3848 0.615234 14.5577 0.615234 13.5381V2.46191C0.615234 1.44231 1.44231 0.615234 2.46191 0.615234Z",
18
- stroke: colorValue,
19
- strokeWidth: 1.23077
20
- })
21
- });
22
- case 'checkboxOn':
23
- return /*#__PURE__*/ jsxs(react_native_svg, {
24
- fill: "none",
25
- height: size,
26
- viewBox: "0 0 16 16",
27
- width: size,
28
- ...props,
29
- children: [
30
- /*#__PURE__*/ jsx(Path, {
31
- d: "M2.46154 16H13.5385C14.8979 16 16 14.8979 16 13.5385V2.46154C16 1.10207 14.8979 0 13.5385 0H2.46154C1.10207 0 0 1.10207 0 2.46154V13.5385C0 14.8979 1.10207 16 2.46154 16Z",
32
- fill: colorValue
33
- }),
34
- /*#__PURE__*/ jsx(Path, {
35
- d: "M6.75547 9.24601L4.84436 7.3349C4.68139 7.17193 4.47399 7.09045 4.22214 7.09045C3.97028 7.09045 3.76288 7.17193 3.59991 7.3349C3.43695 7.49786 3.35547 7.70527 3.35547 7.95712C3.35547 8.20897 3.43695 8.41638 3.59991 8.57934L6.13325 11.1127C6.31102 11.2905 6.51843 11.3793 6.75547 11.3793C6.99251 11.3793 7.19991 11.2905 7.37769 11.1127L12.3999 6.09045C12.5629 5.92749 12.6444 5.72008 12.6444 5.46823C12.6444 5.21638 12.5629 5.00897 12.3999 4.84601C12.237 4.68304 12.0295 4.60156 11.7777 4.60156C11.5258 4.60156 11.3184 4.68304 11.1555 4.84601L6.75547 9.24601Z",
36
- fill: "#ffffff"
37
- })
38
- ]
39
- });
40
9
  case 'check':
41
10
  return /*#__PURE__*/ jsx(react_native_svg, {
42
11
  width: size,
@@ -1,7 +1,7 @@
1
1
  import type { SvgProps } from 'react-native-svg';
2
2
  import type { UXForegroundColor } from '@particle-network/ui-shared';
3
3
  export type IconProps = SvgProps & {
4
- name: 'checkboxOff' | 'checkboxOn' | 'check' | 'close' | 'dot' | 'radioOff' | 'radioOn' | 'question' | 'arrow-right';
4
+ name: 'check' | 'close' | 'dot' | 'radioOff' | 'radioOn' | 'question' | 'arrow-right';
5
5
  size?: number;
6
6
  color?: UXForegroundColor;
7
7
  };
@@ -10,6 +10,12 @@ export declare const en: {
10
10
  cancel: string;
11
11
  errorBothRequired: string;
12
12
  errorStartBeforeEnd: string;
13
+ selectDate: string;
14
+ selectTime: string;
15
+ selectDateAndTime: string;
16
+ selectDateRange: string;
17
+ selectTimeRange: string;
18
+ selectDateAndTimeRange: string;
13
19
  };
14
20
  modal: {
15
21
  confirm: string;
@@ -9,7 +9,13 @@ const en = {
9
9
  confirm: 'Confirm',
10
10
  cancel: 'Cancel',
11
11
  errorBothRequired: 'Both start and end dates are required',
12
- errorStartBeforeEnd: 'Start date can not be after end date'
12
+ errorStartBeforeEnd: 'Start date can not be after end date',
13
+ selectDate: 'Select Date',
14
+ selectTime: 'Select Time',
15
+ selectDateAndTime: 'Select Date and Time',
16
+ selectDateRange: 'Select Date Range',
17
+ selectTimeRange: 'Select Time Range',
18
+ selectDateAndTimeRange: 'Select Date and Time Range'
13
19
  },
14
20
  modal: {
15
21
  confirm: 'Confirm',
@@ -14,6 +14,12 @@ export declare const locales: {
14
14
  cancel: string;
15
15
  errorBothRequired: string;
16
16
  errorStartBeforeEnd: string;
17
+ selectDate: string;
18
+ selectTime: string;
19
+ selectDateAndTime: string;
20
+ selectDateRange: string;
21
+ selectTimeRange: string;
22
+ selectDateAndTimeRange: string;
17
23
  };
18
24
  modal: {
19
25
  confirm: string;
@@ -48,6 +54,12 @@ export declare const locales: {
48
54
  cancel: string;
49
55
  errorBothRequired: string;
50
56
  errorStartBeforeEnd: string;
57
+ selectDate: string;
58
+ selectTime: string;
59
+ selectDateAndTime: string;
60
+ selectDateRange: string;
61
+ selectTimeRange: string;
62
+ selectDateAndTimeRange: string;
51
63
  };
52
64
  modal: {
53
65
  confirm: string;
@@ -83,6 +95,12 @@ export declare function getLocaleText(locale: Locale): {
83
95
  cancel: string;
84
96
  errorBothRequired: string;
85
97
  errorStartBeforeEnd: string;
98
+ selectDate: string;
99
+ selectTime: string;
100
+ selectDateAndTime: string;
101
+ selectDateRange: string;
102
+ selectTimeRange: string;
103
+ selectDateAndTimeRange: string;
86
104
  };
87
105
  modal: {
88
106
  confirm: string;
@@ -9,7 +9,13 @@ const zh = {
9
9
  confirm: '确认',
10
10
  cancel: '取消',
11
11
  errorBothRequired: '请输入开始和结束日期',
12
- errorStartBeforeEnd: '开始日期不能晚于结束日期'
12
+ errorStartBeforeEnd: '开始日期不能晚于结束日期',
13
+ selectDate: '选择日期',
14
+ selectTime: '选择时间',
15
+ selectDateAndTime: '选择日期和时间',
16
+ selectDateRange: '选择起止日期',
17
+ selectTimeRange: '选择起止时间',
18
+ selectDateAndTimeRange: '选择起止日期和时间'
13
19
  },
14
20
  modal: {
15
21
  confirm: '确认',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-network/ui-native",
3
- "version": "0.1.4-beta.1",
3
+ "version": "0.1.4-beta.3",
4
4
  "main": "./entry.js",
5
5
  "react-native": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -90,9 +90,9 @@
90
90
  "unfetch": "^4.2.0",
91
91
  "vite": "^6.3.5",
92
92
  "zustand": "^5.0.8",
93
- "@particle-network/icons": "0.1.3-beta.3",
93
+ "@particle-network/lintstaged-config": "0.1.0",
94
94
  "@particle-network/eslint-config": "0.3.0",
95
- "@particle-network/lintstaged-config": "0.1.0"
95
+ "@particle-network/icons": "0.1.3-beta.3"
96
96
  },
97
97
  "overrides": {
98
98
  "react-docgen-typescript": "2.2.2",