@creekjs/web-components 1.0.2 → 1.0.3
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/.fatherrc.ts +1 -5
- package/.turbo/turbo-father$colon$build.log +5 -0
- package/.turbo/turbo-father$colon$dev.log +33 -0
- package/dist/creek-config-provider/CreekConfigContext.js +31 -2
- package/dist/creek-config-provider/CreekConfigContext.js.map +7 -0
- package/dist/creek-config-provider/index.js +35 -13
- package/dist/creek-config-provider/index.js.map +7 -0
- package/dist/creek-hooks/index.d.ts +1 -0
- package/dist/creek-hooks/index.js +26 -1
- package/dist/creek-hooks/index.js.map +7 -0
- package/dist/creek-hooks/useApp/DrawerHelper.d.ts +9 -0
- package/dist/creek-hooks/useApp/DrawerHelper.js +62 -0
- package/dist/creek-hooks/useApp/DrawerHelper.js.map +7 -0
- package/dist/creek-hooks/useApp/ModalHelper.d.ts +9 -0
- package/dist/creek-hooks/useApp/ModalHelper.js +62 -0
- package/dist/creek-hooks/useApp/ModalHelper.js.map +7 -0
- package/dist/creek-hooks/useApp/index.d.ts +25 -0
- package/dist/creek-hooks/useApp/index.js +118 -0
- package/dist/creek-hooks/useApp/index.js.map +7 -0
- package/dist/creek-hooks/useApp/types.d.ts +26 -0
- package/dist/creek-hooks/useApp/types.js +18 -0
- package/dist/creek-hooks/useApp/types.js.map +7 -0
- package/dist/creek-hooks/useViewportHeight.js +99 -97
- package/dist/creek-hooks/useViewportHeight.js.map +7 -0
- package/dist/creek-icon/index.js +53 -31
- package/dist/creek-icon/index.js.map +7 -0
- package/dist/creek-keep-alive/index.js +36 -18
- package/dist/creek-keep-alive/index.js.map +7 -0
- package/dist/creek-layout/CollapseButton.js +69 -47
- package/dist/creek-layout/CollapseButton.js.map +7 -0
- package/dist/creek-layout/Exception/NotFound.js +42 -13
- package/dist/creek-layout/Exception/NotFound.js.map +7 -0
- package/dist/creek-layout/Exception/NotFoundPage.js +30 -5
- package/dist/creek-layout/Exception/NotFoundPage.js.map +7 -0
- package/dist/creek-layout/Exception/index.js +37 -8
- package/dist/creek-layout/Exception/index.js.map +7 -0
- package/dist/creek-layout/HeaderContent/FullScreen.js +45 -39
- package/dist/creek-layout/HeaderContent/FullScreen.js.map +7 -0
- package/dist/creek-layout/HeaderContent/UserInfo.js +75 -53
- package/dist/creek-layout/HeaderContent/UserInfo.js.map +7 -0
- package/dist/creek-layout/HeaderContent/index.js +48 -28
- package/dist/creek-layout/HeaderContent/index.js.map +7 -0
- package/dist/creek-layout/index.js +117 -81
- package/dist/creek-layout/index.js.map +7 -0
- package/dist/creek-loading/index.js +55 -48
- package/dist/creek-loading/index.js.map +7 -0
- package/dist/creek-table/SearchTable.js +107 -116
- package/dist/creek-table/SearchTable.js.map +7 -0
- package/dist/creek-table/TableOptionRender.js +69 -60
- package/dist/creek-table/TableOptionRender.js.map +7 -0
- package/dist/creek-table/TableViewContent.js +59 -40
- package/dist/creek-table/TableViewContent.js.map +7 -0
- package/dist/creek-table/hooks/index.d.ts +1 -1
- package/dist/creek-table/hooks/index.js +28 -3
- package/dist/creek-table/hooks/index.js.map +7 -0
- package/dist/creek-table/hooks/useAdaptiveToolBar.js +48 -36
- package/dist/creek-table/hooks/useAdaptiveToolBar.js.map +7 -0
- package/dist/creek-table/hooks/useAutoWidthColumns.d.ts +6 -0
- package/dist/creek-table/hooks/useAutoWidthColumns.js +187 -0
- package/dist/creek-table/hooks/useAutoWidthColumns.js.map +7 -0
- package/dist/creek-table/hooks/useElementDistance.js +51 -39
- package/dist/creek-table/hooks/useElementDistance.js.map +7 -0
- package/dist/creek-table/index.js +35 -25
- package/dist/creek-table/index.js.map +7 -0
- package/dist/creek-table/toolBarRender.js +55 -33
- package/dist/creek-table/toolBarRender.js.map +7 -0
- package/dist/creek-table/type.d.ts +1 -1
- package/dist/creek-table/type.js +18 -1
- package/dist/creek-table/type.js.map +7 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +34 -7
- package/dist/index.js.map +7 -0
- package/package.json +2 -2
- package/src/creek-hooks/index.ts +2 -0
- package/src/creek-hooks/useApp/DrawerHelper.tsx +43 -0
- package/src/creek-hooks/useApp/ModalHelper.tsx +43 -0
- package/src/creek-hooks/useApp/index.tsx +119 -0
- package/src/creek-hooks/useApp/types.ts +25 -0
- package/src/creek-hooks/useViewportHeight.tsx +34 -5
- package/src/creek-table/SearchTable.tsx +16 -37
- package/src/creek-table/TableViewContent.tsx +21 -14
- package/src/creek-table/hooks/index.ts +1 -1
- package/src/creek-table/hooks/useAutoWidthColumns.tsx +212 -0
- package/src/creek-table/index.tsx +1 -5
- package/src/creek-table/type.ts +1 -1
- package/src/index.tsx +2 -2
- package/dist/bg-center/index.d.ts +0 -5
- package/dist/bg-center/index.d.ts.map +0 -1
- package/dist/bg-center/index.js +0 -28
- package/dist/creek-config-provider/CreekConfigContext.d.ts.map +0 -1
- package/dist/creek-config-provider/index.d.ts.map +0 -1
- package/dist/creek-hooks/index.d.ts.map +0 -1
- package/dist/creek-hooks/useViewportHeight.d.ts.map +0 -1
- package/dist/creek-icon/index.d.ts.map +0 -1
- package/dist/creek-keep-alive/index.d.ts.map +0 -1
- package/dist/creek-layout/CollapseButton.d.ts.map +0 -1
- package/dist/creek-layout/Exception/NotFound.d.ts.map +0 -1
- package/dist/creek-layout/Exception/NotFoundPage.d.ts.map +0 -1
- package/dist/creek-layout/Exception/index.d.ts.map +0 -1
- package/dist/creek-layout/HeaderContent/FullScreen.d.ts.map +0 -1
- package/dist/creek-layout/HeaderContent/UserInfo.d.ts.map +0 -1
- package/dist/creek-layout/HeaderContent/index.d.ts.map +0 -1
- package/dist/creek-layout/index.d.ts.map +0 -1
- package/dist/creek-loading/index.d.ts.map +0 -1
- package/dist/creek-search/CreekSearch.d.ts +0 -7
- package/dist/creek-search/CreekSearch.d.ts.map +0 -1
- package/dist/creek-search/CreekSearch.js +0 -51
- package/dist/creek-search/CreekSearchContext.d.ts +0 -54
- package/dist/creek-search/CreekSearchContext.d.ts.map +0 -1
- package/dist/creek-search/CreekSearchContext.js +0 -546
- package/dist/creek-search/CreekSearchFilterDisplay.d.ts +0 -5
- package/dist/creek-search/CreekSearchFilterDisplay.d.ts.map +0 -1
- package/dist/creek-search/CreekSearchFilterDisplay.js +0 -97
- package/dist/creek-search/CreekSearchInput.d.ts +0 -4
- package/dist/creek-search/CreekSearchInput.d.ts.map +0 -1
- package/dist/creek-search/CreekSearchInput.js +0 -96
- package/dist/creek-search/CreekSearchValueSelector.d.ts +0 -5
- package/dist/creek-search/CreekSearchValueSelector.d.ts.map +0 -1
- package/dist/creek-search/CreekSearchValueSelector.js +0 -422
- package/dist/creek-search/index.d.ts +0 -5
- package/dist/creek-search/index.d.ts.map +0 -1
- package/dist/creek-search/index.js +0 -5
- package/dist/creek-search/type.d.ts +0 -8
- package/dist/creek-search/type.d.ts.map +0 -1
- package/dist/creek-search/type.js +0 -1
- package/dist/creek-table/SearchTable.d.ts.map +0 -1
- package/dist/creek-table/TableOptionRender.d.ts.map +0 -1
- package/dist/creek-table/TableViewContent.d.ts.map +0 -1
- package/dist/creek-table/hooks/index.d.ts.map +0 -1
- package/dist/creek-table/hooks/useAdaptiveToolBar.d.ts.map +0 -1
- package/dist/creek-table/hooks/useAutoAddFilterToColumns.d.ts +0 -12
- package/dist/creek-table/hooks/useAutoAddFilterToColumns.d.ts.map +0 -1
- package/dist/creek-table/hooks/useAutoAddFilterToColumns.js +0 -96
- package/dist/creek-table/hooks/useElementDistance.d.ts.map +0 -1
- package/dist/creek-table/index.d.ts.map +0 -1
- package/dist/creek-table/toolBarRender.d.ts.map +0 -1
- package/dist/creek-table/type.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/src/bg-center/index.tsx +0 -26
- package/src/creek-search/CreekSearch.tsx +0 -60
- package/src/creek-search/CreekSearchContext.tsx +0 -593
- package/src/creek-search/CreekSearchFilterDisplay.tsx +0 -84
- package/src/creek-search/CreekSearchInput.tsx +0 -75
- package/src/creek-search/CreekSearchValueSelector.tsx +0 -324
- package/src/creek-search/index.tsx +0 -5
- package/src/creek-search/type.ts +0 -9
- package/src/creek-table/hooks/useAutoAddFilterToColumns.tsx +0 -90
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { useMemoizedFn } from 'ahooks';
|
|
2
|
+
import { App } from 'antd';
|
|
3
|
+
import React, { createContext, useContext, useMemo, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { DrawerHelper } from './DrawerHelper';
|
|
6
|
+
import { ModalHelper } from './ModalHelper';
|
|
7
|
+
import {
|
|
8
|
+
AppContextType,
|
|
9
|
+
DrawerConfig,
|
|
10
|
+
FormDrawerConfig,
|
|
11
|
+
FormModalConfig,
|
|
12
|
+
ModalConfig,
|
|
13
|
+
NormalDrawerConfig,
|
|
14
|
+
NormalModalConfig,
|
|
15
|
+
} from './types';
|
|
16
|
+
|
|
17
|
+
// --- Helper Hook for State Management ---
|
|
18
|
+
const usePopupState = <T extends object>() => {
|
|
19
|
+
const [state, setState] = useState<{ open: boolean; config: T }>({
|
|
20
|
+
open: false,
|
|
21
|
+
config: {} as T,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const show = useMemoizedFn((config: T) => {
|
|
25
|
+
setState({ open: true, config });
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const close = useMemoizedFn(() => {
|
|
29
|
+
setState((prev) => ({ ...prev, open: false }));
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return { ...state, show, close };
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const AppContext = createContext<AppContextType | null>(null);
|
|
36
|
+
|
|
37
|
+
export const AppProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
38
|
+
const drawer = usePopupState<DrawerConfig>();
|
|
39
|
+
const modal = usePopupState<ModalConfig>();
|
|
40
|
+
|
|
41
|
+
const handleCloseModal = useMemoizedFn(() => {
|
|
42
|
+
modal.close();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const handleCloseDrawer = useMemoizedFn(() => {
|
|
46
|
+
drawer.close();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const contextValue = useMemo(
|
|
50
|
+
() => ({
|
|
51
|
+
openDrawer: drawer.show,
|
|
52
|
+
closeDrawer: handleCloseDrawer,
|
|
53
|
+
openModal: modal.show,
|
|
54
|
+
closeModal: handleCloseModal,
|
|
55
|
+
}),
|
|
56
|
+
[drawer.show, handleCloseDrawer, modal.show, handleCloseModal],
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<AppContext.Provider value={contextValue}>
|
|
61
|
+
{children}
|
|
62
|
+
<DrawerHelper open={drawer.open} config={drawer.config} onClose={handleCloseDrawer} />
|
|
63
|
+
<ModalHelper open={modal.open} config={modal.config} onClose={handleCloseModal} />
|
|
64
|
+
</AppContext.Provider>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const useApp = () => {
|
|
69
|
+
const antdApp = App.useApp();
|
|
70
|
+
const appContext = useContext(AppContext);
|
|
71
|
+
|
|
72
|
+
return useMemo(() => {
|
|
73
|
+
const { openDrawer, closeDrawer, openModal, closeModal } = appContext || {};
|
|
74
|
+
const warn = () => console.warn('AppProvider is missing');
|
|
75
|
+
|
|
76
|
+
const createOpener = <T extends NormalModalConfig | NormalDrawerConfig>(
|
|
77
|
+
opener: ((config: T) => void) | undefined,
|
|
78
|
+
type: 'normal',
|
|
79
|
+
) => {
|
|
80
|
+
return (config: T) => {
|
|
81
|
+
if (opener) {
|
|
82
|
+
opener({ ...config, type } as T);
|
|
83
|
+
} else {
|
|
84
|
+
warn();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const createFormOpener = <T extends FormModalConfig | FormDrawerConfig>(
|
|
90
|
+
opener: ((config: T) => void) | undefined,
|
|
91
|
+
type: 'form',
|
|
92
|
+
) => {
|
|
93
|
+
return (config: Omit<T, 'type'>) => {
|
|
94
|
+
if (opener) {
|
|
95
|
+
opener({ ...config, type } as T);
|
|
96
|
+
} else {
|
|
97
|
+
warn();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
...antdApp,
|
|
104
|
+
drawer: {
|
|
105
|
+
open: createOpener<NormalDrawerConfig>(openDrawer, 'normal'),
|
|
106
|
+
openForm: createFormOpener<FormDrawerConfig>(openDrawer, 'form'),
|
|
107
|
+
close: closeDrawer || warn,
|
|
108
|
+
},
|
|
109
|
+
modal: {
|
|
110
|
+
...antdApp.modal,
|
|
111
|
+
open: createOpener<NormalModalConfig>(openModal, 'normal'),
|
|
112
|
+
openForm: createFormOpener<FormModalConfig>(openModal, 'form'),
|
|
113
|
+
close: closeModal || warn,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}, [antdApp, appContext]);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export * from './types';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DrawerFormProps, ModalFormProps } from '@ant-design/pro-components';
|
|
2
|
+
import { DrawerProps, ModalProps } from 'antd';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
// --- Common ---
|
|
6
|
+
export type BaseConfig = {
|
|
7
|
+
content?: React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// --- Modal Types ---
|
|
11
|
+
export type NormalModalConfig = BaseConfig & ModalProps & { type?: 'normal' };
|
|
12
|
+
export type FormModalConfig<T = any> = BaseConfig & Omit<ModalFormProps<T>, 'content'> & { type: 'form' };
|
|
13
|
+
export type ModalConfig = NormalModalConfig | FormModalConfig;
|
|
14
|
+
|
|
15
|
+
// --- Drawer Types ---
|
|
16
|
+
export type NormalDrawerConfig = BaseConfig & DrawerProps & { type?: 'normal' };
|
|
17
|
+
export type FormDrawerConfig<T = any> = BaseConfig & Omit<DrawerFormProps<T>, 'content'> & { type: 'form' };
|
|
18
|
+
export type DrawerConfig = NormalDrawerConfig | FormDrawerConfig;
|
|
19
|
+
|
|
20
|
+
export interface AppContextType {
|
|
21
|
+
openDrawer: (config: DrawerConfig) => void;
|
|
22
|
+
closeDrawer: () => void;
|
|
23
|
+
openModal: (config: ModalConfig) => void;
|
|
24
|
+
closeModal: () => void;
|
|
25
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useDebounceEffect, useDeepCompareEffect, useEventListener, useMemoizedFn, useMount, useUnmount } from 'ahooks';
|
|
1
|
+
import { useDebounceEffect, useDebounceFn, useDeepCompareEffect, useEventListener, useMemoizedFn, useMount, useUnmount } from 'ahooks';
|
|
2
2
|
import { useRef, useState } from 'react';
|
|
3
3
|
|
|
4
4
|
interface UseViewportHeightOptions {
|
|
@@ -23,12 +23,13 @@ interface UseViewportHeightOptions {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export const useViewportHeight = (options: UseViewportHeightOptions = {}) => {
|
|
26
|
-
const { bottomOffset = 0, topOffset, margin = 0, minHeight = 0, maxHeight, debug = false, debounceDelay =
|
|
26
|
+
const { bottomOffset = 0, topOffset, margin = 0, minHeight = 0, maxHeight, debug = false, debounceDelay = 500, deps = [], isObserverParent } = options;
|
|
27
27
|
|
|
28
28
|
const [viewPortHeight, setHeight] = useState<number | undefined>(undefined);
|
|
29
29
|
let containerRef = useRef<HTMLDivElement| null>(null);
|
|
30
30
|
const resizeObserverRef = useRef<ResizeObserver | null>(null);
|
|
31
31
|
const mutationObserverRef = useRef<MutationObserver | null>(null);
|
|
32
|
+
const lastHeightRef = useRef<number>(window.innerHeight);
|
|
32
33
|
|
|
33
34
|
// 使用 useMemoizedFn 缓存计算函数,避免不必要的重新创建
|
|
34
35
|
const calculateHeight = useMemoizedFn(() => {
|
|
@@ -69,8 +70,38 @@ export const useViewportHeight = (options: UseViewportHeightOptions = {}) => {
|
|
|
69
70
|
setHeight(availableHeight);
|
|
70
71
|
});
|
|
71
72
|
|
|
73
|
+
const { run: debouncedCalculateHeight } = useDebounceFn(
|
|
74
|
+
() => {
|
|
75
|
+
calculateHeight();
|
|
76
|
+
},
|
|
77
|
+
{ wait: debounceDelay },
|
|
78
|
+
);
|
|
79
|
+
|
|
72
80
|
// 使用 ahooks 的 useEventListener 监听窗口 resize 事件
|
|
73
|
-
useEventListener(
|
|
81
|
+
useEventListener(
|
|
82
|
+
'resize',
|
|
83
|
+
() => {
|
|
84
|
+
const currentHeight = window.innerHeight;
|
|
85
|
+
// 只有高度发生变化时才重新计算
|
|
86
|
+
if (Math.abs(currentHeight - lastHeightRef.current) > 1) {
|
|
87
|
+
lastHeightRef.current = currentHeight;
|
|
88
|
+
// 防抖调用 calculateHeight
|
|
89
|
+
if (debounceDelay > 0) {
|
|
90
|
+
// 清除之前的定时器(如果有)
|
|
91
|
+
// 注意:这里需要一个 ref 来存储 timer,但为了简化,我们依赖 useDebounceEffect 的重新触发
|
|
92
|
+
// 或者更直接地,我们可以在这里直接调用 debouncedCalculateHeight
|
|
93
|
+
// 但由于 calculateHeight 本身是同步的,我们可以利用 ahooks 的 run 方法如果它是 useDebounceFn 返回的
|
|
94
|
+
|
|
95
|
+
// 简单起见,我们在这里直接触发一个状态更新或者调用防抖函数
|
|
96
|
+
// 由于 calculateHeight 被用在多个地方,我们给它包一层 debounce
|
|
97
|
+
debouncedCalculateHeight();
|
|
98
|
+
} else {
|
|
99
|
+
calculateHeight();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{ target: () => window },
|
|
104
|
+
);
|
|
74
105
|
|
|
75
106
|
// 使用 useDebounceEffect 处理依赖项变化时的防抖计算
|
|
76
107
|
useDebounceEffect(
|
|
@@ -141,8 +172,6 @@ export const useViewportHeight = (options: UseViewportHeightOptions = {}) => {
|
|
|
141
172
|
}
|
|
142
173
|
}, [containerRef.current])
|
|
143
174
|
|
|
144
|
-
console.log(viewPortHeight, 'viewPortHeight');
|
|
145
|
-
|
|
146
175
|
return {
|
|
147
176
|
/** 容器引用,需要绑定到目标元素的容器 */
|
|
148
177
|
containerRef,
|
|
@@ -2,11 +2,9 @@ import { ParamsType, ProTable } from '@ant-design/pro-components';
|
|
|
2
2
|
import { createStyles } from 'antd-style';
|
|
3
3
|
import classnames from 'classnames';
|
|
4
4
|
import _ from 'lodash';
|
|
5
|
-
import {
|
|
5
|
+
import { useRef } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
import { useAdaptiveToolBar, useAutoAddFilterToColumns } from './hooks';
|
|
7
|
+
import { useAutoWidthColumns } from './hooks';
|
|
10
8
|
import { TableOptionRender } from './TableOptionRender';
|
|
11
9
|
import { TableViewContent } from './TableViewContent';
|
|
12
10
|
import { toolBarRender } from './toolBarRender';
|
|
@@ -40,45 +38,31 @@ export const SearchProTable = <T extends ParamsType, U extends ParamsType, Value
|
|
|
40
38
|
...restProps
|
|
41
39
|
} = props;
|
|
42
40
|
|
|
43
|
-
const
|
|
44
|
-
const { filters, filtersToParams } = searchContext;
|
|
45
|
-
|
|
46
|
-
const proTableRef = useRef(null);
|
|
41
|
+
const proTableRef = useRef<HTMLDivElement>(null);
|
|
47
42
|
|
|
48
|
-
// 使用自定义 hook
|
|
49
|
-
const {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
});
|
|
43
|
+
// // 使用自定义 hook 处理工具栏的自适应功能
|
|
44
|
+
// const { shouldCollapse } = useAdaptiveToolBar({
|
|
45
|
+
// containerRef: proTableRef,
|
|
46
|
+
// prefixCls,
|
|
47
|
+
// });
|
|
53
48
|
|
|
54
|
-
|
|
55
|
-
const { shouldCollapse } = useAdaptiveToolBar({
|
|
56
|
-
containerRef: proTableRef,
|
|
57
|
-
prefixCls,
|
|
58
|
-
});
|
|
49
|
+
const { columns: adaptiveColumns, totalWidth } = useAutoWidthColumns(columns, proTableRef);
|
|
59
50
|
|
|
60
51
|
const { styles } = useStyles();
|
|
61
52
|
|
|
62
|
-
// 获取搜素的参数
|
|
63
|
-
const finalParams = useMemo(() => {
|
|
64
|
-
let result = filtersToParams(filters) as U;
|
|
65
|
-
return result;
|
|
66
|
-
}, [filters]);
|
|
67
|
-
|
|
68
53
|
return (
|
|
69
54
|
<div ref={proTableRef}>
|
|
70
55
|
<ProTable<T, U, ValueType>
|
|
71
56
|
{...restProps}
|
|
72
57
|
className={classnames(styles['creek-table-container'], className)}
|
|
73
|
-
columns={
|
|
58
|
+
columns={adaptiveColumns}
|
|
59
|
+
scroll={{
|
|
60
|
+
x: totalWidth,
|
|
61
|
+
...restProps.scroll,
|
|
62
|
+
}}
|
|
74
63
|
toolbar={{
|
|
75
64
|
...restProps.toolbar,
|
|
76
65
|
}}
|
|
77
|
-
params={{
|
|
78
|
-
...params,
|
|
79
|
-
...finalParams,
|
|
80
|
-
}}
|
|
81
|
-
search={false}
|
|
82
66
|
pagination={{
|
|
83
67
|
showTotal: (total) => <span>共 {total} 条</span>,
|
|
84
68
|
showSizeChanger: true,
|
|
@@ -92,17 +76,12 @@ export const SearchProTable = <T extends ParamsType, U extends ParamsType, Value
|
|
|
92
76
|
: [];
|
|
93
77
|
}}
|
|
94
78
|
toolBarRender={() => {
|
|
95
|
-
return toolBarRender({
|
|
79
|
+
return toolBarRender({ shouldCollapse: false, restProps });
|
|
96
80
|
}}
|
|
97
|
-
// 在 headerTitle 中只放搜索输入框
|
|
98
|
-
headerTitle={<CreekSearchInput />}
|
|
99
81
|
// 在表格内容区上方显示筛选条件
|
|
100
82
|
tableViewRender={(defaultProps, defaultDom) => {
|
|
101
83
|
return _.isFunction(tableViewRender) ? (
|
|
102
|
-
<>
|
|
103
|
-
<CreekFilterDisplay />
|
|
104
|
-
{tableViewRender(defaultProps, defaultDom)}
|
|
105
|
-
</>
|
|
84
|
+
<>{tableViewRender(defaultProps, defaultDom)}</>
|
|
106
85
|
) : (
|
|
107
86
|
<TableViewContent<T, U, ValueType> pageFixedBottom={pageFixedBottom} pageFixedBottomConfig={pageFixedBottomConfig} prefixCls={prefixCls}>
|
|
108
87
|
{defaultDom}
|
|
@@ -3,7 +3,6 @@ import { ParamsType } from '@ant-design/pro-components';
|
|
|
3
3
|
import { useDebounceFn, useDeepCompareEffect } from 'ahooks';
|
|
4
4
|
|
|
5
5
|
import { useViewportHeight } from '../creek-hooks';
|
|
6
|
-
import { CreekFilterDisplay } from '../creek-search';
|
|
7
6
|
import { CreekTableProps } from './type';
|
|
8
7
|
|
|
9
8
|
export type CreekTableViewRender<T extends ParamsType, U extends ParamsType, ValueType = 'text'> = CreekTableProps<T, U, ValueType>['tableViewRender'];
|
|
@@ -17,18 +16,27 @@ export const TableViewContent = <T extends ParamsType, U extends ParamsType, Val
|
|
|
17
16
|
});
|
|
18
17
|
|
|
19
18
|
// 设置antd内容区的高度,使得分页永远在底部
|
|
20
|
-
const { run: setAntdTableContentHeight } = useDebounceFn(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
const { run: setAntdTableContentHeight } = useDebounceFn(
|
|
20
|
+
(mainHeight: number) => {
|
|
21
|
+
const antdTableContentElement = containerRef.current?.querySelector(`.${prefixCls}-table`);
|
|
22
|
+
const antdPaginationElement = containerRef.current?.querySelector(`.${prefixCls}-pagination`);
|
|
23
|
+
if (antdTableContentElement) {
|
|
24
|
+
const paginationHeight = antdPaginationElement?.clientHeight || 0;
|
|
25
|
+
const bottomFix = pageFixedBottomConfig?.bottomFix || 20;
|
|
26
|
+
const parentElement = containerRef.current?.parentElement;
|
|
27
|
+
let parentPaddingBottom = 0;
|
|
28
|
+
if (parentElement) {
|
|
29
|
+
const style = window.getComputedStyle(parentElement);
|
|
30
|
+
parentPaddingBottom = parseFloat(style.paddingBottom) || 0;
|
|
31
|
+
}
|
|
32
|
+
const tableContentHeight = mainHeight - paginationHeight - parentPaddingBottom - bottomFix - parentPaddingBottom;
|
|
33
|
+
antdTableContentElement.setAttribute('style', `height: ${tableContentHeight}px`);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
wait: 16,
|
|
38
|
+
},
|
|
39
|
+
);
|
|
32
40
|
|
|
33
41
|
useDeepCompareEffect(() => {
|
|
34
42
|
if (pageFixedBottom) {
|
|
@@ -39,7 +47,6 @@ export const TableViewContent = <T extends ParamsType, U extends ParamsType, Val
|
|
|
39
47
|
// 默认渲染逻辑
|
|
40
48
|
return (
|
|
41
49
|
<>
|
|
42
|
-
<CreekFilterDisplay />
|
|
43
50
|
<div ref={containerRef}>{children}</div>
|
|
44
51
|
</>
|
|
45
52
|
);
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { ProColumns } from '@ant-design/pro-components';
|
|
2
|
+
import { useMemoizedFn } from 'ahooks';
|
|
3
|
+
import { Space } from 'antd';
|
|
4
|
+
import { RefObject, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_PADDING_WIDTH = 16;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 估算字符串宽度(简单估算:汉字 14px,非汉字 8px,左右 padding 16px)
|
|
10
|
+
*/
|
|
11
|
+
const estimateWidth = (text: string) => {
|
|
12
|
+
let width = 0;
|
|
13
|
+
for (const char of text) {
|
|
14
|
+
if (/[\u4e00-\u9fa5]/.test(char)) {
|
|
15
|
+
width += 14;
|
|
16
|
+
} else {
|
|
17
|
+
width += 8;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return width + DEFAULT_PADDING_WIDTH; // padding
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 根据 valueType 获取默认宽度
|
|
25
|
+
*/
|
|
26
|
+
const getValueTypeWidth = (valueType: string | undefined): number => {
|
|
27
|
+
switch (valueType) {
|
|
28
|
+
case 'date':
|
|
29
|
+
case 'dateRange':
|
|
30
|
+
return 120;
|
|
31
|
+
case 'dateTime':
|
|
32
|
+
case 'dateTimeRange':
|
|
33
|
+
return 180;
|
|
34
|
+
case 'time':
|
|
35
|
+
case 'timeRange':
|
|
36
|
+
return 100;
|
|
37
|
+
case 'index':
|
|
38
|
+
case 'indexBorder':
|
|
39
|
+
return 60;
|
|
40
|
+
case 'money':
|
|
41
|
+
return 100;
|
|
42
|
+
case 'digit':
|
|
43
|
+
return 100;
|
|
44
|
+
case 'select':
|
|
45
|
+
return 120;
|
|
46
|
+
default:
|
|
47
|
+
return 80; // 默认给 80
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 一个用于测量的包裹组件
|
|
53
|
+
*/
|
|
54
|
+
const MeasureWrapper = ({ children, onResize }: { children: React.ReactNode; onResize: (width: number) => void }) => {
|
|
55
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (!ref.current) return;
|
|
59
|
+
|
|
60
|
+
// 初次测量
|
|
61
|
+
onResize(ref.current.offsetWidth);
|
|
62
|
+
|
|
63
|
+
// 监听变化
|
|
64
|
+
const observer = new ResizeObserver((entries) => {
|
|
65
|
+
for (const entry of entries) {
|
|
66
|
+
onResize((entry.target as HTMLElement).offsetWidth);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
observer.observe(ref.current);
|
|
71
|
+
|
|
72
|
+
return () => {
|
|
73
|
+
observer.disconnect();
|
|
74
|
+
};
|
|
75
|
+
}, []); // 依赖为空,只在挂载时设置监听
|
|
76
|
+
|
|
77
|
+
return <Space ref={ref}>{children}</Space>;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const useAutoWidthColumns = <T, ValueType>(
|
|
81
|
+
columns: ProColumns<T, ValueType>[] | undefined,
|
|
82
|
+
tableRef: RefObject<HTMLDivElement>,
|
|
83
|
+
): { columns: ProColumns<T, ValueType>[] | undefined; totalWidth: number | undefined } => {
|
|
84
|
+
// 存储每个列的最大宽度:key 是 dataIndex 或 title,value 是最大宽度
|
|
85
|
+
const [columnWidths, setColumnWidths] = useState<Record<string, number>>({});
|
|
86
|
+
const [tableWidth, setTableWidth] = useState<number>(0);
|
|
87
|
+
|
|
88
|
+
// 监听 table 容器宽度变化
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (!tableRef.current) return;
|
|
91
|
+
|
|
92
|
+
// 立即获取一次宽度
|
|
93
|
+
setTableWidth(tableRef.current.offsetWidth);
|
|
94
|
+
|
|
95
|
+
// 使用 requestAnimationFrame + setTimeout 防抖
|
|
96
|
+
let rafId: number;
|
|
97
|
+
let timerId: NodeJS.Timeout;
|
|
98
|
+
|
|
99
|
+
const updateWidth = (width: number) => {
|
|
100
|
+
cancelAnimationFrame(rafId);
|
|
101
|
+
clearTimeout(timerId);
|
|
102
|
+
|
|
103
|
+
rafId = requestAnimationFrame(() => {
|
|
104
|
+
timerId = setTimeout(() => {
|
|
105
|
+
setTableWidth(width);
|
|
106
|
+
}, 500);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const observer = new ResizeObserver((entries) => {
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
updateWidth(entry.contentRect.width);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
observer.observe(tableRef.current);
|
|
117
|
+
|
|
118
|
+
// 监听 window resize 作为后备
|
|
119
|
+
const handleWindowResize = () => {
|
|
120
|
+
if (tableRef.current) {
|
|
121
|
+
updateWidth(tableRef.current.offsetWidth);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
window.addEventListener('resize', handleWindowResize);
|
|
125
|
+
|
|
126
|
+
return () => {
|
|
127
|
+
observer.disconnect();
|
|
128
|
+
window.removeEventListener('resize', handleWindowResize);
|
|
129
|
+
cancelAnimationFrame(rafId);
|
|
130
|
+
clearTimeout(timerId);
|
|
131
|
+
};
|
|
132
|
+
}, [tableRef]);
|
|
133
|
+
|
|
134
|
+
const handleResize = useMemoizedFn((key: string, width: number) => {
|
|
135
|
+
setColumnWidths((prev) => {
|
|
136
|
+
const currentMax = prev[key] || 0;
|
|
137
|
+
if (width > currentMax) {
|
|
138
|
+
return { ...prev, [key]: width };
|
|
139
|
+
}
|
|
140
|
+
return prev;
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const { columns: finalColumns, totalWidth } = useMemo(() => {
|
|
145
|
+
if (!columns) return { columns: undefined, totalWidth: undefined };
|
|
146
|
+
|
|
147
|
+
// 1. 先计算所有列的理想宽度(不考虑 table 宽度)
|
|
148
|
+
const calculatedColumns = columns.map((col, index) => {
|
|
149
|
+
const colKey = (col.dataIndex as string) || (col.key as string) || `col-${index}`;
|
|
150
|
+
const measuredWidth = columnWidths[colKey];
|
|
151
|
+
let width: number;
|
|
152
|
+
if (col.width) {
|
|
153
|
+
width = typeof col.width === 'number' ? col.width : 100; // 暂时给个默认值如果手动设了 string width
|
|
154
|
+
} else if (col.valueType === 'option' && measuredWidth) {
|
|
155
|
+
width = measuredWidth + DEFAULT_PADDING_WIDTH;
|
|
156
|
+
} else {
|
|
157
|
+
width = Math.max(estimateWidth(col.title as string), getValueTypeWidth(col.valueType as string));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
...col,
|
|
162
|
+
_calculatedWidth: width,
|
|
163
|
+
_colKey: colKey,
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// 2. 计算所有列的总宽度
|
|
168
|
+
const totalCalculatedWidth = calculatedColumns.reduce((acc, col) => acc + col._calculatedWidth, 0);
|
|
169
|
+
|
|
170
|
+
// 3. 判断是否需要自适应
|
|
171
|
+
// 如果总宽度小于 table 宽度,说明空间足够,除了 option 列,其他列可以不设宽度让 table 自动撑开
|
|
172
|
+
const isOverflow = totalCalculatedWidth > tableWidth;
|
|
173
|
+
|
|
174
|
+
const processedColumns = calculatedColumns.map((col) => {
|
|
175
|
+
// 提取内部使用的字段
|
|
176
|
+
const { _calculatedWidth, _colKey, ...originalCol } = col;
|
|
177
|
+
|
|
178
|
+
// 针对 valueType === 'option' (操作列),始终需要特殊处理(包裹测量组件)
|
|
179
|
+
if (col.valueType === 'option') {
|
|
180
|
+
const originalRender = col.render;
|
|
181
|
+
return {
|
|
182
|
+
...originalCol,
|
|
183
|
+
// 始终设置 option 列宽度
|
|
184
|
+
width: _calculatedWidth,
|
|
185
|
+
fixed: col.fixed ?? 'right',
|
|
186
|
+
render: (dom: any, entity: any, index: any, action: any, schema: any) => {
|
|
187
|
+
const originalRenderResult = originalRender ? (originalRender(dom, entity, index, action, schema) as React.ReactNode) : dom;
|
|
188
|
+
return <MeasureWrapper onResize={(width) => handleResize(_colKey, width)}>{originalRenderResult}</MeasureWrapper>;
|
|
189
|
+
},
|
|
190
|
+
} as ProColumns<T, ValueType>;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// 非 option 列
|
|
194
|
+
return {
|
|
195
|
+
...originalCol,
|
|
196
|
+
// 只有当内容溢出(需要滚动)或者手动设置了宽度时,才应用计算出的宽度
|
|
197
|
+
// 否则不设置 width,让 Antd Table 自动布局占满剩余空间
|
|
198
|
+
width: isOverflow || col.width ? _calculatedWidth : undefined,
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
columns: processedColumns,
|
|
204
|
+
totalWidth: isOverflow ? totalCalculatedWidth : undefined,
|
|
205
|
+
};
|
|
206
|
+
}, [columns, columnWidths, tableWidth]);
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
columns: finalColumns,
|
|
210
|
+
totalWidth,
|
|
211
|
+
};
|
|
212
|
+
};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { ParamsType } from '@ant-design/pro-components';
|
|
2
2
|
|
|
3
|
-
import { CreekSearchProvider } from '../creek-search';
|
|
4
|
-
|
|
5
3
|
import { SearchProTable } from './SearchTable';
|
|
6
4
|
import { CreekTableProps } from './type';
|
|
7
5
|
|
|
@@ -9,8 +7,6 @@ export const CreekTable = <T extends ParamsType, U extends ParamsType, ValueType
|
|
|
9
7
|
const { columns = [], onSubmit, ...restProps } = props;
|
|
10
8
|
|
|
11
9
|
return (
|
|
12
|
-
|
|
13
|
-
<SearchProTable columns={columns} {...restProps} />
|
|
14
|
-
</CreekSearchProvider>
|
|
10
|
+
<SearchProTable columns={columns} {...restProps} />
|
|
15
11
|
);
|
|
16
12
|
};
|
package/src/creek-table/type.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type OptionRenderCustom = {
|
|
|
6
6
|
onClick?: () => void;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
export type CreekTableProps<T extends ParamsType, U extends ParamsType, ValueType = 'text'> = Omit<ProTableProps<T, U, ValueType>,
|
|
9
|
+
export type CreekTableProps<T extends ParamsType, U extends ParamsType, ValueType = 'text'> = Omit<ProTableProps<T, U, ValueType>, 'options'> & {
|
|
10
10
|
pageFixedBottom?: boolean; // 是否固定分页在底部
|
|
11
11
|
pageFixedBottomConfig?: {
|
|
12
12
|
/** 底部保留空间(如固定在底部的元素高度),默认 0 */
|
package/src/index.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
export * from './creek-config-provider';
|
|
3
|
+
export * from './creek-hooks';
|
|
3
4
|
export * from './creek-icon';
|
|
4
5
|
export * from './creek-layout';
|
|
5
6
|
export * from './creek-loading';
|
|
6
|
-
export * from './creek-search';
|
|
7
7
|
export * from './creek-table';
|
|
8
8
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bg-center/index.tsx"],"names":[],"mappings":";AAEA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,QAAQ,iBAAkB,aAAa,4CAmBnD,CAAC"}
|
package/dist/bg-center/index.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { createStyles } from 'antd-style';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
export var BgCenter = function BgCenter(_ref) {
|
|
4
|
-
var children = _ref.children;
|
|
5
|
-
var useStyles = createStyles(function (_ref2) {
|
|
6
|
-
var token = _ref2.token;
|
|
7
|
-
return {
|
|
8
|
-
bgCenterContianer: {
|
|
9
|
-
display: 'flex',
|
|
10
|
-
alignItems: 'center',
|
|
11
|
-
justifyContent: 'center',
|
|
12
|
-
position: 'fixed',
|
|
13
|
-
top: 0,
|
|
14
|
-
left: 0,
|
|
15
|
-
right: 0,
|
|
16
|
-
bottom: 0,
|
|
17
|
-
backgroundColor: 'rgba(255, 255, 255, 0.7)',
|
|
18
|
-
zIndex: token.zIndexBase
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
});
|
|
22
|
-
var _useStyles = useStyles(),
|
|
23
|
-
styles = _useStyles.styles;
|
|
24
|
-
return /*#__PURE__*/_jsx("div", {
|
|
25
|
-
className: styles.bgCenterContianer,
|
|
26
|
-
children: children
|
|
27
|
-
});
|
|
28
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CreekConfigContext.d.ts","sourceRoot":"","sources":["../../src/creek-config-provider/CreekConfigContext.tsx"],"names":[],"mappings":";AAEA,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,kDAA6C,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/creek-config-provider/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAsB,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEnF,MAAM,MAAM,wBAAwB,GAAG,uBAAuB,GAAG;IAC/D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,mBAAmB;YAAW,wBAAwB;;CAGlE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/creek-hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useViewportHeight.d.ts","sourceRoot":"","sources":["../../src/creek-hooks/useViewportHeight.tsx"],"names":[],"mappings":";AAGA,UAAU,wBAAwB;IAChC,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yBAAyB;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,IAAI,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC;IAE5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,iBAAiB,aAAa,wBAAwB;IA0H/D,wBAAwB;;IAExB,kBAAkB;;IAElB,kBAAkB;;IAElB,gBAAgB;;CAGnB,CAAC"}
|