From da74c622fb323879078a07398b8f90939ccebdaa Mon Sep 17 00:00:00 2001 From: Jonas Knobloch Date: Wed, 6 Nov 2024 10:26:42 +0100 Subject: [PATCH] Extend dropdown visibility fix to all affected keybinds --- .../Private/App/Components/VisualSearch.js | 35 +++++++------------ Resources/Public/visualsearch.min.js | 2 +- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/Resources/Private/App/Components/VisualSearch.js b/Resources/Private/App/Components/VisualSearch.js index 0305e9c..ff93c19 100644 --- a/Resources/Private/App/Components/VisualSearch.js +++ b/Resources/Private/App/Components/VisualSearch.js @@ -376,40 +376,29 @@ export class VisualSearch extends LitElement { return; } - if (event.key === 'ArrowDown') { - event.preventDefault(); - - this.renderRoot.querySelector('.vs-search__dropdown-item')?.focus(); - - return; - } - - if (event.key === 'ArrowUp' || (event.key === 'Tab' && event.shiftKey)) { + // Firefox: necessary to navigate to dropdown + if (event.key === 'Tab' || event.key === 'ArrowDown' || event.key === 'ArrowUp') + { event.preventDefault(); - const items = this.renderRoot.querySelectorAll('.vs-search__dropdown-item'); + const dropdown = this.renderRoot.querySelector('.vs-search__dropdown'); - if (items.length === 0) { + if (dropdown === null) { return; } - items.item(items.length - 1).focus(); + const items = dropdown.querySelectorAll('.vs-search__dropdown-item'); - return; - } - - // Firefox: necessary to navigate to first item in dropdown - if (event.key === 'Tab' && !event.shiftKey) { - event.preventDefault(); + dropdown.classList.add('vs-search__dropdown--visible'); - const dropdown = this.renderRoot.querySelector('.vs-search__dropdown'); + if ((event.key === 'Tab' && !event.shiftKey) || event.key === 'ArrowDown') { + items.item(0)?.focus(); + } - if (dropdown === null) { - return; + if ((event.key === 'Tab' && event.shiftKey) || event.key === 'ArrowUp') { + items.item(items.length - 1)?.focus(); } - dropdown.classList.add('vs-search__dropdown--visible'); - dropdown.querySelector('.vs-search__dropdown-item')?.focus(); dropdown.classList.remove('vs-search__dropdown--visible'); return; diff --git a/Resources/Public/visualsearch.min.js b/Resources/Public/visualsearch.min.js index 5c3dcba..2ffe0be 100644 --- a/Resources/Public/visualsearch.min.js +++ b/Resources/Public/visualsearch.min.js @@ -199,7 +199,7 @@ ${this.changed&&this.selectedFacets.at(-1)?.value!==null?d``:""} - `}_mode(){return this.selectedFacets.length>0&&this.selectedFacets.at(-1).value==null}_input(){return this.renderRoot.querySelector("input")}_sort(){return this.renderRoot.querySelector("#sorting")}_log(t){let e=new CustomEvent("debug",{detail:{message:t}});this.renderRoot.dispatchEvent(e)}complete(t){this._log("complete: "+t.label),this._mode()?this.pushValue(t.obj):this.pushFacet(t.obj)}handleFocus(t){t.target.value===""&&this.completeTerm("")}handleKeyDown(t){if(t.key==="Enter"){if(this._mode()){if(t.target.value==="")return;this.pushValue(new E(t.target.value,t.target.value))}else this.storeQuery(this.collectQuery()).then(()=>{window.location.reload()});return}if(t.key==="Backspace"&&t.target.value===""){this.popFacet();return}if(t.key==="ArrowDown"){t.preventDefault(),this.renderRoot.querySelector(".vs-search__dropdown-item")?.focus();return}if(t.key==="ArrowUp"||t.key==="Tab"&&t.shiftKey){t.preventDefault();let e=this.renderRoot.querySelectorAll(".vs-search__dropdown-item");if(e.length===0)return;e.item(e.length-1).focus();return}if(t.key==="Tab"&&!t.shiftKey){t.preventDefault();let e=this.renderRoot.querySelector(".vs-search__dropdown");if(e===null)return;e.classList.add("vs-search__dropdown--visible"),e.querySelector(".vs-search__dropdown-item")?.focus(),e.classList.remove("vs-search__dropdown--visible");return}if(t.key==="Escape"){this._input().blur();return}}handleNavigation(t,e){if(t.key==="ArrowDown"){if(t.preventDefault(),e===this.autocomplete.length-1){this._input().focus();return}this.renderRoot.querySelectorAll(".vs-search__dropdown-item").item(e+1).focus();return}if(t.key==="ArrowUp"){if(t.preventDefault(),e===0){this._input().focus();return}this.renderRoot.querySelectorAll(".vs-search__dropdown-item").item(e-1).focus();return}if(t.key==="Tab"&&!t.shiftKey&&e===this.autocomplete.length-1){t.preventDefault(),this._input().focus();return}if(t.key==="Escape"){this._input().focus();return}}handleInput(t){this.completeTerm(t.target.value)}completeTerm(t){let e=(s,...i)=>{s(...i).then(()=>{this.updateAutocomplete()}).catch(o=>{this._log(o)})};this.storeQuery(this.collectQuery()).then(()=>{this._mode()?e(this.fetchValues.bind(this),this.selectedFacets.at(-1).facet.value,"",t):e(this.fetchFacets.bind(this),"",t)})}loadStateFromQuery(){this.selectedFacets=this.query.facets.map(t=>({facet:new L(t.facet,t.facetLabel),value:new E(t.value,t.valueLabel)}))}updateAutocomplete(){this._mode()?this.autocomplete=this.values.map(t=>({value:t.value,label:t.label,obj:t})):this.autocomplete=this.facets.map(t=>({value:t.value,label:t.label,obj:t}))}pushFacet(t){this.selectedFacets.push({facet:t,value:null}),this.requestUpdate("selectedFacets"),t.inputType&&(this._input().type=t.inputType),this._input().value="",this.autocomplete=[],this.renderRoot.activeElement!==this._input()?this._input().focus():this.completeTerm("")}pushValue(t){this.selectedFacets.at(-1).value=t,this.requestUpdate("selectedFacets"),this._input().type="text",this._input().value="",this.autocomplete=[],this.renderRoot.activeElement!==this._input()?this._input().focus():this.completeTerm("")}popFacet(){let t=this.selectedFacets.pop();return this.requestUpdate("selectedFacets"),this._input().type="text",this.completeTerm(""),t}popValue(){if(this.selectedFacets.length===0)return;let t=this.selectedFacets.at(-1).value;return this.selectedFacets.at(-1).value=null,this.requestUpdate("selectedFacets"),this._input().type="text",this.completeTerm(""),t}submit(){this._mode()&&this.popFacet(),this.storeQuery(this.collectQuery()).then(()=>{window.location.reload()})}clear(){this._input().value="",this._sort()&&(this._sort().value=""),this.selectedFacets=[],this.autocomplete=[],this.storeQuery(this.collectQuery()).then(()=>{window.location.reload()})}deleteFacet(t){this.selectedFacets.splice(t,1),this.requestUpdate("selectedFacets"),this.completeTerm(this._input().value)}async fetchFacets(t,e){let s=new URL(this.facetsAction,window.location.origin);return s.searchParams.set("search",this.search),t===void 0&&(t=""),e===void 0&&(e=""),s.searchParams.set("query",t),s.searchParams.set("term",e),fetch(s,{method:"GET",headers:{Accept:"application/json"}}).then(o=>{if(!o.ok)throw new Error(o.statusText);return o.json()}).then(o=>{let n=o.map(c=>L.fromObject(c));n.every(L.validate)||this._log("invalid facets"),this.facets=n})}async fetchValues(t,e,s){let i=new URL(this.valueAction,window.location.origin);return i.searchParams.set("search",this.search),t===void 0&&(t=""),e===void 0&&(e=""),s===void 0&&(s=""),i.searchParams.set("facet",t),i.searchParams.set("query",e),i.searchParams.set("term",s),fetch(i,{method:"GET",headers:{Accept:"application/json"}}).then(n=>{if(!n.ok)throw new Error(n.statusText);return n.json()}).then(n=>{let c=n.map(a=>E.fromObject(a));c.every(E.validate)||this._log("invalid values"),this.values=c})}async storeQuery(t){let e=new URL(this.queryAction,window.location.origin);t===void 0&&(t={});let s={method:"PUT",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({query:t})};return fetch(e,s).then(i=>{if(!i.ok)throw new Error(i.statusText);return i.json()})}collectQuery(){let t=this.selectedFacets.reduce((e,s)=>(s.value==null||e.push({facetLabel:s.facet.label,facet:s.facet.value,valueLabel:s.value.label,value:s.value.value}),e),[]);return{identifier:this.search,sorting:this._sort()?this._sort().value:"",facets:t}}encodeQuery(){return btoa(encodeURIComponent(JSON.stringify(this.collectQuery().facets)))}};customElements.define("visual-search",Y);var tt=class extends f{static styles=g` + `}_mode(){return this.selectedFacets.length>0&&this.selectedFacets.at(-1).value==null}_input(){return this.renderRoot.querySelector("input")}_sort(){return this.renderRoot.querySelector("#sorting")}_log(t){let e=new CustomEvent("debug",{detail:{message:t}});this.renderRoot.dispatchEvent(e)}complete(t){this._log("complete: "+t.label),this._mode()?this.pushValue(t.obj):this.pushFacet(t.obj)}handleFocus(t){t.target.value===""&&this.completeTerm("")}handleKeyDown(t){if(t.key==="Enter"){if(this._mode()){if(t.target.value==="")return;this.pushValue(new E(t.target.value,t.target.value))}else this.storeQuery(this.collectQuery()).then(()=>{window.location.reload()});return}if(t.key==="Backspace"&&t.target.value===""){this.popFacet();return}if(t.key==="Tab"||t.key==="ArrowDown"||t.key==="ArrowUp"){t.preventDefault();let e=this.renderRoot.querySelector(".vs-search__dropdown");if(e===null)return;let s=e.querySelectorAll(".vs-search__dropdown-item");e.classList.add("vs-search__dropdown--visible"),(t.key==="Tab"&&!t.shiftKey||t.key==="ArrowDown")&&s.item(0)?.focus(),(t.key==="Tab"&&t.shiftKey||t.key==="ArrowUp")&&s.item(s.length-1)?.focus(),e.classList.remove("vs-search__dropdown--visible");return}if(t.key==="Escape"){this._input().blur();return}}handleNavigation(t,e){if(t.key==="ArrowDown"){if(t.preventDefault(),e===this.autocomplete.length-1){this._input().focus();return}this.renderRoot.querySelectorAll(".vs-search__dropdown-item").item(e+1).focus();return}if(t.key==="ArrowUp"){if(t.preventDefault(),e===0){this._input().focus();return}this.renderRoot.querySelectorAll(".vs-search__dropdown-item").item(e-1).focus();return}if(t.key==="Tab"&&!t.shiftKey&&e===this.autocomplete.length-1){t.preventDefault(),this._input().focus();return}if(t.key==="Escape"){this._input().focus();return}}handleInput(t){this.completeTerm(t.target.value)}completeTerm(t){let e=(s,...i)=>{s(...i).then(()=>{this.updateAutocomplete()}).catch(o=>{this._log(o)})};this.storeQuery(this.collectQuery()).then(()=>{this._mode()?e(this.fetchValues.bind(this),this.selectedFacets.at(-1).facet.value,"",t):e(this.fetchFacets.bind(this),"",t)})}loadStateFromQuery(){this.selectedFacets=this.query.facets.map(t=>({facet:new L(t.facet,t.facetLabel),value:new E(t.value,t.valueLabel)}))}updateAutocomplete(){this._mode()?this.autocomplete=this.values.map(t=>({value:t.value,label:t.label,obj:t})):this.autocomplete=this.facets.map(t=>({value:t.value,label:t.label,obj:t}))}pushFacet(t){this.selectedFacets.push({facet:t,value:null}),this.requestUpdate("selectedFacets"),t.inputType&&(this._input().type=t.inputType),this._input().value="",this.autocomplete=[],this.renderRoot.activeElement!==this._input()?this._input().focus():this.completeTerm("")}pushValue(t){this.selectedFacets.at(-1).value=t,this.requestUpdate("selectedFacets"),this._input().type="text",this._input().value="",this.autocomplete=[],this.renderRoot.activeElement!==this._input()?this._input().focus():this.completeTerm("")}popFacet(){let t=this.selectedFacets.pop();return this.requestUpdate("selectedFacets"),this._input().type="text",this.completeTerm(""),t}popValue(){if(this.selectedFacets.length===0)return;let t=this.selectedFacets.at(-1).value;return this.selectedFacets.at(-1).value=null,this.requestUpdate("selectedFacets"),this._input().type="text",this.completeTerm(""),t}submit(){this._mode()&&this.popFacet(),this.storeQuery(this.collectQuery()).then(()=>{window.location.reload()})}clear(){this._input().value="",this._sort()&&(this._sort().value=""),this.selectedFacets=[],this.autocomplete=[],this.storeQuery(this.collectQuery()).then(()=>{window.location.reload()})}deleteFacet(t){this.selectedFacets.splice(t,1),this.requestUpdate("selectedFacets"),this.completeTerm(this._input().value)}async fetchFacets(t,e){let s=new URL(this.facetsAction,window.location.origin);return s.searchParams.set("search",this.search),t===void 0&&(t=""),e===void 0&&(e=""),s.searchParams.set("query",t),s.searchParams.set("term",e),fetch(s,{method:"GET",headers:{Accept:"application/json"}}).then(o=>{if(!o.ok)throw new Error(o.statusText);return o.json()}).then(o=>{let n=o.map(c=>L.fromObject(c));n.every(L.validate)||this._log("invalid facets"),this.facets=n})}async fetchValues(t,e,s){let i=new URL(this.valueAction,window.location.origin);return i.searchParams.set("search",this.search),t===void 0&&(t=""),e===void 0&&(e=""),s===void 0&&(s=""),i.searchParams.set("facet",t),i.searchParams.set("query",e),i.searchParams.set("term",s),fetch(i,{method:"GET",headers:{Accept:"application/json"}}).then(n=>{if(!n.ok)throw new Error(n.statusText);return n.json()}).then(n=>{let c=n.map(a=>E.fromObject(a));c.every(E.validate)||this._log("invalid values"),this.values=c})}async storeQuery(t){let e=new URL(this.queryAction,window.location.origin);t===void 0&&(t={});let s={method:"PUT",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({query:t})};return fetch(e,s).then(i=>{if(!i.ok)throw new Error(i.statusText);return i.json()})}collectQuery(){let t=this.selectedFacets.reduce((e,s)=>(s.value==null||e.push({facetLabel:s.facet.label,facet:s.facet.value,valueLabel:s.value.label,value:s.value.value}),e),[]);return{identifier:this.search,sorting:this._sort()?this._sort().value:"",facets:t}}encodeQuery(){return btoa(encodeURIComponent(JSON.stringify(this.collectQuery().facets)))}};customElements.define("visual-search",Y);var tt=class extends f{static styles=g` :host { display: inline-flex; gap: 4px;