Files
oldboy/src/lib/components/ui/Modal.svelte
2025-10-15 16:52:39 +02:00

79 lines
1.5 KiB
Svelte

<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
visible?: boolean;
title?: string;
onClose?: () => void;
children: Snippet;
}
let { visible = $bindable(false), title = '', onClose, children }: Props = $props();
function handleBackdropClick(e: MouseEvent) {
if (e.target === e.currentTarget) {
close();
}
}
function close() {
visible = false;
onClose?.();
}
</script>
{#if visible}
<div class="modal-backdrop" onclick={handleBackdropClick} role="dialog" tabindex="-1">
<div class="modal-content">
{#if title}
<div class="modal-header">
<h3>{title}</h3>
</div>
{/if}
<div class="modal-body">
{@render children()}
</div>
</div>
</div>
{/if}
<style>
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-content {
background-color: var(--color-surface-3);
border: 1px solid var(--color-border-default);
min-width: 300px;
max-width: 500px;
max-height: 80vh;
overflow: auto;
}
.modal-header {
padding: var(--space-lg) var(--space-xl);
border-bottom: 1px solid var(--color-border-default);
}
.modal-header h3 {
margin: 0;
color: var(--color-text-primary);
font-size: var(--font-lg);
font-weight: 600;
}
.modal-body {
padding: var(--space-xl);
}
</style>