Skip to content

Commit 1f86987

Browse files
committed
refactor: fix CR issues
1 parent 2391159 commit 1f86987

File tree

5 files changed

+303
-61
lines changed

5 files changed

+303
-61
lines changed

.eslintrc.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ module.exports = {
3232
],
3333
rules: {
3434
"@typescript-eslint/no-floating-promises": "off",
35-
"jest/expect-expect": "off"
35+
"jest/expect-expect": [
36+
"error",
37+
{
38+
"assertFunctionNames": ["expect", "getByRole", "getByTestId"],
39+
}
40+
],
41+
"no-plusplus": "off",
3642
}
3743
}
44+

packages/theme/components/Header/Navigation/HeaderNavigation.vue

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
<template>
2-
<div
3-
class="header-navigation"
4-
>
5-
<div class="header-navigation__main">
2+
<div class="header-navigation">
3+
<div class="sf-header-navigation-item__item sf-header-navigation-item__item--desktop">
64
<HeaderNavigationItem
75
v-for="(category, index) in categoryTree"
86
:key="index"
7+
ref="lvl0CatRefs"
98
:data-testid="category.uid"
10-
class="nav-item"
119
:label="category.name"
1210
:link="localePath(getCatLink(category))"
13-
@mouseenter.native="setCurrentCategory(category)"
14-
@keyup.tab.native="setCurrentCategory(category)"
11+
tabindex="1"
12+
aria-haspopup="true"
13+
class="nav-item"
14+
:data-index="index"
15+
:has-children="hasChildren(category)"
16+
@mouseenter.native.prevent="onMouseEnter(category)"
17+
@keydown.down.native.prevent="setCurrentCategory(category)"
18+
@keydown.up.native.prevent="setCurrentCategory(null)"
19+
@keyup.tab.native.prevent="setFocus($event)"
20+
@keydown.right.native.prevent="navRight()"
21+
@keydown.left.native.prevent="navLeft()"
1522
/>
1623
</div>
1724
<HeaderNavigationSubcategories
1825
v-if="hasChildren(currentCategory)"
1926
:current-category="currentCategory"
20-
@hideSubcategories="setCurrentCategory(null)"
27+
:has-focus="hasFocus"
28+
@hideSubcategories="focusRootElementAndHideSubcategories"
2129
/>
2230
</div>
2331
</template>
@@ -44,19 +52,68 @@ export default defineComponent({
4452
},
4553
setup() {
4654
const { getCatLink } = useUiHelpers();
55+
4756
const currentCategory = ref<CategoryTree>(null);
57+
const lvl0CatRefs = ref([]);
58+
const hasFocus = ref(false);
59+
let lvl0CatFocusIdx = 0;
60+
let focusedElement = null;
4861
4962
const setCurrentCategory = (category: CategoryTree | null) => {
5063
currentCategory.value = category;
5164
};
5265
5366
const hasChildren = (category: CategoryTree) => Boolean(category?.children);
5467
68+
const setFocus = (event) => {
69+
focusedElement = event.target;
70+
lvl0CatFocusIdx = Number(event.target.dataset.index);
71+
hasFocus.value = true;
72+
};
73+
74+
const focusRootElementAndHideSubcategories = () => {
75+
setCurrentCategory(null);
76+
if (focusedElement !== null) focusedElement.focus();
77+
};
78+
79+
const navRight = () => {
80+
lvl0CatFocusIdx++;
81+
if (lvl0CatRefs.value[lvl0CatFocusIdx]) {
82+
lvl0CatRefs.value[lvl0CatFocusIdx].$el.focus();
83+
focusedElement = lvl0CatRefs.value[lvl0CatFocusIdx].$el;
84+
} else {
85+
lvl0CatFocusIdx--;
86+
}
87+
};
88+
89+
const navLeft = () => {
90+
lvl0CatFocusIdx--;
91+
if (lvl0CatRefs.value[lvl0CatFocusIdx]) {
92+
lvl0CatRefs.value[lvl0CatFocusIdx].$el.focus();
93+
focusedElement = lvl0CatRefs.value[lvl0CatFocusIdx].$el;
94+
} else {
95+
lvl0CatFocusIdx++;
96+
}
97+
};
98+
99+
const onMouseEnter = (category: CategoryTree) => {
100+
currentCategory.value = category;
101+
focusedElement = null;
102+
hasFocus.value = false;
103+
};
104+
55105
return {
56106
getCatLink,
57107
setCurrentCategory,
58108
currentCategory,
59109
hasChildren,
110+
setFocus,
111+
focusRootElementAndHideSubcategories,
112+
lvl0CatRefs,
113+
navRight,
114+
navLeft,
115+
hasFocus,
116+
onMouseEnter,
60117
};
61118
},
62119
});
Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
<template>
2-
<div class="sf-header-navigation-item">
3-
<div class="sf-header-navigation-item__item sf-header-navigation-item__item--desktop">
4-
<SfLink
5-
class="sf-header-navigation-item__link"
6-
:link="link"
7-
>
8-
{{
9-
label
10-
}}
11-
</SfLink>
12-
</div>
13-
</div>
2+
<SfLink
3+
class="sf-header-navigation-item__link"
4+
:link="link"
5+
>
6+
{{
7+
label
8+
}}
9+
<SfIcon
10+
v-if="hasChildren"
11+
icon="chevron_down"
12+
size="xxs"
13+
color="green-primary"
14+
viewBox="0 0 24 24"
15+
:coverage="1"
16+
/>
17+
</SfLink>
1418
</template>
1519
<script lang="ts">
16-
import { SfLink } from '@storefront-ui/vue';
20+
import { SfLink, SfIcon } from '@storefront-ui/vue';
1721
1822
export default {
1923
name: 'HeaderNavigationItem',
2024
components: {
2125
SfLink,
26+
SfIcon,
2227
},
2328
props: {
2429
label: {
@@ -29,6 +34,19 @@ export default {
2934
type: [String, Object],
3035
default: '',
3136
},
37+
hasChildren: {
38+
type: Boolean,
39+
default: false,
40+
},
3241
},
3342
};
3443
</script>
44+
<style lang="scss">
45+
.sf-header-navigation-item__link {
46+
display: flex;
47+
.sf-icon {
48+
display: inline-flex;
49+
margin: 0 var(--spacer-xs);
50+
}
51+
}
52+
</style>

0 commit comments

Comments
 (0)