86 lines
2.1 KiB
Svelte
86 lines
2.1 KiB
Svelte
<script lang="ts">
|
|
type Position =
|
|
| 'top-start'
|
|
| 'top-center'
|
|
| 'top-end'
|
|
| 'middle-start'
|
|
| 'middle-center'
|
|
| 'middle-end'
|
|
| 'bottom-start'
|
|
| 'bottom-center'
|
|
| 'bottom-end';
|
|
|
|
type AlertType = 'info' | 'success' | 'warning' | 'error';
|
|
|
|
let props = $props();
|
|
|
|
let message = props.message || '';
|
|
let type = (props.type as AlertType) || 'info';
|
|
let position = (props.position as Position) || 'bottom-end';
|
|
let duration = props.duration || 3000;
|
|
let showClose = props.showClose || false;
|
|
|
|
// Create a new object without the known props
|
|
let restProps = { ...props };
|
|
delete restProps.message;
|
|
delete restProps.type;
|
|
delete restProps.position;
|
|
delete restProps.duration;
|
|
delete restProps.showClose;
|
|
|
|
let visible = $state(true);
|
|
|
|
// Map position prop to DaisyUI classes
|
|
const getPositionClasses = (pos: Position): string => {
|
|
const [vertical, horizontal] = pos.split('-');
|
|
|
|
let classes = 'toast';
|
|
|
|
// Vertical position
|
|
if (vertical === 'top') classes += ' toast-top';
|
|
if (vertical === 'middle') classes += ' toast-middle';
|
|
// bottom is default, no class needed
|
|
|
|
// Horizontal position
|
|
if (horizontal === 'start') classes += ' toast-start';
|
|
if (horizontal === 'center') classes += ' toast-center';
|
|
if (horizontal === 'end') classes += ' toast-end';
|
|
|
|
return classes;
|
|
};
|
|
|
|
// Auto-hide the toast after duration
|
|
if (duration > 0) {
|
|
setTimeout(() => {
|
|
visible = false;
|
|
}, duration);
|
|
}
|
|
|
|
const closeToast = () => {
|
|
visible = false;
|
|
};
|
|
</script>
|
|
|
|
{#if visible}
|
|
<div class={getPositionClasses(position)} {...restProps}>
|
|
<div class="alert alert-{type}">
|
|
<span>{message}</span>
|
|
{#if showClose}
|
|
<button class="btn btn-circle btn-xs" onclick={closeToast}>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-4 w-4"
|
|
viewBox="0 0 20 20"
|
|
fill="currentColor"
|
|
>
|
|
<path
|
|
fill-rule="evenodd"
|
|
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
|
clip-rule="evenodd"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
{/if}
|