Skip to content

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

Copy link
Contributor Author

@hcopp hcopp left a comment

Choose a reason for hiding this comment

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

Tested all the docs

media={<Avatar size="m" />}
/>
)}
</StylesExplorer>
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


## Selectors

<ComponentStylesTable componentName="ListCell" 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

}
/>
)}
</StylesExplorer>
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


## Selectors

<ComponentStylesTable componentName="ProgressBar" 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


<StylesExplorer selectors={webStylesData.selectors}>
{(classNames) => <ProgressBar progress={0.65} classNames={classNames} />}
</StylesExplorer>
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


<StylesExplorer selectors={webStylesData.selectors}>
{(classNames) => <SidebarExample classNames={classNames} />}
</StylesExplorer>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here's an example where the component is taller than the # of styles

Image


<StylesExplorer selectors={webStylesData.selectors}>
{(classNames) => <StepperExample classNames={classNames} direction="vertical" />}
</StylesExplorer>
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

We can even do multiple examples

<IconButton name="bell" />
</DotCount>
)}
</StylesExplorer>
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

This is the hardest example to see the outline but I think it is fine.

</Box>
</VStack>
);
});
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 followed the design of component props table

</Box>
</VStack>
);
});
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Didn't have a ton to go off here, I choose to do background of bg to match our code examples. I initially tried setting the sidebar of selectors to match table colors (so gray10 for the top part and then no extra background for the list cells) but this current setup was the one that looked the best to me.

@hcopp hcopp marked this pull request as ready for review January 26, 2026 17:24
@hcopp
Copy link
Contributor Author

hcopp commented Jan 26, 2026

I'll wait to bump versions since this PR might not get merged for a bit

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