@turk.net/mui 3.0.9 → 3.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/rules/design-compliance.md +8 -5
- package/.opencode/skills/onehub-design-verification/SKILL.md +4 -4
- package/.opencode/skills/turknet-onehub-component-usage/SKILL.md +24 -14
- package/COMPONENT_MAP.md +576 -47
- package/DESIGN_RULES.md +43 -19
- package/DESIGN_SOURCES.md +22 -0
- package/DESIGN_TOKENS_MAP.md +14 -5
- package/ESLINT_DESIGN_RULES.md +5 -3
- package/LLM_EXAMPLES.md +5 -5
- package/LLM_GUIDELINES.md +7 -7
- package/PAGE_PATTERNS.md +1 -1
- package/SKILL_SETUP.md +14 -14
- package/dist/index.js +75 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +76 -5
- package/dist/index.mjs.map +1 -1
- package/dist/theme/components/Tabs.d.mts +3 -0
- package/dist/theme/components/Tabs.d.ts +3 -0
- package/dist/theme/index.js +75 -4
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +76 -5
- package/dist/theme/index.mjs.map +1 -1
- package/package.json +1 -1
package/COMPONENT_MAP.md
CHANGED
|
@@ -24,17 +24,20 @@
|
|
|
24
24
|
| B1 | Primary / Filled Blue | `contained` | `medium` | `primary` | Blue bg (`--brand-background-1-rest`), white text, `borderRadius: 8px`, `height: 32px` |
|
|
25
25
|
| B2 | Primary / Filled Large | `contained` | `large` | `primary` | Same as B1 but taller |
|
|
26
26
|
| B3 | Primary / Filled Small | `contained` | `small` | `primary` | Same as B1 but smaller |
|
|
27
|
-
| B4 |
|
|
28
|
-
| B5 |
|
|
29
|
-
| B6 | Secondary / Outlined
|
|
30
|
-
| B7 |
|
|
31
|
-
| B8 |
|
|
32
|
-
| B9 |
|
|
33
|
-
| B10 |
|
|
34
|
-
| B11 |
|
|
35
|
-
| B12 |
|
|
36
|
-
| B13 |
|
|
37
|
-
| B14 |
|
|
27
|
+
| B4 | Primary / Filled Extra-Small | `contained` | `extra-small` | `primary` | Compact button, used in ButtonGroup pagination selectors |
|
|
28
|
+
| B5 | Primary / Filled Extra-Large | `contained` | `extra-large` | `primary` | Tallest variant |
|
|
29
|
+
| B6 | Secondary / Outlined | `outlined` | `medium` | `secondary` | Gray border (`--neutral-stroke-1-rest`), transparent bg, dark text |
|
|
30
|
+
| B7 | Secondary / Outlined Large | `outlined` | `large` | `secondary` | Same as B6 but taller |
|
|
31
|
+
| B8 | Secondary / Outlined Small | `outlined` | `small` | `secondary` | Same as B6 but smaller |
|
|
32
|
+
| B9 | Secondary / Outlined Extra-Small | `outlined` | `extra-small` | `secondary` | Compact outlined, ButtonGroup pagination |
|
|
33
|
+
| B10 | Text / Ghost | `text` | `medium` | `primary` | No bg, no border, blue text |
|
|
34
|
+
| B11 | Text / Ghost Small | `text` | `small` | `primary` | Same as B10 but smaller |
|
|
35
|
+
| B12 | Error / Danger | `contained` | `medium` | `error` | Red bg, white text |
|
|
36
|
+
| B13 | Error / Outlined | `outlined` | `medium` | `error` | Red border, transparent bg, red text |
|
|
37
|
+
| B14 | Icon Only (transparent) | `text` | `medium` | `primary` | No padding, transparent bg, `--neutral-background-subtle-rest` |
|
|
38
|
+
| B15 | Icon Only (gray bg) | `text` | `medium` | `secondary` | Gray bg (`--neutral-background-2-rest`), border |
|
|
39
|
+
| B16 | Filter Button (gray) | `text` | `medium` | `secondary` | Gray bg (`--neutral-background-2-rest`), `neutral-stroke-1` border, icon+text |
|
|
40
|
+
| B17 | Filter Button (clear) | `text` | `medium` | `primary` | Transparent bg, delete icon, no text or "Temizle" |
|
|
38
41
|
|
|
39
42
|
### Button State Tokens
|
|
40
43
|
|
|
@@ -67,14 +70,33 @@
|
|
|
67
70
|
|
|
68
71
|
**MUI Component:** `TextField` from `@mui/material`
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
|
73
|
-
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
|
|
|
73
|
+
**Valid variants:** `outlined` (standart), `filled` (login formları, özel sayfalar)
|
|
74
|
+
|
|
75
|
+
| # | Figma Pattern | Color | Size | Variant | Key Visual Traits |
|
|
76
|
+
|---|--------------|-------|------|---------|-------------------|
|
|
77
|
+
| T1 | Default Input | `neutral` | `medium` | `outlined` | Gray border, white bg |
|
|
78
|
+
| T2 | Brand Input | `brand` | `medium` | `outlined` | Blue border/focus |
|
|
79
|
+
| T3 | Error Input | `danger` | `medium` | `outlined` | Red border, error text |
|
|
80
|
+
| T4 | Large Input | `neutral` | `large` | `outlined` | Taller input field |
|
|
81
|
+
| T5 | Disabled Input | `neutral` | `medium` | `outlined` | Gray bg, disabled border |
|
|
82
|
+
| T6 | Read-only Input | `neutral` | `medium` | `outlined` | No border, subtle bg |
|
|
83
|
+
| T7 | Filled Login Input | `neutral` | `medium` | `filled` | Gray fill bg, no border, used in login/authentication forms |
|
|
84
|
+
|
|
85
|
+
### TextField Variant Guidelines
|
|
86
|
+
|
|
87
|
+
- `variant="outlined"` → Varsayılan, form ve veri giriş sayfalarında kullanılır
|
|
88
|
+
- `variant="filled"` → Login, parola, kimlik doğrulama gibi özel sayfalarda kullanılır
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// ✅ CORRECT — Standart veri formu
|
|
92
|
+
<TextField label="E-posta" variant="outlined" color="neutral" size="medium" fullWidth />
|
|
93
|
+
|
|
94
|
+
// ✅ CORRECT — Login formu
|
|
95
|
+
<TextField label="E-posta" variant="filled" color="neutral" size="medium" autoFocus fullWidth name="email" />
|
|
96
|
+
|
|
97
|
+
// ❌ WRONG — variant="standard" tema override'ı yok
|
|
98
|
+
<TextField variant="standard" />
|
|
99
|
+
```
|
|
78
100
|
|
|
79
101
|
### TextField Label
|
|
80
102
|
|
|
@@ -191,6 +213,22 @@ Figma's "Radio" uses the same `CheckboxBase` component with `rounded-[8px]` for
|
|
|
191
213
|
|
|
192
214
|
**MUI Component:** `Chip` from `@mui/material`
|
|
193
215
|
|
|
216
|
+
### Chip Colors (Tema Tanımlı)
|
|
217
|
+
|
|
218
|
+
Chip için tema override'ı olan geçerli `color` değerleri:
|
|
219
|
+
|
|
220
|
+
| Color | Kullanım Amacı | Görsel |
|
|
221
|
+
|-------|---------------|--------|
|
|
222
|
+
| `primary` | Varsayılan marka rengi (mavi) | Blue bg/fill |
|
|
223
|
+
| `secondary` | İkincil/nötr durumlar | Gray bg/fill |
|
|
224
|
+
| `error` / `danger` | Hata/kritik durumlar | Red bg/fill |
|
|
225
|
+
| `success` | Başarılı/tamamlanan durumlar | Green bg/fill |
|
|
226
|
+
| `informative` | Bilgilendirme/sayım etiketleri | Neutral blue bg |
|
|
227
|
+
| `brand` | Marka vurgusu (primary ile aynı palette) | Brand blue |
|
|
228
|
+
| `severewarning` | Ciddi uyarı durumları | Orange/amber |
|
|
229
|
+
| `warning` | Genel uyarı durumları | Yellow |
|
|
230
|
+
| `important` | Seçili/aktif filtre | Vurgulu renk |
|
|
231
|
+
|
|
194
232
|
### Chip Variants
|
|
195
233
|
|
|
196
234
|
| # | Figma Pattern | Variant | Color | Size |
|
|
@@ -201,6 +239,36 @@ Figma's "Radio" uses the same `CheckboxBase` component with `rounded-[8px]` for
|
|
|
201
239
|
| CH4 | Ghost (text only) | `ghost` | `primary` | `medium` |
|
|
202
240
|
| CH5 | Filled Error | `filled` | `error` | `medium` |
|
|
203
241
|
| CH6 | Tint Error | `tint` | `error` | `medium` |
|
|
242
|
+
| CH7 | Status: Aktif | `tint` | `success` | `small` |
|
|
243
|
+
| CH8 | Status: Hizmet dışı | `tint` | `danger` | `small` |
|
|
244
|
+
| CH9 | Status: Dondurulmuş | `tint` | `severewarning` | `small` |
|
|
245
|
+
| CH10 | Status: Devam ediyor | `tint` | `brand` | `small` |
|
|
246
|
+
| CH11 | Count/info label | `filled` | `informative` | `small` |
|
|
247
|
+
| CH12 | Filter pill (selected) | `filled` | `important` | `small` |
|
|
248
|
+
| CH13 | Filter pill (unselected) | `outline` | `informative` | `small` |
|
|
249
|
+
|
|
250
|
+
### Gerçek Proje Kullanım Örnekleri
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
// ✅ CORRECT — Status chip'leri
|
|
254
|
+
<Chip size="small" variant="tint" color="success" label="Aktif" />
|
|
255
|
+
<Chip size="small" variant="tint" color="danger" label="Hizmet dışı" />
|
|
256
|
+
<Chip size="small" variant="tint" color="severewarning" label="Dondurulmuş" />
|
|
257
|
+
<Chip size="small" variant="tint" color="brand" label="Devam ediyor" />
|
|
258
|
+
|
|
259
|
+
// ✅ CORRECT — Bilgi/sayım chip'i
|
|
260
|
+
<Chip label={`${unreadCount} okunmamış`} size="small" variant="filled" color="informative" />
|
|
261
|
+
|
|
262
|
+
// ✅ CORRECT — Filtre chip'leri
|
|
263
|
+
<Chip size="small" variant="filled" color="important" label="Hepsi" onClick={handleFilter} />
|
|
264
|
+
<Chip size="small" variant="outline" color="informative" label="Tamamlanan" onClick={handleFilter} icon={<Dot />} />
|
|
265
|
+
|
|
266
|
+
// ✅ CORRECT — Silinebilir chip
|
|
267
|
+
<Chip label="Filtre" variant="tint" color="primary" size="small" onDelete={handleDelete} />
|
|
268
|
+
|
|
269
|
+
// ❌ WRONG — color="warning" on Chip (use severewarning or use Alert)
|
|
270
|
+
<Chip color="warning" label="Warning" />
|
|
271
|
+
```
|
|
204
272
|
|
|
205
273
|
### Filter Tags (from Figma)
|
|
206
274
|
|
|
@@ -234,6 +302,16 @@ Figma shows "Badge" with `rounded-[16px]`, `brand-background-2-rest` bg, `brand-
|
|
|
234
302
|
| BD6 | Important Badge | `important` | `medium` |
|
|
235
303
|
| BD7 | Dot Badge (6px) | `default` | `dot` |
|
|
236
304
|
| BD8 | Small Badge | `default` | `small` |
|
|
305
|
+
| BD9 | Extra-Large Badge (bildirim sayısı) | `danger` | `extra-large` |
|
|
306
|
+
|
|
307
|
+
### Gerçek Proje Kullanımı
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
// ✅ CORRECT — Bildirim ikonu üzerinde sayı
|
|
311
|
+
<Badge size="extra-large" color="danger" badgeContent={unreadNotificationCount}>
|
|
312
|
+
<Bell01Icon />
|
|
313
|
+
</Badge>
|
|
314
|
+
```
|
|
237
315
|
|
|
238
316
|
### Dot Badge (from Figma)
|
|
239
317
|
|
|
@@ -339,7 +417,63 @@ Tooltip styling is handled by theme overrides. Use standard MUI Tooltip API.
|
|
|
339
417
|
|
|
340
418
|
## Table / Data Grid
|
|
341
419
|
|
|
342
|
-
OneHub
|
|
420
|
+
OneHub'da iki tablo yaklaşımı kullanılır:
|
|
421
|
+
|
|
422
|
+
1. **MUI Table** — Standart veri tabloları için (gerçek projelerde en yaygın kullanım)
|
|
423
|
+
2. **Custom Box tablosu** — Karmaşık, özel tasarım tablolar için (Figma spesifikasyonlarına birebir uyması gerektiğinde)
|
|
424
|
+
|
|
425
|
+
### Yaklaşım 1: MUI Table (Tercih Edilen)
|
|
426
|
+
|
|
427
|
+
```tsx
|
|
428
|
+
import TableContainer from "@mui/material/TableContainer";
|
|
429
|
+
import Table from "@mui/material/Table";
|
|
430
|
+
import TableHead from "@mui/material/TableHead";
|
|
431
|
+
import TableBody from "@mui/material/TableBody";
|
|
432
|
+
import TableRow from "@mui/material/TableRow";
|
|
433
|
+
import TableCell from "@mui/material/TableCell";
|
|
434
|
+
import Paper from "@mui/material/Paper";
|
|
435
|
+
|
|
436
|
+
// ✅ CORRECT — Standart veri tablosu (gerçek projelerdeki kullanım)
|
|
437
|
+
<TableContainer component={Paper}>
|
|
438
|
+
<Table sx={{ minWidth: "100%" }}>
|
|
439
|
+
<TableHead sx={{
|
|
440
|
+
height: "40px",
|
|
441
|
+
"& > tr > th": {
|
|
442
|
+
padding: (t) => t.spacing(3, 6),
|
|
443
|
+
...(t) => t.typography["text.xs.medium"],
|
|
444
|
+
},
|
|
445
|
+
}}>
|
|
446
|
+
<TableRow>
|
|
447
|
+
<TableCell>Müşteri No</TableCell>
|
|
448
|
+
<TableCell>Ad Soyad</TableCell>
|
|
449
|
+
{/* ... */}
|
|
450
|
+
</TableRow>
|
|
451
|
+
</TableHead>
|
|
452
|
+
<TableBody sx={{
|
|
453
|
+
"& > tr > td": {
|
|
454
|
+
height: "56px",
|
|
455
|
+
padding: (t) => t.spacing(2, 6),
|
|
456
|
+
...(t) => t.typography["text.sm.regular"],
|
|
457
|
+
color: "neutral.foreground.3.rest",
|
|
458
|
+
},
|
|
459
|
+
"& > tr:hover": {
|
|
460
|
+
background: "var(--palette-neutral-background-1-hover)"
|
|
461
|
+
}
|
|
462
|
+
}}>
|
|
463
|
+
{items.map((row) => (
|
|
464
|
+
<TableRow key={row.id}>
|
|
465
|
+
<TableCell>{row.customerNo}</TableCell>
|
|
466
|
+
<TableCell>{row.name}</TableCell>
|
|
467
|
+
</TableRow>
|
|
468
|
+
))}
|
|
469
|
+
</TableBody>
|
|
470
|
+
</Table>
|
|
471
|
+
</TableContainer>
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Yaklaşım 2: Custom Box Tablosu (Figma Birebir)
|
|
475
|
+
|
|
476
|
+
Figma spesifikasyonlarına birebir uyulması gereken karmaşık tablolarda kullanılır. Bu durumda `Box` bileşenleri ile özel yapı kurulur.
|
|
343
477
|
|
|
344
478
|
### Table Structure (from Figma)
|
|
345
479
|
|
|
@@ -348,7 +482,8 @@ OneHub tables are **not** MUI `Table` — they use custom styled `Box` rows with
|
|
|
348
482
|
| **Table Header** | `40px` | `--neutral-background-2-rest` (`#fafafa`) | Bottom: `--neutral-stroke-3-rest` |
|
|
349
483
|
| **Table Row** | `56px` | `--neutral-background-1-rest` (white) | Bottom: `--neutral-stroke-3-rest` |
|
|
350
484
|
| **Table Row Hover** | `56px` | — | Bottom: `--neutral-stroke-3-rest` |
|
|
351
|
-
| **
|
|
485
|
+
| **TableCell Horizontal Padding** | — | — | `theme.spacing(8)` (32px) |
|
|
486
|
+
| **TableCell Vertical Padding** | — | — | `theme.spacing(2)` (8px) for data, `theme.spacing(3)` for header |
|
|
352
487
|
| **Pagination Row** | `56px` | `--neutral-background-1-rest` | Top: `--neutral-stroke-3-rest` |
|
|
353
488
|
|
|
354
489
|
### Table Typography
|
|
@@ -361,8 +496,46 @@ OneHub tables are **not** MUI `Table` — they use custom styled `Box` rows with
|
|
|
361
496
|
| Date number (large) | `text.lg.medium` (`18px`, `500`) | `neutral.foreground[2].rest` |
|
|
362
497
|
| Date month (small) | `text.sm.regular` (`14px`, `400`) | `neutral.foreground[4].rest` |
|
|
363
498
|
|
|
499
|
+
### Table Loading (Skeleton)
|
|
500
|
+
|
|
501
|
+
```tsx
|
|
502
|
+
import Skeleton from "@mui/material/Skeleton";
|
|
503
|
+
|
|
504
|
+
// ✅ CORRECT — Tablo yükleme durumu gösterimi
|
|
505
|
+
<TableBody>
|
|
506
|
+
{isLoading && Array.from({ length: pageSize }).map((_, i) => (
|
|
507
|
+
<TableRow key={i}>
|
|
508
|
+
{Array.from({ length: columnCount }).map((_, j) => (
|
|
509
|
+
<TableCell key={j}>
|
|
510
|
+
<Skeleton variant="text" sx={{ fontSize: "14px" }} />
|
|
511
|
+
</TableCell>
|
|
512
|
+
))}
|
|
513
|
+
</TableRow>
|
|
514
|
+
))}
|
|
515
|
+
</TableBody>
|
|
516
|
+
```
|
|
517
|
+
|
|
364
518
|
### Search & Filter Bar
|
|
365
519
|
|
|
520
|
+
**İki yaklaşım vardır:**
|
|
521
|
+
|
|
522
|
+
#### InputBase ile (ince tasarım)
|
|
523
|
+
```tsx
|
|
524
|
+
import InputBase from "@mui/material/InputBase";
|
|
525
|
+
import TuneIcon from "@/components/ui/icon";
|
|
526
|
+
|
|
527
|
+
<Box sx={{ display: "flex", alignItems: "center", gap: 1, px: 2, py: 1 }}>
|
|
528
|
+
<TuneIcon name="search-md" size="20px" />
|
|
529
|
+
<InputBase
|
|
530
|
+
placeholder="Ara..."
|
|
531
|
+
value={search}
|
|
532
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
533
|
+
sx={{ fontSize: "14px", color: "neutral.foreground.3.rest" }}
|
|
534
|
+
/>
|
|
535
|
+
</Box>
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
#### TextField ile (standart)
|
|
366
539
|
| Element | MUI Component(s) | Notes |
|
|
367
540
|
|---------|-----------------|-------|
|
|
368
541
|
| Search Input | `TextField` color="neutral" size="medium" + search icon | `placeholder="Ara"` |
|
|
@@ -374,7 +547,45 @@ OneHub tables are **not** MUI `Table` — they use custom styled `Box` rows with
|
|
|
374
547
|
|
|
375
548
|
| Element | MUI Component |
|
|
376
549
|
|---------|---------------|
|
|
377
|
-
| Pagination
|
|
550
|
+
| Pagination | `Pagination` from `@mui/material` |
|
|
551
|
+
| Page size selector | `ButtonGroup` variant="outlined" color="secondary" size="extra-small" |
|
|
552
|
+
| Navigation buttons | Custom `Button` or icon buttons with Geri/İleri text |
|
|
553
|
+
|
|
554
|
+
```tsx
|
|
555
|
+
import Pagination from "@mui/material/Pagination";
|
|
556
|
+
import Button from "@mui/material/Button";
|
|
557
|
+
import ButtonGroup from "@mui/material/ButtonGroup";
|
|
558
|
+
|
|
559
|
+
// ✅ CORRECT — Gerçek proje pagination pattern'i
|
|
560
|
+
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", p: 2 }}>
|
|
561
|
+
<ButtonGroup variant="outlined" color="secondary" size="extra-small">
|
|
562
|
+
{[10, 50, 100].map((size) => (
|
|
563
|
+
<Button key={size}
|
|
564
|
+
sx={{ backgroundColor: size === pageSize ? "neutral.background.1.selected" : "unset" }}
|
|
565
|
+
onClick={() => setPageSize(size)}
|
|
566
|
+
>
|
|
567
|
+
{size}
|
|
568
|
+
</Button>
|
|
569
|
+
))}
|
|
570
|
+
</ButtonGroup>
|
|
571
|
+
|
|
572
|
+
<Pagination
|
|
573
|
+
count={totalPages}
|
|
574
|
+
page={page + 1}
|
|
575
|
+
onChange={handlePageChange}
|
|
576
|
+
shape="rounded"
|
|
577
|
+
/>
|
|
578
|
+
|
|
579
|
+
<Box sx={{ display: "flex", gap: 1 }}>
|
|
580
|
+
<Button disabled={!hasPrevious} onClick={handlePrev}>
|
|
581
|
+
<ArrowNarrowLeftIcon /> Geri
|
|
582
|
+
</Button>
|
|
583
|
+
<Button disabled={!hasNext} onClick={handleNext}>
|
|
584
|
+
İleri <ArrowNarrowRightIcon />
|
|
585
|
+
</Button>
|
|
586
|
+
</Box>
|
|
587
|
+
</Box>
|
|
588
|
+
```
|
|
378
589
|
|
|
379
590
|
---
|
|
380
591
|
|
|
@@ -458,13 +669,33 @@ Tab styling is handled by theme overrides. Use standard MUI Tabs API.
|
|
|
458
669
|
|
|
459
670
|
## Sidebar / Navigation
|
|
460
671
|
|
|
461
|
-
**Layout
|
|
672
|
+
**Layout Pattern:** Dashboard layout with custom `DashboardSidebar` component.
|
|
462
673
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
674
|
+
Modül seviyesinde özel sidebar component'i oluşturulur. Sidebar; içerik alanı, kullanıcı menüsü ve daraltılabilir navigasyon öğelerini içerir.
|
|
675
|
+
|
|
676
|
+
```tsx
|
|
677
|
+
// Tipik dashboard layout yapısı
|
|
678
|
+
import DashboardSidebar from "@/components/ui/dashboardSidebar/dashboardSidebar";
|
|
679
|
+
|
|
680
|
+
const DashboardLayout = ({ children }: { children: ReactNode }) => (
|
|
681
|
+
<Box sx={{ display: "flex", height: "100vh" }}>
|
|
682
|
+
<Box sx={{ width: "256px", flexShrink: 0 }}>
|
|
683
|
+
<DashboardSidebar />
|
|
684
|
+
</Box>
|
|
685
|
+
<Box sx={{ flexGrow: 1, overflow: "auto" }}>
|
|
686
|
+
{children}
|
|
687
|
+
</Box>
|
|
688
|
+
</Box>
|
|
689
|
+
);
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
| Property | Spec |
|
|
693
|
+
|----------|------|
|
|
694
|
+
| Width | `256px` |
|
|
695
|
+
| Collapsed width | Modüle göre değişir |
|
|
696
|
+
| Background | Tema varsayılan |
|
|
467
697
|
| Nav items | `CollapsableListItem` |
|
|
698
|
+
| User menu | `UserDropdownMenu` |
|
|
468
699
|
|
|
469
700
|
---
|
|
470
701
|
|
|
@@ -510,7 +741,7 @@ function MyPageContent() {
|
|
|
510
741
|
| **Left content** | Navigation buttons (menu toggle, add tab) |
|
|
511
742
|
| **Right content** | Action buttons (notifications, calendar, settings, help, bug report) |
|
|
512
743
|
| **Background** | Theme-handled |
|
|
513
|
-
| **Layout** | `@
|
|
744
|
+
| **Layout** | `@turk.net/mui/layouts/app/TabBased` |
|
|
514
745
|
|
|
515
746
|
### What This Means for Page Development
|
|
516
747
|
|
|
@@ -561,15 +792,33 @@ Slider styling is handled by theme overrides.
|
|
|
561
792
|
|
|
562
793
|
## Icon
|
|
563
794
|
|
|
564
|
-
**Icons:**
|
|
795
|
+
**Icons:** İki kaynaktan import edilir:
|
|
565
796
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
import { CheckIcon, ChevronDownIcon, SearchIcon } from '@turknet/onehub/icons'
|
|
797
|
+
1. `@turk.net/mui/icons/*` — SVG React bileşenleri (tercih edilen)
|
|
798
|
+
2. Projeye özel `TuneIcon` bileşeni — Icon font tabanlı (eski projelerde)
|
|
569
799
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
800
|
+
```typescript
|
|
801
|
+
// ✅ CORRECT — SVG ikon (tercih edilen yöntem)
|
|
802
|
+
import Settings01Icon from "@turk.net/mui/icons/Settings01Icon";
|
|
803
|
+
import Menu01Icon from "@turk.net/mui/icons/Menu01Icon";
|
|
804
|
+
import Bell01Icon from "@turk.net/mui/icons/Bell01Icon";
|
|
805
|
+
import ArrowRightIcon from "@turk.net/mui/icons/ArrowRightIcon";
|
|
806
|
+
import ArrowNarrowLeftIcon from "@turk.net/mui/icons/ArrowNarrowLeftIcon";
|
|
807
|
+
import ArrowNarrowRightIcon from "@turk.net/mui/icons/ArrowNarrowRightIcon";
|
|
808
|
+
import RefreshCcw01Icon from "@turk.net/mui/icons/RefreshCcw01Icon";
|
|
809
|
+
import DotsVerticalIcon from "@turk.net/mui/icons/DotsVerticalIcon";
|
|
810
|
+
import EyeIcon from "@turk.net/mui/icons/EyeIcon";
|
|
811
|
+
import EyeOffIcon from "@turk.net/mui/icons/EyeOffIcon";
|
|
812
|
+
import SearchMdIcon from "@turk.net/mui/icons/SearchMdIcon";
|
|
813
|
+
|
|
814
|
+
// ✅ CORRECT — TuneIcon (eski projelerde, icon font)
|
|
815
|
+
import TuneIcon from "@/components/ui/icon";
|
|
816
|
+
<TuneIcon name="search-md" size="20px" />
|
|
817
|
+
<TuneIcon name="arrow-right" />
|
|
818
|
+
<TuneIcon name="trash-01" size="24px" />
|
|
819
|
+
|
|
820
|
+
// ⚠️ İSTİSNA — MUI ikonları sadece belirli durumlarda
|
|
821
|
+
import Error from "@mui/icons-material/Error"; // Alert içinde ikon override
|
|
573
822
|
```
|
|
574
823
|
|
|
575
824
|
---
|
|
@@ -615,6 +864,266 @@ See `DESIGN_TOKENS_MAP.md#typography-token-map` for the complete variant list.
|
|
|
615
864
|
|
|
616
865
|
---
|
|
617
866
|
|
|
867
|
+
## Drawer (Sağ Panel)
|
|
868
|
+
|
|
869
|
+
**MUI Component:** `Drawer` from `@mui/material`
|
|
870
|
+
|
|
871
|
+
Form şablonu düzenleme, görev atama gibi sağdan açılan paneller için kullanılır.
|
|
872
|
+
|
|
873
|
+
```tsx
|
|
874
|
+
import Drawer from "@mui/material/Drawer";
|
|
875
|
+
import { drawerClasses } from "@mui/material";
|
|
876
|
+
|
|
877
|
+
// ✅ CORRECT — Sağ panel
|
|
878
|
+
<Drawer
|
|
879
|
+
open={isOpen}
|
|
880
|
+
onClose={() => setOpen(false)}
|
|
881
|
+
anchor="right"
|
|
882
|
+
slotProps={{
|
|
883
|
+
paper: { sx: { borderRadius: "0" } },
|
|
884
|
+
backdrop: {
|
|
885
|
+
sx: {
|
|
886
|
+
backdropFilter: "blur(8px)",
|
|
887
|
+
backgroundColor: "neutral.background.overlay.background",
|
|
888
|
+
},
|
|
889
|
+
},
|
|
890
|
+
}}
|
|
891
|
+
>
|
|
892
|
+
<Box sx={{ width: "600px", p: 6 }}>
|
|
893
|
+
{/* Drawer içeriği */}
|
|
894
|
+
</Box>
|
|
895
|
+
</Drawer>
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
| Property | Value |
|
|
899
|
+
|----------|-------|
|
|
900
|
+
| Anchor | `right` (standart sağ panel) |
|
|
901
|
+
| Paper borderRadius | `0` (tam ekran yükseklik) |
|
|
902
|
+
| Backdrop | `blur(8px)` + overlay rengi |
|
|
903
|
+
| Genişlik | Değişken (tipik: `400px`-`800px`) |
|
|
904
|
+
|
|
905
|
+
---
|
|
906
|
+
|
|
907
|
+
## Modal
|
|
908
|
+
|
|
909
|
+
**MUI Component:** `Modal` from `@mui/material`
|
|
910
|
+
|
|
911
|
+
Tüm onay, bilgi ve detay modal pencereleri için kullanılır. Redux-tabanlı modal yönetim sistemi ile çalışır.
|
|
912
|
+
|
|
913
|
+
```tsx
|
|
914
|
+
import { Modal, CircularProgress } from "@mui/material";
|
|
915
|
+
import { Suspense } from "react";
|
|
916
|
+
|
|
917
|
+
// ✅ CORRECT — Modal pattern'i (Redux modal sistemi ile)
|
|
918
|
+
<Modal
|
|
919
|
+
sx={{ display: "flex", alignItems: "center", justifyContent: "center" }}
|
|
920
|
+
slotProps={{
|
|
921
|
+
backdrop: {
|
|
922
|
+
sx: {
|
|
923
|
+
background: "var(--palette-neutral-background-overlay-background, rgba(0,0,0,0.40))",
|
|
924
|
+
backdropFilter: "blur(8px)",
|
|
925
|
+
},
|
|
926
|
+
},
|
|
927
|
+
}}
|
|
928
|
+
open={modalOpen}
|
|
929
|
+
onClose={handleClose}
|
|
930
|
+
>
|
|
931
|
+
<Suspense fallback={<CircularProgress disableShrink />}>
|
|
932
|
+
<ModalComponent {...props} />
|
|
933
|
+
</Suspense>
|
|
934
|
+
</Modal>
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
Modal içeriği `Paper` ile sarılır (DefaultModalLayout pattern'i):
|
|
938
|
+
|
|
939
|
+
```tsx
|
|
940
|
+
import Paper from "@mui/material/Paper";
|
|
941
|
+
import Grow from "@mui/material/Grow";
|
|
942
|
+
import Typography from "@mui/material/Typography";
|
|
943
|
+
import Button from "@mui/material/Button";
|
|
944
|
+
|
|
945
|
+
// ✅ CORRECT — Modal içerik layout'u
|
|
946
|
+
<Grow in={open}>
|
|
947
|
+
<Paper sx={{ width: "800px", boxShadow: "var(--shadow-16)" }}>
|
|
948
|
+
<Box sx={{ p: 6, display: "flex", flexDirection: "column", gap: 4 }}>
|
|
949
|
+
<Box sx={{ display: "flex", justifyContent: "space-between" }}>
|
|
950
|
+
<TuneIcon name="trash-01" size="24px" />
|
|
951
|
+
<Button onClick={onClose} variant="text" color="secondary">
|
|
952
|
+
<TuneIcon name="x-close" size="24px" />
|
|
953
|
+
</Button>
|
|
954
|
+
</Box>
|
|
955
|
+
<Typography variant="text.lg.semibold">Başlık</Typography>
|
|
956
|
+
<Typography variant="text.sm.regular" sx={{ color: "var(--palette-neutral-foreground-4-rest)" }}>
|
|
957
|
+
Açıklama metni
|
|
958
|
+
</Typography>
|
|
959
|
+
</Box>
|
|
960
|
+
<Box sx={{ display: "flex", gap: 3, p: 6, pt: 0 }}>
|
|
961
|
+
<Button variant="outlined" size="medium" color="secondary" onClick={onClose}>İptal</Button>
|
|
962
|
+
<Button variant="contained" size="medium" color="error" onClick={handleConfirm}>Onayla</Button>
|
|
963
|
+
</Box>
|
|
964
|
+
</Paper>
|
|
965
|
+
</Grow>
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
---
|
|
969
|
+
|
|
970
|
+
## InputBase (Arama Alanı - İnce Tasarım)
|
|
971
|
+
|
|
972
|
+
**MUI Component:** `InputBase` from `@mui/material`
|
|
973
|
+
|
|
974
|
+
Tablo üstü arama çubuklarında, TextField'dan daha hafif/ince bir görünüm için kullanılır.
|
|
975
|
+
|
|
976
|
+
```tsx
|
|
977
|
+
import InputBase from "@mui/material/InputBase";
|
|
978
|
+
import Box from "@mui/material/Box";
|
|
979
|
+
import TuneIcon from "@/components/ui/icon";
|
|
980
|
+
|
|
981
|
+
// ✅ CORRECT — İnce arama alanı
|
|
982
|
+
<Box sx={{ display: "flex", alignItems: "center", gap: 1, px: 2, py: 1, borderBottom: "1px solid", borderColor: "var(--palette-neutral-stroke-3-rest)" }}>
|
|
983
|
+
<TuneIcon name="search-md" size="20px" />
|
|
984
|
+
<InputBase
|
|
985
|
+
placeholder="Ara..."
|
|
986
|
+
value={searchQuery}
|
|
987
|
+
onChange={(e) => handleSearch(e.target.value)}
|
|
988
|
+
sx={{ fontSize: "14px", color: "neutral.foreground.3.rest", width: "100%" }}
|
|
989
|
+
/>
|
|
990
|
+
</Box>
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
---
|
|
994
|
+
|
|
995
|
+
## IconButton + Tooltip
|
|
996
|
+
|
|
997
|
+
**MUI Components:** `IconButton` + `Tooltip` from `@mui/material`
|
|
998
|
+
|
|
999
|
+
```tsx
|
|
1000
|
+
import IconButton from "@mui/material/IconButton";
|
|
1001
|
+
import Tooltip from "@mui/material/Tooltip";
|
|
1002
|
+
|
|
1003
|
+
// ✅ CORRECT
|
|
1004
|
+
<Tooltip arrow title="Yenile">
|
|
1005
|
+
<IconButton size="small" onClick={() => refetch()}>
|
|
1006
|
+
<RefreshCcw01Icon />
|
|
1007
|
+
</IconButton>
|
|
1008
|
+
</Tooltip>
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
---
|
|
1012
|
+
|
|
1013
|
+
## ButtonGroup (Sayfa Boyutu Seçici)
|
|
1014
|
+
|
|
1015
|
+
**MUI Component:** `ButtonGroup` from `@mui/material`
|
|
1016
|
+
|
|
1017
|
+
```tsx
|
|
1018
|
+
import ButtonGroup from "@mui/material/ButtonGroup";
|
|
1019
|
+
import Button from "@mui/material/Button";
|
|
1020
|
+
|
|
1021
|
+
// ✅ CORRECT — Sayfa boyutu seçici
|
|
1022
|
+
<ButtonGroup variant="outlined" color="secondary" size="extra-small">
|
|
1023
|
+
{[10, 50, 100].map((size) => (
|
|
1024
|
+
<Button key={size}
|
|
1025
|
+
sx={{
|
|
1026
|
+
backgroundColor: size === pageSize
|
|
1027
|
+
? "neutral.background.1.selected"
|
|
1028
|
+
: "unset"
|
|
1029
|
+
}}
|
|
1030
|
+
onClick={() => setPageSize(size)}
|
|
1031
|
+
>
|
|
1032
|
+
{size}
|
|
1033
|
+
</Button>
|
|
1034
|
+
))}
|
|
1035
|
+
</ButtonGroup>
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
---
|
|
1039
|
+
|
|
1040
|
+
## Skeleton (Yükleme Göstergesi)
|
|
1041
|
+
|
|
1042
|
+
**MUI Component:** `Skeleton` from `@mui/material`
|
|
1043
|
+
|
|
1044
|
+
```tsx
|
|
1045
|
+
import Skeleton from "@mui/material/Skeleton";
|
|
1046
|
+
|
|
1047
|
+
// ✅ CORRECT — Tablo yükleme skeleton'ı
|
|
1048
|
+
<TableBody>
|
|
1049
|
+
{isLoading && Array.from({ length: pageSize }).map((_, i) => (
|
|
1050
|
+
<TableRow key={i}>
|
|
1051
|
+
{Array.from({ length: 8 }).map((_, j) => (
|
|
1052
|
+
<TableCell key={j}>
|
|
1053
|
+
<Skeleton variant="text" sx={{ fontSize: "14px" }} />
|
|
1054
|
+
</TableCell>
|
|
1055
|
+
))}
|
|
1056
|
+
</TableRow>
|
|
1057
|
+
))}
|
|
1058
|
+
</TableBody>
|
|
1059
|
+
|
|
1060
|
+
// ✅ CORRECT — Metin skeleton
|
|
1061
|
+
<Skeleton variant="text" sx={{ fontSize: "14px" }} width="200px" />
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
---
|
|
1065
|
+
|
|
1066
|
+
## LinearProgress
|
|
1067
|
+
|
|
1068
|
+
**MUI Component:** `LinearProgress` from `@mui/material`
|
|
1069
|
+
|
|
1070
|
+
```tsx
|
|
1071
|
+
import LinearProgress from "@mui/material/LinearProgress";
|
|
1072
|
+
import Stack from "@mui/material/Stack";
|
|
1073
|
+
import Typography from "@mui/material/Typography";
|
|
1074
|
+
|
|
1075
|
+
// ✅ CORRECT — İlerleme çubuğu (örn: form tamamlanma yüzdesi)
|
|
1076
|
+
<Stack direction="row" sx={{ alignItems: "center" }} spacing={3}>
|
|
1077
|
+
<LinearProgress
|
|
1078
|
+
variant="determinate"
|
|
1079
|
+
color="warning"
|
|
1080
|
+
value={percentage}
|
|
1081
|
+
sx={{
|
|
1082
|
+
height: "8px",
|
|
1083
|
+
borderRadius: "4px",
|
|
1084
|
+
width: "100px",
|
|
1085
|
+
backgroundColor: "neutral.background.5.rest",
|
|
1086
|
+
}}
|
|
1087
|
+
/>
|
|
1088
|
+
<Typography variant="text.sm.regular" sx={{ color: "neutral.foreground.3.rest" }}>
|
|
1089
|
+
%{percentage.toFixed(1)}
|
|
1090
|
+
</Typography>
|
|
1091
|
+
</Stack>
|
|
1092
|
+
```
|
|
1093
|
+
|
|
1094
|
+
---
|
|
1095
|
+
|
|
1096
|
+
## Kompakt Sayfa Layout Bileşenleri
|
|
1097
|
+
|
|
1098
|
+
Gerçek projelerde sayfa düzeni için özel wrapper bileşenler kullanılır:
|
|
1099
|
+
|
|
1100
|
+
### PageContentContainer
|
|
1101
|
+
|
|
1102
|
+
```tsx
|
|
1103
|
+
import Box from "@mui/material/Box";
|
|
1104
|
+
|
|
1105
|
+
// Sayfa içeriğini sarmalayan container
|
|
1106
|
+
const PageContentContainer = ({ children }: { children: React.ReactNode }) => (
|
|
1107
|
+
<Box sx={{ display: "flex", flexDirection: "column", gap: 6, p: 8 }}>
|
|
1108
|
+
{children}
|
|
1109
|
+
</Box>
|
|
1110
|
+
);
|
|
1111
|
+
```
|
|
1112
|
+
|
|
1113
|
+
### PageContentHeader
|
|
1114
|
+
|
|
1115
|
+
```tsx
|
|
1116
|
+
// Sayfa başlık ve aksiyon barı
|
|
1117
|
+
const PageContentHeader = ({ title, actions }: { title: string; actions?: React.ReactNode }) => (
|
|
1118
|
+
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
|
1119
|
+
<Typography variant="text.xl.medium">{title}</Typography>
|
|
1120
|
+
{actions && <Box sx={{ display: "flex", gap: 2 }}>{actions}</Box>}
|
|
1121
|
+
</Box>
|
|
1122
|
+
);
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
---
|
|
1126
|
+
|
|
618
1127
|
## Components NOT Allowed (No Theme Override)
|
|
619
1128
|
|
|
620
1129
|
The following MUI components do NOT have theme overrides and MUST NOT be used:
|
|
@@ -627,6 +1136,11 @@ The following MUI components do NOT have theme overrides and MUST NOT be used:
|
|
|
627
1136
|
| `BottomNavigation` | Not overridden | Custom solution |
|
|
628
1137
|
| `MobileStepper` | Not overridden | Custom solution |
|
|
629
1138
|
| `ImageList` | Not overridden | CSS Grid/Flex |
|
|
1139
|
+
| `AppBar` | Not overridden | Use TabBased layout from @turk.net/mui |
|
|
1140
|
+
| `Drawer` (MUI) | Not overridden | Use `slotProps` ile manuel stil (izin verilir) |
|
|
1141
|
+
| `Breadcrumbs` | Not overridden | Custom solution |
|
|
1142
|
+
| `Accordion` | Not overridden | Custom solution |
|
|
1143
|
+
| `Timeline` | Not overridden | Custom solution |
|
|
630
1144
|
|
|
631
1145
|
---
|
|
632
1146
|
|
|
@@ -634,23 +1148,38 @@ The following MUI components do NOT have theme overrides and MUST NOT be used:
|
|
|
634
1148
|
|
|
635
1149
|
| If you see in Figma... | Use this MUI component |
|
|
636
1150
|
|------------------------|----------------------|
|
|
637
|
-
| A filled blue button | `Button variant="contained" color="primary"` |
|
|
638
|
-
| An outlined gray button | `Button variant="outlined" color="secondary"` |
|
|
639
|
-
| A text-only button | `Button variant="text" color="primary"` |
|
|
640
|
-
| A
|
|
1151
|
+
| A filled blue button | `Button variant="contained" color="primary" size="medium"` |
|
|
1152
|
+
| An outlined gray button | `Button variant="outlined" color="secondary" size="medium"` |
|
|
1153
|
+
| A text-only button | `Button variant="text" color="primary" size="medium"` |
|
|
1154
|
+
| A compact button (pagination) | `Button variant="outlined" color="secondary" size="extra-small"` |
|
|
1155
|
+
| A text input field | `TextField variant="outlined" color="neutral"` |
|
|
1156
|
+
| A login form input | `TextField variant="filled" color="neutral"` |
|
|
641
1157
|
| A dropdown selector | `Select color="neutral"` |
|
|
642
|
-
| A checkbox | `Checkbox color="primary"` |
|
|
643
|
-
| A radio button | `Radio color="primary"` |
|
|
1158
|
+
| A checkbox | `Checkbox color="primary" size="small"` |
|
|
1159
|
+
| A radio button | `Radio color="primary" size="small"` |
|
|
644
1160
|
| A toggle switch | `Switch color="primary"` |
|
|
645
1161
|
| A blue tag/chip | `Chip variant="tint" color="primary"` |
|
|
646
|
-
| A red error chip | `Chip variant="tint" color="
|
|
647
|
-
| A
|
|
1162
|
+
| A red error chip | `Chip variant="tint" color="danger"` |
|
|
1163
|
+
| A green success chip | `Chip variant="tint" color="success"` |
|
|
1164
|
+
| Active filter pill (selected) | `Chip variant="filled" color="important"` |
|
|
1165
|
+
| Inactive filter pill | `Chip variant="outline" color="informative"` |
|
|
1166
|
+
| A filter pill with X | `Chip variant="tint" color="primary" size="small" onDelete={...}` |
|
|
648
1167
|
| A status dot (6px) | `Badge size="dot" color="..."` |
|
|
649
|
-
|
|
|
650
|
-
| A
|
|
1168
|
+
| Notification count badge | `Badge size="extra-large" color="danger" badgeContent={count}` |
|
|
1169
|
+
| A standard data table | `TableContainer` > `Table` > `TableHead`/`TableBody` |
|
|
1170
|
+
| A table header | `TableCell` with `text.xs.medium` |
|
|
1171
|
+
| A table data row | `TableCell` with `text.sm.regular` |
|
|
1172
|
+
| A table loading state | `Skeleton variant="text"` inside `TableCell` |
|
|
1173
|
+
| A search input (thin) | `InputBase` with search icon |
|
|
1174
|
+
| A search input (standard) | `TextField color="neutral" size="medium"` |
|
|
1175
|
+
| A page size selector | `ButtonGroup variant="outlined" size="extra-small"` |
|
|
1176
|
+
| Pagination controls | `Pagination shape="rounded"` |
|
|
1177
|
+
| A progress bar | `LinearProgress variant="determinate"` |
|
|
651
1178
|
| A success message | `Alert severity="success"` |
|
|
652
|
-
| A modal/dialog | `
|
|
653
|
-
| A
|
|
1179
|
+
| A modal/dialog | `Modal` + `Paper` (Redux modal sistemi ile) |
|
|
1180
|
+
| A confirmation dialog | `Modal` + `DefaultModalLayout` |
|
|
1181
|
+
| A right-side panel | `Drawer anchor="right"` |
|
|
1182
|
+
| A tooltip on hover | `Tooltip` + `IconButton` |
|
|
654
1183
|
| A date picker | `DatePicker` (from `@mui/x-date-pickers`) |
|
|
655
1184
|
| A search with dropdown | `Autocomplete` |
|
|
656
1185
|
| Navigation tabs | `Tabs` + `Tab` |
|