@ndla/ui 56.0.142-alpha.0 → 56.0.144-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.
- package/dist/panda.buildinfo.json +2 -3
- package/dist/styles.css +5 -9
- package/es/Article/Article.mjs +10 -12
- package/es/Article/Article.mjs.map +1 -1
- package/es/Article/ArticleByline.mjs.map +1 -1
- package/es/Article/ArticleFootNotes.mjs.map +1 -1
- package/es/AudioPlayer/AudioPlayer.mjs +3 -3
- package/es/AudioPlayer/AudioPlayer.mjs.map +1 -1
- package/es/AudioPlayer/Controls.mjs +1 -1
- package/es/AudioPlayer/Controls.mjs.map +1 -1
- package/es/AudioPlayer/SpeechControl.mjs +1 -1
- package/es/AudioPlayer/SpeechControl.mjs.map +1 -1
- package/es/Breadcrumb/Breadcrumb.mjs +3 -8
- package/es/Breadcrumb/Breadcrumb.mjs.map +1 -1
- package/es/Breadcrumb/BreadcrumbItem.mjs +7 -18
- package/es/Breadcrumb/BreadcrumbItem.mjs.map +1 -1
- package/es/Breadcrumb/HomeBreadcrumb.mjs +4 -4
- package/es/Breadcrumb/HomeBreadcrumb.mjs.map +1 -1
- package/es/CampaignBlock/CampaignBlock.mjs +1 -1
- package/es/CampaignBlock/CampaignBlock.mjs.map +1 -1
- package/es/CodeBlock/CodeBlock.mjs +1 -1
- package/es/CodeBlock/CodeBlock.mjs.map +1 -1
- package/es/CodeBlock/codeLanguageOptions.mjs.map +1 -1
- package/es/Concept/Concept.mjs +5 -5
- package/es/Concept/Concept.mjs.map +1 -1
- package/es/ContactBlock/ContactBlock.mjs.map +1 -1
- package/es/ContentTypeBadge/ContentTypeBadge.mjs.map +1 -1
- package/es/CopyParagraphButton/CopyParagraphButton.mjs +1 -1
- package/es/CopyParagraphButton/CopyParagraphButton.mjs.map +1 -1
- package/es/Embed/AudioEmbed.mjs +3 -3
- package/es/Embed/AudioEmbed.mjs.map +1 -1
- package/es/Embed/BrightcoveEmbed.mjs +2 -2
- package/es/Embed/BrightcoveEmbed.mjs.map +1 -1
- package/es/Embed/CodeEmbed.mjs +3 -4
- package/es/Embed/CodeEmbed.mjs.map +1 -1
- package/es/Embed/ConceptEmbed.mjs +2 -2
- package/es/Embed/ConceptEmbed.mjs.map +1 -1
- package/es/Embed/ConceptInlineTriggerButton.mjs.map +1 -1
- package/es/Embed/ContentLinkEmbed.mjs +1 -1
- package/es/Embed/ContentLinkEmbed.mjs.map +1 -1
- package/es/Embed/CopyrightEmbed.mjs +1 -1
- package/es/Embed/CopyrightEmbed.mjs.map +1 -1
- package/es/Embed/EmbedErrorPlaceholder.mjs +1 -1
- package/es/Embed/EmbedErrorPlaceholder.mjs.map +1 -1
- package/es/Embed/EmbedWrapper.mjs.map +1 -1
- package/es/Embed/ExternalEmbed.mjs +3 -3
- package/es/Embed/ExternalEmbed.mjs.map +1 -1
- package/es/Embed/FootnoteEmbed.mjs +1 -1
- package/es/Embed/FootnoteEmbed.mjs.map +1 -1
- package/es/Embed/GlossEmbed.mjs +2 -2
- package/es/Embed/GlossEmbed.mjs.map +1 -1
- package/es/Embed/H5pEmbed.mjs +2 -2
- package/es/Embed/H5pEmbed.mjs.map +1 -1
- package/es/Embed/IframeEmbed.mjs +3 -3
- package/es/Embed/IframeEmbed.mjs.map +1 -1
- package/es/Embed/ImageEmbed.mjs +2 -4
- package/es/Embed/ImageEmbed.mjs.map +1 -1
- package/es/Embed/InlineTriggerButton.mjs.map +1 -1
- package/es/Embed/RelatedContentEmbed.mjs +2 -3
- package/es/Embed/RelatedContentEmbed.mjs.map +1 -1
- package/es/Embed/UnknownEmbed.mjs +1 -1
- package/es/Embed/UnknownEmbed.mjs.map +1 -1
- package/es/Embed/UuDisclaimerEmbed.mjs +1 -1
- package/es/Embed/UuDisclaimerEmbed.mjs.map +1 -1
- package/es/FactBox/FactBox.mjs +1 -1
- package/es/FactBox/FactBox.mjs.map +1 -1
- package/es/FileList/File.mjs +34 -30
- package/es/FileList/File.mjs.map +1 -1
- package/es/FileList/FileList.mjs.map +1 -1
- package/es/FileList/PdfFile.mjs.map +1 -1
- package/es/Gloss/Gloss.mjs +5 -7
- package/es/Gloss/Gloss.mjs.map +1 -1
- package/es/Gloss/GlossExample.mjs +1 -1
- package/es/Gloss/GlossExample.mjs.map +1 -1
- package/es/Grid/Grid.mjs.map +1 -1
- package/es/Grid/GridParallaxItem.mjs.map +1 -1
- package/es/KeyFigure/KeyFigure.mjs +1 -1
- package/es/KeyFigure/KeyFigure.mjs.map +1 -1
- package/es/LicenseByline/EmbedByline.mjs +1 -2
- package/es/LicenseByline/EmbedByline.mjs.map +1 -1
- package/es/LicenseByline/LicenseLink.mjs.map +1 -1
- package/es/LinkBlock/LinkBlock.mjs +1 -1
- package/es/LinkBlock/LinkBlock.mjs.map +1 -1
- package/es/LinkBlock/LinkBlockSection.mjs +1 -1
- package/es/LinkBlock/LinkBlockSection.mjs.map +1 -1
- package/es/Pitch/Pitch.mjs.map +1 -1
- package/es/RelatedArticleList/RelatedArticleList.mjs.map +1 -1
- package/es/ResourceBox/ResourceBox.mjs +1 -1
- package/es/ResourceBox/ResourceBox.mjs.map +1 -1
- package/es/TagSelector/TagSelector.mjs.map +1 -1
- package/es/ZendeskButton/ZendeskButton.mjs.map +1 -1
- package/es/_virtual/rolldown_runtime.mjs +3 -1
- package/es/i18n/formatNestedMessages.mjs.map +1 -1
- package/es/i18n/useComponentTranslations.mjs +1 -2
- package/es/i18n/useComponentTranslations.mjs.map +1 -1
- package/es/index.mjs +34 -38
- package/es/locale/messages-en.mjs +2 -2
- package/es/locale/messages-en.mjs.map +1 -1
- package/es/locale/messages-nb.mjs +2 -2
- package/es/locale/messages-nb.mjs.map +1 -1
- package/es/locale/messages-nn.mjs +2 -2
- package/es/locale/messages-nn.mjs.map +1 -1
- package/es/locale/messages-se.mjs +2 -2
- package/es/locale/messages-se.mjs.map +1 -1
- package/es/model/ContentType.mjs.map +1 -1
- package/es/model/SubjectCategories.mjs +1 -2
- package/es/model/SubjectCategories.mjs.map +1 -1
- package/es/model/SubjectTypes.mjs +1 -2
- package/es/model/SubjectTypes.mjs.map +1 -1
- package/es/model/WordClass.mjs +1 -2
- package/es/model/WordClass.mjs.map +1 -1
- package/es/model/index.mjs +1 -1
- package/es/model/index.mjs.map +1 -1
- package/es/utils/licenseAttributes.mjs +1 -2
- package/es/utils/licenseAttributes.mjs.map +1 -1
- package/es/utils/relativeUrl.mjs.map +1 -1
- package/lib/Article/Article.js +24 -20
- package/lib/Article/Article.js.map +1 -1
- package/lib/Article/ArticleByline.js +18 -10
- package/lib/Article/ArticleByline.js.map +1 -1
- package/lib/Article/ArticleFootNotes.js +6 -3
- package/lib/Article/ArticleFootNotes.js.map +1 -1
- package/lib/AudioPlayer/AudioPlayer.js +17 -11
- package/lib/AudioPlayer/AudioPlayer.js.map +1 -1
- package/lib/AudioPlayer/Controls.js +15 -8
- package/lib/AudioPlayer/Controls.js.map +1 -1
- package/lib/AudioPlayer/SpeechControl.js +11 -6
- package/lib/AudioPlayer/SpeechControl.js.map +1 -1
- package/lib/Breadcrumb/Breadcrumb.d.ts +3 -5
- package/lib/Breadcrumb/Breadcrumb.js +12 -13
- package/lib/Breadcrumb/Breadcrumb.js.map +1 -1
- package/lib/Breadcrumb/BreadcrumbItem.d.ts +3 -3
- package/lib/Breadcrumb/BreadcrumbItem.js +11 -19
- package/lib/Breadcrumb/BreadcrumbItem.js.map +1 -1
- package/lib/Breadcrumb/HomeBreadcrumb.js +13 -9
- package/lib/Breadcrumb/HomeBreadcrumb.js.map +1 -1
- package/lib/CampaignBlock/CampaignBlock.js +17 -10
- package/lib/CampaignBlock/CampaignBlock.js.map +1 -1
- package/lib/CodeBlock/CodeBlock.js +9 -5
- package/lib/CodeBlock/CodeBlock.js.map +1 -1
- package/lib/CodeBlock/codeLanguageOptions.js.map +1 -1
- package/lib/Concept/Concept.js +19 -15
- package/lib/Concept/Concept.js.map +1 -1
- package/lib/ContactBlock/ContactBlock.js +10 -6
- package/lib/ContactBlock/ContactBlock.js.map +1 -1
- package/lib/ContentTypeBadge/ContentTypeBadge.js +28 -24
- package/lib/ContentTypeBadge/ContentTypeBadge.js.map +1 -1
- package/lib/CopyParagraphButton/CopyParagraphButton.js +13 -7
- package/lib/CopyParagraphButton/CopyParagraphButton.js.map +1 -1
- package/lib/Embed/AudioEmbed.js +16 -13
- package/lib/Embed/AudioEmbed.js.map +1 -1
- package/lib/Embed/BrightcoveEmbed.js +19 -13
- package/lib/Embed/BrightcoveEmbed.js.map +1 -1
- package/lib/Embed/CodeEmbed.js +19 -14
- package/lib/Embed/CodeEmbed.js.map +1 -1
- package/lib/Embed/ConceptEmbed.js +21 -15
- package/lib/Embed/ConceptEmbed.js.map +1 -1
- package/lib/Embed/ConceptInlineTriggerButton.js +4 -3
- package/lib/Embed/ConceptInlineTriggerButton.js.map +1 -1
- package/lib/Embed/ContentLinkEmbed.js +7 -4
- package/lib/Embed/ContentLinkEmbed.js.map +1 -1
- package/lib/Embed/CopyrightEmbed.js +7 -5
- package/lib/Embed/CopyrightEmbed.js.map +1 -1
- package/lib/Embed/EmbedErrorPlaceholder.js +13 -8
- package/lib/Embed/EmbedErrorPlaceholder.js.map +1 -1
- package/lib/Embed/EmbedWrapper.js +10 -5
- package/lib/Embed/EmbedWrapper.js.map +1 -1
- package/lib/Embed/ExternalEmbed.js +15 -10
- package/lib/Embed/ExternalEmbed.js.map +1 -1
- package/lib/Embed/FootnoteEmbed.js +7 -4
- package/lib/Embed/FootnoteEmbed.js.map +1 -1
- package/lib/Embed/GlossEmbed.js +17 -12
- package/lib/Embed/GlossEmbed.js.map +1 -1
- package/lib/Embed/H5pEmbed.js +11 -7
- package/lib/Embed/H5pEmbed.js.map +1 -1
- package/lib/Embed/IframeEmbed.js +15 -10
- package/lib/Embed/IframeEmbed.js.map +1 -1
- package/lib/Embed/ImageEmbed.js +21 -16
- package/lib/Embed/ImageEmbed.js.map +1 -1
- package/lib/Embed/InlineTriggerButton.js +8 -4
- package/lib/Embed/InlineTriggerButton.js.map +1 -1
- package/lib/Embed/RelatedContentEmbed.js +12 -11
- package/lib/Embed/RelatedContentEmbed.js.map +1 -1
- package/lib/Embed/UnknownEmbed.js +7 -4
- package/lib/Embed/UnknownEmbed.js.map +1 -1
- package/lib/Embed/UuDisclaimerEmbed.js +15 -8
- package/lib/Embed/UuDisclaimerEmbed.js.map +1 -1
- package/lib/FactBox/FactBox.js +13 -7
- package/lib/FactBox/FactBox.js.map +1 -1
- package/lib/FileList/File.js +51 -39
- package/lib/FileList/File.js.map +1 -1
- package/lib/FileList/FileList.js +8 -4
- package/lib/FileList/FileList.js.map +1 -1
- package/lib/FileList/PdfFile.js +6 -3
- package/lib/FileList/PdfFile.js.map +1 -1
- package/lib/Gloss/Gloss.js +23 -17
- package/lib/Gloss/Gloss.js.map +1 -1
- package/lib/Gloss/GlossExample.js +9 -5
- package/lib/Gloss/GlossExample.js.map +1 -1
- package/lib/Grid/Grid.js +6 -3
- package/lib/Grid/Grid.js.map +1 -1
- package/lib/Grid/GridParallaxItem.js +6 -3
- package/lib/Grid/GridParallaxItem.js.map +1 -1
- package/lib/KeyFigure/KeyFigure.js +7 -4
- package/lib/KeyFigure/KeyFigure.js.map +1 -1
- package/lib/LicenseByline/EmbedByline.js +17 -11
- package/lib/LicenseByline/EmbedByline.js.map +1 -1
- package/lib/LicenseByline/LicenseLink.js +8 -4
- package/lib/LicenseByline/LicenseLink.js.map +1 -1
- package/lib/LinkBlock/LinkBlock.js +17 -10
- package/lib/LinkBlock/LinkBlock.js.map +1 -1
- package/lib/LinkBlock/LinkBlockSection.js +7 -4
- package/lib/LinkBlock/LinkBlockSection.js.map +1 -1
- package/lib/Pitch/Pitch.js +14 -8
- package/lib/Pitch/Pitch.js.map +1 -1
- package/lib/RelatedArticleList/RelatedArticleList.js +20 -12
- package/lib/RelatedArticleList/RelatedArticleList.js.map +1 -1
- package/lib/ResourceBox/ResourceBox.js +14 -7
- package/lib/ResourceBox/ResourceBox.js.map +1 -1
- package/lib/TagSelector/TagSelector.js +12 -6
- package/lib/TagSelector/TagSelector.js.map +1 -1
- package/lib/ZendeskButton/ZendeskButton.js +6 -3
- package/lib/ZendeskButton/ZendeskButton.js.map +1 -1
- package/lib/_virtual/rolldown_runtime.js +5 -13
- package/lib/i18n/formatNestedMessages.js.map +1 -1
- package/lib/i18n/useComponentTranslations.js +5 -4
- package/lib/i18n/useComponentTranslations.js.map +1 -1
- package/lib/index.d.ts +51 -30
- package/lib/index.js +145 -152
- package/lib/locale/messages-en.js +5 -4
- package/lib/locale/messages-en.js.map +1 -1
- package/lib/locale/messages-nb.js +5 -4
- package/lib/locale/messages-nb.js.map +1 -1
- package/lib/locale/messages-nn.js +5 -4
- package/lib/locale/messages-nn.js.map +1 -1
- package/lib/locale/messages-se.js +5 -4
- package/lib/locale/messages-se.js.map +1 -1
- package/lib/model/ContentType.js.map +1 -1
- package/lib/model/SubjectCategories.js +1 -2
- package/lib/model/SubjectCategories.js.map +1 -1
- package/lib/model/SubjectTypes.js +1 -2
- package/lib/model/SubjectTypes.js.map +1 -1
- package/lib/model/WordClass.js +1 -2
- package/lib/model/WordClass.js.map +1 -1
- package/lib/model/index.js +11 -11
- package/lib/model/index.js.map +1 -1
- package/lib/utils/licenseAttributes.js +3 -3
- package/lib/utils/licenseAttributes.js.map +1 -1
- package/lib/utils/relativeUrl.js.map +1 -1
- package/package.json +8 -8
- package/src/Article/Article.tsx +8 -4
- package/src/Breadcrumb/Breadcrumb.stories.tsx +1 -16
- package/src/Breadcrumb/Breadcrumb.tsx +3 -16
- package/src/Breadcrumb/BreadcrumbItem.tsx +9 -28
- package/src/Breadcrumb/HomeBreadcrumb.tsx +2 -2
- package/src/Concept/Concept.tsx +5 -1
- package/src/Embed/AudioEmbed.stories.tsx +1 -1
- package/src/Embed/AudioEmbed.tsx +2 -2
- package/src/Embed/BrightcoveEmbed.stories.tsx +1 -1
- package/src/Embed/BrightcoveEmbed.tsx +1 -1
- package/src/Embed/CodeEmbed.tsx +2 -2
- package/src/Embed/ConceptEmbed.stories.tsx +1 -1
- package/src/Embed/CopyrightEmbed.tsx +1 -1
- package/src/Embed/EmbedErrorPlaceholder.tsx +1 -2
- package/src/Embed/ExternalEmbed.stories.tsx +1 -1
- package/src/Embed/ExternalEmbed.tsx +1 -1
- package/src/Embed/FootnoteEmbed.stories.tsx +1 -1
- package/src/Embed/GlossEmbed.tsx +1 -1
- package/src/Embed/H5pEmbed.stories.tsx +1 -1
- package/src/Embed/IframeEmbed.stories.tsx +1 -1
- package/src/Embed/IframeEmbed.tsx +1 -1
- package/src/Embed/ImageEmbed.stories.tsx +2 -2
- package/src/Embed/ImageEmbed.tsx +1 -1
- package/src/Embed/RelatedContentEmbed.stories.tsx +2 -2
- package/src/Embed/UuDisclaimerEmbed.stories.tsx +3 -3
- package/src/FileList/File.tsx +18 -7
- package/src/LinkBlock/LinkBlock.stories.tsx +1 -1
- package/src/Pitch/Pitch.stories.tsx +2 -2
- package/src/index.ts +53 -61
- package/es/AudioPlayer/index.mjs +0 -8
- package/es/AudioPlayer/index.mjs.map +0 -1
- package/es/Breadcrumb/index.mjs +0 -9
- package/es/Breadcrumb/index.mjs.map +0 -1
- package/es/ContentTypeBlockQuote/ContentTypeBlockQuote.mjs +0 -25
- package/es/ContentTypeBlockQuote/ContentTypeBlockQuote.mjs.map +0 -1
- package/es/ContentTypeFramedContent/ContentTypeFramedContent.mjs +0 -25
- package/es/ContentTypeFramedContent/ContentTypeFramedContent.mjs.map +0 -1
- package/es/ContentTypeHero/ContentTypeHero.mjs +0 -39
- package/es/ContentTypeHero/ContentTypeHero.mjs.map +0 -1
- package/es/CopyParagraphButton/index.mjs +0 -8
- package/es/CopyParagraphButton/index.mjs.map +0 -1
- package/es/FactBox/index.mjs +0 -8
- package/es/FactBox/index.mjs.map +0 -1
- package/es/RelatedArticleList/index.mjs +0 -8
- package/es/RelatedArticleList/index.mjs.map +0 -1
- package/lib/Article/index.d.ts +0 -10
- package/lib/AudioPlayer/index.d.ts +0 -9
- package/lib/AudioPlayer/index.js +0 -8
- package/lib/AudioPlayer/index.js.map +0 -1
- package/lib/Breadcrumb/index.d.ts +0 -11
- package/lib/Breadcrumb/index.js +0 -9
- package/lib/Breadcrumb/index.js.map +0 -1
- package/lib/CampaignBlock/index.d.ts +0 -8
- package/lib/CodeBlock/index.d.ts +0 -9
- package/lib/ContactBlock/index.d.ts +0 -9
- package/lib/ContentTypeBlockQuote/ContentTypeBlockQuote.d.ts +0 -16
- package/lib/ContentTypeBlockQuote/ContentTypeBlockQuote.js +0 -26
- package/lib/ContentTypeBlockQuote/ContentTypeBlockQuote.js.map +0 -1
- package/lib/ContentTypeFramedContent/ContentTypeFramedContent.d.ts +0 -16
- package/lib/ContentTypeFramedContent/ContentTypeFramedContent.js +0 -26
- package/lib/ContentTypeFramedContent/ContentTypeFramedContent.js.map +0 -1
- package/lib/ContentTypeHero/ContentTypeHero.d.ts +0 -14
- package/lib/ContentTypeHero/ContentTypeHero.js +0 -40
- package/lib/ContentTypeHero/ContentTypeHero.js.map +0 -1
- package/lib/ContentTypeHero/index.d.ts +0 -9
- package/lib/CopyParagraphButton/index.d.ts +0 -10
- package/lib/CopyParagraphButton/index.js +0 -8
- package/lib/CopyParagraphButton/index.js.map +0 -1
- package/lib/Embed/index.d.ts +0 -27
- package/lib/FactBox/index.d.ts +0 -9
- package/lib/FactBox/index.js +0 -8
- package/lib/FactBox/index.js.map +0 -1
- package/lib/FileList/index.d.ts +0 -10
- package/lib/Gloss/index.d.ts +0 -9
- package/lib/Grid/index.d.ts +0 -10
- package/lib/KeyFigure/index.d.ts +0 -8
- package/lib/LicenseByline/index.d.ts +0 -9
- package/lib/LinkBlock/index.d.ts +0 -9
- package/lib/Pitch/index.d.ts +0 -8
- package/lib/RelatedArticleList/index.d.ts +0 -10
- package/lib/RelatedArticleList/index.js +0 -8
- package/lib/RelatedArticleList/index.js.map +0 -1
- package/lib/ResourceBox/index.d.ts +0 -9
- package/lib/i18n/index.d.ts +0 -9
- package/src/Article/index.ts +0 -20
- package/src/AudioPlayer/index.ts +0 -11
- package/src/Breadcrumb/index.ts +0 -15
- package/src/CampaignBlock/index.ts +0 -9
- package/src/CodeBlock/index.ts +0 -10
- package/src/ContactBlock/index.ts +0 -10
- package/src/ContentTypeBlockQuote/ContentTypeBlockQuote.tsx +0 -32
- package/src/ContentTypeFramedContent/ContentTypeFramedContent.tsx +0 -34
- package/src/ContentTypeHero/ContentTypeHero.stories.tsx +0 -75
- package/src/ContentTypeHero/ContentTypeHero.tsx +0 -56
- package/src/ContentTypeHero/index.ts +0 -10
- package/src/CopyParagraphButton/index.tsx +0 -12
- package/src/Embed/index.ts +0 -28
- package/src/FactBox/index.ts +0 -11
- package/src/FileList/index.ts +0 -11
- package/src/Gloss/index.tsx +0 -10
- package/src/Grid/index.ts +0 -12
- package/src/KeyFigure/index.ts +0 -9
- package/src/LicenseByline/index.tsx +0 -10
- package/src/LinkBlock/index.ts +0 -10
- package/src/Pitch/index.ts +0 -9
- package/src/RelatedArticleList/index.ts +0 -13
- package/src/ResourceBox/index.ts +0 -11
- package/src/i18n/index.ts +0 -19
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"overflowWrap]___[value:anywhere",
|
|
22
22
|
"gap]___[value:xxlarge",
|
|
23
23
|
"paddingBlockEnd]___[value:5xlarge]___[cond:& > :is(:last-child)",
|
|
24
|
-
"
|
|
24
|
+
"justifyContent]___[value:space-between",
|
|
25
25
|
"gap]___[value:small",
|
|
26
|
+
"minHeight]___[value:xxlarge",
|
|
26
27
|
"flexWrap]___[value:wrap",
|
|
27
28
|
"marginBlockStart]___[value:medium",
|
|
28
29
|
"paddingBlockStart]___[value:xsmall",
|
|
29
30
|
"borderTop]___[value:1px solid",
|
|
30
31
|
"borderColor]___[value:stroke.subtle",
|
|
31
32
|
"gap]___[value:3xsmall",
|
|
32
|
-
"justifyContent]___[value:space-between",
|
|
33
33
|
"paddingBlock]___[value:xsmall",
|
|
34
34
|
"textStyle]___[value:body.medium",
|
|
35
35
|
"marginInlineStart]___[value:auto]___[cond:& [data-contributors=\"false\"]",
|
|
@@ -281,7 +281,6 @@
|
|
|
281
281
|
"paddingBlock]___[value:small",
|
|
282
282
|
"paddingInlineEnd]___[value:medium",
|
|
283
283
|
"paddingInlineStart]___[value:small",
|
|
284
|
-
"flexDirection]___[value:row",
|
|
285
284
|
"inset]___[value:0]___[cond:_before",
|
|
286
285
|
"zIndex]___[value:0]___[cond:_before",
|
|
287
286
|
"background]___[value:surface.infoSubtle",
|
package/dist/styles.css
CHANGED
|
@@ -356,6 +356,10 @@
|
|
|
356
356
|
overflow-wrap: anywhere;
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
+
.jc_space-between {
|
|
360
|
+
justify-content: space-between;
|
|
361
|
+
}
|
|
362
|
+
|
|
359
363
|
.flex-wrap_wrap {
|
|
360
364
|
flex-wrap: wrap;
|
|
361
365
|
}
|
|
@@ -368,10 +372,6 @@
|
|
|
368
372
|
padding-block-start: var(--spacing-xsmall);
|
|
369
373
|
}
|
|
370
374
|
|
|
371
|
-
.jc_space-between {
|
|
372
|
-
justify-content: space-between;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
375
|
.bx-sh_full {
|
|
376
376
|
box-shadow: var(--shadows-full);
|
|
377
377
|
}
|
|
@@ -567,10 +567,6 @@
|
|
|
567
567
|
padding-inline-start: var(--spacing-small);
|
|
568
568
|
}
|
|
569
569
|
|
|
570
|
-
.flex-d_row {
|
|
571
|
-
flex-direction: row;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
570
|
.font-style_italic {
|
|
575
571
|
font-style: italic;
|
|
576
572
|
}
|
|
@@ -1488,7 +1484,7 @@
|
|
|
1488
1484
|
}
|
|
1489
1485
|
|
|
1490
1486
|
@media screen and (max-width: 29.7475rem) {
|
|
1491
|
-
.mobileWideDown\:disabled\:d_none:is(:disabled, [disabled], [data-disabled], [aria-disabled=
|
|
1487
|
+
.mobileWideDown\:disabled\:d_none:is(:disabled, [disabled], [data-disabled], [aria-disabled=true]) {
|
|
1492
1488
|
display: none;
|
|
1493
1489
|
}
|
|
1494
1490
|
}
|
package/es/Article/Article.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { ContentTypeBadge } from "../ContentTypeBadge/ContentTypeBadge.mjs";
|
|
|
2
2
|
import { ArticleByline } from "./ArticleByline.mjs";
|
|
3
3
|
import { forwardRef } from "react";
|
|
4
4
|
import { Heading, Text } from "@ndla/primitives";
|
|
5
|
-
import {
|
|
5
|
+
import { styled } from "@ndla/styled-system/jsx";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { ark } from "@ark-ui/react";
|
|
8
8
|
import { cx } from "@ndla/styled-system/css";
|
|
@@ -58,7 +58,11 @@ const ArticleFooter = styled(ark.footer, { base: {
|
|
|
58
58
|
width: "100%",
|
|
59
59
|
"& > :is(:last-child)": { paddingBlockEnd: "5xlarge" }
|
|
60
60
|
} }, { baseComponent: true });
|
|
61
|
-
const
|
|
61
|
+
const InfoWrapper = styled("div", { base: {
|
|
62
|
+
display: "flex",
|
|
63
|
+
alignItems: "center",
|
|
64
|
+
justifyContent: "space-between",
|
|
65
|
+
gap: "small",
|
|
62
66
|
width: "100%",
|
|
63
67
|
minHeight: "xxlarge"
|
|
64
68
|
} });
|
|
@@ -70,16 +74,10 @@ const StyledWrapper = styled("div", { base: {
|
|
|
70
74
|
} });
|
|
71
75
|
const ArticleTitle = ({ contentType, heartButton, title, lang, id, introduction, contentTypeLabel, competenceGoals, disclaimer }) => {
|
|
72
76
|
return /* @__PURE__ */ jsxs(ArticleHeader, { children: [
|
|
73
|
-
/* @__PURE__ */ jsxs(ArticleHGroup, { children: [(!!contentType || !!heartButton) && /* @__PURE__ */ jsxs(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
gap: "small",
|
|
78
|
-
children: [!!contentType && /* @__PURE__ */ jsx(ContentTypeBadge, {
|
|
79
|
-
contentType,
|
|
80
|
-
children: contentTypeLabel
|
|
81
|
-
}), heartButton]
|
|
82
|
-
}), /* @__PURE__ */ jsx(Heading, {
|
|
77
|
+
/* @__PURE__ */ jsxs(ArticleHGroup, { children: [(!!contentType || !!heartButton) && /* @__PURE__ */ jsxs(InfoWrapper, { children: [!!contentType && /* @__PURE__ */ jsx(ContentTypeBadge, {
|
|
78
|
+
contentType,
|
|
79
|
+
children: contentTypeLabel
|
|
80
|
+
}), heartButton] }), /* @__PURE__ */ jsx(Heading, {
|
|
83
81
|
textStyle: "heading.medium",
|
|
84
82
|
id,
|
|
85
83
|
lang,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Article.mjs","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 {
|
|
1
|
+
{"version":3,"file":"Article.mjs","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 { styled } from \"@ndla/styled-system/jsx\";\nimport type { StyledProps } 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\"> & StyledProps>(\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\"> & StyledProps>((props, ref) => (\n <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 InfoWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"small\",\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 <InfoWrapper>\n {!!contentType && <ContentTypeBadge contentType={contentType}>{contentTypeLabel}</ContentTypeBadge>}\n {heartButton}\n </InfoWrapper>\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 lang={lang}\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,EAAE,EAAE,EAAE,eAAe,MAAM,CAAC;AAE7E,MAAa,iBAAiB,YAC3B,EAAE,UAAW,GAAG,SAAS,QACxB,oBAAC;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,mCACZ;CACD,QAAQ;EACN,SAAS;EACT,SAAS;EACT,OAAO;EACR;CACF,EACF,EACD,EAAE,eAAe,MAAM,CACxB;AAED,MAAa,iBAAiB,YAAyE,OAAO,QAC5G,oBAAC;CAAqB,qBAAkB;CAAQ;CAAK,GAAI;EAAS,CAClE;AAEF,MAAa,gBAAgB,OAC3B,IAAI,QACJ,EACE,MAAM;CACJ,SAAS;CACT,OAAO;CACP,eAAe;CACf,YAAY;CACZ,QAAQ,EACN,cAAc,YACf;CACF,EACF,EACD,EAAE,eAAe,MAAM,CACxB;AAED,MAAa,gBAAgB,OAC3B,IAAI,QACJ,EACE,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,YAAY;CACZ,OAAO;CACP,mBAAmB;CACnB,cAAc;CACf,EACF,EACD,EAAE,eAAe,MAAM,CACxB;AAED,MAAa,gBAAgB,OAC3B,IAAI,QACJ,EACE,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACL,OAAO;CACP,wBAAwB,EACtB,iBAAiB,WAClB;CACF,EACF,EACD,EAAE,eAAe,MAAM,CACxB;AAED,MAAM,cAAc,OAAO,OAAO,EAChC,MAAM;CACJ,SAAS;CACT,YAAY;CACZ,gBAAgB;CAChB,KAAK;CACL,OAAO;CACP,WAAW;CACZ,EACF,CAAC;AAEF,MAAM,gBAAgB,OAAO,OAAO,EAClC,MAAM;CACJ,SAAS;CACT,KAAK;CACL,UAAU;CACV,YAAY;CACb,EACF,CAAC;AAcF,MAAa,gBAAgB,EAC3B,aACA,aACA,OACA,MACA,IACA,cACA,kBACA,iBACA,iBACuB;AACvB,QACE,qBAAC;EACC,qBAAC,6BACG,CAAC,CAAC,eAAe,CAAC,CAAC,gBACnB,qBAAC,0BACE,CAAC,CAAC,eAAe,oBAAC;GAA8B;aAAc;IAAoC,EAClG,eACW,EAEhB,oBAAC;GAAQ,WAAU;GAAqB;GAAU;GAAM,UAAS;aAC9D;IACO,IACI;EACf,CAAC,CAAC,gBACD,oBAAC;GAAW;GAAM,WAAU;GAAc;GAAQ;aAChD,oBAAC,mBAAK,eAAmB;IACpB;EAET,qBAAC,4BACE,iBACA,cACa;KACF;;AAiBpB,MAAa,WAAW,EACtB,SACA,aACA,YACA,UACA,iBACA,kBACA,IACA,aACA,MACA,iBACW;CACX,MAAM,EAAE,OAAO,cAAc,WAAW,SAAS,WAAW,cAAc;CAE1E,MAAM,UACJ,WAAW,SAAS,UAAU,WAAW,cAAc,SAAS,UAAU,WAAW,WAAW;AAElG,QACE,qBAAC;EACC,oBAAC;GACK;GACS;GACA;GACN;GACO;GACG;GACX;GACY;GACN;IACZ;EACF,oBAAC,4BAAgB,UAAyB;EAC1C,qBAAC,4BACC,oBAAC;GACO;GACN,WAAW;GACF;GACT,WAAW,WAAW;GACX;GACC;IACZ,EACD,YACa;KACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArticleByline.mjs","names":[
|
|
1
|
+
{"version":3,"file":"ArticleByline.mjs","names":[],"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 ReactNode, forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useLocation } from \"react-router\";\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 { SafeLink } from \"@ndla/safelink\";\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 lang?: string;\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 learningpathCopiedFrom?: string;\n};\n\nfunction formatList(list: SupplierProps[], listFormatter: Intl.ListFormat) {\n return listFormatter.format(list.map((l) => l.name));\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 lang,\n authors = [],\n suppliers = [],\n footnotes,\n licenseBox,\n published,\n displayByline = true,\n bylineType = \"article\",\n bylineSuffix,\n learningpathCopiedFrom,\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 const listFormatter = new Intl.ListFormat(lang, { style: \"long\", type: \"conjunction\" });\n\n return (\n <Wrapper>\n {!!displayByline && (\n <TextWrapper learningpath={bylineType === \"learningPath\"}>\n {!!showPrimaryContributors && (\n <span>\n {authors.length > 0 &&\n `${t(\"article.authorsLabel\", { context: bylineType })} ${formatList(authors, listFormatter)}. `}\n {suppliers.length > 0 &&\n `${t(\"article.supplierLabel\", { count: suppliers.length })} ${formatList(suppliers, listFormatter)}.`}\n </span>\n )}\n {learningpathCopiedFrom ? (\n <SafeLink to={learningpathCopiedFrom}>{t(`learningPath.copiedFrom`)}</SafeLink>\n ) : null}\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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArticleFootNotes.mjs","names":[
|
|
1
|
+
{"version":3,"file":"ArticleFootNotes.mjs","names":[],"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,oBAAoB,gBAAqC,cAAc,GAAG,YAAY,MAAM;AAMlG,MAAM,aAAa,OAAO,QAAQ,EAChC,MAAM;CACJ,SAAS;CACT,YAAY;CACZ,KAAK;CACN,EACF,CAAC;AAEF,MAAM,YAAY,EAAE,eAClB,oBAAC,kBACC,oBAAC;CAAK,IAAI,OAAO,SAAS;CAAO;CAAQ;CAAW,WAAU;WAC5D,qBAAC;EACC,oBAAC;GAAE,MAAM,OAAO,SAAS;GAAO,QAAO;aACpC,SAAS;IACR;EACH,IAAI,SAAS,MAAM,KAAK,SAAS,QAAQ,KAAK,IAAI,CAAC,IAAI,iBAAiB,SAAS,QAAQ,GAAG,iBAC3F,SAAS,UACV,GAAG,SAAS,KAAK;EACjB,SAAS,MACR,qBAAC;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;CACZ,EACF,CAAC;AAEF,MAAa,oBAAoB,EAAE,gBACjC,oBAAC,0BACE,UAAU,KAAK,aACd,oBAAC,YAAsC,YAAxB,SAAS,IAA2B,CACnD,GACW"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import Controls_default from "./Controls.mjs";
|
|
2
|
+
import SpeechControl_default from "./SpeechControl.mjs";
|
|
3
3
|
import { useId, useMemo, useState } from "react";
|
|
4
4
|
import { Button, Heading, Text } from "@ndla/primitives";
|
|
5
5
|
import { styled } from "@ndla/styled-system/jsx";
|
|
@@ -153,5 +153,5 @@ const AudioPlayer = ({ src, title, subtitle, speech, description, img, textVersi
|
|
|
153
153
|
var AudioPlayer_default = AudioPlayer;
|
|
154
154
|
|
|
155
155
|
//#endregion
|
|
156
|
-
export { AudioPlayer_default as
|
|
156
|
+
export { AudioPlayer_default as default };
|
|
157
157
|
//# sourceMappingURL=AudioPlayer.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioPlayer.mjs","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":";;;;;;;;;;AAkBA,MAAM,qBAAqB,OAAO,OAAO,EACvC,MAAM;CACJ,QAAQ;CACR,aAAa;CACb,cAAc;CACd,WAAW;CACX,gBAAgB;CAChB,UAAU;
|
|
1
|
+
{"version":3,"file":"AudioPlayer.mjs","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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Controls.mjs","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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"}
|
|
1
|
+
{"version":3,"file":"Controls.mjs","names":["currentTime"],"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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpeechControl.mjs","names":[],"sources":["../../src/AudioPlayer/SpeechControl.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 { useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { VolumeUpFill } from \"@ndla/icons\";\nimport { IconButton } from \"@ndla/primitives\";\n\ntype Props = {\n src: string;\n title: string;\n type?: \"gloss\" | \"audio\";\n};\n\nconst SpeechControl = ({ src, title, type = \"audio\" }: Props) => {\n const { t } = useTranslation();\n const audioRef = useRef<HTMLAudioElement>(null);\n\n const togglePlay = () => {\n if (audioRef.current) {\n const audioElement = audioRef.current;\n if (audioElement.paused) {\n audioElement.play();\n } else {\n audioElement.pause();\n }\n }\n };\n return (\n <div data-embed-type=\"speech\">\n {/* eslint-disable-next-line jsx-a11y/media-has-caption */}\n <audio ref={audioRef} src={src} title={title} preload=\"metadata\" />\n <IconButton variant=\"tertiary\" aria-label={t(`${type}.play`)} title={t(`${type}.play`)} onClick={togglePlay}>\n <VolumeUpFill />\n </IconButton>\n </div>\n );\n};\n\nexport default SpeechControl;\n"],"mappings":";;;;;;;AAmBA,MAAM,
|
|
1
|
+
{"version":3,"file":"SpeechControl.mjs","names":[],"sources":["../../src/AudioPlayer/SpeechControl.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 { useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { VolumeUpFill } from \"@ndla/icons\";\nimport { IconButton } from \"@ndla/primitives\";\n\ntype Props = {\n src: string;\n title: string;\n type?: \"gloss\" | \"audio\";\n};\n\nconst SpeechControl = ({ src, title, type = \"audio\" }: Props) => {\n const { t } = useTranslation();\n const audioRef = useRef<HTMLAudioElement>(null);\n\n const togglePlay = () => {\n if (audioRef.current) {\n const audioElement = audioRef.current;\n if (audioElement.paused) {\n audioElement.play();\n } else {\n audioElement.pause();\n }\n }\n };\n return (\n <div data-embed-type=\"speech\">\n {/* eslint-disable-next-line jsx-a11y/media-has-caption */}\n <audio ref={audioRef} src={src} title={title} preload=\"metadata\" />\n <IconButton variant=\"tertiary\" aria-label={t(`${type}.play`)} title={t(`${type}.play`)} onClick={togglePlay}>\n <VolumeUpFill />\n </IconButton>\n </div>\n );\n};\n\nexport default SpeechControl;\n"],"mappings":";;;;;;;AAmBA,MAAM,iBAAiB,EAAE,KAAK,OAAO,OAAO,cAAqB;CAC/D,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,WAAW,OAAyB,KAAK;CAE/C,MAAM,mBAAmB;AACvB,MAAI,SAAS,SAAS;GACpB,MAAM,eAAe,SAAS;AAC9B,OAAI,aAAa,OACf,cAAa,MAAM;OAEnB,cAAa,OAAO;;;AAI1B,QACE,qBAAC;EAAI,mBAAgB;aAEnB,oBAAC;GAAM,KAAK;GAAe;GAAY;GAAO,SAAQ;IAAa,EACnE,oBAAC;GAAW,SAAQ;GAAW,cAAY,EAAE,GAAG,KAAK,OAAO;GAAE,OAAO,EAAE,GAAG,KAAK,OAAO;GAAE,SAAS;aAC/F,oBAAC,iBAAe;IACL;GACT;;AAIV,4BAAe"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BreadcrumbItem_default from "./BreadcrumbItem.mjs";
|
|
2
2
|
import "react";
|
|
3
3
|
import { styled } from "@ndla/styled-system/jsx";
|
|
4
4
|
import { useTranslation } from "react-i18next";
|
|
@@ -17,18 +17,13 @@ const StyledList = styled("ol", { base: {
|
|
|
17
17
|
flexDirection: "column"
|
|
18
18
|
}
|
|
19
19
|
} });
|
|
20
|
-
const Breadcrumb = ({ items, renderItem, renderSeparator
|
|
20
|
+
const Breadcrumb = ({ items, renderItem, renderSeparator }) => {
|
|
21
21
|
const { t } = useTranslation();
|
|
22
22
|
return /* @__PURE__ */ jsx("nav", {
|
|
23
23
|
"aria-label": t("breadcrumb.breadcrumb"),
|
|
24
24
|
children: /* @__PURE__ */ jsx(StyledList, { children: items.map((item, index) => /* @__PURE__ */ jsx(BreadcrumbItem_default, {
|
|
25
25
|
renderItem,
|
|
26
26
|
renderSeparator,
|
|
27
|
-
ref: (element) => {
|
|
28
|
-
if (element === null || !collapseFirst && index === 0 || !collapseLast && index === items.length - 1) {
|
|
29
|
-
if (element) element.setMaxWidth("none");
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
27
|
totalCount: items.length,
|
|
33
28
|
item: {
|
|
34
29
|
...item,
|
|
@@ -40,5 +35,5 @@ const Breadcrumb = ({ items, renderItem, renderSeparator, collapseFirst, collaps
|
|
|
40
35
|
var Breadcrumb_default = Breadcrumb;
|
|
41
36
|
|
|
42
37
|
//#endregion
|
|
43
|
-
export { Breadcrumb_default as
|
|
38
|
+
export { Breadcrumb_default as default };
|
|
44
39
|
//# sourceMappingURL=Breadcrumb.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumb.mjs","names":["BreadcrumbItem"],"sources":["../../src/Breadcrumb/Breadcrumb.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 ReactNode } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport BreadcrumbItem, { type IndexedBreadcrumbItem, type SimpleBreadcrumbItem } from \"./BreadcrumbItem\";\n\ninterface Props {\n items: SimpleBreadcrumbItem[];\n
|
|
1
|
+
{"version":3,"file":"Breadcrumb.mjs","names":["BreadcrumbItem"],"sources":["../../src/Breadcrumb/Breadcrumb.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 ReactNode } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport BreadcrumbItem, { type IndexedBreadcrumbItem, type SimpleBreadcrumbItem } from \"./BreadcrumbItem\";\n\ninterface Props {\n items: SimpleBreadcrumbItem[];\n renderItem: (item: IndexedBreadcrumbItem, totalCount: number) => ReactNode;\n renderSeparator: (item: IndexedBreadcrumbItem, totalCount: number) => ReactNode;\n}\n\nconst StyledList = styled(\"ol\", {\n base: {\n display: \"flex\",\n flexWrap: \"wrap\",\n alignItems: \"center\",\n listStyle: \"none\",\n gap: \"xxsmall\",\n mobileDown: {\n alignItems: \"flex-start\",\n justifyContent: \"center\",\n flexDirection: \"column\",\n },\n },\n});\n\nconst Breadcrumb = ({ items, renderItem, renderSeparator }: Props) => {\n const { t } = useTranslation();\n\n return (\n <nav aria-label={t(\"breadcrumb.breadcrumb\")}>\n <StyledList>\n {items.map((item, index) => (\n <BreadcrumbItem\n renderItem={renderItem}\n renderSeparator={renderSeparator}\n key={typeof item.to === \"string\" ? item.to : item.to.pathname}\n totalCount={items.length}\n item={{ ...item, index }}\n />\n ))}\n </StyledList>\n </nav>\n );\n};\n\nexport default Breadcrumb;\n"],"mappings":";;;;;;;AAmBA,MAAM,aAAa,OAAO,MAAM,EAC9B,MAAM;CACJ,SAAS;CACT,UAAU;CACV,YAAY;CACZ,WAAW;CACX,KAAK;CACL,YAAY;EACV,YAAY;EACZ,gBAAgB;EAChB,eAAe;EAChB;CACF,EACF,CAAC;AAEF,MAAM,cAAc,EAAE,OAAO,YAAY,sBAA6B;CACpE,MAAM,EAAE,MAAM,gBAAgB;AAE9B,QACE,oBAAC;EAAI,cAAY,EAAE,wBAAwB;YACzC,oBAAC,wBACE,MAAM,KAAK,MAAM,UAChB,oBAACA;GACa;GACK;GAEjB,YAAY,MAAM;GAClB,MAAM;IAAE,GAAG;IAAM;IAAO;KAFnB,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK,KAAK,GAAG,SAGrD,CACF,GACS;GACT;;AAIV,yBAAe"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "react";
|
|
2
2
|
import { styled } from "@ndla/styled-system/jsx";
|
|
3
|
-
import {
|
|
4
|
-
import { SafeLink } from "@ndla/safelink";
|
|
5
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { jsxs } from "react/jsx-runtime";
|
|
6
4
|
|
|
7
5
|
//#region src/Breadcrumb/BreadcrumbItem.tsx
|
|
8
6
|
const StyledListItem = styled("li", { base: {
|
|
@@ -13,24 +11,15 @@ const StyledListItem = styled("li", { base: {
|
|
|
13
11
|
tabletDown: { display: "block" },
|
|
14
12
|
"& a": { _visited: { color: "inherit" } }
|
|
15
13
|
} });
|
|
16
|
-
const BreadcrumbItem =
|
|
17
|
-
const
|
|
18
|
-
useImperativeHandle(ref, () => ({ setMaxWidth: (maxWidth) => {
|
|
19
|
-
liRef.current.children[0].style.maxWidth = maxWidth;
|
|
20
|
-
} }));
|
|
21
|
-
const { to, name, index } = item;
|
|
22
|
-
const isLast = index === totalCount - 1;
|
|
14
|
+
const BreadcrumbItem = ({ renderItem, renderSeparator, item, totalCount }) => {
|
|
15
|
+
const isLast = item.index === totalCount - 1;
|
|
23
16
|
return /* @__PURE__ */ jsxs(StyledListItem, {
|
|
24
|
-
ref: liRef,
|
|
25
17
|
"aria-current": isLast ? "page" : void 0,
|
|
26
|
-
children: [renderItem
|
|
27
|
-
to,
|
|
28
|
-
children: /* @__PURE__ */ jsx("span", { children: name })
|
|
29
|
-
}), renderSeparator ? renderSeparator(item, totalCount) : !isLast && /* @__PURE__ */ jsx(ArrowRightShortLine, {})]
|
|
18
|
+
children: [renderItem(item, totalCount), renderSeparator(item, totalCount)]
|
|
30
19
|
});
|
|
31
|
-
}
|
|
20
|
+
};
|
|
32
21
|
var BreadcrumbItem_default = BreadcrumbItem;
|
|
33
22
|
|
|
34
23
|
//#endregion
|
|
35
|
-
export { BreadcrumbItem_default };
|
|
24
|
+
export { BreadcrumbItem_default as default };
|
|
36
25
|
//# sourceMappingURL=BreadcrumbItem.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BreadcrumbItem.mjs","names":[
|
|
1
|
+
{"version":3,"file":"BreadcrumbItem.mjs","names":[],"sources":["../../src/Breadcrumb/BreadcrumbItem.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 ReactNode } from \"react\";\nimport { styled } from \"@ndla/styled-system/jsx\";\n\nexport interface SimpleBreadcrumbItem {\n to: string | Partial<Location>;\n name: ReactNode;\n}\n\nexport interface IndexedBreadcrumbItem extends SimpleBreadcrumbItem {\n index: number;\n}\n\nexport interface BreadcrumbRenderProps {\n item: IndexedBreadcrumbItem;\n totalCount: number;\n}\n\nconst StyledListItem = styled(\"li\", {\n base: {\n display: \"flex\",\n color: \"inherit\",\n gap: \"3xsmall\",\n alignItems: \"flex-end\",\n tabletDown: {\n display: \"block\",\n },\n \"& a\": {\n _visited: {\n color: \"inherit\",\n },\n },\n },\n});\n\ninterface Props {\n item: IndexedBreadcrumbItem;\n autoCollapse?: boolean;\n totalCount: number;\n renderItem: (item: IndexedBreadcrumbItem, totalCount: number) => ReactNode;\n renderSeparator: (item: IndexedBreadcrumbItem, totalCount: number) => ReactNode;\n}\n\nconst BreadcrumbItem = ({ renderItem, renderSeparator, item, totalCount }: Props) => {\n const isLast = item.index === totalCount - 1;\n return (\n <StyledListItem aria-current={isLast ? \"page\" : undefined}>\n {renderItem(item, totalCount)}\n {renderSeparator(item, totalCount)}\n </StyledListItem>\n );\n};\n\nexport default BreadcrumbItem;\n"],"mappings":";;;;;AAyBA,MAAM,iBAAiB,OAAO,MAAM,EAClC,MAAM;CACJ,SAAS;CACT,OAAO;CACP,KAAK;CACL,YAAY;CACZ,YAAY,EACV,SAAS,SACV;CACD,OAAO,EACL,UAAU,EACR,OAAO,WACR,EACF;CACF,EACF,CAAC;AAUF,MAAM,kBAAkB,EAAE,YAAY,iBAAiB,MAAM,iBAAwB;CACnF,MAAM,SAAS,KAAK,UAAU,aAAa;AAC3C,QACE,qBAAC;EAAe,gBAAc,SAAS,SAAS;aAC7C,WAAW,MAAM,WAAW,EAC5B,gBAAgB,MAAM,WAAW;GACnB;;AAIrB,6BAAe"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Breadcrumb_default from "./Breadcrumb.mjs";
|
|
2
2
|
import { styled } from "@ndla/styled-system/jsx";
|
|
3
3
|
import { ArrowRightShortLine, HomeLine } from "@ndla/icons";
|
|
4
4
|
import { SafeLink } from "@ndla/safelink";
|
|
@@ -28,8 +28,8 @@ const HomeBreadcrumb = ({ items }) => {
|
|
|
28
28
|
};
|
|
29
29
|
const renderSeparator = (item, totalCount) => {
|
|
30
30
|
if (item.index === totalCount - 1) return null;
|
|
31
|
-
if (item.index === 0) return /* @__PURE__ */ jsx(StyledArrowRight, {});
|
|
32
|
-
return /* @__PURE__ */ jsx(ArrowRightShortLine, {});
|
|
31
|
+
if (item.index === 0) return /* @__PURE__ */ jsx(StyledArrowRight, { "aria-hidden": true });
|
|
32
|
+
return /* @__PURE__ */ jsx(ArrowRightShortLine, { "aria-hidden": true });
|
|
33
33
|
};
|
|
34
34
|
return /* @__PURE__ */ jsx(Breadcrumb_default, {
|
|
35
35
|
items,
|
|
@@ -40,5 +40,5 @@ const HomeBreadcrumb = ({ items }) => {
|
|
|
40
40
|
var HomeBreadcrumb_default = HomeBreadcrumb;
|
|
41
41
|
|
|
42
42
|
//#endregion
|
|
43
|
-
export { HomeBreadcrumb_default };
|
|
43
|
+
export { HomeBreadcrumb_default as default };
|
|
44
44
|
//# sourceMappingURL=HomeBreadcrumb.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HomeBreadcrumb.mjs","names":["
|
|
1
|
+
{"version":3,"file":"HomeBreadcrumb.mjs","names":["Breadcrumb"],"sources":["../../src/Breadcrumb/HomeBreadcrumb.tsx"],"sourcesContent":["/**\n * Copyright (c) 2022-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 { ArrowRightShortLine, HomeLine } from \"@ndla/icons\";\nimport { SafeLink } from \"@ndla/safelink\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport Breadcrumb from \"./Breadcrumb\";\nimport type { IndexedBreadcrumbItem, SimpleBreadcrumbItem } from \"./BreadcrumbItem\";\n\nconst StyledSafeLink = styled(SafeLink, {\n base: {\n color: \"inherit\",\n textDecoration: \"underline\",\n _hover: {\n textDecoration: \"none\",\n },\n _focusVisible: {\n textDecoration: \"none\",\n },\n },\n});\n\nconst StyledArrowRight = styled(ArrowRightShortLine, {\n base: {\n tabletDown: {\n display: \"none\",\n },\n },\n});\n\nconst IconSafeLink = styled(SafeLink, {\n base: {\n color: \"inherit\",\n },\n});\n\ninterface Props {\n items: SimpleBreadcrumbItem[];\n}\n\nconst HomeBreadcrumb = ({ items }: Props) => {\n const renderItem = (item: IndexedBreadcrumbItem, totalCount: number) => {\n if (item.index === totalCount - 1) {\n return <span>{item.name}</span>;\n }\n if (item.index === 0 && typeof item.name === \"string\") {\n return (\n <IconSafeLink aria-label={item.name} to={item.to}>\n <HomeLine title={item.name} />\n </IconSafeLink>\n );\n }\n return <StyledSafeLink to={item.to}>{item.name}</StyledSafeLink>;\n };\n\n const renderSeparator = (item: IndexedBreadcrumbItem, totalCount: number) => {\n if (item.index === totalCount - 1) {\n return null;\n }\n if (item.index === 0) {\n return <StyledArrowRight aria-hidden />;\n }\n return <ArrowRightShortLine aria-hidden />;\n };\n\n return <Breadcrumb items={items} renderItem={renderItem} renderSeparator={renderSeparator} />;\n};\n\nexport default HomeBreadcrumb;\n"],"mappings":";;;;;;;AAcA,MAAM,iBAAiB,OAAO,UAAU,EACtC,MAAM;CACJ,OAAO;CACP,gBAAgB;CAChB,QAAQ,EACN,gBAAgB,QACjB;CACD,eAAe,EACb,gBAAgB,QACjB;CACF,EACF,CAAC;AAEF,MAAM,mBAAmB,OAAO,qBAAqB,EACnD,MAAM,EACJ,YAAY,EACV,SAAS,QACV,EACF,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,UAAU,EACpC,MAAM,EACJ,OAAO,WACR,EACF,CAAC;AAMF,MAAM,kBAAkB,EAAE,YAAmB;CAC3C,MAAM,cAAc,MAA6B,eAAuB;AACtE,MAAI,KAAK,UAAU,aAAa,EAC9B,QAAO,oBAAC,oBAAM,KAAK,OAAY;AAEjC,MAAI,KAAK,UAAU,KAAK,OAAO,KAAK,SAAS,SAC3C,QACE,oBAAC;GAAa,cAAY,KAAK;GAAM,IAAI,KAAK;aAC5C,oBAAC,YAAS,OAAO,KAAK,OAAQ;IACjB;AAGnB,SAAO,oBAAC;GAAe,IAAI,KAAK;aAAK,KAAK;IAAsB;;CAGlE,MAAM,mBAAmB,MAA6B,eAAuB;AAC3E,MAAI,KAAK,UAAU,aAAa,EAC9B,QAAO;AAET,MAAI,KAAK,UAAU,EACjB,QAAO,oBAAC,oBAAiB,sBAAc;AAEzC,SAAO,oBAAC,uBAAoB,sBAAc;;AAG5C,QAAO,oBAACA;EAAkB;EAAmB;EAA6B;GAAmB;;AAG/F,6BAAe"}
|
|
@@ -127,5 +127,5 @@ const CampaignBlock = ({ title, image, imageSide = "left", description, headingL
|
|
|
127
127
|
var CampaignBlock_default = CampaignBlock;
|
|
128
128
|
|
|
129
129
|
//#endregion
|
|
130
|
-
export { CampaignBlock_default };
|
|
130
|
+
export { CampaignBlock_default as default };
|
|
131
131
|
//# sourceMappingURL=CampaignBlock.mjs.map
|