Component Docs logo

Component Docs

Community
dylantarre
component-docs

Generates component API documentation with props tables, usage examples, and guidelines. Use when documenting component libraries, creating API references, or building component documentation for designers and developers.

Overview

Publisherdylantarre
Repositorydesign-system-skills
Skill namecomponent-docs
Stars
50
Forks
4
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by dylantarre on GitHub. Read the source before you install it.

Installation

Install the Component Docs AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/dylantarre/design-system-skills/tree/main/skills/documentation/component-docs
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/dylantarre/design-system-skills.git /tmp/design-system-skills
mkdir -p .claude/skills
cp -r /tmp/design-system-skills/skills/documentation/component-docs .claude/skills/component-docs
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Component Docs in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Component Docs on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Component Docs is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Component Documentation Generator

Overview

Generate comprehensive component documentation including API references, usage examples, accessibility guidelines, and design specifications. Create documentation that serves both designers and developers.

When to Use

  • Documenting new components
  • Creating component API references
  • Writing usage guidelines
  • Building a design system documentation site

Quick Reference: Documentation Sections

SectionPurposeAudience
OverviewWhat the component doesAll
When to UseDecision guidanceDesigners
Props/APITechnical referenceDevelopers
ExamplesCode snippetsDevelopers
VariantsVisual optionsAll
StatesInteractive statesDesigners
AccessibilityA11y guidelinesAll
Design SpecsSpacing, tokens usedDesigners
Do/Don'tUsage guidanceAll

The Process

  1. Identify component scope: What does it do, what doesn't it do?
  2. Define props interface: All configurable options
  3. Create examples: Basic, advanced, edge cases
  4. Document variants: Visual variations
  5. Add accessibility: ARIA, keyboard, screen reader
  6. Include design specs: Spacing, colors, typography tokens
  7. Write guidelines: When to use, when not to

Component Documentation Template

markdown
# Button

Buttons allow users to take actions and make choices with a single tap.

## Overview

The Button component is used for triggering actions. Use buttons to submit forms,
navigate between pages, or trigger in-page functionality.

## When to Use

| Scenario | Recommendation |
|----------|----------------|
| Primary action | Use `variant="primary"` |
| Secondary action | Use `variant="secondary"` |
| Destructive action | Use `variant="danger"` |
| Navigation | Consider using a Link instead |
| In forms | Use `type="submit"` |

## Import

```tsx
import { Button } from '@acme/design-system';

Basic Usage

tsx
<Button onClick={handleClick}>Click me</Button>

Props

PropTypeDefaultDescription
variant'primary' | 'secondary' | 'ghost' | 'danger''primary'Visual style variant
size'sm' | 'md' | 'lg''md'Button size
disabledbooleanfalseDisables the button
loadingbooleanfalseShows loading spinner
fullWidthbooleanfalseMakes button 100% width
leftIconReactNode-Icon before text
rightIconReactNode-Icon after text
type'button' | 'submit' | 'reset''button'HTML button type
onClick(event: MouseEvent) => void-Click handler
childrenReactNode-Button label

Variants

Primary

Use for the main action on a page or in a form.

tsx
<Button variant="primary">Save changes</Button>

Secondary

Use for secondary actions that support the primary action.

tsx
<Button variant="secondary">Cancel</Button>

Ghost

Use for tertiary actions or in dense UIs.

tsx
<Button variant="ghost">Learn more</Button>

Danger

Use for destructive actions like delete.

tsx
<Button variant="danger">Delete account</Button>

Sizes

tsx
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
SizeHeightFont SizeUse Case
sm32px14pxCompact UIs, tables
md40px16pxDefault, most uses
lg48px18pxHero sections, emphasis

States

Default

tsx
<Button>Default</Button>

Hover

Slightly darkened background. Applied automatically on mouse hover.

Active

Pressed state with slight scale reduction.

Focus

Focus ring appears on keyboard focus (focus-visible).

Disabled

tsx
<Button disabled>Disabled</Button>
  • 50% opacity
  • Cursor changes to not-allowed
  • Click events are ignored

Loading

tsx
<Button loading>Saving...</Button>
  • Shows spinner icon
  • Button is disabled
  • Label remains for width consistency
  • aria-busy="true" for screen readers

With Icons

tsx
// Icon before text
<Button leftIcon={<PlusIcon />}>Add item</Button>

// Icon after text
<Button rightIcon={<ArrowRightIcon />}>Continue</Button>

// Icon only (use aria-label)
<Button aria-label="Settings">
  <SettingsIcon />
</Button>

Full Width

tsx
<Button fullWidth>Sign up</Button>

Button Groups

tsx
<div className="button-group">
  <Button variant="secondary">Cancel</Button>
  <Button variant="primary">Save</Button>
</div>

Accessibility

Keyboard Navigation

KeyAction
TabMove focus to button
EnterActivate button
SpaceActivate button

ARIA

  • Uses native <button> element
  • aria-disabled when disabled (maintains focusability)
  • aria-busy when loading
  • aria-pressed for toggle buttons

Screen Readers

  • Ensure button has accessible name (text content or aria-label)
  • Loading state announced via aria-busy
  • Icon-only buttons require aria-label

Focus Management

  • Focus ring visible on keyboard focus (not mouse)
  • 2px outline with 2px offset
  • Meets WCAG 2.4.7 Focus Visible

Design Specifications

Spacing

ElementTokenValue
Horizontal padding (sm)--spacing-sm8px
Horizontal padding (md)--spacing-md16px
Horizontal padding (lg)--spacing-lg24px
Icon gap--spacing-xs4px
Button group gap--spacing-sm8px

Colors

VariantBackgroundTextBorder
Primary--color-primary-500white-
Primary:hover--color-primary-600white-
Secondarytransparent--color-gray-700--color-gray-300
Ghosttransparent--color-gray-700-
Danger--color-error-500white-

Typography

SizeTokenWeight
sm--text-sm (14px)500
md--text-base (16px)500
lg--text-lg (18px)500

Other

PropertyTokenValue
Border radius--radius-md8px
Focus ring--color-primary-5002px solid
Transition-150ms ease

Do's and Don'ts

Do ✅

  • Use clear, action-oriented labels ("Save", "Delete", "Continue")
  • Place primary action on the right in button groups
  • Use loading state for async actions
  • Provide aria-label for icon-only buttons

Don't ❌

  • Don't use vague labels ("Click here", "Submit")
  • Don't use more than one primary button per view
  • Don't disable buttons without explanation
  • Don't use buttons for navigation (use Links)

Related Components

Changelog

VersionChanges
1.2.0Added loading prop
1.1.0Added ghost variant
1.0.0Initial release

---

## API Documentation Template

**For TypeScript components:**

```markdown
## API Reference

### ButtonProps

```typescript
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  /**
   * Visual style variant
   * @default 'primary'
   */
  variant?: 'primary' | 'secondary' | 'ghost' | 'danger';

  /**
   * Button size
   * @default 'md'
   */
  size?: 'sm' | 'md' | 'lg';

  /**
   * Shows loading spinner and disables button
   * @default false
   */
  loading?: boolean;

  /**
   * Makes button full width of container
   * @default false
   */
  fullWidth?: boolean;

  /**
   * Icon element to display before text
   */
  leftIcon?: React.ReactNode;

  /**
   * Icon element to display after text
   */
  rightIcon?: React.ReactNode;

  /**
   * Button content (label)
   */
  children: React.ReactNode;
}

Ref

The Button component forwards its ref to the underlying <button> element.

tsx
const buttonRef = useRef<HTMLButtonElement>(null);
<Button ref={buttonRef}>Click me</Button>

CSS Classes

ClassDescription
.btnBase button styles
.btn--primaryPrimary variant
.btn--secondarySecondary variant
.btn--ghostGhost variant
.btn--dangerDanger variant
.btn--smSmall size
.btn--mdMedium size
.btn--lgLarge size
.btn--loadingLoading state
.btn--full-widthFull width modifier

---

## Auto-Generation from TypeScript

**generate-component-docs.ts:**
```typescript
import ts from 'typescript';
import fs from 'fs';

interface PropDoc {
  name: string;
  type: string;
  description: string;
  defaultValue?: string;
  required: boolean;
}

function extractPropsFromInterface(
  sourceFile: ts.SourceFile,
  interfaceName: string
): PropDoc[] {
  const props: PropDoc[] = [];

  function visit(node: ts.Node) {
    if (ts.isInterfaceDeclaration(node) && node.name.text === interfaceName) {
      node.members.forEach((member) => {
        if (ts.isPropertySignature(member) && member.name) {
          const name = member.name.getText(sourceFile);
          const type = member.type?.getText(sourceFile) || 'unknown';
          const required = !member.questionToken;

          // Extract JSDoc
          const jsDoc = ts.getJSDocTags(member);
          const description = ts.getJSDocCommentsAndTags(member)
            .map((c) => c.getText())
            .join(' ')
            .replace(/\/\*\*|\*\/|\*/g, '')
            .trim();

          const defaultTag = jsDoc.find((t) => t.tagName.text === 'default');
          const defaultValue = defaultTag?.comment?.toString();

          props.push({ name, type, description, defaultValue, required });
        }
      });
    }
    ts.forEachChild(node, visit);
  }

  visit(sourceFile);
  return props;
}

function generatePropsTable(props: PropDoc[]): string {
  let md = '| Prop | Type | Default | Required | Description |\n';
  md += '|------|------|---------|----------|-------------|\n';

  for (const prop of props) {
    const required = prop.required ? 'Yes' : 'No';
    const defaultVal = prop.defaultValue || '-';
    md += `| \`${prop.name}\` | \`${prop.type}\` | ${defaultVal} | ${required} | ${prop.description} |\n`;
  }

  return md;
}

// Usage
const sourceCode = fs.readFileSync('./components/Button.tsx', 'utf-8');
const sourceFile = ts.createSourceFile(
  'Button.tsx',
  sourceCode,
  ts.ScriptTarget.Latest,
  true
);

const props = extractPropsFromInterface(sourceFile, 'ButtonProps');
const table = generatePropsTable(props);

console.log(table);

Documentation Site Structure

docs/
├── getting-started/
│   ├── installation.md
│   ├── quick-start.md
│   └── theming.md
├── foundations/
│   ├── colors.md
│   ├── typography.md
│   ├── spacing.md
│   └── icons.md
├── components/
│   ├── primitives/
│   │   ├── button.md
│   │   ├── input.md
│   │   └── text.md
│   ├── composite/
│   │   ├── card.md
│   │   ├── modal.md
│   │   └── dropdown.md
│   └── layout/
│       ├── stack.md
│       ├── grid.md
│       └── container.md
├── patterns/
│   ├── forms.md
│   ├── navigation.md
│   └── data-display.md
└── resources/
    ├── changelog.md
    ├── migration.md
    └── contributing.md

Best Practices

  1. Lead with examples: Show code before explaining
  2. Be consistent: Use same structure for all components
  3. Include visuals: Screenshots, diagrams, live demos
  4. Document edge cases: Empty states, long text, RTL
  5. Keep it updated: Automate where possible
  6. Cross-reference: Link related components
  7. Show context: Include realistic usage scenarios
  8. Test your examples: Ensure code snippets work

Frequently asked questions

What does the Component Docs AI skill do?

Generates component API documentation with props tables, usage examples, and guidelines. Use when documenting component libraries, creating API references, or building component documentation for designers and developers.

Why use Component Docs on TypingMind?

Because you install it once and use it with any model. Component Docs is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Component Docs in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/dylantarre/design-system-skills/tree/main/skills/documentation/component-docs. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Component Docs?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Component Docs?

As many as you like. As long as a model supports skills, you can use Component Docs with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Component Docs AI skill free?

Yes. It is published on GitHub by dylantarre under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇