react-hover-video-player
Advanced tools
Comparing version 6.6.1 to 6.6.2
@@ -1,75 +0,7 @@ | ||
var _pausedOverlayWrapper, _videoSizingStyles; | ||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
import React from 'react'; | ||
import { formatVideoSrc, formatVideoCaptions } from './utils'; // Enumerates states that the hover player can be in | ||
var HOVER_PLAYER_STATE = { | ||
paused: 'paused', | ||
loading: 'loading', | ||
playing: 'playing' | ||
}; // Enumerates sizing modes which define how the player's contents should be sized relative to each other | ||
var SIZING_MODES = { | ||
// Everything should be sized based on the paused overlay's dimensions - the video element will expand to fill that space | ||
overlay: 'overlay', | ||
// Everything should be sized based on the video element's dimensions - the overlays will expand to cover the video | ||
video: 'video', | ||
// Everything should be sized based on the player's outer container div - the overlays and video will all expand to cover | ||
// the container | ||
container: 'container', | ||
// Manual mode does not apply any special styling and allows the developer to exercise full control | ||
// over how everything should be sized - this means you will likely need to provide your own custom styling for | ||
// both the paused overlay and the video element | ||
manual: 'manual' | ||
}; // Enumerates states that the video can be in | ||
export var VIDEO_STATE = { | ||
paused: 'paused', | ||
loading: 'loading', | ||
playing: 'playing' | ||
}; | ||
import { getVideoState, formatVideoSrc, formatVideoCaptions } from './utils'; | ||
import { VIDEO_STATE, HOVER_PLAYER_STATE, SIZING_MODES, expandToFillContainerStyle, pausedOverlayWrapperSizingStyles, videoSizingStyles } from './constants'; | ||
/** | ||
* @function getVideoState | ||
* | ||
* Takes a video element and returns its current playing state | ||
* | ||
* @param {node} videoElement | ||
*/ | ||
export function getVideoState(videoElement) { | ||
if (videoElement.paused || videoElement.ended) { | ||
return VIDEO_STATE.paused; | ||
} // If the video isn't paused but its readyState indicates it isn't loaded enough | ||
// to play yet, it is loading | ||
if (videoElement.readyState < 3) { | ||
return VIDEO_STATE.loading; | ||
} // If the video isn't paused and its ready state indicates it's loaded enough to play, | ||
// assume it's playing | ||
return VIDEO_STATE.playing; | ||
} // CSS styles to make some contents in the player expand to fill the container | ||
var expandToFillContainerStyle = { | ||
position: 'absolute', | ||
width: '100%', | ||
height: '100%', | ||
top: 0, | ||
bottom: 0, | ||
left: 0, | ||
right: 0 | ||
}; // Styles to apply to the paused overlay wrapper and video element for different sizing modes | ||
var pausedOverlayWrapperSizingStyles = (_pausedOverlayWrapper = {}, _pausedOverlayWrapper[SIZING_MODES.overlay] = { | ||
position: 'relative' | ||
}, _pausedOverlayWrapper[SIZING_MODES.video] = expandToFillContainerStyle, _pausedOverlayWrapper[SIZING_MODES.container] = expandToFillContainerStyle, _pausedOverlayWrapper[SIZING_MODES.manual] = null, _pausedOverlayWrapper); | ||
var videoSizingStyles = (_videoSizingStyles = {}, _videoSizingStyles[SIZING_MODES.overlay] = expandToFillContainerStyle, _videoSizingStyles[SIZING_MODES.video] = { | ||
display: 'block', | ||
width: '100%' | ||
}, _videoSizingStyles[SIZING_MODES.container] = expandToFillContainerStyle, _videoSizingStyles[SIZING_MODES.manual] = null, _videoSizingStyles); | ||
/** | ||
* @component HoverVideoPlayer | ||
@@ -83,4 +15,3 @@ * | ||
* - **Array**: if you would like to provide multiple sources, you can provide an array of URL strings and/or objects with the shape described above | ||
* @param {!(string|string[]|VideoCaptionsTrack|VideoCaptionsTrack[])} [videoCaptions] - Captions track(s) to use for the video player for accessibility. Accepts 3 different formats: | ||
* - **String**: the URL string to use as the captions track's src | ||
* @param {!(VideoCaptionsTrack|VideoCaptionsTrack[])} [videoCaptions] - Captions track(s) to use for the video player for accessibility. Accepts 2 formats: | ||
* - **Object**: an object with attributes: | ||
@@ -470,2 +401,3 @@ * - src: The src URL string for the captions track file | ||
return /*#__PURE__*/React.createElement("div", { | ||
"data-testid": "hover-video-player-container", | ||
ref: containerRef, | ||
@@ -482,3 +414,4 @@ className: className, | ||
}, pausedOverlayWrapperStyle), | ||
className: pausedOverlayWrapperClassName | ||
className: pausedOverlayWrapperClassName, | ||
"data-testid": "paused-overlay-wrapper" | ||
}, pausedOverlay), loadingOverlay && /*#__PURE__*/React.createElement("div", { | ||
@@ -490,3 +423,4 @@ style: _extends({}, expandToFillContainerStyle, { | ||
}, loadingOverlayWrapperStyle), | ||
className: loadingOverlayWrapperClassName | ||
className: loadingOverlayWrapperClassName, | ||
"data-testid": "loading-overlay-wrapper" | ||
}, loadingOverlay), /*#__PURE__*/React.createElement("video", { | ||
@@ -500,3 +434,4 @@ loop: loop, | ||
}, videoStyle), | ||
className: videoClassName | ||
className: videoClassName, | ||
"data-testid": "video-element" | ||
}, !isVideoUnloaded && // If the video is not unloaded, parse the `videoSrc` prop into an array of objects and render them | ||
@@ -503,0 +438,0 @@ // as sources for the video |
@@ -0,2 +1,26 @@ | ||
import { VIDEO_STATE } from './constants'; | ||
/** | ||
* @function getVideoState | ||
* | ||
* Takes a video element and returns its current playing state | ||
* | ||
* @param {node} videoElement | ||
*/ | ||
export function getVideoState(videoElement) { | ||
if (videoElement.paused || videoElement.ended) { | ||
return VIDEO_STATE.paused; | ||
} // If the video isn't paused but its readyState indicates it isn't loaded enough | ||
// to play yet, it is loading | ||
if (videoElement.readyState < 3) { | ||
return VIDEO_STATE.loading; | ||
} // If the video isn't paused and its ready state indicates it's loaded enough to play, | ||
// assume it's playing | ||
return VIDEO_STATE.playing; | ||
} | ||
/** | ||
* @typedef {object} VideoSource | ||
@@ -22,2 +46,3 @@ * @property {string} src - The src URL string to use for a video player source | ||
*/ | ||
export function formatVideoSrc(videoSrc) { | ||
@@ -24,0 +49,0 @@ var formattedVideoSources = []; |
118
lib/index.js
"use strict"; | ||
exports.__esModule = true; | ||
exports.getVideoState = getVideoState; | ||
exports["default"] = HoverVideoPlayer; | ||
exports.VIDEO_STATE = void 0; | ||
@@ -12,3 +10,3 @@ var _react = _interopRequireDefault(require("react")); | ||
var _pausedOverlayWrapper, _videoSizingStyles; | ||
var _constants = require("./constants"); | ||
@@ -19,73 +17,3 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
// Enumerates states that the hover player can be in | ||
var HOVER_PLAYER_STATE = { | ||
paused: 'paused', | ||
loading: 'loading', | ||
playing: 'playing' | ||
}; // Enumerates sizing modes which define how the player's contents should be sized relative to each other | ||
var SIZING_MODES = { | ||
// Everything should be sized based on the paused overlay's dimensions - the video element will expand to fill that space | ||
overlay: 'overlay', | ||
// Everything should be sized based on the video element's dimensions - the overlays will expand to cover the video | ||
video: 'video', | ||
// Everything should be sized based on the player's outer container div - the overlays and video will all expand to cover | ||
// the container | ||
container: 'container', | ||
// Manual mode does not apply any special styling and allows the developer to exercise full control | ||
// over how everything should be sized - this means you will likely need to provide your own custom styling for | ||
// both the paused overlay and the video element | ||
manual: 'manual' | ||
}; // Enumerates states that the video can be in | ||
var VIDEO_STATE = { | ||
paused: 'paused', | ||
loading: 'loading', | ||
playing: 'playing' | ||
}; | ||
/** | ||
* @function getVideoState | ||
* | ||
* Takes a video element and returns its current playing state | ||
* | ||
* @param {node} videoElement | ||
*/ | ||
exports.VIDEO_STATE = VIDEO_STATE; | ||
function getVideoState(videoElement) { | ||
if (videoElement.paused || videoElement.ended) { | ||
return VIDEO_STATE.paused; | ||
} // If the video isn't paused but its readyState indicates it isn't loaded enough | ||
// to play yet, it is loading | ||
if (videoElement.readyState < 3) { | ||
return VIDEO_STATE.loading; | ||
} // If the video isn't paused and its ready state indicates it's loaded enough to play, | ||
// assume it's playing | ||
return VIDEO_STATE.playing; | ||
} // CSS styles to make some contents in the player expand to fill the container | ||
var expandToFillContainerStyle = { | ||
position: 'absolute', | ||
width: '100%', | ||
height: '100%', | ||
top: 0, | ||
bottom: 0, | ||
left: 0, | ||
right: 0 | ||
}; // Styles to apply to the paused overlay wrapper and video element for different sizing modes | ||
var pausedOverlayWrapperSizingStyles = (_pausedOverlayWrapper = {}, _pausedOverlayWrapper[SIZING_MODES.overlay] = { | ||
position: 'relative' | ||
}, _pausedOverlayWrapper[SIZING_MODES.video] = expandToFillContainerStyle, _pausedOverlayWrapper[SIZING_MODES.container] = expandToFillContainerStyle, _pausedOverlayWrapper[SIZING_MODES.manual] = null, _pausedOverlayWrapper); | ||
var videoSizingStyles = (_videoSizingStyles = {}, _videoSizingStyles[SIZING_MODES.overlay] = expandToFillContainerStyle, _videoSizingStyles[SIZING_MODES.video] = { | ||
display: 'block', | ||
width: '100%' | ||
}, _videoSizingStyles[SIZING_MODES.container] = expandToFillContainerStyle, _videoSizingStyles[SIZING_MODES.manual] = null, _videoSizingStyles); | ||
/** | ||
* @component HoverVideoPlayer | ||
@@ -99,4 +27,3 @@ * | ||
* - **Array**: if you would like to provide multiple sources, you can provide an array of URL strings and/or objects with the shape described above | ||
* @param {!(string|string[]|VideoCaptionsTrack|VideoCaptionsTrack[])} [videoCaptions] - Captions track(s) to use for the video player for accessibility. Accepts 3 different formats: | ||
* - **String**: the URL string to use as the captions track's src | ||
* @param {!(VideoCaptionsTrack|VideoCaptionsTrack[])} [videoCaptions] - Captions track(s) to use for the video player for accessibility. Accepts 2 formats: | ||
* - **Object**: an object with attributes: | ||
@@ -144,3 +71,2 @@ * - src: The src URL string for the captions track file | ||
*/ | ||
function HoverVideoPlayer(_ref) { | ||
@@ -191,6 +117,6 @@ var videoSrc = _ref.videoSrc, | ||
_ref$sizingMode = _ref.sizingMode, | ||
sizingMode = _ref$sizingMode === void 0 ? SIZING_MODES.video : _ref$sizingMode; | ||
sizingMode = _ref$sizingMode === void 0 ? _constants.SIZING_MODES.video : _ref$sizingMode; | ||
// Keep track of state to determine how the paused and loading overlays should be displayed | ||
var _React$useState = _react["default"].useState(HOVER_PLAYER_STATE.paused), | ||
var _React$useState = _react["default"].useState(_constants.HOVER_PLAYER_STATE.paused), | ||
overlayState = _React$useState[0], | ||
@@ -275,4 +201,4 @@ setOverlayState = _React$useState[1]; // Keep track of whether the video is unloaded, meaning its sources should be removed from | ||
if (getVideoState(videoElement) === VIDEO_STATE.playing) { | ||
setOverlayState(HOVER_PLAYER_STATE.playing); | ||
if ((0, _utils.getVideoState)(videoElement) === _constants.VIDEO_STATE.playing) { | ||
setOverlayState(_constants.HOVER_PLAYER_STATE.playing); | ||
return; | ||
@@ -287,3 +213,3 @@ } | ||
// player to show a loading state | ||
setOverlayState(HOVER_PLAYER_STATE.loading); | ||
setOverlayState(_constants.HOVER_PLAYER_STATE.loading); | ||
}, loadingStateTimeout); | ||
@@ -341,3 +267,3 @@ } // If a play attempt is already in progress, don't start a new one | ||
// If the play attempt wasn't cancelled, hide the overlays to reveal the video now that it's playing | ||
setOverlayState(HOVER_PLAYER_STATE.playing); | ||
setOverlayState(_constants.HOVER_PLAYER_STATE.playing); | ||
} | ||
@@ -385,5 +311,5 @@ })["catch"](function (error) { | ||
if (focused || getVideoState(videoElement) === VIDEO_STATE.paused) return; // Start fading the paused overlay back in | ||
if (focused || (0, _utils.getVideoState)(videoElement) === _constants.VIDEO_STATE.paused) return; // Start fading the paused overlay back in | ||
setOverlayState(HOVER_PLAYER_STATE.paused); | ||
setOverlayState(_constants.HOVER_PLAYER_STATE.paused); | ||
@@ -505,2 +431,3 @@ if (mutableVideoState.current.isPlayAttemptInProgress) { | ||
return /*#__PURE__*/_react["default"].createElement("div", { | ||
"data-testid": "hover-video-player-container", | ||
ref: containerRef, | ||
@@ -512,15 +439,17 @@ className: className, | ||
}, pausedOverlay && /*#__PURE__*/_react["default"].createElement("div", { | ||
style: _extends({}, pausedOverlayWrapperSizingStyles[sizingMode], { | ||
style: _extends({}, _constants.pausedOverlayWrapperSizingStyles[sizingMode], { | ||
zIndex: 1, | ||
opacity: overlayState !== HOVER_PLAYER_STATE.playing ? 1 : 0, | ||
opacity: overlayState !== _constants.HOVER_PLAYER_STATE.playing ? 1 : 0, | ||
transition: "opacity " + overlayTransitionDuration + "ms" | ||
}, pausedOverlayWrapperStyle), | ||
className: pausedOverlayWrapperClassName | ||
className: pausedOverlayWrapperClassName, | ||
"data-testid": "paused-overlay-wrapper" | ||
}, pausedOverlay), loadingOverlay && /*#__PURE__*/_react["default"].createElement("div", { | ||
style: _extends({}, expandToFillContainerStyle, { | ||
style: _extends({}, _constants.expandToFillContainerStyle, { | ||
zIndex: 2, | ||
opacity: overlayState === HOVER_PLAYER_STATE.loading ? 1 : 0, | ||
opacity: overlayState === _constants.HOVER_PLAYER_STATE.loading ? 1 : 0, | ||
transition: "opacity " + overlayTransitionDuration + "ms" | ||
}, loadingOverlayWrapperStyle), | ||
className: loadingOverlayWrapperClassName | ||
className: loadingOverlayWrapperClassName, | ||
"data-testid": "loading-overlay-wrapper" | ||
}, loadingOverlay), /*#__PURE__*/_react["default"].createElement("video", { | ||
@@ -531,6 +460,7 @@ loop: loop, | ||
ref: videoRef, | ||
style: _extends({}, videoSizingStyles[sizingMode], { | ||
style: _extends({}, _constants.videoSizingStyles[sizingMode], { | ||
objectFit: 'cover' | ||
}, videoStyle), | ||
className: videoClassName | ||
className: videoClassName, | ||
"data-testid": "video-element" | ||
}, !isVideoUnloaded && // If the video is not unloaded, parse the `videoSrc` prop into an array of objects and render them | ||
@@ -560,2 +490,4 @@ // as sources for the video | ||
}))); | ||
} | ||
} | ||
module.exports = exports.default; |
"use strict"; | ||
exports.__esModule = true; | ||
exports.getVideoState = getVideoState; | ||
exports.formatVideoSrc = formatVideoSrc; | ||
exports.formatVideoCaptions = formatVideoCaptions; | ||
var _constants = require("./constants"); | ||
/** | ||
* @function getVideoState | ||
* | ||
* Takes a video element and returns its current playing state | ||
* | ||
* @param {node} videoElement | ||
*/ | ||
function getVideoState(videoElement) { | ||
if (videoElement.paused || videoElement.ended) { | ||
return _constants.VIDEO_STATE.paused; | ||
} // If the video isn't paused but its readyState indicates it isn't loaded enough | ||
// to play yet, it is loading | ||
if (videoElement.readyState < 3) { | ||
return _constants.VIDEO_STATE.loading; | ||
} // If the video isn't paused and its ready state indicates it's loaded enough to play, | ||
// assume it's playing | ||
return _constants.VIDEO_STATE.playing; | ||
} | ||
/** | ||
* @typedef {object} VideoSource | ||
@@ -28,2 +53,4 @@ * @property {string} src - The src URL string to use for a video player source | ||
*/ | ||
function formatVideoSrc(videoSrc) { | ||
@@ -30,0 +57,0 @@ var formattedVideoSources = []; |
{ | ||
"name": "react-hover-video-player", | ||
"version": "6.6.1", | ||
"version": "6.6.2", | ||
"description": "React component which manages playing a video when the user hovers over it and pausing when they stop.", | ||
@@ -15,3 +15,4 @@ "main": "es/index.js", | ||
"start:demo": "nwb serve-react-demo", | ||
"test": "jest --config=tests/jest.config.js", | ||
"test": "jest --config=tests/jest.dev.config.js", | ||
"test:release": "npm run build -- --no-demo && jest --config=tests/jest.prod.config.js", | ||
"test:watch": "npm run test -- --watch --no-cache", | ||
@@ -29,4 +30,6 @@ "commit": "npx git-cz" | ||
"@commitlint/config-conventional": "^8.3.4", | ||
"@semantic-release/changelog": "^5.0.1", | ||
"@semantic-release/git": "^9.0.0", | ||
"@semantic-release/commit-analyzer": "^8.0.1", | ||
"@semantic-release/github": "^7.0.7", | ||
"@semantic-release/npm": "^7.0.5", | ||
"@semantic-release/release-notes-generator": "^9.0.1", | ||
"@testing-library/jest-dom": "^5.3.0", | ||
@@ -36,3 +39,2 @@ "@testing-library/react": "^10.0.2", | ||
"babel-jest": "^25.2.6", | ||
"babel-plugin-jsx-remove-data-test-id": "^2.1.3", | ||
"commitizen": "^4.1.2", | ||
@@ -125,15 +127,5 @@ "core-js": "^3.6.5", | ||
"@semantic-release/npm", | ||
[ | ||
"@semantic-release/git", | ||
{ | ||
"assets": [ | ||
"package.json", | ||
"package-lock.json", | ||
"CHANGELOG.md" | ||
], | ||
"message": "chore(release): ${nextRelease.version} [skip ci]nn${nextRelease.notes}" | ||
} | ||
] | ||
"@semantic-release/github" | ||
] | ||
} | ||
} |
@@ -10,4 +10,35 @@ # React Hover Video Player | ||
## What it is | ||
## Table of Contents | ||
1. **[What It Is](#what-it-is)** | ||
1. **[Features](#features)** | ||
1. **[How It Works](#how-it-works)** | ||
1. **[Get Started](#get-started)** | ||
- [Installation](#installation) | ||
- [Basic Usage](#basic-usage) | ||
1. **[Sources](#sources)** | ||
- [videoSrc](#videosrc) | ||
- [videoCaptions](#videocaptions) | ||
1. **[Overlays](#overlays)** | ||
- [pausedOverlay](#pausedoverlay) | ||
- [loadingOverlay](#loadingoverlay) | ||
- [overlayTransitionDuration](#overlaytransitionduration) | ||
- [loadingStateTimeout](#loadingstatetimeout) | ||
1. **[Custom Event Handling](#custom-event-handling)** | ||
- [hoverTargetRef](#hovertargetref) | ||
- [focused](#focused) | ||
- [disableDefaultEventHandling](#disabledefaulteventhandling) | ||
1. **[Video Behavior](#video-behavior)** | ||
- [restartOnPaused](#restartonpaused) | ||
- [muted](#muted) | ||
- [loop](#loop) | ||
1. **[Custom Styling](#custom-styling)** | ||
- [Applying classNames and styles](#applying-classnames-and-styles) | ||
- [sizingMode](#sizingmode) | ||
1. **[Optimization](#optimization)** | ||
- [preload](#preload) | ||
- [unloadVideoOnPaused](#unloadvideoonpaused) | ||
## What It Is | ||
A React component that makes it super easy to set up a video that will play when the user hovers over it. This is particularly useful for setting up a thumbnail that will play a video preview on hover. | ||
@@ -17,7 +48,7 @@ | ||
- Support for both mouse and touchscreen interactions | ||
- Out-of-the-box support for both mouse and touchscreen interactions | ||
- Easily add custom thumbnails and loading states | ||
- Lightning fast | ||
- Clean, error-free handling of async video playback | ||
- Lightweight and fast | ||
- No dependencies | ||
- Easy to customize | ||
@@ -62,3 +93,3 @@ ## How It Works | ||
**Type**: `string` or `array` of objects | **This prop is required** | ||
**Type**: `string` or `array` of strings and/or objects | **This prop is required** | ||
@@ -75,3 +106,3 @@ `videoSrc` accepts one or multiple values descibing the video source file(s) that should be used for the video player. | ||
If you have **multiple video sources**, you can provide all of them in an array of objects with the shape: | ||
If you have **multiple video sources**, you can provide all of them in an array of strings or objects with the shape: | ||
@@ -78,0 +109,0 @@ ```javascript |
93155
9
1125
488
37