@particle-network/ui-react 0.4.0-beta.17 → 0.4.0-beta.19
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/UXDivider/divider.extend.d.ts +5 -5
- package/dist/components/UXDrawer/index.d.ts +9 -0
- package/dist/components/UXDrawer/index.js +89 -0
- package/dist/components/UXEmpty/index.d.ts +1 -1
- package/dist/components/UXHint/index.d.ts +1 -1
- package/dist/components/UXInput/index.d.ts +9 -9
- package/dist/components/UXInput/input.extend.d.ts +9 -9
- package/dist/components/UXModal/index.js +3 -1
- package/dist/components/UXSwitch/index.d.ts +8 -8
- package/dist/components/UXSwitch/switch.extend.d.ts +8 -8
- package/dist/components/UXTable/index.d.ts +29 -29
- package/dist/components/UXTable/table.extend.d.ts +29 -29
- package/dist/components/UXTabs/index.d.ts +1 -1
- package/dist/components/UXThemeSwitch/theme-item.js +4 -4
- package/dist/components/UXThemeSwitch/theme-switch.js +69 -83
- package/dist/components/UXThemeSwitch/use-theme-store.d.ts +0 -5
- package/dist/components/UXThemeSwitch/use-theme-store.js +1 -5
- package/dist/components/UXThemeSwitch/use-theme.d.ts +1 -3
- package/dist/components/UXThemeSwitch/use-theme.js +62 -49
- package/dist/components/UXToast/index.d.ts +1 -0
- package/dist/components/UXToast/index.js +2 -2
- package/dist/components/UXTooltip/tooltip.extend.d.ts +7 -7
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/package.json +2 -2
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
2
|
-
|
|
2
|
+
className?: string | undefined;
|
|
3
|
+
size?: "md" | "lg" | undefined;
|
|
4
|
+
color?: "default" | "success" | "primary" | "secondary" | "warning" | "danger" | undefined;
|
|
5
|
+
radius?: "none" | "sm" | "md" | "lg" | undefined;
|
|
6
|
+
disableAnimation?: boolean | undefined;
|
|
7
|
+
shadow?: "none" | "sm" | "md" | "lg" | undefined;
|
|
8
|
+
"aria-label"?: string | undefined;
|
|
9
|
+
"aria-labelledby"?: string | undefined;
|
|
10
|
+
"aria-describedby"?: string | undefined;
|
|
11
|
+
"aria-details"?: string | undefined;
|
|
12
|
+
slot?: any;
|
|
13
|
+
style?: import("react").CSSProperties | undefined;
|
|
14
|
+
summary?: string | undefined;
|
|
15
|
+
title?: string | undefined;
|
|
3
16
|
ref?: import("@heroui/react-utils").ReactRef<HTMLElement | null> | undefined;
|
|
4
|
-
children?: ((string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | import("react").ReactPortal | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | null) & [import("react").ReactElement<import("@react-types/table").TableHeaderProps<object>, string | import("react").JSXElementConstructor<any>>, import("react").ReactElement<import("@react-types/table").TableBodyProps<object>, string | import("react").JSXElementConstructor<any>>]) | undefined;
|
|
5
17
|
defaultChecked?: any;
|
|
6
18
|
defaultValue?: any;
|
|
19
|
+
as?: import("@heroui/system-rsc").As<any> | undefined;
|
|
20
|
+
key?: import("react").Key | null | undefined;
|
|
7
21
|
suppressContentEditableWarning?: boolean | undefined;
|
|
8
22
|
suppressHydrationWarning?: boolean | undefined;
|
|
9
23
|
accessKey?: string | undefined;
|
|
10
24
|
autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | (string & {}) | undefined;
|
|
11
25
|
autoFocus?: boolean | undefined;
|
|
12
|
-
className?: string | undefined;
|
|
13
26
|
contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
|
|
14
27
|
contextMenu?: string | undefined;
|
|
15
28
|
dir?: string | undefined;
|
|
@@ -19,11 +32,8 @@ declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
19
32
|
id?: string | undefined;
|
|
20
33
|
lang?: string | undefined;
|
|
21
34
|
nonce?: string | undefined;
|
|
22
|
-
slot?: any;
|
|
23
35
|
spellCheck?: (boolean | "true" | "false") | undefined;
|
|
24
|
-
style?: import("react").CSSProperties | undefined;
|
|
25
36
|
tabIndex?: number | undefined;
|
|
26
|
-
title?: string | undefined;
|
|
27
37
|
translate?: "yes" | "no" | undefined;
|
|
28
38
|
radioGroup?: string | undefined;
|
|
29
39
|
role?: import("react").AriaRole | undefined;
|
|
@@ -40,7 +50,6 @@ declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
40
50
|
vocab?: string | undefined;
|
|
41
51
|
autoCorrect?: string | undefined;
|
|
42
52
|
autoSave?: string | undefined;
|
|
43
|
-
color?: "default" | "success" | "secondary" | "primary" | "danger" | "warning" | undefined;
|
|
44
53
|
itemProp?: string | undefined;
|
|
45
54
|
itemScope?: boolean | undefined;
|
|
46
55
|
itemType?: string | undefined;
|
|
@@ -53,7 +62,7 @@ declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
53
62
|
popoverTargetAction?: "toggle" | "show" | "hide" | undefined;
|
|
54
63
|
popoverTarget?: string | undefined;
|
|
55
64
|
inert?: boolean | undefined;
|
|
56
|
-
inputMode?: "search" | "
|
|
65
|
+
inputMode?: "search" | "text" | "none" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined;
|
|
57
66
|
is?: string | undefined;
|
|
58
67
|
exportparts?: string | undefined;
|
|
59
68
|
part?: string | undefined;
|
|
@@ -69,28 +78,24 @@ declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
69
78
|
"aria-colindextext"?: string | undefined;
|
|
70
79
|
"aria-colspan"?: number | undefined;
|
|
71
80
|
"aria-controls"?: string | undefined;
|
|
72
|
-
"aria-current"?: boolean | "true" | "false" | "page" | "step" | "location" | "date" |
|
|
73
|
-
"aria-describedby"?: string | undefined;
|
|
81
|
+
"aria-current"?: boolean | "time" | "true" | "false" | "page" | "step" | "location" | "date" | undefined;
|
|
74
82
|
"aria-description"?: string | undefined;
|
|
75
|
-
"aria-details"?: string | undefined;
|
|
76
83
|
"aria-disabled"?: (boolean | "true" | "false") | undefined;
|
|
77
84
|
"aria-dropeffect"?: "link" | "none" | "copy" | "execute" | "move" | "popup" | undefined;
|
|
78
85
|
"aria-errormessage"?: string | undefined;
|
|
79
86
|
"aria-expanded"?: (boolean | "true" | "false") | undefined;
|
|
80
87
|
"aria-flowto"?: string | undefined;
|
|
81
88
|
"aria-grabbed"?: (boolean | "true" | "false") | undefined;
|
|
82
|
-
"aria-haspopup"?: boolean | "
|
|
89
|
+
"aria-haspopup"?: boolean | "dialog" | "menu" | "true" | "false" | "grid" | "listbox" | "tree" | undefined;
|
|
83
90
|
"aria-hidden"?: (boolean | "true" | "false") | undefined;
|
|
84
91
|
"aria-invalid"?: boolean | "true" | "false" | "grammar" | "spelling" | undefined;
|
|
85
92
|
"aria-keyshortcuts"?: string | undefined;
|
|
86
|
-
"aria-label"?: string | undefined;
|
|
87
|
-
"aria-labelledby"?: string | undefined;
|
|
88
93
|
"aria-level"?: number | undefined;
|
|
89
94
|
"aria-live"?: "off" | "assertive" | "polite" | undefined;
|
|
90
95
|
"aria-modal"?: (boolean | "true" | "false") | undefined;
|
|
91
96
|
"aria-multiline"?: (boolean | "true" | "false") | undefined;
|
|
92
97
|
"aria-multiselectable"?: (boolean | "true" | "false") | undefined;
|
|
93
|
-
"aria-orientation"?: "
|
|
98
|
+
"aria-orientation"?: "horizontal" | "vertical" | undefined;
|
|
94
99
|
"aria-owns"?: string | undefined;
|
|
95
100
|
"aria-placeholder"?: string | undefined;
|
|
96
101
|
"aria-posinset"?: number | undefined;
|
|
@@ -110,6 +115,7 @@ declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
110
115
|
"aria-valuemin"?: number | undefined;
|
|
111
116
|
"aria-valuenow"?: number | undefined;
|
|
112
117
|
"aria-valuetext"?: string | undefined;
|
|
118
|
+
children?: ((string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | import("react").ReactPortal | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | null) & [import("react").ReactElement<import("@react-types/table").TableHeaderProps<object>, string | import("react").JSXElementConstructor<any>>, import("react").ReactElement<import("@react-types/table").TableBodyProps<object>, string | import("react").JSXElementConstructor<any>>]) | undefined;
|
|
113
119
|
dangerouslySetInnerHTML?: {
|
|
114
120
|
__html: string | TrustedHTML;
|
|
115
121
|
} | undefined;
|
|
@@ -281,28 +287,22 @@ declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
281
287
|
onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLTableElement> | undefined;
|
|
282
288
|
onTransitionStart?: import("react").TransitionEventHandler<HTMLTableElement> | undefined;
|
|
283
289
|
onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLTableElement> | undefined;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
radius?: "sm" | "md" | "lg" | "none" | undefined;
|
|
290
|
+
classNames?: import("@heroui/theme").SlotsToClasses<"base" | "table" | "tbody" | "td" | "tfoot" | "th" | "thead" | "tr" | "wrapper" | "sortIcon" | "emptyWrapper" | "loadingWrapper"> | undefined;
|
|
291
|
+
align?: "center" | "start" | "end" | undefined;
|
|
292
|
+
fullWidth?: boolean | undefined;
|
|
288
293
|
layout?: "auto" | "fixed" | undefined;
|
|
289
|
-
|
|
290
|
-
key?: import("react").Key | null | undefined;
|
|
291
|
-
classNames?: import("@heroui/theme").SlotsToClasses<"table" | "base" | "tbody" | "td" | "tfoot" | "th" | "thead" | "tr" | "wrapper" | "sortIcon" | "emptyWrapper" | "loadingWrapper"> | undefined;
|
|
292
|
-
disableAnimation?: boolean | undefined;
|
|
293
|
-
summary?: string | undefined;
|
|
294
|
-
as?: import("@heroui/system-rsc").As<any> | undefined;
|
|
294
|
+
width?: string | number | undefined;
|
|
295
295
|
baseRef?: import("@heroui/react-utils").ReactRef<HTMLElement | null> | undefined;
|
|
296
|
+
scrollRef?: import("@react-types/shared").RefObject<HTMLElement | null> | undefined;
|
|
297
|
+
border?: number | undefined;
|
|
296
298
|
disallowEmptySelection?: boolean | undefined;
|
|
297
299
|
onSelectionChange?: ((keys: import("@react-types/shared").Selection) => void) | undefined;
|
|
298
300
|
disabledKeys?: Iterable<import("@react-types/shared").Key> | undefined;
|
|
299
|
-
scrollRef?: import("@react-types/shared").RefObject<HTMLElement | null> | undefined;
|
|
300
301
|
isVirtualized?: boolean | undefined;
|
|
301
|
-
shadow?: "sm" | "md" | "lg" | "none" | undefined;
|
|
302
302
|
topContent?: import("react").ReactNode;
|
|
303
303
|
bottomContent?: import("react").ReactNode;
|
|
304
304
|
keyboardDelegate?: import("@react-types/shared").KeyboardDelegate | undefined;
|
|
305
|
-
selectionBehavior?: "
|
|
305
|
+
selectionBehavior?: "toggle" | "replace" | undefined;
|
|
306
306
|
shouldSelectOnPressUp?: boolean | undefined;
|
|
307
307
|
escapeKeyBehavior?: "none" | "clearSelection" | undefined;
|
|
308
308
|
selectionMode?: import("@react-types/shared").SelectionMode | undefined;
|
|
@@ -321,7 +321,7 @@ declare const ExtendedTable: import("react").ForwardRefExoticComponent<Omit<{
|
|
|
321
321
|
isMultiSelectable?: boolean | undefined;
|
|
322
322
|
layoutDelegate?: import("@react-types/shared").LayoutDelegate | undefined;
|
|
323
323
|
disallowTypeAhead?: boolean | undefined;
|
|
324
|
-
focusMode?: "
|
|
324
|
+
focusMode?: "cell" | "row" | undefined;
|
|
325
325
|
getRowText?: ((key: import("@react-types/shared").Key) => string) | undefined;
|
|
326
326
|
onRowAction?: (((key: import("react").Key) => void) & ((key: import("@react-types/shared").Key) => void)) | undefined;
|
|
327
327
|
onCellAction?: (((key: import("react").Key) => void) & ((key: import("@react-types/shared").Key) => void)) | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ExtendedTabs from './tabs.extend';
|
|
3
3
|
export type UXTabsProps = React.ComponentPropsWithRef<typeof ExtendedTabs>;
|
|
4
|
-
export declare const UXTabs: React.ForwardRefExoticComponent<Omit<Omit<import("@heroui/tabs").TabsProps, "
|
|
4
|
+
export declare const UXTabs: React.ForwardRefExoticComponent<Omit<Omit<import("@heroui/tabs").TabsProps, "variant" | "color"> & {
|
|
5
5
|
variant?: "solid" | "light" | "text" | "switch";
|
|
6
6
|
color?: "default" | "primary" | "success" | "warning" | "danger" | "bullish" | "bearish";
|
|
7
7
|
}, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -9,15 +9,15 @@ const ThemeItem = ({ id, zhName, enName, isSelected, onClick })=>{
|
|
|
9
9
|
return /*#__PURE__*/ jsxs(VStack, {
|
|
10
10
|
center: true,
|
|
11
11
|
gap: 2,
|
|
12
|
-
className: cn('cursor-pointer
|
|
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', isSelected ? 'border-primary' : 'border-transparent'),
|
|
16
|
+
className: cn('rounded-medium border-2 hover:scale-105 transition-all duration-300', isSelected ? 'border-primary' : 'border-transparent'),
|
|
17
17
|
children: /*#__PURE__*/ jsxs("svg", {
|
|
18
18
|
xmlns: "http://www.w3.org/2000/svg",
|
|
19
|
-
width: "
|
|
20
|
-
height: "
|
|
19
|
+
width: "120",
|
|
20
|
+
height: "71",
|
|
21
21
|
viewBox: "0 0 120 71",
|
|
22
22
|
fill: "none",
|
|
23
23
|
children: [
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import "react";
|
|
3
|
-
import { Drawer, DrawerBody, DrawerContent, DrawerFooter, DrawerHeader } from "@heroui/drawer";
|
|
4
3
|
import { useDisclosure } from "@heroui/use-disclosure";
|
|
5
4
|
import { ChartColorSwitchIcon } from "@particle-network/icons/web";
|
|
6
5
|
import { themeData } from "@particle-network/ui-shared";
|
|
7
6
|
import { useI18n } from "../../hooks/index.js";
|
|
8
|
-
import {
|
|
7
|
+
import { HStack, VStack } from "../layout/index.js";
|
|
9
8
|
import { Text } from "../typography/Text.js";
|
|
10
9
|
import { UXButton } from "../UXButton/index.js";
|
|
11
10
|
import { UXDivider } from "../UXDivider/index.js";
|
|
11
|
+
import { UXDrawer } from "../UXDrawer/index.js";
|
|
12
12
|
import { UXInput } from "../UXInput/index.js";
|
|
13
13
|
import { UXSpinner } from "../UXSpinner/index.js";
|
|
14
14
|
import { ThemeItem } from "./theme-item.js";
|
|
15
15
|
import { useTheme } from "./use-theme.js";
|
|
16
16
|
const UXThemeSwitchDrawer = ({ isOpen, onClose, onOpenChange, ...props })=>{
|
|
17
17
|
const i18n = useI18n();
|
|
18
|
-
const { selectedTheme, setSelectedTheme, savedTheme, setSavedTheme, selectedFontLink, setSelectedFontLink, savedFontLink, setSavedFontLink, fontName, fontLoadStatus
|
|
18
|
+
const { selectedTheme, setSelectedTheme, savedTheme, setSavedTheme, selectedFontLink, setSelectedFontLink, savedFontLink, setSavedFontLink, fontName, fontLoadStatus } = useTheme();
|
|
19
19
|
const handleOpenChange = (_isOpen)=>{
|
|
20
20
|
onOpenChange?.(_isOpen);
|
|
21
21
|
if (!_isOpen) {
|
|
@@ -32,96 +32,82 @@ const UXThemeSwitchDrawer = ({ isOpen, onClose, onOpenChange, ...props })=>{
|
|
|
32
32
|
setSelectedTheme(savedTheme);
|
|
33
33
|
setSelectedFontLink(savedFontLink);
|
|
34
34
|
};
|
|
35
|
-
return /*#__PURE__*/
|
|
35
|
+
return /*#__PURE__*/ jsxs(UXDrawer, {
|
|
36
36
|
isOpen: isOpen,
|
|
37
37
|
backdrop: "transparent",
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
title: i18n.theme.title,
|
|
39
|
+
footer: /*#__PURE__*/ jsxs(HStack, {
|
|
40
|
+
fullWidth: true,
|
|
41
|
+
gap: "lg",
|
|
41
42
|
children: [
|
|
42
|
-
/*#__PURE__*/ jsx(
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
/*#__PURE__*/ jsx(UXButton, {
|
|
44
|
+
fullWidth: true,
|
|
45
|
+
size: "lg",
|
|
46
|
+
onPress: handleReset,
|
|
47
|
+
children: i18n.theme.reset
|
|
45
48
|
}),
|
|
46
|
-
/*#__PURE__*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
/*#__PURE__*/ jsx(UXButton, {
|
|
50
|
+
fullWidth: true,
|
|
51
|
+
isDisabled: 'error' === fontLoadStatus,
|
|
52
|
+
size: "lg",
|
|
53
|
+
color: "primary",
|
|
54
|
+
onPress: handleApplyTheme,
|
|
55
|
+
children: i18n.theme.apply
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
}),
|
|
59
|
+
onOpenChange: handleOpenChange,
|
|
60
|
+
...props,
|
|
61
|
+
children: [
|
|
62
|
+
/*#__PURE__*/ jsx("div", {
|
|
63
|
+
className: "grid grid-cols-3 gap-y-5",
|
|
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
|
|
60
84
|
}),
|
|
61
|
-
|
|
62
|
-
|
|
85
|
+
isInvalid: 'error' === fontLoadStatus,
|
|
86
|
+
className: "w-full",
|
|
87
|
+
placeholder: i18n.theme.font.placeholder,
|
|
88
|
+
value: selectedFontLink,
|
|
89
|
+
description: /*#__PURE__*/ jsxs(Fragment, {
|
|
63
90
|
children: [
|
|
64
|
-
/*#__PURE__*/
|
|
65
|
-
|
|
66
|
-
|
|
91
|
+
'success' === fontLoadStatus && /*#__PURE__*/ jsxs(Text, {
|
|
92
|
+
body3Bold: true,
|
|
93
|
+
color: "success",
|
|
94
|
+
children: [
|
|
95
|
+
i18n.theme.font.success,
|
|
96
|
+
fontName
|
|
97
|
+
]
|
|
67
98
|
}),
|
|
68
|
-
/*#__PURE__*/ jsx(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}),
|
|
73
|
-
isInvalid: 'error' === fontLoadStatus,
|
|
74
|
-
className: "w-full",
|
|
75
|
-
placeholder: i18n.theme.font.placeholder,
|
|
76
|
-
value: selectedFontLink,
|
|
77
|
-
description: /*#__PURE__*/ jsxs(Fragment, {
|
|
78
|
-
children: [
|
|
79
|
-
'success' === fontLoadStatus && /*#__PURE__*/ jsxs(Text, {
|
|
80
|
-
body3Bold: true,
|
|
81
|
-
color: "success",
|
|
82
|
-
children: [
|
|
83
|
-
i18n.theme.font.success,
|
|
84
|
-
fontName
|
|
85
|
-
]
|
|
86
|
-
}),
|
|
87
|
-
'error' === fontLoadStatus && fontLoadError && /*#__PURE__*/ jsx(Text, {
|
|
88
|
-
body3Bold: true,
|
|
89
|
-
color: "danger",
|
|
90
|
-
children: fontLoadError
|
|
91
|
-
})
|
|
92
|
-
]
|
|
93
|
-
}),
|
|
94
|
-
onValueChange: setSelectedFontLink
|
|
99
|
+
'error' === fontLoadStatus && /*#__PURE__*/ jsx(Text, {
|
|
100
|
+
body3Bold: true,
|
|
101
|
+
color: "danger",
|
|
102
|
+
children: i18n.theme.font.error
|
|
95
103
|
})
|
|
96
104
|
]
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
}),
|
|
100
|
-
/*#__PURE__*/ jsx(DrawerFooter, {
|
|
101
|
-
className: "mb-8",
|
|
102
|
-
children: /*#__PURE__*/ jsxs(HStack, {
|
|
103
|
-
fullWidth: true,
|
|
104
|
-
gap: "lg",
|
|
105
|
-
children: [
|
|
106
|
-
/*#__PURE__*/ jsx(UXButton, {
|
|
107
|
-
fullWidth: true,
|
|
108
|
-
size: "lg",
|
|
109
|
-
onPress: handleReset,
|
|
110
|
-
children: i18n.theme.reset
|
|
111
|
-
}),
|
|
112
|
-
/*#__PURE__*/ jsx(UXButton, {
|
|
113
|
-
fullWidth: true,
|
|
114
|
-
isDisabled: 'error' === fontLoadStatus,
|
|
115
|
-
size: "lg",
|
|
116
|
-
color: "primary",
|
|
117
|
-
onPress: handleApplyTheme,
|
|
118
|
-
children: i18n.theme.apply
|
|
119
|
-
})
|
|
120
|
-
]
|
|
105
|
+
}),
|
|
106
|
+
onValueChange: setSelectedFontLink
|
|
121
107
|
})
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
108
|
+
]
|
|
109
|
+
})
|
|
110
|
+
]
|
|
125
111
|
});
|
|
126
112
|
};
|
|
127
113
|
const UXThemeSwitch = ({ children })=>{
|
|
@@ -25,10 +25,6 @@ interface State {
|
|
|
25
25
|
* 字体加载状态
|
|
26
26
|
*/
|
|
27
27
|
fontLoadStatus: FontLoadStatus;
|
|
28
|
-
/**
|
|
29
|
-
* 字体加载错误信息
|
|
30
|
-
*/
|
|
31
|
-
fontLoadError: string | null;
|
|
32
28
|
}
|
|
33
29
|
interface Actions {
|
|
34
30
|
setSelectedTheme: (theme: ThemeItemType) => void;
|
|
@@ -36,7 +32,6 @@ interface Actions {
|
|
|
36
32
|
setSelectedFontLink: (link: string) => void;
|
|
37
33
|
setSavedFontLink: (link: string) => void;
|
|
38
34
|
setFontLoadStatus: (status: FontLoadStatus) => void;
|
|
39
|
-
setFontLoadError: (error: string | null) => void;
|
|
40
35
|
setFontName: (name: string) => void;
|
|
41
36
|
}
|
|
42
37
|
type ThemeStore = State & Actions;
|
|
@@ -8,7 +8,6 @@ const useThemeStore = create()(persist((set)=>({
|
|
|
8
8
|
savedFontLink: '',
|
|
9
9
|
fontName: '',
|
|
10
10
|
fontLoadStatus: 'idle',
|
|
11
|
-
fontLoadError: null,
|
|
12
11
|
setSelectedTheme: (theme)=>set({
|
|
13
12
|
selectedTheme: theme
|
|
14
13
|
}),
|
|
@@ -24,14 +23,11 @@ const useThemeStore = create()(persist((set)=>({
|
|
|
24
23
|
setFontLoadStatus: (status)=>set({
|
|
25
24
|
fontLoadStatus: status
|
|
26
25
|
}),
|
|
27
|
-
setFontLoadError: (error)=>set({
|
|
28
|
-
fontLoadError: error
|
|
29
|
-
}),
|
|
30
26
|
setFontName: (name)=>set({
|
|
31
27
|
fontName: name
|
|
32
28
|
})
|
|
33
29
|
}), {
|
|
34
|
-
name: 'ux-theme',
|
|
30
|
+
name: 'ux-theme-1',
|
|
35
31
|
storage: createJSONStorage(()=>'undefined' != typeof window ? window.localStorage : {}),
|
|
36
32
|
partialize: (state)=>({
|
|
37
33
|
selectedTheme: state.selectedTheme,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type ThemeItemType } from '@particle-network/ui-shared';
|
|
2
|
-
import { type FontLoadStatus } from './use-theme-store';
|
|
3
2
|
/**
|
|
4
3
|
* UX 主题管理 Hook
|
|
5
4
|
*/
|
|
@@ -12,7 +11,6 @@ export declare const useTheme: () => {
|
|
|
12
11
|
setSelectedFontLink: (link: string) => void;
|
|
13
12
|
savedFontLink: string;
|
|
14
13
|
setSavedFontLink: (link: string) => void;
|
|
15
|
-
fontLoadStatus: FontLoadStatus;
|
|
16
|
-
fontLoadError: string | null;
|
|
14
|
+
fontLoadStatus: import("./use-theme-store").FontLoadStatus;
|
|
17
15
|
fontName: string;
|
|
18
16
|
};
|
|
@@ -2,7 +2,18 @@ import { useEffect } from "react";
|
|
|
2
2
|
import { themeKeys } from "@particle-network/ui-shared";
|
|
3
3
|
import { useDebounceFn } from "ahooks";
|
|
4
4
|
import { useThemeStore } from "./use-theme-store.js";
|
|
5
|
-
const DEFAULT_FONT_FAMILY = '
|
|
5
|
+
const DEFAULT_FONT_FAMILY = 'Inter,system-ui,sans-serif,"Microsoft YaHei"';
|
|
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
|
+
};
|
|
6
17
|
const applyTheme = (theme)=>{
|
|
7
18
|
if ('undefined' == typeof window) return;
|
|
8
19
|
const root = document.documentElement;
|
|
@@ -21,50 +32,21 @@ const extractFontFamilyFromLink = (link)=>{
|
|
|
21
32
|
const url = new URL(link);
|
|
22
33
|
const familyParam = url.searchParams.get('family');
|
|
23
34
|
if (!familyParam) return null;
|
|
24
|
-
const
|
|
25
|
-
return
|
|
35
|
+
const firstFamily = familyParam.split('&family=')[0].split(':')[0].replace(/\+/g, ' ');
|
|
36
|
+
return firstFamily;
|
|
26
37
|
} catch {
|
|
27
38
|
return null;
|
|
28
39
|
}
|
|
29
40
|
};
|
|
30
|
-
const
|
|
31
|
-
const { setFontLoadStatus, setFontLoadError, setFontName } = options;
|
|
41
|
+
const applyFont = (fontName)=>{
|
|
32
42
|
if ('undefined' == typeof window) return;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
if (fontName) {
|
|
44
|
+
document.documentElement.style.setProperty('--ux-font-family', `"${fontName}", ${DEFAULT_FONT_FAMILY}`);
|
|
45
|
+
document.body.style.fontFamily = `"${fontName}", ${DEFAULT_FONT_FAMILY}`;
|
|
46
|
+
} else {
|
|
36
47
|
document.documentElement.style.setProperty('--ux-font-family', DEFAULT_FONT_FAMILY);
|
|
37
48
|
document.body.style.fontFamily = DEFAULT_FONT_FAMILY;
|
|
38
|
-
setFontLoadStatus('idle');
|
|
39
|
-
setFontLoadError(null);
|
|
40
|
-
setFontName('');
|
|
41
|
-
return;
|
|
42
49
|
}
|
|
43
|
-
setFontLoadStatus('loading');
|
|
44
|
-
setFontLoadError(null);
|
|
45
|
-
const linkElement = document.createElement('link');
|
|
46
|
-
linkElement.id = 'ux-google-font-link';
|
|
47
|
-
linkElement.rel = 'stylesheet';
|
|
48
|
-
linkElement.href = link;
|
|
49
|
-
linkElement.onload = ()=>{
|
|
50
|
-
setFontLoadStatus('success');
|
|
51
|
-
setFontLoadError(null);
|
|
52
|
-
const fontFamily = extractFontFamilyFromLink(link);
|
|
53
|
-
if (fontFamily) {
|
|
54
|
-
document.documentElement.style.setProperty('--ux-font-family', `"${fontFamily}", ${DEFAULT_FONT_FAMILY}`);
|
|
55
|
-
document.body.style.fontFamily = `"${fontFamily}", ${DEFAULT_FONT_FAMILY}`;
|
|
56
|
-
setFontName(fontFamily);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
linkElement.onerror = ()=>{
|
|
60
|
-
const errorMessage = '字体加载失败,请检查链接是否正确';
|
|
61
|
-
setFontLoadStatus('error');
|
|
62
|
-
setFontLoadError(errorMessage);
|
|
63
|
-
setFontName('');
|
|
64
|
-
document.documentElement.style.setProperty('--ux-font-family', DEFAULT_FONT_FAMILY);
|
|
65
|
-
document.body.style.fontFamily = DEFAULT_FONT_FAMILY;
|
|
66
|
-
};
|
|
67
|
-
document.head.appendChild(linkElement);
|
|
68
50
|
};
|
|
69
51
|
const useTheme = ()=>{
|
|
70
52
|
const selectedTheme = useThemeStore((state)=>state.selectedTheme);
|
|
@@ -73,24 +55,55 @@ const useTheme = ()=>{
|
|
|
73
55
|
const savedFontLink = useThemeStore((state)=>state.savedFontLink);
|
|
74
56
|
const fontName = useThemeStore((state)=>state.fontName);
|
|
75
57
|
const fontLoadStatus = useThemeStore((state)=>state.fontLoadStatus);
|
|
76
|
-
const fontLoadError = useThemeStore((state)=>state.fontLoadError);
|
|
77
58
|
const storeSetSelectedTheme = useThemeStore((state)=>state.setSelectedTheme);
|
|
78
59
|
const storeSetSavedTheme = useThemeStore((state)=>state.setSavedTheme);
|
|
79
60
|
const storeSetSelectedFontLink = useThemeStore((state)=>state.setSelectedFontLink);
|
|
80
61
|
const storeSetSavedFontLink = useThemeStore((state)=>state.setSavedFontLink);
|
|
81
62
|
const storeSetFontLoadStatus = useThemeStore((state)=>state.setFontLoadStatus);
|
|
82
|
-
const storeSetFontLoadError = useThemeStore((state)=>state.setFontLoadError);
|
|
83
63
|
const storeSetFontName = useThemeStore((state)=>state.setFontName);
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
64
|
+
const applyFontWithStatus = (customFontLink, themeFontName)=>{
|
|
65
|
+
if ('undefined' == typeof window) return;
|
|
66
|
+
const isCustomFont = !!customFontLink?.trim();
|
|
67
|
+
if (!isCustomFont) return void applyFont(themeFontName);
|
|
68
|
+
const existingLink = document.getElementById('ux-google-font-link');
|
|
69
|
+
if (existingLink) existingLink.remove();
|
|
70
|
+
storeSetFontLoadStatus('loading');
|
|
71
|
+
const linkElement = document.createElement('link');
|
|
72
|
+
linkElement.id = 'ux-google-font-link';
|
|
73
|
+
linkElement.rel = 'stylesheet';
|
|
74
|
+
linkElement.href = customFontLink;
|
|
75
|
+
linkElement.onload = ()=>{
|
|
76
|
+
storeSetFontLoadStatus('success');
|
|
77
|
+
const fontFamily = extractFontFamilyFromLink(customFontLink);
|
|
78
|
+
if (fontFamily) {
|
|
79
|
+
applyFont(fontFamily);
|
|
80
|
+
storeSetFontName(fontFamily);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
linkElement.onerror = ()=>{
|
|
84
|
+
storeSetFontLoadStatus('error');
|
|
85
|
+
storeSetFontName('');
|
|
86
|
+
applyFont(themeFontName);
|
|
87
|
+
};
|
|
88
|
+
document.head.appendChild(linkElement);
|
|
89
|
+
};
|
|
90
|
+
const { run: debouncedApplyFont } = useDebounceFn((customFontLink, themeFontName)=>applyFontWithStatus(customFontLink, themeFontName), {
|
|
91
|
+
wait: 300
|
|
90
92
|
});
|
|
93
|
+
useEffect(()=>{
|
|
94
|
+
preloadFonts();
|
|
95
|
+
}, []);
|
|
96
|
+
useEffect(()=>{
|
|
97
|
+
if (!selectedFontLink.trim()) {
|
|
98
|
+
storeSetFontLoadStatus('idle');
|
|
99
|
+
storeSetFontName('');
|
|
100
|
+
}
|
|
101
|
+
}, [
|
|
102
|
+
selectedFontLink
|
|
103
|
+
]);
|
|
91
104
|
useEffect(()=>{
|
|
92
105
|
applyTheme(savedTheme);
|
|
93
|
-
|
|
106
|
+
debouncedApplyFont(savedFontLink, savedTheme.fontName);
|
|
94
107
|
}, [
|
|
95
108
|
savedTheme,
|
|
96
109
|
savedFontLink
|
|
@@ -98,6 +111,7 @@ const useTheme = ()=>{
|
|
|
98
111
|
const setSelectedTheme = (theme)=>{
|
|
99
112
|
storeSetSelectedTheme(theme);
|
|
100
113
|
applyTheme(theme);
|
|
114
|
+
debouncedApplyFont(selectedFontLink, theme.fontName);
|
|
101
115
|
};
|
|
102
116
|
const setSavedTheme = (theme)=>{
|
|
103
117
|
storeSetSavedTheme(theme);
|
|
@@ -105,11 +119,11 @@ const useTheme = ()=>{
|
|
|
105
119
|
};
|
|
106
120
|
const setSelectedFontLink = (link)=>{
|
|
107
121
|
storeSetSelectedFontLink(link);
|
|
108
|
-
|
|
122
|
+
debouncedApplyFont(link, selectedTheme.fontName);
|
|
109
123
|
};
|
|
110
124
|
const setSavedFontLink = (link)=>{
|
|
111
125
|
storeSetSavedFontLink(link);
|
|
112
|
-
|
|
126
|
+
debouncedApplyFont(link, savedTheme.fontName);
|
|
113
127
|
};
|
|
114
128
|
return {
|
|
115
129
|
selectedTheme,
|
|
@@ -121,7 +135,6 @@ const useTheme = ()=>{
|
|
|
121
135
|
savedFontLink,
|
|
122
136
|
setSavedFontLink,
|
|
123
137
|
fontLoadStatus,
|
|
124
|
-
fontLoadError,
|
|
125
138
|
fontName
|
|
126
139
|
};
|
|
127
140
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { ToastProps } from '@heroui/toast';
|
|
3
|
+
export { addToast, closeAll, closeToast, getToastQueue, isToastClosing } from '@heroui/toast';
|
|
3
4
|
export type UXToastType = 'success' | 'error' | 'loading' | 'info';
|
|
4
5
|
export type UXToastProps = Partial<ToastProps> & {
|
|
5
6
|
type: UXToastType;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { ToastProvider, addToast, closeAll, closeToast } from "@heroui/toast";
|
|
2
|
+
import { ToastProvider, addToast, closeAll, closeToast, getToastQueue, isToastClosing } from "@heroui/toast";
|
|
3
3
|
import CircleCheckIcon from "@particle-network/icons/web/CircleCheckIcon";
|
|
4
4
|
import CircleCloseIcon from "@particle-network/icons/web/CircleCloseIcon";
|
|
5
5
|
import CloseIcon from "@particle-network/icons/web/CloseIcon";
|
|
@@ -106,4 +106,4 @@ const toast = {
|
|
|
106
106
|
closeAll: closeAll,
|
|
107
107
|
close: closeToast
|
|
108
108
|
};
|
|
109
|
-
export { UXToastProvider, toast };
|
|
109
|
+
export { UXToastProvider, addToast, closeAll, closeToast, getToastQueue, isToastClosing, toast };
|