Skip to content

Commit 3d91644

Browse files
committed
fix: [Video] show the play button when the cover is specified
1 parent 3199031 commit 3d91644

File tree

3 files changed

+63
-37
lines changed

3 files changed

+63
-37
lines changed

src/components/Video/index.tsx

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
1-
import React, { useState, useRef, useEffect } from 'react';
1+
import React, { useState, useRef } from 'react';
22
import clsx from 'clsx';
33

44
export interface VideoProps {
55
className?: string;
6-
src: string;
6+
src?: string;
77
cover?: string;
88
duration?: string | number;
99
style?: React.CSSProperties;
10+
videoRef?: React.RefObject<HTMLVideoElement>;
1011
onClick?: (paused: boolean, event: React.MouseEvent) => void;
1112
onCoverLoad?: (event: React.SyntheticEvent) => void;
1213
}
1314

1415
export const Video: React.FC<VideoProps> = (props) => {
15-
const { className, src, cover, duration, onClick, onCoverLoad, style, ...other } = props;
16+
const {
17+
className,
18+
src,
19+
cover,
20+
duration,
21+
onClick,
22+
onCoverLoad,
23+
style,
24+
videoRef = useRef<HTMLVideoElement>(null),
25+
children,
26+
...other
27+
} = props;
1628

1729
const [isPlayed, setIsPlayed] = useState(false);
1830
const [paused, setPaused] = useState(true);
19-
const videoRef = useRef<HTMLVideoElement>(null);
2031

2132
function handleClick(e: React.MouseEvent) {
2233
setIsPlayed(true);
@@ -34,52 +45,42 @@ export const Video: React.FC<VideoProps> = (props) => {
3445
}
3546
}
3647

37-
useEffect(() => {
38-
const video = videoRef.current;
39-
const handlePlay = () => {
40-
setPaused(false);
41-
};
42-
const handlePause = () => {
43-
setPaused(true);
44-
};
48+
function handlePlay() {
49+
setPaused(false);
50+
}
4551

46-
if (video) {
47-
video.addEventListener('play', handlePlay);
48-
video.addEventListener('pause', handlePause);
49-
video.addEventListener('ended', handlePause);
50-
}
52+
function handlePause() {
53+
setPaused(true);
54+
}
5155

52-
return () => {
53-
if (video) {
54-
video.removeEventListener('play', handlePlay);
55-
video.removeEventListener('pause', handlePause);
56-
video.removeEventListener('ended', handlePause);
57-
}
58-
};
59-
}, []);
56+
const hasCover = !isPlayed && !!cover;
57+
const hasDuration = hasCover && !!duration;
6058

6159
return (
6260
<div
6361
className={clsx('Video', `Video--${paused ? 'paused' : 'playing'}`, className)}
6462
style={style}
6563
>
66-
{!isPlayed && (
67-
<>
68-
{cover && <img className="Video-cover" src={cover} onLoad={onCoverLoad} alt="" />}
69-
{duration && <span className="Video-duration">{duration}</span>}
70-
</>
71-
)}
64+
{hasCover && <img className="Video-cover" src={cover} onLoad={onCoverLoad} alt="" />}
65+
{hasDuration && <span className="Video-duration">{duration}</span>}
7266
<video
7367
className="Video-video"
7468
src={src}
7569
ref={videoRef}
76-
hidden={!!cover && !isPlayed}
70+
hidden={hasCover}
7771
controls
72+
onPlay={handlePlay}
73+
onPause={handlePause}
74+
onEnded={handlePause}
7875
{...other}
79-
/>
80-
<button className={clsx('Video-playBtn', { paused })} type="button" onClick={handleClick}>
81-
<span className="Video-playIcon" />
82-
</button>
76+
>
77+
{children}
78+
</video>
79+
{hasCover && (
80+
<button className={clsx('Video-playBtn', { paused })} type="button" onClick={handleClick}>
81+
<span className="Video-playIcon" />
82+
</button>
83+
)}
8384
</div>
8485
);
85-
};
86+
};

src/components/Video/style.less

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
padding: 0;
3434
border: 0;
3535
background: transparent;
36+
37+
&:hover {
38+
cursor: pointer;
39+
}
3640
}
3741

3842
.Video-playIcon {

storybook/stories/Video.stories.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react';
2+
import { Story, Meta } from '@storybook/react/types-6-0';
3+
4+
import { Video, VideoProps } from '../../src';
5+
// import '../../src/components/Video/style.less';
6+
7+
export default {
8+
title: 'Video',
9+
component: Video,
10+
} as Meta;
11+
12+
const Template: Story<VideoProps> = (args) => <Video {...args} />;
13+
14+
export const Default = Template.bind({});
15+
Default.args = {
16+
src: '//interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4',
17+
alt: 'flower',
18+
style: {
19+
width: '320px'
20+
}
21+
};

0 commit comments

Comments
 (0)