react-compare-slider
Advanced tools
Comparing version 1.0.0 to 1.0.1-rc.1
import React from 'react'; | ||
/** | ||
* Whether client supports the CSS `object-fit` property | ||
* Whether client supports the CSS `object-fit` property. | ||
*/ | ||
export declare const CLIENT_SUPPORTS_CSS_OBJECT_FIT: boolean; | ||
/** | ||
* Properties for `ReactCompareSliderImage` | ||
* Properties for `ReactCompareSliderImage`. | ||
*/ | ||
@@ -15,4 +15,4 @@ export interface ReactCompareSliderImageProps { | ||
* Image with fallback background for browsers that don't support the | ||
* `object-fit` CSS property | ||
* `object-fit` CSS property. | ||
*/ | ||
export declare const ReactCompareSliderImage: React.FC<React.ImgHTMLAttributes<HTMLImageElement> & ReactCompareSliderImageProps>; |
@@ -7,3 +7,2 @@ 'use strict'; | ||
var tslib = require('tslib'); | ||
var React = require('react'); | ||
@@ -13,16 +12,49 @@ var React__default = _interopDefault(React); | ||
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); | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
if (source == null) return {}; | ||
var target = {}; | ||
var sourceKeys = Object.keys(source); | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
key = sourceKeys[i]; | ||
if (excluded.indexOf(key) >= 0) continue; | ||
target[key] = source[key]; | ||
} | ||
return target; | ||
} | ||
/** | ||
* CSS style util for child to fit container | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) | ||
* fit their container and maintain their aspect ratio. | ||
*/ | ||
var styleFitContainer = function styleFitContainer(_a) { | ||
if (_a === void 0) { | ||
_a = {}; | ||
} | ||
var styleFitContainer = function styleFitContainer(_temp) { | ||
var _ref = _temp === void 0 ? {} : _temp, | ||
_ref$objectFit = _ref.objectFit, | ||
objectFit = _ref$objectFit === void 0 ? 'cover' : _ref$objectFit, | ||
_ref$objectPosition = _ref.objectPosition, | ||
objectPosition = _ref$objectPosition === void 0 ? 'center' : _ref$objectPosition, | ||
props = _objectWithoutPropertiesLoose(_ref, ["objectFit", "objectPosition"]); | ||
var _b = _a.objectFit, | ||
objectFit = _b === void 0 ? 'cover' : _b, | ||
props = tslib.__rest(_a, ["objectFit"]); | ||
return tslib.__assign({ | ||
return _extends({ | ||
display: 'block', | ||
@@ -32,7 +64,31 @@ width: '100%', | ||
maxWidth: '100%', | ||
objectFit: objectFit | ||
objectFit: objectFit, | ||
objectPosition: objectPosition | ||
}, props); | ||
}; | ||
/** Perform strict primitive equals. */ | ||
var strictEquals = function strictEquals(prev, next) { | ||
return prev === next; | ||
}; | ||
/** | ||
* Event listener binding hook | ||
* Use previous value. | ||
* @see https://github.com/streamich/react-use/blob/master/src/usePreviousDistinct.ts | ||
*/ | ||
var usePrevious = function usePrevious(value) { | ||
var previousRef = React.useRef(); | ||
var currentRef = React.useRef(); | ||
if (!strictEquals(currentRef.current, value)) { | ||
previousRef.current = currentRef.current; | ||
currentRef.current = value; | ||
} // Return previous value (happens before update in useEffect above) | ||
return previousRef.current; | ||
}; | ||
/** | ||
* Event listener binding hook. | ||
* @param eventName - Event to bind to | ||
@@ -47,5 +103,5 @@ * @param handler - Callback handler | ||
element = window; | ||
} // Create a ref that stores handler | ||
} | ||
// Create a ref that stores handler | ||
var savedHandler = React.useRef(); // Update ref.current value if handler changes. | ||
@@ -78,3 +134,3 @@ // This allows our effect below to always get latest handler ... | ||
/** | ||
* Bind resize observer to ref | ||
* Bind resize observer to ref. | ||
* @param ref - Ref to bind to | ||
@@ -86,4 +142,4 @@ * @param handler - Callback for handling entry's bounding rect | ||
var useResizeObserver = function useResizeObserver(ref, handler) { | ||
var observer = React.useRef(new resizeObserver.ResizeObserver(function (_a) { | ||
var entry = _a[0]; | ||
var observer = React.useRef(new resizeObserver.ResizeObserver(function (_ref2) { | ||
var entry = _ref2[0]; | ||
handler && handler(entry.contentRect); | ||
@@ -107,3 +163,3 @@ })); | ||
/** | ||
* Whether client supports the CSS `object-fit` property | ||
* Whether client supports the CSS `object-fit` property. | ||
*/ | ||
@@ -116,13 +172,13 @@ | ||
* Image with fallback background for browsers that don't support the | ||
* `object-fit` CSS property | ||
* `object-fit` CSS property. | ||
*/ | ||
var ReactCompareSliderImage = function ReactCompareSliderImage(_a) { | ||
var className = _a.className, | ||
_b = _a.fallbackEnable, | ||
fallbackEnable = _b === void 0 ? true : _b, | ||
style = _a.style, | ||
props = tslib.__rest(_a, ["className", "fallbackEnable", "style"]); | ||
var ReactCompareSliderImage = function ReactCompareSliderImage(_ref) { | ||
var className = _ref.className, | ||
_ref$fallbackEnable = _ref.fallbackEnable, | ||
fallbackEnable = _ref$fallbackEnable === void 0 ? true : _ref$fallbackEnable, | ||
style = _ref.style, | ||
props = _objectWithoutPropertiesLoose(_ref, ["className", "fallbackEnable", "style"]); | ||
var innerStyle = styleFitContainer(tslib.__assign({}, style)); | ||
var innerStyle = styleFitContainer(_extends({}, style)); | ||
var containerStyle = { | ||
@@ -146,3 +202,3 @@ width: innerStyle.width, | ||
"data-rcs": "image-root" | ||
}, React__default.createElement("img", tslib.__assign({}, props, { | ||
}, React__default.createElement("img", Object.assign({}, props, { | ||
style: innerStyle, | ||
@@ -153,8 +209,8 @@ "data-rcs": "image-inner" | ||
/** Handle container to control position */ | ||
/** Handle container to control position. */ | ||
var ReactCompareSliderHandleContainer = function ReactCompareSliderHandleContainer(_a) { | ||
var children = _a.children, | ||
position = _a.position, | ||
portrait = _a.portrait; | ||
var ReactCompareSliderHandleContainer = function ReactCompareSliderHandleContainer(_ref) { | ||
var children = _ref.children, | ||
position = _ref.position, | ||
portrait = _ref.portrait; | ||
var style = { | ||
@@ -183,18 +239,20 @@ position: 'absolute', | ||
}; | ||
/** Overridable handle */ | ||
/** Overridable handle. */ | ||
var ReactCompareSliderHandle = function ReactCompareSliderHandle(_a) { | ||
var portrait = _a.portrait, | ||
props = tslib.__rest(_a, ["portrait"]); | ||
var ReactCompareSliderHandle = function ReactCompareSliderHandle(_ref2) { | ||
var portrait = _ref2.portrait, | ||
style = _ref2.style, | ||
props = _objectWithoutPropertiesLoose(_ref2, ["portrait", "style"]); | ||
var style = { | ||
var rootStyle = _extends({ | ||
height: portrait ? 3 : '100%', | ||
width: portrait ? '100%' : 3, | ||
backgroundColor: '#ffffff', | ||
boxShadow: '0 0 .2rem #000000', | ||
backgroundColor: '#fff', | ||
boxShadow: '0 0 .2rem #000', | ||
cursor: portrait ? 'ns-resize' : 'ew-resize' | ||
}; | ||
return React__default.createElement("div", tslib.__assign({}, props, { | ||
style: style, | ||
}, style); | ||
return React__default.createElement("div", Object.assign({}, props, { | ||
style: rootStyle, | ||
"data-rcs": "main-handle-inner" | ||
@@ -205,6 +263,6 @@ })); | ||
var ReactCompareSliderItem = function ReactCompareSliderItem(_a) { | ||
var portrait = _a.portrait, | ||
position = _a.position, | ||
props = tslib.__rest(_a, ["portrait", "position"]); | ||
var ReactCompareSliderItem = function ReactCompareSliderItem(_ref3) { | ||
var portrait = _ref3.portrait, | ||
position = _ref3.position, | ||
props = _objectWithoutPropertiesLoose(_ref3, ["portrait", "position"]); | ||
@@ -224,3 +282,3 @@ var style = { | ||
}; | ||
return React__default.createElement("div", tslib.__assign({}, props, { | ||
return React__default.createElement("div", Object.assign({}, props, { | ||
style: style, | ||
@@ -230,65 +288,109 @@ "data-rcs": "clip-item" | ||
}; | ||
/** Comparison slider */ | ||
/** Root Comparison slider. */ | ||
var ReactCompareSlider = function ReactCompareSlider(_a) { | ||
var handle = _a.handle, | ||
itemOne = _a.itemOne, | ||
itemTwo = _a.itemTwo, | ||
onPositionChange = _a.onPositionChange, | ||
portrait = _a.portrait, | ||
_b = _a.position, | ||
position = _b === void 0 ? 50 : _b, | ||
style = _a.style, | ||
props = tslib.__rest(_a, ["handle", "itemOne", "itemTwo", "onPositionChange", "portrait", "position", "style"]); | ||
var ReactCompareSlider = function ReactCompareSlider(_ref4) { | ||
var handle = _ref4.handle, | ||
itemOne = _ref4.itemOne, | ||
itemTwo = _ref4.itemTwo, | ||
onPositionChange = _ref4.onPositionChange, | ||
portrait = _ref4.portrait, | ||
_ref4$position = _ref4.position, | ||
position = _ref4$position === void 0 ? 50 : _ref4$position, | ||
style = _ref4.style, | ||
props = _objectWithoutPropertiesLoose(_ref4, ["handle", "itemOne", "itemTwo", "onPositionChange", "portrait", "position", "style"]); | ||
var _c = React.useState({ | ||
width: 0, | ||
height: 0 | ||
}), | ||
containerBounds = _c[0], | ||
setContainerBounds = _c[1]; | ||
/** Reference to root container. */ | ||
var containerRef = React.useRef(document.createElement('div')); | ||
/** Previous props positon (tracks user-supplied `position`). */ | ||
var containerRef = React.useRef(document.createElement('div')); | ||
var prevPropsPosition = usePrevious(position); | ||
/** Previous props positon (tracks user-supplied `portrait`). */ | ||
var prevPropsPortrait = usePrevious(portrait); | ||
/** Reference to current position as a percentage value. */ | ||
var internalPositionPc = React.useRef(position); | ||
/** Internal position in pixels. */ | ||
var _d = React.useState(0), | ||
internalPositionPx = _d[0], | ||
setInternalPositionPx = _d[1]; | ||
var _useState = React.useState(0), | ||
internalPositionPx = _useState[0], | ||
setInternalPositionPx = _useState[1]; | ||
/** Reference to previous `internalPositionPx` value. */ | ||
var _e = React.useState(false), | ||
isDragging = _e[0], | ||
setIsDragging = _e[1]; | ||
/** Whether user is currently dragging. */ | ||
var _useState2 = React.useState(false), | ||
isDragging = _useState2[0], | ||
setIsDragging = _useState2[1]; | ||
/** Whether component has a `window` event binding. */ | ||
var hasWindowBinding = React.useRef(false); | ||
var updateInternalPosition = React.useCallback(function (_a) { | ||
var x = _a.x, | ||
y = _a.y; | ||
/** Update internal px and pc */ | ||
var _b = containerRef.current.getBoundingClientRect(), | ||
top = _b.top, | ||
left = _b.left; | ||
var updateInternalPosition = React.useCallback(function (_ref5) { | ||
var x = _ref5.x, | ||
y = _ref5.y, | ||
isOffset = _ref5.isOffset; | ||
var positionPx = portrait ? y - top - window.pageYOffset : x - left - window.pageXOffset; | ||
setInternalPositionPx(positionPx); // Calculate percentage with bounds checking | ||
var _containerRef$current = containerRef.current.getBoundingClientRect(), | ||
top = _containerRef$current.top, | ||
left = _containerRef$current.left, | ||
width = _containerRef$current.width, | ||
height = _containerRef$current.height; // Early out if width or height are zero, can't calculate values | ||
// from zeros. | ||
internalPositionPc.current = Math.min(Math.max(positionPx / (portrait ? containerBounds.height : containerBounds.width) * 100, 0), 100); | ||
if (width === 0 || height === 0) return; | ||
/** Position in pixels with offsets *optionally* applied. */ | ||
var positionPx = portrait ? isOffset ? y - top - window.pageYOffset : y : isOffset ? x - left - window.pageXOffset : x; // Snap `positionPx` to container extremity if it exceeds container bounds. | ||
if (positionPx < 0) { | ||
positionPx = 0; | ||
} else if (portrait && positionPx > height) { | ||
positionPx = height; | ||
} else if (!portrait && positionPx > width) { | ||
positionPx = width; | ||
} // Calculate percentage with bounds checking. | ||
internalPositionPc.current = Math.min(Math.max(positionPx / (portrait ? height : width) * 100, 0), 100); | ||
setInternalPositionPx(positionPx); | ||
if (onPositionChange) onPositionChange(internalPositionPc.current); | ||
}, [containerBounds.height, containerBounds.width, onPositionChange, portrait]); // Update internal position if `position` prop changes | ||
}, [onPositionChange, portrait]); // Update internal position if `position` prop changes | ||
React.useEffect(function () { | ||
var _a = containerRef.current.getBoundingClientRect(), | ||
top = _a.top, | ||
left = _a.left, | ||
width = _a.width, | ||
height = _a.height; | ||
// Early out if position hasn't changed | ||
if (prevPropsPosition === position || prevPropsPosition === portrait) { | ||
return; | ||
} | ||
var _containerRef$current2 = containerRef.current.getBoundingClientRect(), | ||
width = _containerRef$current2.width, | ||
height = _containerRef$current2.height; // Parse `portrait` changes before `position` ones. | ||
if (prevPropsPortrait !== portrait) { | ||
// Update using internal percentage when `portrait` changes. | ||
updateInternalPosition({ | ||
x: width / 100 * internalPositionPc.current, | ||
y: height / 100 * internalPositionPc.current | ||
}); | ||
return; | ||
} | ||
updateInternalPosition({ | ||
x: width / 100 * position + left, | ||
y: height / 100 * position + top | ||
x: width / 100 * position, | ||
y: height / 100 * position | ||
}); | ||
}, [position, updateInternalPosition]); | ||
}, [portrait, position, prevPropsPortrait, prevPropsPosition, updateInternalPosition]); | ||
/** Handle mouse/touch down */ | ||
var handlePointerDown = React.useCallback(function (ev) { | ||
ev.preventDefault(); | ||
updateInternalPosition({ | ||
isOffset: true, | ||
x: ev instanceof MouseEvent ? ev.pageX : ev.touches[0].pageX, | ||
@@ -299,2 +401,4 @@ y: ev instanceof MouseEvent ? ev.pageY : ev.touches[0].pageY | ||
}, [updateInternalPosition]); | ||
/** Handle mouse/touch move */ | ||
var handlePointerMove = React.useCallback(function (ev) { | ||
@@ -304,2 +408,3 @@ if (!isDragging) return; | ||
updateInternalPosition({ | ||
isOffset: true, | ||
x: ev instanceof MouseEvent ? ev.pageX : ev.touches[0].pageX, | ||
@@ -310,14 +415,17 @@ y: ev instanceof MouseEvent ? ev.pageY : ev.touches[0].pageY | ||
}, [isDragging, updateInternalPosition]); | ||
/** Handle mouse/touch up */ | ||
var handlePointerUp = React.useCallback(function () { | ||
setIsDragging(false); | ||
}, []); | ||
var handleResize = React.useCallback(function (_a) { | ||
var width = _a.width, | ||
height = _a.height; | ||
setContainerBounds({ | ||
width: width, | ||
height: height | ||
/** Resync internal position on resize */ | ||
var handleResize = React.useCallback(function (_ref6) { | ||
var width = _ref6.width, | ||
height = _ref6.height; | ||
updateInternalPosition({ | ||
x: width / 100 * internalPositionPc.current, | ||
y: height / 100 * internalPositionPc.current | ||
}); | ||
setInternalPositionPx((portrait ? height : width) / 100 * internalPositionPc.current); | ||
}, [portrait]); // Allow drag outside of container while pointer is still down | ||
}, [updateInternalPosition]); // Allow drag outside of container while pointer is still down | ||
@@ -329,3 +437,3 @@ React.useEffect(function () { | ||
}); | ||
document.addEventListener('mouseup', handlePointerUp, { | ||
window.addEventListener('mouseup', handlePointerUp, { | ||
passive: true | ||
@@ -373,6 +481,7 @@ }); | ||
var rootStyle = tslib.__assign({ | ||
var rootStyle = _extends({ | ||
position: 'relative', | ||
overflow: 'hidden', | ||
cursor: isDragging ? portrait ? 'ns-resize' : 'ew-resize' : undefined, | ||
touchAction: portrait ? 'pan-x' : 'pan-y', | ||
userSelect: 'none', | ||
@@ -384,3 +493,3 @@ KhtmlUserSelect: 'none', | ||
return React__default.createElement("div", tslib.__assign({}, props, { | ||
return React__default.createElement("div", Object.assign({}, props, { | ||
ref: containerRef, | ||
@@ -387,0 +496,0 @@ style: rootStyle, |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("tslib"),n=require("react"),r=(e=n)&&"object"==typeof e&&"default"in e?e.default:e,i=require("resize-observer"),o=function(e){void 0===e&&(e={});var n=e.objectFit,r=void 0===n?"cover":n,i=t.__rest(e,["objectFit"]);return t.__assign({display:"block",width:"100%",height:"100%",maxWidth:"100%",objectFit:r},i)},a=function(e,t,r,i){void 0===r&&(r=window);var o=n.useRef();n.useEffect((function(){o.current=t}),[t]),n.useEffect((function(){if(r&&r.addEventListener){var t=function(e){return o.current&&o.current(e)};return r.addEventListener(e,t,i),function(){r.removeEventListener(e,t,i)}}}),[e,r,i])},s="undefined"!=typeof CSS&&CSS.supports&&CSS.supports("object-fit","cover"),c=function(e){var t=e.position,n=e.portrait;return r.createElement("div",{style:{position:"absolute",top:0,width:"100%",height:"100%",transform:n?"translateY("+t+"px)":"translateX("+t+"px)",pointerEvents:"none"},"data-rcs":"main-handle-container"},r.createElement("div",{style:{position:"absolute",width:n?"100%":void 0,height:n?void 0:"100%",transform:n?"translateY(-50%)":"translateX(-50%)",pointerEvents:"all"}},e.children))},u=function(e){var n=e.portrait,i=t.__rest(e,["portrait"]);return r.createElement("div",t.__assign({},i,{style:{height:n?3:"100%",width:n?"100%":3,backgroundColor:"#ffffff",boxShadow:"0 0 .2rem #000000",cursor:n?"ns-resize":"ew-resize"},"data-rcs":"main-handle-inner"}))},l=function(e){var n=e.portrait,i=e.position,o=t.__rest(e,["portrait","position"]);return r.createElement("div",t.__assign({},o,{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",clip:n?"rect(auto,auto,"+i+"px,auto)":"rect(auto,"+i+"px,auto,auto)",willChange:"clip",userSelect:"none",KhtmlUserSelect:"none",MozUserSelect:"none",WebkitUserSelect:"none"},"data-rcs":"clip-item"}))};exports.CLIENT_SUPPORTS_CSS_OBJECT_FIT=s,exports.ReactCompareSlider=function(e){var o=e.handle,s=e.itemOne,d=e.itemTwo,p=e.onPositionChange,f=e.portrait,v=e.position,h=void 0===v?50:v,m=e.style,g=t.__rest(e,["handle","itemOne","itemTwo","onPositionChange","portrait","position","style"]),w=n.useState({width:0,height:0}),b=w[0],E=w[1],_=n.useRef(document.createElement("div")),S=n.useRef(h),C=n.useState(0),y=C[0],k=C[1],x=n.useState(!1),R=x[0],L=x[1],z=n.useRef(!1),M=n.useCallback((function(e){var t=e.x,n=e.y,r=_.current.getBoundingClientRect(),i=f?n-r.top-window.pageYOffset:t-r.left-window.pageXOffset;k(i),S.current=Math.min(Math.max(i/(f?b.height:b.width)*100,0),100),p&&p(S.current)}),[b.height,b.width,p,f]);n.useEffect((function(){var e=_.current.getBoundingClientRect();M({x:e.width/100*h+e.left,y:e.height/100*h+e.top})}),[h,M]);var O,P,U,X,Y,j=n.useCallback((function(e){e.preventDefault(),M({x:e instanceof MouseEvent?e.pageX:e.touches[0].pageX,y:e instanceof MouseEvent?e.pageY:e.touches[0].pageY}),L(!0)}),[M]),F=n.useCallback((function(e){R&&requestAnimationFrame((function(){M({x:e instanceof MouseEvent?e.pageX:e.touches[0].pageX,y:e instanceof MouseEvent?e.pageY:e.touches[0].pageY})}))}),[R,M]),T=n.useCallback((function(){L(!1)}),[]),I=n.useCallback((function(e){var t=e.width,n=e.height;E({width:t,height:n}),k((f?n:t)/100*S.current)}),[f]);n.useEffect((function(){return R&&!z.current&&(window.addEventListener("mousemove",F,{passive:!0}),document.addEventListener("mouseup",T,{passive:!0}),window.addEventListener("touchmove",F,{passive:!0}),window.addEventListener("touchend",T,{passive:!0}),z.current=!0),function(){z.current&&(window.removeEventListener("mousemove",F),window.removeEventListener("mouseup",T),z.current=!1)}}),[F,T,R]),O=_,P=I,U=n.useRef(new i.ResizeObserver((function(e){P&&P(e[0].contentRect)}))),X=n.useCallback((function(){var e=U.current;e&&e.disconnect()}),[]),Y=n.useCallback((function(){O.current&&U.current.observe(O.current)}),[O]),n.useLayoutEffect((function(){return Y(),function(){return X()}}),[X,Y]),a("mousedown",j,_.current,{capture:!0,passive:!1}),a("touchmove",F,_.current,{capture:!1,passive:!0}),a("touchend",T,_.current,{capture:!1,passive:!0}),a("touchstart",j,_.current,{capture:!0,passive:!1});var q=o||r.createElement(u,{portrait:f}),N=t.__assign({position:"relative",overflow:"hidden",cursor:R?f?"ns-resize":"ew-resize":void 0,userSelect:"none",KhtmlUserSelect:"none",MozUserSelect:"none",WebkitUserSelect:"none"},m);return r.createElement("div",t.__assign({},g,{ref:_,style:N,"data-rcs":"root"}),d,r.createElement(l,{position:y,portrait:f},s),r.createElement(c,{position:y,portrait:f},q))},exports.ReactCompareSliderHandle=u,exports.ReactCompareSliderImage=function(e){var n=e.className,i=e.fallbackEnable,a=void 0===i||i,c=e.style,u=t.__rest(e,["className","fallbackEnable","style"]),l=o(t.__assign({},c)),d={width:l.width,height:l.height};return!s&&a&&(d.backgroundImage=l.backgroundImage||"url("+u.src+")",d.backgroundSize=l.backgroundSize||"cover",d.backgroundPosition=l.backgroundPosition||"center",l.opacity=0),r.createElement("div",{className:n,style:d,"data-rcs":"image-root"},r.createElement("img",t.__assign({},u,{style:l,"data-rcs":"image-inner"})))},exports.styleFitContainer=o; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("react"),n=(e=t)&&"object"==typeof e&&"default"in e?e.default:e,r=require("resize-observer");function o(){return(o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function i(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)t.indexOf(n=i[r])>=0||(o[n]=e[n]);return o}var a=function(e){var t=void 0===e?{}:e,n=t.objectFit,r=t.objectPosition;return o({display:"block",width:"100%",height:"100%",maxWidth:"100%",objectFit:void 0===n?"cover":n,objectPosition:void 0===r?"center":r},i(t,["objectFit","objectPosition"]))},s=function(e){var n=t.useRef(),r=t.useRef();return r.current!==e&&(n.current=r.current,r.current=e),n.current},c=function(e,n,r,o){void 0===r&&(r=window);var i=t.useRef();t.useEffect((function(){i.current=n}),[n]),t.useEffect((function(){if(r&&r.addEventListener){var t=function(e){return i.current&&i.current(e)};return r.addEventListener(e,t,o),function(){r.removeEventListener(e,t,o)}}}),[e,r,o])},u="undefined"!=typeof CSS&&CSS.supports&&CSS.supports("object-fit","cover"),l=function(e){var t=e.position,r=e.portrait;return n.createElement("div",{style:{position:"absolute",top:0,width:"100%",height:"100%",transform:r?"translateY("+t+"px)":"translateX("+t+"px)",pointerEvents:"none"},"data-rcs":"main-handle-container"},n.createElement("div",{style:{position:"absolute",width:r?"100%":void 0,height:r?void 0:"100%",transform:r?"translateY(-50%)":"translateX(-50%)",pointerEvents:"all"}},e.children))},d=function(e){var t=e.portrait,r=e.style,a=i(e,["portrait","style"]),s=o({height:t?3:"100%",width:t?"100%":3,backgroundColor:"#fff",boxShadow:"0 0 .2rem #000",cursor:t?"ns-resize":"ew-resize"},r);return n.createElement("div",Object.assign({},a,{style:s,"data-rcs":"main-handle-inner"}))},f=function(e){var t=e.portrait,r=e.position,o=i(e,["portrait","position"]);return n.createElement("div",Object.assign({},o,{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",clip:t?"rect(auto,auto,"+r+"px,auto)":"rect(auto,"+r+"px,auto,auto)",willChange:"clip",userSelect:"none",KhtmlUserSelect:"none",MozUserSelect:"none",WebkitUserSelect:"none"},"data-rcs":"clip-item"}))};exports.CLIENT_SUPPORTS_CSS_OBJECT_FIT=u,exports.ReactCompareSlider=function(e){var a=e.handle,u=e.itemOne,p=e.itemTwo,v=e.onPositionChange,h=e.portrait,m=e.position,g=void 0===m?50:m,b=e.style,w=i(e,["handle","itemOne","itemTwo","onPositionChange","portrait","position","style"]),E=t.useRef(document.createElement("div")),y=s(g),S=s(h),C=t.useRef(g),x=t.useState(0),k=x[0],O=x[1],j=t.useState(!1),R=j[0],L=j[1],P=t.useRef(!1),z=t.useCallback((function(e){var t=e.x,n=e.y,r=e.isOffset,o=E.current.getBoundingClientRect(),i=o.width,a=o.height;if(0!==i&&0!==a){var s=h?r?n-o.top-window.pageYOffset:n:r?t-o.left-window.pageXOffset:t;s<0?s=0:h&&s>a?s=a:!h&&s>i&&(s=i),C.current=Math.min(Math.max(s/(h?a:i)*100,0),100),O(s),v&&v(C.current)}}),[v,h]);t.useEffect((function(){if(y!==g&&y!==h){var e=E.current.getBoundingClientRect(),t=e.width,n=e.height;z(S===h?{x:t/100*g,y:n/100*g}:{x:t/100*C.current,y:n/100*C.current})}}),[h,g,S,y,z]);var M,U,X,Y,F,T=t.useCallback((function(e){e.preventDefault(),z({isOffset:!0,x:e instanceof MouseEvent?e.pageX:e.touches[0].pageX,y:e instanceof MouseEvent?e.pageY:e.touches[0].pageY}),L(!0)}),[z]),_=t.useCallback((function(e){R&&requestAnimationFrame((function(){z({isOffset:!0,x:e instanceof MouseEvent?e.pageX:e.touches[0].pageX,y:e instanceof MouseEvent?e.pageY:e.touches[0].pageY})}))}),[R,z]),I=t.useCallback((function(){L(!1)}),[]),N=t.useCallback((function(e){z({x:e.width/100*C.current,y:e.height/100*C.current})}),[z]);t.useEffect((function(){return R&&!P.current&&(window.addEventListener("mousemove",_,{passive:!0}),window.addEventListener("mouseup",I,{passive:!0}),window.addEventListener("touchmove",_,{passive:!0}),window.addEventListener("touchend",I,{passive:!0}),P.current=!0),function(){P.current&&(window.removeEventListener("mousemove",_),window.removeEventListener("mouseup",I),P.current=!1)}}),[_,I,R]),M=E,U=N,X=t.useRef(new r.ResizeObserver((function(e){U&&U(e[0].contentRect)}))),Y=t.useCallback((function(){var e=X.current;e&&e.disconnect()}),[]),F=t.useCallback((function(){M.current&&X.current.observe(M.current)}),[M]),t.useLayoutEffect((function(){return F(),function(){return Y()}}),[Y,F]),c("mousedown",T,E.current,{capture:!0,passive:!1}),c("touchmove",_,E.current,{capture:!1,passive:!0}),c("touchend",I,E.current,{capture:!1,passive:!0}),c("touchstart",T,E.current,{capture:!0,passive:!1});var q=a||n.createElement(d,{portrait:h}),B=o({position:"relative",overflow:"hidden",cursor:R?h?"ns-resize":"ew-resize":void 0,touchAction:h?"pan-x":"pan-y",userSelect:"none",KhtmlUserSelect:"none",MozUserSelect:"none",WebkitUserSelect:"none"},b);return n.createElement("div",Object.assign({},w,{ref:E,style:B,"data-rcs":"root"}),p,n.createElement(f,{position:k,portrait:h},u),n.createElement(l,{position:k,portrait:h},q))},exports.ReactCompareSliderHandle=d,exports.ReactCompareSliderImage=function(e){var t=e.className,r=e.fallbackEnable,s=void 0===r||r,c=e.style,l=i(e,["className","fallbackEnable","style"]),d=a(o({},c)),f={width:d.width,height:d.height};return!u&&s&&(f.backgroundImage=d.backgroundImage||"url("+l.src+")",f.backgroundSize=d.backgroundSize||"cover",f.backgroundPosition=d.backgroundPosition||"center",d.opacity=0),n.createElement("div",{className:t,style:f,"data-rcs":"image-root"},n.createElement("img",Object.assign({},l,{style:d,"data-rcs":"image-inner"})))},exports.styleFitContainer=a; | ||
//# sourceMappingURL=react-compare-slider.cjs.production.min.js.map |
import React from 'react'; | ||
/** Slider position prop */ | ||
/** Slider position property. */ | ||
declare type ReactCompareSliderPropPosition = number; | ||
/** Common props shared between child components */ | ||
/** Common props shared between child components. */ | ||
interface ReactCompareSliderCommonProps { | ||
/** Orientation */ | ||
portrait?: boolean; | ||
/** Divider position in pixels */ | ||
position: ReactCompareSliderPropPosition; | ||
} | ||
/** Overridable handle */ | ||
export declare const ReactCompareSliderHandle: React.FC<Pick<ReactCompareSliderCommonProps, 'portrait'>>; | ||
/** Comparison slider props */ | ||
/** Props for `ReactCompareSliderHandle`. */ | ||
export interface ReactCompareSliderHandleProps extends Pick<ReactCompareSliderCommonProps, 'portrait'> { | ||
/** Optional inline styles */ | ||
style?: React.CSSProperties; | ||
} | ||
/** Overridable handle. */ | ||
export declare const ReactCompareSliderHandle: React.FC<ReactCompareSliderHandleProps>; | ||
/** Comparison slider properties. */ | ||
export interface ReactCompareSliderProps { | ||
@@ -22,8 +29,8 @@ /** Custom handle component */ | ||
/** Orientation */ | ||
portrait?: boolean; | ||
/** Percentage position of divide */ | ||
portrait?: ReactCompareSliderCommonProps['portrait']; | ||
/** Percentage position of divide (`0-100`) */ | ||
position?: ReactCompareSliderPropPosition; | ||
} | ||
/** Comparison slider */ | ||
/** Root Comparison slider. */ | ||
export declare const ReactCompareSlider: React.FC<ReactCompareSliderProps & React.HtmlHTMLAttributes<HTMLDivElement>>; | ||
export {}; |
@@ -1,19 +0,51 @@ | ||
import { __rest, __assign } from 'tslib'; | ||
import React, { useRef, useEffect, useCallback, useLayoutEffect, useState } from 'react'; | ||
import { ResizeObserver } from 'resize-observer'; | ||
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); | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
if (source == null) return {}; | ||
var target = {}; | ||
var sourceKeys = Object.keys(source); | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
key = sourceKeys[i]; | ||
if (excluded.indexOf(key) >= 0) continue; | ||
target[key] = source[key]; | ||
} | ||
return target; | ||
} | ||
/** | ||
* CSS style util for child to fit container | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) | ||
* fit their container and maintain their aspect ratio. | ||
*/ | ||
var styleFitContainer = function styleFitContainer(_a) { | ||
if (_a === void 0) { | ||
_a = {}; | ||
} | ||
var styleFitContainer = function styleFitContainer(_temp) { | ||
var _ref = _temp === void 0 ? {} : _temp, | ||
_ref$objectFit = _ref.objectFit, | ||
objectFit = _ref$objectFit === void 0 ? 'cover' : _ref$objectFit, | ||
_ref$objectPosition = _ref.objectPosition, | ||
objectPosition = _ref$objectPosition === void 0 ? 'center' : _ref$objectPosition, | ||
props = _objectWithoutPropertiesLoose(_ref, ["objectFit", "objectPosition"]); | ||
var _b = _a.objectFit, | ||
objectFit = _b === void 0 ? 'cover' : _b, | ||
props = __rest(_a, ["objectFit"]); | ||
return __assign({ | ||
return _extends({ | ||
display: 'block', | ||
@@ -23,7 +55,31 @@ width: '100%', | ||
maxWidth: '100%', | ||
objectFit: objectFit | ||
objectFit: objectFit, | ||
objectPosition: objectPosition | ||
}, props); | ||
}; | ||
/** Perform strict primitive equals. */ | ||
var strictEquals = function strictEquals(prev, next) { | ||
return prev === next; | ||
}; | ||
/** | ||
* Event listener binding hook | ||
* Use previous value. | ||
* @see https://github.com/streamich/react-use/blob/master/src/usePreviousDistinct.ts | ||
*/ | ||
var usePrevious = function usePrevious(value) { | ||
var previousRef = useRef(); | ||
var currentRef = useRef(); | ||
if (!strictEquals(currentRef.current, value)) { | ||
previousRef.current = currentRef.current; | ||
currentRef.current = value; | ||
} // Return previous value (happens before update in useEffect above) | ||
return previousRef.current; | ||
}; | ||
/** | ||
* Event listener binding hook. | ||
* @param eventName - Event to bind to | ||
@@ -38,5 +94,5 @@ * @param handler - Callback handler | ||
element = window; | ||
} // Create a ref that stores handler | ||
} | ||
// Create a ref that stores handler | ||
var savedHandler = useRef(); // Update ref.current value if handler changes. | ||
@@ -69,3 +125,3 @@ // This allows our effect below to always get latest handler ... | ||
/** | ||
* Bind resize observer to ref | ||
* Bind resize observer to ref. | ||
* @param ref - Ref to bind to | ||
@@ -77,4 +133,4 @@ * @param handler - Callback for handling entry's bounding rect | ||
var useResizeObserver = function useResizeObserver(ref, handler) { | ||
var observer = useRef(new ResizeObserver(function (_a) { | ||
var entry = _a[0]; | ||
var observer = useRef(new ResizeObserver(function (_ref2) { | ||
var entry = _ref2[0]; | ||
handler && handler(entry.contentRect); | ||
@@ -98,3 +154,3 @@ })); | ||
/** | ||
* Whether client supports the CSS `object-fit` property | ||
* Whether client supports the CSS `object-fit` property. | ||
*/ | ||
@@ -107,13 +163,13 @@ | ||
* Image with fallback background for browsers that don't support the | ||
* `object-fit` CSS property | ||
* `object-fit` CSS property. | ||
*/ | ||
var ReactCompareSliderImage = function ReactCompareSliderImage(_a) { | ||
var className = _a.className, | ||
_b = _a.fallbackEnable, | ||
fallbackEnable = _b === void 0 ? true : _b, | ||
style = _a.style, | ||
props = __rest(_a, ["className", "fallbackEnable", "style"]); | ||
var ReactCompareSliderImage = function ReactCompareSliderImage(_ref) { | ||
var className = _ref.className, | ||
_ref$fallbackEnable = _ref.fallbackEnable, | ||
fallbackEnable = _ref$fallbackEnable === void 0 ? true : _ref$fallbackEnable, | ||
style = _ref.style, | ||
props = _objectWithoutPropertiesLoose(_ref, ["className", "fallbackEnable", "style"]); | ||
var innerStyle = styleFitContainer(__assign({}, style)); | ||
var innerStyle = styleFitContainer(_extends({}, style)); | ||
var containerStyle = { | ||
@@ -137,3 +193,3 @@ width: innerStyle.width, | ||
"data-rcs": "image-root" | ||
}, React.createElement("img", __assign({}, props, { | ||
}, React.createElement("img", Object.assign({}, props, { | ||
style: innerStyle, | ||
@@ -144,8 +200,8 @@ "data-rcs": "image-inner" | ||
/** Handle container to control position */ | ||
/** Handle container to control position. */ | ||
var ReactCompareSliderHandleContainer = function ReactCompareSliderHandleContainer(_a) { | ||
var children = _a.children, | ||
position = _a.position, | ||
portrait = _a.portrait; | ||
var ReactCompareSliderHandleContainer = function ReactCompareSliderHandleContainer(_ref) { | ||
var children = _ref.children, | ||
position = _ref.position, | ||
portrait = _ref.portrait; | ||
var style = { | ||
@@ -174,18 +230,20 @@ position: 'absolute', | ||
}; | ||
/** Overridable handle */ | ||
/** Overridable handle. */ | ||
var ReactCompareSliderHandle = function ReactCompareSliderHandle(_a) { | ||
var portrait = _a.portrait, | ||
props = __rest(_a, ["portrait"]); | ||
var ReactCompareSliderHandle = function ReactCompareSliderHandle(_ref2) { | ||
var portrait = _ref2.portrait, | ||
style = _ref2.style, | ||
props = _objectWithoutPropertiesLoose(_ref2, ["portrait", "style"]); | ||
var style = { | ||
var rootStyle = _extends({ | ||
height: portrait ? 3 : '100%', | ||
width: portrait ? '100%' : 3, | ||
backgroundColor: '#ffffff', | ||
boxShadow: '0 0 .2rem #000000', | ||
backgroundColor: '#fff', | ||
boxShadow: '0 0 .2rem #000', | ||
cursor: portrait ? 'ns-resize' : 'ew-resize' | ||
}; | ||
return React.createElement("div", __assign({}, props, { | ||
style: style, | ||
}, style); | ||
return React.createElement("div", Object.assign({}, props, { | ||
style: rootStyle, | ||
"data-rcs": "main-handle-inner" | ||
@@ -196,6 +254,6 @@ })); | ||
var ReactCompareSliderItem = function ReactCompareSliderItem(_a) { | ||
var portrait = _a.portrait, | ||
position = _a.position, | ||
props = __rest(_a, ["portrait", "position"]); | ||
var ReactCompareSliderItem = function ReactCompareSliderItem(_ref3) { | ||
var portrait = _ref3.portrait, | ||
position = _ref3.position, | ||
props = _objectWithoutPropertiesLoose(_ref3, ["portrait", "position"]); | ||
@@ -215,3 +273,3 @@ var style = { | ||
}; | ||
return React.createElement("div", __assign({}, props, { | ||
return React.createElement("div", Object.assign({}, props, { | ||
style: style, | ||
@@ -221,65 +279,109 @@ "data-rcs": "clip-item" | ||
}; | ||
/** Comparison slider */ | ||
/** Root Comparison slider. */ | ||
var ReactCompareSlider = function ReactCompareSlider(_a) { | ||
var handle = _a.handle, | ||
itemOne = _a.itemOne, | ||
itemTwo = _a.itemTwo, | ||
onPositionChange = _a.onPositionChange, | ||
portrait = _a.portrait, | ||
_b = _a.position, | ||
position = _b === void 0 ? 50 : _b, | ||
style = _a.style, | ||
props = __rest(_a, ["handle", "itemOne", "itemTwo", "onPositionChange", "portrait", "position", "style"]); | ||
var ReactCompareSlider = function ReactCompareSlider(_ref4) { | ||
var handle = _ref4.handle, | ||
itemOne = _ref4.itemOne, | ||
itemTwo = _ref4.itemTwo, | ||
onPositionChange = _ref4.onPositionChange, | ||
portrait = _ref4.portrait, | ||
_ref4$position = _ref4.position, | ||
position = _ref4$position === void 0 ? 50 : _ref4$position, | ||
style = _ref4.style, | ||
props = _objectWithoutPropertiesLoose(_ref4, ["handle", "itemOne", "itemTwo", "onPositionChange", "portrait", "position", "style"]); | ||
var _c = useState({ | ||
width: 0, | ||
height: 0 | ||
}), | ||
containerBounds = _c[0], | ||
setContainerBounds = _c[1]; | ||
/** Reference to root container. */ | ||
var containerRef = useRef(document.createElement('div')); | ||
/** Previous props positon (tracks user-supplied `position`). */ | ||
var containerRef = useRef(document.createElement('div')); | ||
var prevPropsPosition = usePrevious(position); | ||
/** Previous props positon (tracks user-supplied `portrait`). */ | ||
var prevPropsPortrait = usePrevious(portrait); | ||
/** Reference to current position as a percentage value. */ | ||
var internalPositionPc = useRef(position); | ||
/** Internal position in pixels. */ | ||
var _d = useState(0), | ||
internalPositionPx = _d[0], | ||
setInternalPositionPx = _d[1]; | ||
var _useState = useState(0), | ||
internalPositionPx = _useState[0], | ||
setInternalPositionPx = _useState[1]; | ||
/** Reference to previous `internalPositionPx` value. */ | ||
var _e = useState(false), | ||
isDragging = _e[0], | ||
setIsDragging = _e[1]; | ||
/** Whether user is currently dragging. */ | ||
var _useState2 = useState(false), | ||
isDragging = _useState2[0], | ||
setIsDragging = _useState2[1]; | ||
/** Whether component has a `window` event binding. */ | ||
var hasWindowBinding = useRef(false); | ||
var updateInternalPosition = useCallback(function (_a) { | ||
var x = _a.x, | ||
y = _a.y; | ||
/** Update internal px and pc */ | ||
var _b = containerRef.current.getBoundingClientRect(), | ||
top = _b.top, | ||
left = _b.left; | ||
var updateInternalPosition = useCallback(function (_ref5) { | ||
var x = _ref5.x, | ||
y = _ref5.y, | ||
isOffset = _ref5.isOffset; | ||
var positionPx = portrait ? y - top - window.pageYOffset : x - left - window.pageXOffset; | ||
setInternalPositionPx(positionPx); // Calculate percentage with bounds checking | ||
var _containerRef$current = containerRef.current.getBoundingClientRect(), | ||
top = _containerRef$current.top, | ||
left = _containerRef$current.left, | ||
width = _containerRef$current.width, | ||
height = _containerRef$current.height; // Early out if width or height are zero, can't calculate values | ||
// from zeros. | ||
internalPositionPc.current = Math.min(Math.max(positionPx / (portrait ? containerBounds.height : containerBounds.width) * 100, 0), 100); | ||
if (width === 0 || height === 0) return; | ||
/** Position in pixels with offsets *optionally* applied. */ | ||
var positionPx = portrait ? isOffset ? y - top - window.pageYOffset : y : isOffset ? x - left - window.pageXOffset : x; // Snap `positionPx` to container extremity if it exceeds container bounds. | ||
if (positionPx < 0) { | ||
positionPx = 0; | ||
} else if (portrait && positionPx > height) { | ||
positionPx = height; | ||
} else if (!portrait && positionPx > width) { | ||
positionPx = width; | ||
} // Calculate percentage with bounds checking. | ||
internalPositionPc.current = Math.min(Math.max(positionPx / (portrait ? height : width) * 100, 0), 100); | ||
setInternalPositionPx(positionPx); | ||
if (onPositionChange) onPositionChange(internalPositionPc.current); | ||
}, [containerBounds.height, containerBounds.width, onPositionChange, portrait]); // Update internal position if `position` prop changes | ||
}, [onPositionChange, portrait]); // Update internal position if `position` prop changes | ||
useEffect(function () { | ||
var _a = containerRef.current.getBoundingClientRect(), | ||
top = _a.top, | ||
left = _a.left, | ||
width = _a.width, | ||
height = _a.height; | ||
// Early out if position hasn't changed | ||
if (prevPropsPosition === position || prevPropsPosition === portrait) { | ||
return; | ||
} | ||
var _containerRef$current2 = containerRef.current.getBoundingClientRect(), | ||
width = _containerRef$current2.width, | ||
height = _containerRef$current2.height; // Parse `portrait` changes before `position` ones. | ||
if (prevPropsPortrait !== portrait) { | ||
// Update using internal percentage when `portrait` changes. | ||
updateInternalPosition({ | ||
x: width / 100 * internalPositionPc.current, | ||
y: height / 100 * internalPositionPc.current | ||
}); | ||
return; | ||
} | ||
updateInternalPosition({ | ||
x: width / 100 * position + left, | ||
y: height / 100 * position + top | ||
x: width / 100 * position, | ||
y: height / 100 * position | ||
}); | ||
}, [position, updateInternalPosition]); | ||
}, [portrait, position, prevPropsPortrait, prevPropsPosition, updateInternalPosition]); | ||
/** Handle mouse/touch down */ | ||
var handlePointerDown = useCallback(function (ev) { | ||
ev.preventDefault(); | ||
updateInternalPosition({ | ||
isOffset: true, | ||
x: ev instanceof MouseEvent ? ev.pageX : ev.touches[0].pageX, | ||
@@ -290,2 +392,4 @@ y: ev instanceof MouseEvent ? ev.pageY : ev.touches[0].pageY | ||
}, [updateInternalPosition]); | ||
/** Handle mouse/touch move */ | ||
var handlePointerMove = useCallback(function (ev) { | ||
@@ -295,2 +399,3 @@ if (!isDragging) return; | ||
updateInternalPosition({ | ||
isOffset: true, | ||
x: ev instanceof MouseEvent ? ev.pageX : ev.touches[0].pageX, | ||
@@ -301,14 +406,17 @@ y: ev instanceof MouseEvent ? ev.pageY : ev.touches[0].pageY | ||
}, [isDragging, updateInternalPosition]); | ||
/** Handle mouse/touch up */ | ||
var handlePointerUp = useCallback(function () { | ||
setIsDragging(false); | ||
}, []); | ||
var handleResize = useCallback(function (_a) { | ||
var width = _a.width, | ||
height = _a.height; | ||
setContainerBounds({ | ||
width: width, | ||
height: height | ||
/** Resync internal position on resize */ | ||
var handleResize = useCallback(function (_ref6) { | ||
var width = _ref6.width, | ||
height = _ref6.height; | ||
updateInternalPosition({ | ||
x: width / 100 * internalPositionPc.current, | ||
y: height / 100 * internalPositionPc.current | ||
}); | ||
setInternalPositionPx((portrait ? height : width) / 100 * internalPositionPc.current); | ||
}, [portrait]); // Allow drag outside of container while pointer is still down | ||
}, [updateInternalPosition]); // Allow drag outside of container while pointer is still down | ||
@@ -320,3 +428,3 @@ useEffect(function () { | ||
}); | ||
document.addEventListener('mouseup', handlePointerUp, { | ||
window.addEventListener('mouseup', handlePointerUp, { | ||
passive: true | ||
@@ -364,6 +472,7 @@ }); | ||
var rootStyle = __assign({ | ||
var rootStyle = _extends({ | ||
position: 'relative', | ||
overflow: 'hidden', | ||
cursor: isDragging ? portrait ? 'ns-resize' : 'ew-resize' : undefined, | ||
touchAction: portrait ? 'pan-x' : 'pan-y', | ||
userSelect: 'none', | ||
@@ -375,3 +484,3 @@ KhtmlUserSelect: 'none', | ||
return React.createElement("div", __assign({}, props, { | ||
return React.createElement("div", Object.assign({}, props, { | ||
ref: containerRef, | ||
@@ -378,0 +487,0 @@ style: rootStyle, |
import { RefObject } from 'react'; | ||
import { ContentRect } from 'resize-observer/lib/ContentRect'; | ||
/** | ||
* CSS style util for child to fit container | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) | ||
* fit their container and maintain their aspect ratio. | ||
*/ | ||
export declare const styleFitContainer: ({ objectFit, ...props }?: import("react").CSSProperties) => import("react").CSSProperties; | ||
export declare const styleFitContainer: ({ objectFit, objectPosition, ...props }?: import("react").CSSProperties) => import("react").CSSProperties; | ||
/** | ||
* Event listener binding hook | ||
* Use previous value. | ||
* @see https://github.com/streamich/react-use/blob/master/src/usePreviousDistinct.ts | ||
*/ | ||
export declare const usePrevious: <T>(value: T) => T | undefined; | ||
/** | ||
* Event listener binding hook. | ||
* @param eventName - Event to bind to | ||
@@ -15,6 +21,6 @@ * @param handler - Callback handler | ||
export declare const useEventListener: (eventName: string, handler: Function, element: EventTarget | undefined, handlerOptions: AddEventListenerOptions) => void; | ||
/** Params passed to `useResizeObserver` `handler` function */ | ||
/** Params passed to `useResizeObserver` `handler` function. */ | ||
export declare type UseResizeObserverHandlerParams = ContentRect; | ||
/** | ||
* Bind resize observer to ref | ||
* Bind resize observer to ref. | ||
* @param ref - Ref to bind to | ||
@@ -21,0 +27,0 @@ * @param handler - Callback for handling entry's bounding rect |
{ | ||
"name": "react-compare-slider", | ||
"version": "1.0.0", | ||
"version": "1.0.1-rc.1", | ||
"license": "MIT", | ||
@@ -9,3 +9,3 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/nerdyman/react-compare-slider#readme", | ||
"homepage": "https://react-compare-slider.netlify.app/", | ||
"author": { | ||
@@ -16,2 +16,3 @@ "email": "averynerdyman@gmail.com", | ||
}, | ||
"description": "Comparison slider for React components. Supports images, videos... and everything else.", | ||
"keywords": [ | ||
@@ -28,2 +29,3 @@ "react", | ||
], | ||
"sideEffects": false, | ||
"main": "dist/index.js", | ||
@@ -38,2 +40,3 @@ "module": "dist/react-compare-slider.esm.js", | ||
"build": "tsdx build", | ||
"dedupe-types": "rm -rf node_modules && yarn remove @types/react && yarn && yarn add --dev @types/react && npx yarn-deduplicate --packages @types/react yarn.lock", | ||
"release": "np", | ||
@@ -57,5 +60,4 @@ "test": "CI=true tsdx test --color", | ||
"**/*.{js,jsx,ts,tsx}": [ | ||
"pretty-quick", | ||
"pretty-quick --staged", | ||
"eslint --config ./.eslintrc.precommit.js --fix", | ||
"git add", | ||
"yarn test --bail --findRelatedTests" | ||
@@ -76,37 +78,36 @@ ] | ||
"devDependencies": { | ||
"@storybook/addon-actions": "^5.3.0-rc.6", | ||
"@storybook/addon-docs": "^5.3.0-rc.6", | ||
"@storybook/addon-info": "^5.3.0-rc.6", | ||
"@storybook/addon-knobs": "^5.3.0-rc.6", | ||
"@storybook/addon-links": "^5.3.0-rc.6", | ||
"@storybook/addon-viewport": "^5.3.0-rc.6", | ||
"@storybook/addons": "^5.3.0-rc.6", | ||
"@storybook/preset-typescript": "^1.2.0", | ||
"@storybook/react": "^5.3.0-rc.6", | ||
"@storybook/theming": "^5.3.0-rc.6", | ||
"@testing-library/react": "^9.4.0", | ||
"@types/jest": "^24.0.25", | ||
"@types/node": "12.11.7", | ||
"@types/react": "^16.9.17", | ||
"@types/react-dom": "^16.9.4", | ||
"@types/storybook__react": "^4.0.2", | ||
"@typescript-eslint/eslint-plugin": "^2.14.0", | ||
"@typescript-eslint/parser": "^2.14.0", | ||
"@storybook/addon-actions": "^5.3.17", | ||
"@storybook/addon-docs": "^5.3.17", | ||
"@storybook/addon-knobs": "^5.3.17", | ||
"@storybook/addon-links": "^5.3.17", | ||
"@storybook/addon-storysource": "^5.3.17", | ||
"@storybook/addon-viewport": "^5.3.17", | ||
"@storybook/addons": "^5.3.17", | ||
"@storybook/preset-typescript": "1.2.2", | ||
"@storybook/react": "^5.3.17", | ||
"@storybook/theming": "^5.3.17", | ||
"@testing-library/react": "^10.0.1", | ||
"@types/jest": "^25.1.4", | ||
"@types/node": "^12.12.26", | ||
"@types/react": "^16.9.23", | ||
"@types/react-dom": "^16.9.5", | ||
"@typescript-eslint/eslint-plugin": "^2.23.0", | ||
"@typescript-eslint/parser": "^2.23.0", | ||
"babel-loader": "^8.0.6", | ||
"eslint": "^6.8.0", | ||
"eslint-plugin-jest": "^23.2.0", | ||
"eslint-plugin-react": "^7.17.0", | ||
"eslint-plugin-react-hooks": "^2.3.0", | ||
"husky": "^3.1.0", | ||
"lint-staged": "^9.5.0", | ||
"np": "^5.2.1", | ||
"eslint-plugin-jest": "^23.8.2", | ||
"eslint-plugin-react": "^7.19.0", | ||
"eslint-plugin-react-hooks": "^2.5.0", | ||
"husky": "^4.2.3", | ||
"lint-staged": "^10.0.8", | ||
"np": "^6.2.0", | ||
"prettier": "^1.19.1", | ||
"pretty-quick": "^2.0.1", | ||
"react": "^16.12.0", | ||
"react-docgen-typescript-loader": "^3.6.0", | ||
"react-dom": "^16.12.0", | ||
"react": "^16.13.0", | ||
"react-docgen-typescript-loader": "^3.7.1", | ||
"react-dom": "^16.13.0", | ||
"ts-loader": "^6.2.1", | ||
"tsdx": "^0.12.1", | ||
"tslib": "^1.10.0", | ||
"typescript": "^3.7.4" | ||
"tsdx": "^0.12.3", | ||
"tslib": "^1.11.1", | ||
"typescript": "^3.8.3" | ||
}, | ||
@@ -113,0 +114,0 @@ "dependencies": { |
@@ -6,14 +6,18 @@ <div align="center"> | ||
<a href="https://github.com/nerdyman/react-compare-slider/blob/master/LICENSE"> | ||
<img src="https://img.shields.io/npm/l/react-compare-slider.svg" alt="License MIT"> | ||
<img src="https://img.shields.io/npm/l/react-compare-slider.svg" alt="License MIT" /> | ||
</a> | ||
<a href="https://npmjs.com/package/react-compare-slider"> | ||
<img src="https://img.shields.io/npm/v/react-compare-slider.svg" alt="NPM package"> | ||
<img src="https://img.shields.io/npm/v/react-compare-slider.svg" alt="NPM package" /> | ||
</a> | ||
<a href="https://bundlephobia.com/result?p=react-compare-slider"> | ||
<img src="https://img.shields.io/bundlephobia/minzip/react-compare-slider.svg" alt="Bundle size"> | ||
<img src="https://img.shields.io/bundlephobia/minzip/react-compare-slider.svg" alt="Bundle size" /> | ||
</a> | ||
<br/> | ||
<a href="https://github.com/nerdyman/react-compare-slider/actions?query=workflow%3Abuild"> | ||
<img src="https://github.com/nerdyman/react-compare-slider/workflows/build/badge.svg" alt="Build Status"> | ||
<img src="https://img.shields.io/github/workflow/status/nerdyman/react-compare-slider/build" alt="Build Status" /> | ||
</a> | ||
<a href="https://festive-darwin-fab443.netlify.com/"> | ||
<a href="https://codeclimate.com/github/nerdyman/react-compare-slider"> | ||
<img src="https://img.shields.io/codeclimate/coverage/nerdyman/react-compare-slider" alt="Coverage" /> | ||
</a> | ||
<a href="https://react-compare-slider.netlify.app/"> | ||
<img src="https://img.shields.io/badge/demos-🚀-blue.svg" alt="Demos" /> | ||
@@ -38,4 +42,6 @@ </a> | ||
See Storybook for [documentation](https://festive-darwin-fab443.netlify.com/?path=/docs/docs-intro--page) and [demos](https://festive-darwin-fab443.netlify.com/?path=/docs/demos-images--default). | ||
See Storybook for [documentation](https://react-compare-slider.netlify.app/?path=/docs/docs-intro--page) and [demos](https://react-compare-slider.netlify.app/?path=/docs/demos-images--default). | ||
Also see the local [example](./example) folder for standalone demos. | ||
## Usage | ||
@@ -60,10 +66,13 @@ | ||
<ReactCompareSlider | ||
itemOne={<ReactCompareSliderImage src="..." srcSet="..." alt="Image one" />} | ||
itemTwo={<ReactCompareSliderImage src="..." srcSet="..." alt="Image two" />} | ||
itemOne={<ReactCompareSliderImage src="..." srcSet="..." alt="Image one" />} | ||
itemTwo={<ReactCompareSliderImage src="..." srcSet="..." alt="Image two" />} | ||
/> | ||
``` | ||
See the [Image Playground](https://react-compare-slider.netlify.app/?path=/docs/demos-images--playground) | ||
to experiment with images using the "Knobs" tab. | ||
### Advanced Usage | ||
See the [docs](https://festive-darwin-fab443.netlify.com/?path=/docs/docs-intro--page) for advanced examples. | ||
See the [docs](https://react-compare-slider.netlify.app/?path=/docs/docs-intro--page) for advanced examples. | ||
@@ -81,56 +90,18 @@ ## Props | ||
See the [API docs](https://festive-darwin-fab443.netlify.com/?path=/docs/docs-api--page) for detailed information. | ||
See the [API docs](https://react-compare-slider.netlify.app/?path=/docs/docs-api--page) for more information. | ||
## Extending | ||
### `ReactCompareSliderImage` | ||
### Custom Components | ||
`ReactCompareSliderImage` is a standalone image component that detects whether the browser supports the `object-fit` CSS property, if not it will apply a background image to achieve the same effect. It will set `background-size`, `background-position` and `background-image` if they have not already been defined in a passed `style` prop. | ||
Custom components can apply the same base styles as `ReactCompareSliderImage` | ||
by using the `styleFitContainer` CSS utility. | ||
#### `ReactCompareSliderImage` Props | ||
See the [styleFitContainer docs](https://react-compare-slider.netlify.app/?path=/docs/docs-api--page#stylefitcontainer) | ||
for more information. | ||
`ReactCompareSliderImage` supports all attributes assignable to an `img` component, in addition to the following: | ||
### Images | ||
| Prop | Type | Required | Default value | Description | | ||
|------|------|:--------:|---------------|-------------| | ||
| `fallbackEnable` | `boolean` | | `true` | Whether to enable fallback background | | ||
See the [Images docs](https://react-compare-slider.netlify.app/?path=/docs/docs-images--page) for more information. | ||
#### Example | ||
Standalone: | ||
```jsx | ||
import { ReactCompareSliderImage } from 'react-compare-slider'; | ||
// `src` will be used as background image on unsupported browsers | ||
<ReactCompareSliderImage src="..." /> | ||
// `backgroundImage` will be used as background image on unsupported browsers | ||
<ReactCompareSliderImage src="..." style={{ backgroundImage: 'url(...)' }} /> | ||
``` | ||
### `styleFitContainer` | ||
The `styleFitContainer` utility makes any child media component (`img`, `picture`, `video`, etc.) fill its parent and maintain the correct aspect ratio. It returns a React `style` object and accepts a | ||
CSS object as an argument and defaults to `object-fit` to `cover`. | ||
#### Example | ||
Fill a full width/height container: | ||
```jsx | ||
import { styleFitContainer } from 'react-compare-slider'; | ||
<div style={{ width: '100vw', height: '100vh' }}> | ||
<video | ||
style={{ | ||
...styleFitContainer({ | ||
objectFit: 'contain', | ||
objectPosition: 'center', | ||
}) | ||
}} | ||
/> | ||
</div> | ||
``` | ||
## Requirements | ||
@@ -137,0 +108,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
126996
34
934
0
2
110