Files
tnsu-ui-kit/src/ConfirmDialog/confirmModal.ts
T
2026-08-13 14:53:11 +05:00

45 lines
2.2 KiB
TypeScript

// Императивный вызов модалки подтверждения из любого места (в т.ч. из обычных
// модулей вроде shared/unsavedChanges.ts, где нет React-контекста).
//
// Модалка живёт в React-дереве (ConfirmHost, монтируется один раз в
// RequestPortal). Здесь — только «мостик»: confirmModal(...) отдаёт промис,
// который резолвится, когда пользователь нажмёт «Продолжить»/«Отмена».
export interface IConfirmOptions {
/** Заголовок окна. */
title?: string;
/** Основной текст-вопрос. */
message: string;
/** Подпись подтверждающей кнопки. По умолчанию — «Продолжить». */
confirmText?: string;
/** Подпись кнопки отмены. По умолчанию — «Отмена». */
cancelText?: string;
/** Опасное действие (потеря данных) — подтверждающая кнопка красная. */
danger?: boolean;
}
type ConfirmHandler = (opts: IConfirmOptions, resolve: (ok: boolean) => void) => void;
// Единственный подписчик — смонтированный ConfirmHost. Больше одного окна
// подтверждения одновременно нам не нужно.
let handler: ConfirmHandler | undefined;
export function registerConfirmHost(fn: ConfirmHandler): () => void {
handler = fn;
return () => {
if (handler === fn) handler = undefined;
};
}
/**
* Показать модальное подтверждение. Промис резолвится в true («Продолжить») или
* false («Отмена»/Esc/клик по фону). Если хост почему-то не смонтирован —
* падаем на нативный confirm, чтобы не потерять защиту от потери данных.
*/
export function confirmModal(opts: IConfirmOptions): Promise<boolean> {
if (!handler) {
return Promise.resolve(window.confirm(opts.message));
}
return new Promise<boolean>((resolve) => handler!(opts, resolve));
}