diff --git a/src/components/card/card.less b/src/components/card/card.less index 9b16b8f1a5..ba31f08a36 100644 --- a/src/components/card/card.less +++ b/src/components/card/card.less @@ -9,6 +9,7 @@ display: flex; justify-content: space-between; align-items: center; + gap: var(--adm-card-header-gap, 8px); box-sizing: border-box; padding: var(--adm-card-header-padding-block, 12px) 0; &:not(:last-child) { diff --git a/src/components/card/card.patch.less b/src/components/card/card.patch.less index 06d9083701..a1b2aa81a6 100644 --- a/src/components/card/card.patch.less +++ b/src/components/card/card.patch.less @@ -12,6 +12,12 @@ &-title { font-size: 15px; } + &-icon { + margin-right: 8px; + } + &-extra { + margin-left: 8px; + } } &-body { padding: 12px 0; diff --git a/src/components/card/card.tsx b/src/components/card/card.tsx index b503beb25a..992de61950 100644 --- a/src/components/card/card.tsx +++ b/src/components/card/card.tsx @@ -1,12 +1,13 @@ -import React from 'react' -import type { FC, ReactNode, CSSProperties } from 'react' import classNames from 'classnames' +import type { CSSProperties, FC, ReactNode } from 'react' +import React from 'react' import { NativeProps, withNativeProps } from '../../utils/native-props' const classPrefix = `adm-card` export type CardProps = { title?: ReactNode + icon?: ReactNode extra?: ReactNode headerStyle?: CSSProperties headerClassName?: string @@ -29,8 +30,13 @@ export const Card: FC = props => { style={props.headerStyle} onClick={props.onHeaderClick} > + {props.icon && ( +
{props.icon}
+ )}
{props.title}
- {props.extra} + {props.extra && ( +
{props.extra}
+ )} ) } diff --git a/src/components/card/demos/demo1.tsx b/src/components/card/demos/demo1.tsx index b90cc02cdd..58c612d06d 100644 --- a/src/components/card/demos/demo1.tsx +++ b/src/components/card/demos/demo1.tsx @@ -1,7 +1,7 @@ -import React from 'react' -import { Card, Toast, Button } from 'antd-mobile' -import { DemoBlock } from 'demos' +import { Button, Card, Toast } from 'antd-mobile' import { AntOutline, RightOutline } from 'antd-mobile-icons' +import { DemoBlock } from 'demos' +import React from 'react' import styles from './demo1.less' @@ -35,12 +35,8 @@ export default () => { - - 卡片标题 - - } + icon={} + title={
卡片标题
} extra={} onBodyClick={onBodyClick} onHeaderClick={onHeaderClick} diff --git a/src/components/card/index.en.md b/src/components/card/index.en.md index 796910b8ae..6f7083723c 100644 --- a/src/components/card/index.en.md +++ b/src/components/card/index.en.md @@ -14,25 +14,27 @@ It can carry text, lists, pictures, paragraphs, etc., which is convenient for us ### Props -| Name | Description | Type | Default | -| --- | --- | --- | --- | -| bodyClassName | The custom class name of the body | `string` | - | -| bodyStyle | The custom style of the body | `React.CSSProperties` | - | -| extra | The right area of the header | `ReactNode` | - | -| headerClassName | The custom class name of the header | `string` | - | -| headerStyle | The custom style of the header | `React.CSSProperties` | - | -| onBodyClick | The click event of the body area | `(event: React.MouseEvent) => void` | - | -| onClick | The click event of the Card | `(event: React.MouseEvent) => void` | - | -| onHeaderClick | The click event of the header area | `(event: React.MouseEvent) => void` | - | -| title | The left area of the header | `ReactNode` | - | +| Name | Description | Type | Default | Version | +| --- | --- | --- | --- | --- | +| bodyClassName | The custom class name of the body | `string` | - | | +| bodyStyle | The custom style of the body | `React.CSSProperties` | - | | +| extra | The right area of the header | `ReactNode` | - | | +| headerClassName | The custom class name of the header | `string` | - | | +| headerStyle | The custom style of the header | `React.CSSProperties` | - | | +| icon | The left icon of the header | `ReactNode` | - | 5.38.0 | +| onBodyClick | The click event of the body area | `(event: React.MouseEvent) => void` | - | | +| onClick | The click event of the Card | `(event: React.MouseEvent) => void` | - | | +| onHeaderClick | The click event of the header area | `(event: React.MouseEvent) => void` | - | | +| title | The left area of the header | `ReactNode` | - | | ### CSS Variables -| Name | Description | Default | Global | -| --- | --- | --- | --- | -| `--adm-card-border-radius` | Border radius of the button. | `8px` | `--adm-card-border-radius` | -| `--adm-card-padding-inline` | Horizontal padding of the card. | `12px` | `--adm-card-padding-inline` | -| `--adm-card-header-border-width` | Bottom border width of the card header. | `0.5px` | `--adm-card-header-border-width` | -| `--adm-card-header-border-color` | Bottom border color of the card header. | `var(--adm-color-border)` | `--adm-card-header-border-color` | -| `--adm-card-header-padding-block` | Vertical of the card header. | `12px` | `--adm-card-header-padding-block` | -| `--adm-card-body-padding-block` | Vertical padding of the card body. | `12px` | `--adm-card-body-padding-block` | +| Name | Description | Default | Global | Version | +| --- | --- | --- | --- | --- | +| `--adm-card-border-radius` | Border radius of the button. | `8px` | `--adm-card-border-radius` | | +| `--adm-card-padding-inline` | Horizontal padding of the card. | `12px` | `--adm-card-padding-inline` | | +| `--adm-card-header-border-width` | Bottom border width of the card header. | `0.5px` | `--adm-card-header-border-width` | | +| `--adm-card-header-border-color` | Bottom border color of the card header. | `var(--adm-color-border)` | `--adm-card-header-border-color` | | +| `--adm-card-header-gap` | Horizontal gap of the card header. | `8px` | `--adm-card-header-gap` | 5.38.0 | +| `--adm-card-header-padding-block` | Vertical of the card header. | `12px` | `--adm-card-header-padding-block` | | +| `--adm-card-body-padding-block` | Vertical padding of the card body. | `12px` | `--adm-card-body-padding-block` | | diff --git a/src/components/card/index.zh.md b/src/components/card/index.zh.md index 5de22c6af8..00a05b01aa 100644 --- a/src/components/card/index.zh.md +++ b/src/components/card/index.zh.md @@ -14,25 +14,27 @@ ### 属性 -| 属性 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| bodyClassName | body 自定义类名 | `string` | - | -| bodyStyle | body 自定义样式 | `React.CSSProperties` | - | -| extra | header 右边区域 | `ReactNode` | - | -| headerClassName | header 自定义类名 | `string` | - | -| headerStyle | header 自定义样式 | `React.CSSProperties` | - | -| onBodyClick | body 区域点击事件 | `(event: React.MouseEvent) => void` | - | -| onClick | 卡片点击事件 | `(event: React.MouseEvent) => void` | - | -| onHeaderClick | header 区域点击事件 | `(event: React.MouseEvent) => void` | - | -| title | header 左边区域 | `ReactNode` | - | +| 属性 | 说明 | 类型 | 默认值 | 版本 | +| --- | --- | --- | --- | --- | +| bodyClassName | body 自定义类名 | `string` | - | | +| bodyStyle | body 自定义样式 | `React.CSSProperties` | - | | +| extra | header 右边区域 | `ReactNode` | - | | +| headerClassName | header 自定义类名 | `string` | - | | +| headerStyle | header 自定义样式 | `React.CSSProperties` | - | | +| icon | header 左边图标 | `ReactNode` | - | 5.38.0 | +| onBodyClick | body 区域点击事件 | `(event: React.MouseEvent) => void` | - | | +| onClick | 卡片点击事件 | `(event: React.MouseEvent) => void` | - | | +| onHeaderClick | header 区域点击事件 | `(event: React.MouseEvent) => void` | - | | +| title | header 左边区域 | `ReactNode` | - | | ### CSS 变量 -| 属性 | 说明 | 默认值 | 全局变量 | -| --- | --- | --- | --- | -| `--adm-card-border-radius` | 圆角大小 | `8px` | `--adm-card-border-radius` | -| `--adm-card-padding-inline` | 水平内边距 | `12px` | `--adm-card-padding-inline` | -| `--adm-card-header-border-width` | header 分割线宽度 | `0.5px` | `--adm-card-header-border-width` | -| `--adm-card-header-border-color` | header 分割线颜色 | `var(--adm-color-border)` | `--adm-card-header-border-color` | -| `--adm-card-header-padding-block` | header 垂直内边距 | `12px` | `--adm-card-header-padding-block` | -| `--adm-card-body-padding-block` | body 垂直内边距 | `12px` | `--adm-card-body-padding-block` | +| 属性 | 说明 | 默认值 | 全局变量 | 版本 | +| --- | --- | --- | --- | --- | +| `--adm-card-border-radius` | 圆角大小 | `8px` | `--adm-card-border-radius` | | +| `--adm-card-padding-inline` | 水平内边距 | `12px` | `--adm-card-padding-inline` | | +| `--adm-card-header-border-width` | header 分割线宽度 | `0.5px` | `--adm-card-header-border-width` | | +| `--adm-card-header-border-color` | header 分割线颜色 | `var(--adm-color-border)` | `--adm-card-header-border-color` | | +| `--adm-card-header-gap` | header 水平间隙 | `8px` | `--adm-card-header-gap` | 5.38.0 | +| `--adm-card-header-padding-block` | header 垂直内边距 | `12px` | `--adm-card-header-padding-block` | | +| `--adm-card-body-padding-block` | body 垂直内边距 | `12px` | `--adm-card-body-padding-block` | | diff --git a/src/components/card/tests/card.test.tsx b/src/components/card/tests/card.test.tsx index abbe34c125..ed4cfdddf6 100644 --- a/src/components/card/tests/card.test.tsx +++ b/src/components/card/tests/card.test.tsx @@ -1,6 +1,6 @@ +import { RightOutline } from 'antd-mobile-icons' import * as React from 'react' import { fireEvent, render, testA11y, waitFor } from 'testing' -import { AppOutline, RightOutline } from 'antd-mobile-icons' import Card from '../' const classPrefix = `adm-card` @@ -10,9 +10,9 @@ it('passes a11y test', async () => { }) test('renders with title', () => { - const { getByText } = render(Card) + const { getByText } = render(body) expect(getByText('title')).toHaveClass(`${classPrefix}-header-title`) - expect(getByText('Card')).toHaveClass(`${classPrefix}-body`) + expect(getByText('body')).toHaveClass(`${classPrefix}-body`) }) test('renders with event', async () => { @@ -21,24 +21,21 @@ test('renders with event', async () => { const { getByText } = render( - - 卡片标题 - - } + icon='icon' + title='title' extra={} onBodyClick={onBodyClick} onHeaderClick={onHeaderClick} > - Card + body ) - fireEvent.click(getByText('卡片标题')) + fireEvent.click(getByText('title')) + fireEvent.click(getByText('icon')) await waitFor(() => { - expect(onHeaderClick).toBeCalledTimes(1) + expect(onHeaderClick).toBeCalledTimes(2) }) - fireEvent.click(getByText('Card')) + fireEvent.click(getByText('body')) await waitFor(() => { expect(onBodyClick).toBeCalledTimes(1) }) @@ -46,7 +43,7 @@ test('renders with event', async () => { test('renders without children', async () => { const { getByTestId } = render( - + ) expect(getByTestId('test-card-id')).not.toHaveClass(`${classPrefix}-body`) })