Kazkadien logo Kazkadien

Toast

Svelte

<script>
  let toasts = [{ type: 'danger', mes: 'Some message ' + Math.random() }]
</script>

{#each toasts as el, idx (el.mes)}
<Toast
  accent="{el.type}"
  closable
  autoclose
  on:close="{() => (toasts = toasts.filter((_, i) => i !== idx))}"
>
  <p>{el.mes}</p>
</Toast>
{/each}
<!-- With a default slot -->
<Toast>
  <p style="display: flex; gap: 1ch;">
    <Icon name="info" />
    <b>Error</b>
  </p>
  <p>I am a toast</p>
</Toast>
<!-- Or with props -->
<Toast iconName="info" title="Error" body="I am a toast" />

First item at bottom, last - at top. If closable=false (no close btn), then autoclose defaults to 5000ms

HTML

<!-- "teleport" to #toasts-container -->
<div class="toast [accent]">
  <div class="toast-body">
    <div class="toast-content">
      <p>Message ...</p>
    </div>

    <div class="toast-close">
      <button class="btn base icon-only">
        <svg height="24px" width="24px" viewBox="0 0 24 24" fill="currentColor">
          <use href="#close"></use>
        </svg>
      </button>
    </div>
  </div>
</div>

Customize CSS

#toasts-container {
  --toast-container-max-width: 80ch;
  --gap-between-toasts: 1rem;

  --toast-border-radius: 0.33rem;
  --toast-padding: 1.25rem;
  --toast-opacity: 0.85;
  --toast-opacity-on-hover: 1;

  --toast-progress-bar-width: 2px;
}

Play