diff --git a/DESCRIPTION b/DESCRIPTION
index d39915b7d..d4846269b 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,6 +1,6 @@
Package: bslib
Title: Custom 'Bootstrap' 'Sass' Themes for 'shiny' and 'rmarkdown'
-Version: 0.6.2.9000
+Version: 0.7.0
Authors@R: c(
person("Carson", "Sievert", , "carson@posit.co", role = c("aut", "cre"),
comment = c(ORCID = "0000-0002-4958-2844")),
@@ -28,15 +28,12 @@ URL: https://rstudio.github.io/bslib/, https://github.com/rstudio/bslib
BugReports: https://github.com/rstudio/bslib/issues
Depends:
R (>= 2.10)
-Remotes:
- rstudio/shiny,
- rstudio/htmltools
Imports:
base64enc,
cachem,
fastmap (>= 1.1.1),
grDevices,
- htmltools (>= 0.5.7.9000),
+ htmltools (>= 0.5.8),
jquerylib (>= 0.1.3),
jsonlite,
lifecycle,
@@ -54,7 +51,7 @@ Suggests:
magrittr,
rappdirs,
rmarkdown (>= 2.7),
- shiny (>= 1.8.0),
+ shiny (>= 1.8.1),
testthat,
thematic,
withr
diff --git a/NEWS.md b/NEWS.md
index 612658904..6995f7fbb 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,49 +1,61 @@
-# bslib (development version)
+# bslib 0.7.0
-## Breaking changes
+This large release includes many improvements and bug fixes for newer UI components like `layout_columns()`, `card()`, and `sidebar()`. In addition, the new `input_task_button()` offers a drop-in replacement for `shiny::actionButton()` (to prevent multiple submissions of the same operation) as well as pairing nicely with the new `shiny::ExtendedTask` for implementing truly non-blocking operations in Shiny.
-* `as_fillable_container()`, `as_fill_item()` and `as_fill_carrier()` now always include the htmltools fill CSS dependency. This means that they are no longer usable with the `$addAttr()` `htmltools::tagQuery` method; authors should instead pass elements to the `as_fillable_container()` and `as_fill_*()` functions and use the `css_selector` argument to apply fill options to specific elements. (#946)
+## New features
-* A `sidebar()` passed to `page_sidebar()`/`page_navbar()` is now always open (and not collapsible) by default on mobile screens. To revert to the old behavior, set `open = "desktop"` in the `sidebar`. (#943)
+* Added `input_task_button()`, a replacement for `shiny::actionButton()` that automatically prevents an operation from being submitted multiple times. It does this by, upon click, immediately transitioning to a "Processing..." visual state that does not let the button be clicked again. The button resets to its clickable state automatically after the reactive flush it causes is complete; or, for advanced scenarios, `update_task_button()` can be used to manually control when the button resets.
-* `page_sidebar()` now places the `title` element in a `.navbar` container that matches the structure of `page_navbar()`. This ensures that the title elements of `page_sidebar()` and `page_navbar()` have consistent appearance. (#998)
+* Both `card()` and `value_box()` now take an `id` argument that, when provided, is used to report the full screen state of the card or value box to the server. For example, when using `card(id = "my_card", full_screen = TRUE)` you can determine if the card is currently in full screen mode by reading the boolean value of `input$my_card_full_screen`. (#1006, #1032)
-* The `col_widths` argument of `layout_columns()` now sets the `sm` breakpoint by default, rather than the `md` breakpoint. For example, `col_widths = c(12, 6, 6)` is now equivalent to `breakpoints(sm = c(12, 6, 6))` rather than `breakpoints(md = c(12, 6, 6))`. (#1014)
+## Changes & improvements
-## New features
+* For `sidebar()`:
-* Added `input_task_button()`, a replacement for `shiny::actionButton()` that automatically prevents an operation from being submitted multiple times. It does this by, upon click, immediately transitioning to a "Processing..." visual state that does not let the button be clicked again. The button resets to its clickable state automatically after the reactive flush it causes is complete; or, for advanced scenarios, `update_task_button()` can be used to manually control when the button resets.
+ * The page-level `sidebar` for `page_sidebar()`/`page_navbar()` is now always open (and not collapsible) by default on mobile screens. To revert to the old behavior, set `open = "desktop"` in the `sidebar`. (#943)
-* Both `card()` and `value_box()` now take an `id` argument that, when provided, is used to report the full screen state of the card or value box to the server. For example, when using `card(id = "my_card", full_screen = TRUE)` you can determine if the card is currently in full screen mode by reading the boolean value of `input$my_card_full_screen`. (#1006, #1032)
+ * `open` now accepts a list with `mobile` and `desktop` values to control the sidebar's initial state on each screen size, choosing from `"open"`, `"closed"`, or `"always"` (for an always-open sidebar that cannot be collapsed). (#943)
-## Improvements
+ * The collapse toggle now has a high `z-index` value to ensure it always appears above elements in the main content area. The sidebar overlay also now receives the same high `z-index` on mobile layouts. (#958)
-* `layout_columns()` was rewritten in Typescript as a custom element to improve the portability of the component. (#931)
+* Improved `card(full_screen = TRUE, ...)` accessibility:
-* When `layout_columns()` is given a `row_heights` value that is not a `breakpoints()` object, that value is used for the row heights at all breakpoints. Previously, it was used for the row heights from `"sm"` up. (#931)
+ * Full-screen cards are now supported on mobile devices: the _Expand card_ button is revealed when a user taps on the card (thanks @Damonsoul, #961).
-* When `layout_columns()` is given a `col_widths` value with `breakpoints()` at `lg` or wider, it now uses a better default column width for the smaller breakpoints not listed in the `col_widths` value. That said, you can always include `sm` or `md` in your `breakpoints()` definition to have complete control over column widths at those sizes. (#931)
+ * The _Expand card_ button is now accessible via keyboard navigation and appropriate ARIA attributes connect the card with the expand and close buttons.
+
+ * For JavaScript-oriented users, the expansion/collapse is now accompanied by a custom `bslib.card` event with the full screen state reported in the `event.detail.fullScreen` property. (#959)
-* `sidebar()` now supports separate choices for the `open` argument on mobile or desktop screens. You can pass a list with `mobile` and `desktop` values to `open` to control the sidebar's initial state on each screen size, choosing from `"open"`, `"closed"`, or `"always"` (for an always-open sidebar that cannot be collapsed). (#943)
+* Improvements to the default theme (i.e., Shiny preset):
-* The sidebar's collapse toggle now has a high `z-index` value to ensure it always appears above elements in the main content area of `layout_sidebar()`. The sidebar overlay also now receives the same high `z-index` on mobile layouts. (#958)
+ * In the default theme, cards now use a slightly smaller shadow and the same shadow style is also now used by popovers. (#998)
-* We've improved the accessibility of full screen cards created with `card(full_screen = TRUE, ...)`. The _Expand card_ button is now accessible via keyboard navigation and appropriate ARIA attributes connect the card with the expand and close buttons. For JavaScript-oriented users, the expansion/collapse is now accompanied by a custom `bslib.card` event with the full screen state reported in the `event.detail.fullScreen` property. (#959)
+ * Increased spacing between elements. This change is most noticeable in the `layout_columns()` or `layout_column_wrap()` component. In these and other components, you can use `gap` and `padding` arguments to choose your own values, or you can set the `$bslib-spacer` (Sass) or `--bslib-spacer` (CSS) variable. (#998)
-* Full-screen cards are now supported on mobile devices: the _Expand card_ button is revealed when a user taps on the card (thanks @Damonsoul, #961).
+* For `layout_columns()`:
-* We adjusted the shadows used for cards and popovers in the Shiny preset. Cards now use a slightly smaller shadow and the same shadow style is also now used by popovers. (#998)
+ * `col_widths` now sets the `sm` breakpoint by default, rather than the `md` breakpoint. For example, `col_widths = c(12, 6, 6)` is now equivalent to `breakpoints(sm = c(12, 6, 6))` rather than `breakpoints(md = c(12, 6, 6))`. (#1014)
-* We increased the spacing between elements just slightly in the Shiny preset. This change is most noticeable in the `layout_columns()` or `layout_column_wrap()` component. In these and other components, you can use `gap` and `padding` arguments to choose your own values, or you can set the `$bslib-spacer` (Sass) or `--bslib-spacer` (CSS) variable. (#998)
+ * When `col_widths` has a `breakpoints()` at `lg` or wider, it now uses a better default column width for the smaller breakpoints not listed in the `col_widths` value. That said, you can always include `sm` or `md` in your `breakpoints()` definition to have complete control over column widths at those sizes. (#931)
+
+ * When `row_heights` is a non-`breakpoints()` object, that value is used for the row heights at all breakpoints. Previously, it was used for the row heights from `"sm"` up. (#931)
+
+ * When an integer value for any breakpoint is provided to `col_widths`, a 12-unit grid is always used. For example, `breakpoints(md = 3, lg = NA)` will pick a best-fitting layout for large screen sizes using the 12-column grid. Previously, the best fit algorithm might adjust the number of columns as a shortcut to an easy solution. That shortcut is only taken when an auto-fit layout is requested for every breakpoint, e.g. `col_widths = breakpoints(md = NA, lg = NA)` or `col_widths = NA`. (#928)
+
+ * Underlying logic moved from R to Typescript to improve the portability of the component. (#931)
* `value_box()`, `layout_columns()` and `layout_column_wrap()` now all have `min_height` and `max_height` arguments. These are useful in filling layouts, like `page_fillable()`, `page_sidebar(fillable = TRUE)` or `page_navbar(fillable = TRUE)`. For example, you can use `layout_columns(min_height = 300, max_height = 500)` to ensure that a set of items (likely arranged in a row of columns) are always between 300 and 500 pixels tall. (#1016)
-## Bug fixes
+* `page_sidebar()` now places the `title` element in a `.navbar` container that matches the structure of `page_navbar()`. This ensures that the title elements of `page_sidebar()` and `page_navbar()` have consistent appearance. (#998)
-* `layout_columns()` now always uses a 12-unit grid when the user provides an integer value to `col_widths` for any breakpoint. For example, `breakpoints(md = 3, lg = NA)` will pick a best-fitting layout for large screen sizes using the 12-column grid. Previously, the best fit algorithm might adjust the number of columns as a shortcut to an easy solution. That shortcut is only taken when an auto-fit layout is requested for every breakpoint, e.g. `col_widths = breakpoints(md = NA, lg = NA)` or `col_widths = NA`. (#928)
+* `as_fillable_container()`, `as_fill_item()` and `as_fill_carrier()` now always include the htmltools fill CSS dependency. This means that they are no longer usable with the `$addAttr()` `htmltools::tagQuery` method; authors should instead pass elements to the `as_fillable_container()` and `as_fill_*()` functions and use the `css_selector` argument to apply fill options to specific elements. (#946)
+
+## Bug fixes
* Fixed an issue where the page might be given a window title of `NA` if the primary `title` argument of a page function, such as `page_sidebar()`, is `NULL` or a suitable window title could not be inferred. (#933)
+* `card()`s (and `value_box()`s) now correctly exit full screen mode when they are removed from the UI. If you want to update a card without potentially exiting the full-screen mode, update specific parts of the card using `uiOutput()` or `textOutput()`. (#1005)
+
* Fixed a handful of `update_popover()` bugs. (#747, #1017)
* `tooltip()` and `popover()` now work as expected when inserted into a navbar/navset via `nav_insert()`. (#1020)
@@ -52,8 +64,6 @@
* `page_navbar()` and `navset_bar()` now validate and transform `padding` and `gap` arguments into appropriate CSS values. (#991)
-* Fixed an issue that could happen with a `card()` or `value_box()` that is rendered entirely via `renderUI()` when it is replaced by an updated card but the user had expanded the original card into full screen mode. Now the full screen state is reset for the new card or value box. If you want to update a card without potentially exiting the full-screen mode, update specific parts of the card using `uiOutput()` or `textOutput()`. (#1005)
-
* Fixed an issue where the `xs` breakpoint in a `breakpoints()` object used for `row_heights` in `layout_columns()` would override all other breakpoints. (#1014)
# bslib 0.6.2
diff --git a/inst/components/dist/components.js b/inst/components/dist/components.js
index 955524005..68dd8f2e6 100644
--- a/inst/components/dist/components.js
+++ b/inst/components/dist/components.js
@@ -1,4 +1,4 @@
-/*! bslib 0.6.2.9000 | (c) 2012-2024 RStudio, PBC. | License: MIT + file LICENSE */
+/*! bslib 0.7.0 | (c) 2012-2024 RStudio, PBC. | License: MIT + file LICENSE */
"use strict";
(() => {
var __getOwnPropNames = Object.getOwnPropertyNames;
diff --git a/inst/components/dist/components.min.js b/inst/components/dist/components.min.js
index 2e695b3ae..5a012af60 100644
--- a/inst/components/dist/components.min.js
+++ b/inst/components/dist/components.min.js
@@ -1,4 +1,4 @@
-/*! bslib 0.6.2.9000 | (c) 2012-2024 RStudio, PBC. | License: MIT + file LICENSE */
+/*! bslib 0.7.0 | (c) 2012-2024 RStudio, PBC. | License: MIT + file LICENSE */
"use strict";(()=>{var f=(r,e)=>()=>(r&&(e=r(r=0)),e);var X=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var x=(r,e,t)=>{if(!e.has(r))throw TypeError("Cannot "+t)};var v=(r,e,t)=>(x(r,e,"read from private field"),t?t.call(r):e.get(r)),H=(r,e,t)=>{if(e.has(r))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(r):e.set(r,t)};var A=(r,e,t)=>(x(r,e,"access private method"),t);var h=(r,e,t)=>new Promise((n,i)=>{var s=o=>{try{d(t.next(o))}catch(b){i(b)}},l=o=>{try{d(t.throw(o))}catch(b){i(b)}},d=o=>o.done?n(o.value):Promise.resolve(o.value).then(s,l);d((t=t.apply(r,e)).next())});function y(r,e){u&&u.inputBindings.register(new r,"bslib."+e)}function w(r,e){return Object.prototype.hasOwnProperty.call(r,e)&&r[e]!==void 0}function k(r){let e=["a[href]","area[href]","button","details summary","input","iframe","select","textarea",'[contentEditable=""]','[contentEditable="true"]','[contentEditable="TRUE"]',"[tabindex]"],t=[':not([tabindex="-1"])',":not([disabled])"],n=e.map(s=>s+t.join("")),i=r.querySelectorAll(n.join(", "));return Array.from(i)}function E(...r){return h(this,null,function*(){if(!u)throw new Error("This function must be called in a Shiny app.");return u.renderContentAsync?yield u.renderContentAsync.apply(null,r):yield u.renderContent.apply(null,r)})}var u,m,L=f(()=>{"use strict";u=window.Shiny,m=u?u.InputBinding:class{}});var O,U=f(()=>{"use strict";L();O=class extends m{find(e){return $(e).find(".accordion.bslib-accordion-input")}getValue(e){let n=this._getItemInfo(e).filter(i=>i.isOpen()).map(i=>i.value);return n.length===0?null:n}subscribe(e,t){$(e).on("shown.bs.collapse.accordionInputBinding hidden.bs.collapse.accordionInputBinding",function(n){t(!0)})}unsubscribe(e){$(e).off(".accordionInputBinding")}receiveMessage(e,t){return h(this,null,function*(){let n=t.method;if(n==="set")this._setItems(e,t);else if(n==="open")this._openItems(e,t);else if(n==="close")this._closeItems(e,t);else if(n==="remove")this._removeItem(e,t);else if(n==="insert")yield this._insertItem(e,t);else if(n==="update")yield this._updateItem(e,t);else throw new Error(`Method not yet implemented: ${n}`)})}_setItems(e,t){let n=this._getItemInfo(e),i=this._getValues(e,n,t.values);n.forEach(s=>{i.indexOf(s.value)>-1?s.show():s.hide()})}_openItems(e,t){let n=this._getItemInfo(e),i=this._getValues(e,n,t.values);n.forEach(s=>{i.indexOf(s.value)>-1&&s.show()})}_closeItems(e,t){let n=this._getItemInfo(e),i=this._getValues(e,n,t.values);n.forEach(s=>{i.indexOf(s.value)>-1&&s.hide()})}_insertItem(e,t){return h(this,null,function*(){let n=this._findItem(e,t.target);n||(n=t.position==="before"?e.firstElementChild:e.lastElementChild);let i=t.panel;if(n?yield E(n,i,t.position==="before"?"beforeBegin":"afterEnd"):yield E(e,i),this._isAutoClosing(e)){let s=$(i.html).attr("data-value");$(e).find(`[data-value="${s}"] .accordion-collapse`).attr("data-bs-parent","#"+e.id)}})}_removeItem(e,t){let n=this._getItemInfo(e).filter(s=>t.target.indexOf(s.value)>-1),i=Shiny==null?void 0:Shiny.unbindAll;n.forEach(s=>{i&&i(s.item),s.item.remove()})}_updateItem(e,t){return h(this,null,function*(){let n=this._findItem(e,t.target);if(!n)throw new Error(`Unable to find an accordion_panel() with a value of ${t.target}`);if(w(t,"value")&&(n.dataset.value=t.value),w(t,"body")){let s=n.querySelector(".accordion-body");yield E(s,t.body)}let i=n.querySelector(".accordion-header");if(w(t,"title")){let s=i.querySelector(".accordion-title");yield E(s,t.title)}if(w(t,"icon")){let s=i.querySelector(".accordion-button > .accordion-icon");yield E(s,t.icon)}})}_getItemInfo(e){return Array.from(e.querySelectorAll(":scope > .accordion-item")).map(n=>this._getSingleItemInfo(n))}_getSingleItemInfo(e){let t=e.querySelector(".accordion-collapse"),n=()=>$(t).hasClass("show");return{item:e,value:e.dataset.value,isOpen:n,show:()=>{n()||$(t).collapse("show")},hide:()=>{n()&&$(t).collapse("hide")}}}_getValues(e,t,n){let i=n!==!0?n:t.map(l=>l.value);return this._isAutoClosing(e)&&(i=i.slice(i.length-1,i.length)),i}_findItem(e,t){return e.querySelector(`[data-value="${t}"]`)}_isAutoClosing(e){return e.classList.contains("autoclose")}};y(O,"accordion")});var S,R=f(()=>{"use strict";S=class{constructor(){this.resizeObserverEntries=[],this.resizeObserver=new ResizeObserver(e=>{let t=new Event("resize");if(window.dispatchEvent(t),!window.Shiny)return;let n=[];for(let i of e)i.target instanceof HTMLElement&&i.target.querySelector(".shiny-bound-output")&&i.target.querySelectorAll(".shiny-bound-output").forEach(s=>{if(n.includes(s))return;let{binding:l,onResize:d}=$(s).data("shinyOutputBinding");if(!l||!l.resize)return;let o=s.shinyResizeObserver;if(o&&o!==this||(o||(s.shinyResizeObserver=this),d(s),n.push(s),!s.classList.contains("shiny-plot-output")))return;let b=s.querySelector('img:not([width="100%"])');b&&b.setAttribute("width","100%")})})}observe(e){this.resizeObserver.observe(e),this.resizeObserverEntries.push(e)}unobserve(e){let t=this.resizeObserverEntries.indexOf(e);t<0||(this.resizeObserver.unobserve(e),this.resizeObserverEntries.splice(t,1))}flush(){this.resizeObserverEntries.forEach(e=>{document.body.contains(e)||this.unobserve(e)})}}});var _,q=f(()=>{"use strict";_=class{constructor(e,t){this.watching=new Set,this.observer=new MutationObserver(n=>{let i=new Set;for(let{type:s,removedNodes:l}of n)if(s==="childList"&&l.length!==0)for(let d of l)d instanceof HTMLElement&&(d.matches(e)&&i.add(d),d.querySelector(e)&&d.querySelectorAll(e).forEach(o=>i.add(o)));if(i.size!==0)for(let s of i)try{t(s)}catch(l){console.error(l)}})}observe(e){let t=this._flush();if(this.watching.has(e)){if(!t)return}else this.watching.add(e);t?this._restartObserver():this.observer.observe(e,{childList:!0,subtree:!0})}unobserve(e){this.watching.has(e)&&(this.watching.delete(e),this._flush(),this._restartObserver())}_restartObserver(){this.observer.disconnect();for(let e of this.watching)this.observer.observe(e,{childList:!0,subtree:!0})}_flush(){let e=!1,t=Array.from(this.watching);for(let n of t)document.body.contains(n)||(this.watching.delete(n),e=!0);return e}}});var a,g,B=f(()=>{"use strict";L();R();q();a=class{constructor(e){var t;e.removeAttribute(a.attr.ATTR_INIT),(t=e.querySelector(`script[${a.attr.ATTR_INIT}]`))==null||t.remove(),this.card=e,a.instanceMap.set(e,this),a.shinyResizeObserver.observe(this.card),a.cardRemovedObserver.observe(document.body),this._addEventListeners(),this.overlay=this._createOverlay(),this._setShinyInput(),this._exitFullScreenOnEscape=this._exitFullScreenOnEscape.bind(this),this._trapFocusExit=this._trapFocusExit.bind(this)}enterFullScreen(e){var t;e&&e.preventDefault(),this.card.id&&this.overlay.anchor.setAttribute("aria-controls",this.card.id),document.addEventListener("keydown",this._exitFullScreenOnEscape,!1),document.addEventListener("keydown",this._trapFocusExit,!0),this.card.setAttribute(a.attr.ATTR_FULL_SCREEN,"true"),document.body.classList.add(a.attr.CLASS_HAS_FULL_SCREEN),this.card.insertAdjacentElement("beforebegin",this.overlay.container),(!this.card.contains(document.activeElement)||(t=document.activeElement)!=null&&t.classList.contains(a.attr.CLASS_FULL_SCREEN_ENTER))&&(this.card.setAttribute("tabindex","-1"),this.card.focus()),this._emitFullScreenEvent(!0),this._setShinyInput()}exitFullScreen(){document.removeEventListener("keydown",this._exitFullScreenOnEscape,!1),document.removeEventListener("keydown",this._trapFocusExit,!0),this.overlay.container.remove(),this.card.setAttribute(a.attr.ATTR_FULL_SCREEN,"false"),this.card.removeAttribute("tabindex"),document.body.classList.remove(a.attr.CLASS_HAS_FULL_SCREEN),this._emitFullScreenEvent(!1),this._setShinyInput()}_setShinyInput(){if(!this.card.classList.contains(a.attr.CLASS_SHINY_INPUT)||!u)return;if(!u.setInputValue){setTimeout(()=>this._setShinyInput(),0);return}let e=this.card.getAttribute(a.attr.ATTR_FULL_SCREEN);u.setInputValue(this.card.id+"_full_screen",e==="true")}_emitFullScreenEvent(e){let t=new CustomEvent("bslib.card",{bubbles:!0,detail:{fullScreen:e}});this.card.dispatchEvent(t)}_addEventListeners(){let e=this.card.querySelector(`:scope > * > .${a.attr.CLASS_FULL_SCREEN_ENTER}`);e&&e.addEventListener("click",t=>this.enterFullScreen(t))}_exitFullScreenOnEscape(e){if(!(e.target instanceof HTMLElement))return;let t=["select[open]","input[aria-expanded='true']"];e.target.matches(t.join(", "))||e.key==="Escape"&&this.exitFullScreen()}_trapFocusExit(e){if(!(e instanceof KeyboardEvent)||e.key!=="Tab")return;let t=e.target===this.card,n=e.target===this.overlay.anchor,i=this.card.contains(e.target),s=()=>{e.preventDefault(),e.stopImmediatePropagation()};if(!(i||t||n)){s(),this.card.focus();return}let l=k(this.card).filter(I=>!I.classList.contains(a.attr.CLASS_FULL_SCREEN_ENTER));if(!(l.length>0)){s(),this.overlay.anchor.focus();return}if(t)return;let o=l[l.length-1],b=e.target===o;if(n&&e.shiftKey){s(),o.focus();return}if(b&&!e.shiftKey){s(),this.overlay.anchor.focus();return}}_createOverlay(){let e=document.createElement("div");e.id=a.attr.ID_FULL_SCREEN_OVERLAY,e.onclick=this.exitFullScreen.bind(this);let t=this._createOverlayCloseAnchor();return e.appendChild(t),{container:e,anchor:t}}_createOverlayCloseAnchor(){let e=document.createElement("a");return e.classList.add(a.attr.CLASS_FULL_SCREEN_EXIT),e.tabIndex=0,e.setAttribute("aria-expanded","true"),e.setAttribute("aria-label","Close card"),e.setAttribute("role","button"),e.onclick=t=>{this.exitFullScreen(),t.stopPropagation()},e.onkeydown=t=>{(t.key==="Enter"||t.key===" ")&&this.exitFullScreen()},e.innerHTML=this._overlayCloseHtml(),e}_overlayCloseHtml(){return"Close "}static getInstance(e){return a.instanceMap.get(e)}static initializeAllCards(e=!0){if(document.readyState==="loading"){a.onReadyScheduled||(a.onReadyScheduled=!0,document.addEventListener("DOMContentLoaded",()=>{a.initializeAllCards(!1)}));return}e&&a.shinyResizeObserver.flush();let t=`.${a.attr.CLASS_CARD}[${a.attr.ATTR_INIT}]`;if(!document.querySelector(t))return;document.querySelectorAll(t).forEach(i=>new a(i))}},g=a;g.attr={ATTR_INIT:"data-bslib-card-init",CLASS_CARD:"bslib-card",ATTR_FULL_SCREEN:"data-full-screen",CLASS_HAS_FULL_SCREEN:"bslib-has-full-screen",CLASS_FULL_SCREEN_ENTER:"bslib-full-screen-enter",CLASS_FULL_SCREEN_EXIT:"bslib-full-screen-exit",ID_FULL_SCREEN_OVERLAY:"bslib-full-screen-overlay",CLASS_SHINY_INPUT:"bslib-card-input"},g.shinyResizeObserver=new S,g.cardRemovedObserver=new _(`.${a.attr.CLASS_CARD}`,e=>{let t=a.getInstance(e);t&&t.card.getAttribute(a.attr.ATTR_FULL_SCREEN)==="true"&&t.exitFullScreen()}),g.instanceMap=new WeakMap,g.onReadyScheduled=!1;window.bslib=window.bslib||{};window.bslib.Card=g});var c,p,z,D=f(()=>{"use strict";L();R();c=class{constructor(e){this.windowSize="";var i;c.instanceMap.set(e,this),this.layout={container:e,main:e.querySelector(":scope > .main"),sidebar:e.querySelector(":scope > .sidebar"),toggle:e.querySelector(":scope > .collapse-toggle")};let t=this.layout.sidebar.querySelector(":scope > .sidebar-content > .accordion");t&&((i=t==null?void 0:t.parentElement)==null||i.classList.add("has-accordion"),t.classList.add("accordion-flush")),this._initSidebarCounters(),this._initSidebarState(),(this._isCollapsible("desktop")||this._isCollapsible("mobile"))&&this._initEventListeners(),c.shinyResizeObserver.observe(this.layout.main),e.removeAttribute("data-bslib-sidebar-init");let n=e.querySelector(":scope > script[data-bslib-sidebar-init]");n&&e.removeChild(n)}get isClosed(){return this.layout.container.classList.contains(c.classes.COLLAPSE)}static getInstance(e){return c.instanceMap.get(e)}_isCollapsible(e="desktop"){let{container:t}=this.layout,n=e==="desktop"?"collapsibleDesktop":"collapsibleMobile",i=t.dataset[n];return i===void 0?!0:i.trim().toLowerCase()!=="false"}static initCollapsibleAll(e=!0){if(document.readyState==="loading"){c.onReadyScheduled||(c.onReadyScheduled=!0,document.addEventListener("DOMContentLoaded",()=>{c.initCollapsibleAll(!1)}));return}let t=`.${c.classes.LAYOUT}[data-bslib-sidebar-init]`;if(!document.querySelector(t))return;e&&c.shinyResizeObserver.flush(),document.querySelectorAll(t).forEach(i=>new c(i))}_initEventListeners(){var t;let{toggle:e}=this.layout;e.addEventListener("click",n=>{n.preventDefault(),this.toggle("toggle")}),(t=e.querySelector(".collapse-icon"))==null||t.addEventListener("transitionend",()=>this._finalizeState()),!(this._isCollapsible("desktop")&&this._isCollapsible("mobile"))&&window.addEventListener("resize",()=>this._handleWindowResizeEvent())}_initSidebarCounters(){let{container:e}=this.layout,t=`.${c.classes.LAYOUT}> .main > .${c.classes.LAYOUT}:not([data-bslib-sidebar-open="always"])`;if(!(e.querySelector(t)===null))return;function i(o){return o=o?o.parentElement:null,o&&o.classList.contains("main")&&(o=o.parentElement),o&&o.classList.contains(c.classes.LAYOUT)?o:null}let s=[e],l=i(e);for(;l;)s.unshift(l),l=i(l);let d={left:0,right:0};s.forEach(function(o){let I=o.classList.contains("sidebar-right")?d.right++:d.left++;o.style.setProperty("--_js-toggle-count-this-side",I.toString()),o.style.setProperty("--_js-toggle-count-max-side",Math.max(d.right,d.left).toString())})}_getWindowSize(){let{container:e}=this.layout;return window.getComputedStyle(e).getPropertyValue("--bslib-sidebar-js-window-size").trim()}_initialToggleState(){var i,s;let{container:e}=this.layout,t=this.windowSize==="desktop"?"openDesktop":"openMobile",n=(s=(i=e.dataset[t])==null?void 0:i.trim())==null?void 0:s.toLowerCase();return n===void 0||["open","always"].includes(n)?"open":["close","closed"].includes(n)?"close":"open"}_initSidebarState(){this.windowSize=this._getWindowSize();let e=this._initialToggleState();this.toggle(e,!0)}_handleWindowResizeEvent(){let e=this._getWindowSize();!e||e==this.windowSize||this._initSidebarState()}toggle(e,t=!1){typeof e=="undefined"&&(e="toggle");let{container:n,sidebar:i}=this.layout,s=this.isClosed;if(["open","close","toggle"].indexOf(e)===-1)throw new Error(`Unknown method ${e}`);if(e==="toggle"&&(e=s?"open":"close"),s&&e==="close"||!s&&e==="open"){t&&this._finalizeState();return}e==="open"&&(i.hidden=!1),n.classList.toggle(c.classes.TRANSITIONING,!t),n.classList.toggle(c.classes.COLLAPSE),t&&this._finalizeState()}_finalizeState(){let{container:e,sidebar:t,toggle:n}=this.layout;e.classList.remove(c.classes.TRANSITIONING),t.hidden=this.isClosed,n.setAttribute("aria-expanded",this.isClosed?"false":"true");let i=new CustomEvent("bslib.sidebar",{bubbles:!0,detail:{open:!this.isClosed}});t.dispatchEvent(i),$(t).trigger("toggleCollapse.sidebarInputBinding"),$(t).trigger(this.isClosed?"hidden":"shown")}},p=c;p.shinyResizeObserver=new S,p.classes={LAYOUT:"bslib-sidebar-layout",COLLAPSE:"sidebar-collapsed",TRANSITIONING:"transitioning"},p.onReadyScheduled=!1,p.instanceMap=new WeakMap;z=class extends m{find(e){return $(e).find(`.${p.classes.LAYOUT} > .bslib-sidebar-input`)}getValue(e){let t=p.getInstance(e.parentElement);return t?!t.isClosed:!1}setValue(e,t){let n=t?"open":"close";this.receiveMessage(e,{method:n})}subscribe(e,t){$(e).on("toggleCollapse.sidebarInputBinding",function(n){t(!0)})}unsubscribe(e){$(e).off(".sidebarInputBinding")}receiveMessage(e,t){let n=p.getInstance(e.parentElement);n&&n.toggle(t.method)}};y(z,"sidebar");window.bslib=window.bslib||{};window.bslib.Sidebar=p});var T,M,C,N,F,P=f(()=>{"use strict";L();F=class extends m{constructor(){super(...arguments);H(this,C);H(this,T,new WeakMap);H(this,M,new WeakMap)}find(t){return $(t).find(".bslib-task-button")}getValue(t){var n;return{value:(n=v(this,T).get(t))!=null?n:0,autoReset:t.hasAttribute("data-auto-reset")}}getType(){return"bslib.taskbutton"}subscribe(t,n){v(this,M).has(t)&&this.unsubscribe(t);let i=()=>{var s;v(this,T).set(t,((s=v(this,T).get(t))!=null?s:0)+1),n(!0),A(this,C,N).call(this,t,"busy")};v(this,M).set(t,i),t.addEventListener("click",i)}unsubscribe(t){let n=v(this,M).get(t);n&&t.removeEventListener("click",n)}receiveMessage(i,s){return h(this,arguments,function*(t,{state:n}){A(this,C,N).call(this,t,n)})}};T=new WeakMap,M=new WeakMap,C=new WeakSet,N=function(t,n){t.disabled=n==="busy";let i=t.querySelector("bslib-switch-inline");i&&(i.case=n)};y(F,"task-button")});function W(r){if(window.Shiny)for(let[e,t]of Object.entries(r))Shiny.addCustomMessageHandler(e,t)}var V=f(()=>{"use strict"});var K=X(j=>{U();B();D();P();L();V();var G={"bslib.toggle-input-binary":r=>h(j,null,function*(){let e=document.getElementById(r.id);e||console.warn("[bslib.toggle-input-binary] No element found",r);let t=$(e).data("shiny-input-binding");if(!(t instanceof m)){console.warn("[bslib.toggle-input-binary] No input binding found",r);return}let n=r.value;typeof n=="undefined"&&(n=!t.getValue(e)),yield t.receiveMessage(e,{value:n})})};window.Shiny&&W(G);function Y(){let r=document.createElement("div");r.innerHTML=`