@ahmetilhn/hanui 1.2.0 → 2.0.1

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/README.md CHANGED
@@ -83,6 +83,9 @@ const THEME = {
83
83
  light: { blue: '#0d6efd', 'blue-text': '#0a58ca' },
84
84
  dark: { blue: '#6ea8fe' },
85
85
  fonts: { heading: 'Archivo, sans-serif', body: 'Inter, sans-serif' },
86
+ // Ölçüler tema başına DEĞİL: bir markanın yuvarlaklığı açık temada
87
+ // 12 px, koyu temada 8 px olmaz.
88
+ metrics: { 'radius-md': '2px', 'radius-lg': '4px', 'duration-normal': '120ms' },
86
89
  };
87
90
 
88
91
  <HanuiProvider theme={THEME} linkComponent={NextLink}>
@@ -97,16 +100,65 @@ React'in dışından (bir `<head>` betiğinden, Storybook'tan) aynı işi
97
100
  (`next/font`, `@font-face`, CDN) siz yaparsınız. Bir UI paketinin ağdan font
98
101
  çekmesi, sizin ölçemediğiniz bir istek demek.
99
102
 
103
+ #### Ezilebilen ölçüler
104
+
105
+ `radius-*` · `space-0…9` · `font-size-2xs…4xl` · `leading-*` · `icon-xs…xl` ·
106
+ `duration-*` · `ease-*` — tam liste `METRIC_TOKENS` içinde ve dışa veriliyor.
107
+
108
+ Ezilemeyenler ve nedenleri: **kırılma noktaları** (`@media (max-width: var(--x))`
109
+ geçersiz CSS), **katman (`z-*`)** (yığılma sırası, marka kararı değil) ve
110
+ **dokunma hedefi** (44 px; yoğun kipte de küçülmemeli — WCAG 2.5.8).
111
+
112
+ ### Bilgi yoğunluğu
113
+
114
+ ```html
115
+ <html data-hanui-density="compact"></html>
116
+ ```
117
+
118
+ Satır yüksekliği, dolgu ve punto bir kademe iner. Vitrin bir ekranda 8 satır,
119
+ operasyon paneli 80 satır gösteriyor; ikisini tek ölçekle karşılamanın yolu yok.
120
+ Kararı `initHanui({ density: 'compact' })` da verebilir.
121
+
122
+ **Yarıçap değişmez** (yuvarlaklık yoğunluğun değil markanın işi) ve **dokunma
123
+ hedefi küçülmez**: görsel kutu daralır, `tap-target` örtüsü 44 px kalır.
124
+
125
+ ### CSS'imizi ezmek — `@layer hanui`
126
+
127
+ Kütüphane CSS'inin tamamı `@layer hanui` içinde. Katmanlı bir kural, katmansız
128
+ bir kurala **her zaman yenilir** — özgüllüğe ve sıraya bakılmaksızın:
129
+
130
+ ```css
131
+ /* Bu kadarı yeter; `!important` ya da `.app .card .card` gerekmez. */
132
+ .my-card {
133
+ padding: 0;
134
+ }
135
+ ```
136
+
137
+ Katman olmadan sizin sınıfınız ile bizimki aynı özgüllükte (0,1,0) yarışıyordu
138
+ ve kazananı **kaynak sırası** belirliyordu; o sıra da bundler'ınızın elinde —
139
+ geliştirme ile üretim aynı olmak zorunda değil.
140
+
100
141
  ### Temayı değiştirmek
101
142
 
102
143
  ```tsx
103
- const { scheme, toggle, isReady } = useHanuiTheme();
144
+ const { scheme, preference, setScheme, toggle, isReady } = useHanuiTheme();
104
145
 
105
146
  useEffect(() => {
106
- if (isReady) localStorage.setItem('theme', scheme);
107
- }, [scheme, isReady]);
147
+ if (isReady) localStorage.setItem('theme', preference);
148
+ }, [preference, isReady]);
108
149
  ```
109
150
 
151
+ | Alan | |
152
+ | --- | --- |
153
+ | `scheme` | **ÇÖZÜLMÜŞ** tema — ekranda çizili olan (`light` \| `dark`) |
154
+ | `preference` | kullanıcının **SEÇİMİ** (`light` \| `dark` \| `system`) |
155
+ | `setScheme` | `'system'` verildiğinde açık seçim SİLİNİR |
156
+
157
+ Üç durumlu bir anahtar (Açık / Koyu / Sistem) `preference` okur; `scheme`
158
+ okusaydı "Sistem" seçiliyken düğme "Koyu"yu işaretli gösterirdi. `system` bir
159
+ değer değil **değerin yokluğu**: öznitelik silinir ve
160
+ `:not([data-hanui-theme])` sorgusu devreye girer.
161
+
110
162
  Kalıcılık **kancanın işi değil**: seçimi `localStorage`a mı, sunucuda
111
163
  okunabilsin diye bir çereze mi, kullanıcı profiline mi yazacağınız sizin
112
164
  kararınız. Kütüphane `localStorage`a yazsaydı sunucu tarafı onu okuyamayacağı
@@ -121,13 +173,27 @@ uyuşmazlık üretiyordu.
121
173
 
122
174
  ```
123
175
  theme/palette.ts → ham hex (TEK hex kaynağı)
124
- theme/tokens.ts → anlamsal token → hex (açık + koyu)
176
+ theme/tokens.ts → anlamsal token → değer
177
+ LIGHT_THEME / DARK_THEME (renk, temaya bağlı)
178
+ METRIC_TOKENS (ölçü, temadan bağımsız)
179
+ COMPACT_DENSITY (yoğun kipin ezdikleri)
125
180
  styles/*.generated → yukarıdakinden ÜRETİLİR (npm run tokens)
126
181
  ```
127
182
 
128
183
  SCSS ve TypeScript tarafı elle tutulsaydı bir tarafta var olup diğerinde
129
184
  olmayan bir token çıkardı — ve ayrışma sessiz: bileşen `var(--hanui-yok)`
130
- okuyup rengini kaybediyor, derleme yeşil dönüyor.
185
+ okuyup rengini kaybediyor, derleme yeşil dönüyor. Nöbetçi
186
+ `theme/__tests__/tokens.contract.test.ts`.
187
+
188
+ **Ölçüler CSS değişkeni olduğu için SCSS aritmetiği çalışmaz.**
189
+ `$space-8 - $space-2` derlenmez — ve Sass hata da vermez: ifadeyi olduğu gibi
190
+ geçirip tarayıcıya `var(--a)-var(--b)` yazar, tarayıcı bütün bildirimi atar.
191
+ Hesap `calc()` içinde yazılır, negatif değer dahil:
192
+
193
+ ```scss
194
+ padding-inline-start: calc(#{$space-8} - #{$space-2});
195
+ margin-inline: calc(-1 * #{$space-2});
196
+ ```
131
197
 
132
198
  ---
133
199
 
@@ -350,20 +416,63 @@ import NextLink from 'next/link';
350
416
  ```bash
351
417
  nvm use # .nvmrc → 24
352
418
  npm install
353
- npm run verify # tokens → typecheck → lint → test → build
419
+ npm run verify # tokens → kontrast → typecheck → lint → kapsam → build → boyut
420
+ npm run playground # bileşen galerisi → http://localhost:5273
354
421
  ```
355
422
 
356
- | Komut | |
357
- | ------------------- | -------------------------------------------------- |
358
- | `npm run tokens` | SCSS token dosyalarını `theme/tokens.ts`ten üretir |
359
- | `npm run build` | `build/` (ESM + CJS + `.d.ts` + `styles.css`) |
360
- | `npm run test` | Jest + Testing Library |
361
- | `npm run typecheck` | `tsc --noEmit` |
423
+ | Komut | |
424
+ | ------------------------- | --------------------------------------------------------------- |
425
+ | `npm run tokens` | SCSS token dosyalarını `theme/tokens.ts`ten üretir |
426
+ | `npm run build` | `build/` (ESM + CJS + `.d.ts` + `styles.css`) |
427
+ | `npm run test` | Jest + Testing Library + `jest-axe` |
428
+ | `npm run test:coverage` | kapsam kapısı — `helpers`/`hooks`/`theme` satır ≥ %80 |
429
+ | `npm run test:visual` | görsel regresyon (Playwright); `verify` İÇİNDE DEĞİL, aşağı bkz. |
430
+ | `npm run check:contrast` | WCAG kontrast ölçümü, iki temada 118 çift |
431
+ | `npm run size` | paket boyutu bütçesi (`size-limit`) |
432
+ | `npm run playground` | bileşen galerisi (tema · RTL · yoğunluk anahtarı) |
433
+ | `npm run lint` | ESLint (TS) + stylelint (SCSS) |
434
+ | `npm run typecheck` | `tsc --noEmit` |
435
+
436
+ ### Nöbetçiler ne koruyor
437
+
438
+ - **Eksen taraması** — dışa verilen her bileşen, her anlamlı durumunda
439
+ (`components/__tests__/a11y.test.tsx`). Deftere girmeyen yeni bir bileşen
440
+ testi kırar.
441
+ - **Klavye sözleşmesi** — tuş matrisleri her bileşenin JSDoc'unda, nöbetçisi
442
+ `components/__tests__/keyboard.test.tsx`.
443
+ - **Kontrast** — metin ≥ 4,5:1, ikon ve odak halkası ≥ 3:1. Eşiği tutmayan bir
444
+ token derlemeyi kırar; düzeltme daima `palette.ts` düzeyinde yapılır.
445
+ - **Token sözleşmesi** — açık/koyu anahtar kümeleri ve üretilmiş SCSS kaynakla
446
+ eşleşir. Ayrışma bugüne kadar sessizdi.
447
+ - **Paket boyutu** — tek bileşen import eden bir uygulamanın ne indirdiği
448
+ ölçülür (`Badge` 2,7 kB, `Button` 3,4 kB, tüm paket 22,2 kB gzip).
449
+ - **Odak halkası ve hareket ölçeği** — stylelint, `focus-ring` mixin'i dışında
450
+ `outline` ve bileşen SCSS'inde ham süre değeri (`0.7s`) yazılmasını
451
+ engelliyor. Üç bileşen kendi halkasını, iki bileşen kendi süresini
452
+ yazıyordu.
453
+
454
+ **Görsel regresyon `verify` içinde değil**: ekran görüntüsü platforma bağlı
455
+ (yazı tipi tarama, alt piksel yumuşatma) ve macOS'te üretilmiş bir referans
456
+ ubuntu üzerinde koşan CI'da her dosyada kırmızı döner. Referanslar platform
457
+ başına saklanıyor (`e2e/__screenshots__/{platform}/`); CI'da açılacağı gün doğru
458
+ yol, Playwright'ın resmi konteynerinde koşup `linux` referanslarını orada
459
+ üretmek.
362
460
 
363
461
  `master`a her push `npm publish` çalıştırır — **`package.json` sürümünü
364
462
  yükseltmeyi unutmayın**, aynı sürüm ikinci kez yayımlanamaz ve iş akışı kırmızı
365
463
  döner.
366
464
 
465
+ ## Belgeler
466
+
467
+ | | |
468
+ | --- | --- |
469
+ | [`docs/DESIGN-SYSTEM.md`](docs/DESIGN-SYSTEM.md) | Öğe kataloğu · **hangi durumda hangi bileşen** |
470
+ | [`docs/A11Y.md`](docs/A11Y.md) | Nöbetçiler, kontrast eşikleri, değişmez kurallar |
471
+ | [`docs/MOTION.md`](docs/MOTION.md) | Hareket ölçeği ve koreografi |
472
+ | [`docs/THEMING.md`](docs/THEMING.md) | Marka uyarlama, ezilebilir token listesi |
473
+ | [`docs/MIGRATION.md`](docs/MIGRATION.md) | Kırıcı değişiklikler ve `@deprecated` yollar |
474
+ | [`docs/CONSUMER-ADOPTION.md`](docs/CONSUMER-ADOPTION.md) | `hanparca-*` geçiş planı |
475
+
367
476
  ## Lisans
368
477
 
369
478
  MIT