diff --git a/components/badge/Ribbon.tsx b/components/badge/Ribbon.tsx index 05760f6e93..453c071d0c 100644 --- a/components/badge/Ribbon.tsx +++ b/components/badge/Ribbon.tsx @@ -1,10 +1,10 @@ import classNames from 'classnames'; import * as React from 'react'; -import { ConfigContext } from '../config-provider'; import type { PresetColorType } from '../_util/colors'; -import type { LiteralUnion } from '../_util/type'; -import useStyle from './style'; import { isPresetColor } from '../_util/colors'; +import type { LiteralUnion } from '../_util/type'; +import { ConfigContext } from '../config-provider'; +import useStyle from './style'; type RibbonPlacement = 'start' | 'end'; @@ -18,15 +18,16 @@ export interface RibbonProps { placement?: RibbonPlacement; } -const Ribbon: React.FC = ({ - className, - prefixCls: customizePrefixCls, - style, - color, - children, - text, - placement = 'end', -}) => { +const Ribbon: React.FC = (props) => { + const { + className, + prefixCls: customizePrefixCls, + style, + color, + children, + text, + placement = 'end', + } = props; const { getPrefixCls, direction } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('ribbon', customizePrefixCls); const colorInPreset = isPresetColor(color, false); diff --git a/components/badge/ScrollNumber.tsx b/components/badge/ScrollNumber.tsx index 83eaafbde5..a71762ac2c 100644 --- a/components/badge/ScrollNumber.tsx +++ b/components/badge/ScrollNumber.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; import * as React from 'react'; -import { ConfigContext } from '../config-provider'; import { cloneElement } from '../_util/reactNode'; +import { ConfigContext } from '../config-provider'; import SingleNumber from './SingleNumber'; export interface ScrollNumberProps { @@ -21,75 +21,67 @@ export interface ScrollNumberState { count?: string | number | null; } -const ScrollNumber = React.forwardRef( - ( - { - prefixCls: customizePrefixCls, - count, - className, - motionClassName, - style, - title, - show, - component: Component = 'sup', - children, - ...restProps - }, - ref, - ) => { - const { getPrefixCls } = React.useContext(ConfigContext); - const prefixCls = getPrefixCls('scroll-number', customizePrefixCls); +const ScrollNumber = React.forwardRef((props, ref) => { + const { + prefixCls: customizePrefixCls, + count, + className, + motionClassName, + style, + title, + show, + component: Component = 'sup', + children, + ...restProps + } = props; + const { getPrefixCls } = React.useContext(ConfigContext); + const prefixCls = getPrefixCls('scroll-number', customizePrefixCls); - // ============================ Render ============================ - const newProps = { - ...restProps, - 'data-show': show, - style, - className: classNames(prefixCls, className, motionClassName), - title: title as string, + // ============================ Render ============================ + const newProps = { + ...restProps, + 'data-show': show, + style, + className: classNames(prefixCls, className, motionClassName), + title: title as string, + }; + + // Only integer need motion + let numberNodes: React.ReactNode = count; + if (count && Number(count) % 1 === 0) { + const numberList = String(count).split(''); + + numberNodes = numberList.map((num, i) => ( + + )); + } + + // allow specify the border + // mock border-color by box-shadow for compatible with old usage: + // + if (style && style.borderColor) { + newProps.style = { + ...style, + boxShadow: `0 0 0 1px ${style.borderColor} inset`, }; + } + if (children) { + return cloneElement(children, (oriProps) => ({ + className: classNames(`${prefixCls}-custom-component`, oriProps?.className, motionClassName), + })); + } - // Only integer need motion - let numberNodes: React.ReactNode = count; - if (count && Number(count) % 1 === 0) { - const numberList = String(count).split(''); - - numberNodes = numberList.map((num, i) => ( - - )); - } - - // allow specify the border - // mock border-color by box-shadow for compatible with old usage: - // - if (style && style.borderColor) { - newProps.style = { - ...style, - boxShadow: `0 0 0 1px ${style.borderColor} inset`, - }; - } - if (children) { - return cloneElement(children, (oriProps) => ({ - className: classNames( - `${prefixCls}-custom-component`, - oriProps?.className, - motionClassName, - ), - })); - } - - return ( - - {numberNodes} - - ); - }, -); + return ( + + {numberNodes} + + ); +}); export default ScrollNumber; diff --git a/components/button/LoadingIcon.tsx b/components/button/LoadingIcon.tsx index 8b4cc16a4f..8ab9d6d291 100644 --- a/components/button/LoadingIcon.tsx +++ b/components/button/LoadingIcon.tsx @@ -1,7 +1,7 @@ import LoadingOutlined from '@ant-design/icons/LoadingOutlined'; +import classNames from 'classnames'; import CSSMotion from 'rc-motion'; import React, { forwardRef } from 'react'; -import classNames from 'classnames'; import IconWrapper from './IconWrapper'; type InnerLoadingIconProps = { @@ -43,13 +43,8 @@ const getRealWidth = (node: HTMLElement): React.CSSProperties => ({ transform: 'scale(1)', }); -const LoadingIcon: React.FC = ({ - prefixCls, - loading, - existIcon, - className, - style, -}) => { +const LoadingIcon: React.FC = (props) => { + const { prefixCls, loading, existIcon, className, style } = props; const visible = !!loading; if (existIcon) { diff --git a/components/date-picker/__tests__/DatePicker.test.tsx b/components/date-picker/__tests__/DatePicker.test.tsx index 6df4622b3e..c7b7533ba1 100644 --- a/components/date-picker/__tests__/DatePicker.test.tsx +++ b/components/date-picker/__tests__/DatePicker.test.tsx @@ -21,7 +21,7 @@ jest.mock('@rc-component/trigger', () => { const h: typeof React = jest.requireActual('react'); return { - default: h.forwardRef((props, ref) => { + default: h.forwardRef((props, ref) => { triggerProps = props; return h.createElement(Trigger, { ref, ...props }); }), diff --git a/components/descriptions/Cell.tsx b/components/descriptions/Cell.tsx index fe7bd3ca2a..55256c8407 100644 --- a/components/descriptions/Cell.tsx +++ b/components/descriptions/Cell.tsx @@ -19,19 +19,20 @@ export interface CellProps { colon?: boolean; } -const Cell: React.FC = ({ - itemPrefixCls, - component, - span, - className, - style, - labelStyle, - contentStyle, - bordered, - label, - content, - colon, -}) => { +const Cell: React.FC = (props) => { + const { + itemPrefixCls, + component, + span, + className, + style, + labelStyle, + contentStyle, + bordered, + label, + content, + colon, + } = props; const Component = component as any; if (bordered) { diff --git a/components/descriptions/index.tsx b/components/descriptions/index.tsx index 055901ecb1..ca8c685eb7 100644 --- a/components/descriptions/index.tsx +++ b/components/descriptions/index.tsx @@ -92,6 +92,10 @@ function getRows(children: React.ReactNode, column: number) { return rows; } +interface CompoundedComponent { + Item: typeof DescriptionsItem; +} + export interface DescriptionsProps { prefixCls?: string; className?: string; @@ -109,23 +113,24 @@ export interface DescriptionsProps { contentStyle?: React.CSSProperties; } -function Descriptions({ - prefixCls: customizePrefixCls, - title, - extra, - column = DEFAULT_COLUMN_MAP, - colon = true, - bordered, - layout, - children, - className, - rootClassName, - style, - size: customizeSize, - labelStyle, - contentStyle, - ...restProps -}: DescriptionsProps) { +const Descriptions: React.FC & CompoundedComponent = (props) => { + const { + prefixCls: customizePrefixCls, + title, + extra, + column = DEFAULT_COLUMN_MAP, + colon = true, + bordered, + layout, + children, + className, + rootClassName, + style, + size: customizeSize, + labelStyle, + contentStyle, + ...restProps + } = props; const { getPrefixCls, direction, descriptions } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('descriptions', customizePrefixCls); const [screens, setScreens] = React.useState({}); @@ -202,7 +207,7 @@ function Descriptions({ , ); -} +}; if (process.env.NODE_ENV !== 'production') { Descriptions.displayName = 'Descriptions'; diff --git a/components/dropdown/__tests__/index.test.tsx b/components/dropdown/__tests__/index.test.tsx index fa3f15b081..0af4b9fcac 100644 --- a/components/dropdown/__tests__/index.test.tsx +++ b/components/dropdown/__tests__/index.test.tsx @@ -15,7 +15,7 @@ jest.mock('@rc-component/trigger', () => { const h: typeof React = jest.requireActual('react'); return { - default: h.forwardRef((props, ref) => { + default: h.forwardRef((props, ref) => { triggerProps = props; return h.createElement(Trigger, { ref, ...props }); }), diff --git a/components/input/TextArea.tsx b/components/input/TextArea.tsx index 5104fbcf76..e4d79a303f 100644 --- a/components/input/TextArea.tsx +++ b/components/input/TextArea.tsx @@ -29,103 +29,97 @@ export interface TextAreaRef { resizableTextArea?: RcTextAreaRef['resizableTextArea']; } -const TextArea = forwardRef( - ( - { - prefixCls: customizePrefixCls, - bordered = true, - size: customizeSize, - disabled: customDisabled, - status: customStatus, - allowClear, - showCount, - classNames: classes, - ...rest +const TextArea = forwardRef((props, ref) => { + const { + prefixCls: customizePrefixCls, + bordered = true, + size: customizeSize, + disabled: customDisabled, + status: customStatus, + allowClear, + showCount, + classNames: classes, + ...rest + } = props; + const { getPrefixCls, direction } = React.useContext(ConfigContext); + + // ===================== Size ===================== + const mergedSize = useSize(customizeSize); + + // ===================== Disabled ===================== + const disabled = React.useContext(DisabledContext); + const mergedDisabled = customDisabled ?? disabled; + + // ===================== Status ===================== + const { + status: contextStatus, + hasFeedback, + feedbackIcon, + } = React.useContext(FormItemInputContext); + const mergedStatus = getMergedStatus(contextStatus, customStatus); + + // ===================== Ref ===================== + const innerRef = React.useRef(null); + + React.useImperativeHandle(ref, () => ({ + resizableTextArea: innerRef.current?.resizableTextArea, + focus: (option?: InputFocusOptions) => { + triggerFocus(innerRef.current?.resizableTextArea?.textArea, option); }, - ref, - ) => { - const { getPrefixCls, direction } = React.useContext(ConfigContext); + blur: () => innerRef.current?.blur(), + })); - // ===================== Size ===================== - const mergedSize = useSize(customizeSize); + const prefixCls = getPrefixCls('input', customizePrefixCls); - // ===================== Disabled ===================== - const disabled = React.useContext(DisabledContext); - const mergedDisabled = customDisabled ?? disabled; + // Allow clear + let mergedAllowClear: BaseInputProps['allowClear']; + if (typeof allowClear === 'object' && allowClear?.clearIcon) { + mergedAllowClear = allowClear; + } else if (allowClear) { + mergedAllowClear = { clearIcon: }; + } - // ===================== Status ===================== - const { - status: contextStatus, - hasFeedback, - feedbackIcon, - } = React.useContext(FormItemInputContext); - const mergedStatus = getMergedStatus(contextStatus, customStatus); + // ===================== Style ===================== + const [wrapSSR, hashId] = useStyle(prefixCls); - // ===================== Ref ===================== - const innerRef = React.useRef(null); - - React.useImperativeHandle(ref, () => ({ - resizableTextArea: innerRef.current?.resizableTextArea, - focus: (option?: InputFocusOptions) => { - triggerFocus(innerRef.current?.resizableTextArea?.textArea, option); - }, - blur: () => innerRef.current?.blur(), - })); - - const prefixCls = getPrefixCls('input', customizePrefixCls); - - // Allow clear - let mergedAllowClear: BaseInputProps['allowClear']; - if (typeof allowClear === 'object' && allowClear?.clearIcon) { - mergedAllowClear = allowClear; - } else if (allowClear) { - mergedAllowClear = { clearIcon: }; - } - - // ===================== Style ===================== - const [wrapSSR, hashId] = useStyle(prefixCls); - - return wrapSSR( - {feedbackIcon} - } - showCount={showCount} - ref={innerRef} - />, - ); - }, -); + return wrapSSR( + {feedbackIcon}} + showCount={showCount} + ref={innerRef} + />, + ); +}); export default TextArea; diff --git a/components/modal/demo/modal-render.tsx b/components/modal/demo/modal-render.tsx index f6d98c7f84..60725675c8 100644 --- a/components/modal/demo/modal-render.tsx +++ b/components/modal/demo/modal-render.tsx @@ -1,5 +1,5 @@ -import React, { useRef, useState } from 'react'; import { Button, Modal } from 'antd'; +import React, { useRef, useState } from 'react'; import type { DraggableData, DraggableEvent } from 'react-draggable'; import Draggable from 'react-draggable'; @@ -71,6 +71,7 @@ const App: React.FC = () => { onStart(event, uiData)} >
{modal}
diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx index 9263c11357..5e3e8b5661 100644 --- a/components/popconfirm/index.tsx +++ b/components/popconfirm/index.tsx @@ -9,7 +9,7 @@ import { cloneElement } from '../_util/reactNode'; import type { ButtonProps, LegacyButtonType } from '../button/button'; import { ConfigContext } from '../config-provider'; import Popover from '../popover'; -import type { AbstractTooltipProps } from '../tooltip'; +import type { AbstractTooltipProps, TooltipRef } from '../tooltip'; import PurePanel, { Overlay } from './PurePanel'; import usePopconfirmStyle from './style'; @@ -37,7 +37,7 @@ export interface PopconfirmState { open?: boolean; } -const Popconfirm = React.forwardRef((props, ref) => { +const Popconfirm = React.forwardRef((props, ref) => { const { prefixCls: customizePrefixCls, placement = 'top', diff --git a/components/popover/PurePanel.tsx b/components/popover/PurePanel.tsx index 29259c7f15..218583505f 100644 --- a/components/popover/PurePanel.tsx +++ b/components/popover/PurePanel.tsx @@ -25,7 +25,11 @@ export interface PurePanelProps extends Omit { children?: React.ReactNode; } -export function RawPurePanel(props: any) { +interface RawPurePanelProps extends PopoverProps { + hashId: string; +} + +export const RawPurePanel: React.FC = (props) => { const { hashId, prefixCls, @@ -50,13 +54,13 @@ export function RawPurePanel(props: any) { >
- {children || getOverlay(prefixCls, title, content)} + {children || getOverlay(prefixCls!, title, content)}
); -} +}; -export default function PurePanel(props: any) { +const PurePanel: React.FC = (props) => { const { prefixCls: customizePrefixCls, ...restProps } = props; const { getPrefixCls } = React.useContext(ConfigContext); @@ -64,4 +68,6 @@ export default function PurePanel(props: any) { const [wrapSSR, hashId] = useStyle(prefixCls); return wrapSSR(); -} +}; + +export default PurePanel; diff --git a/components/popover/index.tsx b/components/popover/index.tsx index 23db59123e..42a7ddf9f6 100644 --- a/components/popover/index.tsx +++ b/components/popover/index.tsx @@ -4,7 +4,7 @@ import type { RenderFunction } from '../_util/getRenderPropValue'; import { getRenderPropValue } from '../_util/getRenderPropValue'; import { getTransitionName } from '../_util/motion'; import { ConfigContext } from '../config-provider'; -import type { AbstractTooltipProps } from '../tooltip'; +import type { AbstractTooltipProps, TooltipRef } from '../tooltip'; import Tooltip from '../tooltip'; import PurePanel from './PurePanel'; // CSSINJS @@ -28,7 +28,7 @@ const Overlay: React.FC = ({ title, content, prefixCls }) => ( ); -const Popover = React.forwardRef((props, ref) => { +const Popover = React.forwardRef((props, ref) => { const { prefixCls: customizePrefixCls, title, diff --git a/components/tooltip/index.tsx b/components/tooltip/index.tsx index 4b7432b32d..4d3b402837 100644 --- a/components/tooltip/index.tsx +++ b/components/tooltip/index.tsx @@ -10,6 +10,7 @@ import useMergedState from 'rc-util/lib/hooks/useMergedState'; import type { CSSProperties } from 'react'; import * as React from 'react'; import type { PresetColorType } from '../_util/colors'; +import type { RenderFunction } from '../_util/getRenderPropValue'; import { getTransitionName } from '../_util/motion'; import type { AdjustOverflow, PlacementsConfig } from '../_util/placements'; import getPlacements from '../_util/placements'; @@ -110,8 +111,6 @@ export interface AbstractTooltipProps extends LegacyTooltipProps { destroyTooltipOnHide?: boolean | { keepParent?: boolean }; } -export type RenderFunction = () => React.ReactNode; - export interface TooltipPropsWithOverlay extends AbstractTooltipProps { title?: React.ReactNode | RenderFunction; overlay?: React.ReactNode | RenderFunction; diff --git a/package.json b/package.json index 8bcd89af9b..e51970ba11 100644 --- a/package.json +++ b/package.json @@ -291,7 +291,7 @@ "stylelint": "^15.1.0", "stylelint-config-rational-order": "^0.1.2", "stylelint-config-standard": "^34.0.0", - "stylelint-prettier": "^3.0.0", + "stylelint-prettier": "^4.0.0", "sylvanas": "^0.6.1", "terser": "^5.16.1", "ts-node": "^10.8.2", diff --git a/tests/__mocks__/@rc-component/trigger.tsx b/tests/__mocks__/@rc-component/trigger.tsx index b9c9d5c88d..1c331e7774 100644 --- a/tests/__mocks__/@rc-component/trigger.tsx +++ b/tests/__mocks__/@rc-component/trigger.tsx @@ -1,4 +1,4 @@ -import type { TriggerProps } from '@rc-component/trigger'; +import type { TriggerProps, TriggerRef } from '@rc-component/trigger'; import MockTrigger from '@rc-component/trigger/lib/mock'; import * as React from 'react'; import { TriggerMockContext } from '../../shared/demoTestContext'; @@ -6,22 +6,21 @@ import { TriggerMockContext } from '../../shared/demoTestContext'; let OriginTrigger = jest.requireActual('@rc-component/trigger'); OriginTrigger = OriginTrigger.default ?? OriginTrigger; -const ForwardTrigger = React.forwardRef((props, ref) => { +const ForwardTrigger = React.forwardRef((props, ref) => { const context = React.useContext(TriggerMockContext); const mergedPopupVisible = context?.popupVisible ?? props.popupVisible; (global as any).triggerProps = props; - const mergedProps = { + const mergedProps: TriggerProps = { ...props, - ref, - popupVisible: mergedPopupVisible as boolean, + popupVisible: mergedPopupVisible, }; if (context?.mock === false) { - return ; + return ; } - return ; + return ; }); export default ForwardTrigger;