@ndla/ui 42.1.1 → 42.1.2
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/AudioPlayer/AudioPlayer.js +27 -33
- package/es/CampaignBlock/CampaignBlock.js +32 -18
- package/es/LicenseByline/EmbedByline.js +5 -5
- package/es/MyNdla/Resource/Folder.js +27 -66
- package/es/Resource/BlockResource.js +13 -22
- package/es/Resource/ListResource.js +12 -14
- package/es/Resource/resourceComponents.js +59 -29
- package/es/TreeStructure/ComboboxButton.js +17 -20
- package/es/TreeStructure/FolderItem.js +42 -65
- package/es/TreeStructure/FolderItems.js +25 -19
- package/es/TreeStructure/TreeStructure.js +19 -26
- package/lib/AudioPlayer/AudioPlayer.js +27 -33
- package/lib/CampaignBlock/CampaignBlock.js +32 -18
- package/lib/LicenseByline/EmbedByline.js +5 -5
- package/lib/MyNdla/Resource/Folder.js +27 -66
- package/lib/Resource/BlockResource.d.ts +1 -1
- package/lib/Resource/BlockResource.js +12 -21
- package/lib/Resource/ListResource.js +11 -13
- package/lib/Resource/resourceComponents.d.ts +5 -10
- package/lib/Resource/resourceComponents.js +63 -31
- package/lib/TreeStructure/ComboboxButton.js +17 -20
- package/lib/TreeStructure/FolderItem.js +40 -63
- package/lib/TreeStructure/FolderItems.js +31 -26
- package/lib/TreeStructure/TreeStructure.js +19 -26
- package/package.json +14 -14
- package/src/AudioPlayer/AudioPlayer.tsx +24 -34
- package/src/CampaignBlock/CampaignBlock.tsx +10 -10
- package/src/LicenseByline/EmbedByline.tsx +1 -1
- package/src/MyNdla/Resource/Folder.tsx +28 -35
- package/src/Resource/BlockResource.tsx +21 -18
- package/src/Resource/ListResource.tsx +17 -12
- package/src/Resource/resourceComponents.tsx +34 -15
- package/src/TreeStructure/ComboboxButton.tsx +5 -7
- package/src/TreeStructure/FolderItem.tsx +49 -32
- package/src/TreeStructure/FolderItems.tsx +6 -8
- package/src/TreeStructure/TreeStructure.tsx +16 -25
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import React, { KeyboardEvent, useEffect, useRef } from 'react';
|
|
9
|
+
import React, { CSSProperties, KeyboardEvent, useEffect, useMemo, useRef } from 'react';
|
|
10
10
|
import { useTranslation } from 'react-i18next';
|
|
11
11
|
import styled from '@emotion/styled';
|
|
12
12
|
import { ArrowDropDownRounded } from '@ndla/icons/common';
|
|
@@ -20,7 +20,7 @@ import { CommonFolderItemsProps } from './types';
|
|
|
20
20
|
import { arrowNavigation } from './arrowNavigation';
|
|
21
21
|
import { treestructureId } from './helperFunctions';
|
|
22
22
|
|
|
23
|
-
const OpenButton = styled.span
|
|
23
|
+
const OpenButton = styled.span`
|
|
24
24
|
display: flex;
|
|
25
25
|
align-items: center;
|
|
26
26
|
justify-content: center;
|
|
@@ -34,7 +34,12 @@ const OpenButton = styled.span<{ isOpen: boolean }>`
|
|
|
34
34
|
svg {
|
|
35
35
|
width: 24px;
|
|
36
36
|
height: 24px;
|
|
37
|
-
transform: rotate(
|
|
37
|
+
transform: rotate(-90deg);
|
|
38
|
+
}
|
|
39
|
+
&[data-open='true'] {
|
|
40
|
+
svg {
|
|
41
|
+
transform: rotate(0deg);
|
|
42
|
+
}
|
|
38
43
|
}
|
|
39
44
|
`;
|
|
40
45
|
|
|
@@ -59,55 +64,67 @@ const FolderIconWrapper = styled.div`
|
|
|
59
64
|
|
|
60
65
|
const shouldForwardProp = (name: string) => !['selected', 'level', 'focused', 'isCreatingFolder'].includes(name);
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
selected?: boolean;
|
|
64
|
-
level: number;
|
|
65
|
-
isCreatingFolder?: boolean;
|
|
66
|
-
focused?: boolean;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const FolderName = styled(Button, { shouldForwardProp })<FolderNameProps>`
|
|
67
|
+
const FolderName = styled(Button)`
|
|
70
68
|
display: grid;
|
|
71
69
|
grid-template-columns: auto 1fr auto;
|
|
72
|
-
padding-left:
|
|
70
|
+
padding-left: calc(0.75 * ${spacing.normal} * var(--level));
|
|
73
71
|
gap: ${spacing.xxsmall};
|
|
74
72
|
border: none;
|
|
75
73
|
outline: none;
|
|
76
|
-
|
|
77
|
-
isCreatingFolder ? 'none' : selected ? colors.brand.lighter : focused && colors.brand.lightest};
|
|
78
|
-
color: ${({ isCreatingFolder, focused }) =>
|
|
79
|
-
isCreatingFolder && focused ? colors.brand.primary : colors.text.primary};
|
|
74
|
+
color: ${colors.text.primary};
|
|
80
75
|
transition: ${animations.durations.superFast};
|
|
81
76
|
word-break: break-word;
|
|
82
77
|
|
|
83
78
|
&:hover {
|
|
84
79
|
box-shadow: none;
|
|
85
80
|
outline: none;
|
|
86
|
-
background: ${
|
|
81
|
+
background: ${colors.brand.lightest};
|
|
87
82
|
color: ${colors.text.primary};
|
|
88
83
|
}
|
|
84
|
+
|
|
85
|
+
&[data-focused='true'] {
|
|
86
|
+
background: ${colors.brand.lightest};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&[data-selected='true'] {
|
|
90
|
+
background: ${colors.brand.lighter};
|
|
91
|
+
&:hover {
|
|
92
|
+
background: ${colors.brand.light};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&[data-creating='true'][data-focused='true'] {
|
|
97
|
+
color: ${colors.brand.primary};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&[data-creating='true'] {
|
|
101
|
+
background: none;
|
|
102
|
+
}
|
|
89
103
|
`;
|
|
90
104
|
|
|
91
105
|
const StyledDone = styled(Done)`
|
|
92
106
|
color: ${colors.support.green};
|
|
93
107
|
`;
|
|
94
108
|
|
|
95
|
-
const FolderNameLink = styled(SafeLink, { shouldForwardProp })
|
|
109
|
+
const FolderNameLink = styled(SafeLink, { shouldForwardProp })`
|
|
96
110
|
display: grid;
|
|
97
111
|
align-items: center;
|
|
98
112
|
grid-template-columns: ${spacing.medium} 1fr auto;
|
|
99
113
|
padding: ${spacing.small} ${spacing.xxsmall};
|
|
100
|
-
|
|
114
|
+
padding-left: calc(0.75 * ${spacing.normal} * var(--level));
|
|
101
115
|
gap: ${spacing.xxsmall};
|
|
102
116
|
cursor: pointer;
|
|
103
117
|
|
|
104
118
|
border: none;
|
|
105
119
|
box-shadow: none;
|
|
106
|
-
color: ${
|
|
107
|
-
font-weight: ${({ selected }) => selected && fonts.weight.semibold};
|
|
120
|
+
color: ${colors.text.primary};
|
|
108
121
|
font-size: ${fonts.sizes('16px')};
|
|
109
122
|
transition: ${animations.durations.superFast};
|
|
110
123
|
word-break: break-word;
|
|
124
|
+
&[data-selected='true'] {
|
|
125
|
+
color: ${colors.brand.primary};
|
|
126
|
+
font-weight: ${fonts.weight.semibold};
|
|
127
|
+
}
|
|
111
128
|
&:hover,
|
|
112
129
|
&:focus {
|
|
113
130
|
color: ${colors.brand.primary};
|
|
@@ -145,6 +162,8 @@ const FolderItem = ({
|
|
|
145
162
|
const ref = useRef<HTMLButtonElement & HTMLAnchorElement>(null);
|
|
146
163
|
const selected = selectedFolder ? selectedFolder.id === id : false;
|
|
147
164
|
|
|
165
|
+
const levelVariable = useMemo(() => ({ '--level': level } as unknown as CSSProperties), [level]);
|
|
166
|
+
|
|
148
167
|
const focused = focusedFolder?.id === id;
|
|
149
168
|
|
|
150
169
|
const handleClickFolder = () => {
|
|
@@ -195,7 +214,7 @@ const FolderItem = ({
|
|
|
195
214
|
aria-current={selected ? 'page' : undefined}
|
|
196
215
|
aria-describedby={containsResource ? `alreadyAdded-${folder.id}` : undefined}
|
|
197
216
|
ref={ref}
|
|
198
|
-
|
|
217
|
+
style={levelVariable}
|
|
199
218
|
onKeyDown={(e: KeyboardEvent<HTMLElement>) => {
|
|
200
219
|
if (e.key === 'Enter') {
|
|
201
220
|
setSelectedFolder(folder);
|
|
@@ -205,7 +224,7 @@ const FolderItem = ({
|
|
|
205
224
|
}}
|
|
206
225
|
to={loading ? '' : linkPath}
|
|
207
226
|
tabIndex={tabable ? 0 : -1}
|
|
208
|
-
selected={selected}
|
|
227
|
+
data-selected={selected}
|
|
209
228
|
onFocus={() => setFocusedFolder(folder)}
|
|
210
229
|
onClick={handleClickFolder}
|
|
211
230
|
>
|
|
@@ -213,7 +232,7 @@ const FolderItem = ({
|
|
|
213
232
|
<OpenButton
|
|
214
233
|
aria-hidden
|
|
215
234
|
tabIndex={-1}
|
|
216
|
-
|
|
235
|
+
data-open={isOpen}
|
|
217
236
|
onClick={(e) => {
|
|
218
237
|
e.stopPropagation();
|
|
219
238
|
e.preventDefault();
|
|
@@ -237,7 +256,7 @@ const FolderItem = ({
|
|
|
237
256
|
id={treestructureId(type, folder.id)}
|
|
238
257
|
aria-expanded={isMaxDepth || emptyFolder ? undefined : isOpen}
|
|
239
258
|
aria-selected={selected}
|
|
240
|
-
focused={focusedFolder?.id === folder.id}
|
|
259
|
+
data-focused={focusedFolder?.id === folder.id}
|
|
241
260
|
aria-describedby={containsResource ? `alreadyAdded-${folder.id}` : undefined}
|
|
242
261
|
aria-label={`${name}${folder.status === 'shared' ? `, ${t('myNdla.folder.sharing.shared')}` : ''}`}
|
|
243
262
|
variant="ghost"
|
|
@@ -245,21 +264,19 @@ const FolderItem = ({
|
|
|
245
264
|
fontWeight="normal"
|
|
246
265
|
colorTheme="light"
|
|
247
266
|
ref={ref}
|
|
248
|
-
|
|
249
|
-
selected={selected}
|
|
267
|
+
style={levelVariable}
|
|
268
|
+
data-selected={selected}
|
|
250
269
|
disabled={loading}
|
|
251
|
-
onFocus={(
|
|
252
|
-
setFocusedFolder(focusedFolder || folder);
|
|
253
|
-
}}
|
|
270
|
+
onFocus={() => setFocusedFolder(focusedFolder || folder)}
|
|
254
271
|
onClick={handleClickFolder}
|
|
255
|
-
|
|
272
|
+
data-creating={isCreatingFolder}
|
|
256
273
|
>
|
|
257
274
|
<IconWrapper>
|
|
258
275
|
{!hideArrow && (
|
|
259
276
|
<OpenButton
|
|
260
277
|
aria-hidden
|
|
261
278
|
tabIndex={-1}
|
|
262
|
-
|
|
279
|
+
data-open={isOpen}
|
|
263
280
|
onClick={(e) => {
|
|
264
281
|
e.stopPropagation();
|
|
265
282
|
setFocusedFolder(folder);
|
|
@@ -11,7 +11,7 @@ import styled from '@emotion/styled';
|
|
|
11
11
|
import { animations } from '@ndla/core';
|
|
12
12
|
import { IFolder } from '@ndla/types-backend/learningpath-api';
|
|
13
13
|
import FolderItem from './FolderItem';
|
|
14
|
-
import { CommonFolderItemsProps, NewFolderInputFunc, OnCreatedFunc
|
|
14
|
+
import { CommonFolderItemsProps, NewFolderInputFunc, OnCreatedFunc } from './types';
|
|
15
15
|
import { treestructureId } from './helperFunctions';
|
|
16
16
|
|
|
17
17
|
const StyledUL = styled.ul`
|
|
@@ -25,16 +25,14 @@ const StyledUL = styled.ul`
|
|
|
25
25
|
padding: 0;
|
|
26
26
|
`;
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
type?: TreeStructureType;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const StyledLI = styled.li<StyledLiProps>`
|
|
28
|
+
const StyledLI = styled.li`
|
|
33
29
|
display: flex;
|
|
34
30
|
flex-direction: column;
|
|
35
|
-
align-items: ${({ type }) => type === 'navigation' && 'flex-start'};
|
|
36
31
|
margin: 0;
|
|
37
32
|
padding: 0;
|
|
33
|
+
&[data-type='navigation'] {
|
|
34
|
+
align-items: flex-start;
|
|
35
|
+
}
|
|
38
36
|
`;
|
|
39
37
|
|
|
40
38
|
export interface FolderItemsProps extends CommonFolderItemsProps {
|
|
@@ -80,7 +78,7 @@ const FolderItems = ({
|
|
|
80
78
|
const isOpen = openFolders?.includes(id);
|
|
81
79
|
|
|
82
80
|
return (
|
|
83
|
-
<StyledLI key={id} tabIndex={-1} role="none" type={type}>
|
|
81
|
+
<StyledLI key={id} tabIndex={-1} role="none" data-type={type}>
|
|
84
82
|
<FolderItem
|
|
85
83
|
index={index}
|
|
86
84
|
folder={folder}
|
|
@@ -9,12 +9,11 @@
|
|
|
9
9
|
import React, { useEffect, useState, useMemo, useRef } from 'react';
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
11
|
import { colors, fonts, misc, utils } from '@ndla/core';
|
|
12
|
-
import { css } from '@emotion/react';
|
|
13
12
|
import uniq from 'lodash/uniq';
|
|
14
13
|
import { IFolder } from '@ndla/types-backend/learningpath-api';
|
|
15
14
|
import FolderItems from './FolderItems';
|
|
16
15
|
import { flattenFolders, treestructureId } from './helperFunctions';
|
|
17
|
-
import { CommonTreeStructureProps, NewFolderInputFunc
|
|
16
|
+
import { CommonTreeStructureProps, NewFolderInputFunc } from './types';
|
|
18
17
|
import ComboboxButton from './ComboboxButton';
|
|
19
18
|
import AddFolderButton from './AddFolderButton';
|
|
20
19
|
|
|
@@ -36,35 +35,27 @@ const Row = styled.div`
|
|
|
36
35
|
justify-content: space-between;
|
|
37
36
|
`;
|
|
38
37
|
|
|
39
|
-
const TreeStructureWrapper = styled.div
|
|
38
|
+
const TreeStructureWrapper = styled.div`
|
|
40
39
|
display: flex;
|
|
41
40
|
flex-direction: column;
|
|
42
|
-
${({ type }) =>
|
|
43
|
-
type === 'picker' &&
|
|
44
|
-
css`
|
|
45
|
-
overflow: hidden;
|
|
46
|
-
border: 1px solid ${colors.brand.neutral7};
|
|
47
|
-
border-radius: ${misc.borderRadius};
|
|
48
|
-
scroll-behavior: smooth;
|
|
49
|
-
`}
|
|
50
41
|
transition: ${misc.transition.default};
|
|
42
|
+
&[data-type='picker'] {
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
border: 1px solid ${colors.brand.neutral7};
|
|
45
|
+
border-radius: ${misc.borderRadius};
|
|
46
|
+
scroll-behavior: smooth;
|
|
47
|
+
}
|
|
51
48
|
&:focus-within {
|
|
52
49
|
border-color: ${colors.brand.tertiary};
|
|
53
50
|
}
|
|
54
51
|
`;
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
type
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
type === 'picker' &&
|
|
63
|
-
css`
|
|
64
|
-
overflow: auto;
|
|
65
|
-
overflow: overlay;
|
|
66
|
-
${utils.scrollbar}
|
|
67
|
-
`}
|
|
53
|
+
const ScrollableDiv = styled.div`
|
|
54
|
+
&[data-type='picker'] {
|
|
55
|
+
overflow: auto;
|
|
56
|
+
overflow: overlay;
|
|
57
|
+
${utils.scrollbar}
|
|
58
|
+
}
|
|
68
59
|
`;
|
|
69
60
|
|
|
70
61
|
export interface TreeStructureProps extends CommonTreeStructureProps {
|
|
@@ -198,7 +189,7 @@ const TreeStructure = ({
|
|
|
198
189
|
/>
|
|
199
190
|
)}
|
|
200
191
|
</Row>
|
|
201
|
-
<TreeStructureWrapper aria-label={label} type={type}>
|
|
192
|
+
<TreeStructureWrapper aria-label={label} data-type={type}>
|
|
202
193
|
{type === 'picker' && (
|
|
203
194
|
<ComboboxButton
|
|
204
195
|
ref={ref}
|
|
@@ -218,7 +209,7 @@ const TreeStructure = ({
|
|
|
218
209
|
/>
|
|
219
210
|
)}
|
|
220
211
|
{showTree && (
|
|
221
|
-
<ScrollableDiv type={type}>
|
|
212
|
+
<ScrollableDiv data-type={type}>
|
|
222
213
|
<FolderItems
|
|
223
214
|
focusedFolder={focusedFolder}
|
|
224
215
|
folders={folders}
|