import * as React from 'react'; import CheckCircleFilled from '@ant-design/icons/CheckCircleFilled'; import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled'; import WarningFilled from '@ant-design/icons/WarningFilled'; import classNames from 'classnames'; import { devUseWarning } from '../_util/warning'; import { ConfigContext } from '../config-provider'; import noFound from './noFound'; import serverError from './serverError'; import useStyle from './style'; import unauthorized from './unauthorized'; 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; export interface ResultProps { icon?: React.ReactNode; status?: ResultStatusType; title?: React.ReactNode; subTitle?: React.ReactNode; extra?: React.ReactNode; prefixCls?: string; className?: string; rootClassName?: string; style?: React.CSSProperties; children?: React.ReactNode; } // ExceptionImageMap keys const ExceptionStatus = Object.keys(ExceptionMap); /** * Render icon if ExceptionStatus includes ,render svg image else render iconNode * * @param prefixCls * @param {status, icon} */ interface IconProps { prefixCls: string; icon: React.ReactNode; status: ResultStatusType; } const Icon: React.FC = ({ prefixCls, icon, status }) => { const className = classNames(`${prefixCls}-icon`); if (process.env.NODE_ENV !== 'production') { const warning = devUseWarning('Result'); warning( !(typeof icon === 'string' && icon.length > 2), 'breaking', `\`icon\` is using ReactNode instead of string naming in v4. Please check \`${icon}\` at https://ant.design/components/icon`, ); } if (ExceptionStatus.includes(`${status}`)) { const SVGComponent = ExceptionMap[status as ExceptionStatusType]; return (
); } const iconNode = React.createElement( IconMap[status as Exclude], ); if (icon === null || icon === false) { return null; } return
{icon || iconNode}
; }; interface ExtraProps { prefixCls: string; extra: React.ReactNode; } const Extra: React.FC = ({ prefixCls, extra }) => { if (!extra) { return null; } return
{extra}
; }; export interface ResultType extends React.FC { PRESENTED_IMAGE_404: React.FC; PRESENTED_IMAGE_403: React.FC; PRESENTED_IMAGE_500: React.FC; } const Result: ResultType = ({ prefixCls: customizePrefixCls, className: customizeClassName, rootClassName, subTitle, title, style, children, status = 'info', icon, extra, }) => { const { getPrefixCls, direction, result } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('result', customizePrefixCls); // Style const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls); const className = classNames( prefixCls, `${prefixCls}-${status}`, customizeClassName, result?.className, rootClassName, { [`${prefixCls}-rtl`]: direction === 'rtl' }, hashId, cssVarCls, ); const mergedStyle: React.CSSProperties = { ...result?.style, ...style }; return wrapCSSVar(
{title}
{subTitle &&
{subTitle}
} {children &&
{children}
}
, ); }; Result.PRESENTED_IMAGE_403 = ExceptionMap['403']; Result.PRESENTED_IMAGE_404 = ExceptionMap['404']; Result.PRESENTED_IMAGE_500 = ExceptionMap['500']; if (process.env.NODE_ENV !== 'production') { Result.displayName = 'Result'; } export default Result;