diff --git a/.gitignore b/.gitignore index 1b026b304e..7c87415936 100644 --- a/.gitignore +++ b/.gitignore @@ -58,5 +58,9 @@ pnpm-lock.*.yaml # vitest /html +# local v4 upgrade workflow (personal, not for commit) +.cursor/skills/nutui-component-v4-upgrade/ +.claude/commands/nutui-v4-upgrade.md + # Harmony CSS files src/packages/**/*.harmony.css \ No newline at end of file diff --git a/src/packages/configprovider/types.ts b/src/packages/configprovider/types.ts index cb8829f00f..73bfd07a94 100644 --- a/src/packages/configprovider/types.ts +++ b/src/packages/configprovider/types.ts @@ -772,13 +772,26 @@ export type NutCSSVariables = | 'nutuiSegmentedActiveBackground' | 'nutuiSegmentedIconMarginRight' | 'nutuiEmptyPadding' - | 'nutuiEmptyImageSize' - | 'nutuiEmptyImageSmallSize' - | 'nutuiEmptyTitleMarginTop' - | 'nutuiEmptyBackgroundColor' - | 'nutuiEmptyTitleMarginBottom' - | 'nutuiEmptyTitleLineHeight' - | 'nutuiEmptyDescriptionLineHeight' + | 'nutuiEmptyTitleColor' + | 'nutuiEmptyDescriptionColor' + | 'nutuiEmptyFullPaddingTop' + | 'nutuiEmptyFullImageSize' + | 'nutuiEmptyFullTitleFontSize' + | 'nutuiEmptyFullTitleLineHeight' + | 'nutuiEmptyFullDescriptionFontSize' + | 'nutuiEmptyFullDescriptionLineHeight' + | 'nutuiEmptyFullActionsMarginTop' + | 'nutuiEmptyHalfImageSize' + | 'nutuiEmptyHalfTitleFontSize' + | 'nutuiEmptyHalfTitleLineHeight' + | 'nutuiEmptyHalfDescriptionFontSize' + | 'nutuiEmptyHalfDescriptionLineHeight' + | 'nutuiEmptyHalfActionsMarginTop' + | 'nutuiEmptyPartialPadding' + | 'nutuiEmptyPartialImageSize' + | 'nutuiEmptyPartialContentGap' + | 'nutuiEmptyPartialDescriptionFontSize' + | 'nutuiEmptyPartialDescriptionLineHeight' | 'nutuiCascaderFontSize' | 'nutuiCascaderPaneHeight' | 'nutuiCascaderPanePaddingTop' diff --git a/src/packages/empty/__test__/__snapshots__/empty.spec.tsx.snap b/src/packages/empty/__test__/__snapshots__/empty.spec.tsx.snap index 93e53ef345..c5c2f03107 100644 --- a/src/packages/empty/__test__/__snapshots__/empty.spec.tsx.snap +++ b/src/packages/empty/__test__/__snapshots__/empty.spec.tsx.snap @@ -3,14 +3,14 @@ exports[`should render description correctly 1`] = `
empty
diff --git a/src/packages/empty/__test__/empty.spec.tsx b/src/packages/empty/__test__/empty.spec.tsx index 3f27c2685d..d82138c524 100644 --- a/src/packages/empty/__test__/empty.spec.tsx +++ b/src/packages/empty/__test__/empty.spec.tsx @@ -1,7 +1,8 @@ import * as React from 'react' -import { render } from '@testing-library/react' +import { render, waitFor } from '@testing-library/react' import '@testing-library/jest-dom' +import { EMPTY_STATUS_IMAGES } from '@/types' import { Empty } from '../empty' test('should render description correctly', () => { @@ -9,21 +10,64 @@ test('should render description correctly', () => { expect(getByText('暂无数据')).toBeTruthy() expect(container).toMatchSnapshot() }) -test('should render imageSize correctly', () => { + +test('should render title correctly', () => { + const { getByText } = render( + + ) + expect(getByText('网络连接已断开')).toHaveClass('nut-empty-title') +}) + +test('should use default half size and network status image', () => { + const { container } = render() + expect(container.querySelector('.nut-empty')).toHaveClass('nut-empty--half') + expect(container.querySelector('.nut-empty-image img')).toHaveAttribute( + 'src', + EMPTY_STATUS_IMAGES.network + ) +}) + +test('should render imageSize correctly', async () => { const { container } = render() - // expect(container.querySelector('.nut-empty-image')).toHaveStyle({ - // width: '100px', - // }) + await waitFor(() => { + expect(container.querySelector('.nut-empty-image')).toHaveStyle({ + width: '100px', + height: '100px', + }) + }) }) -test('should render image props correctly', () => { - const { container } = render() - // expect(container.querySelector('.img')).toHaveAttribute( - // 'src', - // 'https://storage.360buyimg.com/imgtools/30186cfda0-0d3eee40-c0ac-11ee-9382-9125782aa3b8.png' - // ) + +test('should render status image correctly', () => { + const { container } = render() + expect(container.querySelector('.nut-empty-image img')).toHaveAttribute( + 'src', + EMPTY_STATUS_IMAGES.search + ) }) + +test('should render full size modifier class', () => { + const { container } = render( + + ) + expect(container.querySelector('.nut-empty')).toHaveClass('nut-empty--full') + expect( + container.querySelector('.nut-empty-partial-body') + ).not.toBeInTheDocument() +}) + +test('should render partial layout structure', () => { + const { container } = render( + + ) + expect(container.querySelector('.nut-empty')).toHaveClass( + 'nut-empty--partial' + ) + expect(container.querySelector('.nut-empty-partial-body')).toBeInTheDocument() + expect(container.querySelector('.nut-empty-content')).toBeInTheDocument() +}) + test('should render actions correctly', () => { - const { container, getByTestId } = render( + const { container } = render( { actions={[{ text: '操作1' }, { text: '操作2' }]} /> ) - expect(container.querySelector('.nut-empty-actions-base')).toBeTruthy() + expect(container.querySelector('.nut-empty-actions')).toBeTruthy() expect( - container.querySelectorAll('.nut-empty-actions-base .nut-button').length + container.querySelectorAll('.nut-empty-actions .nut-button').length ).toEqual(2) }) + test('should render custom image correctly', () => { const { getByTestId } = render( { 'https://static-ftcms.jd.com/p/files/61a9e3313985005b3958672e.png' ) }) + +test('should render children correctly', () => { + const { getByTestId } = render( + + + + ) + expect(getByTestId('custom-child')).toBeInTheDocument() +}) diff --git a/src/packages/empty/demo.taro.tsx b/src/packages/empty/demo.taro.tsx index eaffb8054f..ea4c84dfb6 100644 --- a/src/packages/empty/demo.taro.tsx +++ b/src/packages/empty/demo.taro.tsx @@ -9,32 +9,36 @@ import Demo3 from './demos/taro/demo3' import Demo4 from './demos/taro/demo4' import Demo5 from './demos/taro/demo5' import Demo6 from './demos/taro/demo6' +import Demo7 from './demos/taro/demo7' const EmptyDemo = () => { const [translated] = useTranslate({ 'zh-CN': { - ce5c5446: '基础用法', - c38a08ee: 'Size 为 small 时,可用于半屏', - c38a08ef: '自定义内容大小', - b840c88f: '图片类型,内置3个', + ce5c5446: '全屏 full', + c38a08ee: '半屏 half', + c38a08ed: '局部 partial', + c38a08ef: '自定义图片大小', + b840c88f: '图片类型,内置8个', a74a1fd4: '自定义图片', - '8dab2f66': '底部内容', + '8dab2f66': '自定义底部按钮', }, 'zh-TW': { - ce5c5446: '基礎用法', - c38a08ee: 'Size 为 small 时,可用于半屏', - c38a08ef: '自定義內容大小', - b840c88f: '圖片類型,內置3個', + ce5c5446: '全屏 full', + c38a08ee: '半屏 half', + c38a08ed: '局部 partial', + c38a08ef: '自定義圖片大小', + b840c88f: '圖片類型,內置8個', a74a1fd4: '自定義圖片', - '8dab2f66': '底部內容', + '8dab2f66': '自定義底部按鈕', }, 'en-US': { - ce5c5446: 'Basic usage', - c38a08ee: 'Size is small', - c38a08ef: 'Custom content size', - b840c88f: 'Picture type, built-in 3', + ce5c5446: 'Full', + c38a08ee: 'Half', + c38a08ed: 'Partial', + c38a08ef: 'Custom image size', + b840c88f: 'Picture type, built-in 8', a74a1fd4: 'Custom image', - '8dab2f66': 'Bottom content', + '8dab2f66': 'Custom bottom buttons', }, }) @@ -46,10 +50,12 @@ const EmptyDemo = () => { {translated.c38a08ee} - {translated.c38a08ef} + {translated.c38a08ed} {translated.b840c88f} + {translated.c38a08ef} + {translated.a74a1fd4} {translated['8dab2f66']} diff --git a/src/packages/empty/demo.tsx b/src/packages/empty/demo.tsx index 56ea6d42b9..029b17f8d2 100644 --- a/src/packages/empty/demo.tsx +++ b/src/packages/empty/demo.tsx @@ -6,32 +6,36 @@ import Demo3 from './demos/h5/demo3' import Demo4 from './demos/h5/demo4' import Demo5 from './demos/h5/demo5' import Demo6 from './demos/h5/demo6' +import Demo7 from './demos/h5/demo7' const EmptyDemo = () => { const [translated] = useTranslate({ 'zh-CN': { - ce5c5446: '基础用法', - c38a08ee: 'Size 为 small 时,可用于半屏', - c38a08ef: '自定义内容大小', - b840c88f: '图片类型,内置3个', + ce5c5446: '全屏 full', + c38a08ee: '半屏 half', + c38a08ed: '局部 partial', + c38a08ef: '自定义图片大小', + b840c88f: '图片类型,内置8个', a74a1fd4: '自定义图片', - '8dab2f66': '底部内容', + '8dab2f66': '自定义底部按钮', }, 'zh-TW': { - ce5c5446: '基礎用法', - c38a08ee: 'Size 为 small 时,可用于半屏', - c38a08ef: '自定義內容大小', - b840c88f: '圖片類型,內置3個', + ce5c5446: '全屏 full', + c38a08ee: '半屏 half', + c38a08ed: '局部 partial', + c38a08ef: '自定義圖片大小', + b840c88f: '圖片類型,內置8個', a74a1fd4: '自定義圖片', - '8dab2f66': '底部內容', + '8dab2f66': '自定義底部按鈕', }, 'en-US': { - ce5c5446: 'Basic usage', - c38a08ee: 'Size is small', - c38a08ef: 'Custom content size', - b840c88f: 'Picture type, built-in 3', + ce5c5446: 'Full', + c38a08ee: 'Half', + c38a08ed: 'Partial', + c38a08ef: 'Custom image size', + b840c88f: 'Picture type, built-in 8', a74a1fd4: 'Custom image', - '8dab2f66': 'Bottom content', + '8dab2f66': 'Custom bottom buttons', }, }) @@ -41,10 +45,12 @@ const EmptyDemo = () => {

{translated.c38a08ee}

-

{translated.c38a08ef}

+

{translated.c38a08ed}

{translated.b840c88f}

+

{translated.c38a08ef}

+

{translated.a74a1fd4}

{translated['8dab2f66']}

diff --git a/src/packages/empty/demos/h5/demo1.tsx b/src/packages/empty/demos/h5/demo1.tsx index 8aec3ada54..d912b0430c 100644 --- a/src/packages/empty/demos/h5/demo1.tsx +++ b/src/packages/empty/demos/h5/demo1.tsx @@ -1,24 +1,23 @@ import React from 'react' -import { Empty } from '@nutui/nutui-react' +import { Cell, Empty, Toast } from '@nutui/nutui-react' const Demo1 = () => { return ( - <> + Toast.show('正在刷新...'), + }, + ]} /> - - - + ) } export default Demo1 diff --git a/src/packages/empty/demos/h5/demo2.tsx b/src/packages/empty/demos/h5/demo2.tsx index b33f413281..fc2b50710e 100644 --- a/src/packages/empty/demos/h5/demo2.tsx +++ b/src/packages/empty/demos/h5/demo2.tsx @@ -1,13 +1,27 @@ import React from 'react' -import { Empty } from '@nutui/nutui-react' +import { Cell, Empty, Toast } from '@nutui/nutui-react' const Demo2 = () => { return ( - + + Toast.show('逛逛秒杀'), + }, + { + text: '看看关注', + type: 'primary', + onClick: () => Toast.show('看看关注'), + }, + ]} + /> + ) } export default Demo2 diff --git a/src/packages/empty/demos/h5/demo3.tsx b/src/packages/empty/demos/h5/demo3.tsx index b32231b793..553082ccd6 100644 --- a/src/packages/empty/demos/h5/demo3.tsx +++ b/src/packages/empty/demos/h5/demo3.tsx @@ -1,7 +1,11 @@ import React from 'react' -import { Empty } from '@nutui/nutui-react' +import { Cell, Empty } from '@nutui/nutui-react' const Demo3 = () => { - return + return ( + + + + ) } export default Demo3 diff --git a/src/packages/empty/demos/h5/demo4.tsx b/src/packages/empty/demos/h5/demo4.tsx index 31dbd568d0..7f8ad9e008 100644 --- a/src/packages/empty/demos/h5/demo4.tsx +++ b/src/packages/empty/demos/h5/demo4.tsx @@ -1,5 +1,48 @@ import React, { useState } from 'react' -import { Tabs, TabPane, Empty } from '@nutui/nutui-react' +import { Empty, TabPane, Tabs } from '@nutui/nutui-react' + +const statusList = [ + { + status: 'network' as const, + title: '网络连接已断开', + description: '请检查网络设置或刷新页面', + }, + { + status: 'comment' as const, + title: '暂无评价', + description: '快来发表第一条评价吧', + }, + { + status: 'search' as const, + title: '暂无搜索结果', + description: '换个关键词试试吧', + }, + { + status: 'shop' as const, + title: '暂无店铺', + description: '去看看其他店铺吧', + }, + { + status: 'address' as const, + title: '暂无收货地址', + description: '添加地址,享受便捷购物', + }, + { + status: 'order' as const, + title: '暂无订单', + description: '快去挑选心仪的商品吧', + }, + { + status: 'favor' as const, + title: '暂无收藏', + description: '收藏喜欢的商品,方便下次查看', + }, + { + status: 'cart' as const, + title: '小购物车大容量', + description: '把喜欢的商品都加进来吧', + }, +] const Demo4 = () => { const [tabvalue, setTabvalue] = useState('0') @@ -11,15 +54,16 @@ const Demo4 = () => { setTabvalue(paneKey) }} > - - - - - - - - - + {statusList.map((item, index) => ( + + + + ))} ) } diff --git a/src/packages/empty/demos/h5/demo5.tsx b/src/packages/empty/demos/h5/demo5.tsx index 489649136e..575a22fea4 100644 --- a/src/packages/empty/demos/h5/demo5.tsx +++ b/src/packages/empty/demos/h5/demo5.tsx @@ -1,17 +1,19 @@ import React from 'react' -import { Empty } from '@nutui/nutui-react' +import { Cell, Empty } from '@nutui/nutui-react' const Demo5 = () => { return ( - - } - /> + + + } + /> + ) } export default Demo5 diff --git a/src/packages/empty/demos/h5/demo6.tsx b/src/packages/empty/demos/h5/demo6.tsx index b160f4a3b4..5318f1daab 100644 --- a/src/packages/empty/demos/h5/demo6.tsx +++ b/src/packages/empty/demos/h5/demo6.tsx @@ -1,19 +1,17 @@ import React from 'react' -import { Empty, Button } from '@nutui/nutui-react' +import { Button, Cell, Empty } from '@nutui/nutui-react' const Demo6 = () => { return ( - -
- -
-
+ + +
+ +
+
+
) } export default Demo6 diff --git a/src/packages/empty/demos/h5/demo7.tsx b/src/packages/empty/demos/h5/demo7.tsx new file mode 100644 index 0000000000..8df6fbd724 --- /dev/null +++ b/src/packages/empty/demos/h5/demo7.tsx @@ -0,0 +1,11 @@ +import React from 'react' +import { Cell, Empty } from '@nutui/nutui-react' + +const Demo7 = () => { + return ( + + + + ) +} +export default Demo7 diff --git a/src/packages/empty/demos/taro/demo1.tsx b/src/packages/empty/demos/taro/demo1.tsx index a741fd8ea9..d83a692c67 100644 --- a/src/packages/empty/demos/taro/demo1.tsx +++ b/src/packages/empty/demos/taro/demo1.tsx @@ -1,23 +1,29 @@ import React from 'react' -import { Empty, pxTransform } from '@nutui/nutui-react-taro' +import { Cell, Empty, Toast } from '@nutui/nutui-react-taro' const Demo1 = () => { return ( <> - - - + + + Toast.show('empty-demo1', { + title: '正在刷新...', + icon: 'none', + }), + }, + ]} + /> + + ) } diff --git a/src/packages/empty/demos/taro/demo2.tsx b/src/packages/empty/demos/taro/demo2.tsx index ce26362696..af5e174f01 100644 --- a/src/packages/empty/demos/taro/demo2.tsx +++ b/src/packages/empty/demos/taro/demo2.tsx @@ -1,13 +1,32 @@ import React from 'react' -import { Empty } from '@nutui/nutui-react-taro' +import { Cell, Empty, Toast } from '@nutui/nutui-react-taro' const Demo2 = () => { return ( - + <> + + + Toast.show('empty-demo2', { title: '逛逛秒杀', icon: 'none' }), + }, + { + text: '看看关注', + type: 'primary', + onClick: () => + Toast.show('empty-demo2', { title: '看看关注', icon: 'none' }), + }, + ]} + /> + + + ) } export default Demo2 diff --git a/src/packages/empty/demos/taro/demo3.tsx b/src/packages/empty/demos/taro/demo3.tsx index ba9510f9ce..95a868bab0 100644 --- a/src/packages/empty/demos/taro/demo3.tsx +++ b/src/packages/empty/demos/taro/demo3.tsx @@ -1,7 +1,11 @@ import React from 'react' -import { Empty, pxTransform } from '@nutui/nutui-react-taro' +import { Cell, Empty } from '@nutui/nutui-react-taro' const Demo3 = () => { - return + return ( + + + + ) } export default Demo3 diff --git a/src/packages/empty/demos/taro/demo4.tsx b/src/packages/empty/demos/taro/demo4.tsx index 94190f6411..b4d95d951d 100644 --- a/src/packages/empty/demos/taro/demo4.tsx +++ b/src/packages/empty/demos/taro/demo4.tsx @@ -1,32 +1,70 @@ import React, { useState } from 'react' -// import { Tabs, TabPane, Empty } from '@nutui/nutui-react-taro' -import { Empty } from '@nutui/nutui-react-taro' +import { Empty, TabPane, Tabs } from '@nutui/nutui-react-taro' + +const statusList = [ + { + status: 'network' as const, + title: '网络连接已断开', + description: '请检查网络设置或刷新页面', + }, + { + status: 'comment' as const, + title: '暂无评价', + description: '快来发表第一条评价吧', + }, + { + status: 'search' as const, + title: '暂无搜索结果', + description: '换个关键词试试吧', + }, + { + status: 'shop' as const, + title: '暂无店铺', + description: '去看看其他店铺吧', + }, + { + status: 'address' as const, + title: '暂无收货地址', + description: '添加地址,享受便捷购物', + }, + { + status: 'order' as const, + title: '暂无订单', + description: '快去挑选心仪的商品吧', + }, + { + status: 'favor' as const, + title: '暂无收藏', + description: '收藏喜欢的商品,方便下次查看', + }, + { + status: 'cart' as const, + title: '小购物车大容量', + description: '把喜欢的商品都加进来吧', + }, +] const Demo4 = () => { const [tabvalue, setTabvalue] = useState('0') return ( - // { - // setTabvalue(paneKey) - // }} - // > - // - // - // - // - // - // - // - // - // - // - <> - - - - + { + setTabvalue(paneKey) + }} + > + {statusList.map((item, index) => ( + + + + ))} + ) } export default Demo4 diff --git a/src/packages/empty/demos/taro/demo5.tsx b/src/packages/empty/demos/taro/demo5.tsx index 75465a3c43..dafe6dbe63 100644 --- a/src/packages/empty/demos/taro/demo5.tsx +++ b/src/packages/empty/demos/taro/demo5.tsx @@ -1,21 +1,23 @@ import React from 'react' -import { Empty } from '@nutui/nutui-react-taro' +import { Cell, Empty } from '@nutui/nutui-react-taro' import { Image } from '@tarojs/components' const Demo5 = () => { return ( - - } - /> + + + } + /> + ) } export default Demo5 diff --git a/src/packages/empty/demos/taro/demo6.tsx b/src/packages/empty/demos/taro/demo6.tsx index 316ecc978b..db282d868a 100644 --- a/src/packages/empty/demos/taro/demo6.tsx +++ b/src/packages/empty/demos/taro/demo6.tsx @@ -1,16 +1,18 @@ import React from 'react' -import { Empty, Button, pxTransform } from '@nutui/nutui-react-taro' +import { Button, Cell, Empty, pxTransform } from '@nutui/nutui-react-taro' import { View } from '@tarojs/components' const Demo6 = () => { return ( - - - - - + + + + + + + ) } export default Demo6 diff --git a/src/packages/empty/demos/taro/demo7.tsx b/src/packages/empty/demos/taro/demo7.tsx new file mode 100644 index 0000000000..b18dddfd69 --- /dev/null +++ b/src/packages/empty/demos/taro/demo7.tsx @@ -0,0 +1,11 @@ +import React from 'react' +import { Cell, Empty, pxTransform } from '@nutui/nutui-react-taro' + +const Demo7 = () => { + return ( + + + + ) +} +export default Demo7 diff --git a/src/packages/empty/doc.en-US.md b/src/packages/empty/doc.en-US.md index aa6eeebc66..9bc4662d70 100644 --- a/src/packages/empty/doc.en-US.md +++ b/src/packages/empty/doc.en-US.md @@ -10,7 +10,7 @@ import { Empty } from '@nutui/nutui-react' ## Demo -### Basic usage +### Full :::demo @@ -18,7 +18,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### Size is small +### Half :::demo @@ -26,7 +26,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### Custom content size +### Partial :::demo @@ -34,7 +34,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### Picture type, 3 built-in +### Picture type, 8 built-in :::demo @@ -42,6 +42,14 @@ import { Empty } from '@nutui/nutui-react' ::: +### Custom image size + +:::demo + + + +::: + ### Custom image > If you are inner user in JD, you can get the image links from us for default types. @@ -52,7 +60,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### Bottom content +### Custom bottom buttons :::demo @@ -70,9 +78,9 @@ import { Empty } from '@nutui/nutui-react' | imageSize | Image size, the unit of number type is px | `number` \| `string` | `-` | | title | Title below the image | `ReactNode` | `-` | | description | Description below the image | `ReactNode` | `-` | -| size | Size of component,used by full screen or half screen | `small` \| `base` | `base` | -| status | The Default error type | `empty` \| `error` \| `network` | `empty` | -| actions | Actions of operation | `Array` | `[]` | +| size | Component size per JD APP V11.0 empty-state spec | `full` \| `half` \| `partial` | `half` | +| status | Built-in illustration type mapped to design scenarios | `network` \| `comment` \| `search` \| `shop` \| `address` \| `order` \| `favor` \| `cart` | `network` | +| actions | Actions list; fields align with Button, including `onClick` | `EmptyAction[]` | `[]` | ## Theming @@ -80,14 +88,45 @@ import { Empty } from '@nutui/nutui-react' The component provides the following CSS variables, which can be used to customize styles. Please refer to [ConfigProvider component](#/en-US/component/configprovider). +**Common** + +| Name | Description | Default | +| --- | --- | --- | +| \--nutui-empty-padding | Component padding | `20px` | +| \--nutui-empty-title-color | Title color | `$color-title` (`#11141A`) | +| \--nutui-empty-description-color | Description color | `$color-text-help` (`#8D9199`) | + +**`full`** + +| Name | Description | Default | +| --- | --- | --- | +| \--nutui-empty-full-padding-top | Top spacing | `160px` | +| \--nutui-empty-full-image-size | Image size | `160px` | +| \--nutui-empty-full-title-font-size | Title font size | `$font-size-md` | +| \--nutui-empty-full-title-line-height | Title line height | `$line-height-xxl` | +| \--nutui-empty-full-description-font-size | Description font size | `$font-size-base` | +| \--nutui-empty-full-description-line-height | Description line height | `22px` | +| \--nutui-empty-full-actions-margin-top | Actions margin top | `8px` | + +**`half`** + +| Name | Description | Default | +| --- | --- | --- | +| \--nutui-empty-half-image-size | Image size | `80px` | +| \--nutui-empty-half-title-font-size | Title font size | `$font-size-s` | +| \--nutui-empty-half-title-line-height | Title line height | `22px` | +| \--nutui-empty-half-description-font-size | Description font size | `$font-size-m` | +| \--nutui-empty-half-description-line-height | Description line height | `$line-height-2xl` | +| \--nutui-empty-half-actions-margin-top | Actions margin top | `8px` | + +**`partial`** + | Name | Description | Default | | --- | --- | --- | -| \--nutui-empty-padding | The padding value of the Empty component image | `32px 40px` | -| \--nutui-empty-image-size | The size of the Empty component image | `160px` | -| \--nutui-empty-image-small-size | When size is small, the size of the Empty component image | `120px` | -| \--nutui-empty-title-margin-top | The value of margin-top of the Empty component image title | `0px` | -| \--nutui-empty-title-line-height | Empty component image title line height | `$font-size-l` | -| \--nutui-empty-description-line-height | Empty component image description line height | `1` | -| \--nutui-empty-background-color | Empty component background color | `#fff` | +| \--nutui-empty-partial-padding | Container padding | `0 16px` | +| \--nutui-empty-partial-image-size | Image size | `32px` | +| \--nutui-empty-partial-content-gap | Gap between image and text | `8px` | +| \--nutui-empty-partial-description-font-size | Text font size | `$font-size-m` | +| \--nutui-empty-partial-description-line-height | Text line height | `32px` | diff --git a/src/packages/empty/doc.md b/src/packages/empty/doc.md index 76a90bc1ab..09efcd7462 100644 --- a/src/packages/empty/doc.md +++ b/src/packages/empty/doc.md @@ -10,7 +10,7 @@ import { Empty } from '@nutui/nutui-react' ## 示例代码 -### 基础用法 +### 全屏 full :::demo @@ -18,7 +18,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### Size 为 small 时,可用于半屏 +### 半屏 half :::demo @@ -26,7 +26,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### 自定义内容大小 +### 局部 partial :::demo @@ -34,7 +34,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### 图片类型,内置 3 个 +### 图片类型,内置 8 个 :::demo @@ -42,6 +42,14 @@ import { Empty } from '@nutui/nutui-react' ::: +### 自定义图片大小 + +:::demo + + + +::: + ### 自定义图片 > 如果您是京东站内相关项目的开发,我们特意为您提供了一系列的缺省状态的图片链接,您可通过内部群获取。 @@ -52,7 +60,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### 底部内容 +### 自定义底部按钮 :::demo @@ -70,9 +78,9 @@ import { Empty } from '@nutui/nutui-react' | imageSize | 图片大小,number 类型单位为 px | `number` \| `string` | `-` | | title | 图片下方的标题 | `ReactNode` | `-` | | description | 图片下方的描述文字 | `ReactNode` | `-` | -| size | 组件整体大小,适配于全屏或半屏 | `small` \| `base` | `base` | -| status | 默认图片错误类型 | `empty` \| `error` \| `network` | `empty` | -| actions | 可用于处理操作的一组数据 | `Array` | `[]` | +| size | 组件尺寸,对齐 JD APP V11.0 缺省状态规范 | `full` \| `half` \| `partial` | `half` | +| status | 内置缺省插图类型,与设计稿业务场景一一对应 | `network` \| `comment` \| `search` \| `shop` \| `address` \| `order` \| `favor` \| `cart` | `network` | +| actions | 操作按钮列表,项内字段同 Button,支持 `onClick` | `EmptyAction[]` | `[]` | ## 主题定制 @@ -80,14 +88,45 @@ import { Empty } from '@nutui/nutui-react' 组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 [ConfigProvider 组件](#/zh-CN/component/configprovider)。 +**通用** + +| 名称 | 说明 | 默认值 | +| --- | --- | --- | +| \--nutui-empty-padding | 组件内边距 | `20px` | +| \--nutui-empty-title-color | 标题颜色 | `$color-title`(`#11141A`) | +| \--nutui-empty-description-color | 描述颜色 | `$color-text-help`(`#8D9199`) | + +**全屏 `full`** + +| 名称 | 说明 | 默认值 | +| --- | --- | --- | +| \--nutui-empty-full-padding-top | 顶部间距 | `160px` | +| \--nutui-empty-full-image-size | 插图尺寸 | `160px` | +| \--nutui-empty-full-title-font-size | 标题字号 | `$font-size-md` | +| \--nutui-empty-full-title-line-height | 标题行高 | `$line-height-xxl` | +| \--nutui-empty-full-description-font-size | 描述字号 | `$font-size-base` | +| \--nutui-empty-full-description-line-height | 描述行高 | `22px` | +| \--nutui-empty-full-actions-margin-top | 操作区上边距 | `8px` | + +**半屏 `half`** + +| 名称 | 说明 | 默认值 | +| --- | --- | --- | +| \--nutui-empty-half-image-size | 插图尺寸 | `80px` | +| \--nutui-empty-half-title-font-size | 标题字号 | `$font-size-s` | +| \--nutui-empty-half-title-line-height | 标题行高 | `22px` | +| \--nutui-empty-half-description-font-size | 描述字号 | `$font-size-m` | +| \--nutui-empty-half-description-line-height | 描述行高 | `$line-height-2xl` | +| \--nutui-empty-half-actions-margin-top | 操作区上边距 | `8px` | + +**局部 `partial`** + | 名称 | 说明 | 默认值 | | --- | --- | --- | -| \--nutui-empty-padding | Empty组件图片的padding值 | `32px 40px` | -| \--nutui-empty-image-size | Empty组件图片的尺寸大小 | `160px` | -| \--nutui-empty-image-small-size | size 为 small 时,Empty组件图片的尺寸大小 | `120px` | -| \--nutui-empty-title-margin-top | Empty组件图片标题margin-top的值 | `0px` | -| \--nutui-empty-title-line-height | Empty组件图片标题行高 | `$font-size-l` | -| \--nutui-empty-description-line-height | Empty组件图片描述行高 | `1` | -| \--nutui-empty-background-color | Empty组件背景色 | `#fff` | +| \--nutui-empty-partial-padding | 容器内边距 | `0 16px` | +| \--nutui-empty-partial-image-size | 插图尺寸 | `32px` | +| \--nutui-empty-partial-content-gap | 图与文案间距 | `8px` | +| \--nutui-empty-partial-description-font-size | 文案字号 | `$font-size-m` | +| \--nutui-empty-partial-description-line-height | 文案行高 | `32px` | diff --git a/src/packages/empty/doc.taro.md b/src/packages/empty/doc.taro.md index cb738c583f..0817486f0b 100644 --- a/src/packages/empty/doc.taro.md +++ b/src/packages/empty/doc.taro.md @@ -10,7 +10,7 @@ import { Empty } from '@nutui/nutui-react-taro' ## 示例代码 -### 基础用法 +### 全屏 full :::demo @@ -18,7 +18,7 @@ import { Empty } from '@nutui/nutui-react-taro' ::: -### Size 为 small 时,可用于半屏 +### 半屏 half :::demo @@ -26,7 +26,7 @@ import { Empty } from '@nutui/nutui-react-taro' ::: -### 自定义内容大小 +### 局部 partial :::demo @@ -34,7 +34,7 @@ import { Empty } from '@nutui/nutui-react-taro' ::: -### 图片类型,内置 3 个 +### 图片类型,内置 8 个 :::demo @@ -42,6 +42,14 @@ import { Empty } from '@nutui/nutui-react-taro' ::: +### 自定义图片大小 + +:::demo + + + +::: + ### 自定义图片 > 如果您是京东站内相关项目的开发,我们特意为您提供了一系列的缺省状态的图片链接,您可通过内部群获取。 @@ -52,7 +60,7 @@ import { Empty } from '@nutui/nutui-react-taro' ::: -### 底部内容 +### 自定义底部按钮 :::demo @@ -70,9 +78,9 @@ import { Empty } from '@nutui/nutui-react-taro' | imageSize | 图片大小,number 类型单位为 px | `number` \| `string` | `-` | | title | 图片下方的标题 | `ReactNode` | `-` | | description | 图片下方的描述文字 | `ReactNode` | `-` | -| size | 组件整体大小,适配于全屏或半屏 | `small` \| `base` | `base` | -| status | 默认图片错误类型 | `empty` \| `error` \| `network` | `empty` | -| actions | 可用于处理操作的一组数据 | `Array` | `[]` | +| size | 组件尺寸,对齐 JD APP V11.0 缺省状态规范 | `full` \| `half` \| `partial` | `half` | +| status | 内置缺省插图类型,与设计稿业务场景一一对应 | `network` \| `comment` \| `search` \| `shop` \| `address` \| `order` \| `favor` \| `cart` | `network` | +| actions | 操作按钮列表,项内字段同 Button,支持 `onClick` | `EmptyAction[]` | `[]` | ## 主题定制 @@ -80,14 +88,45 @@ import { Empty } from '@nutui/nutui-react-taro' 组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 [ConfigProvider 组件](#/zh-CN/component/configprovider)。 +**通用** + +| 名称 | 说明 | 默认值 | +| --- | --- | --- | +| \--nutui-empty-padding | 组件内边距 | `20px` | +| \--nutui-empty-title-color | 标题颜色 | `$color-title`(`#11141A`) | +| \--nutui-empty-description-color | 描述颜色 | `$color-text-help`(`#8D9199`) | + +**全屏 `full`** + +| 名称 | 说明 | 默认值 | +| --- | --- | --- | +| \--nutui-empty-full-padding-top | 顶部间距 | `160px` | +| \--nutui-empty-full-image-size | 插图尺寸 | `160px` | +| \--nutui-empty-full-title-font-size | 标题字号 | `$font-size-md` | +| \--nutui-empty-full-title-line-height | 标题行高 | `$line-height-xxl` | +| \--nutui-empty-full-description-font-size | 描述字号 | `$font-size-base` | +| \--nutui-empty-full-description-line-height | 描述行高 | `22px` | +| \--nutui-empty-full-actions-margin-top | 操作区上边距 | `8px` | + +**半屏 `half`** + +| 名称 | 说明 | 默认值 | +| --- | --- | --- | +| \--nutui-empty-half-image-size | 插图尺寸 | `80px` | +| \--nutui-empty-half-title-font-size | 标题字号 | `$font-size-s` | +| \--nutui-empty-half-title-line-height | 标题行高 | `22px` | +| \--nutui-empty-half-description-font-size | 描述字号 | `$font-size-m` | +| \--nutui-empty-half-description-line-height | 描述行高 | `$line-height-2xl` | +| \--nutui-empty-half-actions-margin-top | 操作区上边距 | `8px` | + +**局部 `partial`** + | 名称 | 说明 | 默认值 | | --- | --- | --- | -| \--nutui-empty-padding | Empty组件图片的padding值 | `32px 40px` | -| \--nutui-empty-image-size | Empty组件图片的尺寸大小 | `160px` | -| \--nutui-empty-image-small-size | size 为 small 时,Empty组件图片的尺寸大小 | `120px` | -| \--nutui-empty-title-margin-top | Empty组件图片标题margin-top的值 | `0px` | -| \--nutui-empty-title-line-height | Empty组件图片标题行高 | `$font-size-l` | -| \--nutui-empty-description-line-height | Empty组件图片描述行高 | `1` | -| \--nutui-empty-background-color | Empty组件背景色 | `#fff` | +| \--nutui-empty-partial-padding | 容器内边距 | `0 16px` | +| \--nutui-empty-partial-image-size | 插图尺寸 | `32px` | +| \--nutui-empty-partial-content-gap | 图与文案间距 | `8px` | +| \--nutui-empty-partial-description-font-size | 文案字号 | `$font-size-m` | +| \--nutui-empty-partial-description-line-height | 文案行高 | `32px` | diff --git a/src/packages/empty/doc.zh-TW.md b/src/packages/empty/doc.zh-TW.md index 27d742e484..54897bea70 100644 --- a/src/packages/empty/doc.zh-TW.md +++ b/src/packages/empty/doc.zh-TW.md @@ -10,7 +10,7 @@ import { Empty } from '@nutui/nutui-react' ## 示例代碼 -### 基礎用法 +### 全屏 full :::demo @@ -18,7 +18,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### Size 為 small 時,可用於半屏 +### 半屏 half :::demo @@ -26,7 +26,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### 自定義內容大小 +### 局部 partial :::demo @@ -34,7 +34,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### 圖片類型,內置 3 個 +### 圖片類型,內置 8 個 :::demo @@ -42,6 +42,14 @@ import { Empty } from '@nutui/nutui-react' ::: +### 自定義圖片大小 + +:::demo + + + +::: + ### 自定義圖片 > 如果您是京東站內相關項目的開發,我們特意為您提供了一繫列的缺省狀態的圖片鏈接,您可通過內部群獲取。 @@ -52,7 +60,7 @@ import { Empty } from '@nutui/nutui-react' ::: -### 底部內容 +### 自定義底部按鈕 :::demo @@ -70,9 +78,9 @@ import { Empty } from '@nutui/nutui-react' | imageSize | 圖片大小,number 類型單位為 px | `number` \| `string` | `-` | | title | 圖片下方的標題 | `ReactNode` | `-` | | description | 圖片下方的描述文字 | `ReactNode` | `-` | -| size | 組件整體大小,適配於全屏或半屏 | `small` \| `base` | `base` | -| status | 默認圖片錯誤類型 | `empty` \| `error` \| `network` | `empty` | -| actions | 可用於處理操作的一組數據 | `Array` | `[]` | +| size | 組件尺寸,對齊 JD APP V11.0 缺省狀態規範 | `full` \| `half` \| `partial` | `half` | +| status | 內置缺省插圖類型,與設計稿業務場景一一對應 | `network` \| `comment` \| `search` \| `shop` \| `address` \| `order` \| `favor` \| `cart` | `network` | +| actions | 操作按鈕列表,項內字段同 Button,支持 `onClick` | `EmptyAction[]` | `[]` | ## 主題定製 @@ -80,14 +88,45 @@ import { Empty } from '@nutui/nutui-react' 組件提供了下列 CSS 變量,可用於自定義樣式,使用方法請參考 [ConfigProvider 組件](#/zh-CN/component/configprovider)。 +**通用** + +| 名稱 | 説明 | 默認值 | +| --- | --- | --- | +| \--nutui-empty-padding | 組件內邊距 | `20px` | +| \--nutui-empty-title-color | 標題顏色 | `$color-title`(`#11141A`) | +| \--nutui-empty-description-color | 描述顏色 | `$color-text-help`(`#8D9199`) | + +**全屏 `full`** + +| 名稱 | 説明 | 默認值 | +| --- | --- | --- | +| \--nutui-empty-full-padding-top | 頂部間距 | `160px` | +| \--nutui-empty-full-image-size | 插圖尺寸 | `160px` | +| \--nutui-empty-full-title-font-size | 標題字號 | `$font-size-md` | +| \--nutui-empty-full-title-line-height | 標題行高 | `$line-height-xxl` | +| \--nutui-empty-full-description-font-size | 描述字號 | `$font-size-base` | +| \--nutui-empty-full-description-line-height | 描述行高 | `22px` | +| \--nutui-empty-full-actions-margin-top | 操作區上邊距 | `8px` | + +**半屏 `half`** + +| 名稱 | 説明 | 默認值 | +| --- | --- | --- | +| \--nutui-empty-half-image-size | 插圖尺寸 | `80px` | +| \--nutui-empty-half-title-font-size | 標題字號 | `$font-size-s` | +| \--nutui-empty-half-title-line-height | 標題行高 | `22px` | +| \--nutui-empty-half-description-font-size | 描述字號 | `$font-size-m` | +| \--nutui-empty-half-description-line-height | 描述行高 | `$line-height-2xl` | +| \--nutui-empty-half-actions-margin-top | 操作區上邊距 | `8px` | + +**局部 `partial`** + | 名稱 | 説明 | 默認值 | | --- | --- | --- | -| \--nutui-empty-padding | Empty組件圖片的padding值 | `32px 40px` | -| \--nutui-empty-image-size | Empty組件圖片的尺寸大小 | `160px` | -| \--nutui-empty-image-small-size | size 爲 small 時,Empty組件圖片的尺寸大小 | `120px` | -| \--nutui-empty-title-margin-top | Empty組件圖片標題margin-top的值 | `0px` | -| \--nutui-empty-title-line-height | Empty組件圖片標題行高 | `$font-size-l` | -| \--nutui-empty-description-line-height | Empty組件圖片描述行高 | `1` | -| \--nutui-empty-background-color | Empty組件背景色 | `#fff` | +| \--nutui-empty-partial-padding | 容器內邊距 | `0 16px` | +| \--nutui-empty-partial-image-size | 插圖尺寸 | `32px` | +| \--nutui-empty-partial-content-gap | 圖與文案間距 | `8px` | +| \--nutui-empty-partial-description-font-size | 文案字號 | `$font-size-m` | +| \--nutui-empty-partial-description-line-height | 文案行高 | `32px` | diff --git a/src/packages/empty/empty.scss b/src/packages/empty/empty.scss index 7ec5e472fa..8a78783033 100644 --- a/src/packages/empty/empty.scss +++ b/src/packages/empty/empty.scss @@ -1,4 +1,5 @@ @import '../button/button.scss'; + .nut-empty { box-sizing: border-box; width: 100%; @@ -7,23 +8,8 @@ flex-direction: column; justify-content: center; padding: $empty-padding; - background-color: $empty-background-color; - - &-base { - width: $empty-image-size; - height: $empty-image-size; - - img, - image { - width: 100%; - height: 100%; - } - } - - &-small { - width: $empty-image-small-size; - height: $empty-image-small-size; + &-image { img, image { width: 100%; @@ -32,32 +18,113 @@ } &-title { - margin-top: $empty-title-margin-top; + text-align: center; + color: $empty-title-color; font-weight: $font-weight-bold; - margin-bottom: $empty-title-margin-bottom; - color: $color-title; - font-size: $font-size-l; - line-height: $empty-title-line-height; } &-description { - color: $color-text; - font-size: $font-size-s; - line-height: $empty-description-line-height; - } - &-actions-base { - display: flex; - flex-direction: row; - margin-top: 24px; + text-align: center; + color: $empty-description-color; + font-weight: $font-weight; } - &-actions-small { + + &-actions { display: flex; flex-direction: row; - margin-top: 16px; + justify-content: center; } &-action { margin-right: 6px; margin-left: 6px; } + + &-partial-body { + display: flex; + flex-direction: row; + align-items: center; + max-width: 100%; + } + + &-content { + flex: 1; + min-width: 0; + } + + // 全屏型:整页无数据 + &--full { + padding-top: $empty-full-padding-top; + + .nut-empty-image { + width: $empty-full-image-size; + height: $empty-full-image-size; + } + + .nut-empty-title { + font-size: $empty-full-title-font-size; + line-height: $empty-full-title-line-height; + } + + .nut-empty-description { + font-size: $empty-full-description-font-size; + line-height: $empty-full-description-line-height; + } + + .nut-empty-actions { + margin-top: $empty-full-actions-margin-top; + } + } + + // 半屏型:模块、弹层等区域 + &--half { + .nut-empty-image { + width: $empty-half-image-size; + height: $empty-half-image-size; + } + + .nut-empty-title { + font-size: $empty-half-title-font-size; + line-height: $empty-half-title-line-height; + } + + .nut-empty-description { + font-size: $empty-half-description-font-size; + line-height: $empty-half-description-line-height; + } + + .nut-empty-actions { + margin-top: $empty-half-actions-margin-top; + } + } + + // 局部型:横向图文 + &--partial { + padding: $empty-partial-padding; + + .nut-empty-partial-body { + gap: $empty-partial-content-gap; + } + + .nut-empty-image { + width: $empty-partial-image-size; + height: $empty-partial-image-size; + } + + .nut-empty-title { + text-align: left; + font-size: $empty-partial-description-font-size; + line-height: $empty-partial-description-line-height; + color: $empty-title-color; + font-weight: $font-weight; + } + + .nut-empty-description { + text-align: left; + font-size: $empty-partial-description-font-size; + line-height: $empty-partial-description-line-height; + color: $empty-description-color; + font-weight: $font-weight; + } + } } diff --git a/src/packages/empty/empty.taro.tsx b/src/packages/empty/empty.taro.tsx index 9d3795625d..d1a8921c6b 100644 --- a/src/packages/empty/empty.taro.tsx +++ b/src/packages/empty/empty.taro.tsx @@ -2,37 +2,23 @@ import React, { FunctionComponent, useEffect, useState, ReactNode } from 'react' import classNames from 'classnames' import { View, Image } from '@tarojs/components' import { BasicComponent, ComponentDefaults } from '@/utils/typings' -import { UIFill, UISize, UIType } from '@/types/base/atoms' import { Button } from '@/packages/button/button.taro' +import { + getEmptyStatusImage, + type EmptyAction, + type EmptySize, + type EmptyStatus, +} from '@/types' -export interface EmptyAction { - text: React.ReactNode - type?: UIType - size?: UISize - fill?: UIFill - disabled?: boolean - onClick?: () => () => void -} - -type statusOptions = { - [key: string]: string -} +export type { EmptyAction, EmptySize, EmptyStatus } from '@/types' -const defaultStatus: statusOptions = { - empty: - 'https://storage.360buyimg.com/imgtools/30186cfda0-0d3eee40-c0ac-11ee-9382-9125782aa3b8.png', - error: - 'https://storage.360buyimg.com/imgtools/f3278d0ebb-0ce360c0-c0ac-11ee-8375-193101bb1a46.png', - network: - 'https://storage.360buyimg.com/imgtools/43c30f7e29-0d483d10-c0ac-11ee-bec4-eb4d2a09a51d.png', -} export interface EmptyProps extends BasicComponent { image?: ReactNode imageSize: number | string title: ReactNode description: ReactNode - size: 'small' | 'base' - status: 'empty' | 'error' | 'network' + size: EmptySize + status: EmptyStatus actions: Array } @@ -41,8 +27,8 @@ const defaultProps = { title: '', description: '', imageSize: '', - size: 'base', - status: 'empty', + size: 'half', + status: 'network', actions: [], } as EmptyProps @@ -69,7 +55,7 @@ export const Empty: FunctionComponent< const [imgStyle, setImgStyle] = useState({}) - const imageUrl = image || defaultStatus[status] + const imageUrl = image || getEmptyStatusImage(status) const imageNode = typeof imageUrl === 'string' ? ( + {imageNode} + + ) + + const titleBlock = + typeof title === 'string' && title ? ( + {title} + ) : ( + title + ) + + const descriptionBlock = + typeof description === 'string' ? ( + {description} + ) : ( + description + ) return ( - - {imageNode} - - {typeof title === 'string' && title ? ( - {title} - ) : ( - title - )} - {typeof description === 'string' ? ( - {description} + {size === 'partial' ? ( + + {imageBlock} + + {titleBlock} + {descriptionBlock} + + ) : ( - description + <> + {imageBlock} + {titleBlock} + {descriptionBlock} + )} {actions.length ? ( - + {actions.map((action, index) => { const { text, ...rest } = action return ( diff --git a/src/packages/empty/empty.tsx b/src/packages/empty/empty.tsx index 7ed09f1134..7377823ba0 100644 --- a/src/packages/empty/empty.tsx +++ b/src/packages/empty/empty.tsx @@ -3,36 +3,22 @@ import classNames from 'classnames' import { BasicComponent, ComponentDefaults } from '@/utils/typings' import Button from '../button' -import { UIType, UISize, UIFill } from '@/types/base/atoms' +import { + getEmptyStatusImage, + type EmptyAction, + type EmptySize, + type EmptyStatus, +} from '@/types' -export interface EmptyAction { - text: React.ReactNode - type?: UIType - size?: UISize - fill?: UIFill - disabled?: boolean - onClick?: () => () => void -} - -type statusOptions = { - [key: string]: string -} +export type { EmptyAction, EmptySize, EmptyStatus } from '@/types' -const defaultStatus: statusOptions = { - empty: - 'https://storage.360buyimg.com/imgtools/30186cfda0-0d3eee40-c0ac-11ee-9382-9125782aa3b8.png', - error: - 'https://storage.360buyimg.com/imgtools/f3278d0ebb-0ce360c0-c0ac-11ee-8375-193101bb1a46.png', - network: - 'https://storage.360buyimg.com/imgtools/43c30f7e29-0d483d10-c0ac-11ee-bec4-eb4d2a09a51d.png', -} export interface EmptyProps extends BasicComponent { image?: ReactNode imageSize: number | string title: ReactNode description: ReactNode - size: 'small' | 'base' - status: 'empty' | 'error' | 'network' + size: EmptySize + status: EmptyStatus actions: Array } @@ -41,8 +27,8 @@ const defaultProps = { title: '', description: '', imageSize: '', - size: 'base', - status: 'empty', + size: 'half', + status: 'network', actions: [], } as EmptyProps @@ -69,7 +55,7 @@ export const Empty: FunctionComponent< const [imgStyle, setImgStyle] = useState({}) - const imageUrl = image || defaultStatus[status] + const imageUrl = image || getEmptyStatusImage(status) const imageNode = typeof imageUrl === 'string' ? ( + {imageNode} +
+ ) + + const titleBlock = + typeof title === 'string' && title ? ( +
{title}
+ ) : ( + title + ) + + const descriptionBlock = + typeof description === 'string' ? ( +
{description}
+ ) : ( + description + ) return ( -
-
- {imageNode} -
- {typeof title === 'string' && title ? ( -
{title}
- ) : ( - title - )} - {typeof description === 'string' ? ( -
{description}
+
+ {size === 'partial' ? ( +
+ {imageBlock} +
+ {titleBlock} + {descriptionBlock} +
+
) : ( - description + <> + {imageBlock} + {titleBlock} + {descriptionBlock} + )} {actions.length ? ( -
+
{actions.map((action, index) => { const { text, ...rest } = action return ( diff --git a/src/packages/empty/index.taro.ts b/src/packages/empty/index.taro.ts index 63e6f3f254..74b0cdd13a 100644 --- a/src/packages/empty/index.taro.ts +++ b/src/packages/empty/index.taro.ts @@ -1,5 +1,10 @@ import { Empty } from './empty.taro' -export type { EmptyProps } from './empty' +export type { + EmptyAction, + EmptyProps, + EmptySize, + EmptyStatus, +} from './empty.taro' export default Empty diff --git a/src/packages/empty/index.ts b/src/packages/empty/index.ts index b6e6961588..bba4fddb8d 100644 --- a/src/packages/empty/index.ts +++ b/src/packages/empty/index.ts @@ -1,5 +1,5 @@ import { Empty } from './empty' -export type { EmptyProps } from './empty' +export type { EmptyAction, EmptyProps, EmptySize, EmptyStatus } from './empty' export default Empty diff --git a/src/sites/sites-react/doc/docs/react/migrate-from-v3.en-US.md b/src/sites/sites-react/doc/docs/react/migrate-from-v3.en-US.md index 74f933d091..47e8cd2b8e 100644 --- a/src/sites/sites-react/doc/docs/react/migrate-from-v3.en-US.md +++ b/src/sites/sites-react/doc/docs/react/migrate-from-v3.en-US.md @@ -48,3 +48,33 @@ npm install @nutui/nutui-react-taro - **Dark Mode Correction**: - Resolved incorrect color variables/mappings under Dark Mode (`theme-dark`) for Checkbox background colors and borders. + +### Empty + +> **No v3 compatibility in v4**: no prop aliases, no runtime fallbacks, and no `EmptyState` type alias. Migrate manually using the tables below. + +- **`size` Enum Breaking Change**: + - Removed `base` / `small`. Aligned with JD APP V11.0 empty-state spec: `full` / `half` / `partial`. + - Default changed from `base` to `half`. + - Recommended migration: + - `size="base"` (v3 default, 160px image) → use `size="full"` for full-page states, or `size="partial"` for embedded partial areas. + - `size="small"` (v3, 120px image) → `size="half"` (half-screen, 80px image). +- **Visual Spec Updates**: + - **`full`**: 160px image, title `$font-size-md` / line height 24px / `#11141A`, description `$font-size-base` / line height 22px / `#8D9199`, 160px top spacing. + - **`half`**: 80px image, title `$font-size-s` / line height 22px, description `$font-size-m` / line height 20px. + - **`partial`**: 32px image in horizontal layout, text `$font-size-m` / line height 32px, padding `0 16px`, 8px gap between image and text. +- **CSS Class Name Breaking Changes**: + - Size modifiers: `.nut-empty-base` / `.nut-empty-small` → `.nut-empty--full` / `.nut-empty--half` / `.nut-empty--partial`. + - Image wrapper: `.nut-empty-base` / `.nut-empty-small` → `.nut-empty-image`. + - Actions: `.nut-empty-actions-base` / `.nut-empty-actions-small` → `.nut-empty-actions`. +- **Theme Variable Updates**: + - Added `--nutui-empty-title-color`, `--nutui-empty-description-color`, and per-size variables (e.g. `--nutui-empty-full-image-size`). + - Font sizes default to `$font-size-*` theme tokens; line heights use `$line-height-*` when available (e.g. 24px, 20px), otherwise design-spec px values (e.g. 22px, 32px). + - Legacy `--nutui-empty-image-size`, `--nutui-empty-image-small-size`, and `--nutui-empty-background-color` have been removed; use per-size variables instead. The component itself is transparent; use an outer container (e.g. `Cell`) for display backgrounds. +- **`status` Enum Breaking Change**: + - 8 built-in scenarios: `network` / `comment` / `search` / `shop` / `address` / `order` / `favor` / `cart`. + - Removed `empty` and `error`; default changed from `empty` to `network`. + - Recommended v3 → v4 mapping (code changes required; no automatic conversion): + - `status="empty"` → `status="search"` (generic empty) or another enum above + - `status="error"` → `status="network"` or a custom `image` + - Images load from CDN URLs at runtime; see `src/types/spec/empty/base.ts` for the mapping. diff --git a/src/sites/sites-react/doc/docs/react/migrate-from-v3.md b/src/sites/sites-react/doc/docs/react/migrate-from-v3.md index e03d06d1b8..c942fe3ad1 100644 --- a/src/sites/sites-react/doc/docs/react/migrate-from-v3.md +++ b/src/sites/sites-react/doc/docs/react/migrate-from-v3.md @@ -48,3 +48,33 @@ npm install @nutui/nutui-react-taro - **暗黑模式修复与设计稿适配**: - 修复并适配了多选框在暗黑模式(`theme-dark`)下的背景色、勾选框边框色等异常色彩映射问题。 + +### Empty (反馈类) + +> **v4 不提供 v3 兼容**:无 Props 别名、无运行时 fallback、无 `EmptyState` 类型别名。请按下表手动迁移。 + +- **`size` 枚举值变更(不兼容)**: + - 移除 `base` / `small`,对齐 JD APP V11.0 缺省状态规范,改为 `full` / `half` / `partial` 三种尺寸。 + - 默认值由 `base` 调整为 `half`。 + - 推荐迁移映射: + - `size="base"`(v3 默认,插图 160px)→ 整页场景用 `size="full"`,局部内嵌场景用 `size="partial"`。 + - `size="small"`(v3 插图 120px)→ `size="half"`(半屏型,插图 80px)。 +- **视觉规格对齐设计稿**: + - **全屏型 `full`**:插图 160px,标题 `$font-size-md` / 行高 24px / `#11141A`,描述 `$font-size-base` / 行高 22px / `#8D9199`,顶部间距 160px。 + - **半屏型 `half`**:插图 80px,标题 `$font-size-s` / 行高 22px,描述 `$font-size-m` / 行高 20px。 + - **局部型 `partial`**:插图 32px 横排,文案 `$font-size-m` / 行高 32px,容器 `padding: 0 16px`,图与文案间距 8px。 +- **CSS 类名变更(不兼容)**: + - 尺寸修饰类:`.nut-empty-base` / `.nut-empty-small` → `.nut-empty--full` / `.nut-empty--half` / `.nut-empty--partial`。 + - 插图容器:`.nut-empty-base` / `.nut-empty-small` → `.nut-empty-image`。 + - 操作区:`.nut-empty-actions-base` / `.nut-empty-actions-small` → `.nut-empty-actions`。 +- **主题变量调整**: + - 新增 `--nutui-empty-title-color`、`--nutui-empty-description-color` 及分尺寸变量(如 `--nutui-empty-full-image-size`)。 + - 字号默认引用 `$font-size-*` 主题 token;行高有对应 token 时引用 `$line-height-*`(如 24px、20px),其余按设计稿 px 值(如 22px、32px)。 + - 旧变量 `--nutui-empty-image-size`、`--nutui-empty-image-small-size`、`--nutui-empty-background-color` 已移除,请改用对应尺寸变量;组件本身为透明背景,展示区域背景由外层容器(如 `Cell`)控制。 +- **`status` 枚举变更(不兼容)**: + - 内置 8 种业务场景:`network` / `comment` / `search` / `shop` / `address` / `order` / `favor` / `cart`。 + - 移除 `empty`、`error`;默认值由 `empty` 调整为 `network`。 + - v3 → v4 推荐映射(需改代码,组件不会自动转换): + - `status="empty"` → `status="search"`(通用空态)或按场景选用上表枚举 + - `status="error"` → `status="network"` 或通过 `image` 传入自定义插图 + - 插图通过 CDN URL 运行时加载,映射表见 `src/types/spec/empty/base.ts`。 diff --git a/src/sites/sites-react/doc/docs/taro/migrate-from-v3.en-US.md b/src/sites/sites-react/doc/docs/taro/migrate-from-v3.en-US.md index 74f933d091..47e8cd2b8e 100644 --- a/src/sites/sites-react/doc/docs/taro/migrate-from-v3.en-US.md +++ b/src/sites/sites-react/doc/docs/taro/migrate-from-v3.en-US.md @@ -48,3 +48,33 @@ npm install @nutui/nutui-react-taro - **Dark Mode Correction**: - Resolved incorrect color variables/mappings under Dark Mode (`theme-dark`) for Checkbox background colors and borders. + +### Empty + +> **No v3 compatibility in v4**: no prop aliases, no runtime fallbacks, and no `EmptyState` type alias. Migrate manually using the tables below. + +- **`size` Enum Breaking Change**: + - Removed `base` / `small`. Aligned with JD APP V11.0 empty-state spec: `full` / `half` / `partial`. + - Default changed from `base` to `half`. + - Recommended migration: + - `size="base"` (v3 default, 160px image) → use `size="full"` for full-page states, or `size="partial"` for embedded partial areas. + - `size="small"` (v3, 120px image) → `size="half"` (half-screen, 80px image). +- **Visual Spec Updates**: + - **`full`**: 160px image, title `$font-size-md` / line height 24px / `#11141A`, description `$font-size-base` / line height 22px / `#8D9199`, 160px top spacing. + - **`half`**: 80px image, title `$font-size-s` / line height 22px, description `$font-size-m` / line height 20px. + - **`partial`**: 32px image in horizontal layout, text `$font-size-m` / line height 32px, padding `0 16px`, 8px gap between image and text. +- **CSS Class Name Breaking Changes**: + - Size modifiers: `.nut-empty-base` / `.nut-empty-small` → `.nut-empty--full` / `.nut-empty--half` / `.nut-empty--partial`. + - Image wrapper: `.nut-empty-base` / `.nut-empty-small` → `.nut-empty-image`. + - Actions: `.nut-empty-actions-base` / `.nut-empty-actions-small` → `.nut-empty-actions`. +- **Theme Variable Updates**: + - Added `--nutui-empty-title-color`, `--nutui-empty-description-color`, and per-size variables (e.g. `--nutui-empty-full-image-size`). + - Font sizes default to `$font-size-*` theme tokens; line heights use `$line-height-*` when available (e.g. 24px, 20px), otherwise design-spec px values (e.g. 22px, 32px). + - Legacy `--nutui-empty-image-size`, `--nutui-empty-image-small-size`, and `--nutui-empty-background-color` have been removed; use per-size variables instead. The component itself is transparent; use an outer container (e.g. `Cell`) for display backgrounds. +- **`status` Enum Breaking Change**: + - 8 built-in scenarios: `network` / `comment` / `search` / `shop` / `address` / `order` / `favor` / `cart`. + - Removed `empty` and `error`; default changed from `empty` to `network`. + - Recommended v3 → v4 mapping (code changes required; no automatic conversion): + - `status="empty"` → `status="search"` (generic empty) or another enum above + - `status="error"` → `status="network"` or a custom `image` + - Images load from CDN URLs at runtime; see `src/types/spec/empty/base.ts` for the mapping. diff --git a/src/sites/sites-react/doc/docs/taro/migrate-from-v3.md b/src/sites/sites-react/doc/docs/taro/migrate-from-v3.md index e03d06d1b8..c942fe3ad1 100644 --- a/src/sites/sites-react/doc/docs/taro/migrate-from-v3.md +++ b/src/sites/sites-react/doc/docs/taro/migrate-from-v3.md @@ -48,3 +48,33 @@ npm install @nutui/nutui-react-taro - **暗黑模式修复与设计稿适配**: - 修复并适配了多选框在暗黑模式(`theme-dark`)下的背景色、勾选框边框色等异常色彩映射问题。 + +### Empty (反馈类) + +> **v4 不提供 v3 兼容**:无 Props 别名、无运行时 fallback、无 `EmptyState` 类型别名。请按下表手动迁移。 + +- **`size` 枚举值变更(不兼容)**: + - 移除 `base` / `small`,对齐 JD APP V11.0 缺省状态规范,改为 `full` / `half` / `partial` 三种尺寸。 + - 默认值由 `base` 调整为 `half`。 + - 推荐迁移映射: + - `size="base"`(v3 默认,插图 160px)→ 整页场景用 `size="full"`,局部内嵌场景用 `size="partial"`。 + - `size="small"`(v3 插图 120px)→ `size="half"`(半屏型,插图 80px)。 +- **视觉规格对齐设计稿**: + - **全屏型 `full`**:插图 160px,标题 `$font-size-md` / 行高 24px / `#11141A`,描述 `$font-size-base` / 行高 22px / `#8D9199`,顶部间距 160px。 + - **半屏型 `half`**:插图 80px,标题 `$font-size-s` / 行高 22px,描述 `$font-size-m` / 行高 20px。 + - **局部型 `partial`**:插图 32px 横排,文案 `$font-size-m` / 行高 32px,容器 `padding: 0 16px`,图与文案间距 8px。 +- **CSS 类名变更(不兼容)**: + - 尺寸修饰类:`.nut-empty-base` / `.nut-empty-small` → `.nut-empty--full` / `.nut-empty--half` / `.nut-empty--partial`。 + - 插图容器:`.nut-empty-base` / `.nut-empty-small` → `.nut-empty-image`。 + - 操作区:`.nut-empty-actions-base` / `.nut-empty-actions-small` → `.nut-empty-actions`。 +- **主题变量调整**: + - 新增 `--nutui-empty-title-color`、`--nutui-empty-description-color` 及分尺寸变量(如 `--nutui-empty-full-image-size`)。 + - 字号默认引用 `$font-size-*` 主题 token;行高有对应 token 时引用 `$line-height-*`(如 24px、20px),其余按设计稿 px 值(如 22px、32px)。 + - 旧变量 `--nutui-empty-image-size`、`--nutui-empty-image-small-size`、`--nutui-empty-background-color` 已移除,请改用对应尺寸变量;组件本身为透明背景,展示区域背景由外层容器(如 `Cell`)控制。 +- **`status` 枚举变更(不兼容)**: + - 内置 8 种业务场景:`network` / `comment` / `search` / `shop` / `address` / `order` / `favor` / `cart`。 + - 移除 `empty`、`error`;默认值由 `empty` 调整为 `network`。 + - v3 → v4 推荐映射(需改代码,组件不会自动转换): + - `status="empty"` → `status="search"`(通用空态)或按场景选用上表枚举 + - `status="error"` → `status="network"` 或通过 `image` 传入自定义插图 + - 插图通过 CDN URL 运行时加载,映射表见 `src/types/spec/empty/base.ts`。 diff --git a/src/styles/variables-daojia.scss b/src/styles/variables-daojia.scss index 61390c644c..982b6bada4 100644 --- a/src/styles/variables-daojia.scss +++ b/src/styles/variables-daojia.scss @@ -1409,18 +1409,30 @@ $segmented-icon-margin-right: var(--nutui-segmented-icon-margin-right, $spacing-xxxs) !default; // empty(✅) -$empty-padding: var(--nutui-empty-padding, 32px 40px) !default; -$empty-image-size: var(--nutui-empty-image-size, 160px) !default; -$empty-image-small-size: var(--nutui-empty-image-small-size, 120px) !default; -$empty-title-margin-top: var(--nutui-empty-title-margin-top, 0px) !default; -$empty-background-color: var(--nutui-empty-background-color, - $color-background-overlay) !default; -$empty-title-margin-bottom: var(--nutui-empty-title-margin-bottom, - 12px) !default; -$empty-title-line-height: var(--nutui-empty-title-line-height, - $font-size-l) !default; -$empty-description-line-height: var(--nutui-empty-description-line-height, - 1) !default; +$empty-padding: var(--nutui-empty-padding, 20px) !default; +$empty-title-color: var(--nutui-empty-title-color, $color-title) !default; +$empty-description-color: var(--nutui-empty-description-color, $color-text-help) !default; +$empty-full-padding-top: var(--nutui-empty-full-padding-top, 160px) !default; +$empty-full-image-size: var(--nutui-empty-full-image-size, 160px) !default; +$empty-full-title-font-size: var(--nutui-empty-full-title-font-size, $font-size-md) !default; +$empty-full-title-line-height: var(--nutui-empty-full-title-line-height, $line-height-xxl) !default; +$empty-full-description-font-size: var(--nutui-empty-full-description-font-size, $font-size-base) !default; +$empty-full-description-line-height: var( + --nutui-empty-full-description-line-height, + 22px +) !default; +$empty-full-actions-margin-top: var(--nutui-empty-full-actions-margin-top, 8px) !default; +$empty-half-image-size: var(--nutui-empty-half-image-size, 80px) !default; +$empty-half-title-font-size: var(--nutui-empty-half-title-font-size, $font-size-s) !default; +$empty-half-title-line-height: var(--nutui-empty-half-title-line-height, 22px) !default; +$empty-half-description-font-size: var(--nutui-empty-half-description-font-size, $font-size-m) !default; +$empty-half-description-line-height: var(--nutui-empty-half-description-line-height, $line-height-2xl) !default; +$empty-half-actions-margin-top: var(--nutui-empty-half-actions-margin-top, 8px) !default; +$empty-partial-padding: var(--nutui-empty-partial-padding, 0px 16px) !default; +$empty-partial-image-size: var(--nutui-empty-partial-image-size, 32px) !default; +$empty-partial-content-gap: var(--nutui-empty-partial-content-gap, 8px) !default; +$empty-partial-description-font-size: var(--nutui-empty-partial-description-font-size, $font-size-m) !default; +$empty-partial-description-line-height: var(--nutui-empty-partial-description-line-height, 32px) !default; // cascader(✅) $cascader-font-size: var(--nutui-cascader-font-size, $font-size-base) !default; diff --git a/src/styles/variables-jmapp.scss b/src/styles/variables-jmapp.scss index 4b505b8824..699c9d6666 100644 --- a/src/styles/variables-jmapp.scss +++ b/src/styles/variables-jmapp.scss @@ -2364,26 +2364,50 @@ $segmented-icon-margin-right: var( // empty(✅) -$empty-padding: var(--nutui-empty-padding, 32px 40px) !default; -$empty-image-size: var(--nutui-empty-image-size, 160px) !default; -$empty-image-small-size: var(--nutui-empty-image-small-size, 120px) !default; -$empty-title-margin-top: var(--nutui-empty-title-margin-top, 0px) !default; -$empty-background-color: var(--nutui-empty-background-color, #fff) !default; -$empty-title-margin-bottom: var( - --nutui-empty-title-margin-bottom, - 8px -) !default; -$empty-title-line-height: var( - --nutui-empty-title-line-height, +$empty-padding: var(--nutui-empty-padding, 20px) !default; +$empty-title-color: var(--nutui-empty-title-color, $color-title) !default; +$empty-description-color: var(--nutui-empty-description-color, $color-text-help) !default; + +// 全屏型 +$empty-full-padding-top: var(--nutui-empty-full-padding-top, 160px) !default; +$empty-full-image-size: var(--nutui-empty-full-image-size, 160px) !default; +$empty-full-title-font-size: var(--nutui-empty-full-title-font-size, $font-size-md) !default; +$empty-full-title-line-height: var(--nutui-empty-full-title-line-height, $line-height-xxl) !default; +$empty-full-description-font-size: var( + --nutui-empty-full-description-font-size, $font-size-base ) !default; -$empty-description-margin-top: var( - --nutui-empty-description-margin-top, - 0px +$empty-full-description-line-height: var( + --nutui-empty-full-description-line-height, + 22px +) !default; +$empty-full-actions-margin-top: var(--nutui-empty-full-actions-margin-top, 8px) !default; + +// 半屏型 +$empty-half-image-size: var(--nutui-empty-half-image-size, 80px) !default; +$empty-half-title-font-size: var(--nutui-empty-half-title-font-size, $font-size-s) !default; +$empty-half-title-line-height: var(--nutui-empty-half-title-line-height, 22px) !default; +$empty-half-description-font-size: var( + --nutui-empty-half-description-font-size, + $font-size-m +) !default; +$empty-half-description-line-height: var( + --nutui-empty-half-description-line-height, + $line-height-2xl ) !default; -$empty-description-line-height: var( - --nutui-empty-description-line-height, - 1.2 +$empty-half-actions-margin-top: var(--nutui-empty-half-actions-margin-top, 8px) !default; + +// 局部型 +$empty-partial-padding: var(--nutui-empty-partial-padding, 0px 16px) !default; +$empty-partial-image-size: var(--nutui-empty-partial-image-size, 32px) !default; +$empty-partial-content-gap: var(--nutui-empty-partial-content-gap, 8px) !default; +$empty-partial-description-font-size: var( + --nutui-empty-partial-description-font-size, + $font-size-m +) !default; +$empty-partial-description-line-height: var( + --nutui-empty-partial-description-line-height, + 32px ) !default; // cascader(✅) diff --git a/src/styles/variables-jrkf.scss b/src/styles/variables-jrkf.scss index c82688e2f5..a39df2f708 100644 --- a/src/styles/variables-jrkf.scss +++ b/src/styles/variables-jrkf.scss @@ -2439,27 +2439,30 @@ $searchbar-input-text-align: var( // empty(✅) -$empty-padding: var(--nutui-empty-padding, 32px 40px) !default; -$empty-image-size: var(--nutui-empty-image-size, 160px) !default; -$empty-image-small-size: var(--nutui-empty-image-small-size, 120px) !default; -$empty-title-margin-top: var(--nutui-empty-title-margin-top, 0px) !default; -$empty-background-color: var(--nutui-empty-background-color, #fff) !default; -$empty-title-margin-bottom: var( - --nutui-empty-title-margin-bottom, - 8px -) !default; -$empty-title-line-height: var( - --nutui-empty-title-line-height, - $font-size-base -) !default; -$empty-description-margin-top: var( - --nutui-empty-description-margin-top, - 0px -) !default; -$empty-description-line-height: var( - --nutui-empty-description-line-height, - 1.2 +$empty-padding: var(--nutui-empty-padding, 20px) !default; +$empty-title-color: var(--nutui-empty-title-color, $color-title) !default; +$empty-description-color: var(--nutui-empty-description-color, $color-text-help) !default; +$empty-full-padding-top: var(--nutui-empty-full-padding-top, 160px) !default; +$empty-full-image-size: var(--nutui-empty-full-image-size, 160px) !default; +$empty-full-title-font-size: var(--nutui-empty-full-title-font-size, $font-size-md) !default; +$empty-full-title-line-height: var(--nutui-empty-full-title-line-height, $line-height-xxl) !default; +$empty-full-description-font-size: var(--nutui-empty-full-description-font-size, $font-size-base) !default; +$empty-full-description-line-height: var( + --nutui-empty-full-description-line-height, + 22px ) !default; +$empty-full-actions-margin-top: var(--nutui-empty-full-actions-margin-top, 8px) !default; +$empty-half-image-size: var(--nutui-empty-half-image-size, 80px) !default; +$empty-half-title-font-size: var(--nutui-empty-half-title-font-size, $font-size-s) !default; +$empty-half-title-line-height: var(--nutui-empty-half-title-line-height, 22px) !default; +$empty-half-description-font-size: var(--nutui-empty-half-description-font-size, $font-size-m) !default; +$empty-half-description-line-height: var(--nutui-empty-half-description-line-height, $line-height-2xl) !default; +$empty-half-actions-margin-top: var(--nutui-empty-half-actions-margin-top, 8px) !default; +$empty-partial-padding: var(--nutui-empty-partial-padding, 0px 16px) !default; +$empty-partial-image-size: var(--nutui-empty-partial-image-size, 32px) !default; +$empty-partial-content-gap: var(--nutui-empty-partial-content-gap, 8px) !default; +$empty-partial-description-font-size: var(--nutui-empty-partial-description-font-size, $font-size-m) !default; +$empty-partial-description-line-height: var(--nutui-empty-partial-description-line-height, 32px) !default; // cascader(✅) $cascader-font-size: var(--nutui-cascader-font-size, $font-size-base) !default; diff --git a/src/styles/variables.scss b/src/styles/variables.scss index 84851b9e7e..fecc48c7b4 100644 --- a/src/styles/variables.scss +++ b/src/styles/variables.scss @@ -1496,7 +1496,7 @@ $steps-horizontal-item-line-padding: var( ) !default; $steps-horizontal-item-special-padding-right: var( --nutui-steps-horizontal-item-special-padding-right, - scale-px(22px) + scale-font-px(22px) ) !default; $steps-horizontal-item-special-3-padding-right: var( --nutui-steps-horizontal-item-special-3-padding-right, @@ -2277,26 +2277,33 @@ $segmented-icon-margin-right: var( ) !default; // empty(✅) -$empty-padding: var(--nutui-empty-padding, scale-px(32px) scale-px(40px)) !default; -$empty-image-size: var(--nutui-empty-image-size, scale-px(160px)) !default; -$empty-image-small-size: var(--nutui-empty-image-small-size, scale-px(120px)) !default; -$empty-title-margin-top: var(--nutui-empty-title-margin-top, 0px) !default; -$empty-background-color: var( - --nutui-empty-background-color, - $color-background-overlay -) !default; -$empty-title-margin-bottom: var( - --nutui-empty-title-margin-bottom, - scale-px(12px) -) !default; -$empty-title-line-height: var( - --nutui-empty-title-line-height, - $font-size-l -) !default; -$empty-description-line-height: var( - --nutui-empty-description-line-height, - 1 -) !default; +$empty-padding: var(--nutui-empty-padding, scale-px(20px) ) !default; +$empty-title-color: var(--nutui-empty-title-color, $color-title) !default; +$empty-description-color: var(--nutui-empty-description-color, $color-text-help) !default; + +// 全屏型 +$empty-full-padding-top: var(--nutui-empty-full-padding-top, scale-px(160px)) !default; +$empty-full-image-size: var(--nutui-empty-full-image-size, scale-px(160px)) !default; +$empty-full-title-font-size: var(--nutui-empty-full-title-font-size, $font-size-md) !default; +$empty-full-title-line-height: var(--nutui-empty-full-title-line-height, $line-height-xxl) !default; +$empty-full-description-font-size: var(--nutui-empty-full-description-font-size, $font-size-base) !default; +$empty-full-description-line-height: var(--nutui-empty-full-description-line-height, scale-font-px(22px)) !default; +$empty-full-actions-margin-top: var(--nutui-empty-full-actions-margin-top, scale-px(8px)) !default; + +// 半屏型 +$empty-half-image-size: var(--nutui-empty-half-image-size, scale-px(80px)) !default; +$empty-half-title-font-size: var(--nutui-empty-half-title-font-size, $font-size-s) !default; +$empty-half-title-line-height: var(--nutui-empty-half-title-line-height, scale-font-px(22px)) !default; +$empty-half-description-font-size: var(--nutui-empty-half-description-font-size, $font-size-m) !default; +$empty-half-description-line-height: var(--nutui-empty-half-description-line-height, $line-height-2xl) !default; +$empty-half-actions-margin-top: var(--nutui-empty-half-actions-margin-top, scale-px(8px)) !default; + +// 局部型 +$empty-partial-padding: var(--nutui-empty-partial-padding, scale-px(0px) scale-px(16px)) !default; +$empty-partial-image-size: var(--nutui-empty-partial-image-size, scale-px(32px)) !default; +$empty-partial-content-gap: var(--nutui-empty-partial-content-gap, scale-px(8px)) !default; +$empty-partial-description-font-size: var(--nutui-empty-partial-description-font-size, $font-size-m) !default; +$empty-partial-description-line-height: var(--nutui-empty-partial-description-line-height, scale-font-px(32px)) !default; // cascader(✅) $cascader-font-size: var(--nutui-cascader-font-size, $font-size-base) !default; diff --git a/src/types/spec/empty/base.ts b/src/types/spec/empty/base.ts index 54880f83b1..0b94411d85 100644 --- a/src/types/spec/empty/base.ts +++ b/src/types/spec/empty/base.ts @@ -4,17 +4,45 @@ import { SimpleValue, UIFill, UISize, UIType } from '../../base/atoms' export interface EmptyAction { text: ReactNode - type: UIType - size: UISize - fill: UIFill - disabled: boolean - onClick: () => void + type?: UIType + size?: UISize + fill?: UIFill + disabled?: boolean + onClick?: () => void } -export type EmptyState = 'empty' | 'error' | 'network' +export type EmptyStatus = + | 'network' + | 'comment' + | 'search' + | 'shop' + | 'address' + | 'order' + | 'favor' + | 'cart' -type statusOptions = { - [key: string]: string +export type EmptySize = 'full' | 'half' | 'partial' + +/** 内置缺省插图 URL;图片本体走 CDN 运行时加载,打进包内的仅为 URL 字符串 */ +export const EMPTY_STATUS_IMAGES: Record = { + network: + 'https://img10.360buyimg.com/imagetools/jfs/t1/449411/36/15729/19102/6a30e810F36720c83/03e61e01e08ab731.png', + comment: + 'https://img12.360buyimg.com/imagetools/jfs/t1/458866/29/4221/20560/6a30e810F02e0c676/03e61e01e02c0dab.png', + search: + 'https://img12.360buyimg.com/imagetools/jfs/t1/453287/39/13487/21638/6a30e810Fc7b15ec6/03e61e01e0bf5f81.png', + shop: 'https://img11.360buyimg.com/imagetools/jfs/t1/447986/21/19304/24327/6a30e810F0a9c3aca/03e61e01dd8d09b1.png', + address: + 'https://img12.360buyimg.com/imagetools/jfs/t1/446923/19/19328/23073/6a30e810F37ec221d/03e61e01e0e69357.png', + order: + 'https://img11.360buyimg.com/imagetools/jfs/t1/455990/2/7107/24405/6a30e810Fcb5a39b1/03e61e01e0715a43.png', + favor: + 'https://img12.360buyimg.com/imagetools/jfs/t1/458517/13/4983/22338/6a30e810F9d69ff57/03e61e01e092c3f9.png', + cart: 'https://img11.360buyimg.com/imagetools/jfs/t1/453149/9/10304/23216/6a30e810Ff6c0d230/03e61e01e0b41203.png', +} + +export const getEmptyStatusImage = (status: EmptyStatus) => { + return EMPTY_STATUS_IMAGES[status] || EMPTY_STATUS_IMAGES.network } export interface BaseEmpty extends BaseProps { @@ -22,7 +50,7 @@ export interface BaseEmpty extends BaseProps { imageSize: SimpleValue title: ReactNode description: ReactNode - size: Extract - status: EmptyState + size: EmptySize + status: EmptyStatus actions: Array }