Skip to content

Commit

Permalink
feat(Card): icon prop (#6683)
Browse files Browse the repository at this point in the history
  • Loading branch information
guoyunhe authored Jul 29, 2024
1 parent 4799993 commit 7fc3714
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 64 deletions.
1 change: 1 addition & 0 deletions src/components/card/card.less
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 6 additions & 0 deletions src/components/card/card.patch.less
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
&-title {
font-size: 15px;
}
&-icon {
margin-right: 8px;
}
&-extra {
margin-left: 8px;
}
}
&-body {
padding: 12px 0;
Expand Down
12 changes: 9 additions & 3 deletions src/components/card/card.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -29,8 +30,13 @@ export const Card: FC<CardProps> = props => {
style={props.headerStyle}
onClick={props.onHeaderClick}
>
{props.icon && (
<div className={`${classPrefix}-header-icon`}>{props.icon}</div>
)}
<div className={`${classPrefix}-header-title`}>{props.title}</div>
{props.extra}
{props.extra && (
<div className={`${classPrefix}-header-extra`}>{props.extra}</div>
)}
</div>
)
}
Expand Down
14 changes: 5 additions & 9 deletions src/components/card/demos/demo1.tsx
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -35,12 +35,8 @@ export default () => {

<DemoBlock title='自定义卡片内容' background='gray'>
<Card
title={
<div style={{ fontWeight: 'normal' }}>
<AntOutline style={{ marginRight: '4px', color: '#1677ff' }} />
卡片标题
</div>
}
icon={<AntOutline style={{ color: '#1677ff' }} />}
title={<div style={{ fontWeight: 'normal' }}>卡片标题</div>}
extra={<RightOutline />}
onBodyClick={onBodyClick}
onHeaderClick={onHeaderClick}
Expand Down
40 changes: 21 additions & 19 deletions src/components/card/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLDivElement, MouseEvent>) => void` | - |
| onClick | The click event of the Card | `(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void` | - |
| onHeaderClick | The click event of the header area | `(event: React.MouseEvent<HTMLDivElement, 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<HTMLDivElement, MouseEvent>) => void` | - | |
| onClick | The click event of the Card | `(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void` | - | |
| onHeaderClick | The click event of the header area | `(event: React.MouseEvent<HTMLDivElement, 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` | |
40 changes: 21 additions & 19 deletions src/components/card/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLDivElement, MouseEvent>) => void` | - |
| onClick | 卡片点击事件 | `(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void` | - |
| onHeaderClick | header 区域点击事件 | `(event: React.MouseEvent<HTMLDivElement, 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<HTMLDivElement, MouseEvent>) => void` | - | |
| onClick | 卡片点击事件 | `(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void` | - | |
| onHeaderClick | header 区域点击事件 | `(event: React.MouseEvent<HTMLDivElement, 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` | |
25 changes: 11 additions & 14 deletions src/components/card/tests/card.test.tsx
Original file line number Diff line number Diff line change
@@ -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`
Expand All @@ -10,9 +10,9 @@ it('passes a11y test', async () => {
})

test('renders with title', () => {
const { getByText } = render(<Card title='title'>Card</Card>)
const { getByText } = render(<Card title='title'>body</Card>)
expect(getByText('title')).toHaveClass(`${classPrefix}-header-title`)
expect(getByText('Card')).toHaveClass(`${classPrefix}-body`)
expect(getByText('body')).toHaveClass(`${classPrefix}-body`)
})

test('renders with event', async () => {
Expand All @@ -21,32 +21,29 @@ test('renders with event', async () => {

const { getByText } = render(
<Card
title={
<div style={{ fontWeight: 'normal' }}>
<AppOutline style={{ marginRight: '4px', color: '#1677ff' }} />
卡片标题
</div>
}
icon='icon'
title='title'
extra={<RightOutline />}
onBodyClick={onBodyClick}
onHeaderClick={onHeaderClick}
>
Card
body
</Card>
)
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)
})
})

test('renders without children', async () => {
const { getByTestId } = render(
<Card title={'标题'} data-testid='test-card-id' />
<Card title='title' data-testid='test-card-id' />
)
expect(getByTestId('test-card-id')).not.toHaveClass(`${classPrefix}-body`)
})

0 comments on commit 7fc3714

Please sign in to comment.