components.write-docs

作者: coinbase

components.write-docs — 一個可安裝的 AI 代理技能,由 coinbase/cds 發布。

npx skills add https://github.com/coinbase/cds --skill components.write-docs

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.

Step 1: Check for Existing Documentation

First, check if documentation already exists for this component:

apps/docs/docs/components/*/[ComponentName]/
  • If docs exist: Review the existing documentation and identify what needs to be added, updated, or improved. Consider the user's additional context if provided.
  • If docs don't exist: Follow the full workflow below to create new documentation.

For updates, focus on the specific areas that need improvement rather than rewriting everything.

Reference Components

When creating or updating docs, reference these well-documented components to understand the documentation style and patterns:

  • LineChart (apps/docs/docs/components/charts/LineChart/) - Comprehensive example with many composed examples
  • Button (apps/docs/docs/components/buttons/Button/) - Good basic component documentation
  • IconButton (apps/docs/docs/components/buttons/IconButton/) - Simple component with clear examples
  • Sidebar (apps/docs/docs/components/navigation/Sidebar/) - Complex component with multiple sub-components

Review these before writing to ensure consistency in style, structure, and depth.

Reference Files

When writing examples, reference these files for valid values:

  • Icon names (packages/icons/src/IconName.ts) - All valid icon names (e.g., 'checkmark', 'close', 'warning')
  • Design tokens - Use the components.best-practices SKILL for knowledge on valid CDS design token values (Color, Space, BorderRadius, Font, etc.)

Step 2: Research Phase (for new docs or major updates)

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:

  • Material UI (mui.com)
  • Radix UI (radix-ui.com)
  • Mantine (mantine.dev)
  • Ant Design (ant.design)
  • Base UI (base-ui.com)

Look for:

  • What examples they provide and how they're organized
  • Common use cases they demonstrate
  • Edge cases or patterns worth highlighting
  • Accessibility guidance they include
  • How they explain complex features

Use these insights to inform your documentation structure and examples.

Step 3: Check Component Availability

Verify where the component exists:

packages/web/src/[source-category]/[ComponentName].tsx    # for web
packages/mobile/src/[source-category]/[ComponentName].tsx # for mobile

Also check for Storybook stories (packages/*/src/**/__stories__/[ComponentName].stories.tsx). If one exists, add the storybook field to webMetadata.json.

Check for Styles

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 selectors
  • classNames?: { ... } prop with named class selectors

If the component has these props, the docgen will generate styles data that can be used for the styles doc.

Step 4: Required Setup Steps (for new docs only)

Before creating the component documentation, complete these setup steps:

4.1 Add to ReactLiveScope

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.

4.2 Update sidebars.ts

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',
      ],
    },
  ],
};

4.3 Update docgen.config.js

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',
      },
    },
  },
};

Step 5: Create Directory Structure (for new docs only)

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

File Templates

Metadata Files

webMetadata.json

{
  "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:
    1. Check the component's source file for imports from external packages (e.g., framer-motion)
    2. Cross-reference those imports with peerDependencies in packages/web/package.json
    3. Use the exact version range from peerDependencies in the package.json file
  • relatedComponents should link to components commonly used together

mobileMetadata.json

{
  "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 provided
  • dependencies is optional - only include if the component imports from external packages that are peer dependencies. To determine:
    1. Check the component's source file for imports from external packages (e.g., @shopify/react-native-skia, react-native-reanimated, react-native-gesture-handler)
    2. Cross-reference those imports with peerDependencies in packages/mobile/package.json
    3. Use the exact version range from peerDependencies in the package.json file

Props Tables

_webPropsTable.mdx

import 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}
/>

_mobilePropsTable.mdx

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

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.

_webStyles.mdx (with Explorer)

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:

  • For components with multiple variants (e.g., horizontal/vertical), add multiple explorer sections with h3 headings
  • The StylesExplorer passes classNames to highlight selected elements

Creating 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:

  • Check conditional rendering: Some selectors only appear with certain props (e.g., Stepper's header only renders in horizontal mode)
  • Include nested structures: If the component has nested elements like subSteps, include them to showcase selectors like substepContainer
  • Add optional content: Include props like title if the component has a title selector
  • Use realistic data: Provide enough items/steps to demonstrate the full component structure

Example 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' },
];

_mobileStyles.mdx (Selectors Only)

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

Main Documentation (index.mdx)

For Web-Only Components

---
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>

For Mobile-Only Components

---
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>

For Cross-Platform Components

---
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

Example Structure Guidelines

Examples should follow this recommended structure:

  1. Brief intro - A short functional note (NOT the full description - that goes in metadata). Mention what the component uses/wraps or key dependencies.
  2. Basics - Simplest usage explaining how to use the core API
  3. Feature sections - Group related functionality by topic (e.g., Styling with Color/Sizing subsections)
  4. Accessibility - How to make the component accessible

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.

_webExamples.mdx (Live Examples)

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"
/>
```

_mobileExamples.mdx (Static Examples)

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"
/>
```

Best Practices for Examples

Code Quality

  • Use named functions for complex examples that need state or effects
  • Memoize with useMemo for expensive computations or computed styles
  • Memoize with useCallback for event handlers passed as props
  • Include accessibility labels in interactive examples
  • Format values for display using Intl.NumberFormat, Intl.DateTimeFormat, etc.
  • Ensure live examples are responsive - The doc site can be viewed on mobile viewports, so examples should render well at narrow widths (e.g., add flexWrap="wrap" to HStacks with multiple items)

Documentation Quality

  • Start with introductory prose explaining what the component does before any code
  • Progress from simple to complex - basic examples first, advanced examples last
  • Cross-reference related components using markdown links: [ComponentName](/components/category/ComponentName)
  • Explain the "why" not just the "how" - help users understand when to use each feature
  • Show edge cases like empty states, loading states, error states, missing data

Common Sections to Consider

Depending on the component, consider including these sections:

  • Setup - Prerequisites or providers needed (especially for mobile)
  • Basics - Core API usage
  • Feature-specific sections - Group related functionality (e.g., if the component works with other components, show that integration)
  • Styling - Color, Sizing, and other customization options as subsections
  • Accessibility - Screen reader support, keyboard navigation, etc.
  • Composed Examples - Used for complex components where showing real-world patterns that combine multiple features into new component compositions adds significant value.

Final Checklist

Before completing, verify:

  • Researched similar components in other libraries for inspiration
  • Verified component existence in web/mobile
  • Created only necessary platform-specific files
  • Set correct platform_switcher_options
  • Metadata files have correct package imports
  • Added dependencies field if component has peer dependencies
  • Props tables import from correct package with correct variable names
  • Styles files created if component has styles/classNames API
  • StylesExplorer is used in web styles (if present) and includes working example with appropriate props
  • Examples start with introductory prose
  • Examples include accessibility guidance
  • Examples progress from basic to advanced
  • Web examples use jsx live (or jsx for short snippets); mobile examples use jsx only (no live)
  • ComponentTabsContainer includes only existing platform props
  • All imports use correct source categories
  • Component description is clear and helpful
  • Added storybook/figma links if story files exist or links are provided
  • Design token values are valid (followed components.best-practices SKILL)

Additional Notes

  1. Source category might differ from docs category
  2. Add storybook and figma links to metadata if provided
  3. Ensure all examples work and have proper code snippets
  4. Include accessibility section with specific examples
  5. Test all examples and props tables render correctly

來自 coinbase 的更多技能

git.repo-manager
coinbase
git.repo-manager — 一個可安裝的AI代理技能,由coinbase/cds發布。
official
agentic-wallet
coinbase
透過 awal CLI 進行加密錢包操作 — 登入、查詢餘額、發送 USDC/ETH/POL/SOL、交易代幣、為錢包充值,以及使用 x402 支付協議來…
official
authenticate-wallet
coinbase
基於電子郵件OTP的錢包驗證,包含驗證與狀態檢查。兩步驟登入流程:先透過電子郵件發起請求以接收6位數OTP,再使用flowId與驗證碼完成驗證。內建電子郵件、flowId及OTP的輸入驗證規則,防止在執行指令前發生Shell注入。提供狀態檢查、餘額查詢、地址擷取及透過配套CLI指令存取錢包視窗等功能。所有指令皆支援--json輸出,以利機器讀取...
official
fund
coinbase
透過 Coinbase Onramp 或直接轉帳將 USDC 存入錢包。開啟輔助介面,用戶可選擇預設金額(10 美元、20 美元、50 美元)或自訂數值,並從 Apple Pay、簽帳卡、銀行轉帳或 Coinbase 帳戶資金中選擇付款方式。支援多種付款方式,結算時間各異:卡片與 Apple Pay 即時到帳,ACH 銀行轉帳需 1–3 天。資金以 Base 網路上的 USDC 存入;用戶亦可透過 npx awal@2.0.3... 直接將 USDC 發送至錢包地址。
official
monetize-service
coinbase
部署一個付費API端點,其他代理可透過x402協議發現並付費使用。基於HTTP 402支付協議,在Base鏈上按請求收取USDC;客戶端使用簽名交易支付,無需API金鑰或帳戶。當您聲明發現擴展時,自動將端點註冊至x402 Bazaar供代理發現。支援多種定價層級、萬用路由,以及透過Express中介軟體為每個端點設定多種支付選項。基於@x402/express和@x402/core建置...
official
pay-for-service
coinbase
在Base上透過x402協議自動以USDC支付來呼叫付費API。執行HTTP請求(GET、POST等)至支援x402的端點,自動處理原子化USDC支付。支援透過方法、JSON主體、查詢參數及自訂標頭進行請求自訂。包含支付控制:設定每次請求的最大USDC金額,並使用關聯ID分組相關操作。需要錢包驗證及足夠的USDC餘額;驗證所有使用者輸入以防止shell...
official
query-blockchain-data
coinbase
透過 CDP SQL API 與 x402 查詢 Base 上的鏈上區塊鏈數據。當您或用戶想查看關於已解碼區塊的鏈上資訊時使用…
official
query-onchain-data
coinbase
使用SQL在Base上查詢鏈上數據,每次查詢需支付x402費用。透過CoinbaseQL(基於ClickHouse的SQL方言)存取解碼事件、交易與區塊,支援JOIN、CTE、子查詢及標準函數。主要提供三個資料表:base.events(解碼的智能合約日誌)、base.transactions(完整交易數據)及base.blocks(區塊元數據)。查詢事件時需對索引欄位(event_signature、address、block_timestamp)進行過濾,以避免掃描完整資料表...
official