@ndla/ui 34.3.6 → 34.5.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/Article/Article.js +6 -7
- package/es/ContentTypeBadge/ContentTypeBadge.js +3 -6
- package/es/MyNdla/Resource/Folder.js +38 -29
- package/es/Resource/BlockResource.js +21 -13
- package/es/Resource/ListResource.js +12 -21
- package/es/Resource/resourceComponents.js +18 -22
- package/es/SearchTypeResult/ResultNavigation.js +7 -5
- package/es/SearchTypeResult/SearchItem.js +51 -89
- package/es/SearchTypeResult/SearchItems.js +14 -10
- package/es/SearchTypeResult/SearchTypeHeader.js +14 -12
- package/es/SearchTypeResult/SearchTypeResult.js +6 -4
- package/es/SearchTypeResult/components/ItemContexts.js +12 -14
- package/es/SearchTypeResult/components/ItemResourceHeader.js +35 -33
- package/es/SearchTypeResult/components/ItemTopicHeader.js +6 -6
- package/es/locale/messages-en.js +3 -3
- package/es/locale/messages-nb.js +3 -3
- package/es/locale/messages-nn.js +3 -3
- package/es/locale/messages-sma.js +7 -7
- package/lib/Article/Article.js +6 -7
- package/lib/ContentTypeBadge/ContentTypeBadge.d.ts +3 -8
- package/lib/ContentTypeBadge/ContentTypeBadge.js +3 -6
- package/lib/MyNdla/Resource/Folder.js +38 -29
- package/lib/Resource/BlockResource.js +20 -12
- package/lib/Resource/ListResource.js +12 -21
- package/lib/Resource/resourceComponents.d.ts +0 -4
- package/lib/Resource/resourceComponents.js +19 -24
- package/lib/SearchTypeResult/ResultNavigation.d.ts +4 -1
- package/lib/SearchTypeResult/ResultNavigation.js +7 -5
- package/lib/SearchTypeResult/SearchItem.d.ts +4 -4
- package/lib/SearchTypeResult/SearchItem.js +62 -88
- package/lib/SearchTypeResult/SearchItems.d.ts +2 -2
- package/lib/SearchTypeResult/SearchItems.js +14 -10
- package/lib/SearchTypeResult/SearchTypeHeader.js +14 -12
- package/lib/SearchTypeResult/SearchTypeResult.js +6 -4
- package/lib/SearchTypeResult/components/ItemContexts.js +12 -14
- package/lib/SearchTypeResult/components/ItemResourceHeader.d.ts +2 -2
- package/lib/SearchTypeResult/components/ItemResourceHeader.js +35 -33
- package/lib/SearchTypeResult/components/ItemTopicHeader.d.ts +2 -2
- package/lib/SearchTypeResult/components/ItemTopicHeader.js +6 -6
- package/lib/locale/messages-en.js +3 -3
- package/lib/locale/messages-nb.js +3 -3
- package/lib/locale/messages-nn.js +3 -3
- package/lib/locale/messages-sma.js +7 -7
- package/package.json +14 -14
- package/src/Article/Article.tsx +4 -3
- package/src/ContentTypeBadge/ContentTypeBadge.tsx +4 -9
- package/src/MyNdla/Resource/Folder.tsx +8 -12
- package/src/Resource/BlockResource.tsx +8 -8
- package/src/Resource/ListResource.tsx +15 -13
- package/src/Resource/resourceComponents.tsx +5 -6
- package/src/SearchTypeResult/ResultNavigation.tsx +6 -2
- package/src/SearchTypeResult/SearchItem.tsx +61 -77
- package/src/SearchTypeResult/SearchItems.tsx +25 -16
- package/src/SearchTypeResult/SearchTypeHeader.tsx +9 -3
- package/src/SearchTypeResult/SearchTypeResult.tsx +2 -2
- package/src/SearchTypeResult/components/ItemContexts.tsx +9 -9
- package/src/SearchTypeResult/components/ItemResourceHeader.tsx +33 -31
- package/src/SearchTypeResult/components/ItemTopicHeader.tsx +9 -15
- package/src/locale/messages-en.ts +3 -3
- package/src/locale/messages-nb.ts +3 -3
- package/src/locale/messages-nn.ts +3 -3
- package/src/locale/messages-sma.ts +7 -7
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import React, { ReactNode } from 'react';
|
|
9
|
+
import React, { ReactNode, useRef } from 'react';
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
11
|
import parse from 'html-react-parser';
|
|
12
12
|
|
|
@@ -20,25 +20,19 @@ import ItemTopicHeader from './components/ItemTopicHeader';
|
|
|
20
20
|
import ItemResourceHeader from './components/ItemResourceHeader';
|
|
21
21
|
const { contentTypes } = constants;
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
interface ItemTypeProps {
|
|
24
24
|
contentType?: ContentType;
|
|
25
25
|
isTopic?: boolean;
|
|
26
|
-
}
|
|
26
|
+
}
|
|
27
27
|
|
|
28
|
-
const Container = styled.
|
|
28
|
+
const Container = styled.article`
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
position: relative;
|
|
29
31
|
display: flex;
|
|
30
|
-
height: 400px;
|
|
31
|
-
align-items: center;
|
|
32
|
-
justify-content: center;
|
|
33
|
-
`;
|
|
34
|
-
|
|
35
|
-
const ItemWrapper = styled.div`
|
|
36
32
|
flex-direction: column;
|
|
37
|
-
display: flex;
|
|
38
|
-
width: 100%;
|
|
39
|
-
height: 100%;
|
|
40
|
-
border: 1px solid ${colors.brand.neutral7};
|
|
41
33
|
border-radius: 5px;
|
|
34
|
+
border: 1px solid ${colors.brand.neutral7};
|
|
35
|
+
|
|
42
36
|
img {
|
|
43
37
|
transition: all ${animations.durations.fast} ease-in-out;
|
|
44
38
|
}
|
|
@@ -49,43 +43,36 @@ const ItemWrapper = styled.div`
|
|
|
49
43
|
}
|
|
50
44
|
`;
|
|
51
45
|
|
|
52
|
-
const ItemLink = styled(SafeLink)`
|
|
53
|
-
box-shadow: none;
|
|
54
|
-
color: unset;
|
|
55
|
-
text-decoration: none;
|
|
56
|
-
display: flex;
|
|
57
|
-
flex-direction: column;
|
|
58
|
-
position: relative;
|
|
59
|
-
min-height: 0;
|
|
60
|
-
flex: 1;
|
|
61
|
-
`;
|
|
62
|
-
|
|
63
|
-
const TextWrapper = styled.div`
|
|
64
|
-
padding: 0 ${spacing.normal} ${spacing.small};
|
|
65
|
-
`;
|
|
66
|
-
|
|
67
|
-
const ItemTitleWrapper = styled.div<ItemTypeProps>`
|
|
68
|
-
margin-top: ${spacing.small};
|
|
69
|
-
`;
|
|
70
|
-
|
|
71
46
|
const ItemTitle = styled.h3<ItemTypeProps>`
|
|
47
|
+
display: inline;
|
|
72
48
|
${fonts.sizes('24px', '28px')};
|
|
73
49
|
color: ${colors.brand.primary};
|
|
74
|
-
${(props) => props.isTopic &&
|
|
50
|
+
margin-bottom: ${(props) => props.isTopic && spacing.small};
|
|
75
51
|
font-weight: ${fonts.weight.semibold};
|
|
76
|
-
overflow-wrap:
|
|
77
|
-
|
|
78
|
-
${
|
|
79
|
-
box-shadow:
|
|
80
|
-
|
|
52
|
+
overflow-wrap: break-word;
|
|
53
|
+
margin: 0;
|
|
54
|
+
${Container}:hover & {
|
|
55
|
+
box-shadow: 0 -1px inset;
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
const StyledLink = styled(SafeLink)`
|
|
60
|
+
box-shadow: none;
|
|
61
|
+
color: ${colors.brand.primary};
|
|
62
|
+
|
|
63
|
+
:after {
|
|
64
|
+
content: '';
|
|
65
|
+
position: absolute;
|
|
66
|
+
z-index: 1;
|
|
67
|
+
top: 0;
|
|
68
|
+
right: 0;
|
|
69
|
+
bottom: 0;
|
|
70
|
+
left: 0;
|
|
81
71
|
}
|
|
82
72
|
`;
|
|
73
|
+
|
|
83
74
|
const ItemText = styled.div<ItemTypeProps>`
|
|
84
|
-
overflow: hidden;
|
|
85
75
|
${fonts.sizes('16px', '24px')};
|
|
86
|
-
word-break: break-word;
|
|
87
|
-
overflow-wrap: anywhere;
|
|
88
|
-
margin-top: ${spacing.small};
|
|
89
76
|
${(props) =>
|
|
90
77
|
props.isTopic &&
|
|
91
78
|
`
|
|
@@ -93,12 +80,14 @@ const ItemText = styled.div<ItemTypeProps>`
|
|
|
93
80
|
`};
|
|
94
81
|
`;
|
|
95
82
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
83
|
+
const ContentWrapper = styled.main`
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-direction: column;
|
|
86
|
+
gap: ${spacing.small};
|
|
87
|
+
padding: ${spacing.small} ${spacing.normal};
|
|
99
88
|
`;
|
|
100
89
|
|
|
101
|
-
export
|
|
90
|
+
export interface SearchItemProps {
|
|
102
91
|
id: string | number;
|
|
103
92
|
title: string;
|
|
104
93
|
url: string;
|
|
@@ -108,44 +97,39 @@ export type SearchItemProps = {
|
|
|
108
97
|
labels?: string[];
|
|
109
98
|
type?: ContentType;
|
|
110
99
|
children?: ReactNode;
|
|
111
|
-
}
|
|
112
|
-
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface SearchItemType {
|
|
113
103
|
item: SearchItemProps;
|
|
114
104
|
type?: ContentType;
|
|
115
|
-
}
|
|
105
|
+
}
|
|
106
|
+
|
|
116
107
|
const SearchItem = ({ item, type }: SearchItemType) => {
|
|
117
|
-
const { title, url, ingress, contexts, img = null, labels = []
|
|
108
|
+
const { title, url, ingress, contexts = [], img = null, labels = [] } = item;
|
|
109
|
+
const linkRef = useRef<HTMLAnchorElement>(null);
|
|
118
110
|
|
|
119
111
|
const isTopic = type === contentTypes.TOPIC || type === contentTypes.MULTIDISCIPLINARY_TOPIC;
|
|
120
112
|
|
|
121
113
|
return (
|
|
122
114
|
<Container>
|
|
123
|
-
|
|
124
|
-
<
|
|
125
|
-
{
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
</>
|
|
142
|
-
)}
|
|
143
|
-
<ContextWrapper>
|
|
144
|
-
{contexts && contexts.length > 0 && <ItemContexts contexts={contexts} id={item.id} title={item.title} />}
|
|
145
|
-
</ContextWrapper>
|
|
146
|
-
</ItemLink>
|
|
147
|
-
{children}
|
|
148
|
-
</ItemWrapper>
|
|
115
|
+
{isTopic ? (
|
|
116
|
+
<ItemTopicHeader image={img} type={type}>
|
|
117
|
+
<StyledLink to={url} ref={linkRef}>
|
|
118
|
+
<ItemTitle>{title}</ItemTitle>
|
|
119
|
+
</StyledLink>
|
|
120
|
+
</ItemTopicHeader>
|
|
121
|
+
) : (
|
|
122
|
+
<ItemResourceHeader labels={labels} img={img} type={type} />
|
|
123
|
+
)}
|
|
124
|
+
<ContentWrapper>
|
|
125
|
+
{!isTopic && (
|
|
126
|
+
<StyledLink to={url} ref={linkRef}>
|
|
127
|
+
<ItemTitle>{title}</ItemTitle>
|
|
128
|
+
</StyledLink>
|
|
129
|
+
)}
|
|
130
|
+
<ItemText isTopic={isTopic}>{parse(ingress)}</ItemText>
|
|
131
|
+
{contexts.length > 0 && <ItemContexts contexts={contexts} id={item.id} title={item.title} />}
|
|
132
|
+
</ContentWrapper>
|
|
149
133
|
</Container>
|
|
150
134
|
);
|
|
151
135
|
};
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import React, { memo } from 'react';
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
|
+
import { css } from '@emotion/react';
|
|
11
12
|
import { breakpoints, mq, spacing } from '@ndla/core';
|
|
12
13
|
import SearchItem, { SearchItemProps } from './SearchItem';
|
|
13
14
|
import { ContentType } from './SearchTypeResult';
|
|
@@ -18,41 +19,49 @@ const Wrapper = styled.div`
|
|
|
18
19
|
position: relative;
|
|
19
20
|
`;
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
interface ContainerProps {
|
|
22
23
|
viewType: Props['viewType'];
|
|
23
|
-
}
|
|
24
|
+
}
|
|
24
25
|
|
|
25
|
-
const Container = styled.
|
|
26
|
+
const Container = styled.ul<ContainerProps>`
|
|
26
27
|
display: grid;
|
|
28
|
+
align-items: flex-start;
|
|
29
|
+
list-style: none;
|
|
27
30
|
row-gap: ${spacing.normal};
|
|
28
31
|
grid-template-columns: repeat(1, 1fr);
|
|
29
32
|
|
|
30
33
|
${(props) =>
|
|
31
34
|
props.viewType === 'grid' &&
|
|
32
|
-
`
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
css`
|
|
36
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
37
|
+
column-gap: ${spacing.normal};
|
|
38
|
+
grid-template-columns: repeat(2, 1fr);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
42
|
+
grid-template-columns: repeat(3, 1fr);
|
|
43
|
+
}
|
|
44
|
+
`}
|
|
41
45
|
`;
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
interface Props {
|
|
44
48
|
items: SearchItemProps[];
|
|
45
49
|
type?: ContentType;
|
|
46
50
|
viewType?: 'grid' | 'list';
|
|
47
|
-
}
|
|
51
|
+
}
|
|
52
|
+
|
|
48
53
|
const SearchItems = ({ items, type, viewType = 'grid' }: Props) => {
|
|
49
54
|
return (
|
|
50
55
|
<Wrapper>
|
|
51
|
-
<Container viewType={viewType}>
|
|
56
|
+
<Container aria-labelledby={`searchitem-header-${type}`} viewType={viewType}>
|
|
52
57
|
{items.map((item) => {
|
|
53
58
|
const contentType = type || item.type;
|
|
54
59
|
const Component = viewType === 'list' ? SearchItemList : SearchItem;
|
|
55
|
-
return
|
|
60
|
+
return (
|
|
61
|
+
<li key={`${item.id}`}>
|
|
62
|
+
<Component item={item} type={contentType} />
|
|
63
|
+
</li>
|
|
64
|
+
);
|
|
56
65
|
})}
|
|
57
66
|
</Container>
|
|
58
67
|
</Wrapper>
|
|
@@ -42,10 +42,13 @@ const BadgeWrapper = styled.span`
|
|
|
42
42
|
margin-right: ${spacing.small};
|
|
43
43
|
`;
|
|
44
44
|
|
|
45
|
-
const SubjectName = styled.
|
|
45
|
+
const SubjectName = styled.div`
|
|
46
|
+
display: flex;
|
|
47
|
+
gap: ${spacing.small};
|
|
46
48
|
${fonts.sizes('18px', '24px')};
|
|
47
49
|
margin: 2px 0;
|
|
48
|
-
|
|
50
|
+
h2 {
|
|
51
|
+
margin: 0;
|
|
49
52
|
${fonts.sizes('18px', '24px')};
|
|
50
53
|
margin-right: 4px;
|
|
51
54
|
}
|
|
@@ -97,7 +100,9 @@ const SearchTypeHeader = ({ filters = [], onFilterClick, totalCount, type }: Pro
|
|
|
97
100
|
</BadgeWrapper>
|
|
98
101
|
)}
|
|
99
102
|
<SubjectName>
|
|
100
|
-
<
|
|
103
|
+
<h2 id={`searchitem-header-${type}`}>
|
|
104
|
+
{type ? t(`contentTypes.${type}`) : t(`searchPage.resultType.allContentTypes`)}
|
|
105
|
+
</h2>
|
|
101
106
|
{totalCount && <Count>{t(`searchPage.resultType.hits`, { count: totalCount })}</Count>}
|
|
102
107
|
</SubjectName>
|
|
103
108
|
</TypeWrapper>
|
|
@@ -107,6 +112,7 @@ const SearchTypeHeader = ({ filters = [], onFilterClick, totalCount, type }: Pro
|
|
|
107
112
|
{filters.map((option: FilterOptionsType) => (
|
|
108
113
|
<CategoryTypeButtonWrapper key={option.id}>
|
|
109
114
|
<Button
|
|
115
|
+
aria-current={option.active}
|
|
110
116
|
size="xsmall"
|
|
111
117
|
borderShape="rounded"
|
|
112
118
|
greyLighter={!option.active}
|
|
@@ -16,7 +16,7 @@ import SearchItems from './SearchItems';
|
|
|
16
16
|
import { SearchItemProps } from './SearchItem';
|
|
17
17
|
import ResultNavigation, { PaginationType } from './ResultNavigation';
|
|
18
18
|
|
|
19
|
-
const Wrapper = styled.
|
|
19
|
+
const Wrapper = styled.section`
|
|
20
20
|
display: flex;
|
|
21
21
|
flex-direction: column;
|
|
22
22
|
flex: 1;
|
|
@@ -81,7 +81,7 @@ const SearchTypeResult = ({
|
|
|
81
81
|
)}
|
|
82
82
|
<SearchTypeHeader onFilterClick={onFilterClick} filters={filters} totalCount={totalCount} type={type} />
|
|
83
83
|
<SearchItems items={items} type={type} viewType={viewType} />
|
|
84
|
-
{pagination && <ResultNavigation {...pagination} />}
|
|
84
|
+
{pagination && <ResultNavigation {...pagination} type={type} />}
|
|
85
85
|
{children}
|
|
86
86
|
</Wrapper>
|
|
87
87
|
);
|
|
@@ -11,8 +11,8 @@ import SafeLink from '@ndla/safelink';
|
|
|
11
11
|
import { Additional, Core } from '@ndla/icons/common';
|
|
12
12
|
import styled from '@emotion/styled';
|
|
13
13
|
import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
|
|
14
|
-
import
|
|
15
|
-
import
|
|
14
|
+
import { ButtonV2 } from '@ndla/button';
|
|
15
|
+
import { ModalV2, ModalCloseButton } from '@ndla/modal';
|
|
16
16
|
import { useTranslation } from 'react-i18next';
|
|
17
17
|
|
|
18
18
|
const BreadcrumbPath = styled.div`
|
|
@@ -24,7 +24,9 @@ const BreadcrumbPath = styled.div`
|
|
|
24
24
|
}
|
|
25
25
|
`;
|
|
26
26
|
|
|
27
|
-
const ModalButton = styled(
|
|
27
|
+
const ModalButton = styled(ButtonV2)`
|
|
28
|
+
z-index: 1;
|
|
29
|
+
position: relative;
|
|
28
30
|
${fonts.sizes('14px', '20px')};
|
|
29
31
|
box-shadow: none;
|
|
30
32
|
&:hover {
|
|
@@ -97,19 +99,17 @@ const ItemContexts = ({ contexts, id, title }: ItemContextsType) => {
|
|
|
97
99
|
<Breadcrumb breadcrumb={mainContext.breadcrumb}>
|
|
98
100
|
|
|
99
101
|
{contexts.length > 1 && (
|
|
100
|
-
<
|
|
102
|
+
<ModalV2
|
|
101
103
|
label={t('searchPage.contextModal.ariaLabel')}
|
|
102
104
|
activateButton={
|
|
103
|
-
<ModalButton link>
|
|
105
|
+
<ModalButton variant="link">
|
|
104
106
|
{t('searchPage.contextModal.button', {
|
|
105
107
|
count: contexts.length - 1,
|
|
106
108
|
})}
|
|
107
109
|
</ModalButton>
|
|
108
110
|
}
|
|
109
111
|
animation="subtle"
|
|
110
|
-
animationDuration={50}
|
|
111
|
-
backgroundColor="white"
|
|
112
|
-
size="medium">
|
|
112
|
+
animationDuration={50}>
|
|
113
113
|
{(onClose: () => void) => (
|
|
114
114
|
<>
|
|
115
115
|
<ModalHeader>
|
|
@@ -130,7 +130,7 @@ const ItemContexts = ({ contexts, id, title }: ItemContextsType) => {
|
|
|
130
130
|
</ModalContent>
|
|
131
131
|
</>
|
|
132
132
|
)}
|
|
133
|
-
</
|
|
133
|
+
</ModalV2>
|
|
134
134
|
)}
|
|
135
135
|
</Breadcrumb>
|
|
136
136
|
);
|
|
@@ -18,29 +18,20 @@ import { SearchItemType } from '../SearchItem';
|
|
|
18
18
|
import resourceTypeColor from '../../utils/resourceTypeColor';
|
|
19
19
|
import ContentTypeBadge from '../../ContentTypeBadge';
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
interface ItemTypeProps {
|
|
22
22
|
contentType?: ContentType;
|
|
23
|
-
}
|
|
23
|
+
}
|
|
24
24
|
|
|
25
25
|
const ImageElement = styled.img`
|
|
26
26
|
width: 100%;
|
|
27
27
|
height: 100%;
|
|
28
28
|
object-fit: cover;
|
|
29
|
-
`;
|
|
30
|
-
|
|
31
|
-
const ImageWrapper = styled.div`
|
|
32
|
-
flex: 1;
|
|
33
|
-
border-top-left-radius: 5px;
|
|
34
|
-
border-top-right-radius: 5px;
|
|
35
29
|
overflow: hidden;
|
|
36
30
|
`;
|
|
37
31
|
|
|
38
32
|
const NoImageElement = styled.div<ItemTypeProps>`
|
|
39
|
-
border-top-left-radius: 5px;
|
|
40
|
-
border-top-right-radius: 5px;
|
|
41
33
|
flex: 1;
|
|
42
34
|
background: ${(props) => props.contentType && `${resourceTypeColor(props.contentType)}`};
|
|
43
|
-
position: relative;
|
|
44
35
|
display: flex;
|
|
45
36
|
align-items: center;
|
|
46
37
|
justify-content: center;
|
|
@@ -59,7 +50,6 @@ const NoImageElement = styled.div<ItemTypeProps>`
|
|
|
59
50
|
const ContentTypeWrapper = styled.div<ItemTypeProps>`
|
|
60
51
|
height: 48px;
|
|
61
52
|
background: ${(props) => props.contentType && `${resourceTypeColor(props.contentType)}`};
|
|
62
|
-
flex: 0 0 auto;
|
|
63
53
|
position: relative;
|
|
64
54
|
display: flex;
|
|
65
55
|
align-items: center;
|
|
@@ -69,47 +59,59 @@ const ContentTypeWrapper = styled.div<ItemTypeProps>`
|
|
|
69
59
|
`;
|
|
70
60
|
|
|
71
61
|
const ContentTypeIcon = styled.span<ItemTypeProps>`
|
|
62
|
+
display: flex;
|
|
72
63
|
position: absolute;
|
|
73
|
-
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='78' height='23' viewBox='17 0 78 23' fill='none'%3E%3Cpath d='M35.6874 10.8284C37.0999 8.9889 38.405 7.28934 40 6C44.8452 2.08335 48.9078 0 56 0C63.0922 0 67.6548 2.5833 72.5 6.49995C74.0499 7.75284 75.2937 9.39082 76.6385 11.1617C80.0028 15.5921 83.9988 20.8545 95 23H17C27.9865 20.8573 32.1701 15.409 35.6874 10.8284ZM352' fill='${(
|
|
74
|
-
props,
|
|
75
|
-
) => props.contentType && `${encodeURIComponent(resourceTypeColor(props.contentType))}`}'/%3E%3C/svg%3E");
|
|
76
|
-
background-position: top;
|
|
77
|
-
background-repeat: no-repeat;
|
|
78
|
-
left: 17px;
|
|
79
64
|
top: -23px;
|
|
80
|
-
|
|
81
|
-
width: 78px;
|
|
82
|
-
display: flex;
|
|
65
|
+
margin-left: ${spacing.small};
|
|
83
66
|
justify-content: center;
|
|
84
|
-
|
|
85
|
-
|
|
67
|
+
::before {
|
|
68
|
+
content: '';
|
|
69
|
+
position: absolute;
|
|
70
|
+
height: 23px;
|
|
71
|
+
width: 78px;
|
|
72
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='78' height='23' viewBox='17 0 78 23' fill='none'%3E%3Cpath d='M35.6874 10.8284C37.0999 8.9889 38.405 7.28934 40 6C44.8452 2.08335 48.9078 0 56 0C63.0922 0 67.6548 2.5833 72.5 6.49995C74.0499 7.75284 75.2937 9.39082 76.6385 11.1617C80.0028 15.5921 83.9988 20.8545 95 23H17C27.9865 20.8573 32.1701 15.409 35.6874 10.8284ZM352' fill='${(
|
|
73
|
+
props,
|
|
74
|
+
) => props.contentType && `${encodeURIComponent(resourceTypeColor(props.contentType))}`}'/%3E%3C/svg%3E");
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
const StyledContentTypeBadge = styled(ContentTypeBadge)`
|
|
79
|
+
z-index: 1;
|
|
80
|
+
margin-top: ${spacing.xxsmall};
|
|
81
|
+
|
|
86
82
|
svg {
|
|
87
83
|
width: 20px;
|
|
88
84
|
height: 20px;
|
|
89
85
|
}
|
|
90
86
|
`;
|
|
91
87
|
|
|
92
|
-
|
|
88
|
+
const Wrapper = styled.header`
|
|
89
|
+
display: grid;
|
|
90
|
+
grid-template-rows: 1fr auto;
|
|
91
|
+
overflow: hidden;
|
|
92
|
+
flex-direction: column;
|
|
93
|
+
height: 180px;
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
interface Props {
|
|
93
97
|
labels: SearchItemType['item']['labels'];
|
|
94
98
|
img?: SearchItemType['item']['img'] | null;
|
|
95
99
|
type?: ContentType;
|
|
96
|
-
}
|
|
100
|
+
}
|
|
97
101
|
|
|
98
102
|
const ItemResourceHeader = ({ labels = [], img, type }: Props) => {
|
|
99
103
|
const { t } = useTranslation();
|
|
100
104
|
return (
|
|
101
|
-
|
|
105
|
+
<Wrapper>
|
|
102
106
|
{img ? (
|
|
103
|
-
<
|
|
104
|
-
<ImageElement src={img.url} alt={img.alt} />
|
|
105
|
-
</ImageWrapper>
|
|
107
|
+
<ImageElement src={img.url} alt={img.alt} />
|
|
106
108
|
) : (
|
|
107
109
|
<NoImageElement contentType={type}>{type && <ContentTypeBadge type={type} border={false} />}</NoImageElement>
|
|
108
110
|
)}
|
|
109
111
|
<ContentTypeWrapper className="resource-type-wrapper" contentType={type}>
|
|
110
112
|
{img && type && (
|
|
111
113
|
<ContentTypeIcon className="resource-icon-wrapper" contentType={type}>
|
|
112
|
-
<
|
|
114
|
+
<StyledContentTypeBadge type={type} border={false} />
|
|
113
115
|
</ContentTypeIcon>
|
|
114
116
|
)}
|
|
115
117
|
{type && t(`contentTypes.${type}`)}
|
|
@@ -124,7 +126,7 @@ const ItemResourceHeader = ({ labels = [], img, type }: Props) => {
|
|
|
124
126
|
</>
|
|
125
127
|
)}
|
|
126
128
|
</ContentTypeWrapper>
|
|
127
|
-
|
|
129
|
+
</Wrapper>
|
|
128
130
|
);
|
|
129
131
|
};
|
|
130
132
|
|
|
@@ -15,11 +15,8 @@ import { SearchItemType } from '../SearchItem';
|
|
|
15
15
|
import ContentTypeBadge from '../../ContentTypeBadge';
|
|
16
16
|
import { ContentType } from '../SearchTypeResult';
|
|
17
17
|
|
|
18
|
-
const Wrapper = styled.
|
|
19
|
-
padding: ${spacing.small} ${spacing.normal};
|
|
20
|
-
position: relative;
|
|
21
|
-
min-height: 0;
|
|
22
|
-
flex: 1;
|
|
18
|
+
const Wrapper = styled.header`
|
|
19
|
+
padding: ${spacing.small} ${spacing.normal} 0;
|
|
23
20
|
`;
|
|
24
21
|
|
|
25
22
|
const Label = styled.div`
|
|
@@ -28,7 +25,7 @@ const Label = styled.div`
|
|
|
28
25
|
height: 26px;
|
|
29
26
|
display: flex;
|
|
30
27
|
align-items: center;
|
|
31
|
-
margin
|
|
28
|
+
margin: ${spacing.small} 0;
|
|
32
29
|
|
|
33
30
|
.c-content-type-badge {
|
|
34
31
|
width: 26px;
|
|
@@ -46,15 +43,11 @@ const Label = styled.div`
|
|
|
46
43
|
const TopicHeaderVisualElementWrapper = styled.div`
|
|
47
44
|
float: right;
|
|
48
45
|
margin-left: ${spacing.small};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
height: 112px;
|
|
46
|
+
width: 110px;
|
|
47
|
+
height: 110px;
|
|
52
48
|
display: flex;
|
|
53
|
-
justify-content: center;
|
|
54
|
-
align-items: center;
|
|
55
49
|
overflow: hidden;
|
|
56
50
|
border-radius: 50%;
|
|
57
|
-
-webkit-mask-image: -webkit-radial-gradient(white, black);
|
|
58
51
|
`;
|
|
59
52
|
|
|
60
53
|
const TopicHeaderImage = styled.img`
|
|
@@ -64,18 +57,19 @@ const TopicHeaderImage = styled.img`
|
|
|
64
57
|
max-width: unset;
|
|
65
58
|
`;
|
|
66
59
|
|
|
67
|
-
|
|
60
|
+
interface Props {
|
|
68
61
|
children: ReactNode;
|
|
69
62
|
image?: SearchItemType['item']['img'] | null;
|
|
70
63
|
type?: ContentType;
|
|
71
|
-
}
|
|
64
|
+
}
|
|
65
|
+
|
|
72
66
|
const ItemTopicHeader = ({ children, image, type }: Props) => {
|
|
73
67
|
const { t } = useTranslation();
|
|
74
68
|
return (
|
|
75
69
|
<Wrapper>
|
|
76
70
|
{image && (
|
|
77
71
|
<TopicHeaderVisualElementWrapper>
|
|
78
|
-
<TopicHeaderImage className="topic-header-image" src={image.url} alt=
|
|
72
|
+
<TopicHeaderImage className="topic-header-image" src={image.url} alt="" />
|
|
79
73
|
</TopicHeaderVisualElementWrapper>
|
|
80
74
|
)}
|
|
81
75
|
<Label className="topic-label">
|
|
@@ -335,7 +335,7 @@ const messages = {
|
|
|
335
335
|
multidisciplinarySubjects: 'Multidisciplinary subjects',
|
|
336
336
|
toolboxStudents: 'Toolbox - for students',
|
|
337
337
|
toolboxTeachers: 'Toolbox - for teachers',
|
|
338
|
-
film: 'NDLA
|
|
338
|
+
film: 'NDLA film',
|
|
339
339
|
about: {
|
|
340
340
|
title: 'About NDLA',
|
|
341
341
|
numbers: 'Numbers and reports',
|
|
@@ -793,7 +793,7 @@ const messages = {
|
|
|
793
793
|
loadingMovies: 'Loading movies..',
|
|
794
794
|
subjectsInMovies: 'Subjects in film',
|
|
795
795
|
about: {
|
|
796
|
-
heading: 'About NDLA
|
|
796
|
+
heading: 'About NDLA film',
|
|
797
797
|
more: 'Read more about NDLA film',
|
|
798
798
|
text: 'Ndla film er ei nettbasert filmtjeneste for elever og lærere i videregående skole. Her finn du spillefilmer, kortfilmer, dokumentarfilmer og TV-serier.',
|
|
799
799
|
},
|
|
@@ -835,7 +835,7 @@ const messages = {
|
|
|
835
835
|
},
|
|
836
836
|
allMovieGroupTitleLabel: 'Movies starting with {{letter}}',
|
|
837
837
|
moreAboutNdlaFilm: {
|
|
838
|
-
header: 'NDLA
|
|
838
|
+
header: 'NDLA film',
|
|
839
839
|
firstParagraph:
|
|
840
840
|
"The films in the film service are taken from Norwegian and international film heritage and are linked to curricula in several subjects. They have been selected by NDLA's editors in collaboration with Norgesfilm AS.",
|
|
841
841
|
secondParagraph:
|
|
@@ -334,7 +334,7 @@ const messages = {
|
|
|
334
334
|
multidisciplinarySubjects: 'Tverrfaglige tema',
|
|
335
335
|
toolboxStudents: 'Verktøykassa - for elever',
|
|
336
336
|
toolboxTeachers: 'Verktøykassa - for lærere',
|
|
337
|
-
film: 'NDLA
|
|
337
|
+
film: 'NDLA film',
|
|
338
338
|
about: {
|
|
339
339
|
title: 'Om NDLA',
|
|
340
340
|
numbers: 'Tall og rapporter',
|
|
@@ -792,7 +792,7 @@ const messages = {
|
|
|
792
792
|
loadingMovies: 'Henter filmer...',
|
|
793
793
|
subjectsInMovies: 'Emner i film',
|
|
794
794
|
about: {
|
|
795
|
-
heading: 'Om NDLA
|
|
795
|
+
heading: 'Om NDLA film',
|
|
796
796
|
more: 'Les mer om NDLA film',
|
|
797
797
|
text: 'Ndla film er en nettbasert filmtjeneste for elever og lærere i videregående skole. Her funner du spillefilmer, kortfilmer, dokumentarfilmer og TV-serier.',
|
|
798
798
|
},
|
|
@@ -834,7 +834,7 @@ const messages = {
|
|
|
834
834
|
},
|
|
835
835
|
allMovieGroupTitleLabel: 'Filmer som starter på {{letter}}',
|
|
836
836
|
moreAboutNdlaFilm: {
|
|
837
|
-
header: 'NDLA
|
|
837
|
+
header: 'NDLA film',
|
|
838
838
|
firstParagraph:
|
|
839
839
|
'Filmene i filmtjenesten er hentet fra norsk og internasjonal filmarv og kobles mot læreplaner i flere fag. De er valgt ut av NDLAs redaksjoner i samarbeid med Norgesfilm AS.',
|
|
840
840
|
secondParagraph:
|
|
@@ -334,7 +334,7 @@ const messages = {
|
|
|
334
334
|
multidisciplinarySubjects: 'Tverrfaglege tema',
|
|
335
335
|
toolboxStudents: 'Verktøykassa - for elevar',
|
|
336
336
|
toolboxTeachers: 'Verktøykassa - for lærarar',
|
|
337
|
-
film: 'NDLA
|
|
337
|
+
film: 'NDLA film',
|
|
338
338
|
about: {
|
|
339
339
|
title: 'Om NDLA',
|
|
340
340
|
numbers: 'Tall og rapporter',
|
|
@@ -792,7 +792,7 @@ const messages = {
|
|
|
792
792
|
loadingMovies: 'Hentar filmar...',
|
|
793
793
|
subjectsInMovies: 'Emne i film',
|
|
794
794
|
about: {
|
|
795
|
-
heading: 'Om NDLA
|
|
795
|
+
heading: 'Om NDLA film',
|
|
796
796
|
more: 'Les meir om NDLA film',
|
|
797
797
|
text: 'NDLA film er ei nettbasert filmteneste for elevar og lærarar i vidaregåande skule. Her finn du spelefilmar, kortfilmar, dokumentarfilmar og TV-seriar.',
|
|
798
798
|
},
|
|
@@ -834,7 +834,7 @@ const messages = {
|
|
|
834
834
|
},
|
|
835
835
|
allMovieGroupTitleLabel: 'Filmar som startar på {{letter}}',
|
|
836
836
|
moreAboutNdlaFilm: {
|
|
837
|
-
header: 'NDLA
|
|
837
|
+
header: 'NDLA film',
|
|
838
838
|
firstParagraph:
|
|
839
839
|
'Filmane i filmtenesta er henta frå norsk og internasjonal filmarv og er kopla mot læreplanar i fleire fag. Dei er valde av redaksjonane til NDLA i samarbeid med Norgesfilm AS.',
|
|
840
840
|
secondParagraph:
|