@@ -217,20 +217,19 @@ const Dropdown = (props: DropdownProps) => {
217217 let sortedOptions = filteredOptions ;
218218 if ( multi ) {
219219 // Sort filtered options: selected first, then unselected
220+ // ES2019+ guarantees stable sort, preserving order within groups
220221 sortedOptions = [ ...filteredOptions ] . sort ( ( a , b ) => {
221222 const aSelected = sanitizedValues . includes ( a . value ) ;
222223 const bSelected = sanitizedValues . includes ( b . value ) ;
223-
224224 if ( aSelected && ! bSelected ) {
225225 return - 1 ;
226226 }
227227 if ( ! aSelected && bSelected ) {
228228 return 1 ;
229229 }
230- return 0 ; // Maintain original order within each group
230+ return 0 ;
231231 } ) ;
232232 }
233-
234233 setDisplayOptions ( sortedOptions ) ;
235234 }
236235 } , [ filteredOptions , isOpen ] ) ;
@@ -280,20 +279,41 @@ const Dropdown = (props: DropdownProps) => {
280279 // Handle keyboard navigation in popover
281280 const handleKeyDown = useCallback (
282281 ( e : React . KeyboardEvent ) => {
283- // Handle TAB to select first option and close dropdown
282+ // Handle TAB to select highlighted option and close dropdown
284283 if ( e . key === 'Tab' && ! e . shiftKey ) {
285284 if ( displayOptions . length > 0 ) {
286- const firstOption = displayOptions [ 0 ] ;
287- if ( ! firstOption . disabled ) {
285+ // Check if an option is currently focused
286+ const focusedElement = document . activeElement ;
287+ let optionToSelect = displayOptions [ 0 ] ;
288+
289+ if (
290+ focusedElement instanceof HTMLInputElement &&
291+ focusedElement . classList . contains (
292+ 'dash-options-list-option-checkbox'
293+ )
294+ ) {
295+ // Find the option matching the focused element's value
296+ const focusedValue = focusedElement . value ;
297+ const focusedOption = displayOptions . find (
298+ opt => String ( opt . value ) === focusedValue
299+ ) ;
300+ if ( focusedOption ) {
301+ optionToSelect = focusedOption ;
302+ }
303+ }
304+
305+ if ( ! optionToSelect . disabled ) {
288306 if ( multi ) {
289- if ( ! sanitizedValues . includes ( firstOption . value ) ) {
307+ if (
308+ ! sanitizedValues . includes ( optionToSelect . value )
309+ ) {
290310 updateSelection ( [
291311 ...sanitizedValues ,
292- firstOption . value ,
312+ optionToSelect . value ,
293313 ] ) ;
294314 }
295315 } else {
296- updateSelection ( [ firstOption . value ] ) ;
316+ updateSelection ( [ optionToSelect . value ] ) ;
297317 }
298318 }
299319 }
0 commit comments