UNPKG

@mui/x-tree-view

Version:

The community edition of the MUI X Tree View components.

158 lines (148 loc) 7.85 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.MinimalTreeViewStore = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _store = require("@mui/x-internals/store"); var _warning = require("@mui/x-internals/warning"); var _EventManager = require("@mui/x-internals/EventManager"); var _disposable = require("@mui/x-internals/disposable"); var _MinimalTreeViewStore = require("./MinimalTreeViewStore.utils"); var _TimeoutManager = require("./TimeoutManager"); var _keyboardNavigation = require("../plugins/keyboardNavigation"); var _TreeViewFocusPlugin = require("../plugins/focus/TreeViewFocusPlugin"); var _TreeViewItemsPlugin = require("../plugins/items/TreeViewItemsPlugin"); var _TreeViewSelectionPlugin = require("../plugins/selection/TreeViewSelectionPlugin"); var _expansion = require("../plugins/expansion"); var _TreeViewItemPluginManager = require("./TreeViewItemPluginManager"); class MinimalTreeViewStore extends _store.Store { initialParameters = null; // Owns the store's teardown. Declared first so the resources below register // against it during field initialization; disposed by `useDisposable` on // unmount (see `[disposeSymbol]`). `public` so plugins can register their own // subscriptions against it (hidden from the context store type). disposables = new _disposable.DisposableStack(); eventManager = this.disposables.adopt(new _EventManager.EventManager(), manager => manager.removeAllListeners()); timeoutManager = this.disposables.adopt(new _TimeoutManager.TimeoutManager(), manager => manager.clearAll()); itemPluginManager = new _TreeViewItemPluginManager.TreeViewItemPluginManager(); constructor(parameters, instanceName, mapper) { const minimalInitialState = (0, _MinimalTreeViewStore.createMinimalInitialState)(parameters); const initialState = mapper.getInitialState(minimalInitialState, parameters); super(initialState); this.parameters = parameters; this.instanceName = instanceName; this.mapper = mapper; // We mount the plugins in the constructor to make sure all the methods of the store are available to the plugins during their construction. this.items = new _TreeViewItemsPlugin.TreeViewItemsPlugin(this); this.focus = new _TreeViewFocusPlugin.TreeViewFocusPlugin(this); this.expansion = new _expansion.TreeViewExpansionPlugin(this); this.selection = new _TreeViewSelectionPlugin.TreeViewSelectionPlugin(this); this.keyboardNavigation = new _keyboardNavigation.TreeViewKeyboardNavigationPlugin(this); if (process.env.NODE_ENV !== 'production') { this.initialParameters = parameters; } } /** * Builds an object containing the method that should be exposed publicly by the Tree View components. */ buildPublicAPI() { return (0, _extends2.default)({}, this.items.buildPublicAPI(), this.focus.buildPublicAPI(), this.expansion.buildPublicAPI(), this.selection.buildPublicAPI()); } /** * Updates the state of the Tree View based on the new parameters provided to the root component. */ updateStateFromParameters(parameters) { const updateModel = (mutableNewState, controlledProp, defaultProp) => { if (parameters[controlledProp] !== undefined) { mutableNewState[controlledProp] = parameters[controlledProp]; } if (process.env.NODE_ENV !== 'production') { const defaultValue = parameters[defaultProp]; const isControlled = parameters[controlledProp] !== undefined; const initialDefaultValue = this.initialParameters?.[defaultProp]; const initialIsControlled = this.initialParameters?.[controlledProp] !== undefined; if (initialIsControlled !== isControlled) { (0, _warning.warnOnce)([`MUI X Tree View: A component is changing the ${initialIsControlled ? '' : 'un'}controlled ${controlledProp} state of ${this.instanceName} to be ${initialIsControlled ? 'un' : ''}controlled.`, 'Elements should not switch from uncontrolled to controlled (or vice versa).', `Decide between using a controlled or uncontrolled ${controlledProp} element for the lifetime of the component.`, "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.", 'More info: https://fb.me/react-controlled-components'], 'error'); } else if (JSON.stringify(initialDefaultValue) !== JSON.stringify(defaultValue)) { (0, _warning.warnOnce)([`MUI X Tree View: A component is changing the default ${controlledProp} state of an uncontrolled ${this.instanceName} after being initialized. `, `To suppress this warning opt to use a controlled ${this.instanceName}.`], 'error'); } } }; const newMinimalState = (0, _MinimalTreeViewStore.deriveStateFromParameters)(parameters); updateModel(newMinimalState, 'expandedItems', 'defaultExpandedItems'); updateModel(newMinimalState, 'selectedItems', 'defaultSelectedItems'); if (this.state.providedTreeId !== parameters.id || this.state.treeId === undefined) { newMinimalState.treeId = (0, _MinimalTreeViewStore.createTreeViewDefaultId)(); } if (!this.mapper.shouldIgnoreItemsStateUpdate(parameters) && _TreeViewItemsPlugin.TreeViewItemsPlugin.shouldRebuildItemsState(parameters, this.parameters)) { Object.assign(newMinimalState, _TreeViewItemsPlugin.TreeViewItemsPlugin.buildItemsStateIfNeeded(parameters)); } const newState = this.mapper.updateStateFromParameters(newMinimalState, parameters, updateModel); this.update(newState); this.parameters = parameters; } /** * Runs mount-time side effects that must not happen during render (the store * is created during render by `useDisposable`). No-op by default; overridden * by stores that kick off work on mount (e.g. lazy-loading fetches). Safe to * call more than once (StrictMode replays mount effects). */ mountEffect = () => {}; /** * Disposes the store synchronously when the component unmounts. `useDisposable` * handles React StrictMode's simulated unmount, so this runs once on real unmount. */ [_disposable.disposeSymbol]() { if (this.disposables.disposed) { return; } try { this.disposables.dispose(); } catch (error) { if (process.env.NODE_ENV !== 'production') { console.error('MUI X Tree View: error while disposing the store.', ...(0, _disposable.unwrapSuppressedErrors)(error)); } } } /** * Whether updates based on `props.items` change should be ignored. */ shouldIgnoreItemsStateUpdate = () => { return this.mapper.shouldIgnoreItemsStateUpdate(this.parameters); }; /** * Registers an effect to be run when the value returned by the selector changes. */ registerStoreEffect = (selector, effect) => { let previousValue = selector(this.state); this.disposables.defer(this.subscribe(state => { const nextValue = selector(state); if (nextValue !== previousValue) { effect(previousValue, nextValue); previousValue = nextValue; } })); }; /** * Publishes an event to all its subscribers. */ publishEvent = (name, params, event) => { if (isSyntheticEvent(event) && event.isPropagationStopped()) { return; } this.eventManager.emit(name, params, event); }; /** * Subscribe to an event emitted by the store. * For now, the subscription is only removed when the store is destroyed. */ subscribeEvent = (eventName, handler) => { this.eventManager.on(eventName, handler); }; } exports.MinimalTreeViewStore = MinimalTreeViewStore; function isSyntheticEvent(event) { return event?.isPropagationStopped !== undefined; }