@explorer-1/vue 0.2.14 → 0.2.16

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 (80) hide show
  1. package/components.d.ts +7 -0
  2. package/dist/explorer-1-vue.js +2415 -2405
  3. package/dist/explorer-1-vue.umd.cjs +12 -12
  4. package/dist/src/components/BaseAccordionItem/BaseAccordionItem.stories.d.ts +99 -0
  5. package/dist/src/components/BaseButton/BaseButton.stories.d.ts +13 -0
  6. package/dist/src/components/BaseButton/BaseButton.vue.d.ts +15 -1
  7. package/dist/src/components/BaseImage/BaseImage.vue.d.ts +1 -1
  8. package/dist/src/components/BaseImagePlaceholder/BaseImagePlaceholder.vue.d.ts +1 -1
  9. package/dist/src/components/BaseLink/BaseLink.vue.d.ts +1 -1
  10. package/dist/src/components/BaseModal/BaseModal.stories.d.ts +26 -0
  11. package/dist/src/components/BaseSwimlane/BaseSwimlane.vue.d.ts +2 -2
  12. package/dist/src/components/BaseTimer/BaseTimer.vue.d.ts +2 -2
  13. package/dist/src/components/BlockAccordion/BlockAccordion.stories.d.ts +98 -0
  14. package/dist/src/components/BlockHeading/BlockHeading.stories.d.ts +1 -0
  15. package/dist/src/components/BlockHeading/BlockHeading.vue.d.ts +13 -11
  16. package/dist/src/components/BlockLinkCard/BlockLinkCard.vue.d.ts +1 -1
  17. package/dist/src/components/BlockLinkCarousel/BlockLinkCarousel.vue.d.ts +1 -1
  18. package/dist/src/components/BlockRelatedLinks/RelatedLink.vue.d.ts +1 -1
  19. package/dist/src/components/BlockStreamfield/BlockStreamfield.stories.d.ts +75 -40
  20. package/dist/src/components/BlockStreamfield/BlockStreamfield.vue.d.ts +2 -19
  21. package/dist/src/components/BlockText/BlockText.vue.d.ts +1 -1
  22. package/dist/src/components/HeroMedia/HeroMedia.vue.d.ts +7 -0
  23. package/dist/src/components/LayoutHelper/LayoutHelper.vue.d.ts +1 -1
  24. package/dist/src/components/MetaPanel/MetaPanel.stories.d.ts +51 -0
  25. package/dist/src/components/MetaPanelItems/MetaPanelItems.stories.d.ts +25 -0
  26. package/dist/src/components/MetadataEduResource/MetadataEduResource.stories.d.ts +1 -1
  27. package/dist/src/components/MixinCarousel/MixinCarousel.vue.d.ts +2 -2
  28. package/dist/src/components/NavSecondary/NavSecondary.vue.d.ts +4 -0
  29. package/dist/src/interfaces.d.ts +84 -7
  30. package/dist/src/templates/PageContent/PageContent.stories.d.ts +6 -5
  31. package/dist/src/templates/PageImageDetail/PageImageDetail.stories.d.ts +43 -16
  32. package/dist/src/templates/PageNewsDetail/PageNewsDetail.stories.d.ts +344 -128
  33. package/dist/src/templates/edu/PageEduExplainerArticle/PageEduExplainerArticle.stories.d.ts +44 -16
  34. package/dist/src/templates/edu/PageEduLesson/PageEduLesson.stories.d.ts +544 -0
  35. package/dist/src/templates/edu/PageEduNewsDetail/PageEduNewsDetail.stories.d.ts +67 -63
  36. package/dist/src/templates/www/PageAsteroidWatchIndex/PageAsteroidWatchIndex.stories.d.ts +22 -21
  37. package/dist/src/templates/www/PageCuratedGallery/PageCuratedGallery.stories.d.ts +43 -16
  38. package/dist/src/templates/www/PageRoboticsDetail/PageRoboticsDetail.stories.d.ts +43 -16
  39. package/dist/src/utils/getHeadingId.d.ts +3 -1
  40. package/dist/style.css +1 -1
  41. package/package.json +3 -2
  42. package/src/components/BaseAccordionItem/BaseAccordionItem.stories.js +15 -0
  43. package/src/components/BaseAccordionItem/BaseAccordionItem.vue +108 -0
  44. package/src/components/BaseButton/BaseButton.vue +12 -1
  45. package/src/components/BaseImage/BaseImage.vue +1 -1
  46. package/src/components/BaseImagePlaceholder/BaseImagePlaceholder.vue +1 -1
  47. package/src/components/BaseLink/BaseLink.vue +1 -1
  48. package/src/components/BaseTimer/BaseTimer.vue +6 -3
  49. package/src/components/BlockAccordion/BlockAccordion.stories.js +29 -0
  50. package/src/components/BlockAccordion/BlockAccordion.vue +32 -0
  51. package/src/components/BlockHeading/BlockHeading.stories.js +2 -2
  52. package/src/components/BlockHeading/BlockHeading.vue +15 -7
  53. package/src/components/BlockLinkCarousel/BlockLinkCarousel.vue +1 -1
  54. package/src/components/BlockRelatedLinks/RelatedLink.vue +1 -1
  55. package/src/components/BlockStreamfield/BlockStreamfield.stories.js +23 -5
  56. package/src/components/BlockStreamfield/BlockStreamfield.vue +8 -26
  57. package/src/components/BlockText/BlockText.vue +1 -1
  58. package/src/components/HeroMedia/HeroMedia.vue +10 -1
  59. package/src/components/LayoutHelper/LayoutHelper.vue +1 -1
  60. package/src/components/MetaPanel/MetaPanel.stories.js +112 -0
  61. package/src/components/MetaPanel/MetaPanel.vue +237 -0
  62. package/src/components/MetaPanelAccordion/MetaPanelAccordion.vue +64 -0
  63. package/src/components/MetaPanelItems/MetaPanelItems.stories.js +27 -0
  64. package/src/components/MetaPanelItems/MetaPanelItems.vue +186 -0
  65. package/src/components/MetadataEduResource/MetadataEduResource.stories.js +2 -4
  66. package/src/components/MixinCarousel/MixinCarousel.vue +2 -2
  67. package/src/components/NavJumpMenu/NavJumpMenu.vue +10 -8
  68. package/src/components/NavSecondary/NavSecondary.vue +26 -15
  69. package/src/components/ShareButtonsEdu/ShareButtonsEdu.vue +1 -1
  70. package/src/interfaces.ts +91 -8
  71. package/src/main.ts +2 -0
  72. package/src/templates/edu/PageEduExplainerArticle/PageEduExplainerArticle.stories.js +1 -0
  73. package/src/templates/edu/PageEduExplainerArticle/PageEduExplainerArticle.vue +10 -1
  74. package/src/templates/edu/PageEduLesson/PageEduLesson.stories.js +303 -0
  75. package/src/templates/edu/PageEduLesson/PageEduLesson.vue +410 -0
  76. package/src/templates/edu/PageEduLesson/PageEduLessonSection.vue +98 -0
  77. package/src/templates/edu/PageEduNewsDetail/PageEduNewsDetail.stories.js +1 -0
  78. package/src/templates/edu/PageEduNewsDetail/PageEduNewsDetail.vue +4 -21
  79. package/src/utils/dayjs.js +0 -6
  80. package/src/utils/getHeadingId.ts +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@explorer-1/vue",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -27,9 +27,10 @@
27
27
  "tailwindcss": "^3.4.3",
28
28
  "twitter-widgets": "^2.0.0",
29
29
  "vue": "^3.4.21",
30
+ "vue-bind-once": "^0.2.1",
30
31
  "vue-observe-visibility": "^1.0.0",
31
32
  "vue3-compare-image": "^1.2.5",
32
- "@explorer-1/common": "1.1.4"
33
+ "@explorer-1/common": "1.1.5"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@vitejs/plugin-vue": "^5.0.4",
@@ -0,0 +1,15 @@
1
+ import BaseAccordionItem from './BaseAccordionItem.vue'
2
+ import { BlockStreamfieldTruncatedData } from '../BlockStreamfield/BlockStreamfield.stories'
3
+ export default {
4
+ title: 'Components/Base/BaseAccordionItem',
5
+ component: BaseAccordionItem
6
+ }
7
+
8
+ // stories
9
+ export const BaseStory = {
10
+ name: 'BaseAccordionItem',
11
+ args: {
12
+ headingLevel: 'h3',
13
+ item: { title: 'Title for the accordion', body: BlockStreamfieldTruncatedData.body }
14
+ }
15
+ }
@@ -0,0 +1,108 @@
1
+ <script setup lang="ts">
2
+ import { computed, reactive, ref } from 'vue'
3
+ import { AccordionItemObject } from './../../interfaces.ts'
4
+ import { uniqueId } from 'lodash'
5
+ import IconPlus from './../Icons/IconPlus.vue'
6
+ import BlockStreamfield from './../BlockStreamfield/BlockStreamfield.vue'
7
+
8
+ export interface BaseAccordionItemProps {
9
+ headingLevel?: string
10
+ item: AccordionItemObject
11
+ backgroundClass?: string
12
+ }
13
+
14
+ // define props
15
+ const props = withDefaults(defineProps<BaseAccordionItemProps>(), {
16
+ headingLevel: 'h2',
17
+ backgroundClass: undefined,
18
+ item(): AccordionItemObject {
19
+ return {
20
+ title: undefined,
21
+ body: undefined
22
+ }
23
+ }
24
+ })
25
+
26
+ const { headingLevel, item } = reactive(props)
27
+
28
+ const ariaExpanded = ref(false)
29
+ const isHidden = ref(true)
30
+ const itemId = ref(uniqueId())
31
+
32
+ const panelId = computed(() => {
33
+ return `block_accordion_panel_${itemId.value}`
34
+ })
35
+
36
+ const headingId = computed(() => {
37
+ return `block_accordion_heading_${itemId.value}`
38
+ })
39
+
40
+ const handleClick = () => {
41
+ ariaExpanded.value = !ariaExpanded.value
42
+ isHidden.value = !isHidden.value
43
+ if (isHidden.value) {
44
+ emit('accordionItemClosed')
45
+ } else {
46
+ emit('accordionItemOpened')
47
+ }
48
+ }
49
+
50
+ const emit = defineEmits(['accordionItemOpened', 'accordionItemClosed'])
51
+ </script>
52
+ <template>
53
+ <div
54
+ class="BaseAccordionItem"
55
+ :class="{ '-open': !isHidden }"
56
+ >
57
+ <div class="BaseAccordionHeader">
58
+ <slot name="header">
59
+ <div
60
+ v-if="headingLevel && item"
61
+ class="border-b border-gray-light-mid"
62
+ >
63
+ <component :is="headingLevel">
64
+ <button
65
+ v-bind-once="{ id: headingId, 'aria-controls': panelId }"
66
+ :aria-expanded="ariaExpanded"
67
+ class="BaseAccordion-trigger group flex flex-nowrap justify-between items-center w-full can-hover:hover:underline text-body-lg"
68
+ @click="handleClick()"
69
+ >
70
+ <slot name="heading">
71
+ <div class="pointer-events-none text-left p-4 xl:py-6">
72
+ {{ item.title }}
73
+ </div>
74
+ </slot>
75
+ <span
76
+ class="BaseAccordion-icon pointer-events-none text-xs text-action flex-shrink-0 transform transition-transform"
77
+ :class="{ 'rotate-45': !isHidden }"
78
+ >
79
+ <IconPlus />
80
+ </span>
81
+ </button>
82
+ </component>
83
+ </div>
84
+ </slot>
85
+ </div>
86
+ <div
87
+ v-show="!isHidden"
88
+ class="BaseAccordionContent"
89
+ >
90
+ <slot>
91
+ <div
92
+ v-bind-once="{ id: panelId, 'aria-labelledby': headingId }"
93
+ role="region"
94
+ class="BaseAccordion-panel"
95
+ >
96
+ <slot name="panelContents">
97
+ <div class="px-4 pb-8">
98
+ <BlockStreamfield
99
+ :data="item.body"
100
+ variant="fluid"
101
+ />
102
+ </div>
103
+ </slot>
104
+ </div>
105
+ </slot>
106
+ </div>
107
+ </div>
108
+ </template>
@@ -2,7 +2,7 @@
2
2
  import { defineComponent } from 'vue'
3
3
 
4
4
  interface Variants {
5
- [name: string]: string
5
+ [key: string]: string
6
6
  }
7
7
 
8
8
  export const variants: Variants = {
@@ -11,6 +11,11 @@ export const variants: Variants = {
11
11
  dark: '-dark',
12
12
  social: '-social'
13
13
  }
14
+ export const colors: Variants = {
15
+ primary: '-color-primary',
16
+ secondary: '-color-secondary',
17
+ action: '-color-action'
18
+ }
14
19
 
15
20
  export default defineComponent({
16
21
  name: 'BaseButton',
@@ -21,6 +26,12 @@ export default defineComponent({
21
26
  default: 'primary',
22
27
  validator: (prop: string): boolean => Object.keys(variants).includes(prop)
23
28
  },
29
+ color: {
30
+ type: String,
31
+ required: false,
32
+ default: 'primary',
33
+ validator: (prop: string): boolean => Object.keys(colors).includes(prop)
34
+ },
24
35
  compact: {
25
36
  type: Boolean,
26
37
  default: false,
@@ -5,7 +5,7 @@ import type { PropType } from 'vue'
5
5
  export type ImageLoader = 'lazy' | 'eager' | undefined
6
6
 
7
7
  interface ObjectFitClasses {
8
- [name: string]: string
8
+ [key: string]: string
9
9
  }
10
10
 
11
11
  export const objectFitClasses: ObjectFitClasses = {
@@ -2,7 +2,7 @@
2
2
  import { defineComponent } from 'vue'
3
3
 
4
4
  interface AspectRatios {
5
- [name: string]: string
5
+ [key: string]: string
6
6
  }
7
7
 
8
8
  export const aspectRatios: AspectRatios = {
@@ -4,7 +4,7 @@ import { eventBus } from './../../utils/eventBus'
4
4
  import MixinAnimationCaret from './../MixinAnimationCaret/MixinAnimationCaret.vue'
5
5
 
6
6
  interface Variants {
7
- [name: string]: string
7
+ [key: string]: string
8
8
  }
9
9
 
10
10
  export const variants: Variants = {
@@ -51,9 +51,12 @@
51
51
  <script lang="ts">
52
52
  import type { PropType } from 'vue'
53
53
  import { defineComponent } from 'vue'
54
- import dayjs from './../../utils/dayjs'
55
- import { type Dayjs } from 'dayjs'
56
- import { type Duration } from 'dayjs/plugin/duration.js'
54
+ import dayjs, { type Dayjs } from 'dayjs'
55
+ import duration, { type Duration } from 'dayjs/plugin/duration.js'
56
+ import minMax from 'dayjs/plugin/minMax.js'
57
+
58
+ dayjs.extend(duration)
59
+ dayjs.extend(minMax)
57
60
 
58
61
  const calculateDuration = (start: Dayjs): Duration | undefined => {
59
62
  // Use round seconds so the datetime string stays valid and can be read by screen readers.
@@ -0,0 +1,29 @@
1
+ import BlockAccordion from './BlockAccordion.vue'
2
+ import { BlockStreamfieldTruncatedData } from '../BlockStreamfield/BlockStreamfield.stories'
3
+
4
+ export default {
5
+ title: 'Components/Blocks/BlockAccordion',
6
+ component: BlockAccordion
7
+ }
8
+
9
+ // stories
10
+ export const BaseStory = {
11
+ name: 'BlockAccordion',
12
+ args: {
13
+ headingLevel: 'h5',
14
+ items: [
15
+ {
16
+ title: 'Title for the accordion',
17
+ body: BlockStreamfieldTruncatedData.body
18
+ },
19
+ {
20
+ title: 'Another',
21
+ body: BlockStreamfieldTruncatedData.body
22
+ },
23
+ {
24
+ title: 'Yet another',
25
+ body: BlockStreamfieldTruncatedData.body
26
+ }
27
+ ]
28
+ }
29
+ }
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts">
2
+ import { reactive } from 'vue'
3
+ import { AccordionItemObject } from '../../interfaces'
4
+ import BaseAccordionItem from './../BaseAccordionItem/BaseAccordionItem.vue'
5
+
6
+ interface BlockAccordionProps {
7
+ autoClose?: boolean
8
+ headingLevel?: string
9
+ items?: AccordionItemObject[]
10
+ }
11
+
12
+ // define props
13
+ const props = withDefaults(defineProps<BlockAccordionProps>(), {
14
+ autoClose: false,
15
+ headingLevel: 'h2',
16
+ items: undefined
17
+ })
18
+
19
+ const { headingLevel, items } = reactive(props)
20
+ </script>
21
+ <template>
22
+ <div class="BlockAccordion">
23
+ <slot>
24
+ <BaseAccordionItem
25
+ v-for="(item, index) in items"
26
+ :key="index"
27
+ :heading-level="headingLevel"
28
+ :item="item"
29
+ />
30
+ </slot>
31
+ </div>
32
+ </template>
@@ -1,5 +1,4 @@
1
1
  import BlockHeading from './BlockHeading.vue'
2
-
3
2
  export default {
4
3
  title: 'Components/Blocks/BlockHeading',
5
4
  component: BlockHeading,
@@ -10,7 +9,8 @@ export const BlockHeadingData = {
10
9
  blockType: 'HeadingBlock',
11
10
  heading: 'Heading Text',
12
11
  level: 'h2',
13
- size: 'h2'
12
+ size: 'h2',
13
+ blockId: `${Math.random().toString(36).slice(2)}`
14
14
  }
15
15
 
16
16
  // stories
@@ -11,10 +11,20 @@
11
11
  </template>
12
12
 
13
13
  <script lang="ts">
14
- import { defineComponent } from 'vue'
14
+ import { defineComponent, type PropType } from 'vue'
15
+ import { type HeadingLevel } from './../BaseHeading/BaseHeading.vue'
15
16
  import { getHeadingId } from '../../utils/getHeadingId'
17
+
16
18
  import BaseHeading from './../BaseHeading/BaseHeading.vue'
17
19
 
20
+ export interface BlockHeadingObject {
21
+ blockType?: string
22
+ heading: HeadingLevel
23
+ level?: HeadingLevel
24
+ size?: string
25
+ blockId?: string
26
+ }
27
+
18
28
  export default defineComponent({
19
29
  name: 'BlockHeading',
20
30
  components: {
@@ -22,11 +32,7 @@ export default defineComponent({
22
32
  },
23
33
  props: {
24
34
  data: {
25
- type: Object,
26
- required: false
27
- },
28
- index: {
29
- type: Number,
35
+ type: Object as PropType<BlockHeadingObject>,
30
36
  required: false,
31
37
  default: undefined
32
38
  },
@@ -37,7 +43,9 @@ export default defineComponent({
37
43
  },
38
44
  computed: {
39
45
  getId() {
40
- return this.generateId ? getHeadingId(this.data?.heading, this.index) : undefined
46
+ return this.data && this.generateId
47
+ ? getHeadingId(this.data.heading, this.data.blockId)
48
+ : undefined
41
49
  }
42
50
  }
43
51
  })
@@ -21,7 +21,7 @@ import BlockLinkCard from './../BlockLinkCard/BlockLinkCard.vue'
21
21
  import BlockLinkTile from './../BlockLinkTile/BlockLinkTile.vue'
22
22
 
23
23
  interface Variants {
24
- [name: string]: string
24
+ [key: string]: string
25
25
  }
26
26
 
27
27
  export const itemTypes: Variants = {
@@ -24,7 +24,7 @@ import IconDownload from './../Icons/IconDownload.vue'
24
24
  import IconExternal from './../Icons/IconExternal.vue'
25
25
 
26
26
  interface Variants {
27
- [name: string]: string
27
+ [key: string]: string
28
28
  }
29
29
 
30
30
  export const variants: Variants = {
@@ -32,24 +32,42 @@ export default {
32
32
  excludeStories: /.*(Data)$/
33
33
  }
34
34
 
35
+ export const BlockStreamfieldMinimalData = {
36
+ body: [
37
+ {
38
+ blockType: 'RichTextBlock',
39
+ value:
40
+ '<p>Lorem ipsum <a href="/missions/test-mission/">dolor</a> sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.</p>\n'
41
+ },
42
+ {
43
+ blockType: 'RichTextBlock',
44
+ value:
45
+ '<p>Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.</p>\n'
46
+ }
47
+ ]
48
+ }
35
49
  export const BlockStreamfieldTruncatedData = {
36
50
  body: [
37
51
  BlockKeyPointsData,
38
- BlockHeadingData,
39
52
  {
40
53
  blockType: 'RichTextBlock',
41
54
  value:
42
55
  '<p>Lorem ipsum <a href="/missions/test-mission/">dolor</a> sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.</p><p>Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.</p>\n'
43
56
  },
44
- BlockImageComparisonData,
45
- BlockHeadingData,
57
+ { ...BlockHeadingData, blockId: Math.random().toString(36).slice(2) },
46
58
  {
47
59
  blockType: 'RichTextBlock',
48
60
  value:
49
61
  '<p>Lorem ipsum <a href="/missions/test-mission/">dolor</a> sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.</p><p>Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.</p>\n'
50
62
  },
51
- BlockInlineImageData.block,
52
- BlockIframeEmbedData
63
+ BlockImageData,
64
+ { ...BlockHeadingData, blockId: Math.random().toString(36).slice(2) },
65
+ {
66
+ blockType: 'RichTextBlock',
67
+ value:
68
+ '<p>Lorem ipsum <a href="/missions/test-mission/">dolor</a> sit amet, consectetur adipiscing elit. Quisque vitae justo quis justo malesuada molestie. Cras sed tincidunt dui.</p><p>Integer imperdiet blandit neque vitae euismod. Nulla aliquet lacus nibh, vel tincidunt urna efficitur non. In et eros vitae ex posuere maximus quis eget urna. Suspendisse fringilla posuere velit sit amet posuere. Morbi malesuada bibendum vehicula. Donec faucibus ut erat ut mattis. Suspendisse ornare, quam at placerat cursus, dolor mi lacinia nunc, eget maximus augue nulla in dolor.</p>\n'
69
+ },
70
+ BlockInlineImageData.block
53
71
  ]
54
72
  }
55
73
  export const BlockStreamfieldData = {
@@ -12,7 +12,7 @@
12
12
  class="mb-5"
13
13
  >
14
14
  <BlockHeading
15
- :data="block"
15
+ :data="block as BlockHeadingObject"
16
16
  :index="index"
17
17
  generate-id
18
18
  />
@@ -212,13 +212,11 @@
212
212
  <script lang="ts">
213
213
  import { defineComponent } from 'vue'
214
214
  import type { PropType } from 'vue'
215
- import type { BlockData, ImageObject } from '../../interfaces'
216
- import type { BlockData as VideoBlockEmbedData } from './../BlockVideoEmbed/BlockVideoEmbed.vue'
217
- import type { BlockQuoteAttributes } from './../BlockQuote/BlockQuote.vue'
215
+ import type { StreamfieldBlockData } from '../../interfaces'
218
216
  import LayoutHelper from './../LayoutHelper/LayoutHelper.vue'
219
217
  import BlockCardGrid from './../BlockCardGrid/BlockCardGrid.vue'
220
218
  import BlockCta from './../BlockCta/BlockCta.vue'
221
- import BlockHeading from './../BlockHeading/BlockHeading.vue'
219
+ import BlockHeading, { BlockHeadingObject } from './../BlockHeading/BlockHeading.vue'
222
220
  import BlockImage from './../BlockImage/BlockImage.vue'
223
221
  import BlockImageCarousel from './../BlockImageCarousel/BlockImageCarousel.vue'
224
222
  import BlockImageComparison from './../BlockImageComparison/BlockImageComparison.vue'
@@ -226,7 +224,7 @@ import BlockImageGallery from './../BlockImageGallery/BlockImageGallery.vue'
226
224
  import BlockInlineImage from './../BlockInlineImage/BlockInlineImage.vue'
227
225
  import BlockKeyPoints from './../BlockKeyPoints/BlockKeyPoints.vue'
228
226
  import BlockListCards from './../BlockListCards/BlockListCards.vue'
229
- import BlockQuote from './../BlockQuote/BlockQuote.vue'
227
+ import BlockQuote, { type BlockQuoteAttributes } from './../BlockQuote/BlockQuote.vue'
230
228
  import BlockRelatedLinks, {
231
229
  type BlockRelatedLinksObject
232
230
  } from './../BlockRelatedLinks/BlockRelatedLinks.vue'
@@ -236,10 +234,12 @@ import BlockText from './../BlockText/BlockText.vue'
236
234
  import BlockTwitterEmbed from './../BlockTwitterEmbed/BlockTwitterEmbed.vue'
237
235
  import BlockIframeEmbed from './../BlockIframeEmbed/BlockIframeEmbed.vue'
238
236
  import BlockVideo from './../BlockVideo/BlockVideo.vue'
239
- import BlockVideoEmbed from './../BlockVideoEmbed/BlockVideoEmbed.vue'
237
+ import BlockVideoEmbed, {
238
+ type BlockData as VideoBlockEmbedData
239
+ } from './../BlockVideoEmbed/BlockVideoEmbed.vue'
240
240
  import BlockAnchor from './../BlockAnchor/BlockAnchor.vue'
241
241
  interface Variants {
242
- [name: string]: string
242
+ [key: string]: string
243
243
  }
244
244
 
245
245
  export const variants: Variants = {
@@ -247,24 +247,6 @@ export const variants: Variants = {
247
247
  fluid: '-fluid'
248
248
  }
249
249
 
250
- export interface StreamfieldBlockData extends BlockData {
251
- id: string
252
- fullBleed: boolean
253
- heading: string
254
- galleryTitle: string
255
- galleryDescription: string
256
- coverImage: ImageObject
257
- gallerySlides: ImageObject[]
258
- blocks: object[]
259
- value: string
260
- customLabel: string
261
- introduction: string
262
- teaserPage: object | string[]
263
- image: ImageObject
264
- buttonText: string
265
- fullWidthImage: boolean
266
- }
267
-
268
250
  export default defineComponent({
269
251
  name: 'BlockStreamfield',
270
252
  components: {
@@ -9,7 +9,7 @@
9
9
  import { defineComponent } from 'vue'
10
10
 
11
11
  interface Variants {
12
- [name: string]: string
12
+ [key: string]: string
13
13
  }
14
14
 
15
15
  export const variants: Variants = {
@@ -53,6 +53,8 @@
53
53
  </template>
54
54
  <script lang="ts">
55
55
  import { defineComponent } from 'vue'
56
+ import { mapStores } from 'pinia'
57
+ import { useThemeStore } from '../../store/theme'
56
58
  import MixinVideoBg from './../MixinVideoBg/MixinVideoBg.vue'
57
59
  import BaseImageCaption from './../BaseImageCaption/BaseImageCaption.vue'
58
60
  import IconInfo from './../Icons/IconInfo.vue'
@@ -105,6 +107,7 @@ export default defineComponent({
105
107
  }
106
108
  },
107
109
  computed: {
110
+ ...mapStores(useThemeStore),
108
111
  theImageCaption(): string | undefined {
109
112
  if (this.image && this.caption && this.caption.length > 2 && this.displayCaption) {
110
113
  return this.caption
@@ -149,7 +152,13 @@ export default defineComponent({
149
152
  },
150
153
  hasCaptionArea(): string | boolean {
151
154
  if (this.theImageData) {
152
- return this.theImageCaption || this.image?.credit || this.image?.detailUrl
155
+ if (this.themeStore.isEdu) {
156
+ // For EDU, only show the caption area if there is a caption
157
+ return this.theImageCaption ? this.theImageCaption : false
158
+ } else {
159
+ // For others, show the caption area if there is also a credit or detail URL
160
+ return this.theImageCaption || this.image?.credit || this.image?.detailUrl
161
+ }
153
162
  } else if (this.customCaption) {
154
163
  return true
155
164
  }
@@ -2,7 +2,7 @@
2
2
  import { defineComponent } from 'vue'
3
3
 
4
4
  interface Indents {
5
- [name: string]: string
5
+ [key: string]: string
6
6
  }
7
7
 
8
8
  export const indents: Indents = {
@@ -0,0 +1,112 @@
1
+ import MetaPanel from './MetaPanel.vue'
2
+
3
+ export default {
4
+ title: 'Components/Utilities/MetaPanel',
5
+ component: MetaPanel,
6
+ tags: ['!autodocs'],
7
+ decorators: [
8
+ () => ({
9
+ template: `<div><div class="h-40 w-full max-w-screen-3xl mx-auto bg-gray-dark"><p class="text-white">Dark background for demo purposes only and not part of the component.</p></div><div id="storyDecorator"><story/></div><div class="h-40 w-full max-w-screen-3xl mx-auto bg-gray-dark"><p class="text-white">Dark background for demo purposes only and not part of the component.</p></div></div>`
10
+ })
11
+ ],
12
+ parameters: {
13
+ layout: 'fullscreen'
14
+ },
15
+ argTypes: {
16
+ theme: {
17
+ type: { name: 'string', required: false },
18
+ control: { type: 'select' },
19
+ options: ['primary', 'secondary', 'stars']
20
+ }
21
+ }
22
+ }
23
+
24
+ // stories
25
+ export const BaseStory = {
26
+ name: 'MetaPanel',
27
+ args: {
28
+ negativeTop: true,
29
+ negativeBottom: true,
30
+ button: 'View Standards',
31
+ primarySubject: 'Math',
32
+ additionalSubjects: ['Science'],
33
+ time: '30mins - hr',
34
+ gradeLevels: [
35
+ { gradeLevel: 'All Ages' },
36
+ { gradeLevel: 'K' },
37
+ { gradeLevel: '1' },
38
+ { gradeLevel: '2' },
39
+ { gradeLevel: '5' },
40
+ { gradeLevel: '6' },
41
+ { gradeLevel: '7' },
42
+ { gradeLevel: '8' }
43
+ ],
44
+ standards: [
45
+ {
46
+ standard: {
47
+ code: 'CCRA.R.1',
48
+ definition:
49
+ 'Read closely to determine what the text says explicitly and to make logical inferences from it; cite specific textual evidence when writing or speaking to support conclusions drawn from the text.',
50
+ domain: {
51
+ domain: 'College and Career Readiness Anchor Standards for Reading'
52
+ },
53
+ type: 'ccss_english_language_arts'
54
+ }
55
+ },
56
+ {
57
+ standard: {
58
+ code: 'RL.3.2',
59
+ definition:
60
+ 'Recount stories, including fables, folktales, and myths from diverse cultures; determine the central message, lesson, or moral and explain how it is conveyed through key details in the text.',
61
+ domain: {
62
+ domain: 'Reading Standards for Literature'
63
+ },
64
+ type: 'ccss_english_language_arts'
65
+ }
66
+ },
67
+ {
68
+ standard: {
69
+ code: 'RL.1.5',
70
+ definition:
71
+ 'Explain major differences between books that tell stories and books that give information, drawing on a wide reading of a range of text types.',
72
+ domain: {
73
+ domain: 'Reading Standards for Literature'
74
+ },
75
+ type: 'ccss_english_language_arts'
76
+ }
77
+ },
78
+ {
79
+ standard: {
80
+ code: 'K.CC.A',
81
+ definition: 'Know number names and the count sequence.',
82
+ domain: {
83
+ domain: 'Counting and Cardinality'
84
+ },
85
+ type: 'ccss_maths'
86
+ }
87
+ },
88
+ {
89
+ standard: {
90
+ code: 'K.CC.A.3',
91
+ definition:
92
+ 'Write numbers from 0 to 20. Represent a number of objects with a written numeral 0-20 (with 0 representing a count of no objects).',
93
+ domain: {
94
+ domain: 'Counting and Cardinality'
95
+ },
96
+ type: 'ccss_maths'
97
+ }
98
+ },
99
+ {
100
+ standard: {
101
+ code: 'K-PS2-1',
102
+ definition:
103
+ 'Plan and conduct an investigation to compare the effects of different strengths or different directions of pushes and pulls on the motion of an object.',
104
+ domain: {
105
+ domain: 'Physical Sciences'
106
+ },
107
+ type: 'ngss'
108
+ }
109
+ }
110
+ ]
111
+ }
112
+ }