mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 09:26:06 +08:00
feat(Button): support color from Antd's colors (#51550)
* feat(button): add antd preset colors * chore(button): add colors to docs * test(button): add tests for colors * refactor: remove LiteralUnion * test: add const to colors * refactor(button): import from preset colors * chore(button): update docs * test(button): test with preset colors * test(button): import from relative path * fix(button): color * fix(button): add missing box shadow * test(button): merge preset colors and variants test case * refactor(button): use light color as box shadow * refactor(button): set hover color to 5 * docs(button): update doc * docs(button): update doc --------- Co-authored-by: ice <49827327+coding-ice@users.noreply.github.com> Co-authored-by: lijianan <574980606@qq.com>
This commit is contained in:
parent
6973bf2344
commit
6b98f84c62
@ -472,6 +472,162 @@ exports[`renders components/button/demo/color-variant.tsx extend context correct
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-solid ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Solid
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-outlined ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Outlined
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-dashed ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Dashed
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-filled ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Filled
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-text ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Text
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-link ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Link
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-solid ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Solid
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-outlined ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Outlined
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-dashed ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Dashed
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-filled ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Filled
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-text ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Text
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-link ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Link
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-solid ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Solid
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-outlined ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Outlined
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-dashed ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Dashed
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-filled ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Filled
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-text ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Text
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-link ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Link
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
@ -461,6 +461,162 @@ exports[`renders components/button/demo/color-variant.tsx correctly 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-solid ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Solid
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-outlined ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Outlined
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-dashed ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Dashed
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-filled ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Filled
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-text ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Text
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-link ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Link
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-solid ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Solid
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-outlined ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Outlined
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-dashed ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Dashed
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-filled ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Filled
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-text ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Text
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-link ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Link
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-solid ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Solid
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-outlined ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Outlined
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-dashed ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Dashed
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-filled ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Filled
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-text ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Text
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-link ant-btn-sm"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Link
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
@ -2,13 +2,14 @@ import React, { Suspense, useRef, useState } from 'react';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { resetWarned } from 'rc-util/lib/warning';
|
||||
|
||||
import Button from '..';
|
||||
import Button, { _ButtonVariantTypes } from '..';
|
||||
import type { GetRef } from '../../_util/type';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
import theme from '../../theme';
|
||||
import { PresetColors } from '../../theme/interface';
|
||||
import type { BaseButtonProps } from '../button';
|
||||
|
||||
describe('Button', () => {
|
||||
@ -475,6 +476,20 @@ describe('Button', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should render preset colors and variants correctly', () => {
|
||||
PresetColors.forEach((color) => {
|
||||
_ButtonVariantTypes.forEach((variant) => {
|
||||
const { container } = render(
|
||||
<Button color={color} variant={variant}>
|
||||
{color}
|
||||
</Button>,
|
||||
);
|
||||
expect(container.firstChild).toHaveClass(`ant-btn-color-${color}`);
|
||||
expect(container.firstChild).toHaveClass(`ant-btn-variant-${variant}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('autoFocus should work', () => {
|
||||
const { container } = render(<Button autoFocus>button</Button>);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import { cloneElement, isFragment } from '../_util/reactNode';
|
||||
import { PresetColors } from '../theme/interface';
|
||||
import type { BaseButtonProps, LegacyButtonType } from './button';
|
||||
|
||||
const rxTwoCNChar = /^[\u4E00-\u9FA5]{2}$/;
|
||||
@ -94,5 +95,6 @@ export const _ButtonVariantTypes = [
|
||||
] as const;
|
||||
export type ButtonVariantType = (typeof _ButtonVariantTypes)[number];
|
||||
|
||||
export const _ButtonColorTypes = ['default', 'primary', 'danger'] as const;
|
||||
export const _ButtonColorTypes = ['default', 'primary', 'danger', ...PresetColors] as const;
|
||||
|
||||
export type ButtonColorType = (typeof _ButtonColorTypes)[number];
|
||||
|
@ -68,6 +68,67 @@ const App: React.FC = () => {
|
||||
Link
|
||||
</Button>
|
||||
</Flex>
|
||||
<Flex gap="middle" wrap>
|
||||
<Button color="pink" variant="solid">
|
||||
Solid
|
||||
</Button>
|
||||
<Button color="pink" variant="outlined">
|
||||
Outlined
|
||||
</Button>
|
||||
<Button color="pink" variant="dashed">
|
||||
Dashed
|
||||
</Button>
|
||||
<Button color="pink" variant="filled">
|
||||
Filled
|
||||
</Button>
|
||||
<Button color="pink" variant="text">
|
||||
Text
|
||||
</Button>
|
||||
<Button color="pink" variant="link">
|
||||
Link
|
||||
</Button>
|
||||
</Flex>
|
||||
<Flex gap="middle" wrap>
|
||||
<Button color="purple" variant="solid">
|
||||
Solid
|
||||
</Button>
|
||||
<Button color="purple" variant="outlined">
|
||||
Outlined
|
||||
</Button>
|
||||
<Button color="purple" variant="dashed">
|
||||
Dashed
|
||||
</Button>
|
||||
<Button color="purple" variant="filled">
|
||||
Filled
|
||||
</Button>
|
||||
<Button color="purple" variant="text">
|
||||
Text
|
||||
</Button>
|
||||
<Button color="purple" variant="link">
|
||||
Link
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
<Flex gap="middle" wrap>
|
||||
<Button color="cyan" variant="solid">
|
||||
Solid
|
||||
</Button>
|
||||
<Button color="cyan" variant="outlined">
|
||||
Outlined
|
||||
</Button>
|
||||
<Button color="cyan" variant="dashed">
|
||||
Dashed
|
||||
</Button>
|
||||
<Button color="cyan" variant="filled">
|
||||
Filled
|
||||
</Button>
|
||||
<Button color="cyan" variant="text">
|
||||
Text
|
||||
</Button>
|
||||
<Button color="cyan" variant="link">
|
||||
Link
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
@ -63,7 +63,7 @@ Different button styles generated by setting Button properties. The recommended
|
||||
| autoInsertSpace | We add a space between two Chinese characters by default, which removed by setting `autoInsertSpace` to `false`. | boolean | `true` | 5.17.0 |
|
||||
| block | Option to fit button width to its parent width | boolean | false | |
|
||||
| classNames | Semantic DOM class | [Record<SemanticDOM, string>](#semantic-dom) | - | 5.4.0 |
|
||||
| color | Set button color | `default` \| `primary` \| `danger` | - | 5.21.0 |
|
||||
| color | Set button color | `default` \| `primary` \| `danger` \| [PresetColors](#presetcolors) | - | `default`, `primary` and `danger`: 5.21.0, `PresetColors`: 5.23.0 |
|
||||
| danger | Syntactic sugar. Set the danger status of button. will follow `color` if provided | boolean | false | |
|
||||
| disabled | Disabled state of button | boolean | false | |
|
||||
| ghost | Make background transparent and invert text and border colors | boolean | false | |
|
||||
@ -82,6 +82,10 @@ Different button styles generated by setting Button properties. The recommended
|
||||
|
||||
It accepts all props which native buttons support.
|
||||
|
||||
### PresetColors
|
||||
|
||||
> type PresetColors = 'blue' | 'purple' | 'cyan' | 'green' | 'magenta' | 'pink' | 'red' | 'orange' | 'yellow' | 'volcano' | 'geekblue' | 'lime' | 'gold';
|
||||
|
||||
## Semantic DOM
|
||||
|
||||
<code src="./demo/_semantic.tsx" simplify="true"></code>
|
||||
|
@ -69,7 +69,7 @@ group:
|
||||
| autoInsertSpace | 我们默认提供两个汉字之间的空格,可以设置 `autoInsertSpace` 为 `false` 关闭 | boolean | `true` | 5.17.0 |
|
||||
| block | 将按钮宽度调整为其父宽度的选项 | boolean | false | |
|
||||
| classNames | 语义化结构 class | [Record<SemanticDOM, string>](#semantic-dom) | - | 5.4.0 |
|
||||
| color | 设置按钮的颜色 | `default` \| `primary` \| `danger` | - | 5.21.0 |
|
||||
| color | 设置按钮的颜色 | `default` \| `primary` \| `danger` \| [PresetColors](#presetcolors) | - | `default`、`primary` 和 `danger`: 5.21.0, `PresetColors`: 5.23.0 |
|
||||
| danger | 语法糖,设置危险按钮。当设置 `color` 时会以后者为准 | boolean | false | |
|
||||
| disabled | 设置按钮失效状态 | boolean | false | |
|
||||
| ghost | 幽灵属性,使按钮背景透明 | boolean | false | |
|
||||
@ -88,6 +88,10 @@ group:
|
||||
|
||||
支持原生 button 的其他所有属性。
|
||||
|
||||
### PresetColors
|
||||
|
||||
> type PresetColors = 'blue' | 'purple' | 'cyan' | 'green' | 'magenta' | 'pink' | 'red' | 'orange' | 'yellow' | 'volcano' | 'geekblue' | 'lime' | 'gold';
|
||||
|
||||
## Semantic DOM
|
||||
|
||||
<code src="./demo/_semantic.tsx" simplify="true"></code>
|
||||
|
@ -2,7 +2,8 @@ import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
|
||||
import { unit } from '@ant-design/cssinjs';
|
||||
|
||||
import { genFocusStyle } from '../../style';
|
||||
import type { GenerateStyle } from '../../theme/internal';
|
||||
import { PresetColors } from '../../theme/interface';
|
||||
import type { GenerateStyle, PresetColorKey } from '../../theme/internal';
|
||||
import { genStyleHooks, mergeToken } from '../../theme/internal';
|
||||
import type { ButtonVariantType } from '../buttonHelpers';
|
||||
import genGroupStyle from './group';
|
||||
@ -14,6 +15,7 @@ export type { ComponentToken };
|
||||
// ============================== Shared ==============================
|
||||
const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSSObject => {
|
||||
const { componentCls, iconCls, fontWeight } = token;
|
||||
|
||||
return {
|
||||
[componentCls]: {
|
||||
outline: 'none',
|
||||
@ -234,6 +236,95 @@ const genTextLinkButtonStyle = (
|
||||
});
|
||||
|
||||
// =============================== Color ==============================
|
||||
const genPresetColorStyle: GenerateStyle<ButtonToken, CSSObject> = (token) => {
|
||||
const { componentCls } = token;
|
||||
|
||||
return PresetColors.reduce<CSSObject>((prev: CSSObject, colorKey: PresetColorKey) => {
|
||||
const darkColor = token[`${colorKey}6`];
|
||||
const lightColor = token[`${colorKey}1`];
|
||||
const hoverColor = token[`${colorKey}5`];
|
||||
const lightHoverColor = token[`${colorKey}2`];
|
||||
const lightBorderColor = token[`${colorKey}3`];
|
||||
const activeColor = token[`${colorKey}7`];
|
||||
const boxShadow = `0 ${token.controlOutlineWidth} 0 ${token[`${colorKey}1`]}`;
|
||||
|
||||
return {
|
||||
...prev,
|
||||
[`&${componentCls}-color-${colorKey}`]: {
|
||||
color: darkColor,
|
||||
boxShadow,
|
||||
|
||||
...genSolidButtonStyle(
|
||||
token,
|
||||
token.colorTextLightSolid,
|
||||
darkColor,
|
||||
{
|
||||
background: hoverColor,
|
||||
},
|
||||
{
|
||||
background: activeColor,
|
||||
},
|
||||
),
|
||||
|
||||
...genOutlinedDashedButtonStyle(
|
||||
token,
|
||||
darkColor,
|
||||
token.colorBgContainer,
|
||||
{
|
||||
color: hoverColor,
|
||||
borderColor: hoverColor,
|
||||
background: token.colorBgContainer,
|
||||
},
|
||||
{
|
||||
color: activeColor,
|
||||
borderColor: activeColor,
|
||||
background: token.colorBgContainer,
|
||||
},
|
||||
),
|
||||
|
||||
...genDashedButtonStyle(token),
|
||||
|
||||
...genFilledButtonStyle(
|
||||
token,
|
||||
lightColor,
|
||||
{
|
||||
background: lightHoverColor,
|
||||
},
|
||||
{
|
||||
background: lightBorderColor,
|
||||
},
|
||||
),
|
||||
|
||||
...genTextLinkButtonStyle(
|
||||
token,
|
||||
darkColor,
|
||||
'link',
|
||||
{
|
||||
color: hoverColor,
|
||||
},
|
||||
{
|
||||
color: activeColor,
|
||||
},
|
||||
),
|
||||
|
||||
...genTextLinkButtonStyle(
|
||||
token,
|
||||
darkColor,
|
||||
'text',
|
||||
{
|
||||
color: hoverColor,
|
||||
background: lightColor,
|
||||
},
|
||||
{
|
||||
color: activeColor,
|
||||
background: lightBorderColor,
|
||||
},
|
||||
),
|
||||
},
|
||||
};
|
||||
}, {});
|
||||
};
|
||||
|
||||
const genDefaultButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token) => ({
|
||||
color: token.defaultColor,
|
||||
|
||||
@ -447,6 +538,8 @@ const genColorButtonStyle: GenerateStyle<ButtonToken> = (token) => {
|
||||
[`${componentCls}-color-default`]: genDefaultButtonStyle(token),
|
||||
[`${componentCls}-color-primary`]: genPrimaryButtonStyle(token),
|
||||
[`${componentCls}-color-dangerous`]: genDangerousStyle(token),
|
||||
|
||||
...genPresetColorStyle(token),
|
||||
};
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user