yet-another-react-lightbox 1.4.1 → 1.5.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.
@@ -1,5 +1,5 @@
1
- /// <reference types="react" />
2
- import { Plugin } from "../types.js";
1
+ import * as React from "react";
2
+ import { LightboxProps, Plugin } from "../types.js";
3
3
  /** Video slide attributes */
4
4
  export interface SlideVideo {
5
5
  /** video slide type marker */
@@ -10,6 +10,26 @@ export interface SlideVideo {
10
10
  width?: number;
11
11
  /** video height in pixels */
12
12
  height?: number;
13
+ /** if `true`, the video automatically begins to play */
14
+ autoPlay?: boolean;
15
+ /** if `true`, the browser will offer controls to allow the user to control video playback */
16
+ controls?: boolean;
17
+ /** indicates what controls to show */
18
+ controlsList?: string;
19
+ /** indicates whether to use CORS to fetch the related video */
20
+ crossOrigin?: string;
21
+ /** video preload setting */
22
+ preload?: string;
23
+ /** if `true`, the browser will automatically seek back to the start upon reaching the end of the video */
24
+ loop?: boolean;
25
+ /** the default setting of the audio contained in the video */
26
+ muted?: boolean;
27
+ /** if `true`, the video is to be played "inline", that is within the element's playback area. */
28
+ playsInline?: boolean;
29
+ /** prevents the browser from suggesting a Picture-in-Picture context menu */
30
+ disablePictureInPicture?: boolean;
31
+ /** disables the capability of remote playback */
32
+ disableRemotePlayback?: boolean;
13
33
  /** an array of video files */
14
34
  sources?: {
15
35
  /** video source URL */
@@ -23,11 +43,17 @@ declare module "../types.js" {
23
43
  /** video slide type */
24
44
  SlideVideo: SlideVideo;
25
45
  }
46
+ interface LightboxProps {
47
+ /** video plugin settings */
48
+ video?: Pick<SlideVideo, "autoPlay" | "controls" | "controlsList" | "crossOrigin" | "preload" | "loop" | "muted" | "playsInline" | "disablePictureInPicture" | "disableRemotePlayback">;
49
+ }
26
50
  }
27
- /** Video slide */
28
- export declare const VideoSlide: ({ slide: { sources, poster, width, height } }: {
51
+ declare type VideoSlideProps = Required<Pick<LightboxProps, "video">> & {
29
52
  slide: SlideVideo;
30
- }) => JSX.Element;
53
+ offset: number;
54
+ };
55
+ /** Video slide */
56
+ export declare const VideoSlide: React.FC<VideoSlideProps>;
31
57
  /** Video plugin */
32
58
  export declare const Video: Plugin;
33
59
  export default Video;
@@ -1,19 +1,53 @@
1
1
  import * as React from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import { SlideTypesPropTypes } from "../types.js";
4
- import { clsx, cssClass, useContainerRect } from "../core/index.js";
4
+ import { clsx, cssClass, useContainerRect, useLatest } from "../core/index.js";
5
5
  SlideTypesPropTypes.push(PropTypes.shape({
6
6
  type: PropTypes.oneOf(["video"]).isRequired,
7
7
  poster: PropTypes.string,
8
8
  width: PropTypes.number,
9
9
  height: PropTypes.number,
10
+ autoPlay: PropTypes.bool,
11
+ controls: PropTypes.bool,
12
+ controlsList: PropTypes.string,
13
+ crossOrigin: PropTypes.string,
14
+ preload: PropTypes.string,
15
+ loop: PropTypes.bool,
16
+ muted: PropTypes.bool,
17
+ playsInline: PropTypes.bool,
18
+ disablePictureInPicture: PropTypes.bool,
19
+ disableRemotePlayback: PropTypes.bool,
10
20
  sources: PropTypes.arrayOf(PropTypes.shape({
11
21
  src: PropTypes.string.isRequired,
12
22
  type: PropTypes.string.isRequired,
13
23
  }).isRequired),
14
24
  }));
15
- export const VideoSlide = ({ slide: { sources, poster, width, height } }) => {
25
+ export const VideoSlide = ({ slide, video, offset }) => {
16
26
  const { setContainerRef, containerRect } = useContainerRect();
27
+ const videoRef = React.useRef(null);
28
+ React.useEffect(() => {
29
+ if (offset !== 0 && videoRef.current && !videoRef.current.paused) {
30
+ videoRef.current.pause();
31
+ }
32
+ }, [offset]);
33
+ React.useEffect(() => {
34
+ if (offset === 0 && videoRef.current && (slide.autoPlay || video.autoPlay)) {
35
+ videoRef.current.play().catch(() => { });
36
+ }
37
+ }, [offset, video.autoPlay, slide.autoPlay]);
38
+ const latestOffset = useLatest(offset);
39
+ const latestVideoAutoPlay = useLatest(video.autoPlay);
40
+ const latestSlideAutoPlay = useLatest(slide.autoPlay);
41
+ const setVideoRef = React.useCallback((el) => {
42
+ videoRef.current = el;
43
+ if (el &&
44
+ latestOffset.current === 0 &&
45
+ (latestVideoAutoPlay.current || latestSlideAutoPlay.current) &&
46
+ el.paused) {
47
+ el.play().catch(() => { });
48
+ }
49
+ }, [latestOffset, latestVideoAutoPlay, latestSlideAutoPlay]);
50
+ const { width, height, poster, sources } = slide;
17
51
  const scaleWidthAndHeight = () => {
18
52
  if (!width || !height || !containerRect)
19
53
  return null;
@@ -23,24 +57,49 @@ export const VideoSlide = ({ slide: { sources, poster, width, height } }) => {
23
57
  height: !widthBound ? containerRect.height : Math.round((containerRect.width / width) * height),
24
58
  };
25
59
  };
60
+ const resolveBoolean = (attr) => {
61
+ if (slide[attr] === false)
62
+ return null;
63
+ if (slide[attr] === true)
64
+ return { [attr]: true };
65
+ if (video[attr] === false)
66
+ return null;
67
+ if (video[attr] === true)
68
+ return { [attr]: true };
69
+ return null;
70
+ };
71
+ const resolveString = (attr) => {
72
+ if (video[attr] || slide[attr]) {
73
+ return { [attr]: slide[attr] || video[attr] };
74
+ }
75
+ return null;
76
+ };
26
77
  return (React.createElement(React.Fragment, null, sources && (React.createElement("div", { ref: setContainerRef, style: {
27
78
  width: "100%",
28
79
  height: "100%",
29
80
  ...(width ? { maxWidth: `${width}px` } : null),
30
- }, className: clsx(cssClass("video_container"), cssClass("flex_center")) }, containerRect && (React.createElement("video", { controls: true, playsInline: true, poster: poster, ...scaleWidthAndHeight() }, sources.map(({ src, type }, index) => (React.createElement("source", { key: index, src: src, type: type })))))))));
81
+ }, className: clsx(cssClass("video_container"), cssClass("flex_center")) }, containerRect && (React.createElement("video", { ref: setVideoRef, poster: poster, ...scaleWidthAndHeight(), ...resolveBoolean("controls"), ...resolveBoolean("playsInline"), ...resolveBoolean("loop"), ...resolveBoolean("muted"), ...resolveBoolean("playsInline"), ...resolveBoolean("disablePictureInPicture"), ...resolveBoolean("disableRemotePlayback"), ...resolveString("controlsList"), ...resolveString("crossOrigin"), ...resolveString("preload") }, sources.map(({ src, type }, index) => (React.createElement("source", { key: index, src: src, type: type })))))))));
31
82
  };
32
83
  export const Video = ({ augment }) => {
33
- augment(({ render: { slide: renderSlide, ...restRender }, ...restProps }) => ({
34
- render: {
35
- slide: (slide, offset, rect) => {
36
- if ("type" in slide && slide.type === "video") {
37
- return React.createElement(VideoSlide, { slide: slide });
38
- }
39
- return renderSlide === null || renderSlide === void 0 ? void 0 : renderSlide(slide, offset, rect);
84
+ augment(({ render: { slide: renderSlide, ...restRender }, video: originalVideo, ...restProps }) => {
85
+ const video = {
86
+ controls: true,
87
+ playsInline: true,
88
+ ...originalVideo,
89
+ };
90
+ return {
91
+ render: {
92
+ slide: (slide, offset, rect) => {
93
+ if ("type" in slide && slide.type === "video") {
94
+ return React.createElement(VideoSlide, { slide: slide, video: video, offset: offset });
95
+ }
96
+ return renderSlide === null || renderSlide === void 0 ? void 0 : renderSlide(slide, offset, rect);
97
+ },
98
+ ...restRender,
40
99
  },
41
- ...restRender,
42
- },
43
- ...restProps,
44
- }));
100
+ video,
101
+ ...restProps,
102
+ };
103
+ });
45
104
  };
46
105
  export default Video;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yet-another-react-lightbox",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Modern React lightbox component",
5
5
  "author": "Igor Danchenko",
6
6
  "license": "MIT",