react-compare-slider
Advanced tools
Comparing version 1.2.1 to 2.0.1
@@ -1,3 +0,7 @@ | ||
export { ReactCompareSlider, ReactCompareSliderProps, ReactCompareSliderHandle, ReactCompareSliderHandleProps, } from './react-compare-slider'; | ||
export { ReactCompareSliderImage, ReactCompareSliderImageProps, } from './react-compare-slider-image'; | ||
export { styleFitContainer, supportsCssObjectFit } from './utils'; | ||
export { ReactCompareSlider } from './ReactCompareSlider'; | ||
export type { ReactCompareSliderProps } from './ReactCompareSlider'; | ||
export { ReactCompareSliderHandle } from './ReactCompareSliderHandle'; | ||
export type { ReactCompareSliderHandleProps } from './ReactCompareSliderHandle'; | ||
export { ReactCompareSliderImage } from './ReactCompareSliderImage'; | ||
export type { ReactCompareSliderImageProps } from './ReactCompareSliderImage'; | ||
export { styleFitContainer } from './utils'; |
@@ -9,77 +9,107 @@ 'use strict'; | ||
var React__default = _interopDefault(React); | ||
var resizeObserver = require('resize-observer'); | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
const ThisArrow = ({ | ||
flip | ||
}) => { | ||
const style = { | ||
width: 0, | ||
height: 0, | ||
borderTop: '8px solid transparent', | ||
borderRight: '10px solid', | ||
borderBottom: '8px solid transparent', | ||
transform: flip ? 'rotate(180deg)' : undefined | ||
}; | ||
return React__default.createElement("div", { | ||
style: style | ||
}); | ||
}; | ||
/** Default `handle`. */ | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
const ReactCompareSliderHandle = ({ | ||
portrait, | ||
buttonStyle, | ||
linesStyle, | ||
style, | ||
...props | ||
}) => { | ||
const _style = { | ||
display: 'flex', | ||
flexDirection: portrait ? 'row' : 'column', | ||
placeItems: 'center', | ||
height: '100%', | ||
cursor: portrait ? 'ns-resize' : 'ew-resize', | ||
pointerEvents: 'none', | ||
color: '#fff', | ||
...style | ||
}; | ||
const _linesStyle = { | ||
flexGrow: 1, | ||
height: portrait ? 2 : '100%', | ||
width: portrait ? '100%' : 2, | ||
backgroundColor: 'currentColor', | ||
pointerEvents: 'auto', | ||
boxShadow: '0 0 7px rgba(0,0,0,.35)', | ||
...linesStyle | ||
}; | ||
const _buttonStyle = { | ||
display: 'grid', | ||
gridAutoFlow: 'column', | ||
gap: 8, | ||
placeContent: 'center', | ||
flexShrink: 0, | ||
width: 56, | ||
height: 56, | ||
borderRadius: '50%', | ||
borderStyle: 'solid', | ||
borderWidth: 2, | ||
pointerEvents: 'auto', | ||
backdropFilter: 'blur(7px)', | ||
boxShadow: '0 0 7px rgba(0,0,0,.35)', | ||
transform: portrait ? 'rotate(90deg)' : undefined, | ||
...buttonStyle | ||
}; | ||
return React__default.createElement("div", Object.assign({ | ||
className: "__rcs-handle-root" | ||
}, props, { | ||
style: _style | ||
}), React__default.createElement("div", { | ||
className: "__rcs-handle-line", | ||
style: _linesStyle | ||
}), React__default.createElement("div", { | ||
className: "__rcs-handle-button", | ||
style: _buttonStyle | ||
}, React__default.createElement(ThisArrow, null), React__default.createElement(ThisArrow, { | ||
flip: true | ||
})), React__default.createElement("div", { | ||
className: "__rcs-handle-line", | ||
style: _linesStyle | ||
})); | ||
}; | ||
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; | ||
} | ||
/** Whether runtime is client-side. */ | ||
var isClient = !!(typeof window !== 'undefined' && window.document && window.document.createElement); | ||
/** | ||
* Whether client supports the CSS `object-fit` property. | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) fit their | ||
* container. | ||
*/ | ||
var supportsCssObjectFit = function supportsCssObjectFit() { | ||
// Assume object-fit is supported in SSR - it will be picked up again by the | ||
// client anyway. | ||
if (!isClient) return true; | ||
return typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('object-fit', 'cover'); | ||
}; | ||
/** | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) | ||
* fit their container and maintain their aspect ratio. | ||
*/ | ||
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"]); | ||
return _extends({ | ||
display: 'block', | ||
width: '100%', | ||
height: '100%', | ||
maxWidth: '100%', | ||
objectFit: objectFit, | ||
objectPosition: objectPosition | ||
}, props); | ||
}; | ||
const styleFitContainer = ({ | ||
boxSizing = 'border-box', | ||
objectFit = 'cover', | ||
objectPosition = 'center', | ||
...props | ||
} = {}) => ({ | ||
display: 'block', | ||
width: '100%', | ||
height: '100%', | ||
maxWidth: '100%', | ||
boxSizing, | ||
objectFit, | ||
objectPosition, | ||
...props | ||
}); | ||
/** Store the previous supplied value. */ | ||
var usePrevious = function usePrevious(value) { | ||
var ref = React.useRef(value); | ||
React.useEffect(function () { | ||
const usePrevious = value => { | ||
const ref = React.useRef(value); | ||
React.useEffect(() => { | ||
ref.current = value; | ||
@@ -91,42 +121,31 @@ }); | ||
* Event listener binding hook. | ||
* @param eventName - Event to bind to | ||
* @param handler - Callback handler | ||
* @param element - Element to bind to | ||
* @param handlerOptions - Event handler options | ||
* @param eventName - Event to bind to. | ||
* @param handler - Callback handler. | ||
* @param element - Element to bind to. | ||
* @param handlerOptions - Event handler options. | ||
*/ | ||
var useEventListener = function useEventListener(eventName, handler, element, handlerOptions) { | ||
// Create a ref that stores handler | ||
var savedHandler = React.useRef(); // Update ref.current value if handler changes. | ||
// This allows our effect below to always get latest handler ... | ||
// ... without us needing to pass it in effect deps array ... | ||
// ... and potentially cause effect to re-run every render. | ||
React.useEffect(function () { | ||
const useEventListener = (eventName, handler, element, handlerOptions) => { | ||
const savedHandler = React.useRef(); | ||
React.useEffect(() => { | ||
savedHandler.current = handler; | ||
}, [handler]); | ||
React.useEffect(function () { | ||
// Make sure element supports addEventListener | ||
var isSupported = element && element.addEventListener; | ||
if (!isSupported) return; // Create event listener that calls handler function stored in ref | ||
React.useEffect(() => { | ||
// Make sure element supports addEventListener. | ||
if (!(element && element.addEventListener)) return; // Create event listener that calls handler function stored in ref. | ||
var eventListener = function eventListener(event) { | ||
return savedHandler.current && savedHandler.current(event); | ||
}; // Add event listener | ||
const eventListener = event => savedHandler.current && savedHandler.current(event); | ||
element.addEventListener(eventName, eventListener, handlerOptions); // Remove event listener on cleanup | ||
return function () { | ||
element.addEventListener(eventName, eventListener, handlerOptions); | ||
return () => { | ||
element.removeEventListener(eventName, eventListener, handlerOptions); | ||
}; | ||
}, [eventName, element, handlerOptions] // Re-run if eventName or element changes | ||
); | ||
}, [eventName, element, handlerOptions]); | ||
}; | ||
/** | ||
* Conditionally use `useLayoutEffect` for client *or* `useEffect` for SSR. | ||
* @see https://github.com/reduxjs/react-redux/blob/c581d480dd675f2645851fb006bef91aeb6ac24d/src/utils/useIsomorphicLayoutEffect.js | ||
* @see <https://github.com/reduxjs/react-redux/blob/c581d480dd675f2645851fb006bef91aeb6ac24d/src/utils/useIsomorphicLayoutEffect.js> | ||
*/ | ||
var useIsomorphicLayoutEffect = isClient ? React.useLayoutEffect : React.useEffect; | ||
const useIsomorphicLayoutEffect = typeof window !== 'undefined' && window.document && window.document.createElement ? React.useLayoutEffect : React.useEffect; | ||
/** | ||
@@ -138,29 +157,44 @@ * Bind resize observer callback to element. | ||
var useResizeObserver = function useResizeObserver(ref, handler) { | ||
var observer = React.useRef(new resizeObserver.ResizeObserver(function (_ref2) { | ||
var entry = _ref2[0]; | ||
return handler(entry.contentRect); | ||
})); | ||
var observe = React.useCallback(function () { | ||
const useResizeObserver = (ref, handler) => { | ||
const observer = React.useRef(new ResizeObserver(([entry]) => handler(entry.contentRect))); | ||
const observe = React.useCallback(() => { | ||
ref.current && observer.current.observe(ref.current); | ||
}, [ref]); // Bind/rebind observer when `handler` changes. | ||
useIsomorphicLayoutEffect(function () { | ||
observer.current = new resizeObserver.ResizeObserver(function (_ref3) { | ||
var entry = _ref3[0]; | ||
return handler(entry.contentRect); | ||
}); | ||
useIsomorphicLayoutEffect(() => { | ||
observer.current = new ResizeObserver(([entry]) => handler(entry.contentRect)); | ||
observe(); | ||
return function () { | ||
return observer.current.disconnect(); | ||
}; | ||
return () => observer.current.disconnect(); | ||
}, [handler, observe]); | ||
}; | ||
/** Container for clipped item. */ | ||
const ThisClipContainer = /*#__PURE__*/React.forwardRef((props, ref) => { | ||
const style = { | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
willChange: 'clip', | ||
userSelect: 'none', | ||
KhtmlUserSelect: 'none', | ||
MozUserSelect: 'none', | ||
WebkitUserSelect: 'none' | ||
}; | ||
return React__default.createElement("div", Object.assign({}, props, { | ||
style: style, | ||
"data-rcs": "clip-item", | ||
ref: ref | ||
})); | ||
}); | ||
ThisClipContainer.displayName = 'ThisClipContainer'; | ||
/** Handle container to control position. */ | ||
var ReactCompareSliderHandleContainer = /*#__PURE__*/React.forwardRef(function (_ref, ref) { | ||
var children = _ref.children, | ||
portrait = _ref.portrait; | ||
var style = { | ||
const ThisHandleContainer = /*#__PURE__*/React.forwardRef(({ | ||
children, | ||
portrait | ||
}, ref) => { | ||
const style = { | ||
position: 'absolute', | ||
@@ -172,3 +206,3 @@ top: 0, | ||
}; | ||
var innerStyle = { | ||
const innerStyle = { | ||
position: 'absolute', | ||
@@ -188,94 +222,49 @@ width: portrait ? '100%' : undefined, | ||
}); | ||
ReactCompareSliderHandleContainer.displayName = 'ReactCompareSliderHandleContainer'; | ||
/** Overridable handle. */ | ||
var ReactCompareSliderHandle = function ReactCompareSliderHandle(_ref2) { | ||
var portrait = _ref2.portrait, | ||
style = _ref2.style, | ||
props = _objectWithoutPropertiesLoose(_ref2, ["portrait", "style"]); | ||
var rootStyle = _extends({ | ||
height: portrait ? 4 : '100%', | ||
width: portrait ? '100%' : 4, | ||
backgroundColor: '#fff', | ||
boxShadow: '0 0 .2rem #000', | ||
cursor: portrait ? 'ns-resize' : 'ew-resize' | ||
}, style); | ||
return React__default.createElement("div", Object.assign({}, props, { | ||
style: rootStyle, | ||
"data-rcs": "handle-inner" | ||
})); | ||
ThisHandleContainer.displayName = 'ThisHandleContainer'; | ||
const EVENT_PASSIVE_PARAMS = { | ||
passive: true | ||
}; | ||
/** Container for items passed to main component. */ | ||
var ReactCompareSliderClipContainer = /*#__PURE__*/React.forwardRef(function (props, ref) { | ||
var style = { | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
willChange: 'clip', | ||
userSelect: 'none', | ||
KhtmlUserSelect: 'none', | ||
MozUserSelect: 'none', | ||
WebkitUserSelect: 'none' | ||
}; | ||
return React__default.createElement("div", Object.assign({}, props, { | ||
style: style, | ||
"data-rcs": "clip-item", | ||
ref: ref | ||
})); | ||
}); | ||
ReactCompareSliderClipContainer.displayName = 'ReactCompareSliderClipContainer'; | ||
const EVENT_CAPTURE_PARAMS = { | ||
capture: true, | ||
passive: false | ||
}; | ||
/** Root Comparison slider. */ | ||
var ReactCompareSlider = function ReactCompareSlider(_ref3) { | ||
var handle = _ref3.handle, | ||
itemOne = _ref3.itemOne, | ||
itemTwo = _ref3.itemTwo, | ||
_ref3$onlyHandleDragg = _ref3.onlyHandleDraggable, | ||
onlyHandleDraggable = _ref3$onlyHandleDragg === void 0 ? false : _ref3$onlyHandleDragg, | ||
onPositionChange = _ref3.onPositionChange, | ||
_ref3$portrait = _ref3.portrait, | ||
portrait = _ref3$portrait === void 0 ? false : _ref3$portrait, | ||
_ref3$position = _ref3.position, | ||
position = _ref3$position === void 0 ? 50 : _ref3$position, | ||
_ref3$boundsPadding = _ref3.boundsPadding, | ||
boundsPadding = _ref3$boundsPadding === void 0 ? 0 : _ref3$boundsPadding, | ||
style = _ref3.style, | ||
props = _objectWithoutPropertiesLoose(_ref3, ["handle", "itemOne", "itemTwo", "onlyHandleDraggable", "onPositionChange", "portrait", "position", "boundsPadding", "style"]); | ||
const ReactCompareSlider = ({ | ||
handle, | ||
itemOne, | ||
itemTwo, | ||
onlyHandleDraggable = false, | ||
onPositionChange, | ||
portrait = false, | ||
position = 50, | ||
boundsPadding = 0, | ||
style, | ||
...props | ||
}) => { | ||
/** Reference to root container. */ | ||
var rootContainerRef = React.useRef(null); | ||
const rootContainerRef = React.useRef(null); | ||
/** Reference to clip container. */ | ||
var clipContainerRef = React.useRef(null); | ||
const clipContainerRef = React.useRef(null); | ||
/** Reference to handle container. */ | ||
var handleContainerRef = React.useRef(null); | ||
const handleContainerRef = React.useRef(null); | ||
/** Reference to current position as a percentage value. */ | ||
var internalPositionPc = React.useRef(position); | ||
const internalPositionPc = React.useRef(position); | ||
/** Previous `position` prop value. */ | ||
var prevPropPosition = usePrevious(position); | ||
const prevPropPosition = usePrevious(position); | ||
/** Whether user is currently dragging. */ | ||
var _useState = React.useState(false), | ||
isDragging = _useState[0], | ||
setIsDragging = _useState[1]; | ||
const [isDragging, setIsDragging] = React.useState(false); | ||
/** Whether component has a `window` event binding. */ | ||
var hasWindowBinding = React.useRef(false); | ||
const hasWindowBinding = React.useRef(false); | ||
/** Target container for pointer events. */ | ||
var _useState2 = React.useState(), | ||
interactiveTarget = _useState2[0], | ||
setInteractiveTarget = _useState2[1]; // Set target container for pointer events. | ||
const [interactiveTarget, setInteractiveTarget] = React.useState(); // Set target container for pointer events. | ||
React.useEffect(function () { | ||
React.useEffect(() => { | ||
setInteractiveTarget(onlyHandleDraggable ? handleContainerRef.current : rootContainerRef.current); | ||
@@ -285,17 +274,17 @@ }, [onlyHandleDraggable]); | ||
var updateInternalPosition = React.useCallback(function updateInternalCall(_ref4) { | ||
var x = _ref4.x, | ||
y = _ref4.y, | ||
isOffset = _ref4.isOffset, | ||
_portrait = _ref4.portrait, | ||
_boundsPadding = _ref4.boundsPadding; | ||
var _rootContainerRef$cur = rootContainerRef.current.getBoundingClientRect(), | ||
top = _rootContainerRef$cur.top, | ||
left = _rootContainerRef$cur.left, | ||
width = _rootContainerRef$cur.width, | ||
height = _rootContainerRef$cur.height; // Early out if width or height are zero, can't calculate values | ||
const updateInternalPosition = React.useCallback(function updateInternalCall({ | ||
x, | ||
y, | ||
isOffset, | ||
portrait: _portrait, | ||
boundsPadding: _boundsPadding | ||
}) { | ||
const { | ||
top, | ||
left, | ||
width, | ||
height | ||
} = rootContainerRef.current.getBoundingClientRect(); // Early out if width or height are zero, can't calculate values | ||
// from zeros. | ||
if (width === 0 || height === 0) return; // Clamp pixel position to always be within the container's bounds. | ||
@@ -305,13 +294,17 @@ // This does *not* take `boundsPadding` into account because we need | ||
var positionPx = Math.min(Math.max( // Determine bounds based on orientation | ||
const positionPx = Math.min(Math.max( // Determine bounds based on orientation | ||
_portrait ? isOffset ? y - top - window.pageYOffset : y : isOffset ? x - left - window.pageXOffset : x, // Min value | ||
0), // Max value | ||
_portrait ? height : width); // Calculate internal position percentage *without* bounds - we always | ||
// want to return 0-100 of the *slideable* bounds. | ||
_portrait ? height : width); | ||
/** | ||
* Internal position percentage *without* bounds. | ||
* @NOTE This uses the entire container bounds **without** `boundsPadding` | ||
* to get the *real* bounds. | ||
*/ | ||
var nextInternalPositionPc = positionPx / (_portrait ? height : width) * 100; | ||
const nextInternalPositionPc = positionPx / (_portrait ? height : width) * 100; | ||
/** Determine if the current pixel position meets the min/max bounds. */ | ||
var positionMeetsBounds = _portrait ? positionPx === 0 || positionPx === height : positionPx === 0 || positionPx === width; | ||
var canSkipPositionPc = nextInternalPositionPc === internalPositionPc.current && (internalPositionPc.current === 0 || internalPositionPc.current === 100); // Early out if pixel and percentage positions are already at the min/max | ||
const positionMeetsBounds = _portrait ? positionPx === 0 || positionPx === height : positionPx === 0 || positionPx === width; | ||
const canSkipPositionPc = nextInternalPositionPc === internalPositionPc.current && (internalPositionPc.current === 0 || internalPositionPc.current === 100); // Early out if pixel and percentage positions are already at the min/max | ||
// to prevent update spamming when the user is sliding outside of the | ||
@@ -328,23 +321,23 @@ // container. | ||
var clampedPx = Math.min( // Get largest from pixel position *or* bounds padding. | ||
const clampedPx = Math.min( // Get largest from pixel position *or* bounds padding. | ||
Math.max(positionPx, 0 + _boundsPadding), // Use height *or* width based on orientation. | ||
(_portrait ? height : width) - _boundsPadding); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
clipContainerRef.current.style.clip = _portrait ? "rect(auto,auto," + clampedPx + "px,auto)" : "rect(auto," + clampedPx + "px,auto,auto)"; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
clipContainerRef.current.style.clip = _portrait ? `rect(auto,auto,${clampedPx}px,auto)` : `rect(auto,${clampedPx}px,auto,auto)`; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
handleContainerRef.current.style.transform = _portrait ? "translate3d(0," + clampedPx + "px,0)" : "translate3d(" + clampedPx + "px,0,0)"; | ||
handleContainerRef.current.style.transform = _portrait ? `translate3d(0,${clampedPx}px,0)` : `translate3d(${clampedPx}px,0,0)`; | ||
if (onPositionChange) onPositionChange(internalPositionPc.current); | ||
}, [onPositionChange]); // Update internal position if `position` prop changes. | ||
}, [onPositionChange]); // Update internal position when other user controllable props change. | ||
React.useEffect(function () { | ||
React.useEffect(() => { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
var _rootContainerRef$cur2 = rootContainerRef.current.getBoundingClientRect(), | ||
width = _rootContainerRef$cur2.width, | ||
height = _rootContainerRef$cur2.height; // Use current internal position if `position` hasn't changed. | ||
const { | ||
width, | ||
height | ||
} = rootContainerRef.current.getBoundingClientRect(); // Use current internal position if `position` hasn't changed. | ||
var nextPosition = position === prevPropPosition ? internalPositionPc.current : position; | ||
const nextPosition = position === prevPropPosition ? internalPositionPc.current : position; | ||
updateInternalPosition({ | ||
portrait: portrait, | ||
boundsPadding: boundsPadding, | ||
portrait, | ||
boundsPadding, | ||
x: width / 100 * nextPosition, | ||
@@ -356,7 +349,7 @@ y: height / 100 * nextPosition | ||
var handlePointerDown = React.useCallback(function (ev) { | ||
const handlePointerDown = React.useCallback(ev => { | ||
ev.preventDefault(); | ||
updateInternalPosition({ | ||
portrait: portrait, | ||
boundsPadding: boundsPadding, | ||
portrait, | ||
boundsPadding, | ||
isOffset: true, | ||
@@ -370,7 +363,6 @@ x: ev instanceof MouseEvent ? ev.pageX : ev.touches[0].pageX, | ||
var handlePointerMove = React.useCallback(function moveCall(ev) { | ||
if (!isDragging) return; | ||
const handlePointerMove = React.useCallback(function moveCall(ev) { | ||
updateInternalPosition({ | ||
portrait: portrait, | ||
boundsPadding: boundsPadding, | ||
portrait, | ||
boundsPadding, | ||
isOffset: true, | ||
@@ -380,6 +372,6 @@ x: ev instanceof MouseEvent ? ev.pageX : ev.touches[0].pageX, | ||
}); | ||
}, [portrait, isDragging, boundsPadding, updateInternalPosition]); | ||
}, [portrait, boundsPadding, updateInternalPosition]); | ||
/** Handle mouse/touch up. */ | ||
var handlePointerUp = React.useCallback(function () { | ||
const handlePointerUp = React.useCallback(() => { | ||
setIsDragging(false); | ||
@@ -389,8 +381,9 @@ }, []); | ||
var handleResize = React.useCallback(function (_ref5) { | ||
var width = _ref5.width, | ||
height = _ref5.height; | ||
const handleResize = React.useCallback(({ | ||
width, | ||
height | ||
}) => { | ||
updateInternalPosition({ | ||
portrait: portrait, | ||
boundsPadding: boundsPadding, | ||
portrait, | ||
boundsPadding, | ||
x: width / 100 * internalPositionPc.current, | ||
@@ -401,20 +394,12 @@ y: height / 100 * internalPositionPc.current | ||
React.useEffect(function () { | ||
React.useEffect(() => { | ||
if (isDragging && !hasWindowBinding.current) { | ||
window.addEventListener('mousemove', handlePointerMove, { | ||
passive: true | ||
}); | ||
window.addEventListener('mouseup', handlePointerUp, { | ||
passive: true | ||
}); | ||
window.addEventListener('touchmove', handlePointerMove, { | ||
passive: true | ||
}); | ||
window.addEventListener('touchend', handlePointerUp, { | ||
passive: true | ||
}); | ||
window.addEventListener('mousemove', handlePointerMove, EVENT_PASSIVE_PARAMS); | ||
window.addEventListener('mouseup', handlePointerUp, EVENT_PASSIVE_PARAMS); | ||
window.addEventListener('touchmove', handlePointerMove, EVENT_PASSIVE_PARAMS); | ||
window.addEventListener('touchend', handlePointerUp, EVENT_PASSIVE_PARAMS); | ||
hasWindowBinding.current = true; | ||
} | ||
return function () { | ||
return () => { | ||
if (hasWindowBinding.current) { | ||
@@ -430,19 +415,12 @@ window.removeEventListener('mousemove', handlePointerMove); | ||
useResizeObserver(rootContainerRef, handleResize); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
useResizeObserver(rootContainerRef, handleResize); | ||
useEventListener('mousedown', handlePointerDown, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
interactiveTarget, EVENT_CAPTURE_PARAMS); | ||
useEventListener('touchstart', handlePointerDown, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
interactiveTarget, EVENT_CAPTURE_PARAMS); // Use custom handle if requested. | ||
useEventListener('mousedown', handlePointerDown, interactiveTarget, { | ||
capture: true, | ||
passive: false | ||
}); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
useEventListener('touchstart', handlePointerDown, interactiveTarget, { | ||
capture: true, | ||
passive: false | ||
}); // Use custom handle if requested. | ||
var Handle = handle || React__default.createElement(ReactCompareSliderHandle, { | ||
const Handle = handle || React__default.createElement(ReactCompareSliderHandle, { | ||
portrait: portrait | ||
}); | ||
var rootStyle = _extends({ | ||
const rootStyle = { | ||
position: 'relative', | ||
@@ -455,5 +433,5 @@ overflow: 'hidden', | ||
MozUserSelect: 'none', | ||
WebkitUserSelect: 'none' | ||
}, style); | ||
WebkitUserSelect: 'none', | ||
...style | ||
}; | ||
return React__default.createElement("div", Object.assign({}, props, { | ||
@@ -463,5 +441,5 @@ ref: rootContainerRef, | ||
"data-rcs": "root" | ||
}), itemTwo, React__default.createElement(ReactCompareSliderClipContainer, { | ||
}), itemTwo, React__default.createElement(ThisClipContainer, { | ||
ref: clipContainerRef | ||
}, itemOne), React__default.createElement(ReactCompareSliderHandleContainer, { | ||
}, itemOne), React__default.createElement(ThisHandleContainer, { | ||
portrait: portrait, | ||
@@ -472,40 +450,13 @@ ref: handleContainerRef | ||
/** | ||
* Image with fallback background for browsers that don't support the | ||
* `object-fit` CSS property. | ||
*/ | ||
/** Image with defaults from `styleFitContainer` applied. */ | ||
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"]); | ||
/** Runtime support for `object-fit`. Ref based to allow updates after SSR. */ | ||
var objectFitIsSupported = React.useRef(supportsCssObjectFit()); | ||
var innerStyle = styleFitContainer(_extends({}, style)); | ||
var containerStyle = { | ||
width: innerStyle.width, | ||
height: innerStyle.height, | ||
boxSizing: 'border-box' | ||
}; // Add fallback background props if requested | ||
if (!objectFitIsSupported.current && fallbackEnable) { | ||
// Set fallback CSS properties, use props from `innerStyle` if defined | ||
containerStyle.backgroundImage = innerStyle.backgroundImage || "url(" + props.src + ")"; | ||
containerStyle.backgroundSize = innerStyle.backgroundSize || 'cover'; | ||
containerStyle.backgroundPosition = innerStyle.backgroundPosition || 'center'; // Hide inner image | ||
innerStyle.opacity = 0; | ||
} | ||
return React__default.createElement("div", { | ||
className: className, | ||
style: containerStyle, | ||
"data-rcs": "image-root" | ||
}, React__default.createElement("img", Object.assign({}, props, { | ||
style: innerStyle, | ||
"data-rcs": "image-inner" | ||
}))); | ||
const ReactCompareSliderImage = ({ | ||
style, | ||
...props | ||
}) => { | ||
const rootStyle = styleFitContainer(style); | ||
return React__default.createElement("img", Object.assign({}, props, { | ||
style: rootStyle, | ||
"data-rcs": "image" | ||
})); | ||
}; | ||
@@ -517,3 +468,2 @@ | ||
exports.styleFitContainer = styleFitContainer; | ||
exports.supportsCssObjectFit = supportsCssObjectFit; | ||
//# sourceMappingURL=react-compare-slider.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"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=!("undefined"==typeof window||!window.document||!window.document.createElement),s=function(){return!a||"undefined"!=typeof CSS&&"function"==typeof CSS.supports&&CSS.supports("object-fit","cover")},c=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"]))},u=function(e,n,r,o){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])},d=a?t.useLayoutEffect:t.useEffect,l=t.forwardRef((function(e,t){var r=e.portrait;return n.createElement("div",{style:{position:"absolute",top:0,width:"100%",height:"100%",pointerEvents:"none"},"data-rcs":"handle-container",ref:t},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))}));l.displayName="ReactCompareSliderHandleContainer";var f=function(e){var t=e.portrait,r=e.style,a=i(e,["portrait","style"]),s=o({height:t?4:"100%",width:t?"100%":4,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":"handle-inner"}))},p=t.forwardRef((function(e,t){return n.createElement("div",Object.assign({},e,{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",willChange:"clip",userSelect:"none",KhtmlUserSelect:"none",MozUserSelect:"none",WebkitUserSelect:"none"},"data-rcs":"clip-item",ref:t}))}));p.displayName="ReactCompareSliderClipContainer",exports.ReactCompareSlider=function(e){var a,s,c=e.handle,v=e.itemOne,h=e.itemTwo,g=e.onlyHandleDraggable,m=void 0!==g&&g,b=e.onPositionChange,w=e.portrait,E=void 0!==w&&w,y=e.position,S=void 0===y?50:y,C=e.boundsPadding,x=void 0===C?0:C,R=e.style,O=i(e,["handle","itemOne","itemTwo","onlyHandleDraggable","onPositionChange","portrait","position","boundsPadding","style"]),k=t.useRef(null),j=t.useRef(null),P=t.useRef(null),z=t.useRef(S),L=(s=t.useRef(a=S),t.useEffect((function(){s.current=a})),s.current),M=t.useState(!1),U=M[0],X=M[1],Y=t.useRef(!1),F=t.useState(),N=F[0],H=F[1];t.useEffect((function(){H(m?P.current:k.current)}),[m]);var D=t.useCallback((function(e){var t=e.x,n=e.y,r=e.isOffset,o=e.portrait,i=e.boundsPadding,a=k.current.getBoundingClientRect(),s=a.width,c=a.height;if(0!==s&&0!==c){var u=Math.min(Math.max(o?r?n-a.top-window.pageYOffset:n:r?t-a.left-window.pageXOffset:t,0),o?c:s),d=u/(o?c:s)*100;if(d!==z.current||0!==z.current&&100!==z.current||!(o?0===u||u===c:0===u||u===s)){z.current=d;var l=Math.min(Math.max(u,0+i),(o?c:s)-i);j.current.style.clip=o?"rect(auto,auto,"+l+"px,auto)":"rect(auto,"+l+"px,auto,auto)",P.current.style.transform=o?"translate3d(0,"+l+"px,0)":"translate3d("+l+"px,0,0)",b&&b(z.current)}}}),[b]);t.useEffect((function(){var e=k.current.getBoundingClientRect(),t=S===L?z.current:S;D({portrait:E,boundsPadding:x,x:e.width/100*t,y:e.height/100*t})}),[E,S,L,x,D]);var I=t.useCallback((function(e){e.preventDefault(),D({portrait:E,boundsPadding:x,isOffset:!0,x:e instanceof MouseEvent?e.pageX:e.touches[0].pageX,y:e instanceof MouseEvent?e.pageY:e.touches[0].pageY}),X(!0)}),[E,x,D]),W=t.useCallback((function(e){U&&D({portrait:E,boundsPadding:x,isOffset:!0,x:e instanceof MouseEvent?e.pageX:e.touches[0].pageX,y:e instanceof MouseEvent?e.pageY:e.touches[0].pageY})}),[E,U,x,D]),q=t.useCallback((function(){X(!1)}),[]),B=t.useCallback((function(e){D({portrait:E,boundsPadding:x,x:e.width/100*z.current,y:e.height/100*z.current})}),[E,x,D]);t.useEffect((function(){return U&&!Y.current&&(window.addEventListener("mousemove",W,{passive:!0}),window.addEventListener("mouseup",q,{passive:!0}),window.addEventListener("touchmove",W,{passive:!0}),window.addEventListener("touchend",q,{passive:!0}),Y.current=!0),function(){Y.current&&(window.removeEventListener("mousemove",W),window.removeEventListener("mouseup",q),window.removeEventListener("touchmove",W),window.removeEventListener("touchend",q),Y.current=!1)}}),[W,q,U]),function(e,n){var o=t.useRef(new r.ResizeObserver((function(e){return n(e[0].contentRect)}))),i=t.useCallback((function(){e.current&&o.current.observe(e.current)}),[e]);d((function(){return o.current=new r.ResizeObserver((function(e){return n(e[0].contentRect)})),i(),function(){return o.current.disconnect()}}),[n,i])}(k,B),u("mousedown",I,N,{capture:!0,passive:!1}),u("touchstart",I,N,{capture:!0,passive:!1});var K=c||n.createElement(f,{portrait:E}),T=o({position:"relative",overflow:"hidden",cursor:U?E?"ns-resize":"ew-resize":void 0,userSelect:"none",KhtmlUserSelect:"none",msUserSelect:"none",MozUserSelect:"none",WebkitUserSelect:"none"},R);return n.createElement("div",Object.assign({},O,{ref:k,style:T,"data-rcs":"root"}),h,n.createElement(p,{ref:j},v),n.createElement(l,{portrait:E,ref:P},K))},exports.ReactCompareSliderHandle=f,exports.ReactCompareSliderImage=function(e){var r=e.className,a=e.fallbackEnable,u=void 0===a||a,d=e.style,l=i(e,["className","fallbackEnable","style"]),f=t.useRef(s()),p=c(o({},d)),v={width:p.width,height:p.height,boxSizing:"border-box"};return!f.current&&u&&(v.backgroundImage=p.backgroundImage||"url("+l.src+")",v.backgroundSize=p.backgroundSize||"cover",v.backgroundPosition=p.backgroundPosition||"center",p.opacity=0),n.createElement("div",{className:r,style:v,"data-rcs":"image-root"},n.createElement("img",Object.assign({},l,{style:p,"data-rcs":"image-inner"})))},exports.styleFitContainer=c,exports.supportsCssObjectFit=s; | ||
"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;const r=({flip:e})=>n.createElement("div",{style:{width:0,height:0,borderTop:"8px solid transparent",borderRight:"10px solid",borderBottom:"8px solid transparent",transform:e?"rotate(180deg)":void 0}}),o=({portrait:e,buttonStyle:t,linesStyle:o,style:s,...i})=>{const a={display:"flex",flexDirection:e?"row":"column",placeItems:"center",height:"100%",cursor:e?"ns-resize":"ew-resize",pointerEvents:"none",color:"#fff",...s},c={flexGrow:1,height:e?2:"100%",width:e?"100%":2,backgroundColor:"currentColor",pointerEvents:"auto",boxShadow:"0 0 7px rgba(0,0,0,.35)",...o},l={display:"grid",gridAutoFlow:"column",gap:8,placeContent:"center",flexShrink:0,width:56,height:56,borderRadius:"50%",borderStyle:"solid",borderWidth:2,pointerEvents:"auto",backdropFilter:"blur(7px)",boxShadow:"0 0 7px rgba(0,0,0,.35)",transform:e?"rotate(90deg)":void 0,...t};return n.createElement("div",Object.assign({className:"__rcs-handle-root"},i,{style:a}),n.createElement("div",{className:"__rcs-handle-line",style:c}),n.createElement("div",{className:"__rcs-handle-button",style:l},n.createElement(r,null),n.createElement(r,{flip:!0})),n.createElement("div",{className:"__rcs-handle-line",style:c}))},s=({boxSizing:e="border-box",objectFit:t="cover",objectPosition:n="center",...r}={})=>({display:"block",width:"100%",height:"100%",maxWidth:"100%",boxSizing:e,objectFit:t,objectPosition:n,...r}),i=(e,n,r,o)=>{const s=t.useRef();t.useEffect(()=>{s.current=n},[n]),t.useEffect(()=>{if(!r||!r.addEventListener)return;const t=e=>s.current&&s.current(e);return r.addEventListener(e,t,o),()=>{r.removeEventListener(e,t,o)}},[e,r,o])},a="undefined"!=typeof window&&window.document&&window.document.createElement?t.useLayoutEffect:t.useEffect,c=t.forwardRef((e,t)=>n.createElement("div",Object.assign({},e,{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",willChange:"clip",userSelect:"none",KhtmlUserSelect:"none",MozUserSelect:"none",WebkitUserSelect:"none"},"data-rcs":"clip-item",ref:t})));c.displayName="ThisClipContainer";const l=t.forwardRef(({children:e,portrait:t},r)=>n.createElement("div",{style:{position:"absolute",top:0,width:"100%",height:"100%",pointerEvents:"none"},"data-rcs":"handle-container",ref:r},n.createElement("div",{style:{position:"absolute",width:t?"100%":void 0,height:t?void 0:"100%",transform:t?"translateY(-50%)":"translateX(-50%)",pointerEvents:"all"}},e)));l.displayName="ThisHandleContainer";const d={passive:!0},u={capture:!0,passive:!1};exports.ReactCompareSlider=({handle:e,itemOne:r,itemTwo:s,onlyHandleDraggable:p=!1,onPositionChange:f,portrait:h=!1,position:m=50,boundsPadding:v=0,style:g,...b})=>{const w=t.useRef(null),E=t.useRef(null),y=t.useRef(null),x=t.useRef(m),S=(e=>{const n=t.useRef(e);return t.useEffect(()=>{n.current=e}),n.current})(m),[R,C]=t.useState(!1),O=t.useRef(!1),[k,L]=t.useState();t.useEffect(()=>{L(p?y.current:w.current)},[p]);const M=t.useCallback((function({x:e,y:t,isOffset:n,portrait:r,boundsPadding:o}){const{top:s,left:i,width:a,height:c}=w.current.getBoundingClientRect();if(0===a||0===c)return;const l=Math.min(Math.max(r?n?t-s-window.pageYOffset:t:n?e-i-window.pageXOffset:e,0),r?c:a),d=l/(r?c:a)*100;if(d===x.current&&(0===x.current||100===x.current)&&(r?0===l||l===c:0===l||l===a))return;x.current=d;const u=Math.min(Math.max(l,0+o),(r?c:a)-o);E.current.style.clip=r?`rect(auto,auto,${u}px,auto)`:`rect(auto,${u}px,auto,auto)`,y.current.style.transform=r?`translate3d(0,${u}px,0)`:`translate3d(${u}px,0,0)`,f&&f(x.current)}),[f]);t.useEffect(()=>{const{width:e,height:t}=w.current.getBoundingClientRect(),n=m===S?x.current:m;M({portrait:h,boundsPadding:v,x:e/100*n,y:t/100*n})},[h,m,S,v,M]);const j=t.useCallback(e=>{e.preventDefault(),M({portrait:h,boundsPadding:v,isOffset:!0,x:e instanceof MouseEvent?e.pageX:e.touches[0].pageX,y:e instanceof MouseEvent?e.pageY:e.touches[0].pageY}),C(!0)},[h,v,M]),z=t.useCallback((function(e){M({portrait:h,boundsPadding:v,isOffset:!0,x:e instanceof MouseEvent?e.pageX:e.touches[0].pageX,y:e instanceof MouseEvent?e.pageY:e.touches[0].pageY})}),[h,v,M]),P=t.useCallback(()=>{C(!1)},[]),_=t.useCallback(({width:e,height:t})=>{M({portrait:h,boundsPadding:v,x:e/100*x.current,y:t/100*x.current})},[h,v,M]);t.useEffect(()=>(R&&!O.current&&(window.addEventListener("mousemove",z,d),window.addEventListener("mouseup",P,d),window.addEventListener("touchmove",z,d),window.addEventListener("touchend",P,d),O.current=!0),()=>{O.current&&(window.removeEventListener("mousemove",z),window.removeEventListener("mouseup",P),window.removeEventListener("touchmove",z),window.removeEventListener("touchend",P),O.current=!1)}),[z,P,R]),((e,n)=>{const r=t.useRef(new ResizeObserver(([e])=>n(e.contentRect))),o=t.useCallback(()=>{e.current&&r.current.observe(e.current)},[e]);a(()=>(r.current=new ResizeObserver(([e])=>n(e.contentRect)),o(),()=>r.current.disconnect()),[n,o])})(w,_),i("mousedown",j,k,u),i("touchstart",j,k,u);const U=e||n.createElement(o,{portrait:h}),N={position:"relative",overflow:"hidden",cursor:R?h?"ns-resize":"ew-resize":void 0,userSelect:"none",KhtmlUserSelect:"none",msUserSelect:"none",MozUserSelect:"none",WebkitUserSelect:"none",...g};return n.createElement("div",Object.assign({},b,{ref:w,style:N,"data-rcs":"root"}),s,n.createElement(c,{ref:E},r),n.createElement(l,{portrait:h,ref:y},U))},exports.ReactCompareSliderHandle=o,exports.ReactCompareSliderImage=({style:e,...t})=>{const r=s(e);return n.createElement("img",Object.assign({},t,{style:r,"data-rcs":"image"}))},exports.styleFitContainer=s; | ||
//# sourceMappingURL=react-compare-slider.cjs.production.min.js.map |
import React, { useRef, useEffect, useCallback, useLayoutEffect, useState, forwardRef } 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]; | ||
const ThisArrow = ({ | ||
flip | ||
}) => { | ||
const style = { | ||
width: 0, | ||
height: 0, | ||
borderTop: '8px solid transparent', | ||
borderRight: '10px solid', | ||
borderBottom: '8px solid transparent', | ||
transform: flip ? 'rotate(180deg)' : undefined | ||
}; | ||
return React.createElement("div", { | ||
style: style | ||
}); | ||
}; | ||
/** Default `handle`. */ | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
const ReactCompareSliderHandle = ({ | ||
portrait, | ||
buttonStyle, | ||
linesStyle, | ||
style, | ||
...props | ||
}) => { | ||
const _style = { | ||
display: 'flex', | ||
flexDirection: portrait ? 'row' : 'column', | ||
placeItems: 'center', | ||
height: '100%', | ||
cursor: portrait ? 'ns-resize' : 'ew-resize', | ||
pointerEvents: 'none', | ||
color: '#fff', | ||
...style | ||
}; | ||
const _linesStyle = { | ||
flexGrow: 1, | ||
height: portrait ? 2 : '100%', | ||
width: portrait ? '100%' : 2, | ||
backgroundColor: 'currentColor', | ||
pointerEvents: 'auto', | ||
boxShadow: '0 0 7px rgba(0,0,0,.35)', | ||
...linesStyle | ||
}; | ||
const _buttonStyle = { | ||
display: 'grid', | ||
gridAutoFlow: 'column', | ||
gap: 8, | ||
placeContent: 'center', | ||
flexShrink: 0, | ||
width: 56, | ||
height: 56, | ||
borderRadius: '50%', | ||
borderStyle: 'solid', | ||
borderWidth: 2, | ||
pointerEvents: 'auto', | ||
backdropFilter: 'blur(7px)', | ||
boxShadow: '0 0 7px rgba(0,0,0,.35)', | ||
transform: portrait ? 'rotate(90deg)' : undefined, | ||
...buttonStyle | ||
}; | ||
return React.createElement("div", Object.assign({ | ||
className: "__rcs-handle-root" | ||
}, props, { | ||
style: _style | ||
}), React.createElement("div", { | ||
className: "__rcs-handle-line", | ||
style: _linesStyle | ||
}), React.createElement("div", { | ||
className: "__rcs-handle-button", | ||
style: _buttonStyle | ||
}, React.createElement(ThisArrow, null), React.createElement(ThisArrow, { | ||
flip: true | ||
})), React.createElement("div", { | ||
className: "__rcs-handle-line", | ||
style: _linesStyle | ||
})); | ||
}; | ||
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; | ||
} | ||
/** Whether runtime is client-side. */ | ||
var isClient = !!(typeof window !== 'undefined' && window.document && window.document.createElement); | ||
/** | ||
* Whether client supports the CSS `object-fit` property. | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) fit their | ||
* container. | ||
*/ | ||
var supportsCssObjectFit = function supportsCssObjectFit() { | ||
// Assume object-fit is supported in SSR - it will be picked up again by the | ||
// client anyway. | ||
if (!isClient) return true; | ||
return typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('object-fit', 'cover'); | ||
}; | ||
/** | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) | ||
* fit their container and maintain their aspect ratio. | ||
*/ | ||
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"]); | ||
return _extends({ | ||
display: 'block', | ||
width: '100%', | ||
height: '100%', | ||
maxWidth: '100%', | ||
objectFit: objectFit, | ||
objectPosition: objectPosition | ||
}, props); | ||
}; | ||
const styleFitContainer = ({ | ||
boxSizing = 'border-box', | ||
objectFit = 'cover', | ||
objectPosition = 'center', | ||
...props | ||
} = {}) => ({ | ||
display: 'block', | ||
width: '100%', | ||
height: '100%', | ||
maxWidth: '100%', | ||
boxSizing, | ||
objectFit, | ||
objectPosition, | ||
...props | ||
}); | ||
/** Store the previous supplied value. */ | ||
var usePrevious = function usePrevious(value) { | ||
var ref = useRef(value); | ||
useEffect(function () { | ||
const usePrevious = value => { | ||
const ref = useRef(value); | ||
useEffect(() => { | ||
ref.current = value; | ||
@@ -83,42 +113,31 @@ }); | ||
* Event listener binding hook. | ||
* @param eventName - Event to bind to | ||
* @param handler - Callback handler | ||
* @param element - Element to bind to | ||
* @param handlerOptions - Event handler options | ||
* @param eventName - Event to bind to. | ||
* @param handler - Callback handler. | ||
* @param element - Element to bind to. | ||
* @param handlerOptions - Event handler options. | ||
*/ | ||
var useEventListener = function useEventListener(eventName, handler, element, handlerOptions) { | ||
// Create a ref that stores handler | ||
var savedHandler = useRef(); // Update ref.current value if handler changes. | ||
// This allows our effect below to always get latest handler ... | ||
// ... without us needing to pass it in effect deps array ... | ||
// ... and potentially cause effect to re-run every render. | ||
useEffect(function () { | ||
const useEventListener = (eventName, handler, element, handlerOptions) => { | ||
const savedHandler = useRef(); | ||
useEffect(() => { | ||
savedHandler.current = handler; | ||
}, [handler]); | ||
useEffect(function () { | ||
// Make sure element supports addEventListener | ||
var isSupported = element && element.addEventListener; | ||
if (!isSupported) return; // Create event listener that calls handler function stored in ref | ||
useEffect(() => { | ||
// Make sure element supports addEventListener. | ||
if (!(element && element.addEventListener)) return; // Create event listener that calls handler function stored in ref. | ||
var eventListener = function eventListener(event) { | ||
return savedHandler.current && savedHandler.current(event); | ||
}; // Add event listener | ||
const eventListener = event => savedHandler.current && savedHandler.current(event); | ||
element.addEventListener(eventName, eventListener, handlerOptions); // Remove event listener on cleanup | ||
return function () { | ||
element.addEventListener(eventName, eventListener, handlerOptions); | ||
return () => { | ||
element.removeEventListener(eventName, eventListener, handlerOptions); | ||
}; | ||
}, [eventName, element, handlerOptions] // Re-run if eventName or element changes | ||
); | ||
}, [eventName, element, handlerOptions]); | ||
}; | ||
/** | ||
* Conditionally use `useLayoutEffect` for client *or* `useEffect` for SSR. | ||
* @see https://github.com/reduxjs/react-redux/blob/c581d480dd675f2645851fb006bef91aeb6ac24d/src/utils/useIsomorphicLayoutEffect.js | ||
* @see <https://github.com/reduxjs/react-redux/blob/c581d480dd675f2645851fb006bef91aeb6ac24d/src/utils/useIsomorphicLayoutEffect.js> | ||
*/ | ||
var useIsomorphicLayoutEffect = isClient ? useLayoutEffect : useEffect; | ||
const useIsomorphicLayoutEffect = typeof window !== 'undefined' && window.document && window.document.createElement ? useLayoutEffect : useEffect; | ||
/** | ||
@@ -130,29 +149,44 @@ * Bind resize observer callback to element. | ||
var useResizeObserver = function useResizeObserver(ref, handler) { | ||
var observer = useRef(new ResizeObserver(function (_ref2) { | ||
var entry = _ref2[0]; | ||
return handler(entry.contentRect); | ||
})); | ||
var observe = useCallback(function () { | ||
const useResizeObserver = (ref, handler) => { | ||
const observer = useRef(new ResizeObserver(([entry]) => handler(entry.contentRect))); | ||
const observe = useCallback(() => { | ||
ref.current && observer.current.observe(ref.current); | ||
}, [ref]); // Bind/rebind observer when `handler` changes. | ||
useIsomorphicLayoutEffect(function () { | ||
observer.current = new ResizeObserver(function (_ref3) { | ||
var entry = _ref3[0]; | ||
return handler(entry.contentRect); | ||
}); | ||
useIsomorphicLayoutEffect(() => { | ||
observer.current = new ResizeObserver(([entry]) => handler(entry.contentRect)); | ||
observe(); | ||
return function () { | ||
return observer.current.disconnect(); | ||
}; | ||
return () => observer.current.disconnect(); | ||
}, [handler, observe]); | ||
}; | ||
/** Container for clipped item. */ | ||
const ThisClipContainer = /*#__PURE__*/forwardRef((props, ref) => { | ||
const style = { | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
willChange: 'clip', | ||
userSelect: 'none', | ||
KhtmlUserSelect: 'none', | ||
MozUserSelect: 'none', | ||
WebkitUserSelect: 'none' | ||
}; | ||
return React.createElement("div", Object.assign({}, props, { | ||
style: style, | ||
"data-rcs": "clip-item", | ||
ref: ref | ||
})); | ||
}); | ||
ThisClipContainer.displayName = 'ThisClipContainer'; | ||
/** Handle container to control position. */ | ||
var ReactCompareSliderHandleContainer = /*#__PURE__*/forwardRef(function (_ref, ref) { | ||
var children = _ref.children, | ||
portrait = _ref.portrait; | ||
var style = { | ||
const ThisHandleContainer = /*#__PURE__*/forwardRef(({ | ||
children, | ||
portrait | ||
}, ref) => { | ||
const style = { | ||
position: 'absolute', | ||
@@ -164,3 +198,3 @@ top: 0, | ||
}; | ||
var innerStyle = { | ||
const innerStyle = { | ||
position: 'absolute', | ||
@@ -180,94 +214,49 @@ width: portrait ? '100%' : undefined, | ||
}); | ||
ReactCompareSliderHandleContainer.displayName = 'ReactCompareSliderHandleContainer'; | ||
/** Overridable handle. */ | ||
var ReactCompareSliderHandle = function ReactCompareSliderHandle(_ref2) { | ||
var portrait = _ref2.portrait, | ||
style = _ref2.style, | ||
props = _objectWithoutPropertiesLoose(_ref2, ["portrait", "style"]); | ||
var rootStyle = _extends({ | ||
height: portrait ? 4 : '100%', | ||
width: portrait ? '100%' : 4, | ||
backgroundColor: '#fff', | ||
boxShadow: '0 0 .2rem #000', | ||
cursor: portrait ? 'ns-resize' : 'ew-resize' | ||
}, style); | ||
return React.createElement("div", Object.assign({}, props, { | ||
style: rootStyle, | ||
"data-rcs": "handle-inner" | ||
})); | ||
ThisHandleContainer.displayName = 'ThisHandleContainer'; | ||
const EVENT_PASSIVE_PARAMS = { | ||
passive: true | ||
}; | ||
/** Container for items passed to main component. */ | ||
var ReactCompareSliderClipContainer = /*#__PURE__*/forwardRef(function (props, ref) { | ||
var style = { | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
willChange: 'clip', | ||
userSelect: 'none', | ||
KhtmlUserSelect: 'none', | ||
MozUserSelect: 'none', | ||
WebkitUserSelect: 'none' | ||
}; | ||
return React.createElement("div", Object.assign({}, props, { | ||
style: style, | ||
"data-rcs": "clip-item", | ||
ref: ref | ||
})); | ||
}); | ||
ReactCompareSliderClipContainer.displayName = 'ReactCompareSliderClipContainer'; | ||
const EVENT_CAPTURE_PARAMS = { | ||
capture: true, | ||
passive: false | ||
}; | ||
/** Root Comparison slider. */ | ||
var ReactCompareSlider = function ReactCompareSlider(_ref3) { | ||
var handle = _ref3.handle, | ||
itemOne = _ref3.itemOne, | ||
itemTwo = _ref3.itemTwo, | ||
_ref3$onlyHandleDragg = _ref3.onlyHandleDraggable, | ||
onlyHandleDraggable = _ref3$onlyHandleDragg === void 0 ? false : _ref3$onlyHandleDragg, | ||
onPositionChange = _ref3.onPositionChange, | ||
_ref3$portrait = _ref3.portrait, | ||
portrait = _ref3$portrait === void 0 ? false : _ref3$portrait, | ||
_ref3$position = _ref3.position, | ||
position = _ref3$position === void 0 ? 50 : _ref3$position, | ||
_ref3$boundsPadding = _ref3.boundsPadding, | ||
boundsPadding = _ref3$boundsPadding === void 0 ? 0 : _ref3$boundsPadding, | ||
style = _ref3.style, | ||
props = _objectWithoutPropertiesLoose(_ref3, ["handle", "itemOne", "itemTwo", "onlyHandleDraggable", "onPositionChange", "portrait", "position", "boundsPadding", "style"]); | ||
const ReactCompareSlider = ({ | ||
handle, | ||
itemOne, | ||
itemTwo, | ||
onlyHandleDraggable = false, | ||
onPositionChange, | ||
portrait = false, | ||
position = 50, | ||
boundsPadding = 0, | ||
style, | ||
...props | ||
}) => { | ||
/** Reference to root container. */ | ||
var rootContainerRef = useRef(null); | ||
const rootContainerRef = useRef(null); | ||
/** Reference to clip container. */ | ||
var clipContainerRef = useRef(null); | ||
const clipContainerRef = useRef(null); | ||
/** Reference to handle container. */ | ||
var handleContainerRef = useRef(null); | ||
const handleContainerRef = useRef(null); | ||
/** Reference to current position as a percentage value. */ | ||
var internalPositionPc = useRef(position); | ||
const internalPositionPc = useRef(position); | ||
/** Previous `position` prop value. */ | ||
var prevPropPosition = usePrevious(position); | ||
const prevPropPosition = usePrevious(position); | ||
/** Whether user is currently dragging. */ | ||
var _useState = useState(false), | ||
isDragging = _useState[0], | ||
setIsDragging = _useState[1]; | ||
const [isDragging, setIsDragging] = useState(false); | ||
/** Whether component has a `window` event binding. */ | ||
var hasWindowBinding = useRef(false); | ||
const hasWindowBinding = useRef(false); | ||
/** Target container for pointer events. */ | ||
var _useState2 = useState(), | ||
interactiveTarget = _useState2[0], | ||
setInteractiveTarget = _useState2[1]; // Set target container for pointer events. | ||
const [interactiveTarget, setInteractiveTarget] = useState(); // Set target container for pointer events. | ||
useEffect(function () { | ||
useEffect(() => { | ||
setInteractiveTarget(onlyHandleDraggable ? handleContainerRef.current : rootContainerRef.current); | ||
@@ -277,17 +266,17 @@ }, [onlyHandleDraggable]); | ||
var updateInternalPosition = useCallback(function updateInternalCall(_ref4) { | ||
var x = _ref4.x, | ||
y = _ref4.y, | ||
isOffset = _ref4.isOffset, | ||
_portrait = _ref4.portrait, | ||
_boundsPadding = _ref4.boundsPadding; | ||
var _rootContainerRef$cur = rootContainerRef.current.getBoundingClientRect(), | ||
top = _rootContainerRef$cur.top, | ||
left = _rootContainerRef$cur.left, | ||
width = _rootContainerRef$cur.width, | ||
height = _rootContainerRef$cur.height; // Early out if width or height are zero, can't calculate values | ||
const updateInternalPosition = useCallback(function updateInternalCall({ | ||
x, | ||
y, | ||
isOffset, | ||
portrait: _portrait, | ||
boundsPadding: _boundsPadding | ||
}) { | ||
const { | ||
top, | ||
left, | ||
width, | ||
height | ||
} = rootContainerRef.current.getBoundingClientRect(); // Early out if width or height are zero, can't calculate values | ||
// from zeros. | ||
if (width === 0 || height === 0) return; // Clamp pixel position to always be within the container's bounds. | ||
@@ -297,13 +286,17 @@ // This does *not* take `boundsPadding` into account because we need | ||
var positionPx = Math.min(Math.max( // Determine bounds based on orientation | ||
const positionPx = Math.min(Math.max( // Determine bounds based on orientation | ||
_portrait ? isOffset ? y - top - window.pageYOffset : y : isOffset ? x - left - window.pageXOffset : x, // Min value | ||
0), // Max value | ||
_portrait ? height : width); // Calculate internal position percentage *without* bounds - we always | ||
// want to return 0-100 of the *slideable* bounds. | ||
_portrait ? height : width); | ||
/** | ||
* Internal position percentage *without* bounds. | ||
* @NOTE This uses the entire container bounds **without** `boundsPadding` | ||
* to get the *real* bounds. | ||
*/ | ||
var nextInternalPositionPc = positionPx / (_portrait ? height : width) * 100; | ||
const nextInternalPositionPc = positionPx / (_portrait ? height : width) * 100; | ||
/** Determine if the current pixel position meets the min/max bounds. */ | ||
var positionMeetsBounds = _portrait ? positionPx === 0 || positionPx === height : positionPx === 0 || positionPx === width; | ||
var canSkipPositionPc = nextInternalPositionPc === internalPositionPc.current && (internalPositionPc.current === 0 || internalPositionPc.current === 100); // Early out if pixel and percentage positions are already at the min/max | ||
const positionMeetsBounds = _portrait ? positionPx === 0 || positionPx === height : positionPx === 0 || positionPx === width; | ||
const canSkipPositionPc = nextInternalPositionPc === internalPositionPc.current && (internalPositionPc.current === 0 || internalPositionPc.current === 100); // Early out if pixel and percentage positions are already at the min/max | ||
// to prevent update spamming when the user is sliding outside of the | ||
@@ -320,23 +313,23 @@ // container. | ||
var clampedPx = Math.min( // Get largest from pixel position *or* bounds padding. | ||
const clampedPx = Math.min( // Get largest from pixel position *or* bounds padding. | ||
Math.max(positionPx, 0 + _boundsPadding), // Use height *or* width based on orientation. | ||
(_portrait ? height : width) - _boundsPadding); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
clipContainerRef.current.style.clip = _portrait ? "rect(auto,auto," + clampedPx + "px,auto)" : "rect(auto," + clampedPx + "px,auto,auto)"; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
clipContainerRef.current.style.clip = _portrait ? `rect(auto,auto,${clampedPx}px,auto)` : `rect(auto,${clampedPx}px,auto,auto)`; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
handleContainerRef.current.style.transform = _portrait ? "translate3d(0," + clampedPx + "px,0)" : "translate3d(" + clampedPx + "px,0,0)"; | ||
handleContainerRef.current.style.transform = _portrait ? `translate3d(0,${clampedPx}px,0)` : `translate3d(${clampedPx}px,0,0)`; | ||
if (onPositionChange) onPositionChange(internalPositionPc.current); | ||
}, [onPositionChange]); // Update internal position if `position` prop changes. | ||
}, [onPositionChange]); // Update internal position when other user controllable props change. | ||
useEffect(function () { | ||
useEffect(() => { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
var _rootContainerRef$cur2 = rootContainerRef.current.getBoundingClientRect(), | ||
width = _rootContainerRef$cur2.width, | ||
height = _rootContainerRef$cur2.height; // Use current internal position if `position` hasn't changed. | ||
const { | ||
width, | ||
height | ||
} = rootContainerRef.current.getBoundingClientRect(); // Use current internal position if `position` hasn't changed. | ||
var nextPosition = position === prevPropPosition ? internalPositionPc.current : position; | ||
const nextPosition = position === prevPropPosition ? internalPositionPc.current : position; | ||
updateInternalPosition({ | ||
portrait: portrait, | ||
boundsPadding: boundsPadding, | ||
portrait, | ||
boundsPadding, | ||
x: width / 100 * nextPosition, | ||
@@ -348,7 +341,7 @@ y: height / 100 * nextPosition | ||
var handlePointerDown = useCallback(function (ev) { | ||
const handlePointerDown = useCallback(ev => { | ||
ev.preventDefault(); | ||
updateInternalPosition({ | ||
portrait: portrait, | ||
boundsPadding: boundsPadding, | ||
portrait, | ||
boundsPadding, | ||
isOffset: true, | ||
@@ -362,7 +355,6 @@ x: ev instanceof MouseEvent ? ev.pageX : ev.touches[0].pageX, | ||
var handlePointerMove = useCallback(function moveCall(ev) { | ||
if (!isDragging) return; | ||
const handlePointerMove = useCallback(function moveCall(ev) { | ||
updateInternalPosition({ | ||
portrait: portrait, | ||
boundsPadding: boundsPadding, | ||
portrait, | ||
boundsPadding, | ||
isOffset: true, | ||
@@ -372,6 +364,6 @@ x: ev instanceof MouseEvent ? ev.pageX : ev.touches[0].pageX, | ||
}); | ||
}, [portrait, isDragging, boundsPadding, updateInternalPosition]); | ||
}, [portrait, boundsPadding, updateInternalPosition]); | ||
/** Handle mouse/touch up. */ | ||
var handlePointerUp = useCallback(function () { | ||
const handlePointerUp = useCallback(() => { | ||
setIsDragging(false); | ||
@@ -381,8 +373,9 @@ }, []); | ||
var handleResize = useCallback(function (_ref5) { | ||
var width = _ref5.width, | ||
height = _ref5.height; | ||
const handleResize = useCallback(({ | ||
width, | ||
height | ||
}) => { | ||
updateInternalPosition({ | ||
portrait: portrait, | ||
boundsPadding: boundsPadding, | ||
portrait, | ||
boundsPadding, | ||
x: width / 100 * internalPositionPc.current, | ||
@@ -393,20 +386,12 @@ y: height / 100 * internalPositionPc.current | ||
useEffect(function () { | ||
useEffect(() => { | ||
if (isDragging && !hasWindowBinding.current) { | ||
window.addEventListener('mousemove', handlePointerMove, { | ||
passive: true | ||
}); | ||
window.addEventListener('mouseup', handlePointerUp, { | ||
passive: true | ||
}); | ||
window.addEventListener('touchmove', handlePointerMove, { | ||
passive: true | ||
}); | ||
window.addEventListener('touchend', handlePointerUp, { | ||
passive: true | ||
}); | ||
window.addEventListener('mousemove', handlePointerMove, EVENT_PASSIVE_PARAMS); | ||
window.addEventListener('mouseup', handlePointerUp, EVENT_PASSIVE_PARAMS); | ||
window.addEventListener('touchmove', handlePointerMove, EVENT_PASSIVE_PARAMS); | ||
window.addEventListener('touchend', handlePointerUp, EVENT_PASSIVE_PARAMS); | ||
hasWindowBinding.current = true; | ||
} | ||
return function () { | ||
return () => { | ||
if (hasWindowBinding.current) { | ||
@@ -422,19 +407,12 @@ window.removeEventListener('mousemove', handlePointerMove); | ||
useResizeObserver(rootContainerRef, handleResize); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
useResizeObserver(rootContainerRef, handleResize); | ||
useEventListener('mousedown', handlePointerDown, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
interactiveTarget, EVENT_CAPTURE_PARAMS); | ||
useEventListener('touchstart', handlePointerDown, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
interactiveTarget, EVENT_CAPTURE_PARAMS); // Use custom handle if requested. | ||
useEventListener('mousedown', handlePointerDown, interactiveTarget, { | ||
capture: true, | ||
passive: false | ||
}); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
useEventListener('touchstart', handlePointerDown, interactiveTarget, { | ||
capture: true, | ||
passive: false | ||
}); // Use custom handle if requested. | ||
var Handle = handle || React.createElement(ReactCompareSliderHandle, { | ||
const Handle = handle || React.createElement(ReactCompareSliderHandle, { | ||
portrait: portrait | ||
}); | ||
var rootStyle = _extends({ | ||
const rootStyle = { | ||
position: 'relative', | ||
@@ -447,5 +425,5 @@ overflow: 'hidden', | ||
MozUserSelect: 'none', | ||
WebkitUserSelect: 'none' | ||
}, style); | ||
WebkitUserSelect: 'none', | ||
...style | ||
}; | ||
return React.createElement("div", Object.assign({}, props, { | ||
@@ -455,5 +433,5 @@ ref: rootContainerRef, | ||
"data-rcs": "root" | ||
}), itemTwo, React.createElement(ReactCompareSliderClipContainer, { | ||
}), itemTwo, React.createElement(ThisClipContainer, { | ||
ref: clipContainerRef | ||
}, itemOne), React.createElement(ReactCompareSliderHandleContainer, { | ||
}, itemOne), React.createElement(ThisHandleContainer, { | ||
portrait: portrait, | ||
@@ -464,43 +442,16 @@ ref: handleContainerRef | ||
/** | ||
* Image with fallback background for browsers that don't support the | ||
* `object-fit` CSS property. | ||
*/ | ||
/** Image with defaults from `styleFitContainer` applied. */ | ||
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"]); | ||
/** Runtime support for `object-fit`. Ref based to allow updates after SSR. */ | ||
var objectFitIsSupported = useRef(supportsCssObjectFit()); | ||
var innerStyle = styleFitContainer(_extends({}, style)); | ||
var containerStyle = { | ||
width: innerStyle.width, | ||
height: innerStyle.height, | ||
boxSizing: 'border-box' | ||
}; // Add fallback background props if requested | ||
if (!objectFitIsSupported.current && fallbackEnable) { | ||
// Set fallback CSS properties, use props from `innerStyle` if defined | ||
containerStyle.backgroundImage = innerStyle.backgroundImage || "url(" + props.src + ")"; | ||
containerStyle.backgroundSize = innerStyle.backgroundSize || 'cover'; | ||
containerStyle.backgroundPosition = innerStyle.backgroundPosition || 'center'; // Hide inner image | ||
innerStyle.opacity = 0; | ||
} | ||
return React.createElement("div", { | ||
className: className, | ||
style: containerStyle, | ||
"data-rcs": "image-root" | ||
}, React.createElement("img", Object.assign({}, props, { | ||
style: innerStyle, | ||
"data-rcs": "image-inner" | ||
}))); | ||
const ReactCompareSliderImage = ({ | ||
style, | ||
...props | ||
}) => { | ||
const rootStyle = styleFitContainer(style); | ||
return React.createElement("img", Object.assign({}, props, { | ||
style: rootStyle, | ||
"data-rcs": "image" | ||
})); | ||
}; | ||
export { ReactCompareSlider, ReactCompareSliderHandle, ReactCompareSliderImage, styleFitContainer, supportsCssObjectFit }; | ||
export { ReactCompareSlider, ReactCompareSliderHandle, ReactCompareSliderImage, styleFitContainer }; | ||
//# sourceMappingURL=react-compare-slider.esm.js.map |
@@ -1,12 +0,7 @@ | ||
import { RefObject } from 'react'; | ||
import { ContentRect } from 'resize-observer/lib/ContentRect'; | ||
import { RefObject, useLayoutEffect } from 'react'; | ||
/** | ||
* Whether client supports the CSS `object-fit` property. | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) fit their | ||
* container. | ||
*/ | ||
export declare const supportsCssObjectFit: () => boolean; | ||
/** | ||
* Stand-alone CSS utility to make replaced elements (`img`, `video`, etc.) | ||
* fit their container and maintain their aspect ratio. | ||
*/ | ||
export declare const styleFitContainer: ({ objectFit, objectPosition, ...props }?: React.CSSProperties) => React.CSSProperties; | ||
export declare const styleFitContainer: ({ boxSizing, objectFit, objectPosition, ...props }?: React.CSSProperties) => React.CSSProperties; | ||
/** Store the previous supplied value. */ | ||
@@ -16,10 +11,15 @@ export declare const usePrevious: <T>(value: T) => T; | ||
* Event listener binding hook. | ||
* @param eventName - Event to bind to | ||
* @param handler - Callback handler | ||
* @param element - Element to bind to | ||
* @param handlerOptions - Event handler options | ||
* @param eventName - Event to bind to. | ||
* @param handler - Callback handler. | ||
* @param element - Element to bind to. | ||
* @param handlerOptions - Event handler options. | ||
*/ | ||
export declare const useEventListener: (eventName: EventListener['name'], handler: EventListener['caller'], element: EventTarget, handlerOptions: AddEventListenerOptions) => void; | ||
/** | ||
* Conditionally use `useLayoutEffect` for client *or* `useEffect` for SSR. | ||
* @see <https://github.com/reduxjs/react-redux/blob/c581d480dd675f2645851fb006bef91aeb6ac24d/src/utils/useIsomorphicLayoutEffect.js> | ||
*/ | ||
export declare const useIsomorphicLayoutEffect: typeof useLayoutEffect; | ||
/** Params passed to `useResizeObserver` `handler` function. */ | ||
export declare type UseResizeObserverHandlerParams = ContentRect; | ||
export declare type UseResizeObserverHandlerParams = DOMRect; | ||
/** | ||
@@ -26,0 +26,0 @@ * Bind resize observer callback to element. |
129
package.json
{ | ||
"name": "react-compare-slider", | ||
"version": "1.2.1", | ||
"version": "2.0.1", | ||
"license": "MIT", | ||
@@ -38,3 +38,3 @@ "repository": { | ||
"start": "tsdx watch", | ||
"build": "tsdx build", | ||
"build": "NODE_ENV=production 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", | ||
@@ -50,9 +50,29 @@ "release": "yarn build && np --no-2fa", | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.8", | ||
"react-dom": ">=16.8" | ||
"browserslist": { | ||
"production": [ | ||
"last 2 chrome versions", | ||
"last 2 edge versions", | ||
"last 2 firefox versions", | ||
"last 2 safari versions", | ||
"not dead", | ||
"not ie > 0", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
}, | ||
"np": { | ||
"yarn": true | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
}, | ||
"jest": { | ||
"verbose": true, | ||
"setupFilesAfterEnv": [ | ||
"./test/setupTests.ts" | ||
] | ||
}, | ||
"lint-staged": { | ||
@@ -65,9 +85,7 @@ "**/*.{js,jsx,ts,tsx}": [ | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
"np": { | ||
"yarn": true | ||
}, | ||
"prettier": { | ||
"printWidth": 80, | ||
"printWidth": 90, | ||
"semi": true, | ||
@@ -77,46 +95,53 @@ "singleQuote": true, | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.8", | ||
"react-dom": ">=16.8" | ||
}, | ||
"devDependencies": { | ||
"@emotion/babel-preset-css-prop": "^10.0.27", | ||
"@emotion/css": "^10.0.27", | ||
"@storybook/addon-actions": "^6.0.21", | ||
"@storybook/addon-console": "^1.2.1", | ||
"@storybook/addon-controls": "^6.0.21", | ||
"@storybook/addon-docs": "^6.0.21", | ||
"@storybook/addon-storysource": "^6.0.21", | ||
"@storybook/addon-viewport": "^6.0.21", | ||
"@storybook/addons": "^6.0.21", | ||
"@emotion/babel-preset-css-prop": "^11.0.0", | ||
"@emotion/css": "^11.1.3", | ||
"@emotion/react": "^11.1.4", | ||
"@storybook/addon-actions": "^6.2.0-alpha.10", | ||
"@storybook/addon-console": "^1.2.2", | ||
"@storybook/addon-controls": "^6.2.0-alpha.10", | ||
"@storybook/addon-docs": "^6.2.0-alpha.10", | ||
"@storybook/addon-storysource": "^6.2.0-alpha.10", | ||
"@storybook/addon-viewport": "^6.2.0-alpha.10", | ||
"@storybook/addons": "^6.2.0-alpha.10", | ||
"@storybook/preset-typescript": "3.0.0", | ||
"@storybook/react": "^6.0.21", | ||
"@storybook/theming": "^6.0.21", | ||
"@testing-library/jest-dom": "^5.11.4", | ||
"@testing-library/react": "^11.0.2", | ||
"@types/jest": "^26.0.13", | ||
"@types/node": "^12.12.26", | ||
"@types/react": "^16.9.49", | ||
"@types/react-dom": "^16.9.8", | ||
"@typescript-eslint/eslint-plugin": "^4.0.1", | ||
"@typescript-eslint/parser": "^4.0.1", | ||
"babel-loader": "^8.1.0", | ||
"eslint": "^7.8.1", | ||
"eslint-plugin-jest": "^24.0.0", | ||
"eslint-plugin-jest-dom": "^3.2.2", | ||
"eslint-plugin-react": "^7.20.6", | ||
"eslint-plugin-react-hooks": "^4.1.0", | ||
"eslint-plugin-testing-library": "^3.8.0", | ||
"@storybook/react": "^6.2.0-alpha.10", | ||
"@storybook/theming": "^6.2.0-alpha.10", | ||
"@testing-library/jest-dom": "^5.11.8", | ||
"@testing-library/react": "^11.2.2", | ||
"@testing-library/react-hooks": "^3.7.0", | ||
"@types/jest": "^26.0.19", | ||
"@types/node": "^14.14.17", | ||
"@types/react": "^17.0.0", | ||
"@types/react-dom": "^17.0.0", | ||
"@types/resize-observer-browser": "^0.1.4", | ||
"@typescript-eslint/eslint-plugin": "^4.11.1", | ||
"@typescript-eslint/parser": "^4.11.1", | ||
"babel-loader": "^8.2.2", | ||
"eslint": "^7.16.0", | ||
"eslint-plugin-jest": "^24.1.3", | ||
"eslint-plugin-jest-dom": "^3.6.5", | ||
"eslint-plugin-react": "^7.22.0", | ||
"eslint-plugin-react-hooks": "^4.2.0", | ||
"eslint-plugin-testing-library": "^3.10.1", | ||
"google-maps-react": "^2.0.6", | ||
"husky": "^4.2.5", | ||
"lint-staged": "^10.3.0", | ||
"np": "^6.5.0", | ||
"prettier": "^2.1.1", | ||
"pretty-quick": "^3.0.0", | ||
"react": "^16.13.1", | ||
"react-dom": "^16.13.1", | ||
"remark-codesandbox": "^0.6.0", | ||
"tsdx": "^0.13.3", | ||
"tslib": "^2.0.1", | ||
"typescript": "^4.0.2" | ||
"husky": "^4.3.6", | ||
"lint-staged": "^10.5.3", | ||
"np": "^7.2.0", | ||
"prettier": "^2.2.1", | ||
"pretty-quick": "^3.1.0", | ||
"react": "^17.0.1", | ||
"react-dom": "^17.0.1", | ||
"react-test-renderer": "^17.0.1", | ||
"remark-codesandbox": "^0.10.0", | ||
"rollup-plugin-analyzer": "^4.0.0", | ||
"tsdx": "^0.14.1", | ||
"tslib": "^2.0.3", | ||
"typescript": "^4.1.3" | ||
}, | ||
"dependencies": { | ||
"resize-observer": "^1.0.0" | ||
} | ||
"dependencies": {} | ||
} |
<div align="center"> | ||
<h1>React Compare Slider</h1> | ||
<p>Compare two components side-by-side or top-to-toe.</p> | ||
<h1>React Compare Slider</h1> | ||
<p>Compare two components side-by-side or top-to-toe.</p> | ||
@@ -8,19 +8,19 @@ [![Example](./example/default-handle-capture.gif)](https://codesandbox.io/s/react-compare-slider-simple-example-9si6l?file=/src/App.jsx) | ||
<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://img.shields.io/github/workflow/status/nerdyman/react-compare-slider/build" alt="Build Status" /> | ||
<img src="https://img.shields.io/github/workflow/status/nerdyman/react-compare-slider/build" alt="Build Status" /> | ||
</a> | ||
<a href="https://codeclimate.com/github/nerdyman/react-compare-slider"> | ||
<img src="https://img.shields.io/codeclimate/coverage/nerdyman/react-compare-slider" alt="Coverage" /> | ||
<img src="https://img.shields.io/codeclimate/coverage/nerdyman/react-compare-slider" alt="Coverage" /> | ||
</a> | ||
<a href="https://react-compare-slider.vercel.app"> | ||
<img src="https://raw.githubusercontent.com/storybookjs/brand/8d28584c89959d7075c237e9345955c895048977/badge/badge-storybook.svg" alt="Demos" /> | ||
<img src="https://raw.githubusercontent.com/storybookjs/brand/8d28584c89959d7075c237e9345955c895048977/badge/badge-storybook.svg" alt="Demos" /> | ||
</a> | ||
@@ -39,6 +39,8 @@ | ||
- Responsive, fluid | ||
- Works in IE11+ | ||
- [Teeny-tiny](https://bundlephobia.com/result?p=react-compare-slider), only one ponyfill dependency | ||
- [Teeny-tiny](https://bundlephobia.com/result?p=react-compare-slider) | ||
- Zero dependencies | ||
- Type safe | ||
<br /> | ||
## Demo | ||
@@ -104,3 +106,3 @@ | ||
[![Custom Handles](./example/custom-handle-capture.gif)](https://codesandbox.io/s/react-compare-slider-simple-example-9si6l?file=/src/App.jsx) | ||
[![Custom Handles](./example/custom-handle-capture.gif)](https://react-compare-slider.vercel.app/?path=/story/demos-handles--individual-styles) | ||
@@ -115,2 +117,2 @@ See the [Handles docs](https://react-compare-slider.vercel.app/?path=/docs/docs-handles--page) for more information. | ||
Bootstrapped with [TSDX](<https://github.com/palmerhq/tsdx>). | ||
Bootstrapped with [TSDX](https://github.com/formium/tsdx). |
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
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
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
2
16
115
140677
44
904
1
- Removedresize-observer@^1.0.0
- Removedresize-observer@1.0.4(transitive)