@ndla/ui 56.0.154-alpha.0 → 56.0.155-alpha.0

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 (244) hide show
  1. package/dist/panda.buildinfo.json +2 -0
  2. package/dist/styles.css +8 -0
  3. package/es/Article/Article.mjs +8 -1
  4. package/es/Article/Article.mjs.map +1 -1
  5. package/es/Article/ArticleByline.mjs +7 -0
  6. package/es/Article/ArticleByline.mjs.map +1 -1
  7. package/es/Article/ArticleFootNotes.mjs +7 -0
  8. package/es/Article/ArticleFootNotes.mjs.map +1 -1
  9. package/es/Article/BadgesContainer.mjs +7 -0
  10. package/es/Article/BadgesContainer.mjs.map +1 -1
  11. package/es/AudioPlayer/AudioPlayer.mjs +7 -0
  12. package/es/AudioPlayer/AudioPlayer.mjs.map +1 -1
  13. package/es/AudioPlayer/Controls.mjs +7 -0
  14. package/es/AudioPlayer/Controls.mjs.map +1 -1
  15. package/es/AudioPlayer/SpeechControl.mjs +7 -0
  16. package/es/AudioPlayer/SpeechControl.mjs.map +1 -1
  17. package/es/Breadcrumb/HomeBreadcrumb.mjs +7 -0
  18. package/es/Breadcrumb/HomeBreadcrumb.mjs.map +1 -1
  19. package/es/CampaignBlock/CampaignBlock.mjs +7 -0
  20. package/es/CampaignBlock/CampaignBlock.mjs.map +1 -1
  21. package/es/CodeBlock/CodeBlock.mjs +7 -0
  22. package/es/CodeBlock/CodeBlock.mjs.map +1 -1
  23. package/es/Concept/Concept.mjs +7 -0
  24. package/es/Concept/Concept.mjs.map +1 -1
  25. package/es/ContactBlock/ContactBlock.mjs +7 -0
  26. package/es/ContactBlock/ContactBlock.mjs.map +1 -1
  27. package/es/ContentTypeBadge/ContentTypeBadge.mjs +7 -0
  28. package/es/ContentTypeBadge/ContentTypeBadge.mjs.map +1 -1
  29. package/es/CopyParagraphButton/CopyParagraphButton.mjs +7 -0
  30. package/es/CopyParagraphButton/CopyParagraphButton.mjs.map +1 -1
  31. package/es/Embed/AudioEmbed.mjs +7 -0
  32. package/es/Embed/AudioEmbed.mjs.map +1 -1
  33. package/es/Embed/BrightcoveEmbed.mjs +7 -0
  34. package/es/Embed/BrightcoveEmbed.mjs.map +1 -1
  35. package/es/Embed/CodeEmbed.mjs +7 -0
  36. package/es/Embed/CodeEmbed.mjs.map +1 -1
  37. package/es/Embed/ConceptEmbed.mjs +7 -0
  38. package/es/Embed/ConceptEmbed.mjs.map +1 -1
  39. package/es/Embed/ConceptInlineTriggerButton.mjs +7 -0
  40. package/es/Embed/ConceptInlineTriggerButton.mjs.map +1 -1
  41. package/es/Embed/EmbedWrapper.mjs +7 -0
  42. package/es/Embed/EmbedWrapper.mjs.map +1 -1
  43. package/es/Embed/ExternalEmbed.mjs +7 -0
  44. package/es/Embed/ExternalEmbed.mjs.map +1 -1
  45. package/es/Embed/FootnoteEmbed.mjs +7 -0
  46. package/es/Embed/FootnoteEmbed.mjs.map +1 -1
  47. package/es/Embed/GlossEmbed.mjs +7 -0
  48. package/es/Embed/GlossEmbed.mjs.map +1 -1
  49. package/es/Embed/H5pEmbed.mjs +7 -0
  50. package/es/Embed/H5pEmbed.mjs.map +1 -1
  51. package/es/Embed/IframeEmbed.mjs +7 -0
  52. package/es/Embed/IframeEmbed.mjs.map +1 -1
  53. package/es/Embed/ImageEmbed.mjs +13 -6
  54. package/es/Embed/ImageEmbed.mjs.map +1 -1
  55. package/es/Embed/InlineTriggerButton.mjs +7 -0
  56. package/es/Embed/InlineTriggerButton.mjs.map +1 -1
  57. package/es/Embed/RelatedContentEmbed.mjs +9 -7
  58. package/es/Embed/RelatedContentEmbed.mjs.map +1 -1
  59. package/es/Embed/UnknownEmbed.mjs +7 -0
  60. package/es/Embed/UnknownEmbed.mjs.map +1 -1
  61. package/es/FactBox/FactBox.mjs +7 -0
  62. package/es/FactBox/FactBox.mjs.map +1 -1
  63. package/es/FileList/File.mjs +7 -0
  64. package/es/FileList/File.mjs.map +1 -1
  65. package/es/FileList/PdfFile.mjs +7 -0
  66. package/es/FileList/PdfFile.mjs.map +1 -1
  67. package/es/Gloss/Gloss.mjs +7 -0
  68. package/es/Gloss/Gloss.mjs.map +1 -1
  69. package/es/Gloss/GlossExample.mjs +7 -0
  70. package/es/Gloss/GlossExample.mjs.map +1 -1
  71. package/es/KeyFigure/KeyFigure.mjs +7 -0
  72. package/es/KeyFigure/KeyFigure.mjs.map +1 -1
  73. package/es/LicenseByline/EmbedByline.mjs +7 -0
  74. package/es/LicenseByline/EmbedByline.mjs.map +1 -1
  75. package/es/LicenseByline/LicenseLink.mjs +7 -0
  76. package/es/LicenseByline/LicenseLink.mjs.map +1 -1
  77. package/es/LinkBlock/LinkBlock.mjs +7 -0
  78. package/es/LinkBlock/LinkBlock.mjs.map +1 -1
  79. package/es/LinkBlock/LinkBlockSection.mjs +7 -0
  80. package/es/LinkBlock/LinkBlockSection.mjs.map +1 -1
  81. package/es/Pitch/Pitch.mjs +10 -2
  82. package/es/Pitch/Pitch.mjs.map +1 -1
  83. package/es/RelatedArticleList/RelatedArticleList.mjs +13 -8
  84. package/es/RelatedArticleList/RelatedArticleList.mjs.map +1 -1
  85. package/es/ResourceBox/ResourceBox.mjs +7 -0
  86. package/es/ResourceBox/ResourceBox.mjs.map +1 -1
  87. package/es/TagSelector/TagSelector.mjs +7 -0
  88. package/es/TagSelector/TagSelector.mjs.map +1 -1
  89. package/es/ZendeskButton/ZendeskButton.mjs +7 -0
  90. package/es/ZendeskButton/ZendeskButton.mjs.map +1 -1
  91. package/es/i18n/useComponentTranslations.mjs +7 -0
  92. package/es/i18n/useComponentTranslations.mjs.map +1 -1
  93. package/es/index.mjs +1 -1
  94. package/es/locale/messages-en.mjs +7 -0
  95. package/es/locale/messages-en.mjs.map +1 -1
  96. package/es/locale/messages-nb.mjs +7 -0
  97. package/es/locale/messages-nb.mjs.map +1 -1
  98. package/es/locale/messages-nn.mjs +7 -0
  99. package/es/locale/messages-nn.mjs.map +1 -1
  100. package/es/locale/messages-se.mjs +7 -0
  101. package/es/locale/messages-se.mjs.map +1 -1
  102. package/es/model/index.mjs +7 -0
  103. package/es/model/index.mjs.map +1 -1
  104. package/es/utils/licenseAttributes.mjs +7 -0
  105. package/es/utils/licenseAttributes.mjs.map +1 -1
  106. package/lib/Article/Article.js +8 -7
  107. package/lib/Article/Article.js.map +1 -1
  108. package/lib/Article/ArticleByline.js +7 -8
  109. package/lib/Article/ArticleByline.js.map +1 -1
  110. package/lib/Article/ArticleFootNotes.js +7 -3
  111. package/lib/Article/ArticleFootNotes.js.map +1 -1
  112. package/lib/Article/BadgesContainer.js +7 -1
  113. package/lib/Article/BadgesContainer.js.map +1 -1
  114. package/lib/AudioPlayer/AudioPlayer.js +7 -6
  115. package/lib/AudioPlayer/AudioPlayer.js.map +1 -1
  116. package/lib/AudioPlayer/Controls.js +7 -7
  117. package/lib/AudioPlayer/SpeechControl.js +7 -5
  118. package/lib/AudioPlayer/SpeechControl.js.map +1 -1
  119. package/lib/Breadcrumb/Breadcrumb.js +7 -4
  120. package/lib/Breadcrumb/Breadcrumb.js.map +1 -1
  121. package/lib/Breadcrumb/BreadcrumbItem.js +7 -3
  122. package/lib/Breadcrumb/BreadcrumbItem.js.map +1 -1
  123. package/lib/Breadcrumb/HomeBreadcrumb.js +7 -4
  124. package/lib/Breadcrumb/HomeBreadcrumb.js.map +1 -1
  125. package/lib/CampaignBlock/CampaignBlock.js +7 -6
  126. package/lib/CampaignBlock/CampaignBlock.js.map +1 -1
  127. package/lib/CodeBlock/CodeBlock.js +7 -4
  128. package/lib/CodeBlock/CodeBlock.js.map +1 -1
  129. package/lib/Concept/Concept.d.ts +1 -1
  130. package/lib/Concept/Concept.js +7 -4
  131. package/lib/Concept/Concept.js.map +1 -1
  132. package/lib/ContactBlock/ContactBlock.d.ts +2 -2
  133. package/lib/ContactBlock/ContactBlock.js +7 -4
  134. package/lib/ContactBlock/ContactBlock.js.map +1 -1
  135. package/lib/ContentTypeBadge/ContentTypeBadge.js +7 -4
  136. package/lib/ContentTypeBadge/ContentTypeBadge.js.map +1 -1
  137. package/lib/CopyParagraphButton/CopyParagraphButton.js +7 -6
  138. package/lib/CopyParagraphButton/CopyParagraphButton.js.map +1 -1
  139. package/lib/Embed/AudioEmbed.js +7 -3
  140. package/lib/Embed/AudioEmbed.js.map +1 -1
  141. package/lib/Embed/BrightcoveEmbed.js +7 -5
  142. package/lib/Embed/BrightcoveEmbed.js.map +1 -1
  143. package/lib/Embed/CodeEmbed.js +7 -6
  144. package/lib/Embed/CodeEmbed.js.map +1 -1
  145. package/lib/Embed/ConceptEmbed.js +7 -5
  146. package/lib/Embed/ConceptEmbed.js.map +1 -1
  147. package/lib/Embed/ConceptInlineTriggerButton.js +7 -1
  148. package/lib/Embed/ConceptInlineTriggerButton.js.map +1 -1
  149. package/lib/Embed/ContentLinkEmbed.js +0 -3
  150. package/lib/Embed/ContentLinkEmbed.js.map +1 -1
  151. package/lib/Embed/CopyrightEmbed.js +0 -2
  152. package/lib/Embed/CopyrightEmbed.js.map +1 -1
  153. package/lib/Embed/EmbedErrorPlaceholder.js +7 -5
  154. package/lib/Embed/EmbedErrorPlaceholder.js.map +1 -1
  155. package/lib/Embed/EmbedWrapper.js +7 -5
  156. package/lib/Embed/EmbedWrapper.js.map +1 -1
  157. package/lib/Embed/ExternalEmbed.js +7 -5
  158. package/lib/Embed/ExternalEmbed.js.map +1 -1
  159. package/lib/Embed/FootnoteEmbed.js +7 -3
  160. package/lib/Embed/FootnoteEmbed.js.map +1 -1
  161. package/lib/Embed/GlossEmbed.js +7 -5
  162. package/lib/Embed/GlossEmbed.js.map +1 -1
  163. package/lib/Embed/H5pEmbed.js +7 -4
  164. package/lib/Embed/H5pEmbed.js.map +1 -1
  165. package/lib/Embed/IframeEmbed.js +7 -5
  166. package/lib/Embed/IframeEmbed.js.map +1 -1
  167. package/lib/Embed/ImageEmbed.js +13 -12
  168. package/lib/Embed/ImageEmbed.js.map +1 -1
  169. package/lib/Embed/InlineTriggerButton.js +7 -4
  170. package/lib/Embed/InlineTriggerButton.js.map +1 -1
  171. package/lib/Embed/RelatedContentEmbed.d.ts +1 -2
  172. package/lib/Embed/RelatedContentEmbed.js +9 -10
  173. package/lib/Embed/RelatedContentEmbed.js.map +1 -1
  174. package/lib/Embed/UnknownEmbed.js +7 -3
  175. package/lib/Embed/UnknownEmbed.js.map +1 -1
  176. package/lib/Embed/UuDisclaimerEmbed.js +7 -7
  177. package/lib/Embed/types.d.ts +2 -2
  178. package/lib/FactBox/FactBox.js +7 -5
  179. package/lib/FactBox/FactBox.js.map +1 -1
  180. package/lib/FileList/File.js +7 -8
  181. package/lib/FileList/File.js.map +1 -1
  182. package/lib/FileList/FileList.js +7 -4
  183. package/lib/FileList/FileList.js.map +1 -1
  184. package/lib/FileList/PdfFile.js +7 -3
  185. package/lib/FileList/PdfFile.js.map +1 -1
  186. package/lib/Gloss/Gloss.d.ts +2 -2
  187. package/lib/Gloss/Gloss.js +7 -7
  188. package/lib/Gloss/Gloss.js.map +1 -1
  189. package/lib/Gloss/GlossExample.d.ts +2 -2
  190. package/lib/Gloss/GlossExample.js +7 -4
  191. package/lib/Gloss/GlossExample.js.map +1 -1
  192. package/lib/Grid/Grid.js +7 -3
  193. package/lib/Grid/Grid.js.map +1 -1
  194. package/lib/Grid/GridParallaxItem.js +7 -3
  195. package/lib/Grid/GridParallaxItem.js.map +1 -1
  196. package/lib/KeyFigure/KeyFigure.js +7 -2
  197. package/lib/KeyFigure/KeyFigure.js.map +1 -1
  198. package/lib/LicenseByline/EmbedByline.d.ts +4 -4
  199. package/lib/LicenseByline/EmbedByline.js +7 -7
  200. package/lib/LicenseByline/EmbedByline.js.map +1 -1
  201. package/lib/LicenseByline/LicenseLink.js +7 -4
  202. package/lib/LicenseByline/LicenseLink.js.map +1 -1
  203. package/lib/LinkBlock/LinkBlock.js +7 -6
  204. package/lib/LinkBlock/LinkBlock.js.map +1 -1
  205. package/lib/LinkBlock/LinkBlockSection.js +7 -3
  206. package/lib/LinkBlock/LinkBlockSection.js.map +1 -1
  207. package/lib/Pitch/Pitch.js +10 -7
  208. package/lib/Pitch/Pitch.js.map +1 -1
  209. package/lib/RelatedArticleList/RelatedArticleList.d.ts +2 -3
  210. package/lib/RelatedArticleList/RelatedArticleList.js +13 -16
  211. package/lib/RelatedArticleList/RelatedArticleList.js.map +1 -1
  212. package/lib/ResourceBox/ResourceBox.js +7 -6
  213. package/lib/ResourceBox/ResourceBox.js.map +1 -1
  214. package/lib/TagSelector/TagSelector.js +7 -6
  215. package/lib/TagSelector/TagSelector.js.map +1 -1
  216. package/lib/ZendeskButton/ZendeskButton.js +7 -3
  217. package/lib/ZendeskButton/ZendeskButton.js.map +1 -1
  218. package/lib/i18n/useComponentTranslations.js +7 -2
  219. package/lib/i18n/useComponentTranslations.js.map +1 -1
  220. package/lib/index.js +1 -1
  221. package/lib/locale/messages-en.js +7 -1
  222. package/lib/locale/messages-en.js.map +1 -1
  223. package/lib/locale/messages-nb.js +7 -1
  224. package/lib/locale/messages-nb.js.map +1 -1
  225. package/lib/locale/messages-nn.js +7 -1
  226. package/lib/locale/messages-nn.js.map +1 -1
  227. package/lib/locale/messages-se.js +7 -1
  228. package/lib/locale/messages-se.js.map +1 -1
  229. package/lib/model/index.js +7 -0
  230. package/lib/model/index.js.map +1 -1
  231. package/lib/utils/licenseAttributes.js +7 -1
  232. package/lib/utils/licenseAttributes.js.map +1 -1
  233. package/package.json +7 -7
  234. package/src/Concept/Concept.tsx +1 -1
  235. package/src/ContactBlock/ContactBlock.tsx +2 -2
  236. package/src/Embed/ImageEmbed.stories.tsx +2 -2
  237. package/src/Embed/ImageEmbed.tsx +6 -6
  238. package/src/Embed/RelatedContentEmbed.tsx +1 -9
  239. package/src/Embed/types.ts +2 -2
  240. package/src/Gloss/Gloss.tsx +4 -4
  241. package/src/Gloss/GlossExample.tsx +2 -2
  242. package/src/LicenseByline/EmbedByline.tsx +4 -4
  243. package/src/Pitch/Pitch.tsx +3 -2
  244. package/src/RelatedArticleList/RelatedArticleList.tsx +11 -28
@@ -1 +1 @@
1
- {"version":3,"file":"ContactBlock.mjs","names":["BackgroundVariant: Record<ContactBlockBackground, SystemStyleObject>"],"sources":["../../src/ContactBlock/ContactBlock.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useTranslation } from \"react-i18next\";\nimport { Text } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { SystemStyleObject } from \"@ndla/styled-system/types\";\nimport type { IImageMetaInformationV3DTO } from \"@ndla/types-backend/image-api\";\nimport { LicenseContainerContent } from \"../LicenseByline/EmbedByline\";\n\nexport type ContactBlockBackground = \"strong\" | \"moderate\" | \"subtle\";\n\nconst BackgroundVariant: Record<ContactBlockBackground, SystemStyleObject> = {\n strong: { _before: { backgroundColor: \"surface.brand.3\" } },\n moderate: { _before: { backgroundColor: \"surface.brand.3.moderate\" } },\n subtle: { _before: { backgroundColor: \"surface.brand.3.subtle\" } },\n};\n\nexport const contactBlockBackgrounds = Object.keys(BackgroundVariant) as ContactBlockBackground[];\n\nconst StyledWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n minWidth: \"surface.xxsmall\",\n padding: \"medium\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n boxShadow: \"full\",\n border: \"1px solid\",\n gap: \"medium\",\n position: \"relative\",\n borderColor: \"stroke.default\",\n borderRadius: \"xsmall\",\n overflow: \"hidden\",\n background: \"surface.default\",\n flexDirection: \"column-reverse\",\n tablet: {\n alignItems: \"unset\",\n flexDirection: \"row\",\n },\n },\n});\n\nconst EmailLink = styled(\"a\", {\n base: {\n color: \"text.default\",\n textDecoration: \"underline\",\n _hover: { textDecoration: \"none\" },\n _focusVisible: { textDecoration: \"none\" },\n },\n});\n\nconst HeaderWrapper = styled(\"div\", {\n base: {\n position: \"relative\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"3xsmall\",\n zIndex: \"base\",\n _before: {\n content: '\"\"',\n position: \"absolute\",\n top: \"-60px\",\n left: \"-50px\",\n right: \"0\",\n bottom: \"0\",\n height: \"calc(100% + 50px)\",\n width: \"surface.3xlarge\",\n transform: \"rotate(-4deg)\",\n zIndex: \"hide\",\n },\n },\n variants: {\n variant: BackgroundVariant,\n imageExists: {\n true: {\n tabletDown: {\n _before: {\n display: \"none\",\n },\n },\n },\n },\n },\n});\n\nconst ImageWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"xxsmall\",\n alignItems: \"flex-start\",\n justifyContent: \"flex-start\",\n flexDirection: \"column\",\n zIndex: \"base\",\n tabletDown: {\n _before: {\n content: '\"\"',\n position: \"absolute\",\n top: \"-50px\",\n left: \"-50px\",\n right: \"0\",\n bottom: \"0\",\n height: \"surface.xxsmall\",\n width: \"surface.3xlarge\",\n transform: \"rotate(-4deg)\",\n zIndex: \"hide\",\n },\n },\n },\n variants: {\n variant: BackgroundVariant,\n },\n});\n\nconst StyledImage = styled(\"img\", {\n base: {\n borderRadius: \"xsmall\",\n width: \"surface.xsmall\",\n height: \"surface.xsmall\",\n objectFit: \"cover\",\n },\n});\n\nconst ContentWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"medium\",\n flex: \"1\",\n width: \"100%\",\n },\n});\n\nconst StyledDescription = styled(Text, {\n base: {\n fontFamily: \"serif\",\n },\n});\n\ninterface Props {\n image?: IImageMetaInformationV3DTO;\n jobTitle: string;\n description: string;\n backgroundColor?: ContactBlockBackground;\n imageWidth?: number;\n name: string;\n email: string;\n embedAlt?: string;\n lang?: string;\n}\n\nexport const ContactBlock = ({\n image,\n jobTitle,\n description,\n name,\n email,\n embedAlt,\n lang,\n backgroundColor = \"strong\",\n}: Props) => {\n const { t } = useTranslation();\n return (\n <StyledWrapper data-embed-type=\"contact-block\">\n <ContentWrapper>\n <HeaderWrapper variant={backgroundColor} imageExists={!!image}>\n <Text lang={lang} fontWeight=\"bold\" textStyle=\"heading.small\">\n {name}\n </Text>\n <Text lang={lang}>{jobTitle}</Text>\n <Text>\n {`${t(\"email\")}: `}\n <EmailLink href={`mailto:${email}`}>{email}</EmailLink>\n </Text>\n </HeaderWrapper>\n <StyledDescription textStyle=\"body.large\">{description}</StyledDescription>\n </ContentWrapper>\n {!!image && (\n <ImageWrapper variant={backgroundColor}>\n <StyledImage\n alt={embedAlt !== undefined ? embedAlt : image.alttext.alttext}\n src={image.image.imageUrl}\n width={300}\n height={300}\n />\n <LicenseContainerContent type=\"image\" copyright={image.copyright} />\n </ImageWrapper>\n )}\n </StyledWrapper>\n );\n};\n"],"mappings":";;;;;;;AAiBA,MAAMA,oBAAuE;CAC3E,QAAQ,EAAE,SAAS,EAAE,iBAAiB,mBAAmB,EAAE;CAC3D,UAAU,EAAE,SAAS,EAAE,iBAAiB,4BAA4B,EAAE;CACtE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,0BAA0B,EAAE;CACnE;AAED,MAAa,0BAA0B,OAAO,KAAK,kBAAkB;AAErE,MAAM,gBAAgB,OAAO,OAAO,EAClC,MAAM;CACJ,SAAS;CACT,UAAU;CACV,SAAS;CACT,YAAY;CACZ,gBAAgB;CAChB,WAAW;CACX,QAAQ;CACR,KAAK;CACL,UAAU;CACV,aAAa;CACb,cAAc;CACd,UAAU;CACV,YAAY;CACZ,eAAe;CACf,QAAQ;EACN,YAAY;EACZ,eAAe;EAChB;CACF,EACF,CAAC;AAEF,MAAM,YAAY,OAAO,KAAK,EAC5B,MAAM;CACJ,OAAO;CACP,gBAAgB;CAChB,QAAQ,EAAE,gBAAgB,QAAQ;CAClC,eAAe,EAAE,gBAAgB,QAAQ;CAC1C,EACF,CAAC;AAEF,MAAM,gBAAgB,OAAO,OAAO;CAClC,MAAM;EACJ,UAAU;EACV,SAAS;EACT,eAAe;EACf,KAAK;EACL,QAAQ;EACR,SAAS;GACP,SAAS;GACT,UAAU;GACV,KAAK;GACL,MAAM;GACN,OAAO;GACP,QAAQ;GACR,QAAQ;GACR,OAAO;GACP,WAAW;GACX,QAAQ;GACT;EACF;CACD,UAAU;EACR,SAAS;EACT,aAAa,EACX,MAAM,EACJ,YAAY,EACV,SAAS,EACP,SAAS,QACV,EACF,EACF,EACF;EACF;CACF,CAAC;AAEF,MAAM,eAAe,OAAO,OAAO;CACjC,MAAM;EACJ,SAAS;EACT,KAAK;EACL,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,QAAQ;EACR,YAAY,EACV,SAAS;GACP,SAAS;GACT,UAAU;GACV,KAAK;GACL,MAAM;GACN,OAAO;GACP,QAAQ;GACR,QAAQ;GACR,OAAO;GACP,WAAW;GACX,QAAQ;GACT,EACF;EACF;CACD,UAAU,EACR,SAAS,mBACV;CACF,CAAC;AAEF,MAAM,cAAc,OAAO,OAAO,EAChC,MAAM;CACJ,cAAc;CACd,OAAO;CACP,QAAQ;CACR,WAAW;CACZ,EACF,CAAC;AAEF,MAAM,iBAAiB,OAAO,OAAO,EACnC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,MAAM;CACN,OAAO;CACR,EACF,CAAC;AAEF,MAAM,oBAAoB,OAAO,MAAM,EACrC,MAAM,EACJ,YAAY,SACb,EACF,CAAC;AAcF,MAAa,gBAAgB,EAC3B,OACA,UACA,aACA,MACA,OACA,UACA,MACA,kBAAkB,eACP;CACX,MAAM,EAAE,MAAM,gBAAgB;AAC9B,QACE,qBAAC;EAAc,mBAAgB;aAC7B,qBAAC,6BACC,qBAAC;GAAc,SAAS;GAAiB,aAAa,CAAC,CAAC;;IACtD,oBAAC;KAAW;KAAM,YAAW;KAAO,WAAU;eAC3C;MACI;IACP,oBAAC;KAAW;eAAO;MAAgB;IACnC,qBAAC,mBACE,GAAG,EAAE,QAAQ,CAAC,KACf,oBAAC;KAAU,MAAM,UAAU;eAAU;MAAkB,IAClD;;IACO,EAChB,oBAAC;GAAkB,WAAU;aAAc;IAAgC,IAC5D,EAChB,CAAC,CAAC,SACD,qBAAC;GAAa,SAAS;cACrB,oBAAC;IACC,KAAK,aAAa,SAAY,WAAW,MAAM,QAAQ;IACvD,KAAK,MAAM,MAAM;IACjB,OAAO;IACP,QAAQ;KACR,EACF,oBAAC;IAAwB,MAAK;IAAQ,WAAW,MAAM;KAAa;IACvD;GAEH"}
1
+ {"version":3,"file":"ContactBlock.mjs","names":["BackgroundVariant: Record<ContactBlockBackground, SystemStyleObject>"],"sources":["../../src/ContactBlock/ContactBlock.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useTranslation } from \"react-i18next\";\nimport { Text } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { SystemStyleObject } from \"@ndla/styled-system/types\";\nimport type { ImageMetaInformationV3DTO } from \"@ndla/types-backend/image-api\";\nimport { LicenseContainerContent } from \"../LicenseByline/EmbedByline\";\n\nexport type ContactBlockBackground = \"strong\" | \"moderate\" | \"subtle\";\n\nconst BackgroundVariant: Record<ContactBlockBackground, SystemStyleObject> = {\n strong: { _before: { backgroundColor: \"surface.brand.3\" } },\n moderate: { _before: { backgroundColor: \"surface.brand.3.moderate\" } },\n subtle: { _before: { backgroundColor: \"surface.brand.3.subtle\" } },\n};\n\nexport const contactBlockBackgrounds = Object.keys(BackgroundVariant) as ContactBlockBackground[];\n\nconst StyledWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n minWidth: \"surface.xxsmall\",\n padding: \"medium\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n boxShadow: \"full\",\n border: \"1px solid\",\n gap: \"medium\",\n position: \"relative\",\n borderColor: \"stroke.default\",\n borderRadius: \"xsmall\",\n overflow: \"hidden\",\n background: \"surface.default\",\n flexDirection: \"column-reverse\",\n tablet: {\n alignItems: \"unset\",\n flexDirection: \"row\",\n },\n },\n});\n\nconst EmailLink = styled(\"a\", {\n base: {\n color: \"text.default\",\n textDecoration: \"underline\",\n _hover: { textDecoration: \"none\" },\n _focusVisible: { textDecoration: \"none\" },\n },\n});\n\nconst HeaderWrapper = styled(\"div\", {\n base: {\n position: \"relative\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"3xsmall\",\n zIndex: \"base\",\n _before: {\n content: '\"\"',\n position: \"absolute\",\n top: \"-60px\",\n left: \"-50px\",\n right: \"0\",\n bottom: \"0\",\n height: \"calc(100% + 50px)\",\n width: \"surface.3xlarge\",\n transform: \"rotate(-4deg)\",\n zIndex: \"hide\",\n },\n },\n variants: {\n variant: BackgroundVariant,\n imageExists: {\n true: {\n tabletDown: {\n _before: {\n display: \"none\",\n },\n },\n },\n },\n },\n});\n\nconst ImageWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"xxsmall\",\n alignItems: \"flex-start\",\n justifyContent: \"flex-start\",\n flexDirection: \"column\",\n zIndex: \"base\",\n tabletDown: {\n _before: {\n content: '\"\"',\n position: \"absolute\",\n top: \"-50px\",\n left: \"-50px\",\n right: \"0\",\n bottom: \"0\",\n height: \"surface.xxsmall\",\n width: \"surface.3xlarge\",\n transform: \"rotate(-4deg)\",\n zIndex: \"hide\",\n },\n },\n },\n variants: {\n variant: BackgroundVariant,\n },\n});\n\nconst StyledImage = styled(\"img\", {\n base: {\n borderRadius: \"xsmall\",\n width: \"surface.xsmall\",\n height: \"surface.xsmall\",\n objectFit: \"cover\",\n },\n});\n\nconst ContentWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"medium\",\n flex: \"1\",\n width: \"100%\",\n },\n});\n\nconst StyledDescription = styled(Text, {\n base: {\n fontFamily: \"serif\",\n },\n});\n\ninterface Props {\n image?: ImageMetaInformationV3DTO;\n jobTitle: string;\n description: string;\n backgroundColor?: ContactBlockBackground;\n imageWidth?: number;\n name: string;\n email: string;\n embedAlt?: string;\n lang?: string;\n}\n\nexport const ContactBlock = ({\n image,\n jobTitle,\n description,\n name,\n email,\n embedAlt,\n lang,\n backgroundColor = \"strong\",\n}: Props) => {\n const { t } = useTranslation();\n return (\n <StyledWrapper data-embed-type=\"contact-block\">\n <ContentWrapper>\n <HeaderWrapper variant={backgroundColor} imageExists={!!image}>\n <Text lang={lang} fontWeight=\"bold\" textStyle=\"heading.small\">\n {name}\n </Text>\n <Text lang={lang}>{jobTitle}</Text>\n <Text>\n {`${t(\"email\")}: `}\n <EmailLink href={`mailto:${email}`}>{email}</EmailLink>\n </Text>\n </HeaderWrapper>\n <StyledDescription textStyle=\"body.large\">{description}</StyledDescription>\n </ContentWrapper>\n {!!image && (\n <ImageWrapper variant={backgroundColor}>\n <StyledImage\n alt={embedAlt !== undefined ? embedAlt : image.alttext.alttext}\n src={image.image.imageUrl}\n width={300}\n height={300}\n />\n <LicenseContainerContent type=\"image\" copyright={image.copyright} />\n </ImageWrapper>\n )}\n </StyledWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AAiBA,MAAMA,oBAAuE;CAC3E,QAAQ,EAAE,SAAS,EAAE,iBAAiB,mBAAmB,EAAE;CAC3D,UAAU,EAAE,SAAS,EAAE,iBAAiB,4BAA4B,EAAE;CACtE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,0BAA0B,EAAE;CACnE;AAED,MAAa,0BAA0B,OAAO,KAAK,kBAAkB;AAErE,MAAM,gBAAgB,OAAO,OAAO,EAClC,MAAM;CACJ,SAAS;CACT,UAAU;CACV,SAAS;CACT,YAAY;CACZ,gBAAgB;CAChB,WAAW;CACX,QAAQ;CACR,KAAK;CACL,UAAU;CACV,aAAa;CACb,cAAc;CACd,UAAU;CACV,YAAY;CACZ,eAAe;CACf,QAAQ;EACN,YAAY;EACZ,eAAe;EAChB;CACF,EACF,CAAC;AAEF,MAAM,YAAY,OAAO,KAAK,EAC5B,MAAM;CACJ,OAAO;CACP,gBAAgB;CAChB,QAAQ,EAAE,gBAAgB,QAAQ;CAClC,eAAe,EAAE,gBAAgB,QAAQ;CAC1C,EACF,CAAC;AAEF,MAAM,gBAAgB,OAAO,OAAO;CAClC,MAAM;EACJ,UAAU;EACV,SAAS;EACT,eAAe;EACf,KAAK;EACL,QAAQ;EACR,SAAS;GACP,SAAS;GACT,UAAU;GACV,KAAK;GACL,MAAM;GACN,OAAO;GACP,QAAQ;GACR,QAAQ;GACR,OAAO;GACP,WAAW;GACX,QAAQ;GACT;EACF;CACD,UAAU;EACR,SAAS;EACT,aAAa,EACX,MAAM,EACJ,YAAY,EACV,SAAS,EACP,SAAS,QACV,EACF,EACF,EACF;EACF;CACF,CAAC;AAEF,MAAM,eAAe,OAAO,OAAO;CACjC,MAAM;EACJ,SAAS;EACT,KAAK;EACL,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,QAAQ;EACR,YAAY,EACV,SAAS;GACP,SAAS;GACT,UAAU;GACV,KAAK;GACL,MAAM;GACN,OAAO;GACP,QAAQ;GACR,QAAQ;GACR,OAAO;GACP,WAAW;GACX,QAAQ;GACT,EACF;EACF;CACD,UAAU,EACR,SAAS,mBACV;CACF,CAAC;AAEF,MAAM,cAAc,OAAO,OAAO,EAChC,MAAM;CACJ,cAAc;CACd,OAAO;CACP,QAAQ;CACR,WAAW;CACZ,EACF,CAAC;AAEF,MAAM,iBAAiB,OAAO,OAAO,EACnC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,MAAM;CACN,OAAO;CACR,EACF,CAAC;AAEF,MAAM,oBAAoB,OAAO,MAAM,EACrC,MAAM,EACJ,YAAY,SACb,EACF,CAAC;AAcF,MAAa,gBAAgB,EAC3B,OACA,UACA,aACA,MACA,OACA,UACA,MACA,kBAAkB,eACP;CACX,MAAM,EAAE,MAAM,gBAAgB;AAC9B,QACE,qBAAC;EAAc,mBAAgB;aAC7B,qBAAC,6BACC,qBAAC;GAAc,SAAS;GAAiB,aAAa,CAAC,CAAC;;IACtD,oBAAC;KAAW;KAAM,YAAW;KAAO,WAAU;eAC3C;MACI;IACP,oBAAC;KAAW;eAAO;MAAgB;IACnC,qBAAC,mBACE,GAAG,EAAE,QAAQ,CAAC,KACf,oBAAC;KAAU,MAAM,UAAU;eAAU;MAAkB,IAClD;;IACO,EAChB,oBAAC;GAAkB,WAAU;aAAc;IAAgC,IAC5D,EAChB,CAAC,CAAC,SACD,qBAAC;GAAa,SAAS;cACrB,oBAAC;IACC,KAAK,aAAa,SAAY,WAAW,MAAM,QAAQ;IACvD,KAAK,MAAM,MAAM;IACjB,OAAO;IACP,QAAQ;KACR,EACF,oBAAC;IAAwB,MAAK;IAAQ,WAAW,MAAM;KAAa;IACvD;GAEH"}
@@ -5,6 +5,13 @@ import { useTranslation } from "react-i18next";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
 
7
7
  //#region src/ContentTypeBadge/ContentTypeBadge.tsx
8
+ /**
9
+ * Copyright (c) 2024-present, NDLA.
10
+ *
11
+ * This source code is licensed under the GPLv3 license found in the
12
+ * LICENSE file in the root directory of this source tree.
13
+ *
14
+ */
8
15
  const contentTypeToBadgeVariantMap = {
9
16
  [SUBJECT_MATERIAL]: "brand1",
10
17
  [TASKS_AND_ACTIVITIES]: "brand2",
@@ -1 +1 @@
1
- {"version":3,"file":"ContentTypeBadge.mjs","names":["contentTypeToBadgeVariantMap: Record<ContentType, BadgeVariant>","contentTypes.SUBJECT_MATERIAL","contentTypes.TASKS_AND_ACTIVITIES","contentTypes.ASSESSMENT_RESOURCES","contentTypes.SUBJECT","contentTypes.SOURCE_MATERIAL","contentTypes.LEARNING_PATH","contentTypes.TOPIC","contentTypes.MULTIDISCIPLINARY","contentTypes.CONCEPT","contentTypes.EXTERNAL","contentTypes.IMAGE","contentTypes.AUDIO","contentTypes.PODCAST","contentTypes.VIDEO","contentTypes.MISSING","contentTypes.PODCAST_SERIES","contentTypes.GLOSS","contentTypes.PROGRAMME","contentTypes.FRONTPAGE_ARTICLE"],"sources":["../../src/ContentTypeBadge/ContentTypeBadge.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { forwardRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Badge, type BadgeProps, type BadgeVariant } from \"@ndla/primitives\";\nimport * as contentTypes from \"../model/ContentType\";\n\nexport interface ContentTypeBadgeProps extends Omit<BadgeProps, \"colorTheme\"> {\n contentType: ContentType | undefined;\n}\n\nexport type StrictContentType =\n | typeof contentTypes.SUBJECT_MATERIAL\n | typeof contentTypes.TASKS_AND_ACTIVITIES\n | typeof contentTypes.ASSESSMENT_RESOURCES\n | typeof contentTypes.SUBJECT\n | typeof contentTypes.SOURCE_MATERIAL\n | typeof contentTypes.LEARNING_PATH\n | typeof contentTypes.TOPIC\n | typeof contentTypes.MULTIDISCIPLINARY\n | typeof contentTypes.CONCEPT\n | typeof contentTypes.EXTERNAL\n | typeof contentTypes.IMAGE\n | typeof contentTypes.AUDIO\n | typeof contentTypes.VIDEO\n | typeof contentTypes.MISSING\n | typeof contentTypes.PODCAST\n | typeof contentTypes.GLOSS\n | typeof contentTypes.PROGRAMME\n | typeof contentTypes.PODCAST_SERIES\n | typeof contentTypes.FRONTPAGE_ARTICLE;\n\nexport type ContentType =\n | StrictContentType\n // This allows for us to fallback to string without getting a ts error, while still keeping intellisense\n | (string & {});\n\nexport const contentTypeToBadgeVariantMap: Record<ContentType, BadgeVariant> = {\n [contentTypes.SUBJECT_MATERIAL]: \"brand1\",\n [contentTypes.TASKS_AND_ACTIVITIES]: \"brand2\",\n [contentTypes.ASSESSMENT_RESOURCES]: \"brand2\",\n [contentTypes.SUBJECT]: \"neutral\",\n [contentTypes.SOURCE_MATERIAL]: \"brand1\",\n [contentTypes.LEARNING_PATH]: \"brand3\",\n [contentTypes.TOPIC]: \"neutral\",\n [contentTypes.MULTIDISCIPLINARY]: \"neutral\",\n [contentTypes.CONCEPT]: \"brand1\",\n [contentTypes.EXTERNAL]: \"brand2\",\n [contentTypes.IMAGE]: \"brand1\",\n [contentTypes.AUDIO]: \"brand1\",\n [contentTypes.PODCAST]: \"brand1\",\n [contentTypes.VIDEO]: \"brand1\",\n [contentTypes.MISSING]: \"neutral\",\n [contentTypes.PODCAST_SERIES]: \"brand1\",\n [contentTypes.GLOSS]: \"brand1\",\n [contentTypes.PROGRAMME]: \"neutral\",\n [contentTypes.FRONTPAGE_ARTICLE]: \"brand2\",\n};\n\nexport const ContentTypeBadge = forwardRef<HTMLDivElement, ContentTypeBadgeProps>(\n ({ contentType, children, ...props }, ref) => {\n const { t } = useTranslation();\n return (\n <Badge\n colorTheme={contentTypeToBadgeVariantMap[contentType ?? \"missing\"] ?? contentTypeToBadgeVariantMap[\"missing\"]}\n {...props}\n ref={ref}\n >\n {children ?? t(`contentTypes.${contentType}`)}\n </Badge>\n );\n },\n);\n"],"mappings":";;;;;;;AA2CA,MAAaA,+BAAkE;EAC5EC,mBAAgC;EAChCC,uBAAoC;EACpCC,uBAAoC;EACpCC,UAAuB;EACvBC,kBAA+B;EAC/BC,gBAA6B;EAC7BC,QAAqB;EACrBC,oBAAiC;EACjCC,UAAuB;EACvBC,WAAwB;EACxBC,QAAqB;EACrBC,QAAqB;EACrBC,UAAuB;EACvBC,QAAqB;EACrBC,UAAuB;EACvBC,iBAA8B;EAC9BC,QAAqB;EACrBC,YAAyB;EACzBC,oBAAiC;CACnC;AAED,MAAa,mBAAmB,YAC7B,EAAE,aAAa,SAAU,GAAG,SAAS,QAAQ;CAC5C,MAAM,EAAE,MAAM,gBAAgB;AAC9B,QACE,oBAAC;EACC,YAAY,6BAA6B,eAAe,cAAc,6BAA6B;EACnG,GAAI;EACC;YAEJ,YAAY,EAAE,gBAAgB,cAAc;GACvC;EAGb"}
1
+ {"version":3,"file":"ContentTypeBadge.mjs","names":["contentTypeToBadgeVariantMap: Record<ContentType, BadgeVariant>","contentTypes.SUBJECT_MATERIAL","contentTypes.TASKS_AND_ACTIVITIES","contentTypes.ASSESSMENT_RESOURCES","contentTypes.SUBJECT","contentTypes.SOURCE_MATERIAL","contentTypes.LEARNING_PATH","contentTypes.TOPIC","contentTypes.MULTIDISCIPLINARY","contentTypes.CONCEPT","contentTypes.EXTERNAL","contentTypes.IMAGE","contentTypes.AUDIO","contentTypes.PODCAST","contentTypes.VIDEO","contentTypes.MISSING","contentTypes.PODCAST_SERIES","contentTypes.GLOSS","contentTypes.PROGRAMME","contentTypes.FRONTPAGE_ARTICLE"],"sources":["../../src/ContentTypeBadge/ContentTypeBadge.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { forwardRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Badge, type BadgeProps, type BadgeVariant } from \"@ndla/primitives\";\nimport * as contentTypes from \"../model/ContentType\";\n\nexport interface ContentTypeBadgeProps extends Omit<BadgeProps, \"colorTheme\"> {\n contentType: ContentType | undefined;\n}\n\nexport type StrictContentType =\n | typeof contentTypes.SUBJECT_MATERIAL\n | typeof contentTypes.TASKS_AND_ACTIVITIES\n | typeof contentTypes.ASSESSMENT_RESOURCES\n | typeof contentTypes.SUBJECT\n | typeof contentTypes.SOURCE_MATERIAL\n | typeof contentTypes.LEARNING_PATH\n | typeof contentTypes.TOPIC\n | typeof contentTypes.MULTIDISCIPLINARY\n | typeof contentTypes.CONCEPT\n | typeof contentTypes.EXTERNAL\n | typeof contentTypes.IMAGE\n | typeof contentTypes.AUDIO\n | typeof contentTypes.VIDEO\n | typeof contentTypes.MISSING\n | typeof contentTypes.PODCAST\n | typeof contentTypes.GLOSS\n | typeof contentTypes.PROGRAMME\n | typeof contentTypes.PODCAST_SERIES\n | typeof contentTypes.FRONTPAGE_ARTICLE;\n\nexport type ContentType =\n | StrictContentType\n // This allows for us to fallback to string without getting a ts error, while still keeping intellisense\n | (string & {});\n\nexport const contentTypeToBadgeVariantMap: Record<ContentType, BadgeVariant> = {\n [contentTypes.SUBJECT_MATERIAL]: \"brand1\",\n [contentTypes.TASKS_AND_ACTIVITIES]: \"brand2\",\n [contentTypes.ASSESSMENT_RESOURCES]: \"brand2\",\n [contentTypes.SUBJECT]: \"neutral\",\n [contentTypes.SOURCE_MATERIAL]: \"brand1\",\n [contentTypes.LEARNING_PATH]: \"brand3\",\n [contentTypes.TOPIC]: \"neutral\",\n [contentTypes.MULTIDISCIPLINARY]: \"neutral\",\n [contentTypes.CONCEPT]: \"brand1\",\n [contentTypes.EXTERNAL]: \"brand2\",\n [contentTypes.IMAGE]: \"brand1\",\n [contentTypes.AUDIO]: \"brand1\",\n [contentTypes.PODCAST]: \"brand1\",\n [contentTypes.VIDEO]: \"brand1\",\n [contentTypes.MISSING]: \"neutral\",\n [contentTypes.PODCAST_SERIES]: \"brand1\",\n [contentTypes.GLOSS]: \"brand1\",\n [contentTypes.PROGRAMME]: \"neutral\",\n [contentTypes.FRONTPAGE_ARTICLE]: \"brand2\",\n};\n\nexport const ContentTypeBadge = forwardRef<HTMLDivElement, ContentTypeBadgeProps>(\n ({ contentType, children, ...props }, ref) => {\n const { t } = useTranslation();\n return (\n <Badge\n colorTheme={contentTypeToBadgeVariantMap[contentType ?? \"missing\"] ?? contentTypeToBadgeVariantMap[\"missing\"]}\n {...props}\n ref={ref}\n >\n {children ?? t(`contentTypes.${contentType}`)}\n </Badge>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;AA2CA,MAAaA,+BAAkE;EAC5EC,mBAAgC;EAChCC,uBAAoC;EACpCC,uBAAoC;EACpCC,UAAuB;EACvBC,kBAA+B;EAC/BC,gBAA6B;EAC7BC,QAAqB;EACrBC,oBAAiC;EACjCC,UAAuB;EACvBC,WAAwB;EACxBC,QAAqB;EACrBC,QAAqB;EACrBC,UAAuB;EACvBC,QAAqB;EACrBC,UAAuB;EACvBC,iBAA8B;EAC9BC,QAAqB;EACrBC,YAAyB;EACzBC,oBAAiC;CACnC;AAED,MAAa,mBAAmB,YAC7B,EAAE,aAAa,SAAU,GAAG,SAAS,QAAQ;CAC5C,MAAM,EAAE,MAAM,gBAAgB;AAC9B,QACE,oBAAC;EACC,YAAY,6BAA6B,eAAe,cAAc,6BAA6B;EACnG,GAAI;EACC;YAEJ,YAAY,EAAE,gBAAgB,cAAc;GACvC;EAGb"}
@@ -6,6 +6,13 @@ import { LinkMedium } from "@ndla/icons";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
 
8
8
  //#region src/CopyParagraphButton/CopyParagraphButton.tsx
9
+ /**
10
+ * Copyright (c) 2021-present, NDLA.
11
+ *
12
+ * This source code is licensed under the GPLv3 license found in the
13
+ * LICENSE file in the root directory of this source tree.
14
+ *
15
+ */
9
16
  const ContainerDiv = styled("div", { base: {
10
17
  position: "relative",
11
18
  _hover: { "& [data-copy-button]": {
@@ -1 +1 @@
1
- {"version":3,"file":"CopyParagraphButton.mjs","names":[],"sources":["../../src/CopyParagraphButton/CopyParagraphButton.tsx"],"sourcesContent":["/**\n * Copyright (c) 2021-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { type ReactNode, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { LinkMedium } from \"@ndla/icons\";\nimport { IconButton } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\n\nconst ContainerDiv = styled(\"div\", {\n base: {\n position: \"relative\",\n _hover: {\n \"& [data-copy-button]\": {\n opacity: \"1\",\n cursor: \"pointer\",\n },\n },\n },\n});\n\nconst StyledIconButton = styled(IconButton, {\n base: {\n position: \"absolute\",\n left: \"-xxlarge\",\n top: \"-4xsmall\",\n opacity: \"0\",\n cursor: \"pointer\",\n \"&:focus, &:focus-visible, &:active\": {\n opacity: \"1\",\n },\n },\n});\n\ninterface Props {\n // What to render within the h2\n children: ReactNode;\n copyText: string;\n lang?: string;\n}\nexport const CopyParagraphButton = ({ children, copyText, lang }: Props) => {\n const [hasCopied, setHasCopied] = useState(false);\n const { t } = useTranslation();\n const sanitizedTitle = useMemo(() => encodeURIComponent(copyText.replace(/ /g, \"-\")), [copyText]);\n\n useEffect(() => {\n if (hasCopied) {\n setTimeout(() => setHasCopied(false), 3000);\n }\n }, [hasCopied]);\n\n const onCopyClick = useCallback(async () => {\n const { location } = window;\n const newHash = `#${sanitizedTitle}`;\n const port = location.port ? `:${location.port}` : \"\";\n const urlToCopy = `${location.protocol}//${location.hostname}${port}${location.pathname}${location.search}${newHash}`;\n try {\n await navigator.clipboard.writeText(urlToCopy);\n setHasCopied(true);\n } catch {\n // do nothing\n }\n }, [sanitizedTitle]);\n\n const tooltip = hasCopied ? t(\"article.copyPageLinkCopied\") : t(\"article.copyHeaderLink\");\n return (\n <ContainerDiv data-embed-type=\"copy-heading\">\n <StyledIconButton\n variant=\"clear\"\n data-copy-button=\"\"\n onClick={onCopyClick}\n title={tooltip}\n aria-label={`${tooltip}: ${copyText}`}\n >\n <LinkMedium />\n </StyledIconButton>\n <h2 id={sanitizedTitle} tabIndex={-1} lang={lang}>\n {children}\n </h2>\n </ContainerDiv>\n );\n};\n"],"mappings":";;;;;;;;AAcA,MAAM,eAAe,OAAO,OAAO,EACjC,MAAM;CACJ,UAAU;CACV,QAAQ,EACN,wBAAwB;EACtB,SAAS;EACT,QAAQ;EACT,EACF;CACF,EACF,CAAC;AAEF,MAAM,mBAAmB,OAAO,YAAY,EAC1C,MAAM;CACJ,UAAU;CACV,MAAM;CACN,KAAK;CACL,SAAS;CACT,QAAQ;CACR,sCAAsC,EACpC,SAAS,KACV;CACF,EACF,CAAC;AAQF,MAAa,uBAAuB,EAAE,UAAU,UAAU,WAAkB;CAC1E,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,iBAAiB,cAAc,mBAAmB,SAAS,QAAQ,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;AAEjG,iBAAgB;AACd,MAAI,UACF,kBAAiB,aAAa,MAAM,EAAE,IAAK;IAE5C,CAAC,UAAU,CAAC;CAEf,MAAM,cAAc,YAAY,YAAY;EAC1C,MAAM,EAAE,aAAa;EACrB,MAAM,UAAU,IAAI;EACpB,MAAM,OAAO,SAAS,OAAO,IAAI,SAAS,SAAS;EACnD,MAAM,YAAY,GAAG,SAAS,SAAS,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,SAAS,SAAS;AAC5G,MAAI;AACF,SAAM,UAAU,UAAU,UAAU,UAAU;AAC9C,gBAAa,KAAK;UACZ;IAGP,CAAC,eAAe,CAAC;CAEpB,MAAM,UAAU,YAAY,EAAE,6BAA6B,GAAG,EAAE,yBAAyB;AACzF,QACE,qBAAC;EAAa,mBAAgB;aAC5B,oBAAC;GACC,SAAQ;GACR,oBAAiB;GACjB,SAAS;GACT,OAAO;GACP,cAAY,GAAG,QAAQ,IAAI;aAE3B,oBAAC,eAAa;IACG,EACnB,oBAAC;GAAG,IAAI;GAAgB,UAAU;GAAU;GACzC;IACE;GACQ"}
1
+ {"version":3,"file":"CopyParagraphButton.mjs","names":[],"sources":["../../src/CopyParagraphButton/CopyParagraphButton.tsx"],"sourcesContent":["/**\n * Copyright (c) 2021-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { type ReactNode, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { LinkMedium } from \"@ndla/icons\";\nimport { IconButton } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\n\nconst ContainerDiv = styled(\"div\", {\n base: {\n position: \"relative\",\n _hover: {\n \"& [data-copy-button]\": {\n opacity: \"1\",\n cursor: \"pointer\",\n },\n },\n },\n});\n\nconst StyledIconButton = styled(IconButton, {\n base: {\n position: \"absolute\",\n left: \"-xxlarge\",\n top: \"-4xsmall\",\n opacity: \"0\",\n cursor: \"pointer\",\n \"&:focus, &:focus-visible, &:active\": {\n opacity: \"1\",\n },\n },\n});\n\ninterface Props {\n // What to render within the h2\n children: ReactNode;\n copyText: string;\n lang?: string;\n}\nexport const CopyParagraphButton = ({ children, copyText, lang }: Props) => {\n const [hasCopied, setHasCopied] = useState(false);\n const { t } = useTranslation();\n const sanitizedTitle = useMemo(() => encodeURIComponent(copyText.replace(/ /g, \"-\")), [copyText]);\n\n useEffect(() => {\n if (hasCopied) {\n setTimeout(() => setHasCopied(false), 3000);\n }\n }, [hasCopied]);\n\n const onCopyClick = useCallback(async () => {\n const { location } = window;\n const newHash = `#${sanitizedTitle}`;\n const port = location.port ? `:${location.port}` : \"\";\n const urlToCopy = `${location.protocol}//${location.hostname}${port}${location.pathname}${location.search}${newHash}`;\n try {\n await navigator.clipboard.writeText(urlToCopy);\n setHasCopied(true);\n } catch {\n // do nothing\n }\n }, [sanitizedTitle]);\n\n const tooltip = hasCopied ? t(\"article.copyPageLinkCopied\") : t(\"article.copyHeaderLink\");\n return (\n <ContainerDiv data-embed-type=\"copy-heading\">\n <StyledIconButton\n variant=\"clear\"\n data-copy-button=\"\"\n onClick={onCopyClick}\n title={tooltip}\n aria-label={`${tooltip}: ${copyText}`}\n >\n <LinkMedium />\n </StyledIconButton>\n <h2 id={sanitizedTitle} tabIndex={-1} lang={lang}>\n {children}\n </h2>\n </ContainerDiv>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAcA,MAAM,eAAe,OAAO,OAAO,EACjC,MAAM;CACJ,UAAU;CACV,QAAQ,EACN,wBAAwB;EACtB,SAAS;EACT,QAAQ;EACT,EACF;CACF,EACF,CAAC;AAEF,MAAM,mBAAmB,OAAO,YAAY,EAC1C,MAAM;CACJ,UAAU;CACV,MAAM;CACN,KAAK;CACL,SAAS;CACT,QAAQ;CACR,sCAAsC,EACpC,SAAS,KACV;CACF,EACF,CAAC;AAQF,MAAa,uBAAuB,EAAE,UAAU,UAAU,WAAkB;CAC1E,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,iBAAiB,cAAc,mBAAmB,SAAS,QAAQ,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;AAEjG,iBAAgB;AACd,MAAI,UACF,kBAAiB,aAAa,MAAM,EAAE,IAAK;IAE5C,CAAC,UAAU,CAAC;CAEf,MAAM,cAAc,YAAY,YAAY;EAC1C,MAAM,EAAE,aAAa;EACrB,MAAM,UAAU,IAAI;EACpB,MAAM,OAAO,SAAS,OAAO,IAAI,SAAS,SAAS;EACnD,MAAM,YAAY,GAAG,SAAS,SAAS,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,SAAS,SAAS;AAC5G,MAAI;AACF,SAAM,UAAU,UAAU,UAAU,UAAU;AAC9C,gBAAa,KAAK;UACZ;IAGP,CAAC,eAAe,CAAC;CAEpB,MAAM,UAAU,YAAY,EAAE,6BAA6B,GAAG,EAAE,yBAAyB;AACzF,QACE,qBAAC;EAAa,mBAAgB;aAC5B,oBAAC;GACC,SAAQ;GACR,oBAAiB;GACjB,SAAS;GACT,OAAO;GACP,cAAY,GAAG,QAAQ,IAAI;aAE3B,oBAAC,eAAa;IACG,EACnB,oBAAC;GAAG,IAAI;GAAgB,UAAU;GAAU;GACzC;IACE;GACQ"}
@@ -7,6 +7,13 @@ import { styled } from "@ndla/styled-system/jsx";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
 
9
9
  //#region src/Embed/AudioEmbed.tsx
10
+ /**
11
+ * Copyright (c) 2023-present, NDLA.
12
+ *
13
+ * This source code is licensed under the GPLv3 license found in the
14
+ * LICENSE file in the root directory of this source tree.
15
+ *
16
+ */
10
17
  const StyledFigure = styled(Figure, { base: { clear: "both" } });
11
18
  const AudioEmbed = ({ embed, lang }) => {
12
19
  const type = embed.embedData.type === "standard" ? "audio" : "podcast";
@@ -1 +1 @@
1
- {"version":3,"file":"AudioEmbed.mjs","names":[],"sources":["../../src/Embed/AudioEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { AudioMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport type { Author } from \"./ImageEmbed\";\nimport { AudioPlayer } from \"../AudioPlayer/AudioPlayer\";\nimport { EmbedByline } from \"../LicenseByline/EmbedByline\";\nimport { licenseAttributes } from \"../utils/licenseAttributes\";\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n },\n});\n\ninterface Props {\n embed: AudioMetaData;\n lang?: string;\n}\n\nexport const getFirstNonEmptyLicenseCredits = (authors: {\n creators: Author[];\n rightsholders: Author[];\n processors: Author[];\n}) => Object.values(authors).find((i) => i.length > 0) ?? [];\n\nexport const AudioEmbed = ({ embed, lang }: Props) => {\n const type = embed.embedData.type === \"standard\" ? \"audio\" : \"podcast\";\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type={type} />;\n }\n\n const { data, embedData } = embed;\n\n if (embedData.type === \"minimal\") {\n return <AudioPlayer speech src={data.audioFile.url} title={data.title.title} />;\n }\n\n const subtitle = data.series ? { title: data.series.title.title, url: `/podkast/${data.series.id}` } : undefined;\n\n const coverPhoto = data.podcastMeta?.coverPhoto;\n\n const img = coverPhoto && { url: coverPhoto.url, alt: coverPhoto.altText };\n\n const licenseProps = licenseAttributes(data.copyright.license.license, lang, embedData.url);\n\n return (\n <StyledFigure lang={lang} data-embed-type={type} {...licenseProps}>\n <AudioPlayer\n description={data.podcastMeta?.introduction ?? \"\"}\n img={img}\n src={data.audioFile.url}\n textVersion={\n data.manuscript?.manuscript.length ? (\n <div dangerouslySetInnerHTML={{ __html: data.manuscript.manuscript }} />\n ) : undefined\n }\n title={data.title.title}\n subtitle={subtitle}\n />\n <EmbedByline\n error={false}\n type={data.audioType === \"standard\" ? \"audio\" : \"podcast\"}\n copyright={embed.data.copyright}\n />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;AAiBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,OAAO,QACR,EACF,CAAC;AAaF,MAAa,cAAc,EAAE,OAAO,WAAkB;CACpD,MAAM,OAAO,MAAM,UAAU,SAAS,aAAa,UAAU;AAC7D,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAA4B,OAAQ;CAG9C,MAAM,EAAE,MAAM,cAAc;AAE5B,KAAI,UAAU,SAAS,UACrB,QAAO,oBAAC;EAAY;EAAO,KAAK,KAAK,UAAU;EAAK,OAAO,KAAK,MAAM;GAAS;CAGjF,MAAM,WAAW,KAAK,SAAS;EAAE,OAAO,KAAK,OAAO,MAAM;EAAO,KAAK,YAAY,KAAK,OAAO;EAAM,GAAG;CAEvG,MAAM,aAAa,KAAK,aAAa;CAErC,MAAM,MAAM,cAAc;EAAE,KAAK,WAAW;EAAK,KAAK,WAAW;EAAS;CAE1E,MAAM,eAAe,kBAAkB,KAAK,UAAU,QAAQ,SAAS,MAAM,UAAU,IAAI;AAE3F,QACE,qBAAC;EAAmB;EAAM,mBAAiB;EAAM,GAAI;aACnD,oBAAC;GACC,aAAa,KAAK,aAAa,gBAAgB;GAC1C;GACL,KAAK,KAAK,UAAU;GACpB,aACE,KAAK,YAAY,WAAW,SAC1B,oBAAC,SAAI,yBAAyB,EAAE,QAAQ,KAAK,WAAW,YAAY,GAAI,GACtE;GAEN,OAAO,KAAK,MAAM;GACR;IACV,EACF,oBAAC;GACC,OAAO;GACP,MAAM,KAAK,cAAc,aAAa,UAAU;GAChD,WAAW,MAAM,KAAK;IACtB;GACW"}
1
+ {"version":3,"file":"AudioEmbed.mjs","names":[],"sources":["../../src/Embed/AudioEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { AudioMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport type { Author } from \"./ImageEmbed\";\nimport { AudioPlayer } from \"../AudioPlayer/AudioPlayer\";\nimport { EmbedByline } from \"../LicenseByline/EmbedByline\";\nimport { licenseAttributes } from \"../utils/licenseAttributes\";\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n },\n});\n\ninterface Props {\n embed: AudioMetaData;\n lang?: string;\n}\n\nexport const getFirstNonEmptyLicenseCredits = (authors: {\n creators: Author[];\n rightsholders: Author[];\n processors: Author[];\n}) => Object.values(authors).find((i) => i.length > 0) ?? [];\n\nexport const AudioEmbed = ({ embed, lang }: Props) => {\n const type = embed.embedData.type === \"standard\" ? \"audio\" : \"podcast\";\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type={type} />;\n }\n\n const { data, embedData } = embed;\n\n if (embedData.type === \"minimal\") {\n return <AudioPlayer speech src={data.audioFile.url} title={data.title.title} />;\n }\n\n const subtitle = data.series ? { title: data.series.title.title, url: `/podkast/${data.series.id}` } : undefined;\n\n const coverPhoto = data.podcastMeta?.coverPhoto;\n\n const img = coverPhoto && { url: coverPhoto.url, alt: coverPhoto.altText };\n\n const licenseProps = licenseAttributes(data.copyright.license.license, lang, embedData.url);\n\n return (\n <StyledFigure lang={lang} data-embed-type={type} {...licenseProps}>\n <AudioPlayer\n description={data.podcastMeta?.introduction ?? \"\"}\n img={img}\n src={data.audioFile.url}\n textVersion={\n data.manuscript?.manuscript.length ? (\n <div dangerouslySetInnerHTML={{ __html: data.manuscript.manuscript }} />\n ) : undefined\n }\n title={data.title.title}\n subtitle={subtitle}\n />\n <EmbedByline\n error={false}\n type={data.audioType === \"standard\" ? \"audio\" : \"podcast\"}\n copyright={embed.data.copyright}\n />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,OAAO,QACR,EACF,CAAC;AAaF,MAAa,cAAc,EAAE,OAAO,WAAkB;CACpD,MAAM,OAAO,MAAM,UAAU,SAAS,aAAa,UAAU;AAC7D,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAA4B,OAAQ;CAG9C,MAAM,EAAE,MAAM,cAAc;AAE5B,KAAI,UAAU,SAAS,UACrB,QAAO,oBAAC;EAAY;EAAO,KAAK,KAAK,UAAU;EAAK,OAAO,KAAK,MAAM;GAAS;CAGjF,MAAM,WAAW,KAAK,SAAS;EAAE,OAAO,KAAK,OAAO,MAAM;EAAO,KAAK,YAAY,KAAK,OAAO;EAAM,GAAG;CAEvG,MAAM,aAAa,KAAK,aAAa;CAErC,MAAM,MAAM,cAAc;EAAE,KAAK,WAAW;EAAK,KAAK,WAAW;EAAS;CAE1E,MAAM,eAAe,kBAAkB,KAAK,UAAU,QAAQ,SAAS,MAAM,UAAU,IAAI;AAE3F,QACE,qBAAC;EAAmB;EAAM,mBAAiB;EAAM,GAAI;aACnD,oBAAC;GACC,aAAa,KAAK,aAAa,gBAAgB;GAC1C;GACL,KAAK,KAAK,UAAU;GACpB,aACE,KAAK,YAAY,WAAW,SAC1B,oBAAC,SAAI,yBAAyB,EAAE,QAAQ,KAAK,WAAW,YAAY,GAAI,GACtE;GAEN,OAAO,KAAK,MAAM;GACR;IACV,EACF,oBAAC;GACC,OAAO;GACP,MAAM,KAAK,cAAc,aAAa,UAAU;GAChD,WAAW,MAAM,KAAK;IACtB;GACW"}
@@ -9,6 +9,13 @@ import { useTranslation } from "react-i18next";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
 
11
11
  //#region src/Embed/BrightcoveEmbed.tsx
12
+ /**
13
+ * Copyright (c) 2023-present, NDLA.
14
+ *
15
+ * This source code is licensed under the GPLv3 license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ *
18
+ */
12
19
  const LinkedVideoButton = styled(Button, { base: { marginBlockStart: "3xsmall" } });
13
20
  const BrightcoveIframe = styled("iframe", { base: {
14
21
  border: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"BrightcoveEmbed.mjs","names":[],"sources":["../../src/Embed/BrightcoveEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport parse from \"html-react-parser\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Button, Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveEmbedData, BrightcoveMetaData, BrightcoveVideoSource } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport type { RenderContext } from \"./types\";\nimport { EmbedByline } from \"../LicenseByline/EmbedByline\";\nimport { licenseAttributes } from \"../utils/licenseAttributes\";\n\ninterface Props {\n embed: BrightcoveMetaData;\n renderContext?: RenderContext;\n lang?: string;\n}\n\nconst LinkedVideoButton = styled(Button, {\n base: {\n marginBlockStart: \"3xsmall\",\n },\n});\n\nconst BrightcoveIframe = styled(\"iframe\", {\n base: {\n border: 0,\n height: \"auto\",\n width: \"100%\",\n },\n});\n\nexport const makeIframeString = (url: string, width: string | number, height: string | number, title = \"\") => {\n const strippedWidth = typeof width === \"number\" ? width : width.replace(/\\s*px/, \"\");\n const strippedHeight = typeof height === \"number\" ? height : height.replace(/\\s*px/, \"\");\n const urlOrTitle = title || url;\n return `<iframe title=\"${urlOrTitle}\" aria-label=\"${urlOrTitle}\" src=\"${url}\" width=\"${strippedWidth}\" height=\"${strippedHeight}\" allowfullscreen scrolling=\"no\" frameborder=\"0\" loading=\"lazy\"></iframe>`;\n};\n\nexport const isNumeric = (value: any) => !Number.isNaN(value - Number.parseFloat(value));\n\nconst getIframeProps = (data: BrightcoveEmbedData, sources: BrightcoveVideoSource[]) => {\n const { account, videoid, player = \"default\" } = data;\n\n const source = sources.filter((s) => s.width && s.height).toSorted((a, b) => a!.height! - b.height!)[0];\n\n return {\n src: `https://players.brightcove.net/${account}/${player}_default/index.html?videoId=${videoid}`,\n height: source?.height ?? \"480\",\n width: source?.width ?? \"640\",\n };\n};\nexport const BrightcoveEmbed = ({ embed, renderContext = \"article\", lang }: Props) => {\n const [showOriginalVideo, setShowOriginalVideo] = useState(true);\n const { t } = useTranslation();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const { embedData } = embed;\n const fallbackTitle = `${t(\"embed.type.video\")}: ${embedData.videoid}`;\n const parsedDescription = useMemo(() => {\n if (embed.embedData.caption || renderContext === \"article\") {\n return embed.embedData.caption ? parse(embed.embedData.caption) : undefined;\n } else if (embed.status === \"success\" && embed.data.description) {\n return parse(embed.data.description);\n }\n }, [embed, renderContext]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (iframe) {\n const [width, height] = [parseInt(iframe.width), parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width}/${height}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n if (embed.status === \"error\") {\n return (\n <EmbedErrorPlaceholder type=\"video\">\n <BrightcoveIframe\n ref={iframeRef}\n title={embedData.alt || fallbackTitle}\n aria-label={embedData.alt || fallbackTitle}\n {...getIframeProps(embedData, [])}\n allow=\"fullscreen; encrypted-media\"\n />\n </EmbedErrorPlaceholder>\n );\n }\n const { data } = embed;\n\n const linkedVideoId = isNumeric(data.link?.text) ? data.link?.text : undefined;\n\n const originalVideoProps = getIframeProps(embedData, data.sources);\n const alternativeVideoProps = linkedVideoId\n ? getIframeProps({ ...embedData, videoid: linkedVideoId }, data.sources)\n : undefined;\n\n const licenseProps = licenseAttributes(data?.copyright?.license.license, lang, embedData.pageUrl);\n\n const title = data.name?.trim() ? `${t(\"embed.type.video\")}: ${data.name}` : fallbackTitle;\n\n return (\n <Figure data-embed-type=\"brightcove\" {...licenseProps}>\n <div className=\"brightcove-video\">\n <BrightcoveIframe\n ref={iframeRef}\n className=\"original\"\n title={title}\n aria-label={title}\n {...(alternativeVideoProps && !showOriginalVideo ? alternativeVideoProps : originalVideoProps)}\n allow=\"fullscreen; encrypted-media\"\n />\n </div>\n <EmbedByline type=\"video\" copyright={data.copyright!} description={parsedDescription}>\n <div>\n {!!linkedVideoId && (\n <LinkedVideoButton size=\"small\" variant=\"secondary\" onClick={() => setShowOriginalVideo((p) => !p)}>\n {t(`figure.button.${!showOriginalVideo ? \"original\" : \"alternative\"}`)}\n </LinkedVideoButton>\n )}\n </div>\n </EmbedByline>\n </Figure>\n );\n};\n"],"mappings":";;;;;;;;;;;AAyBA,MAAM,oBAAoB,OAAO,QAAQ,EACvC,MAAM,EACJ,kBAAkB,WACnB,EACF,CAAC;AAEF,MAAM,mBAAmB,OAAO,UAAU,EACxC,MAAM;CACJ,QAAQ;CACR,QAAQ;CACR,OAAO;CACR,EACF,CAAC;AASF,MAAa,aAAa,UAAe,CAAC,OAAO,MAAM,QAAQ,OAAO,WAAW,MAAM,CAAC;AAExF,MAAM,kBAAkB,MAA2B,YAAqC;CACtF,MAAM,EAAE,SAAS,SAAS,SAAS,cAAc;CAEjD,MAAM,SAAS,QAAQ,QAAQ,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,GAAG,MAAM,EAAG,SAAU,EAAE,OAAQ,CAAC;AAErG,QAAO;EACL,KAAK,kCAAkC,QAAQ,GAAG,OAAO,8BAA8B;EACvF,QAAQ,QAAQ,UAAU;EAC1B,OAAO,QAAQ,SAAS;EACzB;;AAEH,MAAa,mBAAmB,EAAE,OAAO,gBAAgB,WAAW,WAAkB;CACpF,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,KAAK;CAChE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,YAAY,OAA0B,KAAK;CACjD,MAAM,EAAE,cAAc;CACtB,MAAM,gBAAgB,GAAG,EAAE,mBAAmB,CAAC,IAAI,UAAU;CAC7D,MAAM,oBAAoB,cAAc;AACtC,MAAI,MAAM,UAAU,WAAW,kBAAkB,UAC/C,QAAO,MAAM,UAAU,UAAU,MAAM,MAAM,UAAU,QAAQ,GAAG;WACzD,MAAM,WAAW,aAAa,MAAM,KAAK,YAClD,QAAO,MAAM,MAAM,KAAK,YAAY;IAErC,CAAC,OAAO,cAAc,CAAC;AAE1B,iBAAgB;EACd,MAAM,SAAS,UAAU;AACzB,MAAI,QAAQ;GACV,MAAM,CAAC,OAAO,UAAU,CAAC,SAAS,OAAO,MAAM,EAAE,SAAS,OAAO,OAAO,CAAC;AACzE,UAAO,MAAM,cAAc,GAAG,MAAM,GAAG;AACvC,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AACN,KAAI,MAAM,WAAW,QACnB,QACE,oBAAC;EAAsB,MAAK;YAC1B,oBAAC;GACC,KAAK;GACL,OAAO,UAAU,OAAO;GACxB,cAAY,UAAU,OAAO;GAC7B,GAAI,eAAe,WAAW,EAAE,CAAC;GACjC,OAAM;IACN;GACoB;CAG5B,MAAM,EAAE,SAAS;CAEjB,MAAM,gBAAgB,UAAU,KAAK,MAAM,KAAK,GAAG,KAAK,MAAM,OAAO;CAErE,MAAM,qBAAqB,eAAe,WAAW,KAAK,QAAQ;CAClE,MAAM,wBAAwB,gBAC1B,eAAe;EAAE,GAAG;EAAW,SAAS;EAAe,EAAE,KAAK,QAAQ,GACtE;CAEJ,MAAM,eAAe,kBAAkB,MAAM,WAAW,QAAQ,SAAS,MAAM,UAAU,QAAQ;CAEjG,MAAM,QAAQ,KAAK,MAAM,MAAM,GAAG,GAAG,EAAE,mBAAmB,CAAC,IAAI,KAAK,SAAS;AAE7E,QACE,qBAAC;EAAO,mBAAgB;EAAa,GAAI;aACvC,oBAAC;GAAI,WAAU;aACb,oBAAC;IACC,KAAK;IACL,WAAU;IACH;IACP,cAAY;IACZ,GAAK,yBAAyB,CAAC,oBAAoB,wBAAwB;IAC3E,OAAM;KACN;IACE,EACN,oBAAC;GAAY,MAAK;GAAQ,WAAW,KAAK;GAAY,aAAa;aACjE,oBAAC,mBACE,CAAC,CAAC,iBACD,oBAAC;IAAkB,MAAK;IAAQ,SAAQ;IAAY,eAAe,sBAAsB,MAAM,CAAC,EAAE;cAC/F,EAAE,iBAAiB,CAAC,oBAAoB,aAAa,gBAAgB;KACpD,GAElB;IACM;GACP"}
1
+ {"version":3,"file":"BrightcoveEmbed.mjs","names":[],"sources":["../../src/Embed/BrightcoveEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport parse from \"html-react-parser\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Button, Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { BrightcoveEmbedData, BrightcoveMetaData, BrightcoveVideoSource } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport type { RenderContext } from \"./types\";\nimport { EmbedByline } from \"../LicenseByline/EmbedByline\";\nimport { licenseAttributes } from \"../utils/licenseAttributes\";\n\ninterface Props {\n embed: BrightcoveMetaData;\n renderContext?: RenderContext;\n lang?: string;\n}\n\nconst LinkedVideoButton = styled(Button, {\n base: {\n marginBlockStart: \"3xsmall\",\n },\n});\n\nconst BrightcoveIframe = styled(\"iframe\", {\n base: {\n border: 0,\n height: \"auto\",\n width: \"100%\",\n },\n});\n\nexport const makeIframeString = (url: string, width: string | number, height: string | number, title = \"\") => {\n const strippedWidth = typeof width === \"number\" ? width : width.replace(/\\s*px/, \"\");\n const strippedHeight = typeof height === \"number\" ? height : height.replace(/\\s*px/, \"\");\n const urlOrTitle = title || url;\n return `<iframe title=\"${urlOrTitle}\" aria-label=\"${urlOrTitle}\" src=\"${url}\" width=\"${strippedWidth}\" height=\"${strippedHeight}\" allowfullscreen scrolling=\"no\" frameborder=\"0\" loading=\"lazy\"></iframe>`;\n};\n\nexport const isNumeric = (value: any) => !Number.isNaN(value - Number.parseFloat(value));\n\nconst getIframeProps = (data: BrightcoveEmbedData, sources: BrightcoveVideoSource[]) => {\n const { account, videoid, player = \"default\" } = data;\n\n const source = sources.filter((s) => s.width && s.height).toSorted((a, b) => a!.height! - b.height!)[0];\n\n return {\n src: `https://players.brightcove.net/${account}/${player}_default/index.html?videoId=${videoid}`,\n height: source?.height ?? \"480\",\n width: source?.width ?? \"640\",\n };\n};\nexport const BrightcoveEmbed = ({ embed, renderContext = \"article\", lang }: Props) => {\n const [showOriginalVideo, setShowOriginalVideo] = useState(true);\n const { t } = useTranslation();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const { embedData } = embed;\n const fallbackTitle = `${t(\"embed.type.video\")}: ${embedData.videoid}`;\n const parsedDescription = useMemo(() => {\n if (embed.embedData.caption || renderContext === \"article\") {\n return embed.embedData.caption ? parse(embed.embedData.caption) : undefined;\n } else if (embed.status === \"success\" && embed.data.description) {\n return parse(embed.data.description);\n }\n }, [embed, renderContext]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (iframe) {\n const [width, height] = [parseInt(iframe.width), parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width}/${height}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n if (embed.status === \"error\") {\n return (\n <EmbedErrorPlaceholder type=\"video\">\n <BrightcoveIframe\n ref={iframeRef}\n title={embedData.alt || fallbackTitle}\n aria-label={embedData.alt || fallbackTitle}\n {...getIframeProps(embedData, [])}\n allow=\"fullscreen; encrypted-media\"\n />\n </EmbedErrorPlaceholder>\n );\n }\n const { data } = embed;\n\n const linkedVideoId = isNumeric(data.link?.text) ? data.link?.text : undefined;\n\n const originalVideoProps = getIframeProps(embedData, data.sources);\n const alternativeVideoProps = linkedVideoId\n ? getIframeProps({ ...embedData, videoid: linkedVideoId }, data.sources)\n : undefined;\n\n const licenseProps = licenseAttributes(data?.copyright?.license.license, lang, embedData.pageUrl);\n\n const title = data.name?.trim() ? `${t(\"embed.type.video\")}: ${data.name}` : fallbackTitle;\n\n return (\n <Figure data-embed-type=\"brightcove\" {...licenseProps}>\n <div className=\"brightcove-video\">\n <BrightcoveIframe\n ref={iframeRef}\n className=\"original\"\n title={title}\n aria-label={title}\n {...(alternativeVideoProps && !showOriginalVideo ? alternativeVideoProps : originalVideoProps)}\n allow=\"fullscreen; encrypted-media\"\n />\n </div>\n <EmbedByline type=\"video\" copyright={data.copyright!} description={parsedDescription}>\n <div>\n {!!linkedVideoId && (\n <LinkedVideoButton size=\"small\" variant=\"secondary\" onClick={() => setShowOriginalVideo((p) => !p)}>\n {t(`figure.button.${!showOriginalVideo ? \"original\" : \"alternative\"}`)}\n </LinkedVideoButton>\n )}\n </div>\n </EmbedByline>\n </Figure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,MAAM,oBAAoB,OAAO,QAAQ,EACvC,MAAM,EACJ,kBAAkB,WACnB,EACF,CAAC;AAEF,MAAM,mBAAmB,OAAO,UAAU,EACxC,MAAM;CACJ,QAAQ;CACR,QAAQ;CACR,OAAO;CACR,EACF,CAAC;AASF,MAAa,aAAa,UAAe,CAAC,OAAO,MAAM,QAAQ,OAAO,WAAW,MAAM,CAAC;AAExF,MAAM,kBAAkB,MAA2B,YAAqC;CACtF,MAAM,EAAE,SAAS,SAAS,SAAS,cAAc;CAEjD,MAAM,SAAS,QAAQ,QAAQ,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,GAAG,MAAM,EAAG,SAAU,EAAE,OAAQ,CAAC;AAErG,QAAO;EACL,KAAK,kCAAkC,QAAQ,GAAG,OAAO,8BAA8B;EACvF,QAAQ,QAAQ,UAAU;EAC1B,OAAO,QAAQ,SAAS;EACzB;;AAEH,MAAa,mBAAmB,EAAE,OAAO,gBAAgB,WAAW,WAAkB;CACpF,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,KAAK;CAChE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,YAAY,OAA0B,KAAK;CACjD,MAAM,EAAE,cAAc;CACtB,MAAM,gBAAgB,GAAG,EAAE,mBAAmB,CAAC,IAAI,UAAU;CAC7D,MAAM,oBAAoB,cAAc;AACtC,MAAI,MAAM,UAAU,WAAW,kBAAkB,UAC/C,QAAO,MAAM,UAAU,UAAU,MAAM,MAAM,UAAU,QAAQ,GAAG;WACzD,MAAM,WAAW,aAAa,MAAM,KAAK,YAClD,QAAO,MAAM,MAAM,KAAK,YAAY;IAErC,CAAC,OAAO,cAAc,CAAC;AAE1B,iBAAgB;EACd,MAAM,SAAS,UAAU;AACzB,MAAI,QAAQ;GACV,MAAM,CAAC,OAAO,UAAU,CAAC,SAAS,OAAO,MAAM,EAAE,SAAS,OAAO,OAAO,CAAC;AACzE,UAAO,MAAM,cAAc,GAAG,MAAM,GAAG;AACvC,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AACN,KAAI,MAAM,WAAW,QACnB,QACE,oBAAC;EAAsB,MAAK;YAC1B,oBAAC;GACC,KAAK;GACL,OAAO,UAAU,OAAO;GACxB,cAAY,UAAU,OAAO;GAC7B,GAAI,eAAe,WAAW,EAAE,CAAC;GACjC,OAAM;IACN;GACoB;CAG5B,MAAM,EAAE,SAAS;CAEjB,MAAM,gBAAgB,UAAU,KAAK,MAAM,KAAK,GAAG,KAAK,MAAM,OAAO;CAErE,MAAM,qBAAqB,eAAe,WAAW,KAAK,QAAQ;CAClE,MAAM,wBAAwB,gBAC1B,eAAe;EAAE,GAAG;EAAW,SAAS;EAAe,EAAE,KAAK,QAAQ,GACtE;CAEJ,MAAM,eAAe,kBAAkB,MAAM,WAAW,QAAQ,SAAS,MAAM,UAAU,QAAQ;CAEjG,MAAM,QAAQ,KAAK,MAAM,MAAM,GAAG,GAAG,EAAE,mBAAmB,CAAC,IAAI,KAAK,SAAS;AAE7E,QACE,qBAAC;EAAO,mBAAgB;EAAa,GAAI;aACvC,oBAAC;GAAI,WAAU;aACb,oBAAC;IACC,KAAK;IACL,WAAU;IACH;IACP,cAAY;IACZ,GAAK,yBAAyB,CAAC,oBAAoB,wBAAwB;IAC3E,OAAM;KACN;IACE,EACN,oBAAC;GAAY,MAAK;GAAQ,WAAW,KAAK;GAAY,aAAa;aACjE,oBAAC,mBACE,CAAC,CAAC,iBACD,oBAAC;IAAkB,MAAK;IAAQ,SAAQ;IAAY,eAAe,sBAAsB,MAAM,CAAC,EAAE;cAC/F,EAAE,iBAAiB,CAAC,oBAAoB,aAAa,gBAAgB;KACpD,GAElB;IACM;GACP"}
@@ -9,6 +9,13 @@ import { CheckLine, FileCopyLine } from "@ndla/icons";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
 
11
11
  //#region src/Embed/CodeEmbed.tsx
12
+ /**
13
+ * Copyright (c) 2023-present, NDLA.
14
+ *
15
+ * This source code is licensed under the GPLv3 license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ *
18
+ */
12
19
  const StyledFigCaption = styled("figcaption", { base: {
13
20
  textStyle: "label.large",
14
21
  fontWeight: "bold"
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEmbed.mjs","names":[],"sources":["../../src/Embed/CodeEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { FileCopyLine, CheckLine } from \"@ndla/icons\";\nimport { Button, Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { CodeMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { CodeBlock } from \"../CodeBlock/CodeBlock\";\nimport { codeLanguageOptions, type ICodeLangugeOption } from \"../CodeBlock/codeLanguageOptions\";\n\ninterface Props {\n embed: CodeMetaData;\n}\n\nconst StyledFigCaption = styled(\"figcaption\", {\n base: {\n textStyle: \"label.large\",\n fontWeight: \"bold\",\n },\n});\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n // We apply margin here to allow for the float and size props on figure to work as intended.\n \"& > *:not(:where(:first-child))\": {\n marginBlockStart: \"xsmall\",\n },\n },\n});\n\nconst getTitleFromFormat = (format: string) => {\n const selectedLanguage = codeLanguageOptions.find((item: ICodeLangugeOption) => item.format === format);\n if (selectedLanguage) {\n return selectedLanguage.title;\n }\n return;\n};\n\nexport const CodeEmbed = ({ embed }: Props) => {\n const [isCopied, setIsCopied] = useState(false);\n const { t } = useTranslation();\n\n useEffect(() => {\n if (isCopied) {\n const timer = setInterval(() => setIsCopied(false), 3000);\n // ensure interval is cleared - also if unmounted\n return () => {\n clearTimeout(timer);\n };\n }\n }, [isCopied]);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"code\" />;\n }\n\n return (\n <StyledFigure data-embed-type=\"code-block\">\n <StyledFigCaption>{embed.embedData.title || getTitleFromFormat(embed.embedData.codeFormat)}</StyledFigCaption>\n <CodeBlock\n highlightedCode={embed.status === \"success\" ? embed.data.highlightedCode : \"\"}\n format={embed.embedData.codeFormat}\n />\n <Button\n variant=\"secondary\"\n onClick={async () => {\n if (embed.status === \"success\") {\n try {\n await navigator.clipboard.writeText(embed.data.decodedContent);\n setIsCopied(true);\n } catch {\n // do nothing\n }\n }\n }}\n >\n {isCopied ? <CheckLine /> : <FileCopyLine />}\n {isCopied ? t(\"codeBlock.copiedCode\") : t(\"codeBlock.copyCode\")}\n </Button>\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;AAsBA,MAAM,mBAAmB,OAAO,cAAc,EAC5C,MAAM;CACJ,WAAW;CACX,YAAY;CACb,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM;CACJ,OAAO;CAEP,mCAAmC,EACjC,kBAAkB,UACnB;CACF,EACF,CAAC;AAEF,MAAM,sBAAsB,WAAmB;CAC7C,MAAM,mBAAmB,oBAAoB,MAAM,SAA6B,KAAK,WAAW,OAAO;AACvG,KAAI,iBACF,QAAO,iBAAiB;;AAK5B,MAAa,aAAa,EAAE,YAAmB;CAC7C,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;CAC/C,MAAM,EAAE,MAAM,gBAAgB;AAE9B,iBAAgB;AACd,MAAI,UAAU;GACZ,MAAM,QAAQ,kBAAkB,YAAY,MAAM,EAAE,IAAK;AAEzD,gBAAa;AACX,iBAAa,MAAM;;;IAGtB,CAAC,SAAS,CAAC;AAEd,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAAsB,MAAK,SAAS;AAG9C,QACE,qBAAC;EAAa,mBAAgB;;GAC5B,oBAAC,8BAAkB,MAAM,UAAU,SAAS,mBAAmB,MAAM,UAAU,WAAW,GAAoB;GAC9G,oBAAC;IACC,iBAAiB,MAAM,WAAW,YAAY,MAAM,KAAK,kBAAkB;IAC3E,QAAQ,MAAM,UAAU;KACxB;GACF,qBAAC;IACC,SAAQ;IACR,SAAS,YAAY;AACnB,SAAI,MAAM,WAAW,UACnB,KAAI;AACF,YAAM,UAAU,UAAU,UAAU,MAAM,KAAK,eAAe;AAC9D,kBAAY,KAAK;aACX;;eAMX,WAAW,oBAAC,cAAY,GAAG,oBAAC,iBAAe,EAC3C,WAAW,EAAE,uBAAuB,GAAG,EAAE,qBAAqB;KACxD;;GACI"}
1
+ {"version":3,"file":"CodeEmbed.mjs","names":[],"sources":["../../src/Embed/CodeEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { FileCopyLine, CheckLine } from \"@ndla/icons\";\nimport { Button, Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { CodeMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { CodeBlock } from \"../CodeBlock/CodeBlock\";\nimport { codeLanguageOptions, type ICodeLangugeOption } from \"../CodeBlock/codeLanguageOptions\";\n\ninterface Props {\n embed: CodeMetaData;\n}\n\nconst StyledFigCaption = styled(\"figcaption\", {\n base: {\n textStyle: \"label.large\",\n fontWeight: \"bold\",\n },\n});\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n // We apply margin here to allow for the float and size props on figure to work as intended.\n \"& > *:not(:where(:first-child))\": {\n marginBlockStart: \"xsmall\",\n },\n },\n});\n\nconst getTitleFromFormat = (format: string) => {\n const selectedLanguage = codeLanguageOptions.find((item: ICodeLangugeOption) => item.format === format);\n if (selectedLanguage) {\n return selectedLanguage.title;\n }\n return;\n};\n\nexport const CodeEmbed = ({ embed }: Props) => {\n const [isCopied, setIsCopied] = useState(false);\n const { t } = useTranslation();\n\n useEffect(() => {\n if (isCopied) {\n const timer = setInterval(() => setIsCopied(false), 3000);\n // ensure interval is cleared - also if unmounted\n return () => {\n clearTimeout(timer);\n };\n }\n }, [isCopied]);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"code\" />;\n }\n\n return (\n <StyledFigure data-embed-type=\"code-block\">\n <StyledFigCaption>{embed.embedData.title || getTitleFromFormat(embed.embedData.codeFormat)}</StyledFigCaption>\n <CodeBlock\n highlightedCode={embed.status === \"success\" ? embed.data.highlightedCode : \"\"}\n format={embed.embedData.codeFormat}\n />\n <Button\n variant=\"secondary\"\n onClick={async () => {\n if (embed.status === \"success\") {\n try {\n await navigator.clipboard.writeText(embed.data.decodedContent);\n setIsCopied(true);\n } catch {\n // do nothing\n }\n }\n }}\n >\n {isCopied ? <CheckLine /> : <FileCopyLine />}\n {isCopied ? t(\"codeBlock.copiedCode\") : t(\"codeBlock.copyCode\")}\n </Button>\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsBA,MAAM,mBAAmB,OAAO,cAAc,EAC5C,MAAM;CACJ,WAAW;CACX,YAAY;CACb,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM;CACJ,OAAO;CAEP,mCAAmC,EACjC,kBAAkB,UACnB;CACF,EACF,CAAC;AAEF,MAAM,sBAAsB,WAAmB;CAC7C,MAAM,mBAAmB,oBAAoB,MAAM,SAA6B,KAAK,WAAW,OAAO;AACvG,KAAI,iBACF,QAAO,iBAAiB;;AAK5B,MAAa,aAAa,EAAE,YAAmB;CAC7C,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;CAC/C,MAAM,EAAE,MAAM,gBAAgB;AAE9B,iBAAgB;AACd,MAAI,UAAU;GACZ,MAAM,QAAQ,kBAAkB,YAAY,MAAM,EAAE,IAAK;AAEzD,gBAAa;AACX,iBAAa,MAAM;;;IAGtB,CAAC,SAAS,CAAC;AAEd,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAAsB,MAAK,SAAS;AAG9C,QACE,qBAAC;EAAa,mBAAgB;;GAC5B,oBAAC,8BAAkB,MAAM,UAAU,SAAS,mBAAmB,MAAM,UAAU,WAAW,GAAoB;GAC9G,oBAAC;IACC,iBAAiB,MAAM,WAAW,YAAY,MAAM,KAAK,kBAAkB;IAC3E,QAAQ,MAAM,UAAU;KACxB;GACF,qBAAC;IACC,SAAQ;IACR,SAAS,YAAY;AACnB,SAAI,MAAM,WAAW,UACnB,KAAI;AACF,YAAM,UAAU,UAAU,UAAU,MAAM,KAAK,eAAe;AAC9D,kBAAY,KAAK;aACX;;eAMX,WAAW,oBAAC,cAAY,GAAG,oBAAC,iBAAe,EAC3C,WAAW,EAAE,uBAAuB,GAAG,EAAE,qBAAqB;KACxD;;GACI"}
@@ -10,6 +10,13 @@ import { jsx, jsxs } from "react/jsx-runtime";
10
10
  import { Portal } from "@ark-ui/react";
11
11
 
12
12
  //#region src/Embed/ConceptEmbed.tsx
13
+ /**
14
+ * Copyright (c) 2024-present, NDLA.
15
+ *
16
+ * This source code is licensed under the GPLv3 license found in the
17
+ * LICENSE file in the root directory of this source tree.
18
+ *
19
+ */
13
20
  const StyledPopoverContent = styled(PopoverContent, { base: {
14
21
  width: "surface.xlarge",
15
22
  maxHeight: "50vh",
@@ -1 +1 @@
1
- {"version":3,"file":"ConceptEmbed.mjs","names":[],"sources":["../../src/Embed/ConceptEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport parse from \"html-react-parser\";\nimport { forwardRef, useMemo, useRef, type ReactNode } from \"react\";\nimport { Portal } from \"@ark-ui/react\";\nimport { PopoverContent, PopoverRoot, PopoverTrigger } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { ConceptMetaData } from \"@ndla/types-embed\";\nimport { ConceptInlineTriggerButton } from \"./ConceptInlineTriggerButton\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { GlossEmbed } from \"./GlossEmbed\";\nimport type { RenderContext } from \"./types\";\nimport { Concept, type ConceptProps } from \"../Concept/Concept\";\n\ninterface BaseProps {\n renderContext?: RenderContext;\n lang?: string;\n previewAlt?: boolean;\n}\n\ninterface Props extends BaseProps {\n embed: ConceptMetaData;\n children?: ReactNode;\n}\n\nconst StyledPopoverContent = styled(PopoverContent, {\n base: {\n width: \"surface.xlarge\",\n maxHeight: \"50vh\",\n overflowY: \"auto\",\n },\n});\n\nexport const ConceptEmbed = ({ embed, renderContext, lang, previewAlt, children }: Props) => {\n const parsedContent = useMemo(() => {\n if (embed.status === \"error\" || !embed.data.concept.content) return undefined;\n return parse(embed.data.concept.content.htmlContent);\n }, [embed]);\n\n const parsedTitle = useMemo(\n () => (embed.status === \"success\" ? parse(embed.data.concept.title.htmlTitle) : undefined),\n [embed],\n );\n\n if (embed.status === \"error\" && embed.embedData.type === \"inline\") {\n return <span>{children}</span>;\n }\n if (embed.status === \"error\") {\n // TODO: This could be either concept or gloss. We don't know if it errors out. :)\n return <EmbedErrorPlaceholder type=\"gloss\" />;\n }\n\n const { concept, visualElement } = embed.data;\n\n // TODO: Consider whether we should do this in article-converter instead.\n if (embed.data.concept.glossData) {\n return <GlossEmbed embed={embed} />;\n }\n\n if (embed.embedData.type === \"inline\") {\n return (\n <InlineConcept\n previewAlt={previewAlt}\n linkContent={children}\n copyright={concept.copyright}\n visualElement={visualElement}\n lang={lang}\n title={parsedTitle}\n source={concept.source}\n >\n {parsedContent}\n </InlineConcept>\n );\n }\n\n return (\n <BlockConcept\n previewAlt={previewAlt}\n copyright={concept.copyright}\n visualElement={visualElement}\n lang={lang}\n title={renderContext === \"embed\" ? undefined : parsedTitle}\n source={concept.source}\n >\n {parsedContent}\n </BlockConcept>\n );\n};\n\nexport interface InlineConceptProps extends ConceptProps, BaseProps {\n linkContent?: ReactNode;\n source?: string;\n}\n\nexport const InlineConcept = forwardRef<HTMLSpanElement, InlineConceptProps>(\n ({ linkContent, copyright, visualElement, previewAlt, lang, children, title, source, ...rest }, ref) => {\n const contentRef = useRef<HTMLDivElement>(null);\n return (\n <PopoverRoot initialFocusEl={() => contentRef.current}>\n {/* @ts-expect-error placing ref and rest on popover trigger somehow removes a bug where the popover target becomes a bit bigger */}\n <PopoverTrigger asChild ref={ref} {...rest}>\n <ConceptInlineTriggerButton>{linkContent}</ConceptInlineTriggerButton>\n </PopoverTrigger>\n <Portal>\n <StyledPopoverContent ref={contentRef}>\n <Concept\n copyright={copyright}\n visualElement={visualElement}\n title={title}\n lang={lang}\n source={source}\n previewAlt={previewAlt}\n >\n {children}\n </Concept>\n </StyledPopoverContent>\n </Portal>\n </PopoverRoot>\n );\n },\n);\n\nexport interface BlockConceptProps extends ConceptProps {}\n\nexport const BlockConcept = forwardRef<HTMLElement, BlockConceptProps>((props, ref) => (\n <Concept {...props} data-embed-type=\"concept\" ref={ref} />\n));\n"],"mappings":";;;;;;;;;;;;AA+BA,MAAM,uBAAuB,OAAO,gBAAgB,EAClD,MAAM;CACJ,OAAO;CACP,WAAW;CACX,WAAW;CACZ,EACF,CAAC;AAEF,MAAa,gBAAgB,EAAE,OAAO,eAAe,MAAM,YAAY,eAAsB;CAC3F,MAAM,gBAAgB,cAAc;AAClC,MAAI,MAAM,WAAW,WAAW,CAAC,MAAM,KAAK,QAAQ,QAAS,QAAO;AACpE,SAAO,MAAM,MAAM,KAAK,QAAQ,QAAQ,YAAY;IACnD,CAAC,MAAM,CAAC;CAEX,MAAM,cAAc,cACX,MAAM,WAAW,YAAY,MAAM,MAAM,KAAK,QAAQ,MAAM,UAAU,GAAG,QAChF,CAAC,MAAM,CACR;AAED,KAAI,MAAM,WAAW,WAAW,MAAM,UAAU,SAAS,SACvD,QAAO,oBAAC,UAAM,WAAgB;AAEhC,KAAI,MAAM,WAAW,QAEnB,QAAO,oBAAC,yBAAsB,MAAK,UAAU;CAG/C,MAAM,EAAE,SAAS,kBAAkB,MAAM;AAGzC,KAAI,MAAM,KAAK,QAAQ,UACrB,QAAO,oBAAC,cAAkB,QAAS;AAGrC,KAAI,MAAM,UAAU,SAAS,SAC3B,QACE,oBAAC;EACa;EACZ,aAAa;EACb,WAAW,QAAQ;EACJ;EACT;EACN,OAAO;EACP,QAAQ,QAAQ;YAEf;GACa;AAIpB,QACE,oBAAC;EACa;EACZ,WAAW,QAAQ;EACJ;EACT;EACN,OAAO,kBAAkB,UAAU,SAAY;EAC/C,QAAQ,QAAQ;YAEf;GACY;;AASnB,MAAa,gBAAgB,YAC1B,EAAE,aAAa,WAAW,eAAe,YAAY,MAAM,UAAU,OAAO,OAAQ,GAAG,QAAQ,QAAQ;CACtG,MAAM,aAAa,OAAuB,KAAK;AAC/C,QACE,qBAAC;EAAY,sBAAsB,WAAW;aAE5C,oBAAC;GAAe;GAAa;GAAK,GAAI;aACpC,oBAAC,wCAA4B,cAAyC;IACvD,EACjB,oBAAC,oBACC,oBAAC;GAAqB,KAAK;aACzB,oBAAC;IACY;IACI;IACR;IACD;IACE;IACI;IAEX;KACO;IACW,GAChB;GACG;EAGnB;AAID,MAAa,eAAe,YAA4C,OAAO,QAC7E,oBAAC;CAAQ,GAAI;CAAO,mBAAgB;CAAe;EAAO,CAC1D"}
1
+ {"version":3,"file":"ConceptEmbed.mjs","names":[],"sources":["../../src/Embed/ConceptEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport parse from \"html-react-parser\";\nimport { forwardRef, useMemo, useRef, type ReactNode } from \"react\";\nimport { Portal } from \"@ark-ui/react\";\nimport { PopoverContent, PopoverRoot, PopoverTrigger } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { ConceptMetaData } from \"@ndla/types-embed\";\nimport { ConceptInlineTriggerButton } from \"./ConceptInlineTriggerButton\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { GlossEmbed } from \"./GlossEmbed\";\nimport type { RenderContext } from \"./types\";\nimport { Concept, type ConceptProps } from \"../Concept/Concept\";\n\ninterface BaseProps {\n renderContext?: RenderContext;\n lang?: string;\n previewAlt?: boolean;\n}\n\ninterface Props extends BaseProps {\n embed: ConceptMetaData;\n children?: ReactNode;\n}\n\nconst StyledPopoverContent = styled(PopoverContent, {\n base: {\n width: \"surface.xlarge\",\n maxHeight: \"50vh\",\n overflowY: \"auto\",\n },\n});\n\nexport const ConceptEmbed = ({ embed, renderContext, lang, previewAlt, children }: Props) => {\n const parsedContent = useMemo(() => {\n if (embed.status === \"error\" || !embed.data.concept.content) return undefined;\n return parse(embed.data.concept.content.htmlContent);\n }, [embed]);\n\n const parsedTitle = useMemo(\n () => (embed.status === \"success\" ? parse(embed.data.concept.title.htmlTitle) : undefined),\n [embed],\n );\n\n if (embed.status === \"error\" && embed.embedData.type === \"inline\") {\n return <span>{children}</span>;\n }\n if (embed.status === \"error\") {\n // TODO: This could be either concept or gloss. We don't know if it errors out. :)\n return <EmbedErrorPlaceholder type=\"gloss\" />;\n }\n\n const { concept, visualElement } = embed.data;\n\n // TODO: Consider whether we should do this in article-converter instead.\n if (embed.data.concept.glossData) {\n return <GlossEmbed embed={embed} />;\n }\n\n if (embed.embedData.type === \"inline\") {\n return (\n <InlineConcept\n previewAlt={previewAlt}\n linkContent={children}\n copyright={concept.copyright}\n visualElement={visualElement}\n lang={lang}\n title={parsedTitle}\n source={concept.source}\n >\n {parsedContent}\n </InlineConcept>\n );\n }\n\n return (\n <BlockConcept\n previewAlt={previewAlt}\n copyright={concept.copyright}\n visualElement={visualElement}\n lang={lang}\n title={renderContext === \"embed\" ? undefined : parsedTitle}\n source={concept.source}\n >\n {parsedContent}\n </BlockConcept>\n );\n};\n\nexport interface InlineConceptProps extends ConceptProps, BaseProps {\n linkContent?: ReactNode;\n source?: string;\n}\n\nexport const InlineConcept = forwardRef<HTMLSpanElement, InlineConceptProps>(\n ({ linkContent, copyright, visualElement, previewAlt, lang, children, title, source, ...rest }, ref) => {\n const contentRef = useRef<HTMLDivElement>(null);\n return (\n <PopoverRoot initialFocusEl={() => contentRef.current}>\n {/* @ts-expect-error placing ref and rest on popover trigger somehow removes a bug where the popover target becomes a bit bigger */}\n <PopoverTrigger asChild ref={ref} {...rest}>\n <ConceptInlineTriggerButton>{linkContent}</ConceptInlineTriggerButton>\n </PopoverTrigger>\n <Portal>\n <StyledPopoverContent ref={contentRef}>\n <Concept\n copyright={copyright}\n visualElement={visualElement}\n title={title}\n lang={lang}\n source={source}\n previewAlt={previewAlt}\n >\n {children}\n </Concept>\n </StyledPopoverContent>\n </Portal>\n </PopoverRoot>\n );\n },\n);\n\nexport interface BlockConceptProps extends ConceptProps {}\n\nexport const BlockConcept = forwardRef<HTMLElement, BlockConceptProps>((props, ref) => (\n <Concept {...props} data-embed-type=\"concept\" ref={ref} />\n));\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA+BA,MAAM,uBAAuB,OAAO,gBAAgB,EAClD,MAAM;CACJ,OAAO;CACP,WAAW;CACX,WAAW;CACZ,EACF,CAAC;AAEF,MAAa,gBAAgB,EAAE,OAAO,eAAe,MAAM,YAAY,eAAsB;CAC3F,MAAM,gBAAgB,cAAc;AAClC,MAAI,MAAM,WAAW,WAAW,CAAC,MAAM,KAAK,QAAQ,QAAS,QAAO;AACpE,SAAO,MAAM,MAAM,KAAK,QAAQ,QAAQ,YAAY;IACnD,CAAC,MAAM,CAAC;CAEX,MAAM,cAAc,cACX,MAAM,WAAW,YAAY,MAAM,MAAM,KAAK,QAAQ,MAAM,UAAU,GAAG,QAChF,CAAC,MAAM,CACR;AAED,KAAI,MAAM,WAAW,WAAW,MAAM,UAAU,SAAS,SACvD,QAAO,oBAAC,UAAM,WAAgB;AAEhC,KAAI,MAAM,WAAW,QAEnB,QAAO,oBAAC,yBAAsB,MAAK,UAAU;CAG/C,MAAM,EAAE,SAAS,kBAAkB,MAAM;AAGzC,KAAI,MAAM,KAAK,QAAQ,UACrB,QAAO,oBAAC,cAAkB,QAAS;AAGrC,KAAI,MAAM,UAAU,SAAS,SAC3B,QACE,oBAAC;EACa;EACZ,aAAa;EACb,WAAW,QAAQ;EACJ;EACT;EACN,OAAO;EACP,QAAQ,QAAQ;YAEf;GACa;AAIpB,QACE,oBAAC;EACa;EACZ,WAAW,QAAQ;EACJ;EACT;EACN,OAAO,kBAAkB,UAAU,SAAY;EAC/C,QAAQ,QAAQ;YAEf;GACY;;AASnB,MAAa,gBAAgB,YAC1B,EAAE,aAAa,WAAW,eAAe,YAAY,MAAM,UAAU,OAAO,OAAQ,GAAG,QAAQ,QAAQ;CACtG,MAAM,aAAa,OAAuB,KAAK;AAC/C,QACE,qBAAC;EAAY,sBAAsB,WAAW;aAE5C,oBAAC;GAAe;GAAa;GAAK,GAAI;aACpC,oBAAC,wCAA4B,cAAyC;IACvD,EACjB,oBAAC,oBACC,oBAAC;GAAqB,KAAK;aACzB,oBAAC;IACY;IACI;IACR;IACD;IACE;IACI;IAEX;KACO;IACW,GAChB;GACG;EAGnB;AAID,MAAa,eAAe,YAA4C,OAAO,QAC7E,oBAAC;CAAQ,GAAI;CAAO,mBAAgB;CAAe;EAAO,CAC1D"}
@@ -2,6 +2,13 @@ import { InlineTriggerButton } from "./InlineTriggerButton.mjs";
2
2
  import { styled } from "@ndla/styled-system/jsx";
3
3
 
4
4
  //#region src/Embed/ConceptInlineTriggerButton.tsx
5
+ /**
6
+ * Copyright (c) 2024-present, NDLA.
7
+ *
8
+ * This source code is licensed under the GPLv3 license found in the
9
+ * LICENSE file in the root directory of this source tree.
10
+ *
11
+ */
5
12
  const ConceptInlineTriggerButton = styled(InlineTriggerButton, { base: {
6
13
  position: "relative",
7
14
  overflow: "visible",
@@ -1 +1 @@
1
- {"version":3,"file":"ConceptInlineTriggerButton.mjs","names":[],"sources":["../../src/Embed/ConceptInlineTriggerButton.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport { InlineTriggerButton } from \"./InlineTriggerButton\";\n\nexport const ConceptInlineTriggerButton = styled(InlineTriggerButton, {\n base: {\n position: \"relative\",\n overflow: \"visible\",\n borderBottom: \"1px solid\",\n borderStyle: \"dashed\",\n borderColor: \"stroke.hover\",\n paddingBlockStart: \"5xsmall\",\n width: \"fit-content\",\n cursor: \"pointer\",\n _hover: {\n borderColor: \"text.link\",\n background: \"surface.actionSubtle.hover\",\n },\n _active: {\n borderColor: \"text.link\",\n background: \"surface.actionSubtle.active\",\n },\n // The global focus ring forces the border-radius to be xsmall, causing the dashed border to be cut off. This is a workaround.\n _focusVisible: {\n outline: \"none\",\n borderRadius: \"0\",\n _after: {\n content: '\"\"',\n position: \"absolute\",\n inset: \"0\",\n outline: \"3px\",\n borderRadius: \"xsmall\",\n outlineColor: \"stroke.default\",\n outlineOffset: \"3px\",\n outlineStyle: \"solid\",\n },\n },\n },\n});\n"],"mappings":";;;;AAWA,MAAa,6BAA6B,OAAO,qBAAqB,EACpE,MAAM;CACJ,UAAU;CACV,UAAU;CACV,cAAc;CACd,aAAa;CACb,aAAa;CACb,mBAAmB;CACnB,OAAO;CACP,QAAQ;CACR,QAAQ;EACN,aAAa;EACb,YAAY;EACb;CACD,SAAS;EACP,aAAa;EACb,YAAY;EACb;CAED,eAAe;EACb,SAAS;EACT,cAAc;EACd,QAAQ;GACN,SAAS;GACT,UAAU;GACV,OAAO;GACP,SAAS;GACT,cAAc;GACd,cAAc;GACd,eAAe;GACf,cAAc;GACf;EACF;CACF,EACF,CAAC"}
1
+ {"version":3,"file":"ConceptInlineTriggerButton.mjs","names":[],"sources":["../../src/Embed/ConceptInlineTriggerButton.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport { InlineTriggerButton } from \"./InlineTriggerButton\";\n\nexport const ConceptInlineTriggerButton = styled(InlineTriggerButton, {\n base: {\n position: \"relative\",\n overflow: \"visible\",\n borderBottom: \"1px solid\",\n borderStyle: \"dashed\",\n borderColor: \"stroke.hover\",\n paddingBlockStart: \"5xsmall\",\n width: \"fit-content\",\n cursor: \"pointer\",\n _hover: {\n borderColor: \"text.link\",\n background: \"surface.actionSubtle.hover\",\n },\n _active: {\n borderColor: \"text.link\",\n background: \"surface.actionSubtle.active\",\n },\n // The global focus ring forces the border-radius to be xsmall, causing the dashed border to be cut off. This is a workaround.\n _focusVisible: {\n outline: \"none\",\n borderRadius: \"0\",\n _after: {\n content: '\"\"',\n position: \"absolute\",\n inset: \"0\",\n outline: \"3px\",\n borderRadius: \"xsmall\",\n outlineColor: \"stroke.default\",\n outlineOffset: \"3px\",\n outlineStyle: \"solid\",\n },\n },\n },\n});\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,6BAA6B,OAAO,qBAAqB,EACpE,MAAM;CACJ,UAAU;CACV,UAAU;CACV,cAAc;CACd,aAAa;CACb,aAAa;CACb,mBAAmB;CACnB,OAAO;CACP,QAAQ;CACR,QAAQ;EACN,aAAa;EACb,YAAY;EACb;CACD,SAAS;EACP,aAAa;EACb,YAAY;EACb;CAED,eAAe;EACb,SAAS;EACT,cAAc;EACd,QAAQ;GACN,SAAS;GACT,UAAU;GACV,OAAO;GACP,SAAS;GACT,cAAc;GACd,cAAc;GACd,eAAe;GACf,cAAc;GACf;EACF;CACF,EACF,CAAC"}
@@ -5,6 +5,13 @@ import { ark } from "@ark-ui/react";
5
5
  import { css, cva } from "@ndla/styled-system/css";
6
6
 
7
7
  //#region src/Embed/EmbedWrapper.tsx
8
+ /**
9
+ * Copyright (c) 2024-present, NDLA.
10
+ *
11
+ * This source code is licensed under the GPLv3 license found in the
12
+ * LICENSE file in the root directory of this source tree.
13
+ *
14
+ */
8
15
  const embedWrapperRecipe = cva({
9
16
  base: { position: "relative" },
10
17
  defaultVariants: { noClear: false },
@@ -1 +1 @@
1
- {"version":3,"file":"EmbedWrapper.mjs","names":[],"sources":["../../src/Embed/EmbedWrapper.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { forwardRef } from \"react\";\nimport { ark, type HTMLArkProps } from \"@ark-ui/react\";\nimport { css, cva } from \"@ndla/styled-system/css\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { StyledProps, RecipeVariantProps } from \"@ndla/styled-system/types\";\n\nconst embedWrapperRecipe = cva({\n base: {\n position: \"relative\",\n },\n defaultVariants: {\n noClear: false,\n },\n variants: {\n noClear: {\n true: {\n \"& + [data-embed-wrapper]\": {\n clear: \"both\",\n },\n },\n false: {\n clear: \"both\",\n },\n },\n },\n});\n\nexport type EmbedWrapperVariantProps = NonNullable<RecipeVariantProps<typeof embedWrapperRecipe>>;\n\nexport interface EmbedWrapperProps extends HTMLArkProps<\"div\">, StyledProps, EmbedWrapperVariantProps {}\n\nconst StyledEmbedWrapper = styled(ark.div, {}, { baseComponent: true });\n\nexport const EmbedWrapper = forwardRef<HTMLDivElement, EmbedWrapperProps>(\n ({ noClear, css: cssProp, ...props }, ref) => (\n <StyledEmbedWrapper\n css={css.raw(embedWrapperRecipe.raw({ noClear }), cssProp)}\n data-embed-wrapper=\"\"\n {...props}\n ref={ref}\n />\n ),\n);\n"],"mappings":";;;;;;;AAcA,MAAM,qBAAqB,IAAI;CAC7B,MAAM,EACJ,UAAU,YACX;CACD,iBAAiB,EACf,SAAS,OACV;CACD,UAAU,EACR,SAAS;EACP,MAAM,EACJ,4BAA4B,EAC1B,OAAO,QACR,EACF;EACD,OAAO,EACL,OAAO,QACR;EACF,EACF;CACF,CAAC;AAMF,MAAM,qBAAqB,OAAO,IAAI,KAAK,EAAE,EAAE,EAAE,eAAe,MAAM,CAAC;AAEvE,MAAa,eAAe,YACzB,EAAE,SAAS,KAAK,QAAS,GAAG,SAAS,QACpC,oBAAC;CACC,KAAK,IAAI,IAAI,mBAAmB,IAAI,EAAE,SAAS,CAAC,EAAE,QAAQ;CAC1D,sBAAmB;CACnB,GAAI;CACC;EACL,CAEL"}
1
+ {"version":3,"file":"EmbedWrapper.mjs","names":[],"sources":["../../src/Embed/EmbedWrapper.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { forwardRef } from \"react\";\nimport { ark, type HTMLArkProps } from \"@ark-ui/react\";\nimport { css, cva } from \"@ndla/styled-system/css\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { StyledProps, RecipeVariantProps } from \"@ndla/styled-system/types\";\n\nconst embedWrapperRecipe = cva({\n base: {\n position: \"relative\",\n },\n defaultVariants: {\n noClear: false,\n },\n variants: {\n noClear: {\n true: {\n \"& + [data-embed-wrapper]\": {\n clear: \"both\",\n },\n },\n false: {\n clear: \"both\",\n },\n },\n },\n});\n\nexport type EmbedWrapperVariantProps = NonNullable<RecipeVariantProps<typeof embedWrapperRecipe>>;\n\nexport interface EmbedWrapperProps extends HTMLArkProps<\"div\">, StyledProps, EmbedWrapperVariantProps {}\n\nconst StyledEmbedWrapper = styled(ark.div, {}, { baseComponent: true });\n\nexport const EmbedWrapper = forwardRef<HTMLDivElement, EmbedWrapperProps>(\n ({ noClear, css: cssProp, ...props }, ref) => (\n <StyledEmbedWrapper\n css={css.raw(embedWrapperRecipe.raw({ noClear }), cssProp)}\n data-embed-wrapper=\"\"\n {...props}\n ref={ref}\n />\n ),\n);\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAM,qBAAqB,IAAI;CAC7B,MAAM,EACJ,UAAU,YACX;CACD,iBAAiB,EACf,SAAS,OACV;CACD,UAAU,EACR,SAAS;EACP,MAAM,EACJ,4BAA4B,EAC1B,OAAO,QACR,EACF;EACD,OAAO,EACL,OAAO,QACR;EACF,EACF;CACF,CAAC;AAMF,MAAM,qBAAqB,OAAO,IAAI,KAAK,EAAE,EAAE,EAAE,eAAe,MAAM,CAAC;AAEvE,MAAa,eAAe,YACzB,EAAE,SAAS,KAAK,QAAS,GAAG,SAAS,QACpC,oBAAC;CACC,KAAK,IAAI,IAAI,mBAAmB,IAAI,EAAE,SAAS,CAAC,EAAE,QAAQ;CAC1D,sBAAmB;CACnB,GAAI;CACC;EACL,CAEL"}
@@ -7,6 +7,13 @@ import { useTranslation } from "react-i18next";
7
7
  import { jsx } from "react/jsx-runtime";
8
8
 
9
9
  //#region src/Embed/ExternalEmbed.tsx
10
+ /**
11
+ * Copyright (c) 2023-present, NDLA.
12
+ *
13
+ * This source code is licensed under the GPLv3 license found in the
14
+ * LICENSE file in the root directory of this source tree.
15
+ *
16
+ */
10
17
  const StyledFigure = styled(Figure, { base: { "& iframe": {
11
18
  height: "auto",
12
19
  width: "100%"
@@ -1 +1 @@
1
- {"version":3,"file":"ExternalEmbed.mjs","names":[],"sources":["../../src/Embed/ExternalEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { OembedMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { ResourceBox } from \"../ResourceBox/ResourceBox\";\n\ninterface Props {\n embed: OembedMetaData;\n}\n\nconst StyledFigure = styled(Figure, {\n base: {\n \"& iframe\": {\n height: \"auto\",\n width: \"100%\",\n },\n },\n});\n\nexport const ExternalEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n const figRef = useRef<HTMLElement>(null);\n\n useEffect(() => {\n const iframe = figRef.current?.querySelector(\"iframe\");\n if (iframe) {\n const [width, height] = [Number.parseInt(iframe.width), Number.parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"external\" />;\n }\n\n const { embedData, data } = embed;\n\n if (embedData.type === \"fullscreen\") {\n const image = {\n src: data.iframeImage?.image.imageUrl,\n alt: embedData.alt !== undefined ? embedData.alt : (data.iframeImage?.alttext?.alttext ?? \"\"),\n };\n return (\n <Figure data-embed-type=\"external\">\n <ResourceBox\n image={image}\n title={embedData.title ?? \"\"}\n url={embedData.url}\n caption={embedData.caption ?? \"\"}\n buttonText={t(\"license.other.itemImage.ariaLabel\")}\n />\n </Figure>\n );\n }\n\n return (\n <StyledFigure\n data-embed-type=\"external\"\n ref={figRef}\n dangerouslySetInnerHTML={{ __html: data?.oembed?.html ?? \"\" }}\n />\n );\n};\n"],"mappings":";;;;;;;;;AAoBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,YAAY;CACV,QAAQ;CACR,OAAO;CACR,EACF,EACF,CAAC;AAEF,MAAa,iBAAiB,EAAE,YAAmB;CACjD,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,SAAS,OAAoB,KAAK;AAExC,iBAAgB;EACd,MAAM,SAAS,OAAO,SAAS,cAAc,SAAS;AACtD,MAAI,QAAQ;GACV,MAAM,CAAC,OAAO,UAAU,CAAC,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,SAAS,OAAO,OAAO,CAAC;AACvF,UAAO,MAAM,cAAc,GAAG,QAAQ,QAAQ,GAAG,GAAG,SAAS,SAAS;AACtE,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AAEN,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAAsB,MAAK,aAAa;CAGlD,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,UAAU,SAAS,cAAc;EACnC,MAAM,QAAQ;GACZ,KAAK,KAAK,aAAa,MAAM;GAC7B,KAAK,UAAU,QAAQ,SAAY,UAAU,MAAO,KAAK,aAAa,SAAS,WAAW;GAC3F;AACD,SACE,oBAAC;GAAO,mBAAgB;aACtB,oBAAC;IACQ;IACP,OAAO,UAAU,SAAS;IAC1B,KAAK,UAAU;IACf,SAAS,UAAU,WAAW;IAC9B,YAAY,EAAE,oCAAoC;KAClD;IACK;;AAIb,QACE,oBAAC;EACC,mBAAgB;EAChB,KAAK;EACL,yBAAyB,EAAE,QAAQ,MAAM,QAAQ,QAAQ,IAAI;GAC7D"}
1
+ {"version":3,"file":"ExternalEmbed.mjs","names":[],"sources":["../../src/Embed/ExternalEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { OembedMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { ResourceBox } from \"../ResourceBox/ResourceBox\";\n\ninterface Props {\n embed: OembedMetaData;\n}\n\nconst StyledFigure = styled(Figure, {\n base: {\n \"& iframe\": {\n height: \"auto\",\n width: \"100%\",\n },\n },\n});\n\nexport const ExternalEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n const figRef = useRef<HTMLElement>(null);\n\n useEffect(() => {\n const iframe = figRef.current?.querySelector(\"iframe\");\n if (iframe) {\n const [width, height] = [Number.parseInt(iframe.width), Number.parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"external\" />;\n }\n\n const { embedData, data } = embed;\n\n if (embedData.type === \"fullscreen\") {\n const image = {\n src: data.iframeImage?.image.imageUrl,\n alt: embedData.alt !== undefined ? embedData.alt : (data.iframeImage?.alttext?.alttext ?? \"\"),\n };\n return (\n <Figure data-embed-type=\"external\">\n <ResourceBox\n image={image}\n title={embedData.title ?? \"\"}\n url={embedData.url}\n caption={embedData.caption ?? \"\"}\n buttonText={t(\"license.other.itemImage.ariaLabel\")}\n />\n </Figure>\n );\n }\n\n return (\n <StyledFigure\n data-embed-type=\"external\"\n ref={figRef}\n dangerouslySetInnerHTML={{ __html: data?.oembed?.html ?? \"\" }}\n />\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAoBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,YAAY;CACV,QAAQ;CACR,OAAO;CACR,EACF,EACF,CAAC;AAEF,MAAa,iBAAiB,EAAE,YAAmB;CACjD,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,SAAS,OAAoB,KAAK;AAExC,iBAAgB;EACd,MAAM,SAAS,OAAO,SAAS,cAAc,SAAS;AACtD,MAAI,QAAQ;GACV,MAAM,CAAC,OAAO,UAAU,CAAC,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,SAAS,OAAO,OAAO,CAAC;AACvF,UAAO,MAAM,cAAc,GAAG,QAAQ,QAAQ,GAAG,GAAG,SAAS,SAAS;AACtE,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AAEN,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAAsB,MAAK,aAAa;CAGlD,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,UAAU,SAAS,cAAc;EACnC,MAAM,QAAQ;GACZ,KAAK,KAAK,aAAa,MAAM;GAC7B,KAAK,UAAU,QAAQ,SAAY,UAAU,MAAO,KAAK,aAAa,SAAS,WAAW;GAC3F;AACD,SACE,oBAAC;GAAO,mBAAgB;aACtB,oBAAC;IACQ;IACP,OAAO,UAAU,SAAS;IAC1B,KAAK,UAAU;IACf,SAAS,UAAU,WAAW;IAC9B,YAAY,EAAE,oCAAoC;KAClD;IACK;;AAIb,QACE,oBAAC;EACC,mBAAgB;EAChB,KAAK;EACL,yBAAyB,EAAE,QAAQ,MAAM,QAAQ,QAAQ,IAAI;GAC7D"}
@@ -3,6 +3,13 @@ import { useTranslation } from "react-i18next";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
 
5
5
  //#region src/Embed/FootnoteEmbed.tsx
6
+ /**
7
+ * Copyright (c) 2023-present, NDLA.
8
+ *
9
+ * This source code is licensed under the GPLv3 license found in the
10
+ * LICENSE file in the root directory of this source tree.
11
+ *
12
+ */
6
13
  const StyledSup = styled("sup", { base: { "& a": {
7
14
  textStyle: "label.xsmall",
8
15
  marginInlineStart: "1"
@@ -1 +1 @@
1
- {"version":3,"file":"FootnoteEmbed.mjs","names":[],"sources":["../../src/Embed/FootnoteEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useTranslation } from \"react-i18next\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { FootnoteMetaData } from \"@ndla/types-embed\";\n\ninterface Props {\n embed: FootnoteMetaData;\n}\n\nconst StyledSup = styled(\"sup\", {\n base: {\n \"& a\": {\n textStyle: \"label.xsmall\",\n marginInlineStart: \"1\",\n },\n },\n});\n\nexport const FootnoteEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n if (embed.status === \"error\") {\n return <div>{t(\"error\")}</div>;\n }\n\n return (\n <span id={`ref${embed.data.entryNum}`} data-embed-type=\"footnote\">\n <StyledSup>\n <a href={`#note${embed.data.entryNum}`} target=\"_self\">{`[${embed.data.entryNum}]`}</a>\n </StyledSup>\n </span>\n );\n};\n"],"mappings":";;;;;AAgBA,MAAM,YAAY,OAAO,OAAO,EAC9B,MAAM,EACJ,OAAO;CACL,WAAW;CACX,mBAAmB;CACpB,EACF,EACF,CAAC;AAEF,MAAa,iBAAiB,EAAE,YAAmB;CACjD,MAAM,EAAE,MAAM,gBAAgB;AAC9B,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,mBAAK,EAAE,QAAQ,GAAO;AAGhC,QACE,oBAAC;EAAK,IAAI,MAAM,MAAM,KAAK;EAAY,mBAAgB;YACrD,oBAAC,uBACC,oBAAC;GAAE,MAAM,QAAQ,MAAM,KAAK;GAAY,QAAO;aAAS,IAAI,MAAM,KAAK,SAAS;IAAO,GAC7E;GACP"}
1
+ {"version":3,"file":"FootnoteEmbed.mjs","names":[],"sources":["../../src/Embed/FootnoteEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useTranslation } from \"react-i18next\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { FootnoteMetaData } from \"@ndla/types-embed\";\n\ninterface Props {\n embed: FootnoteMetaData;\n}\n\nconst StyledSup = styled(\"sup\", {\n base: {\n \"& a\": {\n textStyle: \"label.xsmall\",\n marginInlineStart: \"1\",\n },\n },\n});\n\nexport const FootnoteEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n if (embed.status === \"error\") {\n return <div>{t(\"error\")}</div>;\n }\n\n return (\n <span id={`ref${embed.data.entryNum}`} data-embed-type=\"footnote\">\n <StyledSup>\n <a href={`#note${embed.data.entryNum}`} target=\"_self\">{`[${embed.data.entryNum}]`}</a>\n </StyledSup>\n </span>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAM,YAAY,OAAO,OAAO,EAC9B,MAAM,EACJ,OAAO;CACL,WAAW;CACX,mBAAmB;CACpB,EACF,EACF,CAAC;AAEF,MAAa,iBAAiB,EAAE,YAAmB;CACjD,MAAM,EAAE,MAAM,gBAAgB;AAC9B,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,mBAAK,EAAE,QAAQ,GAAO;AAGhC,QACE,oBAAC;EAAK,IAAI,MAAM,MAAM,KAAK;EAAY,mBAAgB;YACrD,oBAAC,uBACC,oBAAC;GAAE,MAAM,QAAQ,MAAM,KAAK;GAAY,QAAO;aAAS,IAAI,MAAM,KAAK,SAAS;IAAO,GAC7E;GACP"}
@@ -8,6 +8,13 @@ import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { Portal } from "@ark-ui/react";
9
9
 
10
10
  //#region src/Embed/GlossEmbed.tsx
11
+ /**
12
+ * Copyright (c) 2024-present, NDLA.
13
+ *
14
+ * This source code is licensed under the GPLv3 license found in the
15
+ * LICENSE file in the root directory of this source tree.
16
+ *
17
+ */
11
18
  const StyledPopoverContent = styled(PopoverContent, { base: { width: "surface.xlarge" } });
12
19
  const GlossEmbed = ({ embed, children }) => {
13
20
  const contentRef = useRef(null);
@@ -1 +1 @@
1
- {"version":3,"file":"GlossEmbed.mjs","names":[],"sources":["../../src/Embed/GlossEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useRef, type ReactNode } from \"react\";\nimport { Portal } from \"@ark-ui/react\";\nimport { Figure, PopoverContent, PopoverRoot, PopoverTrigger } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { ConceptMetaData } from \"@ndla/types-embed\";\nimport { ConceptInlineTriggerButton } from \"./ConceptInlineTriggerButton\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { Gloss } from \"../Gloss/Gloss\";\n\ninterface Props {\n embed: ConceptMetaData;\n children?: ReactNode;\n}\n\nconst StyledPopoverContent = styled(PopoverContent, {\n base: {\n width: \"surface.xlarge\",\n },\n});\n\nexport const GlossEmbed = ({ embed, children }: Props) => {\n const contentRef = useRef<HTMLDivElement>(null);\n if (embed.status === \"error\" && embed.embedData.type === \"inline\") {\n return <span>{children}</span>;\n }\n if (embed.status === \"error\" || !embed.data.concept.glossData) {\n return <EmbedErrorPlaceholder type=\"gloss\" />;\n }\n\n const { concept, visualElement } = embed.data;\n\n const audio =\n visualElement?.status === \"success\" && visualElement.resource === \"audio\"\n ? {\n src: visualElement.data.audioFile.url,\n title: visualElement.data.title.title,\n }\n : undefined;\n\n if (embed.embedData.type === \"inline\") {\n return (\n <PopoverRoot initialFocusEl={() => contentRef.current}>\n <PopoverTrigger asChild>\n <ConceptInlineTriggerButton>{children}</ConceptInlineTriggerButton>\n </PopoverTrigger>\n <Portal>\n <StyledPopoverContent ref={contentRef}>\n <Figure>\n <Gloss\n glossData={concept.glossData}\n title={concept.title}\n audio={audio}\n exampleIds={embed.embedData.exampleIds}\n exampleLangs={embed.embedData.exampleLangs}\n />\n </Figure>\n </StyledPopoverContent>\n </Portal>\n </PopoverRoot>\n );\n }\n\n return (\n <Figure data-embed-type=\"gloss\">\n <Gloss\n glossData={concept.glossData}\n title={concept.title}\n audio={audio}\n exampleIds={embed.embedData.exampleIds}\n exampleLangs={embed.embedData.exampleLangs}\n variant=\"bordered\"\n />\n </Figure>\n );\n};\n"],"mappings":";;;;;;;;;;AAsBA,MAAM,uBAAuB,OAAO,gBAAgB,EAClD,MAAM,EACJ,OAAO,kBACR,EACF,CAAC;AAEF,MAAa,cAAc,EAAE,OAAO,eAAsB;CACxD,MAAM,aAAa,OAAuB,KAAK;AAC/C,KAAI,MAAM,WAAW,WAAW,MAAM,UAAU,SAAS,SACvD,QAAO,oBAAC,UAAM,WAAgB;AAEhC,KAAI,MAAM,WAAW,WAAW,CAAC,MAAM,KAAK,QAAQ,UAClD,QAAO,oBAAC,yBAAsB,MAAK,UAAU;CAG/C,MAAM,EAAE,SAAS,kBAAkB,MAAM;CAEzC,MAAM,QACJ,eAAe,WAAW,aAAa,cAAc,aAAa,UAC9D;EACE,KAAK,cAAc,KAAK,UAAU;EAClC,OAAO,cAAc,KAAK,MAAM;EACjC,GACD;AAEN,KAAI,MAAM,UAAU,SAAS,SAC3B,QACE,qBAAC;EAAY,sBAAsB,WAAW;aAC5C,oBAAC;GAAe;aACd,oBAAC,8BAA4B,WAAsC;IACpD,EACjB,oBAAC,oBACC,oBAAC;GAAqB,KAAK;aACzB,oBAAC,oBACC,oBAAC;IACC,WAAW,QAAQ;IACnB,OAAO,QAAQ;IACR;IACP,YAAY,MAAM,UAAU;IAC5B,cAAc,MAAM,UAAU;KAC9B,GACK;IACY,GAChB;GACG;AAIlB,QACE,oBAAC;EAAO,mBAAgB;YACtB,oBAAC;GACC,WAAW,QAAQ;GACnB,OAAO,QAAQ;GACR;GACP,YAAY,MAAM,UAAU;GAC5B,cAAc,MAAM,UAAU;GAC9B,SAAQ;IACR;GACK"}
1
+ {"version":3,"file":"GlossEmbed.mjs","names":[],"sources":["../../src/Embed/GlossEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useRef, type ReactNode } from \"react\";\nimport { Portal } from \"@ark-ui/react\";\nimport { Figure, PopoverContent, PopoverRoot, PopoverTrigger } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { ConceptMetaData } from \"@ndla/types-embed\";\nimport { ConceptInlineTriggerButton } from \"./ConceptInlineTriggerButton\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { Gloss } from \"../Gloss/Gloss\";\n\ninterface Props {\n embed: ConceptMetaData;\n children?: ReactNode;\n}\n\nconst StyledPopoverContent = styled(PopoverContent, {\n base: {\n width: \"surface.xlarge\",\n },\n});\n\nexport const GlossEmbed = ({ embed, children }: Props) => {\n const contentRef = useRef<HTMLDivElement>(null);\n if (embed.status === \"error\" && embed.embedData.type === \"inline\") {\n return <span>{children}</span>;\n }\n if (embed.status === \"error\" || !embed.data.concept.glossData) {\n return <EmbedErrorPlaceholder type=\"gloss\" />;\n }\n\n const { concept, visualElement } = embed.data;\n\n const audio =\n visualElement?.status === \"success\" && visualElement.resource === \"audio\"\n ? {\n src: visualElement.data.audioFile.url,\n title: visualElement.data.title.title,\n }\n : undefined;\n\n if (embed.embedData.type === \"inline\") {\n return (\n <PopoverRoot initialFocusEl={() => contentRef.current}>\n <PopoverTrigger asChild>\n <ConceptInlineTriggerButton>{children}</ConceptInlineTriggerButton>\n </PopoverTrigger>\n <Portal>\n <StyledPopoverContent ref={contentRef}>\n <Figure>\n <Gloss\n glossData={concept.glossData}\n title={concept.title}\n audio={audio}\n exampleIds={embed.embedData.exampleIds}\n exampleLangs={embed.embedData.exampleLangs}\n />\n </Figure>\n </StyledPopoverContent>\n </Portal>\n </PopoverRoot>\n );\n }\n\n return (\n <Figure data-embed-type=\"gloss\">\n <Gloss\n glossData={concept.glossData}\n title={concept.title}\n audio={audio}\n exampleIds={embed.embedData.exampleIds}\n exampleLangs={embed.embedData.exampleLangs}\n variant=\"bordered\"\n />\n </Figure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAsBA,MAAM,uBAAuB,OAAO,gBAAgB,EAClD,MAAM,EACJ,OAAO,kBACR,EACF,CAAC;AAEF,MAAa,cAAc,EAAE,OAAO,eAAsB;CACxD,MAAM,aAAa,OAAuB,KAAK;AAC/C,KAAI,MAAM,WAAW,WAAW,MAAM,UAAU,SAAS,SACvD,QAAO,oBAAC,UAAM,WAAgB;AAEhC,KAAI,MAAM,WAAW,WAAW,CAAC,MAAM,KAAK,QAAQ,UAClD,QAAO,oBAAC,yBAAsB,MAAK,UAAU;CAG/C,MAAM,EAAE,SAAS,kBAAkB,MAAM;CAEzC,MAAM,QACJ,eAAe,WAAW,aAAa,cAAc,aAAa,UAC9D;EACE,KAAK,cAAc,KAAK,UAAU;EAClC,OAAO,cAAc,KAAK,MAAM;EACjC,GACD;AAEN,KAAI,MAAM,UAAU,SAAS,SAC3B,QACE,qBAAC;EAAY,sBAAsB,WAAW;aAC5C,oBAAC;GAAe;aACd,oBAAC,8BAA4B,WAAsC;IACpD,EACjB,oBAAC,oBACC,oBAAC;GAAqB,KAAK;aACzB,oBAAC,oBACC,oBAAC;IACC,WAAW,QAAQ;IACnB,OAAO,QAAQ;IACR;IACP,YAAY,MAAM,UAAU;IAC5B,cAAc,MAAM,UAAU;KAC9B,GACK;IACY,GAChB;GACG;AAIlB,QACE,oBAAC;EAAO,mBAAgB;YACtB,oBAAC;GACC,WAAW,QAAQ;GACnB,OAAO,QAAQ;GACR;GACP,YAAY,MAAM,UAAU;GAC5B,cAAc,MAAM,UAAU;GAC9B,SAAQ;IACR;GACK"}
@@ -5,6 +5,13 @@ import { useTranslation } from "react-i18next";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
 
7
7
  //#region src/Embed/H5pEmbed.tsx
8
+ /**
9
+ * Copyright (c) 2023-present, NDLA.
10
+ *
11
+ * This source code is licensed under the GPLv3 license found in the
12
+ * LICENSE file in the root directory of this source tree.
13
+ *
14
+ */
8
15
  const StyledFigure = styled(Figure, { base: { "& iframe": {
9
16
  height: "auto",
10
17
  width: "100%"
@@ -1 +1 @@
1
- {"version":3,"file":"H5pEmbed.mjs","names":[],"sources":["../../src/Embed/H5pEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useTranslation } from \"react-i18next\";\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { H5pMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\n\ninterface Props {\n embed: H5pMetaData;\n}\n\nconst StyledFigure = styled(Figure, {\n base: {\n \"& iframe\": {\n height: \"auto\",\n width: \"100%\",\n },\n },\n});\n\nconst FigureOembed = styled(Figure, {\n base: {\n width: \"100%\",\n \"& iframe\": {\n width: \"100%\",\n },\n },\n});\n\nexport const H5pEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"h5p\" />;\n }\n\n if (embed.data.oembed) {\n return <FigureOembed data-embed-type=\"h5p\" dangerouslySetInnerHTML={{ __html: embed.data.oembed.html ?? \"\" }} />;\n }\n\n const title = embed.embedData.title?.trim()\n ? embed.embedData.title\n : embed.data.h5pLicenseInformation?.h5p.title?.trim()\n ? embed.data.h5pLicenseInformation.h5p.title\n : embed.embedData.url;\n\n const titleWithPrefix = `${t(\"embed.type.h5p\")}: ${title}`;\n\n return (\n <StyledFigure data-embed-type=\"h5p\">\n <iframe title={titleWithPrefix} aria-label={titleWithPrefix} src={embed.embedData.url} />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;AAkBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,YAAY;CACV,QAAQ;CACR,OAAO;CACR,EACF,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM;CACJ,OAAO;CACP,YAAY,EACV,OAAO,QACR;CACF,EACF,CAAC;AAEF,MAAa,YAAY,EAAE,YAAmB;CAC5C,MAAM,EAAE,MAAM,gBAAgB;AAC9B,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAAsB,MAAK,QAAQ;AAG7C,KAAI,MAAM,KAAK,OACb,QAAO,oBAAC;EAAa,mBAAgB;EAAM,yBAAyB,EAAE,QAAQ,MAAM,KAAK,OAAO,QAAQ,IAAI;GAAI;CAGlH,MAAM,QAAQ,MAAM,UAAU,OAAO,MAAM,GACvC,MAAM,UAAU,QAChB,MAAM,KAAK,uBAAuB,IAAI,OAAO,MAAM,GACjD,MAAM,KAAK,sBAAsB,IAAI,QACrC,MAAM,UAAU;CAEtB,MAAM,kBAAkB,GAAG,EAAE,iBAAiB,CAAC,IAAI;AAEnD,QACE,oBAAC;EAAa,mBAAgB;YAC5B,oBAAC;GAAO,OAAO;GAAiB,cAAY;GAAiB,KAAK,MAAM,UAAU;IAAO;GAC5E"}
1
+ {"version":3,"file":"H5pEmbed.mjs","names":[],"sources":["../../src/Embed/H5pEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useTranslation } from \"react-i18next\";\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { H5pMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\n\ninterface Props {\n embed: H5pMetaData;\n}\n\nconst StyledFigure = styled(Figure, {\n base: {\n \"& iframe\": {\n height: \"auto\",\n width: \"100%\",\n },\n },\n});\n\nconst FigureOembed = styled(Figure, {\n base: {\n width: \"100%\",\n \"& iframe\": {\n width: \"100%\",\n },\n },\n});\n\nexport const H5pEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"h5p\" />;\n }\n\n if (embed.data.oembed) {\n return <FigureOembed data-embed-type=\"h5p\" dangerouslySetInnerHTML={{ __html: embed.data.oembed.html ?? \"\" }} />;\n }\n\n const title = embed.embedData.title?.trim()\n ? embed.embedData.title\n : embed.data.h5pLicenseInformation?.h5p.title?.trim()\n ? embed.data.h5pLicenseInformation.h5p.title\n : embed.embedData.url;\n\n const titleWithPrefix = `${t(\"embed.type.h5p\")}: ${title}`;\n\n return (\n <StyledFigure data-embed-type=\"h5p\">\n <iframe title={titleWithPrefix} aria-label={titleWithPrefix} src={embed.embedData.url} />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AAkBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,YAAY;CACV,QAAQ;CACR,OAAO;CACR,EACF,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM;CACJ,OAAO;CACP,YAAY,EACV,OAAO,QACR;CACF,EACF,CAAC;AAEF,MAAa,YAAY,EAAE,YAAmB;CAC5C,MAAM,EAAE,MAAM,gBAAgB;AAC9B,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAAsB,MAAK,QAAQ;AAG7C,KAAI,MAAM,KAAK,OACb,QAAO,oBAAC;EAAa,mBAAgB;EAAM,yBAAyB,EAAE,QAAQ,MAAM,KAAK,OAAO,QAAQ,IAAI;GAAI;CAGlH,MAAM,QAAQ,MAAM,UAAU,OAAO,MAAM,GACvC,MAAM,UAAU,QAChB,MAAM,KAAK,uBAAuB,IAAI,OAAO,MAAM,GACjD,MAAM,KAAK,sBAAsB,IAAI,QACrC,MAAM,UAAU;CAEtB,MAAM,kBAAkB,GAAG,EAAE,iBAAiB,CAAC,IAAI;AAEnD,QACE,oBAAC;EAAa,mBAAgB;YAC5B,oBAAC;GAAO,OAAO;GAAiB,cAAY;GAAiB,KAAK,MAAM,UAAU;IAAO;GAC5E"}
@@ -7,6 +7,13 @@ import { useTranslation } from "react-i18next";
7
7
  import { jsx } from "react/jsx-runtime";
8
8
 
9
9
  //#region src/Embed/IframeEmbed.tsx
10
+ /**
11
+ * Copyright (c) 2023-present, NDLA.
12
+ *
13
+ * This source code is licensed under the GPLv3 license found in the
14
+ * LICENSE file in the root directory of this source tree.
15
+ *
16
+ */
10
17
  const StyledIframe = styled("iframe", { base: {
11
18
  width: "100%",
12
19
  border: 0
@@ -1 +1 @@
1
- {"version":3,"file":"IframeEmbed.mjs","names":["width","height"],"sources":["../../src/Embed/IframeEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { IframeMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { ResourceBox } from \"../ResourceBox/ResourceBox\";\n\ninterface Props {\n embed: IframeMetaData;\n}\n\nconst StyledIframe = styled(\"iframe\", {\n base: {\n width: \"100%\",\n border: 0,\n },\n});\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n },\n});\n\nexport const IframeEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (iframe) {\n const [width, height] = [Number.parseInt(iframe.width), Number.parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"external\" />;\n }\n\n const { embedData, data } = embed;\n\n if (embedData.type === \"fullscreen\") {\n const iframeImage = embed.status === \"success\" ? data.iframeImage : undefined;\n const alt = embedData.alt !== undefined ? embedData.alt : iframeImage?.alttext.alttext;\n const image = { src: iframeImage?.image.imageUrl, alt: alt ?? \"\" };\n return (\n <StyledFigure data-embed-type=\"iframe\">\n <ResourceBox\n image={image}\n title={embedData.title ?? \"\"}\n url={embedData.url}\n caption={embedData.caption ?? \"\"}\n buttonText={t(\"license.other.itemImage.ariaLabel\")}\n />\n </StyledFigure>\n );\n }\n\n const { width, height, url } = embedData;\n\n const strippedWidth = typeof width === \"number\" ? width : width?.replace(/\\s*px/, \"\");\n const strippedHeight = typeof height === \"number\" ? height : height?.replace(/\\s*px/, \"\");\n const title = `${t(\"embed.type.external\")}: ${embedData.title?.trim() ? embedData.title : url}`;\n\n return (\n <StyledFigure data-embed-type=\"iframe\">\n <StyledIframe\n ref={iframeRef}\n title={title}\n aria-label={title}\n src={url}\n width={strippedWidth}\n height={strippedHeight}\n allow=\"fullscreen; encrypted-media\"\n loading=\"lazy\"\n />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;AAoBA,MAAM,eAAe,OAAO,UAAU,EACpC,MAAM;CACJ,OAAO;CACP,QAAQ;CACT,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,OAAO,QACR,EACF,CAAC;AAEF,MAAa,eAAe,EAAE,YAAmB;CAC/C,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,YAAY,OAA0B,KAAK;AAEjD,iBAAgB;EACd,MAAM,SAAS,UAAU;AACzB,MAAI,QAAQ;GACV,MAAM,CAACA,SAAOC,YAAU,CAAC,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,SAAS,OAAO,OAAO,CAAC;AACvF,UAAO,MAAM,cAAc,GAAGD,UAAQA,UAAQ,GAAG,GAAGC,WAASA,WAAS;AACtE,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AAEN,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAAsB,MAAK,aAAa;CAGlD,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,UAAU,SAAS,cAAc;EACnC,MAAM,cAAc,MAAM,WAAW,YAAY,KAAK,cAAc;EACpE,MAAM,MAAM,UAAU,QAAQ,SAAY,UAAU,MAAM,aAAa,QAAQ;EAC/E,MAAM,QAAQ;GAAE,KAAK,aAAa,MAAM;GAAU,KAAK,OAAO;GAAI;AAClE,SACE,oBAAC;GAAa,mBAAgB;aAC5B,oBAAC;IACQ;IACP,OAAO,UAAU,SAAS;IAC1B,KAAK,UAAU;IACf,SAAS,UAAU,WAAW;IAC9B,YAAY,EAAE,oCAAoC;KAClD;IACW;;CAInB,MAAM,EAAE,OAAO,QAAQ,QAAQ;CAE/B,MAAM,gBAAgB,OAAO,UAAU,WAAW,QAAQ,OAAO,QAAQ,SAAS,GAAG;CACrF,MAAM,iBAAiB,OAAO,WAAW,WAAW,SAAS,QAAQ,QAAQ,SAAS,GAAG;CACzF,MAAM,QAAQ,GAAG,EAAE,sBAAsB,CAAC,IAAI,UAAU,OAAO,MAAM,GAAG,UAAU,QAAQ;AAE1F,QACE,oBAAC;EAAa,mBAAgB;YAC5B,oBAAC;GACC,KAAK;GACE;GACP,cAAY;GACZ,KAAK;GACL,OAAO;GACP,QAAQ;GACR,OAAM;GACN,SAAQ;IACR;GACW"}
1
+ {"version":3,"file":"IframeEmbed.mjs","names":["width","height"],"sources":["../../src/Embed/IframeEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { IframeMetaData } from \"@ndla/types-embed\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport { ResourceBox } from \"../ResourceBox/ResourceBox\";\n\ninterface Props {\n embed: IframeMetaData;\n}\n\nconst StyledIframe = styled(\"iframe\", {\n base: {\n width: \"100%\",\n border: 0,\n },\n});\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n },\n});\n\nexport const IframeEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (iframe) {\n const [width, height] = [Number.parseInt(iframe.width), Number.parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"external\" />;\n }\n\n const { embedData, data } = embed;\n\n if (embedData.type === \"fullscreen\") {\n const iframeImage = embed.status === \"success\" ? data.iframeImage : undefined;\n const alt = embedData.alt !== undefined ? embedData.alt : iframeImage?.alttext.alttext;\n const image = { src: iframeImage?.image.imageUrl, alt: alt ?? \"\" };\n return (\n <StyledFigure data-embed-type=\"iframe\">\n <ResourceBox\n image={image}\n title={embedData.title ?? \"\"}\n url={embedData.url}\n caption={embedData.caption ?? \"\"}\n buttonText={t(\"license.other.itemImage.ariaLabel\")}\n />\n </StyledFigure>\n );\n }\n\n const { width, height, url } = embedData;\n\n const strippedWidth = typeof width === \"number\" ? width : width?.replace(/\\s*px/, \"\");\n const strippedHeight = typeof height === \"number\" ? height : height?.replace(/\\s*px/, \"\");\n const title = `${t(\"embed.type.external\")}: ${embedData.title?.trim() ? embedData.title : url}`;\n\n return (\n <StyledFigure data-embed-type=\"iframe\">\n <StyledIframe\n ref={iframeRef}\n title={title}\n aria-label={title}\n src={url}\n width={strippedWidth}\n height={strippedHeight}\n allow=\"fullscreen; encrypted-media\"\n loading=\"lazy\"\n />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAoBA,MAAM,eAAe,OAAO,UAAU,EACpC,MAAM;CACJ,OAAO;CACP,QAAQ;CACT,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,OAAO,QACR,EACF,CAAC;AAEF,MAAa,eAAe,EAAE,YAAmB;CAC/C,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,YAAY,OAA0B,KAAK;AAEjD,iBAAgB;EACd,MAAM,SAAS,UAAU;AACzB,MAAI,QAAQ;GACV,MAAM,CAACA,SAAOC,YAAU,CAAC,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,SAAS,OAAO,OAAO,CAAC;AACvF,UAAO,MAAM,cAAc,GAAGD,UAAQA,UAAQ,GAAG,GAAGC,WAASA,WAAS;AACtE,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AAEN,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,yBAAsB,MAAK,aAAa;CAGlD,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,UAAU,SAAS,cAAc;EACnC,MAAM,cAAc,MAAM,WAAW,YAAY,KAAK,cAAc;EACpE,MAAM,MAAM,UAAU,QAAQ,SAAY,UAAU,MAAM,aAAa,QAAQ;EAC/E,MAAM,QAAQ;GAAE,KAAK,aAAa,MAAM;GAAU,KAAK,OAAO;GAAI;AAClE,SACE,oBAAC;GAAa,mBAAgB;aAC5B,oBAAC;IACQ;IACP,OAAO,UAAU,SAAS;IAC1B,KAAK,UAAU;IACf,SAAS,UAAU,WAAW;IAC9B,YAAY,EAAE,oCAAoC;KAClD;IACW;;CAInB,MAAM,EAAE,OAAO,QAAQ,QAAQ;CAE/B,MAAM,gBAAgB,OAAO,UAAU,WAAW,QAAQ,OAAO,QAAQ,SAAS,GAAG;CACrF,MAAM,iBAAiB,OAAO,WAAW,WAAW,SAAS,QAAQ,QAAQ,SAAS,GAAG;CACzF,MAAM,QAAQ,GAAG,EAAE,sBAAsB,CAAC,IAAI,UAAU,OAAO,MAAM,GAAG,UAAU,QAAQ;AAE1F,QACE,oBAAC;EAAa,mBAAgB;YAC5B,oBAAC;GACC,KAAK;GACE;GACP,cAAY;GACZ,KAAK;GACL,OAAO;GACP,QAAQ;GACR,OAAM;GACN,SAAQ;IACR;GACW"}
@@ -10,6 +10,13 @@ import { AddLine } from "@ndla/icons";
10
10
  import { jsx, jsxs } from "react/jsx-runtime";
11
11
 
12
12
  //#region src/Embed/ImageEmbed.tsx
13
+ /**
14
+ * Copyright (c) 2023-present, NDLA.
15
+ *
16
+ * This source code is licensed under the GPLv3 license found in the
17
+ * LICENSE file in the root directory of this source tree.
18
+ *
19
+ */
13
20
  const getFigureProps = (size, float) => {
14
21
  const actualFloat = float === "left" ? "left" : float === "right" ? "right" : void 0;
15
22
  const replacedSize = size?.replace("-hide-byline", "") ?? "full";
@@ -111,7 +118,7 @@ const ExpandButton = styled("button", { base: {
111
118
  tabletDown: { display: "none" }
112
119
  } }, { defaultProps: { type: "button" } });
113
120
  const ImageEmbed = ({ embed, previewAlt, lang, renderContext = "article", children }) => {
114
- const [imageSizes, setImageSizes] = useState(void 0);
121
+ const [expanded, setExpanded] = useState(false);
115
122
  const figureProps = getFigureProps(embed.embedData.size, embed.embedData.align);
116
123
  const { t } = useTranslation();
117
124
  const parsedDescription = useMemo(() => {
@@ -129,13 +136,13 @@ const ImageEmbed = ({ embed, previewAlt, lang, renderContext = "article", childr
129
136
  const focalPoint = getFocalPoint(embedData);
130
137
  const crop = getCrop(embedData);
131
138
  const toggleImageSize = () => {
132
- setImageSizes((sizes$1) => !sizes$1 ? expandedSizes : void 0);
139
+ setExpanded((prev) => !prev);
133
140
  };
134
141
  const licenseProps = licenseAttributes(data.copyright.license.license, lang, embedData.url);
135
142
  const figureSize = figureProps?.float ? figureProps?.size ?? "medium" : "full";
136
143
  return /* @__PURE__ */ jsxs(StyledFigure, {
137
144
  float: figureProps?.float,
138
- size: imageSizes ? "full" : figureSize,
145
+ size: expanded ? "full" : figureSize,
139
146
  "data-embed-type": "image",
140
147
  ...licenseProps,
141
148
  children: [
@@ -147,16 +154,16 @@ const ImageEmbed = ({ embed, previewAlt, lang, renderContext = "article", childr
147
154
  focalPoint,
148
155
  contentType: data.image.contentType,
149
156
  crop,
150
- sizes: imageSizes ?? sizes,
157
+ sizes: expanded ? expandedSizes : sizes,
151
158
  alt: altText,
152
159
  src: data.image.imageUrl,
153
160
  lang,
154
161
  onClick: figureProps?.float ? toggleImageSize : void 0,
155
162
  variant: "rounded"
156
163
  }), (embedData.align === "right" || embedData.align === "left") && /* @__PURE__ */ jsx(ExpandButton, {
157
- "aria-label": t(`license.images.itemImage.zoom${imageSizes ? "Out" : ""}ImageButtonLabel`),
164
+ "aria-label": t(`license.images.itemImage.zoom${expanded ? "Out" : ""}ImageButtonLabel`),
158
165
  onClick: toggleImageSize,
159
- "data-expanded": !!imageSizes,
166
+ "data-expanded": expanded,
160
167
  children: /* @__PURE__ */ jsx(AddLine, {})
161
168
  })]
162
169
  }),