Use this skill whenever working on CDS React components in any package.
These high quality components demonstrate proper use of patterns/conventions:
Every main CDS component should live within its own folder:
ComponentName/
├── ComponentName.tsx # Main component file
├── SubComponent.tsx # Supporting component (if needed)
├── index.ts # Re-exports for public API
├── __stories__/ # Storybook stories
│ └── ComponentName.stories.tsx
├── __tests__/ # Unit tests
│ └── ComponentName.test.tsx
├── __figma__/ # Figma Code Connect files
│ └── ComponentName.figma.tsxOrganize components into category folders:
buttons - Button, IconButton, SlideButtoncontrols - TextInput, Select, Checkbox, Radio, Switchcards - Card, DataCard, ContentCardoverlays - Modal, Toast, Alert, Drawerlayout - Box, Stack, Dividertypography - Text, Headingicons - Iconnavigation - Tabs, Breadcrumb@default tags*BaseProps and *Props type (e.g., ButtonBaseProps, ButtonProps)testID prop on root element for every componentDesign tokens are defined in packages/common/src/core/theme.ts:
Colors use a spectrum system with hue + step notation:
Semantic tokens map to spectrum colors and adapt to light/dark mode:
fgPrimary: blue60 (light) / blue70 (dark)bgPrimary: blue60 (light) / blue70 (dark)bgNegative: red60 (both modes)bgPositive: green60 (both modes)space: {
'0': 0, // 0px
'0.25': 2, // 2px
'0.5': 4, // 4px
'0.75': 6, // 6px
'1': 8, // 8px - base unit
'1.5': 12, // 12px
'2': 16, // 16px
'3': 24, // 24px
'4': 32, // 32px
'5': 40, // 40px
// ... up to 10 (80px)
}*Component/Default* naming:
NavigationComponent = DefaultCarouselNavigation,
PaginationComponent = DefaultCarouselPagination,classNames.pagination, styles.pagination).Benefits:
use*Context() hooks that throw descriptive errors on misuse:
export const useCarouselContext = () => {
const context = useContext(CarouselContext);
if (!context) throw new Error('useCarouselContext must be used within Carousel');
return context;
};value but not onChange)const open = openProp ?? openInternal;type SelectComponent = <Type extends SelectType, Value extends string>(
props: SelectProps<Type, Value>,
) => React.ReactElement;When a composite wraps inner Text and intercepts typography style props so they style the label (not the layout wrapper), intercept and forward the full set: font, fontFamily, fontSize, fontWeight, lineHeight, textTransform.
Reference: SegmentedTab and Tag.
Component modules encapsulate two prop Types: *BaseProps (platform-agnostic) and *Props (extends BaseProps with platform and component specific properties like className, classNames, styles, etc.)
Reuse other components' Types via utilities: Pick being preferred then secondarily Omit/Exclude
Compose prop types using Typescript intersections (&) in this order: (1) full types (2) Picks (3) Omits (4) other type literal(s):
type MyComponentProps = BoxBaseProps &
Pick<OtherComponentProps, 'someProp'> &
Omit<AnotherComponentProps, 'otherProp'> & {
propA: string;
propB: number;
};When accepting components as props, define the contract types (*Props, *Component) in the main component file. These child component contracts do not use the *BaseProps pattern—only the main component needs BaseProps/Props separation. Default implementations can extend the contract with additional props in their own file:
// In MyComponent.tsx - defines the contract
type ChildProps = { id: string; label: ReactNode };
type ChildComponent = React.FC<ChildProps>;
// In DefaultChild.tsx - extends for default implementation
type DefaultChildProps = SharedProps & Omit<HStackProps, 'children'> & ChildProps;coinbase/cds
f42b0bb
Also appears in
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.