From 8eb12cb45af3d29e2e9c09ec657bb8ea324895a9 Mon Sep 17 00:00:00 2001 From: awmleer Date: Sun, 29 May 2022 12:28:37 +0800 Subject: [PATCH] feat(ErrorBlock): add `createErrorBlock` function for generating more light-weighted or customized ErrorBlock --- .../error-block/create-error-block.tsx | 68 ++++++++++++++++ src/components/error-block/demos/demo-3.tsx | 23 ++++++ src/components/error-block/demos/demo-4.less | 4 + src/components/error-block/demos/demo-4.tsx | 23 ++++++ src/components/error-block/error-block.tsx | 81 ++++--------------- src/components/error-block/images/index.tsx | 19 +---- src/components/error-block/index.en.md | 53 +++++++++++- src/components/error-block/index.ts | 8 +- src/components/error-block/index.zh.md | 53 +++++++++++- src/index.ts | 2 + 10 files changed, 250 insertions(+), 84 deletions(-) create mode 100644 src/components/error-block/create-error-block.tsx create mode 100644 src/components/error-block/demos/demo-3.tsx create mode 100644 src/components/error-block/demos/demo-4.less create mode 100644 src/components/error-block/demos/demo-4.tsx diff --git a/src/components/error-block/create-error-block.tsx b/src/components/error-block/create-error-block.tsx new file mode 100644 index 0000000000..6b920c241d --- /dev/null +++ b/src/components/error-block/create-error-block.tsx @@ -0,0 +1,68 @@ +import React, { FC, ReactElement, ReactNode } from 'react' +import classNames from 'classnames' +import { mergeProps } from '../../utils/with-default-props' +import { NativeProps, withNativeProps } from '../../utils/native-props' +import { useConfig } from '../config-provider' +import type { ErrorBlockStatus, ImageRecord } from '.' + +const classPrefix = `adm-error-block` + +export type ErrorBlockProps = { + status?: ErrorBlockStatus + title?: ReactNode + image?: string | ReactElement + description?: ReactNode + fullPage?: boolean + children?: React.ReactNode +} & NativeProps< + | '--image-height' + | '--image-height-full-page' + | '--image-width' + | '--image-width-full-page' +> + +const defaultProps = { + status: 'default', +} + +export function createErrorBlock(imageRecord: ImageRecord) { + const ErrorBlock: FC = p => { + const props = mergeProps(defaultProps, p) + const { locale } = useConfig() + const contentPack = locale.ErrorBlock[props.status] + const des = + 'description' in props ? props.description : contentPack.description + const title = 'title' in props ? props.title : contentPack.title + const image: ReactNode = props.image ?? imageRecord[props.status] + const imageNode = + typeof image === 'string' ? ( + error block image + ) : ( + image + ) + + return withNativeProps( + props, +
+
{imageNode}
+
+ {title && ( +
{title}
+ )} + {des && ( +
{des}
+ )} +
+ + {props.children && ( +
{props.children}
+ )} +
+ ) + } + return ErrorBlock +} diff --git a/src/components/error-block/demos/demo-3.tsx b/src/components/error-block/demos/demo-3.tsx new file mode 100644 index 0000000000..b5d07157e5 --- /dev/null +++ b/src/components/error-block/demos/demo-3.tsx @@ -0,0 +1,23 @@ +import React from 'react' +import { createErrorBlock, Space } from 'antd-mobile' +import { DemoBlock } from 'demos' +import { defaultImage } from 'antd-mobile/es/components/error-block/images' + +const ErrorBlock = createErrorBlock({ + 'default': defaultImage, + 'empty': + 'https://gw.alipayobjects.com/zos/bmw-prod/7a2970f8-9247-4196-b3b3-2d0218c18b59.svg', +}) + +export default () => { + return ( + <> + + + + + + + + ) +} diff --git a/src/components/error-block/demos/demo-4.less b/src/components/error-block/demos/demo-4.less new file mode 100644 index 0000000000..c2f13c9faf --- /dev/null +++ b/src/components/error-block/demos/demo-4.less @@ -0,0 +1,4 @@ +.myErrorBlockIcon { + font-size: 48px; + color: var(--adm-color-weak); +} diff --git a/src/components/error-block/demos/demo-4.tsx b/src/components/error-block/demos/demo-4.tsx new file mode 100644 index 0000000000..2d1eb5a2d1 --- /dev/null +++ b/src/components/error-block/demos/demo-4.tsx @@ -0,0 +1,23 @@ +import React from 'react' +import { createErrorBlock, Space } from 'antd-mobile' +import { DemoBlock } from 'demos' +import { FileWrongOutline, SearchOutline } from 'antd-mobile-icons' +import styles from './demo-4.less' + +const ErrorBlock = createErrorBlock({ + 'default': , + 'empty': , +}) + +export default () => { + return ( + <> + + + + + + + + ) +} diff --git a/src/components/error-block/error-block.tsx b/src/components/error-block/error-block.tsx index cac4a13190..7af9782e0c 100644 --- a/src/components/error-block/error-block.tsx +++ b/src/components/error-block/error-block.tsx @@ -1,67 +1,20 @@ -import React, { FC, ReactElement, ReactNode } from 'react' -import classNames from 'classnames' -import { mergeProps } from '../../utils/with-default-props' -import { NativeProps, withNativeProps } from '../../utils/native-props' -import { useConfig } from '../config-provider' -import { imageRecord } from './images' +import { createErrorBlock } from './create-error-block' +import { ReactElement } from 'react' +import { + busyImage, + defaultImage, + disconnectedImage, + emptyImage, +} from './images' -const classPrefix = `adm-error-block` - -export type ErrorBlockProps = { - status?: 'default' | 'disconnected' | 'empty' | 'busy' - title?: ReactNode - image?: string | ReactElement - description?: ReactNode - fullPage?: boolean - children?: React.ReactNode -} & NativeProps< - | '--image-height' - | '--image-height-full-page' - | '--image-width' - | '--image-width-full-page' -> - -const defaultProps = { - status: 'default', +const imageRecord: Record< + 'default' | 'disconnected' | 'empty' | 'busy', + ReactElement +> = { + 'default': defaultImage, + 'disconnected': disconnectedImage, + 'empty': emptyImage, + 'busy': busyImage, } -export const ErrorBlock: FC = p => { - const props = mergeProps(defaultProps, p) - const { locale } = useConfig() - const contentPack = locale.ErrorBlock[props.status] - const des = - 'description' in props ? props.description : contentPack.description - const title = 'title' in props ? props.title : contentPack.title - let imageNode: ReactNode = imageRecord[props.status] - - if (props.image) { - if (typeof props.image === 'string') { - imageNode = error block image - } else { - imageNode = props.image - } - } - - return withNativeProps( - props, -
-
{imageNode}
-
- {title && ( -
{title}
- )} - {des && ( -
{des}
- )} -
- - {props.children && ( -
{props.children}
- )} -
- ) -} +export const ErrorBlock = createErrorBlock(imageRecord) diff --git a/src/components/error-block/images/index.tsx b/src/components/error-block/images/index.tsx index 09d5a98bbc..aad0006727 100644 --- a/src/components/error-block/images/index.tsx +++ b/src/components/error-block/images/index.tsx @@ -1,15 +1,4 @@ -import { ReactElement } from 'react' -import { defaultImage } from './default' -import { disconnectedImage } from './disconnected' -import { emptyImage } from './empty' -import { busyImage } from './busy' - -export const imageRecord: Record< - 'default' | 'disconnected' | 'empty' | 'busy', - ReactElement -> = { - 'default': defaultImage, - 'disconnected': disconnectedImage, - 'empty': emptyImage, - 'busy': busyImage, -} +export { defaultImage } from './default' +export { disconnectedImage } from './disconnected' +export { emptyImage } from './empty' +export { busyImage } from './busy' diff --git a/src/components/error-block/index.en.md b/src/components/error-block/index.en.md index 2c59c27d3a..1f758f2400 100644 --- a/src/components/error-block/index.en.md +++ b/src/components/error-block/index.en.md @@ -6,14 +6,16 @@ Use scene illustrations to indicate page exceptions. Feedback prompts for six abnormal scenarios. +## ErrorBlock + +### Demos + -## ErrorBlock - ### Props | Name | Description | Type | Default | @@ -32,3 +34,50 @@ Feedback prompts for six abnormal scenarios. | --image-height-full-page | Height of the image in `fullPage` mode | `200px` | `--adm-error-block-image-height-full-page` | | --image-width | Width of the image | `auto` | `--adm-error-block-image-width` | | --image-width-full-page | Width of the image in `fullPage` mode | `auto` | `--adm-error-block-image-width-full-page` | + +## createErrorBlock + +The `ErrorBlock` component is very simple to use, but it inevitably brings a problem: since we don't know which `status` you will use, we can only package image resources in four states. There will be some package size problems. + +In order to import as few resources as possible, we provide a utility function `createErrorBlock`, which you can use to create a custom `ErrorBlock` component that contains only the materials you need. + +Its type definition is: + +```ts +declare function createErrorBlock(imageRecord: ImageRecord): React.ComponentType + +type ImageRecord = Partial> +type ErrorBlockStatus = 'default' | 'disconnected' | 'empty' | 'busy' +``` + +For example: + +### Demos + +If in your application, the ErrorBlock only needs to support the `default` state, then you can create a lightweight ErrorBlock that only packs the `default` image material like this: + +```jsx +import {defaultImage} from 'antd-mobile/es/components/error-block/images' + +const ErrorBlock = createErrorBlock({ + 'default': defaultImage, +}) +``` + +We have exported images corresponding to four states in `antd-mobile/es/components/error-block/images`, you can use them directly: `defaultImage` `disconnectedImage` `emptyImage` `busyImage`. + +Even, you can directly configure the image resources in the online CDN, which can greatly reduce the packaging size: + +```jsx +const ErrorBlock = createErrorBlock({ + 'empty': 'https://gw.alipayobjects.com/zos/bmw-prod/7a2970f8-9247-4196-b3b3-2d0218c18b59.svg', +}) +``` + +The final effect is: + + + +`createErrorBlock` does more than that, you can also use it to configure custom image presets to create a custom version of ErrorBlock. You can replace the image material to match the visual style of your own project, or replace it with a minimalist icon like this: + + diff --git a/src/components/error-block/index.ts b/src/components/error-block/index.ts index 8665687171..f40a004c74 100644 --- a/src/components/error-block/index.ts +++ b/src/components/error-block/index.ts @@ -1,6 +1,12 @@ import './error-block.less' +import { ReactNode } from 'react' import { ErrorBlock } from './error-block' -export type { ErrorBlockProps } from './error-block' +export { createErrorBlock } from './create-error-block' + +export type { ErrorBlockProps } from './create-error-block' + +export type ErrorBlockStatus = 'default' | 'disconnected' | 'empty' | 'busy' +export type ImageRecord = Partial> export default ErrorBlock diff --git a/src/components/error-block/index.zh.md b/src/components/error-block/index.zh.md index 256de9c880..95077f2009 100644 --- a/src/components/error-block/index.zh.md +++ b/src/components/error-block/index.zh.md @@ -6,14 +6,16 @@ 适用于六种异常场景的反馈提示。 +## ErrorBlock + +### 示例 + -## ErrorBlock - ### 属性 | 属性 | 说明 | 类型 | 默认值 | @@ -32,3 +34,50 @@ | --image-height-full-page | 整页模式下的图片高度 | `200px` | `--adm-error-block-image-height-full-page` | | --image-width | 图片的宽度 | `auto` | `--adm-error-block-image-width` | | --image-width-full-page | 整页模式下的图片宽度 | `auto` | `--adm-error-block-image-width-full-page` | + +## createErrorBlock + +`ErrorBlock` 组件用起来非常简单,但是它不可避免的带来了一个问题:由于我们不知道你会用到哪些 `status`,所以我们只能把四种状态下的图片资源都打包进来,这会带来一些包体积上的问题。 + +为了能够尽可能少的引入资源,我们提供了一个工具函数 `createErrorBlock`,你可以使用它来创建一个定制化的 `ErrorBlock` 组件,其中只包含你需要的素材。 + +它的类型定义是: + +```ts +declare function createErrorBlock(imageRecord: ImageRecord): React.ComponentType + +type ImageRecord = Partial> +type ErrorBlockStatus = 'default' | 'disconnected' | 'empty' | 'busy' +``` + +例如: + +### 示例 + +如果在你的应用中,ErrorBlock 只需要支持 `default` 这种状态,那么你可以这样创建一个只打包了 `default` 图片素材的轻量化的 ErrorBlock: + +```jsx +import {defaultImage} from 'antd-mobile/es/components/error-block/images' + +const ErrorBlock = createErrorBlock({ + 'default': defaultImage, +}) +``` + +我们在 `antd-mobile/es/components/error-block/images` 中 export 了四种状态对应的图片,你可以直接使用它们:`defaultImage` `disconnectedImage` `emptyImage` `busyImage`。 + +甚至,你可以直接配置成在线 CDN 中的图片资源,这样就可以很大程度上降低打包体积: + +```jsx +const ErrorBlock = createErrorBlock({ + 'empty': 'https://gw.alipayobjects.com/zos/bmw-prod/7a2970f8-9247-4196-b3b3-2d0218c18b59.svg', +}) +``` + +最终效果是: + + + +`createErrorBlock` 的作用不止于此,你还可以使用它配置自定义的图片预设,创建出一个定制版的 ErrorBlock。你可以把图片素材替换成符合你自己项目中视觉风格的,也可以像下面这样替换成极简风格的图标: + + diff --git a/src/index.ts b/src/index.ts index d34ab2eaca..0d018083e5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -79,3 +79,5 @@ export { default as Toast } from './components/toast' export { default as TreeSelect } from './components/tree-select' export { default as VirtualInput } from './components/virtual-input' export { default as WaterMark } from './components/water-mark' + +export { createErrorBlock } from './components/error-block'