@ndla/ui 18.0.0 → 18.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/Masthead/MastheadAuthModal.js +8 -3
- package/es/MyNdla/Resource/Folder.js +7 -7
- package/es/Resource/resourceComponents.js +8 -8
- package/es/TreeStructure/FolderItems.js +3 -3
- package/es/TreeStructure/TreeStructure.js +51 -73
- package/es/TreeStructure/keyboardNavigation/keyboardNavigation.js +23 -11
- package/es/locale/messages-en.js +1 -0
- package/es/locale/messages-nb.js +1 -0
- package/es/locale/messages-nn.js +1 -0
- package/es/locale/messages-se.js +1 -0
- package/es/locale/messages-sma.js +1 -0
- package/lib/Masthead/MastheadAuthModal.js +14 -7
- package/lib/MyNdla/Resource/Folder.js +7 -7
- package/lib/Resource/resourceComponents.js +8 -8
- package/lib/TreeStructure/FolderItems.js +3 -3
- package/lib/TreeStructure/TreeStructure.js +52 -73
- package/lib/TreeStructure/TreeStructure.types.d.ts +2 -2
- package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.js +23 -11
- package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.d.ts +1 -1
- package/lib/locale/messages-en.d.ts +1 -0
- package/lib/locale/messages-en.js +1 -0
- package/lib/locale/messages-nb.d.ts +1 -0
- package/lib/locale/messages-nb.js +1 -0
- package/lib/locale/messages-nn.d.ts +1 -0
- package/lib/locale/messages-nn.js +1 -0
- package/lib/locale/messages-se.d.ts +1 -0
- package/lib/locale/messages-se.js +1 -0
- package/lib/locale/messages-sma.d.ts +1 -0
- package/lib/locale/messages-sma.js +1 -0
- package/package.json +2 -2
- package/src/Masthead/MastheadAuthModal.tsx +9 -0
- package/src/MyNdla/Resource/Folder.tsx +1 -1
- package/src/Resource/resourceComponents.tsx +3 -0
- package/src/TreeStructure/FolderItems.tsx +1 -1
- package/src/TreeStructure/TreeStructure.tsx +33 -35
- package/src/TreeStructure/TreeStructure.types.ts +2 -2
- package/src/TreeStructure/keyboardNavigation/keyboardNavigation.ts +7 -7
- package/src/TreeStructure/keyboardNavigation/keyboardNavigation.types.ts +1 -1
- package/src/locale/messages-en.ts +1 -0
- package/src/locale/messages-nb.ts +1 -0
- package/src/locale/messages-nn.ts +1 -0
- package/src/locale/messages-se.ts +1 -0
- package/src/locale/messages-sma.ts +1 -0
|
@@ -13,6 +13,7 @@ import Tooltip from '@ndla/tooltip';
|
|
|
13
13
|
import { useTranslation } from 'react-i18next';
|
|
14
14
|
import styled from '@emotion/styled';
|
|
15
15
|
import { spacing, fonts } from '@ndla/core';
|
|
16
|
+
import { uniq } from 'lodash';
|
|
16
17
|
import TreeStructureStyledWrapper from './TreeStructureWrapper';
|
|
17
18
|
import FolderItems from './FolderItems';
|
|
18
19
|
import { getIdPathsOfFolder, getPathOfFolder, getFolderName } from './helperFunctions';
|
|
@@ -44,18 +45,19 @@ const TreeStructure = ({
|
|
|
44
45
|
}: TreeStructureProps) => {
|
|
45
46
|
const { t } = useTranslation();
|
|
46
47
|
const [newFolder, setNewFolder] = useState<NewFolderProps | undefined>();
|
|
47
|
-
const [openFolders, setOpenFolders] = useState<
|
|
48
|
+
const [openFolders, setOpenFolders] = useState<string[]>(defaultOpenFolders || []);
|
|
48
49
|
const [focusedFolderId, setFocusedFolderId] = useState<string | undefined>();
|
|
49
|
-
const [markedFolderId, setMarkedFolderId] = useState<string | undefined>(folderIdMarkedByDefault || data[0]
|
|
50
|
+
const [markedFolderId, setMarkedFolderId] = useState<string | undefined>(folderIdMarkedByDefault || data[0]?.id);
|
|
50
51
|
const treestructureRef = useRef<HTMLDivElement>(null);
|
|
51
52
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
52
53
|
const rootLevelId = useMemo(() => uuid(), []); // TODO: use useId hook when we update to React 18
|
|
53
54
|
|
|
54
55
|
useEffect(() => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
if (defaultOpenFolders) {
|
|
57
|
+
setOpenFolders((prev) => {
|
|
58
|
+
return uniq([...defaultOpenFolders, ...prev]);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
59
61
|
}, [defaultOpenFolders]);
|
|
60
62
|
|
|
61
63
|
useEffect(() => {
|
|
@@ -65,48 +67,44 @@ const TreeStructure = ({
|
|
|
65
67
|
}, [loading]);
|
|
66
68
|
|
|
67
69
|
const onToggleOpen = (id: string) => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
);
|
|
79
|
-
if (markedFolderIsSubPath) {
|
|
80
|
-
setMarkedFolderId(closingFolderPath[closingFolderPath.length - 1]);
|
|
81
|
-
}
|
|
70
|
+
if (openFolders.includes(id)) {
|
|
71
|
+
// Did we just closed a folder with a marked folder inside it?
|
|
72
|
+
// If so, we need to mark the folder we just closed.
|
|
73
|
+
if (markedFolderId) {
|
|
74
|
+
const closingFolderPath = getPathOfFolder(data, id);
|
|
75
|
+
const markedFolderPath = getPathOfFolder(data, markedFolderId);
|
|
76
|
+
const markedFolderIsSubPath = closingFolderPath.every(
|
|
77
|
+
(folderId, _index) => markedFolderPath[_index] === folderId,
|
|
78
|
+
);
|
|
79
|
+
if (markedFolderIsSubPath) {
|
|
80
|
+
setMarkedFolderId(closingFolderPath[closingFolderPath.length - 1]);
|
|
82
81
|
}
|
|
83
|
-
} else {
|
|
84
|
-
prev.add(id);
|
|
85
82
|
}
|
|
86
|
-
|
|
87
|
-
}
|
|
83
|
+
setOpenFolders(openFolders.filter((folder) => folder !== id));
|
|
84
|
+
} else {
|
|
85
|
+
setOpenFolders(uniq([...openFolders, id]));
|
|
86
|
+
}
|
|
88
87
|
};
|
|
89
88
|
|
|
90
89
|
const onCreateNewFolder = (props: { idPaths: number[]; parentId?: string }) => {
|
|
91
90
|
setNewFolder(props);
|
|
92
91
|
};
|
|
93
92
|
|
|
94
|
-
const onSaveNewFolder =
|
|
93
|
+
const onSaveNewFolder = (value: string) => {
|
|
95
94
|
if (newFolder) {
|
|
96
95
|
// We would like to create a new folder with the name of value.
|
|
97
96
|
// Its location in structure is based on newFolder object
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
onNewFolder({ ...newFolder, value }).then((newFolderId) => {
|
|
98
|
+
if (newFolderId) {
|
|
99
|
+
setMarkedFolderId(newFolderId);
|
|
100
|
+
setFocusedFolderId(newFolderId);
|
|
101
|
+
// Open current folder in case it was closed..
|
|
102
|
+
|
|
104
103
|
if (newFolder.parentId) {
|
|
105
|
-
|
|
104
|
+
setOpenFolders(uniq([...openFolders, newFolder.parentId]));
|
|
106
105
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
110
108
|
}
|
|
111
109
|
};
|
|
112
110
|
|
|
@@ -49,7 +49,7 @@ export type onCreateNewFolderProp = ({
|
|
|
49
49
|
parentId: string | undefined;
|
|
50
50
|
}) => void;
|
|
51
51
|
|
|
52
|
-
export type SetOpenFolderProp = React.Dispatch<React.SetStateAction<
|
|
52
|
+
export type SetOpenFolderProp = React.Dispatch<React.SetStateAction<string[]>>;
|
|
53
53
|
export type SetFocusedFolderId = React.Dispatch<React.SetStateAction<string | undefined>>;
|
|
54
54
|
|
|
55
55
|
export type FolderChildFuncType = (id: string, tabIndex: number) => ReactNode;
|
|
@@ -60,7 +60,7 @@ export interface FolderItemsProps extends CommonFolderProps {
|
|
|
60
60
|
onCancelNewFolder: () => void;
|
|
61
61
|
onCreateNewFolder: onCreateNewFolderProp;
|
|
62
62
|
newFolder: NewFolderProps | undefined;
|
|
63
|
-
openFolders:
|
|
63
|
+
openFolders: string[];
|
|
64
64
|
markedFolderId?: string;
|
|
65
65
|
onMarkFolder: (id: string) => void;
|
|
66
66
|
idPaths: number[];
|
|
@@ -66,7 +66,7 @@ const keyboardNavigation = ({
|
|
|
66
66
|
if (dataId === id) {
|
|
67
67
|
elementWithKeyFocus.paths = paths;
|
|
68
68
|
elementWithKeyFocus.index = _index;
|
|
69
|
-
elementWithKeyFocus.isOpen = openFolders.
|
|
69
|
+
elementWithKeyFocus.isOpen = openFolders.includes(dataId) && childData && childData.length > 0;
|
|
70
70
|
elementWithKeyFocus.data = childData;
|
|
71
71
|
elementWithKeyFocus.parent = parent;
|
|
72
72
|
elementWithKeyFocus.parentId = parentId;
|
|
@@ -78,7 +78,7 @@ const keyboardNavigation = ({
|
|
|
78
78
|
if (!updatePathToElementWithKeyFocus(data, [], data)) {
|
|
79
79
|
// Couldn't find its location in the tree.
|
|
80
80
|
// This should not happen, reset its value to root.
|
|
81
|
-
setFocusedFolderId(e.key === 'ArrowDown' ? data[0]
|
|
81
|
+
setFocusedFolderId(e.key === 'ArrowDown' ? data[0]?.id : undefined);
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
84
|
e.preventDefault();
|
|
@@ -113,7 +113,7 @@ const keyboardNavigation = ({
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
if (!id && e.key === 'ArrowDown') {
|
|
116
|
-
setFocusedFolderId(data[0]
|
|
116
|
+
setFocusedFolderId(data[0]?.id);
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
if (!id) {
|
|
@@ -124,7 +124,7 @@ const keyboardNavigation = ({
|
|
|
124
124
|
if (elementWithKeyFocus.index > 0) {
|
|
125
125
|
// Move upwards to the parent folder
|
|
126
126
|
setFocusedFolderId(
|
|
127
|
-
elementWithKeyFocus.parent ? elementWithKeyFocus.parent[elementWithKeyFocus.index - 1]
|
|
127
|
+
elementWithKeyFocus.parent ? elementWithKeyFocus.parent[elementWithKeyFocus.index - 1]?.id : undefined,
|
|
128
128
|
);
|
|
129
129
|
} else if (elementWithKeyFocus.paths.length > 0) {
|
|
130
130
|
elementWithKeyFocus.paths.pop();
|
|
@@ -133,14 +133,14 @@ const keyboardNavigation = ({
|
|
|
133
133
|
findParent = findParent[index].data as FolderStructureProps[];
|
|
134
134
|
});
|
|
135
135
|
const parentsCurrentIndex = findParent.findIndex(({ id }) => id === elementWithKeyFocus.parentId);
|
|
136
|
-
setFocusedFolderId(findParent[parentsCurrentIndex]
|
|
136
|
+
setFocusedFolderId(findParent[parentsCurrentIndex]?.id);
|
|
137
137
|
}
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
if (elementWithKeyFocus.isOpen) {
|
|
142
142
|
if (elementWithKeyFocus.data?.length) {
|
|
143
|
-
setFocusedFolderId(elementWithKeyFocus.data[0]
|
|
143
|
+
setFocusedFolderId(elementWithKeyFocus.data[0]?.id);
|
|
144
144
|
} else {
|
|
145
145
|
// move to next child of parent if any... need new traverse :-/
|
|
146
146
|
traverseUpwards(data, setFocusedFolderId, elementWithKeyFocus.paths, elementWithKeyFocus.index);
|
|
@@ -150,7 +150,7 @@ const keyboardNavigation = ({
|
|
|
150
150
|
|
|
151
151
|
if (elementWithKeyFocus.parent && elementWithKeyFocus.index < elementWithKeyFocus.parent?.length - 1) {
|
|
152
152
|
// Move downwards to the next child
|
|
153
|
-
setFocusedFolderId(elementWithKeyFocus.parent[elementWithKeyFocus.index + 1]
|
|
153
|
+
setFocusedFolderId(elementWithKeyFocus.parent[elementWithKeyFocus.index + 1]?.id);
|
|
154
154
|
return;
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -12,7 +12,7 @@ export interface KeyboardNavigationProps {
|
|
|
12
12
|
e: React.KeyboardEvent<HTMLElement>;
|
|
13
13
|
data: FolderStructureProps[];
|
|
14
14
|
setFocusedFolderId: SetFocusedFolderId;
|
|
15
|
-
openFolders:
|
|
15
|
+
openFolders: string[];
|
|
16
16
|
onToggleOpen: (id: string) => void;
|
|
17
17
|
focusedFolderId: string | undefined;
|
|
18
18
|
}
|