126 lines
2.9 KiB
Svelte
126 lines
2.9 KiB
Svelte
<script lang="ts">
|
|
import { Info, X } from 'lucide-svelte';
|
|
|
|
interface Props {
|
|
open: boolean;
|
|
title?: string;
|
|
message: string;
|
|
buttonText?: string;
|
|
onClose: () => void;
|
|
}
|
|
|
|
let {
|
|
open = $bindable(false),
|
|
title = 'Atenção',
|
|
message,
|
|
buttonText = 'OK',
|
|
onClose
|
|
}: Props = $props();
|
|
|
|
function handleClose() {
|
|
open = false;
|
|
onClose();
|
|
}
|
|
</script>
|
|
|
|
{#if open}
|
|
<div
|
|
class="pointer-events-none fixed inset-0 z-[9999]"
|
|
style="animation: fadeIn 0.2s ease-out;"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby="modal-alert-title"
|
|
>
|
|
<!-- Backdrop -->
|
|
<div
|
|
class="pointer-events-auto absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity duration-200"
|
|
onclick={handleClose}
|
|
></div>
|
|
|
|
<!-- Modal Box -->
|
|
<div
|
|
class="bg-base-100 pointer-events-auto absolute left-1/2 top-1/2 z-10 flex max-h-[90vh] w-full max-w-md transform -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-2xl shadow-2xl transition-all duration-300"
|
|
style="animation: slideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);"
|
|
onclick={(e) => e.stopPropagation()}
|
|
>
|
|
<!-- Header -->
|
|
<div
|
|
class="border-base-300 from-info/10 to-info/5 flex flex-shrink-0 items-center justify-between border-b bg-linear-to-r px-6 py-4"
|
|
>
|
|
<h2 id="modal-alert-title" class="text-info flex items-center gap-2 text-xl font-bold">
|
|
<Info class="h-6 w-6" strokeWidth={2.5} />
|
|
{title}
|
|
</h2>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm btn-circle btn-ghost hover:bg-base-300"
|
|
onclick={handleClose}
|
|
aria-label="Fechar"
|
|
>
|
|
<X class="h-5 w-5" />
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="modal-scroll flex-1 overflow-y-auto px-6 py-6">
|
|
<p class="text-base-content text-base leading-relaxed">{message}</p>
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<div class="border-base-300 flex flex-shrink-0 justify-end border-t px-6 py-4">
|
|
<button class="btn btn-primary" onclick={handleClose}>{buttonText}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
|
|
<style>
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes slideUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translate(-50%, -40%) scale(0.95);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translate(-50%, -50%) scale(1);
|
|
}
|
|
}
|
|
|
|
/* Scrollbar customizada */
|
|
:global(.modal-scroll) {
|
|
scrollbar-width: thin;
|
|
scrollbar-color: hsl(var(--bc) / 0.3) transparent;
|
|
scroll-behavior: smooth;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
:global(.modal-scroll::-webkit-scrollbar) {
|
|
width: 8px;
|
|
}
|
|
|
|
:global(.modal-scroll::-webkit-scrollbar-track) {
|
|
background: transparent;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
:global(.modal-scroll::-webkit-scrollbar-thumb) {
|
|
background-color: hsl(var(--bc) / 0.3);
|
|
border-radius: 4px;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
:global(.modal-scroll::-webkit-scrollbar-thumb:hover) {
|
|
background-color: hsl(var(--bc) / 0.5);
|
|
}
|
|
</style>
|
|
|