fix: notification placement via app component (#43522)

* fix: respect notification placement in App

* style: sort imports

* fix: prioritize global config

Fixes regression on global config test from previous change

* test: check if notification placement works

* lint: use consistent-type-import

* style: remove extra new lines in import block

* docs: update config demo

* chore: fix lint

---------

Co-authored-by: 二货机器人 <smith3816@gmail.com>
This commit is contained in:
Rajil Bajracharya 2023-07-17 09:15:06 +05:45 committed by GitHub
parent 74c7d207c1
commit e825e781de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 166 additions and 6 deletions

View File

@ -48,3 +48,39 @@ exports[`renders components/app/demo/basic.tsx extend context correctly 1`] = `
</div>
</div>
`;
exports[`renders components/app/demo/config.tsx extend context correctly 1`] = `
<div
class="ant-app"
>
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
style="margin-right: 8px;"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Message for only one
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Notification for bottomLeft
</span>
</button>
</div>
</div>
</div>
`;

View File

@ -48,3 +48,39 @@ exports[`renders components/app/demo/basic.tsx correctly 1`] = `
</div>
</div>
`;
exports[`renders components/app/demo/config.tsx correctly 1`] = `
<div
class="ant-app"
>
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
style="margin-right:8px"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Message for only one
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Notification for bottomLeft
</span>
</button>
</div>
</div>
</div>
`;

View File

@ -1,4 +1,5 @@
import React, { useEffect } from 'react';
import type { NotificationConfig } from 'antd/es/notification/interface';
import App from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
@ -123,6 +124,46 @@ describe('App', () => {
expect(config?.notification).toStrictEqual({ maxCount: 30, bottom: 41 });
});
it('should respect notification placement config from props in priority', async () => {
let consumedConfig: AppConfig | undefined;
const Consumer = () => {
const { notification } = App.useApp();
consumedConfig = React.useContext(AppConfigContext);
useEffect(() => {
notification.success({ message: 'Notification 1' });
notification.success({ message: 'Notification 2' });
notification.success({ message: 'Notification 3' });
}, [notification]);
return <div />;
};
const config: NotificationConfig = {
placement: 'bottomLeft',
top: 100,
bottom: 50,
};
const Wrapper = () => (
<App notification={config}>
<Consumer />
</App>
);
render(<Wrapper />);
await waitFakeTimer();
expect(consumedConfig?.notification).toStrictEqual(config);
expect(document.querySelector('.ant-notification-topRight')).not.toBeInTheDocument();
expect(document.querySelector('.ant-notification-bottomLeft')).toHaveStyle({
top: '',
left: '0px',
bottom: '50px',
});
});
it('support className', () => {
const { container } = render(
<App className="test-class">

View File

@ -1,7 +1,7 @@
## zh-CN
获取 `message`、`notification`、`modal` 静态方法
获取 `message`、`notification`、`modal` 实例
## en-US
Static method for `message`, `notification`, `modal`.
Get instance for `message`, `notification`, `modal`.

View File

@ -0,0 +1,7 @@
## zh-CN
`message`、`notification` 进行配置。
## en-US
Config for `message`, `notification`.

View File

@ -0,0 +1,36 @@
import React from 'react';
import { App, Button, Space } from 'antd';
// Sub page
const MyPage = () => {
const { message, notification } = App.useApp();
const showMessage = () => {
message.success('Success!');
};
const showNotification = () => {
notification.info({
message: `Notification`,
description: 'Hello, Ant Design!!',
});
};
return (
<Space>
<Button type="primary" onClick={showMessage}>
Message for only one
</Button>
<Button type="primary" onClick={showNotification}>
Notification for bottomLeft
</Button>
</Space>
);
};
// Entry component
export default () => (
<App message={{ maxCount: 1 }} notification={{ placement: 'bottomLeft' }}>
<MyPage />
</App>
);

View File

@ -18,7 +18,8 @@ Application wrapper for some global usages.
## Examples
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">basic</code>
<code src="./demo/basic.tsx">Basic</code>
<code src="./demo/config.tsx">Hooks config</code>
## How to use

View File

@ -20,6 +20,7 @@ demo:
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">基本用法</code>
<code src="./demo/config.tsx">Hooks 配置</code>
## 如何使用

View File

@ -1,22 +1,23 @@
import * as React from 'react';
import classNames from 'classnames';
import { useNotification as useRcNotification } from 'rc-notification';
import type { NotificationAPI } from 'rc-notification/lib';
import * as React from 'react';
import warning from '../_util/warning';
import { ConfigContext } from '../config-provider';
import type { ComponentStyleConfig } from '../config-provider/context';
import { PureContent, getCloseIcon } from './PurePanel';
import type {
ArgsProps,
NotificationConfig,
NotificationInstance,
NotificationPlacement,
} from './interface';
import { getCloseIcon, PureContent } from './PurePanel';
import useStyle from './style';
import { getMotion, getPlacementStyle } from './util';
const DEFAULT_OFFSET = 24;
const DEFAULT_DURATION = 4.5;
const DEFAULT_PLACEMENT: NotificationPlacement = 'topRight';
// ==============================================================================
// == Holder ==
@ -125,7 +126,8 @@ export function useInternalNotification(
const realCloseIcon = getCloseIcon(noticePrefixCls, closeIcon);
return originOpen({
placement: 'topRight',
// use placement from props instead of hard-coding "topRight"
placement: notificationConfig?.placement ?? DEFAULT_PLACEMENT,
...restConfig,
content: (
<PureContent