Skip to content

Commit 863ee32

Browse files
authoredJan 4, 2022
Merge pull request #309 from tjallingt/canary
chore: release
2 parents 431debc + c563e8b commit 863ee32

File tree

9 files changed

+192
-132
lines changed

9 files changed

+192
-132
lines changed
 

‎.github/workflows/deploy.yml

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ jobs:
1111
steps:
1212
- name: Checkout
1313
uses: actions/checkout@v2
14-
- name: Use Node.js 14
15-
uses: actions/setup-node@v1
14+
- name: Setup Node.js
15+
uses: actions/setup-node@v2
1616
with:
17-
node-version: 14.x
17+
node-version-file: '.nvmrc'
18+
cache: 'yarn'
1819
- name: Install dependencies
19-
uses: bahmutov/npm-install@v1
20+
run: yarn install
2021
- name: Build example
2122
run: yarn example:build
2223
- name: Deploy to GitHub pages

‎.github/workflows/release.yml

+5-4
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ jobs:
1212
steps:
1313
- name: Checkout
1414
uses: actions/checkout@v2
15-
- name: Use Node.js 14
16-
uses: actions/setup-node@v1
15+
- name: Setup Node.js
16+
uses: actions/setup-node@v2
1717
with:
18-
node-version: 14.x
18+
node-version-file: '.nvmrc'
19+
cache: 'yarn'
1920
- name: Install dependencies
20-
uses: bahmutov/npm-install@v1
21+
run: yarn install
2122
- name: Run tests
2223
run: yarn test
2324
- name: Build

‎.github/workflows/tests.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@ jobs:
88
name: Node.js ${{ matrix.node }}
99
strategy:
1010
matrix:
11-
node: ["10.x", "11.x", "12.x", "13.x", "14.x", "15.x"]
11+
node: ['10.x', '11.x', '12.x', '13.x', '14.x', '15.x', '16.x', '17.x']
1212
steps:
1313
- name: Checkout
1414
uses: actions/checkout@v2
1515
- name: Setup Node.js ${{ matrix.node }}
16-
uses: actions/setup-node@v1
16+
uses: actions/setup-node@v2
1717
with:
1818
node-version: ${{ matrix.node }}
19+
cache: 'yarn'
1920
- name: Install dependencies
20-
uses: bahmutov/npm-install@v1
21+
run: yarn install
2122
- name: Run tests
2223
run: yarn test:ci

‎.nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
16.13

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ $ npm install react-youtube
2424
id={string} // defaults -> null
2525
className={string} // defaults -> null
2626
containerClassName={string} // defaults -> ''
27+
title={string} // defaults -> null
2728
opts={obj} // defaults -> {}
2829
onReady={func} // defaults -> noop
2930
onPlay={func} // defaults -> noop

‎index.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export interface YouTubeProps {
3737
id?: string;
3838
className?: string;
3939
containerClassName?: string;
40+
title?: string;
41+
loading?: 'lazy' | 'eager' | 'auto';
4042
opts?: Options;
4143
onReady?(event: { target: YouTubePlayer }): void;
4244
onError?(event: { target: YouTubePlayer; data: number }): void;

‎src/YouTube.js

+27-4
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ function shouldUpdateVideo(prevProps, props) {
3333
function filterResetOptions(opts) {
3434
return {
3535
...opts,
36+
height: 0,
37+
width: 0,
3638
playerVars: {
39+
...opts.playerVars,
3740
autoplay: 0,
3841
start: 0,
3942
end: 0,
40-
...opts.playerVars,
4143
},
4244
};
4345
}
@@ -52,7 +54,9 @@ function filterResetOptions(opts) {
5254
* @param {Object} props
5355
*/
5456
function shouldResetPlayer(prevProps, props) {
55-
return !isEqual(filterResetOptions(prevProps.opts), filterResetOptions(props.opts));
57+
return (
58+
prevProps.videoId !== props.videoId || !isEqual(filterResetOptions(prevProps.opts), filterResetOptions(props.opts))
59+
);
5660
}
5761

5862
/**
@@ -62,7 +66,13 @@ function shouldResetPlayer(prevProps, props) {
6266
* @param {Object} props
6367
*/
6468
function shouldUpdatePlayer(prevProps, props) {
65-
return prevProps.id !== props.id || prevProps.className !== props.className;
69+
return (
70+
prevProps.id !== props.id ||
71+
prevProps.className !== props.className ||
72+
prevProps.opts.width !== props.opts.width ||
73+
prevProps.opts.height !== props.opts.height ||
74+
prevProps.title !== props.title
75+
);
6676
}
6777

6878
class YouTube extends React.Component {
@@ -213,6 +223,12 @@ class YouTube extends React.Component {
213223
else iframe.removeAttribute('id');
214224
if (this.props.className) iframe.setAttribute('class', this.props.className);
215225
else iframe.removeAttribute('class');
226+
if (this.props.opts && this.props.opts.width) iframe.setAttribute('width', this.props.opts.width);
227+
else iframe.removeAttribute('width');
228+
if (this.props.opts && this.props.opts.height) iframe.setAttribute('height', this.props.opts.height);
229+
else iframe.removeAttribute('height');
230+
if (typeof this.props.title === 'string') iframe.setAttribute('title', this.props.title);
231+
else iframe.setAttribute('title', 'YouTube video player');
216232
});
217233
};
218234

@@ -265,7 +281,7 @@ class YouTube extends React.Component {
265281
render() {
266282
return (
267283
<div className={this.props.containerClassName}>
268-
<div id={this.props.id} className={this.props.className} ref={this.refContainer} />
284+
<div id={this.props.id} className={this.props.className} ref={this.refContainer} loading={this.props.loading} />
269285
</div>
270286
);
271287
}
@@ -281,6 +297,11 @@ YouTube.propTypes = {
281297
className: PropTypes.string,
282298
// custom class name for player container element
283299
containerClassName: PropTypes.string,
300+
// custom title for the iFrame, see https://www.w3.org/TR/WCAG20-TECHS/H64.html
301+
title: PropTypes.string,
302+
303+
// custom loading for player element
304+
loading: PropTypes.oneOf(['lazy', 'eager', 'auto']),
284305

285306
// https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player
286307
opts: PropTypes.objectOf(PropTypes.any),
@@ -300,6 +321,7 @@ YouTube.defaultProps = {
300321
videoId: null,
301322
id: null,
302323
className: null,
324+
loading: null,
303325
opts: {},
304326
containerClassName: '',
305327
onReady: () => {},
@@ -310,6 +332,7 @@ YouTube.defaultProps = {
310332
onStateChange: () => {},
311333
onPlaybackRateChange: () => {},
312334
onPlaybackQualityChange: () => {},
335+
title: null,
313336
};
314337

315338
export default YouTube;

‎src/Youtube.test.js

+55
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,22 @@ describe('YouTube', () => {
4444
expect(playerMock.getIframe).toHaveBeenCalled();
4545
});
4646

47+
it('should update the title when modified', () => {
48+
const { rerender } = render(<YouTube title="Video about a cat" videoId="XxVg_s8xAms" />);
49+
50+
rerender(<YouTube title="Video about a dancing cat" videoId="XxVg_s8xAms" />);
51+
52+
expect(playerMock.getIframe).toHaveBeenCalled();
53+
});
54+
55+
it('should update the title when removed', () => {
56+
const { rerender } = render(<YouTube title="Video about a cat" videoId="XxVg_s8xAms" />);
57+
58+
rerender(<YouTube videoId="XxVg_s8xAms" />);
59+
60+
expect(playerMock.getIframe).toHaveBeenCalled();
61+
});
62+
4763
it('should not update id and className when no change in them', () => {
4864
const className = 'custom-class';
4965
const videoId = 'XxVg_s8xAms';
@@ -117,6 +133,8 @@ describe('YouTube', () => {
117133
width: '480px',
118134
height: '360px',
119135
playerVars: {
136+
height: 0, // changed, does not force destroy & rebind
137+
width: 0, // changed, does not force destroy & rebind
120138
autoplay: 1, // changed, does not force destroy & rebind
121139
start: 10, // changed, does not force destroy & rebind
122140
end: 20, // changed, does not force destroy & rebind
@@ -127,6 +145,43 @@ describe('YouTube', () => {
127145

128146
// player is destroyed & rebound, despite the changes
129147
expect(playerMock.destroy).toHaveBeenCalled();
148+
// and the video is updated
149+
expect(playerMock.loadVideoById).toHaveBeenCalled();
150+
});
151+
152+
it('should not create and bind a new YouTube player when only playerVars.autoplay, playerVars.start, or playerVars.end change', () => {
153+
const { rerender } = render(
154+
<YouTube
155+
videoId="XxVg_s8xAms"
156+
opts={{
157+
width: '480px',
158+
height: '360px',
159+
playerVars: {
160+
autoplay: 0,
161+
start: 0,
162+
end: 50,
163+
},
164+
}}
165+
/>,
166+
);
167+
168+
rerender(
169+
<YouTube
170+
videoId="XxVg_s8xAms"
171+
opts={{
172+
width: '480px',
173+
height: '360px',
174+
playerVars: {
175+
autoplay: 1, // changed, does not force destroy & rebind
176+
start: 10, // changed, does not force destroy & rebind
177+
end: 20, // changed, does not force destroy & rebind
178+
},
179+
}}
180+
/>,
181+
);
182+
183+
// player is destroyed & rebound, despite the changes
184+
expect(playerMock.destroy).not.toHaveBeenCalled();
130185
// instead only the video is updated
131186
expect(playerMock.loadVideoById).toHaveBeenCalled();
132187
});

‎yarn.lock

+92-117
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.