Element focus after variant selection (#275)

* Element focus after variant selection * Keyboard navigation fixed

Elchin Zakizadeh committed Oct 28, 2022 at 18:09 UTC 34b48188717cef31c61e0fda49404d77e6b6d0dc
1 file changed +35 -6
theme/src/components/variant-select.js
+35 -6
@@ -16,6 +16,18 @@ VariantSelect.Menu = styled(Dropdown.Menu)`
16 function VariantSelect(props) {
17 const path = NavHierarchy.getPath(props.location.pathname);
18 const vp = NavHierarchy.getVariantAndPage(props.root, path);
19 + const wrapper = React.createRef(null)
20 +
21 + React.useEffect(() => {
22 + const queryParams = new URLSearchParams(window.location.search)
23 + if (queryParams.get('v') === 'true') {
24 + wrapper?.current?.querySelector('summary')?.focus()
25 +
26 + const url = new URL(window.location);
27 + url.searchParams.delete('v')
28 + window.history.replaceState(null, '', url.toString());
29 + }
30 + }, [])
31
32 if (!vp) {
33 return null;
@@ -38,17 +50,32 @@ function VariantSelect(props) {
50 document.body.click()
51 }
52
53 + function anchorClickHandler(event, url) {
54 + event.preventDefault()
55 + window.location.href = url + "?v=true";
56 + }
57 +
58 + function onItemEnterKey(event, url) {
59 + if (event.key === 'Enter') {
60 + window.location.href = url + "?v=true";
61 + }
62 + }
63 +
64 variantPages.forEach((match, index) => {
65 if (match.page.url === path) {
66 selectedItem = match;
67 }
45 - function onItemEnterKey(event) {
46 - if (event.key === 'Enter') {
47 - window.location.href = match.page.url;
48 - }
49 - }
68 items.push(
51 - <a style={{ textDecoration: 'none' }} aria-label={`${match.variant.title}. List items ${index + 1} of ${variantPages.length}`} href={match.page.url} onKeyDown={onItemEnterKey} onBlur={index === (variantPages.length - 1) ? collapseDropdown : undefined} tabIndex={0} key={match.variant.title}>
69 + <a
70 + style={{ textDecoration: 'none' }}
71 + tabIndex={0}
72 + key={match.variant.title}
73 + href={match.page.url}
74 + onClick={e => anchorClickHandler(e, match.page.url)}
75 + onKeyDown={e => onItemEnterKey(e, match.page.url)}
76 + onBlur={index === (variantPages.length - 1) ? collapseDropdown : undefined}
77 + aria-label={`${match.variant.title}. List items ${index + 1} of ${variantPages.length}`}
78 + >
79 <Dropdown.Item>{match.variant.title}</Dropdown.Item>
80 </a>
81 );
@@ -66,12 +93,14 @@ function VariantSelect(props) {
93 }
94
95 return (
96 + <div ref={wrapper}>
97 <Dropdown onKeyDown={onDropDownKeyDown} overlay={props.overlay}>
98 <Dropdown.Button>{selectedItem.variant.title}</Dropdown.Button>
99 <VariantSelect.Menu direction={props.direction} width={props.menuWidth}>
100 {items}
101 </VariantSelect.Menu>
102 </Dropdown>
103 + </div>
104 );
105 }
106