From ba6757e85907a9e7ef89da05e58989f96b9077c4 Mon Sep 17 00:00:00 2001
From: Sendya <18x@loacg.com>
Date: Thu, 10 Oct 2019 15:16:37 +0800
Subject: [PATCH] feat: add Result component
---
components/index.js | 4 +
.../__tests__/__snapshots__/demo.test.js.snap | 98 ++++++
components/result/__tests__/demo.test.js | 3 +
components/result/__tests__/index.test.js | 66 ++++
components/result/demo/403.md | 31 ++
components/result/demo/404.md | 31 ++
components/result/demo/500.md | 31 ++
components/result/demo/customIcon.md | 30 ++
components/result/demo/error.md | 47 +++
components/result/demo/index.vue | 71 ++++
components/result/demo/info.md | 29 ++
components/result/demo/success.md | 32 ++
components/result/demo/warning.md | 27 ++
components/result/index.en-US.md | 9 +
components/result/index.jsx | 94 +++++
components/result/index.zh-CN.md | 9 +
components/result/noFound.svg | 280 +++++++++++++++
components/result/serverError.svg | 325 ++++++++++++++++++
components/result/style/index.js | 2 +
components/result/style/index.less | 71 ++++
components/result/unauthorized.svg | 141 ++++++++
site/components.js | 2 +
site/demo.js | 6 +
site/demoRoutes.js | 8 +
types/result.d.ts | 38 ++
25 files changed, 1485 insertions(+)
create mode 100644 components/result/__tests__/__snapshots__/demo.test.js.snap
create mode 100644 components/result/__tests__/demo.test.js
create mode 100644 components/result/__tests__/index.test.js
create mode 100644 components/result/demo/403.md
create mode 100644 components/result/demo/404.md
create mode 100644 components/result/demo/500.md
create mode 100644 components/result/demo/customIcon.md
create mode 100644 components/result/demo/error.md
create mode 100644 components/result/demo/index.vue
create mode 100644 components/result/demo/info.md
create mode 100644 components/result/demo/success.md
create mode 100644 components/result/demo/warning.md
create mode 100644 components/result/index.en-US.md
create mode 100644 components/result/index.jsx
create mode 100644 components/result/index.zh-CN.md
create mode 100644 components/result/noFound.svg
create mode 100644 components/result/serverError.svg
create mode 100644 components/result/style/index.js
create mode 100644 components/result/style/index.less
create mode 100644 components/result/unauthorized.svg
create mode 100644 types/result.d.ts
diff --git a/components/index.js b/components/index.js
index 7c6cc7313..cfb3b4429 100644
--- a/components/index.js
+++ b/components/index.js
@@ -137,6 +137,8 @@ import { default as ConfigProvider } from './config-provider';
import { default as Empty } from './empty';
+import { default as Result } from './result';
+
const components = [
Base,
Affix,
@@ -195,6 +197,7 @@ const components = [
Comment,
ConfigProvider,
Empty,
+ Result,
];
const install = function(Vue) {
@@ -279,6 +282,7 @@ export {
Comment,
ConfigProvider,
Empty,
+ Result,
};
export default {
diff --git a/components/result/__tests__/__snapshots__/demo.test.js.snap b/components/result/__tests__/__snapshots__/demo.test.js.snap
new file mode 100644
index 000000000..3268f0800
--- /dev/null
+++ b/components/result/__tests__/__snapshots__/demo.test.js.snap
@@ -0,0 +1,98 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders ./components/result/demo/403.md correctly 1`] = `
+
+
+
403
+
Sorry, you are not authorized to access this page.
+
+
+`;
+
+exports[`renders ./components/result/demo/404.md correctly 1`] = `
+
+
+
404
+
Sorry, the page you visited does not exist.
+
+
+`;
+
+exports[`renders ./components/result/demo/500.md correctly 1`] = `
+
+
+
500
+
Sorry, the server is wrong.
+
+
+`;
+
+exports[`renders ./components/result/demo/customIcon.md correctly 1`] = `
+
+
+
Great, we have done all the operations!
+
+
+
+`;
+
+exports[`renders ./components/result/demo/error.md correctly 1`] = `
+
+
+
Submission Failed
+
Please check and modify the following information before resubmitting.
+
+
+
The content you submitted has the following error:
+
Your account has been frozen Thaw immediately >
+
Your account is not yet eligible to apply Apply Unlock >
+
+
+
+
+`;
+
+exports[`renders ./components/result/demo/info.md correctly 1`] = `
+
+
+
Your operation has been executed
+
+
+
+`;
+
+exports[`renders ./components/result/demo/success.md correctly 1`] = `
+
+
+
Successfully Purchased Cloud Server ECS!
+
Order number: 2017182818828182881 Cloud server configuration takes 1-5 minutes, please wait.
+
+
+`;
+
+exports[`renders ./components/result/demo/warning.md correctly 1`] = `
+
+
+
There are some problems with your operation.
+
+
+
+`;
diff --git a/components/result/__tests__/demo.test.js b/components/result/__tests__/demo.test.js
new file mode 100644
index 000000000..bb3506ef1
--- /dev/null
+++ b/components/result/__tests__/demo.test.js
@@ -0,0 +1,3 @@
+import demoTest from '../../../tests/shared/demoTest';
+
+demoTest('result');
diff --git a/components/result/__tests__/index.test.js b/components/result/__tests__/index.test.js
new file mode 100644
index 000000000..fff8d2530
--- /dev/null
+++ b/components/result/__tests__/index.test.js
@@ -0,0 +1,66 @@
+import { mount } from '@vue/test-utils';
+import Result from '../index';
+import Button from '../../button';
+
+describe('Result', () => {
+
+ it('🙂 successPercent should decide the progress status when it exists', () => {
+ const wrapper = mount({
+ render () {
+ return (
+ Go Console}
+ />
+ );
+ },
+ });
+ expect(wrapper.findAll('.anticon-check-circle')).toHaveLength(1);
+ });
+
+ it('🙂 different status, different class', () => {
+ const wrapper = mount(Result, { propsData: { status: 'warning' } });
+ expect(wrapper.findAll('.ant-result-warning')).toHaveLength(1);
+
+ wrapper.setProps({
+ status: 'error',
+ });
+
+ expect(wrapper.findAll('.ant-result-error')).toHaveLength(1);
+
+ wrapper.setProps({
+ status: '500',
+ });
+
+ expect(wrapper.findAll('.ant-result-500')).toHaveLength(1);
+ });
+
+ it('🙂 When status = 404, the icon is an image', () => {
+ const wrapper = mount({
+ render () {
+ return ;
+ },
+ });
+ expect(wrapper.findAll('.ant-result-404 .ant-result-image')).toHaveLength(1);
+ });
+
+ it('🙂 When extra is undefined, the extra dom is undefined', () => {
+ const wrapper = mount({
+ render () {
+ return ;
+ },
+ });
+ expect(wrapper.findAll('.ant-result-extra')).toHaveLength(0);
+ });
+
+ it('🙂 result should support className', () => {
+ const wrapper = mount({
+ render () {
+ return ;
+ },
+ });
+ expect(wrapper.findAll('.ant-result.my-result')).toHaveLength(1);
+ });
+});
diff --git a/components/result/demo/403.md b/components/result/demo/403.md
new file mode 100644
index 000000000..d1606da22
--- /dev/null
+++ b/components/result/demo/403.md
@@ -0,0 +1,31 @@
+
+#### 403
+你没有此页面的访问权限。
+
+
+
+#### 403
+you are not authorized to access this page.
+
+
+```html
+
+
+
+ Back Home
+
+
+
+
+```
diff --git a/components/result/demo/404.md b/components/result/demo/404.md
new file mode 100644
index 000000000..850588a43
--- /dev/null
+++ b/components/result/demo/404.md
@@ -0,0 +1,31 @@
+
+#### 404
+此页面未找到。
+
+
+
+#### 404
+The page you visited does not exist.
+
+
+```html
+
+
+
+ Back Home
+
+
+
+
+```
diff --git a/components/result/demo/500.md b/components/result/demo/500.md
new file mode 100644
index 000000000..3e3830101
--- /dev/null
+++ b/components/result/demo/500.md
@@ -0,0 +1,31 @@
+
+#### 500
+服务器发生了错误。
+
+
+
+#### 500
+The server is wrong.
+
+
+```html
+
+
+
+ Back Home
+
+
+
+
+```
diff --git a/components/result/demo/customIcon.md b/components/result/demo/customIcon.md
new file mode 100644
index 000000000..0389bebce
--- /dev/null
+++ b/components/result/demo/customIcon.md
@@ -0,0 +1,30 @@
+
+#### 自定义 icon
+自定义 icon。
+
+
+
+#### Custom icon
+Custom icon.
+
+
+```html
+
+
+
+
+
+
+ Next
+
+
+
+
+```
diff --git a/components/result/demo/error.md b/components/result/demo/error.md
new file mode 100644
index 000000000..1293cb2be
--- /dev/null
+++ b/components/result/demo/error.md
@@ -0,0 +1,47 @@
+
+#### Error
+复杂的错误反馈。
+
+
+
+#### Error
+Complex error feedback.
+
+
+```html
+
+
+
+
+ Go Console
+
+
+ Buy Again
+
+
+
+
+
The content you submitted has the following error:
+
Your account has been frozen Thaw immediately >
+
Your account is not yet eligible to apply Apply Unlock >
+
+
+
+
+
+```
diff --git a/components/result/demo/index.vue b/components/result/demo/index.vue
new file mode 100644
index 000000000..fb87b832a
--- /dev/null
+++ b/components/result/demo/index.vue
@@ -0,0 +1,71 @@
+
diff --git a/components/result/demo/info.md b/components/result/demo/info.md
new file mode 100644
index 000000000..c3ee08064
--- /dev/null
+++ b/components/result/demo/info.md
@@ -0,0 +1,29 @@
+
+#### Info
+展示处理结果。
+
+
+
+#### Info
+Show processing results.
+
+
+```html
+
+
+
+
+ Go Console
+
+
+
+
+
+```
diff --git a/components/result/demo/success.md b/components/result/demo/success.md
new file mode 100644
index 000000000..414dab18f
--- /dev/null
+++ b/components/result/demo/success.md
@@ -0,0 +1,32 @@
+
+#### Success
+成功的结果。
+
+
+
+#### Success
+Show successful results.
+
+
+```html
+
+
+
+ Go Console
+ Buy Again
+
+
+
+
+```
diff --git a/components/result/demo/warning.md b/components/result/demo/warning.md
new file mode 100644
index 000000000..371cb5dad
--- /dev/null
+++ b/components/result/demo/warning.md
@@ -0,0 +1,27 @@
+
+#### Warning
+警告类型的结果。
+
+
+
+#### Warning
+The result of the warning.
+
+
+```html
+
+
+
+ Go Console
+
+
+
+
+```
diff --git a/components/result/index.en-US.md b/components/result/index.en-US.md
new file mode 100644
index 000000000..e86df6f6e
--- /dev/null
+++ b/components/result/index.en-US.md
@@ -0,0 +1,9 @@
+## API
+
+| Property | Description | Type | Default |
+| -------- | ------------------------------------- | ----------------------------------------------------------------- | ------- |
+| title | title string | string \| VNode \| v-slot:title | - |
+| subTitle | subTitle string | string \| VNode \| v-slot:subTitle | - |
+| status | result status,decide icons and colors | `'success' | 'error' | 'info' | 'warning'| '404' | '403' | '500'` | 'info' |
+| icon | custom back icon | v-slot:icon | - |
+| extra | operating area | v-slot:extra | - |
diff --git a/components/result/index.jsx b/components/result/index.jsx
new file mode 100644
index 000000000..5c75e27e8
--- /dev/null
+++ b/components/result/index.jsx
@@ -0,0 +1,94 @@
+import PropTypes from '../_util/vue-types';
+import { getOptionProps, getComponentFromProp } from '../_util/props-util';
+import { ConfigConsumerProps } from '../config-provider';
+import Icon from '../icon';
+import Base from '../base';
+import noFound from './noFound.svg';
+import serverError from './serverError.svg';
+import unauthorized from './unauthorized.svg';
+
+export const IconMap = {
+ success: 'check-circle',
+ error: 'close-circle',
+ info: 'exclamation-circle',
+ warning: 'warning',
+};
+
+export const ExceptionMap = {
+ '404': noFound,
+ '500': serverError,
+ '403': unauthorized,
+};
+
+// ExceptionImageMap keys
+const ExceptionStatus = Object.keys(ExceptionMap);
+
+export const ResultProps = {
+ prefixCls: PropTypes.string,
+ icon: PropTypes.any,
+ status: PropTypes.oneOf(['success', 'error', 'info', 'warning', '404', '403', '500']).def('info'),
+ title: PropTypes.any,
+ subTitle: PropTypes.any,
+ extra: PropTypes.any,
+};
+
+const renderIcon = (h, prefixCls, { status, icon }) => {
+ if (ExceptionStatus.includes(status)) {
+ const svgImg = ExceptionMap[status];
+ return (
+
+

+
+ );
+ }
+ // prop `icon` require slot or VNode
+ const iconString = IconMap[status];
+ const iconNode = icon || ;
+ return {iconNode}
;
+};
+
+const renderExtra = (h, prefixCls, extra) => extra && ;
+
+const Result = {
+ name: 'AResult',
+ props: ResultProps,
+ inject: {
+ configProvider: { default: () => ConfigConsumerProps },
+ },
+ render(h) {
+ const {
+ prefixCls: customizePrefixCls,
+ status,
+ ...restProps
+ } = getOptionProps(this);
+ const getPrefixCls = this.configProvider.getPrefixCls;
+ const prefixCls = getPrefixCls('result', customizePrefixCls);
+
+ const title = getComponentFromProp(this, 'title');
+ const subTitle = getComponentFromProp(this, 'subTitle');
+ const icon = getComponentFromProp(this, 'icon');
+ const extra = getComponentFromProp(this, 'extra');
+
+ return (
+
+ {renderIcon(h, prefixCls, { status, icon })}
+
{title}
+ {subTitle &&
{subTitle}
}
+ {this.$slots.default &&
{this.$slots.default}
}
+ {renderExtra(h, prefixCls, extra)}
+
+ );
+ },
+};
+
+/* 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(Vue) {
+ Vue.use(Base);
+ Vue.component(Result.name, Result);
+};
+export default Result;
diff --git a/components/result/index.zh-CN.md b/components/result/index.zh-CN.md
new file mode 100644
index 000000000..15d02eb28
--- /dev/null
+++ b/components/result/index.zh-CN.md
@@ -0,0 +1,9 @@
+## API
+
+| 参数 | 说明 | 类型 | 默认值 |
+| -------- | ------------------------- | ----------------------------------------------------------------- | ------ |
+| title | title 文字 | string \| VNode \| v-slot:title | - |
+| subTitle | subTitle 文字 | string \| VNode \| v-slot:subTitle | - |
+| status | 结果的状态,决定图标和颜色 | `'success' | 'error' | 'info' | 'warning'| '404' | '403' | '500'` | 'info' |
+| icon | 自定义 icon | v-slot:icon | - |
+| extra | 操作区 | v-slot:extra | - |
diff --git a/components/result/noFound.svg b/components/result/noFound.svg
new file mode 100644
index 000000000..5246a5cdf
--- /dev/null
+++ b/components/result/noFound.svg
@@ -0,0 +1,280 @@
+
diff --git a/components/result/serverError.svg b/components/result/serverError.svg
new file mode 100644
index 000000000..a8e933bb9
--- /dev/null
+++ b/components/result/serverError.svg
@@ -0,0 +1,325 @@
+
diff --git a/components/result/style/index.js b/components/result/style/index.js
new file mode 100644
index 000000000..3a3ab0de5
--- /dev/null
+++ b/components/result/style/index.js
@@ -0,0 +1,2 @@
+import '../../style/index.less';
+import './index.less';
diff --git a/components/result/style/index.less b/components/result/style/index.less
new file mode 100644
index 000000000..5ebf40dcf
--- /dev/null
+++ b/components/result/style/index.less
@@ -0,0 +1,71 @@
+@import '../../style/themes/default';
+@import '../../style/mixins/index';
+
+@result-prefix-cls: ~'@{ant-prefix}-result';
+
+.@{result-prefix-cls} {
+ padding: 48px 32px;
+ // status color
+ &-success &-icon > .anticon {
+ color: @success-color;
+ }
+
+ &-error &-icon > .anticon {
+ color: @error-color;
+ }
+
+ &-info &-icon > .anticon {
+ color: @info-color;
+ }
+
+ &-warning &-icon > .anticon {
+ color: @warning-color;
+ }
+
+ // Exception Status image
+ &-image {
+ width: 250px;
+ height: 295px;
+ margin: auto;
+ }
+
+ &-icon {
+ margin-bottom: 24px;
+ text-align: center;
+
+ > .anticon {
+ font-size: 72px;
+ }
+ }
+
+ &-title {
+ color: @heading-color;
+ font-size: 24px;
+ line-height: 1.8;
+ text-align: center;
+ }
+
+ &-subtitle {
+ color: @text-color-secondary;
+ font-size: 14px;
+ line-height: 1.6;
+ text-align: center;
+ }
+
+ &-extra {
+ margin-top: 32px;
+ text-align: center;
+ > * {
+ margin-right: 8px;
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+
+ &-content {
+ margin-top: 24px;
+ padding: 24px 40px;
+ background-color: @background-color-light;
+ }
+}
diff --git a/components/result/unauthorized.svg b/components/result/unauthorized.svg
new file mode 100644
index 000000000..e3974c977
--- /dev/null
+++ b/components/result/unauthorized.svg
@@ -0,0 +1,141 @@
+
diff --git a/site/components.js b/site/components.js
index 4a4df60ec..5fd855ddf 100644
--- a/site/components.js
+++ b/site/components.js
@@ -61,6 +61,7 @@ import {
ConfigProvider,
Empty,
Base,
+ Result,
} from 'ant-design-vue';
Vue.prototype.$message = message;
@@ -130,6 +131,7 @@ Vue.use(Skeleton);
Vue.use(Comment);
Vue.use(ConfigProvider);
Vue.use(Empty);
+Vue.use(Result);
/* v1.1.2 registration methods */
// Vue.component(Affix.name, Affix) // a-affix
diff --git a/site/demo.js b/site/demo.js
index 654774385..636ccf3bb 100644
--- a/site/demo.js
+++ b/site/demo.js
@@ -174,6 +174,12 @@ export default {
type: 'Feedback',
title: 'Spin',
},
+ result: {
+ category: 'Components',
+ subtitle: '结果',
+ type: 'Feedback',
+ title: 'Result',
+ },
switch: {
category: 'Components',
subtitle: '开关',
diff --git a/site/demoRoutes.js b/site/demoRoutes.js
index b23c6d993..5aa0e8445 100644
--- a/site/demoRoutes.js
+++ b/site/demoRoutes.js
@@ -455,4 +455,12 @@ export default [
path: 'empty-cn',
component: () => import('../components/empty/demo/index.vue'),
},
+ {
+ path: 'result',
+ component: () => import('../components/result/demo/index.vue'),
+ },
+ {
+ path: 'result-cn',
+ component: () => import('../components/result/demo/index.vue'),
+ },
];
diff --git a/types/result.d.ts b/types/result.d.ts
new file mode 100644
index 000000000..455de57c0
--- /dev/null
+++ b/types/result.d.ts
@@ -0,0 +1,38 @@
+import { AntdComponent } from './component';
+
+export declare class Result extends AntdComponent {
+ /**
+ * result title
+ * @type string
+ */
+ title: string;
+
+ /**
+ * result sub title
+ *
+ * @type string
+ */
+ subTitle: string;
+
+ /**
+ * result status,decide icons and colors
+ * enum of 'success' | 'error' | 'info' | 'warning'| '404' | '403' | '500'` | 'info'
+ *
+ * @default 'info'
+ * @type string
+ */
+ status: string;
+
+ /**
+ * custom back icon
+ * @type any v-slot
+ */
+ icon: any;
+
+ /**
+ * operating area
+ * @type any v-slot
+ */
+ extra: any;
+
+}