@ndla/ui 3.3.5 → 3.3.9
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/AudioPlayer/Controls.js +30 -30
- package/es/Breadcrumb/Breadcrumb.js +2 -1
- package/es/ContentTypeBadge/ContentTypeBadge.js +30 -10
- package/es/NDLAFilm/FilmSlideshow.js +213 -247
- package/es/NDLAFilm/NavigationArrow.js +13 -60
- package/es/NDLAFilm/SlideshowIndicator.js +16 -63
- package/es/NDLAFilm/interfaces.js +0 -0
- package/es/Programme/Programme.js +11 -36
- package/es/Programme/ProgrammeSubjects.js +15 -42
- package/es/SearchTypeResult/SearchTypeHeader.js +7 -6
- package/es/Spinner/Spinner.js +3 -3
- package/lib/AudioPlayer/Controls.js +30 -30
- package/lib/Breadcrumb/Breadcrumb.js +2 -1
- package/lib/ContentTypeBadge/ContentTypeBadge.d.ts +3 -1
- package/lib/ContentTypeBadge/ContentTypeBadge.js +30 -10
- package/lib/NDLAFilm/FilmSlideshow.d.ts +16 -0
- package/lib/NDLAFilm/FilmSlideshow.js +214 -248
- package/lib/NDLAFilm/NavigationArrow.d.ts +15 -0
- package/lib/NDLAFilm/NavigationArrow.js +20 -65
- package/lib/NDLAFilm/SlideshowIndicator.d.ts +15 -0
- package/lib/NDLAFilm/SlideshowIndicator.js +16 -69
- package/lib/NDLAFilm/interfaces.d.ts +10 -0
- package/lib/NDLAFilm/interfaces.js +1 -0
- package/lib/NDLAFilm/shapes.d.ts +15 -0
- package/lib/Programme/Programme.d.ts +1 -1
- package/lib/Programme/Programme.js +11 -36
- package/lib/Programme/ProgrammeSubjects.d.ts +12 -17
- package/lib/Programme/ProgrammeSubjects.js +23 -48
- package/lib/SearchTypeResult/SearchTypeHeader.js +7 -6
- package/lib/Spinner/Spinner.d.ts +3 -3
- package/lib/Spinner/Spinner.js +2 -2
- package/package.json +10 -10
- package/src/AudioPlayer/Controls.tsx +2 -2
- package/src/Breadcrumb/Breadcrumb.tsx +1 -1
- package/src/ContentTypeBadge/ContentTypeBadge.tsx +11 -9
- package/src/NDLAFilm/FilmSlideshow.tsx +264 -0
- package/src/NDLAFilm/NavigationArrow.tsx +42 -0
- package/src/NDLAFilm/SlideshowIndicator.tsx +40 -0
- package/src/NDLAFilm/interfaces.ts +10 -0
- package/src/NDLAFilm/{shapes.js → shapes.ts} +0 -0
- package/src/Programme/Programme.tsx +3 -15
- package/src/Programme/ProgrammeSubjects.tsx +19 -43
- package/src/SearchTypeResult/SearchTypeHeader.tsx +1 -1
- package/src/Spinner/Spinner.tsx +9 -5
- package/src/NDLAFilm/FilmSlideshow.jsx +0 -277
- package/src/NDLAFilm/NavigationArrow.jsx +0 -46
- package/src/NDLAFilm/SlideshowIndicator.jsx +0 -43
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2016-present, NDLA.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the GPLv3 license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import React, { Component } from 'react';
|
|
10
|
-
import PropTypes from 'prop-types';
|
|
11
|
-
import { Swipeable } from 'react-swipeable';
|
|
12
|
-
import BEMHelper from 'react-bem-helper';
|
|
13
|
-
import { OneColumn } from '@ndla/ui';
|
|
14
|
-
import SafeLink from '@ndla/safelink';
|
|
15
|
-
import Spinner from '../Spinner';
|
|
16
|
-
import { movieShape } from './shapes';
|
|
17
|
-
import NavigationArrow from './NavigationArrow';
|
|
18
|
-
import SlideshowIndicator from './SlideshowIndicator';
|
|
19
|
-
|
|
20
|
-
const classes = new BEMHelper({
|
|
21
|
-
name: 'film-slideshow',
|
|
22
|
-
prefix: 'c-',
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const defaultTransitionSwipeEnd = 'transform 600ms cubic-bezier(0, 0.76, 0.09, 1)';
|
|
26
|
-
const defaultTransitionText = 'opacity 600ms ease';
|
|
27
|
-
|
|
28
|
-
const renderSlideItem = (slide) => (
|
|
29
|
-
<div
|
|
30
|
-
{...classes('item')}
|
|
31
|
-
key={slide.id}
|
|
32
|
-
role="img"
|
|
33
|
-
aria-label={(slide.metaImage && slide.metaImage.alt) || ''}
|
|
34
|
-
style={{
|
|
35
|
-
backgroundImage: `url(${(slide.metaImage && slide.metaImage.url) || ''})`,
|
|
36
|
-
}}
|
|
37
|
-
/>
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
class FilmSlideshow extends Component {
|
|
41
|
-
constructor(props) {
|
|
42
|
-
super(props);
|
|
43
|
-
const startIndex = this.props.randomStart ? Math.floor(Math.random() * this.props.slideshow.length) : 0;
|
|
44
|
-
this.state = {
|
|
45
|
-
slideIndex: startIndex,
|
|
46
|
-
slideIndexTarget: startIndex,
|
|
47
|
-
animationComplete: true,
|
|
48
|
-
};
|
|
49
|
-
this.swipeDistance = 0;
|
|
50
|
-
this.slideRef = React.createRef();
|
|
51
|
-
this.slideText = React.createRef();
|
|
52
|
-
this.onSwipeEnd = this.onSwipeEnd.bind(this);
|
|
53
|
-
this.onSwipe = this.onSwipe.bind(this);
|
|
54
|
-
this.gotoSlide = this.gotoSlide.bind(this);
|
|
55
|
-
this.onChangedSlide = this.onChangedSlide.bind(this);
|
|
56
|
-
this.onTransitionEnd = this.onTransitionEnd.bind(this);
|
|
57
|
-
|
|
58
|
-
this.timer = null;
|
|
59
|
-
this.onChangedSlideBlock = false;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
componentDidMount() {
|
|
63
|
-
this.initTimer();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
onChangedSlide() {
|
|
67
|
-
if (!this.state.animationComplete) {
|
|
68
|
-
this.slideRef.current.style.transition = 'none';
|
|
69
|
-
this.slideRef.current.style.transform = `translateX(${this.state.slideIndexTarget * 100}vw))`;
|
|
70
|
-
this.setState((prevState) => ({
|
|
71
|
-
animationComplete: true,
|
|
72
|
-
slideIndex: prevState.slideIndexTarget,
|
|
73
|
-
}));
|
|
74
|
-
} else if (this.state.slideIndexTarget === -1) {
|
|
75
|
-
// Go to last slide for continuous loop
|
|
76
|
-
this.slideRef.current.style.transition = 'none';
|
|
77
|
-
this.slideRef.current.style.transform = `translateX(${this.props.slideshow.length * 100}vw))`;
|
|
78
|
-
this.setState({
|
|
79
|
-
slideIndex: this.props.slideshow.length - 1,
|
|
80
|
-
slideIndexTarget: this.props.slideshow.length - 1,
|
|
81
|
-
animationComplete: true,
|
|
82
|
-
});
|
|
83
|
-
} else if (this.state.slideIndexTarget === this.props.slideshow.length) {
|
|
84
|
-
// Go to first slide for continuous loop
|
|
85
|
-
this.slideRef.current.style.transition = 'none';
|
|
86
|
-
this.slideRef.current.style.transform = `translateX(100vw))`;
|
|
87
|
-
this.setState({
|
|
88
|
-
slideIndex: 0,
|
|
89
|
-
slideIndexTarget: 0,
|
|
90
|
-
animationComplete: true,
|
|
91
|
-
});
|
|
92
|
-
} else {
|
|
93
|
-
this.setState((prevState) => ({
|
|
94
|
-
animationComplete: true,
|
|
95
|
-
slideIndex: prevState.slideIndexTarget,
|
|
96
|
-
}));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
onSwipeEnd() {
|
|
101
|
-
let slide;
|
|
102
|
-
if (this.swipeDistance > 40) {
|
|
103
|
-
slide = -1;
|
|
104
|
-
} else if (this.swipeDistance < -40) {
|
|
105
|
-
slide = 1;
|
|
106
|
-
} else {
|
|
107
|
-
slide = 0;
|
|
108
|
-
}
|
|
109
|
-
this.slideRef.current.style.transition = defaultTransitionSwipeEnd;
|
|
110
|
-
this.slideText.current.style.transition = defaultTransitionText;
|
|
111
|
-
this.slideText.current.style.opacity = 1;
|
|
112
|
-
this.swipeDistance = 0;
|
|
113
|
-
this.initTimer();
|
|
114
|
-
if (slide !== 0) {
|
|
115
|
-
this.setState((prevState) => {
|
|
116
|
-
return {
|
|
117
|
-
slideIndex: prevState.slideIndex + slide,
|
|
118
|
-
slideIndexTarget: prevState.slideIndex + slide,
|
|
119
|
-
};
|
|
120
|
-
});
|
|
121
|
-
} else {
|
|
122
|
-
// Reset transfrom
|
|
123
|
-
this.slideRef.current.style.transform = this.getSlidePosition(this.state.slideIndex + slide);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
onSwipe(eventData) {
|
|
128
|
-
if (eventData.dir === 'Up' || eventData.dir === 'Down') {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
clearTimeout(this.timer);
|
|
132
|
-
this.swipeDistance = -eventData.deltaX;
|
|
133
|
-
this.slideRef.current.style.transition = 'none';
|
|
134
|
-
this.slideRef.current.style.transform = this.getSlidePosition(this.state.slideIndexTarget);
|
|
135
|
-
const opacityText = 1 - Math.min(100, Math.abs(this.swipeDistance)) / 100;
|
|
136
|
-
this.slideText.current.style.transition = 'none';
|
|
137
|
-
this.slideText.current.style.opacity = opacityText;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
onTransitionEnd() {
|
|
141
|
-
const slideshowLength = this.props.slideshow.length;
|
|
142
|
-
if (this.state.slideIndex === -1) {
|
|
143
|
-
this.slideRef.current.style.transition = 'none';
|
|
144
|
-
this.slideRef.current.style.transform = this.getSlidePosition(slideshowLength - 1);
|
|
145
|
-
this.setState({
|
|
146
|
-
slideIndex: slideshowLength - 1,
|
|
147
|
-
slideIndexTarget: slideshowLength - 1,
|
|
148
|
-
});
|
|
149
|
-
} else if (this.state.slideIndex >= slideshowLength) {
|
|
150
|
-
this.slideRef.current.style.transition = 'none';
|
|
151
|
-
this.slideRef.current.style.transform = this.getSlidePosition(0);
|
|
152
|
-
this.setState({
|
|
153
|
-
slideIndex: 0,
|
|
154
|
-
slideIndexTarget: 0,
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
getSlidePosition(target) {
|
|
160
|
-
if (this.swipeDistance !== 0) {
|
|
161
|
-
return `translateX(calc(${this.swipeDistance}px -
|
|
162
|
-
${(target + 1) * 100}vw))`;
|
|
163
|
-
}
|
|
164
|
-
return `translateX(-${(target + 1) * 100}vw)`;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
gotoSlide(slideIndexTarget, useAnimation) {
|
|
168
|
-
this.swipeDistance = 0;
|
|
169
|
-
clearTimeout(this.timer);
|
|
170
|
-
this.initTimer();
|
|
171
|
-
this.setState({
|
|
172
|
-
slideIndexTarget,
|
|
173
|
-
animationComplete: !useAnimation,
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
initTimer() {
|
|
178
|
-
if (this.props.autoSlide) {
|
|
179
|
-
this.timer = setTimeout(() => {
|
|
180
|
-
this.gotoSlide(this.state.slideIndex + 1);
|
|
181
|
-
}, this.props.slideInterval);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
render() {
|
|
186
|
-
const { slideshow } = this.props;
|
|
187
|
-
const { slideIndex, slideIndexTarget, animationComplete } = this.state;
|
|
188
|
-
|
|
189
|
-
if (slideshow.length === 0) {
|
|
190
|
-
return (
|
|
191
|
-
<div>
|
|
192
|
-
<div {...classes('slideshow')}>
|
|
193
|
-
<Spinner inverted />
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
const slideshowWidth = `${(slideshow.length + 2) * 100}vw`;
|
|
199
|
-
let activeSlide = slideIndex;
|
|
200
|
-
if (activeSlide < 0) {
|
|
201
|
-
activeSlide = slideshow.length - 1;
|
|
202
|
-
} else if (activeSlide >= slideshow.length) {
|
|
203
|
-
activeSlide = 0;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return (
|
|
207
|
-
<section>
|
|
208
|
-
<Swipeable {...classes('')} onSwiped={this.onSwipeEnd} onSwiping={this.onSwipe}>
|
|
209
|
-
<div {...classes('slide-link-wrapper')}>
|
|
210
|
-
<OneColumn>
|
|
211
|
-
<SafeLink
|
|
212
|
-
to={slideshow[activeSlide].path}
|
|
213
|
-
{...classes('item-wrapper', 'text', {
|
|
214
|
-
out: !animationComplete,
|
|
215
|
-
})}>
|
|
216
|
-
<div {...classes('slide-info')} ref={this.slideText}>
|
|
217
|
-
<h1>{slideshow[activeSlide].title}</h1>
|
|
218
|
-
<p>{slideshow[activeSlide].metaDescription}</p>
|
|
219
|
-
</div>
|
|
220
|
-
</SafeLink>
|
|
221
|
-
</OneColumn>
|
|
222
|
-
</div>
|
|
223
|
-
<NavigationArrow
|
|
224
|
-
slideIndexTarget={slideIndexTarget > 0 ? slideIndexTarget - 1 : slideshow.length - 1}
|
|
225
|
-
gotoSlide={this.gotoSlide}
|
|
226
|
-
/>
|
|
227
|
-
<NavigationArrow
|
|
228
|
-
slideIndexTarget={slideIndexTarget < slideshow.length - 1 ? slideIndexTarget + 1 : 0}
|
|
229
|
-
gotoSlide={this.gotoSlide}
|
|
230
|
-
rightArrow
|
|
231
|
-
/>
|
|
232
|
-
{!animationComplete && (
|
|
233
|
-
<div
|
|
234
|
-
{...classes('item', 'fade-over')}
|
|
235
|
-
role="img"
|
|
236
|
-
onAnimationEnd={this.onChangedSlide}
|
|
237
|
-
style={{
|
|
238
|
-
backgroundImage: `url(${
|
|
239
|
-
(slideshow[activeSlide].metaImage && slideshow[activeSlide].metaImage.url) || ''
|
|
240
|
-
})`,
|
|
241
|
-
}}
|
|
242
|
-
/>
|
|
243
|
-
)}
|
|
244
|
-
<div
|
|
245
|
-
ref={this.slideRef}
|
|
246
|
-
{...classes('item-wrapper')}
|
|
247
|
-
onTransitionEnd={this.onTransitionEnd}
|
|
248
|
-
style={{
|
|
249
|
-
width: slideshowWidth,
|
|
250
|
-
transform: this.getSlidePosition(slideIndex),
|
|
251
|
-
}}>
|
|
252
|
-
{renderSlideItem(slideshow[slideshow.length - 1], -1)}
|
|
253
|
-
{slideshow.map(renderSlideItem)}
|
|
254
|
-
{renderSlideItem(slideshow[0], slideshow.length)}
|
|
255
|
-
</div>
|
|
256
|
-
</Swipeable>
|
|
257
|
-
<SlideshowIndicator slideshow={slideshow} activeSlide={activeSlide} gotoSlide={this.gotoSlide} />
|
|
258
|
-
</section>
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
FilmSlideshow.propTypes = {
|
|
264
|
-
autoSlide: PropTypes.bool,
|
|
265
|
-
randomStart: PropTypes.bool,
|
|
266
|
-
slideshow: PropTypes.arrayOf(movieShape),
|
|
267
|
-
slideInterval: PropTypes.number,
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
FilmSlideshow.defaultProps = {
|
|
271
|
-
autoSlide: false,
|
|
272
|
-
randomStart: false,
|
|
273
|
-
slideshow: [],
|
|
274
|
-
slideInterval: 5000,
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
export default FilmSlideshow;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2016-present, NDLA.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the GPLv3 license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import React, { Component } from 'react';
|
|
10
|
-
import PropTypes from 'prop-types';
|
|
11
|
-
import BEMHelper from 'react-bem-helper';
|
|
12
|
-
import { ChevronRight, ChevronLeft } from '@ndla/icons/common';
|
|
13
|
-
|
|
14
|
-
const classes = new BEMHelper({
|
|
15
|
-
name: 'film-slideshow',
|
|
16
|
-
prefix: 'c-',
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
class NavigationArrow extends Component {
|
|
20
|
-
render() {
|
|
21
|
-
const { slideIndexTarget, gotoSlide, rightArrow } = this.props;
|
|
22
|
-
const Chevron = rightArrow ? ChevronRight : ChevronLeft;
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<div {...classes('navigation-arrows', rightArrow ? 'right' : '')}>
|
|
26
|
-
<button
|
|
27
|
-
type="button"
|
|
28
|
-
tabIndex={-1}
|
|
29
|
-
onClick={() => {
|
|
30
|
-
gotoSlide(slideIndexTarget, true);
|
|
31
|
-
}}>
|
|
32
|
-
<Chevron />
|
|
33
|
-
</button>
|
|
34
|
-
</div>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
NavigationArrow.propTypes = {
|
|
40
|
-
slideIndexTarget: PropTypes.number,
|
|
41
|
-
slideshowLength: PropTypes.number,
|
|
42
|
-
gotoSlide: PropTypes.func,
|
|
43
|
-
rightArrow: PropTypes.bool,
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export default NavigationArrow;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2019-present, NDLA.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the GPLv3 license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import React, { Component } from 'react';
|
|
10
|
-
import PropTypes from 'prop-types';
|
|
11
|
-
import BEMHelper from 'react-bem-helper';
|
|
12
|
-
import { movieShape } from './shapes';
|
|
13
|
-
|
|
14
|
-
const classes = new BEMHelper({
|
|
15
|
-
name: 'film-slideshow',
|
|
16
|
-
prefix: 'c-',
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
class SlideshowIndicator extends Component {
|
|
20
|
-
render() {
|
|
21
|
-
const { slideshow, activeSlide, gotoSlide } = this.props;
|
|
22
|
-
return (
|
|
23
|
-
<div {...classes('indicator-wrapper')}>
|
|
24
|
-
{slideshow.map((slide, index) => (
|
|
25
|
-
<button
|
|
26
|
-
key={`indicator_${index}`} // eslint-disable-line react/no-array-index-key
|
|
27
|
-
type="button"
|
|
28
|
-
{...classes('indicator-dot', index === activeSlide ? 'active' : '')}
|
|
29
|
-
onClick={() => gotoSlide(index, true)}>
|
|
30
|
-
<span />
|
|
31
|
-
</button>
|
|
32
|
-
))}
|
|
33
|
-
</div>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
SlideshowIndicator.propTypes = {
|
|
39
|
-
slideshow: PropTypes.arrayOf(movieShape),
|
|
40
|
-
activeSlide: PropTypes.number,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export default SlideshowIndicator;
|