Skip to content

Commit c7c51b1

Browse files
ukutahtclaude
andcommitted
Fix focus handling when clearing input in creatable combobox
- Reorder create option visibility logic to run after regular options filtering - Add test for focus handling when clearing input after filtering to create option only - Fix issue where Wallaby fill_in with empty string doesn't trigger input event - Ensure first visible option gets focus when clearing filtered input 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 3ab8269 commit c7c51b1

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

assets/js/hooks/combobox.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,9 @@ export default {
9898
onInput(e) {
9999
const searchValue = e.target.value
100100

101-
// Update create option content and visibility
101+
// Update create option content first
102102
if (this.hasCreateOption) {
103103
this.updateCreateOption(searchValue)
104-
this.updateCreateOptionVisibility(searchValue)
105104
}
106105

107106
if (this.mode === 'async') {
@@ -125,6 +124,11 @@ export default {
125124
}
126125
}
127126

127+
// Handle create option visibility after regular options are processed
128+
if (this.hasCreateOption) {
129+
this.updateCreateOptionVisibility(searchValue)
130+
}
131+
128132
if (previouslyFocusedOptionIsHidden) {
129133
this.focusFirstOption()
130134
}

lib/prima_web/live/demo_live/creatable_combobox_demo.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
transition_leave={{"ease-in duration-100", "opacity-100", "opacity-0"}}
1111
class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
1212
>
13+
1314
<%= for option <- ["Apple", "Pear", "Mango", "Pineapple"] do %>
1415
<.combobox_option
1516
value={option}
@@ -18,7 +19,6 @@
1819
{option}
1920
</.combobox_option>
2021
<% end %>
21-
2222
<.creatable_option class="group relative cursor-default select-none py-2 pl-3 pr-9 text-gray-500 data-focus:bg-indigo-600 data-focus:text-white italic border-t border-gray-200" />
2323
</.combobox_options>
2424
</.combobox>

test/wallaby/prima_web/creatable_combobox_test.exs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,64 @@ defmodule PrimaWeb.CreatableComboboxTest do
210210
Query.css("#demo-creatable-combobox [role=option][data-value='Apple'][data-focus=true]")
211211
)
212212
end
213+
214+
feature "focus handling when clearing input after filtering to create option only", %{
215+
session: session
216+
} do
217+
session
218+
|> visit("/fixtures/creatable-combobox")
219+
|> click(@search_input)
220+
|> fill_in(@search_input, with: "z")
221+
# Only create option should be visible
222+
|> assert_has(@create_option |> Query.visible(true))
223+
|> assert_has(
224+
Query.css("#demo-creatable-combobox [data-prima-ref=create-option][data-focus=true]")
225+
)
226+
# All regular options should be hidden
227+
|> assert_missing(
228+
Query.css("#demo-creatable-combobox [role=option][data-value='Apple']")
229+
|> Query.visible(true)
230+
)
231+
|> assert_missing(
232+
Query.css("#demo-creatable-combobox [role=option][data-value='Pear']")
233+
|> Query.visible(true)
234+
)
235+
|> assert_missing(
236+
Query.css("#demo-creatable-combobox [role=option][data-value='Mango']")
237+
|> Query.visible(true)
238+
)
239+
|> assert_missing(
240+
Query.css("#demo-creatable-combobox [role=option][data-value='Pineapple']")
241+
|> Query.visible(true)
242+
)
243+
# Clear the input
244+
|> fill_in(@search_input, with: "")
245+
# Manually trigger input event since Wallaby doesn't trigger it for empty values
246+
|> execute_script(
247+
"document.querySelector('#demo-creatable-combobox input[data-prima-ref=search_input]').dispatchEvent(new Event('input', {bubbles: true}))"
248+
)
249+
# Create option should be hidden (empty input)
250+
|> assert_missing(@create_option |> Query.visible(true))
251+
# All regular options should be visible again
252+
|> assert_has(
253+
Query.css("#demo-creatable-combobox [role=option][data-value='Apple']")
254+
|> Query.visible(true)
255+
)
256+
|> assert_has(
257+
Query.css("#demo-creatable-combobox [role=option][data-value='Pear']")
258+
|> Query.visible(true)
259+
)
260+
|> assert_has(
261+
Query.css("#demo-creatable-combobox [role=option][data-value='Mango']")
262+
|> Query.visible(true)
263+
)
264+
|> assert_has(
265+
Query.css("#demo-creatable-combobox [role=option][data-value='Pineapple']")
266+
|> Query.visible(true)
267+
)
268+
# First visible option (Apple) should be focused
269+
|> assert_has(
270+
Query.css("#demo-creatable-combobox [role=option][data-value='Apple'][data-focus=true]")
271+
)
272+
end
213273
end

0 commit comments

Comments
 (0)