quarto-dev / quarto-dev/quarto-cli
Dashboard tabset: second tab has inverted row/column layout orientation
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 6k
- Forks
- 458
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
I have:
- searched the issue tracker for similar issues
- installed the latest version of Quarto CLI
- formatted my issue following the Bug Reports guide
Bug description
When a dashboard tabset contains tabs with nested #### Column and ##### Row layout headings, all even-positioned tabs (2nd, 4th, 6th...) render with inverted grid orientation (rows become columns, columns become rows). Odd-positioned tabs render correctly.
Steps to reproduce
---
title: "Second tab has inverted layout orientation"
format: dashboard
---
## Row {.tabset}
### Tab A
#### Column
##### Row
::: {.card title="Card 1"}
Should be side-by-side with Card 2
:::
::: {.card title="Card 2"}
Should be side-by-side with Card 1
:::
### Tab B
#### Column
##### Row
::: {.card title="Card 1"}
Should be side-by-side with Card 2 **BUT IS STACKED**
:::
::: {.card title="Card 2"}
Should be side-by-side with Card 1 **BUT IS STACKED**
:::
### Tab C
#### Column
##### Row
::: {.card title="Card 1"}
Should be side-by-side with Card 2
:::
::: {.card title="Card 2"}
Should be side-by-side with Card 1
:::
Actual behavior
- Tab A: Cards are side-by-side (correct)
- Tab B: Cards are stacked vertically (wrong - layout is inverted)
- Tab C: Cards are side-by-side (correct)
Inspecting the HTML shows Tab B has grid-template-rows where Tab A and C have grid-template-columns, and vice versa for nested elements.
Expected behavior
All three tabs should render identically with cards side-by-side.
Possible root cause analysis
(I updated this as Claude had a few hypotheses before this conclusion we got to after we found a temp workaround of adding new dummy tabs which are hidden)
The bug is in the dashboard Lua filters. Two pieces of global mutable state persist across tab processing:
lastLevelinmain.lua(~line 7683) - tracks the last heading level seencurrentOrientationinlayout.lua(line 123) - tracks current layout orientation
The orientation logic in main.lua (~lines 8087-8097) rotates orientation when a new heading level is encountered:
local toOrientation = dashboard.layout.currentOrientation()
if level ~= lastLevel then
lastLevel = level
toOrientation = dashboard.layout.rotatedOrientation()
end
And orientContents mutates currentOrientation as a side effect.
When processing tabs with nested #### Column (level 4) and ##### Row (level 5):
-
Tab A:
#### Columnis level 4 (new), rotates.##### Rowis level 5 (new), rotates again. After processing,lastLevel=5. -
Tab B:
#### Columnis level 4, butlastLevelis still 5 from Tab A. Since 4 ≠ 5, it rotates when it shouldn't. Then##### Rowis level 5, same as the newlastLevel, so it doesn't rotate when it should. Result: inverted layout. -
Tab C: Same pattern as Tab B, but the double-wrong rotations happen to cancel out and produce the correct layout.
This affects all even-positioned tabs (2, 4, 6...), not just the second one.
The fix should reset lastLevel before processing each tab's contents, so each tab starts fresh rather than inheriting state from the previous sibling.
Your environment
IDE: Positron 2025.02.0-149
OS: Ubuntu 24.04.4 LTS
Quarto check output
Quarto 1.9.35
[✓] Checking versions of quarto binary dependencies...
Pandoc version 3.8.3: OK
Dart Sass version 1.87.0: OK
Deno version 2.4.5: OK
Typst version 0.14.2: OK
[✓] Checking Quarto installation......OK
Version: 1.9.35
Path: /opt/quarto/bin
[✓] Checking R installation...........OK
Version: 4.5.2
knitr: 1.51
rmarkdown: 2.30
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in main.lua around the tab and heading-processing logic near lines 7683 and 8087-8097, then inspect currentOrientation and orientContents in layout.lua around line 123. Reproduce the supplied Quarto dashboard and verify that resetting tab-level state makes every tab render its cards side-by-side.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100