Fix search being auto-focused randomly (#40271)

This commit is contained in:
diondiondion
2026-08-25 13:25:29 +00:00
committed by GitHub
parent d9a5fe4ea0
commit 9e7f3690aa
4 changed files with 28 additions and 11 deletions

View File

@@ -4,6 +4,7 @@ import classNames from 'classnames';
import type { PolymorphicProps } from '@/types/polymorphic';
import type { NamedFocusTarget } from '../navigation_focus_target';
import { NavigationFocusTarget } from '../navigation_focus_target';
import classes from './redesign.module.scss';
@@ -48,7 +49,7 @@ type HeadingLevels = 1 | 2 | 3 | 4 | 5 | 6;
type ModalTitleProps = { children: React.ReactNode; level?: HeadingLevels } & (
| { noFocus: true }
| { noFocus?: false; focusTargetName?: string }
| { noFocus?: false; focusTargetName?: NamedFocusTarget }
);
export const ModalTitle: React.FC<

View File

@@ -14,11 +14,12 @@ import type { MastodonLocation } from '../router';
export const FOCUS_TARGET = {
POST: 'detailed-status',
SEARCH: 'search',
} as const;
export type FocusTarget =
| boolean
| (typeof FOCUS_TARGET)[keyof typeof FOCUS_TARGET];
export type NamedFocusTarget = (typeof FOCUS_TARGET)[keyof typeof FOCUS_TARGET];
export type FocusTarget = boolean | NamedFocusTarget;
const FocusTargetContext = createContext<React.RefObject<FocusTarget> | null>(
null,
@@ -98,7 +99,7 @@ export const FocusTargetProvider: React.FC<{
);
};
export function useFocusOnNavigation(targetName?: string) {
export function useFocusOnNavigation(targetName?: NamedFocusTarget) {
const focusTargetRef = useContext(FocusTargetContext);
return useCallback(
@@ -110,7 +111,11 @@ export function useFocusOnNavigation(targetName?: string) {
return;
}
if (focusTarget === true || focusTarget === targetName) {
const shouldSetFocus = targetName
? focusTarget === targetName
: focusTarget === true;
if (shouldSetFocus) {
setTimeout(() => {
element.focus({ preventScroll: true });
}, 0);
@@ -121,7 +126,7 @@ export function useFocusOnNavigation(targetName?: string) {
}
interface FocusTargetElementProps extends React.ComponentPropsWithoutRef<'h1'> {
focusTargetName?: string;
focusTargetName?: NamedFocusTarget;
}
export const NavigationFocusTarget = polymorphicForwardRef<

View File

@@ -19,9 +19,13 @@ import { useHistory } from 'react-router-dom';
import { isFulfilled } from '@reduxjs/toolkit';
import { useFocusOnNavigation } from '@/mastodon/components/navigation_focus_target';
import {
FOCUS_TARGET,
useFocusOnNavigation,
} from '@/mastodon/components/navigation_focus_target';
import { getCollectionPath } from '@/mastodon/features/collections/utils';
import { useMergedRefs } from '@/mastodon/hooks/useMergedRefs';
import { isRedesignEnabled } from '@/mastodon/utils/environment';
import CancelIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
@@ -107,7 +111,7 @@ export const Search: React.FC<{
const [expanded, setExpanded] = useState(false);
const [selectedOption, setSelectedOption] = useState(-1);
const [quickActions, setQuickActions] = useState<SearchOption[]>([]);
const focusOnNavigation = useFocusOnNavigation('search');
const focusOnNavigation = useFocusOnNavigation(FOCUS_TARGET.SEARCH);
const unfocus = useCallback(() => {
document.querySelector('.ui')?.parentElement?.focus();
@@ -561,7 +565,10 @@ export const Search: React.FC<{
className={classNames('search', { active: expanded })}
>
<input
ref={useMergedRefs(searchInputRef, focusOnNavigation)}
ref={useMergedRefs(
searchInputRef,
isRedesignEnabled() ? focusOnNavigation : null,
)}
className='search__input'
type='text'
inputMode='search'

View File

@@ -15,6 +15,7 @@ import {
import FediIcon from '@/images/icons/icon_fediverse.svg?react';
import { fetchLists } from '@/mastodon/actions/lists';
import { fetchFollowedHashtags } from '@/mastodon/actions/tags_typed';
import { FOCUS_TARGET } from '@/mastodon/components/navigation_focus_target';
import { useIdentity } from '@/mastodon/identity_context';
import { openNewComposer } from '@/mastodon/reducers/slices/composer';
import { getOrderedLists } from '@/mastodon/selectors/lists';
@@ -104,7 +105,10 @@ export const RedesignNavigationPanel: React.FC<{ siteName?: string }> = ({
<FormattedMessage id='tabs_bar.home' defaultMessage='Home' />
</NavigationLink>
<NavigationLink
to={{ pathname: '/explore', state: { focusTarget: 'search' } }}
to={{
pathname: '/explore',
state: { focusTarget: FOCUS_TARGET.SEARCH },
}}
iconComponent={MagnifyingGlassIcon}
>
<FormattedMessage