Guidelines for creating or updating documentation for a CDS component on the docsite (apps/docs/). Use this skill after creating or making updates to a CDS React component to write high quality documentaiton in the CDS docsite.
Goal: Create or update documentation for a CDS component on the docsite (apps/docs/).
If no component name is provided, ask the user which component they want to document.
First, check if documentation already exists for this component:
apps/docs/docs/components/*/[ComponentName]/For updates, focus on the specific areas that need improvement rather than rewriting everything.
When creating or updating docs, reference these well-documented components to understand the documentation style and patterns:
apps/docs/docs/components/charts/LineChart/) - Comprehensive example with many composed examplesapps/docs/docs/components/buttons/Button/) - Good basic component documentationapps/docs/docs/components/buttons/IconButton/) - Simple component with clear examplesapps/docs/docs/components/navigation/Sidebar/) - Complex component with multiple sub-componentsReview these before writing to ensure consistency in style, structure, and depth.
When writing examples, reference these files for valid values:
packages/icons/src/IconName.ts) - All valid icon names (e.g., 'checkmark', 'close', 'warning')components.best-practices SKILL for knowledge on valid CDS design token values (Color, Space, BorderRadius, Font, etc.)Before writing documentation, research how other popular component libraries document the same (or similar) component. Use web search to find documentation for the component in:
Look for:
Use these insights to inform your documentation structure and examples.
Verify where the component exists:
packages/web/src/[source-category]/[ComponentName].tsx # for web
packages/mobile/src/[source-category]/[ComponentName].tsx # for mobileAlso check visualization packages if applicable:
packages/web-visualization/src/...packages/mobile-visualization/src/...Also check for Storybook stories (packages/*/src/**/__stories__/[ComponentName].stories.tsx). If one exists, add the storybook field to webMetadata.json.
Check if the component supports the styles and/or classNames props by looking at its type definitions. Components with these props should have a styles tab in the documentation. Look for:
styles?: { ... } prop with named style selectorsclassNames?: { ... } prop with named class selectorsIf the component has these props, the docgen will generate styles data that can be used for the styles doc.
Before creating the component documentation, complete these setup steps:
In apps/docs/src/components/page/ReactLiveScope.ts, add the component imports and add them to the scope:
// Add imports
import { ComponentName } from '@coinbase/cds-web';
// Add to scope object
const ReactLiveScope = {
// ... existing scope
ComponentName,
};There is a chance that the component has already been imported.
In apps/docs/sidebars.ts, add the component to its category section:
module.exports = {
docs: [
// ... other sections
{
type: 'category',
label: 'Category', // e.g., 'Buttons', 'Layout', etc.
items: [
// ... other components
'components/category/ComponentName/index',
],
},
],
};In apps/docs/docgen.config.js, add the component paths to generate props data:
module.exports = {
web: {
// ... other configs
category: {
// e.g., 'buttons', 'layout', etc.
ComponentName: {
source: 'packages/web/src/category/ComponentName.tsx',
},
},
},
// If component has a mobile version
mobile: {
// ... other configs
category: {
ComponentName: {
source: 'packages/mobile/src/category/ComponentName.tsx',
},
},
},
};Create the documentation directory and files based on component availability:
apps/docs/docs/components/[docs-category]/[ComponentName]/
├── index.mdx # Required for all components
├── webMetadata.json # If web version exists
├── _webExamples.mdx # If web version exists
├── _webPropsTable.mdx # If web version exists
├── _webStyles.mdx # If web version has styles/classNames API
├── mobileMetadata.json # If mobile version exists
├── _mobileExamples.mdx # If mobile version exists
├── _mobilePropsTable.mdx # If mobile version exists
└── _mobileStyles.mdx # If mobile version has styles/classNames API{
"import": "import { ComponentName } from '@coinbase/cds-web/[source-category]/[ComponentName]'",
"source": "https://github.com/coinbase/cds/blob/master/packages/web/src/[source-category]/[ComponentName].tsx",
"description": "[Component description]",
"figma": "[figma link]",
"storybook": "[storybook link]",
"relatedComponents": [
{ "label": "[componentName]", "url": "/components/[category]/[componentName]" }
],
"dependencies": [{ "name": "[peer-dependency-name]", "version": "[version-range]" }]
}Notes:
description should be the full component description - what the component is and when to use it (e.g., "A non-intrusive notification component that temporarily displays brief messages at the bottom of the screen.")figma and storybook fields are optional - only add if provided (check for story files in packages/web/src/**/__stories__/)dependencies is optional - only include if the component imports from external packages that are peer dependencies. To determine:
framer-motion)peerDependencies in packages/web/package.jsonpeerDependencies in the package.json filerelatedComponents should link to components commonly used together{
"import": "import { ComponentName } from '@coinbase/cds-mobile/[source-category]/[ComponentName]'",
"source": "https://github.com/coinbase/cds/blob/master/packages/mobile/src/[source-category]/[ComponentName].tsx",
"description": "[Component description]",
"figma": "[figma link]",
"relatedComponents": [
{ "label": "[componentName]", "url": "/components/[category]/[componentName]" }
],
"dependencies": [{ "name": "[peer-dependency-name]", "version": "[version-range]" }]
}Notes:
figma is optional - only add if provideddependencies is optional - only include if the component imports from external packages that are peer dependencies. To determine:
@shopify/react-native-skia, react-native-reanimated, react-native-gesture-handler)peerDependencies in packages/mobile/package.jsonpeerDependencies in the package.json fileimport ComponentPropsTable from '@site/src/components/page/ComponentPropsTable';
import webPropsData from ':docgen/web/[source-category]/[ComponentName]/data';
import { sharedParentTypes } from ':docgen/_types/sharedParentTypes';
import { sharedTypeAliases } from ':docgen/_types/sharedTypeAliases';
<ComponentPropsTable
props={webPropsData}
sharedTypeAliases={sharedTypeAliases}
sharedParentTypes={sharedParentTypes}
/>import ComponentPropsTable from '@site/src/components/page/ComponentPropsTable';
import mobilePropsData from ':docgen/mobile/[source-category]/[ComponentName]/data';
import { sharedParentTypes } from ':docgen/_types/sharedParentTypes';
import { sharedTypeAliases } from ':docgen/_types/sharedTypeAliases';
<ComponentPropsTable
props={mobilePropsData}
sharedTypeAliases={sharedTypeAliases}
sharedParentTypes={sharedParentTypes}
/>Styles doc showcases the styles and classNames API for components that support custom styling of internal elements. Only create these files if the component has a styles/classNames API.
For web components, always include both the selectors table AND the interactive StylesExplorer. The StylesExplorer lets users hover or click on selectors to highlight the corresponding elements in a live example:
import { ComponentStylesTable } from '@site/src/components/page/ComponentStylesTable';
import { StylesExplorer } from '@site/src/components/page/StylesExplorer';
import { [ComponentName] } from '@coinbase/cds-web/[source-category]/[ComponentName]';
import webStylesData from ':docgen/web/[source-category]/[ComponentName]/styles-data';
## Explorer
<StylesExplorer selectors={webStylesData.selectors}>
{(classNames) => (
<[ComponentName] {...exampleProps} classNames={classNames} />
)}
</StylesExplorer>
## Selectors
<ComponentStylesTable componentName="[ComponentName]" styles={webStylesData} />If the component requires state management, bundle everything into a single exported example component.
import { useState } from 'react';
import { ComponentStylesTable } from '@site/src/components/page/ComponentStylesTable';
import { StylesExplorer } from '@site/src/components/page/StylesExplorer';
import { Select } from '@coinbase/cds-web/alpha/select';
import webStylesData from ':docgen/web/alpha/select/Select/styles-data';
export const SelectExample = ({ classNames }) => {
const [value, setValue] = useState('1');
const options = [
{ value: '1', label: 'Option 1' },
{ value: '2', label: 'Option 2' },
{ value: '3', label: 'Option 3' },
];
return (
<Select
classNames={classNames}
label="Choose an option"
value={value}
onChange={setValue}
options={options}
placeholder="Select an option"
style={{ width: '100%' }}
/>
);
};
## Explorer
<StylesExplorer selectors={webStylesData.selectors}>
{(classNames) => <SelectExample classNames={classNames} />}
</StylesExplorer>
## Selectors
<ComponentStylesTable componentName="Select" styles={webStylesData} />Notes:
StylesExplorer passes classNames to highlight selected elementsCreating Comprehensive Explorer Examples:
The explorer example should be designed to showcase all available selectors. Review the component's classNames type to identify all selectors, then configure your example to render the elements that use each selector:
header only renders in horizontal mode)subSteps, include them to showcase selectors like substepContainertitle if the component has a title selectorExample for a component with conditional selectors:
{/* Steps with subSteps to showcase all selectors including substepContainer */}
export const steps = [
{ id: '1', label: 'Step 1' },
{
id: '2',
label: 'Step 2',
subSteps: [
{ id: '2a', label: 'Sub-step A' },
{ id: '2b', label: 'Sub-step B' },
],
},
{ id: '3', label: 'Step 3' },
];For mobile components, only include the selectors table (no interactive explorer):
import { ComponentStylesTable } from '@site/src/components/page/ComponentStylesTable';
import mobileStylesData from ':docgen/mobile/[source-category]/[ComponentName]/styles-data';
## Selectors
<ComponentStylesTable componentName="[ComponentName]" styles={mobileStylesData} />---
id: [component-id]
title: [ComponentName]
platform_switcher_options: { web: true, mobile: false }
hide_title: true
---
import { VStack } from '@coinbase/cds-web/layout';
import { ComponentHeader } from '@site/src/components/page/ComponentHeader';
import { ComponentTabsContainer } from '@site/src/components/page/ComponentTabsContainer';
import webPropsToc from ':docgen/web/[source-category]/[ComponentName]/toc-props';
import WebPropsTable from './_webPropsTable.mdx';
// If component has styles API, add this import:
import WebStyles, { toc as webStylesToc } from './_webStyles.mdx';
import WebExamples, { toc as webExamplesToc } from './_webExamples.mdx';
import webMetadata from './webMetadata.json';
<VStack gap={5}>
<ComponentHeader title="[ComponentName]" webMetadata={webMetadata} />
<ComponentTabsContainer
webExamples={<WebExamples />}
webExamplesToc={webExamplesToc}
webPropsTable={<WebPropsTable />}
webPropsToc={webPropsToc}
// If component has styles API, add these props:
webStylesTable={<WebStyles />}
webStylesToc={webStylesToc}
/>
</VStack>---
id: [component-id]
title: [ComponentName]
platform_switcher_options: { web: false, mobile: true }
hide_title: true
---
import { VStack } from '@coinbase/cds-web/layout';
import { ComponentHeader } from '@site/src/components/page/ComponentHeader';
import { ComponentTabsContainer } from '@site/src/components/page/ComponentTabsContainer';
import mobilePropsToc from ':docgen/mobile/[source-category]/[ComponentName]/toc-props';
import MobilePropsTable from './_mobilePropsTable.mdx';
// If component has styles API, add this import:
import MobileStyles, { toc as mobileStylesToc } from './_mobileStyles.mdx';
import MobileExamples, { toc as mobileExamplesToc } from './_mobileExamples.mdx';
import mobileMetadata from './mobileMetadata.json';
<VStack gap={5}>
<ComponentHeader title="[ComponentName]" mobileMetadata={mobileMetadata} />
<ComponentTabsContainer
mobileExamples={<MobileExamples />}
mobileExamplesToc={mobileExamplesToc}
mobilePropsTable={<MobilePropsTable />}
mobilePropsToc={mobilePropsToc}
// If component has styles API, add these props:
mobileStylesTable={<MobileStyles />}
mobileStylesToc={mobileStylesToc}
/>
</VStack>---
id: [component-id]
title: [ComponentName]
platform_switcher_options: { web: true, mobile: true }
hide_title: true
---
import { VStack } from '@coinbase/cds-web/layout';
import { ComponentHeader } from '@site/src/components/page/ComponentHeader';
import { ComponentTabsContainer } from '@site/src/components/page/ComponentTabsContainer';
import webPropsToc from ':docgen/web/[source-category]/[ComponentName]/toc-props';
import mobilePropsToc from ':docgen/mobile/[source-category]/[ComponentName]/toc-props';
import WebPropsTable from './_webPropsTable.mdx';
import MobilePropsTable from './_mobilePropsTable.mdx';
// If component has styles API, add these imports:
import WebStyles, { toc as webStylesToc } from './_webStyles.mdx';
import MobileStyles, { toc as mobileStylesToc } from './_mobileStyles.mdx';
import WebExamples, { toc as webExamplesToc } from './_webExamples.mdx';
import MobileExamples, { toc as mobileExamplesToc } from './_mobileExamples.mdx';
import webMetadata from './webMetadata.json';
import mobileMetadata from './mobileMetadata.json';
<VStack gap={5}>
<ComponentHeader
title="[ComponentName]"
webMetadata={webMetadata}
mobileMetadata={mobileMetadata}
/>
<ComponentTabsContainer
mobileExamples={<MobileExamples />}
mobileExamplesToc={mobileExamplesToc}
mobilePropsTable={<MobilePropsTable />}
mobilePropsToc={mobilePropsToc}
// If component has styles API, add these props:
mobileStylesTable={<MobileStyles />}
mobileStylesToc={mobileStylesToc}
webExamples={<WebExamples />}
webExamplesToc={webExamplesToc}
webPropsTable={<WebPropsTable />}
webPropsToc={webPropsToc}
// If component has styles API, add these props:
webStylesTable={<WebStyles />}
webStylesToc={webStylesToc}
/>
</VStack>Examples should follow this recommended structure:
Important: Do NOT repeat the full component description from metadata in the examples. The examples should focus on how to use the component, not what it is.
Web examples use jsx live blocks which render interactively in the browser. For short, incomplete code snippets that are meant to illustrate a concept rather than be runnable, you may use plain jsx blocks instead.
[ComponentName] uses [dependency/wrapper] to [brief functional note]. [Any key setup requirement in one sentence].
## Basics
[Explain how to use the component's core API - e.g., "Call `toast.show()` with a message string to display a toast."]
```jsx live
<[ComponentName]
requiredProp="value"
/>
```
## [Feature Category]
[Brief explanation of this feature category]
### [Specific Feature]
```jsx live
<[ComponentName]
featureProp="value"
/>
```
## Styling
### Color
[Show color customization options]
```jsx live
<[ComponentName] color="fgPrimary" />
```
### Sizing
[Show sizing options]
```jsx live
<[ComponentName] size="large" />
```
## Accessibility
Use `accessibilityLabel` to provide context for screen readers. When [specific scenario], also consider [accessibility guidance].
```jsx live
<[ComponentName]
accessibilityLabel="Descriptive label for screen readers"
requiredProp="value"
/>
```Mobile examples use static jsx blocks only. Do not use jsx live - React Native cannot run in the browser.
[ComponentName] uses [dependency/wrapper] to [brief functional note]. [Any mobile-specific behavior in one sentence, e.g., "On mobile, toasts can be swiped away."]
## Basics
[Explain how to use the component's core API - e.g., "Call `toast.show()` with a message string to display a toast."]
```jsx
<[ComponentName]
requiredProp="value"
/>
```
## [Feature Category]
[Brief explanation of this feature category]
### [Specific Feature]
```jsx
<[ComponentName]
featureProp="value"
/>
```
## Styling
### Color
[Show color customization options]
```jsx
<[ComponentName] color="fgPrimary" />
```
### Sizing
[Show sizing options]
```jsx
<[ComponentName] size="large" />
```
## Accessibility
Use `accessibilityLabel` to provide context for screen readers.
```jsx
<[ComponentName]
accessibilityLabel="Descriptive label for screen readers"
requiredProp="value"
/>
```useMemo for expensive computations or computed stylesuseCallback for event handlers passed as propsIntl.NumberFormat, Intl.DateTimeFormat, etc.flexWrap="wrap" to HStacks with multiple items)[ComponentName](/components/category/ComponentName)Depending on the component, consider including these sections:
Before completing, verify:
platform_switcher_optionsdependencies field if component has peer dependenciesjsx live (or jsx for short snippets); mobile examples use jsx only (no live)components.best-practices SKILL)web-visualization or mobile-visualization instead of web or mobilef79a780
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.