UNPKG

ui-widget-toolkit

Version:

UI widgets built on top of D3, Pixi.js and ag-grid-community

290 lines (252 loc) • 9.9 kB
<link rel='import' href='../../../../bower_components/paper-checkbox/paper-checkbox.html'> <!-- `<uwt-checkbox-tree-node>` display a tree node with expandable/collapsible capabilities and a checkbox for each row ## Styling The following custom properties and mixins are available for styling: Custom property | Description | Default ----------------|-------------|---------- `--uwt-checkbox-selected-background-color` | Highlight color for selected node | `rgba(200, 200, 200, 0.5)` `--uwt-checkbox-selected-color` | Text and icon color for selected node | `inherit` `--uwt-checkbox-toggle-theme` | Change theme for node +/- toggle | `--uwt-checkbox-icon-theme` | Change theme for node icon | --> <dom-module id='uwt-checkbox-tree-node'> <template> <style> :host(.selected)>.node-container>.node-row { background-color: var(--uwt-checkbox-selected-background-color, rgba(200, 200, 200, 0.5)); color: var(--uwt-checkbox-selected-color, inherit); } .node-container { white-space: nowrap; } .node-row { padding-left: 4px; padding-right: 4px; } .node-preicon.collapsed, .node-preicon.expanded { padding-left: 0px; } .node-preicon { padding-left: 18px; } .node-preicon:before { margin-right: 5px; @apply --uwt-checkbox-toggle-theme; } .node-preicon.collapsed:before { content: '\002B'; } .node-preicon.expanded:before { content: '\2212'; } .node-preicon, .node-name { cursor: pointer; } ul { margin: 0; padding-left: 20px; } li { list-style-type: none; } </style> <div class='node-container'> <div class='node-row'> <span class$='{{_computeClass(data.*)}}' on-click='toggleChildren'></span> <template is='dom-if' if='{{!data.notCheckable}}'> <paper-checkbox title='{{data.name}}' checked='{{data.checked}}' on-change='_onCheckChanged'> {{data.name}}</paper-checkbox> </template> <template is='dom-if' if='{{data.notCheckable}}'> {{data.name}} </template> </div> <template is='dom-if' if='{{data.open}}'> <ul> <template is='dom-repeat' items='{{data.children}}'> <li> <uwt-checkbox-tree-node id='{{item.name}}' data='{{item}}' onCheckChanged='[[onCheckChanged]]' class='checkbox-tree-node'></uwt-checkbox-tree-node> </li> </template> </ul> </template> </div> </template> </dom-module> <script> class UWTCheckboxTreeNode extends Polymer.Element { static get is() { return 'uwt-checkbox-tree-node'; } static get properties() { return { /** * Data hold by this node (contains the children). * * Specific data: * * - `data.name`: string representing the node name. * - `data.open`: boolean telling whether the node is expanded or not. * - `data.children` array containing the children of the node. */ data: { type: Object, value: function () { return null; }, observer: '_onDataChanged' }, onCheckChanged: { type: Function, } } } _onCheckChanged($event) { this.onCheckChanged(this.data); this._updateChildCheckBox(this, $event.target.checked); this._updateParentCheckBox(this.getParent()); } _updateChildCheckBox(node, checked, force) { if (node.get('data.checked') !== checked) { node.set('data.checked', checked); if (!node.get('data.notCheckable')) { node.onCheckChanged(node.data); } } if (node.getChildren().length) { node.getChildren().forEach((child) => this._updateChildCheckBox(child, checked, true)); } } _updateParentCheckBox(nodeData) { if (nodeData) { if (nodeData.getChildren().length) { let allChildChecked = true; for (let child of nodeData.getChildren()) { let childChecked = child.get('data.checked'); if (!childChecked) { allChildChecked = false; break; } } if (nodeData.get('data.checked') !== allChildChecked) { nodeData.set('data.checked', allChildChecked); if (!nodeData.get('data.notCheckable')) { nodeData.onCheckChanged(nodeData.data); } } } nodeData._updateParentCheckBox(nodeData.getParent()); } } _initializeChildren(parent) { if (parent.data && parent.data.open) { var nodes = parent.shadowRoot.querySelectorAll('.checkbox-tree-node'); if (nodes) { for (let i = 0; i < nodes.length; ++i) { nodes[i].onCheckChanged = parent.onCheckChanged; } } for (let i = 0; i < parent.data.children.length; ++i) { parent.data.children[i].parent = parent.data; } } } /** * Called whenever the data is changed to notify the lower nodes. */ _onDataChanged() { let self = this; setTimeout(function () { self._initializeChildren(self); }); } /** * Returns the necessary classes. * * @param {object} change An object containing the property that changed and its value. * @return {string} The class name indicating whether the node is open or closed */ _computeClass(change) { var open = change && change.base && change.base.open; var children = change && change.base && change.base.children; return 'node-preicon ' + ((open && children && children.length) ? 'expanded' : children && children.length ? 'collapsed' : ''); } /** * Returns the parent tree node. Returns `null` if root. */ getParent() { let host = Polymer.dom(this).getOwnerRoot().host; return host.tagName === 'INTEL-CHECKBOX-TREE-NODE' ? host : null; } /** * Returns the children tree nodes. */ getChildren() { return Polymer.dom(this.root).querySelectorAll('uwt-checkbox-tree-node'); } /** * Display/Hide the children nodes. */ toggleChildren() { let self = this; self.set('data.open', !self.data.open && self.data.children && self.data.children.length); setTimeout(function () { self.dispatchEvent(new CustomEvent('toggle', self)); self._initializeChildren(self); }); } } customElements.define(UWTCheckboxTreeNode.is, UWTCheckboxTreeNode); </script> <!-- `<uwt-checkbox-tree>` display a browsable tree of nodes (`<uwt-checkbox-tree-node>`) with expandable/collapsible capabilities and actions menu for each node. Example: <uwt-checkbox-tree></uwt-checkbox-tree> @demo --> <dom-module id='uwt-checkbox-tree'> <template> <div> <uwt-checkbox-tree-node id='root' data='{{data}}' onCheckChanged='{{onCheckChanged}}' class='checkbox-tree-node'></uwt-checkbox-tree-node> </div> </template> </dom-module> <script> class UWTCheckboxTree extends Polymer.Element { static get is() { return 'uwt-checkbox-tree'; } static get properties() { return { /** * Data hold by the root node (contains the children). * * Specific data: * * - `data.name`: string representing the node name. * - `data.open`: boolean telling whether the node is expanded or not. * - `data.children` array containing the children of the node. */ data: { type: Object, value: function () { return null; }, observer: '_onDataChanged' }, onCheckChanged: { type: Function } } } /** * Called whenever the data is changed to notify the lower nodes. */ _onDataChanged() { this.$.root.data = this.data; this.$.root.onCheckChanged = this.onCheckChanged; } } customElements.define(UWTCheckboxTree.is, UWTCheckboxTree); </script>