130 lines
3.6 KiB
JavaScript
130 lines
3.6 KiB
JavaScript
export const TreeInteractionsMixin = (superClass) => class TreeInteractionsMixin extends superClass {
|
|
_dispatchAction(action, item, source, originalEvent) {
|
|
const ev = new CustomEvent('node-action', {
|
|
detail: { action, item, source, originalEvent },
|
|
bubbles: true,
|
|
composed: true,
|
|
cancelable: true,
|
|
});
|
|
this.dispatchEvent(ev);
|
|
}
|
|
|
|
_onInlineAction(item, action, originalEvent) {
|
|
originalEvent.stopPropagation();
|
|
this._dispatchAction(action?.action, item, 'inline-action', originalEvent);
|
|
}
|
|
|
|
_onRowDoubleClick(item, originalEvent) {
|
|
this._suppressNextClick = true;
|
|
queueMicrotask(() => {
|
|
this._suppressNextClick = false;
|
|
});
|
|
|
|
this.dispatchEvent(new CustomEvent('node-dblclick', {
|
|
detail: { node: item.node, path: item.path, originalEvent },
|
|
bubbles: true,
|
|
composed: true,
|
|
cancelable: true,
|
|
}));
|
|
}
|
|
|
|
_onRowClick(item, originalEvent) {
|
|
if (this._suppressNextClick) {
|
|
originalEvent?.stopPropagation?.();
|
|
originalEvent?.preventDefault?.();
|
|
return;
|
|
}
|
|
|
|
const isDouble = this.expandOnDoubleClick && !this.expandOnSingleClick && originalEvent?.detail === 2;
|
|
|
|
if (this.manageState) {
|
|
const pathStr = item.path.join('/');
|
|
const set = new Set(this._selectedPathSet);
|
|
|
|
if (this.multiSelect) {
|
|
if (set.has(pathStr)) {
|
|
set.delete(pathStr);
|
|
} else {
|
|
set.add(pathStr);
|
|
}
|
|
} else {
|
|
set.clear();
|
|
set.add(pathStr);
|
|
}
|
|
|
|
this._selectedPathSet = set;
|
|
this.selectedPaths = Array.from(set);
|
|
this._applySelectionStates();
|
|
|
|
this.dispatchEvent(new CustomEvent('node-selected', {
|
|
detail: { node: item.node, path: item.path, originalEvent },
|
|
bubbles: true,
|
|
composed: true,
|
|
}));
|
|
}
|
|
|
|
if (isDouble) {
|
|
this._toggleExpand(item, 'double-click', originalEvent);
|
|
}
|
|
|
|
if (this.expandOnSingleClick) {
|
|
this._toggleExpand(item, 'single-click', originalEvent);
|
|
}
|
|
|
|
if (!isDouble) {
|
|
this.dispatchEvent(new CustomEvent('node-click', {
|
|
detail: { node: item.node, path: item.path, originalEvent },
|
|
bubbles: true,
|
|
composed: true,
|
|
cancelable: true,
|
|
}));
|
|
}
|
|
}
|
|
|
|
_onChevronClick(item, originalEvent) {
|
|
originalEvent.stopPropagation();
|
|
this._toggleExpand(item, 'chevron', originalEvent);
|
|
}
|
|
|
|
_toggleExpand(item, source, originalEvent) {
|
|
const shouldLoad = typeof this.loadChildren === 'function';
|
|
|
|
if (this.manageState) {
|
|
const pathStr = item.path.join('/');
|
|
const set = new Set(this._expandedPathSet);
|
|
const wasExpanded = set.has(pathStr);
|
|
|
|
if (wasExpanded) {
|
|
set.delete(pathStr);
|
|
this._expandedPathSet = set;
|
|
this.expandedPaths = Array.from(set);
|
|
this._rebuildManagedTree();
|
|
this._dispatchAction('toggle', item, source, originalEvent);
|
|
return;
|
|
}
|
|
|
|
if (shouldLoad) {
|
|
this._updateNodeStatesByKey(item.key, (n) => {
|
|
const states = Array.isArray(n.states) ? n.states : [];
|
|
const next = states.filter((s) => s !== 'loaded');
|
|
if (!next.includes('loading')) next.push('loading');
|
|
return { ...n, states: next };
|
|
});
|
|
}
|
|
|
|
set.add(pathStr);
|
|
this._expandedPathSet = set;
|
|
this.expandedPaths = Array.from(set);
|
|
this._rebuildManagedTree();
|
|
this._dispatchAction('toggle', item, source, originalEvent);
|
|
|
|
if (shouldLoad) {
|
|
this._loadChildrenForExpanded(item.key, source, originalEvent, item.node, item.path);
|
|
}
|
|
return;
|
|
}
|
|
|
|
this._dispatchAction('toggle', item, source, originalEvent);
|
|
}
|
|
};
|