@oceanbase/design 1.0.0-alpha.15 → 1.0.0-alpha.17

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 (79) hide show
  1. package/dist/design.min.js +1 -1
  2. package/es/alert/index.d.ts +1 -1
  3. package/es/alert/index.js +4 -2
  4. package/es/filter/components/CountNumber.js +2 -1
  5. package/es/filter/components/FilterButton.d.ts +2 -0
  6. package/es/filter/components/FilterButton.js +6 -3
  7. package/es/filter/components/FilterCascader/components/CascaderOption/OptionCheckbox.d.ts +20 -0
  8. package/es/filter/components/FilterCascader/components/CascaderOption/OptionCheckbox.js +101 -0
  9. package/es/filter/components/FilterCascader/components/CascaderOption/OptionItem.d.ts +13 -0
  10. package/es/filter/components/FilterCascader/components/CascaderOption/OptionItem.js +44 -0
  11. package/es/filter/components/FilterCascader/components/FlatCascaderContent/index.d.ts +16 -0
  12. package/es/filter/components/FilterCascader/components/FlatCascaderContent/index.js +64 -0
  13. package/es/filter/components/FilterCascader/components/NormalCascaderContent.d.ts +24 -0
  14. package/es/filter/components/FilterCascader/components/NormalCascaderContent.js +284 -0
  15. package/es/filter/components/FilterCascader/constants.d.ts +7 -0
  16. package/es/filter/components/FilterCascader/constants.js +8 -0
  17. package/es/filter/components/FilterCascader/hooks/useCascaderCallbacks.d.ts +12 -0
  18. package/es/filter/components/FilterCascader/hooks/useCascaderCallbacks.js +101 -0
  19. package/es/filter/components/FilterCascader/hooks/useCascaderLabels.d.ts +9 -0
  20. package/es/filter/components/FilterCascader/hooks/useCascaderLabels.js +50 -0
  21. package/es/filter/components/FilterCascader/hooks/useNormalizedValue.d.ts +7 -0
  22. package/es/filter/components/FilterCascader/hooks/useNormalizedValue.js +53 -0
  23. package/es/filter/components/FilterCascader/index.d.ts +5 -0
  24. package/es/filter/components/FilterCascader/index.js +317 -0
  25. package/es/filter/components/FilterCascader/types.d.ts +56 -0
  26. package/es/filter/components/FilterCascader/types.js +1 -0
  27. package/es/filter/components/FilterCascader/utils/countUtils.d.ts +13 -0
  28. package/es/filter/components/FilterCascader/utils/countUtils.js +48 -0
  29. package/es/filter/components/FilterCascader/utils/pathUtils.d.ts +17 -0
  30. package/es/filter/components/FilterCascader/utils/pathUtils.js +91 -0
  31. package/es/filter/components/FilterCheckbox.js +29 -7
  32. package/es/filter/components/FilterWrap.js +30 -1
  33. package/es/filter/components/ResponsiveFilterGroup.js +252 -359
  34. package/es/filter/index.d.ts +1 -1
  35. package/es/filter/index.js +11 -7
  36. package/es/filter/style/index.js +9 -2
  37. package/es/filter/type.d.ts +5 -0
  38. package/es/table/index.d.ts +2 -2
  39. package/lib/alert/index.d.ts +1 -1
  40. package/lib/alert/index.js +3 -1
  41. package/lib/filter/components/CountNumber.js +2 -1
  42. package/lib/filter/components/FilterButton.d.ts +2 -0
  43. package/lib/filter/components/FilterButton.js +4 -2
  44. package/lib/filter/components/FilterCascader/components/CascaderOption/OptionCheckbox.d.ts +20 -0
  45. package/lib/filter/components/FilterCascader/components/CascaderOption/OptionCheckbox.js +91 -0
  46. package/lib/filter/components/FilterCascader/components/CascaderOption/OptionItem.d.ts +13 -0
  47. package/lib/filter/components/FilterCascader/components/CascaderOption/OptionItem.js +51 -0
  48. package/lib/filter/components/FilterCascader/components/FlatCascaderContent/index.d.ts +16 -0
  49. package/lib/filter/components/FilterCascader/components/FlatCascaderContent/index.js +70 -0
  50. package/lib/filter/components/FilterCascader/components/NormalCascaderContent.d.ts +24 -0
  51. package/lib/filter/components/FilterCascader/components/NormalCascaderContent.js +263 -0
  52. package/lib/filter/components/FilterCascader/constants.d.ts +7 -0
  53. package/lib/filter/components/FilterCascader/constants.js +14 -0
  54. package/lib/filter/components/FilterCascader/hooks/useCascaderCallbacks.d.ts +12 -0
  55. package/lib/filter/components/FilterCascader/hooks/useCascaderCallbacks.js +81 -0
  56. package/lib/filter/components/FilterCascader/hooks/useCascaderLabels.d.ts +9 -0
  57. package/lib/filter/components/FilterCascader/hooks/useCascaderLabels.js +56 -0
  58. package/lib/filter/components/FilterCascader/hooks/useNormalizedValue.d.ts +7 -0
  59. package/lib/filter/components/FilterCascader/hooks/useNormalizedValue.js +48 -0
  60. package/lib/filter/components/FilterCascader/index.d.ts +5 -0
  61. package/lib/filter/components/FilterCascader/index.js +298 -0
  62. package/lib/filter/components/FilterCascader/types.d.ts +56 -0
  63. package/lib/filter/components/FilterCascader/types.js +5 -0
  64. package/lib/filter/components/FilterCascader/utils/countUtils.d.ts +13 -0
  65. package/lib/filter/components/FilterCascader/utils/countUtils.js +49 -0
  66. package/lib/filter/components/FilterCascader/utils/pathUtils.d.ts +17 -0
  67. package/lib/filter/components/FilterCascader/utils/pathUtils.js +56 -0
  68. package/lib/filter/components/FilterCheckbox.js +29 -7
  69. package/lib/filter/components/FilterWrap.js +28 -1
  70. package/lib/filter/components/ResponsiveFilterGroup.js +214 -340
  71. package/lib/filter/index.d.ts +1 -1
  72. package/lib/filter/index.js +11 -7
  73. package/lib/filter/style/index.js +10 -1
  74. package/lib/filter/type.d.ts +5 -0
  75. package/package.json +3 -3
  76. package/es/filter/components/FilterCascader.d.ts +0 -31
  77. package/es/filter/components/FilterCascader.js +0 -529
  78. package/lib/filter/components/FilterCascader.d.ts +0 -31
  79. package/lib/filter/components/FilterCascader.js +0 -449
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ "use client";
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.NormalCascaderContent = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _antd = require("antd");
9
+ var _checkbox = _interopRequireDefault(require("../../../../checkbox"));
10
+ var _theme = _interopRequireDefault(require("../../../../theme"));
11
+ var _input = _interopRequireDefault(require("../../../../input"));
12
+ var _empty = _interopRequireDefault(require("../../../../empty"));
13
+ var _icons = require("@oceanbase/icons");
14
+ var _classnames = _interopRequireDefault(require("classnames"));
15
+ var _style = require("../../../style");
16
+ var _constants = require("../constants");
17
+ var _jsxRuntime = require("react/jsx-runtime");
18
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
+ /**
20
+ * 非 Flat 模式的级联内容组件
21
+ */
22
+ const NormalCascaderContent = ({
23
+ options,
24
+ currentValue,
25
+ multiple,
26
+ prefixCls,
27
+ openPopoverKey,
28
+ filterButtonRef,
29
+ onOpenPopoverKeyChange,
30
+ onValueChange,
31
+ onHandleChange,
32
+ onClearByParent,
33
+ onSelectAllChildren,
34
+ showSearch = false,
35
+ searchKeyword = '',
36
+ onSearchChange
37
+ }) => {
38
+ const {
39
+ token
40
+ } = _theme.default.useToken();
41
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
42
+ style: {
43
+ padding: _constants.PADDING_VERTICAL,
44
+ maxHeight: _constants.MAX_HEIGHT,
45
+ overflowY: 'auto'
46
+ },
47
+ children: [showSearch && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
48
+ style: {
49
+ marginInline: 12,
50
+ marginBottom: 8
51
+ },
52
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_input.default, {
53
+ placeholder: "\u641C\u7D22",
54
+ prefix: /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.SearchOutlined, {}),
55
+ allowClear: true,
56
+ value: searchKeyword,
57
+ onChange: e => onSearchChange?.(e.target.value),
58
+ onClick: e => e.stopPropagation()
59
+ })
60
+ }), options.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_empty.default, {
61
+ image: _empty.default.PRESENTED_IMAGE_SIMPLE,
62
+ description: "\u65E0\u5339\u914D\u7ED3\u679C",
63
+ style: {
64
+ padding: '16px 0'
65
+ }
66
+ }) : options.map(option => {
67
+ const selectedChildren = currentValue.filter(item => item[0] === option.value).map(item => item[1]);
68
+ const hasSelectedChildren = selectedChildren.length > 0;
69
+ const hasChildren = option.children && option.children.length > 0;
70
+ const allChildrenSelected = multiple && hasChildren && selectedChildren.length === option.children.length;
71
+
72
+ // 判断当前节点是否被选中(用于无子节点的情况)
73
+ const isNodeSelected = currentValue.some(item => item[0] === option.value && !item[1]);
74
+
75
+ // 处理无子节点的点击事件
76
+ const handleNodeClick = () => {
77
+ if (option.disabled) {
78
+ return;
79
+ }
80
+ if (!hasChildren) {
81
+ // 无子节点时,直接选中/取消选中该节点
82
+ if (multiple) {
83
+ const isSelected = currentValue.some(item => item[0] === option.value && !item[1]);
84
+ if (isSelected) {
85
+ onValueChange(currentValue.filter(item => !(item[0] === option.value && !item[1])));
86
+ } else {
87
+ onValueChange([...currentValue, [option.value, '']]);
88
+ }
89
+ } else {
90
+ const isSelected = currentValue.some(item => item[0] === option.value && !item[1]);
91
+ if (isSelected) {
92
+ onValueChange([]);
93
+ } else {
94
+ onValueChange([[option.value, '']]);
95
+ }
96
+ onOpenPopoverKeyChange(null);
97
+ setTimeout(() => {
98
+ filterButtonRef.current?.closePopover();
99
+ }, 0);
100
+ }
101
+ }
102
+ };
103
+
104
+ // 没有子节点时,直接渲染节点项,不使用 Popover
105
+ if (!hasChildren) {
106
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
107
+ style: {
108
+ padding: _constants.PADDING_HORIZONTAL
109
+ },
110
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Flex, {
111
+ gap: _constants.GAP_SIZE_SMALL * 2,
112
+ className: (0, _classnames.default)((0, _style.getFilterCls)(prefixCls, 'select-option'), {
113
+ [(0, _style.getFilterCls)(prefixCls, 'has-selected')]: isNodeSelected
114
+ }),
115
+ justify: "space-between",
116
+ align: "center",
117
+ onClick: handleNodeClick,
118
+ style: {
119
+ cursor: option.disabled ? 'not-allowed' : 'pointer',
120
+ color: option.disabled ? token.colorTextDisabled : 'inherit'
121
+ },
122
+ children: multiple ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_checkbox.default, {
123
+ checked: isNodeSelected,
124
+ disabled: option.disabled,
125
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
126
+ className: (0, _style.getFilterCls)(prefixCls, 'text-ellipsis'),
127
+ children: option.label
128
+ })
129
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
130
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
131
+ className: (0, _style.getFilterCls)(prefixCls, 'text-ellipsis'),
132
+ children: option.label
133
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
134
+ children: isNodeSelected && /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.CheckOutlined, {
135
+ style: {
136
+ color: token.colorPrimary
137
+ }
138
+ })
139
+ })]
140
+ })
141
+ })
142
+ }, option.value);
143
+ }
144
+
145
+ // 有子节点时,使用 Popover
146
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Popover, {
147
+ placement: "rightTop",
148
+ trigger: 'hover',
149
+ arrow: false,
150
+ open: option?.disabled ? false : multiple ? undefined : openPopoverKey === option.value,
151
+ onOpenChange: multiple ? undefined : open => {
152
+ if (!open) {
153
+ onOpenPopoverKeyChange(null);
154
+ } else {
155
+ onOpenPopoverKeyChange(option.value);
156
+ }
157
+ },
158
+ content: option.children?.map(child => {
159
+ const isSelected = selectedChildren.includes(child.value);
160
+ const isChildDisabled = child.disabled || false;
161
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Flex, {
162
+ gap: _constants.GAP_SIZE_SMALL * 2,
163
+ className: (0, _style.getFilterCls)(prefixCls, 'select-option'),
164
+ justify: "space-between",
165
+ onClick: e => {
166
+ e.stopPropagation();
167
+ if (!isChildDisabled) {
168
+ onHandleChange(option.value, child.value);
169
+ }
170
+ },
171
+ style: {
172
+ cursor: isChildDisabled ? 'not-allowed' : 'pointer',
173
+ color: isChildDisabled ? token.colorTextDisabled : 'inherit'
174
+ },
175
+ children: multiple ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_checkbox.default, {
176
+ checked: isSelected,
177
+ disabled: isChildDisabled,
178
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
179
+ className: (0, _style.getFilterCls)(prefixCls, 'text-ellipsis'),
180
+ children: child.label
181
+ })
182
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
183
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
184
+ className: (0, _style.getFilterCls)(prefixCls, 'text-ellipsis'),
185
+ children: child.label
186
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
187
+ children: isSelected && /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.CheckOutlined, {
188
+ style: {
189
+ color: token.colorPrimary
190
+ }
191
+ })
192
+ })]
193
+ })
194
+ }, child.value);
195
+ }),
196
+ styles: {
197
+ body: {
198
+ padding: 8,
199
+ maxHeight: 220,
200
+ maxWidth: 300,
201
+ overflowY: 'auto'
202
+ }
203
+ },
204
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
205
+ style: {
206
+ padding: _constants.PADDING_HORIZONTAL
207
+ },
208
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_antd.Flex, {
209
+ gap: _constants.GAP_SIZE_SMALL * 2,
210
+ className: (0, _classnames.default)((0, _style.getFilterCls)(prefixCls, 'select-option'), {
211
+ [(0, _style.getFilterCls)(prefixCls, 'has-selected')]: hasSelectedChildren
212
+ }),
213
+ justify: "space-between",
214
+ align: "center",
215
+ style: {
216
+ cursor: option.disabled ? 'not-allowed' : 'pointer',
217
+ color: option.disabled ? token.colorTextDisabled : 'inherit'
218
+ },
219
+ children: [multiple ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_checkbox.default, {
220
+ checked: allChildrenSelected,
221
+ indeterminate: hasSelectedChildren && !allChildrenSelected,
222
+ disabled: option.disabled,
223
+ onClick: e => e.stopPropagation(),
224
+ onChange: () => {
225
+ if (!option.disabled) {
226
+ if (allChildrenSelected) {
227
+ onClearByParent(option.value);
228
+ } else {
229
+ onSelectAllChildren(option);
230
+ }
231
+ }
232
+ },
233
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
234
+ className: (0, _style.getFilterCls)(prefixCls, 'text-ellipsis'),
235
+ children: option.label
236
+ })
237
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
238
+ className: (0, _style.getFilterCls)(prefixCls, 'text-ellipsis'),
239
+ children: option.label
240
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Flex, {
241
+ align: "center",
242
+ gap: _constants.GAP_SIZE_SMALL,
243
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
244
+ className: (0, _style.getFilterCls)(prefixCls, 'icon-wrapper'),
245
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.RightOutlined, {
246
+ className: hasSelectedChildren ? (0, _style.getFilterCls)(prefixCls, 'arrow-icon') : ''
247
+ }), hasSelectedChildren && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
248
+ className: (0, _style.getFilterCls)(prefixCls, 'clear-icon'),
249
+ onClick: e => {
250
+ e.stopPropagation();
251
+ onClearByParent(option.value);
252
+ },
253
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.CloseOutlined, {})
254
+ })]
255
+ })
256
+ })]
257
+ })
258
+ })
259
+ }, option.value);
260
+ })]
261
+ });
262
+ };
263
+ exports.NormalCascaderContent = NormalCascaderContent;
@@ -0,0 +1,7 @@
1
+ export declare const COLUMN_WIDTH = 200;
2
+ export declare const MAX_HEIGHT = 300;
3
+ export declare const PADDING_VERTICAL = "8px 0px";
4
+ export declare const PADDING_HORIZONTAL = "0px 8px";
5
+ export declare const ICON_SIZE = 12;
6
+ export declare const GAP_SIZE = 8;
7
+ export declare const GAP_SIZE_SMALL = 4;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PADDING_VERTICAL = exports.PADDING_HORIZONTAL = exports.MAX_HEIGHT = exports.ICON_SIZE = exports.GAP_SIZE_SMALL = exports.GAP_SIZE = exports.COLUMN_WIDTH = void 0;
7
+ // 样式常量
8
+ const COLUMN_WIDTH = exports.COLUMN_WIDTH = 200;
9
+ const MAX_HEIGHT = exports.MAX_HEIGHT = 300;
10
+ const PADDING_VERTICAL = exports.PADDING_VERTICAL = '8px 0px';
11
+ const PADDING_HORIZONTAL = exports.PADDING_HORIZONTAL = '0px 8px';
12
+ const ICON_SIZE = exports.ICON_SIZE = 12;
13
+ const GAP_SIZE = exports.GAP_SIZE = 8;
14
+ const GAP_SIZE_SMALL = exports.GAP_SIZE_SMALL = 4;
@@ -0,0 +1,12 @@
1
+ import type { CascaderOption } from '../types';
2
+ import type { FilterButtonRef } from '../../FilterButton';
3
+ /**
4
+ * 管理级联选择器的所有回调函数
5
+ */
6
+ export declare const useCascaderCallbacks: (currentValue: string[][], setValue: (value: string[][]) => void, options: CascaderOption[], multiple: boolean, filterButtonRef: React.RefObject<FilterButtonRef>, setOpenPopoverKey: (key: string | null) => void) => {
7
+ handleChange: (parentValue: string, childValue: string) => void;
8
+ clearByParent: (parentValue: string) => void;
9
+ handleClear: () => void;
10
+ selectAllChildren: (option: CascaderOption) => void;
11
+ handleRemoveTag: (tagValue: string) => void;
12
+ };
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useCascaderCallbacks = void 0;
7
+ var _react = require("react");
8
+ /**
9
+ * 管理级联选择器的所有回调函数
10
+ */
11
+ const useCascaderCallbacks = (currentValue, setValue, options, multiple, filterButtonRef, setOpenPopoverKey) => {
12
+ const handleChange = (0, _react.useCallback)((parentValue, childValue) => {
13
+ const parentOption = options.find(opt => opt.value === parentValue);
14
+ const childOption = parentOption?.children?.find(child => child.value === childValue);
15
+ if (parentOption?.disabled || childOption?.disabled) {
16
+ return;
17
+ }
18
+ if (multiple) {
19
+ const existingIndex = currentValue.findIndex(item => item[0] === parentValue && item[1] === childValue);
20
+ let newValueList;
21
+ if (existingIndex !== -1) {
22
+ newValueList = currentValue.filter((_, index) => index !== existingIndex);
23
+ } else {
24
+ newValueList = [...currentValue, [parentValue, childValue]];
25
+ }
26
+ setValue(newValueList);
27
+ } else {
28
+ const isCurrentSelected = currentValue.length === 1 && currentValue[0][0] === parentValue && currentValue[0][1] === childValue;
29
+ let newValueList;
30
+ if (isCurrentSelected) {
31
+ newValueList = [];
32
+ } else {
33
+ newValueList = [[parentValue, childValue]];
34
+ }
35
+ setValue(newValueList);
36
+ setOpenPopoverKey(null);
37
+ setTimeout(() => {
38
+ filterButtonRef.current?.closePopover();
39
+ }, 0);
40
+ }
41
+ }, [currentValue, multiple, setValue, options, filterButtonRef, setOpenPopoverKey]);
42
+ const clearByParent = (0, _react.useCallback)(parentValue => {
43
+ const newValueList = currentValue.filter(item => item[0] !== parentValue);
44
+ setValue(newValueList);
45
+ }, [currentValue, setValue]);
46
+ const handleClear = (0, _react.useCallback)(() => {
47
+ setValue([]);
48
+ }, [setValue]);
49
+ const selectAllChildren = (0, _react.useCallback)(option => {
50
+ if (option.disabled) {
51
+ return;
52
+ }
53
+ const otherValues = currentValue.filter(item => item[0] !== option.value);
54
+ const allChildValues = option.children?.filter(child => !child.disabled).map(child => [option.value, child.value]) || [];
55
+ const newValueList = [...otherValues, ...allChildValues];
56
+ setValue(newValueList);
57
+ }, [currentValue, setValue]);
58
+
59
+ // 移除某个选中的值
60
+ const handleRemoveTag = (0, _react.useCallback)(tagValue => {
61
+ // tagValue 格式:path1::path2::path3::index
62
+ const parts = tagValue.split('::');
63
+ if (parts.length >= 2) {
64
+ const pathParts = parts.slice(0, -1); // 移除最后的 index
65
+
66
+ const newValueList = currentValue.filter(item => {
67
+ if (item.length !== pathParts.length) return true;
68
+ return !item.every((val, idx) => val === pathParts[idx]);
69
+ });
70
+ setValue(newValueList);
71
+ }
72
+ }, [currentValue, setValue]);
73
+ return {
74
+ handleChange,
75
+ clearByParent,
76
+ handleClear,
77
+ selectAllChildren,
78
+ handleRemoveTag
79
+ };
80
+ };
81
+ exports.useCascaderCallbacks = useCascaderCallbacks;
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { CascaderOption, SelectedTag } from '../types';
3
+ /**
4
+ * 管理级联选择器的标签显示逻辑
5
+ */
6
+ export declare const useCascaderLabels: (currentValue: string[][], options: CascaderOption[], label: ReactNode, multiple: boolean, isCollapsed: boolean) => {
7
+ getSelectedLabel: () => ReactNode;
8
+ getSelectedTags: () => SelectedTag[];
9
+ };
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useCascaderLabels = void 0;
7
+ var _react = require("react");
8
+ var _pathUtils = require("../utils/pathUtils");
9
+ /**
10
+ * 管理级联选择器的标签显示逻辑
11
+ */
12
+ const useCascaderLabels = (currentValue, options, label, multiple, isCollapsed) => {
13
+ // 获取当前选中值的 label(用于单选模式显示)
14
+ const getSelectedLabel = (0, _react.useCallback)(() => {
15
+ if (isCollapsed && currentValue.length === 0) {
16
+ return '';
17
+ }
18
+ if (currentValue.length === 0) {
19
+ return label;
20
+ }
21
+ if (!multiple && currentValue.length === 1) {
22
+ const selectedPath = currentValue[0];
23
+
24
+ // 如果是空路径
25
+ if (!selectedPath || selectedPath.length === 0) {
26
+ return label;
27
+ }
28
+
29
+ // 对于多层级路径,查找最后一个节点
30
+ const currentOption = (0, _pathUtils.findOptionByPath)(options, selectedPath);
31
+ return currentOption?.label || label;
32
+ }
33
+ return label;
34
+ }, [currentValue, isCollapsed, label, multiple, options]);
35
+
36
+ // 获取选中值的 tags(用于多选模式 Tag 显示)
37
+ const getSelectedTags = (0, _react.useCallback)(() => {
38
+ return currentValue.map((selectedPath, index) => {
39
+ // 对于多层级路径,查找最后一个节点
40
+ const currentOption = (0, _pathUtils.findOptionByPath)(options, selectedPath);
41
+ const displayLabel = currentOption?.label || selectedPath[selectedPath.length - 1];
42
+ const valueKey = selectedPath.join('::') + `::${index}`;
43
+ return {
44
+ label: displayLabel,
45
+ value: valueKey,
46
+ parentValue: selectedPath[0],
47
+ childValue: selectedPath[selectedPath.length - 1]
48
+ };
49
+ });
50
+ }, [currentValue, options]);
51
+ return {
52
+ getSelectedLabel,
53
+ getSelectedTags
54
+ };
55
+ };
56
+ exports.useCascaderLabels = useCascaderLabels;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 管理级联选择器的值,处理单选/多选格式转换
3
+ */
4
+ export declare const useNormalizedValue: (value: string[] | string[][] | undefined, onChange: ((value: string[]) => void) | ((value: string[][]) => void), multiple: boolean) => {
5
+ currentValue: string[][];
6
+ setValue: (newValue: string[][]) => void;
7
+ };
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useNormalizedValue = void 0;
7
+ var _react = require("react");
8
+ /**
9
+ * 管理级联选择器的值,处理单选/多选格式转换
10
+ */
11
+ const useNormalizedValue = (value, onChange, multiple) => {
12
+ const normalizeValue = (0, _react.useCallback)(val => {
13
+ if (!val) return [];
14
+ if (val.length === 0) return [];
15
+ // 判断是否为单选格式 string[]
16
+ if (!multiple && val.length > 0 && typeof val[0] === 'string') {
17
+ return [val];
18
+ }
19
+ return val;
20
+ }, [multiple]);
21
+ const denormalizeValue = (0, _react.useCallback)(val => {
22
+ if (!multiple && val.length > 0) {
23
+ return val[0]; // 单选模式返回 string[]
24
+ }
25
+ return val; // 多选模式返回 string[][]
26
+ }, [multiple]);
27
+
28
+ // 使用受控状态 hook,内部统一使用 string[][] 格式
29
+ const [internalValue, setInternalValue] = (0, _react.useState)(() => normalizeValue(value));
30
+
31
+ // 同步外部 value 到内部
32
+ (0, _react.useEffect)(() => {
33
+ setInternalValue(normalizeValue(value));
34
+ }, [value, normalizeValue]);
35
+
36
+ // 内部 setValue 包装函数
37
+ const setValue = (0, _react.useCallback)(newValue => {
38
+ setInternalValue(newValue);
39
+ if (onChange) {
40
+ onChange(denormalizeValue(newValue));
41
+ }
42
+ }, [onChange, denormalizeValue]);
43
+ return {
44
+ currentValue: internalValue,
45
+ setValue
46
+ };
47
+ };
48
+ exports.useNormalizedValue = useNormalizedValue;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { FilterCascaderProps } from './types';
3
+ declare const FilterCascader: React.FC<FilterCascaderProps>;
4
+ export type { FilterCascaderProps, CascaderOption } from './types';
5
+ export default FilterCascader;