From 49e0b6e6e55258e6d32d363c09a14f4901c568a8 Mon Sep 17 00:00:00 2001 From: yilin Date: Thu, 10 Feb 2022 14:12:33 +0800 Subject: [PATCH] V10 tag (#1876) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ✨ 新增 `LinkTag` 和 `SelectTag` 组件 - ✨ 新增 `size` 属性,支持调整组件尺寸 - 📚 `彩色标签`和`可关闭标签`新版设计已不再使用,文档中加了对应说明 ## break change - 默认 theme 调整为 `grey` 以适配新版设计语言 --- packages/zent/__tests__/tag.spec.jsx | 41 ++++++++++++-- packages/zent/assets/tag.scss | 46 +++++++++++++++- packages/zent/src/form/README_zh-CN.md | 4 +- packages/zent/src/tag/LinkTag.tsx | 30 +++++++++++ packages/zent/src/tag/README_en-US.md | 46 +++++++++++++--- packages/zent/src/tag/README_zh-CN.md | 66 +++++++++++++++++------ packages/zent/src/tag/SelectTag.tsx | 37 +++++++++++++ packages/zent/src/tag/Tag.tsx | 5 +- packages/zent/src/tag/demos/basic.md | 6 +-- packages/zent/src/tag/demos/custom.md | 2 +- packages/zent/src/tag/demos/on-close.md | 13 ++--- packages/zent/src/tag/demos/select-tag.md | 29 ++++++++++ packages/zent/src/tag/demos/size.md | 32 +++++++++++ packages/zent/src/tag/demos/style.md | 2 +- packages/zent/src/tag/index.ts | 2 + 15 files changed, 316 insertions(+), 45 deletions(-) create mode 100644 packages/zent/src/tag/LinkTag.tsx create mode 100644 packages/zent/src/tag/SelectTag.tsx create mode 100644 packages/zent/src/tag/demos/select-tag.md create mode 100644 packages/zent/src/tag/demos/size.md diff --git a/packages/zent/__tests__/tag.spec.jsx b/packages/zent/__tests__/tag.spec.jsx index d1e9cb7434..edb6dfa323 100644 --- a/packages/zent/__tests__/tag.spec.jsx +++ b/packages/zent/__tests__/tag.spec.jsx @@ -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() }); @@ -10,7 +10,7 @@ describe('Tag', () => { const wrapper = mount(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( @@ -25,6 +25,11 @@ describe('Tag', () => { expect(wrapper.find('.zent-tag.label').length).toBe(1); }); + it('can be invisible', () => { + const wrapper = mount(); + expect(wrapper.find('.zent-tag').length).toBe(0); + }); + it('can have close button', () => { const wrapper = mount( @@ -44,6 +49,11 @@ describe('Tag', () => { expect(() => wrapper.find('ZentIcon').simulate('click')).not.toThrow(); }); + it('has different size', () => { + const wrapper = mount(); + expect(wrapper.find('.zent-tag-size-large').length).toBe(1); + }); + it('has red theme', () => { const wrapper = mount(); expect(wrapper.find('.zent-tag-style-red').length).toBe(1); @@ -71,7 +81,7 @@ describe('Tag', () => { it('has outline style', () => { const wrapper = mount(); - 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', () => { @@ -88,7 +98,7 @@ describe('Tag', () => { expect( wrapper.containsMatchingElement(
#ff1493
@@ -117,3 +127,26 @@ describe('Tag', () => { ).toBe(true); }); }); + +describe('LinkTag', () => { + it('has a link icon', () => { + const wrapper = mount( + + tag + + ); + expect(wrapper.find('ZentIcon').length).toBe(1); + }); +}); + +describe('SelectTag', () => { + it('can have a onChange callback', () => { + const onChange = jest.fn(); + let wrapper = mount(); + wrapper.simulate('click'); + expect(onChange.mock.calls.length).toBe(1); + + wrapper = mount(); + expect(() => wrapper.simulate('click')).not.toThrow(); + }); +}); diff --git a/packages/zent/assets/tag.scss b/packages/zent/assets/tag.scss index 260eb0069b..b40a2eada1 100644 --- a/packages/zent/assets/tag.scss +++ b/packages/zent/assets/tag.scss @@ -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; } @@ -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 { diff --git a/packages/zent/src/form/README_zh-CN.md b/packages/zent/src/form/README_zh-CN.md index 14bbcc8258..87cd0d7c8b 100644 --- a/packages/zent/src/form/README_zh-CN.md +++ b/packages/zent/src/form/README_zh-CN.md @@ -365,7 +365,7 @@ type Middleware = (next: IValidator) => IValidator; - `Form.useFieldArrayChildModels` - `Form.useNamedChildModel(parent: FieldSetModel, name: string): BasicModel`,注意 `FormModel` 是 `FieldSetModel` 的子类,所以也适用于这个方法。 - + 这两个 hook 不监听子 model 内部状态的变化,如有需要,需使用它们返回的 model 对象自行调用 `useField` 等 hook 来实现。 通过结合上述这些能力,就可以完成 `Model` 模式下表单项的动态增删了。 @@ -432,7 +432,7 @@ type Middleware = (next: IValidator) => IValidator; `Form` 组件使用 `flex` 布局,有两个参数控制基本的布局结构 - `layout` 控制**表单项内**的布局方式,支持水平 `horizontal` 和垂直 `vertical` 两种布局 -- `direction` 控制**表单项间**的排列方式,支持 `column` 和 `row` 两种排列。 +- `direction` 控制**表单项间**的排列方式,支持 `column` 和 `row` 两种排列。 水平排列通常来说需要设置表单项的**最小宽度**才能正常工作,可以通过 `FormContext` 中的 `controlStyle` 来批量设置。 diff --git a/packages/zent/src/tag/LinkTag.tsx b/packages/zent/src/tag/LinkTag.tsx new file mode 100644 index 0000000000..de4497cfb7 --- /dev/null +++ b/packages/zent/src/tag/LinkTag.tsx @@ -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( + ({ className, children, linkIconStyle, ...rest }, ref) => { + return ( + +
{children}
+ +
+ ); + } +); + +LinkTag.displayName = 'ZentLinkTag'; + +export default LinkTag; diff --git a/packages/zent/src/tag/README_en-US.md b/packages/zent/src/tag/README_en-US.md index cd7e65372d..171a85a8b1 100644 --- a/packages/zent/src/tag/README_en-US.md +++ b/packages/zent/src/tag/README_en-US.md @@ -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 + + + + + +#### The following functions is obsolete in the new design system and is only used as a reference for the old version + + + + ### 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 diff --git a/packages/zent/src/tag/README_zh-CN.md b/packages/zent/src/tag/README_zh-CN.md index 6594b5c36f..0e93691de6 100644 --- a/packages/zent/src/tag/README_zh-CN.md +++ b/packages/zent/src/tag/README_zh-CN.md @@ -2,31 +2,65 @@ title: Tag subtitle: 标签 path: component/tag -group: 展示 +group: 基础控件 +scatter: true --- ## Tag 标签 -标签用于进行标记和分类。 +常用于标记对象属性、分类,通常为圆角矩形。 ### 使用指南 -- 用于添加特殊标记或者分类记号。 -- 可添加多个标签。 -- 标签内字数建议不超过四个字。 +- 当需要对内容进行属性、维度的标记,或补充描述时使用 +- 使用标签进行跨层级的检索 +- 标签文本建议不超过7个字,展示标签的尺寸可根据需要配置 + +### 代码演示 + + + + + +#### 以下功能新版设计语言已废弃,仅作为老版使用的参考 + + + + ### 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 的选中状态是完全受控的 diff --git a/packages/zent/src/tag/SelectTag.tsx b/packages/zent/src/tag/SelectTag.tsx new file mode 100644 index 0000000000..6a8510134a --- /dev/null +++ b/packages/zent/src/tag/SelectTag.tsx @@ -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( + ({ className, children, selected, onChange, ...rest }, ref) => { + const handleClick = (_e: React.MouseEvent) => { + onChange?.(!selected); + }; + return ( + + {children} + + ); + } +); + +SelectTag.displayName = 'ZentSelectTag'; + +export default SelectTag; diff --git a/packages/zent/src/tag/Tag.tsx b/packages/zent/src/tag/Tag.tsx index 02394727b4..09f573bc57 100644 --- a/packages/zent/src/tag/Tag.tsx +++ b/packages/zent/src/tag/Tag.tsx @@ -19,12 +19,14 @@ export interface ITagProps extends React.HTMLAttributes { style?: React.CSSProperties; closeButtonStyle?: React.CSSProperties; visible?: boolean; + size?: 'small' | 'medium' | 'large'; } export const Tag = forwardRef( ( { - theme = 'red', + size = 'small', + theme = 'grey', outline, rounded = true, closable, @@ -48,6 +50,7 @@ export const Tag = forwardRef( className={cx( 'zent-tag', `zent-tag-style${colorPart}${outlinePart}`, + `zent-tag-size-${size}`, className, { 'zent-tag-rounded': rounded, diff --git a/packages/zent/src/tag/demos/basic.md b/packages/zent/src/tag/demos/basic.md index cc65d67176..1d8906aeae 100644 --- a/packages/zent/src/tag/demos/basic.md +++ b/packages/zent/src/tag/demos/basic.md @@ -11,12 +11,12 @@ en-US: --- ```jsx -import { Tag } from 'zent'; +import { Tag, LinkTag } from 'zent'; ReactDOM.render(
- {i18n.content} - {i18n.link} + {i18n.content} + {i18n.link}
, mountNode ); diff --git a/packages/zent/src/tag/demos/custom.md b/packages/zent/src/tag/demos/custom.md index 11e5c967cd..d91268bf99 100644 --- a/packages/zent/src/tag/demos/custom.md +++ b/packages/zent/src/tag/demos/custom.md @@ -1,5 +1,5 @@ --- -order: 3 +order: 5 zh-CN: title: 支持自定义色彩,非圆角,标签大小 color: 自定义色彩 diff --git a/packages/zent/src/tag/demos/on-close.md b/packages/zent/src/tag/demos/on-close.md index e0e6350bcd..f9b414b8c6 100644 --- a/packages/zent/src/tag/demos/on-close.md +++ b/packages/zent/src/tag/demos/on-close.md @@ -1,15 +1,13 @@ --- -order: 3 +order: 6 zh-CN: title: 关闭标签,支持添加关闭事件 text1: 自定义色彩 - text2: 非圆角 - text3: 自定义关闭按钮颜色 + text2: 自定义关闭按钮颜色 en-US: title: Support the callback function that is trigger text1: custom color - text2: rectangle - text3: custom close button color + text2: custom close button color --- ```jsx @@ -28,11 +26,8 @@ ReactDOM.render( {i18n.text1} - - {i18n.text2} - - {i18n.text3} + {i18n.text2}
, mountNode diff --git a/packages/zent/src/tag/demos/select-tag.md b/packages/zent/src/tag/demos/select-tag.md new file mode 100644 index 0000000000..554459c864 --- /dev/null +++ b/packages/zent/src/tag/demos/select-tag.md @@ -0,0 +1,29 @@ +--- +order: 3 +zh-CN: + title: 可选中标签 + selected: 选中标签 +en-US: + title: Selectable Tags + selected: selected tag +--- + +```jsx +import { Tag, SelectTag } from 'zent'; + +function Demo() { + const [selected, setSelected] = React.useState(true); + + const handleChange = (selected) => { + setSelected(selected); + } + + return ( +
+ {i18n.selected} +
+ ); +} + +ReactDOM.render(, mountNode); +``` diff --git a/packages/zent/src/tag/demos/size.md b/packages/zent/src/tag/demos/size.md new file mode 100644 index 0000000000..22dd96b071 --- /dev/null +++ b/packages/zent/src/tag/demos/size.md @@ -0,0 +1,32 @@ +--- +order: 2 +zh-CN: + title: 标签尺寸 + small: 小标签 + medium: 中标签 + large: 大标签 +en-US: + title: Tag Size + small: small tag + medium: medium tag + large: large tag +--- + +```jsx +import { Tag } from 'zent'; + +ReactDOM.render( +
+ {i18n.small} + {i18n.medium} + {i18n.large} +
+ , mountNode +); +``` + + diff --git a/packages/zent/src/tag/demos/style.md b/packages/zent/src/tag/demos/style.md index f12900371c..7ebad9cc17 100644 --- a/packages/zent/src/tag/demos/style.md +++ b/packages/zent/src/tag/demos/style.md @@ -1,5 +1,5 @@ --- -order: 2 +order: 4 zh-CN: title: 两种风格和五种预定样式:`red`,`green`,`yellow`,`blue`,`grey` colorRed: 红色 diff --git a/packages/zent/src/tag/index.ts b/packages/zent/src/tag/index.ts index d775f93b32..62d49143ab 100644 --- a/packages/zent/src/tag/index.ts +++ b/packages/zent/src/tag/index.ts @@ -1,3 +1,5 @@ import Tag from './Tag'; export * from './Tag'; +export * from './LinkTag'; +export * from './SelectTag'; export default Tag;