index.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import { withDirectives as _withDirectives, vShow as _vShow, createVNode as _createVNode } from "vue";
  3. import { computed, defineComponent, shallowRef } from 'vue';
  4. import CloseOutlined from "@ant-design/icons-vue/es/icons/CloseOutlined";
  5. import CheckCircleOutlined from "@ant-design/icons-vue/es/icons/CheckCircleOutlined";
  6. import ExclamationCircleOutlined from "@ant-design/icons-vue/es/icons/ExclamationCircleOutlined";
  7. import InfoCircleOutlined from "@ant-design/icons-vue/es/icons/InfoCircleOutlined";
  8. import CloseCircleOutlined from "@ant-design/icons-vue/es/icons/CloseCircleOutlined";
  9. import CheckCircleFilled from "@ant-design/icons-vue/es/icons/CheckCircleFilled";
  10. import ExclamationCircleFilled from "@ant-design/icons-vue/es/icons/ExclamationCircleFilled";
  11. import InfoCircleFilled from "@ant-design/icons-vue/es/icons/InfoCircleFilled";
  12. import CloseCircleFilled from "@ant-design/icons-vue/es/icons/CloseCircleFilled";
  13. import classNames from '../_util/classNames';
  14. import PropTypes from '../_util/vue-types';
  15. import { getTransitionProps, Transition } from '../_util/transition';
  16. import { isValidElement } from '../_util/props-util';
  17. import { tuple, withInstall } from '../_util/type';
  18. import { cloneElement } from '../_util/vnode';
  19. import useConfigInject from '../config-provider/hooks/useConfigInject';
  20. import useStyle from './style';
  21. const iconMapFilled = {
  22. success: CheckCircleFilled,
  23. info: InfoCircleFilled,
  24. error: CloseCircleFilled,
  25. warning: ExclamationCircleFilled
  26. };
  27. const iconMapOutlined = {
  28. success: CheckCircleOutlined,
  29. info: InfoCircleOutlined,
  30. error: CloseCircleOutlined,
  31. warning: ExclamationCircleOutlined
  32. };
  33. const AlertTypes = tuple('success', 'info', 'warning', 'error');
  34. export const alertProps = () => ({
  35. /**
  36. * Type of Alert styles, options: `success`, `info`, `warning`, `error`
  37. */
  38. type: PropTypes.oneOf(AlertTypes),
  39. /** Whether Alert can be closed */
  40. closable: {
  41. type: Boolean,
  42. default: undefined
  43. },
  44. /** Close text to show */
  45. closeText: PropTypes.any,
  46. /** Content of Alert */
  47. message: PropTypes.any,
  48. /** Additional content of Alert */
  49. description: PropTypes.any,
  50. /** Trigger when animation ending of Alert */
  51. afterClose: Function,
  52. /** Whether to show icon */
  53. showIcon: {
  54. type: Boolean,
  55. default: undefined
  56. },
  57. prefixCls: String,
  58. banner: {
  59. type: Boolean,
  60. default: undefined
  61. },
  62. icon: PropTypes.any,
  63. closeIcon: PropTypes.any,
  64. onClose: Function
  65. });
  66. const Alert = defineComponent({
  67. compatConfig: {
  68. MODE: 3
  69. },
  70. name: 'AAlert',
  71. inheritAttrs: false,
  72. props: alertProps(),
  73. setup(props, _ref) {
  74. let {
  75. slots,
  76. emit,
  77. attrs,
  78. expose
  79. } = _ref;
  80. const {
  81. prefixCls,
  82. direction
  83. } = useConfigInject('alert', props);
  84. const [wrapSSR, hashId] = useStyle(prefixCls);
  85. const closing = shallowRef(false);
  86. const closed = shallowRef(false);
  87. const alertNode = shallowRef();
  88. const handleClose = e => {
  89. e.preventDefault();
  90. const dom = alertNode.value;
  91. dom.style.height = `${dom.offsetHeight}px`;
  92. // Magic code
  93. // 重复一次后才能正确设置 height
  94. dom.style.height = `${dom.offsetHeight}px`;
  95. closing.value = true;
  96. emit('close', e);
  97. };
  98. const animationEnd = () => {
  99. var _a;
  100. closing.value = false;
  101. closed.value = true;
  102. (_a = props.afterClose) === null || _a === void 0 ? void 0 : _a.call(props);
  103. };
  104. const mergedType = computed(() => {
  105. const {
  106. type
  107. } = props;
  108. if (type !== undefined) {
  109. return type;
  110. }
  111. // banner 模式默认为警告
  112. return props.banner ? 'warning' : 'info';
  113. });
  114. expose({
  115. animationEnd
  116. });
  117. const motionStyle = shallowRef({});
  118. return () => {
  119. var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
  120. const {
  121. banner,
  122. closeIcon: customCloseIcon = (_a = slots.closeIcon) === null || _a === void 0 ? void 0 : _a.call(slots)
  123. } = props;
  124. let {
  125. closable,
  126. showIcon
  127. } = props;
  128. const closeText = (_b = props.closeText) !== null && _b !== void 0 ? _b : (_c = slots.closeText) === null || _c === void 0 ? void 0 : _c.call(slots);
  129. const description = (_d = props.description) !== null && _d !== void 0 ? _d : (_e = slots.description) === null || _e === void 0 ? void 0 : _e.call(slots);
  130. const message = (_f = props.message) !== null && _f !== void 0 ? _f : (_g = slots.message) === null || _g === void 0 ? void 0 : _g.call(slots);
  131. const icon = (_h = props.icon) !== null && _h !== void 0 ? _h : (_j = slots.icon) === null || _j === void 0 ? void 0 : _j.call(slots);
  132. const action = (_k = slots.action) === null || _k === void 0 ? void 0 : _k.call(slots);
  133. // banner模式默认有 Icon
  134. showIcon = banner && showIcon === undefined ? true : showIcon;
  135. const IconType = (description ? iconMapOutlined : iconMapFilled)[mergedType.value] || null;
  136. // closeable when closeText is assigned
  137. if (closeText) {
  138. closable = true;
  139. }
  140. const prefixClsValue = prefixCls.value;
  141. const alertCls = classNames(prefixClsValue, {
  142. [`${prefixClsValue}-${mergedType.value}`]: true,
  143. [`${prefixClsValue}-closing`]: closing.value,
  144. [`${prefixClsValue}-with-description`]: !!description,
  145. [`${prefixClsValue}-no-icon`]: !showIcon,
  146. [`${prefixClsValue}-banner`]: !!banner,
  147. [`${prefixClsValue}-closable`]: closable,
  148. [`${prefixClsValue}-rtl`]: direction.value === 'rtl',
  149. [hashId.value]: true
  150. });
  151. const closeIcon = closable ? _createVNode("button", {
  152. "type": "button",
  153. "onClick": handleClose,
  154. "class": `${prefixClsValue}-close-icon`,
  155. "tabindex": 0
  156. }, [closeText ? _createVNode("span", {
  157. "class": `${prefixClsValue}-close-text`
  158. }, [closeText]) : customCloseIcon === undefined ? _createVNode(CloseOutlined, null, null) : customCloseIcon]) : null;
  159. const iconNode = icon && (isValidElement(icon) ? cloneElement(icon, {
  160. class: `${prefixClsValue}-icon`
  161. }) : _createVNode("span", {
  162. "class": `${prefixClsValue}-icon`
  163. }, [icon])) || _createVNode(IconType, {
  164. "class": `${prefixClsValue}-icon`
  165. }, null);
  166. const transitionProps = getTransitionProps(`${prefixClsValue}-motion`, {
  167. appear: false,
  168. css: true,
  169. onAfterLeave: animationEnd,
  170. onBeforeLeave: node => {
  171. node.style.maxHeight = `${node.offsetHeight}px`;
  172. },
  173. onLeave: node => {
  174. node.style.maxHeight = '0px';
  175. }
  176. });
  177. return wrapSSR(closed.value ? null : _createVNode(Transition, transitionProps, {
  178. default: () => [_withDirectives(_createVNode("div", _objectSpread(_objectSpread({
  179. "role": "alert"
  180. }, attrs), {}, {
  181. "style": [attrs.style, motionStyle.value],
  182. "class": [attrs.class, alertCls],
  183. "data-show": !closing.value,
  184. "ref": alertNode
  185. }), [showIcon ? iconNode : null, _createVNode("div", {
  186. "class": `${prefixClsValue}-content`
  187. }, [message ? _createVNode("div", {
  188. "class": `${prefixClsValue}-message`
  189. }, [message]) : null, description ? _createVNode("div", {
  190. "class": `${prefixClsValue}-description`
  191. }, [description]) : null]), action ? _createVNode("div", {
  192. "class": `${prefixClsValue}-action`
  193. }, [action]) : null, closeIcon]), [[_vShow, !closing.value]])]
  194. }));
  195. };
  196. }
  197. });
  198. export default withInstall(Alert);