2018-04-13 16:40:26 -07:00
|
|
|
/**
|
2016-12-20 16:21:35 -08:00
|
|
|
@license
|
2017-03-03 16:54:36 -08:00
|
|
|
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
2016-12-20 16:21:35 -08:00
|
|
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
|
|
|
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
|
|
|
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
|
|
|
|
Code distributed by Google as part of the polymer project is also
|
|
|
|
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
2018-04-13 16:40:26 -07:00
|
|
|
*/
|
|
|
|
|
import { PolymerElement } from '../../polymer-element.js';
|
|
|
|
|
|
|
|
|
|
import { dedupingMixin } from '../utils/mixin.js';
|
|
|
|
|
import { calculateSplices } from '../utils/array-splice.js';
|
|
|
|
|
import { ElementMixin } from '../mixins/element-mixin.js';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Element mixin for recording dynamic associations between item paths in a
|
|
|
|
|
* master `items` array and a `selected` array such that path changes to the
|
|
|
|
|
* master array (at the host) element or elsewhere via data-binding) are
|
|
|
|
|
* correctly propagated to items in the selected array and vice-versa.
|
|
|
|
|
*
|
|
|
|
|
* The `items` property accepts an array of user data, and via the
|
|
|
|
|
* `select(item)` and `deselect(item)` API, updates the `selected` property
|
|
|
|
|
* which may be bound to other parts of the application, and any changes to
|
|
|
|
|
* sub-fields of `selected` item(s) will be kept in sync with items in the
|
|
|
|
|
* `items` array. When `multi` is false, `selected` is a property
|
|
|
|
|
* representing the last selected item. When `multi` is true, `selected`
|
|
|
|
|
* is an array of multiply selected items.
|
|
|
|
|
*
|
|
|
|
|
* @polymer
|
|
|
|
|
* @mixinFunction
|
2018-04-23 17:33:52 -07:00
|
|
|
* @appliesMixin ElementMixin
|
2018-04-13 16:40:26 -07:00
|
|
|
* @summary Element mixin for recording dynamic associations between item paths in a
|
|
|
|
|
* master `items` array and a `selected` array
|
|
|
|
|
*/
|
|
|
|
|
let ArraySelectorMixin = dedupingMixin(superClass => {
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
/**
|
|
|
|
|
* @constructor
|
|
|
|
|
* @implements {Polymer_ElementMixin}
|
2018-07-20 21:40:34 -07:00
|
|
|
* @private
|
2018-04-13 16:40:26 -07:00
|
|
|
*/
|
|
|
|
|
let elementBase = ElementMixin(superClass);
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2017-02-21 23:23:40 -08:00
|
|
|
/**
|
2017-04-26 14:58:43 -07:00
|
|
|
* @polymer
|
2018-04-13 16:40:26 -07:00
|
|
|
* @mixinClass
|
|
|
|
|
* @implements {Polymer_ArraySelectorMixin}
|
|
|
|
|
* @unrestricted
|
2017-02-21 23:23:40 -08:00
|
|
|
*/
|
2018-04-13 16:40:26 -07:00
|
|
|
class ArraySelectorMixin extends elementBase {
|
|
|
|
|
|
|
|
|
|
static get properties() {
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* An array containing items from which selection will be made.
|
|
|
|
|
*/
|
|
|
|
|
items: {
|
|
|
|
|
type: Array,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* When `true`, multiple items may be selected at once (in this case,
|
|
|
|
|
* `selected` is an array of currently selected items). When `false`,
|
|
|
|
|
* only one item may be selected at a time.
|
|
|
|
|
*/
|
|
|
|
|
multi: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
value: false,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* When `multi` is true, this is an array that contains any selected.
|
|
|
|
|
* When `multi` is false, this is the currently selected item, or `null`
|
|
|
|
|
* if no item is selected.
|
2018-11-04 13:29:04 -08:00
|
|
|
* @type {?Object|?Array<!Object>}
|
2018-04-13 16:40:26 -07:00
|
|
|
*/
|
2018-11-04 13:29:04 -08:00
|
|
|
selected: {type: Object, notify: true},
|
2018-04-13 16:40:26 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* When `multi` is false, this is the currently selected item, or `null`
|
|
|
|
|
* if no item is selected.
|
|
|
|
|
* @type {?Object}
|
|
|
|
|
*/
|
2018-11-04 13:29:04 -08:00
|
|
|
selectedItem: {type: Object, notify: true},
|
2018-04-13 16:40:26 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* When `true`, calling `select` on an item that is already selected
|
|
|
|
|
* will deselect the item.
|
|
|
|
|
*/
|
2018-11-04 13:29:04 -08:00
|
|
|
toggle: {type: Boolean, value: false}
|
2017-06-06 11:35:38 -07:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
};
|
|
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
static get observers() {
|
|
|
|
|
return ['__updateSelection(multi, items.*)'];
|
|
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
constructor() {
|
|
|
|
|
super();
|
|
|
|
|
this.__lastItems = null;
|
|
|
|
|
this.__lastMulti = null;
|
|
|
|
|
this.__selectedMap = null;
|
|
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
__updateSelection(multi, itemsInfo) {
|
|
|
|
|
let path = itemsInfo.path;
|
2019-02-20 06:14:45 -06:00
|
|
|
if (path == JSCompiler_renameProperty('items', this)) {
|
2018-04-13 16:40:26 -07:00
|
|
|
// Case 1 - items array changed, so diff against previous array and
|
|
|
|
|
// deselect any removed items and adjust selected indices
|
|
|
|
|
let newItems = itemsInfo.base || [];
|
|
|
|
|
let lastItems = this.__lastItems;
|
|
|
|
|
let lastMulti = this.__lastMulti;
|
|
|
|
|
if (multi !== lastMulti) {
|
|
|
|
|
this.clearSelection();
|
|
|
|
|
}
|
|
|
|
|
if (lastItems) {
|
|
|
|
|
let splices = calculateSplices(newItems, lastItems);
|
|
|
|
|
this.__applySplices(splices);
|
|
|
|
|
}
|
|
|
|
|
this.__lastItems = newItems;
|
|
|
|
|
this.__lastMulti = multi;
|
2019-02-20 06:14:45 -06:00
|
|
|
} else if (itemsInfo.path == `${JSCompiler_renameProperty('items', this)}.splices`) {
|
2018-04-13 16:40:26 -07:00
|
|
|
// Case 2 - got specific splice information describing the array mutation:
|
|
|
|
|
// deselect any removed items and adjust selected indices
|
|
|
|
|
this.__applySplices(itemsInfo.value.indexSplices);
|
|
|
|
|
} else {
|
|
|
|
|
// Case 3 - an array element was changed, so deselect the previous
|
|
|
|
|
// item for that index if it was previously selected
|
2019-02-20 06:14:45 -06:00
|
|
|
let part = path.slice(`${JSCompiler_renameProperty('items', this)}.`.length);
|
2018-04-13 16:40:26 -07:00
|
|
|
let idx = parseInt(part, 10);
|
|
|
|
|
if ((part.indexOf('.') < 0) && part == idx) {
|
|
|
|
|
this.__deselectChangedIdx(idx);
|
|
|
|
|
}
|
2017-01-03 10:22:25 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
}
|
2017-01-03 10:22:25 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
__applySplices(splices) {
|
|
|
|
|
let selected = this.__selectedMap;
|
|
|
|
|
// Adjust selected indices and mark removals
|
|
|
|
|
for (let i=0; i<splices.length; i++) {
|
|
|
|
|
let s = splices[i];
|
|
|
|
|
selected.forEach((idx, item) => {
|
|
|
|
|
if (idx < s.index) {
|
|
|
|
|
// no change
|
|
|
|
|
} else if (idx >= s.index + s.removed.length) {
|
|
|
|
|
// adjust index
|
|
|
|
|
selected.set(item, idx + s.addedCount - s.removed.length);
|
|
|
|
|
} else {
|
|
|
|
|
// remove index
|
|
|
|
|
selected.set(item, -1);
|
2016-12-20 16:21:35 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
});
|
|
|
|
|
for (let j=0; j<s.addedCount; j++) {
|
|
|
|
|
let idx = s.index + j;
|
|
|
|
|
if (selected.has(this.items[idx])) {
|
|
|
|
|
selected.set(this.items[idx], idx);
|
2017-01-26 11:03:33 -08:00
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
}
|
|
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
// Update linked paths
|
|
|
|
|
this.__updateLinks();
|
|
|
|
|
// Remove selected items that were removed from the items array
|
|
|
|
|
let sidx = 0;
|
|
|
|
|
selected.forEach((idx, item) => {
|
|
|
|
|
if (idx < 0) {
|
|
|
|
|
if (this.multi) {
|
2019-02-20 06:14:45 -06:00
|
|
|
this.splice(JSCompiler_renameProperty('selected', this), sidx, 1);
|
2018-04-13 16:40:26 -07:00
|
|
|
} else {
|
|
|
|
|
this.selected = this.selectedItem = null;
|
2017-01-09 11:28:48 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
selected.delete(item);
|
|
|
|
|
} else {
|
|
|
|
|
sidx++;
|
2017-01-06 11:31:49 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__updateLinks() {
|
|
|
|
|
this.__dataLinkedPaths = {};
|
|
|
|
|
if (this.multi) {
|
2017-01-09 11:28:48 -08:00
|
|
|
let sidx = 0;
|
2018-04-13 16:40:26 -07:00
|
|
|
this.__selectedMap.forEach(idx => {
|
|
|
|
|
if (idx >= 0) {
|
2019-02-20 06:14:45 -06:00
|
|
|
this.linkPaths(
|
|
|
|
|
`${JSCompiler_renameProperty('items', this)}.${idx}`,
|
|
|
|
|
`${JSCompiler_renameProperty('selected', this)}.${sidx++}`);
|
2017-01-05 18:51:29 -08:00
|
|
|
}
|
2017-01-09 11:28:48 -08:00
|
|
|
});
|
2018-04-13 16:40:26 -07:00
|
|
|
} else {
|
|
|
|
|
this.__selectedMap.forEach(idx => {
|
2019-02-20 06:14:45 -06:00
|
|
|
this.linkPaths(
|
|
|
|
|
JSCompiler_renameProperty('selected', this),
|
|
|
|
|
`${JSCompiler_renameProperty('items', this)}.${idx}`);
|
|
|
|
|
this.linkPaths(
|
|
|
|
|
JSCompiler_renameProperty('selectedItem', this),
|
|
|
|
|
`${JSCompiler_renameProperty('items', this)}.${idx}`);
|
2018-04-13 16:40:26 -07:00
|
|
|
});
|
2016-12-20 16:21:35 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
/**
|
|
|
|
|
* Clears the selection state.
|
2018-11-04 13:29:04 -08:00
|
|
|
* @override
|
2018-04-13 16:40:26 -07:00
|
|
|
* @return {void}
|
|
|
|
|
*/
|
|
|
|
|
clearSelection() {
|
|
|
|
|
// Unbind previous selection
|
|
|
|
|
this.__dataLinkedPaths = {};
|
|
|
|
|
// The selected map stores 3 pieces of information:
|
|
|
|
|
// key: items array object
|
|
|
|
|
// value: items array index
|
|
|
|
|
// order: selected array index
|
|
|
|
|
this.__selectedMap = new Map();
|
|
|
|
|
// Initialize selection
|
|
|
|
|
this.selected = this.multi ? [] : null;
|
|
|
|
|
this.selectedItem = null;
|
|
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
/**
|
|
|
|
|
* Returns whether the item is currently selected.
|
|
|
|
|
*
|
2018-11-04 13:29:04 -08:00
|
|
|
* @override
|
2018-04-13 16:40:26 -07:00
|
|
|
* @param {*} item Item from `items` array to test
|
|
|
|
|
* @return {boolean} Whether the item is selected
|
|
|
|
|
*/
|
|
|
|
|
isSelected(item) {
|
|
|
|
|
return this.__selectedMap.has(item);
|
|
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
/**
|
|
|
|
|
* Returns whether the item is currently selected.
|
|
|
|
|
*
|
2018-11-04 13:29:04 -08:00
|
|
|
* @override
|
2018-04-13 16:40:26 -07:00
|
|
|
* @param {number} idx Index from `items` array to test
|
|
|
|
|
* @return {boolean} Whether the item is selected
|
|
|
|
|
*/
|
|
|
|
|
isIndexSelected(idx) {
|
|
|
|
|
return this.isSelected(this.items[idx]);
|
|
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
__deselectChangedIdx(idx) {
|
|
|
|
|
let sidx = this.__selectedIndexForItemIndex(idx);
|
|
|
|
|
if (sidx >= 0) {
|
|
|
|
|
let i = 0;
|
|
|
|
|
this.__selectedMap.forEach((idx, item) => {
|
|
|
|
|
if (sidx == i++) {
|
|
|
|
|
this.deselect(item);
|
|
|
|
|
}
|
|
|
|
|
});
|
2017-01-05 18:51:29 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
}
|
2017-01-05 18:51:29 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
__selectedIndexForItemIndex(idx) {
|
2019-02-20 06:14:45 -06:00
|
|
|
let selected = this.__dataLinkedPaths[`${JSCompiler_renameProperty('items', this)}.${idx}`];
|
2018-04-13 16:40:26 -07:00
|
|
|
if (selected) {
|
2019-02-20 06:14:45 -06:00
|
|
|
return parseInt(selected.slice(`${JSCompiler_renameProperty('selected', this)}.`.length), 10);
|
2017-01-26 11:03:33 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
}
|
2017-01-26 11:03:33 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
/**
|
|
|
|
|
* Deselects the given item if it is already selected.
|
|
|
|
|
*
|
2018-11-04 13:29:04 -08:00
|
|
|
* @override
|
2018-04-13 16:40:26 -07:00
|
|
|
* @param {*} item Item from `items` array to deselect
|
|
|
|
|
* @return {void}
|
|
|
|
|
*/
|
|
|
|
|
deselect(item) {
|
|
|
|
|
let idx = this.__selectedMap.get(item);
|
|
|
|
|
if (idx >= 0) {
|
|
|
|
|
this.__selectedMap.delete(item);
|
|
|
|
|
let sidx;
|
|
|
|
|
if (this.multi) {
|
|
|
|
|
sidx = this.__selectedIndexForItemIndex(idx);
|
2017-01-26 11:03:33 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
this.__updateLinks();
|
|
|
|
|
if (this.multi) {
|
2019-02-20 06:14:45 -06:00
|
|
|
this.splice(JSCompiler_renameProperty('selected', this), sidx, 1);
|
2018-04-13 16:40:26 -07:00
|
|
|
} else {
|
|
|
|
|
this.selected = this.selectedItem = null;
|
2016-12-20 16:21:35 -08:00
|
|
|
}
|
|
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
/**
|
|
|
|
|
* Deselects the given index if it is already selected.
|
|
|
|
|
*
|
2018-11-04 13:29:04 -08:00
|
|
|
* @override
|
2018-04-13 16:40:26 -07:00
|
|
|
* @param {number} idx Index from `items` array to deselect
|
|
|
|
|
* @return {void}
|
|
|
|
|
*/
|
|
|
|
|
deselectIndex(idx) {
|
|
|
|
|
this.deselect(this.items[idx]);
|
|
|
|
|
}
|
2017-01-26 11:03:33 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
/**
|
|
|
|
|
* Selects the given item. When `toggle` is true, this will automatically
|
|
|
|
|
* deselect the item if already selected.
|
|
|
|
|
*
|
2018-11-04 13:29:04 -08:00
|
|
|
* @override
|
2018-04-13 16:40:26 -07:00
|
|
|
* @param {*} item Item from `items` array to select
|
|
|
|
|
* @return {void}
|
|
|
|
|
*/
|
|
|
|
|
select(item) {
|
|
|
|
|
this.selectIndex(this.items.indexOf(item));
|
|
|
|
|
}
|
2017-01-05 18:51:29 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
/**
|
|
|
|
|
* Selects the given index. When `toggle` is true, this will automatically
|
|
|
|
|
* deselect the item if already selected.
|
|
|
|
|
*
|
2018-11-04 13:29:04 -08:00
|
|
|
* @override
|
2018-04-13 16:40:26 -07:00
|
|
|
* @param {number} idx Index from `items` array to select
|
|
|
|
|
* @return {void}
|
|
|
|
|
*/
|
|
|
|
|
selectIndex(idx) {
|
|
|
|
|
let item = this.items[idx];
|
|
|
|
|
if (!this.isSelected(item)) {
|
|
|
|
|
if (!this.multi) {
|
|
|
|
|
this.__selectedMap.clear();
|
|
|
|
|
}
|
|
|
|
|
this.__selectedMap.set(item, idx);
|
|
|
|
|
this.__updateLinks();
|
|
|
|
|
if (this.multi) {
|
2019-02-20 06:14:45 -06:00
|
|
|
this.push(JSCompiler_renameProperty('selected', this), item);
|
2018-04-13 16:40:26 -07:00
|
|
|
} else {
|
|
|
|
|
this.selected = this.selectedItem = item;
|
2016-12-20 16:21:35 -08:00
|
|
|
}
|
2018-04-13 16:40:26 -07:00
|
|
|
} else if (this.toggle) {
|
|
|
|
|
this.deselectIndex(idx);
|
2016-12-20 16:21:35 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-21 23:23:40 -08:00
|
|
|
}
|
2016-12-20 16:21:35 -08:00
|
|
|
|
2018-04-13 16:40:26 -07:00
|
|
|
return ArraySelectorMixin;
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// export mixin
|
|
|
|
|
export { ArraySelectorMixin };
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @constructor
|
2018-04-23 17:33:52 -07:00
|
|
|
* @extends {PolymerElement}
|
2018-04-13 16:40:26 -07:00
|
|
|
* @implements {Polymer_ArraySelectorMixin}
|
2018-07-23 17:10:41 -07:00
|
|
|
* @private
|
2018-04-13 16:40:26 -07:00
|
|
|
*/
|
|
|
|
|
let baseArraySelector = ArraySelectorMixin(PolymerElement);
|
|
|
|
|
|
|
|
|
|
/**
|
2018-04-23 17:33:52 -07:00
|
|
|
* Element implementing the `ArraySelector` mixin, which records
|
2018-04-13 16:40:26 -07:00
|
|
|
* dynamic associations between item paths in a master `items` array and a
|
|
|
|
|
* `selected` array such that path changes to the master array (at the host)
|
|
|
|
|
* element or elsewhere via data-binding) are correctly propagated to items
|
|
|
|
|
* in the selected array and vice-versa.
|
|
|
|
|
*
|
|
|
|
|
* The `items` property accepts an array of user data, and via the
|
|
|
|
|
* `select(item)` and `deselect(item)` API, updates the `selected` property
|
|
|
|
|
* which may be bound to other parts of the application, and any changes to
|
|
|
|
|
* sub-fields of `selected` item(s) will be kept in sync with items in the
|
|
|
|
|
* `items` array. When `multi` is false, `selected` is a property
|
|
|
|
|
* representing the last selected item. When `multi` is true, `selected`
|
|
|
|
|
* is an array of multiply selected items.
|
|
|
|
|
*
|
|
|
|
|
* Example:
|
|
|
|
|
*
|
2018-04-23 17:33:52 -07:00
|
|
|
* ```js
|
|
|
|
|
* import {PolymerElement} from '@polymer/polymer';
|
|
|
|
|
* import '@polymer/polymer/lib/elements/array-selector.js';
|
2018-04-13 16:40:26 -07:00
|
|
|
*
|
2018-04-23 17:33:52 -07:00
|
|
|
* class EmployeeList extends PolymerElement {
|
|
|
|
|
* static get _template() {
|
|
|
|
|
* return html`
|
|
|
|
|
* <div> Employee list: </div>
|
|
|
|
|
* <dom-repeat id="employeeList" items="{{employees}}">
|
|
|
|
|
* <template>
|
|
|
|
|
* <div>First name: <span>{{item.first}}</span></div>
|
|
|
|
|
* <div>Last name: <span>{{item.last}}</span></div>
|
|
|
|
|
* <button on-click="toggleSelection">Select</button>
|
|
|
|
|
* </template>
|
|
|
|
|
* </dom-repeat>
|
2018-04-13 16:40:26 -07:00
|
|
|
*
|
2018-04-23 17:33:52 -07:00
|
|
|
* <array-selector id="selector"
|
|
|
|
|
* items="{{employees}}"
|
|
|
|
|
* selected="{{selected}}"
|
|
|
|
|
* multi toggle></array-selector>
|
2018-04-13 16:40:26 -07:00
|
|
|
*
|
2018-04-23 17:33:52 -07:00
|
|
|
* <div> Selected employees: </div>
|
|
|
|
|
* <dom-repeat items="{{selected}}">
|
|
|
|
|
* <template>
|
|
|
|
|
* <div>First name: <span>{{item.first}}</span></div>
|
|
|
|
|
* <div>Last name: <span>{{item.last}}</span></div>
|
|
|
|
|
* </template>
|
|
|
|
|
* </dom-repeat>`;
|
|
|
|
|
* }
|
|
|
|
|
* static get is() { return 'employee-list'; }
|
|
|
|
|
* static get properties() {
|
|
|
|
|
* return {
|
|
|
|
|
* employees: {
|
|
|
|
|
* value() {
|
|
|
|
|
* return [
|
|
|
|
|
* {first: 'Bob', last: 'Smith'},
|
|
|
|
|
* {first: 'Sally', last: 'Johnson'},
|
|
|
|
|
* ...
|
|
|
|
|
* ];
|
|
|
|
|
* }
|
|
|
|
|
* }
|
|
|
|
|
* };
|
|
|
|
|
* }
|
|
|
|
|
* toggleSelection(e) {
|
|
|
|
|
* const item = this.$.employeeList.itemForElement(e.target);
|
|
|
|
|
* this.$.selector.select(item);
|
|
|
|
|
* }
|
|
|
|
|
* }
|
2018-04-13 16:40:26 -07:00
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
* @polymer
|
|
|
|
|
* @customElement
|
|
|
|
|
* @extends {baseArraySelector}
|
2018-04-23 17:33:52 -07:00
|
|
|
* @appliesMixin ArraySelectorMixin
|
2018-04-13 16:40:26 -07:00
|
|
|
* @summary Custom element that links paths between an input `items` array and
|
|
|
|
|
* an output `selected` item or array based on calls to its selection API.
|
|
|
|
|
*/
|
|
|
|
|
class ArraySelector extends baseArraySelector {
|
|
|
|
|
// Not needed to find template; can be removed once the analyzer
|
|
|
|
|
// can find the tag name from customElements.define call
|
|
|
|
|
static get is() { return 'array-selector'; }
|
2018-10-30 17:15:27 -04:00
|
|
|
static get template() { return null; }
|
2018-04-13 16:40:26 -07:00
|
|
|
}
|
|
|
|
|
customElements.define(ArraySelector.is, ArraySelector);
|
|
|
|
|
export { ArraySelector };
|