@ndla/ui 55.0.13-alpha.0 → 55.0.15-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 (337) hide show
  1. package/dist/panda.buildinfo.json +142 -1
  2. package/dist/styles.css +597 -0
  3. package/es/Article/ArticleByline.js +7 -7
  4. package/es/Article/ArticleParagraph.js +11 -13
  5. package/es/AudioPlayer/AudioPlayer.js +1 -0
  6. package/es/CampaignBlock/CampaignBlock.js +103 -68
  7. package/es/Concept/Concept.js +69 -0
  8. package/es/ContactBlock/ContactBlock.js +17 -17
  9. package/es/ContentTypeBadge/ContentTypeBadgeNew.js +48 -0
  10. package/es/Embed/AudioEmbed.js +1 -2
  11. package/es/Embed/BrightcoveEmbed.js +13 -25
  12. package/es/Embed/ConceptEmbed.js +57 -301
  13. package/es/Embed/ConceptListEmbed.js +18 -24
  14. package/es/Embed/ContentLinkEmbed.js +10 -10
  15. package/es/Embed/CopyrightEmbed.js +3 -21
  16. package/es/Embed/ExternalEmbed.js +10 -18
  17. package/es/Embed/FootnoteEmbed.js +11 -8
  18. package/es/Embed/GlossEmbed.js +68 -0
  19. package/es/Embed/H5pEmbed.js +19 -19
  20. package/es/Embed/IframeEmbed.js +9 -6
  21. package/es/Embed/InlineTriggerButton.js +70 -0
  22. package/es/Embed/UnknownEmbed.js +9 -9
  23. package/es/Embed/UuDisclaimerEmbed.js +14 -25
  24. package/es/Embed/index.js +1 -3
  25. package/es/ErrorMessage/ErrorMessage.js +41 -22
  26. package/es/ErrorMessage/ErrorResourceAccessDenied.js +8 -6
  27. package/es/FactBox/FactBox.js +118 -47
  28. package/es/FileList/PdfFile.js +23 -5
  29. package/es/Gloss/Gloss.js +116 -86
  30. package/es/Gloss/GlossExample.js +49 -51
  31. package/es/LicenseByline/EmbedByline.js +143 -33
  32. package/es/LicenseByline/LicenseLink.js +16 -9
  33. package/es/LicenseByline/index.js +2 -2
  34. package/es/LinkBlock/LinkBlock.js +61 -33
  35. package/es/LinkBlock/LinkBlockSection.js +9 -6
  36. package/es/Logo/Logo.js +1 -30
  37. package/es/RelatedArticleList/RelatedArticleList.js +70 -87
  38. package/es/ResourceBox/ResourceBox.js +65 -37
  39. package/es/TagSelector/TagSelector.js +124 -131
  40. package/es/i18n/index.js +2 -1
  41. package/es/i18n/useComponentTranslations.js +83 -0
  42. package/es/index.js +4 -12
  43. package/es/locale/messages-en.js +30 -4
  44. package/es/locale/messages-nb.js +30 -4
  45. package/es/locale/messages-nn.js +30 -4
  46. package/es/locale/messages-se.js +30 -4
  47. package/es/locale/messages-sma.js +30 -4
  48. package/es/model/ContentType.js +3 -0
  49. package/es/styles.css +597 -0
  50. package/lib/Article/ArticleByline.js +8 -8
  51. package/lib/Article/ArticleParagraph.js +12 -14
  52. package/lib/AudioPlayer/AudioPlayer.js +1 -0
  53. package/lib/CampaignBlock/CampaignBlock.d.ts +2 -2
  54. package/lib/CampaignBlock/CampaignBlock.js +106 -68
  55. package/lib/Concept/Concept.d.ts +18 -0
  56. package/lib/Concept/Concept.js +75 -0
  57. package/lib/ContactBlock/ContactBlock.js +18 -18
  58. package/lib/ContentTypeBadge/ContentTypeBadgeNew.d.ts +17 -0
  59. package/lib/ContentTypeBadge/ContentTypeBadgeNew.js +56 -0
  60. package/lib/Embed/AudioEmbed.js +2 -3
  61. package/lib/Embed/BrightcoveEmbed.d.ts +1 -2
  62. package/lib/Embed/BrightcoveEmbed.js +16 -26
  63. package/lib/Embed/ConceptEmbed.d.ts +15 -21
  64. package/lib/Embed/ConceptEmbed.js +58 -301
  65. package/lib/Embed/ConceptListEmbed.js +21 -26
  66. package/lib/Embed/ContentLinkEmbed.js +10 -11
  67. package/lib/Embed/CopyrightEmbed.js +5 -22
  68. package/lib/Embed/ExternalEmbed.d.ts +1 -2
  69. package/lib/Embed/ExternalEmbed.js +13 -19
  70. package/lib/Embed/FootnoteEmbed.js +11 -9
  71. package/lib/Embed/GlossEmbed.d.ts +13 -0
  72. package/lib/Embed/GlossEmbed.js +76 -0
  73. package/lib/Embed/H5pEmbed.d.ts +1 -2
  74. package/lib/Embed/H5pEmbed.js +21 -19
  75. package/lib/Embed/IframeEmbed.d.ts +1 -2
  76. package/lib/Embed/IframeEmbed.js +11 -8
  77. package/lib/Embed/InlineTriggerButton.d.ts +11 -0
  78. package/lib/Embed/InlineTriggerButton.js +76 -0
  79. package/lib/Embed/UnknownEmbed.js +9 -10
  80. package/lib/Embed/UuDisclaimerEmbed.js +16 -26
  81. package/lib/Embed/index.d.ts +2 -3
  82. package/lib/Embed/index.js +2 -9
  83. package/lib/ErrorMessage/ErrorMessage.js +40 -23
  84. package/lib/ErrorMessage/ErrorResourceAccessDenied.js +7 -6
  85. package/lib/FactBox/FactBox.d.ts +0 -1
  86. package/lib/FactBox/FactBox.js +119 -46
  87. package/lib/FileList/PdfFile.js +23 -5
  88. package/lib/Gloss/Gloss.d.ts +10 -2
  89. package/lib/Gloss/Gloss.js +116 -85
  90. package/lib/Gloss/GlossExample.d.ts +3 -5
  91. package/lib/Gloss/GlossExample.js +49 -52
  92. package/lib/LicenseByline/EmbedByline.d.ts +2 -4
  93. package/lib/LicenseByline/EmbedByline.js +145 -35
  94. package/lib/LicenseByline/LicenseLink.d.ts +2 -2
  95. package/lib/LicenseByline/LicenseLink.js +16 -9
  96. package/lib/LicenseByline/index.d.ts +2 -2
  97. package/lib/LicenseByline/index.js +4 -5
  98. package/lib/LinkBlock/LinkBlock.js +62 -34
  99. package/lib/LinkBlock/LinkBlockSection.js +9 -7
  100. package/lib/Logo/Logo.d.ts +1 -3
  101. package/lib/Logo/Logo.js +2 -30
  102. package/lib/RelatedArticleList/RelatedArticleList.d.ts +4 -4
  103. package/lib/RelatedArticleList/RelatedArticleList.js +74 -90
  104. package/lib/ResourceBox/ResourceBox.js +64 -37
  105. package/lib/TagSelector/TagSelector.d.ts +27 -12
  106. package/lib/TagSelector/TagSelector.js +126 -131
  107. package/lib/i18n/index.d.ts +1 -0
  108. package/lib/i18n/index.js +20 -1
  109. package/lib/i18n/useComponentTranslations.d.ts +14 -0
  110. package/lib/i18n/useComponentTranslations.js +93 -0
  111. package/lib/index.d.ts +5 -15
  112. package/lib/index.js +70 -102
  113. package/lib/locale/messages-en.d.ts +26 -0
  114. package/lib/locale/messages-en.js +30 -4
  115. package/lib/locale/messages-nb.d.ts +26 -0
  116. package/lib/locale/messages-nb.js +30 -4
  117. package/lib/locale/messages-nn.d.ts +26 -0
  118. package/lib/locale/messages-nn.js +30 -4
  119. package/lib/locale/messages-se.d.ts +26 -0
  120. package/lib/locale/messages-se.js +30 -4
  121. package/lib/locale/messages-sma.d.ts +26 -0
  122. package/lib/locale/messages-sma.js +30 -4
  123. package/lib/model/ContentType.d.ts +3 -0
  124. package/lib/model/ContentType.js +4 -1
  125. package/lib/styles.css +597 -0
  126. package/package.json +11 -13
  127. package/src/Article/ArticleByline.tsx +1 -1
  128. package/src/Article/ArticleParagraph.tsx +11 -9
  129. package/src/AudioPlayer/AudioPlayer.tsx +1 -0
  130. package/src/CampaignBlock/CampaignBlock.tsx +92 -55
  131. package/src/Concept/Concept.stories.tsx +142 -0
  132. package/src/Concept/Concept.tsx +73 -0
  133. package/src/ContactBlock/ContactBlock.tsx +1 -1
  134. package/src/ContentTypeBadge/ContentTypeBadgeNew.stories.tsx +70 -0
  135. package/src/ContentTypeBadge/ContentTypeBadgeNew.tsx +69 -0
  136. package/src/Embed/AudioEmbed.tsx +2 -2
  137. package/src/Embed/BrightcoveEmbed.stories.tsx +0 -3
  138. package/src/Embed/BrightcoveEmbed.tsx +18 -20
  139. package/src/Embed/ConceptEmbed.stories.tsx +1 -105
  140. package/src/Embed/ConceptEmbed.tsx +60 -385
  141. package/src/Embed/ConceptListEmbed.tsx +20 -19
  142. package/src/Embed/ContentLinkEmbed.tsx +8 -10
  143. package/src/Embed/CopyrightEmbed.tsx +1 -11
  144. package/src/Embed/ExternalEmbed.tsx +14 -17
  145. package/src/Embed/FootnoteEmbed.stories.tsx +2 -5
  146. package/src/Embed/FootnoteEmbed.tsx +13 -16
  147. package/src/Embed/GlossEmbed.stories.tsx +140 -0
  148. package/src/Embed/GlossEmbed.tsx +64 -0
  149. package/src/Embed/H5pEmbed.tsx +22 -16
  150. package/src/Embed/IframeEmbed.tsx +12 -6
  151. package/src/Embed/InlineTriggerButton.tsx +72 -0
  152. package/src/Embed/UnknownEmbed.tsx +6 -7
  153. package/src/Embed/UuDisclaimerEmbed.stories.tsx +4 -4
  154. package/src/Embed/UuDisclaimerEmbed.tsx +17 -25
  155. package/src/Embed/index.ts +2 -3
  156. package/src/ErrorMessage/ErrorMessage.tsx +40 -29
  157. package/src/ErrorMessage/ErrorResourceAccessDenied.tsx +8 -6
  158. package/src/FactBox/FactBox.tsx +115 -115
  159. package/src/FactBox/Factbox.stories.tsx +43 -27
  160. package/src/FileList/FileList.stories.tsx +6 -1
  161. package/src/FileList/PdfFile.tsx +22 -5
  162. package/src/Gloss/Gloss.stories.tsx +107 -1
  163. package/src/Gloss/Gloss.tsx +143 -156
  164. package/src/Gloss/GlossExample.tsx +51 -77
  165. package/src/LicenseByline/EmbedByline.stories.tsx +9 -4
  166. package/src/LicenseByline/EmbedByline.tsx +139 -53
  167. package/src/LicenseByline/LicenseLink.tsx +15 -15
  168. package/src/LicenseByline/index.tsx +2 -2
  169. package/src/LinkBlock/LinkBlock.stories.tsx +8 -10
  170. package/src/LinkBlock/LinkBlock.tsx +54 -59
  171. package/src/LinkBlock/LinkBlockSection.tsx +9 -12
  172. package/src/Logo/Logo.stories.tsx +0 -1
  173. package/src/Logo/Logo.tsx +2 -30
  174. package/src/RelatedArticleList/RelatedArticleList.tsx +69 -88
  175. package/src/ResourceBox/ResourceBox.tsx +63 -59
  176. package/src/TagSelector/TagSelector.stories.tsx +92 -68
  177. package/src/TagSelector/TagSelector.tsx +161 -126
  178. package/src/i18n/index.ts +5 -0
  179. package/src/i18n/useComponentTranslations.ts +72 -0
  180. package/src/index.ts +23 -19
  181. package/src/locale/messages-en.ts +28 -2
  182. package/src/locale/messages-nb.ts +28 -2
  183. package/src/locale/messages-nn.ts +28 -2
  184. package/src/locale/messages-se.ts +28 -2
  185. package/src/locale/messages-sma.ts +28 -2
  186. package/src/model/ContentType.ts +3 -0
  187. package/es/DefinitionList/DefinitionDescription.js +0 -28
  188. package/es/DefinitionList/DefinitionTerm.js +0 -28
  189. package/es/DefinitionList/index.js +0 -10
  190. package/es/Embed/conceptComponents.js +0 -155
  191. package/es/ExpandableBox/ExpandableBox.js +0 -29
  192. package/es/ExpandableBox/index.js +0 -9
  193. package/es/Figure/Figure.js +0 -73
  194. package/es/Figure/index.js +0 -9
  195. package/es/FramedContent/FramedContent.js +0 -28
  196. package/es/FramedContent/index.js +0 -10
  197. package/es/Image/Image.js +0 -99
  198. package/es/Image/ImageLink.js +0 -39
  199. package/es/Image/index.js +0 -12
  200. package/es/LetterFilter/LetterFilter.js +0 -54
  201. package/es/LetterFilter/alphabet.js +0 -9
  202. package/es/LetterFilter/index.js +0 -10
  203. package/es/LicenseByline/LicenseDescription.js +0 -63
  204. package/es/List/OrderedList.js +0 -41
  205. package/es/List/UnOrderedList.js +0 -28
  206. package/es/List/index.js +0 -10
  207. package/es/Notion/Notion.js +0 -76
  208. package/es/Notion/NotionImage.js +0 -46
  209. package/es/Notion/index.js +0 -9
  210. package/es/Table/Table.js +0 -141
  211. package/es/Table/index.js +0 -11
  212. package/es/TagSelector/Control.js +0 -28
  213. package/es/TagSelector/DropdownIndicator.js +0 -60
  214. package/es/TagSelector/Input.js +0 -22
  215. package/es/TagSelector/Menu.js +0 -27
  216. package/es/TagSelector/MenuList.js +0 -28
  217. package/es/TagSelector/Option.js +0 -60
  218. package/es/TagSelector/SelectContainer.js +0 -27
  219. package/es/TagSelector/ValueButton.js +0 -53
  220. package/es/TagSelector/ariaMessages.js +0 -94
  221. package/es/TagSelector/index.js +0 -10
  222. package/es/TagSelector/types.js +0 -1
  223. package/lib/DefinitionList/DefinitionDescription.d.ts +0 -10
  224. package/lib/DefinitionList/DefinitionDescription.js +0 -35
  225. package/lib/DefinitionList/DefinitionTerm.d.ts +0 -10
  226. package/lib/DefinitionList/DefinitionTerm.js +0 -35
  227. package/lib/DefinitionList/index.d.ts +0 -9
  228. package/lib/DefinitionList/index.js +0 -20
  229. package/lib/Embed/conceptComponents.d.ts +0 -40
  230. package/lib/Embed/conceptComponents.js +0 -163
  231. package/lib/ExpandableBox/ExpandableBox.d.ts +0 -15
  232. package/lib/ExpandableBox/ExpandableBox.js +0 -37
  233. package/lib/ExpandableBox/index.d.ts +0 -8
  234. package/lib/ExpandableBox/index.js +0 -18
  235. package/lib/Figure/Figure.d.ts +0 -16
  236. package/lib/Figure/Figure.js +0 -81
  237. package/lib/Figure/index.d.ts +0 -9
  238. package/lib/Figure/index.js +0 -13
  239. package/lib/FramedContent/FramedContent.d.ts +0 -12
  240. package/lib/FramedContent/FramedContent.js +0 -35
  241. package/lib/FramedContent/index.d.ts +0 -9
  242. package/lib/FramedContent/index.js +0 -16
  243. package/lib/Image/Image.d.ts +0 -38
  244. package/lib/Image/Image.js +0 -105
  245. package/lib/Image/ImageLink.d.ts +0 -18
  246. package/lib/Image/ImageLink.js +0 -44
  247. package/lib/Image/index.d.ts +0 -12
  248. package/lib/Image/index.js +0 -30
  249. package/lib/LetterFilter/LetterFilter.d.ts +0 -14
  250. package/lib/LetterFilter/LetterFilter.js +0 -61
  251. package/lib/LetterFilter/alphabet.d.ts +0 -8
  252. package/lib/LetterFilter/alphabet.js +0 -15
  253. package/lib/LetterFilter/index.d.ts +0 -9
  254. package/lib/LetterFilter/index.js +0 -16
  255. package/lib/LicenseByline/LicenseDescription.d.ts +0 -15
  256. package/lib/LicenseByline/LicenseDescription.js +0 -70
  257. package/lib/List/OrderedList.d.ts +0 -16
  258. package/lib/List/OrderedList.js +0 -48
  259. package/lib/List/UnOrderedList.d.ts +0 -10
  260. package/lib/List/UnOrderedList.js +0 -35
  261. package/lib/List/index.d.ts +0 -9
  262. package/lib/List/index.js +0 -20
  263. package/lib/Notion/Notion.d.ts +0 -20
  264. package/lib/Notion/Notion.js +0 -82
  265. package/lib/Notion/NotionImage.d.ts +0 -13
  266. package/lib/Notion/NotionImage.js +0 -54
  267. package/lib/Notion/index.d.ts +0 -8
  268. package/lib/Notion/index.js +0 -13
  269. package/lib/Table/Table.d.ts +0 -19
  270. package/lib/Table/Table.js +0 -145
  271. package/lib/Table/index.d.ts +0 -10
  272. package/lib/Table/index.js +0 -23
  273. package/lib/TagSelector/Control.d.ts +0 -11
  274. package/lib/TagSelector/Control.js +0 -35
  275. package/lib/TagSelector/DropdownIndicator.d.ts +0 -11
  276. package/lib/TagSelector/DropdownIndicator.js +0 -64
  277. package/lib/TagSelector/Input.d.ts +0 -12
  278. package/lib/TagSelector/Input.js +0 -29
  279. package/lib/TagSelector/Menu.d.ts +0 -12
  280. package/lib/TagSelector/Menu.js +0 -34
  281. package/lib/TagSelector/MenuList.d.ts +0 -16
  282. package/lib/TagSelector/MenuList.js +0 -35
  283. package/lib/TagSelector/Option.d.ts +0 -12
  284. package/lib/TagSelector/Option.js +0 -67
  285. package/lib/TagSelector/SelectContainer.d.ts +0 -11
  286. package/lib/TagSelector/SelectContainer.js +0 -34
  287. package/lib/TagSelector/ValueButton.d.ts +0 -20
  288. package/lib/TagSelector/ValueButton.js +0 -60
  289. package/lib/TagSelector/ariaMessages.d.ts +0 -16
  290. package/lib/TagSelector/ariaMessages.js +0 -101
  291. package/lib/TagSelector/index.d.ts +0 -11
  292. package/lib/TagSelector/index.js +0 -13
  293. package/lib/TagSelector/types.d.ts +0 -11
  294. package/lib/TagSelector/types.js +0 -5
  295. package/src/DefinitionList/DefinitionDescription.tsx +0 -26
  296. package/src/DefinitionList/DefinitionTerm.tsx +0 -26
  297. package/src/DefinitionList/index.tsx +0 -10
  298. package/src/Embed/conceptComponents.tsx +0 -293
  299. package/src/ExpandableBox/ExpandableBox.stories.tsx +0 -41
  300. package/src/ExpandableBox/ExpandableBox.tsx +0 -23
  301. package/src/ExpandableBox/index.ts +0 -9
  302. package/src/Figure/Figure.tsx +0 -167
  303. package/src/Figure/index.ts +0 -11
  304. package/src/FramedContent/FramedContent.stories.tsx +0 -152
  305. package/src/FramedContent/FramedContent.tsx +0 -26
  306. package/src/FramedContent/index.ts +0 -10
  307. package/src/Image/Image.stories.tsx +0 -61
  308. package/src/Image/Image.tsx +0 -147
  309. package/src/Image/ImageLink.tsx +0 -37
  310. package/src/Image/index.ts +0 -14
  311. package/src/LetterFilter/LetterFilter.stories.tsx +0 -29
  312. package/src/LetterFilter/LetterFilter.tsx +0 -78
  313. package/src/LetterFilter/alphabet.ts +0 -39
  314. package/src/LetterFilter/index.ts +0 -11
  315. package/src/LicenseByline/LicenseDescription.tsx +0 -100
  316. package/src/List/OrderedList.stories.tsx +0 -135
  317. package/src/List/OrderedList.tsx +0 -158
  318. package/src/List/UnOrderedList.tsx +0 -43
  319. package/src/List/UnorderedList.stories.tsx +0 -72
  320. package/src/List/index.ts +0 -10
  321. package/src/Notion/Notion.tsx +0 -96
  322. package/src/Notion/NotionImage.tsx +0 -64
  323. package/src/Notion/index.ts +0 -9
  324. package/src/Table/Table.stories.tsx +0 -738
  325. package/src/Table/Table.tsx +0 -284
  326. package/src/Table/index.ts +0 -12
  327. package/src/TagSelector/Control.tsx +0 -34
  328. package/src/TagSelector/DropdownIndicator.tsx +0 -55
  329. package/src/TagSelector/Input.tsx +0 -31
  330. package/src/TagSelector/Menu.tsx +0 -38
  331. package/src/TagSelector/MenuList.tsx +0 -30
  332. package/src/TagSelector/Option.tsx +0 -58
  333. package/src/TagSelector/SelectContainer.tsx +0 -31
  334. package/src/TagSelector/ValueButton.tsx +0 -47
  335. package/src/TagSelector/ariaMessages.ts +0 -96
  336. package/src/TagSelector/index.ts +0 -14
  337. package/src/TagSelector/types.ts +0 -12
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) 2023-present, NDLA.
2
+ * Copyright (c) 2024-present, NDLA.
3
3
  *
4
4
  * This source code is licensed under the GPLv3 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -7,431 +7,106 @@
7
7
  */
8
8
 
9
9
  import parse from "html-react-parser";
10
- import { ReactNode, forwardRef, useCallback, useMemo, useRef, useState } from "react";
11
- import { isMobile } from "react-device-detect";
12
- import { useTranslation } from "react-i18next";
13
- import styled from "@emotion/styled";
14
- import { Root, Trigger, Content, Anchor, Close, Portal } from "@radix-ui/react-popover";
15
- import { IconButtonV2 } from "@ndla/button";
16
- import { breakpoints, colors, mq, spacing, stackOrder } from "@ndla/core";
17
- import { Cross } from "@ndla/icons/action";
18
- import { Tooltip } from "@ndla/tooltip";
10
+ import { forwardRef, useMemo } from "react";
11
+ import { Figure, PopoverContent, PopoverRoot, PopoverTrigger } from "@ndla/primitives";
12
+ import { styled } from "@ndla/styled-system/jsx";
19
13
  import { ConceptMetaData } from "@ndla/types-embed";
20
- import { ConceptNotionV2, ConceptNotionData, ConceptType } from "./conceptComponents";
21
14
  import EmbedErrorPlaceholder from "./EmbedErrorPlaceholder";
15
+ import { GlossEmbed } from "./GlossEmbed";
16
+ import { InlineTriggerButton } from "./InlineTriggerButton";
22
17
  import { RenderContext } from "./types";
23
- import { Figure } from "../Figure";
24
- import { Gloss } from "../Gloss";
25
- import { EmbedByline } from "../LicenseByline";
26
- import { Notion as UINotion } from "../Notion";
27
- import { NotionImage } from "../Notion/NotionImage";
18
+ import { Concept, ConceptProps } from "../Concept/Concept";
28
19
 
29
- interface PopoverPosition {
30
- top?: number;
20
+ interface BaseProps {
21
+ renderContext?: RenderContext;
22
+ lang?: string;
31
23
  }
32
24
 
33
- const PopoverWrapper = styled.div<PopoverPosition>`
34
- div[data-radix-popper-content-wrapper] {
35
- position: absolute !important;
36
- left: 50% !important;
37
- transform: translateX(-50%) !important;
38
- top: ${({ top }) => top}px !important;
39
- z-index: ${stackOrder.popover} !important;
40
- }
41
-
42
- ${mq.range({ until: breakpoints.tablet })} {
43
- div[data-radix-popper-content-wrapper] {
44
- // Fix for popover positioning on mobile.
45
- // If we modify all popovers we break license icons.
46
- // https://github.com/radix-ui/primitives/issues/1839
47
- position: fixed !important;
48
- transform: none !important;
49
- top: 0 !important;
50
- left: 0 !important;
51
- width: 100vw;
52
- z-index: ${stackOrder.popover} !important;
53
- height: 100vh;
54
- min-width: 100vw !important;
55
- }
56
- }
57
- `;
58
-
59
- const ImageWrapper = styled.div`
60
- float: right;
61
- padding-left: ${spacing.normal};
62
- position: relative;
63
-
64
- ${mq.range({ until: breakpoints.tabletWide })} {
65
- width: 100%;
66
- padding-left: 0;
67
- }
68
- `;
69
-
70
- interface Props {
25
+ interface Props extends BaseProps {
71
26
  embed: ConceptMetaData;
72
- fullWidth?: boolean;
73
- lang?: string;
74
- renderContext?: RenderContext;
75
27
  }
76
28
 
77
- const StyledButton = styled.button`
78
- background: none;
79
- border: none;
80
- font-family: inherit;
81
- font-style: inherit;
82
- line-height: 1em;
83
- padding: 0 0 ${spacing.xxsmall} 0;
84
- margin-bottom: -${spacing.xxsmall};
85
- text-decoration: none;
86
- color: #000;
87
- position: relative;
88
- cursor: pointer;
89
- &:focus,
90
- &:hover {
91
- color: ${colors.brand.primary};
92
- outline: none;
93
- }
94
- `;
29
+ const StyledPopoverContent = styled(PopoverContent, {
30
+ base: {
31
+ width: "surface.xlarge",
32
+ },
33
+ });
95
34
 
96
- export const ConceptEmbed = ({ embed, fullWidth, lang, renderContext }: Props) => {
35
+ export const ConceptEmbed = ({ embed, renderContext, lang }: Props) => {
97
36
  const parsedContent = useMemo(() => {
98
37
  if (embed.status === "error" || !embed.data.concept.content) return undefined;
99
38
  return parse(embed.data.concept.content.htmlContent);
100
39
  }, [embed]);
40
+
101
41
  if (embed.status === "error" && embed.embedData.type === "inline") {
102
42
  return <span>{embed.embedData.linkText}</span>;
103
43
  }
104
44
  if (embed.status === "error") {
105
- return <EmbedErrorPlaceholder type="concept" />;
45
+ return <EmbedErrorPlaceholder type="gloss" />;
106
46
  }
107
47
 
108
- const {
109
- data: { concept, visualElement },
110
- } = embed;
48
+ const { concept, visualElement } = embed.data;
111
49
 
112
- if (embed.embedData.type === "block") {
113
- return (
114
- <BlockConcept
115
- fullWidth={fullWidth}
116
- title={concept.title}
117
- content={parsedContent}
118
- metaImage={concept.metaImage}
119
- copyright={concept.copyright}
120
- source={concept.source}
121
- visualElement={visualElement}
122
- conceptType={concept.conceptType}
123
- glossData={concept.glossData}
124
- lang={lang}
125
- exampleIds={embed.embedData.exampleIds}
126
- exampleLangs={embed.embedData.exampleLangs}
127
- />
128
- );
50
+ // TODO: Consider whether we should do this in article-converter instead.
51
+ if (embed.data.concept.glossData) {
52
+ return <GlossEmbed embed={embed} />;
129
53
  }
54
+
130
55
  if (embed.embedData.type === "inline") {
131
56
  return (
132
57
  <InlineConcept
133
- title={concept.title}
134
- content={parsedContent}
135
- metaImage={concept.metaImage}
58
+ linkText={embed.embedData.linkText}
136
59
  copyright={concept.copyright}
137
- source={concept.source}
138
60
  visualElement={visualElement}
139
- linkText={embed.embedData.linkText}
140
- conceptType={concept.conceptType}
141
- glossData={concept.glossData}
142
61
  lang={lang}
143
- exampleIds={embed.embedData.exampleIds}
144
- exampleLangs={embed.embedData.exampleLangs}
145
- />
62
+ title={concept.title.title}
63
+ >
64
+ {parsedContent}
65
+ </InlineConcept>
146
66
  );
147
67
  }
68
+
148
69
  return (
149
- <ConceptNotionV2
150
- title={concept.title}
151
- content={parsedContent}
70
+ <BlockConcept
152
71
  copyright={concept.copyright}
153
- source={concept.source}
154
72
  visualElement={visualElement}
155
- conceptType={concept.conceptType}
156
- glossData={concept.glossData}
157
73
  lang={lang}
158
- exampleIds={embed.embedData.exampleIds}
159
- exampleLangs={embed.embedData.exampleLangs}
160
- showTitle={renderContext !== "embed"}
161
- />
74
+ title={renderContext === "embed" ? undefined : concept.title.title}
75
+ >
76
+ {parsedContent}
77
+ </BlockConcept>
162
78
  );
163
79
  };
164
80
 
165
- interface InlineConceptProps extends ConceptNotionData {
166
- linkText: ReactNode;
167
- headerButtons?: ReactNode;
168
- exampleIds?: string;
169
- exampleLangs?: string;
170
- setSelection?: (e: MouseEvent) => void;
81
+ export interface InlineConceptProps extends ConceptProps, BaseProps {
82
+ linkText?: string;
171
83
  }
172
84
 
173
- const NotionButton = styled.span`
174
- background: none;
175
- border: none;
176
- font-family: inherit;
177
- font-style: inherit;
178
- line-height: 1em;
179
- text-decoration: none;
180
- position: relative;
181
- text-align: left;
182
- color: ${colors.concept.text};
183
- cursor: pointer;
184
- &:focus,
185
- &:hover,
186
- &:active,
187
- &[data-open="true"] {
188
- color: ${colors.concept.text};
189
- background-color: ${colors.concept.light};
190
- }
191
- display: inline;
192
- border-bottom: 5px double currentColor;
193
- `;
194
-
195
- const StyledAnchor = styled(Anchor)`
196
- ${mq.range({ until: breakpoints.tablet })} {
197
- position: fixed;
198
- top: 0;
199
- }
200
- `;
201
-
202
- const StyledAnchorSpan = styled.span`
203
- position: absolute;
204
- left: 50%;
205
- align-self: center;
206
- `;
207
-
208
- const getModalPosition = (anchor: HTMLElement) => {
209
- const article = anchor.closest("[data-ndla-article]");
210
- const articlePos = article?.getBoundingClientRect();
211
- const anchorPos = anchor.getBoundingClientRect();
212
- return anchorPos.top - (articlePos?.top || -window.scrollY) + 30; // add 30 so that position is under the word
213
- };
85
+ // TODO: Consider if we should make this act like the old concept popover.
86
+ // Should it take up the entire screen height on mobile? I don't think we need to.
87
+ // Should it always stay directly underneath the trigger?
214
88
 
215
89
  export const InlineConcept = forwardRef<HTMLSpanElement, InlineConceptProps>(
216
- (
217
- {
218
- title,
219
- content,
220
- copyright,
221
- source,
222
- visualElement,
223
- linkText,
224
- glossData,
225
- conceptType,
226
- headerButtons,
227
- lang,
228
- exampleIds,
229
- exampleLangs,
230
- setSelection,
231
- ...rest
232
- },
233
- ref,
234
- ) => {
235
- const { t } = useTranslation();
236
- const anchorRef = useRef<HTMLDivElement>(null);
237
- const [modalPos, setModalPos] = useState(-9999);
238
-
239
- const onOpenChange = useCallback((open: boolean) => {
240
- if (open) {
241
- const anchor = anchorRef.current;
242
- if (anchor) {
243
- const top = getModalPosition(anchor);
244
- setModalPos(top);
245
- }
246
- } else {
247
- setModalPos(-9999);
248
- }
249
- }, []);
250
-
251
- const preventAutoFocusInEditor = useCallback(
252
- (e: MouseEvent) => {
253
- e.preventDefault();
254
- e.stopPropagation();
255
- setSelection?.(e);
256
- },
257
- [setSelection],
258
- );
259
-
260
- return (
261
- <Root modal={isMobile} onOpenChange={onOpenChange}>
262
- <StyledAnchor ref={anchorRef} asChild>
263
- <StyledAnchorSpan contentEditable={false} />
264
- </StyledAnchor>
265
- <Trigger asChild>
266
- <NotionButton
267
- onMouseDown={(e) => (setSelection ? preventAutoFocusInEditor(e.nativeEvent) : undefined)}
268
- data-open={modalPos !== -9999}
269
- role="button"
270
- tabIndex={0}
271
- ref={ref}
272
- {...rest}
273
- >
274
- {linkText}
275
- </NotionButton>
276
- </Trigger>
277
- <Portal container={(anchorRef.current?.closest("[data-ndla-article]") as HTMLElement | null) || undefined}>
278
- <PopoverWrapper top={modalPos}>
279
- <Content avoidCollisions={false} side="bottom" asChild>
280
- <ConceptNotionV2
281
- title={title}
282
- content={content}
283
- copyright={copyright}
284
- source={source}
285
- visualElement={visualElement}
286
- inPopover
287
- headerButtons={headerButtons}
288
- lang={lang}
289
- closeButton={
290
- <Close asChild>
291
- <IconButtonV2 aria-label={t("close")} variant="ghost">
292
- <Cross />
293
- </IconButtonV2>
294
- </Close>
295
- }
296
- conceptType={conceptType}
297
- glossData={glossData}
298
- exampleIds={exampleIds}
299
- exampleLangs={exampleLangs}
300
- />
301
- </Content>
302
- </PopoverWrapper>
303
- </Portal>
304
- </Root>
305
- );
306
- },
90
+ ({ linkText, copyright, visualElement, lang, children, title, ...rest }, ref) => (
91
+ <PopoverRoot>
92
+ <PopoverTrigger asChild>
93
+ <InlineTriggerButton {...rest} ref={ref}>
94
+ {linkText}
95
+ </InlineTriggerButton>
96
+ </PopoverTrigger>
97
+ <StyledPopoverContent>
98
+ <Figure>
99
+ <Concept copyright={copyright} visualElement={visualElement} lang={lang} title={title}>
100
+ {children}
101
+ </Concept>
102
+ </Figure>
103
+ </StyledPopoverContent>
104
+ </PopoverRoot>
105
+ ),
307
106
  );
308
107
 
309
- interface ConceptProps extends ConceptNotionData {
310
- fullWidth?: boolean;
311
- exampleIds?: string;
312
- exampleLangs?: string;
313
- }
314
-
315
- export const BlockConcept = ({
316
- title,
317
- content,
318
- metaImage,
319
- copyright,
320
- source,
321
- visualElement,
322
- fullWidth,
323
- glossData,
324
- conceptType,
325
- lang,
326
- exampleIds,
327
- exampleLangs,
328
- }: ConceptProps) => {
329
- const { t } = useTranslation();
330
- const anchorRef = useRef<HTMLDivElement>(null);
331
- const [modalPos, setModalPos] = useState(-9999);
332
-
333
- const onOpenChange = useCallback((open: boolean) => {
334
- if (open) {
335
- const anchor = anchorRef.current;
336
- if (anchor) {
337
- const top = getModalPosition(anchor);
338
- setModalPos(top);
339
- }
340
- } else {
341
- setModalPos(-9999);
342
- }
343
- }, []);
344
-
345
- return (
346
- <Root modal={isMobile} onOpenChange={onOpenChange}>
347
- <StyledAnchor ref={anchorRef} />
348
- <Figure type={fullWidth ? "full" : "full-column"}>
349
- {conceptType === "concept" ? (
350
- <UINotion
351
- id=""
352
- title={title.title}
353
- text={content}
354
- lang={lang}
355
- visualElement={
356
- visualElement?.status === "success" && (
357
- <>
358
- <ImageWrapper>
359
- <Tooltip tooltip={t(`searchPage.resultType.${conceptType}`)}>
360
- <Trigger asChild>
361
- <StyledButton
362
- type="button"
363
- aria-label={t("concept.showDescription", {
364
- title: title,
365
- })}
366
- >
367
- {visualElement.resource === "image" ? (
368
- <NotionImage
369
- src={visualElement.data.image.imageUrl}
370
- alt={visualElement.data.alttext.alttext}
371
- />
372
- ) : metaImage ? (
373
- <NotionImage src={metaImage?.url ?? ""} alt={metaImage?.alt ?? ""} />
374
- ) : undefined}
375
- </StyledButton>
376
- </Trigger>
377
- </Tooltip>
378
- </ImageWrapper>
379
- <Portal
380
- container={
381
- typeof document !== "undefined"
382
- ? (document.querySelector("[data-ndla-article]") as HTMLElement | null) || undefined
383
- : undefined
384
- }
385
- >
386
- <PopoverWrapper top={modalPos}>
387
- <Content avoidCollisions={false} asChild side="bottom">
388
- <ConceptNotionV2
389
- title={title}
390
- content={content}
391
- copyright={copyright}
392
- source={source}
393
- visualElement={visualElement}
394
- inPopover
395
- lang={lang}
396
- closeButton={
397
- <Close asChild>
398
- <IconButtonV2 aria-label={t("close")} variant="ghost">
399
- <Cross />
400
- </IconButtonV2>
401
- </Close>
402
- }
403
- conceptType={conceptType}
404
- glossData={glossData}
405
- />
406
- </Content>
407
- </PopoverWrapper>
408
- </Portal>
409
- </>
410
- )
411
- }
412
- />
413
- ) : (
414
- <Gloss
415
- glossData={glossData}
416
- title={title}
417
- audio={
418
- visualElement?.status === "success" && visualElement.resource === "audio"
419
- ? {
420
- src: visualElement.data.audioFile.url,
421
- title: visualElement.data.title.title,
422
- }
423
- : undefined
424
- }
425
- exampleIds={exampleIds}
426
- exampleLangs={exampleLangs}
427
- />
428
- )}
429
- {copyright && conceptType === "concept" && (
430
- <EmbedByline copyright={copyright} type={conceptType as ConceptType} />
431
- )}
432
- </Figure>
433
- </Root>
434
- );
435
- };
108
+ export interface BlockConceptProps extends ConceptProps {}
436
109
 
437
- export default ConceptEmbed;
110
+ export const BlockConcept = forwardRef<HTMLElement, BlockConceptProps>((props, ref) => (
111
+ <Concept {...props} ref={ref} />
112
+ ));
@@ -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} />
33
23
  </figure>
34
24
  );
35
25
  };