diff --git a/.dumi/pages/index/components/BannerRecommends.tsx b/.dumi/pages/index/components/BannerRecommends.tsx index d80d886f9178..8c6dfc16c2bd 100644 --- a/.dumi/pages/index/components/BannerRecommends.tsx +++ b/.dumi/pages/index/components/BannerRecommends.tsx @@ -36,6 +36,7 @@ const useStyle = createStyles(({ token, css, cx }) => { cardItem: css` &:hover { box-shadow: ${token.boxShadowCard}; + border-color: transparent; } `, sliderItem: css` diff --git a/.dumi/theme/builtins/Audio/index.tsx b/.dumi/theme/builtins/Audio/index.tsx index a1ae83fd5dbb..288bd14cfdc5 100644 --- a/.dumi/theme/builtins/Audio/index.tsx +++ b/.dumi/theme/builtins/Audio/index.tsx @@ -1,13 +1,48 @@ import React from 'react'; import { SoundOutlined } from '@ant-design/icons'; +import { createStyles } from 'antd-style'; -const Audio: React.FC> = ({ domId, children }) => { +const useStyle = createStyles(({ css, token }) => { + const { paddingXXS, fontSizeXL, motionDurationSlow, colorLink, colorLinkHover, colorLinkActive } = + token; + return { + playBtn: css` + display: inline-flex; + justify-content: center; + align-items: center; + column-gap: ${paddingXXS}px; + margin: 0; + `, + icon: css` + font-size: ${fontSizeXL}px; + color: ${colorLink}; + transition: all ${motionDurationSlow}; + &:hover { + color: ${colorLinkHover}; + } + &:active { + color: ${colorLinkActive}; + } + `, + }; +}); + +interface AudioProps { + id?: string; +} + +const AudioControl: React.FC> = ({ id, children }) => { + const { styles } = useStyle(); + const onClick: React.MouseEventHandler = () => { + const audio = document.querySelector(`#${id}`); + audio?.play(); + }; return ( - document.querySelector(`#${domId}`)?.play()}> + {children} - + ); }; -export default Audio; +export default AudioControl; diff --git a/.dumi/theme/builtins/ComponentMeta/index.tsx b/.dumi/theme/builtins/ComponentMeta/index.tsx index 23a6effc7f38..9d70d5abf437 100644 --- a/.dumi/theme/builtins/ComponentMeta/index.tsx +++ b/.dumi/theme/builtins/ComponentMeta/index.tsx @@ -123,7 +123,7 @@ const ComponentMeta: React.FC = (props) => { }, [component, source]); const transformComponentName = (componentName: string) => { - if (componentName === 'Notifiction' || componentName === 'Message') { + if (componentName === 'Notification' || componentName === 'Message') { return componentName.toLowerCase(); } return componentName; diff --git a/.dumi/theme/builtins/DemoWrapper/index.tsx b/.dumi/theme/builtins/DemoWrapper/index.tsx index 8b125ab3fa39..85726b881b32 100644 --- a/.dumi/theme/builtins/DemoWrapper/index.tsx +++ b/.dumi/theme/builtins/DemoWrapper/index.tsx @@ -1,13 +1,6 @@ import React, { useContext } from 'react'; -import { - BugFilled, - BugOutlined, - CodeFilled, - CodeOutlined, - ExperimentFilled, - ExperimentOutlined, -} from '@ant-design/icons'; -import { ConfigProvider, Tooltip } from 'antd'; +import { BugOutlined, CodeOutlined, ExperimentOutlined } from '@ant-design/icons'; +import { ConfigProvider, Tooltip, Button } from 'antd'; import classNames from 'classnames'; import { DumiDemoGrid, FormattedMessage } from 'dumi'; @@ -33,10 +26,6 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => { const [expandAll, setExpandAll] = useLayoutState(false); const [enableCssVar, setEnableCssVar] = useLayoutState(true); - const expandTriggerClass = classNames('code-box-expand-trigger', { - 'code-box-expand-trigger-active': expandAll, - }); - const handleVisibleToggle = () => { setShowDebug?.(!showDebug); }; @@ -84,29 +73,35 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => { } > - {expandAll ? ( - - ) : ( - - )} + {changelogList[0]?.releaseDate} diff --git a/.dumi/theme/common/styles/Demo.tsx b/.dumi/theme/common/styles/Demo.tsx index 7287bda65555..d9d21ef6edfd 100644 --- a/.dumi/theme/common/styles/Demo.tsx +++ b/.dumi/theme/common/styles/Demo.tsx @@ -71,18 +71,6 @@ const GlobalDemoStyles: React.FC = () => { border: 1px solid ${token.colorPrimary}; } - &-expand-trigger { - position: relative; - color: #3b4357; - font-size: ${token.fontSizeXL}px; - cursor: pointer; - opacity: 0.75; - transition: all ${token.motionDurationSlow}; - &:hover { - opacity: 1; - } - } - &-title { position: absolute; top: -14px; @@ -358,7 +346,18 @@ const GlobalDemoStyles: React.FC = () => { inset-inline-end: 0; display: flex; align-items: center; - column-gap: ${token.marginSM}px; + column-gap: ${token.marginXS}px; + + ${antCls}-btn { + opacity: 0.6; + &.icon-enabled { + background: ${token.colorFillSecondary}; + opacity: 1; + ${iconCls} { + color: ${token.colorTextBase}; + font-weight: bold; + } + } } ${antCls}-row-rtl { diff --git a/.github/workflows/issue-labeled.yml b/.github/workflows/issue-labeled.yml index f2ad11a39d16..a2b8a1efde5b 100644 --- a/.github/workflows/issue-labeled.yml +++ b/.github/workflows/issue-labeled.yml @@ -38,9 +38,9 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} body: | - Hello @${{ github.event.issue.user.login }}. Please provide a online reproduction by forking [this one](https://u.ant.design/repro) or provide a minimal GitHub repository like [create-react-app-antd](https://github.com/ant-design/create-react-app-antd). Issues labeled by `Need Reproduce` will be closed if no activities in 3 days. + Hello @${{ github.event.issue.user.login }}. Please provide a online reproduction by forking [this one](https://u.ant.design/reproduce) or provide a minimal GitHub repository like [create-react-app-antd](https://github.com/ant-design/create-react-app-antd). Issues labeled by `Need Reproduce` will be closed if no activities in 3 days. - 你好 @${{ github.event.issue.user.login }},我们需要你提供一个在线的重现实例以便于我们帮你排查问题。你可以通过 fork 这个[在线重现案例](https://u.ant.design/repro) ,或者提供一个最小化的 GitHub 仓库(类似 [create-react-app-antd](https://github.com/ant-design/create-react-app-antd))。3 天内未跟进此 issue 将会被自动关闭。 + 你好 @${{ github.event.issue.user.login }},我们需要你提供一个在线的重现实例以便于我们帮你排查问题。你可以通过 fork 这个[在线重现案例](https://u.ant.design/reproduce) ,或者提供一个最小化的 GitHub 仓库(类似 [create-react-app-antd](https://github.com/ant-design/create-react-app-antd))。3 天内未跟进此 issue 将会被自动关闭。 > [什么是最小化重现,为什么这是必需的?](https://github.com/ant-design/ant-design/wiki/%E4%BB%80%E4%B9%88%E6%98%AF%E6%9C%80%E5%B0%8F%E5%8C%96%E9%87%8D%E7%8E%B0%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E6%98%AF%E5%BF%85%E9%9C%80%E7%9A%84%EF%BC%9F) diff --git a/.github/workflows/pr-check-ci.yml b/.github/workflows/pr-auto-merge.yml similarity index 100% rename from .github/workflows/pr-check-ci.yml rename to .github/workflows/pr-auto-merge.yml diff --git a/.lintstagedrc.json b/.lintstagedrc.json index c13937fccc0b..20c73c0b3599 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,4 +1,4 @@ { - "*.{ts,tsx,js,jsx,css,mjs,json}": ["biome check --write --no-errors-on-unmatched"], + "*.{ts,tsx,js,jsx,css,mjs,json}": ["biome check --write --no-errors-on-unmatched", "eslint"], "*.{md,yml}": ["prettier --ignore-unknown --write"] } diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index ea994dd9012b..58a865973c32 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -1,7 +1,6 @@ --- order: 6 title: Changelog -toc: false timeline: true tag: vVERSION --- @@ -16,6 +15,33 @@ tag: vVERSION --- +## 5.21.4 + +`2024-10-14` + +- 🐞 Fixed Input.Search not applying the `hoverBorderColor/activeBorderColor` token for hover/active states. [#51226](https://github.com/ant-design/ant-design/pull/51226) [@iqingting](https://github.com/iqingting) +- 🐞 Fix Tree icon align issue. [#51181](https://github.com/ant-design/ant-design/pull/51181) [@Meowu](https://github.com/Meowu) +- 🐞 Fix Splitter occasionally shows unnecessary scrollbars in nested combinations. [#51169](https://github.com/ant-design/ant-design/pull/51169) [@zombieJ](https://github.com/zombieJ) +- 💄 Modify Button `textHoverBg` hover background to `colorFillTertiary`. [#51187](https://github.com/ant-design/ant-design/pull/51187) [@coding-ice](https://github.com/coding-ice) +- TypeScript + - 🤖 Improve type of Switch `eventHandler`. [#51165](https://github.com/ant-design/ant-design/pull/51165) [@thinkasany](https://github.com/thinkasany) +## 5.21.3 + +`2024-10-09` + +- 💄 Added a scroll bar to Dropdown when having many items. [#51112](https://github.com/ant-design/ant-design/pull/51112) [@Cameron-Asdf](https://github.com/Cameron-Asdf) +- Slider [#51150](https://github.com/ant-design/ant-design/pull/51150) [@yoyo837](https://github.com/yoyo837) + - 🐞 Fix Slider issue where the `id` prop is not supported. + - 🐞 Fix Slider to address the issue causing `useLayoutEffect does nothing on the server` warning when `extractStyle` is invoked. +- 🐞 Fix ColorPicker with gradient mode, sometimes handle color will be force sync back to first handle color issue. [#51161](https://github.com/ant-design/ant-design/pull/51161) [@zombieJ](https://github.com/zombieJ) +- 🐞 Fix Table `onChange` function receiving incorrect sorter value. [#51114](https://github.com/ant-design/ant-design/pull/51114) [@nathanlao](https://github.com/nathanlao) +- Splitter + - 🐞 Fix the issue about throw a warning when Splitter nested in a hidden tab panel. [#51109](https://github.com/ant-design/ant-design/pull/51109) [@kiner-tang](https://github.com/kiner-tang) + - 🐞 Fix the issue about Splitter had unexpected gaps in Flex. [#51096](https://github.com/ant-design/ant-design/pull/51096) [@kiner-tang](https://github.com/kiner-tang) +- 🐞 MISC: Restore `react` and `react-dom` peerDependencies. [#51079](https://github.com/ant-design/ant-design/pull/51079) [@chentsulin](https://github.com/chentsulin) +- TypeScript + - 🤖 Improve type of Slider `eventName`. [#51156](https://github.com/ant-design/ant-design/pull/51156) [@thinkasany](https://github.com/thinkasany) + ## 5.21.2 `2024-10-01` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index c0d3c6b7704d..2cecb29841e5 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -15,6 +15,33 @@ tag: vVERSION --- +## 5.21.4 + +`2024-10-14` + +- 🐞 修复 Input.Search 无法使用 Input Token `hoverBorderColor/activeBorderColor` 修改边框颜色的问题。[#51226](https://github.com/ant-design/ant-design/pull/51226) [@iqingting](https://github.com/iqingting) +- 🐞 修复 Tree 的图标不对齐的问题。[#51181](https://github.com/ant-design/ant-design/pull/51181) [@Meowu](https://github.com/Meowu) +- 🐞 修复 Splitter 在嵌套组合时,偶尔会出现多余滚动条的问题。[#51169](https://github.com/ant-design/ant-design/pull/51169) [@zombieJ](https://github.com/zombieJ) +- 💄 修改 Button `textHoverBg` 在悬浮状态下的背景色为 `colorFillTertiary`。[#51187](https://github.com/ant-design/ant-design/pull/51187) [@coding-ice](https://github.com/coding-ice) +- TypeScript + - 🤖 优化 Switch `eventHandler` 类型。[#51165](https://github.com/ant-design/ant-design/pull/51165) [@thinkasany](https://github.com/thinkasany) +## 5.21.3 + +`2024-10-09` + +- 💄 优化 Dropdown 列表较长时的滚动条样式。[#51112](https://github.com/ant-design/ant-design/pull/51112) [@Cameron-Asdf](https://github.com/Cameron-Asdf) +- Slider [#51150](https://github.com/ant-design/ant-design/pull/51150) [@yoyo837](https://github.com/yoyo837) + - 🐞 修复 Slider 不支持 `id` 属性的问题。 + - 🐞 修复 Slider 导致 `extractStyle` 时抛出 `useLayoutEffect does nothing on the server` 警告信息的问题。 +- 🐞 修复 ColorPicker 渐变色时,部分节点颜色拖拽会被强制重置为第一个节点颜色的问题。[#51161](https://github.com/ant-design/ant-design/pull/51161) [@zombieJ](https://github.com/zombieJ) +- 🐞 修复 Table 组件在切换页面时 `onChange` 函数接收到错误的 sorter 值的问题。[#51114](https://github.com/ant-design/ant-design/pull/51114) [@nathanlao](https://github.com/nathanlao) +- Splitter + - 🐞 修复 Splitter 嵌套在一个隐藏的 Tabs 面板中时抛出警告的问题。[#51109](https://github.com/ant-design/ant-design/pull/51109) [@kiner-tang](https://github.com/kiner-tang) + - 🐞 修复 Splitter 组件在 Flex 组件下时出现异常间距的问题。[#51096](https://github.com/ant-design/ant-design/pull/51096) [@kiner-tang](https://github.com/kiner-tang) +- 🐞 杂项:重新将 `react` 和 `react-dom` 添加进 peerDependencies。[#51079](https://github.com/ant-design/ant-design/pull/51079) [@chentsulin](https://github.com/chentsulin) +- TypeScript + - 🤖 优化 Slider `eventName` 类型。[#51156](https://github.com/ant-design/ant-design/pull/51156) [@thinkasany](https://github.com/thinkasany) + ## 5.21.2 `2024-10-01` diff --git a/README-zh_CN.md b/README-zh_CN.md index 97d781cd7300..4fd827408d78 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -131,7 +131,7 @@ export default App; - [开发者说明](https://github.com/ant-design/ant-design/wiki/Development) - [版本发布规则](https://github.com/ant-design/ant-design/wiki/%E8%BD%AE%E5%80%BC%E8%A7%84%E5%88%99%E5%92%8C%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E6%B5%81%E7%A8%8B) - [常见问题](https://ant.design/docs/react/faq-cn) -- [Stackblitz 在线演示](https://u.ant.design/reproduce),用于报告 bug +- [在线演示](https://u.ant.design/reproduce),用于报告 bug - [定制主题](https://ant.design/docs/react/customize-theme-cn) - [国际化](https://ant.design/docs/react/i18n-cn) - [成为社区协作成员](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator) diff --git a/README.md b/README.md index 398db81828b7..90b313c47d38 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ export default () => ( - [Developer Instruction](https://github.com/ant-design/ant-design/wiki/Development) - [Versioning Release Note](https://github.com/ant-design/ant-design/wiki/%E8%BD%AE%E5%80%BC%E8%A7%84%E5%88%99%E5%92%8C%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E6%B5%81%E7%A8%8B) - [FAQ](https://ant.design/docs/react/faq) -- [Stackblitz Demo](https://u.ant.design/reproduce) for bug reports +- [Online Playground](https://u.ant.design/reproduce) for bug reports - [Customize Theme](https://ant.design/docs/react/customize-theme) - [How to Apply for Being A Collaborator](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator) diff --git a/components/button/style/token.ts b/components/button/style/token.ts index f570dc1e872f..3a88d8a58b42 100644 --- a/components/button/style/token.ts +++ b/components/button/style/token.ts @@ -283,7 +283,7 @@ export const prepareComponentToken: GetDefaultToken<'Button'> = (token) => { textTextColor: token.colorText, textTextHoverColor: token.colorText, textTextActiveColor: token.colorText, - textHoverBg: token.colorBgTextHover, + textHoverBg: token.colorFillTertiary, defaultColor: token.colorText, defaultBg: token.colorBgContainer, defaultBorderColor: token.colorBorder, diff --git a/components/calendar/index.en-US.md b/components/calendar/index.en-US.md index a5e88b28094f..03b35c6eb0d0 100644 --- a/components/calendar/index.en-US.md +++ b/components/calendar/index.en-US.md @@ -34,17 +34,11 @@ Common props ref:[Common props](/docs/react/common-props) // import 'dayjs/locale/zh-cn'; // dayjs.locale('zh-cn'); - + ``` | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| dateCellRender | Customize the display of the date cell, the returned content will be appended to the cell | function(date: Dayjs): ReactNode | - | | | cellRender | Customize cell content | function(current: dayjs, today: dayjs, info: { originNode: React.ReactElement,today: DateType, range?: 'start' \| 'end', type: PanelMode, locale?: Locale, subType?: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 | | dateFullCellRender | Customize the display of the date cell, the returned content will override the cell | function(date: Dayjs): ReactNode | - | | | fullCellRender | Customize cell content | function(current: dayjs, today: dayjs, info: { originNode: React.ReactElement,today: DateType, range?: 'start' \| 'end', type: PanelMode, locale?: Locale, subType?: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 | @@ -54,8 +48,6 @@ Common props ref:[Common props](/docs/react/common-props) | headerRender | Render custom header in panel | function(object:{value: Dayjs, type: string, onChange: f(), onTypeChange: f()}) | - | | | locale | The calendar's locale | object | [(default)](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | | | mode | The display mode of the calendar | `month` \| `year` | `month` | | -| monthCellRender | Customize the display of the month cell, the returned content will be appended to the cell | function(date: Dayjs): ReactNode | - | | -| monthFullCellRender | Customize the display of the month cell, the returned content will override the cell | function(date: Dayjs): ReactNode | - | | | validRange | To set valid range | \[[dayjs](https://day.js.org/), [dayjs](https://day.js.org/)] | - | | | value | The current selected date | [dayjs](https://day.js.org/) | - | | | onChange | Callback for when date changes | function(date: Dayjs) | - | | diff --git a/components/calendar/index.zh-CN.md b/components/calendar/index.zh-CN.md index d48f3ec1a9a7..c243a5410315 100644 --- a/components/calendar/index.zh-CN.md +++ b/components/calendar/index.zh-CN.md @@ -35,17 +35,11 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*-p-wQLik200AAA // import 'dayjs/locale/zh-cn'; // dayjs.locale('zh-cn'); - + ``` | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| dateCellRender | 自定义渲染日期单元格,返回内容会被追加到单元格,>= 5.4.0 请用 `cellRender` | function(date: Dayjs): ReactNode | - | < 5.4.0 | | cellRender | 自定义单元格的内容 | function(current: dayjs, today: dayjs, info: { originNode: React.ReactElement,today: DateType, range?: 'start' \| 'end', type: PanelMode, locale?: Locale, subType?: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 | | dateFullCellRender | 自定义渲染日期单元格,返回内容覆盖单元格,>= 5.4.0 请用 `fullCellRender` | function(date: Dayjs): ReactNode | - | < 5.4.0 | | fullCellRender | 自定义单元格的内容 | function(current: dayjs, today: dayjs, info: { originNode: React.ReactElement,today: DateType, range?: 'start' \| 'end', type: PanelMode, locale?: Locale, subType?: 'hour' \| 'minute' \| 'second' \| 'meridiem' }) => React.ReactNode | - | 5.4.0 | @@ -55,8 +49,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*-p-wQLik200AAA | headerRender | 自定义头部内容 | function(object:{value: Dayjs, type: string, onChange: f(), onTypeChange: f()}) | - | | | locale | 国际化配置 | object | [(默认配置)](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | | | mode | 初始模式 | `month` \| `year` | `month` | | -| monthCellRender | 自定义渲染月单元格,返回内容会被追加到单元格,>= 5.4.0 请用 `cellRender` | function(date: Dayjs): ReactNode | - | < 5.4.0 | -| monthFullCellRender | 自定义渲染月单元格,返回内容覆盖单元格,>= 5.4.0 请用 `fullCellRender` | function(date: Dayjs): ReactNode | - | < 5.4.0 | | validRange | 设置可以显示的日期 | \[[dayjs](https://day.js.org/), [dayjs](https://day.js.org/)] | - | | | value | 展示日期 | [dayjs](https://day.js.org/) | - | | | onChange | 日期变化回调 | function(date: Dayjs) | - | | diff --git a/components/collapse/index.en-US.md b/components/collapse/index.en-US.md index 9f8e4ded64ff..726f2e59bade 100644 --- a/components/collapse/index.en-US.md +++ b/components/collapse/index.en-US.md @@ -81,7 +81,7 @@ Common props ref:[Common props](/docs/react/common-props) | accordion | If true, Collapse renders as Accordion | boolean | false | | | activeKey | Key of the active panel | string\[] \| string
number\[] \| number | No default value. In [accordion mode](#collapse-demo-accordion), it's the key of the first panel | | | bordered | Toggles rendering of the border around the collapse block | boolean | true | | -| collapsible | Specify whether the panels of children be collapsible or the trigger area of collapsible | `header` \| `icon` \| `disabled` | - | 4.9.0 | +| collapsible | Specify how to trigger Collapse. Either by clicking icon or by clicking any area in header or disable collapse functionality itself | `header` \| `icon` \| `disabled` | - | 4.9.0 | | defaultActiveKey | Key of the initial active panel | string\[] \| string
number\[] \| number | - | | | destroyInactivePanel | Destroy Inactive Panel | boolean | false | | | expandIcon | Allow to customize collapse icon | (panelProps) => ReactNode | - | | diff --git a/components/color-picker/__tests__/gradient.test.tsx b/components/color-picker/__tests__/gradient.test.tsx index 0007a14d27ba..7e490468c534 100644 --- a/components/color-picker/__tests__/gradient.test.tsx +++ b/components/color-picker/__tests__/gradient.test.tsx @@ -306,4 +306,38 @@ describe('ColorPicker.gradient', () => { expect(container.querySelector('.ant-color-picker-gradient-slider')).toBeTruthy(); }); + + // This test case may easily break by jsdom update + // https://github.com/ant-design/ant-design/issues/51159 + it('change color 2 should not be color 1', () => { + const { container } = render( + , + ); + + // Select second one + const handle2 = container.querySelector('.ant-slider-handle-2')!; + doDrag(container, 0, 0, handle2, true); + + // Drag in the color panel + const panelHandle = container.querySelector('.ant-color-picker-saturation')!; + const mouseDown = createEvent.mouseDown(panelHandle); + fireEvent(panelHandle, mouseDown); + + expect(handle2).not.toHaveStyle({ + backgroundColor: 'rgb(255,0,0)', + }); + }); }); diff --git a/components/color-picker/components/PanelPicker/index.tsx b/components/color-picker/components/PanelPicker/index.tsx index 006ad598c30c..504395f64e23 100644 --- a/components/color-picker/components/PanelPicker/index.tsx +++ b/components/color-picker/components/PanelPicker/index.tsx @@ -137,7 +137,7 @@ const PanelPicker: FC = () => { info?: Info, ) => { const nextColor = fillColor(colorValue, info); - setPickerColor(nextColor); + setPickerColor(nextColor.isGradient() ? nextColor.getColors()[activeIndex].color : nextColor); onChange(nextColor, fromPicker); }; diff --git a/components/dropdown/style/index.ts b/components/dropdown/style/index.ts index 13f3ad10cef2..7058246e32bd 100644 --- a/components/dropdown/style/index.ts +++ b/components/dropdown/style/index.ts @@ -96,6 +96,12 @@ const genBaseStyle: GenerateStyle = (token) => { content: '""', }, + // Makes vertical dropdowns have a scrollbar once they become taller than the viewport. + '&-menu-vertical': { + maxHeight: '100vh', + overflowY: 'auto', + }, + [`&-trigger${antCls}-btn`]: { [`& > ${iconCls}-down, & > ${antCls}-btn-icon > ${iconCls}-down`]: { fontSize: fontSizeIcon, diff --git a/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap index de14eb317ae4..f7c73c6f9a79 100644 --- a/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -22005,6 +22005,7 @@ exports[`renders components/form/demo/validate-other.tsx extend context correctl >
= (token: InputToken) => { [searchPrefixCls]: { [componentCls]: { '&:hover, &:focus': { - borderColor: token.colorPrimaryHover, - [`+ ${componentCls}-group-addon ${searchPrefixCls}-button:not(${antCls}-btn-primary)`]: { borderInlineStartColor: token.colorPrimaryHover, }, diff --git a/components/popconfirm/index.en-US.md b/components/popconfirm/index.en-US.md index 5d0ed35b2198..01e7872336dd 100644 --- a/components/popconfirm/index.en-US.md +++ b/components/popconfirm/index.en-US.md @@ -57,10 +57,13 @@ Consult [Tooltip's documentation](/components/tooltip/#api) to find more APIs. ## FAQ -### Why does the warning findDOMNode is deprecated some times appear in strict mode? +### Why does the warning `findDOMNode is deprecated` sometimes appear in strict mode? This is due to the implementation of `rc-trigger`. `rc-trigger` forces children to accept ref, otherwise it will fall back to findDOMNode, so children need to be native html tags. If not, you need to use `React.forwardRef` transparently passes `ref` to native html tags. +- `findDOMNode is deprecated` reproduce: +- Using `forwardRef` to fix: + ## Note Please ensure that the child node of `Popconfirm` accepts `onMouseEnter`, `onMouseLeave`, `onFocus`, `onClick` events. diff --git a/components/popconfirm/index.zh-CN.md b/components/popconfirm/index.zh-CN.md index 7b06eaa7b7a3..53eb07ae8c24 100644 --- a/components/popconfirm/index.zh-CN.md +++ b/components/popconfirm/index.zh-CN.md @@ -58,10 +58,13 @@ demo: ## FAQ -### 为何在严格模式中有时候会出现 findDOMNode is deprecated 这个警告? +### 为何在严格模式中有时候会出现 `findDOMNode is deprecated` 这个警告? 这是由于 `rc-trigger` 的实现方式导致的,`rc-trigger` 强制要求 children 能够接受 ref,否则就会 fallback 到 findDOMNode,所以 children 需要是原生 html 标签,如果不是,则需要使用 `React.forwardRef` 把 `ref` 透传到原生 html 标签。 +- `findDOMNode is deprecated` 重现: +- 使用 `forwardRef` 消除警告: + ## 注意 请确保 `Popconfirm` 的子元素能接受 `onMouseEnter`、`onMouseLeave`、`onFocus`、`onClick` 事件。 diff --git a/components/popover/index.en-US.md b/components/popover/index.en-US.md index 5e64a474a1ae..5ab830070b76 100644 --- a/components/popover/index.en-US.md +++ b/components/popover/index.en-US.md @@ -51,10 +51,13 @@ Please ensure that the child node of `Popover` accepts `onMouseEnter`, `onMouseL ## FAQ -### Why does the warning findDOMNode is deprecated some times appear in strict mode? +### Why does the warning `findDOMNode is deprecated` sometimes appear in strict mode? This is due to the implementation of `rc-trigger`. `rc-trigger` forces children to accept ref, otherwise it will fall back to findDOMNode, so children need to be native html tags. If not, you need to use `React.forwardRef` transparently passes `ref` to native html tags. +- `findDOMNode is deprecated` reproduce: +- Using `forwardRef` to fix: + ### Why sometime not work on HOC? Please ensure that the child node of `Tooltip` accepts `onMouseEnter`, `onMouseLeave`, `onPointerEnter`, `onPointerLeave`, `onFocus`, `onClick` events. diff --git a/components/popover/index.zh-CN.md b/components/popover/index.zh-CN.md index c78eafb5f10a..20612a90d39e 100644 --- a/components/popover/index.zh-CN.md +++ b/components/popover/index.zh-CN.md @@ -52,10 +52,13 @@ demo: ## FAQ -### 为何在严格模式中有时候会出现 findDOMNode is deprecated 这个警告? +### 为何在严格模式中有时候会出现 `findDOMNode is deprecated` 这个警告? 这是由于 `rc-trigger` 的实现方式导致的,`rc-trigger` 强制要求 children 能够接受 ref,否则就会 fallback 到 findDOMNode,所以 children 需要是原生 html 标签,如果不是,则需要使用 `React.forwardRef` 把 `ref` 透传到原生 html 标签。 +- `findDOMNode is deprecated` 重现: +- 使用 `forwardRef` 消除警告: + ### 为何有时候 HOC 组件无法生效? 请确保 `Popover` 的子元素能接受 `onMouseEnter`、`onMouseLeave`、`onPointerEnter`、`onPointerLeave`、`onFocus`、`onClick` 事件。 diff --git a/components/slider/index.tsx b/components/slider/index.tsx index 39a3d2ad5c89..8ba94422585c 100644 --- a/components/slider/index.tsx +++ b/components/slider/index.tsx @@ -267,7 +267,7 @@ const Slider = React.forwardRef const nodeProps = node.props; function proxyEvent( - eventName: string, + eventName: keyof React.DOMAttributes, event: React.SyntheticEvent, triggerRestPropsEvent?: boolean, ) { diff --git a/components/splitter/Splitter.tsx b/components/splitter/Splitter.tsx index 42fcb83f4626..c0ac425e3172 100644 --- a/components/splitter/Splitter.tsx +++ b/components/splitter/Splitter.tsx @@ -71,7 +71,14 @@ const Splitter: React.FC> = (props) => { const [containerSize, setContainerSize] = useState(100); const onContainerResize: GetProp = (size) => { - setContainerSize(isVertical ? size.offsetHeight : size.offsetWidth); + const { offsetWidth, offsetHeight } = size; + const containerSize = isVertical ? offsetHeight : offsetWidth; + // Skip when container has no size, Such as nested in a hidden tab panel + // to fix: https://github.com/ant-design/ant-design/issues/51106 + if (containerSize === 0) { + return; + } + setContainerSize(containerSize); }; // ========================= Size ========================= @@ -146,65 +153,62 @@ const Splitter: React.FC> = (props) => { const mergedStyle: React.CSSProperties = { ...splitter?.style, ...style }; return wrapCSSVar( - <> - -
- {items.map((item, idx) => { - // Panel - const panel = ; - - // Split Bar - let splitBar: React.ReactElement | null = null; - - const resizableInfo = resizableInfos[idx]; - if (resizableInfo) { - const ariaMinStart = (stackSizes[idx - 1] || 0) + itemPtgMinSizes[idx]; - const ariaMinEnd = (stackSizes[idx + 1] || 100) - itemPtgMaxSizes[idx + 1]; - - const ariaMaxStart = (stackSizes[idx - 1] || 0) + itemPtgMaxSizes[idx]; - const ariaMaxEnd = (stackSizes[idx + 1] || 100) - itemPtgMinSizes[idx + 1]; - - splitBar = ( - { - let offset = isVertical ? offsetY : offsetX; - if (reverse) { - offset = -offset; - } - onInternalResizeUpdate(index, offset); - }} - onOffsetEnd={onInternalResizeEnd} - onCollapse={onInternalCollapse} - /> - ); - } - - return ( - - {panel} - {splitBar} - + +
+ {items.map((item, idx) => { + // Panel + const panel = ; + + // Split Bar + let splitBar: React.ReactElement | null = null; + + const resizableInfo = resizableInfos[idx]; + if (resizableInfo) { + const ariaMinStart = (stackSizes[idx - 1] || 0) + itemPtgMinSizes[idx]; + const ariaMinEnd = (stackSizes[idx + 1] || 100) - itemPtgMaxSizes[idx + 1]; + + const ariaMaxStart = (stackSizes[idx - 1] || 0) + itemPtgMaxSizes[idx]; + const ariaMaxEnd = (stackSizes[idx + 1] || 100) - itemPtgMinSizes[idx + 1]; + + splitBar = ( + { + let offset = isVertical ? offsetY : offsetX; + if (reverse) { + offset = -offset; + } + onInternalResizeUpdate(index, offset); + }} + onOffsetEnd={onInternalResizeEnd} + onCollapse={onInternalCollapse} + /> ); - })} -
-
- - {/* Fake mask for cursor */} - {typeof movingIndex === 'number' && ( -
- )} - , + } + + return ( + + {panel} + {splitBar} + + ); + })} + {/* Fake mask for cursor */} + {typeof movingIndex === 'number' && ( +
+ )} +
+ , ); }; diff --git a/components/splitter/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/splitter/__tests__/__snapshots__/demo-extend.test.ts.snap index d03b0062f019..a3bfd50747fe 100644 --- a/components/splitter/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/splitter/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -810,6 +810,132 @@ exports[`renders components/splitter/demo/multiple.tsx extend context correctly exports[`renders components/splitter/demo/multiple.tsx extend context correctly 2`] = `[]`; +exports[`renders components/splitter/demo/nested-in-tabs.tsx extend context correctly 1`] = ` +
+
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
    + +
+
+
+
+
+ Content of Tab Pane 1 +
+
+
+
+`; + +exports[`renders components/splitter/demo/nested-in-tabs.tsx extend context correctly 2`] = `[]`; + exports[`renders components/splitter/demo/size.tsx extend context correctly 1`] = `
`; +exports[`renders components/splitter/demo/nested-in-tabs.tsx correctly 1`] = ` +
+
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ Content of Tab Pane 1 +
+
+
+
+`; + exports[`renders components/splitter/demo/size.tsx correctly 1`] = `
{ expect(onResize).toHaveBeenCalledWith([50, 0, 50]); expect(onResizeEnd).toHaveBeenCalledWith([50, 0, 50]); }); + + it("aria-valuemin/aria-valuemax should not set NaN When container's width be setting zero", async () => { + containerSize = 0; + const App: React.FC = () => { + return ; + }; + const { container } = render(); + mockDrag(container.querySelectorAll('.ant-splitter-bar-dragger')[1], -100); + triggerResize(container.querySelector('.ant-splitter')!); + await act(async () => { + await waitFakeTimer(); + }); + + expect(errSpy).not.toHaveBeenCalled(); + expect(container.querySelector('[aria-valuemin]')?.getAttribute('aria-valuemin')).not.toBe( + 'NaN', + ); + expect(container.querySelector('[aria-valuemax]')?.getAttribute('aria-valuemax')).not.toBe( + 'NaN', + ); + }); }); // ============================= Collapsible ============================= diff --git a/components/splitter/demo/nested-in-tabs.md b/components/splitter/demo/nested-in-tabs.md new file mode 100644 index 000000000000..db5e0b2b948d --- /dev/null +++ b/components/splitter/demo/nested-in-tabs.md @@ -0,0 +1,7 @@ +## zh-CN + +嵌套在标签页中。 + +## en-US + +Nested in tabs. diff --git a/components/splitter/demo/nested-in-tabs.tsx b/components/splitter/demo/nested-in-tabs.tsx new file mode 100644 index 000000000000..c048714756c8 --- /dev/null +++ b/components/splitter/demo/nested-in-tabs.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { Flex, Splitter, Tabs, Typography } from 'antd'; + +const Desc: React.FC> = (props) => ( + + + {props.text} + + +); + +const App: React.FC = () => { + const SplitterContent = ( + + + + + + + + + + + + ); + return ( + + ); +}; + +export default App; diff --git a/components/splitter/index.en-US.md b/components/splitter/index.en-US.md index 2a1206ce0922..a006539b0276 100644 --- a/components/splitter/index.en-US.md +++ b/components/splitter/index.en-US.md @@ -23,6 +23,7 @@ Can be used to separate areas horizontally or vertically. When you need to freel Collapsible Multiple panels Complex combination +Nested in tabs Debug ## API diff --git a/components/splitter/index.zh-CN.md b/components/splitter/index.zh-CN.md index 8a5e7c97a959..3f79bfc14d76 100644 --- a/components/splitter/index.zh-CN.md +++ b/components/splitter/index.zh-CN.md @@ -26,6 +26,7 @@ tag: 5.21.0 可折叠 多面板 复杂组合 +标签页中嵌套 调试 ## API diff --git a/components/splitter/style/index.ts b/components/splitter/style/index.ts index c558d268c41a..06a96d6b3f50 100644 --- a/components/splitter/style/index.ts +++ b/components/splitter/style/index.ts @@ -6,12 +6,18 @@ import { genStyleHooks } from '../../theme/internal'; export interface ComponentToken { /** - * @desc 可改变大小标识 元素大小 - * @descEN Height of content area + * @desc 拖拽标识元素大小 + * @descEN Drag and drop the identity element size + * @deprecated Please use `splitBarDraggableSize` instead. */ resizeSpinnerSize: number; /** * @desc 拖拽标识元素大小 + * @descEN Drag and drop the identity element size + */ + splitBarDraggableSize: number; + /** + * @desc 拖拽元素大小 * @descEN Drag the element size */ splitBarSize: number; @@ -71,7 +77,7 @@ const genSplitterStyle: GenerateStyle = (token: SplitterToken): C const { componentCls, colorFill, - resizeSpinnerSize, + splitBarDraggableSize, splitBarSize, splitTriggerSize, controlItemBgHover, @@ -223,7 +229,7 @@ const genSplitterStyle: GenerateStyle = (token: SplitterToken): C }, '&:after': { - height: resizeSpinnerSize, + height: splitBarDraggableSize, width: splitBarSize, }, }, @@ -278,7 +284,7 @@ const genSplitterStyle: GenerateStyle = (token: SplitterToken): C }, '&:after': { - width: resizeSpinnerSize, + width: splitBarDraggableSize, height: splitBarSize, }, }, @@ -309,9 +315,15 @@ const genSplitterStyle: GenerateStyle = (token: SplitterToken): C padding: '0 1px', scrollbarWidth: 'thin', boxSizing: 'border-box', - }, - [`${splitPanelCls}-hidden`]: { - padding: 0, + + '&-hidden': { + padding: 0, + overflow: 'hidden', + }, + + [`&:has(${componentCls}:only-child)`]: { + overflow: 'hidden', + }, }, ...genRtlStyle(token), @@ -323,11 +335,14 @@ export const prepareComponentToken: GetDefaultToken<'Splitter'> = (token) => { const splitBarSize = token.splitBarSize || 2; const splitTriggerSize = token.splitTriggerSize || 6; + // https://github.com/ant-design/ant-design/pull/51223 const resizeSpinnerSize = token.resizeSpinnerSize || 20; + const splitBarDraggableSize = token.splitBarDraggableSize ?? resizeSpinnerSize; return { splitBarSize, splitTriggerSize, + splitBarDraggableSize, resizeSpinnerSize, }; }; diff --git a/components/switch/index.tsx b/components/switch/index.tsx index 6d9ef3253818..abae39b80153 100755 --- a/components/switch/index.tsx +++ b/components/switch/index.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import LoadingOutlined from '@ant-design/icons/LoadingOutlined'; import classNames from 'classnames'; import RcSwitch from 'rc-switch'; +import type { SwitchChangeEventHandler, SwitchClickEventHandler } from 'rc-switch'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; import Wave from '../_util/wave'; @@ -11,11 +12,7 @@ import useSize from '../config-provider/hooks/useSize'; import useStyle from './style'; export type SwitchSize = 'small' | 'default'; -export type SwitchChangeEventHandler = ( - checked: boolean, - event: React.MouseEvent, -) => void; -export type SwitchClickEventHandler = SwitchChangeEventHandler; +export type { SwitchChangeEventHandler, SwitchClickEventHandler }; export interface SwitchProps { prefixCls?: string; @@ -110,11 +107,10 @@ const InternalSwitch = React.forwardRef((props, return wrapCSSVar( - {/* @ts-ignore */} { const sorter3 = handleChange.mock.calls[2][2]; expect(sorter3.column).toBe(undefined); expect(sorter3.order).toBe(undefined); - expect(sorter3.field).toBe('name'); - expect(sorter3.columnKey).toBe('name'); + expect(sorter3.field).toBe(undefined); + expect(sorter3.columnKey).toBe(undefined); + }); + + it('should not retain sorter value when page changes after cancelling sort', () => { + const handleChange = jest.fn(); + const { container } = render( + createTable({ + onChange: handleChange, + pagination: { pageSize: 2 }, + }), + ); + + // ascending sort + fireEvent.click(container.querySelector('.ant-table-column-sorters')!); + expect(handleChange).toHaveBeenCalledTimes(1); + let sorter = handleChange.mock.calls[0][2]; + expect(sorter.column.dataIndex).toBe('name'); + expect(sorter.order).toBe('ascend'); + expect(sorter.field).toBe('name'); + expect(sorter.columnKey).toBe('name'); + + // descending sort + fireEvent.click(container.querySelector('.ant-table-column-sorters')!); + expect(handleChange).toHaveBeenCalledTimes(2); + sorter = handleChange.mock.calls[1][2]; + expect(sorter.column.dataIndex).toBe('name'); + expect(sorter.order).toBe('descend'); + expect(sorter.field).toBe('name'); + expect(sorter.columnKey).toBe('name'); + + // cancel sort + fireEvent.click(container.querySelector('.ant-table-column-sorters')!); + expect(handleChange).toHaveBeenCalledTimes(3); + sorter = handleChange.mock.calls[2][2]; + expect(sorter.column).toBe(undefined); + expect(sorter.order).toBe(undefined); + expect(sorter.field).toBe(undefined); + expect(sorter.columnKey).toBe(undefined); + + // change page + fireEvent.click(container.querySelector('.ant-pagination-item-2')!); + expect(handleChange).toHaveBeenCalledTimes(4); + sorter = handleChange.mock.calls[3][2]; + + expect(sorter.column).toBe(undefined); + expect(sorter.order).toBe(undefined); + expect(sorter.field).toBe(undefined); + expect(sorter.columnKey).toBe(undefined); }); it('hover header show sorter tooltip', () => { @@ -1141,7 +1188,10 @@ describe('Table.sorter', () => { , ); - function clickToMatchExpect(index: number, sorter: { field: string; order: SortOrder }) { + function clickToMatchExpect( + index: number, + sorter: { field: string | undefined; order: SortOrder }, + ) { fireEvent.click(container.querySelectorAll('.ant-table-column-sorters')[index]); expect(onChange).toHaveBeenCalledWith( @@ -1157,12 +1207,12 @@ describe('Table.sorter', () => { // First clickToMatchExpect(0, { field: 'math', order: 'ascend' }); clickToMatchExpect(0, { field: 'math', order: 'descend' }); - clickToMatchExpect(0, { field: 'math', order: undefined as unknown as SortOrder }); + clickToMatchExpect(0, { field: undefined, order: undefined as unknown as SortOrder }); // Last clickToMatchExpect(1, { field: 'english', order: 'ascend' }); clickToMatchExpect(1, { field: 'english', order: 'descend' }); - clickToMatchExpect(1, { field: 'english', order: undefined as unknown as SortOrder }); + clickToMatchExpect(1, { field: undefined, order: undefined as unknown as SortOrder }); }); // https://github.com/ant-design/ant-design/issues/37024 diff --git a/components/table/__tests__/__snapshots__/empty.test.tsx.snap b/components/table/__tests__/__snapshots__/empty.test.tsx.snap index 3a0695734098..a5f52d2f3e54 100644 --- a/components/table/__tests__/__snapshots__/empty.test.tsx.snap +++ b/components/table/__tests__/__snapshots__/empty.test.tsx.snap @@ -356,7 +356,7 @@ exports[`Table renders empty table with fixed columns should work 1`] = ` class="ant-spin-container" >
( }; const stateToInfo = ( - sorterStates: SortState, + sorterState: SortState, ): SorterResult => { - const { column, sortOrder } = sorterStates; + const { column, sortOrder } = sorterState; return { column, order: sortOrder, @@ -295,25 +295,28 @@ const stateToInfo = ( const generateSorterInfo = ( sorterStates: SortState[], ): SorterResult | SorterResult[] => { - const list = sorterStates + const activeSorters = sorterStates .filter(({ sortOrder }) => sortOrder) .map>(stateToInfo); // =========== Legacy compatible support =========== // https://github.com/ant-design/ant-design/pull/19226 - if (list.length === 0 && sorterStates.length) { + if (activeSorters.length === 0 && sorterStates.length) { const lastIndex = sorterStates.length - 1; return { ...stateToInfo(sorterStates[lastIndex]), column: undefined, + order: undefined, + field: undefined, + columnKey: undefined, }; } - if (list.length <= 1) { - return list[0] || {}; + if (activeSorters.length <= 1) { + return activeSorters[0] || {}; } - return list; + return activeSorters; }; export const getSortData = ( diff --git a/components/tooltip/index.en-US.md b/components/tooltip/index.en-US.md index b25ee810b1f4..6964f7b1e264 100644 --- a/components/tooltip/index.en-US.md +++ b/components/tooltip/index.en-US.md @@ -68,10 +68,13 @@ The following APIs are shared by Tooltip, Popconfirm, Popover. ## FAQ -### Why does the warning findDOMNode is deprecated some times appear in strict mode? +### Why does the warning `findDOMNode is deprecated` sometimes appear in strict mode? This is due to the implementation of `rc-trigger`. `rc-trigger` forces children to accept ref, otherwise it will fall back to findDOMNode, so children need to be native html tags. If not, you need to use `React.forwardRef` transparently passes `ref` to native html tags. +- `findDOMNode is deprecated` reproduce: +- Using `forwardRef` to fix: + ### Why sometime not work on HOC? Please ensure that the child node of `Tooltip` accepts `onMouseEnter`, `onMouseLeave`, `onPointerEnter`, `onPointerLeave`, `onFocus`, `onClick` events. diff --git a/components/tooltip/index.zh-CN.md b/components/tooltip/index.zh-CN.md index ef94468f3c3b..5c4d0487c7ec 100644 --- a/components/tooltip/index.zh-CN.md +++ b/components/tooltip/index.zh-CN.md @@ -70,10 +70,13 @@ demo: ## FAQ -### 为何在严格模式中有时候会出现 findDOMNode is deprecated 这个警告? +### 为何在严格模式中有时候会出现 `findDOMNode is deprecated` 这个警告? 这是由于 `rc-trigger` 的实现方式导致的,`rc-trigger` 强制要求 children 能够接受 ref,否则就会 fallback 到 findDOMNode,所以 children 需要是原生 html 标签,如果不是,则需要使用 `React.forwardRef` 把 `ref` 透传到原生 html 标签。 +- `findDOMNode is deprecated` 重现: +- 使用 `forwardRef` 消除警告: + ### 为何有时候 HOC 组件无法生效? 请确保 `Tooltip` 的子元素能接受 `onMouseEnter`、`onMouseLeave`、`onPointerEnter`、`onPointerLeave`、`onFocus`、`onClick` 事件。 diff --git a/components/tree/style/index.ts b/components/tree/style/index.ts index 7a241a0ec01e..6a27fa57a257 100644 --- a/components/tree/style/index.ts +++ b/components/tree/style/index.ts @@ -258,6 +258,10 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject => cursor: 'pointer', userSelect: 'none', transition: `all ${token.motionDurationSlow}`, + marginInlineEnd: token + .calc(token.calc(titleHeight).sub(token.controlInteractiveSize)) + .div(2) + .equal(), '&-noop': { cursor: 'unset', diff --git a/components/typography/style/mixins.ts b/components/typography/style/mixins.ts index 75433d491572..74c4932f53ae 100644 --- a/components/typography/style/mixins.ts +++ b/components/typography/style/mixins.ts @@ -60,6 +60,7 @@ export const getLinkStyles: GenerateStyle = (token) return { 'a&, a': { ...operationUnit(token), + userSelect: 'text', [`&[disabled], &${componentCls}-disabled`]: { color: token.colorTextDisabled, diff --git a/components/watermark/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/watermark/__tests__/__snapshots__/demo-extend.test.ts.snap index 6c7772127f86..caa9f51bdf12 100644 --- a/components/watermark/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/watermark/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -534,6 +534,7 @@ exports[`renders components/watermark/demo/custom.tsx extend context correctly 1 >
- Switch -In the past major versions, this wave effect could not be modified. If want to turn it off, developers even need to do some "magic code" to achieve it. So when the designer proposed a happy work theme, as a developer, we think this is a good time to make some changes. +In the past major versions, this wave effect could not be modified. If developers want to turn it off, they even need to do some "magic code" to achieve it. So when the designer proposed a happy work theme, as a developer, we think this is a good time to make some changes. ### Wave component diff --git a/docs/blog/suspense.en-US.md b/docs/blog/suspense.en-US.md index 75e09f35bf6e..2e4e1294e23a 100644 --- a/docs/blog/suspense.en-US.md +++ b/docs/blog/suspense.en-US.md @@ -54,8 +54,6 @@ These code can run perfectly in React 17, and also run very well in React 18's S The StrictMode of React 18 is different from [React 17](https://17.reactjs.org/docs/strict-mode.html) in that it will be called multiple times in each phase to ensure that developers clean up the Effect: -````tsx - ```tsx const My = () => { console.log('render'); @@ -85,7 +83,7 @@ const My = () => { // - effect // - effect cleanup // - effect -```` +``` With above sample, we can know that `counter` in StrictMode will be accumulated, but the final value will be correct (that is, each component will only be counted once): diff --git a/docs/react/introduce.en-US.md b/docs/react/introduce.en-US.md index 7b63d980e768..f3d94e73738b 100644 --- a/docs/react/introduce.en-US.md +++ b/docs/react/introduce.en-US.md @@ -7,7 +7,7 @@ title: Ant Design of React -Following the Ant Design specification, we developed a React UI library `antd` () that contains a set of high quality components and demos for building rich, interactive user interfaces. +Following the Ant Design specification, we developed a React UI library `antd` () that contains a set of high quality components and demos for building rich, interactive user interfaces.
diff --git a/docs/react/introduce.zh-CN.md b/docs/react/introduce.zh-CN.md index 19b98e0ef167..0504895b9583 100644 --- a/docs/react/introduce.zh-CN.md +++ b/docs/react/introduce.zh-CN.md @@ -7,7 +7,7 @@ title: Ant Design of React -`antd`()是基于 Ant Design 设计体系的 React UI 组件库,适合企业级中后台产品与前台桌面网站。 +`antd`()是基于 Ant Design 设计体系的 React UI 组件库,适合企业级中后台产品与前台桌面网站。
diff --git a/package.json b/package.json index c75e63aadf36..ae3e96d5b53e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "5.21.2", + "version": "5.21.4", "description": "An enterprise-class UI design language and React components implementation", "license": "MIT", "funding": { @@ -107,7 +107,7 @@ "dependencies": { "@ant-design/colors": "^7.1.0", "@ant-design/cssinjs": "^1.21.1", - "@ant-design/cssinjs-utils": "^1.1.0", + "@ant-design/cssinjs-utils": "^1.1.1", "@ant-design/icons": "^5.5.1", "@ant-design/react-slick": "~1.1.2", "@babel/runtime": "^7.25.6", @@ -141,7 +141,7 @@ "rc-resize-observer": "^1.4.0", "rc-segmented": "~2.5.0", "rc-select": "~14.15.2", - "rc-slider": "~11.1.6", + "rc-slider": "~11.1.7", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", "rc-table": "~7.48.0", @@ -173,7 +173,7 @@ "@emotion/server": "^11.11.0", "@eslint-react/eslint-plugin": "^1.14.3", "@ianvs/prettier-plugin-sort-imports": "^4.3.1", - "@inquirer/prompts": "^6.0.1", + "@inquirer/prompts": "^7.0.0", "@madccc/duplicate-package-checker-webpack-plugin": "^1.0.0", "@microflash/rehype-figure": "^2.1.1", "@npmcli/run-script": "^9.0.0", diff --git a/webpack.config.js b/webpack.config.js index 751dd59609c4..84bf777ae4d9 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,86 +7,85 @@ const CircularDependencyPlugin = require('circular-dependency-plugin'); const DuplicatePackageCheckerPlugin = require('@madccc/duplicate-package-checker-webpack-plugin'); const path = require('path'); -function addLocales(webpackConfig) { +function addLocales(config) { + const newConfig = { ...config }; // Avoid mutating the original config let packageName = 'antd-with-locales'; - if (webpackConfig.entry['antd.min']) { + if (newConfig.entry['antd.min']) { packageName += '.min'; } - webpackConfig.entry[packageName] = './index-with-locales.js'; - webpackConfig.output.filename = '[name].js'; + newConfig.entry[packageName] = './index-with-locales.js'; + newConfig.output.filename = '[name].js'; + return newConfig; } function externalDayjs(config) { - config.externals.dayjs = { + const newConfig = { ...config }; // Shallow copy for safety + newConfig.externals.dayjs = { root: 'dayjs', commonjs2: 'dayjs', commonjs: 'dayjs', amd: 'dayjs', }; + return newConfig; } function externalCssinjs(config) { - config.resolve = config.resolve || {}; - config.resolve.alias = config.resolve.alias || {}; + const newConfig = { ...config }; // Shallow copy for safety + newConfig.resolve = newConfig.resolve || {}; + newConfig.resolve.alias = newConfig.resolve.alias || {}; + newConfig.resolve.alias['@ant-design/cssinjs'] = path.resolve(__dirname, 'alias/cssinjs'); + return newConfig; +} + +function addPluginsForProduction(config) { + const newConfig = { ...config }; // Shallow copy for safety + if (!process.env.CI || process.env.ANALYZER) { + newConfig.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + reportFilename: '../report.html', + }) + ); + } + if (newConfig.mode === 'production' && !process.env.PRODUCTION_ONLY) { + newConfig.plugins.push( + new DuplicatePackageCheckerPlugin({ + verbose: true, + emitError: true, + }) + ); + } + + newConfig.plugins.push( + codecovWebpackPlugin({ + enableBundleAnalysis: process.env.CODECOV_TOKEN !== undefined, + bundleName: 'antd.min', + uploadToken: process.env.CODECOV_TOKEN, + }), + new CircularDependencyPlugin({ + failOnError: true, + }) + ); - config.resolve.alias['@ant-design/cssinjs'] = path.resolve(__dirname, 'alias/cssinjs'); + return newConfig; } let webpackConfig = getWebpackConfig(false); -// Used for `size-limit` ci which only need to check min files if (process.env.PRODUCTION_ONLY) { - // eslint-disable-next-line no-console console.log('🍐 Build production only'); webpackConfig = webpackConfig.filter((config) => config.mode === 'production'); } -// RUN_ENV: https://github.com/ant-design/antd-tools/blob/14ee166fc1f4ab5e87da45ee3b0643a8325f1bc3/lib/gulpfile.js#L48 if (process.env.RUN_ENV === 'PRODUCTION') { - webpackConfig.forEach((config) => { - addLocales(config); - externalDayjs(config); - externalCssinjs(config); - // Reduce non-minified dist files size - config.optimization.usedExports = true; - - if (!process.env.CI || process.env.ANALYZER) { - config.plugins.push( - new BundleAnalyzerPlugin({ - analyzerMode: 'static', - openAnalyzer: false, - reportFilename: '../report.html', - }), - ); - } - - if (config.mode !== 'production') { - return; - } - - if (!process.env.PRODUCTION_ONLY) { - config.plugins.push( - new DuplicatePackageCheckerPlugin({ - verbose: true, - emitError: true, - }), - ); - } - - config.plugins.push( - codecovWebpackPlugin({ - enableBundleAnalysis: process.env.CODECOV_TOKEN !== undefined, - bundleName: 'antd.min', - uploadToken: process.env.CODECOV_TOKEN, - }), - ); - - config.plugins.push( - new CircularDependencyPlugin({ - // add errors to webpack instead of warnings - failOnError: true, - }), - ); + webpackConfig = webpackConfig.map((config) => { + let newConfig = addLocales(config); + newConfig = externalDayjs(newConfig); + newConfig = externalCssinjs(newConfig); + newConfig.optimization.usedExports = true; + newConfig = addPluginsForProduction(newConfig); + return newConfig; }); }