@moontra/moonui 6.16.0 → 6.17.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui",
3
- "version": "6.16.0",
3
+ "version": "6.17.0",
4
4
  "description": "Premium React component library with modern design and customization",
5
5
  "author": "MoonUI",
6
6
  "license": "MIT",
@@ -0,0 +1,95 @@
1
+ /**
2
+ * #354 — `--primary-subtle` token çifti ve kontrast değişmezi.
3
+ *
4
+ * BULGU: pro Sidebar'ın aktif öğesi `bg-primary/10 text-primary` kullanıyordu.
5
+ * Light temada bu bileşim **4.28:1** veriyor (WCAG AA metin için 4.5 ister) ve
6
+ * docs kabuğu bu Sidebar'ı kullandığı için ihlal HER sayfada basılıyordu.
7
+ * Dark tarafta `--primary` neredeyse beyaz olduğu için sorun yoktu (15.73:1).
8
+ *
9
+ * KÖK NEDEN: #313/#314/#323'te kurulan `--*-subtle` ailesi (yumuşak tint + koyu
10
+ * metin) `destructive/success/warning/info` için vardı ama **primary EKSİKTİ** —
11
+ * bu yüzden Sidebar ham `primary/10` kompozisyonuna düşmüştü.
12
+ *
13
+ * Bu test hem token'ların VARLIĞINI hem de KONTRAST oranlarını sabitler: değer
14
+ * değiştirilirse ve oran 4.5'in altına düşerse kırmızı olur.
15
+ */
16
+ import * as fs from 'fs'
17
+ import * as path from 'path'
18
+
19
+ const KOK = path.resolve(__dirname, '../../..')
20
+ const tokens = fs.readFileSync(path.join(KOK, 'styles/tokens.css'), 'utf8')
21
+ const preset = fs.readFileSync(path.resolve(KOK, '../tailwind-preset.js'), 'utf8')
22
+
23
+ /** "H S% L%" biçimindeki token değerini oku (light = :root, dark = .dark bloğu) */
24
+ function tokenOku(ad: string, blok: 'light' | 'dark'): string | null {
25
+ const kaynak =
26
+ blok === 'dark'
27
+ ? tokens.slice(tokens.indexOf('.dark'))
28
+ : tokens.slice(0, tokens.indexOf('.dark'))
29
+ return kaynak.match(new RegExp(`--${ad}:\\s*([^;]+);`))?.[1].trim() ?? null
30
+ }
31
+
32
+ function hslToRgb(h: number, s: number, l: number): [number, number, number] {
33
+ h /= 360
34
+ s /= 100
35
+ l /= 100
36
+ const f = (n: number) => {
37
+ const k = (n + h * 12) % 12
38
+ const a = s * Math.min(l, 1 - l)
39
+ return l - a * Math.max(-1, Math.min(k - 3, Math.min(9 - k, 1)))
40
+ }
41
+ return [Math.round(255 * f(0)), Math.round(255 * f(8)), Math.round(255 * f(4))]
42
+ }
43
+
44
+ function bagilParlaklik([r, g, b]: [number, number, number]): number {
45
+ const c = (v: number) => {
46
+ const x = v / 255
47
+ return x <= 0.03928 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4)
48
+ }
49
+ return 0.2126 * c(r) + 0.7152 * c(g) + 0.0722 * c(b)
50
+ }
51
+
52
+ function kontrast(a: string, b: string): number {
53
+ const ayrıştır = (v: string): [number, number, number] => {
54
+ const [h, s, l] = v.split(/\s+/).map((x) => parseFloat(x))
55
+ return hslToRgb(h, s, l)
56
+ }
57
+ const la = bagilParlaklik(ayrıştır(a))
58
+ const lb = bagilParlaklik(ayrıştır(b))
59
+ const [hi, lo] = la > lb ? [la, lb] : [lb, la]
60
+ return (hi + 0.05) / (lo + 0.05)
61
+ }
62
+
63
+ describe('#354 --primary-subtle token çifti', () => {
64
+ it('hesaplayıcı DOĞRU — bilinen bir çift beklenen oranı veriyor', () => {
65
+ // Sessiz-yeşil koruması: kontrast fonksiyonu bozulursa aşağıdaki testler
66
+ // anlamsız sayılarla yeşil geçebilir. `--info-subtle` çifti tokens.css'te
67
+ // 9.52:1 diye belgelenmiş; hesaplayıcı onu yeniden üretmeli.
68
+ const oran = kontrast(tokenOku('info-subtle', 'light')!, tokenOku('info-subtle-foreground', 'light')!)
69
+ expect(oran).toBeGreaterThan(9.3)
70
+ expect(oran).toBeLessThan(9.7)
71
+ })
72
+
73
+ it.each(['light', 'dark'] as const)('%s temada token çifti TANIMLI', (blok) => {
74
+ expect(tokenOku('primary-subtle', blok)).toBeTruthy()
75
+ expect(tokenOku('primary-subtle-foreground', blok)).toBeTruthy()
76
+ })
77
+
78
+ it.each(['light', 'dark'] as const)('%s temada kontrast WCAG AA (4.5:1) geçiyor', (blok) => {
79
+ const oran = kontrast(tokenOku('primary-subtle', blok)!, tokenOku('primary-subtle-foreground', blok)!)
80
+ expect(oran).toBeGreaterThanOrEqual(4.5)
81
+ })
82
+
83
+ it('light zemin, bugünkü `primary/10` görünümünü KORUYOR', () => {
84
+ // Zemin değişirse aktif öğenin görünümü değişir; bu bilinçli bir karar olmalı.
85
+ // #e7f0fe = beyaz üstüne %10 primary.
86
+ expect(tokenOku('primary-subtle', 'light')).toBe('217 92% 95%')
87
+ })
88
+
89
+ it('preset sınıfları ÜRETİYOR (token tanımlamak yetmez)', () => {
90
+ // Bu oturumda `theme.extend.borderColor`ın nested renkleri GÖLGELEDİĞİ ve
91
+ // sınıfın sessizce hiç CSS üretmediği görülmüştü (#313/#314/#323).
92
+ expect(preset).toContain('hsl(var(--primary-subtle) / <alpha-value>)')
93
+ expect(preset).toContain('hsl(var(--primary-subtle-foreground) / <alpha-value>)')
94
+ })
95
+ })
@@ -199,6 +199,17 @@
199
199
  --info-subtle: 214 100% 97%;
200
200
  --info-subtle-foreground: 224 64% 33%; /* 9.52:1 */
201
201
 
202
+ /* #354: `primary` ailesi bu listede EKSİKTİ. Pro Sidebar'ın aktif öğesi
203
+ "primary metin + primary/10 zemin" deseni kullanıyordu; light temada bu
204
+ 4.28:1 veriyor (gereken 4.5) — yani docs kabuğu her sayfada bir WCAG AA
205
+ ihlali basıyordu. Dark tarafta `--primary` neredeyse beyaz olduğu için
206
+ sorun yoktu (15.73:1, ölçüldü).
207
+
208
+ Zemin, bugünkü `primary/10` bileşiminin BİREBİR HSL karşılığı (beyaz üstüne
209
+ %10 primary = #e7f0fe) → görünüm DEĞİŞMEZ, yalnız metin koyulaşır. */
210
+ --primary-subtle: 217 92% 95%;
211
+ --primary-subtle-foreground: 217.2 91.2% 40%; /* 6.21:1 */
212
+
202
213
  --primary-50: 240 249 255;
203
214
 
204
215
  /* Tailwind preset'i rounded-lg/md/sm'yi var(--radius)'a bagliyor.
@@ -474,6 +485,12 @@
474
485
  --warning-subtle-foreground: 34 100% 92%; /* 14.43:1 */
475
486
  --info-subtle: 217 80% 13%;
476
487
  --info-subtle-foreground: 214 95% 93%; /* 14.11:1 */
488
+
489
+ /* #354: koyu temada mevcut görünüm KORUNUYOR — bugünkü bileşimin birebir
490
+ karşılığı (near-white/10 near-black üstüne). Dark zaten geçiyordu; buradaki
491
+ amaç token ailesini tamamlamak, dark'ın rengini değiştirmek değil. */
492
+ --primary-subtle: 225 18% 13%;
493
+ --primary-subtle-foreground: 210 40% 98%; /* 15.73:1 */
477
494
  --border: 216 34% 17%;
478
495
  /* #284: koyu temada form kontrolü kenarlığı 1.36 idi -> 40% ile ~3.1.
479
496
  Not: --input switch.tsx:27'de kapalı track ZEMİNİ olarak da kullanılıyor;
@@ -76,6 +76,13 @@ module.exports = {
76
76
  primary: {
77
77
  DEFAULT: "hsl(var(--primary) / <alpha-value>)",
78
78
  foreground: "hsl(var(--primary-foreground) / <alpha-value>)",
79
+ // #354: `primary` yumuşak-ton yüzeyi — `bg-primary-subtle` +
80
+ // `text-primary-subtle-foreground`. Aile destructive/success/warning/
81
+ // info için vardı, primary EKSİKTİ ve pro Sidebar'ın aktif öğesi bu
82
+ // yüzden ham `primary/10` kompozisyonuna düşüp light temada 4.28:1
83
+ // veriyordu.
84
+ subtle: "hsl(var(--primary-subtle) / <alpha-value>)",
85
+ "subtle-foreground": "hsl(var(--primary-subtle-foreground) / <alpha-value>)",
79
86
  },
80
87
  secondary: {
81
88
  DEFAULT: "hsl(var(--secondary) / <alpha-value>)",