mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 03:59:01 +08:00
chore: Static warning if exist theme in CP (#41157)
* chore: warning for dynamic theme * chore: warning for static context * chore: add ignore
This commit is contained in:
parent
1df1034f20
commit
36f44575c8
@ -27,6 +27,24 @@ import type { SizeType } from './SizeContext';
|
|||||||
import SizeContext, { SizeContextProvider } from './SizeContext';
|
import SizeContext, { SizeContextProvider } from './SizeContext';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Since too many feedback using static method like `Modal.confirm` not getting theme,
|
||||||
|
* we record the theme register info here to help developer get warning info.
|
||||||
|
*/
|
||||||
|
let existThemeConfig = false;
|
||||||
|
|
||||||
|
export const warnContext: (componentName: string) => void =
|
||||||
|
process.env.NODE_ENV !== 'production'
|
||||||
|
? (componentName: string) => {
|
||||||
|
warning(
|
||||||
|
!existThemeConfig,
|
||||||
|
componentName,
|
||||||
|
`Static function can not consume context like dynamic theme. Please use 'App' component instead.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
: /* istanbul ignore next */
|
||||||
|
null!;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
type RenderEmptyHandler,
|
type RenderEmptyHandler,
|
||||||
ConfigContext,
|
ConfigContext,
|
||||||
@ -192,6 +210,10 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
|
|||||||
|
|
||||||
const mergedTheme = useTheme(theme, parentContext.theme);
|
const mergedTheme = useTheme(theme, parentContext.theme);
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
existThemeConfig = existThemeConfig || !!mergedTheme;
|
||||||
|
}
|
||||||
|
|
||||||
const baseConfig = {
|
const baseConfig = {
|
||||||
csp,
|
csp,
|
||||||
autoInsertSpaceInButton,
|
autoInsertSpaceInButton,
|
||||||
|
57
components/message/__tests__/static-warning.test.tsx
Normal file
57
components/message/__tests__/static-warning.test.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import message, { actWrapper } from '..';
|
||||||
|
import { act, render, waitFakeTimer } from '../../../tests/utils';
|
||||||
|
import ConfigProvider from '../../config-provider';
|
||||||
|
import { awaitPromise, triggerMotionEnd } from './util';
|
||||||
|
|
||||||
|
describe('message static warning', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
actWrapper(act);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
// Clean up
|
||||||
|
message.destroy();
|
||||||
|
await triggerMotionEnd();
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
|
|
||||||
|
await awaitPromise();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Follow test need keep order
|
||||||
|
it('no warning', async () => {
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
|
message.success({
|
||||||
|
content: <div className="bamboo" />,
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
await waitFakeTimer();
|
||||||
|
|
||||||
|
expect(document.querySelector('.bamboo')).toBeTruthy();
|
||||||
|
|
||||||
|
expect(errSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('warning if use theme', async () => {
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
render(<ConfigProvider theme={{}} />);
|
||||||
|
|
||||||
|
message.success({
|
||||||
|
content: <div className="light" />,
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
await waitFakeTimer();
|
||||||
|
|
||||||
|
expect(document.querySelector('.light')).toBeTruthy();
|
||||||
|
|
||||||
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
|
"Warning: [antd: message] Static function can not consume context like dynamic theme. Please use 'App' component instead.",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import { render } from 'rc-util/lib/React/render';
|
import { render } from 'rc-util/lib/React/render';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import ConfigProvider, { globalConfig } from '../config-provider';
|
import ConfigProvider, { globalConfig, warnContext } from '../config-provider';
|
||||||
import type {
|
import type {
|
||||||
ArgsProps,
|
ArgsProps,
|
||||||
ConfigOptions,
|
ConfigOptions,
|
||||||
@ -262,6 +262,11 @@ function open(config: ArgsProps): MessageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function typeOpen(type: NoticeType, args: Parameters<TypeOpen>): MessageType {
|
function typeOpen(type: NoticeType, args: Parameters<TypeOpen>): MessageType {
|
||||||
|
// Warning if exist theme
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
warnContext('message');
|
||||||
|
}
|
||||||
|
|
||||||
const result = wrapPromiseFn((resolve) => {
|
const result = wrapPromiseFn((resolve) => {
|
||||||
let closeFn: VoidFunction;
|
let closeFn: VoidFunction;
|
||||||
|
|
||||||
|
49
components/modal/__tests__/static-warning.test.tsx
Normal file
49
components/modal/__tests__/static-warning.test.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Modal from '..';
|
||||||
|
import { render, waitFakeTimer } from '../../../tests/utils';
|
||||||
|
import ConfigProvider from '../../config-provider';
|
||||||
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
|
describe('Modal.confirm warning', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
resetWarned();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
Modal.destroyAll();
|
||||||
|
|
||||||
|
await waitFakeTimer();
|
||||||
|
document.body.innerHTML = '';
|
||||||
|
jest.clearAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Follow test need keep order
|
||||||
|
it('no warning', async () => {
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
Modal.confirm({
|
||||||
|
content: <div className="bamboo" />,
|
||||||
|
});
|
||||||
|
await waitFakeTimer();
|
||||||
|
|
||||||
|
expect(document.querySelector('.bamboo')).toBeTruthy();
|
||||||
|
|
||||||
|
expect(errSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('warning if use theme', async () => {
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
render(<ConfigProvider theme={{}} />);
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
content: <div className="light" />,
|
||||||
|
});
|
||||||
|
await waitFakeTimer();
|
||||||
|
|
||||||
|
expect(document.querySelector('.light')).toBeTruthy();
|
||||||
|
|
||||||
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
|
"Warning: [antd: Modal] Static function can not consume context like dynamic theme. Please use 'App' component instead.",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import { render as reactRender, unmount as reactUnmount } from 'rc-util/lib/React/render';
|
import { render as reactRender, unmount as reactUnmount } from 'rc-util/lib/React/render';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { globalConfig } from '../config-provider';
|
import { globalConfig, warnContext } from '../config-provider';
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
import ConfirmDialog from './ConfirmDialog';
|
import ConfirmDialog from './ConfirmDialog';
|
||||||
import destroyFns from './destroyFns';
|
import destroyFns from './destroyFns';
|
||||||
@ -23,6 +23,11 @@ export type ModalFunc = (props: ModalFuncProps) => {
|
|||||||
export type ModalStaticFunctions = Record<NonNullable<ModalFuncProps['type']>, ModalFunc>;
|
export type ModalStaticFunctions = Record<NonNullable<ModalFuncProps['type']>, ModalFunc>;
|
||||||
|
|
||||||
export default function confirm(config: ModalFuncProps) {
|
export default function confirm(config: ModalFuncProps) {
|
||||||
|
// Warning if exist theme
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
warnContext('Modal');
|
||||||
|
}
|
||||||
|
|
||||||
const container = document.createDocumentFragment();
|
const container = document.createDocumentFragment();
|
||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||||
let currentConfig = { ...config, close, open: true } as any;
|
let currentConfig = { ...config, close, open: true } as any;
|
||||||
|
57
components/notification/__tests__/static-warning.test.tsx
Normal file
57
components/notification/__tests__/static-warning.test.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import notification, { actWrapper } from '..';
|
||||||
|
import { act, render, waitFakeTimer } from '../../../tests/utils';
|
||||||
|
import ConfigProvider from '../../config-provider';
|
||||||
|
import { awaitPromise, triggerMotionEnd } from './util';
|
||||||
|
|
||||||
|
describe('notification static warning', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
actWrapper(act);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
// Clean up
|
||||||
|
notification.destroy();
|
||||||
|
await triggerMotionEnd();
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
|
|
||||||
|
await awaitPromise();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Follow test need keep order
|
||||||
|
it('no warning', async () => {
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
|
notification.open({
|
||||||
|
message: <div className="bamboo" />,
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
await waitFakeTimer();
|
||||||
|
|
||||||
|
expect(document.querySelector('.bamboo')).toBeTruthy();
|
||||||
|
|
||||||
|
expect(errSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('warning if use theme', async () => {
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
render(<ConfigProvider theme={{}} />);
|
||||||
|
|
||||||
|
notification.open({
|
||||||
|
message: <div className="light" />,
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
await waitFakeTimer();
|
||||||
|
|
||||||
|
expect(document.querySelector('.light')).toBeTruthy();
|
||||||
|
|
||||||
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
|
"Warning: [antd: notification] Static function can not consume context like dynamic theme. Please use 'App' component instead.",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import { render } from 'rc-util/lib/React/render';
|
import { render } from 'rc-util/lib/React/render';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import ConfigProvider, { globalConfig } from '../config-provider';
|
import ConfigProvider, { globalConfig, warnContext } from '../config-provider';
|
||||||
import type { ArgsProps, GlobalConfigProps, NotificationInstance } from './interface';
|
import type { ArgsProps, GlobalConfigProps, NotificationInstance } from './interface';
|
||||||
import PurePanel from './PurePanel';
|
import PurePanel from './PurePanel';
|
||||||
import useNotification, { useInternalNotification } from './useNotification';
|
import useNotification, { useInternalNotification } from './useNotification';
|
||||||
@ -201,6 +201,11 @@ function setNotificationGlobalConfig(config: GlobalConfigProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function open(config: ArgsProps) {
|
function open(config: ArgsProps) {
|
||||||
|
// Warning if exist theme
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
warnContext('notification');
|
||||||
|
}
|
||||||
|
|
||||||
taskQueue.push({
|
taskQueue.push({
|
||||||
type: 'open',
|
type: 'open',
|
||||||
config,
|
config,
|
||||||
|
Loading…
Reference in New Issue
Block a user