You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.3 KiB
74 lines
2.3 KiB
<script lang="ts">
|
|
/**
|
|
* Eidos auto-mount `<Toaster>` — the ergonomic 90 % case.
|
|
*
|
|
* <Toaster {toaster} position="top-right" />
|
|
*
|
|
* Mounts Provider + Viewport + Item-loop with a default item template
|
|
* (status disc fed by `<IntentIcon>`, title, description, action,
|
|
* close). For exotic shapes — custom card layout, multiple toasters,
|
|
* compound trees in different DOM subtrees — the consumer drops down
|
|
* to `<Toast> / <Toast.Viewport> / <Toast.Item>` directly.
|
|
*
|
|
* The intent → glyph mapping lives in
|
|
* `$uix/eidos/components/icon/intent.ts` so any other surface that
|
|
* needs intent icons (Dialog, Field, Banner) reads from the same
|
|
* doctrinal source.
|
|
*/
|
|
import ToastComponent from './toast.svelte';
|
|
import Viewport from './toast-viewport.svelte';
|
|
import Item from './toast-item.svelte';
|
|
import Status from './toast-status.svelte';
|
|
import Main from './toast-main.svelte';
|
|
import Title from './toast-title.svelte';
|
|
import Description from './toast-description.svelte';
|
|
import Action from './toast-action.svelte';
|
|
import Close from './toast-close.svelte';
|
|
import IntentIcon from '$uix/eidos/components/icon/intent-icon.svelte';
|
|
import type { ToasterProps } from './types';
|
|
|
|
let {
|
|
toaster,
|
|
position = 'bottom-right',
|
|
gap,
|
|
label,
|
|
children
|
|
}: ToasterProps = $props();
|
|
</script>
|
|
|
|
<ToastComponent {toaster} {label}>
|
|
<Viewport {position} {gap}>
|
|
{#each toaster.toasts as item (item.id)}
|
|
<Item toast={item}>
|
|
{#if children}
|
|
{@render children({ item })}
|
|
{:else}
|
|
<Status>
|
|
<IntentIcon intent={item.intent} loading={item.loading} size="sm" />
|
|
</Status>
|
|
|
|
<Main>
|
|
{#if item.title}
|
|
<Title>{item.title}</Title>
|
|
{/if}
|
|
{#if item.description}
|
|
<Description>{item.description}</Description>
|
|
{/if}
|
|
{#if item.action}
|
|
<Action altText={item.action.label} onclick={item.action.onClick}>
|
|
{item.action.label}
|
|
</Action>
|
|
{/if}
|
|
</Main>
|
|
|
|
<!-- ToastCloseProvider's onclick already routes through
|
|
runtime.trigger('emerge-dismiss') so Sema fires before the
|
|
toast leaves. Passing our own onclick here would race
|
|
ahead via mergeProps' handler composition. -->
|
|
<Close />
|
|
{/if}
|
|
</Item>
|
|
{/each}
|
|
</Viewport>
|
|
</ToastComponent>
|