summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOliver <oliver@mohlin.dev>2025-10-02 08:30:58 +0200
committerTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-10-07 11:35:59 +0200
commit76bb0a13c190cf65d3acd749b55e4d336c5c5f5a (patch)
tree400a1e976210724a61e69c3575989dab82d4477d
parent1f18eece64ee462dc5ef2214ab1832c403db44f0 (diff)
downloadmullvadvpn-76bb0a13c190cf65d3acd749b55e4d336c5c5f5a.tar.xz
mullvadvpn-76bb0a13c190cf65d3acd749b55e4d336c5c5f5a.zip
Select options via data-attribute instead of role
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/input-option/components/input-option-trigger/InputOptionTrigger.tsx1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/split-option/components/split-option-item/SplitOptionItem.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-option/components/listbox-option-trigger/ListboxOptionTrigger.tsx1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-options/ListboxOptions.tsx1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-focus-option-by-index.ts6
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-get-initial-focus-index.ts6
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-handle-keyboard-navigation.ts11
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-options.ts12
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/utils/get-options.ts6
9 files changed, 30 insertions, 16 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/input-option/components/input-option-trigger/InputOptionTrigger.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/input-option/components/input-option-trigger/InputOptionTrigger.tsx
index e7343ee11a..12e928876a 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/input-option/components/input-option-trigger/InputOptionTrigger.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/input-option/components/input-option-trigger/InputOptionTrigger.tsx
@@ -63,6 +63,7 @@ export const InputOptionTrigger = ({ children, ...props }: InputOptionTriggerPro
return (
<StyledInputOptionTrigger
role="option"
+ data-option
aria-selected={selected}
tabIndex={-1}
onFocus={handleFocus}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/split-option/components/split-option-item/SplitOptionItem.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/split-option/components/split-option-item/SplitOptionItem.tsx
index cbe431ad7e..0c1d362585 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/split-option/components/split-option-item/SplitOptionItem.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/settings-listbox/components/split-option/components/split-option-item/SplitOptionItem.tsx
@@ -4,7 +4,7 @@ export type ListBoxOptionWithNavigationProps = React.ComponentPropsWithRef<'li'>
export function SplitOptionItem({ children, ...props }: ListBoxOptionWithNavigationProps) {
return (
- <Listbox.Option.Trigger {...props}>
+ <Listbox.Option.Trigger data-option {...props}>
<Listbox.Option.Item>
<Listbox.Option.Content>
<Listbox.Option.Group>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-option/components/listbox-option-trigger/ListboxOptionTrigger.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-option/components/listbox-option-trigger/ListboxOptionTrigger.tsx
index 383a0aac32..4c049ec695 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-option/components/listbox-option-trigger/ListboxOptionTrigger.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-option/components/listbox-option-trigger/ListboxOptionTrigger.tsx
@@ -91,6 +91,7 @@ export const ListboxOptionTrigger = ({ children, ...props }: ListboxOptionTrigge
return (
<StyledListItemOptionTrigger
ref={triggerRef}
+ data-option
role="option"
aria-selected={selected}
aria-disabled={disabled}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-options/ListboxOptions.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-options/ListboxOptions.tsx
index fbb97cd492..0a4d36ab40 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-options/ListboxOptions.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/listbox/components/listbox-options/ListboxOptions.tsx
@@ -13,6 +13,7 @@ export function ListboxOptions({ children }: ListboxOptionsProps) {
focusedIndex,
optionsRef,
setFocusedIndex,
+ selector: '[data-option="true"]:not([aria-disabled="true"])',
});
const onKeyDown = React.useCallback(
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-focus-option-by-index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-focus-option-by-index.ts
index bde967f9e9..bc60b0bb70 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-focus-option-by-index.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-focus-option-by-index.ts
@@ -5,17 +5,19 @@ import { getOptions } from '../utils';
export const useFocusOptionByIndex = <T extends HTMLElement>({
optionsRef,
setFocusedIndex,
+ selector,
}: {
optionsRef: React.RefObject<T | null>;
setFocusedIndex: (index: number) => void;
+ selector: string;
}) => {
return React.useCallback(
(index: number) => {
- const options = getOptions(optionsRef.current);
+ const options = getOptions(optionsRef.current, selector);
setFocusedIndex(index);
const option = options[index];
option.focus();
},
- [optionsRef, setFocusedIndex],
+ [optionsRef, selector, setFocusedIndex],
);
};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-get-initial-focus-index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-get-initial-focus-index.ts
index bebd0459bf..3744725990 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-get-initial-focus-index.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-get-initial-focus-index.ts
@@ -5,12 +5,14 @@ import { getOptions, getSelectedOptionIndex } from '../utils';
export const useGetInitialFocusIndex = <T extends HTMLElement>({
focusedIndex,
optionsRef,
+ selector,
}: {
focusedIndex?: number;
optionsRef: React.RefObject<T | null>;
+ selector: string;
}) => {
return React.useCallback(() => {
- const options = getOptions(optionsRef.current);
+ const options = getOptions(optionsRef.current, selector);
if (focusedIndex !== undefined) {
return focusedIndex;
}
@@ -19,5 +21,5 @@ export const useGetInitialFocusIndex = <T extends HTMLElement>({
return selectedOptionIndex;
}
return 0;
- }, [focusedIndex, optionsRef]);
+ }, [focusedIndex, optionsRef, selector]);
};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-handle-keyboard-navigation.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-handle-keyboard-navigation.ts
index 82a74cfe4c..c42d4978df 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-handle-keyboard-navigation.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-handle-keyboard-navigation.ts
@@ -4,23 +4,26 @@ import { getOptions } from '../utils';
import { useFocusOptionByIndex } from './use-focus-option-by-index';
import { useGetInitialFocusIndex } from './use-get-initial-focus-index';
-type Orientation = 'horizontal' | 'vertical';
+export type Orientation = 'horizontal' | 'vertical';
export const useHandleKeyboardNavigation = <T extends HTMLElement>({
optionsRef,
focusedIndex,
setFocusedIndex,
orientation = 'vertical',
+ selector,
}: {
optionsRef: React.RefObject<T | null>;
focusedIndex?: number;
setFocusedIndex: (index: number) => void;
orientation?: Orientation;
+ selector: string;
}) => {
- const getInitialFocusIndex = useGetInitialFocusIndex({ optionsRef, focusedIndex });
+ const getInitialFocusIndex = useGetInitialFocusIndex({ optionsRef, focusedIndex, selector });
const focusOptionByIndex = useFocusOptionByIndex({
optionsRef,
setFocusedIndex,
+ selector,
});
const nextKey = orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight';
@@ -28,7 +31,7 @@ export const useHandleKeyboardNavigation = <T extends HTMLElement>({
return React.useCallback(
(event: React.KeyboardEvent) => {
- const options = getOptions(optionsRef.current);
+ const options = getOptions(optionsRef.current, selector);
const initialFocusedIndex = getInitialFocusIndex();
@@ -52,6 +55,6 @@ export const useHandleKeyboardNavigation = <T extends HTMLElement>({
focusOptionByIndex(options.length - 1);
}
},
- [focusOptionByIndex, getInitialFocusIndex, nextKey, optionsRef, previousKey],
+ [focusOptionByIndex, getInitialFocusIndex, nextKey, optionsRef, previousKey, selector],
);
};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-options.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-options.ts
index a1f41a28db..8f673c9765 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-options.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/hooks/use-options.ts
@@ -1,25 +1,29 @@
import React from 'react';
import { getInitialOption, getOptions } from '../utils';
-import { useHandleKeyboardNavigation } from './use-handle-keyboard-navigation';
+import { Orientation, useHandleKeyboardNavigation } from './use-handle-keyboard-navigation';
export type UseOptionsProps<T extends HTMLElement> = {
optionsRef: React.RefObject<T | null>;
focusedIndex?: number;
setFocusedIndex: React.Dispatch<React.SetStateAction<number | undefined>>;
+ selector: string;
+ orientation?: Orientation;
};
export function useOptions<T extends HTMLElement>({
optionsRef,
focusedIndex,
setFocusedIndex,
+ selector,
+ orientation = 'vertical',
}: UseOptionsProps<T>) {
const [tabIndex, setTabIndex] = React.useState<number>(0);
const handleFocus = React.useCallback(
(event: React.FocusEvent) => {
if (!optionsRef.current?.isSameNode(event.target)) return;
- const options = getOptions(optionsRef.current);
+ const options = getOptions(optionsRef.current, selector);
const initialOption = getInitialOption(options);
if (initialOption) {
@@ -28,13 +32,15 @@ export function useOptions<T extends HTMLElement>({
initialOption.focus();
}
},
- [optionsRef],
+ [optionsRef, selector],
);
const handleKeyboardNavigation = useHandleKeyboardNavigation({
optionsRef,
setFocusedIndex,
focusedIndex,
+ selector,
+ orientation,
});
const handleBlur = React.useCallback(
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/utils/get-options.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/utils/get-options.ts
index d37647936c..0754a72631 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/utils/get-options.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/utils/get-options.ts
@@ -1,7 +1,5 @@
-export const getOptions = (container: HTMLElement | null) => {
- const options = container?.querySelectorAll<HTMLElement>(
- '[role="option"]:not([aria-disabled="true"])',
- );
+export const getOptions = (container: HTMLElement | null, selector: string) => {
+ const options = container?.querySelectorAll<HTMLElement>(selector);
if (options) {
return Array.from(options);