<!-- 1. Create the single toast -->
<script lang="ts">
import { normalizeProps, useActor } from "@zag-js/svelte"
import * as toast from "@zag-js/toast"
interface Props {
actor: toast.Service
}
const { actor }: Props = $props()
const [snapshot, send] = useActor(actor)
const api = $derived(toast.connect(snapshot, send, normalizeProps))
</script>
<div {...api.rootProps}>
<h3 {...api.titleProps}>{api.title}</h3>
<p {...api.descriptionProps}>{api.description}</p>
<button onclick={api.dismiss}>Close</button>
</div>
<!-- 2. Create the toast group provider -->
<script lang="ts">
import { onMount } from "svelte"
import { normalizeProps, useMachine } from "@zag-js/svelte"
import * as toast from "@zag-js/toast"
// Single toast created above
import Toast from "./toast.svelte"
const [snapshot, send] = useMachine(toast.group.machine({ id: "1" }))
const api = $derived(toast.group.connect(snapshot, send, normalizeProps))
function handleEvent(event: any) {
const method = event.type.replace("toast-", "")
const args = event.detail
const result = (api as any)[method](args[0], args[1])
const resultEvent = new CustomEvent(`toast-${method}-result`, { detail: result })
window.dispatchEvent(resultEvent)
}
onMount(() => {
Object.keys(api).forEach((method) => {
window.addEventListener(`toast-${method}`, handleEvent)
})
return () => {
Object.keys(api).forEach((method) => {
window.removeEventListener(`toast-${method}`, handleEvent)
})
}
})
</script>
{#each api.getPlacements() as placement}
<div {...api.getGroupProps({ placement })}>
{#each api.getToastsByPlacement(placement) as toast (toast.id)}
<Toast actor={toast} />
{/each}
</div>
{/each}
<!-- 3. Place the toast provider in root of your app -->
<script lang="ts">
import { ToastProvier } from "./toast-provider.svelte"
</script>
<div>
<h1>App Root</h1>
</div>
<ToastProvider />
<!-- 4. Create js/ts util file to consume toast api -->
import type { GroupApi } from "@zag-js/toast"
export const toast = new Proxy(
{},
{
get(_, method: string) {
return (...args: any[]) => {
let eventResult = null
const event = new CustomEvent(`toast-${method}`, {
detail: args,
})
const handleEventResult = (event: any) => {
eventResult = event.detail
}
window.addEventListener(`toast-${method}-result`, handleEventResult, { once: true })
window.dispatchEvent(event)
window.removeEventListener(`toast-${method}-result`, handleEventResult)
return eventResult
}
},
},
) as GroupApi
<!-- 5. Consume toast api in your app through toast-util.ts -->
<script lang="ts">
import { toast } from "./toast-util"
</script>
<div>
<button
onclick={() => {
toast.create({ title: "Hello", placement: "top-end" })
}}
>
Add top-right toast
</button>
<button
onclick={() => {
toast.create({
title: "Data submitted!",
type: "success",
placement: "bottom-end",
})
}}
>
Add bottom-right toast
</button>
</div>
Created
May 29, 2024 04:53
-
-
Save anubra266/763d55c25873e2940724a7ddcc150933 to your computer and use it in GitHub Desktop.
Svelte toast with events
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment