@ndla/ui 27.1.7 → 29.0.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.
- package/es/Frontpage/FrontpageAllSubjects.js +9 -8
- package/es/Resource/BlockResource.js +22 -13
- package/es/Resource/ListResource.js +24 -15
- package/es/Resource/resourceComponents.js +28 -28
- package/es/TagSelector/Control.js +23 -0
- package/es/TagSelector/DropdownIndicator.js +66 -0
- package/es/TagSelector/Input.js +19 -0
- package/es/TagSelector/Menu.js +26 -0
- package/es/TagSelector/MenuList.js +22 -0
- package/es/TagSelector/Option.js +55 -0
- package/es/TagSelector/SelectContainer.js +18 -0
- package/es/TagSelector/TagSelector.js +161 -100
- package/es/TagSelector/ValueButton.js +46 -0
- package/es/TagSelector/ariaMessages.js +104 -0
- package/es/TagSelector/index.js +2 -1
- package/es/TagSelector/types.js +0 -0
- package/es/TreeStructure/ComboboxButton.js +19 -18
- package/es/TreeStructure/TreeStructure.js +8 -8
- package/es/locale/messages-en.js +46 -8
- package/es/locale/messages-nb.js +57 -19
- package/es/locale/messages-nn.js +56 -18
- package/es/locale/messages-se.js +48 -10
- package/es/locale/messages-sma.js +57 -19
- package/es/model/ContentType.js +23 -1
- package/es/model/SubjectCategories.js +1 -5
- package/es/model/index.js +3 -2
- package/lib/Frontpage/FrontpageAllSubjects.js +10 -8
- package/lib/Resource/BlockResource.d.ts +6 -3
- package/lib/Resource/BlockResource.js +23 -12
- package/lib/Resource/ListResource.d.ts +6 -3
- package/lib/Resource/ListResource.js +25 -14
- package/lib/Resource/resourceComponents.d.ts +6 -3
- package/lib/Resource/resourceComponents.js +30 -30
- package/lib/TagSelector/Control.d.ts +12 -0
- package/lib/TagSelector/Control.js +35 -0
- package/lib/TagSelector/DropdownIndicator.d.ts +12 -0
- package/lib/TagSelector/DropdownIndicator.js +80 -0
- package/lib/TagSelector/Input.d.ts +12 -0
- package/lib/TagSelector/Input.js +33 -0
- package/lib/TagSelector/Menu.d.ts +12 -0
- package/lib/TagSelector/Menu.js +40 -0
- package/lib/TagSelector/MenuList.d.ts +13 -0
- package/lib/TagSelector/MenuList.js +36 -0
- package/lib/TagSelector/Option.d.ts +12 -0
- package/lib/TagSelector/Option.js +61 -0
- package/lib/TagSelector/SelectContainer.d.ts +12 -0
- package/lib/TagSelector/SelectContainer.js +31 -0
- package/lib/TagSelector/TagSelector.d.ts +14 -11
- package/lib/TagSelector/TagSelector.js +165 -96
- package/lib/TagSelector/ValueButton.d.ts +16 -0
- package/lib/TagSelector/ValueButton.js +55 -0
- package/lib/TagSelector/ariaMessages.d.ts +16 -0
- package/lib/TagSelector/ariaMessages.js +113 -0
- package/lib/TagSelector/index.d.ts +2 -1
- package/lib/TagSelector/index.js +3 -5
- package/lib/TagSelector/types.d.ts +11 -0
- package/lib/TagSelector/types.js +1 -0
- package/lib/TreeStructure/ComboboxButton.js +19 -18
- package/lib/TreeStructure/TreeStructure.js +7 -7
- package/lib/locale/messages-en.d.ts +56 -25
- package/lib/locale/messages-en.js +46 -8
- package/lib/locale/messages-nb.d.ts +56 -25
- package/lib/locale/messages-nb.js +57 -19
- package/lib/locale/messages-nn.d.ts +56 -25
- package/lib/locale/messages-nn.js +56 -18
- package/lib/locale/messages-se.d.ts +56 -25
- package/lib/locale/messages-se.js +48 -10
- package/lib/locale/messages-sma.d.ts +56 -25
- package/lib/locale/messages-sma.js +57 -19
- package/lib/model/ContentType.d.ts +18 -0
- package/lib/model/ContentType.js +32 -2
- package/lib/model/SubjectCategories.d.ts +0 -3
- package/lib/model/SubjectCategories.js +3 -10
- package/lib/model/index.d.ts +12 -2
- package/lib/model/index.js +4 -3
- package/package.json +15 -14
- package/src/Frontpage/FrontpageAllSubjects.tsx +5 -2
- package/src/Resource/BlockResource.tsx +18 -11
- package/src/Resource/ListResource.tsx +14 -11
- package/src/Resource/resourceComponents.tsx +13 -14
- package/src/TagSelector/Control.tsx +34 -0
- package/src/TagSelector/DropdownIndicator.tsx +47 -0
- package/src/TagSelector/Input.tsx +31 -0
- package/src/TagSelector/Menu.tsx +38 -0
- package/src/TagSelector/MenuList.tsx +30 -0
- package/src/TagSelector/Option.tsx +53 -0
- package/src/TagSelector/SelectContainer.tsx +32 -0
- package/src/TagSelector/TagSelector.tsx +105 -84
- package/src/TagSelector/ValueButton.tsx +46 -0
- package/src/TagSelector/ariaMessages.ts +87 -0
- package/src/TagSelector/index.ts +2 -1
- package/src/TagSelector/types.ts +12 -0
- package/src/TreeStructure/ComboboxButton.tsx +15 -17
- package/src/TreeStructure/TreeStructure.tsx +2 -11
- package/src/locale/messages-en.ts +46 -9
- package/src/locale/messages-nb.ts +57 -20
- package/src/locale/messages-nn.ts +56 -19
- package/src/locale/messages-se.ts +48 -11
- package/src/locale/messages-sma.ts +57 -20
- package/src/model/ContentType.ts +29 -0
- package/src/model/SubjectCategories.ts +0 -5
- package/src/model/index.ts +2 -1
- package/es/TagSelector/SuggestionInput.js +0 -285
- package/es/TagSelector/Suggestions.js +0 -97
- package/lib/TagSelector/SuggestionInput.d.ts +0 -19
- package/lib/TagSelector/SuggestionInput.js +0 -299
- package/lib/TagSelector/Suggestions.d.ts +0 -12
- package/lib/TagSelector/Suggestions.js +0 -99
- package/src/.DS_Store +0 -0
- package/src/TagSelector/SuggestionInput.tsx +0 -287
- package/src/TagSelector/Suggestions.tsx +0 -139
package/lib/model/ContentType.js
CHANGED
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.ListOfContentTypes = exports.MULTIDISCIPLINARY_TOPIC = exports.TOPIC = exports.LEARNING_PATH = exports.SOURCE_MATERIAL = exports.EXTERNAL_LEARNING_RESOURCES = exports.SUBJECT = exports.ASSESSMENT_RESOURCES = exports.TASKS_AND_ACTIVITIES = exports.SUBJECT_MATERIAL = void 0;
|
|
6
|
+
exports.contentTypeMapping = exports.ListOfContentTypes = exports.RESOURCE_TYPE_SOURCE_MATERIAL = exports.RESOURCE_TYPE_EXTERNAL_LEARNING_RESOURCES = exports.RESOURCE_TYPE_ASSESSMENT_RESOURCES = exports.RESOURCE_TYPE_TASKS_AND_ACTIVITIES = exports.RESOURCE_TYPE_SUBJECT_MATERIAL = exports.RESOURCE_TYPE_LEARNING_PATH = exports.contentTypes = exports.MULTIDISCIPLINARY_TOPIC = exports.TOPIC = exports.LEARNING_PATH = exports.SOURCE_MATERIAL = exports.EXTERNAL_LEARNING_RESOURCES = exports.SUBJECT = exports.ASSESSMENT_RESOURCES = exports.TASKS_AND_ACTIVITIES = exports.SUBJECT_MATERIAL = void 0;
|
|
7
|
+
|
|
8
|
+
var _contentTypeMapping;
|
|
9
|
+
|
|
10
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* Copyright (c) 2017-present, NDLA.
|
|
@@ -30,5 +34,31 @@ var TOPIC = 'topic';
|
|
|
30
34
|
exports.TOPIC = TOPIC;
|
|
31
35
|
var MULTIDISCIPLINARY_TOPIC = 'multidisciplinary-topic';
|
|
32
36
|
exports.MULTIDISCIPLINARY_TOPIC = MULTIDISCIPLINARY_TOPIC;
|
|
37
|
+
var contentTypes = {
|
|
38
|
+
SUBJECT_MATERIAL: SUBJECT_MATERIAL,
|
|
39
|
+
TASKS_AND_ACTIVITIES: TASKS_AND_ACTIVITIES,
|
|
40
|
+
ASSESSMENT_RESOURCES: ASSESSMENT_RESOURCES,
|
|
41
|
+
SUBJECT: SUBJECT,
|
|
42
|
+
EXTERNAL_LEARNING_RESOURCES: EXTERNAL_LEARNING_RESOURCES,
|
|
43
|
+
SOURCE_MATERIAL: SOURCE_MATERIAL,
|
|
44
|
+
LEARNING_PATH: LEARNING_PATH,
|
|
45
|
+
TOPIC: TOPIC,
|
|
46
|
+
MULTIDISCIPLINARY_TOPIC: MULTIDISCIPLINARY_TOPIC
|
|
47
|
+
};
|
|
48
|
+
exports.contentTypes = contentTypes;
|
|
49
|
+
var RESOURCE_TYPE_LEARNING_PATH = 'urn:resourcetype:learningPath';
|
|
50
|
+
exports.RESOURCE_TYPE_LEARNING_PATH = RESOURCE_TYPE_LEARNING_PATH;
|
|
51
|
+
var RESOURCE_TYPE_SUBJECT_MATERIAL = 'urn:resourcetype:subjectMaterial';
|
|
52
|
+
exports.RESOURCE_TYPE_SUBJECT_MATERIAL = RESOURCE_TYPE_SUBJECT_MATERIAL;
|
|
53
|
+
var RESOURCE_TYPE_TASKS_AND_ACTIVITIES = 'urn:resourcetype:tasksAndActivities';
|
|
54
|
+
exports.RESOURCE_TYPE_TASKS_AND_ACTIVITIES = RESOURCE_TYPE_TASKS_AND_ACTIVITIES;
|
|
55
|
+
var RESOURCE_TYPE_ASSESSMENT_RESOURCES = 'urn:resourcetype:reviewResource';
|
|
56
|
+
exports.RESOURCE_TYPE_ASSESSMENT_RESOURCES = RESOURCE_TYPE_ASSESSMENT_RESOURCES;
|
|
57
|
+
var RESOURCE_TYPE_EXTERNAL_LEARNING_RESOURCES = 'urn:resourcetype:externalResource';
|
|
58
|
+
exports.RESOURCE_TYPE_EXTERNAL_LEARNING_RESOURCES = RESOURCE_TYPE_EXTERNAL_LEARNING_RESOURCES;
|
|
59
|
+
var RESOURCE_TYPE_SOURCE_MATERIAL = 'urn:resourcetype:SourceMaterial';
|
|
60
|
+
exports.RESOURCE_TYPE_SOURCE_MATERIAL = RESOURCE_TYPE_SOURCE_MATERIAL;
|
|
33
61
|
var ListOfContentTypes = ['SUBJECT_MATERIAL', 'TASKS_AND_ACTIVITIES', 'ASSESSMENT_RESOURCES', 'SUBJECT', 'EXTERNAL_LEARNING_RESOURCES', 'SOURCE_MATERIAL', 'LEARNING_PATH', 'TOPIC', 'MULTIDISIPLINARY_TOPIC'];
|
|
34
|
-
exports.ListOfContentTypes = ListOfContentTypes;
|
|
62
|
+
exports.ListOfContentTypes = ListOfContentTypes;
|
|
63
|
+
var contentTypeMapping = (_contentTypeMapping = {}, _defineProperty(_contentTypeMapping, RESOURCE_TYPE_LEARNING_PATH, LEARNING_PATH), _defineProperty(_contentTypeMapping, RESOURCE_TYPE_SUBJECT_MATERIAL, SUBJECT_MATERIAL), _defineProperty(_contentTypeMapping, RESOURCE_TYPE_TASKS_AND_ACTIVITIES, TASKS_AND_ACTIVITIES), _defineProperty(_contentTypeMapping, RESOURCE_TYPE_ASSESSMENT_RESOURCES, ASSESSMENT_RESOURCES), _defineProperty(_contentTypeMapping, RESOURCE_TYPE_EXTERNAL_LEARNING_RESOURCES, EXTERNAL_LEARNING_RESOURCES), _defineProperty(_contentTypeMapping, RESOURCE_TYPE_SOURCE_MATERIAL, SOURCE_MATERIAL), _defineProperty(_contentTypeMapping, "default", SUBJECT_MATERIAL), _contentTypeMapping);
|
|
64
|
+
exports.contentTypeMapping = contentTypeMapping;
|
|
@@ -8,6 +8,3 @@
|
|
|
8
8
|
export declare const ACTIVE_SUBJECTS = "active";
|
|
9
9
|
export declare const BETA_SUBJECTS = "beta";
|
|
10
10
|
export declare const ARCHIVE_SUBJECTS = "archive";
|
|
11
|
-
export declare const COMMON_SUBJECTS = "common";
|
|
12
|
-
export declare const PROGRAMME_SUBJECTS = "programme";
|
|
13
|
-
export declare const SPECIALIZED_SUBJECTS = "specialized";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.ARCHIVE_SUBJECTS = exports.BETA_SUBJECTS = exports.ACTIVE_SUBJECTS = void 0;
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Copyright (c) 2021-present, NDLA.
|
|
@@ -16,12 +16,5 @@ var ACTIVE_SUBJECTS = 'active';
|
|
|
16
16
|
exports.ACTIVE_SUBJECTS = ACTIVE_SUBJECTS;
|
|
17
17
|
var BETA_SUBJECTS = 'beta';
|
|
18
18
|
exports.BETA_SUBJECTS = BETA_SUBJECTS;
|
|
19
|
-
var ARCHIVE_SUBJECTS = 'archive';
|
|
20
|
-
|
|
21
|
-
exports.ARCHIVE_SUBJECTS = ARCHIVE_SUBJECTS;
|
|
22
|
-
var COMMON_SUBJECTS = 'common';
|
|
23
|
-
exports.COMMON_SUBJECTS = COMMON_SUBJECTS;
|
|
24
|
-
var PROGRAMME_SUBJECTS = 'programme';
|
|
25
|
-
exports.PROGRAMME_SUBJECTS = PROGRAMME_SUBJECTS;
|
|
26
|
-
var SPECIALIZED_SUBJECTS = 'specialized';
|
|
27
|
-
exports.SPECIALIZED_SUBJECTS = SPECIALIZED_SUBJECTS;
|
|
19
|
+
var ARCHIVE_SUBJECTS = 'archive';
|
|
20
|
+
exports.ARCHIVE_SUBJECTS = ARCHIVE_SUBJECTS;
|
package/lib/model/index.d.ts
CHANGED
|
@@ -5,12 +5,22 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import * as contentTypes from './ContentType';
|
|
9
8
|
import * as subjectCategories from './SubjectCategories';
|
|
10
9
|
import * as subjectTypes from './SubjectTypes';
|
|
11
10
|
declare const model: {
|
|
12
|
-
contentTypes:
|
|
11
|
+
contentTypes: {
|
|
12
|
+
SUBJECT_MATERIAL: string;
|
|
13
|
+
TASKS_AND_ACTIVITIES: string;
|
|
14
|
+
ASSESSMENT_RESOURCES: string;
|
|
15
|
+
SUBJECT: string;
|
|
16
|
+
EXTERNAL_LEARNING_RESOURCES: string;
|
|
17
|
+
SOURCE_MATERIAL: string;
|
|
18
|
+
LEARNING_PATH: string;
|
|
19
|
+
TOPIC: string;
|
|
20
|
+
MULTIDISCIPLINARY_TOPIC: string;
|
|
21
|
+
};
|
|
13
22
|
subjectCategories: typeof subjectCategories;
|
|
14
23
|
subjectTypes: typeof subjectTypes;
|
|
24
|
+
contentTypeMapping: Record<string, string>;
|
|
15
25
|
};
|
|
16
26
|
export default model;
|
package/lib/model/index.js
CHANGED
|
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
});
|
|
8
8
|
exports["default"] = void 0;
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _ContentType = require("./ContentType");
|
|
11
11
|
|
|
12
12
|
var subjectCategories = _interopRequireWildcard(require("./SubjectCategories"));
|
|
13
13
|
|
|
@@ -25,9 +25,10 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
|
|
|
25
25
|
*
|
|
26
26
|
*/
|
|
27
27
|
var model = {
|
|
28
|
-
contentTypes: contentTypes,
|
|
28
|
+
contentTypes: _ContentType.contentTypes,
|
|
29
29
|
subjectCategories: subjectCategories,
|
|
30
|
-
subjectTypes: subjectTypes
|
|
30
|
+
subjectTypes: subjectTypes,
|
|
31
|
+
contentTypeMapping: _ContentType.contentTypeMapping
|
|
31
32
|
};
|
|
32
33
|
var _default = model;
|
|
33
34
|
exports["default"] = _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ndla/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "29.0.0",
|
|
4
4
|
"description": "UI component library for NDLA.",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -32,19 +32,19 @@
|
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@ndla/article-scripts": "^3.0.2",
|
|
35
|
-
"@ndla/button": "^3.
|
|
36
|
-
"@ndla/carousel": "^1.2.
|
|
37
|
-
"@ndla/core": "^2.3.
|
|
38
|
-
"@ndla/forms": "^3.3.
|
|
35
|
+
"@ndla/button": "^3.7.0",
|
|
36
|
+
"@ndla/carousel": "^1.2.24",
|
|
37
|
+
"@ndla/core": "^2.3.6",
|
|
38
|
+
"@ndla/forms": "^3.3.6",
|
|
39
39
|
"@ndla/hooks": "^1.1.6",
|
|
40
|
-
"@ndla/icons": "^1.
|
|
41
|
-
"@ndla/licenses": "^5.0.
|
|
42
|
-
"@ndla/modal": "^1.
|
|
43
|
-
"@ndla/notion": "^3.1.
|
|
44
|
-
"@ndla/safelink": "^2.2.
|
|
45
|
-
"@ndla/switch": "^0.1.
|
|
46
|
-
"@ndla/tabs": "^1.1.
|
|
47
|
-
"@ndla/tooltip": "^2.2.
|
|
40
|
+
"@ndla/icons": "^1.14.0",
|
|
41
|
+
"@ndla/licenses": "^5.0.18",
|
|
42
|
+
"@ndla/modal": "^1.6.1",
|
|
43
|
+
"@ndla/notion": "^3.1.48",
|
|
44
|
+
"@ndla/safelink": "^2.2.20",
|
|
45
|
+
"@ndla/switch": "^0.1.14",
|
|
46
|
+
"@ndla/tabs": "^1.1.23",
|
|
47
|
+
"@ndla/tooltip": "^2.2.2",
|
|
48
48
|
"@ndla/types-learningpath-api": "^0.0.13",
|
|
49
49
|
"@ndla/util": "^3.1.0",
|
|
50
50
|
"@reach/menu-button": "^0.16.2",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"lodash": "^4.17.20",
|
|
59
59
|
"react-bem-helper": "1.4.1",
|
|
60
60
|
"react-device-detect": "^2.1.2",
|
|
61
|
+
"react-select": "^5.4.0",
|
|
61
62
|
"react-swipeable": "^6.2.0",
|
|
62
63
|
"react-transition-group": "^2.5.3",
|
|
63
64
|
"remarkable": "^2.0.1",
|
|
@@ -85,5 +86,5 @@
|
|
|
85
86
|
"publishConfig": {
|
|
86
87
|
"access": "public"
|
|
87
88
|
},
|
|
88
|
-
"gitHead": "
|
|
89
|
+
"gitHead": "2c5d6b7038c442a871b4cd69247d243cadd129da"
|
|
89
90
|
}
|
|
@@ -6,6 +6,7 @@ import SafeLink from '@ndla/safelink';
|
|
|
6
6
|
import { colors, fonts, mq, breakpoints } from '@ndla/core';
|
|
7
7
|
import { MessageBox } from '../Messages';
|
|
8
8
|
import { ToggleItem } from '../Filter';
|
|
9
|
+
import constants from '../model';
|
|
9
10
|
|
|
10
11
|
const StyledWrapper = styled.nav`
|
|
11
12
|
margin: 32px 0 0;
|
|
@@ -198,12 +199,14 @@ const FrontpageAllSubjects = ({
|
|
|
198
199
|
content: (
|
|
199
200
|
<>
|
|
200
201
|
{/* Should be persistent til fall 2022 */}
|
|
201
|
-
{category.name === t('subjectCategories.beta')
|
|
202
|
+
{(category.name === t('subjectCategories.beta') ||
|
|
203
|
+
category.type === constants.subjectCategories.BETA_SUBJECTS) && (
|
|
202
204
|
<MessageBoxWrapper>
|
|
203
205
|
<MessageBox>{t('messageBoxInfo.frontPageBeta')}</MessageBox>
|
|
204
206
|
</MessageBoxWrapper>
|
|
205
207
|
)}
|
|
206
|
-
{category.name === t('subjectCategories.archive')
|
|
208
|
+
{(category.name === t('subjectCategories.archive') ||
|
|
209
|
+
category.type === constants.subjectCategories.ARCHIVE_SUBJECTS) && (
|
|
207
210
|
<MessageBoxWrapper>
|
|
208
211
|
<MessageBox>{t('messageBoxInfo.frontPageExpired')}</MessageBox>
|
|
209
212
|
</MessageBoxWrapper>
|
|
@@ -17,12 +17,13 @@ import {
|
|
|
17
17
|
ResourceImageProps,
|
|
18
18
|
ResourceTitle,
|
|
19
19
|
Row,
|
|
20
|
-
|
|
20
|
+
ResourceTypeList,
|
|
21
21
|
ResourceTitleLink,
|
|
22
22
|
LoaderProps,
|
|
23
23
|
StyledContentIconWrapper,
|
|
24
24
|
} from './resourceComponents';
|
|
25
25
|
import ContentLoader from '../ContentLoader';
|
|
26
|
+
import { contentTypeMapping } from '../model/ContentType';
|
|
26
27
|
|
|
27
28
|
interface BlockResourceProps {
|
|
28
29
|
id: string;
|
|
@@ -30,13 +31,13 @@ interface BlockResourceProps {
|
|
|
30
31
|
tagLinkPrefix?: string;
|
|
31
32
|
title: string;
|
|
32
33
|
resourceImage: ResourceImageProps;
|
|
33
|
-
topics: string[];
|
|
34
34
|
tags?: string[];
|
|
35
35
|
description?: string;
|
|
36
|
+
headingLevel?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
36
37
|
menuItems?: MenuItemProps[];
|
|
37
38
|
isLoading?: boolean;
|
|
38
39
|
targetBlank?: boolean;
|
|
39
|
-
|
|
40
|
+
resourceTypes?: { id: string; name: string }[];
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
const BlockElementWrapper = styled.div`
|
|
@@ -128,7 +129,7 @@ const BlockImage = ({ image, loading, contentType }: BlockImageProps) => {
|
|
|
128
129
|
}
|
|
129
130
|
};
|
|
130
131
|
|
|
131
|
-
const
|
|
132
|
+
const ResourceTypeAndTitleLoader = ({ children, loading }: LoaderProps) => {
|
|
132
133
|
if (loading) {
|
|
133
134
|
return (
|
|
134
135
|
<ContentLoader height={'18px'} width={'100%'} viewBox={null} preserveAspectRatio="none">
|
|
@@ -148,14 +149,16 @@ const BlockResource = ({
|
|
|
148
149
|
title,
|
|
149
150
|
tags,
|
|
150
151
|
resourceImage,
|
|
151
|
-
topics,
|
|
152
152
|
description,
|
|
153
153
|
menuItems,
|
|
154
154
|
isLoading,
|
|
155
|
+
headingLevel = 'h2',
|
|
155
156
|
targetBlank,
|
|
156
|
-
|
|
157
|
+
resourceTypes,
|
|
157
158
|
}: BlockResourceProps) => {
|
|
158
159
|
const linkRef = useRef<HTMLAnchorElement>(null);
|
|
160
|
+
const firstResourceType = resourceTypes?.[0].id ?? '';
|
|
161
|
+
const Title = ResourceTitle.withComponent(headingLevel);
|
|
159
162
|
|
|
160
163
|
const handleClick = () => {
|
|
161
164
|
if (linkRef.current) {
|
|
@@ -166,15 +169,19 @@ const BlockResource = ({
|
|
|
166
169
|
return (
|
|
167
170
|
<BlockElementWrapper onClick={handleClick} id={id}>
|
|
168
171
|
<ImageWrapper>
|
|
169
|
-
<BlockImage
|
|
172
|
+
<BlockImage
|
|
173
|
+
image={resourceImage}
|
|
174
|
+
loading={isLoading}
|
|
175
|
+
contentType={contentTypeMapping[firstResourceType] ?? contentTypeMapping['default']}
|
|
176
|
+
/>
|
|
170
177
|
</ImageWrapper>
|
|
171
178
|
<BlockInfoWrapper>
|
|
172
|
-
<
|
|
179
|
+
<ResourceTypeAndTitleLoader loading={isLoading}>
|
|
173
180
|
<ResourceTitleLink title={title} target={targetBlank ? '_blank' : undefined} to={link} ref={linkRef}>
|
|
174
|
-
<
|
|
181
|
+
<Title>{title}</Title>
|
|
175
182
|
</ResourceTitleLink>
|
|
176
|
-
</
|
|
177
|
-
<
|
|
183
|
+
</ResourceTypeAndTitleLoader>
|
|
184
|
+
<ResourceTypeList resourceTypes={resourceTypes} />
|
|
178
185
|
<BlockDescription>{description}</BlockDescription>
|
|
179
186
|
<RightRow>
|
|
180
187
|
{tags && <CompressedTagList tagLinkPrefix={tagLinkPrefix} tags={tags} />}
|
|
@@ -16,12 +16,13 @@ import {
|
|
|
16
16
|
ResourceImageProps,
|
|
17
17
|
ResourceTitle,
|
|
18
18
|
ResourceTitleLink,
|
|
19
|
-
|
|
19
|
+
ResourceTypeList,
|
|
20
20
|
StyledContentIconWrapper,
|
|
21
21
|
LoaderProps,
|
|
22
22
|
} from './resourceComponents';
|
|
23
23
|
import ContentLoader from '../ContentLoader';
|
|
24
24
|
import ContentTypeBadge from '../ContentTypeBadge';
|
|
25
|
+
import { contentTypeMapping } from '../model/ContentType';
|
|
25
26
|
|
|
26
27
|
const StyledResourceDescription = styled.p`
|
|
27
28
|
grid-area: description;
|
|
@@ -124,13 +125,13 @@ export interface ListResourceProps {
|
|
|
124
125
|
tagLinkPrefix?: string;
|
|
125
126
|
title: string;
|
|
126
127
|
resourceImage: ResourceImageProps;
|
|
127
|
-
|
|
128
|
+
headingLevel?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
129
|
+
resourceTypes: { id: string; name: string }[];
|
|
128
130
|
tags?: string[];
|
|
129
131
|
description?: string;
|
|
130
132
|
menuItems?: MenuItemProps[];
|
|
131
133
|
isLoading?: boolean;
|
|
132
134
|
targetBlank?: boolean;
|
|
133
|
-
contentType: string;
|
|
134
135
|
}
|
|
135
136
|
|
|
136
137
|
interface ListResourceImageProps {
|
|
@@ -169,7 +170,7 @@ const ListResourceImage = ({ resourceImage, loading, type, contentType }: ListRe
|
|
|
169
170
|
);
|
|
170
171
|
};
|
|
171
172
|
|
|
172
|
-
const
|
|
173
|
+
const ResourceTypeAndTitleLoader = ({ loading, children }: LoaderProps) => {
|
|
173
174
|
if (loading) {
|
|
174
175
|
return (
|
|
175
176
|
<ContentLoader height={'40px'} width={'100%'} viewBox={null} preserveAspectRatio="none">
|
|
@@ -205,16 +206,18 @@ const ListResource = ({
|
|
|
205
206
|
title,
|
|
206
207
|
tags,
|
|
207
208
|
resourceImage,
|
|
208
|
-
|
|
209
|
+
resourceTypes,
|
|
210
|
+
headingLevel = 'h2',
|
|
209
211
|
description,
|
|
210
212
|
menuItems,
|
|
211
213
|
isLoading = false,
|
|
212
214
|
targetBlank,
|
|
213
|
-
contentType,
|
|
214
215
|
}: ListResourceProps) => {
|
|
215
216
|
const showDescription = description !== undefined;
|
|
216
217
|
const imageType = showDescription ? 'normal' : 'compact';
|
|
217
218
|
const linkRef = useRef<HTMLAnchorElement>(null);
|
|
219
|
+
const firstContentType = resourceTypes?.[0]?.id ?? '';
|
|
220
|
+
const Title = ResourceTitle.withComponent(headingLevel);
|
|
218
221
|
const handleClick = () => {
|
|
219
222
|
if (linkRef.current) {
|
|
220
223
|
linkRef.current.click();
|
|
@@ -228,16 +231,16 @@ const ListResource = ({
|
|
|
228
231
|
resourceImage={resourceImage}
|
|
229
232
|
loading={isLoading}
|
|
230
233
|
type={imageType}
|
|
231
|
-
contentType={
|
|
234
|
+
contentType={contentTypeMapping[firstContentType] ?? contentTypeMapping['default']}
|
|
232
235
|
/>
|
|
233
236
|
</StyledImageWrapper>
|
|
234
237
|
<TopicAndTitleWrapper>
|
|
235
|
-
<
|
|
238
|
+
<ResourceTypeAndTitleLoader loading={isLoading}>
|
|
236
239
|
<ResourceTitleLink to={link} target={targetBlank ? '_blank' : undefined} ref={linkRef}>
|
|
237
|
-
<
|
|
240
|
+
<Title>{title}</Title>
|
|
238
241
|
</ResourceTitleLink>
|
|
239
|
-
<
|
|
240
|
-
</
|
|
242
|
+
<ResourceTypeList resourceTypes={resourceTypes} />
|
|
243
|
+
</ResourceTypeAndTitleLoader>
|
|
241
244
|
</TopicAndTitleWrapper>
|
|
242
245
|
{showDescription && <ResourceDescription description={description} loading={isLoading} />}
|
|
243
246
|
<TagsandActionMenu>
|
|
@@ -65,13 +65,12 @@ const StyledSafeLink = styled(SafeLink)`
|
|
|
65
65
|
}
|
|
66
66
|
`;
|
|
67
67
|
|
|
68
|
-
const
|
|
68
|
+
const StyledResourceTypeList = styled.ul`
|
|
69
69
|
list-style: none;
|
|
70
70
|
display: flex;
|
|
71
71
|
margin: 0;
|
|
72
72
|
padding: 0;
|
|
73
73
|
overflow: hidden;
|
|
74
|
-
grid-area: topicList;
|
|
75
74
|
`;
|
|
76
75
|
|
|
77
76
|
const StyledTopicDivider = styled.span`
|
|
@@ -79,7 +78,7 @@ const StyledTopicDivider = styled.span`
|
|
|
79
78
|
padding: 0 ${spacing.xxsmall};
|
|
80
79
|
`;
|
|
81
80
|
|
|
82
|
-
const
|
|
81
|
+
const StyledResourceListElement = styled.li`
|
|
83
82
|
${fonts.sizes(12)};
|
|
84
83
|
margin: 0;
|
|
85
84
|
line-height: 1.5;
|
|
@@ -187,21 +186,21 @@ export const CompressedTagList = ({ tags, tagLinkPrefix }: CompressedTagListProp
|
|
|
187
186
|
);
|
|
188
187
|
};
|
|
189
188
|
|
|
190
|
-
interface
|
|
191
|
-
|
|
189
|
+
interface ResourceTypeListProps {
|
|
190
|
+
resourceTypes?: { id: string; name: string }[];
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
export const
|
|
193
|
+
export const ResourceTypeList = ({ resourceTypes }: ResourceTypeListProps) => {
|
|
195
194
|
const { t } = useTranslation();
|
|
196
|
-
if (!
|
|
195
|
+
if (!resourceTypes) return null;
|
|
197
196
|
return (
|
|
198
|
-
<
|
|
199
|
-
{
|
|
200
|
-
<
|
|
201
|
-
{
|
|
202
|
-
{i !==
|
|
203
|
-
</
|
|
197
|
+
<StyledResourceTypeList aria-label={t('navigation.topics')}>
|
|
198
|
+
{resourceTypes.map((resource, i) => (
|
|
199
|
+
<StyledResourceListElement key={resource.id}>
|
|
200
|
+
{resource.name}
|
|
201
|
+
{i !== resourceTypes.length - 1 && <StyledTopicDivider aria-hidden="true">•</StyledTopicDivider>}
|
|
202
|
+
</StyledResourceListElement>
|
|
204
203
|
))}
|
|
205
|
-
</
|
|
204
|
+
</StyledResourceTypeList>
|
|
206
205
|
);
|
|
207
206
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
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 { spacing, utils } from '@ndla/core';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { ControlProps } from 'react-select';
|
|
13
|
+
import { TagType } from './types';
|
|
14
|
+
|
|
15
|
+
const StyledTagSelectorControl = styled.div`
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-wrap: wrap;
|
|
18
|
+
justify-content: space-between;
|
|
19
|
+
align-items: center;
|
|
20
|
+
margin: ${spacing.xxsmall};
|
|
21
|
+
|
|
22
|
+
overflow: overlay;
|
|
23
|
+
${utils.scrollbar}
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
const Control = ({ innerProps, children, innerRef }: ControlProps<TagType, true>) => {
|
|
27
|
+
return (
|
|
28
|
+
<StyledTagSelectorControl ref={innerRef} {...innerProps}>
|
|
29
|
+
{children}
|
|
30
|
+
</StyledTagSelectorControl>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default Control;
|
|
@@ -0,0 +1,47 @@
|
|
|
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 { ChevronDown, ChevronUp } from '@ndla/icons/common';
|
|
10
|
+
import React, { useMemo } from 'react';
|
|
11
|
+
import styled from '@emotion/styled';
|
|
12
|
+
import { useTranslation } from 'react-i18next';
|
|
13
|
+
import { DropdownIndicatorProps, components } from 'react-select';
|
|
14
|
+
import { iconButtonStyle } from '@ndla/button';
|
|
15
|
+
import { TagType } from './types';
|
|
16
|
+
|
|
17
|
+
const StyledIconWrapper = styled.span`
|
|
18
|
+
svg {
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const DropdownIndicator = ({ selectProps, children, ...props }: DropdownIndicatorProps<TagType, true>) => {
|
|
24
|
+
const { t } = useTranslation();
|
|
25
|
+
|
|
26
|
+
const { menuIsOpen } = selectProps;
|
|
27
|
+
const Icon = menuIsOpen ? ChevronUp : ChevronDown;
|
|
28
|
+
|
|
29
|
+
const css = useMemo(
|
|
30
|
+
() => iconButtonStyle({ colorTheme: 'greyLighter', variant: 'ghost', shape: 'pill', size: 'small' }),
|
|
31
|
+
[],
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<components.DropdownIndicator
|
|
36
|
+
css={css}
|
|
37
|
+
{...props}
|
|
38
|
+
selectProps={selectProps}
|
|
39
|
+
aria-label={menuIsOpen ? t('tagSelector.hideTags') : t('tagSelector.showTags')}>
|
|
40
|
+
<StyledIconWrapper aria-hidden>
|
|
41
|
+
<Icon />
|
|
42
|
+
</StyledIconWrapper>
|
|
43
|
+
</components.DropdownIndicator>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default DropdownIndicator;
|
|
@@ -0,0 +1,31 @@
|
|
|
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 css from '@emotion/css';
|
|
10
|
+
import { colors, spacing } from '@ndla/core';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { components, InputProps } from 'react-select';
|
|
13
|
+
import { TagType } from './types';
|
|
14
|
+
import { StyledValueButton } from './ValueButton';
|
|
15
|
+
|
|
16
|
+
const inputStyle = css`
|
|
17
|
+
&& {
|
|
18
|
+
padding: 0 ${spacing.small};
|
|
19
|
+
color: ${colors.brand.primary};
|
|
20
|
+
margin: 0;
|
|
21
|
+
${StyledValueButton} + & {
|
|
22
|
+
padding-left: ${spacing.xxsmall};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
const Input = (props: InputProps<TagType, true>) => {
|
|
28
|
+
return <components.Input css={inputStyle} {...props} />;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default Input;
|
|
@@ -0,0 +1,38 @@
|
|
|
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 css from '@emotion/css';
|
|
10
|
+
import { colors } from '@ndla/core';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { MenuProps, components } from 'react-select';
|
|
13
|
+
import { StyledMenuList } from './MenuList';
|
|
14
|
+
import { TagType } from './types';
|
|
15
|
+
|
|
16
|
+
const menuStyle = css`
|
|
17
|
+
display: flex;
|
|
18
|
+
position: relative;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
margin: 0;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
border-top: 1px solid ${colors.brand.tertiary};
|
|
23
|
+
min-height: 70px;
|
|
24
|
+
|
|
25
|
+
:has(${StyledMenuList}>*:only-child) {
|
|
26
|
+
min-height: 40px;
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
const Menu = ({ children, ...props }: MenuProps<TagType, true>) => {
|
|
31
|
+
return (
|
|
32
|
+
<components.Menu css={menuStyle} {...props}>
|
|
33
|
+
{children}
|
|
34
|
+
</components.Menu>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default Menu;
|
|
@@ -0,0 +1,30 @@
|
|
|
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 { utils } from '@ndla/core';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { MenuListProps } from 'react-select';
|
|
13
|
+
import { TagType } from './types';
|
|
14
|
+
|
|
15
|
+
export const StyledMenuList = styled.div`
|
|
16
|
+
overflow: overlay;
|
|
17
|
+
${utils.scrollbar}
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const MenuList = ({ innerProps, innerRef, children }: MenuListProps<TagType, true>) => {
|
|
23
|
+
return (
|
|
24
|
+
<StyledMenuList ref={innerRef} {...innerProps}>
|
|
25
|
+
{children}
|
|
26
|
+
</StyledMenuList>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default MenuList;
|
|
@@ -0,0 +1,53 @@
|
|
|
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 React from 'react';
|
|
10
|
+
import { OptionProps } from 'react-select';
|
|
11
|
+
import { buttonStyleV2 as buttonStyle } from '@ndla/button';
|
|
12
|
+
import styled from '@emotion/styled';
|
|
13
|
+
import { colors, fonts } from '@ndla/core';
|
|
14
|
+
import { Done } from '@ndla/icons/editor';
|
|
15
|
+
import { TagType } from './types';
|
|
16
|
+
|
|
17
|
+
interface StyledProps {
|
|
18
|
+
selected: boolean;
|
|
19
|
+
focused: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const StyledMenuOption = styled.div<StyledProps>`
|
|
23
|
+
&& {
|
|
24
|
+
background: ${({ focused }) => focused && colors.brand.lighter};
|
|
25
|
+
color: ${({ focused }) => focused && colors.brand.primary};
|
|
26
|
+
justify-content: space-between;
|
|
27
|
+
${fonts.sizes(16)};
|
|
28
|
+
font-weight: ${fonts.weight.normal};
|
|
29
|
+
color: ${({ selected }) => selected && colors.brand.grey};
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
const StyledCheck = styled(Done)`
|
|
34
|
+
width: 24px;
|
|
35
|
+
height: 24px;
|
|
36
|
+
fill: ${colors.brand.tertiary};
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
const Option = ({ innerProps, innerRef, children, isSelected, isFocused }: OptionProps<TagType, true>) => {
|
|
40
|
+
return (
|
|
41
|
+
<StyledMenuOption
|
|
42
|
+
focused={isFocused}
|
|
43
|
+
selected={isSelected}
|
|
44
|
+
css={buttonStyle({ colorTheme: 'lighter', variant: 'ghost', shape: 'sharp' })}
|
|
45
|
+
ref={innerRef}
|
|
46
|
+
{...innerProps}>
|
|
47
|
+
{children}
|
|
48
|
+
{isSelected && <StyledCheck />}
|
|
49
|
+
</StyledMenuOption>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default Option;
|