inst/examples/quakewatch: Quake Watch, a realistic demo (a seismic monitor for the Fiji region built ondatasets::quakes) complementing the exhaustive widget catalogue ininst/examples/demo. It exercises the designer hand-off (bootstrict_theme(variables = "_variables.scss")), UI-declared overlays (offcanvas filter drawer, modal event records, toasts), state-reporting components driven byupdate_bs_*(), and the 5.3 surface (colour modes,.nav-underline,.progress-stacked). Run it withshiny::runApp(system.file("examples/quakewatch", package = "bootstrict")).
The package now targets Bootstrap 5.3 (5.3.8, the runtime bslib actually
ships) instead of 5.2, resolving the former 5.2-markup / 5.3-runtime split.
- Colour modes:
bs_page()/bs_page_fluid()/bs_page_fillable()gaincolor_mode(initialdata-bs-themeon the page body) and the newset_bs_color_mode()switches it from the server. The dark variants of navbar (theme = "dark"), dropdown and carousel (dark = TRUE) and the close button (white = TRUE) now emitdata-bs-theme="dark"— their 5.2-era classes (.navbar-dark,.dropdown-menu-dark,.carousel-dark,.btn-close-white) are deprecated in 5.3. - Progress uses the 5.3 markup:
role="progressbar"and thearia-value*attributes live on the.progresstrack (which now carries theid), the inner.progress-baris purely visual, and passing several bars tobs_progress()renders a.progress-stackedgroup.bs_progress_bar()gainsaria_label. - New 5.3 surface:
bs_nav()/bs_tabset()accepttype = "underline",bs_img()gainsobject_fit(.object-fit-*),bs_icon_link()renders the icon-link helper, andbs_navbar(bg =)accepts"body","body-secondary","body-tertiary","white","black","transparent". - 5.3 reference markup details:
bs_card_subtitle()usestext-body-secondary(.text-mutedis deprecated),bs_modal_title()is an<h1 class="modal-title fs-5">again, tab panes carrytabindex="0", tooltips/popovers usedata-bs-title(no more native-tooltip flash), andhelp =text is wired to its control viaaria-describedby.
bs_page_fillable()loses itsfillableargument:bslib::page_fillable()has no such parameter, so the value leaked into the page markup as an invalidfillableHTML attribute and controlled nothing.bs_modal(backdrop = FALSE)now renders a modal with no backdrop (data-bs-backdrop="false"), matching Bootstrap andbs_offcanvas(). Usebackdrop = "static"for a backdrop that does not dismiss on outside click (the previous behaviour ofFALSE).bs_input_group()andbs_floating_label()now raise an error when given an input whose Shiny binding lives on its container (bs_date_input(),bs_date_range_input(),bs_file_input(),bs_radio_input(),bs_checkbox_group_input()). Previously they silently emitted a dead control with no id, binding, or dependencies.- Layout constructors now validate their scales instead of emitting
non-existent classes:
bs_col()spans (1-12,"auto",TRUE),bs_row(cols=)(1-6,"auto"), gutters and stackgap(0-5),offset(0-11),order(0-5,"first","last"), headinglevels (1-6),bs_pagination_numbered(current=)(1..n),bs_color_input(value=)(#rrggbb), andbs_tabset(selected=)must match a panel value. bs_notify_toast()requires plain-textbody/title(they are rendered viatextContent; tags now raise an error instead of displaying raw markup or[object Object]), and its...must be empty.
-
bs_tooltip()/bs_popover()no longer break the tag they decorate when it is already a data-API trigger (bs_modal_trigger(),bs_offcanvas_trigger(),bs_collapse_trigger(), a dropdown toggle…). They used to append a seconddata-bs-togglevalue (e.g."offcanvas tooltip"), which Bootstrap's exact[data-bs-toggle="offcanvas"]delegated selector no longer matched — the trigger went dead. The existing attribute is now left untouched; tooltip and popover initialisation never relied on it (it is driven bydata-bootstrict-tip). -
Named arguments in
...are now applied to the documented element: thebs_dropdown()wrapper (they were rendered as visible page text), thebs_modal()root (they landed on.modal-body), and thebs_navbar()<nav>(they landed on the collapse<div>). -
Extra attributes passed to
bs_checkbox_input()/bs_switch_input()are no longer silently dropped, andbs_file_input()'s...now lands on the real<input type="file">instead of the readonly display box (internalhas_class()only saw the first of severalclassattribute entries). -
Attributes passed through
...now replace a same-named attribute set by shiny instead of merging with it (bs_text_input("x", type = "email")no longer renders the invalidtype="text email"). -
First server-driven update on a never-toggled collapse/accordion panel no longer does the opposite of what was asked: Bootstrap Collapse instances are now created with
{toggle: false}(the constructor defaulttoggle: truetoggled the panel before the requested action ran). -
Responsive offcanvas (
bs_offcanvas(responsive =)) now binds its state input: the JS selector matched.offcanvasonly, never.offcanvas-{bp}, soinput$idwas never registered. Above the breakpoint the inline-shown panel now reportsTRUE. -
bs_carousel(autoplay = FALSE)now omitsdata-bs-rideentirely; it used to emitdata-bs-ride="true", which resumes autoplay after the first user interaction. -
update_bs_list_group(id, selected = NULL)is now the documented no-op; it used to clear the whole selection and resetinput$id. Aselectedvalue matching no item warns and leaves the selection unchanged. -
update_bs_accordion():open = TRUEnow opens all panels (it used to send the literal string"TRUE");open/close = FALSEare no-ops. -
bs_button(href =, disabled = TRUE)now renders the.disabledclass andtabindex="-1"(the anchor was still clickable). -
Accordion state no longer leaks between nested accordions (panel discovery and Bootstrap events are now scoped to the accordion's own panels), and an accordion with every panel closed reports
NULLinstead oflist(). -
Progress: percentages are clamped to 0-100 as documented; a min/max-only update recomputes the width; a colour update no longer strips
bg-opacity-*/bg-gradientclasses (see also the Bootstrap 5.3 markup restructure above). -
Ids containing CSS-special characters (e.g. dotted module namespaces) no longer break declarative wiring: every generated
data-bs-target/data-bs-parent/ triggerhrefselector is now CSS-escaped. -
Dynamic UI lifecycle: Bootstrap instances are disposed when Shiny unbinds a widget (modals/offcanvas hide first — no more stuck backdrops after a
renderUI()re-render),bs_notify_toast()disposes each toast on hide (it leaked a detached DOM node and instance per notification), the list-group click handler unbinds cleanly (it used to stack up across unbind/rebind cycles), tooltip/popover auto-ids no longer collide (a shared timestamp gave duplicate ids) and their instances are disposed on unbind, and carousels/scrollspys inserted viarenderUI()are now initialised at bind time (Bootstrap only scans on page load). -
bs_range_input()dragging is debounced as documented (inputevents now route through the rate policy;changestill submits immediately), and the range/color JS selectors are scoped to bootstrict's owndata-bootstrictmarker so hand-written Bootstrap markup is not hijacked. -
bs_range_input()andbs_color_input()participate in Shiny bookmarking (restoreInput()). -
parse_scss_variables()strips multi-line/* ... */comments (variables inside a commented block were parsed as real) and reads every declaration on a line, not just the first. -
use_bootstrict_golem()scaffolds_variables.scss(SCSS syntax, whichparse_scss_variables()reads) instead of_variables.sass(indented syntax, which silently parsed to nothing). -
Radio/checkbox group labels get
.form-label, per-option and single checkbox labels get.form-check-label, andbs_file_input()drops the leftover Bootstrap 3/4 markup (.input-group-btnwrapper, BS3 progress animation classes). -
Selectable / action list groups no longer emit invalid HTML (
<li>items inside their<div>container are converted to<div>s); disabled anchor items gettabindex="-1". -
Modals and offcanvas with a
titlenow wirearia-labelledbyto the title element; vertical tabsets setaria-orientation="vertical";bs_collapse_trigger()gainsexpandedfor a correct initialaria-expanded/.collapsedstate;bs_breadcrumb(divider =)escapes quotes/backslashes. -
Responsive
bs_dropdown(align = list(...))now setsdata-bs-display="static"on the toggle, without which Bootstrap ignores the responsive alignment classes.
update_bs_list_group(id, selected = character(0))clears the selection (deselects every item and resetsinput$idtoNULL).selected = NULLremains the no-op that leaves the current selection untouched, so a group can now be cleared server-side without the surprise reset that the pre-NULLno-op behaviour carried.bs_checkbox_input(),bs_switch_input(),bs_date_input()andbs_date_range_input()gain thehelpargument the other inputs already had.bs_notify_toast()gainsautohide(useFALSEfor a persistent notification); header-less notifications now include a close button (they were undismissable), dark-background notifications get the dark-context close button (data-bs-theme="dark"), and the auto-created container is anaria-liveregion.bs_scrollspy()gains anid(auto-generated by default) and reports the active section's link asinput$id.bs_offcanvas_trigger()delegates tobs_button()likebs_modal_trigger()(it was a bare unstyled.btn).- Server messages targeting a missing element now
console.warnwith the offending id instead of failing silently (the most common module namespacing mistake becomes visible). bootstrict_dep()is built once per session and cached.
- Initial development version.