Skip to content

[6.x] Mirror the selected tab in the location hash - #19862

Closed
brianjhanson wants to merge 1 commit into
6.xfrom
fix/tabs-location-hash
Closed

brianjhanson wants to merge 1 commit into
6.xfrom
fix/tabs-location-hash

Conversation

@brianjhanson

Copy link
Copy Markdown
Contributor

Selecting a tab now puts its panel's id in location.hash, and a hash present on load selects the tab that owns it. A tab is a place in the control panel, so it gets a URL.

sync-location-hash is on by default, and sync-location-hash="false" turns it off for a strip that isn't the page's own — a dialog, or a slideout over a page whose URL belongs to what's behind it.

Only a panel's id becomes a hash

A hash is written only for a tab naming its panel through controls. That id comes from the page, so it means something in a URL and survives a reload. A slotted strip's ids are generated per render, so there is nothing to link to and nothing is written — which is what makes the default safe to turn on everywhere rather than something each caller has to opt into.

The selection is written with replaceState: moving between tabs isn't navigation, and a history entry per tab would make Back walk them instead of leaving the page. A hashchange listener follows the hash the other way, so Back, Forward and in-page links all land on the right tab.

_layouts/cp keeps the hash

That layout removed the hash on load, to stop the browser scrolling to the element it named. Tabs are what the hash names now, and the component selects the tab rather than scrolling to it, so the hash stays. window.LOCATION_HASH is still published for the legacy tab manager.

Leaving it on the URL is also what carries a tab across a save: the document fragment survives the post, and a redirect that specifies none inherits it.

Verification

On a screen with tabs: clicking a tab adds its panel's id to the URL, loading that URL selects the tab and shows its panel, and saving returns to the tab it was on. Eight new tests cover selection from the hash on load, writing on select, following hashchange, ignoring a hash that names no panel, the default being on, turning it off, and nothing written for a slotted strip.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NjeigCjRgjTJpnhbvyrxv8

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

📚 Storybook previews

@craftcms/ui — open Storybook

Changed components:

resources/js — open Storybook

No changed components detected in this Storybook.

@brianjhanson

Copy link
Copy Markdown
Contributor Author

Superseded by #19884, which carries tabs.ts, tabs.test.ts and Cp/Components/Tabs.php byte-identical to this branch and builds the bridged-screen shell on top of the same _layouts/cp changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant