Tab — hover shows a filled button/pill shape instead of a bottom bar
- Dominant language
- TypeScript
- Stars
- 13k
- Forks
- 1.1k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 690
Description
**Component:** `XDSTab`
**Type:** Bug — hover styling
### Description
Hovering an unselected `XDSTab` renders a **filled button/pill shape** behind the tab, rather than showing a **bottom bar** consistent with the selected-tab indicator.
In `packages/core/src/TabList/XDSTab.tsx`, hover is driven by a full-size background element (`hoverBg`), which fills the tab with an overlay color and a rounded radius:
```tsx
hoverBg: {
position: 'absolute',
inset: 0,
width: '100%',
borderRadius: radiusVars['--radius-element'], // ← rounded "button" shape
backgroundColor: {
default: 'transparent',
[stylex.when.ancestor(':hover', tabScope)]: {
'@media (hover: hover)': colorVars['--color-overlay-hover'], // ← filled background
},
},
…
},
```
This `hoverBgElement` is rendered for every tab and sized to the full tab (`hoverSizeStyles[size]`), so on hover it reads as a button/pill.
Meanwhile the bottom-bar `indicator` only shows when selected — unselected tabs get `indicatorUnselected` (`opacity: 0`, `backgroundColor: 'transparent'`), so hover never reveals the bar:
```tsx
indicatorSelected: { backgroundColor: colorVars['--color-icon-primary'], opacity: 1 },
indicatorUnselected: { backgroundColor: 'transparent', opacity: 0 },
```
### Proposed fix
Make hover use the **bottom-bar indicator** rather than a filled background:
- On hover of an unselected tab, show the `indicator` bar (e.g. a muted/secondary color, or reduced opacity) so the affordance matches the selected state — just a bottom bar, not a pill.
- Remove (or neutralize) the `hoverBg` filled-background + `--radius-element` treatment so hover no longer produces a button/pill shape. If a subtle background or text-color shift on hover is still desired, keep it minimal and avoid the rounded full-tab fill.
- Keep the selected indicator visually distinct from the hover indicator (e.g. selected = `--color-icon-primary` full opacity; hover = muted), and ensure it only applies under `@media (hover: hover)`.
End result: hovering a tab reveals a bottom bar consistent with the selected tab, not a button shape.
---
_Split out from the tracking issue #2631 (item 17 of 17)._
Contributor guide
Assessment
This issue has not been assessed yet.