diff --git a/.dumi/theme/builtins/ColorChunk/index.tsx b/.dumi/theme/builtins/ColorChunk/index.tsx index 743ded015d..42c4634a7d 100644 --- a/.dumi/theme/builtins/ColorChunk/index.tsx +++ b/.dumi/theme/builtins/ColorChunk/index.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { FastColor } from '@ant-design/fast-color'; -import type { ColorInput } from '@ant-design/fast-color'; +// @ts-ignore +import { TinyColor } from 'dumi-plugin-color-chunk/component'; import { createStyles } from 'antd-style'; const useStyle = createStyles(({ token, css }) => ({ @@ -22,7 +22,7 @@ const useStyle = createStyles(({ token, css }) => ({ })); interface ColorChunkProps { - value: ColorInput; + value: any; } const ColorChunk: React.FC> = (props) => { @@ -30,7 +30,7 @@ const ColorChunk: React.FC> = (props) = const { value, children } = props; const dotColor = React.useMemo(() => { - const _color = new FastColor(value).toHexString(); + const _color = new TinyColor(value).toHex8String(); return _color.endsWith('ff') ? _color.slice(0, -2) : _color; }, [value]); diff --git a/.dumi/theme/builtins/DemoWrapper/index.tsx b/.dumi/theme/builtins/DemoWrapper/index.tsx index e6d22a9956..18ca44f5b5 100644 --- a/.dumi/theme/builtins/DemoWrapper/index.tsx +++ b/.dumi/theme/builtins/DemoWrapper/index.tsx @@ -1,7 +1,6 @@ import React, { Suspense, useContext } from 'react'; import { BugOutlined, CodeOutlined, ExperimentOutlined } from '@ant-design/icons'; import { ConfigProvider, Tooltip, Button } from 'antd'; -import classNames from 'classnames'; import { DumiDemoGrid, FormattedMessage, DumiDemo } from 'dumi'; import { css, Global } from '@emotion/react'; @@ -42,13 +41,16 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => { const demos = React.useMemo( () => - items.map((item: any) => { + items.reduce((acc, item) => { const { previewerProps } = item; const { debug } = previewerProps; - return { + if (debug && !showDebug) { + return acc; + } + return acc.concat({ ...item, previewerProps: { - ...item.previewerProps, + ...previewerProps, expand: expandAll, // always override debug property, because dumi will hide debug demo in production debug: false, @@ -58,17 +60,13 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => { */ originDebug: debug, }, - }; - }), + }); + }, []), [expandAll, showDebug], ); return ( -
+
{ ( - }> - + }> + )} /> diff --git a/.dumi/theme/common/styles/Demo.tsx b/.dumi/theme/common/styles/Demo.tsx index 8e55b24371..8c658fef91 100644 --- a/.dumi/theme/common/styles/Demo.tsx +++ b/.dumi/theme/common/styles/Demo.tsx @@ -325,7 +325,6 @@ const GlobalDemoStyles: React.FC = () => { &-debug { border-color: ${token.purple3}; - display: none; } &-debug &-title a { @@ -335,10 +334,6 @@ const GlobalDemoStyles: React.FC = () => { .demo-wrapper { position: relative; - - &-show-debug .code-box-debug { - display: block; - } } .all-code-box-controls { diff --git a/.dumi/theme/slots/Content/ContributorAvatar.tsx b/.dumi/theme/slots/Content/ContributorAvatar.tsx index 04f4cfbee8..3b745f5844 100644 --- a/.dumi/theme/slots/Content/ContributorAvatar.tsx +++ b/.dumi/theme/slots/Content/ContributorAvatar.tsx @@ -1,19 +1,6 @@ import React from 'react'; import type { AvatarListItem } from '@qixian.cs/github-contributors-list/dist/AvatarList'; -import { Avatar, Skeleton, Tooltip } from 'antd'; - -const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 3 }) => ( -
  • - {Array.from({ length: num }).map((_, i) => ( - - ))} -
  • -); +import { Avatar, Tooltip } from 'antd'; interface ContributorAvatarProps { loading?: boolean; @@ -23,11 +10,7 @@ interface ContributorAvatarProps { const ContributorAvatar: React.FC = (props) => { const { item: { username, url } = {}, - loading, } = props; - if (loading) { - return ; - } if (username?.includes('github-actions')) { return null; } diff --git a/.dumi/theme/slots/Content/index.tsx b/.dumi/theme/slots/Content/index.tsx index 1b9c77f932..f9a55859f0 100644 --- a/.dumi/theme/slots/Content/index.tsx +++ b/.dumi/theme/slots/Content/index.tsx @@ -1,5 +1,5 @@ import React, { useContext, useLayoutEffect, useMemo, useState } from 'react'; -import { Col, Flex, Space, Typography } from 'antd'; +import { Col, Flex, Space, Typography, Skeleton } from 'antd'; import classNames from 'classnames'; import { FormattedMessage, useRouteMeta } from 'dumi'; @@ -20,6 +20,11 @@ const Footer = React.lazy(() => import('../Footer')); const PrevAndNext = React.lazy(() => import('../../common/PrevAndNext')); const EditButton = React.lazy(() => import('../../common/EditButton')); +const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 6 }) => + Array.from({ length: num }).map((_, i) => ( + + )); + const Content: React.FC = ({ children }) => { const meta = useRouteMeta(); const { pathname, hash } = useLocation(); @@ -87,7 +92,7 @@ const Content: React.FC = ({ children }) => { /> )}
    {children}
    - + = ({ children }) => { />
    - }> + }>
    diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 792db583a1..0932329cf8 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -15,6 +15,22 @@ tag: vVERSION --- +## 5.23.2 + +`2025-01-20` + +- 🐞 Fix Space.Compact throwing `Should not use more than one & in a selector` warning. [#52489](https://github.com/ant-design/ant-design/pull/52489) +- 💄 Fix the Layout switching sidebar button style was lost. [#52477](https://github.com/ant-design/ant-design/pull/52477) +- 💄 Fix the scroll bar height is not 0 when the first row of the virtual scroll Table is collapsed. [#52447](https://github.com/ant-design/ant-design/pull/52447) [@LeeSSHH](https://github.com/LeeSSHH) +- 💄 Fix the last item in Descriptions did not correctly fill the remaining space. [#52410](https://github.com/ant-design/ant-design/pull/52410) [@anyuxuan](https://github.com/anyuxuan) +- 💄 Fix extra margin for the last item in Radio. [#52433](https://github.com/ant-design/ant-design/pull/52433) +- 💄 Fix the Input/Mentions clear button padding was incorrect. [#52407](https://github.com/ant-design/ant-design/pull/52407) [@ustcfury](https://github.com/ustcfury) +- 💄 Fix rounded corners of `addonAfter` in Input compact mode. [#52490](https://github.com/ant-design/ant-design/pull/52490) [@DDDDD12138](https://github.com/DDDDD12138) +- 💄 Fix Menu.Item links were still clickable and lacked disabled styles when in disabled state. [#52402](https://github.com/ant-design/ant-design/pull/52402) [@aojunhao123](https://github.com/aojunhao123) +- TypeScript + - 🤖 MISC: Optimize PurePanel to use React.ComponentType type. [#52480](https://github.com/ant-design/ant-design/pull/52480) + - 🤖 Fix missing token type for Skeleton and Rate. [#52406](https://github.com/ant-design/ant-design/pull/52406) [@coding-ice](https://github.com/coding-ice) + ## 5.23.1 `2025-01-13` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 495c54c2df..ed784505e1 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -15,6 +15,22 @@ tag: vVERSION --- +## 5.23.2 + +`2025-01-20` + +- 🐞 修复 Space.Compact 抛出 `Should not use more than one & in a selector` 警告信息的问题。[#52489](https://github.com/ant-design/ant-design/pull/52489) +- 💄 修复 Layout 切换侧边栏按钮样式丢失的问题。[#52477](https://github.com/ant-design/ant-design/pull/52477) +- 💄 修复 Table 收起虚拟滚动表格第一行时滚动条高度不为 0 的问题。[#52447](https://github.com/ant-design/ant-design/pull/52447) [@LeeSSHH](https://github.com/LeeSSHH) +- 💄 修复 Descriptions 最后一项未正确填充满剩余空间的问题。[#52410](https://github.com/ant-design/ant-design/pull/52410) [@anyuxuan](https://github.com/anyuxuan) +- 💄 修复 Radio.Group 最后一项多余 margin 的问题。[#52433](https://github.com/ant-design/ant-design/pull/52433) +- 💄 修复 Input/Mentions 清除按钮 padding 不正确的问题。[#52407](https://github.com/ant-design/ant-design/pull/52407) [@ustcfury](https://github.com/ustcfury) +- 💄 修复 Input 紧凑模式中 `addonAfter` 的圆角问题。[#52490](https://github.com/ant-design/ant-design/pull/52490) [@DDDDD12138](https://github.com/DDDDD12138) +- 💄 修复 Menu.Item 在禁用状态下链接仍可点击且缺少禁用样式的问题。[#52402](https://github.com/ant-design/ant-design/pull/52402) [@aojunhao123](https://github.com/aojunhao123) +- TypeScript + - 🤖 MISC: 优化 PurePanel 使用 React.ComponentType 类型。[#52480](https://github.com/ant-design/ant-design/pull/52480) + - 🤖 修复 Skeleton 和 Rate 缺失的 token 类型。[#52406](https://github.com/ant-design/ant-design/pull/52406) [@coding-ice](https://github.com/coding-ice) + ## 5.23.1 `2025-01-13` diff --git a/README-zh_CN.md b/README-zh_CN.md index b349a31044..04aee17006 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -20,8 +20,8 @@ [npm-image]: https://img.shields.io/npm/v/antd.svg?style=flat-square [npm-url]: https://npmjs.org/package/antd -[github-action-image]: https://github.com/ant-design/ant-design/workflows/%E2%9C%85%20test/badge.svg -[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22 +[github-action-image]: https://github.com/ant-design/ant-design/actions/workflows/test.yml/badge.svg +[github-action-url]: https://github.com/ant-design/ant-design/actions/workflows/test.yml [codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square [codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master [download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square diff --git a/README.md b/README.md index 43e154a3ad..995df5dc87 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ An enterprise-class UI design language and React UI library. [npm-image]: https://img.shields.io/npm/v/antd.svg?style=flat-square [npm-url]: https://npmjs.org/package/antd -[github-action-image]: https://github.com/ant-design/ant-design/workflows/%E2%9C%85%20test/badge.svg -[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22 +[github-action-image]: https://github.com/ant-design/ant-design/actions/workflows/test.yml/badge.svg +[github-action-url]: https://github.com/ant-design/ant-design/actions/workflows/test.yml [codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square [codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master [download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square diff --git a/components/_util/PurePanel.tsx b/components/_util/PurePanel.tsx index badc7551e9..ecb1b0827e 100644 --- a/components/_util/PurePanel.tsx +++ b/components/_util/PurePanel.tsx @@ -19,7 +19,7 @@ export interface BaseProps { /* istanbul ignore next */ const genPurePanel = ( - Component: any, + Component: React.ComponentType>, alignPropName?: 'align' | 'dropdownAlign' | 'popupAlign', postProps?: (props: ComponentProps) => ComponentProps, defaultPrefixCls?: string, diff --git a/components/_util/isNumeric.ts b/components/_util/isNumeric.ts deleted file mode 100644 index b1aeed28f1..0000000000 --- a/components/_util/isNumeric.ts +++ /dev/null @@ -1,3 +0,0 @@ -const isNumeric = (value: any): boolean => !isNaN(parseFloat(value)) && isFinite(value); - -export default isNumeric; diff --git a/components/badge/demo/_semantic.tsx b/components/badge/demo/_semantic.tsx index a0673ab962..01952c8cad 100644 --- a/components/badge/demo/_semantic.tsx +++ b/components/badge/demo/_semantic.tsx @@ -6,8 +6,8 @@ import useLocale from '../../../.dumi/hooks/useLocale'; const locales = { cn: { - root: '根节点', - indicator: '指示器节点', + root: '根元素', + indicator: '指示器元素', }, en: { root: 'Root element', diff --git a/components/badge/demo/_semantic_ribbon.tsx b/components/badge/demo/_semantic_ribbon.tsx index 80097db3d4..3798f7b6f8 100644 --- a/components/badge/demo/_semantic_ribbon.tsx +++ b/components/badge/demo/_semantic_ribbon.tsx @@ -6,9 +6,9 @@ import useLocale from '../../../.dumi/hooks/useLocale'; const locales = { cn: { - root: '根节点', - indicator: '指示器节点', - content: '文本节点', + root: '根元素', + indicator: '指示器元素', + content: '文本元素', }, en: { root: 'Root element', diff --git a/components/button/button.tsx b/components/button/button.tsx index d50fc040a0..50151969fe 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -310,7 +310,7 @@ const InternalCompoundedButton = React.forwardRef< {icon} - ) : typeof loading === 'object' && loading.icon ? ( + ) : loading && typeof loading === 'object' && loading.icon ? ( {loading.icon} diff --git a/components/button/demo/component-token.tsx b/components/button/demo/component-token.tsx index bde16b0040..4bde62ab2a 100644 --- a/components/button/demo/component-token.tsx +++ b/components/button/demo/component-token.tsx @@ -2,28 +2,28 @@ import React from 'react'; import { Button, ConfigProvider, Flex } from 'antd'; const App: React.FC = () => ( - + - + }} + > @@ -36,7 +36,18 @@ const App: React.FC = () => ( - + + + + + + + + + + + - + ); export default App; diff --git a/components/button/style/compact.ts b/components/button/style/compact.ts index 8f17385011..e487144335 100644 --- a/components/button/style/compact.ts +++ b/components/button/style/compact.ts @@ -11,21 +11,20 @@ import { prepareComponentToken, prepareToken } from './token'; const genButtonCompactStyle: GenerateStyle = (token) => { const { componentCls, colorPrimaryHover, lineWidth, calc } = token; const insetOffset = calc(lineWidth).mul(-1).equal(); - const getCompactBorderStyle = (vertical?: boolean) => - ({ - [`${componentCls}-compact${vertical ? '-vertical' : ''}-item${componentCls}-primary:not([disabled])`]: - { - '& + &::before': { - position: 'absolute', - top: vertical ? insetOffset : 0, - insetInlineStart: vertical ? 0 : insetOffset, - backgroundColor: colorPrimaryHover, - content: '""', - width: vertical ? '100%' : lineWidth, - height: vertical ? lineWidth : '100%', - }, - }, - }) as CSSObject; + const getCompactBorderStyle = (vertical?: boolean) => { + const selector = `${componentCls}-compact${vertical ? '-vertical' : ''}-item${componentCls}-primary:not([disabled])`; + return { + [`${selector} + ${selector}::before`]: { + position: 'absolute', + top: vertical ? insetOffset : 0, + insetInlineStart: vertical ? 0 : insetOffset, + backgroundColor: colorPrimaryHover, + content: '""', + width: vertical ? '100%' : lineWidth, + height: vertical ? lineWidth : '100%', + } as CSSObject, + }; + }; // Special styles for Primary Button return { ...getCompactBorderStyle(), diff --git a/components/button/style/index.ts b/components/button/style/index.ts index 3260e5f7f9..db11c173d0 100644 --- a/components/button/style/index.ts +++ b/components/button/style/index.ts @@ -171,7 +171,7 @@ const genGhostButtonStyle = ( textColor: string | false, borderColor: string | false, textColorDisabled: string | false, - borderColorDisabled: string | false, + colorBorderDisabled: string | false, hoverStyle?: CSSObject, activeStyle?: CSSObject, ): CSSObject => ({ @@ -196,7 +196,7 @@ const genGhostButtonStyle = ( '&:disabled': { cursor: 'not-allowed', color: textColorDisabled || undefined, - borderColor: borderColorDisabled || undefined, + borderColor: colorBorderDisabled || undefined, }, }, }); diff --git a/components/button/style/token.ts b/components/button/style/token.ts index 42f476994b..b97964e38a 100644 --- a/components/button/style/token.ts +++ b/components/button/style/token.ts @@ -83,6 +83,7 @@ export interface ComponentToken { */ defaultActiveBorderColor: string; /** + * @deprecated use `colorBorderDisabled` instead * @desc 禁用状态边框颜色 * @descEN Border color of disabled button */ @@ -239,12 +240,13 @@ export interface ButtonToken extends FullToken<'Button'> { export const prepareToken: (token: Parameters>[0]) => ButtonToken = ( token, ) => { - const { paddingInline, onlyIconSize } = token; + const { paddingInline, onlyIconSize, borderColorDisabled } = token; const buttonToken = mergeToken(token, { buttonPaddingHorizontal: paddingInline, buttonPaddingVertical: 0, buttonIconOnlyFontSize: onlyIconSize, + colorBorderDisabled: borderColorDisabled, }); return buttonToken; @@ -268,7 +270,7 @@ export const prepareComponentToken: GetDefaultToken<'Button'> = (token) => { dangerShadow: `0 ${token.controlOutlineWidth}px 0 ${token.colorErrorOutline}`, primaryColor: token.colorTextLightSolid, dangerColor: token.colorTextLightSolid, - borderColorDisabled: token.colorBorder, + borderColorDisabled: token.colorBorderDisabled, defaultGhostColor: token.colorBgContainer, ghostBg: 'transparent', defaultGhostBorderColor: token.colorBgContainer, diff --git a/components/config-provider/__tests__/form.test.tsx b/components/config-provider/__tests__/form.test.tsx index c4f36801b4..9704dfdd55 100644 --- a/components/config-provider/__tests__/form.test.tsx +++ b/components/config-provider/__tests__/form.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import type { ValidateMessages } from 'rc-field-form/es/interface'; +import type { ValidateMessages } from '@rc-component/form/lib/interface'; import scrollIntoView from 'scroll-into-view-if-needed'; import ConfigProvider from '..'; diff --git a/components/config-provider/context.ts b/components/config-provider/context.ts index 99c15596eb..0885fea0cd 100644 --- a/components/config-provider/context.ts +++ b/components/config-provider/context.ts @@ -192,13 +192,19 @@ export type SelectConfig = ComponentStyleConfig & Pick; -export type TooltipConfig = Pick; +export type TooltipConfig = Pick< + TooltipProps, + 'className' | 'style' | 'styles' | 'classNames' | 'arrow' +>; -export type PopoverConfig = Pick; +export type PopoverConfig = Pick< + PopoverProps, + 'className' | 'style' | 'styles' | 'classNames' | 'arrow' +>; export type PopconfirmConfig = Pick< PopconfirmProps, - 'className' | 'style' | 'styles' | 'classNames' + 'className' | 'style' | 'styles' | 'classNames' | 'arrow' >; export type SliderConfig = ComponentStyleConfig & Pick; diff --git a/components/config-provider/index.en-US.md b/components/config-provider/index.en-US.md index e5a1edfb62..b25fb4cfc3 100644 --- a/components/config-provider/index.en-US.md +++ b/components/config-provider/index.en-US.md @@ -163,9 +163,9 @@ const { | timeline | Set Timeline common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 | | timePicker | Set TimePicker common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 | | tour | Set Tour common props | { closeIcon?: React.ReactNode } | - | 5.14.0 | -| tooltip | Set Tooltip common props | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip#api), styles?: [Tooltip\["styles"\]](/components/tooltip#api) } | - | 5.23.0 | -| popover | Set Popover common props | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover#api), styles?: [Popover\["styles"\]](/components/popover#api) } | - | 5.23.0 | -| popconfirm | Set Popconfirm common props | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm#api) } | - | 5.23.0 | +| tooltip | Set Tooltip common props | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip#api), styles?: [Tooltip\["styles"\]](/components/tooltip#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 | +| popover | Set Popover common props | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover#api), styles?: [Popover\["styles"\]](/components/popover#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 | +| popconfirm | Set Popconfirm common props | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 | | transfer | Set Transfer common props | { className?: string, style?: React.CSSProperties, selectionsIcon?: React.ReactNode } | - | 5.7.0, selectionsIcon: 5.14.0 | | tree | Set Tree common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 | | typography | Set Typography common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 | diff --git a/components/config-provider/index.zh-CN.md b/components/config-provider/index.zh-CN.md index fbbff6c1d1..04d78e902b 100644 --- a/components/config-provider/index.zh-CN.md +++ b/components/config-provider/index.zh-CN.md @@ -165,9 +165,9 @@ const { | timeline | 设置 Timeline 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 | | timePicker | 设置 TimePicker 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 | | tour | 设置 Tour 组件的通用属性 | { closeIcon?: React.ReactNode } | - | 5.14.0 | -| tooltip | 设置 Tooltip 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip-cn#api), styles?: [Tooltip\["styles"\]](/components/tooltip-cn#api) } | - | 5.23.0 | -| popover | 设置 Popover 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover-cn#api), styles?: [Popover\["styles"\]](/components/popover-cn#api) } | - | 5.23.0 | -| popconfirm | 设置 Popconfirm 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm-cn#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm-cn#api) } | - | 5.23.0 | +| tooltip | 设置 Tooltip 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip-cn#api), styles?: [Tooltip\["styles"\]](/components/tooltip-cn#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 | +| popover | 设置 Popover 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover-cn#api), styles?: [Popover\["styles"\]](/components/popover-cn#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 | +| popconfirm | 设置 Popconfirm 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm-cn#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm-cn#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 | | transfer | 设置 Transfer 组件的通用属性 | { className?: string, style?: React.CSSProperties, selectionsIcon?: React.ReactNode } | - | 5.7.0, selectionsIcon: 5.14.0 | | tree | 设置 Tree 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 | | typography | 设置 Typography 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 | diff --git a/components/descriptions/demo/_semantic.tsx b/components/descriptions/demo/_semantic.tsx index 444071b70b..ed2c0026d7 100644 --- a/components/descriptions/demo/_semantic.tsx +++ b/components/descriptions/demo/_semantic.tsx @@ -6,7 +6,7 @@ import useLocale from '../../../.dumi/hooks/useLocale'; const locales = { cn: { - root: '根节点', + root: '根元素', header: '头部元素', title: '标题元素', extra: '额外内容', diff --git a/components/form/Form.tsx b/components/form/Form.tsx index a29031ea2f..11c1f3f8f5 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -1,11 +1,16 @@ import * as React from 'react'; +import FieldForm, { List, useWatch } from '@rc-component/form'; +import type { FormProps as RcFormProps } from '@rc-component/form/lib/Form'; +import type { + FormRef, + InternalNamePath, + ValidateErrorEntity, +} from '@rc-component/form/lib/interface'; import classNames from 'classnames'; -import FieldForm, { List, useWatch } from 'rc-field-form'; -import type { FormProps as RcFormProps } from 'rc-field-form/lib/Form'; -import type { FormRef, InternalNamePath, ValidateErrorEntity } from 'rc-field-form/lib/interface'; import type { Options } from 'scroll-into-view-if-needed'; import { ConfigContext } from '../config-provider'; +import type { Variant } from '../config-provider'; import DisabledContext, { DisabledContextProvider } from '../config-provider/DisabledContext'; import useCSSVarCls from '../config-provider/hooks/useCSSVarCls'; import useSize from '../config-provider/hooks/useSize'; @@ -18,7 +23,6 @@ import type { FeedbackIcons } from './FormItem'; import useForm from './hooks/useForm'; import type { FormInstance } from './hooks/useForm'; import useFormWarning from './hooks/useFormWarning'; -import type { Variant } from '../config-provider'; import type { FormLabelAlign } from './interface'; import useStyle from './style'; import ValidateMessagesContext from './validateMessagesContext'; diff --git a/components/form/FormItem/ItemHolder.tsx b/components/form/FormItem/ItemHolder.tsx index e2c1f11c55..99c6fe4664 100644 --- a/components/form/FormItem/ItemHolder.tsx +++ b/components/form/FormItem/ItemHolder.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; +import type { Meta } from '@rc-component/form/lib/interface'; import isVisible from '@rc-component/util/lib/Dom/isVisible'; import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect'; import omit from '@rc-component/util/lib/omit'; import classNames from 'classnames'; -import type { Meta } from 'rc-field-form/lib/interface'; import type { FormItemProps } from '.'; import { Row } from '../../grid'; diff --git a/components/form/FormItem/StatusProvider.tsx b/components/form/FormItem/StatusProvider.tsx index 71dfba54f2..fc6e4c4558 100644 --- a/components/form/FormItem/StatusProvider.tsx +++ b/components/form/FormItem/StatusProvider.tsx @@ -3,8 +3,8 @@ import CheckCircleFilled from '@ant-design/icons/CheckCircleFilled'; import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled'; import LoadingOutlined from '@ant-design/icons/LoadingOutlined'; +import type { Meta } from '@rc-component/form/lib/interface'; import classNames from 'classnames'; -import type { Meta } from 'rc-field-form/lib/interface'; import type { FeedbackIcons, ValidateStatus } from '.'; import { FormContext, FormItemInputContext } from '../context'; diff --git a/components/form/FormItem/index.tsx b/components/form/FormItem/index.tsx index 38e82c0684..cfcbd899c3 100644 --- a/components/form/FormItem/index.tsx +++ b/components/form/FormItem/index.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; import type { JSX } from 'react'; +import { Field, FieldContext, ListContext } from '@rc-component/form'; +import type { FieldProps } from '@rc-component/form/lib/Field'; +import type { InternalNamePath, Meta } from '@rc-component/form/lib/interface'; import useState from '@rc-component/util/lib/hooks/useState'; import { supportRef } from '@rc-component/util/lib/ref'; import classNames from 'classnames'; -import { Field, FieldContext, ListContext } from 'rc-field-form'; -import type { FieldProps } from 'rc-field-form/lib/Field'; -import type { InternalNamePath, Meta } from 'rc-field-form/lib/interface'; import { cloneElement } from '../../_util/reactNode'; import { devUseWarning } from '../../_util/warning'; diff --git a/components/form/FormList.tsx b/components/form/FormList.tsx index e5cb839f16..645a80ce28 100644 --- a/components/form/FormList.tsx +++ b/components/form/FormList.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { List } from 'rc-field-form'; -import type { StoreValue, ValidatorRule } from 'rc-field-form/lib/interface'; +import { List } from '@rc-component/form'; +import type { StoreValue, ValidatorRule } from '@rc-component/form/lib/interface'; import { devUseWarning } from '../_util/warning'; import { ConfigContext } from '../config-provider'; diff --git a/components/form/__tests__/ref.test.tsx b/components/form/__tests__/ref.test.tsx index 9cd40a2cb8..2dc1d660d5 100644 --- a/components/form/__tests__/ref.test.tsx +++ b/components/form/__tests__/ref.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import type { FormRef } from 'rc-field-form/lib/interface'; +import type { FormRef } from '@rc-component/form/lib/interface'; import Form, { FormInstance } from '..'; import { fireEvent, render } from '../../../tests/utils'; diff --git a/components/form/context.tsx b/components/form/context.tsx index fe0afa3cca..5471b1e874 100644 --- a/components/form/context.tsx +++ b/components/form/context.tsx @@ -1,9 +1,9 @@ import type { PropsWithChildren, ReactNode } from 'react'; import * as React from 'react'; +import { FormProvider as RcFormProvider } from '@rc-component/form'; +import type { FormProviderProps as RcFormProviderProps } from '@rc-component/form/lib/FormContext'; +import type { Meta } from '@rc-component/form/lib/interface'; import omit from '@rc-component/util/lib/omit'; -import { FormProvider as RcFormProvider } from 'rc-field-form'; -import type { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext'; -import type { Meta } from 'rc-field-form/lib/interface'; import type { Variant } from '../config-provider'; import type { ColProps } from '../grid/col'; diff --git a/components/form/hooks/useForm.ts b/components/form/hooks/useForm.ts index bf1d41a143..845347a3b9 100644 --- a/components/form/hooks/useForm.ts +++ b/components/form/hooks/useForm.ts @@ -1,7 +1,7 @@ import * as React from 'react'; +import type { FormInstance as RcFormInstance } from '@rc-component/form'; +import { useForm as useRcForm } from '@rc-component/form'; import { getDOM } from '@rc-component/util/lib/Dom/findDOMNode'; -import type { FormInstance as RcFormInstance } from 'rc-field-form'; -import { useForm as useRcForm } from 'rc-field-form'; import scrollIntoView from 'scroll-into-view-if-needed'; import type { InternalNamePath, NamePath, ScrollOptions } from '../interface'; diff --git a/components/form/index.tsx b/components/form/index.tsx index 5bd61d20cb..8d6134ca6a 100644 --- a/components/form/index.tsx +++ b/components/form/index.tsx @@ -1,4 +1,5 @@ -import type { Rule, RuleObject, RuleRender } from 'rc-field-form/lib/interface'; +import type { Rule, RuleObject, RuleRender } from '@rc-component/form/lib/interface'; + import { FormProvider } from './context'; import ErrorList from './ErrorList'; import type { ErrorListProps } from './ErrorList'; diff --git a/components/form/interface.ts b/components/form/interface.ts index d153f37222..60a6ee408c 100644 --- a/components/form/interface.ts +++ b/components/form/interface.ts @@ -1,3 +1,8 @@ -export type { InternalNamePath, NamePath, Store, StoreValue } from 'rc-field-form/lib/interface'; +export type { + InternalNamePath, + NamePath, + Store, + StoreValue, +} from '@rc-component/form/lib/interface'; export type { Options as ScrollOptions } from 'scroll-into-view-if-needed'; export type FormLabelAlign = 'left' | 'right'; diff --git a/components/form/util.ts b/components/form/util.ts index 1b18bd552c..37f2a6c05a 100644 --- a/components/form/util.ts +++ b/components/form/util.ts @@ -1,4 +1,4 @@ -import type { Meta } from 'rc-field-form/lib/interface'; +import type { Meta } from '@rc-component/form/lib/interface'; import type { ValidateStatus } from './FormItem'; import type { InternalNamePath } from './interface'; diff --git a/components/form/validateMessagesContext.tsx b/components/form/validateMessagesContext.tsx index 53ca868277..780938bc1a 100644 --- a/components/form/validateMessagesContext.tsx +++ b/components/form/validateMessagesContext.tsx @@ -1,7 +1,7 @@ import { createContext } from 'react'; -import type { ValidateMessages } from 'rc-field-form/lib/interface'; +import type { ValidateMessages } from '@rc-component/form/lib/interface'; // ZombieJ: We export single file here since // ConfigProvider use this which will make loop deps -// to import whole `rc-field-form` +// to import whole `rc-component/form` export default createContext(undefined); diff --git a/components/input/style/index.ts b/components/input/style/index.ts index 20dc670845..e985932ad6 100644 --- a/components/input/style/index.ts +++ b/components/input/style/index.ts @@ -642,6 +642,14 @@ const genGroupStyle: GenerateStyle = (token: InputToken) => { borderEndEndRadius: 0, }, }, + // Fix the issue of input use `addonAfter` param in space compact mode + // https://github.com/ant-design/ant-design/issues/52483 + [`&:not(${componentCls}-compact-first-item)${componentCls}-compact-item`]: { + [`${componentCls}-affix-wrapper`]: { + borderStartStartRadius: 0, + borderEndStartRadius: 0, + }, + }, }, }, }; diff --git a/components/layout/Sider.tsx b/components/layout/Sider.tsx index 4f23ce1fa6..1c0013219b 100644 --- a/components/layout/Sider.tsx +++ b/components/layout/Sider.tsx @@ -6,7 +6,6 @@ import RightOutlined from '@ant-design/icons/RightOutlined'; import omit from '@rc-component/util/lib/omit'; import classNames from 'classnames'; -import isNumeric from '../_util/isNumeric'; import { ConfigContext } from '../config-provider'; import { LayoutContext } from './context'; import useStyle from './style/sider'; @@ -20,6 +19,8 @@ const dimensionMaxMap = { xxl: '1599.98px', }; +const isNumeric = (value: any) => !Number.isNaN(Number.parseFloat(value)) && isFinite(value); + export interface SiderContextProps { siderCollapsed?: boolean; } @@ -152,74 +153,77 @@ const Sider = React.forwardRef((props, ref) => { handleSetCollapsed(!collapsed, 'clickTrigger'); }; - const renderSider = () => { - const divProps = omit(otherProps, ['collapsed']); - const rawWidth = collapsed ? collapsedWidth : width; - // use "px" as fallback unit for width - const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth); - // special trigger when collapsedWidth == 0 - const zeroWidthTrigger = - parseFloat(String(collapsedWidth || 0)) === 0 ? ( - - {trigger || } - - ) : null; - const reverseIcon = (direction === 'rtl') === !reverseArrow; - const iconObj = { - expanded: reverseIcon ? : , - collapsed: reverseIcon ? : , - }; - const status = collapsed ? 'collapsed' : 'expanded'; - const defaultTrigger = iconObj[status]; - const triggerDom = - trigger !== null - ? zeroWidthTrigger || ( -
    - {trigger || defaultTrigger} -
    - ) - : null; + const divProps = omit(otherProps, ['collapsed']); + const rawWidth = collapsed ? collapsedWidth : width; + // use "px" as fallback unit for width + const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth); + // special trigger when collapsedWidth == 0 + const zeroWidthTrigger = + parseFloat(String(collapsedWidth || 0)) === 0 ? ( + + {trigger || } + + ) : null; - const divStyle: React.CSSProperties = { - ...style, - flex: `0 0 ${siderWidth}`, - maxWidth: siderWidth, // Fix width transition bug in IE11 - minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349 - width: siderWidth, - }; + const reverseIcon = (direction === 'rtl') === !reverseArrow; - const siderCls = classNames( - prefixCls, - `${prefixCls}-${theme}`, - { - [`${prefixCls}-collapsed`]: !!collapsed, - [`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger, - [`${prefixCls}-below`]: !!below, - [`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0, - }, - className, - hashId, - cssVarCls, - ); - return ( + const iconObj = { + expanded: reverseIcon ? : , + collapsed: reverseIcon ? : , + }; + + const status = collapsed ? 'collapsed' : 'expanded'; + const defaultTrigger = iconObj[status]; + const triggerDom = + trigger !== null + ? zeroWidthTrigger || ( +
    + {trigger || defaultTrigger} +
    + ) + : null; + + const divStyle: React.CSSProperties = { + ...style, + flex: `0 0 ${siderWidth}`, + maxWidth: siderWidth, // Fix width transition bug in IE11 + minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349 + width: siderWidth, + }; + + const siderCls = classNames( + prefixCls, + `${prefixCls}-${theme}`, + { + [`${prefixCls}-collapsed`]: !!collapsed, + [`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger, + [`${prefixCls}-below`]: !!below, + [`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0, + }, + className, + hashId, + cssVarCls, + ); + + const contextValue = React.useMemo( + () => ({ siderCollapsed: collapsed }), + [collapsed], + ); + + return wrapCSSVar( + - ); - }; - - const contextValue = React.useMemo(() => ({ siderCollapsed: collapsed }), [collapsed]); - - return wrapCSSVar( - {renderSider()}, + , ); }); diff --git a/components/layout/style/sider.ts b/components/layout/style/sider.ts index c800760738..03902a46d2 100644 --- a/components/layout/style/sider.ts +++ b/components/layout/style/sider.ts @@ -19,7 +19,7 @@ const genSiderStyle: GenerateStyle = (token) => { headerHeight, zeroTriggerWidth, zeroTriggerHeight, - borderRadius, + borderRadiusLG, lightSiderBg, lightTriggerColor, lightTriggerBg, @@ -74,7 +74,7 @@ const genSiderStyle: GenerateStyle = (token) => { overflow: 'hidden', }, - [`${componentCls}-zero-width-trigger`]: { + '&-trigger': { position: 'absolute', top: headerHeight, insetInlineEnd: token.calc(zeroTriggerWidth).mul(-1).equal(), @@ -87,11 +87,7 @@ const genSiderStyle: GenerateStyle = (token) => { alignItems: 'center', justifyContent: 'center', background: siderBg, - borderStartStartRadius: 0, - borderStartEndRadius: borderRadius, - borderEndEndRadius: borderRadius, - borderEndStartRadius: 0, - + borderRadius: `0 ${unit(borderRadiusLG)} ${unit(borderRadiusLG)} 0`, cursor: 'pointer', transition: `background ${motionDurationSlow} ease`, @@ -109,10 +105,7 @@ const genSiderStyle: GenerateStyle = (token) => { '&-right': { insetInlineStart: token.calc(zeroTriggerWidth).mul(-1).equal(), - borderStartStartRadius: borderRadius, - borderStartEndRadius: 0, - borderEndEndRadius: 0, - borderEndStartRadius: borderRadius, + borderRadius: `${unit(borderRadiusLG)} 0 0 ${unit(borderRadiusLG)}`, }, }, }, diff --git a/components/locale/az_AZ.ts b/components/locale/az_AZ.ts index 7e7c3b7f0c..0c9b4b49fe 100644 --- a/components/locale/az_AZ.ts +++ b/components/locale/az_AZ.ts @@ -24,7 +24,7 @@ const localeValues: Locale = { selectAll: 'Cari səhifəni seç', selectInvert: 'Mövcud səhifənin elementlərinin sırasını tərs çevir', filterEmptyText: 'Filter yoxdur', - filterCheckall: 'Bütün maddələri seç', + filterCheckAll: 'Bütün maddələri seç', filterSearchPlaceholder: 'Filterlərdə axtar', selectNone: 'Bütün məlumatı sil', selectionAll: 'Bütün məlumatı seç', diff --git a/components/locale/by_BY.ts b/components/locale/by_BY.ts index 8028cbfa9f..41be77fceb 100644 --- a/components/locale/by_BY.ts +++ b/components/locale/by_BY.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Скінуць', filterEmptyText: 'Без фільтраў', - filterCheckall: 'Выбраць усё', + filterCheckAll: 'Выбраць усё', filterSearchPlaceholder: 'Пошук фільтраў', emptyText: 'Няма даных', selectAll: 'Выбраць усё', diff --git a/components/locale/cs_CZ.ts b/components/locale/cs_CZ.ts index c5372056f4..b58d89847c 100644 --- a/components/locale/cs_CZ.ts +++ b/components/locale/cs_CZ.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'Potvrdit', filterReset: 'Obnovit', filterEmptyText: 'Žádné filtry', - filterCheckall: 'Vybrat všechny položky', + filterCheckAll: 'Vybrat všechny položky', filterSearchPlaceholder: 'Vyhledat ve filtrech', emptyText: 'Žádná data', selectAll: 'Vybrat všechny řádky na současné stránce', diff --git a/components/locale/de_DE.ts b/components/locale/de_DE.ts index 75ecae8e4a..fef49bd473 100644 --- a/components/locale/de_DE.ts +++ b/components/locale/de_DE.ts @@ -22,7 +22,7 @@ const localeValues: Locale = { filterReset: 'Zurücksetzen', filterEmptyText: 'Keine Filter', filterSearchPlaceholder: 'Suche in Filtern', - filterCheckall: 'Alle auswählen', + filterCheckAll: 'Alle auswählen', selectAll: 'Selektiere Alle', selectInvert: 'Selektion Invertieren', selectionAll: 'Wählen Sie alle Daten aus', diff --git a/components/locale/el_GR.ts b/components/locale/el_GR.ts index b2f139dddc..a4b1d955c7 100644 --- a/components/locale/el_GR.ts +++ b/components/locale/el_GR.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'ΟΚ', filterReset: 'Επαναφορά', filterEmptyText: 'Χωρίς φίλτρα', - filterCheckall: 'Επιλογή όλων', + filterCheckAll: 'Επιλογή όλων', filterSearchPlaceholder: 'Αναζήτηση στα φίλτρα', emptyText: 'Δεν υπάρχουν δεδομένα', selectAll: 'Επιλογή τρέχουσας σελίδας', diff --git a/components/locale/en_GB.ts b/components/locale/en_GB.ts index 316d390668..2e7bf4af57 100644 --- a/components/locale/en_GB.ts +++ b/components/locale/en_GB.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Reset', filterEmptyText: 'No filters', - filterCheckall: 'Select all items', + filterCheckAll: 'Select all items', filterSearchPlaceholder: 'Search in filters', emptyText: 'No data', selectAll: 'Select current page', diff --git a/components/locale/en_US.ts b/components/locale/en_US.ts index ee9428e31f..f733748e55 100644 --- a/components/locale/en_US.ts +++ b/components/locale/en_US.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Reset', filterEmptyText: 'No filters', - filterCheckall: 'Select all items', + filterCheckAll: 'Select all items', filterSearchPlaceholder: 'Search in filters', emptyText: 'No data', selectAll: 'Select current page', diff --git a/components/locale/es_ES.ts b/components/locale/es_ES.ts index 2afb8396d0..e85c58e865 100644 --- a/components/locale/es_ES.ts +++ b/components/locale/es_ES.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'Aceptar', filterReset: 'Reiniciar', filterEmptyText: 'Sin filtros', - filterCheckall: 'Seleccionar todo', + filterCheckAll: 'Seleccionar todo', filterSearchPlaceholder: 'Buscar en filtros', emptyText: 'Sin datos', selectAll: 'Seleccionar todo', diff --git a/components/locale/et_EE.ts b/components/locale/et_EE.ts index 8866848600..fe10bfbc76 100644 --- a/components/locale/et_EE.ts +++ b/components/locale/et_EE.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Nulli', filterEmptyText: 'Filtreid pole', - filterCheckall: 'Vali kõik', + filterCheckAll: 'Vali kõik', filterSearchPlaceholder: 'Otsi filtritest', emptyText: 'Andmed puuduvad', selectAll: 'Vali kõik', diff --git a/components/locale/eu_ES.ts b/components/locale/eu_ES.ts index e20d1c56b2..7af856608a 100644 --- a/components/locale/eu_ES.ts +++ b/components/locale/eu_ES.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'Onartu', filterReset: 'Garbitu', filterEmptyText: 'Iragazkirik gabe', - filterCheckall: 'Hautatu dena', + filterCheckAll: 'Hautatu dena', filterSearchPlaceholder: 'Bilatu iragazkietan', emptyText: 'Daturik gabe', selectAll: 'Hautatu dena', diff --git a/components/locale/fa_IR.ts b/components/locale/fa_IR.ts index e40895a709..4c6e67d6fd 100644 --- a/components/locale/fa_IR.ts +++ b/components/locale/fa_IR.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'تایید', filterReset: 'پاک کردن', filterEmptyText: 'بدون فیلتر', - filterCheckall: 'انتخاب همه‌ی موارد', + filterCheckAll: 'انتخاب همه‌ی موارد', filterSearchPlaceholder: 'جستجو در فیلترها', emptyText: 'بدون داده', selectAll: 'انتخاب صفحه‌ی کنونی', diff --git a/components/locale/fr_BE.ts b/components/locale/fr_BE.ts index e151c968e5..d63654d7b6 100644 --- a/components/locale/fr_BE.ts +++ b/components/locale/fr_BE.ts @@ -18,7 +18,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Réinitialiser', filterEmptyText: 'Aucun filtre', - filterCheckall: 'Tout sélectionner', + filterCheckAll: 'Tout sélectionner', filterSearchPlaceholder: 'Chercher dans les filtres', emptyText: 'Aucune donnée', selectAll: 'Sélectionner la page actuelle', diff --git a/components/locale/fr_CA.ts b/components/locale/fr_CA.ts index 8f764ff55a..76d9af675f 100644 --- a/components/locale/fr_CA.ts +++ b/components/locale/fr_CA.ts @@ -18,7 +18,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Réinitialiser', filterEmptyText: 'Aucun filtre', - filterCheckall: 'Tout sélectionner', + filterCheckAll: 'Tout sélectionner', filterSearchPlaceholder: 'Chercher dans les filtres', emptyText: 'Aucune donnée', selectAll: 'Sélectionner la page actuelle', diff --git a/components/locale/fr_FR.ts b/components/locale/fr_FR.ts index fb8f3e5a19..cf5de2664f 100644 --- a/components/locale/fr_FR.ts +++ b/components/locale/fr_FR.ts @@ -18,7 +18,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Réinitialiser', filterEmptyText: 'Aucun filtre', - filterCheckall: 'Tout sélectionner', + filterCheckAll: 'Tout sélectionner', filterSearchPlaceholder: 'Chercher dans les filtres', emptyText: 'Aucune donnée', selectAll: 'Sélectionner la page actuelle', diff --git a/components/locale/id_ID.ts b/components/locale/id_ID.ts index b4b22b717f..c293837021 100644 --- a/components/locale/id_ID.ts +++ b/components/locale/id_ID.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Reset', filterEmptyText: 'Tidak ada filter', - filterCheckall: 'Pilih semua item', + filterCheckAll: 'Pilih semua item', filterSearchPlaceholder: 'Cari di filter', emptyText: 'Tidak ada data', selectAll: 'Pilih halaman saat ini', diff --git a/components/locale/index.tsx b/components/locale/index.tsx index 7372a72555..54fcc20666 100644 --- a/components/locale/index.tsx +++ b/components/locale/index.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { ValidateMessages } from 'rc-field-form/lib/interface'; +import type { ValidateMessages } from '@rc-component/form/lib/interface'; import { devUseWarning } from '../_util/warning'; import type { PickerLocale as DatePickerLocale } from '../date-picker/generatePicker'; diff --git a/components/locale/it_IT.ts b/components/locale/it_IT.ts index d81460f100..077fbd2e31 100644 --- a/components/locale/it_IT.ts +++ b/components/locale/it_IT.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Reset', filterEmptyText: 'Senza filtri', - filterCheckall: 'Seleziona tutti', + filterCheckAll: 'Seleziona tutti', filterSearchPlaceholder: 'Cerca nei filtri', emptyText: 'Senza dati', selectAll: 'Seleziona pagina corrente', diff --git a/components/locale/ja_JP.ts b/components/locale/ja_JP.ts index 02fe1de1e3..6bbaf6c6f4 100644 --- a/components/locale/ja_JP.ts +++ b/components/locale/ja_JP.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'リセット', filterEmptyText: 'フィルターなし', - filterCheckall: 'すべてを選択', + filterCheckAll: 'すべてを選択', filterSearchPlaceholder: 'フィルターで検索', emptyText: 'データなし', selectAll: 'ページ単位で選択', diff --git a/components/locale/kn_IN.ts b/components/locale/kn_IN.ts index 4b8606c51c..e859bf558d 100644 --- a/components/locale/kn_IN.ts +++ b/components/locale/kn_IN.ts @@ -26,7 +26,7 @@ const localeValues: Locale = { selectInvert: 'ಪ್ರಸ್ತುತ ಪುಟವನ್ನು ತಿರುಗಿಸಿ', sortTitle: 'ವಿಂಗಡಿಸಿ', filterEmptyText: 'ಫಿಲ್ಟರ್ ಇಲ್ಲ', - filterCheckall: 'ಎಲ್ಲಾ ಐಟಂಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ', + filterCheckAll: 'ಎಲ್ಲಾ ಐಟಂಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ', filterSearchPlaceholder: 'ಫಿಲ್ಟರ್‌ಗಳೊಂದಿಗೆ ಹುಡುಕಿ', selectNone: 'ಯಾವುದನ್ನೂ ಆಯ್ಕೆ ಮಾಡಬೇಡಿ', selectionAll: 'ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಆಯ್ಕೆಮಾಡಿ', diff --git a/components/locale/ko_KR.ts b/components/locale/ko_KR.ts index e97f913830..33d1213960 100644 --- a/components/locale/ko_KR.ts +++ b/components/locale/ko_KR.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: '확인', filterReset: '초기화', filterEmptyText: '필터 없음', - filterCheckall: '전체 선택', + filterCheckAll: '전체 선택', filterSearchPlaceholder: '필터 검색', emptyText: '데이터 없음', selectAll: '전체 선택', diff --git a/components/locale/lt_LT.ts b/components/locale/lt_LT.ts index 66050e0d2e..f2c63687d3 100644 --- a/components/locale/lt_LT.ts +++ b/components/locale/lt_LT.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'Gerai', filterReset: 'Atstatyti', filterEmptyText: 'Be filtrų', - filterCheckall: 'Pasirinkti visus', + filterCheckAll: 'Pasirinkti visus', filterSearchPlaceholder: 'Ieškoti filtruose', emptyText: 'Nėra duomenų', selectAll: 'Pasirinkti viską', diff --git a/components/locale/mn_MN.ts b/components/locale/mn_MN.ts index 72055c754c..4622eeb53f 100644 --- a/components/locale/mn_MN.ts +++ b/components/locale/mn_MN.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'Тийм', filterReset: 'Цэвэрлэх', filterEmptyText: 'Шүүлтүүр байхгүй', - filterCheckall: 'Бүх зүйлийг сонгоно уу', + filterCheckAll: 'Бүх зүйлийг сонгоно уу', filterSearchPlaceholder: 'Шүүлтүүрээс хайх', emptyText: 'Өгөгдөл алга', selectAll: 'Бүгдийг сонгох', diff --git a/components/locale/ms_MY.ts b/components/locale/ms_MY.ts index c05bb22d23..c2729238dd 100644 --- a/components/locale/ms_MY.ts +++ b/components/locale/ms_MY.ts @@ -24,7 +24,7 @@ const localeValues: Locale = { selectAll: 'Pilih Semua', selectInvert: 'Terbalikkan', filterEmptyText: 'Tiada Saringan', - filterCheckall: 'Semak Semua', + filterCheckAll: 'Semak Semua', filterSearchPlaceholder: 'Cari', selectNone: 'Kosong Semua', selectionAll: 'Semua Data', diff --git a/components/locale/my_MM.ts b/components/locale/my_MM.ts index 55d8b8765a..ddea3ebfd6 100644 --- a/components/locale/my_MM.ts +++ b/components/locale/my_MM.ts @@ -22,7 +22,7 @@ const localeValues: Locale = { filterConfirm: 'အိုကေ', filterReset: 'ပြန်လည်သတ်မှတ်ပါ။', filterEmptyText: 'စစ်ထုတ်မှုများမရှိပါ။', - filterCheckall: 'ပစ္စည်းအားလုံးကို ရွေးပါ။', + filterCheckAll: 'ပစ္စည်းအားလုံးကို ရွေးပါ။', filterSearchPlaceholder: 'စစ်ထုတ်မှုများတွင် ရှာဖွေပါ။', selectAll: 'လက်ရှိစာမျက်နှာကို ရွေးပါ။', selectInvert: 'လက်ရှိစာမျက်နှာကို ပြောင်းလိုက်ပါ။', diff --git a/components/locale/ne_NP.ts b/components/locale/ne_NP.ts index 6e9d98b81d..318c68ea9b 100644 --- a/components/locale/ne_NP.ts +++ b/components/locale/ne_NP.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'हो', filterReset: 'रीसेट', filterEmptyText: 'कुनै फिल्टर छैन', - filterCheckall: 'सबै छान्नु', + filterCheckAll: 'सबै छान्नु', filterSearchPlaceholder: 'फिल्टर भित्र खोज्नुहोस्', emptyText: 'डाटा छैन', selectAll: 'सबै छान्नुुहोस्', diff --git a/components/locale/pl_PL.ts b/components/locale/pl_PL.ts index 5f8b38652a..fcc417f8e9 100644 --- a/components/locale/pl_PL.ts +++ b/components/locale/pl_PL.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Usuń filtry', filterEmptyText: 'Brak filtrów', - filterCheckall: 'Wybierz wszystkie elementy', + filterCheckAll: 'Wybierz wszystkie elementy', filterSearchPlaceholder: 'Szukaj w filtrach', emptyText: 'Brak danych', selectAll: 'Zaznacz bieżącą stronę', diff --git a/components/locale/pt_BR.ts b/components/locale/pt_BR.ts index 81666d5e0d..1a8039df00 100644 --- a/components/locale/pt_BR.ts +++ b/components/locale/pt_BR.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Resetar', filterEmptyText: 'Sem filtros', - filterCheckall: 'Selecionar todos os itens', + filterCheckAll: 'Selecionar todos os itens', filterSearchPlaceholder: 'Pesquisar nos filtros', emptyText: 'Sem conteúdo', selectAll: 'Selecionar página atual', diff --git a/components/locale/pt_PT.ts b/components/locale/pt_PT.ts index 4505468592..7df081f06f 100644 --- a/components/locale/pt_PT.ts +++ b/components/locale/pt_PT.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'Aplicar', filterReset: 'Repor', filterEmptyText: 'Sem filtros', - filterCheckall: 'Selecionar todos os itens', + filterCheckAll: 'Selecionar todos os itens', filterSearchPlaceholder: 'Pesquisar nos filtros', emptyText: 'Sem dados', selectAll: 'Selecionar página atual', diff --git a/components/locale/ru_RU.ts b/components/locale/ru_RU.ts index 89385f5075..2c5814ee46 100644 --- a/components/locale/ru_RU.ts +++ b/components/locale/ru_RU.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Сбросить', filterEmptyText: 'Без фильтров', - filterCheckall: 'Выбрать все элементы', + filterCheckAll: 'Выбрать все элементы', filterSearchPlaceholder: 'Поиск в фильтрах', emptyText: 'Нет данных', selectAll: 'Выбрать всё', diff --git a/components/locale/si_LK.ts b/components/locale/si_LK.ts index a55a46416b..16344c4e56 100644 --- a/components/locale/si_LK.ts +++ b/components/locale/si_LK.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'හරි', filterReset: 'යළි සකසන්න', filterEmptyText: 'පෙරහන් නැත', - filterCheckall: 'සියළු අථක තෝරන්න', + filterCheckAll: 'සියළු අථක තෝරන්න', filterSearchPlaceholder: 'පෙරහන් තුළ සොයන්න', emptyText: 'දත්ත නැත', selectAll: 'වත්මන් පිටුව තෝරන්න', diff --git a/components/locale/sk_SK.ts b/components/locale/sk_SK.ts index ea2499b03f..33f0fe08ff 100644 --- a/components/locale/sk_SK.ts +++ b/components/locale/sk_SK.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Obnoviť', filterEmptyText: 'Žiadne filtre', - filterCheckall: 'Vyber všetky položky', + filterCheckAll: 'Vyber všetky položky', filterSearchPlaceholder: 'Vyhľadaj vo filtroch', emptyText: 'Žiadne dáta', selectAll: 'Označ všetky položky', diff --git a/components/locale/sv_SE.ts b/components/locale/sv_SE.ts index fbb7bed498..a82fe4fa2a 100644 --- a/components/locale/sv_SE.ts +++ b/components/locale/sv_SE.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Återställ', filterEmptyText: 'Inga filter', - filterCheckall: 'Markera alla objekt', + filterCheckAll: 'Markera alla objekt', filterSearchPlaceholder: 'Sök i filter', emptyText: 'Ingen data', selectAll: 'Markera nuvarande sida', diff --git a/components/locale/ta_IN.ts b/components/locale/ta_IN.ts index eab86023fa..059c848d7c 100644 --- a/components/locale/ta_IN.ts +++ b/components/locale/ta_IN.ts @@ -26,7 +26,7 @@ const localeValues: Locale = { selectInvert: 'தலைகீழாக மாற்று', sortTitle: 'தலைப்பை வரிசைப்படுத்தவும்', filterEmptyText: 'No filters', - filterCheckall: 'அனைத்து பொருட்களையும் தேர்ந்தெடுக்கவும்', + filterCheckAll: 'அனைத்து பொருட்களையும் தேர்ந்தெடுக்கவும்', filterSearchPlaceholder: 'வடிப்பான்களில் தேடவும்', expand: 'வரிசையை விரிவாக்கு', collapse: 'வரிசையைச் சுருக்கு', diff --git a/components/locale/th_TH.ts b/components/locale/th_TH.ts index 219078520b..b7cea5933d 100644 --- a/components/locale/th_TH.ts +++ b/components/locale/th_TH.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'ยืนยัน', filterReset: 'รีเซ็ต', filterEmptyText: 'ไม่มีตัวกรอง', - filterCheckall: 'เลือกรายการทั้งหมด', + filterCheckAll: 'เลือกรายการทั้งหมด', filterSearchPlaceholder: 'ค้นหาตัวกรอง', emptyText: 'ไม่มีข้อมูล', selectAll: 'เลือกทั้งหมดในหน้านี้', diff --git a/components/locale/tr_TR.ts b/components/locale/tr_TR.ts index b1c1d3a874..9d80becd7e 100644 --- a/components/locale/tr_TR.ts +++ b/components/locale/tr_TR.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'Tamam', filterReset: 'Sıfırla', filterEmptyText: 'Filtre yok', - filterCheckall: 'Tümünü seç', + filterCheckAll: 'Tümünü seç', selectAll: 'Tüm sayfayı seç', selectInvert: 'Tersini seç', selectionAll: 'Tümünü seç', diff --git a/components/locale/uk_UA.ts b/components/locale/uk_UA.ts index f74d0405b2..5b641d0650 100644 --- a/components/locale/uk_UA.ts +++ b/components/locale/uk_UA.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Скинути', filterEmptyText: 'Фільтри відсутні', - filterCheckall: 'Обрати всі', + filterCheckAll: 'Обрати всі', filterSearchPlaceholder: 'Пошук у фільтрах', emptyText: 'Даних немає', selectAll: 'Обрати всі на сторінці', diff --git a/components/locale/uz_UZ.ts b/components/locale/uz_UZ.ts index e4e28e636b..4d7b305bf9 100644 --- a/components/locale/uz_UZ.ts +++ b/components/locale/uz_UZ.ts @@ -26,7 +26,7 @@ const localeValues: Locale = { filterConfirm: 'OK', filterReset: 'Bekor qilish', filterEmptyText: 'Filtrlarsiz', - filterCheckall: 'Barcha elementlarni tanlash', + filterCheckAll: 'Barcha elementlarni tanlash', filterSearchPlaceholder: 'Filtrlarda qidiruv', emptyText: "Ma'lumotlar topilmadi", selectAll: 'Barchasini tanlash', diff --git a/components/locale/vi_VN.ts b/components/locale/vi_VN.ts index 0a4d660334..5d64545d91 100644 --- a/components/locale/vi_VN.ts +++ b/components/locale/vi_VN.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: 'Đồng ý', filterReset: 'Bỏ lọc', filterEmptyText: 'Không có bộ lọc', - filterCheckall: 'Chọn tất cả', + filterCheckAll: 'Chọn tất cả', filterSearchPlaceholder: 'Tìm kiếm bộ lọc', emptyText: 'Trống', selectAll: 'Chọn tất cả', diff --git a/components/locale/zh_CN.ts b/components/locale/zh_CN.ts index 5c4897ef6b..6edc68071a 100644 --- a/components/locale/zh_CN.ts +++ b/components/locale/zh_CN.ts @@ -22,7 +22,7 @@ const localeValues: Locale = { filterConfirm: '确定', filterReset: '重置', filterEmptyText: '无筛选项', - filterCheckall: '全选', + filterCheckAll: '全选', filterSearchPlaceholder: '在筛选项中搜索', emptyText: '暂无数据', selectAll: '全选当页', diff --git a/components/locale/zh_HK.ts b/components/locale/zh_HK.ts index c4539d6453..52f7c2768f 100644 --- a/components/locale/zh_HK.ts +++ b/components/locale/zh_HK.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: '確定', filterReset: '重置', filterEmptyText: '無篩選項', - filterCheckall: '全選', + filterCheckAll: '全選', filterSearchPlaceholder: '在篩選項中搜尋', emptyText: '暫無數據', selectAll: '全部選取', diff --git a/components/locale/zh_TW.ts b/components/locale/zh_TW.ts index 7bc6acadea..3b0d61cf44 100644 --- a/components/locale/zh_TW.ts +++ b/components/locale/zh_TW.ts @@ -21,7 +21,7 @@ const localeValues: Locale = { filterConfirm: '確定', filterReset: '重置', filterEmptyText: '無篩選項', - filterCheckall: '全選', + filterCheckAll: '全選', filterSearchPlaceholder: '在篩選項中搜尋', emptyText: '暫無數據', selectAll: '全部選取', diff --git a/components/notification/__tests__/hooks.test.tsx b/components/notification/__tests__/hooks.test.tsx index 38ba2ef229..91ffad9ef6 100644 --- a/components/notification/__tests__/hooks.test.tsx +++ b/components/notification/__tests__/hooks.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { render as testLibRender } from '@testing-library/react'; import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs'; import notification from '..'; @@ -235,4 +236,39 @@ describe('notification.hooks', () => { }); expect(getNoticeCount()).toBe(0); }); + + it('should hide close btn when closeIcon setting to null or false', () => { + const Demo = () => { + const Holder = (className: string, closeIcon?: React.ReactNode) => { + const [api, holder] = notification.useNotification({ closeIcon }); + + React.useEffect(() => { + api.info({ + className, + message: 'Notification Title', + duration: 0, + }); + }, []); + + return holder; + }; + + return ( + <> + {Holder('normal')} + {Holder('custom', Close)} + {Holder('with-null', null)} + {Holder('with-false', false)} + + ); + }; + + // We use origin testing lib here since StrictMode will render multiple times + testLibRender(); + + expect(document.querySelectorAll('.normal .ant-notification-notice-close').length).toBe(1); + expect(document.querySelectorAll('.custom .custom-close-icon').length).toBe(1); + expect(document.querySelectorAll('.with-null .ant-notification-notice-close').length).toBe(0); + expect(document.querySelectorAll('.with-false .ant-notification-notice-close').length).toBe(0); + }); }); diff --git a/components/notification/interface.ts b/components/notification/interface.ts index 6bd9e143a4..0ec5e337e8 100644 --- a/components/notification/interface.ts +++ b/components/notification/interface.ts @@ -78,4 +78,5 @@ export interface NotificationConfig { duration?: number; showProgress?: boolean; pauseOnHover?: boolean; + closeIcon?: React.ReactNode; } diff --git a/components/notification/style/stack.ts b/components/notification/style/stack.ts index 909ded1fb2..6b79de5468 100644 --- a/components/notification/style/stack.ts +++ b/components/notification/style/stack.ts @@ -74,7 +74,8 @@ const genStackStyle: GenerateStyle = (token) => { return { [`${componentCls}-stack`]: { [`& > ${componentCls}-notice-wrapper`]: { - transition: `all ${token.motionDurationSlow}, backdrop-filter 0s`, + transition: `transform ${token.motionDurationSlow}, backdrop-filter 0s`, + willChange: 'transform, opacity', position: 'absolute', ...genStackChildrenStyle(token), diff --git a/components/notification/useNotification.tsx b/components/notification/useNotification.tsx index cc24b035bd..9c140e7ea4 100644 --- a/components/notification/useNotification.tsx +++ b/components/notification/useNotification.tsx @@ -17,7 +17,7 @@ import type { } from './interface'; import { getCloseIcon, PureContent } from './PurePanel'; import useStyle from './style'; -import { getMotion, getPlacementStyle } from './util'; +import { getMotion, getPlacementStyle, getCloseIconConfig } from './util'; const DEFAULT_OFFSET = 24; const DEFAULT_DURATION = 4.5; @@ -158,7 +158,7 @@ export function useInternalNotification( const realCloseIcon = getCloseIcon( noticePrefixCls, - typeof closeIcon !== 'undefined' ? closeIcon : notification?.closeIcon, + getCloseIconConfig(closeIcon, notificationConfig, notification), ); return originOpen({ diff --git a/components/notification/util.ts b/components/notification/util.ts index 3dcacac69b..efb43c50fa 100644 --- a/components/notification/util.ts +++ b/components/notification/util.ts @@ -1,7 +1,8 @@ import type * as React from 'react'; import type { CSSMotionProps } from 'rc-motion'; -import type { NotificationPlacement } from './interface'; +import type { NotificationConfig, NotificationPlacement } from './interface'; +import type { NotificationConfig as CPNotificationConfig } from '../config-provider/context'; export function getPlacementStyle(placement: NotificationPlacement, top: number, bottom: number) { let style: React.CSSProperties; @@ -67,3 +68,17 @@ export function getMotion(prefixCls: string): CSSMotionProps { motionName: `${prefixCls}-fade`, }; } + +export function getCloseIconConfig( + closeIcon: React.ReactNode, + notificationConfig?: NotificationConfig, + notification?: CPNotificationConfig, +) { + if (typeof closeIcon !== 'undefined') { + return closeIcon; + } + if (typeof notificationConfig?.closeIcon !== 'undefined') { + return notificationConfig.closeIcon; + } + return notification?.closeIcon; +} diff --git a/components/popconfirm/__tests__/index.test.tsx b/components/popconfirm/__tests__/index.test.tsx index 35954b0160..7bd7d50e6a 100644 --- a/components/popconfirm/__tests__/index.test.tsx +++ b/components/popconfirm/__tests__/index.test.tsx @@ -6,6 +6,7 @@ import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils'; import Button from '../../button'; +import ConfigProvider from '../../config-provider'; // TODO: Remove this. Mock for React 19 jest.mock('react-dom', () => { @@ -353,4 +354,67 @@ describe('Popconfirm', () => { expect(popconfirmElement.style.backgroundColor).toBe('blue'); expect(popconfirmBodyElement.style.color).toBe('red'); }); + it('ConfigProvider support arrow props', () => { + const TooltipTestComponent = () => { + const [configArrow, setConfigArrow] = React.useState(true); + + return ( + + + +
    target
    +
    +
    + ); + }; + const { container } = render(); + const getTooltipArrow = () => container.querySelector('.ant-popover-arrow'); + const configbtn = container.querySelector('.configArrow'); + + expect(getTooltipArrow()).not.toBeNull(); + fireEvent.click(configbtn!); + expect(getTooltipArrow()).toBeNull(); + }); + it('ConfigProvider with arrow set to false, Tooltip arrow controlled by prop', () => { + const TooltipTestComponent = () => { + const [arrow, setArrow] = React.useState(true); + + return ( + + + +
    target
    +
    +
    + ); + }; + + const { container } = render(); + + const getTooltipArrow = () => container.querySelector('.ant-popover-arrow'); + const toggleArrowBtn = container.querySelector('.toggleArrow'); + + // Initial render, arrow should be visible because Tooltip's arrow prop is true + expect(getTooltipArrow()).not.toBeNull(); + + // Click the toggleArrow button to hide the arrow + fireEvent.click(toggleArrowBtn!); + expect(getTooltipArrow()).toBeNull(); + + // Click the toggleArrow button again to show the arrow + fireEvent.click(toggleArrowBtn!); + expect(getTooltipArrow()).not.toBeNull(); + }); }); diff --git a/components/popconfirm/demo/_semantic.tsx b/components/popconfirm/demo/_semantic.tsx index d56e2eb1fa..9aa75cd017 100644 --- a/components/popconfirm/demo/_semantic.tsx +++ b/components/popconfirm/demo/_semantic.tsx @@ -6,7 +6,7 @@ import useLocale from '../../../.dumi/hooks/useLocale'; const locales = { cn: { - root: '根节点 (包含箭头、内容元素)', + root: '根元素 (包含箭头、内容元素)', body: '内容元素', }, en: { diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx index ea0ce01e8f..940aca1b42 100644 --- a/components/popconfirm/index.tsx +++ b/components/popconfirm/index.tsx @@ -10,6 +10,7 @@ import { ConfigContext } from '../config-provider'; import type { PopoverProps } from '../popover'; import Popover from '../popover'; import type { AbstractTooltipProps, TooltipRef } from '../tooltip'; +import useMergedArrow from '../tooltip/hook/useMergedArrow'; import PurePanel, { Overlay } from './PurePanel'; import useStyle from './style'; @@ -49,6 +50,7 @@ const InternalPopconfirm = React.forwardRef((props, onOpenChange, overlayStyle, styles, + arrow: popconfirmArrow, classNames: popconfirmClassNames, ...restProps } = props; @@ -58,6 +60,7 @@ const InternalPopconfirm = React.forwardRef((props, value: props.open, defaultValue: props.defaultOpen, }); + const mergedArrow = useMergedArrow(popconfirmArrow, popconfirm?.arrow); const settingOpen: PopoverProps['onOpenChange'] = (value, e) => { setOpen(value, true); @@ -96,6 +99,7 @@ const InternalPopconfirm = React.forwardRef((props, return wrapCSSVar( { expect(popoverElement.style.backgroundColor).toBe('blue'); expect(popoverBodyElement.style.color).toBe('red'); }); + it('ConfigProvider support arrow props', () => { + const TooltipTestComponent = () => { + const [configArrow, setConfigArrow] = React.useState(true); + + return ( + + + +
    target
    +
    +
    + ); + }; + const { container } = render(); + const getTooltipArrow = () => container.querySelector('.ant-popover-arrow'); + const configbtn = container.querySelector('.configArrow'); + + expect(getTooltipArrow()).not.toBeNull(); + fireEvent.click(configbtn!); + expect(getTooltipArrow()).toBeNull(); + }); + it('ConfigProvider with arrow set to false, Tooltip arrow controlled by prop', () => { + const TooltipTestComponent = () => { + const [arrow, setArrow] = React.useState(true); + + return ( + + + +
    target
    +
    +
    + ); + }; + + const { container } = render(); + + const getTooltipArrow = () => container.querySelector('.ant-popover-arrow'); + const toggleArrowBtn = container.querySelector('.toggleArrow'); + + // Initial render, arrow should be visible because Tooltip's arrow prop is true + expect(getTooltipArrow()).not.toBeNull(); + + // Click the toggleArrow button to hide the arrow + fireEvent.click(toggleArrowBtn!); + expect(getTooltipArrow()).toBeNull(); + + // Click the toggleArrow button again to show the arrow + fireEvent.click(toggleArrowBtn!); + expect(getTooltipArrow()).not.toBeNull(); + }); }); diff --git a/components/popover/demo/_semantic.tsx b/components/popover/demo/_semantic.tsx index 18a3ed98cf..a3fc2d749a 100644 --- a/components/popover/demo/_semantic.tsx +++ b/components/popover/demo/_semantic.tsx @@ -6,7 +6,7 @@ import useLocale from '../../../.dumi/hooks/useLocale'; const locales = { cn: { - root: '根节点 (包含箭头、内容元素)', + root: '根元素 (包含箭头、内容元素)', body: '内容元素', }, en: { diff --git a/components/popover/index.tsx b/components/popover/index.tsx index 042ae81bf9..93cfd633c5 100644 --- a/components/popover/index.tsx +++ b/components/popover/index.tsx @@ -10,6 +10,7 @@ import { cloneElement } from '../_util/reactNode'; import { ConfigContext } from '../config-provider'; import type { AbstractTooltipProps, TooltipRef } from '../tooltip'; import Tooltip from '../tooltip'; +import useMergedArrow from '../tooltip/hook/useMergedArrow'; import PurePanel, { Overlay } from './PurePanel'; // CSSINJS import useStyle from './style'; @@ -39,13 +40,15 @@ const InternalPopover = React.forwardRef((props, ref) styles, classNames: popoverClassNames, motion, - ...otherProps + arrow: popoverArrow, + ...restProps } = props; const { popover, getPrefixCls } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('popover', customizePrefixCls); const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls); const rootPrefixCls = getPrefixCls(); + const mergedArrow = useMergedArrow(popoverArrow, popover?.arrow); const rootClassNames = classNames( overlayClassName, @@ -84,11 +87,12 @@ const InternalPopover = React.forwardRef((props, ref) return wrapCSSVar(
    +
    +
    + + + + + + $ + + + +
    +
    `; diff --git a/components/space/__tests__/__snapshots__/demo.test.tsx.snap b/components/space/__tests__/__snapshots__/demo.test.tsx.snap index 4d07d13047..652bbd2826 100644 --- a/components/space/__tests__/__snapshots__/demo.test.tsx.snap +++ b/components/space/__tests__/__snapshots__/demo.test.tsx.snap @@ -2040,6 +2040,41 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = ` +
    +
    + + + + + + $ + + + +
    +
    `; diff --git a/components/space/demo/compact.tsx b/components/space/demo/compact.tsx index a33f7e5db0..f4a54bf188 100644 --- a/components/space/demo/compact.tsx +++ b/components/space/demo/compact.tsx @@ -202,6 +202,10 @@ const App: React.FC = () => ( + + + + ); diff --git a/components/splitter/Splitter.tsx b/components/splitter/Splitter.tsx index bc999de226..0d1e33e355 100644 --- a/components/splitter/Splitter.tsx +++ b/components/splitter/Splitter.tsx @@ -89,7 +89,7 @@ const Splitter: React.FC> = (props) => { useSizes(items, containerSize); // ====================== Resizable ======================= - const resizableInfos = useResizable(items, itemPxSizes); + const resizableInfos = useResizable(items, itemPxSizes, isRTL); const [onOffsetStart, onOffsetUpdate, onOffsetEnd, onCollapse, movingIndex] = useResize( items, @@ -97,6 +97,7 @@ const Splitter: React.FC> = (props) => { itemPtgSizes, containerSize, updateSizes, + isRTL, ); // ======================== Events ======================== diff --git a/components/splitter/hooks/useResizable.ts b/components/splitter/hooks/useResizable.ts index 7f1688e654..994b892700 100644 --- a/components/splitter/hooks/useResizable.ts +++ b/components/splitter/hooks/useResizable.ts @@ -8,7 +8,7 @@ export type ResizableInfo = { endCollapsible: boolean; }; -export default function useResizable(items: ItemType[], pxSizes: number[]) { +export default function useResizable(items: ItemType[], pxSizes: number[], isRTL: boolean) { return React.useMemo(() => { const resizeInfos: ResizableInfo[] = []; @@ -52,8 +52,8 @@ export default function useResizable(items: ItemType[], pxSizes: number[]) { resizeInfos[i] = { resizable: mergedResizable, - startCollapsible: !!startCollapsible, - endCollapsible: !!endCollapsible, + startCollapsible: !!(isRTL ? endCollapsible : startCollapsible), + endCollapsible: !!(isRTL ? startCollapsible : endCollapsible), }; } diff --git a/components/splitter/hooks/useResize.ts b/components/splitter/hooks/useResize.ts index abb5164f04..2d6e645c47 100644 --- a/components/splitter/hooks/useResize.ts +++ b/components/splitter/hooks/useResize.ts @@ -13,6 +13,7 @@ export default function useResize( percentSizes: number[], containerSize: number | undefined, updateSizes: (sizes: number[]) => void, + isRTL: boolean, ) { const limitSizes = items.map((item) => [item.min, item.max]); @@ -119,9 +120,10 @@ export default function useResize( // ======================= Collapse ======================= const onCollapse = (index: number, type: 'start' | 'end') => { const currentSizes = getPxSizes(); + const adjustedType = isRTL ? (type === 'start' ? 'end' : 'start') : type; - const currentIndex = type === 'start' ? index : index + 1; - const targetIndex = type === 'start' ? index + 1 : index; + const currentIndex = adjustedType === 'start' ? index : index + 1; + const targetIndex = adjustedType === 'start' ? index + 1 : index; const currentSize = currentSizes[currentIndex]; const targetSize = currentSizes[targetIndex]; diff --git a/components/statistic/demo/_semantic.tsx b/components/statistic/demo/_semantic.tsx index 0747a66aee..1a10cbc3d2 100644 --- a/components/statistic/demo/_semantic.tsx +++ b/components/statistic/demo/_semantic.tsx @@ -7,7 +7,7 @@ import useLocale from '../../../.dumi/hooks/useLocale'; const locales = { cn: { - root: '根节点', + root: '根元素', header: '头部元素', title: '标题元素', content: '内容元素', diff --git a/components/table/hooks/useFilter/FilterDropdown.tsx b/components/table/hooks/useFilter/FilterDropdown.tsx index 53a6545890..0829fc1fbb 100644 --- a/components/table/hooks/useFilter/FilterDropdown.tsx +++ b/components/table/hooks/useFilter/FilterDropdown.tsx @@ -203,6 +203,11 @@ const FilterDropdown = ( deprecatedList.forEach(([deprecatedName, newName]) => { warning.deprecated(!(deprecatedName in column), deprecatedName, newName); }); + warning.deprecated( + !('filterCheckall' in locale), + 'filterCheckall' as 'deprecated', + 'locale.filterCheckAll', + ); } const mergedVisible = @@ -416,7 +421,7 @@ const FilterDropdown = ( className={`${tablePrefixCls}-filter-dropdown-checkall`} onChange={onCheckAll} > - {locale.filterCheckall} + {locale?.filterCheckall ?? locale?.filterCheckAll} ) : null} diff --git a/components/table/interface.ts b/components/table/interface.ts index 8b08885aa1..8e1b7c7548 100644 --- a/components/table/interface.ts +++ b/components/table/interface.ts @@ -43,7 +43,11 @@ export interface TableLocale { filterConfirm?: React.ReactNode; filterReset?: React.ReactNode; filterEmptyText?: React.ReactNode; + /** + * @deprecated Please use `filterCheckAll` instead. + */ filterCheckall?: React.ReactNode; + filterCheckAll?: React.ReactNode; filterSearchPlaceholder?: string; emptyText?: React.ReactNode | (() => React.ReactNode); selectAll?: React.ReactNode; diff --git a/components/tag/demo/component-token.tsx b/components/tag/demo/component-token.tsx index 5b9d4b6f3b..bb7098da81 100644 --- a/components/tag/demo/component-token.tsx +++ b/components/tag/demo/component-token.tsx @@ -4,7 +4,11 @@ import { ConfigProvider, Flex, Tag } from 'antd'; const App: React.FC = () => ( @@ -38,6 +42,9 @@ const App: React.FC = () => ( } color="processing"> processing + + disabled + ); diff --git a/components/tag/style/index.ts b/components/tag/style/index.ts index 3b514b083e..87057c4681 100644 --- a/components/tag/style/index.ts +++ b/components/tag/style/index.ts @@ -39,7 +39,7 @@ const genBaseStyle = (token: TagToken): CSSInterpolation => { color: token.colorTextDisabled, cursor: 'not-allowed', backgroundColor: token.colorBgContainerDisabled, - borderColor: token.colorBorder, + borderColor: token.colorBorderDisabled, a: { cursor: 'not-allowed', pointerEvents: 'none', diff --git a/components/tag/style/presetCmp.ts b/components/tag/style/presetCmp.ts index a0fd940709..b328ff7638 100644 --- a/components/tag/style/presetCmp.ts +++ b/components/tag/style/presetCmp.ts @@ -19,7 +19,7 @@ const genPresetStyle = (token: TagToken) => [`&${token.componentCls}-disabled`]: { color: token.colorTextDisabled, backgroundColor: token.colorBgContainerDisabled, - borderColor: token.colorBorder, + borderColor: token.colorBorderDisabled, }, }, [`&${token.componentCls}-borderless`]: { @@ -31,7 +31,7 @@ const genPresetStyle = (token: TagToken) => [`&${token.componentCls}-disabled`]: { color: token.colorTextDisabled, backgroundColor: token.colorBgContainerDisabled, - borderColor: token.colorBorder, + borderColor: token.colorBorderDisabled, }, }, })); diff --git a/components/tag/style/statusCmp.ts b/components/tag/style/statusCmp.ts index f4bbdd883d..78c56c5eb6 100644 --- a/components/tag/style/statusCmp.ts +++ b/components/tag/style/statusCmp.ts @@ -29,7 +29,7 @@ const genTagStatusStyle = ( [`&${token.componentCls}-disabled`]: { color: token.colorTextDisabled, backgroundColor: token.colorBgContainerDisabled, - borderColor: token.colorBorder, + borderColor: token.colorBorderDisabled, }, }, }; diff --git a/components/theme/context.ts b/components/theme/context.ts index d8225ed3c5..b8779843e8 100644 --- a/components/theme/context.ts +++ b/components/theme/context.ts @@ -1,12 +1,10 @@ import React from 'react'; import type { Theme } from '@ant-design/cssinjs'; -import { createTheme } from '@ant-design/cssinjs'; import type { AliasToken, MapToken, OverrideToken, SeedToken } from './interface'; -import defaultDerivative from './themes/default'; import defaultSeedToken from './themes/seed'; -export const defaultTheme = createTheme(defaultDerivative); +export { default as defaultTheme } from './themes/default/theme'; // ================================ Context ================================= // To ensure snapshot stable. We disable hashed in test env. diff --git a/components/theme/getDesignToken.ts b/components/theme/getDesignToken.ts index 44fedacee9..9ba10f64a3 100644 --- a/components/theme/getDesignToken.ts +++ b/components/theme/getDesignToken.ts @@ -2,12 +2,12 @@ import { createTheme, getComputedToken } from '@ant-design/cssinjs'; import type { ThemeConfig } from '../config-provider/context'; import type { AliasToken } from './interface'; -import defaultDerivative from './themes/default'; +import defaultTheme from './themes/default/theme'; import seedToken from './themes/seed'; import formatToken from './util/alias'; const getDesignToken = (config?: ThemeConfig): AliasToken => { - const theme = config?.algorithm ? createTheme(config.algorithm) : createTheme(defaultDerivative); + const theme = config?.algorithm ? createTheme(config.algorithm) : defaultTheme; const mergedToken = { ...seedToken, ...config?.token, diff --git a/components/theme/interface/maps/colors.ts b/components/theme/interface/maps/colors.ts index 54be256c7c..fe3d1b1480 100644 --- a/components/theme/interface/maps/colors.ts +++ b/components/theme/interface/maps/colors.ts @@ -59,6 +59,14 @@ export interface ColorNeutralMapToken { */ colorBorderSecondary: string; + /** + * @nameZH 禁用态边框颜色 + * @nameEN Disabled state border color + * @desc 控制元素在禁用状态下的边框颜色。 + * @descEN Control the border color of the element in the disabled state. + */ + colorBorderDisabled: string; + // ---------- Fill ---------- // /** @@ -628,5 +636,4 @@ export interface ColorMapToken * @desc 不随主题变化的纯黑色 * @default #0000 */ - // colorBlack: string; } diff --git a/components/theme/themes/dark/colors.ts b/components/theme/themes/dark/colors.ts index afa1e5de70..789f22061d 100644 --- a/components/theme/themes/dark/colors.ts +++ b/components/theme/themes/dark/colors.ts @@ -16,9 +16,6 @@ export const generateColorPalettes: GenerateColorMap = (baseColor: string) => { 8: colors[6], 9: colors[5], 10: colors[4], - // 8: colors[9], - // 9: colors[8], - // 10: colors[7], }; }; @@ -54,6 +51,7 @@ export const generateNeutralColorPalettes: GenerateNeutralColorMap = ( colorBgBlur: getAlphaColor(colorTextBase, 0.04), colorBorder: getSolidColor(colorBgBase, 26), + colorBorderDisabled: getSolidColor(colorBgBase, 26), colorBorderSecondary: getSolidColor(colorBgBase, 19), }; }; diff --git a/components/theme/themes/default/colors.ts b/components/theme/themes/default/colors.ts index 16c1032ddd..5c876968d8 100644 --- a/components/theme/themes/default/colors.ts +++ b/components/theme/themes/default/colors.ts @@ -16,9 +16,6 @@ export const generateColorPalettes: GenerateColorMap = (baseColor: string) => { 8: colors[4], 9: colors[5], 10: colors[6], - // 8: colors[7], - // 9: colors[8], - // 10: colors[9], }; }; @@ -54,6 +51,7 @@ export const generateNeutralColorPalettes: GenerateNeutralColorMap = ( colorBgBlur: 'transparent', colorBorder: getSolidColor(colorBgBase, 15), + colorBorderDisabled: getSolidColor(colorBgBase, 15), colorBorderSecondary: getSolidColor(colorBgBase, 6), }; }; diff --git a/components/theme/themes/default/theme.ts b/components/theme/themes/default/theme.ts new file mode 100644 index 0000000000..3181299f01 --- /dev/null +++ b/components/theme/themes/default/theme.ts @@ -0,0 +1,6 @@ +import { createTheme } from '@ant-design/cssinjs'; +import defaultDerivative from './index'; + +const defaultTheme = createTheme(defaultDerivative); + +export default defaultTheme; diff --git a/components/tooltip/__tests__/tooltip.test.tsx b/components/tooltip/__tests__/tooltip.test.tsx index aabf58b0da..699e6efdf4 100644 --- a/components/tooltip/__tests__/tooltip.test.tsx +++ b/components/tooltip/__tests__/tooltip.test.tsx @@ -8,6 +8,7 @@ import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { fireEvent, render, waitFakeTimer } from '../../../tests/utils'; import Button from '../../button'; +import ConfigProvider from '../../config-provider'; import DatePicker from '../../date-picker'; import Input from '../../input'; import Group from '../../input/Group'; @@ -499,4 +500,67 @@ describe('Tooltip', () => { expect(tooltipElement.style.backgroundColor).toBe('blue'); expect(tooltipBodyElement.style.color).toBe('red'); }); + + it('ConfigProvider support arrow props', () => { + const TooltipTestComponent = () => { + const [configArrow, setConfigArrow] = React.useState(true); + + return ( + + + +
    target
    +
    +
    + ); + }; + const { container } = render(); + const getTooltipArrow = () => container.querySelector('.ant-tooltip-arrow'); + const configbtn = container.querySelector('.configArrow'); + + expect(getTooltipArrow()).not.toBeNull(); + fireEvent.click(configbtn!); + expect(getTooltipArrow()).toBeNull(); + }); + it('ConfigProvider with arrow set to false, Tooltip arrow controlled by prop', () => { + const TooltipTestComponent = () => { + const [arrow, setArrow] = React.useState(true); + + return ( + + + +
    target
    +
    +
    + ); + }; + + const { container } = render(); + const getTooltipArrow = () => container.querySelector('.ant-tooltip-arrow'); + const toggleArrowBtn = container.querySelector('.toggleArrow'); + + // Initial render, arrow should be visible because Tooltip's arrow prop is true + expect(getTooltipArrow()).not.toBeNull(); + + // Click the toggleArrow button to hide the arrow + fireEvent.click(toggleArrowBtn!); + expect(getTooltipArrow()).toBeNull(); + + // Click the toggleArrow button again to show the arrow + fireEvent.click(toggleArrowBtn!); + expect(getTooltipArrow()).not.toBeNull(); + }); }); diff --git a/components/tooltip/demo/_semantic.tsx b/components/tooltip/demo/_semantic.tsx index bcf321e703..8397072faa 100644 --- a/components/tooltip/demo/_semantic.tsx +++ b/components/tooltip/demo/_semantic.tsx @@ -6,7 +6,7 @@ import useLocale from '../../../.dumi/hooks/useLocale'; const locales = { cn: { - root: '根节点 (包含箭头、内容元素)', + root: '根元素 (包含箭头、内容元素)', body: '内容元素', }, en: { diff --git a/components/tooltip/demo/disabled.md b/components/tooltip/demo/disabled.md index 44db81b218..954d32dc42 100644 --- a/components/tooltip/demo/disabled.md +++ b/components/tooltip/demo/disabled.md @@ -1,7 +1,7 @@ ## zh-CN -通过设置 `title=""` 可以禁用 Tooltip。 +通过设置 `title={null}` 或者 `title=""` 可以禁用 Tooltip。 ## en-US -The Tooltip can be disabled by setting `title=""`. +The Tooltip can be disabled by setting `title={null}` or `title=""`. diff --git a/components/tooltip/hook/useMergedArrow.ts b/components/tooltip/hook/useMergedArrow.ts new file mode 100644 index 0000000000..7cee2cef4d --- /dev/null +++ b/components/tooltip/hook/useMergedArrow.ts @@ -0,0 +1,28 @@ +import React from 'react'; + +import { AbstractTooltipProps } from '..'; +import { TooltipConfig } from '../../config-provider/context'; + +interface MergedArrow { + show: boolean; + pointAtCenter?: boolean; +} +const useMergedArrow = ( + providedArrow?: AbstractTooltipProps['arrow'], + providedContextArrow?: TooltipConfig['arrow'], +): MergedArrow => { + const toConfig = (arrow?: boolean | AbstractTooltipProps['arrow']): Partial => + typeof arrow === 'boolean' ? { show: arrow } : arrow || {}; + + return React.useMemo(() => { + const arrowConfig = toConfig(providedArrow); + const contextArrowConfig = toConfig(providedContextArrow); + + return { + ...contextArrowConfig, + ...arrowConfig, + show: arrowConfig.show ?? contextArrowConfig.show ?? true, + }; + }, [providedArrow, providedContextArrow]); +}; +export default useMergedArrow; diff --git a/components/tooltip/index.tsx b/components/tooltip/index.tsx index 2ef63fa21c..aa7032787e 100644 --- a/components/tooltip/index.tsx +++ b/components/tooltip/index.tsx @@ -22,6 +22,7 @@ import { devUseWarning } from '../_util/warning'; import zIndexContext from '../_util/zindexContext'; import { ConfigContext } from '../config-provider'; import { useToken } from '../theme/internal'; +import useMergedArrow from './hook/useMergedArrow'; import PurePanel from './PurePanel'; import useStyle from './style'; import { parseColor } from './util'; @@ -127,16 +128,24 @@ const InternalTooltip = React.forwardRef((props, ref) children, afterOpenChange, destroyTooltipOnHide, - arrow = true, + arrow: tooltipArrow, title, overlay, builtinPlacements, autoAdjustOverflow = true, motion, + getPopupContainer, + placement = 'top', + mouseEnterDelay = 0.1, + mouseLeaveDelay = 0.1, + overlayStyle, + rootClassName, + overlayClassName, + styles, + classNames: tooltipClassNames, + ...restProps } = props; - const mergedShowArrow = !!arrow; - const [, token] = useToken(); const { @@ -145,6 +154,8 @@ const InternalTooltip = React.forwardRef((props, ref) direction, tooltip, } = React.useContext(ConfigContext); + const mergedArrow = useMergedArrow(tooltipArrow, tooltip?.arrow); + const mergedShowArrow = mergedArrow.show; // ============================== Ref =============================== const warning = devUseWarning('Tooltip'); @@ -196,7 +207,7 @@ const InternalTooltip = React.forwardRef((props, ref) return ( builtinPlacements || getPlacements({ - arrowPointAtCenter: typeof arrow === 'object' ? arrow?.pointAtCenter : false, + arrowPointAtCenter: mergedArrow?.pointAtCenter ?? false, autoAdjustOverflow, arrowWidth: mergedShowArrow ? token.sizePopupArrow : 0, borderRadius: token.borderRadius, @@ -204,7 +215,7 @@ const InternalTooltip = React.forwardRef((props, ref) visibleFirst: true, }) ); - }, [arrow, builtinPlacements, token]); + }, [mergedArrow, builtinPlacements, token]); const memoOverlay = React.useMemo(() => { if (title === 0) { @@ -219,19 +230,6 @@ const InternalTooltip = React.forwardRef((props, ref) ); - const { - getPopupContainer, - placement = 'top', - mouseEnterDelay = 0.1, - mouseLeaveDelay = 0.1, - overlayStyle, - rootClassName, - overlayClassName, - styles, - classNames: tooltipClassNames, - ...otherProps - } = props; - const prefixCls = getPrefixCls('tooltip', customizePrefixCls); const rootPrefixCls = getPrefixCls(); @@ -276,11 +274,11 @@ const InternalTooltip = React.forwardRef((props, ref) const bodyClassNames = classNames(tooltip?.classNames?.body, tooltipClassNames?.body); // ============================ zIndex ============================ - const [zIndex, contextZIndex] = useZIndex('Tooltip', otherProps.zIndex); + const [zIndex, contextZIndex] = useZIndex('Tooltip', restProps.zIndex); const content = ( HTMLElement` `HTMLElement` | - | | +| target | Get the element the guide card points to. Empty makes it show in center of screen | `() => HTMLElement` \| `HTMLElement` | - | | | arrow | Whether to show the arrow, including the configuration whether to point to the center of the element | `boolean` `{ pointAtCenter: boolean}` | `true` | | | closeIcon | Customize close icon | `React.ReactNode` | `true` | 5.9.0 | | cover | Displayed pictures or videos | `ReactNode` | - | | diff --git a/components/tour/index.zh-CN.md b/components/tour/index.zh-CN.md index 2f67369588..fd69b994db 100644 --- a/components/tour/index.zh-CN.md +++ b/components/tour/index.zh-CN.md @@ -61,7 +61,7 @@ tag: 5.0.0 | cover | 展示的图片或者视频 | `ReactNode` | - | | | title | 标题 | `ReactNode` | - | | | description | 主要描述部分 | `ReactNode` | - | | -| placement | 引导卡片相对于目标元素的位置 | `center` `left` `leftTop` `leftBottom` `right` `rightTop` `rightBottom` `top` `topLeft` `topRight` `bottom` `bottomLeft` `bottomRight` `bottom` | | | +| placement | 引导卡片相对于目标元素的位置 | `center` `left` `leftTop` `leftBottom` `right` `rightTop` `rightBottom` `top` `topLeft` `topRight` `bottom` `bottomLeft` `bottomRight` | `bottom` | | | onClose | 关闭引导时的回调函数 | `Function` | - | | | mask | 是否启用蒙层,也可传入配置改变蒙层样式和填充色,默认跟随 Tour 的 `mask` 属性 | `boolean \| { style?: React.CSSProperties; color?: string; }` | `true` | | | type | 类型,影响底色与文字颜色 | `default` \| `primary` | `default` | | diff --git a/docs/blog/contributor-development-maintenance-guide.en-US.md b/docs/blog/contributor-development-maintenance-guide.en-US.md index f81ef17dbf..be82e6a4db 100644 --- a/docs/blog/contributor-development-maintenance-guide.en-US.md +++ b/docs/blog/contributor-development-maintenance-guide.en-US.md @@ -80,7 +80,7 @@ Run `npm link "Project name"` in Ant Design Once we have verified, we can open PR to the repo. Noted that link may cause exceptions when running the test command. Therefore, we need to run the following commands locally to delete the package from link. ```bash -npm unlink "rc-field-form" --no-save +npm unlink "@rc-component/form" --no-save npm i ``` diff --git a/docs/blog/contributor-development-maintenance-guide.zh-CN.md b/docs/blog/contributor-development-maintenance-guide.zh-CN.md index 3ed5784892..12a92e1735 100644 --- a/docs/blog/contributor-development-maintenance-guide.zh-CN.md +++ b/docs/blog/contributor-development-maintenance-guide.zh-CN.md @@ -76,7 +76,7 @@ npm i 需要注意的是,link 可能会导致运行 test 命令时产生异常,因此,我们在本地验证完毕后,需要本地运行以下命令删除 link 过来的包: ```bash -npm unlink "rc-field-form" --no-save +npm unlink "@rc-component/form" --no-save npm i ``` diff --git a/docs/react/recommendation.en-US.md b/docs/react/recommendation.en-US.md index b5bc277347..2a9d6c9dd3 100644 --- a/docs/react/recommendation.en-US.md +++ b/docs/react/recommendation.en-US.md @@ -38,7 +38,7 @@ title: Third-Party Libraries | Image Crop | [antd-img-crop](https://github.com/nanxiaobei/antd-img-crop) [react-image-crop](https://github.com/DominicTobias/react-image-crop) | | Keywords highlight | [react-highlight-words](https://github.com/bvaughn/react-highlight-words) | | Text Loop | [react-text-loop-next](https://github.com/samarmohan/react-text-loop-next) [react-fast-marquee](https://github.com/justin-chu/react-fast-marquee) | -| Animation | [framer-motion](https://github.com/framer/motion) [Ant Motion](https://motion.ant.design/components/tween-one) [react-spring](https://github.com/pmndrs/react-spring) | +| Animation | [motion](https://github.com/framer/motion) [Ant Motion](https://motion.ant.design/components/tween-one) [react-spring](https://github.com/pmndrs/react-spring) | | Page Footer | [rc-footer](https://github.com/react-component/footer) | | Number/Currency | [react-countup](https://www.npmjs.com/package/react-countup) [react-number-format](https://github.com/s-yadav/react-number-format) [react-currency-input-field](https://github.com/cchanxzy/react-currency-input-field) | | Application Frameworks | [umi](https://github.com/umijs/umi/) [remix](https://github.com/remix-run/remix) [refine](https://github.com/pankod/refine) | @@ -46,6 +46,7 @@ title: Third-Party Libraries | Phone Input | [react-phone-number-input](https://gitlab.com/catamphetamine/react-phone-number-input) [antd-phone-input](https://github.com/ArtyomVancyan/antd-phone-input/) | | AI Chat | [pro-chat](https://github.com/ant-design/pro-chat) | | PDF | [react-pdf](https://github.com/diegomura/react-pdf) [@react-pdf/renderer](https://github.com/diegomura/react-pdf) | +| React Gesture | [use-gesture](https://use-gesture.netlify.app) | ## Products we are using ✨ diff --git a/docs/react/recommendation.zh-CN.md b/docs/react/recommendation.zh-CN.md index ba13876496..ba2c180df4 100644 --- a/docs/react/recommendation.zh-CN.md +++ b/docs/react/recommendation.zh-CN.md @@ -39,7 +39,7 @@ title: 社区精选组件 | 图片裁切 | [antd-img-crop](https://github.com/nanxiaobei/antd-img-crop) [react-image-crop](https://github.com/DominicTobias/react-image-crop) | | 关键字高亮 | [react-highlight-words](https://github.com/bvaughn/react-highlight-words) | | 文字轮播 | [react-text-loop-next](https://github.com/samarmohan/react-text-loop-next) [react-fast-marquee](https://github.com/justin-chu/react-fast-marquee) | -| 动画 | [framer-motion](https://github.com/framer/motion) [Ant Motion](https://motion.ant.design/components/tween-one) [react-spring](https://github.com/pmndrs/react-spring) | +| 动画 | [motion](https://github.com/framer/motion) [Ant Motion](https://motion.ant.design/components/tween-one) [react-spring](https://github.com/pmndrs/react-spring) | | 页脚 | [rc-footer](https://github.com/react-component/footer) | | 数字/金额 | [react-number-format](https://github.com/s-yadav/react-number-format) [react-currency-input-field](https://github.com/cchanxzy/react-currency-input-field) | | 移动端探测 | [react-device-detect](https://github.com/duskload/react-device-detect) | @@ -48,6 +48,7 @@ title: 社区精选组件 | 电话输入 | [react-phone-number-input](https://gitlab.com/catamphetamine/react-phone-number-input) [antd-phone-input](https://github.com/ArtyomVancyan/antd-phone-input/) | | AI 对话界面 | [pro-chat](https://github.com/ant-design/pro-chat) | | PDF | [react-pdf](https://github.com/diegomura/react-pdf) [@react-pdf/renderer](https://github.com/diegomura/react-pdf) | +| React 手势库 | [use-gesture](https://use-gesture.netlify.app) | ## 推荐产品 ✨ diff --git a/docs/react/server-side-rendering.en-US.md b/docs/react/server-side-rendering.en-US.md index f15c28c048..cc315e415e 100644 --- a/docs/react/server-side-rendering.en-US.md +++ b/docs/react/server-side-rendering.en-US.md @@ -243,16 +243,15 @@ import path from 'path'; import { extractStyle } from '@ant-design/cssinjs'; import type Entity from '@ant-design/cssinjs/lib/Cache'; -export type DoExtraStyleOptions = { +export interface DoExtraStyleOptions { cache: Entity; dir?: string; baseFileName?: string; -}; -export function doExtraStyle({ - cache, - dir = 'antd-output', - baseFileName = 'antd.min', -}: DoExtraStyleOptions) { +} + +export const doExtraStyle = (opts: DoExtraStyleOptions) => { + const { cache, dir = 'antd-output', baseFileName = 'antd.min' } = opts; + const baseDir = path.resolve(__dirname, '../../static/css'); const outputCssPath = path.join(baseDir, dir); @@ -262,7 +261,10 @@ export function doExtraStyle({ } const css = extractStyle(cache, true); - if (!css) return ''; + + if (!css) { + return ''; + } const md5 = createHash('md5'); const hash = md5.update(css).digest('hex'); @@ -271,12 +273,14 @@ export function doExtraStyle({ const res = `_next/static/css/${dir}/${fileName}`; - if (fs.existsSync(fullpath)) return res; + if (fs.existsSync(fullpath)) { + return res; + } fs.writeFileSync(fullpath, css); return res; -} +}; ``` Export on demand using the above tools in `_document.tsx` diff --git a/docs/react/server-side-rendering.zh-CN.md b/docs/react/server-side-rendering.zh-CN.md index 41869c6965..6c38da1afb 100644 --- a/docs/react/server-side-rendering.zh-CN.md +++ b/docs/react/server-side-rendering.zh-CN.md @@ -243,16 +243,15 @@ import path from 'path'; import { extractStyle } from '@ant-design/cssinjs'; import type Entity from '@ant-design/cssinjs/lib/Cache'; -export type DoExtraStyleOptions = { +export interface DoExtraStyleOptions { cache: Entity; dir?: string; baseFileName?: string; -}; -export function doExtraStyle({ - cache, - dir = 'antd-output', - baseFileName = 'antd.min', -}: DoExtraStyleOptions) { +} + +export const doExtraStyle = (opts: DoExtraStyleOptions) => { + const { cache, dir = 'antd-output', baseFileName = 'antd.min' } = opts; + const baseDir = path.resolve(__dirname, '../../static/css'); const outputCssPath = path.join(baseDir, dir); @@ -262,7 +261,10 @@ export function doExtraStyle({ } const css = extractStyle(cache, true); - if (!css) return ''; + + if (!css) { + return ''; + } const md5 = createHash('md5'); const hash = md5.update(css).digest('hex'); @@ -271,12 +273,14 @@ export function doExtraStyle({ const res = `_next/static/css/${dir}/${fileName}`; - if (fs.existsSync(fullpath)) return res; + if (fs.existsSync(fullpath)) { + return res; + } fs.writeFileSync(fullpath, css); return res; -} +}; ``` 在 `_document.tsx` 中使用上述工具进行按需导出: diff --git a/docs/react/v5-for-19.en-US.md b/docs/react/v5-for-19.en-US.md index 8e9b7d9f61..a2a4bf3436 100644 --- a/docs/react/v5-for-19.en-US.md +++ b/docs/react/v5-for-19.en-US.md @@ -28,9 +28,7 @@ You can choose one of the following methods, and it is recommended to use the co Install the compatibility package -```bash -npm install --save-dev @ant-design/v5-patch-for-react-19 -``` + Import the compatibility package at the application entry diff --git a/docs/react/v5-for-19.zh-CN.md b/docs/react/v5-for-19.zh-CN.md index 8057ee10cf..fc6ce9b4a3 100644 --- a/docs/react/v5-for-19.zh-CN.md +++ b/docs/react/v5-for-19.zh-CN.md @@ -28,9 +28,7 @@ antd v5 默认兼容 React 16 ~ 18 版本,对于 React 19 版本,可以使 安装兼容包 -```bash -npm install --save-dev @ant-design/v5-patch-for-react-19 -``` + 在应用入口处引入兼容包 diff --git a/package.json b/package.json index cfcfcfefaf..1f49e65730 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "5.23.1", + "version": "5.23.2", "description": "An enterprise-class UI design language and React components implementation", "license": "MIT", "funding": { @@ -113,6 +113,7 @@ "@babel/runtime": "^7.26.0", "@rc-component/collapse": "~1.0.1", "@rc-component/color-picker": "~2.0.1", + "@rc-component/form": "~1.0.0", "@rc-component/mutate-observer": "^1.1.0", "@rc-component/qrcode": "~1.0.0", "@rc-component/segmented": "~1.0.0", @@ -129,7 +130,6 @@ "rc-dialog": "~9.6.0", "rc-drawer": "~8.0.0", "rc-dropdown": "~4.2.1", - "rc-field-form": "~2.7.0", "rc-image": "~7.11.0", "rc-input": "~1.7.2", "rc-input-number": "~9.4.0", @@ -142,7 +142,7 @@ "rc-progress": "~4.0.0", "rc-rate": "~2.13.0", "rc-resize-observer": "^1.4.3", - "rc-select": "~14.16.5", + "rc-select": "~14.16.6", "rc-slider": "~11.1.8", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", @@ -298,7 +298,7 @@ "react-intersection-observer": "^9.13.1", "react-resizable": "^3.0.5", "react-router-dom": "^7.0.1", - "react-scan": "^0.0.54", + "react-scan": "^0.1.0", "react-sticky-box": "^2.0.5", "regenerator-runtime": "^0.14.1", "rehype-stringify": "^10.0.1",