@ndla/ui 55.0.12-alpha.0 → 55.0.13-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 (192) hide show
  1. package/dist/all-aout.js +0 -0
  2. package/dist/all.css +1 -0
  3. package/dist/panda.buildinfo.json +170 -0
  4. package/dist/styles.css +686 -0
  5. package/es/Article/Article.js +3 -4
  6. package/es/Article/ArticleByline.js +9 -9
  7. package/es/Article/ArticleFootNotes.js +4 -4
  8. package/es/AudioPlayer/AudioPlayer.js +142 -163
  9. package/es/AudioPlayer/Controls.js +187 -203
  10. package/es/AudioPlayer/SpeechControl.js +13 -11
  11. package/es/BlogPost/BlogPost.js +85 -23
  12. package/es/CampaignBlock/CampaignBlock.js +3 -4
  13. package/es/CodeBlock/CodeBlock.js +88 -96
  14. package/es/ContactBlock/ContactBlock.js +54 -40
  15. package/es/ContentLoader/index.js +7 -7
  16. package/es/CopyParagraphButton/CopyParagraphButton.js +4 -4
  17. package/es/Embed/AudioEmbed.js +5 -9
  18. package/es/Embed/BrightcoveEmbed.js +12 -15
  19. package/es/Embed/CodeEmbed.js +58 -10
  20. package/es/Embed/ConceptEmbed.js +15 -20
  21. package/es/Embed/ContentLinkEmbed.js +1 -1
  22. package/es/Embed/EmbedErrorPlaceholder.js +32 -17
  23. package/es/Embed/ExternalEmbed.js +7 -10
  24. package/es/Embed/FootnoteEmbed.js +3 -3
  25. package/es/Embed/H5pEmbed.js +1 -2
  26. package/es/Embed/IframeEmbed.js +8 -9
  27. package/es/Embed/ImageEmbed.js +167 -122
  28. package/es/Embed/RelatedContentEmbed.js +8 -10
  29. package/es/Embed/UuDisclaimerEmbed.js +2 -2
  30. package/es/Embed/conceptComponents.js +9 -9
  31. package/es/ErrorMessage/ErrorMessage.js +1 -1
  32. package/es/FactBox/FactBox.js +2 -2
  33. package/es/FileList/File.js +1 -1
  34. package/es/FileList/Format.js +3 -3
  35. package/es/FrontpageArticle/FrontpageArticle.js +1 -1
  36. package/es/Gloss/Gloss.js +9 -11
  37. package/es/Gloss/GlossExample.js +3 -4
  38. package/es/Grid/Grid.js +1 -1
  39. package/es/Image/Image.js +7 -8
  40. package/es/Image/ImageLink.js +1 -1
  41. package/es/KeyFigure/KeyFigure.js +2 -2
  42. package/es/LanguageSelector/LanguageSelector.js +2 -2
  43. package/es/LetterFilter/LetterFilter.js +1 -1
  44. package/es/LicenseByline/EmbedByline.js +5 -6
  45. package/es/LicenseByline/LicenseDescription.js +1 -1
  46. package/es/LicenseByline/LicenseLink.js +1 -2
  47. package/es/Messages/MessageBox.js +1 -1
  48. package/es/Notion/Notion.js +2 -2
  49. package/es/Notion/NotionImage.js +12 -57
  50. package/es/RelatedArticleList/RelatedArticleList.js +3 -3
  51. package/es/ResourceBox/ResourceBox.js +12 -17
  52. package/es/Search/ActiveFilters.js +1 -1
  53. package/es/Search/ContentTypeResult.js +9 -6
  54. package/es/Search/ContentTypeResultStyles.js +1 -1
  55. package/es/Search/IsPathToHighlight.js +1 -1
  56. package/es/Search/SearchField.js +6 -8
  57. package/es/Search/SearchResult.js +14 -19
  58. package/es/Search/SearchResultSleeve.js +14 -16
  59. package/es/SnackBar/SnackbarProvider.js +8 -11
  60. package/es/TagSelector/TagSelector.js +1 -1
  61. package/es/TagSelector/ariaMessages.js +6 -6
  62. package/es/TreeStructure/AddFolderButton.js +4 -6
  63. package/es/TreeStructure/ComboboxButton.js +4 -7
  64. package/es/TreeStructure/FolderItem.js +12 -15
  65. package/es/TreeStructure/FolderItems.js +3 -3
  66. package/es/TreeStructure/TreeStructure.js +9 -12
  67. package/es/TreeStructure/helperFunctions.js +1 -1
  68. package/es/ZendeskButton/ZendeskButton.js +55 -0
  69. package/es/i18n/formatNestedMessages.js +1 -1
  70. package/es/index.js +2 -1
  71. package/es/locale/messages-en.js +9 -8
  72. package/es/locale/messages-nb.js +9 -8
  73. package/es/locale/messages-nn.js +9 -8
  74. package/es/locale/messages-se.js +9 -8
  75. package/es/locale/messages-sma.js +9 -8
  76. package/es/styles.css +686 -0
  77. package/es/utils/relativeUrl.js +3 -3
  78. package/lib/Article/Article.js +3 -4
  79. package/lib/Article/ArticleByline.js +9 -9
  80. package/lib/Article/ArticleFootNotes.js +4 -4
  81. package/lib/AudioPlayer/AudioPlayer.d.ts +1 -2
  82. package/lib/AudioPlayer/AudioPlayer.js +142 -162
  83. package/lib/AudioPlayer/Controls.js +190 -205
  84. package/lib/AudioPlayer/SpeechControl.js +13 -11
  85. package/lib/BlogPost/BlogPost.d.ts +2 -2
  86. package/lib/BlogPost/BlogPost.js +85 -24
  87. package/lib/CampaignBlock/CampaignBlock.js +3 -4
  88. package/lib/CodeBlock/CodeBlock.d.ts +5 -8
  89. package/lib/CodeBlock/CodeBlock.js +88 -96
  90. package/lib/ContactBlock/ContactBlock.js +55 -43
  91. package/lib/ContentLoader/index.js +7 -7
  92. package/lib/CopyParagraphButton/CopyParagraphButton.js +4 -4
  93. package/lib/Embed/AudioEmbed.js +5 -9
  94. package/lib/Embed/BrightcoveEmbed.js +12 -15
  95. package/lib/Embed/CodeEmbed.js +56 -8
  96. package/lib/Embed/ConceptEmbed.js +15 -20
  97. package/lib/Embed/ContentLinkEmbed.js +1 -1
  98. package/lib/Embed/EmbedErrorPlaceholder.d.ts +4 -3
  99. package/lib/Embed/EmbedErrorPlaceholder.js +32 -18
  100. package/lib/Embed/ExternalEmbed.js +7 -10
  101. package/lib/Embed/FootnoteEmbed.js +3 -3
  102. package/lib/Embed/H5pEmbed.js +1 -2
  103. package/lib/Embed/IframeEmbed.js +8 -9
  104. package/lib/Embed/ImageEmbed.d.ts +1 -2
  105. package/lib/Embed/ImageEmbed.js +167 -123
  106. package/lib/Embed/RelatedContentEmbed.js +8 -10
  107. package/lib/Embed/UuDisclaimerEmbed.js +2 -2
  108. package/lib/Embed/conceptComponents.js +9 -9
  109. package/lib/ErrorMessage/ErrorMessage.js +1 -1
  110. package/lib/FactBox/FactBox.js +2 -2
  111. package/lib/FileList/File.js +1 -1
  112. package/lib/FileList/Format.js +3 -3
  113. package/lib/FrontpageArticle/FrontpageArticle.js +1 -1
  114. package/lib/Gloss/Gloss.js +9 -11
  115. package/lib/Gloss/GlossExample.js +3 -4
  116. package/lib/Grid/Grid.js +1 -1
  117. package/lib/Image/Image.js +7 -8
  118. package/lib/Image/ImageLink.js +1 -1
  119. package/lib/KeyFigure/KeyFigure.js +2 -2
  120. package/lib/LanguageSelector/LanguageSelector.js +2 -2
  121. package/lib/LetterFilter/LetterFilter.js +1 -1
  122. package/lib/LicenseByline/EmbedByline.js +5 -6
  123. package/lib/LicenseByline/LicenseDescription.js +1 -1
  124. package/lib/LicenseByline/LicenseLink.js +1 -2
  125. package/lib/Messages/MessageBox.js +1 -1
  126. package/lib/Notion/Notion.js +2 -2
  127. package/lib/Notion/NotionImage.d.ts +1 -11
  128. package/lib/Notion/NotionImage.js +12 -59
  129. package/lib/RelatedArticleList/RelatedArticleList.js +3 -3
  130. package/lib/ResourceBox/ResourceBox.js +13 -18
  131. package/lib/Search/ActiveFilters.js +1 -1
  132. package/lib/Search/ContentTypeResult.js +9 -6
  133. package/lib/Search/ContentTypeResultStyles.js +1 -1
  134. package/lib/Search/IsPathToHighlight.js +1 -1
  135. package/lib/Search/SearchField.js +6 -8
  136. package/lib/Search/SearchResult.js +14 -19
  137. package/lib/Search/SearchResultSleeve.js +14 -16
  138. package/lib/SnackBar/SnackbarProvider.js +8 -11
  139. package/lib/TagSelector/TagSelector.js +1 -1
  140. package/lib/TagSelector/ariaMessages.js +6 -6
  141. package/lib/TreeStructure/AddFolderButton.js +4 -6
  142. package/lib/TreeStructure/ComboboxButton.js +4 -7
  143. package/lib/TreeStructure/FolderItem.js +12 -15
  144. package/lib/TreeStructure/FolderItems.js +3 -3
  145. package/lib/TreeStructure/TreeStructure.js +9 -12
  146. package/lib/TreeStructure/helperFunctions.js +1 -1
  147. package/lib/ZendeskButton/ZendeskButton.d.ts +19 -0
  148. package/lib/ZendeskButton/ZendeskButton.js +61 -0
  149. package/lib/i18n/formatNestedMessages.js +1 -1
  150. package/lib/index.d.ts +2 -0
  151. package/lib/index.js +7 -0
  152. package/lib/locale/messages-en.d.ts +1 -0
  153. package/lib/locale/messages-en.js +9 -8
  154. package/lib/locale/messages-nb.d.ts +1 -0
  155. package/lib/locale/messages-nb.js +9 -8
  156. package/lib/locale/messages-nn.d.ts +1 -0
  157. package/lib/locale/messages-nn.js +9 -8
  158. package/lib/locale/messages-se.d.ts +1 -0
  159. package/lib/locale/messages-se.js +9 -8
  160. package/lib/locale/messages-sma.d.ts +1 -0
  161. package/lib/locale/messages-sma.js +9 -8
  162. package/lib/styles.css +686 -0
  163. package/lib/types.d.ts +1 -0
  164. package/lib/utils/relativeUrl.js +3 -3
  165. package/package.json +17 -12
  166. package/src/AudioPlayer/AudioPlayer.tsx +139 -176
  167. package/src/AudioPlayer/Controls.tsx +210 -250
  168. package/src/AudioPlayer/SpeechControl.tsx +9 -7
  169. package/src/BlogPost/BlogPost.tsx +82 -58
  170. package/src/CodeBlock/CodeBlock.stories.tsx +0 -43
  171. package/src/CodeBlock/CodeBlock.tsx +91 -202
  172. package/src/ContactBlock/ContactBlock.tsx +10 -2
  173. package/src/Embed/CodeEmbed.stories.tsx +95 -0
  174. package/src/Embed/CodeEmbed.tsx +62 -7
  175. package/src/Embed/ConceptEmbed.tsx +1 -9
  176. package/src/Embed/EmbedErrorPlaceholder.tsx +31 -28
  177. package/src/Embed/ImageEmbed.stories.tsx +53 -11
  178. package/src/Embed/ImageEmbed.tsx +162 -166
  179. package/src/Notion/NotionImage.tsx +4 -54
  180. package/src/ResourceBox/ResourceBox.tsx +3 -15
  181. package/src/Search/ContentTypeResult.tsx +9 -3
  182. package/src/Search/SearchResultSleeve.tsx +5 -2
  183. package/src/ZendeskButton/ZendeskButton.tsx +58 -0
  184. package/src/index.ts +4 -0
  185. package/src/locale/messages-en.ts +1 -0
  186. package/src/locale/messages-nb.ts +1 -0
  187. package/src/locale/messages-nn.ts +1 -0
  188. package/src/locale/messages-se.ts +1 -0
  189. package/src/locale/messages-sma.ts +1 -0
  190. package/src/types.ts +2 -0
  191. package/src/Image/__tests__/Image-test.tsx +0 -66
  192. package/src/Image/__tests__/__snapshots__/Image-test.tsx.snap +0 -194
@@ -58,7 +58,7 @@ export const SnackbarProvider = _ref => {
58
58
  };
59
59
  const snackbarInAnimation = keyframes({
60
60
  "0%": {
61
- transform: "translateY(".concat(spacing.medium, ")"),
61
+ transform: `translateY(${spacing.medium})`,
62
62
  opacity: 0
63
63
  },
64
64
  "100%": {
@@ -70,7 +70,7 @@ const snackbarOutAnimation = keyframes({
70
70
  opacity: 1
71
71
  },
72
72
  "100%": {
73
- transform: "translateY(".concat(spacing.medium, ")"),
73
+ transform: `translateY(${spacing.medium})`,
74
74
  opacity: 0
75
75
  }
76
76
  });
@@ -109,15 +109,12 @@ const SnackbarContainer = _ref4 => {
109
109
  return _jsx(StyledSnackList, {
110
110
  "aria-live": "polite",
111
111
  role: "region",
112
- children: snacks.map(snack => {
113
- var _snack$render, _snack$render2;
114
- return _jsx(BaseSnack, {
115
- ...snack,
116
- children: (_snack$render = (_snack$render2 = snack.render) === null || _snack$render2 === void 0 ? void 0 : _snack$render2.call(snack, snack.id)) !== null && _snack$render !== void 0 ? _snack$render : _jsx(DefaultSnack, {
117
- ...snack
118
- })
119
- }, snack.id);
120
- })
112
+ children: snacks.map(snack => _jsx(BaseSnack, {
113
+ ...snack,
114
+ children: snack.render?.(snack.id) ?? _jsx(DefaultSnack, {
115
+ ...snack
116
+ })
117
+ }, snack.id))
121
118
  });
122
119
  };
123
120
  export default SnackbarProvider;
@@ -27,7 +27,7 @@ const styles = {
27
27
  dropdownIndicator: () => ({}),
28
28
  placeholder: provided => ({
29
29
  ...provided,
30
- padding: "0 ".concat(spacing.small),
30
+ padding: `0 ${spacing.small}`,
31
31
  color: colors.brand.primary,
32
32
  margin: 0
33
33
  }),
@@ -17,9 +17,9 @@ export const createAriaMessages = t => ({
17
17
  } = props;
18
18
  switch (context) {
19
19
  case "menu":
20
- return "".concat(t("tagSelector.aria.guidance.menu.updown")).concat(isDisabled ? "" : ", ".concat(t("tagSelector.aria.guidance.menu.enter")), ", ").concat(t("tagSelector.aria.guidance.menu.escape")).concat(tabSelectsValue ? ", ".concat(t("tagSelector.aria.guidance.menu.tab")) : "", ".");
20
+ return `${t("tagSelector.aria.guidance.menu.updown")}${isDisabled ? "" : `, ${t("tagSelector.aria.guidance.menu.enter")}`}, ${t("tagSelector.aria.guidance.menu.escape")}${tabSelectsValue ? `, ${t("tagSelector.aria.guidance.menu.tab")}` : ""}.`;
21
21
  case "input":
22
- return "".concat(props["aria-label"] || t("tagSelector.aria.guidance.input.select"), " ").concat(t("tagSelector.aria.guidance.input.focused"), " ").concat(isSearchable ? ", ".concat(t("tagSelector.aria.guidance.input.refine")) : "", ", ").concat(t("tagSelector.aria.guidance.input.down"), ", ").concat(isMulti ? " ".concat(t("tagSelector.aria.guidance.input.left")) : "", ", ").concat(t("tagSelector.aria.guidance.input.space"));
22
+ return `${props["aria-label"] || t("tagSelector.aria.guidance.input.select")} ${t("tagSelector.aria.guidance.input.focused")} ${isSearchable ? `, ${t("tagSelector.aria.guidance.input.refine")}` : ""}, ${t("tagSelector.aria.guidance.input.down")}, ${isMulti ? ` ${t("tagSelector.aria.guidance.input.left")}` : ""}, ${t("tagSelector.aria.guidance.input.space")}`;
23
23
  case "value":
24
24
  return t("tagSelector.aria.guidance.value");
25
25
  default:
@@ -66,7 +66,7 @@ export const createAriaMessages = t => ({
66
66
  isDisabled,
67
67
  isSelected
68
68
  } = props;
69
- const getArrayIndex = (arr, item) => arr && arr.length ? "".concat(arr.indexOf(item) + 1, " ").concat(t("tagSelector.aria.onFocus.of"), " ").concat(arr.length) : "";
69
+ const getArrayIndex = (arr, item) => arr && arr.length ? `${arr.indexOf(item) + 1} ${t("tagSelector.aria.onFocus.of")} ${arr.length}` : "";
70
70
  if (context === "value" && selectValue) {
71
71
  return t("tagSelector.aria.onFocus.value", {
72
72
  label,
@@ -74,8 +74,8 @@ export const createAriaMessages = t => ({
74
74
  });
75
75
  }
76
76
  if (context === "menu") {
77
- const disabled = isDisabled ? " ".concat(t("tagSelector.aria.disabled")) : "";
78
- const status = "".concat(isSelected ? t("tagSelector.aria.selected") : t("tagSelector.aria.focused")).concat(disabled);
77
+ const disabled = isDisabled ? ` ${t("tagSelector.aria.disabled")}` : "";
78
+ const status = `${isSelected ? t("tagSelector.aria.selected") : t("tagSelector.aria.focused")}${disabled}`;
79
79
  return t("tagSelector.aria.onFocus.menu", {
80
80
  label,
81
81
  status,
@@ -89,6 +89,6 @@ export const createAriaMessages = t => ({
89
89
  inputValue,
90
90
  resultsMessage
91
91
  } = props;
92
- return "".concat(resultsMessage).concat(inputValue ? " ".concat(t("tagSelector.aria.onFilter"), " ") + inputValue : "", ".");
92
+ return `${resultsMessage}${inputValue ? ` ${t("tagSelector.aria.onFilter")} ` + inputValue : ""}.`;
93
93
  }
94
94
  });
@@ -51,7 +51,7 @@ const AddFolderButton = _ref => {
51
51
  } = useTranslation();
52
52
  const ref = useRef(null);
53
53
  const tooltip = loading ? t("loading") : canAddFolder ? t("myNdla.newFolderUnder", {
54
- folderName: focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.name
54
+ folderName: focusedFolder?.name
55
55
  }) : t("treeStructure.maxFoldersAlreadyAdded");
56
56
  return _jsx(Tooltip, {
57
57
  tooltip: tooltip,
@@ -62,20 +62,18 @@ const AddFolderButton = _ref => {
62
62
  disabled: loading || !canAddFolder,
63
63
  "aria-label": tooltip,
64
64
  onMouseDown: e => {
65
- var _ref$current;
66
65
  e.preventDefault();
67
66
  e.stopPropagation();
68
- (_ref$current = ref.current) === null || _ref$current === void 0 || _ref$current.focus();
67
+ ref.current?.focus();
69
68
  },
70
69
  onMouseUp: e => {
71
- var _ref$current2;
72
70
  e.preventDefault();
73
71
  e.stopPropagation();
74
- (_ref$current2 = ref.current) === null || _ref$current2 === void 0 || _ref$current2.focus();
72
+ ref.current?.focus();
75
73
  },
76
74
  onClick: e => {
77
75
  e.currentTarget.focus();
78
- setNewFolderParentId(focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.id);
76
+ setNewFolderParentId(focusedFolder?.id);
79
77
  setShowTree(true);
80
78
  },
81
79
  children: [_jsx(StyledPlus, {}), " ", t("myNdla.newFolder")]
@@ -68,11 +68,10 @@ const ComboboxButton = /*#__PURE__*/forwardRef((_ref, ref) => {
68
68
  "data-open": showTree,
69
69
  onMouseDown: e => {
70
70
  if (!e.defaultPrevented) {
71
- var _innerRef$current;
72
71
  e.preventDefault();
73
72
  e.stopPropagation();
74
73
  onToggleTree(!showTree);
75
- (_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 || _innerRef$current.focus();
74
+ innerRef.current?.focus();
76
75
  }
77
76
  },
78
77
  children: [loading && _jsx(ContentLoader, {
@@ -104,11 +103,10 @@ const ComboboxButton = /*#__PURE__*/forwardRef((_ref, ref) => {
104
103
  shape: "sharp",
105
104
  onKeyDown: onKeyDown,
106
105
  onClick: () => {
107
- var _innerRef$current2;
108
- (_innerRef$current2 = innerRef.current) === null || _innerRef$current2 === void 0 || _innerRef$current2.focus();
106
+ innerRef.current?.focus();
109
107
  onToggleTree(showTree);
110
108
  },
111
- children: selectedFolder === null || selectedFolder === void 0 ? void 0 : selectedFolder.name
109
+ children: selectedFolder?.name
112
110
  }), _jsx(IconButton, {
113
111
  disabled: loading,
114
112
  "aria-busy": loading,
@@ -119,8 +117,7 @@ const ComboboxButton = /*#__PURE__*/forwardRef((_ref, ref) => {
119
117
  colorTheme: "greyLighter",
120
118
  size: "small",
121
119
  onClick: () => {
122
- var _innerRef$current3;
123
- (_innerRef$current3 = innerRef.current) === null || _innerRef$current3 === void 0 || _innerRef$current3.focus();
120
+ innerRef.current?.focus();
124
121
  onToggleTree(!showTree);
125
122
  },
126
123
  children: showTree ? _jsx(ChevronUp, {}) : _jsx(ChevronDown, {})
@@ -103,7 +103,7 @@ const FolderItem = _ref => {
103
103
  const levelVariable = useMemo(() => ({
104
104
  "--level": level
105
105
  }), [level]);
106
- const focused = (focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.id) === id;
106
+ const focused = focusedFolder?.id === id;
107
107
  const handleClickFolder = () => {
108
108
  if (!selected) {
109
109
  setSelectedFolder(folder);
@@ -116,21 +116,19 @@ const FolderItem = _ref => {
116
116
  }
117
117
  };
118
118
  useEffect(() => {
119
- if ((focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.id) === id && !isCreatingFolder) {
119
+ if (focusedFolder?.id === id && !isCreatingFolder) {
120
120
  if (type === "navigation") {
121
- var _ref$current;
122
- (_ref$current = ref.current) === null || _ref$current === void 0 || _ref$current.focus();
121
+ ref.current?.focus();
123
122
  }
124
123
  if (type === "picker") {
125
- var _ref$current2;
126
- (_ref$current2 = ref.current) === null || _ref$current2 === void 0 || _ref$current2.scrollIntoView({
124
+ ref.current?.scrollIntoView({
127
125
  behavior: "smooth",
128
126
  block: "start"
129
127
  });
130
128
  }
131
129
  }
132
130
  }, [focusedFolder, ref, id, isCreatingFolder, type]);
133
- const linkPath = "/minndla/folders/".concat(id);
131
+ const linkPath = `/minndla/folders/${id}`;
134
132
  const containsResource = targetResource && folder.resources.some(resource => resource.resourceId === targetResource.resourceId);
135
133
  const emptyFolder = folder.subfolders.length === 0;
136
134
  const isMaxDepth = level > maxLevel;
@@ -139,10 +137,10 @@ const FolderItem = _ref => {
139
137
  const tabable = selected || focused || !focusedFolder && !folder.parentId && index === 0;
140
138
  return type === "navigation" ? _jsxs(FolderNameLink, {
141
139
  role: "treeitem",
142
- "aria-owns": folder.subfolders.length ? treestructureId(type, "subfolders-".concat(folder.id)) : undefined,
140
+ "aria-owns": folder.subfolders.length ? treestructureId(type, `subfolders-${folder.id}`) : undefined,
143
141
  "aria-expanded": isMaxDepth || emptyFolder ? undefined : isOpen,
144
142
  "aria-current": selected ? "page" : undefined,
145
- "aria-describedby": containsResource ? "alreadyAdded-".concat(folder.id) : undefined,
143
+ "aria-describedby": containsResource ? `alreadyAdded-${folder.id}` : undefined,
146
144
  ref: ref,
147
145
  style: levelVariable,
148
146
  onKeyDown: e => {
@@ -163,10 +161,9 @@ const FolderItem = _ref => {
163
161
  "data-open": isOpen,
164
162
  "data-hide-arrow": hideArrow,
165
163
  onClick: e => {
166
- var _ref$current3;
167
164
  e.stopPropagation();
168
165
  e.preventDefault();
169
- (_ref$current3 = ref.current) === null || _ref$current3 === void 0 || _ref$current3.focus();
166
+ ref.current?.focus();
170
167
  if (isOpen) {
171
168
  onCloseFolder(id);
172
169
  } else {
@@ -183,9 +180,9 @@ const FolderItem = _ref => {
183
180
  id: treestructureId(type, folder.id),
184
181
  "aria-expanded": isMaxDepth || emptyFolder ? undefined : isOpen,
185
182
  "aria-selected": selected,
186
- "data-focused": (focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.id) === folder.id,
187
- "aria-describedby": containsResource ? "alreadyAdded-".concat(folder.id) : undefined,
188
- "aria-label": "".concat(name).concat(folder.status === "shared" ? ", ".concat(t("myNdla.folder.sharing.shared")) : ""),
183
+ "data-focused": focusedFolder?.id === folder.id,
184
+ "aria-describedby": containsResource ? `alreadyAdded-${folder.id}` : undefined,
185
+ "aria-label": `${name}${folder.status === "shared" ? `, ${t("myNdla.folder.sharing.shared")}` : ""}`,
189
186
  variant: "ghost",
190
187
  shape: "sharp",
191
188
  fontWeight: "normal",
@@ -220,7 +217,7 @@ const FolderItem = _ref => {
220
217
  children: name
221
218
  }), containsResource && _jsx(StyledDone, {
222
219
  "aria-label": t("myNdla.alreadyInFolder"),
223
- id: "alreadyAdded-".concat(folder.id),
220
+ id: `alreadyAdded-${folder.id}`,
224
221
  title: t("myNdla.alreadyInFolder")
225
222
  })]
226
223
  });
@@ -44,7 +44,7 @@ const FolderItems = _ref => {
44
44
  ...rest
45
45
  } = _ref;
46
46
  return _jsxs(StyledUL, {
47
- id: level === 0 && type === "picker" ? treestructureId(type, "popup") : parentFolder ? treestructureId(type, "subfolders-".concat(parentFolder.id)) : undefined,
47
+ id: level === 0 && type === "picker" ? treestructureId(type, "popup") : parentFolder ? treestructureId(type, `subfolders-${parentFolder.id}`) : undefined,
48
48
  tabIndex: -1,
49
49
  "aria-labelledby": level === 0 && type === "picker" ? treestructureId(type, "label") : undefined,
50
50
  role: level === 0 ? "tree" : "group",
@@ -53,7 +53,7 @@ const FolderItems = _ref => {
53
53
  subfolders,
54
54
  id
55
55
  } = folder;
56
- const isOpen = openFolders === null || openFolders === void 0 ? void 0 : openFolders.includes(id);
56
+ const isOpen = openFolders?.includes(id);
57
57
  return _jsxs(StyledLI, {
58
58
  tabIndex: -1,
59
59
  role: "none",
@@ -81,7 +81,7 @@ const FolderItems = _ref => {
81
81
  ...rest,
82
82
  children: newFolderParentId === id && _jsx("li", {
83
83
  role: "none",
84
- children: newFolderInput === null || newFolderInput === void 0 ? void 0 : newFolderInput({
84
+ children: newFolderInput?.({
85
85
  parentId: id,
86
86
  onClose: onCancelNewFolder,
87
87
  onCreate
@@ -67,7 +67,7 @@ const TreeStructure = _ref => {
67
67
  ariaDescribedby
68
68
  } = _ref;
69
69
  const ref = useRef(null);
70
- const defaultSelectedFolderId = defaultOpenFolders === null || defaultOpenFolders === void 0 ? void 0 : defaultOpenFolders[defaultOpenFolders.length - 1];
70
+ const defaultSelectedFolderId = defaultOpenFolders?.[defaultOpenFolders.length - 1];
71
71
  const [openFolders, setOpenFolders] = useState(defaultOpenFolders || []);
72
72
  const [newFolderParentId, setNewFolderParentId] = useState();
73
73
  const [focusedFolder, _setFocusedFolder] = useState();
@@ -104,13 +104,12 @@ const TreeStructure = _ref => {
104
104
  };
105
105
  const setSelectedFolder = folder => {
106
106
  _setSelectedFolder(folder);
107
- onSelectFolder === null || onSelectFolder === void 0 || onSelectFolder(folder.id);
107
+ onSelectFolder?.(folder.id);
108
108
  };
109
109
  const setFocusedFolder = folder => {
110
- var _ref$current;
111
110
  _setFocusedFolder(folder);
112
111
  setNewFolderParentId(undefined);
113
- (_ref$current = ref.current) === null || _ref$current === void 0 || _ref$current.focus({
112
+ ref.current?.focus({
114
113
  preventScroll: true
115
114
  });
116
115
  };
@@ -121,7 +120,7 @@ const TreeStructure = _ref => {
121
120
  const closedFolder = flattenedFolders.find(folder => folder.id === id);
122
121
  if (closedFolder) {
123
122
  const subFolders = closedFolder.subfolders && flattenFolders(closedFolder.subfolders);
124
- if (subFolders.some(folder => folder.id === (selectedFolder === null || selectedFolder === void 0 ? void 0 : selectedFolder.id))) {
123
+ if (subFolders.some(folder => folder.id === selectedFolder?.id)) {
125
124
  setFocusedFolder(closedFolder);
126
125
  }
127
126
  }
@@ -129,24 +128,22 @@ const TreeStructure = _ref => {
129
128
  };
130
129
  const onNewFolderCreated = (newFolder, parentId) => {
131
130
  if (newFolder) {
132
- var _ref$current2;
133
131
  setSelectedFolder(newFolder);
134
132
  setFocusedFolder(newFolder);
135
133
  setOpenFolders(uniq(openFolders.concat(parentId)));
136
- setNewFolderParentId === null || setNewFolderParentId === void 0 || setNewFolderParentId(undefined);
137
- (_ref$current2 = ref.current) === null || _ref$current2 === void 0 || _ref$current2.focus({
134
+ setNewFolderParentId?.(undefined);
135
+ ref.current?.focus({
138
136
  preventScroll: true
139
137
  });
140
138
  }
141
139
  };
142
140
  const onCancelNewFolder = () => {
143
- var _ref$current3;
144
- setNewFolderParentId === null || setNewFolderParentId === void 0 || setNewFolderParentId(undefined);
145
- (_ref$current3 = ref.current) === null || _ref$current3 === void 0 || _ref$current3.focus({
141
+ setNewFolderParentId?.(undefined);
142
+ ref.current?.focus({
146
143
  preventScroll: true
147
144
  });
148
145
  };
149
- const canAddFolder = selectedFolder && (selectedFolder === null || selectedFolder === void 0 ? void 0 : selectedFolder.breadcrumbs.length) < (maxLevel || 1);
146
+ const canAddFolder = selectedFolder && selectedFolder?.breadcrumbs.length < (maxLevel || 1);
150
147
  return _jsxs(StyledTreeStructure, {
151
148
  onBlur: e => {
152
149
  if (type === "picker" && !e.currentTarget.contains(e.relatedTarget)) {
@@ -28,5 +28,5 @@ export const flattenFolders = (folders, openFolders) => {
28
28
  }, []);
29
29
  };
30
30
  export const treestructureId = (type, modifier) => {
31
- return "".concat(type, "-treestructure-").concat(modifier);
31
+ return `${type}-treestructure-${modifier}`;
32
32
  };
@@ -0,0 +1,55 @@
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 { forwardRef, useState } from "react";
10
+ import { Button } from "@ndla/primitives";
11
+
12
+ // TODO: Let's consider abandoning `disabled` on the button here. It should instead just open/close the widget based on its current state.
13
+ import { jsx as _jsx } from "@emotion/react/jsx-runtime";
14
+ export const ZendeskButton = /*#__PURE__*/forwardRef((_ref, ref) => {
15
+ let {
16
+ locale,
17
+ variant = "secondary",
18
+ widgetKey,
19
+ children,
20
+ ...rest
21
+ } = _ref;
22
+ const [loading, setLoading] = useState(false);
23
+ const handleClick = () => {
24
+ if (window && !window.zE) {
25
+ setLoading(true);
26
+ // Asynchronously load zendesk scripts for better performance
27
+ const script = document.createElement("script");
28
+ script.id = "ze-snippet";
29
+ script.type = "text/javascript";
30
+ script.async = true;
31
+ script.onload = () => {
32
+ if (window.zE) {
33
+ window.zE("webWidget", "setLocale", locale);
34
+ window.zE("webWidget:on", "close", () => {
35
+ setLoading(false);
36
+ });
37
+ window.zE("webWidget", "open");
38
+ }
39
+ };
40
+ script.src = `https://static.zdassets.com/ekr/snippet.js?key=${widgetKey}`;
41
+ document.body.appendChild(script);
42
+ } else if (window?.zE) {
43
+ window.zE("webWidget", "open");
44
+ }
45
+ };
46
+ return _jsx(Button, {
47
+ onClick: handleClick,
48
+ variant: variant,
49
+ id: "zendeskButton",
50
+ disabled: loading,
51
+ ...rest,
52
+ ref: ref,
53
+ children: children
54
+ });
55
+ });
@@ -15,7 +15,7 @@ export const formatNestedMessages = function (phrases) {
15
15
  Object.keys(phrases).forEach(key => {
16
16
  const value = phrases[key];
17
17
  if ({}.hasOwnProperty.call(phrases, key)) {
18
- const keyWithPrefix = prefix ? "".concat(prefix, ".").concat(key) : key;
18
+ const keyWithPrefix = prefix ? `${prefix}.${key}` : key;
19
19
  if (typeof value === "object") {
20
20
  formatNestedMessages(value, formattedMessages, keyWithPrefix);
21
21
  } else {
package/es/index.js CHANGED
@@ -64,4 +64,5 @@ export { default as FrontpageArticle, FRONTPAGE_ARTICLE_MAX_WIDTH, WIDE_FRONTPAG
64
64
  export { DefinitionTerm, DefinitionDescription } from "./DefinitionList";
65
65
  export { Gloss, GlossExample } from "./Gloss";
66
66
  export { LinkBlock, LinkBlockSection } from "./LinkBlock";
67
- export { CodeBlock, codeLanguageOptions } from "./CodeBlock";
67
+ export { CodeBlock, codeLanguageOptions } from "./CodeBlock";
68
+ export { ZendeskButton } from "./ZendeskButton/ZendeskButton";
@@ -61,7 +61,7 @@ const messages = {
61
61
  onChange: {
62
62
  deselect: "tag {{label}}, deselected.",
63
63
  clear: "All selected options have been cleared.",
64
- initialFocus: "Tags {{labels}}, selected.",
64
+ initialFocus: `Tags {{labels}}, selected.`,
65
65
  selectedDisabled: "Tag {{label}} is disabled. Select another option.",
66
66
  selected: "Tag {{label}}, selected."
67
67
  },
@@ -82,11 +82,11 @@ const messages = {
82
82
  },
83
83
  htmlTitles: {
84
84
  titleTemplate,
85
- welcomePage: "Frontpage".concat(titleTemplate),
85
+ welcomePage: `Frontpage${titleTemplate}`,
86
86
  topicPage: "Topic",
87
- subjectsPage: "Choose subjects".concat(titleTemplate),
88
- searchPage: "Search".concat(titleTemplate),
89
- notFound: "Page not found".concat(titleTemplate)
87
+ subjectsPage: `Choose subjects${titleTemplate}`,
88
+ searchPage: `Search${titleTemplate}`,
89
+ notFound: `Page not found${titleTemplate}`
90
90
  },
91
91
  askNDLA: "Ask NDLA",
92
92
  articlePage: {
@@ -724,7 +724,7 @@ const messages = {
724
724
  previousArrow: "Go to previous step"
725
725
  },
726
726
  dropdown: {
727
- numberHits: "Search returned {{hits}} hits",
727
+ numberHits: `Search returned {{hits}} hits`,
728
728
  searching: "Searching...",
729
729
  create: "Create new",
730
730
  isSelectedItem: "Added",
@@ -812,6 +812,7 @@ const messages = {
812
812
  url: "Error loading the audio.",
813
813
  caption: "Sorry, an error occurred while loading the audio."
814
814
  },
815
+ valueText: "{{start}} of {{end}}",
815
816
  controls: {
816
817
  forward15sec: "Forward 15 seconds",
817
818
  rewind15sec: "Rewind 15 seconds",
@@ -1369,9 +1370,9 @@ const messages = {
1369
1370
  embed: {
1370
1371
  conceptListError: "Failed to show concept list",
1371
1372
  linkError: "Failed to show link.",
1372
- unsupported: "Embed {{type}} not supported.",
1373
+ unsupported: `Embed {{type}} not supported.`,
1373
1374
  goTo: "Go to {{type}}",
1374
- embedError: "An error occurred while loading the {{type}}. Try reloading the page.",
1375
+ embedError: `An error occurred while loading the {{type}}. Try reloading the page.`,
1375
1376
  type: {
1376
1377
  image: "Image",
1377
1378
  video: "Video",
@@ -61,7 +61,7 @@ const messages = {
61
61
  onChange: {
62
62
  deselect: "emneknagg {{label}}, fjernet.",
63
63
  clear: "Alle valgte emneknagger fjernet.",
64
- initialFocus: "Emneknagger {{labels}}, valgt.",
64
+ initialFocus: `Emneknagger {{labels}}, valgt.`,
65
65
  selectedDisabled: "Emneknagg {{label}} kan ikke velges. Velg et annet alternativ.",
66
66
  selected: "Emneknagg {{label}}, valgt."
67
67
  },
@@ -82,11 +82,11 @@ const messages = {
82
82
  },
83
83
  htmlTitles: {
84
84
  titleTemplate,
85
- welcomePage: "Forsiden".concat(titleTemplate),
85
+ welcomePage: `Forsiden${titleTemplate}`,
86
86
  topicPage: "Emne",
87
- subjectsPage: "Velg fag".concat(titleTemplate),
88
- searchPage: "S\xF8k".concat(titleTemplate),
89
- notFound: "Siden finnes ikke".concat(titleTemplate)
87
+ subjectsPage: `Velg fag${titleTemplate}`,
88
+ searchPage: `Søk${titleTemplate}`,
89
+ notFound: `Siden finnes ikke${titleTemplate}`
90
90
  },
91
91
  askNDLA: "Spør NDLA",
92
92
  articlePage: {
@@ -724,7 +724,7 @@ const messages = {
724
724
  previousArrow: "Gå til forrige steg"
725
725
  },
726
726
  dropdown: {
727
- numberHits: "S\xF8ket gav {{hits}} treff",
727
+ numberHits: `Søket gav {{hits}} treff`,
728
728
  searching: "Søker...",
729
729
  create: "Opprett ny",
730
730
  isSelectedItem: "Lagt til",
@@ -812,6 +812,7 @@ const messages = {
812
812
  url: "Feil ved lasting av lydfil.",
813
813
  caption: "Beklager, en feil oppstod ved lasting av lydfil."
814
814
  },
815
+ valueText: "{{start}} av {{end}}",
815
816
  controls: {
816
817
  forward15sec: "Spol 15 sekunder fram",
817
818
  rewind15sec: "Spol 15 sekunder tilbake",
@@ -1369,9 +1370,9 @@ const messages = {
1369
1370
  embed: {
1370
1371
  conceptListError: "Klarte ikke å vise forklaringsliste",
1371
1372
  linkError: "Klarte ikke å vise lenke.",
1372
- unsupported: "Embed {{type}} er ikke st\xF8ttet.",
1373
+ unsupported: `Embed {{type}} er ikke støttet.`,
1373
1374
  goTo: "Gå til {{type}}",
1374
- embedError: "Beklager, en feil oppstod ved lasting av {{type}}. Pr\xF8v \xE5 laste inn siden p\xE5 nytt.",
1375
+ embedError: `Beklager, en feil oppstod ved lasting av {{type}}. Prøv å laste inn siden nytt.`,
1375
1376
  type: {
1376
1377
  image: "Bilde",
1377
1378
  video: "Video",
@@ -61,7 +61,7 @@ const messages = {
61
61
  onChange: {
62
62
  deselect: "emneknagg {{label}}, fjerna.",
63
63
  clear: "Alle valgte emneknaggar fjerna.",
64
- initialFocus: "Emneknaggar {{labels}}, valgt.",
64
+ initialFocus: `Emneknaggar {{labels}}, valgt.`,
65
65
  selectedDisabled: "Emneknagg {{label}} kan ikkje velgast. Velg eit anna alternativ.",
66
66
  selected: "Emneknagg {{label}}, valgt."
67
67
  },
@@ -82,11 +82,11 @@ const messages = {
82
82
  },
83
83
  htmlTitles: {
84
84
  titleTemplate,
85
- welcomePage: "Framsida".concat(titleTemplate),
85
+ welcomePage: `Framsida${titleTemplate}`,
86
86
  topicPage: "Emne",
87
- subjectsPage: "Velg fag".concat(titleTemplate),
88
- searchPage: "S\xF8k".concat(titleTemplate),
89
- notFound: "Sida finst ikkje".concat(titleTemplate)
87
+ subjectsPage: `Velg fag${titleTemplate}`,
88
+ searchPage: `Søk${titleTemplate}`,
89
+ notFound: `Sida finst ikkje${titleTemplate}`
90
90
  },
91
91
  askNDLA: "Spør NDLA",
92
92
  articlePage: {
@@ -724,7 +724,7 @@ const messages = {
724
724
  previousArrow: "Gå til førre steg"
725
725
  },
726
726
  dropdown: {
727
- numberHits: "S\xF8ket gav {{hits}} treff",
727
+ numberHits: `Søket gav {{hits}} treff`,
728
728
  searching: "Søkjer...",
729
729
  create: "Opprett ny",
730
730
  isSelectedItem: "Lagt til",
@@ -812,6 +812,7 @@ const messages = {
812
812
  url: "Feil ved lasting av lydfil.",
813
813
  caption: "Orsak, ein feil oppstod ved lasting av lydfil."
814
814
  },
815
+ valueText: "{{start}} av {{end}}",
815
816
  controls: {
816
817
  forward15sec: "Spol 15 sekund fram",
817
818
  rewind15sec: "Spol 15 sekund tilbake",
@@ -1369,9 +1370,9 @@ const messages = {
1369
1370
  embed: {
1370
1371
  conceptListError: "Klarte ikkje å vise forklaringsliste",
1371
1372
  linkError: "Klarte ikkje å vise lenke.",
1372
- unsupported: "Embed {{type}} er ikkje st\xF8tta.",
1373
+ unsupported: `Embed {{type}} er ikkje støtta.`,
1373
1374
  goTo: "Gå til {{type}}",
1374
- embedError: "Orsak, ein feil oppstod ved lasting av {{type}}. Pr\xF8v \xE5 laste inn sida p\xE5 nytt.",
1375
+ embedError: `Orsak, ein feil oppstod ved lasting av {{type}}. Prøv å laste inn sida nytt.`,
1375
1376
  type: {
1376
1377
  image: "Bilete",
1377
1378
  video: "Video",
@@ -61,7 +61,7 @@ const messages = {
61
61
  onChange: {
62
62
  deselect: "fáddágilkor {{label}}, sihkkojuvvon.",
63
63
  clear: "Buot válljejuvvon fáddágilkorat sihkkojuvvon.",
64
- initialFocus: "F\xE1dd\xE1gilkorat {{labels}}, v\xE1lljejuvvon.",
64
+ initialFocus: `Fáddágilkorat {{labels}}, válljejuvvon.`,
65
65
  selectedDisabled: "Fáddágilkor {{label}} ii sáhte válljejuvvot. Vállje eará molsaeavttu.",
66
66
  selected: "Fáddágilkor {{label}}, vállejuvvon."
67
67
  },
@@ -82,11 +82,11 @@ const messages = {
82
82
  },
83
83
  htmlTitles: {
84
84
  titleTemplate,
85
- welcomePage: "Ovdasiidu".concat(titleTemplate),
85
+ welcomePage: `Ovdasiidu${titleTemplate}`,
86
86
  topicPage: "Fáddá",
87
- subjectsPage: "V\xE1llje f\xE1ga".concat(titleTemplate),
88
- searchPage: "Oza".concat(titleTemplate),
89
- notFound: "Siidu ii g\xE1vdno".concat(titleTemplate)
87
+ subjectsPage: `Vállje fága${titleTemplate}`,
88
+ searchPage: `Oza${titleTemplate}`,
89
+ notFound: `Siidu ii gávdno${titleTemplate}`
90
90
  },
91
91
  askNDLA: "Jeara NDLA:s",
92
92
  articlePage: {
@@ -724,7 +724,7 @@ const messages = {
724
724
  previousArrow: "Mana ovddit lávkái"
725
725
  },
726
726
  dropdown: {
727
- numberHits: "Ohcamis ledje {{hits}} deaivama",
727
+ numberHits: `Ohcamis ledje {{hits}} deaivama`,
728
728
  searching: "Ohcá...",
729
729
  create: "Ráhkat ođđa",
730
730
  isSelectedItem: "Lasihuvvon",
@@ -812,6 +812,7 @@ const messages = {
812
812
  url: "Boasttuvuohta jietnafiilla viežžamis.",
813
813
  caption: "Šállošat, boasttuvuohta čuožžilii jietnafiilla viežžamis."
814
814
  },
815
+ valueText: "{{start}} av {{end}}",
815
816
  controls: {
816
817
  forward15sec: "Sirdde 15 sekundda ovddas",
817
818
  rewind15sec: "Sirdde 15 sekundda maŋos",
@@ -1369,9 +1370,9 @@ const messages = {
1369
1370
  embed: {
1370
1371
  conceptListError: "Ii sáhttán čájehit čilgehuslisttu",
1371
1372
  linkError: "Ii sáhttán čájehit liŋkka.",
1372
- unsupported: "Embed {{type}} ii dorjojuvvo.",
1373
+ unsupported: `Embed {{type}} ii dorjojuvvo.`,
1373
1374
  goTo: "Mana {{type}}",
1374
- embedError: "\u0160attai meatt\xE1hus {{type}} vie\u010D\u010Dadettiin. Geah\u010D\u010Dal vie\u017E\u017Eat siiddu o\u0111\u0111asit.",
1375
+ embedError: `Šattai meattáhus {{type}} vieččadettiin. Geahččal viežžat siiddu ođđasit.`,
1375
1376
  type: {
1376
1377
  image: "Govva",
1377
1378
  video: "Video",