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.
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.
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.
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 */ }