icon

Morainev0.5.0

Toast
overlaystoast

Toast

Temporary notification messages backed by the solid-toaster package.

View as MarkdownUpstream

Import#

Install solid-toaster:

bun add solid-toaster

Then import styles, mount a Toaster instance.

import 'solid-toaster/style.css'
import { Button } from '@subframe7536/moraine'
import { Toaster, toast } from 'solid-toaster'
export default function App() {
return (
<>
<Button onClick={() => toast.success('Saved!')}>Toast</Button>
<Toaster />
</>
)
}

Examples#

Basic Toasts#

Send status toasts to the global toaster instance, including loading to success update.

function BasicToasts() {
const wait = (ms: number) =>
new Promise<void>((resolve) => {
setTimeout(resolve, ms)
})
const runLoadingToast = async () => {
const id = toast.loading('Uploading files...')
await wait(1200)
toast.success('Upload complete', { id })
}
return (
<div class="flex flex-wrap gap-3 items-center">
<Button onClick={() => toast('Default message', { onAutoClose: console.log })}>
Default
</Button>
<Button variant="secondary" onClick={() => toast.success('Saved successfully')}>
Success
</Button>
<Button variant="outline" onClick={() => toast.warning('Careful with this action')}>
Warning
</Button>
<Button variant="destructive" onClick={() => toast.error('Something went wrong')}>
Error
</Button>
<Button variant="ghost" onClick={runLoadingToast}>
Loading -&gt; Success
</Button>
</div>
)
}

Promise + Scoped Instances#

Use toast.promise for async lifecycle and route toasts by toasterId.

function PromiseScopedInstances() {
const [promiseRuns, setPromiseRuns] = createSignal(0)
const wait = (ms: number) =>
new Promise<void>((resolve) => {
setTimeout(resolve, ms)
})
const runPromiseToast = () => {
const nextRun = promiseRuns() + 1
setPromiseRuns(nextRun)
const request = wait(1400).then(() => ({ run: nextRun }))
toast.promise(request, {
loading: `Sync #${nextRun} in progress...`,
success: (result) => `Sync #${result.run} finished`,
error: (error) => `Sync failed: ${String(error)}`,
duration: 1e6,
})
}
return (
<div class="flex flex-wrap gap-3 items-center">
<Button onClick={runPromiseToast}>Run promise toast ({promiseRuns()})</Button>
<Button
variant="outline"
onClick={() => toast.info('To bottom-left custom', { toasterId: 'custom' })}
>
Send to custom toaster
</Button>
<Button variant="ghost" onClick={() => toast.dismiss()}>
Dismiss all
</Button>
</div>
)
}