@ndla/ui 20.0.3 → 22.0.1
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.
- package/es/Breadcrumb/ActionBreadcrumb.js +4 -4
- package/es/LearningPaths/LearningPathInformation.js +21 -3
- package/es/LearningPaths/LearningPathMenuAsideCopyright.js +17 -4
- package/es/MyNdla/Resource/Folder.js +7 -6
- package/es/Resource/BlockResource.js +6 -5
- package/es/Resource/ListResource.js +7 -6
- package/es/ResourceGroup/ResourceGroup.js +3 -3
- package/es/ResourceGroup/ResourceItem.js +12 -12
- package/es/ResourceGroup/ResourceList.js +2 -2
- package/es/Search/ContentTypeResult.js +1 -2
- package/es/SearchTypeResult/SearchItem.js +8 -8
- package/es/TopicMenu/TopicMenuButton.js +4 -2
- package/es/TreeStructure/FolderItem.js +109 -68
- package/es/TreeStructure/FolderItems.js +34 -62
- package/es/TreeStructure/FolderNameInput.js +14 -13
- package/es/TreeStructure/TreeStructure.js +89 -98
- package/es/TreeStructure/helperFunctions.js +4 -73
- package/es/TreeStructure/{TreeStructure.types.js → types.js} +0 -0
- package/es/locale/messages-en.js +8 -0
- package/es/locale/messages-nb.js +8 -0
- package/es/locale/messages-nn.js +8 -0
- package/es/locale/messages-se.js +8 -0
- package/es/locale/messages-sma.js +8 -0
- package/lib/Breadcrumb/ActionBreadcrumb.js +4 -4
- package/lib/LearningPaths/LearningPathInformation.js +19 -2
- package/lib/LearningPaths/LearningPathMenuAsideCopyright.js +16 -3
- package/lib/MyNdla/Resource/Folder.js +7 -6
- package/lib/Resource/BlockResource.js +6 -5
- package/lib/Resource/ListResource.js +7 -6
- package/lib/ResourceGroup/ResourceGroup.d.ts +1 -1
- package/lib/ResourceGroup/ResourceGroup.js +3 -3
- package/lib/ResourceGroup/ResourceItem.d.ts +1 -1
- package/lib/ResourceGroup/ResourceItem.js +12 -12
- package/lib/ResourceGroup/ResourceList.d.ts +1 -1
- package/lib/ResourceGroup/ResourceList.js +2 -2
- package/lib/Search/ContentTypeResult.js +1 -2
- package/lib/SearchTypeResult/SearchItem.js +8 -8
- package/lib/TopicMenu/TopicMenuButton.js +3 -1
- package/lib/TreeStructure/FolderItem.d.ts +6 -20
- package/lib/TreeStructure/FolderItem.js +112 -68
- package/lib/TreeStructure/FolderItems.d.ts +11 -2
- package/lib/TreeStructure/FolderItems.js +34 -62
- package/lib/TreeStructure/FolderNameInput.js +14 -13
- package/lib/TreeStructure/TreeStructure.d.ts +12 -2
- package/lib/TreeStructure/TreeStructure.js +87 -96
- package/lib/TreeStructure/helperFunctions.d.ts +2 -4
- package/lib/TreeStructure/helperFunctions.js +5 -80
- package/lib/TreeStructure/index.d.ts +2 -1
- package/lib/TreeStructure/types.d.ts +33 -0
- package/lib/TreeStructure/{TreeStructure.types.js → types.js} +0 -0
- package/lib/index.d.ts +1 -1
- package/lib/locale/messages-en.d.ts +8 -0
- package/lib/locale/messages-en.js +8 -0
- package/lib/locale/messages-nb.d.ts +8 -0
- package/lib/locale/messages-nb.js +8 -0
- package/lib/locale/messages-nn.d.ts +8 -0
- package/lib/locale/messages-nn.js +8 -0
- package/lib/locale/messages-se.d.ts +8 -0
- package/lib/locale/messages-se.js +8 -0
- package/lib/locale/messages-sma.d.ts +8 -0
- package/lib/locale/messages-sma.js +8 -0
- package/package.json +15 -14
- package/src/.DS_Store +0 -0
- package/src/Breadcrumb/ActionBreadcrumb.tsx +1 -1
- package/src/LearningPaths/LearningPathInformation.tsx +27 -12
- package/src/LearningPaths/LearningPathMenuAsideCopyright.tsx +22 -20
- package/src/MyNdla/Resource/Folder.tsx +1 -1
- package/src/Resource/BlockResource.tsx +1 -1
- package/src/Resource/ListResource.tsx +1 -1
- package/src/ResourceGroup/ResourceGroup.tsx +1 -1
- package/src/ResourceGroup/ResourceItem.tsx +2 -2
- package/src/ResourceGroup/ResourceList.tsx +1 -1
- package/src/Search/ContentTypeResult.tsx +0 -1
- package/src/SearchTypeResult/SearchItem.tsx +0 -1
- package/src/TopicMenu/TopicMenuButton.jsx +5 -1
- package/src/TreeStructure/FolderItem.tsx +105 -94
- package/src/TreeStructure/FolderItems.tsx +33 -52
- package/src/TreeStructure/FolderNameInput.tsx +6 -11
- package/src/TreeStructure/TreeStructure.tsx +80 -73
- package/src/TreeStructure/helperFunctions.ts +3 -37
- package/src/TreeStructure/index.ts +2 -1
- package/src/TreeStructure/types.ts +38 -0
- package/src/index.ts +1 -1
- package/src/locale/messages-en.ts +8 -0
- package/src/locale/messages-nb.ts +8 -0
- package/src/locale/messages-nn.ts +8 -0
- package/src/locale/messages-se.ts +8 -0
- package/src/locale/messages-sma.ts +8 -0
- package/lib/TreeStructure/TreeStructure.types.d.ts +0 -61
- package/src/TreeStructure/TreeStructure.types.ts +0 -71
|
@@ -154,7 +154,6 @@ const ItemText = styled.div<ItemTypeProps>`
|
|
|
154
154
|
|
|
155
155
|
const ContextWrapper = styled.div`
|
|
156
156
|
background: white;
|
|
157
|
-
z-index: 1;
|
|
158
157
|
padding: 0 ${spacing.normal} ${spacing.small};
|
|
159
158
|
transition: all ${animations.durations.fast} ease-in-out;
|
|
160
159
|
${ItemWrapper}:hover & {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
11
|
import { css } from '@emotion/core';
|
|
12
|
-
import { spacing, fonts, colors } from '@ndla/core';
|
|
12
|
+
import { spacing, fonts, colors, mq, breakpoints } from '@ndla/core';
|
|
13
13
|
import { Menu } from '@ndla/icons/common';
|
|
14
14
|
import Button from '@ndla/button';
|
|
15
15
|
|
|
@@ -38,6 +38,10 @@ const style = css`
|
|
|
38
38
|
background: ${colors.white};
|
|
39
39
|
color: ${colors.brand.primary};
|
|
40
40
|
}
|
|
41
|
+
${mq.range({ until: breakpoints.tablet })} {
|
|
42
|
+
padding-left: ${spacing.xsmall};
|
|
43
|
+
padding-right: ${spacing.xsmall};
|
|
44
|
+
}
|
|
41
45
|
`;
|
|
42
46
|
|
|
43
47
|
const TopicMenuButton = ({ ndlaFilm, children, ...rest }) => (
|
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import React, { KeyboardEvent, useEffect, useRef } from 'react';
|
|
9
|
+
import React, { KeyboardEvent, MouseEvent, useEffect, useRef } from 'react';
|
|
10
|
+
import { useTranslation } from 'react-i18next';
|
|
10
11
|
import styled from '@emotion/styled';
|
|
11
12
|
import { ArrowDropDown } from '@ndla/icons/common';
|
|
13
|
+
import { Done } from '@ndla/icons/editor';
|
|
14
|
+
import { MenuButton } from '@ndla/button';
|
|
12
15
|
import { FolderOutlined } from '@ndla/icons/contentType';
|
|
13
16
|
import { colors, spacing, misc, animations } from '@ndla/core';
|
|
14
17
|
import SafeLink from '@ndla/safelink';
|
|
15
|
-
import {
|
|
18
|
+
import { CommonFolderItemsProps, FolderType } from './types';
|
|
16
19
|
import { arrowNavigation } from './arrowNavigation';
|
|
17
20
|
|
|
18
21
|
const OpenButton = styled.button<{ isOpen: boolean }>`
|
|
@@ -39,112 +42,123 @@ const FolderItemWrapper = styled.div`
|
|
|
39
42
|
align-items: center;
|
|
40
43
|
`;
|
|
41
44
|
|
|
42
|
-
const WrapperForFolderChild = styled.div
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
&:focus,
|
|
48
|
-
&:focus-within {
|
|
49
|
-
opacity: 1;
|
|
50
|
-
}
|
|
45
|
+
const WrapperForFolderChild = styled.div`
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: row;
|
|
48
|
+
align-items: center;
|
|
49
|
+
gap: ${spacing.xsmall};
|
|
51
50
|
`;
|
|
52
51
|
|
|
53
|
-
const
|
|
54
|
-
|
|
52
|
+
const shouldForwardProp = (name: string) => !['selected', 'noArrow'].includes(name);
|
|
53
|
+
|
|
54
|
+
interface FolderNameProps {
|
|
55
|
+
selected?: boolean;
|
|
55
56
|
noArrow?: boolean;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const FolderName = styled('button', { shouldForwardProp })<FolderNameProps>`
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
padding: ${spacing.xsmall};
|
|
62
|
+
margin: 0;
|
|
63
|
+
margin-left: ${({ noArrow }) => (noArrow ? `29px` : `0px`)};
|
|
64
|
+
flex-grow: 1;
|
|
65
|
+
display: grid;
|
|
66
|
+
grid-template-columns: auto 1fr auto;
|
|
67
|
+
align-items: center;
|
|
68
|
+
gap: ${spacing.xxsmall};
|
|
69
|
+
border: 0;
|
|
70
|
+
border-radius: ${misc.borderRadius};
|
|
71
|
+
box-shadow: none;
|
|
72
|
+
background: ${({ selected }) => (selected ? colors.brand.lighter : 'transparent')};
|
|
59
73
|
color: ${colors.text.primary};
|
|
74
|
+
transition: ${animations.durations.superFast};
|
|
75
|
+
text-align: left;
|
|
76
|
+
line-height: 1;
|
|
77
|
+
word-break: break-word;
|
|
60
78
|
&:hover,
|
|
61
79
|
&:focus {
|
|
62
|
-
background: ${({
|
|
80
|
+
background: ${({ selected }) => (selected ? colors.brand.light : colors.brand.lightest)};
|
|
63
81
|
color: ${colors.brand.primary};
|
|
64
82
|
+ ${WrapperForFolderChild} {
|
|
65
83
|
opacity: 1;
|
|
66
84
|
}
|
|
67
85
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
gap: ${spacing.xxsmall};
|
|
73
|
-
align-items: center;
|
|
74
|
-
cursor: pointer;
|
|
75
|
-
padding: ${spacing.xsmall};
|
|
76
|
-
margin: 0;
|
|
77
|
-
margin-left: ${({ noArrow }) => (noArrow ? `29px` : `0px`)};
|
|
78
|
-
flex-grow: 1;
|
|
79
|
-
box-shadow: none;
|
|
80
|
-
text-align: left;
|
|
86
|
+
`;
|
|
87
|
+
|
|
88
|
+
const StyledDone = styled(Done)`
|
|
89
|
+
color: ${colors.support.green};
|
|
81
90
|
`;
|
|
82
91
|
|
|
83
92
|
const FolderNameLink = FolderName.withComponent(SafeLink);
|
|
84
93
|
|
|
85
|
-
interface Props {
|
|
86
|
-
name: string;
|
|
87
|
-
id: string;
|
|
88
|
-
level: number;
|
|
89
|
-
onCloseFolder: (id: string) => void;
|
|
90
|
-
onOpenFolder: (id: string) => void;
|
|
91
|
-
onMarkFolder: (id: string) => void;
|
|
92
|
-
onSelectFolder?: (id: string) => void;
|
|
93
|
-
isOpen: boolean;
|
|
94
|
-
markedFolderId?: string;
|
|
95
|
-
focusedFolderId?: string;
|
|
96
|
-
visibleFolders: string[];
|
|
97
|
-
loading?: boolean;
|
|
98
|
-
openOnFolderClick?: boolean;
|
|
94
|
+
interface Props extends CommonFolderItemsProps {
|
|
99
95
|
hideArrow?: boolean;
|
|
100
|
-
|
|
101
|
-
|
|
96
|
+
isOpen: boolean;
|
|
97
|
+
folder: FolderType;
|
|
102
98
|
noPaddingWhenArrowIsHidden?: boolean;
|
|
103
|
-
folderChild?: FolderChildFuncType;
|
|
104
99
|
}
|
|
105
100
|
|
|
106
101
|
const FolderItem = ({
|
|
102
|
+
focusedFolderId,
|
|
103
|
+
menuItems,
|
|
107
104
|
hideArrow,
|
|
108
|
-
|
|
105
|
+
folder,
|
|
106
|
+
isOpen,
|
|
109
107
|
level,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
loading,
|
|
109
|
+
selectedFolder,
|
|
110
|
+
noPaddingWhenArrowIsHidden,
|
|
113
111
|
onCloseFolder,
|
|
114
112
|
onOpenFolder,
|
|
115
|
-
onMarkFolder,
|
|
116
113
|
onSelectFolder,
|
|
117
|
-
isOpen,
|
|
118
|
-
markedFolderId,
|
|
119
|
-
focusedFolderId,
|
|
120
114
|
openOnFolderClick,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
115
|
+
setFocusedId,
|
|
116
|
+
setSelectedFolder,
|
|
117
|
+
targetResource,
|
|
118
|
+
visibleFolders,
|
|
125
119
|
}: Props) => {
|
|
120
|
+
const { t } = useTranslation();
|
|
121
|
+
const { id, icon, name } = folder;
|
|
126
122
|
const ref = useRef<HTMLButtonElement & HTMLAnchorElement>(null);
|
|
127
|
-
const
|
|
123
|
+
const selected = selectedFolder && selectedFolder.id === id;
|
|
124
|
+
const focused = focusedFolderId === id;
|
|
128
125
|
|
|
129
|
-
const
|
|
130
|
-
onMarkFolder(id);
|
|
126
|
+
const handleClickFolder = () => {
|
|
131
127
|
if (openOnFolderClick) {
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
128
|
+
if (selected) {
|
|
129
|
+
if (isOpen) {
|
|
130
|
+
onCloseFolder(id);
|
|
131
|
+
} else {
|
|
132
|
+
onOpenFolder(id);
|
|
133
|
+
}
|
|
136
134
|
}
|
|
137
135
|
}
|
|
136
|
+
if (!selected) {
|
|
137
|
+
setSelectedFolder(folder);
|
|
138
|
+
setFocusedId(id);
|
|
139
|
+
}
|
|
140
|
+
onSelectFolder?.(id);
|
|
138
141
|
};
|
|
139
142
|
|
|
140
143
|
useEffect(() => {
|
|
141
144
|
if (focusedFolderId === id) {
|
|
142
|
-
|
|
143
|
-
ref.current.focus();
|
|
144
|
-
}
|
|
145
|
+
ref.current?.focus();
|
|
145
146
|
}
|
|
146
147
|
}, [focusedFolderId, ref, id]);
|
|
147
148
|
|
|
149
|
+
const actions = menuItems?.map((item) => {
|
|
150
|
+
const { onClick } = item;
|
|
151
|
+
return {
|
|
152
|
+
...item,
|
|
153
|
+
onClick: (e?: MouseEvent<HTMLDivElement>) => onClick(e, folder),
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const linkPath = `/minndla${level > 0 ? '/folders' : ''}/${id}`;
|
|
158
|
+
|
|
159
|
+
const containsResource =
|
|
160
|
+
targetResource && folder.resources.some((resource) => resource.resourceId === targetResource.resourceId);
|
|
161
|
+
|
|
148
162
|
return (
|
|
149
163
|
<FolderItemWrapper>
|
|
150
164
|
{!hideArrow && (
|
|
@@ -160,43 +174,40 @@ const FolderItem = ({
|
|
|
160
174
|
<>
|
|
161
175
|
<FolderName
|
|
162
176
|
ref={ref}
|
|
163
|
-
onKeyDown={(e) => arrowNavigation(e, id, visibleFolders,
|
|
177
|
+
onKeyDown={(e) => arrowNavigation(e, id, visibleFolders, setFocusedId, onOpenFolder, onCloseFolder)}
|
|
164
178
|
noArrow={hideArrow && !noPaddingWhenArrowIsHidden}
|
|
165
|
-
tabIndex={
|
|
166
|
-
|
|
179
|
+
tabIndex={selected || focused ? 0 : -1}
|
|
180
|
+
selected={selected}
|
|
167
181
|
disabled={loading}
|
|
168
|
-
onFocus={() =>
|
|
169
|
-
|
|
170
|
-
}}
|
|
171
|
-
onClick={() => {
|
|
172
|
-
handleMarkFolder();
|
|
173
|
-
onSelectFolder(id);
|
|
174
|
-
}}>
|
|
182
|
+
onFocus={() => setFocusedId(id)}
|
|
183
|
+
onClick={handleClickFolder}>
|
|
175
184
|
{icon || <FolderOutlined />}
|
|
176
185
|
{name}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
186
|
+
<WrapperForFolderChild>
|
|
187
|
+
{containsResource && <StyledDone title={t('myNdla.alreadyInFolder')} />}
|
|
188
|
+
{actions && (
|
|
189
|
+
<MenuButton
|
|
190
|
+
onClick={(e) => e.stopPropagation()}
|
|
191
|
+
size="xsmall"
|
|
192
|
+
menuItems={actions}
|
|
193
|
+
tabIndex={selected || id === focusedFolderId ? 0 : -1}
|
|
194
|
+
/>
|
|
195
|
+
)}
|
|
181
196
|
</WrapperForFolderChild>
|
|
182
|
-
|
|
197
|
+
</FolderName>
|
|
183
198
|
</>
|
|
184
199
|
) : (
|
|
185
200
|
<FolderNameLink
|
|
186
201
|
ref={ref}
|
|
187
202
|
onKeyDown={(e: KeyboardEvent<HTMLElement>) =>
|
|
188
|
-
arrowNavigation(e, id, visibleFolders,
|
|
203
|
+
arrowNavigation(e, id, visibleFolders, setFocusedId, onOpenFolder, onCloseFolder)
|
|
189
204
|
}
|
|
190
205
|
noArrow={hideArrow}
|
|
191
|
-
to={loading ? '' :
|
|
192
|
-
tabIndex={
|
|
193
|
-
|
|
194
|
-
onFocus={() =>
|
|
195
|
-
|
|
196
|
-
}}
|
|
197
|
-
onClick={() => {
|
|
198
|
-
handleMarkFolder();
|
|
199
|
-
}}>
|
|
206
|
+
to={loading ? '' : linkPath}
|
|
207
|
+
tabIndex={selected || focused || level === 0 ? 0 : -1}
|
|
208
|
+
selected={selected}
|
|
209
|
+
onFocus={() => setFocusedId(id)}
|
|
210
|
+
onClick={handleClickFolder}>
|
|
200
211
|
{icon || <FolderOutlined />}
|
|
201
212
|
{name}
|
|
202
213
|
</FolderNameLink>
|
|
@@ -11,7 +11,7 @@ import styled from '@emotion/styled';
|
|
|
11
11
|
import { animations, spacing } from '@ndla/core';
|
|
12
12
|
import FolderItem from './FolderItem';
|
|
13
13
|
import FolderNameInput from './FolderNameInput';
|
|
14
|
-
import {
|
|
14
|
+
import { CommonFolderItemsProps, FolderType } from './types';
|
|
15
15
|
|
|
16
16
|
const StyledUL = styled.ul<{ firstLevel?: boolean }>`
|
|
17
17
|
${animations.fadeInLeft(animations.durations.fast)};
|
|
@@ -30,85 +30,66 @@ const StyledLI = styled.li`
|
|
|
30
30
|
padding: 0;
|
|
31
31
|
`;
|
|
32
32
|
|
|
33
|
+
export interface FolderItemsProps extends CommonFolderItemsProps {
|
|
34
|
+
folders: FolderType[];
|
|
35
|
+
editable?: boolean;
|
|
36
|
+
maximumLevelsOfFoldersAllowed: number;
|
|
37
|
+
newFolderParentId: string | undefined;
|
|
38
|
+
onCancelNewFolder: () => void;
|
|
39
|
+
onSaveNewFolder: (name: string, parentId: string) => void;
|
|
40
|
+
openFolders: string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
const FolderItems = ({
|
|
34
|
-
|
|
44
|
+
editable,
|
|
35
45
|
folders,
|
|
36
46
|
level,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
onOpenFolder,
|
|
41
|
-
onCreateNewFolder,
|
|
47
|
+
loading,
|
|
48
|
+
maximumLevelsOfFoldersAllowed,
|
|
49
|
+
newFolderParentId,
|
|
42
50
|
onCancelNewFolder,
|
|
43
51
|
onSaveNewFolder,
|
|
44
|
-
newFolderParentId,
|
|
45
|
-
visibleFolders,
|
|
46
52
|
openFolders,
|
|
47
|
-
|
|
48
|
-
onMarkFolder,
|
|
49
|
-
openOnFolderClick,
|
|
50
|
-
focusedFolderId,
|
|
51
|
-
setFocusedFolderId,
|
|
52
|
-
folderChild,
|
|
53
|
-
maximumLevelsOfFoldersAllowed,
|
|
53
|
+
...rest
|
|
54
54
|
}: FolderItemsProps) => (
|
|
55
|
-
<StyledUL role="group" firstLevel={level ===
|
|
56
|
-
{folders.map((
|
|
55
|
+
<StyledUL role="group" firstLevel={level === 0}>
|
|
56
|
+
{folders.map((folder) => {
|
|
57
|
+
const { subfolders, id } = folder;
|
|
57
58
|
const isOpen = openFolders?.includes(id);
|
|
59
|
+
|
|
58
60
|
return (
|
|
59
61
|
<StyledLI key={id} role="treeitem">
|
|
60
62
|
<div>
|
|
61
63
|
<FolderItem
|
|
64
|
+
hideArrow={subfolders?.length === 0 || level > maximumLevelsOfFoldersAllowed}
|
|
65
|
+
folder={folder}
|
|
66
|
+
isOpen={isOpen}
|
|
62
67
|
level={level}
|
|
63
|
-
icon={icon}
|
|
64
|
-
onSelectFolder={onSelectFolder}
|
|
65
|
-
openOnFolderClick={openOnFolderClick}
|
|
66
68
|
loading={loading}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
visibleFolders={visibleFolders}
|
|
70
|
-
name={name}
|
|
71
|
-
markedFolderId={markedFolderId}
|
|
72
|
-
focusedFolderId={focusedFolderId}
|
|
73
|
-
onMarkFolder={onMarkFolder}
|
|
74
|
-
onCloseFolder={onCloseFolder}
|
|
75
|
-
onOpenFolder={onOpenFolder}
|
|
76
|
-
hideArrow={subfolders?.length === 0 || level > maximumLevelsOfFoldersAllowed}
|
|
77
|
-
noPaddingWhenArrowIsHidden={editable && level === 1 && subfolders?.length === 0}
|
|
78
|
-
setFocusedFolderId={setFocusedFolderId}
|
|
79
|
-
folderChild={folderChild}
|
|
69
|
+
noPaddingWhenArrowIsHidden={editable && level === 0 && subfolders?.length === 0}
|
|
70
|
+
{...rest}
|
|
80
71
|
/>
|
|
81
72
|
</div>
|
|
82
73
|
{newFolderParentId === id && (
|
|
83
74
|
<FolderNameInput
|
|
84
|
-
parentId={newFolderParentId}
|
|
85
75
|
loading={loading}
|
|
86
76
|
onCancelNewFolder={onCancelNewFolder}
|
|
87
77
|
onSaveNewFolder={onSaveNewFolder}
|
|
78
|
+
parentId={newFolderParentId}
|
|
88
79
|
/>
|
|
89
80
|
)}
|
|
90
81
|
{subfolders && isOpen && (
|
|
91
82
|
<FolderItems
|
|
92
|
-
onSelectFolder={onSelectFolder}
|
|
93
|
-
loading={loading}
|
|
94
|
-
newFolderParentId={newFolderParentId}
|
|
95
|
-
visibleFolders={visibleFolders}
|
|
96
|
-
openFolders={openFolders}
|
|
97
|
-
level={level + 1}
|
|
98
83
|
editable={editable}
|
|
99
84
|
folders={subfolders}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
onCreateNewFolder={onCreateNewFolder}
|
|
103
|
-
onSaveNewFolder={onSaveNewFolder}
|
|
104
|
-
onCancelNewFolder={onCancelNewFolder}
|
|
105
|
-
markedFolderId={markedFolderId}
|
|
106
|
-
onMarkFolder={onMarkFolder}
|
|
107
|
-
openOnFolderClick={openOnFolderClick}
|
|
108
|
-
focusedFolderId={focusedFolderId}
|
|
109
|
-
setFocusedFolderId={setFocusedFolderId}
|
|
110
|
-
folderChild={folderChild}
|
|
85
|
+
level={level + 1}
|
|
86
|
+
loading={loading}
|
|
111
87
|
maximumLevelsOfFoldersAllowed={maximumLevelsOfFoldersAllowed}
|
|
88
|
+
newFolderParentId={newFolderParentId}
|
|
89
|
+
onCancelNewFolder={onCancelNewFolder}
|
|
90
|
+
onSaveNewFolder={onSaveNewFolder}
|
|
91
|
+
openFolders={openFolders}
|
|
92
|
+
{...rest}
|
|
112
93
|
/>
|
|
113
94
|
)}
|
|
114
95
|
</StyledLI>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import React, { useEffect, useState, useRef } from 'react';
|
|
9
|
+
import React, { useEffect, useState, useRef, ChangeEvent, KeyboardEvent } from 'react';
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
11
|
import { FolderOutlined } from '@ndla/icons/contentType';
|
|
12
12
|
import { ArrowDropDown as ArrowDropDownRaw } from '@ndla/icons/common';
|
|
@@ -65,11 +65,9 @@ const FolderNameInput = ({ onSaveNewFolder, parentId, onCancelNewFolder, loading
|
|
|
65
65
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
66
66
|
|
|
67
67
|
useEffect(() => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
inputRef.current.scrollIntoView({ behavior: 'smooth' });
|
|
72
|
-
}
|
|
68
|
+
inputRef.current?.select();
|
|
69
|
+
if (isMobile) {
|
|
70
|
+
inputRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
73
71
|
}
|
|
74
72
|
}, []);
|
|
75
73
|
|
|
@@ -85,7 +83,7 @@ const FolderNameInput = ({ onSaveNewFolder, parentId, onCancelNewFolder, loading
|
|
|
85
83
|
disabled={loading}
|
|
86
84
|
value={name}
|
|
87
85
|
onBlur={() => onCancelNewFolder()}
|
|
88
|
-
onKeyDown={(e:
|
|
86
|
+
onKeyDown={(e: KeyboardEvent<HTMLInputElement>) => {
|
|
89
87
|
if (e.key === 'Escape') {
|
|
90
88
|
onCancelNewFolder();
|
|
91
89
|
} else if (e.key === 'Enter' || e.key === 'Tab') {
|
|
@@ -93,10 +91,7 @@ const FolderNameInput = ({ onSaveNewFolder, parentId, onCancelNewFolder, loading
|
|
|
93
91
|
onSaveNewFolder(name, parentId);
|
|
94
92
|
}
|
|
95
93
|
}}
|
|
96
|
-
onChange={(e:
|
|
97
|
-
const target = e.target;
|
|
98
|
-
setName(target.value);
|
|
99
|
-
}}
|
|
94
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) => setName(e.target.value)}
|
|
100
95
|
/>
|
|
101
96
|
{loading && <Spinner size="small" />}
|
|
102
97
|
</InputWrapper>
|