Introduce DevBreadcrumbs component for navigation and replace headers in /dev pages with breadcrumb navigation. Adjust spacing for consistent layout.

This commit is contained in:
2025-11-02 16:07:39 +01:00
parent 86d8e1cace
commit 911d4a594e
7 changed files with 109 additions and 62 deletions

View File

@@ -9,6 +9,7 @@ import { promises as fs } from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { MarkdownContent } from '@/components/docs/MarkdownContent';
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
interface DocPageProps {
params: Promise<{ slug: string[] }>;
@@ -56,10 +57,23 @@ export default async function DocPage({ params }: DocPageProps) {
notFound();
}
// Extract title from first heading or use filename
const title = doc.content.match(/^#\s+(.+)$/m)?.[1] || slug[slug.length - 1];
return (
<div className="container mx-auto px-4 py-8">
<div className="mx-auto max-w-4xl">
<MarkdownContent content={doc.content} />
<div className="bg-background">
{/* Breadcrumbs */}
<DevBreadcrumbs
items={[
{ label: 'Documentation', href: '/dev/docs' },
{ label: title }
]}
/>
<div className="container mx-auto px-4 py-12">
<div className="mx-auto max-w-4xl">
<MarkdownContent content={doc.content} />
</div>
</div>
</div>
);

View File

@@ -9,6 +9,7 @@ import { BookOpen, Sparkles, Layout, Palette, Code2, FileCode, Accessibility, Li
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
interface DocItem {
title: string;
@@ -98,8 +99,11 @@ const referencesDocs: DocItem[] = [
export default function DocsHub() {
return (
<div className="bg-background">
{/* Breadcrumbs */}
<DevBreadcrumbs items={[{ label: 'Documentation' }]} />
{/* Hero Section */}
<section className="border-b bg-gradient-to-b from-background to-muted/20 py-16">
<section className="border-b bg-gradient-to-b from-background to-muted/20 py-12">
<div className="container mx-auto px-4">
<div className="mx-auto max-w-3xl text-center">
<h2 className="text-4xl font-bold tracking-tight mb-4">

View File

@@ -11,8 +11,9 @@ import Link from 'next/link';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { ArrowLeft, CheckCircle2, Loader2 } from 'lucide-react';
import { CheckCircle2, Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
import {
Card,
CardContent,
@@ -94,26 +95,12 @@ export default function FormsPage() {
};
return (
<div className="min-h-screen bg-background">
{/* Header */}
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="container mx-auto flex h-16 items-center gap-4 px-4">
<Link href="/dev">
<Button variant="ghost" size="icon" aria-label="Back to hub">
<ArrowLeft className="h-5 w-5" />
</Button>
</Link>
<div>
<h1 className="text-xl font-bold">Form Patterns</h1>
<p className="text-sm text-muted-foreground">
react-hook-form + Zod validation examples
</p>
</div>
</div>
</header>
<div className="bg-background">
{/* Breadcrumbs */}
<DevBreadcrumbs items={[{ label: 'Forms' }]} />
{/* Content */}
<main className="container mx-auto px-4 py-8">
<main className="container mx-auto px-4 py-12">
<div className="space-y-12">
{/* Introduction */}
<div className="max-w-3xl space-y-4">

View File

@@ -6,7 +6,8 @@
import type { Metadata } from 'next';
import Link from 'next/link';
import { ArrowLeft, Grid3x3 } from 'lucide-react';
import { Grid3x3 } from 'lucide-react';
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
import { Button } from '@/components/ui/button';
import {
Card,
@@ -26,26 +27,12 @@ export const metadata: Metadata = {
export default function LayoutsPage() {
return (
<div className="min-h-screen bg-background">
{/* Header */}
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="container mx-auto flex h-16 items-center gap-4 px-4">
<Link href="/dev">
<Button variant="ghost" size="icon" aria-label="Back to hub">
<ArrowLeft className="h-5 w-5" />
</Button>
</Link>
<div>
<h1 className="text-xl font-bold">Layout Patterns</h1>
<p className="text-sm text-muted-foreground">
Essential patterns for pages, dashboards, and forms
</p>
</div>
</div>
</header>
<div className="bg-background">
{/* Breadcrumbs */}
<DevBreadcrumbs items={[{ label: 'Layouts' }]} />
{/* Content */}
<main className="container mx-auto px-4 py-8">
<main className="container mx-auto px-4 py-12">
<div className="space-y-12">
{/* Introduction */}
<div className="max-w-3xl space-y-4">

View File

@@ -7,7 +7,8 @@
import type { Metadata } from 'next';
import dynamic from 'next/dynamic';
import Link from 'next/link';
import { ArrowLeft, Ruler } from 'lucide-react';
import { Ruler } from 'lucide-react';
import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs';
import { Button } from '@/components/ui/button';
import {
Card,
@@ -41,26 +42,12 @@ export const metadata: Metadata = {
export default function SpacingPage() {
return (
<div className="min-h-screen bg-background">
{/* Header */}
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="container mx-auto flex h-16 items-center gap-4 px-4">
<Link href="/dev">
<Button variant="ghost" size="icon" aria-label="Back to hub">
<ArrowLeft className="h-5 w-5" />
</Button>
</Link>
<div>
<h1 className="text-xl font-bold">Spacing Patterns</h1>
<p className="text-sm text-muted-foreground">
Parent-controlled spacing philosophy
</p>
</div>
</div>
</header>
<div className="bg-background">
{/* Breadcrumbs */}
<DevBreadcrumbs items={[{ label: 'Spacing' }]} />
{/* Content */}
<main className="container mx-auto px-4 py-8">
<main className="container mx-auto px-4 py-12">
<div className="space-y-12">
{/* Introduction */}
<div className="max-w-3xl space-y-4">

View File

@@ -67,6 +67,7 @@ import {
TableRow,
} from '@/components/ui/table';
import { Example, ExampleGrid, ExampleSection } from './Example';
import { DevBreadcrumbs } from './DevBreadcrumbs';
/**
* Component showcase
@@ -76,8 +77,11 @@ export function ComponentShowcase() {
return (
<div className="bg-background">
{/* Breadcrumbs */}
<DevBreadcrumbs items={[{ label: 'Components' }]} />
{/* Content */}
<main className="container mx-auto px-4 py-8">
<main className="container mx-auto px-4 py-12">
<div className="space-y-12">
{/* Colors */}
<ExampleSection

View File

@@ -0,0 +1,64 @@
/* istanbul ignore file */
/**
* DevBreadcrumbs Component
* Breadcrumb navigation for dev pages
* This file is excluded from coverage as it's a development tool
*/
'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;
}
export function DevBreadcrumbs({ items, className }: DevBreadcrumbsProps) {
return (
<nav
className={cn('bg-muted/30 border-b', className)}
aria-label="Breadcrumb"
>
<div className="container mx-auto px-4 py-3">
<ol className="flex items-center gap-2 text-sm">
{/* Home link */}
<li>
<Link
href="/dev"
className="inline-flex items-center gap-1.5 text-muted-foreground hover:text-foreground transition-colors"
>
<Home className="h-4 w-4" />
<span>Hub</span>
</Link>
</li>
{/* Breadcrumb items */}
{items.map((item, index) => (
<li key={index} className="flex items-center gap-2">
<ChevronRight className="h-4 w-4 text-muted-foreground" />
{item.href ? (
<Link
href={item.href}
className="text-muted-foreground hover:text-foreground transition-colors"
>
{item.label}
</Link>
) : (
<span className="text-foreground font-medium">{item.label}</span>
)}
</li>
))}
</ol>
</div>
</nav>
);
}