@ilo-org/react 0.10.5 → 0.11.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.
Files changed (195) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/lib/cjs/AccordionCtx-be704051.js +9 -0
  3. package/lib/cjs/{GlobalCtx-97e4b433.js → GlobalCtx-10114bdd.js} +2 -2
  4. package/lib/cjs/ListCtx-14aa546f.js +9 -0
  5. package/lib/cjs/TagCtx-690a1d54.js +7 -0
  6. package/lib/cjs/components/Accordion/Accordion.js +6 -6
  7. package/lib/cjs/components/Accordion/AccordionButton.js +5 -5
  8. package/lib/cjs/components/Accordion/AccordionItem.js +2 -2
  9. package/lib/cjs/components/Accordion/AccordionPanel.js +8 -8
  10. package/lib/cjs/components/Accordion/index.js +2 -2
  11. package/lib/cjs/components/Breadcrumb/Breadcrumb.js +5 -5
  12. package/lib/cjs/components/Breadcrumb/index.js +1 -1
  13. package/lib/cjs/components/Button/Button.js +1 -1
  14. package/lib/cjs/components/Button/index.js +1 -1
  15. package/lib/cjs/components/Callout/Callout.js +4 -4
  16. package/lib/cjs/components/Callout/index.js +1 -1
  17. package/lib/cjs/components/Card/Card.js +2 -2
  18. package/lib/cjs/components/Card/CardGroup.js +2 -2
  19. package/lib/cjs/components/Card/index.js +2 -2
  20. package/lib/cjs/components/Checkbox/Checkbox.js +5 -5
  21. package/lib/cjs/components/Checkbox/index.js +1 -1
  22. package/lib/cjs/components/Collapse/Collapse.js +1194 -44
  23. package/lib/cjs/components/Collapse/index.js +0 -1
  24. package/lib/cjs/components/ContextMenu/ContextMenu.js +1 -1
  25. package/lib/cjs/components/ContextMenu/index.js +1 -1
  26. package/lib/cjs/components/Credit/Credit.js +3 -3
  27. package/lib/cjs/components/Credit/index.js +1 -1
  28. package/lib/cjs/components/DatePicker/DatePicker.js +4 -4
  29. package/lib/cjs/components/DatePicker/index.js +1 -1
  30. package/lib/cjs/components/Dropdown/Dropdown.js +5 -5
  31. package/lib/cjs/components/Dropdown/index.js +1 -1
  32. package/lib/cjs/components/Empty/Empty.js +1 -1
  33. package/lib/cjs/components/Empty/index.js +1 -1
  34. package/lib/cjs/components/Fieldset/Fieldset.js +5 -5
  35. package/lib/cjs/components/Fieldset/index.js +1 -1
  36. package/lib/cjs/components/FileUpload/FileUpload.js +5 -5
  37. package/lib/cjs/components/FileUpload/index.js +1 -1
  38. package/lib/cjs/components/Footer/Footer.js +1 -1
  39. package/lib/cjs/components/Footer/index.js +1 -1
  40. package/lib/cjs/components/Form/Form.js +3 -3
  41. package/lib/cjs/components/Form/index.js +1 -1
  42. package/lib/cjs/components/FormControl/FormControl.js +7 -7
  43. package/lib/cjs/components/FormControl/index.js +1 -1
  44. package/lib/cjs/components/GlobalProvider/GlobalProvider.js +1 -1
  45. package/lib/cjs/components/GlobalProvider/index.js +1 -1
  46. package/lib/cjs/components/Heading/Heading.js +1 -1
  47. package/lib/cjs/components/Heading/index.js +1 -1
  48. package/lib/cjs/components/Hero/Hero.js +1 -1
  49. package/lib/cjs/components/Hero/HeroCard.js +1 -1
  50. package/lib/cjs/components/Hero/index.js +1 -1
  51. package/lib/cjs/components/Icon/Icon.js +3 -3
  52. package/lib/cjs/components/Icon/index.js +1 -1
  53. package/lib/cjs/components/Image/Image.js +1 -1
  54. package/lib/cjs/components/Image/index.js +1 -1
  55. package/lib/cjs/components/Input/Input.js +3 -3
  56. package/lib/cjs/components/Input/index.js +1 -1
  57. package/lib/cjs/components/Link/Link.js +1 -1
  58. package/lib/cjs/components/Link/index.js +1 -1
  59. package/lib/cjs/components/LinkList/LinkList.js +1 -1
  60. package/lib/cjs/components/LinkList/index.js +1 -1
  61. package/lib/cjs/components/List/List.js +4 -4
  62. package/lib/cjs/components/List/ListItem.js +2 -2
  63. package/lib/cjs/components/List/index.js +2 -2
  64. package/lib/cjs/components/Loading/Loading.js +1 -1
  65. package/lib/cjs/components/Loading/index.js +1 -1
  66. package/lib/cjs/components/LocalNav/LocalNav.js +4 -4
  67. package/lib/cjs/components/LocalNav/index.js +1 -1
  68. package/lib/cjs/components/Logo/Logo.js +15 -15
  69. package/lib/cjs/components/Logo/index.js +1 -1
  70. package/lib/cjs/components/LogoGrid/LogoGrid.js +1 -1
  71. package/lib/cjs/components/LogoGrid/index.js +1 -1
  72. package/lib/cjs/components/Navigation/Navigation.js +8 -6
  73. package/lib/cjs/components/Navigation/index.js +3 -1
  74. package/lib/cjs/components/Notification/Notification.js +3 -3
  75. package/lib/cjs/components/Notification/index.js +1 -1
  76. package/lib/cjs/components/NumberPicker/NumberPicker.js +4 -4
  77. package/lib/cjs/components/NumberPicker/index.js +1 -1
  78. package/lib/cjs/components/Pagination/Pagination.js +1 -1
  79. package/lib/cjs/components/Pagination/index.js +1 -1
  80. package/lib/cjs/components/Profile/Profile.js +1 -1
  81. package/lib/cjs/components/Profile/index.js +1 -1
  82. package/lib/cjs/components/Radio/Radio.js +5 -5
  83. package/lib/cjs/components/Radio/index.js +1 -1
  84. package/lib/cjs/components/ReadMore/ReadMore.js +4 -4
  85. package/lib/cjs/components/ReadMore/index.js +1 -1
  86. package/lib/cjs/components/RichText/RichText.js +1 -1
  87. package/lib/cjs/components/RichText/index.js +1 -1
  88. package/lib/cjs/components/SearchField/SearchField.js +16 -6
  89. package/lib/cjs/components/SearchField/index.js +4 -2
  90. package/lib/cjs/components/SocialMedia/SocialMedia.js +1 -1
  91. package/lib/cjs/components/SocialMedia/index.js +1 -1
  92. package/lib/cjs/components/TableOfContents/TableOfContents.js +1 -1
  93. package/lib/cjs/components/TableOfContents/index.js +1 -1
  94. package/lib/cjs/components/Tabs/Tabs.args.js +156 -0
  95. package/lib/cjs/components/Tabs/Tabs.js +24 -0
  96. package/lib/cjs/components/Tabs/index.js +15 -0
  97. package/lib/cjs/components/Tag/Tag.js +4 -4
  98. package/lib/cjs/components/Tag/TagSet.js +6 -6
  99. package/lib/cjs/components/Tag/index.js +2 -2
  100. package/lib/cjs/components/TextInput/TextInput.js +4 -4
  101. package/lib/cjs/components/TextInput/index.js +1 -1
  102. package/lib/cjs/components/Textarea/Textarea.js +4 -4
  103. package/lib/cjs/components/Textarea/index.js +1 -1
  104. package/lib/cjs/components/Toggle/Toggle.js +4 -4
  105. package/lib/cjs/components/Toggle/index.js +1 -1
  106. package/lib/cjs/components/Tooltip/Tooltip.js +5 -5
  107. package/lib/cjs/components/Tooltip/index.js +1 -1
  108. package/lib/cjs/components/Video/Video.js +11 -12
  109. package/lib/cjs/components/Video/VideoPlayer.js +55 -13
  110. package/lib/cjs/components/Video/index.js +6 -8
  111. package/lib/cjs/components/index.js +9 -8
  112. package/lib/cjs/hooks/index.js +1 -1
  113. package/lib/cjs/hooks/useGlobalSettings.js +3 -3
  114. package/lib/cjs/hooks/usePrevious.js +3 -3
  115. package/lib/cjs/hooks/useVideoPlayer.js +7 -7
  116. package/lib/cjs/index.js +9 -8
  117. package/lib/esm/components/Collapse/Collapse.js +1156 -6
  118. package/lib/esm/components/Collapse/index.js +0 -1
  119. package/lib/esm/components/FileUpload/FileUpload.js +3 -3
  120. package/lib/esm/components/Input/Input.js +2 -2
  121. package/lib/esm/components/Navigation/Navigation.js +2 -0
  122. package/lib/esm/components/Navigation/index.js +2 -0
  123. package/lib/esm/components/NumberPicker/NumberPicker.js +3 -3
  124. package/lib/esm/components/Radio/Radio.js +3 -3
  125. package/lib/esm/components/SearchField/SearchField.js +15 -5
  126. package/lib/esm/components/SearchField/index.js +3 -1
  127. package/lib/esm/components/Tabs/Tabs.args.js +154 -0
  128. package/lib/esm/components/Tabs/Tabs.js +22 -0
  129. package/lib/esm/components/Tabs/index.js +9 -0
  130. package/lib/esm/components/TextInput/TextInput.js +3 -3
  131. package/lib/esm/components/Textarea/Textarea.js +3 -3
  132. package/lib/esm/components/Video/Video.js +10 -11
  133. package/lib/esm/components/Video/VideoPlayer.js +57 -11
  134. package/lib/esm/components/Video/index.js +5 -7
  135. package/lib/esm/components/index.js +4 -4
  136. package/lib/esm/index.js +4 -4
  137. package/lib/types/react/src/components/Input/Input.props.d.ts +1 -0
  138. package/lib/types/react/src/components/Tabs/Tabs.args.d.ts +10 -0
  139. package/lib/types/react/src/components/Tabs/Tabs.d.ts +4 -0
  140. package/lib/types/react/src/components/Tabs/Tabs.props.d.ts +12 -0
  141. package/lib/types/react/src/components/Tabs/index.d.ts +1 -0
  142. package/lib/types/react/src/components/Video/Video.d.ts +2 -2
  143. package/lib/types/react/src/components/Video/Video.props.d.ts +5 -43
  144. package/lib/types/react/src/components/Video/VideoPlayer.d.ts +3 -3
  145. package/lib/types/react/src/components/Video/VideoPlayer.props.d.ts +6 -31
  146. package/lib/types/react/src/components/index.d.ts +1 -0
  147. package/package.json +6 -4
  148. package/src/components/Input/Input.props.ts +2 -0
  149. package/src/components/Input/Input.tsx +2 -0
  150. package/src/components/SearchField/SearchField.args.ts +5 -0
  151. package/src/components/SearchField/SearchField.tsx +38 -16
  152. package/src/components/Tabs/Tabs.args.tsx +201 -0
  153. package/src/components/Tabs/Tabs.props.ts +13 -0
  154. package/src/components/Tabs/Tabs.tsx +60 -0
  155. package/src/components/Tabs/index.ts +1 -0
  156. package/src/components/Video/Video.args.ts +18 -24
  157. package/src/components/Video/Video.props.ts +5 -47
  158. package/src/components/Video/Video.tsx +24 -19
  159. package/src/components/Video/VideoPlayer.props.ts +7 -38
  160. package/src/components/Video/VideoPlayer.tsx +67 -322
  161. package/src/components/index.ts +1 -0
  162. package/src/declarations.d.ts +22 -0
  163. package/lib/cjs/AccordionCtx-fe08ff45.js +0 -9
  164. package/lib/cjs/DailyMotion-17b56ecb.js +0 -259
  165. package/lib/cjs/Facebook-0c8d86ee.js +0 -239
  166. package/lib/cjs/FilePlayer-01d6dc08.js +0 -596
  167. package/lib/cjs/Kaltura-40e8e581.js +0 -235
  168. package/lib/cjs/ListCtx-7db7fe04.js +0 -9
  169. package/lib/cjs/Mixcloud-e23f49d6.js +0 -222
  170. package/lib/cjs/Preview-8e490f54.js +0 -227
  171. package/lib/cjs/SoundCloud-2500b6cb.js +0 -249
  172. package/lib/cjs/Streamable-00723065.js +0 -234
  173. package/lib/cjs/TagCtx-929c7753.js +0 -7
  174. package/lib/cjs/Twitch-2c5c5733.js +0 -244
  175. package/lib/cjs/VideoPlayer-5f0a64c6.js +0 -2067
  176. package/lib/cjs/Vidyard-d36d6c45.js +0 -237
  177. package/lib/cjs/Vimeo-d311e3b8.js +0 -285
  178. package/lib/cjs/Wistia-318b4e43.js +0 -288
  179. package/lib/cjs/YouTube-a3796a55.js +0 -377
  180. package/lib/cjs/index-0af02e81.js +0 -1154
  181. package/lib/esm/DailyMotion-989c2db3.js +0 -257
  182. package/lib/esm/Facebook-04e9cc59.js +0 -237
  183. package/lib/esm/FilePlayer-0789336d.js +0 -594
  184. package/lib/esm/Kaltura-a9ed37a9.js +0 -233
  185. package/lib/esm/Mixcloud-5a3b4353.js +0 -220
  186. package/lib/esm/Preview-7ca1835e.js +0 -225
  187. package/lib/esm/SoundCloud-47bccd79.js +0 -247
  188. package/lib/esm/Streamable-ee762126.js +0 -232
  189. package/lib/esm/Twitch-3cd4b54b.js +0 -242
  190. package/lib/esm/VideoPlayer-96c2b20c.js +0 -2062
  191. package/lib/esm/Vidyard-258ab0ef.js +0 -235
  192. package/lib/esm/Vimeo-4b29b580.js +0 -283
  193. package/lib/esm/Wistia-3cbce669.js +0 -286
  194. package/lib/esm/YouTube-db52da1c.js +0 -375
  195. package/lib/esm/index-623ce3f5.js +0 -1152
@@ -1,45 +1,39 @@
1
1
  import { VideoProps } from "./Video.props";
2
2
 
3
3
  const videofile: VideoProps = {
4
- alt: "The ILO logo on a blue background",
5
4
  className: "image",
6
5
  caption:
7
6
  "The ILO brings together governments, employers and workers to set labour standards and promote decent work.",
8
7
  poster: {
9
- url: [{ src: "/media-file-poster.jpg" }],
10
- alt: "",
8
+ src: "/media-file-poster.jpg",
9
+ alt: "The ILO logo on a blue background",
11
10
  },
12
- video: {
13
- controls: {
14
- fullscreen: "Fullscreen",
15
- play: "Play",
16
- pause: "Pause",
17
- volume: "Volume",
18
- },
19
- src: "/video-example.mp4",
20
- youtube: false,
11
+ controls: {
12
+ fullscreen: "Fullscreen",
13
+ play: "Play",
14
+ pause: "Pause",
15
+ volume: "Volume",
21
16
  },
17
+ src: "/video-example.mp4",
18
+ youtube: false,
22
19
  };
23
20
 
24
21
  const videoyt: VideoProps = {
25
- alt: "An smiling woman with gray hair holds a bowl full of corn in front of her home.",
26
22
  caption:
27
23
  "Indigenous entrepreneur Celestina Ábalos runs a tourism business in the UNESCO World Heritage site of Quebrada de Humahuaca in northern Argentina. ©ILO/Ivar Velasquez",
28
24
  className: "image",
29
25
  poster: {
30
- url: [{ src: "/youtube-video-poster.avif" }],
31
- alt: "",
26
+ src: "/youtube-video-poster.avif",
27
+ alt: "An smiling woman with gray hair holds a bowl full of corn in front of her home.",
32
28
  },
33
- video: {
34
- controls: {
35
- fullscreen: "Fullscreen",
36
- play: "Play",
37
- pause: "Pause",
38
- volume: "Volume",
39
- },
40
- src: "https://youtu.be/X72_A4_6zjU",
41
- youtube: true,
29
+ controls: {
30
+ fullscreen: "Fullscreen",
31
+ play: "Play",
32
+ pause: "Pause",
33
+ volume: "Volume",
42
34
  },
35
+ src: "https://youtu.be/X72_A4_6zjU",
36
+ youtube: true,
43
37
  };
44
38
 
45
39
  /**
@@ -1,59 +1,22 @@
1
- import { TracksConfig } from "./VideoPlayer.props";
1
+ import { VideoPlayerControls } from "./VideoPlayer.props";
2
2
 
3
3
  export interface Poster {
4
- url: { src: string }[];
4
+ src: string;
5
5
  alt: string;
6
6
  }
7
7
 
8
- interface VideoPlayerControls {
9
- /**
10
- * Specify the label for the fullscreen button
11
- */
12
- fullscreen?: Required<string>;
13
-
14
- /**
15
- * Specify the label for the play button
16
- */
17
- play?: Required<string>;
18
-
19
- /**
20
- * Specify the label for the pause button
21
- */
22
- pause?: Required<string>;
23
-
24
- /**
25
- * Specify the label for the volume button
26
- */
27
- volume?: Required<string>;
28
- }
8
+ export interface VideoProps {
9
+ src: string;
29
10
 
30
- interface Video {
31
11
  /**
32
12
  * Specify the strings to be used as labels for the video controls
33
13
  */
34
- controls?: Required<VideoPlayerControls | false>;
35
-
36
- /**
37
- * if self-hosted, specify the url of this video
38
- */
39
- src?: string | null;
40
-
41
- /**
42
- * if there are closed-caption tracks,
43
- */
44
- tracks?: TracksConfig[];
14
+ controls?: VideoPlayerControls;
45
15
 
46
16
  /**
47
17
  * if YouTube, set to true
48
18
  */
49
19
  youtube?: boolean;
50
- }
51
-
52
- export interface VideoProps {
53
- /**
54
- * Specify the alt for the image
55
- */
56
- alt: string;
57
20
 
58
21
  /**
59
22
  * Specify the caption for the image/video
@@ -69,9 +32,4 @@ export interface VideoProps {
69
32
  * Specify the image src for the image
70
33
  */
71
34
  poster?: Poster;
72
-
73
- /**
74
- * Specify whether there is a video being shown
75
- */
76
- video: Video;
77
35
  }
@@ -1,29 +1,34 @@
1
- import { FC } from "react";
1
+ import { forwardRef } from "react";
2
2
  import classNames from "classnames";
3
3
  import useGlobalSettings from "../../hooks/useGlobalSettings";
4
4
  import { VideoProps } from "./Video.props";
5
5
  import VideoPlayer from "./VideoPlayer";
6
+ import { VideoPlayerRef } from "./VideoPlayer.props";
6
7
 
7
- const Video: FC<VideoProps> = ({ className, caption, poster, video }) => {
8
- const { prefix } = useGlobalSettings();
9
- const baseClass = `${prefix}--legacyvideo`;
8
+ const Video = forwardRef<VideoPlayerRef, VideoProps>(
9
+ ({ className, caption, ...video }, ref) => {
10
+ const { prefix } = useGlobalSettings();
11
+ const baseClass = `${prefix}--video`;
10
12
 
11
- const videoClasses = classNames(className, {
12
- [baseClass]: true,
13
- });
13
+ const videoClasses = classNames(className, {
14
+ [baseClass]: true,
15
+ });
14
16
 
15
- const captionClasses = classNames("", {
16
- [`${baseClass}--caption`]: true,
17
- });
17
+ const captionClasses = classNames("", {
18
+ [`${baseClass}--caption`]: true,
19
+ });
18
20
 
19
- return (
20
- <figure className={videoClasses}>
21
- <div className={`${videoClasses}--wrapper`}>
22
- {video && <VideoPlayer {...video} poster={poster} />}
23
- </div>
24
- {caption && <figcaption className={captionClasses}>{caption}</figcaption>}
25
- </figure>
26
- );
27
- };
21
+ return (
22
+ <figure className={videoClasses}>
23
+ <div className={`${videoClasses}--wrapper`}>
24
+ {video && <VideoPlayer {...video} ref={ref} />}
25
+ </div>
26
+ {caption && (
27
+ <figcaption className={captionClasses}>{caption}</figcaption>
28
+ )}
29
+ </figure>
30
+ );
31
+ }
32
+ );
28
33
 
29
34
  export default Video;
@@ -1,5 +1,9 @@
1
1
  import { Poster } from "./Video.props";
2
+ import videojs from "video.js";
2
3
 
4
+ export interface VideoPlayerRef {
5
+ player: videojs.Player | undefined;
6
+ }
3
7
  export interface VideoPlayerControls {
4
8
  /**
5
9
  * Specify the label for the fullscreen button
@@ -22,29 +26,9 @@ export interface VideoPlayerControls {
22
26
  volume: string;
23
27
  }
24
28
 
25
- export interface TracksConfig {
26
- /**
27
- * is this the default track?
28
- */
29
- default?: boolean;
30
-
31
- /**
32
- * What kind of track is it?
33
- */
34
- kind?: string;
35
-
36
- /**
37
- * url for the track
38
- */
39
- src?: string;
40
-
41
- /**
42
- * language of the track
43
- */
44
- srcLang?: string;
45
- }
46
-
47
29
  export interface VideoPlayerProps {
30
+ src: string;
31
+
48
32
  /**
49
33
  * Specify an optional className to be added to your Media.
50
34
  */
@@ -53,28 +37,13 @@ export interface VideoPlayerProps {
53
37
  /**
54
38
  * Specify the strings to be used as labels for the video controls
55
39
  */
56
- controls?: Required<VideoPlayerControls | false>;
57
-
58
- /**
59
- * Specify whether a video is to be shown
60
- */
61
- hasvideo?: Required<boolean>;
40
+ controls?: VideoPlayerControls;
62
41
 
63
42
  /**
64
43
  * poster image for video
65
44
  */
66
45
  poster?: Poster;
67
46
 
68
- /**
69
- * if self-hosted, specify the url of this video
70
- */
71
- src?: string | null;
72
-
73
- /**
74
- * if there are closed-caption tracks,
75
- */
76
- tracks?: Required<Array<TracksConfig>> | null;
77
-
78
47
  /**
79
48
  * if YouTube, set to true
80
49
  */
@@ -1,326 +1,71 @@
1
- import {
2
- FC,
3
- FocusEvent,
4
- MouseEvent,
5
- createRef,
6
- useCallback,
7
- useState,
8
- } from "react";
9
- /* temporary way of importing ReactPlayer due to a known issue with ReactPlayer.
10
- * Revert to standard method of importing once RP's dev has fixed.
11
- */
12
- import { default as RP } from "react-player/lazy";
13
- import { findDOMNode } from "react-dom";
14
- import { ReactPlayerProps } from "react-player/types/lib";
15
- const ReactPlayer = RP as unknown as FC<ReactPlayerProps>;
16
- import classNames from "classnames";
17
- import useGlobalSettings from "../../hooks/useGlobalSettings";
18
- import { VideoPlayerProps } from "./VideoPlayer.props";
19
- import hoursMinutesSeconds from "../../utils/hoursMinutesSeconds";
20
- import screenfull from "screenfull";
21
-
22
- const VideoPlayer: FC<VideoPlayerProps> = ({
23
- controls,
24
- src,
25
- poster,
26
- youtube,
27
- tracks,
28
- }) => {
29
- const { prefix } = useGlobalSettings();
30
- const baseClass = `${prefix}--legacyvideo`;
31
-
32
- const playerClasses = classNames("", {
33
- [`${baseClass}--player`]: true,
34
- [`youtube`]: youtube,
35
- });
36
-
37
- const controlsClasses = classNames("", {
38
- [`${baseClass}--controls`]: true,
39
- });
40
-
41
- /**
42
- * State hooks for our player controls
43
- */
44
- const [duration, setDuration] = useState("0:00");
45
- const [playedtime, setPlayedtime] = useState("0:00");
46
- const [buffer, setBuffer] = useState(0);
47
- const [playing, setPlaying] = useState(false);
48
- const [playhead, setPlayhead] = useState(0);
49
- const [volume, setVolume] = useState(0.8);
50
- const [muted, setMute] = useState(false);
51
- const [showposter, showPoster] = useState(true);
52
- const [showvolume, showVolume] = useState(false);
53
- const [seeking, setSeeking] = useState(false);
54
-
55
- /**
56
- * Ref for the video element
57
- */
58
- const videoElement = createRef();
59
-
60
- /**
61
- * Ref for the video container
62
- */
63
- const videoContainer = createRef();
64
-
65
- const youtubeparams = {
66
- controls: 0,
67
- modestbranding: 1,
68
- };
69
-
70
- const playerconfig = {
71
- file: {
72
- tracks: tracks || [],
73
- },
74
- youtube: youtube ? { playerVars: youtubeparams } : {},
75
- };
76
-
77
- /**
78
- * Fullscreen functionality
79
- */
80
- const toggleFullscreen = () => {
81
- /* This is a known issue with ReactPlayer */
82
- /* @ts-ignore */
83
- screenfull.request(findDOMNode(videoContainer.current));
84
- };
85
-
86
- /**
87
- * Play/pause functionality
88
- */
89
- const togglePlay = () => {
90
- setPlaying(!playing);
91
- showPoster(false);
92
- };
93
-
94
- /**
95
- * Show volume slider
96
- */
97
- const showVolumeSlider = () => {
98
- showVolume(true);
99
- };
100
-
101
- /**
102
- * Hide volume slider
103
- */
104
- const hideVolumeSlider = () => {
105
- setTimeout(() => {
106
- showVolume(false);
107
- }, 2000);
108
- };
109
-
110
- /**
111
- * Mute/unmute
112
- */
113
- const toggleMute = () => {
114
- setMute(!muted);
115
- hideVolumeSlider();
116
- };
117
-
118
- /**
119
- * Volume change
120
- */
121
- const handleVolumeChange = (event: any) => {
122
- console.log("handleVolumeChange", event.target.value);
123
- setVolume(event.target.value * 0.1);
124
- };
125
-
126
- /**
127
- * Begin seek
128
- */
129
- const handleSeekMouseDown = () => {
130
- setSeeking(true);
131
- };
132
-
133
- /**
134
- * Seek
135
- */
136
- const handleSeekChange = (event: any) => {
137
- setPlayhead(parseFloat(event.target.value));
138
- };
139
-
140
- /**
141
- * End seek
142
- */
143
- const handleSeekMouseUp = (event: any) => {
144
- setSeeking(false);
145
- /* This is a known issue with ReactPlayer */
146
- /* @ts-ignore */
147
- videoElement.current.seekTo(parseFloat(event.target.value));
148
- };
149
-
150
- /**
151
- * handle display of progress
152
- */
153
- const handleProgress = (state: any) => {
154
- if (!seeking) {
155
- setPlayhead(state.played);
156
- setBuffer(state.loaded);
157
- setPlayedtime(hoursMinutesSeconds(state.playedSeconds));
158
- }
159
- };
160
-
161
- /**
162
- * get the duration to display
163
- */
164
- const handleDuration = (duration: any) => {
165
- setDuration(hoursMinutesSeconds(duration));
166
- };
167
-
168
- /**
169
- * on video end
170
- */
171
- const handleEnded = () => {
172
- setPlaying(false);
173
- setSeeking(false);
174
- };
175
-
176
- const handlePlayHover = useCallback(
177
- (
178
- event: MouseEvent<HTMLButtonElement> | FocusEvent<HTMLButtonElement>,
179
- state: boolean
180
- ) => {
181
- const element = event.currentTarget;
182
- if (!element.classList.contains(`${controlsClasses}--play`)) {
183
- return;
1
+ import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
2
+ import "videojs-youtube";
3
+ import { VideoPlayerProps, VideoPlayerRef } from "./VideoPlayer.props";
4
+ import videojs, { ILOVideo } from "video.js";
5
+
6
+ const video = videojs as unknown as ILOVideo;
7
+
8
+ const VideoPlayer = forwardRef<VideoPlayerRef, VideoPlayerProps>(
9
+ ({ src, poster, youtube }, ref) => {
10
+ const videoNode = useRef<HTMLVideoElement>(null);
11
+ const player = useRef<videojs.Player>();
12
+
13
+ useImperativeHandle(
14
+ ref,
15
+ () => ({
16
+ get player() {
17
+ return player.current;
18
+ },
19
+ }),
20
+ [player]
21
+ );
22
+
23
+ useEffect(() => {
24
+ if (videoNode.current) {
25
+ player.current = video(videoNode.current, {
26
+ autoplay: false,
27
+ controls: true,
28
+ preload: "auto",
29
+ bigPlayButton: false,
30
+ poster: poster?.src,
31
+ controlBar: {
32
+ descriptionsButton: false,
33
+ playbackRateMenuButton: false,
34
+ chaptersButton: false,
35
+ audioTrackButton: false,
36
+ pictureInPictureToggle: false,
37
+ subsCapsButton: false,
38
+ seekToLive: false,
39
+ liveDisplay: false,
40
+ },
41
+ errorDisplay: false,
42
+ textTrackSettings: false,
43
+ resizeManager: false,
44
+ /**
45
+ * If youtube is true, it will default to the youtube video
46
+ */
47
+ sources: [
48
+ { type: youtube ? "video/youtube" : undefined, src: src as string },
49
+ ],
50
+ dataSetup: {
51
+ techOrder: ["youtube"],
52
+ },
53
+ liveTracker: false,
54
+ });
184
55
  }
185
-
186
- const duration = element.previousSibling;
187
- if (duration instanceof HTMLLabelElement) {
188
- duration.classList.toggle(
189
- `${controlsClasses}--duration--hovered`,
190
- state
191
- );
192
- }
193
- },
194
- [controlsClasses]
195
- );
196
-
197
- return (
198
- <div
199
- className={`${baseClass}--container`}
200
- ref={videoContainer as React.RefObject<HTMLDivElement>}
201
- >
202
- <ReactPlayer
203
- className={playerClasses}
204
- config={playerconfig as any}
205
- loop={false}
206
- muted={muted}
207
- playing={playing}
208
- ref={videoElement}
209
- url={src as any}
210
- width="100%"
211
- height="100%"
212
- progressInterval={30}
213
- volume={volume}
214
- onProgress={handleProgress}
215
- onDuration={handleDuration}
216
- onEnded={handleEnded}
217
- />
218
- <picture className={`${baseClass}--poster ${showposter ? "show" : ""}`}>
219
- {poster?.url &&
220
- poster.url
221
- .sort(
222
- (a: any, b: any) =>
223
- parseFloat(a.breakpoint) - parseFloat(b.breakpoint)
224
- )
225
- .slice(1)
226
- .reverse()
227
- .map((item: any, index: any) => (
228
- <source
229
- srcSet={item.src}
230
- media={`(min-width: ${item.breakpoint}px)`}
231
- key={index}
232
- />
233
- ))}
234
- <img src={poster?.url[0]?.src} alt={poster?.alt} />
235
- </picture>
236
- <div className={`${controlsClasses} ${showposter ? "notplayed" : ""}`}>
237
- <label
238
- className={`${controlsClasses}--duration ${showposter ? "show" : ""}`}
239
- >
240
- {duration}
241
- </label>
242
- <button
243
- className={`${controlsClasses}--${!playing ? "play" : "pause"}`}
244
- onClick={togglePlay}
245
- onMouseOver={(e) => handlePlayHover(e, true)}
246
- onFocus={(e) => handlePlayHover(e, true)}
247
- onMouseOut={(e) => handlePlayHover(e, false)}
248
- onBlur={(e) => handlePlayHover(e, false)}
249
- >
250
- <span>
251
- {!playing ? controls && controls.play : controls && controls.pause}
252
- </span>
253
- </button>
254
- <div
255
- className={`${controlsClasses}--progress ${showposter ? "" : "show"}`}
256
- >
257
- <input
258
- type="range"
259
- min={0}
260
- max={0.999999}
261
- step="any"
262
- value={playhead}
263
- onMouseDown={handleSeekMouseDown}
264
- onChange={handleSeekChange}
265
- onMouseUp={handleSeekMouseUp}
266
- className={`${controlsClasses}--progress-playhead`}
267
- />
268
- <progress
269
- className={`${controlsClasses}--progress-current`}
270
- max={1}
271
- value={playhead}
272
- />
273
- <progress
274
- className={`${controlsClasses}--progress-loaded`}
275
- max={1}
276
- value={buffer}
277
- />
278
- <div className={`${controlsClasses}--progress-played-container`}>
279
- <label
280
- className={`${controlsClasses}--progress-played`}
281
- style={{ ["--playhead" as any]: `${playhead * 100}%` }}
282
- >
283
- {playedtime}
284
- </label>
285
- </div>
286
- </div>
287
- <div
288
- className={`${controlsClasses}--volume ${showposter ? "" : "show"}`}
289
- onMouseEnter={showVolumeSlider}
290
- onMouseLeave={hideVolumeSlider}
291
- >
292
- <button
293
- className={`${controlsClasses}--showvolume ${muted ? "muted" : ""}`}
294
- onClick={toggleMute}
295
- >
296
- <span>{controls && controls.volume}</span>
297
- </button>
298
- <div className={`${controlsClasses}--setvolume-container`}>
299
- <input
300
- className={`${controlsClasses}--setvolume ${
301
- showvolume ? "show" : ""
302
- }`}
303
- type="range"
304
- step="0.5"
305
- defaultValue={volume}
306
- min="1"
307
- max="10"
308
- onChange={handleVolumeChange}
309
- onMouseLeave={hideVolumeSlider}
310
- />
311
- </div>
312
- </div>
313
- <button
314
- className={`${controlsClasses}--fullscreen ${
315
- showposter ? "" : "show"
316
- }`}
317
- onClick={toggleFullscreen}
318
- >
319
- <span>{controls && controls.fullscreen}</span>
320
- </button>
56
+ return () => {
57
+ if (player.current) {
58
+ player.current.dispose();
59
+ }
60
+ };
61
+ }, [poster?.src, src, youtube]);
62
+
63
+ return (
64
+ <div className="ilo--videoplayer">
65
+ <video ref={videoNode} className="ilo--video--element" />
321
66
  </div>
322
- </div>
323
- );
324
- };
67
+ );
68
+ }
69
+ );
325
70
 
326
71
  export default VideoPlayer;
@@ -43,3 +43,4 @@ export { LocalNav } from "./LocalNav";
43
43
  export { Navigation } from "./Navigation";
44
44
  export { Card, CardGroup } from "./Card";
45
45
  export { Breadcrumb } from "./Breadcrumb";
46
+ export { Tabs } from "./Tabs";
@@ -1,3 +1,5 @@
1
+ import videojs from "video.js";
2
+
1
3
  declare module "*.svg" {
2
4
  const content: string;
3
5
  export default content;
@@ -12,3 +14,23 @@ declare module "*.jpg" {
12
14
  const content: string;
13
15
  export default content;
14
16
  }
17
+
18
+ declare module "video.js" {
19
+ interface VideoJsPlayerOptionsAugmentation extends videojs.PlayerOptions {
20
+ liveTracker: boolean;
21
+ textTrackSettings: boolean;
22
+ errorDisplay: boolean;
23
+ resizeManager: boolean;
24
+ dataSetup: {
25
+ techOrder: string[];
26
+ };
27
+ }
28
+
29
+ type ILOVideo = (
30
+ id: string | HTMLVideoElement,
31
+ options: VideoJsPlayerOptionsAugmentation,
32
+ ready?: () => void
33
+ ) => videojs.Player;
34
+ }
35
+
36
+ declare module "videojs-youtube" {}