From 0846d4fce74f832d6e35b35246fb3992d4e4b0ce Mon Sep 17 00:00:00 2001 From: Yuki Zhang Date: Fri, 13 May 2022 14:40:56 +0800 Subject: [PATCH 1/7] refactor: modal confirm button style (#35530) * fix: modal rtl style * fix: cannot use logic css * chore: change css writing order --- components/modal/style/confirm.less | 2 +- components/modal/style/rtl.less | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/modal/style/confirm.less b/components/modal/style/confirm.less index dfe34d1d20..dc750b2deb 100644 --- a/components/modal/style/confirm.less +++ b/components/modal/style/confirm.less @@ -46,8 +46,8 @@ } .@{confirm-prefix-cls}-btns { - float: right; margin-top: 24px; + text-align: right; .@{ant-prefix}-btn + .@{ant-prefix}-btn { margin-bottom: 0; diff --git a/components/modal/style/rtl.less b/components/modal/style/rtl.less index 8a19025b6b..6cf9ad5b32 100644 --- a/components/modal/style/rtl.less +++ b/components/modal/style/rtl.less @@ -53,7 +53,7 @@ &-btns { .@{dialog-wrap-rtl-cls} & { - float: left; + text-align: left; } .@{ant-prefix}-btn + .@{ant-prefix}-btn { .@{dialog-wrap-rtl-cls} & { From f56e66a2626c1ce5bc4f309a92629f379da87c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Sat, 14 May 2022 16:34:35 +0800 Subject: [PATCH 2/7] fix: Picker focus & blur not working (#35552) --- .../generatePicker/generateRangePicker.tsx | 204 ++++++++-------- .../generatePicker/generateSinglePicker.tsx | 227 +++++++++--------- 2 files changed, 206 insertions(+), 225 deletions(-) diff --git a/components/date-picker/generatePicker/generateRangePicker.tsx b/components/date-picker/generatePicker/generateRangePicker.tsx index a1c54de61b..7bd19851d4 100644 --- a/components/date-picker/generatePicker/generateRangePicker.tsx +++ b/components/date-picker/generatePicker/generateRangePicker.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { forwardRef, useContext } from 'react'; +import { forwardRef, useContext, useImperativeHandle } from 'react'; import classNames from 'classnames'; import CalendarOutlined from '@ant-design/icons/CalendarOutlined'; import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined'; @@ -17,127 +17,117 @@ import type { PickerLocale, RangePickerProps } from '.'; import { Components, getTimeProps } from '.'; import { FormItemInputContext } from '../../form/context'; import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; -import type { PickerComponentClass } from './interface'; +import type { PickerComponentClass, CommonPickerMethods } from './interface'; export default function generateRangePicker( generateConfig: GenerateConfig, ): PickerComponentClass> { type InternalRangePickerProps = RangePickerProps & {}; - const RangePicker = forwardRef>( - (props, ref) => { - const { - prefixCls: customizePrefixCls, - getPopupContainer: customGetPopupContainer, - className, - placement, - size: customizeSize, - disabled: customDisabled, - bordered = true, - placeholder, - status: customStatus, - onBlur, - onFocus, - ...restProps - } = props; + const RangePicker = forwardRef< + InternalRangePickerProps | CommonPickerMethods, + RangePickerProps + >((props, ref) => { + const { + prefixCls: customizePrefixCls, + getPopupContainer: customGetPopupContainer, + className, + placement, + size: customizeSize, + disabled: customDisabled, + bordered = true, + placeholder, + status: customStatus, + ...restProps + } = props; - const pickerRef = (ref as any) || React.createRef>(); - const { getPrefixCls, direction, getPopupContainer } = useContext(ConfigContext); - const prefixCls = getPrefixCls('picker', customizePrefixCls); - const { format, showTime, picker } = props as any; - const rootPrefixCls = getPrefixCls(); + const innerRef = React.useRef>(null); + const { getPrefixCls, direction, getPopupContainer } = useContext(ConfigContext); + const prefixCls = getPrefixCls('picker', customizePrefixCls); + const { format, showTime, picker } = props as any; + const rootPrefixCls = getPrefixCls(); - let additionalOverrideProps: any = {}; - additionalOverrideProps = { - ...additionalOverrideProps, - ...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}), - ...(picker === 'time' ? getTimeProps({ format, ...props, picker }) : {}), - }; + let additionalOverrideProps: any = {}; + additionalOverrideProps = { + ...additionalOverrideProps, + ...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}), + ...(picker === 'time' ? getTimeProps({ format, ...props, picker }) : {}), + }; - // ===================== Size ===================== - const size = React.useContext(SizeContext); - const mergedSize = customizeSize || size; + // ===================== Size ===================== + const size = React.useContext(SizeContext); + const mergedSize = customizeSize || size; - // ===================== Disabled ===================== - const disabled = React.useContext(DisabledContext); - const mergedDisabled = customDisabled || disabled; + // ===================== Disabled ===================== + const disabled = React.useContext(DisabledContext); + const mergedDisabled = customDisabled || disabled; - // ===================== FormItemInput ===================== - const formItemContext = useContext(FormItemInputContext); - const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext; + // ===================== FormItemInput ===================== + const formItemContext = useContext(FormItemInputContext); + const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext; - const suffixNode = ( - <> - {picker === 'time' ? : } - {hasFeedback && feedbackIcon} - - ); + const suffixNode = ( + <> + {picker === 'time' ? : } + {hasFeedback && feedbackIcon} + + ); - const focus = () => { - if (pickerRef.current) { - pickerRef.current.focus(); - } - }; + useImperativeHandle(ref, () => ({ + focus: () => innerRef.current?.focus(), + blur: () => innerRef.current?.blur(), + })); - const blur = () => { - if (pickerRef.current) { - pickerRef.current.blur(); - } - }; + return ( + + {(contextLocale: PickerLocale) => { + const locale = { ...contextLocale, ...props.locale }; - return ( - - {(contextLocale: PickerLocale) => { - const locale = { ...contextLocale, ...props.locale }; - - return ( - - separator={ - - - - } - disabled={mergedDisabled} - ref={pickerRef} - onBlur={onBlur || blur} - onFocus={onFocus || focus} - dropdownAlign={transPlacement2DropdownAlign(direction, placement)} - placeholder={getRangePlaceholder(picker, locale, placeholder)} - suffixIcon={suffixNode} - clearIcon={} - prevIcon={} - nextIcon={} - superPrevIcon={} - superNextIcon={} - allowClear - transitionName={`${rootPrefixCls}-slide-up`} - {...restProps} - {...additionalOverrideProps} - className={classNames( - { - [`${prefixCls}-${mergedSize}`]: mergedSize, - [`${prefixCls}-borderless`]: !bordered, - }, - getStatusClassNames( - prefixCls as string, - getMergedStatus(contextStatus, customStatus), - hasFeedback, - ), - className, - )} - locale={locale!.lang} - prefixCls={prefixCls} - getPopupContainer={customGetPopupContainer || getPopupContainer} - generateConfig={generateConfig} - components={Components} - direction={direction} - /> - ); - }} - - ); - }, - ); + return ( + + separator={ + + + + } + disabled={mergedDisabled} + ref={innerRef} + dropdownAlign={transPlacement2DropdownAlign(direction, placement)} + placeholder={getRangePlaceholder(picker, locale, placeholder)} + suffixIcon={suffixNode} + clearIcon={} + prevIcon={} + nextIcon={} + superPrevIcon={} + superNextIcon={} + allowClear + transitionName={`${rootPrefixCls}-slide-up`} + {...restProps} + {...additionalOverrideProps} + className={classNames( + { + [`${prefixCls}-${mergedSize}`]: mergedSize, + [`${prefixCls}-borderless`]: !bordered, + }, + getStatusClassNames( + prefixCls as string, + getMergedStatus(contextStatus, customStatus), + hasFeedback, + ), + className, + )} + locale={locale!.lang} + prefixCls={prefixCls} + getPopupContainer={customGetPopupContainer || getPopupContainer} + generateConfig={generateConfig} + components={Components} + direction={direction} + /> + ); + }} + + ); + }); return RangePicker as unknown as PickerComponentClass>; } diff --git a/components/date-picker/generatePicker/generateSinglePicker.tsx b/components/date-picker/generatePicker/generateSinglePicker.tsx index 548e1bda90..c9ad89d509 100644 --- a/components/date-picker/generatePicker/generateSinglePicker.tsx +++ b/components/date-picker/generatePicker/generateSinglePicker.tsx @@ -6,7 +6,7 @@ import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; import RCPicker from 'rc-picker'; import type { PickerMode } from 'rc-picker/lib/interface'; import type { GenerateConfig } from 'rc-picker/lib/generate/index'; -import { forwardRef, useContext } from 'react'; +import { forwardRef, useContext, useImperativeHandle } from 'react'; import enUS from '../locale/en_US'; import { getPlaceholder, transPlacement2DropdownAlign } from '../util'; import warning from '../../_util/warning'; @@ -19,7 +19,7 @@ import { getTimeProps, Components } from '.'; import { FormItemInputContext } from '../../form/context'; import type { InputStatus } from '../../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; -import type { DatePickRef, PickerComponentClass } from './interface'; +import type { DatePickRef, PickerComponentClass, CommonPickerMethods } from './interface'; export default function generatePicker(generateConfig: GenerateConfig) { type DatePickerProps = PickerProps & { @@ -30,131 +30,122 @@ export default function generatePicker(generateConfig: GenerateConfig< picker?: PickerMode, displayName?: string, ) { - const Picker = forwardRef, InnerPickerProps>((props, ref) => { - const { - prefixCls: customizePrefixCls, - getPopupContainer: customizeGetPopupContainer, - className, - size: customizeSize, - bordered = true, - placement, - placeholder, - disabled: customDisabled, - status: customStatus, - onBlur, - onFocus, - ...restProps - } = props; + const Picker = forwardRef | CommonPickerMethods, InnerPickerProps>( + (props, ref) => { + const { + prefixCls: customizePrefixCls, + getPopupContainer: customizeGetPopupContainer, + className, + size: customizeSize, + bordered = true, + placement, + placeholder, + disabled: customDisabled, + status: customStatus, + ...restProps + } = props; - warning( - picker !== 'quarter', - displayName!, - `DatePicker.${displayName} is legacy usage. Please use DatePicker[picker='${picker}'] directly.`, - ); + warning( + picker !== 'quarter', + displayName!, + `DatePicker.${displayName} is legacy usage. Please use DatePicker[picker='${picker}'] directly.`, + ); - const { getPrefixCls, direction, getPopupContainer } = useContext(ConfigContext); - const prefixCls = getPrefixCls('picker', customizePrefixCls); - const pickerRef = (ref as any) || React.createRef>(); - const { format, showTime } = props as any; + const { getPrefixCls, direction, getPopupContainer } = useContext(ConfigContext); + const prefixCls = getPrefixCls('picker', customizePrefixCls); + const innerRef = React.useRef>(null); + const { format, showTime } = props as any; - const additionalProps = { - showToday: true, - }; + useImperativeHandle(ref, () => ({ + focus: () => innerRef.current?.focus(), + blur: () => innerRef.current?.blur(), + })); - let additionalOverrideProps: any = {}; - if (picker) { - additionalOverrideProps.picker = picker; - } - const mergedPicker = picker || props.picker; + const additionalProps = { + showToday: true, + }; - additionalOverrideProps = { - ...additionalOverrideProps, - ...(showTime ? getTimeProps({ format, picker: mergedPicker, ...showTime }) : {}), - ...(mergedPicker === 'time' - ? getTimeProps({ format, ...props, picker: mergedPicker }) - : {}), - }; - const rootPrefixCls = getPrefixCls(); - - // ===================== Size ===================== - const size = React.useContext(SizeContext); - const mergedSize = customizeSize || size; - - // ===================== Disabled ===================== - const disabled = React.useContext(DisabledContext); - const mergedDisabled = customDisabled || disabled; - - // ===================== FormItemInput ===================== - const formItemContext = useContext(FormItemInputContext); - const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext; - - const suffixNode = ( - <> - {mergedPicker === 'time' ? : } - {hasFeedback && feedbackIcon} - - ); - - const focus = () => { - if (pickerRef.current) { - pickerRef.current.focus(); + let additionalOverrideProps: any = {}; + if (picker) { + additionalOverrideProps.picker = picker; } - }; + const mergedPicker = picker || props.picker; - const blur = () => { - if (pickerRef.current) { - pickerRef.current.blur(); - } - }; + additionalOverrideProps = { + ...additionalOverrideProps, + ...(showTime ? getTimeProps({ format, picker: mergedPicker, ...showTime }) : {}), + ...(mergedPicker === 'time' + ? getTimeProps({ format, ...props, picker: mergedPicker }) + : {}), + }; + const rootPrefixCls = getPrefixCls(); - return ( - - {(contextLocale: PickerLocale) => { - const locale = { ...contextLocale, ...props.locale }; + // ===================== Size ===================== + const size = React.useContext(SizeContext); + const mergedSize = customizeSize || size; - return ( - - ref={pickerRef} - placeholder={getPlaceholder(mergedPicker, locale, placeholder)} - suffixIcon={suffixNode} - dropdownAlign={transPlacement2DropdownAlign(direction, placement)} - clearIcon={} - prevIcon={} - nextIcon={} - superPrevIcon={} - superNextIcon={} - allowClear - transitionName={`${rootPrefixCls}-slide-up`} - onBlur={onBlur || blur} - onFocus={onFocus || focus} - {...additionalProps} - {...restProps} - {...additionalOverrideProps} - locale={locale!.lang} - className={classNames( - { - [`${prefixCls}-${mergedSize}`]: mergedSize, - [`${prefixCls}-borderless`]: !bordered, - }, - getStatusClassNames( - prefixCls as string, - getMergedStatus(contextStatus, customStatus), - hasFeedback, - ), - className, - )} - prefixCls={prefixCls} - getPopupContainer={customizeGetPopupContainer || getPopupContainer} - generateConfig={generateConfig} - components={Components} - direction={direction} - disabled={mergedDisabled} - /> - ); - }} - - ); - }); + // ===================== Disabled ===================== + const disabled = React.useContext(DisabledContext); + const mergedDisabled = customDisabled || disabled; + + // ===================== FormItemInput ===================== + const formItemContext = useContext(FormItemInputContext); + const { hasFeedback, status: contextStatus, feedbackIcon } = formItemContext; + + const suffixNode = ( + <> + {mergedPicker === 'time' ? : } + {hasFeedback && feedbackIcon} + + ); + + return ( + + {(contextLocale: PickerLocale) => { + const locale = { ...contextLocale, ...props.locale }; + + return ( + + ref={innerRef} + placeholder={getPlaceholder(mergedPicker, locale, placeholder)} + suffixIcon={suffixNode} + dropdownAlign={transPlacement2DropdownAlign(direction, placement)} + clearIcon={} + prevIcon={} + nextIcon={} + superPrevIcon={} + superNextIcon={} + allowClear + transitionName={`${rootPrefixCls}-slide-up`} + {...additionalProps} + {...restProps} + {...additionalOverrideProps} + locale={locale!.lang} + className={classNames( + { + [`${prefixCls}-${mergedSize}`]: mergedSize, + [`${prefixCls}-borderless`]: !bordered, + }, + getStatusClassNames( + prefixCls as string, + getMergedStatus(contextStatus, customStatus), + hasFeedback, + ), + className, + )} + prefixCls={prefixCls} + getPopupContainer={customizeGetPopupContainer || getPopupContainer} + generateConfig={generateConfig} + components={Components} + direction={direction} + disabled={mergedDisabled} + /> + ); + }} + + ); + }, + ); if (displayName) { Picker.displayName = displayName; From 2631855b4ea4a34e42b978fd41134d1a23743ca3 Mon Sep 17 00:00:00 2001 From: MadCcc <1075746765@qq.com> Date: Sun, 15 May 2022 15:11:25 +0800 Subject: [PATCH 3/7] docs: changelog 4.20.5 (#35560) --- CHANGELOG.en-US.md | 7 +++++++ CHANGELOG.zh-CN.md | 7 +++++++ package.json | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 31d1467860..ca9e0091ca 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -15,6 +15,13 @@ timeline: true --- +## 4.20.5 + +`2022-05-15` + +- 🤖 Deprecated Table `rowSelection.onSelectNone` and `rowSelection.onSelectMultiple` in TS type. [#35545](https://github.com/ant-design/ant-design/pull/35545) +- 🐞 Ignore the decimal part in InputNumber when the precision is negative. [#35520](https://github.com/ant-design/ant-design/pull/35520) [@ty888](https://github.com/ty888) + ## 4.20.4 `2022-05-11` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index d4b6b25157..b0545bd1bf 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -15,6 +15,13 @@ timeline: true --- +## 4.20.5 + +`2022-05-15 + +- 🤖 在 TypeScript 定义中废弃 Table `rowSelection.onSelectNone` 和 `rowSelection.onSelectMultiple`。[#35545](https://github.com/ant-design/ant-design/pull/35545) +- 🐞 InputNUmber 当精度为负数时忽略小数部分。[#35520](https://github.com/ant-design/ant-design/pull/35520) [@ty888](https://github.com/ty888)` + ## 4.20.4 `2022-05-11` diff --git a/package.json b/package.json index 88bac2aaf4..dbba191efc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "4.20.4", + "version": "4.20.5", "description": "An enterprise-class UI design language and React components implementation", "title": "Ant Design", "keywords": [ From 47d40325feceb6264ff74ac53e71e7b04334a92a Mon Sep 17 00:00:00 2001 From: zombiej Date: Sun, 15 May 2022 18:48:24 +0800 Subject: [PATCH 4/7] chore: Update github action release helper release title --- .github/workflows/release-helper.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-helper.yml b/.github/workflows/release-helper.yml index 61723624cc..f2ab3d29a9 100644 --- a/.github/workflows/release-helper.yml +++ b/.github/workflows/release-helper.yml @@ -28,6 +28,7 @@ jobs: branch: 'master' dingding-token: ${{ secrets.DINGDING_BOT_TOKEN }} ${{ secrets.DINGDING_BOT_BIGFISH_TOKEN }} dingding-msg: 'CHANGELOG.zh-CN.md' + msg-title: '# Ant Design {{v}} 发布日志' msg-poster: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*zx7LTI_ECSAAAAAAAAAAAABkARQnAQ' msg-footer: '💬 前往 [**Ant Design Releases**]({{url}}) 查看更新日志' prettier: true From 644e4bfc6ad66367d6485344ca49b1b541338126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <7971419+crazyair@users.noreply.github.com> Date: Mon, 16 May 2022 10:14:26 +0800 Subject: [PATCH 5/7] fix: drawer close speed (#35339) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: drawer close speed * chroe: snap * chroe: test * chroe: test * feat: remove file * feat: 重新整理 * feat: forceRender * feat: snap * chroe: test * chroe: test * chroe: test * feat: create event * feat: diff code * feat: forceRender * chore: test (#35364) * Update components/drawer/index.tsx Co-authored-by: afc163 * feat: remove load state * feat: test * fix: destroyOnClose * feat: add load * fix: update snap * fix: update snap * feat: reset test * feat: docs * feat: test * feat: test Co-authored-by: afc163 --- .../drawer/__tests__/DrawerEvent.test.js | 17 ++++- .../__snapshots__/Drawer.test.js.snap | 2 - components/drawer/index.tsx | 73 ++++++++++--------- 3 files changed, 53 insertions(+), 39 deletions(-) diff --git a/components/drawer/__tests__/DrawerEvent.test.js b/components/drawer/__tests__/DrawerEvent.test.js index 4e39699478..e7973683a8 100644 --- a/components/drawer/__tests__/DrawerEvent.test.js +++ b/components/drawer/__tests__/DrawerEvent.test.js @@ -50,7 +50,9 @@ describe('Drawer', () => { const { container, rerender } = render(getDrawer({ destroyOnClose: true })); rerender(getDrawer({ destroyOnClose: true, visible: false })); - fireEvent.transitionEnd(container.querySelector('.ant-drawer-wrapper-body')); + const ev = new TransitionEvent('transitionend', { bubbles: true }); + ev.propertyName = 'transform'; + fireEvent(document.querySelector('.ant-drawer-content-wrapper'), ev); expect(container.querySelector('.ant-drawer-wrapper-body')).toBeFalsy(); }); @@ -60,8 +62,19 @@ describe('Drawer', () => { expect(container.querySelector('.ant-drawer-wrapper-body')).toBeTruthy(); rerender(getDrawer({ visible: false })); - fireEvent.transitionEnd(container.querySelector('.ant-drawer-wrapper-body')); + const ev = new TransitionEvent('transitionend', { bubbles: true }); + ev.propertyName = 'transform'; + fireEvent(document.querySelector('.ant-drawer-content-wrapper'), ev); expect(container.querySelector('.ant-drawer-wrapper-body')).toBeTruthy(); }); + it('test afterVisibleChange', async () => { + const afterVisibleChange = jest.fn(); + const { rerender } = render(getDrawer({ afterVisibleChange, visible: true })); + rerender(getDrawer({ afterVisibleChange, visible: false })); + const ev = new TransitionEvent('transitionend', { bubbles: true }); + ev.propertyName = 'transform'; + fireEvent(document.querySelector('.ant-drawer-content-wrapper'), ev); + expect(afterVisibleChange).toBeCalledTimes(1); + }); }); diff --git a/components/drawer/__tests__/__snapshots__/Drawer.test.js.snap b/components/drawer/__tests__/__snapshots__/Drawer.test.js.snap index 70de5f365c..5b2c71c7d7 100644 --- a/components/drawer/__tests__/__snapshots__/Drawer.test.js.snap +++ b/components/drawer/__tests__/__snapshots__/Drawer.test.js.snap @@ -20,7 +20,6 @@ exports[`Drawer className is test_drawer 1`] = ` >
( bodyStyle, drawerStyle, className, - visible, + visible: propsVisible, + forceRender, children, zIndex, destroyOnClose, @@ -100,14 +100,31 @@ const Drawer = React.forwardRef( prefixCls: customizePrefixCls, getContainer: customizeGetContainer, extra, + afterVisibleChange, ...rest }, ref, ) => { - const forceUpdate = useForceUpdate(); const [internalPush, setPush] = React.useState(false); const parentDrawer = React.useContext(DrawerContext); - const destroyClose = React.useRef(false); + const destroyCloseRef = React.useRef(false); + + const [load, setLoad] = React.useState(false); + const [visible, setVisible] = React.useState(false); + + React.useEffect(() => { + if (propsVisible) { + setLoad(true); + } else { + setVisible(false); + } + }, [propsVisible]); + + React.useEffect(() => { + if (load && propsVisible) { + setVisible(true); + } + }, [load, propsVisible]); const { getPopupContainer, getPrefixCls, direction } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('drawer', customizePrefixCls); @@ -120,7 +137,7 @@ const Drawer = React.forwardRef( React.useEffect(() => { // fix: delete drawer in child and re-render, no push started. // {show && } - if (visible && parentDrawer) { + if (propsVisible && parentDrawer) { parentDrawer.push(); } @@ -160,18 +177,6 @@ const Drawer = React.forwardRef( React.useImperativeHandle(ref, () => operations, [operations]); - const isDestroyOnClose = destroyOnClose && !visible; - - const onDestroyTransitionEnd = () => { - if (!isDestroyOnClose) { - return; - } - if (!visible) { - destroyClose.current = true; - forceUpdate(); - } - }; - const getOffsetStyle = () => { // https://github.com/ant-design/ant-design/issues/24287 if (!visible && !mask) { @@ -260,28 +265,13 @@ const Drawer = React.forwardRef( // render drawer body dom const renderBody = () => { - if (destroyClose.current && !visible) { + // destroyCloseRef.current =false Load the body only once by default + if (destroyCloseRef.current && !forceRender && !load) { return null; } - destroyClose.current = false; - - const containerStyle: React.CSSProperties = {}; - - if (isDestroyOnClose) { - // Increase the opacity transition, delete children after closing. - containerStyle.opacity = 0; - containerStyle.transition = 'opacity .3s'; - } return ( -
+
{renderHeader()}
{children} @@ -312,6 +302,7 @@ const Drawer = React.forwardRef( keyboard, children, onClose, + forceRender, ...rest, }} {...offsetStyle} @@ -320,6 +311,18 @@ const Drawer = React.forwardRef( style={getRcDrawerStyle()} className={drawerClassName} getContainer={getContainer} + afterVisibleChange={open => { + if (!open) { + if (destroyCloseRef.current === false) { + // set true only once + destroyCloseRef.current = true; + } + if (destroyOnClose) { + setLoad(false); + } + } + afterVisibleChange?.(open); + }} > {renderBody()} From a909fbb7e76ee703e04c89de0ae03f7defd2379d Mon Sep 17 00:00:00 2001 From: MadCcc <1075746765@qq.com> Date: Mon, 16 May 2022 11:09:58 +0800 Subject: [PATCH 6/7] docs: fix 4.20.5 changelog typo (#35567) --- CHANGELOG.en-US.md | 2 +- CHANGELOG.zh-CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index ca9e0091ca..2faa7ac10a 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -20,7 +20,7 @@ timeline: true `2022-05-15` - 🤖 Deprecated Table `rowSelection.onSelectNone` and `rowSelection.onSelectMultiple` in TS type. [#35545](https://github.com/ant-design/ant-design/pull/35545) -- 🐞 Ignore the decimal part in InputNumber when the precision is negative. [#35520](https://github.com/ant-design/ant-design/pull/35520) [@ty888](https://github.com/ty888) +- 🐞 Ignore the decimal part in InputNumber when `precision` is negative. [#35520](https://github.com/ant-design/ant-design/pull/35520) [@ty888](https://github.com/ty888) ## 4.20.4 diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index b0545bd1bf..c487a2b774 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -20,7 +20,7 @@ timeline: true `2022-05-15 - 🤖 在 TypeScript 定义中废弃 Table `rowSelection.onSelectNone` 和 `rowSelection.onSelectMultiple`。[#35545](https://github.com/ant-design/ant-design/pull/35545) -- 🐞 InputNUmber 当精度为负数时忽略小数部分。[#35520](https://github.com/ant-design/ant-design/pull/35520) [@ty888](https://github.com/ty888)` +- 🐞 InputNumber 当精度为负数时忽略小数部分。[#35520](https://github.com/ant-design/ant-design/pull/35520) [@ty888](https://github.com/ty888)` ## 4.20.4 From 3d21ec54e2078b4919c7a0e56ef3daf83476bde0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Mon, 16 May 2022 16:34:42 +0800 Subject: [PATCH 7/7] refactor: reduce empty cycling deps (#35570) * chore: rm in root * chore: fix ts * test: Update snapshot * chore: ignore part --- components/cascader/index.tsx | 3 +- .../__snapshots__/index.test.js.snap | 76 ------------------- .../config-provider/__tests__/index.test.js | 15 +++- components/config-provider/context.tsx | 8 +- ...renderEmpty.tsx => defaultRenderEmpty.tsx} | 9 ++- components/config-provider/index.tsx | 2 +- components/list/index.tsx | 3 +- components/mentions/index.tsx | 3 +- components/select/index.tsx | 3 +- components/table/Table.tsx | 3 +- components/transfer/index.tsx | 3 +- components/tree-select/index.tsx | 3 +- 12 files changed, 35 insertions(+), 96 deletions(-) delete mode 100644 components/config-provider/__tests__/__snapshots__/index.test.js.snap rename components/config-provider/{renderEmpty.tsx => defaultRenderEmpty.tsx} (71%) diff --git a/components/cascader/index.tsx b/components/cascader/index.tsx index c76c98207c..516f91429a 100644 --- a/components/cascader/index.tsx +++ b/components/cascader/index.tsx @@ -16,6 +16,7 @@ import LeftOutlined from '@ant-design/icons/LeftOutlined'; import { useContext } from 'react'; import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; +import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; import type { SizeType } from '../config-provider/SizeContext'; import SizeContext from '../config-provider/SizeContext'; import DisabledContext from '../config-provider/DisabledContext'; @@ -175,7 +176,7 @@ const Cascader = React.forwardRef((props: CascaderProps, ref: React.Ref -
- - - - - - - - - - - - - - - - -
-
- No Data -
-
-`; diff --git a/components/config-provider/__tests__/index.test.js b/components/config-provider/__tests__/index.test.js index aecf780620..6189748304 100644 --- a/components/config-provider/__tests__/index.test.js +++ b/components/config-provider/__tests__/index.test.js @@ -1,12 +1,12 @@ import React, { useState } from 'react'; import { mount } from 'enzyme'; import { SmileOutlined } from '@ant-design/icons'; -import { fireEvent, render } from '@testing-library/react'; import ConfigProvider, { ConfigContext } from '..'; import Button from '../../button'; import Table from '../../table'; import Input from '../../input'; import mountTest from '../../../tests/shared/mountTest'; +import { render, fireEvent } from '../../../tests/utils'; describe('ConfigProvider', () => { mountTest(() => ( @@ -104,16 +104,23 @@ describe('ConfigProvider', () => { }); it('render empty', () => { + let rendered = false; + let cacheRenderEmpty; + const App = () => { const { renderEmpty } = React.useContext(ConfigContext); - return renderEmpty(); + rendered = true; + cacheRenderEmpty = renderEmpty; + return null; }; - const wrapper = mount( + + render( , ); - expect(wrapper.render()).toMatchSnapshot(); + expect(rendered).toBeTruthy(); + expect(cacheRenderEmpty).toBeFalsy(); }); }); diff --git a/components/config-provider/context.tsx b/components/config-provider/context.tsx index 5c61ba4515..c0d21059e9 100644 --- a/components/config-provider/context.tsx +++ b/components/config-provider/context.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; -import type { RenderEmptyHandler } from './renderEmpty'; -import defaultRenderEmpty from './renderEmpty'; +import type { RenderEmptyHandler } from './defaultRenderEmpty'; import type { Locale } from '../locale-provider'; import type { SizeType } from './SizeContext'; import type { RequiredMark } from '../form/Form'; @@ -26,7 +25,7 @@ export interface ConfigConsumerProps { rootPrefixCls?: string; iconPrefixCls?: string; getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string; - renderEmpty: RenderEmptyHandler; + renderEmpty?: RenderEmptyHandler; csp?: CSPConfig; autoInsertSpaceInButton?: boolean; input?: { @@ -54,11 +53,10 @@ const defaultGetPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => return suffixCls ? `ant-${suffixCls}` : 'ant'; }; +// zombieJ: 🚨 Do not pass `defaultRenderEmpty` here since it will case circular dependency. export const ConfigContext = React.createContext({ // We provide a default function for Context without provider getPrefixCls: defaultGetPrefixCls, - - renderEmpty: defaultRenderEmpty, }); export const ConfigConsumer = ConfigContext.Consumer; diff --git a/components/config-provider/renderEmpty.tsx b/components/config-provider/defaultRenderEmpty.tsx similarity index 71% rename from components/config-provider/renderEmpty.tsx rename to components/config-provider/defaultRenderEmpty.tsx index 86830f9be1..b81a8f7124 100644 --- a/components/config-provider/renderEmpty.tsx +++ b/components/config-provider/defaultRenderEmpty.tsx @@ -3,7 +3,7 @@ import Empty from '../empty'; import type { ConfigConsumerProps } from '.'; import { ConfigConsumer } from '.'; -const renderEmpty = (componentName?: string): React.ReactNode => ( +const defaultRenderEmpty = (componentName?: string): React.ReactNode => ( {({ getPrefixCls }: ConfigConsumerProps) => { const prefix = getPrefixCls('empty'); @@ -19,13 +19,16 @@ const renderEmpty = (componentName?: string): React.ReactNode => ( case 'Transfer': case 'Mentions': return ; + + /* istanbul ignore next */ default: + // Should never hit if we take all the component into consider. return ; } }} ); -export type RenderEmptyHandler = typeof renderEmpty; +export type RenderEmptyHandler = typeof defaultRenderEmpty; -export default renderEmpty; +export default defaultRenderEmpty; diff --git a/components/config-provider/index.tsx b/components/config-provider/index.tsx index 94cb85ff39..a66a36b964 100644 --- a/components/config-provider/index.tsx +++ b/components/config-provider/index.tsx @@ -3,7 +3,7 @@ import IconContext from '@ant-design/icons/lib/components/Context'; import { FormProvider as RcFormProvider } from 'rc-field-form'; import type { ValidateMessages } from 'rc-field-form/lib/interface'; import useMemo from 'rc-util/lib/hooks/useMemo'; -import { RenderEmptyHandler } from './renderEmpty'; +import { RenderEmptyHandler } from './defaultRenderEmpty'; import type { Locale } from '../locale-provider'; import LocaleProvider, { ANT_MARK } from '../locale-provider'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; diff --git a/components/list/index.tsx b/components/list/index.tsx index a942c0fc05..56b082243b 100644 --- a/components/list/index.tsx +++ b/components/list/index.tsx @@ -11,6 +11,7 @@ import type { PaginationConfig } from '../pagination'; import Pagination from '../pagination'; import { Row } from '../grid'; import Item from './Item'; +import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; export { ListItemProps, ListItemMetaProps } from './Item'; @@ -259,7 +260,7 @@ function List({
    {items}
); } else if (!children && !isLoading) { - childrenContent = renderEmptyFunc(prefixCls, renderEmpty); + childrenContent = renderEmptyFunc(prefixCls, renderEmpty || defaultRenderEmpty); } const paginationPosition = paginationProps.position || 'bottom'; diff --git a/components/mentions/index.tsx b/components/mentions/index.tsx index e4b688a43d..be548e164b 100644 --- a/components/mentions/index.tsx +++ b/components/mentions/index.tsx @@ -8,6 +8,7 @@ import { ConfigContext } from '../config-provider'; import { FormItemInputContext } from '../form/context'; import type { InputStatus } from '../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; +import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; export const { Option } = RcMentions; @@ -93,7 +94,7 @@ const InternalMentions: React.ForwardRefRenderFunction = return notFoundContent; } - return renderEmpty('Select'); + return (renderEmpty || defaultRenderEmpty)('Select'); }; const getOptions = () => { diff --git a/components/select/index.tsx b/components/select/index.tsx index d34f1cf24f..99bda4878f 100755 --- a/components/select/index.tsx +++ b/components/select/index.tsx @@ -18,6 +18,7 @@ import type { InputStatus } from '../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; import type { SelectCommonPlacement } from '../_util/motion'; import { getTransitionName, getTransitionDirection } from '../_util/motion'; +import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; type RawValue = string | number; @@ -122,7 +123,7 @@ const InternalSelect = ( data={pageData} rowKey={getRowKey} rowClassName={internalRowClassName} - emptyText={(locale && locale.emptyText) || renderEmpty('Table')} + emptyText={(locale && locale.emptyText) || (renderEmpty || defaultRenderEmpty)('Table')} // Internal internalHooks={INTERNAL_HOOKS} internalRefs={internalRefs as any} diff --git a/components/transfer/index.tsx b/components/transfer/index.tsx index 9019b45ce4..b52662666c 100644 --- a/components/transfer/index.tsx +++ b/components/transfer/index.tsx @@ -14,6 +14,7 @@ import warning from '../_util/warning'; import { FormItemInputContext } from '../form/context'; import type { InputStatus } from '../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; +import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; export { TransferListProps } from './list'; export { TransferOperationProps } from './operation'; @@ -375,7 +376,7 @@ class Transfer extends React.Com status: customStatus, } = this.props; const prefixCls = getPrefixCls('transfer', customizePrefixCls); - const locale = this.getLocale(transferLocale, renderEmpty); + const locale = this.getLocale(transferLocale, renderEmpty || defaultRenderEmpty); const { sourceSelectedKeys, targetSelectedKeys } = this.state; const mergedStatus = getMergedStatus(contextStatus, customStatus); diff --git a/components/tree-select/index.tsx b/components/tree-select/index.tsx index 3b1176b693..dec102a5fa 100644 --- a/components/tree-select/index.tsx +++ b/components/tree-select/index.tsx @@ -20,6 +20,7 @@ import { getTransitionName, getTransitionDirection } from '../_util/motion'; import { FormItemInputContext } from '../form/context'; import type { InputStatus } from '../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; +import defaultRenderEmpty from '../config-provider/defaultRenderEmpty'; type RawValue = string | number; @@ -131,7 +132,7 @@ const InternalTreeSelect =