@synerise/ds-alert 0.6.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,41 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.7.2](https://github.com/Synerise/synerise-design/compare/@synerise/ds-alert@0.7.1...@synerise/ds-alert@0.7.2) (2022-07-28)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-alert
9
+
10
+
11
+
12
+
13
+
14
+ ## [0.7.1](https://github.com/Synerise/synerise-design/compare/@synerise/ds-alert@0.7.0...@synerise/ds-alert@0.7.1) (2022-04-05)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **alert:** Notification's notice border-radius ([1017519](https://github.com/Synerise/synerise-design/commit/1017519504de355667618737075adaf5b5bcb426))
20
+
21
+
22
+
23
+
24
+
25
+ # [0.7.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-alert@0.6.1...@synerise/ds-alert@0.7.0) (2022-04-01)
26
+
27
+
28
+ ### Bug Fixes
29
+
30
+ * **alert:** linter Promise, async function returns Promise<void> ([5c1e54d](https://github.com/Synerise/synerise-design/commit/5c1e54d52a0897345cd88609adcbdcdcf5fd85bf))
31
+
32
+
33
+ ### Features
34
+
35
+ * **alert:** notificationOpen to use Promise interface ([531b813](https://github.com/Synerise/synerise-design/commit/531b81318370f97d29c13d14510e602b861e20f4))
36
+
37
+
38
+
39
+
40
+
6
41
  ## [0.6.1](https://github.com/Synerise/synerise-design/compare/@synerise/ds-alert@0.6.0...@synerise/ds-alert@0.6.1) (2022-03-31)
7
42
 
8
43
 
package/README.md CHANGED
@@ -28,22 +28,31 @@ import Alert from '@synerise/ds-alert'
28
28
 
29
29
  ```
30
30
 
31
- ### notifications api usage
31
+ ### Notifications
32
32
 
33
- #### Simple (`ant`-based)
33
+ Notifications API offer three things:
34
+
35
+ * `<Notification/>` component for styled content,
36
+ * `notificationApi.useNotification()` for building a tunnel for the the right ContextApi (notifications use both `React.createPortal` plus they are mounted in container mounted in `document.body` for making it possible to position them correctly),
37
+ * *Pro-users*: change `getContainer` for sending notifications in other scrollable sections (`@synerise/ds-modal`, `@synerise/ds-section`).
38
+ * and `notificationOpen` for scheduling showing notificaitons.
39
+
40
+ #### The simplest notification call
34
41
 
35
42
  ```jsx
36
- import notification from '@ant/notification'
43
+ import notificationApi from '@synerise/ds-alert'
37
44
 
38
- notification.open({message: 'Message content', duration 4.5})
45
+ notification.open({message: 'Message content'});
39
46
  ```
40
47
 
41
- #### A `synerise-design`-styled notification
48
+ #### Styled notification
42
49
  ```jsx
43
- import Notification from '@ds-alert/Notification'
44
- import notification from '@ant/notification'
50
+ import { Notification, notificationApi} from '@synerise/ds-alert'
45
51
 
46
- notification.open({message: <Notification>'Message content'</Notification>, duration: 4.5})
52
+ notificationApi.open({
53
+ duration: 4.5,
54
+ message: <Notification>Message content</Notification>
55
+ });
47
56
  ```
48
57
 
49
58
  #### Differently positioned notification
@@ -52,14 +61,21 @@ notification.open({message: <Notification>'Message content'</Notification>, dura
52
61
  `getContainer` has to be a `styled-components`-scoped element, this is done in `mountInstance`, see source code for more.
53
62
 
54
63
  ```jsx
55
- import open from '@ds-alert/Notification'
56
-
57
- const [api, contextHolder] = notification.useNotification();
58
- open({message: Message content, duration: 4.5}, api, contextHolder))
64
+ import { Notification, notificationApi, notificationOpen } from '@synerise/ds-alert';
59
65
 
60
- console.log('@synerise/ds-alert notifications get mounted in this container', document.querySelector('.popup-container'))
66
+ const [api, contextHolder] = notificationApi.useNotification();
67
+ notificationOpen({
68
+ message: <Notification>You have new message.</Notification>,
69
+ placement: 'topLeft'
70
+ }, api, contextHolder);
61
71
  ```
62
72
 
73
+ ### Usage recommendations
74
+
75
+ It is recommended to call `notificationOpen` from `React.useEffect`.
76
+ Of course you can mount styled `<Notification/>` component by yourself,
77
+ but then you need to manage its rendering lifecycle.
78
+
63
79
  ## Demo
64
80
 
65
81
  <iframe src="/storybook-static/iframe.html?id=components-alert--default"></iframe>
@@ -2,6 +2,9 @@ import * as React from 'react';
2
2
  import { NotificationInstance } from 'antd/lib/notification';
3
3
  import type { ArgsProps, NotificationApi } from 'antd/es/notification';
4
4
  import 'antd/lib/notification/style/index.less';
5
+ /**
6
+ * Typings for using better autocompletion for defining an argument for `notificationOpen`'s message property.
7
+ */
5
8
  export declare type NotificationProps = {
6
9
  /** content of the notification */
7
10
  children?: JSX.Element | React.ReactNode | React.ReactNode[];
@@ -14,11 +17,15 @@ export declare type NotificationProps = {
14
17
  /** close icon class */
15
18
  closeIconClassName?: string;
16
19
  /** where to position notification, `"{top,bottom}{Left,Right}" | "bottom"` */
17
- placement: ArgsProps['placement'] | 'bottom';
20
+ placement?: ArgsProps['placement'] | 'bottom';
18
21
  } & Partial<Omit<ArgsProps, 'placement'>>;
19
22
  declare type NotificationApiHook = ReturnType<NotificationApi['useNotification']>;
20
23
  declare type ApiHook = NotificationApiHook[0];
21
24
  declare type ContextHolder = NotificationApiHook[1];
25
+ /**
26
+ * Component with the content of the notification.
27
+ * Note that in order to show notification you need to use `notificationOpen`
28
+ */
22
29
  export declare function Notification({ buttonText, children, onButtonClick, onClose, icon, closeIconClassName, }: NotificationProps): JSX.Element;
23
30
  /**
24
31
  * creates a div, mounts it in getContainer and returns reference to it.
@@ -31,6 +38,28 @@ export declare function Notification({ buttonText, children, onButtonClick, onCl
31
38
  export declare function mountInstance(contextHolder?: ContextHolder, { getContainer, className }?: {
32
39
  getContainer?: (() => HTMLElement) | undefined;
33
40
  className?: string | undefined;
34
- }): [HTMLElement | null, Function];
35
- export declare function notificationOpen({ type, className, message, icon, onClick, onClose, closeIconClassName, placement, ...props }: NotificationProps, notificationApi?: ApiHook, contextHolder?: ContextHolder): void;
41
+ }): [Promise<HTMLElement>, HTMLElement, () => void];
42
+ /**
43
+ * Function for showing new notifications.
44
+ * It requires proper context to be injected (see `notificationApi.useNotification`)
45
+ * and `message` prop in its first argument.
46
+ * Below you will find an example usage.
47
+ * Please remember that it is on you to provide contextHolder in the right place.
48
+ * ```
49
+ * import { notificationApi, Notification, notificationOpen } from '@synerise/ds-alert';
50
+ * const [api, contextHolder] = notificationApi.useNotification();
51
+ *
52
+ * function App() {
53
+ * return (<div id="app">
54
+ * {contextHolder}
55
+ * <button onClick={() => notificationOpen({
56
+ * message: <Notification>You have been notified.</Notification>
57
+ * })}>
58
+ * Show notification
59
+ * </button>);
60
+ *
61
+ * ReactDOM.render(<App/>, document.querySelector('#app'));
62
+ * ```
63
+ */
64
+ export declare function notificationOpen({ type, className, message, icon, onClick, onClose, closeIconClassName, placement, ...props }: NotificationProps, notificationApi?: ApiHook, contextHolder?: ContextHolder): Promise<void>;
36
65
  export default Notification;
@@ -8,6 +8,10 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
8
8
 
9
9
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
10
10
 
11
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
12
+
13
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
14
+
11
15
  import * as React from 'react';
12
16
  import * as ReactDOM from 'react-dom';
13
17
  import { notification } from 'antd';
@@ -15,6 +19,14 @@ import "antd/lib/notification/style/index.css";
15
19
  import Button from '@synerise/ds-button';
16
20
  import Icon, { UserAddM, CloseM } from '@synerise/ds-icon';
17
21
  import * as S from './Notification.styles';
22
+ /**
23
+ * Typings for using better autocompletion for defining an argument for `notificationOpen`'s message property.
24
+ */
25
+
26
+ /**
27
+ * Component with the content of the notification.
28
+ * Note that in order to show notification you need to use `notificationOpen`
29
+ */
18
30
  export function Notification(_ref) {
19
31
  var buttonText = _ref.buttonText,
20
32
  _ref$children = _ref.children,
@@ -62,73 +74,112 @@ export function mountInstance(contextHolder, _temp) {
62
74
  var cont = getContainer();
63
75
  cont.appendChild(element);
64
76
  var jsxEl = /*#__PURE__*/React.createElement(S.NotificationsWrapper, null, contextHolder);
65
- ReactDOM.render(jsxEl, element);
77
+ var renderPromsie = new Promise(function (resolve) {
78
+ ReactDOM.render(jsxEl, element, function () {
79
+ return resolve(element);
80
+ });
81
+ });
66
82
 
67
83
  var cleanUpFunction = function cleanUpFunction() {
68
84
  cont.removeChild(element);
69
85
  };
70
86
 
71
- return [element, cleanUpFunction];
87
+ return [renderPromsie, element, cleanUpFunction];
72
88
  }
73
- export function notificationOpen(_ref3, notificationApi, contextHolder) {
74
- var _ref3$type = _ref3.type,
75
- type = _ref3$type === void 0 ? 'info' : _ref3$type,
76
- _ref3$className = _ref3.className,
77
- className = _ref3$className === void 0 ? 'popup-container' : _ref3$className,
78
- message = _ref3.message,
79
- icon = _ref3.icon,
80
- onClick = _ref3.onClick,
81
- onClose = _ref3.onClose,
82
- _ref3$closeIconClassN = _ref3.closeIconClassName,
83
- closeIconClassName = _ref3$closeIconClassN === void 0 ? 'ds-close-icon' : _ref3$closeIconClassN,
84
- _ref3$placement = _ref3.placement,
85
- placement = _ref3$placement === void 0 ? 'bottom' : _ref3$placement,
86
- props = _objectWithoutPropertiesLoose(_ref3, _excluded);
87
-
88
- var api = notificationApi || notification; // TODO: check if context is actually available
89
-
90
- var el = document.body.querySelector("." + className);
91
-
92
- if (!el) {
93
- var _mountInstance = mountInstance(contextHolder, {
94
- className: className
95
- });
96
-
97
- el = _mountInstance[0];
98
- }
99
-
100
- var getContainer = function getContainer() {
101
- var _el;
102
-
103
- return (_el = el) == null ? void 0 : _el.querySelector('div>div,.NotificationsBottomPlacementWrapper>.NotificationsWrapper');
104
- };
105
- /** a workaround for handling close clicks,
106
- * since there's no way for injecting other element triggering onClose listener.
107
- * It is set as a listener for all the clicks
108
- * and fires onClose when close-icon was clicked */
109
-
110
-
111
- var maybeCloseClick = function maybeCloseClick(ev) {
112
- var _ev$currentTarget;
113
-
114
- var isClickedElementChildOfCloseIcon = ev.target.closest("." + closeIconClassName);
115
- var isThisCloseIcon = ev == null ? void 0 : (_ev$currentTarget = ev.currentTarget) == null ? void 0 : _ev$currentTarget.classList.contains("" + closeIconClassName);
116
-
117
- if (isClickedElementChildOfCloseIcon || isThisCloseIcon) {
118
- return onClose && onClose();
119
- }
89
+ /**
90
+ * Function for showing new notifications.
91
+ * It requires proper context to be injected (see `notificationApi.useNotification`)
92
+ * and `message` prop in its first argument.
93
+ * Below you will find an example usage.
94
+ * Please remember that it is on you to provide contextHolder in the right place.
95
+ * ```
96
+ * import { notificationApi, Notification, notificationOpen } from '@synerise/ds-alert';
97
+ * const [api, contextHolder] = notificationApi.useNotification();
98
+ *
99
+ * function App() {
100
+ * return (<div id="app">
101
+ * {contextHolder}
102
+ * <button onClick={() => notificationOpen({
103
+ * message: <Notification>You have been notified.</Notification>
104
+ * })}>
105
+ * Show notification
106
+ * </button>);
107
+ *
108
+ * ReactDOM.render(<App/>, document.querySelector('#app'));
109
+ * ```
110
+ */
120
111
 
121
- return onClick && onClick();
122
- };
112
+ export function notificationOpen(_x, _x2, _x3) {
113
+ return _notificationOpen.apply(this, arguments);
114
+ }
123
115
 
124
- return api.open(_objectSpread({
125
- message: message,
126
- type: type,
127
- placement: placement,
128
- getContainer: getContainer,
129
- icon: icon,
130
- onClick: maybeCloseClick,
131
- bottom: 16
132
- }, props));
116
+ function _notificationOpen() {
117
+ _notificationOpen = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(_ref3, notificationApi, contextHolder) {
118
+ var _ref3$type, type, _ref3$className, className, message, icon, onClick, onClose, _ref3$closeIconClassN, closeIconClassName, _ref3$placement, placement, props, api, el, containerPromise, _mountInstance, getContainer, maybeCloseClick;
119
+
120
+ return regeneratorRuntime.wrap(function _callee$(_context) {
121
+ while (1) {
122
+ switch (_context.prev = _context.next) {
123
+ case 0:
124
+ _ref3$type = _ref3.type, type = _ref3$type === void 0 ? 'info' : _ref3$type, _ref3$className = _ref3.className, className = _ref3$className === void 0 ? 'popup-container' : _ref3$className, message = _ref3.message, icon = _ref3.icon, onClick = _ref3.onClick, onClose = _ref3.onClose, _ref3$closeIconClassN = _ref3.closeIconClassName, closeIconClassName = _ref3$closeIconClassN === void 0 ? 'ds-close-icon' : _ref3$closeIconClassN, _ref3$placement = _ref3.placement, placement = _ref3$placement === void 0 ? 'bottom' : _ref3$placement, props = _objectWithoutPropertiesLoose(_ref3, _excluded);
125
+ api = notificationApi || notification; // TODO: check if context is actually available
126
+
127
+ el = document.body.querySelector("." + className);
128
+
129
+ if (!el) {
130
+ _mountInstance = mountInstance(contextHolder, {
131
+ className: className
132
+ });
133
+ containerPromise = _mountInstance[0];
134
+ el = _mountInstance[1];
135
+ }
136
+
137
+ _context.next = 6;
138
+ return containerPromise;
139
+
140
+ case 6:
141
+ getContainer = function getContainer() {
142
+ var _el;
143
+
144
+ return (_el = el) == null ? void 0 : _el.querySelector('div>div,.NotificationsBottomPlacementWrapper>.NotificationsWrapper');
145
+ };
146
+ /** a workaround for handling close clicks,
147
+ * since there's no way for injecting other element triggering onClose listener.
148
+ * It is set as a listener for all the clicks
149
+ * and fires onClose when close-icon was clicked */
150
+
151
+
152
+ maybeCloseClick = function maybeCloseClick(ev) {
153
+ var _ev$currentTarget;
154
+
155
+ var isClickedElementChildOfCloseIcon = ev.target.closest("." + closeIconClassName);
156
+ var isThisCloseIcon = ev == null ? void 0 : (_ev$currentTarget = ev.currentTarget) == null ? void 0 : _ev$currentTarget.classList.contains("" + closeIconClassName);
157
+
158
+ if (isClickedElementChildOfCloseIcon || isThisCloseIcon) {
159
+ return onClose && onClose();
160
+ }
161
+
162
+ return onClick && onClick();
163
+ };
164
+
165
+ return _context.abrupt("return", api.open(_objectSpread({
166
+ message: message,
167
+ type: type,
168
+ placement: placement,
169
+ getContainer: getContainer,
170
+ icon: icon,
171
+ onClick: maybeCloseClick,
172
+ bottom: 16
173
+ }, props)));
174
+
175
+ case 9:
176
+ case "end":
177
+ return _context.stop();
178
+ }
179
+ }
180
+ }, _callee);
181
+ }));
182
+ return _notificationOpen.apply(this, arguments);
133
183
  }
184
+
134
185
  export default Notification;
@@ -19,7 +19,7 @@ export var TextLabel = styled.div.withConfig({
19
19
  export var NotificationsWrapper = styled.div.withConfig({
20
20
  displayName: "Notificationstyles__NotificationsWrapper",
21
21
  componentId: "sc-1ke52b0-3"
22
- })(["& .ant-notification-bottom .ant-notification-hook-holder{margin:0;&:not(:first-child){margin-top:8px;}}& .ant-notification.ant-notification-bottom{right:0;left:0;margin:0 auto;width:588px;bottom:8px;}& .ant-notification-hook-holder{background-color:transparent;box-shadow:none;width:588px;}& .ant-notification-notice{padding:0;background-color:transparent;margin:unset;}& .ant-notification-notice{background-color:transparent;width:588px;border-radius:3px;box-shadow:0 16px 32px 0 ", "1a,0 8px 16px 0 ", "1a;}.ant-notification-notice-icon{display:none;}.ant-notification-notice-with-icon{background-color:transparent;}.ant-notification-notice-close{display:none;}& .ant-notification-notice-message,& .ant-notification-notice-closable .ant-notification-notice-message{padding-right:0;}& .ant-notification-notice-message,& .ant-notification-notice-with-icon .ant-notification-notice-message{margin-left:0;margin-bottom:0;}}"], function (props) {
22
+ })(["& .ant-notification-bottom .ant-notification-hook-holder{margin:0;&:not(:first-child){margin-top:8px;}}& .ant-notification.ant-notification-bottom{right:0;left:0;margin:0 auto;width:588px;bottom:8px;}& .ant-notification-hook-holder{background-color:transparent;box-shadow:none;width:588px;}& .ant-notification-notice{padding:0;background-color:transparent;margin:unset;}& .ant-notification-notice{background-color:transparent;width:588px;border-radius:6px;box-shadow:0 16px 32px 0 ", "1a,0 8px 16px 0 ", "1a;}.ant-notification-notice-icon{display:none;}.ant-notification-notice-with-icon{background-color:transparent;}.ant-notification-notice-close{display:none;}& .ant-notification-notice-message,& .ant-notification-notice-closable .ant-notification-notice-message{padding-right:0;}& .ant-notification-notice-message,& .ant-notification-notice-with-icon .ant-notification-notice-message{margin-left:0;margin-bottom:0;}}"], function (props) {
23
23
  var _palette2;
24
24
 
25
25
  return (_palette2 = ((props == null ? void 0 : props.theme) || theme).palette) == null ? void 0 : _palette2['grey-900'];
@@ -24,4 +24,6 @@ describe('notification', function () {
24
24
  it.todo('sending notification with another placement handles it correctly');
25
25
  it.todo('getContainer should always point at NotificationsWrapper element');
26
26
  it.todo('.ant-notification-bottom should be properly styled even if e.g. .ant-notification-topLeft was added first (`.ant-notification{, }.ant-notification-bottom`)');
27
+ it.todo('notificationOpen works with useEffect');
28
+ it.todo('if running from useEffect handle it so works, do not force used to rely on useLayoutEffect');
27
29
  });
package/dist/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  export { default } from './Alert';
2
2
  export * as S from './Notification/Notification.styles';
3
- export { default as Notification } from './Notification/Notification';
3
+ /**
4
+ * notificationApi is required for properly handling injecting ContextApi for styling and locales.
5
+ * It's a proxy to `antd`'s `notification` module.
6
+ */
7
+ export declare const notificationsApi: import("antd/lib/notification").NotificationApi;
4
8
  export type { NotificationProps } from './Notification/Notification';
9
+ export { default as Notification } from './Notification/Notification';
5
10
  export { notificationOpen } from './Notification/Notification';
package/dist/index.js CHANGED
@@ -1,5 +1,12 @@
1
+ import { notification } from 'antd';
1
2
  export { default } from './Alert';
2
3
  import * as _S from './Notification/Notification.styles';
3
4
  export { _S as S };
5
+ /**
6
+ * notificationApi is required for properly handling injecting ContextApi for styling and locales.
7
+ * It's a proxy to `antd`'s `notification` module.
8
+ */
9
+
10
+ export var notificationsApi = notification;
4
11
  export { default as Notification } from './Notification/Notification';
5
12
  export { notificationOpen } from './Notification/Notification';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-alert",
3
- "version": "0.6.1",
3
+ "version": "0.7.2",
4
4
  "description": "Alert UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "Synerise/synerise-design",
@@ -35,7 +35,7 @@
35
35
  "@synerise/ds-button": "^0.17.2",
36
36
  "@synerise/ds-icon": "^0.49.0",
37
37
  "@synerise/ds-typography": "^0.12.2",
38
- "@synerise/ds-unordered-list": "^0.2.10",
38
+ "@synerise/ds-unordered-list": "^0.2.11",
39
39
  "animate.css": "^4.1.1",
40
40
  "react-animate-height": "^2.0.23",
41
41
  "react-mount-animation": "0.0.9"
@@ -47,5 +47,5 @@
47
47
  "devDependencies": {
48
48
  "@synerise/ds-utils": "^0.19.0"
49
49
  },
50
- "gitHead": "510d01309981d010c794496292be958796c0b6b6"
50
+ "gitHead": "bf12565ec1e6a4124b0c54cdb61e22eae4401d93"
51
51
  }
@@ -1 +0,0 @@
1
- .ant-image-preview,.ant-modal{pointer-events:none}.ant-image-preview.zoom-appear,.ant-image-preview.zoom-enter,.ant-modal.zoom-appear,.ant-modal.zoom-enter{transform:none;opacity:0;animation-duration:.3s;user-select:none}.ant-image-preview-mask,.ant-modal-mask{position:fixed;top:0;right:0;bottom:0;left:0;z-index:991000;height:100%;background-color:rgba(0,0,0,.2);filter:alpha(opacity=50)}.ant-image-preview-mask-hidden,.ant-modal-mask-hidden{display:none}.ant-image-preview-wrap,.ant-modal-wrap{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto;outline:0;-webkit-overflow-scrolling:touch}.ant-alert{box-sizing:border-box;margin:0;padding:0;color:#6a7580;font-size:13px;font-variant:tabular-nums;line-height:1.38;list-style:none;font-feature-settings:'tnum';position:relative;padding:8px 15px 8px 37px;word-wrap:break-word;border-radius:3px}.ant-alert.ant-alert-no-icon{padding:8px 15px}.ant-alert.ant-alert-no-icon .ant-alert-close-icon{top:10.47px}.ant-alert.ant-alert-closable{padding-right:30px}.ant-alert-icon{position:absolute;top:10.47px;left:16px}.ant-alert-description{display:none;font-size:13px;line-height:21px}.ant-alert-success{background-color:#f4ffe6;border:1px solid #b7f280}.ant-alert-success .ant-alert-icon{color:#54cb0b}.ant-alert-info{background-color:#e6f4ff;border:1px solid #85c0ff}.ant-alert-info .ant-alert-icon{color:#0b68ff}.ant-alert-warning{background-color:#fffce6;border:1px solid #ffe97a}.ant-alert-warning .ant-alert-icon{color:#fab700}.ant-alert-error{background-color:#fff3f0;border:1px solid #ffab9e}.ant-alert-error .ant-alert-icon{color:#f52922}.ant-alert-error .ant-alert-description>pre{margin:0;padding:0}.ant-alert-close-icon{position:absolute;top:10.47px;right:16px;padding:0;overflow:hidden;font-size:11px;line-height:11px;background-color:transparent;border:none;outline:0;cursor:pointer}.ant-alert-close-icon .anticon-close{color:#232936;transition:color .3s}.ant-alert-close-icon .anticon-close:hover{color:rgba(0,0,0,.75)}.ant-alert-close-text{color:#232936;transition:color .3s}.ant-alert-close-text:hover{color:rgba(0,0,0,.75)}.ant-alert-with-description{position:relative;padding:15px 15px 15px 63px;color:#6a7580;line-height:1.38;border-radius:3px}.ant-alert-with-description.ant-alert-no-icon{padding:15px 15px}.ant-alert-with-description .ant-alert-icon{position:absolute;top:15px;left:24px;font-size:24px}.ant-alert-with-description .ant-alert-close-icon{position:absolute;top:16px;right:16px;font-size:13px;cursor:pointer}.ant-alert-with-description .ant-alert-message{display:block;margin-bottom:4px;color:#384350;font-size:13px}.ant-alert-message{color:#384350}.ant-alert-with-description .ant-alert-description{display:block}.ant-alert.ant-alert-motion-leave{overflow:hidden;opacity:1;transition:max-height .3s cubic-bezier(.78,.14,.15,.86),opacity .3s cubic-bezier(.78,.14,.15,.86),padding-top .3s cubic-bezier(.78,.14,.15,.86),padding-bottom .3s cubic-bezier(.78,.14,.15,.86),margin-bottom .3s cubic-bezier(.78,.14,.15,.86)}.ant-alert.ant-alert-motion-leave-active{max-height:0;margin-bottom:0!important;padding-top:0;padding-bottom:0;opacity:0}.ant-alert-banner{margin-bottom:0;border:0;border-radius:0}.ant-alert.ant-alert-rtl{padding:8px 37px 8px 15px;direction:rtl}.ant-alert-rtl.ant-alert.ant-alert-no-icon{padding:8px 15px}.ant-alert.ant-alert-rtl.ant-alert.ant-alert-closable{padding-right:37px;padding-left:30px}.ant-alert.ant-alert-rtl.ant-alert.ant-alert-no-icon.ant-alert-closable{padding-right:15px;padding-left:30px}.ant-alert-rtl .ant-alert-icon{right:16px;left:auto}.ant-alert-rtl .ant-alert-close-icon{right:auto;left:16px}.ant-alert.ant-alert-rtl.ant-alert-with-description,.ant-alert.ant-alert-rtl.ant-alert-with-description.ant-alert-closable{padding:15px 63px 15px 15px}.ant-alert.ant-alert-rtl.ant-alert-with-description.ant-alert-no-icon{padding:15px}.ant-alert-rtl.ant-alert-with-description .ant-alert-icon{right:24px;left:auto}.ant-alert-rtl.ant-alert-with-description .ant-alert-close-icon{right:auto;left:16px}.ant-alert{box-sizing:border-box;margin:0;padding:0;color:#6a7580;font-size:13px;font-variant:tabular-nums;line-height:1.38;list-style:none;font-feature-settings:'tnum';position:relative;padding:13px 24px;word-wrap:break-word;border-radius:3px;max-width:792px;width:100%;display:flex;flex-display:row;align-items:flex-start;justify-content:flex-start;border:0}.ant-alert.ant-alert-no-icon{padding:13px 24px}.ant-alert-icon{position:relative;margin-right:12px;top:0;left:0}.ant-alert-description{display:none;font-size:13px;line-height:22px}.ant-alert-success{background-color:#f9ffed;box-shadow:0 0 0 1px #54cb0b;color:#399903}.ant-alert-success .ant-alert-icon svg{color:#399903;fill:#399903}.ant-alert-info{background-color:#f9fafb;box-shadow:0 0 0 1px #6a7580;color:#6a7580}.ant-alert-info .ant-alert-icon svg{color:#6a7580;fill:#6a7580}.ant-alert-warning{background-color:#fffcf0;box-shadow:0 0 0 1px #fab700;color:#eda600}.ant-alert-warning .ant-alert-icon svg{color:#eda600;fill:#eda600}.ant-alert-error{background-color:#fff6f4;box-shadow:0 0 0 1px #f52922;color:#f52922}.ant-alert-error .ant-alert-icon svg{color:#f52922;fill:#f52922}.ant-alert-error .ant-alert-description>pre{margin:0;padding:0}.ant-alert-close-icon{position:absolute;top:8px;right:16px;padding:0;overflow:hidden;font-size:11px;line-height:22px;background-color:transparent;border:none;outline:0;cursor:pointer}.ant-alert-close-icon .anticon-close{color:#232936;transition:color .3s}.ant-alert-close-icon .anticon-close:hover{color:rgba(0,0,0,.75)}.ant-alert-close-text{color:#232936;transition:color .3s}.ant-alert-close-text:hover{color:rgba(0,0,0,.75)}.ant-alert-message{color:inherit}.ant-alert-with-description .ant-alert-description{display:block}.ant-alert.ant-alert-closing{height:0!important;margin:0;padding-top:0;padding-bottom:0;transform-origin:50% 0;transition:all .3s cubic-bezier(.78,.14,.15,.86)}.ant-alert-slide-up-leave{animation:antAlertSlideUpOut .3s cubic-bezier(.78,.14,.15,.86);animation-fill-mode:both}.ant-alert-banner{margin-bottom:0;border:0;border-radius:0}@keyframes antAlertSlideUpIn{0%{transform:scaleY(0);transform-origin:0 0;opacity:0}100%{transform:scaleY(1);transform-origin:0 0;opacity:1}}@keyframes antAlertSlideUpOut{0%{transform:scaleY(1);transform-origin:0 0;opacity:1}100%{transform:scaleY(0);transform-origin:0 0;opacity:0}}