Merge branch 'master' into feature-merge-master

This commit is contained in:
yoyo837
2025-12-03 17:31:33 +08:00
18 changed files with 253 additions and 63 deletions

View File

@@ -157,21 +157,11 @@ const RoutesPlugin = async (api: IApi) => {
api.modifyRoutes((routes) => {
// TODO: append extra routes, such as home, changelog, form-v3
/**
* **important!** Make sure that the `id` and `path` are consistent.
* see: https://github.com/ant-design/ant-design/issues/55960
*/
const extraRoutesList: IRoute[] = [
{
id: 'changelog-cn',
path: 'changelog-cn',
absPath: '/changelog-cn',
parentId: 'DocLayout',
file: resolve('../../CHANGELOG.zh-CN.md'),
},
{
id: 'components-changelog-cn',
path: 'components/changelog-cn',
absPath: '/changelog-cn',
parentId: 'DocLayout',
file: resolve('../../CHANGELOG.zh-CN.md'),
},
{
id: 'changelog',
path: 'changelog',
@@ -180,12 +170,26 @@ const RoutesPlugin = async (api: IApi) => {
file: resolve('../../CHANGELOG.en-US.md'),
},
{
id: 'components-changelog',
id: 'changelog-cn',
path: 'changelog-cn',
absPath: '/changelog-cn',
parentId: 'DocLayout',
file: resolve('../../CHANGELOG.zh-CN.md'),
},
{
id: 'components/changelog',
path: 'components/changelog',
absPath: '/changelog',
absPath: '/components/changelog',
parentId: 'DocLayout',
file: resolve('../../CHANGELOG.en-US.md'),
},
{
id: 'components/changelog-cn',
path: 'components/changelog-cn',
absPath: '/components/changelog-cn',
parentId: 'DocLayout',
file: resolve('../../CHANGELOG.zh-CN.md'),
},
];
extraRoutesList.forEach((itemRoute) => {

View File

@@ -25,9 +25,9 @@ jobs:
with:
trigger: tag
changelogs: 'CHANGELOG.en-US.md, CHANGELOG.zh-CN.md'
branch: 'master, 4.x-stable'
tag: '5*, 4*'
latest: '5*'
branch: 'master, 5.x-stable, 4.x-stable'
tag: '6*, 5*, 4*'
latest: '6*'
dingding-token: ${{ secrets.DINGDING_BOT_TOKEN }} ${{ secrets.DINGDING_BOT_COLLABORATOR_TOKEN }} ${{ secrets.DINGDING_BOT_MAINTAINER_TOKEN }}
dingding-msg: CHANGELOG.zh-CN.md
msg-title: '# Ant Design {{v}} 发布日志'
@@ -41,9 +41,9 @@ jobs:
with:
trigger: tag
changelogs: 'CHANGELOG.en-US.md, CHANGELOG.zh-CN.md'
branch: 'master, 4.x-stable'
tag: '5*, 4*'
latest: '5*'
branch: 'master, 5.x-stable, 4.x-stable'
tag: '6*, 5*, 4*'
latest: '6*'
dingding-token: ${{ secrets.DINGDING_BOT_BIGFISH_TOKEN }} ${{ secrets.DINGDING_BOT_BIGFISH_2_TOKEN }} ${{ secrets.DINGDING_BOT_YUNFENGDIE_TOKEN }}
dingding-msg: CHANGELOG.zh-CN.md
dingding-delay-minute: 10

View File

@@ -25,7 +25,7 @@ tag: vVERSION
- Input
- 🐞 Fix Input `colorText` token does not work with `filled` variant without affix. [#56019](https://github.com/ant-design/ant-design/pull/56019) [@ug-hero](https://github.com/ug-hero)
- 🐞 Fix Input.OTP empty slots can be skipped when typing. [#56001](https://github.com/ant-design/ant-design/pull/56001) [@aojunhao123](https://github.com/aojunhao123)
- 🐞 Fix Anchor scroll problem when click same link rapidly. [#55814](https://github.com/ant-design/ant-design/pull/55814) [@tuzixiangs](https://github.com/tuzixiangs) [@tuzixiangs](https://github.com/tuzixiangs)
- 🐞 Fix Anchor scroll problem when click same link rapidly. [#55814](https://github.com/ant-design/ant-design/pull/55814) [@tuzixiangs](https://github.com/tuzixiangs)
- 🐞 Fix Button hover text color in `solid` variant. [#55825](https://github.com/ant-design/ant-design/pull/55825) [@andriib-ship-it](https://github.com/andriib-ship-it)
- 🐞 Fix Cascader page scroll to top on first open with defaultValue. [#55890](https://github.com/ant-design/ant-design/pull/55890) [@tuzixiangs](https://github.com/tuzixiangs)
- 🐞 Fix DatePicker `borderRadiusSM` and `borderRadiusLG` token not working bug. [#56018](https://github.com/ant-design/ant-design/pull/56018) [@ug-hero](https://github.com/ug-hero)
@@ -233,6 +233,7 @@ tag: vVERSION
- Notification
- 🛠 Notification support `closable` to take `onClose` & `closeIcon` into it. [#54645](https://github.com/ant-design/ant-design/pull/54645) [@EmilyyyLiu](https://github.com/EmilyyyLiu)
- 🆕 Notification support custom progress bar color. [#52964](https://github.com/ant-design/ant-design/pull/52964) [@yellowryan](https://github.com/yellowryan)
- 🆕 Notification adds new `title` property to replace the `message` property, and deprecates `message`. [#52759](https://github.com/ant-design/ant-design/pull/52759) [@thinkasany](https://github.com/thinkasany)
- Image
- 🆕 Image `cover` support placement. [#54492](https://github.com/ant-design/ant-design/pull/54492) [@kiner-tang](https://github.com/kiner-tang)
- 🛠 Image remove default cover icon & text (Still can use `cover` to config). [#54379](https://github.com/ant-design/ant-design/pull/54379) [@765477020](https://github.com/765477020)

View File

@@ -25,7 +25,7 @@ tag: vVERSION
- Input
- 🐞 修复 Input `colorText` token 在无前后缀的 `filled` 变体下不工作的问题。[#56019](https://github.com/ant-design/ant-design/pull/56019) [@ug-hero](https://github.com/ug-hero)
- 🐞 修复 Input.OTP 在输入时可跳过空位的问题。[#56001](https://github.com/ant-design/ant-design/pull/56001) [@aojunhao123](https://github.com/aojunhao123)
- 🐞 修复 Anchor 快速点击同一链接时的滚动问题。[#55814](https://github.com/ant-design/ant-design/pull/55814) [@tuzixiangs](https://github.com/tuzixiangs) [@tuzixiangs](https://github.com/tuzixiangs)
- 🐞 修复 Anchor 快速点击同一链接时的滚动问题。[#55814](https://github.com/ant-design/ant-design/pull/55814) [@tuzixiangs](https://github.com/tuzixiangs)
- 🐞 修复 Button 在 `solid` 变体下悬浮态的文字颜色。[#55825](https://github.com/ant-design/ant-design/pull/55825) [@andriib-ship-it](https://github.com/andriib-ship-it)
- 🐞 修复 Cascader 使用 defaultValue 时首次打开会滚动到页面顶部的问题。[#55890](https://github.com/ant-design/ant-design/pull/55890) [@tuzixiangs](https://github.com/tuzixiangs)
- 🐞 修复 DatePicker `borderRadiusSM``borderRadiusLG` token 未生效问题。[#56018](https://github.com/ant-design/ant-design/pull/56018) [@ug-hero](https://github.com/ug-hero)
@@ -233,6 +233,7 @@ tag: vVERSION
- Notification
- 🛠 Notification 提供 `closable` 属性将 `onClose``closeIcon` 收敛至其中。[#54645](https://github.com/ant-design/ant-design/pull/54645) [@EmilyyyLiu](https://github.com/EmilyyyLiu)
- 🆕 Notification 支持自定义进度条颜色。[#52964](https://github.com/ant-design/ant-design/pull/52964) [@yellowryan](https://github.com/yellowryan)
- 🆕 Notification 新增 `title` 属性用以替代 `message` 属性,同时废弃 `message` 属性。[#52759](https://github.com/ant-design/ant-design/pull/52759) [@thinkasany](https://github.com/thinkasany)
- Image
- 🆕 Image 的预览遮罩 `cover` 支持设置遮罩位置。[#54492](https://github.com/ant-design/ant-design/pull/54492) [@kiner-tang](https://github.com/kiner-tang)
- 🛠 Image 移除默认的查看图标和文案(仍然可以通过 `cover` 配置)。[#54379](https://github.com/ant-design/ant-design/pull/54379) [@765477020](https://github.com/765477020)

View File

@@ -916,6 +916,58 @@ exports[`renders components/button/demo/debug-color-variant.tsx extend context c
</span>
</button>
</div>
<div
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
type="button"
>
<span>
Primary
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-primary ant-btn-variant-solid"
type="button"
>
<span>
Solid primary
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-dangerous ant-btn-variant-solid"
type="button"
>
<span>
Solid danger
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Default
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Outlined
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-dashed ant-btn-color-default ant-btn-variant-dashed"
type="button"
>
<span>
Dashed
</span>
</button>
</div>
</div>
`;

View File

@@ -900,6 +900,58 @@ exports[`renders components/button/demo/debug-color-variant.tsx correctly 1`] =
</span>
</button>
</div>
<div
class="ant-flex css-var-test-id ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
type="button"
>
<span>
Primary
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-primary ant-btn-variant-solid"
type="button"
>
<span>
Solid primary
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-dangerous ant-btn-variant-solid"
type="button"
>
<span>
Solid danger
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Default
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Outlined
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-dashed ant-btn-color-default ant-btn-variant-dashed"
type="button"
>
<span>
Dashed
</span>
</button>
</div>
</div>
`;

View File

@@ -1,5 +1,6 @@
import React from 'react';
import { Button, ConfigProvider, Flex } from 'antd';
import type { ThemeConfig } from 'antd';
import { createStyles } from 'antd-style';
const useSpecStyle = createStyles(({ css }) => ({
@@ -46,6 +47,17 @@ const useOriginalClsStyle = createStyles(({ css }) => ({
`,
}));
const theme: ThemeConfig = {
components: {
Button: {
defaultHoverBg: 'orange',
defaultActiveBg: 'blue',
primaryColor: 'pink',
dangerColor: 'green',
},
},
};
const App: React.FC = () => {
const { styles: specStyle } = useSpecStyle();
const { styles: originalClsStyle } = useOriginalClsStyle();
@@ -87,6 +99,24 @@ const App: React.FC = () => {
<Button type="text">Text Button</Button>
<Button type="link">Link Button</Button>
</Flex>
{/* theme config */}
<Flex gap="small" wrap>
<ConfigProvider theme={theme}>
<Button type="primary" variant="solid">
Primary
</Button>
<Button color="primary" variant="solid">
Solid primary
</Button>
<Button color="danger" variant="solid">
Solid danger
</Button>
<Button type="default">Default</Button>
<Button variant="outlined">Outlined</Button>
<Button type="dashed">Dashed</Button>
</ConfigProvider>
</Flex>
</Flex>
);
};

View File

@@ -173,6 +173,12 @@ const genVariantStyle: GenerateStyle<ButtonToken> = (token) => {
[getCssVar('color-light-active')]: token.colorPrimaryBorder,
[getCssVar('shadow')]: token.primaryShadow,
[`&${componentCls}-variant-solid`]: {
[getCssVar('text-color')]: token.primaryColor,
[getCssVar('text-color-hover')]: `var(${getCssVar('text-color')})`,
[getCssVar('text-color-active')]: `var(${getCssVar('text-color')})`,
},
},
// >>>>> Danger
@@ -185,6 +191,12 @@ const genVariantStyle: GenerateStyle<ButtonToken> = (token) => {
[getCssVar('color-light-active')]: token.colorErrorBgActive,
[getCssVar('shadow')]: token.dangerShadow,
[`&${componentCls}-variant-solid`]: {
[getCssVar('text-color')]: token.dangerColor,
[getCssVar('text-color-hover')]: `var(${getCssVar('text-color')})`,
[getCssVar('text-color-active')]: `var(${getCssVar('text-color')})`,
},
},
// >>>>> Default
@@ -218,6 +230,11 @@ const genVariantStyle: GenerateStyle<ButtonToken> = (token) => {
[getCssVar('text-color-active')]: `var(${getCssVar('text-color')})`,
},
[`&${componentCls}-variant-outlined, &${componentCls}-variant-dashed`]: {
[getCssVar('bg-color-hover')]: token.defaultHoverBg,
[getCssVar('bg-color-active')]: token.defaultActiveBg,
},
[`&${componentCls}-background-ghost`]: {
[`&${componentCls}-variant-outlined, &${componentCls}-variant-dashed`]: {
[getCssVar('text-color')]: token.defaultGhostColor,

View File

@@ -103,18 +103,21 @@ const MenuItem: GenericComponent = (props) => {
},
className,
)}
style={firstLevel ? styles.item : styles.subMenu.item}
style={{
...(firstLevel ? styles.item : styles.subMenu.item),
...props.style,
}}
title={typeof title === 'string' ? title : undefined}
>
{cloneElement(icon, (oriProps) => ({
className: clsx(
oriProps.className,
`${prefixCls}-item-icon`,
firstLevel ? classNames.itemIcon : classNames.subMenu.itemIcon,
oriProps.className,
),
style: {
...oriProps.style,
...(firstLevel ? styles.itemIcon : styles.subMenu.itemIcon),
...oriProps.style,
},
}))}
{renderItemChildren(isInlineCollapsed)}

View File

@@ -133,4 +133,40 @@ describe('Menu.Semantic', () => {
backgroundColor: 'rgb(255, 255, 255)',
});
});
// https://github.com/ant-design/ant-design/issues/56017
it('support MenuItem style', () => {
const items = [
{ label: 'One', key: 'one', style: { color: 'red' } },
{
label: 'Two',
key: 'two',
children: [
{ label: 'Two-One', key: 'two-one', style: { color: 'green' } },
{ label: 'Two-Two', key: 'two-two', style: { color: 'blue' } },
],
},
];
const { getAllByRole } = render(<Menu mode="inline" items={items} openKeys={['two']} />);
const menuItems = getAllByRole('menuitem');
expect(menuItems).toBeTruthy();
// { [label: color] }
const expected: any = {
One: 'rgb(255, 0, 0)',
'Two-One': 'rgb(0, 128, 0)',
'Two-Two': 'rgb(0, 0, 255)',
};
menuItems.forEach((item) => {
const labelNode = item.querySelector('.ant-menu-title-content');
const label = labelNode?.textContent?.trim();
if (label && expected[label]) {
expect(item).toHaveStyle({ color: expected[label] });
}
});
});
});

View File

@@ -1,7 +1,7 @@
## zh-CN
第一个对话框
调试使用
## en-US
Basic modal.
Demo for debugging.

View File

@@ -28,7 +28,7 @@ Additionally, if you need to show a simple confirmation dialog, you can use [`Ap
<code src="./demo/locale.tsx">Internationalization</code>
<code src="./demo/manual.tsx">Manual to update destroy</code>
<code src="./demo/position.tsx">To customize the position of modal</code>
<code src="./demo/dark.tsx" debug>Dark Bg</code>
<code src="./demo/dark.tsx" debug>Demo for debugging</code>
<code src="./demo/button-props.tsx">Customize footer buttons props</code>
<code src="./demo/modal-render.tsx">Custom modal content render</code>
<code src="./demo/width.tsx">To customize the width of modal</code>

View File

@@ -29,7 +29,7 @@ demo:
<code src="./demo/locale.tsx">国际化</code>
<code src="./demo/manual.tsx">手动更新和移除</code>
<code src="./demo/position.tsx">自定义位置</code>
<code src="./demo/dark.tsx" debug>暗背景</code>
<code src="./demo/dark.tsx" debug>调试使用</code>
<code src="./demo/button-props.tsx">自定义页脚按钮属性</code>
<code src="./demo/modal-render.tsx">自定义渲染对话框</code>
<code src="./demo/width.tsx">自定义模态的宽度</code>

View File

@@ -63,8 +63,8 @@ The properties of config are as follows:
| pauseOnHover | keep the timer running or not on hover | boolean | true | 5.18.0 |
| icon | Customized icon | ReactNode | - | - |
| key | The unique identifier of the Notification | string | - | - |
| title | The title of notification box (required) | ReactNode | - | 6.0.0 |
| ~~message~~ | The title of notification box (required), please use `title` instead | ReactNode | - | - |
| title | The title of notification box | ReactNode | - | 6.0.0 |
| ~~message~~ | The title of notification box (deprecated), please use `title` instead | ReactNode | - | - |
| placement | Position of Notification, can be one of `top` \| `topLeft` \| `topRight` \| `bottom` \| `bottomLeft` \| `bottomRight` | string | `topRight` | - |
| role | The semantics of notification content recognized by screen readers. The default value is `alert`. When set as the default value, the screen reader will promptly interrupt any ongoing content reading and prioritize the notification content for immediate attention. | `alert \| status` | `alert` | 5.6.0 |
| style | Customized inline style | [CSSProperties](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e434515761b36830c3e58a970abf5186f005adac/types/react/index.d.ts#L794) | - | - |

View File

@@ -65,8 +65,8 @@ config 参数如下:
| pauseOnHover | 悬停时是否暂停计时器 | boolean | true | 5.18.0 |
| icon | 自定义图标 | ReactNode | - | - |
| key | 当前通知唯一标志 | string | - | - |
| title | 通知提醒标题,必选 | ReactNode | - | 6.0.0 |
| ~~message~~ | 通知提醒标题,必选, 请使用 `title` 替换 | ReactNode | - | - |
| title | 通知提醒标题 | ReactNode | - | 6.0.0 |
| ~~message~~ | 通知提醒标题,请使用 `title` 替换 | ReactNode | - | - |
| placement | 弹出位置,可选 `top` \| `topLeft` \| `topRight` \| `bottom` \| `bottomLeft` \| `bottomRight` | string | `topRight` | - |
| role | 供屏幕阅读器识别的通知内容语义,默认为 `alert`。此情况下屏幕阅读器会立即打断当前正在阅读的其他内容,转而阅读通知内容 | `alert \| status` | `alert` | 5.6.0 |
| style | 自定义内联样式 | [CSSProperties](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e434515761b36830c3e58a970abf5186f005adac/types/react/index.d.ts#L794) | - | - |

View File

@@ -28,7 +28,7 @@ export type NotificationStylesType = SemanticStylesType<ArgsProps, NotificationS
export interface ArgsProps {
/** @deprecated Please use `title` instead */
message?: React.ReactNode;
title: React.ReactNode;
title?: React.ReactNode;
description?: React.ReactNode;
/** @deprecated Please use `actions` instead */
btn?: React.ReactNode;

View File

@@ -139,7 +139,7 @@
"@rc-component/rate": "~1.0.1",
"@rc-component/resize-observer": "^1.0.1",
"@rc-component/segmented": "~1.2.3",
"@rc-component/select": "~1.3.0",
"@rc-component/select": "~1.3.1",
"@rc-component/slider": "~1.0.1",
"@rc-component/steps": "~1.2.2",
"@rc-component/switch": "~1.0.3",

View File

@@ -1,21 +1,18 @@
/**
* 本地运行视觉回归测试
*/
import { spawnSync } from 'child_process';
import path from 'path';
import fs from 'fs-extra';
import simpleGit from 'simple-git';
import envPaths from 'env-paths';
import fg from 'fast-glob';
import minimist from 'minimist';
import { Readable } from 'stream';
import { finished } from 'stream/promises';
import { extract } from 'tar';
import { Octokit } from '@octokit/rest';
import { spawnSync } from 'child_process';
import difference from 'lodash/difference';
import open from 'open';
import { checkbox, confirm, input, select } from '@inquirer/prompts';
import { Octokit } from '@octokit/rest';
import envPaths from 'env-paths';
import fg from 'fast-glob';
import fs from 'fs-extra';
import difference from 'lodash/difference';
import minimist from 'minimist';
import open from 'open';
import { getUserAgent, resolveCommand } from 'package-manager-detector';
import simpleGit from 'simple-git';
import { extract } from 'tar';
const ROOT = path.resolve(__dirname, '../../');
// ==================== 环境变量 ====================
@@ -37,20 +34,17 @@ fs.ensureDirSync(STORE_PATH);
const git = simpleGit(ROOT);
const octokit = new Octokit({ auth: GITHUB_TOKEN });
const packageManager = getUserAgent();
const components = fg.sync('components/*/index.ts[x]', { cwd: ROOT }).reduce((acc, file) => {
const basePath = path.dirname(file);
if (
[
fs.existsSync(path.join(basePath, 'index.en-US.md')),
fs.existsSync(path.join(basePath, 'demo')),
fs.existsSync(path.join(basePath, '__tests__')),
].every(Boolean)
) {
acc.push(basePath);
}
return acc;
}, [] as string[]);
const components = fg
.sync('components/*/index.ts[x]', { cwd: ROOT })
.reduce<string[]>((acc, file) => {
const basePath = path.dirname(file);
const requiredFiles = ['index.en-US.md', 'demo', '__tests__'];
if (requiredFiles.every((item) => fs.existsSync(path.join(basePath, item)))) {
acc.push(basePath);
}
return acc;
}, []);
// ==================== scripts ====================
const imagesTestsScript = 'test:image';