rsuite 5.31.1 → 5.32.0

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 (60) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/cjs/Calendar/CalendarContainer.d.ts +2 -0
  3. package/cjs/Calendar/CalendarContainer.js +4 -1
  4. package/cjs/Calendar/MonthDropdown.js +1 -1
  5. package/cjs/Cascader/Cascader.d.ts +2 -2
  6. package/cjs/Cascader/Cascader.js +83 -71
  7. package/cjs/Cascader/DropdownMenu.d.ts +6 -2
  8. package/cjs/Cascader/DropdownMenu.js +8 -4
  9. package/cjs/Cascader/utils.d.ts +52 -17
  10. package/cjs/Cascader/utils.js +99 -138
  11. package/cjs/DatePicker/DatePicker.d.ts +3 -1
  12. package/cjs/DatePicker/DatePicker.js +4 -1
  13. package/cjs/DateRangePicker/Calendar.d.ts +1 -0
  14. package/cjs/DateRangePicker/Calendar.js +4 -1
  15. package/cjs/DateRangePicker/DateRangePicker.d.ts +3 -1
  16. package/cjs/DateRangePicker/DateRangePicker.js +4 -1
  17. package/cjs/MultiCascader/DropdownMenu.d.ts +2 -2
  18. package/cjs/MultiCascader/MultiCascader.d.ts +1 -1
  19. package/cjs/MultiCascader/MultiCascader.js +12 -7
  20. package/cjs/MultiCascader/utils.d.ts +2 -2
  21. package/cjs/MultiCascader/utils.js +3 -3
  22. package/cjs/Picker/utils.d.ts +4 -3
  23. package/cjs/Picker/utils.js +8 -4
  24. package/cjs/utils/getDataGroupBy.js +1 -1
  25. package/cjs/utils/treeUtils.d.ts +5 -1
  26. package/cjs/utils/treeUtils.js +31 -6
  27. package/cjs/utils/useMap.d.ts +6 -0
  28. package/cjs/utils/useMap.js +35 -0
  29. package/dist/rsuite.js +186 -14
  30. package/dist/rsuite.js.map +1 -1
  31. package/dist/rsuite.min.js +1 -1
  32. package/dist/rsuite.min.js.map +1 -1
  33. package/esm/Calendar/CalendarContainer.d.ts +2 -0
  34. package/esm/Calendar/CalendarContainer.js +4 -1
  35. package/esm/Calendar/MonthDropdown.js +1 -1
  36. package/esm/Cascader/Cascader.d.ts +2 -2
  37. package/esm/Cascader/Cascader.js +85 -75
  38. package/esm/Cascader/DropdownMenu.d.ts +6 -2
  39. package/esm/Cascader/DropdownMenu.js +8 -4
  40. package/esm/Cascader/utils.d.ts +52 -17
  41. package/esm/Cascader/utils.js +100 -135
  42. package/esm/DatePicker/DatePicker.d.ts +3 -1
  43. package/esm/DatePicker/DatePicker.js +4 -1
  44. package/esm/DateRangePicker/Calendar.d.ts +1 -0
  45. package/esm/DateRangePicker/Calendar.js +4 -1
  46. package/esm/DateRangePicker/DateRangePicker.d.ts +3 -1
  47. package/esm/DateRangePicker/DateRangePicker.js +4 -1
  48. package/esm/MultiCascader/DropdownMenu.d.ts +2 -2
  49. package/esm/MultiCascader/MultiCascader.d.ts +1 -1
  50. package/esm/MultiCascader/MultiCascader.js +12 -7
  51. package/esm/MultiCascader/utils.d.ts +2 -2
  52. package/esm/MultiCascader/utils.js +4 -4
  53. package/esm/Picker/utils.d.ts +4 -3
  54. package/esm/Picker/utils.js +8 -4
  55. package/esm/utils/getDataGroupBy.js +2 -2
  56. package/esm/utils/treeUtils.d.ts +5 -1
  57. package/esm/utils/treeUtils.js +30 -6
  58. package/esm/utils/useMap.d.ts +6 -0
  59. package/esm/utils/useMap.js +29 -0
  60. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ # [5.32.0](https://github.com/rsuite/rsuite/compare/v5.31.1...v5.32.0) (2023-04-21)
2
+
3
+ ### Bug Fixes
4
+
5
+ - **build:** fix broken lodash currying in CDN bundles ([#3159](https://github.com/rsuite/rsuite/issues/3159)) ([896a9d5](https://github.com/rsuite/rsuite/commit/896a9d53cf2c1e0140e43eea024c4f0361c04328))
6
+ - **Cascader:** avoid mutating data prop ([#3157](https://github.com/rsuite/rsuite/issues/3157)) ([6d13318](https://github.com/rsuite/rsuite/commit/6d133185ea1c65b47b35da61499d5cff77dde122))
7
+
8
+ ### Features
9
+
10
+ - **DateRangePicker:** add `limitStartYear` prop ([#3163](https://github.com/rsuite/rsuite/issues/3163)) ([fd27df2](https://github.com/rsuite/rsuite/commit/fd27df21e1c36372ea8b444f79521c901a65780c))
11
+
1
12
  ## [5.31.1](https://github.com/rsuite/rsuite/compare/v5.31.0...v5.31.1) (2023-04-14)
2
13
 
3
14
  ### Bug Fixes
@@ -34,6 +34,8 @@ export interface CalendarProps extends WithAsProps, Omit<HTMLAttributes<HTMLDivE
34
34
  isoWeek?: boolean;
35
35
  /** Limit showing how many years in the future */
36
36
  limitEndYear?: number;
37
+ /** Limit showing how many years in the past */
38
+ limitStartYear?: number;
37
39
  /** Custom locale */
38
40
  locale: CalendarLocale;
39
41
  /** Callback after the date has changed */
@@ -51,6 +51,7 @@ var CalendarContainer = /*#__PURE__*/_react.default.forwardRef(function (props,
51
51
  _props$isoWeek = props.isoWeek,
52
52
  isoWeek = _props$isoWeek === void 0 ? false : _props$isoWeek,
53
53
  limitEndYear = props.limitEndYear,
54
+ limitStartYear = props.limitStartYear,
54
55
  locale = props.locale,
55
56
  onChangeMonth = props.onChangeMonth,
56
57
  onChangeTime = props.onChangeTime,
@@ -68,7 +69,7 @@ var CalendarContainer = /*#__PURE__*/_react.default.forwardRef(function (props,
68
69
  showMeridian = props.showMeridian,
69
70
  showWeekNumbers = props.showWeekNumbers,
70
71
  inline = props.inline,
71
- rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "className", "classPrefix", "dateRange", "disabledBackward", "defaultState", "disabledDate", "disabledForward", "format", "hoverRangeValue", "isoWeek", "limitEndYear", "locale", "onChangeMonth", "onChangeTime", "onMouseMove", "onMoveBackward", "onMoveForward", "onSelect", "onToggleMeridian", "onToggleMonthDropdown", "onToggleTimeDropdown", "calendarDate", "renderCell", "renderTitle", "renderToolbar", "showMeridian", "showWeekNumbers", "inline"]);
72
+ rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "className", "classPrefix", "dateRange", "disabledBackward", "defaultState", "disabledDate", "disabledForward", "format", "hoverRangeValue", "isoWeek", "limitEndYear", "limitStartYear", "locale", "onChangeMonth", "onChangeTime", "onMouseMove", "onMoveBackward", "onMoveForward", "onSelect", "onToggleMeridian", "onToggleMonthDropdown", "onToggleTimeDropdown", "calendarDate", "renderCell", "renderTitle", "renderToolbar", "showMeridian", "showWeekNumbers", "inline"]);
72
73
 
73
74
  var _useClassNames = (0, _utils.useClassNames)(classPrefix),
74
75
  withClassPrefix = _useClassNames.withClassPrefix,
@@ -182,6 +183,7 @@ var CalendarContainer = /*#__PURE__*/_react.default.forwardRef(function (props,
182
183
  }), renderDate && /*#__PURE__*/_react.default.createElement(_CalendarBody.default, null), renderMonth && /*#__PURE__*/_react.default.createElement(_MonthDropdown.default, {
183
184
  show: showMonth,
184
185
  limitEndYear: limitEndYear,
186
+ limitStartYear: limitStartYear,
185
187
  disabledMonth: isDisabledDate
186
188
  }), renderTime && /*#__PURE__*/_react.default.createElement(_TimeDropdown.default, (0, _extends2.default)({}, timeDropdownProps, {
187
189
  show: showTime,
@@ -207,6 +209,7 @@ CalendarContainer.propTypes = {
207
209
  hideSeconds: _propTypes.default.func,
208
210
  isoWeek: _propTypes.default.bool,
209
211
  limitEndYear: _propTypes.default.number,
212
+ limitStartYear: _propTypes.default.number,
210
213
  locale: _propTypes.default.object,
211
214
  onChangeMonth: _propTypes.default.func,
212
215
  onChangeTime: _propTypes.default.func,
@@ -66,7 +66,7 @@ var MonthDropdown = /*#__PURE__*/_react.default.forwardRef(function (props, ref)
66
66
 
67
67
  var thisYear = _utils.DateUtils.getYear(new Date());
68
68
 
69
- var startYear = limitStartYear ? thisYear - limitStartYear : 1900;
69
+ var startYear = limitStartYear ? thisYear - limitStartYear + 1 : 1900;
70
70
  var rowCount = (0, _react.useMemo)(function () {
71
71
  var endYear = thisYear + limitEndYear;
72
72
  return endYear - startYear;
@@ -15,7 +15,7 @@ export interface CascaderProps<T = ValueType> extends FormControlPickerProps<T |
15
15
  /** When true, make the parent node selectable */
16
16
  parentSelectable?: boolean;
17
17
  /** Custom render menu */
18
- renderMenu?: (items: ItemDataType[], menu: React.ReactNode, parentNode?: any, layer?: number) => React.ReactNode;
18
+ renderMenu?: (items: readonly ItemDataType[], menu: React.ReactNode, parentNode?: any, layer?: number) => React.ReactNode;
19
19
  /** Custom render menu items */
20
20
  renderMenuItem?: (itemLabel: React.ReactNode, item: ItemDataType) => React.ReactNode;
21
21
  /** Custom render search items */
@@ -29,7 +29,7 @@ export interface CascaderProps<T = ValueType> extends FormControlPickerProps<T |
29
29
  /** Called when searching */
30
30
  onSearch?: (searchKeyword: string, event: React.SyntheticEvent) => void;
31
31
  /** Asynchronously load the children of the tree node. */
32
- getChildren?: (node: ItemDataType) => ItemDataType[] | Promise<ItemDataType[]>;
32
+ getChildren?: (node: ItemDataType<T>) => ItemDataType<T>[] | Promise<ItemDataType<T>[]>;
33
33
  }
34
34
  export interface CascaderComponent {
35
35
  <T>(props: CascaderProps<T> & {
@@ -13,6 +13,8 @@ var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runt
13
13
 
14
14
  var _react = _interopRequireWildcard(require("react"));
15
15
 
16
+ var _reactUseSet = require("react-use-set");
17
+
16
18
  var _propTypes = _interopRequireDefault(require("prop-types"));
17
19
 
18
20
  var _omit = _interopRequireDefault(require("lodash/omit"));
@@ -35,6 +37,8 @@ var _utils2 = require("../utils");
35
37
 
36
38
  var _Picker = require("../Picker");
37
39
 
40
+ var _useMap = require("../utils/useMap");
41
+
38
42
  var emptyArray = [];
39
43
 
40
44
  var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
@@ -94,10 +98,6 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
94
98
  active = _useState[0],
95
99
  setActive = _useState[1];
96
100
 
97
- var _useState2 = (0, _react.useState)((0, _treeUtils.flattenTree)(data, childrenKey)),
98
- flattenData = _useState2[0],
99
- setFlattenData = _useState2[1];
100
-
101
101
  var triggerRef = (0, _react.useRef)(null);
102
102
  var overlayRef = (0, _react.useRef)(null);
103
103
  var targetRef = (0, _react.useRef)(null);
@@ -107,25 +107,47 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
107
107
  value = _ref[0],
108
108
  setValue = _ref[1];
109
109
 
110
+ var isMounted = (0, _utils2.useIsMounted)();
111
+ var loadingItemsSet = (0, _reactUseSet.useSet)();
112
+ var asyncChildrenMap = (0, _useMap.useMap)();
113
+ var parentMap = (0, _react.useMemo)(function () {
114
+ return (0, _utils.getParentMap)(data, function (item) {
115
+ var _asyncChildrenMap$get;
116
+
117
+ return (_asyncChildrenMap$get = asyncChildrenMap.get(item)) !== null && _asyncChildrenMap$get !== void 0 ? _asyncChildrenMap$get : item[childrenKey];
118
+ });
119
+ }, [asyncChildrenMap, childrenKey, data]);
120
+ var flattenedData = (0, _react.useMemo)(function () {
121
+ return (0, _treeUtils.flattenTree)(data, function (item) {
122
+ var _asyncChildrenMap$get2;
123
+
124
+ return (_asyncChildrenMap$get2 = asyncChildrenMap.get(item)) !== null && _asyncChildrenMap$get2 !== void 0 ? _asyncChildrenMap$get2 : item[childrenKey];
125
+ });
126
+ }, [asyncChildrenMap, childrenKey, data]); // The item that focus is on
127
+
128
+ var _useState2 = (0, _react.useState)(),
129
+ activeItem = _useState2[0],
130
+ setActiveItem = _useState2[1];
131
+
110
132
  var _usePaths = (0, _utils.usePaths)({
111
133
  data: data,
112
- valueKey: valueKey,
113
- childrenKey: childrenKey,
114
- value: value
134
+ activeItem: activeItem,
135
+ selectedItem: flattenedData.find(function (item) {
136
+ return item[valueKey] === value;
137
+ }),
138
+ getParent: function getParent(item) {
139
+ return parentMap.get(item);
140
+ },
141
+ getChildren: function getChildren(item) {
142
+ var _asyncChildrenMap$get3;
143
+
144
+ return (_asyncChildrenMap$get3 = asyncChildrenMap.get(item)) !== null && _asyncChildrenMap$get3 !== void 0 ? _asyncChildrenMap$get3 : item[childrenKey];
145
+ }
115
146
  }),
116
- selectedPaths = _usePaths.selectedPaths,
117
- valueToPaths = _usePaths.valueToPaths,
118
- columnData = _usePaths.columnData,
119
- addColumn = _usePaths.addColumn,
120
- removeColumnByIndex = _usePaths.removeColumnByIndex,
121
- setValueToPaths = _usePaths.setValueToPaths,
122
- setColumnData = _usePaths.setColumnData,
123
- setSelectedPaths = _usePaths.setSelectedPaths,
124
- enforceUpdate = _usePaths.enforceUpdate;
125
-
126
- (0, _react.useEffect)(function () {
127
- setFlattenData((0, _treeUtils.flattenTree)(data, childrenKey));
128
- }, [data, childrenKey]);
147
+ columnsToDisplay = _usePaths.columnsToDisplay,
148
+ pathTowardsActiveItem = _usePaths.pathTowardsActiveItem,
149
+ pathTowardsSelectedItem = _usePaths.pathTowardsSelectedItem;
150
+
129
151
  (0, _Picker.usePublicMethods)(ref, {
130
152
  triggerRef: triggerRef,
131
153
  overlayRef: overlayRef,
@@ -141,7 +163,7 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
141
163
  */
142
164
 
143
165
 
144
- var hasValue = valueToPaths.length > 0 || !(0, _isNil.default)(value) && (0, _isFunction.default)(renderValue);
166
+ var hasValue = pathTowardsSelectedItem.length > 0 || !(0, _isNil.default)(value) && (0, _isFunction.default)(renderValue);
145
167
 
146
168
  var _useClassNames = (0, _utils2.useClassNames)(classPrefix),
147
169
  prefix = _useClassNames.prefix,
@@ -156,15 +178,17 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
156
178
  return true;
157
179
  }
158
180
 
159
- if (item.parent && someKeyword(item.parent)) {
181
+ var parent = parentMap.get(item);
182
+
183
+ if (parent && someKeyword(parent)) {
160
184
  return true;
161
185
  }
162
186
 
163
187
  return false;
164
- }, [labelKey, searchKeyword]);
188
+ }, [labelKey, parentMap, searchKeyword]);
165
189
  var getSearchResult = (0, _react.useCallback)(function (keyword) {
166
190
  var items = [];
167
- var result = flattenData.filter(function (item) {
191
+ var result = flattenedData.filter(function (item) {
168
192
  if (!parentSelectable && item[childrenKey]) {
169
193
  return false;
170
194
  }
@@ -181,19 +205,24 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
181
205
  }
182
206
 
183
207
  return items;
184
- }, [childrenKey, flattenData, someKeyword, parentSelectable]); // Used to hover the focuse item when trigger `onKeydown`
208
+ }, [childrenKey, flattenedData, someKeyword, parentSelectable]); // Used to hover the focuse item when trigger `onKeydown`
185
209
 
186
210
  var _useFocusItemValue = (0, _Picker.useFocusItemValue)(value, {
187
211
  rtl: rtl,
188
- data: flattenData,
212
+ data: flattenedData,
189
213
  valueKey: valueKey,
190
- defaultLayer: valueToPaths !== null && valueToPaths !== void 0 && valueToPaths.length ? valueToPaths.length - 1 : 0,
214
+ defaultLayer: pathTowardsSelectedItem !== null && pathTowardsSelectedItem !== void 0 && pathTowardsSelectedItem.length ? pathTowardsSelectedItem.length - 1 : 0,
191
215
  target: function target() {
192
216
  return overlayRef.current;
193
217
  },
218
+ getParent: function getParent(item) {
219
+ return parentMap.get(item);
220
+ },
194
221
  callback: (0, _react.useCallback)(function (value) {
195
- enforceUpdate(value, true);
196
- }, [enforceUpdate])
222
+ setActiveItem(flattenedData.find(function (item) {
223
+ return item[valueKey] === value;
224
+ }));
225
+ }, [flattenedData, setActiveItem, valueKey])
197
226
  }),
198
227
  focusItemValue = _useFocusItemValue.focusItemValue,
199
228
  setFocusItemValue = _useFocusItemValue.setFocusItemValue,
@@ -239,12 +268,9 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
239
268
  return;
240
269
  }
241
270
 
242
- setColumnData([data]);
243
271
  setValue(null);
244
- setSelectedPaths([]);
245
- setValueToPaths([]);
246
272
  onChange === null || onChange === void 0 ? void 0 : onChange(null, event);
247
- }, [data, disabled, onChange, setSelectedPaths, setColumnData, setValueToPaths, setValue]);
273
+ }, [disabled, onChange, setValue]);
248
274
  var handleMenuPressEnter = (0, _react.useCallback)(function (event) {
249
275
  var focusItem = (0, _treeUtils.findNodeOfTree)(data, function (item) {
250
276
  return item[valueKey] === focusItemValue;
@@ -253,10 +279,9 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
253
279
 
254
280
  if (isLeafNode) {
255
281
  setValue(focusItemValue);
256
- setValueToPaths(selectedPaths);
257
282
 
258
- if (selectedPaths.length) {
259
- setLayer(selectedPaths.length - 1);
283
+ if (pathTowardsActiveItem.length) {
284
+ setLayer(pathTowardsActiveItem.length - 1);
260
285
  }
261
286
 
262
287
  if (!(0, _shallowEqual.default)(value, focusItemValue)) {
@@ -265,7 +290,7 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
265
290
 
266
291
  handleClose();
267
292
  }
268
- }, [childrenKey, data, focusItemValue, handleClose, onChange, selectedPaths, setLayer, setValue, setValueToPaths, value, valueKey]);
293
+ }, [childrenKey, data, focusItemValue, handleClose, onChange, pathTowardsActiveItem, setLayer, setValue, value, valueKey]);
269
294
  var onPickerKeyDown = (0, _Picker.useToggleKeyDownEvent)((0, _extends3.default)({
270
295
  toggle: !focusItemValue || !active,
271
296
  triggerRef: triggerRef,
@@ -279,44 +304,32 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
279
304
  }, rest));
280
305
 
281
306
  var handleSelect = function handleSelect(node, cascadePaths, isLeafNode, event) {
282
- var _node$childrenKey, _node$childrenKey2, _triggerRef$current2;
307
+ var _node$childrenKey, _triggerRef$current2;
283
308
 
284
309
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(node, cascadePaths, event);
285
- setSelectedPaths(cascadePaths);
286
- var nextValue = node[valueKey];
287
- var columnIndex = cascadePaths.length; // Lazy load node's children
310
+ setActiveItem(node);
311
+ var nextValue = node[valueKey]; // Lazy load node's children
288
312
 
289
- if (typeof getChildren === 'function' && ((_node$childrenKey = node[childrenKey]) === null || _node$childrenKey === void 0 ? void 0 : _node$childrenKey.length) === 0) {
290
- node.loading = true;
313
+ if (typeof getChildren === 'function' && ((_node$childrenKey = node[childrenKey]) === null || _node$childrenKey === void 0 ? void 0 : _node$childrenKey.length) === 0 && !asyncChildrenMap.has(node)) {
314
+ loadingItemsSet.add(node);
291
315
  var children = getChildren(node);
292
316
 
293
317
  if (children instanceof Promise) {
294
318
  children.then(function (data) {
295
- node.loading = false;
296
- node[childrenKey] = data;
297
-
298
- if (targetRef.current || inline) {
299
- addColumn(data, columnIndex);
319
+ if (isMounted()) {
320
+ loadingItemsSet.delete(node);
321
+ asyncChildrenMap.set(node, data);
300
322
  }
301
323
  });
302
324
  } else {
303
- node.loading = false;
304
- node[childrenKey] = children;
305
- addColumn(children, columnIndex);
325
+ loadingItemsSet.delete(node);
326
+ asyncChildrenMap.set(node, children);
306
327
  }
307
- } else if ((_node$childrenKey2 = node[childrenKey]) !== null && _node$childrenKey2 !== void 0 && _node$childrenKey2.length) {
308
- addColumn(node[childrenKey], columnIndex);
309
- } else {
310
- // Removes subsequent columns of the current column when the clicked node is a leaf node.
311
- removeColumnByIndex(columnIndex);
312
328
  }
313
329
 
314
330
  if (isLeafNode) {
315
331
  // Determines whether the option is a leaf node, and if so, closes the picker.
316
- handleClose(); // Update the selected path to the value path.
317
- // That is, the selected path will be displayed on the button after clicking the child node.
318
-
319
- setValueToPaths(cascadePaths);
332
+ handleClose();
320
333
  setValue(nextValue);
321
334
 
322
335
  if (!(0, _shallowEqual.default)(value, nextValue)) {
@@ -331,7 +344,6 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
331
344
  if (parentSelectable && !(0, _shallowEqual.default)(value, nextValue)) {
332
345
  setValue(nextValue);
333
346
  onChange === null || onChange === void 0 ? void 0 : onChange(nextValue, event);
334
- setValueToPaths(cascadePaths);
335
347
  } // Update menu position
336
348
 
337
349
 
@@ -347,16 +359,15 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
347
359
  handleClose();
348
360
  setSearchKeyword('');
349
361
  setValue(nextValue);
350
- setValueToPaths(nodes);
351
- enforceUpdate(nextValue);
352
362
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(node, nodes, event);
353
363
  onChange === null || onChange === void 0 ? void 0 : onChange(nextValue, event);
354
364
  };
355
365
 
356
366
  var renderSearchRow = function renderSearchRow(item, key) {
357
367
  var regx = new RegExp((0, _utils2.getSafeRegExpString)(searchKeyword), 'ig');
358
- var nodes = (0, _treeUtils.getNodeParents)(item);
359
- nodes.push(item);
368
+ var nodes = (0, _utils.getPathTowardsItem)(item, function (item) {
369
+ return parentMap.get(item);
370
+ });
360
371
  var formattedNodes = nodes.map(function (node) {
361
372
  var _extends2;
362
373
 
@@ -448,12 +459,13 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
448
459
  menuWidth: menuWidth,
449
460
  menuHeight: menuHeight,
450
461
  disabledItemValues: disabledItemValues,
462
+ loadingItemsSet: loadingItemsSet,
451
463
  valueKey: valueKey,
452
464
  labelKey: labelKey,
453
465
  childrenKey: childrenKey,
454
466
  classPrefix: 'picker-cascader-menu',
455
- cascadeData: columnData,
456
- cascadePaths: selectedPaths,
467
+ cascadeData: columnsToDisplay,
468
+ cascadePaths: pathTowardsActiveItem,
457
469
  activeItemValue: value // FIXME make onSelect generic
458
470
  ,
459
471
  onSelect: handleSelect,
@@ -464,15 +476,15 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
464
476
 
465
477
  var selectedElement = placeholder;
466
478
 
467
- if (valueToPaths.length > 0) {
479
+ if (pathTowardsSelectedItem.length > 0) {
468
480
  selectedElement = [];
469
- valueToPaths.forEach(function (item, index) {
481
+ pathTowardsSelectedItem.forEach(function (item, index) {
470
482
  var key = item[valueKey] || item[labelKey];
471
483
  selectedElement.push( /*#__PURE__*/_react.default.createElement("span", {
472
484
  key: key
473
485
  }, item[labelKey]));
474
486
 
475
- if (index < valueToPaths.length - 1) {
487
+ if (index < pathTowardsSelectedItem.length - 1) {
476
488
  selectedElement.push( /*#__PURE__*/_react.default.createElement("span", {
477
489
  className: "separator",
478
490
  key: key + "-separator"
@@ -482,7 +494,7 @@ var Cascader = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
482
494
  }
483
495
 
484
496
  if (!(0, _isNil.default)(value) && (0, _isFunction.default)(renderValue)) {
485
- selectedElement = renderValue(value, valueToPaths, selectedElement); // If renderValue returns null or undefined, hasValue is false.
497
+ selectedElement = renderValue(value, pathTowardsSelectedItem, selectedElement); // If renderValue returns null or undefined, hasValue is false.
486
498
 
487
499
  if ((0, _isNil.default)(selectedElement)) {
488
500
  hasValue = false;
@@ -2,19 +2,23 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { ItemDataType, WithAsProps, RsRefForwardingComponent } from '../@types/common';
4
4
  import { ValueType } from './Cascader';
5
+ declare type SetLike<T = unknown> = {
6
+ has(value: T): boolean;
7
+ };
5
8
  export interface DropdownMenuProps extends Omit<WithAsProps, 'classPrefix'> {
6
9
  classPrefix: string;
7
10
  disabledItemValues: ValueType[];
8
11
  activeItemValue?: ValueType | null;
9
12
  childrenKey: string;
10
- cascadeData: ItemDataType[][];
13
+ cascadeData: (readonly ItemDataType[])[];
14
+ loadingItemsSet?: SetLike<ItemDataType>;
11
15
  cascadePaths: ItemDataType[];
12
16
  valueKey: string;
13
17
  labelKey: string;
14
18
  menuWidth?: number;
15
19
  menuHeight?: number | string;
16
20
  renderMenuItem?: (itemLabel: React.ReactNode, item: ItemDataType) => React.ReactNode;
17
- renderMenu?: (items: ItemDataType[], menu: React.ReactNode, parentNode?: ItemDataType, layer?: number) => React.ReactNode;
21
+ renderMenu?: (items: readonly ItemDataType[], menu: React.ReactNode, parentNode?: ItemDataType, layer?: number) => React.ReactNode;
18
22
  onSelect?: (node: ItemDataType, cascadePaths: ItemDataType[], isLeafNode: boolean, event: React.MouseEvent) => void;
19
23
  }
20
24
  declare const DropdownMenu: RsRefForwardingComponent<'div', DropdownMenuProps>;
@@ -55,12 +55,13 @@ var DropdownMenu = /*#__PURE__*/_react.default.forwardRef(function (props, ref)
55
55
  cascadeData = _props$cascadeData === void 0 ? emptyArray : _props$cascadeData,
56
56
  _props$cascadePaths = props.cascadePaths,
57
57
  cascadePaths = _props$cascadePaths === void 0 ? emptyArray : _props$cascadePaths,
58
+ loadingItemsSet = props.loadingItemsSet,
58
59
  _props$labelKey = props.labelKey,
59
60
  labelKey = _props$labelKey === void 0 ? 'label' : _props$labelKey,
60
61
  renderMenu = props.renderMenu,
61
62
  renderMenuItem = props.renderMenuItem,
62
63
  onSelect = props.onSelect,
63
- rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "activeItemValue", "classPrefix", "className", "childrenKey", "disabledItemValues", "menuWidth", "menuHeight", "valueKey", "cascadeData", "cascadePaths", "labelKey", "renderMenu", "renderMenuItem", "onSelect"]);
64
+ rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "activeItemValue", "classPrefix", "className", "childrenKey", "disabledItemValues", "menuWidth", "menuHeight", "valueKey", "cascadeData", "cascadePaths", "loadingItemsSet", "labelKey", "renderMenu", "renderMenuItem", "onSelect"]);
64
65
 
65
66
  var _useClassNames = (0, _utils.useClassNames)(classPrefix),
66
67
  merge = _useClassNames.merge,
@@ -114,15 +115,18 @@ var DropdownMenu = /*#__PURE__*/_react.default.forwardRef(function (props, ref)
114
115
  };
115
116
 
116
117
  var renderCascadeNode = function renderCascadeNode(node, index, layer, focus) {
118
+ var _loadingItemsSet$has;
119
+
117
120
  var children = node[childrenKey];
118
121
  var value = node[valueKey];
119
122
  var label = node[labelKey];
120
123
  var disabled = disabledItemValues.some(function (disabledValue) {
121
124
  return (0, _utils.shallowEqual)(disabledValue, value);
122
- }); // Use `value` in keys when If `value` is string or number
125
+ });
126
+ var loading = (_loadingItemsSet$has = loadingItemsSet === null || loadingItemsSet === void 0 ? void 0 : loadingItemsSet.has(node)) !== null && _loadingItemsSet$has !== void 0 ? _loadingItemsSet$has : false; // Use `value` in keys when If `value` is string or number
123
127
 
124
128
  var onlyKey = typeof value === 'number' || typeof value === 'string' ? value : index;
125
- var Icon = node.loading ? _Spinner.default : rtl ? _AngleLeft.default : _AngleRight.default;
129
+ var Icon = loading ? _Spinner.default : rtl ? _AngleLeft.default : _AngleRight.default;
126
130
  return /*#__PURE__*/_react.default.createElement(_Picker.DropdownMenuItem, {
127
131
  classPrefix: "picker-cascader-menu-item",
128
132
  as: 'li',
@@ -139,7 +143,7 @@ var DropdownMenu = /*#__PURE__*/_react.default.forwardRef(function (props, ref)
139
143
  }
140
144
  }, renderMenuItem ? renderMenuItem(label, node) : label, children ? /*#__PURE__*/_react.default.createElement(Icon, {
141
145
  className: prefix('caret'),
142
- spin: node.loading
146
+ spin: loading
143
147
  }) : null);
144
148
  };
145
149
 
@@ -1,23 +1,58 @@
1
- /// <reference types="react" />
2
- export declare function getColumnsAndPaths<T extends Record<string, unknown>>(data: T[], value: any, options: any): {
3
- columns: T[][];
4
- paths: T[];
1
+ declare type GetColumnsAndPathsOptions<T> = {
2
+ getParent: (item: T) => T | undefined;
3
+ getChildren: (item: T) => readonly T[] | undefined;
4
+ };
5
+ /**
6
+ * Calculate columns to be displayed:
7
+ *
8
+ * - Every ancestor level of activeItem should be displayed
9
+ * - The level that activeItem is at should be displayed
10
+ * - If activeItem is a parent node, its child level should be displayed
11
+ *
12
+ * @param items
13
+ * @param value
14
+ * @param options
15
+ * @returns
16
+ */
17
+ export declare function getColumnsAndPaths<T extends Record<string, unknown>>(items: readonly T[], pathTarget: T | undefined, options: GetColumnsAndPathsOptions<T>): {
18
+ columns: (readonly T[])[];
19
+ path: T[];
5
20
  };
6
21
  declare type UsePathsParams<T> = {
7
22
  data: T[];
8
- valueKey: string;
9
- childrenKey: string;
10
- value: unknown;
23
+ /**
24
+ * The item where the focus is on
25
+ */
26
+ activeItem: T | undefined;
27
+ /**
28
+ * The item selected by Cascader's value
29
+ */
30
+ selectedItem: T | undefined;
31
+ getParent: (item: T) => T | undefined;
32
+ getChildren: (item: T) => readonly T[] | undefined;
11
33
  };
12
- export declare function usePaths<T extends Record<string, unknown>>(params: UsePathsParams<T>): {
13
- enforceUpdate: (nextValue: any, isAttachChildren?: boolean) => void;
14
- columnData: T[][];
15
- valueToPaths: T[];
16
- selectedPaths: T[];
17
- setValueToPaths: import("react").Dispatch<import("react").SetStateAction<T[]>>;
18
- setColumnData: import("react").Dispatch<import("react").SetStateAction<T[][]>>;
19
- setSelectedPaths: import("react").Dispatch<import("react").SetStateAction<T[]>>;
20
- addColumn: (column: T[], index: number) => void;
21
- removeColumnByIndex: (index: number) => void;
34
+ /**
35
+ * Caculate following 3 things
36
+ *
37
+ * - The columns of items to be displayed
38
+ * - The path towards the current focused item
39
+ * - The path towards the current selected item (referred to by Cascader's value)
40
+ *
41
+ * @param params
42
+ * @returns
43
+ */
44
+ export declare function usePaths<T extends Record<string, unknown>>({ data, activeItem, selectedItem, getParent, getChildren }: UsePathsParams<T>): {
45
+ columnsToDisplay: (readonly T[])[];
46
+ pathTowardsSelectedItem: T[];
47
+ pathTowardsActiveItem: T[];
22
48
  };
49
+ /**
50
+ * Returns a WeakMap that maps each item in `items` to its parent
51
+ * indicated by `getChildren` function
52
+ */
53
+ export declare function getParentMap<T extends Record<string, unknown>>(items: readonly T[], getChildren: (item: T) => readonly T[] | undefined): WeakMap<T, T>;
54
+ /**
55
+ * Returns an array indicating the hirearchy path from root towards `target` item
56
+ */
57
+ export declare function getPathTowardsItem<T>(target: T | undefined, getParent: (item: T) => T | undefined): T[];
23
58
  export {};