diff --git a/packages/zent/__tests__/card.spec.jsx b/packages/zent/__tests__/card.spec.jsx index 48a8c7579e..8dcb0b1139 100644 --- a/packages/zent/__tests__/card.spec.jsx +++ b/packages/zent/__tests__/card.spec.jsx @@ -42,4 +42,76 @@ describe('Card', () => { const cardBody = card.find('.zent-card-body'); expect(cardBody.prop('style').background).toBe('blue'); }); + it('should render borderless card', () => { + const card = shallow( + +

card items

+
+ ); + expect(card.find('.zent-card--borderless').length).toBe(1); + }); + it('card loading', () => { + const card = shallow( + +

card items

+
+ ); + expect(card.find('TextBlock').length).toBe(1); + }); +}); + +describe('Small Card', () => { + it('should render children in card-body', () => { + const card = shallow( + +

card items

+
+ ); + expect(card.find('.zent-card-body').children().length).toBe(1); + }); + it('should only render title in header', () => { + const card = shallow( + + card items + + ); + expect(card.find('.zent-card-header__action').length).toBe(0); + expect(card.find('.zent-card-header').text()).toBe('card title'); + expect(card.find('.zent-card-body').text()).toBe('card items'); + }); + it('should render left extra', () => { + const card = shallow( + +

card items

+
+ ); + expect(card.find('.zent-card__left-extra').length).toBe(1); + expect(card.find('.zent-card__left-extra').text()).toBe('left extra'); + }); + it('should render right extra', () => { + const card = shallow( + +

card items

+
+ ); + expect(card.find('.zent-card__right-extra').length).toBe(1); + expect(card.find('.zent-card__right-extra').text()).toBe('right extra'); + }); + it('should render bottom extra', () => { + const card = shallow( + +

card items

+
+ ); + expect(card.find('.zent-card__bottom-extra').length).toBe(1); + expect(card.find('.zent-card__bottom-extra').text()).toBe('bottom extra'); + }); + it('small card loading', () => { + const card = shallow( + +

card items

+
+ ); + expect(card.find('TextBlock').length).toBe(1); + }); }); diff --git a/packages/zent/assets/button.scss b/packages/zent/assets/button.scss index 270cedc773..9b76934874 100644 --- a/packages/zent/assets/button.scss +++ b/packages/zent/assets/button.scss @@ -211,6 +211,13 @@ $btn-warning-active: 1; &.zent-btn-text { @include theme-color(background-color, primary, 4, 0.03); } + + &.zent-btn-icon { + background: transparent; + } + &.zent-btn-text { + @include theme-color(background-color, primary, 4, 0.03); + } } &[type='button'], @@ -489,6 +496,20 @@ $btn-warning-active: 1; @include theme-color(border-top-color, stroke, 1); @include theme-color(border-right-color, stroke, 1); } + + &.zent-btn-small::after, + &.zent-btn-text::after { + width: 12px; + height: 12px; + margin-left: -6px; + margin-top: -6px; + border-radius: 6px; + } + + &.zent-btn-icon::after { + border-top-color: $text-300; + border-right-color: $text-300; + } } &#{&}-border-transparent { diff --git a/packages/zent/assets/card.scss b/packages/zent/assets/card.scss index 942550fdce..695f5562b4 100644 --- a/packages/zent/assets/card.scss +++ b/packages/zent/assets/card.scss @@ -1,26 +1,27 @@ @import './theme/default'; @import './theme/font'; +@import './theme/timing-functions'; .zent-card { @include theme-color(background-color, stroke, 9); @include theme-color(border-color, stroke, 6); - border-radius: 2px; + border-radius: 4px; position: relative; - border-width: 1px; - border-style: solid; overflow: hidden; + &:not(.zent-card--borderless) { + border-width: 1px; + border-style: solid; + } + &-header { @include theme-color(border-bottom-color, stroke, 6); - height: 48px; - padding: 0 20px; - border-bottom-width: 1px; - border-bottom-style: solid; + padding: 24px 24px 0; box-sizing: border-box; display: flex; justify-content: flex-end; align-items: center; - font-weight: 500; + font-weight: 600; &__title { @include theme-color(color, stroke, 1); @@ -28,6 +29,7 @@ overflow: hidden; white-space: nowrap; width: 100%; + line-height: 26px; } &__action { @@ -36,12 +38,12 @@ } &-body { - padding: 20px; + margin: 24px; } &--normal { .zent-card-header { - font-size: $font-size-large; + font-size: $font-size-h4; } .zent-card-body { @@ -53,6 +55,50 @@ .zent-card-header { @include theme-color(background-color, stroke, 8); font-size: $font-size-normal; + padding-top: 12px; + padding-bottom: 12px; + } + } + + &--small { + padding: 8px; + border-radius: 4px; + display: flex; + width: fit-content; + box-sizing: border-box; + cursor: pointer; + border: 1px solid transparent; + transition: border-color 100ms $timing-fn-linear; + + &:hover { + @include theme-color(border-color, primary, 4); + } + + .zent-card__left-extra { + margin-right: 8px; + } + + .zent-card__right-extra { + flex-grow: 1; + display: flex; + flex-direction: row-reverse; + align-items: center; + } + + .zent-card__content { + .zent-card-header { + display: block; + padding: 0; + font-size: $font-size-normal; + font-weight: 400; + } + + .zent-card-body { + @include theme-color(color, stroke, 3); + padding: 0; + margin: 0; + font-size: $font-size-small; + } } } } diff --git a/packages/zent/src/card/Card.tsx b/packages/zent/src/card/Card.tsx index c67379c41e..cba92831c1 100644 --- a/packages/zent/src/card/Card.tsx +++ b/packages/zent/src/card/Card.tsx @@ -3,6 +3,8 @@ import cx from 'classnames'; import Placeholder from '../placeholder'; import isNil from '../utils/isNil'; +export type CardSize = 'large' | 'small'; + export interface ICardProps { type?: 'normal' | 'nested'; title?: React.ReactNode; @@ -11,6 +13,11 @@ export interface ICardProps { bodyStyle?: React.CSSProperties; loading?: boolean; className?: string; + size?: CardSize; + bordered?: boolean; + leftExtra?: React.ReactNode; + rightExtra?: React.ReactNode; + bottomExtra?: React.ReactNode; } export class Card extends Component { @@ -20,6 +27,8 @@ export class Card extends Component { bodyStyle: {}, loading: false, className: '', + size: 'large', + bordered: true, }; render() { @@ -32,16 +41,49 @@ export class Card extends Component { children, className, bodyStyle, + bordered, + size, + leftExtra, + rightExtra, + bottomExtra, } = this.props; const isValidTitle = !isNil(title); const isValidAction = !isNil(action); + if (size === 'small') { + return ( +
+ {leftExtra && ( +
{leftExtra}
+ )} +
+ {isValidTitle &&
{title}
} +
+ {loading ? : children} +
+ {bottomExtra && ( +
{bottomExtra}
+ )} +
+ {rightExtra && ( +
{rightExtra}
+ )} +
+ ); + } + return (
diff --git a/packages/zent/src/card/README_en-US.md b/packages/zent/src/card/README_en-US.md index 64853c0dcf..938ffc8ebe 100644 --- a/packages/zent/src/card/README_en-US.md +++ b/packages/zent/src/card/README_en-US.md @@ -1,27 +1,44 @@ --- title: Card path: component/card -group: Data Display +group: Container +scatter: true --- ## Card -Card is used for information displayed on the card container. +The most basic information container, a rounded rectangle, is visually defined as a single unit of information. ### Guides - Control whether to display title by `title` - Provide interactive operation through `action` -- Customize content style through `bodyStyle` +- Customize content style through `bodyStyle` + +### Demos + + + + + ### API -| Props | Description | Type | Default | Alternative | -| --------- | ------- | ------ | ---- |-----| -| title | Card's title | `node` | | | -| action | Card's operation | `node` | | | -| loading | Loading state | `bool` | `false` | `true` | -| type | Card type | string | `'normal'` | `'nested'` | -| style | Custom style of the card container | `object` | `{}` | | -| bodyStyle | Custom style of the content area | `object` | `{}` | | -| className | Custom calssname | `string` | `''` | | +| Props | Description | Type | Default | Alternative | +| ----------- | ------------------------------------------------------------------------- | -------- | ---------- | ----------- | +| title | Card's title | `node` | | | +| action | Card's operation | `node` | | | +| loading | Loading state | `bool` | `false` | `true` | +| type | Card type | string | `'normal'` | `'nested'` | +| style | Custom style of the card container | `object` | `{}` | | +| bodyStyle | Custom style of the content area | `object` | `{}` | | +| className | Custom calssname | `string` | `''` | | +| size | Card Size | `string` | `'large'` | `'small'` | +| leftExtra | Custom content on the left side of the card (only for small size cards) | `node` | | | +| rightExtra | Custom content on the right side of the card (only for small size cards) | `node` | | | +| bottomExtra | Custom content on the bottom side of the card (only for small size cards) | `node` | | | + +#### The following functions is obsolete in the new design system and is only used as a reference for the old version + + + diff --git a/packages/zent/src/card/README_zh-CN.md b/packages/zent/src/card/README_zh-CN.md index 022dcd24e4..9521630b56 100644 --- a/packages/zent/src/card/README_zh-CN.md +++ b/packages/zent/src/card/README_zh-CN.md @@ -3,11 +3,12 @@ title: Card subtitle: 卡片 path: component/card group: 信息展示 +scatter: true --- ## Card 卡片 -用于在卡片容器内展示信息。 +最基础的信息容器,圆角矩形,视觉上定义为一个独立的信息单元。 ### 使用指南 @@ -15,14 +16,30 @@ group: 信息展示 - 通过 `action` 来提供交互操作 - 通过 `bodyStyle` 来自定义内容样式 +### 代码演示 + + + + + + ### API -| 参数 | 说明 | 类型 | 默认值 | 备选值 | -| --------- | ------- | ------ | ---- |-------| -| title | 标题 | `node` | | | -| action | 操作 | `node` | | | -| loading | 加载状态 | `bool` | `false` | `true` | -| type | 卡片类型,现在有两种,普通和嵌套 | `string` | `'normal'` | `'nested'` | -| style | 卡片容器自定义样式 | `object` | `{}` | | -| bodyStyle | 内容区域自定义样式 | `object` | `{}` | | -| className | 自定义额外类名 | `string` | `''` | | +| 参数 | 说明 | 类型 | 默认值 | 备选值 | +| ----------- | ---------------------------------------- | -------- | ---------- | ---------- | +| title | 标题 | `node` | | | +| action | 操作 | `node` | | | +| loading | 加载状态 | `bool` | `false` | `true` | +| type | 卡片类型,现在有两种,普通和嵌套 | `string` | `'normal'` | `'nested'` | +| style | 卡片容器自定义样式 | `object` | `{}` | | +| bodyStyle | 内容区域自定义样式 | `object` | `{}` | | +| className | 自定义额外类名 | `string` | `''` | | +| size | 卡片尺寸 | `string` | `'large'` | `'small'` | +| leftExtra | 卡片左侧自定义内容(仅在小尺寸卡片有效) | `node` | | | +| rightExtra | 卡片右侧自定义内容(仅在小尺寸卡片有效) | `node` | | | +| bottomExtra | 卡片底部自定义内容(仅在小尺寸卡片有效) | `node` | | | + +#### 以下功能新版设计语言已废弃,仅作为老版使用的参考 + + + diff --git a/packages/zent/src/card/demos/basic.md b/packages/zent/src/card/demos/basic.md index 27cffbce63..6f1e904a32 100644 --- a/packages/zent/src/card/demos/basic.md +++ b/packages/zent/src/card/demos/basic.md @@ -10,9 +10,32 @@ en-US: import { Card } from 'zent'; ReactDOM.render( - -

Card item

-
- , mountNode +
+ +

Card item

+
+ +

Card item

+
+
, + mountNode ); ``` + + diff --git a/packages/zent/src/card/demos/custom-style.md b/packages/zent/src/card/demos/custom-style.md index 6416eb10e8..b9eff2d589 100644 --- a/packages/zent/src/card/demos/custom-style.md +++ b/packages/zent/src/card/demos/custom-style.md @@ -1,5 +1,5 @@ --- -order: 5 +order: 6 zh-CN: title: 支持自定义样式 en-US: @@ -10,9 +10,20 @@ en-US: import { Card } from 'zent'; ReactDOM.render( - -

Custom background

-
+
+ + +
, mountNode ); ``` diff --git a/packages/zent/src/card/demos/loading.md b/packages/zent/src/card/demos/loading.md deleted file mode 100644 index da8ef6edab..0000000000 --- a/packages/zent/src/card/demos/loading.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -order: 6 -zh-CN: - title: 加载中状态 -en-US: - title: Loading state ---- - -```js -import { Card } from 'zent'; - -ReactDOM.render( - -

Card item

-
- , mountNode -); -``` diff --git a/packages/zent/src/card/demos/nested.md b/packages/zent/src/card/demos/nested.md index 559ad61009..4b972278f8 100644 --- a/packages/zent/src/card/demos/nested.md +++ b/packages/zent/src/card/demos/nested.md @@ -1,5 +1,5 @@ --- -order: 4 +order: 5 zh-CN: title: 嵌套卡片 outerCardTitle: 外层卡片 diff --git a/packages/zent/src/card/demos/size.md b/packages/zent/src/card/demos/size.md new file mode 100644 index 0000000000..58fc2bf046 --- /dev/null +++ b/packages/zent/src/card/demos/size.md @@ -0,0 +1,111 @@ +--- +order: 4 +zh-CN: + title: 小尺寸的卡片 + cardTitle: 卡片标题 + cardContent: 内容内容内容内容内容内容内容 + button: 按钮 +en-US: + title: Small size cards + cardTitle: Card Title + cardContent: Content Content Content Content Content Content + button: button +--- + +```js +import { Card, Button, Icon } from 'zent'; + +const PLACEHOLDER_IMG = + 'https://img01.yzcdn.cn/upload_files/2021/11/25/FnBovVAfgTaDHBmBQh23PpMwwjkY.jpg'; + +ReactDOM.render( +
+ + {i18n.cardContent} + + + } + > + {i18n.cardContent} + + + } + rightExtra={ + + } + > + {i18n.cardContent} + + + } + bottomExtra={ +
+ + + +
+ } + > + {i18n.cardContent} +
+
, + mountNode +); +``` + + diff --git a/packages/zent/src/card/demos/with-action.md b/packages/zent/src/card/demos/with-action.md index 5d80bd02c3..b1b0dcc9e0 100644 --- a/packages/zent/src/card/demos/with-action.md +++ b/packages/zent/src/card/demos/with-action.md @@ -9,20 +9,20 @@ en-US: --- ```js -import { Card } from 'zent'; +import { Card, Button } from 'zent'; ReactDOM.render( - - {i18n.youzan} - - } - > -

Card item

-
, +
+ {i18n.youzan}} + > +

Card item

+
+
+ , mountNode ); ``` diff --git a/packages/zent/src/card/demos/with-title.md b/packages/zent/src/card/demos/with-title.md index 67262d2032..a3e170e3ae 100644 --- a/packages/zent/src/card/demos/with-title.md +++ b/packages/zent/src/card/demos/with-title.md @@ -10,10 +10,18 @@ en-US: import { Card } from 'zent'; ReactDOM.render( - -

Card item

-

Card item

-
- , mountNode +
+ +

Card item

+

Card item

+

Card item

+
+
, + mountNode ); ```