@mui/x-tree-view 8.0.0-alpha.13 → 8.0.0-alpha.14

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 (120) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/RichTreeView/RichTreeView.js +24 -5
  3. package/SimpleTreeView/SimpleTreeView.js +8 -6
  4. package/TreeItem/TreeItem.d.ts +2 -0
  5. package/TreeItem/TreeItem.js +46 -5
  6. package/TreeItem/TreeItem.types.d.ts +14 -0
  7. package/TreeItemIcon/TreeItemIcon.js +2 -0
  8. package/esm/RichTreeView/RichTreeView.js +24 -5
  9. package/esm/SimpleTreeView/SimpleTreeView.js +8 -6
  10. package/esm/TreeItem/TreeItem.d.ts +2 -0
  11. package/esm/TreeItem/TreeItem.js +45 -4
  12. package/esm/TreeItem/TreeItem.types.d.ts +14 -0
  13. package/esm/TreeItemIcon/TreeItemIcon.js +2 -0
  14. package/esm/hooks/useTreeItemUtils/useTreeItemUtils.d.ts +3 -2
  15. package/esm/hooks/useTreeItemUtils/useTreeItemUtils.js +21 -9
  16. package/esm/hooks/useTreeViewApiRef.d.ts +1 -1
  17. package/esm/index.js +1 -1
  18. package/esm/internals/index.d.ts +6 -1
  19. package/esm/internals/index.js +4 -1
  20. package/esm/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +35 -12
  21. package/esm/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.d.ts +4 -0
  22. package/esm/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +40 -16
  23. package/esm/internals/plugins/useTreeViewItems/useTreeViewItems.js +157 -16
  24. package/esm/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.d.ts +172 -0
  25. package/esm/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +13 -0
  26. package/esm/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +49 -0
  27. package/esm/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +2 -2
  28. package/esm/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +16 -7
  29. package/esm/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +2 -1
  30. package/esm/internals/plugins/useTreeViewLazyLoading/index.d.ts +1 -0
  31. package/esm/internals/plugins/useTreeViewLazyLoading/index.js +1 -0
  32. package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.d.ts +249 -0
  33. package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.js +27 -0
  34. package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.types.d.ts +83 -0
  35. package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.types.js +1 -0
  36. package/esm/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +4 -4
  37. package/esm/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +12 -12
  38. package/esm/internals/utils/selectors.d.ts +7 -0
  39. package/esm/internals/utils/selectors.js +9 -0
  40. package/esm/useTreeItem/useTreeItem.d.ts +1 -1
  41. package/esm/useTreeItem/useTreeItem.js +13 -0
  42. package/esm/useTreeItem/useTreeItem.types.d.ts +21 -0
  43. package/esm/utils/cache.d.ts +38 -0
  44. package/esm/utils/cache.js +31 -0
  45. package/esm/utils/index.d.ts +1 -0
  46. package/esm/utils/index.js +1 -0
  47. package/hooks/useTreeItemUtils/useTreeItemUtils.d.ts +3 -2
  48. package/hooks/useTreeItemUtils/useTreeItemUtils.js +22 -10
  49. package/hooks/useTreeViewApiRef.d.ts +1 -1
  50. package/index.js +1 -1
  51. package/internals/index.d.ts +6 -1
  52. package/internals/index.js +33 -0
  53. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +35 -12
  54. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.d.ts +4 -0
  55. package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +40 -16
  56. package/internals/plugins/useTreeViewItems/useTreeViewItems.js +157 -16
  57. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.d.ts +172 -0
  58. package/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +14 -1
  59. package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +49 -0
  60. package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +1 -1
  61. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +16 -7
  62. package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +2 -1
  63. package/internals/plugins/useTreeViewLazyLoading/index.d.ts +1 -0
  64. package/internals/plugins/useTreeViewLazyLoading/index.js +5 -0
  65. package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.d.ts +249 -0
  66. package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.js +33 -0
  67. package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.types.d.ts +83 -0
  68. package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.types.js +5 -0
  69. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +4 -4
  70. package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +12 -12
  71. package/internals/utils/selectors.d.ts +7 -0
  72. package/internals/utils/selectors.js +9 -0
  73. package/modern/RichTreeView/RichTreeView.js +24 -5
  74. package/modern/SimpleTreeView/SimpleTreeView.js +8 -6
  75. package/modern/TreeItem/TreeItem.d.ts +2 -0
  76. package/modern/TreeItem/TreeItem.js +45 -4
  77. package/modern/TreeItem/TreeItem.types.d.ts +14 -0
  78. package/modern/TreeItemIcon/TreeItemIcon.js +2 -0
  79. package/modern/hooks/useTreeItemUtils/useTreeItemUtils.d.ts +3 -2
  80. package/modern/hooks/useTreeItemUtils/useTreeItemUtils.js +21 -9
  81. package/modern/hooks/useTreeViewApiRef.d.ts +1 -1
  82. package/modern/index.js +1 -1
  83. package/modern/internals/index.d.ts +6 -1
  84. package/modern/internals/index.js +4 -1
  85. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +35 -12
  86. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.d.ts +4 -0
  87. package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +40 -16
  88. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +157 -16
  89. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.d.ts +172 -0
  90. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js +13 -0
  91. package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +49 -0
  92. package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +2 -2
  93. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +16 -7
  94. package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +2 -1
  95. package/modern/internals/plugins/useTreeViewLazyLoading/index.d.ts +1 -0
  96. package/modern/internals/plugins/useTreeViewLazyLoading/index.js +1 -0
  97. package/modern/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.d.ts +249 -0
  98. package/modern/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.js +27 -0
  99. package/modern/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.types.d.ts +83 -0
  100. package/modern/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.types.js +1 -0
  101. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +4 -4
  102. package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +12 -12
  103. package/modern/internals/utils/selectors.d.ts +7 -0
  104. package/modern/internals/utils/selectors.js +9 -0
  105. package/modern/useTreeItem/useTreeItem.d.ts +1 -1
  106. package/modern/useTreeItem/useTreeItem.js +13 -0
  107. package/modern/useTreeItem/useTreeItem.types.d.ts +21 -0
  108. package/modern/utils/cache.d.ts +38 -0
  109. package/modern/utils/cache.js +31 -0
  110. package/modern/utils/index.d.ts +1 -0
  111. package/modern/utils/index.js +1 -0
  112. package/package.json +1 -1
  113. package/tsconfig.build.tsbuildinfo +1 -1
  114. package/useTreeItem/useTreeItem.d.ts +1 -1
  115. package/useTreeItem/useTreeItem.js +13 -0
  116. package/useTreeItem/useTreeItem.types.d.ts +21 -0
  117. package/utils/cache.d.ts +38 -0
  118. package/utils/cache.js +38 -0
  119. package/utils/index.d.ts +1 -0
  120. package/utils/index.js +16 -0
@@ -3,6 +3,8 @@
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
+ import Alert from '@mui/material/Alert';
7
+ import Typography from '@mui/material/Typography';
6
8
  import composeClasses from '@mui/utils/composeClasses';
7
9
  import useSlotProps from '@mui/utils/useSlotProps';
8
10
  import { warnOnce } from '@mui/x-internals/warning';
@@ -12,6 +14,8 @@ import { useTreeView } from "../internals/useTreeView/index.js";
12
14
  import { TreeViewProvider } from "../internals/TreeViewProvider/index.js";
13
15
  import { RICH_TREE_VIEW_PLUGINS } from "./RichTreeView.plugins.js";
14
16
  import { RichTreeViewItems } from "../internals/components/RichTreeViewItems.js";
17
+ import { useSelector } from "../internals/hooks/useSelector.js";
18
+ import { selectorGetTreeViewError, selectorIsTreeViewLoading } from "../internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js";
15
19
  import { jsx as _jsx } from "react/jsx-runtime";
16
20
  const useThemeProps = createUseThemeProps('MuiRichTreeView');
17
21
  const useUtilityClasses = ownerState => {
@@ -62,6 +66,8 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
62
66
  rootRef: ref,
63
67
  props
64
68
  });
69
+ const isLoading = useSelector(contextValue.store, selectorIsTreeViewLoading);
70
+ const treeViewError = useSelector(contextValue.store, selectorGetTreeViewError);
65
71
  const {
66
72
  slots,
67
73
  slotProps
@@ -75,6 +81,17 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
75
81
  getSlotProps: getRootProps,
76
82
  ownerState: props
77
83
  });
84
+ if (isLoading) {
85
+ return /*#__PURE__*/_jsx(Typography, {
86
+ children: "Loading..."
87
+ });
88
+ }
89
+ if (treeViewError) {
90
+ return /*#__PURE__*/_jsx(Alert, {
91
+ severity: "error",
92
+ children: treeViewError.message
93
+ });
94
+ }
78
95
  return /*#__PURE__*/_jsx(TreeViewProvider, {
79
96
  value: contextValue,
80
97
  children: /*#__PURE__*/_jsx(Root, _extends({}, rootProps, {
@@ -100,8 +117,10 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
100
117
  getItemDOMElement: PropTypes.func.isRequired,
101
118
  getItemOrderedChildrenIds: PropTypes.func.isRequired,
102
119
  getItemTree: PropTypes.func.isRequired,
103
- selectItem: PropTypes.func.isRequired,
120
+ getParentId: PropTypes.func.isRequired,
121
+ setIsItemDisabled: PropTypes.func.isRequired,
104
122
  setItemExpansion: PropTypes.func.isRequired,
123
+ setItemSelection: PropTypes.func.isRequired,
105
124
  updateItemLabel: PropTypes.func.isRequired
106
125
  })
107
126
  }),
@@ -205,7 +224,7 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
205
224
  multiSelect: PropTypes.bool,
206
225
  /**
207
226
  * Callback fired when Tree Items are expanded/collapsed.
208
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
227
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemExpansion()` method.
209
228
  * @param {array} itemIds The ids of the expanded items.
210
229
  */
211
230
  onExpandedItemsChange: PropTypes.func,
@@ -217,7 +236,7 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
217
236
  onItemClick: PropTypes.func,
218
237
  /**
219
238
  * Callback fired when a Tree Item is expanded or collapsed.
220
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
239
+ * @param {React.SyntheticEvent | null} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemExpansion()` method.
221
240
  * @param {array} itemId The itemId of the modified item.
222
241
  * @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed.
223
242
  */
@@ -236,14 +255,14 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
236
255
  onItemLabelChange: PropTypes.func,
237
256
  /**
238
257
  * Callback fired when a Tree Item is selected or deselected.
239
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
258
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemSelection()` method.
240
259
  * @param {array} itemId The itemId of the modified item.
241
260
  * @param {array} isSelected `true` if the item has just been selected, `false` if it has just been deselected.
242
261
  */
243
262
  onItemSelectionToggle: PropTypes.func,
244
263
  /**
245
264
  * Callback fired when Tree Items are selected/deselected.
246
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
265
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemSelection()` method.
247
266
  * @param {string[] | string} itemIds The ids of the selected items.
248
267
  * When `multiSelect` is `true`, this is an array of strings; when false (default) a string.
249
268
  */
@@ -99,8 +99,10 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
99
99
  getItemDOMElement: PropTypes.func.isRequired,
100
100
  getItemOrderedChildrenIds: PropTypes.func.isRequired,
101
101
  getItemTree: PropTypes.func.isRequired,
102
- selectItem: PropTypes.func.isRequired,
103
- setItemExpansion: PropTypes.func.isRequired
102
+ getParentId: PropTypes.func.isRequired,
103
+ setIsItemDisabled: PropTypes.func.isRequired,
104
+ setItemExpansion: PropTypes.func.isRequired,
105
+ setItemSelection: PropTypes.func.isRequired
104
106
  })
105
107
  }),
106
108
  /**
@@ -173,7 +175,7 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
173
175
  multiSelect: PropTypes.bool,
174
176
  /**
175
177
  * Callback fired when Tree Items are expanded/collapsed.
176
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
178
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemExpansion()` method.
177
179
  * @param {array} itemIds The ids of the expanded items.
178
180
  */
179
181
  onExpandedItemsChange: PropTypes.func,
@@ -185,7 +187,7 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
185
187
  onItemClick: PropTypes.func,
186
188
  /**
187
189
  * Callback fired when a Tree Item is expanded or collapsed.
188
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
190
+ * @param {React.SyntheticEvent | null} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemExpansion()` method.
189
191
  * @param {array} itemId The itemId of the modified item.
190
192
  * @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed.
191
193
  */
@@ -198,14 +200,14 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
198
200
  onItemFocus: PropTypes.func,
199
201
  /**
200
202
  * Callback fired when a Tree Item is selected or deselected.
201
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
203
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemSelection()` method.
202
204
  * @param {array} itemId The itemId of the modified item.
203
205
  * @param {array} isSelected `true` if the item has just been selected, `false` if it has just been deselected.
204
206
  */
205
207
  onItemSelectionToggle: PropTypes.func,
206
208
  /**
207
209
  * Callback fired when Tree Items are selected/deselected.
208
- * @param {React.SyntheticEvent} event The DOM event that triggered the change.
210
+ * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemSelection()` method.
209
211
  * @param {string[] | string} itemIds The ids of the selected items.
210
212
  * When `multiSelect` is `true`, this is an array of strings; when false (default) a string.
211
213
  */
@@ -11,6 +11,8 @@ export declare const TreeItemLabel: import("@emotion/styled").StyledComponent<im
11
11
  }, React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
12
12
  export declare const TreeItemIconContainer: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.ClassAttributes<HTMLDivElement> | keyof React.HTMLAttributes<HTMLDivElement>>, {}>;
13
13
  export declare const TreeItemGroupTransition: import("@emotion/styled").StyledComponent<Pick<import("@mui/material").CollapseProps, keyof import("@mui/material").CollapseProps> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
14
+ export declare const TreeItemErrorContainer: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.ClassAttributes<HTMLDivElement> | keyof React.HTMLAttributes<HTMLDivElement>>, {}>;
15
+ export declare const TreeItemLoadingContainer: import("@emotion/styled").StyledComponent<Pick<import("@mui/material").CircularProgressProps, keyof import("@mui/material").CircularProgressProps> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
14
16
  export declare const TreeItemCheckbox: import("@emotion/styled").StyledComponent<Pick<Omit<CheckboxProps & {
15
17
  visible?: boolean;
16
18
  }, "ref"> & React.RefAttributes<HTMLButtonElement>, "hidden" | "visible" | "color" | "content" | "size" | "style" | "icon" | "translate" | "disabled" | "form" | "slot" | "title" | "action" | "checked" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "name" | "readOnly" | "required" | "value" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "id" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "popover" | "popoverTargetAction" | "popoverTarget" | "inert" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onResize" | "onResizeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onToggle" | "onBeforeToggle" | "onTransitionCancel" | "onTransitionCancelCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "onTransitionRun" | "onTransitionRunCapture" | "onTransitionStart" | "onTransitionStartCapture" | "component" | "sx" | "classes" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge" | "checkedIcon" | "inputProps" | "inputRef" | "indeterminate" | "indeterminateIcon" | keyof React.RefAttributes<HTMLButtonElement>> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
@@ -7,6 +7,7 @@ const _excluded = ["visible"],
7
7
  import * as React from 'react';
8
8
  import PropTypes from 'prop-types';
9
9
  import clsx from 'clsx';
10
+ import CircularProgress from '@mui/material/CircularProgress';
10
11
  import unsupportedProp from '@mui/utils/unsupportedProp';
11
12
  import { alpha } from '@mui/material/styles';
12
13
  import Collapse from '@mui/material/Collapse';
@@ -132,6 +133,7 @@ export const TreeItemIconContainer = styled('div', {
132
133
  display: 'flex',
133
134
  flexShrink: 0,
134
135
  justifyContent: 'center',
136
+ position: 'relative',
135
137
  '& svg': {
136
138
  fontSize: 18
137
139
  }
@@ -144,6 +146,25 @@ export const TreeItemGroupTransition = styled(Collapse, {
144
146
  margin: 0,
145
147
  padding: 0
146
148
  });
149
+ export const TreeItemErrorContainer = styled('div', {
150
+ name: 'MuiTreeItem',
151
+ slot: 'ErrorIcon',
152
+ overridesResolver: (props, styles) => styles.errorIcon
153
+ })({
154
+ position: 'absolute',
155
+ right: -3,
156
+ width: 7,
157
+ height: 7,
158
+ borderRadius: '50%',
159
+ backgroundColor: 'red'
160
+ });
161
+ export const TreeItemLoadingContainer = styled(CircularProgress, {
162
+ name: 'MuiTreeItem',
163
+ slot: 'LoadingIcon',
164
+ overridesResolver: (props, styles) => styles.loadingIcon
165
+ })({
166
+ color: 'text.primary'
167
+ });
147
168
  export const TreeItemCheckbox = styled(/*#__PURE__*/React.forwardRef((props, ref) => {
148
169
  const {
149
170
  visible
@@ -180,7 +201,9 @@ const useUtilityClasses = ownerState => {
180
201
  label: ['label'],
181
202
  groupTransition: ['groupTransition'],
182
203
  labelInput: ['labelInput'],
183
- dragAndDropOverlay: ['dragAndDropOverlay']
204
+ dragAndDropOverlay: ['dragAndDropOverlay'],
205
+ errorIcon: ['errorIcon'],
206
+ loadingIcon: ['loadingIcon']
184
207
  };
185
208
  return composeClasses(slots, getTreeItemUtilityClass, classes);
186
209
  };
@@ -219,6 +242,8 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
219
242
  getGroupTransitionProps,
220
243
  getLabelInputProps,
221
244
  getDragAndDropOverlayProps,
245
+ getErrorContainerProps,
246
+ getLoadingContainerProps,
222
247
  status
223
248
  } = useTreeItem({
224
249
  id,
@@ -297,15 +322,31 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
297
322
  ownerState: {},
298
323
  className: classes.dragAndDropOverlay
299
324
  });
325
+ const ErrorIcon = slots.errorIcon ?? TreeItemErrorContainer;
326
+ const errorContainerProps = useSlotProps({
327
+ elementType: ErrorIcon,
328
+ getSlotProps: getErrorContainerProps,
329
+ externalSlotProps: slotProps.errorIcon,
330
+ ownerState: {},
331
+ className: classes.errorIcon
332
+ });
333
+ const LoadingIcon = slots.loadingIcon ?? TreeItemLoadingContainer;
334
+ const loadingContainerProps = useSlotProps({
335
+ elementType: LoadingIcon,
336
+ getSlotProps: getLoadingContainerProps,
337
+ externalSlotProps: slotProps.loadingIcon,
338
+ ownerState: {},
339
+ className: classes.loadingIcon
340
+ });
300
341
  return /*#__PURE__*/_jsx(TreeItemProvider, _extends({}, getContextProviderProps(), {
301
342
  children: /*#__PURE__*/_jsxs(Root, _extends({}, rootProps, {
302
343
  children: [/*#__PURE__*/_jsxs(Content, _extends({}, contentProps, {
303
- children: [/*#__PURE__*/_jsx(IconContainer, _extends({}, iconContainerProps, {
304
- children: /*#__PURE__*/_jsx(TreeItemIcon, {
344
+ children: [/*#__PURE__*/_jsxs(IconContainer, _extends({}, iconContainerProps, {
345
+ children: [status.error && /*#__PURE__*/_jsx(ErrorIcon, _extends({}, errorContainerProps)), status.loading ? /*#__PURE__*/_jsx(LoadingIcon, _extends({}, loadingContainerProps)) : /*#__PURE__*/_jsx(TreeItemIcon, {
305
346
  status: status,
306
347
  slots: slots,
307
348
  slotProps: slotProps
308
- })
349
+ })]
309
350
  })), /*#__PURE__*/_jsx(Checkbox, _extends({}, checkboxProps)), status.editing ? /*#__PURE__*/_jsx(LabelInput, _extends({}, labelInputProps)) : /*#__PURE__*/_jsx(Label, _extends({}, labelProps)), /*#__PURE__*/_jsx(DragAndDropOverlay, _extends({}, dragAndDropOverlayProps))]
310
351
  })), children && /*#__PURE__*/_jsx(TreeItemGroupTransition, _extends({
311
352
  as: GroupTransition
@@ -49,6 +49,18 @@ export interface TreeItemSlots extends TreeItemIconSlots {
49
49
  * @default TreeItemDragAndDropOverlay
50
50
  */
51
51
  dragAndDropOverlay?: React.ElementType;
52
+ /**
53
+ * The component that is rendered when the item is in an error state.
54
+ * Warning: This slot is only useful when using the `<RichTreeViewPro />` component is lazy loading is enabled.
55
+ * @default TreeItemErrorContainer
56
+ */
57
+ errorIcon?: React.ElementType;
58
+ /**
59
+ * The component that is rendered when the item is in an loading state.
60
+ * Warning: This slot is only useful when using the `<RichTreeViewPro />` component is lazy loading is enabled.
61
+ * @default TreeItemLoadingContainer
62
+ */
63
+ loadingIcon?: React.ElementType;
52
64
  }
53
65
  export interface TreeItemSlotProps extends TreeItemIconSlotProps {
54
66
  root?: SlotComponentProps<'li', {}, {}>;
@@ -59,6 +71,8 @@ export interface TreeItemSlotProps extends TreeItemIconSlotProps {
59
71
  label?: SlotComponentProps<'div', {}, {}>;
60
72
  labelInput?: SlotComponentProps<'input', {}, {}>;
61
73
  dragAndDropOverlay?: SlotComponentProps<'div', {}, {}>;
74
+ errorIcon?: SlotComponentProps<'div', {}, {}>;
75
+ loadingIcon?: SlotComponentProps<'div', {}, {}>;
62
76
  }
63
77
  export interface TreeItemProps extends Omit<UseTreeItemParameters, 'rootRef'>, Omit<React.HTMLAttributes<HTMLLIElement>, 'onFocus'> {
64
78
  className?: string;
@@ -63,9 +63,11 @@ process.env.NODE_ENV !== "production" ? TreeItemIcon.propTypes = {
63
63
  disabled: PropTypes.bool.isRequired,
64
64
  editable: PropTypes.bool.isRequired,
65
65
  editing: PropTypes.bool.isRequired,
66
+ error: PropTypes.bool.isRequired,
66
67
  expandable: PropTypes.bool.isRequired,
67
68
  expanded: PropTypes.bool.isRequired,
68
69
  focused: PropTypes.bool.isRequired,
70
+ loading: PropTypes.bool.isRequired,
69
71
  selected: PropTypes.bool.isRequired
70
72
  }).isRequired
71
73
  } : void 0;
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import type { UseTreeViewLazyLoadingSignature } from '../../internals/plugins/useTreeViewLazyLoading';
2
3
  import type { UseTreeViewSelectionSignature } from '../../internals/plugins/useTreeViewSelection';
3
4
  import type { UseTreeViewExpansionSignature } from '../../internals/plugins/useTreeViewExpansion';
4
5
  import type { UseTreeViewItemsSignature } from '../../internals/plugins/useTreeViewItems';
@@ -21,7 +22,7 @@ type UseTreeItemUtilsMinimalPlugins = readonly [UseTreeViewSelectionSignature, U
21
22
  /**
22
23
  * Plugins that `useTreeItemUtils` can use if they are present, but are not required.
23
24
  */
24
- export type UseTreeItemUtilsOptionalPlugins = readonly [UseTreeViewLabelSignature];
25
+ export type UseTreeItemUtilsOptionalPlugins = readonly [UseTreeViewLabelSignature, UseTreeViewLazyLoadingSignature];
25
26
  interface UseTreeItemUtilsReturnValue<TSignatures extends UseTreeItemUtilsMinimalPlugins, TOptionalSignatures extends UseTreeItemUtilsOptionalPlugins> {
26
27
  interactions: UseTreeItemInteractions;
27
28
  status: UseTreeItemStatus;
@@ -30,7 +31,7 @@ interface UseTreeItemUtilsReturnValue<TSignatures extends UseTreeItemUtilsMinima
30
31
  */
31
32
  publicAPI: TreeViewPublicAPI<TSignatures, TOptionalSignatures>;
32
33
  }
33
- export declare const isItemExpandable: (reactChildren: React.ReactNode) => boolean;
34
+ export declare const itemHasChildren: (reactChildren: React.ReactNode) => boolean;
34
35
  export declare const useTreeItemUtils: <TSignatures extends UseTreeItemUtilsMinimalPlugins = UseTreeItemUtilsMinimalPlugins, TOptionalSignatures extends UseTreeItemUtilsOptionalPlugins = UseTreeItemUtilsOptionalPlugins>({
35
36
  itemId,
36
37
  children
@@ -4,10 +4,11 @@ import { useTreeViewContext } from "../../internals/TreeViewProvider/index.js";
4
4
  import { useTreeViewLabel } from "../../internals/plugins/useTreeViewLabel/index.js";
5
5
  import { hasPlugin } from "../../internals/utils/plugins.js";
6
6
  import { useSelector } from "../../internals/hooks/useSelector.js";
7
- import { selectorIsItemExpanded } from "../../internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js";
7
+ import { selectorIsItemExpandable, selectorIsItemExpanded } from "../../internals/plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js";
8
8
  import { selectorIsItemFocused } from "../../internals/plugins/useTreeViewFocus/useTreeViewFocus.selectors.js";
9
9
  import { selectorIsItemDisabled } from "../../internals/plugins/useTreeViewItems/useTreeViewItems.selectors.js";
10
10
  import { selectorIsItemSelected } from "../../internals/plugins/useTreeViewSelection/useTreeViewSelection.selectors.js";
11
+ import { selectorGetTreeItemError, selectorIsItemLoading, selectorIsLazyLoadingEnabled } from "../../internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.js";
11
12
  import { selectorIsItemBeingEdited, selectorIsItemEditable } from "../../internals/plugins/useTreeViewLabel/useTreeViewLabel.selectors.js";
12
13
 
13
14
  /**
@@ -18,9 +19,9 @@ import { selectorIsItemBeingEdited, selectorIsItemEditable } from "../../interna
18
19
  * Plugins that `useTreeItemUtils` can use if they are present, but are not required.
19
20
  */
20
21
 
21
- export const isItemExpandable = reactChildren => {
22
+ export const itemHasChildren = reactChildren => {
22
23
  if (Array.isArray(reactChildren)) {
23
- return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
24
+ return reactChildren.length > 0 && reactChildren.some(itemHasChildren);
24
25
  }
25
26
  return Boolean(reactChildren);
26
27
  };
@@ -37,6 +38,11 @@ export const useTreeItemUtils = ({
37
38
  },
38
39
  publicAPI
39
40
  } = useTreeViewContext();
41
+ const isItemExpandable = useSelector(store, selectorIsItemExpandable, itemId);
42
+ const isLazyLoadingEnabled = useSelector(store, selectorIsLazyLoadingEnabled);
43
+ const loading = useSelector(store, state => isLazyLoadingEnabled ? selectorIsItemLoading(state, itemId) : false);
44
+ const error = useSelector(store, state => isLazyLoadingEnabled ? Boolean(selectorGetTreeItemError(state, itemId)) : false);
45
+ const isExpandable = itemHasChildren(children) || isItemExpandable;
40
46
  const isExpanded = useSelector(store, selectorIsItemExpanded, itemId);
41
47
  const isFocused = useSelector(store, selectorIsItemFocused, itemId);
42
48
  const isSelected = useSelector(store, selectorIsItemSelected, itemId);
@@ -47,13 +53,15 @@ export const useTreeItemUtils = ({
47
53
  isItemEditable: label.isItemEditable
48
54
  }));
49
55
  const status = {
50
- expandable: isItemExpandable(children),
56
+ expandable: isExpandable,
51
57
  expanded: isExpanded,
52
58
  focused: isFocused,
53
59
  selected: isSelected,
54
60
  disabled: isDisabled,
55
61
  editing: isEditing,
56
- editable: isEditable
62
+ editable: isEditable,
63
+ loading,
64
+ error
57
65
  };
58
66
  const handleExpansion = event => {
59
67
  if (status.disabled) {
@@ -66,7 +74,11 @@ export const useTreeItemUtils = ({
66
74
 
67
75
  // If already expanded and trying to toggle selection don't close
68
76
  if (status.expandable && !(multiple && selectorIsItemExpanded(store.value, itemId))) {
69
- instance.toggleItemExpansion(event, itemId);
77
+ // make sure the children selection is propagated again
78
+ instance.setItemExpansion({
79
+ event,
80
+ itemId
81
+ });
70
82
  }
71
83
  };
72
84
  const handleSelection = event => {
@@ -81,14 +93,14 @@ export const useTreeItemUtils = ({
81
93
  if (event.shiftKey) {
82
94
  instance.expandSelectionRange(event, itemId);
83
95
  } else {
84
- instance.selectItem({
96
+ instance.setItemSelection({
85
97
  event,
86
98
  itemId,
87
99
  keepExistingSelection: true
88
100
  });
89
101
  }
90
102
  } else {
91
- instance.selectItem({
103
+ instance.setItemSelection({
92
104
  event,
93
105
  itemId,
94
106
  shouldBeSelected: true
@@ -100,7 +112,7 @@ export const useTreeItemUtils = ({
100
112
  if (multiSelect && hasShift) {
101
113
  instance.expandSelectionRange(event, itemId);
102
114
  } else {
103
- instance.selectItem({
115
+ instance.setItemSelection({
104
116
  event,
105
117
  itemId,
106
118
  keepExistingSelection: multiSelect,
@@ -4,4 +4,4 @@ import { RichTreeViewPluginSignatures } from "../RichTreeView/RichTreeView.plugi
4
4
  /**
5
5
  * Hook that instantiates a [[TreeViewApiRef]].
6
6
  */
7
- export declare const useTreeViewApiRef: <TSignatures extends readonly TreeViewAnyPluginSignature[] = readonly [import("../internals").UseTreeViewItemsSignature, import("../internals").UseTreeViewExpansionSignature, import("../internals").UseTreeViewSelectionSignature, import("../internals").UseTreeViewFocusSignature, import("../internals").UseTreeViewKeyboardNavigationSignature, import("../internals").UseTreeViewIconsSignature, import("../internals").UseTreeViewLabelSignature]>() => React.RefObject<TreeViewPublicAPI<TSignatures> | undefined>;
7
+ export declare const useTreeViewApiRef: <TSignatures extends readonly TreeViewAnyPluginSignature[] = RichTreeViewPluginSignatures>() => React.RefObject<TreeViewPublicAPI<TSignatures> | undefined>;
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v8.0.0-alpha.13
2
+ * @mui/x-tree-view v8.0.0-alpha.14
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -2,7 +2,7 @@ export { useTreeView } from "./useTreeView/index.js";
2
2
  export { TreeViewProvider, useTreeViewContext } from "./TreeViewProvider/index.js";
3
3
  export { RichTreeViewItems } from "./components/RichTreeViewItems.js";
4
4
  export type { RichTreeViewItemsSlots, RichTreeViewItemsSlotProps } from './components/RichTreeViewItems';
5
- export { unstable_resetCleanupTracking } from "./hooks/useInstanceEventHandler.js";
5
+ export { unstable_resetCleanupTracking, useInstanceEventHandler } from "./hooks/useInstanceEventHandler.js";
6
6
  export { useSelector } from "./hooks/useSelector.js";
7
7
  export type { TreeViewPlugin, TreeViewPluginSignature, ConvertPluginsIntoSignatures, MergeSignaturesProperty, TreeViewPublicAPI, TreeViewState, TreeViewExperimentalFeatures, TreeViewItemMeta, TreeViewInstance, TreeViewItemPlugin, TreeViewUsedStore } from './models';
8
8
  export type { TreeViewCorePluginParameters } from './corePlugins';
@@ -21,6 +21,11 @@ export { selectorItemMetaLookup, selectorItemMeta, selectorItemIndex, selectorIt
21
21
  export type { UseTreeViewItemsSignature, UseTreeViewItemsParameters, UseTreeViewItemsState } from './plugins/useTreeViewItems';
22
22
  export { useTreeViewLabel } from "./plugins/useTreeViewLabel/index.js";
23
23
  export type { UseTreeViewLabelSignature, UseTreeViewLabelParameters } from './plugins/useTreeViewLabel';
24
+ export { selectorIsItemExpanded } from "./plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js";
25
+ export { selectorIsItemSelected } from "./plugins/useTreeViewSelection/useTreeViewSelection.selectors.js";
26
+ export { selectorDataSourceState, selectorGetTreeItemError } from "./plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.js";
27
+ export type { UseTreeViewLazyLoadingSignature } from './plugins/useTreeViewLazyLoading';
28
+ export type { UseTreeViewLazyLoadingParameters } from './plugins/useTreeViewLazyLoading';
24
29
  export { useTreeViewJSXItems } from "./plugins/useTreeViewJSXItems/index.js";
25
30
  export type { UseTreeViewJSXItemsSignature, UseTreeViewJSXItemsParameters } from './plugins/useTreeViewJSXItems';
26
31
  export { createSelector } from "./utils/selectors.js";
@@ -1,7 +1,7 @@
1
1
  export { useTreeView } from "./useTreeView/index.js";
2
2
  export { TreeViewProvider, useTreeViewContext } from "./TreeViewProvider/index.js";
3
3
  export { RichTreeViewItems } from "./components/RichTreeViewItems.js";
4
- export { unstable_resetCleanupTracking } from "./hooks/useInstanceEventHandler.js";
4
+ export { unstable_resetCleanupTracking, useInstanceEventHandler } from "./hooks/useInstanceEventHandler.js";
5
5
  export { useSelector } from "./hooks/useSelector.js";
6
6
 
7
7
  // Core plugins
@@ -15,6 +15,9 @@ export { useTreeViewIcons } from "./plugins/useTreeViewIcons/index.js";
15
15
  export { useTreeViewItems, buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from "./plugins/useTreeViewItems/index.js";
16
16
  export { selectorItemMetaLookup, selectorItemMeta, selectorItemIndex, selectorItemOrderedChildrenIds } from "./plugins/useTreeViewItems/useTreeViewItems.selectors.js";
17
17
  export { useTreeViewLabel } from "./plugins/useTreeViewLabel/index.js";
18
+ export { selectorIsItemExpanded } from "./plugins/useTreeViewExpansion/useTreeViewExpansion.selectors.js";
19
+ export { selectorIsItemSelected } from "./plugins/useTreeViewSelection/useTreeViewSelection.selectors.js";
20
+ export { selectorDataSourceState, selectorGetTreeItemError } from "./plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.selectors.js";
18
21
  export { useTreeViewJSXItems } from "./plugins/useTreeViewJSXItems/index.js";
19
22
  export { createSelector } from "./utils/selectors.js";
20
23
  export { isTargetInDescendants } from "./utils/tree.js";
@@ -4,6 +4,7 @@ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
4
4
  import { selectorIsItemExpandable, selectorIsItemExpanded } from "./useTreeViewExpansion.selectors.js";
5
5
  import { createExpandedItemsMap, getExpansionTrigger } from "./useTreeViewExpansion.utils.js";
6
6
  import { selectorItemMeta, selectorItemOrderedChildrenIds } from "../useTreeViewItems/useTreeViewItems.selectors.js";
7
+ import { publishTreeViewEvent } from "../../utils/publishTreeViewEvent.js";
7
8
  export const useTreeViewExpansion = ({
8
9
  instance,
9
10
  store,
@@ -37,26 +38,48 @@ export const useTreeViewExpansion = ({
37
38
  params.onExpandedItemsChange?.(event, value);
38
39
  models.expandedItems.setControlledValue(value);
39
40
  };
40
- const toggleItemExpansion = useEventCallback((event, itemId) => {
41
- const isExpandedBefore = selectorIsItemExpanded(store.value, itemId);
42
- instance.setItemExpansion(event, itemId, !isExpandedBefore);
43
- });
44
- const setItemExpansion = useEventCallback((event, itemId, isExpanded) => {
45
- const isExpandedBefore = selectorIsItemExpanded(store.value, itemId);
46
- if (isExpandedBefore === isExpanded) {
47
- return;
48
- }
41
+ const applyItemExpansion = useEventCallback(({
42
+ itemId,
43
+ event,
44
+ shouldBeExpanded
45
+ }) => {
49
46
  let newExpanded;
50
- if (isExpanded) {
47
+ if (shouldBeExpanded) {
51
48
  newExpanded = [itemId].concat(models.expandedItems.value);
52
49
  } else {
53
50
  newExpanded = models.expandedItems.value.filter(id => id !== itemId);
54
51
  }
55
52
  if (params.onItemExpansionToggle) {
56
- params.onItemExpansionToggle(event, itemId, isExpanded);
53
+ params.onItemExpansionToggle(event, itemId, shouldBeExpanded);
57
54
  }
58
55
  setExpandedItems(event, newExpanded);
59
56
  });
57
+ const setItemExpansion = useEventCallback(({
58
+ itemId,
59
+ event = null,
60
+ shouldBeExpanded
61
+ }) => {
62
+ const isExpandedBefore = selectorIsItemExpanded(store.value, itemId);
63
+ const cleanShouldBeExpanded = shouldBeExpanded ?? !isExpandedBefore;
64
+ if (isExpandedBefore === cleanShouldBeExpanded) {
65
+ return;
66
+ }
67
+ const eventParameters = {
68
+ isExpansionPrevented: false,
69
+ shouldBeExpanded: cleanShouldBeExpanded,
70
+ event,
71
+ itemId
72
+ };
73
+ publishTreeViewEvent(instance, 'beforeItemToggleExpansion', eventParameters);
74
+ if (eventParameters.isExpansionPrevented) {
75
+ return;
76
+ }
77
+ instance.applyItemExpansion({
78
+ itemId,
79
+ event,
80
+ shouldBeExpanded: cleanShouldBeExpanded
81
+ });
82
+ });
60
83
  const expandAllSiblings = (event, itemId) => {
61
84
  const itemMeta = selectorItemMeta(store.value, itemId);
62
85
  if (itemMeta == null) {
@@ -80,7 +103,7 @@ export const useTreeViewExpansion = ({
80
103
  },
81
104
  instance: {
82
105
  setItemExpansion,
83
- toggleItemExpansion,
106
+ applyItemExpansion,
84
107
  expandAllSiblings
85
108
  }
86
109
  };
@@ -90,6 +90,8 @@ export declare const selectorIsItemExpandable: ((state: any, itemId: string | nu
90
90
  [itemId: string]: number;
91
91
  };
92
92
  };
93
+ loading: boolean;
94
+ error: Error | null;
93
95
  }) => {
94
96
  [itemId: string]: import("../..").TreeViewItemMeta;
95
97
  };
@@ -109,6 +111,8 @@ export declare const selectorIsItemExpandable: ((state: any, itemId: string | nu
109
111
  [itemId: string]: number;
110
112
  };
111
113
  };
114
+ loading: boolean;
115
+ error: Error | null;
112
116
  }) => {
113
117
  [itemId: string]: import("../..").TreeViewItemMeta;
114
118
  }) & {