Skip to content

Component Library Documentation

Learn how to create comprehensive documentation for your component library using VitePress with live examples and interactive demos.

Overview

Component library documentation should include:

  • Component API reference
  • Live interactive examples
  • Usage guidelines
  • Design principles
  • Accessibility information

Key Features

🎨 Live Demos

  • Interactive component previews
  • Real-time code editing
  • Multiple example variations
  • Responsive testing

📚 Comprehensive API

  • Props documentation
  • Event descriptions
  • Slot information
  • Method references

🎯 Developer Experience

  • Copy-to-clipboard functionality
  • TypeScript definitions
  • Import/export examples
  • Best practices

Project Structure

docs/
├── .vitepress/
│   ├── config.js
│   └── theme/
│       ├── index.js
│       └── components/
│           ├── Demo.vue
│           ├── ApiTable.vue
│           └── ComponentPreview.vue
├── components/
│   ├── index.md
│   ├── button.md
│   ├── input.md
│   ├── modal.md
│   └── data-table.md
├── guide/
│   ├── installation.md
│   ├── getting-started.md
│   └── theming.md
└── index.md

Configuration

js
// .vitepress/config.js
import { defineConfig } from 'vitepress'

export default defineConfig({
  title: 'UI Component Library',
  description: 'Beautiful and accessible Vue components',
  
  themeConfig: {
    nav: [
      { text: 'Guide', link: '/guide/' },
      { text: 'Components', link: '/components/' },
      { text: 'Examples', link: '/examples/' }
    ],
    
    sidebar: {
      '/guide/': [
        {
          text: 'Getting Started',
          items: [
            { text: 'Installation', link: '/guide/installation' },
            { text: 'Quick Start', link: '/guide/getting-started' },
            { text: 'Theming', link: '/guide/theming' }
          ]
        }
      ],
      '/components/': [
        {
          text: 'Form Components',
          items: [
            { text: 'Button', link: '/components/button' },
            { text: 'Input', link: '/components/input' },
            { text: 'Select', link: '/components/select' }
          ]
        },
        {
          text: 'Layout Components',
          items: [
            { text: 'Container', link: '/components/container' },
            { text: 'Grid', link: '/components/grid' },
            { text: 'Card', link: '/components/card' }
          ]
        },
        {
          text: 'Feedback Components',
          items: [
            { text: 'Modal', link: '/components/modal' },
            { text: 'Toast', link: '/components/toast' },
            { text: 'Loading', link: '/components/loading' }
          ]
        }
      ]
    }
  }
})

Component Documentation Template

markdown
# Button

A versatile button component with multiple variants and sizes.

## Basic Usage

<Demo 
  component="Button" 
  :initial-props="{ text: 'Click me' }"
  :editable-props="{ 
    text: 'Click me',
    variant: ['primary', 'secondary', 'danger'],
    size: ['small', 'medium', 'large'],
    disabled: false,
    loading: false
  }"
/>

## Variants

### Primary Button
<Demo 
  component="Button" 
  :initial-props="{ text: 'Primary', variant: 'primary' }"
  :show-controls="false"
/>

### Secondary Button
<Demo 
  component="Button" 
  :initial-props="{ text: 'Secondary', variant: 'secondary' }"
  :show-controls="false"
/>

### Danger Button
<Demo 
  component="Button" 
  :initial-props="{ text: 'Delete', variant: 'danger' }"
  :show-controls="false"
/>

## Sizes

<div style="display: flex; gap: 1rem; align-items: center;">
  <Demo 
    component="Button" 
    :initial-props="{ text: 'Small', size: 'small' }"
    :show-controls="false"
  />
  <Demo 
    component="Button" 
    :initial-props="{ text: 'Medium', size: 'medium' }"
    :show-controls="false"
  />
  <Demo 
    component="Button" 
    :initial-props="{ text: 'Large', size: 'large' }"
    :show-controls="false"
  />
</div>

## States

### Loading State
<Demo 
  component="Button" 
  :initial-props="{ text: 'Loading...', loading: true }"
  :show-controls="false"
/>

### Disabled State
<Demo 
  component="Button" 
  :initial-props="{ text: 'Disabled', disabled: true }"
  :show-controls="false"
/>

## API Reference

<ApiTable 
  title="Props"
  :items="[
    {
      name: 'text',
      type: 'string',
      default: undefined,
      description: 'Button text content',
      required: true
    },
    {
      name: 'variant',
      type: 'primary | secondary | danger',
      default: 'primary',
      description: 'Button visual style'
    },
    {
      name: 'size',
      type: 'small | medium | large',
      default: 'medium',
      description: 'Button size'
    },
    {
      name: 'disabled',
      type: 'boolean',
      default: false,
      description: 'Whether the button is disabled'
    },
    {
      name: 'loading',
      type: 'boolean',
      default: false,
      description: 'Whether the button is in loading state'
    }
  ]"
/>

<ApiTable 
  title="Events"
  :items="[
    {
      name: 'click',
      type: '(event: MouseEvent) => void',
      description: 'Emitted when button is clicked'
    }
  ]"
/>

<ApiTable 
  title="Slots"
  :items="[
    {
      name: 'default',
      type: 'any',
      description: 'Button content (alternative to text prop)'
    },
    {
      name: 'icon',
      type: 'any',
      description: 'Icon content displayed before text'
    }
  ]"
/>

## Usage Examples

### With Icon
```vue
<template>
  <Button variant="primary">
    <template #icon>
      <IconPlus />
    </template>
    Add Item
  </Button>
</template>

With Custom Content

vue
<template>
  <Button variant="secondary">
    <strong>Bold</strong> text with <em>emphasis</em>
  </Button>
</template>

Event Handling

vue
<template>
  <Button @click="handleClick">
    Click me
  </Button>
</template>

<script setup>
const handleClick = (event) => {
  console.log('Button clicked!', event)
}
</script>

Accessibility

  • Supports keyboard navigation (Enter and Space keys)
  • Proper ARIA attributes for screen readers
  • Focus management and visual indicators
  • High contrast support

Best Practices

Do's

  • Use descriptive button text
  • Choose appropriate variants for context
  • Provide loading states for async actions
  • Use consistent sizing throughout your app

Don'ts

  • Don't use buttons for navigation (use links instead)
  • Don't make buttons too small (minimum 44px touch target)
  • Don't use too many variants in one interface
  • Don't forget to handle loading and error states

## API Table Component

```vue
<!-- .vitepress/theme/components/ApiTable.vue -->
<template>
  <div class="api-table">
    <h4>{{ title }}</h4>
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Type</th>
          <th>Default</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in items" :key="item.name">
          <td>
            <code>{{ item.name }}</code>
            <span v-if="item.required" class="required">*</span>
          </td>
          <td>
            <code class="type">{{ item.type }}</code>
          </td>
          <td>
            <code v-if="item.default !== undefined">{{ item.default }}</code>
            <span v-else class="no-default">-</span>
          </td>
          <td>{{ item.description }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup>
defineProps({
  title: String,
  items: Array
})
</script>

<style scoped>
.api-table {
  margin: 2rem 0;
}

.api-table h4 {
  margin-bottom: 1rem;
  color: var(--vp-c-text-1);
}

table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  overflow: hidden;
}

th, td {
  padding: 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--vp-c-divider);
}

th {
  background: var(--vp-c-bg-soft);
  font-weight: 600;
  color: var(--vp-c-text-1);
}

td {
  color: var(--vp-c-text-2);
}

code {
  background: var(--vp-c-bg-soft);
  padding: 0.2rem 0.4rem;
  border-radius: 3px;
  font-size: 0.9em;
}

.type {
  color: var(--vp-c-brand);
}

.required {
  color: var(--vp-c-danger);
  margin-left: 0.25rem;
}

.no-default {
  color: var(--vp-c-text-3);
  font-style: italic;
}

tr:last-child td {
  border-bottom: none;
}
</style>

Theme Integration

js
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import Demo from './components/Demo.vue'
import ApiTable from './components/ApiTable.vue'

// Import your component library
import * as Components from 'your-component-library'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    // Register demo components
    app.component('Demo', Demo)
    app.component('ApiTable', ApiTable)
    
    // Register your component library
    Object.keys(Components).forEach(key => {
      app.component(key, Components[key])
    })
  }
}

Advanced Features

TypeScript Integration

vue
<!-- Component with TypeScript props -->
<script setup lang="ts">
interface ButtonProps {
  text: string
  variant?: 'primary' | 'secondary' | 'danger'
  size?: 'small' | 'medium' | 'large'
  disabled?: boolean
  loading?: boolean
}

const props = withDefaults(defineProps<ButtonProps>(), {
  variant: 'primary',
  size: 'medium',
  disabled: false,
  loading: false
})
</script>

Design Tokens Documentation

markdown
## Design Tokens

### Colors
- Primary: `#3b82f6`
- Secondary: `#6b7280`
- Danger: `#ef4444`

### Spacing
- Small: `8px`
- Medium: `16px`
- Large: `24px`

### Typography
- Font Family: `Inter, sans-serif`
- Font Sizes: `14px`, `16px`, `18px`

Responsive Examples

vue
<template>
  <div class="responsive-demo">
    <Demo 
      component="Grid"
      :initial-props="{ 
        cols: { xs: 1, sm: 2, md: 3, lg: 4 },
        gap: 16
      }"
    />
  </div>
</template>

Testing Documentation

markdown
## Testing

### Unit Tests
```javascript
import { mount } from '@vue/test-utils'
import Button from './Button.vue'

describe('Button', () => {
  it('renders text correctly', () => {
    const wrapper = mount(Button, {
      props: { text: 'Click me' }
    })
    expect(wrapper.text()).toBe('Click me')
  })
  
  it('emits click event', async () => {
    const wrapper = mount(Button, {
      props: { text: 'Click me' }
    })
    await wrapper.trigger('click')
    expect(wrapper.emitted('click')).toBeTruthy()
  })
})

Accessibility Tests

javascript
import { axe, toHaveNoViolations } from 'jest-axe'

expect.extend(toHaveNoViolations)

it('should not have accessibility violations', async () => {
  const wrapper = mount(Button, {
    props: { text: 'Accessible button' }
  })
  const results = await axe(wrapper.element)
  expect(results).toHaveNoViolations()
})

## Best Practices

### Documentation Structure
- Start with basic usage examples
- Show all variants and states
- Include comprehensive API reference
- Provide real-world usage examples
- Document accessibility features

### Interactive Demos
- Allow users to modify props in real-time
- Show generated code for easy copying
- Include multiple example variations
- Test responsive behavior
- Demonstrate edge cases

### Code Examples
- Use realistic, practical examples
- Show both template and script usage
- Include TypeScript examples
- Demonstrate event handling
- Show integration patterns

## Live Examples

- [Ant Design Vue](https://antdv.com/components/overview)
- [Element Plus](https://element-plus.org/en-US/component/button.html)
- [Vuetify](https://vuetifyjs.com/en/components/buttons/)
- [Quasar](https://quasar.dev/vue-components/button)

## Next Steps

- [Custom Theme](../guide/custom-theme.md) - Theme customization
- [TypeScript Integration](../guide/typescript.md) - TypeScript setup
- [Testing Guide](../guide/testing.md) - Component testing

VitePress Development Guide