UNPKG

@gravity-ui/uikit

Version:

Gravity UI base styling and components

61 lines (60 loc) 3.1 kB
'use client'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from 'react'; import { CircleCheck, CircleInfo, Thunderbolt, TriangleExclamation, Xmark } from '@gravity-ui/icons'; import { useCloseOnTimeout } from "../../../hooks/private/index.js"; import { Button } from "../../Button/index.js"; import { Icon } from "../../Icon/index.js"; import { block } from "../../utils/cn.js"; import i18n from "../i18n/index.js"; import "./Toast.css"; const b = block('toast'); const DEFAULT_TIMEOUT = 5000; const TITLE_ICONS = { normal: null, info: CircleInfo, success: CircleCheck, warning: TriangleExclamation, danger: TriangleExclamation, utility: Thunderbolt, }; function renderActions({ actions, onClose }) { if (!actions || !actions.length) { return null; } return (_jsx("div", { className: b('actions'), children: actions.map(({ label, onClick, view = 'outlined', removeAfterClick = true }, index) => { const onActionClick = () => { onClick(); if (removeAfterClick) { onClose(); } }; return (_jsx(Button, { className: b('action'), onClick: onActionClick, type: "button", size: "l", view: view, width: "auto", children: label }, `${label}__${index}`)); }) })); } function renderIconByType({ theme }) { if (!theme || !TITLE_ICONS[theme]) { return null; } return _jsx(Icon, { data: TITLE_ICONS[theme], size: 20, className: b('icon', { [theme]: true }) }); } export const Toast = React.forwardRef(function Toast(props, ref) { const { name, content, actions, title, className, theme = 'normal', renderIcon, autoHiding: timeoutProp = DEFAULT_TIMEOUT, isClosable = true, mobile = false, onClose, removeCallback, } = props; const handleClose = React.useCallback(() => { removeCallback(name); if (onClose) { onClose(); } }, [removeCallback, onClose, name]); const timeout = typeof timeoutProp === 'number' ? timeoutProp : undefined; const closeOnTimeoutProps = useCloseOnTimeout({ onClose: handleClose, timeout }); const mods = { mobile, theme, }; const hasTitle = Boolean(title); const hasContent = Boolean(content); const icon = renderIcon ? renderIcon(props) : renderIconByType({ theme }); return (_jsxs("div", { ref: ref, className: b(mods, className), ...closeOnTimeoutProps, "data-toast": true, children: [icon && _jsx("div", { className: b('icon-container'), children: icon }), _jsxs("div", { className: b('container'), children: [hasTitle && _jsx("h3", { className: b('title'), children: title }), isClosable && (_jsx(Button, { size: "s", view: "flat", className: b('btn-close'), onClick: handleClose, "aria-label": i18n('label_close-button'), children: _jsx(Icon, { data: Xmark }) })), hasContent && (_jsx("div", { className: b('content', { 'without-title': !hasTitle }), children: content })), renderActions({ actions, onClose: handleClose })] })] })); }); //# sourceMappingURL=Toast.js.map