@ndla/ui 19.0.1 → 19.2.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 (64) hide show
  1. package/es/Breadcrumb/ActionBreadcrumb.js +9 -3
  2. package/es/MyNdla/Resource/Folder.js +7 -7
  3. package/es/Resource/ListResource.js +7 -7
  4. package/es/TreeStructure/FolderItem.js +54 -38
  5. package/es/TreeStructure/FolderItems.js +29 -35
  6. package/es/TreeStructure/FolderNameInput.js +11 -15
  7. package/es/TreeStructure/TreeStructure.js +64 -91
  8. package/es/TreeStructure/arrowNavigation.js +44 -0
  9. package/es/TreeStructure/helperFunctions.js +41 -35
  10. package/es/locale/messages-en.js +10 -1
  11. package/es/locale/messages-nb.js +10 -1
  12. package/es/locale/messages-nn.js +10 -1
  13. package/es/locale/messages-se.js +10 -1
  14. package/es/locale/messages-sma.js +10 -1
  15. package/lib/Breadcrumb/ActionBreadcrumb.js +9 -3
  16. package/lib/MyNdla/Resource/Folder.js +7 -7
  17. package/lib/Resource/ListResource.js +7 -7
  18. package/lib/TreeStructure/FolderItem.d.ts +6 -3
  19. package/lib/TreeStructure/FolderItem.js +55 -38
  20. package/lib/TreeStructure/FolderItems.d.ts +1 -1
  21. package/lib/TreeStructure/FolderItems.js +29 -35
  22. package/lib/TreeStructure/FolderNameInput.d.ts +3 -2
  23. package/lib/TreeStructure/FolderNameInput.js +11 -15
  24. package/lib/TreeStructure/TreeStructure.d.ts +1 -6
  25. package/lib/TreeStructure/TreeStructure.js +63 -92
  26. package/lib/TreeStructure/TreeStructure.types.d.ts +13 -20
  27. package/lib/TreeStructure/arrowNavigation.d.ts +9 -0
  28. package/lib/TreeStructure/arrowNavigation.js +54 -0
  29. package/lib/TreeStructure/helperFunctions.d.ts +3 -4
  30. package/lib/TreeStructure/helperFunctions.js +45 -35
  31. package/lib/locale/messages-en.d.ts +10 -1
  32. package/lib/locale/messages-en.js +10 -1
  33. package/lib/locale/messages-nb.d.ts +10 -1
  34. package/lib/locale/messages-nb.js +10 -1
  35. package/lib/locale/messages-nn.d.ts +10 -1
  36. package/lib/locale/messages-nn.js +10 -1
  37. package/lib/locale/messages-se.d.ts +10 -1
  38. package/lib/locale/messages-se.js +10 -1
  39. package/lib/locale/messages-sma.d.ts +10 -1
  40. package/lib/locale/messages-sma.js +10 -1
  41. package/package.json +5 -5
  42. package/src/Breadcrumb/ActionBreadcrumb.tsx +3 -0
  43. package/src/MyNdla/Resource/Folder.tsx +1 -1
  44. package/src/Resource/ListResource.tsx +4 -2
  45. package/src/TreeStructure/FolderItem.tsx +63 -40
  46. package/src/TreeStructure/FolderItems.tsx +26 -19
  47. package/src/TreeStructure/FolderNameInput.tsx +9 -11
  48. package/src/TreeStructure/TreeStructure.tsx +56 -71
  49. package/src/TreeStructure/TreeStructure.types.ts +13 -17
  50. package/src/TreeStructure/arrowNavigation.ts +53 -0
  51. package/src/TreeStructure/helperFunctions.ts +17 -25
  52. package/src/locale/messages-en.ts +10 -1
  53. package/src/locale/messages-nb.ts +10 -1
  54. package/src/locale/messages-nn.ts +10 -1
  55. package/src/locale/messages-se.ts +10 -1
  56. package/src/locale/messages-sma.ts +10 -1
  57. package/es/TreeStructure/keyboardNavigation/keyboardNavigation.js +0 -194
  58. package/es/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +0 -0
  59. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.d.ts +0 -11
  60. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.js +0 -198
  61. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.d.ts +0 -26
  62. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +0 -1
  63. package/src/TreeStructure/keyboardNavigation/keyboardNavigation.ts +0 -161
  64. package/src/TreeStructure/keyboardNavigation/keyboardNavigation.types.ts +0 -28
@@ -951,7 +951,13 @@ var messages = _objectSpread(_objectSpread({
951
951
  resources_plural: '{{count}} Resources',
952
952
  folders: '{{count}} Folder',
953
953
  folders_plural: '{{count}} Folders',
954
- folder: 'Folder',
954
+ folder: {
955
+ folder: 'Folder',
956
+ "delete": 'Delete',
957
+ edit: 'Edit'
958
+ },
959
+ confirmDeleteFolder: 'Are you sure you want to delete this folder? This process cannot be undone.',
960
+ confirmDeleteTag: 'Are you sure you want to delete this tag? This process cannot be undone.',
955
961
  myFolders: 'My folders',
956
962
  myTags: 'My tags',
957
963
  newFolder: 'New folder',
@@ -997,6 +1003,9 @@ var messages = _objectSpread(_objectSpread({
997
1003
  }
998
1004
  },
999
1005
  resource: {
1006
+ add: 'Add folder/tag',
1007
+ remove: 'Remove',
1008
+ copyLink: 'Copy link to this page',
1000
1009
  addToMyNdla: 'Add to My NDLA',
1001
1010
  addedToMyNdla: 'Added to My NDLA'
1002
1011
  }
@@ -58,7 +58,13 @@ declare const messages: {
58
58
  resources_plural: string;
59
59
  folders: string;
60
60
  folders_plural: string;
61
- folder: string;
61
+ folder: {
62
+ folder: string;
63
+ delete: string;
64
+ edit: string;
65
+ };
66
+ confirmDeleteFolder: string;
67
+ confirmDeleteTag: string;
62
68
  myFolders: string;
63
69
  myTags: string;
64
70
  newFolder: string;
@@ -104,6 +110,9 @@ declare const messages: {
104
110
  };
105
111
  };
106
112
  resource: {
113
+ add: string;
114
+ remove: string;
115
+ copyLink: string;
107
116
  addToMyNdla: string;
108
117
  addedToMyNdla: string;
109
118
  };
@@ -951,7 +951,13 @@ var messages = _objectSpread(_objectSpread({
951
951
  resources_plural: '{{count}} ressurser',
952
952
  folders: '{{count}} mappe',
953
953
  folders_plural: '{{count}} mapper',
954
- folder: 'Mappe',
954
+ folder: {
955
+ folder: 'Mappe',
956
+ "delete": 'Slett',
957
+ edit: 'Rediger'
958
+ },
959
+ confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
960
+ confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
955
961
  myFolders: 'Mine mapper',
956
962
  myTags: 'Mine tags',
957
963
  newFolder: 'Ny mappe',
@@ -997,6 +1003,9 @@ var messages = _objectSpread(_objectSpread({
997
1003
  }
998
1004
  },
999
1005
  resource: {
1006
+ add: 'Legg til mappe/tag',
1007
+ remove: 'Fjern',
1008
+ copyLink: 'Kopier lenke til siden',
1000
1009
  addToMyNdla: 'Legg i Min NDLA',
1001
1010
  addedToMyNdla: 'Lagt i Min NDLA'
1002
1011
  }
@@ -58,7 +58,13 @@ declare const messages: {
58
58
  resources_plural: string;
59
59
  folders: string;
60
60
  folders_plural: string;
61
- folder: string;
61
+ folder: {
62
+ folder: string;
63
+ delete: string;
64
+ edit: string;
65
+ };
66
+ confirmDeleteFolder: string;
67
+ confirmDeleteTag: string;
62
68
  myFolders: string;
63
69
  myTags: string;
64
70
  newFolder: string;
@@ -104,6 +110,9 @@ declare const messages: {
104
110
  };
105
111
  };
106
112
  resource: {
113
+ add: string;
114
+ remove: string;
115
+ copyLink: string;
107
116
  addToMyNdla: string;
108
117
  addedToMyNdla: string;
109
118
  };
@@ -951,7 +951,13 @@ var messages = _objectSpread(_objectSpread({
951
951
  resources_plural: '{{count}} ressursar',
952
952
  folders: '{{count}} mappe',
953
953
  folders_plural: '{{count}} mapper',
954
- folder: 'Mappe',
954
+ folder: {
955
+ folder: 'Mappe',
956
+ "delete": 'Slett',
957
+ edit: 'Rediger'
958
+ },
959
+ confirmDeleteFolder: 'Er du sikker på at du vil slette mappa? Denne handlinga kan ikkje angres.',
960
+ confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlinga kan ikkje angres.',
955
961
  myFolders: 'Mine mapper',
956
962
  myTags: 'Mine tags',
957
963
  newFolder: 'Ny mappe',
@@ -997,6 +1003,9 @@ var messages = _objectSpread(_objectSpread({
997
1003
  }
998
1004
  },
999
1005
  resource: {
1006
+ add: 'Legg til mappe/tag',
1007
+ remove: 'Fjern',
1008
+ copyLink: 'Kopier lenke til sida',
1000
1009
  addToMyNdla: 'Legg i Min NDLA',
1001
1010
  addedToMyNdla: 'Lagt i Min NDLA'
1002
1011
  }
@@ -58,7 +58,13 @@ declare const messages: {
58
58
  resources_plural: string;
59
59
  folders: string;
60
60
  folders_plural: string;
61
- folder: string;
61
+ folder: {
62
+ folder: string;
63
+ delete: string;
64
+ edit: string;
65
+ };
66
+ confirmDeleteFolder: string;
67
+ confirmDeleteTag: string;
62
68
  myFolders: string;
63
69
  myTags: string;
64
70
  newFolder: string;
@@ -104,6 +110,9 @@ declare const messages: {
104
110
  };
105
111
  };
106
112
  resource: {
113
+ add: string;
114
+ remove: string;
115
+ copyLink: string;
107
116
  addToMyNdla: string;
108
117
  addedToMyNdla: string;
109
118
  };
@@ -951,7 +951,13 @@ var messages = _objectSpread(_objectSpread({
951
951
  resources_plural: '{{count}} ressurser',
952
952
  folders: '{{count}} mappe',
953
953
  folders_plural: '{{count}} mapper',
954
- folder: 'Mappe',
954
+ folder: {
955
+ folder: 'Mappe',
956
+ "delete": 'Slett',
957
+ edit: 'Rediger'
958
+ },
959
+ confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
960
+ confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
955
961
  myFolders: 'Mine mapper',
956
962
  myTags: 'Mine tags',
957
963
  newFolder: 'Ny mappe',
@@ -997,6 +1003,9 @@ var messages = _objectSpread(_objectSpread({
997
1003
  }
998
1004
  },
999
1005
  resource: {
1006
+ add: 'Legg til mappe/tag',
1007
+ remove: 'Fjern',
1008
+ copyLink: 'Kopier lenke til siden',
1000
1009
  addToMyNdla: 'Legg i Min NDLA',
1001
1010
  addedToMyNdla: 'Lagt i Min NDLA'
1002
1011
  }
@@ -58,7 +58,13 @@ declare const messages: {
58
58
  resources_plural: string;
59
59
  folders: string;
60
60
  folders_plural: string;
61
- folder: string;
61
+ folder: {
62
+ folder: string;
63
+ delete: string;
64
+ edit: string;
65
+ };
66
+ confirmDeleteFolder: string;
67
+ confirmDeleteTag: string;
62
68
  myFolders: string;
63
69
  myTags: string;
64
70
  newFolder: string;
@@ -104,6 +110,9 @@ declare const messages: {
104
110
  };
105
111
  };
106
112
  resource: {
113
+ add: string;
114
+ remove: string;
115
+ copyLink: string;
107
116
  addToMyNdla: string;
108
117
  addedToMyNdla: string;
109
118
  };
@@ -951,7 +951,13 @@ var messages = _objectSpread(_objectSpread({
951
951
  resources_plural: '{{count}} ressurser',
952
952
  folders: '{{count}} mappe',
953
953
  folders_plural: '{{count}} mapper',
954
- folder: 'Mappe',
954
+ folder: {
955
+ folder: 'Mappe',
956
+ "delete": 'Slett',
957
+ edit: 'Rediger'
958
+ },
959
+ confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
960
+ confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
955
961
  myFolders: 'Mine mapper',
956
962
  myTags: 'Mine tags',
957
963
  newFolder: 'Ny mappe',
@@ -997,6 +1003,9 @@ var messages = _objectSpread(_objectSpread({
997
1003
  }
998
1004
  },
999
1005
  resource: {
1006
+ add: 'Legg til mappe/tag',
1007
+ remove: 'Fjern',
1008
+ copyLink: 'Kopier lenke til siden',
1000
1009
  addToMyNdla: 'Legg i Min NDLA',
1001
1010
  addedToMyNdla: 'Lagt i Min NDLA'
1002
1011
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "19.0.1",
3
+ "version": "19.2.0",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -31,15 +31,15 @@
31
31
  "types"
32
32
  ],
33
33
  "dependencies": {
34
- "@ndla/button": "^3.0.0",
34
+ "@ndla/button": "^3.1.2",
35
35
  "@ndla/carousel": "^1.2.11",
36
36
  "@ndla/core": "^2.3.0",
37
37
  "@ndla/hooks": "^1.1.4",
38
38
  "@ndla/icons": "^1.10.0",
39
39
  "@ndla/licenses": "^5.0.2",
40
40
  "@ndla/modal": "^1.2.12",
41
- "@ndla/notion": "^3.1.19",
42
- "@ndla/safelink": "^2.1.0",
41
+ "@ndla/notion": "^3.1.22",
42
+ "@ndla/safelink": "^2.2.0",
43
43
  "@ndla/switch": "^0.1.7",
44
44
  "@ndla/tabs": "^1.1.10",
45
45
  "@ndla/tooltip": "^2.1.2",
@@ -81,5 +81,5 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  },
84
- "gitHead": "8c51904170c455fc66f1c624b02829efe15c1482"
84
+ "gitHead": "5f018a6a78778970d0d448896de96bb16e970fab"
85
85
  }
@@ -44,6 +44,9 @@ interface Props {
44
44
 
45
45
  const ActionBreadcrumb = ({ items, actionItems }: Props) => {
46
46
  const renderItem = (item: IndexedBreadcrumbItem, totalCount: number) => {
47
+ if (totalCount === 1) {
48
+ return <StyledSpan title={item.name}>{item.name}</StyledSpan>;
49
+ }
47
50
  if (item.index === totalCount - 1) {
48
51
  return (
49
52
  <MenuButton menuItems={actionItems} size="small">
@@ -136,7 +136,7 @@ const Folder = ({ link, title, subFolders, subResources, type = 'list', menuItem
136
136
  return (
137
137
  <FolderWrapper to={link}>
138
138
  <FolderIconWrapper type={type}>
139
- <FolderOutlined aria-label={t('myNdla.folder')} />
139
+ <FolderOutlined aria-label={t('myNdla.folder.folder')} />
140
140
  </FolderIconWrapper>
141
141
  <FolderTitle>{title}</FolderTitle>
142
142
  <IconCount layoutType={type} type={'folder'} count={subFolders} />
@@ -31,12 +31,13 @@ const ResourceDescription = styled.p`
31
31
  `;
32
32
 
33
33
  const ResourceWrapper = styled(SafeLink)`
34
- display: grid;
35
34
  flex: 1;
35
+ display: grid;
36
+ grid-template-columns: auto 1fr auto;
36
37
  grid-template-areas:
37
38
  'image topicAndTitle tags'
38
39
  'image description description';
39
- grid-template-columns: auto 1fr auto;
40
+
40
41
  ${mq.range({ until: breakpoints.mobileWide })} {
41
42
  grid-template-columns: auto 1fr;
42
43
  grid-template-areas:
@@ -52,6 +53,7 @@ const ResourceWrapper = styled(SafeLink)`
52
53
  border-radius: 2px;
53
54
  color: ${colors.brand.greyDark};
54
55
  gap: 0 ${spacing.small};
56
+
55
57
  &:hover {
56
58
  box-shadow: 1px 1px 6px 2px rgba(9, 55, 101, 0.08);
57
59
  transition-duration: 0.2s;
@@ -6,13 +6,14 @@
6
6
  *
7
7
  */
8
8
 
9
- import React, { useEffect, useRef } from 'react';
9
+ import React, { KeyboardEvent, useEffect, useRef } from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { ArrowDropDown } from '@ndla/icons/common';
12
12
  import { FolderOutlined } from '@ndla/icons/contentType';
13
13
  import { colors, spacing, misc, animations } from '@ndla/core';
14
14
  import SafeLink from '@ndla/safelink';
15
15
  import { SetFocusedFolderId, FolderChildFuncType } from './TreeStructure.types';
16
+ import { arrowNavigation } from './arrowNavigation';
16
17
 
17
18
  const OpenButton = styled.button<{ isOpen: boolean }>`
18
19
  background: transparent;
@@ -49,7 +50,10 @@ const WrapperForFolderChild = styled.div<{ marked: boolean }>`
49
50
  }
50
51
  `;
51
52
 
52
- const FolderName = styled.button<{ marked: boolean; noArrow?: boolean }>`
53
+ const FolderName = styled('button', { shouldForwardProp: (name) => !['marked', 'noArrow'].includes(name) })<{
54
+ marked: boolean;
55
+ noArrow?: boolean;
56
+ }>`
53
57
  line-height: 1;
54
58
  background: ${({ marked }) => (marked ? colors.brand.lighter : 'transparent')};
55
59
  color: ${colors.text.primary};
@@ -81,16 +85,19 @@ const FolderNameLink = FolderName.withComponent(SafeLink);
81
85
  interface Props {
82
86
  name: string;
83
87
  id: string;
84
- onToggleOpen: (id: string) => void;
88
+ level: number;
89
+ onCloseFolder: (id: string) => void;
90
+ onOpenFolder: (id: string) => void;
85
91
  onMarkFolder: (id: string) => void;
92
+ onSelectFolder?: (id: string) => void;
86
93
  isOpen: boolean;
87
94
  markedFolderId?: string;
88
95
  focusedFolderId?: string;
96
+ visibleFolders: string[];
89
97
  loading?: boolean;
90
98
  openOnFolderClick?: boolean;
91
99
  hideArrow?: boolean;
92
100
  setFocusedFolderId: SetFocusedFolderId;
93
- url?: string;
94
101
  icon?: React.ReactNode;
95
102
  noPaddingWhenArrowIsHidden?: boolean;
96
103
  folderChild?: FolderChildFuncType;
@@ -99,62 +106,61 @@ interface Props {
99
106
  const FolderItem = ({
100
107
  hideArrow,
101
108
  loading,
109
+ level,
102
110
  name,
103
111
  id,
104
- onToggleOpen,
112
+ visibleFolders,
113
+ onCloseFolder,
114
+ onOpenFolder,
105
115
  onMarkFolder,
116
+ onSelectFolder,
106
117
  isOpen,
107
118
  markedFolderId,
108
119
  focusedFolderId,
109
120
  openOnFolderClick,
110
121
  setFocusedFolderId,
111
122
  icon,
112
- url,
113
123
  noPaddingWhenArrowIsHidden,
114
124
  folderChild,
115
125
  }: Props) => {
116
- const folderNameLinkRef = useRef<HTMLAnchorElement | null>(null);
117
- const folderNameButtonRef = useRef<HTMLButtonElement | null>(null);
126
+ const ref = useRef<HTMLButtonElement & HTMLAnchorElement>(null);
127
+ const marked = markedFolderId === id;
128
+
129
+ const handleMarkFolder = () => {
130
+ onMarkFolder(id);
131
+ if (openOnFolderClick) {
132
+ if (isOpen) {
133
+ onCloseFolder(id);
134
+ } else {
135
+ onOpenFolder(id);
136
+ }
137
+ }
138
+ };
139
+
118
140
  useEffect(() => {
119
141
  if (focusedFolderId === id) {
120
- if (url && folderNameLinkRef.current) {
121
- folderNameLinkRef.current.focus();
122
- } else if (folderNameButtonRef.current) {
123
- folderNameButtonRef.current.focus();
142
+ if (ref.current) {
143
+ ref.current.focus();
124
144
  }
125
145
  }
126
- }, [focusedFolderId, folderNameLinkRef, folderNameButtonRef, url, id]);
127
- const marked = markedFolderId === id;
146
+ }, [focusedFolderId, ref, id]);
147
+
128
148
  return (
129
149
  <FolderItemWrapper>
130
150
  {!hideArrow && (
131
- <OpenButton tabIndex={-1} isOpen={isOpen} disabled={loading} onClick={() => onToggleOpen(id)}>
151
+ <OpenButton
152
+ tabIndex={-1}
153
+ isOpen={isOpen}
154
+ disabled={loading}
155
+ onClick={() => (isOpen ? onCloseFolder(id) : onOpenFolder(id))}>
132
156
  <ArrowDropDown />
133
157
  </OpenButton>
134
158
  )}
135
- {url ? (
136
- <FolderNameLink
137
- ref={folderNameLinkRef}
138
- noArrow={hideArrow}
139
- to={loading ? '' : url}
140
- tabIndex={marked ? 0 : -1}
141
- marked={marked}
142
- onFocus={() => {
143
- setFocusedFolderId(id);
144
- }}
145
- onClick={() => {
146
- onMarkFolder(id);
147
- if (openOnFolderClick) {
148
- onToggleOpen(id);
149
- }
150
- }}>
151
- {icon || <FolderOutlined />}
152
- {name}
153
- </FolderNameLink>
154
- ) : (
159
+ {onSelectFolder ? (
155
160
  <>
156
161
  <FolderName
157
- ref={folderNameButtonRef}
162
+ ref={ref}
163
+ onKeyDown={(e) => arrowNavigation(e, id, visibleFolders, setFocusedFolderId, onOpenFolder, onCloseFolder)}
158
164
  noArrow={hideArrow && !noPaddingWhenArrowIsHidden}
159
165
  tabIndex={marked ? 0 : -1}
160
166
  marked={marked}
@@ -163,10 +169,8 @@ const FolderItem = ({
163
169
  setFocusedFolderId(id);
164
170
  }}
165
171
  onClick={() => {
166
- onMarkFolder(id);
167
- if (openOnFolderClick) {
168
- onToggleOpen(id);
169
- }
172
+ handleMarkFolder();
173
+ onSelectFolder(id);
170
174
  }}>
171
175
  {icon || <FolderOutlined />}
172
176
  {name}
@@ -177,6 +181,25 @@ const FolderItem = ({
177
181
  </WrapperForFolderChild>
178
182
  )}
179
183
  </>
184
+ ) : (
185
+ <FolderNameLink
186
+ ref={ref}
187
+ onKeyDown={(e: KeyboardEvent<HTMLElement>) =>
188
+ arrowNavigation(e, id, visibleFolders, setFocusedFolderId, onOpenFolder, onCloseFolder)
189
+ }
190
+ noArrow={hideArrow}
191
+ to={loading ? '' : `/minndla/${level > 1 ? 'folders/' : ''}${id}`}
192
+ tabIndex={marked || level === 1 ? 0 : -1}
193
+ marked={marked}
194
+ onFocus={() => {
195
+ setFocusedFolderId(id);
196
+ }}
197
+ onClick={() => {
198
+ handleMarkFolder();
199
+ }}>
200
+ {icon || <FolderOutlined />}
201
+ {name}
202
+ </FolderNameLink>
180
203
  )}
181
204
  </FolderItemWrapper>
182
205
  );
@@ -32,65 +32,73 @@ const StyledLI = styled.li`
32
32
 
33
33
  const FolderItems = ({
34
34
  loading,
35
- data,
36
- idPaths,
35
+ folders,
36
+ level,
37
37
  editable,
38
- onToggleOpen,
38
+ onSelectFolder,
39
+ onCloseFolder,
40
+ onOpenFolder,
39
41
  onCreateNewFolder,
40
42
  onCancelNewFolder,
41
43
  onSaveNewFolder,
42
- newFolder,
44
+ newFolderParentId,
45
+ visibleFolders,
43
46
  openFolders,
44
47
  markedFolderId,
45
48
  onMarkFolder,
46
49
  openOnFolderClick,
47
50
  focusedFolderId,
48
51
  setFocusedFolderId,
49
- firstLevel,
50
52
  folderChild,
51
53
  maximumLevelsOfFoldersAllowed,
52
54
  }: FolderItemsProps) => (
53
- <StyledUL role="group" firstLevel={firstLevel}>
54
- {data.map(({ name, data: dataChildren, id, url, icon }, _index) => {
55
- const newIdPaths = [...idPaths, _index];
55
+ <StyledUL role="group" firstLevel={level === 1}>
56
+ {folders.map(({ name, subfolders, id, icon }, _index) => {
56
57
  const isOpen = openFolders?.includes(id);
57
58
  return (
58
59
  <StyledLI key={id} role="treeitem">
59
60
  <div>
60
61
  <FolderItem
62
+ level={level}
61
63
  icon={icon}
62
- url={url}
64
+ onSelectFolder={onSelectFolder}
63
65
  openOnFolderClick={openOnFolderClick}
64
66
  loading={loading}
65
67
  isOpen={isOpen}
66
68
  id={id}
69
+ visibleFolders={visibleFolders}
67
70
  name={name}
68
71
  markedFolderId={markedFolderId}
69
72
  focusedFolderId={focusedFolderId}
70
- onToggleOpen={onToggleOpen}
71
73
  onMarkFolder={onMarkFolder}
72
- hideArrow={dataChildren?.length === 0 || newIdPaths.length >= maximumLevelsOfFoldersAllowed}
73
- noPaddingWhenArrowIsHidden={editable && firstLevel && dataChildren?.length === 0}
74
+ onCloseFolder={onCloseFolder}
75
+ onOpenFolder={onOpenFolder}
76
+ hideArrow={subfolders?.length === 0 || level > maximumLevelsOfFoldersAllowed}
77
+ noPaddingWhenArrowIsHidden={editable && level === 1 && subfolders?.length === 0}
74
78
  setFocusedFolderId={setFocusedFolderId}
75
79
  folderChild={folderChild}
76
80
  />
77
81
  </div>
78
- {newFolder?.parentId === id && (
82
+ {newFolderParentId === id && (
79
83
  <FolderNameInput
84
+ parentId={newFolderParentId}
80
85
  loading={loading}
81
86
  onCancelNewFolder={onCancelNewFolder}
82
87
  onSaveNewFolder={onSaveNewFolder}
83
88
  />
84
89
  )}
85
- {dataChildren && isOpen && (
90
+ {subfolders && isOpen && (
86
91
  <FolderItems
92
+ onSelectFolder={onSelectFolder}
87
93
  loading={loading}
88
- newFolder={newFolder}
94
+ newFolderParentId={newFolderParentId}
95
+ visibleFolders={visibleFolders}
89
96
  openFolders={openFolders}
90
- idPaths={newIdPaths}
97
+ level={level + 1}
91
98
  editable={editable}
92
- data={dataChildren}
93
- onToggleOpen={onToggleOpen}
99
+ folders={subfolders}
100
+ onCloseFolder={onCloseFolder}
101
+ onOpenFolder={onOpenFolder}
94
102
  onCreateNewFolder={onCreateNewFolder}
95
103
  onSaveNewFolder={onSaveNewFolder}
96
104
  onCancelNewFolder={onCancelNewFolder}
@@ -99,7 +107,6 @@ const FolderItems = ({
99
107
  openOnFolderClick={openOnFolderClick}
100
108
  focusedFolderId={focusedFolderId}
101
109
  setFocusedFolderId={setFocusedFolderId}
102
- firstLevel={false}
103
110
  folderChild={folderChild}
104
111
  maximumLevelsOfFoldersAllowed={maximumLevelsOfFoldersAllowed}
105
112
  />
@@ -53,14 +53,15 @@ const StyledInput = styled.input`
53
53
  `;
54
54
 
55
55
  interface FolderNameInputProps {
56
- onSaveNewFolder: (value: string) => void;
56
+ onSaveNewFolder: (name: string, parentId: string) => void;
57
+ parentId: string;
57
58
  onCancelNewFolder: () => void;
58
59
  loading?: boolean;
59
60
  }
60
61
 
61
- const FolderNameInput = ({ onSaveNewFolder, onCancelNewFolder, loading }: FolderNameInputProps) => {
62
+ const FolderNameInput = ({ onSaveNewFolder, parentId, onCancelNewFolder, loading }: FolderNameInputProps) => {
62
63
  const { t } = useTranslation();
63
- const [value, setValue] = useState<string>(t('treeStructure.newFolder.defaultName'));
64
+ const [name, setName] = useState<string>(t('treeStructure.newFolder.defaultName'));
64
65
  const inputRef = useRef<HTMLInputElement>(null);
65
66
 
66
67
  useEffect(() => {
@@ -82,22 +83,19 @@ const FolderNameInput = ({ onSaveNewFolder, onCancelNewFolder, loading }: Folder
82
83
  autoFocus
83
84
  placeholder={t('treeStructure.newFolder.placeholder')}
84
85
  disabled={loading}
85
- value={value}
86
+ value={name}
86
87
  onBlur={() => onCancelNewFolder()}
87
88
  onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
88
89
  if (e.key === 'Escape') {
89
90
  onCancelNewFolder();
90
- return;
91
- }
92
- if (e.key === 'Enter' || e.key === 'Tab') {
93
- onSaveNewFolder(value);
91
+ } else if (e.key === 'Enter' || e.key === 'Tab') {
94
92
  e.preventDefault();
93
+ onSaveNewFolder(name, parentId);
95
94
  }
96
- return;
97
95
  }}
98
96
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
99
- const target = e.target as HTMLInputElement;
100
- setValue(target.value);
97
+ const target = e.target;
98
+ setName(target.value);
101
99
  }}
102
100
  />
103
101
  {loading && <Spinner size="small" />}