@explorer-1/vue 0.2.39 → 0.2.41

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 (72) hide show
  1. package/components.d.ts +3 -0
  2. package/dist/explorer-1-vue.js +4912 -4553
  3. package/dist/explorer-1-vue.umd.cjs +13 -13
  4. package/dist/src/components/BasePill/BasePill.vue.d.ts +4 -10
  5. package/dist/src/components/BaseSwimlane/BaseSwimlane.vue.d.ts +2 -2
  6. package/dist/src/components/BlockIframeEmbed/BlockIframeEmbed.vue.d.ts +9 -1
  7. package/dist/src/components/BlockImage/BlockImageFullBleed.vue.d.ts +23 -4
  8. package/dist/src/components/BlockImage/BlockImageStandard.vue.d.ts +23 -4
  9. package/dist/src/components/BlockImageComparison/BlockImageComparison.vue.d.ts +11 -1
  10. package/dist/src/components/BlockVideo/BlockVideo.vue.d.ts +19 -1
  11. package/dist/src/components/BlockVideoEmbed/BlockVideoEmbed.vue.d.ts +9 -0
  12. package/dist/src/components/DetailHeadline/DetailHeadline.vue.d.ts +9 -0
  13. package/dist/src/components/HeroListingIndex/HeroListingIndex.stories.d.ts +82 -93
  14. package/dist/src/components/MetadataEduResource/MetadataEduResource.vue.d.ts +4 -0
  15. package/dist/src/components/MetadataEvent/MetadataEvent.stories.d.ts +1 -0
  16. package/dist/src/components/MixinCarousel/MixinCarousel.stories.d.ts +4 -4
  17. package/dist/src/components/MixinCarousel/MixinCarousel.vue.d.ts +2 -2
  18. package/dist/src/components/MixinFancybox/MixinFancybox.vue.d.ts +1 -1
  19. package/dist/src/components/NavDesktop/NavDesktop.stories.d.ts +4 -4
  20. package/dist/src/components/NavDesktop/NavDesktop.vue.d.ts +2 -2
  21. package/dist/src/components/NavDesktopEdu/NavDesktopEdu.stories.d.ts +2 -2
  22. package/dist/src/components/NavMobile/NavMobile.stories.d.ts +3 -3
  23. package/dist/src/components/NavMobile/NavMobile.vue.d.ts +1 -1
  24. package/dist/src/components/NavMobile/NavMobileEdu.stories.d.ts +3 -3
  25. package/dist/src/components/NavSecondary/NavSecondaryDropdown.vue.d.ts +4 -4
  26. package/dist/src/components/NewsDetailMediaContact/NewsDetailMediaContact.vue.d.ts +1 -1
  27. package/dist/src/components/SearchFilterGroup/SearchFilterGroup.vue.d.ts +7 -0
  28. package/dist/src/components/SearchResultCard/SearchResultCard.vue.d.ts +54 -5
  29. package/dist/src/components/SearchResultGridItem/SearchResultGridItem.vue.d.ts +42 -4
  30. package/dist/src/components/TextArea/TextArea.vue.d.ts +9 -9
  31. package/dist/src/components/TextInput/TextInput.vue.d.ts +9 -9
  32. package/dist/src/constants.d.ts +12 -2
  33. package/dist/src/interfaces.d.ts +16 -9
  34. package/dist/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.stories.d.ts +284 -0
  35. package/dist/src/templates/edu/PageEduLesson/PageEduLesson.stories.d.ts +8 -2
  36. package/dist/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.stories.d.ts +359 -0
  37. package/dist/src/utils/getHeadingId.d.ts +1 -3
  38. package/dist/src/utils/lookupContentType.d.ts +3 -0
  39. package/dist/src/utils/mixins.d.ts +1 -1
  40. package/dist/style.css +1 -1
  41. package/package.json +2 -2
  42. package/src/components/BaseButton/BaseButton.vue +3 -3
  43. package/src/components/BaseCarousel/BaseCarousel.vue +152 -0
  44. package/src/components/BaseImageCaption/BaseImageCaption.vue +10 -7
  45. package/src/components/BlockImage/BlockImageFullBleed.vue +37 -7
  46. package/src/components/BlockImage/BlockImageStandard.vue +36 -8
  47. package/src/components/BlockImageComparison/BlockImageComparison.vue +23 -20
  48. package/src/components/BlockLinkCard/BlockLinkCard.vue +1 -0
  49. package/src/components/BlockRelatedLinks/RelatedLink.vue +2 -2
  50. package/src/components/BlockVideo/BlockVideo.vue +22 -2
  51. package/src/components/BlockVideoEmbed/BlockVideoEmbed.vue +10 -2
  52. package/src/components/DetailHeadline/DetailHeadline.vue +11 -6
  53. package/src/components/HeroListingIndex/HeroListingIndex.stories.js +92 -100
  54. package/src/components/HeroListingIndex/HeroListingIndex.vue +13 -15
  55. package/src/components/HeroMedium/HeroMedium.vue +1 -1
  56. package/src/components/MetadataEduResource/MetadataEduResource.vue +8 -2
  57. package/src/components/MetadataEvent/MetadataEvent.stories.js +1 -0
  58. package/src/components/MetadataEvent/MetadataEvent.vue +24 -8
  59. package/src/components/NavDesktop/NavDesktop.vue +6 -4
  60. package/src/components/NavDesktopEdu/NavDesktopEdu.vue +7 -3
  61. package/src/components/NavMobile/NavMobile.vue +5 -3
  62. package/src/components/NewsDetailMediaContact/NewsDetailMediaContact.vue +5 -3
  63. package/src/components/SearchFilterGroup/SearchFilterGroup.vue +26 -24
  64. package/src/components/SearchResultCard/SearchResultCard.vue +17 -1
  65. package/src/components/SearchResultGridItem/SearchResultGridItem.vue +17 -1
  66. package/src/components/SearchResultsList/SearchResultsList.vue +25 -1
  67. package/src/interfaces.ts +4 -0
  68. package/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.stories.js +13 -4
  69. package/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.vue +36 -18
  70. package/src/templates/edu/PageEduMultimediaDetail/PageEduMultimediaDetail.vue +1 -0
  71. package/src/templates/www/PageTimeline/PageTimeline.vue +5 -1
  72. package/src/utils/mixins.ts +8 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@explorer-1/vue",
3
- "version": "0.2.39",
3
+ "version": "0.2.41",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -30,7 +30,7 @@
30
30
  "vue-bind-once": "^0.2.1",
31
31
  "vue-observe-visibility": "^1.0.0",
32
32
  "vue3-compare-image": "^1.2.5",
33
- "@explorer-1/common": "1.1.10"
33
+ "@explorer-1/common": "1.1.12"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@vitejs/plugin-vue": "^5.0.4",
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { defineComponent } from 'vue'
2
+ import { defineComponent, resolveComponent } from 'vue'
3
3
 
4
4
  interface Variants {
5
5
  [key: string]: string
@@ -54,11 +54,11 @@ export default defineComponent({
54
54
  },
55
55
  emits: ['click'],
56
56
  computed: {
57
- tag(): string {
57
+ tag() {
58
58
  if (this.disabled) {
59
59
  return 'button'
60
60
  } else if (this.to) {
61
- return 'nuxt-link'
61
+ return resolveComponent('NuxtLink')
62
62
  } else if (this.href) {
63
63
  return 'a'
64
64
  } else {
@@ -0,0 +1,152 @@
1
+ <template>
2
+ <div class="BaseCarousel w-full overflow-hidden relative">
3
+ <div
4
+ ref="BaseCarousel"
5
+ class="swiper relative"
6
+ >
7
+ <div class="swiper-wrapper">
8
+ <slot />
9
+ </div>
10
+ <div class="swiper-nav lg:block absolute bottom-0 right-0 z-100">
11
+ <div class="relative z-10 flex">
12
+ <BaseButton
13
+ class="swiper-prev xl:text-xl border-collapse"
14
+ aria-label="Previous slide"
15
+ >
16
+ <template #icon>
17
+ <IconPrev />
18
+ </template>
19
+ </BaseButton>
20
+ <BaseButton
21
+ class="swiper-next xl:text-xl border-collapse"
22
+ aria-label="Next slide"
23
+ >
24
+ <template #icon>
25
+ <IconNext />
26
+ </template>
27
+ </BaseButton>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </template>
33
+ <script lang="ts">
34
+ import { defineComponent } from 'vue'
35
+ import Swiper from 'swiper'
36
+ import { A11y, Navigation } from 'swiper/modules'
37
+ import type { SwiperOptions } from 'swiper/types'
38
+ import swiperOptions from '@explorer-1/common/src/js/_swiperOptions'
39
+ import IconPrev from './../Icons/IconPrev.vue'
40
+ import IconNext from './../Icons/IconNext.vue'
41
+ import BaseButton from './../BaseButton/BaseButton.vue'
42
+ const BaseCarouselOptions = swiperOptions.BlockImageCarousel
43
+
44
+ Swiper.use([Navigation, A11y])
45
+
46
+ export default defineComponent({
47
+ name: 'BaseCarousel',
48
+ components: {
49
+ BaseButton,
50
+ IconPrev,
51
+ IconNext
52
+ },
53
+ props: {
54
+ loop: {
55
+ type: Boolean,
56
+ default: false
57
+ },
58
+ itemRole: {
59
+ type: String,
60
+ default: undefined
61
+ }
62
+ },
63
+ data(): {
64
+ currentIndex: number
65
+ slider: Swiper | null
66
+ currentCaption: string
67
+ sliderOptions: SwiperOptions
68
+ } {
69
+ return {
70
+ currentIndex: 0,
71
+ currentCaption: '',
72
+ slider: null,
73
+ sliderOptions: {
74
+ ...BaseCarouselOptions,
75
+ loop: this.loop,
76
+ // this component has custom pagination
77
+ pagination: false,
78
+ a11y: {
79
+ slideRole: this.itemRole as string | undefined
80
+ }
81
+ }
82
+ }
83
+ },
84
+ computed: {},
85
+ watch: {
86
+ slide(value) {
87
+ this.slideTo(value)
88
+ }
89
+ },
90
+ mounted() {
91
+ this.init()
92
+ },
93
+ methods: {
94
+ init() {
95
+ this.slider = new Swiper(this.$refs.BaseCarousel as HTMLElement, this.sliderOptions)
96
+ this.currentIndex = this.slider.realIndex
97
+ },
98
+ updateIndex(val: number) {
99
+ this.currentIndex = val
100
+ },
101
+ slideTo(val: number) {
102
+ if (this.slider) {
103
+ this.slider.slideTo(val)
104
+ }
105
+ }
106
+ }
107
+ })
108
+ </script>
109
+ <style lang="scss">
110
+ @import 'swiper/swiper-bundle.css';
111
+ .BaseCarousel {
112
+ .swiper {
113
+ .swiper-prev {
114
+ @apply mr-px;
115
+ }
116
+
117
+ .swiper-prev,
118
+ .swiper-next {
119
+ &.swiper-button-disabled {
120
+ @apply opacity-75 cursor-default bg-none;
121
+ }
122
+ }
123
+ }
124
+
125
+ .swiper-nav {
126
+ padding-top: 56.25%;
127
+ }
128
+
129
+ // .swiper-dots {
130
+ // padding-top: 56.25%;
131
+ // @apply pointer-events-none;
132
+
133
+ // .swiper-dot {
134
+ // @apply inline-block px-1 py-3 cursor-pointer pointer-events-auto;
135
+
136
+ // &:focus {
137
+ // @apply outline-none ring-1;
138
+ // }
139
+
140
+ // > span {
141
+ // @apply inline-block w-3 h-3 rounded-full bg-gray-light-mid;
142
+ // }
143
+
144
+ // &.swiper-dot-active {
145
+ // > span {
146
+ // @apply bg-primary;
147
+ // }
148
+ // }
149
+ // }
150
+ // }
151
+ }
152
+ </style>
@@ -31,7 +31,10 @@ export default defineComponent({
31
31
  v-if="data"
32
32
  class="BaseImageCaption text-body-sm"
33
33
  >
34
- <div class="inline mr-2">
34
+ <div
35
+ v-if="data.caption || data.credit"
36
+ class="inline mr-2"
37
+ >
35
38
  <div
36
39
  class="the-caption-text inline"
37
40
  v-html="data.caption"
@@ -44,20 +47,20 @@ export default defineComponent({
44
47
  </span>
45
48
  </div>
46
49
  <BaseLink
47
- v-if="data.detailUrl"
50
+ v-if="customLink"
48
51
  class="inline-block"
49
52
  variant="default"
50
- :to="data.detailUrl"
53
+ :to="customLink"
51
54
  >
52
- Full Image Details
55
+ {{ customLinkText }}
53
56
  </BaseLink>
54
57
  <BaseLink
55
- v-else-if="customLink"
58
+ v-else-if="data.detailUrl"
56
59
  class="inline-block"
57
60
  variant="default"
58
- :to="customLink"
61
+ :to="data.detailUrl"
59
62
  >
60
- {{ customLinkText }}
63
+ Full Image Details
61
64
  </BaseLink>
62
65
  </div>
63
66
  </template>
@@ -1,6 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { defineComponent } from 'vue'
3
3
  import type { PropType } from 'vue'
4
+ import { mapStores } from 'pinia'
5
+ import { useThemeStore } from '../../store/theme'
6
+
4
7
  import MixinFancybox from './../MixinFancybox/MixinFancybox.vue'
5
8
  import BaseImage from './../BaseImage/BaseImage.vue'
6
9
  import BaseImagePlaceholder from './../BaseImagePlaceholder/BaseImagePlaceholder.vue'
@@ -19,7 +22,7 @@ export default defineComponent({
19
22
  props: {
20
23
  data: {
21
24
  type: Object as PropType<ImageObject>,
22
- required: false
25
+ default: undefined
23
26
  },
24
27
  // if a caption should even be visible
25
28
  displayCaption: {
@@ -29,7 +32,12 @@ export default defineComponent({
29
32
  // overrides caption provided with image model
30
33
  caption: {
31
34
  type: String,
32
- required: false
35
+ default: undefined
36
+ },
37
+ // overrides detail url provided with image model. Also forces hasCaption to be true
38
+ customDetailUrl: {
39
+ type: String,
40
+ default: undefined
33
41
  },
34
42
  // if the image should be constrained to a fixed aspect ratio (21:9 on smaller screens, 2:1 on larger screens)
35
43
  constrain: {
@@ -43,6 +51,7 @@ export default defineComponent({
43
51
  }
44
52
  },
45
53
  computed: {
54
+ ...mapStores(useThemeStore),
46
55
  theCaption(): string | undefined {
47
56
  if (this.caption && this.caption.length > 2 && this.displayCaption) {
48
57
  return this.caption
@@ -59,19 +68,36 @@ export default defineComponent({
59
68
  theSrcSet(): string | undefined {
60
69
  return this.theData ? mixinGetSrcSet(this.theData) : undefined
61
70
  },
71
+ theCredit() {
72
+ if (this.themeStore.isEdu && !this.displayCaption) {
73
+ return undefined
74
+ }
75
+ return this.data?.credit
76
+ },
62
77
  // reform the data object with the computed caption
63
78
  theData(): ImageObject | undefined {
64
79
  if (this.data) {
65
80
  return {
66
81
  ...this.data,
67
- caption: this.theCaption
82
+ caption: this.theCaption,
83
+ credit: this.theCredit,
84
+ detailUrl: this.customDetailUrl
68
85
  }
69
86
  }
70
87
  return undefined
71
88
  },
72
89
  hasCaptionArea(): boolean {
73
- if (this.data && (this.theCaption || this.data.credit || this.data.detailUrl)) {
74
- return true
90
+ if (this.data) {
91
+ if (this.themeStore.isEdu) {
92
+ return this.theData?.caption || this.customDetailUrl ? true : false
93
+ } else if (
94
+ this.theData?.caption ||
95
+ this.theData?.credit ||
96
+ this.theData?.detailUrl ||
97
+ this.customDetailUrl
98
+ ) {
99
+ return true
100
+ }
75
101
  }
76
102
  return false
77
103
  }
@@ -87,7 +113,7 @@ export default defineComponent({
87
113
  :src="theData.original || theData.src?.url"
88
114
  :caption="theData.caption"
89
115
  :credit="theData.credit"
90
- :detail-url="theData.detailUrl"
116
+ :detail-url="customDetailUrl || theData.detailUrl"
91
117
  >
92
118
  <BaseImagePlaceholder
93
119
  :aspect-ratio="constrain ? '16:9' : 'none'"
@@ -113,7 +139,11 @@ export default defineComponent({
113
139
  v-if="data && hasCaptionArea"
114
140
  class="max-w-screen-3xl p-4 pb-0 mx-auto"
115
141
  >
116
- <BaseImageCaption :data="theData" />
142
+ <BaseImageCaption
143
+ :data="theData"
144
+ :custom-link="customDetailUrl"
145
+ custom-link-text="Full Image Details"
146
+ />
117
147
  </div>
118
148
  </div>
119
149
  </template>
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { defineComponent } from 'vue'
3
3
  import type { PropType } from 'vue'
4
-
4
+ import { mapStores } from 'pinia'
5
+ import { useThemeStore } from '../../store/theme'
5
6
  import type { ImageObject } from './../../interfaces'
6
7
  import MixinFancybox from './../MixinFancybox/MixinFancybox.vue'
7
8
  import BaseImage from './../BaseImage/BaseImage.vue'
@@ -19,7 +20,7 @@ export default defineComponent({
19
20
  props: {
20
21
  data: {
21
22
  type: Object as PropType<ImageObject>,
22
- required: false
23
+ default: undefined
23
24
  },
24
25
  // if a caption should even be visible
25
26
  displayCaption: {
@@ -29,7 +30,12 @@ export default defineComponent({
29
30
  // overrides caption provided with image model
30
31
  caption: {
31
32
  type: String,
32
- required: false
33
+ default: undefined
34
+ },
35
+ // overrides detail url provided with image model. Also forces hasCaption to be true
36
+ customDetailUrl: {
37
+ type: String,
38
+ default: undefined
33
39
  },
34
40
  // if the image should be constrained to a 16:9 aspect ratio
35
41
  constrain: {
@@ -38,6 +44,7 @@ export default defineComponent({
38
44
  }
39
45
  },
40
46
  computed: {
47
+ ...mapStores(useThemeStore),
41
48
  theCaption(): string | undefined {
42
49
  if (this.caption && this.caption.length > 2 && this.displayCaption) {
43
50
  return this.caption
@@ -51,19 +58,36 @@ export default defineComponent({
51
58
  }
52
59
  return undefined
53
60
  },
61
+ theCredit() {
62
+ if (this.themeStore.isEdu && !this.displayCaption) {
63
+ return undefined
64
+ }
65
+ return this.data?.credit
66
+ },
54
67
  // reform the data object with the computed caption
55
68
  theData(): ImageObject | undefined {
56
69
  if (this.data) {
57
70
  return {
58
71
  ...this.data,
59
- caption: this.theCaption
72
+ caption: this.theCaption,
73
+ credit: this.theCredit,
74
+ detailUrl: this.customDetailUrl
60
75
  }
61
76
  }
62
77
  return undefined
63
78
  },
64
79
  hasCaptionArea(): boolean {
65
- if (this.data && (this.theCaption || this.data.credit || this.data.detailUrl)) {
66
- return true
80
+ if (this.theData) {
81
+ if (this.themeStore.isEdu) {
82
+ return this.theData.caption || this.customDetailUrl ? true : false
83
+ } else if (
84
+ this.theData.caption ||
85
+ this.theData.credit ||
86
+ this.theData.detailUrl ||
87
+ this.customDetailUrl
88
+ ) {
89
+ return true
90
+ }
67
91
  }
68
92
  return false
69
93
  }
@@ -77,7 +101,7 @@ export default defineComponent({
77
101
  :src="theData.original || theData.src?.url"
78
102
  :caption="theData.caption"
79
103
  :credit="theData.credit"
80
- :detail-url="theData.detailUrl"
104
+ :detail-url="customDetailUrl || theData.detailUrl"
81
105
  >
82
106
  <BaseImagePlaceholder
83
107
  :aspect-ratio="constrain ? '16:9' : 'none'"
@@ -100,7 +124,11 @@ export default defineComponent({
100
124
  v-if="theData && hasCaptionArea"
101
125
  class="lg:px-0 p-4 pb-0 print:pl-0"
102
126
  >
103
- <BaseImageCaption :data="theData" />
127
+ <BaseImageCaption
128
+ :data="theData"
129
+ :custom-link="customDetailUrl"
130
+ custom-link-text="Full Image Details"
131
+ />
104
132
  </div>
105
133
  </div>
106
134
  </template>
@@ -1,38 +1,41 @@
1
1
  <template>
2
2
  <div v-if="data">
3
- <client-only placeholder="Loading Image Comparison...">
4
- <VueCompareImage
5
- v-if="theBeforeImageSrc && theAfterImageSrc"
6
- class="h-full animate-fadeIn"
7
- :left-image="theBeforeImageSrc.url"
8
- left-image-alt="Left image"
9
- :right-image="theAfterImageSrc.url"
10
- right-image-alt="Right image"
11
- />
12
- </client-only>
3
+ <VueCompareImage
4
+ v-if="theBeforeImageSrc && theAfterImageSrc"
5
+ class="h-full animate-fadeIn"
6
+ :left-image="theBeforeImageSrc.url"
7
+ left-image-alt="Left image"
8
+ :right-image="theAfterImageSrc.url"
9
+ right-image-alt="Right image"
10
+ />
13
11
  <div
14
- v-if="data.caption && data.caption.length > 2"
15
- class="text-gray-mid-dark mt-3"
16
- v-html="data.caption"
17
- ></div>
12
+ v-if="data.caption || customDetailUrl"
13
+ class="lg:px-0 p-4 pb-0 print:pl-0"
14
+ >
15
+ <BaseImageCaption
16
+ :data="{ caption: data.caption }"
17
+ :custom-link="customDetailUrl"
18
+ custom-link-text="Full Image Details"
19
+ />
20
+ </div>
18
21
  </div>
19
22
  </template>
20
23
 
21
24
  <script lang="ts">
22
25
  import { defineComponent } from 'vue'
23
- // import VueCompareImage from 'vue3-compare-image'
24
-
25
- // const VueCompareImage = process.browser ? require('vue3-compare-image') : null
26
+ import BaseImageCaption from './../BaseImageCaption/BaseImageCaption.vue'
26
27
 
27
28
  export default defineComponent({
28
29
  name: 'BlockImageComparison',
29
- // components: {
30
- // VueCompareImage,
31
- // },
30
+ components: { BaseImageCaption },
32
31
  props: {
33
32
  data: {
34
33
  type: Object,
35
34
  required: true
35
+ },
36
+ customDetailUrl: {
37
+ type: String,
38
+ default: undefined
36
39
  }
37
40
  },
38
41
  computed: {
@@ -133,6 +133,7 @@
133
133
  v-else-if="metadataAttrs.type === 'resource'"
134
134
  :resource="theItem as EduResourceCardObject"
135
135
  :variant="metadataAttrs.icons"
136
+ :show-time="true"
136
137
  compact
137
138
  />
138
139
  </div>
@@ -18,7 +18,7 @@
18
18
  </component>
19
19
  </template>
20
20
  <script lang="ts">
21
- import { defineComponent } from 'vue'
21
+ import { defineComponent, resolveComponent } from 'vue'
22
22
  import IconArrow from './../Icons/IconArrow.vue'
23
23
  import IconDownload from './../Icons/IconDownload.vue'
24
24
  import IconExternal from './../Icons/IconExternal.vue'
@@ -59,7 +59,7 @@ export default defineComponent({
59
59
  computed: {
60
60
  tag() {
61
61
  if (this.to) {
62
- return 'nuxt-link'
62
+ return resolveComponent('NuxtLink')
63
63
  } else {
64
64
  return 'a'
65
65
  }
@@ -9,15 +9,21 @@
9
9
  />
10
10
 
11
11
  <div
12
- v-if="(data.caption && data.caption.length > 2) || data.credit"
12
+ v-if="hasCaption"
13
13
  class="lg:px-0 p-4 pb-0 print:pl-0"
14
14
  >
15
- <BaseImageCaption :data="data" />
15
+ <BaseImageCaption
16
+ :data="data"
17
+ :custom-link="customDetailUrl"
18
+ custom-link-text="Full Video Details"
19
+ />
16
20
  </div>
17
21
  </div>
18
22
  </template>
19
23
  <script lang="ts">
20
24
  import { defineComponent } from 'vue'
25
+ import { mapStores } from 'pinia'
26
+ import { useThemeStore } from '../../store/theme'
21
27
  import BaseVideo from './../BaseVideo/BaseVideo.vue'
22
28
  import BaseImageCaption from './../BaseImageCaption/BaseImageCaption.vue'
23
29
 
@@ -35,6 +41,20 @@ export default defineComponent({
35
41
  autoplay: {
36
42
  type: Boolean,
37
43
  default: false
44
+ },
45
+ customDetailUrl: {
46
+ type: String,
47
+ default: undefined
48
+ }
49
+ },
50
+ computed: {
51
+ ...mapStores(useThemeStore),
52
+ hasCaption() {
53
+ if (this.themeStore.isEdu) {
54
+ return this.data?.caption || this.customDetailUrl
55
+ } else {
56
+ return this.data?.caption || this.data?.credit || this.customDetailUrl
57
+ }
38
58
  }
39
59
  }
40
60
  })
@@ -10,10 +10,14 @@
10
10
  <div v-html="data.embed.embed"></div>
11
11
  </BaseImagePlaceholder>
12
12
  <div
13
- v-if="data.caption"
13
+ v-if="data.caption || customDetailUrl"
14
14
  class="lg:px-0 p-4 print:pl-0"
15
15
  >
16
- <BaseImageCaption :data="data" />
16
+ <BaseImageCaption
17
+ :data="data"
18
+ :custom-link="customDetailUrl"
19
+ custom-link-text="Full Video Details"
20
+ />
17
21
  </div>
18
22
  </div>
19
23
  </template>
@@ -45,6 +49,10 @@ export default defineComponent({
45
49
  type: Object as PropType<Partial<BlockData>>,
46
50
  required: false,
47
51
  default: undefined
52
+ },
53
+ customDetailUrl: {
54
+ type: String,
55
+ default: undefined
48
56
  }
49
57
  },
50
58
  mounted() {
@@ -100,12 +100,13 @@
100
100
  <span :itemprop="schema ? 'name' : undefined"> Jet Propulsion Laboratory </span>
101
101
  <span :itemprop="schema ? 'url' : undefined"> https://www.jpl.nasa.gov/ </span>
102
102
  </span>
103
- <span v-if="publicationDate">
104
- <meta
105
- v-if="schema"
106
- itemprop="datePublished"
107
- :content="pubDatetime"
108
- />
103
+ <meta
104
+ v-if="schema && publicationDate"
105
+ itemprop="datePublished"
106
+ :content="pubDatetime"
107
+ />
108
+
109
+ <span v-if="publicationDate && !hideDate">
109
110
  {{
110
111
  // @ts-ignore
111
112
  $filters.displayDate(publicationDate)
@@ -186,6 +187,10 @@ export default defineComponent({
186
187
  schema: {
187
188
  type: Boolean,
188
189
  default: false
190
+ },
191
+ hideDate: {
192
+ type: Boolean,
193
+ default: false
189
194
  }
190
195
  },
191
196
  computed: {