Skip to content

Commit e315a9a

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

File tree

5 files changed

+310
-55
lines changed

5 files changed

+310
-55
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: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
11
<template>
22
<div
33
class="header-navigation"
4+
@mouseleave="setCurrentCategory(null)"
45
>
56
<div class="header-navigation__main">
67
<HeaderNavigationItem
78
v-for="(category, index) in categoryTree"
89
:key="index"
10+
ref="lvl0CatRefs"
911
:data-testid="category.uid"
10-
class="nav-item"
1112
:label="category.name"
1213
:link="localePath(getCatLink(category))"
13-
@mouseenter.native="setCurrentCategory(category)"
14-
@keyup.tab.native="setCurrentCategory(category)"
14+
tabindex="0"
15+
aria-haspopup="true"
16+
class="nav-item"
17+
:data-index="index"
18+
:has-children="hasChildren(category)"
19+
@mouseenter.native.prevent="onMouseEnter(category)"
20+
@keydown.down.native.prevent="setCurrentCategory(category)"
21+
@keydown.up.native.prevent="setCurrentCategory(null)"
22+
@keyup.tab.native.prevent="setFocus($event)"
23+
@keydown.right.native.prevent="navRight()"
24+
@keydown.left.native.prevent="navLeft()"
25+
@keydown.enter.native.prevent="goToCategory(localePath(getCatLink(category)))"
1526
/>
1627
</div>
1728
<HeaderNavigationSubcategories
1829
v-if="hasChildren(currentCategory)"
1930
:current-category="currentCategory"
20-
@hideSubcategories="setCurrentCategory(null)"
31+
:has-focus="hasFocus"
32+
@hideSubcategories="focusRootElementAndHideSubcategories"
2133
/>
2234
</div>
2335
</template>
2436
<script lang="ts">
2537
import {
26-
defineComponent, PropType, ref,
38+
defineComponent, PropType, ref, useRouter,
2739
} from '@nuxtjs/composition-api';
2840
import HeaderNavigationItem from './HeaderNavigationItem.vue';
2941
@@ -44,19 +56,74 @@ export default defineComponent({
4456
},
4557
setup() {
4658
const { getCatLink } = useUiHelpers();
59+
const router = useRouter();
60+
4761
const currentCategory = ref<CategoryTree>(null);
62+
const lvl0CatRefs = ref([]);
63+
const hasFocus = ref(false);
64+
let lvl0CatFocusIdx = 0;
65+
let focusedElement = null;
4866
4967
const setCurrentCategory = (category: CategoryTree | null) => {
5068
currentCategory.value = category;
5169
};
5270
5371
const hasChildren = (category: CategoryTree) => Boolean(category?.children);
5472
73+
const setFocus = (event) => {
74+
focusedElement = event.target;
75+
lvl0CatFocusIdx = Number(event.target.dataset.index);
76+
hasFocus.value = true;
77+
};
78+
79+
const focusRootElementAndHideSubcategories = () => {
80+
setCurrentCategory(null);
81+
if (focusedElement !== null) focusedElement.focus();
82+
};
83+
84+
const navRight = () => {
85+
lvl0CatFocusIdx++;
86+
if (lvl0CatRefs.value[lvl0CatFocusIdx]) {
87+
lvl0CatRefs.value[lvl0CatFocusIdx].$el.focus();
88+
focusedElement = lvl0CatRefs.value[lvl0CatFocusIdx].$el;
89+
} else {
90+
lvl0CatFocusIdx--;
91+
}
92+
};
93+
94+
const navLeft = () => {
95+
lvl0CatFocusIdx--;
96+
if (lvl0CatRefs.value[lvl0CatFocusIdx]) {
97+
lvl0CatRefs.value[lvl0CatFocusIdx].$el.focus();
98+
focusedElement = lvl0CatRefs.value[lvl0CatFocusIdx].$el;
99+
} else {
100+
lvl0CatFocusIdx++;
101+
}
102+
};
103+
104+
const onMouseEnter = (category: CategoryTree) => {
105+
currentCategory.value = category;
106+
focusedElement = null;
107+
hasFocus.value = false;
108+
};
109+
110+
const goToCategory = (path: string) => {
111+
router.push(path);
112+
};
113+
55114
return {
56115
getCatLink,
57116
setCurrentCategory,
58117
currentCategory,
59118
hasChildren,
119+
setFocus,
120+
focusRootElementAndHideSubcategories,
121+
lvl0CatRefs,
122+
navRight,
123+
navLeft,
124+
hasFocus,
125+
onMouseEnter,
126+
goToCategory,
60127
};
61128
},
62129
});
Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
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>
2+
<div class="sf-header-navigation-item__item sf-header-navigation-item__item--desktop">
3+
<SfLink
4+
class="sf-header-navigation-item__link"
5+
:link="link"
6+
tabindex="-1"
7+
>
8+
{{
9+
label
10+
}}
11+
<SfIcon
12+
v-if="hasChildren"
13+
icon="chevron_down"
14+
size="xxs"
15+
color="green-primary"
16+
viewBox="0 0 24 24"
17+
:coverage="1"
18+
/>
19+
</SfLink>
1320
</div>
1421
</template>
1522
<script lang="ts">
16-
import { SfLink } from '@storefront-ui/vue';
23+
import { SfLink, SfIcon } from '@storefront-ui/vue';
1724
1825
export default {
1926
name: 'HeaderNavigationItem',
2027
components: {
2128
SfLink,
29+
SfIcon,
2230
},
2331
props: {
2432
label: {
@@ -29,6 +37,19 @@ export default {
2937
type: [String, Object],
3038
default: '',
3139
},
40+
hasChildren: {
41+
type: Boolean,
42+
default: false,
43+
},
3244
},
3345
};
3446
</script>
47+
<style lang="scss">
48+
.sf-header-navigation-item__link {
49+
display: flex;
50+
.sf-icon {
51+
display: inline-flex;
52+
margin: 0 var(--spacer-xs);
53+
}
54+
}
55+
</style>

0 commit comments

Comments
 (0)