Skip to content
Open
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
41 changes: 41 additions & 0 deletions src/tinyTag/__tests__/__snapshots__/tinyTag.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exports[`test StatusTag should match snapshot 1`] = `
xmlns="http://www.w3.org/2000/svg"
>
<rect
fill="none"
height="14"
rx="1.5"
stroke="currentColor"
Expand All @@ -38,3 +39,43 @@ exports[`test StatusTag should match snapshot 1`] = `
</span>
</DocumentFragment>
`;

exports[`test StatusTag should support fill type 1`] = `
<DocumentFragment>
<span
class="dtc-tinyTag dtc-tinyTag--fill"
>
<svg
fill="none"
height="15"
viewBox="0 0 8 15"
width="8"
xmlns="http://www.w3.org/2000/svg"
>
<rect
fill="#D56161"
height="14"
rx="1.5"
stroke="#D56161"
stroke-linejoin="bevel"
width="7"
x="0.5"
y="0.5"
/>
<text
fill="#fff"
font-size="10"
letter-spacing="0px"
xml:space="preserve"
>
<tspan
x="4"
y="11.1"
>
完成
</tspan>
</text>
</svg>
</span>
</DocumentFragment>
`;
66 changes: 65 additions & 1 deletion src/tinyTag/__tests__/tinyTag.test.tsx
Original file line number Diff line number Diff line change
@@ -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(<TinyTag value="完成" className="dtc-test" />);
expect(asFragment()).toMatchSnapshot();
});

test('should support fill type', () => {
const { asFragment } = render(
<TinyTag value="完成" type="fill" background="#D56161" color="#fff" />
);
expect(asFragment()).toMatchSnapshot();
});

test('should render custom color in default mode', () => {
const { container } = render(<TinyTag value="标签" color="#1890ff" />);
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(
<TinyTag value="标签" type="fill" background="#D56161" color="#ffffff" />
);
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(<TinyTag value="标签" type="fill" />);
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(
<TinyTag
value="点击标签"
id="test-tag"
data-testid="tiny-tag-test"
onClick={handleClick}
/>
);
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);
});
});
1 change: 1 addition & 0 deletions src/tinyTag/demos/basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default () => {
<TinyTag value="袋鼠云" />
<TinyTag className="data-tag" value="数据驱动" />
<TinyTag className="ued-tag" value="UED" />
<TinyTag type="fill" background="#D56161" color="#fff" value="实体标签" />
</Space>
);
};
15 changes: 11 additions & 4 deletions src/tinyTag/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
继承原生 `<span>` 标签的属性,支持所有 `React.HTMLAttributes<HTMLSpanElement>`
:::
42 changes: 37 additions & 5 deletions src/tinyTag/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLSpanElement> {
export interface ITinyTag extends React.HTMLAttributes<HTMLSpanElement> {
value: string;
/**
* @description 标签类型
*/
type?: TinyTagType;
/**
* @description 标签字体颜色,默认模式下同时作为边框颜色
*/
color?: string;
/**
* @description 标签背景色,仅在 fill 模式下生效
*/
background?: string;
}

const useSvgWidth = (): UseSvgWidthResult => {
Expand All @@ -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 (
<span className={classNames('dtc-tinyTag', className)} style={style} {...restProps}>
<span
className={classNames('dtc-tinyTag', className, {
'dtc-tinyTag--fill': isFill,
})}
style={style}
{...restProps}
>
<svg
width={svgWidth}
height="15"
Expand All @@ -48,12 +79,13 @@ export default function TinyTag({ value, className, style, ...restProps }: ITiny
width={rectWidth}
height="14"
rx="1.5"
stroke="currentColor"
fill={isFill ? rectColor : 'none'}
stroke={rectColor}
strokeLinejoin="bevel"
/>
<text
ref={ref}
fill="currentColor"
fill={textColor}
xmlSpace="preserve"
fontSize="10"
letterSpacing="0px"
Expand Down
Loading