Core renders stacks as a bslib::accordion(), and bslib opens the first panel and leaves the rest collapsed. On a board with two stacks the rendered markup is accordion-collapse collapse show for the first and accordion-collapse collapse for the second, so half the blocks are hidden from the moment the board loads — and any stack can be collapsed by the user afterwards. Those blocks evaluate and render regardless, because nothing in core consumes its own visibility signal.
The signal is already there. The accordion container renders as <div class="accordion bslib-accordion-input" id="my_board_stacks">, so bslib has wired it as a Shiny input reporting which panels are open, and each item carries data-value naming its stack. Nothing under R/ reads it.
What to build
Core's own UI becomes an owner in the multi-owner claim set that #337 introduced, on the same footing as blockr.dock: it declares the gate under an owner label, and claims the blocks of every open stack plus every unstacked block. Collapsing a stack releases its blocks, expanding one claims them back. The accordion input is also the client reporting what it has painted, so it can feed the visible axis too — though demand should keep leading acknowledgement rather than being derived from it, for the reason in #321.
This is the first consumer of that claim set from inside core, and a useful check on it: if core's own UI cannot sit in the set as comfortably as a front-end does, the shape is wrong.
The parts that need thought
The accordion input is not in the board module's namespace. The container id is built as paste0(id, "_stacks") in stack_ui.board() rather than through NS(), so it renders as my_board_stacks where the module's own inputs are prefixed my_board-. The board server therefore cannot read it as input[["..."]] without reaching for the root session. Changing the id to ns("stacks") is the cleaner fix, and the container id is not referenced anywhere else — but it is a DOM-visible change, so anything selecting on it downstream needs checking first.
Turning this on flips core boards from eager to lazy. Today expanding a stack reveals a computed result; afterwards it would start the computation, with whatever wait that implies. That is the point of the feature, but it is a visible behaviour change and wants its own opt-in: gate_visibility already defaults to TRUE, so having core declare the gate unconditionally would flip every stacked board at once.
The opening claim is derivable server-side. Because bslib opens the first panel by default, core knows the initial open set without waiting for the client, and can declare and claim synchronously as the board server is set up. That sidesteps the constraint measured in #337, where a gate arriving by payload lands after the first flush has already decided what to construct.
Blocks that belong to no stack are always visible and simply stay claimed.
Core renders stacks as a
bslib::accordion(), andbslibopens the first panel and leaves the rest collapsed. On a board with two stacks the rendered markup isaccordion-collapse collapse showfor the first andaccordion-collapse collapsefor the second, so half the blocks are hidden from the moment the board loads — and any stack can be collapsed by the user afterwards. Those blocks evaluate and render regardless, because nothing in core consumes its own visibility signal.The signal is already there. The accordion container renders as
<div class="accordion bslib-accordion-input" id="my_board_stacks">, sobslibhas wired it as a Shiny input reporting which panels are open, and each item carriesdata-valuenaming its stack. Nothing underR/reads it.What to build
Core's own UI becomes an owner in the multi-owner claim set that #337 introduced, on the same footing as blockr.dock: it declares the gate under an owner label, and claims the blocks of every open stack plus every unstacked block. Collapsing a stack releases its blocks, expanding one claims them back. The accordion input is also the client reporting what it has painted, so it can feed the
visibleaxis too — though demand should keep leading acknowledgement rather than being derived from it, for the reason in #321.This is the first consumer of that claim set from inside core, and a useful check on it: if core's own UI cannot sit in the set as comfortably as a front-end does, the shape is wrong.
The parts that need thought
The accordion input is not in the board module's namespace. The container id is built as
paste0(id, "_stacks")instack_ui.board()rather than throughNS(), so it renders asmy_board_stackswhere the module's own inputs are prefixedmy_board-. The board server therefore cannot read it asinput[["..."]]without reaching for the root session. Changing the id tons("stacks")is the cleaner fix, and the container id is not referenced anywhere else — but it is a DOM-visible change, so anything selecting on it downstream needs checking first.Turning this on flips core boards from eager to lazy. Today expanding a stack reveals a computed result; afterwards it would start the computation, with whatever wait that implies. That is the point of the feature, but it is a visible behaviour change and wants its own opt-in:
gate_visibilityalready defaults toTRUE, so having core declare the gate unconditionally would flip every stacked board at once.The opening claim is derivable server-side. Because
bslibopens the first panel by default, core knows the initial open set without waiting for the client, and can declare and claim synchronously as the board server is set up. That sidesteps the constraint measured in #337, where a gate arriving by payload lands after the first flush has already decided what to construct.Blocks that belong to no stack are always visible and simply stay claimed.