hss-pos / frontend /src /lib /components /Modal.svelte
sashank1989
feat: make all pages mobile-responsive
2bed403
Raw
History Blame Contribute Delete
1.59 kB
<script>
let {
show = false,
title = '',
size = 'md',
onclose = () => {},
children
} = $props();
const sizes = {
sm: 'max-w-sm',
md: 'max-w-lg',
lg: 'max-w-2xl',
xl: 'max-w-4xl',
full: 'max-w-6xl'
};
function handleBackdrop(e) {
if (e.target === e.currentTarget) {
onclose();
}
}
function handleKeydown(e) {
if (e.key === 'Escape') onclose();
}
</script>
<svelte:window onkeydown={handleKeydown} />
{#if show}
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm p-4"
onclick={handleBackdrop}
role="dialog"
aria-modal="true"
>
<div class="card w-full {sizes[size]} max-h-[90vh] flex flex-col animate-in">
{#if title}
<div class="flex items-center justify-between px-6 py-4 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-800">{title}</h2>
<button
onclick={onclose}
class="text-gray-400 hover:text-gray-700 transition-colors p-2 rounded-lg hover:bg-gray-100"
>
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
{/if}
<div class="px-6 py-4 overflow-y-auto flex-1">
{@render children?.()}
</div>
</div>
</div>
{/if}
<style>
.animate-in {
animation: modal-in 0.2s ease-out;
}
@keyframes modal-in {
from {
opacity: 0;
transform: scale(0.95) translateY(10px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
</style>