diff --git a/package.json b/package.json index 6068da0..64cb91e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tp/tp-tag-input", - "version": "1.0.0", + "version": "1.1.0", "description": "", "main": "tp-tag-input.js", "scripts": { diff --git a/tp-tag-input-popup.js b/tp-tag-input-popup.js index 7fae94e..54a0444 100644 --- a/tp-tag-input-popup.js +++ b/tp-tag-input-popup.js @@ -47,11 +47,13 @@ class TpTagInputPopup extends DomQuery(EventHelpers(LitElement)) { } render() { + const { selection } = this; + return html`
-
- ${this.filteredItems.map(item => html` -
${item.label}
+
+ ${this.filteredItems.map((item, idx) => html` +
${item.label}
`)}
@@ -103,12 +105,12 @@ class TpTagInputPopup extends DomQuery(EventHelpers(LitElement)) { } firstUpdated() { - this.listen(this.$.list, 'down', '_onItemTap'); + this.listen(this.$.list, 'mousedown', '_onItemClick'); } disconnectedCallback() { super.disconnectedCallback(); - this.unlisten(this.$.list, 'down', '_onItemTap'); + this.unlisten(this.$.list, 'mousedown', '_onItemClick'); } show() { @@ -132,11 +134,13 @@ class TpTagInputPopup extends DomQuery(EventHelpers(LitElement)) { this.visible = false; } - onItemClick(e) { + _onItemClick(e) { const item = closest(e.composedPath()[0], '.item', true); if (!item) return; - this.value = item.value; + this.value = item.item; this.dispatchEvent(new CustomEvent('selection-changed', { detail: this.value, bubbles: true, composed: true })); + this.hide(); + this.target.focus(); } _filterItemsByTerm() { @@ -176,7 +180,8 @@ class TpTagInputPopup extends DomQuery(EventHelpers(LitElement)) { case 13: // Enter const item = this.$.list.querySelector('.item[selected]'); if (item) { - this.value = this.$.itemRepeater.itemForElement(item); + this.value = item.item; + this.dispatchEvent(new CustomEvent('selection-changed', { detail: this.value, bubbles: true, composed: true })); } this.hide(); e.preventDefault(); @@ -190,16 +195,6 @@ class TpTagInputPopup extends DomQuery(EventHelpers(LitElement)) { } } - _onItemTap(e) { - const item = e.composedPath()[0]; - - if (item.classList.contains('item')) { - this.value = this.$.itemRepeater.itemForElement(item); - this.hide(); - this.target.focus(); - } - } - _scrollIntoView(element, container) { if (!element) { return; diff --git a/tp-tag-input.js b/tp-tag-input.js index 9eee40a..f0afe6e 100644 --- a/tp-tag-input.js +++ b/tp-tag-input.js @@ -13,6 +13,8 @@ import { EventHelpers } from '@tp/helpers/event-helpers.js'; import { DomQuery } from '@tp/helpers/dom-query.js'; import { reach } from '@tp/helpers/reach.js'; import { debounce } from '@tp/helpers/debounce.js'; +import { clone } from '@tp/helpers/clone.js'; +import { closest } from '@tp/helpers/closest.js'; const mixins = [ FormElement, @@ -52,13 +54,15 @@ class TpTagInput extends BaseElement { tp-input { min-height: 15px; outline: none; - margin: 5px; + margin: 0; padding: 0; display: flex; + flex: 1; } - + tp-input::part(wrap) { border: none; + flex: 1; } :host(.has-items) tp-input { @@ -94,20 +98,20 @@ class TpTagInput extends BaseElement { render() { const value = this.value || []; - + return html` -
+
${value.map(item => html` -
- +
+ ${item.label}
`)} - this._inputChanged(e)} required> - + this._inputChanged(e)} required> +
- this._itemSelected(e.detail.item)}> + this._itemSelected(e.detail)}> `; } @@ -173,10 +177,17 @@ class TpTagInput extends BaseElement { return true; } - _inputChanged(e) { - this._input = e.target.value; + _onClick(e) { + if (closest(e.composedPath()[0], '.remove-icon', true)) { + const item = closest(e.composedPath()[0], '.item', true); + if (!item) return; + this.value = this.value.filter(i => i.value !== item.item.value); + } + } + + _inputChanged(e) { + this._input = this.$.input.value; - console.log('input changed'); if (this.api && this._input.length > 2) { this._callFilterApiDebounced(); return; @@ -217,14 +228,13 @@ class TpTagInput extends BaseElement { _itemSelected(item) { if (item !== null) { if (this.allowDuplicates || !this._isAlreadySelected(item.label)) { - // Need to clone the item so polymer won't get confused if the user removes duplicated entries. - if (Array.isArray(this.value)) { - this.push('value', this._clone(item)); + if (!Array.isArray(this.value)) { + this.value = [ clone(item) ]; } else { - this.set('value', [ this._clone(item) ]); + this.value = [...this.value, clone(item)]; } } - this._input = ''; + this._clearInput(); this.$.autoCpl.selection = null; this.$.autoCpl.value = null; } @@ -232,7 +242,7 @@ class TpTagInput extends BaseElement { _inputBlur() { if (!this._tryToAddItem()) { - this._input = ''; + this._clearInput(); this.$.autoCpl.selection = null; this.$.autoCpl.value = null; this.$.autoCpl.hide(); @@ -260,7 +270,7 @@ class TpTagInput extends BaseElement { if (this._keyboardEventMatchesKeys(e, 'backspace')) { if (this._input === '' && this.value) { - this.pop('value'); + this.value = this.value.slice(0, -1); return; } } @@ -314,7 +324,7 @@ class TpTagInput extends BaseElement { const keyList = keys.split(' '); for (const key of keyList) { - if (key === e.key) { + if (key.toLowerCase() === e.key.toLowerCase()) { return true; } } @@ -374,7 +384,10 @@ class TpTagInput extends BaseElement { this.$.input.focus(); } - + _clearInput() { + this._input = ''; + this.$.input.value = ''; + } } window.customElements.define('tp-tag-input', TpTagInput);