mirror of
https://github.com/mastodon/mastodon.git
synced 2026-09-13 01:15:48 -05:00
Fix search being auto-focused randomly (#40271)
This commit is contained in:
@@ -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<
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user