@mui/x-tree-view 9.6.0 → 9.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,115 @@
1
1
  # Changelog
2
2
 
3
+ ## 9.7.0
4
+
5
+ _Jun 25, 2026_
6
+
7
+ We'd like to extend a big thank you to the 13 contributors who made this release possible. Here are some highlights ✨:
8
+
9
+ - 🐞 Bugfixes
10
+ - 📚 Documentation improvements
11
+
12
+ Special thanks go out to these community members for their valuable contributions:
13
+ @Anexus5919, @mustafajw07
14
+
15
+ The following team members contributed to this release:
16
+ @alexfauquette, @arminmeh, @brijeshb42, @Janpot, @JCQuintas, @LukasTy, @MBilalShafi, @michelengelen, @romgrk, @sai6855, @siriwatknp
17
+
18
+ ### Data Grid
19
+
20
+ #### `@mui/x-data-grid@9.7.0`
21
+
22
+ - [DataGrid] Fix `CustomColumnMenuGrid` demo crashing (#22897) @sai6855
23
+ - [DataGrid] Fix crash in `getRowValue` when `colDef` is `undefined` (#22838) @LukasTy
24
+ - [DataGrid] Fix `longText` expand button submitting surrounding form (#22450) @siriwatknp
25
+ - [DataGrid] Remove filename ignore list from `removePropTypesPlugin` in Babel config (#22727) @sai6855
26
+ - [DataGrid] Deduplicate scroll-preserving focus logic (#22916) @sai6855
27
+ - [DataGrid] Fix `singleSelect` clearing to use empty string instead of `null` (#22881) @michelengelen
28
+ - [DataGrid] Wait for rows before reacting on `autosizeOnMount` (#22698) @MBilalShafi
29
+
30
+ #### `@mui/x-data-grid-pro@9.7.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
31
+
32
+ Same changes as in `@mui/x-data-grid@9.7.0`.
33
+
34
+ #### `@mui/x-data-grid-premium@9.7.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
35
+
36
+ Same changes as in `@mui/x-data-grid-pro@9.7.0`.
37
+
38
+ ### Date and Time Pickers
39
+
40
+ #### `@mui/x-date-pickers@9.7.0`
41
+
42
+ - [fields] Announce cardinal day in the day section `aria-valuetext` (#22922) @LukasTy
43
+ - [fields] Avoid focusing the field on blank space clicks (#22285) @LukasTy
44
+ - [pickers] Commit `TimeClock` value when the drag ends outside the clock (#22877) @LukasTy
45
+ - [pickers] Respect explicit `notched` prop on the outlined PickersTextField (#22875) @LukasTy
46
+
47
+ #### `@mui/x-date-pickers-pro@9.7.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
48
+
49
+ Same changes as in `@mui/x-date-pickers@9.7.0`.
50
+
51
+ ### Charts
52
+
53
+ #### `@mui/x-charts@9.7.0`
54
+
55
+ - [charts] Add demo for displaying the sum of all values from the stacked series on top of the stacked bars (#22879) @sai6855
56
+ - [charts] Add `zAxis` custom scatter component demo (#22746) @mustafajw07
57
+ - [charts] Apply axis `colorMap` to radial bar fill (#22800) @JCQuintas
58
+ - [charts] Simplify classes type (#22626) @alexfauquette
59
+ - [charts] Stable progressive scatter batching + responsive zoom/pan (#22862) @JCQuintas
60
+ - [charts] Strip dev-only console diagnostics from production (#22917) @sai6855
61
+ - [docs] Fix scatter renderer table blocking column (#22904) @JCQuintas
62
+ - [docs] Make `ScatterAsyncRenderer` button bar responsive (#22905) @JCQuintas
63
+
64
+ #### `@mui/x-charts-pro@9.7.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
65
+
66
+ Same changes as in `@mui/x-charts@9.7.0`.
67
+
68
+ #### `@mui/x-charts-premium@9.7.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
69
+
70
+ Same changes as in `@mui/x-charts-pro@9.7.0`.
71
+
72
+ ### Tree View
73
+
74
+ #### `@mui/x-tree-view@9.7.0`
75
+
76
+ Internal changes.
77
+
78
+ #### `@mui/x-tree-view-pro@9.7.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
79
+
80
+ Same changes as in `@mui/x-tree-view@9.7.0`.
81
+
82
+ ### Scheduler
83
+
84
+ #### `@mui/x-scheduler@9.0.0-beta.3`
85
+
86
+ - [scheduler] Highlight only the edited occurrence of a recurring event (#22873) @Anexus5919
87
+
88
+ #### `@mui/x-scheduler-premium@9.0.0-beta.3` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
89
+
90
+ Same changes as in `@mui/x-scheduler@9.0.0-beta.3`.
91
+
92
+ ### Codemod
93
+
94
+ #### `@mui/x-codemod@9.7.0`
95
+
96
+ Internal changes.
97
+
98
+ ### Core
99
+
100
+ - [code-infra] Fix react@^18 CI failing on nanoid trust-downgrade (#22923) @LukasTy
101
+ - [code-infra] Reduce Netlify build parallelism to 2 (#22925) @LukasTy
102
+ - [code-infra] Use Turbopack for docs in dev (#22882) @brijeshb42
103
+ - [docs-infra] Pre-render API page descriptions (#22919) @brijeshb42
104
+ - [internal] Use `@base-ui/utils/platform` for platform detection (#22710) @romgrk
105
+ - [internal] Enforce top-level type imports (#22679) @Janpot
106
+
107
+ ### Miscellaneous
108
+
109
+ - [internal] Enable mui/no-floating-cleanup and fix leaks (#22872) @romgrk
110
+ - [infra] Update `.gitignore` to exclude `.claude` sub-directories (#22435) @michelengelen
111
+ - [virtualizer] Improve the dimensions' initial state (#22885) @arminmeh
112
+
3
113
  ## 9.6.0
4
114
 
5
115
  _Jun 18, 2026_
@@ -115,7 +225,7 @@ Same changes as in `@mui/x-scheduler@9.0.0-beta.2`, plus:
115
225
 
116
226
  - [scheduler-premium] Expose premium model types through public API (#22798) @mustafajw07
117
227
  - [scheduler-premium] Remove non-functional `onPreferencesChange` prop from `EventTimelinePremium` (#22777) @rita-codes
118
- - [scheduler-premium] Validate the `FREQ` value in `parseRRule`] (#22786) @rita-codes
228
+ - [scheduler-premium] Validate the `FREQ` value in `parseRRule`] (#22786) @rita-codes
119
229
 
120
230
  ### Codemod
121
231
 
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v9.6.0
2
+ * @mui/x-tree-view v9.7.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-tree-view v9.6.0
2
+ * @mui/x-tree-view v9.7.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -1,4 +1,5 @@
1
1
  import { Store } from '@mui/x-internals/store';
2
+ import { disposeSymbol } from '@mui/x-internals/disposable';
2
3
  import { MinimalTreeViewParameters, TreeViewParametersToStateMapper, MinimalTreeViewState } from "./MinimalTreeViewStore.types.mjs";
3
4
  import { TreeViewValidItem } from "../../models/index.mjs";
4
5
  import { TimeoutManager } from "./TimeoutManager.mjs";
@@ -12,6 +13,7 @@ import { TreeViewEventEvent, TreeViewEventListener, TreeViewEventParameters, Tre
12
13
  export declare class MinimalTreeViewStore<R extends TreeViewValidItem<R>, Multiple extends boolean | undefined, State extends MinimalTreeViewState<R, Multiple> = MinimalTreeViewState<R, Multiple>, Parameters extends MinimalTreeViewParameters<R, Multiple> = MinimalTreeViewParameters<R, Multiple>> extends Store<State> {
13
14
  private initialParameters;
14
15
  private mapper;
16
+ readonly disposables: DisposableStack;
15
17
  private eventManager;
16
18
  instanceName: string;
17
19
  parameters: Parameters;
@@ -67,9 +69,17 @@ export declare class MinimalTreeViewStore<R extends TreeViewValidItem<R>, Multip
67
69
  */
68
70
  updateStateFromParameters(parameters: Parameters): void;
69
71
  /**
70
- * Returns a cleanup function that need to be called when the store is destroyed.
72
+ * Runs mount-time side effects that must not happen during render (the store
73
+ * is created during render by `useDisposable`). No-op by default; overridden
74
+ * by stores that kick off work on mount (e.g. lazy-loading fetches). Safe to
75
+ * call more than once (StrictMode replays mount effects).
71
76
  */
72
- disposeEffect: () => () => void;
77
+ mountEffect: () => void;
78
+ /**
79
+ * Disposes the store synchronously when the component unmounts. `useDisposable`
80
+ * handles React StrictMode's simulated unmount, so this runs once on real unmount.
81
+ */
82
+ [disposeSymbol](): void;
73
83
  /**
74
84
  * Whether updates based on `props.items` change should be ignored.
75
85
  */
@@ -1,4 +1,5 @@
1
1
  import { Store } from '@mui/x-internals/store';
2
+ import { disposeSymbol } from '@mui/x-internals/disposable';
2
3
  import { MinimalTreeViewParameters, TreeViewParametersToStateMapper, MinimalTreeViewState } from "./MinimalTreeViewStore.types.js";
3
4
  import { TreeViewValidItem } from "../../models/index.js";
4
5
  import { TimeoutManager } from "./TimeoutManager.js";
@@ -12,6 +13,7 @@ import { TreeViewEventEvent, TreeViewEventListener, TreeViewEventParameters, Tre
12
13
  export declare class MinimalTreeViewStore<R extends TreeViewValidItem<R>, Multiple extends boolean | undefined, State extends MinimalTreeViewState<R, Multiple> = MinimalTreeViewState<R, Multiple>, Parameters extends MinimalTreeViewParameters<R, Multiple> = MinimalTreeViewParameters<R, Multiple>> extends Store<State> {
13
14
  private initialParameters;
14
15
  private mapper;
16
+ readonly disposables: DisposableStack;
15
17
  private eventManager;
16
18
  instanceName: string;
17
19
  parameters: Parameters;
@@ -67,9 +69,17 @@ export declare class MinimalTreeViewStore<R extends TreeViewValidItem<R>, Multip
67
69
  */
68
70
  updateStateFromParameters(parameters: Parameters): void;
69
71
  /**
70
- * Returns a cleanup function that need to be called when the store is destroyed.
72
+ * Runs mount-time side effects that must not happen during render (the store
73
+ * is created during render by `useDisposable`). No-op by default; overridden
74
+ * by stores that kick off work on mount (e.g. lazy-loading fetches). Safe to
75
+ * call more than once (StrictMode replays mount effects).
71
76
  */
72
- disposeEffect: () => () => void;
77
+ mountEffect: () => void;
78
+ /**
79
+ * Disposes the store synchronously when the component unmounts. `useDisposable`
80
+ * handles React StrictMode's simulated unmount, so this runs once on real unmount.
81
+ */
82
+ [disposeSymbol](): void;
73
83
  /**
74
84
  * Whether updates based on `props.items` change should be ignored.
75
85
  */
@@ -9,6 +9,7 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
9
9
  var _store = require("@mui/x-internals/store");
10
10
  var _warning = require("@mui/x-internals/warning");
11
11
  var _EventManager = require("@mui/x-internals/EventManager");
12
+ var _disposable = require("@mui/x-internals/disposable");
12
13
  var _MinimalTreeViewStore = require("./MinimalTreeViewStore.utils");
13
14
  var _TimeoutManager = require("./TimeoutManager");
14
15
  var _keyboardNavigation = require("../plugins/keyboardNavigation");
@@ -19,8 +20,13 @@ var _expansion = require("../plugins/expansion");
19
20
  var _TreeViewItemPluginManager = require("./TreeViewItemPluginManager");
20
21
  class MinimalTreeViewStore extends _store.Store {
21
22
  initialParameters = null;
22
- eventManager = new _EventManager.EventManager();
23
- timeoutManager = new _TimeoutManager.TimeoutManager();
23
+ // Owns the store's teardown. Declared first so the resources below register
24
+ // against it during field initialization; disposed by `useDisposable` on
25
+ // unmount (see `[disposeSymbol]`). `public` so plugins can register their own
26
+ // subscriptions against it (hidden from the context store type).
27
+ disposables = new _disposable.DisposableStack();
28
+ eventManager = this.disposables.adopt(new _EventManager.EventManager(), manager => manager.removeAllListeners());
29
+ timeoutManager = this.disposables.adopt(new _TimeoutManager.TimeoutManager(), manager => manager.clearAll());
24
30
  itemPluginManager = new _TreeViewItemPluginManager.TreeViewItemPluginManager();
25
31
  constructor(parameters, instanceName, mapper) {
26
32
  const minimalInitialState = (0, _MinimalTreeViewStore.createMinimalInitialState)(parameters);
@@ -83,11 +89,29 @@ class MinimalTreeViewStore extends _store.Store {
83
89
  }
84
90
 
85
91
  /**
86
- * Returns a cleanup function that need to be called when the store is destroyed.
92
+ * Runs mount-time side effects that must not happen during render (the store
93
+ * is created during render by `useDisposable`). No-op by default; overridden
94
+ * by stores that kick off work on mount (e.g. lazy-loading fetches). Safe to
95
+ * call more than once (StrictMode replays mount effects).
87
96
  */
88
- disposeEffect = () => {
89
- return this.timeoutManager.clearAll;
90
- };
97
+ mountEffect = () => {};
98
+
99
+ /**
100
+ * Disposes the store synchronously when the component unmounts. `useDisposable`
101
+ * handles React StrictMode's simulated unmount, so this runs once on real unmount.
102
+ */
103
+ [_disposable.disposeSymbol]() {
104
+ if (this.disposables.disposed) {
105
+ return;
106
+ }
107
+ try {
108
+ this.disposables.dispose();
109
+ } catch (error) {
110
+ if (process.env.NODE_ENV !== 'production') {
111
+ console.error('MUI X Tree View: error while disposing the store.', ...(0, _disposable.unwrapSuppressedErrors)(error));
112
+ }
113
+ }
114
+ }
91
115
 
92
116
  /**
93
117
  * Whether updates based on `props.items` change should be ignored.
@@ -101,13 +125,13 @@ class MinimalTreeViewStore extends _store.Store {
101
125
  */
102
126
  registerStoreEffect = (selector, effect) => {
103
127
  let previousValue = selector(this.state);
104
- this.subscribe(state => {
128
+ this.disposables.defer(this.subscribe(state => {
105
129
  const nextValue = selector(state);
106
130
  if (nextValue !== previousValue) {
107
131
  effect(previousValue, nextValue);
108
132
  previousValue = nextValue;
109
133
  }
110
- });
134
+ }));
111
135
  };
112
136
 
113
137
  /**
@@ -2,6 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { Store } from '@mui/x-internals/store';
3
3
  import { warnOnce } from '@mui/x-internals/warning';
4
4
  import { EventManager } from '@mui/x-internals/EventManager';
5
+ import { DisposableStack, disposeSymbol, unwrapSuppressedErrors } from '@mui/x-internals/disposable';
5
6
  import { createMinimalInitialState, createTreeViewDefaultId, deriveStateFromParameters } from "./MinimalTreeViewStore.utils.mjs";
6
7
  import { TimeoutManager } from "./TimeoutManager.mjs";
7
8
  import { TreeViewKeyboardNavigationPlugin } from "../plugins/keyboardNavigation/index.mjs";
@@ -12,8 +13,13 @@ import { TreeViewExpansionPlugin } from "../plugins/expansion/index.mjs";
12
13
  import { TreeViewItemPluginManager } from "./TreeViewItemPluginManager.mjs";
13
14
  export class MinimalTreeViewStore extends Store {
14
15
  initialParameters = null;
15
- eventManager = new EventManager();
16
- timeoutManager = new TimeoutManager();
16
+ // Owns the store's teardown. Declared first so the resources below register
17
+ // against it during field initialization; disposed by `useDisposable` on
18
+ // unmount (see `[disposeSymbol]`). `public` so plugins can register their own
19
+ // subscriptions against it (hidden from the context store type).
20
+ disposables = new DisposableStack();
21
+ eventManager = this.disposables.adopt(new EventManager(), manager => manager.removeAllListeners());
22
+ timeoutManager = this.disposables.adopt(new TimeoutManager(), manager => manager.clearAll());
17
23
  itemPluginManager = new TreeViewItemPluginManager();
18
24
  constructor(parameters, instanceName, mapper) {
19
25
  const minimalInitialState = createMinimalInitialState(parameters);
@@ -76,11 +82,29 @@ export class MinimalTreeViewStore extends Store {
76
82
  }
77
83
 
78
84
  /**
79
- * Returns a cleanup function that need to be called when the store is destroyed.
85
+ * Runs mount-time side effects that must not happen during render (the store
86
+ * is created during render by `useDisposable`). No-op by default; overridden
87
+ * by stores that kick off work on mount (e.g. lazy-loading fetches). Safe to
88
+ * call more than once (StrictMode replays mount effects).
80
89
  */
81
- disposeEffect = () => {
82
- return this.timeoutManager.clearAll;
83
- };
90
+ mountEffect = () => {};
91
+
92
+ /**
93
+ * Disposes the store synchronously when the component unmounts. `useDisposable`
94
+ * handles React StrictMode's simulated unmount, so this runs once on real unmount.
95
+ */
96
+ [disposeSymbol]() {
97
+ if (this.disposables.disposed) {
98
+ return;
99
+ }
100
+ try {
101
+ this.disposables.dispose();
102
+ } catch (error) {
103
+ if (process.env.NODE_ENV !== 'production') {
104
+ console.error('MUI X Tree View: error while disposing the store.', ...unwrapSuppressedErrors(error));
105
+ }
106
+ }
107
+ }
84
108
 
85
109
  /**
86
110
  * Whether updates based on `props.items` change should be ignored.
@@ -94,13 +118,13 @@ export class MinimalTreeViewStore extends Store {
94
118
  */
95
119
  registerStoreEffect = (selector, effect) => {
96
120
  let previousValue = selector(this.state);
97
- this.subscribe(state => {
121
+ this.disposables.defer(this.subscribe(state => {
98
122
  const nextValue = selector(state);
99
123
  if (nextValue !== previousValue) {
100
124
  effect(previousValue, nextValue);
101
125
  previousValue = nextValue;
102
126
  }
103
- });
127
+ }));
104
128
  };
105
129
 
106
130
  /**
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
+ import { disposeSymbol } from '@mui/x-internals/disposable';
2
3
  import { TreeItemWrapper, TreeViewItemPluginResponse, TreeViewPublicAPI, TreeViewAnyStore } from "../models/index.mjs";
3
4
  import type { TreeItemProps } from "../../TreeItem/TreeItem.types.mjs";
4
5
  import { TreeViewClasses, TreeViewSlotProps, TreeViewSlots } from "./TreeViewStyleContext.mjs";
5
6
  import { UseTreeViewBuildContextParameters } from "./useTreeViewBuildContext.mjs";
6
7
  export type TreeViewItemPluginsRunner = (props: TreeItemProps) => Required<TreeViewItemPluginResponse>;
7
- export type TreeViewStoreInContext<TStore extends TreeViewAnyStore> = Omit<TStore, 'setState' | 'update' | 'set' | 'updateStateFromParameters' | 'disposeEffect' | 'registerStoreEffect' | 'itemPluginManager' | 'parameters'>;
8
+ export type TreeViewStoreInContext<TStore extends TreeViewAnyStore> = Omit<TStore, 'setState' | 'update' | 'set' | 'updateStateFromParameters' | 'disposables' | typeof disposeSymbol | 'mountEffect' | 'registerStoreEffect' | 'itemPluginManager' | 'parameters'>;
8
9
  export interface TreeViewContextValue<TStore extends TreeViewAnyStore> {
9
10
  publicAPI: TreeViewPublicAPI<TStore>;
10
11
  store: TreeViewStoreInContext<TStore>;
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
+ import { disposeSymbol } from '@mui/x-internals/disposable';
2
3
  import { TreeItemWrapper, TreeViewItemPluginResponse, TreeViewPublicAPI, TreeViewAnyStore } from "../models/index.js";
3
4
  import type { TreeItemProps } from "../../TreeItem/TreeItem.types.js";
4
5
  import { TreeViewClasses, TreeViewSlotProps, TreeViewSlots } from "./TreeViewStyleContext.js";
5
6
  import { UseTreeViewBuildContextParameters } from "./useTreeViewBuildContext.js";
6
7
  export type TreeViewItemPluginsRunner = (props: TreeItemProps) => Required<TreeViewItemPluginResponse>;
7
- export type TreeViewStoreInContext<TStore extends TreeViewAnyStore> = Omit<TStore, 'setState' | 'update' | 'set' | 'updateStateFromParameters' | 'disposeEffect' | 'registerStoreEffect' | 'itemPluginManager' | 'parameters'>;
8
+ export type TreeViewStoreInContext<TStore extends TreeViewAnyStore> = Omit<TStore, 'setState' | 'update' | 'set' | 'updateStateFromParameters' | 'disposables' | typeof disposeSymbol | 'mountEffect' | 'registerStoreEffect' | 'itemPluginManager' | 'parameters'>;
8
9
  export interface TreeViewContextValue<TStore extends TreeViewAnyStore> {
9
10
  publicAPI: TreeViewPublicAPI<TStore>;
10
11
  store: TreeViewStoreInContext<TStore>;
@@ -7,21 +7,24 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.useTreeViewStore = useTreeViewStore;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
- var _useRefWithInit = require("@base-ui/utils/useRefWithInit");
11
10
  var _useIsoLayoutEffect = require("@base-ui/utils/useIsoLayoutEffect");
12
11
  var _useOnMount = require("@base-ui/utils/useOnMount");
12
+ var _useDisposable = require("@mui/x-internals/useDisposable");
13
13
  var _RtlProvider = require("@mui/system/RtlProvider");
14
14
  /**
15
15
  * Creates a Tree View store and keep it in sync with the provided parameters.
16
16
  */
17
17
  function useTreeViewStore(StoreClass, parameters) {
18
18
  const isRtl = (0, _RtlProvider.useRtl)();
19
- const store = (0, _useRefWithInit.useRefWithInit)(() => new StoreClass((0, _extends2.default)({}, parameters, {
19
+ const store = (0, _useDisposable.useDisposable)(() => new StoreClass((0, _extends2.default)({}, parameters, {
20
20
  isRtl
21
- }))).current;
21
+ })));
22
22
  (0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => store.updateStateFromParameters((0, _extends2.default)({}, parameters, {
23
23
  isRtl
24
24
  })), [store, isRtl, parameters]);
25
- (0, _useOnMount.useOnMount)(store.disposeEffect);
25
+
26
+ // Mount-time side effects (e.g. kicking off lazy-loading fetches). The store is
27
+ // created during render by `useDisposable`, so these can't run in the factory.
28
+ (0, _useOnMount.useOnMount)(store.mountEffect);
26
29
  return store;
27
30
  }
@@ -1,21 +1,24 @@
1
1
  'use client';
2
2
 
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
- import { useRefWithInit } from '@base-ui/utils/useRefWithInit';
5
4
  import { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect';
6
5
  import { useOnMount } from '@base-ui/utils/useOnMount';
6
+ import { useDisposable } from '@mui/x-internals/useDisposable';
7
7
  import { useRtl } from '@mui/system/RtlProvider';
8
8
  /**
9
9
  * Creates a Tree View store and keep it in sync with the provided parameters.
10
10
  */
11
11
  export function useTreeViewStore(StoreClass, parameters) {
12
12
  const isRtl = useRtl();
13
- const store = useRefWithInit(() => new StoreClass(_extends({}, parameters, {
13
+ const store = useDisposable(() => new StoreClass(_extends({}, parameters, {
14
14
  isRtl
15
- }))).current;
15
+ })));
16
16
  useIsoLayoutEffect(() => store.updateStateFromParameters(_extends({}, parameters, {
17
17
  isRtl
18
18
  })), [store, isRtl, parameters]);
19
- useOnMount(store.disposeEffect);
19
+
20
+ // Mount-time side effects (e.g. kicking off lazy-loading fetches). The store is
21
+ // created during render by `useDisposable`, so these can't run in the factory.
22
+ useOnMount(store.mountEffect);
20
23
  return store;
21
24
  }
@@ -17,7 +17,7 @@ class TreeViewFocusPlugin {
17
17
  // Whenever the items change, we need to ensure the focused item is still present.
18
18
  // If the focused item was removed, focus the closest neighbor instead of the first item.
19
19
  let previousState = store.state;
20
- this.store.subscribe(newState => {
20
+ this.store.disposables.defer(this.store.subscribe(newState => {
21
21
  // Only run when items actually changed.
22
22
  if (newState.itemMetaLookup === previousState.itemMetaLookup) {
23
23
  previousState = newState;
@@ -36,7 +36,7 @@ class TreeViewFocusPlugin {
36
36
  this.applyItemFocus(null, itemToFocusId);
37
37
  }
38
38
  previousState = newState;
39
- });
39
+ }));
40
40
  }
41
41
  setFocusedItemId = itemId => {
42
42
  const focusedItemId = _selectors.focusSelectors.focusedItemId(this.store.state);
@@ -11,7 +11,7 @@ export class TreeViewFocusPlugin {
11
11
  // Whenever the items change, we need to ensure the focused item is still present.
12
12
  // If the focused item was removed, focus the closest neighbor instead of the first item.
13
13
  let previousState = store.state;
14
- this.store.subscribe(newState => {
14
+ this.store.disposables.defer(this.store.subscribe(newState => {
15
15
  // Only run when items actually changed.
16
16
  if (newState.itemMetaLookup === previousState.itemMetaLookup) {
17
17
  previousState = newState;
@@ -30,7 +30,7 @@ export class TreeViewFocusPlugin {
30
30
  this.applyItemFocus(null, itemToFocusId);
31
31
  }
32
32
  previousState = newState;
33
- });
33
+ }));
34
34
  }
35
35
  setFocusedItemId = itemId => {
36
36
  const focusedItemId = focusSelectors.focusedItemId(this.store.state);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-tree-view",
3
- "version": "9.6.0",
3
+ "version": "9.7.0",
4
4
  "author": "MUI Team",
5
5
  "description": "The community edition of the MUI X Tree View components.",
6
6
  "license": "MIT",
@@ -32,13 +32,13 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@babel/runtime": "^7.29.7",
35
- "@base-ui/utils": "^0.2.9",
36
- "@mui/utils": "^9.0.1",
35
+ "@base-ui/utils": "^0.3.0",
36
+ "@mui/utils": "^9.1.1",
37
37
  "@types/react-transition-group": "^4.4.12",
38
38
  "clsx": "^2.1.1",
39
39
  "prop-types": "^15.8.1",
40
40
  "react-transition-group": "^4.4.5",
41
- "@mui/x-internals": "^9.6.0"
41
+ "@mui/x-internals": "^9.7.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "@emotion/react": "^11.9.0",