diff --git a/NEWS.md b/NEWS.md index 0c31b5ca0..23eb91a25 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,7 @@ * `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) +* 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) ## New features diff --git a/R/accordion.R b/R/accordion.R index be62b6e6f..bd771822e 100644 --- a/R/accordion.R +++ b/R/accordion.R @@ -113,8 +113,7 @@ accordion <- function(..., id = NULL, open = NULL, multiple = TRUE, class = NULL height = validateCssUnit(height) ), !!!attrs, - !!!children, - accordion_dependency() + !!!children ) tag <- tag_require(tag, version = 5, caller = "accordion()") @@ -276,14 +275,3 @@ check_character <- function(x, max_length = Inf, min_length = 1, call = rlang::c } x } - -accordion_dependency <- function() { - list( - component_dependency_js("accordion"), - bs_dependency_defer(accordion_dependency_sass) - ) -} - -accordion_dependency_sass <- function(theme) { - component_dependency_sass(theme, "accordion") -} diff --git a/R/bs-dependencies.R b/R/bs-dependencies.R index f43ba590f..5b97ed205 100644 --- a/R/bs-dependencies.R +++ b/R/bs-dependencies.R @@ -147,6 +147,7 @@ bs_theme_dependencies <- function( meta = list(viewport = "width=device-width, initial-scale=1, shrink-to-fit=no") ) ), + if (version >= 5) component_dependencies(), htmlDependencies(out_file) )) } diff --git a/R/card.R b/R/card.R index a8f443b85..725c43835 100644 --- a/R/card.R +++ b/R/card.R @@ -72,7 +72,6 @@ card <- function(..., full_screen = FALSE, height = NULL, max_height = NULL, min !!!attribs, !!!children, if (full_screen) full_screen_toggle(), - card_dependency(), card_init_js() ) @@ -281,17 +280,6 @@ full_screen_toggle <- function() { ) } -card_dependency <- function() { - list( - component_dependency_js("card"), - bs_dependency_defer(card_dependency_sass) - ) -} - -card_dependency_sass <- function(theme) { - component_dependency_sass(theme, "card") -} - card_init_js <- function() { tags$script( `data-bslib-card-init` = NA, diff --git a/R/input-switch.R b/R/input-switch.R index 2567fea8e..b3b16b67e 100644 --- a/R/input-switch.R +++ b/R/input-switch.R @@ -99,7 +99,6 @@ input_checkbox <- function(id, label, class = "bslib-input-checkbox", value = FA class = "form-check-label", `for` = id ) - ), - component_dependency_js("bslibShiny") + ) ) } diff --git a/R/layout.R b/R/layout.R index db3de1f39..0e7dd4a92 100644 --- a/R/layout.R +++ b/R/layout.R @@ -95,8 +95,7 @@ layout_column_wrap <- function( gap = validateCssUnit(gap) ), !!!attribs, - children, - component_dependency_css("grid") + children ) tag <- bindFillRole(tag, item = fill) @@ -221,8 +220,7 @@ layout_columns <- function( ), !!!row_heights_css_vars(row_heights), !!!attribs, - !!!children, - component_dependency_css("grid") + !!!children ) tag <- bindFillRole(tag, item = fill) diff --git a/R/nav-items.R b/R/nav-items.R index 4bc1d359b..b98d076ea 100644 --- a/R/nav-items.R +++ b/R/nav-items.R @@ -65,7 +65,7 @@ is_nav_item <- function(x) { #' @describeIn nav-items Adding spacing between nav items. #' @export nav_spacer <- function() { - div(class = "bslib-nav-spacer", component_dependency_css("nav_spacer")) + div(class = "bslib-nav-spacer") } is_nav_spacer <- function(x) { diff --git a/R/navs-legacy.R b/R/navs-legacy.R index 4c36cd6dd..d59fdf244 100644 --- a/R/navs-legacy.R +++ b/R/navs-legacy.R @@ -308,8 +308,7 @@ navbarPage_ <- function(title, # *Don't* wrap in bootstrapPage() (shiny::navbarPage()) does that part tagList( tags$nav(class = navbarClass, role = "navigation", containerDiv), - contentDiv, - component_dependency_css("page_navbar") + contentDiv ) } diff --git a/R/page.R b/R/page.R index 68f60b156..40dfa0ff7 100644 --- a/R/page.R +++ b/R/page.R @@ -71,8 +71,7 @@ page_fillable <- function(..., padding = NULL, gap = NULL, fillable_mobile = FAL "--bslib-page-fill-mobile-height" = if (fillable_mobile) "100%" else "auto" ), ..., - as_fillable_container(), - component_dependency_css("page_fillable") + as_fillable_container() ) } @@ -147,15 +146,10 @@ page_sidebar <- function(..., sidebar = NULL, title = NULL, fillable = TRUE, fil border = FALSE, border_radius = FALSE, ... - ), - bs_dependency_defer(page_sidebar_dependency_sass) + ) ) } -page_sidebar_dependency_sass <- function(theme) { - component_dependency_sass(theme, "page_sidebar") -} - #' @rdname page #' @inheritParams navset_bar diff --git a/R/sidebar.R b/R/sidebar.R index d8b264139..4b18fd8a7 100644 --- a/R/sidebar.R +++ b/R/sidebar.R @@ -250,7 +250,6 @@ layout_sidebar <- function( "--bslib-sidebar-max-height-mobile" = max_height_mobile ), !!!contents, - sidebar_dependency(), sidebar_init_js() ) @@ -312,15 +311,3 @@ sidebar_init_js <- function() { HTML("bslib.Sidebar.initCollapsibleAll()") ) } - - -sidebar_dependency <- function() { - list( - component_dependency_js("sidebar"), - bs_dependency_defer(sidebar_dependency_sass) - ) -} - -sidebar_dependency_sass <- function(theme) { - component_dependency_sass(theme, "sidebar") -} diff --git a/R/utils-deps.R b/R/utils-deps.R index d3955e0de..6bf3d6f64 100644 --- a/R/utils-deps.R +++ b/R/utils-deps.R @@ -1,62 +1,71 @@ -web_component <- function(tagName, ...) { - js_dep <- component_dependency_js("webComponents", type = "module") - args <- c(list(js_dep), rlang::list2(...)) - tag(tagName, args) +component_dependencies <- function() { + list( + component_dependency_js(), + bs_dependency_defer(component_dependency_sass) + ) } -component_dependency_js <- function(name, ...) { +component_dependency_js <- function() { minified <- get_shiny_devmode_option("shiny.minified", default = TRUE) htmlDependency( - name = paste0("bslib-", name, "-js"), + name = "bslib-component-js", version = get_package_version("bslib"), package = "bslib", - src = file.path("components", "dist", name), + src = "components/dist", script = list( - src = paste0(name, if (minified) ".min", ".js"), - ... - ), - all_files = TRUE + list(src = paste0("components", if (minified) ".min", ".js")), + list( + src = paste0("web-components", if (minified) ".min", ".js"), + type = "module" + ) + ) ) } # Pre-compiled component styles -component_dependency_css <- function(name) { +component_dependency_css <- function() { htmlDependency( - name = paste0("bslib-", name, "-styles"), + name = "bslib-component-css", version = get_package_version("bslib"), package = "bslib", - src = file.path("components", "dist", name), - stylesheet = paste0(name, ".css") + src = "components/dist", + stylesheet = "components.css" ) } # Run-time (Sass) component styles -component_dependency_sass <- function(theme, name) { +component_dependency_sass <- function(theme) { precompiled <- isTRUE(get_precompiled_option()) default_theme <- !is_bs_theme(theme) || identical(theme, bs_theme()) if (precompiled && default_theme) { - component_dependency_css(name) + component_dependency_css() } else { - component_dependency_sass_(theme, name) + component_dependency_sass_(theme) } } -component_dependency_sass_ <- function(theme, name) { - scss_files <- list( - path_components("scss", "mixins", "_mixins.scss"), - path_components("scss", paste0(name, ".scss")) +component_dependency_sass_ <- function(theme) { + scss_dir <- path_inst("components", "scss") + scss_files <- c( + file.path(scss_dir, "mixins", "_mixins.scss"), + dir(scss_dir, pattern = "\\.scss$", full.names = TRUE) ) bs_dependency( input = lapply(scss_files, sass_file), - # At least currently, when statically rendering a component, - # bs_dependency_defer() passes along a NULL theme. We should + # At least currently, when statically rendering a component, + # bs_dependency_defer() passes along a NULL theme. We should # eventually fix that, but for now, fall back to the default theme theme = theme %||% bs_theme(), - name = paste0("bslib-", name, "-styles"), + name = "bslib-component-css", version = get_package_version("bslib"), cache_key_extra = get_package_version("bslib"), .sass_args = list(options = sass_options(output_style = "compressed")) ) } + + +web_component <- function(tagName, ...) { + htmltools::tag(tagName, rlang::list2(...)) +} diff --git a/R/utils.R b/R/utils.R index 3c480e9c8..9b415c839 100644 --- a/R/utils.R +++ b/R/utils.R @@ -36,7 +36,6 @@ path_inst <- function(...) { } path_lib <- function(...) path_inst("lib", ...) -path_components <- function(...) path_inst("components", ...) is_shiny_app <- function() { # Make sure to not load shiny as a side-effect of calling this function. diff --git a/R/value-box.R b/R/value-box.R index a31aa1097..86be43680 100644 --- a/R/value-box.R +++ b/R/value-box.R @@ -157,8 +157,7 @@ value_box <- function( "--bslib-color-bg" = theme$bg ), !!!attribs, - contents, - as.card_item(value_box_dependency()) + contents ) as_fragment(tag_require(res, version = 5, caller = "value_box()")) @@ -196,45 +195,6 @@ value_box_auto_border_class <- function(theme, class = NULL) { return(NULL) } -value_box_dependency <- function() { - bs_dependency_defer(value_box_dependency_sass) -} - -value_box_dependency_sass <- function(theme) { - deps <- component_dependency_sass(theme, "value_box") - # Inject the icon gradient SVG into the dependency $head slot - deps$head <- value_box_dependency_icon_gradient() - deps -} - -value_box_dependency_icon_gradient <- local({ - cached <- NULL - - function() { - if (!is.null(cached)) return(cached) - - x <- tags$script(HTML( - sprintf( - "(function() { - function insert_svg() { - var temp = document.createElement('div'); - temp.innerHTML = `%s`; - document.body.appendChild(temp.firstChild); - } - if (document.readyState === 'complete') { - insert_svg(); - } else { - document.addEventListener('DOMContentLoaded', insert_svg); - } - })()", - read_utf8(path_inst("components", "assets", "icon-gradient.svg")) - ) - )) - - (cached <<- format(x)) - } -}) - #' @param name The name of the theme, e.g. `"primary"`, `"danger"`, `"purple"`. #' @param bg,fg The background and foreground colors for the theme. If only `bg` #' is provided, then the foreground color is automatically chosen from diff --git a/inst/components/assets/icon-gradient.svg b/inst/components/assets/icon-gradient.svg deleted file mode 100644 index c4596e683..000000000 --- a/inst/components/assets/icon-gradient.svg +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/inst/components/dist/accordion/accordion.css b/inst/components/dist/accordion/accordion.css deleted file mode 100644 index 45cd2f8c3..000000000 --- a/inst/components/dist/accordion/accordion.css +++ /dev/null @@ -1 +0,0 @@ -.accordion .accordion-header{font-size:calc(1.325rem + .9vw);margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2;color:var(--bs-heading-color);margin-bottom:0}@media (min-width: 1200px){.accordion .accordion-header{font-size:2rem}}.accordion .accordion-icon:not(:empty){margin-right:0.75rem;display:flex}.accordion .accordion-button:not(.collapsed){box-shadow:none}.accordion .accordion-button:not(.collapsed):focus{box-shadow:var(--bs-accordion-btn-focus-box-shadow)} diff --git a/inst/components/dist/accordion/accordion.js b/inst/components/dist/accordion/accordion.js deleted file mode 100644 index e761a9ab2..000000000 --- a/inst/components/dist/accordion/accordion.js +++ /dev/null @@ -1,176 +0,0 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ -"use strict"; -(() => { - // srcts/src/components/_utils.ts - var InputBinding = window.Shiny ? Shiny.InputBinding : class { - }; - function registerBinding(inputBindingClass, name) { - if (window.Shiny) { - Shiny.inputBindings.register(new inputBindingClass(), "bslib." + name); - } - } - function hasDefinedProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== void 0; - } - - // srcts/src/components/accordion.ts - var AccordionInputBinding = class extends InputBinding { - find(scope) { - return $(scope).find(".accordion.bslib-accordion-input"); - } - getValue(el) { - const items = this._getItemInfo(el); - const selected = items.filter((x) => x.isOpen()).map((x) => x.value); - return selected.length === 0 ? null : selected; - } - subscribe(el, callback) { - $(el).on( - "shown.bs.collapse.accordionInputBinding hidden.bs.collapse.accordionInputBinding", - // eslint-disable-next-line @typescript-eslint/no-unused-vars - function(event) { - callback(true); - } - ); - } - unsubscribe(el) { - $(el).off(".accordionInputBinding"); - } - receiveMessage(el, data) { - const method = data.method; - if (method === "set") { - this._setItems(el, data); - } else if (method === "open") { - this._openItems(el, data); - } else if (method === "close") { - this._closeItems(el, data); - } else if (method === "remove") { - this._removeItem(el, data); - } else if (method === "insert") { - this._insertItem(el, data); - } else if (method === "update") { - this._updateItem(el, data); - } else { - throw new Error(`Method not yet implemented: ${method}`); - } - } - _setItems(el, data) { - const items = this._getItemInfo(el); - const vals = this._getValues(el, items, data.values); - items.forEach((x) => { - vals.indexOf(x.value) > -1 ? x.show() : x.hide(); - }); - } - _openItems(el, data) { - const items = this._getItemInfo(el); - const vals = this._getValues(el, items, data.values); - items.forEach((x) => { - if (vals.indexOf(x.value) > -1) - x.show(); - }); - } - _closeItems(el, data) { - const items = this._getItemInfo(el); - const vals = this._getValues(el, items, data.values); - items.forEach((x) => { - if (vals.indexOf(x.value) > -1) - x.hide(); - }); - } - _insertItem(el, data) { - let targetItem = this._findItem(el, data.target); - if (!targetItem) { - targetItem = data.position === "before" ? el.firstElementChild : el.lastElementChild; - } - const panel = data.panel; - if (targetItem) { - Shiny.renderContent( - targetItem, - panel, - data.position === "before" ? "beforeBegin" : "afterEnd" - ); - } else { - Shiny.renderContent(el, panel); - } - if (this._isAutoClosing(el)) { - const val = $(panel.html).attr("data-value"); - $(el).find(`[data-value="${val}"] .accordion-collapse`).attr("data-bs-parent", "#" + el.id); - } - } - _removeItem(el, data) { - const targetItems = this._getItemInfo(el).filter( - (x) => data.target.indexOf(x.value) > -1 - ); - const unbindAll = Shiny == null ? void 0 : Shiny.unbindAll; - targetItems.forEach((x) => { - if (unbindAll) - unbindAll(x.item); - x.item.remove(); - }); - } - _updateItem(el, data) { - const target = this._findItem(el, data.target); - if (!target) { - throw new Error( - `Unable to find an accordion_panel() with a value of ${data.target}` - ); - } - if (hasDefinedProperty(data, "value")) { - target.dataset.value = data.value; - } - if (hasDefinedProperty(data, "body")) { - const body = target.querySelector(".accordion-body"); - Shiny.renderContent(body, data.body); - } - const header = target.querySelector(".accordion-header"); - if (hasDefinedProperty(data, "title")) { - const title = header.querySelector(".accordion-title"); - Shiny.renderContent(title, data.title); - } - if (hasDefinedProperty(data, "icon")) { - const icon = header.querySelector( - ".accordion-button > .accordion-icon" - ); - Shiny.renderContent(icon, data.icon); - } - } - _getItemInfo(el) { - const items = Array.from( - el.querySelectorAll(":scope > .accordion-item") - ); - return items.map((x) => this._getSingleItemInfo(x)); - } - _getSingleItemInfo(x) { - const collapse = x.querySelector(".accordion-collapse"); - const isOpen = () => $(collapse).hasClass("show"); - return { - item: x, - value: x.dataset.value, - isOpen, - show: () => { - if (!isOpen()) - $(collapse).collapse("show"); - }, - hide: () => { - if (isOpen()) - $(collapse).collapse("hide"); - } - }; - } - _getValues(el, items, values) { - let vals = values !== true ? values : items.map((x) => x.value); - const autoclose = this._isAutoClosing(el); - if (autoclose) { - vals = vals.slice(vals.length - 1, vals.length); - } - return vals; - } - _findItem(el, value) { - return el.querySelector(`[data-value="${value}"]`); - } - _isAutoClosing(el) { - return el.classList.contains("autoclose"); - } - }; - registerBinding(AccordionInputBinding, "accordion"); -})(); -//# sourceMappingURL=accordion.js.map diff --git a/inst/components/dist/accordion/accordion.js.map b/inst/components/dist/accordion/accordion.js.map deleted file mode 100644 index 44f533e42..000000000 --- a/inst/components/dist/accordion/accordion.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../srcts/src/components/_utils.ts", "../../../../srcts/src/components/accordion.ts"], - "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "import type { HtmlDep } from \"./_utils\";\nimport { InputBinding, registerBinding, hasDefinedProperty } from \"./_utils\";\n\ntype AccordionItem = {\n item: HTMLElement;\n value: string;\n isOpen: () => boolean;\n show: () => void;\n hide: () => void;\n};\n\ntype HTMLContent = {\n html: string;\n deps?: HtmlDep[];\n};\n\ntype SetMessage = {\n method: \"set\";\n values: string[];\n};\n\ntype OpenMessage = {\n method: \"open\";\n values: string[] | true;\n};\n\ntype CloseMessage = {\n method: \"close\";\n values: string[] | true;\n};\n\ntype InsertMessage = {\n method: \"insert\";\n panel: HTMLContent;\n target: string;\n position: \"after\" | \"before\";\n};\n\ntype RemoveMessage = {\n method: \"remove\";\n target: string[];\n};\n\ntype UpdateMessage = {\n method: \"update\";\n target: string;\n value: string;\n body: HTMLContent;\n title: HTMLContent;\n icon: HTMLContent;\n};\n\ntype MessageData =\n | CloseMessage\n | InsertMessage\n | OpenMessage\n | RemoveMessage\n | SetMessage\n | UpdateMessage;\n\nclass AccordionInputBinding extends InputBinding {\n find(scope: HTMLElement) {\n return $(scope).find(\".accordion.bslib-accordion-input\");\n }\n\n getValue(el: HTMLElement): string[] | null {\n const items = this._getItemInfo(el);\n const selected = items.filter((x) => x.isOpen()).map((x) => x.value);\n return selected.length === 0 ? null : selected;\n }\n\n subscribe(el: HTMLElement, callback: (x: boolean) => void) {\n $(el).on(\n \"shown.bs.collapse.accordionInputBinding hidden.bs.collapse.accordionInputBinding\",\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function (event) {\n callback(true);\n }\n );\n }\n\n unsubscribe(el: HTMLElement) {\n $(el).off(\".accordionInputBinding\");\n }\n\n receiveMessage(el: HTMLElement, data: MessageData) {\n const method = data.method;\n if (method === \"set\") {\n this._setItems(el, data);\n } else if (method === \"open\") {\n this._openItems(el, data);\n } else if (method === \"close\") {\n this._closeItems(el, data);\n } else if (method === \"remove\") {\n this._removeItem(el, data);\n } else if (method === \"insert\") {\n this._insertItem(el, data);\n } else if (method === \"update\") {\n this._updateItem(el, data);\n } else {\n throw new Error(`Method not yet implemented: ${method}`);\n }\n }\n\n protected _setItems(el: HTMLElement, data: SetMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n vals.indexOf(x.value) > -1 ? x.show() : x.hide();\n });\n }\n\n protected _openItems(el: HTMLElement, data: OpenMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n if (vals.indexOf(x.value) > -1) x.show();\n });\n }\n\n protected _closeItems(el: HTMLElement, data: CloseMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n if (vals.indexOf(x.value) > -1) x.hide();\n });\n }\n\n protected _insertItem(el: HTMLElement, data: InsertMessage) {\n let targetItem = this._findItem(el, data.target);\n\n // If no target was specified, or the target was not found, then default\n // to the first or last item, depending on the position\n if (!targetItem) {\n targetItem = (\n data.position === \"before\" ? el.firstElementChild : el.lastElementChild\n ) as HTMLElement;\n }\n\n const panel = data.panel;\n\n // If there is still no targetItem, then there are no items in the accordion\n if (targetItem) {\n Shiny.renderContent(\n targetItem,\n panel,\n data.position === \"before\" ? \"beforeBegin\" : \"afterEnd\"\n );\n } else {\n Shiny.renderContent(el, panel);\n }\n\n // Need to add a reference to the parent id that makes autoclose to work\n if (this._isAutoClosing(el)) {\n const val = $(panel.html).attr(\"data-value\");\n $(el)\n .find(`[data-value=\"${val}\"] .accordion-collapse`)\n .attr(\"data-bs-parent\", \"#\" + el.id);\n }\n }\n\n protected _removeItem(el: HTMLElement, data: RemoveMessage) {\n const targetItems = this._getItemInfo(el).filter(\n (x) => data.target.indexOf(x.value) > -1\n );\n\n const unbindAll = Shiny?.unbindAll;\n\n targetItems.forEach((x) => {\n if (unbindAll) unbindAll(x.item);\n x.item.remove();\n });\n }\n\n protected _updateItem(el: HTMLElement, data: UpdateMessage) {\n const target = this._findItem(el, data.target);\n\n if (!target) {\n throw new Error(\n `Unable to find an accordion_panel() with a value of ${data.target}`\n );\n }\n\n if (hasDefinedProperty(data, \"value\")) {\n target.dataset.value = data.value;\n }\n\n if (hasDefinedProperty(data, \"body\")) {\n const body = target.querySelector(\".accordion-body\") as HTMLElement; // always exists\n Shiny.renderContent(body, data.body);\n }\n\n const header = target.querySelector(\".accordion-header\") as HTMLElement; // always exists\n\n if (hasDefinedProperty(data, \"title\")) {\n const title = header.querySelector(\".accordion-title\") as HTMLElement; // always exists\n Shiny.renderContent(title, data.title);\n }\n\n if (hasDefinedProperty(data, \"icon\")) {\n const icon = header.querySelector(\n \".accordion-button > .accordion-icon\"\n ) as HTMLElement; // always exists\n Shiny.renderContent(icon, data.icon);\n }\n }\n\n protected _getItemInfo(el: HTMLElement): AccordionItem[] {\n const items = Array.from(\n el.querySelectorAll(\":scope > .accordion-item\")\n ) as HTMLElement[];\n return items.map((x) => this._getSingleItemInfo(x));\n }\n\n protected _getSingleItemInfo(x: HTMLElement): AccordionItem {\n const collapse = x.querySelector(\".accordion-collapse\") as HTMLElement;\n const isOpen = () => $(collapse).hasClass(\"show\");\n return {\n item: x,\n value: x.dataset.value as string,\n isOpen: isOpen,\n show: () => {\n if (!isOpen()) $(collapse).collapse(\"show\");\n },\n hide: () => {\n if (isOpen()) $(collapse).collapse(\"hide\");\n },\n };\n }\n\n protected _getValues(\n el: HTMLElement,\n items: AccordionItem[],\n values: string[] | true\n ): string[] {\n let vals = values !== true ? values : items.map((x) => x.value);\n const autoclose = this._isAutoClosing(el);\n if (autoclose) {\n vals = vals.slice(vals.length - 1, vals.length);\n }\n return vals;\n }\n\n protected _findItem(el: HTMLElement, value: string): HTMLElement | null {\n return el.querySelector(`[data-value=\"${value}\"]`);\n }\n\n protected _isAutoClosing(el: HTMLElement): boolean {\n return el.classList.contains(\"autoclose\");\n }\n}\n\nregisterBinding(AccordionInputBinding, \"accordion\");\n"], - "mappings": "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", - "names": [] -} diff --git a/inst/components/dist/accordion/accordion.min.js b/inst/components/dist/accordion/accordion.min.js deleted file mode 100644 index aa0f17ca2..000000000 --- a/inst/components/dist/accordion/accordion.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ -"use strict";(()=>{var a=window.Shiny?Shiny.InputBinding:class{};function c(i,e){window.Shiny&&Shiny.inputBindings.register(new i,"bslib."+e)}function r(i,e){return Object.prototype.hasOwnProperty.call(i,e)&&i[e]!==void 0}var l=class extends a{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){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")this._insertItem(e,t);else if(n==="update")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(o=>{s.indexOf(o.value)>-1?o.show():o.hide()})}_openItems(e,t){let n=this._getItemInfo(e),s=this._getValues(e,n,t.values);n.forEach(o=>{s.indexOf(o.value)>-1&&o.show()})}_closeItems(e,t){let n=this._getItemInfo(e),s=this._getValues(e,n,t.values);n.forEach(o=>{s.indexOf(o.value)>-1&&o.hide()})}_insertItem(e,t){let n=this._findItem(e,t.target);n||(n=t.position==="before"?e.firstElementChild:e.lastElementChild);let s=t.panel;if(n?Shiny.renderContent(n,s,t.position==="before"?"beforeBegin":"afterEnd"):Shiny.renderContent(e,s),this._isAutoClosing(e)){let o=$(s.html).attr("data-value");$(e).find(`[data-value="${o}"] .accordion-collapse`).attr("data-bs-parent","#"+e.id)}}_removeItem(e,t){let n=this._getItemInfo(e).filter(o=>t.target.indexOf(o.value)>-1),s=Shiny==null?void 0:Shiny.unbindAll;n.forEach(o=>{s&&s(o.item),o.item.remove()})}_updateItem(e,t){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(r(t,"value")&&(n.dataset.value=t.value),r(t,"body")){let o=n.querySelector(".accordion-body");Shiny.renderContent(o,t.body)}let s=n.querySelector(".accordion-header");if(r(t,"title")){let o=s.querySelector(".accordion-title");Shiny.renderContent(o,t.title)}if(r(t,"icon")){let o=s.querySelector(".accordion-button > .accordion-icon");Shiny.renderContent(o,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(d=>d.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")}};c(l,"accordion");})(); -//# sourceMappingURL=accordion.min.js.map diff --git a/inst/components/dist/accordion/accordion.min.js.map b/inst/components/dist/accordion/accordion.min.js.map deleted file mode 100644 index a6a79225c..000000000 --- a/inst/components/dist/accordion/accordion.min.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../srcts/src/components/_utils.ts", "../../../../srcts/src/components/accordion.ts"], - "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "import type { HtmlDep } from \"./_utils\";\nimport { InputBinding, registerBinding, hasDefinedProperty } from \"./_utils\";\n\ntype AccordionItem = {\n item: HTMLElement;\n value: string;\n isOpen: () => boolean;\n show: () => void;\n hide: () => void;\n};\n\ntype HTMLContent = {\n html: string;\n deps?: HtmlDep[];\n};\n\ntype SetMessage = {\n method: \"set\";\n values: string[];\n};\n\ntype OpenMessage = {\n method: \"open\";\n values: string[] | true;\n};\n\ntype CloseMessage = {\n method: \"close\";\n values: string[] | true;\n};\n\ntype InsertMessage = {\n method: \"insert\";\n panel: HTMLContent;\n target: string;\n position: \"after\" | \"before\";\n};\n\ntype RemoveMessage = {\n method: \"remove\";\n target: string[];\n};\n\ntype UpdateMessage = {\n method: \"update\";\n target: string;\n value: string;\n body: HTMLContent;\n title: HTMLContent;\n icon: HTMLContent;\n};\n\ntype MessageData =\n | CloseMessage\n | InsertMessage\n | OpenMessage\n | RemoveMessage\n | SetMessage\n | UpdateMessage;\n\nclass AccordionInputBinding extends InputBinding {\n find(scope: HTMLElement) {\n return $(scope).find(\".accordion.bslib-accordion-input\");\n }\n\n getValue(el: HTMLElement): string[] | null {\n const items = this._getItemInfo(el);\n const selected = items.filter((x) => x.isOpen()).map((x) => x.value);\n return selected.length === 0 ? null : selected;\n }\n\n subscribe(el: HTMLElement, callback: (x: boolean) => void) {\n $(el).on(\n \"shown.bs.collapse.accordionInputBinding hidden.bs.collapse.accordionInputBinding\",\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function (event) {\n callback(true);\n }\n );\n }\n\n unsubscribe(el: HTMLElement) {\n $(el).off(\".accordionInputBinding\");\n }\n\n receiveMessage(el: HTMLElement, data: MessageData) {\n const method = data.method;\n if (method === \"set\") {\n this._setItems(el, data);\n } else if (method === \"open\") {\n this._openItems(el, data);\n } else if (method === \"close\") {\n this._closeItems(el, data);\n } else if (method === \"remove\") {\n this._removeItem(el, data);\n } else if (method === \"insert\") {\n this._insertItem(el, data);\n } else if (method === \"update\") {\n this._updateItem(el, data);\n } else {\n throw new Error(`Method not yet implemented: ${method}`);\n }\n }\n\n protected _setItems(el: HTMLElement, data: SetMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n vals.indexOf(x.value) > -1 ? x.show() : x.hide();\n });\n }\n\n protected _openItems(el: HTMLElement, data: OpenMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n if (vals.indexOf(x.value) > -1) x.show();\n });\n }\n\n protected _closeItems(el: HTMLElement, data: CloseMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n if (vals.indexOf(x.value) > -1) x.hide();\n });\n }\n\n protected _insertItem(el: HTMLElement, data: InsertMessage) {\n let targetItem = this._findItem(el, data.target);\n\n // If no target was specified, or the target was not found, then default\n // to the first or last item, depending on the position\n if (!targetItem) {\n targetItem = (\n data.position === \"before\" ? el.firstElementChild : el.lastElementChild\n ) as HTMLElement;\n }\n\n const panel = data.panel;\n\n // If there is still no targetItem, then there are no items in the accordion\n if (targetItem) {\n Shiny.renderContent(\n targetItem,\n panel,\n data.position === \"before\" ? \"beforeBegin\" : \"afterEnd\"\n );\n } else {\n Shiny.renderContent(el, panel);\n }\n\n // Need to add a reference to the parent id that makes autoclose to work\n if (this._isAutoClosing(el)) {\n const val = $(panel.html).attr(\"data-value\");\n $(el)\n .find(`[data-value=\"${val}\"] .accordion-collapse`)\n .attr(\"data-bs-parent\", \"#\" + el.id);\n }\n }\n\n protected _removeItem(el: HTMLElement, data: RemoveMessage) {\n const targetItems = this._getItemInfo(el).filter(\n (x) => data.target.indexOf(x.value) > -1\n );\n\n const unbindAll = Shiny?.unbindAll;\n\n targetItems.forEach((x) => {\n if (unbindAll) unbindAll(x.item);\n x.item.remove();\n });\n }\n\n protected _updateItem(el: HTMLElement, data: UpdateMessage) {\n const target = this._findItem(el, data.target);\n\n if (!target) {\n throw new Error(\n `Unable to find an accordion_panel() with a value of ${data.target}`\n );\n }\n\n if (hasDefinedProperty(data, \"value\")) {\n target.dataset.value = data.value;\n }\n\n if (hasDefinedProperty(data, \"body\")) {\n const body = target.querySelector(\".accordion-body\") as HTMLElement; // always exists\n Shiny.renderContent(body, data.body);\n }\n\n const header = target.querySelector(\".accordion-header\") as HTMLElement; // always exists\n\n if (hasDefinedProperty(data, \"title\")) {\n const title = header.querySelector(\".accordion-title\") as HTMLElement; // always exists\n Shiny.renderContent(title, data.title);\n }\n\n if (hasDefinedProperty(data, \"icon\")) {\n const icon = header.querySelector(\n \".accordion-button > .accordion-icon\"\n ) as HTMLElement; // always exists\n Shiny.renderContent(icon, data.icon);\n }\n }\n\n protected _getItemInfo(el: HTMLElement): AccordionItem[] {\n const items = Array.from(\n el.querySelectorAll(\":scope > .accordion-item\")\n ) as HTMLElement[];\n return items.map((x) => this._getSingleItemInfo(x));\n }\n\n protected _getSingleItemInfo(x: HTMLElement): AccordionItem {\n const collapse = x.querySelector(\".accordion-collapse\") as HTMLElement;\n const isOpen = () => $(collapse).hasClass(\"show\");\n return {\n item: x,\n value: x.dataset.value as string,\n isOpen: isOpen,\n show: () => {\n if (!isOpen()) $(collapse).collapse(\"show\");\n },\n hide: () => {\n if (isOpen()) $(collapse).collapse(\"hide\");\n },\n };\n }\n\n protected _getValues(\n el: HTMLElement,\n items: AccordionItem[],\n values: string[] | true\n ): string[] {\n let vals = values !== true ? values : items.map((x) => x.value);\n const autoclose = this._isAutoClosing(el);\n if (autoclose) {\n vals = vals.slice(vals.length - 1, vals.length);\n }\n return vals;\n }\n\n protected _findItem(el: HTMLElement, value: string): HTMLElement | null {\n return el.querySelector(`[data-value=\"${value}\"]`);\n }\n\n protected _isAutoClosing(el: HTMLElement): boolean {\n return el.classList.contains(\"autoclose\");\n }\n}\n\nregisterBinding(AccordionInputBinding, \"accordion\");\n"], - "mappings": "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", - "names": ["InputBinding", "registerBinding", "inputBindingClass", "name", "hasDefinedProperty", "obj", "prop", "AccordionInputBinding", "InputBinding", "scope", "el", "selected", "x", "callback", "event", "data", "method", "items", "vals", "targetItem", "panel", "val", "targetItems", "unbindAll", "target", "hasDefinedProperty", "body", "header", "title", "icon", "collapse", "isOpen", "values", "value", "registerBinding"] -} diff --git a/inst/components/dist/bslibShiny/bslibShiny.js b/inst/components/dist/bslibShiny/bslibShiny.js deleted file mode 100644 index 21af54d8b..000000000 --- a/inst/components/dist/bslibShiny/bslibShiny.js +++ /dev/null @@ -1,42 +0,0 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ -"use strict"; -(() => { - // srcts/src/components/_utils.ts - var InputBinding = window.Shiny ? Shiny.InputBinding : class { - }; - - // srcts/src/components/webcomponents/_shinyAddCustomMessageHandlers.ts - function shinyAddCustomMessageHandlers(handlers) { - if (!window.Shiny) { - return; - } - for (const [name, handler] of Object.entries(handlers)) { - Shiny.addCustomMessageHandler(name, handler); - } - } - - // srcts/src/components/bslibShiny.ts - var bslibMessageHandlers = { - // eslint-disable-next-line @typescript-eslint/naming-convention - "bslib.toggle-input-binary": (msg) => { - const el = document.getElementById(msg.id); - if (!el) { - console.warn("[bslib.toggle-input-binary] No element found", msg); - } - const binding = $(el).data("shiny-input-binding"); - if (!(binding instanceof InputBinding)) { - console.warn("[bslib.toggle-input-binary] No input binding found", msg); - return; - } - let value = msg.value; - if (typeof value === "undefined") { - value = !binding.getValue(el); - } - binding.receiveMessage(el, { value }); - } - }; - if (window.Shiny) { - shinyAddCustomMessageHandlers(bslibMessageHandlers); - } -})(); -//# sourceMappingURL=bslibShiny.js.map diff --git a/inst/components/dist/bslibShiny/bslibShiny.js.map b/inst/components/dist/bslibShiny/bslibShiny.js.map deleted file mode 100644 index f130d71d7..000000000 --- a/inst/components/dist/bslibShiny/bslibShiny.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../srcts/src/components/_utils.ts", "../../../../srcts/src/components/webcomponents/_shinyAddCustomMessageHandlers.ts", "../../../../srcts/src/components/bslibShiny.ts"], - "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "import type { Handler as ShinyCustomMessageHandler } from \"rstudio-shiny/srcts/types/src/shiny/shinyapp\";\n\nexport function shinyAddCustomMessageHandlers(handlers: {\n [key: string]: ShinyCustomMessageHandler;\n}): void {\n if (!window.Shiny) {\n return;\n }\n\n for (const [name, handler] of Object.entries(handlers)) {\n Shiny.addCustomMessageHandler(name, handler);\n }\n}\n", "import { InputBinding } from \"./_utils\";\nimport { shinyAddCustomMessageHandlers } from \"./webcomponents/_shinyAddCustomMessageHandlers\";\n\nconst bslibMessageHandlers = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"bslib.toggle-input-binary\": (msg: any) => {\n // This handler was written for `toggle_switch()`, but could be used for any\n // binary Shiny input, e.g. checkbox.\n const el = document.getElementById(msg.id) as HTMLElement;\n if (!el) {\n console.warn(\"[bslib.toggle-input-binary] No element found\", msg);\n }\n\n const binding = $(el).data(\"shiny-input-binding\");\n if (!(binding instanceof InputBinding)) {\n console.warn(\"[bslib.toggle-input-binary] No input binding found\", msg);\n return;\n }\n\n let value = msg.value;\n if (typeof value === \"undefined\") {\n value = !binding.getValue(el);\n }\n binding.receiveMessage(el, { value });\n },\n};\n\nif (window.Shiny) {\n shinyAddCustomMessageHandlers(bslibMessageHandlers);\n}\n"], - "mappings": ";;;;AAQA,MAAM,eACJ,OAAO,QAAQ,MAAM,eAAe,MAAM;AAAA,EAAC;;;ACPtC,WAAS,8BAA8B,UAErC;AACP,QAAI,CAAC,OAAO,OAAO;AACjB;AAAA,IACF;AAEA,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACtD,YAAM,wBAAwB,MAAM,OAAO;AAAA,IAC7C;AAAA,EACF;;;ACTA,MAAM,uBAAuB;AAAA;AAAA,IAE3B,6BAA6B,CAAC,QAAa;AAGzC,YAAM,KAAK,SAAS,eAAe,IAAI,EAAE;AACzC,UAAI,CAAC,IAAI;AACP,gBAAQ,KAAK,gDAAgD,GAAG;AAAA,MAClE;AAEA,YAAM,UAAU,EAAE,EAAE,EAAE,KAAK,qBAAqB;AAChD,UAAI,EAAE,mBAAmB,eAAe;AACtC,gBAAQ,KAAK,sDAAsD,GAAG;AACtE;AAAA,MACF;AAEA,UAAI,QAAQ,IAAI;AAChB,UAAI,OAAO,UAAU,aAAa;AAChC,gBAAQ,CAAC,QAAQ,SAAS,EAAE;AAAA,MAC9B;AACA,cAAQ,eAAe,IAAI,EAAE,MAAM,CAAC;AAAA,IACtC;AAAA,EACF;AAEA,MAAI,OAAO,OAAO;AAChB,kCAA8B,oBAAoB;AAAA,EACpD;", - "names": [] -} diff --git a/inst/components/dist/bslibShiny/bslibShiny.min.js b/inst/components/dist/bslibShiny/bslibShiny.min.js deleted file mode 100644 index 349040cff..000000000 --- a/inst/components/dist/bslibShiny/bslibShiny.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ -"use strict";(()=>{var s=window.Shiny?Shiny.InputBinding:class{};function o(e){if(window.Shiny)for(let[n,t]of Object.entries(e))Shiny.addCustomMessageHandler(n,t)}var r={"bslib.toggle-input-binary":e=>{let n=document.getElementById(e.id);n||console.warn("[bslib.toggle-input-binary] No element found",e);let t=$(n).data("shiny-input-binding");if(!(t instanceof s)){console.warn("[bslib.toggle-input-binary] No input binding found",e);return}let i=e.value;typeof i=="undefined"&&(i=!t.getValue(n)),t.receiveMessage(n,{value:i})}};window.Shiny&&o(r);})(); -//# sourceMappingURL=bslibShiny.min.js.map diff --git a/inst/components/dist/bslibShiny/bslibShiny.min.js.map b/inst/components/dist/bslibShiny/bslibShiny.min.js.map deleted file mode 100644 index ed0bcfbcd..000000000 --- a/inst/components/dist/bslibShiny/bslibShiny.min.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../srcts/src/components/_utils.ts", "../../../../srcts/src/components/webcomponents/_shinyAddCustomMessageHandlers.ts", "../../../../srcts/src/components/bslibShiny.ts"], - "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "import type { Handler as ShinyCustomMessageHandler } from \"rstudio-shiny/srcts/types/src/shiny/shinyapp\";\n\nexport function shinyAddCustomMessageHandlers(handlers: {\n [key: string]: ShinyCustomMessageHandler;\n}): void {\n if (!window.Shiny) {\n return;\n }\n\n for (const [name, handler] of Object.entries(handlers)) {\n Shiny.addCustomMessageHandler(name, handler);\n }\n}\n", "import { InputBinding } from \"./_utils\";\nimport { shinyAddCustomMessageHandlers } from \"./webcomponents/_shinyAddCustomMessageHandlers\";\n\nconst bslibMessageHandlers = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"bslib.toggle-input-binary\": (msg: any) => {\n // This handler was written for `toggle_switch()`, but could be used for any\n // binary Shiny input, e.g. checkbox.\n const el = document.getElementById(msg.id) as HTMLElement;\n if (!el) {\n console.warn(\"[bslib.toggle-input-binary] No element found\", msg);\n }\n\n const binding = $(el).data(\"shiny-input-binding\");\n if (!(binding instanceof InputBinding)) {\n console.warn(\"[bslib.toggle-input-binary] No input binding found\", msg);\n return;\n }\n\n let value = msg.value;\n if (typeof value === \"undefined\") {\n value = !binding.getValue(el);\n }\n binding.receiveMessage(el, { value });\n },\n};\n\nif (window.Shiny) {\n shinyAddCustomMessageHandlers(bslibMessageHandlers);\n}\n"], - "mappings": ";mBAQA,IAAMA,EACJ,OAAO,MAAQ,MAAM,aAAe,KAAM,CAAC,ECPtC,SAASC,EAA8BC,EAErC,CACP,GAAK,OAAO,MAIZ,OAAW,CAACC,EAAMC,CAAO,IAAK,OAAO,QAAQF,CAAQ,EACnD,MAAM,wBAAwBC,EAAMC,CAAO,CAE/C,CCTA,IAAMC,EAAuB,CAE3B,4BAA8BC,GAAa,CAGzC,IAAMC,EAAK,SAAS,eAAeD,EAAI,EAAE,EACpCC,GACH,QAAQ,KAAK,+CAAgDD,CAAG,EAGlE,IAAME,EAAU,EAAED,CAAE,EAAE,KAAK,qBAAqB,EAChD,GAAI,EAAEC,aAAmBC,GAAe,CACtC,QAAQ,KAAK,qDAAsDH,CAAG,EACtE,MACF,CAEA,IAAII,EAAQJ,EAAI,MACZ,OAAOI,GAAU,cACnBA,EAAQ,CAACF,EAAQ,SAASD,CAAE,GAE9BC,EAAQ,eAAeD,EAAI,CAAE,MAAAG,CAAM,CAAC,CACtC,CACF,EAEI,OAAO,OACTC,EAA8BN,CAAoB", - "names": ["InputBinding", "shinyAddCustomMessageHandlers", "handlers", "name", "handler", "bslibMessageHandlers", "msg", "el", "binding", "InputBinding", "value", "shinyAddCustomMessageHandlers"] -} diff --git a/inst/components/dist/card/card.css b/inst/components/dist/card/card.css deleted file mode 100644 index f041b663f..000000000 --- a/inst/components/dist/card/card.css +++ /dev/null @@ -1 +0,0 @@ -.bslib-card{overflow:auto}.bslib-card .card-body+.card-body{padding-top:0}.bslib-card .card-body{overflow:auto}.bslib-card .card-body p{margin-top:0}.bslib-card .card-body p:last-child{margin-bottom:0}.bslib-card .card-body{max-height:var(--bslib-card-body-max-height, none)}.bslib-card[data-full-screen="true"]>.card-body{max-height:var(--bslib-card-body-max-height-full-screen, none)}.bslib-card .card-header .form-group{margin-bottom:0}.bslib-card .card-header .selectize-control{margin-bottom:0}.bslib-card .card-header .selectize-control .item{margin-right:1.15rem}.bslib-card .card-footer{margin-top:auto}.bslib-card .bslib-navs-card-title{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center}.bslib-card .bslib-navs-card-title .nav{margin-left:auto}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border="true"]){border:none}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border-radius="true"]){border-top-left-radius:0;border-top-right-radius:0}[data-full-screen="true"]{position:fixed;inset:3.5rem 1rem 1rem;height:auto !important;max-height:none !important;width:auto !important;z-index:1070}.bslib-full-screen-enter{display:none;position:absolute;bottom:var(--bslib-full-screen-enter-bottom, 0.2rem);right:var(--bslib-full-screen-enter-right, 0);top:var(--bslib-full-screen-enter-top);left:var(--bslib-full-screen-enter-left);color:var(--bslib-color-fg, var(--bs-card-color));background-color:var(--bslib-color-bg, var(--bs-card-bg, var(--bs-body-bg)));border:var(--bs-card-border-width) solid var(--bslib-color-fg, var(--bs-card-border-color));box-shadow:0 2px 4px rgba(0,0,0,0.15);margin:0.2rem 0.4rem;padding:0.55rem !important;font-size:.8rem;cursor:pointer;opacity:0.7;z-index:1070}.bslib-full-screen-enter:hover{opacity:1}.card[data-full-screen="false"]:hover>*>.bslib-full-screen-enter{display:block}.bslib-has-full-screen .card:hover>*>.bslib-full-screen-enter{display:none}@media (max-width: 575.98px){.bslib-full-screen-enter{display:none !important}}.bslib-full-screen-exit{position:relative;top:1.35rem;font-size:0.9rem;cursor:pointer;text-decoration:none;display:flex;float:right;margin-right:2.15rem;align-items:center;color:rgba(var(--bs-body-bg-rgb), 0.8)}.bslib-full-screen-exit:hover{color:rgba(var(--bs-body-bg-rgb), 1)}.bslib-full-screen-exit svg{margin-left:0.5rem;font-size:1.5rem}#bslib-full-screen-overlay{position:fixed;inset:0;background-color:rgba(var(--bs-body-color-rgb), 0.6);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);z-index:1069;animation:bslib-full-screen-overlay-enter 400ms cubic-bezier(0.6, 0.02, 0.65, 1) forwards}@keyframes bslib-full-screen-overlay-enter{0%{opacity:0}100%{opacity:1}} diff --git a/inst/components/dist/card/card.js b/inst/components/dist/card/card.js deleted file mode 100644 index 20ecfd7fd..000000000 --- a/inst/components/dist/card/card.js +++ /dev/null @@ -1,411 +0,0 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ -"use strict"; -(() => { - // srcts/src/components/_utils.ts - var InputBinding = window.Shiny ? Shiny.InputBinding : class { - }; - function getAllFocusableChildren(el) { - const base = [ - "a[href]", - "area[href]", - "button", - "details summary", - "input", - "iframe", - "select", - "textarea", - '[contentEditable=""]', - '[contentEditable="true"]', - '[contentEditable="TRUE"]', - "[tabindex]" - ]; - const modifiers = [':not([tabindex="-1"])', ":not([disabled])"]; - const selectors = base.map((b) => b + modifiers.join("")); - const focusable = el.querySelectorAll(selectors.join(", ")); - return Array.from(focusable); - } - - // srcts/src/components/_shinyResizeObserver.ts - var ShinyResizeObserver = class { - /** - * Watch containers for size changes and ensure that Shiny outputs and - * htmlwidgets within resize appropriately. - * - * @details - * The ShinyResizeObserver is used to watch the containers, such as Sidebars - * and Cards for size changes, in particular when the sidebar state is toggled - * or the card body is expanded full screen. It performs two primary tasks: - * - * 1. Dispatches a `resize` event on the window object. This is necessary to - * ensure that Shiny outputs resize appropriately. In general, the window - * resizing is throttled and the output update occurs when the transition - * is complete. - * 2. If an output with a resize method on the output binding is detected, we - * directly call the `.onResize()` method of the binding. This ensures that - * htmlwidgets transition smoothly. In static mode, htmlwidgets does this - * already. - * - * @note - * This resize observer also handles race conditions in some complex - * fill-based layouts with multiple outputs (e.g., plotly), where shiny - * initializes with the correct sizing, but in-between the 1st and last - * renderValue(), the size of the output containers can change, meaning every - * output but the 1st gets initialized with the wrong size during their - * renderValue(). Then, after the render phase, shiny won't know to trigger a - * resize since all the widgets will return to their original size (and thus, - * Shiny thinks there isn't any resizing to do). The resize observer works - * around this by ensuring that the output is resized whenever its container - * size changes. - * @constructor - */ - constructor() { - this.resizeObserverEntries = []; - this.resizeObserver = new ResizeObserver((entries) => { - const resizeEvent = new Event("resize"); - window.dispatchEvent(resizeEvent); - if (!window.Shiny) - return; - const resized = []; - for (const entry of entries) { - if (!(entry.target instanceof HTMLElement)) - continue; - if (!entry.target.querySelector(".shiny-bound-output")) - continue; - entry.target.querySelectorAll(".shiny-bound-output").forEach((el) => { - if (resized.includes(el)) - return; - const { binding, onResize } = $(el).data("shinyOutputBinding"); - if (!binding || !binding.resize) - return; - const owner = el.shinyResizeObserver; - if (owner && owner !== this) - return; - if (!owner) - el.shinyResizeObserver = this; - onResize(el); - resized.push(el); - if (!el.classList.contains("shiny-plot-output")) - return; - const img = el.querySelector( - 'img:not([width="100%"])' - ); - if (img) - img.setAttribute("width", "100%"); - }); - } - }); - } - /** - * Observe an element for size changes. - * @param {HTMLElement} el - The element to observe. - */ - observe(el) { - this.resizeObserver.observe(el); - this.resizeObserverEntries.push(el); - } - /** - * Stop observing an element for size changes. - * @param {HTMLElement} el - The element to stop observing. - */ - unobserve(el) { - const idxEl = this.resizeObserverEntries.indexOf(el); - if (idxEl < 0) - return; - this.resizeObserver.unobserve(el); - this.resizeObserverEntries.splice(idxEl, 1); - } - /** - * This method checks that we're not continuing to watch elements that no - * longer exist in the DOM. If any are found, we stop observing them and - * remove them from our array of observed elements. - * - * @private - * @static - */ - flush() { - this.resizeObserverEntries.forEach((el) => { - if (!document.body.contains(el)) - this.unobserve(el); - }); - } - }; - - // srcts/src/components/card.ts - var _Card = class { - /** - * Creates an instance of a bslib Card component. - * - * @constructor - * @param {HTMLElement} card - */ - constructor(card) { - var _a; - card.removeAttribute(_Card.attr.ATTR_INIT); - (_a = card.querySelector(`script[${_Card.attr.ATTR_INIT}]`)) == null ? void 0 : _a.remove(); - this.card = card; - _Card.instanceMap.set(card, this); - _Card.shinyResizeObserver.observe(this.card); - this._addEventListeners(); - this.overlay = this._createOverlay(); - this._exitFullScreenOnEscape = this._exitFullScreenOnEscape.bind(this); - this._trapFocusExit = this._trapFocusExit.bind(this); - } - /** - * Enter the card's full screen mode, either programmatically or via an event - * handler. Full screen mode is activated by adding a class to the card that - * positions it absolutely and expands it to fill the viewport. In addition, - * we add a full screen overlay element behind the card and we trap focus in - * the expanded card while in full screen mode. - * - * @param {?Event} [event] - */ - enterFullScreen(event) { - var _a; - if (event) - event.preventDefault(); - document.addEventListener("keydown", this._exitFullScreenOnEscape, false); - document.addEventListener("keydown", this._trapFocusExit, true); - this.card.setAttribute(_Card.attr.ATTR_FULL_SCREEN, "true"); - document.body.classList.add(_Card.attr.CLASS_HAS_FULL_SCREEN); - this.card.insertAdjacentElement("beforebegin", this.overlay.container); - if (!this.card.contains(document.activeElement) || ((_a = document.activeElement) == null ? void 0 : _a.classList.contains( - _Card.attr.CLASS_FULL_SCREEN_ENTER - ))) { - this.card.setAttribute("tabindex", "-1"); - this.card.focus(); - } - } - /** - * Exit full screen mode. This removes the full screen overlay element, - * removes the full screen class from the card, and removes the keyboard event - * listeners that were added when entering full screen mode. - */ - exitFullScreen() { - document.removeEventListener( - "keydown", - this._exitFullScreenOnEscape, - false - ); - document.removeEventListener("keydown", this._trapFocusExit, true); - this.overlay.container.remove(); - this.card.setAttribute(_Card.attr.ATTR_FULL_SCREEN, "false"); - this.card.removeAttribute("tabindex"); - document.body.classList.remove(_Card.attr.CLASS_HAS_FULL_SCREEN); - } - /** - * Adds general card-specific event listeners. - * @private - */ - _addEventListeners() { - const btnFullScreen = this.card.querySelector( - `:scope > * > .${_Card.attr.CLASS_FULL_SCREEN_ENTER}` - ); - if (!btnFullScreen) - return; - btnFullScreen.addEventListener("click", (ev) => this.enterFullScreen(ev)); - } - /** - * An event handler to exit full screen mode when the Escape key is pressed. - * @private - * @param {KeyboardEvent} event - */ - _exitFullScreenOnEscape(event) { - if (!(event.target instanceof HTMLElement)) - return; - const selOpenSelectInput = ["select[open]", "input[aria-expanded='true']"]; - if (event.target.matches(selOpenSelectInput.join(", "))) - return; - if (event.key === "Escape") { - this.exitFullScreen(); - } - } - /** - * An event handler to trap focus within the card when in full screen mode. - * - * @description - * This keyboard event handler ensures that tab focus stays within the card - * when in full screen mode. When the card is first expanded, - * we move focus to the card element itself. If focus somehow leaves the card, - * we returns focus to the card container. - * - * Within the card, we handle only tabbing from the close anchor or the last - * focusable element and only when tab focus would have otherwise left the - * card. In those cases, we cycle focus to the last focusable element or back - * to the anchor. If the card doesn't have any focusable elements, we move - * focus to the close anchor. - * - * @note - * Because the card contents may change, we check for focusable elements - * every time the handler is called. - * - * @private - * @param {KeyboardEvent} event - */ - _trapFocusExit(event) { - if (!(event instanceof KeyboardEvent)) - return; - if (event.key !== "Tab") - return; - const isFocusedContainer = event.target === this.card; - const isFocusedAnchor = event.target === this.overlay.anchor; - const isFocusedWithin = this.card.contains(event.target); - const stopEvent = () => { - event.preventDefault(); - event.stopImmediatePropagation(); - }; - if (!(isFocusedWithin || isFocusedContainer || isFocusedAnchor)) { - stopEvent(); - this.card.focus(); - return; - } - const focusableElements = getAllFocusableChildren(this.card).filter( - (el) => !el.classList.contains(_Card.attr.CLASS_FULL_SCREEN_ENTER) - ); - const hasFocusableElements = focusableElements.length > 0; - if (!hasFocusableElements) { - stopEvent(); - this.overlay.anchor.focus(); - return; - } - if (isFocusedContainer) - return; - const lastFocusable = focusableElements[focusableElements.length - 1]; - const isFocusedLast = event.target === lastFocusable; - if (isFocusedAnchor && event.shiftKey) { - stopEvent(); - lastFocusable.focus(); - return; - } - if (isFocusedLast && !event.shiftKey) { - stopEvent(); - this.overlay.anchor.focus(); - return; - } - } - /** - * Creates the full screen overlay. - * @private - * @returns {CardFullScreenOverlay} - */ - _createOverlay() { - const container = document.createElement("div"); - container.id = _Card.attr.ID_FULL_SCREEN_OVERLAY; - container.onclick = this.exitFullScreen.bind(this); - const anchor = this._createOverlayCloseAnchor(); - container.appendChild(anchor); - return { container, anchor }; - } - /** - * Creates the anchor element used to exit the full screen mode. - * @private - * @returns {HTMLAnchorElement} - */ - _createOverlayCloseAnchor() { - const anchor = document.createElement("a"); - anchor.classList.add(_Card.attr.CLASS_FULL_SCREEN_EXIT); - anchor.tabIndex = 0; - anchor.onclick = () => this.exitFullScreen(); - anchor.onkeydown = (ev) => { - if (ev.key === "Enter" || ev.key === " ") { - this.exitFullScreen(); - } - }; - anchor.innerHTML = this._overlayCloseHtml(); - return anchor; - } - /** - * Returns the HTML for the close icon. - * @private - * @returns {string} - */ - _overlayCloseHtml() { - return "Close "; - } - /** - * Returns the card instance associated with the given element, if any. - * @public - * @static - * @param {HTMLElement} el - * @returns {(Card | undefined)} - */ - static getInstance(el) { - return _Card.instanceMap.get(el); - } - /** - * Initializes all cards that require initialization on the page, or schedules - * initialization if the DOM is not yet ready. - * @public - * @static - * @param {boolean} [flushResizeObserver=true] - */ - static initializeAllCards(flushResizeObserver = true) { - if (document.readyState === "loading") { - if (!_Card.onReadyScheduled) { - _Card.onReadyScheduled = true; - document.addEventListener("DOMContentLoaded", () => { - _Card.initializeAllCards(false); - }); - } - return; - } - if (flushResizeObserver) { - _Card.shinyResizeObserver.flush(); - } - const initSelector = `.${_Card.attr.CLASS_CARD}[${_Card.attr.ATTR_INIT}]`; - if (!document.querySelector(initSelector)) { - return; - } - const cards = document.querySelectorAll(initSelector); - cards.forEach((card) => new _Card(card)); - } - }; - var Card = _Card; - /** - * Key bslib-specific classes and attributes used by the card component. - * @private - * @static - * @type {{ ATTR_INIT: string; CLASS_CARD: string; CLASS_FULL_SCREEN: string; CLASS_HAS_FULL_SCREEN: string; CLASS_FULL_SCREEN_ENTER: string; CLASS_FULL_SCREEN_EXIT: string; ID_FULL_SCREEN_OVERLAY: string; }} - */ - Card.attr = { - // eslint-disable-next-line @typescript-eslint/naming-convention - ATTR_INIT: "data-bslib-card-init", - // eslint-disable-next-line @typescript-eslint/naming-convention - CLASS_CARD: "bslib-card", - // eslint-disable-next-line @typescript-eslint/naming-convention - ATTR_FULL_SCREEN: "data-full-screen", - // eslint-disable-next-line @typescript-eslint/naming-convention - CLASS_HAS_FULL_SCREEN: "bslib-has-full-screen", - // eslint-disable-next-line @typescript-eslint/naming-convention - CLASS_FULL_SCREEN_ENTER: "bslib-full-screen-enter", - // eslint-disable-next-line @typescript-eslint/naming-convention - CLASS_FULL_SCREEN_EXIT: "bslib-full-screen-exit", - // eslint-disable-next-line @typescript-eslint/naming-convention - ID_FULL_SCREEN_OVERLAY: "bslib-full-screen-overlay" - }; - /** - * A Shiny-specific resize observer that ensures Shiny outputs in within the - * card resize appropriately. - * @private - * @type {ShinyResizeObserver} - * @static - */ - Card.shinyResizeObserver = new ShinyResizeObserver(); - /** - * The registry of card instances and their associated DOM elements. - * @private - * @static - * @type {WeakMap} - */ - Card.instanceMap = /* @__PURE__ */ new WeakMap(); - /** - * If cards are initialized before the DOM is ready, we re-schedule the - * initialization to occur on DOMContentLoaded. - * @private - * @static - * @type {boolean} - */ - Card.onReadyScheduled = false; - window.bslib = window.bslib || {}; - window.bslib.Card = Card; -})(); -//# sourceMappingURL=card.js.map diff --git a/inst/components/dist/card/card.js.map b/inst/components/dist/card/card.js.map deleted file mode 100644 index bf88a82df..000000000 --- a/inst/components/dist/card/card.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../srcts/src/components/_utils.ts", "../../../../srcts/src/components/_shinyResizeObserver.ts", "../../../../srcts/src/components/card.ts"], - "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "/**\n * A resize observer that ensures Shiny outputs resize during or just after\n * their parent container size changes. Useful, in particular, for sidebar\n * transitions or for full-screen card transitions.\n *\n * @class ShinyResizeObserver\n * @typedef {ShinyResizeObserver}\n */\nclass ShinyResizeObserver {\n /**\n * The actual ResizeObserver instance.\n * @private\n * @type {ResizeObserver}\n */\n private resizeObserver: ResizeObserver;\n /**\n * An array of elements that are currently being watched by the Resize\n * Observer.\n *\n * @details\n * We don't currently have lifecycle hooks that allow us to unobserve elements\n * when they are removed from the DOM. As a result, we need to manually check\n * that the elements we're watching still exist in the DOM. This array keeps\n * track of the elements we're watching so that we can check them later.\n * @private\n * @type {HTMLElement[]}\n */\n private resizeObserverEntries: HTMLElement[];\n\n /**\n * Watch containers for size changes and ensure that Shiny outputs and\n * htmlwidgets within resize appropriately.\n *\n * @details\n * The ShinyResizeObserver is used to watch the containers, such as Sidebars\n * and Cards for size changes, in particular when the sidebar state is toggled\n * or the card body is expanded full screen. It performs two primary tasks:\n *\n * 1. Dispatches a `resize` event on the window object. This is necessary to\n * ensure that Shiny outputs resize appropriately. In general, the window\n * resizing is throttled and the output update occurs when the transition\n * is complete.\n * 2. If an output with a resize method on the output binding is detected, we\n * directly call the `.onResize()` method of the binding. This ensures that\n * htmlwidgets transition smoothly. In static mode, htmlwidgets does this\n * already.\n *\n * @note\n * This resize observer also handles race conditions in some complex\n * fill-based layouts with multiple outputs (e.g., plotly), where shiny\n * initializes with the correct sizing, but in-between the 1st and last\n * renderValue(), the size of the output containers can change, meaning every\n * output but the 1st gets initialized with the wrong size during their\n * renderValue(). Then, after the render phase, shiny won't know to trigger a\n * resize since all the widgets will return to their original size (and thus,\n * Shiny thinks there isn't any resizing to do). The resize observer works\n * around this by ensuring that the output is resized whenever its container\n * size changes.\n * @constructor\n */\n constructor() {\n this.resizeObserverEntries = [];\n this.resizeObserver = new ResizeObserver((entries) => {\n const resizeEvent = new Event(\"resize\");\n window.dispatchEvent(resizeEvent);\n\n // the rest of this callback is only relevant in Shiny apps\n if (!window.Shiny) return;\n\n const resized = [] as HTMLElement[];\n\n for (const entry of entries) {\n if (!(entry.target instanceof HTMLElement)) continue;\n if (!entry.target.querySelector(\".shiny-bound-output\")) continue;\n\n entry.target\n .querySelectorAll(\".shiny-bound-output\")\n .forEach((el) => {\n if (resized.includes(el)) return;\n\n const { binding, onResize } = $(el).data(\"shinyOutputBinding\");\n if (!binding || !binding.resize) return;\n\n // if this output is owned by another observer, skip it\n const owner = (el as any).shinyResizeObserver;\n if (owner && owner !== this) return;\n // mark this output as owned by this shinyResizeObserver instance\n if (!owner) (el as any).shinyResizeObserver = this;\n\n // trigger immediate resizing of outputs with a resize method\n onResize(el);\n // only once per output and resize event\n resized.push(el);\n\n // set plot images to 100% width temporarily during the transition\n if (!el.classList.contains(\"shiny-plot-output\")) return;\n const img = el.querySelector(\n 'img:not([width=\"100%\"])'\n );\n if (img) img.setAttribute(\"width\", \"100%\");\n });\n }\n });\n }\n\n /**\n * Observe an element for size changes.\n * @param {HTMLElement} el - The element to observe.\n */\n observe(el: HTMLElement): void {\n this.resizeObserver.observe(el);\n this.resizeObserverEntries.push(el);\n }\n\n /**\n * Stop observing an element for size changes.\n * @param {HTMLElement} el - The element to stop observing.\n */\n unobserve(el: HTMLElement): void {\n const idxEl = this.resizeObserverEntries.indexOf(el);\n if (idxEl < 0) return;\n\n this.resizeObserver.unobserve(el);\n this.resizeObserverEntries.splice(idxEl, 1);\n }\n\n /**\n * This method checks that we're not continuing to watch elements that no\n * longer exist in the DOM. If any are found, we stop observing them and\n * remove them from our array of observed elements.\n *\n * @private\n * @static\n */\n flush(): void {\n this.resizeObserverEntries.forEach((el) => {\n if (!document.body.contains(el)) this.unobserve(el);\n });\n }\n}\n\nexport { ShinyResizeObserver };\n", "import { getAllFocusableChildren } from \"./_utils\";\nimport { ShinyResizeObserver } from \"./_shinyResizeObserver\";\n\n/**\n * The overlay element that is placed behind the card when expanded full screen.\n *\n * @interface CardFullScreenOverlay\n * @typedef {CardFullScreenOverlay}\n */\ninterface CardFullScreenOverlay {\n /**\n * The full screen overlay container.\n * @type {HTMLDivElement}\n */\n container: HTMLDivElement;\n /**\n * The anchor element used to close the full screen overlay.\n * @type {HTMLAnchorElement}\n */\n anchor: HTMLAnchorElement;\n}\n\n/**\n * The bslib card component class.\n *\n * @class Card\n * @typedef {Card}\n */\nclass Card {\n /**\n * The card container element.\n * @private\n * @type {HTMLElement}\n */\n private card: HTMLElement;\n /**\n * The card's full screen overlay element. We create this element once and add\n * and remove it from the DOM as needed (this simplifies focus management\n * while in full screen mode).\n * @private\n * @type {CardFullScreenOverlay}\n */\n private overlay: CardFullScreenOverlay;\n\n /**\n * Key bslib-specific classes and attributes used by the card component.\n * @private\n * @static\n * @type {{ ATTR_INIT: string; CLASS_CARD: string; CLASS_FULL_SCREEN: string; CLASS_HAS_FULL_SCREEN: string; CLASS_FULL_SCREEN_ENTER: string; CLASS_FULL_SCREEN_EXIT: string; ID_FULL_SCREEN_OVERLAY: string; }}\n */\n private static attr = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ATTR_INIT: \"data-bslib-card-init\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_CARD: \"bslib-card\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ATTR_FULL_SCREEN: \"data-full-screen\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_HAS_FULL_SCREEN: \"bslib-has-full-screen\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_FULL_SCREEN_ENTER: \"bslib-full-screen-enter\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_FULL_SCREEN_EXIT: \"bslib-full-screen-exit\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ID_FULL_SCREEN_OVERLAY: \"bslib-full-screen-overlay\",\n };\n\n /**\n * A Shiny-specific resize observer that ensures Shiny outputs in within the\n * card resize appropriately.\n * @private\n * @type {ShinyResizeObserver}\n * @static\n */\n private static shinyResizeObserver = new ShinyResizeObserver();\n\n /**\n * Creates an instance of a bslib Card component.\n *\n * @constructor\n * @param {HTMLElement} card\n */\n constructor(card: HTMLElement) {\n // remove initialization attribute and script\n card.removeAttribute(Card.attr.ATTR_INIT);\n card\n .querySelector(`script[${Card.attr.ATTR_INIT}]`)\n ?.remove();\n\n this.card = card;\n Card.instanceMap.set(card, this);\n\n // Let Shiny know to trigger resize when the card size changes\n // TODO: shiny could/should do this itself (rstudio/shiny#3682)\n Card.shinyResizeObserver.observe(this.card);\n\n this._addEventListeners();\n this.overlay = this._createOverlay();\n\n // bind event handler methods to this card instance\n this._exitFullScreenOnEscape = this._exitFullScreenOnEscape.bind(this);\n this._trapFocusExit = this._trapFocusExit.bind(this);\n }\n\n /**\n * Enter the card's full screen mode, either programmatically or via an event\n * handler. Full screen mode is activated by adding a class to the card that\n * positions it absolutely and expands it to fill the viewport. In addition,\n * we add a full screen overlay element behind the card and we trap focus in\n * the expanded card while in full screen mode.\n *\n * @param {?Event} [event]\n */\n enterFullScreen(event?: Event): void {\n if (event) event.preventDefault();\n\n document.addEventListener(\"keydown\", this._exitFullScreenOnEscape, false);\n\n // trap focus in the fullscreen container, listening for Tab key on the\n // capture phase so we have the best chance of preventing other handlers\n document.addEventListener(\"keydown\", this._trapFocusExit, true);\n\n this.card.setAttribute(Card.attr.ATTR_FULL_SCREEN, \"true\");\n document.body.classList.add(Card.attr.CLASS_HAS_FULL_SCREEN);\n this.card.insertAdjacentElement(\"beforebegin\", this.overlay.container);\n\n // Set initial focus on the card, if not already\n if (\n !this.card.contains(document.activeElement) ||\n document.activeElement?.classList.contains(\n Card.attr.CLASS_FULL_SCREEN_ENTER\n )\n ) {\n this.card.setAttribute(\"tabindex\", \"-1\");\n this.card.focus();\n }\n }\n\n /**\n * Exit full screen mode. This removes the full screen overlay element,\n * removes the full screen class from the card, and removes the keyboard event\n * listeners that were added when entering full screen mode.\n */\n exitFullScreen(): void {\n document.removeEventListener(\n \"keydown\",\n this._exitFullScreenOnEscape,\n false\n );\n document.removeEventListener(\"keydown\", this._trapFocusExit, true);\n\n // Remove overlay and remove full screen classes from card\n this.overlay.container.remove();\n this.card.setAttribute(Card.attr.ATTR_FULL_SCREEN, \"false\");\n this.card.removeAttribute(\"tabindex\");\n document.body.classList.remove(Card.attr.CLASS_HAS_FULL_SCREEN);\n }\n\n /**\n * Adds general card-specific event listeners.\n * @private\n */\n private _addEventListeners(): void {\n const btnFullScreen = this.card.querySelector(\n `:scope > * > .${Card.attr.CLASS_FULL_SCREEN_ENTER}`\n );\n if (!btnFullScreen) return;\n btnFullScreen.addEventListener(\"click\", (ev) => this.enterFullScreen(ev));\n }\n\n /**\n * An event handler to exit full screen mode when the Escape key is pressed.\n * @private\n * @param {KeyboardEvent} event\n */\n private _exitFullScreenOnEscape(event: KeyboardEvent): void {\n if (!(event.target instanceof HTMLElement)) return;\n // If the user is in the middle of a select input choice, don't exit\n const selOpenSelectInput = [\"select[open]\", \"input[aria-expanded='true']\"];\n if (event.target.matches(selOpenSelectInput.join(\", \"))) return;\n\n if (event.key === \"Escape\") {\n this.exitFullScreen();\n }\n }\n\n /**\n * An event handler to trap focus within the card when in full screen mode.\n *\n * @description\n * This keyboard event handler ensures that tab focus stays within the card\n * when in full screen mode. When the card is first expanded,\n * we move focus to the card element itself. If focus somehow leaves the card,\n * we returns focus to the card container.\n *\n * Within the card, we handle only tabbing from the close anchor or the last\n * focusable element and only when tab focus would have otherwise left the\n * card. In those cases, we cycle focus to the last focusable element or back\n * to the anchor. If the card doesn't have any focusable elements, we move\n * focus to the close anchor.\n *\n * @note\n * Because the card contents may change, we check for focusable elements\n * every time the handler is called.\n *\n * @private\n * @param {KeyboardEvent} event\n */\n private _trapFocusExit(event: KeyboardEvent): void {\n if (!(event instanceof KeyboardEvent)) return;\n if (event.key !== \"Tab\") return;\n\n const isFocusedContainer = event.target === this.card;\n const isFocusedAnchor = event.target === this.overlay.anchor;\n const isFocusedWithin = this.card.contains(event.target as Node);\n\n const stopEvent = () => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n\n if (!(isFocusedWithin || isFocusedContainer || isFocusedAnchor)) {\n // If focus is outside the card, return to the card\n stopEvent();\n this.card.focus();\n return;\n }\n\n // Check focusables every time because the card contents may have changed\n // but exclude the full screen enter button from this list of elements\n const focusableElements = getAllFocusableChildren(this.card).filter(\n (el) => !el.classList.contains(Card.attr.CLASS_FULL_SCREEN_ENTER)\n );\n const hasFocusableElements = focusableElements.length > 0;\n\n // We need to handle five cases:\n // 1. The card has no focusable elements --> focus the anchor\n // 2. Focus is on the card container (do nothing, natural tab order)\n // 3. Focus is on the anchor and the user pressed Tab + Shift (backwards)\n // -> Move to the last focusable element (end of card)\n // 4. Focus is on the last focusable element and the user pressed Tab\n // (forwards) -> Move to the anchor (top of card)\n // 5. otherwise we don't interfere\n\n if (!hasFocusableElements) {\n // case 1\n stopEvent();\n this.overlay.anchor.focus();\n return;\n }\n\n // case 2\n if (isFocusedContainer) return;\n\n const lastFocusable = focusableElements[focusableElements.length - 1];\n const isFocusedLast = event.target === lastFocusable;\n\n if (isFocusedAnchor && event.shiftKey) {\n stopEvent();\n lastFocusable.focus();\n return;\n }\n\n if (isFocusedLast && !event.shiftKey) {\n stopEvent();\n this.overlay.anchor.focus();\n return;\n }\n }\n\n /**\n * Creates the full screen overlay.\n * @private\n * @returns {CardFullScreenOverlay}\n */\n private _createOverlay(): CardFullScreenOverlay {\n const container = document.createElement(\"div\");\n container.id = Card.attr.ID_FULL_SCREEN_OVERLAY;\n container.onclick = this.exitFullScreen.bind(this);\n\n const anchor = this._createOverlayCloseAnchor();\n container.appendChild(anchor);\n\n return { container, anchor };\n }\n\n /**\n * Creates the anchor element used to exit the full screen mode.\n * @private\n * @returns {HTMLAnchorElement}\n */\n private _createOverlayCloseAnchor(): HTMLAnchorElement {\n const anchor = document.createElement(\"a\");\n anchor.classList.add(Card.attr.CLASS_FULL_SCREEN_EXIT);\n anchor.tabIndex = 0;\n anchor.onclick = () => this.exitFullScreen();\n anchor.onkeydown = (ev) => {\n if (ev.key === \"Enter\" || ev.key === \" \") {\n this.exitFullScreen();\n }\n };\n anchor.innerHTML = this._overlayCloseHtml();\n\n return anchor;\n }\n\n /**\n * Returns the HTML for the close icon.\n * @private\n * @returns {string}\n */\n private _overlayCloseHtml(): string {\n return (\n \"Close \" +\n \"\" +\n \"\"\n );\n }\n\n /**\n * The registry of card instances and their associated DOM elements.\n * @private\n * @static\n * @type {WeakMap}\n */\n private static instanceMap: WeakMap = new WeakMap();\n\n /**\n * Returns the card instance associated with the given element, if any.\n * @public\n * @static\n * @param {HTMLElement} el\n * @returns {(Card | undefined)}\n */\n public static getInstance(el: HTMLElement): Card | undefined {\n return Card.instanceMap.get(el);\n }\n\n /**\n * If cards are initialized before the DOM is ready, we re-schedule the\n * initialization to occur on DOMContentLoaded.\n * @private\n * @static\n * @type {boolean}\n */\n private static onReadyScheduled = false;\n\n /**\n * Initializes all cards that require initialization on the page, or schedules\n * initialization if the DOM is not yet ready.\n * @public\n * @static\n * @param {boolean} [flushResizeObserver=true]\n */\n public static initializeAllCards(flushResizeObserver = true): void {\n if (document.readyState === \"loading\") {\n if (!Card.onReadyScheduled) {\n Card.onReadyScheduled = true;\n document.addEventListener(\"DOMContentLoaded\", () => {\n Card.initializeAllCards(false);\n });\n }\n return;\n }\n\n if (flushResizeObserver) {\n // Trigger a recheck of observed cards to unobserve non-existent cards\n Card.shinyResizeObserver.flush();\n }\n\n const initSelector = `.${Card.attr.CLASS_CARD}[${Card.attr.ATTR_INIT}]`;\n if (!document.querySelector(initSelector)) {\n // no cards to initialize\n return;\n }\n\n const cards = document.querySelectorAll(initSelector);\n cards.forEach((card) => new Card(card as HTMLElement));\n }\n}\n\n// attach Sidebar class to window for global usage\n(window as any).bslib = (window as any).bslib || {};\n(window as any).bslib.Card = Card;\n\nexport { Card };\n"], - "mappings": "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", - "names": [] -} diff --git a/inst/components/dist/card/card.min.js b/inst/components/dist/card/card.min.js deleted file mode 100644 index 08bcaffab..000000000 --- a/inst/components/dist/card/card.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ -"use strict";(()=>{var p=window.Shiny?Shiny.InputBinding:class{};function h(u){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])"],s=e.map(i=>i+t.join("")),r=u.querySelectorAll(s.join(", "));return Array.from(r)}var d=class{constructor(){this.resizeObserverEntries=[],this.resizeObserver=new ResizeObserver(e=>{let t=new Event("resize");if(window.dispatchEvent(t),!window.Shiny)return;let s=[];for(let r of e)r.target instanceof HTMLElement&&r.target.querySelector(".shiny-bound-output")&&r.target.querySelectorAll(".shiny-bound-output").forEach(i=>{if(s.includes(i))return;let{binding:o,onResize:E}=$(i).data("shinyOutputBinding");if(!o||!o.resize)return;let c=i.shinyResizeObserver;if(c&&c!==this||(c||(i.shinyResizeObserver=this),E(i),s.push(i),!i.classList.contains("shiny-plot-output")))return;let l=i.querySelector('img:not([width="100%"])');l&&l.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 n=class{constructor(e){var t;e.removeAttribute(n.attr.ATTR_INIT),(t=e.querySelector(`script[${n.attr.ATTR_INIT}]`))==null||t.remove(),this.card=e,n.instanceMap.set(e,this),n.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(n.attr.ATTR_FULL_SCREEN,"true"),document.body.classList.add(n.attr.CLASS_HAS_FULL_SCREEN),this.card.insertAdjacentElement("beforebegin",this.overlay.container),(!this.card.contains(document.activeElement)||(t=document.activeElement)!=null&&t.classList.contains(n.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(n.attr.ATTR_FULL_SCREEN,"false"),this.card.removeAttribute("tabindex"),document.body.classList.remove(n.attr.CLASS_HAS_FULL_SCREEN)}_addEventListeners(){let e=this.card.querySelector(`:scope > * > .${n.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,s=e.target===this.overlay.anchor,r=this.card.contains(e.target),i=()=>{e.preventDefault(),e.stopImmediatePropagation()};if(!(r||t||s)){i(),this.card.focus();return}let o=h(this.card).filter(b=>!b.classList.contains(n.attr.CLASS_FULL_SCREEN_ENTER));if(!(o.length>0)){i(),this.overlay.anchor.focus();return}if(t)return;let c=o[o.length-1],l=e.target===c;if(s&&e.shiftKey){i(),c.focus();return}if(l&&!e.shiftKey){i(),this.overlay.anchor.focus();return}}_createOverlay(){let e=document.createElement("div");e.id=n.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(n.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 n.instanceMap.get(e)}static initializeAllCards(e=!0){if(document.readyState==="loading"){n.onReadyScheduled||(n.onReadyScheduled=!0,document.addEventListener("DOMContentLoaded",()=>{n.initializeAllCards(!1)}));return}e&&n.shinyResizeObserver.flush();let t=`.${n.attr.CLASS_CARD}[${n.attr.ATTR_INIT}]`;if(!document.querySelector(t))return;document.querySelectorAll(t).forEach(r=>new n(r))}},a=n;a.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"},a.shinyResizeObserver=new d,a.instanceMap=new WeakMap,a.onReadyScheduled=!1;window.bslib=window.bslib||{};window.bslib.Card=a;})(); -//# sourceMappingURL=card.min.js.map diff --git a/inst/components/dist/card/card.min.js.map b/inst/components/dist/card/card.min.js.map deleted file mode 100644 index 9713b11fd..000000000 --- a/inst/components/dist/card/card.min.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../srcts/src/components/_utils.ts", "../../../../srcts/src/components/_shinyResizeObserver.ts", "../../../../srcts/src/components/card.ts"], - "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "/**\n * A resize observer that ensures Shiny outputs resize during or just after\n * their parent container size changes. Useful, in particular, for sidebar\n * transitions or for full-screen card transitions.\n *\n * @class ShinyResizeObserver\n * @typedef {ShinyResizeObserver}\n */\nclass ShinyResizeObserver {\n /**\n * The actual ResizeObserver instance.\n * @private\n * @type {ResizeObserver}\n */\n private resizeObserver: ResizeObserver;\n /**\n * An array of elements that are currently being watched by the Resize\n * Observer.\n *\n * @details\n * We don't currently have lifecycle hooks that allow us to unobserve elements\n * when they are removed from the DOM. As a result, we need to manually check\n * that the elements we're watching still exist in the DOM. This array keeps\n * track of the elements we're watching so that we can check them later.\n * @private\n * @type {HTMLElement[]}\n */\n private resizeObserverEntries: HTMLElement[];\n\n /**\n * Watch containers for size changes and ensure that Shiny outputs and\n * htmlwidgets within resize appropriately.\n *\n * @details\n * The ShinyResizeObserver is used to watch the containers, such as Sidebars\n * and Cards for size changes, in particular when the sidebar state is toggled\n * or the card body is expanded full screen. It performs two primary tasks:\n *\n * 1. Dispatches a `resize` event on the window object. This is necessary to\n * ensure that Shiny outputs resize appropriately. In general, the window\n * resizing is throttled and the output update occurs when the transition\n * is complete.\n * 2. If an output with a resize method on the output binding is detected, we\n * directly call the `.onResize()` method of the binding. This ensures that\n * htmlwidgets transition smoothly. In static mode, htmlwidgets does this\n * already.\n *\n * @note\n * This resize observer also handles race conditions in some complex\n * fill-based layouts with multiple outputs (e.g., plotly), where shiny\n * initializes with the correct sizing, but in-between the 1st and last\n * renderValue(), the size of the output containers can change, meaning every\n * output but the 1st gets initialized with the wrong size during their\n * renderValue(). Then, after the render phase, shiny won't know to trigger a\n * resize since all the widgets will return to their original size (and thus,\n * Shiny thinks there isn't any resizing to do). The resize observer works\n * around this by ensuring that the output is resized whenever its container\n * size changes.\n * @constructor\n */\n constructor() {\n this.resizeObserverEntries = [];\n this.resizeObserver = new ResizeObserver((entries) => {\n const resizeEvent = new Event(\"resize\");\n window.dispatchEvent(resizeEvent);\n\n // the rest of this callback is only relevant in Shiny apps\n if (!window.Shiny) return;\n\n const resized = [] as HTMLElement[];\n\n for (const entry of entries) {\n if (!(entry.target instanceof HTMLElement)) continue;\n if (!entry.target.querySelector(\".shiny-bound-output\")) continue;\n\n entry.target\n .querySelectorAll(\".shiny-bound-output\")\n .forEach((el) => {\n if (resized.includes(el)) return;\n\n const { binding, onResize } = $(el).data(\"shinyOutputBinding\");\n if (!binding || !binding.resize) return;\n\n // if this output is owned by another observer, skip it\n const owner = (el as any).shinyResizeObserver;\n if (owner && owner !== this) return;\n // mark this output as owned by this shinyResizeObserver instance\n if (!owner) (el as any).shinyResizeObserver = this;\n\n // trigger immediate resizing of outputs with a resize method\n onResize(el);\n // only once per output and resize event\n resized.push(el);\n\n // set plot images to 100% width temporarily during the transition\n if (!el.classList.contains(\"shiny-plot-output\")) return;\n const img = el.querySelector(\n 'img:not([width=\"100%\"])'\n );\n if (img) img.setAttribute(\"width\", \"100%\");\n });\n }\n });\n }\n\n /**\n * Observe an element for size changes.\n * @param {HTMLElement} el - The element to observe.\n */\n observe(el: HTMLElement): void {\n this.resizeObserver.observe(el);\n this.resizeObserverEntries.push(el);\n }\n\n /**\n * Stop observing an element for size changes.\n * @param {HTMLElement} el - The element to stop observing.\n */\n unobserve(el: HTMLElement): void {\n const idxEl = this.resizeObserverEntries.indexOf(el);\n if (idxEl < 0) return;\n\n this.resizeObserver.unobserve(el);\n this.resizeObserverEntries.splice(idxEl, 1);\n }\n\n /**\n * This method checks that we're not continuing to watch elements that no\n * longer exist in the DOM. If any are found, we stop observing them and\n * remove them from our array of observed elements.\n *\n * @private\n * @static\n */\n flush(): void {\n this.resizeObserverEntries.forEach((el) => {\n if (!document.body.contains(el)) this.unobserve(el);\n });\n }\n}\n\nexport { ShinyResizeObserver };\n", "import { getAllFocusableChildren } from \"./_utils\";\nimport { ShinyResizeObserver } from \"./_shinyResizeObserver\";\n\n/**\n * The overlay element that is placed behind the card when expanded full screen.\n *\n * @interface CardFullScreenOverlay\n * @typedef {CardFullScreenOverlay}\n */\ninterface CardFullScreenOverlay {\n /**\n * The full screen overlay container.\n * @type {HTMLDivElement}\n */\n container: HTMLDivElement;\n /**\n * The anchor element used to close the full screen overlay.\n * @type {HTMLAnchorElement}\n */\n anchor: HTMLAnchorElement;\n}\n\n/**\n * The bslib card component class.\n *\n * @class Card\n * @typedef {Card}\n */\nclass Card {\n /**\n * The card container element.\n * @private\n * @type {HTMLElement}\n */\n private card: HTMLElement;\n /**\n * The card's full screen overlay element. We create this element once and add\n * and remove it from the DOM as needed (this simplifies focus management\n * while in full screen mode).\n * @private\n * @type {CardFullScreenOverlay}\n */\n private overlay: CardFullScreenOverlay;\n\n /**\n * Key bslib-specific classes and attributes used by the card component.\n * @private\n * @static\n * @type {{ ATTR_INIT: string; CLASS_CARD: string; CLASS_FULL_SCREEN: string; CLASS_HAS_FULL_SCREEN: string; CLASS_FULL_SCREEN_ENTER: string; CLASS_FULL_SCREEN_EXIT: string; ID_FULL_SCREEN_OVERLAY: string; }}\n */\n private static attr = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ATTR_INIT: \"data-bslib-card-init\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_CARD: \"bslib-card\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ATTR_FULL_SCREEN: \"data-full-screen\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_HAS_FULL_SCREEN: \"bslib-has-full-screen\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_FULL_SCREEN_ENTER: \"bslib-full-screen-enter\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_FULL_SCREEN_EXIT: \"bslib-full-screen-exit\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ID_FULL_SCREEN_OVERLAY: \"bslib-full-screen-overlay\",\n };\n\n /**\n * A Shiny-specific resize observer that ensures Shiny outputs in within the\n * card resize appropriately.\n * @private\n * @type {ShinyResizeObserver}\n * @static\n */\n private static shinyResizeObserver = new ShinyResizeObserver();\n\n /**\n * Creates an instance of a bslib Card component.\n *\n * @constructor\n * @param {HTMLElement} card\n */\n constructor(card: HTMLElement) {\n // remove initialization attribute and script\n card.removeAttribute(Card.attr.ATTR_INIT);\n card\n .querySelector(`script[${Card.attr.ATTR_INIT}]`)\n ?.remove();\n\n this.card = card;\n Card.instanceMap.set(card, this);\n\n // Let Shiny know to trigger resize when the card size changes\n // TODO: shiny could/should do this itself (rstudio/shiny#3682)\n Card.shinyResizeObserver.observe(this.card);\n\n this._addEventListeners();\n this.overlay = this._createOverlay();\n\n // bind event handler methods to this card instance\n this._exitFullScreenOnEscape = this._exitFullScreenOnEscape.bind(this);\n this._trapFocusExit = this._trapFocusExit.bind(this);\n }\n\n /**\n * Enter the card's full screen mode, either programmatically or via an event\n * handler. Full screen mode is activated by adding a class to the card that\n * positions it absolutely and expands it to fill the viewport. In addition,\n * we add a full screen overlay element behind the card and we trap focus in\n * the expanded card while in full screen mode.\n *\n * @param {?Event} [event]\n */\n enterFullScreen(event?: Event): void {\n if (event) event.preventDefault();\n\n document.addEventListener(\"keydown\", this._exitFullScreenOnEscape, false);\n\n // trap focus in the fullscreen container, listening for Tab key on the\n // capture phase so we have the best chance of preventing other handlers\n document.addEventListener(\"keydown\", this._trapFocusExit, true);\n\n this.card.setAttribute(Card.attr.ATTR_FULL_SCREEN, \"true\");\n document.body.classList.add(Card.attr.CLASS_HAS_FULL_SCREEN);\n this.card.insertAdjacentElement(\"beforebegin\", this.overlay.container);\n\n // Set initial focus on the card, if not already\n if (\n !this.card.contains(document.activeElement) ||\n document.activeElement?.classList.contains(\n Card.attr.CLASS_FULL_SCREEN_ENTER\n )\n ) {\n this.card.setAttribute(\"tabindex\", \"-1\");\n this.card.focus();\n }\n }\n\n /**\n * Exit full screen mode. This removes the full screen overlay element,\n * removes the full screen class from the card, and removes the keyboard event\n * listeners that were added when entering full screen mode.\n */\n exitFullScreen(): void {\n document.removeEventListener(\n \"keydown\",\n this._exitFullScreenOnEscape,\n false\n );\n document.removeEventListener(\"keydown\", this._trapFocusExit, true);\n\n // Remove overlay and remove full screen classes from card\n this.overlay.container.remove();\n this.card.setAttribute(Card.attr.ATTR_FULL_SCREEN, \"false\");\n this.card.removeAttribute(\"tabindex\");\n document.body.classList.remove(Card.attr.CLASS_HAS_FULL_SCREEN);\n }\n\n /**\n * Adds general card-specific event listeners.\n * @private\n */\n private _addEventListeners(): void {\n const btnFullScreen = this.card.querySelector(\n `:scope > * > .${Card.attr.CLASS_FULL_SCREEN_ENTER}`\n );\n if (!btnFullScreen) return;\n btnFullScreen.addEventListener(\"click\", (ev) => this.enterFullScreen(ev));\n }\n\n /**\n * An event handler to exit full screen mode when the Escape key is pressed.\n * @private\n * @param {KeyboardEvent} event\n */\n private _exitFullScreenOnEscape(event: KeyboardEvent): void {\n if (!(event.target instanceof HTMLElement)) return;\n // If the user is in the middle of a select input choice, don't exit\n const selOpenSelectInput = [\"select[open]\", \"input[aria-expanded='true']\"];\n if (event.target.matches(selOpenSelectInput.join(\", \"))) return;\n\n if (event.key === \"Escape\") {\n this.exitFullScreen();\n }\n }\n\n /**\n * An event handler to trap focus within the card when in full screen mode.\n *\n * @description\n * This keyboard event handler ensures that tab focus stays within the card\n * when in full screen mode. When the card is first expanded,\n * we move focus to the card element itself. If focus somehow leaves the card,\n * we returns focus to the card container.\n *\n * Within the card, we handle only tabbing from the close anchor or the last\n * focusable element and only when tab focus would have otherwise left the\n * card. In those cases, we cycle focus to the last focusable element or back\n * to the anchor. If the card doesn't have any focusable elements, we move\n * focus to the close anchor.\n *\n * @note\n * Because the card contents may change, we check for focusable elements\n * every time the handler is called.\n *\n * @private\n * @param {KeyboardEvent} event\n */\n private _trapFocusExit(event: KeyboardEvent): void {\n if (!(event instanceof KeyboardEvent)) return;\n if (event.key !== \"Tab\") return;\n\n const isFocusedContainer = event.target === this.card;\n const isFocusedAnchor = event.target === this.overlay.anchor;\n const isFocusedWithin = this.card.contains(event.target as Node);\n\n const stopEvent = () => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n\n if (!(isFocusedWithin || isFocusedContainer || isFocusedAnchor)) {\n // If focus is outside the card, return to the card\n stopEvent();\n this.card.focus();\n return;\n }\n\n // Check focusables every time because the card contents may have changed\n // but exclude the full screen enter button from this list of elements\n const focusableElements = getAllFocusableChildren(this.card).filter(\n (el) => !el.classList.contains(Card.attr.CLASS_FULL_SCREEN_ENTER)\n );\n const hasFocusableElements = focusableElements.length > 0;\n\n // We need to handle five cases:\n // 1. The card has no focusable elements --> focus the anchor\n // 2. Focus is on the card container (do nothing, natural tab order)\n // 3. Focus is on the anchor and the user pressed Tab + Shift (backwards)\n // -> Move to the last focusable element (end of card)\n // 4. Focus is on the last focusable element and the user pressed Tab\n // (forwards) -> Move to the anchor (top of card)\n // 5. otherwise we don't interfere\n\n if (!hasFocusableElements) {\n // case 1\n stopEvent();\n this.overlay.anchor.focus();\n return;\n }\n\n // case 2\n if (isFocusedContainer) return;\n\n const lastFocusable = focusableElements[focusableElements.length - 1];\n const isFocusedLast = event.target === lastFocusable;\n\n if (isFocusedAnchor && event.shiftKey) {\n stopEvent();\n lastFocusable.focus();\n return;\n }\n\n if (isFocusedLast && !event.shiftKey) {\n stopEvent();\n this.overlay.anchor.focus();\n return;\n }\n }\n\n /**\n * Creates the full screen overlay.\n * @private\n * @returns {CardFullScreenOverlay}\n */\n private _createOverlay(): CardFullScreenOverlay {\n const container = document.createElement(\"div\");\n container.id = Card.attr.ID_FULL_SCREEN_OVERLAY;\n container.onclick = this.exitFullScreen.bind(this);\n\n const anchor = this._createOverlayCloseAnchor();\n container.appendChild(anchor);\n\n return { container, anchor };\n }\n\n /**\n * Creates the anchor element used to exit the full screen mode.\n * @private\n * @returns {HTMLAnchorElement}\n */\n private _createOverlayCloseAnchor(): HTMLAnchorElement {\n const anchor = document.createElement(\"a\");\n anchor.classList.add(Card.attr.CLASS_FULL_SCREEN_EXIT);\n anchor.tabIndex = 0;\n anchor.onclick = () => this.exitFullScreen();\n anchor.onkeydown = (ev) => {\n if (ev.key === \"Enter\" || ev.key === \" \") {\n this.exitFullScreen();\n }\n };\n anchor.innerHTML = this._overlayCloseHtml();\n\n return anchor;\n }\n\n /**\n * Returns the HTML for the close icon.\n * @private\n * @returns {string}\n */\n private _overlayCloseHtml(): string {\n return (\n \"Close \" +\n \"\" +\n \"\"\n );\n }\n\n /**\n * The registry of card instances and their associated DOM elements.\n * @private\n * @static\n * @type {WeakMap}\n */\n private static instanceMap: WeakMap = new WeakMap();\n\n /**\n * Returns the card instance associated with the given element, if any.\n * @public\n * @static\n * @param {HTMLElement} el\n * @returns {(Card | undefined)}\n */\n public static getInstance(el: HTMLElement): Card | undefined {\n return Card.instanceMap.get(el);\n }\n\n /**\n * If cards are initialized before the DOM is ready, we re-schedule the\n * initialization to occur on DOMContentLoaded.\n * @private\n * @static\n * @type {boolean}\n */\n private static onReadyScheduled = false;\n\n /**\n * Initializes all cards that require initialization on the page, or schedules\n * initialization if the DOM is not yet ready.\n * @public\n * @static\n * @param {boolean} [flushResizeObserver=true]\n */\n public static initializeAllCards(flushResizeObserver = true): void {\n if (document.readyState === \"loading\") {\n if (!Card.onReadyScheduled) {\n Card.onReadyScheduled = true;\n document.addEventListener(\"DOMContentLoaded\", () => {\n Card.initializeAllCards(false);\n });\n }\n return;\n }\n\n if (flushResizeObserver) {\n // Trigger a recheck of observed cards to unobserve non-existent cards\n Card.shinyResizeObserver.flush();\n }\n\n const initSelector = `.${Card.attr.CLASS_CARD}[${Card.attr.ATTR_INIT}]`;\n if (!document.querySelector(initSelector)) {\n // no cards to initialize\n return;\n }\n\n const cards = document.querySelectorAll(initSelector);\n cards.forEach((card) => new Card(card as HTMLElement));\n }\n}\n\n// attach Sidebar class to window for global usage\n(window as any).bslib = (window as any).bslib || {};\n(window as any).bslib.Card = Card;\n\nexport { Card };\n"], - "mappings": ";mBAQA,IAAMA,EACJ,OAAO,MAAQ,MAAM,aAAe,KAAM,CAAC,EA2C7C,SAASC,EAAwBC,EAAgC,CAE/D,IAAMC,EAAO,CACX,UACA,aACA,SACA,kBACA,QACA,SACA,SACA,WACA,uBACA,2BACA,2BACA,YACF,EACMC,EAAY,CAAC,wBAAyB,kBAAkB,EACxDC,EAAYF,EAAK,IAAKG,GAAMA,EAAIF,EAAU,KAAK,EAAE,CAAC,EAClDG,EAAYL,EAAG,iBAAiBG,EAAU,KAAK,IAAI,CAAC,EAC1D,OAAO,MAAM,KAAKE,CAAS,CAC7B,CChEA,IAAMC,EAAN,KAA0B,CAoDxB,aAAc,CACZ,KAAK,sBAAwB,CAAC,EAC9B,KAAK,eAAiB,IAAI,eAAgBC,GAAY,CACpD,IAAMC,EAAc,IAAI,MAAM,QAAQ,EAItC,GAHA,OAAO,cAAcA,CAAW,EAG5B,CAAC,OAAO,MAAO,OAEnB,IAAMC,EAAU,CAAC,EAEjB,QAAWC,KAASH,EACZG,EAAM,kBAAkB,aACzBA,EAAM,OAAO,cAAc,qBAAqB,GAErDA,EAAM,OACH,iBAA8B,qBAAqB,EACnD,QAASC,GAAO,CACf,GAAIF,EAAQ,SAASE,CAAE,EAAG,OAE1B,GAAM,CAAE,QAAAC,EAAS,SAAAC,CAAS,EAAI,EAAEF,CAAE,EAAE,KAAK,oBAAoB,EAC7D,GAAI,CAACC,GAAW,CAACA,EAAQ,OAAQ,OAGjC,IAAME,EAASH,EAAW,oBAW1B,GAVIG,GAASA,IAAU,OAElBA,IAAQH,EAAW,oBAAsB,MAG9CE,EAASF,CAAE,EAEXF,EAAQ,KAAKE,CAAE,EAGX,CAACA,EAAG,UAAU,SAAS,mBAAmB,GAAG,OACjD,IAAMI,EAAMJ,EAAG,cACb,yBACF,EACII,GAAKA,EAAI,aAAa,QAAS,MAAM,CAC3C,CAAC,CAEP,CAAC,CACH,CAMA,QAAQJ,EAAuB,CAC7B,KAAK,eAAe,QAAQA,CAAE,EAC9B,KAAK,sBAAsB,KAAKA,CAAE,CACpC,CAMA,UAAUA,EAAuB,CAC/B,IAAMK,EAAQ,KAAK,sBAAsB,QAAQL,CAAE,EAC/CK,EAAQ,IAEZ,KAAK,eAAe,UAAUL,CAAE,EAChC,KAAK,sBAAsB,OAAOK,EAAO,CAAC,EAC5C,CAUA,OAAc,CACZ,KAAK,sBAAsB,QAASL,GAAO,CACpC,SAAS,KAAK,SAASA,CAAE,GAAG,KAAK,UAAUA,CAAE,CACpD,CAAC,CACH,CACF,EC/GA,IAAMM,EAAN,KAAW,CAsDT,YAAYC,EAAmB,CAlFjC,IAAAC,EAoFID,EAAK,gBAAgBD,EAAK,KAAK,SAAS,GACxCE,EAAAD,EACG,cAAiC,UAAUD,EAAK,KAAK,YAAY,IADpE,MAAAE,EAEI,SAEJ,KAAK,KAAOD,EACZD,EAAK,YAAY,IAAIC,EAAM,IAAI,EAI/BD,EAAK,oBAAoB,QAAQ,KAAK,IAAI,EAE1C,KAAK,mBAAmB,EACxB,KAAK,QAAU,KAAK,eAAe,EAGnC,KAAK,wBAA0B,KAAK,wBAAwB,KAAK,IAAI,EACrE,KAAK,eAAiB,KAAK,eAAe,KAAK,IAAI,CACrD,CAWA,gBAAgBG,EAAqB,CAjHvC,IAAAD,EAkHQC,GAAOA,EAAM,eAAe,EAEhC,SAAS,iBAAiB,UAAW,KAAK,wBAAyB,EAAK,EAIxE,SAAS,iBAAiB,UAAW,KAAK,eAAgB,EAAI,EAE9D,KAAK,KAAK,aAAaH,EAAK,KAAK,iBAAkB,MAAM,EACzD,SAAS,KAAK,UAAU,IAAIA,EAAK,KAAK,qBAAqB,EAC3D,KAAK,KAAK,sBAAsB,cAAe,KAAK,QAAQ,SAAS,GAInE,CAAC,KAAK,KAAK,SAAS,SAAS,aAAa,IAC1CE,EAAA,SAAS,gBAAT,MAAAA,EAAwB,UAAU,SAChCF,EAAK,KAAK,4BAGZ,KAAK,KAAK,aAAa,WAAY,IAAI,EACvC,KAAK,KAAK,MAAM,EAEpB,CAOA,gBAAuB,CACrB,SAAS,oBACP,UACA,KAAK,wBACL,EACF,EACA,SAAS,oBAAoB,UAAW,KAAK,eAAgB,EAAI,EAGjE,KAAK,QAAQ,UAAU,OAAO,EAC9B,KAAK,KAAK,aAAaA,EAAK,KAAK,iBAAkB,OAAO,EAC1D,KAAK,KAAK,gBAAgB,UAAU,EACpC,SAAS,KAAK,UAAU,OAAOA,EAAK,KAAK,qBAAqB,CAChE,CAMQ,oBAA2B,CACjC,IAAMI,EAAgB,KAAK,KAAK,cAC9B,iBAAiBJ,EAAK,KAAK,yBAC7B,EACKI,GACLA,EAAc,iBAAiB,QAAUC,GAAO,KAAK,gBAAgBA,CAAE,CAAC,CAC1E,CAOQ,wBAAwBF,EAA4B,CAC1D,GAAI,EAAEA,EAAM,kBAAkB,aAAc,OAE5C,IAAMG,EAAqB,CAAC,eAAgB,6BAA6B,EACrEH,EAAM,OAAO,QAAQG,EAAmB,KAAK,IAAI,CAAC,GAElDH,EAAM,MAAQ,UAChB,KAAK,eAAe,CAExB,CAwBQ,eAAeA,EAA4B,CAEjD,GADI,EAAEA,aAAiB,gBACnBA,EAAM,MAAQ,MAAO,OAEzB,IAAMI,EAAqBJ,EAAM,SAAW,KAAK,KAC3CK,EAAkBL,EAAM,SAAW,KAAK,QAAQ,OAChDM,EAAkB,KAAK,KAAK,SAASN,EAAM,MAAc,EAEzDO,EAAY,IAAM,CACtBP,EAAM,eAAe,EACrBA,EAAM,yBAAyB,CACjC,EAEA,GAAI,EAAEM,GAAmBF,GAAsBC,GAAkB,CAE/DE,EAAU,EACV,KAAK,KAAK,MAAM,EAChB,MACF,CAIA,IAAMC,EAAoBC,EAAwB,KAAK,IAAI,EAAE,OAC1DC,GAAO,CAACA,EAAG,UAAU,SAASb,EAAK,KAAK,uBAAuB,CAClE,EAYA,GAAI,EAXyBW,EAAkB,OAAS,GAW7B,CAEzBD,EAAU,EACV,KAAK,QAAQ,OAAO,MAAM,EAC1B,MACF,CAGA,GAAIH,EAAoB,OAExB,IAAMO,EAAgBH,EAAkBA,EAAkB,OAAS,CAAC,EAC9DI,EAAgBZ,EAAM,SAAWW,EAEvC,GAAIN,GAAmBL,EAAM,SAAU,CACrCO,EAAU,EACVI,EAAc,MAAM,EACpB,MACF,CAEA,GAAIC,GAAiB,CAACZ,EAAM,SAAU,CACpCO,EAAU,EACV,KAAK,QAAQ,OAAO,MAAM,EAC1B,MACF,CACF,CAOQ,gBAAwC,CAC9C,IAAMM,EAAY,SAAS,cAAc,KAAK,EAC9CA,EAAU,GAAKhB,EAAK,KAAK,uBACzBgB,EAAU,QAAU,KAAK,eAAe,KAAK,IAAI,EAEjD,IAAMC,EAAS,KAAK,0BAA0B,EAC9C,OAAAD,EAAU,YAAYC,CAAM,EAErB,CAAE,UAAAD,EAAW,OAAAC,CAAO,CAC7B,CAOQ,2BAA+C,CACrD,IAAMA,EAAS,SAAS,cAAc,GAAG,EACzC,OAAAA,EAAO,UAAU,IAAIjB,EAAK,KAAK,sBAAsB,EACrDiB,EAAO,SAAW,EAClBA,EAAO,QAAU,IAAM,KAAK,eAAe,EAC3CA,EAAO,UAAaZ,GAAO,EACrBA,EAAG,MAAQ,SAAWA,EAAG,MAAQ,MACnC,KAAK,eAAe,CAExB,EACAY,EAAO,UAAY,KAAK,kBAAkB,EAEnCA,CACT,CAOQ,mBAA4B,CAClC,MACE,iSAOJ,CAiBA,OAAc,YAAYJ,EAAmC,CAC3D,OAAOb,EAAK,YAAY,IAAIa,CAAE,CAChC,CAkBA,OAAc,mBAAmBK,EAAsB,GAAY,CACjE,GAAI,SAAS,aAAe,UAAW,CAChClB,EAAK,mBACRA,EAAK,iBAAmB,GACxB,SAAS,iBAAiB,mBAAoB,IAAM,CAClDA,EAAK,mBAAmB,EAAK,CAC/B,CAAC,GAEH,MACF,CAEIkB,GAEFlB,EAAK,oBAAoB,MAAM,EAGjC,IAAMmB,EAAe,IAAInB,EAAK,KAAK,cAAcA,EAAK,KAAK,aAC3D,GAAI,CAAC,SAAS,cAAcmB,CAAY,EAEtC,OAGY,SAAS,iBAAiBA,CAAY,EAC9C,QAASlB,GAAS,IAAID,EAAKC,CAAmB,CAAC,CACvD,CACF,EAlWMmB,EAANpB,EAAMoB,EAsBW,KAAO,CAEpB,UAAW,uBAEX,WAAY,aAEZ,iBAAkB,mBAElB,sBAAuB,wBAEvB,wBAAyB,0BAEzB,uBAAwB,yBAExB,uBAAwB,2BAC1B,EArCIA,EA8CW,oBAAsB,IAAIC,EA9CrCD,EA4SW,YAA0C,IAAI,QA5SzDA,EAgUW,iBAAmB,GAqCnC,OAAe,MAAS,OAAe,OAAS,CAAC,EACjD,OAAe,MAAM,KAAOA", - "names": ["InputBinding", "getAllFocusableChildren", "el", "base", "modifiers", "selectors", "b", "focusable", "ShinyResizeObserver", "entries", "resizeEvent", "resized", "entry", "el", "binding", "onResize", "owner", "img", "idxEl", "_Card", "card", "_a", "event", "btnFullScreen", "ev", "selOpenSelectInput", "isFocusedContainer", "isFocusedAnchor", "isFocusedWithin", "stopEvent", "focusableElements", "getAllFocusableChildren", "el", "lastFocusable", "isFocusedLast", "container", "anchor", "flushResizeObserver", "initSelector", "Card", "ShinyResizeObserver"] -} diff --git a/inst/components/dist/components.css b/inst/components/dist/components.css new file mode 100644 index 000000000..baca96787 --- /dev/null +++ b/inst/components/dist/components.css @@ -0,0 +1 @@ +.accordion .accordion-header{font-size:calc(1.325rem + .9vw);margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2;color:var(--bs-heading-color);margin-bottom:0}@media (min-width: 1200px){.accordion .accordion-header{font-size:2rem}}.accordion .accordion-icon:not(:empty){margin-right:0.75rem;display:flex}.accordion .accordion-button:not(.collapsed){box-shadow:none}.accordion .accordion-button:not(.collapsed):focus{box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.bslib-card{overflow:auto}.bslib-card .card-body+.card-body{padding-top:0}.bslib-card .card-body{overflow:auto}.bslib-card .card-body p{margin-top:0}.bslib-card .card-body p:last-child{margin-bottom:0}.bslib-card .card-body{max-height:var(--bslib-card-body-max-height, none)}.bslib-card[data-full-screen="true"]>.card-body{max-height:var(--bslib-card-body-max-height-full-screen, none)}.bslib-card .card-header .form-group{margin-bottom:0}.bslib-card .card-header .selectize-control{margin-bottom:0}.bslib-card .card-header .selectize-control .item{margin-right:1.15rem}.bslib-card .card-footer{margin-top:auto}.bslib-card .bslib-navs-card-title{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center}.bslib-card .bslib-navs-card-title .nav{margin-left:auto}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border="true"]){border:none}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border-radius="true"]){border-top-left-radius:0;border-top-right-radius:0}[data-full-screen="true"]{position:fixed;inset:3.5rem 1rem 1rem;height:auto !important;max-height:none !important;width:auto !important;z-index:1070}.bslib-full-screen-enter{display:none;position:absolute;bottom:var(--bslib-full-screen-enter-bottom, 0.2rem);right:var(--bslib-full-screen-enter-right, 0);top:var(--bslib-full-screen-enter-top);left:var(--bslib-full-screen-enter-left);color:var(--bslib-color-fg, var(--bs-card-color));background-color:var(--bslib-color-bg, var(--bs-card-bg, var(--bs-body-bg)));border:var(--bs-card-border-width) solid var(--bslib-color-fg, var(--bs-card-border-color));box-shadow:0 2px 4px rgba(0,0,0,0.15);margin:0.2rem 0.4rem;padding:0.55rem !important;font-size:.8rem;cursor:pointer;opacity:0.7;z-index:1070}.bslib-full-screen-enter:hover{opacity:1}.card[data-full-screen="false"]:hover>*>.bslib-full-screen-enter{display:block}.bslib-has-full-screen .card:hover>*>.bslib-full-screen-enter{display:none}@media (max-width: 575.98px){.bslib-full-screen-enter{display:none !important}}.bslib-full-screen-exit{position:relative;top:1.35rem;font-size:0.9rem;cursor:pointer;text-decoration:none;display:flex;float:right;margin-right:2.15rem;align-items:center;color:rgba(var(--bs-body-bg-rgb), 0.8)}.bslib-full-screen-exit:hover{color:rgba(var(--bs-body-bg-rgb), 1)}.bslib-full-screen-exit svg{margin-left:0.5rem;font-size:1.5rem}#bslib-full-screen-overlay{position:fixed;inset:0;background-color:rgba(var(--bs-body-color-rgb), 0.6);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);z-index:1069;animation:bslib-full-screen-overlay-enter 400ms cubic-bezier(0.6, 0.02, 0.65, 1) forwards}@keyframes bslib-full-screen-overlay-enter{0%{opacity:0}100%{opacity:1}}.bslib-grid{display:grid !important;gap:var(--bslib-spacer, 1rem);height:var(--bslib-grid-height)}.bslib-grid.grid{grid-template-columns:repeat(var(--bs-columns, 12), minmax(0, 1fr));grid-template-rows:unset;grid-auto-rows:var(--bslib-grid--row-heights);--bslib-grid--row-heights--xs: unset;--bslib-grid--row-heights--sm: unset;--bslib-grid--row-heights--md: unset;--bslib-grid--row-heights--lg: unset;--bslib-grid--row-heights--xl: unset;--bslib-grid--row-heights--xxl: unset}.bslib-grid.grid.bslib-grid--row-heights--xs{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xs)}@media (min-width: 576px){.bslib-grid.grid.bslib-grid--row-heights--sm{--bslib-grid--row-heights: var(--bslib-grid--row-heights--sm)}}@media (min-width: 768px){.bslib-grid.grid.bslib-grid--row-heights--md{--bslib-grid--row-heights: var(--bslib-grid--row-heights--md)}}@media (min-width: 992px){.bslib-grid.grid.bslib-grid--row-heights--lg{--bslib-grid--row-heights: var(--bslib-grid--row-heights--lg)}}@media (min-width: 1200px){.bslib-grid.grid.bslib-grid--row-heights--xl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xl)}}@media (min-width: 1400px){.bslib-grid.grid.bslib-grid--row-heights--xxl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xxl)}}.bslib-grid>*>.shiny-input-container{width:100%}.bslib-grid-item{grid-column:auto/span 1}@media (max-width: 767.98px){.bslib-grid-item{grid-column:1 / -1}}@media (max-width: 575.98px){.bslib-grid{grid-template-columns:1fr !important;height:var(--bslib-grid-height-mobile)}.bslib-grid.grid{height:unset !important;grid-auto-rows:var(--bslib-grid--row-heights--xs, auto)}}@media (min-width: 576px){.nav:not(.nav-hidden){display:flex !important;display:-webkit-flex !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column){float:none !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.bslib-nav-spacer{margin-left:auto !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.form-inline{margin-top:auto;margin-bottom:auto}.nav:not(.nav-hidden).nav-stacked{flex-direction:column;-webkit-flex-direction:column;height:100%}.nav:not(.nav-hidden).nav-stacked>.bslib-nav-spacer{margin-top:auto !important}}html{height:100%}.bslib-page-fill{width:100%;height:100%;margin:0;padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}@media (max-width: 575.98px){.bslib-page-fill{height:var(--bslib-page-fill-mobile-height, auto)}}.navbar+.container-fluid:has(>.tab-content>.tab-pane.active.html-fill-container){padding-left:0;padding-right:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container{padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child){padding:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border="true"]){border-left:none;border-right:none;border-bottom:none}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius="true"]){border-radius:0}.navbar+div>.bslib-sidebar-layout{border-top:var(--bslib-sidebar-border)}:root{--bslib-page-sidebar-title-bg: #202020;--bslib-page-sidebar-title-color: #fff}.bslib-page-title{background-color:var(--bslib-page-sidebar-title-bg);color:var(--bslib-page-sidebar-title-color);font-size:1.5rem;font-weight:300;padding:var(--bslib-spacer, 1rem);padding-left:1.5rem;margin-bottom:0;border-bottom:1px solid #dee2e6}.bslib-sidebar-layout{--bslib-sidebar-transition-duration: 500ms;--bslib-sidebar-transition-easing-x: cubic-bezier(0.8, 0.78, 0.22, 1.07);--bslib-sidebar-border: var(--bs-card-border-width, var(--bs-border-width)) solid var(--bs-card-border-color, var(--bs-border-color-translucent));--bslib-sidebar-border-radius: var(--bs-border-radius);--bslib-sidebar-vert-border: var(--bs-card-border-width, var(--bs-border-width)) solid var(--bs-card-border-color, var(--bs-border-color-translucent));--bslib-sidebar-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.05);--bslib-sidebar-fg: var(--bs-emphasis-color, black);--bslib-sidebar-main-fg: var(--bs-card-color, var(--bs-body-color));--bslib-sidebar-main-bg: var(--bs-card-bg, var(--bs-body-bg));--bslib-sidebar-toggle-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.1);--bslib-sidebar-padding: calc(var(--bslib-spacer) * 1.5);--bslib-sidebar-icon-size: var(--bslib-spacer, 1rem);--bslib-sidebar-icon-button-size: calc(var(--bslib-sidebar-icon-size, 1rem) * 2);--bslib-sidebar-padding-icon: calc(var(--bslib-sidebar-icon-button-size, 2rem) * 1.5);--bslib-collapse-toggle-border-radius: var(--bs-border-radius, 3px);--bslib-collapse-toggle-transform: 0deg;--bslib-sidebar-toggle-transition-easing: cubic-bezier(1, 0, 0, 1);--bslib-collapse-toggle-right-transform: 180deg;--bslib-sidebar-column-main: minmax(0, 1fr);display:grid !important;grid-template-columns:Min(calc(100% - var(--bslib-sidebar-icon-size)), var(--bslib-sidebar-width, 250px)) var(--bslib-sidebar-column-main);position:relative;transition:grid-template-columns ease-in-out var(--bslib-sidebar-transition-duration);border:var(--bslib-sidebar-border);border-radius:var(--bslib-sidebar-border-radius)}@media (prefers-reduced-motion: reduce){.bslib-sidebar-layout{transition:none}}.bslib-sidebar-layout[data-bslib-sidebar-border="false"]{border:none}.bslib-sidebar-layout[data-bslib-sidebar-border-radius="false"]{border-radius:initial}.bslib-sidebar-layout>.main,.bslib-sidebar-layout>.sidebar{grid-row:1 / 2;border-radius:inherit;overflow:auto}.bslib-sidebar-layout>.main{grid-column:2 / 3;border-top-left-radius:0;border-bottom-left-radius:0;padding:var(--bslib-sidebar-padding);transition:padding var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration);color:var(--bslib-sidebar-main-fg);background-color:var(--bslib-sidebar-main-bg)}.bslib-sidebar-layout>.sidebar{grid-column:1 / 2;width:100%;height:100%;border-right:var(--bslib-sidebar-vert-border);border-top-right-radius:0;border-bottom-right-radius:0;color:var(--bslib-sidebar-fg);background-color:var(--bslib-sidebar-bg);backdrop-filter:blur(5px)}.bslib-sidebar-layout>.sidebar>.sidebar-content{display:flex;flex-direction:column;gap:var(--bslib-spacer, 1rem);padding:var(--bslib-sidebar-padding);padding-top:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout>.sidebar>.sidebar-content>:last-child:not(.sidebar-title){margin-bottom:0}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion{margin-left:calc(-1 * var(--bslib-sidebar-padding));margin-right:calc(-1 * var(--bslib-sidebar-padding))}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:last-child{margin-bottom:calc(-1 * var(--bslib-sidebar-padding))}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:last-child){margin-bottom:1rem}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion .accordion-body{display:flex;flex-direction:column}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:first-child) .accordion-item:first-child{border-top:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:last-child) .accordion-item:last-child{border-bottom:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.bslib-sidebar-layout>.sidebar>.sidebar-content.has-accordion>.sidebar-title{border-bottom:none;padding-bottom:0}.bslib-sidebar-layout>.sidebar .shiny-input-container{width:100%}.bslib-sidebar-layout[data-bslib-sidebar-open="always"]>.sidebar>.sidebar-content{padding-top:var(--bslib-sidebar-padding)}.bslib-sidebar-layout>.collapse-toggle{grid-row:1 / 2;grid-column:1 / 2;display:inline-flex;align-items:center;position:absolute;right:calc(var(--bslib-sidebar-icon-size));top:calc(var(--bslib-sidebar-icon-size, 1rem) / 2);border:none;border-radius:var(--bslib-collapse-toggle-border-radius);height:var(--bslib-sidebar-icon-button-size, 2rem);width:var(--bslib-sidebar-icon-button-size, 2rem);display:flex;align-items:center;justify-content:center;padding:0;color:var(--bslib-sidebar-fg);background-color:unset;transition:color var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),top var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),right var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),left var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout>.collapse-toggle:hover{background-color:var(--bslib-sidebar-toggle-bg)}.bslib-sidebar-layout>.collapse-toggle>.collapse-icon{opacity:0.8;width:var(--bslib-sidebar-icon-size);height:var(--bslib-sidebar-icon-size);transform:rotateY(var(--bslib-collapse-toggle-transform));transition:transform var(--bslib-sidebar-toggle-transition-easing) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout>.collapse-toggle:hover>.collapse-icon{opacity:1}.bslib-sidebar-layout .sidebar-title{font-size:1.25rem;line-height:1.25;margin-top:0;margin-bottom:1rem;padding-bottom:1rem;border-bottom:var(--bslib-sidebar-border)}.bslib-sidebar-layout.sidebar-right{grid-template-columns:var(--bslib-sidebar-column-main) Min(calc(100% - var(--bslib-sidebar-icon-size)), var(--bslib-sidebar-width, 250px))}.bslib-sidebar-layout.sidebar-right>.main{grid-column:1 / 2;border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:inherit;border-bottom-left-radius:inherit}.bslib-sidebar-layout.sidebar-right>.sidebar{grid-column:2 / 3;border-right:none;border-left:var(--bslib-sidebar-vert-border);border-top-left-radius:0;border-bottom-left-radius:0}.bslib-sidebar-layout.sidebar-right>.collapse-toggle{grid-column:2 / 3;left:var(--bslib-sidebar-icon-size);right:unset;border:var(--bslib-collapse-toggle-border)}.bslib-sidebar-layout.sidebar-right>.collapse-toggle>.collapse-icon{transform:rotateY(var(--bslib-collapse-toggle-right-transform))}.bslib-sidebar-layout.sidebar-collapsed{--bslib-collapse-toggle-transform: 180deg;--bslib-collapse-toggle-right-transform: 0deg;--bslib-sidebar-vert-border: none;grid-template-columns:0 minmax(0, 1fr)}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right{grid-template-columns:minmax(0, 1fr) 0}.bslib-sidebar-layout.sidebar-collapsed:not(.transitioning)>.sidebar>*{display:none}.bslib-sidebar-layout.sidebar-collapsed>.main{border-radius:inherit}.bslib-sidebar-layout.sidebar-collapsed:not(.sidebar-right)>.main{padding-left:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right>.main{padding-right:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout.sidebar-collapsed>.collapse-toggle{color:var(--bslib-sidebar-main-fg);top:calc( var(--bslib-sidebar-overlap-counter, 0) * calc(var(--bslib-sidebar-icon-size) + var(--bslib-sidebar-padding) ) + var(--bslib-sidebar-icon-size, 1rem) / 2);right:calc(-2.5 * var(--bslib-sidebar-icon-size) - var(--bs-card-border-width, 1px))}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right>.collapse-toggle{left:calc(-2.5 * var(--bslib-sidebar-icon-size) - var(--bs-card-border-width, 1px));right:unset}@media (min-width: 576px){.bslib-sidebar-layout.transitioning>.sidebar>.sidebar-content{display:none}}@media (max-width: 575.98px){.bslib-sidebar-layout[data-bslib-sidebar-open="desktop"]{--bslib-sidebar-js-init-collapsed: true}.bslib-sidebar-layout>.sidebar,.bslib-sidebar-layout.sidebar-right>.sidebar{border:none}.bslib-sidebar-layout>.main,.bslib-sidebar-layout.sidebar-right>.main{grid-column:1 / 3}.bslib-sidebar-layout[data-bslib-sidebar-open="always"]{display:block !important}.bslib-sidebar-layout[data-bslib-sidebar-open="always"]>.sidebar{max-height:var(--bslib-sidebar-max-height-mobile);overflow-y:auto;border-top:var(--bslib-sidebar-vert-border)}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]){grid-template-columns:100% 0}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]):not(.sidebar-collapsed)>.sidebar{z-index:1}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]):not(.sidebar-collapsed)>.collapse-toggle{z-index:1}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]).sidebar-right{grid-template-columns:0 100%}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]).sidebar-collapsed{grid-template-columns:0 100%}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]).sidebar-collapsed.sidebar-right{grid-template-columns:100% 0}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]):not(.sidebar-right)>.main{padding-left:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]).sidebar-right>.main{padding-right:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"])>.main{opacity:0;transition:opacity var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout:not([data-bslib-sidebar-open="always"]).sidebar-collapsed>.main{opacity:1}}:root{--bslib-value-box-shadow: 0px 1px 2px rgba(29,31,33,0.1),0px 3px 7px rgba(29,31,33,0.1),0px 12px 30px rgba(29,31,33,0.08);--bslib-value-box-border-width-auto-yes: 0;--bslib-value-box-border-width-auto-no: 0;--bslib-value-box-border-width-baseline: var(--bs-border-width)}.bslib-value-box{border-width:var(--bslib-value-box-border-width-auto-no, var(--bslib-value-box-border-width-baseline));container-name:bslib-value-box;container-type:inline-size}.bslib-value-box.card{box-shadow:var(--bslib-value-box-shadow)}.bslib-value-box.border-auto{border-width:var(--bslib-value-box-border-width-auto-yes, var(--bslib-value-box-border-width-baseline))}.bslib-value-box.default{--bslib-value-box-bg-default: var(--bs-card-bg, #fff);--bslib-value-box-border-color-default: var(--bs-card-border-color, var(--bs-border-color-translucent));color:var(--bslib-value-box-color);background-color:var(--bslib-value-box-bg, var(--bslib-value-box-bg-default));border-color:var(--bslib-value-box-border-color, var(--bslib-value-box-border-color-default))}.bslib-value-box .value-box-grid{display:grid;grid-template-areas:"left right";align-items:center;overflow:hidden}.bslib-value-box .value-box-showcase{height:100%;max-height:var(---bslib-value-box-showcase-max-h, 100%)}.bslib-value-box .value-box-showcase,.bslib-value-box .value-box-showcase>.html-fill-item{width:100%}.bslib-value-box[data-full-screen="true"] .value-box-showcase{max-height:var(---bslib-value-box-showcase-max-h-fs, 100%)}@media screen and (min-width: 575.98px){@container bslib-value-box (max-width: 300px){.bslib-value-box:not(.showcase-bottom) .value-box-grid{grid-template-columns:1fr !important;grid-template-rows:auto auto;grid-template-areas:"top" "bottom"}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-showcase{grid-area:top !important}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-area{grid-area:bottom !important;justify-content:end}}}.bslib-value-box .value-box-area{justify-content:center;padding:1.5rem 1rem;font-size:.9rem;font-weight:500}.bslib-value-box .value-box-area *{margin-bottom:0;margin-top:0}.bslib-value-box .value-box-title{font-size:1rem;margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2}.bslib-value-box .value-box-title:empty::after{content:'\00a0 '}.bslib-value-box .value-box-value{font-size:calc(1.325rem + .9vw);margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2}@media (min-width: 1200px){.bslib-value-box .value-box-value{font-size:2rem}}.bslib-value-box .value-box-value:empty::after{content:'\00a0 '}.bslib-value-box .value-box-showcase{align-items:center;justify-content:center;margin-top:auto;margin-bottom:auto;padding:1rem}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{opacity:.85;min-width:50px;max-width:125%}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{font-size:4rem}.bslib-value-box.showcase-top-right .value-box-grid{grid-template-columns:1fr var(---bslib-value-box-showcase-w, 50%)}.bslib-value-box.showcase-top-right .value-box-grid .value-box-showcase{grid-area:right;margin-left:auto;align-self:start;align-items:end;padding-left:0;padding-bottom:0}.bslib-value-box.showcase-top-right .value-box-grid .value-box-area{grid-area:left;align-self:end}.bslib-value-box.showcase-top-right[data-full-screen="true"] .value-box-grid{grid-template-columns:auto var(---bslib-value-box-showcase-w-fs, 1fr)}.bslib-value-box.showcase-top-right[data-full-screen="true"] .value-box-grid>div{align-self:center}.bslib-value-box.showcase-top-right:not([data-full-screen="true"]) .value-box-showcase{margin-top:0}@container bslib-value-box (max-width: 300px){.bslib-value-box.showcase-top-right:not([data-full-screen="true"]) .value-box-grid .value-box-showcase{padding-left:1rem}}.bslib-value-box.showcase-left-center .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w, 30%) auto}.bslib-value-box.showcase-left-center[data-full-screen="true"] .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w-fs, 1fr) auto}.bslib-value-box.showcase-left-center:not([data-fill-screen="true"]) .value-box-grid .value-box-showcase{grid-area:left}.bslib-value-box.showcase-left-center:not([data-fill-screen="true"]) .value-box-grid .value-box-area{grid-area:right}.bslib-value-box.showcase-bottom .value-box-grid{grid-template-columns:1fr;grid-template-rows:1fr var(---bslib-value-box-showcase-h, auto);grid-template-areas:"top" "bottom";overflow:hidden}.bslib-value-box.showcase-bottom .value-box-grid .value-box-showcase{grid-area:bottom;padding:0;margin:0}.bslib-value-box.showcase-bottom .value-box-grid .value-box-area{grid-area:top}.bslib-value-box.showcase-bottom[data-full-screen="true"] .value-box-grid{grid-template-rows:1fr var(---bslib-value-box-showcase-h-fs, 2fr)}.bslib-value-box.showcase-bottom[data-full-screen="true"] .value-box-grid .value-box-showcase{padding:1rem}[data-bs-theme="dark"] .bslib-value-box{--bslib-value-box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 50%)} diff --git a/inst/components/dist/components.js b/inst/components/dist/components.js new file mode 100644 index 000000000..c1ab3c716 --- /dev/null +++ b/inst/components/dist/components.js @@ -0,0 +1,929 @@ +/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ +"use strict"; +(() => { + // srcts/src/components/_utils.ts + var InputBinding = window.Shiny ? Shiny.InputBinding : class { + }; + function registerBinding(inputBindingClass, name) { + if (window.Shiny) { + Shiny.inputBindings.register(new inputBindingClass(), "bslib." + name); + } + } + function hasDefinedProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== void 0; + } + function getAllFocusableChildren(el) { + const base = [ + "a[href]", + "area[href]", + "button", + "details summary", + "input", + "iframe", + "select", + "textarea", + '[contentEditable=""]', + '[contentEditable="true"]', + '[contentEditable="TRUE"]', + "[tabindex]" + ]; + const modifiers = [':not([tabindex="-1"])', ":not([disabled])"]; + const selectors = base.map((b) => b + modifiers.join("")); + const focusable = el.querySelectorAll(selectors.join(", ")); + return Array.from(focusable); + } + + // srcts/src/components/accordion.ts + var AccordionInputBinding = class extends InputBinding { + find(scope) { + return $(scope).find(".accordion.bslib-accordion-input"); + } + getValue(el) { + const items = this._getItemInfo(el); + const selected = items.filter((x) => x.isOpen()).map((x) => x.value); + return selected.length === 0 ? null : selected; + } + subscribe(el, callback) { + $(el).on( + "shown.bs.collapse.accordionInputBinding hidden.bs.collapse.accordionInputBinding", + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function(event) { + callback(true); + } + ); + } + unsubscribe(el) { + $(el).off(".accordionInputBinding"); + } + receiveMessage(el, data) { + const method = data.method; + if (method === "set") { + this._setItems(el, data); + } else if (method === "open") { + this._openItems(el, data); + } else if (method === "close") { + this._closeItems(el, data); + } else if (method === "remove") { + this._removeItem(el, data); + } else if (method === "insert") { + this._insertItem(el, data); + } else if (method === "update") { + this._updateItem(el, data); + } else { + throw new Error(`Method not yet implemented: ${method}`); + } + } + _setItems(el, data) { + const items = this._getItemInfo(el); + const vals = this._getValues(el, items, data.values); + items.forEach((x) => { + vals.indexOf(x.value) > -1 ? x.show() : x.hide(); + }); + } + _openItems(el, data) { + const items = this._getItemInfo(el); + const vals = this._getValues(el, items, data.values); + items.forEach((x) => { + if (vals.indexOf(x.value) > -1) + x.show(); + }); + } + _closeItems(el, data) { + const items = this._getItemInfo(el); + const vals = this._getValues(el, items, data.values); + items.forEach((x) => { + if (vals.indexOf(x.value) > -1) + x.hide(); + }); + } + _insertItem(el, data) { + let targetItem = this._findItem(el, data.target); + if (!targetItem) { + targetItem = data.position === "before" ? el.firstElementChild : el.lastElementChild; + } + const panel = data.panel; + if (targetItem) { + Shiny.renderContent( + targetItem, + panel, + data.position === "before" ? "beforeBegin" : "afterEnd" + ); + } else { + Shiny.renderContent(el, panel); + } + if (this._isAutoClosing(el)) { + const val = $(panel.html).attr("data-value"); + $(el).find(`[data-value="${val}"] .accordion-collapse`).attr("data-bs-parent", "#" + el.id); + } + } + _removeItem(el, data) { + const targetItems = this._getItemInfo(el).filter( + (x) => data.target.indexOf(x.value) > -1 + ); + const unbindAll = Shiny == null ? void 0 : Shiny.unbindAll; + targetItems.forEach((x) => { + if (unbindAll) + unbindAll(x.item); + x.item.remove(); + }); + } + _updateItem(el, data) { + const target = this._findItem(el, data.target); + if (!target) { + throw new Error( + `Unable to find an accordion_panel() with a value of ${data.target}` + ); + } + if (hasDefinedProperty(data, "value")) { + target.dataset.value = data.value; + } + if (hasDefinedProperty(data, "body")) { + const body = target.querySelector(".accordion-body"); + Shiny.renderContent(body, data.body); + } + const header = target.querySelector(".accordion-header"); + if (hasDefinedProperty(data, "title")) { + const title = header.querySelector(".accordion-title"); + Shiny.renderContent(title, data.title); + } + if (hasDefinedProperty(data, "icon")) { + const icon = header.querySelector( + ".accordion-button > .accordion-icon" + ); + Shiny.renderContent(icon, data.icon); + } + } + _getItemInfo(el) { + const items = Array.from( + el.querySelectorAll(":scope > .accordion-item") + ); + return items.map((x) => this._getSingleItemInfo(x)); + } + _getSingleItemInfo(x) { + const collapse = x.querySelector(".accordion-collapse"); + const isOpen = () => $(collapse).hasClass("show"); + return { + item: x, + value: x.dataset.value, + isOpen, + show: () => { + if (!isOpen()) + $(collapse).collapse("show"); + }, + hide: () => { + if (isOpen()) + $(collapse).collapse("hide"); + } + }; + } + _getValues(el, items, values) { + let vals = values !== true ? values : items.map((x) => x.value); + const autoclose = this._isAutoClosing(el); + if (autoclose) { + vals = vals.slice(vals.length - 1, vals.length); + } + return vals; + } + _findItem(el, value) { + return el.querySelector(`[data-value="${value}"]`); + } + _isAutoClosing(el) { + return el.classList.contains("autoclose"); + } + }; + registerBinding(AccordionInputBinding, "accordion"); + + // srcts/src/components/_shinyResizeObserver.ts + var ShinyResizeObserver = class { + /** + * Watch containers for size changes and ensure that Shiny outputs and + * htmlwidgets within resize appropriately. + * + * @details + * The ShinyResizeObserver is used to watch the containers, such as Sidebars + * and Cards for size changes, in particular when the sidebar state is toggled + * or the card body is expanded full screen. It performs two primary tasks: + * + * 1. Dispatches a `resize` event on the window object. This is necessary to + * ensure that Shiny outputs resize appropriately. In general, the window + * resizing is throttled and the output update occurs when the transition + * is complete. + * 2. If an output with a resize method on the output binding is detected, we + * directly call the `.onResize()` method of the binding. This ensures that + * htmlwidgets transition smoothly. In static mode, htmlwidgets does this + * already. + * + * @note + * This resize observer also handles race conditions in some complex + * fill-based layouts with multiple outputs (e.g., plotly), where shiny + * initializes with the correct sizing, but in-between the 1st and last + * renderValue(), the size of the output containers can change, meaning every + * output but the 1st gets initialized with the wrong size during their + * renderValue(). Then, after the render phase, shiny won't know to trigger a + * resize since all the widgets will return to their original size (and thus, + * Shiny thinks there isn't any resizing to do). The resize observer works + * around this by ensuring that the output is resized whenever its container + * size changes. + * @constructor + */ + constructor() { + this.resizeObserverEntries = []; + this.resizeObserver = new ResizeObserver((entries) => { + const resizeEvent = new Event("resize"); + window.dispatchEvent(resizeEvent); + if (!window.Shiny) + return; + const resized = []; + for (const entry of entries) { + if (!(entry.target instanceof HTMLElement)) + continue; + if (!entry.target.querySelector(".shiny-bound-output")) + continue; + entry.target.querySelectorAll(".shiny-bound-output").forEach((el) => { + if (resized.includes(el)) + return; + const { binding, onResize } = $(el).data("shinyOutputBinding"); + if (!binding || !binding.resize) + return; + const owner = el.shinyResizeObserver; + if (owner && owner !== this) + return; + if (!owner) + el.shinyResizeObserver = this; + onResize(el); + resized.push(el); + if (!el.classList.contains("shiny-plot-output")) + return; + const img = el.querySelector( + 'img:not([width="100%"])' + ); + if (img) + img.setAttribute("width", "100%"); + }); + } + }); + } + /** + * Observe an element for size changes. + * @param {HTMLElement} el - The element to observe. + */ + observe(el) { + this.resizeObserver.observe(el); + this.resizeObserverEntries.push(el); + } + /** + * Stop observing an element for size changes. + * @param {HTMLElement} el - The element to stop observing. + */ + unobserve(el) { + const idxEl = this.resizeObserverEntries.indexOf(el); + if (idxEl < 0) + return; + this.resizeObserver.unobserve(el); + this.resizeObserverEntries.splice(idxEl, 1); + } + /** + * This method checks that we're not continuing to watch elements that no + * longer exist in the DOM. If any are found, we stop observing them and + * remove them from our array of observed elements. + * + * @private + * @static + */ + flush() { + this.resizeObserverEntries.forEach((el) => { + if (!document.body.contains(el)) + this.unobserve(el); + }); + } + }; + + // srcts/src/components/card.ts + var _Card = class { + /** + * Creates an instance of a bslib Card component. + * + * @constructor + * @param {HTMLElement} card + */ + constructor(card) { + var _a; + card.removeAttribute(_Card.attr.ATTR_INIT); + (_a = card.querySelector(`script[${_Card.attr.ATTR_INIT}]`)) == null ? void 0 : _a.remove(); + this.card = card; + _Card.instanceMap.set(card, this); + _Card.shinyResizeObserver.observe(this.card); + this._addEventListeners(); + this.overlay = this._createOverlay(); + this._exitFullScreenOnEscape = this._exitFullScreenOnEscape.bind(this); + this._trapFocusExit = this._trapFocusExit.bind(this); + } + /** + * Enter the card's full screen mode, either programmatically or via an event + * handler. Full screen mode is activated by adding a class to the card that + * positions it absolutely and expands it to fill the viewport. In addition, + * we add a full screen overlay element behind the card and we trap focus in + * the expanded card while in full screen mode. + * + * @param {?Event} [event] + */ + enterFullScreen(event) { + var _a; + if (event) + event.preventDefault(); + document.addEventListener("keydown", this._exitFullScreenOnEscape, false); + document.addEventListener("keydown", this._trapFocusExit, true); + this.card.setAttribute(_Card.attr.ATTR_FULL_SCREEN, "true"); + document.body.classList.add(_Card.attr.CLASS_HAS_FULL_SCREEN); + this.card.insertAdjacentElement("beforebegin", this.overlay.container); + if (!this.card.contains(document.activeElement) || ((_a = document.activeElement) == null ? void 0 : _a.classList.contains( + _Card.attr.CLASS_FULL_SCREEN_ENTER + ))) { + this.card.setAttribute("tabindex", "-1"); + this.card.focus(); + } + } + /** + * Exit full screen mode. This removes the full screen overlay element, + * removes the full screen class from the card, and removes the keyboard event + * listeners that were added when entering full screen mode. + */ + exitFullScreen() { + document.removeEventListener( + "keydown", + this._exitFullScreenOnEscape, + false + ); + document.removeEventListener("keydown", this._trapFocusExit, true); + this.overlay.container.remove(); + this.card.setAttribute(_Card.attr.ATTR_FULL_SCREEN, "false"); + this.card.removeAttribute("tabindex"); + document.body.classList.remove(_Card.attr.CLASS_HAS_FULL_SCREEN); + } + /** + * Adds general card-specific event listeners. + * @private + */ + _addEventListeners() { + const btnFullScreen = this.card.querySelector( + `:scope > * > .${_Card.attr.CLASS_FULL_SCREEN_ENTER}` + ); + if (!btnFullScreen) + return; + btnFullScreen.addEventListener("click", (ev) => this.enterFullScreen(ev)); + } + /** + * An event handler to exit full screen mode when the Escape key is pressed. + * @private + * @param {KeyboardEvent} event + */ + _exitFullScreenOnEscape(event) { + if (!(event.target instanceof HTMLElement)) + return; + const selOpenSelectInput = ["select[open]", "input[aria-expanded='true']"]; + if (event.target.matches(selOpenSelectInput.join(", "))) + return; + if (event.key === "Escape") { + this.exitFullScreen(); + } + } + /** + * An event handler to trap focus within the card when in full screen mode. + * + * @description + * This keyboard event handler ensures that tab focus stays within the card + * when in full screen mode. When the card is first expanded, + * we move focus to the card element itself. If focus somehow leaves the card, + * we returns focus to the card container. + * + * Within the card, we handle only tabbing from the close anchor or the last + * focusable element and only when tab focus would have otherwise left the + * card. In those cases, we cycle focus to the last focusable element or back + * to the anchor. If the card doesn't have any focusable elements, we move + * focus to the close anchor. + * + * @note + * Because the card contents may change, we check for focusable elements + * every time the handler is called. + * + * @private + * @param {KeyboardEvent} event + */ + _trapFocusExit(event) { + if (!(event instanceof KeyboardEvent)) + return; + if (event.key !== "Tab") + return; + const isFocusedContainer = event.target === this.card; + const isFocusedAnchor = event.target === this.overlay.anchor; + const isFocusedWithin = this.card.contains(event.target); + const stopEvent = () => { + event.preventDefault(); + event.stopImmediatePropagation(); + }; + if (!(isFocusedWithin || isFocusedContainer || isFocusedAnchor)) { + stopEvent(); + this.card.focus(); + return; + } + const focusableElements = getAllFocusableChildren(this.card).filter( + (el) => !el.classList.contains(_Card.attr.CLASS_FULL_SCREEN_ENTER) + ); + const hasFocusableElements = focusableElements.length > 0; + if (!hasFocusableElements) { + stopEvent(); + this.overlay.anchor.focus(); + return; + } + if (isFocusedContainer) + return; + const lastFocusable = focusableElements[focusableElements.length - 1]; + const isFocusedLast = event.target === lastFocusable; + if (isFocusedAnchor && event.shiftKey) { + stopEvent(); + lastFocusable.focus(); + return; + } + if (isFocusedLast && !event.shiftKey) { + stopEvent(); + this.overlay.anchor.focus(); + return; + } + } + /** + * Creates the full screen overlay. + * @private + * @returns {CardFullScreenOverlay} + */ + _createOverlay() { + const container = document.createElement("div"); + container.id = _Card.attr.ID_FULL_SCREEN_OVERLAY; + container.onclick = this.exitFullScreen.bind(this); + const anchor = this._createOverlayCloseAnchor(); + container.appendChild(anchor); + return { container, anchor }; + } + /** + * Creates the anchor element used to exit the full screen mode. + * @private + * @returns {HTMLAnchorElement} + */ + _createOverlayCloseAnchor() { + const anchor = document.createElement("a"); + anchor.classList.add(_Card.attr.CLASS_FULL_SCREEN_EXIT); + anchor.tabIndex = 0; + anchor.onclick = () => this.exitFullScreen(); + anchor.onkeydown = (ev) => { + if (ev.key === "Enter" || ev.key === " ") { + this.exitFullScreen(); + } + }; + anchor.innerHTML = this._overlayCloseHtml(); + return anchor; + } + /** + * Returns the HTML for the close icon. + * @private + * @returns {string} + */ + _overlayCloseHtml() { + return "Close "; + } + /** + * Returns the card instance associated with the given element, if any. + * @public + * @static + * @param {HTMLElement} el + * @returns {(Card | undefined)} + */ + static getInstance(el) { + return _Card.instanceMap.get(el); + } + /** + * Initializes all cards that require initialization on the page, or schedules + * initialization if the DOM is not yet ready. + * @public + * @static + * @param {boolean} [flushResizeObserver=true] + */ + static initializeAllCards(flushResizeObserver = true) { + if (document.readyState === "loading") { + if (!_Card.onReadyScheduled) { + _Card.onReadyScheduled = true; + document.addEventListener("DOMContentLoaded", () => { + _Card.initializeAllCards(false); + }); + } + return; + } + if (flushResizeObserver) { + _Card.shinyResizeObserver.flush(); + } + const initSelector = `.${_Card.attr.CLASS_CARD}[${_Card.attr.ATTR_INIT}]`; + if (!document.querySelector(initSelector)) { + return; + } + const cards = document.querySelectorAll(initSelector); + cards.forEach((card) => new _Card(card)); + } + }; + var Card = _Card; + /** + * Key bslib-specific classes and attributes used by the card component. + * @private + * @static + * @type {{ ATTR_INIT: string; CLASS_CARD: string; CLASS_FULL_SCREEN: string; CLASS_HAS_FULL_SCREEN: string; CLASS_FULL_SCREEN_ENTER: string; CLASS_FULL_SCREEN_EXIT: string; ID_FULL_SCREEN_OVERLAY: string; }} + */ + Card.attr = { + // eslint-disable-next-line @typescript-eslint/naming-convention + ATTR_INIT: "data-bslib-card-init", + // eslint-disable-next-line @typescript-eslint/naming-convention + CLASS_CARD: "bslib-card", + // eslint-disable-next-line @typescript-eslint/naming-convention + ATTR_FULL_SCREEN: "data-full-screen", + // eslint-disable-next-line @typescript-eslint/naming-convention + CLASS_HAS_FULL_SCREEN: "bslib-has-full-screen", + // eslint-disable-next-line @typescript-eslint/naming-convention + CLASS_FULL_SCREEN_ENTER: "bslib-full-screen-enter", + // eslint-disable-next-line @typescript-eslint/naming-convention + CLASS_FULL_SCREEN_EXIT: "bslib-full-screen-exit", + // eslint-disable-next-line @typescript-eslint/naming-convention + ID_FULL_SCREEN_OVERLAY: "bslib-full-screen-overlay" + }; + /** + * A Shiny-specific resize observer that ensures Shiny outputs in within the + * card resize appropriately. + * @private + * @type {ShinyResizeObserver} + * @static + */ + Card.shinyResizeObserver = new ShinyResizeObserver(); + /** + * The registry of card instances and their associated DOM elements. + * @private + * @static + * @type {WeakMap} + */ + Card.instanceMap = /* @__PURE__ */ new WeakMap(); + /** + * If cards are initialized before the DOM is ready, we re-schedule the + * initialization to occur on DOMContentLoaded. + * @private + * @static + * @type {boolean} + */ + Card.onReadyScheduled = false; + window.bslib = window.bslib || {}; + window.bslib.Card = Card; + + // srcts/src/components/sidebar.ts + var _Sidebar = class { + /** + * Creates an instance of a collapsible bslib Sidebar. + * @constructor + * @param {HTMLElement} container + */ + constructor(container) { + var _a; + _Sidebar.instanceMap.set(container, this); + this.layout = { + container, + main: container.querySelector(":scope > .main"), + sidebar: container.querySelector(":scope > .sidebar"), + toggle: container.querySelector( + ":scope > .collapse-toggle" + ) + }; + const sideAccordion = this.layout.sidebar.querySelector( + ":scope > .sidebar-content > .accordion" + ); + if (sideAccordion) { + (_a = sideAccordion == null ? void 0 : sideAccordion.parentElement) == null ? void 0 : _a.classList.add("has-accordion"); + sideAccordion.classList.add("accordion-flush"); + } + if (this.layout.toggle) { + this._initEventListeners(); + this._initSidebarCounters(); + this._initDesktop(); + } + _Sidebar.shinyResizeObserver.observe(this.layout.main); + container.removeAttribute("data-bslib-sidebar-init"); + const initScript = container.querySelector( + ":scope > script[data-bslib-sidebar-init]" + ); + if (initScript) { + container.removeChild(initScript); + } + } + /** + * Read the current state of the sidebar. Note that, when calling this method, + * the sidebar may be transitioning into the state returned by this method. + * + * @description + * The sidebar state works as follows, starting from the open state. When the + * sidebar is closed: + * 1. We add both the `COLLAPSE` and `TRANSITIONING` classes to the sidebar. + * 2. The sidebar collapse begins to animate. On desktop devices, and where it + * is supported, we transition the `grid-template-columns` property of the + * sidebar layout. On mobile, the sidebar is hidden immediately. In both + * cases, the collapse icon rotates and we use this rotation to determine + * when the transition is complete. + * 3. If another sidebar state toggle is requested while closing the sidebar, + * we remove the `COLLAPSE` class and the animation immediately starts to + * reverse. + * 4. When the `transition` is complete, we remove the `TRANSITIONING` class. + * @readonly + * @type {boolean} + */ + get isClosed() { + return this.layout.container.classList.contains(_Sidebar.classes.COLLAPSE); + } + /** + * Given a sidebar container, return the Sidebar instance associated with it. + * @public + * @static + * @param {HTMLElement} el + * @returns {(Sidebar | undefined)} + */ + static getInstance(el) { + return _Sidebar.instanceMap.get(el); + } + /** + * Initialize all collapsible sidebars on the page. + * @public + * @static + * @param {boolean} [flushResizeObserver=true] When `true`, we remove + * non-existent elements from the ResizeObserver. This is required + * periodically to prevent memory leaks. To avoid over-checking, we only flush + * the ResizeObserver when initializing sidebars after page load. + */ + static initCollapsibleAll(flushResizeObserver = true) { + if (document.readyState === "loading") { + if (!_Sidebar.onReadyScheduled) { + _Sidebar.onReadyScheduled = true; + document.addEventListener("DOMContentLoaded", () => { + _Sidebar.initCollapsibleAll(false); + }); + } + return; + } + const initSelector = `.${_Sidebar.classes.LAYOUT}[data-bslib-sidebar-init]`; + if (!document.querySelector(initSelector)) { + return; + } + if (flushResizeObserver) + _Sidebar.shinyResizeObserver.flush(); + const containers = document.querySelectorAll(initSelector); + containers.forEach((container) => new _Sidebar(container)); + } + /** + * Initialize event listeners for the sidebar toggle button. + * @private + */ + _initEventListeners() { + var _a; + const { toggle } = this.layout; + toggle.addEventListener("click", (ev) => { + ev.preventDefault(); + this.toggle("toggle"); + }); + (_a = toggle.querySelector(".collapse-icon")) == null ? void 0 : _a.addEventListener("transitionend", () => this._finalizeState()); + } + /** + * Initialize nested sidebar counters. + * + * @description + * This function walks up the DOM tree, adding CSS variables to each direct + * parent sidebar layout that count the layout's position in the stack of + * nested layouts. We use these counters to keep the collapse toggles from + * overlapping. Note that always-open sidebars that don't have collapse + * toggles break the chain of nesting. + * @private + */ + _initSidebarCounters() { + const { container } = this.layout; + const selectorChildLayouts = `.${_Sidebar.classes.LAYOUT}> .main > .${_Sidebar.classes.LAYOUT}:not([data-bslib-sidebar-open="always"])`; + const isInnermostLayout = container.querySelector(selectorChildLayouts) === null; + if (!isInnermostLayout) { + return; + } + function nextSidebarParent(el) { + el = el ? el.parentElement : null; + if (el && el.classList.contains("main")) { + el = el.parentElement; + } + if (el && el.classList.contains(_Sidebar.classes.LAYOUT)) { + return el; + } + return null; + } + const layouts = [container]; + let parent = nextSidebarParent(container); + while (parent) { + layouts.unshift(parent); + parent = nextSidebarParent(parent); + } + const count = { left: 0, right: 0 }; + layouts.forEach(function(x, i) { + x.style.setProperty("--bslib-sidebar-counter", i.toString()); + const isRight = x.classList.contains("sidebar-right"); + const thisCount = isRight ? count.right++ : count.left++; + x.style.setProperty( + "--bslib-sidebar-overlap-counter", + thisCount.toString() + ); + }); + } + /** + * Initialize the sidebar's initial state when `open = "desktop"`. + * @private + */ + _initDesktop() { + var _a; + const { container } = this.layout; + if (((_a = container.dataset.bslibSidebarOpen) == null ? void 0 : _a.trim()) !== "desktop") { + return; + } + const initCollapsed = window.getComputedStyle(container).getPropertyValue("--bslib-sidebar-js-init-collapsed"); + if (initCollapsed.trim() === "true") { + this.toggle("close"); + } + } + /** + * Toggle the sidebar's open/closed state. + * @public + * @param {SidebarToggleMethod | undefined} method Whether to `"open"`, + * `"close"` or `"toggle"` the sidebar. If `.toggle()` is called without an + * argument, it will toggle the sidebar's state. + */ + toggle(method) { + if (typeof method === "undefined") { + method = "toggle"; + } + const { container, sidebar } = this.layout; + const isClosed = this.isClosed; + if (["open", "close", "toggle"].indexOf(method) === -1) { + throw new Error(`Unknown method ${method}`); + } + if (method === "toggle") { + method = isClosed ? "open" : "close"; + } + if (isClosed && method === "close" || !isClosed && method === "open") { + return; + } + if (method === "open") { + sidebar.hidden = false; + } + container.classList.add(_Sidebar.classes.TRANSITIONING); + container.classList.toggle(_Sidebar.classes.COLLAPSE); + } + /** + * When the sidebar open/close transition ends, finalize the sidebar's state. + * @private + */ + _finalizeState() { + const { container, sidebar, toggle } = this.layout; + container.classList.remove(_Sidebar.classes.TRANSITIONING); + sidebar.hidden = this.isClosed; + toggle.setAttribute("aria-expanded", this.isClosed ? "false" : "true"); + const event = new CustomEvent("bslib.sidebar", { + bubbles: true, + detail: { open: !this.isClosed } + }); + sidebar.dispatchEvent(event); + $(sidebar).trigger("toggleCollapse.sidebarInputBinding"); + $(sidebar).trigger(this.isClosed ? "hidden" : "shown"); + } + }; + var Sidebar = _Sidebar; + /** + * A Shiny-specific resize observer that ensures Shiny outputs in the main + * content areas of the sidebar resize appropriately. + * @private + * @type {ShinyResizeObserver} + * @static + */ + Sidebar.shinyResizeObserver = new ShinyResizeObserver(); + /** + * Static classes related to the sidebar layout or state. + * @public + * @static + * @readonly + * @type {{ LAYOUT: string; COLLAPSE: string; TRANSITIONING: string; }} + */ + Sidebar.classes = { + // eslint-disable-next-line @typescript-eslint/naming-convention + LAYOUT: "bslib-sidebar-layout", + // eslint-disable-next-line @typescript-eslint/naming-convention + COLLAPSE: "sidebar-collapsed", + // eslint-disable-next-line @typescript-eslint/naming-convention + TRANSITIONING: "transitioning" + }; + /** + * If sidebars are initialized before the DOM is ready, we re-schedule the + * initialization to occur on DOMContentLoaded. + * @private + * @static + * @type {boolean} + */ + Sidebar.onReadyScheduled = false; + /** + * A map of initialized sidebars to their respective Sidebar instances. + * @private + * @static + * @type {WeakMap} + */ + Sidebar.instanceMap = /* @__PURE__ */ new WeakMap(); + var SidebarInputBinding = class extends InputBinding { + find(scope) { + return $(scope).find(`.${Sidebar.classes.LAYOUT} > .bslib-sidebar-input`); + } + getValue(el) { + const sb = Sidebar.getInstance(el.parentElement); + if (!sb) + return false; + return !sb.isClosed; + } + setValue(el, value) { + const method = value ? "open" : "close"; + this.receiveMessage(el, { method }); + } + subscribe(el, callback) { + $(el).on( + "toggleCollapse.sidebarInputBinding", + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function(event) { + callback(true); + } + ); + } + unsubscribe(el) { + $(el).off(".sidebarInputBinding"); + } + receiveMessage(el, data) { + const sb = Sidebar.getInstance(el.parentElement); + if (sb) + sb.toggle(data.method); + } + }; + registerBinding(SidebarInputBinding, "sidebar"); + window.bslib = window.bslib || {}; + window.bslib.Sidebar = Sidebar; + + // srcts/src/components/_shinyAddCustomMessageHandlers.ts + function shinyAddCustomMessageHandlers(handlers) { + if (!window.Shiny) { + return; + } + for (const [name, handler] of Object.entries(handlers)) { + Shiny.addCustomMessageHandler(name, handler); + } + } + + // srcts/src/components/index.ts + var bslibMessageHandlers = { + // eslint-disable-next-line @typescript-eslint/naming-convention + "bslib.toggle-input-binary": (msg) => { + const el = document.getElementById(msg.id); + if (!el) { + console.warn("[bslib.toggle-input-binary] No element found", msg); + } + const binding = $(el).data("shiny-input-binding"); + if (!(binding instanceof InputBinding)) { + console.warn("[bslib.toggle-input-binary] No input binding found", msg); + return; + } + let value = msg.value; + if (typeof value === "undefined") { + value = !binding.getValue(el); + } + binding.receiveMessage(el, { value }); + } + }; + if (window.Shiny) { + shinyAddCustomMessageHandlers(bslibMessageHandlers); + } + function insertSvgGradient() { + const temp = document.createElement("div"); + temp.innerHTML = ` + `; + document.body.appendChild(temp.children[0]); + } + if (document.readyState === "complete") { + insertSvgGradient(); + } else { + document.addEventListener("DOMContentLoaded", insertSvgGradient); + } +})(); +//# sourceMappingURL=components.js.map diff --git a/inst/components/dist/components.js.map b/inst/components/dist/components.js.map new file mode 100644 index 000000000..68625a4bb --- /dev/null +++ b/inst/components/dist/components.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../../srcts/src/components/_utils.ts", "../../../srcts/src/components/accordion.ts", "../../../srcts/src/components/_shinyResizeObserver.ts", "../../../srcts/src/components/card.ts", "../../../srcts/src/components/sidebar.ts", "../../../srcts/src/components/_shinyAddCustomMessageHandlers.ts", "../../../srcts/src/components/index.ts"], + "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "import type { HtmlDep } from \"./_utils\";\nimport { InputBinding, registerBinding, hasDefinedProperty } from \"./_utils\";\n\ntype AccordionItem = {\n item: HTMLElement;\n value: string;\n isOpen: () => boolean;\n show: () => void;\n hide: () => void;\n};\n\ntype HTMLContent = {\n html: string;\n deps?: HtmlDep[];\n};\n\ntype SetMessage = {\n method: \"set\";\n values: string[];\n};\n\ntype OpenMessage = {\n method: \"open\";\n values: string[] | true;\n};\n\ntype CloseMessage = {\n method: \"close\";\n values: string[] | true;\n};\n\ntype InsertMessage = {\n method: \"insert\";\n panel: HTMLContent;\n target: string;\n position: \"after\" | \"before\";\n};\n\ntype RemoveMessage = {\n method: \"remove\";\n target: string[];\n};\n\ntype UpdateMessage = {\n method: \"update\";\n target: string;\n value: string;\n body: HTMLContent;\n title: HTMLContent;\n icon: HTMLContent;\n};\n\ntype MessageData =\n | CloseMessage\n | InsertMessage\n | OpenMessage\n | RemoveMessage\n | SetMessage\n | UpdateMessage;\n\nclass AccordionInputBinding extends InputBinding {\n find(scope: HTMLElement) {\n return $(scope).find(\".accordion.bslib-accordion-input\");\n }\n\n getValue(el: HTMLElement): string[] | null {\n const items = this._getItemInfo(el);\n const selected = items.filter((x) => x.isOpen()).map((x) => x.value);\n return selected.length === 0 ? null : selected;\n }\n\n subscribe(el: HTMLElement, callback: (x: boolean) => void) {\n $(el).on(\n \"shown.bs.collapse.accordionInputBinding hidden.bs.collapse.accordionInputBinding\",\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function (event) {\n callback(true);\n }\n );\n }\n\n unsubscribe(el: HTMLElement) {\n $(el).off(\".accordionInputBinding\");\n }\n\n receiveMessage(el: HTMLElement, data: MessageData) {\n const method = data.method;\n if (method === \"set\") {\n this._setItems(el, data);\n } else if (method === \"open\") {\n this._openItems(el, data);\n } else if (method === \"close\") {\n this._closeItems(el, data);\n } else if (method === \"remove\") {\n this._removeItem(el, data);\n } else if (method === \"insert\") {\n this._insertItem(el, data);\n } else if (method === \"update\") {\n this._updateItem(el, data);\n } else {\n throw new Error(`Method not yet implemented: ${method}`);\n }\n }\n\n protected _setItems(el: HTMLElement, data: SetMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n vals.indexOf(x.value) > -1 ? x.show() : x.hide();\n });\n }\n\n protected _openItems(el: HTMLElement, data: OpenMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n if (vals.indexOf(x.value) > -1) x.show();\n });\n }\n\n protected _closeItems(el: HTMLElement, data: CloseMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n if (vals.indexOf(x.value) > -1) x.hide();\n });\n }\n\n protected _insertItem(el: HTMLElement, data: InsertMessage) {\n let targetItem = this._findItem(el, data.target);\n\n // If no target was specified, or the target was not found, then default\n // to the first or last item, depending on the position\n if (!targetItem) {\n targetItem = (\n data.position === \"before\" ? el.firstElementChild : el.lastElementChild\n ) as HTMLElement;\n }\n\n const panel = data.panel;\n\n // If there is still no targetItem, then there are no items in the accordion\n if (targetItem) {\n Shiny.renderContent(\n targetItem,\n panel,\n data.position === \"before\" ? \"beforeBegin\" : \"afterEnd\"\n );\n } else {\n Shiny.renderContent(el, panel);\n }\n\n // Need to add a reference to the parent id that makes autoclose to work\n if (this._isAutoClosing(el)) {\n const val = $(panel.html).attr(\"data-value\");\n $(el)\n .find(`[data-value=\"${val}\"] .accordion-collapse`)\n .attr(\"data-bs-parent\", \"#\" + el.id);\n }\n }\n\n protected _removeItem(el: HTMLElement, data: RemoveMessage) {\n const targetItems = this._getItemInfo(el).filter(\n (x) => data.target.indexOf(x.value) > -1\n );\n\n const unbindAll = Shiny?.unbindAll;\n\n targetItems.forEach((x) => {\n if (unbindAll) unbindAll(x.item);\n x.item.remove();\n });\n }\n\n protected _updateItem(el: HTMLElement, data: UpdateMessage) {\n const target = this._findItem(el, data.target);\n\n if (!target) {\n throw new Error(\n `Unable to find an accordion_panel() with a value of ${data.target}`\n );\n }\n\n if (hasDefinedProperty(data, \"value\")) {\n target.dataset.value = data.value;\n }\n\n if (hasDefinedProperty(data, \"body\")) {\n const body = target.querySelector(\".accordion-body\") as HTMLElement; // always exists\n Shiny.renderContent(body, data.body);\n }\n\n const header = target.querySelector(\".accordion-header\") as HTMLElement; // always exists\n\n if (hasDefinedProperty(data, \"title\")) {\n const title = header.querySelector(\".accordion-title\") as HTMLElement; // always exists\n Shiny.renderContent(title, data.title);\n }\n\n if (hasDefinedProperty(data, \"icon\")) {\n const icon = header.querySelector(\n \".accordion-button > .accordion-icon\"\n ) as HTMLElement; // always exists\n Shiny.renderContent(icon, data.icon);\n }\n }\n\n protected _getItemInfo(el: HTMLElement): AccordionItem[] {\n const items = Array.from(\n el.querySelectorAll(\":scope > .accordion-item\")\n ) as HTMLElement[];\n return items.map((x) => this._getSingleItemInfo(x));\n }\n\n protected _getSingleItemInfo(x: HTMLElement): AccordionItem {\n const collapse = x.querySelector(\".accordion-collapse\") as HTMLElement;\n const isOpen = () => $(collapse).hasClass(\"show\");\n return {\n item: x,\n value: x.dataset.value as string,\n isOpen: isOpen,\n show: () => {\n if (!isOpen()) $(collapse).collapse(\"show\");\n },\n hide: () => {\n if (isOpen()) $(collapse).collapse(\"hide\");\n },\n };\n }\n\n protected _getValues(\n el: HTMLElement,\n items: AccordionItem[],\n values: string[] | true\n ): string[] {\n let vals = values !== true ? values : items.map((x) => x.value);\n const autoclose = this._isAutoClosing(el);\n if (autoclose) {\n vals = vals.slice(vals.length - 1, vals.length);\n }\n return vals;\n }\n\n protected _findItem(el: HTMLElement, value: string): HTMLElement | null {\n return el.querySelector(`[data-value=\"${value}\"]`);\n }\n\n protected _isAutoClosing(el: HTMLElement): boolean {\n return el.classList.contains(\"autoclose\");\n }\n}\n\nregisterBinding(AccordionInputBinding, \"accordion\");\n", "/**\n * A resize observer that ensures Shiny outputs resize during or just after\n * their parent container size changes. Useful, in particular, for sidebar\n * transitions or for full-screen card transitions.\n *\n * @class ShinyResizeObserver\n * @typedef {ShinyResizeObserver}\n */\nclass ShinyResizeObserver {\n /**\n * The actual ResizeObserver instance.\n * @private\n * @type {ResizeObserver}\n */\n private resizeObserver: ResizeObserver;\n /**\n * An array of elements that are currently being watched by the Resize\n * Observer.\n *\n * @details\n * We don't currently have lifecycle hooks that allow us to unobserve elements\n * when they are removed from the DOM. As a result, we need to manually check\n * that the elements we're watching still exist in the DOM. This array keeps\n * track of the elements we're watching so that we can check them later.\n * @private\n * @type {HTMLElement[]}\n */\n private resizeObserverEntries: HTMLElement[];\n\n /**\n * Watch containers for size changes and ensure that Shiny outputs and\n * htmlwidgets within resize appropriately.\n *\n * @details\n * The ShinyResizeObserver is used to watch the containers, such as Sidebars\n * and Cards for size changes, in particular when the sidebar state is toggled\n * or the card body is expanded full screen. It performs two primary tasks:\n *\n * 1. Dispatches a `resize` event on the window object. This is necessary to\n * ensure that Shiny outputs resize appropriately. In general, the window\n * resizing is throttled and the output update occurs when the transition\n * is complete.\n * 2. If an output with a resize method on the output binding is detected, we\n * directly call the `.onResize()` method of the binding. This ensures that\n * htmlwidgets transition smoothly. In static mode, htmlwidgets does this\n * already.\n *\n * @note\n * This resize observer also handles race conditions in some complex\n * fill-based layouts with multiple outputs (e.g., plotly), where shiny\n * initializes with the correct sizing, but in-between the 1st and last\n * renderValue(), the size of the output containers can change, meaning every\n * output but the 1st gets initialized with the wrong size during their\n * renderValue(). Then, after the render phase, shiny won't know to trigger a\n * resize since all the widgets will return to their original size (and thus,\n * Shiny thinks there isn't any resizing to do). The resize observer works\n * around this by ensuring that the output is resized whenever its container\n * size changes.\n * @constructor\n */\n constructor() {\n this.resizeObserverEntries = [];\n this.resizeObserver = new ResizeObserver((entries) => {\n const resizeEvent = new Event(\"resize\");\n window.dispatchEvent(resizeEvent);\n\n // the rest of this callback is only relevant in Shiny apps\n if (!window.Shiny) return;\n\n const resized = [] as HTMLElement[];\n\n for (const entry of entries) {\n if (!(entry.target instanceof HTMLElement)) continue;\n if (!entry.target.querySelector(\".shiny-bound-output\")) continue;\n\n entry.target\n .querySelectorAll(\".shiny-bound-output\")\n .forEach((el) => {\n if (resized.includes(el)) return;\n\n const { binding, onResize } = $(el).data(\"shinyOutputBinding\");\n if (!binding || !binding.resize) return;\n\n // if this output is owned by another observer, skip it\n const owner = (el as any).shinyResizeObserver;\n if (owner && owner !== this) return;\n // mark this output as owned by this shinyResizeObserver instance\n if (!owner) (el as any).shinyResizeObserver = this;\n\n // trigger immediate resizing of outputs with a resize method\n onResize(el);\n // only once per output and resize event\n resized.push(el);\n\n // set plot images to 100% width temporarily during the transition\n if (!el.classList.contains(\"shiny-plot-output\")) return;\n const img = el.querySelector(\n 'img:not([width=\"100%\"])'\n );\n if (img) img.setAttribute(\"width\", \"100%\");\n });\n }\n });\n }\n\n /**\n * Observe an element for size changes.\n * @param {HTMLElement} el - The element to observe.\n */\n observe(el: HTMLElement): void {\n this.resizeObserver.observe(el);\n this.resizeObserverEntries.push(el);\n }\n\n /**\n * Stop observing an element for size changes.\n * @param {HTMLElement} el - The element to stop observing.\n */\n unobserve(el: HTMLElement): void {\n const idxEl = this.resizeObserverEntries.indexOf(el);\n if (idxEl < 0) return;\n\n this.resizeObserver.unobserve(el);\n this.resizeObserverEntries.splice(idxEl, 1);\n }\n\n /**\n * This method checks that we're not continuing to watch elements that no\n * longer exist in the DOM. If any are found, we stop observing them and\n * remove them from our array of observed elements.\n *\n * @private\n * @static\n */\n flush(): void {\n this.resizeObserverEntries.forEach((el) => {\n if (!document.body.contains(el)) this.unobserve(el);\n });\n }\n}\n\nexport { ShinyResizeObserver };\n", "import { getAllFocusableChildren } from \"./_utils\";\nimport { ShinyResizeObserver } from \"./_shinyResizeObserver\";\n\n/**\n * The overlay element that is placed behind the card when expanded full screen.\n *\n * @interface CardFullScreenOverlay\n * @typedef {CardFullScreenOverlay}\n */\ninterface CardFullScreenOverlay {\n /**\n * The full screen overlay container.\n * @type {HTMLDivElement}\n */\n container: HTMLDivElement;\n /**\n * The anchor element used to close the full screen overlay.\n * @type {HTMLAnchorElement}\n */\n anchor: HTMLAnchorElement;\n}\n\n/**\n * The bslib card component class.\n *\n * @class Card\n * @typedef {Card}\n */\nclass Card {\n /**\n * The card container element.\n * @private\n * @type {HTMLElement}\n */\n private card: HTMLElement;\n /**\n * The card's full screen overlay element. We create this element once and add\n * and remove it from the DOM as needed (this simplifies focus management\n * while in full screen mode).\n * @private\n * @type {CardFullScreenOverlay}\n */\n private overlay: CardFullScreenOverlay;\n\n /**\n * Key bslib-specific classes and attributes used by the card component.\n * @private\n * @static\n * @type {{ ATTR_INIT: string; CLASS_CARD: string; CLASS_FULL_SCREEN: string; CLASS_HAS_FULL_SCREEN: string; CLASS_FULL_SCREEN_ENTER: string; CLASS_FULL_SCREEN_EXIT: string; ID_FULL_SCREEN_OVERLAY: string; }}\n */\n private static attr = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ATTR_INIT: \"data-bslib-card-init\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_CARD: \"bslib-card\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ATTR_FULL_SCREEN: \"data-full-screen\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_HAS_FULL_SCREEN: \"bslib-has-full-screen\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_FULL_SCREEN_ENTER: \"bslib-full-screen-enter\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_FULL_SCREEN_EXIT: \"bslib-full-screen-exit\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ID_FULL_SCREEN_OVERLAY: \"bslib-full-screen-overlay\",\n };\n\n /**\n * A Shiny-specific resize observer that ensures Shiny outputs in within the\n * card resize appropriately.\n * @private\n * @type {ShinyResizeObserver}\n * @static\n */\n private static shinyResizeObserver = new ShinyResizeObserver();\n\n /**\n * Creates an instance of a bslib Card component.\n *\n * @constructor\n * @param {HTMLElement} card\n */\n constructor(card: HTMLElement) {\n // remove initialization attribute and script\n card.removeAttribute(Card.attr.ATTR_INIT);\n card\n .querySelector(`script[${Card.attr.ATTR_INIT}]`)\n ?.remove();\n\n this.card = card;\n Card.instanceMap.set(card, this);\n\n // Let Shiny know to trigger resize when the card size changes\n // TODO: shiny could/should do this itself (rstudio/shiny#3682)\n Card.shinyResizeObserver.observe(this.card);\n\n this._addEventListeners();\n this.overlay = this._createOverlay();\n\n // bind event handler methods to this card instance\n this._exitFullScreenOnEscape = this._exitFullScreenOnEscape.bind(this);\n this._trapFocusExit = this._trapFocusExit.bind(this);\n }\n\n /**\n * Enter the card's full screen mode, either programmatically or via an event\n * handler. Full screen mode is activated by adding a class to the card that\n * positions it absolutely and expands it to fill the viewport. In addition,\n * we add a full screen overlay element behind the card and we trap focus in\n * the expanded card while in full screen mode.\n *\n * @param {?Event} [event]\n */\n enterFullScreen(event?: Event): void {\n if (event) event.preventDefault();\n\n document.addEventListener(\"keydown\", this._exitFullScreenOnEscape, false);\n\n // trap focus in the fullscreen container, listening for Tab key on the\n // capture phase so we have the best chance of preventing other handlers\n document.addEventListener(\"keydown\", this._trapFocusExit, true);\n\n this.card.setAttribute(Card.attr.ATTR_FULL_SCREEN, \"true\");\n document.body.classList.add(Card.attr.CLASS_HAS_FULL_SCREEN);\n this.card.insertAdjacentElement(\"beforebegin\", this.overlay.container);\n\n // Set initial focus on the card, if not already\n if (\n !this.card.contains(document.activeElement) ||\n document.activeElement?.classList.contains(\n Card.attr.CLASS_FULL_SCREEN_ENTER\n )\n ) {\n this.card.setAttribute(\"tabindex\", \"-1\");\n this.card.focus();\n }\n }\n\n /**\n * Exit full screen mode. This removes the full screen overlay element,\n * removes the full screen class from the card, and removes the keyboard event\n * listeners that were added when entering full screen mode.\n */\n exitFullScreen(): void {\n document.removeEventListener(\n \"keydown\",\n this._exitFullScreenOnEscape,\n false\n );\n document.removeEventListener(\"keydown\", this._trapFocusExit, true);\n\n // Remove overlay and remove full screen classes from card\n this.overlay.container.remove();\n this.card.setAttribute(Card.attr.ATTR_FULL_SCREEN, \"false\");\n this.card.removeAttribute(\"tabindex\");\n document.body.classList.remove(Card.attr.CLASS_HAS_FULL_SCREEN);\n }\n\n /**\n * Adds general card-specific event listeners.\n * @private\n */\n private _addEventListeners(): void {\n const btnFullScreen = this.card.querySelector(\n `:scope > * > .${Card.attr.CLASS_FULL_SCREEN_ENTER}`\n );\n if (!btnFullScreen) return;\n btnFullScreen.addEventListener(\"click\", (ev) => this.enterFullScreen(ev));\n }\n\n /**\n * An event handler to exit full screen mode when the Escape key is pressed.\n * @private\n * @param {KeyboardEvent} event\n */\n private _exitFullScreenOnEscape(event: KeyboardEvent): void {\n if (!(event.target instanceof HTMLElement)) return;\n // If the user is in the middle of a select input choice, don't exit\n const selOpenSelectInput = [\"select[open]\", \"input[aria-expanded='true']\"];\n if (event.target.matches(selOpenSelectInput.join(\", \"))) return;\n\n if (event.key === \"Escape\") {\n this.exitFullScreen();\n }\n }\n\n /**\n * An event handler to trap focus within the card when in full screen mode.\n *\n * @description\n * This keyboard event handler ensures that tab focus stays within the card\n * when in full screen mode. When the card is first expanded,\n * we move focus to the card element itself. If focus somehow leaves the card,\n * we returns focus to the card container.\n *\n * Within the card, we handle only tabbing from the close anchor or the last\n * focusable element and only when tab focus would have otherwise left the\n * card. In those cases, we cycle focus to the last focusable element or back\n * to the anchor. If the card doesn't have any focusable elements, we move\n * focus to the close anchor.\n *\n * @note\n * Because the card contents may change, we check for focusable elements\n * every time the handler is called.\n *\n * @private\n * @param {KeyboardEvent} event\n */\n private _trapFocusExit(event: KeyboardEvent): void {\n if (!(event instanceof KeyboardEvent)) return;\n if (event.key !== \"Tab\") return;\n\n const isFocusedContainer = event.target === this.card;\n const isFocusedAnchor = event.target === this.overlay.anchor;\n const isFocusedWithin = this.card.contains(event.target as Node);\n\n const stopEvent = () => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n\n if (!(isFocusedWithin || isFocusedContainer || isFocusedAnchor)) {\n // If focus is outside the card, return to the card\n stopEvent();\n this.card.focus();\n return;\n }\n\n // Check focusables every time because the card contents may have changed\n // but exclude the full screen enter button from this list of elements\n const focusableElements = getAllFocusableChildren(this.card).filter(\n (el) => !el.classList.contains(Card.attr.CLASS_FULL_SCREEN_ENTER)\n );\n const hasFocusableElements = focusableElements.length > 0;\n\n // We need to handle five cases:\n // 1. The card has no focusable elements --> focus the anchor\n // 2. Focus is on the card container (do nothing, natural tab order)\n // 3. Focus is on the anchor and the user pressed Tab + Shift (backwards)\n // -> Move to the last focusable element (end of card)\n // 4. Focus is on the last focusable element and the user pressed Tab\n // (forwards) -> Move to the anchor (top of card)\n // 5. otherwise we don't interfere\n\n if (!hasFocusableElements) {\n // case 1\n stopEvent();\n this.overlay.anchor.focus();\n return;\n }\n\n // case 2\n if (isFocusedContainer) return;\n\n const lastFocusable = focusableElements[focusableElements.length - 1];\n const isFocusedLast = event.target === lastFocusable;\n\n if (isFocusedAnchor && event.shiftKey) {\n stopEvent();\n lastFocusable.focus();\n return;\n }\n\n if (isFocusedLast && !event.shiftKey) {\n stopEvent();\n this.overlay.anchor.focus();\n return;\n }\n }\n\n /**\n * Creates the full screen overlay.\n * @private\n * @returns {CardFullScreenOverlay}\n */\n private _createOverlay(): CardFullScreenOverlay {\n const container = document.createElement(\"div\");\n container.id = Card.attr.ID_FULL_SCREEN_OVERLAY;\n container.onclick = this.exitFullScreen.bind(this);\n\n const anchor = this._createOverlayCloseAnchor();\n container.appendChild(anchor);\n\n return { container, anchor };\n }\n\n /**\n * Creates the anchor element used to exit the full screen mode.\n * @private\n * @returns {HTMLAnchorElement}\n */\n private _createOverlayCloseAnchor(): HTMLAnchorElement {\n const anchor = document.createElement(\"a\");\n anchor.classList.add(Card.attr.CLASS_FULL_SCREEN_EXIT);\n anchor.tabIndex = 0;\n anchor.onclick = () => this.exitFullScreen();\n anchor.onkeydown = (ev) => {\n if (ev.key === \"Enter\" || ev.key === \" \") {\n this.exitFullScreen();\n }\n };\n anchor.innerHTML = this._overlayCloseHtml();\n\n return anchor;\n }\n\n /**\n * Returns the HTML for the close icon.\n * @private\n * @returns {string}\n */\n private _overlayCloseHtml(): string {\n return (\n \"Close \" +\n \"\" +\n \"\"\n );\n }\n\n /**\n * The registry of card instances and their associated DOM elements.\n * @private\n * @static\n * @type {WeakMap}\n */\n private static instanceMap: WeakMap = new WeakMap();\n\n /**\n * Returns the card instance associated with the given element, if any.\n * @public\n * @static\n * @param {HTMLElement} el\n * @returns {(Card | undefined)}\n */\n public static getInstance(el: HTMLElement): Card | undefined {\n return Card.instanceMap.get(el);\n }\n\n /**\n * If cards are initialized before the DOM is ready, we re-schedule the\n * initialization to occur on DOMContentLoaded.\n * @private\n * @static\n * @type {boolean}\n */\n private static onReadyScheduled = false;\n\n /**\n * Initializes all cards that require initialization on the page, or schedules\n * initialization if the DOM is not yet ready.\n * @public\n * @static\n * @param {boolean} [flushResizeObserver=true]\n */\n public static initializeAllCards(flushResizeObserver = true): void {\n if (document.readyState === \"loading\") {\n if (!Card.onReadyScheduled) {\n Card.onReadyScheduled = true;\n document.addEventListener(\"DOMContentLoaded\", () => {\n Card.initializeAllCards(false);\n });\n }\n return;\n }\n\n if (flushResizeObserver) {\n // Trigger a recheck of observed cards to unobserve non-existent cards\n Card.shinyResizeObserver.flush();\n }\n\n const initSelector = `.${Card.attr.CLASS_CARD}[${Card.attr.ATTR_INIT}]`;\n if (!document.querySelector(initSelector)) {\n // no cards to initialize\n return;\n }\n\n const cards = document.querySelectorAll(initSelector);\n cards.forEach((card) => new Card(card as HTMLElement));\n }\n}\n\n// attach Sidebar class to window for global usage\n(window as any).bslib = (window as any).bslib || {};\n(window as any).bslib.Card = Card;\n\nexport { Card };\n", "import { InputBinding, registerBinding } from \"./_utils\";\nimport { ShinyResizeObserver } from \"./_shinyResizeObserver\";\n\n/**\n * Methods for programmatically toggling the state of the sidebar. These methods\n * describe the desired state of the sidebar: `\"close\"` and `\"open\"` transition\n * the sidebar to the desired state, unless the sidebar is already in that\n * state. `\"toggle\"` transitions the sidebar to the state opposite of its\n * current state.\n * @typedef {SidebarToggleMethod}\n */\ntype SidebarToggleMethod = \"close\" | \"open\" | \"toggle\";\n\n/**\n * Data received by the input binding's `receiveMessage` method.\n * @typedef {SidebarMessageData}\n */\ntype SidebarMessageData = {\n method: SidebarToggleMethod;\n};\n\n/**\n * The DOM elements that make up the sidebar. `main`, `sidebar`, and `toggle`\n * are all direct children of `container` (in that order).\n * @interface SidebarComponents\n * @typedef {SidebarComponents}\n */\ninterface SidebarComponents {\n /**\n * The `layout_sidebar()` parent container, with class\n * `Sidebar.classes.LAYOUT`.\n * @type {HTMLElement}\n */\n container: HTMLElement;\n /**\n * The main content area of the sidebar layout.\n * @type {HTMLElement}\n */\n main: HTMLElement;\n /**\n * The sidebar container of the sidebar layout.\n * @type {HTMLElement}\n */\n sidebar: HTMLElement;\n /**\n * The toggle button that is used to toggle the sidebar state.\n * @type {HTMLElement}\n */\n toggle: HTMLElement;\n}\n\n/**\n * The bslib sidebar component class. This class is only used for collapsible\n * sidebars.\n *\n * @class Sidebar\n * @typedef {Sidebar}\n */\nclass Sidebar {\n /**\n * The DOM elements that make up the sidebar, see `SidebarComponents`.\n * @private\n * @type {SidebarComponents}\n */\n private layout: SidebarComponents;\n\n /**\n * A Shiny-specific resize observer that ensures Shiny outputs in the main\n * content areas of the sidebar resize appropriately.\n * @private\n * @type {ShinyResizeObserver}\n * @static\n */\n private static shinyResizeObserver = new ShinyResizeObserver();\n\n /**\n * Creates an instance of a collapsible bslib Sidebar.\n * @constructor\n * @param {HTMLElement} container\n */\n constructor(container: HTMLElement) {\n Sidebar.instanceMap.set(container, this);\n this.layout = {\n container,\n main: container.querySelector(\":scope > .main\") as HTMLElement,\n sidebar: container.querySelector(\":scope > .sidebar\") as HTMLElement,\n toggle: container.querySelector(\n \":scope > .collapse-toggle\"\n ) as HTMLElement,\n } as SidebarComponents;\n\n const sideAccordion = this.layout.sidebar.querySelector(\n \":scope > .sidebar-content > .accordion\"\n );\n if (sideAccordion) {\n // Add `.has-accordion` class to `.sidebar-content` container\n sideAccordion?.parentElement?.classList.add(\"has-accordion\");\n sideAccordion.classList.add(\"accordion-flush\");\n }\n\n if (this.layout.toggle) {\n this._initEventListeners();\n this._initSidebarCounters();\n this._initDesktop();\n }\n\n // Start watching the main content area for size changes to ensure Shiny\n // outputs resize appropriately during sidebar transitions.\n Sidebar.shinyResizeObserver.observe(this.layout.main);\n\n container.removeAttribute(\"data-bslib-sidebar-init\");\n const initScript = container.querySelector(\n \":scope > script[data-bslib-sidebar-init]\"\n );\n if (initScript) {\n container.removeChild(initScript);\n }\n }\n\n /**\n * Read the current state of the sidebar. Note that, when calling this method,\n * the sidebar may be transitioning into the state returned by this method.\n *\n * @description\n * The sidebar state works as follows, starting from the open state. When the\n * sidebar is closed:\n * 1. We add both the `COLLAPSE` and `TRANSITIONING` classes to the sidebar.\n * 2. The sidebar collapse begins to animate. On desktop devices, and where it\n * is supported, we transition the `grid-template-columns` property of the\n * sidebar layout. On mobile, the sidebar is hidden immediately. In both\n * cases, the collapse icon rotates and we use this rotation to determine\n * when the transition is complete.\n * 3. If another sidebar state toggle is requested while closing the sidebar,\n * we remove the `COLLAPSE` class and the animation immediately starts to\n * reverse.\n * 4. When the `transition` is complete, we remove the `TRANSITIONING` class.\n * @readonly\n * @type {boolean}\n */\n get isClosed(): boolean {\n return this.layout.container.classList.contains(Sidebar.classes.COLLAPSE);\n }\n\n /**\n * Static classes related to the sidebar layout or state.\n * @public\n * @static\n * @readonly\n * @type {{ LAYOUT: string; COLLAPSE: string; TRANSITIONING: string; }}\n */\n public static readonly classes = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n LAYOUT: \"bslib-sidebar-layout\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n COLLAPSE: \"sidebar-collapsed\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n TRANSITIONING: \"transitioning\",\n };\n\n /**\n * If sidebars are initialized before the DOM is ready, we re-schedule the\n * initialization to occur on DOMContentLoaded.\n * @private\n * @static\n * @type {boolean}\n */\n private static onReadyScheduled = false;\n /**\n * A map of initialized sidebars to their respective Sidebar instances.\n * @private\n * @static\n * @type {WeakMap}\n */\n private static instanceMap: WeakMap = new WeakMap();\n\n /**\n * Given a sidebar container, return the Sidebar instance associated with it.\n * @public\n * @static\n * @param {HTMLElement} el\n * @returns {(Sidebar | undefined)}\n */\n public static getInstance(el: HTMLElement): Sidebar | undefined {\n return Sidebar.instanceMap.get(el);\n }\n\n /**\n * Initialize all collapsible sidebars on the page.\n * @public\n * @static\n * @param {boolean} [flushResizeObserver=true] When `true`, we remove\n * non-existent elements from the ResizeObserver. This is required\n * periodically to prevent memory leaks. To avoid over-checking, we only flush\n * the ResizeObserver when initializing sidebars after page load.\n */\n public static initCollapsibleAll(flushResizeObserver = true): void {\n if (document.readyState === \"loading\") {\n if (!Sidebar.onReadyScheduled) {\n Sidebar.onReadyScheduled = true;\n document.addEventListener(\"DOMContentLoaded\", () => {\n Sidebar.initCollapsibleAll(false);\n });\n }\n return;\n }\n\n const initSelector = `.${Sidebar.classes.LAYOUT}[data-bslib-sidebar-init]`;\n if (!document.querySelector(initSelector)) {\n // no sidebars to initialize\n return;\n }\n\n if (flushResizeObserver) Sidebar.shinyResizeObserver.flush();\n\n const containers = document.querySelectorAll(initSelector);\n containers.forEach((container) => new Sidebar(container as HTMLElement));\n }\n\n /**\n * Initialize event listeners for the sidebar toggle button.\n * @private\n */\n private _initEventListeners(): void {\n const { toggle } = this.layout;\n\n toggle.addEventListener(\"click\", (ev) => {\n ev.preventDefault();\n this.toggle(\"toggle\");\n });\n\n // Remove the transitioning class when the transition ends. We watch the\n // collapse toggle icon because it's guaranteed to transition, whereas the\n // sidebar doesn't animate on mobile (or in browsers where animating\n // grid-template-columns is not supported).\n toggle\n .querySelector(\".collapse-icon\")\n ?.addEventListener(\"transitionend\", () => this._finalizeState());\n }\n\n /**\n * Initialize nested sidebar counters.\n *\n * @description\n * This function walks up the DOM tree, adding CSS variables to each direct\n * parent sidebar layout that count the layout's position in the stack of\n * nested layouts. We use these counters to keep the collapse toggles from\n * overlapping. Note that always-open sidebars that don't have collapse\n * toggles break the chain of nesting.\n * @private\n */\n private _initSidebarCounters(): void {\n const { container } = this.layout;\n\n const selectorChildLayouts =\n `.${Sidebar.classes.LAYOUT}` +\n \"> .main > \" +\n `.${Sidebar.classes.LAYOUT}:not([data-bslib-sidebar-open=\"always\"])`;\n\n const isInnermostLayout =\n container.querySelector(selectorChildLayouts) === null;\n\n if (!isInnermostLayout) {\n // There are sidebar layouts nested within this layout; defer to children\n return;\n }\n\n function nextSidebarParent(el: HTMLElement | null): HTMLElement | null {\n el = el ? el.parentElement : null;\n if (el && el.classList.contains(\"main\")) {\n // .bslib-sidebar-layout > .main > .bslib-sidebar-layout\n el = el.parentElement;\n }\n if (el && el.classList.contains(Sidebar.classes.LAYOUT)) {\n return el;\n }\n return null;\n }\n\n const layouts = [container];\n let parent = nextSidebarParent(container);\n\n while (parent) {\n // Add parent to front of layouts array, so we sort outer -> inner\n layouts.unshift(parent);\n parent = nextSidebarParent(parent);\n }\n\n const count = { left: 0, right: 0 };\n layouts.forEach(function (x: HTMLElement, i: number): void {\n x.style.setProperty(\"--bslib-sidebar-counter\", i.toString());\n const isRight = x.classList.contains(\"sidebar-right\");\n const thisCount = isRight ? count.right++ : count.left++;\n x.style.setProperty(\n \"--bslib-sidebar-overlap-counter\",\n thisCount.toString()\n );\n });\n }\n\n /**\n * Initialize the sidebar's initial state when `open = \"desktop\"`.\n * @private\n */\n private _initDesktop(): void {\n const { container } = this.layout;\n // If sidebar is marked open='desktop'...\n if (container.dataset.bslibSidebarOpen?.trim() !== \"desktop\") {\n return;\n }\n\n // then close sidebar on mobile\n const initCollapsed = window\n .getComputedStyle(container)\n .getPropertyValue(\"--bslib-sidebar-js-init-collapsed\");\n\n if (initCollapsed.trim() === \"true\") {\n this.toggle(\"close\");\n }\n }\n\n /**\n * Toggle the sidebar's open/closed state.\n * @public\n * @param {SidebarToggleMethod | undefined} method Whether to `\"open\"`,\n * `\"close\"` or `\"toggle\"` the sidebar. If `.toggle()` is called without an\n * argument, it will toggle the sidebar's state.\n */\n public toggle(method: SidebarToggleMethod | undefined): void {\n if (typeof method === \"undefined\") {\n method = \"toggle\";\n }\n\n const { container, sidebar } = this.layout;\n const isClosed = this.isClosed;\n\n if ([\"open\", \"close\", \"toggle\"].indexOf(method) === -1) {\n throw new Error(`Unknown method ${method}`);\n }\n\n if (method === \"toggle\") {\n method = isClosed ? \"open\" : \"close\";\n }\n\n if ((isClosed && method === \"close\") || (!isClosed && method === \"open\")) {\n // nothing to do, sidebar is already in the desired state\n return;\n }\n\n if (method === \"open\") {\n // unhide sidebar immediately when opening,\n // otherwise the sidebar is hidden on transitionend\n sidebar.hidden = false;\n }\n\n // Add a transitioning class just before adding COLLAPSE_CLASS since we want\n // some of the transitioning styles to apply before the collapse state\n container.classList.add(Sidebar.classes.TRANSITIONING);\n container.classList.toggle(Sidebar.classes.COLLAPSE);\n }\n\n /**\n * When the sidebar open/close transition ends, finalize the sidebar's state.\n * @private\n */\n private _finalizeState(): void {\n const { container, sidebar, toggle } = this.layout;\n container.classList.remove(Sidebar.classes.TRANSITIONING);\n sidebar.hidden = this.isClosed;\n toggle.setAttribute(\"aria-expanded\", this.isClosed ? \"false\" : \"true\");\n\n // Send browser-native event with updated sidebar state\n const event = new CustomEvent(\"bslib.sidebar\", {\n bubbles: true,\n detail: { open: !this.isClosed },\n });\n sidebar.dispatchEvent(event);\n\n // Trigger Shiny input and output binding events\n $(sidebar).trigger(\"toggleCollapse.sidebarInputBinding\");\n $(sidebar).trigger(this.isClosed ? \"hidden\" : \"shown\");\n }\n}\n\n/**\n * A Shiny input binding for a sidebar.\n * @class SidebarInputBinding\n * @typedef {SidebarInputBinding}\n * @extends {InputBinding}\n */\nclass SidebarInputBinding extends InputBinding {\n find(scope: HTMLElement) {\n return $(scope).find(`.${Sidebar.classes.LAYOUT} > .bslib-sidebar-input`);\n }\n\n getValue(el: HTMLElement): boolean {\n const sb = Sidebar.getInstance(el.parentElement as HTMLElement);\n if (!sb) return false;\n return !sb.isClosed;\n }\n\n setValue(el: HTMLElement, value: boolean): void {\n const method = value ? \"open\" : \"close\";\n this.receiveMessage(el, { method });\n }\n\n subscribe(el: HTMLElement, callback: (x: boolean) => void) {\n $(el).on(\n \"toggleCollapse.sidebarInputBinding\",\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function (event) {\n callback(true);\n }\n );\n }\n\n unsubscribe(el: HTMLElement) {\n $(el).off(\".sidebarInputBinding\");\n }\n\n receiveMessage(el: HTMLElement, data: SidebarMessageData) {\n const sb = Sidebar.getInstance(el.parentElement as HTMLElement);\n if (sb) sb.toggle(data.method);\n }\n}\n\nregisterBinding(SidebarInputBinding, \"sidebar\");\n\n// attach Sidebar class to window for global usage\n(window as any).bslib = (window as any).bslib || {};\n(window as any).bslib.Sidebar = Sidebar;\n", "import type { Handler as ShinyCustomMessageHandler } from \"rstudio-shiny/srcts/types/src/shiny/shinyapp\";\n\nexport function shinyAddCustomMessageHandlers(handlers: {\n [key: string]: ShinyCustomMessageHandler;\n}): void {\n if (!window.Shiny) {\n return;\n }\n\n for (const [name, handler] of Object.entries(handlers)) {\n Shiny.addCustomMessageHandler(name, handler);\n }\n}\n", "// ----------------------------------------------------------------------------\n// First, bring in non-webcomponent (legacy) components (they attach to the window)\n// ----------------------------------------------------------------------------\nimport \"./accordion\";\nimport \"./card\";\nimport \"./sidebar\";\n\n// ----------------------------------------------------------------------------\n// Register custom message handlers for Shiny\n// ----------------------------------------------------------------------------\nimport { InputBinding } from \"./_utils\";\nimport { shinyAddCustomMessageHandlers } from \"./_shinyAddCustomMessageHandlers\";\n\nconst bslibMessageHandlers = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"bslib.toggle-input-binary\": (msg: any) => {\n // This handler was written for `toggle_switch()`, but could be used for any\n // binary Shiny input, e.g. checkbox.\n const el = document.getElementById(msg.id) as HTMLElement;\n if (!el) {\n console.warn(\"[bslib.toggle-input-binary] No element found\", msg);\n }\n\n const binding = $(el).data(\"shiny-input-binding\");\n if (!(binding instanceof InputBinding)) {\n console.warn(\"[bslib.toggle-input-binary] No input binding found\", msg);\n return;\n }\n\n let value = msg.value;\n if (typeof value === \"undefined\") {\n value = !binding.getValue(el);\n }\n binding.receiveMessage(el, { value });\n },\n};\n\nif (window.Shiny) {\n shinyAddCustomMessageHandlers(bslibMessageHandlers);\n}\n\n// ----------------------------------------------------------------------\n// Append the (global) SVG linearGradient to the body.\n// value_box() uses this (i.e., bslib---icon-gradient element) to apply a\n// gradient to the icon when bs_theme(preset=\"shiny\").\n// ----------------------------------------------------------------------\n\nfunction insertSvgGradient() {\n const temp = document.createElement(\"div\");\n temp.innerHTML = `\n \n \n \n \n \n \n \n \n \n \n \n `;\n document.body.appendChild(temp.children[0] as Node);\n}\n\nif (document.readyState === \"complete\") {\n insertSvgGradient();\n} else {\n document.addEventListener(\"DOMContentLoaded\", insertSvgGradient);\n}\n"], + "mappings": "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", + "names": [] +} diff --git a/inst/components/dist/components.min.js b/inst/components/dist/components.min.js new file mode 100644 index 000000000..c16a66556 --- /dev/null +++ b/inst/components/dist/components.min.js @@ -0,0 +1,15 @@ +/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ +"use strict";(()=>{var h=window.Shiny?Shiny.InputBinding:class{};function g(a,e){window.Shiny&&Shiny.inputBindings.register(new a,"bslib."+e)}function f(a,e){return Object.prototype.hasOwnProperty.call(a,e)&&a[e]!==void 0}function L(a){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=a.querySelectorAll(n.join(", "));return Array.from(s)}var E=class extends h{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){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")this._insertItem(e,t);else if(n==="update")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){let n=this._findItem(e,t.target);n||(n=t.position==="before"?e.firstElementChild:e.lastElementChild);let s=t.panel;if(n?Shiny.renderContent(n,s,t.position==="before"?"beforeBegin":"afterEnd"):Shiny.renderContent(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){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(f(t,"value")&&(n.dataset.value=t.value),f(t,"body")){let i=n.querySelector(".accordion-body");Shiny.renderContent(i,t.body)}let s=n.querySelector(".accordion-header");if(f(t,"title")){let i=s.querySelector(".accordion-title");Shiny.renderContent(i,t.title)}if(f(t,"icon")){let i=s.querySelector(".accordion-button > .accordion-icon");Shiny.renderContent(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")}};g(E,"accordion");var m=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:b}=$(i).data("shinyOutputBinding");if(!c||!c.resize)return;let o=i.shinyResizeObserver;if(o&&o!==this||(o||(i.shinyResizeObserver=this),b(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 r=class{constructor(e){var t;e.removeAttribute(r.attr.ATTR_INIT),(t=e.querySelector(`script[${r.attr.ATTR_INIT}]`))==null||t.remove(),this.card=e,r.instanceMap.set(e,this),r.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(r.attr.ATTR_FULL_SCREEN,"true"),document.body.classList.add(r.attr.CLASS_HAS_FULL_SCREEN),this.card.insertAdjacentElement("beforebegin",this.overlay.container),(!this.card.contains(document.activeElement)||(t=document.activeElement)!=null&&t.classList.contains(r.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(r.attr.ATTR_FULL_SCREEN,"false"),this.card.removeAttribute("tabindex"),document.body.classList.remove(r.attr.CLASS_HAS_FULL_SCREEN)}_addEventListeners(){let e=this.card.querySelector(`:scope > * > .${r.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=L(this.card).filter(v=>!v.classList.contains(r.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=r.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(r.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 r.instanceMap.get(e)}static initializeAllCards(e=!0){if(document.readyState==="loading"){r.onReadyScheduled||(r.onReadyScheduled=!0,document.addEventListener("DOMContentLoaded",()=>{r.initializeAllCards(!1)}));return}e&&r.shinyResizeObserver.flush();let t=`.${r.attr.CLASS_CARD}[${r.attr.ATTR_INIT}]`;if(!document.querySelector(t))return;document.querySelectorAll(t).forEach(s=>new r(s))}},u=r;u.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"},u.shinyResizeObserver=new m,u.instanceMap=new WeakMap,u.onReadyScheduled=!1;window.bslib=window.bslib||{};window.bslib.Card=u;var 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 b={left:0,right:0};i.forEach(function(o,p){o.style.setProperty("--bslib-sidebar-counter",p.toString());let T=o.classList.contains("sidebar-right")?b.right++:b.left++;o.style.setProperty("--bslib-sidebar-overlap-counter",T.toString())})}_initDesktop(){var n;let{container:e}=this.layout;if(((n=e.dataset.bslibSidebarOpen)==null?void 0:n.trim())!=="desktop")return;window.getComputedStyle(e).getPropertyValue("--bslib-sidebar-js-init-collapsed").trim()==="true"&&this.toggle("close")}toggle(e){typeof e=="undefined"&&(e="toggle");let{container:t,sidebar:n}=this.layout,s=this.isClosed;if(["open","close","toggle"].indexOf(e)===-1)throw new Error(`Unknown method ${e}`);e==="toggle"&&(e=s?"open":"close"),!(s&&e==="close"||!s&&e==="open")&&(e==="open"&&(n.hidden=!1),t.classList.add(l.classes.TRANSITIONING),t.classList.toggle(l.classes.COLLAPSE))}_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")}},d=l;d.shinyResizeObserver=new m,d.classes={LAYOUT:"bslib-sidebar-layout",COLLAPSE:"sidebar-collapsed",TRANSITIONING:"transitioning"},d.onReadyScheduled=!1,d.instanceMap=new WeakMap;var y=class extends h{find(e){return $(e).find(`.${d.classes.LAYOUT} > .bslib-sidebar-input`)}getValue(e){let t=d.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=d.getInstance(e.parentElement);n&&n.toggle(t.method)}};g(y,"sidebar");window.bslib=window.bslib||{};window.bslib.Sidebar=d;function S(a){if(window.Shiny)for(let[e,t]of Object.entries(a))Shiny.addCustomMessageHandler(e,t)}var C={"bslib.toggle-input-binary":a=>{let e=document.getElementById(a.id);e||console.warn("[bslib.toggle-input-binary] No element found",a);let t=$(e).data("shiny-input-binding");if(!(t instanceof h)){console.warn("[bslib.toggle-input-binary] No input binding found",a);return}let n=a.value;typeof n=="undefined"&&(n=!t.getValue(e)),t.receiveMessage(e,{value:n})}};window.Shiny&&S(C);function M(){let a=document.createElement("div");a.innerHTML=` + `,document.body.appendChild(a.children[0])}document.readyState==="complete"?M():document.addEventListener("DOMContentLoaded",M);})(); +//# sourceMappingURL=components.min.js.map diff --git a/inst/components/dist/components.min.js.map b/inst/components/dist/components.min.js.map new file mode 100644 index 000000000..5441c0457 --- /dev/null +++ b/inst/components/dist/components.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../../srcts/src/components/_utils.ts", "../../../srcts/src/components/accordion.ts", "../../../srcts/src/components/_shinyResizeObserver.ts", "../../../srcts/src/components/card.ts", "../../../srcts/src/components/sidebar.ts", "../../../srcts/src/components/_shinyAddCustomMessageHandlers.ts", "../../../srcts/src/components/index.ts"], + "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "import type { HtmlDep } from \"./_utils\";\nimport { InputBinding, registerBinding, hasDefinedProperty } from \"./_utils\";\n\ntype AccordionItem = {\n item: HTMLElement;\n value: string;\n isOpen: () => boolean;\n show: () => void;\n hide: () => void;\n};\n\ntype HTMLContent = {\n html: string;\n deps?: HtmlDep[];\n};\n\ntype SetMessage = {\n method: \"set\";\n values: string[];\n};\n\ntype OpenMessage = {\n method: \"open\";\n values: string[] | true;\n};\n\ntype CloseMessage = {\n method: \"close\";\n values: string[] | true;\n};\n\ntype InsertMessage = {\n method: \"insert\";\n panel: HTMLContent;\n target: string;\n position: \"after\" | \"before\";\n};\n\ntype RemoveMessage = {\n method: \"remove\";\n target: string[];\n};\n\ntype UpdateMessage = {\n method: \"update\";\n target: string;\n value: string;\n body: HTMLContent;\n title: HTMLContent;\n icon: HTMLContent;\n};\n\ntype MessageData =\n | CloseMessage\n | InsertMessage\n | OpenMessage\n | RemoveMessage\n | SetMessage\n | UpdateMessage;\n\nclass AccordionInputBinding extends InputBinding {\n find(scope: HTMLElement) {\n return $(scope).find(\".accordion.bslib-accordion-input\");\n }\n\n getValue(el: HTMLElement): string[] | null {\n const items = this._getItemInfo(el);\n const selected = items.filter((x) => x.isOpen()).map((x) => x.value);\n return selected.length === 0 ? null : selected;\n }\n\n subscribe(el: HTMLElement, callback: (x: boolean) => void) {\n $(el).on(\n \"shown.bs.collapse.accordionInputBinding hidden.bs.collapse.accordionInputBinding\",\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function (event) {\n callback(true);\n }\n );\n }\n\n unsubscribe(el: HTMLElement) {\n $(el).off(\".accordionInputBinding\");\n }\n\n receiveMessage(el: HTMLElement, data: MessageData) {\n const method = data.method;\n if (method === \"set\") {\n this._setItems(el, data);\n } else if (method === \"open\") {\n this._openItems(el, data);\n } else if (method === \"close\") {\n this._closeItems(el, data);\n } else if (method === \"remove\") {\n this._removeItem(el, data);\n } else if (method === \"insert\") {\n this._insertItem(el, data);\n } else if (method === \"update\") {\n this._updateItem(el, data);\n } else {\n throw new Error(`Method not yet implemented: ${method}`);\n }\n }\n\n protected _setItems(el: HTMLElement, data: SetMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n vals.indexOf(x.value) > -1 ? x.show() : x.hide();\n });\n }\n\n protected _openItems(el: HTMLElement, data: OpenMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n if (vals.indexOf(x.value) > -1) x.show();\n });\n }\n\n protected _closeItems(el: HTMLElement, data: CloseMessage) {\n const items = this._getItemInfo(el);\n const vals = this._getValues(el, items, data.values);\n items.forEach((x) => {\n if (vals.indexOf(x.value) > -1) x.hide();\n });\n }\n\n protected _insertItem(el: HTMLElement, data: InsertMessage) {\n let targetItem = this._findItem(el, data.target);\n\n // If no target was specified, or the target was not found, then default\n // to the first or last item, depending on the position\n if (!targetItem) {\n targetItem = (\n data.position === \"before\" ? el.firstElementChild : el.lastElementChild\n ) as HTMLElement;\n }\n\n const panel = data.panel;\n\n // If there is still no targetItem, then there are no items in the accordion\n if (targetItem) {\n Shiny.renderContent(\n targetItem,\n panel,\n data.position === \"before\" ? \"beforeBegin\" : \"afterEnd\"\n );\n } else {\n Shiny.renderContent(el, panel);\n }\n\n // Need to add a reference to the parent id that makes autoclose to work\n if (this._isAutoClosing(el)) {\n const val = $(panel.html).attr(\"data-value\");\n $(el)\n .find(`[data-value=\"${val}\"] .accordion-collapse`)\n .attr(\"data-bs-parent\", \"#\" + el.id);\n }\n }\n\n protected _removeItem(el: HTMLElement, data: RemoveMessage) {\n const targetItems = this._getItemInfo(el).filter(\n (x) => data.target.indexOf(x.value) > -1\n );\n\n const unbindAll = Shiny?.unbindAll;\n\n targetItems.forEach((x) => {\n if (unbindAll) unbindAll(x.item);\n x.item.remove();\n });\n }\n\n protected _updateItem(el: HTMLElement, data: UpdateMessage) {\n const target = this._findItem(el, data.target);\n\n if (!target) {\n throw new Error(\n `Unable to find an accordion_panel() with a value of ${data.target}`\n );\n }\n\n if (hasDefinedProperty(data, \"value\")) {\n target.dataset.value = data.value;\n }\n\n if (hasDefinedProperty(data, \"body\")) {\n const body = target.querySelector(\".accordion-body\") as HTMLElement; // always exists\n Shiny.renderContent(body, data.body);\n }\n\n const header = target.querySelector(\".accordion-header\") as HTMLElement; // always exists\n\n if (hasDefinedProperty(data, \"title\")) {\n const title = header.querySelector(\".accordion-title\") as HTMLElement; // always exists\n Shiny.renderContent(title, data.title);\n }\n\n if (hasDefinedProperty(data, \"icon\")) {\n const icon = header.querySelector(\n \".accordion-button > .accordion-icon\"\n ) as HTMLElement; // always exists\n Shiny.renderContent(icon, data.icon);\n }\n }\n\n protected _getItemInfo(el: HTMLElement): AccordionItem[] {\n const items = Array.from(\n el.querySelectorAll(\":scope > .accordion-item\")\n ) as HTMLElement[];\n return items.map((x) => this._getSingleItemInfo(x));\n }\n\n protected _getSingleItemInfo(x: HTMLElement): AccordionItem {\n const collapse = x.querySelector(\".accordion-collapse\") as HTMLElement;\n const isOpen = () => $(collapse).hasClass(\"show\");\n return {\n item: x,\n value: x.dataset.value as string,\n isOpen: isOpen,\n show: () => {\n if (!isOpen()) $(collapse).collapse(\"show\");\n },\n hide: () => {\n if (isOpen()) $(collapse).collapse(\"hide\");\n },\n };\n }\n\n protected _getValues(\n el: HTMLElement,\n items: AccordionItem[],\n values: string[] | true\n ): string[] {\n let vals = values !== true ? values : items.map((x) => x.value);\n const autoclose = this._isAutoClosing(el);\n if (autoclose) {\n vals = vals.slice(vals.length - 1, vals.length);\n }\n return vals;\n }\n\n protected _findItem(el: HTMLElement, value: string): HTMLElement | null {\n return el.querySelector(`[data-value=\"${value}\"]`);\n }\n\n protected _isAutoClosing(el: HTMLElement): boolean {\n return el.classList.contains(\"autoclose\");\n }\n}\n\nregisterBinding(AccordionInputBinding, \"accordion\");\n", "/**\n * A resize observer that ensures Shiny outputs resize during or just after\n * their parent container size changes. Useful, in particular, for sidebar\n * transitions or for full-screen card transitions.\n *\n * @class ShinyResizeObserver\n * @typedef {ShinyResizeObserver}\n */\nclass ShinyResizeObserver {\n /**\n * The actual ResizeObserver instance.\n * @private\n * @type {ResizeObserver}\n */\n private resizeObserver: ResizeObserver;\n /**\n * An array of elements that are currently being watched by the Resize\n * Observer.\n *\n * @details\n * We don't currently have lifecycle hooks that allow us to unobserve elements\n * when they are removed from the DOM. As a result, we need to manually check\n * that the elements we're watching still exist in the DOM. This array keeps\n * track of the elements we're watching so that we can check them later.\n * @private\n * @type {HTMLElement[]}\n */\n private resizeObserverEntries: HTMLElement[];\n\n /**\n * Watch containers for size changes and ensure that Shiny outputs and\n * htmlwidgets within resize appropriately.\n *\n * @details\n * The ShinyResizeObserver is used to watch the containers, such as Sidebars\n * and Cards for size changes, in particular when the sidebar state is toggled\n * or the card body is expanded full screen. It performs two primary tasks:\n *\n * 1. Dispatches a `resize` event on the window object. This is necessary to\n * ensure that Shiny outputs resize appropriately. In general, the window\n * resizing is throttled and the output update occurs when the transition\n * is complete.\n * 2. If an output with a resize method on the output binding is detected, we\n * directly call the `.onResize()` method of the binding. This ensures that\n * htmlwidgets transition smoothly. In static mode, htmlwidgets does this\n * already.\n *\n * @note\n * This resize observer also handles race conditions in some complex\n * fill-based layouts with multiple outputs (e.g., plotly), where shiny\n * initializes with the correct sizing, but in-between the 1st and last\n * renderValue(), the size of the output containers can change, meaning every\n * output but the 1st gets initialized with the wrong size during their\n * renderValue(). Then, after the render phase, shiny won't know to trigger a\n * resize since all the widgets will return to their original size (and thus,\n * Shiny thinks there isn't any resizing to do). The resize observer works\n * around this by ensuring that the output is resized whenever its container\n * size changes.\n * @constructor\n */\n constructor() {\n this.resizeObserverEntries = [];\n this.resizeObserver = new ResizeObserver((entries) => {\n const resizeEvent = new Event(\"resize\");\n window.dispatchEvent(resizeEvent);\n\n // the rest of this callback is only relevant in Shiny apps\n if (!window.Shiny) return;\n\n const resized = [] as HTMLElement[];\n\n for (const entry of entries) {\n if (!(entry.target instanceof HTMLElement)) continue;\n if (!entry.target.querySelector(\".shiny-bound-output\")) continue;\n\n entry.target\n .querySelectorAll(\".shiny-bound-output\")\n .forEach((el) => {\n if (resized.includes(el)) return;\n\n const { binding, onResize } = $(el).data(\"shinyOutputBinding\");\n if (!binding || !binding.resize) return;\n\n // if this output is owned by another observer, skip it\n const owner = (el as any).shinyResizeObserver;\n if (owner && owner !== this) return;\n // mark this output as owned by this shinyResizeObserver instance\n if (!owner) (el as any).shinyResizeObserver = this;\n\n // trigger immediate resizing of outputs with a resize method\n onResize(el);\n // only once per output and resize event\n resized.push(el);\n\n // set plot images to 100% width temporarily during the transition\n if (!el.classList.contains(\"shiny-plot-output\")) return;\n const img = el.querySelector(\n 'img:not([width=\"100%\"])'\n );\n if (img) img.setAttribute(\"width\", \"100%\");\n });\n }\n });\n }\n\n /**\n * Observe an element for size changes.\n * @param {HTMLElement} el - The element to observe.\n */\n observe(el: HTMLElement): void {\n this.resizeObserver.observe(el);\n this.resizeObserverEntries.push(el);\n }\n\n /**\n * Stop observing an element for size changes.\n * @param {HTMLElement} el - The element to stop observing.\n */\n unobserve(el: HTMLElement): void {\n const idxEl = this.resizeObserverEntries.indexOf(el);\n if (idxEl < 0) return;\n\n this.resizeObserver.unobserve(el);\n this.resizeObserverEntries.splice(idxEl, 1);\n }\n\n /**\n * This method checks that we're not continuing to watch elements that no\n * longer exist in the DOM. If any are found, we stop observing them and\n * remove them from our array of observed elements.\n *\n * @private\n * @static\n */\n flush(): void {\n this.resizeObserverEntries.forEach((el) => {\n if (!document.body.contains(el)) this.unobserve(el);\n });\n }\n}\n\nexport { ShinyResizeObserver };\n", "import { getAllFocusableChildren } from \"./_utils\";\nimport { ShinyResizeObserver } from \"./_shinyResizeObserver\";\n\n/**\n * The overlay element that is placed behind the card when expanded full screen.\n *\n * @interface CardFullScreenOverlay\n * @typedef {CardFullScreenOverlay}\n */\ninterface CardFullScreenOverlay {\n /**\n * The full screen overlay container.\n * @type {HTMLDivElement}\n */\n container: HTMLDivElement;\n /**\n * The anchor element used to close the full screen overlay.\n * @type {HTMLAnchorElement}\n */\n anchor: HTMLAnchorElement;\n}\n\n/**\n * The bslib card component class.\n *\n * @class Card\n * @typedef {Card}\n */\nclass Card {\n /**\n * The card container element.\n * @private\n * @type {HTMLElement}\n */\n private card: HTMLElement;\n /**\n * The card's full screen overlay element. We create this element once and add\n * and remove it from the DOM as needed (this simplifies focus management\n * while in full screen mode).\n * @private\n * @type {CardFullScreenOverlay}\n */\n private overlay: CardFullScreenOverlay;\n\n /**\n * Key bslib-specific classes and attributes used by the card component.\n * @private\n * @static\n * @type {{ ATTR_INIT: string; CLASS_CARD: string; CLASS_FULL_SCREEN: string; CLASS_HAS_FULL_SCREEN: string; CLASS_FULL_SCREEN_ENTER: string; CLASS_FULL_SCREEN_EXIT: string; ID_FULL_SCREEN_OVERLAY: string; }}\n */\n private static attr = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ATTR_INIT: \"data-bslib-card-init\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_CARD: \"bslib-card\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ATTR_FULL_SCREEN: \"data-full-screen\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_HAS_FULL_SCREEN: \"bslib-has-full-screen\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_FULL_SCREEN_ENTER: \"bslib-full-screen-enter\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n CLASS_FULL_SCREEN_EXIT: \"bslib-full-screen-exit\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ID_FULL_SCREEN_OVERLAY: \"bslib-full-screen-overlay\",\n };\n\n /**\n * A Shiny-specific resize observer that ensures Shiny outputs in within the\n * card resize appropriately.\n * @private\n * @type {ShinyResizeObserver}\n * @static\n */\n private static shinyResizeObserver = new ShinyResizeObserver();\n\n /**\n * Creates an instance of a bslib Card component.\n *\n * @constructor\n * @param {HTMLElement} card\n */\n constructor(card: HTMLElement) {\n // remove initialization attribute and script\n card.removeAttribute(Card.attr.ATTR_INIT);\n card\n .querySelector(`script[${Card.attr.ATTR_INIT}]`)\n ?.remove();\n\n this.card = card;\n Card.instanceMap.set(card, this);\n\n // Let Shiny know to trigger resize when the card size changes\n // TODO: shiny could/should do this itself (rstudio/shiny#3682)\n Card.shinyResizeObserver.observe(this.card);\n\n this._addEventListeners();\n this.overlay = this._createOverlay();\n\n // bind event handler methods to this card instance\n this._exitFullScreenOnEscape = this._exitFullScreenOnEscape.bind(this);\n this._trapFocusExit = this._trapFocusExit.bind(this);\n }\n\n /**\n * Enter the card's full screen mode, either programmatically or via an event\n * handler. Full screen mode is activated by adding a class to the card that\n * positions it absolutely and expands it to fill the viewport. In addition,\n * we add a full screen overlay element behind the card and we trap focus in\n * the expanded card while in full screen mode.\n *\n * @param {?Event} [event]\n */\n enterFullScreen(event?: Event): void {\n if (event) event.preventDefault();\n\n document.addEventListener(\"keydown\", this._exitFullScreenOnEscape, false);\n\n // trap focus in the fullscreen container, listening for Tab key on the\n // capture phase so we have the best chance of preventing other handlers\n document.addEventListener(\"keydown\", this._trapFocusExit, true);\n\n this.card.setAttribute(Card.attr.ATTR_FULL_SCREEN, \"true\");\n document.body.classList.add(Card.attr.CLASS_HAS_FULL_SCREEN);\n this.card.insertAdjacentElement(\"beforebegin\", this.overlay.container);\n\n // Set initial focus on the card, if not already\n if (\n !this.card.contains(document.activeElement) ||\n document.activeElement?.classList.contains(\n Card.attr.CLASS_FULL_SCREEN_ENTER\n )\n ) {\n this.card.setAttribute(\"tabindex\", \"-1\");\n this.card.focus();\n }\n }\n\n /**\n * Exit full screen mode. This removes the full screen overlay element,\n * removes the full screen class from the card, and removes the keyboard event\n * listeners that were added when entering full screen mode.\n */\n exitFullScreen(): void {\n document.removeEventListener(\n \"keydown\",\n this._exitFullScreenOnEscape,\n false\n );\n document.removeEventListener(\"keydown\", this._trapFocusExit, true);\n\n // Remove overlay and remove full screen classes from card\n this.overlay.container.remove();\n this.card.setAttribute(Card.attr.ATTR_FULL_SCREEN, \"false\");\n this.card.removeAttribute(\"tabindex\");\n document.body.classList.remove(Card.attr.CLASS_HAS_FULL_SCREEN);\n }\n\n /**\n * Adds general card-specific event listeners.\n * @private\n */\n private _addEventListeners(): void {\n const btnFullScreen = this.card.querySelector(\n `:scope > * > .${Card.attr.CLASS_FULL_SCREEN_ENTER}`\n );\n if (!btnFullScreen) return;\n btnFullScreen.addEventListener(\"click\", (ev) => this.enterFullScreen(ev));\n }\n\n /**\n * An event handler to exit full screen mode when the Escape key is pressed.\n * @private\n * @param {KeyboardEvent} event\n */\n private _exitFullScreenOnEscape(event: KeyboardEvent): void {\n if (!(event.target instanceof HTMLElement)) return;\n // If the user is in the middle of a select input choice, don't exit\n const selOpenSelectInput = [\"select[open]\", \"input[aria-expanded='true']\"];\n if (event.target.matches(selOpenSelectInput.join(\", \"))) return;\n\n if (event.key === \"Escape\") {\n this.exitFullScreen();\n }\n }\n\n /**\n * An event handler to trap focus within the card when in full screen mode.\n *\n * @description\n * This keyboard event handler ensures that tab focus stays within the card\n * when in full screen mode. When the card is first expanded,\n * we move focus to the card element itself. If focus somehow leaves the card,\n * we returns focus to the card container.\n *\n * Within the card, we handle only tabbing from the close anchor or the last\n * focusable element and only when tab focus would have otherwise left the\n * card. In those cases, we cycle focus to the last focusable element or back\n * to the anchor. If the card doesn't have any focusable elements, we move\n * focus to the close anchor.\n *\n * @note\n * Because the card contents may change, we check for focusable elements\n * every time the handler is called.\n *\n * @private\n * @param {KeyboardEvent} event\n */\n private _trapFocusExit(event: KeyboardEvent): void {\n if (!(event instanceof KeyboardEvent)) return;\n if (event.key !== \"Tab\") return;\n\n const isFocusedContainer = event.target === this.card;\n const isFocusedAnchor = event.target === this.overlay.anchor;\n const isFocusedWithin = this.card.contains(event.target as Node);\n\n const stopEvent = () => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n\n if (!(isFocusedWithin || isFocusedContainer || isFocusedAnchor)) {\n // If focus is outside the card, return to the card\n stopEvent();\n this.card.focus();\n return;\n }\n\n // Check focusables every time because the card contents may have changed\n // but exclude the full screen enter button from this list of elements\n const focusableElements = getAllFocusableChildren(this.card).filter(\n (el) => !el.classList.contains(Card.attr.CLASS_FULL_SCREEN_ENTER)\n );\n const hasFocusableElements = focusableElements.length > 0;\n\n // We need to handle five cases:\n // 1. The card has no focusable elements --> focus the anchor\n // 2. Focus is on the card container (do nothing, natural tab order)\n // 3. Focus is on the anchor and the user pressed Tab + Shift (backwards)\n // -> Move to the last focusable element (end of card)\n // 4. Focus is on the last focusable element and the user pressed Tab\n // (forwards) -> Move to the anchor (top of card)\n // 5. otherwise we don't interfere\n\n if (!hasFocusableElements) {\n // case 1\n stopEvent();\n this.overlay.anchor.focus();\n return;\n }\n\n // case 2\n if (isFocusedContainer) return;\n\n const lastFocusable = focusableElements[focusableElements.length - 1];\n const isFocusedLast = event.target === lastFocusable;\n\n if (isFocusedAnchor && event.shiftKey) {\n stopEvent();\n lastFocusable.focus();\n return;\n }\n\n if (isFocusedLast && !event.shiftKey) {\n stopEvent();\n this.overlay.anchor.focus();\n return;\n }\n }\n\n /**\n * Creates the full screen overlay.\n * @private\n * @returns {CardFullScreenOverlay}\n */\n private _createOverlay(): CardFullScreenOverlay {\n const container = document.createElement(\"div\");\n container.id = Card.attr.ID_FULL_SCREEN_OVERLAY;\n container.onclick = this.exitFullScreen.bind(this);\n\n const anchor = this._createOverlayCloseAnchor();\n container.appendChild(anchor);\n\n return { container, anchor };\n }\n\n /**\n * Creates the anchor element used to exit the full screen mode.\n * @private\n * @returns {HTMLAnchorElement}\n */\n private _createOverlayCloseAnchor(): HTMLAnchorElement {\n const anchor = document.createElement(\"a\");\n anchor.classList.add(Card.attr.CLASS_FULL_SCREEN_EXIT);\n anchor.tabIndex = 0;\n anchor.onclick = () => this.exitFullScreen();\n anchor.onkeydown = (ev) => {\n if (ev.key === \"Enter\" || ev.key === \" \") {\n this.exitFullScreen();\n }\n };\n anchor.innerHTML = this._overlayCloseHtml();\n\n return anchor;\n }\n\n /**\n * Returns the HTML for the close icon.\n * @private\n * @returns {string}\n */\n private _overlayCloseHtml(): string {\n return (\n \"Close \" +\n \"\" +\n \"\"\n );\n }\n\n /**\n * The registry of card instances and their associated DOM elements.\n * @private\n * @static\n * @type {WeakMap}\n */\n private static instanceMap: WeakMap = new WeakMap();\n\n /**\n * Returns the card instance associated with the given element, if any.\n * @public\n * @static\n * @param {HTMLElement} el\n * @returns {(Card | undefined)}\n */\n public static getInstance(el: HTMLElement): Card | undefined {\n return Card.instanceMap.get(el);\n }\n\n /**\n * If cards are initialized before the DOM is ready, we re-schedule the\n * initialization to occur on DOMContentLoaded.\n * @private\n * @static\n * @type {boolean}\n */\n private static onReadyScheduled = false;\n\n /**\n * Initializes all cards that require initialization on the page, or schedules\n * initialization if the DOM is not yet ready.\n * @public\n * @static\n * @param {boolean} [flushResizeObserver=true]\n */\n public static initializeAllCards(flushResizeObserver = true): void {\n if (document.readyState === \"loading\") {\n if (!Card.onReadyScheduled) {\n Card.onReadyScheduled = true;\n document.addEventListener(\"DOMContentLoaded\", () => {\n Card.initializeAllCards(false);\n });\n }\n return;\n }\n\n if (flushResizeObserver) {\n // Trigger a recheck of observed cards to unobserve non-existent cards\n Card.shinyResizeObserver.flush();\n }\n\n const initSelector = `.${Card.attr.CLASS_CARD}[${Card.attr.ATTR_INIT}]`;\n if (!document.querySelector(initSelector)) {\n // no cards to initialize\n return;\n }\n\n const cards = document.querySelectorAll(initSelector);\n cards.forEach((card) => new Card(card as HTMLElement));\n }\n}\n\n// attach Sidebar class to window for global usage\n(window as any).bslib = (window as any).bslib || {};\n(window as any).bslib.Card = Card;\n\nexport { Card };\n", "import { InputBinding, registerBinding } from \"./_utils\";\nimport { ShinyResizeObserver } from \"./_shinyResizeObserver\";\n\n/**\n * Methods for programmatically toggling the state of the sidebar. These methods\n * describe the desired state of the sidebar: `\"close\"` and `\"open\"` transition\n * the sidebar to the desired state, unless the sidebar is already in that\n * state. `\"toggle\"` transitions the sidebar to the state opposite of its\n * current state.\n * @typedef {SidebarToggleMethod}\n */\ntype SidebarToggleMethod = \"close\" | \"open\" | \"toggle\";\n\n/**\n * Data received by the input binding's `receiveMessage` method.\n * @typedef {SidebarMessageData}\n */\ntype SidebarMessageData = {\n method: SidebarToggleMethod;\n};\n\n/**\n * The DOM elements that make up the sidebar. `main`, `sidebar`, and `toggle`\n * are all direct children of `container` (in that order).\n * @interface SidebarComponents\n * @typedef {SidebarComponents}\n */\ninterface SidebarComponents {\n /**\n * The `layout_sidebar()` parent container, with class\n * `Sidebar.classes.LAYOUT`.\n * @type {HTMLElement}\n */\n container: HTMLElement;\n /**\n * The main content area of the sidebar layout.\n * @type {HTMLElement}\n */\n main: HTMLElement;\n /**\n * The sidebar container of the sidebar layout.\n * @type {HTMLElement}\n */\n sidebar: HTMLElement;\n /**\n * The toggle button that is used to toggle the sidebar state.\n * @type {HTMLElement}\n */\n toggle: HTMLElement;\n}\n\n/**\n * The bslib sidebar component class. This class is only used for collapsible\n * sidebars.\n *\n * @class Sidebar\n * @typedef {Sidebar}\n */\nclass Sidebar {\n /**\n * The DOM elements that make up the sidebar, see `SidebarComponents`.\n * @private\n * @type {SidebarComponents}\n */\n private layout: SidebarComponents;\n\n /**\n * A Shiny-specific resize observer that ensures Shiny outputs in the main\n * content areas of the sidebar resize appropriately.\n * @private\n * @type {ShinyResizeObserver}\n * @static\n */\n private static shinyResizeObserver = new ShinyResizeObserver();\n\n /**\n * Creates an instance of a collapsible bslib Sidebar.\n * @constructor\n * @param {HTMLElement} container\n */\n constructor(container: HTMLElement) {\n Sidebar.instanceMap.set(container, this);\n this.layout = {\n container,\n main: container.querySelector(\":scope > .main\") as HTMLElement,\n sidebar: container.querySelector(\":scope > .sidebar\") as HTMLElement,\n toggle: container.querySelector(\n \":scope > .collapse-toggle\"\n ) as HTMLElement,\n } as SidebarComponents;\n\n const sideAccordion = this.layout.sidebar.querySelector(\n \":scope > .sidebar-content > .accordion\"\n );\n if (sideAccordion) {\n // Add `.has-accordion` class to `.sidebar-content` container\n sideAccordion?.parentElement?.classList.add(\"has-accordion\");\n sideAccordion.classList.add(\"accordion-flush\");\n }\n\n if (this.layout.toggle) {\n this._initEventListeners();\n this._initSidebarCounters();\n this._initDesktop();\n }\n\n // Start watching the main content area for size changes to ensure Shiny\n // outputs resize appropriately during sidebar transitions.\n Sidebar.shinyResizeObserver.observe(this.layout.main);\n\n container.removeAttribute(\"data-bslib-sidebar-init\");\n const initScript = container.querySelector(\n \":scope > script[data-bslib-sidebar-init]\"\n );\n if (initScript) {\n container.removeChild(initScript);\n }\n }\n\n /**\n * Read the current state of the sidebar. Note that, when calling this method,\n * the sidebar may be transitioning into the state returned by this method.\n *\n * @description\n * The sidebar state works as follows, starting from the open state. When the\n * sidebar is closed:\n * 1. We add both the `COLLAPSE` and `TRANSITIONING` classes to the sidebar.\n * 2. The sidebar collapse begins to animate. On desktop devices, and where it\n * is supported, we transition the `grid-template-columns` property of the\n * sidebar layout. On mobile, the sidebar is hidden immediately. In both\n * cases, the collapse icon rotates and we use this rotation to determine\n * when the transition is complete.\n * 3. If another sidebar state toggle is requested while closing the sidebar,\n * we remove the `COLLAPSE` class and the animation immediately starts to\n * reverse.\n * 4. When the `transition` is complete, we remove the `TRANSITIONING` class.\n * @readonly\n * @type {boolean}\n */\n get isClosed(): boolean {\n return this.layout.container.classList.contains(Sidebar.classes.COLLAPSE);\n }\n\n /**\n * Static classes related to the sidebar layout or state.\n * @public\n * @static\n * @readonly\n * @type {{ LAYOUT: string; COLLAPSE: string; TRANSITIONING: string; }}\n */\n public static readonly classes = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n LAYOUT: \"bslib-sidebar-layout\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n COLLAPSE: \"sidebar-collapsed\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n TRANSITIONING: \"transitioning\",\n };\n\n /**\n * If sidebars are initialized before the DOM is ready, we re-schedule the\n * initialization to occur on DOMContentLoaded.\n * @private\n * @static\n * @type {boolean}\n */\n private static onReadyScheduled = false;\n /**\n * A map of initialized sidebars to their respective Sidebar instances.\n * @private\n * @static\n * @type {WeakMap}\n */\n private static instanceMap: WeakMap = new WeakMap();\n\n /**\n * Given a sidebar container, return the Sidebar instance associated with it.\n * @public\n * @static\n * @param {HTMLElement} el\n * @returns {(Sidebar | undefined)}\n */\n public static getInstance(el: HTMLElement): Sidebar | undefined {\n return Sidebar.instanceMap.get(el);\n }\n\n /**\n * Initialize all collapsible sidebars on the page.\n * @public\n * @static\n * @param {boolean} [flushResizeObserver=true] When `true`, we remove\n * non-existent elements from the ResizeObserver. This is required\n * periodically to prevent memory leaks. To avoid over-checking, we only flush\n * the ResizeObserver when initializing sidebars after page load.\n */\n public static initCollapsibleAll(flushResizeObserver = true): void {\n if (document.readyState === \"loading\") {\n if (!Sidebar.onReadyScheduled) {\n Sidebar.onReadyScheduled = true;\n document.addEventListener(\"DOMContentLoaded\", () => {\n Sidebar.initCollapsibleAll(false);\n });\n }\n return;\n }\n\n const initSelector = `.${Sidebar.classes.LAYOUT}[data-bslib-sidebar-init]`;\n if (!document.querySelector(initSelector)) {\n // no sidebars to initialize\n return;\n }\n\n if (flushResizeObserver) Sidebar.shinyResizeObserver.flush();\n\n const containers = document.querySelectorAll(initSelector);\n containers.forEach((container) => new Sidebar(container as HTMLElement));\n }\n\n /**\n * Initialize event listeners for the sidebar toggle button.\n * @private\n */\n private _initEventListeners(): void {\n const { toggle } = this.layout;\n\n toggle.addEventListener(\"click\", (ev) => {\n ev.preventDefault();\n this.toggle(\"toggle\");\n });\n\n // Remove the transitioning class when the transition ends. We watch the\n // collapse toggle icon because it's guaranteed to transition, whereas the\n // sidebar doesn't animate on mobile (or in browsers where animating\n // grid-template-columns is not supported).\n toggle\n .querySelector(\".collapse-icon\")\n ?.addEventListener(\"transitionend\", () => this._finalizeState());\n }\n\n /**\n * Initialize nested sidebar counters.\n *\n * @description\n * This function walks up the DOM tree, adding CSS variables to each direct\n * parent sidebar layout that count the layout's position in the stack of\n * nested layouts. We use these counters to keep the collapse toggles from\n * overlapping. Note that always-open sidebars that don't have collapse\n * toggles break the chain of nesting.\n * @private\n */\n private _initSidebarCounters(): void {\n const { container } = this.layout;\n\n const selectorChildLayouts =\n `.${Sidebar.classes.LAYOUT}` +\n \"> .main > \" +\n `.${Sidebar.classes.LAYOUT}:not([data-bslib-sidebar-open=\"always\"])`;\n\n const isInnermostLayout =\n container.querySelector(selectorChildLayouts) === null;\n\n if (!isInnermostLayout) {\n // There are sidebar layouts nested within this layout; defer to children\n return;\n }\n\n function nextSidebarParent(el: HTMLElement | null): HTMLElement | null {\n el = el ? el.parentElement : null;\n if (el && el.classList.contains(\"main\")) {\n // .bslib-sidebar-layout > .main > .bslib-sidebar-layout\n el = el.parentElement;\n }\n if (el && el.classList.contains(Sidebar.classes.LAYOUT)) {\n return el;\n }\n return null;\n }\n\n const layouts = [container];\n let parent = nextSidebarParent(container);\n\n while (parent) {\n // Add parent to front of layouts array, so we sort outer -> inner\n layouts.unshift(parent);\n parent = nextSidebarParent(parent);\n }\n\n const count = { left: 0, right: 0 };\n layouts.forEach(function (x: HTMLElement, i: number): void {\n x.style.setProperty(\"--bslib-sidebar-counter\", i.toString());\n const isRight = x.classList.contains(\"sidebar-right\");\n const thisCount = isRight ? count.right++ : count.left++;\n x.style.setProperty(\n \"--bslib-sidebar-overlap-counter\",\n thisCount.toString()\n );\n });\n }\n\n /**\n * Initialize the sidebar's initial state when `open = \"desktop\"`.\n * @private\n */\n private _initDesktop(): void {\n const { container } = this.layout;\n // If sidebar is marked open='desktop'...\n if (container.dataset.bslibSidebarOpen?.trim() !== \"desktop\") {\n return;\n }\n\n // then close sidebar on mobile\n const initCollapsed = window\n .getComputedStyle(container)\n .getPropertyValue(\"--bslib-sidebar-js-init-collapsed\");\n\n if (initCollapsed.trim() === \"true\") {\n this.toggle(\"close\");\n }\n }\n\n /**\n * Toggle the sidebar's open/closed state.\n * @public\n * @param {SidebarToggleMethod | undefined} method Whether to `\"open\"`,\n * `\"close\"` or `\"toggle\"` the sidebar. If `.toggle()` is called without an\n * argument, it will toggle the sidebar's state.\n */\n public toggle(method: SidebarToggleMethod | undefined): void {\n if (typeof method === \"undefined\") {\n method = \"toggle\";\n }\n\n const { container, sidebar } = this.layout;\n const isClosed = this.isClosed;\n\n if ([\"open\", \"close\", \"toggle\"].indexOf(method) === -1) {\n throw new Error(`Unknown method ${method}`);\n }\n\n if (method === \"toggle\") {\n method = isClosed ? \"open\" : \"close\";\n }\n\n if ((isClosed && method === \"close\") || (!isClosed && method === \"open\")) {\n // nothing to do, sidebar is already in the desired state\n return;\n }\n\n if (method === \"open\") {\n // unhide sidebar immediately when opening,\n // otherwise the sidebar is hidden on transitionend\n sidebar.hidden = false;\n }\n\n // Add a transitioning class just before adding COLLAPSE_CLASS since we want\n // some of the transitioning styles to apply before the collapse state\n container.classList.add(Sidebar.classes.TRANSITIONING);\n container.classList.toggle(Sidebar.classes.COLLAPSE);\n }\n\n /**\n * When the sidebar open/close transition ends, finalize the sidebar's state.\n * @private\n */\n private _finalizeState(): void {\n const { container, sidebar, toggle } = this.layout;\n container.classList.remove(Sidebar.classes.TRANSITIONING);\n sidebar.hidden = this.isClosed;\n toggle.setAttribute(\"aria-expanded\", this.isClosed ? \"false\" : \"true\");\n\n // Send browser-native event with updated sidebar state\n const event = new CustomEvent(\"bslib.sidebar\", {\n bubbles: true,\n detail: { open: !this.isClosed },\n });\n sidebar.dispatchEvent(event);\n\n // Trigger Shiny input and output binding events\n $(sidebar).trigger(\"toggleCollapse.sidebarInputBinding\");\n $(sidebar).trigger(this.isClosed ? \"hidden\" : \"shown\");\n }\n}\n\n/**\n * A Shiny input binding for a sidebar.\n * @class SidebarInputBinding\n * @typedef {SidebarInputBinding}\n * @extends {InputBinding}\n */\nclass SidebarInputBinding extends InputBinding {\n find(scope: HTMLElement) {\n return $(scope).find(`.${Sidebar.classes.LAYOUT} > .bslib-sidebar-input`);\n }\n\n getValue(el: HTMLElement): boolean {\n const sb = Sidebar.getInstance(el.parentElement as HTMLElement);\n if (!sb) return false;\n return !sb.isClosed;\n }\n\n setValue(el: HTMLElement, value: boolean): void {\n const method = value ? \"open\" : \"close\";\n this.receiveMessage(el, { method });\n }\n\n subscribe(el: HTMLElement, callback: (x: boolean) => void) {\n $(el).on(\n \"toggleCollapse.sidebarInputBinding\",\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function (event) {\n callback(true);\n }\n );\n }\n\n unsubscribe(el: HTMLElement) {\n $(el).off(\".sidebarInputBinding\");\n }\n\n receiveMessage(el: HTMLElement, data: SidebarMessageData) {\n const sb = Sidebar.getInstance(el.parentElement as HTMLElement);\n if (sb) sb.toggle(data.method);\n }\n}\n\nregisterBinding(SidebarInputBinding, \"sidebar\");\n\n// attach Sidebar class to window for global usage\n(window as any).bslib = (window as any).bslib || {};\n(window as any).bslib.Sidebar = Sidebar;\n", "import type { Handler as ShinyCustomMessageHandler } from \"rstudio-shiny/srcts/types/src/shiny/shinyapp\";\n\nexport function shinyAddCustomMessageHandlers(handlers: {\n [key: string]: ShinyCustomMessageHandler;\n}): void {\n if (!window.Shiny) {\n return;\n }\n\n for (const [name, handler] of Object.entries(handlers)) {\n Shiny.addCustomMessageHandler(name, handler);\n }\n}\n", "// ----------------------------------------------------------------------------\n// First, bring in non-webcomponent (legacy) components (they attach to the window)\n// ----------------------------------------------------------------------------\nimport \"./accordion\";\nimport \"./card\";\nimport \"./sidebar\";\n\n// ----------------------------------------------------------------------------\n// Register custom message handlers for Shiny\n// ----------------------------------------------------------------------------\nimport { InputBinding } from \"./_utils\";\nimport { shinyAddCustomMessageHandlers } from \"./_shinyAddCustomMessageHandlers\";\n\nconst bslibMessageHandlers = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n \"bslib.toggle-input-binary\": (msg: any) => {\n // This handler was written for `toggle_switch()`, but could be used for any\n // binary Shiny input, e.g. checkbox.\n const el = document.getElementById(msg.id) as HTMLElement;\n if (!el) {\n console.warn(\"[bslib.toggle-input-binary] No element found\", msg);\n }\n\n const binding = $(el).data(\"shiny-input-binding\");\n if (!(binding instanceof InputBinding)) {\n console.warn(\"[bslib.toggle-input-binary] No input binding found\", msg);\n return;\n }\n\n let value = msg.value;\n if (typeof value === \"undefined\") {\n value = !binding.getValue(el);\n }\n binding.receiveMessage(el, { value });\n },\n};\n\nif (window.Shiny) {\n shinyAddCustomMessageHandlers(bslibMessageHandlers);\n}\n\n// ----------------------------------------------------------------------\n// Append the (global) SVG linearGradient to the body.\n// value_box() uses this (i.e., bslib---icon-gradient element) to apply a\n// gradient to the icon when bs_theme(preset=\"shiny\").\n// ----------------------------------------------------------------------\n\nfunction insertSvgGradient() {\n const temp = document.createElement(\"div\");\n temp.innerHTML = `\n \n \n \n \n \n \n \n \n \n \n \n `;\n document.body.appendChild(temp.children[0] as Node);\n}\n\nif (document.readyState === \"complete\") {\n insertSvgGradient();\n} else {\n document.addEventListener(\"DOMContentLoaded\", insertSvgGradient);\n}\n"], + "mappings": "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", + "names": ["InputBinding", "registerBinding", "inputBindingClass", "name", "hasDefinedProperty", "obj", "prop", "getAllFocusableChildren", "el", "base", "modifiers", "selectors", "b", "focusable", "AccordionInputBinding", "InputBinding", "scope", "el", "selected", "x", "callback", "event", "data", "method", "items", "vals", "targetItem", "panel", "val", "targetItems", "unbindAll", "target", "hasDefinedProperty", "body", "header", "title", "icon", "collapse", "isOpen", "values", "value", "registerBinding", "ShinyResizeObserver", "entries", "resizeEvent", "resized", "entry", "el", "binding", "onResize", "owner", "img", "idxEl", "_Card", "card", "_a", "event", "btnFullScreen", "ev", "selOpenSelectInput", "isFocusedContainer", "isFocusedAnchor", "isFocusedWithin", "stopEvent", "focusableElements", "getAllFocusableChildren", "el", "lastFocusable", "isFocusedLast", "container", "anchor", "flushResizeObserver", "initSelector", "Card", "ShinyResizeObserver", "_Sidebar", "container", "_a", "sideAccordion", "initScript", "el", "flushResizeObserver", "initSelector", "toggle", "ev", "selectorChildLayouts", "nextSidebarParent", "layouts", "parent", "count", "x", "i", "thisCount", "method", "sidebar", "isClosed", "event", "Sidebar", "ShinyResizeObserver", "SidebarInputBinding", "InputBinding", "scope", "sb", "value", "callback", "data", "registerBinding", "shinyAddCustomMessageHandlers", "handlers", "name", "handler", "bslibMessageHandlers", "msg", "el", "binding", "InputBinding", "value", "shinyAddCustomMessageHandlers", "insertSvgGradient", "temp"] +} diff --git a/inst/components/dist/grid/grid.css b/inst/components/dist/grid/grid.css deleted file mode 100644 index 5552d0a44..000000000 --- a/inst/components/dist/grid/grid.css +++ /dev/null @@ -1 +0,0 @@ -.bslib-grid{display:grid !important;gap:var(--bslib-spacer, 1rem);height:var(--bslib-grid-height)}.bslib-grid.grid{grid-template-columns:repeat(var(--bs-columns, 12), minmax(0, 1fr));grid-template-rows:unset;grid-auto-rows:var(--bslib-grid--row-heights);--bslib-grid--row-heights--xs: unset;--bslib-grid--row-heights--sm: unset;--bslib-grid--row-heights--md: unset;--bslib-grid--row-heights--lg: unset;--bslib-grid--row-heights--xl: unset;--bslib-grid--row-heights--xxl: unset}.bslib-grid.grid.bslib-grid--row-heights--xs{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xs)}@media (min-width: 576px){.bslib-grid.grid.bslib-grid--row-heights--sm{--bslib-grid--row-heights: var(--bslib-grid--row-heights--sm)}}@media (min-width: 768px){.bslib-grid.grid.bslib-grid--row-heights--md{--bslib-grid--row-heights: var(--bslib-grid--row-heights--md)}}@media (min-width: 992px){.bslib-grid.grid.bslib-grid--row-heights--lg{--bslib-grid--row-heights: var(--bslib-grid--row-heights--lg)}}@media (min-width: 1200px){.bslib-grid.grid.bslib-grid--row-heights--xl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xl)}}@media (min-width: 1400px){.bslib-grid.grid.bslib-grid--row-heights--xxl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xxl)}}.bslib-grid>*>.shiny-input-container{width:100%}.bslib-grid-item{grid-column:auto/span 1}@media (max-width: 767.98px){.bslib-grid-item{grid-column:1 / -1}}@media (max-width: 575.98px){.bslib-grid{grid-template-columns:1fr !important;height:var(--bslib-grid-height-mobile)}.bslib-grid.grid{height:unset !important;grid-auto-rows:var(--bslib-grid--row-heights--xs, auto)}} diff --git a/inst/components/dist/nav_spacer/nav_spacer.css b/inst/components/dist/nav_spacer/nav_spacer.css deleted file mode 100644 index be42a4f9e..000000000 --- a/inst/components/dist/nav_spacer/nav_spacer.css +++ /dev/null @@ -1 +0,0 @@ -@media (min-width: 576px){.nav:not(.nav-hidden){display:flex !important;display:-webkit-flex !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column){float:none !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.bslib-nav-spacer{margin-left:auto !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.form-inline{margin-top:auto;margin-bottom:auto}.nav:not(.nav-hidden).nav-stacked{flex-direction:column;-webkit-flex-direction:column;height:100%}.nav:not(.nav-hidden).nav-stacked>.bslib-nav-spacer{margin-top:auto !important}} diff --git a/inst/components/dist/page_fillable/page_fillable.css b/inst/components/dist/page_fillable/page_fillable.css deleted file mode 100644 index b4a492c79..000000000 --- a/inst/components/dist/page_fillable/page_fillable.css +++ /dev/null @@ -1 +0,0 @@ -html{height:100%}.bslib-page-fill{width:100%;height:100%;margin:0;padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}@media (max-width: 575.98px){.bslib-page-fill{height:var(--bslib-page-fill-mobile-height, auto)}} diff --git a/inst/components/dist/page_navbar/page_navbar.css b/inst/components/dist/page_navbar/page_navbar.css deleted file mode 100644 index fca340be7..000000000 --- a/inst/components/dist/page_navbar/page_navbar.css +++ /dev/null @@ -1 +0,0 @@ -.navbar+.container-fluid:has(>.tab-content>.tab-pane.active.html-fill-container){padding-left:0;padding-right:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container{padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child){padding:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border="true"]){border-left:none;border-right:none;border-bottom:none}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius="true"]){border-radius:0}.navbar+div>.bslib-sidebar-layout{border-top:var(--bslib-sidebar-border)} diff --git a/inst/components/dist/page_sidebar/page_sidebar.css b/inst/components/dist/page_sidebar/page_sidebar.css deleted file mode 100644 index 1c05eb278..000000000 --- a/inst/components/dist/page_sidebar/page_sidebar.css +++ /dev/null @@ -1 +0,0 @@ -:root{--bslib-page-sidebar-title-bg: #202020;--bslib-page-sidebar-title-color: #fff}.bslib-page-title{background-color:var(--bslib-page-sidebar-title-bg);color:var(--bslib-page-sidebar-title-color);font-size:1.5rem;font-weight:300;padding:var(--bslib-spacer, 1rem);padding-left:1.5rem;margin-bottom:0;border-bottom:1px solid #dee2e6} diff --git a/inst/components/dist/sidebar/sidebar.js b/inst/components/dist/sidebar/sidebar.js deleted file mode 100644 index 79437ee05..000000000 --- a/inst/components/dist/sidebar/sidebar.js +++ /dev/null @@ -1,412 +0,0 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ -"use strict"; -(() => { - // srcts/src/components/_utils.ts - var InputBinding = window.Shiny ? Shiny.InputBinding : class { - }; - function registerBinding(inputBindingClass, name) { - if (window.Shiny) { - Shiny.inputBindings.register(new inputBindingClass(), "bslib." + name); - } - } - - // srcts/src/components/_shinyResizeObserver.ts - var ShinyResizeObserver = class { - /** - * Watch containers for size changes and ensure that Shiny outputs and - * htmlwidgets within resize appropriately. - * - * @details - * The ShinyResizeObserver is used to watch the containers, such as Sidebars - * and Cards for size changes, in particular when the sidebar state is toggled - * or the card body is expanded full screen. It performs two primary tasks: - * - * 1. Dispatches a `resize` event on the window object. This is necessary to - * ensure that Shiny outputs resize appropriately. In general, the window - * resizing is throttled and the output update occurs when the transition - * is complete. - * 2. If an output with a resize method on the output binding is detected, we - * directly call the `.onResize()` method of the binding. This ensures that - * htmlwidgets transition smoothly. In static mode, htmlwidgets does this - * already. - * - * @note - * This resize observer also handles race conditions in some complex - * fill-based layouts with multiple outputs (e.g., plotly), where shiny - * initializes with the correct sizing, but in-between the 1st and last - * renderValue(), the size of the output containers can change, meaning every - * output but the 1st gets initialized with the wrong size during their - * renderValue(). Then, after the render phase, shiny won't know to trigger a - * resize since all the widgets will return to their original size (and thus, - * Shiny thinks there isn't any resizing to do). The resize observer works - * around this by ensuring that the output is resized whenever its container - * size changes. - * @constructor - */ - constructor() { - this.resizeObserverEntries = []; - this.resizeObserver = new ResizeObserver((entries) => { - const resizeEvent = new Event("resize"); - window.dispatchEvent(resizeEvent); - if (!window.Shiny) - return; - const resized = []; - for (const entry of entries) { - if (!(entry.target instanceof HTMLElement)) - continue; - if (!entry.target.querySelector(".shiny-bound-output")) - continue; - entry.target.querySelectorAll(".shiny-bound-output").forEach((el) => { - if (resized.includes(el)) - return; - const { binding, onResize } = $(el).data("shinyOutputBinding"); - if (!binding || !binding.resize) - return; - const owner = el.shinyResizeObserver; - if (owner && owner !== this) - return; - if (!owner) - el.shinyResizeObserver = this; - onResize(el); - resized.push(el); - if (!el.classList.contains("shiny-plot-output")) - return; - const img = el.querySelector( - 'img:not([width="100%"])' - ); - if (img) - img.setAttribute("width", "100%"); - }); - } - }); - } - /** - * Observe an element for size changes. - * @param {HTMLElement} el - The element to observe. - */ - observe(el) { - this.resizeObserver.observe(el); - this.resizeObserverEntries.push(el); - } - /** - * Stop observing an element for size changes. - * @param {HTMLElement} el - The element to stop observing. - */ - unobserve(el) { - const idxEl = this.resizeObserverEntries.indexOf(el); - if (idxEl < 0) - return; - this.resizeObserver.unobserve(el); - this.resizeObserverEntries.splice(idxEl, 1); - } - /** - * This method checks that we're not continuing to watch elements that no - * longer exist in the DOM. If any are found, we stop observing them and - * remove them from our array of observed elements. - * - * @private - * @static - */ - flush() { - this.resizeObserverEntries.forEach((el) => { - if (!document.body.contains(el)) - this.unobserve(el); - }); - } - }; - - // srcts/src/components/sidebar.ts - var _Sidebar = class { - /** - * Creates an instance of a collapsible bslib Sidebar. - * @constructor - * @param {HTMLElement} container - */ - constructor(container) { - var _a; - _Sidebar.instanceMap.set(container, this); - this.layout = { - container, - main: container.querySelector(":scope > .main"), - sidebar: container.querySelector(":scope > .sidebar"), - toggle: container.querySelector( - ":scope > .collapse-toggle" - ) - }; - const sideAccordion = this.layout.sidebar.querySelector( - ":scope > .sidebar-content > .accordion" - ); - if (sideAccordion) { - (_a = sideAccordion == null ? void 0 : sideAccordion.parentElement) == null ? void 0 : _a.classList.add("has-accordion"); - sideAccordion.classList.add("accordion-flush"); - } - if (this.layout.toggle) { - this._initEventListeners(); - this._initSidebarCounters(); - this._initDesktop(); - } - _Sidebar.shinyResizeObserver.observe(this.layout.main); - container.removeAttribute("data-bslib-sidebar-init"); - const initScript = container.querySelector( - ":scope > script[data-bslib-sidebar-init]" - ); - if (initScript) { - container.removeChild(initScript); - } - } - /** - * Read the current state of the sidebar. Note that, when calling this method, - * the sidebar may be transitioning into the state returned by this method. - * - * @description - * The sidebar state works as follows, starting from the open state. When the - * sidebar is closed: - * 1. We add both the `COLLAPSE` and `TRANSITIONING` classes to the sidebar. - * 2. The sidebar collapse begins to animate. On desktop devices, and where it - * is supported, we transition the `grid-template-columns` property of the - * sidebar layout. On mobile, the sidebar is hidden immediately. In both - * cases, the collapse icon rotates and we use this rotation to determine - * when the transition is complete. - * 3. If another sidebar state toggle is requested while closing the sidebar, - * we remove the `COLLAPSE` class and the animation immediately starts to - * reverse. - * 4. When the `transition` is complete, we remove the `TRANSITIONING` class. - * @readonly - * @type {boolean} - */ - get isClosed() { - return this.layout.container.classList.contains(_Sidebar.classes.COLLAPSE); - } - /** - * Given a sidebar container, return the Sidebar instance associated with it. - * @public - * @static - * @param {HTMLElement} el - * @returns {(Sidebar | undefined)} - */ - static getInstance(el) { - return _Sidebar.instanceMap.get(el); - } - /** - * Initialize all collapsible sidebars on the page. - * @public - * @static - * @param {boolean} [flushResizeObserver=true] When `true`, we remove - * non-existent elements from the ResizeObserver. This is required - * periodically to prevent memory leaks. To avoid over-checking, we only flush - * the ResizeObserver when initializing sidebars after page load. - */ - static initCollapsibleAll(flushResizeObserver = true) { - if (document.readyState === "loading") { - if (!_Sidebar.onReadyScheduled) { - _Sidebar.onReadyScheduled = true; - document.addEventListener("DOMContentLoaded", () => { - _Sidebar.initCollapsibleAll(false); - }); - } - return; - } - const initSelector = `.${_Sidebar.classes.LAYOUT}[data-bslib-sidebar-init]`; - if (!document.querySelector(initSelector)) { - return; - } - if (flushResizeObserver) - _Sidebar.shinyResizeObserver.flush(); - const containers = document.querySelectorAll(initSelector); - containers.forEach((container) => new _Sidebar(container)); - } - /** - * Initialize event listeners for the sidebar toggle button. - * @private - */ - _initEventListeners() { - var _a; - const { toggle } = this.layout; - toggle.addEventListener("click", (ev) => { - ev.preventDefault(); - this.toggle("toggle"); - }); - (_a = toggle.querySelector(".collapse-icon")) == null ? void 0 : _a.addEventListener("transitionend", () => this._finalizeState()); - } - /** - * Initialize nested sidebar counters. - * - * @description - * This function walks up the DOM tree, adding CSS variables to each direct - * parent sidebar layout that count the layout's position in the stack of - * nested layouts. We use these counters to keep the collapse toggles from - * overlapping. Note that always-open sidebars that don't have collapse - * toggles break the chain of nesting. - * @private - */ - _initSidebarCounters() { - const { container } = this.layout; - const selectorChildLayouts = `.${_Sidebar.classes.LAYOUT}> .main > .${_Sidebar.classes.LAYOUT}:not([data-bslib-sidebar-open="always"])`; - const isInnermostLayout = container.querySelector(selectorChildLayouts) === null; - if (!isInnermostLayout) { - return; - } - function nextSidebarParent(el) { - el = el ? el.parentElement : null; - if (el && el.classList.contains("main")) { - el = el.parentElement; - } - if (el && el.classList.contains(_Sidebar.classes.LAYOUT)) { - return el; - } - return null; - } - const layouts = [container]; - let parent = nextSidebarParent(container); - while (parent) { - layouts.unshift(parent); - parent = nextSidebarParent(parent); - } - const count = { left: 0, right: 0 }; - layouts.forEach(function(x, i) { - x.style.setProperty("--bslib-sidebar-counter", i.toString()); - const isRight = x.classList.contains("sidebar-right"); - const thisCount = isRight ? count.right++ : count.left++; - x.style.setProperty( - "--bslib-sidebar-overlap-counter", - thisCount.toString() - ); - }); - } - /** - * Initialize the sidebar's initial state when `open = "desktop"`. - * @private - */ - _initDesktop() { - var _a; - const { container } = this.layout; - if (((_a = container.dataset.bslibSidebarOpen) == null ? void 0 : _a.trim()) !== "desktop") { - return; - } - const initCollapsed = window.getComputedStyle(container).getPropertyValue("--bslib-sidebar-js-init-collapsed"); - if (initCollapsed.trim() === "true") { - this.toggle("close"); - } - } - /** - * Toggle the sidebar's open/closed state. - * @public - * @param {SidebarToggleMethod | undefined} method Whether to `"open"`, - * `"close"` or `"toggle"` the sidebar. If `.toggle()` is called without an - * argument, it will toggle the sidebar's state. - */ - toggle(method) { - if (typeof method === "undefined") { - method = "toggle"; - } - const { container, sidebar } = this.layout; - const isClosed = this.isClosed; - if (["open", "close", "toggle"].indexOf(method) === -1) { - throw new Error(`Unknown method ${method}`); - } - if (method === "toggle") { - method = isClosed ? "open" : "close"; - } - if (isClosed && method === "close" || !isClosed && method === "open") { - return; - } - if (method === "open") { - sidebar.hidden = false; - } - container.classList.add(_Sidebar.classes.TRANSITIONING); - container.classList.toggle(_Sidebar.classes.COLLAPSE); - } - /** - * When the sidebar open/close transition ends, finalize the sidebar's state. - * @private - */ - _finalizeState() { - const { container, sidebar, toggle } = this.layout; - container.classList.remove(_Sidebar.classes.TRANSITIONING); - sidebar.hidden = this.isClosed; - toggle.setAttribute("aria-expanded", this.isClosed ? "false" : "true"); - const event = new CustomEvent("bslib.sidebar", { - bubbles: true, - detail: { open: !this.isClosed } - }); - sidebar.dispatchEvent(event); - $(sidebar).trigger("toggleCollapse.sidebarInputBinding"); - $(sidebar).trigger(this.isClosed ? "hidden" : "shown"); - } - }; - var Sidebar = _Sidebar; - /** - * A Shiny-specific resize observer that ensures Shiny outputs in the main - * content areas of the sidebar resize appropriately. - * @private - * @type {ShinyResizeObserver} - * @static - */ - Sidebar.shinyResizeObserver = new ShinyResizeObserver(); - /** - * Static classes related to the sidebar layout or state. - * @public - * @static - * @readonly - * @type {{ LAYOUT: string; COLLAPSE: string; TRANSITIONING: string; }} - */ - Sidebar.classes = { - // eslint-disable-next-line @typescript-eslint/naming-convention - LAYOUT: "bslib-sidebar-layout", - // eslint-disable-next-line @typescript-eslint/naming-convention - COLLAPSE: "sidebar-collapsed", - // eslint-disable-next-line @typescript-eslint/naming-convention - TRANSITIONING: "transitioning" - }; - /** - * If sidebars are initialized before the DOM is ready, we re-schedule the - * initialization to occur on DOMContentLoaded. - * @private - * @static - * @type {boolean} - */ - Sidebar.onReadyScheduled = false; - /** - * A map of initialized sidebars to their respective Sidebar instances. - * @private - * @static - * @type {WeakMap} - */ - Sidebar.instanceMap = /* @__PURE__ */ new WeakMap(); - var SidebarInputBinding = class extends InputBinding { - find(scope) { - return $(scope).find(`.${Sidebar.classes.LAYOUT} > .bslib-sidebar-input`); - } - getValue(el) { - const sb = Sidebar.getInstance(el.parentElement); - if (!sb) - return false; - return !sb.isClosed; - } - setValue(el, value) { - const method = value ? "open" : "close"; - this.receiveMessage(el, { method }); - } - subscribe(el, callback) { - $(el).on( - "toggleCollapse.sidebarInputBinding", - // eslint-disable-next-line @typescript-eslint/no-unused-vars - function(event) { - callback(true); - } - ); - } - unsubscribe(el) { - $(el).off(".sidebarInputBinding"); - } - receiveMessage(el, data) { - const sb = Sidebar.getInstance(el.parentElement); - if (sb) - sb.toggle(data.method); - } - }; - registerBinding(SidebarInputBinding, "sidebar"); - window.bslib = window.bslib || {}; - window.bslib.Sidebar = Sidebar; -})(); -//# sourceMappingURL=sidebar.js.map diff --git a/inst/components/dist/sidebar/sidebar.js.map b/inst/components/dist/sidebar/sidebar.js.map deleted file mode 100644 index 7e5910ad5..000000000 --- a/inst/components/dist/sidebar/sidebar.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../srcts/src/components/_utils.ts", "../../../../srcts/src/components/_shinyResizeObserver.ts", "../../../../srcts/src/components/sidebar.ts"], - "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "/**\n * A resize observer that ensures Shiny outputs resize during or just after\n * their parent container size changes. Useful, in particular, for sidebar\n * transitions or for full-screen card transitions.\n *\n * @class ShinyResizeObserver\n * @typedef {ShinyResizeObserver}\n */\nclass ShinyResizeObserver {\n /**\n * The actual ResizeObserver instance.\n * @private\n * @type {ResizeObserver}\n */\n private resizeObserver: ResizeObserver;\n /**\n * An array of elements that are currently being watched by the Resize\n * Observer.\n *\n * @details\n * We don't currently have lifecycle hooks that allow us to unobserve elements\n * when they are removed from the DOM. As a result, we need to manually check\n * that the elements we're watching still exist in the DOM. This array keeps\n * track of the elements we're watching so that we can check them later.\n * @private\n * @type {HTMLElement[]}\n */\n private resizeObserverEntries: HTMLElement[];\n\n /**\n * Watch containers for size changes and ensure that Shiny outputs and\n * htmlwidgets within resize appropriately.\n *\n * @details\n * The ShinyResizeObserver is used to watch the containers, such as Sidebars\n * and Cards for size changes, in particular when the sidebar state is toggled\n * or the card body is expanded full screen. It performs two primary tasks:\n *\n * 1. Dispatches a `resize` event on the window object. This is necessary to\n * ensure that Shiny outputs resize appropriately. In general, the window\n * resizing is throttled and the output update occurs when the transition\n * is complete.\n * 2. If an output with a resize method on the output binding is detected, we\n * directly call the `.onResize()` method of the binding. This ensures that\n * htmlwidgets transition smoothly. In static mode, htmlwidgets does this\n * already.\n *\n * @note\n * This resize observer also handles race conditions in some complex\n * fill-based layouts with multiple outputs (e.g., plotly), where shiny\n * initializes with the correct sizing, but in-between the 1st and last\n * renderValue(), the size of the output containers can change, meaning every\n * output but the 1st gets initialized with the wrong size during their\n * renderValue(). Then, after the render phase, shiny won't know to trigger a\n * resize since all the widgets will return to their original size (and thus,\n * Shiny thinks there isn't any resizing to do). The resize observer works\n * around this by ensuring that the output is resized whenever its container\n * size changes.\n * @constructor\n */\n constructor() {\n this.resizeObserverEntries = [];\n this.resizeObserver = new ResizeObserver((entries) => {\n const resizeEvent = new Event(\"resize\");\n window.dispatchEvent(resizeEvent);\n\n // the rest of this callback is only relevant in Shiny apps\n if (!window.Shiny) return;\n\n const resized = [] as HTMLElement[];\n\n for (const entry of entries) {\n if (!(entry.target instanceof HTMLElement)) continue;\n if (!entry.target.querySelector(\".shiny-bound-output\")) continue;\n\n entry.target\n .querySelectorAll(\".shiny-bound-output\")\n .forEach((el) => {\n if (resized.includes(el)) return;\n\n const { binding, onResize } = $(el).data(\"shinyOutputBinding\");\n if (!binding || !binding.resize) return;\n\n // if this output is owned by another observer, skip it\n const owner = (el as any).shinyResizeObserver;\n if (owner && owner !== this) return;\n // mark this output as owned by this shinyResizeObserver instance\n if (!owner) (el as any).shinyResizeObserver = this;\n\n // trigger immediate resizing of outputs with a resize method\n onResize(el);\n // only once per output and resize event\n resized.push(el);\n\n // set plot images to 100% width temporarily during the transition\n if (!el.classList.contains(\"shiny-plot-output\")) return;\n const img = el.querySelector(\n 'img:not([width=\"100%\"])'\n );\n if (img) img.setAttribute(\"width\", \"100%\");\n });\n }\n });\n }\n\n /**\n * Observe an element for size changes.\n * @param {HTMLElement} el - The element to observe.\n */\n observe(el: HTMLElement): void {\n this.resizeObserver.observe(el);\n this.resizeObserverEntries.push(el);\n }\n\n /**\n * Stop observing an element for size changes.\n * @param {HTMLElement} el - The element to stop observing.\n */\n unobserve(el: HTMLElement): void {\n const idxEl = this.resizeObserverEntries.indexOf(el);\n if (idxEl < 0) return;\n\n this.resizeObserver.unobserve(el);\n this.resizeObserverEntries.splice(idxEl, 1);\n }\n\n /**\n * This method checks that we're not continuing to watch elements that no\n * longer exist in the DOM. If any are found, we stop observing them and\n * remove them from our array of observed elements.\n *\n * @private\n * @static\n */\n flush(): void {\n this.resizeObserverEntries.forEach((el) => {\n if (!document.body.contains(el)) this.unobserve(el);\n });\n }\n}\n\nexport { ShinyResizeObserver };\n", "import { InputBinding, registerBinding } from \"./_utils\";\nimport { ShinyResizeObserver } from \"./_shinyResizeObserver\";\n\n/**\n * Methods for programmatically toggling the state of the sidebar. These methods\n * describe the desired state of the sidebar: `\"close\"` and `\"open\"` transition\n * the sidebar to the desired state, unless the sidebar is already in that\n * state. `\"toggle\"` transitions the sidebar to the state opposite of its\n * current state.\n * @typedef {SidebarToggleMethod}\n */\ntype SidebarToggleMethod = \"close\" | \"open\" | \"toggle\";\n\n/**\n * Data received by the input binding's `receiveMessage` method.\n * @typedef {SidebarMessageData}\n */\ntype SidebarMessageData = {\n method: SidebarToggleMethod;\n};\n\n/**\n * The DOM elements that make up the sidebar. `main`, `sidebar`, and `toggle`\n * are all direct children of `container` (in that order).\n * @interface SidebarComponents\n * @typedef {SidebarComponents}\n */\ninterface SidebarComponents {\n /**\n * The `layout_sidebar()` parent container, with class\n * `Sidebar.classes.LAYOUT`.\n * @type {HTMLElement}\n */\n container: HTMLElement;\n /**\n * The main content area of the sidebar layout.\n * @type {HTMLElement}\n */\n main: HTMLElement;\n /**\n * The sidebar container of the sidebar layout.\n * @type {HTMLElement}\n */\n sidebar: HTMLElement;\n /**\n * The toggle button that is used to toggle the sidebar state.\n * @type {HTMLElement}\n */\n toggle: HTMLElement;\n}\n\n/**\n * The bslib sidebar component class. This class is only used for collapsible\n * sidebars.\n *\n * @class Sidebar\n * @typedef {Sidebar}\n */\nclass Sidebar {\n /**\n * The DOM elements that make up the sidebar, see `SidebarComponents`.\n * @private\n * @type {SidebarComponents}\n */\n private layout: SidebarComponents;\n\n /**\n * A Shiny-specific resize observer that ensures Shiny outputs in the main\n * content areas of the sidebar resize appropriately.\n * @private\n * @type {ShinyResizeObserver}\n * @static\n */\n private static shinyResizeObserver = new ShinyResizeObserver();\n\n /**\n * Creates an instance of a collapsible bslib Sidebar.\n * @constructor\n * @param {HTMLElement} container\n */\n constructor(container: HTMLElement) {\n Sidebar.instanceMap.set(container, this);\n this.layout = {\n container,\n main: container.querySelector(\":scope > .main\") as HTMLElement,\n sidebar: container.querySelector(\":scope > .sidebar\") as HTMLElement,\n toggle: container.querySelector(\n \":scope > .collapse-toggle\"\n ) as HTMLElement,\n } as SidebarComponents;\n\n const sideAccordion = this.layout.sidebar.querySelector(\n \":scope > .sidebar-content > .accordion\"\n );\n if (sideAccordion) {\n // Add `.has-accordion` class to `.sidebar-content` container\n sideAccordion?.parentElement?.classList.add(\"has-accordion\");\n sideAccordion.classList.add(\"accordion-flush\");\n }\n\n if (this.layout.toggle) {\n this._initEventListeners();\n this._initSidebarCounters();\n this._initDesktop();\n }\n\n // Start watching the main content area for size changes to ensure Shiny\n // outputs resize appropriately during sidebar transitions.\n Sidebar.shinyResizeObserver.observe(this.layout.main);\n\n container.removeAttribute(\"data-bslib-sidebar-init\");\n const initScript = container.querySelector(\n \":scope > script[data-bslib-sidebar-init]\"\n );\n if (initScript) {\n container.removeChild(initScript);\n }\n }\n\n /**\n * Read the current state of the sidebar. Note that, when calling this method,\n * the sidebar may be transitioning into the state returned by this method.\n *\n * @description\n * The sidebar state works as follows, starting from the open state. When the\n * sidebar is closed:\n * 1. We add both the `COLLAPSE` and `TRANSITIONING` classes to the sidebar.\n * 2. The sidebar collapse begins to animate. On desktop devices, and where it\n * is supported, we transition the `grid-template-columns` property of the\n * sidebar layout. On mobile, the sidebar is hidden immediately. In both\n * cases, the collapse icon rotates and we use this rotation to determine\n * when the transition is complete.\n * 3. If another sidebar state toggle is requested while closing the sidebar,\n * we remove the `COLLAPSE` class and the animation immediately starts to\n * reverse.\n * 4. When the `transition` is complete, we remove the `TRANSITIONING` class.\n * @readonly\n * @type {boolean}\n */\n get isClosed(): boolean {\n return this.layout.container.classList.contains(Sidebar.classes.COLLAPSE);\n }\n\n /**\n * Static classes related to the sidebar layout or state.\n * @public\n * @static\n * @readonly\n * @type {{ LAYOUT: string; COLLAPSE: string; TRANSITIONING: string; }}\n */\n public static readonly classes = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n LAYOUT: \"bslib-sidebar-layout\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n COLLAPSE: \"sidebar-collapsed\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n TRANSITIONING: \"transitioning\",\n };\n\n /**\n * If sidebars are initialized before the DOM is ready, we re-schedule the\n * initialization to occur on DOMContentLoaded.\n * @private\n * @static\n * @type {boolean}\n */\n private static onReadyScheduled = false;\n /**\n * A map of initialized sidebars to their respective Sidebar instances.\n * @private\n * @static\n * @type {WeakMap}\n */\n private static instanceMap: WeakMap = new WeakMap();\n\n /**\n * Given a sidebar container, return the Sidebar instance associated with it.\n * @public\n * @static\n * @param {HTMLElement} el\n * @returns {(Sidebar | undefined)}\n */\n public static getInstance(el: HTMLElement): Sidebar | undefined {\n return Sidebar.instanceMap.get(el);\n }\n\n /**\n * Initialize all collapsible sidebars on the page.\n * @public\n * @static\n * @param {boolean} [flushResizeObserver=true] When `true`, we remove\n * non-existent elements from the ResizeObserver. This is required\n * periodically to prevent memory leaks. To avoid over-checking, we only flush\n * the ResizeObserver when initializing sidebars after page load.\n */\n public static initCollapsibleAll(flushResizeObserver = true): void {\n if (document.readyState === \"loading\") {\n if (!Sidebar.onReadyScheduled) {\n Sidebar.onReadyScheduled = true;\n document.addEventListener(\"DOMContentLoaded\", () => {\n Sidebar.initCollapsibleAll(false);\n });\n }\n return;\n }\n\n const initSelector = `.${Sidebar.classes.LAYOUT}[data-bslib-sidebar-init]`;\n if (!document.querySelector(initSelector)) {\n // no sidebars to initialize\n return;\n }\n\n if (flushResizeObserver) Sidebar.shinyResizeObserver.flush();\n\n const containers = document.querySelectorAll(initSelector);\n containers.forEach((container) => new Sidebar(container as HTMLElement));\n }\n\n /**\n * Initialize event listeners for the sidebar toggle button.\n * @private\n */\n private _initEventListeners(): void {\n const { toggle } = this.layout;\n\n toggle.addEventListener(\"click\", (ev) => {\n ev.preventDefault();\n this.toggle(\"toggle\");\n });\n\n // Remove the transitioning class when the transition ends. We watch the\n // collapse toggle icon because it's guaranteed to transition, whereas the\n // sidebar doesn't animate on mobile (or in browsers where animating\n // grid-template-columns is not supported).\n toggle\n .querySelector(\".collapse-icon\")\n ?.addEventListener(\"transitionend\", () => this._finalizeState());\n }\n\n /**\n * Initialize nested sidebar counters.\n *\n * @description\n * This function walks up the DOM tree, adding CSS variables to each direct\n * parent sidebar layout that count the layout's position in the stack of\n * nested layouts. We use these counters to keep the collapse toggles from\n * overlapping. Note that always-open sidebars that don't have collapse\n * toggles break the chain of nesting.\n * @private\n */\n private _initSidebarCounters(): void {\n const { container } = this.layout;\n\n const selectorChildLayouts =\n `.${Sidebar.classes.LAYOUT}` +\n \"> .main > \" +\n `.${Sidebar.classes.LAYOUT}:not([data-bslib-sidebar-open=\"always\"])`;\n\n const isInnermostLayout =\n container.querySelector(selectorChildLayouts) === null;\n\n if (!isInnermostLayout) {\n // There are sidebar layouts nested within this layout; defer to children\n return;\n }\n\n function nextSidebarParent(el: HTMLElement | null): HTMLElement | null {\n el = el ? el.parentElement : null;\n if (el && el.classList.contains(\"main\")) {\n // .bslib-sidebar-layout > .main > .bslib-sidebar-layout\n el = el.parentElement;\n }\n if (el && el.classList.contains(Sidebar.classes.LAYOUT)) {\n return el;\n }\n return null;\n }\n\n const layouts = [container];\n let parent = nextSidebarParent(container);\n\n while (parent) {\n // Add parent to front of layouts array, so we sort outer -> inner\n layouts.unshift(parent);\n parent = nextSidebarParent(parent);\n }\n\n const count = { left: 0, right: 0 };\n layouts.forEach(function (x: HTMLElement, i: number): void {\n x.style.setProperty(\"--bslib-sidebar-counter\", i.toString());\n const isRight = x.classList.contains(\"sidebar-right\");\n const thisCount = isRight ? count.right++ : count.left++;\n x.style.setProperty(\n \"--bslib-sidebar-overlap-counter\",\n thisCount.toString()\n );\n });\n }\n\n /**\n * Initialize the sidebar's initial state when `open = \"desktop\"`.\n * @private\n */\n private _initDesktop(): void {\n const { container } = this.layout;\n // If sidebar is marked open='desktop'...\n if (container.dataset.bslibSidebarOpen?.trim() !== \"desktop\") {\n return;\n }\n\n // then close sidebar on mobile\n const initCollapsed = window\n .getComputedStyle(container)\n .getPropertyValue(\"--bslib-sidebar-js-init-collapsed\");\n\n if (initCollapsed.trim() === \"true\") {\n this.toggle(\"close\");\n }\n }\n\n /**\n * Toggle the sidebar's open/closed state.\n * @public\n * @param {SidebarToggleMethod | undefined} method Whether to `\"open\"`,\n * `\"close\"` or `\"toggle\"` the sidebar. If `.toggle()` is called without an\n * argument, it will toggle the sidebar's state.\n */\n public toggle(method: SidebarToggleMethod | undefined): void {\n if (typeof method === \"undefined\") {\n method = \"toggle\";\n }\n\n const { container, sidebar } = this.layout;\n const isClosed = this.isClosed;\n\n if ([\"open\", \"close\", \"toggle\"].indexOf(method) === -1) {\n throw new Error(`Unknown method ${method}`);\n }\n\n if (method === \"toggle\") {\n method = isClosed ? \"open\" : \"close\";\n }\n\n if ((isClosed && method === \"close\") || (!isClosed && method === \"open\")) {\n // nothing to do, sidebar is already in the desired state\n return;\n }\n\n if (method === \"open\") {\n // unhide sidebar immediately when opening,\n // otherwise the sidebar is hidden on transitionend\n sidebar.hidden = false;\n }\n\n // Add a transitioning class just before adding COLLAPSE_CLASS since we want\n // some of the transitioning styles to apply before the collapse state\n container.classList.add(Sidebar.classes.TRANSITIONING);\n container.classList.toggle(Sidebar.classes.COLLAPSE);\n }\n\n /**\n * When the sidebar open/close transition ends, finalize the sidebar's state.\n * @private\n */\n private _finalizeState(): void {\n const { container, sidebar, toggle } = this.layout;\n container.classList.remove(Sidebar.classes.TRANSITIONING);\n sidebar.hidden = this.isClosed;\n toggle.setAttribute(\"aria-expanded\", this.isClosed ? \"false\" : \"true\");\n\n // Send browser-native event with updated sidebar state\n const event = new CustomEvent(\"bslib.sidebar\", {\n bubbles: true,\n detail: { open: !this.isClosed },\n });\n sidebar.dispatchEvent(event);\n\n // Trigger Shiny input and output binding events\n $(sidebar).trigger(\"toggleCollapse.sidebarInputBinding\");\n $(sidebar).trigger(this.isClosed ? \"hidden\" : \"shown\");\n }\n}\n\n/**\n * A Shiny input binding for a sidebar.\n * @class SidebarInputBinding\n * @typedef {SidebarInputBinding}\n * @extends {InputBinding}\n */\nclass SidebarInputBinding extends InputBinding {\n find(scope: HTMLElement) {\n return $(scope).find(`.${Sidebar.classes.LAYOUT} > .bslib-sidebar-input`);\n }\n\n getValue(el: HTMLElement): boolean {\n const sb = Sidebar.getInstance(el.parentElement as HTMLElement);\n if (!sb) return false;\n return !sb.isClosed;\n }\n\n setValue(el: HTMLElement, value: boolean): void {\n const method = value ? \"open\" : \"close\";\n this.receiveMessage(el, { method });\n }\n\n subscribe(el: HTMLElement, callback: (x: boolean) => void) {\n $(el).on(\n \"toggleCollapse.sidebarInputBinding\",\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function (event) {\n callback(true);\n }\n );\n }\n\n unsubscribe(el: HTMLElement) {\n $(el).off(\".sidebarInputBinding\");\n }\n\n receiveMessage(el: HTMLElement, data: SidebarMessageData) {\n const sb = Sidebar.getInstance(el.parentElement as HTMLElement);\n if (sb) sb.toggle(data.method);\n }\n}\n\nregisterBinding(SidebarInputBinding, \"sidebar\");\n\n// attach Sidebar class to window for global usage\n(window as any).bslib = (window as any).bslib || {};\n(window as any).bslib.Sidebar = Sidebar;\n"], - "mappings": "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", - "names": [] -} diff --git a/inst/components/dist/sidebar/sidebar.min.js b/inst/components/dist/sidebar/sidebar.min.js deleted file mode 100644 index 41cccfe23..000000000 --- a/inst/components/dist/sidebar/sidebar.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! bslib 0.5.1.9000 | (c) 2012-2023 RStudio, PBC. | License: MIT + file LICENSE */ -"use strict";(()=>{var g=window.Shiny?Shiny.InputBinding:class{};function f(b,e){window.Shiny&&Shiny.inputBindings.register(new b,"bslib."+e)}var u=class{constructor(){this.resizeObserverEntries=[],this.resizeObserver=new ResizeObserver(e=>{let t=new Event("resize");if(window.dispatchEvent(t),!window.Shiny)return;let s=[];for(let r of e)r.target instanceof HTMLElement&&r.target.querySelector(".shiny-bound-output")&&r.target.querySelectorAll(".shiny-bound-output").forEach(o=>{if(s.includes(o))return;let{binding:l,onResize:d}=$(o).data("shinyOutputBinding");if(!l||!l.resize)return;let i=o.shinyResizeObserver;if(i&&i!==this||(i||(o.shinyResizeObserver=this),d(o),s.push(o),!o.classList.contains("shiny-plot-output")))return;let c=o.querySelector('img:not([width="100%"])');c&&c.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 n=class{constructor(e){var r;n.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&&((r=t==null?void 0:t.parentElement)==null||r.classList.add("has-accordion"),t.classList.add("accordion-flush")),this.layout.toggle&&(this._initEventListeners(),this._initSidebarCounters(),this._initDesktop()),n.shinyResizeObserver.observe(this.layout.main),e.removeAttribute("data-bslib-sidebar-init");let s=e.querySelector(":scope > script[data-bslib-sidebar-init]");s&&e.removeChild(s)}get isClosed(){return this.layout.container.classList.contains(n.classes.COLLAPSE)}static getInstance(e){return n.instanceMap.get(e)}static initCollapsibleAll(e=!0){if(document.readyState==="loading"){n.onReadyScheduled||(n.onReadyScheduled=!0,document.addEventListener("DOMContentLoaded",()=>{n.initCollapsibleAll(!1)}));return}let t=`.${n.classes.LAYOUT}[data-bslib-sidebar-init]`;if(!document.querySelector(t))return;e&&n.shinyResizeObserver.flush(),document.querySelectorAll(t).forEach(r=>new n(r))}_initEventListeners(){var t;let{toggle:e}=this.layout;e.addEventListener("click",s=>{s.preventDefault(),this.toggle("toggle")}),(t=e.querySelector(".collapse-icon"))==null||t.addEventListener("transitionend",()=>this._finalizeState())}_initSidebarCounters(){let{container:e}=this.layout,t=`.${n.classes.LAYOUT}> .main > .${n.classes.LAYOUT}:not([data-bslib-sidebar-open="always"])`;if(!(e.querySelector(t)===null))return;function r(i){return i=i?i.parentElement:null,i&&i.classList.contains("main")&&(i=i.parentElement),i&&i.classList.contains(n.classes.LAYOUT)?i:null}let o=[e],l=r(e);for(;l;)o.unshift(l),l=r(l);let d={left:0,right:0};o.forEach(function(i,c){i.style.setProperty("--bslib-sidebar-counter",c.toString());let h=i.classList.contains("sidebar-right")?d.right++:d.left++;i.style.setProperty("--bslib-sidebar-overlap-counter",h.toString())})}_initDesktop(){var s;let{container:e}=this.layout;if(((s=e.dataset.bslibSidebarOpen)==null?void 0:s.trim())!=="desktop")return;window.getComputedStyle(e).getPropertyValue("--bslib-sidebar-js-init-collapsed").trim()==="true"&&this.toggle("close")}toggle(e){typeof e=="undefined"&&(e="toggle");let{container:t,sidebar:s}=this.layout,r=this.isClosed;if(["open","close","toggle"].indexOf(e)===-1)throw new Error(`Unknown method ${e}`);e==="toggle"&&(e=r?"open":"close"),!(r&&e==="close"||!r&&e==="open")&&(e==="open"&&(s.hidden=!1),t.classList.add(n.classes.TRANSITIONING),t.classList.toggle(n.classes.COLLAPSE))}_finalizeState(){let{container:e,sidebar:t,toggle:s}=this.layout;e.classList.remove(n.classes.TRANSITIONING),t.hidden=this.isClosed,s.setAttribute("aria-expanded",this.isClosed?"false":"true");let r=new CustomEvent("bslib.sidebar",{bubbles:!0,detail:{open:!this.isClosed}});t.dispatchEvent(r),$(t).trigger("toggleCollapse.sidebarInputBinding"),$(t).trigger(this.isClosed?"hidden":"shown")}},a=n;a.shinyResizeObserver=new u,a.classes={LAYOUT:"bslib-sidebar-layout",COLLAPSE:"sidebar-collapsed",TRANSITIONING:"transitioning"},a.onReadyScheduled=!1,a.instanceMap=new WeakMap;var p=class extends g{find(e){return $(e).find(`.${a.classes.LAYOUT} > .bslib-sidebar-input`)}getValue(e){let t=a.getInstance(e.parentElement);return t?!t.isClosed:!1}setValue(e,t){let s=t?"open":"close";this.receiveMessage(e,{method:s})}subscribe(e,t){$(e).on("toggleCollapse.sidebarInputBinding",function(s){t(!0)})}unsubscribe(e){$(e).off(".sidebarInputBinding")}receiveMessage(e,t){let s=a.getInstance(e.parentElement);s&&s.toggle(t.method)}};f(p,"sidebar");window.bslib=window.bslib||{};window.bslib.Sidebar=a;})(); -//# sourceMappingURL=sidebar.min.js.map diff --git a/inst/components/dist/sidebar/sidebar.min.js.map b/inst/components/dist/sidebar/sidebar.min.js.map deleted file mode 100644 index c6eeefff3..000000000 --- a/inst/components/dist/sidebar/sidebar.min.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../srcts/src/components/_utils.ts", "../../../../srcts/src/components/_shinyResizeObserver.ts", "../../../../srcts/src/components/sidebar.ts"], - "sourcesContent": ["import type { HtmlDep } from \"rstudio-shiny/srcts/types/src/shiny/render\";\n\nimport type { InputBinding as InputBindingType } from \"rstudio-shiny/srcts/types/src/bindings/input\";\n\n// Exclude undefined from T\ntype NotUndefined = T extends undefined ? never : T;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst InputBinding = (\n window.Shiny ? Shiny.InputBinding : class {}\n) as typeof InputBindingType;\n\nfunction registerBinding(\n inputBindingClass: new () => InputBindingType,\n name: string\n): void {\n if (window.Shiny) {\n Shiny.inputBindings.register(new inputBindingClass(), \"bslib.\" + name);\n }\n}\n\n// Return true if the key exists on the object and the value is not undefined.\n//\n// This method is mainly used in input bindings' `receiveMessage` method.\n// Since we know that the values are sent by Shiny via `{jsonlite}`,\n// then we know that there are no `undefined` values. `null` is possible, but not `undefined`.\nfunction hasDefinedProperty<\n Prop extends keyof X,\n X extends { [key: string]: any }\n>(\n obj: X,\n prop: Prop\n): obj is X & { [key in NonNullable]: NotUndefined } {\n return (\n Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] !== undefined\n );\n}\n\n// TODO: Shiny should trigger resize events when the output\n// https://github.com/rstudio/shiny/pull/3682\nfunction doWindowResizeOnElementResize(el: HTMLElement): void {\n if ($(el).data(\"window-resize-observer\")) {\n return;\n }\n const resizeEvent = new Event(\"resize\");\n const ro = new ResizeObserver(() => {\n window.dispatchEvent(resizeEvent);\n });\n ro.observe(el);\n $(el).data(\"window-resize-observer\", ro);\n}\n\nfunction getAllFocusableChildren(el: HTMLElement): HTMLElement[] {\n // Cross-referenced with https://allyjs.io/data-tables/focusable.html\n const base = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"details summary\",\n \"input\",\n \"iframe\",\n \"select\",\n \"textarea\",\n '[contentEditable=\"\"]',\n '[contentEditable=\"true\"]',\n '[contentEditable=\"TRUE\"]',\n \"[tabindex]\",\n ];\n const modifiers = [':not([tabindex=\"-1\"])', \":not([disabled])\"];\n const selectors = base.map((b) => b + modifiers.join(\"\"));\n const focusable = el.querySelectorAll(selectors.join(\", \"));\n return Array.from(focusable) as HTMLElement[];\n}\n\nexport {\n InputBinding,\n registerBinding,\n hasDefinedProperty,\n doWindowResizeOnElementResize,\n getAllFocusableChildren,\n};\nexport type { HtmlDep };\n", "/**\n * A resize observer that ensures Shiny outputs resize during or just after\n * their parent container size changes. Useful, in particular, for sidebar\n * transitions or for full-screen card transitions.\n *\n * @class ShinyResizeObserver\n * @typedef {ShinyResizeObserver}\n */\nclass ShinyResizeObserver {\n /**\n * The actual ResizeObserver instance.\n * @private\n * @type {ResizeObserver}\n */\n private resizeObserver: ResizeObserver;\n /**\n * An array of elements that are currently being watched by the Resize\n * Observer.\n *\n * @details\n * We don't currently have lifecycle hooks that allow us to unobserve elements\n * when they are removed from the DOM. As a result, we need to manually check\n * that the elements we're watching still exist in the DOM. This array keeps\n * track of the elements we're watching so that we can check them later.\n * @private\n * @type {HTMLElement[]}\n */\n private resizeObserverEntries: HTMLElement[];\n\n /**\n * Watch containers for size changes and ensure that Shiny outputs and\n * htmlwidgets within resize appropriately.\n *\n * @details\n * The ShinyResizeObserver is used to watch the containers, such as Sidebars\n * and Cards for size changes, in particular when the sidebar state is toggled\n * or the card body is expanded full screen. It performs two primary tasks:\n *\n * 1. Dispatches a `resize` event on the window object. This is necessary to\n * ensure that Shiny outputs resize appropriately. In general, the window\n * resizing is throttled and the output update occurs when the transition\n * is complete.\n * 2. If an output with a resize method on the output binding is detected, we\n * directly call the `.onResize()` method of the binding. This ensures that\n * htmlwidgets transition smoothly. In static mode, htmlwidgets does this\n * already.\n *\n * @note\n * This resize observer also handles race conditions in some complex\n * fill-based layouts with multiple outputs (e.g., plotly), where shiny\n * initializes with the correct sizing, but in-between the 1st and last\n * renderValue(), the size of the output containers can change, meaning every\n * output but the 1st gets initialized with the wrong size during their\n * renderValue(). Then, after the render phase, shiny won't know to trigger a\n * resize since all the widgets will return to their original size (and thus,\n * Shiny thinks there isn't any resizing to do). The resize observer works\n * around this by ensuring that the output is resized whenever its container\n * size changes.\n * @constructor\n */\n constructor() {\n this.resizeObserverEntries = [];\n this.resizeObserver = new ResizeObserver((entries) => {\n const resizeEvent = new Event(\"resize\");\n window.dispatchEvent(resizeEvent);\n\n // the rest of this callback is only relevant in Shiny apps\n if (!window.Shiny) return;\n\n const resized = [] as HTMLElement[];\n\n for (const entry of entries) {\n if (!(entry.target instanceof HTMLElement)) continue;\n if (!entry.target.querySelector(\".shiny-bound-output\")) continue;\n\n entry.target\n .querySelectorAll(\".shiny-bound-output\")\n .forEach((el) => {\n if (resized.includes(el)) return;\n\n const { binding, onResize } = $(el).data(\"shinyOutputBinding\");\n if (!binding || !binding.resize) return;\n\n // if this output is owned by another observer, skip it\n const owner = (el as any).shinyResizeObserver;\n if (owner && owner !== this) return;\n // mark this output as owned by this shinyResizeObserver instance\n if (!owner) (el as any).shinyResizeObserver = this;\n\n // trigger immediate resizing of outputs with a resize method\n onResize(el);\n // only once per output and resize event\n resized.push(el);\n\n // set plot images to 100% width temporarily during the transition\n if (!el.classList.contains(\"shiny-plot-output\")) return;\n const img = el.querySelector(\n 'img:not([width=\"100%\"])'\n );\n if (img) img.setAttribute(\"width\", \"100%\");\n });\n }\n });\n }\n\n /**\n * Observe an element for size changes.\n * @param {HTMLElement} el - The element to observe.\n */\n observe(el: HTMLElement): void {\n this.resizeObserver.observe(el);\n this.resizeObserverEntries.push(el);\n }\n\n /**\n * Stop observing an element for size changes.\n * @param {HTMLElement} el - The element to stop observing.\n */\n unobserve(el: HTMLElement): void {\n const idxEl = this.resizeObserverEntries.indexOf(el);\n if (idxEl < 0) return;\n\n this.resizeObserver.unobserve(el);\n this.resizeObserverEntries.splice(idxEl, 1);\n }\n\n /**\n * This method checks that we're not continuing to watch elements that no\n * longer exist in the DOM. If any are found, we stop observing them and\n * remove them from our array of observed elements.\n *\n * @private\n * @static\n */\n flush(): void {\n this.resizeObserverEntries.forEach((el) => {\n if (!document.body.contains(el)) this.unobserve(el);\n });\n }\n}\n\nexport { ShinyResizeObserver };\n", "import { InputBinding, registerBinding } from \"./_utils\";\nimport { ShinyResizeObserver } from \"./_shinyResizeObserver\";\n\n/**\n * Methods for programmatically toggling the state of the sidebar. These methods\n * describe the desired state of the sidebar: `\"close\"` and `\"open\"` transition\n * the sidebar to the desired state, unless the sidebar is already in that\n * state. `\"toggle\"` transitions the sidebar to the state opposite of its\n * current state.\n * @typedef {SidebarToggleMethod}\n */\ntype SidebarToggleMethod = \"close\" | \"open\" | \"toggle\";\n\n/**\n * Data received by the input binding's `receiveMessage` method.\n * @typedef {SidebarMessageData}\n */\ntype SidebarMessageData = {\n method: SidebarToggleMethod;\n};\n\n/**\n * The DOM elements that make up the sidebar. `main`, `sidebar`, and `toggle`\n * are all direct children of `container` (in that order).\n * @interface SidebarComponents\n * @typedef {SidebarComponents}\n */\ninterface SidebarComponents {\n /**\n * The `layout_sidebar()` parent container, with class\n * `Sidebar.classes.LAYOUT`.\n * @type {HTMLElement}\n */\n container: HTMLElement;\n /**\n * The main content area of the sidebar layout.\n * @type {HTMLElement}\n */\n main: HTMLElement;\n /**\n * The sidebar container of the sidebar layout.\n * @type {HTMLElement}\n */\n sidebar: HTMLElement;\n /**\n * The toggle button that is used to toggle the sidebar state.\n * @type {HTMLElement}\n */\n toggle: HTMLElement;\n}\n\n/**\n * The bslib sidebar component class. This class is only used for collapsible\n * sidebars.\n *\n * @class Sidebar\n * @typedef {Sidebar}\n */\nclass Sidebar {\n /**\n * The DOM elements that make up the sidebar, see `SidebarComponents`.\n * @private\n * @type {SidebarComponents}\n */\n private layout: SidebarComponents;\n\n /**\n * A Shiny-specific resize observer that ensures Shiny outputs in the main\n * content areas of the sidebar resize appropriately.\n * @private\n * @type {ShinyResizeObserver}\n * @static\n */\n private static shinyResizeObserver = new ShinyResizeObserver();\n\n /**\n * Creates an instance of a collapsible bslib Sidebar.\n * @constructor\n * @param {HTMLElement} container\n */\n constructor(container: HTMLElement) {\n Sidebar.instanceMap.set(container, this);\n this.layout = {\n container,\n main: container.querySelector(\":scope > .main\") as HTMLElement,\n sidebar: container.querySelector(\":scope > .sidebar\") as HTMLElement,\n toggle: container.querySelector(\n \":scope > .collapse-toggle\"\n ) as HTMLElement,\n } as SidebarComponents;\n\n const sideAccordion = this.layout.sidebar.querySelector(\n \":scope > .sidebar-content > .accordion\"\n );\n if (sideAccordion) {\n // Add `.has-accordion` class to `.sidebar-content` container\n sideAccordion?.parentElement?.classList.add(\"has-accordion\");\n sideAccordion.classList.add(\"accordion-flush\");\n }\n\n if (this.layout.toggle) {\n this._initEventListeners();\n this._initSidebarCounters();\n this._initDesktop();\n }\n\n // Start watching the main content area for size changes to ensure Shiny\n // outputs resize appropriately during sidebar transitions.\n Sidebar.shinyResizeObserver.observe(this.layout.main);\n\n container.removeAttribute(\"data-bslib-sidebar-init\");\n const initScript = container.querySelector(\n \":scope > script[data-bslib-sidebar-init]\"\n );\n if (initScript) {\n container.removeChild(initScript);\n }\n }\n\n /**\n * Read the current state of the sidebar. Note that, when calling this method,\n * the sidebar may be transitioning into the state returned by this method.\n *\n * @description\n * The sidebar state works as follows, starting from the open state. When the\n * sidebar is closed:\n * 1. We add both the `COLLAPSE` and `TRANSITIONING` classes to the sidebar.\n * 2. The sidebar collapse begins to animate. On desktop devices, and where it\n * is supported, we transition the `grid-template-columns` property of the\n * sidebar layout. On mobile, the sidebar is hidden immediately. In both\n * cases, the collapse icon rotates and we use this rotation to determine\n * when the transition is complete.\n * 3. If another sidebar state toggle is requested while closing the sidebar,\n * we remove the `COLLAPSE` class and the animation immediately starts to\n * reverse.\n * 4. When the `transition` is complete, we remove the `TRANSITIONING` class.\n * @readonly\n * @type {boolean}\n */\n get isClosed(): boolean {\n return this.layout.container.classList.contains(Sidebar.classes.COLLAPSE);\n }\n\n /**\n * Static classes related to the sidebar layout or state.\n * @public\n * @static\n * @readonly\n * @type {{ LAYOUT: string; COLLAPSE: string; TRANSITIONING: string; }}\n */\n public static readonly classes = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n LAYOUT: \"bslib-sidebar-layout\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n COLLAPSE: \"sidebar-collapsed\",\n // eslint-disable-next-line @typescript-eslint/naming-convention\n TRANSITIONING: \"transitioning\",\n };\n\n /**\n * If sidebars are initialized before the DOM is ready, we re-schedule the\n * initialization to occur on DOMContentLoaded.\n * @private\n * @static\n * @type {boolean}\n */\n private static onReadyScheduled = false;\n /**\n * A map of initialized sidebars to their respective Sidebar instances.\n * @private\n * @static\n * @type {WeakMap}\n */\n private static instanceMap: WeakMap = new WeakMap();\n\n /**\n * Given a sidebar container, return the Sidebar instance associated with it.\n * @public\n * @static\n * @param {HTMLElement} el\n * @returns {(Sidebar | undefined)}\n */\n public static getInstance(el: HTMLElement): Sidebar | undefined {\n return Sidebar.instanceMap.get(el);\n }\n\n /**\n * Initialize all collapsible sidebars on the page.\n * @public\n * @static\n * @param {boolean} [flushResizeObserver=true] When `true`, we remove\n * non-existent elements from the ResizeObserver. This is required\n * periodically to prevent memory leaks. To avoid over-checking, we only flush\n * the ResizeObserver when initializing sidebars after page load.\n */\n public static initCollapsibleAll(flushResizeObserver = true): void {\n if (document.readyState === \"loading\") {\n if (!Sidebar.onReadyScheduled) {\n Sidebar.onReadyScheduled = true;\n document.addEventListener(\"DOMContentLoaded\", () => {\n Sidebar.initCollapsibleAll(false);\n });\n }\n return;\n }\n\n const initSelector = `.${Sidebar.classes.LAYOUT}[data-bslib-sidebar-init]`;\n if (!document.querySelector(initSelector)) {\n // no sidebars to initialize\n return;\n }\n\n if (flushResizeObserver) Sidebar.shinyResizeObserver.flush();\n\n const containers = document.querySelectorAll(initSelector);\n containers.forEach((container) => new Sidebar(container as HTMLElement));\n }\n\n /**\n * Initialize event listeners for the sidebar toggle button.\n * @private\n */\n private _initEventListeners(): void {\n const { toggle } = this.layout;\n\n toggle.addEventListener(\"click\", (ev) => {\n ev.preventDefault();\n this.toggle(\"toggle\");\n });\n\n // Remove the transitioning class when the transition ends. We watch the\n // collapse toggle icon because it's guaranteed to transition, whereas the\n // sidebar doesn't animate on mobile (or in browsers where animating\n // grid-template-columns is not supported).\n toggle\n .querySelector(\".collapse-icon\")\n ?.addEventListener(\"transitionend\", () => this._finalizeState());\n }\n\n /**\n * Initialize nested sidebar counters.\n *\n * @description\n * This function walks up the DOM tree, adding CSS variables to each direct\n * parent sidebar layout that count the layout's position in the stack of\n * nested layouts. We use these counters to keep the collapse toggles from\n * overlapping. Note that always-open sidebars that don't have collapse\n * toggles break the chain of nesting.\n * @private\n */\n private _initSidebarCounters(): void {\n const { container } = this.layout;\n\n const selectorChildLayouts =\n `.${Sidebar.classes.LAYOUT}` +\n \"> .main > \" +\n `.${Sidebar.classes.LAYOUT}:not([data-bslib-sidebar-open=\"always\"])`;\n\n const isInnermostLayout =\n container.querySelector(selectorChildLayouts) === null;\n\n if (!isInnermostLayout) {\n // There are sidebar layouts nested within this layout; defer to children\n return;\n }\n\n function nextSidebarParent(el: HTMLElement | null): HTMLElement | null {\n el = el ? el.parentElement : null;\n if (el && el.classList.contains(\"main\")) {\n // .bslib-sidebar-layout > .main > .bslib-sidebar-layout\n el = el.parentElement;\n }\n if (el && el.classList.contains(Sidebar.classes.LAYOUT)) {\n return el;\n }\n return null;\n }\n\n const layouts = [container];\n let parent = nextSidebarParent(container);\n\n while (parent) {\n // Add parent to front of layouts array, so we sort outer -> inner\n layouts.unshift(parent);\n parent = nextSidebarParent(parent);\n }\n\n const count = { left: 0, right: 0 };\n layouts.forEach(function (x: HTMLElement, i: number): void {\n x.style.setProperty(\"--bslib-sidebar-counter\", i.toString());\n const isRight = x.classList.contains(\"sidebar-right\");\n const thisCount = isRight ? count.right++ : count.left++;\n x.style.setProperty(\n \"--bslib-sidebar-overlap-counter\",\n thisCount.toString()\n );\n });\n }\n\n /**\n * Initialize the sidebar's initial state when `open = \"desktop\"`.\n * @private\n */\n private _initDesktop(): void {\n const { container } = this.layout;\n // If sidebar is marked open='desktop'...\n if (container.dataset.bslibSidebarOpen?.trim() !== \"desktop\") {\n return;\n }\n\n // then close sidebar on mobile\n const initCollapsed = window\n .getComputedStyle(container)\n .getPropertyValue(\"--bslib-sidebar-js-init-collapsed\");\n\n if (initCollapsed.trim() === \"true\") {\n this.toggle(\"close\");\n }\n }\n\n /**\n * Toggle the sidebar's open/closed state.\n * @public\n * @param {SidebarToggleMethod | undefined} method Whether to `\"open\"`,\n * `\"close\"` or `\"toggle\"` the sidebar. If `.toggle()` is called without an\n * argument, it will toggle the sidebar's state.\n */\n public toggle(method: SidebarToggleMethod | undefined): void {\n if (typeof method === \"undefined\") {\n method = \"toggle\";\n }\n\n const { container, sidebar } = this.layout;\n const isClosed = this.isClosed;\n\n if ([\"open\", \"close\", \"toggle\"].indexOf(method) === -1) {\n throw new Error(`Unknown method ${method}`);\n }\n\n if (method === \"toggle\") {\n method = isClosed ? \"open\" : \"close\";\n }\n\n if ((isClosed && method === \"close\") || (!isClosed && method === \"open\")) {\n // nothing to do, sidebar is already in the desired state\n return;\n }\n\n if (method === \"open\") {\n // unhide sidebar immediately when opening,\n // otherwise the sidebar is hidden on transitionend\n sidebar.hidden = false;\n }\n\n // Add a transitioning class just before adding COLLAPSE_CLASS since we want\n // some of the transitioning styles to apply before the collapse state\n container.classList.add(Sidebar.classes.TRANSITIONING);\n container.classList.toggle(Sidebar.classes.COLLAPSE);\n }\n\n /**\n * When the sidebar open/close transition ends, finalize the sidebar's state.\n * @private\n */\n private _finalizeState(): void {\n const { container, sidebar, toggle } = this.layout;\n container.classList.remove(Sidebar.classes.TRANSITIONING);\n sidebar.hidden = this.isClosed;\n toggle.setAttribute(\"aria-expanded\", this.isClosed ? \"false\" : \"true\");\n\n // Send browser-native event with updated sidebar state\n const event = new CustomEvent(\"bslib.sidebar\", {\n bubbles: true,\n detail: { open: !this.isClosed },\n });\n sidebar.dispatchEvent(event);\n\n // Trigger Shiny input and output binding events\n $(sidebar).trigger(\"toggleCollapse.sidebarInputBinding\");\n $(sidebar).trigger(this.isClosed ? \"hidden\" : \"shown\");\n }\n}\n\n/**\n * A Shiny input binding for a sidebar.\n * @class SidebarInputBinding\n * @typedef {SidebarInputBinding}\n * @extends {InputBinding}\n */\nclass SidebarInputBinding extends InputBinding {\n find(scope: HTMLElement) {\n return $(scope).find(`.${Sidebar.classes.LAYOUT} > .bslib-sidebar-input`);\n }\n\n getValue(el: HTMLElement): boolean {\n const sb = Sidebar.getInstance(el.parentElement as HTMLElement);\n if (!sb) return false;\n return !sb.isClosed;\n }\n\n setValue(el: HTMLElement, value: boolean): void {\n const method = value ? \"open\" : \"close\";\n this.receiveMessage(el, { method });\n }\n\n subscribe(el: HTMLElement, callback: (x: boolean) => void) {\n $(el).on(\n \"toggleCollapse.sidebarInputBinding\",\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n function (event) {\n callback(true);\n }\n );\n }\n\n unsubscribe(el: HTMLElement) {\n $(el).off(\".sidebarInputBinding\");\n }\n\n receiveMessage(el: HTMLElement, data: SidebarMessageData) {\n const sb = Sidebar.getInstance(el.parentElement as HTMLElement);\n if (sb) sb.toggle(data.method);\n }\n}\n\nregisterBinding(SidebarInputBinding, \"sidebar\");\n\n// attach Sidebar class to window for global usage\n(window as any).bslib = (window as any).bslib || {};\n(window as any).bslib.Sidebar = Sidebar;\n"], - "mappings": "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", - "names": ["InputBinding", "registerBinding", "inputBindingClass", "name", "ShinyResizeObserver", "entries", "resizeEvent", "resized", "entry", "el", "binding", "onResize", "owner", "img", "idxEl", "_Sidebar", "container", "_a", "sideAccordion", "initScript", "el", "flushResizeObserver", "initSelector", "toggle", "ev", "selectorChildLayouts", "nextSidebarParent", "layouts", "parent", "count", "x", "i", "thisCount", "method", "sidebar", "isClosed", "event", "Sidebar", "ShinyResizeObserver", "SidebarInputBinding", "InputBinding", "scope", "sb", "value", "callback", "data", "registerBinding"] -} diff --git a/inst/components/dist/value_box/value_box.css b/inst/components/dist/value_box/value_box.css deleted file mode 100644 index 2864ef535..000000000 --- a/inst/components/dist/value_box/value_box.css +++ /dev/null @@ -1 +0,0 @@ -:root{--bslib-value-box-shadow: 0px 1px 2px rgba(29,31,33,0.1),0px 3px 7px rgba(29,31,33,0.1),0px 12px 30px rgba(29,31,33,0.08);--bslib-value-box-border-width-auto-yes: 0;--bslib-value-box-border-width-auto-no: 0;--bslib-value-box-border-width-baseline: var(--bs-border-width)}.bslib-value-box{border-width:var(--bslib-value-box-border-width-auto-no, var(--bslib-value-box-border-width-baseline));container-name:bslib-value-box;container-type:inline-size}.bslib-value-box.card{box-shadow:var(--bslib-value-box-shadow)}.bslib-value-box.border-auto{border-width:var(--bslib-value-box-border-width-auto-yes, var(--bslib-value-box-border-width-baseline))}.bslib-value-box.default{--bslib-value-box-bg-default: var(--bs-card-bg, #fff);--bslib-value-box-border-color-default: var(--bs-card-border-color, var(--bs-border-color-translucent));color:var(--bslib-value-box-color);background-color:var(--bslib-value-box-bg, var(--bslib-value-box-bg-default));border-color:var(--bslib-value-box-border-color, var(--bslib-value-box-border-color-default))}.bslib-value-box .value-box-grid{display:grid;grid-template-areas:"left right";align-items:center;overflow:hidden}.bslib-value-box .value-box-showcase{height:100%;max-height:var(---bslib-value-box-showcase-max-h, 100%)}.bslib-value-box .value-box-showcase,.bslib-value-box .value-box-showcase>.html-fill-item{width:100%}.bslib-value-box[data-full-screen="true"] .value-box-showcase{max-height:var(---bslib-value-box-showcase-max-h-fs, 100%)}@media screen and (min-width: 575.98px){@container bslib-value-box (max-width: 300px){.bslib-value-box:not(.showcase-bottom) .value-box-grid{grid-template-columns:1fr !important;grid-template-rows:auto auto;grid-template-areas:"top" "bottom"}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-showcase{grid-area:top !important}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-area{grid-area:bottom !important;justify-content:end}}}.bslib-value-box .value-box-area{justify-content:center;padding:1.5rem 1rem;font-size:.9rem;font-weight:500}.bslib-value-box .value-box-area *{margin-bottom:0;margin-top:0}.bslib-value-box .value-box-title{font-size:1rem;margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2}.bslib-value-box .value-box-title:empty::after{content:'\00a0 '}.bslib-value-box .value-box-value{font-size:calc(1.325rem + .9vw);margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2}@media (min-width: 1200px){.bslib-value-box .value-box-value{font-size:2rem}}.bslib-value-box .value-box-value:empty::after{content:'\00a0 '}.bslib-value-box .value-box-showcase{align-items:center;justify-content:center;margin-top:auto;margin-bottom:auto;padding:1rem}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{opacity:.85;min-width:50px;max-width:125%}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{font-size:4rem}.bslib-value-box.showcase-top-right .value-box-grid{grid-template-columns:1fr var(---bslib-value-box-showcase-w, 50%)}.bslib-value-box.showcase-top-right .value-box-grid .value-box-showcase{grid-area:right;margin-left:auto;align-self:start;align-items:end;padding-left:0;padding-bottom:0}.bslib-value-box.showcase-top-right .value-box-grid .value-box-area{grid-area:left;align-self:end}.bslib-value-box.showcase-top-right[data-full-screen="true"] .value-box-grid{grid-template-columns:auto var(---bslib-value-box-showcase-w-fs, 1fr)}.bslib-value-box.showcase-top-right[data-full-screen="true"] .value-box-grid>div{align-self:center}.bslib-value-box.showcase-top-right:not([data-full-screen="true"]) .value-box-showcase{margin-top:0}@container bslib-value-box (max-width: 300px){.bslib-value-box.showcase-top-right:not([data-full-screen="true"]) .value-box-grid .value-box-showcase{padding-left:1rem}}.bslib-value-box.showcase-left-center .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w, 30%) auto}.bslib-value-box.showcase-left-center[data-full-screen="true"] .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w-fs, 1fr) auto}.bslib-value-box.showcase-left-center:not([data-fill-screen="true"]) .value-box-grid .value-box-showcase{grid-area:left}.bslib-value-box.showcase-left-center:not([data-fill-screen="true"]) .value-box-grid .value-box-area{grid-area:right}.bslib-value-box.showcase-bottom .value-box-grid{grid-template-columns:1fr;grid-template-rows:1fr var(---bslib-value-box-showcase-h, auto);grid-template-areas:"top" "bottom";overflow:hidden}.bslib-value-box.showcase-bottom .value-box-grid .value-box-showcase{grid-area:bottom;padding:0;margin:0}.bslib-value-box.showcase-bottom .value-box-grid .value-box-area{grid-area:top}.bslib-value-box.showcase-bottom[data-full-screen="true"] .value-box-grid{grid-template-rows:1fr var(---bslib-value-box-showcase-h-fs, 2fr)}.bslib-value-box.showcase-bottom[data-full-screen="true"] .value-box-grid .value-box-showcase{padding:1rem}[data-bs-theme="dark"] .bslib-value-box{--bslib-value-box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 50%)} diff --git a/inst/components/dist/webComponents/webComponents.js b/inst/components/dist/web-components.js similarity index 99% rename from inst/components/dist/webComponents/webComponents.js rename to inst/components/dist/web-components.js index b4b80f7b8..50314afe6 100644 --- a/inst/components/dist/webComponents/webComponents.js +++ b/inst/components/dist/web-components.js @@ -867,7 +867,7 @@ } }; - // srcts/src/components/tooltip.ts + // srcts/src/components/webcomponents/tooltip.ts var bsTooltip = window.bootstrap ? window.bootstrap.Tooltip : class { }; var _BslibTooltip = class extends BslibElement { @@ -1050,7 +1050,7 @@ n({ type: String }) ], BslibTooltip.prototype, "bsOptions", 2); - // srcts/src/components/popover.ts + // srcts/src/components/webcomponents/popover.ts var bsPopover = window.bootstrap ? window.bootstrap.Popover : class { }; var _BslibPopover = class extends BslibElement { @@ -1382,7 +1382,7 @@ return !!header && header.childNodes.length > 0; } - // srcts/src/components/inputDarkMode.ts + // srcts/src/components/webcomponents/inputDarkMode.ts var BslibInputDarkMode = class extends s4 { constructor() { super(...arguments); @@ -1713,7 +1713,7 @@ Shiny.inputBindings.register(new NewCustomBinding(), `${tagName}-Binding`); } - // srcts/src/components/webcomponents/_shinyAddCustomMessageHandlers.ts + // srcts/src/components/_shinyAddCustomMessageHandlers.ts function shinyAddCustomMessageHandlers(handlers) { if (!window.Shiny) { return; @@ -1723,7 +1723,7 @@ } } - // srcts/src/components/webComponents.ts + // srcts/src/components/webcomponents/index.ts [BslibTooltip, BslibPopover, BslibInputDarkMode].forEach((cls) => { customElements.define(cls.tagName, cls); if (window.Shiny) { @@ -1842,4 +1842,4 @@ lit-html/is-server.js: * SPDX-License-Identifier: BSD-3-Clause *) */ -//# sourceMappingURL=webComponents.js.map +//# sourceMappingURL=web-components.js.map diff --git a/inst/components/dist/webComponents/webComponents.js.map b/inst/components/dist/web-components.js.map similarity index 85% rename from inst/components/dist/webComponents/webComponents.js.map rename to inst/components/dist/web-components.js.map index 5917ffeae..7fad7a4c2 100644 --- a/inst/components/dist/webComponents/webComponents.js.map +++ b/inst/components/dist/web-components.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../../../../node_modules/@lit/reactive-element/src/decorators/property.ts", "../../../../node_modules/@lit/reactive-element/src/decorators/query-assigned-elements.ts", "../../../../node_modules/@lit/reactive-element/src/css-tag.ts", "../../../../node_modules/@lit/reactive-element/src/reactive-element.ts", "../../../../node_modules/lit-html/src/lit-html.ts", "../../../../node_modules/lit-element/src/lit-element.ts", "../../../../srcts/src/components/webcomponents/_bslibElement.ts", "../../../../srcts/src/components/_utilsTooltip.ts", "../../../../srcts/src/components/_shinyResizeObserver.ts", "../../../../srcts/src/components/tooltip.ts", "../../../../srcts/src/components/popover.ts", "../../../../srcts/src/components/inputDarkMode.ts", "../../../../srcts/src/components/webcomponents/_makeInputBinding.ts", "../../../../srcts/src/components/webcomponents/_shinyAddCustomMessageHandlers.ts", "../../../../srcts/src/components/webComponents.ts"], - "sourcesContent": ["/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/*\n * IMPORTANT: For compatibility with tsickle and the Closure JS compiler, all\n * property decorators (but not class decorators) in this file that have\n * an @ExportDecoratedItems annotation must be defined as a regular function,\n * not an arrow function.\n */\nimport {PropertyDeclaration, ReactiveElement} from '../reactive-element.js';\nimport {ClassElement} from './base.js';\n\nconst standardProperty = (\n options: PropertyDeclaration,\n element: ClassElement\n) => {\n // When decorating an accessor, pass it through and add property metadata.\n // Note, the `hasOwnProperty` check in `createProperty` ensures we don't\n // stomp over the user's accessor.\n if (\n element.kind === 'method' &&\n element.descriptor &&\n !('value' in element.descriptor)\n ) {\n return {\n ...element,\n finisher(clazz: typeof ReactiveElement) {\n clazz.createProperty(element.key, options);\n },\n };\n } else {\n // createProperty() takes care of defining the property, but we still\n // must return some kind of descriptor, so return a descriptor for an\n // unused prototype field. The finisher calls createProperty().\n return {\n kind: 'field',\n key: Symbol(),\n placement: 'own',\n descriptor: {},\n // store the original key so subsequent decorators have access to it.\n originalKey: element.key,\n // When @babel/plugin-proposal-decorators implements initializers,\n // do this instead of the initializer below. See:\n // https://github.com/babel/babel/issues/9260 extras: [\n // {\n // kind: 'initializer',\n // placement: 'own',\n // initializer: descriptor.initializer,\n // }\n // ],\n initializer(this: {[key: string]: unknown}) {\n if (typeof element.initializer === 'function') {\n this[element.key as string] = element.initializer.call(this);\n }\n },\n finisher(clazz: typeof ReactiveElement) {\n clazz.createProperty(element.key, options);\n },\n };\n }\n};\n\nconst legacyProperty = (\n options: PropertyDeclaration,\n proto: Object,\n name: PropertyKey\n) => {\n (proto.constructor as typeof ReactiveElement).createProperty(name, options);\n};\n\n/**\n * A property decorator which creates a reactive property that reflects a\n * corresponding attribute value. When a decorated property is set\n * the element will update and render. A {@linkcode PropertyDeclaration} may\n * optionally be supplied to configure property features.\n *\n * This decorator should only be used for public fields. As public fields,\n * properties should be considered as primarily settable by element users,\n * either via attribute or the property itself.\n *\n * Generally, properties that are changed by the element should be private or\n * protected fields and should use the {@linkcode state} decorator.\n *\n * However, sometimes element code does need to set a public property. This\n * should typically only be done in response to user interaction, and an event\n * should be fired informing the user; for example, a checkbox sets its\n * `checked` property when clicked and fires a `changed` event. Mutating public\n * properties should typically not be done for non-primitive (object or array)\n * properties. In other cases when an element needs to manage state, a private\n * property decorated via the {@linkcode state} decorator should be used. When\n * needed, state properties can be initialized via public properties to\n * facilitate complex interactions.\n *\n * ```ts\n * class MyElement {\n * @property({ type: Boolean })\n * clicked = false;\n * }\n * ```\n * @category Decorator\n * @ExportDecoratedItems\n */\nexport function property(options?: PropertyDeclaration) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (protoOrDescriptor: Object | ClassElement, name?: PropertyKey): any =>\n name !== undefined\n ? legacyProperty(options!, protoOrDescriptor as Object, name)\n : standardProperty(options!, protoOrDescriptor as ClassElement);\n}\n", "/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/*\n * IMPORTANT: For compatibility with tsickle and the Closure JS compiler, all\n * property decorators (but not class decorators) in this file that have\n * an @ExportDecoratedItems annotation must be defined as a regular function,\n * not an arrow function.\n */\n\nimport {decorateProperty} from './base.js';\n\nimport type {ReactiveElement} from '../reactive-element.js';\nimport type {QueryAssignedNodesOptions} from './query-assigned-nodes.js';\n\nconst NODE_MODE = false;\nconst global = NODE_MODE ? globalThis : window;\n\n/**\n * A tiny module scoped polyfill for HTMLSlotElement.assignedElements.\n */\nconst slotAssignedElements =\n global.HTMLSlotElement?.prototype.assignedElements != null\n ? (slot: HTMLSlotElement, opts?: AssignedNodesOptions) =>\n slot.assignedElements(opts)\n : (slot: HTMLSlotElement, opts?: AssignedNodesOptions) =>\n slot\n .assignedNodes(opts)\n .filter(\n (node): node is Element => node.nodeType === Node.ELEMENT_NODE\n );\n\n/**\n * Options for the {@linkcode queryAssignedElements} decorator. Extends the\n * options that can be passed into\n * [HTMLSlotElement.assignedElements](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedElements).\n */\nexport interface QueryAssignedElementsOptions\n extends QueryAssignedNodesOptions {\n /**\n * CSS selector used to filter the elements returned. For example, a selector\n * of `\".item\"` will only include elements with the `item` class.\n */\n selector?: string;\n}\n\n/**\n * A property decorator that converts a class property into a getter that\n * returns the `assignedElements` of the given `slot`. Provides a declarative\n * way to use\n * [`HTMLSlotElement.assignedElements`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedElements).\n *\n * Can be passed an optional {@linkcode QueryAssignedElementsOptions} object.\n *\n * Example usage:\n * ```ts\n * class MyElement {\n * @queryAssignedElements({ slot: 'list' })\n * listItems!: Array;\n * @queryAssignedElements()\n * unnamedSlotEls!: Array;\n *\n * render() {\n * return html`\n * \n * \n * `;\n * }\n * }\n * ```\n *\n * Note, the type of this property should be annotated as `Array`.\n *\n * @category Decorator\n */\nexport function queryAssignedElements(options?: QueryAssignedElementsOptions) {\n const {slot, selector} = options ?? {};\n return decorateProperty({\n descriptor: (_name: PropertyKey) => ({\n get(this: ReactiveElement) {\n const slotSelector = `slot${slot ? `[name=${slot}]` : ':not([name])'}`;\n const slotEl =\n this.renderRoot?.querySelector(slotSelector);\n const elements =\n slotEl != null ? slotAssignedElements(slotEl, options) : [];\n if (selector) {\n return elements.filter((node) => node.matches(selector));\n }\n return elements;\n },\n enumerable: true,\n configurable: true,\n }),\n });\n}\n", "/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\nconst NODE_MODE = false;\nconst global = NODE_MODE ? globalThis : window;\n\n/**\n * Whether the current browser supports `adoptedStyleSheets`.\n */\nexport const supportsAdoptingStyleSheets: boolean =\n global.ShadowRoot &&\n (global.ShadyCSS === undefined || global.ShadyCSS.nativeShadow) &&\n 'adoptedStyleSheets' in Document.prototype &&\n 'replace' in CSSStyleSheet.prototype;\n\n/**\n * A CSSResult or native CSSStyleSheet.\n *\n * In browsers that support constructible CSS style sheets, CSSStyleSheet\n * object can be used for styling along side CSSResult from the `css`\n * template tag.\n */\nexport type CSSResultOrNative = CSSResult | CSSStyleSheet;\n\nexport type CSSResultArray = Array;\n\n/**\n * A single CSSResult, CSSStyleSheet, or an array or nested arrays of those.\n */\nexport type CSSResultGroup = CSSResultOrNative | CSSResultArray;\n\nconst constructionToken = Symbol();\n\nconst cssTagCache = new WeakMap();\n\n/**\n * A container for a string of CSS text, that may be used to create a CSSStyleSheet.\n *\n * CSSResult is the return value of `css`-tagged template literals and\n * `unsafeCSS()`. In order to ensure that CSSResults are only created via the\n * `css` tag and `unsafeCSS()`, CSSResult cannot be constructed directly.\n */\nexport class CSSResult {\n // This property needs to remain unminified.\n ['_$cssResult$'] = true;\n readonly cssText: string;\n private _styleSheet?: CSSStyleSheet;\n private _strings: TemplateStringsArray | undefined;\n\n private constructor(\n cssText: string,\n strings: TemplateStringsArray | undefined,\n safeToken: symbol\n ) {\n if (safeToken !== constructionToken) {\n throw new Error(\n 'CSSResult is not constructable. Use `unsafeCSS` or `css` instead.'\n );\n }\n this.cssText = cssText;\n this._strings = strings;\n }\n\n // This is a getter so that it's lazy. In practice, this means stylesheets\n // are not created until the first element instance is made.\n get styleSheet(): CSSStyleSheet | undefined {\n // If `supportsAdoptingStyleSheets` is true then we assume CSSStyleSheet is\n // constructable.\n let styleSheet = this._styleSheet;\n const strings = this._strings;\n if (supportsAdoptingStyleSheets && styleSheet === undefined) {\n const cacheable = strings !== undefined && strings.length === 1;\n if (cacheable) {\n styleSheet = cssTagCache.get(strings);\n }\n if (styleSheet === undefined) {\n (this._styleSheet = styleSheet = new CSSStyleSheet()).replaceSync(\n this.cssText\n );\n if (cacheable) {\n cssTagCache.set(strings, styleSheet);\n }\n }\n }\n return styleSheet;\n }\n\n toString(): string {\n return this.cssText;\n }\n}\n\ntype ConstructableCSSResult = CSSResult & {\n new (\n cssText: string,\n strings: TemplateStringsArray | undefined,\n safeToken: symbol\n ): CSSResult;\n};\n\nconst textFromCSSResult = (value: CSSResultGroup | number) => {\n // This property needs to remain unminified.\n if ((value as CSSResult)['_$cssResult$'] === true) {\n return (value as CSSResult).cssText;\n } else if (typeof value === 'number') {\n return value;\n } else {\n throw new Error(\n `Value passed to 'css' function must be a 'css' function result: ` +\n `${value}. Use 'unsafeCSS' to pass non-literal values, but take care ` +\n `to ensure page security.`\n );\n }\n};\n\n/**\n * Wrap a value for interpolation in a {@linkcode css} tagged template literal.\n *\n * This is unsafe because untrusted CSS text can be used to phone home\n * or exfiltrate data to an attacker controlled site. Take care to only use\n * this with trusted input.\n */\nexport const unsafeCSS = (value: unknown) =>\n new (CSSResult as ConstructableCSSResult)(\n typeof value === 'string' ? value : String(value),\n undefined,\n constructionToken\n );\n\n/**\n * A template literal tag which can be used with LitElement's\n * {@linkcode LitElement.styles} property to set element styles.\n *\n * For security reasons, only literal string values and number may be used in\n * embedded expressions. To incorporate non-literal values {@linkcode unsafeCSS}\n * may be used inside an expression.\n */\nexport const css = (\n strings: TemplateStringsArray,\n ...values: (CSSResultGroup | number)[]\n): CSSResult => {\n const cssText =\n strings.length === 1\n ? strings[0]\n : values.reduce(\n (acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1],\n strings[0]\n );\n return new (CSSResult as ConstructableCSSResult)(\n cssText,\n strings,\n constructionToken\n );\n};\n\n/**\n * Applies the given styles to a `shadowRoot`. When Shadow DOM is\n * available but `adoptedStyleSheets` is not, styles are appended to the\n * `shadowRoot` to [mimic spec behavior](https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets).\n * Note, when shimming is used, any styles that are subsequently placed into\n * the shadowRoot should be placed *before* any shimmed adopted styles. This\n * will match spec behavior that gives adopted sheets precedence over styles in\n * shadowRoot.\n */\nexport const adoptStyles = (\n renderRoot: ShadowRoot,\n styles: Array\n) => {\n if (supportsAdoptingStyleSheets) {\n (renderRoot as ShadowRoot).adoptedStyleSheets = styles.map((s) =>\n s instanceof CSSStyleSheet ? s : s.styleSheet!\n );\n } else {\n styles.forEach((s) => {\n const style = document.createElement('style');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const nonce = (global as any)['litNonce'];\n if (nonce !== undefined) {\n style.setAttribute('nonce', nonce);\n }\n style.textContent = (s as CSSResult).cssText;\n renderRoot.appendChild(style);\n });\n }\n};\n\nconst cssResultFromStyleSheet = (sheet: CSSStyleSheet) => {\n let cssText = '';\n for (const rule of sheet.cssRules) {\n cssText += rule.cssText;\n }\n return unsafeCSS(cssText);\n};\n\nexport const getCompatibleStyle =\n supportsAdoptingStyleSheets ||\n (NODE_MODE && global.CSSStyleSheet === undefined)\n ? (s: CSSResultOrNative) => s\n : (s: CSSResultOrNative) =>\n s instanceof CSSStyleSheet ? cssResultFromStyleSheet(s) : s;\n", "/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Use this module if you want to create your own base class extending\n * {@link ReactiveElement}.\n * @packageDocumentation\n */\n\nimport {\n getCompatibleStyle,\n adoptStyles,\n CSSResultGroup,\n CSSResultOrNative,\n} from './css-tag.js';\nimport type {\n ReactiveController,\n ReactiveControllerHost,\n} from './reactive-controller.js';\n\n// In the Node build, this import will be injected by Rollup:\n// import {HTMLElement, customElements} from '@lit-labs/ssr-dom-shim';\n\nexport * from './css-tag.js';\nexport type {\n ReactiveController,\n ReactiveControllerHost,\n} from './reactive-controller.js';\n\nconst NODE_MODE = false;\nconst global = NODE_MODE ? globalThis : window;\n\nif (NODE_MODE) {\n global.customElements ??= customElements;\n}\n\nconst DEV_MODE = true;\n\nlet requestUpdateThenable: (name: string) => {\n then: (\n onfulfilled?: (value: boolean) => void,\n _onrejected?: () => void\n ) => void;\n};\n\nlet issueWarning: (code: string, warning: string) => void;\n\nconst trustedTypes = (global as unknown as {trustedTypes?: {emptyScript: ''}})\n .trustedTypes;\n\n// Temporary workaround for https://crbug.com/993268\n// Currently, any attribute starting with \"on\" is considered to be a\n// TrustedScript source. Such boolean attributes must be set to the equivalent\n// trusted emptyScript value.\nconst emptyStringForBooleanAttribute = trustedTypes\n ? (trustedTypes.emptyScript as unknown as '')\n : '';\n\nconst polyfillSupport = DEV_MODE\n ? global.reactiveElementPolyfillSupportDevMode\n : global.reactiveElementPolyfillSupport;\n\nif (DEV_MODE) {\n // Ensure warnings are issued only 1x, even if multiple versions of Lit\n // are loaded.\n const issuedWarnings: Set = (global.litIssuedWarnings ??=\n new Set());\n\n // Issue a warning, if we haven't already.\n issueWarning = (code: string, warning: string) => {\n warning += ` See https://lit.dev/msg/${code} for more information.`;\n if (!issuedWarnings.has(warning)) {\n console.warn(warning);\n issuedWarnings.add(warning);\n }\n };\n\n issueWarning(\n 'dev-mode',\n `Lit is in dev mode. Not recommended for production!`\n );\n\n // Issue polyfill support warning.\n if (global.ShadyDOM?.inUse && polyfillSupport === undefined) {\n issueWarning(\n 'polyfill-support-missing',\n `Shadow DOM is being polyfilled via \\`ShadyDOM\\` but ` +\n `the \\`polyfill-support\\` module has not been loaded.`\n );\n }\n\n requestUpdateThenable = (name) => ({\n then: (\n onfulfilled?: (value: boolean) => void,\n _onrejected?: () => void\n ) => {\n issueWarning(\n 'request-update-promise',\n `The \\`requestUpdate\\` method should no longer return a Promise but ` +\n `does so on \\`${name}\\`. Use \\`updateComplete\\` instead.`\n );\n if (onfulfilled !== undefined) {\n onfulfilled(false);\n }\n },\n });\n}\n\n/**\n * Contains types that are part of the unstable debug API.\n *\n * Everything in this API is not stable and may change or be removed in the future,\n * even on patch releases.\n */\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace ReactiveUnstable {\n /**\n * When Lit is running in dev mode and `window.emitLitDebugLogEvents` is true,\n * we will emit 'lit-debug' events to window, with live details about the update and render\n * lifecycle. These can be useful for writing debug tooling and visualizations.\n *\n * Please be aware that running with window.emitLitDebugLogEvents has performance overhead,\n * making certain operations that are normally very cheap (like a no-op render) much slower,\n * because we must copy data and dispatch events.\n */\n // eslint-disable-next-line @typescript-eslint/no-namespace\n export namespace DebugLog {\n export type Entry = Update;\n export interface Update {\n kind: 'update';\n }\n }\n}\n\ninterface DebugLoggingWindow {\n // Even in dev mode, we generally don't want to emit these events, as that's\n // another level of cost, so only emit them when DEV_MODE is true _and_ when\n // window.emitLitDebugEvents is true.\n emitLitDebugLogEvents?: boolean;\n}\n\n/**\n * Useful for visualizing and logging insights into what the Lit template system is doing.\n *\n * Compiled out of prod mode builds.\n */\nconst debugLogEvent = DEV_MODE\n ? (event: ReactiveUnstable.DebugLog.Entry) => {\n const shouldEmit = (global as unknown as DebugLoggingWindow)\n .emitLitDebugLogEvents;\n if (!shouldEmit) {\n return;\n }\n global.dispatchEvent(\n new CustomEvent('lit-debug', {\n detail: event,\n })\n );\n }\n : undefined;\n\n/*\n * When using Closure Compiler, JSCompiler_renameProperty(property, object) is\n * replaced at compile time by the munged name for object[property]. We cannot\n * alias this function, so we have to use a small shim that has the same\n * behavior when not compiling.\n */\n/*@__INLINE__*/\nconst JSCompiler_renameProperty =

(\n prop: P,\n _obj: unknown\n): P => prop;\n\n/**\n * Converts property values to and from attribute values.\n */\nexport interface ComplexAttributeConverter {\n /**\n * Called to convert an attribute value to a property\n * value.\n */\n fromAttribute?(value: string | null, type?: TypeHint): Type;\n\n /**\n * Called to convert a property value to an attribute\n * value.\n *\n * It returns unknown instead of string, to be compatible with\n * https://github.com/WICG/trusted-types (and similar efforts).\n */\n toAttribute?(value: Type, type?: TypeHint): unknown;\n}\n\ntype AttributeConverter =\n | ComplexAttributeConverter\n | ((value: string | null, type?: TypeHint) => Type);\n\n/**\n * Defines options for a property accessor.\n */\nexport interface PropertyDeclaration {\n /**\n * When set to `true`, indicates the property is internal private state. The\n * property should not be set by users. When using TypeScript, this property\n * should be marked as `private` or `protected`, and it is also a common\n * practice to use a leading `_` in the name. The property is not added to\n * `observedAttributes`.\n */\n readonly state?: boolean;\n\n /**\n * Indicates how and whether the property becomes an observed attribute.\n * If the value is `false`, the property is not added to `observedAttributes`.\n * If true or absent, the lowercased property name is observed (e.g. `fooBar`\n * becomes `foobar`). If a string, the string value is observed (e.g\n * `attribute: 'foo-bar'`).\n */\n readonly attribute?: boolean | string;\n\n /**\n * Indicates the type of the property. This is used only as a hint for the\n * `converter` to determine how to convert the attribute\n * to/from a property.\n */\n readonly type?: TypeHint;\n\n /**\n * Indicates how to convert the attribute to/from a property. If this value\n * is a function, it is used to convert the attribute value a the property\n * value. If it's an object, it can have keys for `fromAttribute` and\n * `toAttribute`. If no `toAttribute` function is provided and\n * `reflect` is set to `true`, the property value is set directly to the\n * attribute. A default `converter` is used if none is provided; it supports\n * `Boolean`, `String`, `Number`, `Object`, and `Array`. Note,\n * when a property changes and the converter is used to update the attribute,\n * the property is never updated again as a result of the attribute changing,\n * and vice versa.\n */\n readonly converter?: AttributeConverter;\n\n /**\n * Indicates if the property should reflect to an attribute.\n * If `true`, when the property is set, the attribute is set using the\n * attribute name determined according to the rules for the `attribute`\n * property option and the value of the property converted using the rules\n * from the `converter` property option.\n */\n readonly reflect?: boolean;\n\n /**\n * A function that indicates if a property should be considered changed when\n * it is set. The function should take the `newValue` and `oldValue` and\n * return `true` if an update should be requested.\n */\n hasChanged?(value: Type, oldValue: Type): boolean;\n\n /**\n * Indicates whether an accessor will be created for this property. By\n * default, an accessor will be generated for this property that requests an\n * update when set. If this flag is `true`, no accessor will be created, and\n * it will be the user's responsibility to call\n * `this.requestUpdate(propertyName, oldValue)` to request an update when\n * the property changes.\n */\n readonly noAccessor?: boolean;\n}\n\n/**\n * Map of properties to PropertyDeclaration options. For each property an\n * accessor is made, and the property is processed according to the\n * PropertyDeclaration options.\n */\nexport interface PropertyDeclarations {\n readonly [key: string]: PropertyDeclaration;\n}\n\ntype PropertyDeclarationMap = Map;\n\ntype AttributeMap = Map;\n\n/**\n * A Map of property keys to values.\n *\n * Takes an optional type parameter T, which when specified as a non-any,\n * non-unknown type, will make the Map more strongly-typed, associating the map\n * keys with their corresponding value type on T.\n *\n * Use `PropertyValues` when overriding ReactiveElement.update() and\n * other lifecycle methods in order to get stronger type-checking on keys\n * and values.\n */\n// This type is conditional so that if the parameter T is not specified, or\n// is `any`, the type will include `Map`. Since T is not\n// given in the uses of PropertyValues in this file, all uses here fallback to\n// meaning `Map`, but if a developer uses\n// `PropertyValues` (or any other value for T) they will get a\n// strongly-typed Map type.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PropertyValues = T extends object\n ? PropertyValueMap\n : Map;\n\n/**\n * Do not use, instead prefer {@linkcode PropertyValues}.\n */\n// This type must be exported such that JavaScript generated by the Google\n// Closure Compiler can import a type reference.\nexport interface PropertyValueMap extends Map {\n get(k: K): T[K];\n set(key: K, value: T[K]): this;\n has(k: K): boolean;\n delete(k: K): boolean;\n}\n\nexport const defaultConverter: ComplexAttributeConverter = {\n toAttribute(value: unknown, type?: unknown): unknown {\n switch (type) {\n case Boolean:\n value = value ? emptyStringForBooleanAttribute : null;\n break;\n case Object:\n case Array:\n // if the value is `null` or `undefined` pass this through\n // to allow removing/no change behavior.\n value = value == null ? value : JSON.stringify(value);\n break;\n }\n return value;\n },\n\n fromAttribute(value: string | null, type?: unknown) {\n let fromValue: unknown = value;\n switch (type) {\n case Boolean:\n fromValue = value !== null;\n break;\n case Number:\n fromValue = value === null ? null : Number(value);\n break;\n case Object:\n case Array:\n // Do *not* generate exception when invalid JSON is set as elements\n // don't normally complain on being mis-configured.\n // TODO(sorvell): Do generate exception in *dev mode*.\n try {\n // Assert to adhere to Bazel's \"must type assert JSON parse\" rule.\n fromValue = JSON.parse(value!) as unknown;\n } catch (e) {\n fromValue = null;\n }\n break;\n }\n return fromValue;\n },\n};\n\nexport interface HasChanged {\n (value: unknown, old: unknown): boolean;\n}\n\n/**\n * Change function that returns true if `value` is different from `oldValue`.\n * This method is used as the default for a property's `hasChanged` function.\n */\nexport const notEqual: HasChanged = (value: unknown, old: unknown): boolean => {\n // This ensures (old==NaN, value==NaN) always returns false\n return old !== value && (old === old || value === value);\n};\n\nconst defaultPropertyDeclaration: PropertyDeclaration = {\n attribute: true,\n type: String,\n converter: defaultConverter,\n reflect: false,\n hasChanged: notEqual,\n};\n\n/**\n * The Closure JS Compiler doesn't currently have good support for static\n * property semantics where \"this\" is dynamic (e.g.\n * https://github.com/google/closure-compiler/issues/3177 and others) so we use\n * this hack to bypass any rewriting by the compiler.\n */\nconst finalized = 'finalized';\n\n/**\n * A string representing one of the supported dev mode warning categories.\n */\nexport type WarningKind = 'change-in-update' | 'migration';\n\nexport type Initializer = (element: ReactiveElement) => void;\n\n/**\n * Base element class which manages element properties and attributes. When\n * properties change, the `update` method is asynchronously called. This method\n * should be supplied by subclassers to render updates as desired.\n * @noInheritDoc\n */\nexport abstract class ReactiveElement\n // In the Node build, this `extends` clause will be substituted with\n // `(globalThis.HTMLElement ?? HTMLElement)`.\n //\n // This way, we will first prefer any global `HTMLElement` polyfill that the\n // user has assigned, and then fall back to the `HTMLElement` shim which has\n // been imported (see note at the top of this file about how this import is\n // generated by Rollup). Note that the `HTMLElement` variable has been\n // shadowed by this import, so it no longer refers to the global.\n extends HTMLElement\n implements ReactiveControllerHost\n{\n // Note: these are patched in only in DEV_MODE.\n /**\n * Read or set all the enabled warning categories for this class.\n *\n * This property is only used in development builds.\n *\n * @nocollapse\n * @category dev-mode\n */\n static enabledWarnings?: WarningKind[];\n\n /**\n * Enable the given warning category for this class.\n *\n * This method only exists in development builds, so it should be accessed\n * with a guard like:\n *\n * ```ts\n * // Enable for all ReactiveElement subclasses\n * ReactiveElement.enableWarning?.('migration');\n *\n * // Enable for only MyElement and subclasses\n * MyElement.enableWarning?.('migration');\n * ```\n *\n * @nocollapse\n * @category dev-mode\n */\n static enableWarning?: (warningKind: WarningKind) => void;\n\n /**\n * Disable the given warning category for this class.\n *\n * This method only exists in development builds, so it should be accessed\n * with a guard like:\n *\n * ```ts\n * // Disable for all ReactiveElement subclasses\n * ReactiveElement.disableWarning?.('migration');\n *\n * // Disable for only MyElement and subclasses\n * MyElement.disableWarning?.('migration');\n * ```\n *\n * @nocollapse\n * @category dev-mode\n */\n static disableWarning?: (warningKind: WarningKind) => void;\n\n /**\n * Adds an initializer function to the class that is called during instance\n * construction.\n *\n * This is useful for code that runs against a `ReactiveElement`\n * subclass, such as a decorator, that needs to do work for each\n * instance, such as setting up a `ReactiveController`.\n *\n * ```ts\n * const myDecorator = (target: typeof ReactiveElement, key: string) => {\n * target.addInitializer((instance: ReactiveElement) => {\n * // This is run during construction of the element\n * new MyController(instance);\n * });\n * }\n * ```\n *\n * Decorating a field will then cause each instance to run an initializer\n * that adds a controller:\n *\n * ```ts\n * class MyElement extends LitElement {\n * @myDecorator foo;\n * }\n * ```\n *\n * Initializers are stored per-constructor. Adding an initializer to a\n * subclass does not add it to a superclass. Since initializers are run in\n * constructors, initializers will run in order of the class hierarchy,\n * starting with superclasses and progressing to the instance's class.\n *\n * @nocollapse\n */\n static addInitializer(initializer: Initializer) {\n this.finalize();\n (this._initializers ??= []).push(initializer);\n }\n\n static _initializers?: Initializer[];\n\n /*\n * Due to closure compiler ES6 compilation bugs, @nocollapse is required on\n * all static methods and properties with initializers. Reference:\n * - https://github.com/google/closure-compiler/issues/1776\n */\n\n /**\n * Maps attribute names to properties; for example `foobar` attribute to\n * `fooBar` property. Created lazily on user subclasses when finalizing the\n * class.\n * @nocollapse\n */\n private static __attributeToPropertyMap: AttributeMap;\n\n /**\n * Marks class as having finished creating properties.\n */\n protected static [finalized] = true;\n\n /**\n * Memoized list of all element properties, including any superclass properties.\n * Created lazily on user subclasses when finalizing the class.\n * @nocollapse\n * @category properties\n */\n static elementProperties: PropertyDeclarationMap = new Map();\n\n /**\n * User-supplied object that maps property names to `PropertyDeclaration`\n * objects containing options for configuring reactive properties. When\n * a reactive property is set the element will update and render.\n *\n * By default properties are public fields, and as such, they should be\n * considered as primarily settable by element users, either via attribute or\n * the property itself.\n *\n * Generally, properties that are changed by the element should be private or\n * protected fields and should use the `state: true` option. Properties\n * marked as `state` do not reflect from the corresponding attribute\n *\n * However, sometimes element code does need to set a public property. This\n * should typically only be done in response to user interaction, and an event\n * should be fired informing the user; for example, a checkbox sets its\n * `checked` property when clicked and fires a `changed` event. Mutating\n * public properties should typically not be done for non-primitive (object or\n * array) properties. In other cases when an element needs to manage state, a\n * private property set with the `state: true` option should be used. When\n * needed, state properties can be initialized via public properties to\n * facilitate complex interactions.\n * @nocollapse\n * @category properties\n */\n static properties: PropertyDeclarations;\n\n /**\n * Memoized list of all element styles.\n * Created lazily on user subclasses when finalizing the class.\n * @nocollapse\n * @category styles\n */\n static elementStyles: Array = [];\n\n /**\n * Array of styles to apply to the element. The styles should be defined\n * using the {@linkcode css} tag function, via constructible stylesheets, or\n * imported from native CSS module scripts.\n *\n * Note on Content Security Policy:\n *\n * Element styles are implemented with `