Files
gh-jnlei-claude-tools-plugi…/skills/frontend-development/EXAMPLES.md
2025-11-30 08:28:13 +08:00

14 KiB

Examples & Case Studies

Real-world examples demonstrating correct and incorrect application of frontend design principles.


Table of Contents

  1. Case Study: Blog Search Bar (Design Consistency)
  2. Example: Component Reuse Decision Matrix
  3. Example: Typography Consistency
  4. Example: Layout Pattern Matching
  5. Anti-Example: Generic AI Slop

Context: Adding a search bar to a blog page in an existing Next.js application.

WRONG APPROACH (Autopilot Mode)

What happened:

User: "Blog page needs a search bar"
Assistant: [Sees SearchBar component exists] → [Pastes component into blog page] → Done

Implementation:

// Blog page
<section className="py-6 px-6">
  <div className="max-w-5xl mx-auto">
    <SearchBar value={searchQuery} onChange={setSearchQuery} />
  </div>
</section>

// SearchBar component (from tools page)
export default function SearchBar({ value, onChange }: SearchBarProps) {
  return (
    <div className="relative max-w-2xl mx-auto">  {/* ← PROBLEM: Centered with narrow container */}
      <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4" />
      <Input value={value} onChange={onChange} className="pl-10" />
    </div>
  );
}

Result:

  • Search bar centered on left-aligned page
  • max-w-2xl container inside max-w-5xl container
  • Visual inconsistency with rest of blog page
  • Breaks design language

Visual outcome:

Blog Page (LEFT-ALIGNED, max-w-5xl)
┌─────────────────────────────────────────────────┐
│ Blog                                            │
│ Real-world guides...                            │
│                                                 │
│         ┌──────────────────┐                    │  ← Centered, narrow
│         │ [Search bar]     │                    │
│         └──────────────────┘                    │
│                                                 │
│ [All Posts - left-aligned cards]                │
└─────────────────────────────────────────────────┘

RIGHT APPROACH (Design-Thinking Mode)

Process:

Phase 1: Design Language Analysis

## Design Language Analysis

### Files Scanned
- src/app/blog/page.tsx (blog landing page)
- src/app/page.tsx (tools page for comparison)
- src/components/SearchBar.tsx
- src/components/CategoryFilter.tsx
- src/app/globals.css

### Layout Patterns
- Blog page: LEFT-ALIGNED layout throughout
- All blog sections use max-w-5xl container
- Category filter buttons are left-aligned
- Blog cards grid is left-aligned

- Tools page (for comparison): CENTERED layout
- Tools hero uses max-w-3xl centered
- Tools SearchBar uses max-w-2xl centered

**Key insight:** Blog page has CONSISTENT left-aligned pattern with max-w-5xl containers.

### Component Patterns
- SearchBar component exists with built-in max-w-2xl mx-auto (centered)
- This pattern works for tools page but NOT for blog page
- Category filter on blog page is left-aligned (not centered)

Phase 2: Design Decisions

## Design Decisions

### Pattern Application
Blog page requires LEFT-ALIGNED full-width search within max-w-5xl container.
Cannot use SearchBar's centered max-w-2xl pattern - would break consistency.

### Component Approach
Options:
1. Add width/alignment variant props to SearchBar component
2. Create inline search input specifically for blog page
3. Create new FullWidthSearchBar component

Decision: Option 1 - Extend SearchBar with optional props
- Maintains component reuse
- Allows flexibility for different layout contexts
- Avoids code duplication

### Consistency Requirements
MUST maintain:
- max-w-5xl container (matches rest of blog page)
- Full width within container (left-aligned, not centered)
- Same input styling (h-11, pl-10, bg-card, search icon)
- Same search functionality

CAN vary:
- Container width and alignment (adapts to page context)

Phase 3: Implementation

// Enhanced SearchBar component with layout props
interface SearchBarProps {
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  fullWidth?: boolean;  // New prop
}

export default function SearchBar({
  value,
  onChange,
  placeholder = "Search...",
  fullWidth = false  // Default to centered (backward compatible)
}: SearchBarProps) {
  return (
    <div className={`relative ${fullWidth ? 'w-full' : 'max-w-2xl mx-auto'}`}>
      <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4" />
      <Input
        type="text"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder={placeholder}
        className="w-full pl-10 pr-4 h-11 bg-card"
      />
    </div>
  );
}

// Blog page usage
<section className="py-6 px-6">
  <div className="max-w-5xl mx-auto">
    <SearchBar
      value={searchQuery}
      onChange={setSearchQuery}
      placeholder="Search posts by title, author, or tags..."
      fullWidth={true}  // Matches blog's left-aligned pattern
    />
  </div>
</section>

// Tools page usage (unchanged, backward compatible)
<section className="py-6 px-6">
  <div className="max-w-5xl mx-auto">
    <SearchBar
      value={searchQuery}
      onChange={setSearchQuery}
      // No fullWidth prop = defaults to centered
    />
  </div>
</section>

Result:

  • Search bar matches blog page's left-aligned layout
  • Consistent max-w-5xl container width
  • Component reuse with flexibility
  • Backward compatible (tools page unchanged)
  • Design language preserved

Visual outcome:

Blog Page (LEFT-ALIGNED, max-w-5xl)
┌─────────────────────────────────────────────────┐
│ Blog                                            │
│ Real-world guides...                            │
│                                                 │
│ ┌─────────────────────────────────────────────┐ │  ← Full width, left-aligned
│ │ [Search bar]                                │ │
│ └─────────────────────────────────────────────┘ │
│                                                 │
│ [All Posts - left-aligned cards]                │
└─────────────────────────────────────────────────┘

Key Lessons

  1. Don't skip analysis - The checklist exists for a reason
  2. Scan multiple files - Understanding context requires comprehensive analysis
  3. Document patterns - Explicit output makes thinking visible
  4. Consider reuse vs creation - Adapt existing components when possible
  5. Match the context - Blog's left-aligned pattern ≠ Tools' centered pattern

Example: Component Reuse Decision

Scenario: Need a card component for a new dashboard section.

Analysis

Existing components found:

  1. ToolCard - Border, rounded corners, hover effect, vertical layout
  2. BlogPostCard - Border, rounded corners, gradient header, vertical layout
  3. FeatureCard - No border, shadow effect, horizontal layout

Decision Matrix

Option Pros Cons Decision
Reuse ToolCard Matches border/rounded style Vertical layout might not fit Layout mismatch
Reuse FeatureCard Horizontal layout fits No border/rounded style Style mismatch
Create DashboardCard Perfect fit for needs New component = maintenance ⚠️ Only if truly different
Extend ToolCard with layout prop Reuses existing + flexible Small refactor needed Best choice

Implementation

// Extended ToolCard with layout variant
interface ToolCardProps {
  tool: Tool;
  layout?: 'vertical' | 'horizontal';
}

export default function ToolCard({ tool, layout = 'vertical' }: ToolCardProps) {
  const isHorizontal = layout === 'horizontal';

  return (
    <div className={`border rounded-lg p-4 hover:border-foreground/20 transition-all
      ${isHorizontal ? 'flex items-center gap-4' : 'flex flex-col'}`}
    >
      {/* Content adapts to layout */}
    </div>
  );
}

Example: Typography Consistency

Scenario: Adding a new "About" page to existing site.

Analysis Output

## Typography Patterns (from existing pages)

### Heading Hierarchy
- H1: text-3xl md:text-4xl, font-semibold, tracking-tight
- H2: text-xl md:text-2xl, font-semibold
- H3: text-lg, font-medium

### Body Text
- Default: text-base, leading-relaxed
- Small: text-sm
- Meta/timestamps: text-xs, text-muted-foreground

### Font Family
- Primary: Inter with fallbacks
- No display font used
- No monospace needed (no code samples)

Correct Implementation

// About page - matches existing hierarchy
<div className="max-w-3xl mx-auto">
  <h1 className="text-3xl md:text-4xl font-semibold tracking-tight mb-4">
    About Us
  </h1>

  <p className="text-base leading-relaxed mb-6">
    Our story begins...
  </p>

  <h2 className="text-xl md:text-2xl font-semibold mb-3">
    Our Mission
  </h2>

  <p className="text-base leading-relaxed">
    We believe in...
  </p>
</div>

Incorrect Implementation

// DON'T: Different sizes, weights, tracking
<div className="max-w-3xl mx-auto">
  <h1 className="text-5xl font-bold tracking-wide mb-6">  {/* ← Too large, too bold */}
    About Us
  </h1>

  <p className="text-lg leading-normal mb-8">  {/* ← Larger than existing pages */}
    Our story begins...
  </p>

  <h2 className="text-2xl font-bold mb-4">  {/* ← font-bold instead of font-semibold */}
    Our Mission
  </h2>
</div>

Example: Layout Pattern Matching

Scenario: Adding a "Pricing" page.

Pattern Analysis

Existing page patterns:

  • Home: Centered hero (max-w-3xl) → Wide content (max-w-5xl)
  • Blog: All sections left-aligned (max-w-5xl)
  • Tools: Centered hero (max-w-3xl) → Wide grid (max-w-5xl)

Decision: Pricing is marketing content, matches "Home" pattern.

Correct Implementation

// Pricing page - matches Home pattern
export default function PricingPage() {
  return (
    <main>
      {/* Hero: Centered, narrow */}
      <section className="py-12 px-6">
        <div className="max-w-3xl mx-auto text-center">
          <h1 className="text-3xl md:text-4xl font-semibold">
            Simple, Transparent Pricing
          </h1>
        </div>
      </section>

      {/* Plans: Wide, centered grid */}
      <section className="py-8 px-6">
        <div className="max-w-5xl mx-auto">
          <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
            {/* Pricing cards */}
          </div>
        </div>
      </section>
    </main>
  );
}

Anti-Example: Generic AI Slop

The Problem

Request: "Create a landing page for a SaaS product"

Generic AI Output:

// Predictable, seen-it-before structure
<main className="bg-white">
  {/* Purple gradient hero */}
  <section className="bg-gradient-to-r from-purple-600 to-blue-500 text-white py-20">
    <div className="max-w-4xl mx-auto text-center">
      <h1 className="text-5xl font-bold mb-6">
        Revolutionize Your Workflow
      </h1>
      <p className="text-xl mb-8">
        The all-in-one platform for modern teams
      </p>
      <button className="bg-white text-purple-600 px-8 py-3 rounded-lg">
        Get Started
      </button>
    </div>
  </section>

  {/* Three feature cards */}
  <section className="py-20">
    <div className="max-w-6xl mx-auto grid grid-cols-3 gap-8">
      <Card icon="⚡" title="Fast" description="Lightning fast performance" />
      <Card icon="🔒" title="Secure" description="Bank-level security" />
      <Card icon="📈" title="Scalable" description="Grows with you" />
    </div>
  </section>

  {/* Testimonials */}
  {/* CTA */}
</main>

Font: Inter (of course) Colors: Purple gradient (of course) Layout: Centered everything (of course)

Problem: Indistinguishable from 1000 other AI-generated SaaS pages.

Better Approach

Apply design thinking:

  • What makes THIS product different?
  • Who is the audience? (Technical? Creative? Enterprise?)
  • What feeling should the design evoke?
  • What's ONE memorable element?

Example re-design (Brutalist/Technical Direction):

// Bold, distinctive approach
<main className="bg-black text-green-400 font-mono">
  {/* Terminal-style hero */}
  <section className="min-h-screen p-6 flex items-center">
    <div className="max-w-4xl">
      <pre className="text-sm mb-4">$ initialize_revolution.sh</pre>
      <h1 className="text-6xl font-bold mb-4 glitch-effect">
        SYSTEM<br/>
        OVERRIDE
      </h1>
      <p className="text-lg text-green-300 mb-8 max-w-xl">
        For developers who don't compromise. Raw power. Zero abstraction.
      </p>
      <div className="flex gap-4">
        <button className="border-2 border-green-400 px-6 py-2 hover:bg-green-400 hover:text-black transition-colors">
          &gt; ssh access@deploy
        </button>
      </div>
    </div>
  </section>

  {/* Asymmetric feature layout */}
  <section className="p-6">
    <div className="max-w-7xl mx-auto grid grid-cols-12 gap-4">
      <div className="col-span-8 border-2 border-green-400 p-8">
        {/* Main feature */}
      </div>
      <div className="col-span-4 border-2 border-green-400 p-4">
        {/* Stats ticker */}
      </div>
    </div>
  </section>
</main>

Distinctive elements:

  • Terminal/command-line aesthetic
  • Monospace typography
  • High-contrast green-on-black
  • Asymmetric grid layout
  • Technical/hacker vibe
  • Memorable and specific to audience

More Examples

For additional examples and techniques, see: