Merge remote-tracking branch 'origin/feature' into change-styles-classnames-ts-1

This commit is contained in:
crazyair
2026-02-06 17:13:40 +08:00
14 changed files with 83 additions and 24 deletions

View File

@@ -1,13 +1,11 @@
const { moduleNameMapper, transformIgnorePatterns } = require('./.jest');
// jest config for image snapshots
module.exports = {
setupFiles: ['./tests/setup.ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'md'],
moduleNameMapper,
transform: {
'\\.tsx?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
'\\.js$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
'^.+\\.(ts|tsx|js|mjs)$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
'\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor',
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
},

View File

@@ -11,6 +11,7 @@ const compileModules = [
'parse5',
'@exodus',
'jsdom',
'@csstools',
];
// cnpm use `_` as prefix
@@ -62,7 +63,7 @@ module.exports = {
],
transform: {
'\\.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',
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
},

View File

@@ -1,14 +1,12 @@
const { moduleNameMapper, transformIgnorePatterns } = require('./.jest');
// jest config for server render environment
module.exports = {
setupFiles: ['./tests/setup.ts'],
setupFilesAfterEnv: ['./tests/setupAfterEnv.ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'md'],
moduleNameMapper,
transform: {
'\\.tsx?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
'\\.js$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
'^.+\\.(ts|tsx|js|mjs)$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor',
'\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor',
'\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor',
},

View File

@@ -4,9 +4,9 @@ import { unit } from '@ant-design/cssinjs';
import { AggregationColor } from '../../color-picker/color';
import { isBright } from '../../color-picker/components/ColorPresets';
import { PresetColors } from '../../theme/interface';
import type { FullToken, GenStyleFn, GetDefaultToken, PresetColorKey } from '../../theme/internal';
import { getLineHeight, mergeToken } from '../../theme/internal';
import { PresetColors } from '../../theme/interface';
import getAlphaColor from '../../theme/util/getAlphaColor';
/** Component only token. Which will handle additional calculation of alias token */
@@ -247,6 +247,10 @@ type ShadowColorMap = {
[Key in `${PresetColorKey}ShadowColor`]: string;
};
type PresetColorHoverActiveMap = {
[Key in `${PresetColorKey}Hover` | `${PresetColorKey}Active`]: string;
};
type GroupToken = {
/**
* @desc 按钮组边框颜色
@@ -257,7 +261,11 @@ type GroupToken = {
groupBorderColor: string;
};
export interface ButtonToken extends FullToken<'Button'>, ShadowColorMap, GroupToken {
export interface ButtonToken
extends FullToken<'Button'>,
ShadowColorMap,
PresetColorHoverActiveMap,
GroupToken {
/**
* @desc 按钮横向内边距
* @descEN Horizontal padding of button

View File

@@ -268,10 +268,10 @@ const genVariantStyle: GenerateStyle<ButtonToken> = (token) => {
PresetColors.map((colorKey) => {
const darkColor = token[`${colorKey}6`];
const lightColor = token[`${colorKey}1`];
const hoverColor = token[`${colorKey}5`];
const hoverColor = token[`${colorKey}Hover`];
const lightHoverColor = token[`${colorKey}2`];
const lightActiveColor = token[`${colorKey}3`];
const activeColor = token[`${colorKey}7`];
const activeColor = token[`${colorKey}Active`];
const shadowColor = token[`${colorKey}ShadowColor`];

View File

@@ -297,6 +297,7 @@ describe('Modal', () => {
await waitFakeTimer(500);
});
const modalWrap = document.body.querySelectorAll('.ant-modal-wrap')[0];
fireEvent.mouseDown(modalWrap!);
fireEvent.click(modalWrap!);
await act(async () => {
await waitFakeTimer(500);

View File

@@ -678,6 +678,8 @@ describe('Modal.confirm triggers callbacks correctly', () => {
describe('the callback close should be a method when onCancel has a close parameter', () => {
(['confirm', 'info', 'success', 'warning', 'error'] as const).forEach((type) => {
it(`click the close icon to trigger ${type} onCancel`, async () => {
jest.useFakeTimers();
const mock = jest.fn();
Modal[type]?.({
@@ -688,17 +690,21 @@ describe('Modal.confirm triggers callbacks correctly', () => {
await waitFakeTimer();
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1);
$$('.ant-modal-close')[0].click();
fireEvent.click($$('.ant-modal-close')[0]);
await waitFakeTimer();
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(0);
expect(mock).toHaveBeenCalledWith(expect.any(Function));
jest.useRealTimers();
});
});
(['confirm', 'info', 'success', 'warning', 'error'] as const).forEach((type) => {
it(`press ESC to trigger ${type} onCancel`, async () => {
jest.useFakeTimers();
const mock = jest.fn();
Modal[type]?.({
@@ -709,17 +715,21 @@ describe('Modal.confirm triggers callbacks correctly', () => {
await waitFakeTimer();
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1);
fireEvent.keyDown(window, { key: 'Escape' });
fireEvent.keyDown($$(`.ant-modal-confirm-${type}`)[0], { key: 'Escape' });
await waitFakeTimer(0);
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(0);
expect(mock).toHaveBeenCalledWith(expect.any(Function));
jest.useRealTimers();
});
});
(['confirm', 'info', 'success', 'warning', 'error'] as const).forEach((type) => {
it(`click the mask to trigger ${type} onCancel`, async () => {
jest.useFakeTimers();
const mock = jest.fn();
Modal[type]?.({
@@ -732,17 +742,22 @@ describe('Modal.confirm triggers callbacks correctly', () => {
expect($$('.ant-modal-mask')).toHaveLength(1);
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(1);
$$('.ant-modal-wrap')[0].click();
fireEvent.mouseDown($$('.ant-modal-wrap')[0]);
fireEvent.click($$('.ant-modal-wrap')[0]);
await waitFakeTimer();
expect($$(`.ant-modal-confirm-${type}`)).toHaveLength(0);
expect(mock).toHaveBeenCalledWith(expect.any(Function));
jest.useRealTimers();
});
});
});
it('confirm modal click Cancel button close callback is a function', async () => {
jest.useFakeTimers();
const mock = jest.fn();
Modal.confirm({
@@ -751,13 +766,17 @@ describe('Modal.confirm triggers callbacks correctly', () => {
await waitFakeTimer();
$$('.ant-modal-confirm-btns > .ant-btn')[0].click();
fireEvent.click($$('.ant-modal-confirm-btns > .ant-btn')[0]);
await waitFakeTimer();
expect(mock).toHaveBeenCalledWith(expect.any(Function));
jest.useRealTimers();
});
it('close can close modal when onCancel has a close parameter', async () => {
jest.useFakeTimers();
Modal.confirm({
onCancel: (close) => close(),
});
@@ -766,10 +785,12 @@ describe('Modal.confirm triggers callbacks correctly', () => {
expect($$('.ant-modal-confirm-confirm')).toHaveLength(1);
$$('.ant-modal-confirm-btns > .ant-btn')[0].click();
fireEvent.click($$('.ant-modal-confirm-btns > .ant-btn')[0]);
await waitFakeTimer();
expect($$('.ant-modal-confirm-confirm')).toHaveLength(0);
jest.useRealTimers();
});
// https://github.com/ant-design/ant-design/issues/37461

View File

@@ -186,6 +186,7 @@ describe('Modal.hook', () => {
expect(cancelCount).toEqual(1); // click cancel btn, trigger onCancel
fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]);
fireEvent.mouseDown(document.body.querySelectorAll('.ant-modal-wrap')[0]);
fireEvent.click(document.body.querySelectorAll('.ant-modal-wrap')[0]);
expect(cancelCount).toEqual(2); // click modal wrapper, trigger onCancel
});
@@ -224,6 +225,7 @@ describe('Modal.hook', () => {
expect(cancelCount).toEqual(1); // click cancel btn, trigger onCancel
fireEvent.click(container.querySelectorAll('.open-hook-modal-btn')[0]);
fireEvent.mouseDown(document.body.querySelectorAll('.ant-modal-wrap')[0]);
fireEvent.click(document.body.querySelectorAll('.ant-modal-wrap')[0]);
expect(cancelCount).toEqual(2); // click modal wrapper, trigger onCancel
});
@@ -360,6 +362,7 @@ describe('Modal.hook', () => {
expect(document.body.querySelectorAll('.ant-modal-confirm-confirm')).toHaveLength(1);
// Click mask to close
fireEvent.mouseDown(document.body.querySelectorAll('.ant-modal-wrap')[0]);
fireEvent.click(document.body.querySelectorAll('.ant-modal-wrap')[0]);
await waitFakeTimer();

View File

@@ -108,7 +108,7 @@ const genBaseStyle: GenerateStyle<PopoverToken> = (token) => {
userSelect: 'text',
// When use `autoArrow`, origin will follow the arrow position
[varName('valid-offset-x')]: varRef('arrow-offset-horizontal', 'var(--arrow-x)'),
[varName('valid-offset-x')]: varRef('arrow-offset-x', 'var(--arrow-x)'),
transformOrigin: [
varRef('valid-offset-x', FALL_BACK_ORIGIN),
`var(--arrow-y, ${FALL_BACK_ORIGIN})`,

View File

@@ -106,7 +106,7 @@ const getArrowStyle = <
},
'&-placement-topLeft': {
[varName('arrow-offset-horizontal')]: arrowOffsetHorizontal,
[varName('arrow-offset-x')]: arrowOffsetHorizontal,
[`> ${componentCls}-arrow`]: {
left: {
@@ -117,7 +117,7 @@ const getArrowStyle = <
},
'&-placement-topRight': {
[varName('arrow-offset-horizontal')]: `calc(100% - ${unit(arrowOffsetHorizontal)})`,
[varName('arrow-offset-x')]: `calc(100% - ${unit(arrowOffsetHorizontal)})`,
[`> ${componentCls}-arrow`]: {
right: {
@@ -148,7 +148,7 @@ const getArrowStyle = <
},
'&-placement-bottomLeft': {
[varName('arrow-offset-horizontal')]: arrowOffsetHorizontal,
[varName('arrow-offset-x')]: arrowOffsetHorizontal,
[`> ${componentCls}-arrow`]: {
left: {
@@ -159,7 +159,7 @@ const getArrowStyle = <
},
'&-placement-bottomRight': {
[varName('arrow-offset-horizontal')]: `calc(100% - ${unit(arrowOffsetHorizontal)})`,
[varName('arrow-offset-x')]: `calc(100% - ${unit(arrowOffsetHorizontal)})`,
[`> ${componentCls}-arrow`]: {
right: {

View File

@@ -2,6 +2,7 @@ import { generate } from '@ant-design/colors';
import type { DerivativeFunc } from '@ant-design/cssinjs';
import type { MapToken, PresetColorType, SeedToken } from '../../interface';
import { PresetColors } from '../../interface/presetColors';
import defaultAlgorithm from '../default';
import { defaultPresetColors } from '../seed';
import genColorMapToken from '../shared/genColorMapToken';
@@ -29,6 +30,19 @@ const derivative: DerivativeFunc<SeedToken, MapToken> = (token, mapToken) => {
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 {
...mergedMapToken,
@@ -38,6 +52,8 @@ const derivative: DerivativeFunc<SeedToken, MapToken> = (token, mapToken) => {
// Colors
...colorMapToken,
...presetColorHoverActiveTokens,
// Customize selected item background color
// https://github.com/ant-design/ant-design/issues/30524#issuecomment-871961867
colorPrimaryBg: colorMapToken.colorPrimaryBorder,

View File

@@ -1,6 +1,7 @@
import { FastColor } from '@ant-design/fast-color';
import type { ColorMapToken, SeedToken } from '../../interface';
import { PresetColors } from '../../interface/presetColors';
import type { GenerateColorMap, GenerateNeutralColorMap } from '../ColorMap';
interface PaletteGenerators {
@@ -37,6 +38,16 @@ export default function genColorMapToken(
.mix(new FastColor(errorColors[3]), 50)
.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 {
...neutralColors,
@@ -101,6 +112,8 @@ export default function genColorMapToken(
colorLink: linkColors[6],
colorLinkActive: linkColors[7],
...presetColorTokens,
colorBgMask: new FastColor('#000').setA(0.45).toRgbString(),
colorWhite: '#fff',
};

View File

@@ -83,7 +83,7 @@ const genTooltipStyle: GenerateStyle<TooltipToken> = (token) => {
const sharedTransformOrigin: CSSObject = {
// When use `autoArrow`, origin will follow the arrow position
[varName('valid-offset-x')]: varRef('arrow-offset-horizontal', 'var(--arrow-x)'),
[varName('valid-offset-x')]: varRef('arrow-offset-x', 'var(--arrow-x)'),
transformOrigin: [
varRef('valid-offset-x', FALL_BACK_ORIGIN),
`var(--arrow-y, ${FALL_BACK_ORIGIN})`,

View File

@@ -117,7 +117,7 @@
"@rc-component/checkbox": "~2.0.0",
"@rc-component/collapse": "~1.2.0",
"@rc-component/color-picker": "~3.1.0",
"@rc-component/dialog": "~1.8.2",
"@rc-component/dialog": "~1.8.3",
"@rc-component/drawer": "~1.4.1",
"@rc-component/dropdown": "~1.0.2",
"@rc-component/form": "~1.6.2",
@@ -149,7 +149,7 @@
"@rc-component/tree-select": "~1.8.0",
"@rc-component/trigger": "^3.9.0",
"@rc-component/upload": "~1.1.0",
"@rc-component/util": "^1.8.1",
"@rc-component/util": "^1.8.2",
"clsx": "^2.1.1",
"dayjs": "^1.11.11",
"scroll-into-view-if-needed": "^3.1.0",