Toasts

The agnostic-astro package utilizes XElement under-the-hood in order to provide build-time Astro components. These build-time components will help your project get closer to realizing a mostly no client-side runtime…if you do it right, this should mean an all-green 100% Lighthouse performance score! Leverage the benefits of Islands architecture by sending mostly server built agnostic-astro components. Then, sprinkle client-hydrated ones only as needed.

Usage

Ensure you've installed and setup the AgnosticUI Astro integration which will import the required common.min.css onto your page:

npm i astro-agnosticui

Then add the integration to your astro.config.mjs (you may need to run Astro with experimental integrations flag astro dev --experimental-integrations):

import { defineConfig } from 'astro/config';
import agnosticAstro from 'astro-agnosticui';;
export default defineConfig({
  integrations: [agnosticAstro()]
});

Then you can import Astro Toast components:

import AgToasts from 'agnostic-astro/Toasts.astro';
import AgToast from 'agnostic-astro/Toast.astro';

Here's the agnostic-astro Toast component in use:

<AgToasts
  portalRootSelector="body"
  horizontalPosition="end"
  verticalPosition="top"
>
  <AgToast isOpen type="dark">
    <ToastIconExample type="dark" utilityClasses="mie8" />
    <p>This is a success toast message</p>
  </AgToast>
  <div class="mbe14" />
  <AgToast isOpen type="info">
    <ToastIconExample type="info" utilityClasses="mie8" />
    <p>This is a information toast message</p>
  </AgToast>
  <div class="mbe14" />
  <AgToast isOpen type="warning">
    <ToastIconExample type="warning" utilityClasses="mie8" />
    <p>This is a warning toast message</p>
  </AgToast>
</AgToasts>
<AgToasts
  portalRootSelector="body"
  horizontalPosition="center"
  verticalPosition="top"
>
  <AgToast id="infoToast" type="info">
    <ToastIconExample type="info" utilityClasses="mie8" />
    <p class="flex-fill">Success toast message that's closable</p>
    <AgClose
      color="var(--agnostic-primary-dark)"
      @click={(e) => {
        const toast = e.target.closest('#infoToast')
        toast.classList.add('hidden');
      }}
    />
  </AgToast>
  <div class="mbe14" />
  <AgToast id="successToast" type="success">
    <ToastIconExample type="success" utilityClasses="mie8" />
    <p class="flex-fill">Information toast message that's closable</p>
    <AgClose
      color="var(--agnostic-action-dark)"
      @click={(e) => {
        const toast = e.target.closest('#successToast')
        toast.classList.add('hidden');
      }}
    />
  </AgToast>
</AgToasts>
<AgToasts
  portalRootSelector="body"
  horizontalPosition="center"
  verticalPosition="bottom"
>
  <AgToast id="dismissMe" isOpen type="warning">
    <ToastIconExample type="warning" utilityClasses="mie8" />
    <p>This is an warning that will dismiss after 5 seconds</p>
  </AgToast>
  <div class="mbe14" />
  <AgToast id="dismissMe2" isOpen type="error">
    <ToastIconExample type="error" utilityClasses="mie8" />
    <p>This is an error that will dismiss after 5 seconds</p>
  </AgToast>
</AgToasts>
...and so on
<script is:inline>
setTimeout(() => {
  document.getElementById('dismissMe').classList.add('hidden');
  document.getElementById('dismissMe2').classList.add('hidden');
}, 5000);
</script>

This is a toast message

This is a information toast message

This is a warning toast message

Success toast message that's closable

Information toast message that's closable

This is an warning that will dismiss after 5 seconds

This is an error that will dismiss after 5 seconds