@mui/x-tree-view
Version:
The community edition of the MUI X Tree View components.
116 lines (112 loc) • 4.71 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TreeViewJSXItemsPlugin = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _items = require("../items");
var _itemPlugin = require("./itemPlugin");
class TreeViewJSXItemsPlugin {
/**
* Tracks which component instance owns each item id,
* so that duplicate ids from different components can be detected.
*/
itemOwners = new Map();
constructor(store) {
this.store = store;
store.itemPluginManager.register(_itemPlugin.useJSXItemsItemPlugin, _itemPlugin.jsxItemsitemWrapper);
}
/**
* Insert or update an item in the state from a Tree Item component.
* If the item already exists and belongs to the same owner (e.g. after a deps-change re-run of the layout effect),
* its meta is updated in place instead of removing and re-inserting.
*/
upsertJSXItem = (item, ownerToken) => {
const currentOwner = this.itemOwners.get(item.id);
if (currentOwner != null && currentOwner !== ownerToken) {
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'));
}
this.itemOwners.set(item.id, ownerToken);
const existingMeta = _items.itemsSelectors.itemMeta(this.store.state, item.id);
if (existingMeta != null) {
// Update the existing item in place.
let hasChanges = false;
for (const key of Object.keys(item)) {
if (existingMeta[key] !== item[key]) {
hasChanges = true;
break;
}
}
if (hasChanges) {
this.store.update({
itemMetaLookup: (0, _extends2.default)({}, this.store.state.itemMetaLookup, {
[item.id]: (0, _extends2.default)({}, existingMeta, item)
})
});
}
} else {
this.store.update({
itemMetaLookup: (0, _extends2.default)({}, this.store.state.itemMetaLookup, {
[item.id]: item
}),
// For Simple Tree View, we don't have a proper `item` object, so we create a very basic one.
itemModelLookup: (0, _extends2.default)({}, this.store.state.itemModelLookup, {
[item.id]: {
id: item.id,
label: item.label ?? ''
}
})
});
}
return () => {
this.itemOwners.delete(item.id);
const newItemMetaLookup = (0, _extends2.default)({}, this.store.state.itemMetaLookup);
const newItemModelLookup = (0, _extends2.default)({}, this.store.state.itemModelLookup);
delete newItemMetaLookup[item.id];
delete newItemModelLookup[item.id];
this.store.update({
itemMetaLookup: newItemMetaLookup,
itemModelLookup: newItemModelLookup
});
};
};
/**
* Updates the `labelMap` to register the first character of the given item's label.
* This map is used to navigate the tree using type-ahead search.
* @param {TreeViewItemId} itemId The id of the item to map the label of.
* @param {string} label The item's label.
* @returns {() => void} A function to remove the item from the `labelMap`.
*/
mapLabelFromJSX = (itemId, label) => {
this.store.keyboardNavigation.updateLabelMap(labelMap => {
labelMap[itemId] = label;
return labelMap;
});
return () => {
this.store.keyboardNavigation.updateLabelMap(labelMap => {
const newMap = (0, _extends2.default)({}, labelMap);
delete newMap[itemId];
return newMap;
});
};
};
/**
* Store the ids of a given item's children in the state.
* Those ids must be passed in the order they should be rendered.
* @param {TreeViewItemId | null} parentId The id of the item to store the children of.
* @param {TreeViewItemId[]} orderedChildrenIds The ids of the item's children.
*/
setJSXItemsOrderedChildrenIds = (parentId, orderedChildrenIds) => {
const parentIdWithDefault = parentId ?? _items.TREE_VIEW_ROOT_PARENT_ID;
this.store.update({
itemOrderedChildrenIdsLookup: (0, _extends2.default)({}, this.store.state.itemOrderedChildrenIdsLookup, {
[parentIdWithDefault]: orderedChildrenIds
}),
itemChildrenIndexesLookup: (0, _extends2.default)({}, this.store.state.itemChildrenIndexesLookup, {
[parentIdWithDefault]: (0, _items.buildSiblingIndexes)(orderedChildrenIds)
})
});
};
}
exports.TreeViewJSXItemsPlugin = TreeViewJSXItemsPlugin;