UNPKG

@onesy/ui-react

Version:
521 lines (519 loc) 24.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _utils = require("@onesy/utils"); var _styleReact = require("@onesy/style-react"); var _IconMaterialNavigateNextW = _interopRequireDefault(require("@onesy/icons-material-rounded-react/IconMaterialNavigateNextW100")); var _IconMaterialNavigateBeforeW = _interopRequireDefault(require("@onesy/icons-material-rounded-react/IconMaterialNavigateBeforeW100")); var _IconMaterialCloseW = _interopRequireDefault(require("@onesy/icons-material-rounded-react/IconMaterialCloseW100")); var _Image = _interopRequireDefault(require("../Image")); var _Line = _interopRequireDefault(require("../Line")); var _IconButton = _interopRequireDefault(require("../IconButton")); var _Interaction = _interopRequireDefault(require("../Interaction")); var _Backdrop = _interopRequireDefault(require("../Backdrop")); var _utils2 = require("../utils"); var _jsxRuntime = require("react/jsx-runtime"); const _excluded = ["ref", "version", "size", "open", "onClose", "value", "items", "minZoom", "maxZoom", "incrementZoom", "overflow", "arrows", "startMain", "endMain", "startImage", "endImage", "startThumbnails", "endThumbnails", "ImageProps", "ImageWrapperProps", "IconButtonProps", "IconStart", "IconEnd", "IconClose", "className"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } const useStyle = (0, _styleReact.style)(theme => ({ root: { position: 'relative', '&.onesy-Backdrop-root': { display: 'flex', alignItems: 'center', justifyContent: 'center', userSelect: 'none', zIndex: '14000' }, '& .onesy-Backdrop-backdrop-root': { width: '100%', height: '100%', pointerEvents: 'none' } }, version_regular: { minHeight: 'clamp(240px, 100%, 100vh)' }, pointerEventsAuto: { pointerEvents: 'auto' }, wrapper: { height: '100%' }, header: { padding: theme.methods.space.value(3, 'px'), zIndex: '1' }, main: { position: 'relative', zIndex: '14' }, main_version_modal: { height: '0', padding: theme.methods.space.value(5, 'px'), '& .onesy-Image-root': { maxHeight: '100%' // pointerEvents: 'none' } }, main_version_regular_size_small: { height: '340px' }, main_version_regular_size_regular: { height: '540px' }, main_version_regular_size_large: { height: '740px' }, noOverflow: { overflow: 'hidden' }, footer: { padding: `${theme.methods.space.value(3, 'px')} ${theme.methods.space.value(1.5, 'px')}`, zIndex: '1' }, imageWrapper: { position: 'relative', height: '0px', pointerEvents: 'none', // zIndex: 1, transition: theme.methods.transitions.make(['transform'], { duration: 100, timing_function: 'ease' }) }, image: { objectFit: 'contain', width: 'auto', height: 'auto', maxHeight: '100%', maxWidth: '100%' }, itemsWrapper: { position: 'relative', pointerEvents: 'auto', maxWidth: '100%', userSelect: 'none' }, items: { maxWidth: '1024px', overflow: 'auto hidden', '&::-webkit-scrollbar': { width: '16px', height: '16px' }, '&::-webkit-scrollbar-track, &::-webkit-scrollbar-corner': { background: 'transparent' }, '&::-webkit-scrollbar-thumb': { borderRadius: theme.methods.shape.radius.value(1, 'px'), border: '4px solid transparent', backgroundClip: 'content-box', backgroundColor: 'rgba(221, 221, 221, 0.4)', '&:hover': { backgroundColor: 'rgba(221, 221, 221, 0.7)' } } }, item: { width: '140px', height: '140px', position: 'relative', backgroundSize: 'contain', backgroundPosition: 'center', backgroundRepeat: 'no-repeat', flex: '0 0 auto', border: '2px solid transparent', cursor: 'pointer', userSelect: 'none', transition: theme.methods.transitions.make(['border', 'transform']), '&:active': { transform: 'scale(0.94)' } }, itemSelected: { border: '2px solid !important', borderColor: `${theme.methods.palette.color.value('secondary', 30)} !important` }, arrow: { flex: '0 0 auto', alignSelf: 'center', justifySelf: 'center', transition: theme.methods.transitions.make(['opacity'], { duration: 'xxs' }), '&[disabled]': { opacity: '0' } } }), { name: 'onesy-ImageGallery' }); const ImageGallery = props_ => { var _theme$ui, _theme$ui2, _theme$elements, _theme$elements2, _theme$elements3, _theme$elements4, _theme$elements5, _refs$more$current3, _refs$more$current4, _refs$more$current5, _refs$more$current6; const theme = (0, _styleReact.useOnesyTheme)(); const props = _objectSpread(_objectSpread(_objectSpread({}, theme === null || theme === void 0 || (_theme$ui = theme.ui) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.elements) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.all) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.props) === null || _theme$ui === void 0 ? void 0 : _theme$ui.default), theme === null || theme === void 0 || (_theme$ui2 = theme.ui) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.elements) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.onesyImageGallery) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.props) === null || _theme$ui2 === void 0 ? void 0 : _theme$ui2.default), props_); const Line = (theme === null || theme === void 0 || (_theme$elements = theme.elements) === null || _theme$elements === void 0 ? void 0 : _theme$elements.Line) || _Line.default; const Image = (theme === null || theme === void 0 || (_theme$elements2 = theme.elements) === null || _theme$elements2 === void 0 ? void 0 : _theme$elements2.Image) || _Image.default; const IconButton = (theme === null || theme === void 0 || (_theme$elements3 = theme.elements) === null || _theme$elements3 === void 0 ? void 0 : _theme$elements3.IconButton) || _IconButton.default; const Interaction = (theme === null || theme === void 0 || (_theme$elements4 = theme.elements) === null || _theme$elements4 === void 0 ? void 0 : _theme$elements4.Interaction) || _Interaction.default; const Backdrop = (theme === null || theme === void 0 || (_theme$elements5 = theme.elements) === null || _theme$elements5 === void 0 ? void 0 : _theme$elements5.Backdrop) || _Backdrop.default; const { ref, version = 'modal', size = 'regular', open: open_, onClose: onClose_, value: value_, items, minZoom: minZoom_ = 1, maxZoom: maxZoom_ = 2, incrementZoom = 0.07, overflow = true, arrows = true, startMain, endMain, startImage, endImage, startThumbnails, endThumbnails, ImageProps, ImageWrapperProps, IconButtonProps, IconStart = _IconMaterialNavigateBeforeW.default, IconEnd = _IconMaterialNavigateNextW.default, IconClose = _IconMaterialCloseW.default, className } = props, other = (0, _objectWithoutProperties2.default)(props, _excluded); const { classes } = useStyle(); const [, setLoaded] = _react.default.useState(false); const [open, setOpen] = _react.default.useState(false); const [value, setValue] = _react.default.useState(0); const [moveValue, setMoveValue] = _react.default.useState(); const [imageRef, setImageRef] = _react.default.useState(); const [keyDown, setKeyDown] = _react.default.useState(); const refs = { root: _react.default.useRef(null), version: _react.default.useRef(version), more: _react.default.useRef(null), image: _react.default.useRef(null), imageWrapper: _react.default.useRef(null), media: _react.default.useRef(null), zoom: _react.default.useRef(null), incrementZoom: _react.default.useRef(null), minZoom: _react.default.useRef(null), maxZoom: _react.default.useRef(null), mouseDown: _react.default.useRef(null), mouseMovePrevious: _react.default.useRef(null), keyDown: _react.default.useRef(keyDown), useZoom: _react.default.useRef(false) }; const minZoom = (0, _utils.clamp)(minZoom_, 0.1, 1); const maxZoom = (0, _utils.clamp)(maxZoom_, 1, 100); const length = (0, _utils.clamp)(((items === null || items === void 0 ? void 0 : items.length) || 0) - 1, 0); const media = items === null || items === void 0 ? void 0 : items[value]; refs.version.current = version; refs.media.current = !!media; refs.keyDown.current = keyDown; refs.useZoom.current = version === 'modal' || keyDown; refs.incrementZoom.current = incrementZoom; refs.minZoom.current = minZoom; refs.maxZoom.current = maxZoom; const init = () => { setTimeout(() => { var _refs$more$current, _refs$more$current2; setMoveValue({ left: (_refs$more$current = refs.more.current) === null || _refs$more$current === void 0 ? void 0 : _refs$more$current.scrollLeft, top: (_refs$more$current2 = refs.more.current) === null || _refs$more$current2 === void 0 ? void 0 : _refs$more$current2.scrollTop }); setLoaded(true); }, 14); }; const cleanUp = () => { refs.mouseDown.current = false; }; _react.default.useEffect(() => { const onKeyDown = event => { setKeyDown(event.metaKey || event.ctrlKey); }; const onKeyUp = event_0 => { setKeyDown(null); }; window.document.addEventListener('keydown', onKeyDown); window.document.addEventListener('keyup', onKeyUp); return () => { window.document.removeEventListener('keydown', onKeyDown); window.document.removeEventListener('keyup', onKeyUp); }; }, []); _react.default.useEffect(() => { // init if (open) init();else cleanUp(); }, [open]); _react.default.useEffect(() => { if (open_ !== undefined && open !== open_) setOpen(open_); }, [open_]); _react.default.useEffect(() => { if (value_ !== undefined && value !== value_) setValue((0, _utils.clamp)(value_, 0, length)); }, [value_]); const onResetZoom = () => { refs.zoom.current = null; if (refs.imageWrapper.current) { refs.imageWrapper.current.style.transition = 'none'; refs.imageWrapper.current.style.removeProperty('transform'); refs.imageWrapper.current.style.removeProperty('left'); refs.imageWrapper.current.style.removeProperty('top'); setTimeout(() => { refs.imageWrapper.current.style.removeProperty('transition'); }, 14); } }; const onValue = index => { onResetZoom(); setValue(index); }; const onClose = () => { setOpen(false); setTimeout(() => { setLoaded(false); }, 140); if ((0, _utils.is)('function', onClose_)) onClose_(); }; const move = (forward_ = true) => { const forward = forward_; const rect = refs.more.current.getBoundingClientRect(); const moveValue_ = { left: refs.more.current.scrollLeft + (forward ? 1 : -1) * rect.width, behavior: 'smooth' }; refs.more.current.scrollTo(moveValue_); }; const onMouseDown = event_1 => { refs.mouseDown.current = true; refs.mouseMovePrevious.current = { x: event_1.clientX, y: event_1.clientY }; }; const onMouseUp = () => { refs.mouseDown.current = false; refs.mouseMovePrevious.current = null; }; const onWheel = event_2 => { var _refs$zoom$current, _refs$image$current, _refs$zoom$current2; if (!refs.useZoom.current) return; event_2.preventDefault(); event_2.stopPropagation(); let scale = ((_refs$zoom$current = refs.zoom.current) === null || _refs$zoom$current === void 0 ? void 0 : _refs$zoom$current.scale) !== undefined ? refs.zoom.current.scale : 1; const part = refs.incrementZoom.current; const up = event_2.wheelDelta > 0 || event_2.deltaY < 0; scale = (0, _utils.clamp)(up ? scale + part : scale - part, refs.minZoom.current, refs.maxZoom.current); // Only allow in 100's decimal places, ie. 1.01 scale = Math.round(scale * 100) / 100; const imageBoundingRect = (_refs$image$current = refs.image.current) === null || _refs$image$current === void 0 ? void 0 : _refs$image$current.getBoundingClientRect(); if (imageBoundingRect.width <= window.innerWidth) { refs.imageWrapper.current.style.removeProperty('left'); } if (imageBoundingRect.height <= window.innerHeight) { refs.imageWrapper.current.style.removeProperty('top'); } if (scale !== ((_refs$zoom$current2 = refs.zoom.current) === null || _refs$zoom$current2 === void 0 ? void 0 : _refs$zoom$current2.scale)) { refs.zoom.current = { scale }; refs.imageWrapper.current.style.transform = `scale(${scale})`; } }; const onMouseMove = event_3 => { var _refs$mouseMovePrevio, _refs$mouseMovePrevio2, _refs$imageWrapper$cu, _refs$imageWrapper$cu2; if (!refs.useZoom.current) return; if (!(refs.mouseDown.current && refs.image.current)) return; const x = event_3.x - (((_refs$mouseMovePrevio = refs.mouseMovePrevious.current) === null || _refs$mouseMovePrevio === void 0 ? void 0 : _refs$mouseMovePrevio.x) || 0); const y = event_3.y - (((_refs$mouseMovePrevio2 = refs.mouseMovePrevious.current) === null || _refs$mouseMovePrevio2 === void 0 ? void 0 : _refs$mouseMovePrevio2.y) || 0); refs.mouseMovePrevious.current = { x: event_3.clientX, y: event_3.clientY }; let left = Number((_refs$imageWrapper$cu = refs.imageWrapper.current) === null || _refs$imageWrapper$cu === void 0 || (_refs$imageWrapper$cu = _refs$imageWrapper$cu.style) === null || _refs$imageWrapper$cu === void 0 || (_refs$imageWrapper$cu = _refs$imageWrapper$cu.left) === null || _refs$imageWrapper$cu === void 0 ? void 0 : _refs$imageWrapper$cu.replace('px', '')) || 0; let top = Number((_refs$imageWrapper$cu2 = refs.imageWrapper.current) === null || _refs$imageWrapper$cu2 === void 0 || (_refs$imageWrapper$cu2 = _refs$imageWrapper$cu2.style) === null || _refs$imageWrapper$cu2 === void 0 || (_refs$imageWrapper$cu2 = _refs$imageWrapper$cu2.top) === null || _refs$imageWrapper$cu2 === void 0 ? void 0 : _refs$imageWrapper$cu2.replace('px', '')) || 0; const imageBoundingRect_0 = refs.image.current.getBoundingClientRect(); if (imageBoundingRect_0.left <= 0 && imageBoundingRect_0.left + x <= 0 && imageBoundingRect_0.width + imageBoundingRect_0.left + x >= window.innerWidth) { left += x; refs.imageWrapper.current.style.left = `${left}px`; } if (imageBoundingRect_0.top <= 0 && imageBoundingRect_0.top + y <= 0 && imageBoundingRect_0.height + imageBoundingRect_0.top + y >= window.innerHeight) { top += y; refs.imageWrapper.current.style.top = `${top}px`; } }; _react.default.useEffect(() => { if (refs.useZoom.current) { if (imageRef) imageRef.addEventListener('wheel', onWheel, { passive: false }); window.addEventListener('mousemove', onMouseMove); window.addEventListener('mouseup', onMouseUp); window.addEventListener('touchend', onMouseUp); } return () => { if (imageRef) imageRef.removeEventListener('wheel', onWheel); window.removeEventListener('mousemove', onMouseMove); window.removeEventListener('mouseup', onMouseUp); window.removeEventListener('touchend', onMouseUp); }; }, [imageRef, refs.useZoom.current]); const onScroll = event_4 => { if (!refs.useZoom.current) return; if (arrows) { setMoveValue({ left: refs.more.current.scrollLeft, top: refs.more.current.scrollTop }); } }; const iconButtonProps = _objectSpread({ version: 'filled', color: 'default', tonal: true, size: 'small' }, IconButtonProps); const arrowPre = moveValue && /*#__PURE__*/(0, _jsxRuntime.jsx)(IconButton, _objectSpread(_objectSpread({ onClick: () => move(false), disabled: !moveValue || ((_refs$more$current3 = refs.more.current) === null || _refs$more$current3 === void 0 ? void 0 : _refs$more$current3.scrollLeft) === 0 }, iconButtonProps), {}, { className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-arrow', 'onesy-ImageGallery-arrow-start'], iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.className, classes.arrow]), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconStart, {}) })); const arrowPost = moveValue && /*#__PURE__*/(0, _jsxRuntime.jsx)(IconButton, _objectSpread(_objectSpread({ onClick: () => move(), disabled: Math.ceil(((_refs$more$current4 = refs.more.current) === null || _refs$more$current4 === void 0 ? void 0 : _refs$more$current4.clientWidth) + ((_refs$more$current5 = refs.more.current) === null || _refs$more$current5 === void 0 ? void 0 : _refs$more$current5.scrollLeft)) === ((_refs$more$current6 = refs.more.current) === null || _refs$more$current6 === void 0 ? void 0 : _refs$more$current6.scrollWidth) }, iconButtonProps), {}, { className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-arrow', 'onesy-ImageGallery-arrow-end'], iconButtonProps === null || iconButtonProps === void 0 ? void 0 : iconButtonProps.className, classes.arrow]), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconEnd, {}) })); const more = !!(items !== null && items !== void 0 && items.length); const onDragStartImage = event_5 => { event_5.preventDefault(); }; const url = (media === null || media === void 0 ? void 0 : media.url) || (media === null || media === void 0 ? void 0 : media.urlSmall) || ((0, _utils.is)('string', media) ? media : ''); const main = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(Line, { justify: "center", align: "center", flex: true, fullWidth: true, className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-main'], classes.main, classes[`main_version_${version}`], classes[`main_version_${version}_size_${size}`], !overflow && classes.noOverflow]), children: [startMain, /*#__PURE__*/(0, _jsxRuntime.jsxs)(Line, _objectSpread(_objectSpread({ ref: refs.imageWrapper, justify: "center", align: "center", fullWidth: true, flex: true }, ImageWrapperProps), {}, { className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-image-wrapper'], ImageWrapperProps === null || ImageWrapperProps === void 0 ? void 0 : ImageWrapperProps.className, classes.imageWrapper]), style: _objectSpread({}, ImageWrapperProps === null || ImageWrapperProps === void 0 ? void 0 : ImageWrapperProps.style), children: [startImage, url && /*#__PURE__*/(0, _jsxRuntime.jsx)(Image, _objectSpread(_objectSpread({ ref: item => { refs.image.current = item; setImageRef(item); }, src: url, alt: media === null || media === void 0 ? void 0 : media.name, onMouseDown: onMouseDown, onMouseUp: onMouseUp, onTouchStart: onMouseDown, onTouchEnd: onMouseUp, onDragStart: onDragStartImage, lazyLoad: version === 'regular' }, ImageProps), {}, { className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-image'], ImageProps === null || ImageProps === void 0 ? void 0 : ImageProps.className, classes.image, classes.pointerEventsAuto]) })), endImage] })), endMain] }), more && /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, { align: "center", fullWidth: true, className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-footer'], classes.footer]), children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Line, { gap: 1.5, direction: "row", justify: "center", align: "center", className: (0, _styleReact.classNames)([classes.itemsWrapper]), children: [startThumbnails, arrows && arrowPre, /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, { ref: refs.more, gap: 1, direction: "row", align: "center", justify: "flex-start", fullWidth: true, onScroll: onScroll, className: (0, _styleReact.classNames)([classes.items]), children: items.map((item_0, index_0) => /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, { onClick: () => onValue(index_0), className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-item', value === index_0 && 'onesy-ImageGallery-item-selected'], classes.item, value === index_0 && classes.itemSelected]), style: { backgroundImage: `url('${(item_0 === null || item_0 === void 0 ? void 0 : item_0.urlSmall) || (item_0 === null || item_0 === void 0 ? void 0 : item_0.url) || item_0}')` }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Interaction, {}) })) }), arrows && arrowPost, endThumbnails] }) })] }); if (version === 'regular') { return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, _objectSpread(_objectSpread({ ref: item_1 => { if (ref) { if ((0, _utils.is)('function', ref)) ref(item_1);else ref.current = item_1; } refs.root.current = item_1; }, fullWidth: true, className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-root', `onesy-ImageGallery-version-${version}`, `onesy-ImageGallery-size-${size}`], className, classes.root, classes[`version_${version}`]]) }, other), {}, { children: main })); } return /*#__PURE__*/(0, _jsxRuntime.jsx)(Backdrop, _objectSpread(_objectSpread({ ref: item_2 => { if (ref) { if ((0, _utils.is)('function', ref)) ref(item_2);else ref.current = item_2; } refs.root.current = item_2; }, open: open, onClose: onClose, className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-root', `onesy-ImageGallery-version-${version}`], className, classes.root, classes[`version_${version}`]]) }, other), {}, { children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Line, { gap: 0, fullWidth: true, className: classes.wrapper, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Line, { direction: "row", justify: "flex-end", fullWidth: true, className: (0, _styleReact.classNames)([(0, _utils2.staticClassName)('ImageGallery', theme) && ['onesy-ImageGallery-header'], classes.header]), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconButton, { version: "filled", color: theme.palette.light ? 'default' : 'inverted', onClick: onClose, className: (0, _styleReact.classNames)([classes.pointerEventsAuto]), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconClose, {}) }) }), main] }) })); }; ImageGallery.displayName = 'onesy-ImageGallery'; var _default = exports.default = ImageGallery;