@ndla/ui 16.0.0 → 16.2.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/NDLAFilm/CategorySelect.js +51 -25
- package/es/NDLAFilm/FilmMovieList.js +14 -10
- package/es/NDLAFilm/FilmMovieSearch.js +23 -10
- package/es/NDLAFilm/FilmSlideshow.js +117 -19
- package/es/NDLAFilm/MovieGrid.js +23 -14
- package/es/NDLAFilm/NavigationArrow.js +33 -7
- package/es/NDLAFilm/SlideshowIndicator.js +27 -11
- package/es/NDLAFilm/filmStyles.js +23 -0
- package/es/Notion/ConceptNotion.js +1 -1
- package/es/Notion/index.js +2 -1
- package/es/RadioButtonGroup/RadioButtonGroup.js +28 -9
- package/es/Resource/resourceComponents.js +17 -9
- package/es/TreeStructure/FolderItem.js +39 -28
- package/es/TreeStructure/FolderItems.js +8 -5
- package/es/TreeStructure/TreeStructure.js +10 -11
- package/es/TreeStructure/TreeStructureWrapper.js +2 -2
- package/es/all.css +1 -1
- package/es/index.js +1 -1
- package/es/locale/messages-en.js +1 -1
- package/es/locale/messages-nb.js +1 -1
- package/es/locale/messages-nn.js +1 -1
- package/es/locale/messages-se.js +1 -1
- package/es/locale/messages-sma.js +1 -1
- package/lib/Breadcrumblist/index.d.ts +1 -0
- package/lib/NDLAFilm/CategorySelect.js +52 -30
- package/lib/NDLAFilm/FilmMovieList.js +17 -13
- package/lib/NDLAFilm/FilmMovieSearch.js +29 -17
- package/lib/NDLAFilm/FilmSlideshow.js +113 -24
- package/lib/NDLAFilm/MovieGrid.js +26 -16
- package/lib/NDLAFilm/NavigationArrow.d.ts +5 -1
- package/lib/NDLAFilm/NavigationArrow.js +34 -10
- package/lib/NDLAFilm/SlideshowIndicator.js +34 -13
- package/lib/NDLAFilm/filmStyles.d.ts +8 -0
- package/lib/NDLAFilm/filmStyles.js +38 -0
- package/lib/Notion/ConceptNotion.d.ts +1 -1
- package/lib/Notion/ConceptNotion.js +1 -1
- package/lib/Notion/index.d.ts +4 -1
- package/lib/Notion/index.js +11 -3
- package/lib/RadioButtonGroup/RadioButtonGroup.js +28 -13
- package/lib/Resource/resourceComponents.js +17 -9
- package/lib/TreeStructure/FolderItem.d.ts +3 -2
- package/lib/TreeStructure/FolderItem.js +38 -28
- package/lib/TreeStructure/FolderItems.d.ts +1 -1
- package/lib/TreeStructure/FolderItems.js +8 -5
- package/lib/TreeStructure/TreeStructure.d.ts +1 -1
- package/lib/TreeStructure/TreeStructure.js +10 -11
- package/lib/TreeStructure/TreeStructure.types.d.ts +6 -3
- package/lib/TreeStructure/TreeStructureWrapper.js +2 -2
- package/lib/all.css +1 -1
- package/lib/index.d.ts +6 -2
- package/lib/index.js +7 -0
- package/lib/locale/messages-en.js +1 -1
- package/lib/locale/messages-nb.js +1 -1
- package/lib/locale/messages-nn.js +1 -1
- package/lib/locale/messages-se.js +1 -1
- package/lib/locale/messages-sma.js +1 -1
- package/package.json +13 -13
- package/src/Breadcrumblist/{index.tsx → index.ts} +1 -0
- package/src/NDLAFilm/CategorySelect.tsx +110 -23
- package/src/NDLAFilm/FilmMovieList.tsx +13 -11
- package/src/NDLAFilm/FilmMovieSearch.tsx +45 -14
- package/src/NDLAFilm/FilmSlideshow.tsx +186 -25
- package/src/NDLAFilm/MovieGrid.tsx +33 -25
- package/src/NDLAFilm/NavigationArrow.tsx +76 -10
- package/src/NDLAFilm/SlideshowIndicator.tsx +53 -11
- package/src/NDLAFilm/component.film-movielist.scss +0 -46
- package/src/NDLAFilm/filmStyles.ts +33 -0
- package/src/Notion/ConceptNotion.tsx +2 -1
- package/src/Notion/index.ts +4 -1
- package/src/RadioButtonGroup/RadioButtonGroup.tsx +82 -11
- package/src/Resource/resourceComponents.tsx +1 -3
- package/src/TreeStructure/FolderItem.tsx +40 -19
- package/src/TreeStructure/FolderItems.tsx +3 -0
- package/src/TreeStructure/TreeStructure.tsx +7 -11
- package/src/TreeStructure/TreeStructure.types.ts +7 -3
- package/src/TreeStructure/TreeStructureWrapper.tsx +1 -1
- package/src/index.ts +15 -2
- package/src/locale/messages-en.ts +1 -1
- package/src/locale/messages-nb.ts +1 -1
- package/src/locale/messages-nn.ts +1 -1
- package/src/locale/messages-se.ts +1 -1
- package/src/locale/messages-sma.ts +1 -1
- package/src/main.scss +0 -3
- package/src/NDLAFilm/component.film-moviesearch.scss +0 -127
- package/src/NDLAFilm/component.film-slideshow.scss +0 -258
- package/src/RadioButtonGroup/component.radio-button-group.scss +0 -67
|
@@ -8,11 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
10
10
|
import { SwipeEventData, useSwipeable } from 'react-swipeable';
|
|
11
|
-
import
|
|
11
|
+
import styled from '@emotion/styled';
|
|
12
|
+
import { css } from '@emotion/core';
|
|
13
|
+
import { breakpoints, mq, spacing, spacingUnit, fonts, colors } from '@ndla/core';
|
|
12
14
|
import SafeLink from '@ndla/safelink';
|
|
13
15
|
import { OneColumn } from '../Layout';
|
|
14
16
|
import Spinner from '../Spinner';
|
|
15
|
-
import NavigationArrow from './NavigationArrow';
|
|
17
|
+
import NavigationArrow, { StyledNavigationArrow } from './NavigationArrow';
|
|
16
18
|
import SlideshowIndicator from './SlideshowIndicator';
|
|
17
19
|
import { MovieType } from './types';
|
|
18
20
|
|
|
@@ -23,17 +25,180 @@ interface Props {
|
|
|
23
25
|
slideInterval?: number;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const SlideLinkWrapper = styled.div`
|
|
29
|
+
margin: 0 auto;
|
|
30
|
+
display: flex;
|
|
31
|
+
justify-content: flex-start;
|
|
32
|
+
align-items: flex-end;
|
|
33
|
+
position: absolute;
|
|
34
|
+
z-index: 2;
|
|
35
|
+
height: 100vw;
|
|
36
|
+
width: 100%;
|
|
37
|
+
${mq.range({ from: breakpoints.mobileWide })} {
|
|
38
|
+
height: 100vw;
|
|
39
|
+
}
|
|
40
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
41
|
+
height: 75vw;
|
|
42
|
+
}
|
|
43
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
44
|
+
height: 55vw;
|
|
45
|
+
}
|
|
46
|
+
${mq.range({ from: breakpoints.wide })} {
|
|
47
|
+
height: 40vw;
|
|
48
|
+
}
|
|
49
|
+
${mq.range({ from: breakpoints.ultraWide })} {
|
|
50
|
+
height: 36vw;
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
const itemWrapperCSS = css`
|
|
55
|
+
display: flex;
|
|
56
|
+
box-shadow: none;
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
interface SlideshowItemProps {
|
|
60
|
+
fadeOver?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const SlideshowItem = styled.div<SlideshowItemProps>`
|
|
64
|
+
width: 100vw;
|
|
65
|
+
height: 100vw;
|
|
66
|
+
/* aspect ratios */
|
|
67
|
+
${mq.range({ from: breakpoints.mobileWide })} {
|
|
68
|
+
height: 100vw;
|
|
69
|
+
}
|
|
70
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
71
|
+
height: 75vw;
|
|
72
|
+
}
|
|
73
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
74
|
+
height: 55vw;
|
|
75
|
+
}
|
|
76
|
+
${mq.range({ from: breakpoints.wide })} {
|
|
77
|
+
height: 40vw;
|
|
78
|
+
}
|
|
79
|
+
${mq.range({ from: breakpoints.ultraWide })} {
|
|
80
|
+
height: 36vw;
|
|
81
|
+
}
|
|
82
|
+
background-color: '#222';
|
|
83
|
+
background-size: cover;
|
|
84
|
+
background-position-x: center;
|
|
85
|
+
background-position-y: center;
|
|
86
|
+
border: 0;
|
|
87
|
+
position: ${(props) => (props.fadeOver ? 'absolute' : 'relative')};
|
|
88
|
+
animation: ${(props) => props.fadeOver && 'fadeIn 400ms ease'};
|
|
89
|
+
z-index: ${(props) => props.fadeOver && 1};
|
|
90
|
+
&:before {
|
|
91
|
+
content: '';
|
|
92
|
+
opacity: 0.4;
|
|
93
|
+
background: #091a2a;
|
|
94
|
+
top: 0;
|
|
95
|
+
left: 0;
|
|
96
|
+
bottom: 0;
|
|
97
|
+
right: 0;
|
|
98
|
+
position: absolute;
|
|
99
|
+
z-index: 1;
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
interface SlideshowLinkProps {
|
|
104
|
+
out?: boolean;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const SlideshowLink = styled(SafeLink)<SlideshowLinkProps>`
|
|
108
|
+
display: flex;
|
|
109
|
+
box-shadow: none;
|
|
110
|
+
transition: all 400ms ease;
|
|
111
|
+
opacity: ${(props) => props.out && 0};
|
|
112
|
+
animation: ${(props) => !props.out && 'fadeInBottomFixed 600ms ease'};
|
|
113
|
+
${mq.range({ from: breakpoints.mobileWide })} {
|
|
114
|
+
padding-bottom: ${spacing.medium};
|
|
115
|
+
}
|
|
116
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
117
|
+
padding-bottom: ${spacing.large};
|
|
118
|
+
}
|
|
119
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
120
|
+
padding-bottom: ${spacingUnit * 3}px;
|
|
121
|
+
}
|
|
122
|
+
&:hover {
|
|
123
|
+
h1 {
|
|
124
|
+
text-decoration: underline;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
`;
|
|
128
|
+
|
|
129
|
+
const SlideshowWrapper = styled.section`
|
|
130
|
+
&:hover {
|
|
131
|
+
${StyledNavigationArrow} {
|
|
132
|
+
opacity: 1;
|
|
133
|
+
transform: translate(0, 0);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
`;
|
|
137
|
+
|
|
138
|
+
const SlideshowInfo = styled.div`
|
|
139
|
+
border: 0;
|
|
140
|
+
background: none;
|
|
141
|
+
background-color: rgba(3, 23, 43, 0.7);
|
|
142
|
+
border-radius: 4px;
|
|
143
|
+
padding: ${spacing.medium} ${spacing.medium} ${spacing.medium} ${spacing.normal};
|
|
144
|
+
margin: 0 -20px;
|
|
145
|
+
width: 100vw;
|
|
146
|
+
${mq.range({ from: breakpoints.mobileWide })} {
|
|
147
|
+
margin: 0;
|
|
148
|
+
width: 100%;
|
|
149
|
+
padding: ${spacing.medium} ${spacingUnit * 2}px ${spacing.medium} ${spacing.normal};
|
|
150
|
+
}
|
|
151
|
+
h1 {
|
|
152
|
+
${fonts.sizes('22px', '30px')};
|
|
153
|
+
color: ${colors.white};
|
|
154
|
+
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
|
|
155
|
+
margin: 0;
|
|
156
|
+
font-weight: ${fonts.weight.semibold};
|
|
157
|
+
${mq.range({ from: breakpoints.mobileWide })} {
|
|
158
|
+
margin: 0 0 ${spacing.small};
|
|
159
|
+
${fonts.sizes('26px', '30px')};
|
|
160
|
+
}
|
|
161
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
162
|
+
${fonts.sizes('40px', '44px')};
|
|
163
|
+
}
|
|
164
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
165
|
+
${fonts.sizes('48px', '54px')};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
p {
|
|
170
|
+
color: ${colors.white};
|
|
171
|
+
display: inline-block;
|
|
172
|
+
margin: 0;
|
|
173
|
+
padding: 0;
|
|
174
|
+
border-radius: 4px;
|
|
175
|
+
${fonts.sizes('12px', '18px')};
|
|
176
|
+
${mq.range({ from: breakpoints.mobileWide })} {
|
|
177
|
+
${fonts.sizes('15px', '20px')};
|
|
178
|
+
}
|
|
179
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
180
|
+
${fonts.sizes('18px', '24px')};
|
|
181
|
+
}
|
|
182
|
+
${mq.range({ from: breakpoints.wide })} {
|
|
183
|
+
${fonts.sizes('20px', '32px')};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
`;
|
|
187
|
+
|
|
188
|
+
const EmptySlideshow = styled.div`
|
|
189
|
+
background: rgba(255, 255, 255, 0.08);
|
|
190
|
+
margin-bottom: $spacing--large * 4;
|
|
191
|
+
display: flex;
|
|
192
|
+
align-items: center;
|
|
193
|
+
justify-content: center;
|
|
194
|
+
height: 40vw;
|
|
195
|
+
`;
|
|
30
196
|
|
|
31
197
|
const defaultTransitionSwipeEnd = 'transform 600ms cubic-bezier(0, 0.76, 0.09, 1)';
|
|
32
198
|
const defaultTransitionText = 'opacity 600ms ease';
|
|
33
199
|
|
|
34
200
|
const renderSlideItem = (slide: MovieType) => (
|
|
35
|
-
<
|
|
36
|
-
{...classes('item')}
|
|
201
|
+
<SlideshowItem
|
|
37
202
|
key={slide.id}
|
|
38
203
|
role="img"
|
|
39
204
|
aria-label={(slide.metaImage && slide.metaImage.alt) || ''}
|
|
@@ -190,9 +355,9 @@ const FilmSlideshow = ({ autoSlide = false, slideshow = [], slideInterval = 5000
|
|
|
190
355
|
if (slideshow.length === 0) {
|
|
191
356
|
return (
|
|
192
357
|
<div>
|
|
193
|
-
<
|
|
358
|
+
<EmptySlideshow>
|
|
194
359
|
<Spinner inverted />
|
|
195
|
-
</
|
|
360
|
+
</EmptySlideshow>
|
|
196
361
|
</div>
|
|
197
362
|
);
|
|
198
363
|
}
|
|
@@ -208,22 +373,18 @@ const FilmSlideshow = ({ autoSlide = false, slideshow = [], slideInterval = 5000
|
|
|
208
373
|
const backgroundImage = slideshow[activeSlide].metaImage;
|
|
209
374
|
|
|
210
375
|
return (
|
|
211
|
-
<
|
|
376
|
+
<SlideshowWrapper {...handlers}>
|
|
212
377
|
<>
|
|
213
|
-
<
|
|
378
|
+
<SlideLinkWrapper>
|
|
214
379
|
<OneColumn>
|
|
215
|
-
<
|
|
216
|
-
|
|
217
|
-
{...classes('item-wrapper', 'text', {
|
|
218
|
-
out: !animationComplete,
|
|
219
|
-
})}>
|
|
220
|
-
<div {...classes('slide-info')} ref={slideText}>
|
|
380
|
+
<SlideshowLink to={slideshow[activeSlide].path} out={!animationComplete}>
|
|
381
|
+
<SlideshowInfo ref={slideText}>
|
|
221
382
|
<h1>{slideshow[activeSlide].title}</h1>
|
|
222
383
|
<p>{slideshow[activeSlide].metaDescription}</p>
|
|
223
|
-
</
|
|
224
|
-
</
|
|
384
|
+
</SlideshowInfo>
|
|
385
|
+
</SlideshowLink>
|
|
225
386
|
</OneColumn>
|
|
226
|
-
</
|
|
387
|
+
</SlideLinkWrapper>
|
|
227
388
|
<NavigationArrow
|
|
228
389
|
slideIndexTarget={slideIndexTarget > 0 ? slideIndexTarget - 1 : slideshow.length - 1}
|
|
229
390
|
gotoSlide={gotoSlide}
|
|
@@ -234,8 +395,8 @@ const FilmSlideshow = ({ autoSlide = false, slideshow = [], slideInterval = 5000
|
|
|
234
395
|
rightArrow
|
|
235
396
|
/>
|
|
236
397
|
{!animationComplete && (
|
|
237
|
-
<
|
|
238
|
-
|
|
398
|
+
<SlideshowItem
|
|
399
|
+
fadeOver
|
|
239
400
|
role="img"
|
|
240
401
|
onAnimationEnd={onChangedSlide}
|
|
241
402
|
style={{
|
|
@@ -245,7 +406,7 @@ const FilmSlideshow = ({ autoSlide = false, slideshow = [], slideInterval = 5000
|
|
|
245
406
|
)}
|
|
246
407
|
<div
|
|
247
408
|
ref={slideRef}
|
|
248
|
-
{
|
|
409
|
+
css={itemWrapperCSS}
|
|
249
410
|
onTransitionEnd={onTransitionEnd}
|
|
250
411
|
style={{
|
|
251
412
|
width: slideshowWidth,
|
|
@@ -257,7 +418,7 @@ const FilmSlideshow = ({ autoSlide = false, slideshow = [], slideInterval = 5000
|
|
|
257
418
|
</div>
|
|
258
419
|
<SlideshowIndicator slideshow={slideshow} activeSlide={activeSlide} gotoSlide={gotoSlide} />
|
|
259
420
|
</>
|
|
260
|
-
</
|
|
421
|
+
</SlideshowWrapper>
|
|
261
422
|
);
|
|
262
423
|
};
|
|
263
424
|
|
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import styled from '@emotion/styled';
|
|
3
|
+
import { spacing } from '@ndla/core';
|
|
4
4
|
import { CalculatedCarouselProps } from '@ndla/carousel';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import FilmContentCard from './FilmContentCard';
|
|
7
7
|
import { MovieResourceType, MovieType } from './types';
|
|
8
|
+
import { setAnimations, StyledHeadingH1 } from './filmStyles';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
interface MovieListingProps {
|
|
11
|
+
marginLeft?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const MovieListing = styled.div<MovieListingProps>`
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-wrap: wrap;
|
|
17
|
+
margin: ${spacing.small} 0;
|
|
18
|
+
margin-left: ${(props) => props.marginLeft && `${props.marginLeft}px`};
|
|
19
|
+
${setAnimations()};
|
|
20
|
+
> div {
|
|
21
|
+
opacity: 0;
|
|
22
|
+
animation-fill-mode: forwards;
|
|
23
|
+
animation-name: fadeIn;
|
|
24
|
+
animation-duration: 300ms;
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
interface LoadingPlaceholderProps {
|
|
29
|
+
height?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const LoadingPlaceholder = styled.div<LoadingPlaceholderProps>`
|
|
33
|
+
height: ${(props) => props.height};
|
|
34
|
+
`;
|
|
13
35
|
|
|
14
36
|
interface Props {
|
|
15
37
|
autoSizedProps: CalculatedCarouselProps;
|
|
@@ -33,30 +55,16 @@ const MovieGrid = ({
|
|
|
33
55
|
const { t } = useTranslation();
|
|
34
56
|
return (
|
|
35
57
|
<section>
|
|
36
|
-
<
|
|
37
|
-
{...movieListClasses('heading')}
|
|
38
|
-
css={css`
|
|
39
|
-
margin-left: ${autoSizedProps.margin}px;
|
|
40
|
-
`}>
|
|
58
|
+
<StyledHeadingH1 marginLeft={autoSizedProps.margin}>
|
|
41
59
|
{resourceTypeName && resourceTypeName.name}
|
|
42
60
|
<small>
|
|
43
61
|
{fetchingMoviesByType
|
|
44
62
|
? t('ndlaFilm.loadingMovies')
|
|
45
63
|
: `${moviesByType.length} ${t('ndlaFilm.movieMatchInCategory')}`}
|
|
46
64
|
</small>
|
|
47
|
-
</
|
|
48
|
-
<
|
|
49
|
-
{
|
|
50
|
-
css={css`
|
|
51
|
-
margin-left: ${autoSizedProps.margin}px;
|
|
52
|
-
`}>
|
|
53
|
-
{fetchingMoviesByType && (
|
|
54
|
-
<div
|
|
55
|
-
css={css`
|
|
56
|
-
height: ${loadingPlaceholderHeight};
|
|
57
|
-
`}
|
|
58
|
-
/>
|
|
59
|
-
)}
|
|
65
|
+
</StyledHeadingH1>
|
|
66
|
+
<MovieListing marginLeft={autoSizedProps.margin}>
|
|
67
|
+
{fetchingMoviesByType && <LoadingPlaceholder height={loadingPlaceholderHeight} />}
|
|
60
68
|
{!fetchingMoviesByType &&
|
|
61
69
|
moviesByType.map((movie) => (
|
|
62
70
|
<FilmContentCard
|
|
@@ -68,7 +76,7 @@ const MovieGrid = ({
|
|
|
68
76
|
resizeThumbnailImages={resizeThumbnailImages}
|
|
69
77
|
/>
|
|
70
78
|
))}
|
|
71
|
-
</
|
|
79
|
+
</MovieListing>
|
|
72
80
|
</section>
|
|
73
81
|
);
|
|
74
82
|
};
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import React from 'react';
|
|
10
|
-
import BEMHelper from 'react-bem-helper';
|
|
11
10
|
import { ChevronRight, ChevronLeft } from '@ndla/icons/common';
|
|
11
|
+
import styled from '@emotion/styled';
|
|
12
|
+
import { breakpoints, colors, mq, spacing } from '@ndla/core';
|
|
13
|
+
import { css } from '@emotion/core';
|
|
12
14
|
|
|
13
15
|
interface Props {
|
|
14
16
|
slideIndexTarget: number;
|
|
@@ -17,25 +19,89 @@ interface Props {
|
|
|
17
19
|
rightArrow?: boolean;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
interface StyledNavigationArrowProps {
|
|
23
|
+
right?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const StyledNavigationArrow = styled.div<StyledNavigationArrowProps>`
|
|
27
|
+
opacity: 0;
|
|
28
|
+
transition: transform 800ms ease, opacity 800ms ease;
|
|
29
|
+
display: flex;
|
|
30
|
+
justify-content: center;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
position: absolute;
|
|
33
|
+
align-items: center;
|
|
34
|
+
z-index: 2;
|
|
35
|
+
height: 70vw;
|
|
36
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
37
|
+
height: 60vw;
|
|
38
|
+
}
|
|
39
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
40
|
+
height: 55vw;
|
|
41
|
+
}
|
|
42
|
+
${mq.range({ from: breakpoints.wide })} {
|
|
43
|
+
height: 40vw;
|
|
44
|
+
}
|
|
45
|
+
${mq.range({ from: breakpoints.ultraWide })} {
|
|
46
|
+
height: 36vw;
|
|
47
|
+
}
|
|
48
|
+
transform: translate(${spacing.xsmall}, 0);
|
|
49
|
+
${(props) =>
|
|
50
|
+
props.right &&
|
|
51
|
+
`
|
|
52
|
+
right: 0;
|
|
53
|
+
transform: translate(${spacing.xsmall}, 0);
|
|
54
|
+
`}
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
const NavigationArrowButton = styled.button`
|
|
58
|
+
padding: ${spacing.normal} 0;
|
|
59
|
+
border-radius: 4px;
|
|
60
|
+
outline: none;
|
|
61
|
+
background: transparent;
|
|
62
|
+
color: ${colors.white};
|
|
63
|
+
border: 0;
|
|
64
|
+
&:hover,
|
|
65
|
+
&:focus {
|
|
66
|
+
.c-icon {
|
|
67
|
+
opacity: 1;
|
|
68
|
+
}
|
|
69
|
+
background: rgba(0, 0, 0, 0.1);
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
const chevronCss = css`
|
|
74
|
+
fill: ${colors.white};
|
|
75
|
+
width: 52px;
|
|
76
|
+
height: 52px;
|
|
77
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
78
|
+
width: 78px;
|
|
79
|
+
height: 78px;
|
|
80
|
+
}
|
|
81
|
+
opacity: 0.7;
|
|
82
|
+
transition: transform 400ms ease, opacity 400ms ease;
|
|
83
|
+
${NavigationArrowButton}:focus {
|
|
84
|
+
opacity: 1;
|
|
85
|
+
}
|
|
86
|
+
${NavigationArrowButton}:hover {
|
|
87
|
+
opacity: 1;
|
|
88
|
+
}
|
|
89
|
+
`;
|
|
24
90
|
|
|
25
91
|
const NavigationArrow = ({ slideIndexTarget, gotoSlide, rightArrow }: Props) => {
|
|
26
92
|
const Chevron = rightArrow ? ChevronRight : ChevronLeft;
|
|
27
93
|
|
|
28
94
|
return (
|
|
29
|
-
<
|
|
30
|
-
<
|
|
95
|
+
<StyledNavigationArrow right={rightArrow}>
|
|
96
|
+
<NavigationArrowButton
|
|
31
97
|
type="button"
|
|
32
98
|
tabIndex={-1}
|
|
33
99
|
onClick={() => {
|
|
34
100
|
gotoSlide(slideIndexTarget, true);
|
|
35
101
|
}}>
|
|
36
|
-
<Chevron />
|
|
37
|
-
</
|
|
38
|
-
</
|
|
102
|
+
<Chevron css={chevronCss} />
|
|
103
|
+
</NavigationArrowButton>
|
|
104
|
+
</StyledNavigationArrow>
|
|
39
105
|
);
|
|
40
106
|
};
|
|
41
107
|
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import React from 'react';
|
|
10
|
-
import
|
|
10
|
+
import styled from '@emotion/styled';
|
|
11
|
+
import { breakpoints, colors, mq, spacing } from '@ndla/core';
|
|
11
12
|
import { MovieType } from './types';
|
|
12
13
|
|
|
13
14
|
interface Props {
|
|
@@ -16,24 +17,65 @@ interface Props {
|
|
|
16
17
|
gotoSlide: (indexTarget: number, useAnimation: boolean) => void;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
const SlideshowIndicatorWrapper = styled.div`
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
margin: ${spacing.small} 0;
|
|
25
|
+
${mq.range({ from: breakpoints.mobileWide })} {
|
|
26
|
+
margin: ${spacing.normal} 0;
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
interface SlideshowIndicatorDotProps {
|
|
31
|
+
active?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const SlideshowIndicatorDot = styled.button<SlideshowIndicatorDotProps>`
|
|
35
|
+
border: 0;
|
|
36
|
+
display: flex;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
background: transparent;
|
|
39
|
+
span {
|
|
40
|
+
background: ${(props) => (props.active ? colors.white : colors.ndlaFilm.filmColorBright)};
|
|
41
|
+
transition: background 100ms ease;
|
|
42
|
+
height: 8px;
|
|
43
|
+
width: 8px;
|
|
44
|
+
${mq.range({ from: breakpoints.mobileWide })} {
|
|
45
|
+
height: 10px;
|
|
46
|
+
width: 10px;
|
|
47
|
+
}
|
|
48
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
49
|
+
height: ${spacing.small};
|
|
50
|
+
width: ${spacing.small};
|
|
51
|
+
}
|
|
52
|
+
border-radius: 100%;
|
|
53
|
+
}
|
|
54
|
+
padding: ${spacing.xsmall};
|
|
55
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
56
|
+
padding: ${spacing.small};
|
|
57
|
+
}
|
|
58
|
+
&:hover,
|
|
59
|
+
&:focus {
|
|
60
|
+
span {
|
|
61
|
+
background: ${colors.white};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
23
65
|
|
|
24
66
|
const SlideshowIndicator = ({ slideshow, activeSlide, gotoSlide }: Props) => {
|
|
25
67
|
return (
|
|
26
|
-
<
|
|
27
|
-
{slideshow.map((
|
|
28
|
-
<
|
|
68
|
+
<SlideshowIndicatorWrapper>
|
|
69
|
+
{slideshow.map((_, index) => (
|
|
70
|
+
<SlideshowIndicatorDot
|
|
71
|
+
active={index === activeSlide}
|
|
29
72
|
key={`indicator_${index}`}
|
|
30
73
|
type="button"
|
|
31
|
-
{...classes('indicator-dot', index === activeSlide ? 'active' : '')}
|
|
32
74
|
onClick={() => gotoSlide(index, true)}>
|
|
33
75
|
<span />
|
|
34
|
-
</
|
|
76
|
+
</SlideshowIndicatorDot>
|
|
35
77
|
))}
|
|
36
|
-
</
|
|
78
|
+
</SlideshowIndicatorWrapper>
|
|
37
79
|
);
|
|
38
80
|
};
|
|
39
81
|
|
|
@@ -7,52 +7,6 @@
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
.c-film-movielist {
|
|
10
|
-
margin-bottom: $spacing;
|
|
11
|
-
@include mq(tablet) {
|
|
12
|
-
margin-bottom: $spacing--large;
|
|
13
|
-
}
|
|
14
|
-
&__heading {
|
|
15
|
-
@include font-size(22px, 26px);
|
|
16
|
-
font-weight: $font-weight-semibold;
|
|
17
|
-
text-transform: uppercase;
|
|
18
|
-
letter-spacing: 0.05em;
|
|
19
|
-
color: #fff;
|
|
20
|
-
margin: $spacing--small 0;
|
|
21
|
-
small {
|
|
22
|
-
font-weight: normal;
|
|
23
|
-
padding-left: $spacing--small;
|
|
24
|
-
color: $brand-grey--light;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
&__movie-listing {
|
|
28
|
-
display: flex;
|
|
29
|
-
flex-wrap: wrap;
|
|
30
|
-
margin: $spacing--small 0;
|
|
31
|
-
@include set-animations();
|
|
32
|
-
> div {
|
|
33
|
-
opacity: 0;
|
|
34
|
-
animation-fill-mode: forwards;
|
|
35
|
-
animation-name: fadeIn;
|
|
36
|
-
animation-duration: 300ms;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
&__movie-item {
|
|
40
|
-
box-shadow: none;
|
|
41
|
-
padding: $spacing--small / 2;
|
|
42
|
-
@include mq(tablet) {
|
|
43
|
-
margin-bottom: $spacing--large;
|
|
44
|
-
}
|
|
45
|
-
@include mq($from: tablet) {
|
|
46
|
-
width: 25%;
|
|
47
|
-
}
|
|
48
|
-
@include mq($from: mobileWide, $until: tablet) {
|
|
49
|
-
width: 33.3%;
|
|
50
|
-
}
|
|
51
|
-
@include mq($until: mobileWide) {
|
|
52
|
-
width: 50%;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
10
|
&__carousel-wrapper-buttons {
|
|
57
11
|
> div {
|
|
58
12
|
@include set-animations();
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import styled from '@emotion/styled';
|
|
2
|
+
import { fonts, spacing, colors } from '@ndla/core';
|
|
3
|
+
|
|
4
|
+
export const setAnimations = () => {
|
|
5
|
+
const styles: any = {};
|
|
6
|
+
for (let i = 1; i < 20; i++) {
|
|
7
|
+
styles[`> div:nth-child(${i + 1})`] = {
|
|
8
|
+
'animation-delay': `${i * 50}ms`,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return styles;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
interface StyledHeadingProps {
|
|
15
|
+
marginLeft?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const StyledHeadingH1 = styled.h1<StyledHeadingProps>`
|
|
19
|
+
${fonts.sizes('22px', '26px')};
|
|
20
|
+
font-weight: ${fonts.weight.semibold};
|
|
21
|
+
text-transform: uppercase;
|
|
22
|
+
letter-spacing: 0.05em;
|
|
23
|
+
color: ${colors.white};
|
|
24
|
+
margin: ${spacing.small} 0;
|
|
25
|
+
margin-left: ${(props) => props.marginLeft && `${props.marginLeft}px`};
|
|
26
|
+
small {
|
|
27
|
+
font-weight: normal;
|
|
28
|
+
padding-left: ${spacing.small};
|
|
29
|
+
color: ${colors.brand.grey};
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export const StyledHeadingH2 = StyledHeadingH1.withComponent('h2');
|
|
@@ -16,7 +16,8 @@ import { getLicenseCredits } from '@ndla/licenses';
|
|
|
16
16
|
import Notion, { NotionDialogContent, NotionDialogText, NotionDialogLicenses } from '@ndla/notion';
|
|
17
17
|
import { Notion as UINotion } from '.';
|
|
18
18
|
import { NotionImage } from './NotionImage';
|
|
19
|
-
import NotionVisualElement
|
|
19
|
+
import NotionVisualElement from './NotionVisualElement';
|
|
20
|
+
import type { NotionVisualElementType } from './NotionVisualElement';
|
|
20
21
|
import FigureNotion from './FigureNotion';
|
|
21
22
|
import { Copyright } from '../types';
|
|
22
23
|
import { FigureType } from '../Figure';
|
package/src/Notion/index.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
export { default as Notion } from './Notion';
|
|
2
1
|
export { default as ConceptNotion } from './ConceptNotion';
|
|
2
|
+
export { default as Notion } from './Notion';
|
|
3
|
+
export { default as NotionVisualElement } from './NotionVisualElement';
|
|
4
|
+
export type { NotionVisualElementType } from './NotionVisualElement';
|
|
5
|
+
export type { ConceptNotionType } from './ConceptNotion';
|