New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Next: Mega menu for desktop/mobile #5685
Closed
+686
−43
Closed
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
2e5c4f4
fix: from cr and update customQuery
lukaszjedrasik 73a20f8
chore: removed unnecessary fragment from query
lukaszjedrasik 2c7d4b3
chore: fixes
lukaszjedrasik f0d28b7
chore: added changelog
lukaszjedrasik 2fbdf93
refactor
lukaszjedrasik 462c06d
chore: update branch
lukaszjedrasik b810e5c
chore: megaMenu for mobile
lukaszjedrasik 67a2253
fix: dom exception
lukaszjedrasik 5cd82d3
refactor
lukaszjedrasik 8d05e3b
fix: category banner on mobile
lukaszjedrasik a63f8e9
fix: category banner height
lukaszjedrasik 493eb34
chore: ui fixes
lukaszjedrasik c7a46f3
chore: added class to loader
lukaszjedrasik 9f65f3d
fix: naming, banners, transition
lukaszjedrasik d90aa69
fix: fade naming
lukaszjedrasik b7afe44
fix: loader
lukaszjedrasik f2ca1ac
chore: svg instead SfLoader
lukaszjedrasik 5093253
chore: revert svg instead SfLoader
lukaszjedrasik dce3291
chore: better banners loading
lukaszjedrasik e2afaa6
chore: adjustment HeaderNav
lukaszjedrasik c2b5f38
fix: computed instead function
lukaszjedrasik 1636fbd
chore: adjust to next
lukaszjedrasik 7743e23
chore: add function instead copy code
lukaszjedrasik 3147ce9
chore: fixes
lukaszjedrasik 532e2ac
chore: fixes
lukaszjedrasik a131c61
chore: adjust boilerplate
lukaszjedrasik aec6269
fix: transition
lukaszjedrasik f8263d2
chore: adjust to next
lukaszjedrasik c84bcb9
chore: missing spinner
lukaszjedrasik 7a7a878
chore: update
lukaszjedrasik babfefe
fix: loader visibility on mobile
lukaszjedrasik e573905
chore: update changelog
lukaszjedrasik c3f5160
chore: update changelog
lukaszjedrasik 4872662
chore: duplicates refactor
lukaszjedrasik 43cbe0a
chore: hasChildren as a computed
lukaszjedrasik 447174e
fix: cr suggestions
lukaszjedrasik 4596e11
chore: rename NewCatBanners -> CatBanners
lukaszjedrasik 4bfef21
fix loader position
lukaszjedrasik 46526dc
fix routing
lukaszjedrasik 6587eb4
chore: branch update
lukaszjedrasik f5678d3
update branch
lukaszjedrasik File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
223 changes: 223 additions & 0 deletions
223
packages/commercetools/theme/components/Header/HeaderNav.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
<template> | ||
<div> | ||
<SfHeaderNavigation v-if="!isMobile"> | ||
<SfHeaderNavigationItem | ||
v-for="category in categories" | ||
:key="category.id" | ||
:label="category.name" | ||
@mouseenter="() => handleMouseEnter(category.slug)" | ||
@mouseleave="() => handleMouseLeave()" | ||
@click="handleMouseLeave()" | ||
:link="localePath(`/c/${category.slug}`)" | ||
v-e2e="category.name === 'Women' ? 'app-header-url_women' : category.name === 'Men' ? 'app-header-url_women' : ''" | ||
> | ||
<SfMegaMenu | ||
is-absolute | ||
:visible="currentCatSlug === category.slug" | ||
:title="category.name" | ||
@close="currentCatSlug = ''" | ||
v-if="hasChildren" | ||
> | ||
<SfMegaMenuColumn | ||
v-for="subCategory in activeCategory[0].children" | ||
:key="subCategory.id" | ||
:title="subCategory.name" | ||
> | ||
<template #title="{ title, changeActive }"> | ||
<SfMenuItem | ||
:label="title" | ||
class="sf-mega-menu-column__header" | ||
@click="$router.push(`/c/${currentCatSlug}/${subCategory.slug}`)" | ||
/> | ||
</template> | ||
<SfLoader :loading="subCategoriesLoading"> | ||
<SfList v-if="!subCategoriesLoading"> | ||
<SfListItem | ||
v-for="subCategoryChild in subCategory.children" | ||
:key="subCategoryChild.id" | ||
> | ||
<SfMenuItem :label="subCategoryChild.name" :link="localePath(`/c/${currentCatSlug}/${subCategoryChild.slug}`)"> | ||
<SfLink> | ||
{{ subCategoryChild.name }} | ||
</SfLink> | ||
</SfMenuItem> | ||
</SfListItem> | ||
</SfList> | ||
</SfLoader> | ||
</SfMegaMenuColumn> | ||
<CatBanners v-if="!subCategoriesLoading && hasBanners" /> | ||
</SfMegaMenu> | ||
</SfHeaderNavigationItem> | ||
</SfHeaderNavigation> | ||
<transition name="sf-fade" mode="out-in"> | ||
<SfMegaMenu | ||
v-if="isMobile && isMobileMenuOpen" | ||
visible | ||
@close="toggleMobileMenu" | ||
class="mobile-menu" | ||
> | ||
<SfMegaMenuColumn | ||
v-for="category in categories" | ||
:key="category.id" | ||
:title="category.name" | ||
> | ||
<template #title="{ title, changeActive }"> | ||
<SfMenuItem | ||
:label="title" | ||
class="sf-mega-menu-column__header" | ||
@click="changeActive(title); handleClickCategoryLvl(category.slug, 1)" | ||
/> | ||
</template> | ||
<SfLoader :loading="subCategoriesLoading"> | ||
<div v-if="!subCategoriesLoading"> | ||
<SfList v-if="hasChildren"> | ||
<SfListItem | ||
v-for="subCategory in activeCategory[0].children" | ||
:key="subCategory.id" | ||
> | ||
<SfMenuItem | ||
:label="subCategory.name" | ||
@click.native="handleClickCategoryLvl(subCategory.slug, 2)" | ||
> | ||
<SfLink> | ||
{{ subCategory.name }} | ||
</SfLink> | ||
</SfMenuItem> | ||
</SfListItem> | ||
</SfList> | ||
</div> | ||
</SfLoader> | ||
<CatBanners v-if="!subCategoriesLoading && hasBanners" /> | ||
</SfMegaMenuColumn> | ||
</SfMegaMenu> | ||
</transition> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import { SfMegaMenu, SfMenuItem, SfList, SfBanner, SfLoader } from '@storefront-ui/vue'; | ||
import { useCategory } from '@vue-storefront/commercetools'; | ||
import { useUiState } from '~/composables'; | ||
import { onSSR } from '@vue-storefront/core'; | ||
import { ref, computed } from '@vue/composition-api'; | ||
import debounce from 'lodash.debounce'; | ||
|
||
export default { | ||
name: 'HeaderNav', | ||
components: { | ||
SfMegaMenu, | ||
SfMenuItem, | ||
SfList, | ||
SfBanner, | ||
SfLoader, | ||
CatBanners: () => import('./CatBanners') | ||
}, | ||
props: { | ||
isMobile: { | ||
type: Boolean, | ||
default: false | ||
} | ||
}, | ||
setup (_, { emit, root }) { | ||
const { categories, search } = useCategory('menu-categories'); | ||
const { categories: subCategories, search: subCategoriesSearch, loading: subCategoriesLoading } = useCategory('menu-subCategories'); | ||
const { toggleMobileMenu, isMobileMenuOpen } = useUiState(); | ||
const currentCatSlug = ref(''); | ||
const activeCategory = ref(null); | ||
const fetchedSubCategories = ref({}); | ||
const categoriesWithBanners = ref([ | ||
{ slug: 'new' } | ||
]); | ||
|
||
const getCurrentCat = (source, slug) => source.find(src => src.slug === slug); | ||
|
||
const hasChildren = computed(() => activeCategory.value && activeCategory.value[0] && activeCategory.value[0].children); | ||
const hasBanners = computed(() => getCurrentCat(categoriesWithBanners.value, currentCatSlug.value)); | ||
|
||
const fetchSubCategories = async slug => { | ||
await subCategoriesSearch({ slug }); | ||
fetchedSubCategories.value = { | ||
...fetchedSubCategories.value, | ||
[slug]: subCategories.value | ||
}; | ||
}; | ||
|
||
const handleMouseEnter = debounce(async slug => { | ||
currentCatSlug.value = slug; | ||
const { childCount } = getCurrentCat(categories.value, slug); | ||
emit('setOverlay', Boolean(childCount)); | ||
|
||
if (!fetchedSubCategories.value[slug] && Boolean(childCount)) { | ||
await fetchSubCategories(slug); | ||
} | ||
activeCategory.value = fetchedSubCategories.value[slug]; | ||
}, 200); | ||
|
||
const handleMouseLeave = debounce(() => { | ||
emit('setOverlay', false); | ||
currentCatSlug.value = ''; | ||
}, 200); | ||
|
||
const getSubCategories = async (slug, childCount) => { | ||
if (!childCount) { | ||
root.$router.push(`/c/${slug}`); | ||
toggleMobileMenu(); | ||
} | ||
if (!fetchedSubCategories.value[slug]) { | ||
await fetchSubCategories(slug); | ||
} | ||
activeCategory.value = fetchedSubCategories.value[slug]; | ||
}; | ||
|
||
const handleClickCategoryLvl = async (slug, lvl) => { | ||
currentCatSlug.value = slug; | ||
const catElements = lvl === 1 ? categories.value : activeCategory.value[0].children; | ||
const { childCount } = getCurrentCat(catElements, slug); | ||
await getSubCategories(slug, childCount); | ||
}; | ||
|
||
onSSR(async () => { | ||
await search({ customQuery: { categories: 'megamenu-categories-query' } }); | ||
}); | ||
|
||
return { | ||
categories, | ||
activeCategory, | ||
subCategories, | ||
currentCatSlug, | ||
subCategoriesLoading, | ||
handleMouseEnter, | ||
handleMouseLeave, | ||
handleClickCategoryLvl, | ||
hasBanners, | ||
hasChildren, | ||
toggleMobileMenu, | ||
isMobileMenuOpen | ||
}; | ||
} | ||
}; | ||
</script> | ||
|
||
<style lang='scss'> | ||
.sf-mega-menu__bar.sf-bar { | ||
display: flex; | ||
@include for-desktop { | ||
display: none; | ||
} | ||
} | ||
.sf-mega-menu.mobile-menu { | ||
position: absolute; | ||
overflow-y: auto; | ||
top: 0; | ||
z-index: 1; | ||
width: 100%; | ||
--mega-menu-aside-menu-height: calc(100vh - var(--bottom-navigation-height) - var(--bar-height)); | ||
} | ||
.sf-loader__spinner { | ||
margin-bottom: var(--bar-height, 3.125rem); | ||
@include for-mobile { | ||
margin-top: var(--bar-height, 3.125rem); | ||
margin-bottom: 0; | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hardcoded category?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because we don't have any external source of information about the categories in which banners should be visible. Eventually, we can remove banners. WDYT?