Feedback
Use the feedback helpers for short messages, a single question, or copying text. For a dialog with custom content, use <ds-overlay>. For messages in markup, use <ds-message>.
import { toast, confirm, prompt, alert, copyText } from "./ds1/0-face/feedback";
toast.success("Saved");if (await confirm({ title: "Delete this track?", confirm: "Delete", danger: true })) remove();const name = await prompt({ title: "Rename", label: "Name", value: track.name });await alert({ title: "Exported", text: "The file is in your downloads." });await copyText(link);Never call the browser’s alert(), confirm() or prompt(): they block the page, cannot be
styled or translated, and some browsers stop showing them. Never build a page’s own toast or
copy helper either.
Try it
Section titled “Try it”Toasts
Section titled “Toasts”toast() is Sonner’s, exactly as with <ds-toast>: toast(),
toast.success(), .info(), .warning(), .error(), .loading(), .message(),
.promise() and .dismiss(), with the same options (id, description, duration,
action, cancel, dismissible, closeButton, important, onDismiss, onAutoClose).
Toast is based on Sonner, the React toast library by Emil Kowalski (MIT licence), so Sonner’s
documentation describes how it works. The stack behaves as Sonner’s: three show at once, hovering
or focusing spreads them and pauses their time, a swipe towards the edge dismisses one, and Alt+T
reaches them from the keyboard.
configureToaster() takes Sonner’s <Toaster /> props:
import { configureToaster } from "./ds1/0-face/feedback";
configureToaster({ position: "top-center", closeButton: true });| Option | Default | What it does (as in Sonner) |
|---|---|---|
position | bottom-right | top-left, top-center, top-right, bottom-left, bottom-center or bottom-right. |
expand | Off | Keeps the toasts spread out instead of stacked. |
visibleToasts | 3 | How many toasts show at once. |
duration | Infinity | Stays until dismissed. Set a finite duration only for an explicitly timed message. |
closeButton | On | Adds a close button to every toast. |
richColors | Off | Fills success, info, warning and error toasts with their colour. |
label | Notifications | The region’s accessible name. |
closeLabel | Close | The close button’s accessible name. |
Dialogs
Section titled “Dialogs”The helpers manage focus, cancellation and the browser’s modal dialog behavior.
| Call | Options | Resolves to |
|---|---|---|
confirm(options) | title, text, confirm, cancel, danger | true when confirmed, false otherwise |
prompt(options) | title, text, label, value, placeholder, confirm, cancel | the text written (empty text included), or null when cancelled |
alert(options) | title, text, confirm | nothing, once it is dismissed |
A string in place of the options is the title: confirm("Leave without saving?").
- The buttons are
.ds-button--secondary(Cancel) and.ds-button--primary(the answer). Withdanger, the answer is a destructive action: its words are in the danger colour (.ds-button--danger), Cancel has the focus, and a click on the backdrop does not close it. Name the action (confirm: "Delete") rather than leaving it OK. - Focus moves into the dialog when it opens (the field in a prompt, with its text selected) and back to what had it when it closes.
- Escape cancels; Enter in a prompt’s field confirms it.
- A click on the backdrop cancels, except with
danger. - Two never open at once: a dialog asked for while another is open waits for it to close.
- A dialog asked for in a click opens within that click, so a phone shows its keyboard for a prompt’s field.
A prompt’s field is labelled by label, shown above it, or by the title. Its label and the field
are each one row high, so the field takes two squares of the frame.
Copying text
Section titled “Copying text”copyText(text, { toast }) writes the text with the Clipboard API, and where that is missing or
refused (a page served over plain HTTP, an older browser) copies it from a hidden field. It
resolves to whether it was copied, and says so in a toast: “Copied”, or the words in toast;
toast: false shows none. A failure says “Could not copy”. Call it from the click or key press
that asks for it: browsers allow writing to the clipboard only then.
A page that only copies text imports it on its own, and the page toaster stays out of its code until a toast is shown:
import { copyText } from "./ds1/0-face/copy-text";The page toaster loads when copyText first shows a toast and nothing in the page draws toasts
yet. With toast: false, or with a <ds-toast> in the page, it never loads.
The default words are OK, Cancel, Copied, Could not copy, Notifications and Close. The module brings no language runtime of its own:
- On a page without the language module, they read English, and no translation file or request comes with them.
- Where the page loads the language module, they are the shared words in the page’s language, in
all fifteen languages, once
configureI18n({ sharedWords: true })turns them on. setFeedbackWords()gives words of the product’s own: a table of the words it changes, or a function that gives each word in the page’s language.setFeedbackWords(null)goes back to the defaults.
import { setFeedbackWords } from "./ds1/0-face/feedback";
setFeedbackWords({ OK: "Done" });setFeedbackWords(word => myWords[word]);Pass a dialog’s or a toast’s own words where they say more than the shared ones.
Related
Section titled “Related”Message provides inline, banner and toast messages. Overlay provides modals, sheets and drawers. Use with HTML loads the same components in an ordinary HTML file.