浏览代码

feat: add shape option to tag (#1129)

* feat: add shape option to tag

* feat: add shape option to tag
YannLynn 3 年之前
父节点
当前提交
c6bbefad75

+ 17 - 0
content/show/tag/index-en-US.md

@@ -57,6 +57,22 @@ import { Tag } from '@douyinfe/semi-ui';
 );
 ```
 
+### Shape
+
+Supports two Shape: `square`(default)、`circle`。
+
+```jsx live=true
+import React from 'react';
+import { Tag, Space } from '@douyinfe/semi-ui';
+
+() => (
+    <Space>
+        <Tag size="small" shape='circle'> small circle tag </Tag>
+        <Tag size="large" shape='circle'> large circle tag </Tag>
+    </Space>
+);
+```
+
 ### Color
 
 Tag supports 16 colors including whites from Semi's palette: `amber`, `blue`, `cyan`, `green`, `grey`, `indigo`, `light-blue`, `light-green`, `lime`, `orange`, `pink`, `purple`, `red`, `teal`, `violet`, `yellow`, `white`. You can also customize color through `style`.
@@ -294,6 +310,7 @@ class TagGroupCloseableDemo extends React.Component {
 | className | Class name | string |  |  |
 | closable | Toggle whether the tag can be closed | boolean | false |  |
 | color | Color of tags, one of `amber`、 `blue`、 `cyan`、 `green`、 `grey`、 `indigo`、 `light-blue`、 `light-green`、 `lime`、 `orange`、 `pink`、 `purple`、 `red`、 `teal`、 `violet`、 `yellow`、 `white` | string | `grey` |  |
+| shape | Shape of tag, one of `square`、 `circle` | string | `square` | 2.20.0 |
 | size | Size, one of `small`, `large` | string | `small` |  |
 | style | Inline style | object |  |  |
 | type | Style type, one of `ghost`, `solid`, `light` | string | `light` |  |

+ 17 - 0
content/show/tag/index.md

@@ -53,6 +53,22 @@ import { Tag, Space } from '@douyinfe/semi-ui';
 );
 ```
 
+### 形状
+
+默认定义了两种形状:`square`(默认)、`circle`。
+
+```jsx live=true
+import React from 'react';
+import { Tag, Space } from '@douyinfe/semi-ui';
+
+() => (
+    <Space>
+        <Tag size="small" shape='circle'> small circle tag </Tag>
+        <Tag size="large" shape='circle'> large circle tag </Tag>
+    </Space>
+);
+```
+
 ### 颜色
 
 标签支持默认色板的 16 种颜色和白色,包括:`amber`、 `blue`、 `cyan`、 `green`、 `grey`、 `indigo`、 `light-blue`、 `light-green`、 `lime`、 `orange`、 `pink`、 `purple`、 `red`、 `teal`、 `violet`、 `yellow`、 `white`,也可以通过 style 来自定义颜色样式。
@@ -282,6 +298,7 @@ class TagGroupCloseableDemo extends React.Component {
 | className | 类名 | string |     | |
 | closable | 标签是否可以关闭 | boolean  |  false   | |
 | color  | 标签的颜色,可选 `amber`、 `blue`、 `cyan`、 `green`、 `grey`、 `indigo`、 `light-blue`、 `light-green`、 `lime`、 `orange`、 `pink`、 `purple`、 `red`、 `teal`、 `violet`、 `yellow`、 `white` | string  | `grey`| |
+| shape | 标签的形状,可选 `square`、 `circle` | string | `square` | 2.20.0 |
 | size | 标签的尺寸,可选 `small`、 `large` | string | `small` | |
 | style | 样式 | CSSProperties |     | |
 | type  | 标签的样式类型,可选 `ghost`、 `solid`、 `light` | string  | `light`     | |

+ 7 - 0
packages/semi-foundation/tag/tag.scss

@@ -30,6 +30,13 @@ $types: "ghost", "solid", "light";
         }
     }
 
+    &-square {
+        border-radius: $radius-tag;
+    }
+    &-circle {
+        border-radius: $radius-tag_circle;
+    }
+
     &-large {
         @include font-size-small;
         padding: $spacing-tag_large-paddingY $spacing-tag_large-paddingX;

+ 1 - 0
packages/semi-foundation/tag/variables.scss

@@ -20,6 +20,7 @@ $width-tag-outline: 2px; // 标签轮廓宽度
 $height-tag_small: 20px; // 小尺寸标签高度
 $height-tag_large: 24px; // 大尺寸标签高度
 $radius-tag: var(--semi-border-radius-small); // 标签圆角大小
+$radius-tag_circle: var(--semi-border-radius-full); // 胶囊标签圆角大小
 
 $spacing-tag_small-paddingY: 2px; // 小尺寸标签垂直方向内边距
 $spacing-tag_small-paddingX: $spacing-tight; // 小尺寸标签水平方向内边距

+ 28 - 0
packages/semi-ui/tag/_story/tag.stories.js

@@ -4,6 +4,7 @@ import withPropsCombinations from 'react-storybook-addon-props-combinations';
 import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
 
 import { Tag, TagGroup } from '../../index';
+import { Space } from '@douyinfe/semi-ui';
 
 export default {
   title: 'Tag'
@@ -338,3 +339,30 @@ export const Issue1107 = () => {
 Issue1107.story = {
   name: 'issue 1107',
 };
+
+export const TagShape = () => {
+  return (
+   <div>
+      <Space wrap>
+        {
+          ['amber', 'blue', 'cyan', 'green', 'grey', 'indigo',
+            'light-blue', 'light-green', 'lime', 'orange', 'pink',
+            'purple', 'red', 'teal', 'violet', 'yellow', 'white'
+          ].map(item => (<Tag color={item} key={item} shape='circle'> {item} tag </Tag>))
+        }
+      </Space>
+      <Space wrap>
+        {
+          ['amber', 'blue', 'cyan', 'green', 'grey', 'indigo',
+            'light-blue', 'light-green', 'lime', 'orange', 'pink',
+            'purple', 'red', 'teal', 'violet', 'yellow', 'white'
+          ].map(item => (<Tag color={item} key={item}> {item} tag </Tag>))
+        }
+      </Space>
+   </div>
+  )
+};
+
+TagShape.story = {
+  name: 'tag shape',
+};

+ 4 - 1
packages/semi-ui/tag/index.tsx

@@ -35,6 +35,7 @@ export default class Tag extends Component<TagProps, TagState> {
         onClick: () => undefined,
         style: {},
         className: '',
+        shape: 'square',
         avatarShape: 'square',
     };
 
@@ -120,7 +121,7 @@ export default class Tag extends Component<TagProps, TagState> {
     }
 
     render() {
-        const { tagKey, children, size, color, closable, visible, onClose, onClick, className, type, avatarSrc, avatarShape, tabIndex, ...attr } = this.props;
+        const { tagKey, children, size, color, closable, visible, onClose, onClick, className, type, shape, avatarSrc, avatarShape, tabIndex, ...attr } = this.props;
         const { visible: isVisible } = this.state;
         const clickable = onClick !== Tag.defaultProps.onClick || closable;
         // only when the Tag is clickable or closable, the value of tabIndex is allowed to be passed in. 
@@ -134,6 +135,8 @@ export default class Tag extends Component<TagProps, TagState> {
                     [`${prefixCls}-default`]: size === 'default',
                     [`${prefixCls}-small`]: size === 'small',
                     [`${prefixCls}-large`]: size === 'large',
+                    [`${prefixCls}-square`]: shape === 'square',
+                    [`${prefixCls}-circle`]: shape === 'circle',
                     [`${prefixCls}-${type}`]: type,
                     [`${prefixCls}-${color}-${type}`]: color && type,
                     [`${prefixCls}-closable`]: closable,

+ 2 - 0
packages/semi-ui/tag/interface.ts

@@ -21,6 +21,7 @@ export type TagColor =
 export type TagType = 'ghost' | 'solid' | 'light';
 export type TagSize = 'default' | 'small' | 'large';
 export type AvatarShape = 'circle' | 'square';
+export type TagShape = 'circle' | 'square';
 
 export interface TagProps {
     children?: React.ReactNode;
@@ -36,6 +37,7 @@ export interface TagProps {
     className?: string;
     avatarSrc?: string;
     avatarShape?: AvatarShape;
+    shape?: TagShape;
     onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
     'aria-label'?: React.AriaAttributes['aria-label'];
     tabIndex?: number; // use internal, when tag in taInput, we want to use left arrow and right arrow to control the tag focus, so the tabIndex need to be -1.