Alert.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. "use client";
  2. var __rest = this && this.__rest || function (s, e) {
  3. var t = {};
  4. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  5. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  6. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  7. }
  8. return t;
  9. };
  10. import * as React from 'react';
  11. import CheckCircleFilled from "@ant-design/icons/es/icons/CheckCircleFilled";
  12. import CloseCircleFilled from "@ant-design/icons/es/icons/CloseCircleFilled";
  13. import CloseOutlined from "@ant-design/icons/es/icons/CloseOutlined";
  14. import ExclamationCircleFilled from "@ant-design/icons/es/icons/ExclamationCircleFilled";
  15. import InfoCircleFilled from "@ant-design/icons/es/icons/InfoCircleFilled";
  16. import classNames from 'classnames';
  17. import CSSMotion from 'rc-motion';
  18. import pickAttrs from "rc-util/es/pickAttrs";
  19. import { composeRef } from "rc-util/es/ref";
  20. import { replaceElement } from '../_util/reactNode';
  21. import { devUseWarning } from '../_util/warning';
  22. import { useComponentConfig } from '../config-provider/context';
  23. import useStyle from './style';
  24. const iconMapFilled = {
  25. success: CheckCircleFilled,
  26. info: InfoCircleFilled,
  27. error: CloseCircleFilled,
  28. warning: ExclamationCircleFilled
  29. };
  30. const IconNode = props => {
  31. const {
  32. icon,
  33. prefixCls,
  34. type
  35. } = props;
  36. const iconType = iconMapFilled[type] || null;
  37. if (icon) {
  38. return replaceElement(icon, /*#__PURE__*/React.createElement("span", {
  39. className: `${prefixCls}-icon`
  40. }, icon), () => ({
  41. className: classNames(`${prefixCls}-icon`, icon.props.className)
  42. }));
  43. }
  44. return /*#__PURE__*/React.createElement(iconType, {
  45. className: `${prefixCls}-icon`
  46. });
  47. };
  48. const CloseIconNode = props => {
  49. const {
  50. isClosable,
  51. prefixCls,
  52. closeIcon,
  53. handleClose,
  54. ariaProps
  55. } = props;
  56. const mergedCloseIcon = closeIcon === true || closeIcon === undefined ? /*#__PURE__*/React.createElement(CloseOutlined, null) : closeIcon;
  57. return isClosable ? (/*#__PURE__*/React.createElement("button", Object.assign({
  58. type: "button",
  59. onClick: handleClose,
  60. className: `${prefixCls}-close-icon`,
  61. tabIndex: 0
  62. }, ariaProps), mergedCloseIcon)) : null;
  63. };
  64. const Alert = /*#__PURE__*/React.forwardRef((props, ref) => {
  65. const {
  66. description,
  67. prefixCls: customizePrefixCls,
  68. message,
  69. banner,
  70. className,
  71. rootClassName,
  72. style,
  73. onMouseEnter,
  74. onMouseLeave,
  75. onClick,
  76. afterClose,
  77. showIcon,
  78. closable,
  79. closeText,
  80. closeIcon,
  81. action,
  82. id
  83. } = props,
  84. otherProps = __rest(props, ["description", "prefixCls", "message", "banner", "className", "rootClassName", "style", "onMouseEnter", "onMouseLeave", "onClick", "afterClose", "showIcon", "closable", "closeText", "closeIcon", "action", "id"]);
  85. const [closed, setClosed] = React.useState(false);
  86. if (process.env.NODE_ENV !== 'production') {
  87. const warning = devUseWarning('Alert');
  88. warning.deprecated(!closeText, 'closeText', 'closable.closeIcon');
  89. }
  90. const internalRef = React.useRef(null);
  91. React.useImperativeHandle(ref, () => ({
  92. nativeElement: internalRef.current
  93. }));
  94. const {
  95. getPrefixCls,
  96. direction,
  97. closable: contextClosable,
  98. closeIcon: contextCloseIcon,
  99. className: contextClassName,
  100. style: contextStyle
  101. } = useComponentConfig('alert');
  102. const prefixCls = getPrefixCls('alert', customizePrefixCls);
  103. const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
  104. const handleClose = e => {
  105. var _a;
  106. setClosed(true);
  107. (_a = props.onClose) === null || _a === void 0 ? void 0 : _a.call(props, e);
  108. };
  109. const type = React.useMemo(() => {
  110. if (props.type !== undefined) {
  111. return props.type;
  112. }
  113. // banner mode defaults to 'warning'
  114. return banner ? 'warning' : 'info';
  115. }, [props.type, banner]);
  116. // closeable when closeText or closeIcon is assigned
  117. const isClosable = React.useMemo(() => {
  118. if (typeof closable === 'object' && closable.closeIcon) return true;
  119. if (closeText) {
  120. return true;
  121. }
  122. if (typeof closable === 'boolean') {
  123. return closable;
  124. }
  125. // should be true when closeIcon is 0 or ''
  126. if (closeIcon !== false && closeIcon !== null && closeIcon !== undefined) {
  127. return true;
  128. }
  129. return !!contextClosable;
  130. }, [closeText, closeIcon, closable, contextClosable]);
  131. // banner mode defaults to Icon
  132. const isShowIcon = banner && showIcon === undefined ? true : showIcon;
  133. const alertCls = classNames(prefixCls, `${prefixCls}-${type}`, {
  134. [`${prefixCls}-with-description`]: !!description,
  135. [`${prefixCls}-no-icon`]: !isShowIcon,
  136. [`${prefixCls}-banner`]: !!banner,
  137. [`${prefixCls}-rtl`]: direction === 'rtl'
  138. }, contextClassName, className, rootClassName, cssVarCls, hashId);
  139. const restProps = pickAttrs(otherProps, {
  140. aria: true,
  141. data: true
  142. });
  143. const mergedCloseIcon = React.useMemo(() => {
  144. if (typeof closable === 'object' && closable.closeIcon) {
  145. return closable.closeIcon;
  146. }
  147. if (closeText) {
  148. return closeText;
  149. }
  150. if (closeIcon !== undefined) {
  151. return closeIcon;
  152. }
  153. if (typeof contextClosable === 'object' && contextClosable.closeIcon) {
  154. return contextClosable.closeIcon;
  155. }
  156. return contextCloseIcon;
  157. }, [closeIcon, closable, closeText, contextCloseIcon]);
  158. const mergedAriaProps = React.useMemo(() => {
  159. const merged = closable !== null && closable !== void 0 ? closable : contextClosable;
  160. if (typeof merged === 'object') {
  161. const {
  162. closeIcon: _
  163. } = merged,
  164. ariaProps = __rest(merged, ["closeIcon"]);
  165. return ariaProps;
  166. }
  167. return {};
  168. }, [closable, contextClosable]);
  169. return wrapCSSVar(/*#__PURE__*/React.createElement(CSSMotion, {
  170. visible: !closed,
  171. motionName: `${prefixCls}-motion`,
  172. motionAppear: false,
  173. motionEnter: false,
  174. onLeaveStart: node => ({
  175. maxHeight: node.offsetHeight
  176. }),
  177. onLeaveEnd: afterClose
  178. }, ({
  179. className: motionClassName,
  180. style: motionStyle
  181. }, setRef) => (/*#__PURE__*/React.createElement("div", Object.assign({
  182. id: id,
  183. ref: composeRef(internalRef, setRef),
  184. "data-show": !closed,
  185. className: classNames(alertCls, motionClassName),
  186. style: Object.assign(Object.assign(Object.assign({}, contextStyle), style), motionStyle),
  187. onMouseEnter: onMouseEnter,
  188. onMouseLeave: onMouseLeave,
  189. onClick: onClick,
  190. role: "alert"
  191. }, restProps), isShowIcon ? (/*#__PURE__*/React.createElement(IconNode, {
  192. description: description,
  193. icon: props.icon,
  194. prefixCls: prefixCls,
  195. type: type
  196. })) : null, /*#__PURE__*/React.createElement("div", {
  197. className: `${prefixCls}-content`
  198. }, message ? /*#__PURE__*/React.createElement("div", {
  199. className: `${prefixCls}-message`
  200. }, message) : null, description ? /*#__PURE__*/React.createElement("div", {
  201. className: `${prefixCls}-description`
  202. }, description) : null), action ? /*#__PURE__*/React.createElement("div", {
  203. className: `${prefixCls}-action`
  204. }, action) : null, /*#__PURE__*/React.createElement(CloseIconNode, {
  205. isClosable: isClosable,
  206. prefixCls: prefixCls,
  207. closeIcon: mergedCloseIcon,
  208. handleClose: handleClose,
  209. ariaProps: mergedAriaProps
  210. })))));
  211. });
  212. if (process.env.NODE_ENV !== 'production') {
  213. Alert.displayName = 'Alert';
  214. }
  215. export default Alert;