A button, and one message that appears and leaves.
import { toaster } from '@markless/ui';export default functionSavefunction Save(): Element() @{@{ · Component bodyOpens the body of a component, where ordinary statements and the markup they produce sit together. consttoastsconst toasts: { = toaster.statestate · Watched valueDeclares a variable the page follows, which you read and assign exactly like any other variable.(); <main(property) main: GlobalAttributes & MarklessAttributes<HTMLElement> & NativeEventAttributes<HTMLElement>> <button(property) button: GlobalAttributes & MarklessAttributes<HTMLButtonElement> & NativeEventAttributes<HTMLButtonElement> & FormAttributes & {type(property) type?: "button" | "reset" | "submit" | undefined="button"onClickonClick · Event handlerRuns when this element fires the matching DOM event, and receives the native event object.={() => {toasts.queue(property) queue: toaster.ToastRecord[]= toaster.say(alias) say(held: readonly toaster.ToastRecord[], title: string, options?: toaster.ToastOptions): toaster.ToastRecord[]Say something, from a consumer's own handler: the queue goes in, the queue with the message in it comes out. The id is the caller's own or is minted from the queue, because a page-scoped counter is not reachable from here.(toasts.queue, 'Saved', { id: 'save' }); }} >Save</button(property) button: GlobalAttributes & MarklessAttributes<HTMLButtonElement> & NativeEventAttributes<HTMLButtonElement> & FormAttributes & {> <toaster.root(alias) function root({ children, onPointerover, onPointerout, onFocusin, onFocusout, ...rest }: toaster.ToasterRootProps): Element> <div(property) div: GlobalAttributes & MarklessAttributes<HTMLDivElement> & NativeEventAttributes<HTMLDivElement>role(property) role?: string | undefined="presentation">@for@for · ListRenders its block once per item, with an optional key clause naming the stable identity of each row. (constmessageconst message: toaster.ToastRecordof toasts.queue; key message.id) { <toaster.item(alias) function item({ toast, children, ...rest }: toaster.ToasterItemProps): Elementtoast(property) toast: toaster.ToastRecordThe message this row shows.={message}> <toaster.itemicon(alias) function itemicon({ children, ...rest }: toaster.ToasterItemIconProps): Element /> <toaster.itemtitle(alias) function itemtitle({ children, ...rest }: toaster.ToasterItemTitleProps): Element /> <toaster.itemdescription(alias) function itemdescription({ children, ...rest }: toaster.ToasterItemDescriptionProps): Element /> <toaster.itemclose(alias) function itemclose({ children, onClick, ...rest }: toaster.ToasterItemCloseProps): Element aria-label="Dismiss">×</toaster.itemclose(alias) function itemclose({ children, onClick, ...rest }: toaster.ToasterItemCloseProps): Element> </toaster.item(alias) function item({ toast, children, ...rest }: toaster.ToasterItemProps): Element> } </div(property) div: GlobalAttributes & MarklessAttributes<HTMLDivElement> & NativeEventAttributes<HTMLDivElement>> </toaster.root(alias) function root({ children, onPointerover, onPointerout, onFocusin, onFocusout, ...rest }: toaster.ToasterRootProps): Element> </main(property) main: GlobalAttributes & MarklessAttributes<HTMLElement> & NativeEventAttributes<HTMLElement>>}
The region is on the page before the first message, because a live region added at the same moment
as its text is not announced. The root renders no rows of its own, so how many show is your own
repeat to decide — toaster.shown(queue, n) is the cap to write against. A message is raised by
assigning the queue from your handler: toasts.queue = toaster.say(toasts.queue, ...). Say it
again with the same id and the message already showing is updated rather than duplicated.
Anatomy
toaster.root — the <ol> live region. One per page.
toaster.item — one row, handed the message it shows.
toaster.itemtitle, toaster.itemdescription, toaster.itemicon — that row's text and mark.
toaster.itemclose — the button that dismisses the message it sits in.
toaster.say, toaster.drop, toaster.shown — the queue's arithmetic, for your own handler.
It writes ui-toast, ui-toaster, ui-tone, ui-front and ui-paused, plus one per part.
Props on toaster.root
toaster.root takes no props of its own beyond what an <ol> accepts. There is no visible
prop, because the root renders no rows: the cap belongs to your repeat.
toaster.item is where the data goes:
Prop
Type
What it does
toast
ToastRecord
The message this row shows. Required.
index
number
Where it stands in the stack. 0 is the front one.
toaster.say(queue, title, options) takes an id, a tone of neutral, success, warning or
error, a description, and a duration in milliseconds — Infinity keeps the message until
something dismisses it.