vuecssuiant-designantdreactantantd-vueenterprisefrontendui-designvue-antdvue-antd-uivue3vuecomponent
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.9 KiB
121 lines
3.9 KiB
import type { App, VNodeTypes, Plugin, ExtractPropTypes, PropType } from 'vue'; |
|
import { defineComponent, computed } from 'vue'; |
|
import PropTypes from '../_util/vue-types'; |
|
import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled'; |
|
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; |
|
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled'; |
|
import WarningFilled from '@ant-design/icons-vue/WarningFilled'; |
|
import noFound from './noFound'; |
|
import serverError from './serverError'; |
|
import unauthorized from './unauthorized'; |
|
import useConfigInject from '../config-provider/hooks/useConfigInject'; |
|
import classNames from '../_util/classNames'; |
|
import type { CustomSlotsType } from '../_util/type'; |
|
|
|
import useStyle from './style'; |
|
|
|
export const IconMap = { |
|
success: CheckCircleFilled, |
|
error: CloseCircleFilled, |
|
info: ExclamationCircleFilled, |
|
warning: WarningFilled, |
|
}; |
|
|
|
export const ExceptionMap = { |
|
'404': noFound, |
|
'500': serverError, |
|
'403': unauthorized, |
|
}; |
|
|
|
export type ExceptionStatusType = 403 | 404 | 500 | '403' | '404' | '500'; |
|
export type ResultStatusType = ExceptionStatusType | keyof typeof IconMap; |
|
|
|
// ExceptionImageMap keys |
|
const ExceptionStatus = Object.keys(ExceptionMap); |
|
|
|
export const resultProps = () => ({ |
|
prefixCls: String, |
|
icon: PropTypes.any, |
|
status: { type: [Number, String] as PropType<ResultStatusType>, default: 'info' }, |
|
title: PropTypes.any, |
|
subTitle: PropTypes.any, |
|
extra: PropTypes.any, |
|
}); |
|
|
|
export type ResultProps = Partial<ExtractPropTypes<ReturnType<typeof resultProps>>>; |
|
|
|
const renderIcon = (prefixCls: string, { status, icon }) => { |
|
if (ExceptionStatus.includes(`${status}`)) { |
|
const SVGComponent = ExceptionMap[status]; |
|
return ( |
|
<div class={`${prefixCls}-icon ${prefixCls}-image`}> |
|
<SVGComponent /> |
|
</div> |
|
); |
|
} |
|
const IconComponent = IconMap[status]; |
|
const iconNode = icon || <IconComponent />; |
|
return <div class={`${prefixCls}-icon`}>{iconNode}</div>; |
|
}; |
|
|
|
const renderExtra = (prefixCls: string, extra: VNodeTypes) => |
|
extra && <div class={`${prefixCls}-extra`}>{extra}</div>; |
|
|
|
const Result = defineComponent({ |
|
compatConfig: { MODE: 3 }, |
|
name: 'AResult', |
|
inheritAttrs: false, |
|
props: resultProps(), |
|
slots: Object as CustomSlotsType<{ |
|
title?: any; |
|
subTitle?: any; |
|
icon?: any; |
|
extra?: any; |
|
default?: any; |
|
}>, |
|
setup(props, { slots, attrs }) { |
|
const { prefixCls, direction } = useConfigInject('result', props); |
|
|
|
const [wrapSSR, hashId] = useStyle(prefixCls); |
|
|
|
const className = computed(() => |
|
classNames(prefixCls.value, hashId.value, `${prefixCls.value}-${props.status}`, { |
|
[`${prefixCls.value}-rtl`]: direction.value === 'rtl', |
|
}), |
|
); |
|
return () => { |
|
const title = props.title ?? slots.title?.(); |
|
const subTitle = props.subTitle ?? slots.subTitle?.(); |
|
const icon = props.icon ?? slots.icon?.(); |
|
const extra = props.extra ?? slots.extra?.(); |
|
const pre = prefixCls.value; |
|
return wrapSSR( |
|
<div {...attrs} class={[className.value, attrs.class]}> |
|
{renderIcon(pre, { status: props.status, icon })} |
|
<div class={`${pre}-title`}>{title}</div> |
|
{subTitle && <div class={`${pre}-subtitle`}>{subTitle}</div>} |
|
{renderExtra(pre, extra)} |
|
{slots.default && <div class={`${pre}-content`}>{slots.default()}</div>} |
|
</div>, |
|
); |
|
}; |
|
}, |
|
}); |
|
|
|
/* add resource */ |
|
Result.PRESENTED_IMAGE_403 = ExceptionMap[403]; |
|
Result.PRESENTED_IMAGE_404 = ExceptionMap[404]; |
|
Result.PRESENTED_IMAGE_500 = ExceptionMap[500]; |
|
|
|
/* istanbul ignore next */ |
|
Result.install = function (app: App) { |
|
app.component(Result.name, Result); |
|
return app; |
|
}; |
|
|
|
export default Result as typeof Result & |
|
Plugin & { |
|
readonly PRESENTED_IMAGE_403: typeof unauthorized; |
|
readonly PRESENTED_IMAGE_404: typeof noFound; |
|
readonly PRESENTED_IMAGE_500: typeof serverError; |
|
};
|
|
|