feat: alert add action slot
							parent
							
								
									b2841a27ae
								
							
						
					
					
						commit
						1f33babc89
					
				|  | @ -0,0 +1,57 @@ | |||
| <docs> | ||||
| --- | ||||
| order: 0 | ||||
| title: | ||||
|   zh-CN: 操作 | ||||
|   en-US: Action | ||||
| --- | ||||
| 
 | ||||
| ## zh-CN | ||||
| 
 | ||||
| 可以在右上角自定义操作项。 | ||||
| 
 | ||||
| ## en-US | ||||
| 
 | ||||
| Custom action. | ||||
| 
 | ||||
| </docs> | ||||
| 
 | ||||
| <template> | ||||
|   <a-space direction="vertical" style="width: 100%"> | ||||
|     <a-alert message="Success Tips" type="success" show-icon closable> | ||||
|       <template #action> | ||||
|         <a-button size="small" type="text">UNDO</a-button> | ||||
|       </template> | ||||
|     </a-alert> | ||||
|     <a-alert | ||||
|       message="Error Text" | ||||
|       show-icon | ||||
|       description="Error Description Error Description Error Description Error Description" | ||||
|       type="error" | ||||
|     > | ||||
|       <template #action> | ||||
|         <a-button size="small" danger>Detail</a-button> | ||||
|       </template> | ||||
|     </a-alert> | ||||
|     <a-alert message="Warning Text" type="warning" closable> | ||||
|       <template #action> | ||||
|         <a-space> | ||||
|           <a-button size="small" type="ghost">Done</a-button> | ||||
|         </a-space> | ||||
|       </template> | ||||
|     </a-alert> | ||||
|     <a-alert | ||||
|       message="Info Text" | ||||
|       description="Info Description Info Description Info Description Info Description" | ||||
|       type="info" | ||||
|       closable | ||||
|     > | ||||
|       <template #action> | ||||
|         <a-space direction="vertical"> | ||||
|           <a-button size="small" type="primary">Accept</a-button> | ||||
|           <a-button size="small" danger type="ghost">Decline</a-button> | ||||
|         </a-space> | ||||
|       </template> | ||||
|     </a-alert> | ||||
|   </a-space> | ||||
| </template> | ||||
|  | @ -9,6 +9,7 @@ | |||
|     <banner /> | ||||
|     <custom-icon /> | ||||
|     <smooth-closed /> | ||||
|     <action /> | ||||
|   </demo-sort> | ||||
| </template> | ||||
| <script lang="ts"> | ||||
|  | @ -18,6 +19,7 @@ import Closable from './closable.vue'; | |||
| import CloseText from './close-text.vue'; | ||||
| import Description from './description.vue'; | ||||
| import Icon from './icon.vue'; | ||||
| import Action from './action.vue'; | ||||
| import Style from './style.vue'; | ||||
| import SmoothClosed from './smooth-closed.vue'; | ||||
| import CustomIcon from './custom-icon.vue'; | ||||
|  | @ -37,6 +39,7 @@ export default defineComponent({ | |||
|     FourStyle: Style, //style 标签报错 | ||||
|     SmoothClosed, | ||||
|     CustomIcon, | ||||
|     Action, | ||||
|   }, | ||||
|   setup() { | ||||
|     return {}; | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ Alert component for feedback. | |||
| 
 | ||||
| | Property | Description | Type | Default | Version | | ||||
| | --- | --- | --- | --- | --- | | ||||
| | action | The action of Alert | slot | - | 4.0.0 | | ||||
| | afterClose | Called when close animation is finished | () => void | - |  | | ||||
| | banner | Whether to show as banner | boolean | false |  | | ||||
| | closable | Whether Alert can be closed | boolean |  |  | | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import type { CSSProperties, ExtractPropTypes, PropType } from 'vue'; | ||||
| import { defineComponent, ref } from 'vue'; | ||||
| import { computed, defineComponent, ref } from 'vue'; | ||||
| import CloseOutlined from '@ant-design/icons-vue/CloseOutlined'; | ||||
| import CheckCircleOutlined from '@ant-design/icons-vue/CheckCircleOutlined'; | ||||
| import ExclamationCircleOutlined from '@ant-design/icons-vue/ExclamationCircleOutlined'; | ||||
|  | @ -12,7 +12,7 @@ import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; | |||
| import classNames from '../_util/classNames'; | ||||
| import PropTypes from '../_util/vue-types'; | ||||
| import { getTransitionProps, Transition } from '../_util/transition'; | ||||
| import { isValidElement, getPropsSlot } from '../_util/props-util'; | ||||
| import { isValidElement } from '../_util/props-util'; | ||||
| import { tuple, withInstall } from '../_util/type'; | ||||
| import { cloneElement } from '../_util/vnode'; | ||||
| import type { NodeMouseEventHandler } from '../vc-tree/contextTypes'; | ||||
|  | @ -94,25 +94,31 @@ const Alert = defineComponent({ | |||
|       closed.value = true; | ||||
|       props.afterClose?.(); | ||||
|     }; | ||||
| 
 | ||||
|     const mergedType = computed(() => { | ||||
|       const { type } = props; | ||||
|       if (type !== undefined) { | ||||
|         return type; | ||||
|       } | ||||
|       // banner 模式默认为警告 | ||||
|       return props.banner ? 'warning' : 'info'; | ||||
|     }); | ||||
|     expose({ animationEnd }); | ||||
|     const motionStyle = ref<CSSProperties>({}); | ||||
|     return () => { | ||||
|       const { banner, closeIcon: customCloseIcon = slots.closeIcon?.() } = props; | ||||
| 
 | ||||
|       let { closable, type, showIcon } = props; | ||||
|       let { closable, showIcon } = props; | ||||
| 
 | ||||
|       const closeText = getPropsSlot(slots, props, 'closeText'); | ||||
|       const description = getPropsSlot(slots, props, 'description'); | ||||
|       const message = getPropsSlot(slots, props, 'message'); | ||||
|       const icon = getPropsSlot(slots, props, 'icon'); | ||||
|       const closeText = props.closeText ?? slots.closeText?.(); | ||||
|       const description = props.description ?? slots.description?.(); | ||||
|       const message = props.message ?? slots.message?.(); | ||||
|       const icon = props.icon ?? slots.icon?.(); | ||||
|       const action = slots.action?.(); | ||||
| 
 | ||||
|       // banner模式默认有 Icon | ||||
|       showIcon = banner && showIcon === undefined ? true : showIcon; | ||||
|       // banner模式默认为警告 | ||||
|       type = banner && type === undefined ? 'warning' : type || 'info'; | ||||
| 
 | ||||
|       const IconType = (description ? iconMapOutlined : iconMapFilled)[type] || null; | ||||
|       const IconType = (description ? iconMapOutlined : iconMapFilled)[mergedType.value] || null; | ||||
| 
 | ||||
|       // closeable when closeText is assigned | ||||
|       if (closeText) { | ||||
|  | @ -120,7 +126,7 @@ const Alert = defineComponent({ | |||
|       } | ||||
|       const prefixClsValue = prefixCls.value; | ||||
|       const alertCls = classNames(prefixClsValue, { | ||||
|         [`${prefixClsValue}-${type}`]: true, | ||||
|         [`${prefixClsValue}-${mergedType.value}`]: true, | ||||
|         [`${prefixClsValue}-closing`]: closing.value, | ||||
|         [`${prefixClsValue}-with-description`]: !!description, | ||||
|         [`${prefixClsValue}-no-icon`]: !showIcon, | ||||
|  | @ -186,6 +192,7 @@ const Alert = defineComponent({ | |||
|                   <div class={`${prefixClsValue}-description`}>{description}</div> | ||||
|                 ) : null} | ||||
|               </div> | ||||
|               {action ? <div class={`${prefixClsValue}-action`}>{action}</div> : null} | ||||
|               {closeIcon} | ||||
|             </div> | ||||
|           </Transition> | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/8emPa3fjl/Alert.svg | |||
| 
 | ||||
| | 参数 | 说明 | 类型 | 默认值 | 版本 | | ||||
| | --- | --- | --- | --- | --- | | ||||
| | action | 自定义操作项 | slot | - | 4.0.0 | | ||||
| | afterClose | 关闭动画结束后触发的回调函数 | () => void | - |  | | ||||
| | banner | 是否用作顶部公告 | boolean | false |  | | ||||
| | closable | 默认不显示关闭按钮 | boolean | 无 |  | | ||||
|  |  | |||
|  | @ -1,155 +0,0 @@ | |||
| @import '../../style/themes/index'; | ||||
| @import '../../style/mixins/index'; | ||||
| 
 | ||||
| @alert-prefix-cls: ~'@{ant-prefix}-alert'; | ||||
| 
 | ||||
| .@{alert-prefix-cls} { | ||||
|   .reset-component(); | ||||
| 
 | ||||
|   position: relative; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   padding: 8px 15px; | ||||
|   word-wrap: break-word; | ||||
|   border-radius: @border-radius-base; | ||||
| 
 | ||||
|   &-content { | ||||
|     flex: 1; | ||||
|     min-width: 0; | ||||
|   } | ||||
| 
 | ||||
|   &-icon { | ||||
|     margin-right: @margin-xs; | ||||
|   } | ||||
| 
 | ||||
|   &-description { | ||||
|     display: none; | ||||
|     font-size: @font-size-base; | ||||
|     line-height: @font-size-base + 8px; | ||||
|   } | ||||
| 
 | ||||
|   &-success { | ||||
|     background-color: @alert-success-bg-color; | ||||
|     border: @border-width-base @border-style-base @alert-success-border-color; | ||||
|     .@{alert-prefix-cls}-icon { | ||||
|       color: @alert-success-icon-color; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-info { | ||||
|     background-color: @alert-info-bg-color; | ||||
|     border: @border-width-base @border-style-base @alert-info-border-color; | ||||
|     .@{alert-prefix-cls}-icon { | ||||
|       color: @alert-info-icon-color; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-warning { | ||||
|     background-color: @alert-warning-bg-color; | ||||
|     border: @border-width-base @border-style-base @alert-warning-border-color; | ||||
|     .@{alert-prefix-cls}-icon { | ||||
|       color: @alert-warning-icon-color; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-error { | ||||
|     background-color: @alert-error-bg-color; | ||||
|     border: @border-width-base @border-style-base @alert-error-border-color; | ||||
| 
 | ||||
|     .@{alert-prefix-cls}-icon { | ||||
|       color: @alert-error-icon-color; | ||||
|     } | ||||
| 
 | ||||
|     .@{alert-prefix-cls}-description > pre { | ||||
|       margin: 0; | ||||
|       padding: 0; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-action { | ||||
|     margin-left: @margin-xs; | ||||
|   } | ||||
| 
 | ||||
|   &-close-icon { | ||||
|     margin-left: @margin-xs; | ||||
|     padding: 0; | ||||
|     overflow: hidden; | ||||
|     font-size: @font-size-sm; | ||||
|     line-height: @font-size-sm; | ||||
|     background-color: transparent; | ||||
|     border: none; | ||||
|     outline: none; | ||||
|     cursor: pointer; | ||||
| 
 | ||||
|     .@{iconfont-css-prefix}-close { | ||||
|       color: @alert-close-color; | ||||
|       transition: color 0.3s; | ||||
| 
 | ||||
|       &:hover { | ||||
|         color: @alert-close-hover-color; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-close-text { | ||||
|     color: @alert-close-color; | ||||
|     transition: color 0.3s; | ||||
| 
 | ||||
|     &:hover { | ||||
|       color: @alert-close-hover-color; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-with-description { | ||||
|     align-items: flex-start; | ||||
|     padding: @alert-with-description-padding; | ||||
|   } | ||||
| 
 | ||||
|   &-with-description&-no-icon { | ||||
|     padding: @alert-with-description-no-icon-padding-vertical 15px; | ||||
|   } | ||||
| 
 | ||||
|   &-with-description &-icon { | ||||
|     margin-right: @alert-with-description-padding-vertical; | ||||
|     font-size: @alert-with-description-icon-size; | ||||
|   } | ||||
| 
 | ||||
|   &-with-description &-message { | ||||
|     display: block; | ||||
|     margin-bottom: 4px; | ||||
|     color: @alert-message-color; | ||||
|     font-size: @font-size-lg; | ||||
|   } | ||||
| 
 | ||||
|   &-message { | ||||
|     color: @alert-message-color; | ||||
|   } | ||||
| 
 | ||||
|   &-with-description &-description { | ||||
|     display: block; | ||||
|   } | ||||
| 
 | ||||
|   &&-motion-leave { | ||||
|     overflow: hidden; | ||||
|     opacity: 1; | ||||
|     transition: max-height 0.3s @ease-in-out-circ, opacity 0.3s @ease-in-out-circ, | ||||
|       padding-top 0.3s @ease-in-out-circ, padding-bottom 0.3s @ease-in-out-circ, | ||||
|       margin-bottom 0.3s @ease-in-out-circ; | ||||
|   } | ||||
| 
 | ||||
|   &&-motion-leave-active { | ||||
|     max-height: 0; | ||||
|     margin-bottom: 0 !important; | ||||
|     padding-top: 0; | ||||
|     padding-bottom: 0; | ||||
|     opacity: 0; | ||||
|   } | ||||
| 
 | ||||
|   &-banner { | ||||
|     margin-bottom: 0; | ||||
|     border: 0; | ||||
|     border-radius: 0; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @import './rtl'; | ||||
|  | @ -1,2 +0,0 @@ | |||
| import '../../style/index.less'; | ||||
| import './index.less'; | ||||
|  | @ -1,40 +0,0 @@ | |||
| .@{alert-prefix-cls} { | ||||
|   &&-rtl { | ||||
|     direction: rtl; | ||||
|   } | ||||
| 
 | ||||
|   &-icon { | ||||
|     .@{alert-prefix-cls}-rtl & { | ||||
|       margin-right: auto; | ||||
|       margin-left: @margin-xs; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-action { | ||||
|     .@{alert-prefix-cls}-rtl & { | ||||
|       margin-right: @margin-xs; | ||||
|       margin-left: auto; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-close-icon { | ||||
|     .@{alert-prefix-cls}-rtl & { | ||||
|       margin-right: @margin-xs; | ||||
|       margin-left: auto; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-with-description { | ||||
|     .@{alert-prefix-cls}-rtl& { | ||||
|       padding-right: @alert-with-description-icon-size; | ||||
|       padding-left: @alert-with-description-padding-vertical; | ||||
|     } | ||||
| 
 | ||||
|     .@{alert-prefix-cls}-icon { | ||||
|       .@{alert-prefix-cls}-rtl& { | ||||
|         margin-right: auto; | ||||
|         margin-left: @alert-with-description-padding-vertical; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -30,7 +30,7 @@ import './affix/style'; | |||
| import './cascader/style'; | ||||
| import './back-top/style'; | ||||
| import './modal/style'; | ||||
| import './alert/style'; | ||||
| // import './alert/style';
 | ||||
| import './time-picker/style'; | ||||
| import './steps/style'; | ||||
| import './breadcrumb/style'; | ||||
|  |  | |||
|  | @ -1,3 +1,7 @@ | |||
| <template> | ||||
|   <a-alert message="Success Text" prefix-cls="tes" type="success" /> | ||||
|   <a-alert message="Success Tips" type="success" show-icon closable> | ||||
|     <template #action> | ||||
|       <a-button v-if="false" size="small" type="text">UNDO</a-button> | ||||
|     </template> | ||||
|   </a-alert> | ||||
| </template> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou