@hsu-react/ui 0.0.9 → 0.0.11
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/README.md +2 -2
- package/es/components/FormItem/ItemContainer/index.d.ts +2 -0
- package/es/components/FormItem/ItemContainer/index.js +4 -15
- package/es/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.d.ts +3 -3
- package/es/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.js +3 -3
- package/es/components/Search/SearchAdvanced/index.js +26 -148
- package/es/components/Search/SearchCard/index.js +1 -1
- package/es/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.js +2 -2
- package/es/components/Search/SearchCollapsible/index.js +17 -138
- package/es/components/Search/SearchWithFilter/index.js +4 -143
- package/es/components/Search/SearchWithMore/index.js +11 -142
- package/es/components/Search/_components/FilterDropdown/index.js +5 -6
- package/es/components/Search/_components/SearchBase/index.d.ts +32 -0
- package/es/components/Search/_components/SearchBase/index.js +185 -0
- package/es/components/Search/_hooks/useSearchCommon.js +5 -11
- package/es/components/Search/_hooks/useSearchExpand.js +4 -13
- package/es/components/Search/_utils/calculateButtonGroupAndColumnWidth.js +3 -10
- package/es/components/Search/_utils/calculateVisibleItems.js +4 -5
- package/es/components/Search/_utils/index.d.ts +2 -0
- package/es/components/Search/_utils/index.js +3 -1
- package/es/components/Search/_utils/measureButtonGroupWidth.d.ts +6 -0
- package/es/components/Search/_utils/measureButtonGroupWidth.js +18 -0
- package/es/components/Search/_utils/shouldDisplayExtraItem.d.ts +11 -0
- package/es/components/Search/_utils/shouldDisplayExtraItem.js +13 -0
- package/es/components/Search/index.d.ts +4 -0
- package/es/components/Search/index.js +6 -133
- package/es/components/Table/_hooks/useEllipsisTooltip.js +4 -2
- package/es/components/Table/_hooks/useTableColumns.d.ts +1 -0
- package/es/components/Table/_hooks/useTableColumns.js +35 -2
- package/es/components/Table/index.js +2 -1
- package/es/components/TextEllipsis/index.js +32 -14
- package/lib/components/FormItem/ItemContainer/index.d.ts +2 -0
- package/lib/components/FormItem/ItemContainer/index.js +2 -5
- package/lib/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.d.ts +3 -3
- package/lib/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.js +3 -3
- package/lib/components/Search/SearchAdvanced/index.js +19 -134
- package/lib/components/Search/SearchCard/index.js +1 -1
- package/lib/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.js +2 -2
- package/lib/components/Search/SearchCollapsible/index.js +12 -124
- package/lib/components/Search/SearchWithFilter/index.js +5 -129
- package/lib/components/Search/SearchWithMore/index.js +7 -126
- package/lib/components/Search/_components/FilterDropdown/index.js +5 -6
- package/lib/components/Search/_components/SearchBase/index.d.ts +32 -0
- package/lib/components/Search/_components/SearchBase/index.js +169 -0
- package/lib/components/Search/_hooks/useSearchCommon.js +4 -6
- package/lib/components/Search/_hooks/useSearchExpand.js +2 -13
- package/lib/components/Search/_utils/calculateButtonGroupAndColumnWidth.js +2 -10
- package/lib/components/Search/_utils/calculateVisibleItems.js +3 -5
- package/lib/components/Search/_utils/index.d.ts +2 -0
- package/lib/components/Search/_utils/index.js +15 -1
- package/lib/components/Search/_utils/measureButtonGroupWidth.d.ts +6 -0
- package/lib/components/Search/_utils/measureButtonGroupWidth.js +24 -0
- package/lib/components/Search/_utils/shouldDisplayExtraItem.d.ts +11 -0
- package/lib/components/Search/_utils/shouldDisplayExtraItem.js +19 -0
- package/lib/components/Search/index.d.ts +4 -0
- package/lib/components/Search/index.js +8 -119
- package/lib/components/Table/_hooks/useEllipsisTooltip.js +3 -1
- package/lib/components/Table/_hooks/useTableColumns.d.ts +1 -0
- package/lib/components/Table/_hooks/useTableColumns.js +31 -2
- package/lib/components/Table/index.js +2 -1
- package/lib/components/TextEllipsis/index.js +27 -14
- package/package.json +1 -1
- package/src/components/FormItem/ItemContainer/index.tsx +4 -7
- package/src/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.tsx +6 -6
- package/src/components/Search/SearchAdvanced/index.tsx +25 -164
- package/src/components/Search/SearchCard/index.tsx +1 -1
- package/src/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.tsx +2 -2
- package/src/components/Search/SearchCollapsible/index.tsx +13 -162
- package/src/components/Search/SearchWithFilter/index.tsx +2 -164
- package/src/components/Search/SearchWithMore/index.tsx +9 -161
- package/src/components/Search/_components/FilterDropdown/index.tsx +5 -6
- package/src/components/Search/_components/SearchBase/index.tsx +224 -0
- package/src/components/Search/_hooks/useSearchCommon.ts +10 -13
- package/src/components/Search/_hooks/useSearchExpand.ts +3 -13
- package/src/components/Search/_utils/calculateButtonGroupAndColumnWidth.ts +2 -10
- package/src/components/Search/_utils/calculateVisibleItems.ts +10 -11
- package/src/components/Search/_utils/index.ts +2 -0
- package/src/components/Search/_utils/measureButtonGroupWidth.ts +23 -0
- package/src/components/Search/_utils/shouldDisplayExtraItem.ts +23 -0
- package/src/components/Search/index.tsx +7 -153
- package/src/components/Table/_hooks/useEllipsisTooltip.ts +2 -4
- package/src/components/Table/_hooks/useTableColumns.tsx +41 -1
- package/src/components/Table/index.md +2 -0
- package/src/components/Table/index.tsx +1 -0
- package/src/components/TextEllipsis/index.md +1 -1
- package/src/components/TextEllipsis/index.tsx +33 -18
- /package/es/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.d.ts +0 -0
- /package/lib/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.d.ts +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RefObject } from "react";
|
|
2
|
+
import { measureButtonGroupWidth } from "./measureButtonGroupWidth";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* 计算按钮组宽度和列宽
|
|
@@ -26,16 +27,7 @@ export function calculateButtonGroupAndColumnWidth(
|
|
|
26
27
|
const gap = 10; // 项之间的间距
|
|
27
28
|
|
|
28
29
|
// 计算按钮组宽度
|
|
29
|
-
|
|
30
|
-
if (buttonChildren.length > 0) {
|
|
31
|
-
let totalWidth = 0;
|
|
32
|
-
buttonChildren?.forEach((child) => {
|
|
33
|
-
totalWidth += (child as HTMLElement).offsetWidth;
|
|
34
|
-
});
|
|
35
|
-
const childGap = 5;
|
|
36
|
-
totalWidth += (buttonChildren.length - 1) * childGap;
|
|
37
|
-
buttonGroupWidth = totalWidth;
|
|
38
|
-
}
|
|
30
|
+
buttonGroupWidth = measureButtonGroupWidth(buttonGroupRef.current);
|
|
39
31
|
|
|
40
32
|
// 计算列宽(单个搜索项的默认宽度)
|
|
41
33
|
if (adaptiveColumnNum > 0) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FormItemProps } from "../../FormItem";
|
|
2
|
+
import { shouldDisplayExtraItem } from "./shouldDisplayExtraItem";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* 计算当前应该显示的搜索项
|
|
@@ -21,7 +22,7 @@ export function calculateVisibleItems(
|
|
|
21
22
|
columnWidth?: number,
|
|
22
23
|
): FormItemProps[] {
|
|
23
24
|
const visibleItems = searchItems.filter((item) => item.visible);
|
|
24
|
-
const hasCustomWidth = searchItems.
|
|
25
|
+
const hasCustomWidth = searchItems.some((item) => item.width !== undefined);
|
|
25
26
|
|
|
26
27
|
if (!expand) {
|
|
27
28
|
// 当有自定义宽度时,使用自适应计算
|
|
@@ -32,16 +33,14 @@ export function calculateVisibleItems(
|
|
|
32
33
|
} else if (!hasCustomWidth) {
|
|
33
34
|
// 没有自定义宽度时,使用 columnNum(实际搜索项数量)
|
|
34
35
|
// 判断按钮组宽度是否大于列宽,如果是,则显示 实际搜索项数量+1
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
displayCount = columnNum + 1;
|
|
44
|
-
}
|
|
36
|
+
const displayCount = shouldDisplayExtraItem(
|
|
37
|
+
buttonGroupWidth,
|
|
38
|
+
columnWidth,
|
|
39
|
+
columnNum,
|
|
40
|
+
visibleItems.length,
|
|
41
|
+
)
|
|
42
|
+
? columnNum + 1
|
|
43
|
+
: columnNum;
|
|
45
44
|
if (visibleItems.length >= displayCount) {
|
|
46
45
|
return visibleItems.slice(0, displayCount);
|
|
47
46
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { cleanSearchData } from "./cleanSearchData";
|
|
2
2
|
export { calculateVisibleItems } from "./calculateVisibleItems";
|
|
3
3
|
export { calculateButtonGroupAndColumnWidth } from "./calculateButtonGroupAndColumnWidth";
|
|
4
|
+
export { measureButtonGroupWidth } from "./measureButtonGroupWidth";
|
|
5
|
+
export { shouldDisplayExtraItem } from "./shouldDisplayExtraItem";
|
|
4
6
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 计算按钮组的实际宽度(所有子元素宽度总和 + 子元素间距)
|
|
3
|
+
* @param buttonGroupEl 按钮组元素
|
|
4
|
+
* @returns 按钮组宽度;无子元素时返回 undefined
|
|
5
|
+
*/
|
|
6
|
+
export function measureButtonGroupWidth(
|
|
7
|
+
buttonGroupEl: HTMLElement | null
|
|
8
|
+
): number | undefined {
|
|
9
|
+
if (!buttonGroupEl) return undefined;
|
|
10
|
+
|
|
11
|
+
const buttonChildren = Array.from(buttonGroupEl.children);
|
|
12
|
+
if (buttonChildren.length === 0) return undefined;
|
|
13
|
+
|
|
14
|
+
let totalWidth = 0;
|
|
15
|
+
buttonChildren.forEach((child) => {
|
|
16
|
+
totalWidth += (child as HTMLElement).offsetWidth;
|
|
17
|
+
});
|
|
18
|
+
// 加上子元素之间的间距
|
|
19
|
+
const childGap = 5;
|
|
20
|
+
totalWidth += (buttonChildren.length - 1) * childGap;
|
|
21
|
+
|
|
22
|
+
return totalWidth;
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 判断收起状态下是否应多显示一个搜索项
|
|
3
|
+
*
|
|
4
|
+
* 规则:按钮组宽度大于列宽(按钮组独占更宽空间,首行有富余);
|
|
5
|
+
* 或按钮组宽度小于列宽且可见项刚好比列数多 1(此时收起只会藏起 1 项,不如直接放下)。
|
|
6
|
+
* @param buttonGroupWidth 按钮组宽度
|
|
7
|
+
* @param columnWidth 列宽
|
|
8
|
+
* @param columnNum 搜索项列数(不含按钮组)
|
|
9
|
+
* @param visibleCount 可见搜索项总数
|
|
10
|
+
*/
|
|
11
|
+
export function shouldDisplayExtraItem(
|
|
12
|
+
buttonGroupWidth: number | undefined,
|
|
13
|
+
columnWidth: number | undefined,
|
|
14
|
+
columnNum: number,
|
|
15
|
+
visibleCount: number
|
|
16
|
+
): boolean {
|
|
17
|
+
return (
|
|
18
|
+
buttonGroupWidth !== undefined &&
|
|
19
|
+
columnWidth !== undefined &&
|
|
20
|
+
(buttonGroupWidth > columnWidth ||
|
|
21
|
+
(buttonGroupWidth < columnWidth && columnNum + 1 === visibleCount))
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import FormItem from "../FormItem";
|
|
3
|
-
import React, { CSSProperties } from "react";
|
|
4
|
-
import classNames from "classnames";
|
|
5
|
-
import styles from "./index.module.scss";
|
|
6
|
-
import { useSearchCommon } from "./_hooks";
|
|
1
|
+
import React from "react";
|
|
7
2
|
import SearchCard, { SearchCardProps } from "./SearchCard";
|
|
8
3
|
import SearchAdvanced from "./SearchAdvanced";
|
|
9
4
|
import SearchCollapsible from "./SearchCollapsible";
|
|
10
5
|
import SearchWithFilter from "./SearchWithFilter";
|
|
11
6
|
import SearchWithMore from "./SearchWithMore";
|
|
12
|
-
import
|
|
13
|
-
import { SearchButtons } from "./_components/SearchButtons";
|
|
14
|
-
import { ExpandButton } from "./_components/ExpandButton";
|
|
7
|
+
import SearchBase from "./_components/SearchBase";
|
|
15
8
|
import { BaseSearchProps } from "./_types";
|
|
16
9
|
import { ChakraButtonProps } from "../Button";
|
|
17
10
|
|
|
@@ -43,151 +36,12 @@ export type SearchModePropsMap = {
|
|
|
43
36
|
WithMore: React.ComponentProps<SearchFC["WithMore"]>;
|
|
44
37
|
};
|
|
45
38
|
|
|
39
|
+
/**
|
|
40
|
+
* 基础 Search 组件
|
|
41
|
+
* - 标准的搜索表单布局,自适应列数与展开/收起
|
|
42
|
+
*/
|
|
46
43
|
const Search: SearchFC = (props) => {
|
|
47
|
-
|
|
48
|
-
searchItems = [],
|
|
49
|
-
moreSearchItems = [],
|
|
50
|
-
className,
|
|
51
|
-
onSearch,
|
|
52
|
-
onReset,
|
|
53
|
-
externalForm,
|
|
54
|
-
hasPermi,
|
|
55
|
-
columnNum = 4,
|
|
56
|
-
beforeButtonGroup,
|
|
57
|
-
affterButtonGroup,
|
|
58
|
-
searchData,
|
|
59
|
-
minLabelWidth,
|
|
60
|
-
defaultExpanded = false,
|
|
61
|
-
onExpandChange,
|
|
62
|
-
autoAdaptWidth = true,
|
|
63
|
-
baseWidth,
|
|
64
|
-
onValuesChange,
|
|
65
|
-
searchDisabled = false,
|
|
66
|
-
showAllSearchItems = false,
|
|
67
|
-
searchText,
|
|
68
|
-
resetText,
|
|
69
|
-
columnOffsetWidth = 0,
|
|
70
|
-
} = props;
|
|
71
|
-
|
|
72
|
-
const [form] = AntdForm.useForm(externalForm);
|
|
73
|
-
|
|
74
|
-
const {
|
|
75
|
-
containerRef,
|
|
76
|
-
buttonGroupRef,
|
|
77
|
-
cls,
|
|
78
|
-
getLabelWidth,
|
|
79
|
-
currentSearchItems,
|
|
80
|
-
totalColumnNum,
|
|
81
|
-
expand,
|
|
82
|
-
toggleExpand,
|
|
83
|
-
showExpandButton,
|
|
84
|
-
onSearchClick,
|
|
85
|
-
onResetClick,
|
|
86
|
-
shouldRender,
|
|
87
|
-
permitted,
|
|
88
|
-
} = useSearchCommon({
|
|
89
|
-
form,
|
|
90
|
-
searchItems,
|
|
91
|
-
moreSearchItems,
|
|
92
|
-
searchData,
|
|
93
|
-
hasPermi,
|
|
94
|
-
beforeButtonGroup,
|
|
95
|
-
affterButtonGroup,
|
|
96
|
-
columnNum,
|
|
97
|
-
autoAdaptWidth,
|
|
98
|
-
defaultExpanded,
|
|
99
|
-
onExpandChange,
|
|
100
|
-
showAllSearchItems,
|
|
101
|
-
minLabelWidth,
|
|
102
|
-
baseWidth,
|
|
103
|
-
onSearch,
|
|
104
|
-
onReset,
|
|
105
|
-
columnOffsetWidth,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
if (!shouldRender) {
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<div
|
|
114
|
-
ref={containerRef}
|
|
115
|
-
className={classNames(styles.Search, className)}
|
|
116
|
-
style={
|
|
117
|
-
{
|
|
118
|
-
"--column-number": totalColumnNum,
|
|
119
|
-
"--column-offset-width": `${columnOffsetWidth}px`,
|
|
120
|
-
} as CSSProperties
|
|
121
|
-
}
|
|
122
|
-
>
|
|
123
|
-
<div
|
|
124
|
-
className={classNames(styles.searchOption, styles[expand.toString()])}
|
|
125
|
-
>
|
|
126
|
-
<AntdForm
|
|
127
|
-
form={form}
|
|
128
|
-
className={classNames(styles.option, cls)}
|
|
129
|
-
onValuesChange={onValuesChange}
|
|
130
|
-
>
|
|
131
|
-
{permitted &&
|
|
132
|
-
currentSearchItems?.map((item, idx) => {
|
|
133
|
-
const visibleCurrentItems = currentSearchItems.filter(
|
|
134
|
-
(i) => i.visible !== false
|
|
135
|
-
);
|
|
136
|
-
const columnIndex = idx % totalColumnNum;
|
|
137
|
-
const sameColumnItems = visibleCurrentItems.filter(
|
|
138
|
-
(_, _idx) => _idx % totalColumnNum === columnIndex
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
return (
|
|
142
|
-
<FormItem
|
|
143
|
-
{...item}
|
|
144
|
-
key={item.name}
|
|
145
|
-
className={classNames(styles.item, item.className, {
|
|
146
|
-
[styles.unFill]: item.width !== undefined,
|
|
147
|
-
})}
|
|
148
|
-
labelWidth={
|
|
149
|
-
item.width !== undefined
|
|
150
|
-
? undefined
|
|
151
|
-
: getLabelWidth(sameColumnItems, undefined, minLabelWidth)
|
|
152
|
-
}
|
|
153
|
-
/>
|
|
154
|
-
);
|
|
155
|
-
})}
|
|
156
|
-
{(beforeButtonGroup?.length ||
|
|
157
|
-
affterButtonGroup?.length ||
|
|
158
|
-
permitted) && (
|
|
159
|
-
<ButtonGroup
|
|
160
|
-
beforeButtonGroup={beforeButtonGroup}
|
|
161
|
-
affterButtonGroup={affterButtonGroup}
|
|
162
|
-
expandButton={
|
|
163
|
-
<ExpandButton
|
|
164
|
-
expand={expand}
|
|
165
|
-
toggleExpand={toggleExpand}
|
|
166
|
-
advancedFilters={false}
|
|
167
|
-
showExpandButton={showExpandButton}
|
|
168
|
-
showAllSearchItems={
|
|
169
|
-
showAllSearchItems || !!moreSearchItems?.length
|
|
170
|
-
}
|
|
171
|
-
/>
|
|
172
|
-
}
|
|
173
|
-
permitted={permitted}
|
|
174
|
-
ref={buttonGroupRef}
|
|
175
|
-
>
|
|
176
|
-
{currentSearchItems.length > 0 && (
|
|
177
|
-
<SearchButtons
|
|
178
|
-
onSearch={onSearchClick}
|
|
179
|
-
onReset={onResetClick}
|
|
180
|
-
searchDisabled={searchDisabled}
|
|
181
|
-
searchText={searchText}
|
|
182
|
-
resetText={resetText}
|
|
183
|
-
/>
|
|
184
|
-
)}
|
|
185
|
-
</ButtonGroup>
|
|
186
|
-
)}
|
|
187
|
-
</AntdForm>
|
|
188
|
-
</div>
|
|
189
|
-
</div>
|
|
190
|
-
);
|
|
44
|
+
return <SearchBase {...props} />;
|
|
191
45
|
};
|
|
192
46
|
|
|
193
47
|
Search.Card = SearchCard;
|
|
@@ -32,11 +32,9 @@ const useEllipsisTooltip = <T extends AnyObject>(
|
|
|
32
32
|
? text
|
|
33
33
|
: String(text ?? "");
|
|
34
34
|
|
|
35
|
+
// 不传 width:由 TextEllipsis 实测单元格实际渲染宽度作为 Tooltip 宽度
|
|
36
|
+
// (声明的列宽经 fixedWidth 比例分配后与实际宽度并不一致)
|
|
35
37
|
return React.createElement(TextEllipsis, {
|
|
36
|
-
width:
|
|
37
|
-
Math.max(Number(column.width ?? 0), 300) === 300
|
|
38
|
-
? undefined
|
|
39
|
-
: Math.max(Number(column.width ?? 0), 300),
|
|
40
38
|
tooltipConfig: tooltipConfig,
|
|
41
39
|
children: displayValue,
|
|
42
40
|
ellipsisPosition:
|
|
@@ -23,6 +23,29 @@ import { PaginationProps } from "../_components/Pagination";
|
|
|
23
23
|
const MEASURE_ALIGN_FONT_SIZE = 14;
|
|
24
24
|
// Canvas measureText 仅返回 advance width,较 DOM 实际渲染偏窄约 1px,补 2px 缓冲避免最宽行被挤压
|
|
25
25
|
const MEASURE_ALIGN_BUFFER_PX = 2;
|
|
26
|
+
// 单元格左右内边距合计的默认值(默认 --td-padding: 4px 8px),用于把列宽抬到能放下定宽内容块
|
|
27
|
+
const MEASURE_ALIGN_CELL_PADDING_PX = 16;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 解析 tdPadding(CSS padding 简写)的左右内边距合计;
|
|
31
|
+
* 未传或解析不出时回退默认值(与默认 --td-padding: 4px 8px 一致)。
|
|
32
|
+
*/
|
|
33
|
+
const getCellHorizontalPadding = (tdPadding?: string): number => {
|
|
34
|
+
if (!tdPadding) return MEASURE_ALIGN_CELL_PADDING_PX;
|
|
35
|
+
|
|
36
|
+
const parts = tdPadding
|
|
37
|
+
.trim()
|
|
38
|
+
.split(/\s+/)
|
|
39
|
+
.map((v) => parseFloat(v));
|
|
40
|
+
if (!parts.length || parts.some((v) => Number.isNaN(v))) {
|
|
41
|
+
return MEASURE_ALIGN_CELL_PADDING_PX;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// CSS 简写:1 值=四边;2/3 值=第 2 个为左右;4 值=右+左
|
|
45
|
+
if (parts.length === 1) return parts[0] * 2;
|
|
46
|
+
if (parts.length === 4) return parts[1] + parts[3];
|
|
47
|
+
return parts[1] * 2;
|
|
48
|
+
};
|
|
26
49
|
|
|
27
50
|
// 计算 measureAlign 列的定宽(取本列所有行展示文本的最大像素宽)
|
|
28
51
|
const getMeasureAlignWidth = <T extends AnyObject>(
|
|
@@ -63,6 +86,7 @@ interface UseTableColumnsParams<T extends AnyObject> {
|
|
|
63
86
|
bordered?: boolean;
|
|
64
87
|
rowSelection?: TableRowSelection<T>;
|
|
65
88
|
expandable?: TableProps<T>["expandable"];
|
|
89
|
+
tdPadding?: string;
|
|
66
90
|
}
|
|
67
91
|
|
|
68
92
|
const useTableColumns = <T extends AnyObject>(
|
|
@@ -92,6 +116,7 @@ const useTableColumns = <T extends AnyObject>(
|
|
|
92
116
|
bordered,
|
|
93
117
|
rowSelection,
|
|
94
118
|
expandable,
|
|
119
|
+
tdPadding,
|
|
95
120
|
} = params;
|
|
96
121
|
const { checkPermission } = usePermissions();
|
|
97
122
|
const [tableWidth, setTableWidth] = useState<number | null>(null);
|
|
@@ -159,6 +184,21 @@ const useTableColumns = <T extends AnyObject>(
|
|
|
159
184
|
item.width = Math.max(titleWidth, dataIndexWidth) + 32;
|
|
160
185
|
}
|
|
161
186
|
|
|
187
|
+
// measureAlign 列:列宽须容得下最宽行的定宽内容块 + 单元格左右内边距,
|
|
188
|
+
// 否则出现超长值(如 +3357.52%)时内容会被列宽截断;声明的 width 只作下限。
|
|
189
|
+
if (item.measureAlign && typeof item.width === "number") {
|
|
190
|
+
const measured = getMeasureAlignWidth(
|
|
191
|
+
item as ColumnType<T>,
|
|
192
|
+
dataSource
|
|
193
|
+
);
|
|
194
|
+
if (measured > 0) {
|
|
195
|
+
item.width = Math.max(
|
|
196
|
+
item.width,
|
|
197
|
+
measured + getCellHorizontalPadding(tdPadding)
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
162
202
|
return item;
|
|
163
203
|
})
|
|
164
204
|
?.map((item) => {
|
|
@@ -173,7 +213,7 @@ const useTableColumns = <T extends AnyObject>(
|
|
|
173
213
|
});
|
|
174
214
|
|
|
175
215
|
return newColumns;
|
|
176
|
-
}, [autoWidth, columns, dataSource, checkPermission, scroll]);
|
|
216
|
+
}, [autoWidth, columns, dataSource, checkPermission, scroll, tdPadding]);
|
|
177
217
|
|
|
178
218
|
// 渲染列标题
|
|
179
219
|
const renderColumnTitle = useCallback(
|
|
@@ -82,6 +82,8 @@ export default () => (
|
|
|
82
82
|
| measureAlign | 开启定宽右对齐(配合列 `align: "center"` 使用) | `boolean` | - |
|
|
83
83
|
| measureText | 测量宽度所用文本;当单元格由 `render` 产出复合/JSX 内容时,用它提供与展示一致的文本(默认取 `dataIndex` 原始值) | `(record) => string` | - |
|
|
84
84
|
|
|
85
|
+
- 列宽自适应:声明的 `width` 只作下限——实际列宽会按「本列最宽内容块的测量宽 + 单元格左右内边距」自动抬升,出现超长值(如 `+3357.52%`)时内容不会被声明宽度截断。
|
|
86
|
+
|
|
85
87
|
> 注意:不适用于 `render` 返回 `{ children, rowSpan }` 这类合并单元格场景。
|
|
86
88
|
|
|
87
89
|
> 另导出 `TableDrag`,用于行拖拽排序场景。
|
|
@@ -37,7 +37,7 @@ export default () => (
|
|
|
37
37
|
| --- | --- | --- | --- |
|
|
38
38
|
| children | 要显示的文本内容 | `ReactNode` | - |
|
|
39
39
|
| width | 容器宽度,用于计算 Tooltip 宽度 | `number \| string` | - |
|
|
40
|
-
| tooltipConfig | Tooltip 配置(可附加 `defaultWidth
|
|
40
|
+
| tooltipConfig | Tooltip 配置(可附加 `defaultWidth`:容器实际宽度实测不到时的兜底宽) | `Omit<TooltipProps, 'title' \| 'children'> & { defaultWidth?: number }` | - |
|
|
41
41
|
| disabled | 是否禁用 Tooltip(即使溢出也不显示) | `boolean` | `false` |
|
|
42
42
|
| ellipsisPosition | 省略号位置,`start` 省略前面,`end` 省略后面 | `'start' \| 'end'` | `'end'` |
|
|
43
43
|
| style | 文本自定义样式 | `React.CSSProperties` | - |
|
|
@@ -45,6 +45,8 @@ const TextEllipsis: React.FC<TextEllipsisProps> = ({
|
|
|
45
45
|
const measureRef = useRef<HTMLSpanElement>(null);
|
|
46
46
|
const [isOverflow, setIsOverflow] = useState(false);
|
|
47
47
|
const [truncatedText, setTruncatedText] = useState<ReactNode>(children);
|
|
48
|
+
// 容器实际渲染宽度:未声明 width 时(如表格列宽动态分配)作为 Tooltip 宽度
|
|
49
|
+
const [measuredWidth, setMeasuredWidth] = useState(0);
|
|
48
50
|
|
|
49
51
|
useEffect(() => {
|
|
50
52
|
const element = textRef.current;
|
|
@@ -105,29 +107,42 @@ const TextEllipsis: React.FC<TextEllipsisProps> = ({
|
|
|
105
107
|
};
|
|
106
108
|
|
|
107
109
|
const textContent = getTextContent(children);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
110
|
+
|
|
111
|
+
const update = () => {
|
|
112
|
+
const isTextOverflow =
|
|
113
|
+
element.scrollWidth > element.clientWidth ||
|
|
114
|
+
element.scrollHeight > element.clientHeight;
|
|
115
|
+
|
|
116
|
+
setIsOverflow(isTextOverflow);
|
|
117
|
+
setMeasuredWidth(element.clientWidth);
|
|
118
|
+
|
|
119
|
+
// 如果是省略前面且文本溢出,需要计算截断后的文本
|
|
120
|
+
if (ellipsisPosition === "start" && isTextOverflow && textContent) {
|
|
121
|
+
const maxWidth = element.clientWidth;
|
|
122
|
+
const truncated = calculateTruncatedText(textContent, maxWidth);
|
|
123
|
+
setTruncatedText(truncated);
|
|
124
|
+
} else {
|
|
125
|
+
setTruncatedText(children);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
update();
|
|
130
|
+
|
|
131
|
+
// 容器宽度动态变化(如表格列宽重分配、窗口 resize)时重测溢出与宽度
|
|
132
|
+
const resizeObserver = new ResizeObserver(update);
|
|
133
|
+
resizeObserver.observe(element);
|
|
134
|
+
return () => resizeObserver.disconnect();
|
|
122
135
|
}, [children, ellipsisPosition, style]);
|
|
123
136
|
|
|
124
|
-
// 计算 Tooltip
|
|
137
|
+
// 计算 Tooltip 的宽度:显式 width 优先;未声明(或百分比)时用容器实际渲染宽度,
|
|
138
|
+
// 实测不到再回退 defaultWidth
|
|
125
139
|
const getTooltipWidth = () => {
|
|
126
140
|
const defaultWidth = tooltipConfig?.defaultWidth ?? DEFAULT_TOOLTIP_WIDTH;
|
|
127
|
-
|
|
141
|
+
const dynamicWidth = measuredWidth > 0 ? measuredWidth : defaultWidth;
|
|
142
|
+
if (!width) return dynamicWidth;
|
|
128
143
|
if (typeof width === "number") return width;
|
|
129
|
-
if (typeof width === "string" && width.includes("%")) return
|
|
130
|
-
return parseInt(width) ||
|
|
144
|
+
if (typeof width === "string" && width.includes("%")) return dynamicWidth;
|
|
145
|
+
return parseInt(width) || dynamicWidth;
|
|
131
146
|
};
|
|
132
147
|
|
|
133
148
|
const tooltipWidth = getTooltipWidth();
|
|
File without changes
|
|
File without changes
|