@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.
Files changed (88) hide show
  1. package/README.md +2 -2
  2. package/es/components/FormItem/ItemContainer/index.d.ts +2 -0
  3. package/es/components/FormItem/ItemContainer/index.js +4 -15
  4. package/es/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.d.ts +3 -3
  5. package/es/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.js +3 -3
  6. package/es/components/Search/SearchAdvanced/index.js +26 -148
  7. package/es/components/Search/SearchCard/index.js +1 -1
  8. package/es/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.js +2 -2
  9. package/es/components/Search/SearchCollapsible/index.js +17 -138
  10. package/es/components/Search/SearchWithFilter/index.js +4 -143
  11. package/es/components/Search/SearchWithMore/index.js +11 -142
  12. package/es/components/Search/_components/FilterDropdown/index.js +5 -6
  13. package/es/components/Search/_components/SearchBase/index.d.ts +32 -0
  14. package/es/components/Search/_components/SearchBase/index.js +185 -0
  15. package/es/components/Search/_hooks/useSearchCommon.js +5 -11
  16. package/es/components/Search/_hooks/useSearchExpand.js +4 -13
  17. package/es/components/Search/_utils/calculateButtonGroupAndColumnWidth.js +3 -10
  18. package/es/components/Search/_utils/calculateVisibleItems.js +4 -5
  19. package/es/components/Search/_utils/index.d.ts +2 -0
  20. package/es/components/Search/_utils/index.js +3 -1
  21. package/es/components/Search/_utils/measureButtonGroupWidth.d.ts +6 -0
  22. package/es/components/Search/_utils/measureButtonGroupWidth.js +18 -0
  23. package/es/components/Search/_utils/shouldDisplayExtraItem.d.ts +11 -0
  24. package/es/components/Search/_utils/shouldDisplayExtraItem.js +13 -0
  25. package/es/components/Search/index.d.ts +4 -0
  26. package/es/components/Search/index.js +6 -133
  27. package/es/components/Table/_hooks/useEllipsisTooltip.js +4 -2
  28. package/es/components/Table/_hooks/useTableColumns.d.ts +1 -0
  29. package/es/components/Table/_hooks/useTableColumns.js +35 -2
  30. package/es/components/Table/index.js +2 -1
  31. package/es/components/TextEllipsis/index.js +32 -14
  32. package/lib/components/FormItem/ItemContainer/index.d.ts +2 -0
  33. package/lib/components/FormItem/ItemContainer/index.js +2 -5
  34. package/lib/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.d.ts +3 -3
  35. package/lib/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.js +3 -3
  36. package/lib/components/Search/SearchAdvanced/index.js +19 -134
  37. package/lib/components/Search/SearchCard/index.js +1 -1
  38. package/lib/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.js +2 -2
  39. package/lib/components/Search/SearchCollapsible/index.js +12 -124
  40. package/lib/components/Search/SearchWithFilter/index.js +5 -129
  41. package/lib/components/Search/SearchWithMore/index.js +7 -126
  42. package/lib/components/Search/_components/FilterDropdown/index.js +5 -6
  43. package/lib/components/Search/_components/SearchBase/index.d.ts +32 -0
  44. package/lib/components/Search/_components/SearchBase/index.js +169 -0
  45. package/lib/components/Search/_hooks/useSearchCommon.js +4 -6
  46. package/lib/components/Search/_hooks/useSearchExpand.js +2 -13
  47. package/lib/components/Search/_utils/calculateButtonGroupAndColumnWidth.js +2 -10
  48. package/lib/components/Search/_utils/calculateVisibleItems.js +3 -5
  49. package/lib/components/Search/_utils/index.d.ts +2 -0
  50. package/lib/components/Search/_utils/index.js +15 -1
  51. package/lib/components/Search/_utils/measureButtonGroupWidth.d.ts +6 -0
  52. package/lib/components/Search/_utils/measureButtonGroupWidth.js +24 -0
  53. package/lib/components/Search/_utils/shouldDisplayExtraItem.d.ts +11 -0
  54. package/lib/components/Search/_utils/shouldDisplayExtraItem.js +19 -0
  55. package/lib/components/Search/index.d.ts +4 -0
  56. package/lib/components/Search/index.js +8 -119
  57. package/lib/components/Table/_hooks/useEllipsisTooltip.js +3 -1
  58. package/lib/components/Table/_hooks/useTableColumns.d.ts +1 -0
  59. package/lib/components/Table/_hooks/useTableColumns.js +31 -2
  60. package/lib/components/Table/index.js +2 -1
  61. package/lib/components/TextEllipsis/index.js +27 -14
  62. package/package.json +1 -1
  63. package/src/components/FormItem/ItemContainer/index.tsx +4 -7
  64. package/src/components/Search/{_components → SearchAdvanced/_components}/AdvancedFiltersDrawer/index.tsx +6 -6
  65. package/src/components/Search/SearchAdvanced/index.tsx +25 -164
  66. package/src/components/Search/SearchCard/index.tsx +1 -1
  67. package/src/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.tsx +2 -2
  68. package/src/components/Search/SearchCollapsible/index.tsx +13 -162
  69. package/src/components/Search/SearchWithFilter/index.tsx +2 -164
  70. package/src/components/Search/SearchWithMore/index.tsx +9 -161
  71. package/src/components/Search/_components/FilterDropdown/index.tsx +5 -6
  72. package/src/components/Search/_components/SearchBase/index.tsx +224 -0
  73. package/src/components/Search/_hooks/useSearchCommon.ts +10 -13
  74. package/src/components/Search/_hooks/useSearchExpand.ts +3 -13
  75. package/src/components/Search/_utils/calculateButtonGroupAndColumnWidth.ts +2 -10
  76. package/src/components/Search/_utils/calculateVisibleItems.ts +10 -11
  77. package/src/components/Search/_utils/index.ts +2 -0
  78. package/src/components/Search/_utils/measureButtonGroupWidth.ts +23 -0
  79. package/src/components/Search/_utils/shouldDisplayExtraItem.ts +23 -0
  80. package/src/components/Search/index.tsx +7 -153
  81. package/src/components/Table/_hooks/useEllipsisTooltip.ts +2 -4
  82. package/src/components/Table/_hooks/useTableColumns.tsx +41 -1
  83. package/src/components/Table/index.md +2 -0
  84. package/src/components/Table/index.tsx +1 -0
  85. package/src/components/TextEllipsis/index.md +1 -1
  86. package/src/components/TextEllipsis/index.tsx +33 -18
  87. /package/es/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.d.ts +0 -0
  88. /package/lib/components/Search/{_components → SearchCollapsible/_components}/CollapseToggle/index.d.ts +0 -0
@@ -19,6 +19,25 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
19
19
  const MEASURE_ALIGN_FONT_SIZE = 14;
20
20
  // Canvas measureText 仅返回 advance width,较 DOM 实际渲染偏窄约 1px,补 2px 缓冲避免最宽行被挤压
21
21
  const MEASURE_ALIGN_BUFFER_PX = 2;
22
+ // 单元格左右内边距合计的默认值(默认 --td-padding: 4px 8px),用于把列宽抬到能放下定宽内容块
23
+ const MEASURE_ALIGN_CELL_PADDING_PX = 16;
24
+
25
+ /**
26
+ * 解析 tdPadding(CSS padding 简写)的左右内边距合计;
27
+ * 未传或解析不出时回退默认值(与默认 --td-padding: 4px 8px 一致)。
28
+ */
29
+ const getCellHorizontalPadding = tdPadding => {
30
+ if (!tdPadding) return MEASURE_ALIGN_CELL_PADDING_PX;
31
+ const parts = tdPadding.trim().split(/\s+/).map(v => parseFloat(v));
32
+ if (!parts.length || parts.some(v => Number.isNaN(v))) {
33
+ return MEASURE_ALIGN_CELL_PADDING_PX;
34
+ }
35
+
36
+ // CSS 简写:1 值=四边;2/3 值=第 2 个为左右;4 值=右+左
37
+ if (parts.length === 1) return parts[0] * 2;
38
+ if (parts.length === 4) return parts[1] + parts[3];
39
+ return parts[1] * 2;
40
+ };
22
41
 
23
42
  // 计算 measureAlign 列的定宽(取本列所有行展示文本的最大像素宽)
24
43
  const getMeasureAlignWidth = (column, dataSource) => {
@@ -55,7 +74,8 @@ const useTableColumns = params => {
55
74
  cls,
56
75
  bordered,
57
76
  rowSelection,
58
- expandable
77
+ expandable,
78
+ tdPadding
59
79
  } = params;
60
80
  const {
61
81
  checkPermission
@@ -109,6 +129,15 @@ const useTableColumns = params => {
109
129
  }, 0) ?? 0 : 0;
110
130
  item.width = Math.max(titleWidth, dataIndexWidth) + 32;
111
131
  }
132
+
133
+ // measureAlign 列:列宽须容得下最宽行的定宽内容块 + 单元格左右内边距,
134
+ // 否则出现超长值(如 +3357.52%)时内容会被列宽截断;声明的 width 只作下限。
135
+ if (item.measureAlign && typeof item.width === "number") {
136
+ const measured = getMeasureAlignWidth(item, dataSource);
137
+ if (measured > 0) {
138
+ item.width = Math.max(item.width, measured + getCellHorizontalPadding(tdPadding));
139
+ }
140
+ }
112
141
  return item;
113
142
  })?.map(item => {
114
143
  return {
@@ -121,7 +150,7 @@ const useTableColumns = params => {
121
150
  };
122
151
  });
123
152
  return newColumns;
124
- }, [autoWidth, columns, dataSource, checkPermission, scroll]);
153
+ }, [autoWidth, columns, dataSource, checkPermission, scroll, tdPadding]);
125
154
 
126
155
  // 渲染列标题
127
156
  const renderColumnTitle = (0, _react.useCallback)(column => {
@@ -125,7 +125,8 @@ const Table = props => {
125
125
  cls,
126
126
  bordered,
127
127
  rowSelection,
128
- expandable
128
+ expandable,
129
+ tdPadding
129
130
  });
130
131
  (0, _useSetTableHeight.default)({
131
132
  pagination,
@@ -29,6 +29,8 @@ const TextEllipsis = ({
29
29
  const measureRef = (0, _react.useRef)(null);
30
30
  const [isOverflow, setIsOverflow] = (0, _react.useState)(false);
31
31
  const [truncatedText, setTruncatedText] = (0, _react.useState)(children);
32
+ // 容器实际渲染宽度:未声明 width 时(如表格列宽动态分配)作为 Tooltip 宽度
33
+ const [measuredWidth, setMeasuredWidth] = (0, _react.useState)(0);
32
34
  (0, _react.useEffect)(() => {
33
35
  const element = textRef.current;
34
36
  const measureElement = measureRef.current;
@@ -84,26 +86,37 @@ const TextEllipsis = ({
84
86
  return result;
85
87
  };
86
88
  const textContent = getTextContent(children);
87
- const isTextOverflow = element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight;
88
- setIsOverflow(isTextOverflow);
89
+ const update = () => {
90
+ const isTextOverflow = element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight;
91
+ setIsOverflow(isTextOverflow);
92
+ setMeasuredWidth(element.clientWidth);
89
93
 
90
- // 如果是省略前面且文本溢出,需要计算截断后的文本
91
- if (ellipsisPosition === "start" && isTextOverflow && textContent) {
92
- const maxWidth = element.clientWidth;
93
- const truncated = calculateTruncatedText(textContent, maxWidth);
94
- setTruncatedText(truncated);
95
- } else {
96
- setTruncatedText(children);
97
- }
94
+ // 如果是省略前面且文本溢出,需要计算截断后的文本
95
+ if (ellipsisPosition === "start" && isTextOverflow && textContent) {
96
+ const maxWidth = element.clientWidth;
97
+ const truncated = calculateTruncatedText(textContent, maxWidth);
98
+ setTruncatedText(truncated);
99
+ } else {
100
+ setTruncatedText(children);
101
+ }
102
+ };
103
+ update();
104
+
105
+ // 容器宽度动态变化(如表格列宽重分配、窗口 resize)时重测溢出与宽度
106
+ const resizeObserver = new ResizeObserver(update);
107
+ resizeObserver.observe(element);
108
+ return () => resizeObserver.disconnect();
98
109
  }, [children, ellipsisPosition, style]);
99
110
 
100
- // 计算 Tooltip 的宽度
111
+ // 计算 Tooltip 的宽度:显式 width 优先;未声明(或百分比)时用容器实际渲染宽度,
112
+ // 实测不到再回退 defaultWidth
101
113
  const getTooltipWidth = () => {
102
114
  const defaultWidth = tooltipConfig?.defaultWidth ?? DEFAULT_TOOLTIP_WIDTH;
103
- if (!width) return defaultWidth;
115
+ const dynamicWidth = measuredWidth > 0 ? measuredWidth : defaultWidth;
116
+ if (!width) return dynamicWidth;
104
117
  if (typeof width === "number") return width;
105
- if (typeof width === "string" && width.includes("%")) return defaultWidth;
106
- return parseInt(width) || defaultWidth;
118
+ if (typeof width === "string" && width.includes("%")) return dynamicWidth;
119
+ return parseInt(width) || dynamicWidth;
107
120
  };
108
121
  const tooltipWidth = getTooltipWidth();
109
122
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hsu-react/ui",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "一套基于 React + Ant Design 的中后台业务组件库",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -46,6 +46,8 @@ export interface ItemContainerProps extends FormItemProps {
46
46
  labelBreak?: boolean;
47
47
  hideAdditiona?: boolean;
48
48
  hideLabel?: boolean;
49
+ /** 显隐开关,由 FormItem 消费;在此解构剥离,避免透传到 DOM */
50
+ visible?: boolean;
49
51
  }
50
52
 
51
53
  const ItemContainer: React.FC<ItemContainerProps> = (props) => {
@@ -84,6 +86,7 @@ const ItemContainer: React.FC<ItemContainerProps> = (props) => {
84
86
  labelBreak = false,
85
87
  hideAdditiona = false,
86
88
  hideLabel = false,
89
+ visible: _visible,
87
90
  ...formItemProps
88
91
  } = props;
89
92
  const { icon = "material-symbols:help", iconClassName, ...tipsConfig } = tips;
@@ -198,15 +201,9 @@ const ItemContainer: React.FC<ItemContainerProps> = (props) => {
198
201
  return null;
199
202
  }
200
203
 
201
- // 页面层 FormItemProps 的展示控制属性(如 visible)不属于 antd Form.Item,
202
- // 剥离后再透传,避免被 antd 转发到 DOM 触发 React 非法属性警告。
203
- const restFormItemProps = Object.fromEntries(
204
- Object.entries(formItemProps).filter(([key]) => key !== "visible")
205
- );
206
-
207
204
  return (
208
205
  <Form.Item
209
- {...restFormItemProps}
206
+ {...formItemProps}
210
207
  name={name}
211
208
  rules={[
212
209
  {
@@ -1,12 +1,12 @@
1
1
  import React from "react";
2
2
  import type { FormInstance } from "antd";
3
- import Form from "../../../Form";
3
+ import Form from "../../../../Form";
4
4
  import { FilterFilled } from "@ant-design/icons";
5
- import { FormItemProps } from "../../../FormItem";
6
- import { DrawerFormProps } from "../../../Form/DrawerForm";
7
- import Icon from "../../../Icon";
8
- import type useLabelWidth from "../../../../hooks/useLabelWidth";
9
- import styles from "../../index.module.scss";
5
+ import { FormItemProps } from "../../../../FormItem";
6
+ import { DrawerFormProps } from "../../../../Form/DrawerForm";
7
+ import Icon from "../../../../Icon";
8
+ import type useLabelWidth from "../../../../../hooks/useLabelWidth";
9
+ import styles from "../../../index.module.scss";
10
10
 
11
11
  interface AdvancedFiltersDrawerProps {
12
12
  expand: boolean;
@@ -1,17 +1,10 @@
1
1
  import React from "react";
2
- import { Form as AntdForm } from "antd";
3
- import FormItem from "../../FormItem";
4
- import { CSSProperties } from "react";
5
2
  import classNames from "classnames";
6
3
  import styles from "../index.module.scss";
7
- import { useSearchCommon } from "../_hooks";
4
+ import SearchBase from "../_components/SearchBase";
5
+ import { AdvancedFiltersDrawer } from "./_components/AdvancedFiltersDrawer";
8
6
  import { ChakraButtonProps } from "../../Button";
9
7
  import { DrawerFormProps } from "../../Form/DrawerForm";
10
- import { ButtonGroup } from "../_components/ButtonGroup";
11
- import { SearchButtons } from "../_components/SearchButtons";
12
- import { FilterDropdown } from "../_components/FilterDropdown";
13
- import { ExpandButton } from "../_components/ExpandButton";
14
- import { AdvancedFiltersDrawer } from "../_components/AdvancedFiltersDrawer";
15
8
  import { SearchPropsWithFilter } from "../_types";
16
9
 
17
10
  export interface SearchAdvancedProps extends SearchPropsWithFilter {
@@ -28,168 +21,36 @@ export interface SearchAdvancedProps extends SearchPropsWithFilter {
28
21
  */
29
22
  const SearchAdvanced: React.FC<SearchAdvancedProps> = (props) => {
30
23
  const {
31
- searchItems = [],
32
- moreSearchItems = [],
33
24
  className,
34
- onSearch,
35
- onReset,
36
- externalForm,
37
- hasPermi,
38
- columnNum = 4,
39
- beforeButtonGroup,
40
- affterButtonGroup,
41
- searchData,
42
25
  advancedFiltersProps,
43
26
  setFilter,
44
27
  minLabelWidth,
45
- defaultExpanded = false,
46
- onExpandChange,
47
- autoAdaptWidth = true,
48
- baseWidth,
49
- onValuesChange,
50
- searchDisabled = false,
51
- showAllSearchItems = false,
52
- searchText,
53
- resetText,
54
- onFilterChange,
55
- columnOffsetWidth = 0,
28
+ ...rest
56
29
  } = props;
57
30
 
58
- const [form] = AntdForm.useForm(externalForm);
59
-
60
- const {
61
- containerRef,
62
- buttonGroupRef,
63
- cls,
64
- getLabelWidth,
65
- processedSearchItems,
66
- setSearchItems,
67
- currentSearchItems,
68
- totalColumnNum,
69
- expand,
70
- setExpand,
71
- toggleExpand,
72
- showExpandButton,
73
- onSearchClick,
74
- onResetClick,
75
- shouldRender,
76
- permitted,
77
- } = useSearchCommon({
78
- form,
79
- searchItems,
80
- moreSearchItems,
81
- searchData,
82
- hasPermi,
83
- beforeButtonGroup,
84
- affterButtonGroup,
85
- columnNum,
86
- autoAdaptWidth,
87
- defaultExpanded,
88
- onExpandChange,
89
- showAllSearchItems,
90
- minLabelWidth,
91
- baseWidth,
92
- onSearch,
93
- onReset,
94
- columnOffsetWidth,
95
- });
96
-
97
- if (!shouldRender) {
98
- return null;
99
- }
100
-
101
31
  return (
102
- <>
103
- <div
104
- ref={containerRef}
105
- className={classNames(styles.Search, className, {
106
- [styles.advancedFilters]: true,
107
- })}
108
- style={
109
- {
110
- "--column-number": totalColumnNum,
111
- "--column-offset-width": `${columnOffsetWidth}px`,
112
- } as CSSProperties
113
- }
114
- >
115
- <div
116
- className={classNames(styles.searchOption, styles[expand.toString()])}
117
- >
118
- <AntdForm
119
- form={form}
120
- className={classNames(styles.option, cls)}
121
- onValuesChange={onValuesChange}
122
- >
123
- {permitted &&
124
- currentSearchItems?.map((item) => {
125
- return (
126
- <FormItem
127
- {...item}
128
- key={item.name}
129
- className={classNames(styles.item, item.className, {
130
- [styles.unFill]: item.width !== undefined,
131
- })}
132
- label={undefined}
133
- labelWidth={undefined}
134
- />
135
- );
136
- })}
137
- {(beforeButtonGroup?.length ||
138
- affterButtonGroup?.length ||
139
- permitted) && (
140
- <ButtonGroup
141
- beforeButtonGroup={beforeButtonGroup}
142
- affterButtonGroup={affterButtonGroup}
143
- expandButton={
144
- <ExpandButton
145
- expand={expand}
146
- toggleExpand={toggleExpand}
147
- advancedFilters={true}
148
- showExpandButton={showExpandButton}
149
- showAllSearchItems={
150
- showAllSearchItems || !!moreSearchItems?.length
151
- }
152
- />
153
- }
154
- permitted={permitted}
155
- ref={buttonGroupRef}
156
- >
157
- {currentSearchItems.length > 0 && (
158
- <SearchButtons
159
- onSearch={onSearchClick}
160
- onReset={onResetClick}
161
- searchDisabled={searchDisabled}
162
- searchText={searchText}
163
- resetText={resetText}
164
- />
165
- )}
166
- {setFilter && (
167
- <FilterDropdown
168
- searchItems={processedSearchItems}
169
- originalSearchItems={searchItems}
170
- setSearchItems={setSearchItems}
171
- onFilterChange={onFilterChange}
172
- />
173
- )}
174
- </ButtonGroup>
175
- )}
176
- </AntdForm>
177
- </div>
178
- </div>
179
- {permitted && setExpand && (
180
- <AdvancedFiltersDrawer
181
- expand={expand}
182
- setExpand={setExpand}
183
- searchItems={processedSearchItems}
184
- form={form}
185
- getLabelWidth={getLabelWidth}
186
- minLabelWidth={minLabelWidth}
187
- onSearchClick={onSearchClick}
188
- onResetClick={onResetClick}
189
- advancedFiltersProps={advancedFiltersProps}
190
- />
191
- )}
192
- </>
32
+ <SearchBase
33
+ {...rest}
34
+ minLabelWidth={minLabelWidth}
35
+ advancedFilters
36
+ showFilter={!!setFilter}
37
+ className={classNames(className, styles.advancedFilters)}
38
+ renderOutside={(ctx) =>
39
+ ctx.setExpand && (
40
+ <AdvancedFiltersDrawer
41
+ expand={ctx.expand}
42
+ setExpand={ctx.setExpand}
43
+ searchItems={ctx.processedSearchItems}
44
+ form={ctx.form}
45
+ getLabelWidth={ctx.getLabelWidth}
46
+ minLabelWidth={minLabelWidth}
47
+ onSearchClick={ctx.onSearchClick}
48
+ onResetClick={ctx.onResetClick}
49
+ advancedFiltersProps={advancedFiltersProps}
50
+ />
51
+ )
52
+ }
53
+ />
193
54
  );
194
55
  };
195
56
 
@@ -77,7 +77,7 @@ const SearchCard: React.FC<SearchCardProps> = memo((props) => {
77
77
  style={
78
78
  {
79
79
  "--searchCard-column-gap": `${gap}px`,
80
- " --searchCard-padding-left-right": `${padding}px`,
80
+ "--searchCard-padding-left-right": `${padding}px`,
81
81
  } as CSSProperties
82
82
  }
83
83
  >
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
- import Icon from "../../../Icon";
2
+ import Icon from "../../../../Icon";
3
3
  import classNames from "classnames";
4
- import styles from "../../index.module.scss";
4
+ import styles from "../../../index.module.scss";
5
5
 
6
6
  interface CollapseToggleProps {
7
7
  collapse: boolean;
@@ -1,16 +1,9 @@
1
- import React from "react";
2
- import { Form as AntdForm } from "antd";
3
- import FormItem from "../../FormItem";
4
- import { CSSProperties, useCallback, useState } from "react";
1
+ import React, { useCallback, useState } from "react";
5
2
  import classNames from "classnames";
6
3
  import styles from "../index.module.scss";
7
- import { useSearchCommon } from "../_hooks";
4
+ import SearchBase from "../_components/SearchBase";
5
+ import { CollapseToggle } from "./_components/CollapseToggle";
8
6
  import { ChakraButtonProps } from "../../Button";
9
- import { ButtonGroup } from "../_components/ButtonGroup";
10
- import { SearchButtons } from "../_components/SearchButtons";
11
- import { FilterDropdown } from "../_components/FilterDropdown";
12
- import { ExpandButton } from "../_components/ExpandButton";
13
- import { CollapseToggle } from "../_components/CollapseToggle";
14
7
  import { SearchPropsWithFilter } from "../_types";
15
8
 
16
9
  export interface SearchCollapsibleProps extends SearchPropsWithFilter {
@@ -27,73 +20,16 @@ export interface SearchCollapsibleProps extends SearchPropsWithFilter {
27
20
  */
28
21
  const SearchCollapsible: React.FC<SearchCollapsibleProps> = (props) => {
29
22
  const {
30
- searchItems = [],
31
- moreSearchItems = [],
32
23
  className,
33
- onSearch,
34
- onReset,
35
- externalForm,
36
- hasPermi,
37
- columnNum = 4,
38
- beforeButtonGroup,
39
- affterButtonGroup,
40
- searchData,
41
- setFilter,
42
- minLabelWidth,
43
24
  defaultExpanded = false,
44
25
  onCollapseToggle,
45
- onExpandChange,
46
- autoAdaptWidth = true,
47
- baseWidth,
48
- onValuesChange,
49
- searchDisabled = false,
50
- showAllSearchItems = false,
51
- searchText,
52
- resetText,
53
- onFilterChange,
54
- columnOffsetWidth = 0,
26
+ setFilter,
27
+ ...rest
55
28
  } = props;
56
29
 
57
- const [form] = AntdForm.useForm(externalForm);
58
30
  // collapse 的语义是反的,所以需要取反 defaultExpanded
59
31
  const [collapse, setCollapse] = useState(!defaultExpanded);
60
32
 
61
- const {
62
- containerRef,
63
- buttonGroupRef,
64
- cls,
65
- getLabelWidth,
66
- processedSearchItems,
67
- setSearchItems,
68
- currentSearchItems,
69
- totalColumnNum,
70
- expand,
71
- toggleExpand,
72
- showExpandButton,
73
- onSearchClick,
74
- onResetClick,
75
- shouldRender,
76
- permitted,
77
- } = useSearchCommon({
78
- form,
79
- searchItems,
80
- moreSearchItems,
81
- searchData,
82
- hasPermi,
83
- beforeButtonGroup,
84
- affterButtonGroup,
85
- columnNum,
86
- autoAdaptWidth,
87
- defaultExpanded,
88
- onExpandChange,
89
- showAllSearchItems,
90
- minLabelWidth,
91
- baseWidth,
92
- onSearch,
93
- onReset,
94
- columnOffsetWidth,
95
- });
96
-
97
33
  // 处理折叠切换
98
34
  const handleCollapseToggle = useCallback(() => {
99
35
  setCollapse((prev) => {
@@ -103,103 +39,18 @@ const SearchCollapsible: React.FC<SearchCollapsibleProps> = (props) => {
103
39
  });
104
40
  }, [onCollapseToggle]);
105
41
 
106
- if (!shouldRender) {
107
- return null;
108
- }
109
-
110
42
  return (
111
- <div
112
- ref={containerRef}
113
- className={classNames(styles.Search, className, {
114
- [styles.collapseExpand]: true,
43
+ <SearchBase
44
+ {...rest}
45
+ defaultExpanded={defaultExpanded}
46
+ showFilter={!!setFilter}
47
+ className={classNames(className, styles.collapseExpand, {
115
48
  [styles.collapse]: collapse,
116
49
  })}
117
- style={
118
- {
119
- "--column-number": totalColumnNum,
120
- "--column-offset-width": `${columnOffsetWidth}px`,
121
- } as CSSProperties
122
- }
123
- >
124
- <div
125
- className={classNames(styles.searchOption, styles[expand.toString()])}
126
- >
127
- <AntdForm
128
- form={form}
129
- className={classNames(styles.option, cls)}
130
- onValuesChange={onValuesChange}
131
- >
132
- {permitted &&
133
- currentSearchItems?.map((item, idx) => {
134
- // 计算同一列的项(用于计算标签宽度)
135
- const visibleCurrentItems = currentSearchItems.filter(
136
- (i) => i.visible !== false
137
- );
138
- const columnIndex = idx % totalColumnNum;
139
- const sameColumnItems = visibleCurrentItems.filter(
140
- (_, _idx) => _idx % totalColumnNum === columnIndex
141
- );
142
-
143
- return (
144
- <FormItem
145
- {...item}
146
- key={item.name}
147
- className={classNames(styles.item, item.className, {
148
- [styles.unFill]: item.width !== undefined,
149
- })}
150
- labelWidth={
151
- item.width !== undefined
152
- ? undefined
153
- : getLabelWidth(sameColumnItems, undefined, minLabelWidth)
154
- }
155
- />
156
- );
157
- })}
158
- {(beforeButtonGroup?.length ||
159
- affterButtonGroup?.length ||
160
- permitted) && (
161
- <ButtonGroup
162
- beforeButtonGroup={beforeButtonGroup}
163
- affterButtonGroup={affterButtonGroup}
164
- expandButton={
165
- <ExpandButton
166
- expand={expand}
167
- toggleExpand={toggleExpand}
168
- advancedFilters={false}
169
- showExpandButton={showExpandButton}
170
- showAllSearchItems={
171
- showAllSearchItems || !!moreSearchItems?.length
172
- }
173
- />
174
- }
175
- permitted={permitted}
176
- ref={buttonGroupRef}
177
- >
178
- {currentSearchItems.length > 0 && (
179
- <SearchButtons
180
- onSearch={onSearchClick}
181
- onReset={onResetClick}
182
- searchDisabled={searchDisabled}
183
- searchText={searchText}
184
- resetText={resetText}
185
- />
186
- )}
187
- {setFilter && (
188
- <FilterDropdown
189
- searchItems={processedSearchItems}
190
- originalSearchItems={searchItems}
191
- setSearchItems={setSearchItems}
192
- onFilterChange={onFilterChange}
193
- />
194
- )}
195
- </ButtonGroup>
196
- )}
197
- </AntdForm>
198
- </div>
199
- {permitted && (
50
+ afterForm={
200
51
  <CollapseToggle collapse={collapse} onToggle={handleCollapseToggle} />
201
- )}
202
- </div>
52
+ }
53
+ />
203
54
  );
204
55
  };
205
56