@particle-network/ui-react 0.4.0-beta.24 → 0.4.0-beta.25
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/UXInput/index.d.ts +2 -2
- package/dist/components/UXInput/input.extend.d.ts +2 -2
- package/dist/components/UXModal/index.d.ts +1 -1
- package/dist/components/UXModal/index.js +3 -4
- package/dist/components/UXSwitch/index.d.ts +1 -1
- package/dist/components/UXSwitch/switch.extend.d.ts +1 -1
- package/dist/components/UXTable/index.d.ts +1 -1
- package/dist/components/UXTable/table.extend.d.ts +1 -1
- package/dist/components/UXThemeSwitch/theme-item.js +3 -4
- package/dist/components/UXThemeSwitch/theme-switch.d.ts +3 -3
- package/dist/components/UXThemeSwitch/theme-switch.js +132 -87
- package/dist/components/UXThemeSwitch/use-color-scheme.js +3 -3
- package/dist/components/UXThemeSwitch/use-theme-color.js +3 -3
- package/dist/components/UXThemeSwitch/use-theme-store.d.ts +4 -14
- package/dist/components/UXThemeSwitch/use-theme-store.js +13 -23
- package/dist/components/UXThemeSwitch/use-theme.d.ts +5 -8
- package/dist/components/UXThemeSwitch/use-theme.js +27 -49
- package/dist/hooks/useI18n.d.ts +6 -2
- package/dist/hooks/useI18n.js +15 -7
- package/dist/utils/detect.js +1 -2
- package/package.json +3 -3
|
@@ -288,6 +288,7 @@ export declare const UXInput: React.ForwardRefExoticComponent<Omit<Omit<{
|
|
|
288
288
|
list?: string | undefined;
|
|
289
289
|
step?: string | number | undefined;
|
|
290
290
|
size?: "sm" | "md" | "lg" | undefined;
|
|
291
|
+
label?: React.ReactNode;
|
|
291
292
|
value?: string | (readonly string[] & string) | undefined;
|
|
292
293
|
width?: string | number | undefined;
|
|
293
294
|
height?: string | number | undefined;
|
|
@@ -296,7 +297,7 @@ export declare const UXInput: React.ForwardRefExoticComponent<Omit<Omit<{
|
|
|
296
297
|
disabled?: boolean | undefined;
|
|
297
298
|
variant?: "flat" | "bordered" | "faded" | "underlined" | undefined;
|
|
298
299
|
isClearable?: boolean | undefined;
|
|
299
|
-
classNames?: import("@heroui/theme").SlotsToClasses<"
|
|
300
|
+
classNames?: import("@heroui/theme").SlotsToClasses<"base" | "input" | "label" | "description" | "errorMessage" | "clearButton" | "mainWrapper" | "inputWrapper" | "innerWrapper" | "helperWrapper"> | undefined;
|
|
300
301
|
isDisabled?: boolean | undefined;
|
|
301
302
|
isReadOnly?: boolean | undefined;
|
|
302
303
|
isRequired?: boolean | undefined;
|
|
@@ -308,7 +309,6 @@ export declare const UXInput: React.ForwardRefExoticComponent<Omit<Omit<{
|
|
|
308
309
|
errorMessage?: React.ReactNode | ((v: import("@react-types/shared").ValidationResult) => React.ReactNode);
|
|
309
310
|
onFocusChange?: ((isFocused: boolean) => void) | undefined;
|
|
310
311
|
placeholder?: string | undefined;
|
|
311
|
-
label?: React.ReactNode;
|
|
312
312
|
excludeFromTabOrder?: boolean | undefined;
|
|
313
313
|
autoComplete?: string | undefined;
|
|
314
314
|
maxLength?: number | undefined;
|
|
@@ -285,6 +285,7 @@ declare const ExtendedInput: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
285
285
|
list?: string | undefined;
|
|
286
286
|
step?: string | number | undefined;
|
|
287
287
|
size?: "sm" | "md" | "lg" | undefined;
|
|
288
|
+
label?: import("react").ReactNode;
|
|
288
289
|
value?: string | (readonly string[] & string) | undefined;
|
|
289
290
|
width?: string | number | undefined;
|
|
290
291
|
height?: string | number | undefined;
|
|
@@ -293,7 +294,7 @@ declare const ExtendedInput: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
293
294
|
disabled?: boolean | undefined;
|
|
294
295
|
variant?: "flat" | "bordered" | "faded" | "underlined" | undefined;
|
|
295
296
|
isClearable?: boolean | undefined;
|
|
296
|
-
classNames?: import("@heroui/theme").SlotsToClasses<"
|
|
297
|
+
classNames?: import("@heroui/theme").SlotsToClasses<"base" | "input" | "label" | "description" | "errorMessage" | "clearButton" | "mainWrapper" | "inputWrapper" | "innerWrapper" | "helperWrapper"> | undefined;
|
|
297
298
|
isDisabled?: boolean | undefined;
|
|
298
299
|
isReadOnly?: boolean | undefined;
|
|
299
300
|
isRequired?: boolean | undefined;
|
|
@@ -305,7 +306,6 @@ declare const ExtendedInput: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
305
306
|
errorMessage?: import("react").ReactNode | ((v: import("@react-types/shared").ValidationResult) => import("react").ReactNode);
|
|
306
307
|
onFocusChange?: ((isFocused: boolean) => void) | undefined;
|
|
307
308
|
placeholder?: string | undefined;
|
|
308
|
-
label?: import("react").ReactNode;
|
|
309
309
|
excludeFromTabOrder?: boolean | undefined;
|
|
310
310
|
autoComplete?: string | undefined;
|
|
311
311
|
maxLength?: number | undefined;
|
|
@@ -6,4 +6,4 @@ export type UXModalProps = Omit<ModalProps, 'closeButton'> & {
|
|
|
6
6
|
tip?: React.ReactNode;
|
|
7
7
|
titleAlign?: 'left' | 'center';
|
|
8
8
|
};
|
|
9
|
-
export declare const UXModal: React.
|
|
9
|
+
export declare const UXModal: React.FC<UXModalProps>;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import "react";
|
|
3
3
|
import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader } from "@heroui/modal";
|
|
4
4
|
import CloseIcon from "@particle-network/icons/web/CloseIcon";
|
|
5
5
|
import { Center, Circle, Flex } from "../layout/index.js";
|
|
6
6
|
import { Text } from "../typography/Text.js";
|
|
7
7
|
import { UXButton } from "../UXButton/index.js";
|
|
8
|
-
const UXModal =
|
|
8
|
+
const UXModal = (props)=>{
|
|
9
9
|
const { title, footer, backdrop, scrollBehavior = 'inside', children, titleAlign = 'left', classNames, tip, ...restProps } = props;
|
|
10
10
|
return /*#__PURE__*/ jsx(Modal, {
|
|
11
|
-
ref: ref,
|
|
12
11
|
backdrop: backdrop,
|
|
13
12
|
scrollBehavior: scrollBehavior,
|
|
14
13
|
classNames: {
|
|
@@ -88,6 +87,6 @@ const UXModal = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
88
87
|
]
|
|
89
88
|
})
|
|
90
89
|
});
|
|
91
|
-
}
|
|
90
|
+
};
|
|
92
91
|
UXModal.displayName = 'UX.Modal';
|
|
93
92
|
export { UXModal };
|
|
@@ -292,7 +292,7 @@ export declare const UXSwitch: React.ForwardRefExoticComponent<Omit<Omit<{
|
|
|
292
292
|
height?: string | number | undefined;
|
|
293
293
|
multiple?: boolean | undefined;
|
|
294
294
|
disabled?: boolean | undefined;
|
|
295
|
-
classNames?: import("@heroui/theme").SlotsToClasses<"
|
|
295
|
+
classNames?: import("@heroui/theme").SlotsToClasses<"base" | "label" | "startContent" | "endContent" | "wrapper" | "hiddenInput" | "thumb" | "thumbIcon"> | undefined;
|
|
296
296
|
isDisabled?: boolean | undefined;
|
|
297
297
|
isReadOnly?: boolean | undefined;
|
|
298
298
|
onFocusChange?: ((isFocused: boolean) => void) | undefined;
|
|
@@ -289,7 +289,7 @@ declare const ExtendedSwitch: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
289
289
|
height?: string | number | undefined;
|
|
290
290
|
multiple?: boolean | undefined;
|
|
291
291
|
disabled?: boolean | undefined;
|
|
292
|
-
classNames?: import("@heroui/theme").SlotsToClasses<"
|
|
292
|
+
classNames?: import("@heroui/theme").SlotsToClasses<"base" | "label" | "startContent" | "endContent" | "wrapper" | "hiddenInput" | "thumb" | "thumbIcon"> | undefined;
|
|
293
293
|
isDisabled?: boolean | undefined;
|
|
294
294
|
isReadOnly?: boolean | undefined;
|
|
295
295
|
onFocusChange?: ((isFocused: boolean) => void) | undefined;
|
|
@@ -286,13 +286,13 @@ export declare const UXTable: import("@heroui/system-rsc").InternalForwardRefRen
|
|
|
286
286
|
onTransitionStartCapture?: React.TransitionEventHandler<HTMLTableElement> | undefined;
|
|
287
287
|
align?: "start" | "end" | "center" | undefined;
|
|
288
288
|
size?: "md" | "lg" | undefined;
|
|
289
|
+
summary?: string | undefined;
|
|
289
290
|
width?: string | number | undefined;
|
|
290
291
|
radius?: "sm" | "md" | "lg" | "none" | undefined;
|
|
291
292
|
layout?: "auto" | "fixed" | undefined;
|
|
292
293
|
border?: number | undefined;
|
|
293
294
|
classNames?: import("@heroui/theme").SlotsToClasses<"table" | "base" | "tbody" | "td" | "tfoot" | "th" | "thead" | "tr" | "wrapper" | "sortIcon" | "emptyWrapper" | "loadingWrapper"> | undefined;
|
|
294
295
|
disableAnimation?: boolean | undefined;
|
|
295
|
-
summary?: string | undefined;
|
|
296
296
|
as?: import("@heroui/system-rsc").As<any> | undefined;
|
|
297
297
|
key?: React.Key | null | undefined;
|
|
298
298
|
baseRef?: import("@heroui/react-utils").ReactRef<HTMLElement | null> | undefined;
|
|
@@ -283,13 +283,13 @@ declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
283
283
|
onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLTableElement> | undefined;
|
|
284
284
|
align?: "start" | "end" | "center" | undefined;
|
|
285
285
|
size?: "md" | "lg" | undefined;
|
|
286
|
+
summary?: string | undefined;
|
|
286
287
|
width?: string | number | undefined;
|
|
287
288
|
radius?: "sm" | "md" | "lg" | "none" | undefined;
|
|
288
289
|
layout?: "auto" | "fixed" | undefined;
|
|
289
290
|
border?: number | undefined;
|
|
290
291
|
classNames?: import("@heroui/theme").SlotsToClasses<"table" | "base" | "tbody" | "td" | "tfoot" | "th" | "thead" | "tr" | "wrapper" | "sortIcon" | "emptyWrapper" | "loadingWrapper"> | undefined;
|
|
291
292
|
disableAnimation?: boolean | undefined;
|
|
292
|
-
summary?: string | undefined;
|
|
293
293
|
as?: import("@heroui/system-rsc").As<any> | undefined;
|
|
294
294
|
key?: import("react").Key | null | undefined;
|
|
295
295
|
baseRef?: import("@heroui/react-utils").ReactRef<HTMLElement | null> | undefined;
|
|
@@ -7,17 +7,15 @@ import { Text } from "../typography/Text.js";
|
|
|
7
7
|
const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
8
8
|
const lang = useLang();
|
|
9
9
|
return /*#__PURE__*/ jsxs(VStack, {
|
|
10
|
-
center: true,
|
|
11
10
|
gap: 2,
|
|
11
|
+
items: "center",
|
|
12
12
|
className: cn('cursor-pointer', id),
|
|
13
13
|
onClick: onClick,
|
|
14
14
|
children: [
|
|
15
15
|
/*#__PURE__*/ jsx("div", {
|
|
16
|
-
className: cn('rounded-medium border-2 hover:scale-105 transition-all duration-300', isSelected ? 'border-primary' : 'border-transparent'),
|
|
16
|
+
className: cn('rounded-medium border-2 hover:scale-105 transition-all duration-300', 'w-[100px] h-[59px] md:w-[120px] md:h-[71px]', isSelected ? 'border-primary' : 'border-transparent'),
|
|
17
17
|
children: /*#__PURE__*/ jsxs("svg", {
|
|
18
18
|
xmlns: "http://www.w3.org/2000/svg",
|
|
19
|
-
width: "120",
|
|
20
|
-
height: "71",
|
|
21
19
|
viewBox: "0 0 120 71",
|
|
22
20
|
fill: "none",
|
|
23
21
|
children: [
|
|
@@ -138,6 +136,7 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
138
136
|
})
|
|
139
137
|
}),
|
|
140
138
|
/*#__PURE__*/ jsx(Text, {
|
|
139
|
+
align: "center",
|
|
141
140
|
children: 'zh' === lang ? zhName : enName
|
|
142
141
|
})
|
|
143
142
|
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type
|
|
3
|
-
export type
|
|
4
|
-
export declare const
|
|
2
|
+
import { type UXModalProps } from '../UXModal';
|
|
3
|
+
export type UXThemeSwitchModalProps = Omit<UXModalProps, 'children'>;
|
|
4
|
+
export declare const UXThemeSwitchModal: React.FC<UXThemeSwitchModalProps>;
|
|
5
5
|
export interface UXThemeSwitchProps {
|
|
6
6
|
children?: (onOpen: () => void) => React.ReactNode;
|
|
7
7
|
}
|
|
@@ -1,113 +1,158 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { cn } from "@heroui/theme";
|
|
3
4
|
import { useDisclosure } from "@heroui/use-disclosure";
|
|
4
|
-
import { ChartColorSwitchIcon } from "@particle-network/icons/web";
|
|
5
|
+
import { ChartColorSwitchIcon, CopyIcon } from "@particle-network/icons/web";
|
|
5
6
|
import { themeData } from "@particle-network/ui-shared";
|
|
6
7
|
import { useI18n } from "../../hooks/index.js";
|
|
8
|
+
import { UXCopy, UXTooltip } from "../index.js";
|
|
7
9
|
import { HStack, VStack } from "../layout/index.js";
|
|
8
10
|
import { Text } from "../typography/Text.js";
|
|
9
11
|
import { UXButton } from "../UXButton/index.js";
|
|
10
12
|
import { UXDivider } from "../UXDivider/index.js";
|
|
11
|
-
import { UXDrawer } from "../UXDrawer/index.js";
|
|
12
13
|
import { UXInput } from "../UXInput/index.js";
|
|
14
|
+
import { UXModal } from "../UXModal/index.js";
|
|
13
15
|
import { UXSpinner } from "../UXSpinner/index.js";
|
|
14
16
|
import { ThemeItem } from "./theme-item.js";
|
|
15
17
|
import { useTheme } from "./use-theme.js";
|
|
16
|
-
const
|
|
18
|
+
const FONT_EXAMPLES = [
|
|
19
|
+
{
|
|
20
|
+
title: 'Manrope',
|
|
21
|
+
url: 'https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
title: 'Poppins',
|
|
25
|
+
url: 'https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
title: 'Roboto',
|
|
29
|
+
url: 'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
const UXThemeSwitchModal = ({ isOpen, onClose, onOpenChange, ...props })=>{
|
|
17
33
|
const i18n = useI18n();
|
|
18
|
-
const { selectedTheme,
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
if (!_isOpen) {
|
|
22
|
-
setSelectedTheme(savedTheme);
|
|
23
|
-
setSelectedFontLink(savedFontLink);
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
const handleApplyTheme = ()=>{
|
|
27
|
-
setSavedTheme(selectedTheme);
|
|
28
|
-
setSavedFontLink(selectedFontLink);
|
|
29
|
-
onClose?.();
|
|
30
|
-
};
|
|
31
|
-
const handleReset = ()=>{
|
|
32
|
-
setSelectedTheme(savedTheme);
|
|
33
|
-
setSelectedFontLink(savedFontLink);
|
|
34
|
-
};
|
|
35
|
-
return /*#__PURE__*/ jsxs(UXDrawer, {
|
|
34
|
+
const { theme: selectedTheme, setTheme, fontUrl, setFontUrl, fontName, fontLoadStatus, clearFontUrl } = useTheme();
|
|
35
|
+
const [isFontExampleOpen, setIsFontExampleOpen] = useState(false);
|
|
36
|
+
return /*#__PURE__*/ jsx(UXModal, {
|
|
36
37
|
isOpen: isOpen,
|
|
37
|
-
backdrop: "transparent",
|
|
38
38
|
title: i18n.theme.title,
|
|
39
|
-
footer: /*#__PURE__*/
|
|
39
|
+
footer: /*#__PURE__*/ jsx(UXButton, {
|
|
40
40
|
fullWidth: true,
|
|
41
|
+
size: "lg",
|
|
42
|
+
color: "primary",
|
|
43
|
+
onPress: onClose,
|
|
44
|
+
children: i18n.theme.done
|
|
45
|
+
}),
|
|
46
|
+
onOpenChange: onOpenChange,
|
|
47
|
+
...props,
|
|
48
|
+
children: /*#__PURE__*/ jsxs(VStack, {
|
|
41
49
|
gap: "lg",
|
|
42
50
|
children: [
|
|
43
|
-
/*#__PURE__*/ jsx(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
/*#__PURE__*/ jsx("div", {
|
|
52
|
+
className: "grid grid-cols-3 gap-y-5 pt-1",
|
|
53
|
+
children: themeData.map((theme)=>/*#__PURE__*/ jsx(ThemeItem, {
|
|
54
|
+
isSelected: selectedTheme.id === theme.id,
|
|
55
|
+
onClick: ()=>setTheme(theme),
|
|
56
|
+
...theme
|
|
57
|
+
}, theme.id))
|
|
58
|
+
}),
|
|
59
|
+
/*#__PURE__*/ jsx(UXDivider, {}),
|
|
60
|
+
/*#__PURE__*/ jsxs(VStack, {
|
|
61
|
+
gap: "md",
|
|
62
|
+
children: [
|
|
63
|
+
/*#__PURE__*/ jsx(Text, {
|
|
64
|
+
body1Bold: true,
|
|
65
|
+
children: i18n.theme.font.title
|
|
66
|
+
}),
|
|
67
|
+
/*#__PURE__*/ jsx(UXInput, {
|
|
68
|
+
isClearable: true,
|
|
69
|
+
startContent: 'loading' === fontLoadStatus && /*#__PURE__*/ jsx(UXSpinner, {
|
|
70
|
+
size: 18
|
|
71
|
+
}),
|
|
72
|
+
isInvalid: 'error' === fontLoadStatus,
|
|
73
|
+
className: "w-full",
|
|
74
|
+
placeholder: i18n.theme.font.placeholder,
|
|
75
|
+
value: fontUrl,
|
|
76
|
+
description: /*#__PURE__*/ jsxs(Fragment, {
|
|
77
|
+
children: [
|
|
78
|
+
'success' === fontLoadStatus && /*#__PURE__*/ jsxs(Text, {
|
|
79
|
+
body3Bold: true,
|
|
80
|
+
color: "success",
|
|
81
|
+
children: [
|
|
82
|
+
i18n.theme.font.success,
|
|
83
|
+
fontName
|
|
84
|
+
]
|
|
85
|
+
}),
|
|
86
|
+
'error' === fontLoadStatus && /*#__PURE__*/ jsx(Text, {
|
|
87
|
+
body3Bold: true,
|
|
88
|
+
color: "danger",
|
|
89
|
+
children: i18n.theme.font.error
|
|
90
|
+
})
|
|
91
|
+
]
|
|
92
|
+
}),
|
|
93
|
+
onValueChange: setFontUrl,
|
|
94
|
+
onClear: clearFontUrl
|
|
95
|
+
})
|
|
96
|
+
]
|
|
97
|
+
}),
|
|
98
|
+
/*#__PURE__*/ jsxs(Text, {
|
|
99
|
+
color: "secondary",
|
|
100
|
+
children: [
|
|
101
|
+
i18n.theme.font.hint,
|
|
102
|
+
/*#__PURE__*/ jsx("a", {
|
|
103
|
+
href: "https://fonts.google.com/",
|
|
104
|
+
target: "_blank",
|
|
105
|
+
rel: "noopener noreferrer",
|
|
106
|
+
className: "hover:underline",
|
|
107
|
+
children: "https://fonts.google.com/"
|
|
108
|
+
})
|
|
109
|
+
]
|
|
48
110
|
}),
|
|
49
111
|
/*#__PURE__*/ jsx(UXButton, {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
size: "lg",
|
|
112
|
+
className: "self-start",
|
|
113
|
+
variant: "text",
|
|
53
114
|
color: "primary",
|
|
54
|
-
onPress:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
children: themeData.map((theme)=>/*#__PURE__*/ jsx(ThemeItem, {
|
|
65
|
-
isSelected: selectedTheme.id === theme.id,
|
|
66
|
-
onClick: ()=>setSelectedTheme(theme),
|
|
67
|
-
...theme
|
|
68
|
-
}, theme.id))
|
|
69
|
-
}),
|
|
70
|
-
/*#__PURE__*/ jsx(UXDivider, {
|
|
71
|
-
className: "my-lg"
|
|
72
|
-
}),
|
|
73
|
-
/*#__PURE__*/ jsxs(VStack, {
|
|
74
|
-
gap: "md",
|
|
75
|
-
children: [
|
|
76
|
-
/*#__PURE__*/ jsx(Text, {
|
|
77
|
-
body1Bold: true,
|
|
78
|
-
children: i18n.theme.font.title
|
|
79
|
-
}),
|
|
80
|
-
/*#__PURE__*/ jsx(UXInput, {
|
|
81
|
-
isClearable: true,
|
|
82
|
-
startContent: 'loading' === fontLoadStatus && /*#__PURE__*/ jsx(UXSpinner, {
|
|
83
|
-
size: 18
|
|
84
|
-
}),
|
|
85
|
-
isInvalid: 'error' === fontLoadStatus,
|
|
86
|
-
className: "w-full",
|
|
87
|
-
placeholder: i18n.theme.font.placeholder,
|
|
88
|
-
value: selectedFontLink,
|
|
89
|
-
description: /*#__PURE__*/ jsxs(Fragment, {
|
|
115
|
+
onPress: ()=>{
|
|
116
|
+
setIsFontExampleOpen((prev)=>!prev);
|
|
117
|
+
},
|
|
118
|
+
children: i18n.theme.font.example[isFontExampleOpen ? 'hide' : 'show']
|
|
119
|
+
}),
|
|
120
|
+
/*#__PURE__*/ jsx(VStack, {
|
|
121
|
+
gap: "sm",
|
|
122
|
+
className: cn(isFontExampleOpen ? 'flex' : 'hidden'),
|
|
123
|
+
children: FONT_EXAMPLES.map((example)=>/*#__PURE__*/ jsxs(HStack, {
|
|
124
|
+
gap: "lg",
|
|
90
125
|
children: [
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
children:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
126
|
+
/*#__PURE__*/ jsx(UXTooltip, {
|
|
127
|
+
content: example.url,
|
|
128
|
+
placement: "bottom",
|
|
129
|
+
children: /*#__PURE__*/ jsxs(Text, {
|
|
130
|
+
color: "secondary",
|
|
131
|
+
className: "flex-1 truncate cursor-pointer",
|
|
132
|
+
children: [
|
|
133
|
+
example.title,
|
|
134
|
+
": ",
|
|
135
|
+
example.url
|
|
136
|
+
]
|
|
137
|
+
})
|
|
98
138
|
}),
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
children:
|
|
139
|
+
/*#__PURE__*/ jsx(UXCopy, {
|
|
140
|
+
copyText: example.url,
|
|
141
|
+
toastText: example.url,
|
|
142
|
+
children: /*#__PURE__*/ jsx(UXButton, {
|
|
143
|
+
isIconOnly: true,
|
|
144
|
+
size: "sm",
|
|
145
|
+
variant: "light",
|
|
146
|
+
children: /*#__PURE__*/ jsx(CopyIcon, {
|
|
147
|
+
color: "secondary"
|
|
148
|
+
})
|
|
149
|
+
})
|
|
103
150
|
})
|
|
104
151
|
]
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
})
|
|
110
|
-
]
|
|
152
|
+
}, example.title))
|
|
153
|
+
})
|
|
154
|
+
]
|
|
155
|
+
})
|
|
111
156
|
});
|
|
112
157
|
};
|
|
113
158
|
const UXThemeSwitch = ({ children })=>{
|
|
@@ -124,7 +169,7 @@ const UXThemeSwitch = ({ children })=>{
|
|
|
124
169
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
125
170
|
children: [
|
|
126
171
|
renderChildren(),
|
|
127
|
-
/*#__PURE__*/ jsx(
|
|
172
|
+
/*#__PURE__*/ jsx(UXThemeSwitchModal, {
|
|
128
173
|
isOpen: isOpen,
|
|
129
174
|
onClose: onClose,
|
|
130
175
|
onOpenChange: onOpenChange
|
|
@@ -132,4 +177,4 @@ const UXThemeSwitch = ({ children })=>{
|
|
|
132
177
|
]
|
|
133
178
|
});
|
|
134
179
|
};
|
|
135
|
-
export { UXThemeSwitch,
|
|
180
|
+
export { UXThemeSwitch, UXThemeSwitchModal };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useTheme } from "./use-theme.js";
|
|
2
2
|
const useColorScheme = ()=>{
|
|
3
|
-
const {
|
|
4
|
-
const { colorScheme } =
|
|
3
|
+
const { theme } = useTheme();
|
|
4
|
+
const { colorScheme } = theme;
|
|
5
5
|
return {
|
|
6
6
|
colorScheme,
|
|
7
7
|
isDark: 'dark' === colorScheme,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useTheme } from "./use-theme.js";
|
|
2
2
|
const useThemeColor = ()=>{
|
|
3
|
-
const {
|
|
4
|
-
return
|
|
3
|
+
const { theme } = useTheme();
|
|
4
|
+
return theme.colorVariables;
|
|
5
5
|
};
|
|
6
6
|
export { useThemeColor };
|
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
import { type ThemeItemType } from '@particle-network/ui-shared';
|
|
2
2
|
export type FontLoadStatus = 'idle' | 'loading' | 'success' | 'error';
|
|
3
3
|
interface State {
|
|
4
|
-
/**
|
|
5
|
-
* 临时选中的 theme(用于预览)
|
|
6
|
-
*/
|
|
7
|
-
selectedTheme: ThemeItemType;
|
|
8
4
|
/**
|
|
9
5
|
* 保存的主题
|
|
10
6
|
*/
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 临时输入的字体链接(用于预览)
|
|
14
|
-
*/
|
|
15
|
-
selectedFontLink: string;
|
|
7
|
+
theme: ThemeItemType;
|
|
16
8
|
/**
|
|
17
9
|
* 保存的字体链接
|
|
18
10
|
*/
|
|
19
|
-
|
|
11
|
+
fontUrl: string;
|
|
20
12
|
/**
|
|
21
13
|
* 应用的字体名称
|
|
22
14
|
*/
|
|
@@ -27,10 +19,8 @@ interface State {
|
|
|
27
19
|
fontLoadStatus: FontLoadStatus;
|
|
28
20
|
}
|
|
29
21
|
interface Actions {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
setSelectedFontLink: (link: string) => void;
|
|
33
|
-
setSavedFontLink: (link: string) => void;
|
|
22
|
+
setTheme: (theme: ThemeItemType) => void;
|
|
23
|
+
setFontUrl: (fontUrl: string) => void;
|
|
34
24
|
setFontLoadStatus: (status: FontLoadStatus) => void;
|
|
35
25
|
setFontName: (name: string) => void;
|
|
36
26
|
}
|
|
@@ -2,39 +2,29 @@ import { themeData } 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
|
-
|
|
6
|
-
|
|
7
|
-
selectedFontLink: '',
|
|
8
|
-
savedFontLink: '',
|
|
5
|
+
theme: themeData["0"],
|
|
6
|
+
fontUrl: '',
|
|
9
7
|
fontName: '',
|
|
10
8
|
fontLoadStatus: 'idle',
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
setTheme: (theme)=>set({
|
|
10
|
+
theme
|
|
13
11
|
}),
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
setFontUrl: (fontUrl)=>set({
|
|
13
|
+
fontUrl
|
|
16
14
|
}),
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
setFontLoadStatus: (fontLoadStatus)=>set({
|
|
16
|
+
fontLoadStatus
|
|
19
17
|
}),
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}),
|
|
23
|
-
setFontLoadStatus: (status)=>set({
|
|
24
|
-
fontLoadStatus: status
|
|
25
|
-
}),
|
|
26
|
-
setFontName: (name)=>set({
|
|
27
|
-
fontName: name
|
|
18
|
+
setFontName: (fontName)=>set({
|
|
19
|
+
fontName
|
|
28
20
|
})
|
|
29
21
|
}), {
|
|
30
|
-
name: 'ux-theme-
|
|
22
|
+
name: 'ux-theme-2',
|
|
31
23
|
storage: createJSONStorage(()=>'undefined' != typeof window ? window.localStorage : {}),
|
|
32
24
|
partialize: (state)=>({
|
|
33
|
-
|
|
34
|
-
savedTheme: state.savedTheme,
|
|
25
|
+
theme: state.theme,
|
|
35
26
|
fontName: state.fontName,
|
|
36
|
-
|
|
37
|
-
savedFontLink: state.savedFontLink
|
|
27
|
+
fontUrl: state.fontUrl
|
|
38
28
|
})
|
|
39
29
|
}));
|
|
40
30
|
export { useThemeStore };
|
|
@@ -3,14 +3,11 @@ import { type ThemeItemType } from '@particle-network/ui-shared';
|
|
|
3
3
|
* UX 主题管理 Hook
|
|
4
4
|
*/
|
|
5
5
|
export declare const useTheme: () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
setSelectedFontLink: (link: string) => void;
|
|
12
|
-
savedFontLink: string;
|
|
13
|
-
setSavedFontLink: (link: string) => void;
|
|
6
|
+
theme: ThemeItemType;
|
|
7
|
+
setTheme: (theme: ThemeItemType) => void;
|
|
8
|
+
fontUrl: string;
|
|
9
|
+
setFontUrl: (link: string) => void;
|
|
10
|
+
clearFontUrl: () => void;
|
|
14
11
|
fontLoadStatus: import("./use-theme-store").FontLoadStatus;
|
|
15
12
|
fontName: string;
|
|
16
13
|
};
|
|
@@ -49,32 +49,28 @@ const applyFont = (fontName)=>{
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
const useTheme = ()=>{
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const selectedFontLink = useThemeStore((state)=>state.selectedFontLink);
|
|
55
|
-
const savedFontLink = useThemeStore((state)=>state.savedFontLink);
|
|
52
|
+
const theme = useThemeStore((state)=>state.theme);
|
|
53
|
+
const fontUrl = useThemeStore((state)=>state.fontUrl);
|
|
56
54
|
const fontName = useThemeStore((state)=>state.fontName);
|
|
57
55
|
const fontLoadStatus = useThemeStore((state)=>state.fontLoadStatus);
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
const storeSetSelectedFontLink = useThemeStore((state)=>state.setSelectedFontLink);
|
|
61
|
-
const storeSetSavedFontLink = useThemeStore((state)=>state.setSavedFontLink);
|
|
56
|
+
const storeSetTheme = useThemeStore((state)=>state.setTheme);
|
|
57
|
+
const storeSetFontUrl = useThemeStore((state)=>state.setFontUrl);
|
|
62
58
|
const storeSetFontLoadStatus = useThemeStore((state)=>state.setFontLoadStatus);
|
|
63
59
|
const storeSetFontName = useThemeStore((state)=>state.setFontName);
|
|
64
|
-
const applyFontWithStatus = (
|
|
60
|
+
const applyFontWithStatus = (customFontUrl, themeFontName)=>{
|
|
65
61
|
if ('undefined' == typeof window) return;
|
|
66
|
-
const
|
|
67
|
-
if (!
|
|
62
|
+
const url = customFontUrl?.trim();
|
|
63
|
+
if (!url) return void applyFont(themeFontName);
|
|
68
64
|
const existingLink = document.getElementById('ux-google-font-link');
|
|
69
65
|
if (existingLink) existingLink.remove();
|
|
70
66
|
storeSetFontLoadStatus('loading');
|
|
71
67
|
const linkElement = document.createElement('link');
|
|
72
68
|
linkElement.id = 'ux-google-font-link';
|
|
73
69
|
linkElement.rel = 'stylesheet';
|
|
74
|
-
linkElement.href =
|
|
70
|
+
linkElement.href = url;
|
|
75
71
|
linkElement.onload = ()=>{
|
|
76
72
|
storeSetFontLoadStatus('success');
|
|
77
|
-
const fontFamily = extractFontFamilyFromLink(
|
|
73
|
+
const fontFamily = extractFontFamilyFromLink(url);
|
|
78
74
|
if (fontFamily) {
|
|
79
75
|
applyFont(fontFamily);
|
|
80
76
|
storeSetFontName(fontFamily);
|
|
@@ -92,48 +88,30 @@ const useTheme = ()=>{
|
|
|
92
88
|
});
|
|
93
89
|
useEffect(()=>{
|
|
94
90
|
preloadFonts();
|
|
95
|
-
}, []);
|
|
96
|
-
useEffect(()=>{
|
|
97
|
-
if (!selectedFontLink.trim()) {
|
|
98
|
-
storeSetFontLoadStatus('idle');
|
|
99
|
-
storeSetFontName('');
|
|
100
|
-
}
|
|
101
|
-
}, [
|
|
102
|
-
selectedFontLink
|
|
103
|
-
]);
|
|
104
|
-
useEffect(()=>{
|
|
105
|
-
applyTheme(savedTheme);
|
|
106
|
-
debouncedApplyFont(savedFontLink, savedTheme.fontName);
|
|
107
|
-
}, [
|
|
108
|
-
savedTheme,
|
|
109
|
-
savedFontLink
|
|
110
|
-
]);
|
|
111
|
-
const setSelectedTheme = (theme)=>{
|
|
112
|
-
storeSetSelectedTheme(theme);
|
|
113
91
|
applyTheme(theme);
|
|
114
|
-
debouncedApplyFont(
|
|
115
|
-
};
|
|
116
|
-
const
|
|
117
|
-
|
|
92
|
+
debouncedApplyFont(fontUrl, theme.fontName);
|
|
93
|
+
}, []);
|
|
94
|
+
const setTheme = (theme)=>{
|
|
95
|
+
storeSetTheme(theme);
|
|
118
96
|
applyTheme(theme);
|
|
97
|
+
debouncedApplyFont(fontUrl, theme.fontName);
|
|
119
98
|
};
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
debouncedApplyFont(link,
|
|
99
|
+
const setFontUrl = (link)=>{
|
|
100
|
+
storeSetFontUrl(link);
|
|
101
|
+
debouncedApplyFont(link, theme.fontName);
|
|
123
102
|
};
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
103
|
+
const clearFontUrl = ()=>{
|
|
104
|
+
storeSetFontUrl('');
|
|
105
|
+
storeSetFontName('');
|
|
106
|
+
storeSetFontLoadStatus('idle');
|
|
107
|
+
debouncedApplyFont('', theme.fontName);
|
|
127
108
|
};
|
|
128
109
|
return {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
setSelectedFontLink,
|
|
135
|
-
savedFontLink,
|
|
136
|
-
setSavedFontLink,
|
|
110
|
+
theme,
|
|
111
|
+
setTheme,
|
|
112
|
+
fontUrl,
|
|
113
|
+
setFontUrl,
|
|
114
|
+
clearFontUrl,
|
|
137
115
|
fontLoadStatus,
|
|
138
116
|
fontName
|
|
139
117
|
};
|
package/dist/hooks/useI18n.d.ts
CHANGED
|
@@ -10,14 +10,18 @@ export declare const useI18n: () => {
|
|
|
10
10
|
};
|
|
11
11
|
theme: {
|
|
12
12
|
title: string;
|
|
13
|
-
|
|
14
|
-
apply: string;
|
|
13
|
+
done: string;
|
|
15
14
|
font: {
|
|
16
15
|
title: string;
|
|
17
16
|
placeholder: string;
|
|
18
17
|
loading: string;
|
|
19
18
|
success: string;
|
|
20
19
|
error: string;
|
|
20
|
+
hint: string;
|
|
21
|
+
example: {
|
|
22
|
+
show: string;
|
|
23
|
+
hide: string;
|
|
24
|
+
};
|
|
21
25
|
};
|
|
22
26
|
};
|
|
23
27
|
};
|
package/dist/hooks/useI18n.js
CHANGED
|
@@ -11,14 +11,18 @@ const en = {
|
|
|
11
11
|
},
|
|
12
12
|
theme: {
|
|
13
13
|
title: 'Theme',
|
|
14
|
-
|
|
15
|
-
apply: 'Apply Theme',
|
|
14
|
+
done: 'Finish',
|
|
16
15
|
font: {
|
|
17
16
|
title: 'Custom Font',
|
|
18
17
|
placeholder: 'Enter Google Fonts URL or custom font URL',
|
|
19
18
|
loading: 'Loading font...',
|
|
20
19
|
success: 'Font loaded: ',
|
|
21
|
-
error: 'Failed to load font'
|
|
20
|
+
error: 'Failed to load font',
|
|
21
|
+
hint: 'Try Google Fonts: ',
|
|
22
|
+
example: {
|
|
23
|
+
show: 'Show example',
|
|
24
|
+
hide: 'Hide example'
|
|
25
|
+
}
|
|
22
26
|
}
|
|
23
27
|
}
|
|
24
28
|
};
|
|
@@ -34,14 +38,18 @@ const zh = {
|
|
|
34
38
|
},
|
|
35
39
|
theme: {
|
|
36
40
|
title: '主题',
|
|
37
|
-
|
|
38
|
-
apply: '应用主题',
|
|
41
|
+
done: '完成',
|
|
39
42
|
font: {
|
|
40
43
|
title: '自定义字体',
|
|
41
44
|
placeholder: '输入 Google Fonts 或自定义字体链接',
|
|
42
45
|
loading: '正在加载字体...',
|
|
43
|
-
success: '
|
|
44
|
-
error: '字体加载失败'
|
|
46
|
+
success: '已加载字体:',
|
|
47
|
+
error: '字体加载失败',
|
|
48
|
+
hint: '参考 Google Fonts: ',
|
|
49
|
+
example: {
|
|
50
|
+
show: '显示示例',
|
|
51
|
+
hide: '隐藏示例'
|
|
52
|
+
}
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
55
|
};
|
package/dist/utils/detect.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const hasLongWord = (text)=>{
|
|
2
2
|
if ('string' != typeof text) return false;
|
|
3
|
-
const englishWords = text.
|
|
4
|
-
if (!englishWords) return false;
|
|
3
|
+
const englishWords = text.split(' ');
|
|
5
4
|
return englishWords.some((word)=>word.length > 30);
|
|
6
5
|
};
|
|
7
6
|
export { hasLongWord };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@particle-network/ui-react",
|
|
3
|
-
"version": "0.4.0-beta.
|
|
3
|
+
"version": "0.4.0-beta.25",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"ahooks": "^3.9.4",
|
|
50
50
|
"copy-to-clipboard": "^3.3.3",
|
|
51
51
|
"zustand": "^5.0.8",
|
|
52
|
-
"@particle-network/
|
|
53
|
-
"@particle-network/
|
|
52
|
+
"@particle-network/icons": "0.4.0-beta.14",
|
|
53
|
+
"@particle-network/ui-shared": "0.3.0-beta.6"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "rslib build",
|