@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
@@ -67,7 +67,7 @@ const SnackbarProvider = _ref => {
67
67
  exports.SnackbarProvider = SnackbarProvider;
68
68
  const snackbarInAnimation = (0, _react2.keyframes)({
69
69
  "0%": {
70
- transform: "translateY(".concat(_core.spacing.medium, ")"),
70
+ transform: `translateY(${_core.spacing.medium})`,
71
71
  opacity: 0
72
72
  },
73
73
  "100%": {
@@ -79,7 +79,7 @@ const snackbarOutAnimation = (0, _react2.keyframes)({
79
79
  opacity: 1
80
80
  },
81
81
  "100%": {
82
- transform: "translateY(".concat(_core.spacing.medium, ")"),
82
+ transform: `translateY(${_core.spacing.medium})`,
83
83
  opacity: 0
84
84
  }
85
85
  });
@@ -119,15 +119,12 @@ const SnackbarContainer = _ref4 => {
119
119
  return (0, _jsxRuntime.jsx)(StyledSnackList, {
120
120
  "aria-live": "polite",
121
121
  role: "region",
122
- children: snacks.map(snack => {
123
- var _snack$render, _snack$render2;
124
- return (0, _jsxRuntime.jsx)(BaseSnack, {
125
- ...snack,
126
- 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 : (0, _jsxRuntime.jsx)(_DefaultSnackbar.default, {
127
- ...snack
128
- })
129
- }, snack.id);
130
- })
122
+ children: snacks.map(snack => (0, _jsxRuntime.jsx)(BaseSnack, {
123
+ ...snack,
124
+ children: snack.render?.(snack.id) ?? (0, _jsxRuntime.jsx)(_DefaultSnackbar.default, {
125
+ ...snack
126
+ })
127
+ }, snack.id))
131
128
  });
132
129
  };
133
130
  var _default = exports.default = SnackbarProvider;
@@ -32,7 +32,7 @@ const styles = {
32
32
  dropdownIndicator: () => ({}),
33
33
  placeholder: provided => ({
34
34
  ...provided,
35
- padding: "0 ".concat(_core.spacing.small),
35
+ padding: `0 ${_core.spacing.small}`,
36
36
  color: _core.colors.brand.primary,
37
37
  margin: 0
38
38
  }),
@@ -23,9 +23,9 @@ const createAriaMessages = t => ({
23
23
  } = props;
24
24
  switch (context) {
25
25
  case "menu":
26
- 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")) : "", ".");
26
+ 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")}` : ""}.`;
27
27
  case "input":
28
- 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"));
28
+ 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")}`;
29
29
  case "value":
30
30
  return t("tagSelector.aria.guidance.value");
31
31
  default:
@@ -72,7 +72,7 @@ const createAriaMessages = t => ({
72
72
  isDisabled,
73
73
  isSelected
74
74
  } = props;
75
- const getArrayIndex = (arr, item) => arr && arr.length ? "".concat(arr.indexOf(item) + 1, " ").concat(t("tagSelector.aria.onFocus.of"), " ").concat(arr.length) : "";
75
+ const getArrayIndex = (arr, item) => arr && arr.length ? `${arr.indexOf(item) + 1} ${t("tagSelector.aria.onFocus.of")} ${arr.length}` : "";
76
76
  if (context === "value" && selectValue) {
77
77
  return t("tagSelector.aria.onFocus.value", {
78
78
  label,
@@ -80,8 +80,8 @@ const createAriaMessages = t => ({
80
80
  });
81
81
  }
82
82
  if (context === "menu") {
83
- const disabled = isDisabled ? " ".concat(t("tagSelector.aria.disabled")) : "";
84
- const status = "".concat(isSelected ? t("tagSelector.aria.selected") : t("tagSelector.aria.focused")).concat(disabled);
83
+ const disabled = isDisabled ? ` ${t("tagSelector.aria.disabled")}` : "";
84
+ const status = `${isSelected ? t("tagSelector.aria.selected") : t("tagSelector.aria.focused")}${disabled}`;
85
85
  return t("tagSelector.aria.onFocus.menu", {
86
86
  label,
87
87
  status,
@@ -95,7 +95,7 @@ const createAriaMessages = t => ({
95
95
  inputValue,
96
96
  resultsMessage
97
97
  } = props;
98
- return "".concat(resultsMessage).concat(inputValue ? " ".concat(t("tagSelector.aria.onFilter"), " ") + inputValue : "", ".");
98
+ return `${resultsMessage}${inputValue ? ` ${t("tagSelector.aria.onFilter")} ` + inputValue : ""}.`;
99
99
  }
100
100
  });
101
101
  exports.createAriaMessages = createAriaMessages;
@@ -56,7 +56,7 @@ const AddFolderButton = _ref => {
56
56
  } = (0, _reactI18next.useTranslation)();
57
57
  const ref = (0, _react.useRef)(null);
58
58
  const tooltip = loading ? t("loading") : canAddFolder ? t("myNdla.newFolderUnder", {
59
- folderName: focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.name
59
+ folderName: focusedFolder?.name
60
60
  }) : t("treeStructure.maxFoldersAlreadyAdded");
61
61
  return (0, _jsxRuntime.jsx)(_tooltip.Tooltip, {
62
62
  tooltip: tooltip,
@@ -67,20 +67,18 @@ const AddFolderButton = _ref => {
67
67
  disabled: loading || !canAddFolder,
68
68
  "aria-label": tooltip,
69
69
  onMouseDown: e => {
70
- var _ref$current;
71
70
  e.preventDefault();
72
71
  e.stopPropagation();
73
- (_ref$current = ref.current) === null || _ref$current === void 0 || _ref$current.focus();
72
+ ref.current?.focus();
74
73
  },
75
74
  onMouseUp: e => {
76
- var _ref$current2;
77
75
  e.preventDefault();
78
76
  e.stopPropagation();
79
- (_ref$current2 = ref.current) === null || _ref$current2 === void 0 || _ref$current2.focus();
77
+ ref.current?.focus();
80
78
  },
81
79
  onClick: e => {
82
80
  e.currentTarget.focus();
83
- setNewFolderParentId(focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.id);
81
+ setNewFolderParentId(focusedFolder?.id);
84
82
  setShowTree(true);
85
83
  },
86
84
  children: [(0, _jsxRuntime.jsx)(StyledPlus, {}), " ", t("myNdla.newFolder")]
@@ -75,11 +75,10 @@ const ComboboxButton = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
75
75
  "data-open": showTree,
76
76
  onMouseDown: e => {
77
77
  if (!e.defaultPrevented) {
78
- var _innerRef$current;
79
78
  e.preventDefault();
80
79
  e.stopPropagation();
81
80
  onToggleTree(!showTree);
82
- (_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 || _innerRef$current.focus();
81
+ innerRef.current?.focus();
83
82
  }
84
83
  },
85
84
  children: [loading && (0, _jsxRuntime.jsx)(_ContentLoader.default, {
@@ -111,11 +110,10 @@ const ComboboxButton = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
111
110
  shape: "sharp",
112
111
  onKeyDown: onKeyDown,
113
112
  onClick: () => {
114
- var _innerRef$current2;
115
- (_innerRef$current2 = innerRef.current) === null || _innerRef$current2 === void 0 || _innerRef$current2.focus();
113
+ innerRef.current?.focus();
116
114
  onToggleTree(showTree);
117
115
  },
118
- children: selectedFolder === null || selectedFolder === void 0 ? void 0 : selectedFolder.name
116
+ children: selectedFolder?.name
119
117
  }), (0, _jsxRuntime.jsx)(_button.IconButtonV2, {
120
118
  disabled: loading,
121
119
  "aria-busy": loading,
@@ -126,8 +124,7 @@ const ComboboxButton = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
126
124
  colorTheme: "greyLighter",
127
125
  size: "small",
128
126
  onClick: () => {
129
- var _innerRef$current3;
130
- (_innerRef$current3 = innerRef.current) === null || _innerRef$current3 === void 0 || _innerRef$current3.focus();
127
+ innerRef.current?.focus();
131
128
  onToggleTree(!showTree);
132
129
  },
133
130
  children: showTree ? (0, _jsxRuntime.jsx)(_common.ChevronUp, {}) : (0, _jsxRuntime.jsx)(_common.ChevronDown, {})
@@ -108,7 +108,7 @@ const FolderItem = _ref => {
108
108
  const levelVariable = (0, _react.useMemo)(() => ({
109
109
  "--level": level
110
110
  }), [level]);
111
- const focused = (focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.id) === id;
111
+ const focused = focusedFolder?.id === id;
112
112
  const handleClickFolder = () => {
113
113
  if (!selected) {
114
114
  setSelectedFolder(folder);
@@ -121,21 +121,19 @@ const FolderItem = _ref => {
121
121
  }
122
122
  };
123
123
  (0, _react.useEffect)(() => {
124
- if ((focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.id) === id && !isCreatingFolder) {
124
+ if (focusedFolder?.id === id && !isCreatingFolder) {
125
125
  if (type === "navigation") {
126
- var _ref$current;
127
- (_ref$current = ref.current) === null || _ref$current === void 0 || _ref$current.focus();
126
+ ref.current?.focus();
128
127
  }
129
128
  if (type === "picker") {
130
- var _ref$current2;
131
- (_ref$current2 = ref.current) === null || _ref$current2 === void 0 || _ref$current2.scrollIntoView({
129
+ ref.current?.scrollIntoView({
132
130
  behavior: "smooth",
133
131
  block: "start"
134
132
  });
135
133
  }
136
134
  }
137
135
  }, [focusedFolder, ref, id, isCreatingFolder, type]);
138
- const linkPath = "/minndla/folders/".concat(id);
136
+ const linkPath = `/minndla/folders/${id}`;
139
137
  const containsResource = targetResource && folder.resources.some(resource => resource.resourceId === targetResource.resourceId);
140
138
  const emptyFolder = folder.subfolders.length === 0;
141
139
  const isMaxDepth = level > maxLevel;
@@ -144,10 +142,10 @@ const FolderItem = _ref => {
144
142
  const tabable = selected || focused || !focusedFolder && !folder.parentId && index === 0;
145
143
  return type === "navigation" ? (0, _jsxRuntime.jsxs)(FolderNameLink, {
146
144
  role: "treeitem",
147
- "aria-owns": folder.subfolders.length ? (0, _helperFunctions.treestructureId)(type, "subfolders-".concat(folder.id)) : undefined,
145
+ "aria-owns": folder.subfolders.length ? (0, _helperFunctions.treestructureId)(type, `subfolders-${folder.id}`) : undefined,
148
146
  "aria-expanded": isMaxDepth || emptyFolder ? undefined : isOpen,
149
147
  "aria-current": selected ? "page" : undefined,
150
- "aria-describedby": containsResource ? "alreadyAdded-".concat(folder.id) : undefined,
148
+ "aria-describedby": containsResource ? `alreadyAdded-${folder.id}` : undefined,
151
149
  ref: ref,
152
150
  style: levelVariable,
153
151
  onKeyDown: e => {
@@ -168,10 +166,9 @@ const FolderItem = _ref => {
168
166
  "data-open": isOpen,
169
167
  "data-hide-arrow": hideArrow,
170
168
  onClick: e => {
171
- var _ref$current3;
172
169
  e.stopPropagation();
173
170
  e.preventDefault();
174
- (_ref$current3 = ref.current) === null || _ref$current3 === void 0 || _ref$current3.focus();
171
+ ref.current?.focus();
175
172
  if (isOpen) {
176
173
  onCloseFolder(id);
177
174
  } else {
@@ -188,9 +185,9 @@ const FolderItem = _ref => {
188
185
  id: (0, _helperFunctions.treestructureId)(type, folder.id),
189
186
  "aria-expanded": isMaxDepth || emptyFolder ? undefined : isOpen,
190
187
  "aria-selected": selected,
191
- "data-focused": (focusedFolder === null || focusedFolder === void 0 ? void 0 : focusedFolder.id) === folder.id,
192
- "aria-describedby": containsResource ? "alreadyAdded-".concat(folder.id) : undefined,
193
- "aria-label": "".concat(name).concat(folder.status === "shared" ? ", ".concat(t("myNdla.folder.sharing.shared")) : ""),
188
+ "data-focused": focusedFolder?.id === folder.id,
189
+ "aria-describedby": containsResource ? `alreadyAdded-${folder.id}` : undefined,
190
+ "aria-label": `${name}${folder.status === "shared" ? `, ${t("myNdla.folder.sharing.shared")}` : ""}`,
194
191
  variant: "ghost",
195
192
  shape: "sharp",
196
193
  fontWeight: "normal",
@@ -225,7 +222,7 @@ const FolderItem = _ref => {
225
222
  children: name
226
223
  }), containsResource && (0, _jsxRuntime.jsx)(StyledDone, {
227
224
  "aria-label": t("myNdla.alreadyInFolder"),
228
- id: "alreadyAdded-".concat(folder.id),
225
+ id: `alreadyAdded-${folder.id}`,
229
226
  title: t("myNdla.alreadyInFolder")
230
227
  })]
231
228
  });
@@ -49,7 +49,7 @@ const FolderItems = _ref => {
49
49
  ...rest
50
50
  } = _ref;
51
51
  return (0, _jsxRuntime.jsxs)(StyledUL, {
52
- id: level === 0 && type === "picker" ? (0, _helperFunctions.treestructureId)(type, "popup") : parentFolder ? (0, _helperFunctions.treestructureId)(type, "subfolders-".concat(parentFolder.id)) : undefined,
52
+ id: level === 0 && type === "picker" ? (0, _helperFunctions.treestructureId)(type, "popup") : parentFolder ? (0, _helperFunctions.treestructureId)(type, `subfolders-${parentFolder.id}`) : undefined,
53
53
  tabIndex: -1,
54
54
  "aria-labelledby": level === 0 && type === "picker" ? (0, _helperFunctions.treestructureId)(type, "label") : undefined,
55
55
  role: level === 0 ? "tree" : "group",
@@ -58,7 +58,7 @@ const FolderItems = _ref => {
58
58
  subfolders,
59
59
  id
60
60
  } = folder;
61
- const isOpen = openFolders === null || openFolders === void 0 ? void 0 : openFolders.includes(id);
61
+ const isOpen = openFolders?.includes(id);
62
62
  return (0, _jsxRuntime.jsxs)(StyledLI, {
63
63
  tabIndex: -1,
64
64
  role: "none",
@@ -86,7 +86,7 @@ const FolderItems = _ref => {
86
86
  ...rest,
87
87
  children: newFolderParentId === id && (0, _jsxRuntime.jsx)("li", {
88
88
  role: "none",
89
- children: newFolderInput === null || newFolderInput === void 0 ? void 0 : newFolderInput({
89
+ children: newFolderInput?.({
90
90
  parentId: id,
91
91
  onClose: onCancelNewFolder,
92
92
  onCreate
@@ -72,7 +72,7 @@ const TreeStructure = _ref => {
72
72
  ariaDescribedby
73
73
  } = _ref;
74
74
  const ref = (0, _react.useRef)(null);
75
- const defaultSelectedFolderId = defaultOpenFolders === null || defaultOpenFolders === void 0 ? void 0 : defaultOpenFolders[defaultOpenFolders.length - 1];
75
+ const defaultSelectedFolderId = defaultOpenFolders?.[defaultOpenFolders.length - 1];
76
76
  const [openFolders, setOpenFolders] = (0, _react.useState)(defaultOpenFolders || []);
77
77
  const [newFolderParentId, setNewFolderParentId] = (0, _react.useState)();
78
78
  const [focusedFolder, _setFocusedFolder] = (0, _react.useState)();
@@ -109,13 +109,12 @@ const TreeStructure = _ref => {
109
109
  };
110
110
  const setSelectedFolder = folder => {
111
111
  _setSelectedFolder(folder);
112
- onSelectFolder === null || onSelectFolder === void 0 || onSelectFolder(folder.id);
112
+ onSelectFolder?.(folder.id);
113
113
  };
114
114
  const setFocusedFolder = folder => {
115
- var _ref$current;
116
115
  _setFocusedFolder(folder);
117
116
  setNewFolderParentId(undefined);
118
- (_ref$current = ref.current) === null || _ref$current === void 0 || _ref$current.focus({
117
+ ref.current?.focus({
119
118
  preventScroll: true
120
119
  });
121
120
  };
@@ -126,7 +125,7 @@ const TreeStructure = _ref => {
126
125
  const closedFolder = flattenedFolders.find(folder => folder.id === id);
127
126
  if (closedFolder) {
128
127
  const subFolders = closedFolder.subfolders && (0, _helperFunctions.flattenFolders)(closedFolder.subfolders);
129
- if (subFolders.some(folder => folder.id === (selectedFolder === null || selectedFolder === void 0 ? void 0 : selectedFolder.id))) {
128
+ if (subFolders.some(folder => folder.id === selectedFolder?.id)) {
130
129
  setFocusedFolder(closedFolder);
131
130
  }
132
131
  }
@@ -134,24 +133,22 @@ const TreeStructure = _ref => {
134
133
  };
135
134
  const onNewFolderCreated = (newFolder, parentId) => {
136
135
  if (newFolder) {
137
- var _ref$current2;
138
136
  setSelectedFolder(newFolder);
139
137
  setFocusedFolder(newFolder);
140
138
  setOpenFolders(uniq(openFolders.concat(parentId)));
141
- setNewFolderParentId === null || setNewFolderParentId === void 0 || setNewFolderParentId(undefined);
142
- (_ref$current2 = ref.current) === null || _ref$current2 === void 0 || _ref$current2.focus({
139
+ setNewFolderParentId?.(undefined);
140
+ ref.current?.focus({
143
141
  preventScroll: true
144
142
  });
145
143
  }
146
144
  };
147
145
  const onCancelNewFolder = () => {
148
- var _ref$current3;
149
- setNewFolderParentId === null || setNewFolderParentId === void 0 || setNewFolderParentId(undefined);
150
- (_ref$current3 = ref.current) === null || _ref$current3 === void 0 || _ref$current3.focus({
146
+ setNewFolderParentId?.(undefined);
147
+ ref.current?.focus({
151
148
  preventScroll: true
152
149
  });
153
150
  };
154
- const canAddFolder = selectedFolder && (selectedFolder === null || selectedFolder === void 0 ? void 0 : selectedFolder.breadcrumbs.length) < (maxLevel || 1);
151
+ const canAddFolder = selectedFolder && selectedFolder?.breadcrumbs.length < (maxLevel || 1);
155
152
  return (0, _jsxRuntime.jsxs)(StyledTreeStructure, {
156
153
  onBlur: e => {
157
154
  if (type === "picker" && !e.currentTarget.contains(e.relatedTarget)) {
@@ -35,6 +35,6 @@ const flattenFolders = (folders, openFolders) => {
35
35
  };
36
36
  exports.flattenFolders = flattenFolders;
37
37
  const treestructureId = (type, modifier) => {
38
- return "".concat(type, "-treestructure-").concat(modifier);
38
+ return `${type}-treestructure-${modifier}`;
39
39
  };
40
40
  exports.treestructureId = treestructureId;
@@ -0,0 +1,19 @@
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
+ /// <reference types="react" />
9
+ import { ButtonProps } from "@ndla/primitives";
10
+ export interface ZendeskButtonProps extends ButtonProps {
11
+ widgetKey: string;
12
+ locale: string;
13
+ }
14
+ declare global {
15
+ interface Window {
16
+ zE: (modifier: string, action: string, callback?: (() => void) | string) => void;
17
+ }
18
+ }
19
+ export declare const ZendeskButton: import("react").ForwardRefExoticComponent<ZendeskButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ZendeskButton = void 0;
7
+ var _react = require("react");
8
+ var _primitives = require("@ndla/primitives");
9
+ var _jsxRuntime = require("@emotion/react/jsx-runtime");
10
+ /**
11
+ * Copyright (c) 2024-present, NDLA.
12
+ *
13
+ * This source code is licensed under the GPLv3 license found in the
14
+ * LICENSE file in the root directory of this source tree.
15
+ *
16
+ */
17
+
18
+ // TODO: Let's consider abandoning `disabled` on the button here. It should instead just open/close the widget based on its current state.
19
+
20
+ const ZendeskButton = exports.ZendeskButton = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
21
+ let {
22
+ locale,
23
+ variant = "secondary",
24
+ widgetKey,
25
+ children,
26
+ ...rest
27
+ } = _ref;
28
+ const [loading, setLoading] = (0, _react.useState)(false);
29
+ const handleClick = () => {
30
+ if (window && !window.zE) {
31
+ setLoading(true);
32
+ // Asynchronously load zendesk scripts for better performance
33
+ const script = document.createElement("script");
34
+ script.id = "ze-snippet";
35
+ script.type = "text/javascript";
36
+ script.async = true;
37
+ script.onload = () => {
38
+ if (window.zE) {
39
+ window.zE("webWidget", "setLocale", locale);
40
+ window.zE("webWidget:on", "close", () => {
41
+ setLoading(false);
42
+ });
43
+ window.zE("webWidget", "open");
44
+ }
45
+ };
46
+ script.src = `https://static.zdassets.com/ekr/snippet.js?key=${widgetKey}`;
47
+ document.body.appendChild(script);
48
+ } else if (window?.zE) {
49
+ window.zE("webWidget", "open");
50
+ }
51
+ };
52
+ return (0, _jsxRuntime.jsx)(_primitives.Button, {
53
+ onClick: handleClick,
54
+ variant: variant,
55
+ id: "zendeskButton",
56
+ disabled: loading,
57
+ ...rest,
58
+ ref: ref,
59
+ children: children
60
+ });
61
+ });
@@ -21,7 +21,7 @@ const formatNestedMessages = function (phrases) {
21
21
  Object.keys(phrases).forEach(key => {
22
22
  const value = phrases[key];
23
23
  if ({}.hasOwnProperty.call(phrases, key)) {
24
- const keyWithPrefix = prefix ? "".concat(prefix, ".").concat(key) : key;
24
+ const keyWithPrefix = prefix ? `${prefix}.${key}` : key;
25
25
  if (typeof value === "object") {
26
26
  formatNestedMessages(value, formattedMessages, keyWithPrefix);
27
27
  } else {
package/lib/index.d.ts CHANGED
@@ -73,3 +73,5 @@ export { Gloss, GlossExample } from "./Gloss";
73
73
  export { LinkBlock, LinkBlockSection } from "./LinkBlock";
74
74
  export type { Article as ArticleType } from "./types";
75
75
  export { CodeBlock, codeLanguageOptions } from "./CodeBlock";
76
+ export { ZendeskButton } from "./ZendeskButton/ZendeskButton";
77
+ export type { ZendeskButtonProps } from "./ZendeskButton/ZendeskButton";
package/lib/index.js CHANGED
@@ -669,6 +669,12 @@ Object.defineProperty(exports, "WIDE_FRONTPAGE_ARTICLE_MAX_WIDTH", {
669
669
  return _FrontpageArticle.WIDE_FRONTPAGE_ARTICLE_MAX_WIDTH;
670
670
  }
671
671
  });
672
+ Object.defineProperty(exports, "ZendeskButton", {
673
+ enumerable: true,
674
+ get: function () {
675
+ return _ZendeskButton.ZendeskButton;
676
+ }
677
+ });
672
678
  Object.defineProperty(exports, "codeLanguageOptions", {
673
679
  enumerable: true,
674
680
  get: function () {
@@ -815,6 +821,7 @@ var _DefinitionList = require("./DefinitionList");
815
821
  var _Gloss = require("./Gloss");
816
822
  var _LinkBlock = require("./LinkBlock");
817
823
  var _CodeBlock = require("./CodeBlock");
824
+ var _ZendeskButton = require("./ZendeskButton/ZendeskButton");
818
825
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
819
826
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
820
827
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -802,6 +802,7 @@ declare const messages: {
802
802
  url: string;
803
803
  caption: string;
804
804
  };
805
+ valueText: string;
805
806
  controls: {
806
807
  forward15sec: string;
807
808
  rewind15sec: string;
@@ -68,7 +68,7 @@ const messages = {
68
68
  onChange: {
69
69
  deselect: "tag {{label}}, deselected.",
70
70
  clear: "All selected options have been cleared.",
71
- initialFocus: "Tags {{labels}}, selected.",
71
+ initialFocus: `Tags {{labels}}, selected.`,
72
72
  selectedDisabled: "Tag {{label}} is disabled. Select another option.",
73
73
  selected: "Tag {{label}}, selected."
74
74
  },
@@ -89,11 +89,11 @@ const messages = {
89
89
  },
90
90
  htmlTitles: {
91
91
  titleTemplate,
92
- welcomePage: "Frontpage".concat(titleTemplate),
92
+ welcomePage: `Frontpage${titleTemplate}`,
93
93
  topicPage: "Topic",
94
- subjectsPage: "Choose subjects".concat(titleTemplate),
95
- searchPage: "Search".concat(titleTemplate),
96
- notFound: "Page not found".concat(titleTemplate)
94
+ subjectsPage: `Choose subjects${titleTemplate}`,
95
+ searchPage: `Search${titleTemplate}`,
96
+ notFound: `Page not found${titleTemplate}`
97
97
  },
98
98
  askNDLA: "Ask NDLA",
99
99
  articlePage: {
@@ -731,7 +731,7 @@ const messages = {
731
731
  previousArrow: "Go to previous step"
732
732
  },
733
733
  dropdown: {
734
- numberHits: "Search returned {{hits}} hits",
734
+ numberHits: `Search returned {{hits}} hits`,
735
735
  searching: "Searching...",
736
736
  create: "Create new",
737
737
  isSelectedItem: "Added",
@@ -819,6 +819,7 @@ const messages = {
819
819
  url: "Error loading the audio.",
820
820
  caption: "Sorry, an error occurred while loading the audio."
821
821
  },
822
+ valueText: "{{start}} of {{end}}",
822
823
  controls: {
823
824
  forward15sec: "Forward 15 seconds",
824
825
  rewind15sec: "Rewind 15 seconds",
@@ -1376,9 +1377,9 @@ const messages = {
1376
1377
  embed: {
1377
1378
  conceptListError: "Failed to show concept list",
1378
1379
  linkError: "Failed to show link.",
1379
- unsupported: "Embed {{type}} not supported.",
1380
+ unsupported: `Embed {{type}} not supported.`,
1380
1381
  goTo: "Go to {{type}}",
1381
- embedError: "An error occurred while loading the {{type}}. Try reloading the page.",
1382
+ embedError: `An error occurred while loading the {{type}}. Try reloading the page.`,
1382
1383
  type: {
1383
1384
  image: "Image",
1384
1385
  video: "Video",
@@ -802,6 +802,7 @@ declare const messages: {
802
802
  url: string;
803
803
  caption: string;
804
804
  };
805
+ valueText: string;
805
806
  controls: {
806
807
  forward15sec: string;
807
808
  rewind15sec: string;
@@ -68,7 +68,7 @@ const messages = {
68
68
  onChange: {
69
69
  deselect: "emneknagg {{label}}, fjernet.",
70
70
  clear: "Alle valgte emneknagger fjernet.",
71
- initialFocus: "Emneknagger {{labels}}, valgt.",
71
+ initialFocus: `Emneknagger {{labels}}, valgt.`,
72
72
  selectedDisabled: "Emneknagg {{label}} kan ikke velges. Velg et annet alternativ.",
73
73
  selected: "Emneknagg {{label}}, valgt."
74
74
  },
@@ -89,11 +89,11 @@ const messages = {
89
89
  },
90
90
  htmlTitles: {
91
91
  titleTemplate,
92
- welcomePage: "Forsiden".concat(titleTemplate),
92
+ welcomePage: `Forsiden${titleTemplate}`,
93
93
  topicPage: "Emne",
94
- subjectsPage: "Velg fag".concat(titleTemplate),
95
- searchPage: "S\xF8k".concat(titleTemplate),
96
- notFound: "Siden finnes ikke".concat(titleTemplate)
94
+ subjectsPage: `Velg fag${titleTemplate}`,
95
+ searchPage: `Søk${titleTemplate}`,
96
+ notFound: `Siden finnes ikke${titleTemplate}`
97
97
  },
98
98
  askNDLA: "Spør NDLA",
99
99
  articlePage: {
@@ -731,7 +731,7 @@ const messages = {
731
731
  previousArrow: "Gå til forrige steg"
732
732
  },
733
733
  dropdown: {
734
- numberHits: "S\xF8ket gav {{hits}} treff",
734
+ numberHits: `Søket gav {{hits}} treff`,
735
735
  searching: "Søker...",
736
736
  create: "Opprett ny",
737
737
  isSelectedItem: "Lagt til",
@@ -819,6 +819,7 @@ const messages = {
819
819
  url: "Feil ved lasting av lydfil.",
820
820
  caption: "Beklager, en feil oppstod ved lasting av lydfil."
821
821
  },
822
+ valueText: "{{start}} av {{end}}",
822
823
  controls: {
823
824
  forward15sec: "Spol 15 sekunder fram",
824
825
  rewind15sec: "Spol 15 sekunder tilbake",
@@ -1376,9 +1377,9 @@ const messages = {
1376
1377
  embed: {
1377
1378
  conceptListError: "Klarte ikke å vise forklaringsliste",
1378
1379
  linkError: "Klarte ikke å vise lenke.",
1379
- unsupported: "Embed {{type}} er ikke st\xF8ttet.",
1380
+ unsupported: `Embed {{type}} er ikke støttet.`,
1380
1381
  goTo: "Gå til {{type}}",
1381
- embedError: "Beklager, en feil oppstod ved lasting av {{type}}. Pr\xF8v \xE5 laste inn siden p\xE5 nytt.",
1382
+ embedError: `Beklager, en feil oppstod ved lasting av {{type}}. Prøv å laste inn siden nytt.`,
1382
1383
  type: {
1383
1384
  image: "Bilde",
1384
1385
  video: "Video",
@@ -802,6 +802,7 @@ declare const messages: {
802
802
  url: string;
803
803
  caption: string;
804
804
  };
805
+ valueText: string;
805
806
  controls: {
806
807
  forward15sec: string;
807
808
  rewind15sec: string;