A dark notification-settings editor built on the Bootstrap 6 Dialog component. On desktop it is a centered card. Below 768px it fills the whole screen, while the header and footer stay fixed and only the list of switches scrolls. It works well for long forms, settings panels and terms that would be cramped in a small popup on phones.
How it works
The root .fdm-root is pinned to data-bs-theme="dark". It shows a summary card (.fdm-card) with an "Edit preferences" button that opens the dialog through data-bs-toggle="dialog".
The dialog element is <dialog class="dialog dialog-scrollable md-down:dialog-fullscreen fdm-dialog">. dialog-scrollable gives .dialog-body its own scroll area, and md-down:dialog-fullscreen removes the margins, radius and max-width on viewports narrower than 768px. The body holds a <form id="fdm-form"> with four fieldset.fdm-group sections. These contain Bootstrap 6 .switch toggles with form-field-content labels and a digest <select class="form-control">. The Save button sits in .dialog-footer and submits the form through form="fdm-form".
script.js keeps two states: the defaults (the checked/selected attributes in the markup) and the last saved values. Each time show.bs.dialog fires, the form is restored to the saved values, so Cancel discards edits. Save shows a spinner, updates .fdm-count and .fdm-digest-label on the card, announces "Preferences saved." and closes the dialog. .fdm-reset loads the defaults.
Customization
--fdm-accenton.fdm-root: the amber used for section labels and the card icon. The switches and Save button usetheme-warning; swap it for anothertheme-*role.- Change
md-down:dialog-fullscreentosm-down:dialog-fullscreenorlg-down:dialog-fullscreento move the fullscreen breakpoint. --bs-dialog-widthinside themin-width: 768pxmedia query on.fdm-dialog: the desktop width (36rem).- Add more
.fdm-rowswitches or.fdm-groupfieldsets; the count updates automatically. - Replace the
setTimeoutin the submit handler with afetch()that sends the form values to your API. - Remove
data-fdm-autoopenso the dialog no longer opens on load (the attribute is there for the preview).
Use cases
- Settings panels: notification switches scroll in the body while header and footer stay fixed
- Long forms: the dialog is a centered card on desktop and fills the screen on phones
- Terms and policies: lengthy content is easier to read than in a cramped small popup
- Mobile apps on the web: the Save button respects the safe area at the bottom of the screen
Accessibility
Every switch is an input type="checkbox" role="switch" with a <label for> and a description. Groups use fieldset and legend. The dialog is labelled by its title, traps focus, closes with Escape and returns focus to the trigger. The saved message uses role="status". On phones the footer respects env(safe-area-inset-bottom).
Bootstrap 6 notes
This is built on Bootstrap 6.0.0-alpha.1, and alpha APIs can still change. BS5's modal-fullscreen-md-down is now the prefix class md-down:dialog-fullscreen, and modal-dialog-scrollable is dialog-scrollable. form-switch becomes <div class="switch"><input role="switch" switch></div>, and form-select is gone in favour of form-control on the <select>. Buttons use btn-solid, btn-outline and btn-text with theme-* roles.