From 9d1854763d2e46fddd6c95e2cd893cc71e33387c Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Fri, 12 May 2023 14:53:47 +0800 Subject: [PATCH] refactor: add useSize replace React.useContext (#42282) * refactor: add useSize * fix * fix * fix * fix * fix --- components/_util/hooks/useSize.ts | 16 ------- components/avatar/avatar.tsx | 4 +- components/button/button.tsx | 7 ++-- components/card/Card.tsx | 42 +++++++++---------- components/cascader/index.tsx | 21 ++++------ components/collapse/Collapse.tsx | 9 ++-- components/config-provider/SizeContext.tsx | 5 ++- .../__tests__/useSize.test.tsx | 17 ++++++++ components/config-provider/hooks/useSize.ts | 22 ++++++++++ .../generatePicker/generateRangePicker.tsx | 18 +++----- .../generatePicker/generateSinglePicker.tsx | 14 +++---- components/descriptions/index.tsx | 2 +- components/form/Form.tsx | 15 +++---- components/input-number/index.tsx | 24 +++++------ components/input/Input.tsx | 17 ++++---- components/input/Search.tsx | 8 ++-- components/input/TextArea.tsx | 27 ++++++------ components/pagination/Pagination.tsx | 6 +-- components/radio/group.tsx | 9 ++-- components/segmented/index.tsx | 7 +--- components/select/index.tsx | 5 +-- components/space/Compact.tsx | 17 ++++---- components/steps/index.tsx | 8 ++-- components/switch/index.tsx | 13 +++--- components/table/InternalTable.tsx | 6 +-- components/tabs/index.tsx | 13 +++--- components/tree-select/index.tsx | 6 +-- scripts/check-commit.ts | 2 +- 28 files changed, 178 insertions(+), 182 deletions(-) delete mode 100644 components/_util/hooks/useSize.ts create mode 100644 components/config-provider/__tests__/useSize.test.tsx create mode 100644 components/config-provider/hooks/useSize.ts diff --git a/components/_util/hooks/useSize.ts b/components/_util/hooks/useSize.ts deleted file mode 100644 index d21b02fea2..0000000000 --- a/components/_util/hooks/useSize.ts +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import type { SizeType } from '../../config-provider/SizeContext'; -import SizeContext from '../../config-provider/SizeContext'; - -const useSize = (customizeSize?: T) => { - const size = React.useContext(SizeContext); - const mergeSize = React.useMemo(() => { - if (!customizeSize) { - return size as T; - } - return customizeSize ?? size; - }, [customizeSize, size]); - return mergeSize; -}; - -export default useSize; diff --git a/components/avatar/avatar.tsx b/components/avatar/avatar.tsx index bcecaf9acb..69867d50b4 100644 --- a/components/avatar/avatar.tsx +++ b/components/avatar/avatar.tsx @@ -2,11 +2,11 @@ import classNames from 'classnames'; import ResizeObserver from 'rc-resize-observer'; import { composeRef } from 'rc-util/lib/ref'; import * as React from 'react'; -import { ConfigContext } from '../config-provider'; -import useBreakpoint from '../grid/hooks/useBreakpoint'; import type { Breakpoint } from '../_util/responsiveObserver'; import { responsiveArray } from '../_util/responsiveObserver'; import warning from '../_util/warning'; +import { ConfigContext } from '../config-provider'; +import useBreakpoint from '../grid/hooks/useBreakpoint'; import type { AvatarSize } from './SizeContext'; import SizeContext from './SizeContext'; import useStyle from './style'; diff --git a/components/button/button.tsx b/components/button/button.tsx index b3567d261b..ed544aca7b 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -16,7 +16,7 @@ import Wave from '../_util/wave'; import { ConfigContext } from '../config-provider'; import DisabledContext from '../config-provider/DisabledContext'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; import { useCompactItemContext } from '../space/Compact'; import LoadingIcon from './LoadingIcon'; import Group, { GroupSizeContext } from './button-group'; @@ -124,7 +124,6 @@ const InternalButton: React.ForwardRefRenderFunction< const [wrapSSR, hashId] = useStyle(prefixCls); - const size = useContext(SizeContext); const disabled = useContext(DisabledContext); const mergedDisabled = customDisabled ?? disabled; @@ -204,7 +203,9 @@ const InternalButton: React.ForwardRefRenderFunction< const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction); const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined }; - const sizeFullname = compactSize || groupSize || customizeSize || size; + + const sizeFullname = useSize((ctxSize) => compactSize ?? groupSize ?? customizeSize ?? ctxSize); + const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : ''; const iconType = innerLoading ? 'loading' : icon; diff --git a/components/card/Card.tsx b/components/card/Card.tsx index 4bf8199be6..fe416d5167 100644 --- a/components/card/Card.tsx +++ b/components/card/Card.tsx @@ -2,12 +2,11 @@ import classNames from 'classnames'; import omit from 'rc-util/lib/omit'; import * as React from 'react'; import { ConfigContext } from '../config-provider'; -import SizeContext from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; import Skeleton from '../skeleton'; import type { TabsProps } from '../tabs'; import Tabs from '../tabs'; import Grid from './Grid'; - import useStyle from './style'; export type CardType = 'inner'; @@ -55,24 +54,7 @@ function getAction(actions: React.ReactNode[]) { return actionList; } -const Card = React.forwardRef((props: CardProps, ref: React.Ref) => { - const { getPrefixCls, direction } = React.useContext(ConfigContext); - const size = React.useContext(SizeContext); - - const onTabChange = (key: string) => { - props.onTabChange?.(key); - }; - - const isContainGrid = () => { - let containGrid; - React.Children.forEach(props.children, (element: JSX.Element) => { - if (element && element.type && element.type === Grid) { - containGrid = true; - } - }); - return containGrid; - }; - +const Card = React.forwardRef((props, ref) => { const { prefixCls: customizePrefixCls, className, @@ -97,6 +79,22 @@ const Card = React.forwardRef((props: CardProps, ref: React.Ref) ...others } = props; + const { getPrefixCls, direction } = React.useContext(ConfigContext); + + const onTabChange = (key: string) => { + props.onTabChange?.(key); + }; + + const isContainGrid = React.useMemo(() => { + let containGrid = false; + React.Children.forEach(children, (element: JSX.Element) => { + if (element && element.type && element.type === Grid) { + containGrid = true; + } + }); + return containGrid; + }, [children]); + const prefixCls = getPrefixCls('card', customizePrefixCls); const [wrapSSR, hashId] = useStyle(prefixCls); @@ -116,7 +114,7 @@ const Card = React.forwardRef((props: CardProps, ref: React.Ref) }; let head: React.ReactNode; - const mergedSize = customizeSize || size; + const mergedSize = useSize(customizeSize); const tabSize = !mergedSize || mergedSize === 'default' ? 'large' : mergedSize; const tabs = tabList && tabList.length ? ( @@ -160,7 +158,7 @@ const Card = React.forwardRef((props: CardProps, ref: React.Ref) [`${prefixCls}-loading`]: loading, [`${prefixCls}-bordered`]: bordered, [`${prefixCls}-hoverable`]: hoverable, - [`${prefixCls}-contain-grid`]: isContainGrid(), + [`${prefixCls}-contain-grid`]: isContainGrid, [`${prefixCls}-contain-tabs`]: tabList && tabList.length, [`${prefixCls}-${mergedSize}`]: mergedSize, [`${prefixCls}-type-${type}`]: !!type, diff --git a/components/cascader/index.tsx b/components/cascader/index.tsx index ef61f2306d..8e53445404 100644 --- a/components/cascader/index.tsx +++ b/components/cascader/index.tsx @@ -14,25 +14,23 @@ import RcCascader from 'rc-cascader'; import type { Placement } from 'rc-select/lib/BaseSelect'; import omit from 'rc-util/lib/omit'; import * as React from 'react'; -import { ConfigContext } from '../config-provider'; -import DisabledContext from '../config-provider/DisabledContext'; -import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; -import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty'; -import { useCompactItemContext } from '../space/Compact'; - +import genPurePanel from '../_util/PurePanel'; import type { SelectCommonPlacement } from '../_util/motion'; import { getTransitionDirection, getTransitionName } from '../_util/motion'; import type { InputStatus } from '../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; import warning from '../_util/warning'; +import { ConfigContext } from '../config-provider'; +import DisabledContext from '../config-provider/DisabledContext'; +import type { SizeType } from '../config-provider/SizeContext'; +import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty'; +import useSize from '../config-provider/hooks/useSize'; import { FormItemInputContext } from '../form/context'; -import getIcons from '../select/utils/iconUtil'; - -import genPurePanel from '../_util/PurePanel'; import useSelectStyle from '../select/style'; import useBuiltinPlacements from '../select/useBuiltinPlacements'; import useShowArrow from '../select/useShowArrow'; +import getIcons from '../select/utils/iconUtil'; +import { useCompactItemContext } from '../space/Compact'; import useStyle from './style'; // Align the design since we use `rc-select` in root. This help: @@ -232,8 +230,7 @@ const Cascader = React.forwardRef((props: CascaderProps, ref: React.Ref compactSize ?? customizeSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/collapse/Collapse.tsx b/components/collapse/Collapse.tsx index 0742b2908f..565d240167 100644 --- a/components/collapse/Collapse.tsx +++ b/components/collapse/Collapse.tsx @@ -2,19 +2,17 @@ import RightOutlined from '@ant-design/icons/RightOutlined'; import classNames from 'classnames'; import RcCollapse from 'rc-collapse'; import type { CSSMotionProps } from 'rc-motion'; -import * as React from 'react'; - import toArray from 'rc-util/lib/Children/toArray'; import omit from 'rc-util/lib/omit'; +import * as React from 'react'; import initCollapseMotion from '../_util/motion'; import { cloneElement } from '../_util/reactNode'; import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; import type { CollapsibleType } from './CollapsePanel'; import CollapsePanel from './CollapsePanel'; - import useStyle from './style'; /** @deprecated Please use `start` | `end` instead */ @@ -56,7 +54,6 @@ interface PanelProps { const Collapse = React.forwardRef((props, ref) => { const { getPrefixCls, direction } = React.useContext(ConfigContext); - const size = React.useContext(SizeContext); const { prefixCls: customizePrefixCls, @@ -70,7 +67,7 @@ const Collapse = React.forwardRef((props, ref) => expandIcon, } = props; - const mergedSize = customizeSize || size || 'middle'; + const mergedSize = useSize((ctx) => customizeSize ?? ctx ?? 'middle'); const prefixCls = getPrefixCls('collapse', customizePrefixCls); const rootPrefixCls = getPrefixCls(); const [wrapSSR, hashId] = useStyle(prefixCls); diff --git a/components/config-provider/SizeContext.tsx b/components/config-provider/SizeContext.tsx index 5bc5924017..b4b8b0049a 100644 --- a/components/config-provider/SizeContext.tsx +++ b/components/config-provider/SizeContext.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import useSize from './hooks/useSize'; export type SizeType = 'small' | 'middle' | 'large' | undefined; @@ -10,8 +11,8 @@ export interface SizeContextProps { } export const SizeContextProvider: React.FC = ({ children, size }) => { - const originSize = React.useContext(SizeContext); - return {children}; + const mergedSize = useSize(size); + return {children}; }; export default SizeContext; diff --git a/components/config-provider/__tests__/useSize.test.tsx b/components/config-provider/__tests__/useSize.test.tsx new file mode 100644 index 0000000000..2e0c2b20b1 --- /dev/null +++ b/components/config-provider/__tests__/useSize.test.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { render } from '../../../tests/utils'; +import useSize from '../hooks/useSize'; + +describe('useSize', () => { + it('useSize', () => { + const Demo: React.FC<{ size?: any }> = ({ size }) =>
{useSize(size)}
; + const { container, rerender } = render(); + expect(container.querySelector('div')?.textContent).toBe(''); + rerender(); + expect(container.querySelector('div')?.textContent).toBe('test-size1'); + rerender( 'test-size2'} />); + expect(container.querySelector('div')?.textContent).toBe('test-size2'); + rerender(); + expect(container.querySelector('div')?.textContent).toBe(''); + }); +}); diff --git a/components/config-provider/hooks/useSize.ts b/components/config-provider/hooks/useSize.ts new file mode 100644 index 0000000000..e71ba78a6b --- /dev/null +++ b/components/config-provider/hooks/useSize.ts @@ -0,0 +1,22 @@ +import React from 'react'; +import type { SizeType } from '../SizeContext'; +import SizeContext from '../SizeContext'; + +const useSize = (customSize?: T | ((ctxSize: SizeType) => T)): T => { + const size = React.useContext(SizeContext); + const mergedSize = React.useMemo(() => { + if (!customSize) { + return size as T; + } + if (typeof customSize === 'string') { + return customSize ?? size; + } + if (customSize instanceof Function) { + return customSize(size); + } + return size as T; + }, [customSize, size]); + return mergedSize; +}; + +export default useSize; diff --git a/components/date-picker/generatePicker/generateRangePicker.tsx b/components/date-picker/generatePicker/generateRangePicker.tsx index a6bd7e6fc5..7159b8adfd 100644 --- a/components/date-picker/generatePicker/generateRangePicker.tsx +++ b/components/date-picker/generatePicker/generateRangePicker.tsx @@ -9,20 +9,19 @@ import * as React from 'react'; import { forwardRef, useContext, useImperativeHandle } from 'react'; import type { RangePickerProps } from '.'; import { Components, getTimeProps } from '.'; +import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; +import warning from '../../_util/warning'; import { ConfigContext } from '../../config-provider'; import DisabledContext from '../../config-provider/DisabledContext'; -import SizeContext from '../../config-provider/SizeContext'; +import useSize from '../../config-provider/hooks/useSize'; import { FormItemInputContext } from '../../form/context'; import { useLocale } from '../../locale'; import { useCompactItemContext } from '../../space/Compact'; -import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; -import warning from '../../_util/warning'; import enUS from '../locale/en_US'; +import useStyle from '../style'; import { getRangePlaceholder, transPlacement2DropdownAlign } from '../util'; import type { CommonPickerMethods, PickerComponentClass } from './interface'; -import useStyle from '../style'; - export default function generateRangePicker(generateConfig: GenerateConfig) { type InternalRangePickerProps = RangePickerProps & {}; type DateRangePickerProps = RangePickerProps & { @@ -79,8 +78,7 @@ export default function generateRangePicker(generateConfig: GenerateCo } // ===================== Size ===================== - const size = React.useContext(SizeContext); - const mergedSize = compactSize || customizeSize || size; + const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); @@ -132,11 +130,7 @@ export default function generateRangePicker(generateConfig: GenerateCo [`${prefixCls}-${mergedSize}`]: mergedSize, [`${prefixCls}-borderless`]: !bordered, }, - getStatusClassNames( - prefixCls as string, - getMergedStatus(contextStatus, customStatus), - hasFeedback, - ), + getStatusClassNames(prefixCls, getMergedStatus(contextStatus, customStatus), hasFeedback), hashId, compactItemClassnames, className, diff --git a/components/date-picker/generatePicker/generateSinglePicker.tsx b/components/date-picker/generatePicker/generateSinglePicker.tsx index ae755cfa3c..c6c085394c 100644 --- a/components/date-picker/generatePicker/generateSinglePicker.tsx +++ b/components/date-picker/generatePicker/generateSinglePicker.tsx @@ -9,21 +9,20 @@ import * as React from 'react'; import { forwardRef, useContext, useImperativeHandle } from 'react'; import type { PickerProps, PickerTimeProps } from '.'; import { Components, getTimeProps } from '.'; +import type { InputStatus } from '../../_util/statusUtils'; +import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; +import warning from '../../_util/warning'; import { ConfigContext } from '../../config-provider'; import DisabledContext from '../../config-provider/DisabledContext'; -import SizeContext from '../../config-provider/SizeContext'; +import useSize from '../../config-provider/hooks/useSize'; import { FormItemInputContext } from '../../form/context'; import { useLocale } from '../../locale'; import { useCompactItemContext } from '../../space/Compact'; -import type { InputStatus } from '../../_util/statusUtils'; -import { getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; -import warning from '../../_util/warning'; import enUS from '../locale/en_US'; +import useStyle from '../style'; import { getPlaceholder, transPlacement2DropdownAlign } from '../util'; import type { CommonPickerMethods, DatePickRef, PickerComponentClass } from './interface'; -import useStyle from '../style'; - export default function generatePicker(generateConfig: GenerateConfig) { type CustomPickerProps = { status?: InputStatus; @@ -104,8 +103,7 @@ export default function generatePicker(generateConfig: GenerateConfig< } // ===================== Size ===================== - const size = React.useContext(SizeContext); - const mergedSize = compactSize || customizeSize || size; + const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/descriptions/index.tsx b/components/descriptions/index.tsx index 4a1f2d7def..2b5445e8db 100644 --- a/components/descriptions/index.tsx +++ b/components/descriptions/index.tsx @@ -2,12 +2,12 @@ import classNames from 'classnames'; import toArray from 'rc-util/lib/Children/toArray'; import * as React from 'react'; -import useSize from '../_util/hooks/useSize'; import { cloneElement } from '../_util/reactNode'; import type { Breakpoint, ScreenMap } from '../_util/responsiveObserver'; import useResponsiveObserver, { responsiveArray } from '../_util/responsiveObserver'; import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; +import useSize from '../config-provider/hooks/useSize'; import DescriptionsItem from './Item'; import Row from './Row'; import useStyle from './style'; diff --git a/components/form/Form.tsx b/components/form/Form.tsx index d4c6e99ad9..b37e5a781b 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -8,14 +8,14 @@ import type { Options } from 'scroll-into-view-if-needed'; import { ConfigContext } from '../config-provider'; import DisabledContext, { DisabledContextProvider } from '../config-provider/DisabledContext'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext, { SizeContextProvider } from '../config-provider/SizeContext'; +import { SizeContextProvider } from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; import type { ColProps } from '../grid/col'; import type { FormContextProps } from './context'; import { FormContext } from './context'; import useForm, { type FormInstance } from './hooks/useForm'; -import type { FormLabelAlign } from './interface'; - import useFormWarning from './hooks/useFormWarning'; +import type { FormLabelAlign } from './interface'; import useStyle from './style'; export type RequiredMark = boolean | 'optional'; @@ -41,7 +41,6 @@ export interface FormProps extends Omit, 'form } const InternalForm: React.ForwardRefRenderFunction = (props, ref) => { - const contextSize = React.useContext(SizeContext); const contextDisabled = React.useContext(DisabledContext); const { getPrefixCls, direction, form: contextForm } = React.useContext(ConfigContext); @@ -49,7 +48,7 @@ const InternalForm: React.ForwardRefRenderFunction = (p prefixCls: customizePrefixCls, className, rootClassName, - size = contextSize, + size, disabled = contextDisabled, form, colon, @@ -66,6 +65,8 @@ const InternalForm: React.ForwardRefRenderFunction = (p ...restFormProps } = props; + const mergedSize = useSize(size); + if (process.env.NODE_ENV !== 'production') { // eslint-disable-next-line react-hooks/rules-of-hooks useFormWarning(props); @@ -100,7 +101,7 @@ const InternalForm: React.ForwardRefRenderFunction = (p [`${prefixCls}-${layout}`]: true, [`${prefixCls}-hide-required-mark`]: mergedRequiredMark === false, [`${prefixCls}-rtl`]: direction === 'rtl', - [`${prefixCls}-${size}`]: size, + [`${prefixCls}-${mergedSize}`]: mergedSize, }, hashId, className, @@ -156,7 +157,7 @@ const InternalForm: React.ForwardRefRenderFunction = (p return wrapSSR( - + @@ -32,7 +32,7 @@ export interface InputNumberProps const InputNumber = React.forwardRef((props, ref) => { const { getPrefixCls, direction } = React.useContext(ConfigContext); - const size = React.useContext(SizeContext); + const [focused, setFocus] = React.useState(false); const inputRef = React.useRef(null); @@ -87,7 +87,7 @@ const InputNumber = React.forwardRef((props, } = React.useContext(FormItemInputContext); const mergedStatus = getMergedStatus(contextStatus, customStatus); - const mergeSize = compactSize || customizeSize || size; + const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx); const hasPrefix = prefix != null || hasFeedback; const hasAddon = !!(addonBefore || addonAfter); @@ -98,8 +98,8 @@ const InputNumber = React.forwardRef((props, const inputNumberClass = classNames( { - [`${prefixCls}-lg`]: mergeSize === 'large', - [`${prefixCls}-sm`]: mergeSize === 'small', + [`${prefixCls}-lg`]: mergedSize === 'large', + [`${prefixCls}-sm`]: mergedSize === 'small', [`${prefixCls}-rtl`]: direction === 'rtl', [`${prefixCls}-borderless`]: !bordered, [`${prefixCls}-in-form-item`]: isFormItemInput, @@ -132,8 +132,8 @@ const InputNumber = React.forwardRef((props, { [`${prefixCls}-affix-wrapper-focused`]: focused, [`${prefixCls}-affix-wrapper-disabled`]: props.disabled, - [`${prefixCls}-affix-wrapper-sm`]: mergeSize === 'small', - [`${prefixCls}-affix-wrapper-lg`]: mergeSize === 'large', + [`${prefixCls}-affix-wrapper-sm`]: mergedSize === 'small', + [`${prefixCls}-affix-wrapper-lg`]: mergedSize === 'large', [`${prefixCls}-affix-wrapper-rtl`]: direction === 'rtl', [`${prefixCls}-affix-wrapper-readonly`]: readOnly, [`${prefixCls}-affix-wrapper-borderless`]: !bordered, @@ -184,8 +184,8 @@ const InputNumber = React.forwardRef((props, const mergedGroupClassName = classNames( `${prefixCls}-group-wrapper`, { - [`${prefixCls}-group-wrapper-sm`]: mergeSize === 'small', - [`${prefixCls}-group-wrapper-lg`]: mergeSize === 'large', + [`${prefixCls}-group-wrapper-sm`]: mergedSize === 'small', + [`${prefixCls}-group-wrapper-lg`]: mergedSize === 'large', [`${prefixCls}-group-wrapper-rtl`]: direction === 'rtl', }, getStatusClassNames(`${prefixCls}-group-wrapper`, mergedStatus, hasFeedback), diff --git a/components/input/Input.tsx b/components/input/Input.tsx index 8da1ba6826..4bbae04774 100644 --- a/components/input/Input.tsx +++ b/components/input/Input.tsx @@ -1,24 +1,22 @@ import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; import classNames from 'classnames'; -import type { InputProps as RcInputProps, InputRef } from 'rc-input'; +import type { InputRef, InputProps as RcInputProps } from 'rc-input'; import RcInput from 'rc-input'; import type { BaseInputProps } from 'rc-input/lib/interface'; import { composeRef } from 'rc-util/lib/ref'; import React, { forwardRef, useContext, useEffect, useRef } from 'react'; +import type { InputStatus } from '../_util/statusUtils'; +import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; +import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; import DisabledContext from '../config-provider/DisabledContext'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; import { FormItemInputContext, NoFormStyle } from '../form/context'; import { NoCompactStyle, useCompactItemContext } from '../space/Compact'; -import type { InputStatus } from '../_util/statusUtils'; -import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; -import warning from '../_util/warning'; import useRemovePasswordTimeout from './hooks/useRemovePasswordTimeout'; -import { hasPrefixSuffix } from './utils'; - -// CSSINJS import useStyle from './style'; +import { hasPrefixSuffix } from './utils'; export interface InputFocusOptions extends FocusOptions { cursor?: 'start' | 'end' | 'all'; @@ -99,8 +97,7 @@ const Input = forwardRef((props, ref) => { const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction); // ===================== Size ===================== - const size = React.useContext(SizeContext); - const mergedSize = compactSize || customSize || size; + const mergedSize = useSize((ctx) => compactSize ?? customSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/input/Search.tsx b/components/input/Search.tsx index 770e310bfe..61ddd99be6 100644 --- a/components/input/Search.tsx +++ b/components/input/Search.tsx @@ -2,11 +2,11 @@ import SearchOutlined from '@ant-design/icons/SearchOutlined'; import classNames from 'classnames'; import { composeRef } from 'rc-util/lib/ref'; import * as React from 'react'; +import { cloneElement } from '../_util/reactNode'; import Button from '../button'; import { ConfigContext } from '../config-provider'; -import SizeContext from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; import { useCompactItemContext } from '../space/Compact'; -import { cloneElement } from '../_util/reactNode'; import type { InputProps, InputRef } from './Input'; import Input from './Input'; @@ -42,14 +42,14 @@ const Search = React.forwardRef((props, ref) => { } = props; const { getPrefixCls, direction } = React.useContext(ConfigContext); - const contextSize = React.useContext(SizeContext); + const composedRef = React.useRef(false); const prefixCls = getPrefixCls('input-search', customizePrefixCls); const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls); const { compactSize } = useCompactItemContext(prefixCls, direction); - const size = compactSize || customizeSize || contextSize; + const size = useSize((ctx) => compactSize ?? customizeSize ?? ctx); const inputRef = React.useRef(null); diff --git a/components/input/TextArea.tsx b/components/input/TextArea.tsx index 44a2e818bc..5104fbcf76 100644 --- a/components/input/TextArea.tsx +++ b/components/input/TextArea.tsx @@ -1,21 +1,21 @@ -import type { TextAreaProps as RcTextAreaProps } from 'rc-textarea/lib/interface'; -import type { TextAreaRef as RcTextAreaRef } from 'rc-textarea'; -import { forwardRef } from 'react'; -import * as React from 'react'; -import RcTextArea from 'rc-textarea'; -import classNames from 'classnames'; import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; +import classNames from 'classnames'; import type { BaseInputProps } from 'rc-input/lib/interface'; -import { FormItemInputContext } from '../form/context'; -import useStyle from './style'; -import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; +import type { TextAreaRef as RcTextAreaRef } from 'rc-textarea'; +import RcTextArea from 'rc-textarea'; +import type { TextAreaProps as RcTextAreaProps } from 'rc-textarea/lib/interface'; +import * as React from 'react'; +import { forwardRef } from 'react'; import type { InputStatus } from '../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; +import { ConfigContext } from '../config-provider'; +import DisabledContext from '../config-provider/DisabledContext'; +import type { SizeType } from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; +import { FormItemInputContext } from '../form/context'; import type { InputFocusOptions } from './Input'; import { triggerFocus } from './Input'; -import DisabledContext from '../config-provider/DisabledContext'; -import { ConfigContext } from '../config-provider'; +import useStyle from './style'; export interface TextAreaProps extends Omit { bordered?: boolean; @@ -47,8 +47,7 @@ const TextArea = forwardRef( const { getPrefixCls, direction } = React.useContext(ConfigContext); // ===================== Size ===================== - const size = React.useContext(SizeContext); - const mergedSize = customizeSize || size; + const mergedSize = useSize(customizeSize); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/pagination/Pagination.tsx b/components/pagination/Pagination.tsx index 3d4c529c7b..d1492d3f20 100644 --- a/components/pagination/Pagination.tsx +++ b/components/pagination/Pagination.tsx @@ -8,7 +8,7 @@ import RcPagination from 'rc-pagination'; import enUS from 'rc-pagination/lib/locale/en_US'; import * as React from 'react'; import { ConfigContext } from '../config-provider'; -import SizeContext from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; import useBreakpoint from '../grid/hooks/useBreakpoint'; import { useLocale } from '../locale'; import { MiddleSelect, MiniSelect } from './Select'; @@ -99,8 +99,8 @@ const Pagination: React.FC = ({ const locale = { ...contextLocale, ...customLocale }; - const size = React.useContext(SizeContext); - const mergedSize = customizeSize ?? size; + const mergedSize = useSize(customizeSize); + const isSmall = mergedSize === 'small' || !!(xs && !mergedSize && responsive); const selectPrefixCls = getPrefixCls('select', customizeSelectPrefixCls); diff --git a/components/radio/group.tsx b/components/radio/group.tsx index 7e8433d7e1..35973b563e 100644 --- a/components/radio/group.tsx +++ b/components/radio/group.tsx @@ -1,18 +1,16 @@ import classNames from 'classnames'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; import * as React from 'react'; -import { ConfigContext } from '../config-provider'; -import SizeContext from '../config-provider/SizeContext'; import getDataOrAriaProps from '../_util/getDataOrAriaProps'; +import { ConfigContext } from '../config-provider'; +import useSize from '../config-provider/hooks/useSize'; import { RadioGroupContextProvider } from './context'; import type { RadioChangeEvent, RadioGroupButtonStyle, RadioGroupProps } from './interface'; import Radio from './radio'; - import useStyle from './style'; const RadioGroup = React.forwardRef((props, ref) => { const { getPrefixCls, direction } = React.useContext(ConfigContext); - const size = React.useContext(SizeContext); const [value, setValue] = useMergedState(props.defaultValue, { value: props.value, @@ -86,7 +84,8 @@ const RadioGroup = React.forwardRef((props, ref }); } - const mergedSize = customizeSize || size; + const mergedSize = useSize(customizeSize); + const classString = classNames( groupPrefixCls, `${groupPrefixCls}-${buttonStyle}`, diff --git a/components/segmented/index.tsx b/components/segmented/index.tsx index 49190ae081..8b1a16e6b1 100644 --- a/components/segmented/index.tsx +++ b/components/segmented/index.tsx @@ -6,11 +6,9 @@ import type { } from 'rc-segmented'; import RcSegmented from 'rc-segmented'; import * as React from 'react'; - import { ConfigContext } from '../config-provider'; +import useSize from '../config-provider/hooks/useSize'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; - import useStyle from './style'; export type { SegmentedValue } from 'rc-segmented'; @@ -61,8 +59,7 @@ const Segmented = React.forwardRef((props, ref) const [wrapSSR, hashId] = useStyle(prefixCls); // ===================== Size ===================== - const size = React.useContext(SizeContext); - const mergedSize = customSize || size; + const mergedSize = useSize(customSize); // syntactic sugar to support `icon` for Segmented Item const extendedOptions = React.useMemo( diff --git a/components/select/index.tsx b/components/select/index.tsx index 8fc38e8703..38061c9651 100755 --- a/components/select/index.tsx +++ b/components/select/index.tsx @@ -15,8 +15,8 @@ import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; import DisabledContext from '../config-provider/DisabledContext'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty'; +import useSize from '../config-provider/hooks/useSize'; import { FormItemInputContext } from '../form/context'; import { useCompactItemContext } from '../space/Compact'; import useStyle from './style'; @@ -96,7 +96,6 @@ const InternalSelect = compactSize ?? customizeSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/space/Compact.tsx b/components/space/Compact.tsx index 47c64cc538..b1046365a6 100644 --- a/components/space/Compact.tsx +++ b/components/space/Compact.tsx @@ -5,8 +5,8 @@ import * as React from 'react'; import type { DirectionType } from '../config-provider'; import { ConfigContext } from '../config-provider'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; +import useSize from '../config-provider/hooks/useSize'; import useStyle from './style'; export interface SpaceCompactItemContextType { @@ -23,9 +23,10 @@ export const SpaceCompactItemContext = React.createContext { const compactItemContext = React.useContext(SpaceCompactItemContext); - const compactItemClassnames = React.useMemo(() => { - if (!compactItemContext) return ''; - + const compactItemClassnames = React.useMemo(() => { + if (!compactItemContext) { + return ''; + } const { compactDirection, isFirstItem, isLastItem } = compactItemContext; const separator = compactDirection === 'vertical' ? '-vertical-' : '-'; @@ -65,10 +66,9 @@ const CompactItem: React.FC const Compact: React.FC = (props) => { const { getPrefixCls, direction: directionConfig } = React.useContext(ConfigContext); - const sizeInContext = React.useContext(SizeContext); const { - size = sizeInContext || 'middle', + size, direction, block, prefixCls: customizePrefixCls, @@ -78,6 +78,8 @@ const Compact: React.FC = (props) => { ...restProps } = props; + const mergedSize = useSize((ctx) => size ?? ctx ?? 'middle'); + const prefixCls = getPrefixCls('space-compact', customizePrefixCls); const [wrapSSR, hashId] = useStyle(prefixCls); const clx = classNames( @@ -99,11 +101,10 @@ const Compact: React.FC = (props) => { () => childNodes.map((child, i) => { const key = (child && child.key) || `${prefixCls}-item-${i}`; - return ( ( ); const { getPrefixCls, direction } = React.useContext(ConfigContext); - const size = React.useContext(SizeContext); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); @@ -81,9 +78,11 @@ const Switch = React.forwardRef( // Style const [wrapSSR, hashId] = useStyle(prefixCls); + const mergedSize = useSize(customizeSize); + const classes = classNames( { - [`${prefixCls}-small`]: (customizeSize || size) === 'small', + [`${prefixCls}-small`]: mergedSize === 'small', [`${prefixCls}-loading`]: loading, [`${prefixCls}-rtl`]: direction === 'rtl', }, diff --git a/components/table/InternalTable.tsx b/components/table/InternalTable.tsx index 2fa2a9c478..40586fe7bb 100644 --- a/components/table/InternalTable.tsx +++ b/components/table/InternalTable.tsx @@ -8,10 +8,10 @@ import type { Breakpoint } from '../_util/responsiveObserver'; import scrollTo from '../_util/scrollTo'; import warning from '../_util/warning'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; import type { ConfigConsumerProps } from '../config-provider/context'; import { ConfigContext } from '../config-provider/context'; import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty'; +import useSize from '../config-provider/hooks/useSize'; import useBreakpoint from '../grid/hooks/useBreakpoint'; import defaultLocale from '../locale/en_US'; import Pagination from '../pagination'; @@ -173,8 +173,6 @@ const InternalTable = ( const tableProps: TableProps = omit(props, ['className', 'style', 'columns']); - const size = React.useContext(SizeContext); - const { locale: contextLocale = defaultLocale, direction, @@ -183,7 +181,7 @@ const InternalTable = ( getPopupContainer: getContextPopupContainer, } = React.useContext(ConfigContext); - const mergedSize = customizeSize || size; + const mergedSize = useSize(customizeSize); const tableLocale: TableLocale = { ...contextLocale.Table, ...locale }; const rawData: readonly RecordType[] = dataSource || EMPTY_LIST; diff --git a/components/tabs/index.tsx b/components/tabs/index.tsx index 55f237c2ef..fe80f23189 100755 --- a/components/tabs/index.tsx +++ b/components/tabs/index.tsx @@ -6,14 +6,13 @@ import type { TabsProps as RcTabsProps } from 'rc-tabs'; import RcTabs from 'rc-tabs'; import type { EditableConfig } from 'rc-tabs/lib/interface'; import * as React from 'react'; +import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; import type { SizeType } from '../config-provider/SizeContext'; -import SizeContext from '../config-provider/SizeContext'; -import warning from '../_util/warning'; +import useSize from '../config-provider/hooks/useSize'; +import TabPane, { type TabPaneProps } from './TabPane'; import useAnimateConfig from './hooks/useAnimateConfig'; import useLegacyItems from './hooks/useLegacyItems'; -import TabPane, { type TabPaneProps } from './TabPane'; - import useStyle from './style'; export type TabsType = 'line' | 'card' | 'editable-card'; @@ -36,7 +35,7 @@ function Tabs({ type, className, rootClassName, - size: propSize, + size: customSize, onEdit, hideAdd, centered, @@ -75,9 +74,7 @@ function Tabs({ const mergedAnimated = useAnimateConfig(prefixCls, animated); - const contextSize = React.useContext(SizeContext); - - const size = propSize !== undefined ? propSize : contextSize; + const size = useSize(customSize); return wrapSSR( compactSize ?? customizeSize ?? ctx); + // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); const mergedDisabled = customDisabled ?? disabled; diff --git a/scripts/check-commit.ts b/scripts/check-commit.ts index c69976ff02..71f55bdb4d 100644 --- a/scripts/check-commit.ts +++ b/scripts/check-commit.ts @@ -17,7 +17,7 @@ function exitProcess(code = 1) { async function checkVersion() { try { - const { versions } = await fetch('http://registry.npmjs.org/antd').then((res: any) => + const { versions } = await fetch('http://registry.npmjs.org/antd').then((res: Response) => res.json(), ); if (version in versions) {