@ndla/ui 56.0.123-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 (347) hide show
  1. package/es/Article/Article.js +122 -194
  2. package/es/Article/Article.js.map +1 -0
  3. package/es/Article/ArticleByline.js +121 -170
  4. package/es/Article/ArticleByline.js.map +1 -0
  5. package/es/Article/ArticleFootNotes.js +38 -58
  6. package/es/Article/ArticleFootNotes.js.map +1 -0
  7. package/es/AudioPlayer/AudioPlayer.js +151 -212
  8. package/es/AudioPlayer/AudioPlayer.js.map +1 -0
  9. package/es/AudioPlayer/Controls.js +246 -324
  10. package/es/AudioPlayer/Controls.js.map +1 -0
  11. package/es/AudioPlayer/SpeechControl.js +36 -52
  12. package/es/AudioPlayer/SpeechControl.js.map +1 -0
  13. package/es/AudioPlayer/index.js +7 -9
  14. package/es/AudioPlayer/index.js.map +1 -0
  15. package/es/Breadcrumb/Breadcrumb.js +42 -58
  16. package/es/Breadcrumb/Breadcrumb.js.map +1 -0
  17. package/es/Breadcrumb/BreadcrumbItem.js +33 -59
  18. package/es/Breadcrumb/BreadcrumbItem.js.map +1 -0
  19. package/es/Breadcrumb/HomeBreadcrumb.js +41 -74
  20. package/es/Breadcrumb/HomeBreadcrumb.js.map +1 -0
  21. package/es/Breadcrumb/index.js +8 -10
  22. package/es/Breadcrumb/index.js.map +1 -0
  23. package/es/CampaignBlock/CampaignBlock.js +124 -173
  24. package/es/CampaignBlock/CampaignBlock.js.map +1 -0
  25. package/es/CodeBlock/CodeBlock.js +21 -31
  26. package/es/CodeBlock/CodeBlock.js.map +1 -0
  27. package/es/CodeBlock/codeLanguageOptions.js +112 -82
  28. package/es/CodeBlock/codeLanguageOptions.js.map +1 -0
  29. package/es/Concept/Concept.js +46 -68
  30. package/es/Concept/Concept.js.map +1 -0
  31. package/es/ContactBlock/ContactBlock.js +137 -191
  32. package/es/ContactBlock/ContactBlock.js.map +1 -0
  33. package/es/ContentTypeBadge/ContentTypeBadge.js +38 -47
  34. package/es/ContentTypeBadge/ContentTypeBadge.js.map +1 -0
  35. package/es/ContentTypeBlockQuote/ContentTypeBlockQuote.js +21 -28
  36. package/es/ContentTypeBlockQuote/ContentTypeBlockQuote.js.map +1 -0
  37. package/es/ContentTypeFramedContent/ContentTypeFramedContent.js +21 -28
  38. package/es/ContentTypeFramedContent/ContentTypeFramedContent.js.map +1 -0
  39. package/es/ContentTypeHero/ContentTypeHero.js +36 -47
  40. package/es/ContentTypeHero/ContentTypeHero.js.map +1 -0
  41. package/es/CopyParagraphButton/CopyParagraphButton.js +57 -78
  42. package/es/CopyParagraphButton/CopyParagraphButton.js.map +1 -0
  43. package/es/CopyParagraphButton/index.js +7 -10
  44. package/es/CopyParagraphButton/index.js.map +1 -0
  45. package/es/Embed/AudioEmbed.js +49 -73
  46. package/es/Embed/AudioEmbed.js.map +1 -0
  47. package/es/Embed/BrightcoveEmbed.js +90 -127
  48. package/es/Embed/BrightcoveEmbed.js.map +1 -0
  49. package/es/Embed/CodeEmbed.js +55 -73
  50. package/es/Embed/CodeEmbed.js.map +1 -0
  51. package/es/Embed/ConceptEmbed.js +72 -117
  52. package/es/Embed/ConceptEmbed.js.map +1 -0
  53. package/es/Embed/ConceptInlineTriggerButton.js +39 -44
  54. package/es/Embed/ConceptInlineTriggerButton.js.map +1 -0
  55. package/es/Embed/ContentLinkEmbed.js +29 -49
  56. package/es/Embed/ContentLinkEmbed.js.map +1 -0
  57. package/es/Embed/CopyrightEmbed.js +21 -31
  58. package/es/Embed/CopyrightEmbed.js.map +1 -0
  59. package/es/Embed/EmbedErrorPlaceholder.js +40 -55
  60. package/es/Embed/EmbedErrorPlaceholder.js.map +1 -0
  61. package/es/Embed/EmbedWrapper.js +21 -46
  62. package/es/Embed/EmbedWrapper.js.map +1 -0
  63. package/es/Embed/ExternalEmbed.js +50 -70
  64. package/es/Embed/ExternalEmbed.js.map +1 -0
  65. package/es/Embed/FootnoteEmbed.js +25 -42
  66. package/es/Embed/FootnoteEmbed.js.map +1 -0
  67. package/es/Embed/GlossEmbed.js +49 -77
  68. package/es/Embed/GlossEmbed.js.map +1 -0
  69. package/es/Embed/H5pEmbed.js +35 -58
  70. package/es/Embed/H5pEmbed.js.map +1 -0
  71. package/es/Embed/IframeEmbed.js +65 -89
  72. package/es/Embed/IframeEmbed.js.map +1 -0
  73. package/es/Embed/ImageEmbed.js +167 -225
  74. package/es/Embed/ImageEmbed.js.map +1 -0
  75. package/es/Embed/InlineTriggerButton.js +20 -32
  76. package/es/Embed/InlineTriggerButton.js.map +1 -0
  77. package/es/Embed/RelatedContentEmbed.js +36 -53
  78. package/es/Embed/RelatedContentEmbed.js.map +1 -0
  79. package/es/Embed/UnknownEmbed.js +18 -29
  80. package/es/Embed/UnknownEmbed.js.map +1 -0
  81. package/es/Embed/UuDisclaimerEmbed.js +51 -85
  82. package/es/Embed/UuDisclaimerEmbed.js.map +1 -0
  83. package/es/ErrorMessage/ErrorMessage.js +51 -92
  84. package/es/ErrorMessage/ErrorMessage.js.map +1 -0
  85. package/es/ErrorMessage/index.js +7 -9
  86. package/es/ErrorMessage/index.js.map +1 -0
  87. package/es/FactBox/FactBox.js +114 -170
  88. package/es/FactBox/FactBox.js.map +1 -0
  89. package/es/FactBox/index.js +7 -9
  90. package/es/FactBox/index.js.map +1 -0
  91. package/es/FileList/File.js +70 -95
  92. package/es/FileList/File.js.map +1 -0
  93. package/es/FileList/FileList.js +31 -46
  94. package/es/FileList/FileList.js.map +1 -0
  95. package/es/FileList/PdfFile.js +27 -49
  96. package/es/FileList/PdfFile.js.map +1 -0
  97. package/es/Gloss/Gloss.js +133 -166
  98. package/es/Gloss/Gloss.js.map +1 -0
  99. package/es/Gloss/GlossExample.js +42 -60
  100. package/es/Gloss/GlossExample.js.map +1 -0
  101. package/es/Grid/Grid.js +63 -91
  102. package/es/Grid/Grid.js.map +1 -0
  103. package/es/Grid/GridParallaxItem.js +19 -30
  104. package/es/Grid/GridParallaxItem.js.map +1 -0
  105. package/es/KeyFigure/KeyFigure.js +44 -61
  106. package/es/KeyFigure/KeyFigure.js.map +1 -0
  107. package/es/LicenseByline/EmbedByline.js +126 -206
  108. package/es/LicenseByline/EmbedByline.js.map +1 -0
  109. package/es/LicenseByline/LicenseLink.js +28 -53
  110. package/es/LicenseByline/LicenseLink.js.map +1 -0
  111. package/es/LinkBlock/LinkBlock.js +70 -99
  112. package/es/LinkBlock/LinkBlock.js.map +1 -0
  113. package/es/LinkBlock/LinkBlockSection.js +20 -32
  114. package/es/LinkBlock/LinkBlockSection.js.map +1 -0
  115. package/es/Pitch/Pitch.js +59 -80
  116. package/es/Pitch/Pitch.js.map +1 -0
  117. package/es/RelatedArticleList/RelatedArticleList.js +91 -129
  118. package/es/RelatedArticleList/RelatedArticleList.js.map +1 -0
  119. package/es/RelatedArticleList/index.js +7 -10
  120. package/es/RelatedArticleList/index.js.map +1 -0
  121. package/es/ResourceBox/ResourceBox.js +71 -96
  122. package/es/ResourceBox/ResourceBox.js.map +1 -0
  123. package/es/TagSelector/TagSelector.js +93 -136
  124. package/es/TagSelector/TagSelector.js.map +1 -0
  125. package/es/ZendeskButton/ZendeskButton.js +38 -52
  126. package/es/ZendeskButton/ZendeskButton.js.map +1 -0
  127. package/es/_virtual/rolldown_runtime.js +11 -0
  128. package/es/i18n/formatNestedMessages.js +16 -24
  129. package/es/i18n/formatNestedMessages.js.map +1 -0
  130. package/es/i18n/i18n.js +25 -31
  131. package/es/i18n/i18n.js.map +1 -0
  132. package/es/i18n/useComponentTranslations.js +147 -203
  133. package/es/i18n/useComponentTranslations.js.map +1 -0
  134. package/es/index.js +64 -44
  135. package/es/locale/messages-en.js +435 -459
  136. package/es/locale/messages-en.js.map +1 -0
  137. package/es/locale/messages-nb.js +435 -459
  138. package/es/locale/messages-nb.js.map +1 -0
  139. package/es/locale/messages-nn.js +435 -459
  140. package/es/locale/messages-nn.js.map +1 -0
  141. package/es/locale/messages-se.js +435 -459
  142. package/es/locale/messages-se.js.map +1 -0
  143. package/es/model/ContentType.js +69 -65
  144. package/es/model/ContentType.js.map +1 -0
  145. package/es/model/SubjectCategories.js +23 -10
  146. package/es/model/SubjectCategories.js.map +1 -0
  147. package/es/model/SubjectTypes.js +21 -9
  148. package/es/model/SubjectTypes.js.map +1 -0
  149. package/es/model/WordClass.js +51 -43
  150. package/es/model/WordClass.js.map +1 -0
  151. package/es/model/index.js +16 -18
  152. package/es/model/index.js.map +1 -0
  153. package/es/utils/licenseAttributes.js +15 -17
  154. package/es/utils/licenseAttributes.js.map +1 -0
  155. package/es/utils/relativeUrl.js +21 -32
  156. package/es/utils/relativeUrl.js.map +1 -0
  157. package/lib/Article/Article.js +130 -203
  158. package/lib/Article/Article.js.map +1 -0
  159. package/lib/Article/ArticleByline.js +125 -179
  160. package/lib/Article/ArticleByline.js.map +1 -0
  161. package/lib/Article/ArticleFootNotes.js +39 -65
  162. package/lib/Article/ArticleFootNotes.js.map +1 -0
  163. package/lib/AudioPlayer/AudioPlayer.js +155 -221
  164. package/lib/AudioPlayer/AudioPlayer.js.map +1 -0
  165. package/lib/AudioPlayer/Controls.js +249 -332
  166. package/lib/AudioPlayer/Controls.js.map +1 -0
  167. package/lib/AudioPlayer/SpeechControl.js +39 -60
  168. package/lib/AudioPlayer/SpeechControl.js.map +1 -0
  169. package/lib/AudioPlayer/index.js +7 -15
  170. package/lib/AudioPlayer/index.js.map +1 -0
  171. package/lib/Breadcrumb/Breadcrumb.js +43 -65
  172. package/lib/Breadcrumb/Breadcrumb.js.map +1 -0
  173. package/lib/Breadcrumb/BreadcrumbItem.js +34 -65
  174. package/lib/Breadcrumb/BreadcrumbItem.js.map +1 -0
  175. package/lib/Breadcrumb/HomeBreadcrumb.js +43 -82
  176. package/lib/Breadcrumb/HomeBreadcrumb.js.map +1 -0
  177. package/lib/Breadcrumb/index.js +8 -22
  178. package/lib/Breadcrumb/index.js.map +1 -0
  179. package/lib/CampaignBlock/CampaignBlock.js +128 -183
  180. package/lib/CampaignBlock/CampaignBlock.js.map +1 -0
  181. package/lib/CodeBlock/CodeBlock.js +23 -38
  182. package/lib/CodeBlock/CodeBlock.js.map +1 -0
  183. package/lib/CodeBlock/codeLanguageOptions.js +112 -87
  184. package/lib/CodeBlock/codeLanguageOptions.js.map +1 -0
  185. package/lib/Concept/Concept.js +48 -75
  186. package/lib/Concept/Concept.js.map +1 -0
  187. package/lib/ContactBlock/ContactBlock.js +141 -200
  188. package/lib/ContactBlock/ContactBlock.js.map +1 -0
  189. package/lib/ContentTypeBadge/ContentTypeBadge.js +40 -54
  190. package/lib/ContentTypeBadge/ContentTypeBadge.js.map +1 -0
  191. package/lib/ContentTypeBlockQuote/ContentTypeBlockQuote.js +23 -35
  192. package/lib/ContentTypeBlockQuote/ContentTypeBlockQuote.js.map +1 -0
  193. package/lib/ContentTypeFramedContent/ContentTypeFramedContent.js +23 -35
  194. package/lib/ContentTypeFramedContent/ContentTypeFramedContent.js.map +1 -0
  195. package/lib/ContentTypeHero/ContentTypeHero.js +37 -54
  196. package/lib/ContentTypeHero/ContentTypeHero.js.map +1 -0
  197. package/lib/CopyParagraphButton/CopyParagraphButton.js +61 -87
  198. package/lib/CopyParagraphButton/CopyParagraphButton.js.map +1 -0
  199. package/lib/CopyParagraphButton/index.js +7 -21
  200. package/lib/CopyParagraphButton/index.js.map +1 -0
  201. package/lib/Embed/AudioEmbed.js +51 -82
  202. package/lib/Embed/AudioEmbed.js.map +1 -0
  203. package/lib/Embed/BrightcoveEmbed.js +93 -138
  204. package/lib/Embed/BrightcoveEmbed.js.map +1 -0
  205. package/lib/Embed/CodeEmbed.js +59 -83
  206. package/lib/Embed/CodeEmbed.js.map +1 -0
  207. package/lib/Embed/ConceptEmbed.js +77 -127
  208. package/lib/Embed/ConceptEmbed.js.map +1 -0
  209. package/lib/Embed/ConceptInlineTriggerButton.js +39 -49
  210. package/lib/Embed/ConceptInlineTriggerButton.js.map +1 -0
  211. package/lib/Embed/ContentLinkEmbed.js +30 -55
  212. package/lib/Embed/ContentLinkEmbed.js.map +1 -0
  213. package/lib/Embed/CopyrightEmbed.js +22 -37
  214. package/lib/Embed/CopyrightEmbed.js.map +1 -0
  215. package/lib/Embed/EmbedErrorPlaceholder.js +42 -62
  216. package/lib/Embed/EmbedErrorPlaceholder.js.map +1 -0
  217. package/lib/Embed/EmbedWrapper.js +24 -54
  218. package/lib/Embed/EmbedWrapper.js.map +1 -0
  219. package/lib/Embed/ExternalEmbed.js +53 -79
  220. package/lib/Embed/ExternalEmbed.js.map +1 -0
  221. package/lib/Embed/FootnoteEmbed.js +26 -48
  222. package/lib/Embed/FootnoteEmbed.js.map +1 -0
  223. package/lib/Embed/GlossEmbed.js +51 -86
  224. package/lib/Embed/GlossEmbed.js.map +1 -0
  225. package/lib/Embed/H5pEmbed.js +37 -66
  226. package/lib/Embed/H5pEmbed.js.map +1 -0
  227. package/lib/Embed/IframeEmbed.js +68 -98
  228. package/lib/Embed/IframeEmbed.js.map +1 -0
  229. package/lib/Embed/ImageEmbed.js +173 -238
  230. package/lib/Embed/ImageEmbed.js.map +1 -0
  231. package/lib/Embed/InlineTriggerButton.js +23 -40
  232. package/lib/Embed/InlineTriggerButton.js.map +1 -0
  233. package/lib/Embed/RelatedContentEmbed.js +37 -59
  234. package/lib/Embed/RelatedContentEmbed.js.map +1 -0
  235. package/lib/Embed/UnknownEmbed.js +19 -35
  236. package/lib/Embed/UnknownEmbed.js.map +1 -0
  237. package/lib/Embed/UuDisclaimerEmbed.js +53 -92
  238. package/lib/Embed/UuDisclaimerEmbed.js.map +1 -0
  239. package/lib/ErrorMessage/ErrorMessage.js +53 -99
  240. package/lib/ErrorMessage/ErrorMessage.js.map +1 -0
  241. package/lib/ErrorMessage/index.js +7 -15
  242. package/lib/ErrorMessage/index.js.map +1 -0
  243. package/lib/FactBox/FactBox.js +118 -180
  244. package/lib/FactBox/FactBox.js.map +1 -0
  245. package/lib/FactBox/index.js +7 -15
  246. package/lib/FactBox/index.js.map +1 -0
  247. package/lib/FileList/File.js +75 -105
  248. package/lib/FileList/File.js.map +1 -0
  249. package/lib/FileList/FileList.js +33 -52
  250. package/lib/FileList/FileList.js.map +1 -0
  251. package/lib/FileList/PdfFile.js +27 -55
  252. package/lib/FileList/PdfFile.js.map +1 -0
  253. package/lib/Gloss/Gloss.js +138 -176
  254. package/lib/Gloss/Gloss.js.map +1 -0
  255. package/lib/Gloss/GlossExample.js +45 -68
  256. package/lib/Gloss/GlossExample.js.map +1 -0
  257. package/lib/Grid/Grid.js +64 -98
  258. package/lib/Grid/Grid.js.map +1 -0
  259. package/lib/Grid/GridParallaxItem.js +19 -36
  260. package/lib/Grid/GridParallaxItem.js.map +1 -0
  261. package/lib/KeyFigure/KeyFigure.js +45 -68
  262. package/lib/KeyFigure/KeyFigure.js.map +1 -0
  263. package/lib/LicenseByline/EmbedByline.js +130 -216
  264. package/lib/LicenseByline/EmbedByline.js.map +1 -0
  265. package/lib/LicenseByline/LicenseLink.js +29 -59
  266. package/lib/LicenseByline/LicenseLink.js.map +1 -0
  267. package/lib/LinkBlock/LinkBlock.js +73 -108
  268. package/lib/LinkBlock/LinkBlock.js.map +1 -0
  269. package/lib/LinkBlock/LinkBlockSection.js +22 -39
  270. package/lib/LinkBlock/LinkBlockSection.js.map +1 -0
  271. package/lib/Pitch/Pitch.js +61 -89
  272. package/lib/Pitch/Pitch.js.map +1 -0
  273. package/lib/RelatedArticleList/RelatedArticleList.js +96 -140
  274. package/lib/RelatedArticleList/RelatedArticleList.js.map +1 -0
  275. package/lib/RelatedArticleList/index.js +7 -20
  276. package/lib/RelatedArticleList/index.js.map +1 -0
  277. package/lib/ResourceBox/ResourceBox.js +73 -104
  278. package/lib/ResourceBox/ResourceBox.js.map +1 -0
  279. package/lib/TagSelector/TagSelector.js +103 -145
  280. package/lib/TagSelector/TagSelector.js.map +1 -0
  281. package/lib/ZendeskButton/ZendeskButton.js +39 -58
  282. package/lib/ZendeskButton/ZendeskButton.js.map +1 -0
  283. package/lib/_virtual/rolldown_runtime.js +42 -0
  284. package/lib/i18n/formatNestedMessages.js +16 -30
  285. package/lib/i18n/formatNestedMessages.js.map +1 -0
  286. package/lib/i18n/i18n.js +28 -38
  287. package/lib/i18n/i18n.js.map +1 -0
  288. package/lib/i18n/useComponentTranslations.js +154 -215
  289. package/lib/i18n/useComponentTranslations.js.map +1 -0
  290. package/lib/index.js +156 -598
  291. package/lib/locale/messages-en.js +436 -466
  292. package/lib/locale/messages-en.js.map +1 -0
  293. package/lib/locale/messages-nb.js +436 -466
  294. package/lib/locale/messages-nb.js.map +1 -0
  295. package/lib/locale/messages-nn.js +436 -466
  296. package/lib/locale/messages-nn.js.map +1 -0
  297. package/lib/locale/messages-se.js +436 -466
  298. package/lib/locale/messages-se.js.map +1 -0
  299. package/lib/model/ContentType.js +90 -70
  300. package/lib/model/ContentType.js.map +1 -0
  301. package/lib/model/SubjectCategories.js +26 -14
  302. package/lib/model/SubjectCategories.js.map +1 -0
  303. package/lib/model/SubjectTypes.js +24 -13
  304. package/lib/model/SubjectTypes.js.map +1 -0
  305. package/lib/model/WordClass.js +55 -48
  306. package/lib/model/WordClass.js.map +1 -0
  307. package/lib/model/index.js +16 -25
  308. package/lib/model/index.js.map +1 -0
  309. package/lib/utils/licenseAttributes.js +14 -22
  310. package/lib/utils/licenseAttributes.js.map +1 -0
  311. package/lib/utils/relativeUrl.js +20 -38
  312. package/lib/utils/relativeUrl.js.map +1 -0
  313. package/package.json +12 -11
  314. package/es/Article/index.js +0 -11
  315. package/es/CampaignBlock/index.js +0 -9
  316. package/es/CodeBlock/index.js +0 -10
  317. package/es/ContactBlock/index.js +0 -9
  318. package/es/ContentTypeHero/index.js +0 -9
  319. package/es/Embed/index.js +0 -25
  320. package/es/Embed/types.js +0 -1
  321. package/es/FileList/index.js +0 -11
  322. package/es/Gloss/index.js +0 -10
  323. package/es/Grid/index.js +0 -10
  324. package/es/KeyFigure/index.js +0 -9
  325. package/es/LicenseByline/index.js +0 -10
  326. package/es/LinkBlock/index.js +0 -10
  327. package/es/Pitch/index.js +0 -9
  328. package/es/ResourceBox/index.js +0 -10
  329. package/es/i18n/index.js +0 -11
  330. package/es/types.js +0 -1
  331. package/lib/Article/index.js +0 -68
  332. package/lib/CampaignBlock/index.js +0 -13
  333. package/lib/CodeBlock/index.js +0 -20
  334. package/lib/ContactBlock/index.js +0 -18
  335. package/lib/ContentTypeHero/index.js +0 -12
  336. package/lib/Embed/index.js +0 -150
  337. package/lib/Embed/types.js +0 -5
  338. package/lib/FileList/index.js +0 -44
  339. package/lib/Gloss/index.js +0 -20
  340. package/lib/Grid/index.js +0 -19
  341. package/lib/KeyFigure/index.js +0 -13
  342. package/lib/LicenseByline/index.js +0 -19
  343. package/lib/LinkBlock/index.js +0 -20
  344. package/lib/Pitch/index.js +0 -12
  345. package/lib/ResourceBox/index.js +0 -13
  346. package/lib/i18n/index.js +0 -68
  347. package/lib/types.js +0 -5
@@ -1,332 +1,254 @@
1
- /**
2
- * Copyright (c) 2021-present, NDLA.
3
- *
4
- * This source code is licensed under the GPLv3 license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- */
8
-
9
1
  import { useEffect, useRef, useState } from "react";
10
- import { useTranslation } from "react-i18next";
11
- import { createListCollection } from "@ark-ui/react";
12
- import { Replay15Line, Forward15Line, PlayFill, PauseLine, VolumeUpFill, CheckLine } from "@ndla/icons";
13
2
  import { Button, FieldRoot, IconButton, PopoverContent, PopoverRoot, PopoverTrigger, SelectContent, SelectControl, SelectItem, SelectItemIndicator, SelectItemText, SelectLabel, SelectRoot, SelectTrigger, SliderControl, SliderHiddenInput, SliderLabel, SliderRange, SliderRoot, SliderThumb, SliderTrack, Text } from "@ndla/primitives";
14
3
  import { styled } from "@ndla/styled-system/jsx";
15
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
- const ControlsWrapper = styled("div", {
17
- base: {
18
- borderBlockStart: "1px solid",
19
- borderColor: "stroke.default",
20
- borderBottomRadius: "xsmall",
21
- display: "flex",
22
- alignItems: "center",
23
- justifyContent: "center",
24
- background: "background.default",
25
- gap: "xsmall",
26
- paddingBlock: "xsmall",
27
- paddingInline: "medium",
28
- tabletWideDown: {
29
- display: "grid",
30
- paddingBlock: "xsmall",
31
- paddingInline: "xsmall",
32
- gridTemplateColumns: "1fr repeat(5, auto) 1fr",
33
- gridTemplateAreas: `
4
+ import { useTranslation } from "react-i18next";
5
+ import { CheckLine, Forward15Line, PauseLine, PlayFill, Replay15Line, VolumeUpFill } from "@ndla/icons";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { createListCollection } from "@ark-ui/react";
8
+
9
+ //#region src/AudioPlayer/Controls.tsx
10
+ const ControlsWrapper = styled("div", { base: {
11
+ borderBlockStart: "1px solid",
12
+ borderColor: "stroke.default",
13
+ borderBottomRadius: "xsmall",
14
+ display: "flex",
15
+ alignItems: "center",
16
+ justifyContent: "center",
17
+ background: "background.default",
18
+ gap: "xsmall",
19
+ paddingBlock: "xsmall",
20
+ paddingInline: "medium",
21
+ tabletWideDown: {
22
+ display: "grid",
23
+ paddingBlock: "xsmall",
24
+ paddingInline: "xsmall",
25
+ gridTemplateColumns: "1fr repeat(5, auto) 1fr",
26
+ gridTemplateAreas: `
34
27
  "track track track track track track track"
35
28
  ". speed backwards play forwards volume ."
36
29
  `
37
- },
38
- mobileWideDown: {
39
- columnGap: "3xsmall"
40
- }
41
- }
42
- });
43
- const PlayButton = styled(IconButton, {
44
- base: {
45
- gridArea: "play"
46
- }
47
- });
48
- const Forward15SecButton = styled(IconButton, {
49
- base: {
50
- gridArea: "forwards"
51
- }
52
- });
53
- const Back15SecButton = styled(IconButton, {
54
- base: {
55
- gridArea: "backwards"
56
- }
57
- });
58
- const ProgressWrapper = styled("div", {
59
- base: {
60
- flex: "1",
61
- display: "flex",
62
- alignItems: "center",
63
- gap: "xxsmall",
64
- gridArea: "track",
65
- paddingBlock: "xsmall",
66
- mobileDown: {
67
- paddingInline: "xsmall"
68
- }
69
- }
70
- });
71
- const StyledText = styled(Text, {
72
- base: {
73
- minWidth: "xxlarge",
74
- flexShrink: "0",
75
- textAlign: "center"
76
- }
77
- });
78
- const VolumeButton = styled(IconButton, {
79
- base: {
80
- gridArea: "volume"
81
- }
82
- });
83
- const SpeedButton = styled(Button, {
84
- base: {
85
- paddingBlock: "auto",
86
- paddingInline: "auto",
87
- maxWidth: "xxlarge",
88
- maxHeight: "xxlarge",
89
- minWidth: "xxlarge",
90
- minHeight: "xxlarge",
91
- "& span": {
92
- flex: "1"
93
- }
94
- }
95
- });
96
- const StyledSelectRoot = styled(SelectRoot, {
97
- base: {
98
- gridArea: "speed"
99
- }
100
- });
101
- const StyledSliderControl = styled(SliderControl, {
102
- base: {
103
- height: "surface.3xsmall",
104
- minWidth: "small"
105
- }
106
- });
107
- const StyledPopoverContent = styled(PopoverContent, {
108
- base: {
109
- paddingInline: "small"
110
- }
111
- });
112
- const formatTime = seconds => {
113
- const minutes = Math.floor(seconds / 60);
114
- const currentSeconds = seconds % 60;
115
- const formattedSeconds = currentSeconds < 10 ? `0${currentSeconds}` : currentSeconds;
116
- return `${minutes}:${formattedSeconds}`;
30
+ },
31
+ mobileWideDown: { columnGap: "3xsmall" }
32
+ } });
33
+ const PlayButton = styled(IconButton, { base: { gridArea: "play" } });
34
+ const Forward15SecButton = styled(IconButton, { base: { gridArea: "forwards" } });
35
+ const Back15SecButton = styled(IconButton, { base: { gridArea: "backwards" } });
36
+ const ProgressWrapper = styled("div", { base: {
37
+ flex: "1",
38
+ display: "flex",
39
+ alignItems: "center",
40
+ gap: "xxsmall",
41
+ gridArea: "track",
42
+ paddingBlock: "xsmall",
43
+ mobileDown: { paddingInline: "xsmall" }
44
+ } });
45
+ const StyledText = styled(Text, { base: {
46
+ minWidth: "xxlarge",
47
+ flexShrink: "0",
48
+ textAlign: "center"
49
+ } });
50
+ const VolumeButton = styled(IconButton, { base: { gridArea: "volume" } });
51
+ const SpeedButton = styled(Button, { base: {
52
+ paddingBlock: "auto",
53
+ paddingInline: "auto",
54
+ maxWidth: "xxlarge",
55
+ maxHeight: "xxlarge",
56
+ minWidth: "xxlarge",
57
+ minHeight: "xxlarge",
58
+ "& span": { flex: "1" }
59
+ } });
60
+ const StyledSelectRoot = styled(SelectRoot, { base: { gridArea: "speed" } });
61
+ const StyledSliderControl = styled(SliderControl, { base: {
62
+ height: "surface.3xsmall",
63
+ minWidth: "small"
64
+ } });
65
+ const StyledPopoverContent = styled(PopoverContent, { base: { paddingInline: "small" } });
66
+ const formatTime = (seconds) => {
67
+ const minutes = Math.floor(seconds / 60);
68
+ const currentSeconds = seconds % 60;
69
+ const formattedSeconds = currentSeconds < 10 ? `0${currentSeconds}` : currentSeconds;
70
+ return `${minutes}:${formattedSeconds}`;
117
71
  };
118
- const speedValues = createListCollection({
119
- items: ["0.5", "0.75", "1", "1.25", "1.5", "1.75", "2"]
120
- });
121
- const Controls = _ref => {
122
- let {
123
- src,
124
- title
125
- } = _ref;
126
- const {
127
- t
128
- } = useTranslation();
129
- const [speedValue, setSpeedValue] = useState(1);
130
- const [volumeValue, setVolumeValue] = useState(100);
131
- const [currentTime, setCurrentTime] = useState(0);
132
- const [remainingTime, setRemainingTime] = useState(0);
133
- const [playing, setPlaying] = useState(false);
134
- const audioRef = useRef(null);
135
- useEffect(() => {
136
- if (audioRef.current) {
137
- audioRef.current.playbackRate = speedValue;
138
- }
139
- }, [speedValue]);
140
- useEffect(() => {
141
- if (audioRef.current) {
142
- const audioElement = audioRef.current;
143
- const handleTimeUpdate = () => {
144
- const {
145
- currentTime,
146
- duration
147
- } = audioElement;
148
- setCurrentTime(Math.round(currentTime));
149
- setRemainingTime(Math.round(duration - currentTime));
150
- };
151
- const handleLoadedMetaData = () => {
152
- const {
153
- currentTime,
154
- duration
155
- } = audioElement;
156
- setCurrentTime(Math.round(currentTime));
157
- setRemainingTime(Math.round(duration - currentTime));
158
- };
159
- const handleTimeEnded = () => {
160
- setPlaying(false);
161
- };
162
- audioElement.addEventListener("timeupdate", handleTimeUpdate);
163
- audioElement.addEventListener("loadedmetadata", handleLoadedMetaData);
164
- audioElement.addEventListener("ended", handleTimeEnded);
165
- return () => {
166
- audioElement.removeEventListener("timeupdate", handleTimeUpdate);
167
- audioElement.removeEventListener("loadedmetadata", handleLoadedMetaData);
168
- audioElement.removeEventListener("ended", handleTimeEnded);
169
- };
170
- }
171
- }, []);
172
- const togglePlay = () => {
173
- if (audioRef.current) {
174
- const audioElement = audioRef.current;
175
- if (!playing) {
176
- audioElement.play();
177
- } else {
178
- audioElement.pause();
179
- }
180
- setPlaying(!playing);
181
- }
182
- };
183
- const onSeekSeconds = seconds => {
184
- if (audioRef.current) {
185
- audioRef.current.currentTime += seconds;
186
- }
187
- };
188
- const handleSliderChange = details => {
189
- const newValue = details.value[0];
190
- if (audioRef.current && newValue != null && !isNaN(newValue)) {
191
- audioRef.current.currentTime = details.value[0];
192
- }
193
- };
194
- const handleVolumeSliderChange = details => {
195
- if (audioRef.current) {
196
- audioRef.current.volume = details.value[0] / 100;
197
- setVolumeValue(details.value[0]);
198
- }
199
- };
200
- return /*#__PURE__*/_jsxs("div", {
201
- children: [/*#__PURE__*/_jsx("audio", {
202
- ref: audioRef,
203
- src: src,
204
- title: title,
205
- preload: "metadata"
206
- }), /*#__PURE__*/_jsxs(ControlsWrapper, {
207
- children: [/*#__PURE__*/_jsx(Back15SecButton, {
208
- variant: "tertiary",
209
- title: t("audio.controls.rewind15sec"),
210
- "aria-label": t("audio.controls.rewind15sec"),
211
- onClick: () => onSeekSeconds(-15),
212
- children: /*#__PURE__*/_jsx(Replay15Line, {})
213
- }), /*#__PURE__*/_jsx(PlayButton, {
214
- "aria-label": t(playing ? t("audio.pause") : t("audio.play")),
215
- variant: "primary",
216
- onClick: togglePlay,
217
- children: playing ? /*#__PURE__*/_jsx(PauseLine, {}) : /*#__PURE__*/_jsx(PlayFill, {})
218
- }), /*#__PURE__*/_jsx(Forward15SecButton, {
219
- variant: "tertiary",
220
- title: t("audio.controls.forward15sec"),
221
- "aria-label": t("audio.controls.forward15sec"),
222
- onClick: () => onSeekSeconds(15),
223
- children: /*#__PURE__*/_jsx(Forward15Line, {})
224
- }), /*#__PURE__*/_jsxs(ProgressWrapper, {
225
- children: [/*#__PURE__*/_jsx(StyledText, {
226
- textStyle: "label.medium",
227
- asChild: true,
228
- consumeCss: true,
229
- children: /*#__PURE__*/_jsx("div", {
230
- children: formatTime(currentTime)
231
- })
232
- }), /*#__PURE__*/_jsxs(SliderRoot, {
233
- value: [audioRef.current?.currentTime ?? 0],
234
- defaultValue: [0],
235
- step: 1,
236
- max: Math.round(audioRef.current?.duration ?? 0),
237
- onValueChange: handleSliderChange,
238
- getAriaValueText: value => t("audio.valueText", {
239
- start: formatTime(Math.round(value.value)),
240
- end: formatTime(Math.round(audioRef.current?.duration ?? 0))
241
- }),
242
- children: [/*#__PURE__*/_jsx(SliderLabel, {
243
- srOnly: true,
244
- children: t("audio.progressBar")
245
- }), /*#__PURE__*/_jsxs(SliderControl, {
246
- children: [/*#__PURE__*/_jsx(SliderTrack, {
247
- children: /*#__PURE__*/_jsx(SliderRange, {})
248
- }), /*#__PURE__*/_jsx(SliderThumb, {
249
- index: 0,
250
- children: /*#__PURE__*/_jsx(SliderHiddenInput, {})
251
- })]
252
- })]
253
- }), /*#__PURE__*/_jsx(StyledText, {
254
- textStyle: "label.medium",
255
- asChild: true,
256
- consumeCss: true,
257
- children: /*#__PURE__*/_jsxs("div", {
258
- children: ["-", formatTime(remainingTime)]
259
- })
260
- })]
261
- }), /*#__PURE__*/_jsx(FieldRoot, {
262
- children: /*#__PURE__*/_jsxs(StyledSelectRoot, {
263
- collection: speedValues,
264
- value: [speedValue.toString()],
265
- onValueChange: details => setSpeedValue(parseFloat(details.value[0])),
266
- positioning: {
267
- placement: "top"
268
- },
269
- children: [/*#__PURE__*/_jsx(SelectLabel, {
270
- srOnly: true,
271
- children: t("audio.controls.selectSpeed")
272
- }), /*#__PURE__*/_jsx(SelectControl, {
273
- children: /*#__PURE__*/_jsx(SelectTrigger, {
274
- asChild: true,
275
- children: /*#__PURE__*/_jsx(SpeedButton, {
276
- variant: "tertiary",
277
- title: t("audio.controls.selectSpeed"),
278
- "aria-label": t("audio.controls.selectSpeed"),
279
- children: /*#__PURE__*/_jsx("span", {
280
- children: `${speedValue}x`
281
- })
282
- })
283
- })
284
- }), /*#__PURE__*/_jsx(SelectContent, {
285
- children: speedValues.items.map(speed => /*#__PURE__*/_jsxs(SelectItem, {
286
- item: speed,
287
- children: [/*#__PURE__*/_jsxs(SelectItemText, {
288
- children: [speed, "x"]
289
- }), /*#__PURE__*/_jsx(SelectItemIndicator, {
290
- children: /*#__PURE__*/_jsx(CheckLine, {})
291
- })]
292
- }, speed))
293
- })]
294
- })
295
- }), /*#__PURE__*/_jsxs(PopoverRoot, {
296
- positioning: {
297
- placement: "top"
298
- },
299
- children: [/*#__PURE__*/_jsx(PopoverTrigger, {
300
- asChild: true,
301
- children: /*#__PURE__*/_jsx(VolumeButton, {
302
- variant: "tertiary",
303
- "aria-label": t("audio.controls.adjustVolume"),
304
- children: /*#__PURE__*/_jsx(VolumeUpFill, {})
305
- })
306
- }), /*#__PURE__*/_jsx(StyledPopoverContent, {
307
- children: /*#__PURE__*/_jsxs(SliderRoot, {
308
- orientation: "vertical",
309
- value: [volumeValue],
310
- min: 0,
311
- max: 100,
312
- defaultValue: [100],
313
- step: 1,
314
- onValueChange: handleVolumeSliderChange,
315
- children: [/*#__PURE__*/_jsx(SliderLabel, {
316
- srOnly: true,
317
- children: t("audio.controls.adjustVolume")
318
- }), /*#__PURE__*/_jsxs(StyledSliderControl, {
319
- children: [/*#__PURE__*/_jsx(SliderTrack, {
320
- children: /*#__PURE__*/_jsx(SliderRange, {})
321
- }), /*#__PURE__*/_jsx(SliderThumb, {
322
- index: 0,
323
- children: /*#__PURE__*/_jsx(SliderHiddenInput, {})
324
- })]
325
- })]
326
- })
327
- })]
328
- })]
329
- })]
330
- });
72
+ const speedValues = createListCollection({ items: [
73
+ "0.5",
74
+ "0.75",
75
+ "1",
76
+ "1.25",
77
+ "1.5",
78
+ "1.75",
79
+ "2"
80
+ ] });
81
+ const Controls = ({ src, title }) => {
82
+ const { t } = useTranslation();
83
+ const [speedValue, setSpeedValue] = useState(1);
84
+ const [volumeValue, setVolumeValue] = useState(100);
85
+ const [currentTime, setCurrentTime] = useState(0);
86
+ const [remainingTime, setRemainingTime] = useState(0);
87
+ const [playing, setPlaying] = useState(false);
88
+ const audioRef = useRef(null);
89
+ useEffect(() => {
90
+ if (audioRef.current) audioRef.current.playbackRate = speedValue;
91
+ }, [speedValue]);
92
+ useEffect(() => {
93
+ if (audioRef.current) {
94
+ const audioElement = audioRef.current;
95
+ const handleTimeUpdate = () => {
96
+ const { currentTime: currentTime$1, duration } = audioElement;
97
+ setCurrentTime(Math.round(currentTime$1));
98
+ setRemainingTime(Math.round(duration - currentTime$1));
99
+ };
100
+ const handleLoadedMetaData = () => {
101
+ const { currentTime: currentTime$1, duration } = audioElement;
102
+ setCurrentTime(Math.round(currentTime$1));
103
+ setRemainingTime(Math.round(duration - currentTime$1));
104
+ };
105
+ const handleTimeEnded = () => {
106
+ setPlaying(false);
107
+ };
108
+ audioElement.addEventListener("timeupdate", handleTimeUpdate);
109
+ audioElement.addEventListener("loadedmetadata", handleLoadedMetaData);
110
+ audioElement.addEventListener("ended", handleTimeEnded);
111
+ return () => {
112
+ audioElement.removeEventListener("timeupdate", handleTimeUpdate);
113
+ audioElement.removeEventListener("loadedmetadata", handleLoadedMetaData);
114
+ audioElement.removeEventListener("ended", handleTimeEnded);
115
+ };
116
+ }
117
+ }, []);
118
+ const togglePlay = () => {
119
+ if (audioRef.current) {
120
+ const audioElement = audioRef.current;
121
+ if (!playing) audioElement.play();
122
+ else audioElement.pause();
123
+ setPlaying(!playing);
124
+ }
125
+ };
126
+ const onSeekSeconds = (seconds) => {
127
+ if (audioRef.current) audioRef.current.currentTime += seconds;
128
+ };
129
+ const handleSliderChange = (details) => {
130
+ const newValue = details.value[0];
131
+ if (audioRef.current && newValue != null && !isNaN(newValue)) audioRef.current.currentTime = details.value[0];
132
+ };
133
+ const handleVolumeSliderChange = (details) => {
134
+ if (audioRef.current) {
135
+ audioRef.current.volume = details.value[0] / 100;
136
+ setVolumeValue(details.value[0]);
137
+ }
138
+ };
139
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("audio", {
140
+ ref: audioRef,
141
+ src,
142
+ title,
143
+ preload: "metadata"
144
+ }), /* @__PURE__ */ jsxs(ControlsWrapper, { children: [
145
+ /* @__PURE__ */ jsx(Back15SecButton, {
146
+ variant: "tertiary",
147
+ title: t("audio.controls.rewind15sec"),
148
+ "aria-label": t("audio.controls.rewind15sec"),
149
+ onClick: () => onSeekSeconds(-15),
150
+ children: /* @__PURE__ */ jsx(Replay15Line, {})
151
+ }),
152
+ /* @__PURE__ */ jsx(PlayButton, {
153
+ "aria-label": t(playing ? t("audio.pause") : t("audio.play")),
154
+ variant: "primary",
155
+ onClick: togglePlay,
156
+ children: playing ? /* @__PURE__ */ jsx(PauseLine, {}) : /* @__PURE__ */ jsx(PlayFill, {})
157
+ }),
158
+ /* @__PURE__ */ jsx(Forward15SecButton, {
159
+ variant: "tertiary",
160
+ title: t("audio.controls.forward15sec"),
161
+ "aria-label": t("audio.controls.forward15sec"),
162
+ onClick: () => onSeekSeconds(15),
163
+ children: /* @__PURE__ */ jsx(Forward15Line, {})
164
+ }),
165
+ /* @__PURE__ */ jsxs(ProgressWrapper, { children: [
166
+ /* @__PURE__ */ jsx(StyledText, {
167
+ textStyle: "label.medium",
168
+ asChild: true,
169
+ consumeCss: true,
170
+ children: /* @__PURE__ */ jsx("div", { children: formatTime(currentTime) })
171
+ }),
172
+ /* @__PURE__ */ jsxs(SliderRoot, {
173
+ value: [audioRef.current?.currentTime ?? 0],
174
+ defaultValue: [0],
175
+ step: 1,
176
+ max: Math.round(audioRef.current?.duration ?? 0),
177
+ onValueChange: handleSliderChange,
178
+ getAriaValueText: (value) => t("audio.valueText", {
179
+ start: formatTime(Math.round(value.value)),
180
+ end: formatTime(Math.round(audioRef.current?.duration ?? 0))
181
+ }),
182
+ children: [/* @__PURE__ */ jsx(SliderLabel, {
183
+ srOnly: true,
184
+ children: t("audio.progressBar")
185
+ }), /* @__PURE__ */ jsxs(SliderControl, { children: [/* @__PURE__ */ jsx(SliderTrack, { children: /* @__PURE__ */ jsx(SliderRange, {}) }), /* @__PURE__ */ jsx(SliderThumb, {
186
+ index: 0,
187
+ children: /* @__PURE__ */ jsx(SliderHiddenInput, {})
188
+ })] })]
189
+ }),
190
+ /* @__PURE__ */ jsx(StyledText, {
191
+ textStyle: "label.medium",
192
+ asChild: true,
193
+ consumeCss: true,
194
+ children: /* @__PURE__ */ jsxs("div", { children: ["-", formatTime(remainingTime)] })
195
+ })
196
+ ] }),
197
+ /* @__PURE__ */ jsx(FieldRoot, { children: /* @__PURE__ */ jsxs(StyledSelectRoot, {
198
+ collection: speedValues,
199
+ value: [speedValue.toString()],
200
+ onValueChange: (details) => setSpeedValue(parseFloat(details.value[0])),
201
+ positioning: { placement: "top" },
202
+ children: [
203
+ /* @__PURE__ */ jsx(SelectLabel, {
204
+ srOnly: true,
205
+ children: t("audio.controls.selectSpeed")
206
+ }),
207
+ /* @__PURE__ */ jsx(SelectControl, { children: /* @__PURE__ */ jsx(SelectTrigger, {
208
+ asChild: true,
209
+ children: /* @__PURE__ */ jsx(SpeedButton, {
210
+ variant: "tertiary",
211
+ title: t("audio.controls.selectSpeed"),
212
+ "aria-label": t("audio.controls.selectSpeed"),
213
+ children: /* @__PURE__ */ jsx("span", { children: `${speedValue}x` })
214
+ })
215
+ }) }),
216
+ /* @__PURE__ */ jsx(SelectContent, { children: speedValues.items.map((speed) => /* @__PURE__ */ jsxs(SelectItem, {
217
+ item: speed,
218
+ children: [/* @__PURE__ */ jsxs(SelectItemText, { children: [speed, "x"] }), /* @__PURE__ */ jsx(SelectItemIndicator, { children: /* @__PURE__ */ jsx(CheckLine, {}) })]
219
+ }, speed)) })
220
+ ]
221
+ }) }),
222
+ /* @__PURE__ */ jsxs(PopoverRoot, {
223
+ positioning: { placement: "top" },
224
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, {
225
+ asChild: true,
226
+ children: /* @__PURE__ */ jsx(VolumeButton, {
227
+ variant: "tertiary",
228
+ "aria-label": t("audio.controls.adjustVolume"),
229
+ children: /* @__PURE__ */ jsx(VolumeUpFill, {})
230
+ })
231
+ }), /* @__PURE__ */ jsx(StyledPopoverContent, { children: /* @__PURE__ */ jsxs(SliderRoot, {
232
+ orientation: "vertical",
233
+ value: [volumeValue],
234
+ min: 0,
235
+ max: 100,
236
+ defaultValue: [100],
237
+ step: 1,
238
+ onValueChange: handleVolumeSliderChange,
239
+ children: [/* @__PURE__ */ jsx(SliderLabel, {
240
+ srOnly: true,
241
+ children: t("audio.controls.adjustVolume")
242
+ }), /* @__PURE__ */ jsxs(StyledSliderControl, { children: [/* @__PURE__ */ jsx(SliderTrack, { children: /* @__PURE__ */ jsx(SliderRange, {}) }), /* @__PURE__ */ jsx(SliderThumb, {
243
+ index: 0,
244
+ children: /* @__PURE__ */ jsx(SliderHiddenInput, {})
245
+ })] })]
246
+ }) })]
247
+ })
248
+ ] })] });
331
249
  };
332
- export default Controls;
250
+ var Controls_default = Controls;
251
+
252
+ //#endregion
253
+ export { Controls_default };
254
+ //# sourceMappingURL=Controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Controls.js","names":["seconds: number","currentTime","details: SliderValueChangeDetails"],"sources":["../../src/AudioPlayer/Controls.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 { useEffect, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { type SliderValueChangeDetails, createListCollection } from \"@ark-ui/react\";\nimport { Replay15Line, Forward15Line, PlayFill, PauseLine, VolumeUpFill, CheckLine } from \"@ndla/icons\";\nimport {\n Button,\n FieldRoot,\n IconButton,\n PopoverContent,\n PopoverRoot,\n PopoverTrigger,\n SelectContent,\n SelectControl,\n SelectItem,\n SelectItemIndicator,\n SelectItemText,\n SelectLabel,\n SelectRoot,\n SelectTrigger,\n SliderControl,\n SliderHiddenInput,\n SliderLabel,\n SliderRange,\n SliderRoot,\n SliderThumb,\n SliderTrack,\n Text,\n} from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\n\nconst ControlsWrapper = styled(\"div\", {\n base: {\n borderBlockStart: \"1px solid\",\n borderColor: \"stroke.default\",\n borderBottomRadius: \"xsmall\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"background.default\",\n gap: \"xsmall\",\n paddingBlock: \"xsmall\",\n paddingInline: \"medium\",\n tabletWideDown: {\n display: \"grid\",\n paddingBlock: \"xsmall\",\n paddingInline: \"xsmall\",\n gridTemplateColumns: \"1fr repeat(5, auto) 1fr\",\n gridTemplateAreas: `\n \"track track track track track track track\"\n \". speed backwards play forwards volume .\"\n`,\n },\n mobileWideDown: {\n columnGap: \"3xsmall\",\n },\n },\n});\n\nconst PlayButton = styled(IconButton, {\n base: {\n gridArea: \"play\",\n },\n});\n\nconst Forward15SecButton = styled(IconButton, {\n base: {\n gridArea: \"forwards\",\n },\n});\n\nconst Back15SecButton = styled(IconButton, {\n base: {\n gridArea: \"backwards\",\n },\n});\n\nconst ProgressWrapper = styled(\"div\", {\n base: {\n flex: \"1\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"xxsmall\",\n gridArea: \"track\",\n paddingBlock: \"xsmall\",\n mobileDown: {\n paddingInline: \"xsmall\",\n },\n },\n});\n\nconst StyledText = styled(Text, {\n base: {\n minWidth: \"xxlarge\",\n flexShrink: \"0\",\n textAlign: \"center\",\n },\n});\n\nconst VolumeButton = styled(IconButton, {\n base: {\n gridArea: \"volume\",\n },\n});\n\nconst SpeedButton = styled(Button, {\n base: {\n paddingBlock: \"auto\",\n paddingInline: \"auto\",\n maxWidth: \"xxlarge\",\n maxHeight: \"xxlarge\",\n minWidth: \"xxlarge\",\n minHeight: \"xxlarge\",\n \"& span\": {\n flex: \"1\",\n },\n },\n});\n\nconst StyledSelectRoot = styled(SelectRoot<string>, {\n base: {\n gridArea: \"speed\",\n },\n});\n\nconst StyledSliderControl = styled(SliderControl, {\n base: {\n height: \"surface.3xsmall\",\n minWidth: \"small\",\n },\n});\n\nconst StyledPopoverContent = styled(PopoverContent, {\n base: {\n paddingInline: \"small\",\n },\n});\n\nconst formatTime = (seconds: number) => {\n const minutes = Math.floor(seconds / 60);\n const currentSeconds = seconds % 60;\n\n const formattedSeconds = currentSeconds < 10 ? `0${currentSeconds}` : currentSeconds;\n return `${minutes}:${formattedSeconds}`;\n};\n\nconst speedValues = createListCollection({ items: [\"0.5\", \"0.75\", \"1\", \"1.25\", \"1.5\", \"1.75\", \"2\"] });\n\ninterface Props {\n src: string;\n title: string;\n}\n\nconst Controls = ({ src, title }: Props) => {\n const { t } = useTranslation();\n const [speedValue, setSpeedValue] = useState(1);\n const [volumeValue, setVolumeValue] = useState(100);\n const [currentTime, setCurrentTime] = useState(0);\n const [remainingTime, setRemainingTime] = useState(0);\n const [playing, setPlaying] = useState(false);\n const audioRef = useRef<HTMLAudioElement>(null);\n\n useEffect(() => {\n if (audioRef.current) {\n audioRef.current.playbackRate = speedValue;\n }\n }, [speedValue]);\n\n useEffect(() => {\n if (audioRef.current) {\n const audioElement = audioRef.current;\n const handleTimeUpdate = () => {\n const { currentTime, duration } = audioElement;\n setCurrentTime(Math.round(currentTime));\n setRemainingTime(Math.round(duration - currentTime));\n };\n\n const handleLoadedMetaData = () => {\n const { currentTime, duration } = audioElement;\n setCurrentTime(Math.round(currentTime));\n setRemainingTime(Math.round(duration - currentTime));\n };\n\n const handleTimeEnded = () => {\n setPlaying(false);\n };\n\n audioElement.addEventListener(\"timeupdate\", handleTimeUpdate);\n audioElement.addEventListener(\"loadedmetadata\", handleLoadedMetaData);\n audioElement.addEventListener(\"ended\", handleTimeEnded);\n return () => {\n audioElement.removeEventListener(\"timeupdate\", handleTimeUpdate);\n audioElement.removeEventListener(\"loadedmetadata\", handleLoadedMetaData);\n audioElement.removeEventListener(\"ended\", handleTimeEnded);\n };\n }\n }, []);\n\n const togglePlay = () => {\n if (audioRef.current) {\n const audioElement = audioRef.current;\n if (!playing) {\n audioElement.play();\n } else {\n audioElement.pause();\n }\n setPlaying(!playing);\n }\n };\n\n const onSeekSeconds = (seconds: number) => {\n if (audioRef.current) {\n audioRef.current.currentTime += seconds;\n }\n };\n\n const handleSliderChange = (details: SliderValueChangeDetails) => {\n const newValue = details.value[0];\n if (audioRef.current && newValue != null && !isNaN(newValue)) {\n audioRef.current.currentTime = details.value[0];\n }\n };\n\n const handleVolumeSliderChange = (details: SliderValueChangeDetails) => {\n if (audioRef.current) {\n audioRef.current.volume = details.value[0] / 100;\n setVolumeValue(details.value[0]);\n }\n };\n\n return (\n <div>\n {/* TODO: We should tie this up to the textual description somehow */}\n {/* eslint-disable-next-line jsx-a11y/media-has-caption */}\n <audio ref={audioRef} src={src} title={title} preload=\"metadata\" />\n <ControlsWrapper>\n <Back15SecButton\n variant=\"tertiary\"\n title={t(\"audio.controls.rewind15sec\")}\n aria-label={t(\"audio.controls.rewind15sec\")}\n onClick={() => onSeekSeconds(-15)}\n >\n <Replay15Line />\n </Back15SecButton>\n <PlayButton aria-label={t(playing ? t(\"audio.pause\") : t(\"audio.play\"))} variant=\"primary\" onClick={togglePlay}>\n {playing ? <PauseLine /> : <PlayFill />}\n </PlayButton>\n <Forward15SecButton\n variant=\"tertiary\"\n title={t(\"audio.controls.forward15sec\")}\n aria-label={t(\"audio.controls.forward15sec\")}\n onClick={() => onSeekSeconds(15)}\n >\n <Forward15Line />\n </Forward15SecButton>\n <ProgressWrapper>\n <StyledText textStyle=\"label.medium\" asChild consumeCss>\n <div>{formatTime(currentTime)}</div>\n </StyledText>\n <SliderRoot\n value={[audioRef.current?.currentTime ?? 0]}\n defaultValue={[0]}\n step={1}\n max={Math.round(audioRef.current?.duration ?? 0)}\n onValueChange={handleSliderChange}\n getAriaValueText={(value) =>\n t(\"audio.valueText\", {\n start: formatTime(Math.round(value.value)),\n end: formatTime(Math.round(audioRef.current?.duration ?? 0)),\n })\n }\n >\n <SliderLabel srOnly>{t(\"audio.progressBar\")}</SliderLabel>\n <SliderControl>\n <SliderTrack>\n <SliderRange />\n </SliderTrack>\n <SliderThumb index={0}>\n <SliderHiddenInput />\n </SliderThumb>\n </SliderControl>\n </SliderRoot>\n <StyledText textStyle=\"label.medium\" asChild consumeCss>\n <div>-{formatTime(remainingTime)}</div>\n </StyledText>\n </ProgressWrapper>\n <FieldRoot>\n <StyledSelectRoot\n collection={speedValues}\n value={[speedValue.toString()]}\n onValueChange={(details) => setSpeedValue(parseFloat(details.value[0]))}\n positioning={{ placement: \"top\" }}\n >\n <SelectLabel srOnly>{t(\"audio.controls.selectSpeed\")}</SelectLabel>\n <SelectControl>\n <SelectTrigger asChild>\n <SpeedButton\n variant=\"tertiary\"\n title={t(\"audio.controls.selectSpeed\")}\n aria-label={t(\"audio.controls.selectSpeed\")}\n >\n <span>{`${speedValue}x`}</span>\n </SpeedButton>\n </SelectTrigger>\n </SelectControl>\n <SelectContent>\n {speedValues.items.map((speed) => (\n <SelectItem key={speed} item={speed}>\n <SelectItemText>{speed}x</SelectItemText>\n <SelectItemIndicator>\n <CheckLine />\n </SelectItemIndicator>\n </SelectItem>\n ))}\n </SelectContent>\n </StyledSelectRoot>\n </FieldRoot>\n <PopoverRoot positioning={{ placement: \"top\" }}>\n <PopoverTrigger asChild>\n <VolumeButton variant=\"tertiary\" aria-label={t(\"audio.controls.adjustVolume\")}>\n <VolumeUpFill />\n </VolumeButton>\n </PopoverTrigger>\n <StyledPopoverContent>\n <SliderRoot\n orientation=\"vertical\"\n value={[volumeValue]}\n min={0}\n max={100}\n defaultValue={[100]}\n step={1}\n onValueChange={handleVolumeSliderChange}\n >\n <SliderLabel srOnly>{t(\"audio.controls.adjustVolume\")}</SliderLabel>\n <StyledSliderControl>\n <SliderTrack>\n <SliderRange />\n </SliderTrack>\n <SliderThumb index={0}>\n <SliderHiddenInput />\n </SliderThumb>\n </StyledSliderControl>\n </SliderRoot>\n </StyledPopoverContent>\n </PopoverRoot>\n </ControlsWrapper>\n </div>\n );\n};\n\nexport default Controls;\n"],"mappings":"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"}