@alfalab/core-components-notification 9.0.4-alfasans → 9.0.5-alfasans
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.js +6 -2
- package/Component.js.map +1 -1
- package/cssm/Component.js +6 -2
- package/cssm/Component.js.map +1 -1
- package/cssm/index.module.css +12 -3
- package/esm/Component.js +6 -2
- package/esm/Component.js.map +1 -1
- package/esm/index.css +20 -11
- package/esm/index.module.css.js +1 -1
- package/esm/index.module.css.js.map +1 -1
- package/index.css +20 -11
- package/index.module.css.js +1 -1
- package/index.module.css.js.map +1 -1
- package/modern/Component.js +11 -2
- package/modern/Component.js.map +1 -1
- package/modern/index.css +20 -11
- package/modern/index.module.css.js +1 -1
- package/modern/index.module.css.js.map +1 -1
- package/moderncssm/Component.js +11 -2
- package/moderncssm/Component.js.map +1 -1
- package/moderncssm/index.module.css +12 -1
- package/package.json +2 -2
- package/src/Component.tsx +13 -2
- package/src/index.module.css +9 -1
package/Component.js
CHANGED
|
@@ -24,11 +24,14 @@ var elementClosest__default = /*#__PURE__*/_interopDefaultCompat(elementClosest)
|
|
|
24
24
|
|
|
25
25
|
var notificationClassNameSelector = ".".concat(index_module.notificationComponent);
|
|
26
26
|
var Notification = React.forwardRef(function (_a, ref) {
|
|
27
|
-
var className = _a.className, actionSectionClassName = _a.actionSectionClassName, children = _a.children, visible = _a.visible, _b = _a.offset, offset = _b === void 0 ? 108 : _b,
|
|
27
|
+
var className = _a.className, actionSectionClassName = _a.actionSectionClassName, children = _a.children, visible = _a.visible, _b = _a.offset, offset = _b === void 0 ? 108 : _b, legacyHasCloser = _a.hasCloser, _c = _a.autoCloseDelay, autoCloseDelay = _c === void 0 ? 5000 : _c, _d = _a.usePortal, usePortal = _d === void 0 ? true : _d, _e = _a.zIndex, zIndex = _e === void 0 ? coreComponentsStackContext.stackingOrder.TOAST : _e, style = _a.style, _f = _a.position, position = _f === void 0 ? 'top' : _f, onClose = _a.onClose, onCloseTimeout = _a.onCloseTimeout, onMouseEnter = _a.onMouseEnter, onMouseLeave = _a.onMouseLeave, onClickOutside = _a.onClickOutside, containerRef = _a.containerRef, _g = _a.closerProps, closerProps = _g === void 0 ? { hasCloser: true } : _g, restProps = tslib.__rest(_a, ["className", "actionSectionClassName", "children", "visible", "offset", "hasCloser", "autoCloseDelay", "usePortal", "zIndex", "style", "position", "onClose", "onCloseTimeout", "onMouseEnter", "onMouseLeave", "onClickOutside", "containerRef", "closerProps"]);
|
|
28
28
|
var notificationRef = React.useRef(null);
|
|
29
29
|
var autoCloseTimeoutRef = React.useRef(0);
|
|
30
30
|
var closeTimeoutRef = React.useRef(0);
|
|
31
31
|
var _h = React.useState(false), isClosing = _h[0], setIsClosing = _h[1];
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
33
|
+
var _hasCloser = closerProps.hasCloser, restCloserParams = tslib.__rest(closerProps, ["hasCloser"]);
|
|
34
|
+
var hasCloser = legacyHasCloser !== null && legacyHasCloser !== void 0 ? legacyHasCloser : _hasCloser;
|
|
32
35
|
var startAutoCloseTimer = React.useCallback(function () {
|
|
33
36
|
if (autoCloseDelay !== null) {
|
|
34
37
|
autoCloseTimeoutRef.current = window.setTimeout(function () {
|
|
@@ -100,7 +103,8 @@ var Notification = React.forwardRef(function (_a, ref) {
|
|
|
100
103
|
React__default.default.createElement(desktop.ToastPlateDesktop, tslib.__assign({ className: cn__default.default(index_module.notificationComponent, (_a = {},
|
|
101
104
|
_a[index_module.isVisible] = visible,
|
|
102
105
|
_a[index_module.isClosing] = isClosing,
|
|
103
|
-
_a
|
|
106
|
+
_a[index_module.hasCloser] = hasCloser,
|
|
107
|
+
_a), className), contentClassName: index_module.toastContent, actionSectionClassName: cn__default.default(actionSectionClassName, index_module.actionSection), style: tslib.__assign((_b = {}, _b[position] = offset, _b.zIndex = computedZIndex, _b), style), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: mergeRefs__default.default([ref, notificationRef]), role: visible ? 'alert' : undefined, onClose: onClose, closerProps: tslib.__assign({ divider: false, view: 'secondary', hasCloser: hasCloser }, restCloserParams) }, restProps), children))));
|
|
104
108
|
}));
|
|
105
109
|
});
|
|
106
110
|
Notification.displayName = 'Notification';
|
package/Component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser = true,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n hasCloser={hasCloser}\n onClose={onClose}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":["styles","forwardRef","stackingOrder","__rest","useRef","useState","useCallback","useEffect","elementClosest","useClickOutside","useSwipeable","Portal","Fragment","React","Stack","__assign","ToastPlateDesktop","cn","mergeRefs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser: legacyHasCloser,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n closerProps = { hasCloser: true },\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n const { hasCloser: _hasCloser, ...restCloserParams } = closerProps;\n const hasCloser = legacyHasCloser ?? _hasCloser;\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n [styles.hasCloser]: hasCloser,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n onClose={onClose}\n closerProps={{\n divider: false,\n view: 'secondary',\n hasCloser,\n ...restCloserParams,\n }}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":["styles","forwardRef","stackingOrder","__rest","useRef","useState","useCallback","useEffect","elementClosest","useClickOutside","useSwipeable","Portal","Fragment","React","Stack","__assign","ToastPlateDesktop","cn","mergeRefs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAqFA,IAAM,6BAA6B,GAAG,GAAA,CAAA,MAAA,CAAIA,YAAM,CAAC,qBAAqB,CAAE;IAE3D,YAAY,GAAGC,gBAAU,CAClC,UACI,EAoBC,EACD,GAAG,EAAA;AApBC,IAAA,IAAA,SAAS,GAAA,EAAA,CAAA,SAAA,EACT,sBAAsB,GAAA,EAAA,CAAA,sBAAA,EACtB,QAAQ,GAAA,EAAA,CAAA,QAAA,EACR,OAAO,GAAA,EAAA,CAAA,OAAA,EACP,EAAY,GAAA,EAAA,CAAA,MAAA,EAAZ,MAAM,GAAG,EAAA,KAAA,MAAA,GAAA,GAAG,KAAA,EACD,eAAe,GAAA,EAAA,CAAA,SAAA,EAC1B,sBAAqB,EAArB,cAAc,mBAAG,IAAI,GAAA,EAAA,EACrB,EAAgB,GAAA,EAAA,CAAA,SAAA,EAAhB,SAAS,GAAG,EAAA,KAAA,MAAA,GAAA,IAAI,KAAA,EAChB,EAAA,GAAA,EAAA,CAAA,MAA4B,EAA5B,MAAM,GAAA,EAAA,KAAA,MAAA,GAAGC,wCAAa,CAAC,KAAK,GAAA,EAAA,EAC5B,KAAK,GAAA,EAAA,CAAA,KAAA,EACL,gBAAgB,EAAhB,QAAQ,mBAAG,KAAK,GAAA,EAAA,EAChB,OAAO,GAAA,EAAA,CAAA,OAAA,EACP,cAAc,GAAA,EAAA,CAAA,cAAA,EACd,YAAY,GAAA,EAAA,CAAA,YAAA,EACZ,YAAY,GAAA,EAAA,CAAA,YAAA,EACZ,cAAc,oBAAA,EACd,YAAY,kBAAA,EACZ,EAAA,GAAA,EAAA,CAAA,WAAiC,EAAjC,WAAW,GAAA,EAAA,KAAA,MAAA,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,GAAA,EAAA,EAC9B,SAAS,GAAAC,YAAA,CAAA,EAAA,EAnBhB,iQAoBC,CADe;AAIhB,IAAA,IAAM,eAAe,GAAGC,YAAM,CAAiB,IAAI,CAAC;AACpD,IAAA,IAAM,mBAAmB,GAAGA,YAAM,CAAC,CAAC,CAAC;AACrC,IAAA,IAAM,eAAe,GAAGA,YAAM,CAAC,CAAC,CAAC;IAE3B,IAAA,EAAA,GAA4BC,cAAQ,CAAC,KAAK,CAAC,EAA1C,SAAS,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,YAAY,GAAA,EAAA,CAAA,CAAA,CAAmB;;IAGzC,IAAW,UAAU,GAA0B,WAAW,CAArC,SAAA,EAAK,gBAAgB,GAAAF,YAAA,CAAK,WAAW,EAA5D,CAA8C,WAAA,CAAA,CAAF;IAClD,IAAM,SAAS,GAAG,eAAe,KAAA,IAAA,IAAf,eAAe,KAAf,MAAA,GAAA,eAAe,GAAI,UAAU;IAE/C,IAAM,mBAAmB,GAAGG,iBAAW,CAAC,YAAA;AACpC,QAAA,IAAI,cAAc,KAAK,IAAI,EAAE;AACzB,YAAA,mBAAmB,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,YAAA;gBAC5C,IAAI,cAAc,EAAE;AAChB,oBAAA,cAAc,EAAE;;aAEvB,EAAE,cAAc,CAAC;;AAE1B,KAAC,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IAEpC,IAAM,kBAAkB,GAAGA,iBAAW,CAAC,YAAA;AACnC,QAAA,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC;KAC5C,EAAE,EAAE,CAAC;IAENC,eAAS,CACL,cAAM,OAAA,YAAA;AACF,QAAA,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC;AACzC,KAAC,CAFK,EAEL,EACD,EAAE,CACL;AAED,IAAAA,eAAS,CAAC,YAAA;QACNC,+BAAc,CAAC,MAAM,CAAC;KACzB,EAAE,EAAE,CAAC;AAEN,IAAAD,eAAS,CAAC,YAAA;QACN,IAAI,OAAO,EAAE;AACT,YAAA,mBAAmB,EAAE;;QAGzB,OAAO,YAAA;AACH,YAAA,kBAAkB,EAAE;AACxB,SAAC;KACJ,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;AAEtD,IAAA,IAAM,gBAAgB,GAAGD,iBAAW,CAChC,UAAC,KAAuC,EAAA;AACpC,QAAA,kBAAkB,EAAE;QAEpB,IAAI,YAAY,EAAE;YACd,YAAY,CAAC,KAAK,CAAC;;AAE3B,KAAC,EACD,CAAC,YAAY,EAAE,kBAAkB,CAAC,CACrC;AAED,IAAA,IAAM,gBAAgB,GAAGA,iBAAW,CAChC,UAAC,KAAuC,EAAA;AACpC,QAAA,kBAAkB,EAAE;AACpB,QAAA,mBAAmB,EAAE;QAErB,IAAI,YAAY,EAAE;YACd,YAAY,CAAC,KAAK,CAAC;;KAE1B,EACD,CAAC,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,CAAC,CAC1D;AAED,IAAA,IAAM,kBAAkB,GAAGA,iBAAW,CAClC,UAAC,KAA0C,EAAA;AACvC,QAAA,IAAM,oBAAoB,GAAG,CAAC,CAAE,KAAK,CAAC,MAAkB,CAAC,OAAO,CAC5D,6BAA6B,CAChC;AAED;;;AAGG;AACH,QAAA,IAAI,cAAc,IAAI,OAAO,IAAI,CAAC,oBAAoB,EAAE;YACpD,cAAc,CAAC,KAAyB,CAAC;;AAEjD,KAAC,EACD,CAAC,cAAc,EAAE,OAAO,CAAC,CAC5B;AAED,IAAAG,qBAAe,CAAC,eAAe,EAAE,kBAAkB,CAAC;IAEpD,IAAM,iBAAiB,GAAGC,2BAAY,CAAC;QACnC,QAAQ,EAAE,UAAC,EAAO,EAAA;AAAL,YAAA,IAAA,GAAG,GAAA,EAAA,CAAA,GAAA;AACZ,YAAA,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBAClD,YAAY,CAAC,IAAI,CAAC;AAElB,gBAAA,eAAe,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,YAAA;oBACxC,YAAY,CAAC,KAAK,CAAC;AACnB,oBAAA,OAAO,EAAE;iBACZ,EAAE,GAAG,CAAC;;SAEd;AACD,QAAA,KAAK,EAAE,GAAG;AACb,KAAA,CAAC;IAEF,IAAM,OAAO,GAAG,SAAS,GAAGC,2BAAM,GAAGC,cAAQ;IAE7C,QACIC,qCAACC,yBAAK,EAAA,EAAC,KAAK,EAAE,MAAM,EACf,EAAA,UAAC,cAAc,EAAA;;QAAK,QACjBD,qCAAC,OAAO,EAAA,IAAA;AACJ,YAAAA,sBAAA,CAAA,aAAA,CAAA,KAAA,EAAAE,cAAA,CAAA,EAAA,EAAS,iBAAiB,EAAA,EAAE,GAAG,EAAE,YAAY,EAAA,CAAA;gBACzCF,sBAAC,CAAA,aAAA,CAAAG,yBAAiB,mBACd,SAAS,EAAEC,mBAAE,CACTjB,YAAM,CAAC,qBAAqB,GAAA,EAAA,GAAA,EAAA;AAExB,wBAAA,EAAA,CAACA,YAAM,CAAC,SAAS,CAAA,GAAG,OAAO;AAC3B,wBAAA,EAAA,CAACA,YAAM,CAAC,SAAS,CAAA,GAAG,SAAS;AAC7B,wBAAA,EAAA,CAACA,YAAM,CAAC,SAAS,CAAA,GAAG,SAAS;AAEjC,wBAAA,EAAA,GAAA,SAAS,CACZ,EACD,gBAAgB,EAAEA,YAAM,CAAC,YAAY,EACrC,sBAAsB,EAAEiB,mBAAE,CACtB,sBAAsB,EACtBjB,YAAM,CAAC,aAAa,CACvB,EACD,KAAK,EACAe,cAAA,EAAA,EAAA,GAAA,EAAA,EAAA,EAAA,CAAA,QAAQ,IAAG,MAAM,EAClB,SAAM,GAAE,cAAc,OACnB,KAAK,CAAA,EAEZ,YAAY,EAAE,gBAAgB,EAC9B,YAAY,EAAE,gBAAgB,EAC9B,GAAG,EAAEG,0BAAS,CAAC,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EACtC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,EACnC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAAH,cAAA,CAAA,EACP,OAAO,EAAE,KAAK,EACd,IAAI,EAAE,WAAW,EACjB,SAAS,WAAA,EACN,EAAA,gBAAgB,KAEnB,SAAS,CAAA,EAEZ,QAAQ,CACO,CAClB,CACA;KACb,CACG;AAEhB,CAAC;AAGL,YAAY,CAAC,WAAW,GAAG,cAAc;;;;"}
|
package/cssm/Component.js
CHANGED
|
@@ -25,11 +25,14 @@ var styles__default = /*#__PURE__*/_interopDefaultCompat(styles);
|
|
|
25
25
|
|
|
26
26
|
var notificationClassNameSelector = ".".concat(styles__default.default.notificationComponent);
|
|
27
27
|
var Notification = React.forwardRef(function (_a, ref) {
|
|
28
|
-
var className = _a.className, actionSectionClassName = _a.actionSectionClassName, children = _a.children, visible = _a.visible, _b = _a.offset, offset = _b === void 0 ? 108 : _b,
|
|
28
|
+
var className = _a.className, actionSectionClassName = _a.actionSectionClassName, children = _a.children, visible = _a.visible, _b = _a.offset, offset = _b === void 0 ? 108 : _b, legacyHasCloser = _a.hasCloser, _c = _a.autoCloseDelay, autoCloseDelay = _c === void 0 ? 5000 : _c, _d = _a.usePortal, usePortal = _d === void 0 ? true : _d, _e = _a.zIndex, zIndex = _e === void 0 ? cssm.stackingOrder.TOAST : _e, style = _a.style, _f = _a.position, position = _f === void 0 ? 'top' : _f, onClose = _a.onClose, onCloseTimeout = _a.onCloseTimeout, onMouseEnter = _a.onMouseEnter, onMouseLeave = _a.onMouseLeave, onClickOutside = _a.onClickOutside, containerRef = _a.containerRef, _g = _a.closerProps, closerProps = _g === void 0 ? { hasCloser: true } : _g, restProps = tslib.__rest(_a, ["className", "actionSectionClassName", "children", "visible", "offset", "hasCloser", "autoCloseDelay", "usePortal", "zIndex", "style", "position", "onClose", "onCloseTimeout", "onMouseEnter", "onMouseLeave", "onClickOutside", "containerRef", "closerProps"]);
|
|
29
29
|
var notificationRef = React.useRef(null);
|
|
30
30
|
var autoCloseTimeoutRef = React.useRef(0);
|
|
31
31
|
var closeTimeoutRef = React.useRef(0);
|
|
32
32
|
var _h = React.useState(false), isClosing = _h[0], setIsClosing = _h[1];
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
34
|
+
var _hasCloser = closerProps.hasCloser, restCloserParams = tslib.__rest(closerProps, ["hasCloser"]);
|
|
35
|
+
var hasCloser = legacyHasCloser !== null && legacyHasCloser !== void 0 ? legacyHasCloser : _hasCloser;
|
|
33
36
|
var startAutoCloseTimer = React.useCallback(function () {
|
|
34
37
|
if (autoCloseDelay !== null) {
|
|
35
38
|
autoCloseTimeoutRef.current = window.setTimeout(function () {
|
|
@@ -101,7 +104,8 @@ var Notification = React.forwardRef(function (_a, ref) {
|
|
|
101
104
|
React__default.default.createElement(desktop.ToastPlateDesktop, tslib.__assign({ className: cn__default.default(styles__default.default.notificationComponent, (_a = {},
|
|
102
105
|
_a[styles__default.default.isVisible] = visible,
|
|
103
106
|
_a[styles__default.default.isClosing] = isClosing,
|
|
104
|
-
_a
|
|
107
|
+
_a[styles__default.default.hasCloser] = hasCloser,
|
|
108
|
+
_a), className), contentClassName: styles__default.default.toastContent, actionSectionClassName: cn__default.default(actionSectionClassName, styles__default.default.actionSection), style: tslib.__assign((_b = {}, _b[position] = offset, _b.zIndex = computedZIndex, _b), style), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: mergeRefs__default.default([ref, notificationRef]), role: visible ? 'alert' : undefined, onClose: onClose, closerProps: tslib.__assign({ divider: false, view: 'secondary', hasCloser: hasCloser }, restCloserParams) }, restProps), children))));
|
|
105
109
|
}));
|
|
106
110
|
});
|
|
107
111
|
Notification.displayName = 'Notification';
|
package/cssm/Component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser = true,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n hasCloser={hasCloser}\n onClose={onClose}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":["styles","forwardRef","stackingOrder","__rest","useRef","useState","useCallback","useEffect","elementClosest","useClickOutside","useSwipeable","Portal","Fragment","React","Stack","__assign","ToastPlateDesktop","cn","mergeRefs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser: legacyHasCloser,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n closerProps = { hasCloser: true },\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n const { hasCloser: _hasCloser, ...restCloserParams } = closerProps;\n const hasCloser = legacyHasCloser ?? _hasCloser;\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n [styles.hasCloser]: hasCloser,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n onClose={onClose}\n closerProps={{\n divider: false,\n view: 'secondary',\n hasCloser,\n ...restCloserParams,\n }}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":["styles","forwardRef","stackingOrder","__rest","useRef","useState","useCallback","useEffect","elementClosest","useClickOutside","useSwipeable","Portal","Fragment","React","Stack","__assign","ToastPlateDesktop","cn","mergeRefs"],"mappings":"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"}
|
package/cssm/index.module.css
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
--gap-xs: 8px;
|
|
3
2
|
--gap-s: 12px;
|
|
3
|
+
--gap-m: 16px;
|
|
4
4
|
--gap-xl: 24px;
|
|
5
5
|
--gap-4xl: 48px;
|
|
6
6
|
--gap-s-neg: -12px;
|
|
7
7
|
--gap-0: 0px;
|
|
8
|
-
--gap-8: var(--gap-xs);
|
|
9
8
|
--gap-12: var(--gap-s);
|
|
9
|
+
--gap-16: var(--gap-m);
|
|
10
10
|
--gap-24: var(--gap-xl);
|
|
11
11
|
--gap-48: var(--gap-4xl);
|
|
12
12
|
--gap-12-neg: var(--gap-s-neg);
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
-moz-user-select: none;
|
|
25
25
|
user-select: none;
|
|
26
26
|
transition: transform 0.4s ease-out;
|
|
27
|
+
border-radius: var(--gap-16);
|
|
27
28
|
}
|
|
28
29
|
@media screen and (min-width: 600px) {
|
|
29
30
|
.notificationComponent {
|
|
@@ -45,6 +46,9 @@
|
|
|
45
46
|
transform: translate(calc(100% + var(--gap-48)), 0);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
49
|
+
.notificationComponent.hasCloser {
|
|
50
|
+
padding-right: 52px;
|
|
51
|
+
}
|
|
48
52
|
.notificationComponent.notificationComponent {
|
|
49
53
|
position: fixed;
|
|
50
54
|
}
|
|
@@ -53,9 +57,14 @@
|
|
|
53
57
|
width: var(--notification-desktop-content-width);
|
|
54
58
|
}
|
|
55
59
|
}
|
|
60
|
+
.toastContent {
|
|
61
|
+
|
|
62
|
+
box-sizing: border-box;
|
|
63
|
+
gap: var(--gap-16);
|
|
64
|
+
}
|
|
56
65
|
.actionSection {
|
|
57
66
|
min-width: 104px;
|
|
58
67
|
min-height: 48px;
|
|
59
|
-
padding:
|
|
68
|
+
padding: 0;
|
|
60
69
|
margin: var(--gap-12-neg) var(--gap-0);
|
|
61
70
|
}
|
package/esm/Component.js
CHANGED
|
@@ -13,11 +13,14 @@ import styles from './index.module.css.js';
|
|
|
13
13
|
|
|
14
14
|
var notificationClassNameSelector = ".".concat(styles.notificationComponent);
|
|
15
15
|
var Notification = forwardRef(function (_a, ref) {
|
|
16
|
-
var className = _a.className, actionSectionClassName = _a.actionSectionClassName, children = _a.children, visible = _a.visible, _b = _a.offset, offset = _b === void 0 ? 108 : _b,
|
|
16
|
+
var className = _a.className, actionSectionClassName = _a.actionSectionClassName, children = _a.children, visible = _a.visible, _b = _a.offset, offset = _b === void 0 ? 108 : _b, legacyHasCloser = _a.hasCloser, _c = _a.autoCloseDelay, autoCloseDelay = _c === void 0 ? 5000 : _c, _d = _a.usePortal, usePortal = _d === void 0 ? true : _d, _e = _a.zIndex, zIndex = _e === void 0 ? stackingOrder.TOAST : _e, style = _a.style, _f = _a.position, position = _f === void 0 ? 'top' : _f, onClose = _a.onClose, onCloseTimeout = _a.onCloseTimeout, onMouseEnter = _a.onMouseEnter, onMouseLeave = _a.onMouseLeave, onClickOutside = _a.onClickOutside, containerRef = _a.containerRef, _g = _a.closerProps, closerProps = _g === void 0 ? { hasCloser: true } : _g, restProps = __rest(_a, ["className", "actionSectionClassName", "children", "visible", "offset", "hasCloser", "autoCloseDelay", "usePortal", "zIndex", "style", "position", "onClose", "onCloseTimeout", "onMouseEnter", "onMouseLeave", "onClickOutside", "containerRef", "closerProps"]);
|
|
17
17
|
var notificationRef = useRef(null);
|
|
18
18
|
var autoCloseTimeoutRef = useRef(0);
|
|
19
19
|
var closeTimeoutRef = useRef(0);
|
|
20
20
|
var _h = useState(false), isClosing = _h[0], setIsClosing = _h[1];
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
22
|
+
var _hasCloser = closerProps.hasCloser, restCloserParams = __rest(closerProps, ["hasCloser"]);
|
|
23
|
+
var hasCloser = legacyHasCloser !== null && legacyHasCloser !== void 0 ? legacyHasCloser : _hasCloser;
|
|
21
24
|
var startAutoCloseTimer = useCallback(function () {
|
|
22
25
|
if (autoCloseDelay !== null) {
|
|
23
26
|
autoCloseTimeoutRef.current = window.setTimeout(function () {
|
|
@@ -89,7 +92,8 @@ var Notification = forwardRef(function (_a, ref) {
|
|
|
89
92
|
React.createElement(ToastPlateDesktop, __assign({ className: cn(styles.notificationComponent, (_a = {},
|
|
90
93
|
_a[styles.isVisible] = visible,
|
|
91
94
|
_a[styles.isClosing] = isClosing,
|
|
92
|
-
_a
|
|
95
|
+
_a[styles.hasCloser] = hasCloser,
|
|
96
|
+
_a), className), contentClassName: styles.toastContent, actionSectionClassName: cn(actionSectionClassName, styles.actionSection), style: __assign((_b = {}, _b[position] = offset, _b.zIndex = computedZIndex, _b), style), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: mergeRefs([ref, notificationRef]), role: visible ? 'alert' : undefined, onClose: onClose, closerProps: __assign({ divider: false, view: 'secondary', hasCloser: hasCloser }, restCloserParams) }, restProps), children))));
|
|
93
97
|
}));
|
|
94
98
|
});
|
|
95
99
|
Notification.displayName = 'Notification';
|
package/esm/Component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser = true,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n hasCloser={hasCloser}\n onClose={onClose}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser: legacyHasCloser,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n closerProps = { hasCloser: true },\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n const { hasCloser: _hasCloser, ...restCloserParams } = closerProps;\n const hasCloser = legacyHasCloser ?? _hasCloser;\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n [styles.hasCloser]: hasCloser,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n onClose={onClose}\n closerProps={{\n divider: false,\n view: 'secondary',\n hasCloser,\n ...restCloserParams,\n }}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":[],"mappings":"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"}
|
package/esm/index.css
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
--gap-xs: 8px;
|
|
3
2
|
--gap-s: 12px;
|
|
3
|
+
--gap-m: 16px;
|
|
4
4
|
--gap-xl: 24px;
|
|
5
5
|
--gap-4xl: 48px;
|
|
6
6
|
--gap-s-neg: -12px;
|
|
7
7
|
--gap-0: 0px;
|
|
8
|
-
--gap-8: var(--gap-xs);
|
|
9
8
|
--gap-12: var(--gap-s);
|
|
9
|
+
--gap-16: var(--gap-m);
|
|
10
10
|
--gap-24: var(--gap-xl);
|
|
11
11
|
--gap-48: var(--gap-4xl);
|
|
12
12
|
--gap-12-neg: var(--gap-s-neg);
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
:root {
|
|
15
15
|
--notification-desktop-content-width: 278px;
|
|
16
16
|
}
|
|
17
|
-
.
|
|
17
|
+
.notification__notificationComponent_8t50f {
|
|
18
18
|
visibility: hidden;
|
|
19
19
|
right: var(--gap-12);
|
|
20
20
|
transform: translate(0, -500px);
|
|
@@ -24,38 +24,47 @@
|
|
|
24
24
|
-moz-user-select: none;
|
|
25
25
|
user-select: none;
|
|
26
26
|
transition: transform 0.4s ease-out;
|
|
27
|
+
border-radius: var(--gap-16);
|
|
27
28
|
}
|
|
28
29
|
@media screen and (min-width: 600px) {
|
|
29
|
-
.
|
|
30
|
+
.notification__notificationComponent_8t50f {
|
|
30
31
|
right: var(--gap-48);
|
|
31
32
|
width: auto;
|
|
32
33
|
transform: translate(calc(100% + var(--gap-48)), 0);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
|
-
.
|
|
36
|
+
.notification__notificationComponent_8t50f.notification__isVisible_8t50f {
|
|
36
37
|
visibility: visible;
|
|
37
38
|
transform: translate(0, 0);
|
|
38
39
|
}
|
|
39
|
-
.
|
|
40
|
+
.notification__notificationComponent_8t50f.notification__isClosing_8t50f {
|
|
40
41
|
transition: transform 0.1s ease-out;
|
|
41
42
|
transform: translate(100vw, 0);
|
|
42
43
|
}
|
|
43
44
|
@media screen and (min-width: 600px) {
|
|
44
|
-
.
|
|
45
|
+
.notification__notificationComponent_8t50f.notification__isClosing_8t50f {
|
|
45
46
|
transform: translate(calc(100% + var(--gap-48)), 0);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
.
|
|
49
|
+
.notification__notificationComponent_8t50f.notification__hasCloser_8t50f {
|
|
50
|
+
padding-right: 52px;
|
|
51
|
+
}
|
|
52
|
+
.notification__notificationComponent_8t50f.notification__notificationComponent_8t50f {
|
|
49
53
|
position: fixed;
|
|
50
54
|
}
|
|
51
55
|
@media screen and (min-width: 600px) {
|
|
52
|
-
.
|
|
56
|
+
.notification__toastContent_8t50f {
|
|
53
57
|
width: var(--notification-desktop-content-width);
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
|
-
.
|
|
60
|
+
.notification__toastContent_8t50f {
|
|
61
|
+
|
|
62
|
+
box-sizing: border-box;
|
|
63
|
+
gap: var(--gap-16);
|
|
64
|
+
}
|
|
65
|
+
.notification__actionSection_8t50f {
|
|
57
66
|
min-width: 104px;
|
|
58
67
|
min-height: 48px;
|
|
59
|
-
padding:
|
|
68
|
+
padding: 0;
|
|
60
69
|
margin: var(--gap-12-neg) var(--gap-0);
|
|
61
70
|
}
|
package/esm/index.module.css.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './index.css';
|
|
2
2
|
|
|
3
|
-
var styles = {"notificationComponent":"
|
|
3
|
+
var styles = {"notificationComponent":"notification__notificationComponent_8t50f","isVisible":"notification__isVisible_8t50f","isClosing":"notification__isClosing_8t50f","hasCloser":"notification__hasCloser_8t50f","toastContent":"notification__toastContent_8t50f","actionSection":"notification__actionSection_8t50f"};
|
|
4
4
|
|
|
5
5
|
export { styles as default };
|
|
6
6
|
//# sourceMappingURL=index.module.css.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n:root {\n --notification-desktop-content-width: 278px;\n}\n\n.notificationComponent {\n visibility: hidden;\n right: var(--gap-12);\n transform: translate(0, -500px);\n width: calc(100% - var(--gap-24));\n max-width: calc(100vw - var(--gap-24));\n user-select: none;\n transition: transform 0.4s ease-out;\n\n @media screen and (min-width: 600px) {\n right: var(--gap-48);\n width: auto;\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n\n &.isVisible {\n visibility: visible;\n transform: translate(0, 0);\n }\n\n &.isClosing {\n transition: transform 0.1s ease-out;\n transform: translate(100vw, 0);\n\n @media screen and (min-width: 600px) {\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n }\n}\n\n.notificationComponent.notificationComponent {\n position: fixed;\n}\n\n.toastContent {\n @media screen and (min-width: 600px) {\n width: var(--notification-desktop-content-width);\n }\n}\n\n.actionSection {\n min-width: 104px;\n min-height: 48px;\n padding:
|
|
1
|
+
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n:root {\n --notification-desktop-content-width: 278px;\n}\n\n.notificationComponent {\n visibility: hidden;\n right: var(--gap-12);\n transform: translate(0, -500px);\n width: calc(100% - var(--gap-24));\n max-width: calc(100vw - var(--gap-24));\n user-select: none;\n transition: transform 0.4s ease-out;\n border-radius: var(--gap-16);\n\n @media screen and (min-width: 600px) {\n right: var(--gap-48);\n width: auto;\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n\n &.isVisible {\n visibility: visible;\n transform: translate(0, 0);\n }\n\n &.isClosing {\n transition: transform 0.1s ease-out;\n transform: translate(100vw, 0);\n\n @media screen and (min-width: 600px) {\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n }\n\n &.hasCloser {\n padding-right: 52px;\n }\n}\n\n.notificationComponent.notificationComponent {\n position: fixed;\n}\n\n.toastContent {\n @media screen and (min-width: 600px) {\n width: var(--notification-desktop-content-width);\n }\n\n box-sizing: border-box;\n gap: var(--gap-16);\n}\n\n.actionSection {\n min-width: 104px;\n min-height: 48px;\n padding: 0;\n margin: var(--gap-12-neg) var(--gap-0);\n}\n"],"names":[],"mappings":";;AAEgB,aAAe,CAAC,uBAAuB,CAAC,2CAA2C,CAAC,WAAW,CAAC,+BAA+B,CAAC,WAAW,CAAC,+BAA+B,CAAC,WAAW,CAAC,+BAA+B,CAAC,cAAc,CAAC,kCAAkC,CAAC,eAAe,CAAC,mCAAmC,CAAC;;;;"}
|
package/index.css
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
--gap-xs: 8px;
|
|
3
2
|
--gap-s: 12px;
|
|
3
|
+
--gap-m: 16px;
|
|
4
4
|
--gap-xl: 24px;
|
|
5
5
|
--gap-4xl: 48px;
|
|
6
6
|
--gap-s-neg: -12px;
|
|
7
7
|
--gap-0: 0px;
|
|
8
|
-
--gap-8: var(--gap-xs);
|
|
9
8
|
--gap-12: var(--gap-s);
|
|
9
|
+
--gap-16: var(--gap-m);
|
|
10
10
|
--gap-24: var(--gap-xl);
|
|
11
11
|
--gap-48: var(--gap-4xl);
|
|
12
12
|
--gap-12-neg: var(--gap-s-neg);
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
:root {
|
|
15
15
|
--notification-desktop-content-width: 278px;
|
|
16
16
|
}
|
|
17
|
-
.
|
|
17
|
+
.notification__notificationComponent_8t50f {
|
|
18
18
|
visibility: hidden;
|
|
19
19
|
right: var(--gap-12);
|
|
20
20
|
transform: translate(0, -500px);
|
|
@@ -24,38 +24,47 @@
|
|
|
24
24
|
-moz-user-select: none;
|
|
25
25
|
user-select: none;
|
|
26
26
|
transition: transform 0.4s ease-out;
|
|
27
|
+
border-radius: var(--gap-16);
|
|
27
28
|
}
|
|
28
29
|
@media screen and (min-width: 600px) {
|
|
29
|
-
.
|
|
30
|
+
.notification__notificationComponent_8t50f {
|
|
30
31
|
right: var(--gap-48);
|
|
31
32
|
width: auto;
|
|
32
33
|
transform: translate(calc(100% + var(--gap-48)), 0);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
|
-
.
|
|
36
|
+
.notification__notificationComponent_8t50f.notification__isVisible_8t50f {
|
|
36
37
|
visibility: visible;
|
|
37
38
|
transform: translate(0, 0);
|
|
38
39
|
}
|
|
39
|
-
.
|
|
40
|
+
.notification__notificationComponent_8t50f.notification__isClosing_8t50f {
|
|
40
41
|
transition: transform 0.1s ease-out;
|
|
41
42
|
transform: translate(100vw, 0);
|
|
42
43
|
}
|
|
43
44
|
@media screen and (min-width: 600px) {
|
|
44
|
-
.
|
|
45
|
+
.notification__notificationComponent_8t50f.notification__isClosing_8t50f {
|
|
45
46
|
transform: translate(calc(100% + var(--gap-48)), 0);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
.
|
|
49
|
+
.notification__notificationComponent_8t50f.notification__hasCloser_8t50f {
|
|
50
|
+
padding-right: 52px;
|
|
51
|
+
}
|
|
52
|
+
.notification__notificationComponent_8t50f.notification__notificationComponent_8t50f {
|
|
49
53
|
position: fixed;
|
|
50
54
|
}
|
|
51
55
|
@media screen and (min-width: 600px) {
|
|
52
|
-
.
|
|
56
|
+
.notification__toastContent_8t50f {
|
|
53
57
|
width: var(--notification-desktop-content-width);
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
|
-
.
|
|
60
|
+
.notification__toastContent_8t50f {
|
|
61
|
+
|
|
62
|
+
box-sizing: border-box;
|
|
63
|
+
gap: var(--gap-16);
|
|
64
|
+
}
|
|
65
|
+
.notification__actionSection_8t50f {
|
|
57
66
|
min-width: 104px;
|
|
58
67
|
min-height: 48px;
|
|
59
|
-
padding:
|
|
68
|
+
padding: 0;
|
|
60
69
|
margin: var(--gap-12-neg) var(--gap-0);
|
|
61
70
|
}
|
package/index.module.css.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require('./index.css');
|
|
4
4
|
|
|
5
|
-
var styles = {"notificationComponent":"
|
|
5
|
+
var styles = {"notificationComponent":"notification__notificationComponent_8t50f","isVisible":"notification__isVisible_8t50f","isClosing":"notification__isClosing_8t50f","hasCloser":"notification__hasCloser_8t50f","toastContent":"notification__toastContent_8t50f","actionSection":"notification__actionSection_8t50f"};
|
|
6
6
|
|
|
7
7
|
module.exports = styles;
|
|
8
8
|
//# sourceMappingURL=index.module.css.js.map
|
package/index.module.css.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n:root {\n --notification-desktop-content-width: 278px;\n}\n\n.notificationComponent {\n visibility: hidden;\n right: var(--gap-12);\n transform: translate(0, -500px);\n width: calc(100% - var(--gap-24));\n max-width: calc(100vw - var(--gap-24));\n user-select: none;\n transition: transform 0.4s ease-out;\n\n @media screen and (min-width: 600px) {\n right: var(--gap-48);\n width: auto;\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n\n &.isVisible {\n visibility: visible;\n transform: translate(0, 0);\n }\n\n &.isClosing {\n transition: transform 0.1s ease-out;\n transform: translate(100vw, 0);\n\n @media screen and (min-width: 600px) {\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n }\n}\n\n.notificationComponent.notificationComponent {\n position: fixed;\n}\n\n.toastContent {\n @media screen and (min-width: 600px) {\n width: var(--notification-desktop-content-width);\n }\n}\n\n.actionSection {\n min-width: 104px;\n min-height: 48px;\n padding:
|
|
1
|
+
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n:root {\n --notification-desktop-content-width: 278px;\n}\n\n.notificationComponent {\n visibility: hidden;\n right: var(--gap-12);\n transform: translate(0, -500px);\n width: calc(100% - var(--gap-24));\n max-width: calc(100vw - var(--gap-24));\n user-select: none;\n transition: transform 0.4s ease-out;\n border-radius: var(--gap-16);\n\n @media screen and (min-width: 600px) {\n right: var(--gap-48);\n width: auto;\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n\n &.isVisible {\n visibility: visible;\n transform: translate(0, 0);\n }\n\n &.isClosing {\n transition: transform 0.1s ease-out;\n transform: translate(100vw, 0);\n\n @media screen and (min-width: 600px) {\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n }\n\n &.hasCloser {\n padding-right: 52px;\n }\n}\n\n.notificationComponent.notificationComponent {\n position: fixed;\n}\n\n.toastContent {\n @media screen and (min-width: 600px) {\n width: var(--notification-desktop-content-width);\n }\n\n box-sizing: border-box;\n gap: var(--gap-16);\n}\n\n.actionSection {\n min-width: 104px;\n min-height: 48px;\n padding: 0;\n margin: var(--gap-12-neg) var(--gap-0);\n}\n"],"names":[],"mappings":";;;;AAEgB,aAAe,CAAC,uBAAuB,CAAC,2CAA2C,CAAC,WAAW,CAAC,+BAA+B,CAAC,WAAW,CAAC,+BAA+B,CAAC,WAAW,CAAC,+BAA+B,CAAC,cAAc,CAAC,kCAAkC,CAAC,eAAe,CAAC,mCAAmC,CAAC;;;;"}
|
package/modern/Component.js
CHANGED
|
@@ -11,11 +11,14 @@ import { useClickOutside } from './utils/index.js';
|
|
|
11
11
|
import styles from './index.module.css.js';
|
|
12
12
|
|
|
13
13
|
const notificationClassNameSelector = `.${styles.notificationComponent}`;
|
|
14
|
-
const Notification = forwardRef(({ className, actionSectionClassName, children, visible, offset = 108, hasCloser
|
|
14
|
+
const Notification = forwardRef(({ className, actionSectionClassName, children, visible, offset = 108, hasCloser: legacyHasCloser, autoCloseDelay = 5000, usePortal = true, zIndex = stackingOrder.TOAST, style, position = 'top', onClose, onCloseTimeout, onMouseEnter, onMouseLeave, onClickOutside, containerRef, closerProps = { hasCloser: true }, ...restProps }, ref) => {
|
|
15
15
|
const notificationRef = useRef(null);
|
|
16
16
|
const autoCloseTimeoutRef = useRef(0);
|
|
17
17
|
const closeTimeoutRef = useRef(0);
|
|
18
18
|
const [isClosing, setIsClosing] = useState(false);
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
20
|
+
const { hasCloser: _hasCloser, ...restCloserParams } = closerProps;
|
|
21
|
+
const hasCloser = legacyHasCloser ?? _hasCloser;
|
|
19
22
|
const startAutoCloseTimer = useCallback(() => {
|
|
20
23
|
if (autoCloseDelay !== null) {
|
|
21
24
|
autoCloseTimeoutRef.current = window.setTimeout(() => {
|
|
@@ -84,11 +87,17 @@ const Notification = forwardRef(({ className, actionSectionClassName, children,
|
|
|
84
87
|
React.createElement(ToastPlateDesktop, { className: cn(styles.notificationComponent, {
|
|
85
88
|
[styles.isVisible]: visible,
|
|
86
89
|
[styles.isClosing]: isClosing,
|
|
90
|
+
[styles.hasCloser]: hasCloser,
|
|
87
91
|
}, className), contentClassName: styles.toastContent, actionSectionClassName: cn(actionSectionClassName, styles.actionSection), style: {
|
|
88
92
|
[position]: offset,
|
|
89
93
|
zIndex: computedZIndex,
|
|
90
94
|
...style,
|
|
91
|
-
}, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: mergeRefs([ref, notificationRef]), role: visible ? 'alert' : undefined,
|
|
95
|
+
}, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: mergeRefs([ref, notificationRef]), role: visible ? 'alert' : undefined, onClose: onClose, closerProps: {
|
|
96
|
+
divider: false,
|
|
97
|
+
view: 'secondary',
|
|
98
|
+
hasCloser,
|
|
99
|
+
...restCloserParams,
|
|
100
|
+
}, ...restProps }, children))))));
|
|
92
101
|
});
|
|
93
102
|
Notification.displayName = 'Notification';
|
|
94
103
|
|
package/modern/Component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser = true,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n hasCloser={hasCloser}\n onClose={onClose}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser: legacyHasCloser,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n closerProps = { hasCloser: true },\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n const { hasCloser: _hasCloser, ...restCloserParams } = closerProps;\n const hasCloser = legacyHasCloser ?? _hasCloser;\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n [styles.hasCloser]: hasCloser,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n onClose={onClose}\n closerProps={{\n divider: false,\n view: 'secondary',\n hasCloser,\n ...restCloserParams,\n }}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":[],"mappings":"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"}
|
package/modern/index.css
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
--gap-xs: 8px;
|
|
3
2
|
--gap-s: 12px;
|
|
3
|
+
--gap-m: 16px;
|
|
4
4
|
--gap-xl: 24px;
|
|
5
5
|
--gap-4xl: 48px;
|
|
6
6
|
--gap-s-neg: -12px;
|
|
7
7
|
--gap-0: 0px;
|
|
8
|
-
--gap-8: var(--gap-xs);
|
|
9
8
|
--gap-12: var(--gap-s);
|
|
9
|
+
--gap-16: var(--gap-m);
|
|
10
10
|
--gap-24: var(--gap-xl);
|
|
11
11
|
--gap-48: var(--gap-4xl);
|
|
12
12
|
--gap-12-neg: var(--gap-s-neg);
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
:root {
|
|
15
15
|
--notification-desktop-content-width: 278px;
|
|
16
16
|
}
|
|
17
|
-
.
|
|
17
|
+
.notification__notificationComponent_8t50f {
|
|
18
18
|
visibility: hidden;
|
|
19
19
|
right: var(--gap-12);
|
|
20
20
|
transform: translate(0, -500px);
|
|
@@ -24,38 +24,47 @@
|
|
|
24
24
|
-moz-user-select: none;
|
|
25
25
|
user-select: none;
|
|
26
26
|
transition: transform 0.4s ease-out;
|
|
27
|
+
border-radius: var(--gap-16);
|
|
27
28
|
}
|
|
28
29
|
@media screen and (min-width: 600px) {
|
|
29
|
-
.
|
|
30
|
+
.notification__notificationComponent_8t50f {
|
|
30
31
|
right: var(--gap-48);
|
|
31
32
|
width: auto;
|
|
32
33
|
transform: translate(calc(100% + var(--gap-48)), 0);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
|
-
.
|
|
36
|
+
.notification__notificationComponent_8t50f.notification__isVisible_8t50f {
|
|
36
37
|
visibility: visible;
|
|
37
38
|
transform: translate(0, 0);
|
|
38
39
|
}
|
|
39
|
-
.
|
|
40
|
+
.notification__notificationComponent_8t50f.notification__isClosing_8t50f {
|
|
40
41
|
transition: transform 0.1s ease-out;
|
|
41
42
|
transform: translate(100vw, 0);
|
|
42
43
|
}
|
|
43
44
|
@media screen and (min-width: 600px) {
|
|
44
|
-
.
|
|
45
|
+
.notification__notificationComponent_8t50f.notification__isClosing_8t50f {
|
|
45
46
|
transform: translate(calc(100% + var(--gap-48)), 0);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
.
|
|
49
|
+
.notification__notificationComponent_8t50f.notification__hasCloser_8t50f {
|
|
50
|
+
padding-right: 52px;
|
|
51
|
+
}
|
|
52
|
+
.notification__notificationComponent_8t50f.notification__notificationComponent_8t50f {
|
|
49
53
|
position: fixed;
|
|
50
54
|
}
|
|
51
55
|
@media screen and (min-width: 600px) {
|
|
52
|
-
.
|
|
56
|
+
.notification__toastContent_8t50f {
|
|
53
57
|
width: var(--notification-desktop-content-width);
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
|
-
.
|
|
60
|
+
.notification__toastContent_8t50f {
|
|
61
|
+
|
|
62
|
+
box-sizing: border-box;
|
|
63
|
+
gap: var(--gap-16);
|
|
64
|
+
}
|
|
65
|
+
.notification__actionSection_8t50f {
|
|
57
66
|
min-width: 104px;
|
|
58
67
|
min-height: 48px;
|
|
59
|
-
padding:
|
|
68
|
+
padding: 0;
|
|
60
69
|
margin: var(--gap-12-neg) var(--gap-0);
|
|
61
70
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './index.css';
|
|
2
2
|
|
|
3
|
-
const styles = {"notificationComponent":"
|
|
3
|
+
const styles = {"notificationComponent":"notification__notificationComponent_8t50f","isVisible":"notification__isVisible_8t50f","isClosing":"notification__isClosing_8t50f","hasCloser":"notification__hasCloser_8t50f","toastContent":"notification__toastContent_8t50f","actionSection":"notification__actionSection_8t50f"};
|
|
4
4
|
|
|
5
5
|
export { styles as default };
|
|
6
6
|
//# sourceMappingURL=index.module.css.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n:root {\n --notification-desktop-content-width: 278px;\n}\n\n.notificationComponent {\n visibility: hidden;\n right: var(--gap-12);\n transform: translate(0, -500px);\n width: calc(100% - var(--gap-24));\n max-width: calc(100vw - var(--gap-24));\n user-select: none;\n transition: transform 0.4s ease-out;\n\n @media screen and (min-width: 600px) {\n right: var(--gap-48);\n width: auto;\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n\n &.isVisible {\n visibility: visible;\n transform: translate(0, 0);\n }\n\n &.isClosing {\n transition: transform 0.1s ease-out;\n transform: translate(100vw, 0);\n\n @media screen and (min-width: 600px) {\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n }\n}\n\n.notificationComponent.notificationComponent {\n position: fixed;\n}\n\n.toastContent {\n @media screen and (min-width: 600px) {\n width: var(--notification-desktop-content-width);\n }\n}\n\n.actionSection {\n min-width: 104px;\n min-height: 48px;\n padding:
|
|
1
|
+
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n:root {\n --notification-desktop-content-width: 278px;\n}\n\n.notificationComponent {\n visibility: hidden;\n right: var(--gap-12);\n transform: translate(0, -500px);\n width: calc(100% - var(--gap-24));\n max-width: calc(100vw - var(--gap-24));\n user-select: none;\n transition: transform 0.4s ease-out;\n border-radius: var(--gap-16);\n\n @media screen and (min-width: 600px) {\n right: var(--gap-48);\n width: auto;\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n\n &.isVisible {\n visibility: visible;\n transform: translate(0, 0);\n }\n\n &.isClosing {\n transition: transform 0.1s ease-out;\n transform: translate(100vw, 0);\n\n @media screen and (min-width: 600px) {\n transform: translate(calc(100% + var(--gap-48)), 0);\n }\n }\n\n &.hasCloser {\n padding-right: 52px;\n }\n}\n\n.notificationComponent.notificationComponent {\n position: fixed;\n}\n\n.toastContent {\n @media screen and (min-width: 600px) {\n width: var(--notification-desktop-content-width);\n }\n\n box-sizing: border-box;\n gap: var(--gap-16);\n}\n\n.actionSection {\n min-width: 104px;\n min-height: 48px;\n padding: 0;\n margin: var(--gap-12-neg) var(--gap-0);\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,uBAAuB,CAAC,2CAA2C,CAAC,WAAW,CAAC,+BAA+B,CAAC,WAAW,CAAC,+BAA+B,CAAC,WAAW,CAAC,+BAA+B,CAAC,cAAc,CAAC,kCAAkC,CAAC,eAAe,CAAC,mCAAmC,CAAC;;;;"}
|
package/moderncssm/Component.js
CHANGED
|
@@ -11,11 +11,14 @@ import { useClickOutside } from './utils/index.js';
|
|
|
11
11
|
import styles from './index.module.css';
|
|
12
12
|
|
|
13
13
|
const notificationClassNameSelector = `.${styles.notificationComponent}`;
|
|
14
|
-
const Notification = forwardRef(({ className, actionSectionClassName, children, visible, offset = 108, hasCloser
|
|
14
|
+
const Notification = forwardRef(({ className, actionSectionClassName, children, visible, offset = 108, hasCloser: legacyHasCloser, autoCloseDelay = 5000, usePortal = true, zIndex = stackingOrder.TOAST, style, position = 'top', onClose, onCloseTimeout, onMouseEnter, onMouseLeave, onClickOutside, containerRef, closerProps = { hasCloser: true }, ...restProps }, ref) => {
|
|
15
15
|
const notificationRef = useRef(null);
|
|
16
16
|
const autoCloseTimeoutRef = useRef(0);
|
|
17
17
|
const closeTimeoutRef = useRef(0);
|
|
18
18
|
const [isClosing, setIsClosing] = useState(false);
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
20
|
+
const { hasCloser: _hasCloser, ...restCloserParams } = closerProps;
|
|
21
|
+
const hasCloser = legacyHasCloser ?? _hasCloser;
|
|
19
22
|
const startAutoCloseTimer = useCallback(() => {
|
|
20
23
|
if (autoCloseDelay !== null) {
|
|
21
24
|
autoCloseTimeoutRef.current = window.setTimeout(() => {
|
|
@@ -84,11 +87,17 @@ const Notification = forwardRef(({ className, actionSectionClassName, children,
|
|
|
84
87
|
React.createElement(ToastPlateDesktop, { className: cn(styles.notificationComponent, {
|
|
85
88
|
[styles.isVisible]: visible,
|
|
86
89
|
[styles.isClosing]: isClosing,
|
|
90
|
+
[styles.hasCloser]: hasCloser,
|
|
87
91
|
}, className), contentClassName: styles.toastContent, actionSectionClassName: cn(actionSectionClassName, styles.actionSection), style: {
|
|
88
92
|
[position]: offset,
|
|
89
93
|
zIndex: computedZIndex,
|
|
90
94
|
...style,
|
|
91
|
-
}, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: mergeRefs([ref, notificationRef]), role: visible ? 'alert' : undefined,
|
|
95
|
+
}, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: mergeRefs([ref, notificationRef]), role: visible ? 'alert' : undefined, onClose: onClose, closerProps: {
|
|
96
|
+
divider: false,
|
|
97
|
+
view: 'secondary',
|
|
98
|
+
hasCloser,
|
|
99
|
+
...restCloserParams,
|
|
100
|
+
}, ...restProps }, children))))));
|
|
92
101
|
});
|
|
93
102
|
Notification.displayName = 'Notification';
|
|
94
103
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser = true,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n hasCloser={hasCloser}\n onClose={onClose}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n forwardRef,\n Fragment,\n type MouseEvent,\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\nimport { useSwipeable } from 'react-swipeable';\nimport cn from 'classnames';\nimport elementClosest from 'element-closest';\n\nimport { Portal } from '@alfalab/core-components-portal';\nimport { Stack } from '@alfalab/core-components-stack';\nimport { stackingOrder } from '@alfalab/core-components-stack-context';\nimport {\n ToastPlateDesktop,\n type ToastPlateDesktopProps,\n} from '@alfalab/core-components-toast-plate/desktop';\n\nimport { useClickOutside } from './utils';\n\nimport styles from './index.module.css';\n\nexport type NotificationProps = ToastPlateDesktopProps & {\n /**\n * Управление видимостью компонента\n */\n visible?: boolean;\n\n /**\n * Отступ от верхнего края\n */\n offset?: number;\n\n /**\n * Время до закрытия компонента\n */\n autoCloseDelay?: number | null;\n\n /**\n * Использовать портал\n */\n usePortal?: boolean;\n\n /**\n * z-index компонента\n */\n zIndex?: number;\n\n /**\n * Позиционирование компонента от верхнего или нижнего края экрана\n */\n position?: 'top' | 'bottom';\n\n /**\n * Обработчик события истечения времени до закрытия компонента\n */\n onCloseTimeout?: () => void;\n\n /**\n * Обработчик события наведения курсора на компонент\n */\n onMouseEnter?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик события снятия курсора с компонента\n */\n onMouseLeave?: (event?: MouseEvent<HTMLDivElement>) => void;\n\n /**\n * Обработчик клика вне компонента\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onClickOutside?: (event?: MouseEvent<any>) => void;\n\n /**\n * Ссылка на контейнер компонента, к которому применяется анимация\n */\n containerRef?: RefObject<HTMLDivElement>;\n};\n\nconst notificationClassNameSelector = `.${styles.notificationComponent}`;\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n actionSectionClassName,\n children,\n visible,\n offset = 108,\n hasCloser: legacyHasCloser,\n autoCloseDelay = 5000,\n usePortal = true,\n zIndex = stackingOrder.TOAST,\n style,\n position = 'top',\n onClose,\n onCloseTimeout,\n onMouseEnter,\n onMouseLeave,\n onClickOutside,\n containerRef,\n closerProps = { hasCloser: true },\n ...restProps\n },\n ref,\n ) => {\n const notificationRef = useRef<HTMLDivElement>(null);\n const autoCloseTimeoutRef = useRef(0);\n const closeTimeoutRef = useRef(0);\n\n const [isClosing, setIsClosing] = useState(false);\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n const { hasCloser: _hasCloser, ...restCloserParams } = closerProps;\n const hasCloser = legacyHasCloser ?? _hasCloser;\n\n const startAutoCloseTimer = useCallback(() => {\n if (autoCloseDelay !== null) {\n autoCloseTimeoutRef.current = window.setTimeout(() => {\n if (onCloseTimeout) {\n onCloseTimeout();\n }\n }, autoCloseDelay);\n }\n }, [autoCloseDelay, onCloseTimeout]);\n\n const stopAutoCloseTimer = useCallback(() => {\n clearTimeout(autoCloseTimeoutRef.current);\n }, []);\n\n useEffect(\n () => () => {\n clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n useEffect(() => {\n elementClosest(window);\n }, []);\n\n useEffect(() => {\n if (visible) {\n startAutoCloseTimer();\n }\n\n return () => {\n stopAutoCloseTimer();\n };\n }, [startAutoCloseTimer, stopAutoCloseTimer, visible]);\n\n const handleMouseEnter = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n\n if (onMouseEnter) {\n onMouseEnter(event);\n }\n },\n [onMouseEnter, stopAutoCloseTimer],\n );\n\n const handleMouseLeave = useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n stopAutoCloseTimer();\n startAutoCloseTimer();\n\n if (onMouseLeave) {\n onMouseLeave(event);\n }\n },\n [onMouseLeave, startAutoCloseTimer, stopAutoCloseTimer],\n );\n\n const handleOutsideClick = useCallback(\n (event: React.MouseEvent | React.TouchEvent) => {\n const isTargetNotification = !!(event.target as Element).closest(\n notificationClassNameSelector,\n );\n\n /*\n * проверка isTargetNotification нужна для предотвращения срабатывания handleOutsideClick\n * при клике на другие нотификации, если их несколько на странице\n */\n if (onClickOutside && visible && !isTargetNotification) {\n onClickOutside(event as React.MouseEvent);\n }\n },\n [onClickOutside, visible],\n );\n\n useClickOutside(notificationRef, handleOutsideClick);\n\n const swipeableHandlers = useSwipeable({\n onSwiped: ({ dir }) => {\n if (onClose && ['Left', 'Right', 'Up'].includes(dir)) {\n setIsClosing(true);\n\n closeTimeoutRef.current = window.setTimeout(() => {\n setIsClosing(false);\n onClose();\n }, 100);\n }\n },\n delta: 100,\n });\n\n const Wrapper = usePortal ? Portal : Fragment;\n\n return (\n <Stack value={zIndex}>\n {(computedZIndex) => (\n <Wrapper>\n <div {...swipeableHandlers} ref={containerRef}>\n <ToastPlateDesktop\n className={cn(\n styles.notificationComponent,\n {\n [styles.isVisible]: visible,\n [styles.isClosing]: isClosing,\n [styles.hasCloser]: hasCloser,\n },\n className,\n )}\n contentClassName={styles.toastContent}\n actionSectionClassName={cn(\n actionSectionClassName,\n styles.actionSection,\n )}\n style={{\n [position]: offset,\n zIndex: computedZIndex,\n ...style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n ref={mergeRefs([ref, notificationRef])}\n role={visible ? 'alert' : undefined}\n onClose={onClose}\n closerProps={{\n divider: false,\n view: 'secondary',\n hasCloser,\n ...restCloserParams,\n }}\n {...restProps}\n >\n {children}\n </ToastPlateDesktop>\n </div>\n </Wrapper>\n )}\n </Stack>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
-moz-user-select: none;
|
|
15
15
|
user-select: none;
|
|
16
16
|
transition: transform 0.4s ease-out;
|
|
17
|
+
border-radius: var(--gap-16);
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
@media screen and (min-width: 600px) {
|
|
@@ -42,6 +43,10 @@
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
.notificationComponent.hasCloser {
|
|
47
|
+
padding-right: 52px;
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
.notificationComponent.notificationComponent {
|
|
46
51
|
position: fixed;
|
|
47
52
|
}
|
|
@@ -53,9 +58,15 @@
|
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
60
|
|
|
61
|
+
.toastContent {
|
|
62
|
+
|
|
63
|
+
box-sizing: border-box;
|
|
64
|
+
gap: var(--gap-16);
|
|
65
|
+
}
|
|
66
|
+
|
|
56
67
|
.actionSection {
|
|
57
68
|
min-width: 104px;
|
|
58
69
|
min-height: 48px;
|
|
59
|
-
padding:
|
|
70
|
+
padding: 0;
|
|
60
71
|
margin: var(--gap-12-neg) var(--gap-0);
|
|
61
72
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfalab/core-components-notification",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.5-alfasans",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"@alfalab/core-components-portal": "5.0.1-alfasans",
|
|
14
14
|
"@alfalab/core-components-shared": "2.1.1-alfasans",
|
|
15
15
|
"@alfalab/core-components-stack": "7.0.1-alfasans",
|
|
16
|
-
"@alfalab/core-components-toast-plate": "9.0
|
|
16
|
+
"@alfalab/core-components-toast-plate": "9.1.0-alfasans",
|
|
17
17
|
"classnames": "^2.5.1",
|
|
18
18
|
"element-closest": "^3.0.2",
|
|
19
19
|
"react-merge-refs": "^1.1.0",
|
package/src/Component.tsx
CHANGED
|
@@ -93,7 +93,7 @@ export const Notification = forwardRef<HTMLDivElement, NotificationProps>(
|
|
|
93
93
|
children,
|
|
94
94
|
visible,
|
|
95
95
|
offset = 108,
|
|
96
|
-
hasCloser
|
|
96
|
+
hasCloser: legacyHasCloser,
|
|
97
97
|
autoCloseDelay = 5000,
|
|
98
98
|
usePortal = true,
|
|
99
99
|
zIndex = stackingOrder.TOAST,
|
|
@@ -105,6 +105,7 @@ export const Notification = forwardRef<HTMLDivElement, NotificationProps>(
|
|
|
105
105
|
onMouseLeave,
|
|
106
106
|
onClickOutside,
|
|
107
107
|
containerRef,
|
|
108
|
+
closerProps = { hasCloser: true },
|
|
108
109
|
...restProps
|
|
109
110
|
},
|
|
110
111
|
ref,
|
|
@@ -115,6 +116,10 @@ export const Notification = forwardRef<HTMLDivElement, NotificationProps>(
|
|
|
115
116
|
|
|
116
117
|
const [isClosing, setIsClosing] = useState(false);
|
|
117
118
|
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
120
|
+
const { hasCloser: _hasCloser, ...restCloserParams } = closerProps;
|
|
121
|
+
const hasCloser = legacyHasCloser ?? _hasCloser;
|
|
122
|
+
|
|
118
123
|
const startAutoCloseTimer = useCallback(() => {
|
|
119
124
|
if (autoCloseDelay !== null) {
|
|
120
125
|
autoCloseTimeoutRef.current = window.setTimeout(() => {
|
|
@@ -219,6 +224,7 @@ export const Notification = forwardRef<HTMLDivElement, NotificationProps>(
|
|
|
219
224
|
{
|
|
220
225
|
[styles.isVisible]: visible,
|
|
221
226
|
[styles.isClosing]: isClosing,
|
|
227
|
+
[styles.hasCloser]: hasCloser,
|
|
222
228
|
},
|
|
223
229
|
className,
|
|
224
230
|
)}
|
|
@@ -236,8 +242,13 @@ export const Notification = forwardRef<HTMLDivElement, NotificationProps>(
|
|
|
236
242
|
onMouseLeave={handleMouseLeave}
|
|
237
243
|
ref={mergeRefs([ref, notificationRef])}
|
|
238
244
|
role={visible ? 'alert' : undefined}
|
|
239
|
-
hasCloser={hasCloser}
|
|
240
245
|
onClose={onClose}
|
|
246
|
+
closerProps={{
|
|
247
|
+
divider: false,
|
|
248
|
+
view: 'secondary',
|
|
249
|
+
hasCloser,
|
|
250
|
+
...restCloserParams,
|
|
251
|
+
}}
|
|
241
252
|
{...restProps}
|
|
242
253
|
>
|
|
243
254
|
{children}
|
package/src/index.module.css
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
max-width: calc(100vw - var(--gap-24));
|
|
13
13
|
user-select: none;
|
|
14
14
|
transition: transform 0.4s ease-out;
|
|
15
|
+
border-radius: var(--gap-16);
|
|
15
16
|
|
|
16
17
|
@media screen and (min-width: 600px) {
|
|
17
18
|
right: var(--gap-48);
|
|
@@ -32,6 +33,10 @@
|
|
|
32
33
|
transform: translate(calc(100% + var(--gap-48)), 0);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
|
|
37
|
+
&.hasCloser {
|
|
38
|
+
padding-right: 52px;
|
|
39
|
+
}
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
.notificationComponent.notificationComponent {
|
|
@@ -42,11 +47,14 @@
|
|
|
42
47
|
@media screen and (min-width: 600px) {
|
|
43
48
|
width: var(--notification-desktop-content-width);
|
|
44
49
|
}
|
|
50
|
+
|
|
51
|
+
box-sizing: border-box;
|
|
52
|
+
gap: var(--gap-16);
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
.actionSection {
|
|
48
56
|
min-width: 104px;
|
|
49
57
|
min-height: 48px;
|
|
50
|
-
padding:
|
|
58
|
+
padding: 0;
|
|
51
59
|
margin: var(--gap-12-neg) var(--gap-0);
|
|
52
60
|
}
|