Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

AnnouncementDialog

What's new, once: a large dialog with a title, short sections and an illustration, a Got it button and a link to read more.

import { AnnouncementDialog } from "@butteryui/react";

Demo

When to use it

Use it for

  • Telling people about a change to a page they already use, the first time they open it
  • A release worth a moment, with a picture of what changed

Not for

  • Something to set up: use SetupGuide or FeatureIntro
  • A small tip: use Banner or NotificationNudge
  • Anything urgent: say it on the page, where it stays

Examples

Help menu news

Opened from a Help menu's What's new item, with open and onOpenChange kept in useState.

One update to read

Pickup news

A text-only announcement opened from a button, with a closing paragraph after its sections.

Roast planning news

A banner on the roast plan that opens the full announcement, with an illustration and a link to read more.

Roasts now plan themselves from orders and subscriptions.

Monday: 3 batches of the Hill Street blend.

Variants and states

What's new, with an illustration

Side by side in a wide window; the picture goes on top when the dialog is narrower than 720px.

Props

AnnouncementDialog

PropTypeDefaultDescription
refRef<HTMLDivElement>The dialog's content box.
triggerReactElementThe button that opens it again later.
title

required

stringWhat's new, in title-lg. It names the dialog.
sections

required

readonly AnnouncementSection[]The parts of the announcement, 24px apart.
mediaReactNodeThe app's own illustration of what's new, beside the copy or above it when narrow.
doneLabelstring"Got it"The primary button, which closes it. Defaults to "Got it".
learnMoreGuidanceActionWhere to read more, beside the button. A link to another site (https://…) shows the external icon; a page in the app or an action shows the forward arrow and closes the dialog as it goes.
storageKeystringShows it by itself once per key, the first time the page opens, and never again once closed.
openbooleanWhether it's open, when you control it.
defaultOpenbooleanWhether it starts open when uncontrolled. Defaults to opening on a first visit with storageKey, else false.
onOpenChange((open: boolean) => void)Called when it opens or closes.
closeLabelstring"Close"Names the close button. Defaults to "Close".
classNamestringClasses for the content inside the dialog, the element that carries data-bt="AnnouncementDialog".
styleCSSPropertiesInline styles for the same element.

AnnouncementSection

One part of an announcement: a subheading over a paragraph.

FieldTypeDefaultDescription
titlestringThe subheading, in title-sm. Leave it out for a closing paragraph.
body

required

ReactNodeWhat's new, in body.

GuidanceAction

What a guidance part points to: a label, and where it goes or what it does.

FieldTypeDefaultDescription
label

required

stringWhat it says, such as "Connect a label printer".
hrefstringMakes it a link to this page.
onClick((event: MouseEvent<HTMLElement>) => void)Runs when it's pressed, or as its link is followed, where a router can take over.

Accessibility

A modal dialog named by its title; each section's subheading is an h3. Focus starts on Got it, which closes it, as do Escape, the close button and a press outside; the read-more link follows it. Shown by itself once per storageKey, then only from its trigger.

KeysWhat they do
Tab or Shift+TabMoves between Got it, the read-more link and the close button, staying inside the dialog
Enter or SpacePresses the focused button; Got it, where focus starts, closes the dialog
EnterFollows the read-more link, closing the dialog when it goes to a page in the app
EscapeCloses it, handing focus back to the trigger unless it opened by itself

Motion

It appears with a `Presence` preset and leaves faster than it came, in about 60% of the time.

With reduced motion: It and its scrim fade in and out in 100ms, without growing or rising.

Layout

It's 880px wide at most (--bt-w-dialog-lg) and 16px inside the window, padded 32, with the copy and the media in two equal columns from 720px of dialog and the media on top under that; the copy wraps, and a dialog taller than the window scrolls inside. Got it is a 36px button, and the close button a 28px one in the top corner.

See it in the roastery demo.