Browse Source

Merge branch master into master-merge-feature

pull/43459/head
栗嘉男 1 year ago
parent
commit
0e47a7673e
  1. 23
      components/badge/Ribbon.tsx
  2. 124
      components/badge/ScrollNumber.tsx
  3. 11
      components/button/LoadingIcon.tsx
  4. 2
      components/date-picker/__tests__/DatePicker.test.tsx
  5. 27
      components/descriptions/Cell.tsx
  6. 41
      components/descriptions/index.tsx
  7. 2
      components/dropdown/__tests__/index.test.tsx
  8. 172
      components/input/TextArea.tsx
  9. 3
      components/modal/demo/modal-render.tsx
  10. 4
      components/popconfirm/index.tsx
  11. 16
      components/popover/PurePanel.tsx
  12. 4
      components/popover/index.tsx
  13. 3
      components/tooltip/index.tsx
  14. 2
      package.json
  15. 13
      tests/__mocks__/@rc-component/trigger.tsx

23
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 { isPresetColor } from '../_util/colors';
import type { LiteralUnion } from '../_util/type';
import { ConfigContext } from '../config-provider';
import useStyle from './style';
import { isPresetColor } from '../_util/colors';
type RibbonPlacement = 'start' | 'end';
@ -18,15 +18,16 @@ export interface RibbonProps {
placement?: RibbonPlacement;
}
const Ribbon: React.FC<RibbonProps> = ({
className,
prefixCls: customizePrefixCls,
style,
color,
children,
text,
placement = 'end',
}) => {
const Ribbon: React.FC<RibbonProps> = (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);

124
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<HTMLElement, ScrollNumberProps>(
(
{
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<HTMLElement, ScrollNumberProps>((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('');
// 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) => (
<SingleNumber
prefixCls={prefixCls}
count={Number(count)}
value={num}
// eslint-disable-next-line react/no-array-index-key
key={numberList.length - i}
/>
));
}
numberNodes = numberList.map((num, i) => (
<SingleNumber
prefixCls={prefixCls}
count={Number(count)}
value={num}
// eslint-disable-next-line react/no-array-index-key
key={numberList.length - i}
/>
));
}
// allow specify the border
// mock border-color by box-shadow for compatible with old usage:
// <Badge count={4} style={{ backgroundColor: '#fff', color: '#999', borderColor: '#d9d9d9' }} />
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,
),
}));
}
// allow specify the border
// mock border-color by box-shadow for compatible with old usage:
// <Badge count={4} style={{ backgroundColor: '#fff', color: '#999', borderColor: '#d9d9d9' }} />
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 (
<Component {...newProps} ref={ref}>
{numberNodes}
</Component>
);
},
);
return (
<Component {...newProps} ref={ref}>
{numberNodes}
</Component>
);
});
export default ScrollNumber;

11
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<LoadingIconProps> = ({
prefixCls,
loading,
existIcon,
className,
style,
}) => {
const LoadingIcon: React.FC<LoadingIconProps> = (props) => {
const { prefixCls, loading, existIcon, className, style } = props;
const visible = !!loading;
if (existIcon) {

2
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<unknown, TriggerProps>((props, ref) => {
default: h.forwardRef<HTMLElement, TriggerProps>((props, ref) => {
triggerProps = props;
return h.createElement(Trigger, { ref, ...props });
}),

27
components/descriptions/Cell.tsx

@ -19,19 +19,20 @@ export interface CellProps {
colon?: boolean;
}
const Cell: React.FC<CellProps> = ({
itemPrefixCls,
component,
span,
className,
style,
labelStyle,
contentStyle,
bordered,
label,
content,
colon,
}) => {
const Cell: React.FC<CellProps> = (props) => {
const {
itemPrefixCls,
component,
span,
className,
style,
labelStyle,
contentStyle,
bordered,
label,
content,
colon,
} = props;
const Component = component as any;
if (bordered) {

41
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<DescriptionsProps> & 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<ScreenMap>({});
@ -202,7 +207,7 @@ function Descriptions({
</div>
</DescriptionsContext.Provider>,
);
}
};
if (process.env.NODE_ENV !== 'production') {
Descriptions.displayName = 'Descriptions';

2
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<unknown, TriggerProps>((props, ref) => {
default: h.forwardRef<HTMLElement, TriggerProps>((props, ref) => {
triggerProps = props;
return h.createElement(Trigger, { ref, ...props });
}),

172
components/input/TextArea.tsx

@ -29,103 +29,97 @@ export interface TextAreaRef {
resizableTextArea?: RcTextAreaRef['resizableTextArea'];
}
const TextArea = forwardRef<TextAreaRef, TextAreaProps>(
(
{
prefixCls: customizePrefixCls,
bordered = true,
size: customizeSize,
disabled: customDisabled,
status: customStatus,
allowClear,
showCount,
classNames: classes,
...rest
},
ref,
) => {
const { getPrefixCls, direction } = React.useContext(ConfigContext);
const TextArea = forwardRef<TextAreaRef, TextAreaProps>((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);
// ===================== Size =====================
const mergedSize = useSize(customizeSize);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);
const mergedDisabled = customDisabled ?? disabled;
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);
const mergedDisabled = customDisabled ?? disabled;
// ===================== Status =====================
const {
status: contextStatus,
hasFeedback,
feedbackIcon,
} = React.useContext(FormItemInputContext);
const mergedStatus = getMergedStatus(contextStatus, customStatus);
// ===================== Status =====================
const {
status: contextStatus,
hasFeedback,
feedbackIcon,
} = React.useContext(FormItemInputContext);
const mergedStatus = getMergedStatus(contextStatus, customStatus);
// ===================== Ref =====================
const innerRef = React.useRef<RcTextAreaRef>(null);
// ===================== Ref =====================
const innerRef = React.useRef<RcTextAreaRef>(null);
React.useImperativeHandle(ref, () => ({
resizableTextArea: innerRef.current?.resizableTextArea,
focus: (option?: InputFocusOptions) => {
triggerFocus(innerRef.current?.resizableTextArea?.textArea, option);
},
blur: () => innerRef.current?.blur(),
}));
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);
const prefixCls = getPrefixCls('input', customizePrefixCls);
// Allow clear
let mergedAllowClear: BaseInputProps['allowClear'];
if (typeof allowClear === 'object' && allowClear?.clearIcon) {
mergedAllowClear = allowClear;
} else if (allowClear) {
mergedAllowClear = { clearIcon: <CloseCircleFilled /> };
}
// Allow clear
let mergedAllowClear: BaseInputProps['allowClear'];
if (typeof allowClear === 'object' && allowClear?.clearIcon) {
mergedAllowClear = allowClear;
} else if (allowClear) {
mergedAllowClear = { clearIcon: <CloseCircleFilled /> };
}
// ===================== Style =====================
const [wrapSSR, hashId] = useStyle(prefixCls);
// ===================== Style =====================
const [wrapSSR, hashId] = useStyle(prefixCls);
return wrapSSR(
<RcTextArea
{...rest}
disabled={mergedDisabled}
allowClear={mergedAllowClear}
classes={{
affixWrapper: classNames(
`${prefixCls}-textarea-affix-wrapper`,
{
[`${prefixCls}-affix-wrapper-rtl`]: direction === 'rtl',
[`${prefixCls}-affix-wrapper-borderless`]: !bordered,
[`${prefixCls}-affix-wrapper-sm`]: mergedSize === 'small',
[`${prefixCls}-affix-wrapper-lg`]: mergedSize === 'large',
[`${prefixCls}-textarea-show-count`]: showCount,
},
getStatusClassNames(`${prefixCls}-affix-wrapper`, mergedStatus),
hashId,
),
}}
classNames={{
...classes,
textarea: classNames(
{
[`${prefixCls}-borderless`]: !bordered,
[`${prefixCls}-sm`]: mergedSize === 'small',
[`${prefixCls}-lg`]: mergedSize === 'large',
},
getStatusClassNames(prefixCls, mergedStatus),
hashId,
classes?.textarea,
),
}}
prefixCls={prefixCls}
suffix={
hasFeedback && <span className={`${prefixCls}-textarea-suffix`}>{feedbackIcon}</span>
}
showCount={showCount}
ref={innerRef}
/>,
);
},
);
return wrapSSR(
<RcTextArea
{...rest}
disabled={mergedDisabled}
allowClear={mergedAllowClear}
classes={{
affixWrapper: classNames(
`${prefixCls}-textarea-affix-wrapper`,
{
[`${prefixCls}-affix-wrapper-rtl`]: direction === 'rtl',
[`${prefixCls}-affix-wrapper-borderless`]: !bordered,
[`${prefixCls}-affix-wrapper-sm`]: mergedSize === 'small',
[`${prefixCls}-affix-wrapper-lg`]: mergedSize === 'large',
[`${prefixCls}-textarea-show-count`]: showCount,
},
getStatusClassNames(`${prefixCls}-affix-wrapper`, mergedStatus),
hashId,
),
}}
classNames={{
...classes,
textarea: classNames(
{
[`${prefixCls}-borderless`]: !bordered,
[`${prefixCls}-sm`]: mergedSize === 'small',
[`${prefixCls}-lg`]: mergedSize === 'large',
},
getStatusClassNames(prefixCls, mergedStatus),
hashId,
classes?.textarea,
),
}}
prefixCls={prefixCls}
suffix={hasFeedback && <span className={`${prefixCls}-textarea-suffix`}>{feedbackIcon}</span>}
showCount={showCount}
ref={innerRef}
/>,
);
});
export default TextArea;

3
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 = () => {
<Draggable
disabled={disabled}
bounds={bounds}
nodeRef={draggleRef}
onStart={(event, uiData) => onStart(event, uiData)}
>
<div ref={draggleRef}>{modal}</div>

4
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<unknown, PopconfirmProps>((props, ref) => {
const Popconfirm = React.forwardRef<TooltipRef, PopconfirmProps>((props, ref) => {
const {
prefixCls: customizePrefixCls,
placement = 'top',

16
components/popover/PurePanel.tsx

@ -25,7 +25,11 @@ export interface PurePanelProps extends Omit<PopoverProps, 'children'> {
children?: React.ReactNode;
}
export function RawPurePanel(props: any) {
interface RawPurePanelProps extends PopoverProps {
hashId: string;
}
export const RawPurePanel: React.FC<RawPurePanelProps> = (props) => {
const {
hashId,
prefixCls,
@ -50,13 +54,13 @@ export function RawPurePanel(props: any) {
>
<div className={`${prefixCls}-arrow`} />
<Popup {...props} className={hashId} prefixCls={prefixCls}>
{children || getOverlay(prefixCls, title, content)}
{children || getOverlay(prefixCls!, title, content)}
</Popup>
</div>
);
}
};
export default function PurePanel(props: any) {
const PurePanel: React.FC<PurePanelProps> = (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(<RawPurePanel {...restProps} prefixCls={prefixCls} hashId={hashId} />);
}
};
export default PurePanel;

4
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<OverlayProps> = ({ title, content, prefixCls }) => (
</>
);
const Popover = React.forwardRef<unknown, PopoverProps>((props, ref) => {
const Popover = React.forwardRef<TooltipRef, PopoverProps>((props, ref) => {
const {
prefixCls: customizePrefixCls,
title,

3
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;

2
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",

13
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<any, TriggerProps>((props, ref) => {
const ForwardTrigger = React.forwardRef<TriggerRef, TriggerProps>((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 <OriginTrigger {...mergedProps} />;
return <OriginTrigger ref={ref} {...mergedProps} />;
}
return <MockTrigger {...mergedProps} />;
return <MockTrigger ref={ref} {...mergedProps} />;
});
export default ForwardTrigger;

Loading…
Cancel
Save