rsuite 5.32.0 → 5.33.1

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 (50) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/cjs/Carousel/Carousel.js +12 -2
  3. package/cjs/Cascader/Cascader.js +2 -2
  4. package/cjs/Cascader/utils.d.ts +0 -9
  5. package/cjs/Cascader/utils.js +2 -48
  6. package/cjs/CheckPicker/CheckPicker.js +6 -2
  7. package/cjs/CheckTreePicker/CheckTreePicker.js +16 -3
  8. package/cjs/DatePicker/DatePicker.js +1 -1
  9. package/cjs/InputPicker/InputPicker.js +7 -2
  10. package/cjs/MultiCascader/MultiCascader.js +1 -0
  11. package/cjs/Picker/DropdownMenu.d.ts +1 -0
  12. package/cjs/Picker/DropdownMenu.js +19 -6
  13. package/cjs/Picker/utils.d.ts +2 -0
  14. package/cjs/Picker/utils.js +8 -1
  15. package/cjs/SelectPicker/SelectPicker.js +7 -2
  16. package/cjs/Tree/Tree.d.ts +2 -0
  17. package/cjs/TreePicker/TreePicker.js +16 -3
  18. package/cjs/utils/getDataGroupBy.d.ts +4 -1
  19. package/cjs/utils/getDataGroupBy.js +12 -24
  20. package/cjs/utils/index.d.ts +0 -1
  21. package/cjs/utils/index.js +1 -6
  22. package/cjs/utils/treeUtils.d.ts +25 -1
  23. package/cjs/utils/treeUtils.js +121 -9
  24. package/dist/rsuite.js +61 -21
  25. package/dist/rsuite.js.map +1 -1
  26. package/dist/rsuite.min.js +1 -1
  27. package/dist/rsuite.min.js.map +1 -1
  28. package/esm/Carousel/Carousel.js +13 -3
  29. package/esm/Cascader/Cascader.js +2 -2
  30. package/esm/Cascader/utils.d.ts +0 -9
  31. package/esm/Cascader/utils.js +1 -44
  32. package/esm/CheckPicker/CheckPicker.js +5 -2
  33. package/esm/CheckTreePicker/CheckTreePicker.js +17 -4
  34. package/esm/DatePicker/DatePicker.js +1 -1
  35. package/esm/InputPicker/InputPicker.js +6 -2
  36. package/esm/MultiCascader/MultiCascader.js +1 -0
  37. package/esm/Picker/DropdownMenu.d.ts +1 -0
  38. package/esm/Picker/DropdownMenu.js +17 -5
  39. package/esm/Picker/utils.d.ts +2 -0
  40. package/esm/Picker/utils.js +8 -1
  41. package/esm/SelectPicker/SelectPicker.js +6 -2
  42. package/esm/Tree/Tree.d.ts +2 -0
  43. package/esm/TreePicker/TreePicker.js +18 -5
  44. package/esm/utils/getDataGroupBy.d.ts +4 -1
  45. package/esm/utils/getDataGroupBy.js +13 -24
  46. package/esm/utils/index.d.ts +0 -1
  47. package/esm/utils/index.js +0 -1
  48. package/esm/utils/treeUtils.d.ts +25 -1
  49. package/esm/utils/treeUtils.js +111 -10
  50. package/package.json +3 -3
@@ -3,7 +3,7 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
3
3
  import React, { useState, useMemo, useCallback, useRef } from 'react';
4
4
  import PropTypes from 'prop-types';
5
5
  import classNames from 'classnames';
6
- import { useClassNames, useCustom, guid, ReactChildren, useTimeout, mergeRefs, useControlled } from '../utils';
6
+ import { useClassNames, useCustom, guid, ReactChildren, useTimeout, mergeRefs, useControlled, useUpdateEffect } from '../utils';
7
7
  var Carousel = /*#__PURE__*/React.forwardRef(function (props, ref) {
8
8
  var _sliderStyles, _ref;
9
9
 
@@ -43,13 +43,23 @@ var Carousel = /*#__PURE__*/React.forwardRef(function (props, ref) {
43
43
 
44
44
  var _useControlled = useControlled(activeIndexProp, defaultActiveIndex),
45
45
  activeIndex = _useControlled[0],
46
- setActiveIndex = _useControlled[1];
46
+ setActiveIndex = _useControlled[1],
47
+ isControlled = _useControlled[2];
47
48
 
48
49
  var _useState = useState(0),
49
50
  lastIndex = _useState[0],
50
51
  setLastIndex = _useState[1];
51
52
 
52
- var rootRef = useRef(null); // Set a timer for automatic playback.
53
+ var rootRef = useRef(null);
54
+ useUpdateEffect(function () {
55
+ // When the index is controlled, the index is not updated when the number of children changes.
56
+ if (isControlled) {
57
+ return;
58
+ } // Reset the index when the number of children changes.
59
+
60
+
61
+ setActiveIndex(0);
62
+ }, [children, isControlled]); // Set a timer for automatic playback.
53
63
  // `autoplay` needs to be cast to boolean type to avoid undefined parameters.
54
64
 
55
65
  var _useTimeout = useTimeout(function () {
@@ -9,8 +9,8 @@ import isNil from 'lodash/isNil';
9
9
  import isFunction from 'lodash/isFunction';
10
10
  import shallowEqual from '../utils/shallowEqual';
11
11
  import DropdownMenu from './DropdownMenu';
12
- import { findNodeOfTree, flattenTree } from '../utils/treeUtils';
13
- import { getParentMap, getPathTowardsItem, usePaths } from './utils';
12
+ import { getParentMap, getPathTowardsItem, findNodeOfTree, flattenTree } from '../utils/treeUtils';
13
+ import { usePaths } from './utils';
14
14
  import { getSafeRegExpString, createChainedFunction, mergeRefs, useControlled, useCustom, useClassNames, useIsMounted } from '../utils';
15
15
  import { PickerToggle, PickerOverlay, SearchBar, PickerToggleTrigger, usePickerClassName, usePublicMethods, useToggleKeyDownEvent, useFocusItemValue, pickTriggerPropKeys, omitTriggerPropKeys, listPickerPropTypes } from '../Picker';
16
16
  import { useMap } from '../utils/useMap';
@@ -46,13 +46,4 @@ export declare function usePaths<T extends Record<string, unknown>>({ data, acti
46
46
  pathTowardsSelectedItem: T[];
47
47
  pathTowardsActiveItem: T[];
48
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[];
58
49
  export {};
@@ -1,10 +1,5 @@
1
- function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
2
-
3
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
-
5
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
6
-
7
1
  import { useMemo } from 'react';
2
+ import { getPathTowardsItem } from '../utils/treeUtils';
8
3
 
9
4
  /**
10
5
  * Calculate columns to be displayed:
@@ -85,42 +80,4 @@ export function usePaths(_ref) {
85
80
  pathTowardsSelectedItem: pathTowardsSelectedItem,
86
81
  pathTowardsActiveItem: pathTowardsActiveItem
87
82
  };
88
- }
89
- /**
90
- * Returns a WeakMap that maps each item in `items` to its parent
91
- * indicated by `getChildren` function
92
- */
93
-
94
- export function getParentMap(items, getChildren) {
95
- var map = new WeakMap();
96
-
97
- for (var queue = [].concat(items); queue.length > 0;) {
98
- var _item = queue.shift();
99
-
100
- var children = getChildren(_item);
101
-
102
- if (children) {
103
- for (var _iterator = _createForOfIteratorHelperLoose(children), _step; !(_step = _iterator()).done;) {
104
- var child = _step.value;
105
- map.set(child, _item);
106
- queue.push(child);
107
- }
108
- }
109
- }
110
-
111
- return map;
112
- }
113
- /**
114
- * Returns an array indicating the hirearchy path from root towards `target` item
115
- */
116
-
117
- export function getPathTowardsItem(target, getParent) {
118
- if (!target) return [];
119
- var path = [target];
120
-
121
- for (var parent = getParent(target); !!parent; parent = getParent(parent)) {
122
- path.unshift(parent);
123
- }
124
-
125
- return path;
126
83
  }
@@ -14,7 +14,8 @@ import omit from 'lodash/omit';
14
14
  import pick from 'lodash/pick';
15
15
  import isNil from 'lodash/isNil';
16
16
  import { filterNodesOfTree } from '../utils/treeUtils';
17
- import { createChainedFunction, getDataGroupBy, useClassNames, shallowEqual, useCustom, useControlled, mergeRefs } from '../utils';
17
+ import { createChainedFunction, useClassNames, shallowEqual, useCustom, useControlled, mergeRefs } from '../utils';
18
+ import { getDataGroupBy } from '../utils/getDataGroupBy';
18
19
  import { DropdownMenu, DropdownMenuCheckItem as DropdownMenuItem, PickerToggle, PickerOverlay, SearchBar, SelectedElement, PickerToggleTrigger, useFocusItemValue, usePickerClassName, useSearch, usePublicMethods, useToggleKeyDownEvent, pickTriggerPropKeys, omitTriggerPropKeys, listPickerPropTypes } from '../Picker';
19
20
  var emptyArray = [];
20
21
  var CheckPicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
@@ -321,8 +322,10 @@ var CheckPicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
321
322
  dropdownMenuItemAs: DropdownMenuItem,
322
323
  activeItemValues: value,
323
324
  focusItemValue: focusItemValue,
324
- data: [].concat(filteredStickyItems, items),
325
+ data: [].concat(filteredStickyItems, items) // `group` is redundant so long as `groupBy` exists
326
+ ,
325
327
  group: !isUndefined(groupBy),
328
+ groupBy: groupBy,
326
329
  onSelect: handleItemSelect,
327
330
  onGroupTitleClick: onGroupTitleClick,
328
331
  virtualized: virtualized
@@ -12,7 +12,7 @@ import classNames from 'classnames';
12
12
  import { List, AutoSizer } from '../Windowing';
13
13
  import CheckTreeNode from './CheckTreeNode';
14
14
  import TreeContext from '../Tree/TreeContext';
15
- import { getTreeNodeIndent } from '../utils/treeUtils';
15
+ import { getKeyParentMap, getPathTowardsItem, getTreeNodeIndent } from '../utils/treeUtils';
16
16
  import { createChainedFunction, useCustom, useClassNames, useControlled, KEY_VALUES, mergeRefs } from '../utils';
17
17
  import { PickerToggle, onMenuKeyDown as _onMenuKeyDown, PickerOverlay, SearchBar, SelectedElement, PickerToggleTrigger, createConcatChildrenFunction, usePickerClassName, usePublicMethods, pickTriggerPropKeys, omitTriggerPropKeys, listPickerPropTypes, useToggleKeyDownEvent } from '../Picker';
18
18
  import { isEveryChildChecked, isSomeNodeHasChildren, isAllSiblingNodeUncheckable, isEveryFirstLevelNodeUncheckable, getFormattedTree, getDisabledState, getCheckTreePickerDefaultValue, getSelectedItems, isNodeUncheckable } from './utils';
@@ -91,13 +91,14 @@ var CheckTreePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
91
91
  onExited = props.onExited,
92
92
  onSearch = props.onSearch,
93
93
  onSelect = props.onSelect,
94
+ onSelectItem = props.onSelectItem,
94
95
  onOpen = props.onOpen,
95
96
  onScroll = props.onScroll,
96
97
  onExpand = props.onExpand,
97
98
  renderValue = props.renderValue,
98
99
  renderTreeIcon = props.renderTreeIcon,
99
100
  renderTreeNode = props.renderTreeNode,
100
- rest = _objectWithoutPropertiesLoose(props, ["as", "data", "style", "appearance", "cleanable", "countable", "searchBy", "toggleAs", "searchKeyword", "showIndentLine", "locale", "cascade", "disabled", "valueKey", "labelKey", "placement", "childrenKey", "placeholder", "value", "defaultValue", "defaultExpandAll", "disabledItemValues", "expandItemValues", "defaultExpandItemValues", "height", "menuMaxHeight", "menuStyle", "searchable", "virtualized", "className", "classPrefix", "menuClassName", "menuAutoWidth", "uncheckableItemValues", "id", "listProps", "renderMenu", "getChildren", "renderExtraFooter", "onEntered", "onChange", "onClean", "onClose", "onExited", "onSearch", "onSelect", "onOpen", "onScroll", "onExpand", "renderValue", "renderTreeIcon", "renderTreeNode"]);
101
+ rest = _objectWithoutPropertiesLoose(props, ["as", "data", "style", "appearance", "cleanable", "countable", "searchBy", "toggleAs", "searchKeyword", "showIndentLine", "locale", "cascade", "disabled", "valueKey", "labelKey", "placement", "childrenKey", "placeholder", "value", "defaultValue", "defaultExpandAll", "disabledItemValues", "expandItemValues", "defaultExpandItemValues", "height", "menuMaxHeight", "menuStyle", "searchable", "virtualized", "className", "classPrefix", "menuClassName", "menuAutoWidth", "uncheckableItemValues", "id", "listProps", "renderMenu", "getChildren", "renderExtraFooter", "onEntered", "onChange", "onClean", "onClose", "onExited", "onSearch", "onSelect", "onSelectItem", "onOpen", "onScroll", "onExpand", "renderValue", "renderTreeIcon", "renderTreeNode"]);
101
102
 
102
103
  var _useContext = useContext(TreeContext),
103
104
  inline = _useContext.inline;
@@ -343,7 +344,16 @@ var CheckTreePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
343
344
  return values.filter(function (v) {
344
345
  return !uncheckableItemValues.includes(v);
345
346
  });
346
- }, [flattenNodes, uncheckableItemValues, serializeListOnlyParent, toggleDownChecked, toggleUpChecked]);
347
+ }, [flattenNodes, uncheckableItemValues, serializeListOnlyParent, toggleDownChecked, toggleUpChecked]); // TODO-Doma
348
+ // Replace `getKeyParentMap` with `getParentMap`
349
+
350
+ var itemParentMap = useMemo(function () {
351
+ return getKeyParentMap(data, function (node) {
352
+ return node[valueKey];
353
+ }, function (node) {
354
+ return node[childrenKey];
355
+ });
356
+ }, [childrenKey, data, valueKey]);
347
357
  var handleSelect = useCallback(function (node, event) {
348
358
  var currentNode = node.refKey ? flattenNodes[node.refKey] : null;
349
359
 
@@ -368,7 +378,10 @@ var CheckTreePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
368
378
  setFocusItemValue(node[valueKey]);
369
379
  onChange === null || onChange === void 0 ? void 0 : onChange(selectedValues, event);
370
380
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(node, selectedValues, event);
371
- }, [cascade, valueKey, flattenNodes, isControlled, uncheckableItemValues, setValue, onChange, onSelect, toggleChecked, unSerializeList]);
381
+ onSelectItem === null || onSelectItem === void 0 ? void 0 : onSelectItem(node, getPathTowardsItem(node, function (item) {
382
+ return itemParentMap.get(item[valueKey]);
383
+ }));
384
+ }, [flattenNodes, toggleChecked, isControlled, valueKey, onChange, onSelect, onSelectItem, unSerializeList, cascade, uncheckableItemValues, setValue, itemParentMap]);
372
385
  var handleOpen = useCallback(function () {
373
386
  var _triggerRef$current, _triggerRef$current$o;
374
387
 
@@ -89,7 +89,7 @@ var DatePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
89
89
  value = _useControlled[0],
90
90
  setValue = _useControlled[1];
91
91
 
92
- var _useCalendarDate = useCalendarDate(valueProp, calendarDefaultDate),
92
+ var _useCalendarDate = useCalendarDate(value, calendarDefaultDate),
93
93
  calendarDate = _useCalendarDate.calendarDate,
94
94
  setCalendarDate = _useCalendarDate.setCalendarDate,
95
95
  resetCalendarDate = _useCalendarDate.resetCalendarDate;
@@ -18,7 +18,8 @@ import getWidth from 'dom-lib/getWidth';
18
18
  import shallowEqual from '../utils/shallowEqual';
19
19
  import { filterNodesOfTree } from '../utils/treeUtils';
20
20
  import Plaintext from '../Plaintext';
21
- import { createChainedFunction, tplTransform, getDataGroupBy, useClassNames, useCustom, useControlled, mergeRefs, isOneOf, KEY_VALUES } from '../utils';
21
+ import { createChainedFunction, tplTransform, useClassNames, useCustom, useControlled, mergeRefs, isOneOf, KEY_VALUES } from '../utils';
22
+ import { getDataGroupBy } from '../utils/getDataGroupBy';
22
23
  import { DropdownMenu, DropdownMenuItem, DropdownMenuCheckItem, PickerToggle, PickerOverlay, PickerToggleTrigger, useFocusItemValue, usePickerClassName, useSearch, usePublicMethods, useToggleKeyDownEvent, pickTriggerPropKeys, omitTriggerPropKeys, listPickerPropTypes } from '../Picker';
23
24
  import Tag from '../Tag';
24
25
  import InputAutosize from './InputAutosize';
@@ -623,8 +624,11 @@ var InputPicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
623
624
  activeItemValues: multi ? value : [value],
624
625
  focusItemValue: focusItemValue,
625
626
  maxHeight: menuMaxHeight,
626
- data: items,
627
+ data: items // FIXME-Doma
628
+ // `group` is redundant so long as `groupBy` exists
629
+ ,
627
630
  group: !isUndefined(groupBy),
631
+ groupBy: groupBy,
628
632
  onSelect: multi ? handleCheckTag : handleSelectItem // fixme don't use any
629
633
  ,
630
634
  renderMenuGroup: renderMenuGroup,
@@ -225,6 +225,7 @@ var MultiCascader = /*#__PURE__*/React.forwardRef(function (props, ref) {
225
225
  (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 ? void 0 : (_triggerRef$current$u = _triggerRef$current.updatePosition) === null || _triggerRef$current$u === void 0 ? void 0 : _triggerRef$current$u.call(_triggerRef$current);
226
226
  }, [onSelect, getChildren, childrenKey, inline, addFlattenData, addColumn, removeColumnByIndex]);
227
227
  var handleCheck = useCallback(function (node, event, checked) {
228
+ console.log('handleCheck');
228
229
  var nodeValue = node[valueKey];
229
230
  var nextValue = [];
230
231
 
@@ -6,6 +6,7 @@ export interface DropdownMenuProps<Multiple = false> extends StandardProps, Omit
6
6
  classPrefix: string;
7
7
  data?: ItemDataType[];
8
8
  group?: boolean;
9
+ groupBy?: string;
9
10
  disabledItemValues?: any[];
10
11
  activeItemValues?: any[];
11
12
  focusItemValue?: any;
@@ -1,5 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ import _get from "lodash/get";
3
4
 
4
5
  var _this = this;
5
6
 
@@ -22,6 +23,7 @@ var DropdownMenu = /*#__PURE__*/React.forwardRef(function (props, ref) {
22
23
  var _props$data = props.data,
23
24
  data = _props$data === void 0 ? [] : _props$data,
24
25
  group = props.group,
26
+ groupBy = props.groupBy,
25
27
  _props$maxHeight = props.maxHeight,
26
28
  maxHeight = _props$maxHeight === void 0 ? 320 : _props$maxHeight,
27
29
  _props$activeItemValu = props.activeItemValues,
@@ -50,7 +52,7 @@ var DropdownMenu = /*#__PURE__*/React.forwardRef(function (props, ref) {
50
52
  renderMenuItem = props.renderMenuItem,
51
53
  onGroupTitleClick = props.onGroupTitleClick,
52
54
  onSelect = props.onSelect,
53
- rest = _objectWithoutPropertiesLoose(props, ["data", "group", "maxHeight", "activeItemValues", "disabledItemValues", "classPrefix", "valueKey", "labelKey", "virtualized", "listProps", "listRef", "className", "style", "focusItemValue", "dropdownMenuItemClassPrefix", "dropdownMenuItemAs", "rowHeight", "rowGroupHeight", "renderMenuGroup", "renderMenuItem", "onGroupTitleClick", "onSelect"]);
55
+ rest = _objectWithoutPropertiesLoose(props, ["data", "group", "groupBy", "maxHeight", "activeItemValues", "disabledItemValues", "classPrefix", "valueKey", "labelKey", "virtualized", "listProps", "listRef", "className", "style", "focusItemValue", "dropdownMenuItemClassPrefix", "dropdownMenuItemAs", "rowHeight", "rowGroupHeight", "renderMenuGroup", "renderMenuItem", "onGroupTitleClick", "onSelect"]);
54
56
 
55
57
  var _useClassNames = useClassNames(classPrefix),
56
58
  withClassPrefix = _useClassNames.withClassPrefix,
@@ -180,11 +182,21 @@ var DropdownMenu = /*#__PURE__*/React.forwardRef(function (props, ref) {
180
182
  };
181
183
 
182
184
  var filteredItems = group ? data.filter(function (item) {
183
- return !(foldedGroupKeys !== null && foldedGroupKeys !== void 0 && foldedGroupKeys.some(function (key) {
184
- var _item$parent;
185
+ var _item$parent;
185
186
 
186
- return key === ((_item$parent = item.parent) === null || _item$parent === void 0 ? void 0 : _item$parent[KEY_GROUP_TITLE]);
187
- }));
187
+ // Display group title items
188
+ if (item[KEY_GROUP]) return true; // Display items under the unfolded group
189
+ // FIXME-Doma
190
+ // `groupBy` is bound to be string when `group` is true
191
+ // because `group` is actually redundant as a prop
192
+ // It could simply be derived from `groupBy` value
193
+
194
+ var groupValue = _get(item, groupBy, '') || ( // FIXME-Doma
195
+ // Usage of `item.parent` is strongly discouraged
196
+ // It's only here for legacy support
197
+ // Remove once `item.parent` is completely removed across related components
198
+ (_item$parent = item.parent) === null || _item$parent === void 0 ? void 0 : _item$parent[KEY_GROUP_TITLE]);
199
+ return !foldedGroupKeys.includes(groupValue);
188
200
  }) : data;
189
201
  var rowCount = filteredItems.length;
190
202
  useMount(function () {
@@ -73,6 +73,8 @@ export interface ToggleKeyDownEventProps {
73
73
  overlayRef?: React.RefObject<any>;
74
74
  searchInputRef?: React.RefObject<any>;
75
75
  active?: boolean;
76
+ readOnly?: boolean;
77
+ disabled?: boolean;
76
78
  onExit?: (event: any) => void;
77
79
  onKeyDown?: (event: any) => void;
78
80
  onOpen?: () => void;
@@ -403,6 +403,8 @@ export var useToggleKeyDownEvent = function useToggleKeyDownEvent(props) {
403
403
  overlayRef = props.overlayRef,
404
404
  searchInputRef = props.searchInputRef,
405
405
  active = props.active,
406
+ readOnly = props.readOnly,
407
+ disabled = props.disabled,
406
408
  onExit = props.onExit,
407
409
  onOpen = props.onOpen,
408
410
  onClose = props.onClose,
@@ -431,6 +433,11 @@ export var useToggleKeyDownEvent = function useToggleKeyDownEvent(props) {
431
433
  handleOpen();
432
434
  }, [active, handleOpen, handleClose]);
433
435
  var onToggle = useCallback(function (event) {
436
+ // Keyboard events should not be processed when readOnly and disabled are set.
437
+ if (readOnly || disabled) {
438
+ return;
439
+ }
440
+
434
441
  if (event.target === (targetRef === null || targetRef === void 0 ? void 0 : targetRef.current)) {
435
442
  // enter
436
443
  if (toggle && event.key === KEY_VALUES.ENTER) {
@@ -480,7 +487,7 @@ export var useToggleKeyDownEvent = function useToggleKeyDownEvent(props) {
480
487
 
481
488
 
482
489
  onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
483
- }, [handleClose, handleToggleDropdown, overlayRef, onExit, onKeyDown, onMenuKeyDown, onMenuPressBackspace, onMenuPressEnter, toggle, targetRef, searchInputRef]);
490
+ }, [readOnly, disabled, targetRef, overlayRef, onKeyDown, toggle, handleToggleDropdown, onExit, onMenuKeyDown, searchInputRef, onMenuPressEnter, onMenuPressBackspace, handleClose]);
484
491
  return onToggle;
485
492
  };
486
493
 
@@ -11,7 +11,8 @@ import isUndefined from 'lodash/isUndefined';
11
11
  import isNil from 'lodash/isNil';
12
12
  import isFunction from 'lodash/isFunction';
13
13
  import omit from 'lodash/omit';
14
- import { createChainedFunction, getDataGroupBy, useCustom, useClassNames, useControlled, mergeRefs, shallowEqual } from '../utils';
14
+ import { createChainedFunction, useCustom, useClassNames, useControlled, mergeRefs, shallowEqual } from '../utils';
15
+ import { getDataGroupBy } from '../utils/getDataGroupBy';
15
16
  import { DropdownMenu, DropdownMenuItem, PickerToggle, PickerToggleTrigger, PickerOverlay, SearchBar, useFocusItemValue, usePickerClassName, useSearch, usePublicMethods, useToggleKeyDownEvent, pickTriggerPropKeys, omitTriggerPropKeys, listPickerPropTypes } from '../Picker';
16
17
  var emptyArray = [];
17
18
  var SelectPicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
@@ -260,8 +261,11 @@ var SelectPicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
260
261
  dropdownMenuItemAs: DropdownMenuItem,
261
262
  activeItemValues: [value],
262
263
  focusItemValue: focusItemValue,
263
- data: items,
264
+ data: items // FIXME-Doma
265
+ // `group` is redundant so long as `groupBy` exists
266
+ ,
264
267
  group: !isUndefined(groupBy),
268
+ groupBy: groupBy,
265
269
  onSelect: handleItemSelect,
266
270
  onGroupTitleClick: onGroupTitleClick,
267
271
  virtualized: virtualized
@@ -60,6 +60,8 @@ export interface TreeBaseProps<ValueType = string | number, ItemDataType = Recor
60
60
  onExpand?: (expandItemValues: ItemDataType[], activeNode: ItemDataType, concat: (data: ItemDataType[], children: ItemDataType[]) => ItemDataType[]) => void;
61
61
  /** Callback function after selecting tree node */
62
62
  onSelect?: (activeNode: ItemDataType, value: ValueType, event: React.SyntheticEvent) => void;
63
+ /** Callback when a tree item is clicked */
64
+ onSelectItem?: (item: ItemDataType, path: ItemDataType[]) => void;
63
65
  /** Custom Render tree Node */
64
66
  renderTreeNode?: (nodeData: ItemDataType) => React.ReactNode;
65
67
  /** Custom Render icon */
@@ -5,11 +5,11 @@ import _isNil from "lodash/isNil";
5
5
  import _isUndefined from "lodash/isUndefined";
6
6
  import _omit from "lodash/omit";
7
7
  import _pick from "lodash/pick";
8
- import React, { useState, useRef, useEffect, useCallback, useContext } from 'react';
8
+ import React, { useState, useRef, useEffect, useCallback, useContext, useMemo } from 'react';
9
9
  import PropTypes from 'prop-types';
10
10
  import { List, AutoSizer } from '../Windowing';
11
11
  import TreeNode from './TreeNode';
12
- import { createDragPreview, getTreeNodeIndent, removeDragPreview, stringifyTreeNodeLabel } from '../utils/treeUtils';
12
+ import { createDragPreview, getKeyParentMap, getPathTowardsItem, getTreeNodeIndent, removeDragPreview, stringifyTreeNodeLabel } from '../utils/treeUtils';
13
13
  import { createChainedFunction, useClassNames, useCustom, useControlled, TREE_NODE_DROP_POSITION, KEY_VALUES, mergeRefs, shallowEqual } from '../utils';
14
14
  import { getExpandWhenSearching, hasVisibleChildren, getDragNodeKeys, calDropNodePosition, createUpdateTreeDataFunction, useTreeDrag, useFlattenTreeData, getTreeActiveNode, getDefaultExpandItemValues, useTreeNodeRefs, useTreeSearch, focusPreviousItem, getFocusableItems, focusNextItem, getActiveItem, toggleExpand, useGetTreeNodeChildren, focusToActiveTreeNode, leftArrowHandler, focusTreeNode, rightArrowHandler, isSearching } from '../utils/treeUtils';
15
15
  import { PickerToggle, PickerOverlay, SearchBar, PickerToggleTrigger, createConcatChildrenFunction, usePickerClassName, onMenuKeyDown as _onMenuKeyDown, usePublicMethods, listPickerPropTypes, pickTriggerPropKeys, omitTriggerPropKeys, useToggleKeyDownEvent } from '../Picker';
@@ -81,6 +81,7 @@ var TreePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
81
81
  onOpen = props.onOpen,
82
82
  onSearch = props.onSearch,
83
83
  onSelect = props.onSelect,
84
+ onSelectItem = props.onSelectItem,
84
85
  onChange = props.onChange,
85
86
  onEntered = props.onEntered,
86
87
  onClose = props.onClose,
@@ -94,7 +95,7 @@ var TreePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
94
95
  renderExtraFooter = props.renderExtraFooter,
95
96
  renderMenu = props.renderMenu,
96
97
  renderValue = props.renderValue,
97
- rest = _objectWithoutPropertiesLoose(props, ["as", "data", "appearance", "style", "showIndentLine", "value", "locale", "height", "menuMaxHeight", "menuStyle", "className", "disabled", "placement", "cleanable", "searchable", "virtualized", "classPrefix", "defaultValue", "placeholder", "searchKeyword", "menuClassName", "menuAutoWidth", "searchBy", "toggleAs", "labelKey", "valueKey", "childrenKey", "draggable", "defaultExpandAll", "disabledItemValues", "expandItemValues", "defaultExpandItemValues", "id", "listProps", "getChildren", "renderTreeIcon", "renderTreeNode", "onExit", "onExited", "onClean", "onOpen", "onSearch", "onSelect", "onChange", "onEntered", "onClose", "onDragEnd", "onDragStart", "onDragEnter", "onDragLeave", "onDragOver", "onDrop", "onExpand", "renderExtraFooter", "renderMenu", "renderValue"]);
98
+ rest = _objectWithoutPropertiesLoose(props, ["as", "data", "appearance", "style", "showIndentLine", "value", "locale", "height", "menuMaxHeight", "menuStyle", "className", "disabled", "placement", "cleanable", "searchable", "virtualized", "classPrefix", "defaultValue", "placeholder", "searchKeyword", "menuClassName", "menuAutoWidth", "searchBy", "toggleAs", "labelKey", "valueKey", "childrenKey", "draggable", "defaultExpandAll", "disabledItemValues", "expandItemValues", "defaultExpandItemValues", "id", "listProps", "getChildren", "renderTreeIcon", "renderTreeNode", "onExit", "onExited", "onClean", "onOpen", "onSearch", "onSelect", "onSelectItem", "onChange", "onEntered", "onClose", "onDragEnd", "onDragStart", "onDragEnter", "onDragLeave", "onDragOver", "onDrop", "onExpand", "renderExtraFooter", "renderMenu", "renderValue"]);
98
99
 
99
100
  var triggerRef = useRef(null);
100
101
  var targetRef = useRef(null);
@@ -291,8 +292,17 @@ var TreePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
291
292
  onRenderTreeNode: renderTreeNode,
292
293
  onRenderTreeIcon: renderTreeIcon
293
294
  };
294
- };
295
+ }; // TODO-Doma
296
+ // Replace `getKeyParentMap` with `getParentMap`
297
+
295
298
 
299
+ var itemParentMap = useMemo(function () {
300
+ return getKeyParentMap(data, function (node) {
301
+ return node[valueKey];
302
+ }, function (node) {
303
+ return node[childrenKey];
304
+ });
305
+ }, [childrenKey, data, valueKey]);
296
306
  var handleSelect = useCallback(function (nodeData, event) {
297
307
  var _targetRef$current, _triggerRef$current, _triggerRef$current$c;
298
308
 
@@ -309,9 +319,12 @@ var TreePicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
309
319
  setFocusItemValue(nodeData[valueKey]);
310
320
  onChange === null || onChange === void 0 ? void 0 : onChange(nodeValue, event);
311
321
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(nodeData, nodeValue, event);
322
+ onSelectItem === null || onSelectItem === void 0 ? void 0 : onSelectItem(nodeData, getPathTowardsItem(nodeData, function (item) {
323
+ return itemParentMap.get(item[valueKey]);
324
+ }));
312
325
  (_targetRef$current = targetRef.current) === null || _targetRef$current === void 0 ? void 0 : _targetRef$current.focus();
313
326
  (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 ? void 0 : (_triggerRef$current$c = _triggerRef$current.close) === null || _triggerRef$current$c === void 0 ? void 0 : _triggerRef$current$c.call(_triggerRef$current);
314
- }, [valueKey, isControlled, onChange, onSelect, setValue]);
327
+ }, [valueKey, isControlled, onChange, onSelect, onSelectItem, setValue, itemParentMap]);
315
328
  var handleExpand = useCallback(function (node) {
316
329
  var nextExpandItemValues = toggleExpand({
317
330
  node: node,
@@ -1,3 +1,6 @@
1
1
  export declare const KEY_GROUP: string | symbol;
2
2
  export declare const KEY_GROUP_TITLE = "groupTitle";
3
- export default function getDataGroupBy(data: any[] | undefined, key: string, sort?: any): any[];
3
+ export declare function getDataGroupBy<T>(data: readonly T[], key: string, sort?: (isGroup: boolean) => <T>(a: T, b: T) => number): (T | {
4
+ groupTitle: string;
5
+ children: T[];
6
+ })[];
@@ -1,29 +1,13 @@
1
- import _get from "lodash/get";
2
- import { UNSAFE_flattenTree } from '../utils/treeUtils';
1
+ import _groupBy from "lodash/groupBy";
2
+ import { WalkTreeStrategy, flattenTree } from '../utils/treeUtils';
3
3
  var hasSymbol = typeof Symbol === 'function';
4
4
  export var KEY_GROUP = hasSymbol ? Symbol('_$grouped') : '_$grouped';
5
5
  export var KEY_GROUP_TITLE = 'groupTitle';
6
- export default function getDataGroupBy(data, key, sort) {
7
- if (data === void 0) {
8
- data = [];
9
- }
6
+ export function getDataGroupBy(data, key, sort) {
7
+ var groupMap = _groupBy(data, key);
10
8
 
11
- var tempData = {};
12
9
  var isSort = typeof sort === 'function';
13
- data.forEach(function (item) {
14
- // this will allow getting data using dot notation
15
- // i.e groupBy="country.name" as country will be a nested object
16
- // to the item and the name will be nested key to the country object
17
- // can be used with values in arrays, i.e groupBy="addresses.0.country.name"
18
- var groupByValue = _get(item, key, '');
19
-
20
- if (!tempData[groupByValue]) {
21
- tempData[groupByValue] = [];
22
- }
23
-
24
- tempData[groupByValue].push(item);
25
- });
26
- var nextData = Object.entries(tempData).map(function (_ref) {
10
+ var groups = Object.entries(groupMap).map(function (_ref) {
27
11
  var _ref2;
28
12
 
29
13
  var groupTitle = _ref[0],
@@ -34,8 +18,13 @@ export default function getDataGroupBy(data, key, sort) {
34
18
  });
35
19
 
36
20
  if (isSort) {
37
- nextData = nextData.sort(sort(true));
38
- }
21
+ groups.sort(sort(true));
22
+ } // Use DFS traverse
23
+ // Because I want the result to be [group, child, child, group, child, child]
24
+ // rather than [group, group, child, child, child, child]
25
+
39
26
 
40
- return UNSAFE_flattenTree(nextData);
27
+ return flattenTree(groups, function (group) {
28
+ return group.children;
29
+ }, WalkTreeStrategy.DFS);
41
30
  }
@@ -12,7 +12,6 @@ export { default as ReactChildren } from './ReactChildren';
12
12
  export { default as tplTransform } from './tplTransform';
13
13
  export { default as ajaxUpload } from './ajaxUpload';
14
14
  export { default as previewFile } from './previewFile';
15
- export { default as getDataGroupBy } from './getDataGroupBy';
16
15
  export { default as clone } from './clone';
17
16
  export { default as placementPolyfill } from './placementPolyfill';
18
17
  export { default as getDOMNode } from './getDOMNode';
@@ -14,7 +14,6 @@ export { default as ReactChildren } from './ReactChildren';
14
14
  export { default as tplTransform } from './tplTransform';
15
15
  export { default as ajaxUpload } from './ajaxUpload';
16
16
  export { default as previewFile } from './previewFile';
17
- export { default as getDataGroupBy } from './getDataGroupBy';
18
17
  export { default as clone } from './clone';
19
18
  export { default as placementPolyfill } from './placementPolyfill';
20
19
  export { default as getDOMNode } from './getDOMNode';
@@ -21,7 +21,13 @@ export declare function shouldShowNodeByParentExpanded<T>(expandItemValues?: T[]
21
21
  * Use {@link flattenTree} instead.
22
22
  */
23
23
  export declare function UNSAFE_flattenTree<TItem>(tree: TItem[], childrenKey?: string, executor?: (node: any, index: number) => any): TItem[];
24
- export declare function flattenTree<T>(rootNodes: readonly T[], getChildren: (node: T) => readonly T[] | undefined): T[];
24
+ export declare enum WalkTreeStrategy {
25
+ DFS = 0,
26
+ BFS = 1
27
+ }
28
+ export declare function flattenTree<T>(rootNodes: readonly T[], getChildren: (node: T) => readonly T[] | undefined, walkStrategy?: WalkTreeStrategy): T[];
29
+ export declare function walkTreeBfs<T>(rootNodes: readonly T[], getChildren: (node: T) => readonly T[] | undefined, callback: (node: T) => void): void;
30
+ export declare function walkTreeDfs<T>(rootNodes: readonly T[], getChildren: (node: T) => readonly T[] | undefined, callback: (node: T) => void): void;
25
31
  /**
26
32
  * get all ancestor nodes of given node
27
33
  * @param {*} node
@@ -278,3 +284,21 @@ export declare function createDragPreview(name: string, className: string): HTML
278
284
  */
279
285
  export declare function removeDragPreview(): void;
280
286
  export declare function stringifyTreeNodeLabel(label: string | React.ReactNode): string;
287
+ /**
288
+ * Returns a WeakMap that maps each item in `items` to its parent
289
+ * indicated by `getChildren` function
290
+ */
291
+ export declare function getParentMap<T extends Record<string, unknown>>(items: readonly T[], getChildren: (item: T) => readonly T[] | undefined): WeakMap<T, T>;
292
+ /**
293
+ * Returns a Map that maps each item's "key", indicated by `getKey` function,
294
+ * to its parent indicated by `getChildren` function
295
+ *
296
+ * NOTICE:
297
+ * Using this function is discouraged.
298
+ * Use {@link getParentMap} whenever possible.
299
+ */
300
+ export declare function getKeyParentMap<T extends Record<string, unknown>, K = React.Key>(items: readonly T[], getKey: (item: T) => K, getChildren: (item: T) => readonly T[] | undefined): Map<K, T>;
301
+ /**
302
+ * Returns an array indicating the hierarchy path from root towards `target` item
303
+ */
304
+ export declare function getPathTowardsItem<T>(target: T | undefined, getParent: (item: T) => T | undefined): T[];