Refactor AtomsSection and MoleculesSection into focused components

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-17 23:01:41 +00:00
parent 222fdda7c4
commit 311016a0fa
14 changed files with 823 additions and 697 deletions

View File

@@ -1,21 +1,10 @@
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Input } from '@/components/ui/input'
import { Separator } from '@/components/ui/separator'
import { Card } from '@/components/ui/card'
import {
Heart,
Star,
Lightning,
Check,
X,
Plus,
Minus,
MagnifyingGlass,
} from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { atomsCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
import { ButtonsSection } from './ButtonsSection'
import { BadgesSection } from './BadgesSection'
import { InputsSection } from './InputsSection'
import { TypographySection } from './TypographySection'
import { IconsSection } from './IconsSection'
import { ColorsSection } from './ColorsSection'
interface AtomsSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
@@ -24,375 +13,12 @@ interface AtomsSectionProps {
export function AtomsSection({ onSaveSnippet }: AtomsSectionProps) {
return (
<div className="space-y-16">
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Buttons</h2>
<p className="text-muted-foreground">
Interactive controls with multiple variants and states
</p>
</div>
<ComponentShowcase
code={atomsCodeSnippets.buttonWithIcons}
title="Button with Icons"
description="Buttons with icon and text combinations"
category="atoms"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-8">
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Variants
</h3>
<div className="flex flex-wrap gap-4">
<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Sizes
</h3>
<div className="flex flex-wrap items-center gap-4">
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon">
<Heart weight="fill" />
</Button>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
With Icons
</h3>
<div className="flex flex-wrap gap-4">
<Button>
<Star weight="fill" />
Favorite
</Button>
<Button variant="outline">
<Plus weight="bold" />
Add Item
</Button>
<Button variant="secondary">
<Lightning weight="fill" />
Quick Action
</Button>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
States
</h3>
<div className="flex flex-wrap gap-4">
<Button disabled>Disabled</Button>
<Button variant="outline" disabled>
Disabled Outline
</Button>
</div>
</div>
</div>
</Card>
</ComponentShowcase>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Badges</h2>
<p className="text-muted-foreground">
Small status indicators and labels
</p>
</div>
<ComponentShowcase
code={atomsCodeSnippets.badgeWithIcons}
title="Badge with Icons"
description="Badge components with icon combinations"
category="atoms"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-8">
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Variants
</h3>
<div className="flex flex-wrap gap-4">
<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
With Icons
</h3>
<div className="flex flex-wrap gap-4">
<Badge>
<Check weight="bold" className="mr-1" />
Completed
</Badge>
<Badge variant="destructive">
<X weight="bold" className="mr-1" />
Failed
</Badge>
<Badge variant="secondary">
<Star weight="fill" className="mr-1" />
Featured
</Badge>
</div>
</div>
</div>
</Card>
</ComponentShowcase>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Inputs</h2>
<p className="text-muted-foreground">
Form input fields for user data entry
</p>
</div>
<ComponentShowcase
code={atomsCodeSnippets.inputWithIcon}
title="Input with Icon"
description="Input field with icon decoration"
category="atoms"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-8">
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
States
</h3>
<div className="space-y-4 max-w-md">
<Input placeholder="Default input" />
<Input placeholder="Disabled input" disabled />
<div className="relative">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search..." className="pl-10" />
</div>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Types
</h3>
<div className="space-y-4 max-w-md">
<Input type="text" placeholder="Text input" />
<Input type="email" placeholder="email@example.com" />
<Input type="password" placeholder="Password" />
<Input type="number" placeholder="123" />
</div>
</div>
</div>
</Card>
</ComponentShowcase>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Typography</h2>
<p className="text-muted-foreground">
Text styles and hierarchical type scale
</p>
</div>
<Card className="p-6">
<div className="space-y-6">
<div>
<h1 className="text-5xl font-bold mb-2">Heading 1</h1>
<p className="text-sm text-muted-foreground">
Bricolage Grotesque Bold / 48px
</p>
</div>
<Separator />
<div>
<h2 className="text-4xl font-semibold mb-2">Heading 2</h2>
<p className="text-sm text-muted-foreground">
Bricolage Grotesque Semibold / 36px
</p>
</div>
<Separator />
<div>
<h3 className="text-3xl font-semibold mb-2">Heading 3</h3>
<p className="text-sm text-muted-foreground">
Bricolage Grotesque Semibold / 30px
</p>
</div>
<Separator />
<div>
<h4 className="text-2xl font-medium mb-2">Heading 4</h4>
<p className="text-sm text-muted-foreground">
Bricolage Grotesque Medium / 24px
</p>
</div>
<Separator />
<div>
<p className="text-base mb-2">
Body text - The quick brown fox jumps over the lazy dog. This is
regular body text used for paragraphs and general content.
</p>
<p className="text-sm text-muted-foreground">Inter Regular / 16px</p>
</div>
<Separator />
<div>
<p className="text-sm text-muted-foreground mb-2">
Small text - Additional information, captions, and secondary content.
</p>
<p className="text-sm text-muted-foreground">Inter Regular / 14px</p>
</div>
<Separator />
<div>
<code className="text-sm bg-muted px-2 py-1 rounded">
const example = "code text";
</code>
<p className="text-sm text-muted-foreground mt-2">
JetBrains Mono Regular / 14px
</p>
</div>
</div>
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Icons</h2>
<p className="text-muted-foreground">
Phosphor icon set with multiple weights
</p>
</div>
<Card className="p-6">
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 lg:grid-cols-10 gap-6">
<div className="flex flex-col items-center gap-2">
<Heart className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Heart</span>
</div>
<div className="flex flex-col items-center gap-2">
<Star className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Star</span>
</div>
<div className="flex flex-col items-center gap-2">
<Lightning className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Lightning</span>
</div>
<div className="flex flex-col items-center gap-2">
<Check className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Check</span>
</div>
<div className="flex flex-col items-center gap-2">
<X className="h-8 w-8" />
<span className="text-xs text-muted-foreground">X</span>
</div>
<div className="flex flex-col items-center gap-2">
<Plus className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Plus</span>
</div>
<div className="flex flex-col items-center gap-2">
<Minus className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Minus</span>
</div>
<div className="flex flex-col items-center gap-2">
<MagnifyingGlass className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Search</span>
</div>
</div>
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Colors</h2>
<p className="text-muted-foreground">
Semantic color palette with accessibility in mind
</p>
</div>
<Card className="p-6">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<div className="space-y-2">
<div className="h-24 rounded-lg bg-primary" />
<div>
<p className="font-medium">Primary</p>
<code className="text-xs text-muted-foreground">
oklch(0.50 0.18 310)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-secondary" />
<div>
<p className="font-medium">Secondary</p>
<code className="text-xs text-muted-foreground">
oklch(0.30 0.08 310)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-accent" />
<div>
<p className="font-medium">Accent</p>
<code className="text-xs text-muted-foreground">
oklch(0.72 0.20 25)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-destructive" />
<div>
<p className="font-medium">Destructive</p>
<code className="text-xs text-muted-foreground">
oklch(0.577 0.245 27.325)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-muted" />
<div>
<p className="font-medium">Muted</p>
<code className="text-xs text-muted-foreground">
oklch(0.25 0.06 310)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-card border border-border" />
<div>
<p className="font-medium">Card</p>
<code className="text-xs text-muted-foreground">
oklch(0.20 0.12 310)
</code>
</div>
</div>
</div>
</Card>
</section>
<ButtonsSection onSaveSnippet={onSaveSnippet} />
<BadgesSection onSaveSnippet={onSaveSnippet} />
<InputsSection onSaveSnippet={onSaveSnippet} />
<TypographySection />
<IconsSection />
<ColorsSection />
</div>
)
}

View File

@@ -0,0 +1,70 @@
import { Badge } from '@/components/ui/badge'
import { Card } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { Check, X, Star } from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { atomsCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
interface BadgesSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
}
export function BadgesSection({ onSaveSnippet }: BadgesSectionProps) {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Badges</h2>
<p className="text-muted-foreground">
Small status indicators and labels
</p>
</div>
<ComponentShowcase
code={atomsCodeSnippets.badgeWithIcons}
title="Badge with Icons"
description="Badge components with icon combinations"
category="atoms"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-8">
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Variants
</h3>
<div className="flex flex-wrap gap-4">
<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
With Icons
</h3>
<div className="flex flex-wrap gap-4">
<Badge>
<Check weight="bold" className="mr-1" />
Completed
</Badge>
<Badge variant="destructive">
<X weight="bold" className="mr-1" />
Failed
</Badge>
<Badge variant="secondary">
<Star weight="fill" className="mr-1" />
Featured
</Badge>
</div>
</div>
</div>
</Card>
</ComponentShowcase>
</section>
)
}

View File

@@ -0,0 +1,107 @@
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import {
Heart,
Star,
Lightning,
Plus,
} from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { atomsCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
interface ButtonsSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
}
export function ButtonsSection({ onSaveSnippet }: ButtonsSectionProps) {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Buttons</h2>
<p className="text-muted-foreground">
Interactive controls with multiple variants and states
</p>
</div>
<ComponentShowcase
code={atomsCodeSnippets.buttonWithIcons}
title="Button with Icons"
description="Buttons with icon and text combinations"
category="atoms"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-8">
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Variants
</h3>
<div className="flex flex-wrap gap-4">
<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Sizes
</h3>
<div className="flex flex-wrap items-center gap-4">
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon">
<Heart weight="fill" />
</Button>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
With Icons
</h3>
<div className="flex flex-wrap gap-4">
<Button>
<Star weight="fill" />
Favorite
</Button>
<Button variant="outline">
<Plus weight="bold" />
Add Item
</Button>
<Button variant="secondary">
<Lightning weight="fill" />
Quick Action
</Button>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
States
</h3>
<div className="flex flex-wrap gap-4">
<Button disabled>Disabled</Button>
<Button variant="outline" disabled>
Disabled Outline
</Button>
</div>
</div>
</div>
</Card>
</ComponentShowcase>
</section>
)
}

View File

@@ -0,0 +1,73 @@
import { Card } from '@/components/ui/card'
export function ColorsSection() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Colors</h2>
<p className="text-muted-foreground">
Semantic color palette with accessibility in mind
</p>
</div>
<Card className="p-6">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<div className="space-y-2">
<div className="h-24 rounded-lg bg-primary" />
<div>
<p className="font-medium">Primary</p>
<code className="text-xs text-muted-foreground">
oklch(0.50 0.18 310)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-secondary" />
<div>
<p className="font-medium">Secondary</p>
<code className="text-xs text-muted-foreground">
oklch(0.30 0.08 310)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-accent" />
<div>
<p className="font-medium">Accent</p>
<code className="text-xs text-muted-foreground">
oklch(0.72 0.20 25)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-destructive" />
<div>
<p className="font-medium">Destructive</p>
<code className="text-xs text-muted-foreground">
oklch(0.577 0.245 27.325)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-muted" />
<div>
<p className="font-medium">Muted</p>
<code className="text-xs text-muted-foreground">
oklch(0.25 0.06 310)
</code>
</div>
</div>
<div className="space-y-2">
<div className="h-24 rounded-lg bg-card border border-border" />
<div>
<p className="font-medium">Card</p>
<code className="text-xs text-muted-foreground">
oklch(0.20 0.12 310)
</code>
</div>
</div>
</div>
</Card>
</section>
)
}

View File

@@ -0,0 +1,61 @@
import { Card } from '@/components/ui/card'
import {
Heart,
Star,
Lightning,
Check,
X,
Plus,
Minus,
MagnifyingGlass,
} from '@phosphor-icons/react'
export function IconsSection() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Icons</h2>
<p className="text-muted-foreground">
Phosphor icon set with multiple weights
</p>
</div>
<Card className="p-6">
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 lg:grid-cols-10 gap-6">
<div className="flex flex-col items-center gap-2">
<Heart className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Heart</span>
</div>
<div className="flex flex-col items-center gap-2">
<Star className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Star</span>
</div>
<div className="flex flex-col items-center gap-2">
<Lightning className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Lightning</span>
</div>
<div className="flex flex-col items-center gap-2">
<Check className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Check</span>
</div>
<div className="flex flex-col items-center gap-2">
<X className="h-8 w-8" />
<span className="text-xs text-muted-foreground">X</span>
</div>
<div className="flex flex-col items-center gap-2">
<Plus className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Plus</span>
</div>
<div className="flex flex-col items-center gap-2">
<Minus className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Minus</span>
</div>
<div className="flex flex-col items-center gap-2">
<MagnifyingGlass className="h-8 w-8" />
<span className="text-xs text-muted-foreground">Search</span>
</div>
</div>
</Card>
</section>
)
}

View File

@@ -0,0 +1,64 @@
import { Input } from '@/components/ui/input'
import { Card } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { MagnifyingGlass } from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { atomsCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
interface InputsSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
}
export function InputsSection({ onSaveSnippet }: InputsSectionProps) {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Inputs</h2>
<p className="text-muted-foreground">
Form input fields for user data entry
</p>
</div>
<ComponentShowcase
code={atomsCodeSnippets.inputWithIcon}
title="Input with Icon"
description="Input field with icon decoration"
category="atoms"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-8">
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
States
</h3>
<div className="space-y-4 max-w-md">
<Input placeholder="Default input" />
<Input placeholder="Disabled input" disabled />
<div className="relative">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search..." className="pl-10" />
</div>
</div>
</div>
<Separator />
<div className="space-y-3">
<h3 className="text-sm font-medium text-muted-foreground uppercase tracking-wider">
Types
</h3>
<div className="space-y-4 max-w-md">
<Input type="text" placeholder="Text input" />
<Input type="email" placeholder="email@example.com" />
<Input type="password" placeholder="Password" />
<Input type="number" placeholder="123" />
</div>
</div>
</div>
</Card>
</ComponentShowcase>
</section>
)
}

View File

@@ -0,0 +1,71 @@
import { Card } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
export function TypographySection() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Typography</h2>
<p className="text-muted-foreground">
Text styles and hierarchical type scale
</p>
</div>
<Card className="p-6">
<div className="space-y-6">
<div>
<h1 className="text-5xl font-bold mb-2">Heading 1</h1>
<p className="text-sm text-muted-foreground">
Bricolage Grotesque Bold / 48px
</p>
</div>
<Separator />
<div>
<h2 className="text-4xl font-semibold mb-2">Heading 2</h2>
<p className="text-sm text-muted-foreground">
Bricolage Grotesque Semibold / 36px
</p>
</div>
<Separator />
<div>
<h3 className="text-3xl font-semibold mb-2">Heading 3</h3>
<p className="text-sm text-muted-foreground">
Bricolage Grotesque Semibold / 30px
</p>
</div>
<Separator />
<div>
<h4 className="text-2xl font-medium mb-2">Heading 4</h4>
<p className="text-sm text-muted-foreground">
Bricolage Grotesque Medium / 24px
</p>
</div>
<Separator />
<div>
<p className="text-base mb-2">
Body text - The quick brown fox jumps over the lazy dog. This is
regular body text used for paragraphs and general content.
</p>
<p className="text-sm text-muted-foreground">Inter Regular / 16px</p>
</div>
<Separator />
<div>
<p className="text-sm text-muted-foreground mb-2">
Small text - Additional information, captions, and secondary content.
</p>
<p className="text-sm text-muted-foreground">Inter Regular / 14px</p>
</div>
<Separator />
<div>
<code className="text-sm bg-muted px-2 py-1 rounded">
const example = "code text";
</code>
<p className="text-sm text-muted-foreground mt-2">
JetBrains Mono Regular / 14px
</p>
</div>
</div>
</Card>
</section>
)
}

View File

@@ -0,0 +1,72 @@
import { Card } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Calendar } from '@phosphor-icons/react'
export function ContentPreviewCardsSection() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Content Preview Cards</h2>
<p className="text-muted-foreground">
Compact cards displaying content with metadata
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card className="p-6 hover:shadow-lg transition-shadow">
<div className="space-y-4">
<div className="flex items-start justify-between gap-4">
<div className="space-y-1">
<h3 className="font-semibold text-lg line-clamp-2">
Building Scalable Design Systems
</h3>
<p className="text-sm text-muted-foreground">
Learn how to create and maintain design systems that grow with your team.
</p>
</div>
</div>
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<div className="flex items-center gap-1">
<Calendar className="h-4 w-4" />
<span>Mar 15, 2024</span>
</div>
<span></span>
<span>5 min read</span>
</div>
<div className="flex gap-2">
<Badge variant="outline">Design</Badge>
<Badge variant="outline">System</Badge>
</div>
</div>
</Card>
<Card className="p-6 hover:shadow-lg transition-shadow">
<div className="space-y-4">
<div className="flex items-start justify-between gap-4">
<div className="space-y-1">
<h3 className="font-semibold text-lg line-clamp-2">
Advanced TypeScript Patterns
</h3>
<p className="text-sm text-muted-foreground">
Explore advanced type system features and practical patterns for production apps.
</p>
</div>
</div>
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<div className="flex items-center gap-1">
<Calendar className="h-4 w-4" />
<span>Mar 12, 2024</span>
</div>
<span></span>
<span>8 min read</span>
</div>
<div className="flex gap-2">
<Badge variant="outline">TypeScript</Badge>
<Badge variant="outline">Tutorial</Badge>
</div>
</div>
</Card>
</div>
</section>
)
}

View File

@@ -0,0 +1,60 @@
import { Card } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Envelope, Lock } from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { moleculesCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
interface FormFieldsSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
}
export function FormFieldsSection({ onSaveSnippet }: FormFieldsSectionProps) {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Form Fields</h2>
<p className="text-muted-foreground">
Input fields with labels and helper text
</p>
</div>
<ComponentShowcase
code={moleculesCodeSnippets.formField}
title="Form Field with Icon and Helper Text"
description="Complete form field with label, icon, and validation message"
category="molecules"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-6 max-w-md">
<div className="space-y-2">
<Label htmlFor="name">Full Name</Label>
<Input id="name" placeholder="John Doe" />
</div>
<div className="space-y-2">
<Label htmlFor="email">Email Address</Label>
<div className="relative">
<Envelope className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input id="email" type="email" placeholder="john@example.com" className="pl-10" />
</div>
<p className="text-sm text-muted-foreground">
We'll never share your email with anyone else.
</p>
</div>
<div className="space-y-2">
<Label htmlFor="password">Password</Label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input id="password" type="password" placeholder="••••••••" className="pl-10" />
</div>
</div>
</div>
</Card>
</ComponentShowcase>
</section>
)
}

View File

@@ -1,24 +1,10 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Badge } from '@/components/ui/badge'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Separator } from '@/components/ui/separator'
import {
MagnifyingGlass,
Heart,
ChatCircle,
Share,
DotsThree,
User,
Envelope,
Lock,
Calendar,
} from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { moleculesCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
import { FormFieldsSection } from './FormFieldsSection'
import { SearchBarsSection } from './SearchBarsSection'
import { UserCardsSection } from './UserCardsSection'
import { SocialActionsSection } from './SocialActionsSection'
import { StatusIndicatorsSection } from './StatusIndicatorsSection'
import { ContentPreviewCardsSection } from './ContentPreviewCardsSection'
interface MoleculesSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
@@ -27,297 +13,12 @@ interface MoleculesSectionProps {
export function MoleculesSection({ onSaveSnippet }: MoleculesSectionProps) {
return (
<div className="space-y-16">
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Form Fields</h2>
<p className="text-muted-foreground">
Input fields with labels and helper text
</p>
</div>
<ComponentShowcase
code={moleculesCodeSnippets.formField}
title="Form Field with Icon and Helper Text"
description="Complete form field with label, icon, and validation message"
category="molecules"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-6 max-w-md">
<div className="space-y-2">
<Label htmlFor="name">Full Name</Label>
<Input id="name" placeholder="John Doe" />
</div>
<div className="space-y-2">
<Label htmlFor="email">Email Address</Label>
<div className="relative">
<Envelope className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input id="email" type="email" placeholder="john@example.com" className="pl-10" />
</div>
<p className="text-sm text-muted-foreground">
We'll never share your email with anyone else.
</p>
</div>
<div className="space-y-2">
<Label htmlFor="password">Password</Label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input id="password" type="password" placeholder="••••••••" className="pl-10" />
</div>
</div>
</div>
</Card>
</ComponentShowcase>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Search Bars</h2>
<p className="text-muted-foreground">
Combined search input with actions
</p>
</div>
<ComponentShowcase
code={moleculesCodeSnippets.searchBarWithButton}
title="Search Bar with Button"
description="Search input combined with action button"
category="molecules"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-6">
<div className="relative max-w-md">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search..." className="pl-10" />
</div>
<Separator />
<div className="flex gap-2 max-w-md">
<div className="relative flex-1">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search..." className="pl-10" />
</div>
<Button>Search</Button>
</div>
<Separator />
<div className="relative max-w-md">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search products, articles, documentation..." className="pl-10 h-12" />
</div>
</div>
</Card>
</ComponentShowcase>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">User Cards</h2>
<p className="text-muted-foreground">
Profile information with avatar and actions
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card className="p-6">
<div className="flex items-start gap-4">
<Avatar className="h-12 w-12">
<AvatarImage src="https://i.pravatar.cc/150?img=1" />
<AvatarFallback>AM</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<h3 className="font-semibold text-lg">Alex Morgan</h3>
<p className="text-sm text-muted-foreground">@alexmorgan</p>
<p className="text-sm mt-2">
Product designer passionate about creating delightful user experiences.
</p>
</div>
<Button size="sm" variant="outline">
Follow
</Button>
</div>
</Card>
<Card className="p-6">
<div className="flex items-center gap-4">
<Avatar className="h-16 w-16">
<AvatarImage src="https://i.pravatar.cc/150?img=2" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<h3 className="font-semibold text-lg">Jordan Davis</h3>
<p className="text-sm text-muted-foreground mb-2">Senior Developer</p>
<div className="flex gap-2">
<Badge variant="secondary">React</Badge>
<Badge variant="secondary">TypeScript</Badge>
</div>
</div>
</div>
</Card>
</div>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Social Actions</h2>
<p className="text-muted-foreground">
Grouped interactive buttons for social features
</p>
</div>
<Card className="p-6">
<div className="space-y-6">
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm">
<Heart className="mr-2" />
Like
</Button>
<Button variant="ghost" size="sm">
<ChatCircle className="mr-2" />
Comment
</Button>
<Button variant="ghost" size="sm">
<Share className="mr-2" />
Share
</Button>
</div>
<Separator />
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<Button variant="outline" size="sm">
<Heart weight="fill" className="text-destructive mr-2" />
<span className="text-foreground">256</span>
</Button>
<Button variant="outline" size="sm">
<ChatCircle className="mr-2" />
<span>42</span>
</Button>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm">
<Share />
</Button>
<Button variant="ghost" size="sm">
<DotsThree weight="bold" />
</Button>
</div>
</div>
</div>
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Status Indicators</h2>
<p className="text-muted-foreground">
Combined elements showing status and information
</p>
</div>
<Card className="p-6">
<div className="space-y-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="h-3 w-3 rounded-full bg-accent animate-pulse" />
<span className="font-medium">System Online</span>
</div>
<Badge>Active</Badge>
</div>
<Separator />
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="h-3 w-3 rounded-full bg-destructive" />
<span className="font-medium">Service Unavailable</span>
</div>
<Badge variant="destructive">Error</Badge>
</div>
<Separator />
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="h-3 w-3 rounded-full bg-muted" />
<span className="font-medium">Maintenance Mode</span>
</div>
<Badge variant="secondary">Scheduled</Badge>
</div>
</div>
</Card>
</section>
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Content Preview Cards</h2>
<p className="text-muted-foreground">
Compact cards displaying content with metadata
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card className="p-6 hover:shadow-lg transition-shadow">
<div className="space-y-4">
<div className="flex items-start justify-between gap-4">
<div className="space-y-1">
<h3 className="font-semibold text-lg line-clamp-2">
Building Scalable Design Systems
</h3>
<p className="text-sm text-muted-foreground">
Learn how to create and maintain design systems that grow with your team.
</p>
</div>
</div>
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<div className="flex items-center gap-1">
<Calendar className="h-4 w-4" />
<span>Mar 15, 2024</span>
</div>
<span></span>
<span>5 min read</span>
</div>
<div className="flex gap-2">
<Badge variant="outline">Design</Badge>
<Badge variant="outline">System</Badge>
</div>
</div>
</Card>
<Card className="p-6 hover:shadow-lg transition-shadow">
<div className="space-y-4">
<div className="flex items-start justify-between gap-4">
<div className="space-y-1">
<h3 className="font-semibold text-lg line-clamp-2">
Advanced TypeScript Patterns
</h3>
<p className="text-sm text-muted-foreground">
Explore advanced type system features and practical patterns for production apps.
</p>
</div>
</div>
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<div className="flex items-center gap-1">
<Calendar className="h-4 w-4" />
<span>Mar 12, 2024</span>
</div>
<span></span>
<span>8 min read</span>
</div>
<div className="flex gap-2">
<Badge variant="outline">TypeScript</Badge>
<Badge variant="outline">Tutorial</Badge>
</div>
</div>
</Card>
</div>
</section>
<FormFieldsSection onSaveSnippet={onSaveSnippet} />
<SearchBarsSection onSaveSnippet={onSaveSnippet} />
<UserCardsSection />
<SocialActionsSection />
<StatusIndicatorsSection />
<ContentPreviewCardsSection />
</div>
)
}

View File

@@ -0,0 +1,59 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Separator } from '@/components/ui/separator'
import { MagnifyingGlass } from '@phosphor-icons/react'
import { ComponentShowcase } from '@/components/demo/ComponentShowcase'
import { moleculesCodeSnippets } from '@/lib/component-code-snippets'
import { Snippet } from '@/lib/types'
interface SearchBarsSectionProps {
onSaveSnippet: (snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>) => void
}
export function SearchBarsSection({ onSaveSnippet }: SearchBarsSectionProps) {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Search Bars</h2>
<p className="text-muted-foreground">
Combined search input with actions
</p>
</div>
<ComponentShowcase
code={moleculesCodeSnippets.searchBarWithButton}
title="Search Bar with Button"
description="Search input combined with action button"
category="molecules"
onSaveSnippet={onSaveSnippet}
>
<Card className="p-6">
<div className="space-y-6">
<div className="relative max-w-md">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search..." className="pl-10" />
</div>
<Separator />
<div className="flex gap-2 max-w-md">
<div className="relative flex-1">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search..." className="pl-10" />
</div>
<Button>Search</Button>
</div>
<Separator />
<div className="relative max-w-md">
<MagnifyingGlass className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground" />
<Input placeholder="Search products, articles, documentation..." className="pl-10 h-12" />
</div>
</div>
</Card>
</ComponentShowcase>
</section>
)
}

View File

@@ -0,0 +1,59 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Separator } from '@/components/ui/separator'
import { Heart, ChatCircle, Share, DotsThree } from '@phosphor-icons/react'
export function SocialActionsSection() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Social Actions</h2>
<p className="text-muted-foreground">
Grouped interactive buttons for social features
</p>
</div>
<Card className="p-6">
<div className="space-y-6">
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm">
<Heart className="mr-2" />
Like
</Button>
<Button variant="ghost" size="sm">
<ChatCircle className="mr-2" />
Comment
</Button>
<Button variant="ghost" size="sm">
<Share className="mr-2" />
Share
</Button>
</div>
<Separator />
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<Button variant="outline" size="sm">
<Heart weight="fill" className="text-destructive mr-2" />
<span className="text-foreground">256</span>
</Button>
<Button variant="outline" size="sm">
<ChatCircle className="mr-2" />
<span>42</span>
</Button>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm">
<Share />
</Button>
<Button variant="ghost" size="sm">
<DotsThree weight="bold" />
</Button>
</div>
</div>
</div>
</Card>
</section>
)
}

View File

@@ -0,0 +1,48 @@
import { Card } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Separator } from '@/components/ui/separator'
export function StatusIndicatorsSection() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">Status Indicators</h2>
<p className="text-muted-foreground">
Combined elements showing status and information
</p>
</div>
<Card className="p-6">
<div className="space-y-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="h-3 w-3 rounded-full bg-accent animate-pulse" />
<span className="font-medium">System Online</span>
</div>
<Badge>Active</Badge>
</div>
<Separator />
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="h-3 w-3 rounded-full bg-destructive" />
<span className="font-medium">Service Unavailable</span>
</div>
<Badge variant="destructive">Error</Badge>
</div>
<Separator />
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="h-3 w-3 rounded-full bg-muted" />
<span className="font-medium">Maintenance Mode</span>
</div>
<Badge variant="secondary">Scheduled</Badge>
</div>
</div>
</Card>
</section>
)
}

View File

@@ -0,0 +1,55 @@
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
export function UserCardsSection() {
return (
<section className="space-y-6">
<div>
<h2 className="text-3xl font-bold mb-2">User Cards</h2>
<p className="text-muted-foreground">
Profile information with avatar and actions
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card className="p-6">
<div className="flex items-start gap-4">
<Avatar className="h-12 w-12">
<AvatarImage src="https://i.pravatar.cc/150?img=1" />
<AvatarFallback>AM</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<h3 className="font-semibold text-lg">Alex Morgan</h3>
<p className="text-sm text-muted-foreground">@alexmorgan</p>
<p className="text-sm mt-2">
Product designer passionate about creating delightful user experiences.
</p>
</div>
<Button size="sm" variant="outline">
Follow
</Button>
</div>
</Card>
<Card className="p-6">
<div className="flex items-center gap-4">
<Avatar className="h-16 w-16">
<AvatarImage src="https://i.pravatar.cc/150?img=2" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<h3 className="font-semibold text-lg">Jordan Davis</h3>
<p className="text-sm text-muted-foreground mb-2">Senior Developer</p>
<div className="flex gap-2">
<Badge variant="secondary">React</Badge>
<Badge variant="secondary">TypeScript</Badge>
</div>
</div>
</div>
</Card>
</div>
</section>
)
}