Phi
Toast
@dicehub/phiv1.0.0-beta.1

Toast

A notification system for displaying brief, non-intrusive messages to users.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      @click="toastManager.add({
        title: 'Toast created',
        description: 'This is a toast notification.',
      })"
    >
      Show toast
    </Button>
  </Toasty>
</template>

Installation

Barrel

import { Toasty, createPhiToastManager, usePhiToastManager } from "@dicehub/phi";

Granular

import { Toasty, createPhiToastManager, usePhiToastManager } from "@dicehub/phi/components/toast";

Usage

The toast system consists of the Toasty provider component and a toast manager. UseusePhiToastManager() from provider descendants, or pass a manager fromcreatePhiToastManager() when dispatching outside the provider tree.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      @click="toastManager.add({
        title: 'Success!',
        description: 'Your changes have been saved.',
      })"
    >
      Save changes
    </Button>
  </Toasty>
</template>

Setup

Wrap your application or a section of it with the Toasty provider. This sets up the toast context and renders the toast viewport.

<script setup>
import { Toasty } from "@dicehub/phi/components/toast";
</script>

<template>
  <Toasty>
    <App />
  </Toasty>
</template>

Examples

Title and Description

A complete toast with both title and description.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      @click="toastManager.add({
        title: 'Toast created',
        description: 'This is a toast notification.',
      })"
    >
      Show toast
    </Button>
  </Toasty>
</template>

Title Only

A simple toast with just a title for brief messages.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button @click="toastManager.add({ title: 'Settings saved' })">
      Title only
    </Button>
  </Toasty>
</template>

Description Only

A toast with only a description for more detailed messages.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      @click="toastManager.add({
        description: 'Your changes have been saved successfully.',
      })"
    >
      Description only
    </Button>
  </Toasty>
</template>

Success Variant

Use the success variant for confirmations and positive outcomes.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      variant="primary"
      @click="toastManager.add({
        title: 'Deployed successfully',
        description: 'Your Worker is now live.',
        variant: 'success',
      })"
    >
      Deploy Worker
    </Button>
  </Toasty>
</template>

Multiple Toasts

Multiple toasts stack and animate smoothly. Hover over the stack to expand them.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();

const showMultipleToasts = () => {
  toastManager.add({
    title: 'First toast',
    description: 'This is the first notification.',
  });

  setTimeout(() => {
    toastManager.add({
      title: 'Second toast',
      description: 'This is the second notification.',
    });
  }, 500);

  setTimeout(() => {
    toastManager.add({
      title: 'Third toast',
      description: 'This is the third notification.',
    });
  }, 1000);
};
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button @click="showMultipleToasts">Show multiple toasts</Button>
  </Toasty>
</template>

Error Variant

Use the error variant for critical issues that need attention.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      @click="toastManager.add({
        title: 'Deployment failed',
        description: 'Unable to connect to the server.',
        variant: 'error',
      })"
    >
      Show error toast
    </Button>
  </Toasty>
</template>

Warning Variant

Use the warning variant for cautionary messages.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      @click="toastManager.add({
        title: 'Rate limit warning',
        description: 'You\'re approaching your API quota.',
        variant: 'warning',
      })"
    >
      Show warning toast
    </Button>
  </Toasty>
</template>

Info Variant

Use the info variant for neutral informational messages.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      @click="toastManager.add({
        title: 'New version available',
        description: 'Phi v4.2 includes performance improvements.',
        variant: 'info',
      })"
    >
      Show info toast
    </Button>
  </Toasty>
</template>

Custom Content

Use the content prop to render completely custom toast content.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Link } from "@dicehub/phi/components/link";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";
import { PhCheckCircle } from "@phosphor-icons/vue";
import { defineComponent, h } from "vue";

const toastManager = createPhiToastManager();

const CustomToastContent = defineComponent({
  setup() {
    return () =>
      h("div", { class: "toast-demo-custom-content" }, [
        h(PhCheckCircle, { weight: "fill" }),
        h(Link, { href: "/" }, () => "my-first-worker"),
        " created!",
      ]);
  },
});
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button @click="toastManager.add({ content: CustomToastContent })">
      Show custom content
    </Button>
  </Toasty>
</template>

Action Buttons

Add action buttons to toasts for user interaction.

<script setup>
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button
      @click="toastManager.add({
        title: 'Need help?',
        description: 'Get assistance with your deployment.',
        actions: [
          { children: 'Support', variant: 'secondary' },
          { children: 'Ask AI', variant: 'primary' },
        ],
      })"
    >
      Show with actions
    </Button>
  </Toasty>
</template>

Promise

Use the promise method to show loading, success, and error states automatically.

<script setup lang="ts">
import { Button } from "@dicehub/phi/components/button";
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";

const toastManager = createPhiToastManager();

const simulateDeployment = () =>
  new Promise<{ name: string }>((resolve, reject) => {
    setTimeout(() => {
      if (Math.random() > 0.3) {
        resolve({ name: "my-worker" });
      } else {
        reject(new Error("Network error"));
      }
    }, 2000);
  });

const deploy = () => {
  toastManager.promise(simulateDeployment(), {
    loading: {
      title: "Deploying...",
      description: "Please wait while we deploy your Worker.",
    },
    success: (data) => ({
      title: "Deployed!",
      description: `Worker "${data.name}" is now live.`,
    }),
    error: (err) => ({
      title: "Deployment failed",
      description: err.message,
      variant: "error",
    }),
  });
};
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button @click="deploy">Deploy with promise</Button>
  </Toasty>
</template>

Update a Toast

Pass a callback to update() to derive the next options from the current toast, for example replacing a pending title with the result.

<script setup lang="ts">
import { Toasty, createPhiToastManager } from "@dicehub/phi/components/toast";
import { Button } from "@dicehub/phi/components/button";

const toastManager = createPhiToastManager();

const saveChanges = () => {
  const id = toastManager.add({ title: "Saving changes...", timeout: 0 });

  globalThis.setTimeout(() => {
    toastManager.update(id, (toast) => ({
      title: "Changes saved",
      description: `Previously: "${toast.title}"`,
      variant: "success",
      timeout: 4000,
    }));
  }, 1200);
};
</script>

<template>
  <Toasty :toast-manager="toastManager">
    <Button @click="saveChanges">Save with update</Button>
  </Toasty>
</template>

API Reference

Toasty

The provider component that wraps your app and manages the toast system.

Prop / SlotTypeDefaultDescription
defaultslot-Application content wrapped by the toast provider.
containerstring | HTMLElement"body"Teleport target used for the toast viewport.
toastManagerPhiToastManager-Optional manager created by createPhiToastManager() for dispatch outside the provider tree.
variant"default" | "success" | "error" | "warning" | "info""default"Fallback visual style for toasts without their own variant.

usePhiToastManager()

A composable that returns the toast manager for creating toasts.

const toastManager = usePhiToastManager();

toastManager.add(options);

// Update with a partial patch, or derive the patch from the current toast.
toastManager.update(id, { title: "Saved" });
toastManager.update(id, (toast) => ({ description: `Previously: "${toast.title}"` }));

toastManager.promise(asyncFn(), {
  loading: options,
  success: (data) => options,
  error: (err) => options,
});

Manager Methods

update() accepts a partial patch or a callback that receives the currentPhiToast and returns the patch to merge.

MethodTypeDescription
add(options: PhiToastOptions) => stringCreates a toast and returns its id. Adding an existing id updates that toast instead.
update(id: string, options: Partial<PhiToastOptions> | ((toast: PhiToast) => Partial<PhiToastOptions>)) => stringMerges a patch into an existing toast. A callback receives the current PhiToast.
dismiss(id: string) => voidStarts the exit animation and removes the toast afterwards.
remove(id: string) => voidRemoves a toast immediately.
promise(promise: Promise<T>, options: PhiToastPromiseOptions<T>) => Promise<T>Shows loading, success, and error states for one promise.
pauseAll() => voidPauses auto-dismiss timers for every open toast.
resumeAll() => voidResumes auto-dismiss timers with the remaining time.

Toast Options

Options passed to toastManager.add() and promise handlers.

PropTypeDefaultDescription
titlestring-The toast title displayed prominently.
descriptionstring-Secondary text displayed below the title.
variant"default" | "success" | "error" | "warning" | "info""default"Visual style of the toast.
contentComponent | string-Custom Vue component or string rendered inside the toast. Overrides title and description.
actionsToastAction[]-Array of button props rendered as action buttons.
timeoutnumber5000Time in milliseconds before the toast auto-dismisses. Use 0 to keep it open.