Skip to content

fix(Tabs): select nav tab from initial hash#12297

Open
tarunvashishth wants to merge 1 commit intopatternfly:mainfrom
tarunvashishth:fix/tabs-initial-hash-nav
Open

fix(Tabs): select nav tab from initial hash#12297
tarunvashishth wants to merge 1 commit intopatternfly:mainfrom
tarunvashishth:fix/tabs-initial-hash-nav

Conversation

@tarunvashishth
Copy link
Copy Markdown

@tarunvashishth tarunvashishth commented Mar 27, 2026

closes #12094

Summary by CodeRabbit

  • New Features

    • Tabs now support URL hash-based selection for navigation-style tabs. Tabs automatically select based on the page's URL fragment, and selections update when the URL hash changes.
  • Tests

    • Added comprehensive tests for URL hash-driven tab selection behavior.
  • Documentation

    • Added new example demonstrating hash-based tab selection on initial page load.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

Walkthrough

The Tabs component now derives the active tab from URL hash fragments for nav-style tabs, addressing a bug where direct URL access with hash anchors did not highlight the corresponding tab. This includes state management for hash tracking, event listener initialization, and fallback logic preserving existing controlled/uncontrolled behavior when no matching hash is present.

Changes

Cohort / File(s) Summary
Core Implementation
packages/react-core/src/components/Tabs/Tabs.tsx
Added URL hash-based tab selection: tracks currentUrlHash in state, initializes from window.location.hash, listens to hashchange events, and derives active tab from matching href values for nav-style tabs only. Updated mount-on-enter logic and derived state to use URL-derived key when available, with fallback to existing activeKey/defaultActiveKey semantics.
Test Coverage
packages/react-core/src/components/Tabs/__tests__/Tabs.test.tsx
Added navTabs test data and ControlledNavTabs component for nav-tab testing. Introduced two test cases: one verifying initial tab selection from pre-set hash, and another confirming dynamic tab switching when hash changes post-render via hashchange event. Added afterEach cleanup to reset window.location.hash.
Documentation & Examples
packages/react-core/src/components/Tabs/examples/Tabs.md, packages/react-core/src/components/Tabs/examples/TabsNavInitialHash.tsx
Added documentation reference and new example component TabsNavInitialHash demonstrating nav-style tabs with hash-based selection, including tab definitions with href properties, state management, and onSelect handler wiring.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • nicolethoen
  • thatblindgeye
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: enabling nav-style Tabs to select the correct tab based on URL hash on initial load.
Linked Issues check ✅ Passed The changes directly address issue #12094 by implementing URL hash detection for nav-style Tabs to highlight the correct tab on initial page load.
Out of Scope Changes check ✅ Passed All changes are scope-aligned: Tabs component now derives active state from URL hash, tests verify hash-based selection behavior, and examples demonstrate the feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/tabs-initial-hash-nav

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@patternfly-build
Copy link
Copy Markdown
Collaborator

patternfly-build commented Mar 27, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/react-core/src/components/Tabs/Tabs.tsx`:
- Around line 217-229: Tabs currently lets the URL hash override props.activeKey
even in controlled mode: change Tabs.getActiveKeyFromProps to only consider
Tabs.getActiveKeyFromCurrentUrl when the component is uncontrolled (i.e.,
props.activeKey is undefined), so controlled consumers remain authoritative;
likewise, in the internal routine that writes the hash (the code that updates
the URL hash without notifying the parent), either skip updating the URL when
props.activeKey is provided or invoke the owner callback (e.g.,
onSelect/onChange) so the parent can sync before the hash becomes authoritative.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 11069d60-5d7e-45ac-a245-2d32b5b7c58d

📥 Commits

Reviewing files that changed from the base of the PR and between 4e03cd7 and 521d5d1.

📒 Files selected for processing (4)
  • packages/react-core/src/components/Tabs/Tabs.tsx
  • packages/react-core/src/components/Tabs/__tests__/Tabs.test.tsx
  • packages/react-core/src/components/Tabs/examples/Tabs.md
  • packages/react-core/src/components/Tabs/examples/TabsNavInitialHash.tsx

Comment on lines +217 to +229
static getActiveKeyFromProps = (
props: TabsProps,
uncontrolledActiveKey: TabsState['uncontrolledActiveKey'],
currentUrlHash?: string
) => {
const activeKeyFromCurrentUrl = Tabs.getActiveKeyFromCurrentUrl(props, currentUrlHash);

if (activeKeyFromCurrentUrl !== undefined) {
return activeKeyFromCurrentUrl;
}

return props.defaultActiveKey !== undefined ? uncontrolledActiveKey : props.activeKey;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Keep activeKey authoritative in controlled mode.

Lines 224-228 make the hash match win over props.activeKey, and Lines 411-420 update that hash internally without notifying the owner. A controlled <Tabs activeKey={...}> can now render a different selected tab than the parent state on initial load or after hashchange, which breaks separate-content patterns and any parent UI derived from activeKey. Either scope hash resolution to uncontrolled tabs, or add a callback path that keeps the owner in sync before the hash becomes authoritative.

Also applies to: 411-420

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/Tabs/Tabs.tsx` around lines 217 - 229,
Tabs currently lets the URL hash override props.activeKey even in controlled
mode: change Tabs.getActiveKeyFromProps to only consider
Tabs.getActiveKeyFromCurrentUrl when the component is uncontrolled (i.e.,
props.activeKey is undefined), so controlled consumers remain authoritative;
likewise, in the internal routine that writes the hash (the code that updates
the URL hash without notifying the parent), either skip updating the URL when
props.activeKey is provided or invoke the owner callback (e.g.,
onSelect/onChange) so the parent can sync before the hash becomes authoritative.

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.

Bug - Tabs - Tabs linked to nav elements does not highlight url from anchor

2 participants