From 288b10bd103e0a388c407bd5eec5b061ab4844c1 Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Wed, 22 Feb 2023 18:18:26 +0800 Subject: [PATCH] refactoring: use hook replace LocaleReceiver (#40870) * chore: rename useLocaleReceiver => useLocale * refactoring: use hook replace LocaleReceiver * fix * update snap * fix * update snap * fix * rename --- components/calendar/generateCalendar.tsx | 103 ++++++------- components/config-provider/index.tsx | 21 +-- .../generatePicker/generateRangePicker.tsx | 100 ++++++------ .../generatePicker/generateSinglePicker.tsx | 100 ++++++------ components/empty/index.tsx | 70 ++++----- components/form/FormItemLabel.tsx | 4 +- components/locale-provider/LocaleReceiver.ts | 6 +- components/locale/LocaleReceiver.ts | 64 -------- components/locale/useLocale.ts | 24 +++ components/modal/ConfirmDialog.tsx | 82 +++++----- components/modal/Modal.tsx | 14 +- components/modal/PurePanel.tsx | 88 +++++------ components/modal/useModal/HookModal.tsx | 34 ++--- components/pagination/Pagination.tsx | 66 ++++---- components/popconfirm/PurePanel.tsx | 76 +++++----- components/qrcode/index.tsx | 54 ++++--- components/tour/panelRender.tsx | 86 ++++++----- components/transfer/ListItem.tsx | 75 +++++---- components/transfer/index.tsx | 142 +++++++++--------- components/typography/Base/index.tsx | 20 +-- components/upload/Upload.tsx | 82 +++++----- 21 files changed, 615 insertions(+), 696 deletions(-) delete mode 100644 components/locale/LocaleReceiver.ts create mode 100644 components/locale/useLocale.ts diff --git a/components/calendar/generateCalendar.tsx b/components/calendar/generateCalendar.tsx index e9884cbe8c..c2bba1abaa 100644 --- a/components/calendar/generateCalendar.tsx +++ b/components/calendar/generateCalendar.tsx @@ -10,7 +10,7 @@ import type { import useMergedState from 'rc-util/lib/hooks/useMergedState'; import * as React from 'react'; import { ConfigContext } from '../config-provider'; -import LocaleReceiver from '../locale/LocaleReceiver'; +import useLocale from '../locale/useLocale'; import CalendarHeader from './Header'; import enUS from './locale/en_US'; @@ -236,60 +236,57 @@ function generateCalendar(generateConfig: GenerateConfig) { [monthFullCellRender, monthCellRender], ); - return wrapSSR( - - {(contextLocale) => ( -
- {headerRender ? ( - headerRender({ - value: mergedValue, - type: mergedMode, - onChange: onInternalSelect, - onTypeChange: triggerModeChange, - }) - ) : ( - - )} + const contextLocale = useLocale('Calendar', getDefaultLocale); - monthRender(date, contextLocale.lang)} - onSelect={onInternalSelect} - mode={panelMode} - picker={panelMode} - disabledDate={mergedDisabledDate} - hideHeader - /> -
+ return wrapSSR( +
, + style={style} + > + {headerRender ? ( + headerRender({ + value: mergedValue, + type: mergedMode, + onChange: onInternalSelect, + onTypeChange: triggerModeChange, + }) + ) : ( + + )} + monthRender(date, contextLocale?.lang)} + onSelect={onInternalSelect} + mode={panelMode} + picker={panelMode} + disabledDate={mergedDisabledDate} + hideHeader + /> +
, ); }; diff --git a/components/config-provider/index.tsx b/components/config-provider/index.tsx index 671652c501..a9ac4ebad4 100644 --- a/components/config-provider/index.tsx +++ b/components/config-provider/index.tsx @@ -3,13 +3,14 @@ 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 * as React from 'react'; import type { ReactElement } from 'react'; +import * as React from 'react'; import type { Options } from 'scroll-into-view-if-needed'; import type { RequiredMark } from '../form/Form'; import type { Locale } from '../locale'; import LocaleProvider, { ANT_MARK } from '../locale'; -import LocaleReceiver from '../locale/LocaleReceiver'; +import type { LocaleContextProps } from '../locale/context'; +import LocaleContext from '../locale/context'; import defaultLocale from '../locale/en_US'; import { DesignTokenContext } from '../theme/internal'; import defaultSeedToken from '../theme/themes/seed'; @@ -313,17 +314,11 @@ const ConfigProvider: React.FC & { ConfigContext: typeof ConfigContext; SizeContext: typeof SizeContext; config: typeof setGlobalConfig; -} = (props) => ( - - {(_, __, legacyLocale) => ( - - {(context) => ( - - )} - - )} - -); +} = (props) => { + const context = React.useContext(ConfigContext); + const antLocale = React.useContext(LocaleContext); + return ; +}; ConfigProvider.ConfigContext = ConfigContext; ConfigProvider.SizeContext = SizeContext; diff --git a/components/date-picker/generatePicker/generateRangePicker.tsx b/components/date-picker/generatePicker/generateRangePicker.tsx index aff3e16c89..8974388b0b 100644 --- a/components/date-picker/generatePicker/generateRangePicker.tsx +++ b/components/date-picker/generatePicker/generateRangePicker.tsx @@ -13,13 +13,13 @@ import { ConfigContext } from '../../config-provider'; import DisabledContext from '../../config-provider/DisabledContext'; import SizeContext from '../../config-provider/SizeContext'; import { FormItemInputContext } from '../../form/context'; +import useLocale from '../../locale/useLocale'; import { useCompactItemContext } from '../../space/Compact'; -import LocaleReceiver from '../../locale/LocaleReceiver'; import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; +import warning from '../../_util/warning'; import enUS from '../locale/en_US'; import { getRangePlaceholder, transPlacement2DropdownAlign } from '../util'; import type { CommonPickerMethods, PickerComponentClass } from './interface'; -import warning from '../../_util/warning'; import useStyle from '../style'; @@ -102,57 +102,53 @@ export default function generateRangePicker(generateConfig: GenerateCo blur: () => innerRef.current?.blur(), })); - return wrapSSR( - - {(contextLocale) => { - const locale = { ...contextLocale, ...props.locale }; + const contextLocale = useLocale('Calendar', enUS); - return ( - - separator={ - - - - } - disabled={mergedDisabled} - ref={innerRef} - dropdownAlign={transPlacement2DropdownAlign(direction, placement)} - placeholder={getRangePlaceholder(locale, picker, 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, - ), - hashId, - compactItemClassnames, - className, - )} - locale={locale.lang} - prefixCls={prefixCls} - getPopupContainer={customGetPopupContainer || getPopupContainer} - generateConfig={generateConfig} - components={Components} - direction={direction} - dropdownClassName={classNames(hashId, popupClassName || dropdownClassName)} - /> - ); - }} - , + const locale = { ...contextLocale, ...props.locale! }; + + return wrapSSR( + + separator={ + + + + } + disabled={mergedDisabled} + ref={innerRef} + dropdownAlign={transPlacement2DropdownAlign(direction, placement)} + placeholder={getRangePlaceholder(locale, picker, 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, + ), + hashId, + compactItemClassnames, + className, + )} + locale={locale.lang} + prefixCls={prefixCls} + getPopupContainer={customGetPopupContainer || getPopupContainer} + generateConfig={generateConfig} + components={Components} + direction={direction} + dropdownClassName={classNames(hashId, popupClassName || dropdownClassName)} + />, ); }); diff --git a/components/date-picker/generatePicker/generateSinglePicker.tsx b/components/date-picker/generatePicker/generateSinglePicker.tsx index 1a500353a1..68b5bff9e9 100644 --- a/components/date-picker/generatePicker/generateSinglePicker.tsx +++ b/components/date-picker/generatePicker/generateSinglePicker.tsx @@ -13,7 +13,7 @@ import { ConfigContext } from '../../config-provider'; import DisabledContext from '../../config-provider/DisabledContext'; import SizeContext from '../../config-provider/SizeContext'; import { FormItemInputContext } from '../../form/context'; -import LocaleReceiver from '../../locale/LocaleReceiver'; +import useLocale from '../../locale/useLocale'; import { useCompactItemContext } from '../../space/Compact'; import type { InputStatus } from '../../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; @@ -122,58 +122,54 @@ export default function generatePicker(generateConfig: GenerateConfig< ); - return wrapSSR( - - {(contextLocale) => { - const locale = { ...contextLocale, ...props.locale }; + const contextLocale = useLocale('DatePicker', enUS); - return ( - - ref={innerRef} - placeholder={getPlaceholder(locale, mergedPicker, 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, - ), - hashId, - compactItemClassnames, - className, - rootClassName, - )} - prefixCls={prefixCls} - getPopupContainer={customizeGetPopupContainer || getPopupContainer} - generateConfig={generateConfig} - components={Components} - direction={direction} - disabled={mergedDisabled} - dropdownClassName={classNames( - hashId, - rootClassName, - popupClassName || dropdownClassName, - )} - /> - ); - }} - , + const locale = { ...contextLocale, ...props.locale! }; + + return wrapSSR( + + ref={innerRef} + placeholder={getPlaceholder(locale, mergedPicker, 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, + ), + hashId, + compactItemClassnames, + className, + rootClassName, + )} + prefixCls={prefixCls} + getPopupContainer={customizeGetPopupContainer || getPopupContainer} + generateConfig={generateConfig} + components={Components} + direction={direction} + disabled={mergedDisabled} + dropdownClassName={classNames( + hashId, + rootClassName, + popupClassName || dropdownClassName, + )} + />, ); }, ); diff --git a/components/empty/index.tsx b/components/empty/index.tsx index 01031a9802..41d3a376d6 100644 --- a/components/empty/index.tsx +++ b/components/empty/index.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; import * as React from 'react'; import { ConfigContext } from '../config-provider'; -import LocaleReceiver from '../locale/LocaleReceiver'; +import useLocale from '../locale/useLocale'; import DefaultEmptyImg from './empty'; import SimpleEmptyImg from './simple'; @@ -46,43 +46,39 @@ const Empty: CompoundedComponent = ({ const prefixCls = getPrefixCls('empty', customizePrefixCls); const [wrapSSR, hashId] = useStyle(prefixCls); + const locale = useLocale('Empty'); + + const des = typeof description !== 'undefined' ? description : locale?.description; + const alt = typeof des === 'string' ? des : 'empty'; + + let imageNode: React.ReactNode = null; + + if (typeof image === 'string') { + imageNode = {alt}; + } else { + imageNode = image; + } + return wrapSSR( - - {(locale: TransferLocale) => { - const des = typeof description !== 'undefined' ? description : locale.description; - const alt = typeof des === 'string' ? des : 'empty'; - - let imageNode: React.ReactNode = null; - - if (typeof image === 'string') { - imageNode = {alt}; - } else { - imageNode = image; - } - - return ( -
-
- {imageNode} -
- {des &&
{des}
} - {children &&
{children}
} -
- ); - }} -
, +
+
+ {imageNode} +
+ {des &&
{des}
} + {children &&
{children}
} +
, ); }; diff --git a/components/form/FormItemLabel.tsx b/components/form/FormItemLabel.tsx index 3a32982428..c0d696298d 100644 --- a/components/form/FormItemLabel.tsx +++ b/components/form/FormItemLabel.tsx @@ -3,8 +3,8 @@ import classNames from 'classnames'; import * as React from 'react'; import type { ColProps } from '../grid/col'; import Col from '../grid/col'; -import { useLocaleReceiver } from '../locale/LocaleReceiver'; import defaultLocale from '../locale/en_US'; +import useLocale from '../locale/useLocale'; import type { TooltipProps } from '../tooltip'; import Tooltip from '../tooltip'; import type { FormContextProps } from './context'; @@ -53,7 +53,7 @@ const FormItemLabel: React.FC { - const [formLocale] = useLocaleReceiver('Form'); + const formLocale = useLocale('Form'); const { vertical, diff --git a/components/locale-provider/LocaleReceiver.ts b/components/locale-provider/LocaleReceiver.ts index 50d1d6201e..fd15dc9552 100644 --- a/components/locale-provider/LocaleReceiver.ts +++ b/components/locale-provider/LocaleReceiver.ts @@ -1,6 +1,6 @@ // locale-provider 文件夹的移除需要修改 @ant-design/tools 和 antd-img-crop -import LocaleReceiver from '../locale/LocaleReceiver'; +import useLocale from '../locale/useLocale'; -export * from '../locale/LocaleReceiver'; +export * from '../locale/useLocale'; -export default LocaleReceiver; +export default useLocale; diff --git a/components/locale/LocaleReceiver.ts b/components/locale/LocaleReceiver.ts deleted file mode 100644 index 1d59fb6350..0000000000 --- a/components/locale/LocaleReceiver.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as React from 'react'; -import type { Locale } from '.'; -import type { LocaleContextProps } from './context'; -import LocaleContext from './context'; -import defaultLocaleData from './en_US'; - -export type LocaleComponentName = Exclude; - -export interface LocaleReceiverProps { - componentName?: C; - defaultLocale?: Locale[C] | (() => Locale[C]); - children: ( - locale: NonNullable, - localeCode: string, - fullLocale: Locale, - ) => React.ReactElement; -} - -const LocaleReceiver = ( - props: LocaleReceiverProps, -) => { - const { componentName = 'global' as C, defaultLocale, children } = props; - const antLocale = React.useContext(LocaleContext); - - const getLocale = React.useMemo>(() => { - const locale = defaultLocale || defaultLocaleData[componentName]; - const localeFromContext = antLocale?.[componentName] ?? {}; - return { - ...(locale instanceof Function ? locale() : locale), - ...(localeFromContext || {}), - }; - }, [componentName, defaultLocale, antLocale]); - - const getLocaleCode = React.useMemo(() => { - const localeCode = antLocale && antLocale.locale; - // Had use LocaleProvide but didn't set locale - if (antLocale && antLocale.exist && !localeCode) { - return defaultLocaleData.locale; - } - return localeCode!; - }, [antLocale]); - - return children(getLocale, getLocaleCode, antLocale!); -}; - -export default LocaleReceiver; - -export const useLocaleReceiver = ( - componentName: C, - defaultLocale?: Locale[C] | (() => Locale[C]), -): [Locale[C]] => { - const antLocale = React.useContext(LocaleContext); - - const getLocale = React.useMemo>(() => { - const locale = defaultLocale || defaultLocaleData[componentName]; - const localeFromContext = antLocale?.[componentName] ?? {}; - return { - ...(typeof locale === 'function' ? locale() : locale), - ...(localeFromContext || {}), - }; - }, [componentName, defaultLocale, antLocale]); - - return [getLocale]; -}; diff --git a/components/locale/useLocale.ts b/components/locale/useLocale.ts new file mode 100644 index 0000000000..c3b5b01ddd --- /dev/null +++ b/components/locale/useLocale.ts @@ -0,0 +1,24 @@ +import * as React from 'react'; +import type { Locale } from '.'; +import type { LocaleContextProps } from './context'; +import LocaleContext from './context'; +import defaultLocaleData from './en_US'; + +export type LocaleComponentName = Exclude; + +const useLocale = ( + componentName: C, + defaultLocale?: Locale[C] | (() => Locale[C]), +): Locale[C] => { + const antLocale = React.useContext(LocaleContext); + return React.useMemo>(() => { + const locale = defaultLocale || defaultLocaleData[componentName]; + const localeFromContext = antLocale?.[componentName] ?? {}; + return { + ...(typeof locale === 'function' ? locale() : locale), + ...(localeFromContext || {}), + }; + }, [componentName, defaultLocale, antLocale]); +}; + +export default useLocale; diff --git a/components/modal/ConfirmDialog.tsx b/components/modal/ConfirmDialog.tsx index 6e5a8b47ca..b5580743e4 100644 --- a/components/modal/ConfirmDialog.tsx +++ b/components/modal/ConfirmDialog.tsx @@ -5,7 +5,7 @@ import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled'; import classNames from 'classnames'; import * as React from 'react'; import ConfigProvider from '../config-provider'; -import LocaleReceiver from '../locale/LocaleReceiver'; +import useLocale from '../locale/useLocale'; import ActionButton from '../_util/ActionButton'; import { getTransitionName } from '../_util/motion'; import warning from '../_util/warning'; @@ -81,57 +81,53 @@ export function ConfirmContent( const autoFocusButton = props.autoFocusButton === null ? false : props.autoFocusButton || 'ok'; - return ( - - {(locale) => { - const mergedLocale = staticLocale || locale; + const locale = useLocale('Modal'); - const cancelButton = mergedOkCancel && ( + const mergedLocale = staticLocale || locale; + + const cancelButton = mergedOkCancel && ( + + {cancelText || mergedLocale?.cancelText} + + ); + + return ( +
+
+ {mergedIcon} + {props.title === undefined ? null : ( + {props.title} + )} +
{props.content}
+
+ {footer !== undefined ? ( + footer + ) : ( +
+ {cancelButton} - {cancelText || mergedLocale?.cancelText} + {okText || (mergedOkCancel ? mergedLocale?.okText : mergedLocale?.justOkText)} - ); - - return ( -
-
- {mergedIcon} - {props.title === undefined ? null : ( - {props.title} - )} -
{props.content}
-
- {footer !== undefined ? ( - footer - ) : ( -
- {cancelButton} - - {okText || (mergedOkCancel ? mergedLocale?.okText : mergedLocale?.justOkText)} - -
- )} -
- ); - }} - +
+ )} +
); } -const ConfirmDialog = (props: ConfirmDialogProps) => { +const ConfirmDialog: React.FC = (props) => { const { close, zIndex, diff --git a/components/modal/Modal.tsx b/components/modal/Modal.tsx index a47f279c4f..20f5864704 100644 --- a/components/modal/Modal.tsx +++ b/components/modal/Modal.tsx @@ -9,7 +9,7 @@ import { NoCompactStyle } from '../space/Compact'; import { getTransitionName } from '../_util/motion'; import { canUseDocElement } from '../_util/styleChecker'; import warning from '../_util/warning'; -import { renderCloseIcon, renderFooter } from './PurePanel'; +import { Footer, renderCloseIcon } from './PurePanel'; import useStyle from './style'; type MousePosition = { x: number; y: number } | null; @@ -209,11 +209,13 @@ const Modal: React.FC = (props) => { prefixCls={prefixCls} rootClassName={classNames(hashId, rootClassName)} wrapClassName={wrapClassNameExtended} - footer={renderFooter({ - ...props, - onOk: handleOk, - onCancel: handleCancel, - })} + footer={ + props.footer === null ? ( + props.footer + ) : ( +