diff --git a/.Rbuildignore b/.Rbuildignore index e5951b7e6..36a105596 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -29,3 +29,4 @@ inst/lib/bsw3/.npmignore ^\.github$ ^\.gitattributes$ ^CODE_OF_CONDUCT\.md$ +^cran-comments\.md$ diff --git a/DESCRIPTION b/DESCRIPTION index ff5e25378..688bcb7b0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: bslib Title: Custom 'Bootstrap' 'Sass' Themes for 'shiny' and 'rmarkdown' -Version: 0.5.1.9000 +Version: 0.6.0 Authors@R: c( person("Carson", "Sievert", , "carson@posit.co", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-4958-2844")), @@ -32,7 +32,7 @@ Imports: base64enc, cachem, grDevices, - htmltools (>= 0.5.6.9001), + htmltools (>= 0.5.7), jquerylib (>= 0.1.3), jsonlite, lifecycle, @@ -49,13 +49,10 @@ Suggests: magrittr, rappdirs, rmarkdown (>= 2.7), - shiny (>= 1.7.5.9001), + shiny (>= 1.8.0), testthat, thematic, withr -Remotes: - rstudio/htmltools, - rstudio/shiny Config/Needs/deploy: BH, chiflights22, diff --git a/NEWS.md b/NEWS.md index 761dbf1f9..77116b945 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,39 +1,46 @@ -# bslib (development version) +# bslib 0.6.0 ## Breaking changes * `bs_theme()` now defaults to `preset="shiny"`. This provides an additional set of theming defaults and rules that make it easier to create Shiny apps (in particular, dashboards) that look good out of the box. To revert to the previous behavior, set `bs_theme(preset="bootstrap")`. (#711) + * `value_box()` no longer defaults to `theme_color = "primary"`. To restore the previous behavior, please use `theme = "primary"`. In addition to the default style change, the `theme_color` is now deprecated in favor of `theme`. (#758) + * `page_navbar()` now defaults to `underline = TRUE`, meaning that navigation links in the navbar now have underline styling by default (set `underline = FALSE` to revert to previous behavior). (#784) -* `page()` now returns a `
` tag instead of `tagList()`. This change allows `page()` to treat named arguments as HTML attributes. (#809) + +* `page()` now returns a `` tag instead of `tagList()`. This change allows `page()` to treat named arguments as HTML attributes for the `` tag, making it possible to add page-level classes or other attributes. (#809) + * The JS/CSS assets behind `{bslib}` components (e.g., `card()`, `value_box()`, etc) are all now bundled into one `htmlDependency()` and included with the return value of `bs_theme_dependencies()` (previously they were attached at the component-level). (#810) -* `layout_column_wrap()` no longer requires `width` and `width` is no longer the first argument, meaning that `width` must be named if used. The new default is `width = "200px"`, which combines with `fixed_width = FALSE` and produces an automatically responsive layout where each column is at least 200px wide. This means that, in most cases, `layout_column_wrap()` can layout an unknown number of items without you having to set `width`. (#853) + +* `layout_column_wrap()` no longer requires `width` and `width` is no longer the first argument, meaning that `width` must be named if used. The new default is `width = "200px"`, which combines with `fixed_width = FALSE` to produce a responsive layout where each column is at least 200px wide. This means that, in most cases, `layout_column_wrap()` can automatically layout an unknown number of items without you having to set `width`. (#853) ## New features -* Upgraded the default version of Bootstrap from v5.2.2 to v5.3.1. The most notable thing that comes with the update is the ability to toggle between light/dark [color modes](https://getbootstrap.com/docs/5.3/customize/color-modes/) purely client-side (i.e., no calls to Sass required). (#749, #764) +* The default version of Bootstrap is now v5.3.1, upgraded from v5.2.2. The most notable thing that comes with the update is the ability to toggle between light/dark [color modes](https://getbootstrap.com/docs/5.3/customize/color-modes/) purely client-side (i.e., no calls to Sass required). (#749, #764) -* Added new `navset_underline()` & `navset_card_underline()` functions as well as a `underline` argument to `page_navbar()` to leverage the new [nav-underline](https://getbootstrap.com/docs/5.3/components/navs-tabs/#underline) styling on navigation links. (#784) +* Added `input_dark_mode()`, a new input control that provides a toggle button that can be used to switch between the dark and light modes when using Bootstrap 5.3. By default, dark mode is applied automatically if the user's operating system is also in dark mode. App authors can toggle dark mode programmatically from the server using `toggle_dark_mode()`, and if you provide `input_dark_mode()` with an `id`, you can read the current color mode via the corresponding input value. (#787) -* `value_box()` now supports many new themes and styles, or fully customizable themes using the new `value_box_theme()` function. To reflect the new capabilities, we've replaced `theme_color` with a new `theme` argument. The previous argument will continue work as expected, but with a deprecation warning. (#758) +* Shiny's Bootstrap theme preset is now used by default in `bs_theme()` and all related `page_*()` functions in bslib. This theme brings a fresh new design to all Shiny apps and dashboards created with bslib. This dashboard design anticipates heavy use of cards for organizing content, and works best with a gray background for contrast with minimalistic white cards. This treatment can be enabled in `page_sidebar()`, `page_fillable()` and other `page_*()` functions by adding the `bslib-page-dashboard` class to the page container or body tag. - In addition to the Bootstrap theme names (`primary` ,`secondary`, etc.), you can now use the main Boostrap colors (`purple`, `blue`, `red`, etc.). You can also choose to apply the color to the background or foreground by prepending a `bg-` or `text-` prefix to the theme or color name. Finally, we've also added new gradient themes allowing you to pair any two color names as `bg-gradient-{from}-{to}` (e.g., `bg-gradient-purple-blue`). + The preset can also be customized using the `$bslib-dashboard-design` and `$bslib-enable-shadows` Sass variables. Set these to `false` to disable the dashboard treatment and card shadows, respectively. These variables can be set via `bs_theme()`, e.g. `bs_theme("bslib-dashboard-design" = "false")`. (#897, #906) - These named color themes aren't limited to value boxes: because they're powered by small utility classes, you can use them anywhere within your bslib-powered UI. +* `value_box()` has been updated with a number of new features and improvements: -* Added `showcase_bottom()`, a new `value_box()` layout that places the showcase below the value box title and value, perfect for a full-bleed plot. (#758) + * `value_box()` now supports many new themes and styles, or fully customizable themes using the new `value_box_theme()` function. To reflect the new capabilities, we've replaced `theme_color` with a new `theme` argument. The previous argument will continue work as expected, but with a deprecation warning. (#758) -* `showcase_left_center()` and `showcase_top_right()` no longer take two values for the `width` argument. Instead, they now take a single value (e.g., `width = "30%"`) representing the width of the showcase are in the value box. Furthermore, they've both gained `width_full_screen` arguments that determine the width of the showcase area when the value box is expanded to fill the screen. (#758) + In addition to the Bootstrap theme names (`primary` ,`secondary`, etc.), you can now use the main Boostrap colors (`purple`, `blue`, `red`, etc.). You can also choose to apply the color to the background or foreground by prepending a `bg-` or `text-` prefix to the theme or color name. Finally, we've also added new gradient themes allowing you to pair any two color names as `bg-gradient-{from}-{to}` (e.g., `bg-gradient-purple-blue`). -* The `showcase_layout` argument of `value_box()` now accepts one of three character values: `"left center"`, `"top right"`, `"bottom"`. (#758) + These named color themes aren't limited to value boxes: because they're powered by small utility classes, you can use them anywhere within your bslib-powered UI. -* A new [Build a Box app](https://bslib.shinyapps.io/build-a-box/) is now available online or via bslib. See `?value_box()` for details. The app helps preview a set of value boxes while you configure and customize their appearance and provides you with code to copy and paste into your app. (#790) + * Added `showcase_bottom()`, a new `value_box()` layout that places the showcase below the value box title and value, perfect for a full-bleed plot. (#758) -* Added `input_dark_mode()`, a new input control that provides a toggle button that can be used to switch between the dark and light modes when using Bootstrap 5.3. By default, dark mode is applied automatically if the user's operating system is also in dark mode. App authors can toggle dark mode programmatically from the server using `toggle_dark_mode()`, and if you provide `input_dark_mode()` with an `id`, you can read the current color mode via the corresponding input value. (#787) + * `showcase_left_center()` and `showcase_top_right()` no longer take two values for the `width` argument. Instead, they now take a single value (e.g., `width = "30%"`) representing the width of the showcase are in the value box. Furthermore, they've both gained `width_full_screen` arguments that determine the width of the showcase area when the value box is expanded to fill the screen. (#758) -* Shiny's Bootstrap theme preset is now used by default in `bs_theme()` and all related `page_*()` functions in bslib. This theme brings a fresh new design to all Shiny apps and dashboards created with bslib. This dashboard design anticipates heavy use of cards for organizing content, and works best with a gray background for contrast with minimalistic white cards. This treatment can be enabled in `page_sidebar()`, `page_fillable()` and other `page_*()` functions by adding the `bslib-page-dashboard` class to the page container or body tag. + * The `showcase_layout` argument of `value_box()` now accepts one of three character values: `"left center"`, `"top right"`, `"bottom"`. (#758) - The preset can also be customized using the `$bslib-dashboard-design` and `$bslib-enable-shadows` Sass variables. Set these to `false` to disable the dashboard treatment and card shadows, respectively. These variables can be set via `bs_theme()`, e.g. `bs_theme("bslib-dashboard-design" = "false")`. (#897, #906) + * A new [Build a Box app](https://bslib.shinyapps.io/build-a-box/) is now available online or via bslib. See `?value_box()` for details. The app helps preview a set of value boxes while you configure and customize their appearance and provides you with code to copy and paste into your app. (#790) + +* Added new `navset_underline()` & `navset_card_underline()` functions as well as a `underline` argument to `page_navbar()` to leverage the new [nav-underline](https://getbootstrap.com/docs/5.3/components/navs-tabs/#underline) styling on navigation links. (#784) ## Improvements diff --git a/R/bs-theme-layers.R b/R/bs-theme-layers.R index 8c7061679..fcd0d6839 100644 --- a/R/bs-theme-layers.R +++ b/R/bs-theme-layers.R @@ -87,7 +87,7 @@ #' ) #' #' @describeIn bs_bundle Add Bootstrap Sass -#' [variable defaults](http://rstudio.github.io/bslib/articles/bs5-variables/index.html). +#' [variable defaults](https://rstudio.github.io/bslib/articles/bs5-variables/index.html). #' @export bs_add_variables <- function(theme, ..., .where = "defaults", .default_flag = identical(.where, "defaults")) { assert_bs_theme(theme) diff --git a/R/print.R b/R/print.R index 5b3876c28..a920e53b6 100644 --- a/R/print.R +++ b/R/print.R @@ -25,7 +25,7 @@ print.bslib_fragment <- function(x, ...) { #' Save a bslib page/fragment as HTML #' -#' @param x a bslib page/fragment. +#' @param html a bslib page/fragment. #' @param ... passed along to an underlying [save_html()] method. #' @export #' @keywords internal diff --git a/cran-comments.md b/cran-comments.md new file mode 100644 index 000000000..39962c52e --- /dev/null +++ b/cran-comments.md @@ -0,0 +1,7 @@ + +## revdepcheck results + +We checked 57 reverse dependencies (51 from CRAN + 6 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package. + + * We saw 0 new problems + * We failed to check 0 packages diff --git a/inst/components/dist/components.js b/inst/components/dist/components.js index c0e94d64d..0bb75c56c 100644 --- a/inst/components/dist/components.js +++ b/inst/components/dist/components.js @@ -1,4 +1,4 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ +/*! bslib 0.6.0 | (c) 2012-2023 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 4cc2a6373..eb1104abb 100644 --- a/inst/components/dist/components.min.js +++ b/inst/components/dist/components.min.js @@ -1,4 +1,4 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ +/*! bslib 0.6.0 | (c) 2012-2023 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 h=(r,e,t)=>new Promise((n,s)=>{var i=o=>{try{d(t.next(o))}catch(p){s(p)}},c=o=>{try{d(t.throw(o))}catch(p){s(p)}},d=o=>o.done?n(o.value):Promise.resolve(o.value).then(i,c);d((t=t.apply(r,e)).next())});function L(r,e){window.Shiny&&Shiny.inputBindings.register(new r,"bslib."+e)}function E(r,e){return Object.prototype.hasOwnProperty.call(r,e)&&r[e]!==void 0}function w(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(i=>i+t.join("")),s=r.querySelectorAll(n.join(", "));return Array.from(s)}function g(...r){return h(this,null,function*(){if(!window.Shiny)throw new Error("This function must be called in a Shiny app.");return Shiny.renderContentAsync?yield Shiny.renderContentAsync.apply(null,r):yield Shiny.renderContent.apply(null,r)})}var b,v=f(()=>{"use strict";b=window.Shiny?Shiny.InputBinding:class{}});var M,H=f(()=>{"use strict";v();M=class extends b{find(e){return $(e).find(".accordion.bslib-accordion-input")}getValue(e){let n=this._getItemInfo(e).filter(s=>s.isOpen()).map(s=>s.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),s=this._getValues(e,n,t.values);n.forEach(i=>{s.indexOf(i.value)>-1?i.show():i.hide()})}_openItems(e,t){let n=this._getItemInfo(e),s=this._getValues(e,n,t.values);n.forEach(i=>{s.indexOf(i.value)>-1&&i.show()})}_closeItems(e,t){let n=this._getItemInfo(e),s=this._getValues(e,n,t.values);n.forEach(i=>{s.indexOf(i.value)>-1&&i.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 s=t.panel;if(n?yield g(n,s,t.position==="before"?"beforeBegin":"afterEnd"):yield g(e,s),this._isAutoClosing(e)){let i=$(s.html).attr("data-value");$(e).find(`[data-value="${i}"] .accordion-collapse`).attr("data-bs-parent","#"+e.id)}})}_removeItem(e,t){let n=this._getItemInfo(e).filter(i=>t.target.indexOf(i.value)>-1),s=Shiny==null?void 0:Shiny.unbindAll;n.forEach(i=>{s&&s(i.item),i.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(E(t,"value")&&(n.dataset.value=t.value),E(t,"body")){let i=n.querySelector(".accordion-body");yield g(i,t.body)}let s=n.querySelector(".accordion-header");if(E(t,"title")){let i=s.querySelector(".accordion-title");yield g(i,t.title)}if(E(t,"icon")){let i=s.querySelector(".accordion-button > .accordion-icon");yield g(i,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 s=n!==!0?n:t.map(c=>c.value);return this._isAutoClosing(e)&&(s=s.slice(s.length-1,s.length)),s}_findItem(e,t){return e.querySelector(`[data-value="${t}"]`)}_isAutoClosing(e){return e.classList.contains("autoclose")}};L(M,"accordion")});var y,T=f(()=>{"use strict";y=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 s of e)s.target instanceof HTMLElement&&s.target.querySelector(".shiny-bound-output")&&s.target.querySelectorAll(".shiny-bound-output").forEach(i=>{if(n.includes(i))return;let{binding:c,onResize:d}=$(i).data("shinyOutputBinding");if(!c||!c.resize)return;let o=i.shinyResizeObserver;if(o&&o!==this||(o||(i.shinyResizeObserver=this),d(i),n.push(i),!i.classList.contains("shiny-plot-output")))return;let p=i.querySelector('img:not([width="100%"])');p&&p.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 a,m,I=f(()=>{"use strict";v();T();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),this._addEventListeners(),this.overlay=this._createOverlay(),this._exitFullScreenOnEscape=this._exitFullScreenOnEscape.bind(this),this._trapFocusExit=this._trapFocusExit.bind(this)}enterFullScreen(e){var t;e&&e.preventDefault(),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())}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)}_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,s=this.card.contains(e.target),i=()=>{e.preventDefault(),e.stopImmediatePropagation()};if(!(s||t||n)){i(),this.card.focus();return}let c=w(this.card).filter(S=>!S.classList.contains(a.attr.CLASS_FULL_SCREEN_ENTER));if(!(c.length>0)){i(),this.overlay.anchor.focus();return}if(t)return;let o=c[c.length-1],p=e.target===o;if(n&&e.shiftKey){i(),o.focus();return}if(p&&!e.shiftKey){i(),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.onclick=()=>this.exitFullScreen(),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(s=>new a(s))}},m=a;m.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"},m.shinyResizeObserver=new y,m.instanceMap=new WeakMap,m.onReadyScheduled=!1;window.bslib=window.bslib||{};window.bslib.Card=m});var l,u,C,A=f(()=>{"use strict";v();T();l=class{constructor(e){var s;l.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&&((s=t==null?void 0:t.parentElement)==null||s.classList.add("has-accordion"),t.classList.add("accordion-flush")),this.layout.toggle&&(this._initEventListeners(),this._initSidebarCounters(),this._initDesktop()),l.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(l.classes.COLLAPSE)}static getInstance(e){return l.instanceMap.get(e)}static initCollapsibleAll(e=!0){if(document.readyState==="loading"){l.onReadyScheduled||(l.onReadyScheduled=!0,document.addEventListener("DOMContentLoaded",()=>{l.initCollapsibleAll(!1)}));return}let t=`.${l.classes.LAYOUT}[data-bslib-sidebar-init]`;if(!document.querySelector(t))return;e&&l.shinyResizeObserver.flush(),document.querySelectorAll(t).forEach(s=>new l(s))}_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())}_initSidebarCounters(){let{container:e}=this.layout,t=`.${l.classes.LAYOUT}> .main > .${l.classes.LAYOUT}:not([data-bslib-sidebar-open="always"])`;if(!(e.querySelector(t)===null))return;function s(o){return o=o?o.parentElement:null,o&&o.classList.contains("main")&&(o=o.parentElement),o&&o.classList.contains(l.classes.LAYOUT)?o:null}let i=[e],c=s(e);for(;c;)i.unshift(c),c=s(c);let d={left:0,right:0};i.forEach(function(o){let S=o.classList.contains("sidebar-right")?d.right++:d.left++;o.style.setProperty("--_js-toggle-count-this-side",S.toString()),o.style.setProperty("--_js-toggle-count-max-side",Math.max(d.right,d.left).toString())})}_initDesktop(){var s;let{container:e}=this.layout;if(((s=e.dataset.bslibSidebarOpen)==null?void 0:s.trim())!=="desktop")return;let n=window.getComputedStyle(e).getPropertyValue("--bslib-sidebar-js-init-collapsed").trim()==="true"?"close":"open";this.toggle(n,!0)}toggle(e,t=!1){typeof e=="undefined"&&(e="toggle");let{container:n,sidebar:s}=this.layout,i=this.isClosed;if(["open","close","toggle"].indexOf(e)===-1)throw new Error(`Unknown method ${e}`);if(e==="toggle"&&(e=i?"open":"close"),i&&e==="close"||!i&&e==="open"){t&&this._finalizeState();return}e==="open"&&(s.hidden=!1),n.classList.toggle(l.classes.TRANSITIONING,!t),n.classList.toggle(l.classes.COLLAPSE),t&&this._finalizeState()}_finalizeState(){let{container:e,sidebar:t,toggle:n}=this.layout;e.classList.remove(l.classes.TRANSITIONING),t.hidden=this.isClosed,n.setAttribute("aria-expanded",this.isClosed?"false":"true");let s=new CustomEvent("bslib.sidebar",{bubbles:!0,detail:{open:!this.isClosed}});t.dispatchEvent(s),$(t).trigger("toggleCollapse.sidebarInputBinding"),$(t).trigger(this.isClosed?"hidden":"shown")}},u=l;u.shinyResizeObserver=new y,u.classes={LAYOUT:"bslib-sidebar-layout",COLLAPSE:"sidebar-collapsed",TRANSITIONING:"transitioning"},u.onReadyScheduled=!1,u.instanceMap=new WeakMap;C=class extends b{find(e){return $(e).find(`.${u.classes.LAYOUT} > .bslib-sidebar-input`)}getValue(e){let t=u.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=u.getInstance(e.parentElement);n&&n.toggle(t.method)}};L(C,"sidebar");window.bslib=window.bslib||{};window.bslib.Sidebar=u});function O(r){if(window.Shiny)for(let[e,t]of Object.entries(r))Shiny.addCustomMessageHandler(e,t)}var _=f(()=>{"use strict"});var N=x(F=>{H();I();A();v();_();var z={"bslib.toggle-input-binary":r=>h(F,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 b)){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&&O(z);function R(){let r=document.createElement("div");r.innerHTML=`