@explorer-1/vue 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/components.d.ts +3 -1
  2. package/dist/explorer-1-vue.js +4677 -4526
  3. package/dist/explorer-1-vue.umd.cjs +12 -12
  4. package/dist/src/components/BlockHeading/BlockHeading.vue.d.ts +25 -2
  5. package/dist/src/components/DetailHeadline/DetailHeadline.stories.d.ts +29 -1
  6. package/dist/src/components/DetailHeadline/DetailHeadline.vue.d.ts +26 -0
  7. package/dist/src/components/NavDesktop/NavDesktop.stories.d.ts +3 -0
  8. package/dist/src/components/NavDesktop/NavDesktop.vue.d.ts +1 -0
  9. package/dist/src/components/NavDesktop/NavDesktopDropdown.vue.d.ts +1 -0
  10. package/dist/src/components/NavDesktopEdu/NavDesktopEdu.stories.d.ts +1 -0
  11. package/dist/src/components/NavDropdownToggle/NavDropdownToggle.vue.d.ts +19 -6
  12. package/dist/src/components/NavJumpMenu/NavJumpMenu.stories.d.ts +31 -0
  13. package/dist/src/components/NavMobile/NavMobile.stories.d.ts +30 -3
  14. package/dist/src/components/NavMobile/NavMobile.vue.d.ts +1 -0
  15. package/dist/src/components/NavMobile/NavMobileDropdown.vue.d.ts +9 -1
  16. package/dist/src/components/NavMobile/NavMobileEdu.stories.d.ts +3 -0
  17. package/dist/src/components/NavMobile/NavMobileSecondaryDropdown.vue.d.ts +7 -0
  18. package/dist/src/components/NavSecondary/NavSecondary.stories.d.ts +8 -0
  19. package/dist/src/components/NavSecondary/NavSecondary.vue.d.ts +23 -1
  20. package/dist/src/components/NavSecondary/NavSecondaryDropdown.vue.d.ts +33 -2
  21. package/dist/src/components/NavSecondary/NavSecondaryDropdownContent.vue.d.ts +11 -1
  22. package/dist/src/components/NavSecondary/NavSecondaryLink.vue.d.ts +21 -3
  23. package/dist/src/interfaces.d.ts +7 -1
  24. package/dist/src/store/header.d.ts +2 -0
  25. package/dist/src/templates/edu/{PageEduResourceArticle/PageEduResourceArticle.stories.d.ts → PageEduExplainerArticle/PageEduExplainerArticle.stories.d.ts} +3 -2
  26. package/dist/src/templates/edu/PageEduNewsDetail/PageEduNewsDetail.stories.d.ts +1004 -6
  27. package/dist/src/utils/eventBus.d.ts +1 -0
  28. package/dist/src/utils/getHeadingId.d.ts +1 -0
  29. package/dist/src/utils/mixins.d.ts +1 -1
  30. package/dist/style.css +1 -1
  31. package/package.json +3 -2
  32. package/src/components/BaseAudio/BaseAudio.vue +3 -4
  33. package/src/components/BaseLink/BaseLink.vue +2 -0
  34. package/src/components/BaseTag/BaseTag.vue +4 -4
  35. package/src/components/BlockHeading/BlockHeading.vue +28 -0
  36. package/src/components/BlockStreamfield/BlockStreamfield.vue +5 -1
  37. package/src/components/DetailHeadline/DetailHeadline.stories.js +27 -2
  38. package/src/components/DetailHeadline/DetailHeadline.vue +76 -33
  39. package/src/components/NavDesktop/NavDesktopDropdown.vue +2 -4
  40. package/src/components/NavDropdownToggle/NavDropdownToggle.vue +8 -3
  41. package/src/components/NavJumpMenu/NavJumpMenu.stories.js +47 -0
  42. package/src/components/NavJumpMenu/NavJumpMenu.vue +141 -0
  43. package/src/components/NavJumpMenu/NavJumpMenuContent.vue +74 -0
  44. package/src/components/NavMobile/NavMobile.vue +2 -4
  45. package/src/components/NavMobile/NavMobileDropdown.vue +8 -4
  46. package/src/components/NavMobile/NavMobileSecondaryDropdown.vue +4 -1
  47. package/src/components/NavSecondary/NavSecondary.stories.js +8 -3
  48. package/src/components/NavSecondary/NavSecondary.vue +26 -6
  49. package/src/components/NavSecondary/NavSecondaryDropdown.vue +52 -17
  50. package/src/components/NavSecondary/NavSecondaryDropdownContent.vue +5 -1
  51. package/src/components/NavSecondary/NavSecondaryLink.vue +38 -11
  52. package/src/interfaces.ts +7 -1
  53. package/src/store/header.ts +6 -1
  54. package/src/templates/edu/PageEduEventDetail/PageEduEventDetail.vue +2 -2
  55. package/src/templates/edu/{PageEduResourceArticle/PageEduResourceArticle.stories.js → PageEduExplainerArticle/PageEduExplainerArticle.stories.js} +6 -6
  56. package/src/templates/edu/{PageEduResourceArticle/PageEduResourceArticle.vue → PageEduExplainerArticle/PageEduExplainerArticle.vue} +4 -2
  57. package/src/templates/edu/PageEduNewsDetail/PageEduNewsDetail.stories.js +6 -4
  58. package/src/templates/edu/PageEduNewsDetail/PageEduNewsDetail.vue +16 -2
  59. package/src/utils/eventBus.ts +3 -0
  60. package/src/utils/getHeadingId.ts +5 -0
  61. package/src/utils/mixins.ts +5 -1
@@ -42,6 +42,7 @@
42
42
  </template>
43
43
  <template v-else>
44
44
  <NavMobileLink
45
+ v-if="!headerStore.secondaryNavIsJumpMenu && index !== 0"
45
46
  :key="index"
46
47
  :title="index === 0 ? 'Home' : undefined"
47
48
  :data="item"
@@ -59,7 +60,10 @@
59
60
  <script lang="ts">
60
61
  // @ts-nocheck
61
62
  import { defineComponent } from 'vue'
63
+ import { mapStores } from 'pinia'
64
+ import { useHeaderStore } from '../../store/header'
62
65
  import type { LinkObject } from '../../utils/mixins'
66
+ import { eventBus } from './../../utils/eventBus'
63
67
  import NavDropdownToggle from './../NavDropdownToggle/NavDropdownToggle.vue'
64
68
  import NavMobileLink from './../NavMobile/NavMobileLink.vue'
65
69
  import NavMobileSecondaryDropdown from './../NavMobile/NavMobileSecondaryDropdown.vue'
@@ -98,16 +102,16 @@ export default defineComponent({
98
102
  theDropdown: null
99
103
  }
100
104
  },
105
+ computed: {
106
+ ...mapStores(useHeaderStore)
107
+ },
101
108
  mounted() {
102
109
  if (this.startOpen) {
103
110
  this.dropdownVisible = true
104
111
  }
105
112
  this.theDropdown = this.$refs.NavDropdownMobile as HTMLElement
106
113
  if (!this.expandMultiple) {
107
- // TODO: VUE3: find solution for emitting event from slot
108
- // TODO: find a cleaner way to do this w/o using mounted or root level events
109
- // scoped slots? https://github.com/vuejs/vue/issues/4332
110
- // this.$root?.$on('openMobileDropdown', this.closeIfOtherOpened)
114
+ eventBus.on('openMobileDropdown', () => this.closeIfOtherOpened())
111
115
  }
112
116
  },
113
117
  methods: {
@@ -18,6 +18,7 @@
18
18
  <NavSecondaryDropdownContent
19
19
  class="relative w-full text-lg"
20
20
  :item="item"
21
+ :include-overview="!headerStore.secondaryNavIsJumpMenu"
21
22
  />
22
23
  </slot>
23
24
  </template>
@@ -27,6 +28,8 @@
27
28
  <script lang="ts">
28
29
  import { defineComponent } from 'vue'
29
30
  import { mixinIsActivePath } from '../../utils/mixins'
31
+ import { mapStores } from 'pinia'
32
+ import { useHeaderStore } from '../../store/header'
30
33
  import IconCaret from './../Icons/IconCaret.vue'
31
34
  import NavDropdownToggle from './../NavDropdownToggle/NavDropdownToggle.vue'
32
35
  import NavSecondaryDropdownContent from './../NavSecondary/NavSecondaryDropdownContent.vue'
@@ -58,6 +61,7 @@ export default defineComponent({
58
61
  }
59
62
  },
60
63
  computed: {
64
+ ...mapStores(useHeaderStore),
61
65
  startOpen(): Boolean {
62
66
  if (this.item) {
63
67
  return mixinIsActivePath(this.item.path)
@@ -79,7 +83,6 @@ export default defineComponent({
79
83
  },
80
84
  methods: {
81
85
  toggleDropdown() {
82
- console.log('dropdown toggled')
83
86
  if (this.dropdownVisible) {
84
87
  this.closeDropdown()
85
88
  } else {
@@ -1,7 +1,7 @@
1
1
  import NavSecondary from './NavSecondary.vue'
2
2
 
3
3
  export default {
4
- title: 'Navigation/Secondary Navigation/NavSecondary',
4
+ title: 'Navigation/Secondary Navigation',
5
5
  component: NavSecondary,
6
6
  excludeStories: /.*Data$/,
7
7
  parameters: {
@@ -19,6 +19,11 @@ export const NavSecondaryData = {
19
19
  }
20
20
 
21
21
  export const BaseStory = {
22
- name: 'NavSecondary',
23
- args: { breadcrumb: NavSecondaryData.breadcrumb }
22
+ name: 'Secondary Navigation',
23
+ args: {
24
+ breadcrumb: NavSecondaryData.breadcrumb
25
+ }
26
+ }
27
+ export const Inverted = {
28
+ args: { breadcrumb: NavSecondaryData.breadcrumb, invert: true }
24
29
  }
@@ -4,11 +4,17 @@
4
4
  ref="NavSecondary"
5
5
  aria-label="Secondary"
6
6
  class="NavSecondary"
7
- :class="{ 'has-intro': hasIntro }"
7
+ :class="{
8
+ 'has-intro': hasIntro,
9
+ '!bg-transparent': invert
10
+ }"
8
11
  >
9
- <div class="max-w-screen-3xl mx-auto">
12
+ <div
13
+ class="max-w-screen-3xl mx-auto"
14
+ :class="{ 'bg-gradient-to-r from-black to-primary bg-transparent to-90% text-white': invert }"
15
+ >
10
16
  <div
11
- class="nav-secondary-container lg:container lg:px-0 lg:whitespace-normal border-gray-mid text-gray-mid-dark lg:overflow-visible relative px-4 pb-0 mx-auto overflow-x-auto text-sm font-medium whitespace-nowrap border-t border-opacity-50 edu:border-0"
17
+ :class="`nav-secondary-container lg:container lg:px-0 lg:whitespace-normal lg:overflow-visible relative px-4 pb-0 mx-auto overflow-x-auto text-sm font-medium whitespace-nowrap ${invert ? 'border-0' : 'border-t border-gray-mid text-gray-mid-dark border-opacity-50'}`"
12
18
  >
13
19
  <div class="lg:ml-0 2xl:-mr-3 lg:justify-end flex -ml-3">
14
20
  <template v-for="(item, index) in theBreadcrumb">
@@ -18,6 +24,7 @@
18
24
  :item="item"
19
25
  :index="index"
20
26
  :is-last="theBreadcrumb && index === theBreadcrumb.length - 1"
27
+ :invert="invert"
21
28
  />
22
29
  </template>
23
30
  <template v-else>
@@ -25,6 +32,7 @@
25
32
  :key="index"
26
33
  :item="item"
27
34
  :index="index"
35
+ :invert="invert"
28
36
  />
29
37
  </template>
30
38
  </template>
@@ -38,6 +46,7 @@
38
46
  import { defineComponent } from 'vue'
39
47
  import { mapStores } from 'pinia'
40
48
  import { useHeaderStore } from './../../store/header'
49
+ import { useThemeStore } from './../../store/theme'
41
50
  import NavSecondaryDropdown from './NavSecondaryDropdown.vue'
42
51
  import NavSecondaryLink from './NavSecondaryLink.vue'
43
52
  import { mixinHighlightPrimary, mixinUpdateSecondary } from './../../utils/mixins'
@@ -49,19 +58,27 @@ export default defineComponent({
49
58
  ** If there is no breadcrumb override, then it will fallback to using the breadcrumbs derived form the active global nav item (store.header.globalChildren)
50
59
  ** store.header.secondaryNav reverts to null on route changes, so the breadcrumb override is re-evaluted on every page
51
60
  */
61
+ name: 'NavSecondary',
52
62
  components: {
53
63
  NavSecondaryDropdown,
54
64
  NavSecondaryLink
55
65
  },
56
66
  props: {
67
+ // breadcrumbs create a secondary navigation
57
68
  breadcrumb: {
58
69
  type: String,
59
- required: false
70
+ required: false,
71
+ default: undefined
60
72
  },
61
73
  hasIntro: {
62
74
  type: Boolean,
63
75
  required: false,
64
76
  default: false
77
+ },
78
+ invert: {
79
+ type: Boolean,
80
+ required: false,
81
+ default: false
65
82
  }
66
83
  },
67
84
  data() {
@@ -71,7 +88,8 @@ export default defineComponent({
71
88
  },
72
89
  computed: {
73
90
  ...mapStores(useHeaderStore),
74
- theBreadcrumb(): [BreadcrumbPathObject] | undefined {
91
+ ...mapStores(useThemeStore),
92
+ theBreadcrumb(): BreadcrumbPathObject[] | undefined {
75
93
  if (this.breadcrumb) {
76
94
  // we also want to update the store to override secondary nav
77
95
  mixinUpdateSecondary(JSON.parse(this.breadcrumb))
@@ -118,7 +136,9 @@ export default defineComponent({
118
136
  ([e]) => {
119
137
  e.target.classList.toggle('-is-sticky', e.intersectionRatio < 1)
120
138
  },
121
- { threshold: [1] }
139
+ {
140
+ threshold: [1]
141
+ }
122
142
  )
123
143
  const observerOffset = new IntersectionObserver(
124
144
  ([e]) => {
@@ -10,21 +10,14 @@
10
10
  :aria-expanded="dropdownVisible ? true : false"
11
11
  :path="item.path"
12
12
  class="font-medium border-t-2 border-transparent block px-3 py-2"
13
- :class="{
14
- 'mr-auto text-primary font-semibold secondary-root': index === 0,
15
- 'text-gray-dark': index !== 0,
16
- '-open': dropdownVisible
17
- }"
13
+ :class="dropdownToggleClasses(index)"
14
+ :invert="invert"
18
15
  @toggle-clicked="toggleDropdown()"
19
16
  @close-dropdown="closeDropdown()"
20
17
  >
21
18
  <span
22
19
  class="flex content-center pt-2 pb-1 mb-1 transition-colors duration-100 ease-in border-b-2 border-transparent"
23
- :class="
24
- index === 0
25
- ? 'can-hover:group-hover:border-primary'
26
- : 'can-hover:group-hover:border-gray-mid-dark can-hover:group-hover:text-gray-mid-dark '
27
- "
20
+ :class="dropdownButtonClasses(index)"
28
21
  >
29
22
  <span>{{ item.title }}</span>
30
23
  <IconCaret class="transform rotate-90 text-sm ml-2 pl-2 -mt-px" />
@@ -47,6 +40,7 @@
47
40
 
48
41
  <script lang="ts">
49
42
  import { defineComponent } from 'vue'
43
+ import { eventBus } from './../../utils/eventBus'
50
44
  import IconCaret from './../Icons/IconCaret.vue'
51
45
  import NavDropdownToggle from './../NavDropdownToggle/NavDropdownToggle.vue'
52
46
  import NavSecondaryDropdownContent from './../NavSecondary/NavSecondaryDropdownContent.vue'
@@ -62,7 +56,8 @@ export default defineComponent({
62
56
  // the index from the parent v-for loop
63
57
  index: {
64
58
  type: Number,
65
- required: false
59
+ required: false,
60
+ default: 0
66
61
  },
67
62
  isLast: {
68
63
  type: Boolean,
@@ -73,8 +68,15 @@ export default defineComponent({
73
68
  item: {
74
69
  type: Object,
75
70
  required: true
71
+ },
72
+
73
+ invert: {
74
+ type: Boolean,
75
+ required: false,
76
+ default: false
76
77
  }
77
78
  },
79
+ emits: ['closeDropdown', 'openDropdown'],
78
80
  data() {
79
81
  return {
80
82
  dropdownVisible: false
@@ -88,15 +90,10 @@ export default defineComponent({
88
90
  }
89
91
  },
90
92
  mounted() {
91
- // TODO: VUE3: find solution for emitting event from slot
92
- // https://stackoverflow.com/questions/50181858/this-root-emit-not-working-in-vue
93
- // TODO: find a cleaner way to do this w/o using mounted or root level events
94
- // scoped slots? https://github.com/vuejs/vue/issues/4332
95
- // this.$root?.$on('linkClicked', this.closeDropdown)
93
+ eventBus.on('linkClicked', () => this.closeDropdown())
96
94
  },
97
95
  methods: {
98
96
  toggleDropdown() {
99
- console.log('dropdown toggled')
100
97
  if (this.dropdownVisible) {
101
98
  this.closeDropdown()
102
99
  } else {
@@ -120,6 +117,28 @@ export default defineComponent({
120
117
  return true
121
118
  }
122
119
  return false
120
+ },
121
+ dropdownToggleClasses(index: number) {
122
+ return this.invert
123
+ ? {
124
+ 'mr-auto text-white font-semibold secondary-root': index === 0,
125
+ 'text-white': index !== 0,
126
+ '-open': this.dropdownVisible
127
+ }
128
+ : {
129
+ 'mr-auto text-primary font-semibold secondary-root': index === 0,
130
+ 'text-gray-dark': index !== 0,
131
+ '-open': this.dropdownVisible
132
+ }
133
+ },
134
+ dropdownButtonClasses(index: number) {
135
+ const titleButton = this.invert
136
+ ? 'can-hover:group-hover:border-white'
137
+ : 'can-hover:group-hover:border-primary'
138
+ const regularButton = this.invert
139
+ ? 'can-hover:group-hover:border-white can-hover:group-hover:text-white'
140
+ : 'can-hover:group-hover:border-gray-mid-dark can-hover:group-hover:text-gray-mid-dark'
141
+ return index === 0 ? titleButton : regularButton
123
142
  }
124
143
  }
125
144
  })
@@ -131,6 +150,11 @@ export default defineComponent({
131
150
  > span {
132
151
  @apply border-black text-gray-dark #{!important};
133
152
  }
153
+ &.-invert {
154
+ > span {
155
+ @apply border-white text-white #{!important};
156
+ }
157
+ }
134
158
  }
135
159
 
136
160
  &.-active {
@@ -138,12 +162,23 @@ export default defineComponent({
138
162
  @apply font-bold text-gray-dark;
139
163
  @apply border-primary #{!important};
140
164
  }
165
+ &.-invert {
166
+ > span {
167
+ @apply text-white;
168
+ @apply border-white #{!important};
169
+ }
170
+ }
141
171
  }
142
172
  &:hover {
143
173
  &.-active {
144
174
  > span {
145
175
  @apply text-gray-mid-dark;
146
176
  }
177
+ &.-invert {
178
+ > span {
179
+ @apply text-white;
180
+ }
181
+ }
147
182
  }
148
183
  }
149
184
  }
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <ul class="NavSecondaryDropdownContent">
3
- <li>
3
+ <li v-if="includeOverview">
4
4
  <BaseLink
5
5
  :to="item.path"
6
6
  variant="none"
@@ -80,6 +80,10 @@ export default defineComponent({
80
80
  item: {
81
81
  type: Object,
82
82
  required: true
83
+ },
84
+ includeOverview: {
85
+ type: Boolean,
86
+ default: true
83
87
  }
84
88
  },
85
89
  methods: {
@@ -1,19 +1,15 @@
1
1
  <template>
2
2
  <BaseLink
3
- :href="isExternal(item.path) ? item.path : null"
4
- :to="!isExternal(item.path) ? item.path : null"
3
+ :href="isExternal(item.path) ? item.path : undefined"
4
+ :to="!isExternal(item.path) ? item.path : undefined"
5
5
  link-class="block px-3 py-2"
6
6
  variant="none"
7
7
  class="NavSecondaryLink border-t-2 border-transparent"
8
- :class="index === 0 ? 'mr-auto text-primary font-semibold secondary-root' : 'text-gray-dark'"
8
+ :class="baseLinkClasses(index)"
9
9
  >
10
10
  <span
11
11
  class="inline-block pt-2 pb-1 mb-1 transition-colors duration-100 ease-in border-b-2 border-transparent"
12
- :class="
13
- index === 0
14
- ? 'can-hover:group-hover:border-primary'
15
- : 'can-hover:group-hover:border-gray-mid-dark can-hover:group-hover:text-gray-mid-dark '
16
- "
12
+ :class="spanClasses(index)"
17
13
  >
18
14
  {{ item.title }}
19
15
  </span>
@@ -21,7 +17,8 @@
21
17
  </template>
22
18
 
23
19
  <script lang="ts">
24
- import { defineComponent } from 'vue'
20
+ import { defineComponent, type PropType } from 'vue'
21
+ import type { BasicLinkObject } from './../../interfaces'
25
22
  import BaseLink from './../BaseLink/BaseLink.vue'
26
23
  export default defineComponent({
27
24
  name: 'NavSecondaryLink',
@@ -32,12 +29,17 @@ export default defineComponent({
32
29
  // the index from the v-for loop
33
30
  index: {
34
31
  type: Number,
35
- required: false
32
+ required: false,
33
+ default: undefined
36
34
  },
37
35
  // the nav item object that includes path and title
38
36
  item: {
39
- type: Object,
37
+ type: Object as PropType<BasicLinkObject>,
40
38
  required: true
39
+ },
40
+ invert: {
41
+ type: Boolean,
42
+ default: false
41
43
  }
42
44
  },
43
45
  methods: {
@@ -46,6 +48,23 @@ export default defineComponent({
46
48
  return true
47
49
  }
48
50
  return false
51
+ },
52
+ baseLinkClasses(index: number | undefined) {
53
+ let rootClasses = 'mr-auto font-semibold secondary-root'
54
+ rootClasses = this.invert
55
+ ? `${rootClasses} text-white -invert`
56
+ : `${rootClasses} text-primary`
57
+ const regularClasses = this.invert ? 'text-white -invert' : 'text-gray-dark'
58
+ return index === 0 ? rootClasses : regularClasses
59
+ },
60
+ spanClasses(index: number | undefined) {
61
+ const rootClasses = this.invert
62
+ ? 'can-hover:group-hover:border-white'
63
+ : 'can-hover:group-hover:border-primary'
64
+ const regularClasses = this.invert
65
+ ? 'can-hover:group-hover:border-white can-hover:group-hover:text-white'
66
+ : 'can-hover:group-hover:border-gray-mid-dark can-hover:group-hover:text-gray-mid-dark'
67
+ return index === 0 ? rootClasses : regularClasses
49
68
  }
50
69
  }
51
70
  })
@@ -58,5 +77,13 @@ export default defineComponent({
58
77
  @apply border-primary #{!important};
59
78
  }
60
79
  }
80
+ &.-invert {
81
+ .nuxt-link-exact-active {
82
+ span {
83
+ @apply font-bold text-white;
84
+ @apply border-white #{!important};
85
+ }
86
+ }
87
+ }
61
88
  }
62
89
  </style>
package/src/interfaces.ts CHANGED
@@ -1,12 +1,18 @@
1
1
  export interface BreadcrumbPathObject {
2
2
  path: string
3
3
  title: string
4
- children: any[]
4
+ children: BreadcrumbPathObject[]
5
+ }
6
+ export interface BasicLinkObject {
7
+ title: string
8
+ path: string
5
9
  }
6
10
 
7
11
  export interface BlockData {
8
12
  blockType: string
9
13
  field?: string
14
+ heading?: string
15
+ level?: string
10
16
  items?: any[]
11
17
  }
12
18
  export interface ImageSrcObject {
@@ -11,6 +11,7 @@ export interface State {
11
11
  highlightPrimary: boolean
12
12
  globalChildren?: any | null
13
13
  secondaryNav?: any | null
14
+ secondaryNavIsJumpMenu: boolean
14
15
  }
15
16
 
16
17
  export const useHeaderStore = defineStore('header', {
@@ -19,7 +20,8 @@ export const useHeaderStore = defineStore('header', {
19
20
  headerTransparent: false,
20
21
  highlightPrimary: true,
21
22
  globalChildren: null,
22
- secondaryNav: null
23
+ secondaryNav: null,
24
+ secondaryNavIsJumpMenu: false
23
25
  }
24
26
  },
25
27
  actions: {
@@ -35,6 +37,9 @@ export const useHeaderStore = defineStore('header', {
35
37
  },
36
38
  updateSecondary(value: any) {
37
39
  this.secondaryNav = value
40
+ },
41
+ updateSecondaryNavIsJumpMenu(value: boolean) {
42
+ this.secondaryNavIsJumpMenu = value
38
43
  }
39
44
  }
40
45
  })
@@ -32,11 +32,11 @@
32
32
  >
33
33
  <div
34
34
  v-if="data.eventType"
35
- class="flex flex-wrap items-start mb-3"
35
+ class="flex flex-wrap items-start mb-4"
36
36
  >
37
37
  <BaseTag
38
38
  variant="primary"
39
- size="md"
39
+ size="lg"
40
40
  >
41
41
  {{ data.eventType }}
42
42
  </BaseTag>
@@ -8,11 +8,11 @@ import { BlockVideoEmbedData } from './../../../components/BlockVideoEmbed/Block
8
8
  import { BlockRelatedLinksData } from './../../../components/BlockRelatedLinks/BlockRelatedLinks.stories.js'
9
9
  import { BlockLinkCardCarouselData } from './../../../components/BlockLinkCarousel/BlockLinkCarousel.stories.js'
10
10
  import { BlockStreamfieldTruncatedData } from './../../../components/BlockStreamfield/BlockStreamfield.stories'
11
- import PageEduResourceArticle from './PageEduResourceArticle.vue'
11
+ import PageEduExplainerArticle from './PageEduExplainerArticle.vue'
12
12
 
13
13
  export default {
14
- title: 'Templates/EDU/PageEduResourceArticle',
15
- component: PageEduResourceArticle,
14
+ title: 'Templates/EDU/PageEduExplainerArticle',
15
+ component: PageEduExplainerArticle,
16
16
  decorators: [
17
17
  () => ({
18
18
  template: `<div id="storyDecorator" class="disable-nav-offset"><story/></div>`
@@ -30,9 +30,9 @@ export default {
30
30
  export const BaseStory = {
31
31
  args: {
32
32
  data: {
33
- __typename: 'EDUResourceArticlePage',
34
- pageType: 'EDUResourceArticlePage',
35
- contentType: 'edu_resources.EDUResourceArticlePage',
33
+ __typename: 'EDUExplainerArticlePage',
34
+ pageType: 'EDUExplainerArticlePage',
35
+ contentType: 'edu_resources.EDUExplainerArticlePage',
36
36
  seoTitle: 'Test Resource',
37
37
  searchDescription: '',
38
38
  slug: 'test-resource',
@@ -14,7 +14,7 @@ import BlockIframeEmbed from '../../../components/BlockIframeEmbed/BlockIframeEm
14
14
  import BlockRelatedLinks from '../../../components/BlockRelatedLinks/BlockRelatedLinks.vue'
15
15
 
16
16
  export default defineComponent({
17
- name: 'PageEduResourceArticle',
17
+ name: 'PageEduExplainerArticle',
18
18
  components: {
19
19
  HeroMedia,
20
20
  BaseImagePlaceholder,
@@ -107,8 +107,10 @@ export default defineComponent({
107
107
  :publication-date="data.publicationDate"
108
108
  :publication-time="data.publicationTime"
109
109
  :author="data.author"
110
- :label="data.displayLabel"
110
+ label="Explainer Article"
111
+ pill-color="secondary"
111
112
  schema
113
+ pill
112
114
  />
113
115
  <ShareButtonsEdu
114
116
  v-if="data?.url"
@@ -1,5 +1,5 @@
1
1
  import { HeroMediaData } from './../../../components/HeroMedia/HeroMedia.stories'
2
- import { BlockStreamfieldTruncatedData } from './../../../components/BlockStreamfield/BlockStreamfield.stories'
2
+ import { BlockStreamfieldData } from './../../../components/BlockStreamfield/BlockStreamfield.stories'
3
3
  import PageEduNewsDetail from './PageEduNewsDetail.vue'
4
4
 
5
5
  export default {
@@ -56,7 +56,7 @@ export const BaseStory = {
56
56
  heroPosition: 'full_bleed',
57
57
  heroImage: HeroMediaData.image,
58
58
  heroImageInline: HeroMediaData.imageInline,
59
- ...BlockStreamfieldTruncatedData
59
+ ...BlockStreamfieldData
60
60
  }
61
61
  }
62
62
  }
@@ -65,7 +65,8 @@ export const InlineHero = {
65
65
  args: {
66
66
  data: {
67
67
  ...BaseStory.args.data,
68
- heroPosition: 'inline'
68
+ heroPosition: 'inline',
69
+ showJumpMenu: true
69
70
  }
70
71
  }
71
72
  }
@@ -74,7 +75,8 @@ export const NoHero = {
74
75
  args: {
75
76
  data: {
76
77
  ...BaseStory.args.data,
77
- hero: []
78
+ hero: [],
79
+ showJumpMenu: true
78
80
  }
79
81
  }
80
82
  }
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed } from 'vue'
2
+ import { computed, ref, defineExpose } from 'vue'
3
3
  import isEmpty from 'lodash/isEmpty.js'
4
4
  import type { StreamfieldBlockData } from './../../../components/BlockStreamfield/BlockStreamfield.vue'
5
5
  import type {
@@ -17,6 +17,7 @@ import ShareButtonsEdu from './../../../components/ShareButtonsEdu/ShareButtonsE
17
17
  import BlockImageStandard from './../../../components/BlockImage/BlockImageStandard.vue'
18
18
  import BlockText from './../../../components/BlockText/BlockText.vue'
19
19
  import BlockStreamfield from './../../../components/BlockStreamfield/BlockStreamfield.vue'
20
+ import NavJumpMenu from './../../../components/NavJumpMenu/NavJumpMenu.vue'
20
21
 
21
22
  interface PageEduNewsDetailObject extends PageResponseObject {
22
23
  readTime: string
@@ -35,6 +36,7 @@ interface PageEduNewsDetailObject extends PageResponseObject {
35
36
  topper: string
36
37
  relatedLinks: RelatedLinkObject[]
37
38
  body: StreamfieldBlockData[]
39
+ showJumpMenu: boolean
38
40
  }
39
41
 
40
42
  interface PageEduNewsDetailProps {
@@ -44,6 +46,8 @@ interface PageEduNewsDetailProps {
44
46
  // define props
45
47
  const props = defineProps<PageEduNewsDetailProps>()
46
48
 
49
+ const PageEduNewsDetailJumpMenu = ref()
50
+
47
51
  const heroEmpty = computed(() => {
48
52
  return isEmpty(props.data?.heroImage)
49
53
  })
@@ -67,6 +71,10 @@ const computedClass = computed(() => {
67
71
  const dateTimeArray = computed(() => {
68
72
  return props.data.publicationDate.split(' ')
69
73
  })
74
+
75
+ defineExpose({
76
+ PageEduNewsDetailJumpMenu
77
+ })
70
78
  </script>
71
79
  <template>
72
80
  <div
@@ -76,6 +84,13 @@ const dateTimeArray = computed(() => {
76
84
  itemscope
77
85
  itemtype="http://schema.org/Article"
78
86
  >
87
+ <NavJumpMenu
88
+ ref="PageEduNewsDetailJumpMenu"
89
+ :title="data.title"
90
+ :blocks="data.body"
91
+ :enabled="true"
92
+ />
93
+
79
94
  <!-- schema.org -->
80
95
  <meta
81
96
  v-if="data.thumbnailImage && data.thumbnailImage.original"
@@ -147,7 +162,6 @@ const dateTimeArray = computed(() => {
147
162
  {{ data.summary }}
148
163
  </p>
149
164
  </LayoutHelper>
150
-
151
165
  <!-- streamfield blocks -->
152
166
  <BlockStreamfield
153
167
  itemprop="articleBody"
@@ -0,0 +1,3 @@
1
+ import mitt from 'mitt'
2
+
3
+ export const eventBus = mitt()
@@ -0,0 +1,5 @@
1
+ import { camelCase } from 'lodash'
2
+
3
+ export const getHeadingId = (heading: string, index?: number) => {
4
+ return camelCase(heading + (index ? index : ''))
5
+ }
@@ -123,9 +123,13 @@ export const mixinUpdateGlobalChildren = (value: [BreadcrumbPathObject] | null)
123
123
  /* -- mixinUpdateSecondary --
124
124
  This mixin is used by the navigation to share secondary nav override items between components
125
125
  */
126
- export const mixinUpdateSecondary = (value: [BreadcrumbPathObject] | null) => {
126
+ export const mixinUpdateSecondary = (
127
+ value: BreadcrumbPathObject[] | undefined,
128
+ isJumpMenu: boolean = false
129
+ ) => {
127
130
  const headerStore = useHeaderStore()
128
131
  headerStore.updateSecondary(value)
132
+ headerStore.updateSecondaryNavIsJumpMenu(isJumpMenu)
129
133
  }
130
134
  /* -- mixinHighlightPrimary --
131
135
  This mixin is used to specify if active primary navigation items should be highlighted/underlined