mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-08 18:39:20 +08:00
fix(button): add theme-aware preset color hover/active tokens (#56872)
* fix(button): add theme-aware preset color hover/active tokens
Add ${colorKey}Hover and ${colorKey}Active tokens that swap values based on dark/light mode for improved contrast and user experience.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add preset color hover/active tokens for consistent button interaction
- Add xxxHover and xxxActive tokens for preset colors in genColorMapToken
- Override these tokens in dark mode to swap hover/active values
- Update ButtonToken type to include PresetColorHoverActiveMap
- Update button variant styles to use new hover/active tokens
- Fix #56656: button hover/active state inconsistency in dark mode
* test: add @csstools to compileModules
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: support .mjs files in Jest configuration
- Updated .jest.js transform pattern to include .mjs files
- Simplified .jest.node.js transform patterns
- Added jest-mjs-transformer.js for babel-jest mjs handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: remove unused jest-mjs-transformer.js
- Removed jest-mjs-transformer.js as it's no longer used
- .mjs files are now handled by the updated transform patterns in Jest configs
* test: add .mjs support to .jest.image.js
- Updated .jest.image.js transform pattern to include .mjs files
- fixes image test failures due to ES module parsing errors
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,11 @@
|
|||||||
const { moduleNameMapper, transformIgnorePatterns } = require('./.jest');
|
const { moduleNameMapper, transformIgnorePatterns } = require('./.jest');
|
||||||
|
|
||||||
// jest config for image snapshots
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setupFiles: ['./tests/setup.ts'],
|
setupFiles: ['./tests/setup.ts'],
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'md'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'md'],
|
||||||
moduleNameMapper,
|
moduleNameMapper,
|
||||||
transform: {
|
transform: {
|
||||||
'\\.tsx?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
'^.+\\.(ts|tsx|js|mjs)$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
||||||
'\\.js$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
|
||||||
'\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor',
|
'\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor',
|
||||||
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
|
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
|
||||||
},
|
},
|
||||||
|
|||||||
3
.jest.js
3
.jest.js
@@ -11,6 +11,7 @@ const compileModules = [
|
|||||||
'parse5',
|
'parse5',
|
||||||
'@exodus',
|
'@exodus',
|
||||||
'jsdom',
|
'jsdom',
|
||||||
|
'@csstools',
|
||||||
];
|
];
|
||||||
|
|
||||||
// cnpm use `_` as prefix
|
// cnpm use `_` as prefix
|
||||||
@@ -62,7 +63,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
transform: {
|
transform: {
|
||||||
'\\.tsx?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
'\\.tsx?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
||||||
'\\.(m?)js$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
'\\.(m?)js(m)?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
||||||
'\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor',
|
'\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor',
|
||||||
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
|
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
const { moduleNameMapper, transformIgnorePatterns } = require('./.jest');
|
const { moduleNameMapper, transformIgnorePatterns } = require('./.jest');
|
||||||
|
|
||||||
// jest config for server render environment
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setupFiles: ['./tests/setup.ts'],
|
setupFiles: ['./tests/setup.ts'],
|
||||||
setupFilesAfterEnv: ['./tests/setupAfterEnv.ts'],
|
setupFilesAfterEnv: ['./tests/setupAfterEnv.ts'],
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'md'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'md'],
|
||||||
moduleNameMapper,
|
moduleNameMapper,
|
||||||
transform: {
|
transform: {
|
||||||
'\\.tsx?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
'^.+\\.(ts|tsx|js|mjs)$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
||||||
'\\.js$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
|
|
||||||
'\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor',
|
'\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor',
|
||||||
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
|
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { unit } from '@ant-design/cssinjs';
|
|||||||
|
|
||||||
import { AggregationColor } from '../../color-picker/color';
|
import { AggregationColor } from '../../color-picker/color';
|
||||||
import { isBright } from '../../color-picker/components/ColorPresets';
|
import { isBright } from '../../color-picker/components/ColorPresets';
|
||||||
|
import { PresetColors } from '../../theme/interface';
|
||||||
import type { FullToken, GenStyleFn, GetDefaultToken, PresetColorKey } from '../../theme/internal';
|
import type { FullToken, GenStyleFn, GetDefaultToken, PresetColorKey } from '../../theme/internal';
|
||||||
import { getLineHeight, mergeToken } from '../../theme/internal';
|
import { getLineHeight, mergeToken } from '../../theme/internal';
|
||||||
import { PresetColors } from '../../theme/interface';
|
|
||||||
import getAlphaColor from '../../theme/util/getAlphaColor';
|
import getAlphaColor from '../../theme/util/getAlphaColor';
|
||||||
|
|
||||||
/** Component only token. Which will handle additional calculation of alias token */
|
/** Component only token. Which will handle additional calculation of alias token */
|
||||||
@@ -247,6 +247,10 @@ type ShadowColorMap = {
|
|||||||
[Key in `${PresetColorKey}ShadowColor`]: string;
|
[Key in `${PresetColorKey}ShadowColor`]: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type PresetColorHoverActiveMap = {
|
||||||
|
[Key in `${PresetColorKey}Hover` | `${PresetColorKey}Active`]: string;
|
||||||
|
};
|
||||||
|
|
||||||
type GroupToken = {
|
type GroupToken = {
|
||||||
/**
|
/**
|
||||||
* @desc 按钮组边框颜色
|
* @desc 按钮组边框颜色
|
||||||
@@ -257,7 +261,11 @@ type GroupToken = {
|
|||||||
groupBorderColor: string;
|
groupBorderColor: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ButtonToken extends FullToken<'Button'>, ShadowColorMap, GroupToken {
|
export interface ButtonToken
|
||||||
|
extends FullToken<'Button'>,
|
||||||
|
ShadowColorMap,
|
||||||
|
PresetColorHoverActiveMap,
|
||||||
|
GroupToken {
|
||||||
/**
|
/**
|
||||||
* @desc 按钮横向内边距
|
* @desc 按钮横向内边距
|
||||||
* @descEN Horizontal padding of button
|
* @descEN Horizontal padding of button
|
||||||
|
|||||||
@@ -268,10 +268,10 @@ const genVariantStyle: GenerateStyle<ButtonToken> = (token) => {
|
|||||||
PresetColors.map((colorKey) => {
|
PresetColors.map((colorKey) => {
|
||||||
const darkColor = token[`${colorKey}6`];
|
const darkColor = token[`${colorKey}6`];
|
||||||
const lightColor = token[`${colorKey}1`];
|
const lightColor = token[`${colorKey}1`];
|
||||||
const hoverColor = token[`${colorKey}5`];
|
const hoverColor = token[`${colorKey}Hover`];
|
||||||
const lightHoverColor = token[`${colorKey}2`];
|
const lightHoverColor = token[`${colorKey}2`];
|
||||||
const lightActiveColor = token[`${colorKey}3`];
|
const lightActiveColor = token[`${colorKey}3`];
|
||||||
const activeColor = token[`${colorKey}7`];
|
const activeColor = token[`${colorKey}Active`];
|
||||||
|
|
||||||
const shadowColor = token[`${colorKey}ShadowColor`];
|
const shadowColor = token[`${colorKey}ShadowColor`];
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { generate } from '@ant-design/colors';
|
|||||||
import type { DerivativeFunc } from '@ant-design/cssinjs';
|
import type { DerivativeFunc } from '@ant-design/cssinjs';
|
||||||
|
|
||||||
import type { MapToken, PresetColorType, SeedToken } from '../../interface';
|
import type { MapToken, PresetColorType, SeedToken } from '../../interface';
|
||||||
|
import { PresetColors } from '../../interface/presetColors';
|
||||||
import defaultAlgorithm from '../default';
|
import defaultAlgorithm from '../default';
|
||||||
import { defaultPresetColors } from '../seed';
|
import { defaultPresetColors } from '../seed';
|
||||||
import genColorMapToken from '../shared/genColorMapToken';
|
import genColorMapToken from '../shared/genColorMapToken';
|
||||||
@@ -29,6 +30,19 @@ const derivative: DerivativeFunc<SeedToken, MapToken> = (token, mapToken) => {
|
|||||||
generateNeutralColorPalettes,
|
generateNeutralColorPalettes,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const presetColorHoverActiveTokens = PresetColors.reduce<Record<string, string>>(
|
||||||
|
(prev, colorKey) => {
|
||||||
|
const colorBase = token[colorKey as keyof PresetColorType];
|
||||||
|
if (colorBase) {
|
||||||
|
const colorPalette = generateColorPalettes(colorBase);
|
||||||
|
prev[`${colorKey}Hover`] = colorPalette[7];
|
||||||
|
prev[`${colorKey}Active`] = colorPalette[5];
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...mergedMapToken,
|
...mergedMapToken,
|
||||||
|
|
||||||
@@ -38,6 +52,8 @@ const derivative: DerivativeFunc<SeedToken, MapToken> = (token, mapToken) => {
|
|||||||
// Colors
|
// Colors
|
||||||
...colorMapToken,
|
...colorMapToken,
|
||||||
|
|
||||||
|
...presetColorHoverActiveTokens,
|
||||||
|
|
||||||
// Customize selected item background color
|
// Customize selected item background color
|
||||||
// https://github.com/ant-design/ant-design/issues/30524#issuecomment-871961867
|
// https://github.com/ant-design/ant-design/issues/30524#issuecomment-871961867
|
||||||
colorPrimaryBg: colorMapToken.colorPrimaryBorder,
|
colorPrimaryBg: colorMapToken.colorPrimaryBorder,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { FastColor } from '@ant-design/fast-color';
|
import { FastColor } from '@ant-design/fast-color';
|
||||||
|
|
||||||
import type { ColorMapToken, SeedToken } from '../../interface';
|
import type { ColorMapToken, SeedToken } from '../../interface';
|
||||||
|
import { PresetColors } from '../../interface/presetColors';
|
||||||
import type { GenerateColorMap, GenerateNeutralColorMap } from '../ColorMap';
|
import type { GenerateColorMap, GenerateNeutralColorMap } from '../ColorMap';
|
||||||
|
|
||||||
interface PaletteGenerators {
|
interface PaletteGenerators {
|
||||||
@@ -37,6 +38,16 @@ export default function genColorMapToken(
|
|||||||
.mix(new FastColor(errorColors[3]), 50)
|
.mix(new FastColor(errorColors[3]), 50)
|
||||||
.toHexString();
|
.toHexString();
|
||||||
|
|
||||||
|
const presetColorTokens: Record<string, string> = {};
|
||||||
|
PresetColors.forEach((colorKey) => {
|
||||||
|
const colorBase = seed[colorKey];
|
||||||
|
if (colorBase) {
|
||||||
|
const colorPalette = generateColorPalettes(colorBase);
|
||||||
|
presetColorTokens[`${colorKey}Hover`] = colorPalette[5];
|
||||||
|
presetColorTokens[`${colorKey}Active`] = colorPalette[7];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...neutralColors,
|
...neutralColors,
|
||||||
|
|
||||||
@@ -101,6 +112,8 @@ export default function genColorMapToken(
|
|||||||
colorLink: linkColors[6],
|
colorLink: linkColors[6],
|
||||||
colorLinkActive: linkColors[7],
|
colorLinkActive: linkColors[7],
|
||||||
|
|
||||||
|
...presetColorTokens,
|
||||||
|
|
||||||
colorBgMask: new FastColor('#000').setA(0.45).toRgbString(),
|
colorBgMask: new FastColor('#000').setA(0.45).toRgbString(),
|
||||||
colorWhite: '#fff',
|
colorWhite: '#fff',
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user