diff --git a/CHANGELOG.md b/CHANGELOG.md index 31efe42..6ae0af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ -* ArrowUp when there is no active option navigates to the last option +* arrowUp when there is no active option navigates to the last option +* scroll options into view when they become active ## 1.2.1 (2023-10-17) diff --git a/assets/js/live_select.js b/assets/js/live_select.js index fafe3ec..466f13a 100644 --- a/assets/js/live_select.js +++ b/assets/js/live_select.js @@ -108,7 +108,7 @@ export default { if (this.el.id === id) { const option = this.el.querySelector(`div[data-idx="${idx}"]`) if (option) { - option.scrollIntoView(false) + option.scrollIntoView({block: "nearest"}) } } }) diff --git a/priv/static/live_select.min.js b/priv/static/live_select.min.js index 1334626..986f2cd 100644 --- a/priv/static/live_select.min.js +++ b/priv/static/live_select.min.js @@ -1 +1 @@ -function h(e,t){let i;return(...s)=>{clearTimeout(i),i=setTimeout(()=>{e.apply(this,s)},t)}}export default{LiveSelect:{textInput(){return this.el.querySelector("input[type=text]")},debounceMsec(){return parseInt(this.el.dataset.debounce)},updateMinLen(){return parseInt(this.el.dataset.updateMinLen)},maybeStyleClearButton(){const e=this.el.querySelector("button[phx-click=clear]");e&&(this.textInput().parentElement.style.position="relative",e.style.position="absolute",e.style.top="0px",e.style.bottom="0px",e.style.right="5px",e.style.display="block")},pushEventToParent(e,t){const i=this.el.dataset.phxTarget;i?this.pushEventTo(i,e,t):this.pushEvent(e,t)},attachDomEventHandlers(){this.textInput().onkeydown=t=>{t.code==="Enter"&&t.preventDefault(),this.pushEventTo(this.el,"keydown",{key:t.code})},this.changeEvents=h((t,i,s)=>{this.pushEventTo(this.el,"change",{text:s}),this.pushEventToParent("live_select_change",{id:this.el.id,field:i,text:s})},this.debounceMsec()),this.textInput().oninput=t=>{const i=t.target.value.trim(),s=this.el.dataset.field;i.length>=this.updateMinLen()?this.changeEvents(this.el.id,s,i):this.pushEventTo(this.el,"options_clear",{})};const e=this.el.querySelector("ul");e&&(e.onmousedown=t=>{const i=t.target.closest("div[data-idx]");i&&(this.pushEventTo(this.el,"option_click",{idx:i.dataset.idx}),t.preventDefault())}),this.el.querySelectorAll("button[data-idx]").forEach(t=>{t.onclick=i=>{this.pushEventTo(this.el,"option_remove",{idx:t.dataset.idx})}})},setInputValue(e){this.textInput().value=e},inputEvent(e,t){const i=t==="single"?"input.single-mode":e.length===0?"input[data-live-select-empty]":"input[type=hidden]";this.el.querySelector(i).dispatchEvent(new Event("input",{bubbles:!0}))},mounted(){this.maybeStyleClearButton(),this.handleEvent("parent_event",({id:e,event:t,payload:i})=>{this.el.id===e&&this.pushEventToParent(t,i)}),this.handleEvent("select",({id:e,selection:t,mode:i,input_event:s,parent_event:n})=>{if(this.el.id===e){if(i==="single"){const l=t.length>0?t[0].label:null;this.setInputValue(l)}else this.setInputValue(null);s&&this.inputEvent(t,i),n&&this.pushEventToParent(n,{id:e})}}),this.handleEvent("active",({id:e,idx:t})=>{if(this.el.id===e){const i=this.el.querySelector(`div[data-idx="${t}"]`);i&&i.scrollIntoView(!1)}}),this.attachDomEventHandlers()},updated(){this.maybeStyleClearButton(),this.attachDomEventHandlers()}}}; +function h(e,t){let i;return(...s)=>{clearTimeout(i),i=setTimeout(()=>{e.apply(this,s)},t)}}export default{LiveSelect:{textInput(){return this.el.querySelector("input[type=text]")},debounceMsec(){return parseInt(this.el.dataset.debounce)},updateMinLen(){return parseInt(this.el.dataset.updateMinLen)},maybeStyleClearButton(){const e=this.el.querySelector("button[phx-click=clear]");e&&(this.textInput().parentElement.style.position="relative",e.style.position="absolute",e.style.top="0px",e.style.bottom="0px",e.style.right="5px",e.style.display="block")},pushEventToParent(e,t){const i=this.el.dataset.phxTarget;i?this.pushEventTo(i,e,t):this.pushEvent(e,t)},attachDomEventHandlers(){this.textInput().onkeydown=t=>{t.code==="Enter"&&t.preventDefault(),this.pushEventTo(this.el,"keydown",{key:t.code})},this.changeEvents=h((t,i,s)=>{this.pushEventTo(this.el,"change",{text:s}),this.pushEventToParent("live_select_change",{id:this.el.id,field:i,text:s})},this.debounceMsec()),this.textInput().oninput=t=>{const i=t.target.value.trim(),s=this.el.dataset.field;i.length>=this.updateMinLen()?this.changeEvents(this.el.id,s,i):this.pushEventTo(this.el,"options_clear",{})};const e=this.el.querySelector("ul");e&&(e.onmousedown=t=>{const i=t.target.closest("div[data-idx]");i&&(this.pushEventTo(this.el,"option_click",{idx:i.dataset.idx}),t.preventDefault())}),this.el.querySelectorAll("button[data-idx]").forEach(t=>{t.onclick=i=>{this.pushEventTo(this.el,"option_remove",{idx:t.dataset.idx})}})},setInputValue(e){this.textInput().value=e},inputEvent(e,t){const i=t==="single"?"input.single-mode":e.length===0?"input[data-live-select-empty]":"input[type=hidden]";this.el.querySelector(i).dispatchEvent(new Event("input",{bubbles:!0}))},mounted(){this.maybeStyleClearButton(),this.handleEvent("parent_event",({id:e,event:t,payload:i})=>{this.el.id===e&&this.pushEventToParent(t,i)}),this.handleEvent("select",({id:e,selection:t,mode:i,input_event:s,parent_event:n})=>{if(this.el.id===e){if(i==="single"){const l=t.length>0?t[0].label:null;this.setInputValue(l)}else this.setInputValue(null);s&&this.inputEvent(t,i),n&&this.pushEventToParent(n,{id:e})}}),this.handleEvent("active",({id:e,idx:t})=>{if(this.el.id===e){const i=this.el.querySelector(`div[data-idx="${t}"]`);i&&i.scrollIntoView({block:"nearest"})}}),this.attachDomEventHandlers()},updated(){this.maybeStyleClearButton(),this.attachDomEventHandlers()}}};