Skip to content

Commit c6994ae

Browse files
authored
Merge pull request #12316 from quarto-dev/shiny-tabby
tabby - Trigger event for shiny rendering when tab change
2 parents 6164de8 + c6c7a3a commit c6994ae

File tree

6 files changed

+153
-24
lines changed

6 files changed

+153
-24
lines changed

news/changelog-1.7.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,18 @@ All changes included in 1.7:
5050
- ([#12277](https://github.com/quarto-dev/quarto-cli/pull/12277)): Provide light and dark plot and table renderings with `renderings: [light,dark]`
5151
- ([#11860](https://github.com/quarto-dev/quarto-cli/issues/11860)): ES6 modules that import other local JS modules in documents with `embed-resources: true` are now correctly embedded.
5252
- ([#1325](https://github.com/quarto-dev/quarto-cli/issues/1325)): Dark Mode pages should not flash light on reload. (Nor should Light Mode pages flash dark.)
53+
- ([#12307](https://github.com/quarto-dev/quarto-cli/issues/12307)): Tabsets using `tabby.js` in non-boostrap html (`theme: pandoc`, `theme: none` or `minimal: true`) now correctly render reactive content when `server: shiny` is used.
5354

5455
## `pdf` format
5556

5657
- ([#11835](https://github.com/quarto-dev/quarto-cli/issues/11835)): Take markdown structure into account when detecting minimum heading level.
5758
- ([#11903](https://github.com/quarto-dev/quarto-cli/issues/11903)): `crossref` configuration like `fig-title` or `tbl-title` now correctly supports multi word values, e.g. `fig-title: 'Supplementary Figure'`.
5859
- ([#11878](https://github.com/quarto-dev/quarto-cli/issues/11878), [#12085](https://github.com/quarto-dev/quarto-cli/issues/12085)): Correctly fixup raw LaTeX table having an unexpected table env with options (e.g `\begin{table}[!ht]`) to be handled as crossref table.
5960

61+
## `revealjs` format
62+
63+
- ([#12307](https://github.com/quarto-dev/quarto-cli/issues/12307)): Tabsets using `tabby.js` in Revealjs now correctly render reactive content when `server: shiny` is used.
64+
6065
### Quarto PDF engine
6166

6267
- ([#12194](https://github.com/quarto-dev/quarto-cli/issues/12194)): More specific checks added in log parsing to automatically find missing fonts.

src/resources/formats/html/quarto.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,41 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
6666
}
6767
};
6868

69-
// fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior)
70-
function fireSlideEnter(e) {
69+
// dispatch for htmlwidgets
70+
// they use slideenter event to trigger resize
71+
function fireSlideEnter() {
7172
const event = window.document.createEvent("Event");
7273
event.initEvent("slideenter", true, true);
7374
window.document.dispatchEvent(event);
7475
}
76+
7577
const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
7678
tabs.forEach((tab) => {
7779
tab.addEventListener("shown.bs.tab", fireSlideEnter);
7880
});
7981

80-
// fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
81-
document.addEventListener("tabby", fireSlideEnter, false);
82+
// dispatch for shiny
83+
// they use BS shown and hidden events to trigger rendering
84+
function distpatchShinyEvents(previous, current) {
85+
if (window.jQuery) {
86+
if (previous) {
87+
window.jQuery(previous).trigger("hidden");
88+
}
89+
if (current) {
90+
window.jQuery(current).trigger("shown");
91+
}
92+
}
93+
}
94+
95+
// tabby.js listener: Trigger event for htmlwidget and shiny
96+
document.addEventListener(
97+
"tabby",
98+
function (event) {
99+
fireSlideEnter();
100+
distpatchShinyEvents(event.detail.previousTab, event.detail.tab);
101+
},
102+
false
103+
);
82104

83105
// Track scrolling and mark TOC links as active
84106
// get table of contents and sidebar (bail if we don't have at least one)

src/resources/formats/revealjs/plugins/support/support.js

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -281,36 +281,49 @@ window.QuartoSupport = function () {
281281
}
282282
}
283283

284+
// dispatch for htmlwidgets
285+
// they use slideenter event to trigger resize
286+
const fireSlideEnter = () => {
287+
const event = window.document.createEvent("Event");
288+
event.initEvent("slideenter", true, true);
289+
window.document.dispatchEvent(event);
290+
};
291+
292+
// dispatch for shiny
293+
// they use BS shown and hidden events to trigger rendering
294+
const distpatchShinyEvents = (previous, current) => {
295+
if (window.jQuery) {
296+
if (previous) {
297+
window.jQuery(previous).trigger("hidden");
298+
}
299+
if (current) {
300+
window.jQuery(current).trigger("shown");
301+
}
302+
}
303+
};
304+
284305
function handleSlideChanges(deck) {
285-
// dispatch for htmlwidgets
286-
const fireSlideEnter = () => {
287-
const event = window.document.createEvent("Event");
288-
event.initEvent("slideenter", true, true);
289-
window.document.dispatchEvent(event);
290-
};
291306

292307
const fireSlideChanged = (previousSlide, currentSlide) => {
293308
fireSlideEnter();
294-
295-
// dispatch for shiny
296-
if (window.jQuery) {
297-
if (previousSlide) {
298-
window.jQuery(previousSlide).trigger("hidden");
299-
}
300-
if (currentSlide) {
301-
window.jQuery(currentSlide).trigger("shown");
302-
}
303-
}
309+
distpatchShinyEvents(previousSlide, currentSlide);
304310
};
305311

306-
// fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
307-
document.addEventListener("tabby", fireSlideEnter, false);
308-
309312
deck.on("slidechanged", function (event) {
310313
fireSlideChanged(event.previousSlide, event.currentSlide);
311314
});
312315
}
313316

317+
function handleTabbyChanges() {
318+
const fireTabChanged = (previousTab, currentTab) => {
319+
fireSlideEnter()
320+
distpatchShinyEvents(previousTab, currentTab);
321+
};
322+
document.addEventListener("tabby", function(event) {
323+
fireTabChanged(event.detail.previousTab, event.detail.tab);
324+
}, false);
325+
}
326+
314327
function workaroundMermaidDistance(deck) {
315328
if (window.document.querySelector("pre.mermaid-js")) {
316329
const slideCount = deck.getTotalSlides();
@@ -390,6 +403,7 @@ window.QuartoSupport = function () {
390403
addFooter(deck);
391404
addChalkboardButtons(deck);
392405
handleTabbyClicks();
406+
handleTabbyChanges();
393407
handleSlideChanges(deck);
394408
workaroundMermaidDistance(deck);
395409
handleWhiteSpaceInColumns(deck);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
title: "Title"
3+
format: html
4+
server: shiny
5+
_quarto:
6+
playwright-test: serve/shiny-r/shiny-tabby-html.spec.ts
7+
---
8+
9+
```{r}
10+
#| context: server
11+
output$text1 <- renderText({
12+
"hi, it's tab 1"
13+
})
14+
output$text2 <- renderText({
15+
"hi, it's tab 2"
16+
})
17+
output$text3 <- renderText({
18+
"hi, it's tab 3"
19+
})
20+
```
21+
22+
## Slide
23+
24+
::: {.panel-tabset}
25+
26+
### tab1
27+
28+
```{r}
29+
textOutput("text1")
30+
```
31+
32+
### tab2
33+
34+
```{r}
35+
textOutput("text2")
36+
```
37+
38+
### tab3
39+
40+
```{r}
41+
textOutput("text3")
42+
```
43+
44+
:::
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
title: "Title"
3+
format: revealjs
4+
server: shiny
5+
_quarto:
6+
playwright-test: serve/shiny-r/shiny-tabby-reveal.spec.ts
7+
---
8+
9+
```{r}
10+
#| context: server
11+
output$text1 <- renderText({
12+
"hi, it's tab 1"
13+
})
14+
output$text2 <- renderText({
15+
"hi, it's tab 2"
16+
})
17+
output$text3 <- renderText({
18+
"hi, it's tab 3"
19+
})
20+
```
21+
22+
## Slide
23+
24+
::: {.panel-tabset}
25+
26+
### tab1
27+
28+
```{r}
29+
textOutput("text1")
30+
```
31+
32+
### tab2
33+
34+
```{r}
35+
textOutput("text2")
36+
```
37+
38+
### tab3
39+
40+
```{r}
41+
textOutput("text3")
42+
```
43+
44+
:::

tests/integration/playwright-tests.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async function fullInit() {
2424
const globOutput = Deno.args.length
2525
? expandGlobSync(Deno.args[0])
2626
: expandGlobSync(
27-
"docs/playwright/**/*.qmd",
27+
"docs/playwright/!(serve|shiny)/**/*.qmd",
2828
);
2929

3030
setInitializer(fullInit);

0 commit comments

Comments
 (0)