Modal

Overlay dialog that covers the page and holds focus until dismissed. Three sizes: small (24rem), medium (36rem), large (52rem). The Alert Dialog variant (further down) is a focused confirmation style — same component, different role + trimmed structure — for destructive or irreversible actions. Use modals sparingly; for longer flows prefer a route or inline panel.

a11y (built in): the backdrop carries role="dialog" (or role="alertdialog") + aria-modal="true" + aria-labelledby / aria-describedby pointing at the real title and body, and the close X is labelled. open() stores document.activeElement, cycles Tab / Shift+Tab inside .lb-modal, and locks body scroll; close() releases both and returns focus to the opener. Esc always closes, a backdrop click closes everything except .lb-modal--alert, and LB.alert() mints its own id wiring, escapes the strings it renders, and lands focus on the confirm button.

Usage: Drop the .lb-modal-backdrop block anywhere in <body> with inline display:none; data-lb-modal auto-inits on DOMContentLoaded (run LB.init() again for markup injected later — it's idempotent). Drive it with el._lbModal.open() / .close() or construct new LB.Modal(el, { onClose }); the backdrop dispatches lb-modal-open and lb-modal-close on every transition. For one-off confirmations skip the markup entirely — LB.alert(options) mints, opens and disposes its own dialog and resolves its Promise<boolean> with true only on confirm (full options in the API card below).


Default

Standard modal: backdrop, header with close X, body, footer with Cancel/Confirm. Open via el._lbModal.open(), close via .close() or the X button. Esc and backdrop click both dismiss.

Confirm Action

Are you sure you want to proceed? This action cannot be undone.

Alert dialog — programmatic LB.alert()

Alert dialog is the focused confirmation variant — for destructive or irreversible actions (delete, discard, revoke, force-logout). Smaller and more pointed than a general-purpose Modal: one question, two buttons, no X to close by mistake. ARIA role alertdialog (not dialog) so screen readers announce it as a blocking alert. Backdrop click does not dismiss while the dialog carries .lb-modal--alert — users must pick.

Programmatic short form — builds, opens, disposes the dialog. Returns a Promise resolving to true on confirm, false on cancel or Escape.

Last result: (click a button)

Alert dialog — declarative, destructive

Write the markup yourself when you need custom content (long messages, inline forms, links). Use role="alertdialog" + .lb-modal--alert + .lb-btn--danger.

Delete workspace?

You're about to permanently delete letbe.design. This will:

  • Remove all 24 projects and their data
  • Cancel outstanding invites to 8 teammates
  • Revoke all API tokens issued from this workspace

This action cannot be undone.

Alert dialog — declarative, non-destructive

For confirmations that aren't destructive (sign out, publish, enable, etc.), skip the danger icon/button but keep the alertdialog role, the .lb-modal--alert class and the compact size.

Sign out of letbe.design?

You'll need to enter your credentials again to get back in. Offline drafts on this device will be kept.

API — LB.alert(options)

Full options reference for the programmatic helper.

const ok = await LB.alert({ title: 'Delete item?', // required-ish; defaults to "Are you sure?" message: 'Cannot be undone.', // optional body text confirmText: 'Delete', // default 'Confirm' cancelText: 'Cancel', // default 'Cancel' danger: true, // makes confirm button red + adds alert icon icon: 'circle-alert' | 'triangle' | false | '<svg>...</svg>', }); if (ok) { /* user confirmed */ }