Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions docs/zh-CN/components/card.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,109 @@ order: 31

注意它和前面的 `href` 配置冲突,如果设置了 `href` 这个将不会生效

## 配置工具栏

> 1.5.0 及以上版本

```schema: scope="body"
{
"type": "card",
"header": {
"title": "标题",
"subTitle": "副标题",
"description": "这是一段描述",
"avatarClassName": "pull-left thumb-md avatar b-3x m-r",
"avatar": "data:image/svg+xml,%3C%3Fxml version='1.0' standalone='no'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg t='1631083237695' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='2420' xmlns:xlink='http://www.w3.org/1999/xlink' width='1024' height='1024'%3E%3Cdefs%3E%3Cstyle type='text/css'%3E%3C/style%3E%3C/defs%3E%3Cpath d='M959.872 128c0.032 0.032 0.096 0.064 0.128 0.128v767.776c-0.032 0.032-0.064 0.096-0.128 0.128H64.096c-0.032-0.032-0.096-0.064-0.128-0.128V128.128c0.032-0.032 0.064-0.096 0.128-0.128h895.776zM960 64H64C28.8 64 0 92.8 0 128v768c0 35.2 28.8 64 64 64h896c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z' p-id='2421' fill='%23bfbfbf'%3E%3C/path%3E%3Cpath d='M832 288c0 53.024-42.976 96-96 96s-96-42.976-96-96 42.976-96 96-96 96 42.976 96 96zM896 832H128V704l224-384 256 320h64l224-192z' p-id='2422' fill='%23bfbfbf'%3E%3C/path%3E%3C/svg%3E"
},
"body": "这里是内容",
"toolbar": [
{
"type": "button",
"icon": "fa fa-eye",
"actionType": "dialog",
"dialog": {
"title": "查看",
"body": {
"type": "form",
"body": [
{
"type": "static",
"name": "engine",
"label": "Engine"
},
{
"type": "divider"
},
{
"type": "static",
"name": "browser",
"label": "Browser"
},
{
"type": "divider"
},
{
"type": "static",
"name": "platform",
"label": "Platform(s)"
},
{
"type": "divider"
},
{
"type": "static",
"name": "version",
"label": "Engine version"
},
{
"type": "divider"
},
{
"type": "static",
"name": "grade",
"label": "CSS grade"
},
{
"type": "divider"
},
{
"type": "html",
"html": "<p>添加其他 <span>Html 片段</span> 需要支持变量替换(todo).</p>"
}
]
}
}
},
{
"type": "dropdown-button",
"level": "link",
"icon": "fa fa-ellipsis-h",
"hideCaret": true,
"buttons": [
{
"type": "button",
"label": "编辑",
"actionType": "dialog",
"dialog": {
"title": "编辑",
"body": "你正在编辑该卡片"
}
},
{
"type": "button",
"label": "删除",
"actionType": "dialog",
"dialog": {
"title": "提示",
"body": "你删掉了该卡片"
}
}
]
}
]
}
```

## 属性表

| 属性名 | 类型 | 默认值 | 说明 |
Expand Down
2 changes: 2 additions & 0 deletions scss/base/_normalize.scss
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ svg.icon {
width: 1em;
height: 1em;
fill: currentColor;
position: relative;
top: 0.125em;
}

svg.r90 {
Expand Down
22 changes: 8 additions & 14 deletions scss/components/_card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,15 @@
margin-top: var(--gap-xs);
}

&-checkBtn {
position: absolute;
top: 0;
right: 0;
margin: var(--gap-sm);
z-index: 1;

.#{$ns}Checkbox {
margin-right: 0;
}
}

&-dragBtn {
cursor: pointer;
float: right;
margin: var(--gap-sm);
}

&-heading {
overflow: hidden;
display: flex;
flex-direction: row;
padding: var(--gap-sm) var(--gap-base);
flex: 1 0 auto;
}
Expand Down Expand Up @@ -87,12 +76,17 @@

&-meta {
display: block;
flex-grow: 1;
height: 100%;
overflow: hidden;
position: relative;
margin-right: var(--gap-md);
}

&-toolbar {
margin-right: calc(-1 * var(--gap-base));
text-align: right;
}

&-highlight {
background: var(--success);
width: px2rem(8px);
Expand Down
97 changes: 63 additions & 34 deletions src/renderers/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ export interface CardSchema extends BaseSchema {
* 底部按钮集合。
*/
actions?: Array<ActionSchema>;

/**
* 工具栏按钮
*/
toolbar?: Array<ActionSchema>;
}

export interface CardProps
Expand Down Expand Up @@ -273,30 +278,47 @@ export class Card extends React.Component<CardProps> {
multiple,
hideCheckToggler,
classnames: cx,
classPrefix: ns
classPrefix: ns,
toolbar,
render
} = this.props;

if (dragging) {
return (
<div className={cx('Card-dragBtn')}>
<Icon icon="drag-bar" className="icon" />
</div>
const toolbars: Array<JSX.Element> = [];

if (selectable && !hideCheckToggler) {
toolbars.push(
<Checkbox
key="check"
className={cx('Card-checkbox')}
type={multiple ? 'checkbox' : 'radio'}
disabled={!checkable}
checked={selected}
onChange={checkOnItemClick ? noop : this.handleCheck}
/>
);
} else if (selectable && !hideCheckToggler) {
return (
<div className={cx('Card-checkBtn')}>
<Checkbox
classPrefix={ns}
type={multiple ? 'checkbox' : 'radio'}
disabled={!checkable}
checked={selected}
onChange={checkOnItemClick ? noop : this.handleCheck}
/>
</div>
}

if (Array.isArray(toolbar)) {
toolbar.forEach((action, index) =>
toolbars.push(
render(
`toolbar/${index}`,
{
type: 'button',
level: 'link',
size: 'sm',
...(action as any)
},
{
key: index
}
)
)
);
}

return null;
return toolbars.length ? (
<div className={cx('Card-toolbar')}>{toolbars}</div>
) : null;
}

renderActions() {
Expand Down Expand Up @@ -451,12 +473,14 @@ export class Card extends React.Component<CardProps> {
imageClassName,
avatarTextClassName,
href,
itemAction
itemAction,
dragging
} = this.props;

const toolbar = this.renderToolbar();
let heading = null;

if (header) {
if (header || toolbar) {
const {
highlight: highlightTpl,
avatar: avatarTpl,
Expand All @@ -465,31 +489,31 @@ export class Card extends React.Component<CardProps> {
subTitle: subTitleTpl,
subTitlePlaceholder,
desc: descTpl
} = header;
} = header || {};

const descPlaceholder =
header.descriptionPlaceholder || header.descPlaceholder;
header?.descriptionPlaceholder || header?.descPlaceholder;

const highlight = !!evalExpression(highlightTpl!, data as object);
const avatar = filter(avatarTpl, data, '| raw');
const avatarText = filter(avatarTextTpl, data);
const title = filter(titleTpl, data);
const subTitle = filter(subTitleTpl, data);
const desc = filter(header.description || descTpl, data);
const desc = filter(header?.description || descTpl, data);

heading = (
<div className={cx('Card-heading', header.className)}>
<div className={cx('Card-heading', header?.className)}>
{avatar ? (
<span
className={cx(
'Card-avtar',
header.avatarClassName || avatarClassName
header?.avatarClassName || avatarClassName
)}
>
<img
className={cx(
'Card-img',
header.imageClassName || imageClassName
header?.imageClassName || imageClassName
)}
src={avatar}
/>
Expand All @@ -498,7 +522,7 @@ export class Card extends React.Component<CardProps> {
<span
className={cx(
'Card-avtarText',
header.avatarTextClassName || avatarTextClassName
header?.avatarTextClassName || avatarTextClassName
)}
>
{avatarText}
Expand All @@ -509,7 +533,7 @@ export class Card extends React.Component<CardProps> {
<i
className={cx(
'Card-highlight',
header.highlightClassName || highlightClassName
header?.highlightClassName || highlightClassName
)}
/>
) : null}
Expand All @@ -518,7 +542,7 @@ export class Card extends React.Component<CardProps> {
<div
className={cx(
'Card-title',
header.titleClassName || titleClassName
header?.titleClassName || titleClassName
)}
>
{render('title', title)}
Expand All @@ -529,7 +553,7 @@ export class Card extends React.Component<CardProps> {
<div
className={cx(
'Card-subTitle',
header.subTitleClassName || subTitleClassName
header?.subTitleClassName || subTitleClassName
)}
>
{render('sub-title', subTitle || subTitlePlaceholder!, {
Expand All @@ -542,8 +566,8 @@ export class Card extends React.Component<CardProps> {
<div
className={cx(
'Card-desc',
header.descriptionClassName ||
header.descClassName ||
header?.descriptionClassName ||
header?.descClassName ||
descClassName
)}
>
Expand All @@ -553,6 +577,7 @@ export class Card extends React.Component<CardProps> {
</div>
) : null}
</div>
{toolbar}
</div>
);
}
Expand All @@ -570,7 +595,11 @@ export class Card extends React.Component<CardProps> {
'Card--link': href || itemAction
})}
>
{this.renderToolbar()}
{dragging ? (
<div className={cx('Card-dragBtn')}>
<Icon icon="drag-bar" className="icon" />
</div>
) : null}
{heading}
{body ? (
<div className={cx('Card-body', bodyClassName)}>{body}</div>
Expand Down