diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 9f743ef8d6..cef7b8e68f 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -16,6 +16,20 @@ tag: vVERSION --- +## 5.20.2 + +`2024-08-19` + +- 💄 Fix the suffix style problem of InputNumber without control. [#50450](https://github.com/ant-design/ant-design/pull/50450) [@coding-ice](https://github.com/coding-ice) +- 🆕 Form `rule.message` supports skipping variable substitution through `\\${}`. [#50412](https://github.com/ant-design/ant-design/pull/50412) [@zombieJ](https://github.com/zombieJ) +- 🐞 Fixed the issue where the rounded corners of the trigger element are missing when the FloatButton component has shape="square" and in menu mode when the menu pops up. [#50408](https://github.com/ant-design/ant-design/pull/50408) [@li-jia-nan](https://github.com/li-jia-nan) +- 🐞 Fixed the problem that Upload.Dragger does not work when dragging and dropping upload folders. [#50394](https://github.com/ant-design/ant-design/pull/50394) [@huiliangShen](https://github.com/huiliangShen) +- 🐞 Fixed the issue where the arrow icon disappears after hovering when Select specifies `getPopcontainer={node=node.parentNode}`. [#50382](https://github.com/ant-design/ant-design/pull/50382) [@afc163](https://github.com/afc163) +- 🐞 Fixed the arrow misalignment error when Popover sets the `arrow.pointAtCenter` property. [#50260](https://github.com/ant-design/ant-design/pull/50260) [@Wxh16144](https://github.com/Wxh16144) +- 📖 Transfer adds Russian and Ukrainian localization copy. [#50429](https://github.com/ant-design/ant-design/pull/50429) [@alexlag](https://github.com/alexlag) +- TypeScript + - 🤖 Roll back the Table partial generic constraint object to any to reduce break changes caused by [#50351](https://github.com/ant-design/ant-design/pull/50351). [#50372](https://github.com/ant-design/ant-design/pull/50372) [@crazyair](https://github.com/crazyair) + ## 5.20.1 `2024-08-11` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 1d15d761ac..fd3b73bbb5 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -15,6 +15,20 @@ tag: vVERSION --- +## 5.20.2 + +`2024-08-19` + +- 💄 修复 InputNumber 没有控件的后缀样式问题。[#50450](https://github.com/ant-design/ant-design/pull/50450) [@coding-ice](https://github.com/coding-ice) +- 🆕 Form `rule.message` 支持通过 `\\${}` 跳过变量替换。[#50412](https://github.com/ant-design/ant-design/pull/50412) [@zombieJ](https://github.com/zombieJ) +- 🐞 修复了 FloatButton 组件当 shape=“square” 时,并且在菜单模式下,菜单弹出时 trigger 元素圆角缺失的问题。[#50408](https://github.com/ant-design/ant-design/pull/50408) [@li-jia-nan](https://github.com/li-jia-nan) +- 🐞 修复 Upload.Dragger 拖拽上传文件夹时不工作问题。[#50394](https://github.com/ant-design/ant-design/pull/50394) [@huiliangShen](https://github.com/huiliangShen) +- 🐞 修复 Select 指定 `getPopcontainer={node=node.parentNode}` 时箭头图标 hover 后会消失的问题。[#50382](https://github.com/ant-design/ant-design/pull/50382) [@afc163](https://github.com/afc163) +- 🐞 修复 Popover 设置 `arrow.pointAtCenter` 属性时箭头未对齐错误。[#50260](https://github.com/ant-design/ant-design/pull/50260) [@Wxh16144](https://github.com/Wxh16144) +- 📖 Transfer 补充俄罗斯语和乌克兰语本地化文案。[#50429](https://github.com/ant-design/ant-design/pull/50429) [@alexlag](https://github.com/alexlag) +- TypeScript + - 🤖 将 Table 部分泛型约束 object 回滚为 any,以减少 [#50351](https://github.com/ant-design/ant-design/pull/50351) 造成的 break change。[#50372](https://github.com/ant-design/ant-design/pull/50372) [@crazyair](https://github.com/crazyair) + ## 5.20.1 `2024-08-11` diff --git a/components/color-picker/__tests__/index.test.tsx b/components/color-picker/__tests__/index.test.tsx index 88b5dcef46..d325faabb8 100644 --- a/components/color-picker/__tests__/index.test.tsx +++ b/components/color-picker/__tests__/index.test.tsx @@ -34,12 +34,15 @@ function doMouseMove( }); fireEvent(ele, mouseDown); - // Drag - const mouseMove: any = new Event('mousemove'); - mouseMove.pageX = end; - mouseMove.pageY = end; - fireEvent(document, mouseMove); + // Drag + if (start !== end) { + const mouseMove: any = new Event('mousemove'); + mouseMove.pageX = end; + mouseMove.pageY = end; + + fireEvent(document, mouseMove); + } const mouseUp = createEvent.mouseUp(document); fireEvent(document, mouseUp); @@ -848,4 +851,32 @@ describe('ColorPicker', () => { ); }); }); + + it('onChangeComplete with default empty color should not be alpha', async () => { + const spyRect = spyElementPrototypes(HTMLElement, { + getBoundingClientRect: () => ({ + x: 0, + y: 100, + width: 100, + height: 100, + }), + }); + + const handleChangeComplete = jest.fn(); + const { container } = render(); + + // Move + doMouseMove(container, 50, 50); + expect(handleChangeComplete).toHaveBeenCalledTimes(1); + + const color = handleChangeComplete.mock.calls[0][0]; + expect(color.toRgb()).toEqual({ + r: 255, + g: 128, + b: 128, + a: 1, + }); + + spyRect.mockRestore(); + }); }); diff --git a/components/color-picker/components/PanelPicker/index.tsx b/components/color-picker/components/PanelPicker/index.tsx index 3939e6ad8f..c898e9b043 100644 --- a/components/color-picker/components/PanelPicker/index.tsx +++ b/components/color-picker/components/PanelPicker/index.tsx @@ -17,6 +17,11 @@ const components = { slider: ColorSlider, }; +type Info = { + type?: 'hue' | 'alpha'; + value?: number; +}; + const PanelPicker: FC = () => { const panelPickerContext = useContext(PanelPickerContext); @@ -81,32 +86,10 @@ const PanelPicker: FC = () => { }, [value, activeIndex, isSingle, lockedColor, gradientDragging]); // ============================ Change ============================ - const fillColor = (nextColor: AggregationColor) => { - if (mode === 'single') { - return nextColor; - } - - const nextColors = [...colors]; - nextColors[activeIndex] = { - ...nextColors[activeIndex], - color: nextColor, - }; - - return new AggregationColor(nextColors); - }; - - const onInternalChange = ( - colorValue: AggregationColor | Color, - fromPicker?: boolean, - info?: { - type?: 'hue' | 'alpha'; - value?: number; - }, - ) => { - const nextColor = generateColor(colorValue); - - let submitColor = nextColor; + const fillColor = (nextColor: AggregationColor | Color, info?: Info) => { + let submitColor = generateColor(nextColor); + // Fill alpha color to 100% if origin is cleared color if (value.cleared) { const rgb = submitColor.toRgb(); @@ -125,11 +108,29 @@ const PanelPicker: FC = () => { } } - onChange(fillColor(submitColor), fromPicker); + if (mode === 'single') { + return submitColor; + } + + const nextColors = [...colors]; + nextColors[activeIndex] = { + ...nextColors[activeIndex], + color: submitColor, + }; + + return new AggregationColor(nextColors); }; - const onInternalChangeComplete = (nextColor: AggregationColor) => { - onChangeComplete(fillColor(nextColor)); + const onInternalChange = ( + colorValue: AggregationColor | Color, + fromPicker?: boolean, + info?: Info, + ) => { + onChange(fillColor(colorValue, info), fromPicker); + }; + + const onInternalChangeComplete = (nextColor: Color, info?: Info) => { + onChangeComplete(fillColor(nextColor, info)); }; // ============================ Render ============================ @@ -170,8 +171,8 @@ const PanelPicker: FC = () => { onChange={(colorValue, info) => { onInternalChange(colorValue, true, info); }} - onChangeComplete={(colorValue) => { - onInternalChangeComplete(generateColor(colorValue)); + onChangeComplete={(colorValue, info) => { + onInternalChangeComplete(colorValue, info); }} components={components} /> diff --git a/components/float-button/FloatButtonGroup.tsx b/components/float-button/FloatButtonGroup.tsx index 2cac8128e8..277ef411e4 100644 --- a/components/float-button/FloatButtonGroup.tsx +++ b/components/float-button/FloatButtonGroup.tsx @@ -1,8 +1,9 @@ -import React, { memo, useCallback, useContext, useEffect } from 'react'; +import React from 'react'; import CloseOutlined from '@ant-design/icons/CloseOutlined'; import FileTextOutlined from '@ant-design/icons/FileTextOutlined'; import classNames from 'classnames'; import CSSMotion from 'rc-motion'; +import { useEvent } from 'rc-util'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; import { useZIndex } from '../_util/hooks/useZIndex'; @@ -12,10 +13,10 @@ import { ConfigContext } from '../config-provider'; import useCSSVarCls from '../config-provider/hooks/useCSSVarCls'; import { FloatButtonGroupProvider } from './context'; import FloatButton, { floatButtonPrefixCls } from './FloatButton'; -import type { FloatButtonGroupProps, FloatButtonRef } from './interface'; +import type { FloatButtonGroupProps } from './interface'; import useStyle from './style'; -const FloatButtonGroup: React.FC = (props) => { +const FloatButtonGroup: React.FC> = (props) => { const { prefixCls: customizePrefixCls, className, @@ -30,11 +31,12 @@ const FloatButtonGroup: React.FC = (props) => { children, onOpenChange, open: customOpen, + onClick: onTriggerButtonClick, ...floatButtonProps } = props; const { direction, getPrefixCls, floatButtonGroup } = - useContext(ConfigContext); + React.useContext(ConfigContext); const mergedCloseIcon = closeIcon ?? floatButtonGroup?.closeIcon ?? ; @@ -65,53 +67,53 @@ const FloatButtonGroup: React.FC = (props) => { const floatButtonGroupRef = React.useRef(null); - const floatButtonRef = React.useRef(null); + // ========================== Open ========================== + const hoverTrigger = trigger === 'hover'; + const clickTrigger = trigger === 'click'; - const hoverAction = React.useMemo>(() => { - const hoverTypeAction = { - onMouseEnter() { - setOpen(true); - onOpenChange?.(true); - }, - onMouseLeave() { - setOpen(false); - onOpenChange?.(false); - }, - }; - return trigger === 'hover' ? hoverTypeAction : {}; - }, [trigger]); + const triggerOpen = useEvent((nextOpen: boolean) => { + if (open !== nextOpen) { + setOpen(nextOpen); + onOpenChange?.(nextOpen); + } + }); - const handleOpenChange = () => { - setOpen((prevState) => { - onOpenChange?.(!prevState); - return !prevState; - }); + // ===================== Trigger: Hover ===================== + const onMouseEnter: React.MouseEventHandler = () => { + if (hoverTrigger) { + triggerOpen(true); + } }; - const onClick = useCallback( - (e: MouseEvent) => { - if (floatButtonGroupRef.current?.contains(e.target as Node)) { - if (floatButtonRef.current?.contains(e.target as Node)) { - handleOpenChange(); - } - return; - } - setOpen(false); - onOpenChange?.(false); - }, - [trigger], - ); - - useEffect(() => { - if (trigger === 'click') { - document.addEventListener('click', onClick); - return () => { - document.removeEventListener('click', onClick); - }; + const onMouseLeave: React.MouseEventHandler = () => { + if (hoverTrigger) { + triggerOpen(false); } - }, [trigger]); + }; - // =================== Warning ===================== + // ===================== Trigger: Click ===================== + const onInternalTriggerButtonClick: FloatButtonGroupProps['onClick'] = (e) => { + if (clickTrigger) { + triggerOpen(!open); + } + onTriggerButtonClick?.(e); + }; + + React.useEffect(() => { + if (clickTrigger) { + const onDocClick = (e: MouseEvent) => { + // Skip if click on the group + if (floatButtonGroupRef.current?.contains(e.target as Node)) { + return; + } + triggerOpen(false); + }; + document.addEventListener('click', onDocClick, { capture: true }); + return () => document.removeEventListener('click', onDocClick, { capture: true }); + } + }, [clickTrigger]); + + // ======================== Warning ========================= if (process.env.NODE_ENV !== 'production') { const warning = devUseWarning('FloatButton.Group'); @@ -122,9 +124,17 @@ const FloatButtonGroup: React.FC = (props) => { ); } + // ========================= Render ========================= return wrapCSSVar( -
+
{isMenuMode ? ( <> @@ -133,12 +143,12 @@ const FloatButtonGroup: React.FC = (props) => { )} @@ -150,4 +160,4 @@ const FloatButtonGroup: React.FC = (props) => { ); }; -export default memo(FloatButtonGroup); +export default FloatButtonGroup; diff --git a/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap index b780f628d5..fe995b4794 100644 --- a/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -30400,6 +30400,89 @@ exports[`renders components/form/demo/variant.tsx extend context correctly 1`] = class="ant-form ant-form-horizontal" style="max-width: 600px;" > +
+
+
+ +
+
+
+
+
+
+ + + +
+
+
+
+
+
+
diff --git a/components/form/__tests__/__snapshots__/demo.test.tsx.snap b/components/form/__tests__/__snapshots__/demo.test.tsx.snap index 8be3aac791..af9d57013b 100644 --- a/components/form/__tests__/__snapshots__/demo.test.tsx.snap +++ b/components/form/__tests__/__snapshots__/demo.test.tsx.snap @@ -12619,6 +12619,89 @@ exports[`renders components/form/demo/variant.tsx correctly 1`] = ` class="ant-form ant-form-horizontal" style="max-width:600px" > +
+
+
+ +
+
+
+
+
+
+ + + +
+
+
+
+
+
+
diff --git a/components/form/demo/variant.tsx b/components/form/demo/variant.tsx index ba9256a165..7f57329b9d 100644 --- a/components/form/demo/variant.tsx +++ b/components/form/demo/variant.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Button, Cascader, @@ -9,7 +9,9 @@ import { Mentions, Select, TreeSelect, + Segmented, } from 'antd'; +import type { FormProps } from 'antd'; const { RangePicker } = DatePicker; @@ -24,78 +26,99 @@ const formItemLayout = { }, }; -const App: React.FC = () => ( -
- - - +const App: React.FC = () => { + const [componentVariant, setComponentVariant] = useState('filled'); - { + setComponentVariant(variant); + }; + return ( + - - + + + - - - + + + - - - + + + - - + - - - + + + - - - + + + - - - - -); + + + + + + + + + + + + + ); +}; export default App; diff --git a/components/tabs/style/index.ts b/components/tabs/style/index.ts index a9c3d18df9..73cbda9edf 100644 --- a/components/tabs/style/index.ts +++ b/components/tabs/style/index.ts @@ -38,7 +38,7 @@ export interface ComponentToken { */ cardPaddingLG: string; /** - * @desc 标齐页标题文本大小 + * @desc 标签页标题文本大小 * @descEN Font size of title */ titleFontSize: number; diff --git a/package.json b/package.json index 63feea87d8..d5e1c2ea4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "5.20.1", + "version": "5.20.2", "description": "An enterprise-class UI design language and React components implementation", "keywords": [ "ant",