Skip to content

Adding Components to Documentation

This guide walks you through the process of adding a new PayAdvantage UI component to the VitePress documentation. It may also be used to update existing documentation.

Audience: This guide is for documentation maintainers and library developers who need to add new components to the documentation site.

Purpose: The component documentation you create should help library consumers (developers using PayAdvantage UI in their applications) understand how to install, import, and use components effectively.

Overview

Adding a component to the documentation involves three main steps:

  1. Register the component in the VitePress theme
  2. Create consumer-focused component documentation with practical examples using the standardized template
  3. Add navigation to the sidebar

Template Available: Use the standardized template at docs/templates/component-documentation-template.md to ensure consistency across all component documentation.

Please point your LLM or at this document in your code base for context priming docs/guide/adding-components.md.

Step 1: Register Component in VitePress Theme

1.1 Import the Component

Add the component import to docs/.vitepress/theme/index.ts:

typescript
// Import the PayAdvantage UI components
import { PaButton } from '../../../src/components/pa-button'
import { PaIcon } from '../../../src/components/pa-icon'
import { PaBadge } from '../../../src/components/pa-badge'
import { PaInput } from '../../../src/components/pa-input'
import { PaCheckbox } from '../../../src/components/pa-checkbox'
import { PaYourNewComponent } from '../../../src/components/pa-your-new-component' // Add this line

1.2 Register Component Globally

Add the component registration in the enhanceApp function:

typescript
export default {
  extends: DefaultTheme,
  enhanceApp({ app }: { app: App }) {
    // ...existing registrations...
    
    // Register your new component (add these lines)
    app.component('PaYourNewComponent', PaYourNewComponent)
    app.component('pa-your-new-component', PaYourNewComponent)
  }
}

Note: Register both PascalCase and kebab-case versions for flexibility in documentation examples.

Step 2: Create Component Documentation

2.1 Create Documentation File

Create a new file: docs/components/pa-your-new-component.md

2.2 Documentation Structure

Quick Start: Copy the template file docs/templates/component-documentation-template.md and customize it for your component.

Use this template structure for consistent consumer-focused documentation:

markdown
# ComponentName

`<pa-component-name> | PaComponentName`

Brief description of what the component does and its primary use cases for application developers.

\`\`\`vue
<pa-component-name>Basic Example</pa-component-name>
\`\`\`

## Examples

### Basic Usage

<div class="template-wrapper">
  <pa-component-name>Example content</pa-component-name>
</div>
3177 6324
\`\`\`vue
<template>
  <pa-component-name v-model="value">Example content</pa-component-name>
</template>

<script setup>
import { ref } from 'vue'

const value = ref('')
</script>
\`\`\`

### Variants/Props

Document each major prop or variant with visual examples showing how consumers would use them in their applications.

## Importing

\`\`\`typescript
import { PaComponentName } from '@payadvantage/ui-components'
\`\`\`

## Slots

| Name | Description |
|------|-------------|
| (default) | Description of the default slot. |

## Properties

| Name | Description | Reflects | Type | Default |
|------|-------------|----------|------|---------|
| `propName` | Description of the prop. | no | `string` | `'default'` |

## Events

| Name | Description | Event Detail |
|------|-------------|--------------|
| `eventName` | Description of when this event is emitted. | Event payload |

## Dependencies

Description of any dependencies or requirements.

2.3 Visual Example Guidelines

For consistent visual examples, wrap them in the template-wrapper class:

html
<div class="template-wrapper">
  <!-- Your component examples here -->
</div>

For layout examples, use template-wrapper with modifiers:

  • Flex layouts: class="template-wrapper flex"
  • Centered flex: class="template-wrapper flex-center"
  • Constrained width: class="template-wrapper max-width-300"
  • Basic container: class="template-wrapper"

These classes provide consistent styling across all component documentation and make examples look professional for library consumers.

2.4 Code Examples

Always provide both the visual example AND the corresponding code that library consumers can copy into their applications:

markdown
<div class="template-wrapper">
  <pa-component>Live Example</pa-component>
</div>

\`\`\`vue
<template>
  <pa-component v-model="value">Live Example</pa-component>
</template>
\`\`\`

Focus on Component States and Props:

  • Component-focused: Examples should demonstrate different component states, variants, and prop configurations
  • Individual behavior: Show how each prop affects the component's appearance or behavior
  • State variations: Document disabled, loading, error, and other component states
  • Prop combinations: Demonstrate how different props work together within the component
  • Avoid integration: Don't show how the component works with other components or in complex application scenarios
  • Keep isolated: Each example should focus on the component itself, not its role in larger patterns

2.5 Dynamic Interactive Examples

For components that benefit from interactive demonstrations (like sliders, switches, inputs with real-time feedback), create dedicated Vue components for the examples:

Creating Dynamic Example Components

  1. Create a Vue component in docs/.vitepress/components/ directory:

    docs/.vitepress/components/YourComponentBasicExample.vue
  2. Follow the pa-slider examples as a guide:

    • SliderBasicExample.vue - Shows interactive functionality with real-time value display
    • SliderProgressExample.vue - Demonstrates specific use case
    • SliderPriceExample.vue - Shows practical application scenario
  3. Example structure:

    vue
    <template>
      <div class="example-container">
        <pa-your-component 
          v-model="value" 
          @update:modelValue="handleChange"
        />
        <div class="value-display">Current value: {{ value }}</div>
      </div>
    </template>
    
    <script setup>
    import { ref } from 'vue'
    
    const value = ref(initialValue)
    
    const handleChange = (newValue) => {
      // Optional: Handle value changes for demonstration
    }
    </script>
    
    <style scoped>
    .example-container {
      padding: 1rem;
      background: var(--vp-c-bg-soft);
      border-radius: 8px;
      border: 1px solid var(--vp-c-border);
    }
    
    .value-display {
      margin-top: 1rem;
      font-family: var(--vp-font-family-mono);
      color: var(--vp-c-text-2);
    }
    </style>
  4. Register the component in docs/.vitepress/theme/index.ts:

    typescript
    import YourComponentBasicExample from '../components/YourComponentBasicExample.vue'
    
    // In the enhanceApp function:
    app.component('YourComponentBasicExample', YourComponentBasicExample)
  5. Use in documentation:

    markdown
    ### Interactive Example
    
    <YourComponentBasicExample />

When to Create Dynamic Examples

Create interactive Vue components when:

  • User interaction is key - Components like sliders, switches, inputs where seeing real-time changes helps understanding of component behavior
  • State management within component - Components that manage internal state or have multiple interactive features
  • Visual feedback demonstration - Components where the visual response to user actions is a key feature of the component itself
  • Prop interaction effects - When showing how different prop combinations affect component behavior in real-time

Note: Dynamic examples should focus on demonstrating component features and states, not integration with other components or application-level patterns.

Dynamic Example Best Practices

  • Keep it focused - Each example component should demonstrate one component feature or state
  • Show component behavior - Display how the component's internal state or appearance changes
  • Use realistic props - Use example prop values that represent real-world component usage
  • Demonstrate component states - Show how the component behaves in different states (disabled, loading, error, etc.)
  • Avoid integration complexity - Don't show forms, validation, or multi-component interactions
  • Style consistently - Use VitePress CSS custom properties for theming that matches the documentation site

Step 3: Add Navigation

3.1 Update Sidebar Configuration

Add the component to the appropriate section in docs/.vitepress/config.ts:

typescript
sidebar: {
  '/components/': [
    {
      text: 'Overview',
      items: [
        { text: 'All Components', link: '/components/' }
      ]
    },
    {
      text: 'Form Components',
      items: [
        { text: 'Button', link: '/components/pa-button' },
        { text: 'Badge', link: '/components/pa-badge' },
        { text: 'Input', link: '/components/pa-input' },
        { text: 'Checkbox', link: '/components/pa-checkbox' },
        { text: 'Your New Component', link: '/components/pa-your-new-component' } // Add this
      ]
    }
  ]
}

3.2 Organize by Category

Group components logically:

  • Form Components: Button, Input, Checkbox, Radio, Select, etc.
  • Display Components: Badge, Alert, Card, Modal, etc.
  • Navigation Components: Tabs, Breadcrumb, Pagination, etc.
  • Layout Components: Container, Grid, Divider, etc.

Step 4: Testing and Verification

4.1 Start Development Server

bash
npm run docs:dev

4.2 Verify Component Registration

  1. Navigate to your component's documentation page
  2. Check that all visual examples render correctly
  3. Verify that both PascalCase and kebab-case work in examples
  4. Test responsive behavior and styling

4.3 Check Navigation

  1. Verify the component appears in the sidebar
  2. Ensure the link works correctly
  3. Check that the component fits logically in its category

Best Practices

Consumer-Focused Documentation

  • Component-centric: Focus on the individual component's props, states, and behavior
  • Property demonstration: Show how each prop affects the component's appearance or functionality
  • State variations: Document different component states (disabled, loading, error, active, etc.)
  • Variant coverage: Cover all available component variants, sizes, and styling options
  • Clear boundaries: Keep examples focused on the component itself, not its integration with other components
  • Avoid application context: Don't show complex forms, page layouts, or multi-component workflows

Visual Examples

  • Component states: Use examples to show different states (hover, focus, disabled, active)
  • Prop variations: Document how different prop values affect the component's appearance
  • Size and variant options: Show all available sizes, colors, and style variants
  • Content variations: Demonstrate how the component handles different content types or lengths
  • Individual component focus: Keep examples isolated to the component being documented
  • Template-wrapper styling: Use .template-wrapper classes for consistent, professional appearance

Code Quality

  • Component-focused TypeScript: Use proper typing for component props and events
  • Modern Vue 3 syntax: Prefer <script setup> syntax for reactive examples
  • Clear imports: Show both global and individual component imports
  • Minimal reactive data: Use ref() only when needed to demonstrate component behavior
  • Component isolation: Focus on the component's API, not application-level concerns

Troubleshooting

Component Not Rendering

  1. Check that the component is properly imported in index.ts
  2. Verify the component is registered in enhanceApp
  3. Ensure the component path is correct

Styling Issues

  1. Verify theme CSS is imported (theme-payadvantage.css)
  2. Check that design tokens are loaded (design-tokens.css)
  3. Ensure Bootstrap classes are available if needed
  1. Check the sidebar configuration in config.ts
  2. Verify the link path matches the file path
  3. Ensure proper nesting in sidebar structure

Documentation Template

Template Location: docs/templates/component-documentation-template.md

To ensure consistency across all component documentation:

  1. Copy the template file docs/templates/component-documentation-template.md
  2. Rename to docs/components/pa-your-component.md
  3. Replace all placeholders with your component's specific information
  4. Follow the exact structure - do not skip required sections

Template Usage Rules

Required Sections (Every Component Must Have):

  1. Title & Component Tags - Always include both kebab-case and PascalCase
  2. Brief Description - One paragraph explaining purpose and use cases
  3. Usage Section - Show the most common implementation pattern
  4. Examples Section - Minimum of Basic and Advanced examples
  5. Importing Section - Standard import statement
  6. Properties Section - All props with types and defaults
  7. Events Section - All emitted events
  8. Dependencies Section - Required components or "None"

Optional Sections (Include When Applicable):

  • Slots Section - Only if component has slots
  • Advanced Props - For complex prop configurations that affect component behavior

Note: Integration examples showing how components work together should be documented separately in the examples section, not within individual component documentation.

Template Wrapper Guidelines:

  • Always use <div class="template-wrapper"> for visual examples
  • Add modifiers when needed:
    • template-wrapper flex - For flex layouts
    • template-wrapper flex-center - For centered flex
    • template-wrapper max-width-300 - For constrained width

Code Example Requirements:

  • Always include <template> blocks for Vue examples
  • Include <script setup> when using reactive data to demonstrate component behavior
  • Show complete copyable code that focuses on the component
  • Use descriptive prop values that clearly show the component's capabilities
  • Component-focused examples that demonstrate props, states, and variants

Component Documentation vs Integration Examples

Component Documentation Purpose: Individual component documentation should focus solely on demonstrating the component's API, props, states, and individual behavior patterns.

What to Include in Component Docs:

  • All available props and their effects on the component
  • Different component states (disabled, loading, error, active, etc.)
  • Available variants, sizes, and styling options
  • Slot usage and content variations
  • Individual component events and their triggers

What NOT to Include in Component Docs:

  • Multi-component integration patterns
  • Form validation workflows
  • Complex application layouts
  • Page-level composition examples
  • Authentication or data fetching patterns

Where Integration Examples Belong: Integration patterns, workflows, and multi-component examples should be documented in the docs/examples/ section, not within individual component documentation.

Example Structure Distinction:

markdown
<!-- ✅ Good: Component-focused example -->
<pa-button variant="primary" size="large" disabled>
  Large Disabled Button
</pa-button>

<!-- ❌ Avoid: Integration-focused example -->
<form @submit="handleSubmit">
  <pa-input v-model="email" type="email" />
  <pa-button type="submit" :loading="isSubmitting">
    Submit Form
  </pa-button>
</form>

Example: Complete Addition Process

Here's a complete example of adding a new pa-alert component with consumer-focused documentation:

1. Register Component

typescript
// docs/.vitepress/theme/index.ts
import { PaAlert } from '../../../src/components/pa-alert'

app.component('PaAlert', PaAlert)
app.component('pa-alert', PaAlert)

2. Create Consumer-Focused Documentation

markdown
# Alert

`<pa-alert> | PaAlert`

Alerts provide contextual feedback messages for typical user actions in your Vue 3 applications.

## Usage

<div class="template-wrapper">
  <pa-alert variant="info">This is an info alert</pa-alert>
</div>

\`\`\`vue
<template>
  <pa-alert variant="info">This is an info alert</pa-alert>
</template>
\`\`\`

## Examples

### Variants

<div class="template-wrapper flex" style="flex-direction: column;">
  <pa-alert variant="primary">Primary alert for general information</pa-alert>
  <pa-alert variant="danger">Danger alert for errors or critical issues</pa-alert>
</div>

\`\`\`vue
<template>
  <div>
    <pa-alert variant="primary">Primary alert for general information</pa-alert>
    <pa-alert variant="danger">Danger alert for errors or critical issues</pa-alert>
  </div>
</template>
\`\`\`

<!-- Continue with full documentation... -->

3. Add Navigation

typescript
{
  text: 'Display Components',
  items: [
    { text: 'Alert', link: '/components/pa-alert' },
    { text: 'Badge', link: '/components/pa-badge' }
  ]
}

Following this process ensures consistent, high-quality component documentation that helps library consumers understand how to effectively integrate and use PayAdvantage UI components in their Vue 3 applications.