️(frontend) restore focus to input after search filter reset

Move filters out of listbox and refocus the search input (#2044)
This commit is contained in:
Cyril
2026-03-17 16:23:37 +01:00
parent 4cabfcc921
commit cef83067e6
3 changed files with 21 additions and 19 deletions
@@ -32,7 +32,7 @@ export type QuickSearchProps = {
label?: string;
placeholder?: string;
groupKey?: string;
isExpanded?: boolean;
beforeList?: ReactNode;
};
export const QuickSearch = ({
@@ -42,7 +42,7 @@ export const QuickSearch = ({
showInput = true,
label,
placeholder,
isExpanded,
beforeList,
children,
}: PropsWithChildren<QuickSearchProps>) => {
const ref = useRef<HTMLDivElement | null>(null);
@@ -74,11 +74,11 @@ export const QuickSearch = ({
onFilter={onFilter}
placeholder={placeholder}
listId={listId}
isExpanded={isExpanded}
>
{inputContent}
</QuickSearchInput>
)}
{beforeList}
<Command.List id={listId} aria-label={label} role="listbox">
<Box>{children}</Box>
</Command.List>
@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next';
import { HorizontalSeparator } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import { useFocusStore } from '@/stores';
import { Box } from '../Box';
import { Icon } from '../Icon';
@@ -14,7 +15,6 @@ type QuickSearchInputProps = {
placeholder?: string;
withSeparator?: boolean;
listId?: string;
isExpanded?: boolean;
};
export const QuickSearchInput = ({
inputValue,
@@ -23,18 +23,15 @@ export const QuickSearchInput = ({
children,
withSeparator: separator = true,
listId,
isExpanded,
}: PropsWithChildren<QuickSearchInputProps>) => {
const { t } = useTranslation();
const { spacingsTokens } = useCunninghamTheme();
const inputRef = useRef<HTMLInputElement>(null);
const addLastFocus = useFocusStore((state) => state.addLastFocus);
useEffect(() => {
inputRef.current?.setAttribute(
'aria-expanded',
String(isExpanded ?? false),
);
}, [isExpanded]);
addLastFocus(inputRef.current);
}, [addLastFocus]);
if (children) {
return (
@@ -14,7 +14,7 @@ import {
DocSearchFiltersValues,
DocSearchTarget,
} from '@/docs/doc-search';
import { useResponsiveStore } from '@/stores';
import { useFocusStore, useResponsiveStore } from '@/stores';
import EmptySearchIcon from '../assets/illustration-docs-empty.png';
@@ -36,6 +36,7 @@ const DocSearchModalGlobal = ({
}: DocSearchModalGlobalProps) => {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const restoreFocus = useFocusStore((state) => state.restoreFocus);
const router = useRouter();
const [search, setSearch] = useState('');
const [filters, setFilters] = useState<DocSearchFiltersValues>(
@@ -51,6 +52,7 @@ const DocSearchModalGlobal = ({
const handleResetFilters = () => {
setFilters({});
restoreFocus();
};
return (
@@ -89,19 +91,22 @@ const DocSearchModalGlobal = ({
placeholder={t('Type the name of a document')}
loading={loading}
onFilter={handleInputSearch}
isExpanded={search.length > 0}
beforeList={
showFilters ? (
<Box $padding={{ horizontal: '10px' }}>
<DocSearchFilters
values={filters}
onValuesChange={setFilters}
onReset={handleResetFilters}
/>
</Box>
) : undefined
}
>
<Box
$padding={{ horizontal: '10px', vertical: 'base' }}
$height={isDesktop ? '500px' : 'calc(100vh - 68px - 1rem)'}
>
{showFilters && (
<DocSearchFilters
values={filters}
onValuesChange={setFilters}
onReset={handleResetFilters}
/>
)}
{search.length === 0 && (
<Box
$direction="column"