diff --git a/src/components/icon.tsx b/src/components/icon.tsx new file mode 100644 index 000000000..acb96617a --- /dev/null +++ b/src/components/icon.tsx @@ -0,0 +1,101 @@ +import React, { CSSProperties } from 'react'; + +interface IIconProps extends React.HTMLAttributes { + title?: string; + className?: string; + style?: CSSProperties; + onClick?: () => void; +} + +export function SearchIcon({ title, style, className }: IIconProps) { + return ( + + + + + + + + + + + + + + + + + + ); +} +export function LoupeIcon({ title, style, className }: IIconProps) { + return ( + + + + + + + + ); +} diff --git a/src/empty/__tests__/empty.test.tsx b/src/empty/__tests__/empty.test.tsx index 269c4897e..29986bb41 100644 --- a/src/empty/__tests__/empty.test.tsx +++ b/src/empty/__tests__/empty.test.tsx @@ -46,6 +46,18 @@ describe('Empty', () => { expect(srcValue).toEqual(IMG_MAP['project']); }); + it('should render SearchIcon and LoupeIcon when type is search and active is true', () => { + const { container } = render(); + expect(container.querySelector('.dtc-empty__search')).toBeInTheDocument(); + expect(container.querySelector('.dtc-empty__loupe')).toBeInTheDocument(); + }); + + it('should render SearchIcon and LoupeIcon when type is search and active is false', () => { + const { container } = render(); + expect(container.querySelector('.dtc-empty__search')).toBeFalsy(); + expect(container.querySelector('.dtc-empty__loupe')).toBeFalsy(); + }); + it('should show correct content when not empty', () => { const { container } = render( diff --git a/src/empty/index.md b/src/empty/index.md index 3c3bed17e..9c105c7d7 100644 --- a/src/empty/index.md +++ b/src/empty/index.md @@ -158,6 +158,19 @@ export default () => { }; ``` +```jsx +/** + * title: "使用动态的搜索图片" + */ +import React, { useState } from 'react'; +import { Empty } from 'dt-react-component'; +import { Space } from 'antd'; + +export default () => { + return ; +}; +``` + ## API | 参数 | 说明 | 类型 | 默认值 | @@ -167,6 +180,7 @@ export default () => { | showEmpty | 是否展示 Empty 组件 | `boolean` | `true` | | children | 展示内容 | `React.ReactNode` | - | | extra | 替换 antd Empty 的 children | ` React.ReactNode` | - | +| active | 是否展示动态的图片 | `boolean` | `true` | :::info 其余属性[继承 antd4.x 的 Empty](https://ant.design/components/empty-cn/#API) diff --git a/src/empty/index.tsx b/src/empty/index.tsx index a7b644978..abe1dc22f 100644 --- a/src/empty/index.tsx +++ b/src/empty/index.tsx @@ -1,6 +1,7 @@ import React, { ReactNode } from 'react'; import { Empty as AntdEmpty, EmptyProps as AntdEmptyProps } from 'antd'; +import { LoupeIcon, SearchIcon } from '../components/icon'; import './style.scss'; export const IMG_MAP = { @@ -17,6 +18,7 @@ export interface EmptyProps extends AntdEmptyProps { size?: 'default' | 'large'; showEmpty?: boolean; extra?: ReactNode; + active?: boolean; } const Empty = (props: EmptyProps) => { @@ -24,16 +26,29 @@ const Empty = (props: EmptyProps) => { type = 'default', size = 'default', showEmpty = true, + active = false, children, image, imageStyle, extra, ...restProps } = props; + const img = () => { + if (type === 'search' && active) { + return ( +
+ + +
+ ); + } else if (IMG_MAP[type]) { + return ; + } - let newImage: ReactNode = IMG_MAP[type] ? ( - - ) : null; + return null; + }; + + let newImage: ReactNode = img() || null; if (image) newImage = image as ReactNode; const height = size === 'default' ? 80 : 100; diff --git a/src/empty/style.scss b/src/empty/style.scss index 9282d02a2..8355bef7c 100644 --- a/src/empty/style.scss +++ b/src/empty/style.scss @@ -1,5 +1,10 @@ .dtc-empty { .ant-empty { + .ant-empty-image { + display: flex; + justify-content: center; + margin-bottom: 8px; + } .ant-empty-description { color: #8B8FA8; line-height: 20px; @@ -9,3 +14,45 @@ } } } + +.dtc-empty__container { + position: relative; + width: 80px; + height: 80px; + bottom: 8px; + .dtc-empty__search { + font-size: 80px; + position: absolute; + top: 0; + left: 0; + width: 80px; + height: 80px; + } + .dtc-empty__loupe { + font-size: 38px; + position: absolute; + width: 38px; + height: 38px; + animation: + animY 1s cubic-bezier(0.36, 0, 0.64, 1) 0.5s infinite alternate, + animX 1s cubic-bezier(0.36, 0, 0.64, 1) -0s infinite alternate; + } +} + +@keyframes animX { + 0% { + right: 10px; + } + 100% { + right: 25px; + } +} + +@keyframes animY { + 0% { + bottom: 2px; + } + 100% { + bottom: 17px; + } +}