Skip to content

Commit eb1fb5b

Browse files
committed
fix focus bug when selecting with keyboard, and add integration test for it
1 parent 40ed846 commit eb1fb5b

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

components/dash-core-components/src/fragments/Dropdown.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ const Dropdown = (props: DropdownProps) => {
264264
searchInputRef.current.focus();
265265
}
266266
});
267-
}, [isOpen, multi, displayOptions, sanitizedValues]);
267+
}, [isOpen, multi, displayOptions]);
268268

269269
// Handle keyboard navigation in popover
270270
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {

components/dash-core-components/tests/integration/dropdown/test_a11y.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pytest
2-
from dash import Dash
2+
from dash import Dash, Input, Output
33
from dash.dcc import Dropdown
44
from dash.html import Div, Label, P
55
from selenium.common.exceptions import TimeoutException
@@ -202,6 +202,57 @@ def test_a11y005_selection_visibility_multi(dash_duo):
202202
assert dash_duo.get_logs() == []
203203

204204

205+
def test_a11y006_multi_select_keyboard_focus_retention(dash_duo):
206+
def send_keys(key):
207+
actions = ActionChains(dash_duo.driver)
208+
actions.send_keys(key)
209+
actions.perform()
210+
211+
app = Dash(__name__)
212+
app.layout = Div(
213+
[
214+
Dropdown(
215+
id="dropdown",
216+
options=[f"Option {i}" for i in range(0, 10)],
217+
value=[],
218+
multi=True,
219+
searchable=True,
220+
),
221+
Div(id="output"),
222+
]
223+
)
224+
225+
@app.callback(
226+
Output("output", "children"),
227+
Input("dropdown", "value"),
228+
)
229+
def update_output(value):
230+
return f"Selected: {value}"
231+
232+
dash_duo.start_server(app)
233+
234+
dropdown = dash_duo.find_element("#dropdown")
235+
dropdown.click()
236+
dash_duo.wait_for_element(".dash-dropdown-options")
237+
238+
# Select 3 items by alternating ArrowDown and Spacebar
239+
send_keys(Keys.ARROW_DOWN) # Move to first option
240+
send_keys(Keys.SPACE) # Select Option 0
241+
dash_duo.wait_for_text_to_equal("#output", "Selected: ['Option 0']")
242+
243+
send_keys(Keys.ARROW_DOWN) # Move to second option
244+
send_keys(Keys.SPACE) # Select Option 1
245+
dash_duo.wait_for_text_to_equal("#output", "Selected: ['Option 0', 'Option 1']")
246+
247+
send_keys(Keys.ARROW_DOWN) # Move to third option
248+
send_keys(Keys.SPACE) # Select Option 2
249+
dash_duo.wait_for_text_to_equal(
250+
"#output", "Selected: ['Option 0', 'Option 1', 'Option 2']"
251+
)
252+
253+
assert dash_duo.get_logs() == []
254+
255+
205256
def elements_are_visible(dash_duo, elements):
206257
# Check if the given elements are within the visible viewport of the dropdown
207258
elements = elements if isinstance(elements, list) else [elements]

0 commit comments

Comments
 (0)