@moontra/moonui 6.27.0 → 6.29.0
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/dist/cdn/moonui.css +2 -2
- package/dist/cdn/moonui.esm.js +3 -3
- package/dist/cdn/moonui.global.js +3 -3
- package/dist/index.js +178 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +178 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/issue-646-dark-scope-override.test.tsx +19 -2
- package/src/__tests__/issue-708-badge-outline-override.test.tsx +319 -0
- package/src/__tests__/issue-715-button-override-hover.test.tsx +631 -0
- package/src/components/ui/__tests__/alert.test.tsx +12 -12
- package/src/components/ui/__tests__/dark-token-contrast.test.ts +8 -2
- package/src/components/ui/__tests__/select.test.tsx +16 -6
- package/src/components/ui/alert.tsx +19 -6
- package/src/components/ui/badge.tsx +25 -1
- package/src/components/ui/button.tsx +131 -14
- package/src/components/ui/select.tsx +3 -3
- package/src/styles/tokens.css +63 -6
|
@@ -43,23 +43,23 @@ describe('Alert Components', () => {
|
|
|
43
43
|
it('renders primary variant correctly', () => {
|
|
44
44
|
render(<Alert variant="primary" data-testid="alert">Test</Alert>)
|
|
45
45
|
const alert = screen.getByTestId('alert')
|
|
46
|
-
expect(alert).toHaveClass('bg-primary
|
|
47
|
-
expect(alert).toHaveClass('text-primary')
|
|
46
|
+
expect(alert).toHaveClass('bg-primary-subtle')
|
|
47
|
+
expect(alert).toHaveClass('text-primary-subtle-foreground')
|
|
48
48
|
expect(alert).toHaveClass('border-primary/30')
|
|
49
49
|
})
|
|
50
50
|
|
|
51
51
|
it('renders success variant correctly', () => {
|
|
52
52
|
render(<Alert variant="success" data-testid="alert">Test</Alert>)
|
|
53
53
|
const alert = screen.getByTestId('alert')
|
|
54
|
-
expect(alert).toHaveClass('bg-success
|
|
55
|
-
expect(alert).toHaveClass('text-success')
|
|
54
|
+
expect(alert).toHaveClass('bg-success-subtle')
|
|
55
|
+
expect(alert).toHaveClass('text-success-subtle-foreground')
|
|
56
56
|
expect(alert).toHaveClass('border-success/30')
|
|
57
57
|
})
|
|
58
58
|
|
|
59
59
|
it('renders warning variant correctly', () => {
|
|
60
60
|
render(<Alert variant="warning" data-testid="alert">Test</Alert>)
|
|
61
61
|
const alert = screen.getByTestId('alert')
|
|
62
|
-
expect(alert).toHaveClass('bg-warning
|
|
62
|
+
expect(alert).toHaveClass('bg-warning-subtle')
|
|
63
63
|
// #630: metin `text-warning` idi ve `bg-warning/10` zemininde 1.98:1 ölçüldü —
|
|
64
64
|
// AA'nın (4.5) çok altında. Yüzey rengi (`--warning`) DEĞİŞMEDİ; yalnız metin
|
|
65
65
|
// aynı ailenin yüzey-üstü tonuna taşındı: 8.65 (light) / 15.71 (dark).
|
|
@@ -70,16 +70,16 @@ describe('Alert Components', () => {
|
|
|
70
70
|
it('renders error variant correctly', () => {
|
|
71
71
|
render(<Alert variant="error" data-testid="alert">Test</Alert>)
|
|
72
72
|
const alert = screen.getByTestId('alert')
|
|
73
|
-
expect(alert).toHaveClass('bg-destructive
|
|
74
|
-
expect(alert).toHaveClass('text-destructive')
|
|
73
|
+
expect(alert).toHaveClass('bg-destructive-subtle')
|
|
74
|
+
expect(alert).toHaveClass('text-destructive-subtle-foreground')
|
|
75
75
|
expect(alert).toHaveClass('border-destructive/30')
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
it('renders info variant correctly', () => {
|
|
79
79
|
render(<Alert variant="info" data-testid="alert">Test</Alert>)
|
|
80
80
|
const alert = screen.getByTestId('alert')
|
|
81
|
-
expect(alert).toHaveClass('bg-info
|
|
82
|
-
expect(alert).toHaveClass('text-info')
|
|
81
|
+
expect(alert).toHaveClass('bg-info-subtle')
|
|
82
|
+
expect(alert).toHaveClass('text-info-subtle-foreground')
|
|
83
83
|
expect(alert).toHaveClass('border-info/30')
|
|
84
84
|
})
|
|
85
85
|
|
|
@@ -377,7 +377,7 @@ describe('Alert Components', () => {
|
|
|
377
377
|
const description = screen.getByTestId('alert-description')
|
|
378
378
|
expect(description).toHaveClass('text-sm')
|
|
379
379
|
expect(description).toHaveClass('leading-5')
|
|
380
|
-
expect(description).toHaveClass('text-
|
|
380
|
+
expect(description).toHaveClass('text-current')
|
|
381
381
|
})
|
|
382
382
|
|
|
383
383
|
it('forwards ref correctly', () => {
|
|
@@ -407,7 +407,7 @@ describe('Alert Components', () => {
|
|
|
407
407
|
)
|
|
408
408
|
|
|
409
409
|
const alert = screen.getByTestId('alert')
|
|
410
|
-
expect(alert).toHaveClass('bg-success
|
|
410
|
+
expect(alert).toHaveClass('bg-success-subtle')
|
|
411
411
|
expect(alert).toHaveClass('py-4')
|
|
412
412
|
|
|
413
413
|
expect(screen.getByText('Success!')).toBeInTheDocument()
|
|
@@ -432,7 +432,7 @@ describe('Alert Components', () => {
|
|
|
432
432
|
)
|
|
433
433
|
|
|
434
434
|
const alert = screen.getByTestId('alert')
|
|
435
|
-
expect(alert).toHaveClass('bg-destructive
|
|
435
|
+
expect(alert).toHaveClass('bg-destructive-subtle')
|
|
436
436
|
expect(alert).toHaveClass('py-2')
|
|
437
437
|
expect(alert).toHaveClass('rounded-lg')
|
|
438
438
|
expect(alert).toHaveClass('pr-10')
|
|
@@ -149,11 +149,17 @@ describe('#368 koyu tema token kontrastları', () => {
|
|
|
149
149
|
})
|
|
150
150
|
})
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
// Bu blok #368'in KAPSAM kriteriydi: koyu tema düzeltilirken açık tema
|
|
153
|
+
// değerlerine dokunulmadığını kanıtlıyordu. Kalıcı bir "asla değişmez" kuralı
|
|
154
|
+
// DEĞİL — açık temanın kendi kontrast denetimi bu değerleri bilinçli olarak
|
|
155
|
+
// değiştirebilir. `--muted-foreground` 45% → 42% böyle güncellendi: #284 onu
|
|
156
|
+
// yalnız --muted/--background yüzeylerine göre ayarlamıştı, --secondary
|
|
157
|
+
// (#ebeff5) üstünde gerçek render'da 4.42 ölçüldü (AA 4.5 ister).
|
|
158
|
+
describe('kabul kriteri: AÇIK tema değerleri', () => {
|
|
153
159
|
it.each([
|
|
154
160
|
['destructive', '0 84.2% 48%'],
|
|
155
161
|
['muted', '217.2 32.6% 96%'],
|
|
156
|
-
['muted-foreground', '215.4 16.3%
|
|
162
|
+
['muted-foreground', '215.4 16.3% 42%'],
|
|
157
163
|
['primary', '217.2 91.2% 51%'],
|
|
158
164
|
])('--%s açık temada sabit: %s', (name, expected) => {
|
|
159
165
|
expect(tokenOku(name, 'light')).toBe(expected)
|
|
@@ -387,20 +387,30 @@ describe('Select Components', () => {
|
|
|
387
387
|
|
|
388
388
|
rerender(<SelectItem value="item1" variant="destructive">Item</SelectItem>)
|
|
389
389
|
item = screen.getByTestId('select-item')
|
|
390
|
-
expect(item).toHaveClass('text-
|
|
390
|
+
expect(item).toHaveClass('text-destructive-subtle-foreground')
|
|
391
391
|
|
|
392
392
|
rerender(<SelectItem value="item1" variant="success">Item</SelectItem>)
|
|
393
393
|
item = screen.getByTestId('select-item')
|
|
394
|
-
expect(item).toHaveClass('text-success')
|
|
394
|
+
expect(item).toHaveClass('text-success-subtle-foreground')
|
|
395
395
|
|
|
396
396
|
// #623: `text-warning` (DEFAULT token) açık temada beyaz zeminde 2.14:1 ölçüldü —
|
|
397
397
|
// AA'nın (4.5) ve hatta büyük-metin eşiğinin (3.0) altında. `--warning` aynı zamanda
|
|
398
398
|
// `bg-warning` yüzeylerinde kullanıldığı için token'ın kendisi DEĞİŞTİRİLMEDİ;
|
|
399
|
-
// metin rengi
|
|
399
|
+
// metin rengi ham kademe ikilisine taşınmıştı: 4.92 (light) / 10.51 (dark).
|
|
400
|
+
//
|
|
401
|
+
// Kalite koşusu 12 (#710 sınıfı): kardeş varyantlar `destructive` ve `success`
|
|
402
|
+
// `-subtle` token ailesine geçirilmişti, `warning` bu göçün DIŞINDA kalmıştı.
|
|
403
|
+
// Artık hizalandı. İki kazanım:
|
|
404
|
+
// 1. Kontrast 4.92 → 8.83 (light) / 10.51 → 14.43 (dark) — tokens.css'te yazılı
|
|
405
|
+
// 2. `dark:` override KALKTI: token zaten tema duyarlı olduğu için gereksizdi,
|
|
406
|
+
// üstelik `dark:` sınıfı tüketicinin kendi rengini eziyordu (#715'in kök nedeni)
|
|
407
|
+
// Aşağıdaki `not.toHaveClass` bilinçli bir regresyon kilidi — ham kademeye
|
|
408
|
+
// ya da `dark:` override'ına geri dönüş bu testi kırar.
|
|
400
409
|
rerender(<SelectItem value="item1" variant="warning">Item</SelectItem>)
|
|
401
410
|
item = screen.getByTestId('select-item')
|
|
402
|
-
expect(item).toHaveClass('text-warning-
|
|
403
|
-
expect(item).toHaveClass('
|
|
411
|
+
expect(item).toHaveClass('text-warning-subtle-foreground')
|
|
412
|
+
expect(item).not.toHaveClass('text-warning-700')
|
|
413
|
+
expect(item).not.toHaveClass('dark:text-warning-500')
|
|
404
414
|
})
|
|
405
415
|
|
|
406
416
|
it('applies size classes correctly', () => {
|
|
@@ -639,7 +649,7 @@ describe('Select Components', () => {
|
|
|
639
649
|
|
|
640
650
|
const item = screen.getByTestId('select-item')
|
|
641
651
|
expect(item).toHaveClass('py-2')
|
|
642
|
-
expect(item).toHaveClass('text-success')
|
|
652
|
+
expect(item).toHaveClass('text-success-subtle-foreground')
|
|
643
653
|
expect(item).toHaveClass('custom-item')
|
|
644
654
|
expect(screen.getByTestId('right-icon')).toBeInTheDocument()
|
|
645
655
|
expect(screen.getByTestId('custom-indicator')).toBeInTheDocument()
|
|
@@ -19,14 +19,22 @@ const alertVariants = cva(
|
|
|
19
19
|
variants: {
|
|
20
20
|
variant: {
|
|
21
21
|
default: "bg-background text-foreground border-border",
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
// KONTRAST (açık tema): metin rengi ham `text-X` DEĞİL,
|
|
23
|
+
// `text-X-subtle-foreground` olmalı. `bg-X/10 + text-X` deseni
|
|
24
|
+
// açık temada ölçülen 4.11–4.45 veriyor ve WCAG AA eşiğini
|
|
25
|
+
// (4.5) geçmiyor. `-subtle-foreground` token'ları aynı yüzey
|
|
26
|
+
// için 8.20–9.52 sağlıyor (tokens.css'te oranlar yazılı) ve
|
|
27
|
+
// `bg-X-subtle`, `bg-X/10` ile AYNI görünümü verir
|
|
28
|
+
// (tokens.css:217) → görsel kimlik değişmez, yalnız metin
|
|
29
|
+
// koyulaşır. `warning` bu düzeltmeyi zaten taşıyordu.
|
|
30
|
+
primary: "bg-primary-subtle text-primary-subtle-foreground border-primary/30",
|
|
31
|
+
success: "bg-success-subtle text-success-subtle-foreground border-success/30",
|
|
32
|
+
warning: "bg-warning-subtle text-warning-subtle-foreground border-warning/30",
|
|
33
|
+
error: "bg-destructive-subtle text-destructive-subtle-foreground border-destructive/30",
|
|
26
34
|
// `--info` token'ı (tokens.css) blue-500 ile birebir aynı değeri
|
|
27
35
|
// taşır → görsel değişiklik yok, ancak varyant artık temaya ve
|
|
28
36
|
// karanlık moda duyarlı. Kardeş varyantlarla simetrik.
|
|
29
|
-
info: "bg-info
|
|
37
|
+
info: "bg-info-subtle text-info-subtle-foreground border-info/30",
|
|
30
38
|
},
|
|
31
39
|
size: {
|
|
32
40
|
sm: "py-2 text-xs",
|
|
@@ -174,7 +182,12 @@ const AlertDescription = React.forwardRef<
|
|
|
174
182
|
ref={ref}
|
|
175
183
|
className={cn(
|
|
176
184
|
"moonui-theme",
|
|
177
|
-
|
|
185
|
+
// KONTRAST: sabit `text-muted-foreground` (#606f85) renkli varyant
|
|
186
|
+
// yüzeylerinde 4.31–4.48 veriyordu — başlık düzelse bile açıklama
|
|
187
|
+
// satırı eşiğin altında kalıyordu. `text-current` varyantın
|
|
188
|
+
// `-subtle-foreground` rengini miras alır; hiyerarşi renk yerine
|
|
189
|
+
// ağırlıkla (başlık `font-semibold`) ve hafif opaklıkla korunur.
|
|
190
|
+
"text-sm leading-5 text-current opacity-90",
|
|
178
191
|
className
|
|
179
192
|
)}
|
|
180
193
|
{...props}
|
|
@@ -48,12 +48,36 @@ const badgeVariants = cva(
|
|
|
48
48
|
"focus-visible:ring-gray-400/30 dark:focus-visible:ring-gray-500/40",
|
|
49
49
|
"dark:bg-gray-700/50 dark:text-gray-50 dark:shadow-inner dark:shadow-gray-950/10",
|
|
50
50
|
],
|
|
51
|
+
// #708 kalem 3: `outline` varyantı TÜKETİCİYİ EZİYORDU — #715'in `button`da
|
|
52
|
+
// kapattığı deliğin birebir aynısı. `cn()` = `twMerge(clsx(...))`; tüketici
|
|
53
|
+
// `className="text-white"` yazınca twMerge ÖNEKSİZ `text-foreground`u eler,
|
|
54
|
+
// ama `dark:text-gray-100` AYRI modifier grubu olduğu için ELENMEZ ve koyu
|
|
55
|
+
// temada özgüllükle kazanır: (0,2,0) > (0,1,0).
|
|
56
|
+
//
|
|
57
|
+
// Ölçülen sonuç (docs "PRO" rozeti, `from-brand-600 to-brand-accent-600`
|
|
58
|
+
// gradyanı üstünde, `text-xs` = küçük metin → AA 4.5:1):
|
|
59
|
+
// light beyaz → en kötü uç 4.60 ✓ (tüketicinin istediği renk)
|
|
60
|
+
// dark gray-100 → en kötü uç 4.18 ✗ (varyantın dayattığı renk)
|
|
61
|
+
// A18-V 10/10 sayfada ölçtü; axe bunu `violations`a HİÇ yazmıyor (gradyan
|
|
62
|
+
// zemin → `incomplete` kovası), bu yüzden 11 koşu boyunca görülmedi.
|
|
63
|
+
//
|
|
64
|
+
// #715'in AYRIMI satır satır uygulandı:
|
|
65
|
+
// · `dark:bg-transparent` → öneksiz `bg-transparent` zaten aşağıda ve
|
|
66
|
+
// `outline`da başka `bg-*` yok (sıralama guard'ı da değil) → SAF TEKRAR,
|
|
67
|
+
// kaldırıldı.
|
|
68
|
+
// · `dark:text-gray-100` → öneksiz ikizinden (`--foreground` dark =
|
|
69
|
+
// rgb(225,231,239)) FARKLI bir değere gidiyordu, ama fark rozetin kendi
|
|
70
|
+
// okunurluğunda ölçülemeyecek kadar küçük (koyu kart üstünde 15.0 → 13.5;
|
|
71
|
+
// ikisi de AA'nın çok üstünde) ve karşılığında tüketicinin AA'yı GEÇEN
|
|
72
|
+
// `text-white`ını eziyordu → kaldırıldı.
|
|
73
|
+
// · `dark:backdrop-blur-sm` → öneksiz ikizi yok, koyu-temaya özgü gerçek
|
|
74
|
+
// bir efekt → KORUNDU.
|
|
51
75
|
outline: [
|
|
52
76
|
"border-gray-200 dark:border-gray-600",
|
|
53
77
|
"bg-transparent text-foreground",
|
|
54
78
|
"hover:border-gray-300 dark:hover:border-gray-500",
|
|
55
79
|
"focus-visible:ring-gray-400/30 dark:focus-visible:ring-gray-500/40",
|
|
56
|
-
"dark:
|
|
80
|
+
"dark:backdrop-blur-sm",
|
|
57
81
|
],
|
|
58
82
|
// #544: `bg-error` (= --error, #ef4343) beyaz metinle 3.78 veriyordu (AA 4.5 ister),
|
|
59
83
|
// `dark:bg-error/90` ise gerçek koyu kart (#111827) üstünde 4.43 ile kalıyordu.
|
|
@@ -33,11 +33,68 @@ const buttonVariants = cva(
|
|
|
33
33
|
{
|
|
34
34
|
variants: {
|
|
35
35
|
variant: {
|
|
36
|
+
// #715 Dal 1 — GEREKSİZ `dark:` TEKRARI KALDIRILDI.
|
|
37
|
+
// `--primary` ve `--primary-foreground` `.dark` bloğunda ZATEN farklı değer
|
|
38
|
+
// alıyor (tokens.css:129/137 ↔ :545/546), yani öneksiz `bg-primary
|
|
39
|
+
// text-primary-foreground` iki temada da doğru çifti veriyor. `dark:` ikizi
|
|
40
|
+
// hiçbir şey KAZANDIRMIYOR, yalnız özgüllüğü şişiriyordu:
|
|
41
|
+
// .dark\:text-primary-foreground:is(.dark *) → (0,2,0)
|
|
42
|
+
// tüketicinin text-white → (0,1,0)
|
|
43
|
+
// `cn()` = twMerge: tüketici `text-white` yazınca twMerge öneksiz
|
|
44
|
+
// `text-primary-foreground`u ELER ama `dark:` ikizi AYRI modifier grubu
|
|
45
|
+
// olduğu için KALIR → koyu temada metin sessizce dark
|
|
46
|
+
// `--primary-foreground`a (222.2 47.4% 1.2% = rgb(2,2,5)) düşüyordu.
|
|
47
|
+
// Ölçüldü: beyaz metin beklerken 1.28:1 (docs/click-animations gradyan
|
|
48
|
+
// butonları). Öneksiz satır kaldığı için TEMA DAVRANIŞI DEĞİŞMEZ.
|
|
49
|
+
// Kardeş presedans: #533/#646 badge'de `dark:bg-primary/90`ı aynı gerekçeyle
|
|
50
|
+
// kaldırdı; button'a o turda uğranmamıştı.
|
|
51
|
+
//
|
|
52
|
+
// #715 Dal 3 — `primary`nin hover/active ALFA kompoziti AA altındaydı;
|
|
53
|
+
// `destructive`in (Dal 2) birebir aynı kusuru. `/90` ve `/80` zemini BEYAZLA
|
|
54
|
+
// karıştırıp rengi AÇIYOR, metin ise sabit `--primary-foreground` (#f8fafc):
|
|
55
|
+
// resting bg-primary #1067f4 → 4.70 ✓ (#442: geçiyor → DOKUNULMADI)
|
|
56
|
+
// hover bg-primary/90 #2876f5 → 4.01 ✗
|
|
57
|
+
// active bg-primary/80 #4085f6 → 3.40 ✗
|
|
58
|
+
// Koyu tema ZATEN geçiyor (near-white zemin + near-black metin: 19.80 /
|
|
59
|
+
// 15.96 / 12.50) → düzeltmenin onu bozmaması ŞART.
|
|
60
|
+
//
|
|
61
|
+
// ⚠️ Dal 2'nin çözümü (alfa yerine opak `error-NNN` kademesi) BURADA
|
|
62
|
+
// UYGULANAMAZ — `primary`nin skala ailesi YANLIŞ HUE'DA:
|
|
63
|
+
// --primary 217.2 91.2% 51% = #1067f4 (blue, h≈217)
|
|
64
|
+
// --primary-700 3 105 161 = #0369a1 (sky, h≈199)
|
|
65
|
+
// `--primary-50…950` (tokens.css:15-25) Tailwind SKY paleti; `--primary`nin
|
|
66
|
+
// koyusu DEĞİL, başka bir renk. Üstüne preset o kademeleri hiçbir utility'ye
|
|
67
|
+
// bağlamıyor → `bg-primary-700` bugün HİÇ CSS ÜRETMEYEN ölü sınıf (#713).
|
|
68
|
+
// Ölçülen adaylar ve RET gerekçeleri:
|
|
69
|
+
// · preset'e sky kademelerini bağla → açık temada 5.67 ✓, AMA (a) görünür
|
|
70
|
+
// hue kayması, (b) `bg-primary-600` (3.91 ✗) "primary'nin koyusu" sanılan
|
|
71
|
+
// yanıltıcı public API, (c) öneksiz sınıf koyu temada DA uygulanır ve
|
|
72
|
+
// near-black metinle 3.49'a ÇÖKER. → RET
|
|
73
|
+
// · `bg-blue-700` (6.41 ✓) → token'ı by-pass eder; tüketici `--primary`yi
|
|
74
|
+
// override edince hover mavide takılı kalır. → RET
|
|
75
|
+
// · `bg-primary-subtle-foreground` (#0950c3, 6.81 ✓, doğru hue, sınıf ZATEN
|
|
76
|
+
// üretiliyor) → FOREGROUND rolündeki token'ı ZEMİN yapmak iki rolü
|
|
77
|
+
// birbirine kilitler. → RET
|
|
78
|
+
// SEÇİLEN: koyu tonu `--primary`nin KENDİSİNDEN türet (`color-mix`, siyaha
|
|
79
|
+
// doğru). Tek öneksiz sınıf iki temada da doğru sonuç verir ve tüketici
|
|
80
|
+
// `--primary`yi değiştirdiğinde hover/active KENDİLİĞİNDEN uyar —
|
|
81
|
+
// tokens.css:120-128'in bilinçle koruduğu sözleşme bozulmaz.
|
|
82
|
+
// GERÇEK TARAYICIDA ÖLÇÜLDÜ (headless Chrome 140, piksel örneklemesi):
|
|
83
|
+
// hover 85% + black açık #0e57cf → 6.11 ✓ | koyu #d3d4d6 → 13.97 ✓
|
|
84
|
+
// active 75% + black açık #0c4db7 → 7.27 ✓ | koyu #babbbd → 10.79 ✓
|
|
85
|
+
// (Testteki kanal-bazlı model 1/255 yuvarlama farkıyla #0e58cf → 6.05 der;
|
|
86
|
+
// ikisi de eşiğin çok üstünde. `color-mix` gerçekten ÇÖZÜLÜYOR — tarayıcı
|
|
87
|
+
// `color(srgb 0.053652 0.342337 0.813348)` döndürüyor, yani sınıf ölü değil.)
|
|
88
|
+
// `dark:` GUARD GEREKMEZ: Dal 1'den sonra dizide hiç `dark:bg-*` yok; tek
|
|
89
|
+
// rakip öneksiz `bg-primary` (0,1,0) ve `hover:`/`active:` (0,2,0) onu yener.
|
|
90
|
+
// `[color:…]` ETİKETİ BİLEREK yazıldı: sınıfın renk olarak tanınmasını hem
|
|
91
|
+
// Tailwind'in hem twMerge'ün tip ÇIKARIMINA bırakmaz. (Etiketsiz form da
|
|
92
|
+
// bugün doğru çalışıyor — ikisi de deterministik probe'la ölçüldü — ama
|
|
93
|
+
// #715'in tamamı "sessizce yanlış sınıflandırılan sınıf" hikâyesidir.)
|
|
36
94
|
primary: [
|
|
37
95
|
"bg-primary text-primary-foreground",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"active:bg-primary/80 dark:active:bg-primary/80",
|
|
96
|
+
"hover:bg-[color:color-mix(in_srgb,hsl(var(--primary))_85%,black)]",
|
|
97
|
+
"active:bg-[color:color-mix(in_srgb,hsl(var(--primary))_75%,black)]",
|
|
41
98
|
"shadow-sm hover:shadow-md",
|
|
42
99
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
43
100
|
"transition-all duration-200",
|
|
@@ -51,12 +108,18 @@ const buttonVariants = cva(
|
|
|
51
108
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
52
109
|
"shadow-sm hover:shadow-md",
|
|
53
110
|
],
|
|
111
|
+
// #715 Dal 1 — `outline`ın DÖRT `dark:` satırı da aynı token'ın tekrarıydı
|
|
112
|
+
// (`--background`/`--foreground`/`--input`/`--accent(-foreground)` hepsi
|
|
113
|
+
// `.dark` bloğunda tanımlı) → kaldırıldı. Kaskad davranışı korunuyor:
|
|
114
|
+
// Tailwind 3.4.17 çıktısında `hover:`/`active:` kuralları `dark:`ten ÖNCE
|
|
115
|
+
// yazılıyor, yani rakip `dark:bg-background` (0,2,0) gitmeden `hover:bg-accent`
|
|
116
|
+
// (0,2,0) koyu temada kaybederdi — bu yüzden satırlar TEK TEK değil,
|
|
117
|
+
// varyant bazında BÜTÜN olarak kaldırıldı.
|
|
54
118
|
outline: [
|
|
55
119
|
"bg-background text-foreground",
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"active:bg-accent/80 dark:active:bg-accent/80",
|
|
120
|
+
"border border-input",
|
|
121
|
+
"hover:bg-accent hover:text-accent-foreground",
|
|
122
|
+
"active:bg-accent/80",
|
|
60
123
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
61
124
|
"transition-all duration-200",
|
|
62
125
|
],
|
|
@@ -77,11 +140,34 @@ const buttonVariants = cva(
|
|
|
77
140
|
// Not: `dark:bg-destructive` KALDIRILDI, yanına eklenmedi — iki `dark:bg-*`
|
|
78
141
|
// utility'si aynı anda yazılırsa hangisinin kazanacağını sınıf dizgesi sırası
|
|
79
142
|
// DEĞİL Tailwind'in kendi iç sıralaması belirler.
|
|
143
|
+
//
|
|
144
|
+
// #715 Dal 2 — #544 yalnız RESTING durumu ölçmüştü; alfa harmanlı DURUM
|
|
145
|
+
// dalları sayılmadı. Açık temada `/90` ve `/80` zemini BEYAZLA karıştırıp
|
|
146
|
+
// rengi AÇIYOR, yani AA'yı düşürüyor (metin sabit `--destructive-foreground`
|
|
147
|
+
// #f8fafc):
|
|
148
|
+
// resting bg-destructive #e11313 → 4.66 ✓ (#544'ün ölçtüğü)
|
|
149
|
+
// hover bg-destructive/90 #e42b2b → 4.29 ✗ (axe: 4.28, serious)
|
|
150
|
+
// active bg-destructive/80 #e74242 → 3.82 ✗
|
|
151
|
+
// Çözüm koyu dalın ZATEN kullandığı yaklaşım: alfa yerine opak `error`
|
|
152
|
+
// kademesi. Açık dal da aynı kademelere bağlandı:
|
|
153
|
+
// hover bg-error-700 #b91c1c → 6.18 ✓
|
|
154
|
+
// active bg-error-800 #991b1b → 7.94 ✓
|
|
155
|
+
// Yan fayda: durum ilerlemesi artık tutarlı KOYULAŞIYOR (e11313 → b91c1c →
|
|
156
|
+
// 991b1b); alfa sürümünde active, hover'dan DAHA AÇIK oluyordu.
|
|
157
|
+
// `--destructive` token'ına ve resting sınıfına DOKUNULMADI (#442).
|
|
158
|
+
//
|
|
159
|
+
// ⚠️ `dark:hover:`/`dark:active:` ikizleri öneksiziyle aynı değeri taşısa da
|
|
160
|
+
// KALDIRILAMAZ — `dark:bg-error-600` (resting, farklı değer) hâlâ gerekli ve
|
|
161
|
+
// Tailwind 3.4.17 `dark:`i `hover:`ten SONRA yazıyor (aynı özgüllük, 0,2,0):
|
|
162
|
+
// .hover\:bg-error-700:hover < .dark\:bg-error-600:is(.dark *)
|
|
163
|
+
// Öneki atarsak koyu temada hover, resting rengine geri düşer. `dark:hover:`
|
|
164
|
+
// (0,3,0) bu sıralamayı yener. Bu, Dal 1'deki "gereksiz tekrar"dan farklıdır:
|
|
165
|
+
// burada satırın ÖLÇÜLEBİLİR bir işlevi var.
|
|
80
166
|
destructive: [
|
|
81
167
|
"bg-destructive text-destructive-foreground",
|
|
82
|
-
"dark:bg-error-600
|
|
83
|
-
"hover:bg-
|
|
84
|
-
"active:bg-
|
|
168
|
+
"dark:bg-error-600",
|
|
169
|
+
"hover:bg-error-700 dark:hover:bg-error-700",
|
|
170
|
+
"active:bg-error-800 dark:active:bg-error-800",
|
|
85
171
|
"shadow-sm hover:shadow-md",
|
|
86
172
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
87
173
|
"transition-all duration-200",
|
|
@@ -92,10 +178,38 @@ const buttonVariants = cva(
|
|
|
92
178
|
// dokunulmadı (#442 kuralı: geçen yüzeyde regresyon riski açma).
|
|
93
179
|
// Dolgu opak `success` skalasına bağlandı: -600 hâlâ 3.15, ölçümle geçen
|
|
94
180
|
// en açık kademe -700 (4.79).
|
|
181
|
+
// #715 Dal 1: `dark:text-success-foreground` gereksiz tekrardı (aynı token,
|
|
182
|
+
// `.dark` bloğunda tanımlı) → kaldırıldı. `dark:bg-success-700` FARKLI bir
|
|
183
|
+
// değere işaret ettiği için KALDI.
|
|
184
|
+
//
|
|
185
|
+
// #715 Dal 3 — AÇIK temanın hover/active alfası da AA altındaydı
|
|
186
|
+
// (metin sabit `--success-foreground` #f8fafc, zemin beyaz):
|
|
187
|
+
// resting bg-success #12823b → 4.69 ✓ (#442 → DOKUNULMADI)
|
|
188
|
+
// hover bg-success/90 #2a8f4f → 3.90 ✗
|
|
189
|
+
// active bg-success/80 #419b62 → 3.30 ✗
|
|
190
|
+
// Burada `destructive`in çözümü AYNEN geçerli, çünkü `--success-NNN`
|
|
191
|
+
// skalası `--success` ile AYNI hue'da (#15803d ↔ #12823b) — `primary`den
|
|
192
|
+
// ayrıldığı nokta tam da bu. Açık dal, KOYU dalın zaten kullandığı
|
|
193
|
+
// kademelere bağlandı (tek kaynak, tutarlı ilerleme):
|
|
194
|
+
// hover bg-success-800 #166534 → 6.81 ✓
|
|
195
|
+
// active bg-success-900 #14532d → 8.71 ✓
|
|
196
|
+
// -700 (4.79) BİLEREK seçilmedi: hem eşiğe fazla yakın hem de `bg-success`
|
|
197
|
+
// ile neredeyse aynı renk (#15803d ↔ #12823b) — hover geri bildirimi
|
|
198
|
+
// görünmez olurdu.
|
|
199
|
+
//
|
|
200
|
+
// ⚠️ `dark:hover:`/`dark:active:` ikizleri artık öneksiziyle AYNI değeri
|
|
201
|
+
// taşıyor ama KALDIRILAMAZ — `destructive`teki sıralama guard'ının aynısı.
|
|
202
|
+
// Tailwind 3.4.17 çıktısı (deterministik CLI probe'uyla doğrulandı) `dark:`i
|
|
203
|
+
// `hover:`ten SONRA yazıyor ve ikisi de (0,2,0):
|
|
204
|
+
// .hover\:bg-success-800:hover < .dark\:bg-success-700:is(.dark *)
|
|
205
|
+
// `dark:hover:` (0,3,0) bu sıralamayı yener. GERÇEK TARAYICIDA KANITLANDI:
|
|
206
|
+
// guard'sız ikinci bir buton üretilip koyu temada hover'landığında zemin
|
|
207
|
+
// rgb(21,128,61)'de KALDI (= resting/-700, hover HİÇ uygulanmadı);
|
|
208
|
+
// guard'lı buton rgb(22,101,52)'ye (-800) geçti.
|
|
95
209
|
"bg-success text-success-foreground",
|
|
96
|
-
"dark:bg-success-700
|
|
97
|
-
"hover:bg-success
|
|
98
|
-
"active:bg-success
|
|
210
|
+
"dark:bg-success-700",
|
|
211
|
+
"hover:bg-success-800 dark:hover:bg-success-800",
|
|
212
|
+
"active:bg-success-900 dark:active:bg-success-900",
|
|
99
213
|
"shadow-sm hover:shadow-md",
|
|
100
214
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
101
215
|
"transition-all duration-200",
|
|
@@ -145,7 +259,10 @@ const buttonVariants = cva(
|
|
|
145
259
|
// üretiyor, `--primary-foreground` ise koyu — ikisi birbirini yiyordu.
|
|
146
260
|
// #354'ün sidebar'da kanıtlanmış çözümü: subtle token ÇİFTİ (zemin+metin
|
|
147
261
|
// birlikte tanımlı, koyu temada koyu zemin + açık metin).
|
|
148
|
-
|
|
262
|
+
// #715 Dal 1: bu çift ARTIK yukarıdaki öneksiz satırdan geliyor —
|
|
263
|
+
// `dark:bg-primary-subtle dark:text-primary-subtle-foreground` aynı token'ın
|
|
264
|
+
// tekrarıydı, kaldırıldı (#686'nın çözümü aynen KORUNUYOR, yalnız tek
|
|
265
|
+
// yerden yazılıyor). Hover/active dalları FARKLI alfa taşıdığı için KALDI.
|
|
149
266
|
"dark:hover:bg-primary/30 dark:active:bg-primary/40",
|
|
150
267
|
"transition-colors duration-200",
|
|
151
268
|
],
|
|
@@ -295,9 +295,9 @@ const SelectItem = React.forwardRef<
|
|
|
295
295
|
/* Color variants */
|
|
296
296
|
variant === "default" && "focus:bg-accent focus:text-accent-foreground dark:focus:bg-gray-700 dark:focus:text-gray-100",
|
|
297
297
|
variant === "subtle" && "focus:bg-gray-100 dark:focus:bg-gray-800 focus:text-foreground dark:focus:text-gray-200",
|
|
298
|
-
variant === "destructive" && "text-
|
|
299
|
-
variant === "success" && "text-success focus:bg-success
|
|
300
|
-
variant === "warning" && "text-warning-
|
|
298
|
+
variant === "destructive" && "text-destructive-subtle-foreground focus:bg-destructive-subtle focus:text-destructive-subtle-foreground",
|
|
299
|
+
variant === "success" && "text-success-subtle-foreground focus:bg-success-subtle focus:text-success-subtle-foreground",
|
|
300
|
+
variant === "warning" && "text-warning-subtle-foreground focus:bg-warning-subtle focus:text-warning-subtle-foreground",
|
|
301
301
|
|
|
302
302
|
className
|
|
303
303
|
)}
|
package/src/styles/tokens.css
CHANGED
|
@@ -136,14 +136,27 @@
|
|
|
136
136
|
oradaki koyu foreground DOĞRU ve değiştirilmedi.) */
|
|
137
137
|
--primary-foreground: 210 40% 98%;
|
|
138
138
|
--secondary: 217.2 32.6% 94%;
|
|
139
|
-
/* #284: --secondary rozetinde metin rolünde 4.26 (AA altı) idi -> 49
|
|
139
|
+
/* #284: --secondary rozetinde metin rolünde 4.26 (AA altı) idi -> 49%.
|
|
140
140
|
--primary 51%te KALIR: o token zemin rolünde ve beyaz metinle 4.70 taşıyor.
|
|
141
|
-
Aynı mavinin rolüne göre ayrışması --success (#280) ile aynı desendir.
|
|
142
|
-
|
|
141
|
+
Aynı mavinin rolüne göre ayrışması --success (#280) ile aynı desendir.
|
|
142
|
+
|
|
143
|
+
%49 YETMEDİ — 44%'e çekildi. #284'ün hesabı 4.54 diyordu, ama gerçek
|
|
144
|
+
tarayıcı render'ı axe-core ile 4.45 ölçüldü (eşik 4.5): teorik HSL→RGB
|
|
145
|
+
hesabı ile tarayıcının ürettiği renk sınırda ayrışıyor (hesap rgb(11,98,239),
|
|
146
|
+
render #0e64ef). DERS: 4.5–4.6 aralığındaki "geçti" sonuçlarına güvenme,
|
|
147
|
+
gerçek render'da ölç. 44% teorik 5.37 verir ve ölçümde de geçer. */
|
|
148
|
+
--secondary-foreground: 217.2 91.2% 44%;
|
|
143
149
|
--muted: 217.2 32.6% 96%;
|
|
144
150
|
/* #284: --muted zemininde 4.31 (AA altı) idi -> 45% ile 4.56.
|
|
145
|
-
--background üzerinde zaten 4.76 geçiyordu; kırılan yüzey bg-muted (kbd).
|
|
146
|
-
|
|
151
|
+
--background üzerinde zaten 4.76 geçiyordu; kırılan yüzey bg-muted (kbd).
|
|
152
|
+
|
|
153
|
+
%45 de YETMEDİ — 42%'ye çekildi. #284 yalnız --muted ve --background
|
|
154
|
+
yüzeylerine bakmış; --secondary (#ebeff5) HESABA KATILMAMIŞTI ve orada
|
|
155
|
+
gerçek render'da 4.42 ölçüldü (docs/components/card, "Secondary surface").
|
|
156
|
+
42% üç yüzeyde de geçer: secondary 4.90 · muted 5.13 · background 5.66.
|
|
157
|
+
Kademe seçiminde teorik hesabın gerçek render'dan ~0.1 yüksek çıktığı
|
|
158
|
+
gözlendi (bkz. --secondary-foreground notu), o yüzden sınıra yaslanılmadı. */
|
|
159
|
+
--muted-foreground: 215.4 16.3% 42%;
|
|
147
160
|
--accent: 217.2 32.6% 94%;
|
|
148
161
|
/* #647: --accent-foreground 51% idi -> 4.26 (AA 4.5 altı). Zemin (--accent, 94%)
|
|
149
162
|
--secondary ile BİREBİR aynı token değeri; #284'ün --secondary-foreground'da
|
|
@@ -262,7 +275,35 @@
|
|
|
262
275
|
--bg-vivid-2: 328.6 85.5% 70.2%;
|
|
263
276
|
--bg-vivid-3: 213.1 93.9% 67.8%;
|
|
264
277
|
--bg-vivid-4: 158.1 64.4% 51.6%;
|
|
265
|
-
|
|
278
|
+
|
|
279
|
+
/* Yildiz alani — starfield (#720).
|
|
280
|
+
`--bg-space` YALNIZ dekoratif degildir: `children` metni bu zeminin ustune
|
|
281
|
+
dusuyor, yani kontrast hesabina GIRER. `--bg-star` ile ciftin ayrimi #481'de
|
|
282
|
+
olculmustu (beyaz-ustune-beyaz 1.045:1) — degerler o cozumun aynisidir. */
|
|
283
|
+
--bg-star: 215 27.9% 16.9%;
|
|
284
|
+
--bg-space: 210 20% 98%;
|
|
285
|
+
|
|
286
|
+
/* 3'lu nebula paleti — starfield (#720).
|
|
287
|
+
Saf DEKORATIF bulut katmani (uzerine metin dusmez) → AA'ya tabi degil.
|
|
288
|
+
ALFA DEGERIN PARCASIDIR: eski hex'ler `#db278610` gibi 8 haneliydi (alfa
|
|
289
|
+
0x10/255 = 0.0627). Alfa dusurulurse katman 16x koyulasir; bu yuzden token
|
|
290
|
+
`H S% L% / A` biciminde tutulur — canvas `addColorStop` bu sozdizimini
|
|
291
|
+
kabul ediyor (Chrome 152'de olculdu). */
|
|
292
|
+
--bg-nebula-1: 328.3 71.4% 50.6% / 0.0627;
|
|
293
|
+
--bg-nebula-2: 188.7 94.5% 42.7% / 0.0627;
|
|
294
|
+
--bg-nebula-3: 45.4 93.4% 47.5% / 0.0627;
|
|
295
|
+
|
|
296
|
+
/* 5'li pastel mesh paleti — mesh-gradient (#720).
|
|
297
|
+
AYRI BIR SET, `--bg-effect-*` DEGIL: mesh'in kimligi cok acik pastellerdir
|
|
298
|
+
(L %89.8-94.7); EFFECT paleti (L %46.5-78) uzerine tasinsaydi component'in
|
|
299
|
+
gorunumu degisirdi. Token'a tasima gorunumu DEGISTIRMEZ kurali (bu blogun
|
|
300
|
+
bas yorumu) yeni bir grup gerektirdi. */
|
|
301
|
+
--bg-mesh-1: 325.7 77.8% 94.7%;
|
|
302
|
+
--bg-mesh-2: 268.6 100% 91.8%;
|
|
303
|
+
--bg-mesh-3: 250.5 95.2% 91.8%;
|
|
304
|
+
--bg-mesh-4: 226.5 100% 93.9%;
|
|
305
|
+
--bg-mesh-5: 325.9 84.6% 89.8%;
|
|
306
|
+
|
|
266
307
|
/* === TYPOGRAPHY === */
|
|
267
308
|
|
|
268
309
|
/* Font Families */
|
|
@@ -630,6 +671,22 @@
|
|
|
630
671
|
--bg-vivid-2: 330.4 81.2% 60.4%;
|
|
631
672
|
--bg-vivid-3: 217.2 91.2% 59.8%;
|
|
632
673
|
--bg-vivid-4: 160.1 84.1% 39.4%;
|
|
674
|
+
|
|
675
|
+
/* starfield (#720) — koyu temada beyaz yildiz / siyah uzay */
|
|
676
|
+
--bg-star: 0 0% 100%;
|
|
677
|
+
--bg-space: 0 0% 0%;
|
|
678
|
+
|
|
679
|
+
/* starfield nebula (#720) — koyu temada neon, alfa 0x20/255 = 0.1255 */
|
|
680
|
+
--bg-nebula-1: 300 100% 50% / 0.1255;
|
|
681
|
+
--bg-nebula-2: 180 100% 50% / 0.1255;
|
|
682
|
+
--bg-nebula-3: 60 100% 50% / 0.1255;
|
|
683
|
+
|
|
684
|
+
/* mesh-gradient (#720) — koyu temada derin mor set */
|
|
685
|
+
--bg-mesh-1: 263.4 69.3% 42.2%;
|
|
686
|
+
--bg-mesh-2: 262.1 83.3% 57.8%;
|
|
687
|
+
--bg-mesh-3: 238.7 83.5% 66.7%;
|
|
688
|
+
--bg-mesh-4: 258.3 89.5% 66.3%;
|
|
689
|
+
--bg-mesh-5: 263.5 67.4% 34.9%;
|
|
633
690
|
}
|
|
634
691
|
|
|
635
692
|
/* === KEYFRAMES === */
|