# 05 · Komponent kontraktı

> Mənbə: `posflame.com/src/components/base` (28 komponent) + `hub.ubs.az/ui-ux/components`.
> Bu siyahı **minimumdur** — layihə başlayanda bunlar yazılır, sonra səhifələr qurulur.
> Audit tapıntısı P3: `base/` yalnız `Logo.tsx`-dən ibarət olan layihələrdə eyni düymənin
> üç fərqli hündürlüyü yarandı.

---

## 1. Qovluq ayrımı 🔴

```
src/components/
├─ base/      ← domen BİLMİR. Heç bir layihə tipi import etmir.
│              Başqa layihəyə dəyişiksiz köçürülə bilər.
└─ feature/   ← domen bilir (AuthGuard, OrgSelector, BranchFilter, DashboardLayout)
```

Yoxlama: `base/` altında `import { Order } from '@/types'` görünürsə — komponent səhv qovluqdadır.

---

## 2. Minimum base komponentlər (12) — bunlarsız layihə başlamır

| Komponent | Variantlar | Məcburi davranış |
|---|---|---|
| `Button` | primary · secondary · ghost · danger; sm/md/lg; loading; icon | `whitespace-nowrap`, loading-də `aria-busy` + disabled |
| `Input` | normal · error · disabled | `aria-invalid`, `aria-describedby` xəta ilə bağlı |
| `Select` | — | native `<select>` üzərində, klaviatura işləyir |
| `Textarea` | — | `resize: vertical`, simvol limiti göstərilir |
| `Badge` | neutral · primary · success · warning · danger · info; dot | **həmişə mətn daşıyır** |
| `Card` | — | `--surface` + `--border`, kölgəsiz |
| `Modal` | — | backdrop klik **bağlamır**, fokus tələsi var |
| `ConfirmDialog` | default · danger | nəticə rəqəmlə, dağıdıcı düymə sağda |
| `DataTable` | sıralanan · seçilən | boş/xəta/yüklənir vəziyyətlərini özü idarə edir |
| `EmptyState` | — | ikon + başlıq + izah + **hərəkət düyməsi** |
| `ErrorState` | — | səbəb + sorğu ID + **RetryButton** |
| `Skeleton` | text · row · card | real hündürlüyü təkrarlayır |

---

## 3. Genişlənmiş dəst (layihə tələb edərsə)

`PageHeader` · `BreadcrumbHeader` · `SearchInput` · `FilterTabs` · `RowActions` · `FormModal` ·
`FormActions` · `FormError` · `Toggle` · `ToggleField` · `StatusToggle` · `SummaryCard` (stat) ·
`Notice` · `Spinner` · `PageLoader` · `IconButton` · `BackLink` · `Avatar` · `Tooltip` · `Toast`

---

## 4. Feature komponentləri

| Komponent | Məsuliyyəti |
|---|---|
| `AppShell` / `DashboardLayout` | Sidebar + TopBar + (CommandBar) + scroll edən `main` |
| `Sidebar` | qruplaşdırılmış naviqasiya, yığılma, mobil overlay |
| `TopBar` | başlıq, axtarış, tema, dil, bildiriş, istifadəçi menyusu |
| `CommandBar` | səhifə üzrə əməliyyat düymələri + `Ctrl K` |
| `CommandPalette` | qlobal axtarış və əmr |
| `AuthGuard` | rol/icazə yoxlaması, yönləndirmə |
| `NotificationsMenu` | oxunmuş/oxunmamış, boş hal |

---

## 5. Prop müqaviləsi

Hər base komponent bu üç qaydaya tabedir:

1. **Semantik prop, vizual prop yox.**
   ✅ `variant="danger"` ❌ `color="red"`
2. **Native atributlar ötürülür.**
   `...rest` həmişə kök elementə düşür — `aria-*`, `data-*`, `id` işləməlidir.
3. **`className` birləşdirilir, əvəz olunmur.**
   Daxili siniflər saxlanılır, kənardan gələn əlavə olunur.

```tsx
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
  variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  loading?: boolean;
  icon?: React.ReactNode;
};
```

Qadağan: `style` prop-u ilə rəng ötürmək, komponent daxilində `#hex`, `!important`.

---

## 6. Vəziyyət kontraktı

Məlumat çəkən hər feature komponenti eyni üç prop-u qəbul edir:

```tsx
{ data, isLoading, error, onRetry }
```

və dörd vəziyyəti **özü** göstərir (`04-ux-patterns.md` §1). Səhifə bu məntiqi təkrar yazmır.

---

## 7. Əlçatanlıq kontraktı

| Komponent | Tələb |
|---|---|
| `IconButton` | `aria-label` **məcburi** — yoxdursa build-də xəta |
| `Modal` | `role="dialog"`, `aria-modal`, fokus tələsi, açılanda ilk fokuslanan element |
| `DataTable` | `<caption>` və ya `aria-label`, `<th scope="col">` |
| `Badge` | rəngdən əlavə mətn |
| `Input` | `<label for>` və ya `aria-label`; placeholder etiket əvəzi deyil |
| `Toast` | `role="status"` (uğur) / `role="alert"` (xəta) |
| `Tabs` | `role="tablist"`, `aria-selected`, ox düymələri ilə naviqasiya |

---

## 8. Yeni komponent yaratmadan əvvəl

```
1. Bu siyahıda var? → istifadə et
2. Mövcud komponentin variantı ilə həll olunur? → variant əlavə et
3. Rəf kitabxanasında hazır blok var? → Skill: section-library
4. Yalnız bundan sonra yeni komponent
```

Yeni base komponent yaradıldıqda: variantları, əlçatanlıq tələbini və vəziyyətlərini
`UI_UX_SPECIFICATION.md` §4-ə əlavə et — sənədsiz komponent gələn ay yenidən yazılır.
