wix-style-react
Version:
271 lines (235 loc) • 9.34 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
import React, { Children } from 'react';
import PropTypes from 'prop-types';
import { Animator } from 'wix-animations';
import CloseButton from '../CloseButton';
import TextLabel from './TextLabel';
import ActionButton from './ActionButton';
import { st, classes } from './Notification.st.css';
import StatusComplete from 'wix-ui-icons-common/StatusComplete';
import StatusWarning from 'wix-ui-icons-common/StatusWarning';
import StatusAlert from 'wix-ui-icons-common/StatusAlert';
import { dataHooks } from './constants';
export var LOCAL_NOTIFICATION = 'local';
export var GLOBAL_NOTIFICATION = 'global';
export var STICKY_NOTIFICATION = 'sticky';
export var DEFAULT_AUTO_HIDE_TIMEOUT = 6000;
export var DEFAULT_TIMEOUT = DEFAULT_AUTO_HIDE_TIMEOUT;
var animationsTimeouts = {
enter: 300,
exit: 300
};
var themeIcon = {
error: /*#__PURE__*/React.createElement(StatusAlert, {
className: classes.iconStyling
}),
success: /*#__PURE__*/React.createElement(StatusComplete, {
className: classes.iconStyling
}),
warning: /*#__PURE__*/React.createElement(StatusWarning, {
className: classes.iconStyling
})
};
function mapChildren(children) {
var childrenArray = Children.toArray(children);
return childrenArray.reduce(function (childrenAsMap, child) {
switch (child.type.displayName) {
case 'Notification.TextLabel':
childrenAsMap.label = child;
break;
case 'Notification.ActionButton':
childrenAsMap.ctaButton = child;
break;
case 'Notification.CloseButton':
childrenAsMap.closeButton = /*#__PURE__*/React.cloneElement(child, {
size: 'small'
});
break;
}
return childrenAsMap;
}, {});
}
var heightCalculation = function heightCalculation(element) {
var height = element.firstChild.offsetHeight;
element.style.height = "".concat(height, "px");
return height;
};
var Notification = /*#__PURE__*/function (_React$PureComponent) {
_inherits(Notification, _React$PureComponent);
var _super = _createSuper(Notification);
function Notification() {
var _this;
_classCallCheck(this, Notification);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call.apply(_super, [this].concat(args));
_defineProperty(_assertThisInitialized(_this), "closeTimeout", void 0);
_defineProperty(_assertThisInitialized(_this), "state", {
hideByCloseClick: false,
hideByTimer: false
});
_defineProperty(_assertThisInitialized(_this), "_hideNotificationOnCloseClick", function () {
_this.setState({
hideByCloseClick: true
});
setTimeout(function () {
return _this.props.onClose && _this.props.onClose('hide-by-close-click');
}, animationsTimeouts.exit + 100);
});
_defineProperty(_assertThisInitialized(_this), "_hideNotificationOnTimeout", function () {
_this.setState({
hideByTimer: true
});
setTimeout(function () {
return _this.props.onClose && _this.props.onClose('hide-by-timer');
}, animationsTimeouts.exit + 100);
});
return _this;
}
_createClass(Notification, [{
key: "UNSAFE_componentWillReceiveProps",
value: function UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.show) {
this._bypassCloseFlags();
this._clearCloseTimeout();
this._startCloseTimer(nextProps);
}
}
}, {
key: "componentDidMount",
value: function componentDidMount() {
this._startCloseTimer(this.props);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this._clearCloseTimeout();
}
}, {
key: "_startCloseTimer",
value: function _startCloseTimer(_ref) {
var _this2 = this;
var autoHideTimeout = _ref.autoHideTimeout;
if (autoHideTimeout) {
this.closeTimeout = setTimeout(function () {
return _this2._hideNotificationOnTimeout();
}, autoHideTimeout || DEFAULT_AUTO_HIDE_TIMEOUT);
}
}
}, {
key: "_clearCloseTimeout",
value: function _clearCloseTimeout() {
if (this.closeTimeout) {
clearTimeout(this.closeTimeout);
this.closeTimeout = null;
}
}
}, {
key: "_bypassCloseFlags",
value: function _bypassCloseFlags() {
this.setState({
hideByCloseClick: false,
hideByTimer: false
});
}
}, {
key: "_shouldShowNotification",
value: function _shouldShowNotification() {
return this.props.show && !this.state.hideByCloseClick && !this.state.hideByTimer;
}
}, {
key: "render",
value: function render() {
var _this$props = this.props,
dataHook = _this$props.dataHook,
theme = _this$props.theme,
type = _this$props.type,
zIndex = _this$props.zIndex,
children = _this$props.children;
var childrenComponents = mapChildren(children);
var show = this._shouldShowNotification();
return /*#__PURE__*/React.createElement("div", {
className: st(classes.root, {
theme: theme,
type: type
}),
style: {
zIndex: zIndex
},
"data-hook": dataHook,
"data-theme": theme,
"data-type": type
}, /*#__PURE__*/React.createElement(Animator, {
show: show,
className: classes.animator,
childClassName: classes.animatorContent,
timing: "medium",
height: heightCalculation
}, /*#__PURE__*/React.createElement("div", {
className: classes.wrapper
}, /*#__PURE__*/React.createElement("div", {
"data-hook": dataHooks.notificationContent,
className: classes.notification,
role: "alert",
"aria-labelledby": "notification-label",
"aria-live": "polite"
}, themeIcon[theme] && /*#__PURE__*/React.createElement("div", null, themeIcon[theme]), /*#__PURE__*/React.createElement("div", {
className: classes.labelWrapper
}, childrenComponents.label, childrenComponents.ctaButton), childrenComponents.closeButton && /*#__PURE__*/React.createElement("div", {
"data-hook": dataHooks.notificationCloseButton,
className: classes.closeButton,
onClick: this._hideNotificationOnCloseClick,
children: childrenComponents.closeButton
})))));
}
}]);
return Notification;
}(React.PureComponent);
var Close = function Close(props) {
return /*#__PURE__*/React.createElement(CloseButton, _extends({
skin: "lightFilled"
}, props));
};
Close.displayName = 'Notification.CloseButton';
Notification.displayName = 'Notification';
Notification.propTypes = {
/** when set to `true`, notification is shown */
show: PropTypes.bool,
/** Notification theme */
theme: PropTypes.oneOf(['standard', 'error', 'success', 'warning', 'premium']),
/** Sets how <Notification/> should be displayed:
* - `type="global"` will take up space and push the content down.
* - `type="local"` will not take up space and will be displayed on top of content
* - `type="sticky"` will not take up space and will be displayed at the top of whole page and on top of content (position: fixed;)
* */
type: PropTypes.oneOf([GLOBAL_NOTIFICATION, LOCAL_NOTIFICATION, STICKY_NOTIFICATION]),
/** When provided, then the Notification will be hidden after the specified timeout. */
autoHideTimeout: PropTypes.number,
/** Notification z-index */
zIndex: PropTypes.number,
onClose: PropTypes.func,
/** Can be either:
* - `<Notification.TextLabel/>` (required)
* - `<Notification.CloseButton/>`
* - `<Notification.ActionButton/>` */
children: PropTypes.node
};
Notification.defaultProps = {
theme: 'standard',
type: GLOBAL_NOTIFICATION,
onClose: null
};
Notification.CloseButton = Close;
Notification.TextLabel = TextLabel;
Notification.ActionButton = ActionButton;
export default Notification;