From d8b98496435cde588f5c08aaeb6135511e2c5410 Mon Sep 17 00:00:00 2001 From: Guillaume Cusnieux Date: Mon, 22 Feb 2021 12:19:40 +0100 Subject: [PATCH] fix(gv-autocomplete): remove overlap when has several autocomplete --- src/atoms/gv-autocomplete.js | 36 ++++++++++++++++++++---- stories/atoms/gv-autocomplete.stories.js | 2 ++ stories/organisms/gv-schema-form.test.js | 2 ++ stories/resources/schemas/mixed.json | 10 +++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/atoms/gv-autocomplete.js b/src/atoms/gv-autocomplete.js index 14534734..4a61088f 100644 --- a/src/atoms/gv-autocomplete.js +++ b/src/atoms/gv-autocomplete.js @@ -33,6 +33,7 @@ const ESCAPE_KEY_CODE = 27; * * @fires gv-autocomplete:search - Custom event when user search value * @fires gv-autocomplete:select - Custom event when user select value + * @fires gv-autocomplete:opened - Custom event after opened autocomplete * * @slot style - The options style * @slot input - The input to wrap @@ -62,7 +63,7 @@ export class GvAutocomplete extends LitElement { filter: { type: Boolean | Function }, size: { type: Number }, _options: { type: Array, attribute: false }, - _forceOpen: { type: Boolean }, + _forceOpen: { type: Boolean, attribute: false }, }; } @@ -156,6 +157,7 @@ export class GvAutocomplete extends LitElement { this.style = ''; this.filter = false; this.size = 5; + this._handleOpened = this._onOpened.bind(this); } set options(options) { @@ -192,7 +194,7 @@ export class GvAutocomplete extends LitElement { this.value = event.target.value; if (this.value != null && this.value.trim().length >= this.minChars) { this._cancellableTimeout = setTimeout(() => { - this._forceOpen = true; + this._open(); dispatchCustomEvent(this, 'search', this.value); }, 200); } else { @@ -207,7 +209,7 @@ export class GvAutocomplete extends LitElement { }); } this.value = this._getInput().value = value; - this._forceOpen = false; + this._close(); dispatchCustomEvent(this, 'select', option); } @@ -324,7 +326,7 @@ export class GvAutocomplete extends LitElement { this._onSelect(candidate.getAttribute('data-value')); this._updateHover(); } - this._forceOpen = false; + this._close(); break; } @@ -362,13 +364,23 @@ export class GvAutocomplete extends LitElement { } } - _onFocus() { + _open() { this._forceOpen = true; + dispatchCustomEvent(this, 'opened', { target: this }); + } + + _close() { + this._forceOpen = false; + } + + _onFocus() { + this._open(); } _onBlur() { + // Important when using custom HTML in options if (this._shouldSelect === false) { - this._forceOpen = false; + this._close(); } } @@ -416,6 +428,17 @@ export class GvAutocomplete extends LitElement { } } + _onOpened({ detail }) { + if (detail.target !== this) { + this._close(); + } + } + + connectedCallback() { + super.connectedCallback(); + window.addEventListener('gv-autocomplete:opened', this._handleOpened); + } + disconnectedCallback() { if (this._handlers) { this.shadowRoot.removeEventListener('input', this._handlers.input); @@ -425,6 +448,7 @@ export class GvAutocomplete extends LitElement { input.removeEventListener('blur', this._handlers.blur); input.removeEventListener('gv-input:clear', this._handlers.clear); } + window.removeEventListener('gv-autocomplete:open', this._handleOpened); super.disconnectedCallback(); } } diff --git a/stories/atoms/gv-autocomplete.stories.js b/stories/atoms/gv-autocomplete.stories.js index bbad8b4b..b129bab8 100644 --- a/stories/atoms/gv-autocomplete.stories.js +++ b/stories/atoms/gv-autocomplete.stories.js @@ -38,6 +38,8 @@ const conf = { css: ` :host { height: 175px; + display: flex; + flex-direction: column; } gv-autocomplete { width: 350px; diff --git a/stories/organisms/gv-schema-form.test.js b/stories/organisms/gv-schema-form.test.js index 422bdd1f..81bc3caa 100644 --- a/stories/organisms/gv-schema-form.test.js +++ b/stories/organisms/gv-schema-form.test.js @@ -68,6 +68,7 @@ describe('S C H E M A F O R M', () => { 'body-with-el', 'path-operator', 'resources', + 'another-list-resources', 'attributes', 'timeToLiveSeconds', 'useResponseCacheHeaders', @@ -116,6 +117,7 @@ describe('S C H E M A F O R M', () => { 'body-with-el', 'path-operator', 'resources', + 'another-list-resources', 'attributes', 'timeToLiveSeconds', 'useResponseCacheHeaders', diff --git a/stories/resources/schemas/mixed.json b/stories/resources/schemas/mixed.json index c28d7872..d28664c9 100644 --- a/stories/resources/schemas/mixed.json +++ b/stories/resources/schemas/mixed.json @@ -76,6 +76,16 @@ } } }, + "another-list-resources": { + "title": "Async list of resource", + "description": "Special field that's dispatch an event after add in DOM, usefull for async load", + "type": "string", + "x-schema-form": { + "event": { + "name": "fetch-data" + } + } + }, "attributes": { "type": "array", "title": "Assign context attributes",