53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import type { HTMLAttributes, ReactNode } from 'react'
|
||
import styles from './Tag.module.css'
|
||
|
||
/**
|
||
* 标签:分类、标签、元信息。
|
||
*
|
||
* 对齐参考站的 `.tags-list li a`:24px 高、13px 字、胶囊形、浅灰底,
|
||
* 左侧可以带一个小图标。需要强调时用 `variant="solid"` 换成实心底。
|
||
*/
|
||
export type TagTone = 'neutral' | 'primary' | 'success' | 'warning' | 'danger'
|
||
export type TagVariant = 'soft' | 'solid'
|
||
export type TagShape = 'pill' | 'rounded'
|
||
|
||
export type TagProps = {
|
||
tone?: TagTone
|
||
/** soft 浅底(默认)/ solid 实底 */
|
||
variant?: TagVariant
|
||
/** pill 胶囊(默认,用于分类标签)/ rounded 小方块(用于元信息前缀) */
|
||
shape?: TagShape
|
||
/** 前置图标 */
|
||
icon?: ReactNode
|
||
/** 前置状态点(比 icon 更轻,用于「已连接 / 等待中」) */
|
||
dot?: boolean
|
||
children?: ReactNode
|
||
} & HTMLAttributes<HTMLSpanElement>
|
||
|
||
export function Tag({
|
||
tone = 'neutral',
|
||
variant = 'soft',
|
||
shape = 'pill',
|
||
icon,
|
||
dot = false,
|
||
className,
|
||
children,
|
||
...rest
|
||
}: TagProps) {
|
||
const classes = [styles.root, styles[shape], styles[variant], styles[tone], className]
|
||
.filter(Boolean)
|
||
.join(' ')
|
||
|
||
return (
|
||
<span className={classes} {...rest}>
|
||
{dot && <span className={styles.dot} aria-hidden="true" />}
|
||
{icon !== undefined && (
|
||
<span className={styles.icon} aria-hidden="true">
|
||
{icon}
|
||
</span>
|
||
)}
|
||
{children}
|
||
</span>
|
||
)
|
||
}
|