Merge pull request #31281 from backstage/fix-bui-tabs

fix(bui): remove default selection for tabs that have href defined
This commit is contained in:
Charles de Dreuille
2025-10-07 10:13:55 +02:00
committed by GitHub
4 changed files with 81 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/ui': patch
---
Remove auto selection of tabs for tabs that all have href defined
@@ -148,7 +148,11 @@ export const WithCustomActions: Story = {
<>
<Button>Custom action</Button>
<MenuTrigger>
<ButtonIcon variant="tertiary" icon={<RiMore2Line />} />
<ButtonIcon
variant="tertiary"
icon={<RiMore2Line />}
aria-label="More options"
/>
<Menu placement="bottom end">
{menuItems.map(option => (
<MenuItem
@@ -455,3 +455,60 @@ export const RootPathMatching: Story = {
</MemoryRouter>
),
};
export const AutoSelectionOfTabs: Story = {
args: {
children: '',
},
render: () => (
<MemoryRouter initialEntries={['/random-page']}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
<Text style={{ fontSize: '16px', color: '#666' }}>
Current URL: <strong>/random-page</strong>
</Text>
{/* Without hrefs */}
<Text>
{' '}
<strong>Case 1: Without hrefs</strong>
</Text>
<Tabs>
<TabList>
<Tab id="settings">Settings</Tab>
<Tab id="preferences">Preferences</Tab>
<Tab id="advanced">Advanced</Tab>
</TabList>
<TabPanel id="settings">
<Text>Settings content - React Aria manages this selection</Text>
</TabPanel>
<TabPanel id="preferences">
<Text>Preferences content - works normally</Text>
</TabPanel>
<TabPanel id="advanced">
<Text>Advanced content - local state only</Text>
</TabPanel>
</Tabs>
{/* With hrefs */}
<Text>
{' '}
<strong>Case 2: With hrefs</strong> By default no selection is shown
because the URL doesn't match any tab's href.{' '}
</Text>
<Tabs>
<TabList>
<Tab id="catalog" href="/catalog">
Catalog
</Tab>
<Tab id="create" href="/create">
Create
</Tab>
<Tab id="docs" href="/docs">
Docs
</Tab>
</TabList>
</Tabs>
</div>
</MemoryRouter>
),
};
+14 -1
View File
@@ -115,9 +115,22 @@ export const Tabs = (props: TabsProps) => {
}
}
}
//No route matches - check if all tabs have hrefs (pure navigation)
const allTabsHaveHref = tabListChildren.every(
child => isValidElement(child) && child.props.href,
);
if (allTabsHaveHref) {
// Pure navigation tabs, no route match
return null;
} else {
// Mixed tabs or pure local state
return undefined;
}
}
}
return null;
return undefined;
})();
if (!children) return null;