1
- import React , { useState , useRef , useEffect } from 'react' ;
1
+ import React , { useState , useRef } from 'react' ;
2
2
import clsx from 'clsx' ;
3
3
4
4
export interface VideoProps {
5
5
className ?: string ;
6
- src : string ;
6
+ src ? : string ;
7
7
cover ?: string ;
8
8
duration ?: string | number ;
9
9
style ?: React . CSSProperties ;
10
+ videoRef ?: React . RefObject < HTMLVideoElement > ;
10
11
onClick ?: ( paused : boolean , event : React . MouseEvent ) => void ;
11
12
onCoverLoad ?: ( event : React . SyntheticEvent ) => void ;
12
13
}
13
14
14
15
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 ;
16
28
17
29
const [ isPlayed , setIsPlayed ] = useState ( false ) ;
18
30
const [ paused , setPaused ] = useState ( true ) ;
19
- const videoRef = useRef < HTMLVideoElement > ( null ) ;
20
31
21
32
function handleClick ( e : React . MouseEvent ) {
22
33
setIsPlayed ( true ) ;
@@ -34,52 +45,42 @@ export const Video: React.FC<VideoProps> = (props) => {
34
45
}
35
46
}
36
47
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
+ }
45
51
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
+ }
51
55
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 ;
60
58
61
59
return (
62
60
< div
63
61
className = { clsx ( 'Video' , `Video--${ paused ? 'paused' : 'playing' } ` , className ) }
64
62
style = { style }
65
63
>
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 > }
72
66
< video
73
67
className = "Video-video"
74
68
src = { src }
75
69
ref = { videoRef }
76
- hidden = { ! ! cover && ! isPlayed }
70
+ hidden = { hasCover }
77
71
controls
72
+ onPlay = { handlePlay }
73
+ onPause = { handlePause }
74
+ onEnded = { handlePause }
78
75
{ ...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
+ ) }
83
84
</ div >
84
85
) ;
85
- } ;
86
+ } ;
0 commit comments