Skip to content
Barua UI v0.2
Components

Overlays

Modals, sheets, popovers and tooltips — everything that floats above the page. Built on the native <dialog> element and the Popover API, so focus trapping, Esc-to-close and top-layer stacking come from the platform. Glass materials, dimmed scrims and spring motion come from the tokens.

Dialog vs Modal

One element, two behaviours. <dialog> opened with showModal() is modal: it sits in the browser's top layer, renders a ::backdrop scrim, and blocks the page behind it. The same element opened with show() is a non-modal dialog — an inline panel the user can ignore, with no backdrop, no focus trap and no Esc handling. Barua styles both from the same .b-modal class.

Reach for non-modal dialogs for ambient panels like a find bar or a picture-in-picture card; reach for modal when the flow genuinely cannot continue without an answer. If the user could reasonably keep working, it should not be modal.

Alert Dialog

A compact, centered confirmation in the iOS style: title, one-sentence description, then full-width stacked actions separated by hairlines. Mark the destructive choice with .is-destructive and the preferred one with .is-primary. Add .b-alert-dialog__actions--row for the two-button side-by-side arrangement, shown statically below with show()-style inline rendering.

Delete draft?

This draft will be removed from all your devices. You can't undo this.

Row actions

Discard changes?

Your edits to this rule haven't been saved yet.

Accessibility. Point aria-labelledby at the title and aria-describedby at the description so both are spoken on open. Esc closes the dialog natively and barua.js also closes any open dialog when the backdrop is clicked — for irreversible actions, make sure the default (Enter/first-focused) button is the safe one, never the destructive one.
Use an Alert Dialog to confirm destructive, hard-to-undo actions — delete, discard, revoke — with the destructive choice explicitly labelled .is-destructive.
Don't stack modals on top of modals. If a flow needs a second step, replace the content of the open dialog or use a full page — layered scrims disorient people.

Action Sheet

SwiftUI's confirmationDialog: a bottom-anchored glass stack of choices with a separate Cancel group. Destructive choices take .is-destructive. Built on native <dialog> like every Barua overlay.

This conversation will be removed from all your devices.

Sheet

A full-height panel that springs in from the trailing edge — the macOS/iPadOS inspector pattern. It is still a <dialog>, so it gets the scrim, focus trap and Esc handling of a modal while reading as a side panel.

Message details

From Amina Otieno · Today at 09:41

Encrypted in transit · Signed · 2 attachments

Sheets suit secondary detail and editing tasks that relate to the content behind them — the page stays visible under the scrim to preserve context.

Bottom Sheet

Slides up from the bottom edge on a thick glass material, with a grabber affordance and safe-area padding. This is the preferred modal surface on mobile — thumb-reachable, dismissible, and familiar from every iOS share sheet.

Move to…

Pick a destination mailbox. On phone-width layouts, prefer a bottom sheet over a centered modal for any picker or short form.

Accessibility. The grabber is decorative — keep it aria-hidden="true" and always provide a real button (or Esc) to dismiss; barua.js additionally closes the sheet when the scrim above it is tapped. Because it is a modal dialog, focus stays inside until it closes and then returns to the trigger.

Sheet Detents

SwiftUI's presentationDetents for the bottom sheet: .b-bottom-sheet--medium caps the sheet at half the viewport, --large at 92%. The default remains content-sized up to 85%.

Filters

A medium-detent sheet holds to half the screen.

Popover

A light glass card for transient detail, built on the native Popover API: popovers open centered in the viewport by default — add .b-popover--anchored (or .b-menu--anchored) only when you position one against its trigger yourself. Point popovertarget at the popover's id and the browser handles toggling, light-dismiss and Esc — zero JS. Where you need guaranteed positioning without anchor support, wrap trigger and card in .b-popover-anchor to pin the card under its anchor (shown statically below).

Storage
8.2 GB of 15 GB used. Attachments account for most of it — sweep anything older than a year.

Anchored fallback

Verified sender
This address passed DKIM and SPF checks for the sending domain.

Arrowed popover

Apple popovers point at what spawned them. Add .b-popover--arrow-bottom (popover below its anchor, caret on top), --arrow-top, --arrow-start or --arrow-end — the caret inherits the glass background and hairline.

2.1 GB of 5 GB
Attachments make up most of your usage.

Popover card

A structured popover for richer content — __header, __body and a __footer action row, straight from the Apple popover anatomy. Combine with any arrow direction.

AH Share “Q3 Research”

Tooltip

CSS-only. Add .b-tooltip-host and a data-tooltip label to any button or link; the tip fades in above after a 350ms delay so it never flickers during casual mouse travel. Use .b-tooltip-host--bottom when the control sits near the top of the viewport.

Shortcuts
Accessibility. Tooltips also appear on :focus-visible, so keyboard users get the same hint. They are supplementary — an icon-only control still needs its own aria-label, and the tooltip must never carry information available nowhere else.

Hover Card

A richer preview that appears when hovering or focusing a reference to a person or object — GitHub-style. Wrap the link in .b-hover-card-host; the card fades in below after a 250ms delay and stays while hovered.

Assigned to @amina
AO
Amina Otieno
Platform team

Nairobi · joined 2021
412 threads · 38 shared labels

for review.

Context Menu

Right-click menus reuse .b-menu unchanged — see Navigation for menu items, shortcuts, separators and danger rows. Position it at the pointer with your own contextmenu handler; the surface is shown statically here.


Fullscreen Overlay

Takes over the entire viewport for immersive tasks — composing, onboarding, distraction-free reading. A top bar keeps the exit visible at all times; the body scrolls independently beneath it.

Focus mode

Everything else fades away. Esc or the close control returns you exactly where you left off, with focus restored to the trigger.