home / skills / lucking7 / mapcn-skills / mapcn-docs

mapcn-docs skill

/.factory/skills/mapcn-docs

This skill helps you build comprehensive Next.js App Router documentation sites with live previews, code samples, and accessible, theme-aware UI.

npx playbooks add skill lucking7/mapcn-skills --skill mapcn-docs

Review the files below or copy the command above to add this skill to your agents.

Files (5)
SKILL.md
9.8 KB
---
name: mapcn-docs
description: Use when building documentation sites with live code previews, component library docs, API reference pages, or interactive code examples using Next.js App Router and shadcn/ui.
---

# mapcn-docs

Build beautiful, interactive documentation sites with live component previews and copy-paste code examples.

## Overview

This skill implements a documentation system featuring:
- **Live previews** with tabbed preview/code views
- **Syntax-highlighted code** using Shiki with light/dark theme support
- **Copy-to-clipboard** functionality for all code examples
- **Responsive sidebar** navigation with mobile support
- **Scroll-tracking TOC** (Table of Contents)
- **Accessible design** using shadcn/ui components

## When to Use

**Use this skill when:**
- Building a docs site for a component library or design system
- Creating API reference pages with interactive examples
- Need tabbed preview/code views like shadcn/ui docs
- Want copy-paste ready code examples with syntax highlighting

**Do NOT use when:**
- Simple static documentation (use MDX or plain markdown)
- No need for live component previews
- Not using Next.js App Router or React

**Prerequisites:**
- Next.js 13+ with App Router (`app/` directory)
- Tailwind CSS configured
- shadcn/ui initialized (`npx shadcn@latest init`)

## Quick Start

### 1. Directory Structure

```
src/app/docs/
├── layout.tsx                    # Root docs layout
├── page.tsx                      # Introduction page
├── _components/
│   ├── docs.tsx                  # Core UI components
│   ├── docs-sidebar.tsx          # Navigation sidebar
│   ├── docs-toc.tsx              # Table of contents
│   ├── component-preview.tsx     # Server-side preview wrapper
│   ├── component-preview-client.tsx  # Client-side preview tabs
│   ├── code-block.tsx            # Code display
│   ├── copy-button.tsx           # Clipboard utility
│   └── examples/                 # Live example components
└── [route]/page.tsx              # Documentation pages
```

### 2. Install Dependencies

```bash
npm install shiki
npx shadcn@latest add sidebar table card tabs
```

### 3. Create Core Components

See [references/COMPONENTS.md](references/COMPONENTS.md) for complete component implementations.

## Page Structure Pattern

Every documentation page follows this structure:

```tsx
import { Metadata } from "next";
import { DocsLayout, DocsSection, DocsPropTable } from "../_components/docs";
import { ComponentPreview } from "../_components/component-preview";
import { getExampleSource } from "@/lib/get-example-source";
import { MyExample } from "../_components/examples/my-example";

export const metadata: Metadata = { title: "Page Title" };

export default function PageName() {
  const exampleSource = getExampleSource("my-example.tsx");

  return (
    <DocsLayout
      title="Page Title"
      description="Brief description of this page"
      prev={{ title: "Previous", href: "/docs/previous" }}
      next={{ title: "Next", href: "/docs/next" }}
      toc={[
        { title: "Overview", slug: "overview" },
        { title: "Usage", slug: "usage" },
        { title: "API Reference", slug: "api-reference" },
      ]}
    >
      <DocsSection>
        <p>Introduction paragraph.</p>
      </DocsSection>

      <DocsSection title="Overview">
        <p>Section content here.</p>
      </DocsSection>

      <DocsSection title="Usage">
        <ComponentPreview code={exampleSource}>
          <MyExample />
        </ComponentPreview>
      </DocsSection>

      <DocsSection title="API Reference">
        <DocsPropTable
          props={[
            {
              name: "propName",
              type: "string",
              default: "undefined",
              description: "Description of the prop",
            },
          ]}
        />
      </DocsSection>
    </DocsLayout>
  );
}
```

## Example Component Pattern

Create example components in `_components/examples/`:

```tsx
// Client-side example (with state)
"use client";

import { useState } from "react";
import { MyComponent } from "@/registry/my-component";

export function InteractiveExample() {
  const [value, setValue] = useState("initial");

  return (
    <div className="h-[400px] w-full">
      <MyComponent value={value} onChange={setValue} />
    </div>
  );
}
```

```tsx
// Server-side example (no state)
import { MyComponent } from "@/registry/my-component";

export function SimpleExample() {
  return (
    <div className="h-[400px] w-full">
      <MyComponent />
    </div>
  );
}
```

**Key pattern**: Always wrap examples in a fixed-height container (`h-[400px]`) for consistent preview rendering.

## Navigation Configuration

Define navigation in `docs-navigation.ts`:

```tsx
import { BookOpen, Code, Settings } from "lucide-react";

export const docsNavigation = {
  groups: [
    {
      title: "Getting Started",
      items: [
        { title: "Introduction", href: "/docs", icon: BookOpen },
        { title: "Installation", href: "/docs/installation", icon: Code },
      ],
    },
    {
      title: "Components",
      items: [
        { title: "Button", href: "/docs/button", icon: Settings },
        // Add more components...
      ],
    },
  ],
};
```

## Code Highlighting Setup

Create `lib/highlight.ts`:

```tsx
import { codeToHtml } from "shiki";

export async function highlightCode(code: string, lang = "tsx") {
  return codeToHtml(code, {
    lang,
    themes: {
      light: "github-light",
      dark: "github-dark",
    },
  });
}
```

Create `lib/get-example-source.ts`:

```tsx
import fs from "fs";
import path from "path";

export function getExampleSource(filename: string): string {
  const filePath = path.join(
    process.cwd(),
    "src/app/docs/_components/examples",
    filename
  );

  let content = fs.readFileSync(filePath, "utf-8");

  // Transform import paths for user copy-paste
  content = content.replace(
    /@\/registry\//g,
    "@/components/ui/"
  );

  return content;
}
```

## UI Components

The docs system uses these core components:

| Component | Purpose |
|-----------|---------|
| `DocsLayout` | Page wrapper with prev/next nav and TOC |
| `DocsSection` | Content section with auto-generated slug IDs |
| `DocsHeader` | Page title and description |
| `DocsNote` | Highlighted callout boxes |
| `DocsCode` | Inline code styling |
| `DocsLink` | Styled links with external support |
| `DocsPropTable` | API reference tables |
| `ComponentPreview` | Live preview with code tab |
| `CodeBlock` | Standalone code display |

## Preview System Architecture

```
┌─────────────────────────────────────────────┐
│ ComponentPreview (Server Component)          │
│ - Receives code string                       │
│ - Calls highlightCode() with Shiki           │
│ - Passes highlighted HTML to client          │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│ ComponentPreviewClient (Client Component)    │
│ - Renders tabs: Preview | Code               │
│ - Preview tab: renders children              │
│ - Code tab: shows highlighted code           │
│ - Copy button for code                       │
└─────────────────────────────────────────────┘
```

## Adding a New Documentation Page

1. Create route directory: `src/app/docs/[page-name]/page.tsx`
2. Create example component if needed: `_components/examples/[name]-example.tsx`
3. Add to navigation in `docs-navigation.ts`
4. Update prev/next links on adjacent pages

## Best Practices

1. **Keep examples focused** - One concept per example
2. **Use fixed heights** - `h-[400px]` for consistent previews
3. **Transform imports** - Change internal paths for user copy-paste
4. **Include API tables** - Document all props with types and defaults
5. **Add TOC items** - List all major sections for scroll tracking
6. **Mobile-first** - Test sidebar collapse and responsive layouts

## Common Mistakes

| Mistake | Fix |
|---------|-----|
| Calling `highlightCode` in Client Component | Move to Server Component - Shiki requires server-side execution |
| Missing fixed height on examples | Add `h-[400px]` wrapper for consistent preview rendering |
| Using internal import paths in examples | Use `getExampleSource()` to transform `@/registry/` to `@/components/ui/` |
| Forgetting to update navigation | Always add new pages to `docs-navigation.ts` |
| Not updating prev/next links | Check adjacent pages when adding/removing docs |

## Troubleshooting

| Problem | Solution |
|---------|----------|
| shadcn/ui not installed | Run `npx shadcn@latest init` first, then add components |
| Shiki SSR errors | Ensure `highlightCode` is only called in Server Components |
| Dark mode not working | Add `defaultColor: false` to Shiki config and use CSS `[data-theme]` selectors |
| Preview height inconsistent | Always use fixed height (`h-[400px]`) on example wrappers |
| Copy button not working | Ensure HTTPS or localhost (clipboard API requirement) |

## Prerequisites Check

Before using this skill, verify:
1. Next.js 13+ with App Router (`app/` directory)
2. Tailwind CSS configured
3. `cn()` utility from shadcn/ui (`lib/utils.ts`)

If missing shadcn/ui:
```bash
npx shadcn@latest init
```

## File Reference

- [references/COMPONENTS.md](references/COMPONENTS.md) - Complete component implementations
- [references/LAYOUT.md](references/LAYOUT.md) - Layout and sidebar setup
- [scripts/create-doc-page.sh](scripts/create-doc-page.sh) - Generate new doc pages

Overview

This skill helps you build a polished, interactive documentation site for component libraries and design systems using Next.js App Router and shadcn/ui. It provides live component previews, tabbed preview/code views, syntax-highlighted code with Shiki, and copy-to-clipboard for ready-to-use examples. The layout includes responsive sidebar navigation, a scroll-tracking TOC, and accessible UI components.

How this skill works

The system renders example components inside a server-side preview wrapper that calls Shiki to produce highlighted HTML for code tabs. A client-side component manages tabs (Preview | Code), renders the live example, and offers a copy button for the highlighted source. Utility functions transform internal import paths so code examples are copy-paste ready for users.

When to use it

  • Building docs for a component library or design system
  • Creating API reference pages with interactive examples
  • Needing tabbed preview/code views like shadcn/ui docs
  • Providing copy-paste ready, syntax-highlighted code examples
  • Using Next.js App Router with Tailwind and shadcn/ui

Best practices

  • Keep examples focused — one concept per example
  • Wrap examples in a fixed-height container (e.g. h-[400px]) for consistent previews
  • Run Shiki on the server; call highlight functions from server components only
  • Transform internal import paths for public examples (e.g. @/registry → @/components/ui)
  • Include API prop tables and TOC entries for scroll-tracking and discoverability

Example use cases

  • Component demo pages with live previews and copyable code
  • Interactive API reference entries showing stateful examples
  • Design system documentation with responsive sidebar and TOC
  • Tutorial or cookbook pages that show implementation and result side-by-side
  • Showcase pages for complex components with multiple usage examples

FAQ

Do I need shadcn/ui installed to use this system?

Yes. shadcn/ui provides the UI primitives used across the docs components; run the shadcn init command before integrating the docs system.

Where should code highlighting run?

Shiki must run server-side. Call code-highlighting functions from server components and pass the resulting HTML to the client for display.