@ndla/ui 25.3.0 → 26.1.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 (63) hide show
  1. package/es/LanguageSelector/LanguageSelector.js +12 -7
  2. package/es/MyNdla/Resource/Folder.js +10 -8
  3. package/es/Resource/BlockResource.js +9 -7
  4. package/es/Resource/ListResource.js +10 -8
  5. package/es/TreeStructure/FolderItem.js +110 -94
  6. package/es/TreeStructure/FolderItems.js +26 -30
  7. package/es/TreeStructure/FolderNameInput.js +35 -27
  8. package/es/TreeStructure/NavigationLink.js +81 -0
  9. package/es/TreeStructure/TreeStructure.js +169 -45
  10. package/es/locale/messages-en.js +4 -1
  11. package/es/locale/messages-nb.js +4 -1
  12. package/es/locale/messages-nn.js +4 -1
  13. package/es/locale/messages-se.js +4 -1
  14. package/es/locale/messages-sma.js +4 -1
  15. package/lib/LanguageSelector/LanguageSelector.js +13 -7
  16. package/lib/MyNdla/Resource/Folder.d.ts +2 -1
  17. package/lib/MyNdla/Resource/Folder.js +10 -8
  18. package/lib/Resource/BlockResource.d.ts +2 -1
  19. package/lib/Resource/BlockResource.js +9 -7
  20. package/lib/Resource/ListResource.d.ts +2 -1
  21. package/lib/Resource/ListResource.js +10 -8
  22. package/lib/TreeStructure/FolderItem.d.ts +2 -3
  23. package/lib/TreeStructure/FolderItem.js +107 -92
  24. package/lib/TreeStructure/FolderItems.d.ts +1 -3
  25. package/lib/TreeStructure/FolderItems.js +26 -29
  26. package/lib/TreeStructure/FolderNameInput.d.ts +2 -1
  27. package/lib/TreeStructure/FolderNameInput.js +33 -26
  28. package/lib/TreeStructure/NavigationLink.d.ts +15 -0
  29. package/lib/TreeStructure/NavigationLink.js +100 -0
  30. package/lib/TreeStructure/TreeStructure.d.ts +1 -2
  31. package/lib/TreeStructure/TreeStructure.js +163 -45
  32. package/lib/TreeStructure/types.d.ts +4 -1
  33. package/lib/locale/messages-en.d.ts +3 -0
  34. package/lib/locale/messages-en.js +4 -1
  35. package/lib/locale/messages-nb.d.ts +3 -0
  36. package/lib/locale/messages-nb.js +4 -1
  37. package/lib/locale/messages-nn.d.ts +3 -0
  38. package/lib/locale/messages-nn.js +4 -1
  39. package/lib/locale/messages-se.d.ts +3 -0
  40. package/lib/locale/messages-se.js +4 -1
  41. package/lib/locale/messages-sma.d.ts +3 -0
  42. package/lib/locale/messages-sma.js +4 -1
  43. package/package.json +11 -11
  44. package/src/.DS_Store +0 -0
  45. package/src/LanguageSelector/LanguageSelector.tsx +4 -1
  46. package/src/MyNdla/Resource/Folder.tsx +3 -2
  47. package/src/Resource/BlockResource.tsx +3 -1
  48. package/src/Resource/ListResource.tsx +3 -1
  49. package/src/TreeStructure/FolderItem.tsx +126 -104
  50. package/src/TreeStructure/FolderItems.tsx +51 -43
  51. package/src/TreeStructure/FolderNameInput.tsx +43 -28
  52. package/src/TreeStructure/NavigationLink.tsx +100 -0
  53. package/src/TreeStructure/TreeStructure.tsx +187 -61
  54. package/src/TreeStructure/types.ts +5 -1
  55. package/src/locale/messages-en.ts +3 -0
  56. package/src/locale/messages-nb.ts +3 -0
  57. package/src/locale/messages-nn.ts +3 -0
  58. package/src/locale/messages-se.ts +3 -0
  59. package/src/locale/messages-sma.ts +3 -0
  60. package/es/TreeStructure/TreeStructureWrapper.js +0 -13
  61. package/lib/TreeStructure/TreeStructureWrapper.d.ts +0 -12
  62. package/lib/TreeStructure/TreeStructureWrapper.js +0 -24
  63. package/src/TreeStructure/TreeStructureWrapper.tsx +0 -31
@@ -0,0 +1,100 @@
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
+ import styled from '@emotion/styled';
10
+ import { colors, fonts, spacing } from '@ndla/core';
11
+ import React, { KeyboardEvent, useEffect, useRef } from 'react';
12
+ import SafeLink from '@ndla/safelink';
13
+ import { arrowNavigation } from './arrowNavigation';
14
+ import { CommonFolderItemsProps, FolderType } from './types';
15
+
16
+ interface StyledProps {
17
+ selected?: boolean;
18
+ }
19
+
20
+ const StyledSafeLink = styled(SafeLink)<StyledProps>`
21
+ display: grid;
22
+ grid-template-columns: ${spacing.medium} 1fr;
23
+ align-items: center;
24
+ padding: ${spacing.xxsmall};
25
+ margin: ${spacing.xsmall} 0;
26
+ gap: ${spacing.xxsmall};
27
+ box-shadow: none;
28
+
29
+ color: ${({ selected }) => (selected ? colors.brand.primary : colors.text.primary)};
30
+ font-weight: ${({ selected }) => (selected ? fonts.weight.semibold : fonts.weight.normal)};
31
+ ${fonts.sizes('16px')};
32
+
33
+ :hover,
34
+ :focus {
35
+ color: ${colors.brand.primary};
36
+ }
37
+ svg {
38
+ height: 26px;
39
+ width: 26px;
40
+ }
41
+ `;
42
+
43
+ const IconWrapper = styled.span`
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ `;
48
+
49
+ interface Props extends CommonFolderItemsProps {
50
+ isOpen: boolean;
51
+ folder: FolderType;
52
+ }
53
+
54
+ const NavigationLink = ({
55
+ loading,
56
+ folder,
57
+ selectedFolder,
58
+ focusedFolderId,
59
+ setSelectedFolder,
60
+ setFocusedId,
61
+ visibleFolders,
62
+ onOpenFolder,
63
+ onCloseFolder,
64
+ }: Props) => {
65
+ const { id, icon, name } = folder;
66
+ const selected = selectedFolder && selectedFolder.id === id;
67
+ const ref = useRef<HTMLButtonElement & HTMLAnchorElement>(null);
68
+ const focused = focusedFolderId === id;
69
+
70
+ const handleClick = () => {
71
+ if (!selected) {
72
+ setSelectedFolder(folder);
73
+ setFocusedId(id);
74
+ }
75
+ };
76
+
77
+ useEffect(() => {
78
+ if (focusedFolderId === id) {
79
+ ref.current?.focus();
80
+ }
81
+ }, [focusedFolderId, ref, id]);
82
+
83
+ return (
84
+ <StyledSafeLink
85
+ ref={ref}
86
+ onKeyDown={(e: KeyboardEvent<HTMLElement>) =>
87
+ arrowNavigation(e, id, visibleFolders, setFocusedId, onOpenFolder, onCloseFolder)
88
+ }
89
+ tabIndex={selected || focused ? 0 : -1}
90
+ selected={selected}
91
+ onFocus={() => setFocusedId(id)}
92
+ onClick={handleClick}
93
+ to={loading ? '' : `/minndla/${id}`}>
94
+ <IconWrapper>{icon}</IconWrapper>
95
+ {name}
96
+ </StyledSafeLink>
97
+ );
98
+ };
99
+
100
+ export default NavigationLink;
@@ -6,18 +6,20 @@
6
6
  *
7
7
  */
8
8
 
9
- import React, { useEffect, useState, useMemo } from 'react';
10
- import { AddButton } from '@ndla/button';
9
+ import React, { useEffect, useState, useMemo, useRef } from 'react';
10
+ import { ButtonV2 as Button, IconButtonDualStates } from '@ndla/button';
11
+ import { Plus } from '@ndla/icons/action';
12
+ import { ChevronDown, ChevronUp } from '@ndla/icons/common';
11
13
  import Tooltip from '@ndla/tooltip';
12
14
  import { useTranslation } from 'react-i18next';
13
15
  import styled from '@emotion/styled';
14
- import { spacing, fonts } from '@ndla/core';
16
+ import { colors, fonts, misc, spacing } from '@ndla/core';
17
+ import { css } from '@emotion/core';
15
18
  import { uniq } from 'lodash';
16
19
  import { IFolder } from '@ndla/types-learningpath-api';
17
- import TreeStructureStyledWrapper from './TreeStructureWrapper';
18
20
  import FolderItems from './FolderItems';
19
21
  import { flattenFolders } from './helperFunctions';
20
- import { CommonTreeStructureProps, FolderType } from './types';
22
+ import { CommonTreeStructureProps, FolderType, TreeStructureType } from './types';
21
23
 
22
24
  export const MAX_LEVEL_FOR_FOLDERS = 4;
23
25
 
@@ -25,15 +27,86 @@ const StyledLabel = styled.label`
25
27
  font-weight: ${fonts.weight.semibold};
26
28
  `;
27
29
 
28
- const AddFolderWrapper = styled.div`
30
+ interface StyledRowProps {
31
+ isOpen: boolean;
32
+ }
33
+
34
+ const StyledRow = styled.div<StyledRowProps>`
35
+ display: flex;
36
+ justify-content: space-between;
37
+ padding: ${spacing.xxsmall};
38
+ border-bottom: ${({ isOpen }) => isOpen && `1px solid ${colors.brand.tertiary}`};
39
+ `;
40
+
41
+ const StyledTreeStructure = styled.div`
42
+ flex: 1;
43
+ display: flex;
44
+ flex-direction: column;
45
+ `;
46
+
47
+ const TreeStructureWrapper = styled.div<{ type: TreeStructureType }>`
29
48
  display: flex;
30
- margin-top: ${spacing.xsmall};
49
+ flex-direction: column;
50
+ ${({ type }) =>
51
+ (type === 'normal' || type === 'picker') &&
52
+ css`
53
+ overflow: hidden;
54
+ border: 1px solid ${colors.brand.neutral7};
55
+ border-radius: ${misc.borderRadius};
56
+ scroll-behavior: smooth;
57
+ `}
58
+ transition: ${misc.transition.default};
59
+ &:focus-within {
60
+ border-color: ${colors.brand.tertiary};
61
+ }
62
+ `;
63
+ interface ScrollableDivProps {
64
+ type: TreeStructureType;
65
+ }
66
+ const ScrollableDiv = styled.div<ScrollableDivProps>`
67
+ ${({ type }) =>
68
+ (type === 'picker' || type === 'normal') &&
69
+ css`
70
+ overflow: overlay;
71
+ ::-webkit-scrollbar {
72
+ width: ${spacing.small};
73
+ }
74
+ ::-webkit-scrollbar-thumb {
75
+ border: 4px solid transparent;
76
+ border-radius: 14px;
77
+ background-clip: padding-box;
78
+ padding: 0 4px;
79
+ background-color: ${colors.brand.neutral7};
80
+ }
81
+ `}
82
+ `;
83
+
84
+ const StyledSelectedFolder = styled(Button)`
85
+ flex: 1;
86
+ justify-content: flex-start;
87
+ :hover,
88
+ :focus {
89
+ background: none;
90
+ box-shadow: none;
91
+ border-color: transparent;
92
+ }
93
+ `;
94
+
95
+ const StyledAddFolderButton = styled(Button)`
96
+ &,
97
+ &:disabled {
98
+ border-color: transparent;
99
+ }
100
+ `;
101
+
102
+ const StyledPlus = styled(Plus)`
103
+ height: 24px;
104
+ width: 24px;
31
105
  `;
32
106
 
33
107
  export interface TreeStructureProps extends CommonTreeStructureProps {
34
108
  defaultOpenFolders?: string[];
35
109
  folders: FolderType[];
36
- editable?: boolean;
37
110
  label?: string;
38
111
  maximumLevelsOfFoldersAllowed?: number;
39
112
  onNewFolder?: (name: string, parentId: string) => Promise<IFolder>;
@@ -41,10 +114,7 @@ export interface TreeStructureProps extends CommonTreeStructureProps {
41
114
 
42
115
  const TreeStructure = ({
43
116
  defaultOpenFolders,
44
- editable,
45
- menuItems,
46
117
  folders,
47
- framed,
48
118
  label,
49
119
  loading,
50
120
  maximumLevelsOfFoldersAllowed = MAX_LEVEL_FOR_FOLDERS,
@@ -52,9 +122,12 @@ const TreeStructure = ({
52
122
  onSelectFolder,
53
123
  openOnFolderClick,
54
124
  targetResource,
125
+ type = 'normal',
55
126
  }: TreeStructureProps) => {
56
127
  const { t } = useTranslation();
57
128
 
129
+ const ref = useRef<HTMLDivElement>(null);
130
+
58
131
  const defaultSelectedFolderId = defaultOpenFolders && defaultOpenFolders[defaultOpenFolders.length - 1];
59
132
 
60
133
  const [openFolders, setOpenFolders] = useState<string[]>(defaultOpenFolders || []);
@@ -62,10 +135,25 @@ const TreeStructure = ({
62
135
  const [newFolderParentId, setNewFolderParentId] = useState<string | undefined>();
63
136
  const [focusedId, setFocusedId] = useState<string | undefined>();
64
137
  const [selectedFolder, setSelectedFolder] = useState<FolderType | undefined>();
138
+ const [showTree, setShowTree] = useState(type !== 'picker');
65
139
 
66
140
  const flattenedFolders = useMemo(() => flattenFolders(folders, openFolders), [folders, openFolders]);
67
141
  const visibleFolderIds = flattenedFolders.map((folder) => folder.id);
68
142
 
143
+ useEffect(() => {
144
+ const handleClickOutside = (e: MouseEvent) => {
145
+ if (e.target instanceof Element && ref.current && !ref.current.contains(e.target)) {
146
+ setShowTree(false);
147
+ }
148
+ };
149
+ if (type === 'picker') {
150
+ document.addEventListener('mousedown', handleClickOutside);
151
+ return () => {
152
+ document.removeEventListener('mousedown', handleClickOutside);
153
+ };
154
+ }
155
+ }, [ref, type]);
156
+
69
157
  useEffect(() => {
70
158
  if (defaultOpenFolders) {
71
159
  if (!defaultOpenFolders.every((element) => openFolders.includes(element))) {
@@ -77,6 +165,10 @@ const TreeStructure = ({
77
165
  // eslint-disable-next-line react-hooks/exhaustive-deps
78
166
  }, [defaultOpenFolders]);
79
167
 
168
+ useEffect(() => {
169
+ setNewFolderParentId(undefined);
170
+ }, [selectedFolder]);
171
+
80
172
  useEffect(() => {
81
173
  if (defaultSelectedFolderId !== undefined) {
82
174
  const selected = flattenFolders(folders).find((folder) => folder.id === defaultSelectedFolderId);
@@ -114,9 +206,9 @@ const TreeStructure = ({
114
206
  };
115
207
 
116
208
  const onSaveNewFolder = (name: string, parentId: string) => {
117
- setNewFolderParentId(undefined);
118
209
  onNewFolder?.(name, parentId).then((newFolder) => {
119
210
  if (newFolder) {
211
+ setNewFolderParentId?.(undefined);
120
212
  setSelectedFolder(newFolder);
121
213
  onSelectFolder?.(newFolder.id);
122
214
  setFocusedId(newFolder.id);
@@ -126,60 +218,94 @@ const TreeStructure = ({
126
218
  };
127
219
 
128
220
  const onCancelNewFolder = () => {
129
- setNewFolderParentId(undefined);
221
+ setNewFolderParentId?.(undefined);
130
222
  };
131
223
 
132
- const canAddFolder =
133
- editable && selectedFolder && selectedFolder?.breadcrumbs.length < (maximumLevelsOfFoldersAllowed || 1);
224
+ const canAddFolder = selectedFolder && selectedFolder?.breadcrumbs.length < (maximumLevelsOfFoldersAllowed || 1);
134
225
 
135
226
  return (
136
- <div>
227
+ <StyledTreeStructure ref={ref}>
137
228
  {label && <StyledLabel>{label}</StyledLabel>}
138
- <TreeStructureStyledWrapper aria-label="Menu tree" role="tree" framed={framed}>
139
- <FolderItems
140
- editable={editable}
141
- focusedFolderId={focusedId}
142
- menuItems={menuItems}
143
- folders={folders}
144
- level={0}
145
- loading={loading}
146
- selectedFolder={selectedFolder}
147
- maximumLevelsOfFoldersAllowed={maximumLevelsOfFoldersAllowed}
148
- newFolderParentId={newFolderParentId}
149
- onCancelNewFolder={onCancelNewFolder}
150
- onCloseFolder={onCloseFolder}
151
- onOpenFolder={onOpenFolder}
152
- onSaveNewFolder={onSaveNewFolder}
153
- onSelectFolder={onSelectFolder}
154
- openFolders={openFolders}
155
- openOnFolderClick={openOnFolderClick}
156
- setFocusedId={setFocusedId}
157
- setSelectedFolder={setSelectedFolder}
158
- targetResource={targetResource}
159
- visibleFolders={visibleFolderIds}
160
- framed={framed}
161
- />
162
- </TreeStructureStyledWrapper>
163
- {editable && (
164
- <AddFolderWrapper>
165
- <Tooltip
166
- tooltip={
167
- canAddFolder
168
- ? t('myNdla.newFolderUnder', {
169
- folderName: selectedFolder?.name,
170
- })
171
- : t('treeStructure.maxFoldersAlreadyAdded')
172
- }>
173
- <AddButton
174
- disabled={!canAddFolder}
175
- aria-label={t('myNdla.newFolder')}
176
- onClick={() => setNewFolderParentId(selectedFolder?.id)}>
177
- {t('myNdla.newFolder')}
178
- </AddButton>
179
- </Tooltip>
180
- </AddFolderWrapper>
181
- )}
182
- </div>
229
+ <TreeStructureWrapper aria-label={label} type={type}>
230
+ {type === 'picker' && (
231
+ <StyledRow isOpen={showTree}>
232
+ <StyledSelectedFolder
233
+ variant="ghost"
234
+ colorTheme="light"
235
+ fontWeight="normal"
236
+ shape="sharp"
237
+ onClick={() => {
238
+ setShowTree(!showTree);
239
+ }}>
240
+ {selectedFolder?.name}
241
+ </StyledSelectedFolder>
242
+ {onNewFolder && showTree && (
243
+ <Tooltip
244
+ tooltip={
245
+ canAddFolder
246
+ ? t('myNdla.newFolderUnder', {
247
+ folderName: selectedFolder?.name,
248
+ })
249
+ : t('treeStructure.maxFoldersAlreadyAdded')
250
+ }>
251
+ <StyledAddFolderButton
252
+ variant="outline"
253
+ shape="pill"
254
+ disabled={!canAddFolder}
255
+ aria-label={
256
+ canAddFolder
257
+ ? t('myNdla.newFolderUnder', {
258
+ folderName: selectedFolder?.name,
259
+ })
260
+ : t('treeStructure.maxFoldersAlreadyAdded')
261
+ }
262
+ onClick={() => setNewFolderParentId(selectedFolder?.id)}>
263
+ <StyledPlus /> {t('myNdla.newFolder')}
264
+ </StyledAddFolderButton>
265
+ </Tooltip>
266
+ )}
267
+ <IconButtonDualStates
268
+ ariaLabelActive={t('treeStructure.hideFolders')}
269
+ ariaLabelInActive={t('treeStructure.showFolders')}
270
+ active={showTree}
271
+ variant="ghost"
272
+ colorTheme="greyLighter"
273
+ inactiveIcon={<ChevronDown />}
274
+ activeIcon={<ChevronUp />}
275
+ size="small"
276
+ onClick={() => {
277
+ setShowTree(!showTree);
278
+ }}
279
+ />
280
+ </StyledRow>
281
+ )}
282
+ {showTree && (
283
+ <ScrollableDiv type={type}>
284
+ <FolderItems
285
+ focusedFolderId={focusedId}
286
+ folders={folders}
287
+ level={0}
288
+ loading={loading}
289
+ selectedFolder={selectedFolder}
290
+ maxLevel={maximumLevelsOfFoldersAllowed}
291
+ newFolderParentId={newFolderParentId}
292
+ onCancelNewFolder={onCancelNewFolder}
293
+ onCloseFolder={onCloseFolder}
294
+ onOpenFolder={onOpenFolder}
295
+ onSaveNewFolder={onSaveNewFolder}
296
+ onSelectFolder={onSelectFolder}
297
+ openFolders={openFolders}
298
+ openOnFolderClick={openOnFolderClick}
299
+ setFocusedId={setFocusedId}
300
+ setSelectedFolder={setSelectedFolder}
301
+ targetResource={targetResource}
302
+ visibleFolders={visibleFolderIds}
303
+ type={type}
304
+ />
305
+ </ScrollableDiv>
306
+ )}
307
+ </TreeStructureWrapper>
308
+ </StyledTreeStructure>
183
309
  );
184
310
  };
185
311
 
@@ -12,8 +12,11 @@ import { MenuItemProps } from '@ndla/button';
12
12
 
13
13
  export interface FolderType extends IFolder {
14
14
  icon?: ReactNode;
15
+ isNavigation?: boolean;
15
16
  }
16
17
 
18
+ export type TreeStructureType = 'normal' | 'navigation' | 'picker';
19
+
17
20
  export interface TreeStructureMenuProps extends Omit<MenuItemProps, 'onClick'> {
18
21
  onClick: (e: MouseEvent<HTMLDivElement> | undefined, folder: FolderType) => void;
19
22
  }
@@ -22,14 +25,15 @@ export interface CommonTreeStructureProps {
22
25
  loading?: boolean;
23
26
  onSelectFolder?: (id: string) => void;
24
27
  openOnFolderClick?: boolean;
25
- menuItems?: TreeStructureMenuProps[];
26
28
  targetResource?: IResource;
27
29
  framed?: boolean;
30
+ type: TreeStructureType;
28
31
  }
29
32
 
30
33
  export interface CommonFolderItemsProps extends CommonTreeStructureProps {
31
34
  focusedFolderId?: string;
32
35
  level: number;
36
+ maxLevel: number;
33
37
  selectedFolder?: FolderType;
34
38
  onCloseFolder: (id: string) => void;
35
39
  onOpenFolder: (id: string) => void;
@@ -19,6 +19,8 @@ const messages = {
19
19
  edit: 'Edit foldername',
20
20
  delete: 'Delete',
21
21
  },
22
+ hideFolders: 'Hide all folders',
23
+ showFolders: 'Show all folders',
22
24
  createFolder: 'Create folder',
23
25
  maxFoldersAlreadyAdded: 'Maximum subfolders reached',
24
26
  newFolder: {
@@ -992,6 +994,7 @@ const messages = {
992
994
  edit: 'Edit folder',
993
995
  missingName: 'Folder name required',
994
996
  folderDeleted: '"{{folderName}}" deleted',
997
+ folderCreated: '"{{folderName}} created',
995
998
  },
996
999
  tags: '{{count}} tag',
997
1000
  tags_plural: '{{count}} tags',
@@ -19,6 +19,8 @@ const messages = {
19
19
  edit: 'Endre mappenavn',
20
20
  delete: 'Slett',
21
21
  },
22
+ hideFolders: 'Skjul alle mapper',
23
+ showFolders: 'Vis alle mapper',
22
24
  createFolder: 'Lag mappe',
23
25
  maxFoldersAlreadyAdded: 'Maks nivå av undermapper nådd',
24
26
  newFolder: {
@@ -990,6 +992,7 @@ const messages = {
990
992
  edit: 'Rediger mappe',
991
993
  missingName: 'Skriv navn på mappe',
992
994
  folderDeleted: '"{{folderName}}" er slettet',
995
+ folderCreated: '"{{folderName}}" er opprettet',
993
996
  },
994
997
  tags: '{{count}} emneknagg',
995
998
  tags_plural: '{{count}} emneknagger',
@@ -19,6 +19,8 @@ const messages = {
19
19
  edit: 'Endre mappenamn',
20
20
  delete: 'Slett',
21
21
  },
22
+ hideFolders: 'Skjul alle mapper',
23
+ showFolders: 'Vis alle mapper',
22
24
  createFolder: 'Lag mappe',
23
25
  maxFoldersAlreadyAdded: 'Maks nivå av undermapper nådd',
24
26
  newFolder: {
@@ -991,6 +993,7 @@ const messages = {
991
993
  edit: 'Rediger mappe',
992
994
  missingName: 'Skriv namn på mappe',
993
995
  folderDeleted: '"{{folderName}}" er sletta',
996
+ folderCreated: '"{{folderName}}" er oppretta',
994
997
  },
995
998
  tags: '{{count}} emneknagg',
996
999
  tags_plural: '{{count}} emneknaggar',
@@ -19,6 +19,8 @@ const messages = {
19
19
  edit: 'Rievdat máhpa nama',
20
20
  delete: 'Sihko',
21
21
  },
22
+ hideFolders: 'Skjul alle mapper',
23
+ showFolders: 'Vis alle mapper',
22
24
  createFolder: 'Ráhkat máhpa',
23
25
  maxFoldersAlreadyAdded: 'Vuollemáhpaid badjerádji lea olahuvvon',
24
26
  newFolder: {
@@ -991,6 +993,7 @@ const messages = {
991
993
  edit: 'Redigere',
992
994
  missingName: 'Čále nama máhppii',
993
995
  folderDeleted: '"{{folderName}}" lea sihkkojuvvon',
996
+ folderCreated: '"{{folderName}}" er oppretta',
994
997
  },
995
998
  tags: '{{count}} fáddágilkor',
996
999
  tags_plural: '{{count}} fáddágilkorat',
@@ -19,6 +19,8 @@ const messages = {
19
19
  edit: 'Endre mappenavn',
20
20
  delete: 'Slett',
21
21
  },
22
+ hideFolders: 'Skjul alle mapper',
23
+ showFolders: 'Vis alle mapper',
22
24
  createFolder: 'Lag mappe',
23
25
  maxFoldersAlreadyAdded: 'Maks nivå av undermapper nådd',
24
26
  newFolder: {
@@ -991,6 +993,7 @@ const messages = {
991
993
  edit: 'Rediger mappe',
992
994
  missingName: 'Skriv navn på mappe',
993
995
  folderDeleted: '"{{folderName}}" er slettet',
996
+ folderCreated: '"{{folderName}}" er oppretta',
994
997
  },
995
998
  tags: '{{count}} emneknagg',
996
999
  tags_plural: '{{count}} emneknagger',
@@ -1,13 +0,0 @@
1
- import _styled from "@emotion/styled-base";
2
- import { css } from '@emotion/core';
3
- import { colors, misc, spacing } from '@ndla/core';
4
-
5
- var TreeStructureWrapper = _styled("div", {
6
- target: "ez53f4u0",
7
- label: "TreeStructureWrapper"
8
- })("padding:", spacing.xsmall, ";", function (_ref) {
9
- var framed = _ref.framed;
10
- return framed && /*#__PURE__*/css("border:1px solid ", colors.brand.neutral7, ";border-radius:", misc.borderRadius, ";max-height:400px;overflow-y:scroll;scroll-behavior:smooth;padding:", spacing.small, ";;label:TreeStructureWrapper;" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlRyZWVTdHJ1Y3R1cmVXcmFwcGVyLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFnQk8iLCJmaWxlIjoiVHJlZVN0cnVjdHVyZVdyYXBwZXIudHN4Iiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjItcHJlc2VudCwgTkRMQS5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBHUEx2MyBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqL1xuXG5pbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCc7XG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9jb3JlJztcbmltcG9ydCB7IGNvbG9ycywgbWlzYywgc3BhY2luZyB9IGZyb20gJ0BuZGxhL2NvcmUnO1xuXG5jb25zdCBUcmVlU3RydWN0dXJlV3JhcHBlciA9IHN0eWxlZC5kaXY8eyBmcmFtZWQ/OiBib29sZWFuIH0+YFxuICBwYWRkaW5nOiAke3NwYWNpbmcueHNtYWxsfTtcbiAgJHsoeyBmcmFtZWQgfSkgPT5cbiAgICBmcmFtZWQgJiZcbiAgICBjc3NgXG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAke2NvbG9ycy5icmFuZC5uZXV0cmFsN307XG4gICAgICBib3JkZXItcmFkaXVzOiAke21pc2MuYm9yZGVyUmFkaXVzfTtcbiAgICAgIG1heC1oZWlnaHQ6IDQwMHB4O1xuICAgICAgb3ZlcmZsb3cteTogc2Nyb2xsO1xuICAgICAgc2Nyb2xsLWJlaGF2aW9yOiBzbW9vdGg7XG4gICAgICBwYWRkaW5nOiAke3NwYWNpbmcuc21hbGx9O1xuICAgIGB9XG4gIHRyYW5zaXRpb246ICR7bWlzYy50cmFuc2l0aW9uLmRlZmF1bHR9O1xuICAmOmZvY3VzLXdpdGhpbiB7XG4gICAgYm9yZGVyLWNvbG9yOiAke2NvbG9ycy5icmFuZC5wcmltYXJ5fTtcbiAgfVxuYDtcblxuZXhwb3J0IGRlZmF1bHQgVHJlZVN0cnVjdHVyZVdyYXBwZXI7XG4iXX0= */"));
11
- }, " transition:", misc.transition["default"], ";&:focus-within{border-color:", colors.brand.primary, ";}" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlRyZWVTdHJ1Y3R1cmVXcmFwcGVyLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFZNkQiLCJmaWxlIjoiVHJlZVN0cnVjdHVyZVdyYXBwZXIudHN4Iiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjItcHJlc2VudCwgTkRMQS5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBHUEx2MyBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqL1xuXG5pbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCc7XG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9jb3JlJztcbmltcG9ydCB7IGNvbG9ycywgbWlzYywgc3BhY2luZyB9IGZyb20gJ0BuZGxhL2NvcmUnO1xuXG5jb25zdCBUcmVlU3RydWN0dXJlV3JhcHBlciA9IHN0eWxlZC5kaXY8eyBmcmFtZWQ/OiBib29sZWFuIH0+YFxuICBwYWRkaW5nOiAke3NwYWNpbmcueHNtYWxsfTtcbiAgJHsoeyBmcmFtZWQgfSkgPT5cbiAgICBmcmFtZWQgJiZcbiAgICBjc3NgXG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAke2NvbG9ycy5icmFuZC5uZXV0cmFsN307XG4gICAgICBib3JkZXItcmFkaXVzOiAke21pc2MuYm9yZGVyUmFkaXVzfTtcbiAgICAgIG1heC1oZWlnaHQ6IDQwMHB4O1xuICAgICAgb3ZlcmZsb3cteTogc2Nyb2xsO1xuICAgICAgc2Nyb2xsLWJlaGF2aW9yOiBzbW9vdGg7XG4gICAgICBwYWRkaW5nOiAke3NwYWNpbmcuc21hbGx9O1xuICAgIGB9XG4gIHRyYW5zaXRpb246ICR7bWlzYy50cmFuc2l0aW9uLmRlZmF1bHR9O1xuICAmOmZvY3VzLXdpdGhpbiB7XG4gICAgYm9yZGVyLWNvbG9yOiAke2NvbG9ycy5icmFuZC5wcmltYXJ5fTtcbiAgfVxuYDtcblxuZXhwb3J0IGRlZmF1bHQgVHJlZVN0cnVjdHVyZVdyYXBwZXI7XG4iXX0= */"));
12
-
13
- export default TreeStructureWrapper;
@@ -1,12 +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
- /// <reference types="react" />
9
- declare const TreeStructureWrapper: import("@emotion/styled-base").StyledComponent<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
10
- framed?: boolean | undefined;
11
- }, object>;
12
- export default TreeStructureWrapper;
@@ -1,24 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports["default"] = void 0;
7
-
8
- var _styledBase = _interopRequireDefault(require("@emotion/styled-base"));
9
-
10
- var _core = require("@emotion/core");
11
-
12
- var _core2 = require("@ndla/core");
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
-
16
- var TreeStructureWrapper = (0, _styledBase["default"])("div", {
17
- target: "ez53f4u0",
18
- label: "TreeStructureWrapper"
19
- })("padding:", _core2.spacing.xsmall, ";", function (_ref) {
20
- var framed = _ref.framed;
21
- return framed && /*#__PURE__*/(0, _core.css)("border:1px solid ", _core2.colors.brand.neutral7, ";border-radius:", _core2.misc.borderRadius, ";max-height:400px;overflow-y:scroll;scroll-behavior:smooth;padding:", _core2.spacing.small, ";;label:TreeStructureWrapper;" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlRyZWVTdHJ1Y3R1cmVXcmFwcGVyLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFnQk8iLCJmaWxlIjoiVHJlZVN0cnVjdHVyZVdyYXBwZXIudHN4Iiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjItcHJlc2VudCwgTkRMQS5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBHUEx2MyBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqL1xuXG5pbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCc7XG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9jb3JlJztcbmltcG9ydCB7IGNvbG9ycywgbWlzYywgc3BhY2luZyB9IGZyb20gJ0BuZGxhL2NvcmUnO1xuXG5jb25zdCBUcmVlU3RydWN0dXJlV3JhcHBlciA9IHN0eWxlZC5kaXY8eyBmcmFtZWQ/OiBib29sZWFuIH0+YFxuICBwYWRkaW5nOiAke3NwYWNpbmcueHNtYWxsfTtcbiAgJHsoeyBmcmFtZWQgfSkgPT5cbiAgICBmcmFtZWQgJiZcbiAgICBjc3NgXG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAke2NvbG9ycy5icmFuZC5uZXV0cmFsN307XG4gICAgICBib3JkZXItcmFkaXVzOiAke21pc2MuYm9yZGVyUmFkaXVzfTtcbiAgICAgIG1heC1oZWlnaHQ6IDQwMHB4O1xuICAgICAgb3ZlcmZsb3cteTogc2Nyb2xsO1xuICAgICAgc2Nyb2xsLWJlaGF2aW9yOiBzbW9vdGg7XG4gICAgICBwYWRkaW5nOiAke3NwYWNpbmcuc21hbGx9O1xuICAgIGB9XG4gIHRyYW5zaXRpb246ICR7bWlzYy50cmFuc2l0aW9uLmRlZmF1bHR9O1xuICAmOmZvY3VzLXdpdGhpbiB7XG4gICAgYm9yZGVyLWNvbG9yOiAke2NvbG9ycy5icmFuZC5wcmltYXJ5fTtcbiAgfVxuYDtcblxuZXhwb3J0IGRlZmF1bHQgVHJlZVN0cnVjdHVyZVdyYXBwZXI7XG4iXX0= */"));
22
- }, " transition:", _core2.misc.transition["default"], ";&:focus-within{border-color:", _core2.colors.brand.primary, ";}" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlRyZWVTdHJ1Y3R1cmVXcmFwcGVyLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFZNkQiLCJmaWxlIjoiVHJlZVN0cnVjdHVyZVdyYXBwZXIudHN4Iiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjItcHJlc2VudCwgTkRMQS5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBHUEx2MyBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICpcbiAqL1xuXG5pbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCc7XG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9jb3JlJztcbmltcG9ydCB7IGNvbG9ycywgbWlzYywgc3BhY2luZyB9IGZyb20gJ0BuZGxhL2NvcmUnO1xuXG5jb25zdCBUcmVlU3RydWN0dXJlV3JhcHBlciA9IHN0eWxlZC5kaXY8eyBmcmFtZWQ/OiBib29sZWFuIH0+YFxuICBwYWRkaW5nOiAke3NwYWNpbmcueHNtYWxsfTtcbiAgJHsoeyBmcmFtZWQgfSkgPT5cbiAgICBmcmFtZWQgJiZcbiAgICBjc3NgXG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAke2NvbG9ycy5icmFuZC5uZXV0cmFsN307XG4gICAgICBib3JkZXItcmFkaXVzOiAke21pc2MuYm9yZGVyUmFkaXVzfTtcbiAgICAgIG1heC1oZWlnaHQ6IDQwMHB4O1xuICAgICAgb3ZlcmZsb3cteTogc2Nyb2xsO1xuICAgICAgc2Nyb2xsLWJlaGF2aW9yOiBzbW9vdGg7XG4gICAgICBwYWRkaW5nOiAke3NwYWNpbmcuc21hbGx9O1xuICAgIGB9XG4gIHRyYW5zaXRpb246ICR7bWlzYy50cmFuc2l0aW9uLmRlZmF1bHR9O1xuICAmOmZvY3VzLXdpdGhpbiB7XG4gICAgYm9yZGVyLWNvbG9yOiAke2NvbG9ycy5icmFuZC5wcmltYXJ5fTtcbiAgfVxuYDtcblxuZXhwb3J0IGRlZmF1bHQgVHJlZVN0cnVjdHVyZVdyYXBwZXI7XG4iXX0= */"));
23
- var _default = TreeStructureWrapper;
24
- exports["default"] = _default;
@@ -1,31 +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
- import styled from '@emotion/styled';
10
- import { css } from '@emotion/core';
11
- import { colors, misc, spacing } from '@ndla/core';
12
-
13
- const TreeStructureWrapper = styled.div<{ framed?: boolean }>`
14
- padding: ${spacing.xsmall};
15
- ${({ framed }) =>
16
- framed &&
17
- css`
18
- border: 1px solid ${colors.brand.neutral7};
19
- border-radius: ${misc.borderRadius};
20
- max-height: 400px;
21
- overflow-y: scroll;
22
- scroll-behavior: smooth;
23
- padding: ${spacing.small};
24
- `}
25
- transition: ${misc.transition.default};
26
- &:focus-within {
27
- border-color: ${colors.brand.primary};
28
- }
29
- `;
30
-
31
- export default TreeStructureWrapper;