@rainbow-oh/yee-c 0.4.2 → 0.4.4

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 (105) hide show
  1. package/dist/cjs/Cascader/cascader.js +53 -62
  2. package/dist/cjs/Cascader/interface.d.ts +19 -2
  3. package/dist/cjs/Cascader/node.js +11 -6
  4. package/dist/cjs/Cascader/search-list.js +2 -1
  5. package/dist/cjs/Cascader/utils/index.d.ts +58 -14
  6. package/dist/cjs/Cascader/utils/index.js +57 -73
  7. package/dist/cjs/Form/form-store.js +3 -0
  8. package/dist/cjs/Form/hooks/useWatch.js +4 -2
  9. package/dist/cjs/Input/style/index.less +19 -0
  10. package/dist/cjs/Popover/style/index.less +1 -0
  11. package/dist/cjs/Select/interface.d.ts +77 -0
  12. package/dist/cjs/Select/option.d.ts +2 -1
  13. package/dist/cjs/Select/option.js +6 -3
  14. package/dist/cjs/Select/options.d.ts +3 -2
  15. package/dist/cjs/Select/options.js +53 -47
  16. package/dist/cjs/Select/select.js +1 -1
  17. package/dist/cjs/Select/style/index.less +8 -0
  18. package/dist/cjs/Selector/interface.d.ts +4 -0
  19. package/dist/cjs/Selector/selector.js +3 -0
  20. package/dist/cjs/Selector/style/index.less +135 -116
  21. package/dist/cjs/Table/hooks/useFilter.js +1 -1
  22. package/dist/cjs/Table/interface.d.ts +4 -0
  23. package/dist/cjs/Table/style/index.less +2 -0
  24. package/dist/cjs/Table/theader/filter.js +2 -1
  25. package/dist/cjs/Tabs/demo/basic.js +8 -1
  26. package/dist/cjs/Tabs/tabs.js +3 -1
  27. package/dist/cjs/Tag/demo/checkable.js +1 -0
  28. package/dist/cjs/Tag/tag.js +1 -1
  29. package/dist/cjs/TextArea/textarea.js +0 -1
  30. package/dist/cjs/Trigger/trigger.js +1 -1
  31. package/dist/cjs/style/color.css +1 -1
  32. package/dist/cjs/style/size.css +10 -2
  33. package/dist/cjs/style/themes.css +1 -1
  34. package/dist/cjs/style/variables.css +12 -4
  35. package/dist/cjs/version.d.ts +1 -1
  36. package/dist/cjs/version.js +1 -1
  37. package/dist/esm/Cascader/cascader.js +49 -56
  38. package/dist/esm/Cascader/interface.d.ts +19 -2
  39. package/dist/esm/Cascader/node.js +8 -11
  40. package/dist/esm/Cascader/search-list.js +2 -1
  41. package/dist/esm/Cascader/utils/index.d.ts +58 -14
  42. package/dist/esm/Cascader/utils/index.js +124 -75
  43. package/dist/esm/Form/form-store.js +4 -0
  44. package/dist/esm/Form/hooks/useWatch.js +7 -2
  45. package/dist/esm/Input/style/index.less +19 -0
  46. package/dist/esm/Popover/style/index.less +1 -0
  47. package/dist/esm/Select/interface.d.ts +77 -0
  48. package/dist/esm/Select/option.d.ts +2 -1
  49. package/dist/esm/Select/option.js +11 -2
  50. package/dist/esm/Select/options.d.ts +3 -2
  51. package/dist/esm/Select/options.js +3 -1
  52. package/dist/esm/Select/select.js +1 -3
  53. package/dist/esm/Select/style/index.less +8 -0
  54. package/dist/esm/Selector/interface.d.ts +4 -0
  55. package/dist/esm/Selector/selector.js +4 -2
  56. package/dist/esm/Selector/style/index.less +135 -116
  57. package/dist/esm/Table/hooks/useFilter.js +1 -1
  58. package/dist/esm/Table/interface.d.ts +4 -0
  59. package/dist/esm/Table/style/index.less +2 -0
  60. package/dist/esm/Table/theader/filter.js +3 -4
  61. package/dist/esm/Tabs/demo/basic.js +4 -1
  62. package/dist/esm/Tabs/tabs.js +3 -1
  63. package/dist/esm/Tag/demo/checkable.js +1 -0
  64. package/dist/esm/Tag/tag.js +1 -1
  65. package/dist/esm/TextArea/textarea.js +0 -1
  66. package/dist/esm/Trigger/trigger.js +1 -1
  67. package/dist/esm/style/color.css +1 -1
  68. package/dist/esm/style/size.css +10 -2
  69. package/dist/esm/style/themes.css +1 -1
  70. package/dist/esm/style/variables.css +12 -4
  71. package/dist/esm/version.d.ts +1 -1
  72. package/dist/esm/version.js +1 -1
  73. package/dist/umd/yee-c.min.css +2 -2
  74. package/dist/umd/yee-c.min.js +1 -1
  75. package/package.json +1 -1
  76. package/src/Cascader/cascader.tsx +65 -62
  77. package/src/Cascader/interface.ts +19 -2
  78. package/src/Cascader/node.tsx +12 -7
  79. package/src/Cascader/search-list.tsx +1 -1
  80. package/src/Cascader/utils/index.ts +130 -68
  81. package/src/Form/form-store.ts +4 -0
  82. package/src/Form/hooks/useWatch.ts +9 -2
  83. package/src/Input/style/index.less +19 -0
  84. package/src/Popover/style/index.less +1 -0
  85. package/src/Select/interface.ts +87 -0
  86. package/src/Select/option.tsx +13 -4
  87. package/src/Select/options.tsx +49 -43
  88. package/src/Select/select.tsx +5 -2
  89. package/src/Select/style/index.less +8 -0
  90. package/src/Selector/interface.ts +4 -0
  91. package/src/Selector/selector.tsx +2 -0
  92. package/src/Selector/style/index.less +135 -116
  93. package/src/Table/hooks/useFilter.ts +1 -1
  94. package/src/Table/interface.ts +4 -0
  95. package/src/Table/style/index.less +2 -0
  96. package/src/Table/theader/filter.tsx +2 -2
  97. package/src/Tabs/demo/basic.tsx +7 -1
  98. package/src/Tabs/tabs.tsx +3 -2
  99. package/src/Tag/demo/checkable.tsx +1 -0
  100. package/src/Tag/tag.tsx +1 -1
  101. package/src/TextArea/textarea.tsx +0 -2
  102. package/src/Trigger/trigger.tsx +1 -1
  103. package/src/style/color.css +1 -1
  104. package/src/style/size.css +10 -2
  105. package/src/version.ts +1 -1
@@ -147,7 +147,9 @@ var Tabs = (baseprops) => {
147
147
  return;
148
148
  }
149
149
  setMergedActiveKey(key);
150
- onChange == null ? void 0 : onChange(key);
150
+ if (key !== mergedActiveKey) {
151
+ onChange == null ? void 0 : onChange(key);
152
+ }
151
153
  };
152
154
  const contextValue = (0, import_react.useMemo)(
153
155
  () => ({
@@ -40,6 +40,7 @@ var checkable_default = () => {
40
40
  import_yee_c.Tag,
41
41
  {
42
42
  checkable: true,
43
+ variant: "outlined",
43
44
  checked,
44
45
  onChange: (checked2) => setChecked(checked2)
45
46
  },
@@ -112,7 +112,6 @@ var Tag = (0, import_react.forwardRef)(
112
112
  };
113
113
  const cls = (0, import_clsx.default)(
114
114
  prefixCls,
115
- [`${prefixCls}-${variant}`],
116
115
  {
117
116
  [`${prefixCls}-${status}`]: status,
118
117
  [`${prefixCls}-dashed`]: dashed,
@@ -120,6 +119,7 @@ var Tag = (0, import_react.forwardRef)(
120
119
  [`${prefixCls}-${size}`]: size,
121
120
  [`${prefixCls}-checkable`]: checkable
122
121
  },
122
+ [`${prefixCls}-${variant}`],
123
123
  className
124
124
  );
125
125
  const renderClose = () => closable ? /* @__PURE__ */ import_react.default.createElement(
@@ -106,7 +106,6 @@ var TextArea = (0, import_react.forwardRef)(
106
106
  value,
107
107
  defaultValue
108
108
  });
109
- console.log("mergedValue: ", mergedValue, value);
110
109
  (0, import_react.useEffect)(() => {
111
110
  const ele = componentRef.current;
112
111
  if (ele && autoSize) {
@@ -187,7 +187,7 @@ var Trigger = (baseprops) => {
187
187
  return /* @__PURE__ */ import_react.default.createElement(
188
188
  import_trigger.default,
189
189
  __spreadProps(__spreadValues(__spreadProps(__spreadValues({}, rest), {
190
- prefixCls: "yee-trigger",
190
+ prefixCls,
191
191
  mouseEnterDelay,
192
192
  mouseLeaveDelay,
193
193
  arrow,
@@ -30,7 +30,7 @@
30
30
  --yee-text-color-description: #7c7c7c;
31
31
  --yee-text-color-disabled: #bfbfbf;
32
32
  --yee-text-color-highlight: #f58220;
33
- --yee-text-color-auxiliary: #f5f5f5;
33
+ --yee-text-color-auxiliary: #d1d1d1;
34
34
  --yee-color-split: #e7e7e7;
35
35
  --yee-border-color: #cbd6e2;
36
36
  --yee-border-color-hover-focus: #75b9f0;
@@ -278,6 +278,14 @@
278
278
  --yee-input-border-width: 1px;
279
279
  --yee-input-suffix-gap: 4px;
280
280
  --yee-input-clear-padding: 1px;
281
+ --yee-input-small-font-size: 12px;
282
+ --yee-input-small-line-height: 20px;
283
+ --yee-input-small-height: 24px;
284
+ --yee-input-small-padding: 0 6px;
285
+ --yee-input-large-font-size: 16px;
286
+ --yee-input-large-line-height: 24px;
287
+ --yee-input-large-height: 40px;
288
+ --yee-input-large-padding: 4px 12px;
281
289
 
282
290
  /* --JsonViewer-- */
283
291
  --yee-json-view-font-size: 14px;
@@ -651,7 +659,7 @@
651
659
  --yee-table-bordered-cell-border-width: 1px;
652
660
  --yee-table-bordered-thead-border-width: 1px;
653
661
  --yee-table-thead-action-gap: 8px;
654
- --yee-table-filter-popup-padding: 16px;
662
+ --yee-table-filter-popup-padding: 8px;
655
663
  --yee-table-content-border-radius: 6px 6px 0 0;
656
664
  --yee-table-cell-padding: 13px 16px;
657
665
  --yee-table-cell-line-height: 22px;
@@ -740,7 +748,7 @@
740
748
  --yee-tag-font-size: 12px;
741
749
  --yee-tag-line-height: 22px;
742
750
  --yee-tag-border-width: 1px;
743
- --yee-tag-border-radius: 2px;
751
+ --yee-tag-border-radius: 4px;
744
752
  --yee-tag-icon-margin-left: 4px;
745
753
  --yee-tag-small-height: 16px;
746
754
  --yee-tag-large-height: 28px;
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * @rainbow-oh/yee-c CSS Variables
3
3
  * Auto-generated, do not edit manually
4
- * Generated on 2026-07-01T03:21:30.989Z
4
+ * Generated on 2026-07-03T02:41:11.107Z
5
5
  */
6
6
 
7
7
  /* ========== color.blue.css ========== */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * @rainbow-oh/yee-c CSS Variables
3
3
  * Auto-generated, do not edit manually
4
- * Generated on 2026-07-01T03:21:30.989Z
4
+ * Generated on 2026-07-03T02:41:11.107Z
5
5
  */
6
6
 
7
7
  /* ========== color.css ========== */
@@ -37,7 +37,7 @@
37
37
  --yee-text-color-description: #7c7c7c;
38
38
  --yee-text-color-disabled: #bfbfbf;
39
39
  --yee-text-color-highlight: #f58220;
40
- --yee-text-color-auxiliary: #f5f5f5;
40
+ --yee-text-color-auxiliary: #d1d1d1;
41
41
  --yee-color-split: #e7e7e7;
42
42
  --yee-border-color: #cbd6e2;
43
43
  --yee-border-color-hover-focus: #75b9f0;
@@ -1396,6 +1396,14 @@
1396
1396
  --yee-input-border-width: 1px;
1397
1397
  --yee-input-suffix-gap: 4px;
1398
1398
  --yee-input-clear-padding: 1px;
1399
+ --yee-input-small-font-size: 12px;
1400
+ --yee-input-small-line-height: 20px;
1401
+ --yee-input-small-height: 24px;
1402
+ --yee-input-small-padding: 0 6px;
1403
+ --yee-input-large-font-size: 16px;
1404
+ --yee-input-large-line-height: 24px;
1405
+ --yee-input-large-height: 40px;
1406
+ --yee-input-large-padding: 4px 12px;
1399
1407
 
1400
1408
  /* --JsonViewer-- */
1401
1409
  --yee-json-view-font-size: 14px;
@@ -1769,7 +1777,7 @@
1769
1777
  --yee-table-bordered-cell-border-width: 1px;
1770
1778
  --yee-table-bordered-thead-border-width: 1px;
1771
1779
  --yee-table-thead-action-gap: 8px;
1772
- --yee-table-filter-popup-padding: 16px;
1780
+ --yee-table-filter-popup-padding: 8px;
1773
1781
  --yee-table-content-border-radius: 6px 6px 0 0;
1774
1782
  --yee-table-cell-padding: 13px 16px;
1775
1783
  --yee-table-cell-line-height: 22px;
@@ -1858,7 +1866,7 @@
1858
1866
  --yee-tag-font-size: 12px;
1859
1867
  --yee-tag-line-height: 22px;
1860
1868
  --yee-tag-border-width: 1px;
1861
- --yee-tag-border-radius: 2px;
1869
+ --yee-tag-border-radius: 4px;
1862
1870
  --yee-tag-icon-margin-left: 4px;
1863
1871
  --yee-tag-small-height: 16px;
1864
1872
  --yee-tag-large-height: 28px;
@@ -3,4 +3,4 @@ declare global {
3
3
  __yee_c_version__: string;
4
4
  }
5
5
  }
6
- export declare const version = "0.4.2";
6
+ export declare const version = "0.4.4";
@@ -22,7 +22,7 @@ __export(version_exports, {
22
22
  version: () => version
23
23
  });
24
24
  module.exports = __toCommonJS(version_exports);
25
- var version = "0.4.2";
25
+ var version = "0.4.4";
26
26
  if (typeof window !== "undefined") {
27
27
  window.__yee_c_version__ = version;
28
28
  }
@@ -24,7 +24,7 @@ import isEqual from "../utils/isEqual";
24
24
  import mergeContextToProps from "../utils/mergeContextToProps";
25
25
  import Column from "./column";
26
26
  import SearchList from "./search-list";
27
- import { changeToView, flattenOptions, hasChild } from "./utils";
27
+ import { changeToView, flattenOptions, getChildren, isSamePrefixPath, pathToUid } from "./utils";
28
28
  import "./style/index.less";
29
29
  export var CascaderCtx = /*#__PURE__*/createContext({});
30
30
  var Cascader = function Cascader(baseprops) {
@@ -39,7 +39,8 @@ var Cascader = function Cascader(baseprops) {
39
39
  _props$placement = props.placement,
40
40
  placement = _props$placement === void 0 ? 'bottomLeft' : _props$placement,
41
41
  popupClassName = props.popupClassName,
42
- searchable = props.searchable,
42
+ _props$searchable = props.searchable,
43
+ searchable = _props$searchable === void 0 ? true : _props$searchable,
43
44
  _props$fieldNames = props.fieldNames,
44
45
  fieldNames = _props$fieldNames === void 0 ? {
45
46
  label: 'label',
@@ -104,8 +105,6 @@ var Cascader = function Cascader(baseprops) {
104
105
  return;
105
106
  }
106
107
  var _changeToView = changeToView(currentValue || [], flatOptions, {
107
- needNext: true,
108
- // Set to true to expand to full path
109
108
  multiple: multiple
110
109
  }),
111
110
  _changeToView2 = _slicedToArray(_changeToView, 2),
@@ -130,9 +129,9 @@ var Cascader = function Cascader(baseprops) {
130
129
 
131
130
  // node mouse evt
132
131
  var onNodeMouseEnter = function onNodeMouseEnter(item, level) {
133
- if (expandTrigger === 'hover' && hasChild(item)) {
132
+ if (expandTrigger === 'hover' && !item.isLeaf) {
134
133
  var queue = columns.slice(0, level + 1);
135
- queue.push(item.children);
134
+ queue.push(getChildren(flatOptions, item.uid));
136
135
  setColumns(queue);
137
136
  // Also update expandedPath to maintain highlight state
138
137
  setExpandedPath(function (prev) {
@@ -145,24 +144,23 @@ var Cascader = function Cascader(baseprops) {
145
144
  };
146
145
 
147
146
  // Helper function to get all descendant paths of a node
148
- // Note: For very deep trees, consider adding maxDepth parameter or prevent stack overflow
149
147
  var getAllDescendantPaths = useCallback(function (node) {
150
148
  var maxDepth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
151
149
  var paths = [];
152
150
  var traverse = function traverse(currentNode, depth) {
153
151
  if (depth > maxDepth) return; // Prevent stack overflow
154
- if (!hasChild(currentNode)) {
152
+ if (currentNode.isLeaf) {
155
153
  paths.push(currentNode.path);
156
154
  return;
157
155
  }
158
- var children = currentNode.children;
156
+ var children = getChildren(flatOptions, currentNode.uid);
159
157
  children.forEach(function (child) {
160
158
  return traverse(child, depth + 1);
161
159
  });
162
160
  };
163
161
  traverse(node, 0);
164
162
  return paths;
165
- }, []);
163
+ }, [flatOptions]);
166
164
 
167
165
  // cascader node click
168
166
  var onItemClick = useCallback(function (item) {
@@ -180,18 +178,14 @@ var Cascader = function Cascader(baseprops) {
180
178
  var isSelected = currentValue.some(function (v) {
181
179
  return isEqual(v, item.path);
182
180
  });
183
- if (hasChild(item)) {
181
+ if (!item.isLeaf) {
184
182
  // Parent node: select/deselect all descendants
185
183
  var descendantPaths = getAllDescendantPaths(item, 50); // Limit to depth 50 to prevent performance issues
186
- var descendantPathStrs = descendantPaths.map(function (p) {
187
- return p.join('-');
188
- });
189
184
 
190
185
  // Filter out all descendant paths from current value
191
186
  var filteredValue = currentValue.filter(function (v) {
192
- var pathStr = v.join('-');
193
- return !descendantPathStrs.some(function (descPathStr) {
194
- return pathStr.startsWith(descPathStr);
187
+ return !descendantPaths.some(function (descPath) {
188
+ return isSamePrefixPath(descPath, v);
195
189
  });
196
190
  });
197
191
  if (!isSelected) {
@@ -201,8 +195,7 @@ var Cascader = function Cascader(baseprops) {
201
195
  newValue = filteredValue;
202
196
  newOpts = filteredValue.map(function (path) {
203
197
  return path.map(function (_, i) {
204
- var uid = path.slice(0, i + 1).join('-');
205
- return nodeMap.get(uid);
198
+ return nodeMap.get(pathToUid(path.slice(0, i + 1)));
206
199
  });
207
200
  });
208
201
  } else {
@@ -216,8 +209,7 @@ var Cascader = function Cascader(baseprops) {
216
209
  }
217
210
  newOpts = newValue.map(function (path) {
218
211
  return path.map(function (_, i) {
219
- var uid = path.slice(0, i + 1).join('-');
220
- return nodeMap.get(uid);
212
+ return nodeMap.get(pathToUid(path.slice(0, i + 1)));
221
213
  });
222
214
  });
223
215
  }
@@ -225,22 +217,18 @@ var Cascader = function Cascader(baseprops) {
225
217
  } else if (shouldSelect) {
226
218
  // Single select or non-checkable multi-select
227
219
  newValue = multiple ? [].concat(_toConsumableArray(mergedValue), [item.path]) : item.path;
228
- newOpts = multiple ? [].concat(_toConsumableArray(mergedValue.map(function (item) {
229
- var vs = item;
230
- var arr = vs.map(function (_, i) {
231
- return vs.slice(0, i + 1).join('-');
232
- });
233
- return arr.map(function (uid) {
234
- return nodeMap.get(uid);
220
+ newOpts = multiple ? [].concat(_toConsumableArray(mergedValue.map(function (path) {
221
+ var vs = path;
222
+ return vs.map(function (_, i) {
223
+ return nodeMap.get(pathToUid(vs.slice(0, i + 1)));
235
224
  });
236
- })), [[item.path.map(function (_, i) {
237
- var uid = item.path.slice(0, i + 1).join('-');
238
- return nodeMap.get(uid);
239
- })]]) : flatOptions.filter(function (opt) {
240
- var arr = item.path.map(function (_, i) {
241
- return item.path.slice(0, i + 1).join('-');
225
+ })), [item.path.map(function (_, i) {
226
+ return nodeMap.get(pathToUid(item.path.slice(0, i + 1)));
227
+ })]) : flatOptions.filter(function (opt) {
228
+ var ancestors = item.path.map(function (_, i) {
229
+ return pathToUid(item.path.slice(0, i + 1));
242
230
  });
243
- return arr.includes(opt.uid);
231
+ return ancestors.includes(opt.uid);
244
232
  });
245
233
  changed = true;
246
234
  } else {
@@ -284,7 +272,7 @@ var Cascader = function Cascader(baseprops) {
284
272
  _props$onlyParentNode = props.onlyParentNode,
285
273
  onlyParentNode = _props$onlyParentNode === void 0 ? false : _props$onlyParentNode;
286
274
  var formatKey = function formatKey(val) {
287
- return val.join('-');
275
+ return pathToUid(val);
288
276
  };
289
277
  var rawValues = [];
290
278
  if (multiple) {
@@ -297,31 +285,26 @@ var Cascader = function Cascader(baseprops) {
297
285
  // Filter values based on onlyParentNode option
298
286
  var displayValues = rawValues;
299
287
  if (multiple && onlyParentNode) {
300
- // Find parent nodes that have all children selected
301
- var parentIds = [];
302
- var childPathStrs = new Set(rawValues.map(function (v) {
303
- return v.join('-');
304
- }));
288
+ // Find parent nodes that have all (direct) children selected
289
+ var selectedPathKeys = new Set(rawValues.map(pathToUid));
290
+ var parentPaths = [];
305
291
 
306
292
  // Check each node to see if it's a fully selected parent
307
- nodeMap.forEach(function (node, uid) {
308
- if (hasChild(node)) {
309
- var _node$children;
310
- var allChildrenSelected = (_node$children = node.children) === null || _node$children === void 0 ? void 0 : _node$children.every(function (child) {
311
- return childPathStrs.has(child.path.join('-'));
293
+ nodeMap.forEach(function (node) {
294
+ if (!node.isLeaf) {
295
+ var allChildrenSelected = getChildren(flatOptions, node.uid).every(function (child) {
296
+ return selectedPathKeys.has(pathToUid(child.path));
312
297
  });
313
298
  if (allChildrenSelected) {
314
- parentIds.push(uid);
299
+ parentPaths.push(node.path);
315
300
  }
316
301
  }
317
302
  });
318
303
 
319
304
  // Filter out child nodes whose parent is fully selected
320
305
  displayValues = rawValues.filter(function (path) {
321
- var pathStr = path.join('-');
322
- // Keep this path if it's not a child of any fully selected parent
323
- return !parentIds.some(function (parentId) {
324
- return pathStr.startsWith(parentId + '-');
306
+ return !parentPaths.some(function (parentPath) {
307
+ return isSamePrefixPath(parentPath, path);
325
308
  });
326
309
  });
327
310
  }
@@ -338,8 +321,8 @@ var Cascader = function Cascader(baseprops) {
338
321
  options: opts
339
322
  });
340
323
  } else {
341
- var _opts$$source, _opts, _source;
342
- var source = (_opts$$source = (_opts = opts[opts.length - 1]) === null || _opts === void 0 ? void 0 : _opts.$source) !== null && _opts$$source !== void 0 ? _opts$$source : opts[opts.length - 1];
324
+ var _opts, _source;
325
+ var source = (_opts = opts[opts.length - 1]) === null || _opts === void 0 ? void 0 : _opts.$source;
343
326
  label = (_source = source === null || source === void 0 ? void 0 : source[optionLabelProp]) !== null && _source !== void 0 ? _source : '';
344
327
  }
345
328
  } else if (fullNode) {
@@ -359,12 +342,17 @@ var Cascader = function Cascader(baseprops) {
359
342
  options: displayOptions,
360
343
  selectedKeys: selectedKeys
361
344
  };
362
- }, [multiple, mergedValue, nodeMap, optionLabelProp, props.fullNode, props.onlyParentNode]);
345
+ }, [multiple, mergedValue, nodeMap, flatOptions, optionLabelProp, props.fullNode, props.onlyParentNode]);
363
346
 
364
347
  // visible change
365
348
  var onVisibleChange = function onVisibleChange(newVisible) {
366
349
  popupVisible.current = newVisible;
367
350
  };
351
+ var handleClear = function handleClear() {
352
+ setSearchValue('');
353
+ setMergedValue([]);
354
+ onChange === null || onChange === void 0 || onChange([], []);
355
+ };
368
356
 
369
357
  // Performance Note: For large datasets (1000+ options), consider:
370
358
  // 1. Adding debounce to the search input
@@ -379,7 +367,11 @@ var Cascader = function Cascader(baseprops) {
379
367
  try {
380
368
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
381
369
  var item = _step.value;
382
- var text = String(item.label);
370
+ // Match against the full breadcrumb (e.g. "A / B / C") so that:
371
+ // - searching a parent label surfaces its descendants,
372
+ // - the result row shows the full path to disambiguate duplicate leaf
373
+ // labels across different parents.
374
+ var text = item.labelPath.join(' / ');
383
375
  var textLower = text.toLowerCase();
384
376
  if (textLower.includes(lowStr)) {
385
377
  var matches = [];
@@ -427,7 +419,8 @@ var Cascader = function Cascader(baseprops) {
427
419
  searchable: searchable,
428
420
  mode: multiple ? 'multiple' : undefined,
429
421
  value: searchValue,
430
- onSearch: handleSearch
422
+ onSearch: handleSearch,
423
+ onClear: handleClear
431
424
  }));
432
425
  };
433
426
  var renderPopup = function renderPopup() {
@@ -15,11 +15,27 @@ export type FieldNames = {
15
15
  value: string;
16
16
  children: string;
17
17
  };
18
- export type FlattenOption = Option & {
18
+ /**
19
+ * Flattened representation of a tree node.
20
+ *
21
+ * Deliberately a concrete type (not `Option & ...`) so that:
22
+ * - `.label` / `.value` / `.isLeaf` resolve to their precise types (an index
23
+ * signature on `Option` would otherwise widen them to `unknown`),
24
+ * - `.children` is a compile error — flattened nodes intentionally do not
25
+ * carry children; use `getChildren(data, uid)` instead.
26
+ * Dynamic/extra-field access should go through `$source` (the raw node).
27
+ */
28
+ export type FlattenOption = {
29
+ $source: Option;
30
+ label: string;
31
+ value: string | number;
19
32
  pid: string;
20
33
  uid: string;
21
34
  path: Array<string | number>;
22
- $source: Option;
35
+ labelPath: string[];
36
+ level: number;
37
+ isLeaf: boolean;
38
+ disabled?: boolean;
23
39
  };
24
40
  export type NodeProps = FlattenOption & {
25
41
  level: number;
@@ -87,6 +103,7 @@ export interface CascaderProps extends Omit<SelectorProps, 'options' | 'value' |
87
103
  multiple?: boolean;
88
104
  /**
89
105
  * Is it searchable
106
+ * @default true
90
107
  */
91
108
  searchable?: boolean;
92
109
  /**
@@ -15,14 +15,14 @@ import Checkbox from "../Checkbox";
15
15
  import Spin from "../Spin";
16
16
  import isEqual from "../utils/isEqual";
17
17
  import { CascaderCtx } from "./cascader";
18
- import { hasChild, isHalfChecked } from "./utils";
18
+ import { getChildren, isHalfChecked } from "./utils";
19
19
  var Node = function Node(props) {
20
20
  var _expandedPath$level;
21
21
  var uid = props.uid,
22
22
  value = props.value,
23
23
  disabled = props.disabled,
24
24
  label = props.label,
25
- children = props.children,
25
+ $source = props.$source,
26
26
  isLeaf = props.isLeaf,
27
27
  path = props.path,
28
28
  level = props.level;
@@ -33,9 +33,10 @@ var Node = function Node(props) {
33
33
  mergedValue = _useContext.mergedValue,
34
34
  loadData = _useContext.loadData,
35
35
  nodeMap = _useContext.nodeMap,
36
+ flatOptions = _useContext.flatOptions,
36
37
  onNodeMouseEnter = _useContext.onNodeMouseEnter,
37
38
  onItemClick = _useContext.onItemClick;
38
- var isParent = hasChild(props);
39
+ var isParent = !isLeaf;
39
40
 
40
41
  /**
41
42
  * 0: not load
@@ -57,11 +58,7 @@ var Node = function Node(props) {
57
58
  if (loadData && isLeaf === false) {
58
59
  var _loadData;
59
60
  setLoad(1);
60
- (_loadData = loadData({
61
- label: label,
62
- value: value,
63
- children: children
64
- })) === null || _loadData === void 0 || _loadData.then(function () {
61
+ (_loadData = loadData($source)) === null || _loadData === void 0 || _loadData.then(function () {
65
62
  setLoad(2);
66
63
  }).catch(function () {
67
64
  setLoad(0);
@@ -83,12 +80,12 @@ var Node = function Node(props) {
83
80
  var _useMemo = useMemo(function () {
84
81
  var currentNode = nodeMap.get(uid);
85
82
  if (!multiple || !currentNode || !isParent) return [false, false];
86
- return isHalfChecked(mergedValue, currentNode);
87
- }, [nodeMap, uid, mergedValue, isParent, multiple]),
83
+ return isHalfChecked(mergedValue, currentNode, getChildren(flatOptions, uid));
84
+ }, [nodeMap, uid, mergedValue, flatOptions, isParent, multiple]),
88
85
  _useMemo2 = _slicedToArray(_useMemo, 2),
89
86
  checkedAll = _useMemo2[0],
90
87
  indeterminate = _useMemo2[1];
91
- var clsName = clsx("".concat(prefixCls, "-menu-item"), _defineProperty(_defineProperty(_defineProperty({}, "".concat(prefixCls, "-menu-item-expand"), hasChild(props)), "".concat(prefixCls, "-menu-item-disabled"), disabled), "active", ((_expandedPath$level = expandedPath[level]) === null || _expandedPath$level === void 0 ? void 0 : _expandedPath$level.key) === uid), "".concat(prefixCls, "-menu-item-").concat(level));
88
+ var clsName = clsx("".concat(prefixCls, "-menu-item"), _defineProperty(_defineProperty(_defineProperty({}, "".concat(prefixCls, "-menu-item-expand"), !isLeaf), "".concat(prefixCls, "-menu-item-disabled"), disabled), "active", ((_expandedPath$level = expandedPath[level]) === null || _expandedPath$level === void 0 ? void 0 : _expandedPath$level.key) === uid), "".concat(prefixCls, "-menu-item-").concat(level));
92
89
  var handleMouseEnter = function handleMouseEnter() {
93
90
  if (disabled) return;
94
91
  onNodeMouseEnter(props, level);
@@ -14,7 +14,8 @@ var SearchList = function SearchList(props) {
14
14
  return /*#__PURE__*/React.createElement("ul", {
15
15
  className: "".concat(prefixCls, "-filter-menu")
16
16
  }, items.length ? items.map(function (item) {
17
- var title = item.data.title || item.data.label;
17
+ var _item$data$$source;
18
+ var title = ((_item$data$$source = item.data.$source) === null || _item$data$$source === void 0 ? void 0 : _item$data$$source.title) || item.data.labelPath.join(' / ');
18
19
  return /*#__PURE__*/React.createElement("li", {
19
20
  className: "".concat(prefixCls, "-filter-menu-item"),
20
21
  title: typeof title === 'string' ? title : String(title),
@@ -7,23 +7,58 @@ import { FieldNames, FlattenOption } from '../interface';
7
7
  */
8
8
  export declare function hasChild(data: Record<string, any>, childrenField?: string): any;
9
9
  /**
10
- * Populate data into input fields and dropdown lists from a value array
11
- * @param arr - The value array representing the selected path
10
+ * Separator used to build a node's `uid` from its value path. A control
11
+ * character is used on purpose so it can never appear inside a user value —
12
+ * this prevents collisions like value `"a-1"` vs path `["a", "1"]` that a plain
13
+ * `'-'` separator would produce.
14
+ */
15
+ export declare const UID_SEP = "\u0001";
16
+ /**
17
+ * Build the canonical uid for a value path. Use this everywhere a path needs
18
+ * to be turned into a key (nodeMap lookups, selected keys, comparisons) so the
19
+ * format stays consistent with the `uid`/`pid` produced by `flattenOptions`.
20
+ * @param path - The value path
21
+ */
22
+ export declare const pathToUid: (path: Array<string | number>) => string;
23
+ /**
24
+ * Get the direct flattened children of the node identified by `uid`.
25
+ *
26
+ * Flattened nodes intentionally do not carry a `children` reference (it used to
27
+ * point at the raw, un-flattened subtree and caused type lies). Derive children
28
+ * from the flat list via `pid` instead — single source of truth.
29
+ * @param data - The flattened options data
30
+ * @param uid - The parent node's uid
31
+ */
32
+ export declare const getChildren: (data: Array<FlattenOption>, uid: string) => FlattenOption[];
33
+ /**
34
+ * Reconstruct cascade columns and the highlight path from a value path.
35
+ *
36
+ * Walks the flattened options level by level, matching each value segment
37
+ * against the correct parent column via `pid` + `value`. Returns:
38
+ * - `queue`: the columns to render (column 0 = root, then each matched
39
+ * node's children column).
40
+ * - `path`: the highlight breadcrumb shaped as `{ key: uid, label }`, so it
41
+ * aligns with `expandedPath[level].key === uid` in the node view.
42
+ *
43
+ * Stops safely at the last valid segment if the value path does not exist in
44
+ * the data source.
45
+ *
46
+ * @param arr - The selected path. In `multiple` mode the value is an array of
47
+ * paths; the first path is used to drive which columns get expanded.
12
48
  * @param data - The flattened options data
13
49
  * @param options - Optional configuration
14
- * @returns A tuple of [queue, path] where queue is the column data and path is the selected path info
50
+ * @returns A tuple of `[queue, path]`
15
51
  */
16
- export declare const changeToView: (arr: Array<string | number>, data: Array<FlattenOption>, options?: {
17
- needNext?: boolean | undefined;
52
+ export declare const changeToView: (arr: Array<string | number> | Array<Array<string | number>>, data: Array<FlattenOption>, options?: {
18
53
  multiple?: boolean | undefined;
19
- } | undefined) => (FlattenOption[][] | {
20
- id: string | number;
21
- text: string;
22
- }[])[];
54
+ } | undefined) => [FlattenOption[][], Array<{
55
+ key: string;
56
+ label: string;
57
+ }>];
23
58
  /**
24
- * Format a path array into a key string
59
+ * Format a value path into a key string. Alias of `pathToUid` so all path→key
60
+ * conversions share one collision-safe format.
25
61
  * @param val - The path array
26
- * @returns A string key joined by '-'
27
62
  */
28
63
  export declare const formatKey: (val: Array<string | number>) => string;
29
64
  /**
@@ -37,13 +72,22 @@ export declare const isSamePrefixPath: (prefix: Array<unknown>, target: Array<un
37
72
  * Determine if a node is fully selected or half selected (indeterminate)
38
73
  * @param value - The selected value paths
39
74
  * @param item - The flatten option node to check
75
+ * @param children - The node's direct flattened children (derive via `getChildren`)
40
76
  * @returns A tuple [checkedAll, indeterminate]
41
77
  */
42
- export declare function isHalfChecked(value: Array<Array<string | number>>, item: FlattenOption): boolean[];
78
+ export declare function isHalfChecked(value: Array<Array<string | number>>, item: FlattenOption, children: FlattenOption[]): boolean[];
43
79
  /**
44
- * Flatten a tree structure into an array for easier searching and traversal
80
+ * Flatten a tree structure into an array for easier searching and traversal.
81
+ *
82
+ * The flattened nodes intentionally do NOT carry a `children` field — use
83
+ * `getChildren(data, uid)` to read a node's children. `uid`/`pid` are built
84
+ * via `pathToUid` (collision-safe). Includes a depth cap and a cycle guard so
85
+ * malformed input (very deep or self-referencing trees) cannot overflow the
86
+ * stack.
87
+ *
45
88
  * @param tree - The tree data to flatten
46
89
  * @param fieldNames - Custom field names for label, value, and children
90
+ * @param maxDepth - Maximum nesting depth (default 100)
47
91
  * @returns An array of flattened options with additional metadata
48
92
  */
49
- export declare const flattenOptions: (tree: Array<Record<string, unknown>>, fieldNames: FieldNames) => FlattenOption[];
93
+ export declare const flattenOptions: (tree: Array<Record<string, unknown>>, fieldNames?: FieldNames, maxDepth?: number) => FlattenOption[];