diff --git a/package.json b/package.json index f6b48363c..4ee4d20ac 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "devDependencies": { "@types/bootstrap": "5.2.2", "@types/node": "^18.11.18", - "@types/rstudio-shiny": "https://github.com/rstudio/shiny#async-receivemessage", + "@types/rstudio-shiny": "https://github.com/rstudio/shiny#main", "@typescript-eslint/eslint-plugin": "^5.48.1", "@typescript-eslint/parser": "^5.48.1", "esbuild": "^0.16.14", diff --git a/srcts/src/components/_utils.ts b/srcts/src/components/_utils.ts index c9d445631..0ec7a84dc 100644 --- a/srcts/src/components/_utils.ts +++ b/srcts/src/components/_utils.ts @@ -72,11 +72,28 @@ function getAllFocusableChildren(el: HTMLElement): HTMLElement[] { return Array.from(focusable) as HTMLElement[]; } +// Use the new `renderContentAsync` if available, otherwise fallback to `renderContent`. +async function shinyRenderContent( + ...args: Parameters<(typeof Shiny)["renderContentAsync"]> +): Promise { + if (!window.Shiny) { + throw new Error("Shiny is not defined"); + } + // renderContentAsync was introduced in Shiny 1.7.0 + if (Shiny.renderContentAsync) { + // eslint-disable-next-line prefer-rest-params + return await Shiny.renderContentAsync.apply(null, args); + } else { + return await Shiny.renderContent.apply(null, args); + } +} + export { InputBinding, registerBinding, hasDefinedProperty, doWindowResizeOnElementResize, getAllFocusableChildren, + shinyRenderContent, }; export type { HtmlDep }; diff --git a/srcts/src/components/accordion.ts b/srcts/src/components/accordion.ts index 4f7ead026..0d12f7245 100644 --- a/srcts/src/components/accordion.ts +++ b/srcts/src/components/accordion.ts @@ -1,5 +1,10 @@ import type { HtmlDep } from "./_utils"; -import { InputBinding, registerBinding, hasDefinedProperty } from "./_utils"; +import { + InputBinding, + registerBinding, + hasDefinedProperty, + shinyRenderContent, +} from "./_utils"; type AccordionItem = { item: HTMLElement; @@ -141,13 +146,13 @@ class AccordionInputBinding extends InputBinding { // If there is still no targetItem, then there are no items in the accordion if (targetItem) { - await Shiny.renderContent( + await shinyRenderContent( targetItem, panel, data.position === "before" ? "beforeBegin" : "afterEnd" ); } else { - await Shiny.renderContent(el, panel); + await shinyRenderContent(el, panel); } // Need to add a reference to the parent id that makes autoclose to work @@ -187,21 +192,21 @@ class AccordionInputBinding extends InputBinding { if (hasDefinedProperty(data, "body")) { const body = target.querySelector(".accordion-body") as HTMLElement; // always exists - await Shiny.renderContent(body, data.body); + await shinyRenderContent(body, data.body); } const header = target.querySelector(".accordion-header") as HTMLElement; // always exists if (hasDefinedProperty(data, "title")) { const title = header.querySelector(".accordion-title") as HTMLElement; // always exists - await Shiny.renderContent(title, data.title); + await shinyRenderContent(title, data.title); } if (hasDefinedProperty(data, "icon")) { const icon = header.querySelector( ".accordion-button > .accordion-icon" ) as HTMLElement; // always exists - await Shiny.renderContent(icon, data.icon); + await shinyRenderContent(icon, data.icon); } }