@ndla/ui 56.0.185-alpha.0 → 56.0.187-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 (113) hide show
  1. package/dist/panda.buildinfo.json +20 -27
  2. package/dist/styles.css +61 -140
  3. package/es/Article/ArticleByline.mjs +2 -1
  4. package/es/Article/ArticleByline.mjs.map +1 -1
  5. package/es/AudioPlayer/AudioElement.mjs +12 -0
  6. package/es/AudioPlayer/AudioElement.mjs.map +1 -0
  7. package/es/AudioPlayer/AudioPlayer.mjs +7 -2
  8. package/es/AudioPlayer/AudioPlayer.mjs.map +1 -1
  9. package/es/AudioPlayer/AudioProgress.mjs +54 -0
  10. package/es/AudioPlayer/AudioProgress.mjs.map +1 -0
  11. package/es/AudioPlayer/CompactAudioPlayer.mjs +111 -0
  12. package/es/AudioPlayer/CompactAudioPlayer.mjs.map +1 -0
  13. package/es/AudioPlayer/Controls.mjs +25 -110
  14. package/es/AudioPlayer/Controls.mjs.map +1 -1
  15. package/es/AudioPlayer/PlayButton.mjs +24 -0
  16. package/es/AudioPlayer/PlayButton.mjs.map +1 -0
  17. package/es/AudioPlayer/SpeechControl.mjs +5 -16
  18. package/es/AudioPlayer/SpeechControl.mjs.map +1 -1
  19. package/es/AudioPlayer/VolumeSlider.mjs +31 -0
  20. package/es/AudioPlayer/VolumeSlider.mjs.map +1 -0
  21. package/es/AudioPlayer/audioUtils.mjs +17 -0
  22. package/es/AudioPlayer/audioUtils.mjs.map +1 -0
  23. package/es/AudioPlayer/useAudioControls.mjs +55 -0
  24. package/es/AudioPlayer/useAudioControls.mjs.map +1 -0
  25. package/es/Breadcrumb/BreadcrumbItem.mjs +1 -2
  26. package/es/Breadcrumb/BreadcrumbItem.mjs.map +1 -1
  27. package/es/Embed/AudioEmbed.mjs +3 -7
  28. package/es/Embed/AudioEmbed.mjs.map +1 -1
  29. package/es/Embed/ExternalEmbed.mjs +13 -16
  30. package/es/Embed/ExternalEmbed.mjs.map +1 -1
  31. package/es/Embed/IframeEmbed.mjs +4 -5
  32. package/es/Embed/IframeEmbed.mjs.map +1 -1
  33. package/es/FactBox/FactBox.mjs +14 -38
  34. package/es/FactBox/FactBox.mjs.map +1 -1
  35. package/es/Gloss/Gloss.mjs +1 -2
  36. package/es/Gloss/Gloss.mjs.map +1 -1
  37. package/es/Grid/Grid.mjs +1 -2
  38. package/es/Grid/Grid.mjs.map +1 -1
  39. package/es/LinkBlock/LinkBlock.mjs +9 -2
  40. package/es/LinkBlock/LinkBlock.mjs.map +1 -1
  41. package/es/Pitch/Pitch.mjs +1 -2
  42. package/es/Pitch/Pitch.mjs.map +1 -1
  43. package/es/index.mjs +2 -1
  44. package/lib/Article/ArticleByline.js +2 -1
  45. package/lib/Article/ArticleByline.js.map +1 -1
  46. package/lib/AudioPlayer/AudioElement.d.ts +14 -0
  47. package/lib/AudioPlayer/AudioElement.js +13 -0
  48. package/lib/AudioPlayer/AudioElement.js.map +1 -0
  49. package/lib/AudioPlayer/AudioPlayer.d.ts +5 -4
  50. package/lib/AudioPlayer/AudioPlayer.js +7 -2
  51. package/lib/AudioPlayer/AudioPlayer.js.map +1 -1
  52. package/lib/AudioPlayer/AudioProgress.d.ts +16 -0
  53. package/lib/AudioPlayer/AudioProgress.js +55 -0
  54. package/lib/AudioPlayer/AudioProgress.js.map +1 -0
  55. package/lib/AudioPlayer/CompactAudioPlayer.d.ts +13 -0
  56. package/lib/AudioPlayer/CompactAudioPlayer.js +112 -0
  57. package/lib/AudioPlayer/CompactAudioPlayer.js.map +1 -0
  58. package/lib/AudioPlayer/Controls.d.ts +1 -0
  59. package/lib/AudioPlayer/Controls.js +25 -110
  60. package/lib/AudioPlayer/Controls.js.map +1 -1
  61. package/lib/AudioPlayer/PlayButton.d.ts +13 -0
  62. package/lib/AudioPlayer/PlayButton.js +25 -0
  63. package/lib/AudioPlayer/PlayButton.js.map +1 -0
  64. package/lib/AudioPlayer/SpeechControl.d.ts +1 -2
  65. package/lib/AudioPlayer/SpeechControl.js +5 -16
  66. package/lib/AudioPlayer/SpeechControl.js.map +1 -1
  67. package/lib/AudioPlayer/VolumeSlider.d.ts +14 -0
  68. package/lib/AudioPlayer/VolumeSlider.js +32 -0
  69. package/lib/AudioPlayer/VolumeSlider.js.map +1 -0
  70. package/lib/AudioPlayer/audioUtils.d.ts +8 -0
  71. package/lib/AudioPlayer/audioUtils.js +17 -0
  72. package/lib/AudioPlayer/audioUtils.js.map +1 -0
  73. package/lib/AudioPlayer/useAudioControls.d.ts +24 -0
  74. package/lib/AudioPlayer/useAudioControls.js +56 -0
  75. package/lib/AudioPlayer/useAudioControls.js.map +1 -0
  76. package/lib/Breadcrumb/BreadcrumbItem.js +1 -2
  77. package/lib/Breadcrumb/BreadcrumbItem.js.map +1 -1
  78. package/lib/Embed/AudioEmbed.js +3 -7
  79. package/lib/Embed/AudioEmbed.js.map +1 -1
  80. package/lib/Embed/ExternalEmbed.js +13 -16
  81. package/lib/Embed/ExternalEmbed.js.map +1 -1
  82. package/lib/Embed/IframeEmbed.js +4 -5
  83. package/lib/Embed/IframeEmbed.js.map +1 -1
  84. package/lib/FactBox/FactBox.js +13 -37
  85. package/lib/FactBox/FactBox.js.map +1 -1
  86. package/lib/Gloss/Gloss.js +1 -2
  87. package/lib/Gloss/Gloss.js.map +1 -1
  88. package/lib/Grid/Grid.js +1 -2
  89. package/lib/Grid/Grid.js.map +1 -1
  90. package/lib/LinkBlock/LinkBlock.js +9 -2
  91. package/lib/LinkBlock/LinkBlock.js.map +1 -1
  92. package/lib/Pitch/Pitch.js +1 -2
  93. package/lib/Pitch/Pitch.js.map +1 -1
  94. package/lib/index.d.ts +2 -0
  95. package/lib/index.js +2 -0
  96. package/package.json +10 -10
  97. package/src/Article/ArticleByline.tsx +5 -1
  98. package/src/AudioPlayer/AudioElement.tsx +20 -0
  99. package/src/AudioPlayer/{AudiPlayer.stories.tsx → AudioPlayer.stories.tsx} +10 -1
  100. package/src/AudioPlayer/AudioPlayer.tsx +12 -5
  101. package/src/AudioPlayer/AudioProgress.tsx +92 -0
  102. package/src/AudioPlayer/CompactAudioPlayer.tsx +124 -0
  103. package/src/AudioPlayer/Controls.tsx +36 -149
  104. package/src/AudioPlayer/PlayButton.tsx +24 -0
  105. package/src/AudioPlayer/SpeechControl.tsx +6 -19
  106. package/src/AudioPlayer/VolumeSlider.tsx +56 -0
  107. package/src/AudioPlayer/audioUtils.ts +15 -0
  108. package/src/AudioPlayer/useAudioControls.ts +80 -0
  109. package/src/Embed/AudioEmbed.tsx +3 -4
  110. package/src/FactBox/FactBox.tsx +13 -43
  111. package/src/Gloss/Gloss.tsx +1 -1
  112. package/src/LinkBlock/LinkBlock.tsx +5 -2
  113. package/src/index.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"AudioEmbed.mjs","names":[],"sources":["../../src/Embed/AudioEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { AudioMetaData } from \"@ndla/types-embed\";\nimport { AudioPlayer } from \"../AudioPlayer/AudioPlayer\";\nimport { EmbedByline } from \"../LicenseByline/EmbedByline\";\nimport { licenseAttributes } from \"../utils/licenseAttributes\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport type { Author } from \"./ImageEmbed\";\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n },\n});\n\ninterface Props {\n embed: AudioMetaData;\n lang?: string;\n}\n\nexport const getFirstNonEmptyLicenseCredits = (authors: {\n creators: Author[];\n rightsholders: Author[];\n processors: Author[];\n}) => Object.values(authors).find((i) => i.length > 0) ?? [];\n\nexport const AudioEmbed = ({ embed, lang }: Props) => {\n const type = embed.embedData.type === \"standard\" ? \"audio\" : \"podcast\";\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type={type} />;\n }\n\n const { data, embedData } = embed;\n\n if (embedData.type === \"minimal\") {\n return <AudioPlayer speech src={data.audioFile.url} title={data.title.title} />;\n }\n\n const subtitle = data.series ? { title: data.series.title.title, url: `/podkast/${data.series.id}` } : undefined;\n\n const coverPhoto = data.podcastMeta?.coverPhoto;\n\n const img = coverPhoto && { url: coverPhoto.url, alt: coverPhoto.altText };\n\n const licenseProps = licenseAttributes(data.copyright.license.license, lang, embedData.url);\n\n return (\n <StyledFigure lang={lang} data-embed-type={type} {...licenseProps}>\n <AudioPlayer\n description={data.podcastMeta?.introduction ?? \"\"}\n img={img}\n src={data.audioFile.url}\n textVersion={\n data.manuscript?.manuscript.length ? (\n <div dangerouslySetInnerHTML={{ __html: data.manuscript.manuscript }} />\n ) : undefined\n }\n title={data.title.title}\n subtitle={subtitle}\n />\n <EmbedByline\n error={false}\n type={data.audioType === \"standard\" ? \"audio\" : \"podcast\"}\n copyright={embed.data.copyright}\n />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAiBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,OAAO,QACR,EACF,CAAC;AAaF,MAAa,cAAc,EAAE,OAAO,WAAkB;CACpD,MAAM,OAAO,MAAM,UAAU,SAAS,aAAa,UAAU;AAC7D,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,uBAAD,EAA6B,MAAQ,CAAA;CAG9C,MAAM,EAAE,MAAM,cAAc;AAE5B,KAAI,UAAU,SAAS,UACrB,QAAO,oBAAC,aAAD;EAAa,QAAA;EAAO,KAAK,KAAK,UAAU;EAAK,OAAO,KAAK,MAAM;EAAS,CAAA;CAGjF,MAAM,WAAW,KAAK,SAAS;EAAE,OAAO,KAAK,OAAO,MAAM;EAAO,KAAK,YAAY,KAAK,OAAO;EAAM,GAAG,KAAA;CAEvG,MAAM,aAAa,KAAK,aAAa;CAErC,MAAM,MAAM,cAAc;EAAE,KAAK,WAAW;EAAK,KAAK,WAAW;EAAS;CAE1E,MAAM,eAAe,kBAAkB,KAAK,UAAU,QAAQ,SAAS,MAAM,UAAU,IAAI;AAE3F,QACE,qBAAC,cAAD;EAAoB;EAAM,mBAAiB;EAAM,GAAI;YAArD,CACE,oBAAC,aAAD;GACE,aAAa,KAAK,aAAa,gBAAgB;GAC1C;GACL,KAAK,KAAK,UAAU;GACpB,aACE,KAAK,YAAY,WAAW,SAC1B,oBAAC,OAAD,EAAK,yBAAyB,EAAE,QAAQ,KAAK,WAAW,YAAY,EAAI,CAAA,GACtE,KAAA;GAEN,OAAO,KAAK,MAAM;GACR;GACV,CAAA,EACF,oBAAC,aAAD;GACE,OAAO;GACP,MAAM,KAAK,cAAc,aAAa,UAAU;GAChD,WAAW,MAAM,KAAK;GACtB,CAAA,CACW"}
1
+ {"version":3,"file":"AudioEmbed.mjs","names":[],"sources":["../../src/Embed/AudioEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { AudioMetaData } from \"@ndla/types-embed\";\nimport { AudioPlayer, type AudioPlayerVariant } from \"../AudioPlayer/AudioPlayer\";\nimport { EmbedByline } from \"../LicenseByline/EmbedByline\";\nimport { licenseAttributes } from \"../utils/licenseAttributes\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\nimport type { Author } from \"./ImageEmbed\";\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n },\n});\n\ninterface Props {\n embed: AudioMetaData;\n lang?: string;\n}\n\nexport const getFirstNonEmptyLicenseCredits = (authors: {\n creators: Author[];\n rightsholders: Author[];\n processors: Author[];\n}) => Object.values(authors).find((i) => i.length > 0) ?? [];\n\nexport const AudioEmbed = ({ embed, lang }: Props) => {\n const type = embed.embedData.type === \"standard\" ? \"audio\" : \"podcast\";\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type={type} />;\n }\n\n const { data, embedData } = embed;\n\n const variant = embedData.type === \"podcast\" ? \"standard\" : (embedData.type as AudioPlayerVariant);\n\n const subtitle = data.series ? { title: data.series.title.title, url: `/podkast/${data.series.id}` } : undefined;\n\n const coverPhoto = data.podcastMeta?.coverPhoto;\n\n const img = coverPhoto && { url: coverPhoto.url, alt: coverPhoto.altText };\n\n const licenseProps = licenseAttributes(data.copyright.license.license, lang, embedData.url);\n\n return (\n <StyledFigure lang={lang} data-embed-type={type} {...licenseProps}>\n <AudioPlayer\n variant={variant}\n description={data.podcastMeta?.introduction ?? \"\"}\n img={img}\n src={data.audioFile.url}\n textVersion={\n data.manuscript?.manuscript.length ? (\n <div dangerouslySetInnerHTML={{ __html: data.manuscript.manuscript }} />\n ) : undefined\n }\n title={data.title.title}\n subtitle={subtitle}\n />\n <EmbedByline\n error={false}\n type={data.audioType === \"standard\" ? \"audio\" : \"podcast\"}\n copyright={embed.data.copyright}\n />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAiBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,OAAO,QACR,EACF,CAAC;AAaF,MAAa,cAAc,EAAE,OAAO,WAAkB;CACpD,MAAM,OAAO,MAAM,UAAU,SAAS,aAAa,UAAU;AAC7D,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,uBAAD,EAA6B,MAAQ,CAAA;CAG9C,MAAM,EAAE,MAAM,cAAc;CAE5B,MAAM,UAAU,UAAU,SAAS,YAAY,aAAc,UAAU;CAEvE,MAAM,WAAW,KAAK,SAAS;EAAE,OAAO,KAAK,OAAO,MAAM;EAAO,KAAK,YAAY,KAAK,OAAO;EAAM,GAAG,KAAA;CAEvG,MAAM,aAAa,KAAK,aAAa;CAErC,MAAM,MAAM,cAAc;EAAE,KAAK,WAAW;EAAK,KAAK,WAAW;EAAS;AAI1E,QACE,qBAAC,cAAD;EAAoB;EAAM,mBAAiB;EAAM,GAH9B,kBAAkB,KAAK,UAAU,QAAQ,SAAS,MAAM,UAAU,IAAI;YAGzF,CACE,oBAAC,aAAD;GACW;GACT,aAAa,KAAK,aAAa,gBAAgB;GAC1C;GACL,KAAK,KAAK,UAAU;GACpB,aACE,KAAK,YAAY,WAAW,SAC1B,oBAAC,OAAD,EAAK,yBAAyB,EAAE,QAAQ,KAAK,WAAW,YAAY,EAAI,CAAA,GACtE,KAAA;GAEN,OAAO,KAAK,MAAM;GACR;GACV,CAAA,EACF,oBAAC,aAAD;GACE,OAAO;GACP,MAAM,KAAK,cAAc,aAAa,UAAU;GAChD,WAAW,MAAM,KAAK;GACtB,CAAA,CACW"}
@@ -31,22 +31,19 @@ const ExternalEmbed = ({ embed }) => {
31
31
  }, []);
32
32
  if (embed.status === "error") return /* @__PURE__ */ jsx(EmbedErrorPlaceholder, { type: "external" });
33
33
  const { embedData, data } = embed;
34
- if (embedData.type === "fullscreen") {
35
- const image = {
36
- src: data.iframeImage?.image.imageUrl,
37
- alt: embedData.alt !== void 0 ? embedData.alt : data.iframeImage?.alttext?.alttext ?? ""
38
- };
39
- return /* @__PURE__ */ jsx(Figure, {
40
- "data-embed-type": "external",
41
- children: /* @__PURE__ */ jsx(ResourceBox, {
42
- image,
43
- title: embedData.title ?? "",
44
- url: embedData.url,
45
- caption: embedData.caption ?? "",
46
- buttonText: t("license.other.itemImage.ariaLabel")
47
- })
48
- });
49
- }
34
+ if (embedData.type === "fullscreen") return /* @__PURE__ */ jsx(Figure, {
35
+ "data-embed-type": "external",
36
+ children: /* @__PURE__ */ jsx(ResourceBox, {
37
+ image: {
38
+ src: data.iframeImage?.image.imageUrl,
39
+ alt: embedData.alt !== void 0 ? embedData.alt : data.iframeImage?.alttext?.alttext ?? ""
40
+ },
41
+ title: embedData.title ?? "",
42
+ url: embedData.url,
43
+ caption: embedData.caption ?? "",
44
+ buttonText: t("license.other.itemImage.ariaLabel")
45
+ })
46
+ });
50
47
  return /* @__PURE__ */ jsx(StyledFigure, {
51
48
  "data-embed-type": "external",
52
49
  ref: figRef,
@@ -1 +1 @@
1
- {"version":3,"file":"ExternalEmbed.mjs","names":[],"sources":["../../src/Embed/ExternalEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { OembedMetaData } from \"@ndla/types-embed\";\nimport { useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ResourceBox } from \"../ResourceBox/ResourceBox\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\n\ninterface Props {\n embed: OembedMetaData;\n}\n\nconst StyledFigure = styled(Figure, {\n base: {\n \"& iframe\": {\n height: \"auto\",\n width: \"100%\",\n },\n },\n});\n\nexport const ExternalEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n const figRef = useRef<HTMLElement>(null);\n\n useEffect(() => {\n const iframe = figRef.current?.querySelector(\"iframe\");\n if (iframe) {\n const [width, height] = [Number.parseInt(iframe.width), Number.parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"external\" />;\n }\n\n const { embedData, data } = embed;\n\n if (embedData.type === \"fullscreen\") {\n const image = {\n src: data.iframeImage?.image.imageUrl,\n alt: embedData.alt !== undefined ? embedData.alt : (data.iframeImage?.alttext?.alttext ?? \"\"),\n };\n return (\n <Figure data-embed-type=\"external\">\n <ResourceBox\n image={image}\n title={embedData.title ?? \"\"}\n url={embedData.url}\n caption={embedData.caption ?? \"\"}\n buttonText={t(\"license.other.itemImage.ariaLabel\")}\n />\n </Figure>\n );\n }\n\n return (\n <StyledFigure\n data-embed-type=\"external\"\n ref={figRef}\n dangerouslySetInnerHTML={{ __html: data?.oembed?.html ?? \"\" }}\n />\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,YAAY;CACV,QAAQ;CACR,OAAO;CACR,EACF,EACF,CAAC;AAEF,MAAa,iBAAiB,EAAE,YAAmB;CACjD,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,SAAS,OAAoB,KAAK;AAExC,iBAAgB;EACd,MAAM,SAAS,OAAO,SAAS,cAAc,SAAS;AACtD,MAAI,QAAQ;GACV,MAAM,CAAC,OAAO,UAAU,CAAC,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,SAAS,OAAO,OAAO,CAAC;AACvF,UAAO,MAAM,cAAc,GAAG,QAAQ,QAAQ,GAAG,GAAG,SAAS,SAAS;AACtE,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AAEN,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,uBAAD,EAAuB,MAAK,YAAa,CAAA;CAGlD,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,UAAU,SAAS,cAAc;EACnC,MAAM,QAAQ;GACZ,KAAK,KAAK,aAAa,MAAM;GAC7B,KAAK,UAAU,QAAQ,KAAA,IAAY,UAAU,MAAO,KAAK,aAAa,SAAS,WAAW;GAC3F;AACD,SACE,oBAAC,QAAD;GAAQ,mBAAgB;aACtB,oBAAC,aAAD;IACS;IACP,OAAO,UAAU,SAAS;IAC1B,KAAK,UAAU;IACf,SAAS,UAAU,WAAW;IAC9B,YAAY,EAAE,oCAAoC;IAClD,CAAA;GACK,CAAA;;AAIb,QACE,oBAAC,cAAD;EACE,mBAAgB;EAChB,KAAK;EACL,yBAAyB,EAAE,QAAQ,MAAM,QAAQ,QAAQ,IAAI;EAC7D,CAAA"}
1
+ {"version":3,"file":"ExternalEmbed.mjs","names":[],"sources":["../../src/Embed/ExternalEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { OembedMetaData } from \"@ndla/types-embed\";\nimport { useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ResourceBox } from \"../ResourceBox/ResourceBox\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\n\ninterface Props {\n embed: OembedMetaData;\n}\n\nconst StyledFigure = styled(Figure, {\n base: {\n \"& iframe\": {\n height: \"auto\",\n width: \"100%\",\n },\n },\n});\n\nexport const ExternalEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n const figRef = useRef<HTMLElement>(null);\n\n useEffect(() => {\n const iframe = figRef.current?.querySelector(\"iframe\");\n if (iframe) {\n const [width, height] = [Number.parseInt(iframe.width), Number.parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"external\" />;\n }\n\n const { embedData, data } = embed;\n\n if (embedData.type === \"fullscreen\") {\n const image = {\n src: data.iframeImage?.image.imageUrl,\n alt: embedData.alt !== undefined ? embedData.alt : (data.iframeImage?.alttext?.alttext ?? \"\"),\n };\n return (\n <Figure data-embed-type=\"external\">\n <ResourceBox\n image={image}\n title={embedData.title ?? \"\"}\n url={embedData.url}\n caption={embedData.caption ?? \"\"}\n buttonText={t(\"license.other.itemImage.ariaLabel\")}\n />\n </Figure>\n );\n }\n\n return (\n <StyledFigure\n data-embed-type=\"external\"\n ref={figRef}\n dangerouslySetInnerHTML={{ __html: data?.oembed?.html ?? \"\" }}\n />\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,YAAY;CACV,QAAQ;CACR,OAAO;CACR,EACF,EACF,CAAC;AAEF,MAAa,iBAAiB,EAAE,YAAmB;CACjD,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,SAAS,OAAoB,KAAK;AAExC,iBAAgB;EACd,MAAM,SAAS,OAAO,SAAS,cAAc,SAAS;AACtD,MAAI,QAAQ;GACV,MAAM,CAAC,OAAO,UAAU,CAAC,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,SAAS,OAAO,OAAO,CAAC;AACvF,UAAO,MAAM,cAAc,GAAG,QAAQ,QAAQ,GAAG,GAAG,SAAS,SAAS;AACtE,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AAEN,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,uBAAD,EAAuB,MAAK,YAAa,CAAA;CAGlD,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,UAAU,SAAS,aAKrB,QACE,oBAAC,QAAD;EAAQ,mBAAgB;YACtB,oBAAC,aAAD;GACE,OAPQ;IACZ,KAAK,KAAK,aAAa,MAAM;IAC7B,KAAK,UAAU,QAAQ,KAAA,IAAY,UAAU,MAAO,KAAK,aAAa,SAAS,WAAW;IAC3F;GAKK,OAAO,UAAU,SAAS;GAC1B,KAAK,UAAU;GACf,SAAS,UAAU,WAAW;GAC9B,YAAY,EAAE,oCAAoC;GAClD,CAAA;EACK,CAAA;AAIb,QACE,oBAAC,cAAD;EACE,mBAAgB;EAChB,KAAK;EACL,yBAAyB,EAAE,QAAQ,MAAM,QAAQ,QAAQ,IAAI;EAC7D,CAAA"}
@@ -35,14 +35,13 @@ const IframeEmbed = ({ embed }) => {
35
35
  if (embedData.type === "fullscreen") {
36
36
  const iframeImage = embed.status === "success" ? data.iframeImage : void 0;
37
37
  const alt = embedData.alt !== void 0 ? embedData.alt : iframeImage?.alttext.alttext;
38
- const image = {
39
- src: iframeImage?.image.imageUrl,
40
- alt: alt ?? ""
41
- };
42
38
  return /* @__PURE__ */ jsx(StyledFigure, {
43
39
  "data-embed-type": "iframe",
44
40
  children: /* @__PURE__ */ jsx(ResourceBox, {
45
- image,
41
+ image: {
42
+ src: iframeImage?.image.imageUrl,
43
+ alt: alt ?? ""
44
+ },
46
45
  title: embedData.title ?? "",
47
46
  url: embedData.url,
48
47
  caption: embedData.caption ?? "",
@@ -1 +1 @@
1
- {"version":3,"file":"IframeEmbed.mjs","names":[],"sources":["../../src/Embed/IframeEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { IframeMetaData } from \"@ndla/types-embed\";\nimport { useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ResourceBox } from \"../ResourceBox/ResourceBox\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\n\ninterface Props {\n embed: IframeMetaData;\n}\n\nconst StyledIframe = styled(\"iframe\", {\n base: {\n width: \"100%\",\n border: 0,\n },\n});\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n },\n});\n\nexport const IframeEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (iframe) {\n const [width, height] = [Number.parseInt(iframe.width), Number.parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"external\" />;\n }\n\n const { embedData, data } = embed;\n\n if (embedData.type === \"fullscreen\") {\n const iframeImage = embed.status === \"success\" ? data.iframeImage : undefined;\n const alt = embedData.alt !== undefined ? embedData.alt : iframeImage?.alttext.alttext;\n const image = { src: iframeImage?.image.imageUrl, alt: alt ?? \"\" };\n return (\n <StyledFigure data-embed-type=\"iframe\">\n <ResourceBox\n image={image}\n title={embedData.title ?? \"\"}\n url={embedData.url}\n caption={embedData.caption ?? \"\"}\n buttonText={t(\"license.other.itemImage.ariaLabel\")}\n />\n </StyledFigure>\n );\n }\n\n const { width, height, url } = embedData;\n\n const strippedWidth = typeof width === \"number\" ? width : width?.replace(/\\s*px/, \"\");\n const strippedHeight = typeof height === \"number\" ? height : height?.replace(/\\s*px/, \"\");\n const title = `${t(\"embed.type.external\")}: ${embedData.title?.trim() ? embedData.title : url}`;\n\n return (\n <StyledFigure data-embed-type=\"iframe\">\n <StyledIframe\n ref={iframeRef}\n title={title}\n aria-label={title}\n src={url}\n width={strippedWidth}\n height={strippedHeight}\n allow=\"autoplay; encrypted-media; fullscreen\"\n loading=\"lazy\"\n />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,MAAM,eAAe,OAAO,UAAU,EACpC,MAAM;CACJ,OAAO;CACP,QAAQ;CACT,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,OAAO,QACR,EACF,CAAC;AAEF,MAAa,eAAe,EAAE,YAAmB;CAC/C,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,YAAY,OAA0B,KAAK;AAEjD,iBAAgB;EACd,MAAM,SAAS,UAAU;AACzB,MAAI,QAAQ;GACV,MAAM,CAAC,OAAO,UAAU,CAAC,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,SAAS,OAAO,OAAO,CAAC;AACvF,UAAO,MAAM,cAAc,GAAG,QAAQ,QAAQ,GAAG,GAAG,SAAS,SAAS;AACtE,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AAEN,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,uBAAD,EAAuB,MAAK,YAAa,CAAA;CAGlD,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,UAAU,SAAS,cAAc;EACnC,MAAM,cAAc,MAAM,WAAW,YAAY,KAAK,cAAc,KAAA;EACpE,MAAM,MAAM,UAAU,QAAQ,KAAA,IAAY,UAAU,MAAM,aAAa,QAAQ;EAC/E,MAAM,QAAQ;GAAE,KAAK,aAAa,MAAM;GAAU,KAAK,OAAO;GAAI;AAClE,SACE,oBAAC,cAAD;GAAc,mBAAgB;aAC5B,oBAAC,aAAD;IACS;IACP,OAAO,UAAU,SAAS;IAC1B,KAAK,UAAU;IACf,SAAS,UAAU,WAAW;IAC9B,YAAY,EAAE,oCAAoC;IAClD,CAAA;GACW,CAAA;;CAInB,MAAM,EAAE,OAAO,QAAQ,QAAQ;CAE/B,MAAM,gBAAgB,OAAO,UAAU,WAAW,QAAQ,OAAO,QAAQ,SAAS,GAAG;CACrF,MAAM,iBAAiB,OAAO,WAAW,WAAW,SAAS,QAAQ,QAAQ,SAAS,GAAG;CACzF,MAAM,QAAQ,GAAG,EAAE,sBAAsB,CAAC,IAAI,UAAU,OAAO,MAAM,GAAG,UAAU,QAAQ;AAE1F,QACE,oBAAC,cAAD;EAAc,mBAAgB;YAC5B,oBAAC,cAAD;GACE,KAAK;GACE;GACP,cAAY;GACZ,KAAK;GACL,OAAO;GACP,QAAQ;GACR,OAAM;GACN,SAAQ;GACR,CAAA;EACW,CAAA"}
1
+ {"version":3,"file":"IframeEmbed.mjs","names":[],"sources":["../../src/Embed/IframeEmbed.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { Figure } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { IframeMetaData } from \"@ndla/types-embed\";\nimport { useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { ResourceBox } from \"../ResourceBox/ResourceBox\";\nimport { EmbedErrorPlaceholder } from \"./EmbedErrorPlaceholder\";\n\ninterface Props {\n embed: IframeMetaData;\n}\n\nconst StyledIframe = styled(\"iframe\", {\n base: {\n width: \"100%\",\n border: 0,\n },\n});\n\nconst StyledFigure = styled(Figure, {\n base: {\n clear: \"both\",\n },\n});\n\nexport const IframeEmbed = ({ embed }: Props) => {\n const { t } = useTranslation();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (iframe) {\n const [width, height] = [Number.parseInt(iframe.width), Number.parseInt(iframe.height)];\n iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;\n iframe.width = \"\";\n iframe.height = \"\";\n }\n }, []);\n\n if (embed.status === \"error\") {\n return <EmbedErrorPlaceholder type=\"external\" />;\n }\n\n const { embedData, data } = embed;\n\n if (embedData.type === \"fullscreen\") {\n const iframeImage = embed.status === \"success\" ? data.iframeImage : undefined;\n const alt = embedData.alt !== undefined ? embedData.alt : iframeImage?.alttext.alttext;\n const image = { src: iframeImage?.image.imageUrl, alt: alt ?? \"\" };\n return (\n <StyledFigure data-embed-type=\"iframe\">\n <ResourceBox\n image={image}\n title={embedData.title ?? \"\"}\n url={embedData.url}\n caption={embedData.caption ?? \"\"}\n buttonText={t(\"license.other.itemImage.ariaLabel\")}\n />\n </StyledFigure>\n );\n }\n\n const { width, height, url } = embedData;\n\n const strippedWidth = typeof width === \"number\" ? width : width?.replace(/\\s*px/, \"\");\n const strippedHeight = typeof height === \"number\" ? height : height?.replace(/\\s*px/, \"\");\n const title = `${t(\"embed.type.external\")}: ${embedData.title?.trim() ? embedData.title : url}`;\n\n return (\n <StyledFigure data-embed-type=\"iframe\">\n <StyledIframe\n ref={iframeRef}\n title={title}\n aria-label={title}\n src={url}\n width={strippedWidth}\n height={strippedHeight}\n allow=\"autoplay; encrypted-media; fullscreen\"\n loading=\"lazy\"\n />\n </StyledFigure>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,MAAM,eAAe,OAAO,UAAU,EACpC,MAAM;CACJ,OAAO;CACP,QAAQ;CACT,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM,EACJ,OAAO,QACR,EACF,CAAC;AAEF,MAAa,eAAe,EAAE,YAAmB;CAC/C,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,YAAY,OAA0B,KAAK;AAEjD,iBAAgB;EACd,MAAM,SAAS,UAAU;AACzB,MAAI,QAAQ;GACV,MAAM,CAAC,OAAO,UAAU,CAAC,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,SAAS,OAAO,OAAO,CAAC;AACvF,UAAO,MAAM,cAAc,GAAG,QAAQ,QAAQ,GAAG,GAAG,SAAS,SAAS;AACtE,UAAO,QAAQ;AACf,UAAO,SAAS;;IAEjB,EAAE,CAAC;AAEN,KAAI,MAAM,WAAW,QACnB,QAAO,oBAAC,uBAAD,EAAuB,MAAK,YAAa,CAAA;CAGlD,MAAM,EAAE,WAAW,SAAS;AAE5B,KAAI,UAAU,SAAS,cAAc;EACnC,MAAM,cAAc,MAAM,WAAW,YAAY,KAAK,cAAc,KAAA;EACpE,MAAM,MAAM,UAAU,QAAQ,KAAA,IAAY,UAAU,MAAM,aAAa,QAAQ;AAE/E,SACE,oBAAC,cAAD;GAAc,mBAAgB;aAC5B,oBAAC,aAAD;IACE,OAJQ;KAAE,KAAK,aAAa,MAAM;KAAU,KAAK,OAAO;KAAI;IAK5D,OAAO,UAAU,SAAS;IAC1B,KAAK,UAAU;IACf,SAAS,UAAU,WAAW;IAC9B,YAAY,EAAE,oCAAoC;IAClD,CAAA;GACW,CAAA;;CAInB,MAAM,EAAE,OAAO,QAAQ,QAAQ;CAE/B,MAAM,gBAAgB,OAAO,UAAU,WAAW,QAAQ,OAAO,QAAQ,SAAS,GAAG;CACrF,MAAM,iBAAiB,OAAO,WAAW,WAAW,SAAS,QAAQ,QAAQ,SAAS,GAAG;CACzF,MAAM,QAAQ,GAAG,EAAE,sBAAsB,CAAC,IAAI,UAAU,OAAO,MAAM,GAAG,UAAU,QAAQ;AAE1F,QACE,oBAAC,cAAD;EAAc,mBAAgB;YAC5B,oBAAC,cAAD;GACE,KAAK;GACE;GACP,cAAY;GACZ,KAAK;GACL,OAAO;GACP,QAAQ;GACR,OAAM;GACN,SAAQ;GACR,CAAA;EACW,CAAA"}
@@ -1,8 +1,7 @@
1
- import { IconButton } from "@ndla/primitives";
1
+ import { Button } from "@ndla/primitives";
2
2
  import { styled } from "@ndla/styled-system/jsx";
3
3
  import React, { forwardRef, useCallback, useEffect, useId, useMemo, useState } from "react";
4
4
  import { useTranslation } from "react-i18next";
5
- import { ArrowDownShortLine } from "@ndla/icons";
6
5
  import { jsx, jsxs } from "react/jsx-runtime";
7
6
  //#region src/FactBox/FactBox.tsx
8
7
  /**
@@ -27,52 +26,29 @@ const StyledAside = styled("aside", {
27
26
  borderRadius: "xsmall",
28
27
  clear: "both",
29
28
  _open: { gridTemplateRows: "1fr" },
30
- _closed: { _print: {
29
+ _print: {
30
+ gridTemplateRows: "1fr",
31
31
  overflow: "visible",
32
32
  maxHeight: "500vh"
33
- } },
33
+ },
34
34
  "& > div": { minHeight: "surface.3xsmall" }
35
35
  },
36
- variants: { overflowHidden: { true: { "& > div": { overflow: "hidden" } } } }
36
+ variants: { overflowHidden: { true: { "& > div": {
37
+ overflow: "hidden",
38
+ _print: { overflow: "visible" }
39
+ } } } }
37
40
  });
38
41
  const StyledContent = styled("div", { base: {
39
42
  position: "relative",
40
43
  width: "100%",
41
44
  "& :first-child": { marginBlockStart: "0" },
42
- _after: {
43
- content: "\"\"",
44
- textAlign: "center",
45
- position: "absolute",
46
- inset: "0",
47
- transitionProperty: "opacity",
48
- transitionDuration: "slow",
49
- transitionTimingFunction: "ease-in-out",
50
- gradientFrom: "surface.default/20",
51
- gradientTo: "surface.default/95",
52
- backgroundGradient: "to-b",
53
- opacity: "1",
54
- zIndex: "base",
55
- pointerEvents: "none"
56
- },
57
- _print: {
58
- overflow: "visible",
59
- _after: { display: "none" }
60
- },
61
- _open: {
62
- paddingBlockEnd: "xsmall",
63
- _after: { opacity: "0" }
64
- }
45
+ _print: { overflow: "visible" },
46
+ _open: { paddingBlockEnd: "xsmall" }
65
47
  } });
66
- const StyledIconButton = styled(IconButton, { base: {
48
+ const StyledButton = styled(Button, { base: {
67
49
  position: "absolute",
68
50
  bottom: "-medium",
69
51
  zIndex: "base",
70
- "& svg": {
71
- transitionProperty: "transform",
72
- transitionTimingFunction: "ease-in-out",
73
- transitionDuration: "fast"
74
- },
75
- _open: { "& svg": { transform: "rotate(180deg)" } },
76
52
  _print: { display: "none" }
77
53
  } });
78
54
  const FactBox = forwardRef(({ children, open, onOpenChange, defaultOpen = false, ...rest }, ref) => {
@@ -103,14 +79,14 @@ const FactBox = forwardRef(({ children, open, onOpenChange, defaultOpen = false,
103
79
  onTransitionEnd: (e) => {
104
80
  if (e.target === e.currentTarget && state === "open") setOverflowHidden(false);
105
81
  },
106
- children: [/* @__PURE__ */ jsx(StyledIconButton, {
82
+ children: [/* @__PURE__ */ jsx(StyledButton, {
107
83
  "data-state": state,
108
84
  onClick,
109
85
  contentEditable: false,
110
86
  "aria-expanded": state === "open",
87
+ variant: "secondary",
111
88
  "aria-controls": contentId,
112
- "aria-label": t(`factbox.${state === "open" ? "close" : "open"}`),
113
- children: /* @__PURE__ */ jsx(ArrowDownShortLine, {})
89
+ children: t(`factbox.${state === "open" ? "showLess" : "showMore"}`)
114
90
  }), /* @__PURE__ */ jsx(StyledContent, {
115
91
  id: contentId,
116
92
  "data-state": state,
@@ -1 +1 @@
1
- {"version":3,"file":"FactBox.mjs","names":[],"sources":["../../src/FactBox/FactBox.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 { ArrowDownShortLine } from \"@ndla/icons\";\nimport { IconButton } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport React, {\n type ComponentProps,\n type ReactNode,\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useState,\n} from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\ninterface Props extends ComponentProps<\"aside\"> {\n children?: ReactNode;\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nconst StyledAside = styled(\"aside\", {\n base: {\n position: \"relative\",\n padding: \"medium\",\n display: \"grid\",\n gridTemplateRows: \"0fr\",\n transitionProperty: \"grid-template-rows\",\n transitionDuration: \"slow\",\n transitionTimingFunction: \"ease-in-out\",\n justifyItems: \"center\",\n border: \"1px solid\",\n borderColor: \"stroke.default\",\n borderRadius: \"xsmall\",\n clear: \"both\",\n _open: {\n gridTemplateRows: \"1fr\",\n },\n _closed: {\n _print: {\n overflow: \"visible\",\n maxHeight: \"500vh\",\n },\n },\n \"& > div\": {\n minHeight: \"surface.3xsmall\",\n },\n },\n variants: {\n overflowHidden: {\n true: {\n \"& > div\": {\n overflow: \"hidden\",\n },\n },\n },\n },\n});\n\nconst StyledContent = styled(\"div\", {\n base: {\n position: \"relative\",\n width: \"100%\",\n // Reset the top margin of the very first child.\n \"& :first-child\": {\n marginBlockStart: \"0\",\n },\n _after: {\n content: '\"\"',\n textAlign: \"center\",\n position: \"absolute\",\n inset: \"0\",\n transitionProperty: \"opacity\",\n transitionDuration: \"slow\",\n transitionTimingFunction: \"ease-in-out\",\n gradientFrom: \"surface.default/20\",\n gradientTo: \"surface.default/95\",\n backgroundGradient: \"to-b\",\n opacity: \"1\",\n zIndex: \"base\",\n pointerEvents: \"none\",\n },\n _print: {\n overflow: \"visible\",\n _after: {\n display: \"none\",\n },\n },\n _open: {\n paddingBlockEnd: \"xsmall\",\n _after: {\n opacity: \"0\",\n },\n },\n },\n});\n\nconst StyledIconButton = styled(IconButton, {\n base: {\n position: \"absolute\",\n bottom: \"-medium\",\n zIndex: \"base\",\n \"& svg\": {\n transitionProperty: \"transform\",\n transitionTimingFunction: \"ease-in-out\",\n transitionDuration: \"fast\",\n },\n _open: {\n \"& svg\": {\n transform: \"rotate(180deg)\",\n },\n },\n _print: {\n display: \"none\",\n },\n },\n});\n\n// TODO: Consider moving the open trigger depending on whether the content is open or closed.\n\nexport const FactBox = forwardRef<HTMLElement, Props>(\n ({ children, open, onOpenChange, defaultOpen = false, ...rest }, ref) => {\n const { t } = useTranslation();\n const [state, setState] = useState<\"open\" | \"closed\">(defaultOpen ? \"open\" : \"closed\");\n const [overflowHidden, setOverflowHidden] = useState(!defaultOpen);\n const contentId = useId();\n // Inert has existed since early 2023. It allows us to disable tabindex inside the content if it is closed, allowing us to be accessible for users with newish browsers. React 18 removes this because it doesn't recognize the attribute. This is a workaround for that.\n // When running in React 18, we need to use an empty string instead of true.\n // TODO: Remove this hack once we upgrade to React 19 as a peer dep.\n const inertAttribute = useMemo(() => {\n return state === \"closed\" ? { inert: typeof React.use === \"function\" ? true : \"\" } : {};\n }, [state]) as { inert?: boolean };\n\n useEffect(() => {\n if (open !== undefined) {\n setState(open ? \"open\" : \"closed\");\n }\n }, [open]);\n\n const onClick = useCallback(() => {\n const newState = state === \"open\" ? \"closed\" : \"open\";\n setState(newState);\n onOpenChange?.(newState === \"open\");\n }, [state, onOpenChange]);\n\n return (\n <StyledAside\n data-state={state}\n data-embed-type=\"factbox\"\n {...rest}\n ref={ref}\n overflowHidden={overflowHidden}\n onTransitionStart={(e) => {\n if (e.target === e.currentTarget && state === \"closed\") {\n setOverflowHidden(true);\n }\n }}\n onTransitionEnd={(e) => {\n if (e.target === e.currentTarget && state === \"open\") {\n setOverflowHidden(false);\n }\n }}\n >\n <StyledIconButton\n data-state={state}\n onClick={onClick}\n contentEditable={false}\n aria-expanded={state === \"open\"}\n aria-controls={contentId}\n aria-label={t(`factbox.${state === \"open\" ? \"close\" : \"open\"}`)}\n >\n <ArrowDownShortLine />\n </StyledIconButton>\n <StyledContent id={contentId} data-state={state} aria-hidden={state === \"closed\"} {...inertAttribute}>\n {children}\n </StyledContent>\n </StyledAside>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;AA8BA,MAAM,cAAc,OAAO,SAAS;CAClC,MAAM;EACJ,UAAU;EACV,SAAS;EACT,SAAS;EACT,kBAAkB;EAClB,oBAAoB;EACpB,oBAAoB;EACpB,0BAA0B;EAC1B,cAAc;EACd,QAAQ;EACR,aAAa;EACb,cAAc;EACd,OAAO;EACP,OAAO,EACL,kBAAkB,OACnB;EACD,SAAS,EACP,QAAQ;GACN,UAAU;GACV,WAAW;GACZ,EACF;EACD,WAAW,EACT,WAAW,mBACZ;EACF;CACD,UAAU,EACR,gBAAgB,EACd,MAAM,EACJ,WAAW,EACT,UAAU,UACX,EACF,EACF,EACF;CACF,CAAC;AAEF,MAAM,gBAAgB,OAAO,OAAO,EAClC,MAAM;CACJ,UAAU;CACV,OAAO;CAEP,kBAAkB,EAChB,kBAAkB,KACnB;CACD,QAAQ;EACN,SAAS;EACT,WAAW;EACX,UAAU;EACV,OAAO;EACP,oBAAoB;EACpB,oBAAoB;EACpB,0BAA0B;EAC1B,cAAc;EACd,YAAY;EACZ,oBAAoB;EACpB,SAAS;EACT,QAAQ;EACR,eAAe;EAChB;CACD,QAAQ;EACN,UAAU;EACV,QAAQ,EACN,SAAS,QACV;EACF;CACD,OAAO;EACL,iBAAiB;EACjB,QAAQ,EACN,SAAS,KACV;EACF;CACF,EACF,CAAC;AAEF,MAAM,mBAAmB,OAAO,YAAY,EAC1C,MAAM;CACJ,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,SAAS;EACP,oBAAoB;EACpB,0BAA0B;EAC1B,oBAAoB;EACrB;CACD,OAAO,EACL,SAAS,EACP,WAAW,kBACZ,EACF;CACD,QAAQ,EACN,SAAS,QACV;CACF,EACF,CAAC;AAIF,MAAa,UAAU,YACpB,EAAE,UAAU,MAAM,cAAc,cAAc,OAAO,GAAG,QAAQ,QAAQ;CACvE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,CAAC,OAAO,YAAY,SAA4B,cAAc,SAAS,SAAS;CACtF,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,CAAC,YAAY;CAClE,MAAM,YAAY,OAAO;CAIzB,MAAM,iBAAiB,cAAc;AACnC,SAAO,UAAU,WAAW,EAAE,OAAO,OAAO,MAAM,QAAQ,aAAa,OAAO,IAAI,GAAG,EAAE;IACtF,CAAC,MAAM,CAAC;AAEX,iBAAgB;AACd,MAAI,SAAS,KAAA,EACX,UAAS,OAAO,SAAS,SAAS;IAEnC,CAAC,KAAK,CAAC;CAEV,MAAM,UAAU,kBAAkB;EAChC,MAAM,WAAW,UAAU,SAAS,WAAW;AAC/C,WAAS,SAAS;AAClB,iBAAe,aAAa,OAAO;IAClC,CAAC,OAAO,aAAa,CAAC;AAEzB,QACE,qBAAC,aAAD;EACE,cAAY;EACZ,mBAAgB;EAChB,GAAI;EACC;EACW;EAChB,oBAAoB,MAAM;AACxB,OAAI,EAAE,WAAW,EAAE,iBAAiB,UAAU,SAC5C,mBAAkB,KAAK;;EAG3B,kBAAkB,MAAM;AACtB,OAAI,EAAE,WAAW,EAAE,iBAAiB,UAAU,OAC5C,mBAAkB,MAAM;;YAb9B,CAiBE,oBAAC,kBAAD;GACE,cAAY;GACH;GACT,iBAAiB;GACjB,iBAAe,UAAU;GACzB,iBAAe;GACf,cAAY,EAAE,WAAW,UAAU,SAAS,UAAU,SAAS;aAE/D,oBAAC,oBAAD,EAAsB,CAAA;GACL,CAAA,EACnB,oBAAC,eAAD;GAAe,IAAI;GAAW,cAAY;GAAO,eAAa,UAAU;GAAU,GAAI;GACnF;GACa,CAAA,CACJ;;EAGnB"}
1
+ {"version":3,"file":"FactBox.mjs","names":[],"sources":["../../src/FactBox/FactBox.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 { Button } from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport React, {\n type ComponentProps,\n type ReactNode,\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useState,\n} from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\ninterface Props extends ComponentProps<\"aside\"> {\n children?: ReactNode;\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nconst StyledAside = styled(\"aside\", {\n base: {\n position: \"relative\",\n padding: \"medium\",\n display: \"grid\",\n gridTemplateRows: \"0fr\",\n transitionProperty: \"grid-template-rows\",\n transitionDuration: \"slow\",\n transitionTimingFunction: \"ease-in-out\",\n justifyItems: \"center\",\n border: \"1px solid\",\n borderColor: \"stroke.default\",\n borderRadius: \"xsmall\",\n clear: \"both\",\n _open: {\n gridTemplateRows: \"1fr\",\n },\n _print: {\n gridTemplateRows: \"1fr\",\n overflow: \"visible\",\n maxHeight: \"500vh\",\n },\n \"& > div\": {\n minHeight: \"surface.3xsmall\",\n },\n },\n variants: {\n overflowHidden: {\n true: {\n \"& > div\": {\n overflow: \"hidden\",\n _print: {\n overflow: \"visible\",\n },\n },\n },\n },\n },\n});\n\nconst StyledContent = styled(\"div\", {\n base: {\n position: \"relative\",\n width: \"100%\",\n // Reset the top margin of the very first child.\n \"& :first-child\": {\n marginBlockStart: \"0\",\n },\n _print: {\n overflow: \"visible\",\n },\n _open: {\n paddingBlockEnd: \"xsmall\",\n },\n },\n});\n\nconst StyledButton = styled(Button, {\n base: {\n position: \"absolute\",\n bottom: \"-medium\",\n zIndex: \"base\",\n _print: {\n display: \"none\",\n },\n },\n});\n\n// TODO: Consider moving the open trigger depending on whether the content is open or closed.\n\nexport const FactBox = forwardRef<HTMLElement, Props>(\n ({ children, open, onOpenChange, defaultOpen = false, ...rest }, ref) => {\n const { t } = useTranslation();\n const [state, setState] = useState<\"open\" | \"closed\">(defaultOpen ? \"open\" : \"closed\");\n const [overflowHidden, setOverflowHidden] = useState(!defaultOpen);\n const contentId = useId();\n // Inert has existed since early 2023. It allows us to disable tabindex inside the content if it is closed, allowing us to be accessible for users with newish browsers. React 18 removes this because it doesn't recognize the attribute. This is a workaround for that.\n // When running in React 18, we need to use an empty string instead of true.\n // TODO: Remove this hack once we upgrade to React 19 as a peer dep.\n const inertAttribute = useMemo(() => {\n return state === \"closed\" ? { inert: typeof React.use === \"function\" ? true : \"\" } : {};\n }, [state]) as { inert?: boolean };\n\n useEffect(() => {\n if (open !== undefined) {\n setState(open ? \"open\" : \"closed\");\n }\n }, [open]);\n\n const onClick = useCallback(() => {\n const newState = state === \"open\" ? \"closed\" : \"open\";\n setState(newState);\n onOpenChange?.(newState === \"open\");\n }, [state, onOpenChange]);\n\n return (\n <StyledAside\n data-state={state}\n data-embed-type=\"factbox\"\n {...rest}\n ref={ref}\n overflowHidden={overflowHidden}\n onTransitionStart={(e) => {\n if (e.target === e.currentTarget && state === \"closed\") {\n setOverflowHidden(true);\n }\n }}\n onTransitionEnd={(e) => {\n if (e.target === e.currentTarget && state === \"open\") {\n setOverflowHidden(false);\n }\n }}\n >\n <StyledButton\n data-state={state}\n onClick={onClick}\n contentEditable={false}\n aria-expanded={state === \"open\"}\n variant=\"secondary\"\n aria-controls={contentId}\n >\n {t(`factbox.${state === \"open\" ? \"showLess\" : \"showMore\"}`)}\n </StyledButton>\n <StyledContent id={contentId} data-state={state} aria-hidden={state === \"closed\"} {...inertAttribute}>\n {children}\n </StyledContent>\n </StyledAside>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;AA6BA,MAAM,cAAc,OAAO,SAAS;CAClC,MAAM;EACJ,UAAU;EACV,SAAS;EACT,SAAS;EACT,kBAAkB;EAClB,oBAAoB;EACpB,oBAAoB;EACpB,0BAA0B;EAC1B,cAAc;EACd,QAAQ;EACR,aAAa;EACb,cAAc;EACd,OAAO;EACP,OAAO,EACL,kBAAkB,OACnB;EACD,QAAQ;GACN,kBAAkB;GAClB,UAAU;GACV,WAAW;GACZ;EACD,WAAW,EACT,WAAW,mBACZ;EACF;CACD,UAAU,EACR,gBAAgB,EACd,MAAM,EACJ,WAAW;EACT,UAAU;EACV,QAAQ,EACN,UAAU,WACX;EACF,EACF,EACF,EACF;CACF,CAAC;AAEF,MAAM,gBAAgB,OAAO,OAAO,EAClC,MAAM;CACJ,UAAU;CACV,OAAO;CAEP,kBAAkB,EAChB,kBAAkB,KACnB;CACD,QAAQ,EACN,UAAU,WACX;CACD,OAAO,EACL,iBAAiB,UAClB;CACF,EACF,CAAC;AAEF,MAAM,eAAe,OAAO,QAAQ,EAClC,MAAM;CACJ,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,QAAQ,EACN,SAAS,QACV;CACF,EACF,CAAC;AAIF,MAAa,UAAU,YACpB,EAAE,UAAU,MAAM,cAAc,cAAc,OAAO,GAAG,QAAQ,QAAQ;CACvE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,CAAC,OAAO,YAAY,SAA4B,cAAc,SAAS,SAAS;CACtF,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,CAAC,YAAY;CAClE,MAAM,YAAY,OAAO;CAIzB,MAAM,iBAAiB,cAAc;AACnC,SAAO,UAAU,WAAW,EAAE,OAAO,OAAO,MAAM,QAAQ,aAAa,OAAO,IAAI,GAAG,EAAE;IACtF,CAAC,MAAM,CAAC;AAEX,iBAAgB;AACd,MAAI,SAAS,KAAA,EACX,UAAS,OAAO,SAAS,SAAS;IAEnC,CAAC,KAAK,CAAC;CAEV,MAAM,UAAU,kBAAkB;EAChC,MAAM,WAAW,UAAU,SAAS,WAAW;AAC/C,WAAS,SAAS;AAClB,iBAAe,aAAa,OAAO;IAClC,CAAC,OAAO,aAAa,CAAC;AAEzB,QACE,qBAAC,aAAD;EACE,cAAY;EACZ,mBAAgB;EAChB,GAAI;EACC;EACW;EAChB,oBAAoB,MAAM;AACxB,OAAI,EAAE,WAAW,EAAE,iBAAiB,UAAU,SAC5C,mBAAkB,KAAK;;EAG3B,kBAAkB,MAAM;AACtB,OAAI,EAAE,WAAW,EAAE,iBAAiB,UAAU,OAC5C,mBAAkB,MAAM;;YAb9B,CAiBE,oBAAC,cAAD;GACE,cAAY;GACH;GACT,iBAAiB;GACjB,iBAAe,UAAU;GACzB,SAAQ;GACR,iBAAe;aAEd,EAAE,WAAW,UAAU,SAAS,aAAa,aAAa;GAC9C,CAAA,EACf,oBAAC,eAAD;GAAe,IAAI;GAAW,cAAY;GAAO,eAAa,UAAU;GAAU,GAAI;GACnF;GACa,CAAA,CACJ;;EAGnB"}
@@ -110,8 +110,7 @@ const Gloss = ({ title, glossData, audio, exampleIds, exampleLangs, variant }) =
110
110
  })
111
111
  ] }), !!audio?.src && /* @__PURE__ */ jsx(SpeechControl, {
112
112
  src: audio.src,
113
- title: audio.title,
114
- type: "gloss"
113
+ title: audio.title
115
114
  })] }),
116
115
  /* @__PURE__ */ jsxs(StyledContainer, { children: [/* @__PURE__ */ jsx(Text, {
117
116
  textStyle: "label.medium",
@@ -1 +1 @@
1
- {"version":3,"file":"Gloss.mjs","names":["AccordionItemTrigger"],"sources":["../../src/Gloss/Gloss.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { AccordionItemTrigger } from \"@ark-ui/react\";\nimport { ArrowDownShortLine } from \"@ndla/icons\";\nimport {\n AccordionItem,\n AccordionItemContent,\n AccordionItemIndicator,\n AccordionRoot,\n IconButton,\n Text,\n} from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { StyledVariantProps } from \"@ndla/styled-system/types\";\nimport type { ConceptTitleDTO, GlossDataDTO, GlossExampleDTO } from \"@ndla/types-backend/concept-api\";\nimport parse from \"html-react-parser\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { SpeechControl } from \"../AudioPlayer/SpeechControl\";\nimport { GlossExample } from \"./GlossExample\";\n\n// TODO: Figure out padding between bordered and simple variant.\n// The design says that the content above the accordion content should have enough padding to align with the accordion content.\n// When a gloss is bordered there's way too much padding.\n\nconst getFilteredExamples = (\n glossData: GlossDataDTO | undefined,\n exampleIds: string | undefined,\n exampleLangs: string | undefined,\n): GlossExampleDTO[][] => {\n if (exampleIds !== undefined || exampleLangs !== undefined) {\n const exampleIdsList = exampleIds?.toString()?.split(\",\") ?? [];\n const exampleLangsList = exampleLangs?.split(\",\") ?? [];\n\n const filteredExamples =\n glossData?.examples?.map((examples, i) => {\n if (exampleIdsList.includes(i.toString())) {\n return examples.filter((e) => exampleLangsList.includes(e.language));\n }\n return [];\n }) ?? [];\n const examplesWithoutEmpty = filteredExamples.filter((el) => !!el.length);\n return examplesWithoutEmpty;\n }\n return glossData?.examples ?? [];\n};\n\nconst Container = styled(\"div\", {\n base: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n },\n});\n\nconst TextWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"small\",\n },\n});\n\nconst StyledAccordionItemContent = styled(AccordionItemContent, {\n base: {\n paddingInline: \"0\",\n },\n});\n\nconst StyledContainer = styled(Container, {\n base: {\n marginBlockStart: \"3xsmall\",\n },\n});\n\nconst StyledAccordionItem = styled(AccordionItem, {\n base: {\n paddingBlock: \"small\",\n paddingInline: \"medium\",\n },\n defaultVariants: {\n variant: \"simple\",\n },\n variants: {\n variant: {\n simple: {},\n bordered: {\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n borderRadius: \"xsmall\",\n },\n },\n },\n});\n\ntype GlossVariantProps = StyledVariantProps<typeof StyledAccordionItem>;\n\nexport interface Props {\n title: ConceptTitleDTO;\n glossData?: GlossDataDTO;\n audio?: {\n title: string;\n src?: string;\n };\n exampleIds?: string;\n exampleLangs?: string;\n}\n\nexport const Gloss = ({ title, glossData, audio, exampleIds, exampleLangs, variant }: Props & GlossVariantProps) => {\n const { t } = useTranslation();\n\n const parsedTitle = useMemo(() => parse(title.htmlTitle), [title.htmlTitle]);\n\n const filteredExamples = useMemo(\n () => getFilteredExamples(glossData, exampleIds, exampleLangs),\n [exampleIds, exampleLangs, glossData],\n );\n\n if (!glossData) return null;\n\n return (\n <AccordionRoot multiple variant=\"clean\">\n <StyledAccordionItem value=\"gloss\" variant={variant}>\n <Container>\n <TextWrapper>\n <Text textStyle=\"label.medium\" fontWeight=\"bold\" asChild consumeCss lang={glossData.originalLanguage}>\n <span>{glossData.gloss}</span>\n </Text>\n {!!glossData.transcriptions.traditional && (\n <Text textStyle=\"label.medium\" asChild consumeCss>\n <span\n key={t(\"gloss.transcriptions.traditional\")}\n aria-label={t(\"gloss.transcriptions.traditional\")}\n lang={glossData.originalLanguage}\n >\n {glossData.transcriptions.traditional}\n </span>\n </Text>\n )}\n {!!glossData.transcriptions.pinyin && (\n <Text textStyle=\"label.medium\" asChild consumeCss>\n <span\n data-pinyin=\"\"\n key={t(\"gloss.transcriptions.pinyin\")}\n aria-label={t(\"gloss.transcriptions.pinyin\")}\n lang={glossData.originalLanguage}\n >\n {glossData.transcriptions.pinyin}\n </span>\n </Text>\n )}\n {!!glossData.wordClass && (\n <Text textStyle=\"label.medium\" asChild consumeCss>\n <span aria-label={t(\"gloss.wordClass\")}>\n {glossData.wordClass.map((wc) => t(`wordClass.${wc}`).toLowerCase()).join(\" / \")}\n </span>\n </Text>\n )}\n </TextWrapper>\n {!!audio?.src && <SpeechControl src={audio.src} title={audio.title} type=\"gloss\" />}\n </Container>\n <StyledContainer>\n <Text textStyle=\"label.medium\" asChild consumeCss>\n <span lang={title.language}>{parsedTitle}</span>\n </Text>\n {!!filteredExamples.length && (\n <AccordionItemTrigger asChild>\n <IconButton variant=\"tertiary\" aria-label={t(\"gloss.showExamples\")} title={t(\"gloss.showExamples\")}>\n <AccordionItemIndicator asChild>\n <ArrowDownShortLine size=\"medium\" />\n </AccordionItemIndicator>\n </IconButton>\n </AccordionItemTrigger>\n )}\n </StyledContainer>\n <StyledAccordionItemContent>\n {filteredExamples.map((examples, index) => (\n <GlossExample\n key={`gloss-example-${index}`}\n examples={examples}\n originalLanguage={glossData.originalLanguage}\n />\n ))}\n </StyledAccordionItemContent>\n </StyledAccordionItem>\n </AccordionRoot>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Gloss.mjs","names":["AccordionItemTrigger"],"sources":["../../src/Gloss/Gloss.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { AccordionItemTrigger } from \"@ark-ui/react\";\nimport { ArrowDownShortLine } from \"@ndla/icons\";\nimport {\n AccordionItem,\n AccordionItemContent,\n AccordionItemIndicator,\n AccordionRoot,\n IconButton,\n Text,\n} from \"@ndla/primitives\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { StyledVariantProps } from \"@ndla/styled-system/types\";\nimport type { ConceptTitleDTO, GlossDataDTO, GlossExampleDTO } from \"@ndla/types-backend/concept-api\";\nimport parse from \"html-react-parser\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { SpeechControl } from \"../AudioPlayer/SpeechControl\";\nimport { GlossExample } from \"./GlossExample\";\n\n// TODO: Figure out padding between bordered and simple variant.\n// The design says that the content above the accordion content should have enough padding to align with the accordion content.\n// When a gloss is bordered there's way too much padding.\n\nconst getFilteredExamples = (\n glossData: GlossDataDTO | undefined,\n exampleIds: string | undefined,\n exampleLangs: string | undefined,\n): GlossExampleDTO[][] => {\n if (exampleIds !== undefined || exampleLangs !== undefined) {\n const exampleIdsList = exampleIds?.toString()?.split(\",\") ?? [];\n const exampleLangsList = exampleLangs?.split(\",\") ?? [];\n\n const filteredExamples =\n glossData?.examples?.map((examples, i) => {\n if (exampleIdsList.includes(i.toString())) {\n return examples.filter((e) => exampleLangsList.includes(e.language));\n }\n return [];\n }) ?? [];\n const examplesWithoutEmpty = filteredExamples.filter((el) => !!el.length);\n return examplesWithoutEmpty;\n }\n return glossData?.examples ?? [];\n};\n\nconst Container = styled(\"div\", {\n base: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n },\n});\n\nconst TextWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n gap: \"small\",\n },\n});\n\nconst StyledAccordionItemContent = styled(AccordionItemContent, {\n base: {\n paddingInline: \"0\",\n },\n});\n\nconst StyledContainer = styled(Container, {\n base: {\n marginBlockStart: \"3xsmall\",\n },\n});\n\nconst StyledAccordionItem = styled(AccordionItem, {\n base: {\n paddingBlock: \"small\",\n paddingInline: \"medium\",\n },\n defaultVariants: {\n variant: \"simple\",\n },\n variants: {\n variant: {\n simple: {},\n bordered: {\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n borderRadius: \"xsmall\",\n },\n },\n },\n});\n\ntype GlossVariantProps = StyledVariantProps<typeof StyledAccordionItem>;\n\nexport interface Props {\n title: ConceptTitleDTO;\n glossData?: GlossDataDTO;\n audio?: {\n title: string;\n src?: string;\n };\n exampleIds?: string;\n exampleLangs?: string;\n}\n\nexport const Gloss = ({ title, glossData, audio, exampleIds, exampleLangs, variant }: Props & GlossVariantProps) => {\n const { t } = useTranslation();\n\n const parsedTitle = useMemo(() => parse(title.htmlTitle), [title.htmlTitle]);\n\n const filteredExamples = useMemo(\n () => getFilteredExamples(glossData, exampleIds, exampleLangs),\n [exampleIds, exampleLangs, glossData],\n );\n\n if (!glossData) return null;\n\n return (\n <AccordionRoot multiple variant=\"clean\">\n <StyledAccordionItem value=\"gloss\" variant={variant}>\n <Container>\n <TextWrapper>\n <Text textStyle=\"label.medium\" fontWeight=\"bold\" asChild consumeCss lang={glossData.originalLanguage}>\n <span>{glossData.gloss}</span>\n </Text>\n {!!glossData.transcriptions.traditional && (\n <Text textStyle=\"label.medium\" asChild consumeCss>\n <span\n key={t(\"gloss.transcriptions.traditional\")}\n aria-label={t(\"gloss.transcriptions.traditional\")}\n lang={glossData.originalLanguage}\n >\n {glossData.transcriptions.traditional}\n </span>\n </Text>\n )}\n {!!glossData.transcriptions.pinyin && (\n <Text textStyle=\"label.medium\" asChild consumeCss>\n <span\n data-pinyin=\"\"\n key={t(\"gloss.transcriptions.pinyin\")}\n aria-label={t(\"gloss.transcriptions.pinyin\")}\n lang={glossData.originalLanguage}\n >\n {glossData.transcriptions.pinyin}\n </span>\n </Text>\n )}\n {!!glossData.wordClass && (\n <Text textStyle=\"label.medium\" asChild consumeCss>\n <span aria-label={t(\"gloss.wordClass\")}>\n {glossData.wordClass.map((wc) => t(`wordClass.${wc}`).toLowerCase()).join(\" / \")}\n </span>\n </Text>\n )}\n </TextWrapper>\n {!!audio?.src && <SpeechControl src={audio.src} title={audio.title} />}\n </Container>\n <StyledContainer>\n <Text textStyle=\"label.medium\" asChild consumeCss>\n <span lang={title.language}>{parsedTitle}</span>\n </Text>\n {!!filteredExamples.length && (\n <AccordionItemTrigger asChild>\n <IconButton variant=\"tertiary\" aria-label={t(\"gloss.showExamples\")} title={t(\"gloss.showExamples\")}>\n <AccordionItemIndicator asChild>\n <ArrowDownShortLine size=\"medium\" />\n </AccordionItemIndicator>\n </IconButton>\n </AccordionItemTrigger>\n )}\n </StyledContainer>\n <StyledAccordionItemContent>\n {filteredExamples.map((examples, index) => (\n <GlossExample\n key={`gloss-example-${index}`}\n examples={examples}\n originalLanguage={glossData.originalLanguage}\n />\n ))}\n </StyledAccordionItemContent>\n </StyledAccordionItem>\n </AccordionRoot>\n );\n};\n"],"mappings":"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"}
package/es/Grid/Grid.mjs CHANGED
@@ -57,11 +57,10 @@ const StyledGridItem = styled("div", {
57
57
  } } }
58
58
  });
59
59
  const Grid = ({ columns, border, children, ...rest }) => {
60
- const amountOfColumns = children?.length === 3 ? "3" : columns;
61
60
  return /* @__PURE__ */ jsx(GridContainer, {
62
61
  "data-embed-type": "grid",
63
62
  border,
64
- columns: amountOfColumns,
63
+ columns: children?.length === 3 ? "3" : columns,
65
64
  ...rest,
66
65
  children
67
66
  });
@@ -1 +1 @@
1
- {"version":3,"file":"Grid.mjs","names":[],"sources":["../../src/Grid/Grid.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { StyledVariantProps } from \"@ndla/styled-system/types\";\nimport { type ComponentProps, type ReactNode } from \"react\";\n\nconst GridContainer = styled(\"div\", {\n base: {\n display: \"grid\",\n justifyContent: \"center\",\n borderRadius: \"xsmall\",\n gridRowGap: \"large\",\n gridColumnGap: \"medium\",\n width: \"100%\",\n minWidth: \"surface.xxsmall\",\n gridTemplateColumns: \"repeat(2, minmax(0, 1fr))\",\n\n \"& div[data-embed-type='pitch']\": {\n height: \"100%\",\n \"& > :last-child\": {\n marginTop: \"auto\",\n },\n },\n tabletDown: {\n gridTemplateColumns: \"repeat(1, minmax(0, 1fr))\",\n },\n tabletToDesktop: {\n gridTemplateColumns: \"repeat(2, minmax(0, 1fr))\",\n \"& > div:nth-child(3):last-child\": {\n display: \"flex\",\n flexFlow: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gridColumn: \"span 2\",\n },\n },\n },\n variants: {\n columns: {\n \"2\": {},\n \"2x2\": {},\n \"3\": { desktop: { gridTemplateColumns: \"repeat(3, minmax(0, 1fr))\" } },\n \"4\": { desktop: { gridTemplateColumns: \"repeat(4, minmax(0, 1fr))\" } },\n },\n border: {\n lightBlue: {\n padding: \"xsmall\",\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n },\n },\n});\n\nconst StyledGridItem = styled(\"div\", {\n base: {\n padding: \"medium\",\n },\n variants: {\n border: {\n true: {\n outline: \"1px solid\",\n outlineColor: \"stroke.subtle\",\n },\n },\n },\n});\n\ntype GridVariantProps = NonNullable<StyledVariantProps<typeof GridContainer>>;\n\nexport interface GridProps extends ComponentProps<\"div\">, GridVariantProps {\n children?: ReactNode[];\n columns: NonNullable<GridVariantProps[\"columns\"]>;\n}\n\ntype GridItemVariantProps = NonNullable<StyledVariantProps<typeof StyledGridItem>>;\n\nexport interface GridItemProps extends ComponentProps<\"div\">, GridItemVariantProps {}\n\nexport const Grid = ({ columns, border, children, ...rest }: GridProps) => {\n const amountOfColumns = children?.length === 3 ? \"3\" : columns;\n\n return (\n <GridContainer data-embed-type=\"grid\" border={border} columns={amountOfColumns} {...rest}>\n {children}\n </GridContainer>\n );\n};\n\nexport const GridItem = ({ border, children, ...rest }: GridItemProps) => {\n return (\n <StyledGridItem data-embed-type=\"grid-cell\" border={border} {...rest}>\n {children}\n </StyledGridItem>\n );\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,gBAAgB,OAAO,OAAO;CAClC,MAAM;EACJ,SAAS;EACT,gBAAgB;EAChB,cAAc;EACd,YAAY;EACZ,eAAe;EACf,OAAO;EACP,UAAU;EACV,qBAAqB;EAErB,kCAAkC;GAChC,QAAQ;GACR,mBAAmB,EACjB,WAAW,QACZ;GACF;EACD,YAAY,EACV,qBAAqB,6BACtB;EACD,iBAAiB;GACf,qBAAqB;GACrB,mCAAmC;IACjC,SAAS;IACT,UAAU;IACV,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACb;GACF;EACF;CACD,UAAU;EACR,SAAS;GACP,KAAK,EAAE;GACP,OAAO,EAAE;GACT,KAAK,EAAE,SAAS,EAAE,qBAAqB,6BAA6B,EAAE;GACtE,KAAK,EAAE,SAAS,EAAE,qBAAqB,6BAA6B,EAAE;GACvE;EACD,QAAQ,EACN,WAAW;GACT,SAAS;GACT,QAAQ;GACR,aAAa;GACd,EACF;EACF;CACF,CAAC;AAEF,MAAM,iBAAiB,OAAO,OAAO;CACnC,MAAM,EACJ,SAAS,UACV;CACD,UAAU,EACR,QAAQ,EACN,MAAM;EACJ,SAAS;EACT,cAAc;EACf,EACF,EACF;CACF,CAAC;AAaF,MAAa,QAAQ,EAAE,SAAS,QAAQ,UAAU,GAAG,WAAsB;CACzE,MAAM,kBAAkB,UAAU,WAAW,IAAI,MAAM;AAEvD,QACE,oBAAC,eAAD;EAAe,mBAAgB;EAAe;EAAQ,SAAS;EAAiB,GAAI;EACjF;EACa,CAAA;;AAIpB,MAAa,YAAY,EAAE,QAAQ,UAAU,GAAG,WAA0B;AACxE,QACE,oBAAC,gBAAD;EAAgB,mBAAgB;EAAoB;EAAQ,GAAI;EAC7D;EACc,CAAA"}
1
+ {"version":3,"file":"Grid.mjs","names":[],"sources":["../../src/Grid/Grid.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { StyledVariantProps } from \"@ndla/styled-system/types\";\nimport { type ComponentProps, type ReactNode } from \"react\";\n\nconst GridContainer = styled(\"div\", {\n base: {\n display: \"grid\",\n justifyContent: \"center\",\n borderRadius: \"xsmall\",\n gridRowGap: \"large\",\n gridColumnGap: \"medium\",\n width: \"100%\",\n minWidth: \"surface.xxsmall\",\n gridTemplateColumns: \"repeat(2, minmax(0, 1fr))\",\n\n \"& div[data-embed-type='pitch']\": {\n height: \"100%\",\n \"& > :last-child\": {\n marginTop: \"auto\",\n },\n },\n tabletDown: {\n gridTemplateColumns: \"repeat(1, minmax(0, 1fr))\",\n },\n tabletToDesktop: {\n gridTemplateColumns: \"repeat(2, minmax(0, 1fr))\",\n \"& > div:nth-child(3):last-child\": {\n display: \"flex\",\n flexFlow: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gridColumn: \"span 2\",\n },\n },\n },\n variants: {\n columns: {\n \"2\": {},\n \"2x2\": {},\n \"3\": { desktop: { gridTemplateColumns: \"repeat(3, minmax(0, 1fr))\" } },\n \"4\": { desktop: { gridTemplateColumns: \"repeat(4, minmax(0, 1fr))\" } },\n },\n border: {\n lightBlue: {\n padding: \"xsmall\",\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n },\n },\n },\n});\n\nconst StyledGridItem = styled(\"div\", {\n base: {\n padding: \"medium\",\n },\n variants: {\n border: {\n true: {\n outline: \"1px solid\",\n outlineColor: \"stroke.subtle\",\n },\n },\n },\n});\n\ntype GridVariantProps = NonNullable<StyledVariantProps<typeof GridContainer>>;\n\nexport interface GridProps extends ComponentProps<\"div\">, GridVariantProps {\n children?: ReactNode[];\n columns: NonNullable<GridVariantProps[\"columns\"]>;\n}\n\ntype GridItemVariantProps = NonNullable<StyledVariantProps<typeof StyledGridItem>>;\n\nexport interface GridItemProps extends ComponentProps<\"div\">, GridItemVariantProps {}\n\nexport const Grid = ({ columns, border, children, ...rest }: GridProps) => {\n const amountOfColumns = children?.length === 3 ? \"3\" : columns;\n\n return (\n <GridContainer data-embed-type=\"grid\" border={border} columns={amountOfColumns} {...rest}>\n {children}\n </GridContainer>\n );\n};\n\nexport const GridItem = ({ border, children, ...rest }: GridItemProps) => {\n return (\n <StyledGridItem data-embed-type=\"grid-cell\" border={border} {...rest}>\n {children}\n </StyledGridItem>\n );\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,gBAAgB,OAAO,OAAO;CAClC,MAAM;EACJ,SAAS;EACT,gBAAgB;EAChB,cAAc;EACd,YAAY;EACZ,eAAe;EACf,OAAO;EACP,UAAU;EACV,qBAAqB;EAErB,kCAAkC;GAChC,QAAQ;GACR,mBAAmB,EACjB,WAAW,QACZ;GACF;EACD,YAAY,EACV,qBAAqB,6BACtB;EACD,iBAAiB;GACf,qBAAqB;GACrB,mCAAmC;IACjC,SAAS;IACT,UAAU;IACV,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACb;GACF;EACF;CACD,UAAU;EACR,SAAS;GACP,KAAK,EAAE;GACP,OAAO,EAAE;GACT,KAAK,EAAE,SAAS,EAAE,qBAAqB,6BAA6B,EAAE;GACtE,KAAK,EAAE,SAAS,EAAE,qBAAqB,6BAA6B,EAAE;GACvE;EACD,QAAQ,EACN,WAAW;GACT,SAAS;GACT,QAAQ;GACR,aAAa;GACd,EACF;EACF;CACF,CAAC;AAEF,MAAM,iBAAiB,OAAO,OAAO;CACnC,MAAM,EACJ,SAAS,UACV;CACD,UAAU,EACR,QAAQ,EACN,MAAM;EACJ,SAAS;EACT,cAAc;EACf,EACF,EACF;CACF,CAAC;AAaF,MAAa,QAAQ,EAAE,SAAS,QAAQ,UAAU,GAAG,WAAsB;AAGzE,QACE,oBAAC,eAAD;EAAe,mBAAgB;EAAe;EAAQ,SAHhC,UAAU,WAAW,IAAI,MAAM;EAG2B,GAAI;EACjF;EACa,CAAA;;AAIpB,MAAa,YAAY,EAAE,QAAQ,UAAU,GAAG,WAA0B;AACxE,QACE,oBAAC,gBAAD;EAAgB,mBAAgB;EAAoB;EAAQ,GAAI;EAC7D;EACc,CAAA"}
@@ -3,9 +3,11 @@ import { Heading } from "@ndla/primitives";
3
3
  import { styled } from "@ndla/styled-system/jsx";
4
4
  import { useMemo } from "react";
5
5
  import parse from "html-react-parser";
6
+ import { useTranslation } from "react-i18next";
6
7
  import { ArrowRightLine, CalendarLine } from "@ndla/icons";
7
8
  import { SafeLink } from "@ndla/safelink";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
+ import { toIntlLanguage } from "@ndla/util";
9
11
  //#region src/LinkBlock/LinkBlock.tsx
10
12
  /**
11
13
  * Copyright (c) 2023-present, NDLA.
@@ -49,16 +51,21 @@ const StyledDateContainer = styled("div", { base: {
49
51
  } });
50
52
  const StyledCalendarEd = styled(CalendarLine, { base: { color: "icon.strong" } });
51
53
  const LinkBlock = ({ title, articleLanguage, date, url, path }) => {
54
+ const { i18n } = useTranslation();
52
55
  const href = getPossiblyRelativeUrl(url, path);
53
56
  const formattedDate = useMemo(() => {
54
57
  if (!date) return null;
55
- return new Intl.DateTimeFormat(articleLanguage, {
58
+ return new Intl.DateTimeFormat(toIntlLanguage(articleLanguage ?? i18n.language), {
56
59
  timeZone: "CET",
57
60
  day: "2-digit",
58
61
  month: "long",
59
62
  year: "numeric"
60
63
  }).format(new Date(date));
61
- }, [date, articleLanguage]);
64
+ }, [
65
+ date,
66
+ articleLanguage,
67
+ i18n.language
68
+ ]);
62
69
  return /* @__PURE__ */ jsxs(StyledSafeLink, {
63
70
  to: href,
64
71
  "data-embed-type": "link-block",
@@ -1 +1 @@
1
- {"version":3,"file":"LinkBlock.mjs","names":[],"sources":["../../src/LinkBlock/LinkBlock.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { ArrowRightLine, CalendarLine } from \"@ndla/icons\";\nimport { Heading } from \"@ndla/primitives\";\nimport { SafeLink } from \"@ndla/safelink\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { LinkBlockEmbedData } from \"@ndla/types-embed\";\nimport parse from \"html-react-parser\";\nimport { useMemo } from \"react\";\nimport { getPossiblyRelativeUrl } from \"../utils/relativeUrl\";\n\nconst InfoWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n },\n});\n\nconst StyledSafeLink = styled(SafeLink, {\n base: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n background: \"surface.default\",\n padding: \"medium\",\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n borderRadius: \"xsmall\",\n \"& h3\": {\n textDecoration: \"underline\",\n },\n \"& [data-forward]\": {\n transitionProperty: \"width, height\",\n transitionTimingFunction: \"ease-in-out\",\n transitionDuration: \"fast\",\n },\n _hover: {\n \"& h3\": {\n textDecoration: \"none\",\n },\n \"& [data-forward]\": {\n width: \"large\",\n height: \"large\",\n },\n },\n },\n});\n\nconst StyledDateContainer = styled(\"div\", {\n base: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"xxsmall\",\n },\n});\n\nconst StyledCalendarEd = styled(CalendarLine, {\n base: {\n color: \"icon.strong\",\n },\n});\n\ninterface Props extends Omit<LinkBlockEmbedData, \"resource\"> {\n path?: string;\n articleLanguage?: string;\n}\n\nexport const LinkBlock = ({ title, articleLanguage, date, url, path }: Props) => {\n const href = getPossiblyRelativeUrl(url, path);\n const formattedDate = useMemo(() => {\n if (!date) return null;\n return new Intl.DateTimeFormat(articleLanguage, {\n timeZone: \"CET\",\n day: \"2-digit\",\n month: \"long\",\n year: \"numeric\",\n }).format(new Date(date));\n }, [date, articleLanguage]);\n return (\n <StyledSafeLink to={href} data-embed-type=\"link-block\">\n <InfoWrapper>\n <Heading asChild consumeCss textStyle=\"title.medium\">\n <h3 data-heading>{parse(title)}</h3>\n </Heading>\n {!!date && (\n <StyledDateContainer>\n <StyledCalendarEd />\n {formattedDate}\n </StyledDateContainer>\n )}\n </InfoWrapper>\n <ArrowRightLine data-forward />\n </StyledSafeLink>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAM,cAAc,OAAO,OAAO,EAChC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACN,EACF,CAAC;AAEF,MAAM,iBAAiB,OAAO,UAAU,EACtC,MAAM;CACJ,SAAS;CACT,gBAAgB;CAChB,YAAY;CACZ,YAAY;CACZ,SAAS;CACT,QAAQ;CACR,aAAa;CACb,cAAc;CACd,QAAQ,EACN,gBAAgB,aACjB;CACD,oBAAoB;EAClB,oBAAoB;EACpB,0BAA0B;EAC1B,oBAAoB;EACrB;CACD,QAAQ;EACN,QAAQ,EACN,gBAAgB,QACjB;EACD,oBAAoB;GAClB,OAAO;GACP,QAAQ;GACT;EACF;CACF,EACF,CAAC;AAEF,MAAM,sBAAsB,OAAO,OAAO,EACxC,MAAM;CACJ,SAAS;CACT,YAAY;CACZ,KAAK;CACN,EACF,CAAC;AAEF,MAAM,mBAAmB,OAAO,cAAc,EAC5C,MAAM,EACJ,OAAO,eACR,EACF,CAAC;AAOF,MAAa,aAAa,EAAE,OAAO,iBAAiB,MAAM,KAAK,WAAkB;CAC/E,MAAM,OAAO,uBAAuB,KAAK,KAAK;CAC9C,MAAM,gBAAgB,cAAc;AAClC,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,IAAI,KAAK,eAAe,iBAAiB;GAC9C,UAAU;GACV,KAAK;GACL,OAAO;GACP,MAAM;GACP,CAAC,CAAC,OAAO,IAAI,KAAK,KAAK,CAAC;IACxB,CAAC,MAAM,gBAAgB,CAAC;AAC3B,QACE,qBAAC,gBAAD;EAAgB,IAAI;EAAM,mBAAgB;YAA1C,CACE,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,SAAD;GAAS,SAAA;GAAQ,YAAA;GAAW,WAAU;aACpC,oBAAC,MAAD;IAAI,gBAAA;cAAc,MAAM,MAAM;IAAM,CAAA;GAC5B,CAAA,EACT,CAAC,CAAC,QACD,qBAAC,qBAAD,EAAA,UAAA,CACE,oBAAC,kBAAD,EAAoB,CAAA,EACnB,cACmB,EAAA,CAAA,CAEZ,EAAA,CAAA,EACd,oBAAC,gBAAD,EAAgB,gBAAA,MAAe,CAAA,CAChB"}
1
+ {"version":3,"file":"LinkBlock.mjs","names":[],"sources":["../../src/LinkBlock/LinkBlock.tsx"],"sourcesContent":["/**\n * Copyright (c) 2023-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { ArrowRightLine, CalendarLine } from \"@ndla/icons\";\nimport { Heading } from \"@ndla/primitives\";\nimport { SafeLink } from \"@ndla/safelink\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport type { LinkBlockEmbedData } from \"@ndla/types-embed\";\nimport { toIntlLanguage } from \"@ndla/util\";\nimport parse from \"html-react-parser\";\nimport { useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { getPossiblyRelativeUrl } from \"../utils/relativeUrl\";\n\nconst InfoWrapper = styled(\"div\", {\n base: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"xsmall\",\n },\n});\n\nconst StyledSafeLink = styled(SafeLink, {\n base: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n background: \"surface.default\",\n padding: \"medium\",\n border: \"1px solid\",\n borderColor: \"stroke.subtle\",\n borderRadius: \"xsmall\",\n \"& h3\": {\n textDecoration: \"underline\",\n },\n \"& [data-forward]\": {\n transitionProperty: \"width, height\",\n transitionTimingFunction: \"ease-in-out\",\n transitionDuration: \"fast\",\n },\n _hover: {\n \"& h3\": {\n textDecoration: \"none\",\n },\n \"& [data-forward]\": {\n width: \"large\",\n height: \"large\",\n },\n },\n },\n});\n\nconst StyledDateContainer = styled(\"div\", {\n base: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"xxsmall\",\n },\n});\n\nconst StyledCalendarEd = styled(CalendarLine, {\n base: {\n color: \"icon.strong\",\n },\n});\n\ninterface Props extends Omit<LinkBlockEmbedData, \"resource\"> {\n path?: string;\n articleLanguage?: string;\n}\n\nexport const LinkBlock = ({ title, articleLanguage, date, url, path }: Props) => {\n const { i18n } = useTranslation();\n const href = getPossiblyRelativeUrl(url, path);\n const formattedDate = useMemo(() => {\n if (!date) return null;\n return new Intl.DateTimeFormat(toIntlLanguage(articleLanguage ?? i18n.language), {\n timeZone: \"CET\",\n day: \"2-digit\",\n month: \"long\",\n year: \"numeric\",\n }).format(new Date(date));\n }, [date, articleLanguage, i18n.language]);\n return (\n <StyledSafeLink to={href} data-embed-type=\"link-block\">\n <InfoWrapper>\n <Heading asChild consumeCss textStyle=\"title.medium\">\n <h3 data-heading>{parse(title)}</h3>\n </Heading>\n {!!date && (\n <StyledDateContainer>\n <StyledCalendarEd />\n {formattedDate}\n </StyledDateContainer>\n )}\n </InfoWrapper>\n <ArrowRightLine data-forward />\n </StyledSafeLink>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,MAAM,cAAc,OAAO,OAAO,EAChC,MAAM;CACJ,SAAS;CACT,eAAe;CACf,KAAK;CACN,EACF,CAAC;AAEF,MAAM,iBAAiB,OAAO,UAAU,EACtC,MAAM;CACJ,SAAS;CACT,gBAAgB;CAChB,YAAY;CACZ,YAAY;CACZ,SAAS;CACT,QAAQ;CACR,aAAa;CACb,cAAc;CACd,QAAQ,EACN,gBAAgB,aACjB;CACD,oBAAoB;EAClB,oBAAoB;EACpB,0BAA0B;EAC1B,oBAAoB;EACrB;CACD,QAAQ;EACN,QAAQ,EACN,gBAAgB,QACjB;EACD,oBAAoB;GAClB,OAAO;GACP,QAAQ;GACT;EACF;CACF,EACF,CAAC;AAEF,MAAM,sBAAsB,OAAO,OAAO,EACxC,MAAM;CACJ,SAAS;CACT,YAAY;CACZ,KAAK;CACN,EACF,CAAC;AAEF,MAAM,mBAAmB,OAAO,cAAc,EAC5C,MAAM,EACJ,OAAO,eACR,EACF,CAAC;AAOF,MAAa,aAAa,EAAE,OAAO,iBAAiB,MAAM,KAAK,WAAkB;CAC/E,MAAM,EAAE,SAAS,gBAAgB;CACjC,MAAM,OAAO,uBAAuB,KAAK,KAAK;CAC9C,MAAM,gBAAgB,cAAc;AAClC,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,IAAI,KAAK,eAAe,eAAe,mBAAmB,KAAK,SAAS,EAAE;GAC/E,UAAU;GACV,KAAK;GACL,OAAO;GACP,MAAM;GACP,CAAC,CAAC,OAAO,IAAI,KAAK,KAAK,CAAC;IACxB;EAAC;EAAM;EAAiB,KAAK;EAAS,CAAC;AAC1C,QACE,qBAAC,gBAAD;EAAgB,IAAI;EAAM,mBAAgB;YAA1C,CACE,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,SAAD;GAAS,SAAA;GAAQ,YAAA;GAAW,WAAU;aACpC,oBAAC,MAAD;IAAI,gBAAA;cAAc,MAAM,MAAM;IAAM,CAAA;GAC5B,CAAA,EACT,CAAC,CAAC,QACD,qBAAC,qBAAD,EAAA,UAAA,CACE,oBAAC,kBAAD,EAAoB,CAAA,EACnB,cACmB,EAAA,CAAA,CAEZ,EAAA,CAAA,EACd,oBAAC,gBAAD,EAAgB,gBAAA,MAAe,CAAA,CAChB"}
@@ -27,7 +27,6 @@ const StyledCardImage = styled(CardImage, { base: {
27
27
  height: "unset"
28
28
  } });
29
29
  const Pitch = ({ title, url, metaImage, path, description }) => {
30
- const href = getPossiblyRelativeUrl(url, path);
31
30
  return /* @__PURE__ */ jsx(StyledCardRoot, {
32
31
  nonInteractive: true,
33
32
  "data-embed-type": "pitch",
@@ -39,7 +38,7 @@ const Pitch = ({ title, url, metaImage, path, description }) => {
39
38
  asChild: true,
40
39
  consumeCss: true,
41
40
  children: /* @__PURE__ */ jsx(SafeLink, {
42
- to: href,
41
+ to: getPossiblyRelativeUrl(url, path),
43
42
  unstyled: true,
44
43
  css: linkOverlay.raw(),
45
44
  children: parse(title)
@@ -1 +1 @@
1
- {"version":3,"file":"Pitch.mjs","names":[],"sources":["../../src/Pitch/Pitch.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { CardHeading, CardImage, CardRoot, Text } from \"@ndla/primitives\";\nimport { SafeLink } from \"@ndla/safelink\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport { linkOverlay } from \"@ndla/styled-system/patterns\";\nimport parse from \"html-react-parser\";\nimport { getPossiblyRelativeUrl } from \"../utils/relativeUrl\";\n\nexport interface Props {\n title: string;\n url: string;\n description?: string;\n metaImage: {\n url: string;\n alt: string;\n };\n path?: string;\n}\n\nconst StyledCardHeading = styled(CardHeading, {\n base: {\n paddingBlockStart: \"medium\",\n },\n});\n\nconst StyledText = styled(Text, {\n base: {\n paddingBlockEnd: \"medium\",\n },\n});\n\nconst StyledCardRoot = styled(CardRoot, {\n base: {\n outline: \"0px\",\n boxShadow: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"small\",\n },\n});\n\nconst StyledCardImage = styled(CardImage, {\n base: {\n aspectRatio: \"16/9\",\n height: \"unset\",\n },\n});\n\nexport const Pitch = ({ title, url, metaImage, path, description }: Props) => {\n const href = getPossiblyRelativeUrl(url, path);\n\n return (\n <StyledCardRoot nonInteractive data-embed-type=\"pitch\" asChild consumeCss>\n <div>\n <StyledCardHeading textStyle=\"heading.small\" asChild consumeCss>\n <SafeLink to={href} unstyled css={linkOverlay.raw()}>\n {parse(title)}\n </SafeLink>\n </StyledCardHeading>\n {!!description && (\n <StyledText textStyle=\"body.xlarge\" asChild consumeCss>\n <div>{parse(description)}</div>\n </StyledText>\n )}\n <StyledCardImage\n variant=\"rounded\"\n src={metaImage.url}\n alt={metaImage.alt}\n sizes=\"480px\"\n fallbackWidth={300}\n width={550}\n height={310}\n />\n </div>\n </StyledCardRoot>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AA0BA,MAAM,oBAAoB,OAAO,aAAa,EAC5C,MAAM,EACJ,mBAAmB,UACpB,EACF,CAAC;AAEF,MAAM,aAAa,OAAO,MAAM,EAC9B,MAAM,EACJ,iBAAiB,UAClB,EACF,CAAC;AAEF,MAAM,iBAAiB,OAAO,UAAU,EACtC,MAAM;CACJ,SAAS;CACT,WAAW;CACX,SAAS;CACT,eAAe;CACf,KAAK;CACN,EACF,CAAC;AAEF,MAAM,kBAAkB,OAAO,WAAW,EACxC,MAAM;CACJ,aAAa;CACb,QAAQ;CACT,EACF,CAAC;AAEF,MAAa,SAAS,EAAE,OAAO,KAAK,WAAW,MAAM,kBAAyB;CAC5E,MAAM,OAAO,uBAAuB,KAAK,KAAK;AAE9C,QACE,oBAAC,gBAAD;EAAgB,gBAAA;EAAe,mBAAgB;EAAQ,SAAA;EAAQ,YAAA;YAC7D,qBAAC,OAAD,EAAA,UAAA;GACE,oBAAC,mBAAD;IAAmB,WAAU;IAAgB,SAAA;IAAQ,YAAA;cACnD,oBAAC,UAAD;KAAU,IAAI;KAAM,UAAA;KAAS,KAAK,YAAY,KAAK;eAChD,MAAM,MAAM;KACJ,CAAA;IACO,CAAA;GACnB,CAAC,CAAC,eACD,oBAAC,YAAD;IAAY,WAAU;IAAc,SAAA;IAAQ,YAAA;cAC1C,oBAAC,OAAD,EAAA,UAAM,MAAM,YAAY,EAAO,CAAA;IACpB,CAAA;GAEf,oBAAC,iBAAD;IACE,SAAQ;IACR,KAAK,UAAU;IACf,KAAK,UAAU;IACf,OAAM;IACN,eAAe;IACf,OAAO;IACP,QAAQ;IACR,CAAA;GACE,EAAA,CAAA;EACS,CAAA"}
1
+ {"version":3,"file":"Pitch.mjs","names":[],"sources":["../../src/Pitch/Pitch.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024-present, NDLA.\n *\n * This source code is licensed under the GPLv3 license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport { CardHeading, CardImage, CardRoot, Text } from \"@ndla/primitives\";\nimport { SafeLink } from \"@ndla/safelink\";\nimport { styled } from \"@ndla/styled-system/jsx\";\nimport { linkOverlay } from \"@ndla/styled-system/patterns\";\nimport parse from \"html-react-parser\";\nimport { getPossiblyRelativeUrl } from \"../utils/relativeUrl\";\n\nexport interface Props {\n title: string;\n url: string;\n description?: string;\n metaImage: {\n url: string;\n alt: string;\n };\n path?: string;\n}\n\nconst StyledCardHeading = styled(CardHeading, {\n base: {\n paddingBlockStart: \"medium\",\n },\n});\n\nconst StyledText = styled(Text, {\n base: {\n paddingBlockEnd: \"medium\",\n },\n});\n\nconst StyledCardRoot = styled(CardRoot, {\n base: {\n outline: \"0px\",\n boxShadow: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"small\",\n },\n});\n\nconst StyledCardImage = styled(CardImage, {\n base: {\n aspectRatio: \"16/9\",\n height: \"unset\",\n },\n});\n\nexport const Pitch = ({ title, url, metaImage, path, description }: Props) => {\n const href = getPossiblyRelativeUrl(url, path);\n\n return (\n <StyledCardRoot nonInteractive data-embed-type=\"pitch\" asChild consumeCss>\n <div>\n <StyledCardHeading textStyle=\"heading.small\" asChild consumeCss>\n <SafeLink to={href} unstyled css={linkOverlay.raw()}>\n {parse(title)}\n </SafeLink>\n </StyledCardHeading>\n {!!description && (\n <StyledText textStyle=\"body.xlarge\" asChild consumeCss>\n <div>{parse(description)}</div>\n </StyledText>\n )}\n <StyledCardImage\n variant=\"rounded\"\n src={metaImage.url}\n alt={metaImage.alt}\n sizes=\"480px\"\n fallbackWidth={300}\n width={550}\n height={310}\n />\n </div>\n </StyledCardRoot>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AA0BA,MAAM,oBAAoB,OAAO,aAAa,EAC5C,MAAM,EACJ,mBAAmB,UACpB,EACF,CAAC;AAEF,MAAM,aAAa,OAAO,MAAM,EAC9B,MAAM,EACJ,iBAAiB,UAClB,EACF,CAAC;AAEF,MAAM,iBAAiB,OAAO,UAAU,EACtC,MAAM;CACJ,SAAS;CACT,WAAW;CACX,SAAS;CACT,eAAe;CACf,KAAK;CACN,EACF,CAAC;AAEF,MAAM,kBAAkB,OAAO,WAAW,EACxC,MAAM;CACJ,aAAa;CACb,QAAQ;CACT,EACF,CAAC;AAEF,MAAa,SAAS,EAAE,OAAO,KAAK,WAAW,MAAM,kBAAyB;AAG5E,QACE,oBAAC,gBAAD;EAAgB,gBAAA;EAAe,mBAAgB;EAAQ,SAAA;EAAQ,YAAA;YAC7D,qBAAC,OAAD,EAAA,UAAA;GACE,oBAAC,mBAAD;IAAmB,WAAU;IAAgB,SAAA;IAAQ,YAAA;cACnD,oBAAC,UAAD;KAAU,IANL,uBAAuB,KAAK,KAAK;KAMlB,UAAA;KAAS,KAAK,YAAY,KAAK;eAChD,MAAM,MAAM;KACJ,CAAA;IACO,CAAA;GACnB,CAAC,CAAC,eACD,oBAAC,YAAD;IAAY,WAAU;IAAc,SAAA;IAAQ,YAAA;cAC1C,oBAAC,OAAD,EAAA,UAAM,MAAM,YAAY,EAAO,CAAA;IACpB,CAAA;GAEf,oBAAC,iBAAD;IACE,SAAQ;IACR,KAAK,UAAU;IACf,KAAK,UAAU;IACf,OAAM;IACN,eAAe;IACf,OAAO;IACP,QAAQ;IACR,CAAA;GACE,EAAA,CAAA;EACS,CAAA"}
package/es/index.mjs CHANGED
@@ -9,6 +9,7 @@ import { IframeEmbed } from "./Embed/IframeEmbed.mjs";
9
9
  import { ImageEmbed, getCrop, getFocalPoint } from "./Embed/ImageEmbed.mjs";
10
10
  import { Concept } from "./Concept/Concept.mjs";
11
11
  import { InlineTriggerButton } from "./Embed/InlineTriggerButton.mjs";
12
+ import { CompactAudioPlayer } from "./AudioPlayer/CompactAudioPlayer.mjs";
12
13
  import { AudioPlayer } from "./AudioPlayer/AudioPlayer.mjs";
13
14
  import { AudioEmbed } from "./Embed/AudioEmbed.mjs";
14
15
  import { FootnoteEmbed } from "./Embed/FootnoteEmbed.mjs";
@@ -54,4 +55,4 @@ import { LinkBlock } from "./LinkBlock/LinkBlock.mjs";
54
55
  import { LinkBlockSection } from "./LinkBlock/LinkBlockSection.mjs";
55
56
  import { ZendeskButton } from "./ZendeskButton/ZendeskButton.mjs";
56
57
  import { messagesEN, messagesNB, messagesNN, messagesSE } from "@ndla/locales";
57
- export { AnchorHeading, ArticleByline, ArticleBylineAccordionItem, ArticleContent, ArticleFootNotes, ArticleFooter, ArticleHGroup, ArticleHeader, ArticleTitle, ArticleWrapper, AudioEmbed, AudioPlayer, BadgesContainer, BlockConcept, Breadcrumb, BrightcoveEmbed, CampaignBlock, CodeBlock, CodeEmbed, Concept, ConceptEmbed, ConceptInlineTriggerButton, ContactBlock, ContentLinkEmbed, CopyrightEmbed, EmbedByline, EmbedWrapper, ExternalEmbed, FactBox, File, FileListElement, FileListEmbed, FileListItem, FileListWrapper, FootnoteEmbed, Gloss, GlossExample, Grid, GridItem, H5pEmbed, HomeBreadcrumb, IframeEmbed, ImageEmbed, InlineConcept, InlineTriggerButton, KeyFigure, LicenseLink, LinkBlock, LinkBlockSection, PdfFile, Pitch, RelatedArticle, RelatedArticleList, RelatedContentEmbed, ResourceBox, TagSelectorClearTrigger, TagSelectorControl, TagSelectorInput, TagSelectorInputBase, TagSelectorItemInput, TagSelectorLabel, TagSelectorRoot, TagSelectorTrigger, UnknownEmbed, UuDisclaimerEmbed, ZendeskButton, codeLanguageOptions, constants, contactBlockBackgrounds, contentTypeMapping, contentTypes, getCrop, getFocalPoint, getPossiblyRelativeUrl, licenseAttributes, messagesEN, messagesNB, messagesNN, messagesSE, resourceEmbedTypeMapping, subjectCategories, subjectTypes, useAudioSearchTranslations, useComboboxTranslations, useDatePickerTranslations, useImageSearchTranslations, usePaginationTranslations, useTagSelectorTranslations, useTagsInputTranslations, useVideoSearchTranslations, wordClass };
58
+ export { AnchorHeading, ArticleByline, ArticleBylineAccordionItem, ArticleContent, ArticleFootNotes, ArticleFooter, ArticleHGroup, ArticleHeader, ArticleTitle, ArticleWrapper, AudioEmbed, AudioPlayer, BadgesContainer, BlockConcept, Breadcrumb, BrightcoveEmbed, CampaignBlock, CodeBlock, CodeEmbed, CompactAudioPlayer, Concept, ConceptEmbed, ConceptInlineTriggerButton, ContactBlock, ContentLinkEmbed, CopyrightEmbed, EmbedByline, EmbedWrapper, ExternalEmbed, FactBox, File, FileListElement, FileListEmbed, FileListItem, FileListWrapper, FootnoteEmbed, Gloss, GlossExample, Grid, GridItem, H5pEmbed, HomeBreadcrumb, IframeEmbed, ImageEmbed, InlineConcept, InlineTriggerButton, KeyFigure, LicenseLink, LinkBlock, LinkBlockSection, PdfFile, Pitch, RelatedArticle, RelatedArticleList, RelatedContentEmbed, ResourceBox, TagSelectorClearTrigger, TagSelectorControl, TagSelectorInput, TagSelectorInputBase, TagSelectorItemInput, TagSelectorLabel, TagSelectorRoot, TagSelectorTrigger, UnknownEmbed, UuDisclaimerEmbed, ZendeskButton, codeLanguageOptions, constants, contactBlockBackgrounds, contentTypeMapping, contentTypes, getCrop, getFocalPoint, getPossiblyRelativeUrl, licenseAttributes, messagesEN, messagesNB, messagesNN, messagesSE, resourceEmbedTypeMapping, subjectCategories, subjectTypes, useAudioSearchTranslations, useComboboxTranslations, useDatePickerTranslations, useImageSearchTranslations, usePaginationTranslations, useTagSelectorTranslations, useTagsInputTranslations, useVideoSearchTranslations, wordClass };
@@ -7,6 +7,7 @@ let react_i18next = require("react-i18next");
7
7
  let _ndla_icons = require("@ndla/icons");
8
8
  let _ndla_safelink = require("@ndla/safelink");
9
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
+ let _ndla_util = require("@ndla/util");
10
11
  let _ark_ui_react = require("@ark-ui/react");
11
12
  //#region src/Article/ArticleByline.tsx
12
13
  /**
@@ -51,7 +52,7 @@ const accordionItemValue = "rulesForUse";
51
52
  const ArticleByline = ({ lang, authors = [], suppliers = [], footnotes, licenseBox, published, displayByline = true, bylineType = "article", bylineSuffix, learningpathCopiedFrom }) => {
52
53
  const { t, i18n } = (0, react_i18next.useTranslation)();
53
54
  const showPrimaryContributors = suppliers.length > 0 || authors.length > 0;
54
- const listFormatter = new Intl.ListFormat(lang ?? i18n.language, {
55
+ const listFormatter = new Intl.ListFormat((0, _ndla_util.toIntlLanguage)(lang ?? i18n.language), {
55
56
  style: "long",
56
57
  type: "conjunction"
57
58
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ArticleByline.js","names":["AccordionRoot","SafeLink","ArticleFootNotes","AccordionItem","Heading","AccordionItemTrigger","AccordionItemIndicator","ArrowDownShortLine","AccordionItemContent"],"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 { useAccordionContext } from \"@ark-ui/react\";\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 { type ReactNode, forwardRef, useCallback, useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { FootNote } from \"../types\";\nimport { ArticleFootNotes } from \"./ArticleFootNotes\";\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 _print: {\n display: \"none\",\n },\n },\n});\n\nconst refRegexp = /note\\d/;\nconst footnotesAccordionId = \"footnotes\";\nconst accordionItemValue = \"rulesForUse\";\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, i18n } = useTranslation();\n\n const showPrimaryContributors = suppliers.length > 0 || authors.length > 0;\n const listFormatter = new Intl.ListFormat(lang ?? i18n.language, { 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 multiple>\n {!!licenseBox && (\n <ArticleBylineAccordionItem value={accordionItemValue} accordionTitle={t(\"article.useContent\")}>\n {licenseBox}\n </ArticleBylineAccordionItem>\n )}\n {!!footnotes?.length && <ArticleBylineFootnotes footnotes={footnotes} />}\n </StyledAccordionRoot>\n )}\n </Wrapper>\n );\n};\n\ninterface ArticleBylineAccordionprops extends AccordionItemProps {\n accordionTitle: ReactNode;\n}\n\ninterface ArticleBylineFootnotesProps {\n footnotes: FootNote[];\n}\n\nexport const ArticleBylineFootnotes = ({ footnotes }: ArticleBylineFootnotesProps) => {\n const { t } = useTranslation();\n const { value, setValue } = useAccordionContext();\n const ref = useRef<HTMLDivElement>(null);\n\n const onHashChange = useCallback(\n (e: HashChangeEvent) => {\n const hash = e.newURL.split(\"#\")[1];\n if (hash?.match(refRegexp) && !value.includes(footnotesAccordionId)) {\n ref.current?.scrollIntoView({ behavior: \"smooth\" });\n setValue([...value, footnotesAccordionId]);\n setTimeout(() => {\n const el = document.getElementById(`${hash}`);\n el?.click();\n el?.focus();\n }, 300);\n }\n },\n [value, setValue],\n );\n\n useEffect(() => {\n window.addEventListener(\"hashchange\", onHashChange);\n return () => window.removeEventListener(\"hashchange\", onHashChange);\n }, [onHashChange]);\n\n return (\n <ArticleBylineAccordionItem ref={ref} value={footnotesAccordionId} accordionTitle={t(\"article.footnotes\")}>\n <ArticleFootNotes footNotes={footnotes} />\n </ArticleBylineAccordionItem>\n );\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
+ {"version":3,"file":"ArticleByline.js","names":["AccordionRoot","SafeLink","ArticleFootNotes","AccordionItem","Heading","AccordionItemTrigger","AccordionItemIndicator","ArrowDownShortLine","AccordionItemContent"],"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 { useAccordionContext } from \"@ark-ui/react\";\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 { toIntlLanguage } from \"@ndla/util\";\nimport { type ReactNode, forwardRef, useCallback, useEffect, useRef } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport type { FootNote } from \"../types\";\nimport { ArticleFootNotes } from \"./ArticleFootNotes\";\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 _print: {\n display: \"none\",\n },\n },\n});\n\nconst refRegexp = /note\\d/;\nconst footnotesAccordionId = \"footnotes\";\nconst accordionItemValue = \"rulesForUse\";\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, i18n } = useTranslation();\n\n const showPrimaryContributors = suppliers.length > 0 || authors.length > 0;\n const listFormatter = new Intl.ListFormat(toIntlLanguage(lang ?? i18n.language), {\n style: \"long\",\n type: \"conjunction\",\n });\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 multiple>\n {!!licenseBox && (\n <ArticleBylineAccordionItem value={accordionItemValue} accordionTitle={t(\"article.useContent\")}>\n {licenseBox}\n </ArticleBylineAccordionItem>\n )}\n {!!footnotes?.length && <ArticleBylineFootnotes footnotes={footnotes} />}\n </StyledAccordionRoot>\n )}\n </Wrapper>\n );\n};\n\ninterface ArticleBylineAccordionprops extends AccordionItemProps {\n accordionTitle: ReactNode;\n}\n\ninterface ArticleBylineFootnotesProps {\n footnotes: FootNote[];\n}\n\nexport const ArticleBylineFootnotes = ({ footnotes }: ArticleBylineFootnotesProps) => {\n const { t } = useTranslation();\n const { value, setValue } = useAccordionContext();\n const ref = useRef<HTMLDivElement>(null);\n\n const onHashChange = useCallback(\n (e: HashChangeEvent) => {\n const hash = e.newURL.split(\"#\")[1];\n if (hash?.match(refRegexp) && !value.includes(footnotesAccordionId)) {\n ref.current?.scrollIntoView({ behavior: \"smooth\" });\n setValue([...value, footnotesAccordionId]);\n setTimeout(() => {\n const el = document.getElementById(`${hash}`);\n el?.click();\n el?.focus();\n }, 300);\n }\n },\n [value, setValue],\n );\n\n useEffect(() => {\n window.addEventListener(\"hashchange\", onHashChange);\n return () => window.removeEventListener(\"hashchange\", onHashChange);\n }, [onHashChange]);\n\n return (\n <ArticleBylineAccordionItem ref={ref} value={footnotesAccordionId} accordionTitle={t(\"article.footnotes\")}>\n <ArticleFootNotes footNotes={footnotes} />\n </ArticleBylineAccordionItem>\n );\n};\n\nexport const ArticleBylineAccordionItem = forwardRef<HTMLDivElement, ArticleBylineAccordionprops>(\n ({ value, accordionTitle, children, ...props }, ref) => {\n return (\n <AccordionItem value={value} ref={ref} {...props}>\n <Heading asChild consumeCss textStyle=\"label.medium\" fontWeight=\"bold\">\n <h2>\n <AccordionItemTrigger>\n {accordionTitle}\n <AccordionItemIndicator asChild>\n <ArrowDownShortLine />\n </AccordionItemIndicator>\n </AccordionItemTrigger>\n </h2>\n </Heading>\n <AccordionItemContent>{children}</AccordionItemContent>\n </AccordionItem>\n );\n },\n);\n"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Copyright (c) 2026-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
+ import type { ComponentProps } from "react";
9
+ interface Props extends ComponentProps<"audio"> {
10
+ src: string;
11
+ title: string;
12
+ }
13
+ export declare const AudioElement: (props: Props) => import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,13 @@
1
+ require("../_virtual/_rolldown/runtime.js");
2
+ let react_jsx_runtime = require("react/jsx-runtime");
3
+ //#region src/AudioPlayer/AudioElement.tsx
4
+ const AudioElement = (props) => {
5
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("audio", {
6
+ preload: "metadata",
7
+ ...props
8
+ });
9
+ };
10
+ //#endregion
11
+ exports.AudioElement = AudioElement;
12
+
13
+ //# sourceMappingURL=AudioElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioElement.js","names":[],"sources":["../../src/AudioPlayer/AudioElement.tsx"],"sourcesContent":["/**\n * Copyright (c) 2026-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 { ComponentProps } from \"react\";\n\ninterface Props extends ComponentProps<\"audio\"> {\n src: string;\n title: string;\n}\n\nexport const AudioElement = (props: Props) => {\n // TODO: We should tie this up to the textual description somehow\n // oxlint-disable-next-line jsx-a11y/media-has-caption\n return <audio preload=\"metadata\" {...props} />;\n};\n"],"mappings":";;;AAeA,MAAa,gBAAgB,UAAiB;AAG5C,QAAO,iBAAA,GAAA,kBAAA,KAAC,SAAD;EAAO,SAAQ;EAAW,GAAI;EAAS,CAAA"}
@@ -6,20 +6,21 @@
6
6
  *
7
7
  */
8
8
  import { type ReactNode } from "react";
9
- type Props = {
9
+ export type AudioPlayerVariant = "standard" | "minimal" | "compact";
10
+ interface Props {
10
11
  src: string;
11
12
  title: string;
12
13
  subtitle?: {
13
14
  title: string;
14
15
  url?: string;
15
16
  };
16
- speech?: boolean;
17
+ variant?: AudioPlayerVariant;
17
18
  description?: string;
18
19
  textVersion?: ReactNode;
19
20
  img?: {
20
21
  url: string;
21
22
  alt: string;
22
23
  };
23
- };
24
- export declare const AudioPlayer: ({ src, title, subtitle, speech, description, img, textVersion }: Props) => import("react/jsx-runtime").JSX.Element;
24
+ }
25
+ export declare const AudioPlayer: ({ src, title, subtitle, variant, description, img, textVersion }: Props) => import("react/jsx-runtime").JSX.Element;
25
26
  export {};