From b73fc758d16fbe5e721c0ebbc70fcaf1c4a40c9b Mon Sep 17 00:00:00 2001 From: Jose Farias <31393016+josefarias@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:54:21 -0600 Subject: [PATCH] Reroute listbox streams to dialog if necessary (#78) Closes https://github.com/josefarias/hotwire_combobox/issues/76 --- .../hw_combobox/models/combobox/dialog.js | 10 ++++++++++ .../hw_combobox/models/combobox/filtering.js | 2 +- .../hw_combobox/models/combobox/toggle.js | 2 +- app/presenters/hotwire_combobox/component.rb | 3 ++- test/dummy/app/views/layouts/application.html.erb | 6 ++++++ test/system/hotwire_combobox_test.rb | 14 +++++++------- 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/hw_combobox/models/combobox/dialog.js b/app/assets/javascripts/hw_combobox/models/combobox/dialog.js index 958cb63..09f7b73 100644 --- a/app/assets/javascripts/hw_combobox/models/combobox/dialog.js +++ b/app/assets/javascripts/hw_combobox/models/combobox/dialog.js @@ -1,6 +1,12 @@ import Combobox from "hw_combobox/models/combobox/base" Combobox.Dialog = Base => class extends Base { + rerouteListboxStreamToDialog({ detail: { newStream } }) { + if (newStream.target == this.listboxTarget.id && this._dialogIsOpen) { + newStream.setAttribute("target", this.dialogListboxTarget.id) + } + } + _connectDialog() { if (window.visualViewport) { window.visualViewport.addEventListener("resize", this._resizeDialog) @@ -50,4 +56,8 @@ Combobox.Dialog = Base => class extends Base { get _smallViewport() { return window.matchMedia(`(max-width: ${this.smallViewportMaxWidthValue})`).matches } + + get _dialogIsOpen() { + return this.dialogTarget.open + } } diff --git a/app/assets/javascripts/hw_combobox/models/combobox/filtering.js b/app/assets/javascripts/hw_combobox/models/combobox/filtering.js index 0294aa3..99e5b5c 100644 --- a/app/assets/javascripts/hw_combobox/models/combobox/filtering.js +++ b/app/assets/javascripts/hw_combobox/models/combobox/filtering.js @@ -41,7 +41,7 @@ Combobox.Filtering = Base => class extends Base { this._selectNew() } else if (isDeleteEvent(event)) { this._deselect() - } else { + } else if (this._isOpen) { this._select(this._visibleOptionElements[0]) } } diff --git a/app/assets/javascripts/hw_combobox/models/combobox/toggle.js b/app/assets/javascripts/hw_combobox/models/combobox/toggle.js index eedc66d..3e057fd 100644 --- a/app/assets/javascripts/hw_combobox/models/combobox/toggle.js +++ b/app/assets/javascripts/hw_combobox/models/combobox/toggle.js @@ -72,7 +72,7 @@ Combobox.Toggle = Base => class extends Base { _collapse() { this._actingCombobox.setAttribute("aria-expanded", false) // needs to happen before resetting acting combobox - if (this.dialogTarget.open) { + if (this._dialogIsOpen) { this._closeInDialog() } else { this._closeInline() diff --git a/app/presenters/hotwire_combobox/component.rb b/app/presenters/hotwire_combobox/component.rb index 84ede72..0f00b4f 100644 --- a/app/presenters/hotwire_combobox/component.rb +++ b/app/presenters/hotwire_combobox/component.rb @@ -232,7 +232,8 @@ def input_data input->hw-combobox#filter keydown->hw-combobox#navigate click@window->hw-combobox#closeOnClickOutside - focusin@window->hw-combobox#closeOnFocusOutside".squish, + focusin@window->hw-combobox#closeOnFocusOutside + turbo:before-stream-render@document->hw-combobox#rerouteListboxStreamToDialog".squish, hw_combobox_target: "combobox", async_id: canonical_id end diff --git a/test/dummy/app/views/layouts/application.html.erb b/test/dummy/app/views/layouts/application.html.erb index 7d00c59..67959f4 100644 --- a/test/dummy/app/views/layouts/application.html.erb +++ b/test/dummy/app/views/layouts/application.html.erb @@ -26,6 +26,12 @@ .container aside.empty { display: none; } + + @media (max-width: 600px) { + .container aside { + display: none; + } + } diff --git a/test/system/hotwire_combobox_test.rb b/test/system/hotwire_combobox_test.rb index d572721..6ba870d 100644 --- a/test/system/hotwire_combobox_test.rb +++ b/test/system/hotwire_combobox_test.rb @@ -458,21 +458,21 @@ class HotwireComboboxTest < ApplicationSystemTestCase test "dialog" do on_small_screen do - visit html_options_path + visit async_html_path assert_no_selector "dialog[open]" - open_combobox "#state-field" + open_combobox "#movie-field" assert_selector "dialog[open]" within "dialog" do - type_in_combobox "#state-field-hw-dialog-combobox", "Flor" - assert_combobox_display "#state-field-hw-dialog-combobox", "Florida" - assert_selected_option_with text: "Florida" + type_in_combobox "#movie-field-hw-dialog-combobox", "whi" + assert_combobox_display "#movie-field-hw-dialog-combobox", "Whiplash" + assert_selected_option_with text: "Whiplash" end - assert_combobox_value "#state-field", "FL" + assert_combobox_value "#movie-field", movies(:whiplash).id click_away - assert_combobox_display_and_value "#state-field", "Florida", "FL" + assert_combobox_display_and_value "#movie-field", "Whiplash", movies(:whiplash).id assert_no_selector "dialog[open]" end end