diff --git a/assets/js/live_select.js b/assets/js/live_select.js index d105f35..9b4a6a1 100644 --- a/assets/js/live_select.js +++ b/assets/js/live_select.js @@ -112,6 +112,14 @@ export default { } }) this.attachDomEventHandlers() + this.textInput().addEventListener('blur', () => { + clearTimeout(this._blurTimeout) + this._blurTimeout = setTimeout(() => { + if (document.activeElement !== this.textInput()) { + this.pushEventTo(this.el, 'self_blur', {}) + } + }, 100) + }) }, updated() { this.maybeStyleClearButtons() diff --git a/lib/live_select/component.ex b/lib/live_select/component.ex index c08e452..f9e928a 100644 --- a/lib/live_select/component.ex +++ b/lib/live_select/component.ex @@ -202,7 +202,10 @@ defmodule LiveSelect.Component do def handle_event("blur", _params, socket) do socket = socket - |> assign(:hide_dropdown, true) + |> assign( + :hide_dropdown, + if(quick_tags_mode?(socket), do: socket.assigns.hide_dropdown, else: true) + ) |> client_select(%{ parent_event: socket.assigns[:"phx-blur"], current_text: @@ -216,6 +219,11 @@ defmodule LiveSelect.Component do {:noreply, socket} end + @impl true + def handle_event("self_blur", _params, socket) do + handle_event("blur", %{}, assign(socket, :hide_dropdown, true)) + end + @impl true def handle_event(event, _params, socket) when event in ~w(focus click) do socket = diff --git a/priv/static/live_select.min.js b/priv/static/live_select.min.js index a799072..64e69d8 100644 --- a/priv/static/live_select.min.js +++ b/priv/static/live_select.min.js @@ -1 +1 @@ -function o(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)},maybeStyleClearButtons(){const e=this.el.querySelector("button.ls-clear-button");e&&(this.textInput().parentElement.style.position="relative",this.textInput().parentElement.style.display="flex",this.textInput().parentElement.style.alignItems="center",e.style.minHeight="20px",e.style.minWidth="20px",e.style.position="absolute",e.style.right="5px",e.style.display="block"),this.el.querySelectorAll("button.ls-clear-tag-button").forEach(t=>{t.style.minHeight="20px",t.style.minWidth="20px"})},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=o((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.maybeStyleClearButtons(),this.handleEvent("select",({id:e,selection:t,mode:i,current_text:s,input_event:l,parent_event:n})=>{this.el.id===e&&(this.selection=t,s!=null&&this.setInputValue(s),l&&this.inputEvent(t,i),n&&this.pushEventToParent(n,{id:e}))}),this.handleEvent("scroll_to_option",({id:e,idx:t})=>{if(this.el.id===e){const i=this.el.querySelector(`div[data-idx="${t}"]`);i&&i.scrollIntoView({block:"nearest",behavior:"instant",container:"nearest"})}}),this.attachDomEventHandlers()},updated(){this.maybeStyleClearButtons(),this.attachDomEventHandlers()},reconnected(){this.selection&&this.selection.length>0&&this.pushEventTo(this.el,"selection_recovery",this.selection)}}}; +function o(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)},maybeStyleClearButtons(){const e=this.el.querySelector("button.ls-clear-button");e&&(this.textInput().parentElement.style.position="relative",this.textInput().parentElement.style.display="flex",this.textInput().parentElement.style.alignItems="center",e.style.minHeight="20px",e.style.minWidth="20px",e.style.position="absolute",e.style.right="5px",e.style.display="block"),this.el.querySelectorAll("button.ls-clear-tag-button").forEach(t=>{t.style.minHeight="20px",t.style.minWidth="20px"})},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=o((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.maybeStyleClearButtons(),this.handleEvent("select",({id:e,selection:t,mode:i,current_text:s,input_event:l,parent_event:n})=>{this.el.id===e&&(this.selection=t,s!=null&&this.setInputValue(s),l&&this.inputEvent(t,i),n&&this.pushEventToParent(n,{id:e}))}),this.handleEvent("scroll_to_option",({id:e,idx:t})=>{if(this.el.id===e){const i=this.el.querySelector(`div[data-idx="${t}"]`);i&&i.scrollIntoView({block:"nearest",behavior:"instant",container:"nearest"})}}),this.attachDomEventHandlers(),this.textInput().addEventListener("blur",()=>{clearTimeout(this._blurTimeout),this._blurTimeout=setTimeout(()=>{document.activeElement!==this.textInput()&&this.pushEventTo(this.el,"self_blur",{})},100)})},updated(){this.maybeStyleClearButtons(),this.attachDomEventHandlers()},reconnected(){this.selection&&this.selection.length>0&&this.pushEventTo(this.el,"selection_recovery",this.selection)}}};