Primitives
Toast
A short message that shows above the page after an action.
import { Button, toast } from 'ferry-ui'
export default function ToastHero() {
return (
<Button variant="primary" onClick={() => toast.success('Settings saved')}>
Save changes
</Button>
)
}toast from ferry-ui. Do not import it from sonner. The function and the Toaster then use the same copy of sonner.Mount Toaster one time, near the root of the app. Do not mount a second Toaster. Then call toast() in your event handlers.
import { Button, Toaster, toast } from 'ferry-ui'
export function App() {
return (
<>
<Button onClick={() => toast('Project archived')}>Archive</Button>
<Toaster />
</>
)
}toast() shows a neutral message. The four other functions add a status icon.
import { Button, toast } from 'ferry-ui'
export default function ToastTypes() {
return (
<>
<Button onClick={() => toast('Project archived')}>Neutral</Button>
<Button onClick={() => toast.success('Invoice sent')}>Success</Button>
<Button onClick={() => toast.error('Payment failed')}>Error</Button>
<Button onClick={() => toast.warning('Your trial ends in 3 days')}>Warning</Button>
<Button onClick={() => toast.info('A new version is available')}>Info</Button>
</>
)
}| Function | Use |
|---|---|
toast() | A neutral message. |
toast.success() | An action that is complete. |
toast.error() | An action that failed. |
toast.warning() | A problem that needs attention. |
toast.info() | Information for the user. |
The second argument holds the options. Use description to add a second line.
import { Button, toast } from 'ferry-ui'
export default function ToastDescription() {
return (
<Button
onClick={() =>
toast.success('Invoice sent', {
description: 'The customer gets INV-2041 at billing@example.com.',
})
}
>
Send invoice
</Button>
)
}Use action to add a button to the toast. A click on this button runs onClick and closes the toast. Use cancel to add a second button.
import { Button, toast } from 'ferry-ui'
export default function ToastAction() {
return (
<Button
onClick={() =>
toast('Project archived', {
description: 'The project "Website redesign" is in the archive.',
action: { label: 'Undo', onClick: () => toast.success('Project restored') },
cancel: { label: 'Close', onClick: () => {} },
})
}
>
Archive project
</Button>
)
}toast.loading() shows a spinner and returns the id of the toast. Pass this id to a second call to replace the toast.
import { Button, toast } from 'ferry-ui'
export default function ToastLoading() {
function exportMembers() {
const id = toast.loading('Exporting the members…')
// The same id replaces the toast in place.
window.setTimeout(() => toast.success('Export ready', { id, description: '128 rows are in the file.' }), 2000)
}
return <Button onClick={exportMembers}>Export members</Button>
}toast.promise() follows a promise. It shows the loading message first, then the success message or the error message.
import { Button, getErrorMessage, toast } from 'ferry-ui'
// A request that takes 1.5 seconds. Replace it with your own request.
function saveReport() {
return new Promise<{ name: string }>((resolve) => {
window.setTimeout(() => resolve({ name: 'Q3 report' }), 1500)
})
}
export default function ToastPromise() {
return (
<Button
onClick={() => {
toast.promise(saveReport(), {
loading: 'Saving the report…',
success: (report) => `${report.name} saved`,
error: (error: unknown) => getErrorMessage(error),
})
}}
>
Save report
</Button>
)
}toast.dismiss(id) closes one toast. With no argument, it closes all the toasts.
import { Button, toast } from 'ferry-ui'
export default function ToastDismiss() {
return (
<>
<Button onClick={() => toast.info('The import is in progress', { id: 'import', duration: Infinity })}>
Show a toast that stays
</Button>
<Button variant="ghost" onClick={() => toast.dismiss('import')}>
Dismiss it
</Button>
<Button variant="ghost" onClick={() => toast.dismiss()}>
Dismiss all
</Button>
</>
)
}Toaster shows the toasts at the bottom right, with a close button. It follows the theme of the app. Pass an option of sonner to change a default.
<Toaster position="top-center" duration={8000} visibleToasts={5} />Toaster accepts each option of the sonner Toaster.
| Prop | Type | Default |
|---|---|---|
id | string | - |
| See the element or the Radix UI primitive this part renders. | ||
invert | boolean | - |
| See the element or the Radix UI primitive this part renders. | ||
theme | "light" | "dark" | "system" | - |
| See the element or the Radix UI primitive this part renders. | ||
position | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center" | - |
| See the element or the Radix UI primitive this part renders. | ||
hotkey | string[] | - |
| See the element or the Radix UI primitive this part renders. | ||
richColors | boolean | - |
| See the element or the Radix UI primitive this part renders. | ||
expand | boolean | - |
| See the element or the Radix UI primitive this part renders. | ||
duration | number | - |
| See the element or the Radix UI primitive this part renders. | ||
gap | number | - |
| See the element or the Radix UI primitive this part renders. | ||
visibleToasts | number | - |
| See the element or the Radix UI primitive this part renders. | ||
closeButton | boolean | - |
| See the element or the Radix UI primitive this part renders. | ||
toastOptions | ToastOptions | - |
| See the element or the Radix UI primitive this part renders. | ||
className | string | - |
| See the element or the Radix UI primitive this part renders. | ||
style | CSSProperties | - |
| See the element or the Radix UI primitive this part renders. | ||
offset | Offset | - |
| See the element or the Radix UI primitive this part renders. | ||
mobileOffset | Offset | - |
| See the element or the Radix UI primitive this part renders. | ||
dir | "auto" | "ltr" | "rtl" | - |
| See the element or the Radix UI primitive this part renders. | ||
swipeDirections | SwipeDirection[] | - |
| See the element or the Radix UI primitive this part renders. | ||
icons | ToastIcons | - |
| See the element or the Radix UI primitive this part renders. | ||
customAriaLabel | string | - |
| See the element or the Radix UI primitive this part renders. | ||
containerAriaLabel | string | - |
| See the element or the Radix UI primitive this part renders. | ||
Each function that shows a toast returns the id of the toast.
| Function | Role |
|---|---|
toast(title, options) | Shows a neutral toast. |
toast.success(title, options) | Shows a toast with a success icon. |
toast.error(title, options) | Shows a toast with an error icon. |
toast.warning(title, options) | Shows a toast with a warning icon. |
toast.info(title, options) | Shows a toast with an info icon. |
toast.loading(title, options) | Shows a toast with a spinner. |
toast.promise(promise, messages) | Shows the loading, success and error messages of a promise. |
toast.dismiss(id) | Closes one toast, or all the toasts when there is no id. |
The options of a toast:
| Option | Type | Role |
|---|---|---|
description | ReactNode | A second line below the title. |
action | { label, onClick } | A button that runs onClick and closes the toast. |
cancel | { label, onClick } | A second button. |
id | string or number | The id of the toast. A call with the same id replaces the toast. |
duration | number | The time on screen, in milliseconds. |