UNPKG

react-award

Version:

React component for rewarding users

260 lines (248 loc) 8.98 kB
var lottie = require('lottie-web'); var React = require('react'); var reactTransitionState = require('react-transition-state'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var lottie__default = /*#__PURE__*/_interopDefaultLegacy(lottie); var React__default = /*#__PURE__*/_interopDefaultLegacy(React); function _extends() { _extends = Object.assign ? Object.assign.bind() : 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); } /** * Mask component */ var Mask = function Mask(props) { var backgroundColor = props.backgroundColor, className = props.className, children = props.children, _props$style = props.style, style = _props$style === void 0 ? {} : _props$style; if (!props.image) { return null; } return React__default["default"].createElement("div", { className: className, style: _extends({ WebkitMaskImage: "url(" + props.image + ")", maskImage: "url(" + props.image + ")", backgroundColor: backgroundColor }, style) }, children); }; /** * Image component */ var Image = function Image(props) { if (!props.image) { return null; } return React__default["default"].createElement("img", { src: props.image, style: _extends({ transitionDuration: props.duration + "ms" }, props.style || {}), className: props.className }); }; /** * A wrapper for the Lottie player that simplifies the event that is triggered when loading, * and allows you to play or stop the animation in a declarative way. */ var Player = function Player(props) { var animation = props.animation, play = props.play, segments = props.segments, className = props.className, style = props.style, speed = props.speed; var animationRef = React.useRef(null); var containerRef = React.useRef(null); // animation loader React.useEffect(function () { animationRef.current = props.lottie.loadAnimation({ autoplay: false, loop: false, animationData: props.animation, renderer: 'svg', container: containerRef.current }); return function () { var _animationRef$current; (_animationRef$current = animationRef.current) == null ? void 0 : _animationRef$current.destroy(); animationRef.current = null; }; }, [animation]); // event handlers React.useEffect(function () { if (!animationRef.current) { return; } var onLoad = function onLoad() { var _animationRef$current2, _animationRef$current3, _props$onLoad; (_animationRef$current2 = animationRef.current) == null ? void 0 : _animationRef$current2.hide(); (_animationRef$current3 = animationRef.current) == null ? void 0 : _animationRef$current3.stop(); (_props$onLoad = props.onLoad) == null ? void 0 : _props$onLoad.call(null); }; var onComplete = function onComplete() { var _animationRef$current4, _animationRef$current5, _props$onComplete; (_animationRef$current4 = animationRef.current) == null ? void 0 : _animationRef$current4.hide(); (_animationRef$current5 = animationRef.current) == null ? void 0 : _animationRef$current5.stop(); (_props$onComplete = props.onComplete) == null ? void 0 : _props$onComplete.call(null); }; animationRef.current.addEventListener('DOMLoaded', onLoad); animationRef.current.addEventListener('complete', onComplete); return function () { var _animationRef$current6, _animationRef$current7; (_animationRef$current6 = animationRef.current) == null ? void 0 : _animationRef$current6.removeEventListener('DOMLoaded', onLoad); (_animationRef$current7 = animationRef.current) == null ? void 0 : _animationRef$current7.removeEventListener('complete', onComplete); }; }, [props.onLoad, props.onComplete]); React.useEffect(function () { if (play) { var _animationRef$current8, _animationRef$current9; (_animationRef$current8 = animationRef.current) == null ? void 0 : _animationRef$current8.show(); (_animationRef$current9 = animationRef.current) == null ? void 0 : _animationRef$current9.setSpeed(speed || 1); if (Array.isArray(segments)) { var _animationRef$current10; (_animationRef$current10 = animationRef.current) == null ? void 0 : _animationRef$current10.playSegments(segments, true); } else { var _animationRef$current11; (_animationRef$current11 = animationRef.current) == null ? void 0 : _animationRef$current11.play(); } } }, [play, segments, speed]); return React__default["default"].createElement("div", { style: style, className: className, ref: containerRef }); }; /** * Inject award properties to custom child */ var withAwardProperties = function withAwardProperties(WrappedComponent) { return function (props) { if (!React__default["default"].isValidElement(WrappedComponent)) { return null; } return React__default["default"].cloneElement(WrappedComponent, { className: "" + props.className, style: { transitionDuration: props.duration + "ms" } }); }; }; /** * The "useHover" hook allows you to detect if the mouse is hovering over a specific element in a React component. * It returns a reference to the element and a boolean value indicating whether the mouse is hovering over it or not. */ function useHover() { var _useState = React.useState(false), hovered = _useState[0], setHovered = _useState[1]; var ref = React.useRef(null); function handleMouseOver() { setHovered(true); } function handleMouseOut() { //setWasHovered(false); } React.useEffect(function () { var current = ref.current; if (current) { current.addEventListener('mouseover', handleMouseOver); current.addEventListener('mouseout', handleMouseOut); } return function () { if (current) { current.removeEventListener('mouseover', handleMouseOver); current.removeEventListener('mouseout', handleMouseOut); } }; }, [ref]); return [ref, hovered]; } /** Allows to inject the lottie player dependency */ var buildAward = function buildAward(lottie) { /** Award component */ var Award = function Award(props) { var _useHover = useHover(), ref = _useHover[0], hovered = _useHover[1]; var _useState = React.useState(false), loaded = _useState[0], setLoaded = _useState[1]; var _useTransition = reactTransitionState.useTransition({ timeout: props.duration, preEnter: true }), transition = _useTransition[0], showImage = _useTransition[1]; // current status var showPlaceholder = props.showPlaceholder && !loaded; var play = loaded ? props.playOnHover && hovered || !!props.play : false; React.useEffect(function () { showImage(play); }, [play]); var CustomChild = React.useMemo(function () { return withAwardProperties(props.children); }, [props.children]); return React__default["default"].createElement("div", { ref: ref, className: "award-container", style: props.style }, React__default["default"].createElement(Mask, { image: props.image, style: props.maskStyle, backgroundColor: props.backgroundColor, className: "award-mask " + (showPlaceholder && 'placeholder') }, React__default["default"].createElement(Image, { image: props.image, style: props.imageStyle, duration: props.duration, className: "award-image " + transition.status })), React__default["default"].createElement(CustomChild, { duration: props.duration, className: "award-image " + transition.status }), React__default["default"].createElement(Player, { lottie: lottie, play: play, speed: props.speed, segments: props.segments, style: props.playerStyle, animation: props.animation, onLoad: function onLoad() { return setLoaded(true); }, onComplete: props.onComplete, className: "award-player " + transition.status })); }; Award.defaultProps = { duration: 2000, backgroundColor: '#CCCCCC', showPlaceholder: false }; return Award; }; /** * This React component displays a solid color mask with the silhouette of an image, * and when triggered, it performs a fade-in effect to reveal the image. * * The component also plays a confetti animation. * The user can specify different images or animation files for the component to display. */ var Award = buildAward(lottie__default["default"]); exports.Award = Award; //# sourceMappingURL=react-award.js.map