@aurelia-mdc-web/tree-view
Version:
Wrapper for Material Components Web Tree View
159 lines • 6.49 kB
JavaScript
var MdcTreeView_1;
import { __awaiter, __decorate, __metadata } from "tslib";
import { MdcComponent } from '@aurelia-mdc-web/base';
import { MDCFoundation } from '@material/base';
import { customElement, bindable, useView, PLATFORM, processContent, ViewCompiler, ViewResources, inject, Optional, Container } from 'aurelia-framework';
let id = 0;
const templateLookup = {};
const getNextNodeTemplateId = () => ++id;
const NODE_SELECTED_EVENT = 'mdctree:node-selected';
export class MDCTreeViewFoundation extends MDCFoundation {
}
let MdcTreeView = MdcTreeView_1 = class MdcTreeView extends MdcComponent {
getDefaultFoundation() {
return new MDCTreeViewFoundation();
}
static processContent(_viewCompiler, _resources, element) {
const treeNode = element.querySelector('mdc-tree-node');
if (treeNode) {
const nodeTemplateId = getNextNodeTemplateId();
element.setAttribute('data-template-id', nodeTemplateId.toString());
templateLookup[nodeTemplateId] = treeNode.innerHTML;
}
element.innerHTML = '';
return false;
}
/**
* @param element the host element of a <mdc-tree-view/>
* @param container the container associated with a <mdc-tree-view/>
*/
static getNodeFactory(element, container) {
const parent = container.parent ? container.parent.get(Optional.of(MdcTreeView_1)) : null;
const isRoot = !parent;
// a root mdc-tree view means a consumer defined one
// this potentiall contains the template for the tree node
if (isRoot) {
const nodeTemplateId = element.getAttribute('data-template-id');
if (nodeTemplateId && templateLookup[nodeTemplateId]) {
const nodeTemplate = templateLookup[nodeTemplateId];
const nodeViewFactory = container.get(ViewCompiler).compile(`<template>${nodeTemplate}</template>`, container.get(ViewResources));
return nodeViewFactory;
}
else {
// create a default <mdc-tree-node/> factory
// eslint-disable-next-line no-template-curly-in-string
return container.get(ViewCompiler).compile('<template>${$node}</template>', container.get(ViewResources));
}
}
else {
// if it's not a root <mdc-tree-view/>
// assume that the parent has already built the node factory and simply get it from there
return parent.nodeViewFactory;
}
}
constructor(root, container) {
super(root);
/**
* Allows for filtering tree nodes
*/
this.filter = () => true;
this.nodeViewFactory = MdcTreeView_1.getNodeFactory(root, container);
}
bind(bindingContext) {
var _a;
this.rootBindingContext = (_a = this.rootBindingContext) !== null && _a !== void 0 ? _a : bindingContext;
}
toggleExpanded(n, e) {
n.expanded = !n.expanded;
e.stopPropagation();
return false;
}
nodeClicked(n) {
if (this.selectedNode) {
this.selectedNode.selected = false;
}
if (n) {
n.selected = true;
}
this.selectedNode = n;
this.root.dispatchEvent(new CustomEvent(NODE_SELECTED_EVENT, { detail: { node: n }, bubbles: true }));
return true;
}
childNodeSelected(n) {
if (this.selectedNode && this.selectedNode !== n) {
this.selectedNode.selected = false;
}
this.selectedNode = n;
}
findPath(nodes, predicate) {
const path = [];
for (let i = 0; i < nodes.length; ++i) {
if (predicate(nodes[i])) {
return [i];
}
if (!nodes[i].children) {
continue;
}
const filteredChildren = nodes[i].children.filter(x => this.filter(x));
const childPath = this.findPath(filteredChildren, predicate);
if (childPath.length) {
return [i, ...childPath];
}
}
return path;
}
expandPath(path) {
return __awaiter(this, void 0, void 0, function* () {
const filteredNodes = this.nodes.filter(x => this.filter(x));
if (path.length === 1) {
this.nodeClicked(filteredNodes[path[0]]);
this.root.querySelectorAll('.mdc-tree-view__node')[path[0]].scrollIntoView();
}
else {
filteredNodes[path[0]].expanded = true;
// child tree views are hidden with 'if.bind'
// promises are created by a helper element `mdc-promisify-reference`
// this lets dependent code to wait till a view model reference is assigned
yield this.initialised;
const childTreeView = yield (filteredNodes[path[0]].childTreeViewPromise);
yield (childTreeView === null || childTreeView === void 0 ? void 0 : childTreeView.expandPath(path.slice(1)));
}
});
}
find(predicate) {
return __awaiter(this, void 0, void 0, function* () {
// to avoid rendering the whole tree finding a node is a 2-step process
// firstly, find the path - nodes which need to be expanded to display the target node
const filteredNodes = this.nodes.filter(x => this.filter(x));
const path = this.findPath(filteredNodes, predicate);
if (path.length) {
// secondly, expand the path
yield this.expandPath(path);
}
});
}
dispatchEvent(type, node) {
this.root.dispatchEvent(new CustomEvent(type, { bubbles: true, detail: { node } }));
}
};
__decorate([
bindable,
__metadata("design:type", Array)
], MdcTreeView.prototype, "nodes", void 0);
__decorate([
bindable,
__metadata("design:type", Function)
], MdcTreeView.prototype, "filter", void 0);
__decorate([
bindable,
__metadata("design:type", Object)
], MdcTreeView.prototype, "rootBindingContext", void 0);
MdcTreeView = MdcTreeView_1 = __decorate([
inject(Element, Container),
customElement('mdc-tree-view'),
useView(PLATFORM.moduleName('./mdc-tree-view.html')),
processContent(MdcTreeView.processContent),
__metadata("design:paramtypes", [HTMLElement, Container])
], MdcTreeView);
export { MdcTreeView };
//# sourceMappingURL=mdc-tree-view.js.map