Skip to content

Conversation

twjeffery
Copy link
Collaborator

@twjeffery twjeffery commented Oct 9, 2025

Summary

Updates the Tabs component to support V2 design system styling while
maintaining full backward compatibility with V1.

Changes

New Props

  • version ("1" | "2", default "1"): Controls V1 vs V2 styling

V2 Styling Updates

Typography & Colors

  • Active tabs: Semibold weight with blue text
    (color.interactive.default)
  • Inactive tabs: Medium weight with grey text (color.greyscale.600)
  • Hover state: Medium weight with black text (color.text.default)
  • All tabs now use 16px/22px typography with -0.5px letter spacing

Spacing

  • Gap between tabs reduced from 32px to 16px on desktop
  • Desktop padding: 8px 4px 9px 4px (adjusted for 3px indicator + visual
    spacing)
  • Mobile padding: 4px 12px 4px 15px (accommodates left-side indicator)

Active Indicators

  • Desktop: 3px height bottom indicator with rounded top corners (6px)
  • Mobile: 3px width left indicator with rounded right corners (6px)
  • Active state: Blue indicator (color.interactive.default)
  • Hover state: Grey indicator (color.greyscale.300) with rounded corners

State Styling

  • Focus: Updated focus outline width to 4px (from 3px)
  • Hover (Desktop): Bottom border changes to grey underline with
    rounded corners
  • Hover (Mobile): Left border changes to grey with light grey
    background (color.greyscale.50)
  • Container: Updated bottom border color to lighter grey
    (color.greyscale.150)

Other Improvements

  • Mobile active tabs maintain light blue background (color.info.light)
  • Responsive behavior preserved (horizontal desktop, vertical mobile)
  • All state transitions use token-driven colors

Technical Implementation

Token + CSS Approach

  • Pseudo-elements (::after) required for rounded corner indicators
  • CSS borders cannot apply border-radius to specific corners
  • Positioned absolutely within relatively positioned tabs

V2 CSS Scoping

  • All V2-specific styles use .v2 class selector
  • V1 behavior preserved exactly as-is
  • Structural changes isolated to V2 scope

Testing

All changes tested in web components playground with:

  • Desktop and mobile layouts (responsive transition)
  • All tab states (default, active, hover, focus)
  • Multiple tab counts (2, 3, 5, 8+ tabs)
  • Keyboard navigation (arrow keys, Home, End)
  • Hash-based routing and deep linking
  • Tab change events and initial tab selection

Related

@twjeffery twjeffery changed the title feat(#3057): accordion v2 styling update feat(#3095): tabs v2 styling update Oct 9, 2025
@twjeffery twjeffery changed the title feat(#3095): tabs v2 styling update feat(#3095): Tabs v2 styling update Oct 9, 2025
@twjeffery twjeffery linked an issue Oct 9, 2025 that may be closed by this pull request
@twjeffery twjeffery marked this pull request as ready for review October 10, 2025 00:06
@twjeffery twjeffery requested a review from bdfranck October 10, 2025 00:07
Copy link
Collaborator

@bdfranck bdfranck left a comment

Choose a reason for hiding this comment

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

Looks good! You just need to add fallback values for those tokens that don't have v1 values.

gap: var(--goa-tabs-gap-small-screen);
padding-bottom: var(--goa-space-m);
margin-bottom: 2rem;
padding-bottom: var(--goa-tabs-padding-bottom-mobile);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This variable is undefined with v1 tokens. Don't forget to add the space-m fallback.

:global([role="tab"][aria-selected="true"]) {
font: var(--goa-tab-typography-selected);
color: var(--goa-tab-color-text-selected);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This variable is undefined with v1 tokens.

border: none;
font: var(--goa-tab-typography);
color: var(--goa-tab-text-color);
color: var(--goa-tab-color-text-not-selected);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This variable is undefined with v1 tokens.

:global([role="tab"]:hover:not([aria-selected="true"])) {
border-bottom: var(--goa-tab-border-hover);
color: var(--goa-tab-color-text-hover);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This variable is undefined with v1 tokens.

border-left: var(--goa-tab-border-hover);
border-bottom: none;
border-left: var(--goa-tab-border-hover);
background: var(--goa-tab-color-bg-hover-small-screen);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This variable is undefined with v1 tokens.

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.

Tabs 2.0 Update

2 participants