Skip to content

feat: component docs styles tab#328

Open
hcopp wants to merge 30 commits intomasterfrom
hunter/navbar-classnames
Open

feat: component docs styles tab#328
hcopp wants to merge 30 commits intomasterfrom
hunter/navbar-classnames

Conversation

@hcopp
Copy link
Contributor

@hcopp hcopp commented Jan 26, 2026

What changed? Why?

This PR adds

  • StylesAndClassnames type (for web) to enable shared static classnames that share the same key as styles and classnames
  • Styles tab to doc site showcasing styles table and explorer (for use cases of styles only or styles & static classnames)
  • Styles props (and static classnames) to NavigationBar - this is a guinea pig component for static classnames
  • New cursor command to support adding component styles to a component (tested with NavigationBar)
    • Not 100% confident in this command yet as we haven't tested it widespread, it should be improved incrementally
  • Updates to existing component docs to support this styles tab
    • Tested this with all components in web and mobile that supported styles, to great success

Future tasks

  • Support data attributes in styles tab
  • (optional) show styles tab for components taht do not support styles/classNames but have a root static className or data attributes (such as button if we don't add styles)
  • Concrete decision on when to support static classNames for a component
  • Update component style descriptions/make descriptions consistent across the board

Styles tab

Selectors

This table is generated by docgen by trying to select the styles prop from a component. It also looks for this new StylesAndClassNames

export type StylesAndClassNames<ComponentClassNamesMap extends Record<string, string>> = {
  classNames?: { [key in keyof ComponentClassNamesMap]?: string };
  styles?: { [key in keyof ComponentClassNamesMap]?: React.CSSProperties };
};

it uses these values to display one of two tables

Explorer (web only)

The code example is generated by AI and paired with the same selectors from above to let the user highlight

image

It also works with SVG components
image

UI

Carousel Web

image

Carousel Mobile

image

Other library implementations

Ant

image

Mantine

image

Testing

Tested all of these components manually

How has it been tested?

  • Unit tests
  • Interaction tests
  • Pseudo State tests
  • Manual - Web
  • Manual - Android (Emulator / Device)
  • Manual - iOS (Emulator / Device)

Testing instructions

Illustrations/Icons Checklist

Required if this PR changes files under packages/illustrations/** or packages/icons/**

  • verified visreg changes with Terran (include link to visreg run/approval)
  • all illustration/icons names have been reviewed by Dom and/or Terran

Change management

type=routine
risk=low
impact=sev5

automerge=false

@hcopp hcopp self-assigned this Jan 26, 2026
@cb-heimdall
Copy link
Collaborator

cb-heimdall commented Jan 26, 2026

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 1
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1
CODEOWNERS 🟡 See below

🟡 CODEOWNERS

Code Owner Status Calculation
ui-systems-eng-team 🟡 0/1
Denominator calculation
Additional CODEOWNERS Requirement
Show calculation
Sum 0
0
From CODEOWNERS 1
Sum 1

| `titleStackContainer` | Container wrapping titleStack |
| `topContent` | Top section content |
| `track` | Track/rail element (in progress bars, sliders) |
| `trigger` | Trigger element that opens a dropdown/popover |
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know we have discussed potential concern over having a wide range of style names for similar sub-elements so keeping a list should help with this

import { Text } from '../typography/Text';

import type { ChipProps } from './ChipProps';
export type { ChipProps } from './ChipProps';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For docgen to pick this up we need to export it from the file. This will also allow us to be more consisent with other components.

export type StylesAndClassNames<ComponentClassNamesMap extends Record<string, string>> = {
classNames?: { [key in keyof ComponentClassNamesMap]?: string };
styles?: { [key in keyof ComponentClassNamesMap]?: React.CSSProperties };
};
Copy link
Contributor Author

@hcopp hcopp Jan 26, 2026

Choose a reason for hiding this comment

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

Let me know what y'all think about this for web. It allows us to keep the keys consistent across classNames, styles, and static classNames. We still haven't decided if we want static classNames for everything but we could start applying to some components now.

I tested this with NavigationBar.


## Selectors

<ComponentStylesTable componentName="ContentCell" styles={mobileStylesData} />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Image

start: 'cds-NavigationBar-start',
/** Container for the main children content (e.g., title) */
content: 'cds-NavigationBar-content',
} as const;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hcopp todo add eslint rule if we styles or classNames and don't have static classNames

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

Development

Successfully merging this pull request may close these issues.

2 participants