diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 52225c4bd6..f5e6bcca23 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -110,7 +110,7 @@ timeline: true - 💄 修复 RTL 下 Input.Search 边框样式问题。[#37980](https://github.com/ant-design/ant-design/pull/37980) [@foryuki](https://github.com/foryuki) - 🐞 修复 AutoComplete 会报未使用的废弃属性 `dropdownClassName` 的问题。[#37974](https://github.com/ant-design/ant-design/pull/37974) [@heiyu4585](https://github.com/heiyu4585) - 🐞 修复 Typography 省略算法在计算一些元素 fontSize 时为空字符串的情况[#37928](https://github.com/ant-design/ant-design/pull/37928) [@zheeeng](https://github.com/zheeeng) -- 🐞 Fix Tabs 添加按钮在某些边界情况下无法展示的问题。[#37937](https://github.com/ant-design/ant-design/pull/37937) +- 🐞 修复 Tabs 添加按钮在某些边界情况下无法展示的问题。[#37937](https://github.com/ant-design/ant-design/pull/37937) - 🐞 修复 RangePicker 在某些情况下面板会闪烁的问题。[#439](https://github.com/react-component/picker/pull/439) - 🛠 重构 Spin 为 Function Component。[#37969](https://github.com/ant-design/ant-design/pull/37969) [@li-jia-nan](https://github.com/li-jia-nan) - 🛠 重构 Statistic.Countdown 为 Function Component.[#37938](https://github.com/ant-design/ant-design/pull/37938) [@li-jia-nan](https://github.com/li-jia-nan) @@ -1463,7 +1463,7 @@ timeline: true - Dropdown - 🐞 修复 Dropdown 带图标的菜单项禁用样式丢失的问题。[#29433](https://github.com/ant-design/ant-design/pull/29433) - 🐞 修复 Dropdown 内 Menu 不支持 `expandIcon` 的问题。[#29338](https://github.com/ant-design/ant-design/pull/29338) -- 🐞 Fix 在本地开发时会报 tree-shaking 警告信息的问题。[#29378](https://github.com/ant-design/ant-design/pull/29378) +- 🐞 修复在本地开发时会报 tree-shaking 警告信息的问题。[#29378](https://github.com/ant-design/ant-design/pull/29378) - 🇰🇷 修复 TimePicker 本地化。[#29540](https://github.com/ant-design/ant-design/pull/29540) - TypeScript - 🤖 修复 Form.Item 的泛型定义问题。[#29397](https://github.com/ant-design/ant-design/pull/29397) [@mumiao](https://github.com/mumiao) @@ -1860,7 +1860,7 @@ timeline: true - Modal - 🆕 `modal.update()` 支持函数式更新。[#27163](https://github.com/ant-design/ant-design/pull/27163) [@Mongkii](https://github.com/Mongkii) - 🆕 Modal method 增加 `bodyStyle` 属性。[#27292](https://github.com/ant-design/ant-design/pull/27292) - - 🐞 Fix Modal missing `modalRender` prop。[#27272](https://github.com/ant-design/ant-design/pull/27272) [@jieny](https://github.com/jieny) + - 🐞 修复 Modal 丢失 `modalRender` 属性 TS 定义。[#27272](https://github.com/ant-design/ant-design/pull/27272) [@jieny](https://github.com/jieny) - 🐞 `Modal.config` 中设置的 `rootPrefixCls` 可以对 `title` 和 `content` 下使用的 antd 组件生效。[#27376](https://github.com/ant-design/ant-design/pull/27376) [@Chersquwn](https://github.com/Chersquwn) - Input - 🆕 Input.Textarea 支持 `size` 属性。[#27110](https://github.com/ant-design/ant-design/pull/27110) diff --git a/components/breadcrumb/Breadcrumb.tsx b/components/breadcrumb/Breadcrumb.tsx index e353a1f54c..d3399a91d3 100755 --- a/components/breadcrumb/Breadcrumb.tsx +++ b/components/breadcrumb/Breadcrumb.tsx @@ -2,9 +2,11 @@ import classNames from 'classnames'; import toArray from 'rc-util/lib/Children/toArray'; import * as React from 'react'; import { ConfigContext } from '../config-provider'; +import type { DropdownProps } from '../dropdown'; import Menu from '../menu'; import { cloneElement } from '../_util/reactNode'; import warning from '../_util/warning'; +import type { BreadcrumbItemProps } from './BreadcrumbItem'; import BreadcrumbItem from './BreadcrumbItem'; import BreadcrumbSeparator from './BreadcrumbSeparator'; @@ -52,7 +54,7 @@ function defaultItemRender(route: Route, params: any, routes: Route[], paths: st const getPath = (path: string, params: any) => { path = (path || '').replace(/^\//, ''); - Object.keys(params).forEach(key => { + Object.keys(params).forEach((key) => { path = path.replace(`:${key}`, params[key]); }); return path; @@ -92,18 +94,18 @@ const Breadcrumb: BreadcrumbInterface = ({ if (routes && routes.length > 0) { // generated by route const paths: string[] = []; - crumbs = routes.map(route => { + crumbs = routes.map((route) => { const path = getPath(route.path, params); if (path) { paths.push(path); } // generated overlay by route.children - let overlay; + let overlay: DropdownProps['overlay']; if (route.children && route.children.length) { overlay = ( ({ + items={route.children.map((child) => ({ key: child.path || child.breadcrumbName, label: itemRender(child, params, routes, addChildPath(paths, child.path, params)), }))} @@ -111,8 +113,14 @@ const Breadcrumb: BreadcrumbInterface = ({ ); } + const itemProps: BreadcrumbItemProps = { separator }; + + if (overlay) { + itemProps.overlay = overlay; + } + return ( - + {itemRender(route, params, routes, paths)} ); diff --git a/components/breadcrumb/BreadcrumbItem.tsx b/components/breadcrumb/BreadcrumbItem.tsx index 9a4290e943..f0ab97c62c 100644 --- a/components/breadcrumb/BreadcrumbItem.tsx +++ b/components/breadcrumb/BreadcrumbItem.tsx @@ -1,6 +1,5 @@ import DownOutlined from '@ant-design/icons/DownOutlined'; import * as React from 'react'; - import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; import type { DropdownProps } from '../dropdown/dropdown'; @@ -23,7 +22,7 @@ export interface BreadcrumbItemProps { interface BreadcrumbItemInterface extends React.FC { __ANT_BREADCRUMB_ITEM: boolean; } -const BreadcrumbItem: BreadcrumbItemInterface = props => { +const BreadcrumbItem: BreadcrumbItemInterface = (props) => { const { prefixCls: customizePrefixCls, separator = '/', diff --git a/components/breadcrumb/__tests__/Breadcrumb.test.tsx b/components/breadcrumb/__tests__/Breadcrumb.test.tsx index 97090180a8..598b33591b 100644 --- a/components/breadcrumb/__tests__/Breadcrumb.test.tsx +++ b/components/breadcrumb/__tests__/Breadcrumb.test.tsx @@ -181,4 +181,24 @@ describe('Breadcrumb', () => { expect(container.querySelectorAll('.ant-breadcrumb-link')[1].textContent).toBe('0'); expect(container.firstChild).toMatchSnapshot(); }); + + it('should console Error when `overlay` in props', () => { + const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + render( + + test} /> + , + ); + expect(errSpy).toHaveBeenCalledWith( + 'Warning: [antd: Breadcrumb.Item] `overlay` is deprecated. Please use `menu` instead.', + ); + errSpy.mockRestore(); + }); + + it('should not console Error when `overlay` not in props', () => { + const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + render(); + expect(errSpy).not.toHaveBeenCalled(); + errSpy.mockRestore(); + }); }); diff --git a/components/dropdown/__tests__/dropdown-button.test.tsx b/components/dropdown/__tests__/dropdown-button.test.tsx index 35f4ad21a9..a9748a66f5 100644 --- a/components/dropdown/__tests__/dropdown-button.test.tsx +++ b/components/dropdown/__tests__/dropdown-button.test.tsx @@ -131,7 +131,7 @@ describe('DropdownButton', () => { 'ant-btn', ); }); - it('should console Error then `overlay` in props', () => { + it('should console Error when `overlay` in props', () => { const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); render(test} />); expect(errSpy).toHaveBeenCalledWith( @@ -139,7 +139,7 @@ describe('DropdownButton', () => { ); errSpy.mockRestore(); }); - it('should not console Error then `overlay` not in props', () => { + it('should not console Error when `overlay` not in props', () => { const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); render(); expect(errSpy).not.toHaveBeenCalled(); diff --git a/components/form/FormItem/index.tsx b/components/form/FormItem/index.tsx index 19c0751e13..6bb6ef4e6a 100644 --- a/components/form/FormItem/index.tsx +++ b/components/form/FormItem/index.tsx @@ -165,7 +165,7 @@ function InternalFormItem(props: FormItemProps): React.Rea // >>>>> Collect noStyle Field error to the top FormItem const onSubItemMetaChange = (subMeta: Meta & { destroy: boolean }, uniqueKeys: React.Key[]) => { // Only `noStyle` sub item will trigger - setSubFieldErrors(prevSubFieldErrors => { + setSubFieldErrors((prevSubFieldErrors) => { const clone = { ...prevSubFieldErrors, }; @@ -191,7 +191,7 @@ function InternalFormItem(props: FormItemProps): React.Rea const errorList: string[] = [...meta.errors]; const warningList: string[] = [...meta.warnings]; - Object.values(subFieldErrors).forEach(subFieldError => { + Object.values(subFieldErrors).forEach((subFieldError) => { errorList.push(...(subFieldError.errors || [])); warningList.push(...(subFieldError.warnings || [])); }); @@ -262,7 +262,7 @@ function InternalFormItem(props: FormItemProps): React.Rea ? required : !!( rules && - rules.some(rule => { + rules.some((rule) => { if (rule && typeof rule === 'object' && rule.required && !rule.warningOnly) { return true; } @@ -284,13 +284,13 @@ function InternalFormItem(props: FormItemProps): React.Rea warning( !(shouldUpdate && dependencies), 'Form.Item', - "`shouldUpdate` and `dependencies` shouldn't be used together. See https://u.ant.design/#form-deps.", + "`shouldUpdate` and `dependencies` shouldn't be used together. See https://u.ant.design/form-deps.", ); if (Array.isArray(children) && hasName) { warning( false, 'Form.Item', - 'A `Form.Item` with a `name` prop must have a single child element. For information on how to render more complex form items, see https://u.ant.design/#complex-form-item.', + 'A `Form.Item` with a `name` prop must have a single child element. For information on how to render more complex form items, see https://u.ant.design/complex-form-item.', ); childNode = children; } else if (isRenderProps && (!(shouldUpdate || dependencies) || hasName)) { @@ -351,7 +351,7 @@ function InternalFormItem(props: FormItemProps): React.Rea ...toArray(mergedValidateTrigger), ]); - triggers.forEach(eventName => { + triggers.forEach((eventName) => { childProps[eventName] = (...args: any[]) => { mergedControl[eventName]?.(...args); children.props[eventName]?.(...args); diff --git a/components/form/__tests__/index.test.tsx b/components/form/__tests__/index.test.tsx index 13e1ba427a..8b638e5d9c 100644 --- a/components/form/__tests__/index.test.tsx +++ b/components/form/__tests__/index.test.tsx @@ -212,7 +212,7 @@ describe('Form', () => { , ); expect(errorSpy).toHaveBeenCalledWith( - "Warning: [antd: Form.Item] `shouldUpdate` and `dependencies` shouldn't be used together. See https://u.ant.design/#form-deps.", + "Warning: [antd: Form.Item] `shouldUpdate` and `dependencies` shouldn't be used together. See https://u.ant.design/form-deps.", ); }); @@ -239,7 +239,7 @@ describe('Form', () => { , ); expect(errorSpy).toHaveBeenCalledWith( - 'Warning: [antd: Form.Item] A `Form.Item` with a `name` prop must have a single child element. For information on how to render more complex form items, see https://u.ant.design/#complex-form-item.', + 'Warning: [antd: Form.Item] A `Form.Item` with a `name` prop must have a single child element. For information on how to render more complex form items, see https://u.ant.design/complex-form-item.', ); }); @@ -1494,7 +1494,7 @@ describe('Form', () => { it('item customize margin', async () => { const computeSpy = jest .spyOn(window, 'getComputedStyle') - .mockImplementation(() => ({ marginBottom: 24 } as unknown as CSSStyleDeclaration)); + .mockImplementation(() => ({ marginBottom: 24 }) as unknown as CSSStyleDeclaration); const { container } = render(
diff --git a/components/input/Search.tsx b/components/input/Search.tsx index 42e34abc43..770e310bfe 100644 --- a/components/input/Search.tsx +++ b/components/input/Search.tsx @@ -62,7 +62,7 @@ const Search = React.forwardRef((props, ref) => { } }; - const onMouseDown: React.MouseEventHandler = e => { + const onMouseDown: React.MouseEventHandler = (e) => { if (document.activeElement === inputRef.current?.input) { e.preventDefault(); } @@ -75,7 +75,7 @@ const Search = React.forwardRef((props, ref) => { }; const onPressEnter = (e: React.KeyboardEvent) => { - if (composedRef.current) { + if (composedRef.current || loading) { return; } onSearch(e); @@ -140,12 +140,12 @@ const Search = React.forwardRef((props, ref) => { className, ); - const handleOnCompositionStart: React.CompositionEventHandler = e => { + const handleOnCompositionStart: React.CompositionEventHandler = (e) => { composedRef.current = true; onCompositionStart?.(e); }; - const handleOnCompositionEnd: React.CompositionEventHandler = e => { + const handleOnCompositionEnd: React.CompositionEventHandler = (e) => { composedRef.current = false; onCompositionEnd?.(e); }; diff --git a/components/input/__tests__/Search.test.tsx b/components/input/__tests__/Search.test.tsx index a891512de4..028dcb510e 100644 --- a/components/input/__tests__/Search.test.tsx +++ b/components/input/__tests__/Search.test.tsx @@ -161,6 +161,13 @@ describe('Input.Search', () => { expect(asFragmentWithEnterButton().firstChild).toMatchSnapshot(); }); + it('should not trigger onSearch when press enter while loading', () => { + const onSearch = jest.fn(); + const { container } = render(); + fireEvent.keyDown(container.querySelector('input')!, { key: 'Enter', keyCode: 13 }); + expect(onSearch).not.toHaveBeenCalled(); + }); + it('should support addonAfter and suffix for loading', () => { const { asFragment } = render(); const { asFragment: asFragmentWithEnterButton } = render( diff --git a/components/layout/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/layout/__tests__/__snapshots__/demo-extend.test.ts.snap index c019790a4c..d915adaa47 100644 --- a/components/layout/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/layout/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -420,7 +420,7 @@ exports[`renders ./components/layout/demo/fixed.tsx extend context correctly 1`] >