UNPKG

@cainiaofe/cn-ui-m

Version:
106 lines (105 loc) 4.71 kB
import { __assign } from "tslib"; import React, { memo, useRef, useState } from 'react'; import classNames from 'classnames'; import { useTimeout } from 'ahooks'; import { CnIcon } from '../cn-icon'; import { withNativeProps } from "../../utils/with-native-props"; import { useResizeEffect } from '../../hooks/use-resize-effect'; import { useMutationEffect } from '../../hooks/use-mutation-effect'; var clsPrefix = 'cn-ui-m-notice'; var iconTypeMap = { notice: 'horn-fill', warning: 'exclamation-t-fill', success: 'complete-r-fill', error: 'error-r-fill', help: 'exclamation-r-fill', }; var defaultProps = { type: 'notice', delay: 2000, speed: 50, closeable: false, overflowStyle: 'scroll', icon: React.createElement(CnIcon, { type: "horn-fill" }), }; // eslint-disable-next-line react/display-name export var CnNotice = memo(function (p) { var _a; var _b; var props = __assign(__assign(__assign({}, defaultProps), { icon: React.createElement(CnIcon, { type: iconTypeMap[(_b = p.type) !== null && _b !== void 0 ? _b : 'notice'] }) }), p); var containerRef = useRef(null); var textRef = useRef(null); var _c = useState(true), visible = _c[0], setVisible = _c[1]; var speed = props.speed, overflowStyle = props.overflowStyle, onClick = props.onClick; var delayLockRef = useRef(true); var animatingRef = useRef(false); function start() { if (overflowStyle === 'hidden') { return; } if (delayLockRef.current) return; var container = containerRef.current; var text = textRef.current; if (!container || !text) return; if (container.offsetWidth >= text.offsetWidth) { animatingRef.current = false; text.style.removeProperty('transition-duration'); text.style.removeProperty('transform'); return; } if (animatingRef.current) return; var initial = !text.style.transform; text.style.transitionDuration = '0s'; if (initial) { text.style.transform = 'translateX(0)'; } else { text.style.transform = "translateX(".concat(container.offsetWidth, "px)"); } var distance = initial ? text.offsetWidth : container.offsetWidth + text.offsetWidth; animatingRef.current = true; text.style.transitionDuration = "".concat(Math.round(distance / speed), "s"); text.style.transform = "translateX(-".concat(text.offsetWidth, "px)"); } useResizeEffect(function () { start(); }, containerRef); useTimeout(function () { delayLockRef.current = false; start(); }, props.delay); useMutationEffect(function () { start(); }, textRef, { subtree: true, childList: true, characterData: true, }); if (!visible) return null; return withNativeProps(props, React.createElement("div", { className: classNames(CN_UI_HASH_CLASS_NAME, clsPrefix, "".concat(clsPrefix, "-").concat(props.type), "".concat(clsPrefix, "-").concat(overflowStyle)), onClick: onClick }, props.icon && React.createElement("span", { className: "".concat(clsPrefix, "-left") }, props.icon), React.createElement("span", { ref: containerRef, className: "".concat(clsPrefix, "-content") }, React.createElement("span", { onTransitionEnd: function () { animatingRef.current = false; start(); }, ref: textRef, className: "".concat(clsPrefix, "-content-inner") }, props.content)), overflowStyle === 'hidden' ? (React.createElement(CnIcon, { type: "triangle-right-fill", size: "small", outerClassName: classNames("".concat(clsPrefix, "-action")) })) : null, (props.closeable || props.extra) && (React.createElement("span", { className: classNames("".concat(clsPrefix, "-right"), (_a = {}, _a["".concat(clsPrefix, "-right-with-icon")] = overflowStyle === 'hidden', _a)) }, props.extra, props.closeable && (React.createElement("div", { className: "".concat(clsPrefix, "-close"), onClick: function (event) { var _a; setVisible(false); (_a = props.onClose) === null || _a === void 0 ? void 0 : _a.call(props); event.stopPropagation(); }, "data-testid": "cn-notice-close-button" }, React.createElement(CnIcon, { type: "close", size: "small", className: classNames("".concat(clsPrefix, "-close")) }))))))); }); CnNotice.displayName = 'CnNotice';