@appaflytech/zeyrek-ai-mcp 0.0.14 → 0.0.15

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.
@@ -53,23 +53,27 @@ const NODE_SURFACE_NOTE = STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOT
53
53
  const NAVIGATION_STYLE_NOTE = "Menü satırlarının TİPLİ grubu, menünün TAMAMINA uygulanır: padding (CSS kutu kısayolu; sol değer satırın derinlik girintisiyle TOPLANIR), radius (tema kademesi 'sm|md|lg|pill' ya da CSS), textColor · iconColor · hoverBackground (seçili OLMAYAN satırlar), activeBackground · activeTextColor · activeIconColor (seçili satır; zemin hover'da da korunur). Boş iconColor yazı rengini izler. Renkler hex ya da var(--ng-…) token'ı alır. ÖĞE BAZLI STİL YOKTUR: navigations[].style diye bir alan tanımlı değil, yazılan değer sessizce düşer — satır görünümünü yalnız bu grup verir. Grubun yazmadığı CSS için style'ın &__item / &__item--active / &__icon parçaları kullanılır (yalnız navigations bileşeninde; layout'un style'ı menüye ulaşmaz). resolvedStyle raporu bu grubu İÇERMEZ.";
54
54
  export const componentKnowledge = {
55
55
  html: {
56
- summary: 'Kaçış kapısı: hazır komponentler yetmediğinde ham HTML + Mustache şablonu + scoped CSS + satır içi script + flow köprüsüyle her gereksinimi kapatır.',
56
+ summary: 'Kaçış kapısı: hazır komponentler yetmediğinde ham HTML + Mustache şablonu + scoped CSS + satır içi script + flow köprüsüyle her gereksinimi kapatır. KAPSAYICI DEĞİLDİR: içine komponent bırakılamaz, içeriği markup’ının kendisidir.',
57
57
  guide: 'html',
58
58
  behavior: [
59
+ 'KAPSAYICI DEĞİL: children kabul etmez, şema doğrulayıcı çocuk yazılan html düğümünde not-droppable hatası verir. Serbest komponent yerleştirmek için container ya da box kullan; html yalnız kendi markup’ını çizer.',
59
60
  "content `{{` içeriyorsa Mustache şablonu olarak context prop'uyla render edilir; şablon hatasında ham içerik basılır (sayfa ölmez).",
60
61
  "Flow'dan HTML'e veri DÖNER: setter adımı context prop'una yazınca içerik otomatik yeniden render olur — dinamik gösterimin doğru yolu budur.",
61
62
  "HTML içinden flow tetikleme: actions dizisine { key, text, flow } satırı ekle, HTML'de fireEvent('<key>', {...}) çağır. Flow'da event.name = key, event.data = ikinci argüman.",
62
63
  "Satır içi <script> etiketleri çalışır ve içerik her değiştiğinde yeniden çalışır; script gövdesinde komponent-bağlı fireEvent / onCleanup(fn) / loadScript(url) yerelleri hazırdır.",
63
64
  "<script src=...> bilinçli olarak YÜKLENMEZ (öznitelik kopyalanmaz) — harici kütüphane loadScript(url) ile çekilir (Promise döner, url bazında tekilleştirir).",
64
65
  "Script'ler flow ifade bağlamına (Page, Steps, komponent adları) erişemez; köprü yalnız fireEvent (dışarı) ve context (içeri).",
65
- "Şema olayı yalnız mount'tur; aksiyonlar set_event ile DEĞİL kendi flow prop'uyla bağlanır (type:'flow', ref:<flowId>)."
66
+ "Şema olayı yalnız mount'tur; aksiyonlar set_event ile DEĞİL kendi flow prop'uyla bağlanır (type:'flow', ref:<flowId>).",
67
+ 'isLoading açıkken içeriğin YERİNE nabız atan bir iskelet bloğu çizilir ve satır içi script’ler çalışmaz; kapanınca aynı içerik için baştan çalışırlar. mount + setter ile veri çeken ekranda "veri gelene kadar ne görünsün" cevabı budur.',
68
+ 'Temizlenmiş prop kırmaz: content boş ya da metin olmayan bir değer (sayı, null) olduğunda komponent boş çizer, context nesne değilse boş sözlük sayılır — hata atmaz.'
66
69
  ],
67
70
  propNotes: {
68
71
  surfaceStyle: NODE_SURFACE_NOTE,
69
72
  content: "Ham HTML ya da Mustache şablonu. type:'code' + {{ }} ifadesiyle dinamik de beslenebilir.",
70
73
  context: 'Mustache değişken sözlüğü (nesne). Setter ile yazmak içeriği yeniden render eder.',
71
74
  style: "emotion css() bloğu: iç seçiciler ve &:hover çalışır, üretilen sınıf komponente scope'ludur.",
72
- actions: "[{ key, text, flow }] — key fireEvent adıdır (text'ten snake üretilir), flow çalıştırılacak akıştır."
75
+ actions: "[{ key, text, flow }] — key fireEvent adıdır (text'ten snake üretilir), flow çalıştırılacak akıştır.",
76
+ isLoading: 'Yükleme iskeleti anahtarı. Geri YAZILMAZ (komponentin change olayı yok), yalnız akış sürer: fetch öncesi setter ile aç, veriyi context’e yazan setter’dan sonra kapat.'
73
77
  }
74
78
  },
75
79
  table: {
@@ -88,12 +92,13 @@ export const componentKnowledge = {
88
92
  propNotes: {
89
93
  surfaceStyle: NODE_SURFACE_NOTE,
90
94
  rows: 'Satır dizisi; mount/filter/sort/pagination akışlarının setter adımıyla doldurulur.',
91
- appearance: "YÜKSEKLİK/GENİŞLİK ELLE HESAPLANMAZ (ölçüldü 2026-09-05, f11-repro). heightType:'auto' tablo içeriği kadar uzar — satır sayısı × satır yüksekliği hesabı gerekmez. heightType:'fixed' gövdeyi KAYDIRIR (grid-container overflow:auto), satır kaybolmaz; kare'de görünmeyen satır kırpılmış değil kaydırılmıştır. KOLONLAR KARTI TAŞIRMAZ: genişlik toplamı kabı aşarsa tablo kendi içinde YATAY kaydırır ve sağ kenara taşma göstergesi koyar; kabın scrollWidth'i değişmez. Toplam kaptan KÜÇÜKSE kolonlar orantılı büyütülüp kap tam doldurulur (stretchColumns) — bu yüzden 'kolonu daraltayım da sığsın' yamalarına gerek yok. Tek gerçek tuzak yerleşim tarafındadır: FLEX ebeveynde blocks[].size yok sayılır, ölçü appearance'tan gelir; IZGARA ebeveynde tersi (gateway PAGE-019 ile uyarır).",
95
+ appearance: "YÜKSEKLİK/GENİŞLİK ELLE HESAPLANMAZ (ölçüldü 2026-09-05, f11-repro). heightType:'auto' tablo içeriği kadar uzar — satır sayısı × satır yüksekliği hesabı gerekmez. heightType:'fixed' gövdeyi KAYDIRIR (grid-container overflow:auto), satır kaybolmaz; kare'de görünmeyen satır kırpılmış değil kaydırılmıştır. KOLONLAR KARTI TAŞIRMAZ: genişlik toplamı kabı aşarsa tablo kendi içinde YATAY kaydırır; kabın scrollWidth'i değişmez. KAYDIRMA ÇUBUKLARI VARSAYILAN GİZLİDİR (kaydırma Shift+tekerlek, trackpad, dokunma ve klavyeyle çalışır) ve sağda gizli kolon olduğunu gösteren tek işaret sabitlenmiş aksiyon kolonunun (actionsPinned) sol çizgisidir — kolonları sağa taşan tabloda kullanıcının görmesi için showScrollbar:true yaz. Toplam kaptan KÜÇÜKSE kolonlar orantılı büyütülüp kap tam doldurulur (stretchColumns) — bu yüzden 'kolonu daraltayım da sığsın' yamalarına gerek yok. Tek gerçek tuzak yerleşim tarafındadır: FLEX ebeveynde blocks[].size yok sayılır, ölçü appearance'tan gelir; IZGARA ebeveynde tersi (gateway PAGE-019 ile uyarır).",
92
96
  totalRows: "Toplam kayıt: Number(Steps.<adım>?.headers?.[\"total-count\"] ?? 0) guard'lı ifadesiyle yazılır. Yazılmazsa sayfalayıcı tek sayfa kalır ve gösterge eldeki satırları sayar.",
93
97
  rowSelection: "none | single | multi — seçim self.selectedRow / self.selectedRows prop'larından okunur. none 'satır seçilemez' DEMEK DEĞİL: satır tıklaması yine selectedRow'a yazar ve select'i çalıştırır, yalnız vurgu yoktur.",
94
98
  isSearchable: "Araç çubuğuna arama kutusu koyar. Kutu yalnız searchText'i yazar ve search olayını { searchText, offset:0 } ile çalıştırır; SÜZMEYİ AKIŞ YAPAR — search olayını mount'la aynı sorguya bağla ve metni akışta self.searchText ile okuyup uca parametre olarak geçir. Metin kırpılmadan gelir.",
95
99
  searchText: "Uygulanan arama metni. Kutu yazar, akış okur. Tasarımda doldurulursa kutu O METİNLE açılır — ama tablo kendisi aramadığı için ilk sayfa ancak mount akışı da self.searchText'i sorguya geçiriyorsa aranmış gelir. Akıştan yazılırsa kutu o metni gösterir.",
96
100
  size: "Satır YOĞUNLUĞU (panel etiketi 'Row density'): sm sıkı · md ve boş = temanın normal satır yüksekliği · lg ferah. Form bileşenlerinin temadaki varsayılan girdi boyutunu İZLEMEZ. Yalnız satır ve başlık yüksekliğini değiştirir (yazı boyu değişmez); filtre satırı her yoğunlukta aynı kalır.",
101
+ showScrollbar: "Izgaranın kaydırma çubuklarını çizer (ince, tema kenarlık renginde; hangi eksen taşıyorsa o). Varsayılan false: çubuklar gizli ama kaydırma yine çalışır. Kolon genişlikleri toplamı kabı aşan (sağa taşan) ya da heightType:'fixed' ile dikey kayan tablolarda aç — yoksa kullanıcı sağdaki kolonların varlığını fark etmez.",
97
102
  isReadonly: "Düzenlemeyi (isEditable'ı ezer), satır tıklamasının select/doubleClick'ini, multi onay kutularını ve aksiyon kolonunu kapatır; filtre/sıralama/arama/sayfalama çalışmaya devam eder.",
98
103
  limit: "Sayfa boyu. Sayfalayıcıdaki liste 10·20·30·40·50'dir; başka bir değer (25, 100) listeye eklenir ve seçili görünür. pagination olayı { offset, limit } yazar.",
99
104
  columns: TABLE_COLUMN_TYPE_NOTE + " Kolon tanımları; mapping anahtarları kolonların name'iyle birebir eşleşmeli. HİZA: kolonun align alanı left|center|right (boş = left) başlığı ve hücreyi birlikte hizalar — sayı/para kolonlarını sağa yaslamak için; tags kolonu hizalanmaz (rozetler taşma ölçümü için soldan dizilir); progress çubuğu hücreyi doldurur, circle varyantı varsayılan olarak ortalıdır. isBold tag · tags · url · link · switch · image · progress DIŞINDAKİ kolonlarda hücreyi kalın yazar (onlar kendi kalınlığını çizer ya da metin taşımaz). progress ayarları (max, progressVariant, progressLabel, progressColor, customProgressColor, thresholds) YALNIZ type:'progress' kolonunda okunur. RENK: tag kolonu appearance ile 5 token alır (primary · info · success · warning · error) ve satır bazında _columns ezmesiyle değişir; serbest hex gerekiyorsa tags kolonunu kullan ve satır verisine [{ value, color:'#da1e28' }] yaz. Sayı/tarih biçimlendirmesi (prefix/suffix/precision/thousands/dateFormat/imageShape) table'da YOK — o datatable'ın kolon şemasındadır. ORANSAL ÇUBUK: type:'progress' hücrede çubuk çizer ve HAM SAYI bekler (yüzdeyi kendisi hesaplar): value/max. max varsayılanı 100, yani 0..100 arası yüzde alanını doğrudan bağlayabilirsin; sayı 25/40 gibi bir orandan geliyorsa max'ı paydaya ver. Ayarlar: progressVariant(bar|circle) · progressLabel(none|percent|fraction|value) · progressColor(primary|info|success|warning|error|custom) + customProgressColor · thresholds[{from(%), color}] — eşik listesi doluysa çubuğun DOLULUK YÜZDESİNE göre son eşiğin rengi kazanır, yani tek kolon 80'in altında yeşil üstünde kırmızı olur. Sayıya çevrilemeyen değer 0'dır, hücre boş çubuk çizer.",
@@ -123,17 +128,25 @@ export const componentKnowledge = {
123
128
  }
124
129
  },
125
130
  form: {
126
- summary: "Alanları saran kapsayıcı; submit olayı yayar ve doğrulama hatalarını errorElementId'deki form-validation-errors komponentinde toplar.",
131
+ summary: "Alanları saran kapsayıcı; gönderimde her alanın kendi kurallarını ve formun kendi form düzeyi kurallarını koşar, hepsi geçince submit yayar, hataları errorElementId'deki form-validation-errors listesinde toplar; toplu değeri (value) ve geçerliliği (isValid) çalışma zamanında kendi düğümüne yazar.",
127
132
  behavior: [
133
+ "GÖNDERİM: submit yalnız bütün kurallar geçince yayılır; kalırsa alanlar işaretlenir, liste dolar ve sayfa listeye kayar. Alan mesajları formun İLK gönderiminden sonra görünür, o andan itibaren her change o alanı canlı yeniden doğrular. Formu gönderen düğme Type='submit' olur (form içinde ya da formId ile bağlı); akışta event.source.id gönderen düğmenin ADI, event.source.props onun prop'larıdır — event.data boştur (componentEvents).",
134
+ "value ve isValid RUNTIME YAZAR, panelde çizilmez (2026-09-18): Page.components.<form>.value = { <alan adı>: değer } — yalnız doğrulama sözlüğündeki alan bileşenleri girer (text/button gibi gösterim düğümleri girmez), boş alan null, aralık seçici { valueFrom, valueTo }; gönderim akışında self.value ile de okunur ve uca olduğu gibi verilebilir. Page.components.<form>.isValid mount'ta ve her değişimde SESSİZCE yeniden hesaplanır (gizli alanlar muaf, form düzeyi kurallar dahil) — mesaj göstermez; submit düğmesini {{ !Page.components.<form>.isValid }} ile kilitlemenin yolu budur. İkisini setter ile YAZMA, sonraki değişimde ezilir.",
128
135
  "Düzen prop grubunun TAMAMINI taşır (2026-09-01): layout ('flex' | 'grid') + direction/horizontalAlign/verticalAlign/size/gap/wrap, varsayılanları container ile aynı (flex · row · left · top · shrink · medium · wrap açık). 'Form'a layout yazılmaz' eski bilgidir. layout prop'u hiç yazılmamış eski form kayıtları ızgara koordinatıyla (blocks[].position + size.w) dizilmeye devam eder. Platform kataloğu component_get'te hâlâ eski şemayı gösteriyorsa kayıt yenilenmemiştir (ARC-024).",
129
- "Alan doğrulaması komponentin kendi validations dizisindedir: [{ type: 'required'|'email'|'max-length'…, message, value, isActive }] — dördü de zorunlu, eski 'maxLength' yazımı kaydedilir ama runtime doğrulayıcı onu TANIMAZ ve sessizce hiçbir şey doğrulamaz.",
136
+ "Alan doğrulaması komponentin kendi validations dizisindedir: [{ type: 'required'|'email'|'max-length'…, message, value, isActive }] — dördü de zorunlu, eski 'maxLength' yazımı kaydedilir ama runtime doğrulayıcı onu TANIMAZ ve sessizce hiçbir şey doğrulamaz. min-value/max-value tarih kuralının çıplak 'yyyy-MM-dd' değeri YEREL gün okunur (2026-09-18): sınır gününe eşit bir alan değeri her saat diliminde geçer (eskiden UTC okunup Türkiye'de 3 saat kayıyordu, CQ-252).",
130
137
  "message bir ÇEVİRİ ANAHTARI olabilir: 't:' önekiyle yazılan mesaj (ör. 't:form.required') uygulamanın çeviri sözlüğünden çözülür — hem alanın kendi hata metninde hem form-validation-errors listesinde. Öneksiz mesaj yazarın kendi cümlesidir ve iki nokta içerse bile aynen gösterilir. Çözüm form MOUNT olurken bir kez yapılır: ekranda hata dururken dil değiştirilirse metin sayfa yenilenene kadar eski dilde kalır.",
131
- "Formu temizlemek için akış kodunda resetForm('<form adı>') çağrılır (2026-09-15): alanlar başlangıç değerine döner, form gönderilmemiş hâline geçer, hata işaretleri ve form-validation-errors listesi silinir. Alanları setter ile tek tek null'a çekmek YANLIŞ yoldur: form bir kez gönderildiyse her change doğrulamayı yeniden koşturur ve boş form 'zorunlu alan' mesajlarıyla açılır. Gönderim sonrası otomatik temizlik isteniyorsa isClearFormInputsAfterSubmit aynı sıfırlamayı yapar."
138
+ "Formu temizlemek için akış kodunda resetForm('<form adı>') çağrılır (2026-09-15): alanlar başlangıç değerine döner, form gönderilmemiş hâline geçer, hata işaretleri ve form-validation-errors listesi silinir. Alanları setter ile tek tek null'a çekmek YANLIŞ yoldur: form bir kez gönderildiyse her change doğrulamayı yeniden koşturur ve boş form 'zorunlu alan' mesajlarıyla açılır. Gönderim sonrası otomatik temizlik isteniyorsa isClearFormInputsAfterSubmit aynı sıfırlamayı yapar.",
139
+ "isLoading AÇIKKEN alanlar DOM'dan kalkar, yerine yükleme animasyonu çizilir: kapanınca çocuklar yeniden mount olur ve onların mount olayları İKİNCİ kez çalışır; makinedeki değerler korunur. title boş bırakılırsa başlık bandı hiç çizilmez. Kanvas toolbar'ı (2026-09-18): isClearFormInputsAfterSubmit · isLoading · isHidden — yerleşim grubunu container toolbar'ı zaten çizer."
132
140
  ],
133
141
  propNotes: {
134
142
  surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens + " Form grubu KENDİ derler (2026-09-15): değer <form> KÖKÜNE iner, contentOverflow gövdeye ('&__body'). Formu bir kartın içine koyup kendi zeminini/çerçevesini kaldırmanın yolu budur: { background: 'transparent', borderTop: 'none', borderRight: 'none', borderBottom: 'none', borderLeft: 'none' }.",
135
143
  style: STYLE_GROUP_NOTES.styleEscape + " Parçalar: KÖK (anahtarlar doğrudan style'da) <form> elemanıdır ve TABAN zemini (--ng-background-surface), 1px çerçeveyi (--ng-border-primary) ve köşeyi (--ng-rounded) ÇİZER; '&__body' yalnız kaydırma/esneme taşır — çerçeveyi '&__body'ye yazarak kaldıramazsın. '&__header' başlık bandı, '&__title' başlık metni. DOM yapısına bağlı seçiciler ('& > div') belgelenmemiştir ve iç yapı değişince sessizce kırılır.",
136
- errorElementId: "Sayfadaki form-validation-errors komponentinin elementId'si — bağlanmazsa alan doğrulama mesajları görünmez."
144
+ errorElementId: "Sayfadaki form-validation-errors komponentinin elementId'si. BAĞ OLMASA DA alan altı mesajlar GÖRÜNÜR (form her alanın invalidText'ini kendisi yazar); bağ yalnız toplu listeyi doldurur, sayfayı listeye kaydırır ve listenin hideFormValidationMessage'ını okur. Boş bırakılırsa form İÇİNDEKİ ilk form-validation-errors düğümü tipine göre bulunur (2026-09-18; eski yedek yalnız studio paletinin ürettiği id önekine bakıyordu); liste formun DIŞINDAYSA bağ şarttır.",
145
+ validations: "FORM DÜZEYİ kurallar — alanın kendi validations dizisi DEĞİL: [{ name, element, condition, message }]. condition bir ifade ya da fx bağıdır ve TRUE olunca kural KIRILMIŞ sayılır ('table1.rows.length <= 0', 'Page.components.end.value < Page.components.start.value'); element (elementId) işaretlenir, message (t: anahtarı olabilir) listeye o alanın etiketiyle girer. İŞARET ve MESAJ yalnız gönderimde; koşulun kendisi isValid için her alan değişiminde sessizce yeniden değerlendirilir (formun dışındaki bir düğüme bağlı koşul — 'table1.rows.length' gibi — yalnız o anlarda ve gönderimde okunur). Repeater içindeki form için value/isValid tanımsızdır (satır parametresi taşımaz).",
146
+ title: "Başlık bandının metni; boş bırakılırsa bant ve alt çizgisi hiç çizilmez.",
147
+ isLoading: "Açıkken alanlar yerine yükleme animasyonu — çocuklar DOM'dan kalkar, kapanınca yeniden mount olur (mount olayları ikinci kez çalışır). Sorgu sonucu gelene kadar formu kapatmak için akıştan açılıp kapatılır.",
148
+ value: "RUNTIME YAZAR, okunur: { <alan adı>: değer } — alan adı düğümün name'i, boş alan null, aralık seçici { valueFrom, valueTo }; gösterim düğümleri girmez. Panelde görünmez, setter ile yazılmaz.",
149
+ isValid: "RUNTIME YAZAR, okunur: bütün alan kuralları ve form düzeyi kurallar şu an geçiyor mu. Mount'ta ve her değişimde sessizce güncellenir, mesaj göstermez; gizli alanlar muaf."
137
150
  }
138
151
  },
139
152
  box: {
@@ -141,7 +154,9 @@ export const componentKnowledge = {
141
154
  behavior: [
142
155
  "layout iki değer alır: 'flex' (akış) ve 'grid' — ve 'grid' container'ınkiyle AYNI ŞEYDİR: mutlak koordinatlı 12 kolon canvas (kullanıcı kararı 2026-09-02, tek grid kavramı). Şemadaki eski 'cssgrid' değeri (akan GERÇEK display:grid) seçenek olmaktan çıktı: yeni yazımda geçmez (invalid-enum-value), yalnız o değerle KAYITLI eski düğümler çizilmeye devam eder (screen-builder/grid-layout.ts isCssGridLayout yalnız 'cssgrid'e bakar).",
143
156
  "Yerleşim prop'ları bileşende OKUNMAZ: çocuk sarmalayıcısının stilini runtime'da RenderComponent, canvas'ta Draggable uygular (container ile aynı sözleşme).",
144
- "GÖVDE İÇİN DÜĞÜM YOKTUR: kutunun kendi bırakma alanına inen her şey gövdedir. hasHeader/hasFooter ise ayrı 'box-section' DÜĞÜMLERİ açar; bölge kapatılınca içindeki çocuklar SİLİNMEZ, gövdeye taşınır.",
157
+ "GÖVDE İÇİN DÜĞÜM YOKTUR: kutunun kendi bırakma alanına inen her şey gövdedir. hasHeader/hasFooter ise ayrı 'box-section' DÜĞÜMLERİ açar; bölge kapatılınca içindeki çocuklar SİLİNMEZ, gövdeye taşınır — TEK İSTİSNA bölge açılınca tohumlanan varsayılan metindir: dokunulmadıysa bölgeyle birlikte silinir (ölçüldü 2026-09-18), düzenlendiyse o da taşınır.",
158
+ "KANVASTA BIRAKMA ALANI HİÇBİR DURUM PROP'UYLA ÖLMEZ (2026-09-18, CQ-308): isLoading gövdeyi gizler (opacity 0 + pointer-events none) ama yalnız çalışma anında/önizlemede — editörde (_editorMode) sadece yükleyici çizilir ve tasarımcı kutunun içine bileşen bırakmaya devam eder. Yükleyici akış DIŞINDA konumlandırılmış bir kaplamadır ve pointer-events:none ile tıklamayı geçirir; aksi hâlde kutunun üst şeridindeki bırakmayı yiyordu.",
159
+ "Kanvas toolbar'ında dört düğme vardır (2026-09-18): Has header · Has footer · Loading · Is hidden. Yerleşim kontrollerini kanvasın kendi kap toolbar'ı çizer, designer.toolbar'a hiçbir yerleşim prop'u girmez.",
145
160
  "gridColumns/gridTemplate/gridRowGap ARTIK YALNIZ eski 'cssgrid' düğümlerinde okunur: o modda çocuğun blocks[].size.w'si 'grid-column: span N'e çevrilir ve gridTemplate doluysa gridColumns yok sayılır (şablon geçersizse kolon sayısına düşülür). layout:'grid' seçilen yeni kutuda bu üç prop ÖLÜDÜR — kolon payı yine blocks[].size.w'den gelir.",
146
161
  "Yüzeyi TİPLİ GRUPLARDAN yönetilir: surfaceStyle (zemin, köşe, yön yön kenarlık, çok katmanlı gölge, gövde taşması), typographyStyle (içeriğe miras), hoverStyle ve box'a özgü sectionStyle (başlık/altlık bölgelerinin ayracı, ayraç rengi, bölge dolgusu). Bölgeler kutunun içinde bir eleman DEĞİL, gövdeye yerleşen ayrı 'box-section' düğümleridir; bu yüzden sectionStyle onları gerçek sınıflarından ('.ng-box-section--header/--footer') hedefler. style'ın tek parçası '&__body'dir — eski '&__header'/'&__footer' parçaları hiçbir elemana denk gelmediği için kaldırıldı."
147
162
  ],
@@ -151,51 +166,79 @@ export const componentKnowledge = {
151
166
  surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens + " EMEKLİ isBorder prop'unun yerini bu grup aldı (2026-08-31 tipli stil göçü): çerçeve artık yön başına borderTop/Right/Bottom/Left ile açılır, isBorder yazmak unknown-prop verir.",
152
167
  typographyStyle: STYLE_GROUP_NOTES.typographyStyle + ' ' + STYLE_GROUP_NOTES.colorTokens,
153
168
  hoverStyle: STYLE_GROUP_NOTES.hoverStyle,
154
- sectionStyle: "{ headerDivider, footerDivider, dividerColor, sectionPadding(CSS uzunluğu: '12px') }. Ayraç anahtarı false ise bileşenin kendi ayracı KALDIRILIR (yok sayılmaz).",
155
- style: STYLE_GROUP_NOTES.styleEscape + " Parçalar: '&__header' · '&__body' · '&__footer' — ancak yalnız '&__body' gerçek bir elemana denk gelir (CQ-157)."
169
+ sectionStyle: "{ headerDivider, footerDivider, dividerColor, sectionPadding(CSS uzunluğu: '12px') }. Ayraç anahtarı false ise bileşenin kendi ayracı KALDIRILIR (yok sayılmaz). dividerColor boş, yalnız boşluk ya da çözülmemiş ifade ise tema kenarlık token'ına düşer (2026-09-18); eskiden boşluk değeri çizgiyi METİN rengiyle (currentColor) çizdiriyor, çözülmemiş ifade ise bildirimi düşürüp bölgenin taban çizgisine bırakıyordu — ayraç kaybolmuyor, yanlış renkte çiziliyordu.",
170
+ isLoading: "Yükleniyor durumu: gövde gizlenir ve yerine Loader çizilir — ama YALNIZ çalışma anında/önizlemede. Editör kipinde (_editorMode) gövde dokunulmaz kalır, yalnız yükleyici kaplaması eklenir; kanvasta kutunun içine bırakmak çalışmaya devam eder (CQ-308).",
171
+ style: STYLE_GROUP_NOTES.styleEscape + " Tek parça '&__body'dir; eski '&__header'/'&__footer' parçaları şemadan KALDIRILDI çünkü bölgeler kutunun markup'ında eleman değil ayrı box-section düğümleridir (eski CQ-157). Bölge görünümü sectionStyle'ın işidir."
156
172
  }
157
173
  },
158
174
  'box-section': {
159
- summary: "box'ın başlık/altlık bölgesi. Şemaya elle EKLENMEZ: box'ın hasHeader/hasFooter anahtarları bu düğümü açar ve kapatır.",
175
+ summary: "box'ın başlık/altlık bölgesi. AI BU DÜĞÜMÜ DOĞRUDAN KULLANMAZ: şemaya elle eklenmez, yalnız box'ın hasHeader/hasFooter anahtarları onu açar ve kapatır (slot/view emsali).",
160
176
  behavior: [
161
177
  'Yüzeysiz sarmalayıcıdır: kendi zemini/kenarlığı yoktur, yalnız bölge ayracını çizer (header altına, footer üstüne).',
162
178
  "Palette GÖRÜNMEZ (isHide) ve SİLİNEMEZ (isDeletable:false) — kaldırmanın tek yolu box'ın ilgili anahtarını kapatmaktır.",
179
+ "isLoading prop'u YOKTUR: yükleniyor durumu kutunun kendisindedir, bölge onu hiç görmez — dolayısıyla CQ-308'in bırakma alanını öldüren kalıbı bu düğümde hiç oluşmaz.",
180
+ "Kendi yerleşimini panelden değil ELEMENT AĞACINDAN seçilerek düzenler (palette gizli, ağaçta görünür); gap alanı hâlâ eski gap+gapCustom ikilisini taşır (box'ta tek alan allowCustom ile birleşti).",
163
181
  "role prop'u ('header' | 'footer') bölgenin kimliğidir ve gizlidir; elle değiştirmek yerleşimi bozar.",
164
182
  "Ayraç rengi ve bölge dolgusu artık kutunun 'sectionStyle' grubundan yönetilir (bölge düğümünün kendi şemasından değil): headerDivider/footerDivider/dividerColor/sectionPadding."
165
183
  ],
166
184
  propNotes: { role: "'header' | 'footer' — gizli; box'ın bölge uzlaştırması yazar." }
167
185
  },
168
186
  divider: {
169
- summary: 'Yatay ya da dikey ayraç çizgisi; ortasında isteğe bağlı etiket taşır. Olay YAYMAZ.',
187
+ summary: 'Yatay ya da dikey ayraç çizgisi; yatayda ortasında isteğe bağlı etiket taşır. Olay YAYMAZ, kapsayıcı DEĞİLDİR.',
170
188
  behavior: [
171
- "direction 'vertical' iken çizgi kapsayıcının YÜKSEKLİĞİNİ kullanır — yüksekliği olmayan bir akış kabında görünmez kalır.",
172
- 'label doluysa çizgi ikiye bölünür ve metin ortaya yerleşir; boşsa tek parça çizgidir.'
189
+ "direction 'vertical' iken çizgi kapsayıcının YÜKSEKLİĞİNİ kullanır — yüksekliği olmayan bir akış kabında görünmez kalır; flex kap ya da ölçülü hücre gerekir.",
190
+ "label doluysa çizgi ikiye bölünür ve metin ortaya yerleşir; boşsa tek parça çizgidir. Etiket YALNIZ yatayda çizilir — 'vertical' yönde label yok sayılır (hata vermez, çizmez).",
191
+ 'Kutu etiketten darsa etiket üç noktayla kırpılır (tam metin ipucunda), çizgi kutudan taşmaz.',
192
+ "Erişilebilirlik: role='separator' + aria-orientation; etiket varsa aria-label olarak da verilir (separator'ın çocuklarını ekran okuyucu okumaz).",
193
+ "Temizlenen/null gelen direction ve variant varsayılana düşer ('horizontal' / 'solid'); thickness sayı değilse ya da 1'in altındaysa 1px çizilir.",
194
+ "Kanvas toolbar'ı: direction · variant · thickness · color · isHidden."
173
195
  ],
174
196
  propNotes: {
197
+ label: 'Çizginin ortasındaki metin; yalnız yatayda çizilir. Sayı gelirse metne çevrilir.',
198
+ direction: "'horizontal' (varsayılan) | 'vertical'. Dikey çizginin kendi genişliği yoktur, hücresinde ortalanır.",
175
199
  variant: "'solid' | 'dashed' | 'dotted'.",
176
- color: "Beş semantik değer + 'custom' (customColor ile); boş bırakılırsa tema kenarlık rengi."
200
+ thickness: 'Çizgi kalınlığı px; en az 1. Kesikli/noktalı desende parça boyu da bununla büyür.',
201
+ color: "Beş semantik değer + 'custom' (customColor ile); boş bırakılırsa tema kenarlık rengi (--ng-border-primary). 'custom' seçilip customColor geçersiz/boşsa 'primary' tonuna düşer, kenarlık rengine DEĞİL.",
202
+ customColor: "Yalnız color 'custom' iken okunur; hex/rgb/hsl/adlandırılmış renk ya da tema token'ı. Hex/rgb tema değişimini izlemez, var(--ng-…) token'ı izler.",
203
+ style: 'Köke uygulanır; şemada parça seçicisi yok. Çizgi ve etiket kökteki CSS değişkenlerinden boyanır (--divider-color/--divider-width/--divider-style); style içinde bu değişkenler yazılırsa inline değeri EZER (designerCss !important), iç parçalara "& .ng-divider__line" / "& .ng-divider__label" ile ulaşılır.'
177
204
  }
178
205
  },
179
206
  spacer: {
180
- summary: 'Sabit ya da esnek boşluk. Çalışma anında GÖRÜNMEZ; yalnız editörde tarandı çizilir.',
207
+ summary: 'Boşluk bileşeni: sabit yükseklik (size px) ya da esnek itici. Çalışma anında GÖRÜNMEZ; yalnız editörde taralı çizilir. Olay YAYMAZ, içine bileşen bırakılmaz.',
181
208
  behavior: [
182
- "mode 'fixed' iken size kadar px yer kaplar; 'flex' iken kalan boşluğu doldurur (flex kapsayıcıda iki grubu uçlara itmenin yolu).",
183
- 'showInEditor kapatılırsa editörde de görünmez — sayfayı okurken boşluğun neden orada olduğu anlaşılmaz, açık bırakmak yeğdir.',
184
- "Kendi 'size' prop'u px'tir; kapsayıcının flex 'size' prop'uyla (shrink/grow) ilgisi yoktur."
209
+ "mode 'fixed' iken size kadar px YÜKSEKLİK kaplar, genişliği hep %100'dür. Satır (row) kapta yatay boşluk isteniyorsa ölçü size'dan değil düğümün genişliğinden gelir: appearance.widthType 'fixed' + widthString ('24px').",
210
+ "mode 'flex' iken düğüm flex kabın ANA ekseninde kalan alanı alır ve kardeşlerini uçlara iter (sütunda dikey, satırda yatay; wrap açıkken de aynı satırda kalır). 2026-09-18'den önce çalışma anında 0px'ti. Kabın ölçüsü ana eksende belirli olmalı — auto/hug yükseklikli bir sütunda kalan alan yoktur, spacer 0px kalır. Kabın kendi size prop'u 'grow' ise kardeşler de büyür ve kalan alan paylaşılır; itici etkisi için kap 'shrink' kalmalı.",
211
+ "12 kolonlu grid kapta hücre ölçer (blocks[].size.h × satır yüksekliği): 'fixed' size kadar çizilir, hücreden büyükse satırlar uzar; 'flex' kipi düğümün yüksekliği sabitlenmedikçe (appearance.heightType 'fixed'/'fill') 0px'tir, sabitlenince hücreyi doldurur ama kimseyi itmez. Spacer'ın yeri flex kaptır.",
212
+ 'showInEditor kapatılırsa editörde de görünmez — sayfayı okurken boşluğun neden orada olduğu anlaşılmaz, açık bırakmak yeğdir (Element Tree tek seçme yolu kalır).',
213
+ "Kendi 'size' prop'u px'tir; kapsayıcının flex 'size' prop'uyla (shrink/grow) ilgisi yoktur. size 0 geçerli ölçüdür (0px); temizlenmiş/boş değer 16'ya düşer."
185
214
  ],
186
- propNotes: { mode: "'fixed' (size px) | 'flex' (kalanı doldurur)." }
215
+ propNotes: {
216
+ mode: "'fixed' (size px yükseklik) | 'flex' (ana eksende kalanı doldurur, itici). 'flex' ortak katman sözleşmesidir: düğüm sarmalayıcısı flex 1 1 0 alır, appearance genişlik/yükseklik kipinden bağımsız.",
217
+ size: "Yalnız 'fixed' kipte okunur; px, min 0. Yatay boşluk için düğüm genişliği (appearance.widthString) kullanılır, size değil.",
218
+ showInEditor: 'Editördeki taralı iz; runtime her zaman görünmez.'
219
+ }
187
220
  },
188
221
  popover: {
189
- summary: 'Tetikleyici butondan açılan yüzen panel; İÇİNE komponent bırakılır (droppable).',
222
+ summary: 'Tetikleyici butondan açılan yüzen panel; İÇİNE komponent bırakılır (droppable). Modal/drawer gibi kök çerçeve DEĞİLDİR: sayfa ızgarasında normal bir düğümdür, panel tetikleyicinin yanında açılır.',
190
223
  behavior: [
191
- "trigger 'click' ya da 'hover' olabilir; editör kipinde tetikleme çalışmaz (tasarımcı içeriği düzenleyebilsin diye).",
192
- "isOpen çift yönlüdür: açılış/kapanış olayları setter'dır (self.isOpen yazılır), dolayısıyla akış da isOpen'ı yazarak paneli açıp kapatabilir.",
193
- 'closeOnOutside kapatılırsa panel yalnız tetikleyiciyle ya da akışla kapanır.'
224
+ "trigger 'click' ya da 'hover' olabilir; editör kipinde tetikleme çalışmaz ve panel HER ZAMAN açık, akış içinde çizilir (tasarımcı içeriği düzenleyebilsin diye) — gerçek konumlanma yalnız önizleme/çalışma anındadır.",
225
+ "isOpen çift yönlüdür: tetikleyici yolu open/close olayını setter'la yayar (self.isOpen yazılır); akış isOpen'ı yazınca da (2026-09-18'den beri) aynı open/close olayı çıkar, bu kez setter'sız. İlk çizimde olay yok. Yani open'a bağlı bir akış (örn. detay yükle) panel nasıl açılırsa açılsın çalışır.",
226
+ "Panel çocukları panelWidth px genişliğinde bir kutuda 12 sütunlu ızgaraya dizer (varsayılan 320). Eskiden genişlik içeriğe göre 200–320 arası büzülüyordu; editördeki yerleşim çalışma anıyla uyuşmuyordu. Panel tetikleyicinin yanında SAF CSS ile durur: ekran kenarına sığmazsa ÇEVRİLMEZ/kaydırılmaz, taşar; position'ı yerleşime göre seç.",
227
+ "Panel portal'a taşınmaz: overflow:hidden bir atada ya da düğümün kendi surfaceStyle taşması 'hidden' iken kırpılır. Popover'ı taşan kapsayıcının dışına koy, düğümün Surface taşmasını açık bırak.",
228
+ "closeOnOutside panelde yalnız trigger 'click' iken gösterilir (hover kipinde gizlidir; runtime kayıtlı değeri her kipte okur). Kapatılırsa panel yalnız tetikleyici, Escape ya da akışla kapanır. Escape her zaman kapatır. Hover kipinde 250 ms tolerans vardır (tetikleyiciden panele geçerken kapanmaz); klavye odağı da hover kipinde açar/kapatır.",
229
+ "isDisabled tetikleyiciyi kilitler (tıklama/hover açmaz, düğme disabled); akışın isOpen yazması etkilenmez. triggerText boş ve triggerIcon dolu ise düğme yalnız ikon çizer; ikisi de boşsa sözlükteki 'Toggle/Aç-kapat' metni yazılır.",
230
+ "Panel yeniden yerleştirilmez: modal'daki gibi overlay/odak kapanı yoktur, arka plan tıklanabilir kalır. Sayfa akışını kesecek bir onay için modal kullan; satır detayı/hızlı form için popover."
194
231
  ],
195
232
  propNotes: {
196
233
  surfaceStyle: NODE_SURFACE_NOTE,
197
- position: 'Panelin tetikleyiciye göre yönü; yer yoksa kaydırılır.',
198
- isOpen: "Açık/kapalı durumu; open/close olaylarıyla geri yazılır."
234
+ triggerText: "Tetikleyici düğme metni. Boş bırakılıp triggerIcon verilirse yalnız ikon çizilir.",
235
+ trigger: "'click' (tıkla aç/kapat) | 'hover' (üzerine gelince açılır, ayrılınca 250 ms sonra kapanır).",
236
+ position: "'bottom' | 'top' | 'right' | 'left' — panelin tetikleyiciye göre yönü. Saf CSS: yer yoksa çevrilmez, taşar.",
237
+ panelWidth: 'Panel kutusunun genişliği px (160–1200, varsayılan 320; aralık dışı değer kırpılır, sayı olmayan/boş değer 320). Çocuklar bu genişlik içinde 12 sütuna dizilir; kart için 320–400, küçük form için 400–560 iyi başlangıçtır.',
238
+ isDisabled: 'Tetikleyici kilidi; açık paneli kapatmaz, akışın isOpen yazmasını engellemez.',
239
+ closeOnOutside: "Panelde yalnız trigger 'click' iken gösterilir; kapalıysa dışarı tıklamak paneli kapatmaz.",
240
+ style: "Köke uygulanır; parça seçicileri '&__trigger' (düğme) ve '&__panel' (kutu) ile düğme ve panel ayrı boyanır.",
241
+ isOpen: "Açık/kapalı durumu; open/close olaylarıyla geri yazılır, akıştan yazılınca da olay çıkar. Editörde etkisizdir (panel hep açık), önizlemenin başlangıç durumunu belirler."
199
242
  }
200
243
  },
201
244
  phoneinput: {
@@ -222,26 +265,37 @@ export const componentKnowledge = {
222
265
  summary: 'İç içe and/or filtre kuralları kurar ve akışa HEM kural ağacını HEM hazır jexl ifadesini verir.',
223
266
  behavior: [
224
267
  "change olayının yükünde iki alan vardır: 'value' (ağaç) ve 'jexl' (aynı ağacın ifadesi). setter YALNIZ value'yi self'e yazar; jexl yalnız event.data'dadır — sorguya bağlanacak alan odur.",
225
- 'fields dizisi kullanıcıya sunulan alan sözlüğüdür; tipi (text/number/date/dropdown) operatör listesini belirler.',
226
- 'Her kural değişikliğinde change yayılır — sorguyu her tuşta yeniden koşturmak istemiyorsan akışta gecikme kur.'
268
+ 'fields dizisi kullanıcıya sunulan alan sözlüğüdür; tipi operatör listesini belirler (ağaçta operatör ANAHTARI durur, ekrandaki etiket değil): text → eq, neq, contains, notContains, empty, notEmpty · number → eq, neq, gt, gte, lt, lte, between, empty, notEmpty · date → on, before, after, between, empty, notEmpty · select → eq, neq, empty, notEmpty. Sayı alanında operatörler sembolle çizilir (= ≠ > ≥ < ≤ ⟷), doluluk ikilisi metinle.',
269
+ 'Her kural değişikliğinde change yayılır — sorguyu her tuşta yeniden koşturmak istemiyorsan akışta gecikme kur.',
270
+ 'Yarım bırakılan kural ekranda kalır ama jexl çıktısına girmez; sayı alanına sayı olmayan bir değer ya da tipe uymayan bir operatör yazılırsa da girmez. Boş ağaç boş string üretir (filtre yok) — sorguda "jexl boşsa filtre uygulama" dalını kur.',
271
+ 'Kural ağacı çalışma anı durumudur, sayfa tasarımının parçası değil: preview yenilenince sıfırlanır. Kalıcılık için value prop’unu bir State’e bağla.'
227
272
  ],
228
273
  propNotes: {
229
- fields: '[{ label, field, type, options }] — options yalnız dropdown tipinde, virgülle ayrılmış metin.',
230
- value: 'Kural ağacı; gizlidir ve setter ile yazılır.'
274
+ fields: '[{ label, field, type, options }] — type: text|number|date|select (varsayılan text); options yalnız select tipinde okunur, virgülle ayrılmış metin. Aynı field iki satırda tekrarlanırsa ikincisi yok sayılır.',
275
+ value: 'Kural ağacı; gizlidir ve setter ile yazılır. Düğüm kimlikleri (id) ağaçta korunur; aynı kimliği iki düğüme verirsen ikincisine yenisi atanır.',
276
+ showClear: 'Kuralların altına "Tümünü temizle" düğmesi koyar (varsayılan açık); basıldığında ağaç boşalır ve boş jexl ile change yayılır. Ağaç zaten boşken düğme pasiftir.',
277
+ size: 'Kural satırlarının puntosu (sm|md|lg); boş bırakılırsa md.',
278
+ isReadonly: 'Kurallar görünür kalır, hepsi kilitlenir; olay yayılmaz.',
279
+ isViewmode: 'Kurallar çerçevesiz düz metne iner (kayıt görüntüleme ekranı): VE/VEYA düğme çifti yerini etkin birleştiricinin düz metnine bırakır, ekle/kaldır ve temizle düğmeleri çizilmez.'
231
280
  }
232
281
  },
233
282
  comments: {
234
283
  summary: '@bahsetmeli, iç içe yanıtlı yorum akışı; gönderilen her yorumu akışa devreder.',
235
284
  behavior: [
236
- 'İYİMSER KATMAN: gönderilen yorum, beğeni ve silme ANINDA arayüze yansır ama HİÇBİRİ kalıcı değildir — uca yazmak akışın işidir.',
285
+ 'İYİMSER KATMAN: gönderilen yorum, beğeni, DÜZENLEME ve silme ANINDA arayüze yansır ama HİÇBİRİ kalıcı değildir — uca yazmak akışın işidir. Düzenlenen yorum yeni metinle, soluk ve "düzenlendi" işaretiyle görünür.',
237
286
  'Bekleyen katman yalnız rows İÇERİĞİ değiştiğinde temizlenir (referans değişimi yetmez). Akış kaydettikten sonra rows tazelenmezse bekleyen satır bir sonraki içerik değişiminde kaybolur.',
238
- 'people listesi @bahsetme önerilerini besler; submit yükündeki mentions bu listeye göre çözülmüş adlardır.',
239
- 'ownOnly açıkken düzenleme/silme yalnız currentUser’ın kendi yorumlarında görünür — yetki KONTROLÜ değil, arayüz filtresidir; asıl kontrol uçtadır.'
287
+ 'Yorum silinince altındaki her yanıt da ekrandan gizlenir; delete yükü yalnız kök id taşır — yanıtları silmek (ya da bırakmak) akışın/servisin kararıdır.',
288
+ 'Yanıt tek seviyedir: yanıt düğmesi yalnız kök yorumda çıkar, yanıtın yanıtı yoktur.',
289
+ 'people listesi @bahsetme önerilerini besler; submit yükündeki mentions bu listeye göre çözülmüş adlardır. Listede olmayan @ad düz metin kalır.',
290
+ 'ownOnly açıkken düzenleme/silme yalnız currentUser’ın kendi yorumlarında görünür — yetki KONTROLÜ değil, arayüz filtresidir; asıl kontrol uçtadır.',
291
+ 'Kilitler: isDisabled yazma kutusunu soluk (yazılamaz) gösterir; isReadonly ve isViewmode kutuyu hiç çizmez. Üçünde de yanıtla/düzenle/sil gizlenir, beğeni sayacı görünür ama tıklanmaz (like yayılmaz).',
292
+ 'Tekrarlanan id’de ilk satır id’sini korur, sonrakiler "<id>#<sıra>" olur ve olay yükleri bu uydurma id’yi taşır (uç tanımaz) — id benzersiz verilmeli.'
240
293
  ],
241
294
  propNotes: {
242
- rows: '[{ id, author, text, createdAt, parentId, avatar, likeCount, likedByMe }] — parentId dolu olan satır yanıttır.',
243
- currentUser: 'Yorum sahipliğini ve ownOnly filtresini belirleyen ad; boşsa düzenleme/silme gizlenir.',
244
- people: '@bahsetme önerileri (virgülle ayrılmış).'
295
+ rows: '[{ id, author, text, createdAt, parentId, avatar, likeCount, likedByMe }] — parentId dolu olan satır yanıttır. createdAt ISO metni, "YYYY-AA-GG" ya da Unix zaman damgası (10 hane saniye / 13 hane milisaniye) olabilir; boş author+text satırı atlanır.',
296
+ currentUser: 'Yorum sahipliğini ve ownOnly filtresini belirleyen ad; tüm olay yüklerindeki author budur (yorumun sahibi DEĞİL, işlemi yapan). Boşsa düzenleme/silme ownOnly açıkken gizlenir.',
297
+ people: '@bahsetme önerileri: virgülle ayrılmış metin ya da ad dizisi ({{ users.map((u) => u.name) }}).',
298
+ placeholder: 'Boşsa dile göre "Yorum yaz… (@ ile birini an)" gösterilir; yanıt kutusu da aynı metni kullanır.'
245
299
  }
246
300
  },
247
301
  aibox: {
@@ -269,6 +323,8 @@ export const componentKnowledge = {
269
323
  behavior: [
270
324
  "states.isWrapper:true iken salt düzen elemanıdır: title ve __header bloğu ÇİZİLMEZ, zemin/çerçeve taşımaz ve gövdesi dolgusuzdur — kart başlığı gerekiyorsa içine text komponenti koy (platform_guide('page') Bilinen sınırlar). Bu kip artık bileşenin kendi CSS'inde: tipli alanlar (surfaceStyle) sayfa köküne de zemin/çerçeve verebilir.",
271
325
  "KATMAN SIRASI (K4): tema componentStyles → $preset TABANDIR; tipli grup alanları temayı alan alan EZER; düğümün serbest style'ı SON SÖZDÜR. Yüzey/tipografi/hover/başlık kararlarını style'a ham CSS olarak yazma — alanı varsa gruba yaz.",
326
+ "BAŞLIK BANDI title YA DA description doluyken çizilir (2026-09-18): description başlığın altındaki ikinci satırdır (ikincil metin rengi, küçük punto) ve yalnız açıklama yazmak da bandı açar. İki alan da KIRPILIR: yalnız boşluktan ibaret bir başlık/açıklama doldurulmamış sayılır ve bant açılmaz. states.isWrapper:true iken ikisi de çizilmez.",
327
+ "KANVASTA BIRAKMA ALANI HİÇBİR DURUM PROP'UYLA ÖLMEZ (2026-09-18): isLoading gövdeyi 100px'e kırpar ve slot'u pointer-events:none yapar ama yalnız çalışma anında/önizlemede — editörde (_editorMode) sadece yükleyici çizilir, tasarımcı kabın içine bileşen bırakmaya devam eder. Yükleyici akış DIŞINDA, konumlandırılmış bir kaplamadır ve tıklamayı geçirir: akış içinde çizildiğinde bırakma alanını görünür kutunun altına itiyordu. Kanvas toolbar'ında iki düğme vardır (Loading, Is hidden); yerleşim kontrollerini kanvasın kendi kap toolbar'ı çizer.",
272
328
  "page_container'ın isLoading prop'u sayfa açılış akışının yükleniyor bayrağıdır.",
273
329
  "layout:'flex' çocukları akışa alır (RenderComponent düzeni .ng-app__node-children sarmalına yazar): sıra blocks[].position'dan gelir (önce y, sonra x) ama y BOŞLUKLARI yok sayılır — flex'te dikey konum yalnız sıradır, ızgara koordinatı değil.",
274
330
  "Flex çocuğun GENİŞLİĞİ appearance.widthType'tan gelir (2026-09-01): 'fill' kabın tüm genişliği (satırda flex:1 1 100%), 'fixed' + widthString sabit CSS ölçüsü ('240px'/'50%'/calc), 'auto' içerik kadar. widthType HİÇ yazılmamışsa eski 12 kolonluk blocks[].size.w payı geçerlidir (row'da flex-basis w/12, column'da width w/12) — ızgara↔flex geçişi bu fallback sayesinde kayıpsızdır. Şemayı sen kuruyorsan widthType'ı AÇIKÇA yaz; string yalnız 'fixed' modda okunur (PAGE-017/018 uyarıları).",
@@ -283,7 +339,7 @@ export const componentKnowledge = {
283
339
  surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens + " Kapsayıcının TABANI tema token'larıdır (--ng-background-surface zemin, 1px --ng-border-primary çerçeve, --ng-rounded köşe); alan boş bırakılırsa tema izlenir. contentOverflow gövdeye ('&__body') yazılır.",
284
340
  typographyStyle: STYLE_GROUP_NOTES.typographyStyle + ' ' + STYLE_GROUP_NOTES.colorTokens,
285
341
  hoverStyle: STYLE_GROUP_NOTES.hoverStyle,
286
- headerStyle: "{ titleColor, titleSize(CSS uzunluğu), titleWeight(400|500|600|700), divider(bool — false BAŞLIK ÇİZGİSİNİ KALDIRIR, yok saymaz), dividerColor, padding(CSS kutu değeri: '12px' | '8px 16px' | 'var(--ng-spacing-md)'; varsayılanı boşluk ölçeğinden 'var(--ng-spacing-sm) var(--ng-spacing-md)'), minHeight(CSS uzunluğu; bileşenin 41px tabanını kaldırmak için '0'), align(flex-start|center|flex-end), margin(CSS kutu değeri; bandı içeriden almak ya da altına boşluk bırakmak için) }. Alanların HEPSİ varsayılan taşır (titleColor var(--ng-text-primary), titleSize calc(var(--ng-font-size) * 1.4), titleWeight '600', dividerColor var(--ng-border-primary)) — düğüm kurulurken props'a yazılırlar, yani component_get'teki defaults başlığın gerçek görünümüdür. Boyut alanlarında METİN '0' gerçek seçimdir ve bileşenin tabanını kaldırır (sayı 0 'seçilmedi' sayılır). Başlık yalnız title doluyken VE düğüm sarmalayıcı değilken çizilir.",
342
+ headerStyle: "{ titleColor, titleSize(CSS uzunluğu), titleWeight(400|500|600|700), divider(bool — false BAŞLIK ÇİZGİSİNİ KALDIRIR, yok saymaz; alan BOŞ bırakılırsa bileşenin tabanı çizer, yani boş ile false AYNI ŞEY DEĞİLDİR ve panelin kutusu ikisini de işaretsiz gösterir), dividerColor, padding(CSS kutu değeri: '12px' | '8px 16px' | 'var(--ng-spacing-md)'; varsayılanı boşluk ölçeğinden 'var(--ng-spacing-sm) var(--ng-spacing-md)'), minHeight(CSS uzunluğu; bileşenin 41px tabanını kaldırmak için '0'), align(flex-start|center|flex-end), margin(CSS kutu değeri; bandı içeriden almak ya da altına boşluk bırakmak için) }. Alanların HEPSİ varsayılan taşır (titleColor var(--ng-text-primary), titleSize calc(var(--ng-font-size) * 1.4), titleWeight '600', dividerColor var(--ng-border-primary)) — düğüm kurulurken props'a yazılırlar, yani component_get'teki defaults başlığın gerçek görünümüdür. Boyut alanlarında METİN '0' gerçek seçimdir ve bileşenin tabanını kaldırır (sayı 0 'seçilmedi' sayılır). Bant title YA DA description doluyken VE düğüm sarmalayıcı değilken çizilir.",
287
343
  layout: "'flex' (katalog varsayılanı; akış) | 'grid' (12 kolonluk ızgara). Prop hiç yazılmamışsa renderer IZGARA çizer — varsayılan yalnız düğüm kurulurken materyalize olur. Aşağıdaki altı prop YALNIZ 'flex' iken etkilidir.",
288
344
  direction: "'row' (varsayılan) | 'column' → flex-direction. Hangi hizalamanın ana eksen olduğunu bu belirler.",
289
345
  horizontalAlign: "left | center | right | stretch. row'da ANA eksen (justify-content), column'da ÇAPRAZ eksen (align-items). stretch: ana eksende space-between, çapraz eksende tam doldurma.",
@@ -292,15 +348,26 @@ export const componentKnowledge = {
292
348
  gap: "none | small | medium (varsayılan) | large → tema değişkenleri: 0 / var(--ng-spacing-sm) / --ng-spacing-md / --ng-spacing-lg (varsayılan temada 8/16/32px). Alan allowCustom'dır: '18px' ya da 'var(--ng-spacing-xl)' gibi ham CSS değeri de geçer. Çocuk genişlik formülünden payı düşülür, böylece w toplamı 12 olan satır tam kapanır.",
293
349
  wrap: "flex-wrap: wrap. Varsayılan AÇIK (2026-09-01'de flipledi): w:12 çocuklar alt satıra sararak dikey akar. Kapatırsan satıra sığmayan çocuklar sıkışır, alta inmez.",
294
350
  title: "Varsayılanı boştur. isWrapper:false kapta yalnız açıkça doluysa başlık çizer; page_container'da ise dolu değer tarayıcı sekmesinin adını yazar (browserTitle).",
295
- isLoading: 'Gövdeyi 100px’e kısar ve spinner gösterir; sayfa açılış akışında bayrak olarak kullanılır.'
351
+ description: "Başlığın ALTINDAKİ ikinci satır (2026-09-18): ikincil metin renginde, başlıktan küçük punto. Varsayılanı boştur ve boşken eleman hiç çizilmez, bandın yüksekliğini değiştirmez. Yalnız description yazmak başlık bandını açar (title boş kalabilir); sarmalayıcı kipte (page_container, yerleşim kökü) title gibi o da çizilmez. Kart başlığının altına açıklama yazmak için artık içine text bileşeni bırakmak gerekmez.",
352
+ isLoading: "Gövdeyi 100px'e kısar, slot'u gizler ve spinner gösterir — ama YALNIZ çalışma anında ve önizlemede. Kanvasta (editör kipi) gövde kırpılmaz, yalnız yükleyici çizilir ve bırakma alanı çalışmaya devam eder (2026-09-18). page_container'da sayfa açılış akışının yükleniyor bayrağıdır; kanvas toolbar'ından tek tıkla açılır."
296
353
  }
297
354
  },
298
355
  repeater: {
299
- summary: 'Kart listesi: rows dizisindeki her satır için children şablonunu yineler; satır bağlamı item/Row olarak çocuklara iner.',
356
+ summary: 'Kart listesi: rows dizisindeki her satır için children şablonunu yineler, satırları columnCount kolonlu bir ızgaraya dizer; satır bağlamı item/Row (sırası RowIndex) olarak çocuklara iner.',
357
+ behavior: [
358
+ "SEÇİM İKİ YOLDAN YAZILIR, ikisi de self.selectedIndex'e: (1) satırın HERHANGİ bir yerine tıklama — her tıklamada `select`, satır değiştiyse önce `change`; (2) satırdaki bir çocuğun yaydığı olay (buton click, girdi change/focus…) — satır değiştiyse `change`. Yalnız text/image taşıyan kart da tıklamayla seçilir (2026-09-15'ten önce ancak olay yayan bir çocukla seçilebiliyordu). İSTİSNA: tıklamayı kendisi yutan etkileşimli çocuklar (dropdown-button, collapsible-container, tag-input, tarih seçici, dosya girdileri, tree-view, table) satıra ulaştırmaz — orada select gelmez, seçim yalnız o çocuk olay yayarsa change ile yazılır. Etikete tıklamak (switch/checkbox/radio) tek tıklama sayılır. Satırdaki butona tıklanınca akışların BAŞLAMA sırası: repeater `change` → butonun click akışı → repeater `select` (akışlar asenkron, bitiş sırası garanti değil); butonun akışında <repeater>.selectedIndex zaten o satırdır. Butonun akışı satırı SİLER ya da selectedIndex'e null yazarsa, ardından gelen select eski sırayla yayılır ve selectedIndex'i yeniden yazar — silme/temizleme akışını butona bağla, repeater'ın select'ine iş bağlama.",
359
+ "SEÇİLİ SATIRIN VERİSİ `selectedItem`'dır (şema prop'u DEĞİL, runtime türetir): `{{ <repeater>.selectedItem.<alan> }}` ve akışta self.selectedItem. selectedIndex yazılmamışken İLK SATIRI (rows[0]) döndürür — 'henüz seçim yok' ile 'ilk satır seçili'yi ayırmak için selectedIndex'e bak (sayı değilse seçim yok). rows yenilenince selectedIndex SIFIRLANMAZ; eski sıra yeni listede başka satırı gösterebilir, gerekiyorsa sorgu akışında selectedIndex'i null yaz.",
360
+ "rows dizi DEĞİLSE (henüz koşmamış sorgu, null yazan akış) liste boş çizilir, sayfa düşmez; aynı _id/id'yi taşıyan satırlar da çizilir AMA çocuk girdilerin satır başına değerleri o kimliğe göre tutulduğu için bu satırlar yazılan değeri PAYLAŞIR — girdi taşıyan kartlarda id'ler benzersiz olmalı. Boş liste için ayrı bir emptystate bileşeni koy ve isHidden'ını `{{ (<repeater>.rows || []).length > 0 }}` yap — repeater'ın kendi boş durum metni yok.",
361
+ "Izgara: columnCount kolon (en az 1), kartlar arası dikey boşluk verticalSpacing (px, yazılmazsa 20), yatay boşluk horizontalSpacing (px, yazılmazsa 0). autoRowSize:false iken bütün satırlar EN UZUN kart kadar yüksek (1fr); true iken her satır kendi içeriği kadar. Boş/null boşluk varsayılana düşer."
362
+ ],
300
363
  propNotes: {
301
364
  surfaceStyle: NODE_SURFACE_NOTE,
302
- rows: 'Yinelenen veri; çocuk komponent ifadelerinde satıra item / Row ile erişilir.',
303
- selectedIndex: "Satırdaki bir çocuk (ör. buton) olay yayınca RenderComponent `change` ile yazar; akışta self.selectedIndex ile okunur, `{{ <repeater>.selectedIndex }}` ile başka bileşene bağlanır. Şemada gizli durum prop'udur (panelde çizilmez). 2026-09-09'a kadar runtime'daki ters koşul yüzünden HİÇ yazılmıyordu (gerçek ekranda ölçüldü, düzeltildi); eski gizli selectedItem alanı da aynı gün kaldırıldı, kimse okumuyordu."
365
+ rows: "Yinelenen veri; çocuk komponent ifadelerinde satıra item / Row ile, satırın sırasına RowIndex ile (0'dan başlar) erişilir. Satırlara kalıcı bir id ya da _id ver: girilen değerler ve kart örnekleri ona göre eşlenir.",
366
+ columns: "YALNIZ Studio'daki Rows düzenleyicisinin alanlarını tanımlar; runtime OKUMAZ. Kartta ne görüneceğini repeater'ın children'ı ve onların `{{ item.<alan> }}` ifadeleri belirler — columns yazmak kartı değiştirmez.",
367
+ columnCount: 'Bir satırdaki kart sayısı (tam sayı, en az 1; 0/boş 1 sayılır).',
368
+ verticalSpacing: 'Kart satırları arası boşluk, px. Yazılmazsa 20 (şema varsayılanı; 2026-09-15 öncesi yazılmamış düğüm 0 çiziyordu).',
369
+ horizontalSpacing: 'Yan yana kartlar arası boşluk, px. Yazılmazsa 0.',
370
+ selectedIndex: "Tıklanan/olay yayan satırın sırası (0'dan). Runtime `change` ve `select` ile yazar; akışta self.selectedIndex, başka bileşende `{{ <repeater>.selectedIndex }}`. Şemada gizli durum prop'udur (panelde çizilmez); akış yazarak seçimi değiştirebilir ya da null yazıp temizleyebilir. Seçili satırın verisi için behavior'daki selectedItem maddesine bak."
304
371
  }
305
372
  },
306
373
  modal: {
@@ -453,7 +520,30 @@ export const componentKnowledge = {
453
520
  isLoading: "Alanı dondurur (readonly, gri değil; artı/eksi pasif, olay yayılmaz) ve sağda dönen spinner çizer; changed'e bağlı sorgu sürerken aç, tamamlanınca kapat."
454
521
  }
455
522
  },
456
- incrementalinput: { summary: 'Otomatik kod üretici (önek + ayraç + sayaç); bir sonraki kodu runtime’da çeker.' },
523
+ incrementalinput: {
524
+ summary: 'Otomatik kod alanı: önek + ayraç + sıfır dolgulu sayaç (INV-0001); sıradaki kodu runtime’da sunucudan çeker. Sayısal stepper DEĞİLDİR — artır/azalt için numberinput.',
525
+ behavior: [
526
+ 'Sunucu isteği YALNIZ runtime rotalarında atılır (/preview, /view, /dev, /branch) ve ilki 1 sn gecikmeyle gider; tasarım kanvasında hiç atılmaz. Kanvasta alan boş kalır, üretilecek kod YER TUTUCU olarak önizlenir (önek/ayraç/sayaç/hane böylece kanvasta görünür).',
527
+ 'İstek POST entities/{entityId}/row/next-code — entity + alan (field) seçilmeden, sayaç ya da hane 0 iken, ya da önek varken ayraç boşken hiç gitmez. Önek BOŞ olabilir: o zaman ayraç da düşer ve kod yalnız sayaçtır.',
528
+ 'change olayı İKİ farklı yük taşır: sunucudan kod gelince değer NESNEdir ({ Prefix, Separator, Counter, DigitCount, FieldId }) — kodun metni değil kodu ÜRETEN şekil; kullanıcı elle yazınca değer düz METİNdir. self.value okuyan akış ikisini de karşılamalı.',
529
+ 'Elle yazılan değer korunur: yazmaya başlandıktan sonra dönen sunucu yanıtı atılır, alan yeniden yazılmaz. Aynı entity/alan/şekil için istek bir kez atılır (şekil değişirse yenilenir).',
530
+ 'next-code isteği başarısız olursa alan invalid görünür ve hata metni invalidText’in YERİNE yazılır — panelde isInvalid kapalı olsa bile.',
531
+ 'Dört kip ekranda ayrı görünür: isDisabled gri + tıklanamaz, isReadonly okunur zemin, isViewmode çerçevesiz düz metin (önizleme de çizilmez), isLoading alanı dondurur ve sağda spinner döndürür. İstek sürerken bileşen isLoading görünümünü KENDİSİ açar.'
532
+ ],
533
+ propNotes: {
534
+ value: 'Ya sunucudan gelen şekil nesnesi ya da elle yazılmış metin (davranışa bak). Kayıtlı satır nesneyi saklar, ekranda kodun metni görünür.',
535
+ prefix: 'Kodun başındaki sabit ek (INV). Boş bırakılabilir; boşsa ayraç da yazılmaz.',
536
+ separator: 'Önek ile sayaç arasındaki ayraç. Önek varsa ZORUNLUDUR — boşsa kod hiç üretilmez.',
537
+ counter: 'Sayacın başlangıç değeri (en az 1). Sıradaki numarayı backend belirler; bu değer isteğin başlangıç noktasıdır.',
538
+ digitcount: 'Sayacın kaç haneye sıfırla doldurulacağı (en az 1): 4 → 0001.',
539
+ autoFetchNextCode: 'Kapalıyken istek atılmaz VE önek/ayraç/sayaç/hane hiç okunmaz — alan düz bir metin girdisine döner, kanvas önizlemesi de kaybolur.',
540
+ field: 'Kodun hangi tablonun hangi alanı üzerinden ilerleyeceği (entity + alan). Seçilmeden otomatik çekme çalışmaz.',
541
+ placeholder: 'Alan boşken görünen metin. Otomatik çekme açıkken önizlenen kod bunu EZER; buradaki metin yalnız otomatik çekme kapalıyken görünür.',
542
+ prefixIcon: "Alanın İÇİNDE solda çizilen salt görsel ikon ({ name: 'tag' }); value'ya karışmaz. Viewmode'da çizilmez.",
543
+ suffixIcon: "Alanın içinde sağda çizilen ikon; yükleniyor spinner'ının sağında durur. Viewmode'da çizilmez.",
544
+ isLoading: "Alanı dondurur (readonly, gri değil) ve sağda dönen spinner çizer; next-code isteği sürerken bileşen kendisi açar, akıştan kod beklerken elle aç."
545
+ }
546
+ },
457
547
  password: {
458
548
  summary: 'Parola girişi; karakterleri maskeler, sağdaki göz düğmesi geçici olarak açar. Olay sözleşmesi textinput ile aynı.',
459
549
  behavior: [
@@ -627,10 +717,86 @@ export const componentKnowledge = {
627
717
  isLoading: 'Akıştan açılır; alan kilitlenmez, yalnız spinner çizilir ve kök aria-busy taşır.'
628
718
  }
629
719
  },
630
- fileUpload: { summary: 'Sürükle-bırak dosya yükleme (dropzone); seçim self.value’dan okunur.' },
631
- fileInput: { summary: 'Dosya seç girişi; change yükü { value: [{ type, value }], fileName }.' },
632
- filebutton: { summary: 'Buton görünümlü dosya seçici; fileInput ile aynı yük.' },
633
- 'file-viewer': { summary: 'Dosya önizleyici (pdf/görsel); file prop’una drive dosyası bağlanır.', propNotes: { surfaceStyle: NODE_SURFACE_NOTE } },
720
+ fileUpload: {
721
+ summary: 'Sürükle-bırak yükleme ALANI (dropzone): büyük bir hedef kutu, tıklayınca da dosya penceresi açar, seçilenleri silinebilir çip listesi olarak gösterir ve görselleri kırpabilir. Tek satırlık alan için fileInput, düz buton için filebutton. Seçim self.value’dan okunur.',
722
+ behavior: [
723
+ "Komponentin YAYDIĞI value her zaman DİZİDİR: [{ value: base64 data URL, fileName, type: 'file', ref: '' }]. isMultiple:false iken tek elemanlı dizi — nesne değil. Akış tek nesne ya da düz URL metni yazarsa da liste çizilir (2026-09-17'ye kadar hiç çizilmiyordu).",
724
+ 'Çipe tıklamak o dosyayı listeden siler ve change olayını KALAN listeyle yayar; ayrı bir silme olayı yoktur. Kilitliyken (isDisabled/isReadonly/isViewmode) ne ekleme ne silme olur, sürükleme de tepki vermez.',
725
+ 'allowedFiletypes KAPALI bir uzantı listesidir: seçilmeyen uzantı dosya penceresinde de görünmez, sürüklenirse reddedilir ve komponentin içinde tür uyarısı çizilir. jpg ve jpeg AYRI satırdır — ikisini de kabul edeceksen ikisini de seç. Listede HİÇ olmayan bir uzantı için customFiletypes metin alanına yaz ("heic, p7m" — virgül/boşluk/noktalı virgül ayırır, baştaki . ve * atılır, küçük harfe iner); iki kaynak birleşir. İkisi de boşsa her tür serbesttir.',
726
+ 'maxFileSizeMb / maxFileCount yalnız kullanıcıya hızlı geri bildirimdir, sunucu tarafını bağlamaz. 0, negatif ya da boş değer SINIRSIZ demektir. Sınıra takılan dosya listeye girmez, geçenler girer (hepsi ya da hiçbiri değil); boyut ihlali adet ihlalinin önüne geçer. Adet sınırı çok seçimde zaten seçili dosyaları da sayar.',
727
+ 'enableCrop açıkken bırakılan GÖRSELLER sırayla kırpma katmanından geçer (cropAspectRatio çerçeveyi belirler ve yalnız enableCrop açıkken panelde görünür); Onay kırpılmış base64, Atla orijinal, İptal dosyayı düşürür. Tek seçim kipinde fazladan bırakılan dosyalar kırpma sırasına hiç girmez.',
728
+ 'title ve droped_title HTML kabul eder (<strong> vurgusu), description/droped_description düz metindir; droped_* metinleri yalnız dosya alanın ÜZERİNDEYKEN görünür. Varsayılan metindeki "Maximum file size 50 MB." sadece yazıdır — sınırı maxFileSizeMb uygular.',
729
+ 'Doğrulama: required ve pattern. isInvalid/invalidText Form’un merkezi hatasıdır; komponentin kendi tür ve sınır uyarıları ondan ayrı çizilir.'
730
+ ],
731
+ propNotes: {
732
+ value: "Panelde GİZLİ (.hide()): değeri elle yazmak yerine akıştan bağla ya da change'den sonra self.value ile oku. Akış dizi yerine tek nesne ya da düz URL metni yazarsa da çip çizilir (metinde ad son yol parçasından alınır).",
733
+ customFiletypes: "allowedFiletypes listesinde HİÇ olmayan uzantılar için serbest metin: 'heic, p7m' (virgül/boşluk/noktalı virgül ayırır). İki kaynak birleşir; fileInput'taki aynı adlı prop'la aynı sözleşme.",
734
+ size: "sm | md | lg — metin ve ikon ölçeğini değiştirir; boş bırakılırsa uygulamanın form boyutu geçerlidir (2026-09-17 öncesinde hiçbir etkisi yoktu).",
735
+ isMultiple: 'Kapalıyken yeni seçim eskisinin YERİNE geçer, listeye eklenmez.',
736
+ cropAspectRatio: "'1:1' | '4:3' | '3:4' | '16:9'; yalnız enableCrop açıkken okunur."
737
+ }
738
+ },
739
+ fileInput: {
740
+ summary: 'Klasik dosya SEÇME alanı: etiket + seçilen dosyanın çipi + Gözat butonu. Seçim change ile düğümün kendi prop’una yazılır, akış self.value ile okur.',
741
+ behavior: [
742
+ 'change yükü TEK anahtar taşır: { value }. Tek dosyalık alanda value bir NESNEDİR — { type: file, fileName, value: base64 data URL }; isMultiple açıkken aynı nesnelerden oluşan bir DİZİDİR ve yeni seçim eskilerin üstüne EKLENİR (değiştirmez). X ile boşaltmak tek dosyada { type: ref, value: null }, çoklu seçimde bunun tek elemanlı dizisini yazar. Çoklu kipte açılır listedeki satır × de change yayar ve yükü KALAN TÜM listedir; son dosya da silinince yine boşaltma değeri yazılır. fileName ÜST DÜZEY bir anahtar DEĞİLDİR (2026-09-17’ye kadar kayıt öyle diyordu): dosya adı value’nun içindedir, akış self.value.fileName ile okur.',
743
+ 'Tür kapısı 2026-09-17’de bileşenin kendisine kondu: allowedFiletypes listesi ile customFiletypes metni tek bir uzantı listesine iner, listede olmayan uzantı — ve liste doluyken uzantısız dosya — REDDEDİLİR, alanın altında desteklenmeyen tür mesajı çizilir ve change yayılmaz. Öncesinde yalnız input accept özniteliği yazılıyordu; o da işletim sisteminin dosya diyaloğuna İPUCUDUR, Tüm dosyalar seçen kullanıcı yasaklı türü içeri sokabiliyordu. Liste boş bırakılırsa her tür serbesttir.',
744
+ 'Sınıra ya da tür kapısına takılan dosya değere GİRMEZ ve alanın altında tek yerel mesaj çizilir (Form’un merkezî doğrulama hatasını maskelemez). Kabul KISMİDİR: çoklu seçimde geçen dosya varsa change GEÇENLERLE yayılır — 5 dosya seçilip maxFileCount 3 ise 3’ü akışa gider — yalnız hepsi elenirse olay hiç çıkmaz; tek dosyalık alanda zaten hepsi ya da hiçbiri. Sıra sabittir: TÜR ihlali boyut/adet ihlalinin önüne geçer. maxFileSizeMb dosya BAŞINA MB’dir; maxFileCount yalnız isMultiple açıkken okunur (tek dosyalık alanda panelde de gizlidir) ve zaten seçili dosyaları sayar; 0, boş ya da okunamayan sınır sınırsız demektir.',
745
+ 'enableCrop açıkken yalnız GÖRSEL dosyalar seçimden sonra kırpma katmanından geçer; cropAspectRatio yalnız o anahtar açıkken panelde çizilir. Çoklu seçimde dosyalar SIRAYLA sorulur: iptal edilen dosya değere hiç girmez, hepsi iptal edilirse change yayılmaz. Görsel olmayan dosya kırpmaya uğramaz.',
746
+ 'SÜRÜKLE-BIRAK YOKTUR: bu alan tıklanınca işletim sisteminin dosya diyaloğunu açar. Bırakma alanı isteniyorsa fileUpload (dropzone), buton görünümlü seçici isteniyorsa filebutton kullanılır.',
747
+ 'isLoading prop’u YOKTUR ve bilinçlidir (CQ-215): bu dosya ailesinde yükleniyor sözcüğü alan kilidi mi yükleme ilerlemesi mi, karar verilmedi. Alanı dondurmak için isDisabled kullan.'
748
+ ],
749
+ propNotes: {
750
+ value: 'Tek dosyada { type, fileName, value } NESNESİ, isMultiple açıkken bu nesnelerin DİZİSİ; value base64 data URL’dir. Akıştan yazarken de aynı şekli yaz — okunamayan değer alanı BOŞ gösterir, hata vermez.',
751
+ button_text: 'Gözat butonunun metni (varsayılan Browse); boşaltılırsa buton HİÇ çizilmez, görüntüleme ve salt okunur kiplerde de çizilmez. Adın snake_case olması kayıtlı sayfalar yüzündendir (ARC-085); buttonText yazmak unknown-prop verir.',
752
+ placeholder: 'Dosya seçilmemişken gösterilen metin; boş bırakılırsa uygulama dilinde hazır metin yazar (Dosya seçiniz / Choose a file).',
753
+ allowedFiletypes: 'Sabit listeden seçilen uzantılar (pdf, docx, doc, xlsx, xls, pptx, ppt, txt, csv, jpg, png, heic, zip…). Boş bırakmak her tür serbest demektir; listede olmayan uzantı için customFiletypes. Liste 2026-09-17’den beri bir ipucu değil gerçek bir ENGEL olduğu için her uzantı AYRI satırdır: jpg seçip jpeg seçmemek .jpeg dosyasını reddettirir, doc/docx ve xls/xlsx çiftleri de ayrıdır.',
754
+ customFiletypes: 'Listede olmayan uzantılar için serbest metin (2026-09-17): heic, dwg;psd gibi — virgül, noktalı virgül ve boşluk ayraçtır, baştaki nokta ve yıldız atılır, büyük/küçük harf önemsizdir. allowedFiletypes ile BİRLEŞİR, onun yerini almaz.',
755
+ maxFileCount: 'Yalnız isMultiple açıkken okunur; alanda zaten duran dosyalar sayıya dahildir.'
756
+ }
757
+ },
758
+ filebutton: {
759
+ summary: "Buton görünümlü dosya seçici: etrafında girdi çerçevesi yoktur, tek bir butona basılır ve seçilenler butonun ALTINDA satır satır listelenir. Seçim self.value'dan okunur.",
760
+ behavior: [
761
+ "change YÜKÜ tekli ve çoklu kipte FARKLIDIR: isMultiple kapalıyken tek nesne ({ type: 'file', value: base64 data URL, fileName, ref: '' }), açıkken aynı nesnelerin dizisi. Temizleme tekli kipte null, çoklu kipte [] yayar. Akıştan yazarken kipin şekli TERCİH EDİLİR ama şart değildir: çoklu kipe yazılan tek nesne listelenir, tekli kipe yazılan dizinin ilk dosyası çizilir (2026-09-17 öncesinde ikisi de sessizce hiçbir şey göstermiyordu). Uçtan gelen kayıtlı dosya ({ type: 'ref', value, absolute_path, fileName }) olduğu gibi yazılabilir ve adıyla listelenir (2026-09-17: yalnız absolute_path taşıyan kayıtlı dosya hiç çizilmiyordu); hiçbir içerik taşımayan kayıt ne çizilir ne de bir sonraki change yükünde kalır.",
762
+ "Çoklu kipte yeni seçim mevcut listenin ÜSTÜNE eklenir (fileInput/fileUpload ile aynı sözlük; 2026-09-17'ye kadar ikinci seçim birinciyi siliyordu ve maxFileCount her seferinde sıfırdan sayıldığı için sınır aşılabiliyordu). Satırdaki X o dosyayı, 'Tümünü temizle' hepsini siler; her ikisi de change yayar.",
763
+ 'Üç uyarı bağımsızdır ve üst üste çizilir: izin verilmeyen TÜR, boyut/adet sınırı ve Form doğrulaması (isInvalid + invalidText). Tür ve sınır uyarıları komponentin kendi yerel mesajlarıdır, akışa olay taşımaz — elenen dosya değere hiç girmez. Kabul KISMİDİR: bir parti içinde geçen dosya varsa change GEÇENLERLE yayılır (uyarı yine de çizilir), yalnız hepsi elenirse olay hiç çalışmaz. Sıra sabittir: tür kapısı önce işler, yani reddedilen tür maxFileCount kotasını yemez.',
764
+ 'isDisabled/isReadonly/isViewmode üçü de aynı kilidi kurar: buton tıklanamaz, X düğmeleri pasiftir, hiçbir olay yayılmaz. Yükleme ilerlemesi (yüzde/iptal) YOKTUR ve isLoading prop\'u da yoktur — dosya işleme akışı change olayına bağlanır.',
765
+ 'Doğrulama listesi yalnız required (panel file veri tipinin kurallarını çizer); desen/uzunluk kuralı yazılamaz — uzantı kısıtı allowedFiletypes, boyut kısıtı maxFileSizeMb ile kurulur.',
766
+ "Olaylar: mount ve change. mount'ı platform her düğüm için yayar ama bileşen bildirmediği sürece akışa bağlanamıyordu (2026-09-17'de bildirime eklendi)."
767
+ ],
768
+ propNotes: {
769
+ value: "Seçili dosya(lar). Panelde ÇİZİLİR ve akıştan yazılabilir (2026-09-17'ye kadar gizliydi, bu yüzden AI sözlüğünde de görünmüyordu): kayıtlı bir dosyayı forma geri basmanın yolu budur. Tekli kipte nesne, çoklu kipte dizi; boşaltmak için null (çoklu kipte []). Kipiyle uyuşmayan şekil de OKUNUR: çoklu kipte yazılan tek nesne listelenir, tekli kipte yazılan dizinin ilk dosyası çizilir (2026-09-17'ye kadar ikisi de sessizce hiçbir şey göstermiyordu). İçeriği olmayan kayıt (ne value ne data ne absolute_path) hiç çizilmez.",
770
+ text: 'Butonun üzerindeki metin (varsayılan "Attach File"); ikon sabittir. Alanın başlığı ayrı bir prop\'tur: label.',
771
+ description: 'Butonun altındaki yardım metni. Dosya seçilir seçilmez yerini dosya listesi alır, seçim temizlenince geri gelir (fileInput ile aynı kural).',
772
+ allowedFiletypes: 'İzin verilen uzantılar (çoklu seçim, kapalı liste). Hem dosya diyaloğunun accept süzgecini hem de seçimden SONRAKİ denetimi besler: liste dışı bir dosya seçilirse değere girmez ve komponentin içinde "desteklenmiyor" uyarısı çizilir (2026-09-17; öncesinde yalnız diyalog süzgeciydi, "Tüm dosyalar" ile aşılabiliyordu). Hem allowedFiletypes hem customFiletypes boşsa her tür serbesttir.',
773
+ customFiletypes: 'Listede olmayan uzantılar, serbest metin ("heic, dwg;psd"). Virgül, noktalı virgül ve boşluk ayraçtır; baştaki nokta ve yıldız atılır, büyük/küçük harf fark etmez. allowedFiletypes ile BİRLEŞİR, onun yerine geçmez (fileInput ile aynı ad ve aynı kural). Çok parçalı uzantı da yazılabilir ("tar.gz"): eşleşme adın SONUNA bakar, son noktadan sonrasına değil.',
774
+ maxFileSizeMb: 'Dosya BAŞINA en büyük boyut (MB). Boş/0/negatif değer sınırsız demektir; aşan dosya değere girmez, uyarı komponentin içinde çizilir.',
775
+ maxFileCount: "Çoklu kipte toplam dosya sayısı sınırı — zaten seçili olanlar da sayılır. Boş/0/negatif sınırsız. Tekli kipte hiç okunmaz ve panelde de gizlidir (isMultiple'a bağlı).",
776
+ size: "Form ölçüsü: 'sm' | 'md' | 'lg', boş bırakılırsa temanın varsayılan girdi ölçüsü. Butonun yüksekliğini, yazı boyunu ve yatay dolgusunu birlikte değiştirir.",
777
+ style: "Serbest CSS. Parçalar bildirilmiştir; stil düzenleyicisinde kökün yanında butonun kendisi (&__label), dosya listesi (&__files), dosya satırı (&__file), satırdaki silme düğmesi (&__file-delete) ve temizle düğmesi (&__clear) hedeflenebilir."
778
+ }
779
+ },
780
+ 'file-viewer': {
781
+ summary: 'Dosya önizleyici (pdf · görsel · düz metin); tasarımda file prop’una drive dosyası bağlanır, akış value’ya URL metni ya da drive nesnesi yazar.',
782
+ behavior: [
783
+ 'Çizilen kaynak: value doluysa o, boşsa file — akışın sonradan getirdiği dosya tasarım anındaki örneği ezer. İkisi de boşsa emptyTitle/emptyText kutusu çizilir. İki prop da DİZİ kabul eder (çoklu seçen bir dosya alanı öyle yazar); dosya taşıyan İLK öğe çizilir, bu bileşen tek dosya gösterir.',
784
+ 'Adresi ÇÖZÜLEMEYEN kaynak önizleme değil HATA kutusu çizer ve error yayar: yalnız kimliğini taşıyan kayıtlı referans ({ type: "ref", value: "abc" }, absolute_path yok) "dosya var" sayılır ama adresi yoktur. 2026-09-17 öncesinde boş src ile bir çerçeve çiziliyor, tarayıcı about:blank yüklüyor ve hiçbir şey gösterilmediği hâlde load yayılıyordu.',
785
+ 'Adres ŞEMA SÜZGECİNDEN geçer: http(s), göreli yol, blob: ve gerçekten çizilen gömülü türler (data:application/pdf · data:image/* · data:text/*) geçer; javascript:, vbscript:, file: ve sayfa gibi açılabilen gömülü türler (data:text/html, application/xhtml+xml, image/svg+xml) boşa düşer ve hata kutusu çizilir. Gerekçe: aynı adres hem PDF çerçevesine hem de programatik tıklanan indirme bağlantısına yazılıyor, javascript: ikisinde de uygulamanın origin’inde çalışırdı — üstelik son yol parçası .pdf ile biten bir javascript: metni uzantı kuralından PDF dalına giriyordu.',
786
+ 'Tür MIME’den, MIME yoksa UZANTIDAN okunur (drive dosyası ve düz URL MIME taşımaz): görsel · pdf · düz metin (txt md csv tsv log json xml yml yaml) önizlenir, gerisi unsupportedTitle/unsupportedText kutusuna düşer. 2026-09-17 öncesi yalnız bellekteki Blob çizilebiliyordu; URL ya da drive dosyası bağlanan her viewer "desteklenmeyen tür" gösteriyordu.',
787
+ 'isDownloadable bileşenin ÇİZDİĞİ bütün indirme yüzeylerini yönetir: önizlemenin köşesindeki düğme, desteklenmeyen tür kutusundaki düğme ve hata kutusundaki düğme. Kapalıyken (varsayılan) bunların hiçbiri çizilmez — 2026-09-17 öncesi desteklenmeyen tür kutusu bu anahtardan bağımsız indirme sunuyordu.',
788
+ 'controls YALNIZ PDF’te iş yapar: tarayıcının yerleşik araç çubuğunu (sayfa gezinme, yakınlaştırma, yazdırma) açar; kapalıyken çerçeveye #toolbar=0 yazılır. DİKKAT: o araç çubuğu tarayıcının KENDİ indirme ve yazdırma düğmelerini de getirir ve isDownloadable ona ulaşamaz — indirmeyi gerçekten kapatmak isteyen controls’u da kapalı tutar (yalnız indirmeyi gizleyen bir çapa parametresi yoktur).',
789
+ 'Başlık, alt metni ve indirme adı dosyanın KENDİ adından gelir; dosya ad taşımıyorsa fileName kullanılır. fileName runtime’a geri YAZILMAZ, yalnız yedek addır.',
790
+ 'load önizleme çizilince, error yüklenemeyince yayılır ve hata kutusunda errorText görünür. Düz metin URL’den fetch ile okunur; okunamazsa (erişim/CORS) error yayılır.'
791
+ ],
792
+ propNotes: {
793
+ file: 'Tasarımcının seçtiği dosya. Drive nesnesi ya da düz URL metni geçerlidir (CQ-267: şema tipi object görünür).',
794
+ value: 'Akışın setter ile yazdığı dosya; panelde çizilmez ve file’ı ezer.',
795
+ controls: 'PDF dışındaki türlerde etkisizdir. Açıkken tarayıcının kendi indirme/yazdırma düğmeleri de gelir; isDownloadable onları kapatamaz.',
796
+ errorText: 'Yalnız error hâlindeki kutunun başlığı; unsupported kutusu unsupportedTitle kullanır.',
797
+ surfaceStyle: NODE_SURFACE_NOTE
798
+ }
799
+ },
634
800
  button: {
635
801
  summary: "Tıklama kaynağı; type üç işten birini seçer — 'button' click akışını çalıştırır, 'submit' bir Form'u gönderir, 'link' bir adrese gider. click olayı veri taşımaz, bağlam gerekiyorsa ifadede komponent adlarıyla okunur.",
636
802
  behavior: [
@@ -649,71 +815,278 @@ export const componentKnowledge = {
649
815
  badgeValue: "Butonun köşe rozetinin metni ('3', '99+'); boşsa rozet çizilmez. Rengi badgeColor'dan gelir (primary|info|success|warning|error, varsayılan 'error')."
650
816
  }
651
817
  },
652
- 'dropdown-button': { summary: 'Menülü buton; clickItem olayı tıklanan menü öğesini taşır.' },
653
- compound: { summary: 'İkincil metinli büyük buton (compound button); click yayar.' },
654
- 'confirm-bar': { summary: 'Satır içi onay şeridi; click olayı tıklanan buton tanımını taşır.' },
818
+ 'dropdown-button': {
819
+ summary: "Menülü buton: options listesi menüyü kurar, tıklanan öğe clickItem ile gelir. Her öğe KENDİ akışını da taşıyabilir (options[].flow) — tek butonda birden çok aksiyon toplamanın yolu budur.",
820
+ behavior: [
821
+ "Bir öğeye tıklanınca ikisi birden olur: öğenin kendi flow'u (options[].flow doluysa) çalışır VE clickItem olayına bağlı akışlar çalışır. İkisinde de tıklanan öğenin TAMAMI self.currentItem'a yazılıdır ({ key, text, icon, flow, isDanger… }). Aynı işi iki kez yapmamak için ya öğelere flow bağla ya da clickItem'a tek akış bağlayıp içinde self.currentItem.key ile dallan.",
822
+ "click olayı BUTONUN KENDİSİNE basılınca yayılır (menüyü açan/kapatan tıklama) — menü hiç açılmasa bile. isDisabled ya da isLoading açıkken hiç yayılmaz. Öğe tıklamasıyla karıştırma: menü satırı click YAYMAZ, clickItem yayar.",
823
+ "Görünür öğe kalmadıysa (options boş, dizi değil ya da hepsi isHidden) buton devre dışı GÖRÜNÜR ve menü açılmaz — ama click yine yayılır. Menüyü akışla kurarken options'ı yazmadan butonu ekran açılışında ölü göstermemek için bir başlangıç listesi bırak.",
824
+ "Aynı sayfada tek menü açık kalır (ortak popover kaydı): bir menü açılınca diğeri kapanır. Menü kutusu KAYDIRILMAZ — 15-20'yi geçen öğe listesi ekrandan taşar, uzun listeyi dropdown/table gibi bir listeleyene taşı.",
825
+ "İpucu (tooltip) prop'u YOKTUR: düğümün ortak appearance.tooltip alanı (+ tooltipPosition) her komponentte ipucu çizer. Aynı bileşen drawer'ın alt şeridinde de kullanılır (actions[].options dolu olan aksiyon); orada prop'ları aksiyon tanımından gelir, sayfa şemasından değil."
826
+ ],
827
+ propNotes: {
828
+ kind: "ghost | secondary | outline (varsayılan 'outline') — burada kind RENK DEĞİL, butonun yüzey varyantıdır; buton bileşeninin semantik kind sözlüğünden (primary|info|success|warning|error) bir değer yazılırsa invalid-enum-value verir. Temizlenirse (null) 'outline' çizilir.",
829
+ options: "[{ key, text, icon, flow, isDanger, isHidden, isDisabled }] — menü satırları. text satırın etiketi, key akışta okunan kimlik (self.currentItem.key), flow o satıra bağlı akış (Prop ref), isDanger satırı kırmızı çizer, isHidden satırı listeden düşürür, isDisabled tıklanamaz yapar. Dizi olmayan değer (çözülmemiş ifade, nesne) boş liste sayılır — bileşen kırılmaz.",
830
+ optionsTitle: "Menü kutusunun üstündeki başlık; boşsa başlık satırı hiç çizilmez.",
831
+ icon: "{ name: 'more_vert', color? } nesnesi; düz 'more_vert' metni de okunur (CQ-164). Adı boş ya da temizlenmiş ikon HİÇ çizilmez (2026-09-17 öncesi boş ikon nesnesi 'home' glifi çiziyordu).",
832
+ iconPosition: "'left' (varsayılan) | 'right' — ikonun metnin hangi yanında durduğu; chevron her zaman en sağda kalır. İkon yokken etkisiz (panelde de gizlidir).",
833
+ text: "Butonun metni. BOŞ bırakılırsa chevron da çizilmez: buton yalnız ikondan oluşan bir menü düğmesine (kebab) döner. O kipte yükleniyor durumu ikonun yerinde spinner olarak görünür.",
834
+ size: "sm | md (varsayılan 'md') — lg YOKTUR. sm satır yüksekliğini içeriğe indirir ve menüyü butonun SAĞ kenarına yaslar (bottom-end), md ortalar.",
835
+ isLoading: "Butonu kilitler (tıklama ve olay yok) ve chevron'un yerinde — metin yoksa ikonun yerinde — spinner döndürür. Devre dışı görünümüyle aynı soluklukta çizilir.",
836
+ currentItem: "Panelde YOKTUR, yalnız runtime yazar: tıklanan öğenin tamamı. Akışta YALNIZ self.currentItem ile okunur — event.data.currentItem BOŞTUR: event.data'yı yalnız params geçen emit'ler doldurur (flow-execution.functions.ts), clickItem ise yalnız data gönderir ve o da setNode'a gider (CQ-077)."
837
+ }
838
+ },
839
+ compound: {
840
+ summary: 'Kart görünümlü BÜYÜK buton: text + altında subtle satırı + ikon çipi + hover okunu çizer; click yayar ya da href ile gider.',
841
+ behavior: [
842
+ 'KAPSAYICI DEĞİLDİR: çocuk kabul etmez. Metin ve açıklama kendi prop\'larıdır (text, subtle), serbest içerik konmaz.',
843
+ 'href yazılıysa düğüm <a> olarak çizilir ve tıklama gezinir; href boşsa <button> olur ve yalnız click akışını çalıştırır. click olayı İKİ durumda da yayılır — yani bağlantı + akış birlikte koşar. isNewTabLink yalnız href varken anlamlıdır (panelde de href boşken gizlidir) ve yeni sekme rel=noreferrer noopener ile açılır.',
844
+ 'isDisabled ya da isLoading açıkken düğüm KİLİTLİDİR: href düşer (düğüm <button disabled> olur), tıklama click olayını yaymaz. isLoading ayrıca sağdaki oku dönen halkaya çevirir ve halka hover beklemeden görünür; iskelet çizilmez, metin yerinde kalır.',
845
+ 'color yalnız İKON ÇİPİNİ boyar — düğmenin yüzeyi her zaman tema yüzeyidir (--ng-background-surface). İkon yoksa çizilecek çip de yok, o yüzden ikon adı boşken color/customColor panelde HİÇ görünmez.',
846
+ 'Sağdaki ok (arrow_right_alt) sabittir ve normalde görünmez: yalnız hover ederken (ya da isLoading açıkken) belirir. Kapatılamaz, değiştirilemez.',
847
+ 'mount olayı sayfa açılırken bir kez yayılır (platform yayar) — text/subtle/icon değerlerini bir akıştan doldurmanın yolu budur.'
848
+ ],
849
+ propNotes: {
850
+ text: 'Ana metin. Temizlenirse boş çizilir (şema varsayılanı yalnız hiç yazılmamış düğümde devreye girer).',
851
+ subtle: 'Ana metnin altındaki açıklama satırı; boşsa satır hiç çizilmez.',
852
+ icon: 'Solda duran çipin ikonu; { name } nesnesi ya da düz ikon adı metni kabul edilir. Adı boş bırakılırsa çip hiç çizilmez ve color/customColor panelden kalkar. Picker\'ın renk alanı kapalıdır (colorless) — glif rengi color kanalından gelir.',
853
+ color: 'Çipin semantik zemini: primary | info | success | warning | error | custom. Yalnız ikon çipini boyar, düğmenin yüzeyini DEĞİL.',
854
+ customColor: 'color custom iken çipin zemini (hex, rgb() ya da var(--ng-…) teması). Renk olarak okunamayan değer sessizce primary\'ye düşer.',
855
+ href: 'Adres yazılırsa düğüm bağlantı olur; yüklenen dosya alanı nesnesi ya da düz URL metni, ikisi de geçerli. Kilitliyken (isDisabled/isLoading) yok sayılır.',
856
+ isDisabled: 'Kilit: düğme soluklaşır, hover kalkar, href düşer ve click yayılmaz.',
857
+ isLoading: 'Akışın açtığı bekleme durumu: sağdaki ok yerine dönen halka çizilir, düğme kilitlenir (click yayılmaz).',
858
+ style: 'İç parçaların stil kancaları: &__content · &__icon · &__text · &__subtle · &__suffix.'
859
+ }
860
+ },
861
+ 'confirm-bar': {
862
+ summary: 'Satır içi ONAY ŞERİDİ: durum ikonu + başlık (title) + alt metin (subtle) + sağda bir sıra aksiyon butonu. Modal açmadan "bu kaydı onaylıyor musunuz?" sormak için; click olayı tıklanan aksiyonun tanımını currentItem ile taşır.',
863
+ behavior: [
864
+ 'KAPSAYICI DEĞİLDİR: çocuk kabul etmez. Serbest içerik için container, tam ekran karar için modal/drawer kullanın.',
865
+ "Aksiyonlar Button ile çizilir: her aksiyon kendi kind (primary|info|success|warning|error), variant (solid|outline|text), icon, isDisabled, isLoading ve isHidden'ını taşır. isHidden:true aksiyon hiç çizilmez. actions dizi DEĞİLSE (null yazan akış) aksiyon satırı boş kalır, sayfa düşmez.",
866
+ "Aksiyona flow bağlanabilir (actions[].flow) ya da şeridin click olayına akış bağlanabilir; İKİSİ birden bağlıysa tek tıklamada ikisi de koşar — aksiyonun akışı önce. Yalnız biri istensin diye diğerini boş bırakın.",
867
+ "Aksiyona href yazılırsa o aksiyon LİNK olur (Button type:'link'): tarayıcı adrese gider ve click YAYILMAZ, dolayısıyla akış koşmaz. isNewTabLink yeni sekmede açar ve yalnız href doluyken iş görür. Adres NESNE biçiminde data alanından okunur — iç sayfa için { data: '<sayfanın yolu>', ref: '<pageId>' } yazın; data'sı boş bir nesne (yalnız ref) adres saymaz ve aksiyon normal buton olarak çizilir.",
868
+ 'showCloseButton:true iken aksiyonların sağında bir kapatma düğmesi çizilir; basılınca close olayı yayılır ve şerit KENDİNİ gizler (isHidden:true kendi prop’una yazılır). Varsayılan kapalıdır — kayıtlı sayfalarda düğme kendiliğinden çıkmaz.',
869
+ 'Yükseklik 1-5 aralığındadır (varsayılan 5), genişlik 1-12 (varsayılan 12): tek satırlık tam genişlik şerittir.'
870
+ ],
871
+ propNotes: {
872
+ title: 'Şeridin ana metni; boş bırakılırsa başlık satırı hiç çizilmez.',
873
+ subtle: 'Başlığın altındaki ikincil metin; boşsa çizilmez.',
874
+ icon: "{ name: 'lock_open_right', color? } nesnesi; düz 'check' metni de okunur. Adı boş/temizlenmiş ikonda checklist çizilir — ikonsuz şerit YOKTUR.",
875
+ kind: "primary | info | success | warning | error | transparent — şeridin tonu (zemin + kenarlık + ikon dairesi). Temizlenirse ya da sözlükte olmayan bir değer yazılırsa info çizilir. transparent zemini boş bırakır.",
876
+ showCloseButton: 'Kapatma düğmesini çizer (varsayılan false). Basılınca close olayı + isHidden:true.',
877
+ actions: "Buton listesi. Alanlar: key (text'ten snake_case türetilir, currentItem'da geri gelir) · text · kind · variant · icon · flow · href · isNewTabLink · isHidden · isDisabled · isLoading. Sıra dizinin sırasıdır.",
878
+ currentItem: "AI YAZMAZ: şeridin click olayında runtime'ın geri yazdığı durum prop'u — tıklanan aksiyonun tamamı. Akışta self.currentItem (ör. self.currentItem.key) ile okunur.",
879
+ isHidden: 'Şeridi söker. Kapatma düğmesi de bunu yazar; şeridi geri getirmek için akışta isHidden:false yazın.'
880
+ }
881
+ },
655
882
  card: {
656
- summary: 'Görsel + başlık + açıklama + buton metni taşıyan hazır KART; click yayar.',
883
+ summary: 'Hazır KART: görsel bandı + başlık + açıklama + buton; kartın kendisi click, buton buttonClick yayar.',
657
884
  behavior: [
658
885
  "KAPSAYICI DEĞİLDİR: çocuk kabul etmez (not-droppable). Kutu içinde serbest içerik göstermek için container kullanın (istenirse states.isWrapper:true).",
659
- 'Yükseklik 10-50 aralığındadır (min 10, max 20 varsayılan, max 50). Bu sınır grid kanvasının kuralıdır, API aralık dışı blocks[].size.h değerini reddetmez; yine de aralıkta tutun.'
660
- ]
886
+ "Görsel bandının yüksekliği HER ZAMAN yazılıdır: imageHeight (px, varsayılan 160). imageFit yalnız bu yüzden iş görür — object-fit ancak kutu doğal orandan farklıyken görünür. imageWidth yazılmazsa görsel bandın tamamını kaplar, dar yazılırsa banda ortalanır.",
887
+ "image boşsa bant HİÇ çizilmez (kart başlık/açıklama/butona çöker); adres çözülemezse bandın yerine kırık görsel kutusu gelir.",
888
+ "buttonClick kabarcığı DURDURMAZ: butona basınca önce buttonClick, sonra kartın click olayı yayılır. Yalnız buton eylemi isteniyorsa kartın click bağını boş bırakın.",
889
+ "isLoading açıkken içerik yerine iskelet çizilir ve hiçbir tıklama olayı yayılmaz.",
890
+ 'Yükseklik 10-50 aralığındadır (min 10, varsayılan 32, max 50). Varsayılan 32, kartın kendi içeriğinin (160px bant + başlık/açıklama + buton) taşmadan sığdığı en küçük boydur; daha kısaya çekilirse bant sıkışır. Bu sınır grid kanvasının kuralıdır, API aralık dışı blocks[].size.h değerini reddetmez; yine de aralıkta tutun.'
891
+ ],
892
+ propNotes: {
893
+ image: 'Yüklenen dosya alanı nesnesi YA DA düz URL metni; ikisi de geçerli. Boş bırakılırsa görsel bandı hiç çizilmez.',
894
+ imageHeight: 'Görsel bandının yüksekliği (px). Yazılmazsa ya da temizlenirse 160. object-fit’in çalışması buna bağlıdır.',
895
+ imageWidth: 'Görselin bant İÇİNDEKİ genişliği (px). Yazılmazsa bandın tamamı; dar yazılırsa görsel bantta ortalanır.',
896
+ imageFit: "cover|contain|fill|none — CSS object-fit. Temizlenirse 'cover'.",
897
+ isLoading: 'Akışın ya da tasarımcının açtığı iskelet: içerik yerine parlayan kutular çizilir, click/buttonClick yayılmaz.',
898
+ title: 'Kart başlığı; aynı zamanda görselin alt metnidir (ayrı bir alt prop yoktur).'
899
+ }
661
900
  },
662
901
  'qm-card': { summary: 'QM gösterge kartı; click yayar.' },
663
- tabs: { summary: "Sekmeler; tab olayı seçilen sekme anahtarını taşır, her view children sırasıyla eşleşir. Etkin OLMAYAN sekmenin içeriği DOM'da YOKTUR (keepAlways dışında): o sekmedeki bir düğümü hedefleyen doğrulama önce page_screenshot actions { action: 'tab', value: '<sekme anahtarı>' } ister — sekme grubunun köküne click ilk sekmeye gider ve reddedilir.", propNotes: { surfaceStyle: NODE_SURFACE_NOTE } },
664
- 'collapsible-container': { summary: 'Aç/kapa kapsayıcı; collapsed/expanded olayları yayar.', propNotes: { surfaceStyle: NODE_SURFACE_NOTE } },
902
+ tabs: {
903
+ summary: 'Sekmeler: tabs dizisindeki her öğe bir başlık, children\'daki AYNI SIRADAKİ view onun içeriğidir; selected açık sekmenin key\'ini tutar.',
904
+ behavior: [
905
+ "Sekme i'nin içeriği children[i]'dir (type:'view', kendi children'ı sekmenin component'leri). tabs öğe sayısı ile view sayısı eşit olmalı: view'ı olmayan sekme boş açılır, fazla view hiç görünmez. Öğeyi silerken ya da sıralarken aynı sıradaki view'ı da taşı.",
906
+ "Açık sekme: selected seçilebilir (isDisabled/isHidden değil) bir sekmenin key'iyse o. Devre dışı/gizli bir sekmeyi gösteriyorsa en yakın seçilebilir sekme (eşit uzaklıkta öncesi), HİÇBİR sekmeyle eşleşmiyorsa (boş, yanlış yazılmış, metni değişince eskiyen key) İLK seçilebilir sekme açılır. Bu yalnız gösterimdir: selected'a geri yazılmaz ve tab olayı yayılmaz — {{ <tabs>.selected }} kullanıcı bir sekmeye tıklayana kadar yazdığın değeri gösterir.",
907
+ "tab olayı yalnız kullanıcı selected'dan FARKLI key'li bir sekmeye geçince yayılır (tıklama ya da sekme başlığında ←/→/Home/End); selected'ın kendisi olan sekmeye tekrar tıklamak olay üretmez. Görünen sekme bir geri düşüşse (selected eşleşmiyor ya da devre dışı) ona tıklamak geçiş sayılır ve tab yayılır. Akışın selected yazması olay yayılmasına yol açmaz.",
908
+ "keepAlways:false (varsayılan) sekmenin içeriği sekmeden çıkınca SÖKÜLÜR, dönünce yeniden kurulur: içindeki component'lerin mount olayı ve ona bağlı sorgu akışları HER açılışta yeniden koşar. keepAlways:true sekmenin içeriği ise SAYFA AÇILIRKEN (sekme hiç açılmasa, gizli ya da devre dışı olsa bile) bir kez kurulur ve gizlenerek tutulur — mount sorguları sayfa yüklenirken koşar. Kaydırma/girdi durumu korunması gereken ya da sık gidilip gelinen sekmede aç; kullanıcının nadiren açtığı pahalı sekmede kapalı bırak.",
909
+ "Sekme öğesi alanlarına {{ }} bağı çalışma anında ÇÖZÜLMEZ (frontend CQ-117): isDisabled/isHidden'ı koşula bağlamak için akışta setter ile tabs dizisinin TAMAMINI yeniden yaz. Sekmeleri tümüyle akıştan yönetmek (sihirbaz) için hideTabs:true + selected setter'ı.",
910
+ "tabs dizi değilse (null yazan akış) başlık ve içerik boş çizilir, sayfa düşmez. Başlıklar alt satıra kırılmaz; sığmazsa başlık satırı yatay kayar.",
911
+ "Etkin OLMAYAN sekmenin içeriği DOM'da YOKTUR (keepAlways dışında): o sekmedeki bir düğümü hedefleyen doğrulama önce page_screenshot actions { action: 'tab', value: '<sekme anahtarı>' } ister — sekme grubunun köküne click ilk sekmeye gider ve reddedilir."
912
+ ],
913
+ propNotes: {
914
+ surfaceStyle: NODE_SURFACE_NOTE,
915
+ tabs: "[{ key, text, icon, isDisabled, isHidden, keepAlways }] — key sekmenin kimliğidir, benzersiz olmalı; boş bırakılırsa sekmenin SIRASI (\"0\", \"1\"…) kimlik sayılır. Studio key'i text'ten snake_case üretir.",
916
+ selected: "Açık sekmenin key'i; setter ile yazılırsa sekme değişir (olay yayılmaz). Şema varsayılanı 'overview' varsayılan sekme listesine göredir — kendi key'lerini yazdığında selected'ı da yaz, yoksa ilk seçilebilir sekme açılır.",
917
+ variant: "container (varsayılan): başlıklar zemin şeridinde, açık sekme kart gibi; default: alt çizgili düz başlıklar. Yazılmazsa container çizilir (2026-09-15 öncesi yazılmamış düğüm default çiziyordu).",
918
+ headerAlign: 'Başlık satırının hizası: left (varsayılan) · center · right · stretch (sekmeler satırı eşit genişlikte paylaşır; metni sığmayan sekme kendi metni kadar genişler).',
919
+ hideTabs: 'Başlık satırını gizler; içerik yalnız selected ile değişir.'
920
+ }
921
+ },
922
+ 'collapsible-container': {
923
+ summary: "Başlıklı aç/kapa BÖLÜMÜ (akordeon): droppable bir kaptır, çocuklarını gövdesinde çizer; kullanıcı açıp kapayınca expanded/collapsed yayar ve isOpen'ı kendi prop'una geri yazar.",
924
+ behavior: [
925
+ "Gövde KAPALIYKEN HİÇ ÇİZİLMEZ: içindeki komponentler DOM'dan sökülür, her açılışta yeniden kurulur ve mount olayları yeniden koşar. Kapalı bir bölümdeki tablo/sorgu açılana kadar hiç yüklenmez — veriyi expanded olayında çekmek bu yüzden doğru desendir, ama kullanıcının girdiği form değeri de kapanışta kaybolur: korunması gereken durumu bölümün dışında (sayfa değişkeninde) tut.",
926
+ "Başlığa ya da aç/kapa düğmesine tıklamak isOpen'ı ters çevirir ve komponent yeni değeri KENDİ prop'una yazar; akışta self.isOpen ile okunur. Bölüm akıştan da açılıp kapatılır (setter ile isOpen), ama akıştan yazılan değer expanded/collapsed YAYMAZ — olaylar yalnız kullanıcı etkileşiminden çıkar.",
927
+ "Aç/kapa düğmesi yalnız openButtonText, openButtonIcon, closeButtonText ya da closeButtonIcon yazılınca çizilir; hiçbiri yazılmazsa başlığın sağında yuvarlak +/− göstergesi durur. Gösterge de gerçek bir düğmedir: klavyeyle odaklanır, Enter ve Space ile açar (2026-09-18 öncesi düz metindi, fare dışında yol yoktu).",
928
+ "Kanvasta gövde HER ZAMAN çizilir, isOpen false kaydedilmiş olsa bile — bırakma alanı orada durur (drawer/modal ile aynı editör kuralı). Kapalı görünüm yalnız önizlemede ve runtime'da görülür; kanvasta durum toolbar'daki Open düğmesinden okunur.",
929
+ "Düğümün YÜKSEKLİĞİ bölümün kendisine bağlı değildir: kapanan bölüm kutuyu küçültmez, altında boş alan kalır. Kapandığında yer bırakmaması isteniyorsa düğümün Height kipi auto olmalı (ortak katman, appearance.heightType)."
930
+ ],
931
+ propNotes: {
932
+ title: 'Başlık satırının metni; tıklama alanı başlık ŞERİDİNİN tamamıdır (açıklama satırı ve aradaki boşluk dahil).',
933
+ description: 'Başlığın altındaki ikinci satır. Boş bırakılırsa hiç çizilmez.',
934
+ openButtonText: 'Bölüm KAPALIYKEN düğmede yazan metin; açıkken de close karşılığı yazılmamışsa bu kullanılır.',
935
+ closeButtonText: 'Bölüm AÇIKKEN düğmede yazan metin. Yalnız bunu yazmak kapalı durumu etkilemez: orada varsayılan +/− göstergesi çizilir.',
936
+ openButtonIcon: 'Material ikon adı (add, expand_more) ya da { name, color }. Düz metin ad da kabul edilir.',
937
+ closeButtonIcon: 'Açık durumun ikonu; yazılmazsa openButtonIcon kullanılır. Düz metin ad da kabul edilir.',
938
+ openButtonVariant: "Düğmenin rengi: default | primary | success | danger | warning | ghost. Yalnız özel düğme çizildiğinde (metin ya da ikon yazılmışsa) görünür.",
939
+ closeButtonVariant: 'Açık durumun düğme rengi; aynı seçenekler.',
940
+ isOpen: 'Bölüm açık mı (varsayılan true). Kullanıcı tıklaması buraya geri yazar; akıştan setter ile yazmak bölümü açar/kapatır ve olay yaymaz.',
941
+ isDisabled: 'Bölümü kilitler: başlık tıklaması ve düğme çalışmaz, kap yarı saydam çizilir. GÖVDEDEKİ komponentleri devre dışı bırakmaz — açık bir bölüm kilitlendiğinde içerik kullanılabilir kalır.',
942
+ isLoading: 'Gövdeyi kırpıp üstüne yükleniyor göstergesi koyar. Önizlemede ve runtime tarafında bölüm kapalıyken görünmez (gövde yok); kanvasta gövde her zaman çizildiği için orada kapalı bölümde de görünür.',
943
+ isHidden: 'Düğümü hiç kurmaz: kapalı bir bölüm değil, olmayan bir bölümdür (ortak katman).',
944
+ style: 'BEM parçaları: &__header (başlık şeridi) ve &__body (gövde).',
945
+ surfaceStyle: NODE_SURFACE_NOTE
946
+ }
947
+ },
665
948
  'tree-view': {
666
- summary: 'Hiyerarşik liste: data ağacını çizer, satır tıklamasını click olayıyla akışa verir, satır başına aksiyon menüsü ve isteğe bağlı istemci-tarafı arama taşır.',
949
+ summary: 'Hiyerarşik liste: data ağacını çizer, satır tıklamasını click olayıyla akışa verir; isteğe bağlı onay kutulu (isCheckable → checkedKeys + change) çoklu seçim, satır başına aksiyon menüsü ve istemci-tarafı arama taşır.',
667
950
  behavior: [
668
- "click yükü komponentin KENDİ prop'larına yazılır (onEmit → setNode): tıklanan satırın key'i self.selected'a, satırın TAMAMI self.currentItem'a — akışta ikisi de self ile okunur.",
951
+ "click iki kanala birden yazar: tıklanan satırın key'i self.selected'a, satırın TAMAMI self.currentItem'a; aynı { selected, currentItem } akışta event.data'da da gelir.",
952
+ "key satırın kimliğidir ve METİN olarak karşılaştırılır (selected '7' ile data key 7 eşleşir). key'i boş/eksik satır hiç seçili çizilmez ve onay kutusu kilitlidir (yalnız ebeveyninden durum alır); aynı seviyede key tekrar ederse ya da eksikse ağaç kırılmaz ama selected/checkedKeys o satırları ayırt edemez — sorgudan kurarken benzersiz id'yi key'e eşle.",
669
953
  'selected akıştan yazıldığında o düğüme giden dallar KENDİLİĞİNDEN açılır (yalnız açar; kullanıcının elle açtıklarını kapatmaz). Satır verisindeki isExpanded:true de kendi başına açar.',
954
+ "isCheckable:true her satırın soluna onay kutusu koyar; işaretli key'ler checkedKeys dizisidir. Bir üst satırın key'i TÜM dalı temsil eder: checkedKeys'e yalnız ebeveyn yazmak altındaki bütün etkin satırları işaretler; etkin çocuklarının hepsi işaretli ebeveyn işaretli, bir kısmı işaretliyse yarım (—) çizilir. Kutuya tıklamak dalı birlikte işaretler/kaldırır. isDisabled satırın kutusu kilitlidir ve zincir onda durur: ebeveynin işareti ona ve altına inmez, o da ebeveynin durumuna sayılmaz (altındaki etkin satırlar tek tek işaretlenebilir).",
955
+ "change yalnız kullanıcı kutuya tıklayınca yayılır (akışın checkedKeys yazması yaymaz). Yazılan checkedKeys normalize edilmiştir: tam işaretli her satır belge sırasıyla (tamamlanan ebeveyn dahil); ağaçta çizilmeyen key'ler (gizli satır, henüz yüklenmemiş veri) sona olduğu gibi eklenir. Satır tıklaması (click/selected) ile kutu (change/checkedKeys) birbirinden bağımsızdır. checkedKeys'i (ve selected'ı) {{ }} İFADESİNE BAĞLAMA: kullanıcı yazması ifadeli prop'u bozar ve değişiklik kaybolur (platform kusuru CQ-247) — başlangıç listesini statik yaz ya da akıştan self.checkedKeys = [...] ile ver.",
670
956
  "actions komponent düzeyinde BİR KEZ tanımlanır, her satır aynı menüyü çizer; bir satır farklılaşacaksa veri öğesine _actions dizisi konur ve SIRA numarasıyla şablonun üstüne biner (o satırda gizleme / etiket değiştirme).",
671
- "Aksiyonlar set_event ile DEĞİL kendi flow prop'larıyla bağlanır (emptystate/html deseni); tıklanan satır akışa self.currentItem olarak geçer, ayrı bir şema olayı yayılmaz.",
672
- 'isSearchable:true arama kutusunu + tümünü aç/kapat düğmelerini açar. Süzme text ve subtle alanlarında geçer, eşleşenin ataları yerinde kalır, eşleşenin alt ağacı bütün görünür ve süzme sürerken dallar açık çizilir. Süzme İSTEMCİ tarafındadır: sunucuda arama gerekiyorsa kutuyu kapatıp kendi textinput + akış çiftini kur.',
673
- 'isLoading iskelet satır çizer; veri (ya da arama sonucu) boşsa emptyText basılır.',
674
- 'Satır ikonu icon > image > varsayılan klasör ikonu sırasıyla seçilir; satırdaki isHidden satırı hiç çizmez, isDisabled tıklamayı yutar.'
957
+ "Aksiyonlar set_event ile DEĞİL her aksiyonun kendi flow prop'uyla bağlanır; şema olayı yayılmaz. Aksiyonun akışında satır self.currentItem'da, event.data'da { currentItem, actionKey } (actionKey: aksiyonun key'i) gelir. flow'u boş aksiyon hiçbir şey yapmaz.",
958
+ 'isSearchable:true arama kutusunu + tümünü aç/kapat düğmelerini açar. Süzme text ve subtle alanlarında geçer, eşleşenin ataları yerinde kalır, eşleşenin alt ağacı bütün görünür ve süzme sürerken dallar açık çizilir (chevron o sırada etkisizdir). Süzme İSTEMCİ tarafındadır: sunucuda arama gerekiyorsa kutuyu kapatıp kendi textinput + akış çiftini kur. Arama sürerken onay durumu TAM ağaçtan hesaplanır ve bir ebeveyni işaretlemek aramanın gizlediği çocuklarını da işaretler.',
959
+ 'isLoading iskelet satır çizer; veri (ya da arama sonucu) boşsa emptyText basılır. data içindeki null / düz değer öğeler atlanır.',
960
+ 'Satır ikonu icon > image > varsayılan klasör ikonu sırasıyla seçilir; satırdaki isHidden satırı hiç çizmez, isDisabled satır tıklamasını ve kutusunu kilitler (dalı yine açılıp gezilebilir).'
675
961
  ],
676
962
  propNotes: {
677
- data: '[{ key, text, subtle, icon, image, isExpanded, isHidden, isDisabled, children[], _actions[] }] — key satırın kimliğidir, selected onunla eşleşir.',
963
+ data: '[{ key, text, subtle, icon, image, isExpanded, isHidden, isDisabled, children[], _actions[] }] — key satırın kimliğidir (metin olarak karşılaştırılır), selected ve checkedKeys onunla eşleşir.',
678
964
  selected: 'Seçili satırın key’i; setter ile dışarıdan da sürülebilir (o dala kadar ağaç açılır).',
679
- currentItem: 'Gizli prop: son tıklanan / aksiyon alınan satırın tamamı.',
965
+ checkedKeys: "İşaretli satırların key dizisi (yalnız isCheckable:true iken çizilir ve panelde görünür). Ebeveyn key'i tüm dalı işaretler. Kullanıcı kutuya tıklayınca normalize edilmiş diziyle geri yazılır.",
966
+ isCheckable: 'Satırlara onay kutusu koyar (çoklu seçim, dal zinciri, yarım durum); change olayını açar.',
967
+ currentItem: 'Gizli prop: son tıklanan / kutusu değişen / aksiyon alınan satırın tamamı (arama sürerken children süzülmüş hâliyle).',
680
968
  isSearchable: 'İstemci tarafı arama kutusu + tümünü aç/kapat araçları.',
681
- searchPlaceholder: 'Arama kutusunun ipucu metni.',
969
+ searchPlaceholder: 'Arama kutusunun ipucu metni (yalnız isSearchable:true iken).',
682
970
  emptyText: 'Veri ya da arama sonucu boşken basılan metin.',
683
- actionsTitle: 'Aksiyon menüsünün başlığı.',
971
+ actionsTitle: 'Aksiyon düğmesinin ipucu (üstüne gelince görünen metin) ve ekran okuyucu adı; menü başlık çizmez.',
684
972
  isActionsShowAlways: 'Aksiyon düğmesi sürekli görünür (varsayılan: satırın üstüne gelince).'
685
973
  }
686
974
  },
687
975
  text: {
688
- summary: 'Tek satırlık metin gösterimi; değer type:code prop’uyla ifadeye bağlanabilir. Görünümü TİPLİ stil gruplarındadır (typographyStyle · surfaceStyle), ham CSS değil.',
976
+ summary: 'Tek satırlık metin gösterimi; değer type:code prop’uyla ifadeye bağlanabilir. Görünümü TİPLİ stil gruplarındadır (typographyStyle · surfaceStyle), ham CSS değil. Uzun metin lineClamp ile kırpılır, veri beklerken isLoading iskeleti çizilir.',
689
977
  behavior: [
690
978
  "Yükseklik SABİTTİR: maxSize.h = 1 (katalog varsayılanı 8'dir ve olduğu gibi kopyalanırsa kanvasta boyutlandırılamaz; gateway 1'e çeker ve gatewayNormalized ile bildirir). Çok satırlı metin için textarea ya da html kullanın.",
691
- "type HTML etiketi + ölçek seviyesidir (h1|h2|h3|label|p|small; a11y için doğru seviyeyi seç). Punto/kalınlık/renk/hiza kararı typographyStyle'dadır: fontSize seviyenin puntosunu ezer, boş bırakılırsa seviye ölçeği (tema --ng-font-size-*) geçerlidir.",
979
+ "type HTML etiketi + ölçek seviyesidir (h1|h2|h3|h4|label|p|small; a11y için doğru seviyeyi seç; h4 2026-09-16'da açıldı — runtime ve tema ölçeği onu zaten tanıyordu, yalnız şemada yoktu). Punto/kalınlık/renk/hiza kararı typographyStyle'dadır: fontSize seviyenin puntosunu ezer, boş bırakılırsa seviye ölçeği (tema --ng-font-size-*) geçerlidir.",
980
+ "content SAYISAL SIFIRI ve false'ı artık BASAR (2026-09-16'da düzeltildi): şablon content ?? '' okuyor. Öncesinde || kullanılıyordu ve {{ <düğüm>.total }} gibi bir bağlamada değer 0 olduğunda metin BOŞ çiziliyordu — sayaç/toplam basan her ekranda bağlama kopmuş gibi görünüyordu.",
692
981
  "EMEKLİ prop'lar: isBold, align, color, customColor şemada YOK — yazılırsa unknown-prop ile reddedilir. Karşılıkları: typographyStyle.fontWeight ('600'), textAlign, textColor (semantik renk için tema token'ı: var(--ng-status-success) gibi). Kayıtlı eski sayfalarda bu prop'lar render anında takma adla çözülür (resolvedStyle bunu gösterir), yeni yazımda kullanılmaz.",
693
- "Hover grubu yok (metnin hover semantiği yok); surfaceStyle etiket/vurgulu paragraf içindir (zemin, köşe, çerçeve, gölge) ve contentOverflow alanı yoktur (taşma hedefi yok).",
982
+ "Hover grubu yok (metnin hover semantiği yok); surfaceStyle etiket/vurgulu paragraf içindir (zemin, köşe, çerçeve, gölge) ve contentOverflow alanı yoktur (taşma hedefi yok). METNİN taşması surfaceStyle'ın işi değildir, lineClamp prop'unundur.",
983
+ "Olay YOKTUR: şema events sözlüğü boştur, componentEvents kaydı da yoktur. Metne tıklamayı akışa bağlamak isteyen düğümü button ya da bir kaba sarar.",
694
984
  "KATMAN SIRASI (K4): tema componentStyles → $preset TABANDIR; tipli grup alanları temayı alan alan EZER; düğümün serbest style'ı SON SÖZDÜR. Grubun karşılamadığı kararı style kanalına (custom properties) yaz."
695
985
  ],
696
986
  propNotes: {
987
+ content: "Düz metin; {{ }} ile ifadeye bağlanır. 0 ve false BASILIR (bkz. behavior). Biçimli içerik (kalın parça, liste, link) metnin içinde DEĞİL ayrı komponentte kurulur: html ya da texteditor.",
988
+ lineClamp: 'Kırpma satır sayısı, 1-10. 1 → tek satır + üç nokta (white-space:nowrap + text-overflow). 2+ → n satırdan sonra üç nokta (-webkit-box). Boş/0 → kırpma yok, metin sarar. wordBreak SÖZCÜĞÜN nasıl kırılacağını, lineClamp METNİN nerede biteceğini söyler — AMA lineClamp:1 iken metin hiç sarmadığı için (nowrap) wordBreak ETKİSİZDİR; ikisi ancak lineClamp 2+ ya da kırpma kapalıyken birlikte anlamlıdır. Kırpılan metnin tamamını göstermek için düğümün ORTAK ipucu alanını kullan (appearance.tooltip), text\'in kendi tooltip prop\'u YOKTUR.',
989
+ isLoading: 'Metnin yerine nabız atan bir iskelet çubuğu çizer ve aria-busy yazar; content hiç basılmaz. Veri gelene kadar gösterilecek yer tutucu içindir, akıştan setter ile açılıp kapatılır.',
697
990
  surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens,
698
991
  typographyStyle: STYLE_GROUP_NOTES.typographyStyle + ' ' + STYLE_GROUP_NOTES.colorTokens,
699
992
  style: STYLE_GROUP_NOTES.styleEscape
700
993
  }
701
994
  },
702
- image: { summary: 'Görsel; click yayar, src ifadeyle beslenebilir.' },
703
- video: { summary: 'Video oynatıcı; play/pause/ended olayları yayar.' },
704
- qrcode: { summary: 'QR kod üretimi; value prop’undan çizer.' },
705
- tags: { summary: 'Salt gösterim etiket listesi (tag-input’un okunur akrabası).' },
995
+ image: {
996
+ summary: 'Görsel; mount ve click yayar, src ifadeyle beslenebilir. Büyütülmüş önizleme (isZoomable) ve önizlemenin içinde döndürme (isRotatable) vardır.',
997
+ behavior: [
998
+ "ÖLÇEKLEME KİPİ PROP DEĞİL, düğümün appearance kanalındadır: appearance.widthType 'cover' (kutuyu doldurur, taşanı kırpar) ya da 'contain' (tamamını sığdırır ve appearance.alignType ile sola/ortaya/sağa hizalanır); appearance.heightType 'fixed' | 'auto' (appearance.aspectRatio ile oran) | 'fill'. Studio bir image düğümünü bırakırken heightType:'fixed', widthType:'contain', alignType:'center' yazar. 2026-09-16 öncesinde heightType:'fill' ve flex çocuğunun widthType:'fixed'/'fill' kipleri HİÇBİR sınıf üretmiyordu; object-fit tarayıcı varsayılanına düşüp görsel esneyerek bozuluyordu. Artık ikisi de varsayılan kiple (cover) kutuyu kaplar.",
999
+ "Kaynak boşsa ya da yüklenemezse GÖRÜNÜR bir yedek kutu çizilir (ikon + alt metni). 2026-09-16 öncesinde <img> etiketinin kendi alt metni .ng-image kuralındaki color: transparent yüzünden gizleniyordu, yani kırık görsel boş bir dikdörtgenden ayırt edilemiyordu.",
1000
+ 'isLoading açıkken görselin yerine parıltılı iskelet çizilir; akıştan setter ile açılıp kapatılabilir, görselin kendi yükleme iskeletinden bağımsızdır.',
1001
+ "isZoomable açıkken görsele tıklamak tam ekran önizleme açar (Escape, kapatma düğmesi ve zemine tıklama kapatır). Bağlı bir click akışı VARSA o da çalışır; ikisi birbirini iptal etmez, önizleme istenmiyorsa anahtar kapalı bırakılır. Kanvasta (tasarımcı yüzeyinde) önizleme hiç açılmaz. isRotatable yalnız önizlemenin içine 90 derecelik döndürme düğmeleri ekler ve kaydedilen hiçbir değeri değiştirmez.",
1002
+ 'Görünürlük ortak katmandadır (props.isHidden); ipucu, köşe, gölge, kenarlık ve boşluk düğümün appearance kanalından gelir, bu komponentin prop yüzeyinde yoktur.'
1003
+ ],
1004
+ propNotes: {
1005
+ src: "Yüklenen dosya alanının nesnesi (uçtan geldiği gibi) YA DA URL metni; ikisi de kabul edilir. Varsayılan '/images/default.webp'.",
1006
+ alt: 'Erişilebilirlik metni; görsel yüklenemediğinde yedek kutuda GÖRÜNÜR olarak da basılır.',
1007
+ isZoomable: 'Tıklayınca tam ekran önizleme açar (rakiplerdeki zoom/lightbox karşılığı).',
1008
+ isRotatable: 'Önizlemeye sola/sağa 90 derece döndürme düğmeleri ekler; isZoomable kapalıyken panelde çizilmez.',
1009
+ isLoading: 'Görselin yerine iskelet çizer; veri gelene kadar bekletmek için akıştan yazılır.'
1010
+ }
1011
+ },
1012
+ video: {
1013
+ summary: 'HTML5 video oynatıcı: src + poster, autoplay/loop/muted/controls anahtarları, akıştan sürülebilen isPlaying kolu ve play/pause/ended olayları. Tarayıcının kendi kontrollerini çizer — özel oynatıcı arayüzü yoktur.',
1014
+ behavior: [
1015
+ "src hem DOSYA ALANI NESNESİ hem DÜZ URL METNİ kabul eder (getfileUrl: metin olduğu gibi kullanılır, nesnede type:'file' ise data/value, değilse absolute_path okunur). Katalog tipi 'object' görünür çünkü şemada FileProp'tur; metin yazmak geçerlidir ve akıştan gelen uç FILE alanı olduğu gibi taşınabilir. Boş src'de src özniteliği HİÇ yazılmaz (boş istek atılmaz), poster varsa yalnız kapak görünür.",
1016
+ 'OYNATMAYI AKIŞTAN SÜRME: props.isPlaying true yazmak play(), false yazmak pause() demektir; bileşen de play/pause/ended olaylarında aynı prop\'a geri yazar (popover isOpen deseninin aynısı). Tarayıcı jest politikası burada da geçerlidir — SESLİ bir videoyu kullanıcı etkileşimi olmadan başlatmak REDDEDİLİR, söz sessizce yutulur ve isPlaying bir sonraki gerçek olayda düzelir. Akıştan başlatılacak video için muted:true yaz.',
1017
+ 'AUTOPLAY üç şart ister: autoplay:true + muted:true + tarayıcının izin vermesi. muted olmadan autoplay hemen hemen her tarayıcıda engellenir. Eleman her zaman playsinline ile çizilir, yani iOS Safari videoyu tam ekrana almaz.',
1018
+ "loop:true iken 'ended' HİÇ yayılmaz (döngü videosu bitmez); 'bittiğinde şunu yap' akışı loop kapalı ister. Video bittiğinde tarayıcı HTML spesifikasyonuna göre ÖNCE 'pause' SONRA 'ended' yayar — yani 'pause'a bağlı akış, kullanıcı duraklatmasa da bitişte koşar; ikisi de isPlaying'i false yazdığı için durum aynı kalır. 'Kullanıcı duraklattı' ile 'bitti'yi ayırmak gerekiyorsa event.data.currentTime ile duration'ı karşılaştır.",
1019
+ "'click' olayı ancak akışa BAĞLIYSA sarmalayıcı <button> olur; controls:true iken oynat/duraklat düğmesine basmak da bu click'i tetikler (tıklama sarmalayıcıya kabarır). Tıklamayı 'videoyu aç' gibi bir aksiyon için kullanacaksan controls:false ile kullan.",
1020
+ "isHidden:true iken bileşen hiç çizilmez; isLoading:true iken oynatıcı yerine nabız atan bir iskelet kutusu çizilir (src akıştan gelene kadar). mount OLAYI bileşenin kendisinden DEĞİL, ortak render katmanından gelir ve bir kez yayılır (2026-09-16 turuna kadar bileşen ayrıca yayıyordu ve mount'a bağlı akış İKİ KEZ koşuyordu — ARC-006).",
1021
+ "Ölçü/uyum kararı düğümün appearance kanalındadır, prop değil: widthType cover|contain elemanın object-fit'ini seçer, alignType contain'de object-position'ı, heightType:'auto' + aspectRatio en-boy oranını verir. Flex kabında appearance aynı alanda YERLEŞİM kipi taşır (fill/fixed); bunlar 2026-09-16'dan beri contain'e eşlenir — öncesinde sınıfsız kalıp tarayıcının <video> UA varsayılanına (object-fit: contain) düşüyorlardı, yani seçim kayboluyordu ama görüntü bozulmuyordu. Pratik sonuç: flex/fill kutusundaki video LETTERBOX'lanır; kırpmak istiyorsan widthType'ı açıkça cover yap (ARC-079)."
1022
+ ],
1023
+ propNotes: {
1024
+ src: 'Dosya alanı nesnesi YA DA mutlak/göreli URL metni. Boş bırakılırsa oynatıcı kaynaksız çizilir (poster varsa kapak görünür).',
1025
+ poster: 'Oynatmadan önce görünen kapak görseli (URL metni ya da görsel alanı). Oynatma başlayınca kaybolur.',
1026
+ autoplay: 'Tarayıcı otomatik oynatma bayrağını kaynak İLK yüklenirken okur; ekranda duran bir videoda bu anahtarı sonradan açmak oynatmayı başlatmaz (bilinen tarayıcı davranışı, 2026-09-16 turunda ölçülmedi). muted ile birlikte kullan; akıştan başlatmak için isPlaying.',
1027
+ muted: 'Sessiz oynatma. autoplay ve akıştan başlatma için pratikte zorunludur.',
1028
+ controls: "Tarayıcının kendi oynatıcı kontrolleri. false iken tek oynatma yolu akıştan isPlaying'dir.",
1029
+ loop: "Bitince başa sarar; açıkken 'ended' olayı yayılmaz.",
1030
+ isPlaying: "Çift yönlü: akış yazınca oynatır/duraklatır, bileşen play/pause/ended'de geri yazar (self.isPlaying). Başlangıç değeri olarak true yazmak SESLİ videoda çalışmayabilir (jest politikası).",
1031
+ isLoading: "Oynatıcının YERİNE iskelet kutusu çizer — <video> elemanı hiç kurulmaz. Bu sırada click olayı çalışmaz ve oynayan bir video sökülür; sökülme anındaki pause yakalanamadığı için self.isPlaying true KALIR (hiçbir şey oynamadığı hâlde). isLoading kapanınca yeni eleman currentTime 0'dan başlar. Aynısı isHidden için de geçerli. src bir akıştan gelirken kullanılır.",
1032
+ style: 'Serbest CSS kaçışı; ölçü/uyum kararı appearance kanalındadır (widthType/heightType/aspectRatio).'
1033
+ }
1034
+ },
1035
+ qrcode: {
1036
+ summary: 'QR kod üretimi: data prop’undaki METNİ ya da bağlantıyı taranabilir SVG koda çevirir (prop adı `value` DEĞİL `data`). mount · click · error yayar.',
1037
+ behavior: [
1038
+ 'KÜTÜPHANE TEPKİSİZ: `@castlenine/svelte-qrcode` seçeneklerini bir kez okuyup SVG’yi bir kez üretiyor. Sarmalayıcı bu yüzden data · quietZone · errorCorrectionLevel üçlüsünden bir anahtar kurup bileşeni YENİDEN KURUYOR; yani üçünü de akıştan değiştirmek çalışır. 2026-09-17 öncesinde anahtar `data || padding` idi ve data dolu olduğu sürece boşluk ayarı ekranda HİÇ değişmiyordu.',
1039
+ 'DÖRT ÇİZİM HÂLİ var ve sırası sabit: isLoading açıksa nabız atan gri kare (veri yoldayken ESKİ kod taranabilir kalmaz), data boş ya da yalnız boşluksa kesikli QR yer tutucusu, kütüphane üretemediyse kesikli hata yer tutucusu, aksi hâlde kodun kendisi.',
1040
+ 'BOŞ data HATA DEĞİLDİR: yer tutucu çizilir, error olayı YAYILMAZ ve konsola bir şey yazılmaz. Üretilemeyen (çok uzun) data ise error yayar; kütüphanenin kendi console.error satırı da çıkmaya devam eder.',
1041
+ 'KAPASİTE ile errorCorrectionLevel TERS ORANTILI: bayt sınırı L 2953 · M 2331 · Q 1663 · H 1273. Seviyeyi yükseltmek dayanıklılığı artırır ama sığan metni AZALTIR — M’de çizilen bir metin H’de "Data too long" verebilir. Kod hiç çizilmiyorsa önce bu iki değere bak.',
1042
+ 'RENK PROP’U YOK ve bu bilinçli: kod her zaman siyah-beyaz çizilir. QR taranabilirliği koyu/açık kontrastına bağlıdır; tema ya da serbest renk seçimi "çizilen ama okunmayan kod" üretmenin en hızlı yoludur. style prop’u SARMALAYICIYA uygulanır, kodun modül renklerine değil.',
1043
+ 'click YALNIZ şemada bağlıysa ve ekranda GERÇEK bir kod varken yayılır (badge/image deseni): bağlıyken düğüm <button> olur ve odak sırasına girer, bağlı değilken role="img" taşıyan bir <div>tür. Kodun erişilebilir adı kodladığı metnin kendisidir (aria-label = data).',
1044
+ 'mount düğüm çizilince bir kez yayılır — QR’ın göstereceği bağlantıyı üreten sorguyu buradan başlat. Görünürlük ortak katmandadır (props.isHidden); ipucu, köşe, gölge, kenarlık ve boşluk düğümün appearance kanalından gelir.'
1045
+ ],
1046
+ propNotes: {
1047
+ data: "Koda gömülecek metin ya da adres; {{ }} ile bağlanabilir. Sayı ve null kabul edilir (metne çevrilir / boş sayılır). KIRPILMAZ — baştaki ve sondaki boşluk da kodlanır, ama yalnız boşluktan oluşan değer 'boş' sayılır. Şemadaki 'https://zeyrek.glomil.app/' varsayılanı TASARIM ANI değeridir: paletten bırakılan düğüme yazılır, ama data taşımayan bir düğümde (MCP'den yazılan sayfa) runtime varsayılanı boş stringtir ve yer tutucu çizilir — MCP'den kurarken data'yı AÇIKÇA yaz (CQ-265).",
1048
+ errorCorrectionLevel: "L | M | Q | H (varsayılan M). Tanınmayan değer (yanlış yazılmış bir seviye, boş metin, sayı) sessizce M’ye düşer — kütüphane onda Error atıp kodu tamamen kaybettirirdi. Kapasite ilişkisi için behavior.",
1049
+ quietZone: 'Kodun çevresindeki sessiz alan, MODÜL sayısı olarak (piksel DEĞİL), 1–10, varsayılan 1. Adı padding DEĞİL: düğümün padding adlı bir prop’u ortak render katmanınca CSS boşluğu sayılır ve tasarımcının Spacing ayarını ezer (CQ-272).',
1050
+ isLoading: 'Kodun yerine nabız atan gri kare çizer; veriyi üreten sorgu koşarken akıştan açılır. Açıkken kod HİÇ çizilmez — bekleyen bir QR eski değeriyle taranmasın diye.',
1051
+ style: 'Tasarımcı stil nesnesi; SARMALAYICIYA uygulanır, kodun kendi renklerini ya da modüllerini değiştirmez.',
1052
+ isHidden: 'Ortak katman görünürlüğü (RenderComponent okur).'
1053
+ }
1054
+ },
1055
+ tags: {
1056
+ summary: 'Salt gösterim etiket listesi (tag-input’un okunur akrabası); tıklanan etiketi akışa verir.',
1057
+ behavior: [
1058
+ "values bir DİZİdir: [{ label, color?, variant?, isActive? }]. Akıştan gelen liste çizilmeden önce süzülür: dizi olmayan değer (null, düz metin) boş liste; metin/sayı öğe renksiz etiket olur (['billing','critical'] geçerli); label yoksa öğenin value alanı okunur (tag-input değeri doğrudan bağlanabilir, ama hex rengi burada GEÇMEZ); boş metinli ya da metinsiz öğe atlanır.",
1059
+ 'color yalnız status adıdır: primary|info|success|warning|error; başka her şey (hex dahil) nötr gri çizer. variant: solid (varsayılan, açık zemin) | outline (renkli kenarlık). isActive:true zemini belirginleştirir (hover seçili etiketi değiştirmez) — filtre çipi gibi seçili etiketi göstermek için akıştan yaz.',
1060
+ "Düğümün olaylarında clickItem satırı varsa etiketler düğme olur (el imleci, hover, klavyeyle odak) — satıra akış seçilmemiş olsa bile; clickItem satırı yoksa salt metindir. Yayında event.data = { currentItem, index }, öğe ayrıca self.currentItem'a yazılır. index values dizisindeki GERÇEK yerdir (atlanan öğeler kaydırmaz) — akış values[index].isActive'i değiştirip values'u geri yazarak seçimi çevirebilir. Bileşen isActive'i kendisi DEĞİŞTİRMEZ.",
1061
+ "Eski şemada öğe anahtarı active'di ve runtime okumuyordu (2026-09-16 düzeltildi); kayıtlı sayfalardaki active:true artık etkilidir ama paneldeki Active anahtarı onu KAPALI gösterir (isActive okur); yeni yazımda isActive kullan, eski öğeyi kapatmak için isActive:false yaz.",
1062
+ 'Etiket eklemek/silmek gereken ekranda tag-input kullan; tags değer yazmaz, change yaymaz.'
1063
+ ],
1064
+ propNotes: {
1065
+ values: "[{ label, color?, variant?, isActive? }] ya da düz metin dizisi. color: primary|info|success|warning|error; variant: solid|outline.",
1066
+ currentItem: "Gizli prop: son tıklanan öğe (values'taki nesnenin tamamı, düz metin dizisinde metnin kendisi). index yalnız event.data'da.",
1067
+ style: "Kök düğüm ve '&__tag' alt anahtarı (her etiket)."
1068
+ }
1069
+ },
706
1070
  notification: {
707
- summary: 'Sayfa içi geri bildirim kutusu; akışlarda alert adımı yerine bu komponent kullanılır.',
1071
+ summary: 'Sayfa içinde DURAN bilgi/başarı/uyarı/hata bandı: header + content, tür ikonu, kapatma düğmesi ve isteğe bağlı zaman aşımı. Akışlarda alert adımı yerine bu komponent kullanılır; ekranın köşesinde geçici bildirim isteniyorsa toast.',
708
1072
  behavior: [
709
1073
  "isHidden 2026-08-26'dan beri bu komponentin ŞEMASINDA VARDIR (daha önce yoktu ve bu katalog bir dönem 'unknown-prop verir' diyordu): props.isHidden'ı doğrudan şemaya yazabilirsin, başlangıçta gizli bildirim için container'a sarmak GEREKMEZ.",
710
1074
  "Görünürlük yalnız props.isHidden'dır: appearance'ta isHidden alanı YOKTUR (2026-09-15'te platformdan kaldırıldı, S-16). Gövdeye appearance.isHidden konursa gateway onu props.isHidden'a taşır ve gatewayNormalized'da bildirir.",
711
- "Kendini KAPATIRKEN props.isHidden'a yazar: hem timeout dolduğunda hem kapatma düğmesinde 'toggled' emit'i { isHidden: true } taşır (Notification.svelte handleEvent). Şema events sözlüğünde bu ad YOKTUR — akışa bağlanacak bir olay değil, prop'a geri yazma yoludur.",
712
- 'Başlangıçta gizli bir bildirim: şemaya props.isHidden:true yaz, açılışı akıştaki setter ile yap; timeout verilirse kendini kapatır.'
1075
+ "KAPANIŞ ARTIK BİR OLAY (2026-09-17): kapatma düğmesi ve zaman aşımı close olayını yayar; olay hem props.isHidden'a true yazar (akışta self.isHidden) hem sebebi taşır — event.data.reason kullanıcı kapattıysa 'user', süre dolduysa 'timeout'. Eski emit adı toggled kaldırıldı: şema events sözlüğünde hiç bildirilmemişti, dolayısıyla ona bağlı kayıtlı sayfa olamaz.",
1076
+ 'ZAMAN AŞIMI GÖRÜNÜRLÜKLE BAŞLAR: props.isHidden:true ile başlayan bildirim akıştaki setter ile açıldığı anda sayacı kurar, kapanınca sayaç temizlenir; her yeniden açılış yeni bir sayaç demektir. Akış timeout değerini çalışma zamanında değiştirirse sayaç YENİ süreyle yeniden kurulur (2026-09-17). Tasarımcı kanvasında sayaç hiç kurulmaz.',
1077
+ 'Başlangıçta gizli bir bildirim: şemaya props.isHidden:true yaz, açılışı akıştaki setter ile yap; timeout verilirse kendini kapatır ve close yayar.',
1078
+ 'mount olayı ortak render katmanından gelir ve bileşen GÖRÜNÜR olduğunda yayılır (isHidden:true iken yayılmaz) — bandın metnini üretecek sorguyu buradan başlat.',
1079
+ 'İKON: tür ikonu (information info · success check_circle · warning warning · error error) showIcon ile kapatılabilir, icon prop ile başka bir Material Symbols adıyla değiştirilebilir. Rengi her zaman tür verir, ikon seçicide renk alanı YOKTUR — renk bu bandda anlamın kendisidir.'
713
1080
  ],
714
1081
  propNotes: {
715
- kind: 'information | error | success | warning (buton kind sözlüğünden farklıdır: orada info/primary vardır)',
716
- isHidden: 'Şemada tanımlıdır; statik true ile gizli başlatılır, akıştaki setter ile açılıp kapanır. Komponent kendi kapanışında da bu prop\'a yazar.'
1082
+ header: 'Kalın yazılan başlık; ekranda ardına İKİ NOKTA eklenir ve metnin başına akar (ayrı satır değildir). Başlıksız band için boş bırak.',
1083
+ content: 'Bandın metni. Tek satır gerekmez, kutu büyür; uzun kelimeler satır sonunda bölünür.',
1084
+ showIcon: 'Tür ikonunu çizer. false iken ikon kolonu hiç oluşturulmaz (metin sola yaslanır) ve panelde icon alanı gizlenir.',
1085
+ icon: 'Tür ikonunu ezen Material Symbols adı. Boş bırakılırsa tür ikonu çizilir; renk yine türden gelir.',
1086
+ timeout: 'Milisaniye. Bileşen GÖRÜNÜR olduğu sürece sayar, süre dolunca close yayar ve props.isHidden true olur. 0, boş ya da sayı olmayan değer kendiliğinden kapanma YOK demektir.',
1087
+ kind: 'information | error | success | warning — rengi ve ikonu birden seçer. Buton ve toast sözlüğünden farklıdır (orada info/primary/default var): akıştan info gelirse komponent information, danger gelirse error okur, bilinmeyen değer information olur. Panel açılır listesinde yalnız dört değer görünür.',
1088
+ isHidden: 'Şemada tanımlıdır; statik true ile gizli başlatılır, akıştaki setter ile açılıp kapanır. Komponent kendi kapanışında da bu prop\'a yazar.',
1089
+ style: 'Serbest CSS kaçışı. Parçalar: &__icon · &__header · &__content · &__close. Bandın zemin/kenarlık renkleri türden gelir; burada yazılan bildirim onları da ezer.'
717
1090
  }
718
1091
  },
719
1092
  'form-validation-errors': {
@@ -735,13 +1108,43 @@ export const componentKnowledge = {
735
1108
  style: STYLE_GROUP_NOTES.styleEscape + " Parçalar: KÖK (anahtarlar doğrudan style'da) kırmızı kutudur — zemin (--ng-red-50), çerçeve (--ng-red-200), köşe; '&__title' başlık metni. Satır sınıfları belgelenmemiştir."
736
1109
  }
737
1110
  },
738
- breadcrumb: { summary: 'Sayfa yolu; currentTitle setter ile kip etiketine (Yeni/Düzenle) çevrilir.' },
739
- 'page-header': {
740
- summary: 'Sayfa başlığı bandı; yalnız mount yayar.',
1111
+ breadcrumb: {
1112
+ summary: 'Tek satırlık sayfa yolu: homeTitle (kök) + items (aradakiler) + currentTitle (bulunulan sayfa). Adresi olan öğe bağlantıdır, tıklama ayrıca clickItem yayar. KAPSAYICI DEĞİLDİR.',
1113
+ behavior: [
1114
+ 'Üç parça ayrı prop’tur ve sırası sabittir: homeTitle → items → currentTitle. Metni boş olan parça HİÇ çizilmez, yani yalnız items vererek köksüz bir iz de kurulabilir. Ayraç (/) bileşenin kendi CSS’indedir, prop’u yoktur; son öğeden sonra basılmaz.',
1115
+ "Öğenin türü adresine ve olay bağına göre seçilir: href çözülüyorsa <a> (iç adres SPA gezinmesi, dış adres / mailto / tel doğrudan tarayıcı), href yoksa ve clickItem bir akışa bağlıysa <button>, ikisi de yoksa düz metin. 2026-09-17'den önce HER öğe <button> + goto() idi: dış adresler SvelteKit 2'de hata verip hiçbir yere gitmiyordu, bulunulan sayfa ise hiçbir şey yapmayan bir düğmeydi.",
1116
+ 'currentTitle tıklanabilir değildir (aria-current="page"); kip etiketi (Yeni/Düzenle) gibi kullanılacaksa akış bu prop’a setter ile yazar.',
1117
+ "items dizi DEĞİLSE (temizlenmiş prop null, henüz dolmamış {{ }} ifadesi, düz nesne) iz BOŞ çizilir — 2026-09-17'den önce bileşen bu durumda çizim sırasında patlıyordu. Satır { title, href } bekler ama düz metin dizisi (['Müşteriler','Ahmet']) ve title yerine label yazan satır da okunur; metinsiz satır düşer, düşen satır olay yükündeki index'i KAYDIRMAZ.",
1118
+ 'İz sarılır: tek satıra sığmayan kırıntı alt satıra iner (düğüm yüksekliği yetmiyorsa Size’dan artır, maxHeight 6 satırdır). Uzun bir izi tek satırda toplayıp "…" menüsüne indiren varyant AYRI bir komponenttir: breadcrumb-title.',
1119
+ 'Olaylar: mount · clickItem. Sayfa başlığıyla birleşik, kip etiketli, ikonlu ya da katlanan bir iz isteniyorsa breadcrumb-title kullanılır; page-header ise bu komponenti kendi links/pageTitle prop’larıyla İÇİNDE çizer.'
1120
+ ],
741
1121
  propNotes: {
742
- pageTitle: "Bant başlığı; page_container.title ile karıştırılmamalı. `description` diye bir prop YOKTUR (unknown-prop verir).",
743
- links: 'Sağ tarafta çizilen aksiyon/bağlantı listesi.',
744
- breadcrumbStyle: 'Kırıntı izinin görünüm biçimi.',
1122
+ homeTitle: 'Kök öğenin metni (varsayılan Homepage). Boş bırakılırsa kök öğe hiç çizilmez.',
1123
+ homeHref: "Kök öğenin adresi. Çözülüyorsa öğe bağlantı olur; boşken öğe yalnız clickItem bağlıysa tıklanabilir. clickItem yükünde kök öğenin index'i -1'dir.",
1124
+ items: "Aradaki öğeler: [{ title, href }]. Akıştan gelen düz metin dizisi ve label anahtarı da okunur. Dizi olmayan değer boş iz demektir (hata değil).",
1125
+ currentTitle: 'Bulunulan sayfanın adı; izin sonunda, tıklanamaz ve koyu çizilir. Kip etiketi için akıştan setter ile yazılır.',
1126
+ isLoading: 'true iken izin yerine üç nabız atan çubuk çizilir, hiçbir öğe basılmaz ve clickItem yayılmaz — items’ı mount akışından dolduran ekranda boş izin görünmesini engeller. mount BUNDAN BAĞIMSIZDIR: onu render katmanı atar, iskelet açıkken de gelir.',
1127
+ currentItem: "Şemada GİZLİ durum prop'u (panelde çizilmez): clickItem tıklanan öğeyi buraya yazar, akış self.currentItem ile okur. Kendin yazman gerekmez.",
1128
+ style: "Parçalar: KÖK (anahtarlar doğrudan style'da) satırın kendisi; '&__item' her kırıntı; '&__item--current' bulunulan sayfa."
1129
+ }
1130
+ },
1131
+ 'page-header': {
1132
+ summary: 'Sayfa başlığı bandı: links dizisinden çizilen kırıntı izi + ALTINDA h1 olarak pageTitle. İzdeki adresli öğe bağlantıdır, tıklama ayrıca clickItem yayar. KAPSAYICI DEĞİLDİR.',
1133
+ behavior: [
1134
+ 'İki katman, sırası sabit: üstte iz (links), altında başlık (pageTitle). İzi çizen breadcrumb komponentinin KENDİSİDİR (links → items, pageTitle → currentTitle, breadcrumbStyle → style): öğe türü seçimi (<a> / <button> / düz metin), sarma, düz metin dizisi ve label anahtarı okuma breadcrumb ile birebir aynıdır. Kök öğe (homeTitle) YOKTUR — kök gerekiyorsa links’in ilk satırı olarak yazılır; varsayılan Homepage satırı tam bunu yapar.',
1135
+ "links boşsa ya da dizi değilse (temizlenmiş prop null, henüz dolmamış {{ }} ifadesi) iz HİÇ çizilmez, yalnız başlık kalır — 2026-09-18'den önce dizi olmayan links çizim sırasında patlıyordu (links.length).",
1136
+ 'pageTitle izin SON öğesi olarak da basılır (tıklanamaz, aria-current="page") — başlığı links’e bir daha yazma. pageTitle boşsa başlık satırı boş kalır ve izde bulunulan sayfa öğesi çizilmez.',
1137
+ 'isLoading: iz ve başlık yerine iskelet çubukları (üç kırıntı çubuğu + bir başlık çubuğu). links henüz boşken de iz iskeleti çizilir ki mount akışı links’i doldurunca başlık aşağı zıplamasın. İskelet açıkken hiçbir öğe basılmaz ve clickItem yayılmaz; mount bundan bağımsızdır (render katmanı atar).',
1138
+ 'Olaylar: mount · clickItem. Katlanan iz ("…" menüsü), kök ikonu ya da öğe başına akış isteniyorsa breadcrumb-title; başlıksız yalnız iz isteniyorsa breadcrumb.',
1139
+ 'Düğüm boyu: başlık tek başına 40px (4 ızgara satırı), izle birlikte ≈ 62px (7 satır). Auto yükseklikle bırakılırsa içerik kadar uzar; sabit yükseklikte maxSize.h 12’dir — eski 4 satır sınırı izli başlığı sığdıramıyor, tutamaçtan boyutlandırılan düğümü 40px’e çökertiyordu (2026-09-18’de düzeltildi).'
1140
+ ],
1141
+ propNotes: {
1142
+ pageTitle: "Bant başlığı (h1) VE izin son öğesi; page_container.title ile karıştırılmamalı. `description` / altbaşlık diye bir prop YOKTUR (unknown-prop verir) — açıklama satırı için bandın altına ayrı bir text düğümü koy.",
1143
+ links: "Kırıntı izinin öğeleri: [{ title, href }], başlığın ÜSTÜNDE soldan sağa. Sağ tarafta aksiyon bağlantısı ÇİZMEZ (eski kayıt böyle diyordu, runtime hiç öyle çizmedi). Akıştan gelen düz metin dizisi ve label anahtarı da okunur; metinsiz satır düşer. Dizi olmayan değer = iz yok (hata değil).",
1144
+ isLoading: 'true iken iz ve başlık yerine iskelet çubukları çizilir, hiçbir öğe basılmaz, clickItem yayılmaz — links’i mount akışından dolduran ekranda boş bandın görünmesini engeller. mount BUNDAN BAĞIMSIZDIR.',
1145
+ currentItem: "Şemada GİZLİ durum prop'u (panelde çizilmez): clickItem tıklanan links satırını buraya yazar. Akış öğeyi event.data.currentItem ile okusun — self.currentItem ifade yüzeyine yalnız düğüm bu anahtarı kayıtta taşıyorsa çıkar (makine anahtar kümesini kurulurken düğümün prop'larından toplar, şemadan değil). Kendin yazman gerekmez.",
1146
+ breadcrumbStyle: "İzin stili, breadcrumb’ın style sözleşmesiyle aynı: kök anahtarlar izin satırı, '&__item' her kırıntı, '&__item--current' bulunulan sayfa (pageTitle’ın izdeki kopyası). İkinci bir stil prop’u olması bilinçli: style bandın kendisini ve '&__title' ile başlığı boyar.",
1147
+ style: "Bandın kendisi (kök anahtarlar: dikey flex, gap) + '&__title' başlık (h1). İzin görünümü buradan DEĞİL breadcrumbStyle’dan ayarlanır.",
745
1148
  isHidden: "Doğrudan şemaya yazılabilir. 2026-09-08 ölçümü: 101 kayıttan 99'u isHidden tanımlıyor, tanımlamayan yalnız 'slot' ve 'widget-area'."
746
1149
  }
747
1150
  },
@@ -858,8 +1261,51 @@ export const componentKnowledge = {
858
1261
  'isLoading davranış prop’udur (stil değil): açıkken alan içeriği yerine Loader çizilir.'
859
1262
  ]
860
1263
  },
861
- 'audit-basic': { summary: 'Kayıt meta kutusu (oluşturan/güncelleyen); meta prop’u tek setter ile beslenir.' },
862
- 'audit-history': { summary: 'Kayıt geçmişi listesi.' },
1264
+ 'audit-basic': {
1265
+ summary: 'Kayıt künyesi: oluşturan/son güncelleyen ve ne zaman. Tek setter ile meta prop’una kaydın meta nesnesi bağlanır.',
1266
+ behavior: [
1267
+ "meta, kaydı getiren get servisi adımının (get_service) data.meta'sıdır: createdAt, createdUserId, createdUserEmail, createdUserFirstName, createdUserLastName, createdUserFullName ve aynı updated* alanları. Ad önce *UserFullName, yoksa FirstName + LastName, o da yoksa e-posta; e-posta ad değilse alt satırda (createdSubtle/updatedSubtle doluysa onun yerine) basılır.",
1268
+ 'Taraf başına karar: meta o tarafın (created/updated) HERHANGİ bir alanını taşıyorsa o taraf TAMAMEN meta’dan okunur — createdBy/createdAt gibi statik prop’lar (şema varsayılanı John Doe) karışmaz. Meta tarafı hiç anmıyorsa statik prop’lar çizilir; kayıt yüklenene dek demo adın görünmemesi için createdBy/updatedBy’ı boş yaz.',
1269
+ 'Backend meta’yı YALNIZ entity’de denetim izi (AuditTrailType) açıksa ya da istekte history isteniyorsa ekler; değilse data.meta yoktur ve iki taraf da statik prop’ları (John Doe…) çizer — gerçek sayfada createdBy/updatedBy/createdAt/updatedAt’i boşalt ya da entity’de denetim izini aç.',
1270
+ 'Bir taraf ad ya da tarih taşımıyorsa hiç çizilmez; ikisi de boşsa yalnız title kalır. meta nesne değilse (null, metin, dizi) boş sayılır.',
1271
+ 'Tarih ISO metin (ya da Date) olmalı; başka biçim olduğu gibi basılır. Saatsiz tarih (2026-02-13) yalnız tarih olarak basılır. relative gelecekteki zamanı şimdi sayar ve canlı güncellenmez. Dil uygulama dilidir (locale prop’u yok).',
1272
+ 'isLoading açıkken iki satırlık iskelet çizilir. Runtime kendisi yazmaz: kaydı getiren akış başta true, meta’yı yazarken false yazar.'
1273
+ ],
1274
+ propNotes: {
1275
+ meta: "Kaydın meta nesnesi; değer {type:'storage', ref:'<adım ADI>.data.meta'}. Alanları behavior’da.",
1276
+ createdBy: 'Meta created* alanı taşımadığında basılan statik ad (varsayılan John Doe — gerçek sayfada boşalt).',
1277
+ updatedBy: 'Meta updated* alanı taşımadığında basılan statik ad (varsayılan Erick Gallagher — gerçek sayfada boşalt).',
1278
+ createText: 'Oluşturan satırının etiketi; boşsa uygulama dilinde "Oluşturan"/"Created by".',
1279
+ updateText: 'Güncelleyen satırının etiketi; boşsa uygulama dilinde "Güncelleyen"/"Updated by".',
1280
+ createIcon: 'Ad (person_add varsayılan) ya da IconProp nesnesi.',
1281
+ updateIcon: 'Ad (person_edit varsayılan) ya da IconProp nesnesi.',
1282
+ dateFormat: 'absolute (varsayılan; dilin kısa tarih + saat biçimi) | relative ("3 gün önce").',
1283
+ isLoading: 'true iken içerik yerine iskelet.',
1284
+ style: 'Kök + &__item (her satır) + &__icon (yuvarlak ikon kutusu).'
1285
+ }
1286
+ },
1287
+ 'audit-history': {
1288
+ summary: 'Kaydın işlem geçmişi: kim, ne zaman, ne yaptı ve hangi alan neden neye değişti. histories’e kaydın meta.history dizisi doğrudan bağlanır.',
1289
+ behavior: [
1290
+ "histories iki kayıt biçimini aynı kuralla okur. (1) Backend geçmişi — kaydı getiren get servisi adımının data.meta.history'si: { id, occurredAt, userId, userEmail, userFirstName, userLastName, action: CREATE|UPDATE|DELETE, ipAddress, changedFields: [{ fieldId, fieldSlug, fieldName, previousValue, currentValue }] }. (2) Kart alanları — { type, title, username, createdAt, status, statusLabel, icon, previousValue, currentValue }. Kart alanı doluysa kazanır, boşsa backend alanından türetilir: username ← userFirstName + userLastName ← userEmail; createdAt ← occurredAt; status/statusLabel/title/icon ← action (CREATE success 'Oluşturuldu'/'kaydı oluşturdu.', UPDATE primary 'Güncellendi', DELETE danger 'Silindi'; dil bileşenin dili).",
1291
+ 'changedFields’ın her satırı kartta "fieldName: önceki → şimdiki" satırı olur (fieldName yoksa fieldSlug); iki değeri de boş satır çizilmez. Değer nesneyse JSON basılır. Üst düzey previousValue/currentValue etiketsiz tek satırdır.',
1292
+ 'meta.history İKİ şartla gelir: (1) kaydı getiren get servisi adımının kaynak ayarında includeHistory: true (kapalıysa data.meta hiç oluşmaz), (2) entity’de denetim izi (AuditTrailType) Basic ya da Detailed (ya da adımın requestedHistoryType’ı; entity türünü aşarsa istek hata verir). Simple’da history null’dır; changedFields yalnız Detailed’da dolar. Tek ya da liste getirmede kayıt başına EN YENİ 5 işlem gelir ve eskisini sayfa sayfa getiren bir akış yolu yoktur (meta.historyTotalCount toplamı söyler).',
1293
+ 'Sıralama yapılmaz: dizi geldiği sırayla çizilir (backend en yeniyi başa koyar). Nesne olmayan öğe (null, metin) atlanır; histories dizi değilse boş durum çizilir.',
1294
+ 'visibleLogCount üstü kayıtlar atılmaz: altta "Daha fazla göster (N)" çıkar, her basış sınırı visibleLogCount kadar büyütür ve showMore yayar. Boş/0 = hepsi görünür. Backend en fazla 5 işlem verdiği için meta.history bağlıyken düğme ancak visibleLogCount 5’ten küçükken görünür; showMore veri çekmez. Açılan sınır histories değişince (başka kayda geçince de) SIFIRLANMAZ.',
1295
+ 'Şema varsayılanı 5 demo kayıttır (James Anderson…): gerçek sayfada histories’i akışa bağla; kayıt gelene dek demo görünmesin istiyorsan başlangıçta isLoading true ya da histories [] yaz.',
1296
+ 'isLoading açıkken 5 satırlık iskelet çizilir; runtime kendisi yazmaz, akış yazar.'
1297
+ ],
1298
+ propNotes: {
1299
+ histories: "Değer {type:'storage', ref:'<adım ADI>.data.meta.history'} ya da kart alanlarıyla dizi; iki biçim behavior’da.",
1300
+ visibleLogCount: 'İlk görünen kayıt sayısı (varsayılan 15); aşılınca "Daha fazla göster" çıkar. Boş/0 = hepsi.',
1301
+ showMoreText: 'Düğme metni; boşsa dilde "Daha fazla göster"/"Show more". Yanına gizli kayıt sayısı eklenir. Panelde yalnız visibleLogCount doluyken görünür.',
1302
+ emptyText: 'Liste boşken başlık; boşsa dilde "Geçmiş kaydı bulunmuyor" + açıklama. Doluysa açıklama çizilmez.',
1303
+ dateFormat: 'absolute (varsayılan; "11 Mart 2026 09:24") | relative ("3 gün önce", canlı güncellenmez, gelecek zaman şimdi sayılır). ISO olmayan metin olduğu gibi basılır.',
1304
+ locale: 'Tarih, işlem etiketi ve boş durum dili; boşsa uygulama dili.',
1305
+ isLoading: 'true iken içerik yerine iskelet.',
1306
+ style: 'Kök + &__title, &__item (her kart), &__icon (yuvarlak ikon), &__status (durum rozeti), &__empty (boş durum kutusu).'
1307
+ }
1308
+ },
863
1309
  'document-editor': { summary: 'Office şablon doldurma/görüntüleme editörü; file prop’una drive dosyası bağlanır.', propNotes: { surfaceStyle: NODE_SURFACE_NOTE } },
864
1310
  'qm-header': {
865
1311
  summary: 'QM uygulama başlığı: global arama, bildirimler, hesap menüsü, çok seviyeli mega menü.',
@@ -906,74 +1352,137 @@ export const componentKnowledge = {
906
1352
  }
907
1353
  },
908
1354
  avatar: {
909
- summary: 'Kullanıcı avatarı: src yoksa isimden baş harf üretir; items verilirse üst üste binen grup ve "+N" kuyruğu çizer.',
910
- behavior: ["click olayı yalnız bağlıysa komponent tıklanabilir hâle gelir (image deseni)."],
1355
+ summary: 'Kullanıcı avatarı: src yoksa isimden baş harf, ad da yoksa fallbackIcon çizer; items verilirse üst üste binen grup ve "+N" kuyruğu olur.',
1356
+ behavior: [
1357
+ 'click olayı yalnız bağlıysa komponent tıklanabilir hâle gelir (image deseni); isLoading açıkken tıklanmaz.',
1358
+ 'İçerik önceliği HER kipte aynı: src → name baş harfleri → fallbackIcon. Yani name doluyken ikon çizilmez; ikonun görünmesi için name boş olmalı.',
1359
+ 'Akıştan boş dizi gelirse emptyText yazılır. emptyText VERİLMEMİŞSE bileşen tekil avatara düşer (src/name, ikisi de boşsa person ikonu) — yani "kimse yok" demenin tek yolu emptyText doldurmaktır; grup bağlarken onu da ver.',
1360
+ 'mount akış tetikler: items’ı dolduran sorgu buradan koşulur, yükleniyor süresince isLoading ile nabız atan daire çizilir.'
1361
+ ],
911
1362
  propNotes: {
912
1363
  src: 'Görsel URL’i ya da drive dosyası; yüklenemezse baş harflere düşer.',
913
- items: 'Grup kipi: her öğe kendi src/name’ini taşır, maxCount üstü "+N" olur.'
1364
+ name: 'Baş harflerin üretildiği ad; VARSAYILANI YOKTUR. Doluyken fallbackIcon çizilmez.',
1365
+ fallbackIcon: "Ne görsel ne ad varken çizilen ikon; varsayılanı { name: 'person' }.",
1366
+ items: 'Grup kipi: her öğe kendi src/name’ini taşır, maxCount üstü "+N" olur. Boş dizi = emptyText.',
1367
+ emptyText: 'items DİZİ olarak gelip boş olduğunda yazılır; src/name bunu engellemez. Boş bırakılırsa boş grup tekil avatar gibi çizilir.',
1368
+ status: 'Sağ alt köşedeki durum noktası; yalnız TEKİL avatarda çizilir (grupta kimin olduğu belirsiz olurdu).',
1369
+ hasRing: 'Avatarın çevresindeki halka — tekil ve grup kipinde de çizilir; grupta üst üste binen avatarları ayıran şey odur.',
1370
+ ringColor: 'Halkanın rengi; boş bırakılırsa yüzey rengi kullanılır (kart içinde görünmez, renkli zeminde bunu doldur).',
1371
+ isLoading: 'İçerik yerine nabız atan nötr daire(ler) çizer; rozet, durum noktası ve tıklama kapanır.'
914
1372
  }
915
1373
  },
916
1374
  badge: {
917
1375
  summary: 'Sayaç/durum rozeti: maxCount üstü "99+" olur, 0 showZero verilmedikçe gizlenir, isDot ile salt nokta çizer.',
918
1376
  behavior: [
919
1377
  'value SAYIYSA sayaç kuralları işler (0 gizlenir, maxCount aşılırsa "99+"); sayıya çevrilemeyen metin ("Yeni", "Beta") olduğu gibi basılır — durum rozeti böyle kurulur.',
920
- 'isDot:true iken value · icon · maxCount OKUNMAZ, yalnız renkli nokta çizilir; nokta tek başına anlam taşıyorsa dotLabel doldurulmalı (yoksa ekran okuyucuya aria-hidden geçilir).',
921
- 'isPulsing nabız animasyonu ekler ve prefers-reduced-motion açık kullanıcıda kendiliğinden durur.',
922
- "click yalnız şemada bağlıysa yayılır (avatar/image deseni): bağlıyken rozet <button> olur, tıklanabilir görünür ve odak sırasına girer; bağlı değilken salt görsel <span>'dir."
923
- ],
924
- propNotes: {
925
- value: 'Sayı ya da metin; boş string rozeti tamamen gizler.',
926
- icon: 'Metnin soluna küçük ikon; nokta kipinde çizilmez.',
927
- dotLabel: 'Nokta kipinin erişilebilir etiketi (title + aria-label).',
928
- isPulsing: 'Nabız animasyonu — canlı/bekleyen durum vurgusu.',
929
- variant: 'solid | soft | outline — soft ve outline rengi metne taşır, zemini şeffaflaştırır.',
930
- size: 'sm | md | lg — yalnız ölçü değişir, sayaç kuralları aynı kalır.'
1378
+ 'isDot:true iken value · icon · maxCount · showZero · variant · shape · textColor OKUNMAZ, yalnız renkli nokta çizilir (color ve size okunur); nokta tek başına anlam taşıyorsa dotLabel doldurulmalı (yoksa ekran okuyucuya aria-hidden geçilir).',
1379
+ 'isPulsing YALNIZ nokta kipinde çizilir (panelde de yalnız isDot açıkken görünür): sayaç/metin rozetine verilmesi hiçbir şey yapmaz. prefers-reduced-motion açık kullanıcıda animasyon kendiliğinden durur.',
1380
+ "click yalnız şemada bağlıysa yayılır (avatar/image deseni): bağlıyken rozet <button> olur, tıklanabilir görünür ve odak sırasına girer; bağlı değilken salt görsel <span>'dir.",
1381
+ 'TIKLANABİLİR NOKTA İÇİN dotLabel ZORUNLU: nokta kipinde rozetin metni yoktur, click bağlıyken aria-hidden da basılmaz — dotLabel boşsa ekranda adsız bir düğme kalır ve ekran okuyucu onu "düğme" diye okur.',
1382
+ 'Rozet kendi başına durur; başka bir bileşenin köşesine yapışmaz — saydığı şeyin yanına yerleştirilir (button ve icon kendi köşe rozetlerini kendileri çizer).',
1383
+ 'Rozetin kendi hover ipucu prop’u YOKTUR: maxCount sayıyı kısalttığında gerçek değeri göstermek için düğümün ortak appearance.tooltip kanalını kullan — panelde Properties sekmesinin "Görünürlük ve kimlik" bölümündedir, Görünüm sekmesinde değil (nokta kipinde dotLabel zaten title olur).',
1384
+ 'Chip kipinde tıklanabilir rozetin erişilebilir adı çizilen metnin kendisidir: sayaç rozetinde bu yalnız "99+" gibi bir sayıdır ve tek başına ne yaptığını söylemez — sayaca tıklama bağlıyorsan düğümün ortak ipucu alanını da doldur.',
1385
+ 'mount düğüm çizilince bir kez yayılır (sayaç sorgusunu buradan başlat).'
1386
+ ],
1387
+ propNotes: {
1388
+ value: 'Sayı ya da metin; boş string (ve showZero kapalıyken 0) rozeti tamamen gizler — icon dolu olsa bile hiçbir şey çizilmez. Şemadaki 5 varsayılanı TASARIM ANI değeridir: paletten bırakılan düğüme yazılır, ama düğüm value taşımıyorsa runtime varsayılanı boş stringtir ve rozet HİÇ çizilmez. Rozeti buradan kurarken value’yu açıkça yaz (CQ-265).',
1389
+ icon: 'Metnin soluna küçük ikon; nokta kipinde ve value boşken çizilmez.',
1390
+ dotLabel: 'Nokta kipinin erişilebilir etiketi (title + aria-label). Nokta tıklanabilirse zorunludur; yalnız isDot açıkken panelde görünür.',
1391
+ isPulsing: 'Nabız animasyonu — yalnız nokta kipinde etkilidir (canlı/bekleyen durum vurgusu).',
1392
+ color: "Rozetin zemin/çerçeve rengi. custom seçilip customColor geçersiz bir renkse semantik varsayılana (primary) düşer, siyaha boyamaz.",
1393
+ variant: 'solid | soft | outline — soft ve outline rengi metne taşır, zemini şeffaflaştırır. Nokta kipinde okunmaz.',
1394
+ shape: 'pill | rounded | square — köşe yarıçapı; nokta kipinde okunmaz.',
1395
+ textColor: "Boş bırakılırsa metin rengi zemine göre OTOMATİK seçilir (warning/info gibi açık zeminde koyu metin) ve doğru olan genelde budur. Doldurulursa otomatik kontrast devre dışı kalır; custom + geçersiz renk primary değerine DÜŞMEZ, otomatiğe geri döner.",
1396
+ size: 'sm | md | lg — yalnız ölçü değişir, sayaç kuralları aynı kalır.',
1397
+ style: "Özel CSS; parçalar &__icon ve &__text (nokta kipinde ikisi de yoktur, style yalnız köke iner)."
931
1398
  }
932
1399
  },
933
1400
  'breadcrumb-title': {
934
- summary: 'Kalın sayfa başlığı + önünde daralan kırıntı izi; eski mustache "doküman başlık" HTML widget’ının komponent karşılığı.',
1401
+ summary: 'Kalın sayfa başlığı + önünde daralan kırıntı izi; eski mustache "doküman başlık" HTML widget’ının komponent karşılığı. KAPSAYICI DEĞİLDİR, çocuk almaz.',
935
1402
  behavior: [
936
- "Son maxVisibleItems öğe satır içinde kalır, öncekiler '…' menüsüne toplanır (varsayılan 1; 0 = izin tamamı menüde).",
937
- "Öğeye tıklamak önce öğenin KENDİ flow'unu çalıştırır, sonra clickItem yayar (dropdown-button sözleşmesi).",
938
- 'rootHref verilmişse kök ikonu ona gider ve rootFlow ÇALIŞMAZ — href akışı ezer.'
1403
+ "Son maxVisibleItems öğe satır içinde kalır, öncekiler '…' menüsüne toplanır (varsayılan 1; 0 = izin tamamı menüde). Daralma SAYIYLA olur, genişlikle değil — dar düğümde satır içi öğeler kısalıp üç nokta ile biter.",
1404
+ "Öğeye tıklamak önce öğenin KENDİ flow'unu çalıştırır, sonra clickItem yayar (dropdown-button sözleşmesi). Tıklanan öğe düğümün currentItem prop'una yazılır: akış self.currentItem.key ile hangi adımın seçildiğini okur.",
1405
+ 'rootHref verilmişse kök ikonu ona gider ve rootFlow ÇALIŞMAZ — href akışı ezer; clickRoot ise HER durumda yayılır (2026-09-17: href yazılıyken sessizce yutuluyordu). Dış adres (http, https, mailto, tel) tam sayfa gezinmesiyle açılır, uygulama içi yol router ile.',
1406
+ 'isLoading açıkken iz ve başlık yerine iskelet çubukları çizilir; o sırada tıklanacak öğe yoktur. Veriyi mount olayına bağlanan akış getiriyorsa bunu aç, satır boy değiştirmesin.'
939
1407
  ],
940
1408
  propNotes: {
941
- items: '[{ text, flow, isHidden }] — sıralı iz; isHidden olanlar sayımdan önce elenir.',
942
- maxVisibleItems: 'Satır içinde kalacak öğe sayısı (varsayılan 1).'
1409
+ items: '[{ key, text, flow, isHidden }] — sıralı iz; isHidden olanlar sayımdan önce elenir. key tıklanan öğeyi akışta tanımak içindir (tasarımcı text’ten snake_case üretir), flow öğenin kendi akışıdır.',
1410
+ maxVisibleItems: 'Satır içinde kalacak öğe sayısı (varsayılan 1).',
1411
+ rootIcon: 'Kök (ana sayfa) ikonu; NESNE bekler: { name: home }. Üretilen şema tipi string der ama runtime name alanını okur — düz metin de kabul edilir, runtime onu nesneye çevirir. Boş bırakılırsa kök düğmesi hiç çizilmez ve rootHref/rootFlow ulaşılamaz kalır.',
1412
+ title: 'Sayfa başlığı; izin EN SAĞINDA, kalın. Şema varsayılanı Page title ve runtime da aynı varsayılanı çizer (CQ-265). Boş bırakılırsa yalnız iz görünür.',
1413
+ isLoading: 'İçerik yerine iskelet çizer (iz çubuğu + başlık çubuğu). Akış izi yazana kadar açık tutulur.'
943
1414
  }
944
1415
  },
945
1416
  carousel: {
946
- summary: 'Ok/nokta/altyazı ve isteğe bağlı otomatik oynatmalı görsel slider.',
947
- behavior: [
948
- "activeIndex tek doğruluk kaynağıdır: her gezinme slideChange yayar ve indeksi komponentin kendi prop'una yazar; akıştan atanan aralık dışı değer SARILMAZ, son slayta kırpılır.",
949
- 'Slaytta href ya da flow varsa slayt tıklanabilir <a> olur; slideClick yükü tıklanan slaytı ve indeksini taşır.',
950
- 'autoplay + interval (saniye, en az 1) ve pauseOnHover birlikte çalışır; loop kapalıyken uçtaki ok pasifleşir.'
951
- ],
952
- propNotes: {
953
- items: '[{ src, title, description, alt, href, flow }] — src drive dosyası ya da URL.',
954
- activeIndex: 'Görünen slayt; setter ile dışarıdan da sürülebilir.',
955
- fit: 'cover | contain | fill | none (card.imageFit ile aynı sözleşme).'
1417
+ summary: 'Ok/nokta/altyazı ve isteğe bağlı otomatik oynatmalı görsel şerit; slidesPerView ile aynı anda birden çok slayt gösterir.',
1418
+ behavior: [
1419
+ "activeIndex tek doğruluk kaynağıdır: her gezinme slideChange yayar ve indeksi komponentin kendi prop'una yazar; akıştan atanan aralık dışı değer SARILMAZ, son KONUMA kırpılır.",
1420
+ 'SLAYTLAR BİR ŞERİTTİR, tek tek takas edilmez. slidesPerView (varsayılan 1) aynı anda kaç slaytın görüneceğini söyler; 1 iken klasik tek slaytlık carousel. activeIndex İLK GÖRÜNEN slaytın indeksidir, sayfa numarası DEĞİL — üst sınırı length - slidesPerView’dır (10 slayt + slidesPerView:4 ile en büyük geçerli değer 6; 9 yazarsan 6’ya kırpılır, yoksa şeridin sonunda boşluk kalırdı).',
1421
+ 'İstenen slidesPerView dar viewport’ta KENDİLİĞİNDEN DÜŞER: slayt başına 160 pikselin altına inilmez. Yani slidesPerView:4 yazdığın bir carousel dar bir ızgara hücresinde 2 slayt gösterebilir; activeIndex’in üst sınırı ve nokta sayısı da o an görünen sayıya göre hesaplanır.',
1422
+ 'loop SONSUZ ŞERİTTİR (2026-09-17): şeridin iki yanına görünen slayt sayısı kadar klon eklenir, uca gelince şerit klona doğru animasyonla kayar ve sonra animasyonsuz gerçek slayta sıçrar — kullanıcı kesintisiz ileri akış görür, geri sarma olmaz. Klonlar akışa SIZMAZ: activeIndex her zaman gerçek slayt uzayındadır (son slayttan sonra 0) ve slideClick tıklanan klonun değil ORİJİNALİN indeksini gönderir. Noktalar da klonları saymaz. Kesintisiz akış yalnız transition:slide iken görünür; none ve fade’de şerit doğrudan atlar (o iki kipte transform geçişi yoktur).',
1423
+ 'NOKTALAR SLAYT DEĞİL KONUM SAYAR. Nokta sayısı = şeridin durabileceği konum sayısı (slidesToScroll adımıyla). 10 slayt + slidesPerView:4 + slidesToScroll:4 → 0, 4 ve uca yapışan 6, yani ÜÇ nokta. slidesPerView:1 + slidesToScroll:1 iken sayı yine slayt sayısına eşittir.',
1424
+ 'KAYDIRACAK YER YOKSA KONTROL ÇİZİLMEZ: slidesPerView listeyi kaplıyorsa (4 slayt, slidesPerView:4) ok ve noktalar hiç görünmez ve otomatik geçiş sayacı KURULMAZ — showArrows/showDots/autoplay açık olsa bile.',
1425
+ "slideChange ve slideClick yüklerini akışın event.data alanına da gönderir (params): event.data.activeIndex, event.data.currentItem, event.data.index. Üst düzey data ayrıca düğümün prop'una yazılır — activeIndex ve currentItem self ile de okunur, index YAZILMAZ.",
1426
+ 'slideClick HER slayt tıklamasında yayılır, href/flow şart değil. Slaytta href ya da flow varsa slayt tıklanabilir <a> olur; flow varsa panelde bağlı slideClick akışı ile slaytın kendi akışı İKİSİ birden çalışır.',
1427
+ 'autoplay + interval (saniye, en az 1) ve pauseOnHover birlikte çalışır; loop kapalıyken uçtaki ok pasifleşir ve otomatik geçiş son slaytta DURUR. Elle gezinme (ok/nokta/klavye/swipe) sayacı sıfırdan başlatır.',
1428
+ 'transition fade YALNIZ slidesPerView:1 iken anlamlıdır; çok kartlı şeritte söndürülecek tek slayt yoktur ve runtime onu slide gibi çalıştırır (panelde de gizlenir). Kayıtlı bir sayfa fade taşırken slidesPerView büyütülürse prop değeri yerinde kalır, davranış slide olur.',
1429
+ 'Enum dışı ya da boş fit değerinde varsayılan uygulanır. İKİ AYRI EŞİK var: 50 pikseli aşan yatay sürükleme slaytı KAYDIRIR, tıklama bastırması ise 5 pikselde başlar — yani 5 pikselden fazla kayan parmak/fare slaytı ilerletmese bile slideClick YAYMAZ (dokunmatikte en sık karşılaşılan “bazen çalışmıyor” sebebi). href taşıyan slaytta emit bastırılır ama tarayıcı yine de gezinir. Klavyeden yalnız href ya da flow taşıyan slayt tetiklenir; düz slayt yalnız fare/dokunma ile.'
1430
+ ],
1431
+ propNotes: {
1432
+ items: '[{ src, title, caption, description, alt, href, flow }] — src drive dosyası ya da URL.',
1433
+ activeIndex: 'İLK GÖRÜNEN slaytın indeksi (sayfa numarası değil); setter ile dışarıdan da sürülebilir. Üst sınır length - slidesPerView.',
1434
+ slidesPerView: 'Aynı anda görünen slayt sayısı (varsayılan 1). Dar viewport’ta slayt başına 160 pikselin altına düşmemek için kendiliğinden azalır — dikey yönelimde bu ölçü YÜKSEKLİKTİR.',
1435
+ orientation: 'horizontal (varsayılan) | vertical — şeridin akış yönü. Dikeyde slaytlar alt alta dizilir, oklar üst/alt kenara geçer, noktalar sağda dikey durur, klavye yukarı/aşağı okları dinler ve sürükleme dikey eksende çalışır. chart ve timeline ile aynı prop adı ve aynı enum.',
1436
+ slidesToScroll: 'Bir ok/nokta/otomatik geçiş adımının kaç slayt kaydıracağı (varsayılan 1). Sayfa sayfa kaydırmak için slidesPerView ile aynı değeri ver.',
1437
+ gap: 'Slaytlar arası boşluk (piksel). slidesPerView:1 iken görünür bir etkisi yoktur.',
1438
+ isCentered: 'Aktif slayt viewport’un ORTASINDA durur. Açıkken peek payının yerini merkezleme payı alır (ikisi toplanmaz) ve HER slayt ortalanabildiği için activeIndex’in üst sınırı length - slidesPerView değil length - 1 olur; nokta sayısı da buna göre artar.',
1439
+ isDraggable: 'Fare ve dokunmatik sürükleme (varsayılan açık). Kapatınca şerit yalnız ok, nokta ve klavye ile gezilir — olaylar ve setter değişmez.',
1440
+ autoWidth: 'Slayt genişliğini İÇERİĞİNDEN alır (varsayılan kapalı). Açıkken slidesPerView ETKİSİZDİR — genişliği artık içerik belirler — ve öteleme yüzdeden değil ölçülen konumdan çıkar. Her slayt bir duraktır, yani activeIndex’in üst sınırı length - 1 olur ve nokta sayısı slayt sayısına eşittir; bunun bedeli son slayt başa gelince şeridin sonunda boşluk kalabilmesidir.',
1441
+ lazyLoad: 'Yalnız görünen ve komşu slaytların görseli yüklenir (varsayılan AÇIK). Şerit bütün slaytları DOM’a koyduğu için kapalıyken 30 slaytlık bir carousel açılışta 30 görsel çeker. Pencere dışındaki slaytın src’si hiç yazılmaz; alt metni ve altyazısı yerinde kalır, slideClick yükü etkilenmez.',
1442
+ lazyLoadEager: 'Görünen pencerenin İKİ yanında kaç slayt önden yüklenir (varsayılan 1). lazyLoad kapalıyken panelde gizlenir.',
1443
+ transitionDuration: 'Şeridin kayma süresi, milisaniye (varsayılan 260). 1 ms’in altındaki değer varsayılana döner: sıfıra yakın süre transitionend yaymaz ve sonsuz şeridin klon gezintisi orada asılı kalırdı.',
1444
+ peek: 'Şeridin iki yanında bırakılan pay (piksel): komşu slayttan bir dilim görünür ve şeridin devam ettiği anlaşılır (Owl’daki stagePadding).',
1445
+ aspectRatio: 'Slayt kutusunun en-boy oranı, CSS yazımıyla ("16/9"). Boş bırakılırsa oran dayatılmaz ve yükseklik kaptan gelir.',
1446
+ showTitle: 'Altyazı kutusundaki BAŞLIK satırı. showCaption kapalıyken etkisizdir.',
1447
+ showCaptionText: 'Altyazı kutusundaki caption ALANI. Adı showCaption’a benziyor ama aynı şey değil: showCaption bütün kutunun kapısıdır, bu yalnız o tek satırı gizler. Üç alanın üçü de boş ya da kapalıysa kutu HİÇ çizilmez.',
1448
+ showDescription: 'Altyazı kutusundaki AÇIKLAMA paragrafı. showCaption kapalıyken etkisizdir.',
1449
+ fit: 'cover | contain | fill | none (card.imageFit ile aynı sözleşme); tanınmayan değerde ilk seçenek uygulanır.',
1450
+ transition: 'none | fade | slide — şeridin kayışına uygulanan animasyon. fade yalnız slidesPerView:1 iken gerçekten solar; çok kartlıda slide gibi davranır.',
1451
+ currentItem: 'Salt YAZILIR: slideClick tıklanan slaytı buraya koyar (self.currentItem); panelde çizilmez.',
1452
+ style: 'BEM parçaları: &__viewport, &__slide, &__caption, &__arrow, &__dots, &__dot.'
956
1453
  }
957
1454
  },
958
1455
  chart: {
959
- summary: 'ECharts tabanlı grafik (bar/line/area/pie/donut + waterfall, histogram, pareto, bullet, tornado, radial). VERİ ÇEKMEZ: satırlar rows prop’una akışla yazılır.',
1456
+ summary: 'ECharts tabanlı grafik (bar/line/area/pie/donut + waterfall, histogram, pareto, bullet, tornado, radial, funnel, gauge, radar, funnelflow, scatter). VERİ ÇEKMEZ: satırlar rows prop’una akışla yazılır.',
960
1457
  behavior: [
961
1458
  "Veri prop'u data DEĞİL rows'tur (data eski adıdır, yalnız geriye uyumluluk için duruyor). Kategori categoryField, değerler series[].valueField ile çözülür.",
962
1459
  'seriesField + valueField birlikte verilirse satırlar "kategori+seri başına bir satır" sayılıp geniş biçime pivotlanır; series dizisi o zaman prop’tan değil veriden türetilir.',
963
1460
  'aggregate/sort/topN/nullMode veriyi çizimden ÖNCE dönüştürür — aynı işi akışta yapmana gerek yok.',
964
1461
  'isDrillDown:true iken veri noktasına tıklamak kırıntı seviyesi ekler; dataPointClick yükü kaynak satırın TAMAMINI (row) taşır, böylece alt seviye sorgusu tek olayla kurulur. Geri dönüş breadcrumbClick ile bildirilir ve yeniden sorgulamak akışın işidir.',
965
1462
  'isExportable "tablo olarak gör" + dışa aktarma araç çubuğunu açar; showRefresh refresh olayını yayan bir yenile düğmesi ekler.',
966
- "PASTA/HALKA ETİKETİ (2026-08-27 düzeltmesi): dataLabels.show artık pie/donut'a da geçiyor. Öncesinde prop bu dala hiç ulaşmıyordu ve dilim etiketleri HİÇBİR ayarla kapatılamıyordu — çekme çizgileri legend'in üstüne bindiği için halka fiilen kullanılamıyordu. Temiz halka için dataLabels:{ show:false } yaz."
1463
+ "PASTA/HALKA ETİKETİ (2026-08-27 düzeltmesi): dataLabels.show artık pie/donut'a da geçiyor. Öncesinde prop bu dala hiç ulaşmıyordu ve dilim etiketleri HİÇBİR ayarla kapatılamıyordu — çekme çizgileri legend'in üstüne bindiği için halka fiilen kullanılamıyordu. Temiz halka için dataLabels:{ show:false } yaz.",
1464
+ 'LEGENDDEN SERİ GİZLEME ÇALIŞIYOR (2026-09-16 düzeltmesi): legend tıklaması artık kalıcı. Öncesinde tıklama ~8 ms sonra kendiliğinden geri alınıyordu — olay yükü prop’lara yazılıyor, tepkime notMerge çizim yapıyor ve ECharts’ın legend.selected durumu siliniyordu. Seçim çizimden önce option’a geri yazılıyor; listede olmayan seri adları elenir.',
1465
+ 'YATAY + İKİNCİL EKSEN ÇİZİLİYOR (2026-09-16 düzeltmesi): orientation:"horizontal" ile bir seride axis:"secondary" birlikte verilince grafik SESSİZCE boş çiziliyordu — yatayda değer eksenleri xAxis dizisindedir, yAxis tek kategori eksenidir. Kombo grafiği artık iki yönelimde de kurulabilir.',
1466
+ 'RENK KURALLARI (colorRules) artık waterfall, histogram, pareto ve bullet’ta da uygulanıyor. Panelde görünüp hiçbir şey yapmıyorlardı. Kural neyi sınar: waterfall’da İŞARETLİ delta, histogram’da kutunun frekansı, pareto/bullet/scatter’da barın/noktanın kendi değeri, pie/donut ve kartezyende dilim değeri, gauge’de tek sayı.',
1467
+ 'ANIMATION her tipte okunuyor (2026-09-16): animation:{ enabled,duration,easing } önceden yalnız bar/line/area/tornado dalına yazılıyordu, pie/gauge/waterfall/… için ölü bir proptu.',
1468
+ 'PANELDE GÖRÜNMEYEN AYAR ÖLÜ AYAR DEĞİL: barStyle, useDecalPatterns, sampling, isLarge, isZoomable, selectionMode, dataLabels ve legend artık yalnız kendi builder’larının OKUDUĞU tiplerde görünür. Bir ayarı panelde bulamıyorsan seçtiğin chartType onu okumuyor demektir — zorlamak yerine tipi değiştir.'
967
1469
  ],
968
1470
  propNotes: {
969
1471
  rows: 'Satır dizisi; mount/filter akışlarının setter hedefi.',
970
1472
  legend: "{ show, position, orient, showValues }. position artık DÖRT yön: top | bottom | left | right (2026-08-27). Yana yaslanan legend her zaman dikey çizilir — yatay seçilse bile ezilir, çünkü yandaki yatay legend grafiğin üstüne biner. showValues YALNIZ pasta/halkada iş görür: seri adının yanına dilim değerini yazar.",
971
1473
  centerLabel: "{ show, text, subtext } — YALNIZ donut. text boş bırakılırsa dilim değerlerinin TOPLAMI yazılır (valueFormat uygulanır), yani 'ortadaki toplam' için ayrı bir setter gerekmez. Pastada delik olmadığı için görünmez ve panelde gizlidir.",
972
- categoryField: 'Kategori ekseni alan adı (varsayılan "label").',
1474
+ categoryField: 'Kategori ekseni alan adı (varsayılan "label"). SCATTER’DA x ekseninin SAYISAL kolonudur (y = series[0].valueField) — eski xField adı geriye uyumluluk için ayrılmış durumda, onu kullanma.',
973
1475
  series: "[{ valueField, type?, axis?, color?, stack?, lowField/highField?, targetField? }] — yFields'ın yerini aldı.",
974
1476
  stackMode: 'none | stacked | percent.',
975
- dataLabels: "{ show, position, content, showTotal }. showTotal YALNIZ stackMode:'stacked' iken iş görür: her yığının tepesine (yatayda sağına) dilimlerin toplamını yazar, valueFormat uygulanır; toplam EKSENE ve LEGEND'e GİRMEZ. 2026-09-15 düzeltmesi — öncesinde toplam şeffaf bir seri olarak yığına ekleniyordu: değer ekseni gerçek en yüksek yığının İKİ KATINA çıkıyor, toplam etiketi barın çok üstünde boşlukta duruyor ve legend'de '<grup>__total' diye dördüncü bir madde beliriyordu (S-18). percent modunda etkisizdir.",
976
- isDrillDown: 'Veri noktası tıklamasını kırıntı seviyesine çevirir; sorguyu akış yeniler.'
1477
+ dataLabels: "{ show, position, content, showTotal }. showTotal YALNIZ stackMode:'stacked' iken iş görür: her yığının tepesine (yatayda sağına) dilimlerin toplamını yazar, valueFormat uygulanır; toplam EKSENE ve LEGEND'e GİRMEZ. 2026-09-15 düzeltmesi — öncesinde toplam şeffaf bir seri olarak yığına ekleniyordu: değer ekseni gerçek en yüksek yığının İKİ KATINA çıkıyor, toplam etiketi barın çok üstünde boşlukta duruyor ve legend'de '<grup>__total' diye dördüncü bir madde beliriyordu (S-18). İŞARETİ KARIŞIK yığın İKİ etiket yazar (2026-09-16): ECharts pozitifleri yukarı, negatifleri aşağı ayrı yığar, o yüzden pozitif dilimlerin toplamı üstte, negatiflerinki altta durur — tek bir 'net' sayı yanlış barın ucuna düşüyordu. percent modunda etkisizdir.",
1478
+ isDrillDown: 'Veri noktası tıklamasını kırıntı seviyesine çevirir; sorguyu akış yeniler. scatter’da yoktur: noktanın kategori adı yok.',
1479
+ caption: 'Grafiğin ALTINA yazılan açıklama satırı (DOM metni, kanvasın parçası değil). 2026-09-16 öncesinde prop panelde vardı ama hiçbir yere çizilmiyordu.',
1480
+ subtitle: 'Başlığın altına yazılır. Başlık boş bırakılsa da çizilir (2026-09-16 öncesinde title boşken subtitle kayboluyordu).',
1481
+ chartType: "bar | line | area | pie | donut | waterfall | histogram | pareto | bullet | tornado | radial | funnel | gauge | radar | funnelflow | scatter. SEÇİLEN TİP hangi ayarların OKUNDUĞUNU belirler; panel de ona göre gizler.",
1482
+ sizeField: 'YALNIZ scatter: nokta çapını ölçekleyen sayısal kolon (kabarcık grafiği). Boş bırakılırsa bütün noktalar aynı boyda çizilir.',
1483
+ barStyle: '{ barWidth, maxBarWidth, barGap, categoryGap, borderRadius, minBarSize } — YALNIZ bar ve tornado okur. minBarSize çok küçük değerlerin görünmez kalmasını engeller (ECharts barMinHeight); 2026-09-16 öncesinde şemada duruyor ama hiçbir yerde okunmuyordu.',
1484
+ categoryAxis: '{ title, isReversed, labelRotate, gridLines }. Kategori ekseni HER ZAMAN kategori eksenidir; bir zaman ekseni anahtarı vardı, çizilemeyen bir option ürettiği için 2026-09-16’da kaldırıldı. scatter’da bu prop x (değer) eksenini ayarlar.',
1485
+ colorRules: '[{ operator, value, valueTo, color }] — ilk eşleşen kural kazanır. radial/funnel/radar/funnelflow dışındaki her tipte uygulanır.'
977
1486
  }
978
1487
  },
979
1488
  checkboxgroup: {
@@ -1000,37 +1509,52 @@ export const componentKnowledge = {
1000
1509
  }
1001
1510
  },
1002
1511
  emptystate: {
1003
- summary: 'Boş ekran/liste bloğu: görsel ya da ikon + başlık + açıklama + aksiyon düğmeleri.',
1512
+ summary: 'Boş ekran/liste bloğu: görsel ya da ikon + başlık + açıklama + aksiyon düğmeleri. Olayları mount ve actionClick.',
1004
1513
  behavior: [
1005
1514
  "actions[].flow doğrudan çalışır (emit'in flowId'si üzerinden) ve ayrıca actionClick yayılır — table'ın boş durum aksiyonlarıyla aynı sözleşme.",
1006
1515
  'image verilirse icon ÇİZİLMEZ (görsel ikonu ezer); ikisi birden gösterilmez.',
1007
- 'isDisabled aksiyon tıklamayı yutar: ne kendi flow’u çalışır ne actionClick yayılır.'
1516
+ 'isDisabled aksiyon tıklamayı yutar: ne kendi flow’u çalışır ne actionClick yayılır.',
1517
+ 'actions[].href verilen düğme gerçek bir <a> olur (orta tuş/yeni sekme çalışır); href ile flow birlikte verilebilir, tıklamada ikisi de işler. isDisabled olan satır href almaz, aria-disabled alır.',
1518
+ 'BAĞLANTIDA GEZİNME KAZANIR: href dolu satıra normal tıklamada actionClick yayılır AMA aynı sekmede gezinme sayfayı değiştirdiği için olayın sayfa-içi sonucu (uyarı/modal/görünürlük değişimi) görünmeden kaybolur. Hem gezinmenin hem olayın sonucunu istiyorsan satırda isNewTabLink aç (yeni sekme) ya da href yerine flow kullanıp gezinmeyi akıştan yap.',
1519
+ 'isLoading açıkken içerik yerine iskelet çizilir ve hiçbir aksiyon yayılmaz — boş durum mesajı veri gelmeden yanıp sönmesin diye. İskelet parça SAYISINI taklit eder (ikon/görsel yoksa yer tutucu yok, aksiyon yoksa düğme şeridi yok; image seçiliyse daire değil dikdörtgen), ölçüyü birebir taklit etmez.',
1520
+ 'Her parça isteğe bağlıdır; yalnız title taşıyan bir blok geçerlidir. Icon ve görsel ekran okuyucuya dekoratiftir, mesajı h3 olan title taşır.'
1008
1521
  ],
1009
1522
  propNotes: {
1010
1523
  image: 'Drive dosyası ya da URL; verildiğinde icon yok sayılır.',
1011
1524
  size: 'sm | md | lg — ikon/görsel ölçüsünü ve dikey boşluğu birlikte ölçekler (dar kartta sm).',
1012
- actions: '[{ text, icon, kind, variant, flow, isHidden, isDisabled }] — boş bırakılan alanlar hiç çizilmez.'
1525
+ align: 'left | center | right — metin, ikon ve düğmeler birlikte hizalanır.',
1526
+ icon: 'Yalnız ikon ADI okunur; glif rengi iconColor + customIconColor ile verilir (picker’ın gömülü renk alanı kapalı).',
1527
+ iconColor: 'Boş bırakılırsa ikon sönük gri kalır — boş durum genelde bir hata değildir. custom seçilirse renk customIconColor’dan gelir.',
1528
+ isLoading: 'Akış veriyi getirene kadar iskelet. Bileşen geri yazmaz, yalnız akış sürer.',
1529
+ actions: '[{ text, icon, kind, variant, flow, href, isNewTabLink, isHidden, isDisabled }] — boş bırakılan alanlar hiç çizilmez. isNewTabLink yalnız href dolu satırda anlamlıdır (panelde de o koşulla görünür) ve bağlantıyı target="_blank" + rel="noreferrer noopener" ile yeni sekmede açar; sayfa yerinde kaldığı için actionClick’in sonucu da görünür kalır. isHidden satır hiç çizilmez ve actionClick’in index’inde SAYILMAZ.'
1013
1530
  }
1014
1531
  },
1015
1532
  iframe: {
1016
- summary: 'Sandbox’lı dış sayfa gömme. javascript:/data:/vbscript:/file: şemaları engellenir.',
1533
+ summary: 'Sandbox’lı gömme: dış sayfa (src) ya da doğrudan HTML parçası (srcdoc). javascript:/data:/vbscript:/file: şemaları engellenir; gömülü sayfa message olayıyla geri konuşabilir.',
1017
1534
  behavior: [
1018
1535
  "isSandboxed (varsayılan AÇIK) allow-scripts allow-forms allow-popups verir ama allow-same-origin VERMEZ — gömülü sayfa uygulamanın çerezine/depolamasına erişemez.",
1019
- "load/error native <iframe> DOM olaylarından gelir. load ÇAPRAZ KAYNAKTA da güvenilir tetiklenir (tarayıcı frame'i okuyamasa bile yükleme bitince ateşler) ve 'yükleniyor' örtüsünü kapatır. error ise pratikte neredeyse hiç tetiklenmez — engellenen (X-Frame-Options/CSP) ya da 404 çapraz-kaynak sayfalar tarayıcıda genelde sessiz bir load'a döner; ağ hatası yakalamak için güvenilmez."
1536
+ "srcdoc YAZILIYSA src YOK SAYILIR (HTML’in kendi sırası): üçüncü parti 'embed kodu' adres uydurmadan yapıştırılır. html bileşeninden farkı: içerik sayfaya değil sandbox'lı çerçeveye girer, yani uygulamanın origin'ine dokunamaz — ama isSandboxed KAPATILIRSA srcdoc belgesi gömen sayfanın origin'ini devralır, ikisini birlikte kapatmak bilinçli bir karardır. Yalnız boşluktan oluşan srcdoc boş sayılır ve src'ye düşülür.",
1537
+ "load/error native <iframe> DOM olaylarından gelir. load ÇAPRAZ KAYNAKTA da güvenilir tetiklenir (tarayıcı frame'i okuyamasa bile yükleme bitince ateşler) ve 'yükleniyor' örtüsünü kapatır. error ise pratikte neredeyse hiç tetiklenmez — engellenen (X-Frame-Options/CSP) ya da 404 çapraz-kaynak sayfalar tarayıcıda genelde sessiz bir load'a döner; ağ hatası yakalamak için güvenilmez. Örtüyü error de kapatır (2026-09-17 öncesinde kapatmıyordu, 'Loading…' sonsuza dek duruyordu).",
1538
+ "message: gömülü sayfanın window.parent.postMessage(...) çağrısı bu olayı çalıştırır. YALNIZ bu çerçeveden gelen mesaj kabul edilir (event.source karşılaştırması); sayfadaki başka bir iframe ya da uygulamanın kendi postMessage çağrısı tetiklemez. Yük yalnız event.data'dadır ({ message, origin }), hiçbir prop yazılmaz. ORIGIN SÜZGECİ YOK: sandbox açıkken gömülü belgenin origin'i opak olduğu için event.data.origin 'null' gelir — hangi origin'e güvenileceğine akış karar verir.",
1539
+ "Kanvas toolbar'ı: showBorder · isSandboxed · allowFullscreen · isLazy · referrerPolicy · isHidden."
1020
1540
  ]
1021
1541
  },
1022
1542
  icon: {
1023
- summary: 'Tek glif çizer (TİPLİ stil modeli: yalnız hoverStyle): Material Symbols ya da Phosphor setinden ikon + boyut + semantik renk + isteğe bağlı arka plan çipi, köşe rozeti, döndürme/çevirme, spin animasyonu ve click/href etkileşimi.',
1543
+ summary: 'Tek glif çizer (TİPLİ stil modeli: yalnız hoverStyle): Material Symbols ya da Phosphor setinden ikon + boyut + semantik renk + isteğe bağlı arka plan çipi, köşe rozeti, döndürme/çevirme, spin animasyonu, isDisabled kilidi ve click/href etkileşimi.',
1024
1544
  behavior: [
1025
1545
  "İKON ADI iki biçim alır: Material Symbols snake_case adı ('shopping_cart', 'progress_activity', 'account_circle') ya da Phosphor 'ph-<ağırlık> ph-<ad>' çifti ('ph-bold ph-heart'; ağırlıklar: ph-light|ph-bold|ph-duotone|ph-fill|ph-thin|'ph-regular ph'). BİLİNMEYEN Material adı hata vermez, ligature çözülmediği için adın METNİ görünür — adı uydurma, bilinen bir addan emin ol.",
1026
1546
  "RENK TEK KANALDIR: icon.color OKUNMAZ (yazma). Çip kapalıyken glif rengini color/customColor çifti verir; çip açıkken renk sahibi chipColor'dur — solid varyantta glif otomatik kontrast rengini, soft varyantta çip renginin kendisini alır ve panel glif renk satırlarını gizler.",
1027
1547
  "SPIN ile döndürme/çevirme AYRIKTIR: isSpinning açıkken rotation/flipHorizontal/flipVertical uygulanmaz (ikisi aynı CSS transform'unu paylaşamaz); değerler silinmez, spin kapanınca geri döner.",
1028
- "ETKİLEŞİM: href doluysa kök gerçek <a> olur (isNewTabLink yeni sekmede açar) ve click olayı YİNE yayılır; href boş ama click olayı bağlıysa kök <button>tur; ikisi de yoksa salt görsel <div> kalır.",
1548
+ "ETKİLEŞİM: href doluysa kök gerçek <a> olur (isNewTabLink yeni sekmede açar) ve click olayı (kilitli değilken) YİNE yayılır; href boş ama click olayı bağlıysa kök <button>tur; ikisi de yoksa salt görsel <div> kalır.",
1549
+ "KİLİT: isDisabled ikonu soldurur ve etkileşimi keser — bağlantının adresi yazılmaz, düğme disabled olur, click olayı YAYILMAZ. Kökün etiketi kilitlenince DEĞİŞMEZ. Salt görsel ikonda da soldurur (panelde ölü kontrol bırakmamak için).",
1550
+ 'OLAYLAR: mount düğüm ilk çizildiğinde bir kez yayılır (salt görsel ikonda da; isHidden açıkken yayılmaz), click yalnız etkileşimli kökten (href ya da bağlı click) çıkar. İkisi de veri taşımaz.',
1551
+ "İPUCU (tooltip) prop'u YOKTUR: düğümün ortak appearance.tooltip alanı (+ tooltipPosition: top · bottom · left · right) her komponentte ipucu çizer — ikon düğmesinin adını orada yaz.",
1029
1552
  "ERİŞİLEBİLİRLİK: ariaLabel doluysa okuyucular onu okur (salt görselde role=img). Boşsa salt görsel ikon okuyuculardan GİZLENİR; tıklanabilir/bağlantılı ikon ise adsız kalmasın diye ikon adından türetilen etiketi okur. Anlam taşıyan her ikona ariaLabel yaz.",
1030
1553
  'BOYUT tema puntosunun katıdır: sm|md|lg|xl kademeleri --ng-font-size ile ölçeklenir (md varsayılan temada ~24px) ya da elle CSS değeri yazılır — çıplak sayı px sayılır. Elle değer tema yazı ölçeğini izlemez.'
1031
1554
  ],
1032
1555
  propNotes: {
1033
- icon: "{ name } — yalnız ad okunur; renk color/chipColor kanallarından gelir (picker'ın renk bölümü bu komponentte kapalıdır).",
1556
+ icon: "İKİ biçim de geçer: { name: 'shopping_cart' } nesnesi ya da düz metin ('shopping_cart'). Yalnız AD okunur; renk color/chipColor kanallarından gelir (picker'ın renk bölümü bu komponentte kapalıdır). Boş/çözülmemiş değer varsayılan 'star' glifine düşer.",
1557
+ isDisabled: 'Kilit: ikon solar, bağlantı adressiz kalır, düğme disabled olur ve click olayı yayılmaz.',
1034
1558
  size: "sm|md|lg|xl (tema puntosuna oransal) YA DA CSS uzunluğu ('40px', '2.5em'); çıplak sayı px sayılır.",
1035
1559
  color: "primary|info|success|warning|error|custom — çip kapalıyken glifin rengi; custom seçilirse customColor okunur. Semantik değer temayı izler, custom izlemez.",
1036
1560
  chipShape: "none|circle|rounded|square — none dışında glifin arkasına renkli kutu açılır ve renk yönetimi chipColor'a geçer.",
@@ -1047,27 +1571,45 @@ export const componentKnowledge = {
1047
1571
  behavior: [
1048
1572
  "data STRING gelir ve '{' ya da '[' ile başlarsa JSON olarak parse edilip ağaç çizilir — uçtan metin olarak dönen gövdeyi akışta ayrıca çözmeye gerek yok; parse edilemezse düz metin gibi gösterilir.",
1049
1573
  'Boş veri (null · undefined · "" · {} · []) ağaç yerine emptyText satırını çizer ve araç çubuğu gizlenir.',
1050
- 'expandDepth çalışma anında değişirse ağaç YENİDEN kurulur: elle açıp kapattıkların sıfırlanır, düğümler yeni derinliğe göre açılır.',
1574
+ "DİKKAT (ortak katman, CQ-276): data'ya {{ }} ile NESNE bağlanırsa iç içe düz nesneler bileşene null gelir (diziler ve primitifler sağlam). İç içe veri gösterirken metin bağla: data = {{ JSON.stringify(sorgu.data) }} — bileşen JSON metnini kendisi ağaca çevirir. Şemadaki statik varsayılanın içindeki dizi de önizlemede boşalır (ARC-025).",
1575
+ 'expandDepth çalışma anında değişirse ağaç YENİDEN kurulur: elle açıp kapattıkların sıfırlanır, düğümler yeni derinliğe göre açılır. null / boş / sayı olmayan değer varsayılan 1 sayılır (eskiden 0 olup her şeyi kapatıyordu).',
1576
+ 'isSearchable araması anahtarda ve YAPRAK değerinde arar (string yaprağında kırpılmamış tam değer); object/array önizlemesinde ({3}, Array(2)) ve dizi indeksinde aramaz. Büyük/küçük harf duyarsız, düz metin (regex değil). Eşleşen parça sarı zeminle vurgulanır; eşleşme 60 karakterlik kırpmanın ötesindeyse o yaprak tam değeriyle açık gelir. Arama sürerken expandDepth yok sayılır, eşleşmeyen dallar gizlenir; sonuç yoksa emptyText basılır.',
1051
1577
  'Araç çubuğu (showToolbar) tümünü aç / tümünü kapat / JSON kopyala düğmeleridir; her düğümün kendi kopyala düğmesi de vardır. Kopyalama panoya güvenli bağlam ister; izin yoksa sessizce hiçbir şey olmaz.',
1052
1578
  '60 karakteri aşan string yaprakları önizlemede kırpılır ("…"); yaprağa tıklamak tam değeri açar.',
1053
- "nodeClick HER satırda (yaprak ya da object/array) tıklanınca yayılır — aç/kapa oku ayrı davranır, satırın geneline tıklamak nodeClick'i tetikler.",
1054
- "copy iki kaynaktan gelir: araç çubuğundaki 'tümünü kopyala' path:'' + kind:'root' + value:normalize edilmiş TÜM veriyle yayılır; düğümün kendi kopyala düğmesi ise o düğümün path/kind/value'suyla yayılır."
1579
+ "nodeClick HER satırda (yaprak ya da object/array) tıklanınca yayılır; aç/kapa oku ve satırın kopyala düğmesi nodeClick YAYMAZ. Yük akışta event.data.{ path, key, kind, value }; self.currentItem'a (gizli prop) value'SUZ { path, key, kind } yazılır — ham değeri event.data.value'dan oku. Kırpılmış string'e tıklamak hem tam değeri açar hem nodeClick yayar.",
1580
+ "copy iki kaynaktan gelir: araç çubuğundaki 'tümünü kopyala' event.data = { path:'', key:'', kind:'root', value: normalize edilmiş TÜM veri }; düğümün kendi kopyala düğmesi o düğümün { path, key, kind, value }'suyla. copy hiçbir prop YAZMAZ, yalnız event.data taşır; pano izni yoksa olay da yayılmaz.",
1581
+ "Dizi elemanlarının anahtarı indekstir: quotesOnKeys açıkken yalnız obje anahtarları tırnaklanır (ham JSON'daki gibi). path noktalı/köşeli yol üretir; nokta ya da boşluk içeren anahtar yolda kaçırılmaz (a.b anahtarı ile a→b aynı yolu verir)."
1055
1582
  ],
1056
1583
  propNotes: {
1057
1584
  data: 'Nesne/dizi ya da JSON metni; döngüsel referanslar "[Circular]" yaprağına düşer.',
1058
1585
  expandDepth: 'Açılışta açık kalacak seviye sayısı (0 = her şey kapalı).',
1059
1586
  emptyText: 'Veri boşken basılan metin.',
1060
- showToolbar: 'Aç/kapat/kopyala araç çubuğu (varsayılan AÇIK).'
1587
+ showToolbar: 'Aç/kapat/kopyala araç çubuğu (varsayılan AÇIK).',
1588
+ currentItem: "Gizli; runtime yazar. Son tıklanan düğümün { path, key, kind } bilgisi (value YOK — döngüsel veride prop yazması yığını taşırıyordu; değer event.data.value). AI doğrudan set etmez."
1061
1589
  }
1062
1590
  },
1063
1591
  'language-selector': {
1064
1592
  summary: 'Son kullanıcının sayfa dilini değiştirdiği açılır liste; projenin aktif dillerini kendi ana dil adlarıyla listeler.',
1065
1593
  behavior: [
1066
1594
  "change olayında runtime machine.setLanguage(value) çağırır: seçim localStorage'a (zeyrek:{appSlug}:lang) yazılır ve çeviri bağlı bütün prop'lar SAYFA YENİLENMEDEN yeniden çözülür.",
1067
- 'Projede dil tanımlı değilse liste boş çizilir — önce proje dillerini (Translations paneli) kur.',
1595
+ 'Projede dil tanımlı değilse liste boş çizilir — önce proje dillerini (Translations paneli) kur. Bu durumda çizilen tek satır placeholder satırıdır; placeholder varsayılan olarak BOŞ olduğu için metni yazılmadıkça kutu yine boş görünür.',
1596
+ 'mount olayında self.value BOŞTUR (ölçüldü, 2026-09-18): geçerli dili render katmanı her turda prop olarak enjekte ediyor ama düğümün prop kaydına yazmıyor; düğüme yazan tek şey change olayının yüküdür. Yani "açılışta dile göre dallan" kurulamıyor (docs/issues.md ARC-098), dili okuyan akış change olayına bağlanmalı.',
1597
+ 'TASARIM KANVASINDA liste BOŞTUR: dil kümesini ve seçili dili yalnız render katmanı enjekte ediyor, kanvas düğümü enjekte etmiyor. Yani displayMode/size/placeholder etkisi kanvasta değil ÖNİZLEMEDE ölçülür; kanvasta boş görünen liste bir hata değildir.',
1598
+ 'Listeyi ve seçili değeri render katmanı enjekte eder; ikisi de panelden ya da akıştan YAZILAMAZ. value prop gizlidir ve tek yönlüdür: change onu düğüme geri yazar, akış self.value ile okur. Dili akıştan değiştirmenin yolu bu prop DEĞİLDİR.',
1068
1599
  "Dil kümesi KAPALI DEĞİLDİR: projeye eklenen her ISO 639-1 kodu listede çıkar (project_update languages). Komponent kütüphanesinin kendi arayüz metni (sayfalama, filtre operatörleri, boş durumlar) yalnız tr/en sözlüğü taşır ve sözlüğü olmayan dilde İNGİLİZCEYE düşer — sayfa içeriği ve sayı/tarih biçimi ise seçilen dilin kendisini kullanır. Yani 'de' seçili bir uygulamada tablo sayfalaması İngilizce, sayılar Almanca ayraçla çıkar; bu bilinçlidir.",
1069
- "Sekme başlığı (page.browserTitleKey) bu değişimi İZLEMEZ: açılıştaki dilde kalır, sayfa yeniden yüklenince düzelir (platform_guide('translation'))."
1070
- ],
1600
+ "Sekme başlığı (page.browserTitleKey) bu değişimi İZLEMEZ: açılıştaki dilde kalır, sayfa yeniden yüklenince düzelir (platform_guide('translation')).",
1601
+ 'Seçim UYGULAMA başınadır, proje ya da sayfa başına değil: anahtar uygulamanın slug\'ını taşır (zeyrek:{appSlug}:lang), yani aynı tarayıcıda açılan başka bir uygulama kendi değerini tutar ama o uygulamanın bütün sayfaları ve önizlemeleri tek değeri paylaşır. Sayfaya birden fazla koymanın anlamı yok.'
1602
+ ],
1603
+ propNotes: {
1604
+ label: 'Listenin solunda duran etiket; girdiye <label for> ile bağlıdır, ekran okuyucunun okuduğu ad odur. Boşken (yalnız boşluk yazmak da boş sayılır) erişilebilir ad placeholder metnine, o da boşsa Language sabitine düşer.',
1605
+ value: 'Gizli; runtime YAZAR (durum kanalı). Seçilen dil kodu. AI bunu set etmez — panelden ya da akıştan yazılan değer render katmanının enjeksiyonuyla ezilir.',
1606
+ placeholder: 'Yalnız seçili dil listede YOKKEN çizilen, seçilemez ilk satır. Varsayılanı boştur: dil kurulmamış projede kutunun boş görünmemesi için metni SEN yazacaksın.',
1607
+ description: 'Listenin altındaki yardımcı metin.',
1608
+ displayMode: "Seçenek etiketinin biçimi: 'native' ana dil adı (Türkçe), 'code' büyük harf kod (TR), 'both' ikisi birden (Türkçe (TR)). Sözlükte karşılığı olmayan kod her kipte kendi kodunu gösterir.",
1609
+ isDisabled: 'Gerçek disabled özniteliği: liste açılmaz ve Tab sırasından düşer.',
1610
+ size: "Kutu ölçüsü: 'sm' | 'md' | 'lg'; boş bırakılırsa temanın form varsayılanı geçerlidir. Kademeler ekosistemin form belirteçlerinden gelir, yani yanına konan aynı ölçüdeki textinput ile aynı yükseklikte durur.",
1611
+ isHidden: 'Düğümü hiç çizmez (ortak katman).'
1612
+ },
1071
1613
  guide: 'translation'
1072
1614
  },
1073
1615
  otpinput: {
@@ -1090,28 +1632,43 @@ export const componentKnowledge = {
1090
1632
  }
1091
1633
  },
1092
1634
  pagination: {
1093
- summary: 'table/datatable’ın içindeki sayfalayıcının BAĞIMSIZ hâli: repeater, kart listesi ya da özel düzen için offset/limit üretir.',
1635
+ summary: 'table/datatable’ın içindeki sayfalayıcının BAĞIMSIZ hâli: repeater, kart listesi ya da özel düzen için offset/limit üretir; toplam sayı dönmeyen API’ler için isTotalUnknown + hasNextPage kipi vardır.',
1094
1636
  behavior: [
1095
- "Her gezinme change yayar ve offset/limit'i komponentin kendi prop'una yazar. Akışta bu değerleri event.data'dan DEĞİL self.offset / self.limit'ten (ya da value type:'property' ile) oku — event.data boş gelir ve sorgu LIMIT/OFFSET null ile TÜM satırları döndürür.",
1637
+ "Her gezinme change yayar: offset/limit komponentin kendi prop'una yazılır VE event.data = { offset, limit } olarak akışa gider. Akışta ikisi de doludur: event.data.offset ya da self.offset / self.limit (value type:'property').",
1638
+ 'Yalnız offset ya da limit gerçekten değişince yayılır: düğüm zaten o sayfanın offset’indeyken etkin sayfa düğmesine basmak ya da kutuya aynı sayfayı yazmak olay üretmez (sorgu boşuna yeniden koşmaz) — başarısız bir yüklemeyi aynı sayfaya tekrar basarak DENEYEMEZSİN, akış offset’i yeniden yazmalı ya da ayrı bir yenile düğmesi koymalısın. isDisabled ya da isLoading açıkken hiçbir kontrol tıklanmaz; akışın offset/limit yazması olay üretmez.',
1096
1639
  'limit değişince offset her zaman 0’a sıfırlanır (eski offset yeni sayfa boyunda anlamsızdır).',
1640
+ 'Toplam biliniyorsa (varsayılan) sayfa sayısı ceil(totalRows/limit); totalRows küçülüp offset son sayfanın ötesinde kalırsa bar son sayfayı gösterir ama offset prop’u DEĞİŞMEZ — o sayfa numarasına basmak offset’i düzeltip change yayar. Sorguyu yeni filtreyle koşarken offset’i akışta 0’a yaz.',
1641
+ "isTotalUnknown: true → totalRows okunmaz; sayfa floor(offset/limit)+1, ileri düğmesi yalnız hasNextPage true iken açık (hasNextPage'i veriyi çeken akışta setter adımıyla yaz: ör. dönen satır sayısı limit'e eşitse true). Son sayfa düğmesi çizilmez, compact yalnız sayfa numarasını, numbers mevcut sayfaya (+ hasNextPage ise bir sonrakine) kadar düğme gösterir, sayfa kutusunun üst sınırı yoktur; varsayılan bilgi metni '{from}–{to}', şablonda {total}/{pages} '?' basar.",
1097
1642
  'Sayfalama durumunu ya bu komponentin prop’unda tut ve sorguyu {{pagination.offset}} ile bağla, YA DA sayfa değişkeninde tut ve change akışında setter adımıyla yaz. Komponentin prop’unu sayfa değişkenine bağlayıp otomatik geri yazma beklemek ÇALIŞMAZ.',
1098
- 'totalRows/offset/limit adları table/datatable ile birebir aynıdır; aynı sorgu bağları ikisiyle de çalışır.'
1643
+ 'totalRows/offset/limit adları table/datatable ile birebir aynıdır; aynı sorgu bağları ikisiyle de çalışır. Prop’lar metin gelse de sayıya çevrilir; boş/null totalRows 0, geçersiz limit tüm gezinmeyi kapatır.'
1099
1644
  ],
1100
1645
  propNotes: {
1101
- totalRows: 'Toplam kayıt; sayfa sayısı bundan hesaplanır.',
1102
- variant: 'numbers (numaralı düğmeler) | simple (düzenlenebilir sayfa kutusu, varsayılan) | compact (salt "3 / 12").',
1103
- limitOptions: 'Sayfa boyu seçenekleri; geçersizler elenir, hiçbiri kalmazsa [10,20,30,40,50] kullanılır.',
1104
- infoTemplate: '{from} {to} {total} {page} {pages} yer tutucuları; boşsa yerelin varsayılan metni.'
1646
+ totalRows: 'Toplam kayıt; sayfa sayısı bundan hesaplanır. isTotalUnknown açıkken okunmaz (panelde gizlenir).',
1647
+ variant: 'numbers (numaralı düğmeler) | simple (varsayılan; numarasız, sayfa kutusu showJumper ile) | compact (salt "3 / 12", kutu yok). showJumper numbers ve simple’da kutuyu ekler.',
1648
+ siblingCount: 'numbers’ta mevcut sayfanın iki yanındaki komşu sayısı; ilk ve son sayfa hep görünür, atlananlar "…".',
1649
+ align: 'left (varsayılan) | center | right barı doğal genişliğinde konumlar; none hücreyi doldurur.',
1650
+ limitOptions: 'Sayfa boyu seçenekleri; geçersizler elenir, hiçbiri kalmazsa [10,20,30,40,50] kullanılır. Listede olmayan limit seçiciye kendiliğinden eklenir.',
1651
+ infoTemplate: '{from} {to} {total} {page} {pages} yer tutucuları; boşsa yerelin varsayılan metni ("30 / 57", en: "to 30 of 57").',
1652
+ isTotalUnknown: 'Toplam kayıt sayısı dönmeyen (cursor/"daha fazla var mı" tarzı) veri için; açıkken ileri gitmeyi hasNextPage belirler.',
1653
+ hasNextPage: 'Metin gelirse yalnız true/"true" açık sayılır. Yalnız isTotalUnknown açıkken okunur (panelde yalnız o zaman görünür); false → ileri düğmesi kapalı. Varsayılan true.'
1105
1654
  }
1106
1655
  },
1107
1656
  progress: {
1108
- summary: 'Çubuk ya da daire biçiminde ilerleme göstergesi; eşiğe göre renk değiştirir.',
1657
+ summary: 'Çubuk ya da daire biçiminde ilerleme göstergesi; eşiğe göre renk değiştirir. label neyin ilerlediğini yazar, showLabel değer okumasını açar.',
1109
1658
  behavior: [
1110
- "complete yalnız yüzde 100'e İLK ULAŞTIĞINDA (kenar tetiklemesi) bir kez yayılır — her render'da değil; değer 100'ün altına inip yeniden çıkarsa tekrar yayılır. isIndeterminate:true iken hiç yayılmaz (belirsiz modda 'tamamlanma' tanımsızdır)."
1659
+ "complete yalnız yüzde 100'e İLK ULAŞTIĞINDA (kenar tetiklemesi) bir kez yayılır — her render'da değil; değer 100'ün altına inip yeniden çıkarsa tekrar yayılır. isIndeterminate:true iken hiç yayılmaz (belirsiz modda 'tamamlanma' tanımsızdır).",
1660
+ 'click yalnız akış BAĞLIYSA çalışır: bağlıyken sarmalayıcı <button> olur ve odak sırasına girer, bağlı değilken düz <div> kalır (badge/avatar/icon/image/video/statcard ile aynı desen). role="progressbar" içteki elemanda kalır.',
1661
+ 'max alanı TEMİZLENİRSE 100 sayılır (şema varsayılanı), 0 değil — boş sayı alanı panelde null olarak saklanır ve 0 gibi okunsaydı bar tamamen boşalırdı. Prop .min(1) olduğu için kaybedilen bir "0" hâli yoktur.'
1111
1662
  ],
1112
1663
  propNotes: {
1664
+ label: 'Neyin ilerlediğini söyleyen metin ("Uploading…"); barın/dairenin ÜSTÜNDE durur. Değer okuması DEĞİLDİR — o showLabel/labelFormat/labelPosition üçlüsüdür. isIndeterminate:true iken de görünür; belirsiz kipte ekrandaki tek bilgi budur.',
1113
1665
  value: '0..max arası; yüzde kırpılarak hesaplanır.',
1114
- colorMap: '{ "0": "error", "50": "warning", "80": "success" } — yüzdeye eşit/altındaki EN BÜYÜK eşiğin rengi kazanır, yoksa color prop’u.'
1666
+ showLabel: 'DEĞER okumasını açar (40% · 3/10 · 40) — label prop’unu değil. Panel başlığı "Show value".',
1667
+ thresholds: '[{ from: <yüzde>, color: <primary|info|success|warning|error> }] — yüzdeye eşit/altındaki EN BÜYÜK eşiğin rengi kazanır, hiçbiri tutmazsa color prop’u. from BOŞ bırakılan satır düşer; açık 0 geçerlidir. isIndeterminate:true iken eşikler devre dışıdır.',
1668
+ colorMap: '{ "0": "error", "50": "warning", "80": "success" } — thresholds’un ESKİ biçimi, panelde gizli, yalnız thresholds boşken okunur. Yeni iş thresholds yazar.',
1669
+ thickness: 'Piksel. Barda yükseklik, dairede çizgi kalınlığı — daire için ölçülen çaptan çizim birimine çevrilir ve yay kırpılmasın diye sınırlanır, yani çok büyük değerler sessizce tavana oturur. Boş/0 = Size’dan gelen kalınlık.',
1670
+ isStriped: 'Yalnız barda; dairede stroke üzerinde görünmez.',
1671
+ labelPosition: 'DEĞER okumasının yeri (bar içinde / yanında). Dairede etiket zaten ortadadır, ayar gizlenir.'
1115
1672
  }
1116
1673
  },
1117
1674
  rating: {
@@ -1127,8 +1684,23 @@ export const componentKnowledge = {
1127
1684
  }
1128
1685
  },
1129
1686
  result: {
1130
- summary: 'Durum bloğu (success/error/warning/info): büyük ikon + başlık + alt başlık + aksiyonlar — işlem sonucu ekranları için.',
1131
- behavior: ["actions[].flow doğrudan çalışır ve actionClick yayılır (emptystate ile aynı sözleşme)."]
1687
+ summary: 'Durum bloğu (success/error/warning/info): büyük ikon ya da illüstrasyon + başlık + alt başlık + aksiyonlar — işlem sonucu ekranları için. KAPSAYICI DEĞİLDİR, çocuk komponent almaz.',
1688
+ behavior: [
1689
+ 'actions[].flow doğrudan çalışır ve actionClick yayılır (emptystate ile aynı sözleşme).',
1690
+ 'Renk ve varsayılan ikon status prop’undan gelir; icon prop’u yalnız GLİFİ ezer, rengi ezmez — bu komponentte renk anlamın kendisidir (başarı yeşil, hata kırmızı).',
1691
+ 'Görsel slotu hiç boş kalmaz: image doluyken ikon çizilmez, ama adres yüklenemezse durum ikonuna geri dönülür.',
1692
+ 'isLoading açıkken durum ikonu ve metinler ÇİZİLMEZ — yerine nötr bir çark ve iskelet çubuklar gelir ve hiçbir olay yayılmaz. Sebep: varsayılan başlık ile yeşil onay, akış daha cevap vermeden "işlem tamam" derdi. İskelet gerçek yerleşimi taklit eder (yazılı her metin için bir çubuk, görünen her aksiyon için bir şerit; boy ölçüsü size ile ölçeklenir), yani veri gelince blok zıplamaz. Sonucu bir akıştan dolduruyorsan düğümü isLoading açık bırak, akışın son adımı kapatsın.',
1693
+ 'mount ortak katmandan gelir ve sayfa açılınca bir kez yayılır; sonucu dolduran akışın kancası budur.'
1694
+ ],
1695
+ propNotes: {
1696
+ icon: 'Durum ikonunu ezer, RENGİ ezmez (renk her zaman status’tan gelir). Picker’ın gömülü renk alanı bu yüzden kapalıdır — yazılsa okunmazdı.',
1697
+ image: 'İllüstrasyon (Drive dosyası ya da mutlak URL). Doluyken ikon hiç çizilmez ve panelde gizlenir; adres çözülemezse durum ikonuna geri dönülür.',
1698
+ status: 'Hem rengi hem varsayılan ikonu belirler; tanınmayan/boş değer info okunur.',
1699
+ align: 'İçeriğin yatay hizası: metin, ikon ve düğmeler birlikte döner.',
1700
+ size: 'Dolguyu, ikon çipini ve başlığın puntosunu birlikte ölçekler.',
1701
+ actions: 'Düğme listesi. Her satır flow (akış tetikler) ya da href (gezinme) alabilir, ikisi birlikte de çalışır. href dolu satır gerçek bir bağlantı olur (orta tuşla yeni sekme); isNewTabLink açıkken düğme zaten yeni sekmede açılır. isDisabled satırın bağlantısını düşürür ve tıklamayı yaymaz. isHidden satır hiç çizilmez ve actionClick’in index’inde de SAYILMAZ.',
1702
+ isLoading: 'Sonuç henüz belli değilken açılır: blok iskelete döner, actionClick yayılmaz. Akışın kendisi kapatmalı — kendiliğinden kapanmaz.'
1703
+ }
1132
1704
  },
1133
1705
  slider: {
1134
1706
  summary: 'minValue–maxValue arasında sayısal kaydırıcı (tek değer; iki tutamaklı aralık YOKTUR).',
@@ -1148,13 +1720,18 @@ export const componentKnowledge = {
1148
1720
  summary: 'KPI kartı: büyük değer + ikon + trend oku + satır içi sparkline + alt bilgi bağlantısı.',
1149
1721
  behavior: [
1150
1722
  'value SAYIYA çözülüyorsa valueFormat ile biçimlenir, çözülmüyorsa ("N/A", "3 gün") olduğu gibi basılır; boş değer "—" çizer.',
1151
- 'invertTrend yalnız RENGİ ters çevirir (hata oranı gibi "azalan iyidir" metrikleri için); ok yönü değişmez.',
1152
- 'Kartın kendisi click, alt bilgi satırı ayrı footerClick yayar; footerHref verilmişse alt bilgi bağlantı olur ve footerFlow yerine ona gider.'
1723
+ 'invertTrend yalnız RENGİ ters çevirir (hata oranı gibi "azalan iyidir" metrikleri için); ok yönü değişmez. trendFormat yalnız METNİ değiştirir: percent "+12%", value "+340".',
1724
+ 'Kartın kendisi click (yalnız bir akış bağlıysa; bağlıyken ana yüzey <button> olur), alt bilgi satırı ayrı footerClick yayar. footerHref ile footerFlow BİRLİKTE çalışır: satır bağlantı olur ve tıklamada footerClick yine yayılır — gezinme akışı yarıda kesebilir; ikisini birlikte kullanacaksan isNewTabLink aç.',
1725
+ 'İkon rengi TEK kanaldır: iconColor + customIconColor. Icon picker\'ın gömülü renk alanı kapalıdır (colorless); çip zemini custom olduğunda glifin rengi zeminin ÖLÇÜLEN parlaklığından seçilir, açık renkte koyu glif çizilir.',
1726
+ 'Tipli stil grupları kartın PARÇALARINA iner: typographyStyle.textColor başlık + değer + alt başlığı birlikte boyar (trend anlam rengini, alt satır bağlantı rengini korur), fontSize kartın bütün puntolarını orantılı ölçekler, hoverStyle.background tıklanabilir yüzeyde ve alt satırda da geçerlidir. Kartın ipucu için prop yoktur; düğümün ortak appearance.tooltip alanı kullanılır.'
1153
1727
  ],
1154
1728
  propNotes: {
1155
1729
  value: 'Sayı ya da metin; sayıysa valueFormat uygulanır.',
1156
1730
  sparkline: 'Sayı dizisi; kendi min/max’ına göre ölçeklenir (sıfır tabanlı değil).',
1157
- trend: 'Yüzde değişim; 0 nötrdür ve panelden temizlenemez.'
1731
+ trend: 'Değişim miktarı; işareti yönü ve rengi belirler, birimini trendFormat söyler. 0 nötrdür ve panelden temizlenemez.',
1732
+ trendFormat: 'percent (varsayılan) yüzde işaretiyle yazar; value işareti korur, birim yazmaz — mutlak değişim gösteren KPI için.',
1733
+ isNewTabLink: 'Yalnız footerHref doluyken anlamlı: target="_blank" + rel="noreferrer noopener". Yeni sekmede footerFlow akışı da tamamlanır.',
1734
+ isLoading: 'Kartı soldurur ve etkileşimi keser; içerik yerinde kalır, iskelet çizilmez.'
1158
1735
  }
1159
1736
  },
1160
1737
  switcher: {
@@ -1180,28 +1757,41 @@ export const componentKnowledge = {
1180
1757
  }
1181
1758
  },
1182
1759
  'theme-toggle': {
1183
- summary: 'Uygulamayı açık/koyu temaya çeviren tek düğme; tercih tarayıcıda kalıcıdır. Olay YAYMAZ.',
1760
+ summary: 'Uygulamayı açık/koyu temaya çeviren tek düğme; tercih tarayıcıda kalıcıdır. change yayar ve seçilen modu kendi value prop’una yazar.',
1184
1761
  behavior: [
1185
- "Tıklama görünen modun TERSİNE yazar (viewerMode store'u) — proje varsayılanı koyuysa ilk tıklama açığa alır, kapatıp açmaya değil.",
1186
- "Seçim localStorage'a yazılır (language-selector'ın dil anahtarıyla aynı kalıcılık deseni) ve sayfa yenilenmeden temaya bağlı bütün stiller güncellenir.",
1187
- "Studio kanvasında tıklama ÇALIŞMAZ: _editorMode:true iken tıklama hiçbir şey yapmaz — tasarımcı düğmeyi sürüklerken/önizlerken uygulamanın temasını kazayla değiştirmesin diye."
1762
+ "hasAutoMode KAPALIYKEN (varsayılan) tıklama görünen modun TERSİNE yazar (viewerMode store'u) — proje varsayılanı koyuysa ilk tıklama açığa alır, kapatıp açmaya değil.",
1763
+ 'hasAutoMode AÇIKKEN tur üç duraklıdır: tercihsiz → açık → koyu → tercihsiz. Tercihsiz durak localStorage anahtarını SİLER ve uygulama yeniden projenin tema modunu izler; tercihi geri almanın tek yolu budur (2026-09-18 öncesinde yolu yoktu).',
1764
+ "Seçim localStorage'a yazılır (language-selector'ın dil anahtarıyla aynı kalıcılık deseni, anahtar zeyrek-viewer-theme-mode) ve sayfa yenilenmeden temaya bağlı bütün stiller güncellenir. Tercih projenin tema modunun ÖNÜNE geçer ve ORIGIN başına tektir — aynı origin'den sunulan bütün projeler/sayfalar aynı anahtarı paylaşır.",
1765
+ 'İkon her zaman TIKLAMANIN GÖTÜRECEĞİ durumu gösterir: aydınlık sayfada dark_mode, karanlık sayfada light_mode, tur tercihsize dönecekken brightness_auto.',
1766
+ "Studio kanvasında tıklama ÇALIŞMAZ: _editorMode:true iken ne tıklama ne de value prop'u uygulanır — tasarımcı düğmeyi sürüklerken/önizlerken uygulamanın temasını kazayla değiştirmesin diye. Modun gerçekten değiştiğini önizlemede ya da yayımlanmış uygulamada gör."
1188
1767
  ],
1189
1768
  propNotes: {
1190
- label: 'Boşsa yalnız ikon basılır; doluysa ikonun yanına metin de eklenir.',
1769
+ label: 'Boşsa yalnız ikon basılır; doluysa ikonun yanına metin de eklenir ve aria-label de bu metin olur.',
1770
+ value: 'Ziyaretçinin tercihi. Boş değer tercih YOKTUR demektir (projenin teması geçerli). Açılıştaki değer YALNIZ ziyaretçinin kendi tercihi yokken uygulanır: sayfa koyu açılabilir ama daha önce seçim yapmış ziyaretçinin tercihi ezilmez, boş açılış değeri hiçbir zaman uygulanmaz. Açılıştan sonra yazılan her değer uygulanır ve boş yazmak tercihi temizler — ama prop ZATEN boşken boş yazmak bir değişiklik olmadığı için görünmez, o yüzden temizlemeden önce light ya da dark yazılmış olmalı. change olayı buraya geri yazar (setter).',
1771
+ hasAutoMode: 'Turu iki duraktan üçe çıkarır ve üçüncü durak tercihi temizler. Kapalıyken bileşen tercihi asla temizleyemez. Adına ve brightness_auto glifine rağmen işletim sisteminin temasını (prefers-color-scheme) OKUMAZ: üçüncü durak yalnız tercihi silip projenin moduna döner.',
1772
+ lightModeIcon: 'Aydınlık tarafın glifini değiştirir (yerleşik dark_mode/light_mode ikilisinin aydınlık yarısı). Tercihsiz durağın brightness_auto glifi değiştirilemez.',
1773
+ darkModeIcon: 'Karanlık tarafın glifini değiştirir; ikon seçicinin nesnesi de çıplak Material adı da kabul edilir.',
1774
+ size: 'Boş bırakılırsa temanın form varsayılan ölçüsü kullanılır (form bileşenleriyle aynı sözleşme).',
1191
1775
  isHidden: "Bu komponentin kataloğunda VAR — doğrudan şemaya yazılabilir (bkz. 'notification' propNotes'undaki karşıt örnek)."
1192
1776
  }
1193
1777
  },
1194
1778
  timeline: {
1195
- summary: 'Durum renkli işaretçilerle tarihli olay listesi (audit-history’nin serbest veriyle çalışan genel hâli).',
1779
+ summary: 'Durum ya da serbest renkli işaretçilerle tarihli olay listesi (audit-history’nin serbest veriyle çalışan genel hâli); tıklanan öğeyi akışa verir.',
1196
1780
  behavior: [
1197
1781
  'reverse sıralamayı maxCount kırpmasından ÖNCE uygular, böylece "ters + N kayıt" gerçekten EN YENİ N kaydı gösterir.',
1198
- 'maxCount üstü kayıtlar atılmaz: "Show more" çıkar, showMore olayı yayılır ve kalanların tamamı açılır; items yeni bir diziyle değişince görünüm kırpılmış hâline döner.',
1199
- "Öğede href/flow varsa satır tıklanabilir; clickItem yükü öğeyi ve indeksini taşır, öğenin kendi flow'u da doğrudan çalışır."
1782
+ 'maxCount üstü kayıtlar atılmaz: "Show more" çıkar, showMore olayı yayılır ve kalanların tamamı açılır; items yeni bir diziyle değişince (akışın items[index] alanını yazması DAHİL) görünüm kırpılmış hâline döner.',
1783
+ "Her satır tıklaması clickItem yayar: event.data = { currentItem, index }, öğe ayrıca self.currentItem'a yazılır. index items dizisindeki GERÇEK yerdir (reverse/maxCount'tan etkilenmez) — akış items[index]'i güncelleyebilir.",
1784
+ "Öğede flow varsa panelde bağlı clickItem akışı da öğenin kendi flow'u da çalışır — bağlı olay önce başlatılır ama biri diğerini BEKLEMEZ; ikisi de aynı event.data'yı ve self.currentItem'ı görür. Aynı akışı hem olaya hem öğenin flow alanına bağlama: İKİ KEZ çalışır. href'li satır gerçek bağlantıdır (sayfa değişir); flow'lu satır klavyeyle (Enter/Space) de tetiklenir, imleç yalnız href/flow'lu satırda el olur.",
1785
+ 'orientation:horizontal yalnız öğe listesini yatay kayan şerit yapar; title üstte, "Show more" altta kalır.',
1786
+ 'Nesne olmayan öğe (null, düz metin) atlanır; tanınmayan status primary rengine düşer.'
1200
1787
  ],
1201
1788
  propNotes: {
1202
- items: '[{ title, subtitle, description, date, status, icon, avatar, href, flow, isPending }] — boş alanlar çizilmez.',
1789
+ items: '[{ title, subtitle, description, date, status, color, icon, avatar, href, flow, isPending }] — boş alanlar çizilmez. date ISO metin ("2026-01-02" ya da "2026-01-02T14:30:00Z"); başka biçim olduğu gibi basılır. status: primary|info|success|warning|error. color doluysa status rengini ezer: #hex (3/4/6/8 hane), rgb()/hsl()/oklch() gibi renk fonksiyonu, var(--token), düz renk adı ya da status adı; başka her şey (iç içe parantez, ; taşıyan metin) sessizce yok sayılır.',
1203
1790
  dateFormat: 'absolute (varsayılan) | relative ("2 gün önce").',
1204
- maxCount: 'Görünür kayıt sınırı; aşıldığında Show more çıkar.'
1791
+ maxCount: 'Görünür kayıt sınırı; boş/0 = hepsi. Aşıldığında Show more çıkar (showMoreText yalnız maxCount doluyken panelde görünür).',
1792
+ currentItem: "Gizli prop: son tıklanan öğenin tamamı (self.currentItem). index yalnız event.data'da.",
1793
+ locale: 'Tarih dili; boşsa uygulama dili.',
1794
+ emptyText: 'items boşken basılan metin.'
1205
1795
  }
1206
1796
  },
1207
1797
  timepicker: {
@@ -1233,14 +1823,25 @@ export const componentKnowledge = {
1233
1823
  behavior: [
1234
1824
  "Tetikleme isOpen'ın YÜKSELEN KENARIDIR: komponent toast'ı gösterdikten sonra isOpen'ı kendi prop'unda false'a geri yazar. Akışta setter ile true yaz, sıfırlamayı düşünme.",
1235
1825
  'Süre kind’a göre gelir (success/info/default 4sn, warning 6sn, error 8sn, loading süresiz); duration verirsen o kazanır, isSticky ise kapanmaz.',
1236
- "actions[].flow doğrudan çalışır ve actionClick yayılır; keepOpen verilmedikçe tıklama toast'ı kapatır.",
1237
- 'Toast alanını runtime her uygulamada bir kez kurar — ikinci bir toast komponenti eklemek bildirimleri ÇİFTLEMEZ, her tetikleyici kendi toast’ını atar.'
1826
+ "actions[].flow doğrudan çalışır ve actionClick yayılır; keepOpen verilmedikçe tıklama toast'ı kapatır. En çok 2 düğme çizilir, fazlası sessizce atılır.",
1827
+ 'Toast alanını runtime her uygulamada bir kez kurar — ikinci bir toast komponenti eklemek bildirimleri ÇİFTLEMEZ, her tetikleyici kendi toast’ını atar.',
1828
+ "Aynı bildirimin üst üste binmesini duplicates kapatır: ignore aynı anahtarlı toast dururken yenisini ATAR, count tek kart üstünde ×N sayıp süreyi yeniler; varsayılan allow her tetiklemede yeni kart yığar — çift tıklanan Kaydet düğmesinin çözümü budur. ATILAN tetikleme HİÇBİR olay yaymaz: o toast için open, close ve click koşmaz, yani close akışına bağladığın iş ikinci tıklamada çalışmaz.",
1829
+ "Aynılık sayfadaki TÜM toast'lar arasında bakılır (anahtar dedupeKey, yazmazsan kind + title + content): iki ayrı toast düğümü aynı metni taşıyorsa biri ötekini bastırır — varsayılan içeriği bırakmak bunu kolaylaştırır, o yüzden ignore ya da count seçtiğinde dedupeKey yaz. Kuyrukta bekleyen toast da eşleşir, delay ile beklemekte olan eşleşmez.",
1830
+ "open olayı toast KUYRUĞA girdiğinde yayılır: delay beklenir, duplicates ile atılan ya da do-not-disturb ile bastırılan toast open yaymaz, ama aynı konumda 5 toast doluysa fazlası ekranda görünmeden de open yayar. close yükünde reason taşır ve akışta self.reason ile okunur: timeout süre doldu, user kullanıcı kapattı (× düğmesi, closeOnClick tıklaması, kaydırma, Escape, aksiyon düğmesi, Clear all), programmatic koddan kapatıldı. Gecikmede bekleyen toast iptal edilirse close HİÇ yayılmaz."
1238
1831
  ],
1239
1832
  propNotes: {
1240
1833
  isOpen: 'Setter ile true yaz → bir toast; komponent false’a geri döner.',
1241
1834
  kind: 'default | info | success | error | warning | loading.',
1242
1835
  position: '9 çapa: top/bottom × left/center/right, center, top-full/bottom-full (tam genişlik bant).',
1243
- actions: '[{ text, flow, keepOpen, showCountdown }] — en çok 2 düğme.'
1836
+ actions: '[{ text, flow, keepOpen, showCountdown }] — en çok 2 düğme.',
1837
+ dedupeKey: "Aynılık ölçütü; yazılmazsa kind + title + content’ten türer ve sayfadaki bütün toast'ları kapsar. Tek başına hiçbir şey yapmaz, duplicates ile çalışır.",
1838
+ duplicates: 'allow (varsayılan, her tetikleme yeni toast) · ignore (aynı anahtarlı toast dururken yeni tetikleme atılır, olayları da koşmaz) · count (tek kart üstünde ×N sayacı, süre yenilenir). Şemada allow bırakmak ayarlamamakla aynıdır: uygulama koddan başka bir strateji kurduysa o geçerli olur.',
1839
+ icon: "Yazılmazsan türün ikonu çizilir; boş metin (\"\") verirsen hiç ikon çizilmez. kind loading iken ikon hiç okunmaz, yerine dönen halka çizilir.",
1840
+ duration: 'ms; 0 ya da boş = türün varsayılan süresi. Hiç kapanmaması için isSticky.',
1841
+ priority: "Yalnız aynı konumda 5 toast dolduğunda sıra değiştirir (yüksek olan öne geçer); normal bir ekranda gözle görülür etkisi YOKTUR.",
1842
+ showProgress: "Yalnız süreli toast'ta çizilir: isSticky ya da kind loading iken ilerleme çubuğu zaten yok.",
1843
+ pauseOnHover: "Yalnız süreli toast'ta anlamlı: duraklatılacak bir sayaç yoksa (isSticky, loading) etkisizdir.",
1844
+ isHidden: 'Açıkken komponent hiç kurulmaz: toast ATILMAZ. Gizli bir tetikleyici değil, kapalı bir tetikleyicidir — isOpen true yazmak da bir şey göstermez.'
1244
1845
  }
1245
1846
  },
1246
1847
  // — 2026-08-27 eşleme turu: components-new dalıyla gelen 6 yeni komponent.
@@ -1249,77 +1850,104 @@ export const componentKnowledge = {
1249
1850
  // yük params ile DE gönderilir, akışta event.data.<anahtar> DOLU gelir — tekil sözleşmeler
1250
1851
  // componentEvents.ts'te, bulgunun kaydı docs/20-komponent-bilgi-katmani.md §10'da.
1251
1852
  detailview: {
1252
- summary: 'Tek kaydı etiket/değer ızgarası olarak basar; alan başına format (money/date/badge/link…) ve nokta ayraçlı iç içe alan yolu destekler. OLAY YAYMAZ.',
1853
+ summary: 'Tek kaydı etiket/değer ızgarası olarak basar; alan başına format (money/number/boolean/date/badge/link…) ve nokta ayraçlı iç içe alan yolu destekler. KULLANICI ETKİLEŞİMİ OLAYI YAYMAZ — tek olayı mount.',
1253
1854
  behavior: [
1254
- "Veri tek yönlü girer: record prop'u {{ }} ifadesiyle (sorgu çıktısı ya da tablonun selectedRow'u) ya da akıştaki setter ile beslenir; olay yolu yoktur — satır tıklaması gerekiyorsa tıklanabilir bir kapsayıcıya sar.",
1255
- "Boş nesne ({}) 'kayıt yok' sayılır ve emptyText basılır; geçerli kayıt olsa da fields boşsa yine boş durum çizilir. isLoading her dalı ezer ve alan başına iskelet gösterir.",
1256
- "fields[].field nokta ayraçlı iç içe yol alır (department.title, items.0.name); yol kopuksa hücre '-' basar, patlamaz.",
1257
- "format yalnız money/pertance/date/datetime'ı biçimler — 'number' ve 'text' ham String basar (84500 yerelleşmez). money her zaman TRY'dir; pertance (yazımı böyle) <1'i oran, >=1'i yüzde sayar; geçersiz tarih ham metne düşer.",
1855
+ "Veri tek yönlü girer: record prop'u {{ }} ifadesiyle (sorgu çıktısı ya da tablonun selectedRow'u) ya da akıştaki setter ile beslenir; tıklama/seçim olayı yoktur — satır tıklaması gerekiyorsa tıklanabilir bir kapsayıcıya sar. Tek olay mount'tur (yük yok).",
1856
+ "Boş nesne ({}) 'kayıt yok' sayılır ve emptyText basılır; geçerli kayıt olsa da fields boşsa (ya da tüm alanlar isHidden ise) yine boş durum çizilir. isLoading her dalı ezer ve alan başına iskelet gösterir.",
1857
+ "fields[].field nokta ayraçlı iç içe yol alır (department.title, items.0.name); yol kopuksa hücre '-' basar, patlamaz. Aynı alanı iki satırda iki ayrı formatla göstermek geçerlidir (2026-09-16'dan önce sayfayı düşürüyordu).",
1858
+ "format: money/pertance/date/datetime/number biçimlenir, 'text' ham String basar. number dilin ayıraçlarını kullanır (tr 84.500), sayıya çevrilemezse ham metne düşer; money her zaman TRY'dir; pertance (yazımı böyle) <=1'i oran, >1'i yüzde sayar; geçersiz tarih ham metne düşer. boolean değeri ✓/✗ işaretine çevirir — yalnız false/0/'false'/'0' hayırdır, tanınmayan dolu metin evettir (table'ın 'switch' kolon tipinin detailview'daki adı 'boolean').",
1258
1859
  "locale boşken uygulama diline CANLI bağlıdır (dil değişince yeniden biçimler); size boş kaydedilir ve 'md' varsayılanı komponentin içinde çözülür.",
1259
- "columns çalışma anında 1-4 aralığına kırpılır; link formatı ham değeri hem href hem görünen metin yapar (şema doğrulaması yok — 'example.com' göreli URL olur)."
1860
+ "columns 1-4'tür ama sınırı zorlayan tek yüzey kanvas toolbar'ıdır: sağ panel büyük değeri uyarı ikonuyla KABUL EDER ve öyle kaydeder, runtime yine 1-4'e kırpar ve kesirli değeri tam sayıya indirir — yani 8 yazılmış bir sayfa 4 kolon çizer. link formatı görünen metni ham bırakır ama href'i düzeltir: şemasız değer https:// alır, e-posta gibi duran değer mailto: olur, '/...' ve '#...' olduğu gibi kalır; BEYAZ LİSTE dışındaki şema (javascript:, data:…) hiç bağlantı olmaz, değer düz metin basılır."
1260
1861
  ],
1261
1862
  propNotes: {
1262
1863
  record: 'Gösterilecek TEK kayıt (nesne); akıştan beslenecekse setter hedefi budur. Boş nesne = boş durum.',
1263
- fields: "[{ label, field, format, icon }] — field boş satırlar elenir, label boşsa field kullanılır, icon ETİKETİN yanına çizilir.",
1864
+ fields: "[{ label, field, format, icon, isHidden }] — field boş satırlar elenir, isHidden satır çizilmez (table kolonlarındaki isHidden ile aynı iş), label boşsa field kullanılır, icon ETİKETİN yanına çizilir.",
1264
1865
  labelPosition: "top (varsayılan) | left — left'te etiket sütunu minmax(96px, %38) ile ayrılır.",
1866
+ columns: "Izgara kolon sayısı, 1-4. Kanvas toolbar'ı sınıra çeker; sağ panel büyük değeri uyarı ikonuyla kabul eder, runtime yine 1-4'e kırpar.",
1265
1867
  emptyText: "Kayıt ya da geçerli alan yokken basılır; boşsa '—'."
1266
1868
  }
1267
1869
  },
1268
1870
  eventcalendar: {
1269
- summary: 'Ay/hafta/gün görünümlü etkinlik takvimi. VERİ ÇEKMEZ: satırlar rows prop’una akışla yazılır; taşıma/oluşturmanın kalıcılığı akışın işidir.',
1871
+ summary: 'Ay/hafta/gün/ajanda görünümlü etkinlik takvimi. VERİ ÇEKMEZ: satırlar rows prop’una akışla yazılır; taşıma/boyutlandırma/oluşturmanın kalıcılığı akışın işidir.',
1270
1872
  behavior: [
1271
1873
  "TÜM olayların yükü yalnız params ile gider ve self'e YAZILMAZ: akışta event.data.<anahtar> ile okunur (eski komponentlerin self deseninin tersi).",
1272
1874
  "Veri prop'u bilinçli olarak rows'tur, events DEĞİL — Studio kanvası 'events' adlı prop'u düğümün olay bağlarıyla ezer.",
1273
1875
  "startField'ı geçersiz/boş satır SESSİZCE atılır; end geçersizse start'a eşitlenir, ters aralık start'a kırpılır; id yoksa event-<index> üretilir.",
1274
- "Taşıma iyimserdir: eventMove sonrası komponent rows'u DEĞİŞTİRMEZ; akış yeni tarihi uca yazıp rows'u tazeleyince (id:start:end imzası değişince) iyimser katman sıfırlanır — kalıcılaştırılmayan taşıma, veri değiştiği anda geri döner (kanban ile aynı sözleşme).",
1275
- "monthChange gezinme okları/Bugün ile HER görünümde yayılır (ilk mount'ta yayılmaz) ve month 1-TABANLIDIR — veri tazeleme akışı buna bağlanır.",
1276
- "isCreatable:true iken ay hücresi tıklaması dateClick YERİNE eventCreate yayar (start=end=o gün, allDay:true); hafta/gün boş slot tıklaması 60 dakikalık saatli eventCreate üretir. isCreatable kapalıyken slot tıklaması hiçbir şey yapmaz.",
1277
- "Sürükleyerek taşıma yalnız isEditable ile: ay görünümünde gün kayar (saat korunur), hafta/gün kolonunda saat 30 dakikaya yuvarlanır; tüm-gün etkinlik saat KAZANMAZ. Yeniden boyutlandırma (resize) yoktur.",
1278
- "Süresi >=24 saat ya da 00:00→00:00 olan etkinlik 'tüm gün' sayılır ve saat ızgarası yerine üst şeride çizilir; çok günlü etkinlik ay görünümünde kapladığı HER güne ayrı çip düşer (sürekli bant yok).",
1279
- "defaultDate ve defaultView yalnız İLK kurulumda okunur — sonradan prop değişse de takvim kımıldamaz.",
1280
- "Hafta başlangıcı yerele bağlıdır (tr Pazartesi, en Pazar); startHour/endHour saat penceresini belirler, pencereye kısmen taşan blok en az 15 dakikalık yükseklikle çizilir.",
1876
+ "Taşıma ve boyutlandırma iyimserdir: eventMove sonrası komponent rows'u DEĞİŞTİRMEZ; akış yeni tarihi uca yazıp rows'u tazeleyince (id:start:end imzası değişince) iyimser katman sıfırlanır — kalıcılaştırılmayan değişiklik, veri değiştiği anda geri döner (kanban ile aynı sözleşme).",
1877
+ "Veri tazeleme kancası monthChange (oklar/Bugün, HER görünümde) ve viewChange'dir; ikisi de görünen aralığı start/end ('yyyy-MM-dd', iki uç dahil) olarak taşır — sorguyu month/year'a değil start/end'e bağla: ajanda ve hafta ay sınırını aşar, ay ızgarası da komşu ayların günlerini gösterir. end TARİH-YALNIZ ve DAHİLDİR: filtreyi KESİŞİM olarak yaz — etkinlikBaşlangıç < (end + 1 gün) VE etkinlikBitiş >= start; `başlangıç <= end` saatli kolonda son günün saatli kayıtlarını, `başlangıç >= start VE bitiş <= end` kenardan taşan kayıtları düşürür. İlk mount'ta yayılmazlar; açılış aralığını defaultDate/defaultView belirler. month 1-TABANLIDIR.",
1878
+ "isCreatable:true iken tıklama dateClick YERİNE eventCreate yayar: ay hücresi tek günlük allDay:true, hafta/gün boş slotu 60 dakikalık saatli taslak. Basılı tutup sürüklemek aralık seçer: ayda birden çok gün (allDay:true, end son gün dahil), hafta/gün kolonunda aynı günün birden çok saat slotu, etkinlik bloklarının üstünden de (end son slotun sonu) — bırakınca TEK eventCreate. Sürükleyerek seçim fare/kalemle çalışır; dokunmatikte yalnız tek hücre tıklaması oluşturur. Basış sürerken isLoading açılır ya da isCreatable kapanırsa bırakış olay yaymaz. isCreatable kapalıyken slot tıklaması hiçbir şey yapmaz.",
1879
+ "isEditable ile sürükleyerek taşıma: ay görünümünde ve tüm-gün şeridinde gün kayar (saat korunur), hafta/gün kolonunda saat 30 dakikaya yuvarlanır; tüm-gün etkinlik saat KAZANMAZ. Hafta/gün görünümünde saatli bloğun üst/alt kenarından boyutlandırma da vardır (30 dk adım, en az 30 dk) ve AYNI eventMove olayını yayar. Ajanda listesinde sürükleme yoktur.",
1880
+ "Tüm-gün kararı: satırın allDayField (varsayılan 'allDay') bayrağı true ise her zaman tüm gün; false ise yalnız aralıkta saat bilgisi varsa saatli sayılır (tarih-yalnız / 00:00→00:00 satır false'la da şeritte kalır, görünmez olmaz); değer true/false, 'true'/'false', 1/0; bayrak yoksa süresi >=24 saat ya da 00:00→00:00 olan etkinlik tüm gün sayılır. Tüm gün etkinlik saat ızgarası yerine üst şeride çizilir; çok günlü etkinlik ay görünümünde kapladığı HER güne ayrı çip düşer (sürekli bant yok).",
1881
+ "eventMove ve eventCreate tarihleri iki biçimdedir: tüm-gün aralık yerel 'yyyy-MM-dd', saatli aralık ISO-Z (toISOString) — uca yazarken ikisini de karşıla.",
1882
+ "defaultDate ve defaultView DEĞİŞTİKÇE uygulanır (panelde ya da akıştan yazınca takvim o tarihe/görünüme gider, olay yaymaz); aynı değerle tekrar gelen render kullanıcının gezindiği yeri sıfırlamaz — aynı tarihe tekrar gitmek için değerin değişmesi gerekir.",
1883
+ "isLoading: takvim soluklaşır, üstte yükleyici; etkinlik tıklaması (Enter dahil), gün/slot tıklaması, aralık seçimi, taşıma ve boyutlandırma OLAY YAYMAZ. Gezinme okları ve görünüm düğmeleri açık kalır (monthChange/viewChange yayılır) — ay değiştirirken yeniden çekme sürebilir.",
1884
+ "Hafta başlangıcı dile bağlıdır: en Pazar, diğer her dil (tr dahil) Pazartesi — ay ızgarası, gün başlıkları ve hafta görünümü aynı kuralı izler; locale boşsa uygulama dili. startHour/endHour saat penceresini belirler (0–23 / 1–24, endHour en az startHour+1'e kırpılır); pencereye kısmen taşan blok en az 15 dakikalık yükseklikle çizilir.",
1281
1885
  "Etkinlik her görünümde <elementId>__event-<id> data-element-id'si taşır; bırakma hedefleri ay hücresi ve hafta/gün kolonu <elementId>__day-<yyyy-MM-dd>, tüm gün hücresi __allday-<yyyy-MM-dd>, saat dilimi __slot-<yyyy-MM-dd>T<HH> (YEREL tarih). eventClick 'click' ile, eventMove page_screenshot actions 'drag' (target etkinlik, to gün/slot) ile doğrulanır; slota bırakma o saatin ortasına düşer ve 30 dakikaya yuvarlanır. Çok günlü etkinlik aynı kimliği her gününde taşır, hedef ilk eşleşmedir."
1282
1886
  ],
1283
1887
  propNotes: {
1284
- rows: 'Etkinlik satırları; mount/monthChange akışlarının setter hedefi. Alan adları titleField/startField/endField/colorField/idField ile çözülür (nokta ayraçlı iç içe yol çalışır).',
1888
+ rows: 'Etkinlik satırları; monthChange/viewChange akışlarının setter hedefi. Alan adları titleField/startField/endField/colorField/idField/allDayField ile çözülür (nokta ayraçlı iç içe yol çalışır; boşsa title/start/end/color/id/allDay).',
1889
+ allDayField: "Tüm-gün bayrağının kolonu (boşsa 'allDay'). Tanınan değer true/false, 'true'/'false', 1/0; başka değer ya da kolon yoksa aralıktan çıkarılır. true saatli kaydı şeride alır; false 24 saati aşan saatli kaydı ızgarada tutar ama saatsiz (gece yarısı → gece yarısı) kaydı ızgaraya ALMAZ — şeritte kalır.",
1285
1890
  colorField: "Geçerli CSS rengi olduğu gibi kullanılır, semantik durum adı tema değişkenine çözülür, tanınmayan değer accent'e düşer. 'info' beyaz temada görünmezdir — ham renk ver.",
1286
- maxVisibleEvents: 'Ay hücresinde görünen çip sayısı (varsayılan 3); fazlası +n olur.',
1287
- defaultDate: "Açılış ayı (yyyy-MM-dd ya da ISO tarih-saat; katalog varsayılanı örnek veriyle aynı ay olan '2026-08-01'). YALNIZ ilk kurulumda okunur. BOŞ bırakılırsa bugünün ayı açılır — 'bugün' için sabit tarih yazmayın. İfadeyle bağlanacaksa code prop'u '{{ }}' içinde yazılır: { type: 'code', ref: \"{{ new Date().toISOString().slice(0, 10) }}\" } — parantezsiz ifade metin olarak gelir (PAGE-032 reddeder). Bu iki biçim dışındaki her metin bugüne düşer.",
1288
- startHour: 'Hafta/gün görünümünün ilk saati (varsayılan 8); endHour en az startHour+1 olacak biçimde kırpılır (varsayılan 18).'
1891
+ maxVisibleEvents: 'Ay hücresinde görünen çip sayısı (varsayılan 3); fazlası +n olur (+n ayrı tıklanmaz, hücre tıklaması sayılır).',
1892
+ defaultDate: "Açılış tarihi (yyyy-MM-dd; katalog varsayılanı örnek veriyle aynı ay olan '2026-08-01'). Gün korunur: hafta/gün/ajanda o günden açılır. Değiştikçe takvim oraya gider; boşsa bugün. 'bugün' için sabit tarih YAZMAYIN, boş bırakın; ifadeyle bağlanacaksa code prop'u '{{ }}' içinde yazılır: { type: 'code', ref: \"{{ new Date().toISOString().slice(0, 10) }}\" } — parantezsiz ifade metin olarak gelir (PAGE-032 reddeder).",
1893
+ defaultView: "month | week | day | agenda. Değiştikçe uygulanır; showViewSwitcher kapalıysa kullanıcının göreceği TEK görünüm budur.",
1894
+ agendaDays: 'Ajanda listesinin gün sayısı (varsayılan 14); boş günler listelenmez, oklar haftalık kayar. Panelde yalnız ajandaya ulaşılabiliyorsa görünür (defaultView agenda ya da showViewSwitcher açık).',
1895
+ isEditable: 'Sürükleyerek taşıma + hafta/gün kenarından boyutlandırma; ikisi de eventMove.',
1896
+ isCreatable: 'Tıklama ve sürükleyerek aralık seçimiyle eventCreate; açıkken ay görünümünde dateClick YAYILMAZ.',
1897
+ startHour: 'Hafta/gün görünümünün ilk saati (0–23, varsayılan 8); endHour (1–24, varsayılan 18) en az startHour+1 olacak biçimde kırpılır.'
1289
1898
  }
1290
1899
  },
1291
1900
  importwizard: {
1292
- summary: 'Üç adımlı CSV içe aktarma sihirbazı (dosya → kolon eşleme → önizleme); temiz ve hatalı satırları complete olayıyla akışa AYRI AYRI verir.',
1901
+ summary: 'Üç adımlı CSV/Excel içe aktarma sihirbazı (dosya → kolon eşleme → önizleme); temiz ve hatalı satırları complete olayıyla akışa AYRI AYRI verir.',
1293
1902
  behavior: [
1294
1903
  "İçe aktarmayı komponent YAPMAZ: complete akışı satırları uca kendisi yazar (döngü/bulk adımı) — komponent yalnız ayrıştırır, eşler, doğrular. complete yükü hem self'e yazılır hem event.data ile gelir.",
1904
+ "Çıktılar düğümün KENDİ prop'larıdır ve Property → self ile okunur: rows, errors, fileName, total, currentStep. Beşi de gizli (panelde çizilmez), yalnız bileşen yazar.",
1295
1905
  "Kolon eşleme otomatiktir: TR harf katlamalı normalizasyon (ç→c, ı→i…) + önce field, sonra label tam eşleşmesi, sonra içerme; iki alan aynı kolonu isterse İKİSİ de eşlenmemiş kalır ve kullanıcı select ile elle düzeltir.",
1906
+ "targetFields'te aynı field adı iki kez yazılırsa YALNIZ İLK satır kullanılır (eşleme haritası alan adına göre tutulur; tekrarlı ad eskiden sayfayı çökertiyordu).",
1296
1907
  "required alanları eşlenmeden önizlemeye geçilemez; required değeri boş satır rows'a girmez, errors'a düşer. maxRows aşımı satırı kırpmaz, hata kaydı üretir (0 = sınırsız).",
1908
+ "Dosya kapısı: yalnız .csv/.tsv/.txt ve .xlsx kabul edilir (uzantı ya da metin MIME tipi), maxFileSize (MB, 0 = sınırsız) aşan dosya okunmadan reddedilir. Reddedilen dosya adım DEĞİŞTİRMEZ, drop alanının altında uyarı çizilir. CSV kararı xlsx kararından önce verilir: Excel kurulu Windows .csv dosyalarına Excel MIME tipi veriyor.",
1297
1909
  "Ayrıştırma yalnız UTF-8'dir (encoding seçeneği yok); BOM soyulur, tırnak/çift-tırnak kuralları ve tırnak içi ayraç/satır sonu desteklenir. delimiter 'auto' ilk satırdan tahmin eder; tamamen boş satırlar atılır, ilk kalan satır başlıktır.",
1298
- "Geri düğmesi durumu KORUR (parsed/mapping silinmez); ✕ düğmesi (cancel olayı) her şeyi sıfırlar.",
1910
+ "Geri düğmesi durumu KORUR (parsed/mapping silinmez); ✕ düğmesi (cancel olayı) her şeyi sıfırlar — rows/errors/fileName/total/currentStep düğümde de boşaltılır.",
1911
+ "change olayı her adım değişiminde yayılır (dosya okundu → 1, önizleme → 2, geri → 1/0); iptal change yaymaz, cancel yayar.",
1299
1912
  "Değerler her zaman STRING'dir — sayı/tarih dönüşümü akışta yapılır. total temiz satır + hata KAYDI sayısıdır: iki zorunlu alanı boş tek satır total'i iki artırır."
1300
1913
  ],
1301
1914
  propNotes: {
1302
- targetFields: '[{ label, field, required }] — hedef şema; field boş satırlar elenir, otomatik eşleme label/field üzerinden yürür.',
1915
+ targetFields: '[{ label, field, required }] — hedef şema; field boş satırlar ve TEKRARLI field adının ikinci satırı elenir, otomatik eşleme label/field üzerinden yürür.',
1303
1916
  maxRows: '0 = sınırsız; aşan TEMİZ satırlar hata kaydına dönüşür.',
1304
- isLoading: "Gövdeyi soluklaştırır ama düğmeleri kilitlemez; complete akışı sürerken setter ile true yaz."
1917
+ maxFileSize: 'MB cinsinden dosya sınırı; 0 = sınırsız. Aşan dosya hiç okunmaz, uyarı çizilir.',
1918
+ isDisabled: 'Dosya seçimi, sürükle-bırak, eşleme kutuları ve bütün düğmeler kilitlenir; sihirbaz bulunduğu adımda durur.',
1919
+ isLoading: "Gövdeyi soluklaştırır ama düğmeleri kilitlemez; complete akışı sürerken setter ile true yaz. Akış boyunca tıklamayı da engellemek için isDisabled kullan.",
1920
+ currentStep: 'Salt OKUNUR çıktı (0 dosya, 1 eşleme, 2 önizleme); change ve cancel geri yazar, yazmak sihirbazı taşımaz.',
1921
+ rows: 'Salt OKUNUR çıktı: complete anındaki TEMİZ satırlar. Akışta self.rows ile okunur.',
1922
+ errors: 'Salt OKUNUR çıktı: [{ rowIndex, field, code, message, limit?, raw }]. code makine kimliğidir (required | maxRows), message eski metin karşılığı.',
1923
+ total: 'Salt OKUNUR çıktı: temiz satır + hata KAYDI sayısı.',
1924
+ fileName: 'Salt OKUNUR çıktı: okunan dosyanın adı; cancel boşaltır.'
1305
1925
  }
1306
1926
  },
1307
1927
  kanban: {
1308
- summary: 'Satırları durum kolonlarında sürüklenebilir kart olarak dizen pano; her taşıma cardMove olayıyla akışa bildirilir, kalıcılık akışın işidir.',
1928
+ summary: 'Satırları durum kolonlarında sürüklenebilir kart olarak dizen pano; taşıma (cardMove), ekleme isteği (cardAdd) ve silme isteği (cardRemove) akışa bildirilir, kalıcılık akışın işidir.',
1309
1929
  behavior: [
1310
- "cardMove/cardClick yükü BİLİNÇLİ olarak yalnız params ile gider (self'e yazılsa id/from/to çöp prop olur ve tetiklenen render iyimser katmanı aynı karede silerdi): akışta event.data.id / .row / .from / .to ile okunur.",
1930
+ "cardMove/cardClick/cardAdd/cardRemove yükü BİLİNÇLİ olarak yalnız params ile gider (self'e yazılsa id/from/to çöp prop olur ve tetiklenen render iyimser katmanı aynı karede silerdi): akışta event.data.id / .row / .from / .to / .column ile okunur.",
1311
1931
  "Taşıma iyimserdir: komponent rows'u DEĞİŞTİRMEZ; cardMove akışı yeni kolonu uca yazıp rows'u tazeler — (id:kolon) imzası değişince iyimser katman sıfırlanır. Kalıcılaştırılmayan taşıma, veri değiştiği anda eski kolonuna döner.",
1312
- "Kolon eşleşmesi columns[].value ile TAM string eşitliğidir; eşleşmeyen satır ilk kolona değil 'atanmamış' kuyruğuna düşer (kesikli kenarlık; yalnız doluyken çizilir, başlığı unassignedText).",
1932
+ "Ekleme ve silme İYİMSER DEĞİLDİR: isAddable kolon altına '+ addText' düğmesi koyar ve yalnız cardAdd { column } yayar; isRemovable karta × düğmesi koyar ve yalnız cardRemove { id, row, column } yayar (cardClick yaymaz). Kart ancak akış satırı yazıp/silip rows'u tazeleyince eklenir/kaybolur — silmeden önce onay sormak akışın elindedir.",
1933
+ "Kolon eşleşmesi columns[].value ile TAM string eşitliğidir; sayı value metne çevrilir (2 ile '2' eşleşir). Eşleşmeyen satır ilk kolona değil 'atanmamış' kuyruğuna düşer (kesikli kenarlık; yalnız doluyken çizilir, başlığı unassignedText, ekleme düğmesi yok). Aynı value'lu ikinci kolon ve value'su boş kolon çizilmez.",
1934
+ "emptyText iki yerde çizilir: kartı olmayan her kolonun içinde (yalnız doluysa) ve hiç kolon yokken panonun yerinde (boşsa '—').",
1313
1935
  "Kolon içi SIRALAMA yoktur: kartlar rows dizisinin sırasıyla çizilir, aynı kolona bırakma no-op'tur, sıra ne taşınır ne yayılır.",
1314
1936
  "wipLimit yalnız GÖRSELDİR: aşımda kolon başlığı kırmızılaşır ama bırakma engellenmez; 0/boş = sınırsız.",
1315
- "Kart şablonu sabittir: başlığın ilk harfi (TR büyük harf) rozet + başlık + alt başlık — resim avatarı, etiket, tarih alanı yoktur. Renk karta sol şerit, kolona üst şerit olarak iner (ham CSS ya da semantik ad).",
1316
- "Sürükleme yerel HTML5 DnD'dir; klavyeyle taşıma yolu yoktur (Enter yalnız cardClick yayar). isLoading sürüklemeyi de kilitler.",
1937
+ "Kart iki kiptedir: cardFields BOŞSA sabit şablon — titleField + subtitleField; cardFields DOLUYSA her satır bir alanı (iç içe yol) etiketiyle title/subtitle/meta/badge yuvasına ve text/number/date/datetime/money/pertance biçimine yerleştirir (biçim table/detailview ile ortak, dili locale ya da boşsa uygulama dili). Baş harf rozeti (showAvatar, varsayılan açık) İKİ kipte de çizilir ve harfini her zaman titleField'dan alır — cardFields kullanıp title alanı olmayan satırlarda rozet '?' olur: titleField'ı eşle ya da showAvatar:false yaz. Resim avatarı ve serbest component şablonu yoktur. Renk karta sol şerit (atanmamış kuyruktaki kartlar dahil), kolona üst şerit olarak iner (ham CSS ya da semantik ad).",
1938
+ "Sürükleme yerel HTML5 DnD'dir; klavyeyle taşıma yolu yoktur (Enter yalnız cardClick yayar). isLoading:true iken sürükleme, kart tıklaması, ekleme ve silme kilitlenir, hiçbir olay yayılmaz — yükleme bayrağını her dalda false'a döndür.",
1317
1939
  "Kart <elementId>__card-<id>, kolon <elementId>__col-<value> data-element-id'si taşır (id = idField değeri, yoksa card-<sıra>): cardClick page_screenshot actions 'click' ile, cardMove 'drag' (target kart, to kolon) ile uçtan uca doğrulanır — actionsReport flowRuns/requests taşımanın akışı gerçekten koşturduğunu gösterir."
1318
1940
  ],
1319
1941
  propNotes: {
1320
- rows: 'Kart satırları; alan adları columnField/titleField/subtitleField/idField/colorField ile çözülür (nokta ayraçlı iç içe yol çalışır).',
1321
- columns: '[{ label, value, color, wipLimit }] — value boş kolonlar elenir; value satır eşleşmesinin anahtarıdır.',
1322
- isDraggable: 'Varsayılan açık; kapatınca pano salt okunur olur.'
1942
+ rows: 'Kart satırları; alan adları columnField/titleField/subtitleField/idField/colorField ile çözülür (boşsa column/title/subtitle/id/color; nokta ayraçlı iç içe yol çalışır).',
1943
+ columns: "[{ label, value, color, wipLimit }] — value boş ya da yinelenen kolonlar elenir (ilki kalır); value satır eşleşmesinin anahtarıdır, sayı olabilir.",
1944
+ cardFields: "[{ field, label, slot: title|subtitle|meta|badge, format: text|number|date|datetime|money|pertance }] — boş dizi sabit kartı korur; alanı ya da değeri boş satır atlanır, slot'suz alan meta'ya düşer.",
1945
+ emptyText: "Kartsız kolonun içindeki metin (boşsa hiçbir şey) ve kolon yokken pano metni (boşsa '—').",
1946
+ addText: "Ekleme düğmesinin metni ('+ ' önekiyle); boşsa 'Add card'. Yalnız isAddable açıkken panelde görünür.",
1947
+ isAddable: 'Varsayılan kapalı; açınca her kolonun altında ekleme düğmesi, basınca cardAdd { column }.',
1948
+ isRemovable: 'Varsayılan kapalı; açınca her kartın sağ üstünde × düğmesi, basınca cardRemove { id, row, column }.',
1949
+ isDraggable: 'Varsayılan açık; kapatınca taşıma kapanır (kart tıklaması, ekleme ve silme bağımsızdır).',
1950
+ locale: "cardFields'in money/date biçim dili; boşsa uygulama dili."
1323
1951
  }
1324
1952
  },
1325
1953
  signature: {
@@ -1349,15 +1977,19 @@ export const componentKnowledge = {
1349
1977
  "Kapı kuralı: canProceed yalnız false ya da 'false' iken engeller — undefined/''/çözülmemiş şablon dahil geri kalan her şey GEÇİRİR. Güvenilir bağ {{ form1.isValid === true }} biçimidir; çıplak {{ x.value }} ölçümde güvenilmez çıktı.",
1350
1978
  "Adım tanımındaki canProceed bağı çalışma anında undefined çözülür (frontend CQ-117) — kapıyı ÜST DÜZEY canProceed prop'una bağla, adım tanımına statik değer dışında bir şey yazma.",
1351
1979
  "stepChange {currentStep, previous} taşır ve currentStep self'e yazılır; validationFail YALNIZ İleri düğmesinden yayılır (engellenen başlık tıklaması sessiz kalır); finish son adımda kapı açıkken yayılır ve adımı DEĞİŞTİRMEZ.",
1352
- "Başlık tıklaması allowClickNavigation'a bağlıdır: none | backward (varsayılan; yalnız geri) | all. isLinear:true iken ileri sıçramak aradaki HER adımın optional olmasını ister.",
1353
- "Akıştan adım sürme: setter ile currentStep yaz — değer aralığa kırpılır. Hatalı/başarısız adım görseli yoktur; tek gösterge engellenmişken soluklaşan İleri düğmesidir.",
1354
- "Form validations sistemiyle entegrasyonu YOKTUR (kapı yalnız çözülen ifade değeridir); Studio kanvasında adımlar arası geçiş Element Tree üzerindendir."
1980
+ "Başlık tıklaması allowClickNavigation'a bağlıdır: none | backward (varsayılan; yalnız geri) | all. isLinear:true iken ileri sıçramak aradaki HER görünür adımın optional olmasını ister.",
1981
+ "Akıştan adım sürme: setter ile currentStep yaz — değer aralığa kırpılır, gizli bir adımı gösteriyorsa sonraki (yoksa önceki) görünür adım açılır; bu çözüm geri yazılmaz ve olay yaymaz. DİKKAT: gizli adım varken 'currentStep - 1' yazmak takılır (gizli adıma düşen değer yeniden ileri, bulunduğun adıma çözülür) — akıştan geri/ileri giderken hedefi görünür bir adımın indeksi olarak kendin hesapla. Görünür adım hiç yoksa başlık, düğmeler VE içerik çizilmez. Hatalı/başarısız adım görseli yoktur; tek gösterge engellenmişken soluklaşan İleri düğmesidir.",
1982
+ "Adım i'nin içeriği children[i]'dir (type:'view'); steps öğe sayısı ile view sayısı eşit olmalı. Adım içeriği adımdan çıkınca SÖKÜLÜR ve dönünce yeniden kurulur: içindeki component'lerin mount akışları HER girişte yeniden koşar — Geri ile dönülen adımda mount'ta değer yazan bir akış kullanıcının girdiğini EZER. Değerini makineye geri yazan girdiler değeri korur; kaydırma, tablo sayfası gibi yerel durum kaybolur. Adım girdilerini mount'ta doldurma; ilk değeri stepper'ın mount'unda ya da önceki adımın İleri akışında yaz.",
1983
+ "Koşullu adım: steps[].isHidden:true adımı başlıkta çizmez, numaralandırmaz ve İleri/Geri/başlık gezinmesinde atlar (İleri son görünür adımda Bitir olur). Öğe alanlarında {{ }} çözülmediği için (CQ-117) koşula bağlamak için akışta setter ile steps dizisinin TAMAMINI yeniden yaz.",
1984
+ "isLoading:true iken İleri/Geri/Bitir ve başlık tıklamaları devre dışıdır (kaydetme akışında çift finish önlenir) — gönderim akışının başında isLoading'i true, sonunda (hata dalında da) false yaz; true kalırsa sihirbaz kilitli kalır. steps dizi değilse (null yazan akış) başlık ve düğmeler çizilmez, sayfa düşmez.",
1985
+ "Form validations sistemiyle entegrasyonu YOKTUR (kapı yalnız çözülen ifade değeridir). Studio kanvasında adımlar arası geçiş sağ paneldeki Steps listesinin yuvarlak işaretiyle ya da Element Tree'den yapılır (satırın kendisine tıklamak düzenleme çekmecesini açar)."
1355
1986
  ],
1356
1987
  propNotes: {
1357
1988
  surfaceStyle: NODE_SURFACE_NOTE,
1358
- steps: "[{ title, description, icon, optional, canProceed }] — tabs'ın views deseni; her adım children'da kendi kapsayıcısını taşır.",
1989
+ steps: "[{ title, description, icon, optional, isHidden, canProceed }] — tabs'ın views deseni; her adım children'da AYNI SIRADA kendi view'ını taşır. canProceed yalnız statik 'true'/'false'; bağlanabilir kapı üst düzey canProceed.",
1990
+ optionalText: "optional:true adımın başlığındaki rozet metni; boşsa 'optional' (Türkçe arayüzde ör. 'İsteğe bağlı' yaz).",
1359
1991
  canProceed: "Aktif adımın kapısı; ifadeye bağlanır. Yalnız false/'false' engeller.",
1360
- currentStep: '0 tabanlı aktif adım; setter hedefi, aralık dışı değer kırpılır.'
1992
+ currentStep: "0 tabanlı aktif adım; setter hedefi, aralık dışı değer kırpılır. Studio'dan yeni bırakılan düğümde 0 yerine null KAYDEDİLİR (frontend CQ-091, ortak mapper falsy varsayılanı düşürüyor): bileşen null'ı ilk adım sayar ama {{ <stepper>.currentStep }} / self.currentStep kullanıcı ilk kez adım değiştirene kadar null okur — ifadede {{ <stepper>.currentStep || 0 }} yaz. Şemayı kendin yazıyorsan currentStep: 0'ı açıkça ver."
1361
1993
  }
1362
1994
  }
1363
1995
  };