@gravity-ui/uikit
Version:
Gravity UI base styling and components
61 lines (60 loc) • 3.1 kB
JavaScript
'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