# Component Implementation Guide
This document provides detailed code for implementing the proposed dev page components.
## 1. DevPageHeader Component
**File:** `src/components/dev/DevPageHeader.tsx`
```typescript
'use client';
import Link from 'next/link';
import { ArrowLeft } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
interface DevPageHeaderProps {
title: string;
subtitle?: string;
showBackButton?: boolean;
backHref?: string;
}
/**
* DevPageHeader
* Shared sticky header for detail pages with optional back button
*
* Replaces duplicated headers in forms, layouts, and spacing pages
*
* @example
*
*/
export function DevPageHeader({
title,
subtitle,
showBackButton = false,
backHref = '/dev',
}: DevPageHeaderProps) {
return (
{showBackButton && (
)}
{title}
{subtitle && (
{subtitle}
)}
);
}
```
---
## 2. DevBreadcrumbs Component
**File:** `src/components/dev/DevBreadcrumbs.tsx`
```typescript
'use client';
import Link from 'next/link';
import { ChevronRight, Home } from 'lucide-react';
import { cn } from '@/lib/utils';
interface Breadcrumb {
label: string;
href?: string;
}
interface DevBreadcrumbsProps {
items: Breadcrumb[];
className?: string;
}
/**
* DevBreadcrumbs
* Breadcrumb navigation for showing page hierarchy
*
* @example
*
*/
export function DevBreadcrumbs({ items, className }: DevBreadcrumbsProps) {
return (
);
}
```
---
## 3. DevPageFooter Component
**File:** `src/components/dev/DevPageFooter.tsx`
```typescript
import Link from 'next/link';
interface DevPageFooterProps {
documentationLink?: {
label: string;
href: string;
};
}
/**
* DevPageFooter
* Shared footer for dev pages with optional documentation link
*
* @example
*
*/
export function DevPageFooter({ documentationLink }: DevPageFooterProps) {
return (
);
}
```
---
## 4. DevPageLayout Component
**File:** `src/components/dev/DevPageLayout.tsx`
```typescript
import { ReactNode } from 'react';
import { DevPageHeader } from './DevPageHeader';
import { DevBreadcrumbs } from './DevBreadcrumbs';
import { DevPageFooter } from './DevPageFooter';
import { cn } from '@/lib/utils';
interface Breadcrumb {
label: string;
href?: string;
}
interface DocumentationLink {
label: string;
href: string;
}
interface DevPageLayoutProps {
title?: string;
subtitle?: string;
breadcrumbs?: Breadcrumb[];
showBackButton?: boolean;
backHref?: string;
footer?: DocumentationLink | boolean;
children: ReactNode;
className?: string;
}
/**
* DevPageLayout
* Complete page layout wrapper for dev pages
*
* Combines header, breadcrumbs, main content, and footer
*
* @example
*
* {/* Page content */}
*
*/
export function DevPageLayout({
title,
subtitle,
breadcrumbs,
showBackButton = false,
backHref = '/dev',
footer,
children,
className,
}: DevPageLayoutProps) {
// Determine footer configuration
let footerLink: DocumentationLink | undefined;
if (typeof footer === 'object' && footer !== null) {
footerLink = footer;
}
return (
{/* Breadcrumbs (optional) */}
{breadcrumbs && breadcrumbs.length > 0 && (
)}
{/* Page Header (optional) */}
{title && (
)}
{/* Main Content */}
{children}
{/* Footer */}
{footer !== false && }
);
}
```
---
## 5. ExampleLoadingSkeleton Component
**File:** `src/components/dev/ExampleLoadingSkeleton.tsx`
```typescript
import { cn } from '@/lib/utils';
interface ExampleLoadingSkeletonProps {
count?: number;
className?: string;
}
/**
* ExampleLoadingSkeleton
* Loading placeholder for dynamically imported example components
*
* @example
* const Example = dynamic(() => import('@/components/dev/Example'), {
* loading: () => ,
* });
*/
export function ExampleLoadingSkeleton({
count = 1,
className,
}: ExampleLoadingSkeletonProps) {
return (
{Array.from({ length: count }).map((_, i) => (
{/* Title skeleton */}
{/* Description skeleton */}
{/* Content skeleton */}
))}
);
}
```
---
## 6. Example Page Refactoring
### Forms Page (BEFORE)
```typescript
export default function FormsPage() {
const [isSubmitting, setIsSubmitting] = useState(false);
// ... rest of state
return (
Form Patterns
react-hook-form + Zod validation examples
{/* Content sections */}
);
}
```
### Forms Page (AFTER)
```typescript
'use client';
import { useState } from 'react';
import { DevPageLayout } from '@/components/dev/DevPageLayout';
import { ExampleSection } from '@/components/dev/Example';
import { BeforeAfter } from '@/components/dev/BeforeAfter';
// ... other imports
export default function FormsPage() {
const [isSubmitting, setIsSubmitting] = useState(false);
// ... rest of state
return (
{/* Content sections remain the same */}
);
}
```
---
## 7. Updated Component Imports
### Update Example.tsx exports (if extracting ExampleSection)
```typescript
// src/components/dev/Example.tsx
export function Example({ ... }) { ... }
export function ExampleGrid({ ... }) { ... }
export function ExampleSection({ ... }) { ... }
export { ExampleLoadingSkeleton } from './ExampleLoadingSkeleton';
```
### Update spacing/page.tsx dynamic imports
```typescript
import dynamic from 'next/dynamic';
import { ExampleLoadingSkeleton } from '@/components/dev/ExampleLoadingSkeleton';
const Example = dynamic(
() => import('@/components/dev/Example').then((mod) => ({
default: mod.Example
})),
{ loading: () => }
);
const ExampleSection = dynamic(
() => import('@/components/dev/Example').then((mod) => ({
default: mod.ExampleSection
})),
{ loading: () => }
);
const BeforeAfter = dynamic(
() => import('@/components/dev/BeforeAfter').then((mod) => ({
default: mod.BeforeAfter
})),
{ loading: () => }
);
```
---
## 8. Implementation Checklist
### Step 1: Create New Components
- [ ] Create `DevPageHeader.tsx`
- [ ] Create `DevBreadcrumbs.tsx`
- [ ] Create `DevPageFooter.tsx`
- [ ] Create `DevPageLayout.tsx`
- [ ] Create `ExampleLoadingSkeleton.tsx`
### Step 2: Update Forms Page
- [ ] Import `DevPageLayout`
- [ ] Remove custom header
- [ ] Remove custom footer
- [ ] Wrap content with `DevPageLayout`
- [ ] Add breadcrumbs config
- [ ] Test navigation and styling
### Step 3: Update Layouts Page
- [ ] Import `DevPageLayout`
- [ ] Remove custom header
- [ ] Remove custom footer
- [ ] Wrap content with `DevPageLayout`
- [ ] Add breadcrumbs config
- [ ] Test navigation and styling
### Step 4: Update Spacing Page
- [ ] Import `DevPageLayout`
- [ ] Remove custom header
- [ ] Remove custom footer
- [ ] Update dynamic imports to use `ExampleLoadingSkeleton`
- [ ] Wrap content with `DevPageLayout`
- [ ] Add breadcrumbs config
- [ ] Test navigation and styling
### Step 5: Update Components Page
- [ ] Import `DevPageLayout` and `DevBreadcrumbs`
- [ ] Add breadcrumbs
- [ ] Add footer with doc link
- [ ] Update dynamic import to use `ExampleLoadingSkeleton`
- [ ] Test navigation and styling
### Step 6: Update Hub Page
- [ ] Import `DevPageFooter`
- [ ] Add footer component
- [ ] Test styling
### Step 7: Update Docs Page
- [ ] Import `DevPageFooter`
- [ ] Add footer component
- [ ] Test styling
### Step 8: Update Dynamic Docs Page
- [ ] Import `DevPageLayout` or `DevPageFooter`
- [ ] Add breadcrumbs
- [ ] Add footer
- [ ] Test navigation
### Step 9: Testing
- [ ] All pages have consistent headers
- [ ] Breadcrumbs display correctly
- [ ] Back buttons work
- [ ] Footers are present and styled
- [ ] Mobile responsiveness intact
- [ ] No console errors
---
## Usage Examples
### Simple Detail Page (Forms/Layouts/Spacing)
```typescript
{/* Your content */}
```
### Hub Page (with footer only)
```typescript
{/* Hero section */}
{/* Content sections */}
```
### With Breadcrumbs Only
```typescript
{/* Content */}
```
---
## Migration Summary
| Page | Changes |
|------|---------|
| Forms | Remove header/footer, add DevPageLayout |
| Layouts | Remove header/footer, add DevPageLayout |
| Spacing | Remove header/footer, add DevPageLayout, update imports |
| Components | Add breadcrumbs/footer, update imports |
| Hub | Add DevPageFooter |
| Docs | Add DevPageFooter |
| Docs Dynamic | Add DevPageLayout with breadcrumbs |
---
## Testing Commands
```bash
# Type check
npm run type-check
# Lint
npm run lint
# E2E tests
npm run test:e2e
# Build
npm run build
```