@_tc/template-core 0.0.1-bate.37 → 0.0.1-bate.39
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/cjs/bundler/utils.js +13 -5
- package/cjs/packages/core/index.js +1 -1
- package/cjs/packages/core/loader/config.js +4 -2
- package/cjs/packages/core/loader/controller.js +2 -3
- package/cjs/packages/core/loader/extend.js +1 -2
- package/cjs/packages/core/loader/middleware.js +2 -3
- package/cjs/packages/core/loader/model.js +7 -3
- package/cjs/packages/core/loader/router-schema.js +4 -2
- package/cjs/packages/core/loader/router.js +10 -6
- package/cjs/packages/core/loader/service.js +2 -2
- package/cjs/packages/utils/runFileFn.js +46 -1
- package/esm/bundler/utils.js +13 -5
- package/esm/packages/core/index.js +1 -2
- package/esm/packages/core/loader/config.js +4 -3
- package/esm/packages/core/loader/controller.js +2 -4
- package/esm/packages/core/loader/extend.js +1 -3
- package/esm/packages/core/loader/middleware.js +2 -4
- package/esm/packages/core/loader/model.js +7 -4
- package/esm/packages/core/loader/router-schema.js +4 -3
- package/esm/packages/core/loader/router.js +10 -7
- package/esm/packages/core/loader/service.js +2 -3
- package/esm/packages/utils/runFileFn.js +47 -1
- package/fe/frontend/dash/Dashboard.js +11 -1
- package/fe/frontend/dash/dash.entry.js +19 -1
- package/fe/frontend/main.js +2 -0
- package/fe/frontend/widgets/common/CRUD/CRUD.js +1 -0
- package/fe/frontend/widgets/common/importComponent.js +1 -0
- package/fe/frontend/widgets/common/language.js +1 -0
- package/fe/frontend/widgets/common/menu.d.ts +12 -0
- package/fe/frontend/widgets/common/menu.js +21 -0
- package/fe/frontend/widgets/common/request.d.ts +3 -0
- package/fe/frontend/widgets/common/request.js +6 -0
- package/fe/frontend/widgets/components/BasePage/HeaderView.js +3 -1
- package/fe/frontend/widgets/defaultPages/Schema/components/CallCom/PopFrom.js +15 -0
- package/fe/frontend/widgets/defaultPages/Schema/components/SchemaSearch/index.js +5 -0
- package/fe/frontend/widgets/defaultPages/Schema/components/SchemaTable/index.js +13 -1
- package/fe/frontend/widgets/defaultPages/Schema/data/eventInfo.js +4 -4
- package/fe/frontend/widgets/defaultPages/Schema/index.js +7 -0
- package/fe/frontend/widgets/defaultPages/Schema/schemaType.d.ts +9 -0
- package/fe/frontend/widgets/defaultPages/Schema/stores/schemaEventBus.d.ts +19 -0
- package/fe/frontend/widgets/defaultPages/Schema/stores/schemaEventBus.js +4 -0
- package/fe/frontend/widgets/defaultPages/Schema/stores/schemaStore.d.ts +14 -0
- package/fe/frontend/widgets/defaultPages/Schema/stores/schemaStore.js +2 -0
- package/fe/frontend/widgets/defaultPages/Schema/utils/schemaConversion.js +43 -0
- package/fe/frontend/widgets/defaultPages/Schema/utils/validator.d.ts +3 -0
- package/fe/frontend/widgets/defaultPages/Schema/utils/validator.js +5 -0
- package/fe/frontend/widgets/defaultPages/SidebarSlotPage/SidebarSlotContainer.js +7 -0
- package/fe/frontend/widgets/defaultPages/SidebarSlotPage/index.js +1 -0
- package/fe/frontend/widgets/defaultPages/SlotPage/index.js +2 -0
- package/fe/frontend/widgets/hooks/useCurrentMenuData.d.ts +8 -0
- package/fe/frontend/widgets/hooks/useCurrentMenuData.js +8 -0
- package/fe/frontend/widgets/store/mode.d.ts +3 -0
- package/fe/frontend/widgets/store/mode.js +1 -0
- package/fe/model/types/data/button.d.ts +9 -0
- package/fe/model/types/data/button.js +15 -0
- package/fe/model/types/data/component.d.ts +24 -0
- package/fe/model/types/data/component.js +10 -0
- package/fe/model/types/data/fetchInfo.d.ts +12 -0
- package/fe/model/types/data/schema.d.ts +51 -0
- package/fe/model/types/menuType.d.ts +29 -0
- package/fe/model/types/model.d.ts +13 -0
- package/fe/packages/common/i18n/default.d.ts +5 -0
- package/fe/packages/common/i18n/default.js +5 -0
- package/fe/packages/common/i18n/en-US.d.ts +5 -0
- package/fe/packages/common/i18n/en-US.js +5 -0
- package/fe/packages/common/i18n/index.d.ts +24 -0
- package/fe/packages/common/i18n/index.js +31 -0
- package/fe/packages/common/i18n/types.d.ts +24 -0
- package/fe/packages/ui/react/components/Button/Button.d.ts +33 -0
- package/fe/packages/ui/react/components/Button/Button.js +3 -0
- package/fe/packages/ui/react/components/Button/SumbitButton.d.ts +4 -0
- package/fe/packages/ui/react/components/Button/SumbitButton.js +4 -0
- package/fe/packages/ui/react/components/ConfirmDialog/ConfirmDialog.d.ts +8 -0
- package/fe/packages/ui/react/components/DataTable/index.d.ts +19 -0
- package/fe/packages/ui/react/components/DataTable/index.js +4 -0
- package/fe/packages/ui/react/components/Date/Calendar.d.ts +13 -0
- package/fe/packages/ui/react/components/Date/Calendar.js +10 -1
- package/fe/packages/ui/react/components/Date/Date.d.ts +11 -0
- package/fe/packages/ui/react/components/Date/Date.js +19 -0
- package/fe/packages/ui/react/components/Date/LocaleContext.d.ts +4 -0
- package/fe/packages/ui/react/components/Date/LocaleContext.js +4 -0
- package/fe/packages/ui/react/components/Date/LocaleProvider.d.ts +11 -0
- package/fe/packages/ui/react/components/Date/LocaleProvider.js +11 -0
- package/fe/packages/ui/react/components/Date/TimePicker.js +1 -0
- package/fe/packages/ui/react/components/Date/dateLocaleStore.d.ts +6 -0
- package/fe/packages/ui/react/components/Date/locales.d.ts +19 -0
- package/fe/packages/ui/react/components/Date/locales.js +9 -0
- package/fe/packages/ui/react/components/Drawer/Drawer.d.ts +6 -0
- package/fe/packages/ui/react/components/Dropdown/Dropdown.d.ts +1 -0
- package/fe/packages/ui/react/components/Form/Form.d.ts +6 -0
- package/fe/packages/ui/react/components/Form/FormItem.d.ts +21 -0
- package/fe/packages/ui/react/components/Form/FormItem.js +8 -1
- package/fe/packages/ui/react/components/Form/SchemaForm/data.js +1 -0
- package/fe/packages/ui/react/components/Form/SchemaForm/index.d.ts +93 -0
- package/fe/packages/ui/react/components/Form/SchemaForm/index.js +5 -1
- package/fe/packages/ui/react/components/ImagePreview/ImagePreview.js +8 -0
- package/fe/packages/ui/react/components/ImagePreview/PreviewImage.d.ts +3 -0
- package/fe/packages/ui/react/components/Input/Input.d.ts +22 -0
- package/fe/packages/ui/react/components/Input/Input.js +3 -0
- package/fe/packages/ui/react/components/InputNumber/InputNumber.d.ts +2 -0
- package/fe/packages/ui/react/components/Label/Label.d.ts +29 -0
- package/fe/packages/ui/react/components/Label/Label.js +2 -0
- package/fe/packages/ui/react/components/Menu/Menu.js +4 -0
- package/fe/packages/ui/react/components/Menu/SubMenu.d.ts +7 -0
- package/fe/packages/ui/react/components/Menu/SubMenu.js +46 -1
- package/fe/packages/ui/react/components/Menu/menuTypes.d.ts +1 -0
- package/fe/packages/ui/react/components/Message/Message.d.ts +7 -0
- package/fe/packages/ui/react/components/Message/Message.js +3 -0
- package/fe/packages/ui/react/components/Message/MessageManager.js +8 -0
- package/fe/packages/ui/react/components/Modal/Modal.d.ts +6 -0
- package/fe/packages/ui/react/components/Modal/Modal.js +1 -0
- package/fe/packages/ui/react/components/Modal/ModalManager.d.ts +12 -0
- package/fe/packages/ui/react/components/Modal/ModalManager.js +4 -1
- package/fe/packages/ui/react/components/Overlay/Overlay.d.ts +3 -0
- package/fe/packages/ui/react/components/Pagination/Pagination.d.ts +7 -0
- package/fe/packages/ui/react/components/Pagination/Pagination.js +8 -1
- package/fe/packages/ui/react/components/Popup/Popup.js +14 -2
- package/fe/packages/ui/react/components/Search/Search.d.ts +3 -0
- package/fe/packages/ui/react/components/Select/Select.d.ts +5 -0
- package/fe/packages/ui/react/components/Select/Select.js +4 -0
- package/fe/packages/ui/react/components/Skeleton/Skeleton.d.ts +15 -0
- package/fe/packages/ui/react/components/Skeleton/Skeleton.js +1 -1
- package/fe/packages/ui/react/components/TableSearch/TableSearch.d.ts +37 -0
- package/fe/packages/ui/react/components/TableSearch/TableSearch.js +4 -1
- package/fe/packages/ui/react/components/Textarea/Textarea.d.ts +46 -0
- package/fe/packages/ui/react/components/Textarea/Textarea.js +1 -0
- package/fe/packages/ui/react/components/Tooltip/Tooltip.d.ts +16 -0
- package/fe/packages/ui/react/components/Tooltip/Tooltip.js +8 -0
- package/fe/packages/ui/react/components/TreeSelect/TreeSelect.d.ts +6 -0
- package/fe/packages/ui/react/components/TreeSelect/TreeSelect.js +6 -0
- package/fe/packages/ui/react/components/Upload/Upload.d.ts +27 -0
- package/fe/packages/ui/react/components/breadcrumb/breadcrumb.js +9 -0
- package/fe/packages/ui/react/components/hooks/useDropdownPositioning.d.ts +6 -0
- package/fe/packages/ui/react/components/hooks/useDropdownPositioning.js +14 -0
- package/fe/packages/ui/react/components/hooks/useInputController.d.ts +3 -0
- package/fe/packages/ui/react/components/hooks/useInputController.js +7 -0
- package/fe/packages/ui/react/components/testPage/MenuTestPage.js +3 -0
- package/fe/packages/ui/react/components/testPage/index.js +26 -0
- package/fe/packages/ui/react/hooks/useExecuteOnce.d.ts +19 -1
- package/fe/packages/ui/react/hooks/useExecuteOnce.js +22 -1
- package/fe/packages/ui/react/hooks/useRefState.d.ts +12 -0
- package/fe/packages/ui/react/hooks/useRefState.js +1 -0
- package/fe/packages/ui/react/hooks/useWatch.d.ts +8 -0
- package/fe/packages/ui/react/i18n/I18nProvider.d.ts +18 -0
- package/fe/packages/ui/react/i18n/useI18n.d.ts +4 -0
- package/fe/packages/ui/react/i18n/useI18n.js +4 -0
- package/fe/packages/ui/react/index.js +2 -0
- package/fe/packages/ui/react/lib/export.d.ts +44 -0
- package/fe/packages/ui/react/lib/export.js +40 -0
- package/fe/packages/ui/react/lib/utils.d.ts +24 -0
- package/fe/packages/ui/react/lib/utils.js +25 -0
- package/fe/packages/ui/react/stores/breadcrumb.js +2 -0
- package/model/index.d.ts +2 -0
- package/model/types/data/button.d.ts +32 -0
- package/model/types/data/component.d.ts +61 -0
- package/model/types/data/fetchInfo.d.ts +20 -0
- package/model/types/data/schema.d.ts +98 -0
- package/model/types/data/search.d.ts +7 -0
- package/model/types/index.d.ts +2 -0
- package/model/types/menuType.d.ts +73 -0
- package/model/types/model.d.ts +33 -0
- package/model/types/test.d.ts +2 -0
- package/package.json +10 -7
- package/types/packages/utils/runFileFn.d.ts +5 -3
|
@@ -4,6 +4,12 @@ const HIDDEN_POSITION = {
|
|
|
4
4
|
left: -100,
|
|
5
5
|
};
|
|
6
6
|
const EMPTY_DEPS = [];
|
|
7
|
+
/**
|
|
8
|
+
* 计算弹窗该放在哪。
|
|
9
|
+
*
|
|
10
|
+
* right/left:跟触发元素顶部对齐,往右或往左弹。
|
|
11
|
+
* bottom/top:放在触发元素下方或上方,再按 start/end 对齐。
|
|
12
|
+
*/
|
|
7
13
|
export const getDefaultDropdownPosition = ({ anchorRect, contentRect, containerRect, viewportWidth, placement, offset, matchAnchorWidth, }) => {
|
|
8
14
|
const isRight = placement.startsWith("right");
|
|
9
15
|
const isLeft = placement.startsWith("left");
|
|
@@ -23,6 +29,7 @@ export const getDefaultDropdownPosition = ({ anchorRect, contentRect, containerR
|
|
|
23
29
|
nextPosition.left = anchorRect.right + offset - containerLeft;
|
|
24
30
|
}
|
|
25
31
|
else if (isLeft) {
|
|
32
|
+
// 往左弹时,要知道弹窗宽度,才能算出左边应该从哪里开始。
|
|
26
33
|
nextPosition.left = anchorRect.left - (contentRect?.width ?? 0) - offset - containerLeft;
|
|
27
34
|
}
|
|
28
35
|
else if (placement.endsWith("start")) {
|
|
@@ -37,6 +44,7 @@ export function useDropdownPositioning({ open, anchorRef, contentRef, placement
|
|
|
37
44
|
const [position, setPosition] = useState(HIDDEN_POSITION);
|
|
38
45
|
const [ready, setReady] = useState(false);
|
|
39
46
|
const getContentRect = useCallback(() => {
|
|
47
|
+
// 优先用真实 DOM 尺寸。刚打开时可能还量不到,就允许外部给一个预估尺寸。
|
|
40
48
|
const measuredRect = contentRef.current?.getBoundingClientRect();
|
|
41
49
|
if (measuredRect && measuredRect.height > 0) {
|
|
42
50
|
return measuredRect;
|
|
@@ -49,6 +57,7 @@ export function useDropdownPositioning({ open, anchorRef, contentRef, placement
|
|
|
49
57
|
const updatePosition = useCallback(() => {
|
|
50
58
|
if (!anchorRef.current)
|
|
51
59
|
return;
|
|
60
|
+
// 每次定位前重新读取位置,这样滚动或窗口变化后不会用旧坐标。
|
|
52
61
|
const anchorRect = anchorRef.current.getBoundingClientRect();
|
|
53
62
|
const contentRect = getContentRect();
|
|
54
63
|
const containerRect = positionMode === "absolute"
|
|
@@ -80,16 +89,19 @@ export function useDropdownPositioning({ open, anchorRef, contentRef, placement
|
|
|
80
89
|
]);
|
|
81
90
|
useEffect(() => {
|
|
82
91
|
if (!open) {
|
|
92
|
+
// 关闭时先挪到屏幕外,避免 keepMounted 的弹窗在旧位置闪一下。
|
|
83
93
|
setPosition((returnData.current.position = HIDDEN_POSITION));
|
|
84
94
|
setReady((returnData.current.ready = false));
|
|
85
95
|
return;
|
|
86
96
|
}
|
|
97
|
+
// 打开后等两帧再量尺寸:先让 DOM 挂上去,再让浏览器完成布局。
|
|
87
98
|
const rafId = requestAnimationFrame(() => requestAnimationFrame(updatePosition));
|
|
88
99
|
return () => cancelAnimationFrame(rafId);
|
|
89
100
|
}, [open, updatePosition]);
|
|
90
101
|
useEffect(() => {
|
|
91
102
|
if (!open)
|
|
92
103
|
return;
|
|
104
|
+
// 页面滚动、外层容器滚动、窗口缩放时,都重新算一次位置。
|
|
93
105
|
const handleUpdate = () => updatePosition();
|
|
94
106
|
window.addEventListener("scroll", handleUpdate, true);
|
|
95
107
|
window.addEventListener("resize", handleUpdate);
|
|
@@ -102,11 +114,13 @@ export function useDropdownPositioning({ open, anchorRef, contentRef, placement
|
|
|
102
114
|
useEffect(() => {
|
|
103
115
|
if (!open)
|
|
104
116
|
return;
|
|
117
|
+
// 外部内容变化时,可以通过 watchDeps 主动触发重新定位。
|
|
105
118
|
updatePosition();
|
|
106
119
|
}, [deps, open, updatePosition]);
|
|
107
120
|
useEffect(() => {
|
|
108
121
|
if (!open || !contentRef.current)
|
|
109
122
|
return;
|
|
123
|
+
// 弹窗打开后内容高度/宽度可能变,尺寸变了就重新定位。
|
|
110
124
|
let rafId = 0;
|
|
111
125
|
const observer = new ResizeObserver(() => {
|
|
112
126
|
rafId = requestAnimationFrame(() => requestAnimationFrame(updatePosition));
|
|
@@ -4,6 +4,9 @@ interface IParams<T> {
|
|
|
4
4
|
controlledValue?: string;
|
|
5
5
|
disabled?: boolean;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* 处理ref & 判断是否受控 & 使用的value & value.length
|
|
9
|
+
*/
|
|
7
10
|
export declare const useInputController: <T>(params: IParams<T>) => {
|
|
8
11
|
setRefs: (node: T | null) => void;
|
|
9
12
|
setIsFocused: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* 处理ref & 判断是否受控 & 使用的value & value.length
|
|
4
|
+
*/
|
|
2
5
|
export const useInputController = (params) => {
|
|
3
6
|
const { defaultValue, ref, controlledValue } = params;
|
|
4
7
|
const [isFocused, setIsFocused] = useState(false);
|
|
5
8
|
const [internalValue, setInternalValue] = useState(defaultValue || '');
|
|
6
9
|
const controllerRef = useRef(null);
|
|
10
|
+
// 合并 refs
|
|
7
11
|
const setRefs = useCallback((node) => {
|
|
8
12
|
controllerRef.current = node;
|
|
9
13
|
if (typeof ref === 'function') {
|
|
10
14
|
ref(node);
|
|
11
15
|
}
|
|
12
16
|
else if (ref) {
|
|
17
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
13
18
|
ref.current = node;
|
|
14
19
|
}
|
|
15
20
|
}, [ref]);
|
|
16
21
|
const isControlledRef = useRef(false);
|
|
22
|
+
// 外部传了value
|
|
17
23
|
const isControlled = useMemo(() => {
|
|
18
24
|
const r = controlledValue !== undefined;
|
|
25
|
+
// 当传入的value改变时,更新ref值
|
|
19
26
|
isControlledRef.current = r;
|
|
20
27
|
return r;
|
|
21
28
|
}, [controlledValue]);
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { LayoutDashboard, Package, Settings, Users, FileText, BarChart3, ShoppingCart, Bell, HelpCircle, } from 'lucide-react';
|
|
4
4
|
import { Menu } from '../Menu';
|
|
5
|
+
// ─── 示例数据 ────────────────────────────────────────────────────────────────
|
|
5
6
|
const menuItems = [
|
|
6
7
|
{
|
|
7
8
|
key: 'dashboard',
|
|
@@ -71,9 +72,11 @@ const iconMenuItems = [
|
|
|
71
72
|
{ key: 'notifications', label: 'Notifications', icon: _jsx(Bell, { className: "h-4 w-4" }) },
|
|
72
73
|
{ key: 'help', label: 'Help', icon: _jsx(HelpCircle, { className: "h-4 w-4" }) },
|
|
73
74
|
];
|
|
75
|
+
// ─── 区块包装 ────────────────────────────────────────────────────────────────
|
|
74
76
|
function Section({ title, description, children }) {
|
|
75
77
|
return (_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold", children: title }), description && _jsx("p", { className: "text-sm text-muted-foreground", children: description })] }), children] }));
|
|
76
78
|
}
|
|
79
|
+
// ─── 页面 ────────────────────────────────────────────────────────────────────
|
|
77
80
|
export default function MenuTestPage() {
|
|
78
81
|
const [selectedKey, setSelectedKey] = useState('dashboard');
|
|
79
82
|
const [collapsed, setCollapsed] = useState(false);
|
|
@@ -29,9 +29,11 @@ function ThemeSwitcher() {
|
|
|
29
29
|
}, [mode, theme]);
|
|
30
30
|
return (_jsx(Section, { title: "Theme", children: _jsxs("div", { className: "flex w-full flex-wrap items-center gap-6 rounded-xl border border-border bg-background p-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: "\u6A21\u5F0F" }), _jsx(Button, { variant: mode === 'light' ? 'primary' : 'default', size: "sm", onClick: () => setMode('light'), children: "Light" }), _jsx(Button, { variant: mode === 'dark' ? 'primary' : 'default', size: "sm", onClick: () => setMode('dark'), children: "Dark" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: "\u4E3B\u9898" }), _jsx(Button, { variant: theme === 'default' ? 'primary' : 'default', size: "sm", onClick: () => setTheme('default'), children: "Default" }), _jsx(Button, { variant: theme === 'green' ? 'primary' : 'default', size: "sm", onClick: () => setTheme('green'), children: "Green" }), _jsx(Button, { variant: theme === 'gray' ? 'primary' : 'default', size: "sm", onClick: () => setTheme('gray'), children: "Gray" })] }), _jsxs("div", { className: "text-sm text-muted-foreground", children: ["\u5F53\u524D: ", mode, " / ", theme] })] }) }));
|
|
31
31
|
}
|
|
32
|
+
// ─── Section wrapper ────────────────────────────────────────────────────────
|
|
32
33
|
function Section({ title, children }) {
|
|
33
34
|
return (_jsxs("div", { className: "mb-8", children: [_jsx("h2", { className: "text-lg font-semibold mb-3 border-b pb-1", children: title }), _jsx("div", { className: "flex flex-wrap gap-3 items-start", children: children })] }));
|
|
34
35
|
}
|
|
36
|
+
// ─── Button ─────────────────────────────────────────────────────────────────
|
|
35
37
|
function ButtonDemo() {
|
|
36
38
|
const [loading, setLoading] = useState(false);
|
|
37
39
|
return (_jsxs(Section, { title: "Button", children: [_jsx(Button, { children: "default" }), _jsx(Button, { variant: "primary", children: "primary" }), _jsx(Button, { variant: "dashed", children: "dashed" }), _jsx(Button, { variant: "text", children: "text" }), _jsx(Button, { variant: "link", href: "#button", children: "link" }), _jsx(Button, { state: "danger", children: "danger" }), _jsx(Button, { variant: "primary", state: "danger", children: "primary danger" }), _jsx("div", { className: " bg-red-300 p-1.5", children: _jsx(Button, { state: "ghost", children: "ghost" }) }), _jsx(Button, { variant: "primary", state: "ghost", children: "primary ghost" }), _jsx(Button, { disabled: true, children: "disabled" }), _jsx(Button, { loading: loading, onClick: () => {
|
|
@@ -39,6 +41,7 @@ function ButtonDemo() {
|
|
|
39
41
|
setTimeout(() => setLoading(false), 2000);
|
|
40
42
|
}, children: "loading (click)" }), _jsx(Button, { size: "sm", children: "sm" }), _jsx(Button, { size: "md", children: "md" }), _jsx(Button, { size: "lg", children: "lg" })] }));
|
|
41
43
|
}
|
|
44
|
+
// ─── Input ───────────────────────────────────────────────────────────────────
|
|
42
45
|
function InputDemo() {
|
|
43
46
|
return (_jsxs(Section, { title: "Input", children: [_jsx(Input, { placeholder: "\u666E\u901A\u8F93\u5165\u6846" }), _jsx(Input, { type: "password", placeholder: "\u5BC6\u7801\u8F93\u5165\u6846" }), _jsx(Input, { disabled: true, placeholder: "\u7981\u7528\u72B6\u6001" })] }));
|
|
44
47
|
}
|
|
@@ -47,10 +50,12 @@ function InputNumberDemo() {
|
|
|
47
50
|
const [ratio, setRatio] = useState(0.25);
|
|
48
51
|
return (_jsxs(Section, { title: "InputNumber", children: [_jsx(InputNumber, { placeholder: "\u57FA\u7840\u6570\u5B57\u8F93\u5165", className: "w-48" }), _jsx(InputNumber, { value: price, onChange: setPrice, precision: 2, min: 0, max: 9999, placeholder: "\u4EF7\u683C", addonAfter: _jsx("span", { className: "text-xs text-muted-foreground", children: "CNY" }), className: "w-56" }), _jsx(InputNumber, { value: ratio, onChange: setRatio, precision: 2, step: 0.05, min: 0, max: 1, allowStep: true, placeholder: "\u6BD4\u4F8B", className: "w-48" }), _jsx(InputNumber, { defaultValue: 10, step: 0.5, precision: 1, allowStep: true, allowClear: true, className: "w-48" }), _jsx(InputNumber, { disabled: true, defaultValue: 88.8, precision: 1, className: "w-48" })] }));
|
|
49
52
|
}
|
|
53
|
+
// ─── Textarea ────────────────────────────────────────────────────────────────
|
|
50
54
|
function TextareaDemo() {
|
|
51
55
|
const [val, setVal] = useState('');
|
|
52
56
|
return (_jsxs(Section, { title: "Textarea", children: [_jsx(Textarea, { placeholder: "\u8BF7\u8F93\u5165\u5185\u5BB9\uFF08\u6700\u591A 500 \u5B57\uFF09", value: val, onChange: (v) => setVal(v), className: "w-80" }), _jsx(Textarea, { placeholder: "\u4E0D\u663E\u793A\u8BA1\u6570", showCount: false, className: "w-80" })] }));
|
|
53
57
|
}
|
|
58
|
+
// ─── Select ──────────────────────────────────────────────────────────────────
|
|
54
59
|
function SelectDemo() {
|
|
55
60
|
const [val, setVal] = useState(undefined);
|
|
56
61
|
const options = [
|
|
@@ -60,17 +65,21 @@ function SelectDemo() {
|
|
|
60
65
|
];
|
|
61
66
|
return (_jsxs(Section, { title: "Select", children: [_jsx(Select, { options: options, value: val, onChange: setVal, placeholder: "\u8BF7\u9009\u62E9", className: "w-40" }), _jsx(Select, { options: options, placeholder: "\u4E0D\u53EF\u641C\u7D22", searchable: false, className: "w-40" }), _jsx(Select, { options: options, placeholder: "\u4E0D\u53EF\u6E05\u9664", clearable: false, className: "w-40" }), _jsx(Select, { options: options, disabled: true, placeholder: "\u7981\u7528", className: "w-40" }), _jsxs("div", { className: "relative w-64 rounded-lg border border-border bg-muted/30 p-4", children: [_jsx("div", { className: "mb-2 text-sm text-muted-foreground", children: "parent popup container" }), _jsx(Select, { options: options, placeholder: "\u6302\u8F7D\u5230\u7236\u5143\u7D20", getPopupContainer: "parent", className: "w-full" })] })] }));
|
|
62
67
|
}
|
|
68
|
+
// ─── Checkbox ────────────────────────────────────────────────────────────────
|
|
63
69
|
function CheckboxDemo() {
|
|
64
70
|
const [checked, setChecked] = useState(false);
|
|
65
71
|
return (_jsxs(Section, { title: "Checkbox", children: [_jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx(Checkbox, { checked: checked, onChange: (c) => setChecked(c) }), _jsxs("span", { children: ["\u53D7\u63A7: ", checked ? '选中' : '未选中'] })] }), _jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx(Checkbox, { defaultChecked: true }), _jsx("span", { children: "\u975E\u53D7\u63A7\u9ED8\u8BA4\u9009\u4E2D" })] }), _jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx(Checkbox, { indeterminate: true }), _jsx("span", { children: "\u534A\u9009\u72B6\u6001" })] }), _jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx(Checkbox, { disabled: true }), _jsx("span", { children: "\u7981\u7528" })] })] }));
|
|
66
72
|
}
|
|
73
|
+
// ─── Switch ──────────────────────────────────────────────────────────────────
|
|
67
74
|
function SwitchDemo() {
|
|
68
75
|
const [on, setOn] = useState(false);
|
|
69
76
|
return (_jsxs(Section, { title: "Switch", children: [_jsx(Switch, { checked: on, onChange: setOn }), _jsx("span", { className: "self-center text-sm", children: on ? 'ON' : 'OFF' }), _jsx(Switch, { defaultChecked: true }), _jsx(Switch, { disabled: true }), _jsx(Switch, { disabled: true, checked: true })] }));
|
|
70
77
|
}
|
|
78
|
+
// ─── Tooltip ─────────────────────────────────────────────────────────────────
|
|
71
79
|
function TooltipDemo() {
|
|
72
80
|
return (_jsx(Section, { title: "Tooltip", children: ['top', 'bottom', 'left', 'right'].map((p) => (_jsx(Tooltip, { content: `placement: ${p}`, placement: p, children: _jsx(Button, { children: p }) }, p))) }));
|
|
73
81
|
}
|
|
82
|
+
// ─── Dropdown ────────────────────────────────────────────────────────────────
|
|
74
83
|
function DropdownDemo() {
|
|
75
84
|
const items = [
|
|
76
85
|
{ key: 'edit', label: '编辑', onClick: () => console.log('edit') },
|
|
@@ -79,12 +88,14 @@ function DropdownDemo() {
|
|
|
79
88
|
];
|
|
80
89
|
return (_jsxs(Section, { title: "Dropdown", children: [_jsx(Dropdown, { items: items, children: _jsx(Button, { children: "\u64CD\u4F5C \u25BE" }) }), _jsx(Dropdown, { items: items, placement: "bottom-start", children: _jsx(Button, { variant: "text", children: "bottom-start \u25BE" }) })] }));
|
|
81
90
|
}
|
|
91
|
+
// ─── Message ─────────────────────────────────────────────────────────────────
|
|
82
92
|
function MessageDemo() {
|
|
83
93
|
return (_jsxs(Section, { title: "Message (imperative)", children: [_jsx(Button, { onClick: () => message.success('操作成功'), children: "success" }), _jsx(Button, { onClick: () => message.error('操作失败'), children: "error" }), _jsx(Button, { onClick: () => message.warning('警告信息'), children: "warning" }), _jsx(Button, { onClick: () => message.info('提示信息'), children: "info" }), _jsx(Button, { onClick: () => {
|
|
84
94
|
const id = message.success('5秒后关闭', { duration: 5000 });
|
|
85
95
|
setTimeout(() => message.close(id), 2000);
|
|
86
96
|
}, children: "\u63D0\u524D\u5173\u95ED" })] }));
|
|
87
97
|
}
|
|
98
|
+
// ─── Modal ───────────────────────────────────────────────────────────────────
|
|
88
99
|
function ModalDemo() {
|
|
89
100
|
const [open, setOpen] = useState(false);
|
|
90
101
|
return (_jsxs(Section, { title: "Modal", children: [_jsx(Button, { onClick: () => setOpen(true), children: "JSX Modal" }), _jsx(Button, { onClick: () => modal.open({
|
|
@@ -101,6 +112,7 @@ function ModalDemo() {
|
|
|
101
112
|
},
|
|
102
113
|
}), children: "modal.confirm" }), _jsxs(Modal, { open: open, onClose: () => setOpen(false), title: "JSX \u5F39\u7A97", children: [_jsx("p", { children: "\u8FD9\u662F\u4E00\u4E2A\u4F7F\u7528 JSX \u63A7\u5236\u7684\u5F39\u7A97\u3002" }), _jsx("div", { className: "mt-4 flex justify-end gap-2", children: _jsx(Button, { onClick: () => setOpen(false), children: "\u5173\u95ED" }) })] })] }));
|
|
103
114
|
}
|
|
115
|
+
// ─── Drawer ──────────────────────────────────────────────────────────────────
|
|
104
116
|
function DrawerDemo() {
|
|
105
117
|
const [placement, setPlacement] = useState('right');
|
|
106
118
|
const [open, setOpen] = useState(false);
|
|
@@ -116,6 +128,7 @@ function DrawerDemo() {
|
|
|
116
128
|
{ label: '停用', value: 'disabled' },
|
|
117
129
|
] }) })] })] }) })] }));
|
|
118
130
|
}
|
|
131
|
+
// ─── ConfirmDialog ───────────────────────────────────────────────────────────
|
|
119
132
|
function ConfirmDialogDemo() {
|
|
120
133
|
const [open, setOpen] = useState(false);
|
|
121
134
|
return (_jsxs(Section, { title: "ConfirmDialog", children: [_jsx(Button, { onClick: () => setOpen(true), children: "\u6253\u5F00\u786E\u8BA4\u6846" }), _jsx(ConfirmDialog, { open: open, title: "\u5220\u9664\u786E\u8BA4", content: "\u786E\u5B9A\u8981\u5220\u9664\u6B64\u6761\u6570\u636E\u5417\uFF1F\u6B64\u64CD\u4F5C\u4E0D\u53EF\u64A4\u9500\u3002", onOk: () => {
|
|
@@ -123,11 +136,13 @@ function ConfirmDialogDemo() {
|
|
|
123
136
|
setOpen(false);
|
|
124
137
|
}, onCancel: () => setOpen(false) })] }));
|
|
125
138
|
}
|
|
139
|
+
// ─── Pagination ───────────────────────────────────────────────────────────────
|
|
126
140
|
function PaginationDemo() {
|
|
127
141
|
const [page, setPage] = useState(1);
|
|
128
142
|
const [pageSize, setPageSize] = useState(10);
|
|
129
143
|
return (_jsx(Section, { title: "Pagination", children: _jsxs("div", { className: "w-full", children: [_jsxs("p", { className: "text-sm mb-2", children: ["\u5F53\u524D\u9875: ", page, " / \u6BCF\u9875: ", pageSize] }), _jsx(Pagination, { current: page, pageSize: pageSize, total: 238, onChange: setPage, onPageSizeChange: setPageSize })] }) }));
|
|
130
144
|
}
|
|
145
|
+
// ─── Table (低层组件) ─────────────────────────────────────────────────────────
|
|
131
146
|
function TableDemo() {
|
|
132
147
|
const rows = [
|
|
133
148
|
{ id: 1, name: '张三', role: '管理员', status: '正常' },
|
|
@@ -156,6 +171,7 @@ function DataTableDemo() {
|
|
|
156
171
|
onChange: (keys) => setSelectedKeys(keys),
|
|
157
172
|
} })] }) }));
|
|
158
173
|
}
|
|
174
|
+
// ─── Search ───────────────────────────────────────────────────────────────────
|
|
159
175
|
function SearchDemo() {
|
|
160
176
|
return (_jsx(Section, { title: "Search", children: _jsx("div", { className: "w-full", children: _jsxs(Search, { schemas: [
|
|
161
177
|
{ type: 'input', key: 'keyword', label: '关键字', fieldProps: { placeholder: '请输入' } },
|
|
@@ -173,6 +189,7 @@ function SearchDemo() {
|
|
|
173
189
|
},
|
|
174
190
|
], children: [_jsx(Button, { type: "submit", variant: "primary", children: "\u641C\u7D22" }), _jsx(Button, { type: "reset", children: "\u91CD\u7F6E" })] }) }) }));
|
|
175
191
|
}
|
|
192
|
+
// ─── Breadcrumb ───────────────────────────────────────────────────────────────
|
|
176
193
|
function BreadcrumbDemo() {
|
|
177
194
|
const [items, setItems] = useState([
|
|
178
195
|
{ id: 'home', label: '首页' },
|
|
@@ -181,13 +198,16 @@ function BreadcrumbDemo() {
|
|
|
181
198
|
]);
|
|
182
199
|
return (_jsx(Section, { title: "Breadcrumb", children: _jsx(Breadcrumb, { children: _jsx(BreadcrumbList, { children: items.map((item, idx) => (_jsxs(React.Fragment, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { active: item.active, onClose: () => setItems((prev) => prev.filter((i) => i.id !== item.id)), onClick: () => setItems((prev) => prev.map((i) => ({ ...i, active: i.id === item.id }))), className: "cursor-pointer", children: item.label }) }), idx < items.length - 1 && _jsx(BreadcrumbSeparator, {})] }, item.id))) }) }) }));
|
|
183
200
|
}
|
|
201
|
+
// ─── Label ────────────────────────────────────────────────────────────────────
|
|
184
202
|
function LabelDemo() {
|
|
185
203
|
return (_jsxs(Section, { title: "Label", children: [_jsx(Label, { label: "\u6C34\u5E73\u5E03\u5C40", layout: "horizontal", children: _jsx("span", { className: "text-sm", children: "\u5185\u5BB9\u533A\u57DF" }) }), _jsx(Label, { label: "\u5782\u76F4\u5E03\u5C40", layout: "vertical", children: _jsx("span", { className: "text-sm", children: "\u5185\u5BB9\u533A\u57DF" }) })] }));
|
|
186
204
|
}
|
|
205
|
+
// ─── Form ─────────────────────────────────────────────────────────────────────
|
|
187
206
|
function FormDemo() {
|
|
188
207
|
const [form] = useForm();
|
|
189
208
|
return (_jsx(Section, { title: "Form", children: _jsxs(Form, { form: form, onFinish: (v) => console.log('表单值:', v), children: [_jsx(FormItem, { name: "username", label: "\u7528\u6237\u540D", required: true, rules: [{ required: true, message: '请输入用户名' }], children: _jsx(Input, { placeholder: "\u8BF7\u8F93\u5165\u7528\u6237\u540D" }) }), _jsx(FormItem, { name: "password", label: "\u5BC6\u7801", required: true, rules: [{ required: true, message: '请输入密码' }], children: _jsx(Input, { type: "password", placeholder: "\u8BF7\u8F93\u5165\u5BC6\u7801" }) }), _jsx(Button, { type: "submit", children: "\u63D0\u4EA4" })] }) }));
|
|
190
209
|
}
|
|
210
|
+
// ─── SchemaForm ───────────────────────────────────────────────────────────────
|
|
191
211
|
function SchemaFormDemo() {
|
|
192
212
|
const form = useRef(undefined);
|
|
193
213
|
return (_jsx(Section, { title: "SchemaForm", children: _jsx(SchemaForm, { layout: "horizontal", getForm: (f) => {
|
|
@@ -215,6 +235,7 @@ function SchemaFormDemo() {
|
|
|
215
235
|
},
|
|
216
236
|
], onFinish: (values) => console.log(values) }) }));
|
|
217
237
|
}
|
|
238
|
+
// ─── TableSearch ─────────────────────────────────────────────────────────────
|
|
218
239
|
function TableSearchDemo() {
|
|
219
240
|
return (_jsx(Section, { title: "TableSearch", children: _jsx(TableSearch, { onSearch: (v) => console.log(v), schemas: [
|
|
220
241
|
{ type: 'input', key: 'q1', label: '字段1', fieldProps: {} },
|
|
@@ -227,9 +248,11 @@ function TableSearchDemo() {
|
|
|
227
248
|
{ type: 'input', key: 'q8', label: '字段8', fieldProps: {} },
|
|
228
249
|
] }) }));
|
|
229
250
|
}
|
|
251
|
+
// ─── Skeleton ─────────────────────────────────────────────────────────────────
|
|
230
252
|
function SkeletonDemo() {
|
|
231
253
|
return (_jsx(Section, { title: "Skeleton", children: _jsxs("div", { className: "w-full space-y-4", children: [_jsxs("div", { children: [_jsx("p", { className: "text-xs text-gray-500 mb-1", children: "pageloading" }), _jsx(Skeleton, { mode: "pageloading", rows: 3, showTitle: true, showActions: true })] }), _jsxs("div", { children: [_jsx("p", { className: "text-xs text-gray-500 mb-1", children: "tableloading" }), _jsx(Skeleton, { mode: "tableloading", rows: 4 })] }), _jsxs("div", { children: [_jsx("p", { className: "text-xs text-gray-500 mb-1", children: "componentsloading" }), _jsx(Skeleton, { mode: "componentsloading", rows: 2 })] })] }) }));
|
|
232
254
|
}
|
|
255
|
+
// ─── TreeSelect ───────────────────────────────────────────────────────────────
|
|
233
256
|
function TreeSelectDemo() {
|
|
234
257
|
const [value, setValue] = useState(['1.1.1', '1.1.2']);
|
|
235
258
|
const [indeterminate, setIndeterminate] = useState([]);
|
|
@@ -269,6 +292,7 @@ function TreeSelectDemo() {
|
|
|
269
292
|
setIndeterminate(indeterminate);
|
|
270
293
|
} })] }) }));
|
|
271
294
|
}
|
|
295
|
+
// ─── PreviewImage ─────────────────────────────────────────────────────────────
|
|
272
296
|
function PreviewImageDemo() {
|
|
273
297
|
const images = [
|
|
274
298
|
'https://images.unsplash.com/photo-1778512828600-4a6540a1a115?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxmZWF0dXJlZC1waG90b3MtZmVlZHw0fHx8ZW58MHx8fHx8',
|
|
@@ -276,12 +300,14 @@ function PreviewImageDemo() {
|
|
|
276
300
|
];
|
|
277
301
|
return (_jsx(Section, { title: "PreviewImage", children: _jsx(PreviewImage, { images: images, initialIndex: 0 }) }));
|
|
278
302
|
}
|
|
303
|
+
// ─── ImageUpload ─────────────────────────────────────────────────────────────
|
|
279
304
|
function ImageUploadDemo() {
|
|
280
305
|
return (_jsx(Section, { title: "ImageUpload", children: _jsx(ImageUpload, { accept: ".jpg,.png", maxCount: 4, beforeChange: (f) => {
|
|
281
306
|
console.log(f);
|
|
282
307
|
return parseInt(Math.random() * 10 + '') % 2 === 0;
|
|
283
308
|
} }) }));
|
|
284
309
|
}
|
|
310
|
+
// ─── Main ─────────────────────────────────────────────────────────────────────
|
|
285
311
|
const TestPage = () => {
|
|
286
312
|
return (_jsxs("div", { className: "p-6 max-w-5xl mx-auto", children: [_jsx("h1", { className: "text-2xl font-bold mb-6", children: "\u7EC4\u4EF6\u5C55\u793A" }), _jsx(ThemeSwitcher, {}), _jsx(ButtonDemo, {}), _jsx(InputDemo, {}), _jsx(InputNumberDemo, {}), _jsx(TextareaDemo, {}), _jsx(SelectDemo, {}), _jsx(CheckboxDemo, {}), _jsx(SwitchDemo, {}), _jsx(TooltipDemo, {}), _jsx(DropdownDemo, {}), _jsx(MessageDemo, {}), _jsx(ModalDemo, {}), _jsx(DrawerDemo, {}), _jsx(ConfirmDialogDemo, {}), _jsx(PaginationDemo, {}), _jsx(TableDemo, {}), _jsx(DataTableDemo, {}), _jsx(SearchDemo, {}), _jsx(BreadcrumbDemo, {}), _jsx(LabelDemo, {}), _jsx(FormDemo, {}), _jsx(SchemaFormDemo, {}), _jsx(TableSearchDemo, {}), _jsx(SkeletonDemo, {}), _jsx(TreeSelectDemo, {}), _jsx(DateTestPage, {}), _jsx(PreviewImageDemo, {}), _jsx(ImageUploadDemo, {}), _jsx(MenuTestPage, {})] }));
|
|
287
313
|
};
|
|
@@ -5,7 +5,25 @@ export declare const executionPhaseType: {
|
|
|
5
5
|
};
|
|
6
6
|
type ExecutionPhaseTypeKeys = keyof typeof executionPhaseType;
|
|
7
7
|
export type ExecutionPhaseType = (typeof executionPhaseType)[ExecutionPhaseTypeKeys];
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @description 在各个阶段只触发一次
|
|
11
|
+
* @demo
|
|
12
|
+
* ```
|
|
13
|
+
const count = useExecuteOnce(() => {
|
|
14
|
+
console.log('123'); // 只会在第一次render时触发
|
|
15
|
+
return 123
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
// count 123
|
|
19
|
+
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export default function useExecuteOnce<T>(factory: () => T,
|
|
23
|
+
/**
|
|
24
|
+
* @default executionPhase = render
|
|
25
|
+
*/
|
|
26
|
+
options?: {
|
|
9
27
|
executionPhase: ExecutionPhaseType[] | ExecutionPhaseType;
|
|
10
28
|
}): T | null;
|
|
11
29
|
export {};
|
|
@@ -4,11 +4,32 @@ export const executionPhaseType = {
|
|
|
4
4
|
render: 'render',
|
|
5
5
|
unMount: 'unMount',
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
// type ExecutionPhaseType =
|
|
8
|
+
// (typeof executionPhaseType)[keyof typeof executionPhaseType];
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @description 在各个阶段只触发一次
|
|
12
|
+
* @demo
|
|
13
|
+
* ```
|
|
14
|
+
const count = useExecuteOnce(() => {
|
|
15
|
+
console.log('123'); // 只会在第一次render时触发
|
|
16
|
+
return 123
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
// count 123
|
|
20
|
+
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export default function useExecuteOnce(factory,
|
|
24
|
+
/**
|
|
25
|
+
* @default executionPhase = render
|
|
26
|
+
*/
|
|
27
|
+
options) {
|
|
8
28
|
const { executionPhase: pExecutionPhase = executionPhaseType.render } = options ?? {};
|
|
9
29
|
const result = useRef(null);
|
|
10
30
|
const _executionPhase = useMemo(() => (typeof pExecutionPhase === 'string' ? [pExecutionPhase] : pExecutionPhase), [pExecutionPhase]);
|
|
11
31
|
const allowExecution = useRef([]);
|
|
32
|
+
// 跳过依赖;
|
|
12
33
|
const executionPhase = useRef(_executionPhase);
|
|
13
34
|
const runFN = (phase) => {
|
|
14
35
|
if (!allowExecution.current.includes(phase)) {
|
|
@@ -4,6 +4,18 @@ type CallBackFN<T> = (value: T) => void;
|
|
|
4
4
|
type RefState<T> = RefObject<{
|
|
5
5
|
data: T;
|
|
6
6
|
}>;
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @demo
|
|
10
|
+
* ```
|
|
11
|
+
const [data, setData, dataRef] = useState(0);
|
|
12
|
+
|
|
13
|
+
setData(1, (newData) => {
|
|
14
|
+
// newData 1
|
|
15
|
+
// data 0
|
|
16
|
+
})
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
7
19
|
export default function useRefState<S>(initialState: S | (() => S)): [
|
|
8
20
|
S,
|
|
9
21
|
SetState<S>,
|
|
@@ -3,7 +3,15 @@ export type WatchCompare<T> = (value: T, prevValue: T) => boolean;
|
|
|
3
3
|
export type WatchCompareType = 'identity' | 'shallow';
|
|
4
4
|
export type WatchSelector<TSource, TValue> = (source: TSource) => TValue;
|
|
5
5
|
export type UseWatchOptions<T> = {
|
|
6
|
+
/**
|
|
7
|
+
* @default false
|
|
8
|
+
*/
|
|
6
9
|
immediate?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Return true when the two values should be treated as equal.
|
|
12
|
+
*
|
|
13
|
+
* @default Array values use shallow compare, other values use Object.is.
|
|
14
|
+
*/
|
|
7
15
|
compare?: WatchCompareType | WatchCompare<T>;
|
|
8
16
|
};
|
|
9
17
|
export declare const identityCompare: <T>(value: T, prevValue: T) => boolean;
|
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
import type { I18nLanguage, I18nResources } from '../../../common/i18n';
|
|
2
2
|
import { type ReactNode } from 'react';
|
|
3
3
|
export interface I18nProviderProps {
|
|
4
|
+
/**
|
|
5
|
+
* 外部控制的显示语言。
|
|
6
|
+
*/
|
|
4
7
|
language?: I18nLanguage;
|
|
8
|
+
/**
|
|
9
|
+
* 未命中当前语言文案时的兜底语言。
|
|
10
|
+
*/
|
|
5
11
|
fallbackLanguage?: I18nLanguage;
|
|
12
|
+
/**
|
|
13
|
+
* 业务侧注入的多语言资源。
|
|
14
|
+
*/
|
|
6
15
|
resources?: I18nResources;
|
|
16
|
+
/**
|
|
17
|
+
* 是否把传入 resources 和现有 resources 合并。默认 true。
|
|
18
|
+
*/
|
|
7
19
|
mergeResources?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* 是否把 language 写入 localStorage。默认 true。
|
|
22
|
+
*/
|
|
8
23
|
persist?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* localStorage key。
|
|
26
|
+
*/
|
|
9
27
|
storageKey?: string;
|
|
10
28
|
children: ReactNode;
|
|
11
29
|
}
|
|
@@ -5,5 +5,9 @@ export declare const useI18nStore: import("..").StoreHook<{
|
|
|
5
5
|
setState: (partial: Partial<import("../../../common/index.js").I18nStore> | ((state: import("../../../common/index.js").I18nStore) => Partial<import("../../../common/index.js").I18nStore>)) => void;
|
|
6
6
|
subscribe: (listener: import("../../../common/index.js").I18nStoreListener) => () => void;
|
|
7
7
|
}>;
|
|
8
|
+
/**
|
|
9
|
+
* React 组件内使用的翻译 hook。
|
|
10
|
+
* 会订阅 language、fallbackLanguage、resources,语言或资源变化时触发组件更新。
|
|
11
|
+
*/
|
|
8
12
|
export declare function useI18n(): <T = string>(key: string, fillingData?: I18nInterpolationValues, options?: I18nTranslateOptions) => string | T;
|
|
9
13
|
//# sourceMappingURL=useI18n.d.ts.map
|
|
@@ -2,6 +2,10 @@ import { i18nStore, translate } from '../../../common/i18n';
|
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
import { createStoreHook } from '../lib/createStoreHook';
|
|
4
4
|
export const useI18nStore = createStoreHook(i18nStore);
|
|
5
|
+
/**
|
|
6
|
+
* React 组件内使用的翻译 hook。
|
|
7
|
+
* 会订阅 language、fallbackLanguage、resources,语言或资源变化时触发组件更新。
|
|
8
|
+
*/
|
|
5
9
|
export function useI18n() {
|
|
6
10
|
const language = useI18nStore((state) => state.language);
|
|
7
11
|
const fallbackLanguage = useI18nStore((state) => state.fallbackLanguage);
|
|
@@ -1,22 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 导出 Excel 工具方法
|
|
3
|
+
*
|
|
4
|
+
* 功能:
|
|
5
|
+
* - 支持导出「当前页」或「当前查询条件下的全部页数据」
|
|
6
|
+
* - 通过 DataTable 的 columns 控制导出列及顺序
|
|
7
|
+
*
|
|
8
|
+
* 使用方式(示例):
|
|
9
|
+
* ```ts
|
|
10
|
+
* await exportToExcel({
|
|
11
|
+
* fetchData: (pageNum, pageSize) => getWithdrawList({ ...searchParams, pageNum, pageSize }),
|
|
12
|
+
* columns, // 直接复用 DataTable 的 columns
|
|
13
|
+
* exportType: 'all', // 'all' 导出全部页;'current' 仅导出当前页
|
|
14
|
+
* currentPage,
|
|
15
|
+
* pageSize,
|
|
16
|
+
* total,
|
|
17
|
+
* currentPageData: tableData, // 可选,导出当前页时直接使用现有数据,避免重复请求
|
|
18
|
+
* fileName: '提币记录',
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
1
22
|
import { type TableColumnDef } from '../components';
|
|
2
23
|
export declare const ExportType: {
|
|
24
|
+
/**
|
|
25
|
+
* 当前查询条件下所有页
|
|
26
|
+
*/
|
|
3
27
|
readonly all: 0;
|
|
28
|
+
/**
|
|
29
|
+
* 当前页
|
|
30
|
+
*/
|
|
4
31
|
readonly current: 1;
|
|
5
32
|
};
|
|
6
33
|
export type ExportType = (typeof ExportType)[keyof typeof ExportType];
|
|
7
34
|
interface ExportExcelParams<T> {
|
|
35
|
+
/** 获取数据方法 */
|
|
8
36
|
fetchData: (pageNum: number, pageSize: number, searchParams?: Record<string, any>) => Promise<{
|
|
9
37
|
records: T[];
|
|
10
38
|
total: number;
|
|
11
39
|
}>;
|
|
40
|
+
/** 直接复用 DataTable 的 columns 配置 会自动过滤 操作栏*/
|
|
12
41
|
columns: TableColumnDef<T>[];
|
|
42
|
+
/** 导出类型:all=当前查询条件下所有页;current=当前页 */
|
|
13
43
|
exportType: ExportType;
|
|
44
|
+
/** 当前页码(导出当前页时使用)默认 1 */
|
|
14
45
|
currentPage?: number;
|
|
46
|
+
/** 每页条数,默认 2000 */
|
|
15
47
|
pageSize?: number;
|
|
48
|
+
/**
|
|
49
|
+
* 最大导出条数,超过则停止继续请求
|
|
50
|
+
* @default 10000
|
|
51
|
+
*/
|
|
16
52
|
maxCount?: number;
|
|
53
|
+
/**
|
|
54
|
+
* 当前页已有数据
|
|
55
|
+
* - 当 exportType === 'current' 且传入该字段时,将直接使用该数据,不会再次请求接口
|
|
56
|
+
*/
|
|
17
57
|
currentPageData?: T[];
|
|
58
|
+
/** 文件名(不含扩展名),默认:export-YYYYMMDDHHmmss */
|
|
18
59
|
fileName?: string;
|
|
19
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* 通用导出 Excel 方法
|
|
63
|
+
*/
|
|
20
64
|
export declare function exportToExcel<T>(options: ExportExcelParams<T>): Promise<void>;
|
|
21
65
|
export {};
|
|
22
66
|
//# sourceMappingURL=export.d.ts.map
|