@ahmetilhn/hanui 1.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/LICENSE +21 -0
- package/README.md +276 -0
- package/build/index.cjs +18 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.ts +2576 -0
- package/build/index.js +2875 -0
- package/build/index.js.map +1 -0
- package/build/styles.css +1 -0
- package/package.json +103 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/theme/palette.ts","../src/theme/tokens.ts","../src/helpers/theme.helper.ts","../src/theme/context.ts","../src/theme/HanuiProvider.tsx","../src/theme/initHanui.ts","../src/hooks/useHanuiTheme.ts","../src/hooks/useSheetViewport.ts","../src/enums/ui-variant.enum.ts","../src/enums/ui-size.enum.ts","../src/constants/breakpoint.constants.ts","../src/helpers/text.helper.ts","../src/helpers/focus.helper.ts","../src/helpers/class-name.helper.ts","../src/components/Link/index.tsx","../src/components/Spinner/index.tsx","../src/components/Button/index.tsx","../src/components/IconButton/index.tsx","../src/icons/index.tsx","../src/components/TextLink/index.tsx","../src/components/Tooltip/index.tsx","../src/components/Chip/index.tsx","../src/components/ChipGroup/index.tsx","../src/components/BottomSheet/index.tsx","../src/components/Combobox/index.tsx","../src/components/Select/index.tsx","../src/components/Checkbox/index.tsx","../src/components/Radio/index.tsx","../src/components/RadioCard/index.tsx","../src/components/RangeSlider/index.tsx","../src/components/RatingInput/index.tsx","../src/components/QuantityStepper/index.tsx","../src/components/TableCheckbox/index.tsx","../src/components/Input/index.tsx","../src/components/Textarea/index.tsx","../src/components/Field/index.tsx","../src/components/Alert/index.tsx","../src/components/Avatar/index.tsx","../src/components/Badge/index.tsx","../src/components/Breadcrumb/index.tsx","../src/components/Card/index.tsx","../src/components/CopyField/index.tsx","../src/components/Divider/index.tsx","../src/components/Directory/index.tsx","../src/components/EmptyState/index.tsx","../src/components/PageHeader/index.tsx","../src/components/Panel/index.tsx","../src/components/Price/index.tsx","../src/components/Rating/index.tsx","../src/components/SectionHeader/index.tsx","../src/components/Skeleton/index.tsx","../src/components/Tabs/index.tsx","../src/components/Tile/index.tsx","../src/components/Modal/index.tsx","../src/components/ConfirmDialog/index.tsx","../src/components/PromptDialog/index.tsx","../src/components/Table/index.tsx","../src/components/DataTable/index.tsx","../src/components/FilterBar/index.tsx","../src/components/Pagination/index.tsx"],"sourcesContent":["/**\n * HAM PALET — kütüphanenin TEK hex kaynağı.\n *\n * <p>Başka hiçbir dosyada birebir renk değeri yazılmaz. Zincir:\n *\n * <pre>\n * theme/palette.ts → ham hex (yalnızca burada)\n * theme/tokens.ts → anlamsal token adı → hex eşlemesi (açık + koyu)\n * styles/_tokens.generated.scss → `:root` ve `[data-hanui-theme]` yayını\n * styles/_colors.generated.scss → bileşenlerin gördüğü SCSS sözleşmesi\n * </pre>\n *\n * <p>Son iki dosya `scripts/build-tokens.mjs` tarafından ÜRETİLİR. Elle\n * yazıldıklarında TypeScript tarafındaki token listesiyle ayrışıyorlar ve\n * ayrışma sessiz: bir bileşen var olmayan bir değişkeni okuyup rengi\n * kaybediyor, derleme yine yeşil dönüyordu.\n */\n\n// --- Nötr eksen -------------------------------------------------------\n// Serin gri-mavi. Sıcak kum tonundan ayrıldık: ürün fotoğrafları ağırlıkla\n// metal ve siyah plastik; sıcak zemin onları sarartıp kirli gösteriyordu.\nexport const NEUTRAL = {\n n0: '#ffffff',\n n25: '#fafbfc',\n n50: '#f6f7f9',\n n100: '#eef0f4',\n n150: '#e7eaef',\n n200: '#e2e6ec',\n /** Kart/girdi kenarı — `n200` sayfadan ayrılmıyordu. */\n n250: '#d6dce4',\n n300: '#c9d0da',\n n400: '#aab3c0',\n n500: '#8a94a3',\n /**\n * İkincil metnin okunur tabanı.\n *\n * ÖLÇÜLDÜ: `text-3` `n500`'dü ve beyaz üzerinde 3,2:1 veriyor; üstü çizili\n * fiyat, yer tutucu ve yardım metni gövde metni sayıldığı için WCAG\n * 1.4.3'ün 4,5:1 eşiğini GEÇMİYORDU. Aynı ton açısında aydınlık\n * düşürüldü: 4,67:1. Bir kademe daha koyulaştırmak `n600` ile ayrımı yok\n * ediyordu.\n */\n n550: '#6b7583',\n n600: '#5a6472',\n n700: '#3a424f',\n n800: '#232a35',\n n900: '#11151b',\n} as const;\n\n// --- Grafit -----------------------------------------------------------\n// Üst bant, alt bilgi, tablo başlıkları, teknik bloklar ve BİRİNCİL EYLEM.\nexport const GRAPHITE = {\n base: '#1f2937',\n two: '#2b3646',\n three: '#3a4658',\n /** Koyu temada üst bant; sayfadan koyu kalmalı. */\n ink: '#12161d',\n inkTwo: '#1c222b',\n} as const;\n\n// --- Amber ------------------------------------------------------------\n// EKRANDAKİ TEK DOYGUN TURUNCU: dönüşüm eylemi (\"sepete ekle\"). Başka\n// hiçbir yerde dolgu olarak kullanılmaz.\nexport const AMBER = {\n base: '#f59e0b',\n hover: '#d98706',\n active: '#b87205',\n /** Pasif dönüşüm düğmesi; saydamlık değil KENDİ dolgusu. */\n soft: '#f8cd80',\n dark: '#fbbf24',\n darkHover: '#f0af12',\n /** Amber üzerinde metin — beyaz 2,3:1'de kalıyor, okunmuyor. */\n on: '#291500',\n} as const;\n\n// --- Mavi -------------------------------------------------------------\n// Gezinme ve keşif: bağlantı, etkin filtre, odak halkası. Amber ile\n// çarpışmaz çünkü işleri farklı.\nexport const BLUE = {\n base: '#2f6fed',\n hover: '#1d54c4',\n active: '#17439c',\n /** Gövde metni içi bağlantı — `base` 16px'te 4,55:1. */\n text: '#1d54c4',\n tint: '#eaf1fe',\n line: '#bcd2fb',\n dark: '#5b93ff',\n darkHover: '#7aa8ff',\n darkTint: '#16243c',\n darkLine: '#2a3f63',\n} as const;\n\n/**\n * MARKA ANKORLARI: kırmızı ve yeşil.\n *\n * <p>Aşağıdaki iki hex, kendi ailelerinin TEK KAYNAĞIDIR. Ailedeki her ton\n * (tint zemini, kenarlık, metin, koyu tema karşılığı) HSL uzayında bu iki\n * değerden türetildi: ton açısı ve doygunluk korunur, yalnızca aydınlık\n * kaydırılır. Yeni bir kırmızı/yeşil ton gerektiğinde gözle seçilmez —\n * buradan türetilir, yoksa aile zamanla dağılır.\n *\n * <p>⚠ ANKORLAR METİN RENGİ DEĞİLDİR. `green` beyaz üzerinde 2,22:1 —\n * gövde metni olarak WCAG'i geçmez. Bu yüzden aile iki katmanlı: ankor\n * İKON ve DOLGU için, ondan türetilen koyu ton METİN için.\n */\nexport const ANCHOR = {\n red: '#dc2626',\n green: '#34c759',\n} as const;\n\n/**\n * DURUM RENKLERİ.\n *\n * <p>Kural: TINT ZEMİN + KOYU METİN + eşleşen hairline. Asla doygun dolgu —\n * doygun dolgu \"tıklanabilir\" demektir ve durum etiketi tıklanabilir değildir.\n *\n * <p>Kenarlık tonları bir kademe koyulaştırıldı: rozetler \"kutu\" olarak\n * okunmalı; daha açık çizgiler tint zeminin üzerinde kaybolup yan yana duran\n * iki rozeti tek bir lekeye çeviriyordu.\n */\nexport const STATUS = {\n /* Yeşil ailesi `ANCHOR.green`den türetildi (L +44 / S −24, L +33 / S −14). */\n okBg: '#e8f4eb',\n /** 5,58:1 tint üzerinde — metin katmanı. */\n okFg: '#1d6e31',\n okLine: '#a8dcb7',\n okBgDark: '#122817',\n /** Koyu zeminde ankorun kendisi okunuyor (7,05:1). */\n okFgDark: '#34c759',\n okLineDark: '#22542f',\n\n warnBg: '#fdf0dd',\n warnFg: '#7a3e02',\n warnLine: '#ebc687',\n warnBgDark: '#2c2008',\n warnFgDark: '#f5c86b',\n warnLineDark: '#55401a',\n\n offBg: '#f1f2f5',\n offFg: '#3a424f',\n offLine: '#ccd2db',\n offBgDark: '#212630',\n offFgDark: '#a3adbb',\n offLineDark: '#333b47',\n\n /*\n * Kırmızı ailesi `ANCHOR.red`den türetildi. Önceki `badFg` (#7f1d1d) bir\n * bordoydu: favori kalbi ve olumsuz rozet ekranda kirli/kahverengi\n * okunuyordu. Aynı ton açısında kalıp aydınlığı açmak rengi hem canlı hem\n * okunur yapıyor.\n */\n badBg: '#f8ebeb',\n /** 5,45:1 tint üzerinde. */\n badFg: '#bb1e1e',\n badLine: '#e6a6a6',\n badBgDark: '#310f0f',\n /** 6,03:1 koyu tint üzerinde. */\n badFgDark: '#e97575',\n badLineDark: '#621b1b',\n\n /** Birincil / orijinal sınıflandırma tonu. */\n oemBg: '#eaf1fe',\n oemFg: '#16305c',\n oemLine: '#a9c6f9',\n oemBgDark: '#152139',\n oemFgDark: '#9dc0ff',\n oemLineDark: '#27395c',\n\n /** İkincil / muadil sınıflandırma tonu. */\n altBg: '#eeebfa',\n altFg: '#2e2661',\n altLine: '#c0b6ea',\n altBgDark: '#1d1a33',\n altFgDark: '#bfb3f5',\n altLineDark: '#332d56',\n} as const;\n\n/**\n * YIKICI EYLEM DOLGUSU (silme onayı).\n *\n * <p>Durum tinti DEĞİL, gerçek bir düğme. Ankorun kendisi: beyaz metinle\n * 4,83:1. Aynı kırmızıyı taşımaları kullanıcının uyarı etiketine tıklamayı\n * denemesine yol açıyordu.\n */\nexport const DANGER_SOLID = {\n base: '#dc2626',\n hover: '#bb1e1e',\n dark: '#e45b5b',\n darkHover: '#ef7a72',\n onDark: '#1a0b0a',\n} as const;\n\n/**\n * İKON DOLGULARI — favori kalbi gibi METİN OLMAYAN, doygun kalması gereken\n * yerler. WCAG grafik öğesi eşiği 3:1 (1.4.11) ve hepsi geçiyor; gövde\n * metni olarak KULLANILMAZ.\n */\nexport const ACCENT = {\n red: '#dc2626',\n redDark: '#e35252',\n green: '#34c759',\n greenDark: '#4cd76c',\n greenHover: '#2aae4b',\n greenHoverDark: '#63e084',\n /** Yeşil dolgu üzerindeki metin. BEYAZ DEĞİL: #34c759 üzerinde 2,22:1. */\n onGreen: '#06280f',\n} as const;\n\n/**\n * İNDİRİM / OLUMLU DEĞİŞİM ETİKETİ.\n *\n * <p>Fiyat SİYAH kalır; rozet YEŞİL — kazancı kırmızı ile işaretlemek\n * \"uyarı\" gibi okunuyordu, oysa indirim iyi haber.\n */\nexport const SALE = {\n bg: '#e8f4eb',\n fg: '#1d6e31',\n bgDark: '#122817',\n fgDark: '#34c759',\n} as const;\n\n/**\n * YILDIZ ALTINI.\n *\n * <p>Amber ailesinden AYRI kalır (amber yalnızca dönüşüm eylemi), ama eski\n * uyarı tonu (#7a3e02) bir kahverengiydi ve puan yıldızları kirli\n * görünüyordu. Bu ton sıcaklığı korur, doygun turuncuyla yarışmaz ve tek\n * başına bir dolgu olarak okunmaz.\n */\nexport const STAR = {\n /** 5,23:1 beyaz üzerinde. */\n light: '#9a5f04',\n /** 9,82:1 koyu zemin üzerinde. */\n dark: '#f0b429',\n} as const;\n","import {\n ACCENT,\n AMBER,\n BLUE,\n DANGER_SOLID,\n GRAPHITE,\n NEUTRAL,\n SALE,\n STAR,\n STATUS,\n} from './palette';\n\n/**\n * TEMA TOKEN'LARI.\n *\n * <p>Her anahtar bir CSS özel özelliğine karşılık gelir: `page` →\n * `--hanui-page`. Bileşenler SCSS tarafında yalnızca bu adları görür ve hepsi\n * bir `var(--hanui-…)` işaret eder.\n *\n * <h3>Neden CSS değişkeni, neden SCSS değişkeni değil</h3>\n * Açık/koyu tema ÇALIŞMA ZAMANINDA değişir; SCSS değişkeni derleme anında\n * sabitlenir ve tek derlemeden iki tema çıkmaz. Bunun iki sonucu var:\n *\n * <ol>\n * <li>Renk üzerinde SCSS renk fonksiyonu ÇALIŞMAZ (`rgba($surface, .9)`\n * derlenmez). Gereken her saydam değer hazır token olarak durur:\n * `scrim`, `glass`, `ring`, `track`, `glow-1`…</li>\n * <li>`prefers-color-scheme` ile renk SEÇİLMEZ. Tema `data-hanui-theme`\n * üzerinden gelir; medya sorgusu kullanıcının açık seçimini görmez —\n * yalnızca hiç seçim yapılmadığında yedek olarak devreye girer.</li>\n * </ol>\n */\n\n/** Hex rengi `rgba(...)` dizesine çevirir. Renk fonksiyonu üretim ANINDA çalışır. */\nconst alpha = (hex: string, value: number): string => {\n const normalized = hex.replace('#', '');\n const full =\n normalized.length === 3\n ? normalized\n .split('')\n .map(character => character + character)\n .join('')\n : normalized;\n\n const red = parseInt(full.slice(0, 2), 16);\n const green = parseInt(full.slice(2, 4), 16);\n const blue = parseInt(full.slice(4, 6), 16);\n\n return `rgba(${red}, ${green}, ${blue}, ${value})`;\n};\n\nconst BLACK = '#000000';\n\n/**\n * AÇIK TEMA — varsayılan.\n *\n * <p>Bilgi yoğunluğu yüksek ekranlarda açık zeminde okunurluk daha yüksek.\n */\nexport const LIGHT_THEME = {\n // --- Yüzey ---\n page: NEUTRAL.n50,\n surface: NEUTRAL.n0,\n 'surface-2': NEUTRAL.n100,\n 'surface-3': NEUTRAL.n150,\n 'surface-inset': NEUTRAL.n25,\n\n // --- Kenarlık ---\n border: NEUTRAL.n250,\n 'border-strong': NEUTRAL.n300,\n\n // --- Metin ---\n text: NEUTRAL.n900,\n 'text-2': NEUTRAL.n600,\n 'text-3': NEUTRAL.n550,\n\n // --- Grafit: bant, alt bilgi, tablo başlığı, teknik blok ---\n graphite: GRAPHITE.base,\n 'graphite-2': GRAPHITE.two,\n 'graphite-3': GRAPHITE.three,\n\n /*\n * BİRİNCİL EYLEM (dolgulu, nötr).\n *\n * `action` grafittir, amber DEĞİL. Amber tek bir dönüşüm noktasına\n * ayrılmıştır; her dolu düğmeyi amber yapmak o tekilliği yok eder ve\n * kullanıcı hangi turuncunun dönüşüm olduğunu bilemez.\n */\n action: GRAPHITE.base,\n 'action-hover': GRAPHITE.two,\n 'action-active': GRAPHITE.three,\n 'on-action': NEUTRAL.n0,\n /** Pasif dolgu; saydamlık DEĞİL kendi rengi (bkz. Button `:disabled`). */\n 'action-soft': NEUTRAL.n300,\n\n // --- Dönüşüm eylemi: ekrandaki tek doygun turuncu ---\n amber: AMBER.base,\n 'amber-hover': AMBER.hover,\n 'amber-active': AMBER.active,\n 'amber-soft': AMBER.soft,\n 'on-amber': AMBER.on,\n\n // --- Mavi: gezinme ve keşif ---\n blue: BLUE.base,\n 'blue-hover': BLUE.hover,\n 'blue-active': BLUE.active,\n 'blue-text': BLUE.text,\n 'blue-tint': BLUE.tint,\n 'blue-line': BLUE.line,\n\n // --- Durum: tint zemin + koyu metin + eşleşen hairline ---\n 'ok-bg': STATUS.okBg,\n 'ok-fg': STATUS.okFg,\n 'ok-line': STATUS.okLine,\n\n 'warn-bg': STATUS.warnBg,\n 'warn-fg': STATUS.warnFg,\n 'warn-line': STATUS.warnLine,\n\n 'off-bg': STATUS.offBg,\n 'off-fg': STATUS.offFg,\n 'off-line': STATUS.offLine,\n\n 'bad-bg': STATUS.badBg,\n 'bad-fg': STATUS.badFg,\n 'bad-line': STATUS.badLine,\n\n 'oem-bg': STATUS.oemBg,\n 'oem-fg': STATUS.oemFg,\n 'oem-line': STATUS.oemLine,\n\n 'alt-bg': STATUS.altBg,\n 'alt-fg': STATUS.altFg,\n 'alt-line': STATUS.altLine,\n\n 'sale-bg': SALE.bg,\n 'sale-fg': SALE.fg,\n\n // --- İkon vurguları: METİN DEĞİL (WCAG grafik eşiği 3:1) ---\n 'red-accent': ACCENT.red,\n 'green-accent': ACCENT.green,\n 'green-accent-hover': ACCENT.greenHover,\n 'on-green': ACCENT.onGreen,\n star: STAR.light,\n\n // --- Yıkıcı eylem: durum tinti DEĞİL, gerçek bir dolgu ---\n 'danger-solid': DANGER_SOLID.base,\n 'danger-solid-hover': DANGER_SOLID.hover,\n 'on-danger': NEUTRAL.n0,\n\n /*\n * ÜST BANT / ALT BİLGİ / KAHRAMAN BÖLÜMÜ.\n *\n * BU TOKEN'LAR TEMAYI İZLER: açık temada her yer açık, koyu temada her yer\n * koyu. Ayrı bir ad kümesi olarak kalıyorlar çünkü bantların KENDİ yüzey\n * merdiveni var: üst bant sayfadan bir kademe yükselir (beyaz zemin, gri\n * sayfa üzerinde), alt bilgi bir kademe çöker. Bunu `surface` ile yazmak\n * iki bandı sayfayla aynı tonda bırakıyordu.\n */\n 'nav-bg': NEUTRAL.n0,\n 'nav-bg-2': NEUTRAL.n100,\n 'nav-fg': NEUTRAL.n900,\n 'nav-fg-2': NEUTRAL.n600,\n 'nav-fg-3': NEUTRAL.n500,\n 'nav-line': NEUTRAL.n200,\n 'nav-line-strong': NEUTRAL.n300,\n 'nav-hover': NEUTRAL.n100,\n 'footer-bg': NEUTRAL.n100,\n\n // --- Gölge: nötr-serin (sıcak gölge serin gri zeminde kirli durur) ---\n 'shadow-xs': `0 1px 2px ${alpha(NEUTRAL.n900, 0.05)}`,\n 'shadow-sm': `0 1px 2px ${alpha(NEUTRAL.n900, 0.05)}, 0 1px 3px ${alpha(NEUTRAL.n900, 0.04)}`,\n 'shadow-md': `0 2px 4px ${alpha(NEUTRAL.n900, 0.04)}, 0 6px 16px ${alpha(NEUTRAL.n900, 0.07)}`,\n 'shadow-lg': `0 4px 8px ${alpha(NEUTRAL.n900, 0.05)}, 0 16px 32px ${alpha(NEUTRAL.n900, 0.1)}`,\n 'shadow-xl': `0 8px 16px ${alpha(NEUTRAL.n900, 0.06)}, 0 28px 56px ${alpha(NEUTRAL.n900, 0.13)}`,\n /** Yapışkan alt bar; gölge YUKARI düşer. */\n 'shadow-up': `0 -2px 4px ${alpha(NEUTRAL.n900, 0.03)}, 0 -8px 24px ${alpha(NEUTRAL.n900, 0.08)}`,\n\n /** Odak halkası MAVİ: odak bir gezinme olayıdır, bir dönüşüm değil. */\n ring: `0 0 0 3px ${alpha(BLUE.base, 0.28)}`,\n 'ring-color': BLUE.base,\n 'ring-danger': `0 0 0 3px ${alpha(DANGER_SOLID.base, 0.24)}`,\n 'ring-ok': `0 0 0 4px ${alpha(STATUS.okFg, 0.16)}`,\n\n // --- Örtü ve cam: görsel üzerine binen yüzeyler ---\n scrim: alpha(NEUTRAL.n900, 0.55),\n 'scrim-soft': alpha(NEUTRAL.n900, 0.32),\n glass: alpha(NEUTRAL.n0, 0.92),\n 'glass-solid': NEUTRAL.n0,\n 'on-scrim': NEUTRAL.n0,\n\n // --- İskelet ve dönen gösterge ---\n 'skeleton-a': NEUTRAL.n100,\n 'skeleton-b': NEUTRAL.n25,\n track: alpha(NEUTRAL.n900, 0.12),\n\n /** Görsel yer tutucu (medya yoksa). */\n 'media-bg': NEUTRAL.n100,\n\n /*\n * Vurgu bloğundaki ışık lekeleri. Açık temada ZEMİN DE AÇIK olduğu için\n * lekeler çok daha hafif: koyu bant için ayarlanmış %22 opaklık açık\n * zeminde lekeyi kirli bir dasa çeviriyordu.\n */\n 'glow-1': alpha(BLUE.base, 0.1),\n 'glow-2': alpha(BLUE.base, 0.06),\n 'glow-amber': alpha(AMBER.base, 0.09),\n} as const;\n\n/**\n * KOYU TEMA.\n *\n * <p>Yüzey merdiveni açık temanın AYNISI DEĞİL, tersi: koyu temada yükselen\n * yüzey AÇILIR (`surface` > `page`), çünkü ışık yukarıdan gelir. Aynı sırayı\n * korumak kartları sayfaya gömüyordu.\n */\nexport const DARK_THEME: Record<keyof typeof LIGHT_THEME, string> = {\n page: '#0e1116',\n surface: '#171b22',\n 'surface-2': '#1f242d',\n 'surface-3': '#262c36',\n 'surface-inset': '#13171d',\n\n border: '#262c36',\n 'border-strong': '#363e4a',\n\n text: '#e7eaee',\n 'text-2': '#9aa4b2',\n 'text-3': '#6b7583',\n\n graphite: GRAPHITE.ink,\n 'graphite-2': GRAPHITE.inkTwo,\n 'graphite-3': GRAPHITE.two,\n\n /*\n * Koyu temada grafit dolgu sayfadan ayırt edilemez. Birincil eylem AÇIK bir\n * nötr yüzeye döner — koyu zeminde en yüksek vurgu budur.\n */\n action: NEUTRAL.n150,\n 'action-hover': NEUTRAL.n0,\n 'action-active': NEUTRAL.n300,\n 'on-action': NEUTRAL.n900,\n 'action-soft': '#414a58',\n\n amber: AMBER.dark,\n 'amber-hover': AMBER.darkHover,\n 'amber-active': AMBER.base,\n 'amber-soft': '#6d5316',\n 'on-amber': AMBER.on,\n\n blue: BLUE.dark,\n 'blue-hover': BLUE.darkHover,\n 'blue-active': BLUE.base,\n 'blue-text': BLUE.dark,\n 'blue-tint': BLUE.darkTint,\n 'blue-line': BLUE.darkLine,\n\n 'ok-bg': STATUS.okBgDark,\n 'ok-fg': STATUS.okFgDark,\n 'ok-line': STATUS.okLineDark,\n\n 'warn-bg': STATUS.warnBgDark,\n 'warn-fg': STATUS.warnFgDark,\n 'warn-line': STATUS.warnLineDark,\n\n 'off-bg': STATUS.offBgDark,\n 'off-fg': STATUS.offFgDark,\n 'off-line': STATUS.offLineDark,\n\n 'bad-bg': STATUS.badBgDark,\n 'bad-fg': STATUS.badFgDark,\n 'bad-line': STATUS.badLineDark,\n\n 'oem-bg': STATUS.oemBgDark,\n 'oem-fg': STATUS.oemFgDark,\n 'oem-line': STATUS.oemLineDark,\n\n 'alt-bg': STATUS.altBgDark,\n 'alt-fg': STATUS.altFgDark,\n 'alt-line': STATUS.altLineDark,\n\n 'sale-bg': SALE.bgDark,\n 'sale-fg': SALE.fgDark,\n\n 'red-accent': ACCENT.redDark,\n 'green-accent': ACCENT.greenDark,\n 'green-accent-hover': ACCENT.greenHoverDark,\n 'on-green': ACCENT.onGreen,\n star: STAR.dark,\n\n 'danger-solid': DANGER_SOLID.dark,\n 'danger-solid-hover': DANGER_SOLID.darkHover,\n 'on-danger': DANGER_SOLID.onDark,\n\n /* Koyu temada bant sayfadan daha KOYU: aynı tonda olsa yüzüyor görünüyor. */\n 'nav-bg': GRAPHITE.ink,\n 'nav-bg-2': GRAPHITE.inkTwo,\n 'nav-fg': '#e7eaee',\n 'nav-fg-2': '#9aa4b2',\n 'nav-fg-3': '#6b7583',\n 'nav-line': '#262c36',\n 'nav-line-strong': '#363e4a',\n 'nav-hover': alpha(NEUTRAL.n0, 0.07),\n 'footer-bg': GRAPHITE.ink,\n\n /*\n * Koyu zeminde gölge okunmaz; derinlik daha çok kenarlıkla kurulur.\n * Gölgeler yine de KORUNUR ama daha derin: modal ve açılır liste yüzeyin\n * üzerinde durmalı.\n */\n 'shadow-xs': `0 1px 2px ${alpha(BLACK, 0.4)}`,\n 'shadow-sm': `0 1px 2px ${alpha(BLACK, 0.4)}, 0 1px 3px ${alpha(BLACK, 0.3)}`,\n 'shadow-md': `0 2px 4px ${alpha(BLACK, 0.35)}, 0 6px 16px ${alpha(BLACK, 0.45)}`,\n 'shadow-lg': `0 4px 8px ${alpha(BLACK, 0.4)}, 0 16px 32px ${alpha(BLACK, 0.55)}`,\n 'shadow-xl': `0 8px 16px ${alpha(BLACK, 0.45)}, 0 28px 56px ${alpha(BLACK, 0.6)}`,\n 'shadow-up': `0 -2px 4px ${alpha(BLACK, 0.3)}, 0 -8px 24px ${alpha(BLACK, 0.45)}`,\n\n ring: `0 0 0 3px ${alpha(BLUE.dark, 0.36)}`,\n 'ring-color': BLUE.dark,\n 'ring-danger': `0 0 0 3px ${alpha(DANGER_SOLID.dark, 0.32)}`,\n 'ring-ok': `0 0 0 4px ${alpha(STATUS.okFgDark, 0.2)}`,\n\n scrim: alpha(BLACK, 0.68),\n 'scrim-soft': alpha(BLACK, 0.45),\n glass: alpha('#1f242d', 0.92),\n 'glass-solid': '#1f242d',\n 'on-scrim': NEUTRAL.n0,\n\n 'skeleton-a': '#1f242d',\n 'skeleton-b': '#262c36',\n track: alpha(NEUTRAL.n0, 0.14),\n\n 'media-bg': '#1f242d',\n\n 'glow-1': alpha(BLUE.base, 0.2),\n 'glow-2': alpha(BLUE.dark, 0.1),\n 'glow-amber': alpha(AMBER.dark, 0.12),\n};\n\n/** Token adları — `LIGHT_THEME`den türetilir, elle listelenmez. */\nexport type HanuiToken = keyof typeof LIGHT_THEME;\n\n/** Bir temanın token → değer eşlemesi. Kısmî verilebilir; eksikler varsayılandan gelir. */\nexport type HanuiThemeTokens = Partial<Record<HanuiToken, string>>;\n\n/** Bir temanın TAM eşlemesi. */\nexport type HanuiResolvedTokens = Record<HanuiToken, string>;\n\n/** Kullanıcının seçtiği tema. `system` işletim sistemi tercihini izler. */\nexport type HanuiColorScheme = 'light' | 'dark';\n\n/**\n * Yazı tipi ailesi sözleşmesi.\n *\n * <p>Üç rol ayrı: başlık (≥19 px), arayüz metni (11–16 px) ve teknik veri\n * (kod, seri numarası, tutar). KÜÇÜK ARAYÜZ METNİ BAŞLIK FONTUNU KULLANMAZ —\n * grotesk başlık yüzleri 12–14 px yarı-kalında sıkışıp okunurluğu düşürüyor\n * ve düğme etiketleri bir arayüzün en çok okunan kısa metinleri.\n *\n * <p>Kütüphane font YÜKLEMEZ: değerler `font-family` dizesi olarak geçer ve\n * yüklemeyi (next/font, @font-face, CDN) tüketici yapar. Bir UI paketinin\n * ağdan font çekmesi, tüketicinin ölçemediği bir istek demek.\n */\nexport type HanuiFonts = Partial<{\n heading: string;\n body: string;\n mono: string;\n}>;\n\n/** Kütüphanenin varsayılan font yığınları — hepsi sistem fontlarına iner. */\nexport const DEFAULT_FONTS: Required<HanuiFonts> = {\n heading: \"system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n body: \"system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n mono: \"ui-monospace, 'SF Mono', Menlo, Consolas, monospace\",\n};\n\n/**\n * Dışarıdan verilebilecek tema yapılandırması.\n *\n * @example\n * initHanui({\n * theme: {\n * light: { blue: '#0d6efd', 'blue-text': '#0a58ca' },\n * dark: { blue: '#6ea8fe' },\n * fonts: { heading: 'Archivo, sans-serif' },\n * },\n * });\n */\nexport type HanuiThemeConfig = Partial<{\n light: HanuiThemeTokens;\n dark: HanuiThemeTokens;\n fonts: HanuiFonts;\n}>;\n","import { isClient } from '@ahmetilhn/handy-utils';\n\nimport {\n DARK_THEME,\n DEFAULT_FONTS,\n LIGHT_THEME,\n type HanuiColorScheme,\n type HanuiResolvedTokens,\n type HanuiThemeConfig,\n} from '../theme/tokens';\n\n/** CSS özel özelliği öneki — `_tokens.generated.scss` ile aynı olmak zorunda. */\nexport const TOKEN_PREFIX = '--hanui-';\n\n/** Ezme kurallarını taşıyan `<style>` etiketinin kimliği. */\nexport const THEME_STYLE_ID = 'hanui-theme-overrides';\n\n/** Temanın taşındığı öznitelik. `<html data-hanui-theme=\"dark\">`. */\nexport const THEME_ATTRIBUTE = 'data-hanui-theme';\n\n/** Geçiş animasyonlarını tek kare boyunca kapatan sınıf (bkz. `base.scss`). */\nexport const THEME_SWITCHING_CLASS = 'hanui-theme-switching';\n\n/** Verilen şemanın tam token eşlemesi — ezmeler uygulanmış hâliyle. */\nexport const resolveTokens = (\n scheme: HanuiColorScheme,\n config?: HanuiThemeConfig,\n): HanuiResolvedTokens => {\n const base = scheme === 'dark' ? DARK_THEME : LIGHT_THEME;\n const overrides = (scheme === 'dark' ? config?.dark : config?.light) ?? {};\n\n return { ...base, ...overrides };\n};\n\n/**\n * Yapılandırmayı CSS metnine çevirir.\n *\n * <h3>Neden yalnızca EZİLEN token'lar yazılıyor</h3>\n * Tam eşlemeyi yazmak da çalışırdı ama iki bedeli var: çıktı 90 satır yerine\n * 4 satır olurdu ve daha önemlisi, kütüphane bir sonraki sürümde bir token'ın\n * varsayılanını değiştirdiğinde tüketicinin sayfası ESKİ değeri yazmaya devam\n * ederdi — üstelik ezmediği bir token için. Ezmeler ne ise o yazılır.\n *\n * <h3>Neden `<style>`, neden satır içi stil değil</h3>\n * Satır içi stil yalnızca `<html>` üzerinde durur ve `[data-hanui-theme]`\n * seçicisinden daha yüksek özgüllüktedir: kullanıcı temayı değiştirdiğinde\n * ezmeler HER İKİ temada da aynı kalıyordu. Ayrı bir kural bloğu, açık ve\n * koyu ezmeleri kendi seçicilerine bağlar.\n */\nexport const buildThemeCss = (config: HanuiThemeConfig): string => {\n const blocks: string[] = [];\n\n const declarations = (tokens: Record<string, string>, indent = ' ') =>\n Object.entries(tokens)\n .map(([name, value]) => `${indent}${TOKEN_PREFIX}${name}: ${value};`)\n .join('\\n');\n\n const fonts = config.fonts ?? {};\n const fontEntries = Object.entries(fonts).filter(([, value]) => Boolean(value)) as [\n keyof typeof DEFAULT_FONTS,\n string,\n ][];\n\n if (fontEntries.length > 0)\n blocks.push(\n `:root {\\n${fontEntries\n .map(([role, stack]) => ` ${TOKEN_PREFIX}font-${role}: ${stack};`)\n .join('\\n')}\\n}`,\n );\n\n /*\n * Acik tema iki secicide birden yazilir: `:root` (varsayilan) ve\n * `:root[data-hanui-theme='light']` (kullanicinin acik secimi). Yalnizca\n * `:root` yazilsaydi, sistem tercihi koyu olan bir cihazda acik temayi ELLE\n * secen kullanicida ezmeler dusuyordu — cunku uretilmis koyu blok\n * `:root:not([data-hanui-theme])` degil `[data-hanui-theme='light']` ile\n * yarisiyor ve ozgullukte kazaniyor.\n */\n if (config.light && Object.keys(config.light).length > 0) {\n const body = declarations(config.light);\n blocks.push(`:root {\\n${body}\\n}`);\n blocks.push(`:root[${THEME_ATTRIBUTE}='light'] {\\n${body}\\n}`);\n }\n\n if (config.dark && Object.keys(config.dark).length > 0) {\n const body = declarations(config.dark);\n blocks.push(`:root[${THEME_ATTRIBUTE}='dark'] {\\n${body}\\n}`);\n blocks.push(\n `@media (prefers-color-scheme: dark) {\\n :root:not([${THEME_ATTRIBUTE}]) {\\n${declarations(\n config.dark,\n ' ',\n )}\\n }\\n}`,\n );\n }\n\n return blocks.join('\\n\\n');\n};\n\n/**\n * Ezmeleri belgeye yazar. Aynı `<style>` etiketi tekrar kullanılır: her\n * çağrıda yeni bir etiket eklemek, birbirini ezen onlarca blok bırakıyordu.\n *\n * <p>Etiket `<head>`in SONUNA eklenir — paket CSS'i ondan önce yüklenmiş\n * olmalı ki eşit özgüllükte ezme kazansın.\n */\nexport const applyThemeConfig = (config: HanuiThemeConfig | undefined): void => {\n if (!isClient()) return;\n\n const css = config ? buildThemeCss(config) : '';\n const existing = document.getElementById(THEME_STYLE_ID);\n\n if (css === '') {\n existing?.remove();\n return;\n }\n\n const element = existing ?? document.createElement('style');\n element.id = THEME_STYLE_ID;\n element.textContent = css;\n\n if (!existing) document.head.appendChild(element);\n};\n","'use client';\n\nimport { createContext, useContext } from 'react';\n\nimport type { HanuiLinkComponent } from '../types/link.type';\nimport type { HanuiThemeConfig } from './tokens';\n\nexport type HanuiContextValue = {\n /**\n * Tüketicinin yönlendiricisi (`next/link`, `react-router`ın `Link`i…).\n *\n * <p>Verilmezse ham `<a>` çizilir ve gezinme tam sayfa yenilemesi olur.\n * Bir bileşen kütüphanesi kendi yönlendiricisini SEÇEMEZ: `next/link`\n * import etmek paketi Next'e bağlar, `react-router` import etmek başka bir\n * uygulamayı kırar. Karar tüketicinin.\n */\n linkComponent?: HanuiLinkComponent;\n /** Uygulanan tema ezmeleri. Salt okunur; değiştirmek için `HanuiProvider`. */\n theme?: HanuiThemeConfig;\n};\n\nconst HanuiContext = createContext<HanuiContextValue>({});\n\n/**\n * Sağlayıcı ZORUNLU DEĞİL.\n *\n * <p>Sağlayıcısız kullanımda bağlantılar ham `<a>` olur ve tema\n * varsayılanlarda kalır — yani paket `import` edilip hiçbir kurulum\n * yapılmadan çalışır. Sağlayıcıyı zorunlu kılmak, tek bir `Badge` kullanmak\n * isteyen bir tüketiciyi de kök yerleşimi değiştirmeye zorluyordu.\n */\nexport const useHanui = (): HanuiContextValue => useContext(HanuiContext);\n\nexport default HanuiContext;\n","'use client';\n\nimport { type FC, type ReactNode, useEffect, useMemo } from 'react';\n\nimport { applyThemeConfig } from '../helpers/theme.helper';\nimport type { HanuiLinkComponent } from '../types/link.type';\nimport HanuiContext from './context';\nimport type { HanuiThemeConfig } from './tokens';\n\ntype Props = {\n children: ReactNode;\n /**\n * Tema ezmeleri. Yalnızca DEĞİŞTİRİLEN token'lar verilir; verilmeyen her\n * token varsayılanında kalır.\n *\n * <p>Nesne referansı her render'da yeniden üretilirse (satır içi nesne\n * literali) `<style>` etiketi de her render'da yeniden yazılır. Bileşen\n * bunu içerik karşılaştırmasıyla engeller ama yine de sabit bir referans\n * (modül düzeyinde tanımlı bir nesne) tercih edilmeli.\n */\n theme?: HanuiThemeConfig;\n /**\n * Tüketicinin bağlantı bileşeni. Verilmezse ham `<a>` çizilir.\n *\n * @example\n * import NextLink from 'next/link';\n * <HanuiProvider linkComponent={NextLink}>…</HanuiProvider>\n */\n linkComponent?: HanuiLinkComponent;\n};\n\n/**\n * Kütüphane sağlayıcısı.\n *\n * <h3>İki iş yapar, üçüncüsünü YAPMAZ</h3>\n * <ol>\n * <li>Tema ezmelerini belgeye yazar (`<style id=\"hanui-theme-overrides\">`).</li>\n * <li>Yönlendirici bileşenini bileşen ağacına dağıtır.</li>\n * <li><strong>Açık/koyu seçimini YÖNETMEZ.</strong></li>\n * </ol>\n *\n * <h3>Neden tema seçimi burada değil</h3>\n * Seçim `<html data-hanui-theme>` üzerinde taşınır ve o özniteliğin\n * <em>boyamadan önce</em> yazılması gerekir: React ağacı monte olduktan sonra\n * yazıldığında koyu tema seçmiş kullanıcı bir kare beyaz ekran görüyor. Doğru\n * yer, sunucudan gelen HTML'in `<head>`ine konan satır içi bir betik — ve\n * oraya yazmak tüketicinin çatısının işi (Next'te `app/layout.tsx`, Vite'ta\n * `index.html`). Sağlayıcı ondan sonra monte oluyor; oraya koymak sorunu\n * çözmüyor, gizliyor.\n *\n * <p>`useHanuiTheme` kancası seçimi <em>değiştirmek</em> için var; ilk değeri\n * yazmak için değil. README \"Tema\" bölümünde hazır betik duruyor.\n *\n * @example\n * <HanuiProvider linkComponent={NextLink} theme={{ light: { blue: '#0d6efd' } }}>\n * <App />\n * </HanuiProvider>\n */\nconst HanuiProvider: FC<Props> = ({ children, theme, linkComponent }) => {\n /*\n * `JSON.stringify` bagimlilik anahtari olarak kullaniliyor: cagiran taraf\n * neredeyse her zaman satir ici bir nesne literali veriyor ve referans her\n * render'da degisiyor. Referansa baglansaydi `<style>` etiketi saniyede\n * onlarca kez yeniden yazilirdi.\n */\n const themeKey = useMemo(() => (theme ? JSON.stringify(theme) : ''), [theme]);\n\n useEffect(() => {\n applyThemeConfig(theme);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [themeKey]);\n\n /* Bagimlilik `themeKey`: `theme` referansi her render'da degistigi icin\n ona baglanan bir memo hicbir sey saklamaz ve tuketicideki her bilesen\n bos yere yeniden cizilir. */\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const value = useMemo(() => ({ theme, linkComponent }), [themeKey, linkComponent]);\n\n return <HanuiContext.Provider value={value}>{children}</HanuiContext.Provider>;\n};\n\nexport default HanuiProvider;\n","import { isClient } from '@ahmetilhn/handy-utils';\n\nimport { applyThemeConfig, THEME_ATTRIBUTE } from '../helpers/theme.helper';\nimport type { HanuiColorScheme, HanuiThemeConfig } from './tokens';\n\nexport type InitHanuiOptions = Partial<{\n /** Tema ezmeleri. Yalnızca değiştirilen token'lar verilir. */\n theme: HanuiThemeConfig;\n /**\n * Başlangıç şeması. Verilmezse `<html data-hanui-theme>` neyse o kalır;\n * o da yoksa sistem tercihi (`prefers-color-scheme`) devreye girer.\n */\n colorScheme: HanuiColorScheme;\n}>;\n\n/**\n * Kütüphaneyi <strong>React ağacının dışından</strong> yapılandırır.\n *\n * <h3>Ne zaman bu, ne zaman `HanuiProvider`</h3>\n * `HanuiProvider` React'in içinde yaşıyor ve yönlendirici bileşenini de\n * taşıyor — normal yol o. Bu fonksiyon iki durum için:\n *\n * <ul>\n * <li><strong>Boyamadan önce çalışması gereken tema.</strong> Sağlayıcı\n * ağaç monte olduktan sonra yazıyor; koyu tema seçmiş bir kullanıcı o\n * ana kadar beyaz ekran görüyor. `<head>` içindeki satır içi bir\n * betikten çağrıldığında ezmeler ilk boyamadan önce yerinde olur.</li>\n * <li><strong>React kullanmayan bir kabuk.</strong> Tasarım token'ları\n * yalnızca CSS; bir e-posta önizlemesi ya da Storybook temasında\n * bileşen ağacı olmadan da gerekiyor.</li>\n * </ul>\n *\n * <p>İkisi birlikte kullanılabilir: aynı `<style>` etiketini paylaşırlar ve\n * son çağrı kazanır.\n *\n * @example\n * // app/layout.tsx — <head> içine, boyamadan önce.\n * <script dangerouslySetInnerHTML={{ __html: `\n * document.documentElement.dataset.hanuiTheme =\n * localStorage.getItem('theme') ?? 'light';\n * ` }} />\n */\nexport const initHanui = (options: InitHanuiOptions = {}): void => {\n applyThemeConfig(options.theme);\n\n if (!isClient() || !options.colorScheme) return;\n\n document.documentElement.setAttribute(THEME_ATTRIBUTE, options.colorScheme);\n};\n\nexport default initHanui;\n","'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\n\nimport { isClient } from '@ahmetilhn/handy-utils';\n\nimport { THEME_ATTRIBUTE, THEME_SWITCHING_CLASS } from '../helpers/theme.helper';\nimport type { HanuiColorScheme } from '../theme/tokens';\n\n/** Sistem tercihini okur. Betik hiç çalışmamışsa ilk değer buradan gelir. */\nconst readSystemScheme = (): HanuiColorScheme =>\n isClient() && window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n\n/** `<html>` üzerindeki mevcut seçim; yoksa sistem tercihi. */\nconst readScheme = (): HanuiColorScheme => {\n if (!isClient()) return 'light';\n\n const attribute = document.documentElement.getAttribute(THEME_ATTRIBUTE);\n return attribute === 'dark' || attribute === 'light' ? attribute : readSystemScheme();\n};\n\ntype ThemeState = {\n scheme: HanuiColorScheme;\n setScheme: (scheme: HanuiColorScheme) => void;\n toggle: () => void;\n /**\n * Sunucu çıktısında ve hidrasyondan önceki ilk karede `false`.\n *\n * <p>Tema anahtarı bunu bekler: sunucu hangi temanın seçili olduğunu\n * bilmiyor ve bir tahminle çizilen anahtar, doğru tahmin edilse bile\n * hidrasyonda uyuşmazlık üretiyordu. Anahtar hazır olana kadar\n * `aria-hidden` bir yer tutucu çizilir.\n */\n isReady: boolean;\n};\n\n/**\n * Açık/koyu seçimini okur ve değiştirir.\n *\n * <h3>KALICILIK BU KANCANIN İŞİ DEĞİL</h3>\n * Seçimi nereye yazacağı tüketicinin kararı: `localStorage`, bir çerez (SSR'da\n * okunabilmesi için), kullanıcı profili. Kütüphane `localStorage`a yazsaydı\n * sunucu tarafı onu okuyamayacağı için ilk boyama yine yanlış temada\n * olurdu — ve tüketici kendi çerezini kullanmak istediğinde iki kaynak\n * çatışırdı.\n *\n * <h3>Geçiş tek karede kapatılır</h3>\n * Şema değişirken `<html>` bir kare boyunca `hanui-theme-switching` sınıfını\n * taşır. Sınıfsız hâlde her yüzey aynı anda ama FARKLI sürelerde animasyon\n * yapıyordu (kart gölgesi 140 ms, sayfa zemini 200 ms) ve geçiş dalgalı\n * görünüyordu. Ani geçiş, dalgalı geçişten iyi.\n *\n * @example\n * const { scheme, toggle, isReady } = useHanuiTheme();\n *\n * useEffect(() => {\n * if (isReady) localStorage.setItem('theme', scheme);\n * }, [scheme, isReady]);\n */\nconst useHanuiTheme = (): ThemeState => {\n /*\n * Ilk deger SABIT 'light': sunucuda `document` yok ve istemcideki gercek\n * degeri ilk render'da okumak hidrasyon uyusmazligi uretiyordu (sunucu\n * \"light\" cizdi, istemci \"dark\" okudu). Gercek deger monte olduktan sonra\n * yaziliyor ve `isReady` o ana kadar false kaliyor.\n */\n const [scheme, setSchemeState] = useState<HanuiColorScheme>('light');\n const [isReady, setIsReady] = useState(false);\n\n useEffect(() => {\n setSchemeState(readScheme());\n setIsReady(true);\n }, []);\n\n /* Kullanicinin ACIK bir secimi yoksa sistem tercihi izlenmeye devam eder. */\n useEffect(() => {\n if (!isClient() || !window.matchMedia) return;\n\n const query = window.matchMedia('(prefers-color-scheme: dark)');\n const handleChange = () => {\n if (document.documentElement.hasAttribute(THEME_ATTRIBUTE)) return;\n setSchemeState(readSystemScheme());\n };\n\n query.addEventListener('change', handleChange);\n return () => query.removeEventListener('change', handleChange);\n }, []);\n\n const setScheme = useCallback((next: HanuiColorScheme) => {\n if (!isClient()) return;\n\n const root = document.documentElement;\n\n root.classList.add(THEME_SWITCHING_CLASS);\n root.setAttribute(THEME_ATTRIBUTE, next);\n setSchemeState(next);\n\n /*\n * Sinif BIR SONRAKI karede kaldirilir. Ayni karede kaldirilsaydi tarayici\n * hicbir zaman gecissiz bir boyama yapmayacak ve sinifin varligi hicbir\n * ise yaramayacakti.\n */\n window.requestAnimationFrame(() => {\n window.requestAnimationFrame(() => root.classList.remove(THEME_SWITCHING_CLASS));\n });\n }, []);\n\n const toggle = useCallback(\n () => setScheme(scheme === 'dark' ? 'light' : 'dark'),\n [scheme, setScheme],\n );\n\n return { scheme, setScheme, toggle, isReady };\n};\n\nexport default useHanuiTheme;\n","'use client';\n\nimport { useEffect } from 'react';\n\n/** Panelin kaplayabilecegi en fazla yukseklik — GORUNEN alanin yuksekligi. */\nconst HEIGHT_VAR = '--hanui-sheet-height';\n\n/** Panelin dibinin, yerlesim gorunum alaninin dibinden ne kadar yukarida duracagi. */\nconst INSET_VAR = '--hanui-sheet-inset-bottom';\n\n/*\n * Tek olcum, tek dinleyici.\n *\n * Ayni anda birden fazla alt sayfa acilabiliyor (filtre panelinin icindeki bir\n * secim kutusu gibi). Her biri kendi dinleyicisini kursaydi ayni karede ayni\n * degeri birkac kez yazacak, ustelik ustteki panel kapandiginda alttaki hala\n * acikken degiskenler silinecekti. Sayac sifirlanmadan hicbir sey kaldirilmaz.\n */\nlet openCount = 0;\nlet frame = 0;\n\n/**\n * Gorsel gorunum alanini olcup CSS degiskenlerine yazar.\n *\n * `window.innerHeight` YERLESIM gorunum alanidir: iOS'ta adres cubugu\n * daralmis kabul edilerek hesaplanir ve klavye onu hic kucultmez.\n * `visualViewport` ise gercekten GORUNEN alandir. Ikisinin farki, ekranin\n * dibinde kullanicinin goremedigi seridin yuksekligi: klavye, tarayicinin alt\n * cubugu ya da adres cubugu genisken asagi tasan bolum.\n *\n * `position: fixed; bottom: 0` yerlesim gorunum alanina gore hizalanir — yani\n * o seridin ALTINA. Panel bu yuzden dibinden kirpik goruluyordu; kisa bir\n * panel (alti secenekli bir liste) neredeyse yarisini kaybederken ekranin\n * cogunu kaplayan bir panel ayni kaymayi gorunur kilmiyordu.\n */\nconst measure = () => {\n const viewport = window.visualViewport;\n if (!viewport) return;\n\n const covered = window.innerHeight - viewport.height - viewport.offsetTop;\n const root = document.documentElement;\n\n root.style.setProperty(INSET_VAR, `${Math.max(0, Math.round(covered))}px`);\n root.style.setProperty(HEIGHT_VAR, `${Math.round(viewport.height)}px`);\n};\n\n/* Klavye acilirken `resize` ve `scroll` ard arda dusuyor; kare basina bir\n olcum yeterli ve her olcum bir yerlesim okumasi. */\nconst schedule = () => {\n if (frame) return;\n frame = window.requestAnimationFrame(() => {\n frame = 0;\n measure();\n });\n};\n\n/**\n * Alt sayfayi <strong>gorunen</strong> alana yaslar.\n *\n * <h3>Neden `dvh` ve `env()` yetmiyor</h3>\n * `dvh` tarayici cubuklarini hesaba katar ama <em>klavyeyi katmaz</em>;\n * `env(safe-area-inset-bottom)` ise cihazin centik/ana ekran cubugu payidir, o\n * da klavyeden habersiz. iOS'ta klavye acildiginda yerlesim gorunum alani hic\n * degismez: panel oldugu yerde durur, klavye uzerine biner ve alt yarisi —\n * arama kutusuyla birlikte — erisilemez hale gelir.\n *\n * <h3>Android'de ne oluyor</h3>\n * Tuketici `interactiveWidget: 'resizes-content'` verdiginde orada klavye\n * yerlesim alanini da kuculttugu icin fark sifir cikar ve bu kanca hicbir sey\n * degistirmez. Duzeltme iOS icindir, ama olcum platformdan bagimsiz dogru.\n *\n * <h3>Degiskenler `<html>` uzerinde</h3>\n * Panelin kendisine yazilamaz: `::backdrop` ve `<dialog>` ust katmandadir,\n * ayrica ayni degeri iki farkli panel paylasiyor. Kok ogeye yazmak tek kaynak\n * birakir.\n *\n * @param isActive Panel acik mi. Yalnizca acikken olculur: kendisi yalnizca\n * acikken cizilen bir panel varsayilani kullanir, ama sayfa boyunca DOM'da\n * duran bir panel bayraksiz cagirdiginda her kullanicida iki gorunum alani\n * dinleyicisi bos yere acik kaliyordu.\n */\nconst useSheetViewport = (isActive = true) => {\n useEffect(() => {\n if (!isActive) return;\n\n const viewport = window.visualViewport;\n if (!viewport) return;\n\n openCount += 1;\n\n if (openCount === 1) {\n viewport.addEventListener('resize', schedule);\n viewport.addEventListener('scroll', schedule);\n window.addEventListener('orientationchange', schedule);\n }\n\n measure();\n\n return () => {\n openCount -= 1;\n if (openCount > 0) return;\n\n viewport.removeEventListener('resize', schedule);\n viewport.removeEventListener('scroll', schedule);\n window.removeEventListener('orientationchange', schedule);\n\n if (frame) {\n window.cancelAnimationFrame(frame);\n frame = 0;\n }\n\n /* Degiskenler SILINIR, sifirlanmaz: yedek deger CSS'te\n (`var(…, 0px)` / `var(…, 100dvh)`) ve panel kapaliyken dogru olan o. */\n document.documentElement.style.removeProperty(INSET_VAR);\n document.documentElement.style.removeProperty(HEIGHT_VAR);\n };\n }, [isActive]);\n};\n\nexport default useSheetViewport;\n","/**\n * Düğme ve eylem varyantları.\n *\n * <p>Sıra bir <strong>vurgu hiyerarşisi</strong>dir: bir ekranda tek bir\n * `PRIMARY` bulunur. İki dolu düğme yan yana durduğunda hiçbiri öne çıkmaz ve\n * kullanıcı hangisinin beklenen eylem olduğunu bilemez.\n *\n * <h3>Doygun dolgu = tıklanabilir</h3>\n * Bu kuralın karşılığı: durum etiketleri (rozet, uyarı) her zaman tint\n * zeminlidir, eylemler her zaman dolgulu veya çerçevelidir. İkisi karışırsa\n * kullanıcı bir durum etiketine tıklamayı dener.\n */\nenum UIVariant {\n /**\n * Ekranın tek beklenen eylemi: <strong>nötr grafit</strong> dolgu.\n *\n * <p>`CART` DEĞİL. Doygun turuncu tek bir dönüşüm noktasına ayrıldı; her\n * dolu düğmeyi o renge boyamak tekilliği yok eder ve kullanıcı hangi\n * turuncunun dönüşüm olduğunu bilemez.\n */\n PRIMARY = 'PRIMARY',\n /**\n * <strong>Dönüşüm eylemi — ve yalnızca o.</strong>\n *\n * <p>Ekranda görünen tek doygun turuncu. Favori, karşılaştır, paylaş,\n * filtrele hepsi nötr veya mavidir. Bir kampanya bandında bu ton\n * kullanılırsa o ekranda dönüşüm düğmesi `PRIMARY`'ye çevrilir — ikisi aynı\n * anda olmaz.\n *\n * <p>Adı domain'den geliyor (kaynak sistemde \"sepete ekle\") ve\n * kasıtlı korundu: bir ekranda kaç tane olabileceğini adın kendisi\n * söylüyor. `ACCENT` deseydi hiyerarşi bilgisi kaybolurdu.\n */\n CART = 'CART',\n /** Nötr ikincil eylem: gri kenarlık, koyu metin (\"Vazgeç\"). */\n SECONDARY = 'SECONDARY',\n /**\n * Mavi çerçeveli eylem — teşvik edilen ama birincil olmayan gezinme\n * (\"Tümünü gör\").\n *\n * <p>Çerçeveli, dolgulu değil: mavi gezinme ve keşif rengidir; dolu mavi\n * düğme onu bir dönüşüm noktası gibi gösterip `CART` ile yarışıyordu.\n */\n OUTLINE = 'OUTLINE',\n /** Vurgu bandı içindeki eylem: bandın kendi yüzey merdivenini kullanır. */\n DARK = 'DARK',\n /** Nötr yüzey dolgusu; kart içi ikincil eylem. */\n LIGHT = 'LIGHT',\n /** Zeminsiz eylem: araç çubuğu ve satır içi ikincil işler. */\n GHOST = 'GHOST',\n /** Yıkıcı eylem: silme onayı. Durum tinti değil, gerçek bir dolgu. */\n DANGER = 'DANGER',\n}\n\nexport default UIVariant;\n","/**\n * Ölçü basamakları.\n *\n * <p>`MEDIUM` ve `LARGE` dokunma hedefi kuralına uyar (WCAG 2.5.8, ≥44 px).\n * `SMALL` yoğun şeritler içindir ve orada görsel kutu küçülür ama tıklanabilir\n * alan `tap-target` ile korunur.\n */\nenum UISize {\n SMALL = 'SMALL',\n MEDIUM = 'MEDIUM',\n LARGE = 'LARGE',\n}\n\nexport default UISize;\n","/**\n * Kırılma noktaları — `styles/_variables.scss` içindeki `$breakpoint-*` ile\n * <strong>aynı</strong> değerler.\n *\n * <p>Kararı normalde CSS verir; bu sabitler yalnızca <em>JavaScript'in de\n * bilmek zorunda olduğu</em> tek durum için var: kipsel bir panel\n * (`<dialog>`) açıkken pencere büyütüldüğünde. `showModal()` sayfanın geri\n * kalanını inert bırakır ve bu, panelin çizilip çizilmediğine değil kipsel\n * olmasına bağlıdır — CSS onu gizlese bile sayfa tıklanamaz kalır. Panel bu\n * yüzden kırılma noktası aşıldığında JavaScript ile kapatılır.\n *\n * <p>Değerler iki yerde durduğu için ayrışabilir. Ayrışırlarsa panel yanlış\n * genişlikte kapanır; CSS tarafı her zaman kazanır, buradaki değer ona\n * uydurulur.\n */\nexport const MOBILE_BREAKPOINT = 640;\n\nexport const TABLET_PORTRAIT_BREAKPOINT = 768;\n\nexport const TABLET_BREAKPOINT = 1024;\n\n/** Kenar çubuğu ekranda olduğu için filtre paneli bu ölçünün üstünde gizlenir. */\nexport const ABOVE_TABLET_MEDIA_QUERY = `(min-width: ${TABLET_BREAKPOINT + 1}px)`;\n\n/** Seçim kutusunun alt sayfası yalnızca bu ölçünün altında kullanılır. */\nexport const ABOVE_MOBILE_MEDIA_QUERY = `(min-width: ${MOBILE_BREAKPOINT + 1}px)`;\n","/**\n * Metin normalizasyonu — aksan ve büyük/küçük harf duyarsız arama.\n *\n * <p>{@link matchesSearch} `Combobox`ın yerel filtresidir. Sunucu araması\n * (`onSearch`) verildiğinde bileşen hiç filtrelemez; bu yol yalnızca elde\n * duran bir listeyi taramak için.\n */\n\n/**\n * Serbest metin arama anahtarı: ASCII, küçük harf, tek boşlukla ayrılmış.\n *\n * <h3>Neden aksan sökülüyor</h3>\n * Kullanıcı \"sisli\" yazdığında \"Şişli\" bulunmalı. Doğru aksanı yakalamak\n * zorunda kalmak — özellikle mobil klavyede — aramayı bitiren bir sürtünme.\n *\n * <h3>Türkçe `İ` özel durumu</h3>\n * `toLowerCase()`ten <em>önce</em> `İ → i` eşlenir: varsayılan küçültme\n * \"İSTANBUL\"u \"i̇stanbul\" (birleşik nokta ile) yapıyor ve eşleşmeyi\n * kaçırıyordu. Aynı sorun `ı` için ters yönde yok — o zaten tek kod noktası.\n *\n * <p>Latin-1 aksanları (`é`, `ñ`, `ü`…) `NFD` ayrıştırması + birleştirici\n * işaret temizliğiyle sökülür; Türkçe harfler bu yolla çözülmediği için\n * (`ı` ve `İ` ayrı kod noktaları) önce elle eşlenir.\n */\nexport const normalizeSearchTerm = (value: string): string =>\n value\n .replace(/İ/g, 'i')\n .replace(/I/g, 'i')\n .replace(/ı/g, 'i')\n .toLowerCase()\n .normalize('NFD')\n /* Birlestirici aksan isaretleri (U+0300–U+036F). */\n .replace(/[\\u0300-\\u036f]/g, '')\n /* NFD'nin ayristirmadigi harfler: her biri tek kod noktasi. */\n .replace(/ş/g, 's')\n .replace(/ğ/g, 'g')\n .replace(/ç/g, 'c')\n .replace(/ø/g, 'o')\n .replace(/æ/g, 'ae')\n .replace(/ß/g, 'ss')\n .replace(/đ/g, 'd')\n .replace(/ł/g, 'l')\n .replace(/\\s+/g, ' ')\n .trim();\n\n/**\n * Aranan metin, hedefin içinde geçiyor mu?\n *\n * <p>Aramanın tek kapısı burasıdır: her liste kendi `includes` çağrısını\n * yazdığında biri normalizasyonu atlıyor ve o listede aksanlı arama\n * çalışmıyordu.\n */\nexport const matchesSearch = (haystack: string, needle: string): boolean =>\n normalizeSearchTerm(haystack).includes(normalizeSearchTerm(needle));\n","/**\n * Kipsel panel açılırken ekran klavyesinin kendiliğinden açılmasını engeller.\n *\n * <h3>Sorun</h3>\n * `showModal()` odağı panelin <strong>ilk odaklanabilir öğesine</strong> taşır\n * (HTML \"dialog focusing steps\"). O öğe bir metin alanıysa telefonda klavye\n * kendiliğinden açılır: alt sayfa yarı yüksekliğe sıkışır, liste kısalır ve\n * kullanıcı yazmak istemediği hâlde önce klavyeyi kapatmak zorunda kalır.\n *\n * <h3>Neden odak tümüyle bırakılmıyor</h3>\n * Odağı panelin dışında bırakmak kip semantiğini bozar: odak tuzağı çalışmaz,\n * Escape panele ulaşmaz ve ekran okuyucu paneli hiç duyurmaz. Odak panelin\n * KENDİSİNE alınır — kip davranışı durur, klavye açılmaz.\n */\n\n/** Odaklanınca ekran klavyesi AÇMAYAN giriş türleri. */\nconst NON_TEXT_INPUT_TYPES = new Set([\n 'button',\n 'checkbox',\n 'color',\n 'file',\n 'hidden',\n 'image',\n 'radio',\n 'range',\n 'reset',\n 'submit',\n]);\n\n/** Odaklanınca mobilde ekran klavyesini açacak bir öğe mi? */\nexport const isKeyboardOpeningElement = (element: Element | null): boolean => {\n if (!(element instanceof HTMLElement)) return false;\n\n /* `isContentEditable` mirasi da kapsar (duzenlenebilir bolgenin ICINDEKI\n oge), ama jsdom onu uygulamiyor ve her zaman false donuyor; oznitelik\n kontrolu testte de gecerli olan yedek. */\n if (element.isContentEditable) return true;\n const editable = element.getAttribute('contenteditable');\n if (editable === '' || editable === 'true' || editable === 'plaintext-only') return true;\n\n const tagName = element.tagName;\n if (tagName === 'TEXTAREA') return true;\n if (tagName !== 'INPUT') return false;\n\n return !NON_TEXT_INPUT_TYPES.has((element as HTMLInputElement).type);\n};\n\n/**\n * `showModal()` ÇAĞRILDIKTAN SONRA çağrılır. Odak bir metin alanına düştüyse\n * panelin kendisine geri alınır; düşmediyse hiçbir şey yapılmaz.\n */\nexport const preventAutoKeyboard = (dialog: HTMLDialogElement): void => {\n const active = dialog.ownerDocument.activeElement;\n if (!dialog.contains(active) || !isKeyboardOpeningElement(active)) return;\n\n (active as HTMLElement).blur();\n // `<dialog>` varsayılan olarak odaklanabilir değil; odağı alabilmesi için\n // sıra dışı bırakılır (Tab ile gezinmede görünmez, `focus()` ile alınır).\n dialog.tabIndex = -1;\n dialog.focus({ preventScroll: true });\n};\n","/** Sınıf birleştiricinin kabul ettiği değerler. */\nexport type ClassValue = string | false | null | undefined;\n\n/**\n * Sınıf adı birleştirici.\n *\n * <h3>Neden `clsx` değil</h3>\n * Kaynak tasarım sistemi `clsx` kullanıyordu ve orada doğruydu — bir\n * uygulamada 500 baytlık bir bağımlılık bedava. Bir <em>kütüphanede</em> aynı\n * bağımlılık tüketicinin ağacına ineriyor ve `clsx`ın desteklediği yedi\n * girdi biçiminden (nesne, iç içe dizi, sayı…) burada yalnızca ikisi\n * kullanılıyor: dize ve koşullu dize.\n *\n * <p>Bilerek DAR: nesne biçimi (`{ active: true }`) desteklenmez. Desteklemek\n * çağrı yerlerinde iki ayrı yazım stiline yol açıyor ve hangisinin kullanıldığı\n * dosyadan dosyaya değişiyordu.\n */\nexport const cx = (...values: ClassValue[]): string => {\n let result = '';\n\n for (const value of values) {\n if (!value) continue;\n result = result === '' ? value : `${result} ${value}`;\n }\n\n return result;\n};\n","'use client';\n\nimport type { AnchorHTMLAttributes, FC } from 'react';\n\nimport { useHanui } from '../../theme/context';\nimport type { HanuiLinkProps } from '../../types/link.type';\n\n/**\n * Kütüphanenin İÇ bağlantı öğesi.\n *\n * <p>Sağlayıcıya bir `linkComponent` verilmişse ona, verilmemişse ham `<a>`ya\n * çizilir. Böylece bir bağlantı taşıyan her bileşen (`Button href`, `Chip`,\n * `Breadcrumb`, `Pagination`, `TextLink`, `Directory`, `Tile`) yönlendirici\n * kararını TEK yerden alır.\n *\n * <p>Bileşenler bunu doğrudan dışa vermez: tüketici zaten kendi Link'ini\n * kullanır. Dışa vermek \"hanui'nin Link'i\" diye üçüncü bir kavram üretirdi.\n *\n * <h3>Neden `forwardRef` değil</h3>\n * `HanuiLinkProps` yönlendiriciye özgü ek props için bir indeks imzası\n * taşıyor ve `forwardRef`in `PropsWithoutRef` eşlemesi o imzayı açıkça\n * bildirilmiş `children`ın üstüne geçirip tipini `unknown`a düşürüyordu. Ref'e\n * ihtiyaç da yok: hiçbir çağrı yeri bu öğeye ref vermiyor, verecek olan\n * tüketicinin kendi Link'i.\n */\nconst HanuiLink: FC<HanuiLinkProps> = ({ children, ...rest }) => {\n const { linkComponent: LinkComponent } = useHanui();\n\n if (LinkComponent) return <LinkComponent {...(rest as HanuiLinkProps)}>{children}</LinkComponent>;\n\n /*\n * Yonlendirici yoksa ham `<a>`. `rest` indeks imzasi tasiyor (yonlendiriciye\n * ozgu props icin); DOM'a giderken anchor sozlesmesine daraltilir —\n * tanimadigi bir ozniteligi React zaten oldugu gibi geciriyor.\n */\n return <a {...(rest as AnchorHTMLAttributes<HTMLAnchorElement>)}>{children}</a>;\n};\n\nexport default HanuiLink;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n size?: 'sm' | 'md' | 'lg';\n /**\n * Ekran okuyucuya okunacak metin; görsel olarak gizli.\n *\n * <p>ZORUNLU ve boş dizeye izin verilir. Bekleme durumunun duyurulması\n * gerekiyor (\"Yükleniyor\"), ama göstergenin <em>zaten adı olan</em> bir\n * öğenin içinde durduğu yerlerde (yükleniyor durumundaki bir düğme)\n * duyurmak tekrar üretiyor. O zaman `label=\"\"` geçilir; karar çağıranın\n * ve bilinçli olmak zorunda.\n */\n label: string;\n className?: string;\n};\n\n/**\n * Yükleme göstergesi.\n *\n * <p>İskelet (`Skeleton`) tercih edilir; bu bileşen yalnızca <em>şekli\n * bilinmeyen</em> bir bekleme için — düğme içi işlem veya belirsiz süreli bir\n * sorgu gibi.\n */\nconst Spinner: FC<Props> = ({ size = 'md', label, className }) => (\n <span className={cx(styles.spinner, styles[`spinner--${size}`], className)} role=\"status\">\n <span className={styles.spinner__label}>{label}</span>\n </span>\n);\n\nexport default memo(Spinner) as typeof Spinner;\n","'use client';\n\nimport { type ButtonHTMLAttributes, forwardRef, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport UISize from '../../enums/ui-size.enum';\nimport UIVariant from '../../enums/ui-variant.enum';\nimport type { CommonElementProps } from '../../types/common-element-props.type';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport HanuiLink from '../Link';\nimport Spinner from '../Spinner';\n\nimport styles from './index.module.scss';\n\ntype BaseProps = Partial<{\n variant: UIVariant;\n size: UISize;\n isLoading: boolean;\n isFullWidth: boolean;\n startIcon: ReactNode;\n endIcon: ReactNode;\n}> &\n CommonElementProps;\n\ntype Props = BaseProps &\n ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Verilirse düğme bir bağlantı olarak çizilir. */\n href?: string;\n /**\n * Uygulama dışına çıkan bağlantı: yeni sekmede açılır ve yönlendirici\n * devreye girmez.\n */\n isExternal?: boolean;\n /** Yönlendiriciye geçirilecek ek props (`{ scroll: false }`, `{ replace: true }`). */\n linkProps?: HanuiLinkExtraProps;\n };\n\n/**\n * Düğme.\n *\n * <h3>Yüklenirken içerik korunur</h3>\n * Metin dönen çarkla DEĞİŞTİRİLMEZ, yanına eklenir ve düğme genişliği\n * sabitlenir. Metni değiştirmek düğmeyi daraltıp yerleşimi kaydırıyordu ve\n * kullanıcı neye tıkladığını kaybediyordu.\n *\n * <h3>Bağlantı mı düğme mi</h3>\n * `href` verilirse `<a>` çizilir. Görsel olarak düğme gibi duran bir\n * bağlantının gerçekten `<a>` olması gerekir: orta tuşla yeni sekmede\n * açılması ve tarayıcı geçmişine girmesi beklenen davranıştır.\n *\n * <p>`isExternal` ile birlikte yönlendirici DEĞİL ham `<a>` çizilir ve\n * `target=\"_blank\"` + `rel=\"noopener noreferrer\"` eklenir. Uygulama dışı bir\n * adres için yönlendiriciyi araya sokmak anlamsız; `rel` ise zorunlu —\n * `noopener` olmadan açılan sekme `window.opener` üzerinden bu sayfaya\n * erişebiliyor. Düğme benzeri dış bağlantı elle `<a>` olarak yazılmasın diye\n * burada: elle yazılan her bağlantı odak halkasını ve durum matrisini yeniden\n * kurmak zorunda kalıyordu.\n *\n * @example\n * <Button variant={UIVariant.PRIMARY} isLoading={isSaving} onClick={save}>\n * Kaydet\n * </Button>\n */\nconst Button = forwardRef<HTMLButtonElement, Props>(\n (\n {\n variant = UIVariant.PRIMARY,\n size = UISize.MEDIUM,\n isLoading,\n isFullWidth,\n startIcon,\n endIcon,\n className,\n children,\n disabled,\n href,\n isExternal,\n linkProps,\n testId,\n ...rest\n },\n ref,\n ) => {\n const classNames = cx(\n styles.button,\n styles[`button--${variant.toLowerCase()}`],\n styles[`button--${size.toLowerCase()}`],\n isFullWidth && styles['button--full'],\n isLoading && styles['button--loading'],\n className,\n );\n\n const content = (\n <>\n {isLoading && <Spinner size=\"sm\" className={styles.button__spinner} label=\"\" />}\n {!isLoading && startIcon && <span className={styles.button__icon}>{startIcon}</span>}\n <span className={styles.button__label}>{children}</span>\n {endIcon && <span className={styles.button__icon}>{endIcon}</span>}\n </>\n );\n\n if (href && isExternal)\n return (\n <a\n href={href}\n className={classNames}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={rest['aria-label']}\n data-testid={testId}\n >\n {content}\n </a>\n );\n\n if (href)\n return (\n <HanuiLink href={href} className={classNames} data-testid={testId} {...linkProps}>\n {content}\n </HanuiLink>\n );\n\n return (\n <button\n ref={ref}\n className={classNames}\n disabled={disabled || isLoading}\n aria-busy={isLoading}\n data-testid={testId}\n {...rest}\n >\n {content}\n </button>\n );\n },\n);\n\nButton.displayName = 'Button';\n\nexport default memo(Button) as typeof Button;\n","'use client';\n\nimport { type ButtonHTMLAttributes, forwardRef, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport HanuiLink from '../Link';\n\nimport styles from './index.module.scss';\n\nexport type IconButtonVariant = 'ghost' | 'outline' | 'solid' | 'cart' | 'danger';\n\ntype Props = ButtonHTMLAttributes<HTMLButtonElement> & {\n icon: ReactNode;\n /** Görsel etiketi olmayan düğmenin erişilebilir adı — ZORUNLU. */\n label: string;\n /**\n * `cart` <strong>yalnızca dönüşüm eyleminde</strong> kullanılır — ekranda\n * görünen tek doygun turuncu odur. Nötr dolgu için `solid`.\n */\n variant?: IconButtonVariant;\n size?: 'sm' | 'md';\n /** Verilirse öğe bir bağlantı olarak çizilir. */\n href?: string;\n /** Yönlendiriciye geçirilecek ek props. */\n linkProps?: HanuiLinkExtraProps;\n testId?: string;\n};\n\n/**\n * Yalnızca ikon taşıyan düğme.\n *\n * <p>`label` <strong>zorunlu</strong>: görsel etiketi olmayan bir düğme\n * `aria-label` olmadan ekran okuyucuda \"düğme\" diye okunur. Zorunlu tutmak,\n * unutulmasını derleme zamanında engeller.\n *\n * <p>Dokunma hedefi 44×44 px'ten küçük olamaz (WCAG 2.5.8) — görsel kutu daha\n * küçük olsa bile tıklanabilir alan korunur.\n *\n * <h3>`href` verilince `<a>` çizilir</h3>\n * Bir tablo satırının \"düzenle\" simgesi görsel olarak düğme ama davranışı\n * bağlantı: orta tuşla yeni sekmede açılması, adresinin kopyalanabilmesi ve\n * tarayıcı geçmişine girmesi beklenen davranış. `onClick` + `router.push` ile\n * yazıldığında bunların hiçbiri çalışmıyordu.\n *\n * <p>Bağlantı kipinde `disabled` YOKTUR — `<a>` etiketinin devre dışı hâli\n * yok ve `aria-disabled` tıklamayı engellemez. Erişilemez olması gereken bir\n * eylem hiç çizilmez.\n */\nconst IconButton = forwardRef<HTMLButtonElement, Props>(\n (\n {\n icon,\n label,\n variant = 'ghost',\n size = 'md',\n className,\n type = 'button',\n href,\n linkProps,\n testId,\n ...rest\n },\n ref,\n ) => {\n const classNames = cx(\n styles.iconButton,\n styles[`iconButton--${variant}`],\n styles[`iconButton--${size}`],\n className,\n );\n\n if (href)\n return (\n <HanuiLink\n href={href}\n className={classNames}\n aria-label={label}\n title={rest.title ?? label}\n data-testid={testId}\n {...linkProps}\n >\n {icon}\n </HanuiLink>\n );\n\n return (\n <button\n ref={ref}\n type={type}\n className={classNames}\n aria-label={label}\n title={label}\n data-testid={testId}\n {...rest}\n >\n {icon}\n </button>\n );\n },\n);\n\nIconButton.displayName = 'IconButton';\n\nexport default memo(IconButton) as typeof IconButton;\n","import type { FC, SVGProps } from 'react';\n\n/**\n * KABUK İKONLARI — kütüphanenin kendi çizdiği simgeler.\n *\n * <h3>Neden bir ikon paketi bağımlılığı yok</h3>\n * Kaynak tasarım sistemi `react-bootstrap-icons` kullanıyordu ve bir\n * uygulamada bu doğru: ağaç sallama sonrası yalnızca kullanılan ikonlar\n * kalıyor. Bir <em>kütüphanede</em> aynı seçim tüketiciye zorunlu bir paket\n * dayatmak demek — ve tüketicinin kendi ikon seti varsa iki set birden\n * ineriyor.\n *\n * <p>Buradaki on dokuz ikon <strong>bileşenlerin kabuğuna ait</strong>: bir\n * kip pencerenin kapatma çarpısı, bir seçim kutusunun oku, bir uyarı\n * kutusunun ünlemi. Bunlar içerik değil, bileşenin kendi parçası. İçerik\n * ikonları (kategori simgeleri, marka logoları) her zaman `ReactNode` prop'u\n * olarak DIŞARIDAN gelir.\n *\n * <h3>Ölçü `1em`, renk `currentColor`</h3>\n * İkonlar `font-size` ile ölçeklenir ve metnin rengini alır. Sabit piksel\n * ölçüsü verilseydi düğme boyu değiştiğinde ikon aynı kalıp hizayı bozardı;\n * sabit renk verilseydi doygun dolgulu bir düğmede ikon kaybolurdu.\n *\n * <p>Yollar Bootstrap Icons'tan (MIT) alındı ve `viewBox` birebir korundu:\n * ölçü değişirse ikonlar bir piksel kayıyor.\n */\n\ntype IconProps = SVGProps<SVGSVGElement>;\n\n/** Ortak sarmalayıcı. `aria-hidden` VARSAYILAN: ikonun yanında her zaman\n * okunabilir bir metin ya da `aria-label` duruyor; ikisini birden okumak\n * ekran okuyucuda tekrar üretiyordu. */\nconst Icon: FC<IconProps & { children: React.ReactNode }> = ({ children, ...rest }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n aria-hidden\n focusable=\"false\"\n {...rest}\n >\n {children}\n </svg>\n);\n\nexport const XIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M1.293 1.293a1 1 0 0 1 1.414 0L8 6.586l5.293-5.293a1 1 0 1 1 1.414 1.414L9.414 8l5.293 5.293a1 1 0 0 1-1.414 1.414L8 9.414l-5.293 5.293a1 1 0 0 1-1.414-1.414L6.586 8 1.293 2.707a1 1 0 0 1 0-1.414\" />\n </Icon>\n);\n\nexport const CheckIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\" />\n </Icon>\n);\n\nexport const CheckSmallIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0\" />\n </Icon>\n);\n\nexport const ChevronDownIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path\n fillRule=\"evenodd\"\n d=\"M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708\"\n />\n </Icon>\n);\n\nexport const ChevronLeftIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path\n fillRule=\"evenodd\"\n d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0\"\n />\n </Icon>\n);\n\nexport const ChevronRightIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path\n fillRule=\"evenodd\"\n d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708\"\n />\n </Icon>\n);\n\nexport const ArrowRightIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path\n fillRule=\"evenodd\"\n d=\"M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8\"\n />\n </Icon>\n);\n\nexport const SearchIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.44.31.98.85l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.85-.98zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0\" />\n </Icon>\n);\n\nexport const PlusIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2\" />\n </Icon>\n);\n\nexport const MinusIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M2 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11A.5.5 0 0 1 2 8\" />\n </Icon>\n);\n\nexport const CopyIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path\n fillRule=\"evenodd\"\n d=\"M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z\"\n />\n </Icon>\n);\n\nexport const InfoCircleFillIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" />\n </Icon>\n);\n\nexport const CheckCircleFillIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z\" />\n </Icon>\n);\n\nexport const ExclamationTriangleFillIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5m.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2\" />\n </Icon>\n);\n\nexport const XCircleFillIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293z\" />\n </Icon>\n);\n\nexport const ExclamationCircleIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16\" />\n <path d=\"M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z\" />\n </Icon>\n);\n\nexport const QuestionCircleFillIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.496 6.033h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286a.237.237 0 0 0 .241.247m2.325 6.443c.61 0 1.029-.394 1.029-.927 0-.552-.42-.94-1.03-.94-.584 0-1.009.388-1.009.94 0 .533.425.927 1.01.927\" />\n </Icon>\n);\n\nexport const TrashFillIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5M8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5m3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0\" />\n </Icon>\n);\n\nexport const StarIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.56.56 0 0 0-.163-.505L1.71 6.745l4.052-.576a.53.53 0 0 0 .393-.288L8 2.223l1.847 3.658a.53.53 0 0 0 .393.288l4.052.575-2.906 2.77a.56.56 0 0 0-.163.506l.694 3.957-3.686-1.894a.5.5 0 0 0-.461 0z\" />\n </Icon>\n);\n\nexport const StarFillIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" />\n </Icon>\n);\n\nexport const StarHalfIcon: FC<IconProps> = props => (\n <Icon {...props}>\n <path d=\"M5.354 5.119 7.538.792A.52.52 0 0 1 8 .5c.183 0 .366.097.465.292l2.184 4.327 4.898.696A.54.54 0 0 1 16 6.32a.55.55 0 0 1-.17.445l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256a.5.5 0 0 1-.146.05c-.342.06-.668-.254-.6-.642l.83-4.73L.173 6.765a.55.55 0 0 1-.171-.443.5.5 0 0 1 .084-.302.5.5 0 0 1 .37-.245zM8 12.027a.5.5 0 0 1 .232.056l3.686 1.894-.694-3.957a.56.56 0 0 1 .162-.505l2.907-2.77-4.052-.576a.53.53 0 0 1-.393-.288L8.001 2.223 8 2.226z\" />\n </Icon>\n);\n","import { type AnchorHTMLAttributes, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { ArrowRightIcon } from '../../icons';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport HanuiLink from '../Link';\n\nimport styles from './index.module.scss';\n\ntype Props = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> & {\n href: string;\n children: ReactNode;\n /** Sonda ok gösterilir — \"devam et\" anlamı taşıyan bağlantılarda. */\n hasArrow?: boolean;\n tone?: 'brand' | 'muted';\n size?: 'sm' | 'md';\n /** Yönlendiriciye geçirilecek ek props. */\n linkProps?: HanuiLinkExtraProps;\n};\n\n/**\n * Metin bağlantısı.\n *\n * <h3>Ok bir süs değil</h3>\n * Sondaki ok yalnızca <em>gezinme</em> bağlantılarında kullanılır (\"Tümünü gör\n * →\"). Bir eylemi tetikleyen bağlantıya ok koymak, kullanıcıya başka bir\n * sayfaya gideceğini söyler ve beklentiyi yanıltır.\n *\n * <p>Ok, üzerine gelindiğinde <strong>ilerler</strong>: hareket, bağlantının\n * götürdüğü yönü fiziksel olarak sezdirir.\n *\n * <h3>Alt çizgi hover'da eklenir, kaldırılmaz</h3>\n * Sürekli altı çizili bağlantılar yoğun bir liste sayfasında görsel gürültü\n * yaratıyordu. Ama alt çizginin <em>hiç</em> olmaması bağlantıyı düz metinden\n * ayırt edilemez kılar; renk tek başına yeterli değil (WCAG 1.4.1). Çözüm:\n * renk her zaman, alt çizgi etkileşimde.\n */\nconst TextLink = ({\n href,\n children,\n hasArrow,\n tone = 'brand',\n size = 'md',\n className,\n linkProps,\n ...rest\n}: Props) => (\n <HanuiLink\n href={href}\n className={cx(styles.link, styles[`link--${tone}`], styles[`link--${size}`], className)}\n {...linkProps}\n {...rest}\n >\n <span className={styles.link__label}>{children}</span>\n {hasArrow && <ArrowRightIcon className={styles.link__arrow} />}\n </HanuiLink>\n);\n\nexport default memo(TextLink) as typeof TextLink;\n","'use client';\n\nimport { type FC, memo, type ReactNode, useId, useState } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Balonda gösterilecek açıklama. */\n content: ReactNode;\n /** Açıklamanın bağlandığı öğe — düğme, ikon, etiket. */\n children: ReactNode;\n /** Varsayılan üstte; alanı olmayan yerlerde `bottom`. */\n position?: 'top' | 'bottom';\n className?: string;\n};\n\n/**\n * İpucu balonu.\n *\n * <h3>Neden native `title` yetmiyor</h3>\n * Tarayıcının `title` özniteliği <strong>dokunmatikte hiç görünmez</strong>,\n * gecikmesi ayarlanamaz ve biçimlendirilemez. Trafiğin ağırlığı mobil olan\n * bir arayüzde \"üzerine gelince açıklama çıkar\" demek, kullanıcıların çoğu\n * için açıklamanın hiç olmaması demek.\n *\n * <h3>Neden yalnızca AÇIKLAMA taşır</h3>\n * Balonda <em>yalnızca</em> yardımcı metin durur — bağlantı, düğme veya\n * okunması zorunlu bir bilgi değil. İpucu klavyeyle odaklanınca ve fareyle\n * üzerine gelince açılıyor; içine bir eylem konsaydı ona erişmenin yolu\n * olmazdı (fare balona giderken tetikleyiciden çıkıyor). Kalıcı olması\n * gereken metin için `Field`ın `hint`i kullanılır.\n *\n * <h3>Erişilebilirlik</h3>\n * Tetikleyici `aria-describedby` ile balona bağlanır — ekran okuyucu öğenin\n * adını okuduktan sonra açıklamayı da okur. Balon `role=\"tooltip\"`. `Escape`\n * kapatır: klavye kullanıcısı ipucunu kapatabilmeli.\n */\nconst Tooltip: FC<Props> = ({ content, children, position = 'top', className }) => {\n const [isOpen, setIsOpen] = useState(false);\n const id = useId();\n\n return (\n <span\n className={cx(styles.tooltip, className)}\n onMouseEnter={() => setIsOpen(true)}\n onMouseLeave={() => setIsOpen(false)}\n /*\n * Odak SARMALAYICIDA dinleniyor: tetikleyici bir `<button>` de olabilir\n * bir `<span>` de, ve `focus` baloncuklanmadigi icin `focusin`\n * kullaniliyor (React'te `onFocus` zaten baloncuklanan surumu).\n */\n onFocus={() => setIsOpen(true)}\n onBlur={() => setIsOpen(false)}\n onKeyDown={event => {\n if (event.key === 'Escape') setIsOpen(false);\n }}\n >\n <span aria-describedby={isOpen ? id : undefined} className={styles.tooltip__trigger}>\n {children}\n </span>\n\n {/*\n Balon DOM'da yalnizca acikken: kapaliyken de birakip gizlemek, ekran\n okuyucunun onu `aria-describedby` olmadan da bulup okumasina yol\n aciyordu.\n */}\n {isOpen && (\n <span id={id} role=\"tooltip\" className={cx(styles.bubble, styles[`bubble--${position}`])}>\n {content}\n </span>\n )}\n </span>\n );\n};\n\nexport default memo(Tooltip) as typeof Tooltip;\n","'use client';\n\nimport { type ButtonHTMLAttributes, forwardRef, memo, type ReactNode } from 'react';\n\nimport { isDefined } from '@ahmetilhn/handy-utils';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport HanuiLink from '../Link';\n\nimport styles from './index.module.scss';\n\nexport type ChipSize = 'sm' | 'md';\n\ntype Props = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> & {\n /** Görünen metin. Yalnız ikon taşıyan çipte verilmez; `label` zorunlu olur. */\n children?: ReactNode;\n /** Metnin solundaki ikon. */\n icon?: ReactNode;\n /** Metnin sağındaki ikon (ok, çarpı). */\n endIcon?: ReactNode;\n /** Sağda gösterilen sonuç adedi. */\n count?: number;\n isSelected?: boolean;\n size?: ChipSize;\n /**\n * Erişilebilir ad. Görünür metin yoksa <strong>zorunlu</strong>: yalnız ikon\n * taşıyan bir çip ekran okuyucuda \"düğme\" diye okunur.\n */\n label?: string;\n /** Verilirse çip bir bağlantı olarak çizilir. */\n href?: string;\n /** Yönlendiriciye geçirilecek ek props. */\n linkProps?: HanuiLinkExtraProps;\n /**\n * Grup içindeki ARIA rolü. Tek seçimli gruplarda `radio`, çok seçimlide\n * verilmez — {@link ChipGroup} bunu kendisi ayarlar; elle kullanımda\n * `aria-pressed` üretilir.\n */\n role?: 'radio';\n testId?: string;\n};\n\n/**\n * Çip — seçilebilir etiket.\n *\n * <h3>Tasarım sisteminin en çok tekrarlanan öğesi</h3>\n * Kategori seçimi, hızlı filtre, sıralama tercihi, görünüm anahtarı: hepsi\n * aynı öğe. Ayrı ayrı düğme stilleri yazmak yerine tek çip kullanılır;\n * böylece seçili durumun nasıl göründüğü uygulamanın her yerinde aynıdır.\n *\n * <h3>Seçili durum üç sinyalle birden bildirilir</h3>\n * Kenarlık + metin rengi + ikon rengi <em>birlikte</em> değişir. Yalnızca\n * zemini doldurmak (renk tek başına, WCAG 1.4.1) renk körü kullanıcı için\n * ayırt edilemez olurdu; ayrıca dolu zemin çipi düğmeye benzetip \"buraya\n * tıkla\" gibi okutuyordu — oysa çip bir <em>durum</em> gösterir.\n *\n * <h3>Neden `aria-pressed`, `disabled` değil</h3>\n * Seçili çip pasifleştirilmez: kullanıcı seçimini geri alabilmeli. Basılı\n * düğme semantiği (`aria-pressed`) ekran okuyucuya \"seçili, kapatılabilir\"\n * bilgisini verir.\n */\nconst Chip = forwardRef<HTMLButtonElement, Props>(\n (\n {\n children,\n icon,\n endIcon,\n count,\n isSelected,\n size = 'md',\n label,\n href,\n linkProps,\n className,\n type = 'button',\n role,\n testId,\n ...rest\n },\n ref,\n ) => {\n const classNames = cx(\n styles.chip,\n styles[`chip--${size}`],\n isSelected && styles['chip--selected'],\n !children && styles['chip--iconOnly'],\n className,\n );\n\n const content = (\n <>\n {icon && (\n <span className={styles.chip__icon} aria-hidden>\n {icon}\n </span>\n )}\n {children && <span className={styles.chip__label}>{children}</span>}\n {isDefined(count) && <span className={styles.chip__count}>{count}</span>}\n {endIcon && (\n <span className={styles.chip__icon} aria-hidden>\n {endIcon}\n </span>\n )}\n </>\n );\n\n if (href)\n return (\n <HanuiLink\n href={href}\n className={classNames}\n aria-label={children ? undefined : label}\n aria-current={isSelected ? 'page' : undefined}\n title={children ? undefined : label}\n data-testid={testId}\n {...linkProps}\n >\n {content}\n </HanuiLink>\n );\n\n return (\n <button\n ref={ref}\n type={type}\n role={role}\n className={classNames}\n aria-label={children ? undefined : label}\n title={children ? undefined : label}\n data-testid={testId}\n // Tek seçimli grupta radyo semantiği, aksi halde basılı düğme.\n {...(role === 'radio'\n ? { 'aria-checked': Boolean(isSelected) }\n : { 'aria-pressed': Boolean(isSelected) })}\n {...rest}\n >\n {content}\n </button>\n );\n },\n);\n\nChip.displayName = 'Chip';\n\nexport default memo(Chip) as typeof Chip;\n","'use client';\n\nimport { type KeyboardEvent, memo, type ReactNode, useRef } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport Chip, { type ChipSize } from '../Chip';\n\nimport styles from './index.module.scss';\n\nexport type ChipOption<T extends string = string> = {\n value: T;\n label: string;\n icon?: ReactNode;\n count?: number;\n isDisabled?: boolean;\n};\n\ntype BaseProps<T extends string> = {\n options: ChipOption<T>[];\n /** Grubun erişilebilir adı (\"Sıralama\", \"Kalite\"). */\n label: string;\n size?: ChipSize;\n /** Taşan çipleri alta sarmak yerine yatay kaydırır (mobil filtre şeridi). */\n isScrollable?: boolean;\n className?: string;\n};\n\ntype SingleProps<T extends string> = BaseProps<T> & {\n isMultiple?: false;\n value: T | null;\n /** Seçili çipe tekrar basılırsa `null` gelir — seçim geri alınabilir. */\n onChange: (value: T | null) => void;\n};\n\ntype MultipleProps<T extends string> = BaseProps<T> & {\n isMultiple: true;\n value: T[];\n onChange: (value: T[]) => void;\n};\n\ntype Props<T extends string> = SingleProps<T> | MultipleProps<T>;\n\n/**\n * Çip grubu — açılır liste yerine tek dokunuşla seçim.\n *\n * <h3>Ne zaman çip grubu, ne zaman açılır liste</h3>\n * Seçenek sayısı azsa (kabaca 7'ye kadar) ve seçenekler ekranda durabiliyorsa\n * çip grubu kullanılır: kullanıcı listeyi <em>açmadan</em> hem seçenekleri hem\n * de hangisinin seçili olduğunu görür — açılır listede bu bilgi iki tıklama\n * arkasındadır. 5–20 seçenek için {@link Select}, 20+ için {@link Combobox}.\n *\n * <h3>Tek seçim radyo grubudur</h3>\n * Tek seçimli grup `role=\"radiogroup\"` alır ve çipler `role=\"radio\"` olur.\n * Görsel olarak radyo düğmesi gibi durmasalar da davranış aynıdır; ekran\n * okuyucu \"3 seçenekten 2.'si\" diye okur. Yalnız `aria-pressed` kullanmak,\n * seçeneklerin birbirini dışladığı bilgisini kaybettiriyordu.\n *\n * <h3>Gezinme tabindex'i dolaşır (roving tabindex)</h3>\n * Radyo grubunda Tab tuşu <strong>gruba</strong> girer, seçenekler arasında ok\n * tuşlarıyla gezilir. Her çipin ayrı ayrı Tab durağı olması, 7 seçenekli bir\n * filtrede klavye kullanıcısını 7 kez Tab'lamaya zorluyordu.\n */\nconst ChipGroup = <T extends string>({\n options,\n label,\n size = 'md',\n isScrollable,\n className,\n ...selection\n}: Props<T>) => {\n const listRef = useRef<HTMLDivElement>(null);\n\n const isSelected = (value: T) =>\n selection.isMultiple ? selection.value.includes(value) : selection.value === value;\n\n const handleSelect = (value: T) => {\n if (selection.isMultiple) {\n const next = selection.value.includes(value)\n ? selection.value.filter(item => item !== value)\n : [...selection.value, value];\n selection.onChange(next);\n return;\n }\n\n // Seçili çipe tekrar basmak seçimi kaldırır: \"hepsi\" seçeneği olmayan\n // filtrelerde kullanıcının geri dönebileceği tek yol bu.\n selection.onChange(selection.value === value ? null : value);\n };\n\n /** Ok tuşlarıyla gezinme; başta/sonda döner (yalnızca tek seçimde). */\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (selection.isMultiple) return;\n\n const offset =\n event.key === 'ArrowRight' || event.key === 'ArrowDown'\n ? 1\n : event.key === 'ArrowLeft' || event.key === 'ArrowUp'\n ? -1\n : 0;\n if (offset === 0) return;\n\n event.preventDefault();\n\n const enabled = options.filter(option => !option.isDisabled);\n if (enabled.length === 0) return;\n\n const currentIndex = enabled.findIndex(option => option.value === selection.value);\n const next = enabled[(currentIndex + offset + enabled.length) % enabled.length];\n\n selection.onChange(next.value);\n listRef.current?.querySelector<HTMLButtonElement>(`[data-chip-value=\"${next.value}\"]`)?.focus();\n };\n\n // Roving tabindex: seçili çip tabbable; hiçbiri seçili değilse ilki.\n const tabbableValue = selection.isMultiple\n ? null\n : (selection.value ?? options.find(option => !option.isDisabled)?.value ?? null);\n\n return (\n <div\n ref={listRef}\n className={cx(styles.group, isScrollable && styles['group--scrollable'], className)}\n role={selection.isMultiple ? 'group' : 'radiogroup'}\n aria-label={label}\n onKeyDown={handleKeyDown}\n >\n {options.map(option => (\n <Chip\n key={option.value}\n size={size}\n icon={option.icon}\n count={option.count}\n isSelected={isSelected(option.value)}\n disabled={option.isDisabled}\n role={selection.isMultiple ? undefined : 'radio'}\n tabIndex={selection.isMultiple || option.value === tabbableValue ? 0 : -1}\n data-chip-value={option.value}\n onClick={() => handleSelect(option.value)}\n >\n {option.label}\n </Chip>\n ))}\n </div>\n );\n};\n\nexport default memo(ChipGroup) as typeof ChipGroup;\n","'use client';\n\nimport { memo, type MouseEvent, type ReactNode, useCallback, useEffect, useId } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { isClient } from '@ahmetilhn/handy-utils';\n\nimport { ABOVE_MOBILE_MEDIA_QUERY } from '../../constants/breakpoint.constants';\nimport { cx } from '../../helpers/class-name.helper';\nimport { preventAutoKeyboard } from '../../helpers/focus.helper';\nimport useSheetViewport from '../../hooks/useSheetViewport';\nimport { XIcon } from '../../icons';\nimport IconButton from '../IconButton';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n title: string;\n /** Kapatma düğmesinin erişilebilir adı. */\n closeLabel: string;\n onClose: () => void;\n children: ReactNode;\n /**\n * Başlığın altında duran, gövde kaydırılırken yerinde kalan şerit —\n * `Combobox`ın arama kutusu gibi.\n */\n toolbar?: ReactNode;\n /** Dipte duran eylem şeridi. */\n footer?: ReactNode;\n /**\n * Panelin <strong>kendiliğinden kapandığı</strong> medya sorgusu.\n *\n * <p>Varsayılan mobil eşiği (`>640`), çünkü seçim kutuları o eşiğin üstünde\n * listeyi yapışkan panelde açıyor. Kendi eşiği daha geniş olan çağıranlar\n * kendi sorgusunu verir; aksi hâlde 800 px'te açılan panel pencere 641 px'i\n * geçtiğinde kapanıyor ya da hiç kapanmıyordu.\n */\n closeAbove?: string;\n className?: string;\n testId?: string;\n};\n\n/**\n * Alt sayfa (bottom sheet) — ekranın dibinden yükselen kipsel panel.\n *\n * <h3>Ne zaman</h3>\n * Dar ekranda bir <strong>seçim listesi</strong> açan her kutu bunu kullanır\n * ({@link Select}, {@link Combobox}). Masaüstünde aynı liste tetikleyiciye\n * yapışan bir panelde açılır; telefonda o panel klavye açılınca sıkışıyor ve\n * listenin alt ucu ekranın dışında kalıyordu. Alt sayfa baş parmağın\n * erişebildiği yerde durur, satırları büyüktür ve ekranı tek işe ayırır.\n *\n * <h3>Neden yerel `<dialog>` + portal</h3>\n * `showModal()` odak tuzağını, Escape'i ve arka planın etkileşime kapanmasını\n * tarayıcıdan getirir. Panel <strong>gövdeye taşınır</strong>: seçim kutuları\n * `<label>` içinde durabiliyor ve etiketin içindeki tıklama etiketlenen öğeye\n * yönleniyor — seçeneklere basmak aynı anda tetikleyiciyi de tetikliyordu.\n *\n * <h3>Yalnızca açıkken çizilir</h3>\n * Bileşen `isOpen` almaz: çağıran taraf açıkken <em>render eder</em>, kapatmak\n * için kaldırır. Kapalı bir `<dialog>`u CSS ile gizlemeye çalışmak, sınıf\n * seçicisinin tarayıcı kuralını yenmesi yüzünden paneli ekranın dibinde asılı\n * bırakıyordu.\n *\n * <h3>Kırılma noktası aşılırsa kapanır</h3>\n * `showModal()` sayfanın geri kalanını panel çizilsin ya da çizilmesin inert\n * bırakır; pencere büyütülüp panel gizlenseydi sayfa tıklanamaz kalırdı.\n */\nconst BottomSheet = ({\n title,\n closeLabel,\n onClose,\n children,\n toolbar,\n footer,\n closeAbove = ABOVE_MOBILE_MEDIA_QUERY,\n className,\n testId,\n}: Props) => {\n const titleId = useId();\n\n /* Panel GORUNEN alana yaslanir: klavye ve adres cubugu altinda kalmaz. */\n useSheetViewport();\n\n /* Arka plan kaydirmasi kilitlenir: `showModal()` arka plani etkilesime\n kapatir ama kaydirmayi her tarayicida engellemiyor — kullanici alt sayfayi\n kaydirdigini sanirken arkadaki listeyi kaydiriyordu. */\n useEffect(() => {\n const previous = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = previous;\n };\n }, []);\n\n useEffect(() => {\n const query = window.matchMedia(closeAbove);\n query.addEventListener('change', onClose);\n return () => query.removeEventListener('change', onClose);\n }, [closeAbove, onClose]);\n\n const setDialogRef = useCallback((node: HTMLDialogElement | null) => {\n if (!node || node.open) return;\n\n node.showModal();\n /* `showModal()` odagi panelin ILK odaklanabilir ogesine tasiyor; o oge bir\n metin alani oldugunda telefonda klavye kendiliginden aciliyordu. Bugun\n ilk oge kapatma dugmesi ama bu DOM sirasinin tesadufu — kural burada\n zorlanir (bkz. `helpers/focus.helper`). */\n preventAutoKeyboard(node);\n }, []);\n\n const handleBackdropClick = useCallback(\n (event: MouseEvent<HTMLDialogElement>) => {\n // Hedef dialog'un KENDISI ise perdeye tiklanmistir; icerik degil.\n if (event.target === event.currentTarget) onClose();\n },\n [onClose],\n );\n\n /* Portal `document.body`ye baglaniyor; sunucuda `document` yok. */\n if (!isClient()) return null;\n\n return createPortal(\n <dialog\n ref={setDialogRef}\n className={cx(styles.sheet, className)}\n aria-labelledby={titleId}\n data-testid={testId}\n /* Escape'i tarayici isler ama React durumu haberdar olmuyor:\n yakalanmazsa panel kapanip durum acik kaliyor ve kutu bir daha\n acilmiyordu. */\n onCancel={event => {\n event.preventDefault();\n onClose();\n }}\n onClick={handleBackdropClick}\n >\n <header className={styles.sheet__header}>\n <h2 id={titleId} className={styles.sheet__title}>\n {title}\n </h2>\n <IconButton\n icon={<XIcon />}\n label={closeLabel}\n variant=\"ghost\"\n size=\"sm\"\n onClick={onClose}\n />\n </header>\n\n {toolbar && <div className={styles.sheet__toolbar}>{toolbar}</div>}\n\n <div className={styles.sheet__body}>{children}</div>\n\n {footer && <div className={styles.sheet__footer}>{footer}</div>}\n </dialog>,\n document.body,\n );\n};\n\nexport default memo(BottomSheet);\n","'use client';\n\nimport {\n type KeyboardEvent,\n memo,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { ABOVE_MOBILE_MEDIA_QUERY } from '../../constants/breakpoint.constants';\nimport { cx } from '../../helpers/class-name.helper';\nimport { matchesSearch } from '../../helpers/text.helper';\nimport { CheckIcon, ChevronDownIcon, SearchIcon, XIcon } from '../../icons';\nimport BottomSheet from '../BottomSheet';\nimport Spinner from '../Spinner';\n\nimport styles from './index.module.scss';\n\nexport type ComboboxOption<T extends string = string> = {\n value: T;\n label: string;\n /** İkincil satır: kod, numara, ayırt edici bilgi. */\n description?: string;\n isDisabled?: boolean;\n};\n\n/** Bileşenin çizdiği metinler. Hepsi ZORUNLU: kütüphane dil kararı vermez. */\nexport type ComboboxLabels = {\n /** Seçim yokken tetikleyicide ve alt sayfa başlığında görünen metin. */\n placeholder: string;\n /** Arama kutusunun yer tutucusu ve erişilebilir adı. */\n searchPlaceholder: string;\n /** Liste boşken gösterilen metin. */\n emptyMessage: string;\n /** Arama sürerken liste yerine gösterilen metin. */\n loadingMessage: string;\n /** Seçimi kaldıran çarpının erişilebilir adı. */\n clearLabel: string;\n /** Alt sayfanın kapatma düğmesinin erişilebilir adı. */\n closeLabel: string;\n};\n\ntype Props<T extends string> = {\n options: ComboboxOption<T>[];\n value: T | null;\n onChange: (value: T | null) => void;\n labels: ComboboxLabels;\n /**\n * Verilirse arama <strong>sunucuda</strong> yapılır: bileşen listeyi kendisi\n * filtrelemez, yazılanı 300 ms bekleyip buraya bildirir. Verilmezse\n * filtreleme yerelde ve aksan duyarsız yapılır.\n */\n onSearch?: (query: string) => void;\n isLoading?: boolean;\n isDisabled?: boolean;\n /** Seçimi kaldıran çarpı düğmesi gösterilir. */\n isClearable?: boolean;\n /**\n * Arama kutusu GİZLENİR.\n *\n * <p>Az sayıda, sabit seçenekli listelerde arama bir işe yaramıyor: altı\n * satırı taramak yazmaktan hızlı ve kutu açılışta odağı çalıp mobilde\n * klavyeyi açıyordu. Ok tuşlarıyla gezinme ve `Escape` yine çalışır.\n */\n isSearchHidden?: boolean;\n /** Tetikleyicinin solundaki ikon. */\n icon?: ReactNode;\n id?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: boolean;\n className?: string;\n testId?: string;\n};\n\n/**\n * Aranabilir seçim kutusu.\n *\n * <h3>Neden yerel `<select>` değil</h3>\n * Yerel açılır liste 20 seçeneğe kadar iyidir. Binlerce seçenekli bir listede\n * kullanıcı harf harf yazarak (ve yalnızca baştan eşleşerek) arıyor, mobilde\n * ise metrelerce süren bir tekerlek çeviriyor. Aranabilir liste, seçeneği\n * <em>yazarak</em> bulmayı mümkün kılar.\n *\n * <h3>Arama kutusu listenin İÇİNDE</h3>\n * Arama alanını listenin dışına koymak kullanıcıya iki ayrı alan gösteriyor\n * ve hangisinin seçimi belirlediği anlaşılmıyordu. Tek tetikleyici, tek\n * panel: masaüstünde panel açılınca odak doğrudan arama kutusuna gider,\n * yazılır, Enter'a basılır. Dar ekranda odak VERİLMEZ — bkz. aşağıdaki not.\n *\n * <h3>Yerel mi sunucu araması mı</h3>\n * `onSearch` verilmezse bileşen elindeki listeyi aksan duyarsız filtreler.\n * Verilirse filtrelemeyi <em>yapmaz</em> — sunucudan gelen liste zaten\n * filtrelenmiştir; ikinci kez filtrelemek sunucunun daha akıllı eşleşmesini\n * (eş anlamlı, kod eşleşmesi) bozardı.\n *\n * <h3>Seçilenin etiketi listeden düşse de korunur</h3>\n * Sunucu aramasında kullanıcı yeni bir arama yaptığında seçili kayıt gelen\n * listede olmayabilir. Etiket son bilinen değerden hatırlanır; aksi hâlde\n * tetikleyici seçim varken yer tutucuya dönüyordu.\n *\n * <h3>Dar ekranda arama kutusu ODAKLANMAZ</h3>\n * Alt sayfa açılırken kutuya odaklanmak ekran klavyesini kullanıcı istemeden\n * açıyordu: panel yarı yüksekliğe sıkışıyor, liste birkaç satıra iniyor ve\n * seçim yapmak için önce klavyeyi kapatmak gerekiyordu. Telefonda liste\n * taranarak kullanılır; yazmak isteyen kutuya kendisi dokunur.\n *\n * <h3>ARIA</h3>\n * Tetikleyici `aria-haspopup=\"listbox\"`, panel içindeki arama alanı\n * `role=\"combobox\"` + `aria-activedescendant`. Masaüstünde odak arama\n * kutusundan ayrılmaz; ok tuşları yalnızca <em>etkin</em> seçeneği değiştirir.\n * Odağı seçeneklere taşımak, yazmaya devam etmeyi imkânsız kılıyordu.\n */\nconst Combobox = <T extends string>({\n options,\n value,\n onChange,\n labels,\n isSearchHidden,\n onSearch,\n isLoading,\n isDisabled,\n isClearable,\n icon,\n id,\n className,\n testId,\n 'aria-describedby': describedBy,\n 'aria-invalid': isInvalid,\n}: Props<T>) => {\n const generatedId = useId();\n const baseId = id ?? generatedId;\n const listboxId = `${baseId}-listbox`;\n\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n /*\n * Panel NEREDE acilir: masaustunde tetikleyicinin altinda, dar ekranda\n * ekranin dibinde bir alt sayfada. Karar ACILIRKEN verilir — sunucuda ekran\n * genisligi bilinmiyor, ilk boyamada verilecek karar yanlis olurdu.\n */\n const [openMode, setOpenMode] = useState<'popover' | 'sheet' | null>(null);\n const isOpen = openMode !== null;\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n\n // Sunucu araması sırasında seçili kayıt listeden düşebilir; etiketi\n // hatırlarız ki tetikleyici yer tutucuya dönmesin.\n const [cachedLabel, setCachedLabel] = useState<string | null>(null);\n\n const visibleOptions = useMemo(() => {\n // Sunucu araması: gelen liste zaten filtrelidir, tekrar filtrelenmez.\n if (onSearch || query.trim() === '') return options;\n\n const needle = query.trim();\n return options.filter(\n option =>\n matchesSearch(option.label, needle) ||\n (option.description ? matchesSearch(option.description, needle) : false),\n );\n }, [options, query, onSearch]);\n\n const selectedOption = options.find(option => option.value === value) ?? null;\n\n useEffect(() => {\n if (selectedOption) setCachedLabel(selectedOption.label);\n else if (value === null) setCachedLabel(null);\n }, [selectedOption, value]);\n\n const displayLabel = selectedOption?.label ?? cachedLabel;\n\n /*\n * `onSearch` her render'da yeni bir kapanis olabilir; bagimliliga koymak\n * sonsuz dongu uretir. Referansta tutulup etkiden cikarilir.\n */\n const searchRef = useRef(onSearch);\n searchRef.current = onSearch;\n\n useEffect(() => {\n if (!isOpen || !searchRef.current) return;\n\n // Her tuşta istek atmamak için 300 ms beklenir.\n const timer = window.setTimeout(() => searchRef.current?.(query.trim()), 300);\n return () => window.clearTimeout(timer);\n }, [query, isOpen]);\n\n const close = useCallback(() => {\n setOpenMode(null);\n setQuery('');\n }, []);\n\n const open = useCallback(() => {\n if (isDisabled) return;\n setOpenMode(window.matchMedia(ABOVE_MOBILE_MEDIA_QUERY).matches ? 'popover' : 'sheet');\n setQuery('');\n // Panel açılınca etkin seçenek seçili olan olur; kullanıcı listeyi baştan\n // taramak zorunda kalmaz.\n const index = options.findIndex(option => option.value === value);\n setActiveIndex(index >= 0 ? index : 0);\n }, [isDisabled, options, value]);\n\n /*\n * Disari tiklamada kapanir. `mousedown` kullanilir: `click` beklerken\n * kullanici surukleyerek secim yaparsa panel kapanmiyordu.\n *\n * YALNIZCA masaustu panelinde. Alt sayfa govdeye tasindigi icin `rootRef`\n * onu ICERMIYOR: dinleyici acik kalsaydi panelin icindeki her dokunus\n * \"disari tiklama\" sayilip sayfayi kapatirdi. Orada bu isi perde yapiyor.\n */\n useEffect(() => {\n if (openMode !== 'popover') return;\n\n const handlePointerDown = (event: globalThis.MouseEvent) => {\n if (!rootRef.current?.contains(event.target as Node)) close();\n };\n\n document.addEventListener('mousedown', handlePointerDown);\n return () => document.removeEventListener('mousedown', handlePointerDown);\n }, [openMode, close]);\n\n /*\n * Odak arama kutusuna YALNIZCA masaustu panelinde verilir.\n *\n * Alt sayfada (dar ekran) odaklamak, kullanici yazmak istemedigi halde\n * ekran klavyesini aciyordu: panel yari yuksekluge sikisiyor, uzun listeden\n * ucu besi goruntude kaliyor ve secim yapmak icin once klavyeyi kapatmak\n * gerekiyordu. Masaustunde ekran klavyesi YOK; oradaki odak yazarak\n * aramanin ve ok tuslariyla gezinmenin tek dayanagi.\n *\n * `preventScroll` duruyor: iOS odaklanan kutuyu gorunur kilmak icin SAYFAYI\n * kaydiriyor ve arkadaki liste baska bir yere atliyordu.\n */\n useEffect(() => {\n if (openMode === 'popover') inputRef.current?.focus({ preventScroll: true });\n }, [openMode]);\n\n // Etkin seçenek görünür alanın dışına çıkmamalı.\n useEffect(() => {\n if (!isOpen) return;\n listRef.current\n ?.querySelector(`[data-index=\"${activeIndex}\"]`)\n ?.scrollIntoView({ block: 'nearest' });\n }, [activeIndex, isOpen, visibleOptions.length]);\n\n const selectOption = (option: ComboboxOption<T>) => {\n if (option.isDisabled) return;\n setCachedLabel(option.label);\n onChange(option.value);\n close();\n };\n\n /*\n * Kapaninca odak TETIKLEYICIYE doner.\n *\n * Odagi `close()`in hemen ardindan vermek alt sayfada ise yaramiyordu:\n * panel o an hala kipsel ve `showModal()` disaridaki her ogeyi inert\n * birakiyor — `focus()` sessizce hicbir sey yapmiyor, panel kalkinca da\n * odak `<body>`ye dusuyordu. Kullanici secim yaptiktan sonra sayfanin en\n * basina donuyordu.\n */\n const wasOpenRef = useRef(false);\n useEffect(() => {\n if (wasOpenRef.current && !isOpen) triggerRef.current?.focus();\n wasOpenRef.current = isOpen;\n }, [isOpen]);\n\n const handleInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n const lastIndex = visibleOptions.length - 1;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setActiveIndex(current => (current >= lastIndex ? 0 : current + 1));\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n setActiveIndex(current => (current <= 0 ? lastIndex : current - 1));\n break;\n\n case 'Home':\n event.preventDefault();\n setActiveIndex(0);\n break;\n\n case 'End':\n event.preventDefault();\n setActiveIndex(lastIndex);\n break;\n\n case 'Enter': {\n event.preventDefault();\n const option = visibleOptions[activeIndex];\n if (option) selectOption(option);\n break;\n }\n\n case 'Escape':\n event.preventDefault();\n // Odagi geri vermek kapanisi izleyen etkinin isi (bkz. `wasOpenRef`).\n close();\n break;\n\n case 'Tab':\n // Tab paneli kapatır ama varsayılan gezinme sürer.\n close();\n break;\n\n default:\n break;\n }\n };\n\n const clearSelection = () => {\n onChange(null);\n setCachedLabel(null);\n };\n\n /*\n * Arama ve liste IKI YERDE ayni: masaustu panelinde ve alt sayfada. Ayri\n * ayri yazilsalardi biri guncellenip digeri unutulurdu.\n */\n const search = isSearchHidden ? null : (\n <div className={styles.combobox__search}>\n <SearchIcon className={styles.combobox__searchIcon} />\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n className={styles.combobox__searchInput}\n value={query}\n placeholder={labels.searchPlaceholder}\n autoComplete=\"off\"\n aria-autocomplete=\"list\"\n aria-expanded\n aria-controls={listboxId}\n aria-activedescendant={\n visibleOptions[activeIndex] ? `${baseId}-option-${activeIndex}` : undefined\n }\n aria-label={labels.searchPlaceholder}\n onChange={event => {\n setQuery(event.target.value);\n setActiveIndex(0);\n }}\n onKeyDown={handleInputKeyDown}\n />\n {isLoading && <Spinner size=\"sm\" label=\"\" />}\n </div>\n );\n\n const renderList = (isSheet: boolean) => (\n <ul\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n className={cx(styles.combobox__list, isSheet && styles['combobox__list--sheet'])}\n >\n {visibleOptions.map((option, index) => {\n const isActive = index === activeIndex;\n const isChosen = option.value === value;\n\n return (\n <li key={option.value}>\n <div\n id={`${baseId}-option-${index}`}\n role=\"option\"\n data-index={index}\n aria-selected={isChosen}\n aria-disabled={option.isDisabled}\n className={cx(\n styles.combobox__option,\n isActive && styles['combobox__option--active'],\n isChosen && styles['combobox__option--selected'],\n option.isDisabled && styles['combobox__option--disabled'],\n )}\n // Fare imleci seçeneğin üstündeyken etkin seçenek de oraya\n // taşınır; iki ayrı vurgu kullanıcıyı şaşırtıyordu.\n onMouseEnter={() => setActiveIndex(index)}\n onClick={() => selectOption(option)}\n >\n <span className={styles.combobox__optionText}>\n <span className={styles.combobox__optionLabel}>{option.label}</span>\n {option.description && (\n <span className={styles.combobox__optionDescription}>{option.description}</span>\n )}\n </span>\n\n {isChosen && <CheckIcon className={styles.combobox__check} />}\n </div>\n </li>\n );\n })}\n\n {visibleOptions.length === 0 && (\n <li className={styles.combobox__empty}>\n {isLoading ? labels.loadingMessage : labels.emptyMessage}\n </li>\n )}\n </ul>\n );\n\n return (\n <div ref={rootRef} className={cx(styles.combobox, className)} data-testid={testId}>\n <button\n ref={triggerRef}\n id={baseId}\n type=\"button\"\n className={cx(\n styles.combobox__trigger,\n !displayLabel && styles['combobox__trigger--empty'],\n isOpen && styles['combobox__trigger--open'],\n isInvalid && styles['combobox__trigger--invalid'],\n )}\n disabled={isDisabled}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? listboxId : undefined}\n aria-label={labels.placeholder}\n /*\n Hata `aria-invalid` ile DEGIL `aria-describedby` ile duyurulur:\n `aria-invalid`, `role=\"button\"` uzerinde tanimsizdir ve ekran\n okuyucular onu yok sayar. `Field` hata metnini zaten `role=\"alert\"`\n ile bagliyor; buradaki gorev yalnizca gorsel.\n */\n aria-describedby={describedBy}\n onClick={() => (isOpen ? close() : open())}\n >\n {icon && (\n <span className={styles.combobox__leadingIcon} aria-hidden>\n {icon}\n </span>\n )}\n\n <span className={styles.combobox__value}>{displayLabel ?? labels.placeholder}</span>\n\n {isClearable && displayLabel && !isDisabled && (\n /*\n Temizleme, tetikleyicinin İÇİNDE ayrı bir düğme olamaz (iç içe\n düğme geçersiz HTML). Görsel olarak içeride duran, DOM'da kardeş\n olan bir düğme kullanılır.\n */\n <span\n role=\"button\"\n tabIndex={0}\n className={styles.combobox__clear}\n aria-label={labels.clearLabel}\n onClick={event => {\n event.stopPropagation();\n clearSelection();\n }}\n onKeyDown={event => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n event.stopPropagation();\n clearSelection();\n }}\n >\n <XIcon />\n </span>\n )}\n\n <ChevronDownIcon\n className={cx(styles.combobox__chevron, isOpen && styles['combobox__chevron--open'])}\n />\n </button>\n\n {/* Masaüstü: tetikleyiciye yapışan panel. */}\n {openMode === 'popover' && (\n <div className={styles.combobox__panel}>\n {search}\n {renderList(false)}\n </div>\n )}\n\n {/*\n Dar ekran: alt sayfa. Yapışkan panel telefonda klavye açılınca sıkışıyor\n ve uzun listenin alt ucu ekranın dışında kalıyordu; arama kutusu da\n tetikleyiciyle klavyenin arasına hapsoluyordu. Arama `toolbar`\n yuvasında: başlığın altında sabit kalır, liste altında kayar.\n */}\n {openMode === 'sheet' && (\n <BottomSheet\n title={labels.placeholder}\n closeLabel={labels.closeLabel}\n onClose={close}\n toolbar={search ?? undefined}\n >\n {renderList(true)}\n </BottomSheet>\n )}\n </div>\n );\n};\n\nexport default memo(Combobox) as typeof Combobox;\n","'use client';\n\nimport {\n type KeyboardEvent,\n memo,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport { ABOVE_MOBILE_MEDIA_QUERY } from '../../constants/breakpoint.constants';\nimport { cx } from '../../helpers/class-name.helper';\nimport { CheckIcon, ChevronDownIcon } from '../../icons';\nimport BottomSheet from '../BottomSheet';\n\nimport styles from './index.module.scss';\n\nexport type SelectOption<T extends string = string> = {\n value: T;\n label: string;\n isDisabled?: boolean;\n};\n\n/**\n * Seçenek listesinin nerede açıldığı.\n *\n * <p>`popover` tetikleyicinin altında, `sheet` ekranın dibinde. Karar\n * <strong>açılırken</strong> verilir; sunucuda ekran genişliği bilinmediği\n * için ilk boyamada verilecek her karar yanlış olurdu.\n */\ntype OpenMode = 'popover' | 'sheet';\n\ntype Props<T extends string> = {\n options: SelectOption<T>[];\n value: T;\n onChange: (value: T) => void;\n /**\n * Alanın adı. İki işi birden yapar: alt sayfanın başlığı olur ve\n * tetikleyicinin <strong>erişilebilir adı</strong>dır.\n *\n * <p>Tetikleyici bir `<button>` ve düğmenin adı HTML-AAM'e göre\n * `<label>`den GELMEZ — görünür bir etiket olsa bile ekran okuyucu yalnızca\n * seçili değeri okur (\"En yeni, düğme\") ve neyi seçtiğini söylemez.\n */\n label: string;\n /** Seçim yokken tetikleyicide görünen metin. */\n placeholder: string;\n /** Alt sayfanın kapatma düğmesinin erişilebilir adı. */\n closeLabel: string;\n /** Tetikleyicinin solundaki ikon. */\n icon?: ReactNode;\n /** `sm` yoğun şeritler içindir (araç çubuğu); varsayılan form ölçüsü `md`. */\n size?: 'sm' | 'md';\n /**\n * Panelin hangi kenardan hizalanacağı.\n *\n * <p>Şeridin sağ ucundaki bir tetikleyicide `start` hizalama paneli sağa\n * doğru taşırıyordu; `end` panelin sağ kenarını tetikleyiciye yaslar.\n */\n align?: 'start' | 'end';\n isDisabled?: boolean;\n id?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: boolean;\n className?: string;\n testId?: string;\n};\n\n/**\n * Seçim kutusu.\n *\n * <h3>Yerel `<select>` KULLANILMAZ</h3>\n * Yerel açılır liste her tarayıcıda başka türlü çiziliyor, seçeneklerine tek\n * bir stil verilemiyor (seçili değeri işaretlemek, ikon koymak, satırı\n * yükseltmek yok) ve mobilde ekranın ortasında beliren tekerlek uygulamanın\n * geri kalanına hiç benzemiyordu. Kutu baştan sona bizim: masaüstünde\n * tetikleyicinin altında bir panel, mobilde ekranın dibinden yükselen bir\n * <strong>alt sayfa</strong> açar.\n *\n * <p>Bu, \"yerel öğe taklit öğeden iyidir\" kuralının BİLİNÇLİ tek istisnası:\n * bedeli (odak yönetimi, ok tuşları, `aria-activedescendant`) bir kez ödenip\n * tek bileşene kapatıldı.\n *\n * <h3>Klavye — odak TEK yerde</h3>\n * Panel açıkken odak tetikleyicide kalır, alt sayfada ise listenin kendisine\n * geçer; iki durumda da etkin seçenek `aria-activedescendant` ile bildirilir.\n * Seçenekleri tek tek odaklanabilir yapmak, aynı bileşende iki ayrı klavye\n * modeli demekti (APG: listbox + activedescendant).\n *\n * <h3>20+ seçenek varsa bu bileşen DEĞİL</h3>\n * Aramasız bir liste 20 satırdan sonra taranamaz hâle gelir; orada\n * {@link Combobox} kullanılır.\n */\nconst Select = <T extends string>({\n options,\n value,\n onChange,\n label,\n placeholder,\n closeLabel,\n icon,\n size = 'md',\n align = 'start',\n isDisabled,\n id,\n className,\n testId,\n 'aria-describedby': describedBy,\n 'aria-invalid': isInvalid,\n}: Props<T>) => {\n const generatedId = useId();\n const baseId = id ?? generatedId;\n const listboxId = `${baseId}-listbox`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n\n const rootRef = useRef<HTMLSpanElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n const [openMode, setOpenMode] = useState<OpenMode | null>(null);\n const [activeIndex, setActiveIndex] = useState(0);\n\n const isOpen = openMode !== null;\n const selectedIndex = options.findIndex(option => option.value === value);\n const selectedOption = selectedIndex >= 0 ? options[selectedIndex] : null;\n\n const close = useCallback(() => setOpenMode(null), []);\n\n const open = useCallback(() => {\n if (isDisabled || options.length === 0) return;\n\n setOpenMode(window.matchMedia(ABOVE_MOBILE_MEDIA_QUERY).matches ? 'popover' : 'sheet');\n // Etkin seçenek seçili olandan başlar; kullanıcı listeyi baştan taramaz.\n setActiveIndex(selectedIndex >= 0 ? selectedIndex : 0);\n }, [isDisabled, options.length, selectedIndex]);\n\n const selectOption = (option: SelectOption<T>) => {\n if (option.isDisabled) return;\n onChange(option.value);\n close();\n };\n\n /*\n * Kapaninca odak TETIKLEYICIYE doner.\n *\n * Odagi `selectOption` icinde geri vermek ise yaramiyor: alt sayfa ayni\n * commit'te DOM'dan kalkiyor ve odaklanan dugme sokulunce odak `<body>`ye\n * dusuyordu — klavye kullanicisi secim yaptiktan sonra sayfanin en basina\n * donuyordu.\n */\n const wasOpenRef = useRef(false);\n useEffect(() => {\n if (wasOpenRef.current && !isOpen) triggerRef.current?.focus();\n wasOpenRef.current = isOpen;\n }, [isOpen]);\n\n /* Disari tiklamada panel kapanir. Alt sayfada bu is perdenin. */\n useEffect(() => {\n if (openMode !== 'popover') return;\n\n const handlePointerDown = (event: globalThis.MouseEvent) => {\n if (!rootRef.current?.contains(event.target as Node)) close();\n };\n\n document.addEventListener('mousedown', handlePointerDown);\n return () => document.removeEventListener('mousedown', handlePointerDown);\n }, [openMode, close]);\n\n /*\n * Alt sayfada odak listenin kendisine gecer: ok tuslari orada isler.\n *\n * `preventScroll` ZORUNLU: odaklanan oge ust katmanda duran sabit bir\n * panelin icinde ve iOS onu \"gorunur kilmak\" icin sayfayi kaydiriyor —\n * panel oldugu yerde durdugu icin kaydirmanin tek etkisi, arkadaki sayfanin\n * kullanicinin bakmadigi bir yere atlamasiydi.\n */\n useEffect(() => {\n if (openMode === 'sheet') listRef.current?.focus({ preventScroll: true });\n }, [openMode]);\n\n // Etkin seçenek görünür alanın dışına çıkmamalı.\n useEffect(() => {\n if (!isOpen) return;\n listRef.current\n ?.querySelector(`[data-index=\"${activeIndex}\"]`)\n ?.scrollIntoView({ block: 'nearest' });\n }, [activeIndex, isOpen]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n const lastIndex = options.length - 1;\n\n if (!isOpen) {\n if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(event.key)) {\n event.preventDefault();\n open();\n }\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setActiveIndex(current => (current >= lastIndex ? 0 : current + 1));\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n setActiveIndex(current => (current <= 0 ? lastIndex : current - 1));\n break;\n\n case 'Home':\n event.preventDefault();\n setActiveIndex(0);\n break;\n\n case 'End':\n event.preventDefault();\n setActiveIndex(lastIndex);\n break;\n\n case 'Enter':\n case ' ': {\n event.preventDefault();\n const option = options[activeIndex];\n if (option) selectOption(option);\n break;\n }\n\n case 'Escape':\n event.preventDefault();\n close();\n break;\n\n case 'Tab':\n // Tab paneli kapatir ama varsayilan gezinme surer.\n close();\n break;\n\n default:\n break;\n }\n };\n\n const renderList = (isSheet: boolean) => (\n <ul\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n /* Alt sayfada baslik `BottomSheet`in icinde ve kimligi bize kapali;\n listenin adi dogrudan yazilir. */\n aria-label={label}\n /* Odak alt sayfada listede, panelde tetikleyicide: etkin seçeneği\n bildiren öznitelik odağın olduğu öğede durmak zorunda. */\n aria-activedescendant={isSheet && options[activeIndex] ? optionId(activeIndex) : undefined}\n tabIndex={isSheet ? 0 : -1}\n className={cx(styles.list, isSheet && styles['list--sheet'])}\n onKeyDown={isSheet ? handleKeyDown : undefined}\n >\n {options.map((option, index) => {\n const isChosen = option.value === value;\n\n return (\n <li\n key={option.value}\n id={optionId(index)}\n role=\"option\"\n data-index={index}\n aria-selected={isChosen}\n aria-disabled={option.isDisabled}\n className={cx(\n styles.option,\n index === activeIndex && styles['option--active'],\n isChosen && styles['option--selected'],\n option.isDisabled && styles['option--disabled'],\n )}\n // Fare imleci seçeneğin üstündeyken etkin seçenek de oraya taşınır;\n // iki ayrı vurgu kullanıcıyı şaşırtıyordu.\n onMouseEnter={() => setActiveIndex(index)}\n onClick={() => selectOption(option)}\n >\n <span className={styles.option__label}>{option.label}</span>\n {isChosen && <CheckIcon className={styles.option__check} />}\n </li>\n );\n })}\n </ul>\n );\n\n return (\n <span ref={rootRef} className={cx(styles.select, className)} data-testid={testId}>\n <button\n ref={triggerRef}\n id={baseId}\n type=\"button\"\n role=\"combobox\"\n className={cx(\n styles.trigger,\n styles[`trigger--${size}`],\n !selectedOption && styles['trigger--empty'],\n isOpen && styles['trigger--open'],\n )}\n disabled={isDisabled}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={\n openMode === 'popover' && options[activeIndex] ? optionId(activeIndex) : undefined\n }\n aria-label={label}\n aria-describedby={describedBy}\n aria-invalid={isInvalid}\n onClick={() => (isOpen ? close() : open())}\n onKeyDown={handleKeyDown}\n >\n {icon && (\n <span className={styles.trigger__icon} aria-hidden>\n {icon}\n </span>\n )}\n\n <span className={styles.trigger__value}>{selectedOption?.label ?? placeholder}</span>\n\n <ChevronDownIcon\n className={cx(styles.trigger__chevron, isOpen && styles['trigger__chevron--open'])}\n />\n </button>\n\n {openMode === 'popover' && (\n <div className={cx(styles.panel, styles[`panel--${align}`])}>{renderList(false)}</div>\n )}\n\n {/* Dar ekranda liste alt sayfada acilir; panel klavye acilinca sikisiyor\n ve alt ucu ekranin disinda kaliyordu (bkz. `BottomSheet`). */}\n {openMode === 'sheet' && (\n <BottomSheet title={label} closeLabel={closeLabel} onClose={close}>\n {renderList(true)}\n </BottomSheet>\n )}\n </span>\n );\n};\n\nexport default memo(Select) as typeof Select;\n","import { forwardRef, type InputHTMLAttributes, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> & {\n label: ReactNode;\n hint?: string;\n testId?: string;\n};\n\n/**\n * Onay kutusu.\n *\n * <p>Yerel `<input type=\"checkbox\">` korunur ve `accent-color` ile\n * renklendirilir. Özel bir kutu çizmek (gizli input + sahte kare) klavye\n * odağını ve ekran okuyucu davranışını elle yeniden kurmayı gerektirir;\n * kazanç görsel, maliyet erişilebilirlik.\n *\n * <p>Tüm satır tıklanabilir (`<label>` sarmalar): 18 px'lik kareyi\n * hedeflemek özellikle dokunmatik ekranda yorucu.\n */\nconst Checkbox = forwardRef<HTMLInputElement, Props>(\n ({ label, hint, className, testId, ...rest }, ref) => (\n <label className={cx(styles.checkbox, className)} data-testid={testId}>\n <input ref={ref} type=\"checkbox\" className={styles.checkbox__input} {...rest} />\n <span className={styles.checkbox__body}>\n <span className={styles.checkbox__label}>{label}</span>\n {hint && <span className={styles.checkbox__hint}>{hint}</span>}\n </span>\n </label>\n ),\n);\n\nCheckbox.displayName = 'Checkbox';\n\nexport default memo(Checkbox) as typeof Checkbox;\n","import { forwardRef, type InputHTMLAttributes, memo, type ReactNode } from 'react';\n\nimport { isDefined } from '@ahmetilhn/handy-utils';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> & {\n label: ReactNode;\n hint?: string;\n /** Sağda gösterilen sonuç adedi (filtre listelerinde). */\n count?: number;\n testId?: string;\n};\n\n/**\n * Radyo düğmesi.\n *\n * <p>{@link Checkbox} ile aynı gerekçe: yerel `<input type=\"radio\">` korunur\n * ve `accent-color` ile renklendirilir. Sahte bir daire çizmek ok tuşlarıyla\n * gezinmeyi ve grup duyurusunu elle yeniden kurmayı gerektirirdi.\n *\n * <p>Tüm satır tıklanabilir (`<label>` sarmalar): 18 px'lik daireyi\n * hedeflemek özellikle dokunmatik ekranda yorucu.\n */\nconst Radio = forwardRef<HTMLInputElement, Props>(\n ({ label, hint, count, className, testId, ...rest }, ref) => (\n <label className={cx(styles.radio, className)} data-testid={testId}>\n <input ref={ref} type=\"radio\" className={styles.radio__input} {...rest} />\n <span className={styles.radio__body}>\n <span className={styles.radio__label}>{label}</span>\n {hint && <span className={styles.radio__hint}>{hint}</span>}\n </span>\n {isDefined(count) && <span className={styles.radio__count}>{count}</span>}\n </label>\n ),\n);\n\nRadio.displayName = 'Radio';\n\nexport default memo(Radio) as typeof Radio;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport type { CommonElementProps } from '../../types/common-element-props.type';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Radyo grubu adı — aynı gruptaki kartlar ok tuşlarıyla gezilir. */\n name: string;\n value: string;\n isSelected: boolean;\n isDisabled?: boolean;\n onChange: (value: string) => void;\n /** Zengin gövde: kartın içeriği çağırana aittir. */\n children: ReactNode;\n} & CommonElementProps;\n\n/**\n * Seçilebilir kart — zengin gövdeli radyo.\n *\n * <h3>Neden ayrı bir öğe</h3>\n * Varyant seçici ve hesap seçici aynı deseni elle kuruyordu: `<label>` + gizli\n * radyo + gövde + seçili/pasif durum matrisi. İki kopya çoktan ayrışmıştı —\n * biri odak halkasını metnin üstüne, diğeri hiç çizmiyordu; biri seçili zemini\n * boyuyor, diğeri boyamıyordu.\n *\n * <h3>Radyo GERÇEK, daire çizim</h3>\n * `<input type=\"radio\">` görsel olarak gizlenir ama DOM'da kalır: ok\n * tuşlarıyla grup içinde gezinme, `Space` ile seçim ve ekran okuyucu duyurusu\n * tarayıcıdan gelir. Yerel daire bu boyutta bir kartta görsel olarak\n * kaybolduğu için işaret ayrıca çizilir (`__indicator`).\n *\n * <h3>Seçim üç sinyalle</h3>\n * Kenarlık + zemin tinti + dolan işaret aynı anda değişir. İşaretin dolu / boş\n * hâli bir BİÇİM farkıdır — renk tek başına anlam taşımaz (WCAG 1.4.1).\n *\n * <p>Odak halkası kartın kendisinde (`:has(:focus-visible)`): gizli girdiye\n * çizilen halka görünmüyor, yalnızca metne çizilen halka da kartın nerede\n * bittiğini söylemiyordu.\n *\n * <p>{@link Radio} yalın satır içindir, gövde taşıyamaz — ikisi karışmaz.\n */\nconst RadioCard: FC<Props> = ({\n name,\n value,\n isSelected,\n isDisabled,\n onChange,\n children,\n className,\n id,\n testId,\n}) => (\n <label\n className={cx(\n styles.radioCard,\n isSelected && styles['radioCard--selected'],\n isDisabled && styles['radioCard--disabled'],\n className,\n )}\n data-testid={testId}\n >\n <input\n type=\"radio\"\n id={id}\n name={name}\n value={value}\n checked={isSelected}\n disabled={isDisabled}\n onChange={() => onChange(value)}\n className={styles.radioCard__input}\n />\n <span className={styles.radioCard__indicator} aria-hidden />\n <span className={styles.radioCard__body}>{children}</span>\n </label>\n);\n\nexport default memo(RadioCard) as typeof RadioCard;\n","'use client';\n\nimport { memo, useCallback } from 'react';\n\nimport { normalize } from '@ahmetilhn/handy-utils';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\nexport type RangeValue = [number, number];\n\ntype Props = {\n min: number;\n max: number;\n step?: number;\n value: RangeValue;\n /** Sürükleme sürerken her adımda çağrılır — ekrandaki değeri günceller. */\n onChange: (value: RangeValue) => void;\n /**\n * Sürükleme <em>bittiğinde</em> çağrılır. Adres çubuğuna yazmak veya\n * sunucuya istek atmak gibi pahalı işler buraya bağlanır.\n */\n onCommit?: (value: RangeValue) => void;\n /** Ham sayıyı okunur metne çevirir (\"125000\" → \"1.250 TL\"). */\n formatValue?: (value: number) => string;\n /** Grubun erişilebilir adı (\"Fiyat aralığı\"). */\n label: string;\n /** Alt kulbun erişilebilir ad eki (\"En az\"). */\n minLabel: string;\n /** Üst kulbun erişilebilir ad eki (\"En çok\"). */\n maxLabel: string;\n isDisabled?: boolean;\n className?: string;\n testId?: string;\n};\n\n/**\n * Çift kulplu aralık kaydırıcı.\n *\n * <h3>Neden iki gerçek `<input type=\"range\">`</h3>\n * Kulplar `<div>` ile çizilip sürükleme JavaScript'le yazıldığında klavye\n * desteği, ekran okuyucu duyurusu ve dokunma davranışı elle yeniden kurulmak\n * zorunda kalır — ve pratikte biri hep eksik kalır. Üst üste bindirilmiş iki\n * yerel aralık girdisi bunların hepsini ücretsiz getirir: ok tuşları, Home/End,\n * PageUp/PageDown ve aralık duyurusu kendiliğinden çalışır.\n *\n * <h3>Kulplar birbirini geçemez</h3>\n * Alt kulp üst değeri, üst kulp alt değeri aşamaz. Geçmelerine izin vermek\n * \"en az 8.000, en çok 1.200\" gibi anlamsız bir aralık üretiyordu.\n *\n * <h3>Sayı değil METİN duyurulur</h3>\n * `aria-valuetext` biçimlenmiş değeri taşır. Aksi hâlde ekran okuyucu ham\n * sayıyı (\"bir milyon iki yüz elli bin\") okuyordu.\n *\n * <h3>`onChange` ile `onCommit` ayrıdır</h3>\n * Kaydırırken her adımda adres çubuğuna yazmak, tek bir sürüklemede onlarca\n * gezinme kaydı bırakıp geri tuşunu kullanılamaz hâle getiriyordu. Ekran anında\n * güncellenir (`onChange`), sorgu yalnızca kulp bırakılınca yazılır.\n */\nconst RangeSlider = ({\n min,\n max,\n step = 1,\n value,\n onChange,\n onCommit,\n formatValue = String,\n label,\n minLabel,\n maxLabel,\n isDisabled,\n className,\n testId,\n}: Props) => {\n const [low, high] = value;\n\n const handleLowChange = useCallback(\n (raw: number) => onChange([Math.min(raw, high), high]),\n [high, onChange],\n );\n\n const handleHighChange = useCallback(\n (raw: number) => onChange([low, Math.max(raw, low)]),\n [low, onChange],\n );\n\n const commit = useCallback(() => onCommit?.([low, high]), [low, high, onCommit]);\n\n /* `normalize` yuzdeyi verir ve 100'de kirpar; olcek sifir genislikte\n oldugunda (min === max) 0 doner. */\n const span = max - min;\n const lowPercent = span === 0 ? 0 : normalize(low - min, span);\n const highPercent = span === 0 ? 0 : normalize(high - min, span);\n\n /*\n * Iki kulp ust uste geldiginde hangisinin tutulacagi belirsizlesir. Alt kulp\n * olcegin ikinci yarisindaysa one alinir; aksi halde ust kulp onu kapatip\n * alt kulbu yakalanamaz kiliyordu.\n */\n const isLowOnTop = lowPercent > 50;\n\n return (\n <div\n className={cx(styles.range, isDisabled && styles['range--disabled'], className)}\n role=\"group\"\n aria-label={label}\n data-testid={testId}\n >\n <div className={styles.range__readout}>\n <span className={styles.range__value}>{formatValue(low)}</span>\n <span className={styles.range__separator} aria-hidden>\n —\n </span>\n <span className={styles.range__value}>{formatValue(high)}</span>\n </div>\n\n <div className={styles.range__track}>\n {/* Secili aralik: kullanicinin nerede durdugunu tek bakista gosterir. */}\n <span\n className={styles.range__fill}\n style={{ left: `${lowPercent}%`, right: `${100 - highPercent}%` }}\n aria-hidden\n />\n\n <input\n type=\"range\"\n className={styles.range__input}\n style={{ zIndex: isLowOnTop ? 4 : 3 }}\n min={min}\n max={max}\n step={step}\n value={low}\n disabled={isDisabled}\n aria-label={`${label} — ${minLabel}`}\n aria-valuetext={formatValue(low)}\n onChange={event => handleLowChange(Number(event.target.value))}\n onPointerUp={commit}\n onKeyUp={commit}\n />\n\n <input\n type=\"range\"\n className={styles.range__input}\n style={{ zIndex: isLowOnTop ? 3 : 4 }}\n min={min}\n max={max}\n step={step}\n value={high}\n disabled={isDisabled}\n aria-label={`${label} — ${maxLabel}`}\n aria-valuetext={formatValue(high)}\n onChange={event => handleHighChange(Number(event.target.value))}\n onPointerUp={commit}\n onKeyUp={commit}\n />\n </div>\n\n {/* Olcegin uclari: kullanici kendi araligini baglama oturtabilmeli. */}\n <div className={styles.range__bounds} aria-hidden>\n <span>{formatValue(min)}</span>\n <span>{formatValue(max)}</span>\n </div>\n </div>\n );\n};\n\nexport default memo(RangeSlider) as typeof RangeSlider;\n","'use client';\n\nimport { memo, useId, useState } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { StarFillIcon } from '../../icons';\n\nimport styles from './index.module.scss';\n\n/** Beş puanın her birinin ne anlama geldiği. */\nexport type RatingLabels = Record<1 | 2 | 3 | 4 | 5, string>;\n\ntype Props = {\n value: number | null;\n onChange: (value: number) => void;\n /** Grubun erişilebilir adı (\"Ürün puanı\"). */\n label: string;\n /**\n * Puan açıklamaları — ZORUNLU. Hem ekran okuyucuya okunur hem de seçildiğinde\n * yıldızların altında yazar.\n *\n * <p>Dolu yıldız sayısı tek başına bir renk/şekil sinyali. Yanına açıklama\n * yazmak hem anlamı netleştirir hem de renk körü kullanıcıya ikinci bir ipucu\n * verir (WCAG 1.4.1).\n */\n ratingLabels: RatingLabels;\n /** Ekran okuyucuda yıldız sayısını okuyan biçimlendirici (\"4 yıldız\"). */\n formatStarCount: (star: number) => string;\n isDisabled?: boolean;\n className?: string;\n testId?: string;\n};\n\nconst STARS = [1, 2, 3, 4, 5] as const;\n\n/**\n * Yıldızla puan girişi.\n *\n * <h3>Beş gerçek radyo düğmesi</h3>\n * Yıldızlar `<span>` ile çizilip tıklama JavaScript'e bağlanabilirdi. Bunun\n * yerine `<fieldset>` içinde beş yerel `<input type=\"radio\">` kullanılır ve\n * yıldız görünümü etiketlerine verilir. Böylece ok tuşlarıyla gezinme, Tab\n * davranışı, ekran okuyucuda \"5 seçenekten 4'ü seçili\" duyurusu ve form\n * gönderimine katılma <em>bedava</em> gelir.\n *\n * <p>{@link Rating} genişletilemez: o `<span>` üretiyor ve açıkça\n * salt-gösterim. İkisini tek bileşende toplamak, gösterim tarafına hiç\n * kullanılmayan etkileşim kodu taşımak olurdu.\n */\nconst RatingInput = ({\n value,\n onChange,\n label,\n ratingLabels,\n formatStarCount,\n isDisabled,\n className,\n testId,\n}: Props) => {\n const name = useId();\n const [hovered, setHovered] = useState<number | null>(null);\n\n // Fare yildizlarin uzerindeyken onizleme gosterilir; ayrilinca gercek\n // secime doner.\n const shown = hovered ?? value;\n\n return (\n <fieldset\n className={cx(styles.rating, isDisabled && styles['rating--disabled'], className)}\n disabled={isDisabled}\n data-testid={testId}\n >\n <legend className={styles.rating__legend}>{label}</legend>\n\n <div className={styles.rating__stars} onMouseLeave={() => setHovered(null)}>\n {STARS.map(star => (\n <label\n key={star}\n className={cx(\n styles.rating__star,\n shown !== null && star <= shown && styles['rating__star--filled'],\n )}\n onMouseEnter={() => setHovered(star)}\n >\n <input\n type=\"radio\"\n name={name}\n value={star}\n checked={value === star}\n onChange={() => onChange(star)}\n className={styles.rating__input}\n />\n <StarFillIcon />\n <span className={styles.rating__srOnly}>\n {formatStarCount(star)} — {ratingLabels[star]}\n </span>\n </label>\n ))}\n </div>\n\n {/* Secim metni: `aria-hidden` cunku ayni bilgi radyonun etiketinde var. */}\n {shown !== null && (\n <span className={styles.rating__caption} aria-hidden>\n {ratingLabels[shown as 1 | 2 | 3 | 4 | 5]}\n </span>\n )}\n </fieldset>\n );\n};\n\nexport default memo(RatingInput) as typeof RatingInput;\n","'use client';\n\nimport { type FC, memo, useState } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { MinusIcon, PlusIcon } from '../../icons';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n value: number;\n onChange: (value: number) => void;\n /** Grubun ve girdinin erişilebilir adı (\"Adet\"). */\n label: string;\n decreaseLabel: string;\n increaseLabel: string;\n min?: number;\n max?: number;\n isDisabled?: boolean;\n size?: 'sm' | 'md';\n className?: string;\n testId?: string;\n};\n\n/**\n * Adet seçici.\n *\n * <p>Doğrudan yazma da desteklenir: 12 adet isteyen kullanıcının artı düğmesine\n * on iki kez basması kabul edilemez.\n *\n * <p>Yazılan değer <strong>odak kaybında</strong> sınırlara çekilir, her tuş\n * vuruşunda değil: \"12\" yazarken \"1\"i anında 1'e sabitlemek kullanıcının\n * yazmasını engellerdi.\n */\nconst QuantityStepper: FC<Props> = ({\n value,\n onChange,\n label,\n decreaseLabel,\n increaseLabel,\n min = 1,\n max = 99,\n isDisabled,\n size = 'md',\n className,\n testId,\n}) => {\n const [draft, setDraft] = useState<string | null>(null);\n\n const commit = (raw: string) => {\n setDraft(null);\n const parsed = Number(raw.replace(/\\D/g, ''));\n if (!parsed) return;\n onChange(Math.min(Math.max(parsed, min), max));\n };\n\n return (\n <div\n className={cx(styles.stepper, styles[`stepper--${size}`], className)}\n role=\"group\"\n aria-label={label}\n data-testid={testId}\n >\n <button\n type=\"button\"\n className={styles.stepper__button}\n onClick={() => onChange(Math.max(value - 1, min))}\n disabled={isDisabled || value <= min}\n aria-label={decreaseLabel}\n >\n <MinusIcon />\n </button>\n\n <input\n className={styles.stepper__input}\n value={draft ?? String(value)}\n onChange={event => setDraft(event.target.value.replace(/\\D/g, '').slice(0, 2))}\n onBlur={event => commit(event.target.value)}\n onKeyDown={event => {\n if (event.key === 'Enter') {\n event.preventDefault();\n commit((event.target as HTMLInputElement).value);\n }\n }}\n inputMode=\"numeric\"\n disabled={isDisabled}\n aria-label={`${label} (${min}-${max})`}\n />\n\n <button\n type=\"button\"\n className={styles.stepper__button}\n onClick={() => onChange(Math.min(value + 1, max))}\n disabled={isDisabled || value >= max}\n aria-label={increaseLabel}\n >\n <PlusIcon />\n </button>\n </div>\n );\n};\n\nexport default memo(QuantityStepper) as typeof QuantityStepper;\n","import { forwardRef, type InputHTMLAttributes, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'aria-label'> & {\n /**\n * Erişilebilir ad — ZORUNLU. Hücrede görünür etiket yok (etiket sütun\n * başlığında); adsız kutu ekran okuyucuda yalnızca \"onay kutusu\" diye\n * okunur. Satır kutusunda kaydın kimliğini söyleyin (\"SP-2026-000123 seç\").\n */\n label: string;\n testId?: string;\n};\n\n/**\n * Tablo hücresindeki toplu seçim kutusu.\n *\n * <h3>Neden `Checkbox` değil</h3>\n * Seçim sütununda etiket sütun başlığıdır ve `Checkbox` bileşeninin ürettiği\n * `<label>` sarmalayıcısı (yan yana kutu + metin yerleşimi) hücreyi bozar.\n * Doğru olan yalın `<input type=\"checkbox\">` + `aria-label` — bu bileşen o\n * deseni resmileştirir ki ekranlar çıplak `<input>` yazmak zorunda kalmasın.\n *\n * <p>Renk `Checkbox` ile aynı kaynaktan: `accent-color` mavi — onay kutusu bir\n * seçimdir, bir dönüşüm değil.\n */\nconst TableCheckbox = forwardRef<HTMLInputElement, Props>(\n ({ label, className, testId, ...rest }, ref) => (\n <input\n ref={ref}\n type=\"checkbox\"\n aria-label={label}\n className={cx(styles.checkbox, className)}\n data-testid={testId}\n {...rest}\n />\n ),\n);\n\nTableCheckbox.displayName = 'TableCheckbox';\n\nexport default memo(TableCheckbox) as typeof TableCheckbox;\n","import { forwardRef, type InputHTMLAttributes, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\n/*\n * `prefix` HTML'in RDFa nitelikleri arasinda yer alir ve React onu `string`\n * olarak tanimlar. Kaldirilmazsa kendi `ReactNode` tanimimizla kesisip\n * `string & ReactNode` uretiyor ve ikon vermeyi imkansiz kiliyordu.\n */\ntype Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'prefix'> & {\n /** Solda gösterilen ikon veya ön ek (arama simgesi, para birimi). */\n prefix?: ReactNode;\n /** Sağda gösterilen ikon veya birim (göz simgesi, \"kg\"). */\n suffix?: ReactNode;\n /** Teknik veri: SKU, kod, seri numarası — monospace ve harf aralıklı. */\n isTechnical?: boolean;\n testId?: string;\n};\n\n/**\n * Metin girdisi.\n *\n * <p>Ön ek / son ek girdinin <em>içinde</em> konumlanır; girdinin yanına ayrı\n * bir kutu koymak hizalamayı bozar ve odak halkasını ikiye böler.\n *\n * <p>Odak halkası sarmalayıcıda değil girdinin kendisinde: sarmalayıcıya\n * verildiğinde `:focus-visible` klavye/fare ayrımını kaybediyordu.\n */\nconst Input = forwardRef<HTMLInputElement, Props>(\n ({ prefix, suffix, isTechnical, className, testId, ...rest }, ref) => (\n <span className={cx(styles.wrapper, className)}>\n {prefix && (\n <span className={styles.wrapper__prefix} aria-hidden>\n {prefix}\n </span>\n )}\n <input\n ref={ref}\n className={cx(\n styles.input,\n /* `Boolean(...)`: `prefix` bir `ReactNode` ve `0` da gecerli bir\n deger — `prefix &&` ifadesi o durumda dize degil sayi donuyordu. */\n Boolean(prefix) && styles['input--hasPrefix'],\n Boolean(suffix) && styles['input--hasSuffix'],\n isTechnical && styles['input--technical'],\n )}\n data-testid={testId}\n {...rest}\n />\n {suffix && (\n <span className={styles.wrapper__suffix} aria-hidden>\n {suffix}\n </span>\n )}\n </span>\n ),\n);\n\nInput.displayName = 'Input';\n\nexport default memo(Input) as typeof Input;\n","import { forwardRef, memo, type TextareaHTMLAttributes } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = TextareaHTMLAttributes<HTMLTextAreaElement> & { testId?: string };\n\n/**\n * Çok satırlı metin girdisi.\n *\n * <p>Görünüm {@link Input} ile aynı gövdeden gelir: bir formda tek satırlı ve\n * çok satırlı alanlar yan yana durur, kenarlık ve odak davranışları ayrışırsa\n * form derlenmemiş görünür.\n *\n * <p>Yeniden boyutlandırma yalnızca <strong>dikey</strong>: yatayda büyütmek\n * alanı kapsayıcısının dışına taşırıp yerleşimi bozuyordu.\n */\nconst Textarea = forwardRef<HTMLTextAreaElement, Props>(\n ({ className, rows = 4, testId, ...rest }, ref) => (\n <textarea\n ref={ref}\n rows={rows}\n className={cx(styles.textarea, className)}\n data-testid={testId}\n {...rest}\n />\n ),\n);\n\nTextarea.displayName = 'Textarea';\n\nexport default memo(Textarea) as typeof Textarea;\n","import { type FC, memo, type ReactNode, useId } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { ExclamationCircleIcon } from '../../icons';\n\nimport styles from './index.module.scss';\n\n/** Girdiye yayılacak erişilebilirlik bağları. */\nexport type FieldChildProps = {\n id: string;\n 'aria-invalid'?: boolean;\n 'aria-describedby'?: string;\n required?: boolean;\n};\n\ntype BaseProps = {\n label: string;\n /** Girdi bileşenini alan `id` ve `aria-*` bağlarıyla üretir. */\n children: (props: FieldChildProps) => ReactNode;\n hint?: string;\n error?: string;\n /** Etiketi gizler ama ekran okuyucuya bırakır (arama kutusu gibi). */\n isLabelHidden?: boolean;\n className?: string;\n};\n\n/**\n * Zorunluluk işareti ve onun ekran okuyucu karşılığı BİRLİKTE verilir.\n *\n * <p>Yıldız yalnızca görsel bir kısayol; renk ve şekil tek başına anlam\n * taşıyamaz (WCAG 1.4.1). `requiredLabel` bir dil kararı ve kütüphane onu\n * uyduramaz — bu yüzden `isRequired` verildiğinde tip zorunlu kılıyor.\n */\ntype RequiredProps =\n { isRequired: true; requiredLabel: string } | { isRequired?: false; requiredLabel?: never };\n\ntype Props = BaseProps & RequiredProps;\n\n/**\n * Form alanı sarmalayıcısı.\n *\n * <h3>Neden render-prop</h3>\n * Etiket, hata mesajı ve yardım metni girdiye `id` / `aria-describedby` /\n * `aria-invalid` ile <strong>bağlanmak zorunda</strong> — yoksa ekran okuyucu\n * hatayı okumaz. Bu bağları her form alanında elle yazmak kaçınılmaz olarak\n * bir yerde atlanıyor.\n *\n * <p>Render-prop kalıbı bağları bileşene ürettirir: çağıran taraf yalnızca\n * aldığı props'ları girdiye yayar ve erişilebilirlik kendiliğinden doğru olur.\n *\n * <p>Hata varken yardım metni gösterilmez: ikisi birlikte gürültü yapar ve\n * kullanıcının okuması gereken mesaj kaybolur.\n *\n * @example\n * <Field label=\"E-posta\" isRequired requiredLabel=\"(zorunlu)\" error={emailError}>\n * {props => <Input {...props} type=\"email\" value={email} onChange={onChange} />}\n * </Field>\n *\n * @example\n * // `{...props}` yaymayan bileşenlerde (Combobox, Select) yalnızca `id`:\n * <Field label=\"Şehir\">{props => <Combobox id={props.id} … />}</Field>\n */\nconst Field: FC<Props> = ({\n label,\n children,\n hint,\n error,\n isRequired,\n requiredLabel,\n isLabelHidden,\n className,\n}) => {\n const id = useId();\n const errorId = `${id}-error`;\n const hintId = `${id}-hint`;\n\n return (\n <div className={cx(styles.field, className)}>\n <label\n htmlFor={id}\n className={cx(styles.field__label, isLabelHidden && styles['field__label--hidden'])}\n >\n {label}\n {isRequired && (\n <>\n <span className={styles.field__required} aria-hidden>\n *\n </span>\n <span className={styles.field__srOnly}>{requiredLabel}</span>\n </>\n )}\n </label>\n\n {children({\n id,\n required: isRequired || undefined,\n 'aria-invalid': error ? true : undefined,\n 'aria-describedby': error ? errorId : hint ? hintId : undefined,\n })}\n\n {error ? (\n <p id={errorId} className={styles.field__error} role=\"alert\">\n <ExclamationCircleIcon />\n {error}\n </p>\n ) : (\n hint && (\n <p id={hintId} className={styles.field__hint}>\n {hint}\n </p>\n )\n )}\n </div>\n );\n};\n\nexport default memo(Field) as typeof Field;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport {\n CheckCircleFillIcon,\n ExclamationTriangleFillIcon,\n InfoCircleFillIcon,\n XCircleFillIcon,\n} from '../../icons';\n\nimport styles from './index.module.scss';\n\nexport type AlertTone = 'info' | 'success' | 'warning' | 'danger';\n\ntype Props = {\n children: ReactNode;\n tone?: AlertTone;\n title?: string;\n /** Sağda gösterilen eylem (bağlantı veya düğme). */\n action?: ReactNode;\n className?: string;\n testId?: string;\n};\n\n/** Her tona kendi ikonu; renk tek başına anlam taşımaz (WCAG 1.4.1). */\nconst ICONS: Record<AlertTone, ReactNode> = {\n info: <InfoCircleFillIcon />,\n success: <CheckCircleFillIcon />,\n warning: <ExclamationTriangleFillIcon />,\n danger: <XCircleFillIcon />,\n};\n\n/**\n * Bilgi / uyarı kutusu.\n *\n * <p>`danger` ve `warning` tonları `role=\"alert\"` taşır: ekran okuyucu bunları\n * anında duyurur. `info` ve `success` duyurulmaz — sayfa yüklenirken her bilgi\n * kutusunun okunması gürültü olurdu.\n */\nconst Alert: FC<Props> = ({ children, tone = 'info', title, action, className, testId }) => (\n <div\n className={cx(styles.alert, styles[`alert--${tone}`], className)}\n role={tone === 'danger' || tone === 'warning' ? 'alert' : undefined}\n data-testid={testId}\n >\n <span className={styles.alert__icon}>{ICONS[tone]}</span>\n\n <div className={styles.alert__body}>\n {title && <strong className={styles.alert__title}>{title}</strong>}\n <div className={styles.alert__content}>{children}</div>\n </div>\n\n {action && <div className={styles.alert__action}>{action}</div>}\n </div>\n);\n\nexport default memo(Alert) as typeof Alert;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Tam ad; baş harfler buradan üretilir ve görsel yoksa `alt` metnidir. */\n name: string;\n /**\n * Profil görseli. Verilmezse baş harf madalyonuna düşer — çağıran tarafın\n * koşul yazması gerekmez.\n */\n imageUrl?: string;\n /**\n * Baş harfleri büyütürken kullanılacak dil etiketi (\"tr\", \"az\").\n *\n * <p>Türkçede ZORUNLU: `toUpperCase()` \"i\" harfini \"I\" yapıyor ve \"İlhan\"ın\n * baş harfi \"I\" çıkıyor. `toLocaleUpperCase('tr')` doğru \"İ\" verir.\n * Verilmezse çalışma ortamının varsayılan dili kullanılır.\n */\n locale?: string;\n size?: 'sm' | 'md' | 'lg';\n className?: string;\n testId?: string;\n};\n\n/**\n * Baş harfleri üretir: \"Ahmet İlhan\" → \"Aİ\".\n *\n * <p>Tek kelimelik adda ilk iki harf alınır; tek harflik bir madalyon boş\n * görünüyordu.\n */\nconst resolveInitials = (name: string, locale?: string): string => {\n const words = name.trim().split(/\\s+/).filter(Boolean);\n if (words.length === 0) return '?';\n\n const letters =\n words.length === 1 ? words[0].slice(0, 2) : `${words[0][0]}${words[words.length - 1][0]}`;\n\n return locale ? letters.toLocaleUpperCase(locale) : letters.toLocaleUpperCase();\n};\n\n/**\n * Avatar — kullanıcı madalyonu.\n *\n * <h3>Görsel yoksa baş harf</h3>\n * Profil görseli olmayan bir sistemde baş harf madalyonu kimliği\n * <em>yeterince</em> taşır: kullanıcı hesap menüsünün en üstünde doğru hesapta\n * olduğunu görmek ister, fotoğrafını değil. `imageUrl` verildiğinde görsel\n * çizilir ve baş harf yedeğe düşer; çağıran tarafların değişmesi gerekmez.\n *\n * <h3>Ekran okuyucuya okunmaz</h3>\n * Madalyon `aria-hidden`: yanında zaten adın kendisi yazıyor. İkisini de\n * okumak \"A İ Ahmet İlhan\" gibi bir gürültü üretiyordu. Adın yanında\n * durmadığı bir yerde kullanılıyorsa çağıran taraf metni kendisi yazar.\n */\nconst Avatar: FC<Props> = ({ name, imageUrl, locale, size = 'md', className, testId }) => (\n <span\n className={cx(styles.avatar, styles[`avatar--${size}`], className)}\n aria-hidden\n data-testid={testId}\n >\n {imageUrl ? (\n <img className={styles.avatar__image} src={imageUrl} alt=\"\" />\n ) : (\n resolveInitials(name, locale)\n )}\n </span>\n);\n\nexport default memo(Avatar) as typeof Avatar;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\nexport type BadgeTone =\n | 'neutral'\n | 'success'\n | 'danger'\n | 'warning'\n | 'info'\n /** Birincil sınıflandırma tinti (mavi-lacivert aile). */\n | 'oem'\n /** İkincil sınıflandırma tinti (mor aile). */\n | 'alt'\n /** İndirim / olumlu değişim yüzdesi. Tutarın kendisi nötr kalır. */\n | 'sale'\n /** Miktar sayacı (sepet adedi, filtre sayısı) — dolu zemine izin verilir. */\n | 'action'\n /** Gezinme etiketi. */\n | 'link';\n\nexport type BadgeVariant = 'soft' | 'solid' | 'outline';\n\ntype Props = {\n children: ReactNode;\n tone?: BadgeTone;\n variant?: BadgeVariant;\n /** Küçük ikon; metnin solunda gösterilir. */\n icon?: ReactNode;\n className?: string;\n testId?: string;\n};\n\n/**\n * Rozet — durum ve sınıflandırma etiketi.\n *\n * <p><strong>Renk tek başına anlam taşımaz</strong> (WCAG 1.4.1): her rozet\n * okunabilir bir metin içerir. `tone` yalnızca metni pekiştirir; renk körü bir\n * kullanıcı da aynı bilgiyi alır.\n *\n * <h3>Durum tonlarında `solid` ile `soft` aynı şeyi verir</h3>\n * Bu bilinçli. <strong>Doygun dolgu = tıklanabilir</strong> kuralı gereği dolu\n * zeminli bir durum etiketi düğmeye benziyor ve kullanıcılar \"Son 2 adet\" gibi\n * bir etikete tıklamayı deniyordu. Prop çağıran tarafları kırmamak için\n * korundu, görünüm tint'e sabitlendi.\n *\n * <p>Doygun dolgu yalnızca <strong>miktar</strong> tonlarında (`action`,\n * `link`) anlamlı: onlar bir durumu değil bir sayıyı bildirir ve tıklanabilir\n * bir öğenin parçasıdır.\n */\nconst Badge: FC<Props> = ({\n children,\n tone = 'neutral',\n variant = 'soft',\n icon,\n className,\n testId,\n}) => (\n <span\n className={cx(styles.badge, styles[`badge--${tone}`], styles[`badge--${variant}`], className)}\n data-testid={testId}\n >\n {icon && <span className={styles.badge__icon}>{icon}</span>}\n {children}\n </span>\n);\n\nexport default memo(Badge) as typeof Badge;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { ChevronRightIcon } from '../../icons';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport HanuiLink from '../Link';\n\nimport styles from './index.module.scss';\n\nexport type Crumb = {\n label: string;\n /** Son öğede verilmez: bulunduğumuz sayfa bağlantı olmaz. */\n href?: string;\n};\n\ntype Props = {\n items: Crumb[];\n /** Gezinme bölgesinin erişilebilir adı (\"Konum\", \"Breadcrumb\"). */\n label: string;\n /** Yönlendiriciye geçirilecek ek props. */\n linkProps?: HanuiLinkExtraProps;\n className?: string;\n testId?: string;\n};\n\n/**\n * Kırıntı yolu.\n *\n * <p>Son öğe bağlantı DEĞİL ve `aria-current=\"page\"` taşır: bulunduğu sayfaya\n * bağlantı veren bir kırıntı yolu, ekran okuyucu kullanıcısını yanıltır.\n *\n * <p>Ayırıcı ikon `aria-hidden`; ekran okuyucu liste yapısından hiyerarşiyi\n * zaten anlar.\n */\nconst Breadcrumb: FC<Props> = ({ items, label, linkProps, className, testId }) => (\n <nav className={className} aria-label={label} data-testid={testId}>\n <ol className={cx(styles.breadcrumb)}>\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n\n return (\n <li key={`${item.label}-${index}`} className={styles.breadcrumb__item}>\n {item.href && !isLast ? (\n <HanuiLink href={item.href} className={styles.breadcrumb__link} {...linkProps}>\n {item.label}\n </HanuiLink>\n ) : (\n <span className={styles.breadcrumb__current} aria-current=\"page\">\n {item.label}\n </span>\n )}\n\n {!isLast && <ChevronRightIcon className={styles.breadcrumb__separator} />}\n </li>\n );\n })}\n </ol>\n </nav>\n);\n\nexport default memo(Breadcrumb) as typeof Breadcrumb;\n","import { type ElementType, type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport HanuiLink from '../Link';\n\nimport styles from './index.module.scss';\n\ntype CardProps = {\n children: ReactNode;\n /** Kartın tamamı bir hedefe götürüyorsa hover geri bildirimi açılır. */\n isInteractive?: boolean;\n /** Semantik etiket: liste öğesi kartları `article` olmalı. */\n as?: ElementType;\n className?: string;\n testId?: string;\n};\n\n/**\n * Kart — medya + gövde + eylem şeridi.\n *\n * <h3>Neden bileşik (compound) bir bileşen</h3>\n * Bir uygulamadaki her kart (ürün, kampanya, sipariş) aynı üç bölümden oluşur\n * ama içerikleri tamamen farklıdır. Tek bir \"her şeyi yapan\" kart bileşeni on\n * beş isteğe bağlı prop'a şişiyordu. Bunun yerine <em>yerleşim</em>\n * paylaşılır, içerik çağırana bırakılır: kenarlık, yarıçap, gölge, medya oranı\n * ve eylem şeridinin dipte durması tek yerde tanımlıdır.\n *\n * <h3>Eylem şeridi hep dipte</h3>\n * {@link CardFooter} `margin-top: auto` alır. Izgarada yan yana duran kartların\n * başlıkları farklı uzunlukta olsa da alt şerit aynı hizada kalır; aksi hâlde\n * satır dalgalı görünüyordu.\n *\n * @example\n * <Card as=\"article\" isInteractive>\n * <CardMedia href=\"/urun/x\" ratio={1}>\n * <CardOverlay position=\"top-left\"><Badge>Yeni</Badge></CardOverlay>\n * <img src={…} alt=\"\" />\n * </CardMedia>\n * <CardBody>…</CardBody>\n * <CardFooter>…</CardFooter>\n * </Card>\n */\nconst Card: FC<CardProps> = ({ children, isInteractive, as: Tag = 'div', className, testId }) => (\n <Tag\n className={cx(styles.card, isInteractive && styles['card--interactive'], className)}\n data-testid={testId}\n >\n {children}\n </Tag>\n);\n\ntype CardMediaProps = {\n children: ReactNode;\n /** Genişlik / yükseklik oranı. Sabit oran yükleme sırasında kaymayı önler. */\n ratio?: number;\n /** Medya alanı tıklanabilirse: görsel bağlantının içine alınır. */\n href?: string;\n /** Yönlendiriciye geçirilecek ek props. */\n linkProps?: HanuiLinkExtraProps;\n /** İçeriği kırpmak yerine sığdırır (şeffaf zeminli ürün fotoğrafları gibi). */\n isContained?: boolean;\n className?: string;\n};\n\n/**\n * Kartın görsel alanı.\n *\n * <p>Oran <strong>sabittir</strong>: görsel yüklenene kadar yer tutar ve\n * yerleşim kaymasını (CLS) önler. Oransız bırakıldığında kartlar görseller\n * yüklendikçe zıplıyordu.\n */\nexport const CardMedia: FC<CardMediaProps> = memo(\n ({ children, ratio = 1, href, linkProps, isContained = true, className }) => {\n const content = (\n <span\n className={cx(styles.media__frame, isContained && styles['media__frame--contained'])}\n style={{ aspectRatio: ratio }}\n >\n {children}\n </span>\n );\n\n return (\n <div className={cx(styles.media, className)}>\n {href ? (\n // `tabIndex={-1}` + `aria-hidden`: aynı hedefe giden başlık bağlantısı\n // zaten sekme sırasında. Görseli ikinci bir durak yapmak klavye\n // gezinmesini iki katına çıkarıyor, ekran okuyucuda da aynı kayıt\n // arka arkaya iki kez duyuruluyordu.\n <HanuiLink\n href={href}\n className={styles.media__link}\n tabIndex={-1}\n aria-hidden\n {...linkProps}\n >\n {content}\n </HanuiLink>\n ) : (\n content\n )}\n </div>\n );\n },\n);\n\nCardMedia.displayName = 'CardMedia';\n\ntype CardOverlayProps = {\n children: ReactNode;\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n className?: string;\n};\n\n/**\n * Görselin üzerine binen katman: rozetler ve hızlı eylemler.\n *\n * <p>Varsayılan olarak `pointer-events: none` — rozet yığını, altındaki görsel\n * bağlantısının tıklanmasını engellememeli. İçindeki gerçek düğmeler kendi\n * olaylarını geri açar.\n */\nexport const CardOverlay: FC<CardOverlayProps> = memo(\n ({ children, position = 'top-left', className }) => (\n <div className={cx(styles.overlay, styles[`overlay--${position}`], className)}>{children}</div>\n ),\n);\n\nCardOverlay.displayName = 'CardOverlay';\n\ntype CardSectionProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Kartın metin gövdesi: başlık, açıklama, üstyazı. */\nexport const CardBody: FC<CardSectionProps> = memo(({ children, className }) => (\n <div className={cx(styles.body, className)}>{children}</div>\n));\n\nCardBody.displayName = 'CardBody';\n\n/** Eylem şeridi — tutar, düğmeler. Kartın dibine yapışır. */\nexport const CardFooter: FC<CardSectionProps> = memo(({ children, className }) => (\n <div className={cx(styles.footer, className)}>{children}</div>\n));\n\nCardFooter.displayName = 'CardFooter';\n\nexport default memo(Card) as typeof Card;\n","'use client';\n\nimport { type FC, memo, useCallback, useEffect, useRef, useState } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { CheckSmallIcon, CopyIcon } from '../../icons';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Gösterilecek ve panoya kopyalanacak değer. */\n value: string;\n /** Kopyalama düğmesinin erişilebilir adı ve `title`ı. */\n copyLabel: string;\n /** Kopyalandıktan sonraki erişilebilir ad ve `title`. */\n copiedLabel: string;\n /** `aria-live` ile duyurulan onay cümlesi (\"Panoya kopyalandı\"). */\n copiedAnnouncement: string;\n size?: 'sm' | 'md';\n /**\n * Kopyalama düğmesini gizler.\n *\n * <p>Yalnızca değerin <em>zaten tıklanabilir bir şeyin içinde</em> olduğu\n * yerlerde (bir bağlantının gövdesi) verilir: iç içe etkileşim öğesi geçersiz\n * HTML üretir.\n */\n isReadOnly?: boolean;\n className?: string;\n testId?: string;\n};\n\n/** \"Kopyalandı\" geri bildiriminin ekranda kalma suresi (ms). */\nconst COPIED_FEEDBACK_MS = 1600;\n\n/**\n * Kopyalanabilir teknik değer — <strong>tek dokunuşla panoya</strong>.\n *\n * <h3>Neden ayrı bir öğe</h3>\n * Bir kod (SKU, parça numarası, sipariş numarası, IBAN) dekoratif bir metin\n * değil, kullanıcının <em>taşıdığı</em> veri. Düz bir `<span>` olduğunda\n * kullanıcı onu fareyle seçmeye çalışırken kartın tamamını seçiyor ya da\n * yanlışlıkla altındaki bağlantıyı tetikliyordu.\n *\n * <h3>Neden monospace</h3>\n * \"0986479644\" gibi diziler orantılı yazı tipinde okunmuyor: `0`/`O` ve `1`/`l`\n * ayırt edilemiyor ve bir hane atlandığında tamamen başka bir kayıt oluyor.\n * `technical-text` sabit genişlik + `tabular-nums` verir; iki değer alt alta\n * geldiğinde farklı hane gözle bulunur.\n *\n * <h3>Geri bildirim neden düğmenin üstünde</h3>\n * Bir bildirim (toast) da olurdu ama listelerde on beş satır var; ekranın\n * dibinde \"kopyalandı\" yazması <em>hangisinin</em> kopyalandığını\n * söylemiyordu. İkon yerinde tike dönünce cevap tıklanan yerde.\n *\n * <h3>Pano erişimi reddedilirse</h3>\n * `navigator.clipboard` güvenli olmayan bağlamda (HTTP) ve izin verilmediğinde\n * reddeder. O durumda değer sessizce <em>seçilir</em>: kullanıcı Ctrl+C ile\n * kendisi kopyalayabilir. Sessizce hiçbir şey yapmamak, düğmeyi bozuk\n * gösteriyordu.\n */\nconst CopyField: FC<Props> = ({\n value,\n copyLabel,\n copiedLabel,\n copiedAnnouncement,\n size = 'sm',\n isReadOnly,\n className,\n testId,\n}) => {\n const [isCopied, setIsCopied] = useState(false);\n const codeRef = useRef<HTMLSpanElement>(null);\n const timerRef = useRef<number | undefined>(undefined);\n\n // Bilesen sokulurse zamanlayici da gitmeli; aksi halde React \"unmounted\n // component\" uyarisi veriyor.\n useEffect(() => () => window.clearTimeout(timerRef.current), []);\n\n const selectValue = useCallback(() => {\n const node = codeRef.current;\n if (!node) return;\n\n const range = document.createRange();\n range.selectNodeContents(node);\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n }, []);\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(value);\n setIsCopied(true);\n timerRef.current = window.setTimeout(() => setIsCopied(false), COPIED_FEEDBACK_MS);\n } catch {\n // Pano yoksa/izin verilmediyse en azindan secili birakilir.\n selectValue();\n }\n }, [value, selectValue]);\n\n return (\n <span className={cx(styles.copy, styles[`copy--${size}`], className)} data-testid={testId}>\n {/*\n `user-select: all` (CSS): tek tiklama degerin TAMAMINI secer.\n Kullanicilar fareyle surukleyip yarim deger kopyaliyordu.\n */}\n <span className={styles.copy__code} ref={codeRef}>\n {value}\n </span>\n\n {!isReadOnly && (\n <button\n type=\"button\"\n className={cx(styles.copy__button, isCopied && styles['copy__button--done'])}\n onClick={handleCopy}\n aria-label={isCopied ? copiedLabel : copyLabel}\n title={isCopied ? copiedLabel : copyLabel}\n >\n {isCopied ? <CheckSmallIcon /> : <CopyIcon />}\n </button>\n )}\n\n {/*\n Ekran okuyucu icin: ikon degisimi gorsel bir sinyal, duyulmuyor.\n `aria-live` yalnizca DEGISTIGINDE konusur.\n */}\n <span aria-live=\"polite\" className={styles.copy__srOnly}>\n {isCopied ? copiedAnnouncement : ''}\n </span>\n </span>\n );\n};\n\nexport default memo(CopyField) as typeof CopyField;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Ortada gösterilen metin (\"veya\"). */\n label?: string;\n className?: string;\n};\n\n/**\n * Ayırıcı çizgi.\n *\n * <p>Etiketli hâli `role=\"separator\"` taşımaz: metin içerdiğinde ekran okuyucu\n * onu ayırıcı değil içerik olarak okumalı (\"veya\").\n */\nconst Divider: FC<Props> = ({ label, className }) =>\n label ? (\n <div className={cx(styles.divider, styles['divider--labelled'], className)}>\n <span className={styles.divider__label}>{label}</span>\n </div>\n ) : (\n <hr className={cx(styles.divider, className)} />\n );\n\nexport default memo(Divider) as typeof Divider;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport HanuiLink from '../Link';\n\nimport styles from './index.module.scss';\n\ntype DirectoryProps = {\n children: ReactNode;\n className?: string;\n};\n\n/**\n * Dizin — harf veya konu başlıklı, gruplanmış bağlantı listesi.\n *\n * <h3>Neden ortak bir bileşen</h3>\n * Bir marka dizini ile bir kategori dizini aynı işi yapıyor: yüzlerce\n * bağlantıyı gruplayıp taranabilir kılmak. Ama iki container bunu ayrı ayrı\n * kurmuştu ve sonuç iki farklı sayfa oldu — birinde grup başlığı alt çizgili\n * 19 px, diğerinde çizgisiz; birinde satırlar ızgarada, diğerinde tek kolonda.\n *\n * <p>Ortak olan <em>görsel dilbilgisi</em>: grup başlığı + ızgara + satır\n * öğesi. O buraya taşındı; ne listelendiği çağırana kaldı.\n *\n * @example\n * <Directory>\n * <DirectoryGroup label=\"A\">\n * <DirectoryRow href=\"/marka/ate\" name=\"ATE\" media={<img … />} />\n * </DirectoryGroup>\n * </Directory>\n */\nconst Directory: FC<DirectoryProps> = ({ children, className }) => (\n <div className={cx(styles.directory, className)}>{children}</div>\n);\n\ntype DirectoryGroupProps = {\n /** Grup başlığı: harf (\"A\", \"0-9\") veya konu (\"Fren sistemi\"). */\n label: string;\n /**\n * Başlık kendisi bir hedefe götürüyorsa. Harf gruplarında verilmez — \"A\"\n * diye bir sayfa yok.\n */\n href?: string;\n /** Yönlendiriciye geçirilecek ek props. */\n linkProps?: HanuiLinkExtraProps;\n /** Başlığın sağında duran sayaç (\"14 alt kategori\"). */\n meta?: ReactNode;\n children: ReactNode;\n /** Çıpa hedefi: alfabe şeridinden atlamak için. */\n id?: string;\n};\n\n/**\n * Dizin grubu.\n *\n * <p>Başlık <strong>yapışkan</strong>: uzun bir listede kaydırırken hangi\n * harfte olduğunu görmek, listeyi yukarı sarıp kontrol etmekten iyi.\n */\nexport const DirectoryGroup: FC<DirectoryGroupProps> = memo(\n ({ label, href, linkProps, meta, children, id }) => (\n <section className={styles.group} id={id}>\n <header className={styles.group__header}>\n <h2 className={styles.group__label}>\n {href ? (\n <HanuiLink href={href} className={styles.group__link} {...linkProps}>\n {label}\n </HanuiLink>\n ) : (\n label\n )}\n </h2>\n {meta && <span className={styles.group__meta}>{meta}</span>}\n </header>\n\n <ul className={styles.group__list}>{children}</ul>\n </section>\n ),\n);\n\nDirectoryGroup.displayName = 'DirectoryGroup';\n\ntype DirectoryRowProps = {\n href: string;\n name: string;\n /** Logo, ikon veya baş harf madalyonu. Satırın solunda. */\n media?: ReactNode;\n /** Sağ uçta duran işaret: rozet, kayıt sayısı. */\n marker?: ReactNode;\n /** Yönlendiriciye geçirilecek ek props. */\n linkProps?: HanuiLinkExtraProps;\n className?: string;\n};\n\n/**\n * Dizin satırı — tek bir bağlantı.\n *\n * <p>Tüm satır tıklanabilir ve en az 44 px yüksekliğinde (WCAG 2.5.8):\n * yalnızca metnin tıklanabilir olduğu bir listede dokunmatik kullanıcılar\n * satırın boşluğuna basıp hiçbir şey olmadığını görüyordu.\n */\nexport const DirectoryRow: FC<DirectoryRowProps> = memo(\n ({ href, name, media, marker, linkProps, className }) => (\n <li>\n <HanuiLink href={href} className={cx(styles.row, className)} {...linkProps}>\n {media && <span className={styles.row__media}>{media}</span>}\n <span className={styles.row__name}>{name}</span>\n {marker && <span className={styles.row__marker}>{marker}</span>}\n </HanuiLink>\n </li>\n ),\n);\n\nDirectoryRow.displayName = 'DirectoryRow';\n\ntype DirectoryJumpProps = {\n /** Grup etiketleri; her biri kendi çıpasına bağlanır. */\n labels: string[];\n /** Çıpa kimliğini üretir; `DirectoryGroup id` ile aynı olmalı. */\n toId: (label: string) => string;\n /** Şeridin erişilebilir adı (\"Harfe göre atla\"). */\n label: string;\n};\n\n/**\n * Alfabe atlama şeridi.\n *\n * <p>Uzun bir listede \"V\" harfine ulaşmak için kaydırmak dakikalar alıyordu.\n * Şerit yatay kayar ve `#çıpa` bağlantıları taşır — JavaScript gerekmez,\n * tarayıcı kaydırmayı kendisi yapar ve bağlantı paylaşılabilir.\n *\n * <p>Bağlantılar HAM `<a>`: bunlar sayfa içi çıpa, gezinme değil. Bir\n * yönlendiriciden geçirmek aynı sayfayı yeniden çözümleyip kaydırmayı\n * kaçırıyordu.\n */\nexport const DirectoryJump: FC<DirectoryJumpProps> = memo(({ labels, toId, label }) => (\n <nav className={styles.jump} aria-label={label}>\n {labels.map(item => (\n <a key={item} href={`#${toId(item)}`} className={styles.jump__link}>\n {item}\n </a>\n ))}\n </nav>\n));\n\nDirectoryJump.displayName = 'DirectoryJump';\n\nexport default memo(Directory) as typeof Directory;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n title: string;\n description?: string;\n icon?: ReactNode;\n /** Kullanıcının buradan çıkabileceği eylem. */\n action?: ReactNode;\n /** İkincil eylem veya ipucu. */\n secondaryAction?: ReactNode;\n size?: 'sm' | 'md';\n className?: string;\n testId?: string;\n};\n\n/**\n * Boş durum.\n *\n * <h3>Neden her boş durum bir eylem taşır</h3>\n * \"Sonuç bulunamadı\" tek başına çıkmaz sokaktır. Kullanıcı o ekranda ne\n * yapacağını bilmeli: aramayı temizle, filtreyi kaldır, listeye dön. `action`\n * isteğe bağlı ama çağıran taraf onu vermezse kullanıcı tıkanır.\n *\n * <p>Bir listenin BOŞ olması ile YÜKLENEMEMESİ ayrı durumlardır: ağ hatasında\n * bu bileşen çizilmez, hata kendi mesajıyla gösterilir. İkisini birleştirmek\n * kullanıcıya \"kayıt kalmamış\" dedirtiyordu.\n */\nconst EmptyState: FC<Props> = ({\n title,\n description,\n icon,\n action,\n secondaryAction,\n size = 'md',\n className,\n testId,\n}) => (\n <div className={cx(styles.empty, styles[`empty--${size}`], className)} data-testid={testId}>\n {icon && <span className={styles.empty__icon}>{icon}</span>}\n <h3 className={styles.empty__title}>{title}</h3>\n {description && <p className={styles.empty__description}>{description}</p>}\n {(action || secondaryAction) && (\n <div className={styles.empty__actions}>\n {action}\n {secondaryAction}\n </div>\n )}\n </div>\n);\n\nexport default memo(EmptyState) as typeof EmptyState;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n title: string;\n /** Başlığın üstündeki küçük bağlam etiketi (\"HESABIM\", \"KATEGORİ\"). */\n eyebrow?: string;\n /** Bir cümlelik açıklama. 68ch ile sınırlı tutulur. */\n description?: ReactNode;\n /** Sağ tarafta duran eylemler. Dar ekranda başlığın altına düşer. */\n actions?: ReactNode;\n /** Başlık satırının üstündeki kırıntı yolu. */\n breadcrumb?: ReactNode;\n /**\n * Başlığın yanındaki sayaç (\"1.248 kayıt\"). Açıklamanın değil BAŞLIĞIN\n * hizasında durur; kullanıcı sayıyı başlıkla birlikte okur.\n */\n meta?: ReactNode;\n /** Başlık bloğunun altında duran ek içerik (filtre şeridi, sekmeler). */\n children?: ReactNode;\n /** `h1` sayfada bir kez bulunur; iç bölümler `h2` alır. */\n as?: 'h1' | 'h2';\n className?: string;\n testId?: string;\n};\n\n/**\n * Sayfa başlığı — her ekranın aynı giriş bloğu.\n *\n * <h3>Neden ortak bir bileşen</h3>\n * Önceden her container kendi başlığını kuruyordu: bir sayfada punto 29 px,\n * diğerinde 23 px; birinde açıklama başlığın altında, birinde yanında;\n * boşluklar 8 px ile 24 px arasında dolaşıyordu. Sayfalar arası geçiş \"başka\n * bir siteye geçtim\" hissi veriyordu. Bu bileşen o kararları tek yerde verir.\n *\n * <h3>Açıklama genişliği sınırlı</h3>\n * Başlık tam genişlikte akabilir ama açıklama 68ch'de durur: 1360 px\n * genişlikte akan bir açıklama satırında göz satır sonunda yerini kaybediyor.\n *\n * <h3>Eylemler `flex-end`</h3>\n * Düğmeler başlık bloğunun ALT kenarına hizalanır. `baseline` verildiğinde iki\n * satırlık başlıklarda düğme ilk satıra çekiliyordu.\n */\nconst PageHeader: FC<Props> = ({\n title,\n eyebrow,\n description,\n actions,\n breadcrumb,\n meta,\n children,\n as: Heading = 'h1',\n className,\n testId,\n}) => (\n <header className={cx(styles.header, className)} data-testid={testId}>\n {breadcrumb}\n\n <div className={styles.header__top}>\n <div className={styles.header__text}>\n {eyebrow && <span className={styles.header__eyebrow}>{eyebrow}</span>}\n\n <div className={styles.header__titleRow}>\n <Heading className={styles.header__title}>{title}</Heading>\n {meta && <span className={styles.header__meta}>{meta}</span>}\n </div>\n\n {description && <p className={styles.header__description}>{description}</p>}\n </div>\n\n {actions && <div className={styles.header__actions}>{actions}</div>}\n </div>\n\n {children}\n </header>\n);\n\nexport default memo(PageHeader) as typeof PageHeader;\n","import { type ElementType, type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n children: ReactNode;\n /** Panel başlığı. Verilmezse başlık şeridi hiç çizilmez. */\n title?: string;\n /** Başlık altındaki tek satırlık açıklama. */\n description?: ReactNode;\n /** Başlık şeridinin sağında duran eylemler. */\n actions?: ReactNode;\n /** Başlık şeridindeki ikon; başlığın solunda. */\n icon?: ReactNode;\n /** Gövde dolgusunu kaldırır: tablo ve tam genişlikte listeler için. */\n isFlush?: boolean;\n /** Gövde içindeki dikey aralık. */\n gap?: 'sm' | 'md' | 'lg';\n /** Dipte duran eylem şeridi (form kaydet, toplam). */\n footer?: ReactNode;\n as?: ElementType;\n className?: string;\n bodyClassName?: string;\n testId?: string;\n};\n\n/**\n * Panel — başlığı olan içerik kutusu.\n *\n * <h3>Neden bu bileşen var</h3>\n * Bir uygulamanın on bir ayarlar sayfası, on bir farklı kart kuruyordu:\n * birinde dolgu 16 px diğerinde 24 px, birinde başlık kartın içinde diğerinde\n * dışında, birinde `max-width: 560px` diğerinde tam genişlik. Aynı disiplinde\n * görünmeleri için kararların tek yerde verilmesi gerekiyordu.\n *\n * <h3>Genişlik paneli DEĞİL içeriği sınırlar</h3>\n * Panel her zaman kapsayıcısını doldurur. Form alanlarının okunabilir satır\n * uzunluğunu aşmaması gerekiyorsa {@link PanelForm} kullanılır — o iç ızgarayı\n * sınırlar, panelin kendisini daraltmaz. Önceden bir \"profil düzenle\" paneli\n * sayfanın üçte biri kadar kalıp yanındaki boşluğa bakıyordu; sorun formun\n * değil PANELİN daraltılmasıydı.\n *\n * @example\n * <Panel title=\"Profil bilgileri\" description=\"Fatura bu bilgilerle kesilir\">\n * <PanelForm>…alanlar…</PanelForm>\n * </Panel>\n */\nconst Panel: FC<Props> = ({\n children,\n title,\n description,\n actions,\n icon,\n isFlush,\n gap = 'md',\n footer,\n as: Tag = 'section',\n className,\n bodyClassName,\n testId,\n}) => (\n <Tag className={cx(styles.panel, className)} data-testid={testId}>\n {(title || actions) && (\n <div className={styles.panel__header}>\n <div className={styles.panel__heading}>\n {icon && <span className={styles.panel__icon}>{icon}</span>}\n\n <div className={styles.panel__headingText}>\n {title && <h2 className={styles.panel__title}>{title}</h2>}\n {description && <p className={styles.panel__description}>{description}</p>}\n </div>\n </div>\n\n {actions && <div className={styles.panel__actions}>{actions}</div>}\n </div>\n )}\n\n <div\n className={cx(\n styles.panel__body,\n styles[`panel__body--${gap}`],\n isFlush && styles['panel__body--flush'],\n bodyClassName,\n )}\n >\n {children}\n </div>\n\n {footer && <div className={styles.panel__footer}>{footer}</div>}\n </Tag>\n);\n\ntype PanelFormProps = {\n children: ReactNode;\n /** Sütun sayısı. `2` dar ekranda kendiliğinden tek sütuna düşer. */\n columns?: 1 | 2;\n className?: string;\n};\n\n/**\n * Panel içindeki form ızgarası.\n *\n * <p>Genişliği SINIRLI (`$measure-narrow`): girdi alanları okunabilir satır\n * uzunluğunun ötesine uzamamalı — 900 px genişliğinde bir metin kutusu\n * doldurulması zor görünür. Ama bu sınır PANELE değil ızgaraya uygulanır;\n * panel tam genişlikte kalır ve sayfa düzeni bozulmaz.\n */\nexport const PanelForm: FC<PanelFormProps> = memo(({ children, columns = 1, className }) => (\n <div className={cx(styles.form, styles[`form--${columns}`], className)}>{children}</div>\n));\n\nPanelForm.displayName = 'PanelForm';\n\ntype PanelRowProps = {\n children: ReactNode;\n className?: string;\n};\n\n/**\n * İki alanı yan yana koyan satır. Dar ekranda alt alta düşer.\n *\n * <p>`PanelForm columns={2}` tüm ızgarayı ikiye böler; bu yalnızca TEK bir\n * satırı böler (ad + soyad gibi).\n */\nexport const PanelRow: FC<PanelRowProps> = memo(({ children, className }) => (\n <div className={cx(styles.row, className)}>{children}</div>\n));\n\nPanelRow.displayName = 'PanelRow';\n\nexport default memo(Panel) as typeof Panel;\n","import { type FC, memo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** BİÇİMLENMİŞ tutar: \"1.299,90\". Bileşen hesap yapmaz. */\n value: string;\n /** Para birimi simgesi ya da kodu: \"₺\", \"$\", \"EUR\". */\n currency: string;\n /** Üstü çizili liste fiyatı; indirim varsa verilir (biçimlenmiş). */\n listValue?: string;\n /** İndirim oranı (tam sayı yüzde). */\n discountPercent?: number;\n /** İndirim rozetinin metnini üretir (\"%20\", \"-20%\"). */\n formatDiscount?: (percent: number) => string;\n size?: 'sm' | 'md' | 'lg' | 'xl';\n className?: string;\n testId?: string;\n};\n\n/**\n * Tutar gösterimi.\n *\n * <h3>Bileşen HESAP YAPMAZ</h3>\n * Tutar biçimlenmiş gelir. Kuruşu istemcide çevirmek kayan nokta hatası riski\n * taşır ve biçimlendirme iki yerde ayrışır: aynı ürün listede \"1.299,90\",\n * detayda \"1299.9\" çıkıyordu. İndirim oranı da dışarıdan gelir — burada\n * `(1 - fiyat/liste)` hesaplamak için biçimlenmiş metni sayıya çevirmek\n * gerekirdi ve o kırılgan bir iş.\n *\n * <h3>Tutar NÖTR kalır</h3>\n * Güncel tutar `$text`; üstü çizili eski tutar `$text-3`; indirim yüzdesi\n * küçük bir yeşil rozet. Kırmızı fiyat ucuz durur ve kırmızıyı \"olumsuz\"\n * anlamından koparır.\n */\nconst Price: FC<Props> = ({\n value,\n currency,\n listValue,\n discountPercent,\n formatDiscount = percent => `%${percent}`,\n size = 'md',\n className,\n testId,\n}) => (\n <span className={cx(styles.price, styles[`price--${size}`], className)} data-testid={testId}>\n <span className={styles.price__current}>\n {value}\n <span className={styles.price__currency}>{currency}</span>\n </span>\n\n {listValue && (\n <s className={styles.price__list}>\n {listValue}\n <span className={styles.price__currency}>{currency}</span>\n </s>\n )}\n\n {/* `isDefined` DEGIL acik karsilastirma: handy-utils'in koruyucusu\n `Exclude<any, …>` donuyor ve TypeScript'te daraltma uretmiyor. */}\n {discountPercent !== undefined && discountPercent > 0 && (\n <span className={styles.price__discount}>{formatDiscount(discountPercent)}</span>\n )}\n </span>\n);\n\nexport default memo(Price) as typeof Price;\n","import { type FC, memo } from 'react';\n\nimport { isDefined } from '@ahmetilhn/handy-utils';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { StarFillIcon, StarHalfIcon, StarIcon } from '../../icons';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** 0–5 arası puan. Yarım yıldız desteklenir. */\n value: number;\n /** Değerlendirme sayısı; verilirse yıldızların yanında gösterilir. */\n count?: number;\n /**\n * Ekran okuyucuya okunan metin — ZORUNLU.\n *\n * <p>Yıldızlar `aria-hidden`: beş ayrı ikonu tek tek duyurmak anlamsız.\n * Yerine bir cümle okunur (\"5 üzerinden 4,5 — 12 değerlendirme\") ve o cümle\n * hem dile hem sayı biçimine bağlı; kütüphane onu uyduramaz.\n */\n srLabel: string;\n size?: 'sm' | 'md';\n className?: string;\n testId?: string;\n};\n\n/**\n * Yıldız puanı — salt gösterim.\n *\n * <p>Ortalama sunucuda hesaplanır; burada yalnızca gösterilir. Puanı\n * istemcide hesaplamak, sayfalama yüzünden eksik veriyle yanlış ortalama\n * üretirdi.\n *\n * <p>Etkileşimli kardeşi {@link RatingInput}.\n */\nconst Rating: FC<Props> = ({ value, count, srLabel, size = 'sm', className, testId }) => {\n const rounded = Math.round(value * 2) / 2;\n\n return (\n <span className={cx(styles.rating, styles[`rating--${size}`], className)} data-testid={testId}>\n <span className={styles.rating__stars} aria-hidden>\n {Array.from({ length: 5 }, (_, index) => {\n const position = index + 1;\n if (rounded >= position) return <StarFillIcon key={index} />;\n if (rounded >= position - 0.5) return <StarHalfIcon key={index} />;\n return <StarIcon key={index} className={styles.rating__empty} />;\n })}\n </span>\n\n <span className={styles.rating__srOnly}>{srLabel}</span>\n\n {isDefined(count) && (\n <span className={styles.rating__count} aria-hidden>\n ({count})\n </span>\n )}\n </span>\n );\n};\n\nexport default memo(Rating) as typeof Rating;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n title: string;\n description?: string;\n /** Üstte gösterilen küçük büyük-harf etiket. */\n overline?: string;\n /** Sağda gösterilen eylem (\"Tümünü gör\"). */\n action?: ReactNode;\n as?: 'h1' | 'h2' | 'h3';\n size?: 'sm' | 'md' | 'lg';\n className?: string;\n testId?: string;\n};\n\n/**\n * Bölüm başlığı.\n *\n * <p>Başlık düzeyi (`as`) görsel boyuttan (`size`) <strong>ayrı</strong>:\n * sayfa hiyerarşisi anlamsal olmak zorunda ama görsel boyut bağlamla değişir.\n * İkisini birbirine bağlamak, doğru görünüm için yanlış başlık düzeyi seçmeye\n * zorlardı.\n */\nconst SectionHeader: FC<Props> = ({\n title,\n description,\n overline,\n action,\n as: Heading = 'h2',\n size = 'md',\n className,\n testId,\n}) => (\n <header className={cx(styles.header, styles[`header--${size}`], className)} data-testid={testId}>\n <div className={styles.header__text}>\n {overline && <span className={styles.header__overline}>{overline}</span>}\n <Heading className={styles.header__title}>{title}</Heading>\n {description && <p className={styles.header__description}>{description}</p>}\n </div>\n\n {action && <div className={styles.header__action}>{action}</div>}\n </header>\n);\n\nexport default memo(SectionHeader) as typeof SectionHeader;\n","import { type CSSProperties, type FC, memo } from 'react';\n\nimport { isNumber } from '@ahmetilhn/handy-utils';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /** Genişlik: sayı px, dize doğrudan CSS değeri. */\n width?: number | string;\n height?: number | string;\n /** Metin satırı görünümü: yuvarlatılmış, satır yüksekliğinde. */\n variant?: 'block' | 'text' | 'circle';\n /** Kaç satır çizilecek (`text` için). */\n lines?: number;\n className?: string;\n};\n\n/**\n * Yükleme iskeleti.\n *\n * <h3>Neden dönen çark yerine iskelet</h3>\n * İskelet gelecek içeriğin <em>şeklini</em> gösterir; kullanıcı ne beklediğini\n * bilir ve içerik geldiğinde yerleşim kaymaz (CLS). Dönen bir çark hem konumu\n * hem boyutu belirsiz bırakır.\n *\n * <p>`aria-hidden`: ekran okuyucuya \"yükleniyor\" bilgisini veren, iskeletin\n * kendisi değil onu saran bölgenin `aria-busy` özelliğidir.\n */\nconst Skeleton: FC<Props> = ({ width, height, variant = 'block', lines = 1, className }) => {\n const style: CSSProperties = {\n width: isNumber(width) ? `${width}px` : width,\n height: isNumber(height) ? `${height}px` : height,\n };\n\n if (variant === 'text' && lines > 1)\n return (\n <span className={cx(styles.group, className)} aria-hidden>\n {Array.from({ length: lines }, (_, index) => (\n <span\n key={index}\n className={cx(styles.skeleton, styles['skeleton--text'])}\n // Son satır kısa: gerçek paragraflar tam genişlikte bitmez.\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </span>\n );\n\n return (\n <span\n className={cx(styles.skeleton, styles[`skeleton--${variant}`], className)}\n style={style}\n aria-hidden\n />\n );\n};\n\nexport default memo(Skeleton) as typeof Skeleton;\n","'use client';\n\nimport { type FC, type KeyboardEvent, memo, type ReactNode, useId, useState } from 'react';\n\nimport { isDefined } from '@ahmetilhn/handy-utils';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\nexport type TabItem = {\n id: string;\n label: string;\n /** Etiketin yanında gösterilen sayı. */\n count?: number;\n /**\n * Sekmenin paneli.\n *\n * <p>Verilmezse bileşen yalnızca <strong>sekme çubuğu</strong> çizer ve\n * içeriği çağıran taraf yönetir. Bir formun üç kipi tek bir panelin içinde\n * yaşıyorsa üç ayrı panel yazmak aynı alanları üç kez tanımlamak olurdu.\n */\n content?: ReactNode;\n};\n\ntype Props = {\n items: TabItem[];\n /** Kontrolsüz kullanımda açılışta seçili sekme. */\n defaultTabId?: string;\n /**\n * Kontrollü kullanım: seçili sekme çağıranın durumunda.\n *\n * <p>`onChange` ile birlikte verilir. Kontrolsüz sürüm (yalnızca\n * `defaultTabId`) korunur — kendi durumunu tutması yeterli olan sekmelerin\n * dışarıdan yönetilmesi gereksiz.\n */\n activeId?: string;\n onChange?: (id: string) => void;\n /** Sekme çubuğunun erişilebilir adı. */\n ariaLabel?: string;\n className?: string;\n testId?: string;\n};\n\n/**\n * Sekmeler.\n *\n * <p>ARIA sekme kalıbı tam uygulanır: `role=\"tablist\"`, `aria-selected`,\n * `aria-controls` ve ok tuşlarıyla gezinme. Yalnızca görsel olarak sekme gibi\n * duran düğmeler, klavye kullanıcısı için gezinilemez bir yapı olurdu.\n *\n * <p>Seçili olmayan panel DOM'dan çıkarılır: gizli panellerdeki bağlantılar ve\n * girdiler sekme sırasına girmemeli.\n *\n * <h3>İki kullanım</h3>\n * <ul>\n * <li><b>Kontrolsüz + panelli</b> — `items[].content` verilir, bileşen\n * seçimi kendisi tutar.</li>\n * <li><b>Kontrollü + panelsiz</b> — `activeId` + `onChange` verilir,\n * `content` verilmez; bileşen yalnızca çubuğu çizer.</li>\n * </ul>\n */\nconst Tabs: FC<Props> = ({\n items,\n defaultTabId,\n activeId: controlledId,\n onChange,\n ariaLabel,\n className,\n testId,\n}) => {\n const baseId = useId();\n const [uncontrolledId, setUncontrolledId] = useState(defaultTabId ?? items[0]?.id);\n\n const isControlled = isDefined(controlledId);\n const activeId = isControlled ? controlledId : uncontrolledId;\n\n const activeIndex = items.findIndex(item => item.id === activeId);\n const active = items[activeIndex] ?? items[0];\n\n const select = (id: string) => {\n if (!isControlled) setUncontrolledId(id);\n onChange?.(id);\n };\n\n /** Ok tuşlarıyla sekme değiştirme; başta/sonda döner. */\n const handleKeyDown = (event: KeyboardEvent) => {\n const offset = event.key === 'ArrowRight' ? 1 : event.key === 'ArrowLeft' ? -1 : 0;\n if (offset === 0) return;\n\n event.preventDefault();\n const next = (activeIndex + offset + items.length) % items.length;\n select(items[next].id);\n document.getElementById(`${baseId}-tab-${items[next].id}`)?.focus();\n };\n\n if (items.length === 0) return null;\n\n /*\n * Panelsiz kullanimda `aria-controls` VERILMEZ: var olmayan bir kimligi\n * isaret etmek ekran okuyucuda kirik bir bag uretir.\n *\n * Kontrol VARLIK uzerinden: `content` bir dize ya da sayi da olabilir ve\n * `undefined`/`null` disindaki her sey bir panel demek.\n */\n const hasPanel = isDefined(active?.content);\n\n return (\n <div className={cx(styles.tabs, className)} data-testid={testId}>\n <div\n className={styles.tabs__list}\n role=\"tablist\"\n aria-label={ariaLabel}\n onKeyDown={handleKeyDown}\n >\n {items.map(item => {\n const isActive = item.id === active.id;\n\n return (\n <button\n key={item.id}\n id={`${baseId}-tab-${item.id}`}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={hasPanel ? `${baseId}-panel-${item.id}` : undefined}\n // Yalnızca seçili sekme sekme sırasında; gezinme ok tuşlarıyla.\n tabIndex={isActive ? 0 : -1}\n className={cx(styles.tabs__tab, isActive && styles['tabs__tab--active'])}\n onClick={() => select(item.id)}\n >\n {item.label}\n {isDefined(item.count) && <span className={styles.tabs__count}>{item.count}</span>}\n </button>\n );\n })}\n </div>\n\n {hasPanel && (\n <div\n id={`${baseId}-panel-${active.id}`}\n role=\"tabpanel\"\n aria-labelledby={`${baseId}-tab-${active.id}`}\n className={styles.tabs__panel}\n tabIndex={0}\n >\n {active.content}\n </div>\n )}\n </div>\n );\n};\n\nexport default memo(Tabs) as typeof Tabs;\n","import { memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport HanuiLink from '../Link';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n label: string;\n /** İkon DIŞARIDAN gelir: hangi ikonun hangi konuya ait olduğu uygulamanın bilgisi. */\n icon: ReactNode;\n href: string;\n /** Etiketin altında gösterilen ikincil satır (\"1.248 kayıt\"). */\n meta?: ReactNode;\n isActive?: boolean;\n /** Yönlendiriciye geçirilecek ek props. */\n linkProps?: HanuiLinkExtraProps;\n className?: string;\n testId?: string;\n};\n\n/**\n * Karo — ikon madalyonu + etiket.\n *\n * <h3>Neden ikon, neden yuvarlak madalyon</h3>\n * Ana giriş noktaları metin listesi olarak verildiğinde kullanıcı satır satır\n * okuyor. İkon, aranan öğeyi <em>okumadan</em> bulmayı sağlar; madalyon ise\n * ikona sabit bir kutu verir — farklı ikonların doğal genişlikleri karoları\n * düzensiz hizalıyordu.\n *\n * <h3>Karonun tamamı tıklanabilir</h3>\n * Bağlantı yalnızca etiketi değil karonun tümünü kaplar. Küçük bir metin\n * bağlantısını hedeflemek, özellikle dokunmatik ekranda gereksiz bir hassasiyet\n * talebiydi.\n *\n * <h3>`meta` neden sayı değil `ReactNode`</h3>\n * \"1.248 ürün\" cümlesi hem sayı biçimine hem dile bağlı. Bileşen içinde\n * `toLocaleString` çağırmak, o kararı kütüphanenin varsayımına bağlıyordu.\n */\nconst Tile = ({ label, icon, href, meta, isActive, linkProps, className, testId }: Props) => (\n <HanuiLink\n href={href}\n className={cx(styles.tile, isActive && styles['tile--active'], className)}\n aria-current={isActive ? 'page' : undefined}\n data-testid={testId}\n {...linkProps}\n >\n <span className={styles.tile__medallion} aria-hidden>\n {icon}\n </span>\n\n <span className={styles.tile__label}>{label}</span>\n\n {meta && <span className={styles.tile__meta}>{meta}</span>}\n </HanuiLink>\n);\n\nexport default memo(Tile) as typeof Tile;\n","'use client';\n\nimport {\n memo,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n} from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { preventAutoKeyboard } from '../../helpers/focus.helper';\nimport { XIcon } from '../../icons';\nimport IconButton from '../IconButton';\n\nimport styles from './index.module.scss';\n\nexport type ModalTone = 'neutral' | 'danger' | 'warning' | 'success' | 'info';\n\ntype Props = {\n isOpen: boolean;\n onClose: () => void;\n title: string;\n /** Kapatma düğmesinin erişilebilir adı (\"Kapat\", \"Close\"). */\n closeLabel: string;\n children?: ReactNode;\n /**\n * Başlığın altındaki bir cümlelik açıklama.\n *\n * <p>`aria-describedby` ile pencereye bağlanır: ekran okuyucu pencere\n * açıldığında başlıkla birlikte bunu da okur. Gövdeye paragraf olarak\n * yazıldığında duyurulmuyordu.\n */\n description?: ReactNode;\n /** Altta duran eylemler. Sağa yaslanır; dar ekranda tam genişliğe yayılır. */\n footer?: ReactNode;\n /** Başlığın solunda duran ikon madalyonu; `tone` rengini alır. */\n icon?: ReactNode;\n /** İkon madalyonunun tonu. */\n tone?: ModalTone;\n size?: 'sm' | 'md' | 'lg';\n /**\n * `false` iken arka plana tıklama, Escape ve kapatma düğmesi kapatmaz.\n *\n * <p>Yalnızca <strong>sürmekte olan</strong> bir işlem için: silme isteği\n * gönderilmişken pencerenin kapanması, kullanıcıya işlem iptal edilmiş gibi\n * görünüyordu.\n */\n isDismissable?: boolean;\n className?: string;\n testId?: string;\n};\n\n/**\n * Kip pencere (modal).\n *\n * <h3>Yerel `<dialog>` + `showModal()`</h3>\n * Odak tuzağı, Escape ile kapanma, arka planın etkileşime kapanması ve\n * `aria-modal` semantiği tarayıcıdan gelir. Bunları `<div>` üzerine elle\n * kurmak yüzlerce satır ve kaçınılmaz olarak eksik bir odak yönetimi demek.\n *\n * <h3>Neden `open` özniteliği değil `showModal()`</h3>\n * `<dialog open>` pencereyi <em>kipsiz</em> açar: arka plan tıklanabilir kalır\n * ve odak tuzağı çalışmaz. Kipli davranışın tek yolu yöntemi çağırmak.\n *\n * <h3>Arka planın kaydırılması ayrıca engellenir</h3>\n * `showModal()` arka planı <em>etkileşime</em> kapatır ama tarayıcıların bir\n * kısmında sayfa hâlâ kaydırılabiliyor: kullanıcı pencereyi kaydırdığını\n * sanırken arkadaki listeyi kaydırıyordu. `<body>` kilitlenir.\n *\n * <h3>Mobilde alt sayfaya düşer</h3>\n * Dar ekranda ortalanmış bir pencere, klavye açıldığında yukarı sıkışıyor ve\n * dip düğmeleri klavyenin altında kalıyordu. Alt sayfa baş parmağın\n * erişebildiği yerde durur.\n */\nconst Modal = ({\n isOpen,\n onClose,\n title,\n closeLabel,\n children,\n description,\n footer,\n icon,\n tone = 'neutral',\n size = 'md',\n isDismissable = true,\n className,\n testId,\n}: Props) => {\n const dialogRef = useRef<HTMLDialogElement>(null);\n const titleId = useId();\n const descriptionId = useId();\n\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n if (isOpen && !dialog.open) {\n dialog.showModal();\n /* Odak metin alanina dusmesin: pencere `isDismissable={false}` iken\n kapatma dugmesi cizilmiyor ve ilk odaklanabilir oge dogrudan\n govdedeki alan oluyor — form pencerelerinde telefonda klavye\n kendiliginden aciliyordu (bkz. `helpers/focus.helper`). */\n preventAutoKeyboard(dialog);\n }\n if (!isOpen && dialog.open) dialog.close();\n }, [isOpen]);\n\n /*\n * Arka plan kaydirmasi kilitlenir. `showModal()` arka plani etkilesime\n * kapatir ama kaydirmayi her tarayicida engellemiyor: kullanici pencereyi\n * kaydirdigini sanirken arkadaki listeyi kaydiriyordu.\n */\n useEffect(() => {\n if (!isOpen) return;\n\n const previous = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = previous;\n };\n }, [isOpen]);\n\n /*\n * Escape'i tarayici isliyor ama React durumu bundan haberdar olmuyor;\n * `cancel` olayi yakalanmazsa pencere kapanip `isOpen` true kaliyor ve bir\n * daha acilamiyordu.\n */\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n const handleCancel = (event: Event) => {\n // Kapanmaya izin verilmiyorsa Escape de kapatmaz.\n event.preventDefault();\n if (isDismissable) onClose();\n };\n\n dialog.addEventListener('cancel', handleCancel);\n return () => dialog.removeEventListener('cancel', handleCancel);\n }, [onClose, isDismissable]);\n\n const handleBackdropClick = useCallback(\n (event: MouseEvent<HTMLDialogElement>) => {\n if (!isDismissable) return;\n // Hedef dialog'un KENDISI ise arka plana tiklanmistir; panel degil.\n if (event.target === dialogRef.current) onClose();\n },\n [isDismissable, onClose],\n );\n\n return (\n <dialog\n ref={dialogRef}\n className={cx(styles.modal, styles[`modal--${size}`], className)}\n aria-labelledby={titleId}\n aria-describedby={description ? descriptionId : undefined}\n data-testid={testId}\n onClick={handleBackdropClick}\n >\n <div className={styles.modal__panel}>\n <header className={styles.modal__header}>\n {icon && (\n <span className={cx(styles.modal__icon, styles[`modal__icon--${tone}`])}>{icon}</span>\n )}\n\n <div className={styles.modal__heading}>\n <h2 id={titleId} className={styles.modal__title}>\n {title}\n </h2>\n {description && (\n <p id={descriptionId} className={styles.modal__description}>\n {description}\n </p>\n )}\n </div>\n\n {isDismissable && (\n <IconButton\n icon={<XIcon />}\n label={closeLabel}\n variant=\"ghost\"\n size=\"sm\"\n className={styles.modal__close}\n onClick={onClose}\n />\n )}\n </header>\n\n {/*\n Gövde yalnızca içerik VARSA çizilir: onay pencerelerinin çoğunda soru\n başlıkta ve açıklamada duruyor, gövde boş kalıyor ve boş bir kutu\n 40 px'lik bir boşluk bırakıyordu.\n */}\n {children && <div className={styles.modal__body}>{children}</div>}\n\n {footer && <footer className={styles.modal__footer}>{footer}</footer>}\n </div>\n </dialog>\n );\n};\n\nexport default memo(Modal) as typeof Modal;\n","'use client';\n\nimport { type FC, memo, type ReactNode, useState } from 'react';\n\nimport UISize from '../../enums/ui-size.enum';\nimport UIVariant from '../../enums/ui-variant.enum';\nimport { ExclamationTriangleFillIcon, QuestionCircleFillIcon, TrashFillIcon } from '../../icons';\nimport Button from '../Button';\nimport Modal, { type ModalTone } from '../Modal';\n\nexport type ConfirmKind = 'destructive' | 'warning' | 'neutral';\n\nconst KIND_ICON: Record<ConfirmKind, ReactNode> = {\n destructive: <TrashFillIcon />,\n warning: <ExclamationTriangleFillIcon />,\n neutral: <QuestionCircleFillIcon />,\n};\n\nconst KIND_TONE: Record<ConfirmKind, ModalTone> = {\n destructive: 'danger',\n warning: 'warning',\n neutral: 'info',\n};\n\nconst KIND_VARIANT: Record<ConfirmKind, UIVariant> = {\n destructive: UIVariant.DANGER,\n warning: UIVariant.PRIMARY,\n neutral: UIVariant.PRIMARY,\n};\n\ntype Props = {\n isOpen: boolean;\n onClose: () => void;\n /**\n * Onaylandığında çalışır. `Promise` dönerse düğme beklerken yükleme\n * durumuna geçer ve pencere <strong>kapanmaz</strong>.\n *\n * <p>İşlem başarılıysa pencereyi kapatmak çağıranın işi: hata durumunda\n * pencerenin açık kalması gerekiyor ki kullanıcı tekrar deneyebilsin.\n */\n onConfirm: () => void | Promise<void>;\n /** Soru cümlesi. Eylem odaklı yazılır: \"…silinsin mi?\". */\n title: string;\n /** Sonucu açıklar: neyin geri alınamaz olduğu burada yazılır. */\n description?: ReactNode;\n /** Onay düğmesinin etiketi. Eylemi TEKRARLAR: \"Sil\", \"İptal et\". */\n confirmLabel: string;\n cancelLabel: string;\n /** Kapatma düğmesinin erişilebilir adı. */\n closeLabel: string;\n kind?: ConfirmKind;\n /** Ek bağlam: silinecek kaydın özeti, uyarı kutusu. */\n children?: ReactNode;\n};\n\n/**\n * Onay penceresi.\n *\n * <h3>Neden `window.confirm()` yerine bu</h3>\n * Yerel `confirm()`in dört sorunu var:\n * <ul>\n * <li>Görünümü işletim sisteminin — sitenin diliyle hiç ilgisi yok, üstünde\n * tarayıcının alan adı yazıyor.</li>\n * <li><strong>Ana iş parçacığını kilitler.</strong></li>\n * <li>Yıkıcı eylemi vurgulayamaz: \"Tamam\" ile \"İptal\" aynı ağırlıkta ve\n * hangisinin sildiğini yalnızca metinden anlıyorsun.</li>\n * <li>İstek sürerken geri bildirim veremez; kullanıcı silme düğmesine ikinci\n * kez basıyordu.</li>\n * </ul>\n *\n * <h3>Yükleme durumu pencerede kalır</h3>\n * Onaya basıldığında pencere hemen kapanmaz: düğme yükleniyor durumuna geçer\n * ve pencere kapanmaz hâle gelir (`isDismissable={false}`). İstek bittiğinde\n * kapatma kararı çağırana ait — hata varsa pencere açık kalmalı ki kullanıcı\n * tekrar deneyebilsin.\n *\n * @example\n * const [target, setTarget] = useState<Address | null>(null);\n *\n * <ConfirmDialog\n * isOpen={target !== null}\n * onClose={() => setTarget(null)}\n * kind=\"destructive\"\n * title=\"Adres silinsin mi?\"\n * description=\"Bu işlem geri alınamaz.\"\n * confirmLabel=\"Sil\"\n * cancelLabel=\"Vazgeç\"\n * closeLabel=\"Kapat\"\n * onConfirm={async () => {\n * await remove(target!.id);\n * setTarget(null);\n * }}\n * />\n */\nconst ConfirmDialog: FC<Props> = ({\n isOpen,\n onClose,\n onConfirm,\n title,\n description,\n confirmLabel,\n cancelLabel,\n closeLabel,\n kind = 'neutral',\n children,\n}) => {\n const [isRunning, setIsRunning] = useState(false);\n\n const handleConfirm = async () => {\n setIsRunning(true);\n try {\n await onConfirm();\n } finally {\n /*\n * `finally`: istek hata verse de yukleme durumu birakilir. Aksi halde\n * dugme sonsuza kadar donuyor ve kullanici tekrar deneyemiyordu.\n * Pencereyi KAPATMAK cagirana ait — hata varsa acik kalmali.\n */\n setIsRunning(false);\n }\n };\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n closeLabel={closeLabel}\n description={description}\n icon={KIND_ICON[kind]}\n tone={KIND_TONE[kind]}\n size=\"sm\"\n // Islem surerken kapanmaz: kapanma, islem iptal edilmis gibi gorunuyordu.\n isDismissable={!isRunning}\n footer={\n <>\n {/*\n \"Vazgec\" JSX'te ONCE: klavyeyle sekme sirasi soldan saga mantikli\n olmali. Ekranda mobilde `column-reverse` ile alta duser.\n */}\n <Button\n variant={UIVariant.SECONDARY}\n size={UISize.MEDIUM}\n onClick={onClose}\n disabled={isRunning}\n >\n {cancelLabel}\n </Button>\n <Button\n variant={KIND_VARIANT[kind]}\n size={UISize.MEDIUM}\n onClick={handleConfirm}\n isLoading={isRunning}\n >\n {confirmLabel}\n </Button>\n </>\n }\n >\n {children}\n </Modal>\n );\n};\n\nexport default memo(ConfirmDialog) as typeof ConfirmDialog;\n","'use client';\n\nimport { type FC, memo, type ReactNode, useEffect, useId, useRef, useState } from 'react';\n\nimport UISize from '../../enums/ui-size.enum';\nimport UIVariant from '../../enums/ui-variant.enum';\nimport Button from '../Button';\nimport Field, { type FieldChildProps } from '../Field';\nimport Input from '../Input';\nimport Modal from '../Modal';\nimport Textarea from '../Textarea';\n\nimport styles from './index.module.scss';\n\ntype BaseProps = {\n isOpen: boolean;\n /** Vazgeçme ve perde/Escape kapanışı. Başarı kapanışını bileşen kendisi yapar. */\n onClose: () => void;\n /**\n * Girilen değerle çalışır (değer kırpılmış gönderilir). Reddederse pencere\n * AÇIK kalır ve metin korunur; hata bildirimi çağıranın işi — bildirimi\n * gösterip hatayı yeniden fırlatın ya da hiç yakalamayın.\n */\n onSubmit: (value: string) => void | Promise<void>;\n title: string;\n /** Girdi alanının etiketi. */\n label: string;\n submitLabel: string;\n cancelLabel: string;\n /** Kapatma düğmesinin erişilebilir adı. */\n closeLabel: string;\n /** Başlığın altındaki bir cümlelik bağlam. */\n description?: ReactNode;\n hint?: string;\n placeholder?: string;\n defaultValue?: string;\n /**\n * `text` tek satır, `multiline` gerekçe gibi uzun metin, `number` adet/fark\n * gibi sayılar. Değer her durumda dize döner; ayrıştırmak çağıranın işi\n * (bir stok farkı `-5` gibi işaretli olabiliyor).\n */\n inputMode?: 'text' | 'multiline' | 'number';\n maxLength?: number;\n rows?: number;\n};\n\n/** Zorunluluk işareti ve ekran okuyucu karşılığı birlikte (bkz. {@link Field}). */\ntype RequiredProps =\n { isRequired: true; requiredLabel: string } | { isRequired?: false; requiredLabel?: never };\n\ntype Props = BaseProps & RequiredProps;\n\n/**\n * Metin isteyen pencere — `window.prompt()` yerine.\n *\n * <h3>Neden</h3>\n * Tarayıcı istemi tek satırlık, biçimlenemiyor, ana iş parçacığını\n * kilitliyor ve bazı tarayıcılarda sayfayı engelliyor. Bu bileşen aynı işi\n * `Modal` + `Field` + girdi ile yapar ve pencere kapanma kuralını\n * (aşağıda) getirir.\n *\n * <h3>Pencere yalnızca BAŞARIDA kapanır</h3>\n * `onSubmit` reddederse pencere açık kalır ve yazılan metin korunur — istek\n * patlarsa kullanıcının yazdığı gerekçe geri dönüşsüz silinmemeli. Değer\n * yalnızca pencere <em>yeniden açılırken</em> `defaultValue`dan tazelenir.\n *\n * <h3>Enter gönderir</h3>\n * Girdi bir `<form>` içinde; dip düğmesi `form` özniteliğiyle ona bağlanır\n * (`Modal` dip şeridi formun dışında çizer). `multiline` kipinde Enter satır\n * başı yapar, gönderme düğmeden.\n */\nconst PromptDialog: FC<Props> = ({\n isOpen,\n onClose,\n onSubmit,\n title,\n label,\n submitLabel,\n cancelLabel,\n closeLabel,\n description,\n hint,\n placeholder,\n defaultValue = '',\n isRequired,\n requiredLabel,\n inputMode = 'text',\n maxLength,\n rows = 4,\n}) => {\n const formId = useId();\n const [value, setValue] = useState(defaultValue);\n const [isBusy, setIsBusy] = useState(false);\n\n /*\n * Deger yalnizca ACILIS kenarinda tazelenir. `isOpen`'a bagli duz bir etki,\n * pencere acikken gelen her ust render'da yazilani ezebilirdi; hatada acik\n * kalan penceredeki metin de korunmali.\n */\n const wasOpenRef = useRef(false);\n useEffect(() => {\n if (isOpen && !wasOpenRef.current) setValue(defaultValue);\n wasOpenRef.current = isOpen;\n }, [isOpen, defaultValue]);\n\n const trimmed = value.trim();\n const isSubmitDisabled = Boolean(isRequired) && trimmed === '';\n\n /** Girdi, `Field`in urettigi erisilebilirlik baglariyla cizilir. */\n const renderControl = (props: FieldChildProps) =>\n inputMode === 'multiline' ? (\n <Textarea\n {...props}\n value={value}\n onChange={event => setValue(event.target.value)}\n placeholder={placeholder}\n maxLength={maxLength}\n rows={rows}\n />\n ) : (\n <Input\n {...props}\n type={inputMode === 'number' ? 'number' : 'text'}\n value={value}\n onChange={event => setValue(event.target.value)}\n placeholder={placeholder}\n maxLength={maxLength}\n />\n );\n\n const handleSubmit = async () => {\n if (isSubmitDisabled || isBusy) return;\n\n setIsBusy(true);\n try {\n await onSubmit(trimmed);\n // Yalnizca basarida: hata durumunda pencere acik, metin yerinde kalir.\n onClose();\n } catch {\n // Bildirim cagiranin isi; burada yalnizca pencere acik tutulur.\n } finally {\n setIsBusy(false);\n }\n };\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n closeLabel={closeLabel}\n description={description}\n size=\"sm\"\n // Istek surerken kapanmaz: kapanis \"islem iptal oldu\" gibi gorunuyordu.\n isDismissable={!isBusy}\n footer={\n <>\n <Button\n variant={UIVariant.SECONDARY}\n size={UISize.MEDIUM}\n onClick={onClose}\n disabled={isBusy}\n >\n {cancelLabel}\n </Button>\n <Button\n type=\"submit\"\n form={formId}\n variant={UIVariant.PRIMARY}\n size={UISize.MEDIUM}\n disabled={isSubmitDisabled}\n isLoading={isBusy}\n >\n {submitLabel}\n </Button>\n </>\n }\n >\n <form\n id={formId}\n className={styles.form}\n onSubmit={event => {\n event.preventDefault();\n handleSubmit();\n }}\n >\n {/*\n `Field` iki ayri kolda ciziliyor, kosullu yayilimla (`{...(cond ? … )}`)\n degil: `isRequired`/`requiredLabel` ikilisi bir ayrik birlesim\n (discriminated union) ve kosullu bir nesne yayilimi o birlesimin\n hangi koluna dustugunu TypeScript'e anlatamiyor.\n */}\n {isRequired ? (\n <Field label={label} hint={hint} isRequired requiredLabel={requiredLabel}>\n {renderControl}\n </Field>\n ) : (\n <Field label={label} hint={hint}>\n {renderControl}\n </Field>\n )}\n </form>\n </Modal>\n );\n};\n\nexport default memo(PromptDialog) as typeof PromptDialog;\n","import { type FC, type HTMLAttributes, memo, type TableHTMLAttributes } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype ScrollerProps = HTMLAttributes<HTMLDivElement> & {\n /**\n * Çerçeve (hairline + yarıçap + yüzey). Gömülü tablolarda kapatılır: orada\n * tablo zaten bir kartın içinde ve ikinci bir çerçeve kutu içinde kutu\n * görünüyordu.\n */\n hasFrame?: boolean;\n};\n\n/**\n * Tablo kaydırma kutusu — \"tablo kendi kutusunda kayar, sayfa asla yatay\n * kaymaz\" kuralının tek uygulaması.\n *\n * <p>Yatay kaydırma yalnızca BİLEREK kurulur: geniş tablo bu kutunun içinde\n * kayar; `min-width: 0` + `align-self: stretch` kutunun esnek bir kapsayıcıda\n * kendisinin taşmasını engeller. Üç tablonun üç ayrı elle kurulmuş (ya da hiç\n * kurulmamış) kaydırma stratejisi vardı; stratejisi olmayan tabloda monospace\n * değerler 360 px'te sayfanın kendisini yatay kaydırıyordu.\n *\n * <p>Kaydırma çubuğu TEMALI (`custom-scrollbar`): işletim sisteminin açık\n * çubuğu koyu temada tablonun altında parlak bir şerit bırakıyordu.\n */\nexport const TableScroller: FC<ScrollerProps> = memo(\n ({ hasFrame = true, className, children, ...rest }) => (\n <div\n className={cx(styles.scroller, hasFrame && styles['scroller--frame'], className)}\n {...rest}\n >\n {children}\n </div>\n ),\n);\n\nTableScroller.displayName = 'TableScroller';\n\ntype Props = TableHTMLAttributes<HTMLTableElement> &\n Partial<{\n /**\n * Hücre dolgusu. Tablolar aynı iskeleti paylaşır ama yoğunlukları içeriğe\n * göre değişir: yüzlerce satırlık bir liste sıkı, karşılaştırma matrisi\n * ferah durur.\n */\n density: 'compact' | 'regular' | 'spacious';\n /**\n * Başlık satırı `$surface-2` zeminle kutunun içinde YAPIŞKAN kalır.\n * Zemin zorunlu: saydam başlığın arkasından kayan satırlar geçiyordu.\n * `top: 0` doğru olan — referans üst bant değil, tablonun kendi kaydırma\n * kutusu.\n */\n hasStickyHead: boolean;\n /** Satır hover zemini: çok sütunlu tabloda göz satırını kaybediyor. */\n hasRowHover: boolean;\n }>;\n\n/**\n * Temel tablo — hairline satır ayrımı, `$surface-2` başlık, yoğunluk ölçeği.\n *\n * <p>Görsel kararlar (hangi hücre monospace, hangi sütun sabit) çağıranın\n * modülünde kalır; teknik değer hücresi `@include technical-text` ile\n * yazılır. Bileşen yalnızca üç tabloda üçe ayrışmış iskelet kurallarını tek\n * yerde toplar.\n *\n * <p>Operasyon ekranlarının durum satırlı (yükleniyor/hata/boş) sürümü için\n * {@link DataTable}.\n */\nconst Table: FC<Props> = ({\n density = 'regular',\n hasStickyHead,\n hasRowHover,\n className,\n children,\n ...rest\n}) => (\n <table\n className={cx(\n styles.table,\n styles[`table--${density}`],\n hasStickyHead && styles['table--sticky-head'],\n hasRowHover && styles['table--row-hover'],\n className,\n )}\n {...rest}\n >\n {children}\n </table>\n);\n\nexport default memo(Table) as typeof Table;\n","import { Children, type FC, type HTMLAttributes, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport { ExclamationCircleIcon } from '../../icons';\n\nimport styles from './index.module.scss';\n\nexport type DataTableColumn = {\n /** Sütun kimliği (React key). */\n key: string;\n /** Başlık hücresinin içeriği. Toplu seçim kutusu gibi öğeler de girebilir. */\n label?: ReactNode;\n /**\n * Görsel başlığı olmayan sütunun erişilebilir adı (eylem sütunu gibi).\n * Boş bir `<th>` ekran okuyucuda adsız bir sütun bırakıyordu.\n */\n srLabel?: string;\n /**\n * Sıralanabilir sütunun yönü (`aria-sort`). Sıralama düğmesi `label` içinde\n * yaşar; yön bilgisi ekran okuyucu için başlık hücresine yazılır.\n */\n ariaSort?: 'ascending' | 'descending';\n className?: string;\n};\n\ntype Props = {\n columns: DataTableColumn[];\n /**\n * Gövde satırları (`<tr>`). Ekranların özel hücreleri, bağlantıları ve satır\n * tintleri burada yaşar; tablo yalnızca kabuğu ve durum satırlarını\n * üstlenir. Uyarı tinti için {@link DataTableRow}.\n */\n children?: ReactNode;\n /** Satır yokken gösterilen metin. */\n emptyMessage: string;\n /** Yükleme sürerken satırların yerine gösterilen metin. */\n loadingMessage: string;\n isLoading?: boolean;\n /**\n * Liste ÇEKİLEMEDİ. <strong>\"Yüklenemedi\" ile \"boş\" ayrı durumlardır</strong>:\n * hata verilmişken boş mesajı asla çizilmez — ağ hatasını \"kayıt kalmamış\"\n * diye okutmak kullanıcıya yanlış karar verdirir. Hatayı tablonun dışında\n * (`Alert`) gösteren ekran bu prop'u geçmez.\n */\n error?: string | null;\n /**\n * Gövde `100dvh - <bant>` ile sınırlanır ve başlık satırı kendi kaydırma\n * alanına yapışır. Sınırsız yükseklikte `position: sticky` HİÇ çalışmıyordu:\n * `overflow` alanı ekrandan uzun olunca başlık sayfayla birlikte yukarı çıkıp\n * gidiyordu.\n */\n hasViewportCap?: boolean;\n className?: string;\n testId?: string;\n};\n\n/**\n * Operasyon veri tablosu — durum satırlı tablo sözleşmesi.\n *\n * <h3>Neden bir bileşen</h3>\n * On iki ekranda on bir ham tablo ve altı kaydırma sarmalayıcısı kopyası\n * vardı; üçü farklı davranıyordu (kimi dikey kaymıyor, kiminin başlığı\n * yapışmıyor). Kabuk (yüzey + hairline + `overflow: auto`), tablo görünümü ve\n * üç durum satırı (yükleniyor / hata / boş) artık tek yerde; `colSpan` sütun\n * sayısından kendiliğinden hesaplanır — elle yazılan `colSpan={8}` bir sütun\n * eklenince sessizce yanlış kalıyordu.\n *\n * <h3>Durum öncelik sırası</h3>\n * `error` > `isLoading` > boş > satırlar. Hata varken yükleme veya boş\n * mesajı gösterilmez; yüklenirken bayat satır çizilmez.\n */\nconst DataTable: FC<Props> = ({\n columns,\n children,\n isLoading,\n error,\n emptyMessage,\n loadingMessage,\n hasViewportCap,\n className,\n testId,\n}) => {\n /*\n * Bosluk karari satir SAYISINDAN verilir; cagiranin ayrica `isEmpty` gecmesi\n * gerekmez. Satirlar tek bir Fragment icinde verilirse sayi 1 gorunur —\n * satirlari dogrudan (ya da dizi olarak) verin.\n */\n const rowCount = Children.count(children);\n\n const renderStateRow = (content: ReactNode, modifier?: 'error') => (\n <tr>\n <td\n colSpan={columns.length}\n className={cx(styles.state, modifier && styles[`state--${modifier}`])}\n >\n {content}\n </td>\n </tr>\n );\n\n return (\n <div\n className={cx(styles.wrapper, hasViewportCap && styles['wrapper--capped'], className)}\n data-testid={testId}\n >\n <table className={styles.table}>\n <thead>\n <tr>\n {columns.map(column => (\n <th\n key={column.key}\n scope=\"col\"\n aria-label={column.srLabel}\n aria-sort={column.ariaSort}\n className={column.className}\n >\n {column.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {error\n ? renderStateRow(\n <span role=\"alert\" className={styles.state__message}>\n <ExclamationCircleIcon />\n {error}\n </span>,\n 'error',\n )\n : isLoading\n ? renderStateRow(loadingMessage)\n : rowCount === 0\n ? renderStateRow(emptyMessage)\n : children}\n </tbody>\n </table>\n </div>\n );\n};\n\ntype RowProps = HTMLAttributes<HTMLTableRowElement> & {\n children: ReactNode;\n /**\n * Satır dikkat bekleyen iş taşıyor (kritik stok, karar bekleyen talep).\n *\n * <p>TEK desen: tint zemin + ilk hücrede sol kenar işareti. Önceden iki\n * uygulama vardı — yalnız düz uyarı zemini ve zemin + sol iç gölge. Zemin\n * tek başına yetmiyordu: hover vurgusu tinti ezince satırın \"iş bekliyor\"\n * bilgisi kayboluyordu ve renk tek başına zaten anlam taşıyamaz (WCAG\n * 1.4.1) — sol işaret hover'da da yerinde kalır.\n */\n isWarning?: boolean;\n};\n\nexport const DataTableRow: FC<RowProps> = memo(({ isWarning, className, children, ...rest }) => (\n <tr className={cx(isWarning && styles['row--warning'], className)} {...rest}>\n {children}\n </tr>\n));\n\nDataTableRow.displayName = 'DataTableRow';\n\nexport default memo(DataTable) as typeof DataTable;\n","import { type FC, memo, type ReactNode } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\n\nimport styles from './index.module.scss';\n\ntype Props = {\n /**\n * Filtreler uygulanır. `preventDefault` bileşenin işi; çağıran yalnızca\n * durumunu günceller (sayfayı 1'e almak + aramayı uygulamak gibi).\n */\n onSubmit: () => void;\n /** Alanlar — her biri {@link FilterBarField} içinde. */\n children: ReactNode;\n /** Şeridin sağ ucundaki eylemler (\"Uygula\" düğmesi gibi). */\n actions?: ReactNode;\n /** Şeridin erişilebilir adı (\"Filtreler\"). */\n label: string;\n className?: string;\n testId?: string;\n};\n\n/**\n * Filtre şeridi.\n *\n * <h3>Her zaman `<form onSubmit>`</h3>\n * Beş ekran şeridi elle kuruyordu ve yalnızca üçü `<form>` kullanıyordu: arama\n * kutusunda Enter üç ekranda filtreyi uyguluyor, ikisinde hiçbir şey\n * yapmıyordu. Şerit artık her zaman bir formdur ve görünür bir gönderme düğmesi\n * olmasa bile Enter çalışsın diye gizli bir yedek gönderme düğmesi taşır\n * (birden çok alanı olan formda tarayıcının örtük gönderimi ancak bir gönderme\n * düğmesi varsa çalışır).\n *\n * <h3>320px'te taşma yok</h3>\n * Alanlar `min-width: 240–280px` taşıyordu ve en dar ekranda şerit sayfayı yana\n * kaydırıyordu. Genişlik artık `flex-basis` ile istenir, `min-width: 0` ile\n * daraltılabilir kalır: alan tercihen 220px'tir ama sığmadığı yerde küçülür,\n * taşmaz.\n */\nconst FilterBar: FC<Props> = ({ onSubmit, children, actions, label, className, testId }) => (\n <form\n className={cx(styles.bar, className)}\n aria-label={label}\n data-testid={testId}\n onSubmit={event => {\n event.preventDefault();\n onSubmit();\n }}\n >\n {children}\n\n {/*\n Enter'ın yedeği. Görünmez ama tarayıcı için formun varsayılan gönderme\n düğmesi: `display: none` örtük gönderimi bozmaz. Görünür \"Uygula\" düğmesi\n `actions` ile ayrıca verilebilir; ikisi aynı submit olayına düşer.\n */}\n <button type=\"submit\" className={styles.bar__hiddenSubmit} tabIndex={-1} aria-hidden />\n\n {actions && <div className={styles.bar__actions}>{actions}</div>}\n </form>\n);\n\ntype FieldProps = {\n children: ReactNode;\n /**\n * Alan kalan genişliği doldurur (arama kutusu). Diğer alanlar tercih\n * ettikleri genişlikte kalır ve şerit sağa doğru boşluk bırakır.\n */\n isWide?: boolean;\n className?: string;\n};\n\n/**\n * Şerit içindeki tek alanın genişlik sözleşmesi. İçine `Field` + girdi ya da\n * yalın `Input` konur; genişlik kararı alanın kendisine yazılmaz.\n */\nexport const FilterBarField: FC<FieldProps> = memo(({ children, isWide, className }) => (\n <div className={cx(styles.field, isWide && styles['field--wide'], className)}>{children}</div>\n));\n\nFilterBarField.displayName = 'FilterBarField';\n\nexport default memo(FilterBar) as typeof FilterBar;\n","'use client';\n\nimport { type FC, memo, useMemo } from 'react';\n\nimport { cx } from '../../helpers/class-name.helper';\nimport UISize from '../../enums/ui-size.enum';\nimport UIVariant from '../../enums/ui-variant.enum';\nimport { ChevronLeftIcon, ChevronRightIcon } from '../../icons';\nimport type { HanuiLinkExtraProps } from '../../types/link.type';\nimport Button from '../Button';\nimport IconButton from '../IconButton';\nimport HanuiLink from '../Link';\n\nimport styles from './index.module.scss';\n\ntype BaseProps = {\n page: number;\n totalPages: number;\n /** Gezinme bölgesinin erişilebilir adı (\"Sayfalar\"). */\n label: string;\n previousLabel: string;\n nextLabel: string;\n className?: string;\n testId?: string;\n};\n\ntype LinkProps = BaseProps & {\n /**\n * Sayfa numarasının adresini üretir.\n *\n * <p>Verildiğinde numaralar `<a>` olur — ve olması gerekir. Düğmenin `href`i\n * yok: arama motoru bir tıklama olayını çalıştırmaz ve ikinci sayfaya HİÇ\n * geçemez; kullanıcı da orta tuşla yeni sekmede açamaz, adresi kopyalayamaz,\n * durum çubuğunda hedefi göremez.\n */\n buildHref: (page: number) => string;\n onPageChange?: never;\n /** Yönlendiriciye geçirilecek ek props (`{ scroll: false }` gibi). */\n linkProps?: HanuiLinkExtraProps;\n};\n\ntype ButtonProps = BaseProps & {\n /**\n * Sayfa değişimi adres çubuğu YERİNE buraya bildirilir.\n *\n * <p>Yalnızca sayfalamanın adrese yazılmadığı listeler için: kişiye özel,\n * `noindex` ekranlarda kimse \"ikinci sayfa\" bağlantısını paylaşmıyor ve orada\n * adresi kirletmek geri tuşunu kullanılamaz hâle getiriyordu. Bağlantı\n * verilebilecek bir hedef olmadığı için numaralar düğme kalır.\n */\n onPageChange: (page: number) => void;\n buildHref?: never;\n linkProps?: never;\n};\n\ntype Props = LinkProps | ButtonProps;\n\n/** Kenarlarda 1 ve son sayfa her zaman gorunur; arasi kisaltilir. */\nconst buildPageList = (page: number, totalPages: number): (number | 'gap')[] => {\n if (totalPages <= 7) return Array.from({ length: totalPages }, (_, index) => index + 1);\n\n const pages = new Set<number>([1, totalPages, page]);\n if (page - 1 > 1) pages.add(page - 1);\n if (page + 1 < totalPages) pages.add(page + 1);\n\n const sorted = [...pages].sort((left, right) => left - right);\n const result: (number | 'gap')[] = [];\n\n sorted.forEach((value, index) => {\n if (index > 0 && value - sorted[index - 1] > 1) result.push('gap');\n result.push(value);\n });\n\n return result;\n};\n\n/**\n * Sayfalama.\n *\n * <h3>Sayfa numaraları BAĞLANTI, düğme değil</h3>\n * `buildHref` verildiğinde numaralar `<a>` olur. Düğme olarak bırakıldığında\n * iki bedeli vardı:\n * <ul>\n * <li><strong>Tarayıcı (crawler) ikinci sayfaya geçemiyordu.</strong> Düğmenin\n * `href`i yok; arama motoru bir tıklama olayını çalıştırmaz. Derin\n * sayfalardaki kayıtlar yalnızca sitemap'te göründükleri kadar\n * keşfedilebiliyordu.</li>\n * <li><strong>Kullanıcı yeni sekmede açamıyordu.</strong> Orta tık, Cmd+tık ve\n * \"bağlantıyı kopyala\" çalışmıyor, durum çubuğunda hedef görünmüyordu.</li>\n * </ul>\n *\n * <p>Oklar her iki kipte de `IconButton`: devre dışı kalabildikleri için düğme\n * kalırlar — `<a>` etiketinin \"devre dışı\" hâli yok, `aria-disabled` ise\n * tıklamayı engellemez. Sayfa numaraları tarayıcıya zaten tam listeyi veriyor.\n */\nconst Pagination: FC<Props> = ({\n page,\n totalPages,\n label,\n previousLabel,\n nextLabel,\n buildHref,\n onPageChange,\n linkProps,\n className,\n testId,\n}) => {\n const pages = useMemo(() => buildPageList(page, totalPages), [page, totalPages]);\n\n if (totalPages <= 1) return null;\n\n const goTo = (target: number) => {\n if (onPageChange) onPageChange(target);\n };\n\n return (\n <nav className={cx(styles.pagination, className)} aria-label={label} data-testid={testId}>\n <IconButton\n className={styles.pagination__arrow}\n icon={<ChevronLeftIcon />}\n label={previousLabel}\n variant=\"outline\"\n disabled={page <= 1}\n onClick={() => goTo(page - 1)}\n />\n\n <ul className={styles.pagination__list}>\n {pages.map((value, index) =>\n value === 'gap' ? (\n <li key={`gap-${index}`} className={styles.pagination__gap} aria-hidden>\n …\n </li>\n ) : (\n <li key={value}>\n {buildHref ? (\n <HanuiLink\n href={buildHref(value)}\n className={cx(\n styles.pagination__page,\n value === page && styles['pagination__page--active'],\n )}\n aria-current={value === page ? 'page' : undefined}\n {...linkProps}\n >\n {value}\n </HanuiLink>\n ) : (\n <Button\n variant={UIVariant.SECONDARY}\n size={UISize.SMALL}\n className={cx(\n styles.pagination__page,\n value === page && styles['pagination__page--active'],\n )}\n aria-current={value === page ? 'page' : undefined}\n onClick={() => goTo(value)}\n >\n {value}\n </Button>\n )}\n </li>\n ),\n )}\n </ul>\n\n <IconButton\n className={styles.pagination__arrow}\n icon={<ChevronRightIcon />}\n label={nextLabel}\n variant=\"outline\"\n disabled={page >= totalPages}\n onClick={() => goTo(page + 1)}\n />\n </nav>\n );\n};\n\nexport default memo(Pagination) as typeof Pagination;\n"],"names":["NEUTRAL","GRAPHITE","AMBER","BLUE","STATUS","DANGER_SOLID","ACCENT","SALE","STAR","alpha","hex","value","normalized","full","character","red","green","blue","BLACK","LIGHT_THEME","DARK_THEME","DEFAULT_FONTS","TOKEN_PREFIX","THEME_STYLE_ID","THEME_ATTRIBUTE","THEME_SWITCHING_CLASS","resolveTokens","scheme","config","base","overrides","buildThemeCss","blocks","declarations","tokens","indent","name","fonts","fontEntries","role","stack","body","applyThemeConfig","isClient","css","existing","element","HanuiContext","createContext","useHanui","useContext","HanuiProvider","children","theme","linkComponent","themeKey","useMemo","useEffect","jsx","initHanui","options","readSystemScheme","_a","readScheme","attribute","useHanuiTheme","setSchemeState","useState","isReady","setIsReady","query","handleChange","setScheme","useCallback","next","root","toggle","HEIGHT_VAR","INSET_VAR","openCount","frame","measure","viewport","covered","schedule","useSheetViewport","isActive","UIVariant","UISize","MOBILE_BREAKPOINT","TABLET_PORTRAIT_BREAKPOINT","TABLET_BREAKPOINT","ABOVE_TABLET_MEDIA_QUERY","ABOVE_MOBILE_MEDIA_QUERY","normalizeSearchTerm","matchesSearch","haystack","needle","NON_TEXT_INPUT_TYPES","isKeyboardOpeningElement","editable","tagName","preventAutoKeyboard","dialog","active","cx","values","result","HanuiLink","rest","LinkComponent","Spinner","size","label","className","styles","Spinner$1","memo","Button","forwardRef","variant","isLoading","isFullWidth","startIcon","endIcon","disabled","href","isExternal","linkProps","testId","ref","classNames","content","jsxs","Fragment","Button$1","IconButton","icon","type","IconButton$1","Icon","XIcon","props","CheckIcon","CheckSmallIcon","ChevronDownIcon","ChevronLeftIcon","ChevronRightIcon","ArrowRightIcon","SearchIcon","PlusIcon","MinusIcon","CopyIcon","InfoCircleFillIcon","CheckCircleFillIcon","ExclamationTriangleFillIcon","XCircleFillIcon","ExclamationCircleIcon","QuestionCircleFillIcon","TrashFillIcon","StarIcon","StarFillIcon","StarHalfIcon","TextLink","hasArrow","tone","index$y","Tooltip","position","isOpen","setIsOpen","id","useId","event","index$x","Chip","count","isSelected","isDefined","Chip$1","ChipGroup","isScrollable","selection","listRef","useRef","handleSelect","item","handleKeyDown","offset","enabled","option","currentIndex","_b","tabbableValue","index$w","BottomSheet","title","closeLabel","onClose","toolbar","footer","closeAbove","titleId","previous","setDialogRef","node","handleBackdropClick","createPortal","BottomSheet$1","Combobox","onChange","labels","isSearchHidden","onSearch","isDisabled","isClearable","describedBy","isInvalid","generatedId","baseId","listboxId","rootRef","triggerRef","inputRef","openMode","setOpenMode","setQuery","activeIndex","setActiveIndex","cachedLabel","setCachedLabel","visibleOptions","selectedOption","displayLabel","searchRef","timer","close","open","index","handlePointerDown","selectOption","wasOpenRef","handleInputKeyDown","lastIndex","current","clearSelection","search","renderList","isSheet","isChosen","index$v","Select","placeholder","align","optionId","selectedIndex","index$u","Checkbox","hint","index$t","Radio","index$s","RadioCard","index$r","RangeSlider","min","max","step","onCommit","formatValue","minLabel","maxLabel","low","high","handleLowChange","raw","handleHighChange","commit","span","lowPercent","normalize","highPercent","isLowOnTop","index$q","STARS","RatingInput","ratingLabels","formatStarCount","hovered","setHovered","shown","star","index$p","QuantityStepper","decreaseLabel","increaseLabel","draft","setDraft","parsed","index$o","TableCheckbox","index$n","Input","prefix","suffix","isTechnical","Input$1","Textarea","rows","Textarea$1","Field","error","isRequired","requiredLabel","isLabelHidden","errorId","hintId","Field$1","ICONS","Alert","action","index$m","resolveInitials","locale","words","letters","Avatar","imageUrl","index$l","Badge","index$k","Breadcrumb","items","isLast","index$j","Card","isInteractive","Tag","CardMedia","ratio","isContained","CardOverlay","CardBody","CardFooter","index$i","COPIED_FEEDBACK_MS","CopyField","copyLabel","copiedLabel","copiedAnnouncement","isReadOnly","isCopied","setIsCopied","codeRef","timerRef","selectValue","range","handleCopy","index$h","Divider","index$g","Directory","DirectoryGroup","meta","DirectoryRow","media","marker","DirectoryJump","toId","index$f","EmptyState","description","secondaryAction","index$e","PageHeader","eyebrow","actions","breadcrumb","Heading","index$d","Panel","isFlush","gap","bodyClassName","PanelForm","columns","PanelRow","index$c","Price","currency","listValue","discountPercent","formatDiscount","percent","index$b","Rating","srLabel","rounded","_","index$a","SectionHeader","overline","index$9","Skeleton","width","height","lines","style","isNumber","index$8","Tabs","defaultTabId","controlledId","ariaLabel","uncontrolledId","setUncontrolledId","isControlled","activeId","select","hasPanel","index$7","Tile","index$6","Modal","isDismissable","dialogRef","descriptionId","handleCancel","Modal$1","KIND_ICON","KIND_TONE","KIND_VARIANT","ConfirmDialog","onConfirm","confirmLabel","cancelLabel","kind","isRunning","setIsRunning","handleConfirm","index$5","PromptDialog","onSubmit","submitLabel","defaultValue","inputMode","maxLength","formId","setValue","isBusy","setIsBusy","trimmed","isSubmitDisabled","renderControl","handleSubmit","index$4","TableScroller","hasFrame","Table","density","hasStickyHead","hasRowHover","index$3","DataTable","emptyMessage","loadingMessage","hasViewportCap","rowCount","Children","renderStateRow","modifier","column","DataTableRow","isWarning","index$2","FilterBar","FilterBarField","isWide","index$1","buildPageList","page","totalPages","pages","sorted","left","right","Pagination","previousLabel","nextLabel","buildHref","onPageChange","goTo","target"],"mappings":"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"}
|