This commit is contained in:
Tuyang 2025-06-04 04:35:25 +00:00 committed by GitHub
commit e7687a06b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 242 additions and 5 deletions

8
.hintrc Normal file
View File

@ -0,0 +1,8 @@
{
"extends": [
"development"
],
"hints": {
"no-inline-styles": "off"
}
}

View File

@ -0,0 +1,57 @@
import React, { forwardRef } from 'react';
import Space, { SpaceProps } from '../space';
import useToken from '../theme/useToken';
interface CompactProps extends React.HTMLAttributes<HTMLDivElement> {
direction?: SpaceProps['direction'];
}
const Compact: React.ForwardRefRenderFunction<HTMLDivElement, CompactProps> = (
{ direction, children, className, style, ...restProps },
ref,
) => {
const token = useToken()[1];
const csClas: React.CSSProperties = {
overflow: 'hidden',
backdropFilter: 'saturate(180%) blur(16px)',
borderRadius: token.borderRadius,
...style,
};
return (
<Space
ref={ref}
direction={direction}
size={0}
className={className}
{...restProps}
style={csClas}
>
{React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
// 明确类型为包含 style 属性的 React 元素
const typedChild = child as React.ReactElement<{
style?: React.CSSProperties;
}>;
// 合并 props 强制修改标签样式
return React.cloneElement(typedChild, {
...(typedChild.props as Record<string, unknown>), // 明确 props 是对象类型
style: {
margin: 0,
borderRadius: 0,
width: '100%',
textAlign: 'center',
...typedChild.props.style,
},
});
}
return child;
})}
</Space>
);
};
export default forwardRef(Compact);
Compact.displayName = 'Compact';

View File

@ -0,0 +1,7 @@
## zh-CN
`variant="clear"` 配合使用,可以得到一个背景模糊的效果,通常用于封面。
## en-US
When used with variant="clear", a background blur effect can be achieved, which is often used for covers.

View File

@ -0,0 +1,100 @@
import React, { useState } from 'react';
import { Divider, Flex, Segmented, SpaceProps, Tag } from 'antd';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
const App: React.FC = () => {
const [TagLayout, setTagLayout] = useState<SpaceProps['direction']>('horizontal');
return (
<>
<Divider orientation="left">TagLayout</Divider>
<Segmented
shape="round"
value={TagLayout}
onChange={setTagLayout}
options={[
{ value: 'vertical', icon: <AppstoreOutlined /> },
{ value: 'horizontal', icon: <BarsOutlined /> },
]}
/>
<Divider orientation="left">Demo</Divider>
<Tag.Compact direction={TagLayout}>
<Tag color="success" bordered={false}>
success
</Tag>
<Tag bordered={false} color="error">
error
</Tag>
<Tag bordered={false} color="yellow">
yellow
</Tag>
</Tag.Compact>
<Divider orientation="left">Cover Demo</Divider>
<Flex gap="4px 0" wrap>
<div
style={{
width: 262,
display: 'inline-block',
position: 'relative',
}}
>
<img
style={{
width: '100%',
height: '100%',
}}
alt="game"
src="https://www.minecraft.net/content/dam/minecraftnet/games/minecraft/key-art/Homepage_Discover-our-games_MC-Vanilla-KeyArt_864x864.jpg"
/>
<Tag.Compact
direction={TagLayout}
style={{
position: 'absolute',
bottom: 10,
right: 10,
}}
>
<Tag color="success" bordered={false}>
</Tag>
<Tag bordered={false} variant="clear">
¥298
</Tag>
</Tag.Compact>
</div>
<div
style={{
width: 262,
display: 'inline-block',
position: 'relative',
}}
>
<img
style={{
width: '100%',
height: '100%',
}}
alt="game"
src="https://www.minecraft.net/content/dam/minecraftnet/games/dungeons/key-art/Homepage_Discover-our-games_MC-Dungeons-KeyArt_864x864.jpg"
/>
<Tag.Compact
direction={TagLayout}
style={{
position: 'absolute',
bottom: 10,
right: 10,
}}
>
<Tag color="warning" bordered={false}>
</Tag>
<Tag bordered={false} variant="clear">
</Tag>
</Tag.Compact>
</div>
</Flex>
</>
);
};
export default App;

View File

@ -0,0 +1,7 @@
## zh-CN
可以为标签设置透明`clear`变体设置后背景将会为半透明效果受主题Token`colorBgMask`影响,设置后,如果没有设置`color`字体颜色为`#ffffff`。
## en-US
You can set a tag's variant to clear for a transparent effect. When set, the background will be semi-transparent and influenced by the colorBgMask theme token. After setting the variant to clear, if no color is set, the font color defaults to #ffffff (white).

View File

@ -0,0 +1,28 @@
import React from 'react';
import { Flex, Tag } from 'antd';
const PresetColors = [
'magenta',
'red',
'volcano',
'orange',
'gold',
'lime',
'green',
'cyan',
'blue',
'geekblue',
'purple',
];
const App: React.FC = () => (
<>
<Flex gap="4px 0" wrap>
{PresetColors.map((color) => (
<Tag key={color} color={color} variant="clear">
{color}
</Tag>
))}
</Flex>
</>
);
export default App;

View File

@ -19,6 +19,8 @@ demo:
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">Basic</code>
<code src="./demo/variant.tsx" debug>Transparent variant</code>
<code src="./demo/compact.tsx" debug>Combined Tag</code>
<code src="./demo/colorful.tsx">Colorful Tag</code>
<code src="./demo/colorful-inverse.tsx" debug>Inverse Colorful Tag</code>
<code src="./demo/control.tsx">Add & Remove Dynamically</code>
@ -42,10 +44,17 @@ Common props ref[Common props](/docs/react/common-props)
| --- | --- | --- | --- | --- |
| closeIcon | Custom close icon. 5.7.0: close button will be hidden when setting to `null` or `false` | ReactNode | false | 4.4.0 |
| color | Color of the Tag | string | - | |
| variant | Variant | `clear` \| `default` | `default` | |
| icon | Set the icon of tag | ReactNode | - | |
| bordered | Whether has border style | boolean | true | 5.4.0 |
| onClose | Callback executed when tag is closed | (e: React.MouseEvent<HTMLElement, MouseEvent>) => void | - | |
### Tag.Compact
| Property | Description | Type | Default |
| --------- | ------------- | ------------ | ---------- | --------- | ------------ |
| direction | Layout method | "horizontal" | "vertical" | undefined | “horizontal” |
### Tag.CheckableTag
| Property | Description | Type | Default |

View File

@ -15,7 +15,8 @@ import CheckableTag from './CheckableTag';
import useStyle from './style';
import PresetCmp from './style/presetCmp';
import StatusCmp from './style/statusCmp';
import FunVariant, { TagVariant } from './style/variant';
import Compact from './Compact';
export type { CheckableTagProps } from './CheckableTag';
export interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
@ -32,6 +33,7 @@ export interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
style?: React.CSSProperties;
icon?: React.ReactNode;
bordered?: boolean;
variant?: TagVariant;
}
const InternalTag = React.forwardRef<HTMLSpanElement, TagProps>((tagProps, ref) => {
@ -46,6 +48,7 @@ const InternalTag = React.forwardRef<HTMLSpanElement, TagProps>((tagProps, ref)
onClose,
bordered = true,
visible: deprecatedVisible,
variant,
...props
} = tagProps;
const { getPrefixCls, direction, tag: tagContext } = React.useContext(ConfigContext);
@ -69,9 +72,10 @@ const InternalTag = React.forwardRef<HTMLSpanElement, TagProps>((tagProps, ref)
const isPreset = isPresetColor(color);
const isStatus = isPresetStatusColor(color);
const isInternalColor = isPreset || isStatus;
const isVariant = FunVariant(variant as TagVariant);
const tagStyle: React.CSSProperties = {
backgroundColor: color && !isInternalColor ? color : undefined,
color: isVariant ? (!isInternalColor ? '#fff' : undefined) : undefined,
backgroundColor: isVariant || (color && !isInternalColor ? color : undefined),
...tagContext?.style,
...style,
};
@ -153,6 +157,7 @@ const InternalTag = React.forwardRef<HTMLSpanElement, TagProps>((tagProps, ref)
export type TagType = typeof InternalTag & {
CheckableTag: typeof CheckableTag;
Compact: typeof Compact;
};
const Tag = InternalTag as TagType;
@ -160,7 +165,7 @@ const Tag = InternalTag as TagType;
if (process.env.NODE_ENV !== 'production') {
Tag.displayName = 'Tag';
}
Tag.Compact = Compact;
Tag.CheckableTag = CheckableTag;
export default Tag;

View File

@ -19,6 +19,8 @@ demo:
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">基本</code>
<code src="./demo/variant.tsx" debug>透底变体</code>
<code src="./demo/compact.tsx" debug>组合标签</code>
<code src="./demo/colorful.tsx">多彩标签</code>
<code src="./demo/colorful-inverse.tsx" debug>反色多彩标签</code>
<code src="./demo/control.tsx">动态添加和删除</code>
@ -42,6 +44,7 @@ demo:
| --- | --- | --- | --- | --- |
| closeIcon | 自定义关闭按钮。5.7.0:设置为 `null``false` 时隐藏关闭按钮 | ReactNode | false | 4.4.0 |
| color | 标签色 | string | - | |
| variant | 变体 | `clear` \| `default` | `default` | |
| icon | 设置图标 | ReactNode | - | |
| bordered | 是否有边框 | boolean | true | 5.4.0 |
| onClose | 关闭时的回调(可通过 `e.preventDefault()` 来阻止默认行为) | (e: React.MouseEvent<HTMLElement, MouseEvent>) => void | - | |
@ -53,6 +56,12 @@ demo:
| checked | 设置标签的选中状态 | boolean | false |
| onChange | 点击标签时触发的回调 | (checked) => void | - |
### Tag.Compact
| 参数 | 说明 | 类型 | 默认值 |
| --------- | -------- | --------------------------------------- | ------------ |
| direction | 布局方式 | "horizontal" \| "vertical" \| undefined | “horizontal” |
## 主题变量Design Token
<ComponentTokenTable component="Tag"></ComponentTokenTable>

View File

@ -8,7 +8,6 @@ import { genSubStyleComponent } from '../../theme/internal';
// ============================== Status ==============================
type CssVariableType = 'Success' | 'Info' | 'Error' | 'Warning';
const genTagStatusStyle = (
token: TagToken,
status: 'success' | 'processing' | 'error' | 'warning',

View File

@ -0,0 +1,8 @@
import { useToken } from '../../theme/internal';
export type TagVariant = 'clear' | 'default';
export default (variant: TagVariant) => {
const token = useToken()[1];
return variant === 'clear' ? token.colorBgMask : null;
};