@ndla/ui 22.0.3 → 22.3.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/Animation/DisplayOnPageYOffset.js +1 -1
- package/es/Article/Article.js +3 -3
- package/es/Article/ArticleByline.js +5 -6
- package/es/Breadcrumb/ActionBreadcrumb.js +3 -3
- package/es/CompetenceGoalTab/CompetenceGoalItem.js +12 -10
- package/es/CompetenceGoalTab/CompetenceGoalTab.js +11 -9
- package/es/CompetenceGoalTab/CompetenceItem.js +14 -12
- package/es/CompetenceGoalTab/SearchButton.js +7 -4
- package/es/Figure/FigureOpenDialogButton.js +1 -2
- package/es/Filter/FilterListPhone.js +1 -1
- package/es/Frontpage/FrontpageProgramMenu.js +10 -11
- package/es/NDLAFilm/AllMoviesAlphabetically.js +12 -12
- package/es/Resource/BlockResource.js +9 -5
- package/es/Resource/ListResource.js +8 -6
- package/es/Resource/resourceComponents.js +36 -25
- package/es/ResourceGroup/ResourceItem.js +13 -13
- package/es/ResourceGroup/ResourceList.js +3 -3
- package/es/Search/ActiveFilters.js +18 -18
- package/es/Search/SearchPage.js +1 -1
- package/es/SearchTypeResult/ActiveFilters.js +18 -18
- package/es/SearchTypeResult/SearchFieldHeader.js +5 -6
- package/es/TopicMenu/TopicMenu.js +1 -1
- package/es/TreeStructure/FolderItem.js +34 -29
- package/es/TreeStructure/TreeStructure.js +5 -3
- package/es/TreeStructure/TreeStructureWrapper.js +2 -2
- package/es/locale/messages-en.js +5 -1
- package/es/locale/messages-nb.js +5 -1
- package/es/locale/messages-nn.js +5 -1
- package/es/locale/messages-se.js +5 -1
- package/es/locale/messages-sma.js +5 -1
- package/lib/Animation/DisplayOnPageYOffset.js +2 -2
- package/lib/Article/Article.js +4 -4
- package/lib/Article/ArticleByline.js +4 -4
- package/lib/Breadcrumb/ActionBreadcrumb.js +3 -3
- package/lib/CompetenceGoalTab/CompetenceGoalItem.d.ts +1 -1
- package/lib/CompetenceGoalTab/CompetenceGoalItem.js +12 -10
- package/lib/CompetenceGoalTab/CompetenceGoalTab.d.ts +2 -1
- package/lib/CompetenceGoalTab/CompetenceGoalTab.js +11 -9
- package/lib/CompetenceGoalTab/CompetenceItem.d.ts +2 -1
- package/lib/CompetenceGoalTab/CompetenceItem.js +14 -12
- package/lib/CompetenceGoalTab/SearchButton.d.ts +2 -1
- package/lib/CompetenceGoalTab/SearchButton.js +7 -4
- package/lib/Filter/FilterListPhone.js +2 -2
- package/lib/Frontpage/FrontpageProgramMenu.js +9 -9
- package/lib/NDLAFilm/AllMoviesAlphabetically.js +13 -13
- package/lib/Resource/BlockResource.d.ts +2 -1
- package/lib/Resource/BlockResource.js +9 -5
- package/lib/Resource/ListResource.d.ts +2 -1
- package/lib/Resource/ListResource.js +8 -6
- package/lib/Resource/resourceComponents.d.ts +4 -2
- package/lib/Resource/resourceComponents.js +38 -19
- package/lib/ResourceGroup/ResourceItem.js +12 -14
- package/lib/ResourceGroup/ResourceList.js +2 -4
- package/lib/Search/ActiveFilters.js +30 -32
- package/lib/Search/SearchPage.js +2 -2
- package/lib/SearchTypeResult/ActiveFilters.js +37 -39
- package/lib/SearchTypeResult/SearchFieldHeader.js +6 -6
- package/lib/TopicMenu/TopicMenu.js +2 -2
- package/lib/TreeStructure/FolderItem.d.ts +1 -1
- package/lib/TreeStructure/FolderItem.js +34 -29
- package/lib/TreeStructure/TreeStructure.d.ts +0 -1
- package/lib/TreeStructure/TreeStructure.js +5 -3
- package/lib/TreeStructure/TreeStructureWrapper.js +2 -2
- package/lib/TreeStructure/types.d.ts +1 -0
- package/lib/locale/messages-en.d.ts +4 -0
- package/lib/locale/messages-en.js +5 -1
- package/lib/locale/messages-nb.d.ts +4 -0
- package/lib/locale/messages-nb.js +5 -1
- package/lib/locale/messages-nn.d.ts +4 -0
- package/lib/locale/messages-nn.js +5 -1
- package/lib/locale/messages-se.d.ts +4 -0
- package/lib/locale/messages-se.js +5 -1
- package/lib/locale/messages-sma.d.ts +4 -0
- package/lib/locale/messages-sma.js +5 -1
- package/lib/types.d.ts +1 -0
- package/package.json +19 -17
- package/src/Animation/DisplayOnPageYOffset.tsx +1 -1
- package/src/Article/Article.tsx +1 -1
- package/src/Article/ArticleByline.tsx +1 -2
- package/src/Breadcrumb/ActionBreadcrumb.tsx +1 -2
- package/src/CompetenceGoalTab/CompetenceGoalItem.tsx +6 -2
- package/src/CompetenceGoalTab/CompetenceGoalTab.tsx +5 -4
- package/src/CompetenceGoalTab/CompetenceItem.tsx +9 -2
- package/src/CompetenceGoalTab/SearchButton.tsx +3 -2
- package/src/Figure/FigureOpenDialogButton.tsx +1 -2
- package/src/Filter/FilterListPhone.jsx +1 -1
- package/src/Frontpage/FrontpageProgramMenu.tsx +1 -2
- package/src/NDLAFilm/AllMoviesAlphabetically.tsx +1 -1
- package/src/Resource/BlockResource.tsx +4 -2
- package/src/Resource/ListResource.tsx +3 -1
- package/src/Resource/resourceComponents.tsx +25 -9
- package/src/ResourceGroup/ResourceItem.tsx +1 -1
- package/src/ResourceGroup/ResourceList.tsx +1 -1
- package/src/Search/ActiveFilters.jsx +1 -1
- package/src/Search/SearchPage.jsx +1 -1
- package/src/SearchTypeResult/ActiveFilters.tsx +1 -1
- package/src/SearchTypeResult/SearchFieldHeader.tsx +1 -2
- package/src/TopicMenu/TopicMenu.jsx +1 -1
- package/src/TreeStructure/FolderItem.tsx +7 -2
- package/src/TreeStructure/TreeStructure.tsx +2 -1
- package/src/TreeStructure/TreeStructureWrapper.tsx +9 -12
- package/src/TreeStructure/types.ts +1 -0
- package/src/locale/messages-en.ts +4 -0
- package/src/locale/messages-nb.ts +4 -0
- package/src/locale/messages-nn.ts +4 -0
- package/src/locale/messages-se.ts +4 -0
- package/src/locale/messages-sma.ts +4 -0
- package/src/types.ts +1 -0
|
@@ -387,7 +387,9 @@ var messages = _objectSpread(_objectSpread({
|
|
|
387
387
|
competenceTabCorelabel: 'Kjerneelement',
|
|
388
388
|
competenceGoalItem: {
|
|
389
389
|
title: 'Kompetansemål og vurdering'
|
|
390
|
-
}
|
|
390
|
+
},
|
|
391
|
+
licenseData: 'Inneholder data under',
|
|
392
|
+
licenseFrom: 'tilgjengeliggjort på'
|
|
391
393
|
},
|
|
392
394
|
subject: {
|
|
393
395
|
associatedTopics: 'Tilhørende emner'
|
|
@@ -985,6 +987,8 @@ var messages = _objectSpread(_objectSpread({
|
|
|
985
987
|
detailView: 'Detaljrik listevisning',
|
|
986
988
|
shortView: 'Kort visning',
|
|
987
989
|
myPage: {
|
|
990
|
+
confirmDeleteAccount: 'Er du sikker på at du vil slette kontoen?',
|
|
991
|
+
confirmDeleteAccountButton: 'Slett konto',
|
|
988
992
|
myPage: 'Min side',
|
|
989
993
|
deleteAccount: 'Slett Min NDLA',
|
|
990
994
|
logout: 'Logg ut av Min NDLA',
|
|
@@ -86,6 +86,8 @@ declare const messages: {
|
|
|
86
86
|
detailView: string;
|
|
87
87
|
shortView: string;
|
|
88
88
|
myPage: {
|
|
89
|
+
confirmDeleteAccount: string;
|
|
90
|
+
confirmDeleteAccountButton: string;
|
|
89
91
|
myPage: string;
|
|
90
92
|
deleteAccount: string;
|
|
91
93
|
logout: string;
|
|
@@ -552,6 +554,8 @@ declare const messages: {
|
|
|
552
554
|
competenceGoalItem: {
|
|
553
555
|
title: string;
|
|
554
556
|
};
|
|
557
|
+
licenseData: string;
|
|
558
|
+
licenseFrom: string;
|
|
555
559
|
};
|
|
556
560
|
subject: {
|
|
557
561
|
associatedTopics: string;
|
|
@@ -387,7 +387,9 @@ var messages = _objectSpread(_objectSpread({
|
|
|
387
387
|
competenceTabCorelabel: 'Kjerneelement',
|
|
388
388
|
competenceGoalItem: {
|
|
389
389
|
title: 'Kompetansemål og vurdering'
|
|
390
|
-
}
|
|
390
|
+
},
|
|
391
|
+
licenseData: 'Inneholder data under',
|
|
392
|
+
licenseFrom: 'tilgjengeliggjort på'
|
|
391
393
|
},
|
|
392
394
|
subject: {
|
|
393
395
|
associatedTopics: 'Tilhørende emner'
|
|
@@ -985,6 +987,8 @@ var messages = _objectSpread(_objectSpread({
|
|
|
985
987
|
detailView: 'Detaljrik listevisning',
|
|
986
988
|
shortView: 'Kort visning',
|
|
987
989
|
myPage: {
|
|
990
|
+
confirmDeleteAccount: 'Er du sikker på at du vil slette kontoen?',
|
|
991
|
+
confirmDeleteAccountButton: 'Slett konto',
|
|
988
992
|
myPage: 'Min side',
|
|
989
993
|
deleteAccount: 'Slett Min NDLA',
|
|
990
994
|
logout: 'Logg ut av Min NDLA',
|
package/lib/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ndla/ui",
|
|
3
|
-
"version": "22.0
|
|
3
|
+
"version": "22.3.0",
|
|
4
4
|
"description": "UI component library for NDLA.",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -31,21 +31,22 @@
|
|
|
31
31
|
"types"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ndla/
|
|
35
|
-
"@ndla/
|
|
36
|
-
"@ndla/
|
|
37
|
-
"@ndla/
|
|
38
|
-
"@ndla/
|
|
39
|
-
"@ndla/
|
|
40
|
-
"@ndla/
|
|
41
|
-
"@ndla/
|
|
42
|
-
"@ndla/
|
|
43
|
-
"@ndla/
|
|
44
|
-
"@ndla/
|
|
45
|
-
"@ndla/
|
|
46
|
-
"@ndla/
|
|
34
|
+
"@ndla/article-scripts": "^3.0.1",
|
|
35
|
+
"@ndla/button": "^3.3.1",
|
|
36
|
+
"@ndla/carousel": "^1.2.16",
|
|
37
|
+
"@ndla/core": "^2.3.4",
|
|
38
|
+
"@ndla/forms": "^3.1.4",
|
|
39
|
+
"@ndla/hooks": "^1.1.5",
|
|
40
|
+
"@ndla/icons": "^1.11.4",
|
|
41
|
+
"@ndla/licenses": "^5.0.7",
|
|
42
|
+
"@ndla/modal": "^1.2.18",
|
|
43
|
+
"@ndla/notion": "^3.1.30",
|
|
44
|
+
"@ndla/safelink": "^2.2.7",
|
|
45
|
+
"@ndla/switch": "^0.1.11",
|
|
46
|
+
"@ndla/tabs": "^1.1.15",
|
|
47
|
+
"@ndla/tooltip": "^2.1.6",
|
|
47
48
|
"@ndla/types-learningpath-api": "^0.0.12",
|
|
48
|
-
"@ndla/util": "^3.0.
|
|
49
|
+
"@ndla/util": "^3.0.1",
|
|
49
50
|
"@reach/menu-button": "^0.16.2",
|
|
50
51
|
"@reach/slider": "^0.16.0",
|
|
51
52
|
"focus-trap-react": "^8.9.2",
|
|
@@ -68,7 +69,8 @@
|
|
|
68
69
|
"i18next": "^20.3.1",
|
|
69
70
|
"prop-types": "^15.8.1",
|
|
70
71
|
"react": "^16.8.4 || ^17.0.0",
|
|
71
|
-
"react-i18next": "^11.11.0"
|
|
72
|
+
"react-i18next": "^11.11.0",
|
|
73
|
+
"react-router-dom": "^6.3.0"
|
|
72
74
|
},
|
|
73
75
|
"devDependencies": {
|
|
74
76
|
"@babel/plugin-proposal-optional-chaining": "^7.11.0",
|
|
@@ -83,5 +85,5 @@
|
|
|
83
85
|
"publishConfig": {
|
|
84
86
|
"access": "public"
|
|
85
87
|
},
|
|
86
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "1c8439d413eefda014a9438d78a34c1639194321"
|
|
87
89
|
}
|
package/src/Article/Article.tsx
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import React, { ComponentType, ReactNode, useEffect, useRef, useState, forwardRef } from 'react';
|
|
10
10
|
import BEMHelper from 'react-bem-helper';
|
|
11
|
-
import isString from 'lodash
|
|
11
|
+
import { isString } from 'lodash';
|
|
12
12
|
import parse from 'html-react-parser';
|
|
13
13
|
import styled from '@emotion/styled';
|
|
14
14
|
|
|
@@ -13,8 +13,7 @@ import Button, { CopyButton } from '@ndla/button';
|
|
|
13
13
|
import { colors, fonts, spacing } from '@ndla/core';
|
|
14
14
|
import { copyTextToClipboard, printPage } from '@ndla/util';
|
|
15
15
|
import { useTranslation } from 'react-i18next';
|
|
16
|
-
import { LicenseByline } from '@ndla/licenses';
|
|
17
|
-
import { getLicenseByAbbreviation } from '@ndla/licenses';
|
|
16
|
+
import { LicenseByline, getLicenseByAbbreviation } from '@ndla/licenses';
|
|
18
17
|
import { TFunction } from 'i18next';
|
|
19
18
|
|
|
20
19
|
const Wrapper = styled.div`
|
|
@@ -11,8 +11,7 @@ import { colors, fonts, spacing } from '@ndla/core';
|
|
|
11
11
|
import { ChevronRight } from '@ndla/icons/common';
|
|
12
12
|
import SafeLink from '@ndla/safelink';
|
|
13
13
|
import React from 'react';
|
|
14
|
-
import { MenuButton } from '@ndla/button';
|
|
15
|
-
import { MenuItemProps } from '@ndla/button';
|
|
14
|
+
import { MenuButton, MenuItemProps } from '@ndla/button';
|
|
16
15
|
import Breadcrumb from './Breadcrumb';
|
|
17
16
|
import { IndexedBreadcrumbItem, SimpleBreadcrumbItem } from './BreadcrumbItem';
|
|
18
17
|
|
|
@@ -60,7 +60,7 @@ const GoalSearchWrapper = styled.div`
|
|
|
60
60
|
}
|
|
61
61
|
`;
|
|
62
62
|
|
|
63
|
-
const CompetenceGoalItem = ({ title, goals }: CompetenceGoalsItemType) => {
|
|
63
|
+
const CompetenceGoalItem = ({ title, goals, isOembed }: CompetenceGoalsItemType) => {
|
|
64
64
|
const { t } = useTranslation();
|
|
65
65
|
return (
|
|
66
66
|
<GoalItem>
|
|
@@ -73,7 +73,11 @@ const CompetenceGoalItem = ({ title, goals }: CompetenceGoalsItemType) => {
|
|
|
73
73
|
<GoalListInnerTextWrapper>{goal.text}</GoalListInnerTextWrapper>
|
|
74
74
|
{goal.url && goal.type !== 'LK06' && (
|
|
75
75
|
<GoalSearchWrapper>
|
|
76
|
-
<SearchButton
|
|
76
|
+
<SearchButton
|
|
77
|
+
to={goal.url}
|
|
78
|
+
text={t('competenceGoals.competenceGoalResourceSearchText')}
|
|
79
|
+
target={isOembed ? '_blank' : '_self'}
|
|
80
|
+
/>
|
|
77
81
|
</GoalSearchWrapper>
|
|
78
82
|
)}
|
|
79
83
|
</GoalListElementInnerWrapper>
|
|
@@ -19,6 +19,7 @@ import CompetenceItem, { ListItemProp } from './CompetenceItem';
|
|
|
19
19
|
type CompetenceProps = {
|
|
20
20
|
list: ListItemProp[];
|
|
21
21
|
highlightSearchBox?: boolean;
|
|
22
|
+
isOembed?: boolean;
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
const Wrapper = styled.div`
|
|
@@ -79,7 +80,7 @@ const HighlightText = styled.span`
|
|
|
79
80
|
font-family: 'Shadows Into Light Two', cursive;
|
|
80
81
|
`;
|
|
81
82
|
|
|
82
|
-
const CompetenceGoalTab = ({ list, highlightSearchBox }: CompetenceProps) => {
|
|
83
|
+
const CompetenceGoalTab = ({ list, highlightSearchBox, isOembed }: CompetenceProps) => {
|
|
83
84
|
const [currentTabItem, setCurrentTab] = useState(list[0]);
|
|
84
85
|
const { t } = useTranslation();
|
|
85
86
|
|
|
@@ -106,15 +107,15 @@ const CompetenceGoalTab = ({ list, highlightSearchBox }: CompetenceProps) => {
|
|
|
106
107
|
<ArrowFeatureTips />
|
|
107
108
|
</HighlightWrapper>
|
|
108
109
|
)}
|
|
109
|
-
<CompetenceItem item={currentTabItem} />
|
|
110
|
+
<CompetenceItem item={currentTabItem} isOembed={isOembed} />
|
|
110
111
|
<LicenseByline licenseRights={[CC, BY]}>
|
|
111
112
|
<LicenseIconsTextWrapper>UDIR</LicenseIconsTextWrapper>
|
|
112
113
|
</LicenseByline>
|
|
113
|
-
|
|
114
|
+
{`${t('competenceGoals.licenseData')} `}
|
|
114
115
|
<SafeLink to="https://data.norge.no/nlod/no" target="_blank">
|
|
115
116
|
NLOD
|
|
116
117
|
</SafeLink>
|
|
117
|
-
|
|
118
|
+
{`, ${t('competenceGoals.licenseFrom')} `}
|
|
118
119
|
<SafeLink to="https://data.udir.no/" target="_blank">
|
|
119
120
|
data.udir.no
|
|
120
121
|
</SafeLink>
|
|
@@ -79,9 +79,10 @@ export type ListItemProp = {
|
|
|
79
79
|
};
|
|
80
80
|
export type ListItemProps = {
|
|
81
81
|
item: ListItemProp;
|
|
82
|
+
isOembed?: boolean;
|
|
82
83
|
};
|
|
83
84
|
|
|
84
|
-
const CompetenceItem = ({ item }: ListItemProps) => {
|
|
85
|
+
const CompetenceItem = ({ item, isOembed }: ListItemProps) => {
|
|
85
86
|
const { t } = useTranslation();
|
|
86
87
|
const { type, groupedCompetenceGoals, groupedCoreElementItems } = item;
|
|
87
88
|
switch (type) {
|
|
@@ -105,7 +106,13 @@ const CompetenceItem = ({ item }: ListItemProps) => {
|
|
|
105
106
|
{group.elements.length > 0 && (
|
|
106
107
|
<Goals>
|
|
107
108
|
{group.elements.map((goal) => (
|
|
108
|
-
<CompetenceGoalItem
|
|
109
|
+
<CompetenceGoalItem
|
|
110
|
+
key={goal.id}
|
|
111
|
+
id={goal.id}
|
|
112
|
+
title={goal.title}
|
|
113
|
+
goals={goal.goals}
|
|
114
|
+
isOembed={isOembed}
|
|
115
|
+
/>
|
|
109
116
|
))}
|
|
110
117
|
</Goals>
|
|
111
118
|
)}
|
|
@@ -37,11 +37,12 @@ const IconWrapper = styled.span`
|
|
|
37
37
|
type Props = {
|
|
38
38
|
to: string;
|
|
39
39
|
text: string;
|
|
40
|
+
target?: string;
|
|
40
41
|
};
|
|
41
42
|
|
|
42
|
-
const SearchButton = ({ to, text }: Props) => (
|
|
43
|
+
const SearchButton = ({ to, text, target = '_self' }: Props) => (
|
|
43
44
|
<Wrapper>
|
|
44
|
-
<SafeLink to={to}>
|
|
45
|
+
<SafeLink to={to} target={target}>
|
|
45
46
|
<IconWrapper>
|
|
46
47
|
<Search style={{ width: '24px', height: '24px' }} />
|
|
47
48
|
</IconWrapper>
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { Play } from '@ndla/icons/common';
|
|
11
|
-
import { ExpandTwoArrows } from '@ndla/icons/action';
|
|
12
|
-
import { CursorClick } from '@ndla/icons/action';
|
|
11
|
+
import { ExpandTwoArrows, CursorClick } from '@ndla/icons/action';
|
|
13
12
|
|
|
14
13
|
interface Props {
|
|
15
14
|
type?: 'image' | 'video' | 'h5p' | 'iframe' | 'external';
|
|
@@ -12,7 +12,7 @@ import { ChevronDown, ChevronUp } from '@ndla/icons/common';
|
|
|
12
12
|
import { Cross } from '@ndla/icons/action';
|
|
13
13
|
import Modal, { ModalHeader, ModalBody, ModalCloseButton } from '@ndla/modal';
|
|
14
14
|
import Button from '@ndla/button';
|
|
15
|
-
import debounce from 'lodash
|
|
15
|
+
import { debounce } from 'lodash';
|
|
16
16
|
import { classes } from './filterClasses';
|
|
17
17
|
import ToggleItem from './ToggleItem';
|
|
18
18
|
import ActiveFilters from '../Search/ActiveFilters';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import styled from '@emotion/styled';
|
|
3
3
|
import Button from '@ndla/button';
|
|
4
|
-
import { fonts } from '@ndla/core';
|
|
5
|
-
import { breakpoints, mq } from '@ndla/core';
|
|
4
|
+
import { fonts, breakpoints, mq } from '@ndla/core';
|
|
6
5
|
import { useTranslation } from 'react-i18next';
|
|
7
6
|
import NavigationBox, { ItemProps } from '../Navigation/NavigationBox';
|
|
8
7
|
import FrontpageAllSubjects, { subjectsProps } from './FrontpageAllSubjects';
|
|
@@ -10,7 +10,7 @@ import React, { Fragment, RefObject, useEffect, useRef, useState } from 'react';
|
|
|
10
10
|
import { isIE, browserVersion } from 'react-device-detect';
|
|
11
11
|
import styled from '@emotion/styled';
|
|
12
12
|
import { css } from '@emotion/core';
|
|
13
|
-
import throttle from 'lodash
|
|
13
|
+
import { throttle } from 'lodash';
|
|
14
14
|
import { breakpoints, mq, spacing, spacingUnit, colors, fonts, animations } from '@ndla/core';
|
|
15
15
|
import SafeLink from '@ndla/safelink';
|
|
16
16
|
import { makeSrcQueryString } from '../Image';
|
|
@@ -17,6 +17,7 @@ import ContentLoader from '../ContentLoader';
|
|
|
17
17
|
|
|
18
18
|
interface BlockResourceProps {
|
|
19
19
|
link: string;
|
|
20
|
+
tagLinkPrefix?: string;
|
|
20
21
|
title: string;
|
|
21
22
|
resourceImage: ResourceImageProps;
|
|
22
23
|
topics: string[];
|
|
@@ -47,7 +48,7 @@ const BlockDescription = styled.p`
|
|
|
47
48
|
overflow: hidden;
|
|
48
49
|
text-overflow: ellipsis;
|
|
49
50
|
transition: height 0.2s ease-out;
|
|
50
|
-
${() => BlockElementWrapper}:hover & {
|
|
51
|
+
${() => BlockElementWrapper}:hover &, ${() => BlockElementWrapper}:focus & {
|
|
51
52
|
// Unfortunate css needed for multi-line text overflow ellipsis.
|
|
52
53
|
height: 3.1em;
|
|
53
54
|
-webkit-line-clamp: 2;
|
|
@@ -132,6 +133,7 @@ const BlockTopicList = ({ topics, loading }: BlockTopicListProps) => {
|
|
|
132
133
|
|
|
133
134
|
const BlockResource = ({
|
|
134
135
|
link,
|
|
136
|
+
tagLinkPrefix,
|
|
135
137
|
title,
|
|
136
138
|
tags,
|
|
137
139
|
resourceImage,
|
|
@@ -152,7 +154,7 @@ const BlockResource = ({
|
|
|
152
154
|
<BlockTopicList topics={topics} loading={isLoading} />
|
|
153
155
|
<BlockDescription>{description}</BlockDescription>
|
|
154
156
|
<RightRow>
|
|
155
|
-
{tags && <CompressedTagList tags={tags} />}
|
|
157
|
+
{tags && <CompressedTagList tagLinkPrefix={tagLinkPrefix} tags={tags} />}
|
|
156
158
|
{menuItems && menuItems.length > 0 && <MenuButton alignRight size="small" menuItems={menuItems} />}
|
|
157
159
|
</RightRow>
|
|
158
160
|
</BlockInfoWrapper>
|
|
@@ -109,6 +109,7 @@ interface StyledImageProps {
|
|
|
109
109
|
|
|
110
110
|
export interface ListResourceProps {
|
|
111
111
|
link: string;
|
|
112
|
+
tagLinkPrefix?: string;
|
|
112
113
|
title: string;
|
|
113
114
|
resourceImage: ResourceImageProps;
|
|
114
115
|
topics: string[];
|
|
@@ -184,6 +185,7 @@ const ResourceDescription = ({ description, loading }: ResourceDescriptionProps)
|
|
|
184
185
|
|
|
185
186
|
const ListResource = ({
|
|
186
187
|
link,
|
|
188
|
+
tagLinkPrefix,
|
|
187
189
|
title,
|
|
188
190
|
tags,
|
|
189
191
|
resourceImage,
|
|
@@ -205,7 +207,7 @@ const ListResource = ({
|
|
|
205
207
|
</TopicAndTitleWrapper>
|
|
206
208
|
{showDescription && <ResourceDescription description={description} loading={isLoading} />}
|
|
207
209
|
<TagsandActionMenu>
|
|
208
|
-
{tags && <CompressedTagList tags={tags} />}
|
|
210
|
+
{tags && <CompressedTagList tagLinkPrefix={tagLinkPrefix} tags={tags} />}
|
|
209
211
|
{menuItems && menuItems.length > 0 && <MenuButton alignRight size="small" menuItems={menuItems} />}
|
|
210
212
|
</TagsandActionMenu>
|
|
211
213
|
</ResourceWrapper>
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import React from 'react';
|
|
10
9
|
import styled from '@emotion/styled';
|
|
11
|
-
import {
|
|
10
|
+
import { colors, fonts, spacing } from '@ndla/core';
|
|
11
|
+
import React, { MouseEvent } from 'react';
|
|
12
12
|
|
|
13
13
|
import { MenuButton } from '@ndla/button';
|
|
14
|
+
import SafeLink from '@ndla/safelink';
|
|
15
|
+
import { useNavigate } from 'react-router-dom';
|
|
14
16
|
|
|
15
17
|
export interface ResourceImageProps {
|
|
16
18
|
alt: string;
|
|
@@ -42,9 +44,13 @@ const StyledTagList = styled.ul`
|
|
|
42
44
|
`;
|
|
43
45
|
|
|
44
46
|
const StyledTagListElement = styled.li`
|
|
45
|
-
color: ${colors.brand.grey};
|
|
46
47
|
margin: 0;
|
|
47
48
|
${fonts.sizes(14)};
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
const StyledSafeLink = styled(SafeLink)`
|
|
52
|
+
box-shadow: none;
|
|
53
|
+
color: ${colors.brand.grey};
|
|
48
54
|
::before {
|
|
49
55
|
content: '#';
|
|
50
56
|
}
|
|
@@ -90,14 +96,20 @@ const TagCounterWrapper = styled.p`
|
|
|
90
96
|
|
|
91
97
|
interface TagListProps {
|
|
92
98
|
tags?: string[];
|
|
99
|
+
tagLinkPrefix?: string;
|
|
93
100
|
}
|
|
94
|
-
|
|
95
|
-
export const TagList = ({ tags }: TagListProps) => {
|
|
101
|
+
export const TagList = ({ tags, tagLinkPrefix }: TagListProps) => {
|
|
96
102
|
if (!tags) return null;
|
|
97
103
|
return (
|
|
98
104
|
<StyledTagList>
|
|
99
105
|
{tags.map((tag, i) => (
|
|
100
|
-
<StyledTagListElement key={`tag-${i}`}>
|
|
106
|
+
<StyledTagListElement key={`tag-${i}`}>
|
|
107
|
+
<StyledSafeLink
|
|
108
|
+
onClick={(e: MouseEvent<HTMLAnchorElement | HTMLElement>) => e.stopPropagation()}
|
|
109
|
+
to={`${tagLinkPrefix ? tagLinkPrefix : ''}/${tag}`}>
|
|
110
|
+
{tag}
|
|
111
|
+
</StyledSafeLink>
|
|
112
|
+
</StyledTagListElement>
|
|
101
113
|
))}
|
|
102
114
|
</StyledTagList>
|
|
103
115
|
);
|
|
@@ -105,20 +117,24 @@ export const TagList = ({ tags }: TagListProps) => {
|
|
|
105
117
|
|
|
106
118
|
interface CompressedTagListProps {
|
|
107
119
|
tags: string[];
|
|
120
|
+
tagLinkPrefix?: string;
|
|
108
121
|
}
|
|
109
122
|
|
|
110
|
-
export const CompressedTagList = ({ tags }: CompressedTagListProps) => {
|
|
123
|
+
export const CompressedTagList = ({ tags, tagLinkPrefix }: CompressedTagListProps) => {
|
|
124
|
+
const navigate = useNavigate();
|
|
111
125
|
const visibleTags = tags.slice(0, 3);
|
|
112
126
|
const remainingTags = tags.slice(3, tags.length).map((tag) => {
|
|
113
127
|
return {
|
|
114
128
|
text: '#' + tag,
|
|
115
|
-
onClick: () => {
|
|
129
|
+
onClick: () => {
|
|
130
|
+
navigate(`${tagLinkPrefix ? tagLinkPrefix : ''}/${tag}`);
|
|
131
|
+
},
|
|
116
132
|
};
|
|
117
133
|
});
|
|
118
134
|
|
|
119
135
|
return (
|
|
120
136
|
<>
|
|
121
|
-
<TagList tags={visibleTags} />
|
|
137
|
+
<TagList tagLinkPrefix={tagLinkPrefix} tags={visibleTags} />
|
|
122
138
|
{remainingTags.length > 0 && (
|
|
123
139
|
<MenuButton hideMenuIcon={true} menuItems={remainingTags}>
|
|
124
140
|
<TagCounterWrapper>{`+${remainingTags.length}`}</TagCounterWrapper>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { useTranslation } from 'react-i18next';
|
|
11
11
|
import styled from '@emotion/styled';
|
|
12
|
-
import css from '@emotion/
|
|
12
|
+
import { css } from '@emotion/core';
|
|
13
13
|
import { keyframes } from '@emotion/core';
|
|
14
14
|
import SafeLink from '@ndla/safelink';
|
|
15
15
|
import { Additional, Core, HumanMaleBoard } from '@ndla/icons/common';
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
|
-
import css from '@emotion/
|
|
11
|
+
import { css } from '@emotion/core';
|
|
12
12
|
import { keyframes } from '@emotion/core';
|
|
13
13
|
import { useTranslation } from 'react-i18next';
|
|
14
14
|
import NoContentBox from '../NoContentBox';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import styled from '@emotion/styled';
|
|
4
|
-
import css from '@emotion/
|
|
4
|
+
import { css } from '@emotion/core';
|
|
5
5
|
import { spacing, mq, breakpoints } from '@ndla/core';
|
|
6
6
|
import Tooltip from '@ndla/tooltip';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
@@ -2,7 +2,7 @@ import React, { Component, Fragment, createRef } from 'react';
|
|
|
2
2
|
import BEMHelper from 'react-bem-helper';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { Back } from '@ndla/icons/common';
|
|
5
|
-
import debounce from 'lodash
|
|
5
|
+
import { debounce } from 'lodash';
|
|
6
6
|
import { getCurrentBreakpoint, breakpoints } from '@ndla/util';
|
|
7
7
|
import Modal, { ModalHeader, ModalBody, ModalCloseButton } from '@ndla/modal';
|
|
8
8
|
import Button from '@ndla/button';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import React, { ReactElement } from 'react';
|
|
10
10
|
import { useTranslation } from 'react-i18next';
|
|
11
11
|
import styled from '@emotion/styled';
|
|
12
|
-
import css from '@emotion/
|
|
12
|
+
import { css } from '@emotion/core';
|
|
13
13
|
import { spacing, mq, breakpoints } from '@ndla/core';
|
|
14
14
|
import Tooltip from '@ndla/tooltip';
|
|
15
15
|
import Button from '@ndla/button';
|
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import React, { FormEvent, useRef, useState } from 'react';
|
|
9
9
|
import styled from '@emotion/styled';
|
|
10
|
-
import { colors } from '@ndla/core';
|
|
11
10
|
import { Search as SearchIcon } from '@ndla/icons/common';
|
|
12
|
-
import { spacing } from '@ndla/core';
|
|
11
|
+
import { spacing, colors } from '@ndla/core';
|
|
13
12
|
import { Cross as CrossIcon } from '@ndla/icons/action';
|
|
14
13
|
|
|
15
14
|
import { useTranslation } from 'react-i18next';
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import React, { Fragment, useEffect, useState } from 'react';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
14
|
import BEMHelper from 'react-bem-helper';
|
|
15
|
-
import debounce from 'lodash
|
|
15
|
+
import { debounce } from 'lodash';
|
|
16
16
|
|
|
17
17
|
import { Home, Back, Additional, ChevronRight } from '@ndla/icons/common';
|
|
18
18
|
import { Cross } from '@ndla/icons/action';
|
|
@@ -49,19 +49,22 @@ const WrapperForFolderChild = styled.div`
|
|
|
49
49
|
gap: ${spacing.xsmall};
|
|
50
50
|
`;
|
|
51
51
|
|
|
52
|
-
const shouldForwardProp = (name: string) => !['selected', 'noArrow'].includes(name);
|
|
52
|
+
const shouldForwardProp = (name: string) => !['selected', 'noArrow', 'fullWidth'].includes(name);
|
|
53
53
|
|
|
54
54
|
interface FolderNameProps {
|
|
55
55
|
selected?: boolean;
|
|
56
56
|
noArrow?: boolean;
|
|
57
|
+
fullWidth?: boolean;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
const FolderName = styled('button', { shouldForwardProp })<FolderNameProps>`
|
|
60
61
|
cursor: pointer;
|
|
61
62
|
padding: ${spacing.xsmall};
|
|
62
63
|
margin: 0;
|
|
64
|
+
outline-offset: -2px;
|
|
65
|
+
outline-color: ${colors.brand.primary};
|
|
63
66
|
margin-left: ${({ noArrow }) => (noArrow ? `29px` : `0px`)};
|
|
64
|
-
flex-grow: 1;
|
|
67
|
+
flex-grow: ${({ fullWidth }) => fullWidth && 1};
|
|
65
68
|
display: grid;
|
|
66
69
|
grid-template-columns: auto 1fr auto;
|
|
67
70
|
align-items: center;
|
|
@@ -116,6 +119,7 @@ const FolderItem = ({
|
|
|
116
119
|
setSelectedFolder,
|
|
117
120
|
targetResource,
|
|
118
121
|
visibleFolders,
|
|
122
|
+
framed,
|
|
119
123
|
}: Props) => {
|
|
120
124
|
const { t } = useTranslation();
|
|
121
125
|
const { id, icon, name } = folder;
|
|
@@ -173,6 +177,7 @@ const FolderItem = ({
|
|
|
173
177
|
{onSelectFolder ? (
|
|
174
178
|
<>
|
|
175
179
|
<FolderName
|
|
180
|
+
fullWidth={framed}
|
|
176
181
|
ref={ref}
|
|
177
182
|
onKeyDown={(e) => arrowNavigation(e, id, visibleFolders, setFocusedId, onOpenFolder, onCloseFolder)}
|
|
178
183
|
noArrow={hideArrow && !noPaddingWhenArrowIsHidden}
|
|
@@ -34,7 +34,6 @@ export interface TreeStructureProps extends CommonTreeStructureProps {
|
|
|
34
34
|
defaultOpenFolders?: string[];
|
|
35
35
|
folders: FolderType[];
|
|
36
36
|
editable?: boolean;
|
|
37
|
-
framed?: boolean;
|
|
38
37
|
label?: string;
|
|
39
38
|
maximumLevelsOfFoldersAllowed?: number;
|
|
40
39
|
onNewFolder?: (name: string, parentId: string) => Promise<IFolder>;
|
|
@@ -118,6 +117,7 @@ const TreeStructure = ({
|
|
|
118
117
|
onNewFolder?.(name, parentId).then((newFolder) => {
|
|
119
118
|
if (newFolder) {
|
|
120
119
|
setSelectedFolder(newFolder);
|
|
120
|
+
onSelectFolder?.(newFolder.id);
|
|
121
121
|
setFocusedId(newFolder.id);
|
|
122
122
|
setOpenFolders(uniq(openFolders.concat(parentId)));
|
|
123
123
|
}
|
|
@@ -156,6 +156,7 @@ const TreeStructure = ({
|
|
|
156
156
|
setSelectedFolder={setSelectedFolder}
|
|
157
157
|
targetResource={targetResource}
|
|
158
158
|
visibleFolders={visibleFolderIds}
|
|
159
|
+
framed={framed}
|
|
159
160
|
/>
|
|
160
161
|
</TreeStructureStyledWrapper>
|
|
161
162
|
{editable && (
|
|
@@ -13,18 +13,15 @@ import { colors, misc, spacing } from '@ndla/core';
|
|
|
13
13
|
const TreeStructureWrapper = styled.div<{ framed?: boolean }>`
|
|
14
14
|
padding: ${spacing.xsmall};
|
|
15
15
|
${({ framed }) =>
|
|
16
|
-
framed
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
: css`
|
|
26
|
-
margin-left: -${spacing.medium};
|
|
27
|
-
`}
|
|
16
|
+
framed &&
|
|
17
|
+
css`
|
|
18
|
+
border: 1px solid ${colors.brand.neutral7};
|
|
19
|
+
border-radius: ${misc.borderRadius};
|
|
20
|
+
max-height: 400px;
|
|
21
|
+
overflow-y: scroll;
|
|
22
|
+
scroll-behavior: smooth;
|
|
23
|
+
padding: ${spacing.small};
|
|
24
|
+
`}
|
|
28
25
|
transition: ${misc.transition.default};
|
|
29
26
|
&:focus-within {
|
|
30
27
|
border-color: ${colors.brand.primary};
|