chore: auto merge branches (#56199)

chore: merge master into feature
This commit is contained in:
github-actions[bot]
2025-12-12 20:48:26 +00:00
committed by GitHub
35 changed files with 393 additions and 411 deletions

View File

@@ -80,13 +80,13 @@ const Block: React.FC<BlockProps> = ({
align="center"
>
{!singleOnly && (
<Segmented
<Segmented<'single' | 'multiple'>
options={[
{ label: 'Single', value: 'single' },
{ label: 'Multiple', value: 'multiple' },
]}
value={mode}
onChange={(value) => onModeChange(value as 'single' | 'multiple')}
onChange={onModeChange}
/>
)}
<Component

View File

@@ -22,7 +22,7 @@ jobs:
- uses: utooland/setup-utoo@v1
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
path: ~tmpProj/yarn.lock
key: primes-${{ runner.os }}-${{ github.run_id }}
@@ -40,7 +40,7 @@ jobs:
- name: Download success lock file as `success.lock`
if: ${{ failure() }}
uses: actions/cache/restore@v4
uses: actions/cache/restore@v5
with:
path: ~tmpProj/yarn.lock
key: primes-${{ runner.os }}-${{ github.run_id }}

View File

@@ -96,7 +96,7 @@ jobs:
- run: ut
- name: restore cache from dist
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: dist
key: dist-${{ github.sha }}
@@ -146,13 +146,13 @@ jobs:
- run: ut
- name: cache lib
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: lib
key: lib-${{ github.sha }}
- name: cache es
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: es
key: es-${{ github.sha }}
@@ -161,7 +161,7 @@ jobs:
run: ut compile
- name: cache dist
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: dist
key: dist-${{ github.sha }}
@@ -213,7 +213,7 @@ jobs:
- name: restore cache from ${{ matrix.module }}
# lib only run in master branch not in pull request
if: ${{ github.event_name != 'pull_request' || matrix.module != 'lib' }}
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ${{ matrix.module }}
key: ${{ matrix.module }}-${{ github.sha }}

View File

@@ -99,7 +99,7 @@ jobs:
- run: ut
- name: restore cache from dist
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: dist
key: dist-${{ github.sha }}
@@ -151,13 +151,13 @@ jobs:
- run: ut
- name: cache lib
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: lib
key: lib-${{ github.sha }}
- name: cache es
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: es
key: es-${{ github.sha }}
@@ -166,7 +166,7 @@ jobs:
run: ut compile
- name: cache dist
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: dist
key: dist-${{ github.sha }}
@@ -218,7 +218,7 @@ jobs:
- name: restore cache from ${{ matrix.module }}
# lib only run in master branch not in pull request
if: ${{ github.event_name != 'pull_request' || matrix.module != 'lib' }}
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ${{ matrix.module }}
key: ${{ matrix.module }}-${{ github.sha }}

View File

@@ -1,7 +1,7 @@
## zh-CN
使用 `dropdownRender` 对下拉菜单进行自由扩展。
使用 `popupRender` 对下拉菜单进行自由扩展。
## en-US
Customize the dropdown menu via `dropdownRender`.
Customize the dropdown menu via `popupRender`.

View File

@@ -60,7 +60,6 @@ Other Property ref [&lt;img>](https://developer.mozilla.org/en-US/docs/Web/HTML/
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| actionsRender | Custom toolbar render | (originalNode: React.ReactElement, info: ToolbarRenderInfoType) => React.ReactNode | - | |
| classNames | Custom semantic structure class names | [Record<SemanticDOM, string>](#semantic-dom) | - | |
| closeIcon | Custom close icon | React.ReactNode | - | |
| cover | Custom preview mask | React.ReactNode \| [CoverConfig](#coverconfig) | - | CoverConfig support after v6.0 |
| ~~destroyOnClose~~ | Destroy child elements on preview close (removed, no longer supported) | boolean | false | |
@@ -87,6 +86,7 @@ Other Property ref [&lt;img>](https://developer.mozilla.org/en-US/docs/Web/HTML/
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | |
| fallback | Fallback URL for load error | string | - | |
| items | Array of preview items | string[] \| { src: string, crossOrigin: string, ... }[] | - | |
| preview | Preview configuration; disable by setting to false | boolean \| [PreviewGroupType](#previewgrouptype) | true | |
@@ -96,7 +96,6 @@ Other Property ref [&lt;img>](https://developer.mozilla.org/en-US/docs/Web/HTML/
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| actionsRender | Custom toolbar render | (originalNode: React.ReactElement, info: ToolbarRenderInfoType) => React.ReactNode | - | |
| classNames | Custom preview class names object | [Record<SemanticDOM, string>](#semantic-dom) | - | |
| closeIcon | Custom close icon | React.ReactNode | - | |
| countRender | Custom preview count render | (current: number, total: number) => React.ReactNode | - | |
| current | Index of the current preview image | number | - | |

View File

@@ -61,7 +61,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LVQ3R5JjjJEAAA
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| actionsRender | 自定义工具栏渲染 | (originalNode: React.ReactElement, info: ToolbarRenderInfoType) => React.ReactNode | - | |
| classNames | 自定义语义化结构类名 | [Record<SemanticDOM, string>](#semantic-dom) | - | |
| closeIcon | 自定义关闭 Icon | React.ReactNode | - | |
| cover | 自定义预览遮罩 | React.ReactNode \| [CoverConfig](#coverconfig) | - | CoverConfig v6.0 开始支持 |
| ~~destroyOnClose~~ | 关闭预览时销毁子元素,已移除,不再支持 | boolean | false | |
@@ -88,6 +87,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LVQ3R5JjjJEAAA
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| classNames | 用于自定义组件内部各语义化结构的 class支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | |
| fallback | 加载失败容错地址 | string | - | |
| items | 预览数组 | string[] \| { src: string, crossOrigin: string, ... }[] | - | |
| preview | 预览参数,为 `false` 时禁用 | boolean \| [PreviewGroupType](#previewgrouptype) | true | |
@@ -97,7 +97,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LVQ3R5JjjJEAAA
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| actionsRender | 自定义工具栏渲染 | (originalNode: React.ReactElement, info: ToolbarRenderInfoType) => React.ReactNode | - | |
| classNames | 自定义预览类名对象 | [Record<SemanticDOM, string>](#semantic-dom) | - | |
| closeIcon | 自定义关闭 Icon | React.ReactNode | - | |
| countRender | 自定义预览计数内容 | (current: number, total: number) => React.ReactNode | - | |
| current | 当前预览图的 index | number | - | |

View File

@@ -667,7 +667,10 @@ export default genStyleHooks(
// =====================================================
// == Space Compact ==
// =====================================================
genCompactItemStyle(inputToken),
genCompactItemStyle(inputToken, {
focus: true,
focusElCls: `${inputToken.componentCls}-affix-wrapper-focused`,
}),
];
},
initComponentToken,

View File

@@ -94,10 +94,7 @@ const Block: React.FC<
return (
<Flex vertical gap="middle" ref={divRef} align="center">
<Segmented<ModeType>
options={['horizontal', 'vertical', 'inline']}
onChange={(value) => setMode(value)}
/>
<Segmented<ModeType> options={['horizontal', 'vertical', 'inline']} onChange={setMode} />
<div style={{ height: 360 }}>
<Menu
onClick={onClick}

View File

@@ -14,63 +14,43 @@ exports[`renders components/notification/demo/basic.tsx extend context correctly
exports[`renders components/notification/demo/basic.tsx extend context correctly 2`] = `[]`;
exports[`renders components/notification/demo/component-token.tsx extend context correctly 1`] = `
Array [
<h4>
Custom Theme (Enhanced Colors)
</h4>,
<div
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
<div
class="ant-flex css-var-test-id ant-flex-wrap-wrap"
style="gap: 8px;"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-green ant-btn-variant-outlined"
type="button"
>
<div
class="ant-space-item"
>
<button
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
type="button"
>
<span>
Custom Success
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Custom Info
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Custom Warning
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-dangerous ant-btn-color-dangerous ant-btn-variant-outlined"
type="button"
>
<span>
Custom Error
</span>
</button>
</div>
</div>,
]
<span>
Success
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-blue ant-btn-variant-outlined"
type="button"
>
<span>
Info
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-yellow ant-btn-variant-outlined"
type="button"
>
<span>
Warning
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-red ant-btn-variant-outlined"
type="button"
>
<span>
Error
</span>
</button>
</div>
`;
exports[`renders components/notification/demo/component-token.tsx extend context correctly 2`] = `[]`;
@@ -860,56 +840,41 @@ exports[`renders components/notification/demo/with-btn.tsx extend context correc
exports[`renders components/notification/demo/with-icon.tsx extend context correctly 1`] = `
<div
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
class="ant-flex css-var-test-id ant-flex-wrap-wrap"
style="gap: 8px;"
>
<div
class="ant-space-item"
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-green ant-btn-variant-outlined"
type="button"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Success
</span>
</button>
</div>
<div
class="ant-space-item"
<span>
Success
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-blue ant-btn-variant-outlined"
type="button"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Info
</span>
</button>
</div>
<div
class="ant-space-item"
<span>
Info
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-yellow ant-btn-variant-outlined"
type="button"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Warning
</span>
</button>
</div>
<div
class="ant-space-item"
<span>
Warning
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-red ant-btn-variant-outlined"
type="button"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Error
</span>
</button>
</div>
<span>
Error
</span>
</button>
</div>
`;

View File

@@ -12,63 +12,43 @@ exports[`renders components/notification/demo/basic.tsx correctly 1`] = `
`;
exports[`renders components/notification/demo/component-token.tsx correctly 1`] = `
Array [
<h4>
Custom Theme (Enhanced Colors)
</h4>,
<div
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
<div
class="ant-flex css-var-test-id ant-flex-wrap-wrap"
style="gap:8px"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-green ant-btn-variant-outlined"
type="button"
>
<div
class="ant-space-item"
>
<button
class="ant-btn css-var-test-id ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
type="button"
>
<span>
Custom Success
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Custom Info
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Custom Warning
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-dangerous ant-btn-color-dangerous ant-btn-variant-outlined"
type="button"
>
<span>
Custom Error
</span>
</button>
</div>
</div>,
]
<span>
Success
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-blue ant-btn-variant-outlined"
type="button"
>
<span>
Info
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-yellow ant-btn-variant-outlined"
type="button"
>
<span>
Warning
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-red ant-btn-variant-outlined"
type="button"
>
<span>
Error
</span>
</button>
</div>
`;
exports[`renders components/notification/demo/custom-icon.tsx correctly 1`] = `
@@ -832,55 +812,40 @@ exports[`renders components/notification/demo/with-btn.tsx correctly 1`] = `
exports[`renders components/notification/demo/with-icon.tsx correctly 1`] = `
<div
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
class="ant-flex css-var-test-id ant-flex-wrap-wrap"
style="gap:8px"
>
<div
class="ant-space-item"
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-green ant-btn-variant-outlined"
type="button"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Success
</span>
</button>
</div>
<div
class="ant-space-item"
<span>
Success
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-blue ant-btn-variant-outlined"
type="button"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Info
</span>
</button>
</div>
<div
class="ant-space-item"
<span>
Info
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-yellow ant-btn-variant-outlined"
type="button"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Warning
</span>
</button>
</div>
<div
class="ant-space-item"
<span>
Warning
</span>
</button>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-red ant-btn-variant-outlined"
type="button"
>
<button
class="ant-btn css-var-test-id ant-btn-default ant-btn-color-default ant-btn-variant-outlined"
type="button"
>
<span>
Error
</span>
</button>
</div>
<span>
Error
</span>
</button>
</div>
`;

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { Button, ConfigProvider, notification, Space } from 'antd';
import { Button, ConfigProvider, Flex, notification } from 'antd';
type NotificationType = 'success' | 'info' | 'warning' | 'error';
@@ -16,17 +16,28 @@ const CustomThemeDemo: React.FC = () => {
return (
<>
<h4>Custom Theme (Enhanced Colors)</h4>
<Space>
<Button type="primary" onClick={() => openNotificationWithIcon('success')}>
Custom Success
<Flex gap={8} wrap="wrap">
<Button
color="green"
variant="outlined"
onClick={() => openNotificationWithIcon('success')}
>
Success
</Button>
<Button onClick={() => openNotificationWithIcon('info')}>Custom Info</Button>
<Button onClick={() => openNotificationWithIcon('warning')}>Custom Warning</Button>
<Button danger onClick={() => openNotificationWithIcon('error')}>
Custom Error
<Button color="blue" variant="outlined" onClick={() => openNotificationWithIcon('info')}>
Info
</Button>
</Space>
<Button
color="yellow"
variant="outlined"
onClick={() => openNotificationWithIcon('warning')}
>
Warning
</Button>
<Button color="red" variant="outlined" onClick={() => openNotificationWithIcon('error')}>
Error
</Button>
</Flex>
{contextHolder}
</>
);
@@ -37,10 +48,10 @@ const App: React.FC = () => (
theme={{
components: {
Notification: {
colorSuccessBg: '#d9f7be', // Custom light green for success
colorErrorBg: '#ffccc7', // Custom light red for error
colorInfoBg: '#bae0ff', // Custom light blue for info
colorWarningBg: '#ffffb8', // Custom light yellow for warning
colorSuccessBg: 'linear-gradient(30deg, #d9f7be, #f6ffed)',
colorErrorBg: 'linear-gradient(30deg, #ffccc7, #fff1f0)',
colorInfoBg: 'linear-gradient(30deg, #bae0ff, #e6f4ff)',
colorWarningBg: 'linear-gradient(30deg, #ffffb8, #feffe6)',
},
},
}}

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { Button, notification, Space } from 'antd';
import { Button, Flex, notification } from 'antd';
type NotificationType = 'success' | 'info' | 'warning' | 'error';
@@ -17,12 +17,28 @@ const App: React.FC = () => {
return (
<>
{contextHolder}
<Space>
<Button onClick={() => openNotificationWithIcon('success')}>Success</Button>
<Button onClick={() => openNotificationWithIcon('info')}>Info</Button>
<Button onClick={() => openNotificationWithIcon('warning')}>Warning</Button>
<Button onClick={() => openNotificationWithIcon('error')}>Error</Button>
</Space>
<Flex gap={8} wrap="wrap">
<Button
color="green"
variant="outlined"
onClick={() => openNotificationWithIcon('success')}
>
Success
</Button>
<Button color="blue" variant="outlined" onClick={() => openNotificationWithIcon('info')}>
Info
</Button>
<Button
color="yellow"
variant="outlined"
onClick={() => openNotificationWithIcon('warning')}
>
Warning
</Button>
<Button color="red" variant="outlined" onClick={() => openNotificationWithIcon('error')}>
Error
</Button>
</Flex>
</>
);
};

View File

@@ -380,10 +380,13 @@ export const prepareComponentToken = (token: AliasToken) => ({
zIndexPopup: token.zIndexPopupBase + CONTAINER_MAX_OFFSET + 50,
width: 384,
progressBg: `linear-gradient(90deg, ${token.colorPrimaryBorderHover}, ${token.colorPrimary})`,
colorSuccessBg: token.colorSuccessBg,
colorErrorBg: token.colorErrorBg,
colorInfoBg: token.colorInfoBg,
colorWarningBg: token.colorWarningBg,
// Fix notification background color issue
// https://github.com/ant-design/ant-design/issues/55649
// https://github.com/ant-design/ant-design/issues/56055
colorSuccessBg: undefined,
colorErrorBg: undefined,
colorInfoBg: undefined,
colorWarningBg: undefined,
});
export const prepareNotificationToken: (

View File

@@ -42,7 +42,7 @@ const Block: React.FC<Readonly<ProgressProps>> = (props) => {
<Segmented
options={['line', 'steps', 'circle', 'dashboard']}
value={type}
onChange={(value) => setType(value)}
onChange={setType}
/>
<Switch
checked={gradient}

View File

@@ -75,4 +75,27 @@ describe('Result', () => {
const { container: container2 } = render(<Result title="404" icon={false} />);
expect(container2.querySelectorAll('.ant-result-icon')).toHaveLength(0);
});
it('should pass data-* attributes to root element', () => {
const { getByTestId } = render(
<Result status="success" title="Success" data-testid="my-result" data-track-id="track-123" />,
);
const root = getByTestId('my-result');
expect(root).toHaveAttribute('data-track-id', 'track-123');
});
it('should pass aria-* attributes to root element', () => {
const { getByLabelText } = render(
<Result
status="error"
title="Error"
aria-label="操作结果"
aria-describedby="result-description"
/>,
);
const root = getByLabelText('操作结果');
expect(root).toHaveAttribute('aria-describedby', 'result-description');
});
});

View File

@@ -4,7 +4,9 @@ import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
import WarningFilled from '@ant-design/icons/WarningFilled';
import { clsx } from 'clsx';
import pickAttrs from '@rc-component/util/lib/pickAttrs';
import type { HTMLAriaDataAttributes } from '../_util/aria-data-attrs';
import { useMergeSemantic } from '../_util/hooks';
import type { SemanticClassNamesType, SemanticStylesType } from '../_util/hooks';
import { devUseWarning } from '../_util/warning';
@@ -37,7 +39,7 @@ export type ResultClassNamesType = SemanticClassNamesType<ResultProps, SemanticN
export type ResultStylesType = SemanticStylesType<ResultProps, SemanticName>;
export interface ResultProps {
export interface ResultProps extends HTMLAriaDataAttributes {
icon?: React.ReactNode;
status?: ResultStatusType;
title?: React.ReactNode;
@@ -141,6 +143,7 @@ const Result: ResultType = (props) => {
extra,
styles,
classNames,
...rest
} = props;
const {
@@ -203,8 +206,10 @@ const Result: ResultType = (props) => {
...style,
};
const restProps = pickAttrs(rest, { aria: true, data: true });
return (
<div className={rootClassNames} style={rootStyles}>
<div {...restProps} className={rootClassNames} style={rootStyles}>
<Icon className={iconClassNames} style={mergedStyles.icon} status={status} icon={icon} />
<div className={titleClassNames} style={mergedStyles.title}>
{title}

View File

@@ -2,8 +2,8 @@ import React from 'react';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
import { Segmented } from 'antd';
import SemanticPreview from '../../../.dumi/theme/common/SemanticPreview';
import useLocale from '../../../.dumi/hooks/useLocale';
import SemanticPreview from '../../../.dumi/theme/common/SemanticPreview';
const locales = {
cn: {
@@ -33,7 +33,7 @@ const App: React.FC = () => {
{ name: 'icon', desc: locale.icon, version: '6.0.0' },
]}
>
<Segmented
<Segmented<string>
options={[
{ label: 'List', value: 'List', icon: <BarsOutlined /> },
{ label: 'Kanban', value: 'Kanban', icon: <AppstoreOutlined /> },

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { Segmented } from 'antd';
const Demo: React.FC = () => (
<Segmented options={[123, 456, 'longtext-longtext-longtext-longtext']} block />
<Segmented<string | number> options={[123, 456, 'longtext-longtext-longtext-longtext']} block />
);
export default Demo;

View File

@@ -2,9 +2,14 @@ import React, { useState } from 'react';
import { Segmented } from 'antd';
const Demo: React.FC = () => {
const [value, setValue] = useState<string | number>('Map');
return <Segmented options={['Map', 'Transit', 'Satellite']} value={value} onChange={setValue} />;
const [value, setValue] = useState<string>('Map');
return (
<Segmented<string>
options={['Map', 'Transit', 'Satellite']}
value={value}
onChange={setValue}
/>
);
};
export default Demo;

View File

@@ -1,17 +1,14 @@
import React, { useState } from 'react';
import { MoonOutlined, SunOutlined } from '@ant-design/icons';
import { Flex, Segmented } from 'antd';
import type { SizeType } from '../../config-provider/SizeContext';
const Demo: React.FC = () => {
const [size, setSize] = useState<SizeType>('middle');
return (
<Flex gap="small" align="flex-start" vertical>
<Segmented
options={['small', 'middle', 'large']}
value={size}
onChange={(value) => setSize(value as SizeType)}
/>
<Segmented<SizeType> options={['small', 'middle', 'large']} value={size} onChange={setSize} />
<Segmented
size={size}
shape="round"

View File

@@ -10453,12 +10453,12 @@ Array [
>
<span
class="ant-select-selection-item"
title="China"
title="Happy"
>
<span
class="ant-select-selection-item-content"
>
China
Happy
</span>
<span
aria-hidden="true"
@@ -10542,20 +10542,20 @@ Array [
style="height: 0px; width: 0px; overflow: hidden;"
>
<div
aria-label="China"
aria-label="Happy"
aria-selected="true"
id="test-id_list_0"
role="option"
>
china
happy
</div>
<div
aria-label="USA"
aria-label="Sad"
aria-selected="false"
id="test-id_list_1"
role="option"
>
usa
sad
</div>
</div>
<div
@@ -10573,7 +10573,7 @@ Array [
>
<div
class="ant-select-item ant-select-item-option ant-select-item-option-active ant-select-item-option-selected"
title="China"
title="Happy"
>
<div
class="ant-select-item-option-content"
@@ -10585,16 +10585,16 @@ Array [
class="ant-space-item"
>
<span
aria-label="China"
aria-label="Happy"
role="img"
>
🇨🇳
😄
</span>
</div>
<div
class="ant-space-item"
>
China (中国)
Happy (Feeling Good)
</div>
</div>
</div>
@@ -10627,7 +10627,7 @@ Array [
</div>
<div
class="ant-select-item ant-select-item-option"
title="USA"
title="Sad"
>
<div
class="ant-select-item-option-content"
@@ -10639,23 +10639,23 @@ Array [
class="ant-space-item"
>
<span
aria-label="USA"
aria-label="Sad"
role="img"
>
🇺🇸
😢
</span>
</div>
<div
class="ant-space-item"
>
USA (美国)
Sad (Feeling Blue)
</div>
</div>
</div>
</div>
<div
class="ant-select-item ant-select-item-option"
title="Japan"
title="Angry"
>
<div
class="ant-select-item-option-content"
@@ -10667,23 +10667,23 @@ Array [
class="ant-space-item"
>
<span
aria-label="Japan"
aria-label="Angry"
role="img"
>
🇯🇵
😡
</span>
</div>
<div
class="ant-space-item"
>
Japan (日本)
Angry (Furious)
</div>
</div>
</div>
</div>
<div
class="ant-select-item ant-select-item-option"
title="Korea"
title="Cool"
>
<div
class="ant-select-item-option-content"
@@ -10695,16 +10695,44 @@ Array [
class="ant-space-item"
>
<span
aria-label="Korea"
aria-label="Cool"
role="img"
>
🇰🇷
😎
</span>
</div>
<div
class="ant-space-item"
>
Korea (韩国)
Cool (Chilling)
</div>
</div>
</div>
</div>
<div
class="ant-select-item ant-select-item-option"
title="Sleepy"
>
<div
class="ant-select-item-option-content"
>
<div
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small css-var-test-id"
>
<div
class="ant-space-item"
>
<span
aria-label="Sleepy"
role="img"
>
😴
</span>
</div>
<div
class="ant-space-item"
>
Sleepy (Need Sleep)
</div>
</div>
</div>

View File

@@ -3699,12 +3699,12 @@ exports[`renders components/select/demo/option-render.tsx correctly 1`] = `
>
<span
class="ant-select-selection-item"
title="China"
title="Happy"
>
<span
class="ant-select-selection-item-content"
>
China
Happy
</span>
<span
aria-hidden="true"

View File

@@ -1,7 +1,7 @@
## zh-CN
使用 `dropdownRender` 对下拉菜单进行自由扩展。如果希望点击自定义内容后关闭浮层,你需要使用受控模式自行控制([codesandbox](https://codesandbox.io/s/ji-ben-shi-yong-antd-4-21-7-forked-gnp4cy?file=/demo.js))。
使用 `popupRender` 对下拉菜单进行自由扩展。如果希望点击自定义内容后关闭浮层,你需要使用受控模式自行控制([codesandbox](https://codesandbox.io/s/ji-ben-shi-yong-antd-4-21-7-forked-gnp4cy?file=/demo.js))。
## en-US
Customize the dropdown menu via `dropdownRender`. If you want to close the dropdown after clicking the custom content, you need to control `open` prop, here is an [codesandbox](https://codesandbox.io/s/ji-ben-shi-yong-antd-4-21-7-forked-gnp4cy?file=/demo.js).
Customize the dropdown menu via `popupRender`. If you want to close the dropdown after clicking the custom content, you need to control `open` prop, here is an [codesandbox](https://codesandbox.io/s/ji-ben-shi-yong-antd-4-21-7-forked-gnp4cy?file=/demo.js).

View File

@@ -1,34 +1,36 @@
import React from 'react';
import { Select, Space } from 'antd';
const handleChange = (value: string[]) => {
console.log(`selected ${value}`);
};
const options = [
{
label: 'China',
value: 'china',
emoji: '🇨🇳',
desc: 'China (中国)',
label: 'Happy',
value: 'happy',
emoji: '😄',
desc: 'Feeling Good',
},
{
label: 'USA',
value: 'usa',
emoji: '🇺🇸',
desc: 'USA (美国)',
label: 'Sad',
value: 'sad',
emoji: '😢',
desc: 'Feeling Blue',
},
{
label: 'Japan',
value: 'japan',
emoji: '🇯🇵',
desc: 'Japan (日本)',
label: 'Angry',
value: 'angry',
emoji: '😡',
desc: 'Furious',
},
{
label: 'Korea',
value: 'korea',
emoji: '🇰🇷',
desc: 'Korea (韩国)',
label: 'Cool',
value: 'cool',
emoji: '😎',
desc: 'Chilling',
},
{
label: 'Sleepy',
value: 'sleepy',
emoji: '😴',
desc: 'Need Sleep',
},
];
@@ -36,16 +38,18 @@ const App: React.FC = () => (
<Select
mode="multiple"
style={{ width: '100%' }}
placeholder="select one country"
defaultValue={['china']}
onChange={handleChange}
placeholder="Please select your current mood."
defaultValue={['happy']}
onChange={(value) => {
console.log(`selected ${value}`);
}}
options={options}
optionRender={(option) => (
<Space>
<span role="img" aria-label={option.data.label}>
{option.data.emoji}
</span>
{option.data.desc}
{`${option.data.label} (${option.data.desc})`}
</Space>
)}
/>

View File

@@ -173,17 +173,17 @@ Common props ref[Common props](/docs/react/common-props)
It's caused by option with different `label` and `value`. You can use `optionFilterProp="label"` to change filter logic instead.
### When I click elements in dropdownRender, the select dropdown will not be closed? {#faq-dropdown-not-close}
### When I click elements in popupRender, the select dropdown will not be closed? {#faq-popup-not-close}
You can control it by `open` prop: [codesandbox](https://codesandbox.io/s/ji-ben-shi-yong-antd-4-21-7-forked-gnp4cy?file=/demo.js).
### I don't want dropdown close when click inside `dropdownRender`? {#faq-dropdown-keep-open}
### I don't want dropdown close when click inside `popupRender`? {#faq-popup-keep-open}
Select will close when it lose focus. You can prevent event to handle this:
```tsx
<Select
dropdownRender={() => (
popupRender={() => (
<div
onMouseDown={(e) => {
e.preventDefault();

View File

@@ -174,17 +174,17 @@ demo:
这一般是 `options` 中的 `label``value` 不同导致的,你可以通过 `optionFilterProp="label"` 将过滤设置为展示值以避免这种情况。
### 点击 `dropdownRender` 里的元素,下拉菜单不会自动消失? {#faq-dropdown-not-close}
### 点击 `popupRender` 里的元素,下拉菜单不会自动消失? {#faq-popup-not-close}
你可以使用受控模式,手动设置 `open` 属性:[codesandbox](https://codesandbox.io/s/ji-ben-shi-yong-antd-4-21-7-forked-gnp4cy?file=/demo.js)。
### 反过来希望点击 `dropdownRender` 里元素不消失该怎么办? {#faq-dropdown-keep-open}
### 反过来希望点击 `popupRender` 里元素不消失该怎么办? {#faq-popup-keep-open}
Select 当失去焦点时会关闭下拉框,如果你可以通过阻止默认行为避免丢失焦点导致的关闭:
```tsx
<Select
dropdownRender={() => (
popupRender={() => (
<div
onMouseDown={(e) => {
e.preventDefault();

View File

@@ -6,7 +6,7 @@ import SemanticPreview from '../../../.dumi/theme/common/SemanticPreview';
interface PreviewContentProps {
element: string;
setElement: (element: string) => void;
setElement: React.Dispatch<React.SetStateAction<string>>;
}
const COMPONENT_MAP: Record<string, React.ElementType> = {
@@ -25,15 +25,12 @@ const OPTIONS = [
{ value: 'Node', label: 'Node' },
];
const PreviewContent: React.FC<PreviewContentProps> = ({ element, setElement, ...rest }) => {
const PreviewContent: React.FC<PreviewContentProps> = (props) => {
const { element, setElement, ...rest } = props;
const Element = COMPONENT_MAP[element];
return (
<Flex vertical style={{ width: 'fit-content', marginRight: 'auto' }}>
<Segmented
options={OPTIONS}
value={element}
onChange={(value: string) => setElement(value)}
/>
<Segmented options={OPTIONS} value={element} onChange={setElement} />
<Divider titlePlacement="start" plain>
Preview
</Divider>

View File

@@ -100,7 +100,7 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
useSizes(items, containerSize);
// ====================== Resizable =======================
const resizableInfos = useResizable(items, itemPxSizes, isRTL);
const resizableInfos = useResizable(items, itemPxSizes, reverse);
const [onOffsetStart, onOffsetUpdate, onOffsetEnd, onCollapse, movingIndex] = useResize(
items,
@@ -108,7 +108,7 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
itemPtgSizes,
containerSize,
updateSizes,
isRTL,
reverse,
);
// ======================== Events ========================

View File

@@ -32,7 +32,7 @@ function getShowCollapsibleIcon(prev: Option, next: Option) {
return false;
}
export default function useResizable(items: ItemType[], pxSizes: number[], isRTL: boolean) {
export default function useResizable(items: ItemType[], pxSizes: number[], reverse: boolean) {
return React.useMemo(() => {
const resizeInfos: ResizableInfo[] = [];
@@ -94,13 +94,13 @@ export default function useResizable(items: ItemType[], pxSizes: number[], isRTL
resizeInfos[i] = {
resizable: mergedResizable,
startCollapsible: !!(isRTL ? endCollapsible : startCollapsible),
endCollapsible: !!(isRTL ? startCollapsible : endCollapsible),
showStartCollapsibleIcon: isRTL ? showEndCollapsibleIcon : showStartCollapsibleIcon,
showEndCollapsibleIcon: isRTL ? showStartCollapsibleIcon : showEndCollapsibleIcon,
startCollapsible: !!(reverse ? endCollapsible : startCollapsible),
endCollapsible: !!(reverse ? startCollapsible : endCollapsible),
showStartCollapsibleIcon: reverse ? showEndCollapsibleIcon : showStartCollapsibleIcon,
showEndCollapsibleIcon: reverse ? showStartCollapsibleIcon : showEndCollapsibleIcon,
};
}
return resizeInfos;
}, [pxSizes, items, isRTL]);
}, [pxSizes, items, reverse]);
}

View File

@@ -13,7 +13,7 @@ export default function useResize(
percentSizes: number[],
containerSize: number | undefined,
updateSizes: (sizes: number[]) => void,
isRTL: boolean,
reverse: boolean,
) {
const limitSizes = items.map((item) => [item.min, item.max]);
@@ -120,7 +120,7 @@ export default function useResize(
// ======================= Collapse =======================
const onCollapse = (index: number, type: 'start' | 'end') => {
const currentSizes = getPxSizes();
const adjustedType = isRTL ? (type === 'start' ? 'end' : 'start') : type;
const adjustedType = reverse ? (type === 'start' ? 'end' : 'start') : type;
const currentIndex = adjustedType === 'start' ? index : index + 1;
const targetIndex = adjustedType === 'start' ? index + 1 : index;

View File

@@ -30,39 +30,6 @@ export interface ComponentToken {
interface SplitterToken extends FullToken<'Splitter'> {}
const genRtlStyle = (token: SplitterToken): CSSObject => {
const { componentCls } = token;
return {
[`&-rtl${componentCls}-horizontal`]: {
[`> ${componentCls}-bar`]: {
[`${componentCls}-bar-collapse-previous`]: {
insetInlineEnd: 0,
insetInlineStart: 'unset',
},
[`${componentCls}-bar-collapse-next`]: {
insetInlineEnd: 'unset',
insetInlineStart: 0,
},
},
},
[`&-rtl${componentCls}-vertical`]: {
[`> ${componentCls}-bar`]: {
[`${componentCls}-bar-collapse-previous`]: {
insetInlineEnd: '50%',
insetInlineStart: 'unset',
},
[`${componentCls}-bar-collapse-next`]: {
insetInlineEnd: '50%',
insetInlineStart: 'unset',
},
},
},
};
};
const centerStyle: CSSObject = {
position: 'absolute',
top: '50%',
@@ -406,8 +373,6 @@ const genSplitterStyle: GenerateStyle<SplitterToken> = (token: SplitterToken): C
overflow: 'hidden',
},
},
...genRtlStyle(token),
},
};
};

View File

@@ -39,7 +39,7 @@ We provide comprehensive design guidelines, best practices, resources, and tools
- [Ant Design Blazor](https://antblazor.com/)
- [San UI Toolkit for Ant Design](https://ecomfe.github.io/santd)
- [antizer (ClojureScript)](https://github.com/priornix/antizer)
- [AtomUI - Ant Design of Avalonia/.NET](https://github.com/chinware/atomui)
- [AtomUI - Ant Design of Avalonia/.NET](https://github.com/atomui/atomui)
## Who's using Ant Design

View File

@@ -39,7 +39,7 @@ title: 介绍
- [Ant Design Blazor](https://antblazor.com/)(社区实现)
- [San UI Toolkit for Ant Design](https://ecomfe.github.io/santd)(社区实现)
- [antizer (ClojureScript)](https://github.com/priornix/antizer)(社区实现)
- [AtomUI - Ant Design of Avalonia/.NET](https://github.com/chinware/atomui)(社区实现)
- [AtomUI - Ant Design of Avalonia/.NET](https://github.com/atomui/atomui)(社区实现)
## 谁在使用

View File

@@ -160,13 +160,13 @@
},
"devDependencies": {
"@ant-design/compatible": "^5.1.4",
"@ant-design/happy-work-theme": "^1.0.1",
"@ant-design/happy-work-theme": "^2.0.0",
"@ant-design/tools": "^19.1.0",
"@ant-design/x": "^1.6.1",
"@antfu/eslint-config": "^6.4.1",
"@antfu/eslint-config": "^6.6.1",
"@antv/g6": "^4.8.25",
"@biomejs/biome": "^2.3.8",
"@blazediff/core": "^1.4.0",
"@blazediff/core": "^1.7.0",
"@codecov/webpack-plugin": "^1.9.1",
"@codesandbox/sandpack-react": "^2.20.0",
"@dnd-kit/core": "^6.3.1",
@@ -176,13 +176,13 @@
"@emotion/css": "^11.13.5",
"@emotion/react": "^11.14.0",
"@emotion/server": "^11.11.0",
"@eslint-react/eslint-plugin": "^2.3.12",
"@eslint-react/eslint-plugin": "^2.3.13",
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
"@inquirer/prompts": "^8.0.1",
"@inquirer/prompts": "^8.0.2",
"@madccc/duplicate-package-checker-webpack-plugin": "^1.0.0",
"@microflash/rehype-figure": "^2.1.4",
"@npmcli/run-script": "^10.0.0",
"@octokit/rest": "^22.0.0",
"@npmcli/run-script": "^10.0.3",
"@octokit/rest": "^22.0.1",
"@prettier/sync": "^0.6.1",
"@qixian.cs/github-contributors-list": "^2.0.2",
"@rc-component/virtual-list": "^1.0.2",
@@ -193,7 +193,7 @@
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^14.6.1",
"@types/adm-zip": "^0.5.7",
"@types/ali-oss": "^6.16.11",
"@types/ali-oss": "^6.16.13",
"@types/cli-progress": "^3.11.6",
"@types/css-tree": "^2.3.11",
"@types/fs-extra": "^11.0.4",
@@ -206,15 +206,15 @@
"@types/jest-image-snapshot": "^6.4.0",
"@types/jquery": "^3.5.33",
"@types/jsdom": "^27.0.0",
"@types/lodash": "^4.17.20",
"@types/lodash": "^4.17.21",
"@types/minimist": "^1.2.5",
"@types/node": "^25.0.0",
"@types/node": "^25.0.1",
"@types/nprogress": "^0.2.3",
"@types/pngjs": "^6.0.5",
"@types/prismjs": "^1.26.5",
"@types/progress": "^2.0.7",
"@types/react": "^19.2.0",
"@types/react-dom": "^19.2.0",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
"@types/react-highlight-words": "^0.20.0",
"@types/react-resizable": "^3.0.8",
"@types/semver": "^7.7.1",
@@ -228,7 +228,7 @@
"antd-img-crop": "^4.27.0",
"antd-style": "4.0.0-alpha.1",
"antd-token-previewer": "^3.0.0",
"axios": "^1.12.2",
"axios": "^1.13.2",
"chalk": "^5.6.2",
"cheerio": "^1.1.2",
"circular-dependency-plugin": "^5.2.2",
@@ -249,7 +249,7 @@
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"fast-glob": "^3.3.3",
"father": "4.6.8",
"father": "4.6.9",
"fs-extra": "^11.3.2",
"gh-pages": "^6.3.0",
"github-slugger": "^2.0.0",
@@ -259,7 +259,7 @@
"http-server": "^14.1.1",
"husky": "^9.1.7",
"identity-obj-proxy": "^3.0.0",
"immer": "^11.0.0",
"immer": "^11.0.1",
"is-ci": "^4.1.0",
"isomorphic-fetch": "^3.0.0",
"jest": "^30.2.0",
@@ -273,9 +273,9 @@
"jsdom": "27.0.0",
"jsonml-to-react-element": "^1.1.11",
"jsonml.js": "^0.1.0",
"lint-staged": "^16.2.3",
"lint-staged": "^16.2.7",
"lodash": "^4.17.21",
"lunar-typescript": "^1.8.2",
"lunar-typescript": "^1.8.6",
"lz-string": "^1.5.0",
"minimist": "^1.2.8",
"mockdate": "^3.0.5",
@@ -284,25 +284,25 @@
"open": "^11.0.0",
"ora": "^9.0.0",
"p-all": "^5.0.1",
"package-manager-detector": "^1.3.0",
"package-manager-detector": "^1.6.0",
"pngjs": "^7.0.0",
"portfinder": "^1.0.38",
"prettier": "^3.6.2",
"prettier": "^3.7.4",
"pretty-format": "^30.2.0",
"prismjs": "^1.30.0",
"puppeteer": "^24.23.0",
"puppeteer": "^24.33.0",
"rc-footer": "^0.6.8",
"rc-tween-one": "^3.0.6",
"react": "^19.2.0",
"react": "^19.2.3",
"react-countup": "^6.5.3",
"react-dom": "^19.2.0",
"react-dom": "^19.2.3",
"react-draggable": "^4.5.0",
"react-fast-marquee": "^1.6.5",
"react-highlight-words": "^0.21.0",
"react-icons": "^5.5.0",
"react-infinite-scroll-component": "^6.1.0",
"react-infinite-scroll-component": "^6.1.1",
"react-resizable": "^3.0.5",
"react-router-dom": "^7.9.3",
"react-router-dom": "^7.10.1",
"react-sticky-box": "^2.0.5",
"rehype-stringify": "^10.0.1",
"remark": "^15.0.1",
@@ -312,22 +312,22 @@
"remark-lint-no-undefined-references": "^5.0.2",
"remark-preset-lint-recommended": "^7.0.1",
"remark-rehype": "^11.1.2",
"rimraf": "^6.0.1",
"rimraf": "^6.1.2",
"runes2": "^1.1.4",
"semver": "^7.7.2",
"sharp": "^0.34.4",
"simple-git": "^3.28.0",
"semver": "^7.7.3",
"sharp": "^0.34.5",
"simple-git": "^3.30.0",
"size-limit": "^12.0.0",
"spinnies": "^0.5.1",
"swr": "^2.3.6",
"tar": "^7.5.1",
"tsx": "^4.20.6",
"typedoc": "^0.28.13",
"swr": "^2.3.7",
"tar": "^7.5.2",
"tsx": "^4.21.0",
"typedoc": "^0.28.15",
"typescript": "~5.9.3",
"vanilla-jsoneditor": "^3.10.0",
"vanilla-jsoneditor": "^3.11.0",
"vanilla-tilt": "^1.8.1",
"webpack": "^5.102.0",
"webpack-bundle-analyzer": "^5.0.1",
"webpack": "^5.103.0",
"webpack-bundle-analyzer": "^5.1.0",
"xhr-mock": "^2.5.1"
},
"publishConfig": {