Files
meshtastic-web/apps/web/src/components/Dialog/useDialog.ts
T
AustinandGitHub d2cb51d489 Execute oxfmt (#1166)
Ran
pnpm oxfmt .

This should get the web repo aligned so that we can better enforce oxfmt going forward.
2026-06-16 20:30:08 -04:00

119 lines
2.7 KiB
TypeScript

import { type ReactNode, useCallback, useState } from "react";
import type { useTranslation } from "react-i18next";
export type DialogType = "confirm" | "alert" | "info" | "custom";
export interface BaseDialogConfig {
type: DialogType;
title: string;
description?: string;
onConfirm?: () => void | Promise<void>;
onCancel?: () => void;
onClose?: () => void;
}
export interface ConfirmDialogConfig extends BaseDialogConfig {
type: "confirm";
confirmText?: string;
cancelText?: string;
variant?: "default" | "destructive";
icon?: ReactNode;
confirmIcon?: ReactNode;
onConfirm: () => void | Promise<void>;
}
export interface AlertDialogConfig extends BaseDialogConfig {
type: "alert";
dismissText?: string;
icon?: ReactNode;
}
export interface InfoDialogConfig extends BaseDialogConfig {
type: "info";
dismissText?: string;
icon?: ReactNode;
}
export interface CustomDialogConfig extends BaseDialogConfig {
type: "custom";
icon?: React.ReactNode;
content: ReactNode;
footerActions?: ReactNode;
}
export type DialogConfig =
| ConfirmDialogConfig
| AlertDialogConfig
| InfoDialogConfig
| CustomDialogConfig;
export interface DialogState {
isOpen: boolean;
config?: DialogConfig;
}
export interface UseDialogReturn {
isOpen: boolean;
config?: DialogConfig;
openDialog: (config: DialogConfig) => void;
closeDialog: () => void;
handleConfirm: () => void;
handleCancel: () => void;
}
export const useDialog = (initialState?: DialogState): UseDialogReturn => {
const [state, setState] = useState<DialogState>(
initialState ?? { isOpen: false },
);
const openDialog = useCallback((config: DialogConfig) => {
setState({ isOpen: true, config });
}, []);
const closeDialog = useCallback(() => {
state.config?.onClose?.();
setState({ isOpen: false, config: undefined });
}, [state.config]);
const handleConfirm = useCallback(async () => {
if (state.config?.onConfirm) {
await state.config.onConfirm();
}
closeDialog();
}, [state.config, closeDialog]);
const handleCancel = useCallback(() => {
state.config?.onCancel?.();
closeDialog();
}, [state.config, closeDialog]);
return {
isOpen: state.isOpen,
config: state.config,
openDialog,
closeDialog,
handleConfirm,
handleCancel,
};
};
export const getDefaultTexts = (
type: DialogType,
t: ReturnType<typeof useTranslation>["t"],
) => {
switch (type) {
case "confirm":
return {
confirmText: t("button.confirm"),
cancelText: t("button.cancel"),
};
case "alert":
case "info":
return {
dismissText: t("button.dismiss"),
};
default:
return {};
}
};