@mui/x-tree-view 8.27.1 → 8.28.3
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 +455 -0
- package/esm/index.js +1 -1
- package/esm/internals/plugins/focus/TreeViewFocusPlugin.js +16 -9
- package/esm/internals/plugins/items/selectors.js +1 -1
- package/esm/internals/plugins/jsxItems/TreeViewJSXItemsPlugin.d.ts +9 -4
- package/esm/internals/plugins/jsxItems/TreeViewJSXItemsPlugin.js +44 -17
- package/esm/internals/plugins/jsxItems/itemPlugin.js +18 -3
- package/esm/utils/cache.d.ts +8 -9
- package/index.js +1 -1
- package/internals/plugins/focus/TreeViewFocusPlugin.js +16 -9
- package/internals/plugins/items/selectors.js +1 -1
- package/internals/plugins/jsxItems/TreeViewJSXItemsPlugin.d.ts +9 -4
- package/internals/plugins/jsxItems/TreeViewJSXItemsPlugin.js +43 -16
- package/internals/plugins/jsxItems/itemPlugin.js +18 -3
- package/package.json +1 -1
- package/utils/cache.d.ts +8 -9
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,461 @@
|
|
|
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.28.3
|
|
9
|
+
|
|
10
|
+
_Apr 15, 2026_
|
|
11
|
+
|
|
12
|
+
We'd like to extend a big thank you to the 6 contributors who made this release possible. Here are some highlights ✨:
|
|
13
|
+
|
|
14
|
+
- 🐞 Bugfixes
|
|
15
|
+
|
|
16
|
+
Special thanks go out to this community member for their valuable contribution:
|
|
17
|
+
@nk10nikhil
|
|
18
|
+
|
|
19
|
+
The following team members contributed to this release:
|
|
20
|
+
@flaviendelangle, @LukasTy, @MBilalShafi, @michelengelen, @sai6855
|
|
21
|
+
|
|
22
|
+
### Data Grid
|
|
23
|
+
|
|
24
|
+
#### `@mui/x-data-grid@8.28.2`
|
|
25
|
+
|
|
26
|
+
Internal changes.
|
|
27
|
+
|
|
28
|
+
#### `@mui/x-data-grid-pro@8.28.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
29
|
+
|
|
30
|
+
Same changes as in `@mui/x-data-grid@8.28.2`, plus:
|
|
31
|
+
|
|
32
|
+
- [DataGridPro] Improve trigger for nested row reordering (#21996) @MBilalShafi
|
|
33
|
+
|
|
34
|
+
#### `@mui/x-data-grid-premium@8.28.2` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
35
|
+
|
|
36
|
+
Same changes as in `@mui/x-data-grid-pro@8.28.2`.
|
|
37
|
+
|
|
38
|
+
### Date and Time Pickers
|
|
39
|
+
|
|
40
|
+
#### `@mui/x-date-pickers@8.28.3`
|
|
41
|
+
|
|
42
|
+
- [pickers] Ensure correct `display` property on Day component (#21980) @LukasTy
|
|
43
|
+
|
|
44
|
+
#### `@mui/x-date-pickers-pro@8.28.3` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
45
|
+
|
|
46
|
+
Same changes as in `@mui/x-date-pickers@8.28.3`.
|
|
47
|
+
|
|
48
|
+
### Charts
|
|
49
|
+
|
|
50
|
+
#### `@mui/x-charts@8.28.2`
|
|
51
|
+
|
|
52
|
+
- [charts] Add missing export for `ChartsBrushOverlay` (#21993) (#22008) @nk10nikhil
|
|
53
|
+
|
|
54
|
+
#### `@mui/x-charts-pro@8.28.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
55
|
+
|
|
56
|
+
Same changes as in `@mui/x-charts@8.28.2`.
|
|
57
|
+
|
|
58
|
+
#### `@mui/x-charts-premium@8.28.2` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
59
|
+
|
|
60
|
+
Same changes as in `@mui/x-charts-pro@8.28.2`.
|
|
61
|
+
|
|
62
|
+
### Tree View
|
|
63
|
+
|
|
64
|
+
#### `@mui/x-tree-view@8.28.3`
|
|
65
|
+
|
|
66
|
+
- [tree view] Move `lazyLoadedItems` initialization to state initializer (#22087) @michelengelen
|
|
67
|
+
|
|
68
|
+
#### `@mui/x-tree-view-pro@8.28.3` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
69
|
+
|
|
70
|
+
Same changes as in `@mui/x-tree-view@8.28.3`, plus:
|
|
71
|
+
|
|
72
|
+
- [RichTreeViewPro] Allow to auto-expand lazy loaded items (#21957) @flaviendelangle
|
|
73
|
+
|
|
74
|
+
### Docs
|
|
75
|
+
|
|
76
|
+
- [docs] Fix `TreeDataFullExample` data grid demo crash (#22007) @sai6855
|
|
77
|
+
|
|
78
|
+
### Miscellaneous
|
|
79
|
+
|
|
80
|
+
- [core] Post v9 stable updates (#22035) @LukasTy
|
|
81
|
+
|
|
82
|
+
## 8.28.2
|
|
83
|
+
|
|
84
|
+
_Apr 1, 2026_
|
|
85
|
+
|
|
86
|
+
We'd like to extend a big thank you to the 4 contributors who made this release possible.
|
|
87
|
+
|
|
88
|
+
Special thanks go out to this community member for their valuable contribution:
|
|
89
|
+
@mixelburg, @sibananda485
|
|
90
|
+
|
|
91
|
+
The following team members contributed to this release:
|
|
92
|
+
@dav-is, @JCQuintas
|
|
93
|
+
|
|
94
|
+
### Data Grid
|
|
95
|
+
|
|
96
|
+
#### `@mui/x-data-grid@8.28.2`
|
|
97
|
+
|
|
98
|
+
- [DataGrid] Export `GridColumnUnsortedIconProps` for custom column icon slots (#21898) @mixelburg
|
|
99
|
+
|
|
100
|
+
#### `@mui/x-data-grid-pro@8.28.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
101
|
+
|
|
102
|
+
Same changes as in `@mui/x-data-grid@8.28.2`.
|
|
103
|
+
|
|
104
|
+
#### `@mui/x-data-grid-premium@8.28.2` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
105
|
+
|
|
106
|
+
Same changes as in `@mui/x-data-grid-pro@8.28.2`, plus:
|
|
107
|
+
|
|
108
|
+
- [DataGridPremium] Fix clipboard paste issue in portal (#21949) @sibananda485
|
|
109
|
+
|
|
110
|
+
### Charts
|
|
111
|
+
|
|
112
|
+
#### `@mui/x-charts@8.28.2`
|
|
113
|
+
|
|
114
|
+
- [charts] Fix zoom slider preview with discard filter mode (#21906) @JCQuintas
|
|
115
|
+
|
|
116
|
+
#### `@mui/x-charts-pro@8.28.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
117
|
+
|
|
118
|
+
Same changes as in `@mui/x-charts@8.28.2`.
|
|
119
|
+
|
|
120
|
+
#### `@mui/x-charts-premium@8.28.2` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
121
|
+
|
|
122
|
+
Same changes as in `@mui/x-charts-pro@8.28.2`.
|
|
123
|
+
|
|
124
|
+
### Docs
|
|
125
|
+
|
|
126
|
+
- [docs] Fix JSDOM → jsdom casing (#21908) @JCQuintas
|
|
127
|
+
|
|
128
|
+
### Core
|
|
129
|
+
|
|
130
|
+
- [docs-infra] Set `SEARCH_INDEX` Env for v8 (#21875) @dav-is
|
|
131
|
+
|
|
132
|
+
## 8.28.1
|
|
133
|
+
|
|
134
|
+
_Mar 26, 2026_
|
|
135
|
+
|
|
136
|
+
We'd like to extend a big thank you to the 2 contributors who made this release possible.
|
|
137
|
+
|
|
138
|
+
The following team members contributed to this release:
|
|
139
|
+
@arminmeh, @cherniavskii
|
|
140
|
+
|
|
141
|
+
### Data Grid
|
|
142
|
+
|
|
143
|
+
#### `@mui/x-data-grid@8.28.1`
|
|
144
|
+
|
|
145
|
+
- [DataGrid] Prevent repeated `hasScrollbar` state updates (#21847) @arminmeh
|
|
146
|
+
|
|
147
|
+
#### `@mui/x-data-grid-pro@8.28.1` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
148
|
+
|
|
149
|
+
Same changes as in `@mui/x-data-grid@8.28.1`, plus:
|
|
150
|
+
|
|
151
|
+
- [DataGridPro] `fetchRows()` API's default `start` and `end` params based on scroll position with lazy loading (#21811) @arminmeh
|
|
152
|
+
|
|
153
|
+
#### `@mui/x-data-grid-premium@8.28.1` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
154
|
+
|
|
155
|
+
Same changes as in `@mui/x-data-grid-pro@8.28.1`.
|
|
156
|
+
|
|
157
|
+
### Core
|
|
158
|
+
|
|
159
|
+
- [internal] Remove headless data grid packages (#21848) @cherniavskii
|
|
160
|
+
|
|
161
|
+
## 8.28.0
|
|
162
|
+
|
|
163
|
+
_Mar 19, 2026_
|
|
164
|
+
|
|
165
|
+
We'd like to extend a big thank you to the 5 contributors who made this release possible.
|
|
166
|
+
|
|
167
|
+
The following team members contributed to this release:
|
|
168
|
+
@alexfauquette, @brijeshb42, @Janpot, @JCQuintas, @sai6855
|
|
169
|
+
|
|
170
|
+
### Data Grid
|
|
171
|
+
|
|
172
|
+
#### `@mui/x-data-grid@8.28.0`
|
|
173
|
+
|
|
174
|
+
- [DataGrid] Move `elementOverrides` to constants and remove duplicates (@sai6855) (#21752) @github-actions[bot]
|
|
175
|
+
|
|
176
|
+
#### `@mui/x-data-grid-pro@8.28.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
177
|
+
|
|
178
|
+
Same changes as in `@mui/x-data-grid@8.28.0`.
|
|
179
|
+
|
|
180
|
+
#### `@mui/x-data-grid-premium@8.28.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
181
|
+
|
|
182
|
+
Same changes as in `@mui/x-data-grid-pro@8.28.0`.
|
|
183
|
+
|
|
184
|
+
### Date and Time Pickers
|
|
185
|
+
|
|
186
|
+
#### `@mui/x-date-pickers@8.27.2`
|
|
187
|
+
|
|
188
|
+
Internal changes.
|
|
189
|
+
|
|
190
|
+
#### `@mui/x-date-pickers-pro@8.27.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
191
|
+
|
|
192
|
+
Same changes as in `@mui/x-date-pickers@8.27.2`.
|
|
193
|
+
|
|
194
|
+
### Charts
|
|
195
|
+
|
|
196
|
+
#### `@mui/x-charts@8.28.0`
|
|
197
|
+
|
|
198
|
+
- [charts] Improve deprecation warnings (#21760) (#21767) @alexfauquette
|
|
199
|
+
- [charts] Refactor `FunnelChart` classes structure (@JCQuintas) (#21763) @github-actions[bot]
|
|
200
|
+
- [charts] Refactor `Heatmap` classes structure (#21653) (#21745) @JCQuintas
|
|
201
|
+
- [charts] Refactor `PieChart` classes structure (@JCQuintas) (#21715) @github-actions[bot]
|
|
202
|
+
- [charts] Refactor `RadarChart` classes structure (@JCQuintas) (#21730) @github-actions[bot]
|
|
203
|
+
- [charts] Refactor `SankeyChart` classes structure (#21654) (#21726) @JCQuintas
|
|
204
|
+
- [charts] Rename `data-series-id` by `data-series` (#21761) (#21772) @alexfauquette
|
|
205
|
+
|
|
206
|
+
#### `@mui/x-charts-pro@8.28.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
207
|
+
|
|
208
|
+
Same changes as in `@mui/x-charts@8.28.0`, plus:
|
|
209
|
+
|
|
210
|
+
- [charts-pro] Allow `brush` interaction to accept `requiredKeys/pointerMode` (#21723) @JCQuintas
|
|
211
|
+
|
|
212
|
+
#### `@mui/x-charts-premium@8.28.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
213
|
+
|
|
214
|
+
Same changes as in `@mui/x-charts-pro@8.28.0`.
|
|
215
|
+
|
|
216
|
+
### Tree View
|
|
217
|
+
|
|
218
|
+
#### `@mui/x-tree-view@8.27.2`
|
|
219
|
+
|
|
220
|
+
Internal changes.
|
|
221
|
+
|
|
222
|
+
#### `@mui/x-tree-view-pro@8.27.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
223
|
+
|
|
224
|
+
Same changes as in `@mui/x-tree-view@8.27.2`.
|
|
225
|
+
|
|
226
|
+
### Codemod
|
|
227
|
+
|
|
228
|
+
#### `@mui/x-codemod@8.27.0`
|
|
229
|
+
|
|
230
|
+
Internal changes.
|
|
231
|
+
|
|
232
|
+
### Core
|
|
233
|
+
|
|
234
|
+
- [code-infra] Fix contributor generation in changelog (#21712) @brijeshb42
|
|
235
|
+
- [code-infra] Install pkg-pr-new (#21778) @Janpot
|
|
236
|
+
|
|
237
|
+
## 8.27.5
|
|
238
|
+
|
|
239
|
+
_Mar 11, 2026_
|
|
240
|
+
|
|
241
|
+
We'd like to extend a big thank you to the 7 contributors who made this release possible. Here are some highlights ✨:
|
|
242
|
+
|
|
243
|
+
- 🐞 Bugfixes
|
|
244
|
+
|
|
245
|
+
The following team members contributed to this release:
|
|
246
|
+
@bernardobelchior, @JCQuintas, @MBilalShafi, @michelengelen, @mj12albert, @sai6855, @siriwatknp
|
|
247
|
+
|
|
248
|
+
### Data Grid
|
|
249
|
+
|
|
250
|
+
#### `@mui/x-data-grid@8.27.5`
|
|
251
|
+
|
|
252
|
+
- [DataGrid] Fix crash when `rows` and `rowModesModel` are updated simultaneously (#21684) @michelengelen
|
|
253
|
+
- [DataGrid] Forward rest props in `GridFilterInputMultipleValue` (#21444) @siriwatknp
|
|
254
|
+
- [DataGrid] Remove double rtl inversion logic for columns pinning (#21443) @siriwatknp
|
|
255
|
+
- [DataGrid] Add missing `resizablePanelHandle` classes to `gridClasses` object (#21632) @sai6855
|
|
256
|
+
- [DataGrid] Refactor `headerAlign` style calls (#21633) @sai6855
|
|
257
|
+
- [DataGrid] Fix keyboard navigation with single-row checkbox selection (#21529) @mj12albert
|
|
258
|
+
|
|
259
|
+
#### `@mui/x-data-grid-pro@8.27.5` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
260
|
+
|
|
261
|
+
Same changes as in `@mui/x-data-grid@8.27.5`, plus:
|
|
262
|
+
|
|
263
|
+
- [DataGridPro] Add `role="presentation"` to detail panel toggle header content (#21691) @michelengelen
|
|
264
|
+
- [DataGridPro] Fix sorting not reflected in nested server-side data (#21641) @MBilalShafi
|
|
265
|
+
|
|
266
|
+
#### `@mui/x-data-grid-premium@8.27.5` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
267
|
+
|
|
268
|
+
Same changes as in `@mui/x-data-grid-pro@8.27.5`.
|
|
269
|
+
|
|
270
|
+
### Charts
|
|
271
|
+
|
|
272
|
+
#### `@mui/x-charts@8.27.5`
|
|
273
|
+
|
|
274
|
+
- [charts] Refactor `BarChart` classes structure (#21601) (#21644) @JCQuintas
|
|
275
|
+
- [charts] Refactor `LineChart` classes structure (#21672) @JCQuintas
|
|
276
|
+
- [charts] Refactor `ScatterChart` classes structure (#21706) @JCQuintas
|
|
277
|
+
|
|
278
|
+
#### `@mui/x-charts-pro@8.27.5` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
279
|
+
|
|
280
|
+
Same changes as in `@mui/x-charts@8.27.5`, plus:
|
|
281
|
+
|
|
282
|
+
- [charts-pro] Fix image export truncated when page is zoomed out (#21696) @bernardobelchior
|
|
283
|
+
|
|
284
|
+
#### `@mui/x-charts-premium@8.27.5` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
285
|
+
|
|
286
|
+
Same changes as in `@mui/x-charts-pro@8.27.5`.
|
|
287
|
+
|
|
288
|
+
### Docs
|
|
289
|
+
|
|
290
|
+
- [docs] Fix `AssistantWithDataSource` demo crashing (#21631) @sai6855
|
|
291
|
+
- [docs] Move Range Bar Chart to existing charts (#21122) @bernardobelchior
|
|
292
|
+
|
|
293
|
+
### Core
|
|
294
|
+
|
|
295
|
+
- [code-infra] Fix datagrid test flakyness (#21657) @JCQuintas
|
|
296
|
+
- [code-infra] Removed `getTeamMembers` function and usage from the release script (#21608) @michelengelen
|
|
297
|
+
|
|
298
|
+
### Miscellaneous
|
|
299
|
+
|
|
300
|
+
- [test] Add missing tests for forwarding props to filter operators in DataGrid (#21700) @siriwatknp
|
|
301
|
+
|
|
302
|
+
## 8.27.4
|
|
303
|
+
|
|
304
|
+
_Mar 5, 2026_
|
|
305
|
+
|
|
306
|
+
We'd like to extend a big thank you to the 6 contributors who made this release possible. Here are some highlights ✨:
|
|
307
|
+
|
|
308
|
+
- 🐞 Bugfixes
|
|
309
|
+
- 🌎 Improve Ukrainian (uk-UA) locale
|
|
310
|
+
|
|
311
|
+
Special thanks go out to this community member for their valuable contribution:
|
|
312
|
+
@lion1963
|
|
313
|
+
|
|
314
|
+
The following team members contributed to this release:
|
|
315
|
+
@arminmeh, @brijeshb42, @dav-is, @JCQuintas, @sai6855
|
|
316
|
+
|
|
317
|
+
### Data Grid
|
|
318
|
+
|
|
319
|
+
#### `@mui/x-data-grid@8.27.4`
|
|
320
|
+
|
|
321
|
+
- [DataGrid] Prevent unnecessary row selection checkbox rerendering (#21571) @arminmeh
|
|
322
|
+
- [DataGrid] Make `GridScrollArea` overrides resolver dynamic (#21612) @sai6855
|
|
323
|
+
- [l10n] Improve Ukrainian (uk-UA) locale (#21381) @lion1963
|
|
324
|
+
|
|
325
|
+
#### `@mui/x-data-grid-pro@8.27.4` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
326
|
+
|
|
327
|
+
Same changes as in `@mui/x-data-grid@8.27.4`, plus:
|
|
328
|
+
|
|
329
|
+
- [DataGridPro] Use `getRowId` prop to calculate the tree data row update (#21544) @arminmeh
|
|
330
|
+
|
|
331
|
+
#### `@mui/x-data-grid-premium@8.27.4` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
332
|
+
|
|
333
|
+
Same changes as in `@mui/x-data-grid-pro@8.27.4`.
|
|
334
|
+
|
|
335
|
+
### Charts
|
|
336
|
+
|
|
337
|
+
#### `@mui/x-charts@8.27.4`
|
|
338
|
+
|
|
339
|
+
- [charts] Deprecate `ChartDataProvider` in favour of `ChartsDataProvider` (#21549) @JCQuintas
|
|
340
|
+
- [charts] Rename `ChartContainer` to `ChartsContainer` (#21186) @JCQuintas
|
|
341
|
+
- [charts] Rename `ChartZoomSlider` to `ChartsZoomSlider` (#21572) @JCQuintas
|
|
342
|
+
|
|
343
|
+
#### `@mui/x-charts-pro@8.27.4` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
344
|
+
|
|
345
|
+
Same changes as in `@mui/x-charts@8.27.4`.
|
|
346
|
+
|
|
347
|
+
#### `@mui/x-charts-premium@8.27.4` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
348
|
+
|
|
349
|
+
Same changes as in `@mui/x-charts-pro@8.27.4`.
|
|
350
|
+
|
|
351
|
+
### Core
|
|
352
|
+
|
|
353
|
+
- [code-infra] Add eslint rule to prevent `Math.random` in docs (#21505) (#21563) @JCQuintas
|
|
354
|
+
- [code-infra] V8 Dedupe (#21561) @JCQuintas
|
|
355
|
+
- [docs-infra] Apply Cookie Banner to v8.x Branch (#21448) @dav-is
|
|
356
|
+
- [code-infra] Setup checkout to do full clone for non master branches (#21624) @brijeshb42
|
|
357
|
+
|
|
358
|
+
## 8.27.3
|
|
359
|
+
|
|
360
|
+
_Feb 25, 2026_
|
|
361
|
+
|
|
362
|
+
We'd like to extend a big thank you to the 4 contributors who made this release possible. Here are some highlights ✨:
|
|
363
|
+
|
|
364
|
+
- 🐞 Bugfixes
|
|
365
|
+
- ⚡️ Improved dynamic data support and cache invalidation in lazy loading for Data Grid Pro
|
|
366
|
+
|
|
367
|
+
The following team members contributed to this release:
|
|
368
|
+
@cherniavskii, @michelengelen, @MBilalShafi, @arminmeh
|
|
369
|
+
|
|
370
|
+
### Data Grid
|
|
371
|
+
|
|
372
|
+
#### `@mui/x-data-grid@8.27.3`
|
|
373
|
+
|
|
374
|
+
- [DataGrid] Preserve key input during row edit when using `rowModesModel` (#21457) @michelengelen
|
|
375
|
+
|
|
376
|
+
#### `@mui/x-data-grid-pro@8.27.3` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
377
|
+
|
|
378
|
+
Same changes as in `@mui/x-data-grid@8.27.3`, plus:
|
|
379
|
+
|
|
380
|
+
- [DataGridPro] Improve dynamic data support and cache invalidation in lazy loading (#21465) @MBilalShafi
|
|
381
|
+
|
|
382
|
+
#### `@mui/x-data-grid-premium@8.27.3` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
383
|
+
|
|
384
|
+
Same changes as in `@mui/x-data-grid-pro@8.27.3`.
|
|
385
|
+
|
|
386
|
+
### Core
|
|
387
|
+
|
|
388
|
+
- [code-infra] Do not append `x` to the last version for the compare API (#21422) @arminmeh
|
|
389
|
+
- [docs-infra] Fix current version detection logic (#21415) @cherniavskii
|
|
390
|
+
|
|
391
|
+
## 8.27.2
|
|
392
|
+
|
|
393
|
+
_Feb 20, 2026_
|
|
394
|
+
|
|
395
|
+
We'd like to extend a big thank you to the 3 contributors who made this release possible. Here are some highlights ✨:
|
|
396
|
+
|
|
397
|
+
- 🐞 Bugfixes
|
|
398
|
+
|
|
399
|
+
### Data Grid
|
|
400
|
+
|
|
401
|
+
#### `@mui/x-data-grid@8.27.2`
|
|
402
|
+
|
|
403
|
+
Internal changes.
|
|
404
|
+
|
|
405
|
+
#### `@mui/x-data-grid-pro@8.27.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
406
|
+
|
|
407
|
+
Same changes as in `@mui/x-data-grid@8.27.2`, plus:
|
|
408
|
+
|
|
409
|
+
- [DataGridPro] Fix number input visibility in header filters (#21345) @michelengelen
|
|
410
|
+
|
|
411
|
+
#### `@mui/x-data-grid-premium@8.27.2` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
412
|
+
|
|
413
|
+
Same changes as in `@mui/x-data-grid-pro@8.27.2`.
|
|
414
|
+
|
|
415
|
+
### Date and Time Pickers
|
|
416
|
+
|
|
417
|
+
#### `@mui/x-date-pickers@8.27.2`
|
|
418
|
+
|
|
419
|
+
- [DatePicker] Add keyboard support for selecting day, month, and year (#21399) @michelengelen
|
|
420
|
+
|
|
421
|
+
#### `@mui/x-date-pickers-pro@8.27.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
422
|
+
|
|
423
|
+
Same changes as in `@mui/x-date-pickers@8.27.2`, plus:
|
|
424
|
+
|
|
425
|
+
- [DateRangePicker] Fix timezone update issue leading to `invalidRange` error (#21382) @michelengelen
|
|
426
|
+
|
|
427
|
+
### Charts
|
|
428
|
+
|
|
429
|
+
#### `@mui/x-charts@8.27.2`
|
|
430
|
+
|
|
431
|
+
Internal changes.
|
|
432
|
+
|
|
433
|
+
#### `@mui/x-charts-pro@8.27.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
434
|
+
|
|
435
|
+
Same changes as in `@mui/x-charts@8.27.2`, plus:
|
|
436
|
+
|
|
437
|
+
- [charts-pro] Handle edge case in export image (#21206) @bernardobelchior
|
|
438
|
+
|
|
439
|
+
#### `@mui/x-charts-premium@8.27.2` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
440
|
+
|
|
441
|
+
Same changes as in `@mui/x-charts-pro@8.27.2`.
|
|
442
|
+
|
|
443
|
+
### Tree View
|
|
444
|
+
|
|
445
|
+
#### `@mui/x-tree-view@8.27.2`
|
|
446
|
+
|
|
447
|
+
- [tree view] Focus item sibling on unmount instead of the 1st item (#21386) @flaviendelangle
|
|
448
|
+
|
|
449
|
+
#### `@mui/x-tree-view-pro@8.27.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
450
|
+
|
|
451
|
+
Same changes as in `@mui/x-tree-view@8.27.2`.
|
|
452
|
+
|
|
453
|
+
### Codemod
|
|
454
|
+
|
|
455
|
+
#### `@mui/x-codemod@8.27.2`
|
|
456
|
+
|
|
457
|
+
Internal changes.
|
|
458
|
+
|
|
459
|
+
### Core
|
|
460
|
+
|
|
461
|
+
- [code-infra] Only ignore `renovate[bot]` in changelog generation script (#21188) @bernardobelchior
|
|
462
|
+
|
|
8
463
|
## v8.27.1
|
|
9
464
|
|
|
10
465
|
<!-- generated comparing v8.27.0..v8.x -->
|
package/esm/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { expansionSelectors } from "../expansion/index.js";
|
|
2
2
|
import { focusSelectors } from "./selectors.js";
|
|
3
3
|
import { itemsSelectors } from "../items/index.js";
|
|
4
|
+
import { getFirstNavigableItem, getNextNavigableItem, getPreviousNavigableItem } from "../../utils/tree.js";
|
|
4
5
|
export class TreeViewFocusPlugin {
|
|
5
6
|
// We can't type `store`, otherwise we get the following TS error:
|
|
6
7
|
// 'focus' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
|
@@ -8,21 +9,27 @@ export class TreeViewFocusPlugin {
|
|
|
8
9
|
this.store = store;
|
|
9
10
|
|
|
10
11
|
// Whenever the items change, we need to ensure the focused item is still present.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
// If the focused item was removed, focus the closest neighbor instead of the first item.
|
|
13
|
+
let previousState = store.state;
|
|
14
|
+
this.store.subscribe(newState => {
|
|
15
|
+
// Only run when items actually changed.
|
|
16
|
+
if (newState.itemMetaLookup === previousState.itemMetaLookup) {
|
|
17
|
+
previousState = newState;
|
|
14
18
|
return;
|
|
15
19
|
}
|
|
16
|
-
const
|
|
17
|
-
if (
|
|
20
|
+
const focusedItemId = focusSelectors.focusedItemId(newState);
|
|
21
|
+
if (focusedItemId == null || itemsSelectors.itemMeta(newState, focusedItemId)) {
|
|
22
|
+
previousState = newState;
|
|
18
23
|
return;
|
|
19
24
|
}
|
|
20
|
-
const
|
|
21
|
-
|
|
25
|
+
const checkItemInNewTree = itemId => itemId == null || !itemsSelectors.itemMeta(newState, itemId) ? null : itemId;
|
|
26
|
+
const itemToFocusId = checkItemInNewTree(getNextNavigableItem(previousState, focusedItemId)) ?? checkItemInNewTree(getPreviousNavigableItem(previousState, focusedItemId)) ?? getFirstNavigableItem(newState);
|
|
27
|
+
if (itemToFocusId == null) {
|
|
22
28
|
this.setFocusedItemId(null);
|
|
23
|
-
|
|
29
|
+
} else {
|
|
30
|
+
this.applyItemFocus(null, itemToFocusId);
|
|
24
31
|
}
|
|
25
|
-
|
|
32
|
+
previousState = newState;
|
|
26
33
|
});
|
|
27
34
|
}
|
|
28
35
|
setFocusedItemId = itemId => {
|
|
@@ -56,7 +56,7 @@ export const itemsSelectors = {
|
|
|
56
56
|
/**
|
|
57
57
|
* Checks whether an item can be focused.
|
|
58
58
|
*/
|
|
59
|
-
canItemBeFocused: createSelector((state, itemId) => state.disabledItemsFocusable || !isItemDisabled(state.itemMetaLookup, itemId)),
|
|
59
|
+
canItemBeFocused: createSelector((state, itemId) => state.disabledItemsFocusable || state.itemModelLookup[itemId] != null && !isItemDisabled(state.itemMetaLookup, itemId)),
|
|
60
60
|
/**
|
|
61
61
|
* Gets the identation between an item and its children.
|
|
62
62
|
*/
|
|
@@ -3,13 +3,18 @@ import { TreeViewItemMeta } from "../../models/index.js";
|
|
|
3
3
|
import type { SimpleTreeViewStore } from "../../SimpleTreeViewStore/index.js";
|
|
4
4
|
export declare class TreeViewJSXItemsPlugin {
|
|
5
5
|
private store;
|
|
6
|
+
/**
|
|
7
|
+
* Tracks which component instance owns each item id,
|
|
8
|
+
* so that duplicate ids from different components can be detected.
|
|
9
|
+
*/
|
|
10
|
+
private itemOwners;
|
|
6
11
|
constructor(store: SimpleTreeViewStore<any>);
|
|
7
12
|
/**
|
|
8
|
-
* Insert
|
|
9
|
-
*
|
|
10
|
-
*
|
|
13
|
+
* Insert or update an item in the state from a Tree Item component.
|
|
14
|
+
* If the item already exists and belongs to the same owner (e.g. after a deps-change re-run of the layout effect),
|
|
15
|
+
* its meta is updated in place instead of removing and re-inserting.
|
|
11
16
|
*/
|
|
12
|
-
|
|
17
|
+
upsertJSXItem: (item: TreeViewItemMeta, ownerToken: symbol) => () => void;
|
|
13
18
|
/**
|
|
14
19
|
* Updates the `labelMap` to register the first character of the given item's label.
|
|
15
20
|
* This map is used to navigate the tree using type-ahead search.
|
|
@@ -1,34 +1,61 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from "../items/index.js";
|
|
2
|
+
import { buildSiblingIndexes, itemsSelectors, TREE_VIEW_ROOT_PARENT_ID } from "../items/index.js";
|
|
3
3
|
import { jsxItemsitemWrapper, useJSXItemsItemPlugin } from "./itemPlugin.js";
|
|
4
4
|
export class TreeViewJSXItemsPlugin {
|
|
5
|
+
/**
|
|
6
|
+
* Tracks which component instance owns each item id,
|
|
7
|
+
* so that duplicate ids from different components can be detected.
|
|
8
|
+
*/
|
|
9
|
+
itemOwners = (() => new Map())();
|
|
5
10
|
constructor(store) {
|
|
6
11
|
this.store = store;
|
|
7
12
|
store.itemPluginManager.register(useJSXItemsItemPlugin, jsxItemsitemWrapper);
|
|
8
13
|
}
|
|
9
14
|
|
|
10
15
|
/**
|
|
11
|
-
* Insert
|
|
12
|
-
*
|
|
13
|
-
*
|
|
16
|
+
* Insert or update an item in the state from a Tree Item component.
|
|
17
|
+
* If the item already exists and belongs to the same owner (e.g. after a deps-change re-run of the layout effect),
|
|
18
|
+
* its meta is updated in place instead of removing and re-inserting.
|
|
14
19
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
upsertJSXItem = (item, ownerToken) => {
|
|
21
|
+
const currentOwner = this.itemOwners.get(item.id);
|
|
22
|
+
if (currentOwner != null && currentOwner !== ownerToken) {
|
|
17
23
|
throw new Error(['MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', `Two items were provided with the same id in the \`items\` prop: "${item.id}"`].join('\n'));
|
|
18
24
|
}
|
|
19
|
-
this.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
[item
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
this.itemOwners.set(item.id, ownerToken);
|
|
26
|
+
const existingMeta = itemsSelectors.itemMeta(this.store.state, item.id);
|
|
27
|
+
if (existingMeta != null) {
|
|
28
|
+
// Update the existing item in place.
|
|
29
|
+
let hasChanges = false;
|
|
30
|
+
for (const key of Object.keys(item)) {
|
|
31
|
+
if (existingMeta[key] !== item[key]) {
|
|
32
|
+
hasChanges = true;
|
|
33
|
+
break;
|
|
28
34
|
}
|
|
29
|
-
}
|
|
30
|
-
|
|
35
|
+
}
|
|
36
|
+
if (hasChanges) {
|
|
37
|
+
this.store.update({
|
|
38
|
+
itemMetaLookup: _extends({}, this.store.state.itemMetaLookup, {
|
|
39
|
+
[item.id]: _extends({}, existingMeta, item)
|
|
40
|
+
})
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
this.store.update({
|
|
45
|
+
itemMetaLookup: _extends({}, this.store.state.itemMetaLookup, {
|
|
46
|
+
[item.id]: item
|
|
47
|
+
}),
|
|
48
|
+
// For Simple Tree View, we don't have a proper `item` object, so we create a very basic one.
|
|
49
|
+
itemModelLookup: _extends({}, this.store.state.itemModelLookup, {
|
|
50
|
+
[item.id]: {
|
|
51
|
+
id: item.id,
|
|
52
|
+
label: item.label ?? ''
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
}
|
|
31
57
|
return () => {
|
|
58
|
+
this.itemOwners.delete(item.id);
|
|
32
59
|
const newItemMetaLookup = _extends({}, this.store.state.itemMetaLookup);
|
|
33
60
|
const newItemModelLookup = _extends({}, this.store.state.itemModelLookup);
|
|
34
61
|
delete newItemMetaLookup[item.id];
|
|
@@ -4,6 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
import { useStore } from '@mui/x-internals/store';
|
|
5
5
|
import { useMergedRefs } from '@base-ui/utils/useMergedRefs';
|
|
6
6
|
import { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect';
|
|
7
|
+
import { useRefWithInit } from '@base-ui/utils/useRefWithInit';
|
|
7
8
|
import { useTreeViewContext } from "../../TreeViewProvider/index.js";
|
|
8
9
|
import { TreeViewChildrenItemContext, TreeViewChildrenItemProvider } from "../../TreeViewProvider/TreeViewChildrenItemProvider.js";
|
|
9
10
|
import { TreeViewItemDepthContext } from "../../TreeViewItemDepthContext/index.js";
|
|
@@ -39,6 +40,8 @@ export const useJSXItemsItemPlugin = ({
|
|
|
39
40
|
const pluginContentRef = React.useRef(null);
|
|
40
41
|
const handleContentRef = useMergedRefs(pluginContentRef, contentRef);
|
|
41
42
|
const idAttribute = useStore(store, idSelectors.treeItemIdAttribute, itemId, id);
|
|
43
|
+
const isMountedRef = React.useRef(true);
|
|
44
|
+
const ownerTokenRef = useRefWithInit(Symbol);
|
|
42
45
|
|
|
43
46
|
// Prevent any flashing
|
|
44
47
|
useIsoLayoutEffect(() => {
|
|
@@ -49,15 +52,27 @@ export const useJSXItemsItemPlugin = ({
|
|
|
49
52
|
};
|
|
50
53
|
}, [store, registerChild, unregisterChild, idAttribute, itemId]);
|
|
51
54
|
useIsoLayoutEffect(() => {
|
|
52
|
-
|
|
55
|
+
isMountedRef.current = true;
|
|
56
|
+
return () => {
|
|
57
|
+
isMountedRef.current = false;
|
|
58
|
+
};
|
|
59
|
+
}, []);
|
|
60
|
+
useIsoLayoutEffect(() => {
|
|
61
|
+
const remove = store.jsxItems.upsertJSXItem({
|
|
53
62
|
id: itemId,
|
|
54
63
|
idAttribute: id,
|
|
55
64
|
parentId,
|
|
56
65
|
expandable,
|
|
57
66
|
disabled,
|
|
58
67
|
selectable: !disableSelection
|
|
59
|
-
});
|
|
60
|
-
|
|
68
|
+
}, ownerTokenRef.current);
|
|
69
|
+
return () => {
|
|
70
|
+
// Only remove the item if the component is unmounting, not if the dependencies are changing.
|
|
71
|
+
if (!isMountedRef.current) {
|
|
72
|
+
remove();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}, [store, parentId, itemId, expandable, disabled, disableSelection, id, ownerTokenRef]);
|
|
61
76
|
React.useEffect(() => {
|
|
62
77
|
if (label) {
|
|
63
78
|
return store.jsxItems.mapLabelFromJSX(itemId, (pluginContentRef.current?.textContent ?? '').toLowerCase());
|
package/esm/utils/cache.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { TreeViewItemMeta } from "../internals/models/index.js";
|
|
2
1
|
type DataSourceCacheDefaultConfig = {
|
|
3
2
|
/**
|
|
4
3
|
* Time To Live for each cache entry in milliseconds.
|
|
@@ -7,32 +6,32 @@ type DataSourceCacheDefaultConfig = {
|
|
|
7
6
|
*/
|
|
8
7
|
ttl?: number;
|
|
9
8
|
};
|
|
10
|
-
export interface DataSourceCache {
|
|
9
|
+
export interface DataSourceCache<T = any> {
|
|
11
10
|
/**
|
|
12
11
|
* Set the cache entry for the given key.
|
|
13
12
|
* @param {string} key The key of type `string`
|
|
14
|
-
* @param {
|
|
13
|
+
* @param {T[]} value The value to be stored in the cache
|
|
15
14
|
*/
|
|
16
|
-
set: (key: string, value:
|
|
15
|
+
set: (key: string, value: T[]) => void;
|
|
17
16
|
/**
|
|
18
17
|
* Get the cache entry for the given key.
|
|
19
18
|
* @param {string} key The key of type `string`
|
|
20
|
-
* @returns {
|
|
19
|
+
* @returns {T[] | undefined | -1} The value stored in the cache, `undefined` if not found, or `-1` if the cache entry is stale.
|
|
21
20
|
*/
|
|
22
|
-
get: (key: string) =>
|
|
21
|
+
get: (key: string) => T[] | undefined | -1;
|
|
23
22
|
/**
|
|
24
23
|
* Clear the cache.
|
|
25
24
|
*/
|
|
26
25
|
clear: () => void;
|
|
27
26
|
}
|
|
28
|
-
export declare class DataSourceCacheDefault {
|
|
27
|
+
export declare class DataSourceCacheDefault<T = any> implements DataSourceCache<T> {
|
|
29
28
|
private cache;
|
|
30
29
|
private ttl;
|
|
31
30
|
constructor({
|
|
32
31
|
ttl
|
|
33
32
|
}: DataSourceCacheDefaultConfig);
|
|
34
|
-
set(key: string, value:
|
|
35
|
-
get(key: string):
|
|
33
|
+
set(key: string, value: T[]): void;
|
|
34
|
+
get(key: string): T[] | undefined | -1;
|
|
36
35
|
clear(): void;
|
|
37
36
|
}
|
|
38
37
|
export {};
|
package/index.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.TreeViewFocusPlugin = void 0;
|
|
|
7
7
|
var _expansion = require("../expansion");
|
|
8
8
|
var _selectors = require("./selectors");
|
|
9
9
|
var _items = require("../items");
|
|
10
|
+
var _tree = require("../../utils/tree");
|
|
10
11
|
class TreeViewFocusPlugin {
|
|
11
12
|
// We can't type `store`, otherwise we get the following TS error:
|
|
12
13
|
// 'focus' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
|
@@ -14,21 +15,27 @@ class TreeViewFocusPlugin {
|
|
|
14
15
|
this.store = store;
|
|
15
16
|
|
|
16
17
|
// Whenever the items change, we need to ensure the focused item is still present.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// If the focused item was removed, focus the closest neighbor instead of the first item.
|
|
19
|
+
let previousState = store.state;
|
|
20
|
+
this.store.subscribe(newState => {
|
|
21
|
+
// Only run when items actually changed.
|
|
22
|
+
if (newState.itemMetaLookup === previousState.itemMetaLookup) {
|
|
23
|
+
previousState = newState;
|
|
20
24
|
return;
|
|
21
25
|
}
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
26
|
+
const focusedItemId = _selectors.focusSelectors.focusedItemId(newState);
|
|
27
|
+
if (focusedItemId == null || _items.itemsSelectors.itemMeta(newState, focusedItemId)) {
|
|
28
|
+
previousState = newState;
|
|
24
29
|
return;
|
|
25
30
|
}
|
|
26
|
-
const
|
|
27
|
-
|
|
31
|
+
const checkItemInNewTree = itemId => itemId == null || !_items.itemsSelectors.itemMeta(newState, itemId) ? null : itemId;
|
|
32
|
+
const itemToFocusId = checkItemInNewTree((0, _tree.getNextNavigableItem)(previousState, focusedItemId)) ?? checkItemInNewTree((0, _tree.getPreviousNavigableItem)(previousState, focusedItemId)) ?? (0, _tree.getFirstNavigableItem)(newState);
|
|
33
|
+
if (itemToFocusId == null) {
|
|
28
34
|
this.setFocusedItemId(null);
|
|
29
|
-
|
|
35
|
+
} else {
|
|
36
|
+
this.applyItemFocus(null, itemToFocusId);
|
|
30
37
|
}
|
|
31
|
-
|
|
38
|
+
previousState = newState;
|
|
32
39
|
});
|
|
33
40
|
}
|
|
34
41
|
setFocusedItemId = itemId => {
|
|
@@ -62,7 +62,7 @@ const itemsSelectors = exports.itemsSelectors = {
|
|
|
62
62
|
/**
|
|
63
63
|
* Checks whether an item can be focused.
|
|
64
64
|
*/
|
|
65
|
-
canItemBeFocused: (0, _store.createSelector)((state, itemId) => state.disabledItemsFocusable || !(0, _utils.isItemDisabled)(state.itemMetaLookup, itemId)),
|
|
65
|
+
canItemBeFocused: (0, _store.createSelector)((state, itemId) => state.disabledItemsFocusable || state.itemModelLookup[itemId] != null && !(0, _utils.isItemDisabled)(state.itemMetaLookup, itemId)),
|
|
66
66
|
/**
|
|
67
67
|
* Gets the identation between an item and its children.
|
|
68
68
|
*/
|
|
@@ -3,13 +3,18 @@ import { TreeViewItemMeta } from "../../models/index.js";
|
|
|
3
3
|
import type { SimpleTreeViewStore } from "../../SimpleTreeViewStore/index.js";
|
|
4
4
|
export declare class TreeViewJSXItemsPlugin {
|
|
5
5
|
private store;
|
|
6
|
+
/**
|
|
7
|
+
* Tracks which component instance owns each item id,
|
|
8
|
+
* so that duplicate ids from different components can be detected.
|
|
9
|
+
*/
|
|
10
|
+
private itemOwners;
|
|
6
11
|
constructor(store: SimpleTreeViewStore<any>);
|
|
7
12
|
/**
|
|
8
|
-
* Insert
|
|
9
|
-
*
|
|
10
|
-
*
|
|
13
|
+
* Insert or update an item in the state from a Tree Item component.
|
|
14
|
+
* If the item already exists and belongs to the same owner (e.g. after a deps-change re-run of the layout effect),
|
|
15
|
+
* its meta is updated in place instead of removing and re-inserting.
|
|
11
16
|
*/
|
|
12
|
-
|
|
17
|
+
upsertJSXItem: (item: TreeViewItemMeta, ownerToken: symbol) => () => void;
|
|
13
18
|
/**
|
|
14
19
|
* Updates the `labelMap` to register the first character of the given item's label.
|
|
15
20
|
* This map is used to navigate the tree using type-ahead search.
|
|
@@ -9,33 +9,60 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
|
|
|
9
9
|
var _items = require("../items");
|
|
10
10
|
var _itemPlugin = require("./itemPlugin");
|
|
11
11
|
class TreeViewJSXItemsPlugin {
|
|
12
|
+
/**
|
|
13
|
+
* Tracks which component instance owns each item id,
|
|
14
|
+
* so that duplicate ids from different components can be detected.
|
|
15
|
+
*/
|
|
16
|
+
itemOwners = new Map();
|
|
12
17
|
constructor(store) {
|
|
13
18
|
this.store = store;
|
|
14
19
|
store.itemPluginManager.register(_itemPlugin.useJSXItemsItemPlugin, _itemPlugin.jsxItemsitemWrapper);
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
/**
|
|
18
|
-
* Insert
|
|
19
|
-
*
|
|
20
|
-
*
|
|
23
|
+
* Insert or update an item in the state from a Tree Item component.
|
|
24
|
+
* If the item already exists and belongs to the same owner (e.g. after a deps-change re-run of the layout effect),
|
|
25
|
+
* its meta is updated in place instead of removing and re-inserting.
|
|
21
26
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
upsertJSXItem = (item, ownerToken) => {
|
|
28
|
+
const currentOwner = this.itemOwners.get(item.id);
|
|
29
|
+
if (currentOwner != null && currentOwner !== ownerToken) {
|
|
24
30
|
throw new Error(['MUI X: The Tree View component requires all items to have a unique `id` property.', 'Alternatively, you can use the `getItemId` prop to specify a custom id for each item.', `Two items were provided with the same id in the \`items\` prop: "${item.id}"`].join('\n'));
|
|
25
31
|
}
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
[item
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
this.itemOwners.set(item.id, ownerToken);
|
|
33
|
+
const existingMeta = _items.itemsSelectors.itemMeta(this.store.state, item.id);
|
|
34
|
+
if (existingMeta != null) {
|
|
35
|
+
// Update the existing item in place.
|
|
36
|
+
let hasChanges = false;
|
|
37
|
+
for (const key of Object.keys(item)) {
|
|
38
|
+
if (existingMeta[key] !== item[key]) {
|
|
39
|
+
hasChanges = true;
|
|
40
|
+
break;
|
|
35
41
|
}
|
|
36
|
-
}
|
|
37
|
-
|
|
42
|
+
}
|
|
43
|
+
if (hasChanges) {
|
|
44
|
+
this.store.update({
|
|
45
|
+
itemMetaLookup: (0, _extends2.default)({}, this.store.state.itemMetaLookup, {
|
|
46
|
+
[item.id]: (0, _extends2.default)({}, existingMeta, item)
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
this.store.update({
|
|
52
|
+
itemMetaLookup: (0, _extends2.default)({}, this.store.state.itemMetaLookup, {
|
|
53
|
+
[item.id]: item
|
|
54
|
+
}),
|
|
55
|
+
// For Simple Tree View, we don't have a proper `item` object, so we create a very basic one.
|
|
56
|
+
itemModelLookup: (0, _extends2.default)({}, this.store.state.itemModelLookup, {
|
|
57
|
+
[item.id]: {
|
|
58
|
+
id: item.id,
|
|
59
|
+
label: item.label ?? ''
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
});
|
|
63
|
+
}
|
|
38
64
|
return () => {
|
|
65
|
+
this.itemOwners.delete(item.id);
|
|
39
66
|
const newItemMetaLookup = (0, _extends2.default)({}, this.store.state.itemMetaLookup);
|
|
40
67
|
const newItemModelLookup = (0, _extends2.default)({}, this.store.state.itemModelLookup);
|
|
41
68
|
delete newItemMetaLookup[item.id];
|
|
@@ -10,6 +10,7 @@ var React = _interopRequireWildcard(require("react"));
|
|
|
10
10
|
var _store = require("@mui/x-internals/store");
|
|
11
11
|
var _useMergedRefs = require("@base-ui/utils/useMergedRefs");
|
|
12
12
|
var _useIsoLayoutEffect = require("@base-ui/utils/useIsoLayoutEffect");
|
|
13
|
+
var _useRefWithInit = require("@base-ui/utils/useRefWithInit");
|
|
13
14
|
var _TreeViewProvider = require("../../TreeViewProvider");
|
|
14
15
|
var _TreeViewChildrenItemProvider = require("../../TreeViewProvider/TreeViewChildrenItemProvider");
|
|
15
16
|
var _TreeViewItemDepthContext = require("../../TreeViewItemDepthContext");
|
|
@@ -45,6 +46,8 @@ const useJSXItemsItemPlugin = ({
|
|
|
45
46
|
const pluginContentRef = React.useRef(null);
|
|
46
47
|
const handleContentRef = (0, _useMergedRefs.useMergedRefs)(pluginContentRef, contentRef);
|
|
47
48
|
const idAttribute = (0, _store.useStore)(store, _id.idSelectors.treeItemIdAttribute, itemId, id);
|
|
49
|
+
const isMountedRef = React.useRef(true);
|
|
50
|
+
const ownerTokenRef = (0, _useRefWithInit.useRefWithInit)(Symbol);
|
|
48
51
|
|
|
49
52
|
// Prevent any flashing
|
|
50
53
|
(0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
|
|
@@ -55,15 +58,27 @@ const useJSXItemsItemPlugin = ({
|
|
|
55
58
|
};
|
|
56
59
|
}, [store, registerChild, unregisterChild, idAttribute, itemId]);
|
|
57
60
|
(0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
|
|
58
|
-
|
|
61
|
+
isMountedRef.current = true;
|
|
62
|
+
return () => {
|
|
63
|
+
isMountedRef.current = false;
|
|
64
|
+
};
|
|
65
|
+
}, []);
|
|
66
|
+
(0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
|
|
67
|
+
const remove = store.jsxItems.upsertJSXItem({
|
|
59
68
|
id: itemId,
|
|
60
69
|
idAttribute: id,
|
|
61
70
|
parentId,
|
|
62
71
|
expandable,
|
|
63
72
|
disabled,
|
|
64
73
|
selectable: !disableSelection
|
|
65
|
-
});
|
|
66
|
-
|
|
74
|
+
}, ownerTokenRef.current);
|
|
75
|
+
return () => {
|
|
76
|
+
// Only remove the item if the component is unmounting, not if the dependencies are changing.
|
|
77
|
+
if (!isMountedRef.current) {
|
|
78
|
+
remove();
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}, [store, parentId, itemId, expandable, disabled, disableSelection, id, ownerTokenRef]);
|
|
67
82
|
React.useEffect(() => {
|
|
68
83
|
if (label) {
|
|
69
84
|
return store.jsxItems.mapLabelFromJSX(itemId, (pluginContentRef.current?.textContent ?? '').toLowerCase());
|
package/package.json
CHANGED
package/utils/cache.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { TreeViewItemMeta } from "../internals/models/index.js";
|
|
2
1
|
type DataSourceCacheDefaultConfig = {
|
|
3
2
|
/**
|
|
4
3
|
* Time To Live for each cache entry in milliseconds.
|
|
@@ -7,32 +6,32 @@ type DataSourceCacheDefaultConfig = {
|
|
|
7
6
|
*/
|
|
8
7
|
ttl?: number;
|
|
9
8
|
};
|
|
10
|
-
export interface DataSourceCache {
|
|
9
|
+
export interface DataSourceCache<T = any> {
|
|
11
10
|
/**
|
|
12
11
|
* Set the cache entry for the given key.
|
|
13
12
|
* @param {string} key The key of type `string`
|
|
14
|
-
* @param {
|
|
13
|
+
* @param {T[]} value The value to be stored in the cache
|
|
15
14
|
*/
|
|
16
|
-
set: (key: string, value:
|
|
15
|
+
set: (key: string, value: T[]) => void;
|
|
17
16
|
/**
|
|
18
17
|
* Get the cache entry for the given key.
|
|
19
18
|
* @param {string} key The key of type `string`
|
|
20
|
-
* @returns {
|
|
19
|
+
* @returns {T[] | undefined | -1} The value stored in the cache, `undefined` if not found, or `-1` if the cache entry is stale.
|
|
21
20
|
*/
|
|
22
|
-
get: (key: string) =>
|
|
21
|
+
get: (key: string) => T[] | undefined | -1;
|
|
23
22
|
/**
|
|
24
23
|
* Clear the cache.
|
|
25
24
|
*/
|
|
26
25
|
clear: () => void;
|
|
27
26
|
}
|
|
28
|
-
export declare class DataSourceCacheDefault {
|
|
27
|
+
export declare class DataSourceCacheDefault<T = any> implements DataSourceCache<T> {
|
|
29
28
|
private cache;
|
|
30
29
|
private ttl;
|
|
31
30
|
constructor({
|
|
32
31
|
ttl
|
|
33
32
|
}: DataSourceCacheDefaultConfig);
|
|
34
|
-
set(key: string, value:
|
|
35
|
-
get(key: string):
|
|
33
|
+
set(key: string, value: T[]): void;
|
|
34
|
+
get(key: string): T[] | undefined | -1;
|
|
36
35
|
clear(): void;
|
|
37
36
|
}
|
|
38
37
|
export {};
|