@particle-network/ui-react 0.5.1-beta.9 → 0.6.0
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/ProgressWrapper/index.js +1 -2
- package/dist/components/UXAutocomplete/index.js +1 -2
- package/dist/components/UXCheckbox/checkbox.extend.js +15 -12
- package/dist/components/UXColorPicker/color-picker.js +42 -30
- package/dist/components/UXColorPicker/types.d.ts +4 -0
- package/dist/components/UXHint/index.js +1 -1
- package/dist/components/UXModal/index.d.ts +1 -1
- package/dist/components/UXRangeInput/index.d.ts +42 -0
- package/dist/components/UXRangeInput/index.js +94 -0
- package/dist/components/UXThemeSwitch/custom-theme-config.d.ts +4 -1
- package/dist/components/UXThemeSwitch/custom-theme-config.js +4 -3
- package/dist/components/UXThemeSwitch/index.d.ts +2 -2
- package/dist/components/UXThemeSwitch/index.js +2 -2
- package/dist/components/UXThemeSwitch/theme-item.js +3 -4
- package/dist/components/UXThemeSwitch/theme-switch.d.ts +8 -1
- package/dist/components/UXThemeSwitch/theme-switch.js +11 -17
- package/dist/components/UXThemeSwitch/use-theme.d.ts +2 -1
- package/dist/components/UXThemeSwitch/use-theme.js +4 -9
- package/dist/components/UXThemeSwitch/utils.js +43 -6
- package/dist/components/UXToast/index.d.ts +1 -1
- package/dist/components/UXToast/index.js +22 -10
- package/dist/components/UXTooltip/index.js +4 -12
- package/dist/components/WrapText/index.d.ts +6 -0
- package/dist/components/WrapText/index.js +15 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +2 -0
- package/dist/components/layout/Box/box-theme.d.ts +0 -12
- package/dist/components/layout/Box/box-theme.js +4 -8
- package/dist/components/layout/Box/box.js +10 -1
- package/dist/components/typography/Text.js +14 -4
- package/dist/components/typography/Text.type.d.ts +1 -0
- package/dist/hooks/useI18n.d.ts +8 -0
- package/dist/hooks/useI18n.js +8 -0
- package/dist/utils/cn.js +3 -11
- package/dist/utils/common.d.ts +4 -0
- package/dist/utils/common.js +13 -0
- package/package.json +3 -3
- package/tailwind-preset.js +6 -6
- package/dist/components/UXThemeSwitch/use-color-scheme.d.ts +0 -5
- package/dist/components/UXThemeSwitch/use-color-scheme.js +0 -14
- package/dist/components/UXThemeSwitch/use-theme-color.d.ts +0 -1
- package/dist/components/UXThemeSwitch/use-theme-color.js +0 -6
- package/dist/components/UXThemeSwitch/use-theme-store.d.ts +0 -46
- package/dist/components/UXThemeSwitch/use-theme-store.js +0 -36
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo, useRef } from "react";
|
|
4
|
-
import { radiusMap } from "@particle-network/ui-shared";
|
|
4
|
+
import { radiusMap, useThemeColor } from "@particle-network/ui-shared";
|
|
5
5
|
import { useSize } from "ahooks";
|
|
6
6
|
import { cn } from "../../utils/index.js";
|
|
7
7
|
import { Center } from "../layout/index.js";
|
|
8
|
-
import { useThemeColor } from "../UXThemeSwitch/use-theme-color.js";
|
|
9
8
|
const ProgressWrapper = ({ className, value = 0, width, height, radius = 'sm', strokeWidth = 1, color = 'primary', children, svgClassName, ...restProps })=>{
|
|
10
9
|
const uxColors = useThemeColor();
|
|
11
10
|
const autoLayout = !width && !height;
|
|
@@ -3,10 +3,9 @@ import "react";
|
|
|
3
3
|
import { Autocomplete, AutocompleteItem, AutocompleteSection } from "@heroui/autocomplete";
|
|
4
4
|
import ChevronDownIcon from "@particle-network/icons/web/ChevronDownIcon";
|
|
5
5
|
const UXAutocomplete = (props)=>{
|
|
6
|
-
const {
|
|
6
|
+
const { classNames = {}, radius = 'sm', labelPlacement = 'outside-top', ...restProps } = props;
|
|
7
7
|
const { base, popoverContent, selectorButton, endContentWrapper, clearButton, listboxWrapper } = classNames;
|
|
8
8
|
return /*#__PURE__*/ jsx(Autocomplete, {
|
|
9
|
-
fullWidth: fullWidth,
|
|
10
9
|
classNames: {
|
|
11
10
|
base: [
|
|
12
11
|
'ux-base',
|
|
@@ -27,34 +27,37 @@ const ExtendedCheckbox = extendVariants(Checkbox, {
|
|
|
27
27
|
},
|
|
28
28
|
size: {
|
|
29
29
|
sm: {
|
|
30
|
+
base: 'gap-1.5',
|
|
30
31
|
wrapper: [
|
|
31
32
|
'w-3.5 h-3.5 me-0',
|
|
32
33
|
'rounded-[calc(theme(borderRadius.medium)*0.2)]',
|
|
33
34
|
'before:rounded-[calc(theme(borderRadius.medium)*0.2)] before:border-secondary before:border-1',
|
|
34
35
|
'after:rounded-[calc(theme(borderRadius.medium)*0.2)]'
|
|
35
36
|
],
|
|
36
|
-
label: '!text-
|
|
37
|
-
icon: 'h-2
|
|
37
|
+
label: '!text-body2 font-medium',
|
|
38
|
+
icon: 'h-2'
|
|
38
39
|
},
|
|
39
40
|
md: {
|
|
41
|
+
base: 'gap-2',
|
|
40
42
|
wrapper: [
|
|
41
43
|
'w-4 h-4 me-0',
|
|
42
|
-
'rounded-[calc(theme(borderRadius.medium)*0.
|
|
43
|
-
'before:rounded-[calc(theme(borderRadius.medium)*0.
|
|
44
|
-
'after:rounded-[calc(theme(borderRadius.medium)*0.
|
|
44
|
+
'rounded-[calc(theme(borderRadius.medium)*0.3)]',
|
|
45
|
+
'before:rounded-[calc(theme(borderRadius.medium)*0.3)] before:border-secondary before:border-1.5',
|
|
46
|
+
'after:rounded-[calc(theme(borderRadius.medium)*0.3)]'
|
|
45
47
|
],
|
|
46
48
|
label: '!text-body2 font-medium',
|
|
47
|
-
icon: 'h-
|
|
49
|
+
icon: 'h-2.5'
|
|
48
50
|
},
|
|
49
51
|
lg: {
|
|
52
|
+
base: 'gap-2',
|
|
50
53
|
wrapper: [
|
|
51
54
|
'w-[18px] h-[18px] me-0',
|
|
52
|
-
'rounded-[calc(theme(borderRadius.medium)*0.
|
|
53
|
-
'before:rounded-[calc(theme(borderRadius.medium)*0.
|
|
54
|
-
'after:rounded-[calc(theme(borderRadius.medium)*0.
|
|
55
|
+
'rounded-[calc(theme(borderRadius.medium)*0.4)]',
|
|
56
|
+
'before:rounded-[calc(theme(borderRadius.medium)*0.4)] before:border-secondary before:border-1.5',
|
|
57
|
+
'after:rounded-[calc(theme(borderRadius.medium)*0.4)]'
|
|
55
58
|
],
|
|
56
59
|
label: '!text-body1 font-medium',
|
|
57
|
-
icon: 'h-3
|
|
60
|
+
icon: 'h-3'
|
|
58
61
|
}
|
|
59
62
|
},
|
|
60
63
|
radius: {
|
|
@@ -144,10 +147,10 @@ const ExtendedCheckbox = extendVariants(Checkbox, {
|
|
|
144
147
|
},
|
|
145
148
|
labelPlacement: {
|
|
146
149
|
left: {
|
|
147
|
-
base: 'flex-row-reverse
|
|
150
|
+
base: 'flex-row-reverse'
|
|
148
151
|
},
|
|
149
152
|
right: {
|
|
150
|
-
base: 'flex-row
|
|
153
|
+
base: 'flex-row'
|
|
151
154
|
}
|
|
152
155
|
}
|
|
153
156
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { ColorArea, ColorPicker, ColorSlider, ColorSwatch, ColorThumb, SliderTrack, parseColor } from "react-aria-components";
|
|
5
5
|
import ColorPickerIcon from "@particle-network/icons/web/ColorPickerIcon";
|
|
@@ -12,11 +12,12 @@ import { useThemeColor } from "../UXThemeSwitch/index.js";
|
|
|
12
12
|
import { ColorFields } from "./color-fields.js";
|
|
13
13
|
import { ColorInput } from "./color-input.js";
|
|
14
14
|
import { normalizeColor } from "./utils.js";
|
|
15
|
-
const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', value, defaultValue, onChange, onChangeEnd, onValueChange, onValueChangeEnd, isChanged, onReset })=>{
|
|
16
|
-
const
|
|
15
|
+
const UXColorPicker = ({ className, isDisabled, isIconOnly, placement = 'bottom-start', value, defaultValue, onChange, onChangeEnd, onValueChange, onValueChangeEnd, isChanged, onReset })=>{
|
|
16
|
+
const colors = useThemeColor();
|
|
17
17
|
const isControlled = void 0 !== value;
|
|
18
18
|
const [pickerKey, setPickerKey] = useState(0);
|
|
19
19
|
const [isInputFocused, setIsInputFocused] = useState(false);
|
|
20
|
+
const [isInteracting, setIsInteracting] = useState(false);
|
|
20
21
|
const getInitialColor = ()=>{
|
|
21
22
|
if (isControlled && value) return normalizeColor(value);
|
|
22
23
|
if (defaultValue) return normalizeColor(defaultValue);
|
|
@@ -31,12 +32,13 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
31
32
|
return parseColor('#000000');
|
|
32
33
|
});
|
|
33
34
|
const currentColor = useMemo(()=>{
|
|
34
|
-
if (isControlled && value) return normalizeColor(value);
|
|
35
|
+
if (isControlled && value && !isInteracting) return normalizeColor(value);
|
|
35
36
|
return internalColor;
|
|
36
37
|
}, [
|
|
37
38
|
value,
|
|
38
39
|
internalColor,
|
|
39
|
-
isControlled
|
|
40
|
+
isControlled,
|
|
41
|
+
isInteracting
|
|
40
42
|
]);
|
|
41
43
|
useEffect(()=>{
|
|
42
44
|
const initialColor = getInitialColor();
|
|
@@ -62,7 +64,10 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
62
64
|
]);
|
|
63
65
|
const handleChange = useCallback((color)=>{
|
|
64
66
|
if (color) {
|
|
65
|
-
|
|
67
|
+
if (isControlled) {
|
|
68
|
+
setInternalColor(color);
|
|
69
|
+
setIsInteracting(true);
|
|
70
|
+
} else setInternalColor(color);
|
|
66
71
|
onChange?.(color);
|
|
67
72
|
onValueChange?.(color.toString('hex'));
|
|
68
73
|
}
|
|
@@ -86,6 +91,7 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
86
91
|
]);
|
|
87
92
|
const handleChangeEnd = useCallback((color)=>{
|
|
88
93
|
if (color) {
|
|
94
|
+
setIsInteracting(false);
|
|
89
95
|
onChangeEnd?.(color);
|
|
90
96
|
onValueChangeEnd?.(color.toString('hex'));
|
|
91
97
|
}
|
|
@@ -123,12 +129,12 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
123
129
|
handleChangeEnd
|
|
124
130
|
]);
|
|
125
131
|
return /*#__PURE__*/ jsx(ColorPicker, {
|
|
126
|
-
value:
|
|
132
|
+
value: currentColor,
|
|
127
133
|
defaultValue: !isControlled && pickerKey > 0 ? internalColor : defaultValue,
|
|
128
134
|
onChange: handleChange,
|
|
129
135
|
children: /*#__PURE__*/ jsxs(HStack, {
|
|
130
136
|
gap: 2,
|
|
131
|
-
className: cn('rounded-small bg-background-200
|
|
137
|
+
className: cn(!isIconOnly && 'px-md rounded-small bg-background-200 h-[30px] w-[8.5rem]', isDisabled && 'opacity-disabled', isInputFocused && 'ring-foreground ring-1', className),
|
|
132
138
|
children: [
|
|
133
139
|
/*#__PURE__*/ jsxs(UXPopover, {
|
|
134
140
|
placement: placement,
|
|
@@ -139,7 +145,7 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
139
145
|
size: "auto",
|
|
140
146
|
isDisabled: isDisabled,
|
|
141
147
|
children: /*#__PURE__*/ jsx(ColorSwatch, {
|
|
142
|
-
className: cn('h-4 w-4 rounded-[4px]', internalColor.toString('hex') === bg200 && 'border-foreground/10 border')
|
|
148
|
+
className: cn('h-4 w-4 rounded-[4px]', internalColor.toString('hex') === colors.bg200 && 'border-foreground/10 border')
|
|
143
149
|
})
|
|
144
150
|
})
|
|
145
151
|
}),
|
|
@@ -153,6 +159,7 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
153
159
|
xChannel: "saturation",
|
|
154
160
|
yChannel: "brightness",
|
|
155
161
|
className: "aspect-square w-full overflow-hidden rounded-lg",
|
|
162
|
+
onChange: handleChange,
|
|
156
163
|
onChangeEnd: handleChangeEnd,
|
|
157
164
|
children: /*#__PURE__*/ jsx(ColorThumb, {
|
|
158
165
|
className: "h-4 w-4 rounded-full border-2 border-white shadow-[0_2px_4px_rgba(0,0,0,0.2)]"
|
|
@@ -179,6 +186,7 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
179
186
|
className: "min-w-0 flex-1",
|
|
180
187
|
colorSpace: "hsl",
|
|
181
188
|
orientation: "horizontal",
|
|
189
|
+
onChange: handleChange,
|
|
182
190
|
onChangeEnd: handleChangeEnd,
|
|
183
191
|
children: /*#__PURE__*/ jsx(SliderTrack, {
|
|
184
192
|
className: "h-3 rounded-full",
|
|
@@ -191,7 +199,7 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
191
199
|
}),
|
|
192
200
|
/*#__PURE__*/ jsx(ColorFields, {
|
|
193
201
|
defaultValue: !isControlled && pickerKey > 0 ? internalColor : defaultValue,
|
|
194
|
-
value:
|
|
202
|
+
value: currentColor,
|
|
195
203
|
onChange: handleColorFieldsChange
|
|
196
204
|
})
|
|
197
205
|
]
|
|
@@ -199,26 +207,30 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
199
207
|
})
|
|
200
208
|
]
|
|
201
209
|
}),
|
|
202
|
-
/*#__PURE__*/
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
210
|
+
!isIconOnly && /*#__PURE__*/ jsxs(Fragment, {
|
|
211
|
+
children: [
|
|
212
|
+
/*#__PURE__*/ jsx(ColorInput, {
|
|
213
|
+
isDisabled: isDisabled,
|
|
214
|
+
inputClassName: "focus:ring-0 px-0 text-left flex-1 relative bg-transparent",
|
|
215
|
+
value: currentColor,
|
|
216
|
+
defaultValue: !isControlled && pickerKey > 0 ? internalColor : defaultValue,
|
|
217
|
+
onChange: handleColorFieldsChange,
|
|
218
|
+
onFocus: ()=>setIsInputFocused(true),
|
|
219
|
+
onBlur: ()=>setIsInputFocused(false)
|
|
220
|
+
}),
|
|
221
|
+
hasChanged ? /*#__PURE__*/ jsx(UXButton, {
|
|
222
|
+
isIconOnly: true,
|
|
223
|
+
"aria-label": "Reset color",
|
|
224
|
+
isDisabled: isDisabled,
|
|
225
|
+
size: "sm",
|
|
226
|
+
variant: "light",
|
|
227
|
+
color: "secondary",
|
|
228
|
+
onPress: handleReset,
|
|
229
|
+
children: /*#__PURE__*/ jsx(RefreshCcwIcon, {})
|
|
230
|
+
}) : /*#__PURE__*/ jsx("div", {
|
|
231
|
+
className: "size-4 shrink-0"
|
|
232
|
+
})
|
|
233
|
+
]
|
|
222
234
|
})
|
|
223
235
|
]
|
|
224
236
|
})
|
|
@@ -42,6 +42,10 @@ export interface UXColorPickerProps {
|
|
|
42
42
|
* Popover 位置
|
|
43
43
|
*/
|
|
44
44
|
placement?: UXPopoverProps['placement'];
|
|
45
|
+
/**
|
|
46
|
+
* 是否只显示图标
|
|
47
|
+
*/
|
|
48
|
+
isIconOnly?: boolean;
|
|
45
49
|
}
|
|
46
50
|
export interface ColorFieldsProps extends Pick<UXColorPickerProps, 'value' | 'defaultValue'> {
|
|
47
51
|
/**
|
|
@@ -6,7 +6,7 @@ import { cn } from "../../utils/index.js";
|
|
|
6
6
|
const UXHint = (props)=>{
|
|
7
7
|
const { content, children, buttonClassName, iconClassName, triggerType = 'hover', ...restProps } = props;
|
|
8
8
|
const renderTriggerContent = ()=>/*#__PURE__*/ jsx(Center, {
|
|
9
|
-
className: cn('
|
|
9
|
+
className: cn('min-h-4 min-w-4 cursor-pointer', buttonClassName),
|
|
10
10
|
children: /*#__PURE__*/ jsx(CircleQuestionIcon, {
|
|
11
11
|
size: 14,
|
|
12
12
|
className: iconClassName
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type ModalProps } from '@heroui/modal';
|
|
3
|
-
export type UXModalProps = Omit<ModalProps, 'closeButton'> & {
|
|
3
|
+
export type UXModalProps = Omit<ModalProps, 'closeButton' | 'title'> & {
|
|
4
4
|
title?: React.ReactNode;
|
|
5
5
|
footer?: React.ReactNode;
|
|
6
6
|
tip?: React.ReactNode;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type UXNumberInputProps } from '../UXNumberInput';
|
|
3
|
+
export interface UXRangeInputValue {
|
|
4
|
+
min?: number;
|
|
5
|
+
max?: number;
|
|
6
|
+
}
|
|
7
|
+
export type UXRangeInputProps = Omit<UXNumberInputProps, 'value' | 'defaultValue' | 'onValueChange' | 'minValue' | 'maxValue'> & {
|
|
8
|
+
asFragment?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The current value of the range input (controlled)
|
|
11
|
+
*/
|
|
12
|
+
value?: UXRangeInputValue;
|
|
13
|
+
/**
|
|
14
|
+
* The default value of the range input (uncontrolled)
|
|
15
|
+
*/
|
|
16
|
+
defaultValue?: UXRangeInputValue;
|
|
17
|
+
/**
|
|
18
|
+
* The minimum value allowed for both inputs
|
|
19
|
+
*/
|
|
20
|
+
minValue?: number;
|
|
21
|
+
/**
|
|
22
|
+
* The maximum value allowed for both inputs
|
|
23
|
+
*/
|
|
24
|
+
maxValue?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Props for the minimum input
|
|
27
|
+
*/
|
|
28
|
+
minInputProps?: Partial<UXNumberInputProps>;
|
|
29
|
+
/**
|
|
30
|
+
* Props for the maximum input
|
|
31
|
+
*/
|
|
32
|
+
maxInputProps?: Partial<UXNumberInputProps>;
|
|
33
|
+
/**
|
|
34
|
+
* Separator between the two inputs
|
|
35
|
+
*/
|
|
36
|
+
separator?: React.ReactNode;
|
|
37
|
+
/**
|
|
38
|
+
* Callback fired when the value changes
|
|
39
|
+
*/
|
|
40
|
+
onValueChange?: (value: UXRangeInputValue) => void;
|
|
41
|
+
};
|
|
42
|
+
export declare const UXRangeInput: React.FC<UXRangeInputProps>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import react, { Fragment, useCallback, useMemo } from "react";
|
|
3
|
+
import { useI18n } from "../../hooks/index.js";
|
|
4
|
+
import { HStack } from "../layout/index.js";
|
|
5
|
+
import { UXNumberInput } from "../UXNumberInput/index.js";
|
|
6
|
+
const UXRangeInput = (props)=>{
|
|
7
|
+
const { asFragment, value, defaultValue, onValueChange, minValue, maxValue, minInputProps = {}, maxInputProps = {}, separator = '', className, ...restProps } = props;
|
|
8
|
+
const i18n = useI18n();
|
|
9
|
+
const [internalValue, setInternalValue] = react.useState(defaultValue || {
|
|
10
|
+
min: void 0,
|
|
11
|
+
max: void 0
|
|
12
|
+
});
|
|
13
|
+
const currentValue = void 0 !== value ? value : internalValue;
|
|
14
|
+
const handleMinChange = useCallback((newMin)=>{
|
|
15
|
+
const minValue = isNaN(newMin) ? 0 : newMin;
|
|
16
|
+
const newValue = {
|
|
17
|
+
min: minValue,
|
|
18
|
+
max: currentValue.max
|
|
19
|
+
};
|
|
20
|
+
if (void 0 !== currentValue.max && !isNaN(currentValue.max) && minValue > currentValue.max) newValue.max = minValue;
|
|
21
|
+
if (void 0 === value) setInternalValue(newValue);
|
|
22
|
+
onValueChange?.(newValue);
|
|
23
|
+
}, [
|
|
24
|
+
currentValue.max,
|
|
25
|
+
value,
|
|
26
|
+
onValueChange
|
|
27
|
+
]);
|
|
28
|
+
const handleMaxChange = useCallback((newMax)=>{
|
|
29
|
+
const maxValue = isNaN(newMax) ? 0 : newMax;
|
|
30
|
+
const newValue = {
|
|
31
|
+
min: currentValue.min,
|
|
32
|
+
max: maxValue
|
|
33
|
+
};
|
|
34
|
+
if (void 0 !== currentValue.min && !isNaN(currentValue.min) && maxValue < currentValue.min) newValue.min = maxValue;
|
|
35
|
+
if (void 0 === value) setInternalValue(newValue);
|
|
36
|
+
onValueChange?.(newValue);
|
|
37
|
+
}, [
|
|
38
|
+
currentValue.min,
|
|
39
|
+
value,
|
|
40
|
+
onValueChange
|
|
41
|
+
]);
|
|
42
|
+
const minInputMaxValue = useMemo(()=>{
|
|
43
|
+
if (void 0 !== currentValue.max && !isNaN(currentValue.max)) return currentValue.max;
|
|
44
|
+
return maxValue;
|
|
45
|
+
}, [
|
|
46
|
+
currentValue.max,
|
|
47
|
+
maxValue
|
|
48
|
+
]);
|
|
49
|
+
const maxInputMinValue = useMemo(()=>{
|
|
50
|
+
if (void 0 !== currentValue.min && !isNaN(currentValue.min)) return currentValue.min;
|
|
51
|
+
return minValue;
|
|
52
|
+
}, [
|
|
53
|
+
currentValue.min,
|
|
54
|
+
minValue
|
|
55
|
+
]);
|
|
56
|
+
const Wrapper = asFragment ? Fragment : HStack;
|
|
57
|
+
return /*#__PURE__*/ jsxs(Wrapper, {
|
|
58
|
+
gap: 2,
|
|
59
|
+
className: className,
|
|
60
|
+
children: [
|
|
61
|
+
/*#__PURE__*/ jsx(UXNumberInput, {
|
|
62
|
+
startContent: /*#__PURE__*/ jsx("span", {
|
|
63
|
+
className: "shrink-0",
|
|
64
|
+
"aria-hidden": "true",
|
|
65
|
+
children: i18n.rangeInput.min
|
|
66
|
+
}),
|
|
67
|
+
textAlign: "right",
|
|
68
|
+
...restProps,
|
|
69
|
+
...minInputProps,
|
|
70
|
+
value: currentValue.min,
|
|
71
|
+
minValue: minValue,
|
|
72
|
+
maxValue: minInputMaxValue,
|
|
73
|
+
onValueChange: handleMinChange
|
|
74
|
+
}),
|
|
75
|
+
separator,
|
|
76
|
+
/*#__PURE__*/ jsx(UXNumberInput, {
|
|
77
|
+
startContent: /*#__PURE__*/ jsx("span", {
|
|
78
|
+
className: "shrink-0",
|
|
79
|
+
"aria-hidden": "true",
|
|
80
|
+
children: i18n.rangeInput.max
|
|
81
|
+
}),
|
|
82
|
+
textAlign: "right",
|
|
83
|
+
...restProps,
|
|
84
|
+
...maxInputProps,
|
|
85
|
+
value: currentValue.max,
|
|
86
|
+
minValue: maxInputMinValue,
|
|
87
|
+
maxValue: maxValue,
|
|
88
|
+
onValueChange: handleMaxChange
|
|
89
|
+
})
|
|
90
|
+
]
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
UXRangeInput.displayName = 'UX.RangeInput';
|
|
94
|
+
export { UXRangeInput };
|
|
@@ -46,7 +46,7 @@ const COLOR_CATEGORIES = {
|
|
|
46
46
|
'blue'
|
|
47
47
|
]
|
|
48
48
|
};
|
|
49
|
-
const CustomThemeConfig = ()=>{
|
|
49
|
+
const CustomThemeConfig = ({ colorChangeMode = 'dragEnd' })=>{
|
|
50
50
|
const { lang } = useLang();
|
|
51
51
|
const i18n = useI18n();
|
|
52
52
|
const { theme, setTheme, setCustomTheme } = useTheme();
|
|
@@ -102,9 +102,10 @@ const CustomThemeConfig = ()=>{
|
|
|
102
102
|
children: label
|
|
103
103
|
}),
|
|
104
104
|
/*#__PURE__*/ jsx(UXColorPicker, {
|
|
105
|
-
|
|
105
|
+
defaultValue: value,
|
|
106
106
|
isChanged: isCustomized,
|
|
107
|
-
onValueChange: (newValue)=>handleColorChange(color, newValue),
|
|
107
|
+
onValueChange: 'drag' === colorChangeMode ? (newValue)=>handleColorChange(color, newValue) : void 0,
|
|
108
|
+
onValueChangeEnd: 'dragEnd' === colorChangeMode ? (newValue)=>handleColorChange(color, newValue) : void 0,
|
|
108
109
|
onReset: ()=>handleColorChange(color, baseTheme.colorVariables[color])
|
|
109
110
|
})
|
|
110
111
|
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
+
import { useColorScheme, useThemeColor, useThemeStore } from '@particle-network/ui-shared';
|
|
1
2
|
export * from './theme-switch';
|
|
2
|
-
export * from './use-color-scheme';
|
|
3
3
|
export * from './use-theme';
|
|
4
|
-
export
|
|
4
|
+
export { useColorScheme, useThemeColor, useThemeStore };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
+
import { useColorScheme, useThemeColor, useThemeStore } from "@particle-network/ui-shared";
|
|
1
2
|
export * from "./theme-switch.js";
|
|
2
|
-
export * from "./use-color-scheme.js";
|
|
3
3
|
export * from "./use-theme.js";
|
|
4
|
-
export
|
|
4
|
+
export { useColorScheme, useThemeColor, useThemeStore };
|
|
@@ -162,8 +162,7 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
162
162
|
'custom' === id ? /*#__PURE__*/ jsxs(Fragment, {
|
|
163
163
|
children: [
|
|
164
164
|
/*#__PURE__*/ jsx("g", {
|
|
165
|
-
|
|
166
|
-
"data-figma-skip-parse": "true",
|
|
165
|
+
clipPath: "url(#paint0_angular_48986_280686_clip_path)",
|
|
167
166
|
children: /*#__PURE__*/ jsx("g", {
|
|
168
167
|
transform: "matrix(0 0.011 -0.011 0 39 51)",
|
|
169
168
|
children: /*#__PURE__*/ jsx("foreignObject", {
|
|
@@ -188,7 +187,7 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
188
187
|
r: "10.7583",
|
|
189
188
|
"data-figma-gradient-fill": '{"type":"GRADIENT_ANGULAR","stops":[{"color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0},"position":0.0},{"color":{"r":1.0,"g":0.52295231819152832,"b":0.0,"a":1.0},"position":0.15000000596046448},{"color":{"r":0.74555355310440063,"g":1.0,"b":0.0,"a":1.0},"position":0.32499998807907104},{"color":{"r":0.029410807415843010,"g":0.88352936506271362,"b":1.0,"a":1.0},"position":0.55500000715255737},{"color":{"r":0.14000000059604645,"g":0.0,"b":1.0,"a":1.0},"position":0.78500002622604370},{"color":{"r":0.67999994754791260,"g":0.0,"b":1.0,"a":1.0},"position":1.0}],"stopsVar":[{"color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0},"position":0.0},{"color":{"r":1.0,"g":0.52295231819152832,"b":0.0,"a":1.0},"position":0.15000000596046448},{"color":{"r":0.74555355310440063,"g":1.0,"b":0.0,"a":1.0},"position":0.32499998807907104},{"color":{"r":0.029410807415843010,"g":0.88352936506271362,"b":1.0,"a":1.0},"position":0.55500000715255737},{"color":{"r":0.14000000059604645,"g":0.0,"b":1.0,"a":1.0},"position":0.78500002622604370},{"color":{"r":0.67999994754791260,"g":0.0,"b":1.0,"a":1.0},"position":1.0}],"transform":{"m00":1.3471115643134642e-15,"m01":-22.0,"m02":50.0,"m10":22.0,"m11":1.3471115643134642e-15,"m12":40.0},"opacity":1.0,"blendMode":"NORMAL","visible":true}',
|
|
190
189
|
stroke: "#8B8EA1",
|
|
191
|
-
|
|
190
|
+
strokeWidth: "0.483303"
|
|
192
191
|
}),
|
|
193
192
|
/*#__PURE__*/ jsx("defs", {
|
|
194
193
|
children: /*#__PURE__*/ jsx("clipPath", {
|
|
@@ -197,7 +196,7 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
197
196
|
cx: "39",
|
|
198
197
|
cy: "51",
|
|
199
198
|
r: "10.7583",
|
|
200
|
-
|
|
199
|
+
strokeWidth: "0.483303"
|
|
201
200
|
})
|
|
202
201
|
})
|
|
203
202
|
})
|
|
@@ -4,9 +4,16 @@ import { type UXModalProps } from '../UXModal';
|
|
|
4
4
|
export interface UXThemeSwitchModalProps extends Pick<UXModalProps, 'isOpen' | 'onClose' | 'onOpenChange' | 'backdrop'> {
|
|
5
5
|
as?: 'modal' | 'drawer';
|
|
6
6
|
omitThemes?: ThemeId[];
|
|
7
|
+
/**
|
|
8
|
+
* 颜色改变模式
|
|
9
|
+
* - drag: 拖动时改变颜色
|
|
10
|
+
* - dragEnd: 拖动停止时改变颜色
|
|
11
|
+
* @default dragEnd
|
|
12
|
+
*/
|
|
13
|
+
colorChangeMode?: 'drag' | 'dragEnd';
|
|
7
14
|
}
|
|
8
15
|
export declare const UXThemeSwitchModal: React.FC<UXThemeSwitchModalProps>;
|
|
9
|
-
export interface UXThemeSwitchProps extends Pick<UXThemeSwitchModalProps, 'as' | 'omitThemes' | 'backdrop'> {
|
|
16
|
+
export interface UXThemeSwitchProps extends Pick<UXThemeSwitchModalProps, 'as' | 'omitThemes' | 'backdrop' | 'colorChangeMode'> {
|
|
10
17
|
children?: (onOpen: () => void) => React.ReactNode;
|
|
11
18
|
}
|
|
12
19
|
export declare const UXThemeSwitch: React.FC<UXThemeSwitchProps>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo, useState } from "react";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
3
|
import { useDisclosure } from "@heroui/use-disclosure";
|
|
4
4
|
import { ChartColorSwitchIcon, CopyIcon } from "@particle-network/icons/web";
|
|
5
|
-
import {
|
|
5
|
+
import { themeData } from "@particle-network/ui-shared";
|
|
6
6
|
import { useI18n } from "../../hooks/index.js";
|
|
7
7
|
import { cn } from "../../utils/index.js";
|
|
8
8
|
import { HStack, VStack } from "../layout/index.js";
|
|
@@ -32,27 +32,19 @@ const FONT_EXAMPLES = [
|
|
|
32
32
|
url: 'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'
|
|
33
33
|
}
|
|
34
34
|
];
|
|
35
|
-
const UXThemeSwitchModal = ({ as = 'modal', omitThemes = [], backdrop, isOpen, onClose, onOpenChange })=>{
|
|
35
|
+
const UXThemeSwitchModal = ({ as = 'modal', omitThemes = [], backdrop, isOpen, onClose, onOpenChange, colorChangeMode })=>{
|
|
36
36
|
const i18n = useI18n();
|
|
37
|
-
const { theme: selectedTheme, customTheme: savedCustomTheme, setTheme, fontUrl, setFontUrl, fontName, fontLoadStatus, clearFontUrl } = useTheme();
|
|
37
|
+
const { theme: selectedTheme, customTheme: savedCustomTheme, setTheme, initTheme, fontUrl, setFontUrl, fontName, fontLoadStatus, clearFontUrl } = useTheme();
|
|
38
38
|
const [isFontExampleOpen, setIsFontExampleOpen] = useState(false);
|
|
39
|
+
useEffect(()=>{
|
|
40
|
+
initTheme();
|
|
41
|
+
}, []);
|
|
39
42
|
const Component = 'modal' === as ? UXModal : UXDrawer;
|
|
40
43
|
const themes = useMemo(()=>themeData.filter((theme)=>!omitThemes.includes(theme.id)), [
|
|
41
44
|
omitThemes
|
|
42
45
|
]);
|
|
43
46
|
const handleThemeSelect = (theme)=>{
|
|
44
|
-
|
|
45
|
-
else {
|
|
46
|
-
const baseTheme = themeData.find((t)=>t.id === DEFAULT_THEME_ID) || themeData["0"];
|
|
47
|
-
const customTheme = {
|
|
48
|
-
...theme,
|
|
49
|
-
baseThemeId: DEFAULT_THEME_ID,
|
|
50
|
-
colorScheme: baseTheme.colorScheme,
|
|
51
|
-
colorVariables: baseTheme.colorVariables
|
|
52
|
-
};
|
|
53
|
-
setTheme(customTheme);
|
|
54
|
-
}
|
|
55
|
-
else setTheme(theme);
|
|
47
|
+
'custom' === theme.id ? setTheme(savedCustomTheme) : setTheme(theme);
|
|
56
48
|
};
|
|
57
49
|
return /*#__PURE__*/ jsx(Component, {
|
|
58
50
|
isOpen: isOpen,
|
|
@@ -83,7 +75,9 @@ const UXThemeSwitchModal = ({ as = 'modal', omitThemes = [], backdrop, isOpen, o
|
|
|
83
75
|
'custom' === selectedTheme.id && /*#__PURE__*/ jsxs(Fragment, {
|
|
84
76
|
children: [
|
|
85
77
|
/*#__PURE__*/ jsx(UXDivider, {}),
|
|
86
|
-
/*#__PURE__*/ jsx(CustomThemeConfig, {
|
|
78
|
+
/*#__PURE__*/ jsx(CustomThemeConfig, {
|
|
79
|
+
colorChangeMode: colorChangeMode
|
|
80
|
+
})
|
|
87
81
|
]
|
|
88
82
|
}),
|
|
89
83
|
/*#__PURE__*/ jsx(UXDivider, {}),
|
|
@@ -6,10 +6,11 @@ export declare const useTheme: () => {
|
|
|
6
6
|
theme: ThemeItemType;
|
|
7
7
|
customTheme: ThemeItemType;
|
|
8
8
|
setTheme: (theme: ThemeItemType) => void;
|
|
9
|
+
initTheme: () => void;
|
|
9
10
|
setCustomTheme: (customTheme: ThemeItemType) => void;
|
|
10
11
|
fontUrl: string;
|
|
11
12
|
setFontUrl: (link: string) => void;
|
|
12
13
|
clearFontUrl: () => void;
|
|
13
|
-
fontLoadStatus: import("
|
|
14
|
+
fontLoadStatus: import("@particle-network/ui-shared").FontLoadStatus;
|
|
14
15
|
fontName: string;
|
|
15
16
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useThemeStore } from "@particle-network/ui-shared";
|
|
2
2
|
import { useDebounceFn } from "ahooks";
|
|
3
|
-
import { useThemeStore } from "./use-theme-store.js";
|
|
4
3
|
import { applyFont, applyTheme, extractFontFamilyFromLink, preloadFonts } from "./utils.js";
|
|
5
4
|
const useTheme = ()=>{
|
|
6
5
|
const theme = useThemeStore((state)=>state.theme);
|
|
@@ -42,16 +41,11 @@ const useTheme = ()=>{
|
|
|
42
41
|
const { run: debouncedApplyFont } = useDebounceFn((customFontLink, themeFontName)=>applyFontWithStatus(customFontLink, themeFontName), {
|
|
43
42
|
wait: 300
|
|
44
43
|
});
|
|
45
|
-
|
|
44
|
+
const initTheme = ()=>{
|
|
46
45
|
preloadFonts();
|
|
47
46
|
applyTheme(theme);
|
|
48
47
|
debouncedApplyFont(fontUrl, theme.fontName);
|
|
49
|
-
}
|
|
50
|
-
useEffect(()=>{
|
|
51
|
-
applyTheme(theme);
|
|
52
|
-
}, [
|
|
53
|
-
theme
|
|
54
|
-
]);
|
|
48
|
+
};
|
|
55
49
|
const setTheme = (theme)=>{
|
|
56
50
|
storeSetTheme(theme);
|
|
57
51
|
applyTheme(theme);
|
|
@@ -71,6 +65,7 @@ const useTheme = ()=>{
|
|
|
71
65
|
theme,
|
|
72
66
|
customTheme,
|
|
73
67
|
setTheme,
|
|
68
|
+
initTheme,
|
|
74
69
|
setCustomTheme: storeSetCustomTheme,
|
|
75
70
|
fontUrl,
|
|
76
71
|
setFontUrl,
|