@ndla/ui 56.0.34-alpha.0 → 56.0.36-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 (78) hide show
  1. package/dist/panda.buildinfo.json +8 -20
  2. package/dist/styles.css +20 -64
  3. package/es/CampaignBlock/CampaignBlock.js +36 -47
  4. package/es/Embed/CodeEmbed.js +6 -2
  5. package/es/Embed/ConceptEmbed.js +1 -0
  6. package/es/Embed/EmbedErrorPlaceholder.js +8 -9
  7. package/es/Layout/index.js +1 -3
  8. package/es/index.js +1 -2
  9. package/es/locale/messages-en.js +2 -1
  10. package/es/locale/messages-nb.js +2 -1
  11. package/es/locale/messages-nn.js +2 -1
  12. package/es/locale/messages-se.js +2 -1
  13. package/es/locale/messages-sma.js +2 -1
  14. package/lib/CampaignBlock/CampaignBlock.d.ts +4 -2
  15. package/lib/CampaignBlock/CampaignBlock.js +35 -46
  16. package/lib/Embed/CodeEmbed.js +7 -2
  17. package/lib/Embed/ConceptEmbed.js +1 -0
  18. package/lib/Embed/EmbedErrorPlaceholder.js +7 -8
  19. package/lib/Layout/index.d.ts +0 -2
  20. package/lib/Layout/index.js +1 -11
  21. package/lib/LicenseByline/EmbedByline.d.ts +1 -1
  22. package/lib/index.d.ts +1 -3
  23. package/lib/index.js +1 -14
  24. package/lib/locale/messages-en.d.ts +1 -0
  25. package/lib/locale/messages-en.js +2 -1
  26. package/lib/locale/messages-nb.d.ts +1 -0
  27. package/lib/locale/messages-nb.js +2 -1
  28. package/lib/locale/messages-nn.d.ts +1 -0
  29. package/lib/locale/messages-nn.js +2 -1
  30. package/lib/locale/messages-se.d.ts +1 -0
  31. package/lib/locale/messages-se.js +2 -1
  32. package/lib/locale/messages-sma.d.ts +1 -0
  33. package/lib/locale/messages-sma.js +2 -1
  34. package/package.json +6 -6
  35. package/src/CampaignBlock/CampaignBlock.tsx +43 -44
  36. package/src/ContentTypeHero/ContentTypeHero.stories.tsx +3 -4
  37. package/src/Embed/AudioEmbed.stories.tsx +3 -3
  38. package/src/Embed/BrightcoveEmbed.stories.tsx +3 -3
  39. package/src/Embed/CodeEmbed.tsx +5 -2
  40. package/src/Embed/ConceptEmbed.stories.tsx +3 -3
  41. package/src/Embed/ConceptEmbed.tsx +1 -0
  42. package/src/Embed/EmbedErrorPlaceholder.tsx +8 -9
  43. package/src/Embed/ExternalEmbed.stories.tsx +3 -3
  44. package/src/Embed/H5pEmbed.stories.tsx +3 -3
  45. package/src/Embed/IframeEmbed.stories.tsx +3 -3
  46. package/src/Embed/ImageEmbed.stories.tsx +3 -4
  47. package/src/Embed/RelatedContentEmbed.stories.tsx +3 -3
  48. package/src/Embed/UuDisclaimerEmbed.stories.tsx +3 -4
  49. package/src/Grid/Grid.stories.tsx +4 -3
  50. package/src/Layout/index.ts +0 -4
  51. package/src/LicenseByline/EmbedByline.tsx +1 -1
  52. package/src/index.ts +1 -4
  53. package/src/locale/messages-en.ts +1 -0
  54. package/src/locale/messages-nb.ts +1 -0
  55. package/src/locale/messages-nn.ts +1 -0
  56. package/src/locale/messages-se.ts +1 -0
  57. package/src/locale/messages-sma.ts +1 -0
  58. package/es/Layout/LayoutItem.js +0 -35
  59. package/es/TreeStructure/TreeStructure.js +0 -318
  60. package/es/TreeStructure/helperFunctions.js +0 -29
  61. package/es/TreeStructure/index.js +0 -9
  62. package/es/TreeStructure/types.js +0 -1
  63. package/lib/Layout/LayoutItem.d.ts +0 -11
  64. package/lib/Layout/LayoutItem.js +0 -40
  65. package/lib/TreeStructure/TreeStructure.d.ts +0 -22
  66. package/lib/TreeStructure/TreeStructure.js +0 -325
  67. package/lib/TreeStructure/helperFunctions.d.ts +0 -9
  68. package/lib/TreeStructure/helperFunctions.js +0 -36
  69. package/lib/TreeStructure/index.d.ts +0 -9
  70. package/lib/TreeStructure/index.js +0 -12
  71. package/lib/TreeStructure/types.d.ts +0 -15
  72. package/lib/TreeStructure/types.js +0 -5
  73. package/src/Layout/LayoutItem.tsx +0 -36
  74. package/src/TreeStructure/TreeStructure.stories.tsx +0 -282
  75. package/src/TreeStructure/TreeStructure.tsx +0 -354
  76. package/src/TreeStructure/helperFunctions.ts +0 -18
  77. package/src/TreeStructure/index.ts +0 -10
  78. package/src/TreeStructure/types.ts +0 -22
@@ -1,318 +0,0 @@
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 { useCallback, useMemo, useRef, useState } from "react";
10
- import { flushSync } from "react-dom";
11
- import { useTranslation } from "react-i18next";
12
- import { useTreeView, usePopoverContext } from "@ark-ui/react";
13
- import { AddLine, HeartFill } from "@ndla/icons/action";
14
- import { ArrowDownShortLine, ArrowRightShortLine } from "@ndla/icons/common";
15
- import { FolderUserLine } from "@ndla/icons/contentType";
16
- import { FolderLine } from "@ndla/icons/editor";
17
- import { Button, IconButton, PopoverContent, PopoverRoot, PopoverTrigger, Tree, TreeBranch, TreeBranchContent, TreeBranchControl, TreeBranchIndicator, TreeBranchText, TreeBranchTrigger, TreeItem, TreeItemText, TreeLabel, TreeRootProvider } from "@ndla/primitives";
18
- import { HStack, Stack, styled } from "@ndla/styled-system/jsx";
19
- import { flattenFolders } from "./helperFunctions";
20
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
- export const MAX_LEVEL_FOR_FOLDERS = 5;
22
- const StyledButton = styled(Button, {
23
- base: {
24
- width: "100%",
25
- justifyContent: "space-between",
26
- "& span": {
27
- overflow: "hidden",
28
- textOverflow: "ellipsis"
29
- }
30
- }
31
- });
32
- const StyledHStack = styled(HStack, {
33
- base: {
34
- overflow: "hidden"
35
- }
36
- });
37
- const StyledHeartFill = styled(HeartFill, {
38
- base: {
39
- color: "icon.strong"
40
- }
41
- });
42
- const StyledFolderLine = styled(FolderLine, {
43
- base: {
44
- color: "icon.strong"
45
- }
46
- });
47
- const StyledFolderUserLine = styled(FolderUserLine, {
48
- base: {
49
- color: "icon.strong"
50
- }
51
- });
52
- const StyledTreeRootProvider = styled(TreeRootProvider, {
53
- base: {
54
- width: "100%",
55
- maxHeight: "inherit"
56
- }
57
- });
58
- const StyledPopoverContent = styled(PopoverContent, {
59
- base: {
60
- display: "flex",
61
- flexDirection: "column",
62
- gap: "xsmall",
63
- overflow: "auto",
64
- maxHeight: "inherit",
65
- paddingInline: "xsmall",
66
- paddingBlock: "xsmall"
67
- }
68
- });
69
- const LabelHStack = styled(HStack, {
70
- base: {
71
- width: "100%"
72
- }
73
- });
74
- export const TreeStructure = _ref => {
75
- let {
76
- folders,
77
- defaultOpenFolders,
78
- newFolderInput,
79
- label,
80
- targetResource,
81
- loading,
82
- maxLevel = MAX_LEVEL_FOR_FOLDERS,
83
- onSelectFolder,
84
- ariaDescribedby
85
- } = _ref;
86
- const [open, setOpen] = useState(false);
87
- const [selectedValue, setSelectedValue] = useState(defaultOpenFolders?.[defaultOpenFolders?.length - 1] ?? "");
88
- const [expandedValue, setExpandedValue] = useState(defaultOpenFolders ?? []);
89
- const [focusedValue, setFocusedValue] = useState(selectedValue);
90
- const [newFolderParentId, setNewFolderParentId] = useState(null);
91
- const newFolderButtonRef = useRef(null);
92
- const {
93
- t
94
- } = useTranslation();
95
- const rootFolderIds = useMemo(() => folders.map(folder => folder.id), [folders]);
96
- const contentRef = useRef(null);
97
- const selectedFolder = useMemo(() => {
98
- return flattenFolders(folders).find(folder => folder.id === selectedValue);
99
- }, [folders, selectedValue]);
100
- const disableCreateFolder = useMemo(() => {
101
- return (selectedFolder?.breadcrumbs.length ?? 0) > maxLevel - 1;
102
- }, [maxLevel, selectedFolder?.breadcrumbs.length]);
103
- const onOpenChange = useCallback(details => {
104
- setOpen(details.open);
105
- if (!details.open) {
106
- setNewFolderParentId(null);
107
- }
108
- }, []);
109
- const onKeyDown = useCallback(e => {
110
- if (e.key === "ArrowUp" || e.key === "ArrowDown") {
111
- e.stopPropagation();
112
- setOpen(true);
113
- }
114
- }, []);
115
- const onShowInput = useCallback(() => {
116
- if (disableCreateFolder) return;
117
- const flattenedFolders = flattenFolders(folders);
118
- const folder = flattenedFolders.find(folder => folder.id === selectedValue);
119
- const newExpandedIds = rootFolderIds.concat(folder?.breadcrumbs.map(bc => bc.id) ?? []);
120
- setOpen(true);
121
- setExpandedValue(prev => Array.from(new Set([...prev, ...newExpandedIds])));
122
- setNewFolderParentId(selectedValue);
123
- }, [disableCreateFolder, folders, rootFolderIds, selectedValue]);
124
- const treeView = useTreeView({
125
- focusedValue,
126
- onFocusChange: details => !!details.focusedValue && setFocusedValue(details.focusedValue),
127
- expandedValue,
128
- onExpandedChange: details => setExpandedValue(details.expandedValue),
129
- selectedValue: [selectedValue],
130
- onSelectionChange: details => {
131
- // TODO: This is currently a bug in zag. The TreeView component simply expects the already selected value to remain selected. As such, always choose the "last" selected value.
132
- const val = details.selectedValue[details.selectedValue.length - 1];
133
- if (!val) return;
134
- if (val === selectedValue && details.focusedValue === selectedValue) {
135
- setOpen(false);
136
- return;
137
- }
138
- setSelectedValue(val);
139
- onSelectFolder?.(val);
140
- },
141
- expandOnClick: false
142
- });
143
- const onCreateFolder = useCallback(folder => {
144
- if (!folder) return;
145
- const focus = treeView.focusItem;
146
- const expand = treeView.expand;
147
- const select = treeView.select;
148
- flushSync(() => {
149
- setOpen(true);
150
- });
151
- flushSync(() => {
152
- expand(folder.breadcrumbs.map(bc => bc.id));
153
- });
154
- flushSync(() => {
155
- select([folder.id]);
156
- });
157
- flushSync(() => {
158
- focus(folder.id);
159
- });
160
- setNewFolderParentId(null);
161
- }, [treeView.expand, treeView.focusItem, treeView.select]);
162
- const onAnimationEnd = useCallback(() => {
163
- if (open && focusedValue) {
164
- document.getElementById(focusedValue)?.scrollIntoView({
165
- behavior: "smooth",
166
- block: "nearest"
167
- });
168
- }
169
- }, [focusedValue, open]);
170
- const onCancelFolder = useCallback(() => {
171
- if (!selectedFolder) return;
172
- const focusFunc = selectedFolder.subfolders.length ? treeView.focusBranch : treeView.focusItem;
173
- focusFunc(selectedFolder.id);
174
- setNewFolderParentId(null);
175
- }, [selectedFolder, treeView.focusBranch, treeView.focusItem]);
176
- const addTooltip = loading ? t("loading") : disableCreateFolder ? t("treeStructure.maxFoldersAlreadyAdded") : t("myNdla.newFolderUnder", {
177
- folderName: selectedFolder?.name
178
- });
179
- return /*#__PURE__*/_jsx(StyledTreeRootProvider, {
180
- value: treeView,
181
- asChild: true,
182
- ...treeView.getRootProps(),
183
- children: /*#__PURE__*/_jsxs(Stack, {
184
- align: "flex-end",
185
- children: [/*#__PURE__*/_jsxs(LabelHStack, {
186
- gap: "xsmall",
187
- justify: "space-between",
188
- children: [/*#__PURE__*/_jsx(TreeLabel, {
189
- children: label
190
- }), /*#__PURE__*/_jsxs(Button, {
191
- size: "small",
192
- variant: "tertiary",
193
- ref: newFolderButtonRef,
194
- "aria-disabled": disableCreateFolder,
195
- title: addTooltip,
196
- "aria-label": addTooltip,
197
- loading: loading,
198
- onClick: onShowInput,
199
- children: [/*#__PURE__*/_jsx(AddLine, {}), t("myNdla.newFolder")]
200
- })]
201
- }), /*#__PURE__*/_jsxs(PopoverRoot, {
202
- open: open,
203
- positioning: {
204
- sameWidth: true
205
- },
206
- onOpenChange: onOpenChange,
207
- persistentElements: [() => newFolderButtonRef.current],
208
- initialFocusEl: () => contentRef.current?.querySelector("input") ?? null,
209
- children: [/*#__PURE__*/_jsx(PopoverTrigger, {
210
- asChild: true,
211
- children: /*#__PURE__*/_jsxs(StyledButton, {
212
- variant: "secondary",
213
- onKeyDown: onKeyDown,
214
- "aria-haspopup": "tree",
215
- role: "combobox",
216
- "aria-describedby": ariaDescribedby,
217
- "aria-activedescendant": focusedValue ?? undefined,
218
- children: [/*#__PURE__*/_jsx("span", {
219
- children: selectedFolder?.name
220
- }), /*#__PURE__*/_jsx(ArrowDownShortLine, {})]
221
- })
222
- }), /*#__PURE__*/_jsxs(StyledPopoverContent, {
223
- onAnimationEnd: onAnimationEnd,
224
- ref: contentRef,
225
- children: [!!newFolderParentId && newFolderInput?.({
226
- parentId: newFolderParentId,
227
- onCreate: onCreateFolder,
228
- onCancel: onCancelFolder
229
- }), /*#__PURE__*/_jsx(Tree, {
230
- children: folders.map(folder => /*#__PURE__*/_jsx(TreeStructureItem, {
231
- folder: folder,
232
- targetResource: targetResource
233
- }, folder.id))
234
- })]
235
- })]
236
- })]
237
- })
238
- });
239
- };
240
- const TreeStructureItem = _ref2 => {
241
- let {
242
- folder,
243
- targetResource
244
- } = _ref2;
245
- const {
246
- t
247
- } = useTranslation();
248
- const {
249
- setOpen
250
- } = usePopoverContext();
251
- const containsResource = targetResource && folder.resources.some(resource => resource.resourceId === targetResource.resourceId);
252
- const FolderIcon = folder.status === "shared" ? StyledFolderUserLine : StyledFolderLine;
253
- const onKeyDown = useCallback(e => {
254
- if (e.key === "Enter") {
255
- setOpen(false);
256
- }
257
- }, [setOpen]);
258
- if (!folder.subfolders.length) {
259
- return /*#__PURE__*/_jsx(TreeItem, {
260
- value: folder.id,
261
- onKeyDown: onKeyDown,
262
- id: folder.id,
263
- children: /*#__PURE__*/_jsxs(StyledHStack, {
264
- gap: "xsmall",
265
- justify: "space-between",
266
- children: [/*#__PURE__*/_jsxs(StyledHStack, {
267
- gap: "xxsmall",
268
- justify: "center",
269
- children: [/*#__PURE__*/_jsx(FolderIcon, {}), /*#__PURE__*/_jsx(TreeItemText, {
270
- children: folder.name
271
- })]
272
- }), containsResource && /*#__PURE__*/_jsx(StyledHeartFill, {
273
- title: t("myNdla.alreadyInFolder")
274
- })]
275
- })
276
- }, folder.id);
277
- }
278
- const ariaLabel = folder.status === "shared" ? `${folder.name}. ${t("myNdla.folder.sharing.shared")}` : folder.name;
279
- return /*#__PURE__*/_jsxs(TreeBranch, {
280
- value: folder.id,
281
- id: folder.id,
282
- children: [/*#__PURE__*/_jsx(TreeBranchControl, {
283
- onKeyDown: onKeyDown,
284
- asChild: true,
285
- children: /*#__PURE__*/_jsxs(StyledHStack, {
286
- gap: "xsmall",
287
- justify: "space-between",
288
- children: [/*#__PURE__*/_jsxs(StyledHStack, {
289
- gap: "xxsmall",
290
- justify: "center",
291
- children: [/*#__PURE__*/_jsx(IconButton, {
292
- variant: "clear",
293
- asChild: true,
294
- children: /*#__PURE__*/_jsx(TreeBranchTrigger, {
295
- children: /*#__PURE__*/_jsx(TreeBranchIndicator, {
296
- asChild: true,
297
- children: /*#__PURE__*/_jsx(ArrowRightShortLine, {})
298
- })
299
- })
300
- }), /*#__PURE__*/_jsx(FolderIcon, {}), /*#__PURE__*/_jsx(TreeBranchText, {
301
- "aria-label": ariaLabel,
302
- title: ariaLabel,
303
- children: folder.name
304
- })]
305
- }), containsResource && /*#__PURE__*/_jsx(StyledHeartFill, {
306
- title: t("myNdla.alreadyInFolder"),
307
- "aria-label": t("myNdla.alreadyInFolder"),
308
- "aria-hidden": false
309
- })]
310
- })
311
- }), /*#__PURE__*/_jsx(TreeBranchContent, {
312
- children: folder.subfolders.map(subfolder => /*#__PURE__*/_jsx(TreeStructureItem, {
313
- folder: subfolder,
314
- targetResource: targetResource
315
- }, subfolder.id))
316
- })]
317
- }, folder.id);
318
- };
@@ -1,29 +0,0 @@
1
- /**
2
- * Copyright (c) 2022-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
- export const flattenFolders = (folders, openFolders) => {
10
- return folders.reduce((acc, _ref) => {
11
- let {
12
- subfolders,
13
- id,
14
- ...rest
15
- } = _ref;
16
- if (!subfolders || openFolders && !openFolders.includes(id)) {
17
- return acc.concat({
18
- subfolders,
19
- id,
20
- ...rest
21
- });
22
- }
23
- return acc.concat({
24
- subfolders,
25
- id,
26
- ...rest
27
- }, flattenFolders(subfolders, openFolders));
28
- }, []);
29
- };
@@ -1,9 +0,0 @@
1
- /**
2
- * Copyright (c) 2022-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
- export { TreeStructure } from "./TreeStructure";
@@ -1 +0,0 @@
1
- export {};
@@ -1,11 +0,0 @@
1
- /**
2
- * Copyright (c) 2016-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
- export declare const LayoutItem: import("@ndla/styled-system/types").StyledComponent<"section", {
9
- layout?: "center" | "extend" | undefined;
10
- }>;
11
- export default LayoutItem;
@@ -1,40 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = exports.LayoutItem = void 0;
7
- var _jsx = require("@ndla/styled-system/jsx");
8
- /**
9
- * Copyright (c) 2016-present, NDLA.
10
- *
11
- * This source code is licensed under the GPLv3 license found in the
12
- * LICENSE file in the root directory of this source tree.
13
- *
14
- */
15
-
16
- // TODO: Refactor this. This is a copy of our old layout.
17
- const LayoutItem = exports.LayoutItem = (0, _jsx.styled)("section", {
18
- defaultVariants: {
19
- layout: "center"
20
- },
21
- variants: {
22
- layout: {
23
- center: {
24
- position: "relative!",
25
- width: "83.333%",
26
- right: "auto !important",
27
- left: "8.333%"
28
- },
29
- extend: {
30
- tablet: {
31
- position: "relative!",
32
- width: "83.333%",
33
- right: "auto!",
34
- left: "8.333%"
35
- }
36
- }
37
- }
38
- }
39
- });
40
- var _default = exports.default = LayoutItem;
@@ -1,22 +0,0 @@
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
- import { IFolder, IResource } from "@ndla/types-backend/myndla-api";
9
- import { NewFolderInputFunc } from "./types";
10
- export declare const MAX_LEVEL_FOR_FOLDERS = 5;
11
- export interface TreeStructureProps {
12
- loading?: boolean;
13
- targetResource?: IResource;
14
- defaultOpenFolders?: string[];
15
- folders: IFolder[];
16
- label?: string;
17
- maxLevel?: number;
18
- newFolderInput?: NewFolderInputFunc;
19
- onSelectFolder?: (id: string) => void;
20
- ariaDescribedby?: string;
21
- }
22
- export declare const TreeStructure: ({ folders, defaultOpenFolders, newFolderInput, label, targetResource, loading, maxLevel, onSelectFolder, ariaDescribedby, }: TreeStructureProps) => import("react/jsx-runtime").JSX.Element;