diff --git a/.dumirc.ts b/.dumirc.ts index b6dd14e55..d8cf3fd7b 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -164,6 +164,7 @@ export default defineConfig({ { title: 'Modal 对话框', link: '/components/modal' }, { title: 'Drawer 抽屉', link: '/components/drawer' }, { title: 'Notification 通知提醒框', link: '/components/notification' }, + { title: 'Result 结果', link: '/components/result' }, { title: 'Spin 加载中', link: '/components/spin' }, { title: 'Badge 徽标数', link: '/components/badge' }, ], diff --git a/packages/design/src/index.ts b/packages/design/src/index.ts index cc658c56a..fc30708dd 100644 --- a/packages/design/src/index.ts +++ b/packages/design/src/index.ts @@ -71,6 +71,9 @@ export type { SegmentedProps } from './segmented'; export { default as Breadcrumb } from './breadcrumb'; export type { BreadcrumbProps, BreadcrumbItemProps } from './breadcrumb'; +export { default as Result } from './result'; +export type { ResultProps, ResultType, ResultStatusType } from './result'; + export { default as Spin } from './spin'; export type { SpinProps } from './spin'; diff --git a/packages/design/src/result/403.tsx b/packages/design/src/result/403.tsx new file mode 100644 index 000000000..eef6fc159 --- /dev/null +++ b/packages/design/src/result/403.tsx @@ -0,0 +1,124 @@ +import React from 'react'; +import Icon from '@oceanbase/icons'; +import type { CustomIconComponentProps } from '@oceanbase/icons/es/components/Icon'; + +const Svg403 = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const Image403: React.FC = (props: Partial) => ( + +); + +export default Image403; diff --git a/packages/design/src/result/404.tsx b/packages/design/src/result/404.tsx new file mode 100644 index 000000000..093dca5c0 --- /dev/null +++ b/packages/design/src/result/404.tsx @@ -0,0 +1,269 @@ +import React from 'react'; +import Icon from '@oceanbase/icons'; +import type { CustomIconComponentProps } from '@oceanbase/icons/es/components/Icon'; + +const Svg404 = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const Image404: React.FC = (props: Partial) => ( + +); + +export default Image404; diff --git a/packages/design/src/result/500.tsx b/packages/design/src/result/500.tsx new file mode 100644 index 000000000..3e6bbb913 --- /dev/null +++ b/packages/design/src/result/500.tsx @@ -0,0 +1,228 @@ +import React from 'react'; +import Icon from '@oceanbase/icons'; +import type { CustomIconComponentProps } from '@oceanbase/icons/es/components/Icon'; + +const Svg500 = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const Image500: React.FC = (props: Partial) => ( + +); + +export default Image500; diff --git a/packages/design/src/result/Error.tsx b/packages/design/src/result/Error.tsx new file mode 100644 index 000000000..81dbeaa1a --- /dev/null +++ b/packages/design/src/result/Error.tsx @@ -0,0 +1,106 @@ +import React from 'react'; +import Icon from '@oceanbase/icons'; +import type { CustomIconComponentProps } from '@oceanbase/icons/es/components/Icon'; + +const ErrorSvg = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const Error: React.FC = (props: Partial) => ( + +); + +export default Error; diff --git a/packages/design/src/result/Processing.tsx b/packages/design/src/result/Processing.tsx new file mode 100644 index 000000000..1abafb427 --- /dev/null +++ b/packages/design/src/result/Processing.tsx @@ -0,0 +1,230 @@ +import React from 'react'; +import Icon from '@oceanbase/icons'; +import type { CustomIconComponentProps } from '@oceanbase/icons/es/components/Icon'; + +const ProcessingSvg = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const Processing: React.FC = (props: Partial) => ( + +); + +export default Processing; diff --git a/packages/design/src/result/Success.tsx b/packages/design/src/result/Success.tsx new file mode 100644 index 000000000..c72a2e2b7 --- /dev/null +++ b/packages/design/src/result/Success.tsx @@ -0,0 +1,176 @@ +import React from 'react'; +import Icon from '@oceanbase/icons'; +import type { CustomIconComponentProps } from '@oceanbase/icons/es/components/Icon'; + +const SuccessSvg = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const Success: React.FC = (props: Partial) => ( + +); + +export default Success; diff --git a/packages/design/src/result/Warning.tsx b/packages/design/src/result/Warning.tsx new file mode 100644 index 000000000..7a0fb00bd --- /dev/null +++ b/packages/design/src/result/Warning.tsx @@ -0,0 +1,472 @@ +import React from 'react'; +import Icon from '@oceanbase/icons'; +import type { CustomIconComponentProps } from '@oceanbase/icons/es/components/Icon'; + +const WarningSvg = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const Warning: React.FC = (props: Partial) => ( + +); + +export default Warning; diff --git a/packages/design/src/result/demo/403.tsx b/packages/design/src/result/demo/403.tsx new file mode 100644 index 000000000..d3ce26a1a --- /dev/null +++ b/packages/design/src/result/demo/403.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Result, Button } from '@oceanbase/design'; + +export default () => { + return ( + 前往 RAM 角色授权} + /> + ); +}; diff --git a/packages/design/src/result/demo/404.tsx b/packages/design/src/result/demo/404.tsx new file mode 100644 index 000000000..f63c2a3e8 --- /dev/null +++ b/packages/design/src/result/demo/404.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Result, Button } from '@oceanbase/design'; + +export default () => { + return ( + 返回首页} + /> + ); +}; diff --git a/packages/design/src/result/demo/500.tsx b/packages/design/src/result/demo/500.tsx new file mode 100644 index 000000000..5cc996b37 --- /dev/null +++ b/packages/design/src/result/demo/500.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Result, Button } from '@oceanbase/design'; + +export default () => { + return ( + 返回首页} + /> + ); +}; diff --git a/packages/design/src/result/demo/error.tsx b/packages/design/src/result/demo/error.tsx new file mode 100644 index 000000000..dbdf9a5e1 --- /dev/null +++ b/packages/design/src/result/demo/error.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { Result, Button, theme, Typography } from '@oceanbase/design'; + +export default () => { + const { token } = theme.useToken(); + return ( + + 主操作 + , + , + ]} + > + 出错原因 + + {`Error1: Failed to load Stripe-js at HTMLScriptElement. sanonymous> (727.93344492.async.is:1:7397) + Error2: Failed to load Stripe-js at HTMLScriptElement. sanonymous> (727.93344492.async.is:1:7397) + Error3: Failed to load Stripe-js at HTMLScriptElement. sanonymous> (727.93344492.async.is:1:7397) + Error4: Failed to load Stripe-js at HTMLScriptElement. sanonymous> (727.93344492.async.is:1:7397)`} + + + ); +}; diff --git a/packages/design/src/result/demo/icon.tsx b/packages/design/src/result/demo/icon.tsx new file mode 100644 index 000000000..106a6c582 --- /dev/null +++ b/packages/design/src/result/demo/icon.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Result, Button, theme } from '@oceanbase/design'; +import { CheckCircleFilled } from '@oceanbase/icons'; + +export default () => { + const { token } = theme.useToken(); + return ( + } + title="任务执行成功" + subTitle="这是一段关于任务执行成功的描述" + extra={[ + , + , + ]} + /> + ); +}; diff --git a/packages/design/src/result/demo/processing.tsx b/packages/design/src/result/demo/processing.tsx new file mode 100644 index 000000000..efabf2c3a --- /dev/null +++ b/packages/design/src/result/demo/processing.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { Result, Button } from '@oceanbase/design'; + +export default () => { + return ( + + 主操作 + , + , + ]} + /> + ); +}; diff --git a/packages/design/src/result/demo/success.tsx b/packages/design/src/result/demo/success.tsx new file mode 100644 index 000000000..2d9990fdb --- /dev/null +++ b/packages/design/src/result/demo/success.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { Result, Button } from '@oceanbase/design'; + +export default () => { + return ( + + 主操作 + , + , + ]} + /> + ); +}; diff --git a/packages/design/src/result/demo/warning.tsx b/packages/design/src/result/demo/warning.tsx new file mode 100644 index 000000000..d44d5f237 --- /dev/null +++ b/packages/design/src/result/demo/warning.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { Result, Button } from '@oceanbase/design'; + +export default () => { + return ( + + 主操作 + , + , + ]} + /> + ); +}; diff --git a/packages/design/src/result/index.md b/packages/design/src/result/index.md new file mode 100644 index 000000000..3dc4f1f38 --- /dev/null +++ b/packages/design/src/result/index.md @@ -0,0 +1,36 @@ +--- +title: Result 结果 +nav: + title: 基础组件 + path: /components +--- + +- 🔥 完全继承 antd [Result](https://ant.design/components/result-cn) 的能力和 API,可无缝切换。 +- 💄 定制插图、主题和样式,以符合 OceanBase Design 设计规范。 +- 🆕 `status` 属性新增 `processing` 枚举值,用于设置进行中的状态。 + +## 代码演示 + + + + + + + + + + + + + + + + + +## API + +| 参数 | 说明 | 类型 | 默认值 | 版本 | +| :-- | :-- | :-- | :-- | :-- | +| status | 状态 | success \| error \| warning \| processing \| info \| 403 \| 404 \| 500 | info | - | + +- 更多 API 详见 antd Result 文档: https://ant.design/components/result-cn diff --git a/packages/design/src/result/index.ts b/packages/design/src/result/index.ts deleted file mode 100644 index 4dee23425..000000000 --- a/packages/design/src/result/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from 'antd/es/result'; diff --git a/packages/design/src/result/index.tsx b/packages/design/src/result/index.tsx new file mode 100644 index 000000000..2dd720fd7 --- /dev/null +++ b/packages/design/src/result/index.tsx @@ -0,0 +1,66 @@ +import React, { useContext } from 'react'; +import { Result as AntResult } from 'antd'; +import type { + ResultProps as AntResultProps, + ResultStatusType as AntResultStatusType, +} from 'antd/es/result'; +import classNames from 'classnames'; +import ConfigProvider from '../config-provider'; +import Success from './Success'; +import Error from './Error'; +import Warning from './Warning'; +import Processing from './Processing'; +import Image403 from './403'; +import Image404 from './404'; +import Image500 from './500'; +import useStyle from './style'; + +export * from 'antd/es/result'; + +export type ResultStatusType = AntResultStatusType | 'processing'; + +export interface ResultProps extends Omit { + status?: ResultStatusType; +} + +export interface ResultType extends React.FC { + PRESENTED_IMAGE_403: typeof Image403; + PRESENTED_IMAGE_404: typeof Image404; + PRESENTED_IMAGE_500: typeof Image500; +} + +const Result: ResultType = ({ status, prefixCls: customizePrefixCls, ...restProps }) => { + const { getPrefixCls } = useContext(ConfigProvider.ConfigContext); + const prefixCls = getPrefixCls('result', customizePrefixCls); + const { wrapSSR } = useStyle(prefixCls); + const resultCls = classNames(prefixCls); + + const statusMap = { + success: , + error: , + warning: , + processing: , + 403: , + 404: , + 500: , + }; + + return wrapSSR( + + ); +}; + +Result.PRESENTED_IMAGE_403 = Image403; +Result.PRESENTED_IMAGE_404 = Image404; +Result.PRESENTED_IMAGE_500 = Image500; + +if (process.env.NODE_ENV !== 'production') { + Result.displayName = AntResult.displayName; +} + +export default Result; diff --git a/packages/design/src/result/style/index.ts b/packages/design/src/result/style/index.ts new file mode 100644 index 000000000..e0c9b4097 --- /dev/null +++ b/packages/design/src/result/style/index.ts @@ -0,0 +1,16 @@ +import type { CSSObject } from '@ant-design/cssinjs'; +import type { FullToken, GenerateStyle } from 'antd/es/theme/internal'; +import { genComponentStyleHook } from '../../_util/genComponentStyleHook'; + +export type ResultToken = FullToken<'Result'>; + +export const genResultStyle: GenerateStyle = (token: ResultToken): CSSObject => { + return {}; +}; + +export default (prefixCls: string) => { + const useStyle = genComponentStyleHook('Result', token => { + return [genResultStyle(token as ResultToken)]; + }); + return useStyle(prefixCls); +};