@ndla/ui 25.0.2 → 25.1.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/FrontpageSearch.js +5 -3
- package/es/NDLAFilm/FilmSlideshow.js +7 -7
- package/es/NDLAFilm/NavigationArrow.js +4 -4
- package/es/Notion/FigureNotion.js +4 -3
- package/es/Notion/NotionVisualElement.js +3 -2
- package/es/SectionHeading/SectionHeading.js +4 -3
- package/es/Subject/Subject.js +109 -64
- package/es/Subject/SubjectAbout.js +61 -23
- package/es/Subject/SubjectArchive.js +109 -67
- package/es/Subject/SubjectCarousel.js +39 -62
- package/es/Subject/SubjectHeader.js +55 -25
- package/es/Subject/SubjectLinks.js +30 -16
- package/es/Subject/SubjectNewContent.js +76 -21
- package/es/Subject/SubjectShortcuts.js +39 -24
- package/es/Subject/SubjectSocial.js +20 -18
- package/es/all.css +1 -1
- package/es/locale/messages-nb.js +21 -21
- package/es/locale/messages-nn.js +27 -27
- package/es/locale/messages-se.js +22 -22
- package/es/locale/messages-sma.js +22 -22
- package/lib/Frontpage/FrontpageSearch.js +6 -3
- package/lib/NDLAFilm/FilmSlideshow.js +7 -7
- package/lib/NDLAFilm/NavigationArrow.js +4 -4
- package/lib/Notion/FigureNotion.d.ts +2 -1
- package/lib/Notion/FigureNotion.js +4 -3
- package/lib/Notion/NotionVisualElement.d.ts +1 -0
- package/lib/Notion/NotionVisualElement.js +3 -2
- package/lib/SectionHeading/SectionHeading.js +4 -3
- package/lib/Subject/Subject.d.ts +30 -82
- package/lib/Subject/Subject.js +90 -62
- package/lib/Subject/SubjectAbout.d.ts +1 -15
- package/lib/Subject/SubjectAbout.js +56 -25
- package/lib/Subject/SubjectArchive.d.ts +0 -21
- package/lib/Subject/SubjectArchive.js +103 -73
- package/lib/Subject/SubjectCarousel.d.ts +1 -31
- package/lib/Subject/SubjectCarousel.js +47 -76
- package/lib/Subject/SubjectHeader.d.ts +1 -14
- package/lib/Subject/SubjectHeader.js +53 -28
- package/lib/Subject/SubjectLinks.d.ts +1 -11
- package/lib/Subject/SubjectLinks.js +29 -19
- package/lib/Subject/SubjectNewContent.d.ts +1 -13
- package/lib/Subject/SubjectNewContent.js +70 -24
- package/lib/Subject/SubjectShortcuts.d.ts +0 -13
- package/lib/Subject/SubjectShortcuts.js +38 -29
- package/lib/Subject/SubjectSocial.d.ts +7 -22
- package/lib/Subject/SubjectSocial.js +19 -21
- package/lib/all.css +1 -1
- package/lib/locale/messages-nb.js +21 -21
- package/lib/locale/messages-nn.js +27 -27
- package/lib/locale/messages-se.js +22 -22
- package/lib/locale/messages-sma.js +22 -22
- package/package.json +14 -14
- package/src/Frontpage/FrontpageSearch.tsx +3 -1
- package/src/NDLAFilm/FilmSlideshow.tsx +2 -0
- package/src/NDLAFilm/NavigationArrow.tsx +4 -4
- package/src/Notion/FigureNotion.tsx +5 -2
- package/src/Notion/NotionVisualElement.tsx +2 -0
- package/src/SectionHeading/SectionHeading.tsx +6 -2
- package/src/Subject/Subject.tsx +151 -72
- package/src/Subject/SubjectAbout.tsx +97 -27
- package/src/Subject/SubjectArchive.tsx +129 -58
- package/src/Subject/SubjectCarousel.tsx +42 -36
- package/src/Subject/SubjectHeader.tsx +75 -34
- package/src/Subject/SubjectLinks.tsx +21 -19
- package/src/Subject/SubjectNewContent.tsx +87 -32
- package/src/Subject/SubjectShortcuts.tsx +67 -27
- package/src/Subject/SubjectSocial.tsx +19 -20
- package/src/locale/messages-nb.ts +21 -22
- package/src/locale/messages-nn.ts +27 -27
- package/src/locale/messages-se.ts +22 -23
- package/src/locale/messages-sma.ts +22 -23
- package/src/main.scss +0 -1
- package/src/.DS_Store +0 -0
- package/src/Subject/component.subject-about.scss +0 -73
- package/src/Subject/component.subject-archive.scss +0 -92
- package/src/Subject/component.subject-carousel.scss +0 -32
- package/src/Subject/component.subject-concepts.scss +0 -37
- package/src/Subject/component.subject-header.scss +0 -87
- package/src/Subject/component.subject-links.scss +0 -14
- package/src/Subject/component.subject-new-content.scss +0 -82
- package/src/Subject/component.subject-shortcut.scss +0 -57
- package/src/Subject/component.subject.scss +0 -213
package/src/Subject/Subject.tsx
CHANGED
|
@@ -1,11 +1,76 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
2
|
+
import styled from '@emotion/styled';
|
|
3
|
+
import { css } from '@emotion/core';
|
|
4
|
+
import { breakpoints, colors, mq, spacing, spacingUnit } from '@ndla/core';
|
|
5
5
|
import SectionHeading from '../SectionHeading';
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
7
|
+
const SubjectContentWrapper = styled.div`
|
|
8
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
9
|
+
margin-bottom: 100px;
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
const StyledBreadcrumb = styled.div`
|
|
14
|
+
display: none;
|
|
15
|
+
margin: ${spacing.medium} 0 0 0;
|
|
16
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
17
|
+
display: block;
|
|
18
|
+
margin-left: ${spacingUnit * 3}px;
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
interface StyledSubjectContentProps {
|
|
23
|
+
twoColumns: boolean;
|
|
24
|
+
}
|
|
25
|
+
const StyledSubjectContent = styled.div<StyledSubjectContentProps>`
|
|
26
|
+
display: block;
|
|
27
|
+
flex-flow: column;
|
|
28
|
+
margin-top: ${spacing.small};
|
|
29
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-flow: row;
|
|
32
|
+
margin-top: ${spacing.large};
|
|
33
|
+
> *:not(:only-child):last-child {
|
|
34
|
+
padding-left: ${spacingUnit * 3}px;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
& > *:first-child {
|
|
39
|
+
margin-bottom: ${spacing.large};
|
|
40
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
41
|
+
margin-right: 80px;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
${(p) =>
|
|
46
|
+
!p.twoColumns &&
|
|
47
|
+
css`
|
|
48
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
49
|
+
> *:not(:only-child) {
|
|
50
|
+
max-width: 50%;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
${mq.range({ until: breakpoints.desktop })} {
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
}
|
|
56
|
+
${mq.range({ from: breakpoints.tablet, until: breakpoints.desktop })} {
|
|
57
|
+
> *:not(:only-child):last-child {
|
|
58
|
+
padding-left: $subject-margin;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
`};
|
|
62
|
+
|
|
63
|
+
${(p) =>
|
|
64
|
+
p.twoColumns &&
|
|
65
|
+
css`
|
|
66
|
+
flex-flow: column;
|
|
67
|
+
& > *:first-child {
|
|
68
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
69
|
+
margin-right: 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
`};
|
|
73
|
+
`;
|
|
9
74
|
export const SubjectContent = ({
|
|
10
75
|
children,
|
|
11
76
|
breadcrumb,
|
|
@@ -15,102 +80,116 @@ export const SubjectContent = ({
|
|
|
15
80
|
breadcrumb: ReactNode;
|
|
16
81
|
twoColumns?: boolean;
|
|
17
82
|
}) => (
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
</
|
|
83
|
+
<SubjectContentWrapper>
|
|
84
|
+
<StyledBreadcrumb>{breadcrumb}</StyledBreadcrumb>
|
|
85
|
+
<StyledSubjectContent twoColumns={twoColumns}>{children}</StyledSubjectContent>
|
|
86
|
+
</SubjectContentWrapper>
|
|
22
87
|
);
|
|
23
88
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
89
|
+
const StyledSecondaryContent = styled.div`
|
|
90
|
+
background: ${colors.brand.greyLightest};
|
|
91
|
+
padding: ${spacing.large} 0;
|
|
92
|
+
margin-top: ${spacing.large};
|
|
29
93
|
|
|
30
|
-
|
|
94
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
95
|
+
padding: ${spacingUnit * 3}px 0 ${spacing.large};
|
|
96
|
+
margin-bottom: 100px;
|
|
97
|
+
margin-top: 0;
|
|
98
|
+
}
|
|
99
|
+
`;
|
|
31
100
|
|
|
32
101
|
export const SubjectSecondaryContent = ({ children }: { children: ReactNode }) => (
|
|
33
|
-
<
|
|
102
|
+
<StyledSecondaryContent>{children}</StyledSecondaryContent>
|
|
34
103
|
);
|
|
35
104
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const childContentClasses = BEMHelper('c-subject-child-content');
|
|
105
|
+
const StyledChildContent = styled.div`
|
|
106
|
+
padding: 0 ${spacing.normal};
|
|
107
|
+
`;
|
|
41
108
|
|
|
42
109
|
export const SubjectChildContent = ({ children }: { children: ReactNode }) => (
|
|
43
|
-
<
|
|
110
|
+
<StyledChildContent>{children}</StyledChildContent>
|
|
44
111
|
);
|
|
45
112
|
|
|
46
|
-
SubjectChildContent.propTypes = {
|
|
47
|
-
children: PropTypes.node.isRequired,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const topicClasses = BEMHelper('c-subject-topics');
|
|
51
|
-
|
|
52
113
|
export const SubjectTopics = ({ messages, children }: { messages: { heading: string }; children: ReactNode }) => (
|
|
53
|
-
<section
|
|
54
|
-
<header
|
|
55
|
-
<h1
|
|
114
|
+
<section>
|
|
115
|
+
<header>
|
|
116
|
+
<h1>{messages.heading}</h1>
|
|
56
117
|
</header>
|
|
57
|
-
<div
|
|
118
|
+
<div>{children}</div>
|
|
58
119
|
</section>
|
|
59
120
|
);
|
|
60
121
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
122
|
+
const SidebarWrapper = styled.div`
|
|
123
|
+
display: block;
|
|
124
|
+
margin: 0 ${spacing.normal};
|
|
125
|
+
|
|
126
|
+
& > *:last-child {
|
|
127
|
+
margin-bottom: 0;
|
|
128
|
+
}
|
|
67
129
|
|
|
68
|
-
|
|
130
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
131
|
+
flex-basis: 390px;
|
|
132
|
+
flex-shrink: 0;
|
|
133
|
+
margin: 0px 0 0 0;
|
|
134
|
+
}
|
|
135
|
+
`;
|
|
69
136
|
|
|
70
137
|
export const SubjectSidebarWrapper = ({ children }: { children: ReactNode }) => (
|
|
71
|
-
<
|
|
138
|
+
<SidebarWrapper>{children}</SidebarWrapper>
|
|
72
139
|
);
|
|
73
140
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
141
|
+
interface StyledSubjectFlexWrapperProps {
|
|
142
|
+
noMargin: boolean;
|
|
143
|
+
}
|
|
144
|
+
const StyledSubjectFlexWrapper = styled.div<StyledSubjectFlexWrapperProps>`
|
|
145
|
+
display: flex;
|
|
146
|
+
flex-direction: column;
|
|
147
|
+
margin-bottom: ${(p) => !p.noMargin && spacing.large};
|
|
77
148
|
|
|
78
|
-
|
|
149
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
150
|
+
flex-direction: row;
|
|
151
|
+
}
|
|
152
|
+
`;
|
|
79
153
|
|
|
80
154
|
export const SubjectFlexWrapper = ({ children, noMargin = false }: { children: ReactNode; noMargin?: boolean }) => (
|
|
81
|
-
<
|
|
155
|
+
<StyledSubjectFlexWrapper noMargin={noMargin}>{children}</StyledSubjectFlexWrapper>
|
|
82
156
|
);
|
|
83
157
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
158
|
+
const StyledSubjectFlexChild = styled.div`
|
|
159
|
+
box-sizing: border-box;
|
|
160
|
+
padding: 0 ${spacing.small};
|
|
161
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
162
|
+
flex-basis: 50%;
|
|
163
|
+
flex-grow: 1;
|
|
164
|
+
flex-direction: row;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
&:last-child {
|
|
168
|
+
& > * {
|
|
169
|
+
${mq.range({ until: breakpoints.tablet })} {
|
|
170
|
+
margin-bottom: 0;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
& > * {
|
|
175
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
176
|
+
margin-bottom: o;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
88
180
|
|
|
89
181
|
export const SubjectFlexChild = ({ children }: { children: ReactNode }) => (
|
|
90
|
-
<
|
|
182
|
+
<StyledSubjectFlexChild>{children}</StyledSubjectFlexChild>
|
|
91
183
|
);
|
|
92
184
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
};
|
|
185
|
+
const StyledSectionHeading = styled(SectionHeading)`
|
|
186
|
+
margin: 0 0 ${spacing.small} 0;
|
|
96
187
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
children: ReactNode;
|
|
102
|
-
className?: string | null;
|
|
103
|
-
}) => (
|
|
104
|
-
<SectionHeading large className={`c-subject-section-title ${className}`}>
|
|
105
|
-
{children}
|
|
106
|
-
</SectionHeading>
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
SubjectSectionTitle.propTypes = {
|
|
110
|
-
children: PropTypes.string.isRequired,
|
|
111
|
-
className: PropTypes.string,
|
|
112
|
-
};
|
|
188
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
189
|
+
margin: 0 0 ${spacing.normal} 0;
|
|
190
|
+
}
|
|
191
|
+
`;
|
|
113
192
|
|
|
114
|
-
SubjectSectionTitle
|
|
115
|
-
|
|
116
|
-
|
|
193
|
+
export const SubjectSectionTitle = ({ children }: { children: ReactNode }) => (
|
|
194
|
+
<StyledSectionHeading large>{children}</StyledSectionHeading>
|
|
195
|
+
);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { css } from '@emotion/core';
|
|
3
|
+
import styled from '@emotion/styled';
|
|
4
|
+
import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
|
|
4
5
|
import SectionHeading from '../SectionHeading';
|
|
5
6
|
|
|
6
|
-
const classes = BEMHelper('c-subject-about');
|
|
7
|
-
|
|
8
7
|
interface Props {
|
|
9
8
|
fixedWidth?: boolean;
|
|
10
9
|
wide?: boolean;
|
|
@@ -13,30 +12,101 @@ interface Props {
|
|
|
13
12
|
description: string;
|
|
14
13
|
}
|
|
15
14
|
|
|
15
|
+
interface SubjectAboutSectionProps {
|
|
16
|
+
fixedWidth: boolean;
|
|
17
|
+
wide: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const SubjectAboutSection = styled.section<SubjectAboutSectionProps>`
|
|
21
|
+
margin-bottom: ${spacing.large};
|
|
22
|
+
max-width: ${(p) => p.fixedWidth && '350px'};
|
|
23
|
+
|
|
24
|
+
${(p) =>
|
|
25
|
+
p.wide &&
|
|
26
|
+
css`
|
|
27
|
+
margin: 40px 0;
|
|
28
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
29
|
+
display: flex;
|
|
30
|
+
margin: 80px 0;
|
|
31
|
+
}
|
|
32
|
+
`};
|
|
33
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
34
|
+
border: 1px solid ${colors.brand.greyLight};
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
const StyledSectionHeading = styled(SectionHeading)`
|
|
39
|
+
margin: 0 0 ${spacing.small} 0;
|
|
40
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
41
|
+
display: none;
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
interface MediaWrapperProps {
|
|
46
|
+
wide?: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const MediaWrapper = styled.div<MediaWrapperProps>`
|
|
50
|
+
width: 100%;
|
|
51
|
+
display: flex;
|
|
52
|
+
justify-content: center;
|
|
53
|
+
align-items: center;
|
|
54
|
+
text-align: center;
|
|
55
|
+
& > *,
|
|
56
|
+
img {
|
|
57
|
+
width: 100%;
|
|
58
|
+
}
|
|
59
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
60
|
+
width: 50%;
|
|
61
|
+
min-width: 50%;
|
|
62
|
+
}
|
|
63
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
64
|
+
width: 40%;
|
|
65
|
+
min-width: 40%;
|
|
66
|
+
}
|
|
67
|
+
${(p) =>
|
|
68
|
+
p.wide &&
|
|
69
|
+
css`
|
|
70
|
+
margin: 40px 0;
|
|
71
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
72
|
+
display: flex;
|
|
73
|
+
margin: 80px 0;
|
|
74
|
+
}
|
|
75
|
+
`};
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
const StyledContent = styled.div`
|
|
79
|
+
padding: ${spacing.small} 0 0 0;
|
|
80
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
81
|
+
padding: ${spacing.normal};
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
const StyledMainHeading = styled.h1`
|
|
86
|
+
margin: 0 0 ${spacing.small} 0;
|
|
87
|
+
${fonts.sizes('14px', '32px')};
|
|
88
|
+
text-transform: uppercase;
|
|
89
|
+
font-weight: ${fonts.weight.bold};
|
|
90
|
+
display: none;
|
|
91
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
92
|
+
display: block;
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
const StyledDescription = styled.p`
|
|
97
|
+
margin: 0;
|
|
98
|
+
${fonts.sizes('16px', '26px')};
|
|
99
|
+
`;
|
|
100
|
+
|
|
16
101
|
const SubjectAbout = ({ fixedWidth = false, media, heading, description, wide = false }: Props) => (
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
</div>
|
|
26
|
-
</section>
|
|
102
|
+
<SubjectAboutSection wide={wide} fixedWidth={fixedWidth}>
|
|
103
|
+
<StyledSectionHeading large>{heading}</StyledSectionHeading>
|
|
104
|
+
<MediaWrapper>{media}</MediaWrapper>
|
|
105
|
+
<StyledContent>
|
|
106
|
+
<StyledMainHeading>{heading}</StyledMainHeading>
|
|
107
|
+
<StyledDescription>{description}</StyledDescription>
|
|
108
|
+
</StyledContent>
|
|
109
|
+
</SubjectAboutSection>
|
|
27
110
|
);
|
|
28
111
|
|
|
29
|
-
SubjectAbout.propTypes = {
|
|
30
|
-
fixedWidth: PropTypes.bool,
|
|
31
|
-
wide: PropTypes.bool,
|
|
32
|
-
media: PropTypes.node.isRequired,
|
|
33
|
-
heading: PropTypes.string.isRequired,
|
|
34
|
-
description: PropTypes.string.isRequired,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
SubjectAbout.defaultProps = {
|
|
38
|
-
fixedWidth: false,
|
|
39
|
-
wide: false,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
112
|
export default SubjectAbout;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import React, { ReactNode, Component, createRef,
|
|
2
|
-
import
|
|
3
|
-
import BEMHelper from 'react-bem-helper';
|
|
1
|
+
import React, { ReactNode, Component, createRef, RefObject } from 'react';
|
|
2
|
+
import styled from '@emotion/styled';
|
|
4
3
|
import { Forward } from '@ndla/icons/common';
|
|
5
4
|
import { Cross } from '@ndla/icons/action';
|
|
5
|
+
import { breakpoints, colors, fonts, mq, spacing, utils } from '@ndla/core';
|
|
6
6
|
import SafeLink from '@ndla/safelink';
|
|
7
7
|
import SectionHeading from '../SectionHeading';
|
|
8
8
|
|
|
9
|
-
const classes = BEMHelper('c-subject-archive');
|
|
10
|
-
|
|
11
9
|
interface Props {
|
|
12
10
|
featuringArticle: {
|
|
13
11
|
media: ReactNode;
|
|
@@ -26,6 +24,109 @@ interface State {
|
|
|
26
24
|
minHeight: number | null;
|
|
27
25
|
}
|
|
28
26
|
|
|
27
|
+
interface SubjectArchiveSectionProps {
|
|
28
|
+
fixedWidth: boolean;
|
|
29
|
+
animate: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const ArchiveWrapper = styled.div`
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-flow: column;
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
const StyledSectionHeading = styled(SectionHeading)`
|
|
38
|
+
margin: 0 0 ${spacing.small} 0;
|
|
39
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
40
|
+
${utils.visuallyHidden};
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
const ArchiveButon = styled.button`
|
|
45
|
+
display: inline-flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
margin: ${spacing.small} 0 0 0;
|
|
49
|
+
padding: ${spacing.xsmall} 0;
|
|
50
|
+
border: 0;
|
|
51
|
+
color: ${colors.brand.primary};
|
|
52
|
+
${fonts.sizes('16px', '24px')};
|
|
53
|
+
font-weight: ${fonts.weight.semibold};
|
|
54
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
55
|
+
margin: ${spacing.xsmall} ${spacing.normal} ${spacing.normal};
|
|
56
|
+
}
|
|
57
|
+
c-icon {
|
|
58
|
+
width: 18px;
|
|
59
|
+
height: 18px;
|
|
60
|
+
margin-right: ${spacing.small};
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
interface StyledNavProps {
|
|
65
|
+
animate: boolean;
|
|
66
|
+
}
|
|
67
|
+
const StyledNav = styled.nav<StyledNavProps>`
|
|
68
|
+
padding: 0;
|
|
69
|
+
animation: ${(p) => p.animate && 'fadeIn 0.3s ease-in-out'};
|
|
70
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
71
|
+
padding: ${spacing.large} ${spacing.large} 0 ${spacing.large};
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
const StyledArchiveList = styled.ul`
|
|
76
|
+
list-style: none;
|
|
77
|
+
margin: 0;
|
|
78
|
+
padding: 0;
|
|
79
|
+
|
|
80
|
+
li {
|
|
81
|
+
${fonts.sizes('16px', '24px')};
|
|
82
|
+
margin-bottom: ${spacing.small};
|
|
83
|
+
}
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
const MediaWrapper = styled.div`
|
|
87
|
+
width: 100%;
|
|
88
|
+
& > * {
|
|
89
|
+
width: 100%;
|
|
90
|
+
}
|
|
91
|
+
`;
|
|
92
|
+
|
|
93
|
+
const StyledContent = styled.div`
|
|
94
|
+
padding: ${spacing.small} 0 0 0;
|
|
95
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
96
|
+
padding: ${spacing.normal};
|
|
97
|
+
}
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
const StyledHeading = styled.h1`
|
|
101
|
+
${fonts.sizes('20px', '32px')};
|
|
102
|
+
margin: 0 0 ${spacing.small} 0;
|
|
103
|
+
flex: 0 0 auto;
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
const StyledDescription = styled.p`
|
|
107
|
+
margin: 0;
|
|
108
|
+
${fonts.sizes('16px', '26px')}
|
|
109
|
+
`;
|
|
110
|
+
|
|
111
|
+
const SubjectArchiveSection = styled.section<SubjectArchiveSectionProps>`
|
|
112
|
+
margin-bottom: ${spacing.large};
|
|
113
|
+
display: flex;
|
|
114
|
+
flex-direction: column;
|
|
115
|
+
max-width: ${(p) => p.fixedWidth && '350px'};
|
|
116
|
+
animation: ${(p) => p.animate && 'fadeIn 0.3s ease-in-out'};
|
|
117
|
+
|
|
118
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
119
|
+
border: 1px solid ${colors.brand.greyLight};
|
|
120
|
+
}
|
|
121
|
+
`;
|
|
122
|
+
|
|
123
|
+
interface FeaturingSectionProps {
|
|
124
|
+
animate: boolean;
|
|
125
|
+
}
|
|
126
|
+
const FeaturingSection = styled.section<FeaturingSectionProps>`
|
|
127
|
+
animation: ${(p) => p.animate && 'fadeIn 0.3s ease-in-out'};
|
|
128
|
+
`;
|
|
129
|
+
|
|
29
130
|
class SubjectArchive extends Component<Props, State> {
|
|
30
131
|
wrapperRef: RefObject<HTMLElement> | null = createRef<HTMLElement>();
|
|
31
132
|
constructor(props: Props) {
|
|
@@ -59,81 +160,51 @@ class SubjectArchive extends Component<Props, State> {
|
|
|
59
160
|
const archiveId = 'subject-archive';
|
|
60
161
|
|
|
61
162
|
const section = this.state.archiveOpen ? (
|
|
62
|
-
<
|
|
63
|
-
<
|
|
163
|
+
<StyledNav id={archiveId} animate={!!this.state.minHeight}>
|
|
164
|
+
<StyledArchiveList>
|
|
64
165
|
{archiveArticles.map((article) => (
|
|
65
166
|
<li key={article.heading}>
|
|
66
167
|
<SafeLink to={article.url}>{article.heading}</SafeLink>
|
|
67
168
|
</li>
|
|
68
169
|
))}
|
|
69
|
-
</
|
|
70
|
-
</
|
|
170
|
+
</StyledArchiveList>
|
|
171
|
+
</StyledNav>
|
|
71
172
|
) : (
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
<
|
|
75
|
-
<
|
|
173
|
+
<FeaturingSection animate={!!this.state.minHeight}>
|
|
174
|
+
<MediaWrapper>{featuringArticle.media}</MediaWrapper>
|
|
175
|
+
<StyledContent>
|
|
176
|
+
<StyledHeading>
|
|
76
177
|
<SafeLink to={featuringArticle.url}>{featuringArticle.heading}</SafeLink>
|
|
77
|
-
</
|
|
78
|
-
<
|
|
79
|
-
</
|
|
80
|
-
</
|
|
178
|
+
</StyledHeading>
|
|
179
|
+
<StyledDescription>{featuringArticle.description}</StyledDescription>
|
|
180
|
+
</StyledContent>
|
|
181
|
+
</FeaturingSection>
|
|
81
182
|
);
|
|
82
183
|
|
|
83
|
-
const subClasses = Object.entries({ fixedWidth, animate: !!this.state.minHeight })
|
|
84
|
-
.filter(([_, include]) => include)
|
|
85
|
-
.map(([className, _]) => className);
|
|
86
|
-
|
|
87
184
|
return (
|
|
88
|
-
<
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
</SectionHeading>
|
|
92
|
-
<div {...classes('wrapper')}>
|
|
185
|
+
<SubjectArchiveSection animate={!!this.state.minHeight} fixedWidth={fixedWidth} ref={this.wrapperRef}>
|
|
186
|
+
<StyledSectionHeading large>{sectionHeading}</StyledSectionHeading>
|
|
187
|
+
<ArchiveWrapper>
|
|
93
188
|
{section}
|
|
94
|
-
<
|
|
189
|
+
<ArchiveButon
|
|
95
190
|
type="button"
|
|
96
191
|
aria-expanded={this.state.archiveOpen}
|
|
97
192
|
aria-controls={archiveId}
|
|
98
|
-
className={classes('archive-button').className}
|
|
99
193
|
onClick={this.handleToggleArchive}>
|
|
100
194
|
{this.state.archiveOpen ? (
|
|
101
|
-
|
|
195
|
+
<>
|
|
102
196
|
<Cross /> <span>{messages.close}</span>
|
|
103
|
-
|
|
197
|
+
</>
|
|
104
198
|
) : (
|
|
105
|
-
|
|
199
|
+
<>
|
|
106
200
|
<Forward /> <span>{messages.archive}</span>
|
|
107
|
-
|
|
201
|
+
</>
|
|
108
202
|
)}
|
|
109
|
-
</
|
|
110
|
-
</
|
|
111
|
-
</
|
|
203
|
+
</ArchiveButon>
|
|
204
|
+
</ArchiveWrapper>
|
|
205
|
+
</SubjectArchiveSection>
|
|
112
206
|
);
|
|
113
207
|
}
|
|
114
|
-
static propTypes = {
|
|
115
|
-
featuringArticle: PropTypes.shape({
|
|
116
|
-
media: PropTypes.node.isRequired,
|
|
117
|
-
heading: PropTypes.string.isRequired,
|
|
118
|
-
description: PropTypes.string.isRequired,
|
|
119
|
-
url: PropTypes.string.isRequired,
|
|
120
|
-
}).isRequired,
|
|
121
|
-
archiveArticles: PropTypes.arrayOf(
|
|
122
|
-
PropTypes.shape({
|
|
123
|
-
url: PropTypes.string.isRequired,
|
|
124
|
-
heading: PropTypes.string.isRequired,
|
|
125
|
-
}),
|
|
126
|
-
).isRequired,
|
|
127
|
-
sectionHeading: PropTypes.string.isRequired,
|
|
128
|
-
fixedWidth: PropTypes.bool,
|
|
129
|
-
messages: PropTypes.shape({
|
|
130
|
-
archive: PropTypes.string.isRequired,
|
|
131
|
-
}),
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
static defaultProps = {
|
|
135
|
-
fixedWidth: false,
|
|
136
|
-
};
|
|
137
208
|
}
|
|
138
209
|
|
|
139
210
|
export default SubjectArchive;
|