@moontra/moonui 6.24.0 → 6.26.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.
Files changed (56) hide show
  1. package/dist/cdn/moonui.css +2 -2
  2. package/dist/cdn/moonui.esm.js +12 -12
  3. package/dist/cdn/moonui.global.js +12 -12
  4. package/dist/index.d.mts +24 -6
  5. package/dist/index.d.ts +24 -6
  6. package/dist/index.js +436 -93
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +437 -95
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +1 -1
  11. package/src/__tests__/issue-544-kontrast.test.tsx +153 -145
  12. package/src/__tests__/issue-645-overlay-tab-focus.test.tsx +262 -0
  13. package/src/__tests__/issue-646-dark-scope-override.test.tsx +297 -0
  14. package/src/__tests__/issue-661-a11y.test.tsx +113 -0
  15. package/src/__tests__/issue-661-token-kontrast.test.tsx +82 -0
  16. package/src/components/ui/__tests__/accent-foreground-contrast.test.ts +197 -0
  17. package/src/components/ui/__tests__/accordion.test.tsx +6 -4
  18. package/src/components/ui/__tests__/alert.test.tsx +4 -1
  19. package/src/components/ui/__tests__/button.test.tsx +6 -1
  20. package/src/components/ui/__tests__/dark-token-contrast.test.ts +18 -18
  21. package/src/components/ui/__tests__/heading-level-policy.test.tsx +4 -4
  22. package/src/components/ui/__tests__/issue-643-card-token-parite.test.tsx +113 -0
  23. package/src/components/ui/__tests__/issue-649-button-aschild.test.tsx +199 -0
  24. package/src/components/ui/__tests__/issue-664-separator-dekoratif-rol.test.tsx +41 -0
  25. package/src/components/ui/__tests__/preset-color-shadowing.test.ts +10 -10
  26. package/src/components/ui/__tests__/primary-subtle-token.test.ts +7 -7
  27. package/src/components/ui/__tests__/progress-secondary-contrast.test.ts +38 -38
  28. package/src/components/ui/__tests__/progress-warning-error-contrast.test.ts +64 -64
  29. package/src/components/ui/__tests__/quality-group-de.test.tsx +2 -2
  30. package/src/components/ui/__tests__/responsive-color-invariance.test.ts +20 -20
  31. package/src/components/ui/__tests__/select.test.tsx +6 -1
  32. package/src/components/ui/__tests__/semantic-token-usage.test.ts +23 -23
  33. package/src/components/ui/__tests__/size-scale-convention.test.ts +10 -10
  34. package/src/components/ui/__tests__/slider-accent-contrast.test.ts +142 -136
  35. package/src/components/ui/__tests__/slider-secondary-contrast.test.ts +60 -60
  36. package/src/components/ui/__tests__/slider-warning-error-contrast.test.ts +100 -100
  37. package/src/components/ui/__tests__/switch-variant-contrast.test.tsx +103 -103
  38. package/src/components/ui/__tests__/tooltip.test.tsx +122 -0
  39. package/src/components/ui/accordion.tsx +16 -3
  40. package/src/components/ui/alert.tsx +1 -1
  41. package/src/components/ui/badge.tsx +12 -1
  42. package/src/components/ui/button.tsx +95 -24
  43. package/src/components/ui/card.tsx +59 -5
  44. package/src/components/ui/dropdown-menu.tsx +99 -5
  45. package/src/components/ui/file-upload.tsx +4 -0
  46. package/src/components/ui/index.ts +4 -1
  47. package/src/components/ui/popover-pro.tsx +41 -0
  48. package/src/components/ui/popover.tsx +162 -7
  49. package/src/components/ui/rating.tsx +24 -2
  50. package/src/components/ui/select.tsx +4 -4
  51. package/src/components/ui/simple-editor.tsx +3 -18
  52. package/src/components/ui/tabs.tsx +16 -1
  53. package/src/components/ui/textarea.tsx +6 -1
  54. package/src/components/ui/toast.tsx +17 -2
  55. package/src/components/ui/tooltip.tsx +154 -2
  56. package/src/styles/tokens.css +34 -2
@@ -44,12 +44,12 @@ const KOK = path.resolve(__dirname, '../../..')
44
44
  const tokens = fs.readFileSync(path.join(KOK, 'styles/tokens.css'), 'utf8')
45
45
 
46
46
  /** "H S% L%" biçimindeki token değerini oku (light = :root, dark = .dark bloğu) */
47
- function tokenOku(ad: string, blok: 'light' | 'dark'): string | null {
48
- const kaynak =
47
+ function tokenOku(name: string, blok: 'light' | 'dark'): string | null {
48
+ const source =
49
49
  blok === 'dark'
50
50
  ? tokens.slice(tokens.indexOf('.dark'))
51
51
  : tokens.slice(0, tokens.indexOf('.dark'))
52
- return kaynak.match(new RegExp(`--${ad}:\\s*([^;]+);`))?.[1].trim() ?? null
52
+ return source.match(new RegExp(`--${name}:\\s*([^;]+);`))?.[1].trim() ?? null
53
53
  }
54
54
 
55
55
  function hslToRgb(h: number, s: number, l: number): [number, number, number] {
@@ -79,7 +79,7 @@ const rgbTokenRgb = (v: string): [number, number, number] => {
79
79
  return [p[0], p[1], p[2]]
80
80
  }
81
81
 
82
- function bagilParlaklik([r, g, b]: [number, number, number]): number {
82
+ function relativeLuminance([r, g, b]: [number, number, number]): number {
83
83
  const c = (v: number) => {
84
84
  const x = v / 255
85
85
  return x <= 0.03928 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4)
@@ -88,8 +88,8 @@ function bagilParlaklik([r, g, b]: [number, number, number]): number {
88
88
  }
89
89
 
90
90
  function rgbKontrast(a: [number, number, number], b: [number, number, number]): number {
91
- const la = bagilParlaklik(a)
92
- const lb = bagilParlaklik(b)
91
+ const la = relativeLuminance(a)
92
+ const lb = relativeLuminance(b)
93
93
  const [hi, lo] = la > lb ? [la, lb] : [lb, la]
94
94
  return (hi + 0.05) / (lo + 0.05)
95
95
  }
@@ -98,12 +98,12 @@ function rgbKontrast(a: [number, number, number], b: [number, number, number]):
98
98
  function alfaBileske(
99
99
  ust: [number, number, number],
100
100
  alfa: number,
101
- zemin: [number, number, number]
101
+ background: [number, number, number]
102
102
  ): [number, number, number] {
103
103
  return [
104
- Math.round(alfa * ust[0] + (1 - alfa) * zemin[0]),
105
- Math.round(alfa * ust[1] + (1 - alfa) * zemin[1]),
106
- Math.round(alfa * ust[2] + (1 - alfa) * zemin[2]),
104
+ Math.round(alfa * ust[0] + (1 - alfa) * background[0]),
105
+ Math.round(alfa * ust[1] + (1 - alfa) * background[1]),
106
+ Math.round(alfa * ust[2] + (1 - alfa) * background[2]),
107
107
  ]
108
108
  }
109
109
 
@@ -112,23 +112,23 @@ function alfaBileske(
112
112
  * #284/#368 konvansiyonu: kontrast, --background'ın yanında bu gerçek yüzeye göre
113
113
  * de ölçülür. Bu bulguda DARBOĞAZ: en düşük dark oranlarını o veriyor.
114
114
  */
115
- const KART_GERCEK_DARK: [number, number, number] = [17, 24, 39]
115
+ const CARD_ACTUAL_DARK: [number, number, number] = [17, 24, 39]
116
116
 
117
117
  const AILELER = ['warning', 'error'] as const
118
118
  type Aile = (typeof AILELER)[number]
119
119
 
120
120
  /** Semantik token'ın ilgili temadaki değeri — `.dark` ezmesi YOKSA light'a düşer */
121
- function semantikRgb(aile: Aile, blok: 'light' | 'dark'): [number, number, number] {
121
+ function semanticRgb(aile: Aile, blok: 'light' | 'dark'): [number, number, number] {
122
122
  return hslTokenRgb(tokenOku(aile, blok) ?? tokenOku(aile, 'light')!)
123
123
  }
124
124
 
125
125
  /** O temada slider'ın oturabileceği tüm zeminler */
126
- function zeminler(blok: 'light' | 'dark'): Array<[string, [number, number, number]]> {
126
+ function backgrounds(blok: 'light' | 'dark'): Array<[string, [number, number, number]]> {
127
127
  const z: Array<[string, [number, number, number]]> = [
128
128
  ['--background', hslTokenRgb(tokenOku('background', blok)!)],
129
129
  ['--card', hslTokenRgb(tokenOku('card', blok)!)],
130
130
  ]
131
- if (blok === 'dark') z.push(['gerçek kart #111827', KART_GERCEK_DARK])
131
+ if (blok === 'dark') z.push(['gerçek kart #111827', CARD_ACTUAL_DARK])
132
132
  return z
133
133
  }
134
134
 
@@ -136,30 +136,30 @@ function zeminler(blok: 'light' | 'dark'): Array<[string, [number, number, numbe
136
136
  // PR #440'ın dersi: ölçümü `-700` VARSAYIMINA göre yaparsan, biri değeri eskiye
137
137
  // döndürdüğünde kriter testleri yeşil kalır (boş-yeşil). Bu yüzden renkler
138
138
  // slider.tsx'in O ANKİ CVA sınıf dizgelerinden çözülür.
139
- const kaynak = fs.readFileSync(path.join(KOK, 'components/ui/slider.tsx'), 'utf8')
140
- const iTrack = kaynak.indexOf('sliderTrackVariants')
141
- const iRange = kaynak.indexOf('sliderRangeVariants')
142
- const iThumb = kaynak.indexOf('sliderThumbVariants')
143
- const iSon = kaynak.indexOf('SliderBaseProps')
144
- const TRACK_BLOK = kaynak.slice(iTrack, iRange)
145
- const RANGE_BLOK = kaynak.slice(iRange, iThumb)
146
- const THUMB_BLOK = kaynak.slice(iThumb, iSon)
139
+ const source = fs.readFileSync(path.join(KOK, 'components/ui/slider.tsx'), 'utf8')
140
+ const iTrack = source.indexOf('sliderTrackVariants')
141
+ const iRange = source.indexOf('sliderRangeVariants')
142
+ const iThumb = source.indexOf('sliderThumbVariants')
143
+ const iSon = source.indexOf('SliderBaseProps')
144
+ const TRACK_BLOK = source.slice(iTrack, iRange)
145
+ const RANGE_BLOK = source.slice(iRange, iThumb)
146
+ const THUMB_BLOK = source.slice(iThumb, iSon)
147
147
 
148
148
  /** CVA bloğundan `<aile>: "<sınıflar>"` değerini oku */
149
- function varyantSinifi(blok: string, aile: string): string {
149
+ function variantClass(blok: string, aile: string): string {
150
150
  const m = blok.match(new RegExp(`\\n\\s*${aile}:\\s*"([^"]+)"`))
151
151
  if (!m) throw new Error(`${aile} varyantı bulunamadı`)
152
152
  return m[1]
153
153
  }
154
154
 
155
155
  /** Tek bir Tailwind sınıfını renge çevir (arbitrary skala VEYA semantik token) */
156
- function sinifRengi(sinif: string, blok: 'light' | 'dark'): [number, number, number] {
157
- const skala = sinif.match(/^(?:bg|border)-\[rgb\(var\(--([a-z0-9-]+)\)\)\]$/)
158
- if (skala) return rgbTokenRgb(tokenOku(skala[1], 'light')!) // skala yalnız :root'ta
159
- const semantik = sinif.match(/^(?:bg|border)-([a-z-]+)$/)
160
- if (semantik)
161
- return hslTokenRgb(tokenOku(semantik[1], blok) ?? tokenOku(semantik[1], 'light')!)
162
- throw new Error(`çözülemeyen sınıf: ${sinif}`)
156
+ function classColor(cls: string, blok: 'light' | 'dark'): [number, number, number] {
157
+ const scale = cls.match(/^(?:bg|border)-\[rgb\(var\(--([a-z0-9-]+)\)\)\]$/)
158
+ if (scale) return rgbTokenRgb(tokenOku(scale[1], 'light')!) // skala yalnız :root'ta
159
+ const semantic = cls.match(/^(?:bg|border)-([a-z-]+)$/)
160
+ if (semantic)
161
+ return hslTokenRgb(tokenOku(semantic[1], blok) ?? tokenOku(semantic[1], 'light')!)
162
+ throw new Error(`çözülemeyen sınıf: ${cls}`)
163
163
  }
164
164
 
165
165
  /**
@@ -167,40 +167,40 @@ function sinifRengi(sinif: string, blok: 'light' | 'dark'): [number, number, num
167
167
  * `dark:` önekli sınıf dark temada kazanır; `onek` ile eksen seçilir
168
168
  * (thumb dizgesi `border-*` yanında `bg-background` da taşır).
169
169
  */
170
- function uygulananRenk(
170
+ function appliedColor(
171
171
  cvaBlok: string,
172
172
  aile: Aile,
173
173
  onek: 'bg' | 'border',
174
174
  blok: 'light' | 'dark'
175
175
  ): [number, number, number] {
176
- const siniflar = varyantSinifi(cvaBlok, aile)
176
+ const classNames = variantClass(cvaBlok, aile)
177
177
  .split(/\s+/)
178
178
  .filter((s) => s.replace(/^dark:/, '').startsWith(`${onek}-`))
179
- const darkSinif = siniflar.find((s) => s.startsWith('dark:'))?.slice('dark:'.length)
180
- const lightSinif = siniflar.find((s) => !s.startsWith('dark:'))
181
- if (!lightSinif) throw new Error(`${aile}/${onek}: temel (light) sınıf yok`)
182
- return sinifRengi(blok === 'dark' ? darkSinif ?? lightSinif : lightSinif, blok)
179
+ const darkClass = classNames.find((s) => s.startsWith('dark:'))?.slice('dark:'.length)
180
+ const lightClass = classNames.find((s) => !s.startsWith('dark:'))
181
+ if (!lightClass) throw new Error(`${aile}/${onek}: temel (light) sınıf yok`)
182
+ return classColor(blok === 'dark' ? darkClass ?? lightClass : lightClass, blok)
183
183
  }
184
184
 
185
185
  const rangeRengi = (aile: Aile, blok: 'light' | 'dark') =>
186
- uygulananRenk(RANGE_BLOK, aile, 'bg', blok)
187
- const thumbKenarRengi = (aile: Aile, blok: 'light' | 'dark') =>
188
- uygulananRenk(THUMB_BLOK, aile, 'border', blok)
186
+ appliedColor(RANGE_BLOK, aile, 'bg', blok)
187
+ const thumbBorderColor = (aile: Aile, blok: 'light' | 'dark') =>
188
+ appliedColor(THUMB_BLOK, aile, 'border', blok)
189
189
 
190
190
  /** Track'in her zemin üstündeki bileşkesi — alfa da KAYNAKTAN okunur */
191
191
  function trackler(aile: Aile, blok: 'light' | 'dark') {
192
- const sinif = varyantSinifi(TRACK_BLOK, aile)
193
- const m = sinif.match(/^bg-([a-z-]+)\/(\d+)$/)
194
- if (!m) throw new Error(`track sınıfı çözülemedi: ${sinif}`)
195
- const taban = hslTokenRgb(tokenOku(m[1], blok) ?? tokenOku(m[1], 'light')!)
192
+ const cls = variantClass(TRACK_BLOK, aile)
193
+ const m = cls.match(/^bg-([a-z-]+)\/(\d+)$/)
194
+ if (!m) throw new Error(`track sınıfı çözülemedi: ${cls}`)
195
+ const base = hslTokenRgb(tokenOku(m[1], blok) ?? tokenOku(m[1], 'light')!)
196
196
  const alfa = Number(m[2]) / 100
197
- return zeminler(blok).map(([ad, z]) => [ad, alfaBileske(taban, alfa, z)] as const)
197
+ return backgrounds(blok).map(([name, z]) => [name, alfaBileske(base, alfa, z)] as const)
198
198
  }
199
199
 
200
200
  const KADEMELER = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]
201
201
 
202
202
  /** Slider DOM'u: kök > .moonui-theme > track > range; thumb'lar track'in KARDEŞİ */
203
- function parcalar(container: HTMLElement) {
203
+ function parts(container: HTMLElement) {
204
204
  const kabuk = container.querySelector('.moonui-theme') as HTMLElement
205
205
  expect(kabuk).not.toBeNull()
206
206
  const track = kabuk.firstElementChild as HTMLElement
@@ -226,8 +226,8 @@ describe('#442 slider warning/error — hesaplayıcı çapası', () => {
226
226
  it('hesaplayıcı, denetimin TARAYICIDA ölçtüğü renkleri birebir üretiyor', () => {
227
227
  // Çapraz doğrulama (#424/#442 gövdesindeki gerçek tarayıcı ölçümleri): model
228
228
  // bunları tutturamıyorsa aşağıdaki tüm oranlar anlamsızdır.
229
- expect(semantikRgb('warning', 'light')).toEqual([245, 159, 10])
230
- expect(semantikRgb('error', 'light')).toEqual([239, 67, 67])
229
+ expect(semanticRgb('warning', 'light')).toEqual([245, 159, 10])
230
+ expect(semanticRgb('error', 'light')).toEqual([239, 67, 67])
231
231
  expect(trackler('warning', 'light')[0][1]).toEqual([253, 236, 206])
232
232
  expect(trackler('error', 'light')[0][1]).toEqual([252, 217, 217])
233
233
  })
@@ -239,7 +239,7 @@ describe('#442 kök neden: --warning ve --error `.dark` bloğunda EZİLMİYOR',
239
239
  // `--error` eklerse burası kırmızı olur ve component düzeyindeki `dark:`
240
240
  // telafisinin yeniden ölçülmesi gerektiğini söyler.
241
241
  expect(tokenOku(aile, 'dark')).toBeNull()
242
- expect(semantikRgb(aile, 'light')).toEqual(semantikRgb(aile, 'dark'))
242
+ expect(semanticRgb(aile, 'light')).toEqual(semanticRgb(aile, 'dark'))
243
243
  })
244
244
 
245
245
  it('karşıtlık: --success tema-uyarlanabilir olduğu İÇİN eşiği geçiyor', () => {
@@ -262,13 +262,13 @@ describe('#442 kök neden: --warning ve --error `.dark` bloğunda EZİLMİYOR',
262
262
  // Hesap, track'in/tutamacın altındaki yüzeyin --background/--card olduğunu
263
263
  // VARSAYAR. Biri `.moonui-theme`i token kapsamına çevirirse o varsayım
264
264
  // sessizce yanlışlanır — o an burası kırmızı olur (#389 deseni).
265
- const stilDizini = path.join(KOK, 'styles')
266
- const stiller = fs
267
- .readdirSync(stilDizini)
265
+ const styleDir = path.join(KOK, 'styles')
266
+ const styles = fs
267
+ .readdirSync(styleDir)
268
268
  .filter((f) => f.endsWith('.css'))
269
- .map((f) => fs.readFileSync(path.join(stilDizini, f), 'utf8'))
269
+ .map((f) => fs.readFileSync(path.join(styleDir, f), 'utf8'))
270
270
  .join('\n')
271
- expect(stiller).not.toMatch(/\.moonui-theme[^{]*\{[^}]*--(warning|error|background|card)/)
271
+ expect(styles).not.toMatch(/\.moonui-theme[^{]*\{[^}]*--(warning|error|background|card)/)
272
272
  })
273
273
  })
274
274
 
@@ -276,17 +276,17 @@ describe('#442 kaynak sözleşmesi — slider.tsx', () => {
276
276
  it.each(AILELER)('track %s sınıfı `/20` alfasını KORUYOR (yedi varyantın ortak deseni)', (aile) => {
277
277
  // Alternatif öneri track'i `/10`'a çekmekti; kabul edilmedi (track↔zemin
278
278
  // ayrımını zayıflatır, ortak konvansiyonu bozar). Burası o kararı kilitler.
279
- expect(varyantSinifi(TRACK_BLOK, aile)).toBe(`bg-${aile}/20`)
279
+ expect(variantClass(TRACK_BLOK, aile)).toBe(`bg-${aile}/20`)
280
280
  })
281
281
 
282
282
  it.each(AILELER)('EKSEN A: range %s light\'ta -700, dark\'ta semantik token', (aile) => {
283
- expect(varyantSinifi(RANGE_BLOK, aile)).toBe(
283
+ expect(variantClass(RANGE_BLOK, aile)).toBe(
284
284
  `bg-[rgb(var(--${aile}-700))] dark:bg-${aile}`
285
285
  )
286
286
  })
287
287
 
288
288
  it.each(AILELER)('EKSEN B: thumb %s kenarlığı light\'ta -700, dark\'ta semantik token', (aile) => {
289
- expect(varyantSinifi(THUMB_BLOK, aile)).toBe(
289
+ expect(variantClass(THUMB_BLOK, aile)).toBe(
290
290
  `border-[rgb(var(--${aile}-700))] dark:border-${aile} bg-background`
291
291
  )
292
292
  })
@@ -295,8 +295,8 @@ describe('#442 kaynak sözleşmesi — slider.tsx', () => {
295
295
  // Gereksiz değişiklik yeni regresyon riski. Ölçüm: success A light 3.73 /
296
296
  // dark 4.83 · primary A light 3.71 / dark 11.24 — ikisi de ≥3.
297
297
  for (const aile of ['primary', 'success'] as const) {
298
- expect(varyantSinifi(RANGE_BLOK, aile)).toBe(`bg-${aile}`)
299
- expect(varyantSinifi(THUMB_BLOK, aile)).toBe(`border-${aile} bg-background`)
298
+ expect(variantClass(RANGE_BLOK, aile)).toBe(`bg-${aile}`)
299
+ expect(variantClass(THUMB_BLOK, aile)).toBe(`border-${aile} bg-background`)
300
300
  }
301
301
  })
302
302
  })
@@ -306,7 +306,7 @@ describe('#442 render sözleşmesi — <Slider />', () => {
306
306
  const { container } = render(
307
307
  React.createElement(Slider, { trackVariant: aile, rangeVariant: aile })
308
308
  )
309
- const { track, range } = parcalar(container)
309
+ const { track, range } = parts(container)
310
310
  expect(track).toHaveClass(`bg-${aile}/20`)
311
311
  expect(range.className).toContain(`bg-[rgb(var(--${aile}-700))]`)
312
312
  expect(range.className).toContain(`dark:bg-${aile}`)
@@ -316,7 +316,7 @@ describe('#442 render sözleşmesi — <Slider />', () => {
316
316
 
317
317
  it.each(AILELER)('%s: thumb kenarlığı yeni ifadeyle iniyor, dolgusu bg-background kalıyor', (aile) => {
318
318
  const { container } = render(React.createElement(Slider, { thumbVariant: aile }))
319
- const { thumb } = parcalar(container)
319
+ const { thumb } = parts(container)
320
320
  expect(thumb.className).toContain(`border-[rgb(var(--${aile}-700))]`)
321
321
  expect(thumb.className).toContain(`dark:border-${aile}`)
322
322
  expect(thumb.className).toContain('bg-background')
@@ -327,7 +327,7 @@ describe('#442 render sözleşmesi — <Slider />', () => {
327
327
  // `trackVariant || thumbVariant || "default"` ve `rangeVariant || thumbVariant ||
328
328
  // "primary"` düşüşleri değişmedi; en yaygın kullanım bu yoldan geçer.
329
329
  const { container } = render(React.createElement(Slider, { thumbVariant: aile }))
330
- const { track, range, thumb } = parcalar(container)
330
+ const { track, range, thumb } = parts(container)
331
331
  expect(track).toHaveClass(`bg-${aile}/20`)
332
332
  expect(range.className).toContain(`bg-[rgb(var(--${aile}-700))]`)
333
333
  expect(thumb.className).toContain(`border-[rgb(var(--${aile}-700))]`)
@@ -337,7 +337,7 @@ describe('#442 render sözleşmesi — <Slider />', () => {
337
337
  const { container } = render(
338
338
  React.createElement(Slider, { thumbVariant: 'warning', rangeVariant: 'success' })
339
339
  )
340
- const { range, thumb } = parcalar(container)
340
+ const { range, thumb } = parts(container)
341
341
  expect(range.className).toContain('bg-success')
342
342
  expect(range.className).not.toContain('--warning-700')
343
343
  // Eksenler bağımsız: tutamaç kendi varyantını korur.
@@ -348,7 +348,7 @@ describe('#442 render sözleşmesi — <Slider />', () => {
348
348
  const { container } = render(
349
349
  React.createElement(Slider, { rangeVariant: 'primary', thumbVariant: 'primary' })
350
350
  )
351
- const { range, thumb } = parcalar(container)
351
+ const { range, thumb } = parts(container)
352
352
  expect(range.className).toContain('bg-primary')
353
353
  expect(thumb.className).toContain('border-primary')
354
354
  expect(range.className).not.toContain('700')
@@ -362,13 +362,13 @@ describe.each(AILELER)('#442 %s — kabul kriteri ≥3:1 (WCAG 1.4.11)', (aile)
362
362
  (blok) => {
363
363
  // Ölçülen: warning light 4.235 · dark 6.97 (docs kartı 5.77)
364
364
  // error light 4.950 · dark 4.46 (docs kartı 3.82)
365
- const dolgu = rangeRengi(aile, blok)
366
- for (const [ad, track] of trackler(aile, blok)) {
367
- const oran = rgbKontrast(dolgu, track)
368
- expect({ eksen: 'A', zemin: ad, gecti: oran >= 3.0 }).toEqual({
369
- eksen: 'A',
370
- zemin: ad,
371
- gecti: true,
365
+ const fill = rangeRengi(aile, blok)
366
+ for (const [name, track] of trackler(aile, blok)) {
367
+ const oran = rgbKontrast(fill, track)
368
+ expect({ axis: 'A', background: name, didPass: oran >= 3.0 }).toEqual({
369
+ axis: 'A',
370
+ background: name,
371
+ didPass: true,
372
372
  })
373
373
  }
374
374
  }
@@ -379,13 +379,13 @@ describe.each(AILELER)('#442 %s — kabul kriteri ≥3:1 (WCAG 1.4.11)', (aile)
379
379
  (blok) => {
380
380
  // Ölçülen: warning light 4.923 · dark 9.45 (docs kartı 8.32)
381
381
  // error light 6.470 · dark 5.33 (docs kartı 4.69)
382
- const kenar = thumbKenarRengi(aile, blok)
383
- for (const [ad, zemin] of zeminler(blok)) {
384
- const oran = rgbKontrast(kenar, zemin)
385
- expect({ eksen: 'B', zemin: ad, gecti: oran >= 3.0 }).toEqual({
386
- eksen: 'B',
387
- zemin: ad,
388
- gecti: true,
382
+ const border = thumbBorderColor(aile, blok)
383
+ for (const [name, background] of backgrounds(blok)) {
384
+ const oran = rgbKontrast(border, background)
385
+ expect({ axis: 'B', background: name, didPass: oran >= 3.0 }).toEqual({
386
+ axis: 'B',
387
+ background: name,
388
+ didPass: true,
389
389
  })
390
390
  }
391
391
  }
@@ -393,19 +393,19 @@ describe.each(AILELER)('#442 %s — kabul kriteri ≥3:1 (WCAG 1.4.11)', (aile)
393
393
 
394
394
  it('ESKİ range (semantik token) LIGHT temada başarısızdı — bug’ın belgesi', () => {
395
395
  // warning 1.835 · error 2.893. Düzeltmenin GEREKLİLİĞİNİ sabitler.
396
- const eski = semantikRgb(aile, 'light')
396
+ const old = semanticRgb(aile, 'light')
397
397
  for (const [, track] of trackler(aile, 'light')) {
398
- expect(rgbKontrast(eski, track)).toBeLessThan(3.0)
398
+ expect(rgbKontrast(old, track)).toBeLessThan(3.0)
399
399
  }
400
400
  })
401
401
 
402
402
  it('DARK render DEĞİŞMEDİ — iki eksende de eski semantik token uygulanıyor', () => {
403
403
  // Bulgu light'a özgüydü; düzeltmenin dark'ta hiçbir şeyi oynatmaması bilinçli
404
404
  // bir kısıt (regresyon yüzeyini sıfıra indirir).
405
- expect(rangeRengi(aile, 'dark')).toEqual(semantikRgb(aile, 'dark'))
406
- expect(thumbKenarRengi(aile, 'dark')).toEqual(semantikRgb(aile, 'dark'))
405
+ expect(rangeRengi(aile, 'dark')).toEqual(semanticRgb(aile, 'dark'))
406
+ expect(thumbBorderColor(aile, 'dark')).toEqual(semanticRgb(aile, 'dark'))
407
407
  for (const [, track] of trackler(aile, 'dark')) {
408
- expect(rgbKontrast(semantikRgb(aile, 'dark'), track)).toBeGreaterThanOrEqual(3.0)
408
+ expect(rgbKontrast(semanticRgb(aile, 'dark'), track)).toBeGreaterThanOrEqual(3.0)
409
409
  }
410
410
  })
411
411
 
@@ -414,29 +414,29 @@ describe.each(AILELER)('#442 %s — kabul kriteri ≥3:1 (WCAG 1.4.11)', (aile)
414
414
  // ve `error` tutamacının NEDEN değiştirildiğinin kilidi: kontrastı zaten
415
415
  // geçiyordu (3.781), ama range light'ta -700'e inince kenarlığı `border-error`
416
416
  // bırakmak iki-tonlu bir görünüm üretirdi.
417
- expect(thumbKenarRengi(aile, 'light')).toEqual(rangeRengi(aile, 'light'))
418
- expect(thumbKenarRengi(aile, 'dark')).toEqual(rangeRengi(aile, 'dark'))
417
+ expect(thumbBorderColor(aile, 'light')).toEqual(rangeRengi(aile, 'light'))
418
+ expect(thumbBorderColor(aile, 'dark')).toEqual(rangeRengi(aile, 'dark'))
419
419
  })
420
420
  })
421
421
 
422
422
  describe('#442 eksen B — ailelerin başlangıç durumu FARKLIYDI (kapsam kararının belgesi)', () => {
423
423
  it('ESKİ thumb kenarlığı: warning LIGHT\'ta eşiğin ALTINDAYDI (2.133)', () => {
424
- const eski = semantikRgb('warning', 'light')
425
- for (const [, zemin] of zeminler('light')) {
426
- expect(rgbKontrast(eski, zemin)).toBeLessThan(3.0)
424
+ const old = semanticRgb('warning', 'light')
425
+ for (const [, background] of backgrounds('light')) {
426
+ expect(rgbKontrast(old, background)).toBeLessThan(3.0)
427
427
  }
428
428
  })
429
429
 
430
430
  it('ESKİ thumb kenarlığı: error LIGHT\'ta zaten geçiyordu (3.781) — değişim gerekçesi tutarlılık', () => {
431
431
  // Dürüst kayıt: `error` tutamacı bir kontrast BUG'ı değildi. Aynı ifadeye
432
432
  // çekilmesinin sebebi tek-renk tutarlılığı; ölçüm de düşmedi, yükseldi.
433
- const eski = semantikRgb('error', 'light')
434
- for (const [, zemin] of zeminler('light')) {
435
- expect(rgbKontrast(eski, zemin)).toBeGreaterThanOrEqual(3.0)
433
+ const old = semanticRgb('error', 'light')
434
+ for (const [, background] of backgrounds('light')) {
435
+ expect(rgbKontrast(old, background)).toBeGreaterThanOrEqual(3.0)
436
436
  }
437
- const yeni = thumbKenarRengi('error', 'light')
438
- expect(rgbKontrast(yeni, zeminler('light')[0][1])).toBeGreaterThan(
439
- rgbKontrast(eski, zeminler('light')[0][1])
437
+ const yeni = thumbBorderColor('error', 'light')
438
+ expect(rgbKontrast(yeni, backgrounds('light')[0][1])).toBeGreaterThan(
439
+ rgbKontrast(old, backgrounds('light')[0][1])
440
440
  )
441
441
  })
442
442
  })
@@ -446,7 +446,7 @@ describe('#442 seçim gerekçesi — reddedilen alternatifler', () => {
446
446
  // Issue gövdesinin uyardığı refleks. -700 kademesi dark track'e karşı gerçek
447
447
  // docs kartı zemininde eşiğin ALTINDA: warning 2.499 · error 2.232.
448
448
  const k700 = rgbTokenRgb(tokenOku(`${aile}-700`, 'light')!)
449
- const docsTrack = trackler(aile, 'dark').find(([ad]) => ad === 'gerçek kart #111827')![1]
449
+ const docsTrack = trackler(aile, 'dark').find(([name]) => name === 'gerçek kart #111827')![1]
450
450
  expect(rgbKontrast(k700, docsTrack)).toBeLessThan(3.0)
451
451
  })
452
452
 
@@ -457,22 +457,22 @@ describe('#442 seçim gerekçesi — reddedilen alternatifler', () => {
457
457
  // skalanın 11 kademesinin HİÇBİRİ tema-kör olarak iki temayı birden geçemiyor.
458
458
  // Bu, `dark:` ayrımını zorunlu kılan kanıttır.
459
459
  const tumTrackler = [...trackler(aile, 'light'), ...trackler(aile, 'dark')]
460
- const gecen = KADEMELER.filter((k) => {
460
+ const passedCount = KADEMELER.filter((k) => {
461
461
  const ham = tokenOku(`${aile}-${k}`, 'light')
462
462
  if (!ham) return false
463
463
  const d = rgbTokenRgb(ham)
464
464
  return tumTrackler.every(([, t]) => rgbKontrast(d, t) >= 3.0)
465
465
  })
466
- expect(gecen).toEqual([])
466
+ expect(passedCount).toEqual([])
467
467
  })
468
468
 
469
469
  it.each(AILELER)('%s track alfası düşürülmedi — /20 ayrımı /10\'dan güçlü', (aile) => {
470
470
  // Track'i `/10`'a çekmek dolgu↔track'i kazanırken track↔zemin'i harcardı:
471
471
  // barın TOPLAM uzunluğu görünmezleşir.
472
- const zemin = zeminler('light')[0][1]
473
- const sem = semantikRgb(aile, 'light')
474
- expect(rgbKontrast(alfaBileske(sem, 0.2, zemin), zemin)).toBeGreaterThan(
475
- rgbKontrast(alfaBileske(sem, 0.1, zemin), zemin)
472
+ const background = backgrounds('light')[0][1]
473
+ const sem = semanticRgb(aile, 'light')
474
+ expect(rgbKontrast(alfaBileske(sem, 0.2, background), background)).toBeGreaterThan(
475
+ rgbKontrast(alfaBileske(sem, 0.1, background), background)
476
476
  )
477
477
  })
478
478
  })