Skip to content

Commit

Permalink
feature: jump menus (#533)
Browse files Browse the repository at this point in the history
* adding JumpMenu component

* fixing links in jump menu

* adding eventBus

* adding show/hide effects to jump menu

* finishing mobile jump menu

* fixing vue-build errors
  • Loading branch information
stephiescastle authored Aug 7, 2024
1 parent 5490398 commit e143636
Show file tree
Hide file tree
Showing 29 changed files with 534 additions and 72 deletions.
27 changes: 24 additions & 3 deletions apps/vue-storybook/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport'
import useMockComponents from './_mock-components.js'
import { setup, type Preview } from '@storybook/vue3'
import { createRouter, createWebHashHistory, type RouterOptions } from 'vue-router'
import { Swiper, SwiperSlide } from 'swiper/vue'
import vClickOutside from 'click-outside-vue3'
import VueCompareImage from 'vue3-compare-image'
Expand All @@ -13,9 +14,28 @@ import customTheme from '@explorer-1/common-storybook/src/config/customTheme'
import '@explorer-1/common-storybook/src/config/canvas.css'

const pinia = createPinia()

const router = createRouter({
routes: [],
history: createWebHashHistory(),
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
el: to.hash,
behavior: 'smooth'
}
}
if (savedPosition) {
return savedPosition
} else {
return {
top: 0
}
}
}
} as RouterOptions)
setup((app, _context) => {
app.use(pinia)
app.use(router)
app.use(vClickOutside)
app.use(VueCompareImage)
app.component('Swiper', Swiper)
Expand Down Expand Up @@ -122,7 +142,8 @@ const preview: Preview = {
['Overview', 'WWW'],
'Footers',
['Overview', 'WWW'],
'Secondary Navigation'
'Secondary Navigation',
'Jump Menu'
],
'Global Layout',
[
Expand All @@ -149,7 +170,7 @@ const preview: Preview = {
'Cards',
['Overview', 'BlockLinkCard', 'BlockLinkTile', 'BlockCircleImageCard'],
'Blocks',
['Overview', 'Heroes', ['Overview', 'Small', 'Medium', 'Large']],
['BlockStreamfield'],
'Heroes',
['Overview', 'Small', 'Medium', 'Large', 'Media Only', 'HeroListingIndex'],
'Forms',
Expand Down
1 change: 1 addition & 0 deletions apps/vue-storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@tailwindcss/forms": "^0.5.7",
"click-outside-vue3": "^4.0.1",
"dayjs": "^1.11.11",
"mitt": "^3.0.1",
"swiper": "^11.1.3",
"vue": "^3.2.47",
"vue3-compare-image": "^1.2.5"
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/scss/components/_BlockKeyPoints.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.BlockKeyPoints {
ul li {
&::before {
@apply bg-jpl-red;
@apply bg-primary;
@apply inline-block;
@apply relative;
@apply mr-4;
Expand Down
1 change: 1 addition & 0 deletions packages/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"dayjs": "^1.11.11",
"fast-qs": "^2.0.3",
"lodash": "^4.17.21",
"mitt": "^3.0.1",
"sass": "^1.77.4",
"swiper": "^11.1.3",
"tailwindcss": "^3.4.3",
Expand Down
7 changes: 3 additions & 4 deletions packages/vue/src/components/BaseAudio/BaseAudio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue'
// import { eventBus } from './../../utils/eventBus'
import IconPlay from './../Icons/IconPlay.vue'
import IconPause from './../Icons/IconPause.vue'
import IconVolume from './../Icons/IconVolume.vue'
Expand Down Expand Up @@ -326,10 +327,8 @@ export default defineComponent({
this.audio.addEventListener('play', this._handlePlayPause)
this.audio.addEventListener('ended', this._handleEnded)
}
// TODO: VUE3: find solution for emitting event from slot
// TODO: find a cleaner way to do this w/o using mounted or root level events
// scoped slots? https://github.com/vuejs/vue/issues/4332
// this.$root?.$on('play', this.pauseOthers)
// TODO: VUE3: pass uuID to pauseOthers() method
// eventBus.on('play', () => this.pauseOthers())
},
getAudio() {
return this.$el.querySelectorAll('audio')[0]
Expand Down
2 changes: 2 additions & 0 deletions packages/vue/src/components/BaseLink/BaseLink.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { defineComponent } from 'vue'
import { eventBus } from './../../utils/eventBus'
import MixinAnimationCaret from './../MixinAnimationCaret/MixinAnimationCaret.vue'
interface Variants {
Expand Down Expand Up @@ -145,6 +146,7 @@ export default defineComponent({
clickEvent() {
this.$root?.$emit('linkClicked')
this.$emit('specificLinkClicked')
eventBus.emit('linkClicked')
}
}
})
Expand Down
28 changes: 28 additions & 0 deletions packages/vue/src/components/BlockHeading/BlockHeading.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
<template>
<BaseHeading
v-if="data"
:id="getId"
:level="data.level"
class="BlockHeading"
:class="{ 'has-anchor': generateId }"
>
{{ data.heading }}
</BaseHeading>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { getHeadingId } from '../../utils/getHeadingId'
import BaseHeading from './../BaseHeading/BaseHeading.vue'
export default defineComponent({
Expand All @@ -20,7 +24,31 @@ export default defineComponent({
data: {
type: Object,
required: false
},
index: {
type: Number,
required: false,
default: undefined
},
generateId: {
type: Boolean,
default: false
}
},
computed: {
getId() {
return this.generateId ? getHeadingId(this.data?.heading, this.index) : undefined
}
}
})
</script>
<style lang="scss">
.BlockHeading {
&:target {
@apply scroll-mt-14;
@screen lg {
@apply scroll-mt-20;
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
indent="col-3"
class="mb-5"
>
<BlockHeading :data="block" />
<BlockHeading
:data="block"
:index="index"
generate-id
/>
</LayoutHelper>

<!-- custom margin bottom that matches BlockText styles if followed by InlineImageBlock -->
Expand Down
6 changes: 2 additions & 4 deletions packages/vue/src/components/NavDesktop/NavDesktopDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

<script lang="ts">
import { defineComponent } from 'vue'
import { eventBus } from './../../utils/eventBus'
import { mapStores } from 'pinia'
import { useHeaderStore } from './../../store/header'
import NavDropdownToggle from './../NavDropdownToggle/NavDropdownToggle.vue'
Expand Down Expand Up @@ -80,10 +81,7 @@ export default defineComponent({
}
},
mounted() {
// TODO: VUE3: find solution for emitting event from slot
// TODO: find a cleaner way to do this w/o using mounted or root level events
// scoped slots? https://github.com/vuejs/vue/issues/4332
// this.$root?.$on('linkClicked', this.closeDropdown)
eventBus.on('linkClicked', () => this.closeDropdown())
},
methods: {
toggleDropdown() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<button
class="NavDropdownToggle group cursor-pointer"
:class="{ '-active': isActivePath }"
:class="{ '-active': isActivePath, '-invert': invert }"
:aria-expanded="ariaExpanded"
@click="clickEvent()"
@keydown.esc="escEvent()"
Expand All @@ -26,13 +26,18 @@ export default defineComponent({
props: {
path: {
type: String,
required: false
default: undefined
},
ariaExpanded: {
type: Boolean,
required: false
default: false
},
invert: {
type: Boolean,
default: false
}
},
emits: ['closeDropdown', 'toggleClicked'],
computed: {
isActivePath() {
if (this.path) {
Expand Down
47 changes: 47 additions & 0 deletions packages/vue/src/components/NavJumpMenu/NavJumpMenu.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import NavJumpMenu from './NavJumpMenu.vue'

export default {
title: 'Navigation/Jump Menu',
component: NavJumpMenu,
tags: ['!autodocs'],
excludeStories: /.*Data$/
}

const JumpLinksData = [
{
title: 'Heading title',
path: '#heading_title'
},
{
title: 'Heading title',
path: '#heading_title'
},
{
title: 'Heading title',
path: '#heading_title'
},
{
title: 'Heading title',
path: '#heading_title'
},
{
title: 'Heading title',
path: '#heading_title'
}
]
export const BaseStory = {
name: 'Jump Menu',
args: {
title: 'Page Title',
jumpLinks: JumpLinksData,
invert: true
}
}

export const Light = {
args: {
title: 'Page Title',
jumpLinks: JumpLinksData,
invert: false
}
}
Loading

0 comments on commit e143636

Please sign in to comment.