summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-10-03 10:13:53 +0200
committerTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-10-03 10:13:53 +0200
commit2a5afe1ed0eda951f20670754dd445b2863df5d7 (patch)
tree961a35d8d5a7f2469a7915f26d80ae2180dbdbe2
parent02408a4412519eb61d2aa8f147feb0a0112de5e7 (diff)
parent43abc1a78718d25008ac6e5ae47dc196cb3cfddb (diff)
downloadmullvadvpn-2a5afe1ed0eda951f20670754dd445b2863df5d7.tar.xz
mullvadvpn-2a5afe1ed0eda951f20670754dd445b2863df5d7.zip
Merge branch 'fix-focus-not-staying-on-correct-element-after-navigating-des-2560'
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx19
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts3
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReferenceAfterPaint.ts (renamed from desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReference.ts)2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReferenceBeforePaint.ts12
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/hooks/useInitialFocus.ts4
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts5
6 files changed, 24 insertions, 21 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx
index de0c36902e..dcefbdff7e 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx
@@ -1,10 +1,11 @@
-import { useCallback, useEffect } from 'react';
+import { useCallback } from 'react';
import styled from 'styled-components';
import { messages } from '../../shared/gettext';
+import { useFocusReferenceBeforePaint } from '../hooks';
import { Icon, IconButton } from '../lib/components';
import { colors } from '../lib/foundations';
-import { useEffectEvent, useStyledRef } from '../lib/utility-hooks';
+import { useStyledRef } from '../lib/utility-hooks';
import { normalText } from './common-styles';
export const StyledSearchContainer = styled.div({
@@ -76,6 +77,7 @@ export default function SearchBar(props: ISearchBarProps) {
const { disabled, onSearch } = props;
const inputRef = useStyledRef<HTMLInputElement>();
+ useFocusReferenceBeforePaint(inputRef, !props.disableAutoFocus);
const onInput = useCallback(
(event: React.FormEvent) => {
@@ -90,19 +92,6 @@ export default function SearchBar(props: ISearchBarProps) {
inputRef.current?.blur();
}, [inputRef, onSearch]);
- const focusInput = useEffectEvent(() => {
- if (!props.disableAutoFocus) {
- inputRef.current?.focus({ preventScroll: true });
- }
- });
-
- // These lint rules are disabled for now because the react plugin for eslint does
- // not understand that useEffectEvent should not be added to the dependency array.
- // Enable these rules again when eslint can lint useEffectEvent properly.
- // eslint-disable-next-line react-compiler/react-compiler
- // eslint-disable-next-line react-hooks/exhaustive-deps
- useEffect(() => focusInput(), []);
-
return (
<StyledSearchContainer className={props.className}>
<StyledSearchInput
diff --git a/desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts
index 2a4f1dfdaf..ad6223e570 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts
@@ -10,4 +10,5 @@ export * from './useMeasure';
export * from './useScrollToReference';
export * from './useScrollToListItem';
export * from './useInitialFocus';
-export * from './useFocusReference';
+export * from './useFocusReferenceAfterPaint';
+export * from './useFocusReferenceBeforePaint';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReference.ts b/desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReferenceAfterPaint.ts
index d49264630f..8282d0805a 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReference.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReferenceAfterPaint.ts
@@ -1,6 +1,6 @@
import React from 'react';
-export const useFocusReference = <T extends HTMLElement>(
+export const useFocusReferenceAfterPaint = <T extends HTMLElement>(
ref?: React.RefObject<T | null>,
focus?: boolean,
) => {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReferenceBeforePaint.ts b/desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReferenceBeforePaint.ts
new file mode 100644
index 0000000000..09411073f8
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/hooks/useFocusReferenceBeforePaint.ts
@@ -0,0 +1,12 @@
+import React from 'react';
+
+export const useFocusReferenceBeforePaint = <T extends HTMLElement>(
+ ref?: React.RefObject<T | null>,
+ focus?: boolean,
+) => {
+ React.useLayoutEffect(() => {
+ if (focus) {
+ ref?.current?.focus({ preventScroll: true });
+ }
+ }, [ref, focus]);
+};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/hooks/useInitialFocus.ts b/desktop/packages/mullvad-vpn/src/renderer/hooks/useInitialFocus.ts
index 72e8355489..bd1d3a45eb 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/hooks/useInitialFocus.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/hooks/useInitialFocus.ts
@@ -1,6 +1,6 @@
import React from 'react';
-import { useFocusReference } from './useFocusReference';
+import { useFocusReferenceAfterPaint } from './useFocusReferenceAfterPaint';
import { useIsDefaultActiveElementAfterMount } from './useIsDefaultActiveElementAfterMount';
export const useInitialFocus = <T extends HTMLElement = HTMLDivElement>(): {
@@ -11,7 +11,7 @@ export const useInitialFocus = <T extends HTMLElement = HTMLDivElement>(): {
const isDefaultFocus = useIsDefaultActiveElementAfterMount();
const shouldFocus = isDefaultFocus === true;
- useFocusReference(ref, shouldFocus);
+ useFocusReferenceAfterPaint(ref, shouldFocus);
if (!isDefaultFocus)
return {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts b/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts
index 34b42cdfc5..6678f75720 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts
@@ -3,7 +3,7 @@ import React from 'react';
import { ScrollToAnchorId } from '../../shared/ipc-types';
import { ListItemAnimation } from '../lib/components/list-item';
import { useHistory } from '../lib/history';
-import { useFocusReference } from './useFocusReference';
+import { useFocusReferenceBeforePaint } from './useFocusReferenceBeforePaint';
import { useScrollToReference } from './useScrollToReference';
export const useScrollToListItem = <T extends HTMLElement = HTMLDivElement>(
@@ -36,7 +36,7 @@ export const useScrollToListItem = <T extends HTMLElement = HTMLDivElement>(
}, [history, location, scrollToAnchorOption?.id, state]);
useScrollToReference(ref, shouldScroll, handleScrolled);
- useFocusReference(ref, shouldScroll);
+ useFocusReferenceBeforePaint(ref, shouldScroll);
if (scrollToAnchorOption === undefined) {
return {
@@ -44,6 +44,7 @@ export const useScrollToListItem = <T extends HTMLElement = HTMLDivElement>(
animation: undefined,
};
}
+
return {
ref,
animation: shouldScroll ? 'flash' : 'dim',