# ADR-012: UI Component Library Strategy

**Status:** ✅ Accepted
**Date:** 2026-02-24
**Decision Makers:** Frontend Team, UX Designer
**Related Documents:** [Frontend Guidelines](../05-Engineering-Guidelines/05-03-frontend-guidelines.md), [ADR-005: Technology Stack](./ADR-005-technology-stack.md)
**Version Applicability:** v1.8.0+
**Next Review:** 2026-08-01 (6-month cycle)

---

## Gap Analysis & Requirement Linking

### ปิด Gap จาก Requirements:

| Gap/Requirement | แหล่งที่มา | วิธีการแก้ไขใน ADR นี้ |
|----------------|-------------|-------------------|
| **Design Consistency** | [Product Vision](../00-overview/00-03-product-vision.md) - UI/UX Requirements | Shadcn/UI for consistent design system |
| **Accessibility Support** | [Acceptance Criteria](../01-Requirements/01-05-acceptance-criteria.md) - AC-UI-003 | Radix UI primitives for WCAG 2.1 AA |
| **Performance Optimization** | [Frontend Guidelines](../05-Engineering-Guidelines/05-03-frontend-guidelines.md) - Performance | Tree-shakeable components, minimal bundle |
| **Customization Flexibility** | [Engineering Guidelines](../05-Engineering-Guidelines/05-01-fullstack-js-guidelines.md) - DX | Full ownership of component code |
| **Bundle Size Constraints** | [Architecture](../02-architecture/02-02-software-architecture.md) - Performance | Copy-only-what-you-use approach |

### แก้ไขความขัดแย้ง:

- **Conflict:** Library vs. Custom (MUI/Ant Design vs. Shadcn/UI)
- **Resolution:** Chose Shadcn/UI for full control and minimal bundle
- **Trade-off:** Manual updates vs. Complete customization freedom

---

## Impact Analysis

### Affected Components (ส่วนประกอบที่ได้รับผลกระทบ):

| Component | ผลกระทบ | ความสำคัญ |
|-----------|----------|-----------|
| **UI Components** | All UI components use Shadcn/UI | 🔴 Critical |
| **Tailwind Config** | CSS variables and theming | 🔴 Critical |
| **Component Library** | Custom component compositions | 🔴 Critical |
| **Form Components** | Integration with React Hook Form | 🟡 Important |
| **Layout Components** | Page layouts and navigation | 🟡 Important |
| **Theme System** | Dark/light mode support | 🟡 Important |
| **Component Testing** | Unit tests for custom components | 🟡 Important |
| **Documentation** | Component usage guidelines | 🟢 Guidelines |
| **Update Process** | Manual component update workflow | 🟢 Guidelines |

### Required Changes (การเปลี่ยนแปลงที่ต้องดำเนินการ):

#### Frontend (Next.js)
- [x] Initialize Shadcn/UI project
- [x] Add core components (Button, Input, Card, etc.)
- [x] Setup Tailwind CSS with CSS variables
- [x] Create custom component compositions
- [x] Implement theme switching
- [x] Update all pages to use new components
- [x] Add component testing

#### Design System
- [x] Define design tokens and colors
- [x] Create component usage guidelines
- [x] Document customization patterns
- [x] Setup component update workflow

---

## Context and Problem Statement

ต้องการ UI Component Library สำหรับสร้าง User Interface ที่สวยงาม สม่ำเสมอ และ Accessible

### ปัญหาที่ต้องแก้:

1. **Component Library:** ใช้ Library สำเร็จรูป หรือสร้างเอง
2. **Customization:** ปรับแต่งได้ง่ายเพียงใด
3. **Accessibility:** รองรับ ARIA และ Keyboard navigation
4. **Bundle Size:** ขนาดไฟล์ไม่ใหญ่เกินไป
5. **Developer Experience:** ใช้งานง่าย Documentation ครบ

---

## Decision Drivers

- 🎨 **Design Consistency:** UI สม่ำเสมอทั้งระบบ
- ♿ **Accessibility:** รองรับ WCAG 2.1 AA
- 🎯 **Customization:** ปรับแต่งได้ตามต้องการ
- 📦 **Bundle Size:** เล็กและ Tree-shakeable
- ⚡ **Performance:** Render เร็ว
- 🛠️ **DX:** Developer Experience ดี

---

## Considered Options

### Option 1: Material-UI (MUI)

**Pros:**

- ✅ Component ครบชุด
- ✅ Documentation ดี
- ✅ Community ใหญ่
- ✅ Built-in theming

**Cons:**

- ❌ Bundle size ใหญ่
- ❌ Design opinionated (Material Design)
- ❌ Customization ยาก
- ❌ Performance overhead

### Option 2: Ant Design

**Pros:**

- ✅ Component ครบ (เน้น Enterprise)
- ✅ i18n support ดี
- ✅ Form components ครบ

**Cons:**

- ❌ Bundle size ใหญ่มาก
- ❌ Chinese-centric design
- ❌ Customization จำกัด
- ❌ TypeScript support ไม่ดีเท่าไร

### Option 3: Chakra UI

**Pros:**

- ✅ Accessibility ดี
- ✅ Customization ง่าย
- ✅ TypeScript first
- ✅ Dark mode built-in

**Cons:**

- ❌ Bundle size ค่อนข้างใหญ่
- ❌ CSS-in-JS overhead
- ❌ Performance issues with many components

### Option 4: Headless UI + Tailwind CSS

**Pros:**

- ✅ Full control over styling
- ✅ Lightweight
- ✅ Accessibility ดี
- ✅ No styling overhead

**Cons:**

- ❌ ต้องเขียน styles เอง
- ❌ Component library น้อย
- ❌ ใช้เวลาพัฒนานาน

### Option 5: Shadcn/UI + Tailwind CSS

**วิธีการ:** Copy components ที่ต้องการไปยัง Project

**Pros:**

- ✅ **Full ownership:** Components เป็นของเรา ไม่ใช่ dependency
- ✅ **Highly customizable:** แก้ไขได้เต็มที่
- ✅ **Accessibility:** ใช้ Radix UI Primitives
- ✅ **Bundle size:** เฉพาะที่ใช้เท่านั้น
- ✅ **Tailwind CSS:** Utility-first ง่ายต่อการ maintain
- ✅ **TypeScript:** Type-safe
- ✅ **Beautiful defaults:** Design ดูทันสมัย

**Cons:**

- ❌ ต้อง Copy components เอง
- ❌ Update ต้องทำด้วยตัวเอง
- ❌ ไม่มี `npm install` แบบ Library

---

## Decision Outcome

**Chosen Option:** **Option 5 - Shadcn/UI + Tailwind CSS**

### Rationale

1. **Ownership:** เป็นเจ้าของ Code 100% ปรับแต่งได้อย่างเต็มที่
2. **Bundle Size:** เล็กที่สุด (เฉพาะที่ใช้)
3. **Accessibility:** ใช้ Radix UI primitives ที่ทดสอบแล้ว
4. **Customization:** แก้ไขได้ตามต้องการ ไม่ติด Framework
5. **Tailwind CSS:** ทีมคุ้นเคยและใช้อยู่แล้ว
6. **Modern Design:** ดูสวยงามและทันสมัย

---

## Implementation Details

### 1. Setup Shadcn/UI

```bash
# Initialize shadcn/ui
npx shadcn-ui@latest init

# Select options:
# - TypeScript: Yes
# - Style: Default
# - Base color: Slate
# - CSS variables: Yes
```

```typescript
// File: components.json
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.js",
    "css": "app/globals.css",
    "baseColor": "slate",
    "cssVariables": true
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  }
}
```

### 2. Add Components

```bash
# Add specific components
npx shadcn-ui@latest add button
npx shadcn-ui@latest add input
npx shadcn-ui@latest add card
npx shadcn-ui@latest add dialog
npx shadcn-ui@latest add dropdown-menu
npx shadcn-ui@latest add table

# Components will be copied to components/ui/
```

### 3. Component Usage

```typescript
// File: app/correspondences/page.tsx
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { Input } from '@/components/ui/input';

export default function CorrespondencesPage() {
  return (
    <div className="space-y-4">
      <div className="flex justify-between items-center">
        <Input placeholder="Search..." className="max-w-sm" />
        <Button>Create New</Button>
      </div>

      <Card className="p-6">
        <h2 className="text-xl font-bold">Correspondences</h2>
        {/* Content */}
      </Card>
    </div>
  );
}
```

### 4. Customize Components

```typescript
// File: components/ui/button.tsx
// สามารถแก้ไขได้เต็มที่เพราะเป็น Code ของเรา

import * as React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';

const buttonVariants = cva(
  'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',
  {
    variants: {
      variant: {
        default: 'bg-primary text-primary-foreground hover:bg-primary/90',
        destructive:
          'bg-destructive text-destructive-foreground hover:bg-destructive/90',
        outline: 'border border-input bg-background hover:bg-accent',
        ghost: 'hover:bg-accent hover:text-accent-foreground',
        link: 'text-primary underline-offset-4 hover:underline',
        // Add custom variant
        success: 'bg-green-600 text-white hover:bg-green-700',
      },
      size: {
        default: 'h-10 px-4 py-2',
        sm: 'h-9 rounded-md px-3',
        lg: 'h-11 rounded-md px-8',
        icon: 'h-10 w-10',
      },
    },
    defaultVariants: {
      variant: 'default',
      size: 'default',
    },
  }
);

export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, asChild = false, ...props }, ref) => {
    const Comp = asChild ? Slot : 'button';
    return (
      <Comp
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    );
  }
);
Button.displayName = 'Button';

export { Button, buttonVariants };
```

### 5. Theming with CSS Variables

```css
/* File: app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --primary: 221.2 83.2% 53.3%;
    --primary-foreground: 210 40% 98%;
    /* ... more colors */
  }

  .dark {
    --background: 222.2 84% 4.9%;
    --foreground: 210 40% 98%;
    /* ... dark mode colors */
  }
}
```

### 6. Component Composition

```typescript
// File: components/correspondence/card.tsx
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';

export function CorrespondenceCard({ correspondence }) {
  return (
    <Card>
      <CardHeader>
        <div className="flex justify-between items-start">
          <CardTitle>{correspondence.subject}</CardTitle>
          <Badge
            variant={
              correspondence.status === 'APPROVED' ? 'success' : 'default'
            }
          >
            {correspondence.status}
          </Badge>
        </div>
      </CardHeader>
      <CardContent>
        <p className="text-sm text-muted-foreground">
          {correspondence.description}
        </p>
        <div className="mt-4 flex gap-2">
          <Button variant="outline" size="sm">
            View
          </Button>
          <Button size="sm">Edit</Button>
        </div>
      </CardContent>
    </Card>
  );
}
```

---

## Component Inventory

### Core Components (มีอยู่ใน Shadcn/UI)

**Forms:**

- Button
- Input
- Textarea
- Select
- Checkbox
- Radio Group
- Switch
- Slider
- Label

**Data Display:**

- Table
- Card
- Badge
- Avatar
- Separator

**Feedback:**

- Alert
- Dialog
- Toast
- Progress
- Skeleton

**Navigation:**

- Tabs
- Dropdown Menu
- Command
- Popover
- Sheet (Drawer)

**Layout:**

- Accordion
- Collapsible
- Aspect Ratio
- Scroll Area

---

## Consequences

### Positive Consequences

1. ✅ **Full Control:** แก้ไข Components ได้เต็มที่
2. ✅ **Smaller Bundle:** เฉพาะที่ใช้เท่านั้น
3. ✅ **No Lock-in:** ไม่ติด Dependency
4. ✅ **Accessibility:** ใช้ Radix UI (tested)
5. ✅ **Beautiful Design:** ดูทันสมัยและสวยงาม
6. ✅ **TypeScript:** Type-safe

### Negative Consequences

1. ❌ **Manual Updates:** ต้อง Update components ด้วยตัวเอง
2. ❌ **Initial Setup:** ต้อง Copy components ที่ต้องการ
3. ❌ **No Official Support:** ไม่มี Package maintainer

### Mitigation Strategies

- **Documentation:** เขียนเอกสารว่า Components ไหนมา version ไหน
- **Changelog:** Track changes ที่ทำกับ Components
- **Testing:** เขียน Tests สำหรับ Custom components
- **Review Updates:** Check Shadcn/UI releases เป็นระยะ (แนะนำให้ใช้ `npx shadcn-ui@latest diff` ตรวจสอบความแตกต่างทุกๆ X เดือนเพื่อลดภาระการอัปเดตแบบ manual)

---

## ADR Review Cycle

### Core Principle Review Schedule
- **Review Frequency:** ทุก 6 เดือน (กุมภาพันธ์ และ สิงหาคม)
- **Trigger Events:**
  - Major version upgrade (v1.9.0, v2.0.0)
  - Shadcn/UI major updates
  - New component requirements
  - Accessibility standard updates

### Review Checklist
- [ ] Component library still meets design requirements
- [ ] Bundle size within acceptable limits
- [ ] Accessibility compliance maintained
- [ ] Custom components properly documented
- [ ] Cross-document dependencies still valid
- [ ] New component libraries to consider
- [ ] Component update workflow effective

### Version Dependency Matrix

| System Version | ADR Version | Required Changes | Status |
|----------------|-------------|------------------|---------|
| v1.8.0 - v1.8.5 | ADR-012 v1.0 | Base Shadcn/UI implementation | ✅ Complete |
| v1.9.0+ | ADR-012 v1.1 | Review component updates and performance | 📋 Planned |
| v2.0.0+ | ADR-012 v2.0 | Consider new UI patterns or libraries | 📋 Future |

---

## Related ADRs

- [ADR-005: Technology Stack](./ADR-005-technology-stack.md) - เลือกใช้ Tailwind CSS
- [ADR-011: Next.js App Router](./ADR-011-nextjs-app-router.md)

---

## References

- [Shadcn/UI Documentation](https://ui.shadcn.com/)
- [Radix UI Primitives](https://www.radix-ui.com/)
- [Tailwind CSS](https://tailwindcss.com/)

---

**Document Version:** v1.0
**Last Updated:** 2026-02-24
**Next Review:** 2026-08-01 (6-month cycle)
**Version Applicability:** LCBP3 v1.8.0+

---

## Change History

| Version | Date | Changes | Author |
|---------|------|---------|---------|
| v1.0 | 2026-02-24 | Initial ADR creation with UI component strategy | Frontend Team |
| v1.1 | 2026-04-04 | Added structured templates: Impact Analysis, Gap Linking, Version Dependency, Review Cycle | System Architect |
