diff --git a/app/javascript/mastodon/features/compose/components/search.tsx b/app/javascript/mastodon/features/compose/components/search.tsx index 285a352268..c2855e8cb5 100644 --- a/app/javascript/mastodon/features/compose/components/search.tsx +++ b/app/javascript/mastodon/features/compose/components/search.tsx @@ -1,4 +1,11 @@ -import { useCallback, useState, useRef, useEffect, useMemo } from 'react'; +import { + useCallback, + useState, + useRef, + useEffect, + useMemo, + useId, +} from 'react'; import { defineMessages, @@ -432,12 +439,17 @@ export const Search: React.FC<{ switch (e.key) { case 'Escape': e.preventDefault(); - unfocus(); + searchInputRef.current?.focus(); + setExpanded(false); break; case 'ArrowDown': e.preventDefault(); + if (!expanded) { + setExpanded(true); + } + if (navigableOptions.length > 0) { setSelectedOption( Math.min(selectedOption + 1, navigableOptions.length - 1), @@ -476,10 +488,10 @@ export const Search: React.FC<{ break; } }, - [unfocus, navigableOptions, selectedOption, submit, value], + [expanded, navigableOptions, selectedOption, submit, value], ); - const handleFocus = useCallback(() => { + const handleInputFocus = useCallback(() => { setExpanded(true); setSelectedOption(-1); @@ -495,10 +507,16 @@ export const Search: React.FC<{ } }, [setExpanded, setSelectedOption, singleColumn]); - const handleBlur = useCallback(() => { + const handleInputBlur = useCallback(() => { setSelectedOption(-1); }, [setSelectedOption]); + const getOptionFocusHandler = useCallback((index: number) => { + return () => { + setSelectedOption(index); + }; + }, []); + const formRef = useRef(null); useEffect(() => { @@ -526,6 +544,8 @@ export const Search: React.FC<{ return () => null; }, [expanded]); + const searchOptionsHeading = useId(); + return (
-
+ {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */} +
{!hasValue && ( <>

@@ -565,6 +592,7 @@ export const Search: React.FC<{ tabIndex={0} role='button' onMouseDown={action} + onFocus={getOptionFocusHandler(i)} className={classNames( 'search__popout__menu__item search__popout__menu__item--flex', { selected: selectedOption === i }, @@ -606,6 +634,7 @@ export const Search: React.FC<{ - ))} + {searchOptions.map(({ key, label, action }, i) => { + const currentIndex = (quickActions.length || recent.length) + i; + return ( + + ); + })}

) : (