diff --git a/src/tinyTag/__tests__/__snapshots__/tinyTag.test.tsx.snap b/src/tinyTag/__tests__/__snapshots__/tinyTag.test.tsx.snap index edfec6d98..75e9e3fd3 100644 --- a/src/tinyTag/__tests__/__snapshots__/tinyTag.test.tsx.snap +++ b/src/tinyTag/__tests__/__snapshots__/tinyTag.test.tsx.snap @@ -13,6 +13,7 @@ exports[`test StatusTag should match snapshot 1`] = ` xmlns="http://www.w3.org/2000/svg" > `; + +exports[`test StatusTag should support fill type 1`] = ` + + + + + + + 完成 + + + + + +`; diff --git a/src/tinyTag/__tests__/tinyTag.test.tsx b/src/tinyTag/__tests__/tinyTag.test.tsx index e753580df..68a8decf0 100644 --- a/src/tinyTag/__tests__/tinyTag.test.tsx +++ b/src/tinyTag/__tests__/tinyTag.test.tsx @@ -1,12 +1,76 @@ import React from 'react'; -import { cleanup, render } from '@testing-library/react'; +import { cleanup, fireEvent, render } from '@testing-library/react'; +import '@testing-library/jest-dom/extend-expect'; import TinyTag from '..'; describe('test StatusTag', () => { beforeEach(cleanup); + test('should match snapshot', () => { const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); + + test('should support fill type', () => { + const { asFragment } = render( + + ); + expect(asFragment()).toMatchSnapshot(); + }); + + test('should render custom color in default mode', () => { + const { container } = render(); + const rect = container.querySelector('rect'); + const text = container.querySelector('text'); + + expect(rect).toHaveAttribute('stroke', '#1890ff'); + expect(rect).toHaveAttribute('fill', 'none'); + expect(text).toHaveAttribute('fill', '#1890ff'); + }); + + test('should render correct attributes and class in fill mode', () => { + const { container } = render( + + ); + const span = container.querySelector('.dtc-tinyTag'); + const rect = container.querySelector('rect'); + const text = container.querySelector('text'); + + expect(span).toHaveClass('dtc-tinyTag--fill'); + expect(rect).toHaveAttribute('fill', '#D56161'); + expect(rect).toHaveAttribute('stroke', '#D56161'); + expect(text).toHaveAttribute('fill', '#ffffff'); + }); + + test('should fallback colors when background and color are not specified in fill mode', () => { + const { container } = render(); + const rect = container.querySelector('rect'); + const text = container.querySelector('text'); + + expect(rect).toHaveAttribute('fill', 'currentColor'); + expect(rect).toHaveAttribute('stroke', 'currentColor'); + expect(text).toHaveAttribute('fill', '#fff'); + }); + + test('should pass standard HTML attributes and handle events', () => { + const handleClick = jest.fn(); + const { container } = render( + + ); + const span = container.querySelector('span'); + + expect(span).toHaveAttribute('id', 'test-tag'); + expect(span).toHaveAttribute('data-testid', 'tiny-tag-test'); + + if (span) { + fireEvent.click(span); + } + expect(handleClick).toHaveBeenCalledTimes(1); + }); }); diff --git a/src/tinyTag/demos/basic.tsx b/src/tinyTag/demos/basic.tsx index 6e5613539..05339d050 100644 --- a/src/tinyTag/demos/basic.tsx +++ b/src/tinyTag/demos/basic.tsx @@ -10,6 +10,7 @@ export default () => { + ); }; diff --git a/src/tinyTag/index.md b/src/tinyTag/index.md index 2efa4256f..c7efd32d4 100644 --- a/src/tinyTag/index.md +++ b/src/tinyTag/index.md @@ -19,7 +19,14 @@ TinyTag 组件通常用于在某些文案后面,用于标识当前行数据的 ### TinyTag -| 参数 | 说明 | 类型 | 默认值 | -| --------- | ---------- | -------- | ------ | -| value | 标签文案 | `string` | | -| className | class 名称 | `string` | | +| 参数 | 说明 | 类型 | 默认值 | +| ---------- | ---------------------------------------------- | ----------------- | --------- | +| value | 标签文案 | `string` | - | +| type | 标签类型 | `default \| fill` | `default` | +| color | 标签字体颜色,默认模式下同时作为边框颜色 | `string` | - | +| background | 标签背景色,仅在 `type` 为 `fill` 的情况下生效 | `string` | - | +| className | class 名称 | `string` | - | + +:::info +继承原生 `` 标签的属性,支持所有 `React.HTMLAttributes` +::: diff --git a/src/tinyTag/index.tsx b/src/tinyTag/index.tsx index 7da99c41e..af3911db7 100644 --- a/src/tinyTag/index.tsx +++ b/src/tinyTag/index.tsx @@ -5,9 +5,22 @@ import './style.scss'; type UseSvgRef = (element: SVGTextElement) => void; type UseSvgWidthResult = [UseSvgRef, number, number]; +export type TinyTagType = 'default' | 'fill'; -interface ITinyTag extends React.HTMLAttributes { +export interface ITinyTag extends React.HTMLAttributes { value: string; + /** + * @description 标签类型 + */ + type?: TinyTagType; + /** + * @description 标签字体颜色,默认模式下同时作为边框颜色 + */ + color?: string; + /** + * @description 标签背景色,仅在 fill 模式下生效 + */ + background?: string; } const useSvgWidth = (): UseSvgWidthResult => { @@ -31,10 +44,28 @@ const useSvgWidth = (): UseSvgWidthResult => { return [ref, svgWidth, rectWidth]; }; -export default function TinyTag({ value, className, style, ...restProps }: ITinyTag) { +export default function TinyTag({ + value, + className, + style, + type = 'default', + color, + background, + ...restProps +}: ITinyTag) { const [ref, svgWidth, rectWidth] = useSvgWidth(); + const isFill = type === 'fill'; + const rectColor = isFill ? background || 'currentColor' : color || 'currentColor'; + const textColor = isFill ? color || '#fff' : color || 'currentColor'; + return ( - +