Summary
<Tabs> with <TabPanel> children — the slot API documented in the component's own header comment — renders a tab strip with no tabs, and every panel stays hidden. The component is invisible: no strip, no content.
Reproduction
<Tabs>
<TabPanel label="Overview">TAB-ONE-BODY</TabPanel>
<TabPanel label="History">TAB-TWO-BODY</TabPanel>
</Tabs>Measured in the browser:
document.querySelectorAll('[data-stx-tab-panel]').length // 2 ← panels are there
document.querySelectorAll('[role="tab"]').length // 0 ← no tabs rendered
document.body.innerText.includes('TAB-ONE-BODY') // falseThe panels are present, inside the [data-stx-tabs] root, and correctly attributed:
data-stx-tab-panel, data-label="Overview", data-icon, class, role, tabindex, hiddenSo the DOM contract Tabs.stx describes is satisfied. What does not happen is the other half: discoveredTabs stays [], the :for over it renders nothing, and because no tab is ever selected, both panels keep their hidden attribute forever.
No console errors.
Where it goes wrong
Tabs.stx:
const discoveredTabs = state(hasPropTabs ? tabs : [])and, in slot mode, onMount is supposed to enumerate [data-stx-tab-panel] descendants and call discoveredTabs.set(list). Either that mount hook is not running, or the :for does not re-render when the signal updates after mount. I did not narrow which — but the observable result is the same either way, and the legacy prop API (tabs={[…]}) is unaffected, which points at the discovery path specifically.
Expected
<Tabs> + <TabPanel> renders a tab per panel and shows defaultTab's content.
A failure here is silent and total — the author sees an empty area with no error — so it would be worth having the component warn when it is in slot mode and finds zero panels after mount.
Environment
@stacksjs/components0.2.339, stacks 0.75.31, Bun 1.3.x, macOS- The slot API was added in #1703; this report is about that path, not the prop API.
- Found while migrating hq.training onto the component library.