'use client'; import * as React from 'react'; import { Icon20Cancel } from '@vkontakte/icons'; import { classNames, hasReactNode, noop } from '@vkontakte/vkjs'; import { useAdaptivityWithJSMediaQueries } from '../../hooks/useAdaptivityWithJSMediaQueries'; import { usePlatform } from '../../hooks/usePlatform'; import { useCSSKeyframesAnimationController } from '../../lib/animation'; import { stopPropagation } from '../../lib/utils'; import { FocusTrap } from '../FocusTrap/FocusTrap'; import { IconButton } from '../IconButton/IconButton'; import { ModalDismissButton } from '../ModalDismissButton/ModalDismissButton'; import { type AlertActionInterface, type AlertProps } from './Alert'; import { AlertActions } from './AlertActions'; import { AlertDescription, AlertTitle } from './AlertTypography'; import styles from './Alert.module.css'; export interface AlertBaseProps extends Omit { /** * Флаг, определяющий состояние закрытия модального окна. * Когда установлен в true, запускает анимацию закрытия окна. */ closing?: boolean; /** * Функция обратного вызова для управления состоянием закрытия модального окна. * Принимает булево значение, которое определяет, находится ли окно в процессе закрытия. */ setClosing?: (closing: boolean) => void; } export const AlertBase = ({ actions, actionsLayout = 'horizontal', children, title, description, onClose, dismissLabel = 'Закрыть предупреждение', renderAction, actionsAlign, dismissButtonMode = 'outside', dismissButtonTestId, onClick, allowClickPropagation = false, titleTestId, descriptionTestId, closing, setClosing, ...restProps }: AlertBaseProps) => { const generatedId = React.useId(); const titleId = `vkui-alert-${generatedId}-title`; const descriptionId = `vkui-alert-${generatedId}-description`; const platform = usePlatform(); const { isDesktop } = useAdaptivityWithJSMediaQueries(); const itemActionCallbackRef = React.useRef(noop); const [animationState, animationHandlers] = useCSSKeyframesAnimationController( closing ? 'exit' : 'enter', { onExited() { itemActionCallbackRef.current(); itemActionCallbackRef.current = noop; onClose(); }, }, ); const isDismissButtonVisible = isDesktop && platform !== 'ios'; const elementRef = React.useRef(null); const close = React.useCallback(() => { setClosing?.(true); }, [setClosing]); const onItemClick = React.useCallback( (item: AlertActionInterface) => { const { action: itemAction, autoCloseDisabled = false } = item; if (autoCloseDisabled) { itemAction && itemAction({ close }); } else { if (itemAction) { itemActionCallbackRef.current = itemAction; } setClosing?.(true); } }, [close, setClosing], ); const handleClick = allowClickPropagation ? onClick : (event: React.MouseEvent) => { stopPropagation(event); onClick?.(event); }; return (
{hasReactNode(title) && ( {title} )} {hasReactNode(description) && ( {description} )} {children} {isDismissButtonVisible && dismissButtonMode === 'inside' && ( )}
{isDismissButtonVisible && dismissButtonMode === 'outside' && ( {dismissLabel} )}
); };