@ndla/ui 56.0.122-alpha.0 → 56.0.124-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 (314) hide show
  1. package/README.md +1 -1
  2. package/es/Article/Article.js +127 -0
  3. package/es/Article/Article.js.map +1 -0
  4. package/es/Article/ArticleByline.js +133 -0
  5. package/es/Article/ArticleByline.js.map +1 -0
  6. package/es/Article/ArticleFootNotes.js +40 -0
  7. package/es/Article/ArticleFootNotes.js.map +1 -0
  8. package/es/AudioPlayer/AudioPlayer.js +157 -0
  9. package/es/AudioPlayer/AudioPlayer.js.map +1 -0
  10. package/es/AudioPlayer/Controls.js +254 -0
  11. package/es/AudioPlayer/Controls.js.map +1 -0
  12. package/es/AudioPlayer/SpeechControl.js +40 -0
  13. package/es/AudioPlayer/SpeechControl.js.map +1 -0
  14. package/es/AudioPlayer/index.js +8 -0
  15. package/es/AudioPlayer/index.js.map +1 -0
  16. package/es/Breadcrumb/Breadcrumb.js +44 -0
  17. package/es/Breadcrumb/Breadcrumb.js.map +1 -0
  18. package/es/Breadcrumb/BreadcrumbItem.js +36 -0
  19. package/es/Breadcrumb/BreadcrumbItem.js.map +1 -0
  20. package/es/Breadcrumb/HomeBreadcrumb.js +44 -0
  21. package/es/Breadcrumb/HomeBreadcrumb.js.map +1 -0
  22. package/es/Breadcrumb/index.js +9 -0
  23. package/es/Breadcrumb/index.js.map +1 -0
  24. package/es/CampaignBlock/CampaignBlock.js +131 -0
  25. package/es/CampaignBlock/CampaignBlock.js.map +1 -0
  26. package/es/CodeBlock/CodeBlock.js +25 -0
  27. package/es/CodeBlock/CodeBlock.js.map +1 -0
  28. package/es/CodeBlock/codeLanguageOptions.js +114 -0
  29. package/es/CodeBlock/codeLanguageOptions.js.map +1 -0
  30. package/es/Concept/Concept.js +50 -0
  31. package/es/Concept/Concept.js.map +1 -0
  32. package/es/ContactBlock/ContactBlock.js +145 -0
  33. package/es/ContactBlock/ContactBlock.js.map +1 -0
  34. package/es/ContentTypeBadge/ContentTypeBadge.js +41 -0
  35. package/es/ContentTypeBadge/ContentTypeBadge.js.map +1 -0
  36. package/es/ContentTypeBlockQuote/ContentTypeBlockQuote.js +25 -0
  37. package/es/ContentTypeBlockQuote/ContentTypeBlockQuote.js.map +1 -0
  38. package/es/ContentTypeFramedContent/ContentTypeFramedContent.js +25 -0
  39. package/es/ContentTypeFramedContent/ContentTypeFramedContent.js.map +1 -0
  40. package/es/ContentTypeHero/ContentTypeHero.js +39 -0
  41. package/es/ContentTypeHero/ContentTypeHero.js.map +1 -0
  42. package/es/CopyParagraphButton/CopyParagraphButton.js +62 -0
  43. package/es/CopyParagraphButton/CopyParagraphButton.js.map +1 -0
  44. package/es/CopyParagraphButton/index.js +8 -0
  45. package/es/CopyParagraphButton/index.js.map +1 -0
  46. package/es/Embed/AudioEmbed.js +52 -0
  47. package/es/Embed/AudioEmbed.js.map +1 -0
  48. package/es/Embed/BrightcoveEmbed.js +96 -0
  49. package/es/Embed/BrightcoveEmbed.js.map +1 -0
  50. package/es/Embed/CodeEmbed.js +61 -0
  51. package/es/Embed/CodeEmbed.js.map +1 -0
  52. package/es/Embed/ConceptEmbed.js +78 -0
  53. package/es/Embed/ConceptEmbed.js.map +1 -0
  54. package/es/Embed/ConceptInlineTriggerButton.js +40 -0
  55. package/es/Embed/ConceptInlineTriggerButton.js.map +1 -0
  56. package/es/Embed/ContentLinkEmbed.js +31 -0
  57. package/es/Embed/ContentLinkEmbed.js.map +1 -0
  58. package/es/Embed/CopyrightEmbed.js +23 -0
  59. package/es/Embed/CopyrightEmbed.js.map +1 -0
  60. package/es/Embed/EmbedErrorPlaceholder.js +43 -0
  61. package/es/Embed/EmbedErrorPlaceholder.js.map +1 -0
  62. package/es/Embed/EmbedWrapper.js +26 -0
  63. package/es/Embed/EmbedWrapper.js.map +1 -0
  64. package/es/Embed/ExternalEmbed.js +54 -0
  65. package/es/Embed/ExternalEmbed.js.map +1 -0
  66. package/es/Embed/FootnoteEmbed.js +27 -0
  67. package/es/Embed/FootnoteEmbed.js.map +1 -0
  68. package/es/Embed/GlossEmbed.js +52 -0
  69. package/es/Embed/GlossEmbed.js.map +1 -0
  70. package/es/Embed/H5pEmbed.js +38 -0
  71. package/es/Embed/H5pEmbed.js.map +1 -0
  72. package/es/Embed/IframeEmbed.js +69 -0
  73. package/es/Embed/IframeEmbed.js.map +1 -0
  74. package/es/Embed/ImageEmbed.js +180 -0
  75. package/es/Embed/ImageEmbed.js.map +1 -0
  76. package/es/Embed/InlineTriggerButton.js +25 -0
  77. package/es/Embed/InlineTriggerButton.js.map +1 -0
  78. package/es/Embed/RelatedContentEmbed.js +38 -0
  79. package/es/Embed/RelatedContentEmbed.js.map +1 -0
  80. package/es/Embed/UnknownEmbed.js +20 -0
  81. package/es/Embed/UnknownEmbed.js.map +1 -0
  82. package/es/Embed/UuDisclaimerEmbed.js +54 -0
  83. package/es/Embed/UuDisclaimerEmbed.js.map +1 -0
  84. package/es/ErrorMessage/ErrorMessage.js +54 -0
  85. package/es/ErrorMessage/ErrorMessage.js.map +1 -0
  86. package/es/ErrorMessage/index.js +8 -0
  87. package/es/ErrorMessage/index.js.map +1 -0
  88. package/es/FactBox/FactBox.js +121 -0
  89. package/es/FactBox/FactBox.js.map +1 -0
  90. package/es/FactBox/index.js +8 -0
  91. package/es/FactBox/index.js.map +1 -0
  92. package/es/FileList/File.js +76 -0
  93. package/es/FileList/File.js.map +1 -0
  94. package/es/FileList/FileList.js +32 -0
  95. package/es/FileList/FileList.js.map +1 -0
  96. package/es/FileList/PdfFile.js +28 -0
  97. package/es/FileList/PdfFile.js.map +1 -0
  98. package/es/Gloss/Gloss.js +142 -0
  99. package/es/Gloss/Gloss.js.map +1 -0
  100. package/es/Gloss/GlossExample.js +46 -0
  101. package/es/Gloss/GlossExample.js.map +1 -0
  102. package/es/Grid/Grid.js +66 -0
  103. package/es/Grid/Grid.js.map +1 -0
  104. package/es/Grid/GridParallaxItem.js +21 -0
  105. package/es/Grid/GridParallaxItem.js.map +1 -0
  106. package/es/KeyFigure/KeyFigure.js +46 -0
  107. package/es/KeyFigure/KeyFigure.js.map +1 -0
  108. package/es/LicenseByline/EmbedByline.js +132 -0
  109. package/es/LicenseByline/EmbedByline.js.map +1 -0
  110. package/es/LicenseByline/LicenseLink.js +31 -0
  111. package/es/LicenseByline/LicenseLink.js.map +1 -0
  112. package/es/LinkBlock/LinkBlock.js +74 -0
  113. package/es/LinkBlock/LinkBlock.js.map +1 -0
  114. package/es/LinkBlock/LinkBlockSection.js +23 -0
  115. package/es/LinkBlock/LinkBlockSection.js.map +1 -0
  116. package/es/Pitch/Pitch.js +62 -0
  117. package/es/Pitch/Pitch.js.map +1 -0
  118. package/es/RelatedArticleList/RelatedArticleList.js +97 -0
  119. package/es/RelatedArticleList/RelatedArticleList.js.map +1 -0
  120. package/es/RelatedArticleList/index.js +8 -0
  121. package/es/RelatedArticleList/index.js.map +1 -0
  122. package/es/ResourceBox/ResourceBox.js +74 -0
  123. package/es/ResourceBox/ResourceBox.js.map +1 -0
  124. package/es/TagSelector/TagSelector.js +100 -0
  125. package/es/TagSelector/TagSelector.js.map +1 -0
  126. package/es/ZendeskButton/ZendeskButton.js +41 -0
  127. package/es/ZendeskButton/ZendeskButton.js.map +1 -0
  128. package/es/_virtual/rolldown_runtime.js +11 -0
  129. package/es/i18n/formatNestedMessages.js +17 -0
  130. package/es/i18n/formatNestedMessages.js.map +1 -0
  131. package/es/i18n/i18n.js +29 -0
  132. package/es/i18n/i18n.js.map +1 -0
  133. package/es/i18n/useComponentTranslations.js +155 -0
  134. package/es/i18n/useComponentTranslations.js.map +1 -0
  135. package/es/index.js +65 -0
  136. package/es/locale/messages-en.js +438 -0
  137. package/es/locale/messages-en.js.map +1 -0
  138. package/es/locale/messages-nb.js +438 -0
  139. package/es/locale/messages-nb.js.map +1 -0
  140. package/es/locale/messages-nn.js +438 -0
  141. package/es/locale/messages-nn.js.map +1 -0
  142. package/es/locale/messages-se.js +438 -0
  143. package/es/locale/messages-se.js.map +1 -0
  144. package/es/model/ContentType.js +72 -0
  145. package/es/model/ContentType.js.map +1 -0
  146. package/es/model/SubjectCategories.js +25 -0
  147. package/es/model/SubjectCategories.js.map +1 -0
  148. package/es/model/SubjectTypes.js +23 -0
  149. package/es/model/SubjectTypes.js.map +1 -0
  150. package/es/model/WordClass.js +53 -0
  151. package/es/model/WordClass.js.map +1 -0
  152. package/es/model/index.js +19 -0
  153. package/es/model/index.js.map +1 -0
  154. package/es/utils/licenseAttributes.js +16 -0
  155. package/es/utils/licenseAttributes.js.map +1 -0
  156. package/es/utils/relativeUrl.js +26 -0
  157. package/es/utils/relativeUrl.js.map +1 -0
  158. package/lib/Article/Article.js +134 -0
  159. package/lib/Article/Article.js.map +1 -0
  160. package/lib/Article/ArticleByline.js +135 -0
  161. package/lib/Article/ArticleByline.js.map +1 -0
  162. package/lib/Article/ArticleFootNotes.js +41 -0
  163. package/lib/Article/ArticleFootNotes.js.map +1 -0
  164. package/lib/AudioPlayer/AudioPlayer.js +158 -0
  165. package/lib/AudioPlayer/AudioPlayer.js.map +1 -0
  166. package/lib/AudioPlayer/Controls.js +255 -0
  167. package/lib/AudioPlayer/Controls.js.map +1 -0
  168. package/lib/AudioPlayer/SpeechControl.js +41 -0
  169. package/lib/AudioPlayer/SpeechControl.js.map +1 -0
  170. package/lib/AudioPlayer/index.js +8 -0
  171. package/lib/AudioPlayer/index.js.map +1 -0
  172. package/lib/Breadcrumb/Breadcrumb.js +45 -0
  173. package/lib/Breadcrumb/Breadcrumb.js.map +1 -0
  174. package/lib/Breadcrumb/BreadcrumbItem.js +37 -0
  175. package/lib/Breadcrumb/BreadcrumbItem.js.map +1 -0
  176. package/lib/Breadcrumb/HomeBreadcrumb.js +45 -0
  177. package/lib/Breadcrumb/HomeBreadcrumb.js.map +1 -0
  178. package/lib/Breadcrumb/index.js +9 -0
  179. package/lib/Breadcrumb/index.js.map +1 -0
  180. package/lib/CampaignBlock/CampaignBlock.js +132 -0
  181. package/lib/CampaignBlock/CampaignBlock.js.map +1 -0
  182. package/lib/CodeBlock/CodeBlock.js +26 -0
  183. package/lib/CodeBlock/CodeBlock.js.map +1 -0
  184. package/lib/CodeBlock/codeLanguageOptions.js +115 -0
  185. package/lib/CodeBlock/codeLanguageOptions.js.map +1 -0
  186. package/lib/Concept/Concept.js +51 -0
  187. package/lib/Concept/Concept.js.map +1 -0
  188. package/lib/ContactBlock/ContactBlock.js +147 -0
  189. package/lib/ContactBlock/ContactBlock.js.map +1 -0
  190. package/lib/ContentTypeBadge/ContentTypeBadge.js +43 -0
  191. package/lib/ContentTypeBadge/ContentTypeBadge.js.map +1 -0
  192. package/lib/ContentTypeBlockQuote/ContentTypeBlockQuote.js +26 -0
  193. package/lib/ContentTypeBlockQuote/ContentTypeBlockQuote.js.map +1 -0
  194. package/lib/ContentTypeFramedContent/ContentTypeFramedContent.js +26 -0
  195. package/lib/ContentTypeFramedContent/ContentTypeFramedContent.js.map +1 -0
  196. package/lib/ContentTypeHero/ContentTypeHero.js +40 -0
  197. package/lib/ContentTypeHero/ContentTypeHero.js.map +1 -0
  198. package/lib/CopyParagraphButton/CopyParagraphButton.js +63 -0
  199. package/lib/CopyParagraphButton/CopyParagraphButton.js.map +1 -0
  200. package/lib/CopyParagraphButton/index.js +8 -0
  201. package/lib/CopyParagraphButton/index.js.map +1 -0
  202. package/lib/Embed/AudioEmbed.js +53 -0
  203. package/lib/Embed/AudioEmbed.js.map +1 -0
  204. package/lib/Embed/BrightcoveEmbed.js +97 -0
  205. package/lib/Embed/BrightcoveEmbed.js.map +1 -0
  206. package/lib/Embed/CodeEmbed.js +62 -0
  207. package/lib/Embed/CodeEmbed.js.map +1 -0
  208. package/lib/Embed/ConceptEmbed.js +81 -0
  209. package/lib/Embed/ConceptEmbed.js.map +1 -0
  210. package/lib/Embed/ConceptInlineTriggerButton.js +41 -0
  211. package/lib/Embed/ConceptInlineTriggerButton.js.map +1 -0
  212. package/lib/Embed/ContentLinkEmbed.js +32 -0
  213. package/lib/Embed/ContentLinkEmbed.js.map +1 -0
  214. package/lib/Embed/CopyrightEmbed.js +24 -0
  215. package/lib/Embed/CopyrightEmbed.js.map +1 -0
  216. package/lib/Embed/EmbedErrorPlaceholder.js +44 -0
  217. package/lib/Embed/EmbedErrorPlaceholder.js.map +1 -0
  218. package/lib/Embed/EmbedWrapper.js +27 -0
  219. package/lib/Embed/EmbedWrapper.js.map +1 -0
  220. package/lib/Embed/ExternalEmbed.js +55 -0
  221. package/lib/Embed/ExternalEmbed.js.map +1 -0
  222. package/lib/Embed/FootnoteEmbed.js +28 -0
  223. package/lib/Embed/FootnoteEmbed.js.map +1 -0
  224. package/lib/Embed/GlossEmbed.js +53 -0
  225. package/lib/Embed/GlossEmbed.js.map +1 -0
  226. package/lib/Embed/H5pEmbed.js +39 -0
  227. package/lib/Embed/H5pEmbed.js.map +1 -0
  228. package/lib/Embed/IframeEmbed.js +70 -0
  229. package/lib/Embed/IframeEmbed.js.map +1 -0
  230. package/lib/Embed/ImageEmbed.js +183 -0
  231. package/lib/Embed/ImageEmbed.js.map +1 -0
  232. package/lib/Embed/InlineTriggerButton.js +26 -0
  233. package/lib/Embed/InlineTriggerButton.js.map +1 -0
  234. package/lib/Embed/RelatedContentEmbed.js +39 -0
  235. package/lib/Embed/RelatedContentEmbed.js.map +1 -0
  236. package/lib/Embed/UnknownEmbed.js +21 -0
  237. package/lib/Embed/UnknownEmbed.js.map +1 -0
  238. package/lib/Embed/UuDisclaimerEmbed.js +55 -0
  239. package/lib/Embed/UuDisclaimerEmbed.js.map +1 -0
  240. package/lib/ErrorMessage/ErrorMessage.js +55 -0
  241. package/lib/ErrorMessage/ErrorMessage.js.map +1 -0
  242. package/lib/ErrorMessage/index.js +8 -0
  243. package/lib/ErrorMessage/index.js.map +1 -0
  244. package/lib/FactBox/FactBox.js +122 -0
  245. package/lib/FactBox/FactBox.js.map +1 -0
  246. package/lib/FactBox/index.js +8 -0
  247. package/lib/FactBox/index.js.map +1 -0
  248. package/lib/FileList/File.js +78 -0
  249. package/lib/FileList/File.js.map +1 -0
  250. package/lib/FileList/FileList.js +35 -0
  251. package/lib/FileList/FileList.js.map +1 -0
  252. package/lib/FileList/PdfFile.js +29 -0
  253. package/lib/FileList/PdfFile.js.map +1 -0
  254. package/lib/Gloss/Gloss.js +143 -0
  255. package/lib/Gloss/Gloss.js.map +1 -0
  256. package/lib/Gloss/GlossExample.js +47 -0
  257. package/lib/Gloss/GlossExample.js.map +1 -0
  258. package/lib/Grid/Grid.js +67 -0
  259. package/lib/Grid/Grid.js.map +1 -0
  260. package/lib/Grid/GridParallaxItem.js +22 -0
  261. package/lib/Grid/GridParallaxItem.js.map +1 -0
  262. package/lib/KeyFigure/KeyFigure.js +47 -0
  263. package/lib/KeyFigure/KeyFigure.js.map +1 -0
  264. package/lib/LicenseByline/EmbedByline.js +134 -0
  265. package/lib/LicenseByline/EmbedByline.js.map +1 -0
  266. package/lib/LicenseByline/LicenseLink.js +32 -0
  267. package/lib/LicenseByline/LicenseLink.js.map +1 -0
  268. package/lib/LinkBlock/LinkBlock.js +75 -0
  269. package/lib/LinkBlock/LinkBlock.js.map +1 -0
  270. package/lib/LinkBlock/LinkBlockSection.js +24 -0
  271. package/lib/LinkBlock/LinkBlockSection.js.map +1 -0
  272. package/lib/Pitch/Pitch.js +63 -0
  273. package/lib/Pitch/Pitch.js.map +1 -0
  274. package/lib/RelatedArticleList/RelatedArticleList.js +99 -0
  275. package/lib/RelatedArticleList/RelatedArticleList.js.map +1 -0
  276. package/lib/RelatedArticleList/index.js +8 -0
  277. package/lib/RelatedArticleList/index.js.map +1 -0
  278. package/lib/ResourceBox/ResourceBox.js +75 -0
  279. package/lib/ResourceBox/ResourceBox.js.map +1 -0
  280. package/lib/TagSelector/TagSelector.js +108 -0
  281. package/lib/TagSelector/TagSelector.js.map +1 -0
  282. package/lib/ZendeskButton/ZendeskButton.js +42 -0
  283. package/lib/ZendeskButton/ZendeskButton.js.map +1 -0
  284. package/lib/_virtual/rolldown_runtime.js +42 -0
  285. package/lib/i18n/formatNestedMessages.js +18 -0
  286. package/lib/i18n/formatNestedMessages.js.map +1 -0
  287. package/lib/i18n/i18n.js +31 -0
  288. package/lib/i18n/i18n.js.map +1 -0
  289. package/lib/i18n/useComponentTranslations.js +163 -0
  290. package/lib/i18n/useComponentTranslations.js.map +1 -0
  291. package/lib/index.js +157 -0
  292. package/lib/locale/messages-en.js +439 -0
  293. package/lib/locale/messages-en.js.map +1 -0
  294. package/lib/locale/messages-nb.js +439 -0
  295. package/lib/locale/messages-nb.js.map +1 -0
  296. package/lib/locale/messages-nn.js +439 -0
  297. package/lib/locale/messages-nn.js.map +1 -0
  298. package/lib/locale/messages-se.js +439 -0
  299. package/lib/locale/messages-se.js.map +1 -0
  300. package/lib/model/ContentType.js +94 -0
  301. package/lib/model/ContentType.js.map +1 -0
  302. package/lib/model/SubjectCategories.js +30 -0
  303. package/lib/model/SubjectCategories.js.map +1 -0
  304. package/lib/model/SubjectTypes.js +28 -0
  305. package/lib/model/SubjectTypes.js.map +1 -0
  306. package/lib/model/WordClass.js +58 -0
  307. package/lib/model/WordClass.js.map +1 -0
  308. package/lib/model/index.js +19 -0
  309. package/lib/model/index.js.map +1 -0
  310. package/lib/utils/licenseAttributes.js +17 -0
  311. package/lib/utils/licenseAttributes.js.map +1 -0
  312. package/lib/utils/relativeUrl.js +26 -0
  313. package/lib/utils/relativeUrl.js.map +1 -0
  314. package/package.json +12 -11
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ndla-ui
2
2
 
3
- Main UI component library for NDLA.
3
+ Main UI component library for NDLA
4
4
 
5
5
  ## Installation
6
6
 
@@ -0,0 +1,127 @@
1
+ import { ContentTypeBadge } from "../ContentTypeBadge/ContentTypeBadge.js";
2
+ import { ArticleByline } from "./ArticleByline.js";
3
+ import { forwardRef } from "react";
4
+ import { Heading, Text } from "@ndla/primitives";
5
+ import { Stack, styled } from "@ndla/styled-system/jsx";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { ark } from "@ark-ui/react";
8
+ import { cx } from "@ndla/styled-system/css";
9
+
10
+ //#region src/Article/Article.tsx
11
+ const StyledArticleContent = styled(ark.section, {}, { baseComponent: true });
12
+ const ArticleContent = forwardRef(({ className,...props }, ref) => /* @__PURE__ */ jsx(StyledArticleContent, {
13
+ className: cx("ndla-article", className),
14
+ ...props,
15
+ ref
16
+ }));
17
+ const StyledArticleWrapper = styled(ark.article, { base: {
18
+ background: "background.default",
19
+ display: "flex",
20
+ flexDirection: "column",
21
+ color: "text.default",
22
+ alignItems: "center",
23
+ width: "100%",
24
+ overflowWrap: "break-word",
25
+ position: "relative",
26
+ "& mjx-stretchy-v > mjx-ext > mjx-c": { transform: "scaleY(100) translateY(0.075em)" },
27
+ _after: {
28
+ content: "",
29
+ display: "table",
30
+ clear: "both"
31
+ }
32
+ } }, { baseComponent: true });
33
+ const ArticleWrapper = forwardRef((props, ref) => /* @__PURE__ */ jsx(StyledArticleWrapper, {
34
+ "data-ndla-article": "",
35
+ ref,
36
+ ...props
37
+ }));
38
+ const ArticleHGroup = styled(ark.hgroup, { base: {
39
+ display: "flex",
40
+ width: "100%",
41
+ flexDirection: "column",
42
+ alignItems: "flex-start",
43
+ "& h1": { overflowWrap: "anywhere" }
44
+ } }, { baseComponent: true });
45
+ const ArticleHeader = styled(ark.header, { base: {
46
+ display: "flex",
47
+ flexDirection: "column",
48
+ gap: "medium",
49
+ alignItems: "flex-start",
50
+ width: "100%",
51
+ paddingBlockStart: "xxlarge",
52
+ overflowWrap: "anywhere"
53
+ } }, { baseComponent: true });
54
+ const ArticleFooter = styled(ark.footer, { base: {
55
+ display: "flex",
56
+ flexDirection: "column",
57
+ gap: "xxlarge",
58
+ width: "100%",
59
+ "& > :is(:last-child)": { paddingBlockEnd: "5xlarge" }
60
+ } }, { baseComponent: true });
61
+ const StyledStack = styled(Stack, { base: {
62
+ width: "100%",
63
+ minHeight: "xxlarge"
64
+ } });
65
+ const StyledWrapper = styled("div", { base: {
66
+ display: "flex",
67
+ gap: "small",
68
+ flexWrap: "wrap",
69
+ alignItems: "center"
70
+ } });
71
+ const ArticleTitle = ({ contentType, heartButton, title, lang, id, introduction, contentTypeLabel, competenceGoals, disclaimer }) => {
72
+ return /* @__PURE__ */ jsxs(ArticleHeader, { children: [
73
+ /* @__PURE__ */ jsxs(ArticleHGroup, { children: [(!!contentType || !!heartButton) && /* @__PURE__ */ jsxs(StyledStack, {
74
+ justify: "space-between",
75
+ align: "center",
76
+ direction: "row",
77
+ gap: "small",
78
+ children: [!!contentType && /* @__PURE__ */ jsx(ContentTypeBadge, {
79
+ contentType,
80
+ children: contentTypeLabel
81
+ }), heartButton]
82
+ }), /* @__PURE__ */ jsx(Heading, {
83
+ textStyle: "heading.medium",
84
+ id,
85
+ lang,
86
+ property: "dct:title",
87
+ children: title
88
+ })] }),
89
+ !!introduction && /* @__PURE__ */ jsx(Text, {
90
+ lang,
91
+ textStyle: "body.xlarge",
92
+ asChild: true,
93
+ consumeCss: true,
94
+ children: /* @__PURE__ */ jsx("div", { children: introduction })
95
+ }),
96
+ /* @__PURE__ */ jsxs(StyledWrapper, { children: [competenceGoals, disclaimer] })
97
+ ] });
98
+ };
99
+ const Article = ({ article, contentType, licenseBox, children, competenceGoals, contentTypeLabel, id, heartButton, lang, disclaimer }) => {
100
+ const { title, introduction, published, content, footNotes, copyright } = article;
101
+ const authors = copyright?.creators.length || copyright?.rightsholders.length ? copyright.creators : copyright?.processors;
102
+ return /* @__PURE__ */ jsxs(ArticleWrapper, { children: [
103
+ /* @__PURE__ */ jsx(ArticleTitle, {
104
+ id,
105
+ contentType,
106
+ heartButton,
107
+ title,
108
+ introduction,
109
+ competenceGoals,
110
+ lang,
111
+ contentTypeLabel,
112
+ disclaimer
113
+ }),
114
+ /* @__PURE__ */ jsx(ArticleContent, { children: content }),
115
+ /* @__PURE__ */ jsxs(ArticleFooter, { children: [/* @__PURE__ */ jsx(ArticleByline, {
116
+ footnotes: footNotes,
117
+ authors,
118
+ suppliers: copyright?.rightsholders,
119
+ published,
120
+ licenseBox
121
+ }), children] })
122
+ ] });
123
+ };
124
+
125
+ //#endregion
126
+ export { Article, ArticleContent, ArticleFooter, ArticleHGroup, ArticleHeader, ArticleTitle, ArticleWrapper };
127
+ //# sourceMappingURL=Article.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Article.js","names":[],"sources":["../../src/Article/Article.tsx"],"sourcesContent":["/**\n * Copyright (c) 2016-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 ComponentPropsWithRef, type ReactNode, forwardRef } from \"react\";\nimport { ark, type HTMLArkProps } from \"@ark-ui/react\";\nimport { Heading, Text } from \"@ndla/primitives\";\nimport { cx } from \"@ndla/styled-system/css\";\nimport { Stack, styled } from \"@ndla/styled-system/jsx\";\nimport type { JsxStyleProps } from \"@ndla/styled-system/types\";\nimport { ArticleByline } from \"./ArticleByline\";\nimport { ContentTypeBadge, type ContentType } from \"../ContentTypeBadge/ContentTypeBadge\";\nimport type { Article as ArticleType } from \"../types\";\n\nconst StyledArticleContent = styled(ark.section, {}, { baseComponent: true });\n\nexport const ArticleContent = forwardRef<HTMLElement, HTMLArkProps<\"div\"> & JsxStyleProps>(\n ({ className, ...props }, ref) => (\n <StyledArticleContent className={cx(\"ndla-article\", className)} {...props} ref={ref} />\n ),\n);\n\nconst StyledArticleWrapper = styled(\n ark.article,\n {\n base: {\n background: \"background.default\",\n display: \"flex\",\n flexDirection: \"column\",\n color: \"text.default\",\n alignItems: \"center\",\n width: \"100%\",\n overflowWrap: \"break-word\",\n position: \"relative\",\n \"& mjx-stretchy-v > mjx-ext > mjx-c\": {\n transform: \"scaleY(100) translateY(0.075em)\",\n },\n _after: {\n content: \"\",\n display: \"table\",\n clear: \"both\",\n },\n },\n },\n { baseComponent: true },\n);\n\nexport const ArticleWrapper = forwardRef<HTMLElement, ComponentPropsWithRef<\"article\"> & JsxStyleProps>(\n (props, ref) => <StyledArticleWrapper data-ndla-article=\"\" ref={ref} {...props} />,\n);\n\nexport const ArticleHGroup = styled(\n ark.hgroup,\n {\n base: {\n display: \"flex\",\n width: \"100%\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n \"& h1\": {\n overflowWrap: \"anywhere\",\n },\n },\n },\n { baseComponent: true },\n);\n\nexport const ArticleHeader = styled(\n ark.header,\n {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"medium\",\n alignItems: \"flex-start\",\n width: \"100%\",\n paddingBlockStart: \"xxlarge\",\n overflowWrap: \"anywhere\",\n },\n },\n { baseComponent: true },\n);\n\nexport const ArticleFooter = styled(\n ark.footer,\n {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xxlarge\",\n width: \"100%\",\n \"& > :is(:last-child)\": {\n paddingBlockEnd: \"5xlarge\",\n },\n },\n },\n { baseComponent: true },\n);\n\nconst StyledStack = styled(Stack, {\n base: {\n width: \"100%\",\n minHeight: \"xxlarge\",\n },\n});\n\nconst StyledWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"small\",\n flexWrap: \"wrap\",\n alignItems: \"center\",\n },\n});\n\ninterface ArticleTitleProps {\n heartButton?: ReactNode;\n contentType?: ContentType;\n contentTypeLabel?: ReactNode;\n competenceGoals?: ReactNode;\n id: string;\n lang?: string;\n title?: ReactNode;\n introduction?: ReactNode;\n disclaimer?: ReactNode;\n}\n\nexport const ArticleTitle = ({\n contentType,\n heartButton,\n title,\n lang,\n id,\n introduction,\n contentTypeLabel,\n competenceGoals,\n disclaimer,\n}: ArticleTitleProps) => {\n return (\n <ArticleHeader>\n <ArticleHGroup>\n {(!!contentType || !!heartButton) && (\n <StyledStack justify=\"space-between\" align=\"center\" direction=\"row\" gap=\"small\">\n {!!contentType && <ContentTypeBadge contentType={contentType}>{contentTypeLabel}</ContentTypeBadge>}\n {heartButton}\n </StyledStack>\n )}\n <Heading textStyle=\"heading.medium\" id={id} lang={lang} property=\"dct:title\">\n {title}\n </Heading>\n </ArticleHGroup>\n {!!introduction && (\n <Text lang={lang} textStyle=\"body.xlarge\" asChild consumeCss>\n <div>{introduction}</div>\n </Text>\n )}\n <StyledWrapper>\n {competenceGoals}\n {disclaimer}\n </StyledWrapper>\n </ArticleHeader>\n );\n};\n\ninterface Props {\n heartButton?: ReactNode;\n article: ArticleType;\n licenseBox?: ReactNode;\n contentType?: ContentType;\n contentTypeLabel?: ReactNode;\n children?: ReactNode;\n competenceGoals?: ReactNode;\n id: string;\n lang?: string;\n disclaimer?: ReactNode;\n}\n\nexport const Article = ({\n article,\n contentType,\n licenseBox,\n children,\n competenceGoals,\n contentTypeLabel,\n id,\n heartButton,\n lang,\n disclaimer,\n}: Props) => {\n const { title, introduction, published, content, footNotes, copyright } = article;\n\n const authors =\n copyright?.creators.length || copyright?.rightsholders.length ? copyright.creators : copyright?.processors;\n\n return (\n <ArticleWrapper>\n <ArticleTitle\n id={id}\n contentType={contentType}\n heartButton={heartButton}\n title={title}\n introduction={introduction}\n competenceGoals={competenceGoals}\n lang={lang}\n contentTypeLabel={contentTypeLabel}\n disclaimer={disclaimer}\n />\n <ArticleContent>{content}</ArticleContent>\n <ArticleFooter>\n <ArticleByline\n footnotes={footNotes}\n authors={authors}\n suppliers={copyright?.rightsholders}\n published={published}\n licenseBox={licenseBox}\n />\n {children}\n </ArticleFooter>\n </ArticleWrapper>\n );\n};\n"],"mappings":";;;;;;;;;;AAkBA,MAAM,uBAAuB,OAAO,IAAI,SAAS,CAAE,GAAE,EAAE,eAAe,KAAM,EAAC;AAE7E,MAAa,iBAAiB,WAC5B,CAAC,EAAE,UAAW,GAAG,OAAO,EAAE,wBACxB,IAAC;CAAqB,WAAW,GAAG,gBAAgB,UAAU;CAAE,GAAI;CAAY;EAAO,CAE1F;AAED,MAAM,uBAAuB,OAC3B,IAAI,SACJ,EACE,MAAM;CACJ,YAAY;CACZ,SAAS;CACT,eAAe;CACf,OAAO;CACP,YAAY;CACZ,OAAO;CACP,cAAc;CACd,UAAU;CACV,sCAAsC,EACpC,WAAW,kCACZ;CACD,QAAQ;EACN,SAAS;EACT,SAAS;EACT,OAAO;CACR;AACF,EACF,GACD,EAAE,eAAe,KAAM,EACxB;AAED,MAAa,iBAAiB,WAC5B,CAAC,OAAO,wBAAQ,IAAC;CAAqB,qBAAkB;CAAQ;CAAK,GAAI;EAAS,CACnF;AAED,MAAa,gBAAgB,OAC3B,IAAI,QACJ,EACE,MAAM;CACJ,SAAS;CACT,OAAO;CACP,eAAe;CACf,YAAY;CACZ,QAAQ,EACN,cAAc,WACf;AACF,EACF,GACD,EAAE,eAAe,KAAM,EACxB;AAED,MAAa,gBAAgB,OAC3B,IAAI,QACJ,EACE,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,YAAY;CACZ,OAAO;CACP,mBAAmB;CACnB,cAAc;AACf,EACF,GACD,EAAE,eAAe,KAAM,EACxB;AAED,MAAa,gBAAgB,OAC3B,IAAI,QACJ,EACE,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,OAAO;CACP,wBAAwB,EACtB,iBAAiB,UAClB;AACF,EACF,GACD,EAAE,eAAe,KAAM,EACxB;AAED,MAAM,cAAc,OAAO,OAAO,EAChC,MAAM;CACJ,OAAO;CACP,WAAW;AACZ,EACF,EAAC;AAEF,MAAM,gBAAgB,OAAO,OAAO,EAClC,MAAM;CACJ,SAAS;CACT,KAAK;CACL,UAAU;CACV,YAAY;AACb,EACF,EAAC;AAcF,MAAa,eAAe,CAAC,EAC3B,aACA,aACA,OACA,MACA,IACA,cACA,kBACA,iBACA,YACkB,KAAK;AACvB,wBACE,KAAC;kBACC,KAAC,+BACK,iBAAiB,gCACnB,KAAC;GAAY,SAAQ;GAAgB,OAAM;GAAS,WAAU;GAAM,KAAI;gBACnE,+BAAe,IAAC;IAA8B;cAAc;KAAoC,EAClG;IACW,kBAEhB,IAAC;GAAQ,WAAU;GAAqB;GAAU;GAAM,UAAS;aAC9D;IACO,IACI;IACb,gCACD,IAAC;GAAW;GAAM,WAAU;GAAc;GAAQ;6BAChD,IAAC,mBAAK,eAAmB;IACpB;kBAET,KAAC,4BACE,iBACA,cACa;KACF;AAEnB;AAeD,MAAa,UAAU,CAAC,EACtB,SACA,aACA,YACA,UACA,iBACA,kBACA,IACA,aACA,MACA,YACM,KAAK;CACX,MAAM,EAAE,OAAO,cAAc,WAAW,SAAS,WAAW,WAAW,GAAG;CAE1E,MAAM,UACJ,WAAW,SAAS,UAAU,WAAW,cAAc,SAAS,UAAU,WAAW,WAAW;AAElG,wBACE,KAAC;kBACC,IAAC;GACK;GACS;GACA;GACN;GACO;GACG;GACX;GACY;GACN;IACZ;kBACF,IAAC,4BAAgB,UAAyB;kBAC1C,KAAC,4CACC,IAAC;GACC,WAAW;GACF;GACT,WAAW,WAAW;GACX;GACC;IACZ,EACD,YACa;KACD;AAEpB"}
@@ -0,0 +1,133 @@
1
+ import { ArticleFootNotes } from "./ArticleFootNotes.js";
2
+ import { forwardRef, useCallback, useEffect, useState } from "react";
3
+ import { AccordionItem, AccordionItemContent, AccordionItemIndicator, AccordionItemTrigger, AccordionRoot, Heading } from "@ndla/primitives";
4
+ import { styled } from "@ndla/styled-system/jsx";
5
+ import { useTranslation } from "react-i18next";
6
+ import { ArrowDownShortLine } from "@ndla/icons";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { useLocation } from "react-router-dom";
9
+
10
+ //#region src/Article/ArticleByline.tsx
11
+ const Wrapper = styled("div", { base: {
12
+ marginBlockStart: "medium",
13
+ paddingBlockStart: "xsmall",
14
+ borderTop: "1px solid",
15
+ borderColor: "stroke.subtle"
16
+ } });
17
+ const TextWrapper = styled("div", {
18
+ base: {
19
+ display: "flex",
20
+ flexDirection: "column",
21
+ gap: "3xsmall",
22
+ width: "100%",
23
+ justifyContent: "space-between",
24
+ paddingBlock: "xsmall",
25
+ textStyle: "body.medium",
26
+ "& [data-contributors=\"false\"]": { marginInlineStart: "auto" }
27
+ },
28
+ variants: { learningpath: {
29
+ true: {},
30
+ false: { tabletWide: { flexDirection: "row" } }
31
+ } }
32
+ });
33
+ const renderContributors = (contributors, t) => {
34
+ const contributorsArray = contributors.map((contributor, index) => {
35
+ if (index < 1) return contributor.name;
36
+ const sep = index === contributors.length - 1 ? ` ${t("article.conjunction")} ` : ", ";
37
+ return `${sep}${contributor.name}`;
38
+ });
39
+ return contributorsArray.join("");
40
+ };
41
+ const getSuppliersText = (suppliers, t) => {
42
+ if (suppliers.length === 0) return "";
43
+ return suppliers.length > 1 ? t("article.multipleSuppliersLabel", {
44
+ names: renderContributors(suppliers, t),
45
+ interpolation: { escapeValue: false }
46
+ }) : t("article.supplierLabel", {
47
+ name: renderContributors(suppliers, t),
48
+ interpolation: { escapeValue: false }
49
+ });
50
+ };
51
+ const StyledAccordionRoot = styled(AccordionRoot, { base: { paddingBlockStart: "xxlarge" } });
52
+ const refRegexp = /note\d/;
53
+ const footnotesAccordionId = "footnotes";
54
+ const ArticleByline = ({ authors = [], suppliers = [], footnotes, licenseBox, published, displayByline = true, bylineType = "article", bylineSuffix }) => {
55
+ const { t } = useTranslation();
56
+ const { pathname } = useLocation();
57
+ const [openAccordions, setOpenAccordions] = useState([]);
58
+ const accordionItemValue = "rulesForUse";
59
+ const onHashChange = useCallback((e) => {
60
+ const hash = e.newURL.split("#")[1];
61
+ if (hash?.match(refRegexp) && !openAccordions.includes(footnotesAccordionId)) {
62
+ setOpenAccordions([...openAccordions, footnotesAccordionId]);
63
+ const el = document.getElementById(`#${hash}`);
64
+ el?.click();
65
+ el?.focus();
66
+ }
67
+ }, [openAccordions]);
68
+ useEffect(() => {
69
+ setOpenAccordions((prev) => prev.filter((state) => state !== accordionItemValue));
70
+ }, [pathname]);
71
+ useEffect(() => {
72
+ window.addEventListener("hashchange", onHashChange);
73
+ return () => window.removeEventListener("hashchange", onHashChange);
74
+ }, [onHashChange]);
75
+ const showPrimaryContributors = suppliers.length > 0 || authors.length > 0;
76
+ const authorLabel = {
77
+ article: "article.authorsLabel",
78
+ learningPath: "article.authorsLabelLearningpath",
79
+ external: "article.authorsLabelExternal"
80
+ };
81
+ return /* @__PURE__ */ jsxs(Wrapper, { children: [!!displayByline && /* @__PURE__ */ jsxs(TextWrapper, {
82
+ learningpath: bylineType === "learningPath",
83
+ children: [
84
+ !!showPrimaryContributors && /* @__PURE__ */ jsxs("span", { children: [authors.length > 0 && `${t(authorLabel[bylineType], {
85
+ names: renderContributors(authors, t),
86
+ interpolation: { escapeValue: false }
87
+ })}. `, getSuppliersText(suppliers, t)] }),
88
+ published ? /* @__PURE__ */ jsxs("div", {
89
+ "data-contributors": showPrimaryContributors,
90
+ children: [
91
+ t(`${bylineType}.lastUpdated`),
92
+ " ",
93
+ published
94
+ ]
95
+ }) : null,
96
+ bylineSuffix
97
+ ]
98
+ }), (!!licenseBox || !!footnotes?.length) && /* @__PURE__ */ jsxs(StyledAccordionRoot, {
99
+ multiple: true,
100
+ value: openAccordions,
101
+ onValueChange: (details) => setOpenAccordions(details.value),
102
+ children: [!!licenseBox && /* @__PURE__ */ jsx(ArticleBylineAccordionItem, {
103
+ value: accordionItemValue,
104
+ accordionTitle: t("article.useContent"),
105
+ children: licenseBox
106
+ }), !!footnotes?.length && /* @__PURE__ */ jsx(ArticleBylineAccordionItem, {
107
+ value: footnotesAccordionId,
108
+ accordionTitle: t("article.footnotes"),
109
+ children: /* @__PURE__ */ jsx(ArticleFootNotes, { footNotes: footnotes })
110
+ })]
111
+ })] });
112
+ };
113
+ const ArticleBylineAccordionItem = forwardRef(({ value, accordionTitle, children,...props }, ref) => {
114
+ return /* @__PURE__ */ jsxs(AccordionItem, {
115
+ value,
116
+ ref,
117
+ ...props,
118
+ children: [/* @__PURE__ */ jsx(Heading, {
119
+ asChild: true,
120
+ consumeCss: true,
121
+ textStyle: "label.medium",
122
+ fontWeight: "bold",
123
+ children: /* @__PURE__ */ jsx("h2", { children: /* @__PURE__ */ jsxs(AccordionItemTrigger, { children: [accordionTitle, /* @__PURE__ */ jsx(AccordionItemIndicator, {
124
+ asChild: true,
125
+ children: /* @__PURE__ */ jsx(ArrowDownShortLine, {})
126
+ })] }) })
127
+ }), /* @__PURE__ */ jsx(AccordionItemContent, { children })]
128
+ });
129
+ });
130
+
131
+ //#endregion
132
+ export { ArticleByline, ArticleBylineAccordionItem };
133
+ //# sourceMappingURL=ArticleByline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArticleByline.js","names":["contributors: SupplierProps[] | AuthorProps[]","t: TFunction","suppliers: SupplierProps[]","e: HashChangeEvent","authorLabel: Record<string, string>"],"sources":["../../src/Article/ArticleByline.tsx"],"sourcesContent":["/**\n * Copyright (c) 2020-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 { TFunction } from \"i18next\";\nimport { type ReactNode, forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useLocation } from \"react-router-dom\";\nimport { ArrowDownShortLine } from \"@ndla/icons\";\nimport {\n AccordionItem,\n AccordionItemContent,\n AccordionItemIndicator,\n type AccordionItemProps,\n AccordionItemTrigger,\n AccordionRoot,\n Heading,\n} from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport { ArticleFootNotes } from \"./ArticleFootNotes\";\nimport type { FootNote } from \"../types\";\n\nconst Wrapper = styled(\"div\", {\n base: {\n // TODO: Figure out if we want to remove this margin. It's only here to add some gap between the article content and the byline.\n marginBlockStart: \"medium\",\n paddingBlockStart: \"xsmall\",\n borderTop: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n});\n\nconst TextWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"3xsmall\",\n width: \"100%\",\n justifyContent: \"space-between\",\n paddingBlock: \"xsmall\",\n textStyle: \"body.medium\",\n '& [data-contributors=\"false\"]': {\n marginInlineStart: \"auto\",\n },\n },\n variants: {\n learningpath: {\n true: {},\n false: {\n tabletWide: {\n flexDirection: \"row\",\n },\n },\n },\n },\n});\n\ntype AuthorProps = {\n name: string;\n};\n\ntype SupplierProps = {\n name: string;\n};\n\ntype Props = {\n authors?: AuthorProps[];\n suppliers?: SupplierProps[];\n published?: string;\n licenseBox?: ReactNode;\n footnotes?: FootNote[];\n displayByline?: boolean;\n bylineType?: \"article\" | \"learningPath\" | \"external\";\n bylineSuffix?: ReactNode;\n};\n\nconst renderContributors = (contributors: SupplierProps[] | AuthorProps[], t: TFunction) => {\n const contributorsArray = contributors.map((contributor, index) => {\n if (index < 1) return contributor.name;\n const sep = index === contributors.length - 1 ? ` ${t(\"article.conjunction\")} ` : \", \";\n return `${sep}${contributor.name}`;\n });\n return contributorsArray.join(\"\");\n};\n\nconst getSuppliersText = (suppliers: SupplierProps[], t: TFunction) => {\n if (suppliers.length === 0) {\n return \"\";\n }\n return suppliers.length > 1\n ? t(\"article.multipleSuppliersLabel\", {\n names: renderContributors(suppliers, t),\n interpolation: { escapeValue: false },\n })\n : t(\"article.supplierLabel\", {\n name: renderContributors(suppliers, t),\n interpolation: { escapeValue: false },\n });\n};\n\nconst StyledAccordionRoot = styled(AccordionRoot, {\n base: {\n paddingBlockStart: \"xxlarge\",\n },\n});\n\nconst refRegexp = /note\\d/;\nconst footnotesAccordionId = \"footnotes\";\n\nexport const ArticleByline = ({\n authors = [],\n suppliers = [],\n footnotes,\n licenseBox,\n published,\n displayByline = true,\n bylineType = \"article\",\n bylineSuffix,\n}: Props) => {\n const { t } = useTranslation();\n const { pathname } = useLocation();\n const [openAccordions, setOpenAccordions] = useState<string[]>([]);\n const accordionItemValue = \"rulesForUse\";\n\n const onHashChange = useCallback(\n (e: HashChangeEvent) => {\n const hash = e.newURL.split(\"#\")[1];\n if (hash?.match(refRegexp) && !openAccordions.includes(footnotesAccordionId)) {\n setOpenAccordions([...openAccordions, footnotesAccordionId]);\n const el = document.getElementById(`#${hash}`);\n el?.click();\n el?.focus();\n }\n },\n [openAccordions],\n );\n\n useEffect(() => {\n setOpenAccordions((prev) => prev.filter((state) => state !== accordionItemValue));\n }, [pathname]);\n\n useEffect(() => {\n window.addEventListener(\"hashchange\", onHashChange);\n return () => window.removeEventListener(\"hashchange\", onHashChange);\n }, [onHashChange]);\n\n const showPrimaryContributors = suppliers.length > 0 || authors.length > 0;\n\n const authorLabel: Record<string, string> = {\n article: \"article.authorsLabel\",\n learningPath: \"article.authorsLabelLearningpath\",\n external: \"article.authorsLabelExternal\",\n };\n\n return (\n <Wrapper>\n {!!displayByline && (\n <TextWrapper learningpath={bylineType === \"learningPath\"}>\n {!!showPrimaryContributors && (\n <span>\n {authors.length > 0 &&\n `${t(authorLabel[bylineType], {\n names: renderContributors(authors, t),\n interpolation: { escapeValue: false },\n })}. `}\n {getSuppliersText(suppliers, t)}\n </span>\n )}\n {published ? (\n <div data-contributors={showPrimaryContributors}>\n {t(`${bylineType}.lastUpdated`)} {published}\n </div>\n ) : null}\n {bylineSuffix}\n </TextWrapper>\n )}\n {(!!licenseBox || !!footnotes?.length) && (\n <StyledAccordionRoot\n multiple\n value={openAccordions}\n onValueChange={(details) => setOpenAccordions(details.value)}\n >\n {!!licenseBox && (\n <ArticleBylineAccordionItem value={accordionItemValue} accordionTitle={t(\"article.useContent\")}>\n {licenseBox}\n </ArticleBylineAccordionItem>\n )}\n {!!footnotes?.length && (\n <ArticleBylineAccordionItem value={footnotesAccordionId} accordionTitle={t(\"article.footnotes\")}>\n <ArticleFootNotes footNotes={footnotes} />\n </ArticleBylineAccordionItem>\n )}\n </StyledAccordionRoot>\n )}\n </Wrapper>\n );\n};\n\ninterface ArticleBylineAccordionprops extends AccordionItemProps {\n accordionTitle: ReactNode;\n}\n\nexport const ArticleBylineAccordionItem = forwardRef<HTMLDivElement, ArticleBylineAccordionprops>(\n ({ value, accordionTitle, children, ...props }, ref) => {\n return (\n <AccordionItem value={value} ref={ref} {...props}>\n <Heading asChild consumeCss textStyle=\"label.medium\" fontWeight=\"bold\">\n <h2>\n <AccordionItemTrigger>\n {accordionTitle}\n <AccordionItemIndicator asChild>\n <ArrowDownShortLine />\n </AccordionItemIndicator>\n </AccordionItemTrigger>\n </h2>\n </Heading>\n <AccordionItemContent>{children}</AccordionItemContent>\n </AccordionItem>\n );\n },\n);\n"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { Text } from "@ndla/primitives";
2
+ import { styled } from "@ndla/styled-system/jsx";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+
5
+ //#region src/Article/ArticleFootNotes.tsx
6
+ const citeDetailString = (description) => description ? `${description}. ` : "";
7
+ const StyledCite = styled("cite", { base: {
8
+ display: "flex",
9
+ alignItems: "center",
10
+ gap: "xsmall"
11
+ } });
12
+ const FootNote = ({ footNote }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Text, {
13
+ id: `note${footNote.ref}`,
14
+ asChild: true,
15
+ consumeCss: true,
16
+ textStyle: "body.medium",
17
+ children: /* @__PURE__ */ jsxs(StyledCite, { children: [
18
+ /* @__PURE__ */ jsx("a", {
19
+ href: `#ref${footNote.ref}`,
20
+ target: "_self",
21
+ children: footNote.ref
22
+ }),
23
+ `«${footNote.title}». ${footNote.authors.join(" ")}. ${citeDetailString(footNote.edition)}${citeDetailString(footNote.publisher)}${footNote.year}. `,
24
+ footNote.url ? /* @__PURE__ */ jsxs("a", {
25
+ href: footNote.url,
26
+ children: [footNote.url, "."]
27
+ }) : null
28
+ ] })
29
+ }) });
30
+ const FootnoteList = styled("ol", { base: {
31
+ display: "flex",
32
+ flexDirection: "column",
33
+ gap: "medium",
34
+ listStyle: "none"
35
+ } });
36
+ const ArticleFootNotes = ({ footNotes }) => /* @__PURE__ */ jsx(FootnoteList, { children: footNotes.map((footNote) => /* @__PURE__ */ jsx(FootNote, { footNote }, footNote.ref)) });
37
+
38
+ //#endregion
39
+ export { ArticleFootNotes };
40
+ //# sourceMappingURL=ArticleFootNotes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArticleFootNotes.js","names":["description: string | undefined"],"sources":["../../src/Article/ArticleFootNotes.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-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 { Text } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { FootNote as FootNoteType } from \"../types\";\n\nconst citeDetailString = (description: string | undefined) => (description ? `${description}. ` : \"\");\n\ntype FootNoteProps = {\n footNote: FootNoteType;\n};\n\nconst StyledCite = styled(\"cite\", {\n base: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"xsmall\",\n },\n});\n\nconst FootNote = ({ footNote }: FootNoteProps) => (\n <li>\n <Text id={`note${footNote.ref}`} asChild consumeCss textStyle=\"body.medium\">\n <StyledCite>\n <a href={`#ref${footNote.ref}`} target=\"_self\">\n {footNote.ref}\n </a>\n {`«${footNote.title}». ${footNote.authors.join(\" \")}. ${citeDetailString(footNote.edition)}${citeDetailString(\n footNote.publisher,\n )}${footNote.year}. `}\n {footNote.url ? (\n <a href={footNote.url}>\n {footNote.url}\n {\".\"}\n </a>\n ) : null}\n </StyledCite>\n </Text>\n </li>\n);\n\ntype ArticleFootNotesProps = {\n footNotes: Array<FootNoteType>;\n};\n\nconst FootnoteList = styled(\"ol\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"medium\",\n listStyle: \"none\",\n },\n});\n\nexport const ArticleFootNotes = ({ footNotes }: ArticleFootNotesProps) => (\n <FootnoteList>\n {footNotes.map((footNote) => (\n <FootNote key={footNote.ref} footNote={footNote} />\n ))}\n </FootnoteList>\n);\n"],"mappings":";;;;;AAYA,MAAM,mBAAmB,CAACA,gBAAqC,eAAe,EAAE,YAAY,MAAM;AAMlG,MAAM,aAAa,OAAO,QAAQ,EAChC,MAAM;CACJ,SAAS;CACT,YAAY;CACZ,KAAK;AACN,EACF,EAAC;AAEF,MAAM,WAAW,CAAC,EAAE,UAAyB,qBAC3C,IAAC,kCACC,IAAC;CAAK,KAAK,MAAM,SAAS,IAAI;CAAG;CAAQ;CAAW,WAAU;2BAC5D,KAAC;kBACC,IAAC;GAAE,OAAO,MAAM,SAAS,IAAI;GAAG,QAAO;aACpC,SAAS;IACR;GACF,GAAG,SAAS,MAAM,KAAK,SAAS,QAAQ,KAAK,IAAI,CAAC,IAAI,iBAAiB,SAAS,QAAQ,CAAC,EAAE,iBAC3F,SAAS,UACV,CAAC,EAAE,SAAS,KAAK;EACjB,SAAS,sBACR,KAAC;GAAE,MAAM,SAAS;cACf,SAAS,KACT;IACC,GACF;KACO;EACR,GACJ;AAOP,MAAM,eAAe,OAAO,MAAM,EAChC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,WAAW;AACZ,EACF,EAAC;AAEF,MAAa,mBAAmB,CAAC,EAAE,WAAkC,qBACnE,IAAC,0BACE,UAAU,IAAI,CAAC,6BACd,IAAC,YAAsC,YAAxB,SAAS,IAA2B,CACnD,GACW"}
@@ -0,0 +1,157 @@
1
+ import { Controls_default } from "./Controls.js";
2
+ import { SpeechControl_default } from "./SpeechControl.js";
3
+ import { useId, useMemo, useState } from "react";
4
+ import { Button, Heading, Text } from "@ndla/primitives";
5
+ import { styled } from "@ndla/styled-system/jsx";
6
+ import { useTranslation } from "react-i18next";
7
+ import { SafeLink } from "@ndla/safelink";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+
10
+ //#region src/AudioPlayer/AudioPlayer.tsx
11
+ const AudioPlayerWrapper = styled("div", { base: {
12
+ border: "1px solid",
13
+ borderColor: "stroke.default",
14
+ borderRadius: "xsmall",
15
+ boxShadow: "full",
16
+ marginBlockEnd: "4xsmall",
17
+ overflow: "hidden"
18
+ } });
19
+ const InfoWrapper = styled("div", { base: {
20
+ display: "flex",
21
+ tabletWideDown: { display: "block" }
22
+ } });
23
+ const ImageWrapper = styled("div", { base: {
24
+ display: "flex",
25
+ alignItems: "center",
26
+ flex: "1 0 auto",
27
+ width: "surface.4xsmall",
28
+ height: "surface.4xsmall",
29
+ overflow: "hidden",
30
+ "& img": {
31
+ width: "100%",
32
+ height: "100%",
33
+ objectFit: "cover"
34
+ },
35
+ desktop: {
36
+ width: "260px",
37
+ height: "260px"
38
+ },
39
+ tabletWideDown: {
40
+ maxHeight: "surface.small",
41
+ maxWidth: "100%",
42
+ width: "100%",
43
+ height: "auto"
44
+ }
45
+ } });
46
+ const TextWrapper = styled("div", { base: {
47
+ display: "flex",
48
+ alignItems: "flex-start",
49
+ flexDirection: "column",
50
+ gap: "xsmall",
51
+ padding: "xsmall",
52
+ width: "100%",
53
+ "&[data-has-image='true']": { tablet: {
54
+ paddingBlock: "xsmall",
55
+ paddingInline: "medium"
56
+ } }
57
+ } });
58
+ const TitleWrapper = styled("div", { base: {
59
+ display: "flex",
60
+ flexDirection: "column",
61
+ gap: "xsmall",
62
+ fontFamily: "sans",
63
+ tabletWide: {
64
+ width: "100%",
65
+ flexDirection: "row",
66
+ justifyContent: "space-between"
67
+ }
68
+ } });
69
+ const TextVersionWrapper = styled("div", { base: {
70
+ display: "flex",
71
+ flexDirection: "column",
72
+ gap: "xsmall",
73
+ borderBlockStart: "1px solid",
74
+ borderColor: "stroke.default",
75
+ paddingBlock: "medium",
76
+ paddingInline: "xsmall",
77
+ tablet: { paddingInline: "medium" }
78
+ } });
79
+ const TextVersionText = styled("div", { base: {
80
+ maxWidth: "surface.xlarge",
81
+ "& span > *": { whiteSpace: "pre-wrap" },
82
+ "& p:not(:first-child):not(:last-child)": { marginBlock: "small" },
83
+ "& p[data-align=\"center\"]": { textAlign: "center" },
84
+ "& p:has(span[dir=\"rtl\"])": { direction: "rtl" }
85
+ } });
86
+ const TextVersionButton = styled(Button, { base: { alignSelf: "flex-start" } });
87
+ const ShowMoreButton = styled(Button, { base: { marginInlineStart: "3xsmall" } });
88
+ const DESCRIPTION_MAX_LENGTH = 200;
89
+ const AudioPlayer = ({ src, title, subtitle, speech, description, img, textVersion }) => {
90
+ const { t } = useTranslation();
91
+ const [showTextVersion, setShowTextVersion] = useState(false);
92
+ const [showFullDescription, setShowFullDescription] = useState(false);
93
+ const truncatedDescription = useMemo(() => description?.slice(0, DESCRIPTION_MAX_LENGTH), [description]);
94
+ const textDescriptionId = useId();
95
+ if (speech) return /* @__PURE__ */ jsx(SpeechControl_default, {
96
+ src,
97
+ title
98
+ });
99
+ const toggleTextVersion = () => {
100
+ setShowTextVersion((curr) => !curr);
101
+ };
102
+ const textVersionButton = /* @__PURE__ */ jsx(TextVersionButton, {
103
+ variant: "secondary",
104
+ "aria-expanded": showTextVersion,
105
+ "aria-controls": textDescriptionId,
106
+ size: "small",
107
+ onClick: toggleTextVersion,
108
+ children: t(showTextVersion ? "audio.textVersion.close" : "audio.textVersion.heading")
109
+ });
110
+ return /* @__PURE__ */ jsxs(AudioPlayerWrapper, { children: [
111
+ /* @__PURE__ */ jsxs(InfoWrapper, { children: [!!img && /* @__PURE__ */ jsx(ImageWrapper, { children: /* @__PURE__ */ jsx("img", {
112
+ src: img.url,
113
+ alt: img.alt
114
+ }) }), /* @__PURE__ */ jsxs(TextWrapper, {
115
+ "data-has-image": !!img,
116
+ children: [
117
+ /* @__PURE__ */ jsxs(TitleWrapper, { children: [/* @__PURE__ */ jsxs("div", { children: [subtitle?.url ? /* @__PURE__ */ jsx(SafeLink, {
118
+ to: subtitle.url,
119
+ children: subtitle.title
120
+ }) : subtitle?.title, /* @__PURE__ */ jsx(Heading, {
121
+ asChild: true,
122
+ consumeCss: true,
123
+ textStyle: "title.large",
124
+ children: /* @__PURE__ */ jsx("h3", { children: title })
125
+ })] }), !!textVersion && !img && textVersionButton] }),
126
+ !!description && /* @__PURE__ */ jsxs(Text, {
127
+ textStyle: "body.medium",
128
+ children: [showFullDescription || description.length < DESCRIPTION_MAX_LENGTH ? description : `${truncatedDescription}...`, description.length > DESCRIPTION_MAX_LENGTH && /* @__PURE__ */ jsx(ShowMoreButton, {
129
+ variant: "link",
130
+ onClick: () => setShowFullDescription((p) => !p),
131
+ children: t(`audio.${showFullDescription ? "readLessDescriptionLabel" : "readMoreDescriptionLabel"}`)
132
+ })]
133
+ }),
134
+ !!textVersion && !!img && textVersionButton
135
+ ]
136
+ })] }),
137
+ /* @__PURE__ */ jsx(Controls_default, {
138
+ src,
139
+ title
140
+ }),
141
+ !!textVersion && /* @__PURE__ */ jsxs(TextVersionWrapper, {
142
+ id: textDescriptionId,
143
+ hidden: !showTextVersion,
144
+ children: [/* @__PURE__ */ jsx(Heading, {
145
+ asChild: true,
146
+ textStyle: "title.medium",
147
+ consumeCss: true,
148
+ children: /* @__PURE__ */ jsx("h4", { children: t("audio.textVersion.heading") })
149
+ }), /* @__PURE__ */ jsx(TextVersionText, { children: textVersion })]
150
+ })
151
+ ] });
152
+ };
153
+ var AudioPlayer_default = AudioPlayer;
154
+
155
+ //#endregion
156
+ export { AudioPlayer_default };
157
+ //# sourceMappingURL=AudioPlayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioPlayer.js","names":["SpeechControl","Controls"],"sources":["../../src/AudioPlayer/AudioPlayer.tsx"],"sourcesContent":["/**\n * Copyright (c) 2017-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, useId, useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Heading, Text, Button } from \"@ndla/primitives\";\nimport { SafeLink } from \"@ndla/safelink\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport Controls from \"./Controls\";\nimport SpeechControl from \"./SpeechControl\";\n\n// TODO: Could the audio metadata be more tightly coupled to the audio player?\n\nconst AudioPlayerWrapper = styled(\"div\", {\n base: {\n border: \"1px solid\",\n borderColor: \"stroke.default\",\n borderRadius: \"xsmall\",\n boxShadow: \"full\",\n marginBlockEnd: \"4xsmall\",\n overflow: \"hidden\",\n },\n});\n\nconst InfoWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n tabletWideDown: {\n display: \"block\",\n },\n },\n});\n\nconst ImageWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n alignItems: \"center\",\n flex: \"1 0 auto\",\n width: \"surface.4xsmall\",\n height: \"surface.4xsmall\",\n overflow: \"hidden\",\n \"& img\": {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n },\n desktop: {\n width: \"260px\",\n height: \"260px\",\n },\n tabletWideDown: {\n maxHeight: \"surface.small\",\n maxWidth: \"100%\",\n width: \"100%\",\n height: \"auto\",\n },\n },\n});\n\nconst TextWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n alignItems: \"flex-start\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n padding: \"xsmall\",\n width: \"100%\",\n \"&[data-has-image='true']\": {\n tablet: {\n paddingBlock: \"xsmall\",\n paddingInline: \"medium\",\n },\n },\n },\n});\n\nconst TitleWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n fontFamily: \"sans\",\n tabletWide: {\n width: \"100%\",\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n },\n },\n});\n\nconst TextVersionWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n borderBlockStart: \"1px solid\",\n borderColor: \"stroke.default\",\n paddingBlock: \"medium\",\n paddingInline: \"xsmall\",\n tablet: {\n paddingInline: \"medium\",\n },\n },\n});\n\nconst TextVersionText = styled(\"div\", {\n base: {\n maxWidth: \"surface.xlarge\",\n \"& span > *\": {\n whiteSpace: \"pre-wrap\",\n },\n \"& p:not(:first-child):not(:last-child)\": {\n marginBlock: \"small\",\n },\n '& p[data-align=\"center\"]': {\n textAlign: \"center\",\n },\n '& p:has(span[dir=\"rtl\"])': {\n direction: \"rtl\",\n },\n },\n});\n\nconst TextVersionButton = styled(Button, {\n base: {\n alignSelf: \"flex-start\",\n },\n});\n\nconst ShowMoreButton = styled(Button, {\n base: {\n marginInlineStart: \"3xsmall\",\n },\n});\n\nconst DESCRIPTION_MAX_LENGTH = 200;\n\ntype Props = {\n src: string;\n title: string;\n subtitle?: {\n title: string;\n url?: string;\n };\n speech?: boolean;\n description?: string;\n textVersion?: ReactNode;\n img?: {\n url: string;\n alt: string;\n };\n};\n\nconst AudioPlayer = ({ src, title, subtitle, speech, description, img, textVersion }: Props) => {\n const { t } = useTranslation();\n const [showTextVersion, setShowTextVersion] = useState(false);\n const [showFullDescription, setShowFullDescription] = useState(false);\n const truncatedDescription = useMemo(() => description?.slice(0, DESCRIPTION_MAX_LENGTH), [description]);\n const textDescriptionId = useId();\n\n if (speech) {\n return <SpeechControl src={src} title={title} />;\n }\n\n const toggleTextVersion = () => {\n setShowTextVersion((curr) => !curr);\n };\n\n const textVersionButton = (\n <TextVersionButton\n variant=\"secondary\"\n aria-expanded={showTextVersion}\n aria-controls={textDescriptionId}\n size=\"small\"\n onClick={toggleTextVersion}\n >\n {t(showTextVersion ? \"audio.textVersion.close\" : \"audio.textVersion.heading\")}\n </TextVersionButton>\n );\n\n return (\n <AudioPlayerWrapper>\n <InfoWrapper>\n {!!img && (\n <ImageWrapper>\n <img src={img.url} alt={img.alt} />\n </ImageWrapper>\n )}\n <TextWrapper data-has-image={!!img}>\n <TitleWrapper>\n <div>\n {subtitle?.url ? <SafeLink to={subtitle.url}>{subtitle.title}</SafeLink> : subtitle?.title}\n <Heading asChild consumeCss textStyle=\"title.large\">\n <h3>{title}</h3>\n </Heading>\n </div>\n {!!textVersion && !img && textVersionButton}\n </TitleWrapper>\n {!!description && (\n <Text textStyle=\"body.medium\">\n {showFullDescription || description.length < DESCRIPTION_MAX_LENGTH\n ? description\n : `${truncatedDescription}...`}\n {description.length > DESCRIPTION_MAX_LENGTH && (\n <ShowMoreButton variant=\"link\" onClick={() => setShowFullDescription((p) => !p)}>\n {t(`audio.${showFullDescription ? \"readLessDescriptionLabel\" : \"readMoreDescriptionLabel\"}`)}\n </ShowMoreButton>\n )}\n </Text>\n )}\n {!!textVersion && !!img && textVersionButton}\n </TextWrapper>\n </InfoWrapper>\n <Controls src={src} title={title} />\n {!!textVersion && (\n <TextVersionWrapper id={textDescriptionId} hidden={!showTextVersion}>\n <Heading asChild textStyle=\"title.medium\" consumeCss>\n <h4>{t(\"audio.textVersion.heading\")}</h4>\n </Heading>\n <TextVersionText>{textVersion}</TextVersionText>\n </TextVersionWrapper>\n )}\n </AudioPlayerWrapper>\n );\n};\n\nexport default AudioPlayer;\n"],"mappings":"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"}