@gx-design-vue/pro-table 0.2.0-alpha.2 → 0.2.0-alpha.21
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/ProTable.d.ts +14 -493
- package/dist/ProTable.js +902 -511
- package/dist/components/Drag/Handle.d.ts +90 -0
- package/dist/components/Drag/Handle.js +64 -0
- package/dist/components/Drag/Tbody.d.ts +17 -0
- package/dist/components/Drag/Tbody.js +27 -0
- package/dist/components/EllipsisText/index.d.ts +50 -0
- package/dist/components/EllipsisText/index.js +65 -0
- package/dist/components/ScrollBar/Bar.d.ts +79 -0
- package/dist/components/ScrollBar/Bar.js +84 -0
- package/dist/components/ScrollBar/Thumb.d.ts +50 -0
- package/dist/components/ScrollBar/{Thumb/index.js → Thumb.js} +67 -58
- package/dist/components/ScrollBar/context.d.ts +3 -4
- package/dist/components/ScrollBar/context.js +3 -5
- package/dist/components/ScrollBar/util.d.ts +6 -5
- package/dist/components/ScrollBar/util.js +1 -14
- package/dist/components/SearchForm/CollapseToggle.d.ts +53 -0
- package/dist/components/SearchForm/CollapseToggle.js +47 -0
- package/dist/components/SearchForm/FormItemContainer.d.ts +73 -0
- package/dist/components/SearchForm/FormItemContainer.js +225 -0
- package/dist/components/SearchForm/FormItemWrapper.d.ts +80 -0
- package/dist/components/SearchForm/FormItemWrapper.js +62 -0
- package/dist/components/SearchForm/SearchForm.d.ts +128 -0
- package/dist/components/SearchForm/SearchForm.js +319 -0
- package/dist/components/SearchForm/index.d.ts +2 -0
- package/dist/components/SearchForm/index.js +2 -0
- package/dist/components/Toolbar/FullscreenIcon.d.ts +24 -0
- package/dist/components/Toolbar/FullscreenIcon.js +22 -0
- package/dist/components/Toolbar/ListToolBar.d.ts +109 -0
- package/dist/components/Toolbar/ListToolBar.js +101 -0
- package/dist/components/Toolbar/index.d.ts +101 -0
- package/dist/components/Toolbar/index.js +101 -0
- package/dist/components/Toolbar/style.d.ts +8 -0
- package/dist/components/{ListToolBar → Toolbar}/style.js +32 -27
- package/dist/context/TableContext.d.ts +15 -27
- package/dist/context/TableContext.js +3 -5
- package/dist/hooks/index.d.ts +19 -0
- package/dist/hooks/index.js +19 -0
- package/dist/hooks/useAutoScroll.d.ts +32 -0
- package/dist/hooks/useAutoScroll.js +127 -0
- package/dist/hooks/useBreakpoints.d.ts +13 -0
- package/dist/hooks/useBreakpoints.js +65 -0
- package/dist/hooks/useCellRender.d.ts +13 -0
- package/dist/hooks/useCellRender.js +40 -0
- package/dist/hooks/useColumnResize.d.ts +29 -0
- package/dist/hooks/useColumnResize.js +112 -0
- package/dist/hooks/useColumns.d.ts +35 -24
- package/dist/hooks/useColumns.js +89 -58
- package/dist/hooks/useDragHandleColumn.d.ts +26 -0
- package/dist/hooks/useDragHandleColumn.js +52 -0
- package/dist/hooks/useEllipsis.d.ts +20 -0
- package/dist/hooks/useEllipsis.js +51 -0
- package/dist/hooks/useFetchData.d.ts +42 -65
- package/dist/hooks/useFetchData.js +160 -176
- package/dist/hooks/useFitPage.d.ts +19 -0
- package/dist/hooks/useFitPage.js +90 -0
- package/dist/hooks/useKeepAliveReload.d.ts +21 -0
- package/dist/hooks/useKeepAliveReload.js +24 -0
- package/dist/hooks/useLoading.d.ts +18 -7
- package/dist/hooks/useLoading.js +27 -11
- package/dist/hooks/usePagination.d.ts +10 -7
- package/dist/hooks/usePagination.js +38 -29
- package/dist/hooks/useRequestOptions.d.ts +18 -0
- package/dist/hooks/useRequestOptions.js +39 -0
- package/dist/hooks/useRowDrag.d.ts +42 -0
- package/dist/hooks/useRowDrag.js +268 -0
- package/dist/hooks/useRowSelection.d.ts +27 -15
- package/dist/hooks/useRowSelection.js +93 -80
- package/dist/hooks/useTable.d.ts +35 -77
- package/dist/hooks/useTable.js +76 -49
- package/dist/hooks/useTableForm.d.ts +17 -82
- package/dist/hooks/useTableForm.js +137 -52
- package/dist/hooks/useTableScroll.d.ts +33 -31
- package/dist/hooks/useTableScroll.js +71 -28
- package/dist/hooks/useTableSize.d.ts +17 -7
- package/dist/hooks/useTableSize.js +21 -9
- package/dist/index.d.ts +11 -7
- package/dist/index.js +10 -4
- package/dist/interface.d.ts +537 -0
- package/dist/interface.js +1 -0
- package/dist/pro-table.esm.js +8897 -4012
- package/dist/pro-table.js +4 -1
- package/dist/style/ellipsis.d.ts +13 -0
- package/dist/style/ellipsis.js +16 -0
- package/dist/style/fit-page.d.ts +4 -2
- package/dist/style/fit-page.js +10 -5
- package/dist/style/index.d.ts +3 -7
- package/dist/style/index.js +38 -76
- package/dist/style/list.d.ts +4 -2
- package/dist/style/list.js +2 -12
- package/dist/style/resizable.d.ts +8 -0
- package/dist/style/resizable.js +18 -0
- package/dist/style/row-drag.d.ts +8 -0
- package/dist/style/row-drag.js +44 -0
- package/dist/style/scroll.d.ts +4 -2
- package/dist/style/scroll.js +9 -9
- package/dist/style/search.d.ts +8 -0
- package/dist/{components/Form/style.js → style/search.js} +22 -9
- package/dist/theme/augment.d.ts +8 -0
- package/dist/theme/augment.js +1 -0
- package/dist/theme/interface/components.d.ts +8 -0
- package/dist/theme/interface/components.js +1 -0
- package/dist/utils/arrayMove.d.ts +9 -0
- package/dist/utils/arrayMove.js +15 -0
- package/dist/utils/dateFormat.d.ts +9 -0
- package/dist/utils/dateFormat.js +29 -0
- package/dist/utils/ellipsis.d.ts +19 -0
- package/dist/utils/ellipsis.js +30 -0
- package/dist/utils/flipAnimate.d.ts +25 -0
- package/dist/utils/flipAnimate.js +40 -0
- package/dist/utils/formConstants.d.ts +9 -0
- package/dist/utils/formConstants.js +29 -0
- package/dist/utils/valueFormat.d.ts +9 -0
- package/dist/utils/valueFormat.js +27 -0
- package/package.json +23 -11
- package/dist/components/Form/components/RequestSelect.d.ts +0 -50
- package/dist/components/Form/components/RequestSelect.js +0 -58
- package/dist/components/Form/hooks/useForm.d.ts +0 -11
- package/dist/components/Form/hooks/useForm.js +0 -32
- package/dist/components/Form/index.d.ts +0 -33
- package/dist/components/Form/index.js +0 -479
- package/dist/components/Form/style.d.ts +0 -6
- package/dist/components/Form/utils/config.d.ts +0 -9
- package/dist/components/Form/utils/config.js +0 -30
- package/dist/components/Form/utils/dateFormat.d.ts +0 -22
- package/dist/components/Form/utils/dateFormat.js +0 -45
- package/dist/components/ListToolBar/index.d.ts +0 -60
- package/dist/components/ListToolBar/index.js +0 -123
- package/dist/components/ListToolBar/style.d.ts +0 -6
- package/dist/components/ScrollBar/Bar/index.d.ts +0 -49
- package/dist/components/ScrollBar/Bar/index.js +0 -71
- package/dist/components/ScrollBar/Bar/props.d.ts +0 -25
- package/dist/components/ScrollBar/Bar/props.js +0 -18
- package/dist/components/ScrollBar/Thumb/index.d.ts +0 -40
- package/dist/components/ScrollBar/Thumb/props.d.ts +0 -20
- package/dist/components/ScrollBar/Thumb/props.js +0 -18
- package/dist/components/TableCell/index.d.ts +0 -37
- package/dist/components/TableCell/index.js +0 -72
- package/dist/components/ToolBar/FullscreenIcon.d.ts +0 -7
- package/dist/components/ToolBar/FullscreenIcon.js +0 -14
- package/dist/components/ToolBar/index.d.ts +0 -34
- package/dist/components/ToolBar/index.js +0 -100
- package/dist/hooks/tryOnActivated.d.ts +0 -6
- package/dist/hooks/tryOnActivated.js +0 -14
- package/dist/hooks/useDebounceFn.d.ts +0 -8
- package/dist/hooks/useDebounceFn.js +0 -34
- package/dist/hooks/useScrollArea.d.ts +0 -24
- package/dist/hooks/useScrollArea.js +0 -104
- package/dist/props.d.ts +0 -340
- package/dist/props.js +0 -251
- package/dist/types/ColumnTypings.d.ts +0 -129
- package/dist/types/ColumnTypings.js +0 -1
- package/dist/types/SlotsTypings.d.ts +0 -63
- package/dist/types/SlotsTypings.js +0 -13
- package/dist/types/TableTypings.d.ts +0 -359
- package/dist/types/TableTypings.js +0 -1
- package/dist/types/index.d.ts +0 -9
- package/dist/types/index.js +0 -1
- package/dist/utils/utils.d.ts +0 -10
- package/dist/utils/utils.js +0 -91
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
//#region src/hooks/useAutoScroll.ts
|
|
2
|
+
const ScrollDirection = {
|
|
3
|
+
Idle: 0,
|
|
4
|
+
Forward: 1,
|
|
5
|
+
Reverse: -1
|
|
6
|
+
};
|
|
7
|
+
const SCROLL_EPSILON = .5;
|
|
8
|
+
/**
|
|
9
|
+
* 纵向自动滚动 —— 精简复刻 `@dnd-kit/dom` 的 `detectScrollIntent` + `Scroller` 思路,
|
|
10
|
+
* 与 pro-layout Tabs 的横向 `useAutoScroll` 同构(仅轴向不同)。
|
|
11
|
+
*
|
|
12
|
+
* 指针进入 `scrollEl` 上/下边缘 threshold 区域时,按距边缘的比例计算速度
|
|
13
|
+
* (越靠边越快)。滚动方向必须先被用户同向移动解锁;如果当前方向已经到达边界,
|
|
14
|
+
* 则不产生滚动 intent,避免触底后因为鼠标还在边缘区被反复重新激活。
|
|
15
|
+
*
|
|
16
|
+
* 关键:`maxScrollTop` 在 `start()` 时快照一次(`??` 仅在 undefined 时 fallback 到实时值),
|
|
17
|
+
* 拖拽全程都用快照值判定能否滚动。这样即使拖拽中 `transform` 撑大了 `scrollHeight`,
|
|
18
|
+
* 也不会污染滚动判定,避免死循环。
|
|
19
|
+
*/
|
|
20
|
+
function useAutoScroll(scrollEl, getPointerY, options = {}) {
|
|
21
|
+
const { threshold = .2, acceleration = 18, tolerance = 10, onScroll } = options;
|
|
22
|
+
let rafId;
|
|
23
|
+
let lastPointerY = null;
|
|
24
|
+
let maxScrollTop;
|
|
25
|
+
const unlockedDirections = /* @__PURE__ */ new Set();
|
|
26
|
+
function getMaxScrollTop() {
|
|
27
|
+
const el = scrollEl.value;
|
|
28
|
+
if (!el) return 0;
|
|
29
|
+
return maxScrollTop ?? Math.max(0, el.scrollHeight - el.clientHeight);
|
|
30
|
+
}
|
|
31
|
+
function canScroll(direction) {
|
|
32
|
+
const el = scrollEl.value;
|
|
33
|
+
if (!el) return false;
|
|
34
|
+
const max = getMaxScrollTop();
|
|
35
|
+
if (direction === ScrollDirection.Forward) return el.scrollTop < max - SCROLL_EPSILON;
|
|
36
|
+
if (direction === ScrollDirection.Reverse) return el.scrollTop > SCROLL_EPSILON;
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
function getEdgeIntent() {
|
|
40
|
+
const el = scrollEl.value;
|
|
41
|
+
const pointerY = getPointerY();
|
|
42
|
+
if (!el || pointerY == null) return {
|
|
43
|
+
direction: ScrollDirection.Idle,
|
|
44
|
+
speed: 0
|
|
45
|
+
};
|
|
46
|
+
const rect = el.getBoundingClientRect();
|
|
47
|
+
const triggerHeight = rect.height * threshold;
|
|
48
|
+
if (triggerHeight <= 0) return {
|
|
49
|
+
direction: ScrollDirection.Idle,
|
|
50
|
+
speed: 0
|
|
51
|
+
};
|
|
52
|
+
let direction = ScrollDirection.Idle;
|
|
53
|
+
let speed = 0;
|
|
54
|
+
const distBottom = rect.bottom - pointerY;
|
|
55
|
+
const distTop = pointerY - rect.top;
|
|
56
|
+
const canScrollDown = canScroll(ScrollDirection.Forward);
|
|
57
|
+
const canScrollUp = canScroll(ScrollDirection.Reverse);
|
|
58
|
+
if (canScrollDown && distBottom <= triggerHeight && pointerY <= rect.bottom + tolerance) {
|
|
59
|
+
const ratio = Math.abs((rect.bottom - triggerHeight - pointerY) / triggerHeight);
|
|
60
|
+
direction = ScrollDirection.Forward;
|
|
61
|
+
speed = acceleration * Math.min(ratio, 1);
|
|
62
|
+
} else if (canScrollUp && distTop <= triggerHeight && pointerY >= rect.top - tolerance) {
|
|
63
|
+
const ratio = Math.abs((rect.top + triggerHeight - pointerY) / triggerHeight);
|
|
64
|
+
direction = ScrollDirection.Reverse;
|
|
65
|
+
speed = acceleration * Math.min(ratio, 1);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
direction,
|
|
69
|
+
speed
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function applyScroll() {
|
|
73
|
+
const el = scrollEl.value;
|
|
74
|
+
if (!el) return false;
|
|
75
|
+
const { direction, speed } = getEdgeIntent();
|
|
76
|
+
if (direction === ScrollDirection.Idle) return false;
|
|
77
|
+
if (!unlockedDirections.has(direction)) return false;
|
|
78
|
+
if (!canScroll(direction)) return false;
|
|
79
|
+
const delta = direction * speed;
|
|
80
|
+
if (delta !== 0) {
|
|
81
|
+
const before = el.scrollTop;
|
|
82
|
+
const next = Math.min(getMaxScrollTop(), Math.max(0, before + delta));
|
|
83
|
+
if (Math.abs(next - before) <= SCROLL_EPSILON) return false;
|
|
84
|
+
el.scrollTop = next;
|
|
85
|
+
onScroll?.();
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
function tick() {
|
|
91
|
+
rafId = void 0;
|
|
92
|
+
if (applyScroll()) rafId = requestAnimationFrame(tick);
|
|
93
|
+
}
|
|
94
|
+
function scroll() {
|
|
95
|
+
const pointerY = getPointerY();
|
|
96
|
+
if (pointerY == null) return false;
|
|
97
|
+
if (lastPointerY != null) {
|
|
98
|
+
const moveDirection = Math.sign(pointerY - lastPointerY);
|
|
99
|
+
if (moveDirection !== ScrollDirection.Idle) unlockedDirections.add(moveDirection);
|
|
100
|
+
}
|
|
101
|
+
lastPointerY = pointerY;
|
|
102
|
+
const didScroll = applyScroll();
|
|
103
|
+
if (didScroll) rafId ??= requestAnimationFrame(tick);
|
|
104
|
+
return didScroll;
|
|
105
|
+
}
|
|
106
|
+
function start() {
|
|
107
|
+
const el = scrollEl.value;
|
|
108
|
+
maxScrollTop = el ? Math.max(0, el.scrollHeight - el.clientHeight) : void 0;
|
|
109
|
+
scroll();
|
|
110
|
+
}
|
|
111
|
+
function stop() {
|
|
112
|
+
if (rafId != null) {
|
|
113
|
+
cancelAnimationFrame(rafId);
|
|
114
|
+
rafId = void 0;
|
|
115
|
+
}
|
|
116
|
+
lastPointerY = null;
|
|
117
|
+
maxScrollTop = void 0;
|
|
118
|
+
unlockedDirections.clear();
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
scroll,
|
|
122
|
+
start,
|
|
123
|
+
stop
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
export { useAutoScroll };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ColConfig } from "../interface.js";
|
|
2
|
+
import { ComputedRef } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/hooks/useBreakpoints.d.ts
|
|
5
|
+
interface UseProBreakpointsReturn {
|
|
6
|
+
screens: ComputedRef<Record<string, boolean>>;
|
|
7
|
+
isMobile: ComputedRef<boolean>;
|
|
8
|
+
screenWidth: ComputedRef<number>;
|
|
9
|
+
getRowItemsPerBreakpoint: (span: ColConfig | undefined, breakpoint: Record<number, number> | undefined) => number;
|
|
10
|
+
}
|
|
11
|
+
declare function useProBreakpoints(): UseProBreakpointsReturn;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { UseProBreakpointsReturn, useProBreakpoints };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { DEFAULT_BREAKPOINT_SPANS } from "../utils/formConstants.js";
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { useBreakpoints, useWindowSize } from "@vueuse/core";
|
|
4
|
+
//#region src/hooks/useBreakpoints.ts
|
|
5
|
+
const ANTD_BREAKPOINTS = {
|
|
6
|
+
xs: 0,
|
|
7
|
+
sm: 576,
|
|
8
|
+
md: 768,
|
|
9
|
+
lg: 992,
|
|
10
|
+
xl: 1200,
|
|
11
|
+
xxl: 1600
|
|
12
|
+
};
|
|
13
|
+
function useProBreakpoints() {
|
|
14
|
+
const breakpoints = useBreakpoints(ANTD_BREAKPOINTS);
|
|
15
|
+
const { width: screenWidth } = useWindowSize();
|
|
16
|
+
const bpGt = {
|
|
17
|
+
xs: breakpoints.greaterOrEqual("xs"),
|
|
18
|
+
sm: breakpoints.greaterOrEqual("sm"),
|
|
19
|
+
md: breakpoints.greaterOrEqual("md"),
|
|
20
|
+
lg: breakpoints.greaterOrEqual("lg"),
|
|
21
|
+
xl: breakpoints.greaterOrEqual("xl"),
|
|
22
|
+
xxl: breakpoints.greaterOrEqual("xxl")
|
|
23
|
+
};
|
|
24
|
+
const screens = computed(() => ({
|
|
25
|
+
xs: bpGt.xs.value,
|
|
26
|
+
sm: bpGt.sm.value,
|
|
27
|
+
md: bpGt.md.value,
|
|
28
|
+
lg: bpGt.lg.value,
|
|
29
|
+
xl: bpGt.xl.value,
|
|
30
|
+
xxl: bpGt.xxl.value
|
|
31
|
+
}));
|
|
32
|
+
const isMobile = computed(() => !screens.value.xl);
|
|
33
|
+
function getRowItemsPerBreakpoint(span, breakpoint) {
|
|
34
|
+
if (breakpoint && typeof breakpoint === "object" && Object.keys(breakpoint).length > 0) return getBreakpointRowLength(breakpoint, screenWidth.value);
|
|
35
|
+
return getColSpanRowLength(span, screens.value);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
screens,
|
|
39
|
+
isMobile,
|
|
40
|
+
screenWidth: computed(() => screenWidth.value),
|
|
41
|
+
getRowItemsPerBreakpoint
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function getBreakpointRowLength(config, rootWidth) {
|
|
45
|
+
let span = 4;
|
|
46
|
+
const sortedWidths = Object.keys(config).map(Number).filter((key) => !Number.isNaN(key)).sort((a, b) => b - a);
|
|
47
|
+
for (const width of sortedWidths) if (config[width] && rootWidth >= width) {
|
|
48
|
+
span = config[width];
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
return span;
|
|
52
|
+
}
|
|
53
|
+
function getColSpanRowLength(colSpan, rootScreen) {
|
|
54
|
+
let span = 4;
|
|
55
|
+
for (let i = 0; i < DEFAULT_BREAKPOINT_SPANS.length; i += 1) {
|
|
56
|
+
const breakpoint = DEFAULT_BREAKPOINT_SPANS[i].breakpoint;
|
|
57
|
+
if (rootScreen[breakpoint]) {
|
|
58
|
+
span = colSpan?.[breakpoint] ?? DEFAULT_BREAKPOINT_SPANS[i].span;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return span;
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { useProBreakpoints };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProColumnType } from "../interface.js";
|
|
2
|
+
import { ComputedRef } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/hooks/useCellRender.d.ts
|
|
5
|
+
interface UseCellRenderOptions {
|
|
6
|
+
columnEmptyText?: ComputedRef<string | ((record: any) => string) | undefined>;
|
|
7
|
+
prefixCls: ComputedRef<string>;
|
|
8
|
+
}
|
|
9
|
+
declare function useCellRender(options: UseCellRenderOptions): {
|
|
10
|
+
wrapColumnRender: (column: ProColumnType) => ProColumnType;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { UseCellRenderOptions, useCellRender };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import EllipsisText_default from "../components/EllipsisText/index.js";
|
|
2
|
+
import { normalizeEllipsis } from "../utils/ellipsis.js";
|
|
3
|
+
import { valueFormat } from "../utils/valueFormat.js";
|
|
4
|
+
import { h, isVNode } from "vue";
|
|
5
|
+
import { handleEmptyField, isNil } from "@gx-design-vue/pro-utils";
|
|
6
|
+
//#region src/hooks/useCellRender.ts
|
|
7
|
+
function resolveEmptyText(column, record, tableLevelEmptyText) {
|
|
8
|
+
if (column.columnEmptyText !== void 0) return typeof column.columnEmptyText === "function" ? column.columnEmptyText(record) : column.columnEmptyText;
|
|
9
|
+
if (tableLevelEmptyText !== void 0) return typeof tableLevelEmptyText === "function" ? tableLevelEmptyText(record) : tableLevelEmptyText;
|
|
10
|
+
return "-";
|
|
11
|
+
}
|
|
12
|
+
function useCellRender(options) {
|
|
13
|
+
function wrapColumnRender(column) {
|
|
14
|
+
const userRender = column.render;
|
|
15
|
+
const normalizedEllipsis = normalizeEllipsis(column.ellipsis);
|
|
16
|
+
const wrappedRender = (value, record, index) => {
|
|
17
|
+
let cellValue = userRender ? userRender(value, record, index) : value;
|
|
18
|
+
if (!userRender && column.valueType && !isVNode(cellValue)) cellValue = valueFormat(cellValue, column.valueType, { className: options.prefixCls.value });
|
|
19
|
+
const emptyText = resolveEmptyText(column, record, options.columnEmptyText?.value);
|
|
20
|
+
const { value: finalValue } = handleEmptyField(cellValue, emptyText);
|
|
21
|
+
let measurableText = null;
|
|
22
|
+
if (typeof cellValue === "string" && cellValue !== "" || typeof cellValue === "number") measurableText = String(cellValue);
|
|
23
|
+
else if (column.valueType === "link" && !isNil(value) && value !== "" && (typeof value === "string" || typeof value === "number")) measurableText = String(value);
|
|
24
|
+
if (normalizedEllipsis.enabled && measurableText !== null) return h(EllipsisText_default, {
|
|
25
|
+
text: measurableText,
|
|
26
|
+
ellipsis: normalizedEllipsis,
|
|
27
|
+
prefixCls: options.prefixCls.value
|
|
28
|
+
}, { default: () => finalValue });
|
|
29
|
+
return finalValue;
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
...column,
|
|
33
|
+
ellipsis: false,
|
|
34
|
+
render: wrappedRender
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return { wrapColumnRender };
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { useCellRender };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ProColumnType } from "../interface.js";
|
|
2
|
+
import { ComputedRef } from "vue";
|
|
3
|
+
|
|
4
|
+
//#region src/hooks/useColumnResize.d.ts
|
|
5
|
+
interface UseColumnResizeOptions {
|
|
6
|
+
columns: ComputedRef<ProColumnType[]>;
|
|
7
|
+
onResize?: (width: number, column: ProColumnType) => void;
|
|
8
|
+
}
|
|
9
|
+
interface UseColumnResizeReturn {
|
|
10
|
+
resizableColumns: ComputedRef<ProColumnType[]>;
|
|
11
|
+
resizableComponents: ComputedRef<{
|
|
12
|
+
header: {
|
|
13
|
+
cell: ReturnType<typeof createResizableTitle>;
|
|
14
|
+
};
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
interface ResizeInfo {
|
|
18
|
+
size: {
|
|
19
|
+
width: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
interface ResizableHeaderCellProps {
|
|
23
|
+
width?: number;
|
|
24
|
+
onResize?: (event: MouseEvent, info: ResizeInfo) => void;
|
|
25
|
+
}
|
|
26
|
+
declare function createResizableTitle(): import("vue").DefineComponent<ResizableHeaderCellProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ResizableHeaderCellProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
27
|
+
declare function useColumnResize(options: UseColumnResizeOptions): UseColumnResizeReturn;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { ResizeInfo, UseColumnResizeOptions, UseColumnResizeReturn, useColumnResize };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { getColumnKey } from "./useColumns.js";
|
|
2
|
+
import "./useDragHandleColumn.js";
|
|
3
|
+
import { computed, defineComponent, h, onScopeDispose, shallowRef } from "vue";
|
|
4
|
+
//#region src/hooks/useColumnResize.ts
|
|
5
|
+
const MIN_COLUMN_WIDTH = 40;
|
|
6
|
+
function createResizableTitle() {
|
|
7
|
+
return defineComponent({
|
|
8
|
+
name: "ResizableTitle",
|
|
9
|
+
inheritAttrs: false,
|
|
10
|
+
props: {
|
|
11
|
+
width: {
|
|
12
|
+
type: Number,
|
|
13
|
+
default: void 0
|
|
14
|
+
},
|
|
15
|
+
onResize: {
|
|
16
|
+
type: Function,
|
|
17
|
+
default: void 0
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
setup(props, { slots, attrs }) {
|
|
21
|
+
const dragging = shallowRef(false);
|
|
22
|
+
const shouldPreventClick = shallowRef(false);
|
|
23
|
+
const startX = shallowRef(0);
|
|
24
|
+
const startWidth = shallowRef(0);
|
|
25
|
+
function onMouseDown(event) {
|
|
26
|
+
event.preventDefault();
|
|
27
|
+
event.stopPropagation();
|
|
28
|
+
dragging.value = true;
|
|
29
|
+
shouldPreventClick.value = false;
|
|
30
|
+
startX.value = event.clientX;
|
|
31
|
+
startWidth.value = props.width || event.currentTarget?.parentElement?.offsetWidth || 0;
|
|
32
|
+
function onMouseMove(moveEvent) {
|
|
33
|
+
if (!dragging.value) return;
|
|
34
|
+
shouldPreventClick.value = true;
|
|
35
|
+
const nextWidth = Math.max(startWidth.value + moveEvent.clientX - startX.value, MIN_COLUMN_WIDTH);
|
|
36
|
+
props.onResize?.(moveEvent, { size: { width: nextWidth } });
|
|
37
|
+
}
|
|
38
|
+
function onMouseUp() {
|
|
39
|
+
dragging.value = false;
|
|
40
|
+
document.removeEventListener("mousemove", onMouseMove);
|
|
41
|
+
document.removeEventListener("mouseup", onMouseUp);
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
shouldPreventClick.value = false;
|
|
44
|
+
}, 0);
|
|
45
|
+
}
|
|
46
|
+
document.addEventListener("mousemove", onMouseMove);
|
|
47
|
+
document.addEventListener("mouseup", onMouseUp);
|
|
48
|
+
}
|
|
49
|
+
function onClickCapture(event) {
|
|
50
|
+
if (shouldPreventClick.value) {
|
|
51
|
+
event.stopPropagation();
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
shouldPreventClick.value = false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return () => {
|
|
57
|
+
if (props.width == null) return h("th", attrs, slots.default?.());
|
|
58
|
+
return h("th", {
|
|
59
|
+
...attrs,
|
|
60
|
+
class: ["resizable-title", attrs.class],
|
|
61
|
+
style: {
|
|
62
|
+
...attrs.style,
|
|
63
|
+
width: `${props.width}px`
|
|
64
|
+
},
|
|
65
|
+
onClickCapture
|
|
66
|
+
}, [slots.default?.(), h("span", {
|
|
67
|
+
class: "resizable-handle",
|
|
68
|
+
onMousedown: onMouseDown
|
|
69
|
+
})]);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function useColumnResize(options) {
|
|
75
|
+
const columnWidthOverrides = shallowRef(/* @__PURE__ */ new Map());
|
|
76
|
+
function handleColumnResize(columnKey, info) {
|
|
77
|
+
const nextMap = new Map(columnWidthOverrides.value);
|
|
78
|
+
nextMap.set(columnKey, info.size.width);
|
|
79
|
+
columnWidthOverrides.value = nextMap;
|
|
80
|
+
}
|
|
81
|
+
const ResizableTitle = createResizableTitle();
|
|
82
|
+
const resizableColumns = computed(() => {
|
|
83
|
+
const source = options.columns.value;
|
|
84
|
+
const overrides = columnWidthOverrides.value;
|
|
85
|
+
return source.map((column) => {
|
|
86
|
+
if (column.key === "__drag_handle__" || column.dataIndex === "__drag_handle__") return column;
|
|
87
|
+
const columnKey = getColumnKey(column);
|
|
88
|
+
const overriddenWidth = overrides.get(columnKey);
|
|
89
|
+
return {
|
|
90
|
+
...column,
|
|
91
|
+
...overriddenWidth != null ? { width: overriddenWidth } : {},
|
|
92
|
+
onHeaderCell: (col) => ({
|
|
93
|
+
width: col.width,
|
|
94
|
+
onResize: (_event, info) => {
|
|
95
|
+
handleColumnResize(getColumnKey(col), info);
|
|
96
|
+
options.onResize?.(info.size.width, col);
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
const resizableComponents = computed(() => ({ header: { cell: ResizableTitle } }));
|
|
103
|
+
onScopeDispose(() => {
|
|
104
|
+
columnWidthOverrides.value = /* @__PURE__ */ new Map();
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
resizableColumns,
|
|
108
|
+
resizableComponents
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { useColumnResize };
|
|
@@ -1,28 +1,39 @@
|
|
|
1
|
-
import { ProColumnType,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { ProColumnType, ProTableIndexColumn } from "../interface.js";
|
|
2
|
+
import { ComputedRef } from "vue";
|
|
3
|
+
import { AlignType, RecordType } from "@gx-design-vue/pro-utils";
|
|
4
4
|
|
|
5
5
|
//#region src/hooks/useColumns.d.ts
|
|
6
|
-
interface
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
autoScroll: Ref<ProTableProps['autoScroll']>;
|
|
6
|
+
interface UseColumnsOptions<T = RecordType> {
|
|
7
|
+
columns: ComputedRef<ProColumnType<T>[]>;
|
|
8
|
+
align: ComputedRef<AlignType>;
|
|
9
|
+
indexColumn?: ComputedRef<boolean | ProTableIndexColumn | undefined>;
|
|
10
|
+
shouldFixActionColumn?: ComputedRef<boolean>;
|
|
11
|
+
wrapColumnRender?: (column: ProColumnType<T>) => ProColumnType<T>;
|
|
13
12
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
interface UseColumnsReturn<T = RecordType> {
|
|
14
|
+
tableColumns: ComputedRef<ProColumnType<T>[]>;
|
|
15
|
+
cacheColumns: ComputedRef<ProColumnType<T>[]>;
|
|
16
|
+
setColumns: (columns: ProColumnType<any>[]) => void;
|
|
17
|
+
}
|
|
18
|
+
/** 获取列唯一标识,优先 key,回退 dataIndex */
|
|
19
|
+
declare function getColumnKey(col: ProColumnType<any>): string | number;
|
|
20
|
+
/** 规范化单列:补齐 key/dataIndex/align/order,递归处理 children */
|
|
21
|
+
declare function normalizeColumn<T>(col: ProColumnType<T>, index: number, defaultAlign: AlignType): ProColumnType<T>;
|
|
22
|
+
/** 批量规范化列配置 */
|
|
23
|
+
declare function normalizeColumns<T>(columns: ProColumnType<T>[], defaultAlign: AlignType): ProColumnType<T>[];
|
|
24
|
+
declare function applyIndexColumn<T>(columns: ProColumnType<T>[], indexColumn: boolean | ProTableIndexColumn | undefined, defaultAlign: AlignType): ProColumnType<T>[];
|
|
25
|
+
declare function applyActionColumnFixed<T>(columns: ProColumnType<T>[], shouldFixActionColumn: boolean): ProColumnType<T>[];
|
|
26
|
+
/** 过滤掉 show=false 的列 */
|
|
27
|
+
declare function filterVisible<T>(columns: ProColumnType<T>[]): ProColumnType<T>[];
|
|
28
|
+
/** 按 order 字段升序排列 */
|
|
29
|
+
declare function sortByOrder<T>(columns: ProColumnType<T>[]): ProColumnType<T>[];
|
|
30
|
+
/**
|
|
31
|
+
* 列配置管理。
|
|
32
|
+
* 纯函数 + computed 实现,无 watcher/ref 链。
|
|
33
|
+
* - tableColumns: 仅可见列,按 order 排序
|
|
34
|
+
* - cacheColumns: 全量规范化列(含隐藏列)
|
|
35
|
+
* - setColumns: 外部覆写列(用于 sortOrder 同步等),props 变化时自动重置
|
|
36
|
+
*/
|
|
37
|
+
declare function useColumns<T = RecordType>(options: UseColumnsOptions<T>): UseColumnsReturn<T>;
|
|
27
38
|
//#endregion
|
|
28
|
-
export { useColumns };
|
|
39
|
+
export { UseColumnsOptions, UseColumnsReturn, applyActionColumnFixed, applyIndexColumn, filterVisible, getColumnKey, normalizeColumn, normalizeColumns, sortByOrder, useColumns };
|
package/dist/hooks/useColumns.js
CHANGED
|
@@ -1,66 +1,97 @@
|
|
|
1
|
-
import { computed,
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { computed, onScopeDispose, shallowRef, watch } from "vue";
|
|
2
|
+
import { createUUIDFactory } from "@gx-design-vue/pro-utils";
|
|
4
3
|
//#region src/hooks/useColumns.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
4
|
+
/** 获取列唯一标识,优先 key,回退 dataIndex */
|
|
5
|
+
function getColumnKey(col) {
|
|
6
|
+
return col.key ?? col.dataIndex;
|
|
7
|
+
}
|
|
8
|
+
function isActionColumn(column) {
|
|
9
|
+
return getColumnKey(column) === "action" || column.dataIndex === "action";
|
|
10
|
+
}
|
|
11
|
+
function normalizeFixedValue(fixed) {
|
|
12
|
+
if (fixed === "left") return "start";
|
|
13
|
+
if (fixed === "right") return "end";
|
|
14
|
+
return fixed;
|
|
15
|
+
}
|
|
16
|
+
/** 规范化单列:补齐 key/dataIndex/align/order,递归处理 children */
|
|
17
|
+
function normalizeColumn(col, index, defaultAlign) {
|
|
18
|
+
const key = getColumnKey(col);
|
|
19
|
+
const normalized = {
|
|
20
|
+
...col,
|
|
21
|
+
key,
|
|
22
|
+
dataIndex: col.dataIndex ?? key,
|
|
23
|
+
order: col.order ?? index,
|
|
24
|
+
align: col.align ?? defaultAlign
|
|
25
|
+
};
|
|
26
|
+
if (col.children?.length) normalized.children = col.children.map((child, childIndex) => normalizeColumn(child, childIndex, defaultAlign));
|
|
27
|
+
return normalized;
|
|
28
|
+
}
|
|
29
|
+
/** 批量规范化列配置 */
|
|
30
|
+
function normalizeColumns(columns, defaultAlign) {
|
|
31
|
+
return columns.map((col, index) => normalizeColumn(col, index, defaultAlign));
|
|
32
|
+
}
|
|
33
|
+
function createIndexColumn(indexColumn, defaultAlign, firstColumn) {
|
|
34
|
+
const config = typeof indexColumn === "object" ? indexColumn : {};
|
|
35
|
+
return {
|
|
36
|
+
title: config.title ?? "序号",
|
|
37
|
+
align: config.align ?? defaultAlign,
|
|
38
|
+
fixed: normalizeFixedValue(config.fixed ?? firstColumn?.fixed),
|
|
39
|
+
width: config.width ?? 60,
|
|
40
|
+
uuid: createUUIDFactory().uuid(15),
|
|
41
|
+
dataIndex: "sortIndex",
|
|
42
|
+
key: "sortIndex"
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function applyIndexColumn(columns, indexColumn, defaultAlign) {
|
|
46
|
+
if (!indexColumn || columns.length === 0 || columns.some((column) => column.dataIndex === "sortIndex" || getColumnKey(column) === "sortIndex")) return columns;
|
|
47
|
+
return [createIndexColumn(indexColumn === true ? true : indexColumn, defaultAlign, columns[0]), ...columns];
|
|
48
|
+
}
|
|
49
|
+
function applyActionColumnFixed(columns, shouldFixActionColumn) {
|
|
50
|
+
if (!shouldFixActionColumn) return columns;
|
|
51
|
+
return columns.map((column) => {
|
|
52
|
+
if (!isActionColumn(column) || column.fixed !== void 0) return column;
|
|
53
|
+
return {
|
|
54
|
+
...column,
|
|
55
|
+
fixed: "end"
|
|
56
|
+
};
|
|
21
57
|
});
|
|
22
|
-
|
|
23
|
-
|
|
58
|
+
}
|
|
59
|
+
/** 过滤掉 show=false 的列 */
|
|
60
|
+
function filterVisible(columns) {
|
|
61
|
+
return columns.filter((col) => col.show !== false);
|
|
62
|
+
}
|
|
63
|
+
/** 按 order 字段升序排列 */
|
|
64
|
+
function sortByOrder(columns) {
|
|
65
|
+
return [...columns].sort((columnA, columnB) => (columnA.order ?? 0) - (columnB.order ?? 0));
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 列配置管理。
|
|
69
|
+
* 纯函数 + computed 实现,无 watcher/ref 链。
|
|
70
|
+
* - tableColumns: 仅可见列,按 order 排序
|
|
71
|
+
* - cacheColumns: 全量规范化列(含隐藏列)
|
|
72
|
+
* - setColumns: 外部覆写列(用于 sortOrder 同步等),props 变化时自动重置
|
|
73
|
+
*/
|
|
74
|
+
function useColumns(options) {
|
|
75
|
+
const overrideColumns = shallowRef(null);
|
|
76
|
+
const stopWatch = watch(() => options.columns.value, () => {
|
|
77
|
+
overrideColumns.value = null;
|
|
24
78
|
});
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
item.fixed = "right";
|
|
36
|
-
} else {
|
|
37
|
-
const originCol = unref(columns).find((col) => col.dataIndex === item.dataIndex);
|
|
38
|
-
item.width = originCol?.width || "";
|
|
39
|
-
item.fixed = originCol?.fixed;
|
|
40
|
-
}
|
|
41
|
-
return item;
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
function resizeColumnWidth(width, col) {
|
|
45
|
-
proColumnsRef.value = proColumnsRef.value.map((item) => {
|
|
46
|
-
if (item.uuid === col.uuid) item.width = width;
|
|
47
|
-
return item;
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
function setColumns(columnList) {
|
|
51
|
-
if (columnList.length <= 0) {
|
|
52
|
-
proColumnsRef.value = [];
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
if (!isDeepEqualReact(handleColumns(columnList), toRaw(proColumnsRef.value))) proColumnsRef.value = handleColumns(columnList);
|
|
79
|
+
onScopeDispose(() => stopWatch());
|
|
80
|
+
const cacheColumns = computed(() => {
|
|
81
|
+
return applyActionColumnFixed(normalizeColumns(applyIndexColumn(overrideColumns.value ?? options.columns.value, options.indexColumn?.value, options.align.value), options.align.value), !!options.shouldFixActionColumn?.value);
|
|
82
|
+
});
|
|
83
|
+
const tableColumns = computed(() => {
|
|
84
|
+
const visible = sortByOrder(filterVisible(cacheColumns.value));
|
|
85
|
+
return options.wrapColumnRender ? visible.map((col) => options.wrapColumnRender(col)) : visible;
|
|
86
|
+
});
|
|
87
|
+
function setColumns(columns) {
|
|
88
|
+
overrideColumns.value = columns;
|
|
56
89
|
}
|
|
57
90
|
return {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
setColumns
|
|
61
|
-
resizeColumnWidth
|
|
91
|
+
tableColumns,
|
|
92
|
+
cacheColumns,
|
|
93
|
+
setColumns
|
|
62
94
|
};
|
|
63
95
|
}
|
|
64
|
-
|
|
65
96
|
//#endregion
|
|
66
|
-
export { useColumns };
|
|
97
|
+
export { applyActionColumnFixed, applyIndexColumn, filterVisible, getColumnKey, normalizeColumn, normalizeColumns, sortByOrder, useColumns };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ProColumnType, ProTableRowDragOptions } from "../interface.js";
|
|
2
|
+
import { ComputedRef } from "vue";
|
|
3
|
+
import { RecordType } from "@gx-design-vue/pro-utils";
|
|
4
|
+
|
|
5
|
+
//#region src/hooks/useDragHandleColumn.d.ts
|
|
6
|
+
interface UseDragHandleColumnOptions<T = RecordType> {
|
|
7
|
+
columns: ComputedRef<ProColumnType<T>[]>;
|
|
8
|
+
rowDraggable: ComputedRef<boolean | ProTableRowDragOptions | undefined>;
|
|
9
|
+
prefixCls: ComputedRef<string>;
|
|
10
|
+
cssVarCls: ComputedRef<string>;
|
|
11
|
+
}
|
|
12
|
+
interface UseDragHandleColumnReturn<T = RecordType> {
|
|
13
|
+
dragColumns: ComputedRef<ProColumnType<T>[]>;
|
|
14
|
+
}
|
|
15
|
+
/** 把手列内部标记 key */
|
|
16
|
+
declare const DRAG_HANDLE_COLUMN_KEY = "__drag_handle__";
|
|
17
|
+
/**
|
|
18
|
+
* 在列首注入行拖拽把手列。
|
|
19
|
+
*
|
|
20
|
+
* 纯函数实现(对标 `applyIndexColumn`),在 `useColumns` 的 `cacheColumns` computed 中、
|
|
21
|
+
* `applyIndexColumn` 之前调用,确保把手列比序号列更靠前。
|
|
22
|
+
*/
|
|
23
|
+
declare function applyDragHandleColumn<T>(columns: ProColumnType<T>[], rowDraggable: boolean | ProTableRowDragOptions | undefined, prefixCls: string, cssVarCls: string): ProColumnType<T>[];
|
|
24
|
+
declare function useDragHandleColumn<T = RecordType>(options: UseDragHandleColumnOptions<T>): UseDragHandleColumnReturn<T>;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { DRAG_HANDLE_COLUMN_KEY, UseDragHandleColumnOptions, UseDragHandleColumnReturn, applyDragHandleColumn, useDragHandleColumn };
|