Skip to content

Commit

Permalink
V10 tag (#1876)
Browse files Browse the repository at this point in the history
- ✨ 新增 `LinkTag` 和 `SelectTag` 组件
- ✨ 新增 `size` 属性,支持调整组件尺寸
- 📚 `彩色标签`和`可关闭标签`新版设计已不再使用,文档中加了对应说明

## break change
- 默认 theme 调整为 `grey` 以适配新版设计语言
  • Loading branch information
w91 authored Feb 10, 2022
1 parent d3542af commit 49e0b6e
Show file tree
Hide file tree
Showing 15 changed files with 316 additions and 45 deletions.
41 changes: 37 additions & 4 deletions packages/zent/__tests__/tag.spec.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Enzyme, { mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';

import Tag from '../src/tag';
import Tag, { LinkTag, SelectTag } from '../src/tag';

Enzyme.configure({ adapter: new Adapter() });

Expand All @@ -10,7 +10,7 @@ describe('Tag', () => {
const wrapper = mount(<Tag>tag</Tag>);
expect(wrapper.find('.zent-tag').length).toBe(1);
expect(wrapper.find('.zent-tag-rounded').length).toBe(1);
expect(wrapper.find('.zent-tag-style-red').length).toBe(1);
expect(wrapper.find('.zent-tag-style-grey').length).toBe(1);
expect(wrapper.find('.zent-tag-content').length).toBe(1);
expect(wrapper.find('.zent-tag-content').text()).toBe('tag');
expect(
Expand All @@ -25,6 +25,11 @@ describe('Tag', () => {
expect(wrapper.find('.zent-tag.label').length).toBe(1);
});

it('can be invisible', () => {
const wrapper = mount(<Tag visible={false} />);
expect(wrapper.find('.zent-tag').length).toBe(0);
});

it('can have close button', () => {
const wrapper = mount(
<Tag closable>
Expand All @@ -44,6 +49,11 @@ describe('Tag', () => {
expect(() => wrapper.find('ZentIcon').simulate('click')).not.toThrow();
});

it('has different size', () => {
const wrapper = mount(<Tag size="large" />);
expect(wrapper.find('.zent-tag-size-large').length).toBe(1);
});

it('has red theme', () => {
const wrapper = mount(<Tag theme="red" />);
expect(wrapper.find('.zent-tag-style-red').length).toBe(1);
Expand Down Expand Up @@ -71,7 +81,7 @@ describe('Tag', () => {

it('has outline style', () => {
const wrapper = mount(<Tag outline />);
expect(wrapper.find('.zent-tag-style-red-outline').length).toBe(1);
expect(wrapper.find('.zent-tag-style-grey-outline').length).toBe(1);
});

it('can have custom style', () => {
Expand All @@ -88,7 +98,7 @@ describe('Tag', () => {
expect(
wrapper.containsMatchingElement(
<div
className="zent-tag zent-tag-style-red zent-tag-rounded"
className="zent-tag zent-tag-style-grey zent-tag-size-small zent-tag-rounded"
style={{ backgroundColor: '#ff1493', borderColor: '#ff1493' }}
>
<div className="zent-tag-content">#ff1493</div>
Expand Down Expand Up @@ -117,3 +127,26 @@ describe('Tag', () => {
).toBe(true);
});
});

describe('LinkTag', () => {
it('has a link icon', () => {
const wrapper = mount(
<LinkTag>
<span>tag</span>
</LinkTag>
);
expect(wrapper.find('ZentIcon').length).toBe(1);
});
});

describe('SelectTag', () => {
it('can have a onChange callback', () => {
const onChange = jest.fn();
let wrapper = mount(<SelectTag onChange={onChange} />);
wrapper.simulate('click');
expect(onChange.mock.calls.length).toBe(1);

wrapper = mount(<SelectTag onChange={null} />);
expect(() => wrapper.simulate('click')).not.toThrow();
});
});
46 changes: 45 additions & 1 deletion packages/zent/assets/tag.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@
border-style: solid;
box-sizing: border-box;

&.zent-tag-size-medium {
font-size: $font-size-normal;
}

&.zent-tag-size-large {
font-size: $font-size-normal;
line-height: 18px;
}

&.zent-tag-rounded {
border-radius: 2px;
}
Expand Down Expand Up @@ -77,7 +86,42 @@

&.zent-tag-style-grey-outline {
@include theme-color(color, stroke, 1);
@include theme-color(border-color, stroke, 4);
@include theme-color(border-color, stroke, 5);
}

&.zent-link-tag {
padding: 0 4px;

.zent-tag-content {
display: flex;
align-items: center;
}

.zent-link-tag-right-icon {
margin-right: -4px;
font-size: 16px;
@include theme-color(color, hint, color);
}

&:hover {
cursor: pointer;
@include theme-color(color, primary, bg);
@include theme-color(border-color, primary, bg);

.zent-link-tag-right-icon {
@include theme-color(color, primary, bg);
}
}
}

&.zent-select-tag {
cursor: pointer;

&.zent-select-tag-selected {
@include theme-color(color, primary, bg);
@include theme-color(background-color, default, hover-bg);
@include theme-color(border-color, default, hover-bg);
}
}

a {
Expand Down
4 changes: 2 additions & 2 deletions packages/zent/src/form/README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ type Middleware<T> = (next: IValidator<T>) => IValidator<T>;

- `Form.useFieldArrayChildModels`
- `Form.useNamedChildModel(parent: FieldSetModel, name: string): BasicModel`,注意 `FormModel``FieldSetModel` 的子类,所以也适用于这个方法。

这两个 hook 不监听子 model 内部状态的变化,如有需要,需使用它们返回的 model 对象自行调用 `useField` 等 hook 来实现。

通过结合上述这些能力,就可以完成 `Model` 模式下表单项的动态增删了。
Expand Down Expand Up @@ -432,7 +432,7 @@ type Middleware<T> = (next: IValidator<T>) => IValidator<T>;
`Form` 组件使用 `flex` 布局,有两个参数控制基本的布局结构

- `layout` 控制**表单项内**的布局方式,支持水平 `horizontal` 和垂直 `vertical` 两种布局
- `direction` 控制**表单项间**的排列方式,支持 `column``row` 两种排列。
- `direction` 控制**表单项间**的排列方式,支持 `column``row` 两种排列。

水平排列通常来说需要设置表单项的**最小宽度**才能正常工作,可以通过 `FormContext` 中的 `controlStyle` 来批量设置。

Expand Down
30 changes: 30 additions & 0 deletions packages/zent/src/tag/LinkTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { forwardRef } from 'react';
import Icon from '../icon';
import Tag, { ITagProps } from './Tag';

export interface ILinkTagProps
extends Omit<
ITagProps,
'closable' | 'closeButtonStyle' | 'size' | 'theme' | 'outline'
> {
linkIconStyle?: React.CSSProperties;
}

export const LinkTag = forwardRef<HTMLDivElement, ILinkTagProps>(
({ className, children, linkIconStyle, ...rest }, ref) => {
return (
<Tag className={`zent-link-tag ${className}`} ref={ref} outline {...rest}>
<div className="zent-link-tag-content">{children}</div>
<Icon
type="right"
className="zent-link-tag-right-icon"
style={linkIconStyle}
/>
</Tag>
);
}
);

LinkTag.displayName = 'ZentLinkTag';

export default LinkTag;
46 changes: 39 additions & 7 deletions packages/zent/src/tag/README_en-US.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,63 @@
---
title: Tag
path: component/tag
group: Data Display
group: Basics
scatter: true
---

## Tag

Tag is suitable for marking and sorting。
Often used to mark object attributes, classification, usually a rounded rectangle.

### Guides

- Tag is usually used as special marks or sorting marks.
- You can add multiple tags for one item.
- The text in tag should not more than four words.
- Use when you need to mark the attributes and dimensions of the content, or supplement the description
- Use tags for cross-level search
- It is recommended that the label text should not exceed 7 characters, and the size of the display label can be configured as required

### Demos

<!-- demo-slot-1 -->
<!-- demo-slot-2 -->
<!-- demo-slot-3 -->

#### The following functions is obsolete in the new design system and is only used as a reference for the old version

<!-- demo-slot-4 -->
<!-- demo-slot-5 -->
<!-- demo-slot-6 -->

### API

| Property | Description | Type | Default | Alternative |
| ---------------- | ------------------------------------------------------------ | ------------------- | ------- | ---------------------------------------------------------- |
| ---------------- | ------------------------------------------------------------ | ------------------- | ------- | ---------------------------------------------------------- | --- |
| theme | The preset color of tag | string | `'red'` | `'red'` \| `'green'` \| `'yellow'` \| `'blue'` \| `'grey'` |
| outline | The style with colorful border and transparent backgound. | bool | `false` | `true` \| `false` |
| rounded | Whether the tag is rounded or not | bool | `true` | `true` \| `false` |
| closable | Whether the tag can be closed | bool | `false` | `true` \| `false` |
| onClose | The callback function that is trigged when the tag is closed | func | `noop` |
| visible | Tag is visible | bool | `true` | `false` | |
| visible | Tag is visible | bool | `true` | `false` | |
| closeButtonStyle | Style of close button | React.CSSProperties | | |
| className | The custom classname | string | | |
| style | The custom style | React.CSSProperties | | |

> All props are optional, a tag can be closed by using `visible` and `onClose` together.
#### LinkTag

| Property | Description | Type | Default | Alternative |
| ------------- | -------------------------- | ------------------- | ------- | ----------- |
| className | The custom classname | string | | |
| style | The custom style | React.CSSProperties | | |
| linkIconStyle | The custom link icon style | React.CSSProperties | | |

#### SelectTag

| Property | Description | Type | Default | Alternative |
| --------- | --------------------------------------------------------------- | ------------------- | ------- | ----------------- |
| className | The custom classname | string | | |
| style | The custom style | React.CSSProperties | | |
| selected | selected state | boolean | `false` | `true` \| `false` |
| onChange | The callback function that is triggered when the tag is clicked | func | `noop` | |

> the selected state of SelectTag is fully controlled
66 changes: 50 additions & 16 deletions packages/zent/src/tag/README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,65 @@
title: Tag
subtitle: 标签
path: component/tag
group: 展示
group: 基础控件
scatter: true
---

## Tag 标签

标签用于进行标记和分类
常用于标记对象属性、分类,通常为圆角矩形

### 使用指南

- 用于添加特殊标记或者分类记号。
- 可添加多个标签。
- 标签内字数建议不超过四个字。
- 当需要对内容进行属性、维度的标记,或补充描述时使用
- 使用标签进行跨层级的检索
- 标签文本建议不超过7个字,展示标签的尺寸可根据需要配置

### 代码演示

<!-- demo-slot-1 -->
<!-- demo-slot-2 -->
<!-- demo-slot-3 -->

#### 以下功能新版设计语言已废弃,仅作为老版使用的参考

<!-- demo-slot-4 -->
<!-- demo-slot-5 -->
<!-- demo-slot-6 -->

### API

| 参数 | 说明 | 类型 | 默认值 | 备选值 |
| ---------------- | ------------------ | ------------------- | ------- | ---------------------------------------------------------- |
| theme | 标签的预置颜色 | string | `'red'` | `'red'` \| `'green'` \| `'yellow'` \| `'blue'` \| `'grey'` |
| outline | 边框有颜色,无底色 | bool | `false` | `true` \| `false` |
| rounded | 是否有圆角 | bool | `true` | `true` \| `false` |
| closable | 是否可以关闭 | bool | `false` | `true` \| `false` |
| visible | 是否显示 | bool | `true` | `false` |
| onClose | 关闭时的回调 | func | `noop` | |
| closeButtonStyle | 关闭按钮样式 | React.CSSProperties | | |
| className | 自定义额外类名 | string | | |
| style | 自定义样式 | React.CSSProperties | | |
#### Tag

| 参数 | 说明 | 类型 | 默认值 | 备选值 |
| ---------------- | ------------------ | ------------------- | -------- | ---------------------------------------------------------- |
| theme | 标签的预置颜色 | string | `'grey'` | `'red'` \| `'green'` \| `'yellow'` \| `'blue'` \| `'grey'` |
| outline | 边框有颜色,无底色 | bool | `false` | `true` \| `false` |
| rounded | 是否有圆角 | bool | `true` | `true` \| `false` |
| closable | 是否可以关闭 | bool | `false` | `true` \| `false` |
| visible | 是否显示 | bool | `true` | `false` |
| onClose | 关闭时的回调 | func | `noop` | |
| closeButtonStyle | 关闭按钮样式 | React.CSSProperties | | |
| className | 自定义额外类名 | string | | |
| style | 自定义样式 | React.CSSProperties | | |

> 所有参数都是可选,搭配 `visible``onClose` 可以实现关闭效果
#### LinkTag

| 参数 | 说明 | 类型 | 默认值 | 备选值 |
| ------------- | ------------------ | ------------------- | ------ | ------ |
| className | 自定义额外类名 | string | | |
| style | 自定义样式 | React.CSSProperties | | |
| linkIconStyle | 自定义链接图标样式 | React.CSSProperties | | |

#### SelectTag

| 参数 | 说明 | 类型 | 默认值 | 备选值 |
| --------- | ---------------- | ------------------- | ------- | ----------------- |
| className | 自定义额外类名 | string | | |
| style | 自定义样式 | React.CSSProperties | | |
| selected | 选中状态 | boolean | `false` | `true` \| `false` |
| onChange | 标签点击后的回调 | func | `noop` | |

> SelectTag 的选中状态是完全受控的
37 changes: 37 additions & 0 deletions packages/zent/src/tag/SelectTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import cx from 'classnames';
import { forwardRef } from 'react';
import Tag, { ITagProps } from './Tag';

export interface ISelectTagProps
extends Omit<
ITagProps,
'closable' | 'closeButtonStyle' | 'onChange' | 'size' | 'theme' | 'outline'
> {
selected?: boolean;
onChange?: (selected: boolean) => void;
}

export const SelectTag = forwardRef<HTMLDivElement, ISelectTagProps>(
({ className, children, selected, onChange, ...rest }, ref) => {
const handleClick = (_e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
onChange?.(!selected);
};
return (
<Tag
className={cx('zent-select-tag', className, {
'zent-select-tag-selected': selected,
})}
ref={ref}
onClick={handleClick}
outline
{...rest}
>
{children}
</Tag>
);
}
);

SelectTag.displayName = 'ZentSelectTag';

export default SelectTag;
Loading

0 comments on commit 49e0b6e

Please sign in to comment.