Last active
May 29, 2017 23:28
-
-
Save aaronanderson/553de211642ceb2658e8fddc6eb1daf1 to your computer and use it in GitHub Desktop.
A Polymer 2.0 collapsible tree using a caller provided template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link rel="import" href="../polymer/polymer-element.html"> | |
<link rel="import" href="../iron-collapse/iron-collapse.html"> | |
<link rel="import" href="../paper-item/paper-icon-item.html"> | |
<link rel="import" href="../paper-item/paper-item-body.html"> | |
<link rel="import" href="../iron-flex-layout/iron-flex-layout-classes.html"> | |
<link rel="import" href="../iron-icons/iron-icons.html"> | |
<link rel="import" href="../iron-icon/iron-icon.html"> | |
<dom-module id="intworkspace-tree"> | |
<template> | |
<style include="iron-flex iron-flex-alignment"> | |
paper-icon-item { | |
--paper-item-min-height: var(--intworkspace-tree-margin,30px); | |
--paper-item-icon-width : var(--intworkspace-tree-margin,30px); | |
} | |
paper-icon-item:focus::before, | |
paper-icon-item:focus::after { | |
color: inherit; | |
opacity: 0; | |
} | |
.node { | |
margin-left: var(--intworkspace-tree-margin,30px);; | |
} | |
</style> | |
<slot id="labelView"></slot> | |
</template> | |
<template id="nodeView"> | |
<template is="dom-repeat" items="{{tree}}" as="node" index-as="n"> | |
<div class="layout vertical"> | |
<!--<div>index: [[n]]</div> | |
<div>name: [[node.name]]</div>--> | |
<paper-icon-item on-tap="nodeSelected"> | |
<template is="dom-if" if="[[hasNodes(node)]]"> | |
<iron-icon icon="expand-less" slot="item-icon" hidden$="[[!hasNodes(node)]]"></iron-icon> | |
</template> | |
<!-- label goes here--> | |
</paper-icon-item> | |
<template is="dom-if" if="[[hasNodes(node)]]"> | |
<iron-collapse class="node" opened> | |
<intworkspace-tree tree="[[node.nodes]]" node-template="[[nodeTemplate]]" embedded></intworkspace-tree> | |
</iron-collapse> | |
</template> | |
</div> | |
</template> | |
</template> | |
<script> | |
class IntTree extends Polymer.TemplateStamp(Polymer.Element) { | |
static get is() { | |
return 'intworkspace-tree'; | |
} | |
static get properties() { | |
return { | |
tree: { | |
type: Array, | |
value: [] | |
}, | |
nodeTemplate: { | |
type: Object, | |
} | |
}; | |
} | |
ready() { | |
super.ready(); | |
if (!this.hasAttribute("embedded")) { | |
let labelTemplate = this.$.labelView.assignedNodes().find((e) => { | |
return e instanceof HTMLTemplateElement; | |
}); | |
let nodeTemplate = document.importNode(Polymer.DomModule.import(IntTree.is, "#nodeView"), true); | |
let repeatTemplate = nodeTemplate.content.querySelector("template[is='dom-repeat']"); | |
let iconItem = repeatTemplate.content.querySelector('paper-icon-item'); | |
iconItem.appendChild(labelTemplate.content); | |
this.nodeTemplate = nodeTemplate; | |
} | |
let nodeInstance = this._stampTemplate(this.nodeTemplate); | |
this.shadowRoot.appendChild(nodeInstance); | |
} | |
hasNodes(node) { | |
return node.nodes != null && node.nodes.length > 0; | |
} | |
nodeSelected(e) { | |
let collapse = e.currentTarget.parentNode.querySelector("iron-collapse"); | |
let nodeIcon = e.currentTarget.parentNode.querySelector("iron-icon"); | |
if (collapse && nodeIcon) { | |
collapse.toggle(); | |
if (collapse.opened) { | |
nodeIcon.icon = "expand-less"; | |
} else { | |
nodeIcon.icon = "expand-more"; | |
} | |
} | |
} | |
} | |
window.customElements.define(IntTree.is, IntTree); | |
</script> | |
</dom-module> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link rel="import" href="../polymer/polymer-element.html"> | |
<!--<link rel="import" href="../polymer/lib/elements/dom-if.html">--> | |
<!--<link rel="import" href="../polymer/lib/elements/dom-repeat.html">--> | |
<link rel="import" href="../paper-item/paper-item-body.html"> | |
<link rel="import" href="../paper-button/paper-button.html"> | |
<link rel="import" href="intworkspace-tree.html"> | |
<!-- | |
`tree-test` | |
@demo demo/index.html | |
--> | |
<dom-module id="tree-test"> | |
<template> | |
<style> | |
:host { | |
display: block; | |
} | |
</style> | |
<intworkspace-tree tree="{{testTree}}"> | |
<template preserve-content><paper-item-body>[[node.name]]</paper-item-body></template> | |
</intworkspace-tree> | |
<div> | |
<paper-button raised on-tap="reload">Reload</paper-button> | |
</div> | |
</template> | |
<script> | |
/** @polymerElement */ | |
class TreeTest extends Polymer.Element { | |
static get is() { | |
return 'tree-test'; | |
} | |
random(min, max) { | |
return Math.random() * (max - min) + min; | |
} | |
createLevel(newTree, currentDepth) { | |
if (currentDepth == 3) { | |
return; | |
} | |
var numNodes = this.random(currentDepth == 0 ? 1 : 0, 4); | |
var newDepth = currentDepth + 1; | |
for (var i = 1; i <= numNodes; i++) { | |
var id = this.testNodeId++; | |
var childTree = []; | |
this.createLevel(childTree, newDepth); | |
var node = { | |
id: id, | |
name: `Node ${id}`, | |
nodes: childTree | |
} | |
newTree.push(node); | |
} | |
} | |
reload() { | |
this.testNodeId = 1; | |
var newTree = []; | |
this.createLevel(newTree, 0); | |
console.log("new tree", JSON.stringify(newTree)); | |
this.set("testTree", newTree); | |
} | |
static get properties() { | |
return { | |
testTree: { | |
type: Array, | |
value: [] | |
}, | |
testNodeId: { | |
type: Number | |
} | |
}; | |
} | |
ready() { | |
super.ready(); | |
this.reload(); | |
} | |
} | |
window.customElements.define(TreeTest.is, TreeTest); | |
</script> | |
</dom-module> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment