@explorer-1/vue 0.3.6 → 0.3.8

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 (200) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +1 -1
  3. package/src/components/AboutTheAuthor/AboutTheAuthor.stories.js +1 -1
  4. package/src/components/AboutTheAuthor/AboutTheAuthor.vue +9 -9
  5. package/src/components/AsteroidWatchWidget/AsteroidWatchWidget.stories.js +0 -5
  6. package/src/components/AsteroidWatchWidget/AsteroidWatchWidget.vue +5 -1
  7. package/src/components/BackToTop/BackToTop.stories.js +1 -1
  8. package/src/components/BackToTop/BackToTop.vue +10 -0
  9. package/src/components/BaseAccordionItem/BaseAccordionItem.stories.js +5 -29
  10. package/src/components/BaseAccordionItem/BaseAccordionItem.vue +56 -17
  11. package/src/components/BaseAudio/BaseAudio.vue +6 -0
  12. package/src/components/BaseButton/BaseButton.stories.ts +1 -20
  13. package/src/components/BaseButton/BaseButton.vue +34 -10
  14. package/src/components/BaseCheckboxGroup/BaseCheckboxGroup.stories.js +2 -1
  15. package/src/components/BaseCheckboxGroup/BaseCheckboxGroup.vue +5 -0
  16. package/src/components/BaseHeading/BaseHeading.stories.js +0 -15
  17. package/src/components/BaseHeading/BaseHeading.vue +18 -8
  18. package/src/components/BaseImage/BaseImage.stories.ts +6 -21
  19. package/src/components/BaseImage/BaseImage.vue +26 -14
  20. package/src/components/BaseImageCaption/BaseImageCaption.vue +10 -6
  21. package/src/components/BaseImagePlaceholder/BaseImagePlaceholder.stories.js +3 -16
  22. package/src/components/BaseImagePlaceholder/BaseImagePlaceholder.vue +13 -9
  23. package/src/components/BaseLink/BaseLink.stories.js +4 -46
  24. package/src/components/BaseLink/BaseLink.vue +32 -21
  25. package/src/components/BaseModal/BaseModal.stories.js +4 -7
  26. package/src/components/BaseModal/BaseModal.vue +1 -0
  27. package/src/components/BaseModal/BaseModalDialog.vue +1 -6
  28. package/src/components/BasePill/BasePill.stories.js +2 -22
  29. package/src/components/BasePill/BasePill.vue +36 -17
  30. package/src/components/BasePlaceholder/BasePlaceholder.stories.js +4 -7
  31. package/src/components/BasePlaceholder/BasePlaceholder.vue +1 -1
  32. package/src/components/BaseRadioGroup/BaseRadioGroup.stories.js +1 -0
  33. package/src/components/BaseRadioGroup/BaseRadioGroup.vue +9 -2
  34. package/src/components/BaseSwimlane/BaseSwimlane.stories.js +2 -1
  35. package/src/components/BaseSwimlane/BaseSwimlane.vue +2 -0
  36. package/src/components/BaseTimer/BaseTimer.stories.js +6 -1
  37. package/src/components/BaseTimer/BaseTimer.vue +4 -2
  38. package/src/components/BaseUnitToggle/BaseUnitToggle.stories.js +1 -16
  39. package/src/components/BaseUnitToggle/BaseUnitToggle.vue +4 -0
  40. package/src/components/BaseVideo/BaseVideo.vue +7 -3
  41. package/src/components/BlockAccordion/BlockAccordion.stories.js +1 -1
  42. package/src/components/BlockAccordion/BlockAccordion.vue +3 -3
  43. package/src/components/BlockAudio/BlockAudio.stories.js +1 -0
  44. package/src/components/BlockAudio/BlockAudio.vue +11 -3
  45. package/src/components/BlockCardGrid/BlockCardGrid.stories.js +1 -1
  46. package/src/components/BlockCardGrid/BlockCardGrid.vue +1 -1
  47. package/src/components/BlockCardGridItem/BlockCardGridItem.stories.js +1 -1
  48. package/src/components/BlockCircleImageCard/BlockCircleImageCard.stories.js +1 -8
  49. package/src/components/BlockCsrTable/BlockCsrTable.stories.js +1 -0
  50. package/src/components/BlockCsrTable/BlockCsrTable.vue +1 -1
  51. package/src/components/BlockCta/BlockCta.stories.js +1 -0
  52. package/src/components/BlockCta/BlockCta.vue +9 -2
  53. package/src/components/BlockDialog/BlockDialog.stories.js +2 -1
  54. package/src/components/BlockGist/BlockGist.stories.js +3 -2
  55. package/src/components/BlockGist/BlockGist.vue +8 -6
  56. package/src/components/BlockHeading/BlockHeading.stories.js +1 -0
  57. package/src/components/BlockIframeEmbed/BlockIframeEmbed.stories.js +1 -0
  58. package/src/components/BlockIframeEmbed/BlockIframeEmbed.vue +9 -2
  59. package/src/components/BlockImage/BlockImage.stories.js +1 -5
  60. package/src/components/BlockImage/BlockImage.vue +5 -2
  61. package/src/components/BlockImageCarousel/BlockImageCarousel.stories.js +1 -13
  62. package/src/components/BlockImageCarousel/BlockImageCarousel.vue +2 -0
  63. package/src/components/BlockImageCarouselItem/BlockImageCarouselItem.stories.js +0 -14
  64. package/src/components/BlockImageCarouselItem/BlockImageCarouselItem.vue +7 -7
  65. package/src/components/BlockImageComparison/BlockImageComparison.stories.js +3 -1
  66. package/src/components/BlockImageComparison/BlockImageComparison.vue +11 -2
  67. package/src/components/BlockImageGallery/BlockImageGallery.stories.js +2 -9
  68. package/src/components/BlockImageGallery/BlockImageGallery.vue +5 -0
  69. package/src/components/BlockInlineImage/BlockInlineImage.stories.js +1 -8
  70. package/src/components/BlockInlineImage/BlockInlineImage.vue +20 -7
  71. package/src/components/BlockKeyPoints/BlockKeyPoints.stories.js +1 -0
  72. package/src/components/BlockKeyPoints/BlockKeyPoints.vue +12 -3
  73. package/src/components/BlockLinkCard/BlockLinkCard.stories.js +5 -18
  74. package/src/components/BlockLinkCard/BlockLinkCard.vue +27 -8
  75. package/src/components/BlockLinkCard/BlockLinkCardCollectionLg.vue +2 -2
  76. package/src/components/BlockLinkCardList/BlockLinkCardList.stories.js +1 -3
  77. package/src/components/BlockLinkCarousel/BlockLinkCarousel.stories.js +2 -14
  78. package/src/components/BlockLinkCarousel/BlockLinkCarousel.vue +8 -8
  79. package/src/components/BlockLinkTile/BlockLinkTile.stories.js +1 -11
  80. package/src/components/BlockLinkTile/BlockLinkTile.vue +26 -13
  81. package/src/components/BlockListCards/BlockListCards.stories.js +1 -0
  82. package/src/components/BlockListCards/BlockListCards.vue +5 -4
  83. package/src/components/BlockNewsletterSignup/BlockNewsletterSignup.stories.js +1 -0
  84. package/src/components/BlockNewsletterSignup/BlockNewsletterSignup.vue +3 -2
  85. package/src/components/BlockQuote/BlockQuote.stories.js +1 -0
  86. package/src/components/BlockQuote/BlockQuote.vue +3 -2
  87. package/src/components/BlockRelatedLinks/BlockRelatedLinks.stories.js +1 -0
  88. package/src/components/BlockRelatedLinks/BlockRelatedLinks.vue +6 -4
  89. package/src/components/BlockRichTable/BlockRichTable.stories.js +1 -1
  90. package/src/components/BlockRichTable/BlockRichTable.vue +23 -9
  91. package/src/components/BlockStreamfield/BlockStreamfield.stories.js +1 -11
  92. package/src/components/BlockStreamfield/BlockStreamfield.vue +34 -31
  93. package/src/components/BlockTeaser/BlockTeaser.stories.js +1 -0
  94. package/src/components/BlockTeaser/BlockTeaser.vue +20 -12
  95. package/src/components/BlockText/BlockText.stories.js +2 -9
  96. package/src/components/BlockText/BlockText.vue +21 -9
  97. package/src/components/BlockVideo/BlockVideo.stories.js +1 -0
  98. package/src/components/BlockVideo/BlockVideo.vue +14 -3
  99. package/src/components/BlockVideoEmbed/BlockVideoEmbed.stories.js +1 -0
  100. package/src/components/BlockVideoEmbed/BlockVideoEmbed.vue +6 -3
  101. package/src/components/CalendarButton/CalendarButton.vue +7 -0
  102. package/src/components/DetailHeadline/DetailHeadline.stories.js +2 -20
  103. package/src/components/DetailHeadline/DetailHeadline.vue +16 -4
  104. package/src/components/DsnWidget/DsnWidget.stories.js +2 -6
  105. package/src/components/DsnWidget/DsnWidget.vue +18 -4
  106. package/src/components/EventDetailHero/EventDetailHero.vue +4 -7
  107. package/src/components/FormContact/FormContact.stories.js +2 -1
  108. package/src/components/FormNewsletterSignup/FormNewsletterSignup.stories.js +2 -1
  109. package/src/components/HeroInlineMedia/HeroInlineMedia.vue +12 -8
  110. package/src/components/HeroLarge/HeroLarge.stories.js +1 -0
  111. package/src/components/HeroLarge/HeroLarge.vue +12 -7
  112. package/src/components/HeroListingIndex/HeroListingIndex.stories.js +1 -0
  113. package/src/components/HeroListingIndex/HeroListingIndex.vue +18 -13
  114. package/src/components/HeroMedia/HeroMedia.stories.js +13 -8
  115. package/src/components/HeroMedia/HeroMedia.vue +9 -8
  116. package/src/components/HeroMedium/HeroMedium.stories.js +1 -0
  117. package/src/components/HeroMedium/HeroMedium.vue +32 -14
  118. package/src/components/HeroMedium/HeroSmall.stories.js +2 -2
  119. package/src/components/HomepageCarousel/HomepageCarousel.stories.js +1 -1
  120. package/src/components/HomepageCarouselItem/HomepageCarouselItem.vue +2 -6
  121. package/src/components/HomepageEmbedBlock/HomepageEmbedBlock.vue +2 -2
  122. package/src/components/LogoCaltech/LogoCaltech.stories.js +14 -18
  123. package/src/components/LogoCaltech/LogoCaltech.vue +1 -0
  124. package/src/components/LogoTribrand/LogoTribrand.stories.js +66 -51
  125. package/src/components/LogoTribrand/LogoTribrand.vue +4 -2
  126. package/src/components/MetaPanel/MetaPanel.stories.js +4 -8
  127. package/src/components/MetaPanel/MetaPanel.vue +3 -0
  128. package/src/components/MetaPanelItems/MetaPanelItems.stories.js +9 -2
  129. package/src/components/MetaPanelItems/MetaPanelItems.vue +2 -0
  130. package/src/components/MetadataEduResource/MetadataEduResource.stories.js +12 -10
  131. package/src/components/MetadataEduResource/MetadataEduResource.vue +7 -3
  132. package/src/components/MetadataEvent/MetadataEvent.stories.js +1 -1
  133. package/src/components/MissionDetailAbout/MissionDetailAbout.vue +1 -1
  134. package/src/components/MissionDetailHighlights/MissionDetailHighlights.stories.js +1 -0
  135. package/src/components/MissionDetailInlineImage/MissionDetailInlineImage.stories.js +1 -6
  136. package/src/components/MissionDetailInlineImage/MissionDetailInlineImage.vue +10 -5
  137. package/src/components/MissionDetailStats/DistanceStats.vue +10 -5
  138. package/src/components/MissionDetailStats/MissionDetailStats.stories.js +2 -19
  139. package/src/components/MissionDetailStats/MissionDetailStats.vue +21 -5
  140. package/src/components/MissionDetailStreamfield/MissionDetailStreamfield.vue +4 -2
  141. package/src/components/MixinAnimationCaret/MixinAnimationCaret.stories.ts +7 -0
  142. package/src/components/MixinAnimationCaret/MixinAnimationCaret.vue +12 -6
  143. package/src/components/MixinCarousel/MixinCarousel.stories.js +2 -8
  144. package/src/components/MixinCarousel/MixinCarousel.vue +13 -16
  145. package/src/components/MixinVideoBg/MixinVideoBg.stories.js +1 -1
  146. package/src/components/MixinVideoBg/MixinVideoBg.vue +4 -7
  147. package/src/components/NavDesktop/NavDesktop.stories.js +1 -0
  148. package/src/components/NavDesktop/NavDesktop.vue +4 -4
  149. package/src/components/NavDesktop/NavDesktopTopHat.vue +4 -4
  150. package/src/components/NavDesktopEdu/NavDesktopEdu.stories.js +1 -5
  151. package/src/components/NavDesktopEdu/NavDesktopEdu.vue +4 -4
  152. package/src/components/NavHeading/NavHeading.stories.js +1 -0
  153. package/src/components/NavHighlight/NavHighlight.stories.js +1 -0
  154. package/src/components/NavJumpMenu/NavJumpMenu.stories.js +5 -2
  155. package/src/components/NavLinkList/NavLinkList.stories.js +1 -0
  156. package/src/components/NavLinkList/NavLinkList.vue +3 -3
  157. package/src/components/NavLogoLinks/NavLogoLinks.stories.js +1 -0
  158. package/src/components/NavMobile/NavMobile.stories.js +9 -3
  159. package/src/components/NavMobile/NavMobile.vue +18 -5
  160. package/src/components/NavMobile/NavMobileDropdown.vue +2 -2
  161. package/src/components/NavMobile/NavMobileEdu.stories.js +3 -2
  162. package/src/components/NavMobile/NavMobileLink.vue +4 -4
  163. package/src/components/NavSearchForm/NavSearchForm.stories.js +1 -0
  164. package/src/components/NavSecondary/NavSecondary.stories.js +1 -0
  165. package/src/components/NavSecondary/NavSecondary.vue +7 -4
  166. package/src/components/NavSecondary/NavSecondaryDropdownContent.vue +1 -1
  167. package/src/components/NavSocial/NavSocial.stories.js +1 -0
  168. package/src/components/NewsDetailMediaContact/NewsDetailMediaContact.stories.js +2 -1
  169. package/src/components/NewsDetailMediaContact/NewsDetailMediaContact.vue +1 -1
  170. package/src/components/ParallaxContainer/ParallaxContainer.vue +1 -0
  171. package/src/components/PodcastSeriesCarousel/PodcastSeriesCarousel.vue +6 -5
  172. package/src/components/RoboticsDetailStats/RoboticsDetailStats.stories.js +1 -6
  173. package/src/components/SearchFilterGroup/SearchFilterGroup.stories.js +1 -0
  174. package/src/components/SearchInput/SearchInput.stories.js +1 -0
  175. package/src/components/SearchPagination/SearchPagination.stories.js +1 -0
  176. package/src/components/SearchResultCard/SearchResultCard.stories.js +1 -10
  177. package/src/components/SearchResultCard/SearchResultCard.vue +1 -0
  178. package/src/components/SearchResultGridItem/SearchResultGridItem.stories.js +1 -10
  179. package/src/components/SearchResultGridItem/SearchResultGridItem.vue +5 -2
  180. package/src/components/SearchResultsList/SearchResultsList.stories.js +1 -1
  181. package/src/components/SearchSelectMenu/SearchSelectMenu.stories.js +2 -1
  182. package/src/components/SwimlaneCTA/SwimlaneCTA.vue +1 -0
  183. package/src/components/TextArea/TextArea.stories.js +2 -1
  184. package/src/components/TextInput/TextInput.stories.js +2 -1
  185. package/src/components/TheFooter/TheFooter.stories.js +1 -0
  186. package/src/components/TheFooter/TheFooter.vue +30 -4
  187. package/src/components/ThumbnailCarousel/ThumbnailCarousel.stories.js +1 -1
  188. package/src/components/ThumbnailCarousel/ThumbnailCarousel.vue +2 -1
  189. package/src/components/TimelineDialog/TimelineDialog.vue +2 -2
  190. package/src/components/TopicDetailMissionCarousel/TopicDetailMissionCarousel.stories.js +1 -0
  191. package/src/components/TopicDetailMore/TopicDetailMore.stories.js +1 -0
  192. package/src/components/TopicDetailMoreItem/TopicDetailMoreItem.stories.js +1 -0
  193. package/src/components/TopicDetailStreamfield/TopicDetailStreamfield.vue +2 -2
  194. package/src/constants.ts +3 -5
  195. package/src/interfaces.ts +31 -6
  196. package/src/templates/PageAudioDetail/PageAudioDetail.vue +2 -2
  197. package/src/templates/edu/PageEduGalleryDetail/PageEduGalleryDetail.vue +10 -6
  198. package/src/templates/edu/PageEduStudentProject/PageEduStudentProjectSection.vue +10 -6
  199. package/src/templates/www/PageTopicDetail/PageTopicDetail.vue +2 -1
  200. package/src/utils/mixins.ts +7 -7
@@ -1,52 +1,64 @@
1
1
  <script lang="ts">
2
- import { defineComponent } from 'vue'
3
- import type { PropType } from 'vue'
2
+ /**
3
+ * The BaseImage component is a simple `<img />` tag wrapped in a `<div>`
4
+ * and is used to render an image with object-fit classes and lazy loading properties.
5
+ */
4
6
 
5
- export type ImageLoader = 'lazy' | 'eager' | undefined
7
+ import { defineComponent, type PropType } from 'vue'
6
8
 
7
- interface ObjectFitClasses {
8
- [key: string]: string
9
- }
10
-
11
- export const objectFitClasses: ObjectFitClasses = {
9
+ type ImageLoader = 'lazy' | 'eager' | undefined
10
+ const objectFitClasses = {
12
11
  none: 'object-none',
13
12
  contain: 'object-contain',
14
13
  cover: 'object-cover',
15
14
  fill: 'object-fill',
16
15
  scaleDown: 'object-scale-down'
17
- }
16
+ } as const
17
+ type ObjectFitClassesKey = keyof typeof objectFitClasses
18
18
 
19
19
  export default defineComponent({
20
20
  name: 'BaseImage',
21
21
  props: {
22
+ /** CSS classes to apply directory to the `<img>` element */
22
23
  imageClass: {
23
24
  type: String,
24
- required: false
25
+ required: false,
26
+ default: ''
25
27
  },
28
+ /** Tailwind CSS object fit classes to specify how the image will scale within `BaseImagePlaceholder` */
26
29
  objectFitClass: {
27
- type: String,
30
+ type: String as PropType<ObjectFitClassesKey>,
28
31
  required: false,
29
32
  default: 'contain',
30
33
  validator: (prop: string): boolean => Object.keys(objectFitClasses).includes(prop)
31
34
  },
35
+ /** `<img> src` attribute */
32
36
  src: {
33
37
  type: String,
34
38
  required: true
35
39
  },
40
+ /** `<img> srcset` attribute */
36
41
  srcset: {
37
42
  type: String,
38
43
  required: false,
39
44
  default: ''
40
45
  },
46
+ /** `<img> alt` attribute */
41
47
  alt: {
42
- type: String
48
+ type: String,
49
+ default: ''
43
50
  },
51
+ /** `<img> width` attribute */
44
52
  width: {
45
- type: [Number, String]
53
+ type: [Number, String],
54
+ default: ''
46
55
  },
56
+ /** `<img> height` attribute */
47
57
  height: {
48
- type: [Number, String]
58
+ type: [Number, String],
59
+ default: ''
49
60
  },
61
+ /** `<img> loading` attribute */
50
62
  loading: {
51
63
  type: String as PropType<ImageLoader>,
52
64
  required: false,
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
- import { defineComponent } from 'vue'
3
- import type { PropType } from 'vue'
4
- import type { ImageObject } from '../../interfaces'
2
+ /** Caption text used with both images and videos. */
3
+
4
+ import { defineComponent, type PropType } from 'vue'
5
+ import type { ImageObject, VideoObject } from '../../interfaces'
5
6
  import BaseLink from './../BaseLink/BaseLink.vue'
6
7
 
7
8
  export default defineComponent({
@@ -10,15 +11,18 @@ export default defineComponent({
10
11
  BaseLink
11
12
  },
12
13
  props: {
14
+ /** `{ImageObject}` data */
13
15
  data: {
14
- type: Object as PropType<Partial<ImageObject>>,
15
- required: true,
16
- default: undefined
16
+ // type: Object as PropType<<PartialImageObject>>,
17
+ type: Object as PropType<Partial<ImageObject> | Partial<VideoObject> | any>,
18
+ required: true
17
19
  },
20
+ /** Appends a link to the end of the caption. Overrides "Full Image Details" link, if it exists. */
18
21
  customLink: {
19
22
  type: String,
20
23
  default: undefined
21
24
  },
25
+ /** Text for the custom link. Does not appear if `customLink` is blank */
22
26
  customLinkText: {
23
27
  type: String,
24
28
  default: 'Custom Link'
@@ -1,5 +1,5 @@
1
1
  import BaseImage from './../BaseImage/BaseImage.vue'
2
- import BaseImagePlaceholder, { aspectRatios } from './BaseImagePlaceholder.vue'
2
+ import BaseImagePlaceholder from './BaseImagePlaceholder.vue'
3
3
  export default {
4
4
  title: 'Components/Base/BaseImagePlaceholder',
5
5
  component: BaseImagePlaceholder,
@@ -21,21 +21,9 @@ export default {
21
21
  },
22
22
  docs: {
23
23
  description: {
24
- component:
25
- 'Aspect ratio CSS class. View dropdown to see all options. More classes can be added in `/src/scss/_aspect-ratios.scss`'
24
+ component: 'Placeholder image component with aspect ratio and background controls'
26
25
  }
27
26
  }
28
- },
29
- argTypes: {
30
- aspectRatio: {
31
- control: { type: 'select' },
32
- options: Object.keys(aspectRatios)
33
- },
34
- responsiveAspectRatio: {
35
- description:
36
- 'Custom tailwind classes to combine screen-size directives with aspect ratios. Example: `md:aspect-ratio-four-three lg:aspect-ratio-twelve-nine`. Overrides `aspectRatio` setting.',
37
- control: { type: 'text' }
38
- }
39
27
  }
40
28
  }
41
29
 
@@ -76,8 +64,7 @@ export const BaseStory = {
76
64
  objectFitClass: 'scaleDown',
77
65
  loading: ''
78
66
  },
79
-
80
- noLogo: true,
67
+ noLogo: false,
81
68
  aspectRatio: '16:9',
82
69
  responsiveAspectRatio: 'md:aspect-ratio-four-three lg:aspect-ratio-twelve-nine'
83
70
  }
@@ -1,11 +1,8 @@
1
1
  <script lang="ts">
2
- import { defineComponent } from 'vue'
2
+ import { defineComponent, type PropType } from 'vue'
3
+ /** Placeholder image component with aspect ratio and background controls */
3
4
 
4
- interface AspectRatios {
5
- [key: string]: string
6
- }
7
-
8
- export const aspectRatios: AspectRatios = {
5
+ export const aspectRatios = {
9
6
  none: 'aspect-ratio-none',
10
7
  portrait: 'aspect-ratio-four-five',
11
8
  square: 'aspect-ratio-square',
@@ -22,33 +19,40 @@ export const aspectRatios: AspectRatios = {
22
19
  '16:7': 'aspect-ratio-sixteen-seven',
23
20
  '16:9': 'aspect-ratio-sixteen-nine',
24
21
  '21:9': 'aspect-ratio-twentyone-nine'
25
- }
22
+ } as const
23
+ type AspectRatiosKey = keyof typeof aspectRatios
26
24
 
27
25
  export default defineComponent({
28
26
  name: 'BaseImagePlaceholder',
29
27
  props: {
28
+ /** If the placeholder background should be dark */
30
29
  darkMode: {
31
30
  type: Boolean,
32
31
  required: false,
33
32
  default: true
34
33
  },
34
+ /** If the placeholder background should be transparent (ovverrides `darkMode`) */
35
35
  transparentMode: {
36
36
  type: Boolean,
37
37
  required: false,
38
38
  default: false
39
39
  },
40
+ /** If the JPL logo should not appear in the background of the placeholder */
40
41
  noLogo: {
41
42
  type: Boolean,
42
43
  default: false
43
44
  },
45
+ /** Desired aspect ratio of image. If the contained image doesn't match, it will be adjusted to fit within the selected aspect ratio */
44
46
  aspectRatio: {
45
- type: String,
47
+ type: String as PropType<AspectRatiosKey>,
46
48
  default: 'none',
47
49
  validator: (prop: string): boolean => Object.keys(aspectRatios).includes(prop)
48
50
  },
51
+ /** Custom tailwind classes to combine screen-size directives with aspect ratios.
52
+ * Example: `md:aspect-ratio-four-three lg:aspect-ratio-twelve-nine`. Overrides `aspectRatio` setting. */
49
53
  responsiveAspectRatio: {
50
54
  type: String,
51
- required: false
55
+ default: ''
52
56
  }
53
57
  },
54
58
  computed: {
@@ -1,4 +1,4 @@
1
- import BaseLink, { variants } from './BaseLink.vue'
1
+ import BaseLink from './BaseLink.vue'
2
2
  export default {
3
3
  title: 'Components/Base/BaseLink',
4
4
  component: BaseLink,
@@ -8,54 +8,12 @@ export default {
8
8
  }
9
9
  },
10
10
  argTypes: {
11
- variant: {
12
- control: { type: 'select' },
13
- options: Object.keys(variants),
14
- description: 'Preset variants'
15
- },
16
- to: {
17
- description: 'If populated, a router-link will be generated. Overrides `href`'
18
- },
11
+ // JSDoc comments for these events aren't working, so we're setting them here
19
12
  linkClicked: {
20
- type: '@click emit',
21
- description: 'Event emitted at the root-level (globally available)'
13
+ description: 'Click event emitted at the root-level (globally available)'
22
14
  },
23
15
  specificLinkClicked: {
24
- type: '@click emit',
25
- description: 'Locally emitted event (includes event attributes)'
26
- },
27
- linkClass: {
28
- description: 'Apply classes directly to the `<a>` element.'
29
- },
30
- externalTargetBlank: {
31
- description: 'Autmatically sets target to `_blank` for external (non-router) links.'
32
- },
33
- exact: {
34
- description:
35
- "Maps to the `exact` prop in Nuxt's native `NuxtLink` component. If `true`, `active-class` will be applied to the link only if the current path is an exact match. Only affects router links."
36
- },
37
- usePrimaryColor: {
38
- type: 'boolean',
39
- description: "Overrides the theme's `active` color and uses the `primary` color instead."
40
- },
41
- caret: {
42
- description:
43
- 'If a caret icon should be appended to the link. Set automatically when using the `primary` link variant.'
44
- },
45
- caretColor: {
46
- control: { type: 'text' },
47
- description: 'Tailwind text color class for the caret. Ex: `text-primary`'
48
- },
49
- caretWrapperClass: {
50
- description: 'Add classes to the caret wrapper'
51
- },
52
- caretClass: {
53
- description:
54
- "Apply classes directly to the caret. Maps to `MixinAnimationCaret`'s `arrowClass` prop."
55
- },
56
- caretInline: { description: 'Apply `inline` class to the caret wrapper' },
57
- caretMarginLeft: {
58
- description: 'Customize the left margin of the caret using Tailwind classes.'
16
+ description: 'Locally emitted click event (includes event attributes)'
59
17
  }
60
18
  },
61
19
  excludeStories: /.*Data$/
@@ -1,46 +1,47 @@
1
1
  <script lang="ts">
2
- import { defineComponent } from 'vue'
2
+ import { defineComponent, type PropType } from 'vue'
3
3
  import { mapStores } from 'pinia'
4
4
  import { useThemeStore } from '../../store/theme'
5
5
  import { eventBus } from './../../utils/eventBus'
6
6
  import MixinAnimationCaret from './../MixinAnimationCaret/MixinAnimationCaret.vue'
7
7
  import { isEduExternalLink } from './../../utils/isEduExternalLink'
8
8
 
9
- interface Variants {
10
- [key: string]: string
11
- }
12
-
13
- export const variants: Variants = {
9
+ const variants = {
14
10
  primary: 'text-subtitle text-action can-hover:hover:text-action-dark',
15
11
  secondary: 'text-subtitle text-action can-hover:hover:text-action-dark',
16
12
  default: '-default underline text-action can-hover:hover:text-action-dark',
17
13
  none: ''
18
- }
19
- export const primaryColorVariants: Variants = {
14
+ } as const
15
+ type VariantsKey = keyof typeof variants
16
+
17
+ const primaryColorVariants = {
20
18
  primary: 'text-subtitle text-primary can-hover:hover:text-primary-dark',
21
19
  secondary: 'text-subtitle text-primary can-hover:hover:text-primary-dark',
22
20
  default: '-default underline text-primary can-hover:hover:text-primary-dark',
23
21
  none: ''
24
- }
22
+ } as const
25
23
 
26
24
  export default defineComponent({
27
- // this component is useful when you need a link that can either be an 'a' or router link
28
- // falls back to a <div> if no url is provided
25
+ /** this component is useful when you need a link that can either be an 'a' or router link.
26
+ * falls back to a <div> if no url is provided
27
+ */
29
28
  name: 'BaseLink',
30
29
  components: {
31
30
  MixinAnimationCaret
32
31
  },
33
32
  props: {
34
33
  variant: {
35
- type: String,
34
+ type: String as PropType<VariantsKey>,
36
35
  required: false,
37
36
  default: 'default',
38
37
  validator: (prop: string): boolean => Object.keys(variants).includes(prop)
39
38
  },
39
+ /** If populated, a router-link will be generated. Overrides `href` */
40
40
  to: {
41
41
  type: [String, Object],
42
42
  default: undefined
43
43
  },
44
+ /** Maps to the `exact` prop in Nuxt's native `NuxtLink` component. If `true`, `active-class` will be applied to the link only if the current path is an exact match. Only affects router links. */
44
45
  exact: {
45
46
  type: Boolean,
46
47
  default: false
@@ -57,65 +58,73 @@ export default defineComponent({
57
58
  type: String,
58
59
  default: ''
59
60
  },
61
+ /** Apply classes directly to the `<a>` element */
60
62
  linkClass: {
61
63
  type: String,
62
64
  default: ''
63
65
  },
64
- // this will always override the target
66
+ /** This setting will always override the target, regardless of external link settings */
65
67
  target: {
66
68
  type: String,
67
69
  required: false,
68
70
  default: undefined
69
71
  },
70
- // if external links should open in a new window
72
+ /** Autmatically sets target to `_blank` for external (non-router) links */
71
73
  externalTargetBlank: {
72
74
  type: Boolean,
73
75
  required: false,
74
76
  default: false
75
77
  },
76
- // the 'primary' variant will always have the caret
78
+ /** 'If a caret icon should be appended to the link. Set automatically when using the `primary` link variant. */
77
79
  caret: {
78
80
  type: Boolean,
79
81
  required: false,
80
82
  default: false
81
83
  },
82
- // Class applied to the overall MixinAnimationCaret component
84
+ /** Add classes to the caret wrapper */
83
85
  caretWrapperClass: {
84
86
  type: String,
85
87
  default: ''
86
88
  },
87
- // Class applied to the caret itself
89
+ /** Add classes directly to the caret. Maps to `MixinAnimationCaret`'s `arrowClass` prop. */
88
90
  caretClass: {
89
91
  type: String,
90
92
  default: ''
91
93
  },
92
- // if caret should be displayed inline with text
94
+ /** Apply `inline` class to the caret wrapper */
93
95
  caretInline: {
94
96
  type: Boolean,
95
97
  required: false,
96
98
  default: false
97
99
  },
98
- // to customize the caret color. also works with group-hover
100
+ /** Tailwind CSS text color class for the caret. Ex: `text-primary` */
99
101
  caretColor: {
100
102
  type: String,
101
103
  required: false,
102
104
  default: ''
103
105
  },
106
+ /** Customize the left margin of the caret using Tailwind classes */
104
107
  caretMarginLeft: {
105
108
  type: String,
106
109
  required: false,
107
110
  default: ''
108
111
  },
112
+ /** Overrides the theme's `active` color and uses the `primary` color instead. */
109
113
  usePrimaryColor: {
110
114
  type: Boolean,
111
115
  required: false,
112
116
  default: false
113
117
  }
114
118
  },
115
- emits: ['linkClicked', 'specificLinkClicked'],
119
+ emits: [
120
+ /** Apply classes directly to the `<a>` element. */
121
+ 'linkClicked',
122
+ /** Locally emitted click event (includes event attributes) */
123
+ 'specificLinkClicked'
124
+ ],
116
125
  computed: {
117
126
  ...mapStores(useThemeStore),
118
- computedVariants(): Variants {
127
+ computedVariants() {
119
128
  if (this.usePrimaryColor) {
120
129
  return primaryColorVariants
121
130
  }
@@ -131,12 +140,14 @@ export default defineComponent({
131
140
  }
132
141
  return classes
133
142
  },
143
+ /** If the href link is an external link relative to the EDU site */
134
144
  isEduExternal(): boolean | string {
135
145
  if (this.href) {
136
146
  return isEduExternalLink(this.href)
137
147
  }
138
148
  return ''
139
149
  },
150
+ /** If the href is an external link (takes theme and `isEduExternal` into account) */
140
151
  isExternal(): boolean {
141
152
  if (this.href) {
142
153
  if (this.themeStore.isEdu && isEduExternalLink(this.href)) {
@@ -5,9 +5,6 @@ import BaseModalDialog from './BaseModalDialog.vue'
5
5
  export default {
6
6
  title: 'Components/Base/BaseModal',
7
7
  component: BaseModal,
8
- argTypes: {
9
- bgClose: { control: { type: 'boolean' } }
10
- },
11
8
  excludeStories: /.*Data$/
12
9
  }
13
10
 
@@ -15,7 +12,7 @@ export default {
15
12
  const BaseModalTemplate = (args) => ({
16
13
  props: Object.keys(args),
17
14
  components: { BaseModal },
18
- template: `<BaseModal :bg-close="bgClose"><div>Modal content. Lorem ipsum dolor sit amet.</div></BaseModal>`
15
+ template: `<BaseModal :bg-close="bgClose"><div>{{ bgClose }} Modal content. Lorem ipsum dolor sit amet.</div></BaseModal>`
19
16
  })
20
17
  const BaseModalWithTriggerTemplate = (args) => ({
21
18
  props: Object.keys(args),
@@ -72,13 +69,13 @@ export const BaseModalDialogData = {
72
69
 
73
70
  // stories
74
71
  export const BaseStory = BaseModalTemplate.bind({})
75
- BaseStory.args = { ...BaseModalData }
72
+ BaseStory.args = BaseModalData
76
73
 
77
74
  export const CustomTrigger = BaseModalWithTriggerTemplate.bind({})
78
- CustomTrigger.args = { ...BaseModalData }
75
+ CustomTrigger.args = BaseModalData
79
76
 
80
77
  export const Nested = BaseModalNested.bind({})
81
- Nested.args = { ...BaseModalData }
78
+ Nested.args = BaseModalData
82
79
 
83
80
  export const Dialog = BaseModalDialogTemplate.bind({})
84
81
  Dialog.args = { ...BaseModalDialogData, modalHeaderSlot: '' }
@@ -26,6 +26,7 @@ export default defineComponent({
26
26
  BaseModalDialog
27
27
  },
28
28
  props: {
29
+ /** If clicking on the background should close the modal. Note: doesn't have an affect within Storybook */
29
30
  bgClose: {
30
31
  type: Boolean,
31
32
  default: false
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div
3
3
  class="bg-gray-dark fixed top-0 left-0 z-50 flex w-full h-full overflow-auto bg-opacity-75"
4
- @click="bgCloseModal"
4
+ @click="bgClose ? closeModal() : null"
5
5
  >
6
6
  <div
7
7
  class="relative w-full p-8 m-auto bg-white"
@@ -54,11 +54,6 @@ export default defineComponent({
54
54
  methods: {
55
55
  closeModal() {
56
56
  this.$emit('close')
57
- },
58
- bgCloseModal() {
59
- if (this.bgClose) {
60
- this.closeModal()
61
- }
62
57
  }
63
58
  }
64
59
  })
@@ -1,28 +1,8 @@
1
1
  import BasePill from './BasePill.vue'
2
- import { eduMetadataDictionary } from './../../constants'
3
2
 
4
3
  export default {
5
4
  title: 'Components/Base/BasePill',
6
- component: BasePill,
7
- argTypes: {
8
- variant: {
9
- type: { name: 'string', required: false },
10
- description: 'The variant (color) of the pill',
11
- control: { type: 'select' },
12
- options: ['primary', 'secondary', 'action']
13
- },
14
- size: {
15
- type: { name: 'string', required: false },
16
- description: 'The size of the pill',
17
- control: { type: 'select' },
18
- options: ['sm', 'md', 'lg']
19
- },
20
- contentType: {
21
- control: { type: 'select' },
22
- options: Object.keys(eduMetadataDictionary),
23
- description: 'Maps to EDU Resource types. Must use `ThemeEdu` to have an effect.'
24
- }
25
- }
5
+ component: BasePill
26
6
  }
27
7
 
28
8
  // stories
@@ -31,7 +11,7 @@ export const PrimaryMedium = {
31
11
  size: 'md',
32
12
  variant: 'primary',
33
13
  text: 'Psyche Asteroid',
34
- contentType: 'EDULessonPage'
14
+ contentType: undefined
35
15
  }
36
16
  }
37
17
 
@@ -1,34 +1,53 @@
1
1
  <script setup lang="ts">
2
2
  import { computed } from 'vue'
3
- import type { Attributes } from './../../interfaces'
3
+ import type { ContentTypeKey } from './../../interfaces.ts'
4
4
  import { eduMetadataDictionary } from './../../constants'
5
5
 
6
6
  // using borders to vertically center wonky font face
7
- const variantMap: Attributes = {
7
+ const variantMap = {
8
8
  primary: 'bg-primary border-primary',
9
9
  'primary-inverted': 'bg-gray-light-mid !text-primary-darker border-gray-light-mid',
10
10
  secondary: 'bg-secondary border-secondary',
11
11
  action: 'bg-action border-action'
12
- }
12
+ } as const
13
+ type VariantMapKey = keyof typeof variantMap
13
14
 
14
- const sizeMap: Attributes = {
15
+ const sizeMap = {
15
16
  sm: 'text-xs border-t-2 py-1 px-2.5',
16
17
  md: 'text-xs lg:text-base border-t py-1.5 px-3.5',
17
18
  lg: 'text-base lg:text-lg border-t pt-1.5 pb-1 px-5'
18
- }
19
+ } as const
20
+ type SizeMapKey = keyof typeof sizeMap
19
21
 
20
- interface BasePillProps {
21
- text?: string
22
- variant?: string
23
- size?: string
24
- contentType?: string
25
- }
26
-
27
- // define props
28
- const props = withDefaults(defineProps<BasePillProps>(), {
29
- variant: 'primary',
30
- size: 'md',
31
- contentType: undefined
22
+ const props = defineProps({
23
+ /**
24
+ * The text contained in the pill. Plain text only.
25
+ */
26
+ text: {
27
+ type: String,
28
+ default: undefined
29
+ },
30
+ /**
31
+ * The variant (color) of the pill
32
+ */
33
+ variant: {
34
+ type: String as () => VariantMapKey,
35
+ default: 'primary'
36
+ },
37
+ /**
38
+ * The size of the pill
39
+ */
40
+ size: {
41
+ type: String as () => SizeMapKey,
42
+ default: 'md'
43
+ },
44
+ /**
45
+ * Maps to EDU Resource types. Must use `ThemeEdu` to affect color.
46
+ */
47
+ contentType: {
48
+ type: String as () => ContentTypeKey,
49
+ default: undefined
50
+ }
32
51
  })
33
52
 
34
53
  const metadataType = computed(() => {
@@ -4,18 +4,16 @@ export default {
4
4
  title: 'Components/Base/BasePlaceholder',
5
5
  component: BasePlaceholder,
6
6
  excludeStories: /.*Data$/,
7
+ tags: ['autodocs', 'listings'],
7
8
  parameters: {
8
9
  docs: {
9
10
  description: {
10
- component: `An animated loading component frequently used as a placeholder for <a href="/story/components-search-searchresultcard--standard-result" target="_blank">SearchResultCard</a>`
11
+ component:
12
+ 'An animated loading component frequently used as a placeholder for <a href="/story/components-search-searchresultcard--standard-result" target="_blank">SearchResultCard</a>'
11
13
  }
12
14
  }
13
15
  }
14
16
  }
15
-
16
- // shared data
17
- const BasePlaceholderData = {}
18
-
19
17
  // templates
20
18
  const BasePlaceholderTemplate = (args) => ({
21
19
  props: Object.keys(args),
@@ -24,5 +22,4 @@ const BasePlaceholderTemplate = (args) => ({
24
22
  })
25
23
 
26
24
  export const BaseStory = BasePlaceholderTemplate.bind({})
27
- BaseStory.storyName = 'BasePlaceholder' // single story hoisting
28
- BaseStory.args = { ...BasePlaceholderData }
25
+ BaseStory.storyName = 'BasePlaceholder'
@@ -19,7 +19,7 @@
19
19
 
20
20
  <script lang="ts">
21
21
  import { defineComponent } from 'vue'
22
-
22
+ /** An animated loading component frequently used as a placeholder for <a href="/story/components-search-searchresultcard--standard-result" target="_blank">SearchResultCard</a> */
23
23
  export default defineComponent({
24
24
  name: 'BasePlaceholder'
25
25
  })
@@ -3,6 +3,7 @@ import BaseRadioGroup from './BaseRadioGroup.vue'
3
3
  export default {
4
4
  title: 'Components/Base/BaseRadioGroup',
5
5
  component: BaseRadioGroup,
6
+ tags: ['autodocs', 'forms'],
6
7
  parameters: {
7
8
  docs: {
8
9
  description: {