@mui/x-tree-view-pro 8.12.0 → 8.13.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.
- package/CHANGELOG.md +207 -0
- package/RichTreeViewPro/RichTreeViewPro.js +1 -1
- package/RichTreeViewPro/RichTreeViewPro.types.d.ts +2 -3
- package/RichTreeViewPro/index.d.ts +1 -1
- package/esm/RichTreeViewPro/RichTreeViewPro.js +1 -1
- package/esm/RichTreeViewPro/RichTreeViewPro.types.d.ts +2 -3
- package/esm/RichTreeViewPro/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.js +2 -2
- package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.d.ts +1 -2
- package/esm/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.js +123 -157
- package/index.js +1 -1
- package/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.js +2 -2
- package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.d.ts +1 -2
- package/internals/plugins/useTreeViewLazyLoading/useTreeViewLazyLoading.js +125 -159
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,213 @@
|
|
|
5
5
|
All notable changes to this project will be documented in this file.
|
|
6
6
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
7
7
|
|
|
8
|
+
## 8.13.1
|
|
9
|
+
|
|
10
|
+
_Oct 1, 2025_
|
|
11
|
+
|
|
12
|
+
- 🐛 Fix `@mui/x-charts-pro` failure on import due to missing `@mui/x-internals` release
|
|
13
|
+
|
|
14
|
+
### Data Grid
|
|
15
|
+
|
|
16
|
+
#### `@mui/x-data-grid@8.13.1`
|
|
17
|
+
|
|
18
|
+
Internal changes.
|
|
19
|
+
|
|
20
|
+
#### `@mui/x-data-grid-pro@8.13.1` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
21
|
+
|
|
22
|
+
Same changes as in `@mui/x-data-grid@8.13.1`.
|
|
23
|
+
|
|
24
|
+
#### `@mui/x-data-grid-premium@8.13.1` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
25
|
+
|
|
26
|
+
Same changes as in `@mui/x-data-grid-pro@8.13.1`.
|
|
27
|
+
|
|
28
|
+
### Date and Time Pickers
|
|
29
|
+
|
|
30
|
+
#### `@mui/x-date-pickers@8.12.0`
|
|
31
|
+
|
|
32
|
+
Internal changes.
|
|
33
|
+
|
|
34
|
+
#### `@mui/x-date-pickers-pro@8.12.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
35
|
+
|
|
36
|
+
Same changes as in `@mui/x-date-pickers@8.12.0`.
|
|
37
|
+
|
|
38
|
+
### Charts
|
|
39
|
+
|
|
40
|
+
#### `@mui/x-charts@8.13.1`
|
|
41
|
+
|
|
42
|
+
Internal changes.
|
|
43
|
+
|
|
44
|
+
#### `@mui/x-charts-pro@8.13.1` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
45
|
+
|
|
46
|
+
Same changes as in `@mui/x-charts@8.13.1`, plus:
|
|
47
|
+
|
|
48
|
+
- [charts-pro] Fix `@mui/x-charts-pro` failure on import due to missing `@mui/x-internals` release @bernardobelchior
|
|
49
|
+
|
|
50
|
+
#### `@mui/x-charts-premium@8.13.1` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
51
|
+
|
|
52
|
+
Same changes as in `@mui/x-charts-pro@8.13.1`.
|
|
53
|
+
|
|
54
|
+
### Tree View
|
|
55
|
+
|
|
56
|
+
#### `@mui/x-tree-view@8.13.1`
|
|
57
|
+
|
|
58
|
+
Internal changes.
|
|
59
|
+
|
|
60
|
+
#### `@mui/x-tree-view-pro@8.13.1` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
61
|
+
|
|
62
|
+
Same changes as in `@mui/x-tree-view@8.13.1`.
|
|
63
|
+
|
|
64
|
+
### Codemod
|
|
65
|
+
|
|
66
|
+
#### `@mui/x-codemod@8.12.0`
|
|
67
|
+
|
|
68
|
+
Internal changes.
|
|
69
|
+
|
|
70
|
+
## 8.13.0
|
|
71
|
+
|
|
72
|
+
_Oct 1, 2025_
|
|
73
|
+
|
|
74
|
+
We'd like to extend a big thank you to the 14 contributors who made this release possible. Here are some highlights ✨:
|
|
75
|
+
|
|
76
|
+
- 📊 The chart zoom now supports the `tapAndDrag` gesture. Zoom in/out by tapping twice and dragging vertically.
|
|
77
|
+
- 🔎 Charts now allow [fine-grained control for zoom interactions](https://mui.com/x/react-charts/zoom-and-pan/#zoom-interactions-configuration).
|
|
78
|
+
```jsx
|
|
79
|
+
<BarChartPro
|
|
80
|
+
zoomInteractionConfig={{
|
|
81
|
+
// Only zoom when Control key is pressed
|
|
82
|
+
zoom: [{ type: 'wheel', keys: ['Control'] }],
|
|
83
|
+
// Only pan when Shift key is pressed
|
|
84
|
+
pan: [{ type: 'drag', keys: ['Shift'] }],
|
|
85
|
+
}}
|
|
86
|
+
/>
|
|
87
|
+
```
|
|
88
|
+
- ➡️ Data Grid grouping rows now persist their expansion state when the rows are updated.
|
|
89
|
+
- 📜 Updated Data Grid vertical scrollbar to include pinned rows and aggregation sections.
|
|
90
|
+
- 📌 Improved the appearance of [pinned columns](https://mui.com/x/react-data-grid/column-pinning/#pinned-columns-appearance) and [pinned rows](https://mui.com/x/react-data-grid/row-pinning/#pinned-rows-appearance) sections in the Data Grid.
|
|
91
|
+
- 🚀 Tree View now fetches the children of expanded items on mount when using lazy loading.
|
|
92
|
+
- 🐞 Bugfixes
|
|
93
|
+
- 📚 Documentation improvements
|
|
94
|
+
|
|
95
|
+
Special thanks go out to the community members for their valuable contributions:
|
|
96
|
+
@sai6855
|
|
97
|
+
|
|
98
|
+
The following are all team members who have contributed to this release:
|
|
99
|
+
@alexfauquette, @arminmeh, @bernardobelchior, @flaviendelangle, @hasdfa, @Janpot, @JCQuintas, @KenanYusuf, @mapache-salvaje, @MBilalShafi, @mnajdova, @rita-codes, @siriwatknp
|
|
100
|
+
|
|
101
|
+
### Data Grid
|
|
102
|
+
|
|
103
|
+
#### `@mui/x-data-grid@8.13.0`
|
|
104
|
+
|
|
105
|
+
- [DataGrid] Add scroll shadows and fix scrollbar overlap (#16476) @KenanYusuf
|
|
106
|
+
- [DataGrid] Fix row spanning stale state issue (#19733) @MBilalShafi
|
|
107
|
+
- [DataGrid] Fix toolbar `slotProps` not being applied (#19769) @sai6855
|
|
108
|
+
- [DataGrid] Skip calling `fetchRows()` when strategy is not initialized (#19728) @MBilalShafi
|
|
109
|
+
|
|
110
|
+
#### `@mui/x-data-grid-pro@8.13.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
111
|
+
|
|
112
|
+
Same changes as in `@mui/x-data-grid@8.13.0`, plus:
|
|
113
|
+
|
|
114
|
+
- [DataGridPro] Retain expansion state on rows update (#19697) @MBilalShafi
|
|
115
|
+
|
|
116
|
+
#### `@mui/x-data-grid-premium@8.13.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
117
|
+
|
|
118
|
+
Same changes as in `@mui/x-data-grid-pro@8.13.0`, plus:
|
|
119
|
+
|
|
120
|
+
- [DataGridPremium] Add `metadata.referenceId` to AI assistant prompt resolver (#19695) @hasdfa
|
|
121
|
+
- [DataGridPremium] Fix aggregation value retrieval (#19724) @arminmeh
|
|
122
|
+
- [DataGridPremium] Get correct active chart id while rebuilding data (#19720) @arminmeh
|
|
123
|
+
|
|
124
|
+
### Date and Time Pickers
|
|
125
|
+
|
|
126
|
+
#### `@mui/x-date-pickers@8.12.0`
|
|
127
|
+
|
|
128
|
+
Internal changes.
|
|
129
|
+
|
|
130
|
+
#### `@mui/x-date-pickers-pro@8.12.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
131
|
+
|
|
132
|
+
Same changes as in `@mui/x-date-pickers@8.12.0`.
|
|
133
|
+
|
|
134
|
+
### Charts
|
|
135
|
+
|
|
136
|
+
#### `@mui/x-charts@8.13.0`
|
|
137
|
+
|
|
138
|
+
- [charts] Add `tapAndDrag` zoom gesture (#19727) @JCQuintas
|
|
139
|
+
- [charts] Add arc focus indicator that follows the arc form (#19696) @mnajdova
|
|
140
|
+
- [charts] Fix outline color (#19752) @alexfauquette
|
|
141
|
+
- [charts] Improve tooltip doc (#19731) @JCQuintas
|
|
142
|
+
- [charts] Make axis highlight reflect the keyboard interaction (#19631) @alexfauquette
|
|
143
|
+
- [charts] Prevent horizontal scroll on keyboard navigation (#19704) @alexfauquette
|
|
144
|
+
- [charts] Simplify gestures by removing bindings (#19767) @JCQuintas
|
|
145
|
+
|
|
146
|
+
#### `@mui/x-charts-pro@8.13.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
147
|
+
|
|
148
|
+
Same changes as in `@mui/x-charts@8.13.0`, plus:
|
|
149
|
+
|
|
150
|
+
- [charts-pro] Allow zoom interactions to be configured (#18646) @JCQuintas
|
|
151
|
+
- [charts-pro] Fix zoom preview having wrong domain in some cases (#19723) @bernardobelchior
|
|
152
|
+
|
|
153
|
+
#### `@mui/x-charts-premium@8.13.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
154
|
+
|
|
155
|
+
Same changes as in `@mui/x-charts-pro@8.13.0`.
|
|
156
|
+
|
|
157
|
+
### Tree View
|
|
158
|
+
|
|
159
|
+
#### `@mui/x-tree-view@8.13.0`
|
|
160
|
+
|
|
161
|
+
- [tree view] Export the `apiRef` type of each Tree View component (#19543) @flaviendelangle
|
|
162
|
+
- [tree view] Fix indeterminate checkbox state (#19544) @flaviendelangle
|
|
163
|
+
- [tree view] Improve the lazy loading initial expansion (#19284) @flaviendelangle
|
|
164
|
+
- [tree view] Use Base UI utils whenever possible (#19502) @flaviendelangle
|
|
165
|
+
|
|
166
|
+
#### `@mui/x-tree-view-pro@8.13.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
167
|
+
|
|
168
|
+
Same changes as in `@mui/x-tree-view@8.13.0`.
|
|
169
|
+
|
|
170
|
+
### Codemod
|
|
171
|
+
|
|
172
|
+
#### `@mui/x-codemod@8.12.0`
|
|
173
|
+
|
|
174
|
+
Internal changes.
|
|
175
|
+
|
|
176
|
+
### Docs
|
|
177
|
+
|
|
178
|
+
- [docs] Add a recipe to customize editing component with Autocomplete (#19651) @siriwatknp
|
|
179
|
+
- [docs] Refine the electricity scatter tooltip (#19689) @alexfauquette
|
|
180
|
+
- [docs] Revise the Axis doc (#19052) @mapache-salvaje
|
|
181
|
+
- [docs] Remove reference to nonexistent `FocusedMark` API page (#19773) @bernardobelchior
|
|
182
|
+
|
|
183
|
+
### Core
|
|
184
|
+
|
|
185
|
+
- [code-infra] Change charts codspeed integration to use walltime (#19729) @JCQuintas
|
|
186
|
+
- [code-infra] Port stylelint from core repo (#19633) @Janpot
|
|
187
|
+
- [code-infra] Stabilize fake timers in regression tests (#19719) @Janpot
|
|
188
|
+
- [code-infra] Stabilize size for bundles with `releaseInfo` (#19674) @Janpot
|
|
189
|
+
- [code-infra] Fix `pnpm-lock.yaml` broken lockfile (#19755) @bernardobelchior
|
|
190
|
+
|
|
191
|
+
## 8.12.1
|
|
192
|
+
|
|
193
|
+
_Sep 25, 2025_
|
|
194
|
+
|
|
195
|
+
Release highlight ✨:
|
|
196
|
+
|
|
197
|
+
- 🐞 Hotfix for Grid-Charts integration issue with aggregated values
|
|
198
|
+
|
|
199
|
+
### Data Grid
|
|
200
|
+
|
|
201
|
+
#### `@mui/x-data-grid@8.12.1`
|
|
202
|
+
|
|
203
|
+
Internal changes.
|
|
204
|
+
|
|
205
|
+
#### `@mui/x-data-grid-pro@8.12.1` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
206
|
+
|
|
207
|
+
Same changes as in `@mui/x-data-grid@8.12.1`.
|
|
208
|
+
|
|
209
|
+
#### `@mui/x-data-grid-premium@8.12.1` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
210
|
+
|
|
211
|
+
Same changes as in `@mui/x-data-grid-pro@8.12.1`, plus:
|
|
212
|
+
|
|
213
|
+
- [DataGridPremium] Collect aggregated values properly for the charts integration context (#19714) @arminmeh
|
|
214
|
+
|
|
8
215
|
## 8.12.0
|
|
9
216
|
|
|
10
217
|
_Sep 25, 2025_
|
|
@@ -15,7 +15,7 @@ export interface RichTreeViewProSlots extends TreeViewSlots, RichTreeViewItemsSl
|
|
|
15
15
|
export interface RichTreeViewProSlotProps<R extends {}, Multiple extends boolean | undefined> extends TreeViewSlotProps, RichTreeViewItemsSlotProps {
|
|
16
16
|
root?: SlotComponentProps<'ul', {}, RichTreeViewProProps<R, Multiple>>;
|
|
17
17
|
}
|
|
18
|
-
type RichTreeViewProApiRef = React.RefObject<Partial<TreeViewPublicAPI<RichTreeViewProPluginSignatures>> | undefined>;
|
|
18
|
+
export type RichTreeViewProApiRef = React.RefObject<Partial<TreeViewPublicAPI<RichTreeViewProPluginSignatures>> | undefined>;
|
|
19
19
|
export interface RichTreeViewProPropsBase extends React.HTMLAttributes<HTMLUListElement> {
|
|
20
20
|
className?: string;
|
|
21
21
|
/**
|
|
@@ -42,5 +42,4 @@ export interface RichTreeViewProProps<R extends {}, Multiple extends boolean | u
|
|
|
42
42
|
* The ref object that allows Tree View manipulation. Can be instantiated with `useTreeViewApiRef()`.
|
|
43
43
|
*/
|
|
44
44
|
apiRef?: RichTreeViewProApiRef;
|
|
45
|
-
}
|
|
46
|
-
export {};
|
|
45
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from "./RichTreeViewPro.js";
|
|
2
2
|
export * from "./richTreeViewProClasses.js";
|
|
3
|
-
export type { RichTreeViewProProps, RichTreeViewProPropsBase, RichTreeViewProSlots, RichTreeViewProSlotProps } from "./RichTreeViewPro.types.js";
|
|
3
|
+
export type { RichTreeViewProProps, RichTreeViewProPropsBase, RichTreeViewProSlots, RichTreeViewProSlotProps, RichTreeViewProApiRef } from "./RichTreeViewPro.types.js";
|
|
4
4
|
export type { RichTreeViewProPluginSignatures } from "./RichTreeViewPro.plugins.js";
|
|
@@ -15,7 +15,7 @@ export interface RichTreeViewProSlots extends TreeViewSlots, RichTreeViewItemsSl
|
|
|
15
15
|
export interface RichTreeViewProSlotProps<R extends {}, Multiple extends boolean | undefined> extends TreeViewSlotProps, RichTreeViewItemsSlotProps {
|
|
16
16
|
root?: SlotComponentProps<'ul', {}, RichTreeViewProProps<R, Multiple>>;
|
|
17
17
|
}
|
|
18
|
-
type RichTreeViewProApiRef = React.RefObject<Partial<TreeViewPublicAPI<RichTreeViewProPluginSignatures>> | undefined>;
|
|
18
|
+
export type RichTreeViewProApiRef = React.RefObject<Partial<TreeViewPublicAPI<RichTreeViewProPluginSignatures>> | undefined>;
|
|
19
19
|
export interface RichTreeViewProPropsBase extends React.HTMLAttributes<HTMLUListElement> {
|
|
20
20
|
className?: string;
|
|
21
21
|
/**
|
|
@@ -42,5 +42,4 @@ export interface RichTreeViewProProps<R extends {}, Multiple extends boolean | u
|
|
|
42
42
|
* The ref object that allows Tree View manipulation. Can be instantiated with `useTreeViewApiRef()`.
|
|
43
43
|
*/
|
|
44
44
|
apiRef?: RichTreeViewProApiRef;
|
|
45
|
-
}
|
|
46
|
-
export {};
|
|
45
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from "./RichTreeViewPro.js";
|
|
2
2
|
export * from "./richTreeViewProClasses.js";
|
|
3
|
-
export type { RichTreeViewProProps, RichTreeViewProPropsBase, RichTreeViewProSlots, RichTreeViewProSlotProps } from "./RichTreeViewPro.types.js";
|
|
3
|
+
export type { RichTreeViewProProps, RichTreeViewProPropsBase, RichTreeViewProSlots, RichTreeViewProSlotProps, RichTreeViewProApiRef } from "./RichTreeViewPro.types.js";
|
|
4
4
|
export type { RichTreeViewProPluginSignatures } from "./RichTreeViewPro.plugins.js";
|
package/esm/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import
|
|
3
|
+
import { useIsoLayoutEffect } from '@base-ui-components/utils/useIsoLayoutEffect';
|
|
4
4
|
import { itemsSelectors, labelSelectors } from '@mui/x-tree-view/internals';
|
|
5
5
|
import { chooseActionToApply, isAncestor, moveItemInTree } from "./useTreeViewItemsReordering.utils.js";
|
|
6
6
|
import { useTreeViewItemsReorderingItemPlugin } from "./useTreeViewItemsReordering.itemPlugin.js";
|
|
@@ -171,7 +171,7 @@ export const useTreeViewItemsReordering = ({
|
|
|
171
171
|
})
|
|
172
172
|
}));
|
|
173
173
|
}, [store, params.itemChildrenIndentation]);
|
|
174
|
-
|
|
174
|
+
useIsoLayoutEffect(() => {
|
|
175
175
|
store.set('itemsReordering', _extends({}, store.state.itemsReordering, {
|
|
176
176
|
isItemReorderable: params.itemsReordering ? params.isItemReorderable ?? (() => true) : () => false
|
|
177
177
|
}));
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { TreeViewPlugin } from '@mui/x-tree-view/internals';
|
|
2
|
-
import type { UseTreeViewLazyLoadingSignature } from '@mui/x-tree-view/internals';
|
|
1
|
+
import { TreeViewPlugin, UseTreeViewLazyLoadingSignature } from '@mui/x-tree-view/internals';
|
|
3
2
|
export declare const useTreeViewLazyLoading: TreeViewPlugin<UseTreeViewLazyLoadingSignature>;
|
|
@@ -2,205 +2,144 @@
|
|
|
2
2
|
|
|
3
3
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import
|
|
6
|
-
import useEventCallback from '@
|
|
7
|
-
import
|
|
5
|
+
import { useRefWithInit } from '@base-ui-components/utils/useRefWithInit';
|
|
6
|
+
import { useEventCallback } from '@base-ui-components/utils/useEventCallback';
|
|
7
|
+
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
|
|
8
|
+
import { itemsSelectors, expansionSelectors, selectionSelectors, lazyLoadingSelectors, useInstanceEventHandler, TREE_VIEW_ROOT_PARENT_ID } from '@mui/x-tree-view/internals';
|
|
8
9
|
import { DataSourceCacheDefault } from '@mui/x-tree-view/utils';
|
|
9
10
|
import { NestedDataManager } from "./utils.js";
|
|
10
11
|
const INITIAL_STATE = {
|
|
11
12
|
loading: {},
|
|
12
13
|
errors: {}
|
|
13
14
|
};
|
|
14
|
-
const noopCache = {
|
|
15
|
-
clear: () => {},
|
|
16
|
-
get: () => undefined,
|
|
17
|
-
set: () => {}
|
|
18
|
-
};
|
|
19
|
-
function getCache(cacheProp) {
|
|
20
|
-
if (cacheProp === null) {
|
|
21
|
-
return noopCache;
|
|
22
|
-
}
|
|
23
|
-
return cacheProp ?? new DataSourceCacheDefault({});
|
|
24
|
-
}
|
|
25
15
|
export const useTreeViewLazyLoading = ({
|
|
26
16
|
instance,
|
|
27
17
|
params,
|
|
28
18
|
store
|
|
29
19
|
}) => {
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const nestedDataManager = useLazyRef(() => new NestedDataManager(instance)).current;
|
|
33
|
-
const cacheRef = useLazyRef(() => getCache(params.dataSourceCache));
|
|
20
|
+
const nestedDataManager = useRefWithInit(() => new NestedDataManager(instance)).current;
|
|
21
|
+
const cache = useRefWithInit(() => params.dataSourceCache ?? new DataSourceCacheDefault({})).current;
|
|
34
22
|
const setDataSourceLoading = useEventCallback((itemId, isLoading) => {
|
|
35
|
-
if (!
|
|
23
|
+
if (!params.dataSource) {
|
|
36
24
|
return;
|
|
37
25
|
}
|
|
38
|
-
|
|
26
|
+
const itemIdWithDefault = itemId ?? TREE_VIEW_ROOT_PARENT_ID;
|
|
27
|
+
if (lazyLoadingSelectors.isItemLoading(store.state, itemIdWithDefault) === isLoading) {
|
|
39
28
|
return;
|
|
40
29
|
}
|
|
41
|
-
const
|
|
30
|
+
const loading = _extends({}, store.state.lazyLoading.dataSource.loading);
|
|
42
31
|
if (isLoading === false) {
|
|
43
|
-
delete
|
|
32
|
+
delete loading[itemIdWithDefault];
|
|
44
33
|
} else {
|
|
45
|
-
|
|
34
|
+
loading[itemIdWithDefault] = isLoading;
|
|
46
35
|
}
|
|
47
36
|
store.set('lazyLoading', _extends({}, store.state.lazyLoading, {
|
|
48
37
|
dataSource: _extends({}, store.state.lazyLoading.dataSource, {
|
|
49
|
-
loading
|
|
38
|
+
loading
|
|
50
39
|
})
|
|
51
40
|
}));
|
|
52
41
|
});
|
|
53
|
-
const setDataSourceError = (itemId, error) => {
|
|
54
|
-
if (!
|
|
42
|
+
const setDataSourceError = useEventCallback((itemId, error) => {
|
|
43
|
+
if (!params.dataSource) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (lazyLoadingSelectors.itemError(store.state, itemId) === error) {
|
|
55
47
|
return;
|
|
56
48
|
}
|
|
49
|
+
const stateId = itemId ?? TREE_VIEW_ROOT_PARENT_ID;
|
|
57
50
|
const errors = _extends({}, store.state.lazyLoading.dataSource.errors);
|
|
58
|
-
if (error === null && errors[
|
|
59
|
-
delete errors[
|
|
51
|
+
if (error === null && errors[stateId] !== undefined) {
|
|
52
|
+
delete errors[stateId];
|
|
60
53
|
} else {
|
|
61
|
-
errors[
|
|
54
|
+
errors[stateId] = error;
|
|
62
55
|
}
|
|
63
|
-
errors[itemId] = error;
|
|
64
56
|
store.set('lazyLoading', _extends({}, store.state.lazyLoading, {
|
|
65
57
|
dataSource: _extends({}, store.state.lazyLoading.dataSource, {
|
|
66
58
|
errors
|
|
67
59
|
})
|
|
68
60
|
}));
|
|
69
|
-
};
|
|
70
|
-
const resetDataSourceState = useEventCallback(() => {
|
|
71
|
-
if (!isLazyLoadingEnabled) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
store.set('lazyLoading', _extends({}, store.state.lazyLoading, {
|
|
75
|
-
dataSource: INITIAL_STATE
|
|
76
|
-
}));
|
|
77
|
-
});
|
|
78
|
-
const fetchItems = useEventCallback(async parentIds => {
|
|
79
|
-
if (!isLazyLoadingEnabled) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const getChildrenCount = params.dataSource?.getChildrenCount || (() => 0);
|
|
83
|
-
const getTreeItems = params.dataSource?.getTreeItems;
|
|
84
|
-
if (!getTreeItems) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (parentIds) {
|
|
88
|
-
await nestedDataManager.queue(parentIds);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
nestedDataManager.clear();
|
|
92
|
-
// handle loading here
|
|
93
|
-
instance.setTreeViewLoading(true);
|
|
94
|
-
// reset the state if we are refetching the first visible items
|
|
95
|
-
if (lazyLoadingSelectors.dataSource(store.state) !== INITIAL_STATE) {
|
|
96
|
-
resetDataSourceState();
|
|
97
|
-
}
|
|
98
|
-
// handle caching here
|
|
99
|
-
const cachedData = cacheRef.current.get('root');
|
|
100
|
-
if (cachedData !== undefined && cachedData !== -1) {
|
|
101
|
-
instance.addItems({
|
|
102
|
-
items: cachedData,
|
|
103
|
-
depth: 0,
|
|
104
|
-
getChildrenCount
|
|
105
|
-
});
|
|
106
|
-
instance.setTreeViewLoading(false);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
try {
|
|
110
|
-
const getTreeItemsResponse = await getTreeItems();
|
|
111
|
-
|
|
112
|
-
// set caching
|
|
113
|
-
cacheRef.current.set('root', getTreeItemsResponse);
|
|
114
|
-
|
|
115
|
-
// update the items in the state
|
|
116
|
-
instance.addItems({
|
|
117
|
-
items: getTreeItemsResponse,
|
|
118
|
-
depth: 0,
|
|
119
|
-
getChildrenCount
|
|
120
|
-
});
|
|
121
|
-
} catch (error) {
|
|
122
|
-
// set the items to empty
|
|
123
|
-
instance.addItems({
|
|
124
|
-
items: [],
|
|
125
|
-
depth: 0,
|
|
126
|
-
getChildrenCount
|
|
127
|
-
});
|
|
128
|
-
// set error state
|
|
129
|
-
instance.setTreeViewError(error);
|
|
130
|
-
} finally {
|
|
131
|
-
// set loading state
|
|
132
|
-
instance.setTreeViewLoading(false);
|
|
133
|
-
}
|
|
134
61
|
});
|
|
62
|
+
const fetchItems = useEventCallback(async parentIds => nestedDataManager.queue(parentIds));
|
|
135
63
|
const fetchItemChildren = useEventCallback(async ({
|
|
136
64
|
itemId,
|
|
137
65
|
forceRefresh
|
|
138
66
|
}) => {
|
|
139
|
-
if (!
|
|
67
|
+
if (!params.dataSource) {
|
|
140
68
|
return;
|
|
141
69
|
}
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
70
|
+
const {
|
|
71
|
+
getChildrenCount,
|
|
72
|
+
getTreeItems
|
|
73
|
+
} = params.dataSource;
|
|
74
|
+
// clear the request if the item is not in the tree
|
|
75
|
+
if (itemId != null && !itemsSelectors.itemMeta(store.state, itemId)) {
|
|
145
76
|
nestedDataManager.clearPendingRequest(itemId);
|
|
146
77
|
return;
|
|
147
78
|
}
|
|
148
|
-
const parent = itemsSelectors.itemMeta(store.state, itemId);
|
|
149
|
-
if (!parent) {
|
|
150
|
-
nestedDataManager.clearPendingRequest(itemId);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const depth = parent.depth ? parent.depth + 1 : 1;
|
|
154
79
|
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
80
|
+
// reset the state if we are fetching the root items
|
|
81
|
+
if (itemId == null && lazyLoadingSelectors.dataSource(store.state) !== INITIAL_STATE) {
|
|
82
|
+
store.set('lazyLoading', _extends({}, store.state.lazyLoading, {
|
|
83
|
+
dataSource: INITIAL_STATE
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
const cacheKey = itemId ?? TREE_VIEW_ROOT_PARENT_ID;
|
|
159
87
|
if (!forceRefresh) {
|
|
160
|
-
|
|
88
|
+
// reads from the value from the cache
|
|
89
|
+
const cachedData = cache.get(cacheKey);
|
|
161
90
|
if (cachedData !== undefined && cachedData !== -1) {
|
|
162
|
-
|
|
163
|
-
|
|
91
|
+
if (itemId != null) {
|
|
92
|
+
nestedDataManager.setRequestSettled(itemId);
|
|
93
|
+
}
|
|
94
|
+
instance.setItemChildren({
|
|
164
95
|
items: cachedData,
|
|
165
|
-
depth,
|
|
166
96
|
parentId: itemId,
|
|
167
97
|
getChildrenCount
|
|
168
98
|
});
|
|
169
99
|
instance.setDataSourceLoading(itemId, false);
|
|
170
100
|
return;
|
|
171
101
|
}
|
|
102
|
+
|
|
103
|
+
// set the item loading status to true
|
|
104
|
+
instance.setDataSourceLoading(itemId, true);
|
|
172
105
|
if (cachedData === -1) {
|
|
173
106
|
instance.removeChildren(itemId);
|
|
174
107
|
}
|
|
175
108
|
}
|
|
176
|
-
|
|
109
|
+
|
|
110
|
+
// reset existing error if any
|
|
111
|
+
if (lazyLoadingSelectors.itemError(store.state, itemId)) {
|
|
177
112
|
instance.setDataSourceError(itemId, null);
|
|
178
113
|
}
|
|
179
114
|
try {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if (forceRefresh) {
|
|
187
|
-
instance.removeChildren(itemId);
|
|
115
|
+
let response;
|
|
116
|
+
if (itemId == null) {
|
|
117
|
+
response = await getTreeItems();
|
|
118
|
+
} else {
|
|
119
|
+
response = await getTreeItems(itemId);
|
|
120
|
+
nestedDataManager.setRequestSettled(itemId);
|
|
188
121
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
122
|
+
// save the response in the cache
|
|
123
|
+
cache.set(cacheKey, response);
|
|
124
|
+
// update the items in the state
|
|
125
|
+
instance.setItemChildren({
|
|
126
|
+
items: response,
|
|
192
127
|
parentId: itemId,
|
|
193
128
|
getChildrenCount
|
|
194
129
|
});
|
|
195
130
|
} catch (error) {
|
|
196
131
|
const childrenFetchError = error;
|
|
197
|
-
//
|
|
132
|
+
// set the item error in the state
|
|
198
133
|
instance.setDataSourceError(itemId, childrenFetchError);
|
|
199
|
-
|
|
134
|
+
if (forceRefresh) {
|
|
135
|
+
instance.removeChildren(itemId);
|
|
136
|
+
}
|
|
200
137
|
} finally {
|
|
201
|
-
//
|
|
138
|
+
// set the item loading status to false
|
|
202
139
|
instance.setDataSourceLoading(itemId, false);
|
|
203
|
-
|
|
140
|
+
if (itemId != null) {
|
|
141
|
+
nestedDataManager.setRequestSettled(itemId);
|
|
142
|
+
}
|
|
204
143
|
}
|
|
205
144
|
});
|
|
206
145
|
const updateItemChildren = useEventCallback(itemId => {
|
|
@@ -210,15 +149,15 @@ export const useTreeViewLazyLoading = ({
|
|
|
210
149
|
});
|
|
211
150
|
});
|
|
212
151
|
useInstanceEventHandler(instance, 'beforeItemToggleExpansion', async eventParameters => {
|
|
213
|
-
if (!
|
|
152
|
+
if (!params.dataSource || !eventParameters.shouldBeExpanded) {
|
|
214
153
|
return;
|
|
215
154
|
}
|
|
216
|
-
// prevent the default expansion behavior
|
|
217
155
|
|
|
156
|
+
// prevent the default expansion behavior
|
|
218
157
|
eventParameters.isExpansionPrevented = true;
|
|
219
158
|
await instance.fetchItems([eventParameters.itemId]);
|
|
220
|
-
const
|
|
221
|
-
if (!
|
|
159
|
+
const hasError = lazyLoadingSelectors.itemHasError(store.state, eventParameters.itemId);
|
|
160
|
+
if (!hasError) {
|
|
222
161
|
instance.applyItemExpansion({
|
|
223
162
|
itemId: eventParameters.itemId,
|
|
224
163
|
shouldBeExpanded: true,
|
|
@@ -235,29 +174,12 @@ export const useTreeViewLazyLoading = ({
|
|
|
235
174
|
}
|
|
236
175
|
}
|
|
237
176
|
});
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
const getChildrenCount = params.dataSource?.getChildrenCount || (() => 0);
|
|
245
|
-
instance.addItems({
|
|
246
|
-
items: params.items,
|
|
247
|
-
depth: 0,
|
|
248
|
-
getChildrenCount
|
|
249
|
-
});
|
|
250
|
-
} else {
|
|
251
|
-
const expandedItems = expansionSelectors.expandedItemsRaw(store.state);
|
|
252
|
-
if (expandedItems.length > 0) {
|
|
253
|
-
instance.resetItemExpansion();
|
|
254
|
-
}
|
|
255
|
-
instance.fetchItems();
|
|
256
|
-
}
|
|
257
|
-
firstRenderRef.current = false;
|
|
258
|
-
}
|
|
259
|
-
}, [instance, params.items, params.dataSource, isLazyLoadingEnabled, store]);
|
|
260
|
-
if (isLazyLoadingEnabled) {
|
|
177
|
+
useLazyLoadOnMount({
|
|
178
|
+
instance,
|
|
179
|
+
params,
|
|
180
|
+
store
|
|
181
|
+
});
|
|
182
|
+
if (params.dataSource) {
|
|
261
183
|
instance.preventItemUpdates();
|
|
262
184
|
}
|
|
263
185
|
return {
|
|
@@ -282,4 +204,48 @@ useTreeViewLazyLoading.getInitialState = () => ({
|
|
|
282
204
|
useTreeViewLazyLoading.params = {
|
|
283
205
|
dataSource: true,
|
|
284
206
|
dataSourceCache: true
|
|
285
|
-
};
|
|
207
|
+
};
|
|
208
|
+
function useLazyLoadOnMount({
|
|
209
|
+
instance,
|
|
210
|
+
params,
|
|
211
|
+
store
|
|
212
|
+
}) {
|
|
213
|
+
const firstRenderRef = React.useRef(true);
|
|
214
|
+
useEnhancedEffect(() => {
|
|
215
|
+
if (!params.dataSource || !firstRenderRef.current) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
firstRenderRef.current = false;
|
|
219
|
+
store.set('lazyLoading', _extends({}, store.state.lazyLoading, {
|
|
220
|
+
enabled: true
|
|
221
|
+
}));
|
|
222
|
+
async function fetchAllExpandedItems() {
|
|
223
|
+
async function fetchChildrenIfExpanded(parentIds) {
|
|
224
|
+
const expandedItems = parentIds.filter(id => expansionSelectors.isItemExpanded(store.state, id));
|
|
225
|
+
if (expandedItems.length > 0) {
|
|
226
|
+
const itemsToLazyLoad = expandedItems.filter(id => itemsSelectors.itemOrderedChildrenIds(store.state, id).length === 0);
|
|
227
|
+
if (itemsToLazyLoad.length > 0) {
|
|
228
|
+
await instance.fetchItems(itemsToLazyLoad);
|
|
229
|
+
}
|
|
230
|
+
const childrenIds = expandedItems.flatMap(id => itemsSelectors.itemOrderedChildrenIds(store.state, id));
|
|
231
|
+
await fetchChildrenIfExpanded(childrenIds);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (params.items.length) {
|
|
235
|
+
const newlyExpandableItems = getExpandableItemsFromDataSource(store, params.dataSource);
|
|
236
|
+
if (newlyExpandableItems.length > 0) {
|
|
237
|
+
instance.addExpandableItems(newlyExpandableItems);
|
|
238
|
+
}
|
|
239
|
+
} else {
|
|
240
|
+
await instance.fetchItemChildren({
|
|
241
|
+
itemId: null
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
await fetchChildrenIfExpanded(itemsSelectors.itemOrderedChildrenIds(store.state, null));
|
|
245
|
+
}
|
|
246
|
+
fetchAllExpandedItems();
|
|
247
|
+
}, [instance, params.items, params.dataSource, store]);
|
|
248
|
+
}
|
|
249
|
+
function getExpandableItemsFromDataSource(store, dataSource) {
|
|
250
|
+
return Object.values(store.state.items.itemMetaLookup).filter(itemMeta => !itemMeta.expandable && dataSource.getChildrenCount(store.state.items.itemModelLookup[itemMeta.id]) > 0).map(item => item.id);
|
|
251
|
+
}
|
package/index.js
CHANGED
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
exports.useTreeViewItemsReordering = void 0;
|
|
9
9
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
10
10
|
var React = _interopRequireWildcard(require("react"));
|
|
11
|
-
var
|
|
11
|
+
var _useIsoLayoutEffect = require("@base-ui-components/utils/useIsoLayoutEffect");
|
|
12
12
|
var _internals = require("@mui/x-tree-view/internals");
|
|
13
13
|
var _useTreeViewItemsReordering = require("./useTreeViewItemsReordering.utils");
|
|
14
14
|
var _useTreeViewItemsReordering2 = require("./useTreeViewItemsReordering.itemPlugin");
|
|
@@ -179,7 +179,7 @@ const useTreeViewItemsReordering = ({
|
|
|
179
179
|
})
|
|
180
180
|
}));
|
|
181
181
|
}, [store, params.itemChildrenIndentation]);
|
|
182
|
-
(0,
|
|
182
|
+
(0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
|
|
183
183
|
store.set('itemsReordering', (0, _extends2.default)({}, store.state.itemsReordering, {
|
|
184
184
|
isItemReorderable: params.itemsReordering ? params.isItemReorderable ?? (() => true) : () => false
|
|
185
185
|
}));
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { TreeViewPlugin } from '@mui/x-tree-view/internals';
|
|
2
|
-
import type { UseTreeViewLazyLoadingSignature } from '@mui/x-tree-view/internals';
|
|
1
|
+
import { TreeViewPlugin, UseTreeViewLazyLoadingSignature } from '@mui/x-tree-view/internals';
|
|
3
2
|
export declare const useTreeViewLazyLoading: TreeViewPlugin<UseTreeViewLazyLoadingSignature>;
|
|
@@ -9,8 +9,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
9
9
|
exports.useTreeViewLazyLoading = void 0;
|
|
10
10
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
11
11
|
var React = _interopRequireWildcard(require("react"));
|
|
12
|
-
var
|
|
13
|
-
var _useEventCallback =
|
|
12
|
+
var _useRefWithInit = require("@base-ui-components/utils/useRefWithInit");
|
|
13
|
+
var _useEventCallback = require("@base-ui-components/utils/useEventCallback");
|
|
14
|
+
var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
|
|
14
15
|
var _internals = require("@mui/x-tree-view/internals");
|
|
15
16
|
var _utils = require("@mui/x-tree-view/utils");
|
|
16
17
|
var _utils2 = require("./utils");
|
|
@@ -18,214 +19,152 @@ const INITIAL_STATE = {
|
|
|
18
19
|
loading: {},
|
|
19
20
|
errors: {}
|
|
20
21
|
};
|
|
21
|
-
const noopCache = {
|
|
22
|
-
clear: () => {},
|
|
23
|
-
get: () => undefined,
|
|
24
|
-
set: () => {}
|
|
25
|
-
};
|
|
26
|
-
function getCache(cacheProp) {
|
|
27
|
-
if (cacheProp === null) {
|
|
28
|
-
return noopCache;
|
|
29
|
-
}
|
|
30
|
-
return cacheProp ?? new _utils.DataSourceCacheDefault({});
|
|
31
|
-
}
|
|
32
22
|
const useTreeViewLazyLoading = ({
|
|
33
23
|
instance,
|
|
34
24
|
params,
|
|
35
25
|
store
|
|
36
26
|
}) => {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
const setDataSourceLoading = (0, _useEventCallback.default)((itemId, isLoading) => {
|
|
42
|
-
if (!isLazyLoadingEnabled) {
|
|
27
|
+
const nestedDataManager = (0, _useRefWithInit.useRefWithInit)(() => new _utils2.NestedDataManager(instance)).current;
|
|
28
|
+
const cache = (0, _useRefWithInit.useRefWithInit)(() => params.dataSourceCache ?? new _utils.DataSourceCacheDefault({})).current;
|
|
29
|
+
const setDataSourceLoading = (0, _useEventCallback.useEventCallback)((itemId, isLoading) => {
|
|
30
|
+
if (!params.dataSource) {
|
|
43
31
|
return;
|
|
44
32
|
}
|
|
45
|
-
|
|
33
|
+
const itemIdWithDefault = itemId ?? _internals.TREE_VIEW_ROOT_PARENT_ID;
|
|
34
|
+
if (_internals.lazyLoadingSelectors.isItemLoading(store.state, itemIdWithDefault) === isLoading) {
|
|
46
35
|
return;
|
|
47
36
|
}
|
|
48
|
-
const
|
|
37
|
+
const loading = (0, _extends2.default)({}, store.state.lazyLoading.dataSource.loading);
|
|
49
38
|
if (isLoading === false) {
|
|
50
|
-
delete
|
|
39
|
+
delete loading[itemIdWithDefault];
|
|
51
40
|
} else {
|
|
52
|
-
|
|
41
|
+
loading[itemIdWithDefault] = isLoading;
|
|
53
42
|
}
|
|
54
43
|
store.set('lazyLoading', (0, _extends2.default)({}, store.state.lazyLoading, {
|
|
55
44
|
dataSource: (0, _extends2.default)({}, store.state.lazyLoading.dataSource, {
|
|
56
|
-
loading
|
|
45
|
+
loading
|
|
57
46
|
})
|
|
58
47
|
}));
|
|
59
48
|
});
|
|
60
|
-
const setDataSourceError = (itemId, error) => {
|
|
61
|
-
if (!
|
|
49
|
+
const setDataSourceError = (0, _useEventCallback.useEventCallback)((itemId, error) => {
|
|
50
|
+
if (!params.dataSource) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (_internals.lazyLoadingSelectors.itemError(store.state, itemId) === error) {
|
|
62
54
|
return;
|
|
63
55
|
}
|
|
56
|
+
const stateId = itemId ?? _internals.TREE_VIEW_ROOT_PARENT_ID;
|
|
64
57
|
const errors = (0, _extends2.default)({}, store.state.lazyLoading.dataSource.errors);
|
|
65
|
-
if (error === null && errors[
|
|
66
|
-
delete errors[
|
|
58
|
+
if (error === null && errors[stateId] !== undefined) {
|
|
59
|
+
delete errors[stateId];
|
|
67
60
|
} else {
|
|
68
|
-
errors[
|
|
61
|
+
errors[stateId] = error;
|
|
69
62
|
}
|
|
70
|
-
errors[itemId] = error;
|
|
71
63
|
store.set('lazyLoading', (0, _extends2.default)({}, store.state.lazyLoading, {
|
|
72
64
|
dataSource: (0, _extends2.default)({}, store.state.lazyLoading.dataSource, {
|
|
73
65
|
errors
|
|
74
66
|
})
|
|
75
67
|
}));
|
|
76
|
-
};
|
|
77
|
-
const resetDataSourceState = (0, _useEventCallback.default)(() => {
|
|
78
|
-
if (!isLazyLoadingEnabled) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
store.set('lazyLoading', (0, _extends2.default)({}, store.state.lazyLoading, {
|
|
82
|
-
dataSource: INITIAL_STATE
|
|
83
|
-
}));
|
|
84
68
|
});
|
|
85
|
-
const fetchItems = (0, _useEventCallback.
|
|
86
|
-
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const getChildrenCount = params.dataSource?.getChildrenCount || (() => 0);
|
|
90
|
-
const getTreeItems = params.dataSource?.getTreeItems;
|
|
91
|
-
if (!getTreeItems) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
if (parentIds) {
|
|
95
|
-
await nestedDataManager.queue(parentIds);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
nestedDataManager.clear();
|
|
99
|
-
// handle loading here
|
|
100
|
-
instance.setTreeViewLoading(true);
|
|
101
|
-
// reset the state if we are refetching the first visible items
|
|
102
|
-
if (_internals.lazyLoadingSelectors.dataSource(store.state) !== INITIAL_STATE) {
|
|
103
|
-
resetDataSourceState();
|
|
104
|
-
}
|
|
105
|
-
// handle caching here
|
|
106
|
-
const cachedData = cacheRef.current.get('root');
|
|
107
|
-
if (cachedData !== undefined && cachedData !== -1) {
|
|
108
|
-
instance.addItems({
|
|
109
|
-
items: cachedData,
|
|
110
|
-
depth: 0,
|
|
111
|
-
getChildrenCount
|
|
112
|
-
});
|
|
113
|
-
instance.setTreeViewLoading(false);
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
try {
|
|
117
|
-
const getTreeItemsResponse = await getTreeItems();
|
|
118
|
-
|
|
119
|
-
// set caching
|
|
120
|
-
cacheRef.current.set('root', getTreeItemsResponse);
|
|
121
|
-
|
|
122
|
-
// update the items in the state
|
|
123
|
-
instance.addItems({
|
|
124
|
-
items: getTreeItemsResponse,
|
|
125
|
-
depth: 0,
|
|
126
|
-
getChildrenCount
|
|
127
|
-
});
|
|
128
|
-
} catch (error) {
|
|
129
|
-
// set the items to empty
|
|
130
|
-
instance.addItems({
|
|
131
|
-
items: [],
|
|
132
|
-
depth: 0,
|
|
133
|
-
getChildrenCount
|
|
134
|
-
});
|
|
135
|
-
// set error state
|
|
136
|
-
instance.setTreeViewError(error);
|
|
137
|
-
} finally {
|
|
138
|
-
// set loading state
|
|
139
|
-
instance.setTreeViewLoading(false);
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
const fetchItemChildren = (0, _useEventCallback.default)(async ({
|
|
69
|
+
const fetchItems = (0, _useEventCallback.useEventCallback)(async parentIds => nestedDataManager.queue(parentIds));
|
|
70
|
+
const fetchItemChildren = (0, _useEventCallback.useEventCallback)(async ({
|
|
143
71
|
itemId,
|
|
144
72
|
forceRefresh
|
|
145
73
|
}) => {
|
|
146
|
-
if (!
|
|
74
|
+
if (!params.dataSource) {
|
|
147
75
|
return;
|
|
148
76
|
}
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
77
|
+
const {
|
|
78
|
+
getChildrenCount,
|
|
79
|
+
getTreeItems
|
|
80
|
+
} = params.dataSource;
|
|
81
|
+
// clear the request if the item is not in the tree
|
|
82
|
+
if (itemId != null && !_internals.itemsSelectors.itemMeta(store.state, itemId)) {
|
|
152
83
|
nestedDataManager.clearPendingRequest(itemId);
|
|
153
84
|
return;
|
|
154
85
|
}
|
|
155
|
-
const parent = _internals.itemsSelectors.itemMeta(store.state, itemId);
|
|
156
|
-
if (!parent) {
|
|
157
|
-
nestedDataManager.clearPendingRequest(itemId);
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
const depth = parent.depth ? parent.depth + 1 : 1;
|
|
161
86
|
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
87
|
+
// reset the state if we are fetching the root items
|
|
88
|
+
if (itemId == null && _internals.lazyLoadingSelectors.dataSource(store.state) !== INITIAL_STATE) {
|
|
89
|
+
store.set('lazyLoading', (0, _extends2.default)({}, store.state.lazyLoading, {
|
|
90
|
+
dataSource: INITIAL_STATE
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
const cacheKey = itemId ?? _internals.TREE_VIEW_ROOT_PARENT_ID;
|
|
166
94
|
if (!forceRefresh) {
|
|
167
|
-
|
|
95
|
+
// reads from the value from the cache
|
|
96
|
+
const cachedData = cache.get(cacheKey);
|
|
168
97
|
if (cachedData !== undefined && cachedData !== -1) {
|
|
169
|
-
|
|
170
|
-
|
|
98
|
+
if (itemId != null) {
|
|
99
|
+
nestedDataManager.setRequestSettled(itemId);
|
|
100
|
+
}
|
|
101
|
+
instance.setItemChildren({
|
|
171
102
|
items: cachedData,
|
|
172
|
-
depth,
|
|
173
103
|
parentId: itemId,
|
|
174
104
|
getChildrenCount
|
|
175
105
|
});
|
|
176
106
|
instance.setDataSourceLoading(itemId, false);
|
|
177
107
|
return;
|
|
178
108
|
}
|
|
109
|
+
|
|
110
|
+
// set the item loading status to true
|
|
111
|
+
instance.setDataSourceLoading(itemId, true);
|
|
179
112
|
if (cachedData === -1) {
|
|
180
113
|
instance.removeChildren(itemId);
|
|
181
114
|
}
|
|
182
115
|
}
|
|
183
|
-
|
|
116
|
+
|
|
117
|
+
// reset existing error if any
|
|
118
|
+
if (_internals.lazyLoadingSelectors.itemError(store.state, itemId)) {
|
|
184
119
|
instance.setDataSourceError(itemId, null);
|
|
185
120
|
}
|
|
186
121
|
try {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (forceRefresh) {
|
|
194
|
-
instance.removeChildren(itemId);
|
|
122
|
+
let response;
|
|
123
|
+
if (itemId == null) {
|
|
124
|
+
response = await getTreeItems();
|
|
125
|
+
} else {
|
|
126
|
+
response = await getTreeItems(itemId);
|
|
127
|
+
nestedDataManager.setRequestSettled(itemId);
|
|
195
128
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
129
|
+
// save the response in the cache
|
|
130
|
+
cache.set(cacheKey, response);
|
|
131
|
+
// update the items in the state
|
|
132
|
+
instance.setItemChildren({
|
|
133
|
+
items: response,
|
|
199
134
|
parentId: itemId,
|
|
200
135
|
getChildrenCount
|
|
201
136
|
});
|
|
202
137
|
} catch (error) {
|
|
203
138
|
const childrenFetchError = error;
|
|
204
|
-
//
|
|
139
|
+
// set the item error in the state
|
|
205
140
|
instance.setDataSourceError(itemId, childrenFetchError);
|
|
206
|
-
|
|
141
|
+
if (forceRefresh) {
|
|
142
|
+
instance.removeChildren(itemId);
|
|
143
|
+
}
|
|
207
144
|
} finally {
|
|
208
|
-
//
|
|
145
|
+
// set the item loading status to false
|
|
209
146
|
instance.setDataSourceLoading(itemId, false);
|
|
210
|
-
|
|
147
|
+
if (itemId != null) {
|
|
148
|
+
nestedDataManager.setRequestSettled(itemId);
|
|
149
|
+
}
|
|
211
150
|
}
|
|
212
151
|
});
|
|
213
|
-
const updateItemChildren = (0, _useEventCallback.
|
|
152
|
+
const updateItemChildren = (0, _useEventCallback.useEventCallback)(itemId => {
|
|
214
153
|
return instance.fetchItemChildren({
|
|
215
154
|
itemId,
|
|
216
155
|
forceRefresh: true
|
|
217
156
|
});
|
|
218
157
|
});
|
|
219
158
|
(0, _internals.useInstanceEventHandler)(instance, 'beforeItemToggleExpansion', async eventParameters => {
|
|
220
|
-
if (!
|
|
159
|
+
if (!params.dataSource || !eventParameters.shouldBeExpanded) {
|
|
221
160
|
return;
|
|
222
161
|
}
|
|
223
|
-
// prevent the default expansion behavior
|
|
224
162
|
|
|
163
|
+
// prevent the default expansion behavior
|
|
225
164
|
eventParameters.isExpansionPrevented = true;
|
|
226
165
|
await instance.fetchItems([eventParameters.itemId]);
|
|
227
|
-
const
|
|
228
|
-
if (!
|
|
166
|
+
const hasError = _internals.lazyLoadingSelectors.itemHasError(store.state, eventParameters.itemId);
|
|
167
|
+
if (!hasError) {
|
|
229
168
|
instance.applyItemExpansion({
|
|
230
169
|
itemId: eventParameters.itemId,
|
|
231
170
|
shouldBeExpanded: true,
|
|
@@ -242,29 +181,12 @@ const useTreeViewLazyLoading = ({
|
|
|
242
181
|
}
|
|
243
182
|
}
|
|
244
183
|
});
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const getChildrenCount = params.dataSource?.getChildrenCount || (() => 0);
|
|
252
|
-
instance.addItems({
|
|
253
|
-
items: params.items,
|
|
254
|
-
depth: 0,
|
|
255
|
-
getChildrenCount
|
|
256
|
-
});
|
|
257
|
-
} else {
|
|
258
|
-
const expandedItems = _internals.expansionSelectors.expandedItemsRaw(store.state);
|
|
259
|
-
if (expandedItems.length > 0) {
|
|
260
|
-
instance.resetItemExpansion();
|
|
261
|
-
}
|
|
262
|
-
instance.fetchItems();
|
|
263
|
-
}
|
|
264
|
-
firstRenderRef.current = false;
|
|
265
|
-
}
|
|
266
|
-
}, [instance, params.items, params.dataSource, isLazyLoadingEnabled, store]);
|
|
267
|
-
if (isLazyLoadingEnabled) {
|
|
184
|
+
useLazyLoadOnMount({
|
|
185
|
+
instance,
|
|
186
|
+
params,
|
|
187
|
+
store
|
|
188
|
+
});
|
|
189
|
+
if (params.dataSource) {
|
|
268
190
|
instance.preventItemUpdates();
|
|
269
191
|
}
|
|
270
192
|
return {
|
|
@@ -290,4 +212,48 @@ useTreeViewLazyLoading.getInitialState = () => ({
|
|
|
290
212
|
useTreeViewLazyLoading.params = {
|
|
291
213
|
dataSource: true,
|
|
292
214
|
dataSourceCache: true
|
|
293
|
-
};
|
|
215
|
+
};
|
|
216
|
+
function useLazyLoadOnMount({
|
|
217
|
+
instance,
|
|
218
|
+
params,
|
|
219
|
+
store
|
|
220
|
+
}) {
|
|
221
|
+
const firstRenderRef = React.useRef(true);
|
|
222
|
+
(0, _useEnhancedEffect.default)(() => {
|
|
223
|
+
if (!params.dataSource || !firstRenderRef.current) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
firstRenderRef.current = false;
|
|
227
|
+
store.set('lazyLoading', (0, _extends2.default)({}, store.state.lazyLoading, {
|
|
228
|
+
enabled: true
|
|
229
|
+
}));
|
|
230
|
+
async function fetchAllExpandedItems() {
|
|
231
|
+
async function fetchChildrenIfExpanded(parentIds) {
|
|
232
|
+
const expandedItems = parentIds.filter(id => _internals.expansionSelectors.isItemExpanded(store.state, id));
|
|
233
|
+
if (expandedItems.length > 0) {
|
|
234
|
+
const itemsToLazyLoad = expandedItems.filter(id => _internals.itemsSelectors.itemOrderedChildrenIds(store.state, id).length === 0);
|
|
235
|
+
if (itemsToLazyLoad.length > 0) {
|
|
236
|
+
await instance.fetchItems(itemsToLazyLoad);
|
|
237
|
+
}
|
|
238
|
+
const childrenIds = expandedItems.flatMap(id => _internals.itemsSelectors.itemOrderedChildrenIds(store.state, id));
|
|
239
|
+
await fetchChildrenIfExpanded(childrenIds);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (params.items.length) {
|
|
243
|
+
const newlyExpandableItems = getExpandableItemsFromDataSource(store, params.dataSource);
|
|
244
|
+
if (newlyExpandableItems.length > 0) {
|
|
245
|
+
instance.addExpandableItems(newlyExpandableItems);
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
await instance.fetchItemChildren({
|
|
249
|
+
itemId: null
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
await fetchChildrenIfExpanded(_internals.itemsSelectors.itemOrderedChildrenIds(store.state, null));
|
|
253
|
+
}
|
|
254
|
+
fetchAllExpandedItems();
|
|
255
|
+
}, [instance, params.items, params.dataSource, store]);
|
|
256
|
+
}
|
|
257
|
+
function getExpandableItemsFromDataSource(store, dataSource) {
|
|
258
|
+
return Object.values(store.state.items.itemMetaLookup).filter(itemMeta => !itemMeta.expandable && dataSource.getChildrenCount(store.state.items.itemModelLookup[itemMeta.id]) > 0).map(item => item.id);
|
|
259
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/x-tree-view-pro",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.13.1",
|
|
4
4
|
"author": "MUI Team",
|
|
5
5
|
"description": "The Pro plan edition of the MUI X Tree View components.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"directory": "packages/x-tree-view-pro"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@babel/runtime": "^7.28.
|
|
34
|
+
"@babel/runtime": "^7.28.4",
|
|
35
35
|
"@base-ui-components/utils": "0.1.1",
|
|
36
36
|
"@mui/utils": "^7.3.2",
|
|
37
37
|
"@types/react-transition-group": "^4.4.12",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"react-transition-group": "^4.4.5",
|
|
41
41
|
"reselect": "^5.1.1",
|
|
42
42
|
"use-sync-external-store": "^1.5.0",
|
|
43
|
-
"@mui/x-internals": "8.
|
|
44
|
-
"@mui/x-
|
|
45
|
-
"@mui/x-
|
|
43
|
+
"@mui/x-internals": "8.13.1",
|
|
44
|
+
"@mui/x-license": "8.12.0",
|
|
45
|
+
"@mui/x-tree-view": "8.13.1"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@emotion/react": "^11.9.0",
|