115 lines
2.4 KiB
Svelte

<script lang="ts">
export let open = false;
export let title = "";
export let message = "";
export let confirmText = "OK";
export let cancelText = "Cancel";
export let showCancel = false;
export let tone: "default" | "danger" = "default";
export let onConfirm: () => void = () => {};
export let onCancel: () => void = () => {};
function handleConfirm() {
onConfirm();
}
function handleCancel() {
onCancel();
}
function handleWindowKeydown(event: KeyboardEvent) {
if (!open) return;
if (event.key === "Escape") {
handleCancel();
}
}
</script>
<svelte:window on:keydown={handleWindowKeydown} />
{#if open}
<div class="modal-backdrop">
<dialog class="modal" open aria-label={title}>
<header class="modal-header">
<h2>{title}</h2>
</header>
<p class="modal-message">{message}</p>
<div class="modal-actions">
{#if showCancel}
<button type="button" class="secondary" on:click={handleCancel}>{cancelText}</button>
{/if}
<button type="button" class:danger={tone === "danger"} on:click={handleConfirm}>
{confirmText}
</button>
</div>
</dialog>
</div>
{/if}
<style>
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(7, 9, 12, 0.6);
backdrop-filter: blur(2px);
display: grid;
place-items: center;
z-index: 1000;
padding: 16px;
}
.modal {
margin: 0;
width: min(420px, 100%);
border-radius: 12px;
border: 1px solid var(--border-strong);
background: var(--surface-1);
box-shadow: 0 18px 46px rgba(0, 0, 0, 0.45);
padding: 14px;
display: flex;
flex-direction: column;
gap: 10px;
}
.modal-header h2 {
font-size: 0.98rem;
color: var(--text-primary);
}
.modal-message {
color: var(--text-muted);
font-size: 0.86rem;
line-height: 1.45;
}
.modal-actions {
margin-top: 2px;
display: flex;
justify-content: flex-end;
gap: 8px;
}
.modal-actions button {
border-radius: 7px;
border: 1px solid var(--border-soft);
color: var(--text-primary);
background: var(--surface-2);
padding: 6px 11px;
font-size: 0.8rem;
cursor: pointer;
}
.modal-actions button.secondary {
background: var(--surface-1);
color: var(--text-muted);
}
.modal-actions button.danger {
border-color: var(--border-strong);
background: var(--surface-3);
color: var(--text-primary);
}
</style>