summaryrefslogtreecommitdiffhomepage
path: root/desktop
diff options
context:
space:
mode:
authorOliver <oliver@mohlin.dev>2025-09-19 11:58:41 +0200
committerTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-09-22 12:35:44 +0200
commit856d41f836de3983d435c8cdc9deadba2d669b8c (patch)
tree8b88d576a8c549c28a255b791a6a75b9021a70d7 /desktop
parentc263968b301e94856b79f807a6df8cf720f2b071 (diff)
downloadmullvadvpn-856d41f836de3983d435c8cdc9deadba2d669b8c.tar.xz
mullvadvpn-856d41f836de3983d435c8cdc9deadba2d669b8c.zip
Improve accessibility when navigating to setting via feature indicator
Diffstat (limited to 'desktop')
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/settings-accordion/SettingsAccordion.tsx4
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/settings-list-item/SettingsListItem.tsx7
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/SettingsListbox.tsx15
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/settings-toggle-list-item/SettingsToggleListItem.tsx4
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/open-vpn-settings/components/mss-fix-setting/MssFixSetting.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/vpn-settings/components/dns-blocker-settings/DnsBlockerSetting.tsx1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/wireguard-settings/components/mtu-setting/MtuSetting.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts20
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToReference.ts (renamed from desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToAnchor.ts)0
10 files changed, 41 insertions, 16 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/settings-accordion/SettingsAccordion.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/settings-accordion/SettingsAccordion.tsx
index 7df1931bbf..389a4c4a92 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/settings-accordion/SettingsAccordion.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/settings-accordion/SettingsAccordion.tsx
@@ -17,6 +17,7 @@ function SettingsAccordion({ accordionId, anchorId, ...props }: SettingsAccordio
const initialExpanded = location.state.expandedSections[accordionId];
const [expanded, setExpanded] = React.useState(initialExpanded);
const { ref, animation } = useScrollToListItem(anchorId);
+ const titleId = React.useId();
const handleOnExpandedChange = React.useCallback(
(value: boolean) => {
@@ -35,9 +36,12 @@ function SettingsAccordion({ accordionId, anchorId, ...props }: SettingsAccordio
return (
<Accordion
ref={ref}
+ tabIndex={-1}
animation={animation}
expanded={expanded}
onExpandedChange={handleOnExpandedChange}
+ titleId={titleId}
+ aria-labelledby={titleId}
{...props}
/>
);
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/settings-list-item/SettingsListItem.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/settings-list-item/SettingsListItem.tsx
index 268f56c9b6..0c505226ef 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/settings-list-item/SettingsListItem.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/settings-list-item/SettingsListItem.tsx
@@ -4,12 +4,15 @@ import { ListItem, ListItemProps } from '../../lib/components/list-item';
export type SettingsListItemProps = ListItemProps & {
anchorId?: ScrollToAnchorId;
+ labelId?: string;
};
-function SettingsListItem({ anchorId, ...props }: SettingsListItemProps) {
+function SettingsListItem({ labelId, anchorId, ...props }: SettingsListItemProps) {
const { ref, animation } = useScrollToListItem(anchorId);
- return <ListItem ref={ref} animation={animation} {...props} />;
+ return (
+ <ListItem ref={ref} aria-labelledby={labelId} tabIndex={-1} animation={animation} {...props} />
+ );
}
const SettingsListItemNamespace = Object.assign(SettingsListItem, {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/SettingsListbox.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/SettingsListbox.tsx
index 0fca7d4357..3b15c84c6a 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/SettingsListbox.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/SettingsListbox.tsx
@@ -1,3 +1,5 @@
+import React from 'react';
+
import { ScrollToAnchorId } from '../../../shared/ipc-types';
import { useScrollToListItem } from '../../hooks';
import { Listbox, ListboxProps } from '../../lib/components/listbox';
@@ -9,8 +11,19 @@ export type SettingsListboxProps<T> = Omit<ListboxProps<T>, 'animation'> & {
function SettingsListbox<T>({ anchorId, ...props }: SettingsListboxProps<T>) {
const { ref, animation } = useScrollToListItem(anchorId);
+ const labelId = React.useId();
- return <Listbox ref={ref} animation={animation} {...props} />;
+ return (
+ <Listbox
+ ref={ref}
+ tabIndex={-1}
+ role="region"
+ labelId={labelId}
+ aria-labelledby={labelId}
+ animation={animation}
+ {...props}
+ />
+ );
}
const SettingsListboxNamespace = Object.assign(SettingsListbox, {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/settings-toggle-list-item/SettingsToggleListItem.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/settings-toggle-list-item/SettingsToggleListItem.tsx
index e1156772fe..334f1d405c 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/settings-toggle-list-item/SettingsToggleListItem.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/settings-toggle-list-item/SettingsToggleListItem.tsx
@@ -25,12 +25,14 @@ function SettingsToggleListItem({
...props
}: SettingsToggleListItemProps) {
const descriptionId = React.useId();
+ const labelId = React.useId();
return (
<SettingsToggleListItemProvider descriptionId={descriptionId}>
- <SettingsListItem disabled={disabled} {...props}>
+ <SettingsListItem labelId={labelId} disabled={disabled} {...props}>
<SettingsListItem.Item>
<SettingsListItem.Content>
<Switch
+ labelId={labelId}
checked={checked}
onCheckedChange={onCheckedChange}
disabled={disabled}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/open-vpn-settings/components/mss-fix-setting/MssFixSetting.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/open-vpn-settings/components/mss-fix-setting/MssFixSetting.tsx
index 01900b5955..d56b3ddf58 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/views/open-vpn-settings/components/mss-fix-setting/MssFixSetting.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/open-vpn-settings/components/mss-fix-setting/MssFixSetting.tsx
@@ -71,7 +71,7 @@ export function MssFixSetting() {
);
return (
- <SettingsListItem anchorId="mss-fix-setting">
+ <SettingsListItem anchorId="mss-fix-setting" aria-labelledby={labelId}>
<SettingsListItem.Item>
<SettingsListItem.Content>
<SettingsListItem.Label id={labelId}>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/vpn-settings/components/dns-blocker-settings/DnsBlockerSetting.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/vpn-settings/components/dns-blocker-settings/DnsBlockerSetting.tsx
index 2c086d4a5b..52e0d6d28a 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/views/vpn-settings/components/dns-blocker-settings/DnsBlockerSetting.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/vpn-settings/components/dns-blocker-settings/DnsBlockerSetting.tsx
@@ -26,6 +26,7 @@ export function DnsBlockerSettings() {
<SettingsAccordion
accordionId="dns-blocker-setting"
anchorId="dns-blocker-setting"
+ aria-label={messages.pgettext('vpn-settings-view', 'DNS content blockers')}
disabled={dns.state === 'custom'}>
<SettingsAccordion.Header>
<SettingsAccordion.Title>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/wireguard-settings/components/mtu-setting/MtuSetting.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/wireguard-settings/components/mtu-setting/MtuSetting.tsx
index d1fd17e81b..fc4d8f6a27 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/views/wireguard-settings/components/mtu-setting/MtuSetting.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/wireguard-settings/components/mtu-setting/MtuSetting.tsx
@@ -79,7 +79,7 @@ export function MtuSetting() {
);
return (
- <SettingsListItem anchorId="mtu-setting">
+ <SettingsListItem anchorId="mtu-setting" aria-labelledby={labelId}>
<SettingsListItem.Item>
<SettingsListItem.Content>
<SettingsListItem.Label id={labelId}>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts
index a152881c63..2a4f1dfdaf 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/hooks/index.ts
@@ -7,7 +7,7 @@ export * from './useHasAppUpgradeVerifiedInstallerPath';
export * from './useIsDefaultActiveElementAfterMount';
export * from './useIsPlatformLinux';
export * from './useMeasure';
-export * from './useScrollToAnchor';
+export * from './useScrollToReference';
export * from './useScrollToListItem';
export * from './useInitialFocus';
export * from './useFocusReference';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts b/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts
index 91c1064d90..34b42cdfc5 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToListItem.ts
@@ -3,9 +3,10 @@ import React from 'react';
import { ScrollToAnchorId } from '../../shared/ipc-types';
import { ListItemAnimation } from '../lib/components/list-item';
import { useHistory } from '../lib/history';
-import { useScrollToReference } from '.';
+import { useFocusReference } from './useFocusReference';
+import { useScrollToReference } from './useScrollToReference';
-export const useScrollToListItem = <T extends Element = HTMLDivElement>(
+export const useScrollToListItem = <T extends HTMLElement = HTMLDivElement>(
id?: ScrollToAnchorId,
): {
ref?: React.RefObject<T | null>;
@@ -16,13 +17,13 @@ export const useScrollToListItem = <T extends Element = HTMLDivElement>(
const { location } = history;
const { state } = location;
- const anchorId = state?.options?.find((option) => option.type === 'scroll-to-anchor')?.id;
- const scroll = id === anchorId && anchorId !== undefined;
+ const scrollToAnchorOption = state?.options?.find((option) => option.type === 'scroll-to-anchor');
+ const shouldScroll = scrollToAnchorOption && scrollToAnchorOption.id === id;
const handleScrolled = React.useCallback(() => {
const options = state?.options?.filter((option) => {
if (option.type === 'scroll-to-anchor') {
- return option.id !== anchorId;
+ return option.id !== scrollToAnchorOption?.id;
}
return true;
@@ -32,11 +33,12 @@ export const useScrollToListItem = <T extends Element = HTMLDivElement>(
...state,
options,
});
- }, [anchorId, history, location, state]);
+ }, [history, location, scrollToAnchorOption?.id, state]);
- useScrollToReference(ref, scroll, handleScrolled);
+ useScrollToReference(ref, shouldScroll, handleScrolled);
+ useFocusReference(ref, shouldScroll);
- if (anchorId === undefined) {
+ if (scrollToAnchorOption === undefined) {
return {
ref: undefined,
animation: undefined,
@@ -44,6 +46,6 @@ export const useScrollToListItem = <T extends Element = HTMLDivElement>(
}
return {
ref,
- animation: scroll ? 'flash' : 'dim',
+ animation: shouldScroll ? 'flash' : 'dim',
};
};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToAnchor.ts b/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToReference.ts
index fd8919edef..fd8919edef 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToAnchor.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/hooks/useScrollToReference.ts