@ndla/ui 55.0.13-alpha.0 → 55.0.14-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 (297) hide show
  1. package/dist/panda.buildinfo.json +120 -1
  2. package/dist/styles.css +511 -0
  3. package/es/Article/ArticleParagraph.js +11 -13
  4. package/es/CampaignBlock/CampaignBlock.js +103 -68
  5. package/es/Concept/Concept.js +69 -0
  6. package/es/ContentTypeBadge/ContentTypeBadgeNew.js +48 -0
  7. package/es/Embed/AudioEmbed.js +1 -2
  8. package/es/Embed/BrightcoveEmbed.js +13 -24
  9. package/es/Embed/ConceptEmbed.js +57 -301
  10. package/es/Embed/ConceptListEmbed.js +18 -24
  11. package/es/Embed/ContentLinkEmbed.js +10 -10
  12. package/es/Embed/CopyrightEmbed.js +4 -21
  13. package/es/Embed/ExternalEmbed.js +10 -18
  14. package/es/Embed/FootnoteEmbed.js +11 -8
  15. package/es/Embed/GlossEmbed.js +68 -0
  16. package/es/Embed/H5pEmbed.js +19 -19
  17. package/es/Embed/IframeEmbed.js +9 -6
  18. package/es/Embed/InlineTriggerButton.js +70 -0
  19. package/es/Embed/UnknownEmbed.js +9 -9
  20. package/es/Embed/UuDisclaimerEmbed.js +14 -25
  21. package/es/Embed/index.js +1 -3
  22. package/es/ErrorMessage/ErrorMessage.js +41 -22
  23. package/es/ErrorMessage/ErrorResourceAccessDenied.js +8 -6
  24. package/es/FactBox/FactBox.js +118 -47
  25. package/es/FileList/PdfFile.js +23 -5
  26. package/es/Gloss/Gloss.js +116 -86
  27. package/es/Gloss/GlossExample.js +49 -51
  28. package/es/LinkBlock/LinkBlock.js +61 -33
  29. package/es/LinkBlock/LinkBlockSection.js +9 -6
  30. package/es/Logo/Logo.js +1 -30
  31. package/es/RelatedArticleList/RelatedArticleList.js +70 -87
  32. package/es/ResourceBox/ResourceBox.js +65 -37
  33. package/es/TagSelector/TagSelector.js +124 -131
  34. package/es/i18n/index.js +2 -1
  35. package/es/i18n/useComponentTranslations.js +83 -0
  36. package/es/index.js +4 -11
  37. package/es/locale/messages-en.js +30 -4
  38. package/es/locale/messages-nb.js +30 -4
  39. package/es/locale/messages-nn.js +30 -4
  40. package/es/locale/messages-se.js +30 -4
  41. package/es/locale/messages-sma.js +30 -4
  42. package/es/model/ContentType.js +3 -0
  43. package/es/styles.css +511 -0
  44. package/lib/Article/ArticleParagraph.js +12 -14
  45. package/lib/CampaignBlock/CampaignBlock.d.ts +2 -2
  46. package/lib/CampaignBlock/CampaignBlock.js +106 -68
  47. package/lib/Concept/Concept.d.ts +18 -0
  48. package/lib/Concept/Concept.js +75 -0
  49. package/lib/ContentTypeBadge/ContentTypeBadgeNew.d.ts +17 -0
  50. package/lib/ContentTypeBadge/ContentTypeBadgeNew.js +56 -0
  51. package/lib/Embed/AudioEmbed.js +2 -3
  52. package/lib/Embed/BrightcoveEmbed.d.ts +1 -2
  53. package/lib/Embed/BrightcoveEmbed.js +16 -25
  54. package/lib/Embed/ConceptEmbed.d.ts +15 -21
  55. package/lib/Embed/ConceptEmbed.js +58 -301
  56. package/lib/Embed/ConceptListEmbed.js +21 -26
  57. package/lib/Embed/ContentLinkEmbed.js +10 -11
  58. package/lib/Embed/CopyrightEmbed.js +6 -22
  59. package/lib/Embed/ExternalEmbed.d.ts +1 -2
  60. package/lib/Embed/ExternalEmbed.js +13 -19
  61. package/lib/Embed/FootnoteEmbed.js +11 -9
  62. package/lib/Embed/GlossEmbed.d.ts +13 -0
  63. package/lib/Embed/GlossEmbed.js +76 -0
  64. package/lib/Embed/H5pEmbed.d.ts +1 -2
  65. package/lib/Embed/H5pEmbed.js +21 -19
  66. package/lib/Embed/IframeEmbed.d.ts +1 -2
  67. package/lib/Embed/IframeEmbed.js +11 -8
  68. package/lib/Embed/InlineTriggerButton.d.ts +11 -0
  69. package/lib/Embed/InlineTriggerButton.js +76 -0
  70. package/lib/Embed/UnknownEmbed.js +9 -10
  71. package/lib/Embed/UuDisclaimerEmbed.js +16 -26
  72. package/lib/Embed/index.d.ts +2 -3
  73. package/lib/Embed/index.js +2 -9
  74. package/lib/ErrorMessage/ErrorMessage.js +40 -23
  75. package/lib/ErrorMessage/ErrorResourceAccessDenied.js +7 -6
  76. package/lib/FactBox/FactBox.d.ts +0 -1
  77. package/lib/FactBox/FactBox.js +119 -46
  78. package/lib/FileList/PdfFile.js +23 -5
  79. package/lib/Gloss/Gloss.d.ts +10 -2
  80. package/lib/Gloss/Gloss.js +116 -85
  81. package/lib/Gloss/GlossExample.d.ts +3 -5
  82. package/lib/Gloss/GlossExample.js +49 -52
  83. package/lib/LinkBlock/LinkBlock.js +62 -34
  84. package/lib/LinkBlock/LinkBlockSection.js +9 -7
  85. package/lib/Logo/Logo.d.ts +1 -3
  86. package/lib/Logo/Logo.js +2 -30
  87. package/lib/RelatedArticleList/RelatedArticleList.d.ts +4 -4
  88. package/lib/RelatedArticleList/RelatedArticleList.js +74 -90
  89. package/lib/ResourceBox/ResourceBox.js +64 -37
  90. package/lib/TagSelector/TagSelector.d.ts +27 -12
  91. package/lib/TagSelector/TagSelector.js +126 -131
  92. package/lib/i18n/index.d.ts +1 -0
  93. package/lib/i18n/index.js +20 -1
  94. package/lib/i18n/useComponentTranslations.d.ts +14 -0
  95. package/lib/i18n/useComponentTranslations.js +93 -0
  96. package/lib/index.d.ts +5 -14
  97. package/lib/index.js +70 -89
  98. package/lib/locale/messages-en.d.ts +26 -0
  99. package/lib/locale/messages-en.js +30 -4
  100. package/lib/locale/messages-nb.d.ts +26 -0
  101. package/lib/locale/messages-nb.js +30 -4
  102. package/lib/locale/messages-nn.d.ts +26 -0
  103. package/lib/locale/messages-nn.js +30 -4
  104. package/lib/locale/messages-se.d.ts +26 -0
  105. package/lib/locale/messages-se.js +30 -4
  106. package/lib/locale/messages-sma.d.ts +26 -0
  107. package/lib/locale/messages-sma.js +30 -4
  108. package/lib/model/ContentType.d.ts +3 -0
  109. package/lib/model/ContentType.js +4 -1
  110. package/lib/styles.css +511 -0
  111. package/package.json +11 -13
  112. package/src/Article/ArticleParagraph.tsx +11 -9
  113. package/src/CampaignBlock/CampaignBlock.tsx +92 -55
  114. package/src/Concept/Concept.stories.tsx +142 -0
  115. package/src/Concept/Concept.tsx +73 -0
  116. package/src/ContentTypeBadge/ContentTypeBadgeNew.stories.tsx +70 -0
  117. package/src/ContentTypeBadge/ContentTypeBadgeNew.tsx +69 -0
  118. package/src/Embed/AudioEmbed.tsx +2 -2
  119. package/src/Embed/BrightcoveEmbed.stories.tsx +0 -3
  120. package/src/Embed/BrightcoveEmbed.tsx +17 -19
  121. package/src/Embed/ConceptEmbed.stories.tsx +1 -105
  122. package/src/Embed/ConceptEmbed.tsx +60 -385
  123. package/src/Embed/ConceptListEmbed.tsx +20 -19
  124. package/src/Embed/ContentLinkEmbed.tsx +8 -10
  125. package/src/Embed/CopyrightEmbed.tsx +1 -11
  126. package/src/Embed/ExternalEmbed.tsx +14 -17
  127. package/src/Embed/FootnoteEmbed.stories.tsx +2 -5
  128. package/src/Embed/FootnoteEmbed.tsx +13 -16
  129. package/src/Embed/GlossEmbed.stories.tsx +140 -0
  130. package/src/Embed/GlossEmbed.tsx +64 -0
  131. package/src/Embed/H5pEmbed.tsx +22 -16
  132. package/src/Embed/IframeEmbed.tsx +12 -6
  133. package/src/Embed/InlineTriggerButton.tsx +72 -0
  134. package/src/Embed/UnknownEmbed.tsx +6 -7
  135. package/src/Embed/UuDisclaimerEmbed.stories.tsx +4 -4
  136. package/src/Embed/UuDisclaimerEmbed.tsx +17 -25
  137. package/src/Embed/index.ts +2 -3
  138. package/src/ErrorMessage/ErrorMessage.tsx +40 -29
  139. package/src/ErrorMessage/ErrorResourceAccessDenied.tsx +8 -6
  140. package/src/FactBox/FactBox.tsx +115 -115
  141. package/src/FactBox/Factbox.stories.tsx +43 -27
  142. package/src/FileList/FileList.stories.tsx +6 -1
  143. package/src/FileList/PdfFile.tsx +22 -5
  144. package/src/Gloss/Gloss.stories.tsx +107 -1
  145. package/src/Gloss/Gloss.tsx +143 -156
  146. package/src/Gloss/GlossExample.tsx +51 -77
  147. package/src/LinkBlock/LinkBlock.stories.tsx +8 -10
  148. package/src/LinkBlock/LinkBlock.tsx +54 -59
  149. package/src/LinkBlock/LinkBlockSection.tsx +9 -12
  150. package/src/Logo/Logo.stories.tsx +0 -1
  151. package/src/Logo/Logo.tsx +2 -30
  152. package/src/RelatedArticleList/RelatedArticleList.tsx +69 -88
  153. package/src/ResourceBox/ResourceBox.tsx +63 -59
  154. package/src/TagSelector/TagSelector.stories.tsx +92 -68
  155. package/src/TagSelector/TagSelector.tsx +161 -126
  156. package/src/i18n/index.ts +5 -0
  157. package/src/i18n/useComponentTranslations.ts +72 -0
  158. package/src/index.ts +23 -18
  159. package/src/locale/messages-en.ts +28 -2
  160. package/src/locale/messages-nb.ts +28 -2
  161. package/src/locale/messages-nn.ts +28 -2
  162. package/src/locale/messages-se.ts +28 -2
  163. package/src/locale/messages-sma.ts +28 -2
  164. package/src/model/ContentType.ts +3 -0
  165. package/es/DefinitionList/DefinitionDescription.js +0 -28
  166. package/es/DefinitionList/DefinitionTerm.js +0 -28
  167. package/es/DefinitionList/index.js +0 -10
  168. package/es/Embed/conceptComponents.js +0 -155
  169. package/es/ExpandableBox/ExpandableBox.js +0 -29
  170. package/es/ExpandableBox/index.js +0 -9
  171. package/es/Figure/Figure.js +0 -73
  172. package/es/Figure/index.js +0 -9
  173. package/es/FramedContent/FramedContent.js +0 -28
  174. package/es/FramedContent/index.js +0 -10
  175. package/es/Image/Image.js +0 -99
  176. package/es/Image/ImageLink.js +0 -39
  177. package/es/Image/index.js +0 -12
  178. package/es/LetterFilter/LetterFilter.js +0 -54
  179. package/es/LetterFilter/alphabet.js +0 -9
  180. package/es/LetterFilter/index.js +0 -10
  181. package/es/Notion/Notion.js +0 -76
  182. package/es/Notion/NotionImage.js +0 -46
  183. package/es/Notion/index.js +0 -9
  184. package/es/Table/Table.js +0 -141
  185. package/es/Table/index.js +0 -11
  186. package/es/TagSelector/Control.js +0 -28
  187. package/es/TagSelector/DropdownIndicator.js +0 -60
  188. package/es/TagSelector/Input.js +0 -22
  189. package/es/TagSelector/Menu.js +0 -27
  190. package/es/TagSelector/MenuList.js +0 -28
  191. package/es/TagSelector/Option.js +0 -60
  192. package/es/TagSelector/SelectContainer.js +0 -27
  193. package/es/TagSelector/ValueButton.js +0 -53
  194. package/es/TagSelector/ariaMessages.js +0 -94
  195. package/es/TagSelector/index.js +0 -10
  196. package/es/TagSelector/types.js +0 -1
  197. package/lib/DefinitionList/DefinitionDescription.d.ts +0 -10
  198. package/lib/DefinitionList/DefinitionDescription.js +0 -35
  199. package/lib/DefinitionList/DefinitionTerm.d.ts +0 -10
  200. package/lib/DefinitionList/DefinitionTerm.js +0 -35
  201. package/lib/DefinitionList/index.d.ts +0 -9
  202. package/lib/DefinitionList/index.js +0 -20
  203. package/lib/Embed/conceptComponents.d.ts +0 -40
  204. package/lib/Embed/conceptComponents.js +0 -163
  205. package/lib/ExpandableBox/ExpandableBox.d.ts +0 -15
  206. package/lib/ExpandableBox/ExpandableBox.js +0 -37
  207. package/lib/ExpandableBox/index.d.ts +0 -8
  208. package/lib/ExpandableBox/index.js +0 -18
  209. package/lib/Figure/Figure.d.ts +0 -16
  210. package/lib/Figure/Figure.js +0 -81
  211. package/lib/Figure/index.d.ts +0 -9
  212. package/lib/Figure/index.js +0 -13
  213. package/lib/FramedContent/FramedContent.d.ts +0 -12
  214. package/lib/FramedContent/FramedContent.js +0 -35
  215. package/lib/FramedContent/index.d.ts +0 -9
  216. package/lib/FramedContent/index.js +0 -16
  217. package/lib/Image/Image.d.ts +0 -38
  218. package/lib/Image/Image.js +0 -105
  219. package/lib/Image/ImageLink.d.ts +0 -18
  220. package/lib/Image/ImageLink.js +0 -44
  221. package/lib/Image/index.d.ts +0 -12
  222. package/lib/Image/index.js +0 -30
  223. package/lib/LetterFilter/LetterFilter.d.ts +0 -14
  224. package/lib/LetterFilter/LetterFilter.js +0 -61
  225. package/lib/LetterFilter/alphabet.d.ts +0 -8
  226. package/lib/LetterFilter/alphabet.js +0 -15
  227. package/lib/LetterFilter/index.d.ts +0 -9
  228. package/lib/LetterFilter/index.js +0 -16
  229. package/lib/Notion/Notion.d.ts +0 -20
  230. package/lib/Notion/Notion.js +0 -82
  231. package/lib/Notion/NotionImage.d.ts +0 -13
  232. package/lib/Notion/NotionImage.js +0 -54
  233. package/lib/Notion/index.d.ts +0 -8
  234. package/lib/Notion/index.js +0 -13
  235. package/lib/Table/Table.d.ts +0 -19
  236. package/lib/Table/Table.js +0 -145
  237. package/lib/Table/index.d.ts +0 -10
  238. package/lib/Table/index.js +0 -23
  239. package/lib/TagSelector/Control.d.ts +0 -11
  240. package/lib/TagSelector/Control.js +0 -35
  241. package/lib/TagSelector/DropdownIndicator.d.ts +0 -11
  242. package/lib/TagSelector/DropdownIndicator.js +0 -64
  243. package/lib/TagSelector/Input.d.ts +0 -12
  244. package/lib/TagSelector/Input.js +0 -29
  245. package/lib/TagSelector/Menu.d.ts +0 -12
  246. package/lib/TagSelector/Menu.js +0 -34
  247. package/lib/TagSelector/MenuList.d.ts +0 -16
  248. package/lib/TagSelector/MenuList.js +0 -35
  249. package/lib/TagSelector/Option.d.ts +0 -12
  250. package/lib/TagSelector/Option.js +0 -67
  251. package/lib/TagSelector/SelectContainer.d.ts +0 -11
  252. package/lib/TagSelector/SelectContainer.js +0 -34
  253. package/lib/TagSelector/ValueButton.d.ts +0 -20
  254. package/lib/TagSelector/ValueButton.js +0 -60
  255. package/lib/TagSelector/ariaMessages.d.ts +0 -16
  256. package/lib/TagSelector/ariaMessages.js +0 -101
  257. package/lib/TagSelector/index.d.ts +0 -11
  258. package/lib/TagSelector/index.js +0 -13
  259. package/lib/TagSelector/types.d.ts +0 -11
  260. package/lib/TagSelector/types.js +0 -5
  261. package/src/DefinitionList/DefinitionDescription.tsx +0 -26
  262. package/src/DefinitionList/DefinitionTerm.tsx +0 -26
  263. package/src/DefinitionList/index.tsx +0 -10
  264. package/src/Embed/conceptComponents.tsx +0 -293
  265. package/src/ExpandableBox/ExpandableBox.stories.tsx +0 -41
  266. package/src/ExpandableBox/ExpandableBox.tsx +0 -23
  267. package/src/ExpandableBox/index.ts +0 -9
  268. package/src/Figure/Figure.tsx +0 -167
  269. package/src/Figure/index.ts +0 -11
  270. package/src/FramedContent/FramedContent.stories.tsx +0 -152
  271. package/src/FramedContent/FramedContent.tsx +0 -26
  272. package/src/FramedContent/index.ts +0 -10
  273. package/src/Image/Image.stories.tsx +0 -61
  274. package/src/Image/Image.tsx +0 -147
  275. package/src/Image/ImageLink.tsx +0 -37
  276. package/src/Image/index.ts +0 -14
  277. package/src/LetterFilter/LetterFilter.stories.tsx +0 -29
  278. package/src/LetterFilter/LetterFilter.tsx +0 -78
  279. package/src/LetterFilter/alphabet.ts +0 -39
  280. package/src/LetterFilter/index.ts +0 -11
  281. package/src/Notion/Notion.tsx +0 -96
  282. package/src/Notion/NotionImage.tsx +0 -64
  283. package/src/Notion/index.ts +0 -9
  284. package/src/Table/Table.stories.tsx +0 -738
  285. package/src/Table/Table.tsx +0 -284
  286. package/src/Table/index.ts +0 -12
  287. package/src/TagSelector/Control.tsx +0 -34
  288. package/src/TagSelector/DropdownIndicator.tsx +0 -55
  289. package/src/TagSelector/Input.tsx +0 -31
  290. package/src/TagSelector/Menu.tsx +0 -38
  291. package/src/TagSelector/MenuList.tsx +0 -30
  292. package/src/TagSelector/Option.tsx +0 -58
  293. package/src/TagSelector/SelectContainer.tsx +0 -31
  294. package/src/TagSelector/ValueButton.tsx +0 -47
  295. package/src/TagSelector/ariaMessages.ts +0 -96
  296. package/src/TagSelector/index.ts +0 -14
  297. package/src/TagSelector/types.ts +0 -12
@@ -7,29 +7,32 @@
7
7
  */
8
8
 
9
9
  import { useTranslation } from "react-i18next";
10
- import styled from "@emotion/styled";
11
- import { colors } from "@ndla/core";
10
+ import { Figure } from "@ndla/primitives";
11
+ import { styled } from "@ndla/styled-system/jsx";
12
12
  import { ConceptListMetaData } from "@ndla/types-embed";
13
13
  import { BlockConcept } from "./ConceptEmbed";
14
- import { Figure } from "../Figure";
15
14
 
16
15
  interface Props {
17
16
  embed: ConceptListMetaData;
18
17
  lang?: string;
19
18
  }
20
19
 
21
- const ConceptList = styled.div`
22
- & > figure:first-of-type {
23
- margin-top: 32px;
24
- }
25
- & li {
26
- display: block;
27
- }
28
- `;
20
+ // TODO: Find out if we're actually still going to use this.
21
+ // If we are, we need to re-add some margin between the list items. We should also probably parse the concept content to HTML, like we do in ConceptEmbed.
22
+
23
+ const ConceptList = styled("div", {
24
+ base: {
25
+ "& li": {
26
+ display: "block",
27
+ },
28
+ },
29
+ });
29
30
 
30
- const StyledSpan = styled.span`
31
- color: ${colors.support.red};
32
- `;
31
+ const StyledSpan = styled("span", {
32
+ base: {
33
+ color: "text.error",
34
+ },
35
+ });
33
36
 
34
37
  const ConceptListEmbed = ({ embed, lang }: Props) => {
35
38
  const { t } = useTranslation();
@@ -39,20 +42,18 @@ const ConceptListEmbed = ({ embed, lang }: Props) => {
39
42
  const { embedData, data } = embed;
40
43
  return (
41
44
  <div>
42
- <Figure type="full">
45
+ <Figure>
43
46
  {embedData.title && <h2 lang={lang}>{embedData.title}</h2>}
44
47
  <ConceptList>
45
48
  <ul lang={lang}>
46
49
  {data.concepts.map(({ concept, visualElement }) => (
47
50
  <li key={concept.id}>
48
51
  <BlockConcept
49
- title={concept.title}
52
+ title={concept.title.title}
50
53
  content={concept.content.content}
51
- metaImage={concept.metaImage}
52
54
  copyright={concept.copyright}
53
- source={concept.source}
54
55
  visualElement={visualElement}
55
- conceptType={concept.conceptType}
56
+ lang={lang}
56
57
  />
57
58
  </li>
58
59
  ))}
@@ -8,27 +8,25 @@
8
8
 
9
9
  import { ReactNode } from "react";
10
10
  import { useTranslation } from "react-i18next";
11
- import styled from "@emotion/styled";
12
- import { colors } from "@ndla/core";
11
+ import { Text } from "@ndla/primitives";
13
12
  import { ContentLinkMetaData } from "@ndla/types-embed";
13
+
14
14
  interface Props {
15
15
  embed: ContentLinkMetaData;
16
16
  isOembed?: boolean;
17
17
  children?: ReactNode;
18
18
  }
19
19
 
20
- const StyledSpan = styled.span`
21
- color: ${colors.support.red};
22
- `;
23
-
24
20
  const ContentLinkEmbed = ({ embed, isOembed, children }: Props) => {
25
21
  const { t } = useTranslation();
26
22
  if (embed.status === "error") {
27
23
  return (
28
- <StyledSpan>
29
- <span>{`${t("embed.linkError")}: `}</span>
30
- {children}
31
- </StyledSpan>
24
+ <Text color="text.error" asChild consumeCss>
25
+ <span>
26
+ <span>{`${t("embed.linkError")}: `}</span>
27
+ {children}
28
+ </span>
29
+ </Text>
32
30
  );
33
31
  }
34
32
 
@@ -7,7 +7,6 @@
7
7
  */
8
8
 
9
9
  import { ReactNode } from "react";
10
- import styled from "@emotion/styled";
11
10
  import { CopyrightMetaData } from "@ndla/types-embed";
12
11
  import { EmbedByline } from "../LicenseByline";
13
12
 
@@ -16,20 +15,11 @@ interface Props {
16
15
  children?: ReactNode;
17
16
  }
18
17
 
19
- const StyledFigCaption = styled.figcaption`
20
- background: unset;
21
- font-size: unset;
22
- padding: unset;
23
- color: unset;
24
- `;
25
-
26
18
  const CopyrightEmbed = ({ embed, children }: Props) => {
27
19
  return (
28
20
  <figure>
29
21
  {children}
30
- <StyledFigCaption contentEditable={false}>
31
- <EmbedByline type="copyright" copyright={embed.embedData.copyright} bottomRounded />
32
- </StyledFigCaption>
22
+ <EmbedByline type="copyright" copyright={embed.embedData.copyright} bottomRounded />
33
23
  </figure>
34
24
  );
35
25
  };
@@ -8,24 +8,26 @@
8
8
 
9
9
  import { useEffect, useRef } from "react";
10
10
  import { useTranslation } from "react-i18next";
11
- import styled from "@emotion/styled";
11
+ import { Figure } from "@ndla/primitives";
12
+ import { styled } from "@ndla/styled-system/jsx";
12
13
  import { OembedMetaData } from "@ndla/types-embed";
13
14
  import EmbedErrorPlaceholder from "./EmbedErrorPlaceholder";
14
- import { Figure } from "../Figure";
15
15
  import { ResourceBox } from "../ResourceBox";
16
16
 
17
17
  interface Props {
18
18
  embed: OembedMetaData;
19
- isConcept?: boolean;
20
19
  }
21
20
 
22
- const StyledFigure = styled(Figure)`
23
- iframe {
24
- height: auto;
25
- }
26
- `;
21
+ const StyledFigure = styled(Figure, {
22
+ base: {
23
+ "& iframe": {
24
+ height: "auto",
25
+ width: "100%",
26
+ },
27
+ },
28
+ });
27
29
 
28
- const ExternalEmbed = ({ embed, isConcept }: Props) => {
30
+ const ExternalEmbed = ({ embed }: Props) => {
29
31
  const { t } = useTranslation();
30
32
  const figRef = useRef<HTMLElement>(null);
31
33
 
@@ -38,6 +40,7 @@ const ExternalEmbed = ({ embed, isConcept }: Props) => {
38
40
  iframe.height = "";
39
41
  }
40
42
  }, []);
43
+
41
44
  if (embed.status === "error") {
42
45
  return <EmbedErrorPlaceholder type="external" />;
43
46
  }
@@ -50,7 +53,7 @@ const ExternalEmbed = ({ embed, isConcept }: Props) => {
50
53
  alt: embedData.alt !== undefined ? embedData.alt : data.iframeImage?.alttext?.alttext ?? "",
51
54
  };
52
55
  return (
53
- <Figure type="full">
56
+ <Figure>
54
57
  <ResourceBox
55
58
  image={image}
56
59
  title={embedData.title ?? ""}
@@ -62,13 +65,7 @@ const ExternalEmbed = ({ embed, isConcept }: Props) => {
62
65
  );
63
66
  }
64
67
 
65
- return (
66
- <StyledFigure
67
- ref={figRef}
68
- type={isConcept ? "full-column" : undefined}
69
- dangerouslySetInnerHTML={{ __html: data.oembed.html ?? "" }}
70
- />
71
- );
68
+ return <StyledFigure ref={figRef} dangerouslySetInnerHTML={{ __html: data.oembed.html ?? "" }} />;
72
69
  };
73
70
 
74
71
  export default ExternalEmbed;
@@ -99,11 +99,7 @@ const otherFootnoteMeta: FootnoteData = {
99
99
  export const WithSeveralFootnotes: StoryFn<typeof FootnoteEmbed> = ({ ...args }) => (
100
100
  <div>
101
101
  <p>
102
- Her kan det ligge en fotnote
103
- <FootnoteEmbed {...args} />
104
- </p>
105
- <p>
106
- Her kan det ligge en til
102
+ Her kan det ligge en fotnote <FootnoteEmbed {...args} /> for eksempel. Her kan det ligge en til
107
103
  <FootnoteEmbed
108
104
  embed={{
109
105
  resource: "footnote",
@@ -112,6 +108,7 @@ export const WithSeveralFootnotes: StoryFn<typeof FootnoteEmbed> = ({ ...args })
112
108
  embedData: otherFootnoteEmbedData,
113
109
  }}
114
110
  />
111
+ .
115
112
  </p>
116
113
  <ArticleByline
117
114
  footnotes={
@@ -7,24 +7,21 @@
7
7
  */
8
8
 
9
9
  import { useTranslation } from "react-i18next";
10
- import styled from "@emotion/styled";
11
- import { spacing } from "@ndla/core";
10
+ import { styled } from "@ndla/styled-system/jsx";
12
11
  import { FootnoteMetaData } from "@ndla/types-embed";
13
12
 
14
13
  interface Props {
15
14
  embed: FootnoteMetaData;
16
15
  }
17
16
 
18
- const FootnoteRef = styled.span`
19
- sup {
20
- a {
21
- margin-left: -2px;
22
- padding: ${spacing.small} ${spacing.xsmall};
23
- box-shadow: none;
24
- text-decoration: underline;
25
- }
26
- }
27
- `;
17
+ const StyledSup = styled("sup", {
18
+ base: {
19
+ "& a": {
20
+ textStyle: "label.xsmall",
21
+ marginInlineStart: "1",
22
+ },
23
+ },
24
+ });
28
25
 
29
26
  const FootnoteEmbed = ({ embed }: Props) => {
30
27
  const { t } = useTranslation();
@@ -33,11 +30,11 @@ const FootnoteEmbed = ({ embed }: Props) => {
33
30
  }
34
31
 
35
32
  return (
36
- <FootnoteRef id={`ref${embed.data.entryNum}`}>
37
- <sup>
33
+ <span id={`ref${embed.data.entryNum}`}>
34
+ <StyledSup>
38
35
  <a href={`#note${embed.data.entryNum}`} target="_self">{`[${embed.data.entryNum}]`}</a>
39
- </sup>
40
- </FootnoteRef>
36
+ </StyledSup>
37
+ </span>
41
38
  );
42
39
  };
43
40
 
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { Meta, StoryObj } from "@storybook/react";
10
+ import { ConceptData, ConceptEmbedData } from "@ndla/types-embed";
11
+ import { GlossEmbed } from "./GlossEmbed";
12
+
13
+ const glossBlockEmbedData: ConceptEmbedData = {
14
+ contentId: "4942",
15
+ resource: "concept",
16
+ type: "block",
17
+ linkText: "",
18
+ };
19
+
20
+ const glossInlineEmbedData: ConceptEmbedData = {
21
+ contentId: "23",
22
+ linkText: "glose",
23
+ resource: "concept",
24
+ type: "inline",
25
+ };
26
+
27
+ const glossMetaData: ConceptData["concept"] = {
28
+ id: 4942,
29
+ revision: 6,
30
+ title: {
31
+ title: "Ma Hong",
32
+ language: "nb",
33
+ },
34
+ content: {
35
+ content: "Hei",
36
+ htmlContent: "Hei",
37
+ language: "nb",
38
+ },
39
+ copyright: {
40
+ creators: [],
41
+ processors: [],
42
+ rightsholders: [],
43
+ processed: false,
44
+ },
45
+ source: "",
46
+ metaImage: {
47
+ url: "",
48
+ alt: "",
49
+ language: "und",
50
+ },
51
+ created: "2023-07-19T09:30:40.000Z",
52
+ updated: "2023-09-19T17:13:56.573Z",
53
+ updatedBy: ["XxnkdI7rApMl58MeG3p4g4B8", "hd5ZL5Lm4kKkumWgN2gjy9wx"],
54
+ supportedLanguages: ["nb"],
55
+ articleIds: [],
56
+ status: {
57
+ current: "IN_PROGRESS",
58
+ other: [],
59
+ },
60
+ responsible: {
61
+ responsibleId: "XxnkdI7rApMl58MeG3p4g4B8",
62
+ lastUpdated: "2023-07-19T09:30:40.000Z",
63
+ },
64
+ conceptType: "gloss",
65
+ glossData: {
66
+ gloss: "马红",
67
+ wordClass: "personal-pronoun",
68
+ originalLanguage: "zh",
69
+ transcriptions: {},
70
+ examples: [
71
+ [
72
+ {
73
+ example: "我叫马红",
74
+ language: "zh",
75
+ transcriptions: {
76
+ pinyin: "wo jiao ma hong ",
77
+ },
78
+ },
79
+ {
80
+ example: "Jeg heter ma hong",
81
+ language: "nb",
82
+ transcriptions: {},
83
+ },
84
+ ],
85
+ ],
86
+ },
87
+ };
88
+
89
+ const glossBlockData: ConceptData = {
90
+ concept: glossMetaData,
91
+ };
92
+
93
+ export default {
94
+ title: "Embeds/GlossEmbed",
95
+ component: GlossEmbed,
96
+ tags: ["autodocs"],
97
+ render: (args) => <GlossEmbed {...args} />,
98
+ } satisfies Meta<typeof GlossEmbed>;
99
+
100
+ export const Block: StoryObj<typeof GlossEmbed> = {
101
+ args: {
102
+ embed: {
103
+ resource: "concept",
104
+ status: "success",
105
+ embedData: glossBlockEmbedData,
106
+ data: glossBlockData,
107
+ },
108
+ },
109
+ };
110
+
111
+ export const BlockFailed: StoryObj<typeof GlossEmbed> = {
112
+ args: {
113
+ embed: {
114
+ resource: "concept",
115
+ status: "error",
116
+ embedData: glossBlockEmbedData,
117
+ },
118
+ },
119
+ };
120
+
121
+ export const Inline: StoryObj<typeof GlossEmbed> = {
122
+ args: {
123
+ embed: {
124
+ resource: "concept",
125
+ status: "success",
126
+ embedData: glossInlineEmbedData,
127
+ data: glossBlockData,
128
+ },
129
+ },
130
+ };
131
+
132
+ export const InlineFailed: StoryObj<typeof GlossEmbed> = {
133
+ args: {
134
+ embed: {
135
+ resource: "concept",
136
+ status: "error",
137
+ embedData: glossInlineEmbedData,
138
+ },
139
+ },
140
+ };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { Figure, PopoverContent, PopoverRoot, PopoverTrigger } from "@ndla/primitives";
10
+ import { styled } from "@ndla/styled-system/jsx";
11
+ import { ConceptMetaData } from "@ndla/types-embed";
12
+ import EmbedErrorPlaceholder from "./EmbedErrorPlaceholder";
13
+ import { InlineTriggerButton } from "./InlineTriggerButton";
14
+ import { Gloss } from "../Gloss";
15
+
16
+ interface Props {
17
+ embed: ConceptMetaData;
18
+ }
19
+
20
+ const StyledPopoverContent = styled(PopoverContent, {
21
+ base: {
22
+ width: "surface.xlarge",
23
+ },
24
+ });
25
+
26
+ export const GlossEmbed = ({ embed }: Props) => {
27
+ if (embed.status === "error" && embed.embedData.type === "inline") {
28
+ return <span>{embed.embedData.linkText}</span>;
29
+ }
30
+ if (embed.status === "error" || !embed.data.concept.glossData) {
31
+ return <EmbedErrorPlaceholder type="gloss" />;
32
+ }
33
+
34
+ const { concept, visualElement } = embed.data;
35
+
36
+ const audio =
37
+ visualElement?.status === "success" && visualElement.resource === "audio"
38
+ ? {
39
+ src: visualElement.data.audioFile.url,
40
+ title: visualElement.data.title.title,
41
+ }
42
+ : undefined;
43
+
44
+ if (embed.embedData.type === "inline") {
45
+ return (
46
+ <PopoverRoot>
47
+ <PopoverTrigger asChild>
48
+ <InlineTriggerButton>{embed.embedData.linkText}</InlineTriggerButton>
49
+ </PopoverTrigger>
50
+ <StyledPopoverContent>
51
+ <Figure>
52
+ <Gloss glossData={concept.glossData} title={concept.title} audio={audio} />
53
+ </Figure>
54
+ </StyledPopoverContent>
55
+ </PopoverRoot>
56
+ );
57
+ }
58
+
59
+ return (
60
+ <Figure>
61
+ <Gloss glossData={concept.glossData} title={concept.title} audio={audio} variant="bordered" />
62
+ </Figure>
63
+ );
64
+ };
@@ -6,38 +6,44 @@
6
6
  *
7
7
  */
8
8
 
9
- import styled from "@emotion/styled";
9
+ import { Figure } from "@ndla/primitives";
10
+ import { styled } from "@ndla/styled-system/jsx";
10
11
  import { H5pMetaData } from "@ndla/types-embed";
11
12
  import EmbedErrorPlaceholder from "./EmbedErrorPlaceholder";
12
- import { Figure } from "../Figure";
13
13
 
14
14
  interface Props {
15
15
  embed: H5pMetaData;
16
- isConcept?: boolean;
17
16
  }
18
17
 
19
- const StyledFigure = styled(Figure)`
20
- iframe {
21
- height: auto;
22
- }
23
- `;
18
+ const StyledFigure = styled(Figure, {
19
+ base: {
20
+ "& iframe": {
21
+ height: "auto",
22
+ width: "100%",
23
+ },
24
+ },
25
+ });
26
+
27
+ const FigureOembed = styled(Figure, {
28
+ base: {
29
+ width: "100%",
30
+ "& iframe": {
31
+ width: "100%",
32
+ },
33
+ },
34
+ });
24
35
 
25
- const H5pEmbed = ({ embed, isConcept }: Props) => {
36
+ const H5pEmbed = ({ embed }: Props) => {
26
37
  if (embed.status === "error") {
27
38
  return <EmbedErrorPlaceholder type="h5p" />;
28
39
  }
29
40
 
30
41
  if (embed.data.oembed) {
31
- return (
32
- <Figure
33
- type={isConcept ? "full-column" : undefined}
34
- dangerouslySetInnerHTML={{ __html: embed.data.oembed.html ?? "" }}
35
- />
36
- );
42
+ return <FigureOembed dangerouslySetInnerHTML={{ __html: embed.data.oembed.html ?? "" }} />;
37
43
  }
38
44
 
39
45
  return (
40
- <StyledFigure type={isConcept ? "full-column" : undefined}>
46
+ <StyledFigure>
41
47
  <iframe title={embed.embedData.url} aria-label={embed.embedData.url} src={embed.embedData.url} />
42
48
  </StyledFigure>
43
49
  );
@@ -8,17 +8,23 @@
8
8
 
9
9
  import { useEffect, useRef } from "react";
10
10
  import { useTranslation } from "react-i18next";
11
+ import { Figure } from "@ndla/primitives";
12
+ import { styled } from "@ndla/styled-system/jsx";
11
13
  import { IframeMetaData } from "@ndla/types-embed";
12
14
  import EmbedErrorPlaceholder from "./EmbedErrorPlaceholder";
13
- import { Figure } from "../Figure";
14
15
  import { ResourceBox } from "../ResourceBox";
15
16
 
16
17
  interface Props {
17
18
  embed: IframeMetaData;
18
- isConcept?: boolean;
19
19
  }
20
20
 
21
- const IframeEmbed = ({ embed, isConcept }: Props) => {
21
+ const StyledIframe = styled("iframe", {
22
+ base: {
23
+ width: "100%",
24
+ },
25
+ });
26
+
27
+ const IframeEmbed = ({ embed }: Props) => {
22
28
  const { t } = useTranslation();
23
29
  const iframeRef = useRef<HTMLIFrameElement>(null);
24
30
 
@@ -43,7 +49,7 @@ const IframeEmbed = ({ embed, isConcept }: Props) => {
43
49
  const alt = embedData.alt !== undefined ? embedData.alt : iframeImage?.alttext.alttext;
44
50
  const image = { src: iframeImage?.image.imageUrl ?? "", alt: alt ?? "" };
45
51
  return (
46
- <Figure type="full">
52
+ <Figure>
47
53
  <ResourceBox
48
54
  image={image}
49
55
  title={embedData.title ?? ""}
@@ -62,8 +68,8 @@ const IframeEmbed = ({ embed, isConcept }: Props) => {
62
68
  const urlOrTitle = title || url;
63
69
 
64
70
  return (
65
- <Figure type={isConcept ? "full-column" : undefined}>
66
- <iframe
71
+ <Figure>
72
+ <StyledIframe
67
73
  ref={iframeRef}
68
74
  title={urlOrTitle}
69
75
  aria-label={urlOrTitle}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Copyright (c) 2024-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import { ComponentPropsWithRef, KeyboardEvent, forwardRef, useCallback, useRef } from "react";
10
+ import { styled } from "@ndla/styled-system/jsx";
11
+ import { composeRefs } from "@ndla/util";
12
+
13
+ const StyledSpan = styled("span", {
14
+ base: {
15
+ position: "relative",
16
+ overflow: "visible",
17
+ borderBottom: "1px solid",
18
+ borderStyle: "dashed",
19
+ borderColor: "stroke.hover",
20
+ paddingBlock: "4xsmall",
21
+ paddingInline: "4xsmall",
22
+ width: "fit-content",
23
+ cursor: "pointer",
24
+ _hover: {
25
+ borderColor: "text.link",
26
+ background: "surface.actionSubtle.hover",
27
+ },
28
+ _active: {
29
+ borderColor: "text.link",
30
+ background: "surface.actionSubtle.active",
31
+ },
32
+ // The global focus ring forces the border-radius to be xsmall, causing the dashed border to be cut off. This is a workaround.
33
+ _focusVisible: {
34
+ outline: "none",
35
+ borderRadius: "0",
36
+ _after: {
37
+ content: '""',
38
+ position: "absolute",
39
+ inset: "0",
40
+ outline: "3px",
41
+ borderRadius: "xsmall",
42
+ outlineColor: "stroke.default",
43
+ outlineOffset: "3px",
44
+ outlineStyle: "solid",
45
+ },
46
+ },
47
+ },
48
+ });
49
+
50
+ export const InlineTriggerButton = forwardRef<HTMLSpanElement, ComponentPropsWithRef<"span">>(
51
+ ({ onClick, ...props }, ref) => {
52
+ const spanRef = useRef<HTMLSpanElement>(null);
53
+
54
+ // Emulate a button click when pressing Enter or Space
55
+ const onKeyboardEvent = useCallback((event: KeyboardEvent<HTMLSpanElement>) => {
56
+ if (event.key === "Enter" || event.key === " ") {
57
+ spanRef.current?.click();
58
+ }
59
+ }, []);
60
+
61
+ return (
62
+ <StyledSpan
63
+ ref={composeRefs(spanRef, ref)}
64
+ onKeyUp={onKeyboardEvent}
65
+ onClick={onClick}
66
+ role="button"
67
+ tabIndex={0}
68
+ {...props}
69
+ />
70
+ );
71
+ },
72
+ );
@@ -7,21 +7,20 @@
7
7
  */
8
8
 
9
9
  import { useTranslation } from "react-i18next";
10
- import styled from "@emotion/styled";
11
- import { colors } from "@ndla/core";
10
+ import { Text } from "@ndla/primitives";
12
11
  import { MetaData } from "@ndla/types-embed";
13
12
 
14
13
  interface Props {
15
14
  embed: MetaData<any, any>;
16
15
  }
17
16
 
18
- const StyledSpan = styled.span`
19
- color: ${colors.support.red};
20
- `;
21
-
22
17
  const UnknownEmbed = ({ embed }: Props) => {
23
18
  const { t } = useTranslation();
24
- return <StyledSpan>{t("embed.unsupported", { type: embed.resource })}</StyledSpan>;
19
+ return (
20
+ <Text color="text.error" asChild consumeCss>
21
+ <span>{t("embed.unsupported", { type: embed.resource })}</span>
22
+ </Text>
23
+ );
25
24
  };
26
25
 
27
26
  export default UnknownEmbed;