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); } };