@ahmetilhn/hanui 2.0.0 → 2.0.2

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/build/index.d.ts CHANGED
@@ -7,12 +7,14 @@ import { ForwardRefExoticComponent } from 'react';
7
7
  import { HTMLAttributes } from 'react';
8
8
  import { InputHTMLAttributes } from 'react';
9
9
  import { JSX } from 'react';
10
+ import { KeyboardEvent as KeyboardEvent_2 } from 'react';
10
11
  import { MemoExoticComponent } from 'react';
11
12
  import { NamedExoticComponent } from 'react';
12
13
  import { ReactElement } from 'react';
13
14
  import { ReactNode } from 'react';
14
15
  import { ReactPortal } from 'react';
15
16
  import { RefAttributes } from 'react';
17
+ import { RefObject } from 'react';
16
18
  import { TableHTMLAttributes } from 'react';
17
19
  import { TextareaHTMLAttributes } from 'react';
18
20
 
@@ -200,6 +202,16 @@ declare type BaseProps_4 = {
200
202
  previousLabel?: string;
201
203
  /** Verilmezse `labels.pagination.next`. */
202
204
  nextLabel?: string;
205
+ /**
206
+ * Sayfa değiştiğinde ekran okuyucuya duyurulacak metin
207
+ * ("3. sayfa · 1.248 sonuç").
208
+ *
209
+ * <p>Verilmediğinde duyuru YAPILMAZ. Görsel tarafta sayfa numarası
210
+ * `aria-current` ile zaten işaretli ama o yalnızca ODAK oraya geldiğinde
211
+ * okunuyor: bağlantıya basıp listenin başına dönen kullanıcı, kaçıncı
212
+ * sayfada olduğunu ve kaç sonuç kaldığını hiç duymuyordu.
213
+ */
214
+ formatAnnouncement?: (page: number, totalPages: number) => string;
203
215
  className?: string;
204
216
  testId?: string;
205
217
  };
@@ -1740,6 +1752,31 @@ declare type LinkProps = BaseProps_4 & {
1740
1752
  linkProps?: HanuiLinkExtraProps;
1741
1753
  };
1742
1754
 
1755
+ export declare type ListboxNavigation<T extends HTMLElement = HTMLElement> = {
1756
+ activeIndex: number;
1757
+ setActiveIndex: (index: number) => void;
1758
+ /**
1759
+ * Etkin seçeneği görünür alanda tutmak için LİSTEYE bağlanır.
1760
+ *
1761
+ * <p>Tip parametresi çağıran taraf için: `Select` bu referansı `<ul>`e
1762
+ * veriyor ve panel açıldığında `focus()` çağırıyor. `HTMLElement`e sabitlense
1763
+ * çağıran ikinci bir referans tutmak ve ikisini elle eşlemek zorunda kalırdı.
1764
+ */
1765
+ listRef: RefObject<T | null>;
1766
+ handleKeyDown: (event: KeyboardEvent_2<HTMLElement>) => void;
1767
+ };
1768
+
1769
+ export declare type ListboxNavigationOptions = {
1770
+ /** Seçenek sayısı. Liste süzüldüğünde değişir. */
1771
+ count: number;
1772
+ isOpen: boolean;
1773
+ /** Açılışta etkin olacak dizin — genellikle seçili olan. */
1774
+ initialIndex?: number;
1775
+ /** `Enter` / `Space` ile seçildiğinde. */
1776
+ onSelect: (index: number) => void;
1777
+ onClose: () => void;
1778
+ };
1779
+
1743
1780
  /**
1744
1781
  * Aranan metin, hedefin içinde geçiyor mu?
1745
1782
  *
@@ -2092,10 +2129,34 @@ export declare const Popover: typeof Popover_2;
2092
2129
  declare const Popover_2: ({ trigger, children, label, side, align, isOpen: controlledOpen, onOpenChange, className, testId, }: Props_5) => JSX.Element | null;
2093
2130
 
2094
2131
  /** Tercih edilen kenar boyunca hizalama. */
2095
- declare type PositionAlign = 'start' | 'center' | 'end';
2132
+ export declare type PositionAlign = 'start' | 'center' | 'end';
2133
+
2134
+ export declare type PositioningOptions = {
2135
+ side?: PositionSide;
2136
+ align?: PositionAlign;
2137
+ /** Tetikleyici ile yüzey arasındaki boşluk (px). */
2138
+ offset?: number;
2139
+ /** Görünüm alanının kenarından bırakılacak asgari pay (px). */
2140
+ padding?: number;
2141
+ /** Kapalıyken ölçüm yapılmaz ve dinleyici kurulmaz. */
2142
+ isOpen: boolean;
2143
+ };
2144
+
2145
+ export declare type PositioningState = {
2146
+ /** Yüzeye uygulanacak stil — `position: fixed` + hesaplanmış koordinat. */
2147
+ style: {
2148
+ position: 'fixed';
2149
+ top: number;
2150
+ left: number;
2151
+ };
2152
+ /** ÇÖZÜLMÜŞ kenar: çarpışma yüzünden tercih edilenin karşıtı olabilir. */
2153
+ side: PositionSide;
2154
+ /** İlk ölçüm yapıldı mı. Yapılmadan çizilen yüzey sol üst köşede parlıyor. */
2155
+ isPositioned: boolean;
2156
+ };
2096
2157
 
2097
2158
  /** Yüzeyin tercih ettiği kenar. Yer yoksa karşıtına düşer. */
2098
- declare type PositionSide = 'top' | 'bottom' | 'left' | 'right';
2159
+ export declare type PositionSide = 'top' | 'bottom' | 'left' | 'right';
2099
2160
 
2100
2161
  /**
2101
2162
  * `showModal()` ÇAĞRILDIKTAN SONRA çağrılır. Odak bir metin alanına düştüyse
@@ -2542,6 +2603,20 @@ declare type Props_27 = {
2542
2603
  value: string;
2543
2604
  /** Para birimi simgesi ya da kodu. Verilmezse `labels.currency`. */
2544
2605
  currency?: string;
2606
+ /**
2607
+ * Değeri `Intl.NumberFormat` ile biçimlendirir.
2608
+ *
2609
+ * <p>`value` bu kipte de bir DİZE olarak kalıyor ve sayıya çevriliyor —
2610
+ * bileşen hâlâ HESAP YAPMIYOR, yalnızca ayırıcıları ve para birimi
2611
+ * konumunu yerel ayardan alıyor. Yerel ayar `labels.locale`den; verilmezse
2612
+ * biçimlendirme YAPILMAZ ve değer olduğu gibi yazılır. Yanlış yerel ayarda
2613
+ * biçimlendirilmiş bir tutar, biçimlendirilmemiş olandan kötü: "1,250" bir
2614
+ * yerde bin iki yüz elli, başka bir yerde bir tam iki yüz elli.
2615
+ *
2616
+ * <p>Para birimi simgesinin ÖN/ARKA konumu da yerel ayara bağlı ve şu anda
2617
+ * her zaman arkada — `Intl` açıldığında doğru konumu o veriyor.
2618
+ */
2619
+ isFormatted?: boolean;
2545
2620
  /** Üstü çizili liste fiyatı; indirim varsa verilir (biçimlenmiş). */
2546
2621
  listValue?: string;
2547
2622
  /** İndirim oranı (tam sayı yüzde). */
@@ -2770,6 +2845,16 @@ declare type Props_37 = {
2770
2845
  onChange?: (id: string) => void;
2771
2846
  /** Sekme çubuğunun erişilebilir adı. */
2772
2847
  ariaLabel?: string;
2848
+ /**
2849
+ * Ok tuşu yalnızca ODAĞI taşır; seçim `Enter`/`Space` ile yapılır.
2850
+ *
2851
+ * <p>Varsayılan OTOMATİK etkinleştirme (ok tuşu odakla birlikte seçimi de
2852
+ * taşır) ve APG panel içeriği hazır olduğu sürece onu öneriyor. Ama panel
2853
+ * PAHALIYSA — her sekme bir istek atıyorsa — otomatik etkinleştirme,
2854
+ * kullanıcı beşinci sekmeye giderken dört istek atıyor. Manuel kipte
2855
+ * kullanıcı hedefine varıp `Enter`a basıyor: tek istek.
2856
+ */
2857
+ isManualActivation?: boolean;
2773
2858
  className?: string;
2774
2859
  testId?: string;
2775
2860
  };
@@ -2915,6 +3000,16 @@ declare type Props_43 = {
2915
3000
  cancelLabel?: string;
2916
3001
  /** Verilmezse `labels.close`. */
2917
3002
  closeLabel?: string;
3003
+ /**
3004
+ * Onayın türü — ikon, ton ve onay düğmesinin varyantını birlikte belirler.
3005
+ *
3006
+ * <p>Ad `kind`ten `variant`a taşındı: aynı işi yapan üçüncü bir ad
3007
+ * kütüphanede zaten `variant` olarak duruyordu (`Button`, `Badge`) ve
3008
+ * tüketici her bileşende hangisinin geçerli olduğunu hatırlamak zorunda
3009
+ * kalıyordu. Nöbetçi: `src/__tests__/api-consistency.test.ts`.
3010
+ */
3011
+ variant?: ConfirmKind;
3012
+ /** @deprecated `variant` kullanın. Bir sonraki büyük sürümde kalkacak. */
2918
3013
  kind?: ConfirmKind;
2919
3014
  /** Ek bağlam: silinecek kaydın özeti, uyarı kutusu. */
2920
3015
  children?: ReactNode;
@@ -3752,9 +3847,10 @@ export declare const Tabs: typeof Tabs_2;
3752
3847
  * <tr><td>`Tab`</td><td>çubuktan panele çıkar — çubuk TEK durak</td></tr>
3753
3848
  * </table>
3754
3849
  * Ok tuşu odakla birlikte seçimi de taşır (otomatik etkinleştirme). Panel
3755
- * içeriği hazır ve ucuz olduğu sürece APG'nin önerdiği budur; pahalı panelli
3756
- * bir kullanım manuel etkinleştirme ister ve o seçenek HENÜZ YOK. Nöbetçi:
3757
- * `components/__tests__/keyboard.test.tsx`.
3850
+ * içeriği hazır ve ucuz olduğu sürece APG'nin önerdiği budur; her sekmesi bir
3851
+ * istek atan pahalı bir panelde `isManualActivation` verilir — orada otomatik
3852
+ * etkinleştirme, kullanıcı beşinci sekmeye giderken dört istek atıyordu.
3853
+ * Nöbetçi: `components/__tests__/keyboard.test.tsx`.
3758
3854
  */
3759
3855
  declare const Tabs_2: FC<Props_37>;
3760
3856
 
@@ -3802,8 +3898,33 @@ export declare const Textarea: typeof Textarea_2;
3802
3898
  *
3803
3899
  * <p>Yeniden boyutlandırma yalnızca <strong>dikey</strong>: yatayda büyütmek
3804
3900
  * alanı kapsayıcısının dışına taşırıp yerleşimi bozuyordu.
3901
+ *
3902
+ * <h3>Otomatik yükseklik neden CSS ile değil</h3>
3903
+ * `field-sizing: content` bu işi tek satırda yapıyor ama bugün yalnızca
3904
+ * Chromium'da var. Ölçüm yolu her yerde çalışıyor ve tarayıcı desteği
3905
+ * geldiğinde tek dosyada değiştirilecek.
3805
3906
  */
3806
3907
  declare const Textarea_2: ForwardRefExoticComponent<TextareaHTMLAttributes<HTMLTextAreaElement> & {
3908
+ /**
3909
+ * Alan içeriğiyle birlikte BÜYÜR — kaydırma çubuğu yerine yükseklik.
3910
+ *
3911
+ * <p>Sabit yükseklikli bir alanda kullanıcı yazdığının tamamını göremiyor:
3912
+ * dört satırlık bir kutuya on satır yazan kişi, gönderdiğinde ne yazdığını
3913
+ * kontrol etmek için kutunun içinde kaydırmak zorunda kalıyordu. `maxRows`
3914
+ * ile tavan konur; ötesinde kaydırma geri döner (sayfa boyunca uzayan bir
3915
+ * alan, altındaki gönder düğmesini ekrandan çıkarıyordu).
3916
+ */
3917
+ isAutoSize?: boolean;
3918
+ /** Otomatik büyümenin tavanı (satır). */
3919
+ maxRows?: number;
3920
+ /**
3921
+ * Kalan karakter sayacını gösterir. `maxLength` ile birlikte anlamlı.
3922
+ *
3923
+ * <p>Sayaç `aria-hidden`: aynı bilgi her tuşta duyurulsaydı yazma
3924
+ * kesintiye uğrardı. Sınıra YAKLAŞILDIĞINDA (son %10) sayaç uyarı tonuna
3925
+ * geçiyor — sınıra çarpıp yazamamak, yaklaştığını görmemekten kötü.
3926
+ */
3927
+ hasCounter?: boolean;
3807
3928
  testId?: string;
3808
3929
  } & RefAttributes<HTMLTextAreaElement>>;
3809
3930
 
@@ -4149,6 +4270,90 @@ export declare const useHanui: () => HanuiContextValue;
4149
4270
  */
4150
4271
  export declare const useHanuiTheme: () => ThemeState;
4151
4272
 
4273
+ /**
4274
+ * LISTBOX KLAVYE GEZİNMESİ — `Select` ve `Combobox`ın ortak modeli.
4275
+ *
4276
+ * <h3>Neden bir kanca</h3>
4277
+ * İki bileşen aynı klavye modelini <strong>kopya kod</strong> olarak
4278
+ * taşıyordu: `ArrowDown`/`ArrowUp` uçlarda dönme, `Home`/`End`, `Enter` ile
4279
+ * seçme, `Escape` ile kapatma, `Tab` ile kapatıp gezinmeye devam etme ve
4280
+ * etkin seçeneği görünür alanda tutma. Altı davranış, iki yerde. Kopya kod
4281
+ * ayrışmaya açık ve ayrışma sessiz: bir bileşende `Home` çalışıp diğerinde
4282
+ * çalışmadığında hiçbir test kırılmıyordu — ikisinin de kendi testi vardı ve
4283
+ * ikisi de kendi davranışını doğruluyordu.
4284
+ *
4285
+ * <p>Kanca yalnızca <strong>gezinmeyi</strong> taşıyor. Açılma kararı (panel
4286
+ * mi alt sayfa mı), filtreleme ve seçim sözleşmesi (`value`/`onChange`) hâlâ
4287
+ * bileşenlerin: ikisi orada gerçekten farklı ve tek bir kancaya toplamak
4288
+ * `Select`e hiç kullanmayacağı arama koduna taşıtırdı.
4289
+ *
4290
+ * <h3>Klavye</h3>
4291
+ * <table>
4292
+ * <tr><td>`ArrowDown` / `ArrowUp`</td><td>etkin seçenek; uçlarda DÖNER</td></tr>
4293
+ * <tr><td>`Home` / `End`</td><td>ilk / son</td></tr>
4294
+ * <tr><td>`Enter` / `Space`</td><td>etkin seçeneği seçer</td></tr>
4295
+ * <tr><td>`Escape`</td><td>kapatır</td></tr>
4296
+ * <tr><td>`Tab`</td><td>kapatır, gezinme SÜRER (`preventDefault` yok)</td></tr>
4297
+ * </table>
4298
+ *
4299
+ * <p>`Space` yalnızca `hasSpaceSelect` ile: `Combobox`ın arama kutusunda boşluk
4300
+ * bir KARAKTER ve onu seçime çevirmek "fren balatası" yazmayı imkânsız
4301
+ * kılıyordu.
4302
+ */
4303
+ export declare const useListboxNavigation: <T extends HTMLElement = HTMLElement>({ count, isOpen, initialIndex, onSelect, onClose }: ListboxNavigationOptions, { hasSpaceSelect }?: {
4304
+ hasSpaceSelect?: boolean | undefined;
4305
+ }) => ListboxNavigation<T>;
4306
+
4307
+ /**
4308
+ * ÇARPIŞMAYA DUYARLI KONUMLANDIRMA — `Tooltip`, `Popover`, `Menu` ve açılır
4309
+ * listelerin ortak temeli.
4310
+ *
4311
+ * <h3>Neden var: `position: absolute` yetmiyordu</h3>
4312
+ * `Tooltip` balonu tetikleyicinin içinde, `position: absolute` ile duruyordu.
4313
+ * Üç somut sonucu vardı:
4314
+ *
4315
+ * <ul>
4316
+ * <li><b>Kırpılma.</b> `overflow: hidden` taşıyan her kapsayıcı (kart,
4317
+ * tablo kaydırma kutusu, `Panel`) balonu kesiyordu. Bir tablo hücresinde
4318
+ * ipucu görünmüyordu — hiç.</li>
4319
+ * <li><b>Taşma.</b> Ekranın sağ kenarındaki bir tetikleyicinin balonu
4320
+ * görünüm alanının dışına çıkıyor, yatay kaydırma açıyordu.</li>
4321
+ * <li><b>Yığılma bağlamı.</b> `transform` taşıyan bir ata (`Card` hover
4322
+ * animasyonu) yeni bir yığılma bağlamı açıyor ve `z-index` orada
4323
+ * hapsoluyordu; balon kendi kartının altında kalıyordu.</li>
4324
+ * </ul>
4325
+ *
4326
+ * <p>Çözüm portal + `position: fixed`: yüzey gövdeye taşınır, koordinat
4327
+ * görünüm alanına göre hesaplanır. Kırpılacak bir kapsayıcı ve yarışılacak bir
4328
+ * yığılma bağlamı kalmaz.
4329
+ *
4330
+ * <h3>Neden yeni bir bağımlılık YOK</h3>
4331
+ * `floating-ui` bu işi yapıyor ve iyi yapıyor; ama paketin tek çalışma zamanı
4332
+ * bağımlılığının ikon seti olması bilinçli bir karar (bkz. README). Burada
4333
+ * ihtiyaç duyulan şey o kütüphanenin küçük bir alt kümesi: bir kenar, bir
4334
+ * hizalama ve karşıt kenara düşme. Ok konumlandırma, otomatik yerleşim
4335
+ * (`autoPlacement`), sanal öğe ve middleware zinciri gerekmiyor — ve
4336
+ * gerektiğinde eklenecek yer burası.
4337
+ *
4338
+ * <h3>CSS Anchor Positioning neden kullanılmıyor</h3>
4339
+ * Denendi ve BUGÜN kullanılamıyor: `anchor-name` / `position-anchor` yalnızca
4340
+ * Chromium'da var (Safari ve Firefox'ta bayrak arkasında bile değil). İki
4341
+ * kod yolu tutmak — biri modern tarayıcıda, biri yedekte — konumlandırmayı iki
4342
+ * kez yazmak ve ikisinin ayrışmasını beklemek demek. Ölçüm tabanlı yol her
4343
+ * yerde çalışıyor; tarayıcı desteği geldiğinde geçiş TEK dosyada.
4344
+ *
4345
+ * <h3>Ölçüm ne zaman yenileniyor</h3>
4346
+ * Açılışta, pencere yeniden boyutlandığında ve <em>herhangi bir atanın</em>
4347
+ * kaydırılmasında. Sonuncusu için `capture: true` ile belge düzeyinde tek bir
4348
+ * dinleyici: kaydırma olayı baloncuklanmıyor ve her ata için ayrı dinleyici
4349
+ * kurmak, derin bir ağaçta onlarca dinleyici demekti.
4350
+ */
4351
+ export declare const usePositioning: (anchorRef: {
4352
+ current: HTMLElement | null;
4353
+ }, surfaceRef: {
4354
+ current: HTMLElement | null;
4355
+ }, { side, align, offset, padding, isOpen }: PositioningOptions) => PositioningState;
4356
+
4152
4357
  export declare const useScrollLock: (isLocked?: boolean) => void;
4153
4358
 
4154
4359
  /**
@@ -4178,4 +4383,57 @@ export declare const useScrollLock: (isLocked?: boolean) => void;
4178
4383
  */
4179
4384
  export declare const useSheetViewport: (isActive?: boolean) => void;
4180
4385
 
4386
+ /**
4387
+ * SANALLAŞTIRMA — yalnızca görünen satırları çiz.
4388
+ *
4389
+ * <h3>Ölçülen sorun</h3>
4390
+ * 1121 markalı bir `Combobox` listesinde DOM 1121 satır taşıyordu. Panel
4391
+ * açılışı mobilde gözle görülür şekilde donuyor, her tuş vuruşunda liste
4392
+ * yeniden çiziliyordu. Ekran okuyucu tarafında da bedeli var: 1121 öğelik bir
4393
+ * `listbox`ta gezinmek pratikte imkânsız.
4394
+ *
4395
+ * <h3>Neden kütüphane içinde</h3>
4396
+ * `react-window` / `@tanstack/virtual` bu işi yapıyor ve iyi yapıyor; ama
4397
+ * paketin tek çalışma zamanı bağımlılığının ikon seti olması bilinçli bir
4398
+ * karar. Burada gereken şey o kütüphanelerin küçük bir alt kümesi: SABİT
4399
+ * yükseklikli satırlar, tek eksen, yatay yok, değişken yükseklik yok.
4400
+ *
4401
+ * <h3>SABİT satır yüksekliği — ve bu bir kısıt</h3>
4402
+ * Değişken yükseklikli sanallaştırma her satırın ölçülmesini ve bir konum
4403
+ * haritası tutulmasını gerektiriyor. Açılır liste satırları zaten sabit
4404
+ * yükseklikte (`min-height` + tek satır metin); ikincil satır taşıyan
4405
+ * seçeneklerde ölçü `rowHeight` ile verilir.
4406
+ *
4407
+ * <h3>`overscan` neden var</h3>
4408
+ * Yalnızca görünen satırlar çizilseydi hızlı kaydırmada alt kenarda bir kare
4409
+ * boyunca boşluk görünüyordu — tarayıcı kaydırma olayını boyamadan sonra
4410
+ * veriyor. Görünür alanın üstüne ve altına birkaç satır fazladan çizilir.
4411
+ *
4412
+ * <h3>Klavye gezinmesiyle ilişkisi</h3>
4413
+ * Etkin seçeneği görünür tutan `scrollIntoView`, o seçenek ÇİZİLMEMİŞSE
4414
+ * çalışmaz. `scrollToIndex` bu yüzden var: klavyeyle listenin dibine giden
4415
+ * kullanıcı için konum önce hesaplanır, satır sonra çizilir.
4416
+ */
4417
+ export declare const useVirtualList: (count: number, { rowHeight, overscan, isEnabled }?: {
4418
+ rowHeight?: number | undefined;
4419
+ overscan?: number | undefined;
4420
+ isEnabled?: boolean | undefined;
4421
+ }) => {
4422
+ scrollRef: RefObject<HTMLElement | null>;
4423
+ range: VirtualRange;
4424
+ scrollToIndex: (index: number) => void;
4425
+ measure: () => void;
4426
+ };
4427
+
4428
+ export declare type VirtualRange = {
4429
+ /** Çizilecek ilk öğenin dizini. */
4430
+ start: number;
4431
+ /** Çizilecek son öğenin dizini (dahil DEĞİL). */
4432
+ end: number;
4433
+ /** Listenin gerçek toplam yüksekliği — kaydırma çubuğu doğru boyda olmalı. */
4434
+ totalHeight: number;
4435
+ /** Görünen ilk öğenin üstünde bırakılacak boşluk. */
4436
+ offset: number;
4437
+ };
4438
+
4181
4439
  export { }