@alfalab/core-components-notification-manager 7.0.4 → 7.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/component.d.ts +3 -35
- package/component.js +3 -13
- package/component.js.map +1 -1
- package/components/notification/component.d.ts +5 -4
- package/components/notification/component.js +16 -4
- package/components/notification/component.js.map +1 -1
- package/components/notification/index.css +18 -0
- package/components/notification/index.module.css.js +8 -0
- package/components/notification/index.module.css.js.map +1 -0
- package/cssm/component.d.ts +3 -35
- package/cssm/component.js +3 -13
- package/cssm/component.js.map +1 -1
- package/cssm/components/notification/component.d.ts +5 -4
- package/cssm/components/notification/component.js +17 -4
- package/cssm/components/notification/component.js.map +1 -1
- package/cssm/components/notification/index.module.css +18 -0
- package/cssm/index.module.css +0 -17
- package/esm/component.d.ts +3 -35
- package/esm/component.js +5 -15
- package/esm/component.js.map +1 -1
- package/esm/components/notification/component.d.ts +5 -4
- package/esm/components/notification/component.js +16 -5
- package/esm/components/notification/component.js.map +1 -1
- package/esm/components/notification/index.css +18 -0
- package/esm/components/notification/index.module.css.js +6 -0
- package/esm/components/notification/index.module.css.js.map +1 -0
- package/esm/index.css +6 -23
- package/esm/index.module.css.js +1 -1
- package/esm/index.module.css.js.map +1 -1
- package/index.css +6 -23
- package/index.module.css.js +1 -1
- package/index.module.css.js.map +1 -1
- package/modern/component.d.ts +3 -35
- package/modern/component.js +11 -23
- package/modern/component.js.map +1 -1
- package/modern/components/notification/component.d.ts +5 -4
- package/modern/components/notification/component.js +16 -5
- package/modern/components/notification/component.js.map +1 -1
- package/modern/components/notification/index.css +18 -0
- package/modern/components/notification/index.module.css.js +6 -0
- package/modern/components/notification/index.module.css.js.map +1 -0
- package/modern/index.css +6 -23
- package/modern/index.module.css.js +1 -1
- package/modern/index.module.css.js.map +1 -1
- package/moderncssm/component.d.ts +3 -35
- package/moderncssm/component.js +11 -23
- package/moderncssm/component.js.map +1 -1
- package/moderncssm/components/notification/component.d.ts +5 -4
- package/moderncssm/components/notification/component.js +16 -5
- package/moderncssm/components/notification/component.js.map +1 -1
- package/moderncssm/components/notification/index.module.css +22 -0
- package/moderncssm/index.module.css +0 -19
- package/package.json +2 -2
- package/src/component.tsx +36 -58
- package/src/components/notification/{component.ts → component.tsx} +45 -9
- package/src/components/notification/index.module.css +22 -0
- package/src/index.module.css +0 -19
package/moderncssm/component.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, { forwardRef
|
|
2
|
-
import { TransitionGroup
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { TransitionGroup } from 'react-transition-group';
|
|
3
3
|
import cn from 'classnames';
|
|
4
4
|
import { Portal } from '@alfalab/core-components-portal/moderncssm';
|
|
5
5
|
import { Stack } from '@alfalab/core-components-stack/moderncssm';
|
|
@@ -7,27 +7,15 @@ import { stackingOrder } from '@alfalab/core-components-stack-context/moderncssm
|
|
|
7
7
|
import { Notification } from './components/notification/component.js';
|
|
8
8
|
import styles from './index.module.css';
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const nodeRef = useRef(null);
|
|
20
|
-
return (React.createElement(Stack, { value: zIndex }, (computedZIndex) => (React.createElement(Portal, { getPortalContainer: container },
|
|
21
|
-
React.createElement("div", { className: cn(styles.component, className), ref: ref, "data-test-id": dataTestId, style: {
|
|
22
|
-
zIndex: computedZIndex,
|
|
23
|
-
top: offset,
|
|
24
|
-
...style,
|
|
25
|
-
}, ...restProps },
|
|
26
|
-
React.createElement(TransitionGroup, null, notifications.map((element, index) => (React.createElement(CSSTransition, { key: element.props.id, timeout: TIMEOUT, classNames: CSS_TRANSITION_CLASS_NAMES, unmountOnExit: true, nodeRef: nodeRef },
|
|
27
|
-
React.createElement(Notification, { containerRef: nodeRef, element: element, className: cn(styles.notification, {
|
|
28
|
-
[styles.withoutMargin]: offset && index === 0,
|
|
29
|
-
}), onRemoveNotification: onRemoveNotification }))))))))));
|
|
30
|
-
});
|
|
10
|
+
const NotificationManager = forwardRef(({ notifications, className, dataTestId, zIndex = stackingOrder.TOAST, style = {}, offset, onRemoveNotification, container, ...restProps }, ref) => (React.createElement(Stack, { value: zIndex }, (computedZIndex) => (React.createElement(Portal, { getPortalContainer: container },
|
|
11
|
+
React.createElement("div", { className: cn(styles.component, className), ref: ref, "data-test-id": dataTestId, style: {
|
|
12
|
+
zIndex: computedZIndex,
|
|
13
|
+
top: offset,
|
|
14
|
+
...style,
|
|
15
|
+
}, ...restProps },
|
|
16
|
+
React.createElement(TransitionGroup, null, notifications.map((element, index) => (React.createElement(Notification, { key: element.props.id, element: element, onRemoveNotification: onRemoveNotification, className: cn(styles.notification, {
|
|
17
|
+
[styles.withoutMargin]: offset && index === 0,
|
|
18
|
+
}) }))))))))));
|
|
31
19
|
NotificationManager.displayName = 'NotificationManager';
|
|
32
20
|
|
|
33
21
|
export { NotificationManager };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sources":["../src/component.tsx"],"sourcesContent":["import React, { forwardRef, type HTMLAttributes
|
|
1
|
+
{"version":3,"file":"component.js","sources":["../src/component.tsx"],"sourcesContent":["import React, { forwardRef, type HTMLAttributes } from 'react';\nimport { TransitionGroup } from 'react-transition-group';\nimport cn from 'classnames';\n\nimport { Portal, type PortalProps } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\n\nimport { Notification, type NotificationElement } from './components';\n\nimport styles from './index.module.css';\n\nexport interface NotificationManagerProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Массив нотификаций.\n * В нотификации обязательно передавайте id.\n */\n notifications: NotificationElement[];\n\n /**\n * Дополнительный класс (native prop)\n */\n className?: string;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Удаление нотификации\n */\n onRemoveNotification: (id: string) => void;\n\n /**\n * Нода, компонент или функция возвращающая их\n *\n * Контейнер к которому будут добавляться порталы\n */\n container?: PortalProps['getPortalContainer'];\n}\n\nexport const NotificationManager = forwardRef<HTMLDivElement, NotificationManagerProps>(\n (\n {\n notifications,\n className,\n dataTestId,\n zIndex = stackingOrder.TOAST,\n style = {},\n offset,\n onRemoveNotification,\n container,\n ...restProps\n },\n ref,\n ) => (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Portal getPortalContainer={container}>\n <div\n className={cn(styles.component, className)}\n ref={ref}\n data-test-id={dataTestId}\n style={{\n zIndex: computedZIndex,\n top: offset,\n ...style,\n }}\n {...restProps}\n >\n <TransitionGroup>\n {notifications.map((element, index) => (\n <Notification\n key={element.props.id}\n element={element}\n onRemoveNotification={onRemoveNotification}\n className={cn(styles.notification, {\n [styles.withoutMargin]: offset && index === 0,\n })}\n />\n ))}\n </TransitionGroup>\n </div>\n </Portal>\n )}\n </Stack>\n ),\n);\n\nNotificationManager.displayName = 'NotificationManager';\n"],"names":[],"mappings":";;;;;;;;;AAoDa,MAAA,mBAAmB,GAAG,UAAU,CACzC,CACI,EACI,aAAa,EACb,SAAS,EACT,UAAU,EACV,MAAM,GAAG,aAAa,CAAC,KAAK,EAC5B,KAAK,GAAG,EAAE,EACV,MAAM,EACN,oBAAoB,EACpB,SAAS,EACT,GAAG,SAAS,EACf,EACD,GAAG,MAEH,KAAC,CAAA,aAAA,CAAA,KAAK,EAAC,EAAA,KAAK,EAAE,MAAM,EACf,EAAA,CAAC,cAAc,MACZ,KAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EAAC,kBAAkB,EAAE,SAAS,EAAA;AACjC,IAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACI,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,EAC1C,GAAG,EAAE,GAAG,kBACM,UAAU,EACxB,KAAK,EAAE;AACH,YAAA,MAAM,EAAE,cAAc;AACtB,YAAA,GAAG,EAAE,MAAM;AACX,YAAA,GAAG,KAAK;AACX,SAAA,EAAA,GACG,SAAS,EAAA;AAEb,QAAA,KAAA,CAAA,aAAA,CAAC,eAAe,EACX,IAAA,EAAA,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,MAC9B,oBAAC,YAAY,EAAA,EACT,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,EACrB,OAAO,EAAE,OAAO,EAChB,oBAAoB,EAAE,oBAAoB,EAC1C,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE;gBAC/B,CAAC,MAAM,CAAC,aAAa,GAAG,MAAM,IAAI,KAAK,KAAK,CAAC;aAChD,CAAC,EAAA,CACJ,CACL,CAAC,CACY,CAChB,CACD,CACZ,CACG,CACX;AAGL,mBAAmB,CAAC,WAAW,GAAG,qBAAqB;;;;"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { type FC, type ReactElement
|
|
1
|
+
import { type FC, type ReactElement } from 'react';
|
|
2
|
+
import { type CSSTransitionProps } from 'react-transition-group/CSSTransition';
|
|
2
3
|
import { type NotificationProps as CoreNotificationProps } from '@alfalab/core-components-notification/moderncssm';
|
|
3
4
|
export type NotificationElement = ReactElement<CoreNotificationProps & {
|
|
4
5
|
id: string;
|
|
5
6
|
}>;
|
|
6
|
-
type
|
|
7
|
+
type NotificationTransitionProps = Partial<Pick<CSSTransitionProps<HTMLDivElement>, 'in' | 'onExited' | 'appear' | 'enter' | 'exit'>>;
|
|
8
|
+
interface NotificationProps extends NotificationTransitionProps {
|
|
7
9
|
element: NotificationElement;
|
|
8
10
|
className: string;
|
|
9
11
|
onRemoveNotification: (id: string) => void;
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
+
}
|
|
12
13
|
export declare const Notification: FC<NotificationProps>;
|
|
13
14
|
export {};
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
import { useCallback, useMemo, cloneElement } from 'react';
|
|
1
|
+
import React, { useRef, useCallback, useMemo, cloneElement } from 'react';
|
|
2
|
+
import { CSSTransition } from 'react-transition-group';
|
|
2
3
|
import cn from 'classnames';
|
|
4
|
+
import styles from './index.module.css';
|
|
3
5
|
|
|
4
|
-
const
|
|
6
|
+
const TIMEOUT = {
|
|
7
|
+
exit: 0,
|
|
8
|
+
enter: 400,
|
|
9
|
+
};
|
|
10
|
+
const CSS_TRANSITION_CLASS_NAMES = {
|
|
11
|
+
enter: styles.enter,
|
|
12
|
+
enterActive: styles.enterActive,
|
|
13
|
+
};
|
|
14
|
+
const Notification = ({ in: inProp, onExited, appear, enter, exit, element, className, onRemoveNotification, }) => {
|
|
15
|
+
const nodeRef = useRef(null);
|
|
5
16
|
const { onClose, onCloseTimeout } = element.props;
|
|
6
17
|
const handleClose = useCallback(() => {
|
|
7
18
|
if (onClose) {
|
|
@@ -23,11 +34,11 @@ const Notification = ({ element, className, onRemoveNotification, containerRef,
|
|
|
23
34
|
offset: 0,
|
|
24
35
|
onClose: handleClose,
|
|
25
36
|
onCloseTimeout: handleCloseTimeout,
|
|
26
|
-
containerRef,
|
|
37
|
+
containerRef: nodeRef,
|
|
27
38
|
}),
|
|
28
39
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
29
|
-
[element, handleClose, handleCloseTimeout,
|
|
30
|
-
return cloneElement(element, notificationProps);
|
|
40
|
+
[element, handleClose, handleCloseTimeout, className]);
|
|
41
|
+
return (React.createElement(CSSTransition, { in: inProp, onExited: onExited, appear: appear, enter: enter, exit: exit, timeout: TIMEOUT, classNames: CSS_TRANSITION_CLASS_NAMES, unmountOnExit: true, nodeRef: nodeRef }, cloneElement(element, notificationProps)));
|
|
31
42
|
};
|
|
32
43
|
|
|
33
44
|
export { Notification };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sources":["../../../src/components/notification/component.
|
|
1
|
+
{"version":3,"file":"component.js","sources":["../../../src/components/notification/component.tsx"],"sourcesContent":["import React, {\n cloneElement,\n type FC,\n type ReactElement,\n useCallback,\n useMemo,\n useRef,\n} from 'react';\nimport { CSSTransition } from 'react-transition-group';\nimport { type CSSTransitionProps } from 'react-transition-group/CSSTransition';\nimport cn from 'classnames';\n\nimport { type NotificationProps as CoreNotificationProps } from '@alfalab/core-components-notification';\n\nimport styles from './index.module.css';\n\nexport type NotificationElement = ReactElement<CoreNotificationProps & { id: string }>;\n\nconst TIMEOUT = {\n exit: 0,\n enter: 400,\n};\n\nconst CSS_TRANSITION_CLASS_NAMES = {\n enter: styles.enter,\n enterActive: styles.enterActive,\n};\n\ntype NotificationTransitionProps = Partial<\n Pick<CSSTransitionProps<HTMLDivElement>, 'in' | 'onExited' | 'appear' | 'enter' | 'exit'>\n>;\n\ninterface NotificationProps extends NotificationTransitionProps {\n element: NotificationElement;\n className: string;\n onRemoveNotification: (id: string) => void;\n}\n\nexport const Notification: FC<NotificationProps> = ({\n in: inProp,\n onExited,\n appear,\n enter,\n exit,\n element,\n className,\n onRemoveNotification,\n}) => {\n const nodeRef = useRef<HTMLDivElement>(null);\n const { onClose, onCloseTimeout } = element.props;\n\n const handleClose = useCallback(() => {\n if (onClose) {\n onClose();\n }\n\n onRemoveNotification(element.props.id);\n }, [onClose, onRemoveNotification, element.props.id]);\n\n const handleCloseTimeout = useCallback(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n\n onRemoveNotification(element.props.id);\n }, [element.props.id, onCloseTimeout, onRemoveNotification]);\n\n const notificationProps = useMemo<CoreNotificationProps>(\n () => ({\n ...element.props,\n visible: true,\n className: cn(className, element.props.className),\n usePortal: false,\n offset: 0,\n onClose: handleClose,\n onCloseTimeout: handleCloseTimeout,\n containerRef: nodeRef,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [element, handleClose, handleCloseTimeout, className],\n );\n\n return (\n <CSSTransition<HTMLDivElement>\n in={inProp}\n onExited={onExited}\n appear={appear}\n enter={enter}\n exit={exit}\n timeout={TIMEOUT}\n classNames={CSS_TRANSITION_CLASS_NAMES}\n unmountOnExit={true}\n nodeRef={nodeRef}\n >\n {cloneElement(element, notificationProps)}\n </CSSTransition>\n );\n};\n"],"names":[],"mappings":";;;;;AAkBA,MAAM,OAAO,GAAG;AACZ,IAAA,IAAI,EAAE,CAAC;AACP,IAAA,KAAK,EAAE,GAAG;CACb;AAED,MAAM,0BAA0B,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;IACnB,WAAW,EAAE,MAAM,CAAC,WAAW;CAClC;AAYY,MAAA,YAAY,GAA0B,CAAC,EAChD,EAAE,EAAE,MAAM,EACV,QAAQ,EACR,MAAM,EACN,KAAK,EACL,IAAI,EACJ,OAAO,EACP,SAAS,EACT,oBAAoB,GACvB,KAAI;AACD,IAAA,MAAM,OAAO,GAAG,MAAM,CAAiB,IAAI,CAAC;IAC5C,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,KAAK;AAEjD,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,MAAK;QACjC,IAAI,OAAO,EAAE;AACT,YAAA,OAAO,EAAE;;AAGb,QAAA,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;AAC1C,KAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAErD,IAAA,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAK;QACxC,IAAI,cAAc,EAAE;AAChB,YAAA,cAAc,EAAE;;AAGpB,QAAA,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;AAC1C,KAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,EAAE,oBAAoB,CAAC,CAAC;AAE5D,IAAA,MAAM,iBAAiB,GAAG,OAAO,CAC7B,OAAO;QACH,GAAG,OAAO,CAAC,KAAK;AAChB,QAAA,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;AACjD,QAAA,SAAS,EAAE,KAAK;AAChB,QAAA,MAAM,EAAE,CAAC;AACT,QAAA,OAAO,EAAE,WAAW;AACpB,QAAA,cAAc,EAAE,kBAAkB;AAClC,QAAA,YAAY,EAAE,OAAO;KACxB,CAAC;;IAEF,CAAC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,SAAS,CAAC,CACxD;IAED,QACI,oBAAC,aAAa,EAAA,EACV,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,0BAA0B,EACtC,aAAa,EAAE,IAAI,EACnB,OAAO,EAAE,OAAO,EAAA,EAEf,YAAY,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAC7B;AAExB;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
.enter {
|
|
4
|
+
visibility: hidden;
|
|
5
|
+
transform: translate(0, -500px);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.enterActive {
|
|
9
|
+
visibility: visible;
|
|
10
|
+
transform: translate(0);
|
|
11
|
+
transition: transform 0.4s ease-out;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@media (min-width: 600px) {
|
|
15
|
+
.enter {
|
|
16
|
+
transform: translate(100%, 0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.enterActive {
|
|
20
|
+
transform: translate(0);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -22,17 +22,6 @@
|
|
|
22
22
|
position: static;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
.enter {
|
|
26
|
-
visibility: hidden;
|
|
27
|
-
transform: translate(0, -500px);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.enterActive {
|
|
31
|
-
visibility: visible;
|
|
32
|
-
transform: translate(0);
|
|
33
|
-
transition: transform 0.4s ease-out;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
25
|
@media (min-width: 600px) {
|
|
37
26
|
.component {
|
|
38
27
|
right: var(--gap-48);
|
|
@@ -41,12 +30,4 @@
|
|
|
41
30
|
.component .notification {
|
|
42
31
|
width: auto;
|
|
43
32
|
}
|
|
44
|
-
|
|
45
|
-
.enter {
|
|
46
|
-
transform: translate(100%, 0);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.enterActive {
|
|
50
|
-
transform: translate(0);
|
|
51
|
-
}
|
|
52
33
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfalab/core-components-notification-manager",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.5",
|
|
4
4
|
"description": "Notification manager",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"main": "index.js",
|
|
11
11
|
"module": "./esm/index.js",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@alfalab/core-components-notification": "^9.0.
|
|
13
|
+
"@alfalab/core-components-notification": "^9.0.5",
|
|
14
14
|
"@alfalab/core-components-portal": "^5.0.1",
|
|
15
15
|
"@alfalab/core-components-stack": "^7.0.1",
|
|
16
16
|
"classnames": "^2.5.1",
|
package/src/component.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, { forwardRef, type HTMLAttributes
|
|
2
|
-
import {
|
|
1
|
+
import React, { forwardRef, type HTMLAttributes } from 'react';
|
|
2
|
+
import { TransitionGroup } from 'react-transition-group';
|
|
3
3
|
import cn from 'classnames';
|
|
4
4
|
|
|
5
5
|
import { Portal, type PortalProps } from '@alfalab/core-components-portal';
|
|
@@ -10,7 +10,7 @@ import { Notification, type NotificationElement } from './components';
|
|
|
10
10
|
|
|
11
11
|
import styles from './index.module.css';
|
|
12
12
|
|
|
13
|
-
export
|
|
13
|
+
export interface NotificationManagerProps extends HTMLAttributes<HTMLDivElement> {
|
|
14
14
|
/**
|
|
15
15
|
* Массив нотификаций.
|
|
16
16
|
* В нотификации обязательно передавайте id.
|
|
@@ -48,17 +48,7 @@ export type NotificationManagerProps = HTMLAttributes<HTMLDivElement> & {
|
|
|
48
48
|
* Контейнер к которому будут добавляться порталы
|
|
49
49
|
*/
|
|
50
50
|
container?: PortalProps['getPortalContainer'];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const CSS_TRANSITION_CLASS_NAMES = {
|
|
54
|
-
enter: styles.enter,
|
|
55
|
-
enterActive: styles.enterActive,
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const TIMEOUT = {
|
|
59
|
-
exit: 0,
|
|
60
|
-
enter: 400,
|
|
61
|
-
};
|
|
51
|
+
}
|
|
62
52
|
|
|
63
53
|
export const NotificationManager = forwardRef<HTMLDivElement, NotificationManagerProps>(
|
|
64
54
|
(
|
|
@@ -74,50 +64,38 @@ export const NotificationManager = forwardRef<HTMLDivElement, NotificationManage
|
|
|
74
64
|
...restProps
|
|
75
65
|
},
|
|
76
66
|
ref,
|
|
77
|
-
) =>
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
style
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
})}
|
|
110
|
-
onRemoveNotification={onRemoveNotification}
|
|
111
|
-
/>
|
|
112
|
-
</CSSTransition>
|
|
113
|
-
))}
|
|
114
|
-
</TransitionGroup>
|
|
115
|
-
</div>
|
|
116
|
-
</Portal>
|
|
117
|
-
)}
|
|
118
|
-
</Stack>
|
|
119
|
-
);
|
|
120
|
-
},
|
|
67
|
+
) => (
|
|
68
|
+
<Stack value={zIndex}>
|
|
69
|
+
{(computedZIndex) => (
|
|
70
|
+
<Portal getPortalContainer={container}>
|
|
71
|
+
<div
|
|
72
|
+
className={cn(styles.component, className)}
|
|
73
|
+
ref={ref}
|
|
74
|
+
data-test-id={dataTestId}
|
|
75
|
+
style={{
|
|
76
|
+
zIndex: computedZIndex,
|
|
77
|
+
top: offset,
|
|
78
|
+
...style,
|
|
79
|
+
}}
|
|
80
|
+
{...restProps}
|
|
81
|
+
>
|
|
82
|
+
<TransitionGroup>
|
|
83
|
+
{notifications.map((element, index) => (
|
|
84
|
+
<Notification
|
|
85
|
+
key={element.props.id}
|
|
86
|
+
element={element}
|
|
87
|
+
onRemoveNotification={onRemoveNotification}
|
|
88
|
+
className={cn(styles.notification, {
|
|
89
|
+
[styles.withoutMargin]: offset && index === 0,
|
|
90
|
+
})}
|
|
91
|
+
/>
|
|
92
|
+
))}
|
|
93
|
+
</TransitionGroup>
|
|
94
|
+
</div>
|
|
95
|
+
</Portal>
|
|
96
|
+
)}
|
|
97
|
+
</Stack>
|
|
98
|
+
),
|
|
121
99
|
);
|
|
122
100
|
|
|
123
101
|
NotificationManager.displayName = 'NotificationManager';
|
|
@@ -1,30 +1,52 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import React, {
|
|
2
2
|
cloneElement,
|
|
3
3
|
type FC,
|
|
4
4
|
type ReactElement,
|
|
5
|
-
type RefObject,
|
|
6
5
|
useCallback,
|
|
7
6
|
useMemo,
|
|
7
|
+
useRef,
|
|
8
8
|
} from 'react';
|
|
9
|
+
import { CSSTransition } from 'react-transition-group';
|
|
10
|
+
import { type CSSTransitionProps } from 'react-transition-group/CSSTransition';
|
|
9
11
|
import cn from 'classnames';
|
|
10
12
|
|
|
11
13
|
import { type NotificationProps as CoreNotificationProps } from '@alfalab/core-components-notification';
|
|
12
14
|
|
|
15
|
+
import styles from './index.module.css';
|
|
16
|
+
|
|
13
17
|
export type NotificationElement = ReactElement<CoreNotificationProps & { id: string }>;
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
const TIMEOUT = {
|
|
20
|
+
exit: 0,
|
|
21
|
+
enter: 400,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const CSS_TRANSITION_CLASS_NAMES = {
|
|
25
|
+
enter: styles.enter,
|
|
26
|
+
enterActive: styles.enterActive,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type NotificationTransitionProps = Partial<
|
|
30
|
+
Pick<CSSTransitionProps<HTMLDivElement>, 'in' | 'onExited' | 'appear' | 'enter' | 'exit'>
|
|
31
|
+
>;
|
|
32
|
+
|
|
33
|
+
interface NotificationProps extends NotificationTransitionProps {
|
|
16
34
|
element: NotificationElement;
|
|
17
35
|
className: string;
|
|
18
36
|
onRemoveNotification: (id: string) => void;
|
|
19
|
-
|
|
20
|
-
};
|
|
37
|
+
}
|
|
21
38
|
|
|
22
39
|
export const Notification: FC<NotificationProps> = ({
|
|
40
|
+
in: inProp,
|
|
41
|
+
onExited,
|
|
42
|
+
appear,
|
|
43
|
+
enter,
|
|
44
|
+
exit,
|
|
23
45
|
element,
|
|
24
46
|
className,
|
|
25
47
|
onRemoveNotification,
|
|
26
|
-
containerRef,
|
|
27
48
|
}) => {
|
|
49
|
+
const nodeRef = useRef<HTMLDivElement>(null);
|
|
28
50
|
const { onClose, onCloseTimeout } = element.props;
|
|
29
51
|
|
|
30
52
|
const handleClose = useCallback(() => {
|
|
@@ -52,11 +74,25 @@ export const Notification: FC<NotificationProps> = ({
|
|
|
52
74
|
offset: 0,
|
|
53
75
|
onClose: handleClose,
|
|
54
76
|
onCloseTimeout: handleCloseTimeout,
|
|
55
|
-
containerRef,
|
|
77
|
+
containerRef: nodeRef,
|
|
56
78
|
}),
|
|
57
79
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
|
-
[element, handleClose, handleCloseTimeout,
|
|
80
|
+
[element, handleClose, handleCloseTimeout, className],
|
|
59
81
|
);
|
|
60
82
|
|
|
61
|
-
return
|
|
83
|
+
return (
|
|
84
|
+
<CSSTransition<HTMLDivElement>
|
|
85
|
+
in={inProp}
|
|
86
|
+
onExited={onExited}
|
|
87
|
+
appear={appear}
|
|
88
|
+
enter={enter}
|
|
89
|
+
exit={exit}
|
|
90
|
+
timeout={TIMEOUT}
|
|
91
|
+
classNames={CSS_TRANSITION_CLASS_NAMES}
|
|
92
|
+
unmountOnExit={true}
|
|
93
|
+
nodeRef={nodeRef}
|
|
94
|
+
>
|
|
95
|
+
{cloneElement(element, notificationProps)}
|
|
96
|
+
</CSSTransition>
|
|
97
|
+
);
|
|
62
98
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@import '@alfalab/core-components-vars/src/index.css';
|
|
2
|
+
|
|
3
|
+
.enter {
|
|
4
|
+
visibility: hidden;
|
|
5
|
+
transform: translate(0, -500px);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.enterActive {
|
|
9
|
+
visibility: visible;
|
|
10
|
+
transform: translate(0);
|
|
11
|
+
transition: transform 0.4s ease-out;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@media (--tablet-s) {
|
|
15
|
+
.enter {
|
|
16
|
+
transform: translate(100%, 0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.enterActive {
|
|
20
|
+
transform: translate(0);
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/index.module.css
CHANGED
|
@@ -22,17 +22,6 @@
|
|
|
22
22
|
position: static;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
.enter {
|
|
26
|
-
visibility: hidden;
|
|
27
|
-
transform: translate(0, -500px);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.enterActive {
|
|
31
|
-
visibility: visible;
|
|
32
|
-
transform: translate(0);
|
|
33
|
-
transition: transform 0.4s ease-out;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
25
|
@media (--tablet-s) {
|
|
37
26
|
.component {
|
|
38
27
|
right: var(--gap-48);
|
|
@@ -41,12 +30,4 @@
|
|
|
41
30
|
.component .notification {
|
|
42
31
|
width: auto;
|
|
43
32
|
}
|
|
44
|
-
|
|
45
|
-
.enter {
|
|
46
|
-
transform: translate(100%, 0);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.enterActive {
|
|
50
|
-
transform: translate(0);
|
|
51
|
-
}
|
|
52
33
|
}
|