Merge branch 'master' into next-merge-master

This commit is contained in:
MadCcc 2022-10-17 15:54:11 +08:00
commit a431983aad
7 changed files with 49 additions and 96 deletions

View File

@ -1,5 +1,4 @@
import React from 'react';
// eslint-disable-next-line import/no-named-as-default
import { render } from '@testing-library/react';
import debounce from 'lodash/debounce';
import Spin from '..';
@ -32,7 +31,7 @@ describe('delay spinning', () => {
jest.useRealTimers();
});
it('should cancel debounce function when unmount', async () => {
it('should cancel debounce function when unmount', () => {
const debouncedFn = jest.fn();
const cancel = jest.fn();
(debouncedFn as any).cancel = cancel;

View File

@ -1,6 +1,6 @@
import React from 'react';
// eslint-disable-next-line import/no-named-as-default
import { render } from '@testing-library/react';
import { waitFakeTimer } from '../../../tests/utils';
import Spin from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
@ -15,10 +15,8 @@ describe('Spin', () => {
<div>content</div>
</Spin>,
);
expect((container.querySelector('.ant-spin-nested-loading')! as HTMLElement).style.length).toBe(
0,
);
expect((container.querySelector('.ant-spin')! as HTMLElement).style.background).toBe('red');
expect(container.querySelector<HTMLElement>('.ant-spin-nested-loading')?.style.length).toBe(0);
expect(container.querySelector<HTMLElement>('.ant-spin')?.style.background).toBe('red');
});
it("should render custom indicator when it's set", () => {
@ -27,11 +25,15 @@ describe('Spin', () => {
expect(asFragment().firstChild).toMatchSnapshot();
});
it('should be controlled by spinning', () => {
it('should be controlled by spinning', async () => {
jest.useFakeTimers();
const { container, rerender } = render(<Spin spinning={false} />);
expect(container.querySelector('.ant-spin-spinning')).toBeFalsy();
rerender(<Spin spinning />);
await waitFakeTimer();
expect(container.querySelector('.ant-spin-spinning')).toBeTruthy();
jest.clearAllTimers();
jest.useRealTimers();
});
it('if indicator set null should not be render default indicator', () => {

View File

@ -35,11 +35,6 @@ export type SpinFCType = React.FC<SpinProps> & {
setDefaultIndicator: (indicator: React.ReactNode) => void;
};
export interface SpinState {
spinning?: boolean;
notCssAnimationSupported?: boolean;
}
// Render indicator
let defaultIndicator: React.ReactNode = null;
@ -59,8 +54,8 @@ function renderIndicator(prefixCls: string, props: SpinClassProps): React.ReactN
}
if (isValidElement(defaultIndicator)) {
return cloneElement(defaultIndicator as SpinIndicator, {
className: classNames((defaultIndicator as SpinIndicator).props.className, dotClassName),
return cloneElement(defaultIndicator, {
className: classNames(defaultIndicator.props.className, dotClassName),
});
}
@ -78,80 +73,38 @@ function shouldDelay(spinning?: boolean, delay?: number): boolean {
return !!spinning && !!delay && !isNaN(Number(delay));
}
class Spin extends React.Component<SpinClassProps, SpinState> {
static defaultProps = {
spinning: true,
size: 'default' as SpinSize,
wrapperClassName: '',
};
const Spin: React.FC<SpinClassProps> = props => {
const {
spinPrefixCls: prefixCls,
spinning: customSpinning = true,
delay,
className,
size = 'default',
tip,
wrapperClassName,
style,
children,
hashId,
...restProps
} = props;
originalUpdateSpinning: () => void;
const [spinning, setSpinning] = React.useState<boolean>(
() => customSpinning && !shouldDelay(customSpinning, delay),
);
constructor(props: SpinClassProps) {
super(props);
const { spinning, delay } = props;
const shouldBeDelayed = shouldDelay(spinning, delay);
this.state = {
spinning: spinning && !shouldBeDelayed,
React.useEffect(() => {
const updateSpinning = debounce<() => void>(() => {
setSpinning(customSpinning);
}, delay);
updateSpinning();
return () => {
updateSpinning?.cancel?.();
};
this.originalUpdateSpinning = this.updateSpinning;
this.debouncifyUpdateSpinning(props);
}
}, [delay, customSpinning]);
componentDidMount() {
this.updateSpinning();
}
componentDidUpdate() {
this.debouncifyUpdateSpinning();
this.updateSpinning();
}
componentWillUnmount() {
this.cancelExistingSpin();
}
debouncifyUpdateSpinning = (props?: SpinClassProps) => {
const { delay } = props || this.props;
if (delay) {
this.cancelExistingSpin();
this.updateSpinning = debounce(this.originalUpdateSpinning, delay);
}
};
updateSpinning = () => {
const { spinning } = this.props;
const { spinning: currentSpinning } = this.state;
if (currentSpinning !== spinning) {
this.setState({ spinning });
}
};
cancelExistingSpin() {
const { updateSpinning } = this;
if (updateSpinning && (updateSpinning as any).cancel) {
(updateSpinning as any).cancel();
}
}
isNestedPattern() {
return !!(this.props && typeof this.props.children !== 'undefined');
}
renderSpin = ({ direction }: ConfigConsumerProps) => {
const {
spinPrefixCls: prefixCls,
hashId,
className,
size,
tip,
wrapperClassName,
style,
...restProps
} = this.props;
const { spinning } = this.state;
const isNestedPattern = () => typeof children !== 'undefined';
const renderSpin = ({ direction }: ConfigConsumerProps) => {
const spinClassName = classNames(
prefixCls,
{
@ -166,7 +119,7 @@ class Spin extends React.Component<SpinClassProps, SpinState> {
);
// fix https://fb.me/react-unknown-prop
const divProps = omit(restProps, ['spinning', 'delay', 'indicator', 'prefixCls']);
const divProps = omit(restProps, ['indicator', 'prefixCls']);
const spinElement = (
<div
@ -176,11 +129,12 @@ class Spin extends React.Component<SpinClassProps, SpinState> {
aria-live="polite"
aria-busy={spinning}
>
{renderIndicator(prefixCls, this.props)}
{renderIndicator(prefixCls, props)}
{tip ? <div className={`${prefixCls}-text`}>{tip}</div> : null}
</div>
);
if (this.isNestedPattern()) {
if (isNestedPattern()) {
const containerClassName = classNames(`${prefixCls}-container`, {
[`${prefixCls}-blur`]: spinning,
});
@ -191,18 +145,15 @@ class Spin extends React.Component<SpinClassProps, SpinState> {
>
{spinning && <div key="loading">{spinElement}</div>}
<div className={containerClassName} key="container">
{this.props.children}
{children}
</div>
</div>
);
}
return spinElement;
};
render() {
return <ConfigConsumer>{this.renderSpin}</ConfigConsumer>;
}
}
return <ConfigConsumer>{renderSpin}</ConfigConsumer>;
};
const SpinFC: SpinFCType = props => {
const { prefixCls: customizePrefixCls } = props;

View File

@ -64,7 +64,7 @@ const App: React.FC = () => {
};
const onSelectChange = (newSelectedRowKeys: React.Key[]) => {
console.log('selectedRowKeys changed: ', selectedRowKeys);
console.log('selectedRowKeys changed: ', newSelectedRowKeys);
setSelectedRowKeys(newSelectedRowKeys);
};

View File

@ -55,7 +55,7 @@ const App: React.FC = () => {
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const onSelectChange = (newSelectedRowKeys: React.Key[]) => {
console.log('selectedRowKeys changed: ', selectedRowKeys);
console.log('selectedRowKeys changed: ', newSelectedRowKeys);
setSelectedRowKeys(newSelectedRowKeys);
};

View File

@ -14,4 +14,4 @@ services:
- './jest-puppeteer.config.js:/app/jest-puppeteer.config.js'
- './imageSnapshots:/app/imageSnapshots'
- './imageDiffSnapshots:/app/imageDiffSnapshots'
entrypoint: "jest --config .jest.image.js --no-cache -i"
entrypoint: "npm run test-image:docker"

View File

@ -92,6 +92,7 @@
"tsc": "tsc --noEmit",
"site:test": "jest --config .jest.site.js --cache=false --force-exit",
"test-image": "npm run dist && docker-compose run tests",
"test-image:docker": "node node_modules/puppeteer/install.js && jest --config .jest.image.js --no-cache -i",
"argos": "node ./scripts/argos-upload.js",
"version": "node ./scripts/generate-version",
"install-react-16": "npm i --no-save --legacy-peer-deps react@16 react-dom@16",