UNPKG

wix-style-react

Version:
618 lines (615 loc) 22.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _wixUiIconsCommon = require("@wix/wix-ui-icons-common"); var _StatusIndicator = _interopRequireDefault(require("../StatusIndicator")); var _Loader = _interopRequireDefault(require("../Loader")); var _ImageViewerSt = require("./ImageViewer.st.css"); var _Tooltip = _interopRequireDefault(require("../Tooltip")); var _IconButton = _interopRequireDefault(require("../IconButton")); var _AddItem = _interopRequireDefault(require("../AddItem/AddItem")); var _Box = _interopRequireDefault(require("../Box")); var _PopoverMenu = _interopRequireDefault(require("../PopoverMenu")); var _classnames = _interopRequireDefault(require("classnames")); var _constants = require("./constants"); var _TooltipCommon = require("../common/PropTypes/TooltipCommon"); var _StatusContext = require("../FormField/StatusContext"); var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/ImageViewer/ImageViewer.js"; function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } 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; } class ImageViewer extends _react.Component { constructor(props) { super(props); this._renderAddImage = () => { var { onAddImage, addImageInfo, tooltipProps = {}, disabled } = this.props; return /*#__PURE__*/_react.default.createElement(_AddItem.default, { ref: this.focusNode, onClick: onAddImage, theme: "image", dataHook: _constants.dataHooks.addItem, disabled: disabled, tooltipProps: _objectSpread(_objectSpread({}, tooltipProps), {}, { content: addImageInfo }), ariaLabel: addImageInfo, __self: this, __source: { fileName: _jsxFileName, lineNumber: 56, columnNumber: 7 } }); }; /** `display: none` is used to prefetch an image == it fetches the image but doesn't show it */ this._renderImageElement = _ref => { var { imageUrl, shouldDisplay, onLoad, onError, key, dataHook } = _ref; var dataAttributes = { 'data-hook': dataHook, 'data-image-visible': shouldDisplay }; return /*#__PURE__*/_react.default.createElement("img", (0, _extends2.default)({ className: (0, _classnames.default)([_ImageViewerSt.classes.image, _ImageViewerSt.classes.stretch, shouldDisplay && _ImageViewerSt.classes.imageVisible]), src: imageUrl, onLoad: onLoad, onError: onError, key: key }, dataAttributes, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 83, columnNumber: 7 } })); }; this._resetImageLoading = () => { this.setState({ imageLoading: false }); }; this._onImageLoad = e => { var { onImageLoad } = this.props; this.setState({ imageLoading: false }, () => onImageLoad(e)); }; this._getCurrentAndPreviousImages = () => { var { imageUrl: currentImageUrl } = this.props; var { previousImageUrl } = this.state; return { currentImageUrl, previousImageUrl }; }; this._renderImage = () => { var { imageLoading } = this.state; if (!this.props.imageUrl) { return; } var { currentImageUrl, previousImageUrl } = this._getCurrentAndPreviousImages(); var shouldDisplayContainer = !!(currentImageUrl || previousImageUrl); var generateKey = (imageName, imageUrl) => "".concat(imageName, "-").concat(imageUrl); return /*#__PURE__*/_react.default.createElement("div", { className: (0, _ImageViewerSt.st)(_ImageViewerSt.classes.imageContainer, { /** hide container when no image provided, so AddItem behind it can be clickable */ shouldDisplay: shouldDisplayContainer }), "data-container-visible": shouldDisplayContainer, "data-hook": _constants.dataHooks.imagesContainer, __self: this, __source: { fileName: _jsxFileName, lineNumber: 137, columnNumber: 7 } }, this._renderImageElement({ imageUrl: currentImageUrl, shouldDisplay: !!currentImageUrl && !imageLoading, onLoad: this._onImageLoad, onError: () => { this._resetImageLoading(); }, dataHook: _constants.dataHooks.image, key: generateKey(_constants.dataHooks.image, currentImageUrl) }), this._renderImageElement({ imageUrl: previousImageUrl, shouldDisplay: imageLoading && !!previousImageUrl, dataHook: _constants.dataHooks.previousImage, key: generateKey(_constants.dataHooks.previousImage, previousImageUrl) })); }; this._renderUpdateButton = ref => { var { updateImageInfo, onUpdateImage, tooltipProps } = this.props; return /*#__PURE__*/_react.default.createElement(_Tooltip.default, (0, _extends2.default)({}, tooltipProps, { timeout: 0, dataHook: _constants.dataHooks.updateTooltip, content: updateImageInfo, __self: this, __source: { fileName: _jsxFileName, lineNumber: 172, columnNumber: 7 } }), /*#__PURE__*/_react.default.createElement(_IconButton.default, { ref: ref, dataHook: _constants.dataHooks.update, onClick: onUpdateImage, skin: "light", priority: "secondary", __self: this, __source: { fileName: _jsxFileName, lineNumber: 178, columnNumber: 9 } }, /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.Replace, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 185, columnNumber: 11 } }))); }; this._resetPreviousImage = () => this.setState({ previousImageUrl: undefined }); this._renderRemoveButton = ref => { var { removeImageInfo, onRemoveImage, tooltipProps } = this.props; return /*#__PURE__*/_react.default.createElement(_Tooltip.default, (0, _extends2.default)({}, tooltipProps, { timeout: 0, dataHook: _constants.dataHooks.removeTooltip, content: removeImageInfo, __self: this, __source: { fileName: _jsxFileName, lineNumber: 196, columnNumber: 7 } }), /*#__PURE__*/_react.default.createElement(_IconButton.default, { ref: ref, dataHook: _constants.dataHooks.remove, skin: "light", priority: "secondary", onClick: e => { this._resetPreviousImage(); onRemoveImage && onRemoveImage(e); }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 202, columnNumber: 9 } }, /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.Delete, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 212, columnNumber: 11 } }))); }; this._renderDownloadButton = ref => { var { downloadImageInfo, onDownloadImage, tooltipProps } = this.props; return /*#__PURE__*/_react.default.createElement(_Tooltip.default, (0, _extends2.default)({}, tooltipProps, { timeout: 0, dataHook: _constants.dataHooks.downloadTooltip, content: downloadImageInfo, __self: this, __source: { fileName: _jsxFileName, lineNumber: 221, columnNumber: 7 } }), /*#__PURE__*/_react.default.createElement(_IconButton.default, { ref: ref, dataHook: _constants.dataHooks.download, skin: "light", priority: "secondary", onClick: e => { onDownloadImage && onDownloadImage(e); }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 227, columnNumber: 9 } }, /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.Download, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 236, columnNumber: 11 } }))); }; this._hidePopover = () => this.setState({ popoverOpen: false }); this._showPopover = () => this.setState({ popoverOpen: true }); this._renderMoreButton = () => { var { tooltipProps, moreImageInfo, downloadImageInfo, onDownloadImage, removeImageInfo, onRemoveImage } = this.props; return /*#__PURE__*/_react.default.createElement(_PopoverMenu.default, { dataHook: _constants.dataHooks.actionsMenu, onHide: this._hidePopover, onShow: this._showPopover, triggerElement: _ref2 => { var { toggle } = _ref2; return /*#__PURE__*/_react.default.createElement(_Tooltip.default, (0, _extends2.default)({}, tooltipProps, { timeout: 0, dataHook: _constants.dataHooks.moreTooltip, content: moreImageInfo, __self: this, __source: { fileName: _jsxFileName, lineNumber: 261, columnNumber: 11 } }), /*#__PURE__*/_react.default.createElement(_IconButton.default, { onClick: toggle, dataHook: _constants.dataHooks.more, skin: "light", priority: this.state.popoverOpen ? 'primary' : 'secondary', __self: this, __source: { fileName: _jsxFileName, lineNumber: 267, columnNumber: 13 } }, /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.More, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 273, columnNumber: 15 } }))); }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 256, columnNumber: 7 } }, /*#__PURE__*/_react.default.createElement(_PopoverMenu.default.MenuItem, { prefixIcon: /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.Download, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 279, columnNumber: 23 } }), text: downloadImageInfo, onClick: onDownloadImage, __self: this, __source: { fileName: _jsxFileName, lineNumber: 278, columnNumber: 9 } }), /*#__PURE__*/_react.default.createElement(_PopoverMenu.default.MenuItem, { prefixIcon: /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.Delete, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 284, columnNumber: 23 } }), text: removeImageInfo, onClick: onRemoveImage, __self: this, __source: { fileName: _jsxFileName, lineNumber: 283, columnNumber: 9 } })); }; this._renderFirstButton = () => { var { showUpdateButton, showRemoveButton, showDownloadButton } = this.props; if (showUpdateButton) return this._renderUpdateButton(this.focusNode); if (showDownloadButton) return this._renderDownloadButton(this.focusNode); if (showRemoveButton) return this._renderRemoveButton(this.focusNode); return null; }; this._renderSecondButton = () => { var { showUpdateButton, showRemoveButton, showDownloadButton } = this.props; // All three options - show more button if (showUpdateButton && showDownloadButton && showRemoveButton) { return this._renderMoreButton(); } // Two options - show second button if (showUpdateButton && showRemoveButton) return this._renderRemoveButton(); if (showUpdateButton && showDownloadButton) return this._renderDownloadButton(); if (showDownloadButton && showRemoveButton) return this._renderRemoveButton(); return null; }; this._renderLoader = () => /*#__PURE__*/_react.default.createElement(_Box.default, { align: "center", verticalAlign: "middle", height: "100%", dataHook: _constants.dataHooks.loader, __self: this, __source: { fileName: _jsxFileName, lineNumber: 323, columnNumber: 5 } }, /*#__PURE__*/_react.default.createElement(_Loader.default, { size: "small", __self: this, __source: { fileName: _jsxFileName, lineNumber: 329, columnNumber: 7 } })); this._renderButtons = () => { return /*#__PURE__*/_react.default.createElement("div", { className: _ImageViewerSt.classes.buttons, __self: this, __source: { fileName: _jsxFileName, lineNumber: 335, columnNumber: 7 } }, this._renderFirstButton(), this._renderSecondButton()); }; this._renderOverlayWith = content => { var { removeRoundedBorders } = this.props; var { currentImageUrl, previousImageUrl } = this._getCurrentAndPreviousImages(); var shouldDisplayOverlay = !!(currentImageUrl || previousImageUrl); return /*#__PURE__*/_react.default.createElement("div", { className: (0, _ImageViewerSt.st)(_ImageViewerSt.classes.overlay, { removeRadius: removeRoundedBorders, shouldDisplay: shouldDisplayOverlay }), "data-remove-radius": removeRoundedBorders, "data-hook": _constants.dataHooks.overlay, __self: this, __source: { fileName: _jsxFileName, lineNumber: 351, columnNumber: 7 } }, content, /*#__PURE__*/_react.default.createElement("span", { __self: this, __source: { fileName: _jsxFileName, lineNumber: 360, columnNumber: 9 } })); }; /** * Sets focus on the element */ this.focus = () => { this.focusNode.current && this.focusNode.current.focus(); }; var { imageUrl: _imageUrl } = props; this.focusNode = /*#__PURE__*/_react.default.createRef(); this.state = { imageLoading: !!_imageUrl, previousImageUrl: undefined, popoverOpen: false }; } UNSAFE_componentWillReceiveProps(nextProps) { var { imageUrl: currentImageUrl } = this.props; var { imageUrl: nextImageUrl } = nextProps; if (nextImageUrl && currentImageUrl !== nextImageUrl) { this.setState({ imageLoading: true, previousImageUrl: currentImageUrl }); } } render() { var { width, height, disabled, dataHook, removeRoundedBorders, imageUrl, status, statusMessage, className } = this.props; var { imageLoading, previousImageUrl, popoverOpen } = this.state; var finalStatus = (0, _StatusContext.getStatusFromContext)(this.context, status); var hasImage = !!imageUrl; var hasNoPreviousImageWhileLoading = imageLoading && !previousImageUrl; var imageLoaded = hasImage && !imageLoading; var cssStates = { disabled, status: !disabled && finalStatus, removeRadius: removeRoundedBorders, hasImage, popoverOpen }; var rootDataAttributes = { 'data-disabled': disabled, 'data-image-loaded': imageLoaded, 'data-hook': dataHook }; return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({ className: (0, _ImageViewerSt.st)(_ImageViewerSt.classes.root, cssStates, className), style: { width, height } }, rootDataAttributes, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 406, columnNumber: 7 } }), (hasNoPreviousImageWhileLoading || !hasImage) && this._renderAddImage(), this._renderImage(), !disabled && this._renderOverlayWith(imageLoading ? this._renderLoader() : hasImage && this._renderButtons()), (status || finalStatus === 'loading') && !disabled && /*#__PURE__*/_react.default.createElement("div", { className: _ImageViewerSt.classes.statusContainer, __self: this, __source: { fileName: _jsxFileName, lineNumber: 425, columnNumber: 11 } }, /*#__PURE__*/_react.default.createElement(_StatusIndicator.default, { status: finalStatus, message: statusMessage, dataHook: _constants.dataHooks.errorTooltip, __self: this, __source: { fileName: _jsxFileName, lineNumber: 426, columnNumber: 13 } }))); } } ImageViewer.contextType = _StatusContext.StatusContext; ImageViewer.displayName = 'ImageViewer'; ImageViewer.defaultProps = { showUpdateButton: true, showDownloadButton: false, showRemoveButton: true, addImageInfo: 'Add Image', updateImageInfo: 'Update', downloadImageInfo: 'Download', removeImageInfo: 'Remove', moreImageInfo: 'More actions', onImageLoad: () => ({}) }; ImageViewer.propTypes = { /** Applies a data-hook HTML attribute that can be used in the tests. */ dataHook: _propTypes.default.string, /** Specifies a CSS class name to be appended to the component’s root element. */ className: _propTypes.default.string, /** Links to image asset source (URL). Leave it blank when image is not uploaded yet. */ imageUrl: _propTypes.default.string, /** Specifies the status of a viewer. */ status: _propTypes.default.oneOf(['error', 'warning', 'loading']), /** Defines the message to display on status icon hover. If not given or empty there will be no tooltip. */ statusMessage: _propTypes.default.node, /** Allows to pass all common tooltip props. * @linkTypeTo components-overlays--tooltip * @setTypeName TooltipCommonProps */ tooltipProps: _propTypes.default.shape(_TooltipCommon.TooltipCommonProps), /** Specifies whether the update button is visible. */ showUpdateButton: _propTypes.default.bool, /** Specifies whether the download button is visible. */ showDownloadButton: _propTypes.default.bool, /** Specifies whether the remove button is visible. */ showRemoveButton: _propTypes.default.bool, /** Defines a click handler, which is called every time a user clicks on an empty viewer (when no `imageUrl` is provided). */ onAddImage: _propTypes.default.func, /** Defines a handler function, which is called every time user clicks on the ‘Update image’ button. */ onUpdateImage: _propTypes.default.func, /** Defines a handler function, which is called every time user clicks on the download button. */ onDownloadImage: _propTypes.default.func, /** Defines a handler function, which is called every time user clicks on the ‘Remove image’ button. */ onRemoveImage: _propTypes.default.func, /** Defines a handler function which is called right after image loads. */ onImageLoad: _propTypes.default.func, /** Specifies a message to display in a tooltip when no image is uploaded yet. */ addImageInfo: _propTypes.default.string, /** Defines a message to display in a tooltip when ‘Update’ action button is hovered. */ updateImageInfo: _propTypes.default.string, /** Defines a message to display in a tooltip when ‘Download’ action button is hovered. */ downloadImageInfo: _propTypes.default.string, /** Defines a message to display in a tooltip, when ‘remove’ action button is hovered. */ removeImageInfo: _propTypes.default.string, /** Defines a message to display in a tooltip when the ‘More’ action button is hovered. Relevant only when all buttons are visible. */ moreImageInfo: _propTypes.default.string, /** Removes default border radius. */ removeRoundedBorders: _propTypes.default.bool, /** Sets the width of the viewer box. */ width: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]), /** Sets the height of the viewer box. */ height: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]), /** Specifies whether the component is disabled. */ disabled: _propTypes.default.bool }; var _default = exports.default = ImageViewer; //# sourceMappingURL=ImageViewer.js.map