diff --git a/components/result/index.tsx b/components/result/index.tsx index a2ed721fe..bf00929ac 100644 --- a/components/result/index.tsx +++ b/components/result/index.tsx @@ -1,8 +1,6 @@ -import { App, defineComponent, inject, VNodeTypes, Plugin } from 'vue'; +import { App, defineComponent, VNodeTypes, Plugin, ExtractPropTypes, computed } from 'vue'; import PropTypes from '../_util/vue-types'; import { tuple } from '../_util/type'; -import { getComponent } from '../_util/props-util'; -import { defaultConfigProvider } from '../config-provider'; import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled'; import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled'; @@ -10,6 +8,8 @@ import WarningFilled from '@ant-design/icons-vue/WarningFilled'; import noFound from './noFound'; import serverError from './serverError'; import unauthorized from './unauthorized'; +import useConfigInject from '../_util/hooks/useConfigInject'; +import classNames from '../_util/classNames'; export const IconMap = { success: CheckCircleFilled, @@ -27,7 +27,7 @@ export const ExceptionMap = { // ExceptionImageMap keys const ExceptionStatus = Object.keys(ExceptionMap); -export const ResultProps = { +export const resultProps = { prefixCls: PropTypes.string, icon: PropTypes.any, status: PropTypes.oneOf(tuple('success', 'error', 'info', 'warning', '404', '403', '500')).def( @@ -38,6 +38,8 @@ export const ResultProps = { extra: PropTypes.any, }; +export type ResultProps = Partial>; + const renderIcon = (prefixCls: string, { status, icon }) => { if (ExceptionStatus.includes(`${status}`)) { const SVGComponent = ExceptionMap[status]; @@ -57,31 +59,31 @@ const renderExtra = (prefixCls: string, extra: VNodeTypes) => const Result = defineComponent({ name: 'AResult', - props: ResultProps, - setup() { - return { - configProvider: inject('configProvider', defaultConfigProvider), - }; - }, - render() { - const { prefixCls: customizePrefixCls, status } = this; - const getPrefixCls = this.configProvider.getPrefixCls; - const prefixCls = getPrefixCls('result', customizePrefixCls); - - const title = getComponent(this, 'title'); - const subTitle = getComponent(this, 'subTitle'); - const icon = getComponent(this, 'icon'); - const extra = getComponent(this, 'extra'); - - return ( -
- {renderIcon(prefixCls, { status, icon })} -
{title}
- {subTitle &&
{subTitle}
} - {this.$slots.default &&
{this.$slots.default()}
} - {renderExtra(prefixCls, extra)} -
+ props: resultProps, + slots: ['title', 'subTitle', 'icon', 'extra'], + setup(props, { slots }) { + const { prefixCls, direction } = useConfigInject('result', props); + const className = computed(() => + classNames(prefixCls.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 ( +
+ {renderIcon(pre, { status: props.status, icon })} +
{title}
+ {subTitle &&
{subTitle}
} + {renderExtra(pre, extra)} + {slots.default &&
{slots.default()}
} +
+ ); + }; }, }); diff --git a/components/result/style/index.less b/components/result/style/index.less index 5ebf40dcf..f8e800578 100644 --- a/components/result/style/index.less +++ b/components/result/style/index.less @@ -6,19 +6,19 @@ .@{result-prefix-cls} { padding: 48px 32px; // status color - &-success &-icon > .anticon { + &-success &-icon > .@{iconfont-css-prefix} { color: @success-color; } - &-error &-icon > .anticon { + &-error &-icon > .@{iconfont-css-prefix} { color: @error-color; } - &-info &-icon > .anticon { + &-info &-icon > .@{iconfont-css-prefix} { color: @info-color; } - &-warning &-icon > .anticon { + &-warning &-icon > .@{iconfont-css-prefix} { color: @warning-color; } @@ -33,30 +33,31 @@ margin-bottom: 24px; text-align: center; - > .anticon { - font-size: 72px; + > .@{iconfont-css-prefix} { + font-size: @result-icon-font-size; } } &-title { color: @heading-color; - font-size: 24px; + font-size: @result-title-font-size; line-height: 1.8; text-align: center; } &-subtitle { color: @text-color-secondary; - font-size: 14px; + font-size: @result-subtitle-font-size; line-height: 1.6; text-align: center; } &-extra { - margin-top: 32px; + margin: @result-extra-margin; text-align: center; > * { margin-right: 8px; + &:last-child { margin-right: 0; } @@ -69,3 +70,5 @@ background-color: @background-color-light; } } + +@import './rtl'; diff --git a/components/result/style/rtl.less b/components/result/style/rtl.less new file mode 100644 index 000000000..3b286b749 --- /dev/null +++ b/components/result/style/rtl.less @@ -0,0 +1,25 @@ +@import '../../style/themes/default'; +@import '../../style/mixins/index'; + +@result-prefix-cls: ~'@{ant-prefix}-result'; + +.@{result-prefix-cls} { + &-rtl { + direction: rtl; + } + + &-extra { + > * { + .@{result-prefix-cls}-rtl & { + margin-right: 0; + margin-left: 8px; + } + + &:last-child { + .@{result-prefix-cls}-rtl & { + margin-left: 0; + } + } + } + } +} diff --git a/components/style/themes/default.less b/components/style/themes/default.less index 5dca3a0fc..30126c447 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -835,3 +835,10 @@ @notification-bg: @component-background; @notification-padding-vertical: 16px; @notification-padding-horizontal: 24px; + +// Result +// --- +@result-title-font-size: 24px; +@result-subtitle-font-size: @font-size-base; +@result-icon-font-size: 72px; +@result-extra-margin: 24px 0 0 0;