@particle-network/ui-react 0.5.1-beta.4 → 0.5.1-beta.5
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.d.ts +2 -2
- package/dist/components/UXChip/chip.extend.d.ts +2 -1
- package/dist/components/UXChip/index.d.ts +1 -1
- package/dist/components/UXColorPicker/color-picker.js +1 -1
- package/dist/components/UXColorPicker/types.d.ts +1 -1
- package/dist/components/UXThemeSwitch/constants.d.ts +9 -0
- package/dist/components/UXThemeSwitch/constants.js +3 -0
- package/dist/components/UXThemeSwitch/custom-theme-config.js +52 -15
- package/dist/components/UXThemeSwitch/theme-item.js +47 -11
- package/dist/components/UXThemeSwitch/theme-switch.js +6 -5
- package/dist/components/UXThemeSwitch/use-theme-color.d.ts +1 -22
- package/dist/components/UXThemeSwitch/use-theme-color.js +1 -9
- package/dist/components/UXThemeSwitch/use-theme-store.d.ts +5 -0
- package/dist/components/UXThemeSwitch/use-theme-store.js +9 -4
- package/dist/components/UXThemeSwitch/use-theme.d.ts +2 -0
- package/dist/components/UXThemeSwitch/use-theme.js +5 -76
- package/dist/components/UXThemeSwitch/utils.d.ts +28 -0
- package/dist/components/UXThemeSwitch/utils.js +202 -0
- package/dist/components/typography/Text.type.d.ts +2 -2
- package/dist/components/typography/Text.type.js +0 -1
- package/dist/heroui/constants.d.ts +18 -0
- package/dist/heroui/constants.js +98 -0
- package/dist/heroui/types.d.ts +91 -0
- package/dist/heroui/types.js +0 -0
- package/dist/heroui/utils/colors.d.ts +34 -0
- package/dist/heroui/utils/colors.js +121 -0
- package/dist/heroui/utils/object.d.ts +1 -0
- package/dist/heroui/utils/object.js +17 -0
- package/dist/hooks/useI18n.d.ts +54 -38
- package/dist/hooks/useI18n.js +54 -38
- package/package.json +4 -3
- package/tailwind-preset.js +22 -69
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { type UXForegroundColor, type UXRadius } from '@particle-network/ui-shared';
|
|
2
|
+
import { type HexColor, type UXForegroundColor, type UXRadius } from '@particle-network/ui-shared';
|
|
3
3
|
export interface ProgressWrapperProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
/**
|
|
5
5
|
* 进度 (%)
|
|
@@ -24,7 +24,7 @@ export interface ProgressWrapperProps extends React.HTMLAttributes<HTMLDivElemen
|
|
|
24
24
|
/**
|
|
25
25
|
* 进度条颜色
|
|
26
26
|
*/
|
|
27
|
-
color?: UXForegroundColor | 'transparent' |
|
|
27
|
+
color?: Exclude<UXForegroundColor, 'default' | 'white'> | 'transparent' | HexColor;
|
|
28
28
|
/**
|
|
29
29
|
* 进度条 SVG 样式
|
|
30
30
|
*/
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import { type ChipProps } from '@heroui/chip';
|
|
3
|
+
import type { HexColor } from '@particle-network/ui-shared';
|
|
3
4
|
type ExtendedChipProps = Omit<ChipProps, 'color'> & {
|
|
4
|
-
color?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'alert' | 'danger' | 'bullish' | 'bearish' |
|
|
5
|
+
color?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'alert' | 'danger' | 'bullish' | 'bearish' | HexColor;
|
|
5
6
|
};
|
|
6
7
|
declare const ExtendedChip: React.ForwardRefExoticComponent<ExtendedChipProps>;
|
|
7
8
|
export default ExtendedChip;
|
|
@@ -2,5 +2,5 @@ import React from 'react';
|
|
|
2
2
|
import ExtendedChip from './chip.extend';
|
|
3
3
|
export type UXChipProps = React.ComponentPropsWithRef<typeof ExtendedChip>;
|
|
4
4
|
export declare const UXChip: import("@heroui/system-rsc").InternalForwardRefRenderFunction<"div", Omit<import("@heroui/chip").ChipProps, "color"> & {
|
|
5
|
-
color?: "default" | "primary" | "secondary" | "success" | "warning" | "alert" | "danger" | "bullish" | "bearish" |
|
|
5
|
+
color?: "default" | "primary" | "secondary" | "success" | "warning" | "alert" | "danger" | "bullish" | "bearish" | import("@particle-network/ui-shared").HexColor;
|
|
6
6
|
}, never>;
|
|
@@ -201,7 +201,7 @@ const UXColorPicker = ({ className, isDisabled, placement = 'bottom-start', valu
|
|
|
201
201
|
}),
|
|
202
202
|
/*#__PURE__*/ jsx(ColorInput, {
|
|
203
203
|
isDisabled: isDisabled,
|
|
204
|
-
inputClassName: "focus:ring-0 px-0 text-left flex-1 relative
|
|
204
|
+
inputClassName: "focus:ring-0 px-0 text-left flex-1 relative bg-transparent",
|
|
205
205
|
value: value,
|
|
206
206
|
defaultValue: !isControlled && pickerKey > 0 ? internalColor : defaultValue,
|
|
207
207
|
onChange: handleColorFieldsChange,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 默认字体
|
|
3
|
+
*/
|
|
4
|
+
export declare const DEFAULT_FONT_FAMILY = "Inter,system-ui,sans-serif,\"Microsoft YaHei\"";
|
|
5
|
+
/**
|
|
6
|
+
* 预加载所有主题字体的 Google Fonts CSS
|
|
7
|
+
* 包含所有可能用到的字体,一次性加载,避免切换主题时重复加载
|
|
8
|
+
*/
|
|
9
|
+
export declare const PRELOAD_FONTS_URL = "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&display=swap";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
const DEFAULT_FONT_FAMILY = 'Inter,system-ui,sans-serif,"Microsoft YaHei"';
|
|
2
|
+
const PRELOAD_FONTS_URL = 'https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&display=swap';
|
|
3
|
+
export { DEFAULT_FONT_FAMILY, PRELOAD_FONTS_URL };
|
|
@@ -5,6 +5,7 @@ import { produce } from "immer";
|
|
|
5
5
|
import { useI18n, useLang } from "../../hooks/index.js";
|
|
6
6
|
import { HStack, VStack } from "../layout/index.js";
|
|
7
7
|
import { Text } from "../typography/Text.js";
|
|
8
|
+
import { UXButton } from "../UXButton/index.js";
|
|
8
9
|
import { UXColorPicker } from "../UXColorPicker/index.js";
|
|
9
10
|
import { UXSelect, UXSelectItem } from "../UXSelect/index.js";
|
|
10
11
|
import { UXTab, UXTabs } from "../UXTabs/index.js";
|
|
@@ -28,17 +29,25 @@ const COLOR_CATEGORIES = {
|
|
|
28
29
|
'secondary',
|
|
29
30
|
'tertiary'
|
|
30
31
|
],
|
|
32
|
+
candle: [
|
|
33
|
+
'candleUp',
|
|
34
|
+
'candleBorderUp',
|
|
35
|
+
'candleWickUp',
|
|
36
|
+
'candleDown',
|
|
37
|
+
'candleBorderDown',
|
|
38
|
+
'candleWickDown'
|
|
39
|
+
],
|
|
31
40
|
signal: [
|
|
32
41
|
'success',
|
|
33
42
|
'danger',
|
|
34
|
-
'
|
|
35
|
-
'
|
|
43
|
+
'warning',
|
|
44
|
+
'alert'
|
|
36
45
|
]
|
|
37
46
|
};
|
|
38
47
|
const CustomThemeConfig = ()=>{
|
|
39
48
|
const { lang } = useLang();
|
|
40
49
|
const i18n = useI18n();
|
|
41
|
-
const { theme, setTheme } = useTheme();
|
|
50
|
+
const { theme, setTheme, setCustomTheme } = useTheme();
|
|
42
51
|
const baseThemes = useMemo(()=>themeData.filter((t)=>'custom' !== t.id), []);
|
|
43
52
|
const baseThemeId = theme.baseThemeId || DEFAULT_THEME_ID;
|
|
44
53
|
const baseTheme = useMemo(()=>themeData.find((t)=>t.id === baseThemeId) || themeData.find((t)=>t.id === DEFAULT_THEME_ID), [
|
|
@@ -46,18 +55,38 @@ const CustomThemeConfig = ()=>{
|
|
|
46
55
|
]);
|
|
47
56
|
const handleBaseThemeChange = (themeId)=>{
|
|
48
57
|
const selectedBaseTheme = themeData.find((t)=>t.id === themeId);
|
|
49
|
-
if (selectedBaseTheme)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
if (selectedBaseTheme) {
|
|
59
|
+
const updatedTheme = {
|
|
60
|
+
...theme,
|
|
61
|
+
baseThemeId: themeId,
|
|
62
|
+
colorScheme: selectedBaseTheme.colorScheme,
|
|
63
|
+
colorVariables: selectedBaseTheme.colorVariables
|
|
64
|
+
};
|
|
65
|
+
setTheme(updatedTheme);
|
|
66
|
+
setCustomTheme(updatedTheme);
|
|
67
|
+
}
|
|
55
68
|
};
|
|
56
69
|
const handleColorChange = (color, value)=>{
|
|
57
70
|
const updatedTheme = produce(theme, (draft)=>{
|
|
58
71
|
draft.colorVariables[color] = value;
|
|
59
72
|
});
|
|
60
73
|
setTheme(updatedTheme);
|
|
74
|
+
setCustomTheme(updatedTheme);
|
|
75
|
+
};
|
|
76
|
+
const handleSwapUpDown = ()=>{
|
|
77
|
+
const updatedTheme = produce(theme, (draft)=>{
|
|
78
|
+
const { bullish, bearish, candleUp, candleDown, candleWickUp, candleWickDown, candleBorderUp, candleBorderDown } = draft.colorVariables;
|
|
79
|
+
draft.colorVariables.bullish = bearish;
|
|
80
|
+
draft.colorVariables.bearish = bullish;
|
|
81
|
+
draft.colorVariables.candleUp = candleDown;
|
|
82
|
+
draft.colorVariables.candleDown = candleUp;
|
|
83
|
+
draft.colorVariables.candleWickUp = candleWickDown;
|
|
84
|
+
draft.colorVariables.candleWickDown = candleWickUp;
|
|
85
|
+
draft.colorVariables.candleBorderUp = candleBorderDown;
|
|
86
|
+
draft.colorVariables.candleBorderDown = candleBorderUp;
|
|
87
|
+
});
|
|
88
|
+
setTheme(updatedTheme);
|
|
89
|
+
setCustomTheme(updatedTheme);
|
|
61
90
|
};
|
|
62
91
|
const getColorValue = (color)=>theme.colorVariables[color] || baseTheme.colorVariables[color] || '#000000';
|
|
63
92
|
const renderColorItem = (color, label)=>{
|
|
@@ -82,12 +111,20 @@ const CustomThemeConfig = ()=>{
|
|
|
82
111
|
return /*#__PURE__*/ jsxs(VStack, {
|
|
83
112
|
gap: "lg",
|
|
84
113
|
children: [
|
|
85
|
-
/*#__PURE__*/
|
|
114
|
+
/*#__PURE__*/ jsxs(HStack, {
|
|
86
115
|
justify: "between",
|
|
87
|
-
children:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
116
|
+
children: [
|
|
117
|
+
/*#__PURE__*/ jsx(Text, {
|
|
118
|
+
body1Bold: true,
|
|
119
|
+
children: i18n.theme.custom.title
|
|
120
|
+
}),
|
|
121
|
+
/*#__PURE__*/ jsx(UXButton, {
|
|
122
|
+
variant: "text",
|
|
123
|
+
color: "primary",
|
|
124
|
+
onPress: handleSwapUpDown,
|
|
125
|
+
children: i18n.theme.custom.swapUpDown
|
|
126
|
+
})
|
|
127
|
+
]
|
|
91
128
|
}),
|
|
92
129
|
/*#__PURE__*/ jsxs(HStack, {
|
|
93
130
|
justify: "between",
|
|
@@ -120,7 +157,7 @@ const CustomThemeConfig = ()=>{
|
|
|
120
157
|
gap: "md",
|
|
121
158
|
className: "pt-md",
|
|
122
159
|
children: colors.map((color)=>{
|
|
123
|
-
const label = i18n.
|
|
160
|
+
const label = i18n.colors[color] || color;
|
|
124
161
|
return renderColorItem(color, label);
|
|
125
162
|
})
|
|
126
163
|
})
|
|
@@ -4,8 +4,11 @@ import { cn } from "@heroui/theme";
|
|
|
4
4
|
import { useLang } from "../../hooks/index.js";
|
|
5
5
|
import { VStack } from "../layout/index.js";
|
|
6
6
|
import { Text } from "../typography/Text.js";
|
|
7
|
+
import { useTheme } from "./use-theme.js";
|
|
7
8
|
const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
8
9
|
const { lang } = useLang();
|
|
10
|
+
const { customTheme } = useTheme();
|
|
11
|
+
const customColors = customTheme.colorVariables;
|
|
9
12
|
return /*#__PURE__*/ jsxs(VStack, {
|
|
10
13
|
gap: 2,
|
|
11
14
|
items: "center",
|
|
@@ -13,7 +16,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
13
16
|
onClick: onClick,
|
|
14
17
|
children: [
|
|
15
18
|
/*#__PURE__*/ jsx("div", {
|
|
16
|
-
className: cn('rounded-medium border-2 transition-all duration-300 hover:scale-105', 'h-[59px] w-[100px] md:h-[71px] md:w-[120px]', isSelected
|
|
19
|
+
className: cn('rounded-medium border-2 border-transparent transition-all duration-300 hover:scale-105', 'h-[59px] w-[100px] md:h-[71px] md:w-[120px]', isSelected && 'border-primary'),
|
|
20
|
+
style: {
|
|
21
|
+
borderColor: isSelected && 'custom' === id ? customColors.primary : void 0
|
|
22
|
+
},
|
|
17
23
|
children: /*#__PURE__*/ jsxs("svg", {
|
|
18
24
|
xmlns: "http://www.w3.org/2000/svg",
|
|
19
25
|
viewBox: "0 0 120 71",
|
|
@@ -27,7 +33,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
27
33
|
height: "67",
|
|
28
34
|
rx: "5",
|
|
29
35
|
fill: "currentColor",
|
|
30
|
-
className: "text-primary"
|
|
36
|
+
className: "text-primary",
|
|
37
|
+
style: {
|
|
38
|
+
color: 'custom' === id ? customColors.primary : void 0
|
|
39
|
+
}
|
|
31
40
|
}),
|
|
32
41
|
/*#__PURE__*/ jsx("mask", {
|
|
33
42
|
id: "mask0_40928_218196",
|
|
@@ -46,7 +55,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
46
55
|
height: "67",
|
|
47
56
|
rx: "5",
|
|
48
57
|
fill: "currentColor",
|
|
49
|
-
className: "text-background"
|
|
58
|
+
className: "text-background",
|
|
59
|
+
style: {
|
|
60
|
+
color: 'custom' === id ? customColors['bg-default'] : void 0
|
|
61
|
+
}
|
|
50
62
|
})
|
|
51
63
|
}),
|
|
52
64
|
/*#__PURE__*/ jsx("g", {
|
|
@@ -58,7 +70,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
58
70
|
height: "67",
|
|
59
71
|
rx: "6",
|
|
60
72
|
fill: "currentColor",
|
|
61
|
-
className: "text-background"
|
|
73
|
+
className: "text-background",
|
|
74
|
+
style: {
|
|
75
|
+
color: 'custom' === id ? customColors['bg-default'] : void 0
|
|
76
|
+
}
|
|
62
77
|
})
|
|
63
78
|
}),
|
|
64
79
|
/*#__PURE__*/ jsx("rect", {
|
|
@@ -67,7 +82,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
67
82
|
width: "100",
|
|
68
83
|
height: "1",
|
|
69
84
|
fill: "currentColor",
|
|
70
|
-
className: "text-divider"
|
|
85
|
+
className: "text-divider",
|
|
86
|
+
style: {
|
|
87
|
+
color: 'custom' === id ? customColors.divider : void 0
|
|
88
|
+
}
|
|
71
89
|
}),
|
|
72
90
|
/*#__PURE__*/ jsx("rect", {
|
|
73
91
|
x: "54.082",
|
|
@@ -76,7 +94,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
76
94
|
height: "6.01835",
|
|
77
95
|
rx: "3.00917",
|
|
78
96
|
fill: "currentColor",
|
|
79
|
-
className: "text-foreground"
|
|
97
|
+
className: "text-foreground",
|
|
98
|
+
style: {
|
|
99
|
+
color: 'custom' === id ? customColors.foreground : void 0
|
|
100
|
+
}
|
|
80
101
|
}),
|
|
81
102
|
/*#__PURE__*/ jsx("rect", {
|
|
82
103
|
x: "54.082",
|
|
@@ -85,7 +106,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
85
106
|
height: "6.01835",
|
|
86
107
|
rx: "3.00917",
|
|
87
108
|
fill: "currentColor",
|
|
88
|
-
className: "text-bullish"
|
|
109
|
+
className: "text-bullish",
|
|
110
|
+
style: {
|
|
111
|
+
color: 'custom' === id ? customColors.bullish : void 0
|
|
112
|
+
}
|
|
89
113
|
}),
|
|
90
114
|
/*#__PURE__*/ jsx("rect", {
|
|
91
115
|
x: "75.8994",
|
|
@@ -94,7 +118,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
94
118
|
height: "6.01835",
|
|
95
119
|
rx: "3.00917",
|
|
96
120
|
fill: "currentColor",
|
|
97
|
-
className: "text-bearish"
|
|
121
|
+
className: "text-bearish",
|
|
122
|
+
style: {
|
|
123
|
+
color: 'custom' === id ? customColors.bearish : void 0
|
|
124
|
+
}
|
|
98
125
|
}),
|
|
99
126
|
/*#__PURE__*/ jsx("rect", {
|
|
100
127
|
x: "86.4316",
|
|
@@ -103,7 +130,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
103
130
|
height: "6.01835",
|
|
104
131
|
rx: "3.00917",
|
|
105
132
|
fill: "currentColor",
|
|
106
|
-
className: "text-secondary"
|
|
133
|
+
className: "text-secondary",
|
|
134
|
+
style: {
|
|
135
|
+
color: 'custom' === id ? customColors.secondary : void 0
|
|
136
|
+
}
|
|
107
137
|
}),
|
|
108
138
|
/*#__PURE__*/ jsx("rect", {
|
|
109
139
|
x: "94.707",
|
|
@@ -112,7 +142,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
112
142
|
height: "6.01835",
|
|
113
143
|
rx: "3.00917",
|
|
114
144
|
fill: "currentColor",
|
|
115
|
-
className: "text-secondary"
|
|
145
|
+
className: "text-secondary",
|
|
146
|
+
style: {
|
|
147
|
+
color: 'custom' === id ? customColors.secondary : void 0
|
|
148
|
+
}
|
|
116
149
|
}),
|
|
117
150
|
/*#__PURE__*/ jsx("rect", {
|
|
118
151
|
x: "102.981",
|
|
@@ -121,7 +154,10 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
121
154
|
height: "6.01835",
|
|
122
155
|
rx: "3.00917",
|
|
123
156
|
fill: "currentColor",
|
|
124
|
-
className: "text-secondary"
|
|
157
|
+
className: "text-secondary",
|
|
158
|
+
style: {
|
|
159
|
+
color: 'custom' === id ? customColors.secondary : void 0
|
|
160
|
+
}
|
|
125
161
|
}),
|
|
126
162
|
'custom' === id ? /*#__PURE__*/ jsxs(Fragment, {
|
|
127
163
|
children: [
|
|
@@ -34,14 +34,15 @@ const FONT_EXAMPLES = [
|
|
|
34
34
|
];
|
|
35
35
|
const UXThemeSwitchModal = ({ as = 'modal', omitThemes = [], backdrop, isOpen, onClose, onOpenChange })=>{
|
|
36
36
|
const i18n = useI18n();
|
|
37
|
-
const { theme: selectedTheme, setTheme, fontUrl, setFontUrl, fontName, fontLoadStatus, clearFontUrl } = useTheme();
|
|
37
|
+
const { theme: selectedTheme, customTheme: savedCustomTheme, setTheme, fontUrl, setFontUrl, fontName, fontLoadStatus, clearFontUrl } = useTheme();
|
|
38
38
|
const [isFontExampleOpen, setIsFontExampleOpen] = useState(false);
|
|
39
39
|
const Component = 'modal' === as ? UXModal : UXDrawer;
|
|
40
40
|
const themes = useMemo(()=>themeData.filter((theme)=>!omitThemes.includes(theme.id)), [
|
|
41
41
|
omitThemes
|
|
42
42
|
]);
|
|
43
43
|
const handleThemeSelect = (theme)=>{
|
|
44
|
-
if ('custom' === theme.id
|
|
44
|
+
if ('custom' === theme.id) if (savedCustomTheme) setTheme(savedCustomTheme);
|
|
45
|
+
else {
|
|
45
46
|
const baseTheme = themeData.find((t)=>t.id === DEFAULT_THEME_ID) || themeData["0"];
|
|
46
47
|
const customTheme = {
|
|
47
48
|
...theme,
|
|
@@ -50,7 +51,8 @@ const UXThemeSwitchModal = ({ as = 'modal', omitThemes = [], backdrop, isOpen, o
|
|
|
50
51
|
colorVariables: baseTheme.colorVariables
|
|
51
52
|
};
|
|
52
53
|
setTheme(customTheme);
|
|
53
|
-
}
|
|
54
|
+
}
|
|
55
|
+
else setTheme(theme);
|
|
54
56
|
};
|
|
55
57
|
return /*#__PURE__*/ jsx(Component, {
|
|
56
58
|
isOpen: isOpen,
|
|
@@ -81,8 +83,7 @@ const UXThemeSwitchModal = ({ as = 'modal', omitThemes = [], backdrop, isOpen, o
|
|
|
81
83
|
'custom' === selectedTheme.id && /*#__PURE__*/ jsxs(Fragment, {
|
|
82
84
|
children: [
|
|
83
85
|
/*#__PURE__*/ jsx(UXDivider, {}),
|
|
84
|
-
/*#__PURE__*/ jsx(CustomThemeConfig, {})
|
|
85
|
-
/*#__PURE__*/ jsx(UXDivider, {})
|
|
86
|
+
/*#__PURE__*/ jsx(CustomThemeConfig, {})
|
|
86
87
|
]
|
|
87
88
|
}),
|
|
88
89
|
/*#__PURE__*/ jsx(UXDivider, {}),
|
|
@@ -1,22 +1 @@
|
|
|
1
|
-
export declare const useThemeColor: () =>
|
|
2
|
-
transparent: string;
|
|
3
|
-
white: string;
|
|
4
|
-
default: string;
|
|
5
|
-
alert: string;
|
|
6
|
-
success: string;
|
|
7
|
-
foreground: string;
|
|
8
|
-
secondary: string;
|
|
9
|
-
tertiary: string;
|
|
10
|
-
primary: string;
|
|
11
|
-
danger: string;
|
|
12
|
-
warning: string;
|
|
13
|
-
gold: string;
|
|
14
|
-
bullish: string;
|
|
15
|
-
bearish: string;
|
|
16
|
-
"bg-default": string;
|
|
17
|
-
"bg-300": string;
|
|
18
|
-
"bg-200": string;
|
|
19
|
-
"bg-400": string;
|
|
20
|
-
divider: string;
|
|
21
|
-
overlay: string;
|
|
22
|
-
};
|
|
1
|
+
export declare const useThemeColor: () => Record<import("@particle-network/ui-shared").ThemeColorVariable, string>;
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import { useMemo } from "react";
|
|
2
1
|
import { useThemeStore } from "./use-theme-store.js";
|
|
3
2
|
const useThemeColor = ()=>{
|
|
4
3
|
const { colorVariables } = useThemeStore((state)=>state.theme);
|
|
5
|
-
|
|
6
|
-
...colorVariables,
|
|
7
|
-
transparent: 'transparent',
|
|
8
|
-
white: '#FFFFFF'
|
|
9
|
-
}), [
|
|
10
|
-
colorVariables
|
|
11
|
-
]);
|
|
12
|
-
return themeColor;
|
|
4
|
+
return colorVariables;
|
|
13
5
|
};
|
|
14
6
|
export { useThemeColor };
|
|
@@ -5,6 +5,10 @@ interface State {
|
|
|
5
5
|
* 保存的主题
|
|
6
6
|
*/
|
|
7
7
|
theme: ThemeItemType;
|
|
8
|
+
/**
|
|
9
|
+
* 保存的自定义主题配置(当切换到其他主题时保存,切回 custom 时恢复)
|
|
10
|
+
*/
|
|
11
|
+
customTheme: ThemeItemType;
|
|
8
12
|
/**
|
|
9
13
|
* 保存的字体链接
|
|
10
14
|
*/
|
|
@@ -20,6 +24,7 @@ interface State {
|
|
|
20
24
|
}
|
|
21
25
|
interface Actions {
|
|
22
26
|
setTheme: (theme: ThemeItemType) => void;
|
|
27
|
+
setCustomTheme: (customTheme: ThemeItemType) => void;
|
|
23
28
|
setFontUrl: (fontUrl: string) => void;
|
|
24
29
|
setFontLoadStatus: (status: FontLoadStatus) => void;
|
|
25
30
|
setFontName: (name: string) => void;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CustomTheme, UXDarkTheme } from "@particle-network/ui-shared";
|
|
2
2
|
import { create } from "zustand";
|
|
3
3
|
import { createJSONStorage, persist } from "zustand/middleware";
|
|
4
4
|
const useThemeStore = create()(persist((set)=>({
|
|
5
|
-
theme:
|
|
5
|
+
theme: UXDarkTheme,
|
|
6
|
+
customTheme: CustomTheme,
|
|
6
7
|
fontUrl: '',
|
|
7
8
|
fontName: '',
|
|
8
9
|
fontLoadStatus: 'idle',
|
|
9
10
|
setTheme: (theme)=>set({
|
|
10
11
|
theme
|
|
11
12
|
}),
|
|
13
|
+
setCustomTheme: (customTheme)=>set({
|
|
14
|
+
customTheme
|
|
15
|
+
}),
|
|
12
16
|
setFontUrl: (fontUrl)=>set({
|
|
13
17
|
fontUrl
|
|
14
18
|
}),
|
|
@@ -19,11 +23,12 @@ const useThemeStore = create()(persist((set)=>({
|
|
|
19
23
|
fontName
|
|
20
24
|
})
|
|
21
25
|
}), {
|
|
22
|
-
name: 'ux-
|
|
23
|
-
version:
|
|
26
|
+
name: 'ux-preference-theme',
|
|
27
|
+
version: 0,
|
|
24
28
|
storage: createJSONStorage(()=>'undefined' != typeof window ? window.localStorage : {}),
|
|
25
29
|
partialize: (state)=>({
|
|
26
30
|
theme: state.theme,
|
|
31
|
+
customTheme: state.customTheme,
|
|
27
32
|
fontName: state.fontName,
|
|
28
33
|
fontUrl: state.fontUrl
|
|
29
34
|
})
|
|
@@ -4,7 +4,9 @@ import { type ThemeItemType } from '@particle-network/ui-shared';
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const useTheme: () => {
|
|
6
6
|
theme: ThemeItemType;
|
|
7
|
+
customTheme: ThemeItemType;
|
|
7
8
|
setTheme: (theme: ThemeItemType) => void;
|
|
9
|
+
setCustomTheme: (customTheme: ThemeItemType) => void;
|
|
8
10
|
fontUrl: string;
|
|
9
11
|
setFontUrl: (link: string) => void;
|
|
10
12
|
clearFontUrl: () => void;
|
|
@@ -1,88 +1,15 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
|
-
import { colorToCSSVariable, hexColorToHSLValue, themeKeys } from "@particle-network/ui-shared";
|
|
3
2
|
import { useDebounceFn } from "ahooks";
|
|
4
3
|
import { useThemeStore } from "./use-theme-store.js";
|
|
5
|
-
|
|
6
|
-
const PRELOAD_FONTS_URL = 'https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&display=swap';
|
|
7
|
-
const preloadFonts = ()=>{
|
|
8
|
-
if ('undefined' == typeof window) return;
|
|
9
|
-
const existingLink = document.getElementById('ux-preload-fonts-link');
|
|
10
|
-
if (existingLink) return;
|
|
11
|
-
const linkElement = document.createElement('link');
|
|
12
|
-
linkElement.id = 'ux-preload-fonts-link';
|
|
13
|
-
linkElement.rel = 'stylesheet';
|
|
14
|
-
linkElement.href = PRELOAD_FONTS_URL;
|
|
15
|
-
document.head.appendChild(linkElement);
|
|
16
|
-
};
|
|
17
|
-
const applyCustomThemeColors = (theme)=>{
|
|
18
|
-
if ('undefined' == typeof window) return;
|
|
19
|
-
const root = document.documentElement;
|
|
20
|
-
Object.entries(theme.colorVariables).forEach(([color, value])=>{
|
|
21
|
-
const cssVariable = colorToCSSVariable[color]?.self;
|
|
22
|
-
if (cssVariable) cssVariable.forEach((variable)=>{
|
|
23
|
-
root.style.setProperty(variable, hexColorToHSLValue(value));
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
const clearCustomThemeColors = ()=>{
|
|
28
|
-
if ('undefined' == typeof window) return;
|
|
29
|
-
const root = document.documentElement;
|
|
30
|
-
Object.values(colorToCSSVariable).forEach((cssVar)=>{
|
|
31
|
-
cssVar.self?.forEach((variable)=>{
|
|
32
|
-
root.style.removeProperty(variable);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
};
|
|
36
|
-
const applyTheme = (theme)=>{
|
|
37
|
-
if ('undefined' == typeof window) return;
|
|
38
|
-
const root = document.documentElement;
|
|
39
|
-
const isClassListCorrect = root.classList.contains(theme.id);
|
|
40
|
-
const isDataThemeCorrect = root.getAttribute('data-theme') === theme.colorScheme;
|
|
41
|
-
const isDataPrefersColorCorrect = root.getAttribute('data-prefers-color') === theme.colorScheme;
|
|
42
|
-
if ('custom' === theme.id) {
|
|
43
|
-
clearCustomThemeColors();
|
|
44
|
-
applyCustomThemeColors(theme);
|
|
45
|
-
} else clearCustomThemeColors();
|
|
46
|
-
if (isClassListCorrect && isDataThemeCorrect && isDataPrefersColorCorrect && 'custom' !== theme.id) return;
|
|
47
|
-
if (!isDataThemeCorrect) root.setAttribute('data-theme', theme.colorScheme);
|
|
48
|
-
if (!isDataPrefersColorCorrect) root.setAttribute('data-prefers-color', theme.colorScheme);
|
|
49
|
-
root.classList.remove('dark');
|
|
50
|
-
root.classList.remove('light');
|
|
51
|
-
if (!isClassListCorrect) {
|
|
52
|
-
themeKeys.forEach((key)=>{
|
|
53
|
-
root.classList.remove(key);
|
|
54
|
-
});
|
|
55
|
-
root.classList.add('custom' === theme.id ? theme.baseThemeId : theme.id);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
const extractFontFamilyFromLink = (link)=>{
|
|
59
|
-
if (!link) return null;
|
|
60
|
-
try {
|
|
61
|
-
const url = new URL(link);
|
|
62
|
-
const familyParam = url.searchParams.get('family');
|
|
63
|
-
if (!familyParam) return null;
|
|
64
|
-
const firstFamily = familyParam.split('&family=')[0].split(':')[0].replace(/\+/g, ' ');
|
|
65
|
-
return firstFamily;
|
|
66
|
-
} catch {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const applyFont = (fontName)=>{
|
|
71
|
-
if ('undefined' == typeof window) return;
|
|
72
|
-
if (fontName) {
|
|
73
|
-
document.documentElement.style.setProperty('--ux-font-family', `"${fontName}", ${DEFAULT_FONT_FAMILY}`);
|
|
74
|
-
document.body.style.fontFamily = `"${fontName}", ${DEFAULT_FONT_FAMILY}`;
|
|
75
|
-
} else {
|
|
76
|
-
document.documentElement.style.setProperty('--ux-font-family', DEFAULT_FONT_FAMILY);
|
|
77
|
-
document.body.style.fontFamily = DEFAULT_FONT_FAMILY;
|
|
78
|
-
}
|
|
79
|
-
};
|
|
4
|
+
import { applyFont, applyTheme, extractFontFamilyFromLink, preloadFonts } from "./utils.js";
|
|
80
5
|
const useTheme = ()=>{
|
|
81
6
|
const theme = useThemeStore((state)=>state.theme);
|
|
7
|
+
const customTheme = useThemeStore((state)=>state.customTheme);
|
|
82
8
|
const fontUrl = useThemeStore((state)=>state.fontUrl);
|
|
83
9
|
const fontName = useThemeStore((state)=>state.fontName);
|
|
84
10
|
const fontLoadStatus = useThemeStore((state)=>state.fontLoadStatus);
|
|
85
11
|
const storeSetTheme = useThemeStore((state)=>state.setTheme);
|
|
12
|
+
const storeSetCustomTheme = useThemeStore((state)=>state.setCustomTheme);
|
|
86
13
|
const storeSetFontUrl = useThemeStore((state)=>state.setFontUrl);
|
|
87
14
|
const storeSetFontLoadStatus = useThemeStore((state)=>state.setFontLoadStatus);
|
|
88
15
|
const storeSetFontName = useThemeStore((state)=>state.setFontName);
|
|
@@ -142,7 +69,9 @@ const useTheme = ()=>{
|
|
|
142
69
|
};
|
|
143
70
|
return {
|
|
144
71
|
theme,
|
|
72
|
+
customTheme,
|
|
145
73
|
setTheme,
|
|
74
|
+
setCustomTheme: storeSetCustomTheme,
|
|
146
75
|
fontUrl,
|
|
147
76
|
setFontUrl,
|
|
148
77
|
clearFontUrl,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ThemeItemType } from '@particle-network/ui-shared';
|
|
2
|
+
/**
|
|
3
|
+
* 初始化并预加载字体 CSS(仅执行一次)
|
|
4
|
+
*/
|
|
5
|
+
export declare const preloadFonts: () => void;
|
|
6
|
+
export declare const setCSSProperty: (property: string, value: string) => void;
|
|
7
|
+
/**
|
|
8
|
+
* 应用自定义主题的颜色到 CSS 变量
|
|
9
|
+
*/
|
|
10
|
+
export declare const applyCustomThemeColors: (theme: ThemeItemType) => void;
|
|
11
|
+
/**
|
|
12
|
+
* 清除自定义主题的 CSS 变量(切换到其他主题时)
|
|
13
|
+
*/
|
|
14
|
+
export declare const clearCustomThemeColors: () => void;
|
|
15
|
+
/**
|
|
16
|
+
* 应用主题到文档根元素
|
|
17
|
+
*/
|
|
18
|
+
export declare const applyTheme: (theme: ThemeItemType) => void;
|
|
19
|
+
/**
|
|
20
|
+
* 从 Google Fonts 链接中提取字体名称
|
|
21
|
+
* 例如: https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap
|
|
22
|
+
* 提取: Roboto
|
|
23
|
+
*/
|
|
24
|
+
export declare const extractFontFamilyFromLink: (link: string) => string | null;
|
|
25
|
+
/**
|
|
26
|
+
* 应用字体到 DOM
|
|
27
|
+
*/
|
|
28
|
+
export declare const applyFont: (fontName: string | undefined) => void;
|