@appaflytech/zeyrek-ai-mcp 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/.env.example +2 -2
  2. package/.env.production.example +8 -0
  3. package/README.md +9 -8
  4. package/dist/config.js +18 -3
  5. package/dist/knowledge/backendConstraints.js +88 -0
  6. package/dist/knowledge/componentCatalog.js +415 -68
  7. package/dist/knowledge/componentEvents.js +120 -25
  8. package/dist/knowledge/functionGuards.js +134 -0
  9. package/dist/knowledge/normalize.js +512 -25
  10. package/dist/knowledge/outlines.js +31 -0
  11. package/dist/knowledge/policy.js +14 -5
  12. package/dist/knowledge/propTypes.js +5 -4
  13. package/dist/knowledge/rules.js +453 -6
  14. package/dist/knowledge/styleResolve.js +6 -1
  15. package/dist/platform/csv.js +123 -0
  16. package/dist/platform/errors.js +62 -3
  17. package/dist/platform/http.js +11 -2
  18. package/dist/platform/responses.js +16 -4
  19. package/dist/platform/screenshot.js +98 -9
  20. package/dist/platform/strictArguments.js +32 -0
  21. package/dist/platform/writeDiff.js +6 -3
  22. package/dist/resources/examples/flow-call-function.json +66 -0
  23. package/dist/resources/examples/function-total.json +70 -0
  24. package/dist/resources/examples/microfunction-node-sum.json +56 -0
  25. package/dist/resources/examples/page-dynamic-form.json +1 -1
  26. package/dist/resources/examples/page-sign-in.json +2 -2
  27. package/dist/resources/guides/component.md +14 -2
  28. package/dist/resources/guides/entity.md +321 -17
  29. package/dist/resources/guides/expressions.md +9 -0
  30. package/dist/resources/guides/functions.md +262 -0
  31. package/dist/resources/guides/getting-started.md +7 -0
  32. package/dist/resources/guides/layout.md +6 -0
  33. package/dist/resources/guides/merge.md +231 -0
  34. package/dist/resources/guides/microfunction.md +166 -0
  35. package/dist/resources/guides/microservice.md +166 -7
  36. package/dist/resources/guides/modify-existing.md +23 -0
  37. package/dist/resources/guides/page.md +101 -22
  38. package/dist/resources/guides/translation.md +35 -10
  39. package/dist/resources/guides/workflow.md +51 -2
  40. package/dist/resources/schema-fingerprint.json +4 -4
  41. package/dist/resources/schemas/AnalyzeImportQuery.json +51 -0
  42. package/dist/resources/schemas/ApplyMergePlanCommand.json +19 -0
  43. package/dist/resources/schemas/CreateBulkRowCommand.json +3 -0
  44. package/dist/resources/schemas/CreateEnvironmentCommand.json +31 -0
  45. package/dist/resources/schemas/CreateGlobalFunctionCommand.json +95 -0
  46. package/dist/resources/schemas/CreateImportPlanCommand.json +278 -0
  47. package/dist/resources/schemas/CreateMergePlanCommand.json +34 -0
  48. package/dist/resources/schemas/CreateMicrofunctionCommand.json +117 -0
  49. package/dist/resources/schemas/CreateMicrofunctionRuntimeCommand.json +51 -0
  50. package/dist/resources/schemas/CreateMicroserviceCommand.json +123 -2
  51. package/dist/resources/schemas/CreateWorkflowCommand.json +17 -3
  52. package/dist/resources/schemas/DataJobDto.json +267 -0
  53. package/dist/resources/schemas/ExportRowsCommand.json +172 -0
  54. package/dist/resources/schemas/Filter.json +3 -1
  55. package/dist/resources/schemas/GetRowsQuery.json +3 -1
  56. package/dist/resources/schemas/GlobalFunctionDto.json +89 -0
  57. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +249 -0
  58. package/dist/resources/schemas/ImportAnalysisDto.json +401 -0
  59. package/dist/resources/schemas/ImportPlanDto.json +260 -0
  60. package/dist/resources/schemas/ImportSampleDto.json +90 -0
  61. package/dist/resources/schemas/InvokeMicrofunctionCommand.json +25 -0
  62. package/dist/resources/schemas/PreviewMicroserviceCommand.json +123 -2
  63. package/dist/resources/schemas/PreviewWorkflowCommand.json +17 -3
  64. package/dist/resources/schemas/ResolveMergeConflictsCommand.json +58 -0
  65. package/dist/resources/schemas/RevertMergePlanCommand.json +19 -0
  66. package/dist/resources/schemas/RunImportCommand.json +62 -0
  67. package/dist/resources/schemas/StepDto.json +17 -3
  68. package/dist/resources/schemas/UpdateBulkRowCommand.json +3 -0
  69. package/dist/resources/schemas/UpdateEntityCommand.json +3 -1
  70. package/dist/resources/schemas/UpdateGlobalFunctionCommand.json +66 -0
  71. package/dist/resources/schemas/UpdateMicrofunctionCommand.json +121 -0
  72. package/dist/resources/schemas/UpdateMicrofunctionRuntimeCommand.json +54 -0
  73. package/dist/resources/schemas/UpdateMicroserviceCommand.json +123 -2
  74. package/dist/resources/schemas/UpdateWorkflowCommand.json +17 -3
  75. package/dist/server.js +17 -4
  76. package/dist/tools/activities.js +40 -0
  77. package/dist/tools/automations.js +14 -5
  78. package/dist/tools/common.js +16 -0
  79. package/dist/tools/dependencies.js +1 -1
  80. package/dist/tools/environments.js +52 -0
  81. package/dist/tools/files.js +51 -50
  82. package/dist/tools/flows.js +104 -5
  83. package/dist/tools/functions.js +331 -0
  84. package/dist/tools/importSchemas.js +79 -0
  85. package/dist/tools/imports.js +241 -0
  86. package/dist/tools/layouts.js +4 -4
  87. package/dist/tools/merges.js +113 -0
  88. package/dist/tools/microfunctions.js +155 -0
  89. package/dist/tools/microservices.js +112 -9
  90. package/dist/tools/pages.js +188 -66
  91. package/dist/tools/platformInfo.js +4 -1
  92. package/dist/tools/queries.js +72 -6
  93. package/dist/tools/revisions.js +94 -0
  94. package/dist/tools/rows.js +342 -22
  95. package/dist/tools/screenWrite.js +11 -2
  96. package/dist/tools/templates.js +32 -5
  97. package/dist/tools/workflows.js +28 -6
  98. package/package.json +3 -1
@@ -27,7 +27,7 @@ export const TABLE_COLUMN_TYPE_NOTE = "KOLON TİPİ SÖZLÜĞÜ (bekler → çiz
27
27
  "file: dosya alanı ya da url metni → dosya adı + ikon, yeni sekmede açılan bağlantı. " +
28
28
  "url: metin → tıklanabilir bağlantı (ikonlu, http ise yeni sekme). link: metin → tıklanmayan düz bağlantı görünümü. " +
29
29
  "email: metin → düz metin. " +
30
- "dropdown: option value'su → kolonun options listesinden LABEL, appearance renginde rozet. multiselect: value dizisi → eşleşen label'lar rozet olarak. " +
30
+ "dropdown: option value'su → kolonun options listesinden LABEL, appearance renginde rozet. multiselect: value dizisi → DEĞER SIRASIYLA label rozetleri; options'ta karşılığı olmayan değer olduğu gibi yazılır (düşürülmez), tek bir değer tek elemanlı dizi sayılır. " +
31
31
  "tag: metin → appearance renginde TEK rozet; renk kolonun appearance prop'undan gelir (satır bazında rows[i]._columns[<indeks>].appearance ile ezilir), serbest hex ALMAZ. " +
32
32
  "tags: [{ value, color }] dizisi ya da metin dizisi → çok rozet, renk SATIR VERİSİNDEN (serbest hex burada geçer), sığmayanlar +N ile toplanır. " +
33
33
  "action: veri kolonu DEĞİL — aksiyon sütunu ayrı çizilir; kolon tanımında seçilirse ham değer metin olarak görünür.";
@@ -45,9 +45,12 @@ export const STYLE_GROUP_NOTES = {
45
45
  * borderWidth…) yerini alır; kayıtlı appearance değerleri çizilmeye devam eder
46
46
  * ama Studio'da artık düzenlenmez — yeni karar surfaceStyle'a yazılır.
47
47
  */
48
+ const DATE_VALUE_FORMAT_NOTE = "YEREL duvar saati 'yyyy-MM-ddTHH:mm:ss' metni (dilim eki yok; valueOffset verilmişse o kadar saat kaydırılmış) ya da null. Biçim uygulama dilinden ve locale'den BAĞIMSIZDIR — locale yalnız ekrandaki metni değiştirir. Uca type:'text' parametreyle aynen gider; SQL'de ::timestamp ile okunur, to_timestamp/AM-PM ayrıştırması GEREKMEZ (G-01: backend bu değeri eskiden en-US '9/15/2026 10:23:00 PM' metnine çeviriyordu, 2026-09-15'te düzeltildi).";
48
49
  export const LOCALE_FOLLOWS_APP_NOTE = "Boş bırak — komponent o zaman UYGULAMA dilini izler ve language-selector ile dil değişince gün/ay adları ve saat biçimi anında güncellenir. Doldurulursa o dile SABİTLENİR (bilinçli sabitleme için). Tasarımcı listesi tr/en gösterir ama uygulama dili yolu her ISO 639-1 kodunu kabul eder; sözlüğü olmayan dilde METİN İngilizceye düşer, sayı/tarih BİÇİMİ o dilin kendi kuralını kullanır.";
49
50
  const NODE_SURFACE_NOTE = STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens +
50
51
  " Bu bileşen grubu KENDİ OKUMAZ: render katmanı yüzeyi düğüm kutusuna (.ng-app__node-item) yazar, contentOverflow kutunun kendisine iner. Eski appearance Surface alanları (background/borderWidth/radius/shadow/opacity/overflow) EMEKLİ — yeni karar buraya yazılır.";
52
+ /** layout ve navigations'ın ORTAK menü satırı grubu (frontend style-group-schemas.ts navigationStyleGroup + navigation-style-logic.ts). */
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.";
51
54
  export const componentKnowledge = {
52
55
  html: {
53
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.',
@@ -70,22 +73,32 @@ export const componentKnowledge = {
70
73
  }
71
74
  },
72
75
  table: {
73
- summary: 'Etkileşimli veri ızgarası: satır seçimi, çift tık, hücre içi düzenleme, kolon filtreleme/sıralama — her etkileşim AYRI olay olarak akışa bağlanır.',
76
+ summary: 'Etkileşimli veri ızgarası: satır seçimi, çift tık, hücre içi düzenleme, kolon filtreleme/sıralama, araç çubuğunda arama — her etkileşim AYRI olay olarak akışa bağlanır.',
74
77
  behavior: [
75
- 'Süzme/sıralama/sayfalama sunucu taraflıdır: filters/sortField/offset akışla uca gider, dönen satırlar rows prop’una setter ile yazılır.',
78
+ 'Süzme/sıralama/arama/sayfalama sunucu taraflıdır: filters/sortField/searchText/offset akışla uca gider, dönen satırlar rows prop’una setter ile yazılır.',
79
+ 'AKIŞ BAĞLANMAZSA KONTROL ÇİZİLİR AMA SATIR DEĞİŞMEZ: showSort başlığa ok, filterMode filtre satırı/paneli, isSearchable arama kutusu koyar; tablo rows’u KENDİSİ sıralamaz, süzmez, aramaz, sayfalamaz. İlgili olay (sort · filter · search · pagination) mount akışıyla aynı sorguya bağlanmadıysa ok döner, kutu dolar, satırlar yerinde kalır. Üçünün de yazdığı offset 0’a döner.',
80
+ 'SATIR TIKLAMASI HER KİPTE self.selectedRow’a yazar ve select’i çalıştırır — rowSelection:none dahil; rowSelection yalnız VURGUYU ve onay kutularını belirler (none: vurgu yok · single: tıklanan satır boyanır · multi: kutu kolonu). self.selectedRows YALNIZ multi kutularıyla değişir ve selectionChange’i çalıştırır; başlık kutusu yalnız o sayfanın satırlarını seçer/bırakır. Seçimin yeniden sorgudan sonra da tutması için bir kolon isKey olmalı (tipik: gizli id kolonu) — yoksa nesne kimliğiyle eşleşir ve yeni gelen satır nesneleri seçili görünmez.',
81
+ 'isReadonly:true HÜCRE DÜZENLEMEYİ KAPATIR (isEditable:true’yu ezer; çift tık ve Enter editör açmaz), satır tıklamasının select/doubleClick’ini, multi onay kutularını (kilitli çizilir) ve aksiyon kolonunu (hiç çizilmez) kapatır. Filtre, sıralama, arama ve sayfalama salt okunur tabloda da çalışır.',
82
+ 'Satır aksiyonu (actions[i].flow) tıklanınca ÖNCE self.selectedRow o satıra yazılır, SONRA aksiyonun kendi akışı çalışır — olay adı yoktur, akış aksiyon kaydının flow alanındadır. emptyActions satırsız çalışır ve selectedRow YAZMAZ. actionType:"dropdown" aksiyonları ⋯ menüsüne toplar.',
83
+ "totalRows yazılmazsa (0/boş) tablo elindeki satırlardan fazlasını bilemez: sayfalayıcı TEK SAYFA kalır ve gösterge o satırları sayar ('12 / 12'); ileri oku pasiftir. limit sayfa boyu listesinde (10·20·30·40·50) yoksa (25, 100) listeye eklenir. rows/filters/selectedRows akıştan null ya da dizi olmayan bir değerle gelirse boş liste sayılır, tablo çökmez (selectedRows'a tek satır nesnesi yazma — dizi yaz).",
76
84
  "isPaginated:true + akışta limit/offset parametreleri + pagination olayı üçlüsü birlikte kurulmalı; biri eksikse tablo tek sayfa kalır (platform_guide('page') Kural 1c).",
77
- "SATIR BAZLI GÖRÜNÜM EZMESİ: bir satır kendi _columns DİZİSİNİ taşıyabilir — rows[i]._columns[<kolonun columns dizisindeki İNDEKSİ>] = { appearance:'error', isBold:true, options:[...] } kolon tanımıyla birleşir (column-view.ts resolveColumn → Table.svelte:1207 <TableCell {column}>). İndeks TANIM sırasıdır: buildViewColumns index'i isHidden kolonlar elenmeden ÖNCE atar, görünür sıra değil. Kullanıcı kolon menüsünden kolon gizlese bile indeksler kaymaz (hideColumns buildViewColumns'dan SONRA uygulanır). Ezilebilen alanlar appearance · options · isBold; CSV export'u da ezmeyi uygular. Aynı kalıp _actions[i] ile satır bazlı aksiyon ezmesinde de çalışır (rowActions). ŞEMA PROP'U DEĞİLDİR — component_get prop listesinde görünmez, satır verisinin içinde taşınır.",
85
+ "SATIR BAZLI GÖRÜNÜM EZMESİ: bir satır kendi _columns DİZİSİNİ taşıyabilir — rows[i]._columns[<kolonun columns dizisindeki İNDEKSİ>] = { appearance:'error', isBold:true, options:[...] } kolon tanımıyla birleşir (column-view.ts resolveColumn → Table.svelte <TableCell {column}>). İndeks TANIM sırasıdır: buildViewColumns index'i isHidden kolonlar elenmeden ÖNCE atar, görünür sıra değil. Kullanıcı kolon menüsünden kolon gizlese bile indeksler kaymaz (hideColumns buildViewColumns'dan SONRA uygulanır). Ezilebilen alanlar appearance · options · isBold; CSV export'u da ezmeyi uygular. Aynı kalıp _actions[i] ile satır bazlı aksiyon ezmesinde de çalışır (rowActions). ŞEMA PROP'U DEĞİLDİR — component_get prop listesinde görünmez, satır verisinin içinde taşınır.",
78
86
  "Koşullu/satır bazlı renk table'da _columns ile kurulur ve style prop'unu KAYBETTİRMEZ — datatable'ın colorMap'i statiktir. Hem CSS hem satıra göre renk isteyen tablo table'dır; renk için datatable'a mecbur değilsin."
79
87
  ],
80
88
  propNotes: {
81
89
  surfaceStyle: NODE_SURFACE_NOTE,
82
90
  rows: 'Satır dizisi; mount/filter/sort/pagination akışlarının setter adımıyla doldurulur.',
83
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).",
84
- totalRows: "Toplam kayıt: Number(Steps.<adım>?.headers?.[\"total-count\"] ?? 0) guard'lı ifadesiyle yazılır.",
85
- rowSelection: "none | single | multi — seçim self.selectedRow / self.selectedRows prop'larından okunur.",
86
- columns: TABLE_COLUMN_TYPE_NOTE + " Kolon tanımları; mapping anahtarları kolonların name'iyle birebir eşleşmeli. 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.",
92
+ 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
+ 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
+ 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
+ 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
+ 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.",
97
+ 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
+ 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
+ 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.",
87
100
  style: "İKİ AYRI YAZIM KURALI: style.root emotion css() bloğudur (camelCase çalışır, iç seçici yazılabilir); style.thead|th|tr|td ise satır içi style attribute'una basılır (column-view.ts toStyleString anahtarı olduğu gibi yazar) — bu dördünde KEBAB-CASE zorunludur, fontSize sessizce düşer, font-size çalışır.",
88
- isEditable: 'Hücre içi düzenleme; değişen satır rowChange olayında self.rows üzerinde güncellenir.'
101
+ isEditable: "Hücre içi düzenleme: çift tık ya da Enter editörü açar, Enter/dışarı tıklama işler, Escape vazgeçer. Değer GERÇEKTEN değiştiyse rowChange çalışır (saklı değer de aynı normalleştirmeden geçer: '1250' metni tutan money hücresini açıp kapatmak olay üretmez) ve düzenlenen satır YENİ değeriyle self.selectedRow'dadır (satır self.rows içinde de yerinde güncellenir). number · money · pertance · progress kolonları sayı olarak yazılır; tag · tags · link kolonları düzenlenmez. isReadonly:true iken hiçbir hücre düzenlenmez."
89
102
  }
90
103
  },
91
104
  datatable: {
@@ -104,7 +117,7 @@ export const componentKnowledge = {
104
117
  image: "IMAGE/FILE kolonu düz URL string'i KABUL ETMEZ: hücre `{ absolute_path, display_name }` (ya da `fileName`) alanlarını taşıyan bir DOSYA NESNESİ (veya nesne dizisi) bekler — `DisplayCellView.svelte:10` `file.absolute_path ?? ''` okur, düz string verilince kaynak boş kalır ve hücre SESSİZCE boş çizilir (09-04 Y-21). Satır verisi bir metin kolonunda URL taşıyorsa kolonu 'url'/'link' yap ya da veriyi { absolute_path: '<url>', display_name: '<ad>' } biçimine çevir; entity'nin FILE alanı zaten bu şekli döner.",
105
118
  actions: "Satır aksiyonları. kind sözlüğü BUTON'unkinden farklıdır: error · information · solid · transparent · dark · danger · warning (butonda success/error/info/primary/warning). Yanlış sözlükten değer invalid-enum-value verir.",
106
119
  selectedRow: "Salt okunur: satır aksiyonu tıklanınca komponentin kendisi doldurur; akış ifadesinde '<elementId>.selectedRow' ile okunur.",
107
- colorMap: "Kolon içi değer→renk sözlüğü: [{ value:'Active', color:'#16a34a' }]. STATİKTİR — hücrenin kendi değerine bakar, satırın başka alanına göre hesaplanamaz. Satıra göre koşullu renk gerekiyorsa ya table + _columns ezmesi kullan ya da satır verisinde rengi taşı ({ label, color }) — render sırası: veri objesindeki color → colorMap[etiket] → autoColor.",
120
+ colorMap: "Kolon içi değer→renk sözlüğü: [{ value:'Active', color:'#16a34a' }]. STATİKTİR — hücrenin kendi değerine bakar, satırın başka alanına göre hesaplanamaz. Satıra göre koşullu renk gerekiyorsa ya table + _columns ezmesi kullan ya da satır verisinde rengi taşı ({ label, color }) — render sırası: veri objesindeki color → colorMap[etiket] → autoColor. TAG HÜCRE ŞEKLİ: metin, { label, color? } ya da { value, color? } (label yoksa value okunur; ikisi de yoksa obje ham JSON basılır) veya bunların dizisi. RENK (veri objesinde de colorMap'te de): semantik ad primary · info · success · warning · error TEMA TOKEN'INA çözülür (tema değişince izler, ham hex yazmaya gerek yok); hex/rgb/'var(--ng-…)'/CSS renk adı olduğu gibi geçer; başka bir değer (yazım hatası, çözülmemiş '{{ }}') o kademeyi ATLAR ve sıradakine düşer. Veri objesindeki variant OKUNMAZ — outline/solid kolonun appearance'ından gelir. Solid rozetin yazı rengi token'da CSS ile siyah/beyaz seçilir.",
108
121
  tableStyle: "zebra | plain — satır zemini varyantı; CSS DEĞİL. Serbest CSS için ayrı `style` prop'u vardır (parça bazlı).",
109
122
  style: "Parça bazlı CSS: &__toolbar · &__title · &__head · &__th · &__body · &__row · &__td. designerCss her bildirime !important ekler, yani komponentin kendi çerçeve/ayraç varsayılanlarını ezer — Figma tipi düz tablo bununla kurulur."
110
123
  }
@@ -114,10 +127,12 @@ export const componentKnowledge = {
114
127
  behavior: [
115
128
  "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).",
116
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.",
117
- "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."
130
+ "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."
118
132
  ],
119
133
  propNotes: {
120
- surfaceStyle: NODE_SURFACE_NOTE,
134
+ 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
+ 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.",
121
136
  errorElementId: "Sayfadaki form-validation-errors komponentinin elementId'si — bağlanmazsa alan doğrulama mesajları görünmez."
122
137
  }
123
138
  },
@@ -186,11 +201,22 @@ export const componentKnowledge = {
186
201
  phoneinput: {
187
202
  summary: 'Ülke kodu seçicili telefon girişi; değeri her zaman E.164 biçiminde yazar (+905321234567).',
188
203
  behavior: [
189
- 'Yazılan metin ülkeye göre süzülür ve hane sınırına kırpılır; DEĞER DEĞİŞMEDİYSE change YAYILMAZ — duvara çarpan tuşlar boş akış tetiklemez.',
190
- "blur her odak kaybında yayılır (değer aynı olsa bile) ve setter DEĞİLDİR — 'alan bırakıldı' kancası olarak kullan.",
191
- 'defaultCountry yalnız BAŞLANGIÇ ülkesidir; kullanıcı seçiciyi değiştirince değer yeni ülkenin koduyla yeniden kurulur.'
204
+ 'Yazılan metin ülkeye göre süzülür ve hane sınırına kırpılır; DEĞER DEĞİŞMEDİYSE change YAYILMAZ — duvara çarpan tuşlar boş akış tetiklemez. Hane sınırı ülke uzunluk bildirmiyorsa da vardır: alan kodu + numara 15 haneyi (E.164) aşamaz.',
205
+ "blur her odak kaybında yayılır (değer aynı olsa bile) ve setter DEĞİLDİR — 'alan bırakıldı' kancası olarak kullan. focus/blur SATIR düzeyindedir: numara alanı ile ülke seçicisi arasında gezinmek olay yaymaz.",
206
+ 'Üç olay (change, enter, blur) aynı yükü taşır ve ÜÇÜ DE self.value’yu yazar — platform emisyonun data’sını koşulsuz düğüme yazıyor, "setter" bayrağı okunmuyor (ARC-067). Yazılan tek anahtar value’dur; formattedValue ve isValid düğüme YAZILMAZ, akışta yalnız event.data ile okunur.',
207
+ 'defaultCountry yalnız BAŞLANGIÇ ülkesidir; kullanıcı seçiciyi değiştirince değer yeni ülkenin koduyla yeniden kurulur. Kayıtlı bir değerin alan kodu her zaman defaultCountry’yi yener.',
208
+ 'Dört kip ekranda ayrı görünür: isDisabled gri + yasak imleç, isReadonly okunur zemin, isViewmode çerçevesiz düz metin, isLoading ise alanı GRİLEŞTİRMEZ — imleç progress olur ve satırın sonunda spinner döner. isDisabled dışındaki üçü alanı odaklanabilir bırakır.'
192
209
  ],
193
- propNotes: { value: 'E.164 metni; boş girişte boş string.' }
210
+ propNotes: {
211
+ value: 'E.164 metni; boş girişte boş string.',
212
+ defaultCountry: 'Boş alanın açılacağı ülke. Panelden değiştirmek boş alanı ANINDA yeni ülkeye taşır; alanda değer varsa değerin alan kodu kazanır.',
213
+ isCountryLocked: 'Ülke seçicisini kaldırır ve yerine sabit alan kodunu metin olarak çizer — tek ülkeli formda kullanıcının yanlış ülke seçmesini kapatır. Ülkeyi defaultCountry belirler; kayıtlı değerin alan kodu yine kazanır.',
214
+ autofocus: 'Sayfa açılınca odak numara alanına gelir — ülke seçicisine değil (kilitli/yükleniyor alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
215
+ size: 'Alanın yüksekliği, puntosu, köşe yarıçapı ve yan dolgusu; boş bırakılırsa temanın form ölçüsü kullanılır.',
216
+ isReadonly: 'Alan okunur zemine geçer, odaklanabilir ve seçilebilir kalır; yazmak ve ülke değiştirmek kapalıdır, olay yayılmaz.',
217
+ isViewmode: 'Alan çerçevesiz düz metne iner (kayıt görüntüleme ekranı); odak izi yine çizilir, olay yayılmaz.',
218
+ isLoading: 'Alanı dondurur (readonly, gri değil; ülke seçici görünür kalır ama seçim geri alınır, olay yayılmaz) ve satırın sonunda dönen spinner çizer. Numara doğrulama gibi bir sorgu sürerken aç, gelince kapat.'
219
+ }
194
220
  },
195
221
  filterbuilder: {
196
222
  summary: 'İç içe and/or filtre kuralları kurar ve akışa HEM kural ağacını HEM hazır jexl ifadesini verir.',
@@ -261,7 +287,7 @@ export const componentKnowledge = {
261
287
  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.",
262
288
  direction: "'row' (varsayılan) | 'column' → flex-direction. Hangi hizalamanın ana eksen olduğunu bu belirler.",
263
289
  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.",
264
- verticalAlign: "top | middle | bottom | stretch. row'da ÇAPRAZ eksen, column'da ANA eksen — horizontalAlign ile rollerini değiştirirler.",
290
+ verticalAlign: "top | middle | bottom | stretch. row'da ÇAPRAZ eksen, column'da ANA eksen — horizontalAlign ile rollerini değiştirirler. row'da stretch seçiliyken çocuğun sabit yüksekliği (heightType fixed → heightString ya da size.h×10px) HEIGHT değil MIN-HEIGHT olarak yazılır (2026-09-15): çocuklar en uzun kardeşin boyuna eşitlenir, sabit ölçü taban kalır — eşit boylu KPI kartları için her karta elle aynı heightString yazmak gerekmez. İstisna: isScrollable çocuk kesin yüksekliğini korur. Izgara kapta (layout grid) bu prop da gap de okunmaz; eşit kart satırı flex row + stretch ile kurulur.",
265
291
  size: "'shrink' (çocuklar flex: 0 1 auto, varsayılan) | 'grow' (flex: 1 1 auto — çocuklar boşluğu paylaşır).",
266
292
  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.",
267
293
  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.",
@@ -274,12 +300,15 @@ export const componentKnowledge = {
274
300
  propNotes: {
275
301
  surfaceStyle: NODE_SURFACE_NOTE,
276
302
  rows: 'Yinelenen veri; çocuk komponent ifadelerinde satıra item / Row ile erişilir.',
277
- selectedIndex: "change olayının YÜKÜDÜR, şema prop'u DEĞİL (component_get prop listesinde görünmez; şemadaki gizli alan selectedItem'dır). RenderComponent tıklanan kartın sırasını bu adla yayar, akışta self.selectedIndex ile okunur."
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."
278
304
  }
279
305
  },
280
306
  modal: {
281
307
  summary: 'Ortalanmış katman; şemanın KÖKÜNDE page_container’ın kardeşi olarak durur, içeriği (kendi formu ve submit akışı dahil) children’ına eklenir.',
282
- behavior: ["open/close olayları akışa bağlanabilir; açma/kapama isHidden ile değil kendi open state'iyle yürür (setter ile isOpen yaz)."],
308
+ behavior: [
309
+ "open/close olayları akışa bağlanabilir; açma/kapama isHidden ile değil kendi open state'iyle yürür (setter ile isOpen yaz).",
310
+ "Kaplama çerçevesidir (isFrame): kanvasta blok tutmaz, runtime kutu stili yazmadan ayrı dalda çizer. Katalog boyutu bilerek BOŞ aralıktır (minSize 1, maxSize 0) ve 2026-09-15'ten beri doğrulayıcı boş aralıklı eksende blocks[].size'ı DENETLEMEZ — add_component ile kökte (parent null) herhangi bir { w, h } ile eklenir. Daha eski backend build'i her boyutu 'Height of modal must be between 1 and 0' (invalid-size) ile reddeder; o durumda imaj yenilenmemiştir. drawer ve toast aynı kuraldadır."
311
+ ],
283
312
  propNotes: { surfaceStyle: NODE_SURFACE_NOTE }
284
313
  },
285
314
  drawer: {
@@ -288,35 +317,254 @@ export const componentKnowledge = {
288
317
  },
289
318
  dropdown: {
290
319
  summary: 'Tek seçim listesi; options statik verilebilir ya da mount/search akışıyla uzaktan doldurulur.',
320
+ behavior: [
321
+ "Alan SEÇİLİ METNİ options'tan çözer: value dolu ama o value'lu bir option listede YOKSA kutu BOŞ görünür (hata vermez). Uzaktan dolan listede sırayı koru — önce options'ı yaz, sonra value'yu; ikisi ayrı akışlarda yazılıyorsa alan bir an boş kalır.",
322
+ "Eşleşme TİPE DUYARLIDIR (katı ===): options'tan gelen { id: 34 } sayı kalır, alanın value'su ise metindir ('34'), yani bu ikisi EŞLEŞMEZ ve kutu boş görünür. Bu, 'value var ama görünmüyor' vakalarının en sık sebebidir — eşlemeyi akış katmanında aynı tipe getir.",
323
+ "change yükü { value, selectedLabel } taşır ve ikisi de düğümün prop'una yazılır: akışta self.value ve self.selectedLabel ile okunur. selectedLabel 2026-09-11'de eklendi — etiketi göstermek için options'ta arama yapmaya gerek yok. Temizleme (X) de change yayar, ikisi de boş metin olur.",
324
+ "Arama VARSAYILAN OLARAK YERELDİR (label üzerinde bulanık eşleme). Sayfa bu bileşene bir `search` olayı bağlarsa yerel süzme KAPANIR ve tamamen akışın sorumluluğuna geçer: bileşen searchText'i yazıp olayı atar, akış options'ı yeniden yazmazsa liste değişmez. Uzak aramada isLoading'i akıştan aç/kapa.",
325
+ "isLoading KİLİT DEĞİLDİR (2026-09-11): alan odaklanabilir kalır, açık liste yükleniyor satırını gösterir ve kullanıcı yazmayı sürdürebilir. Öncesinde isLoading alanı disabled yapıyordu, yani uzak arama her tuşta odağı düşürüyordu. Tek şart: liste KAPALIYKEN isLoading açıksa chevron'a tıklamak listeyi açmaz (metin alanına tıklamak ve klavye açar) — ortak Select'in kuralı.",
326
+ 'Olaylar: mount (render katmanı atar) · change · search · focus · blur. blur 2026-09-11’de eklendi ve odak alanın TAMAMINI terk edince yayılır — liste açılırken odak arama kutusuna geçtiğinde yayılmaz, yani blur’a bağlanan doğrulama liste içinde tetiklenmez.',
327
+ "optionType='grouped' iken option'ın children'ı alt satırları çizer; çocuğu olan satır VARSAYILAN OLARAK SEÇİLEMEZ, yalnız açılır/kapanır — başlığın kendisi de seçilebilsin isteniyorsa o option'a isSelectable ver. optionType='single' iken children/isExpanded/isSelectable okunmaz.",
328
+ "Tek doğrulama kuralı `required`'dır (2026-09-11; `pattern` bildirimi kaldırıldı, panelde hiç çizilemiyordu)."
329
+ ],
291
330
  propNotes: {
292
- value: "Seçilen option'ın value'su — ilişki alanlarında etiket değil id yazılır/okunur.",
293
- options: '[{ label, value }] dizisi; akışla doldurulacaksa setter hedefi budur.'
331
+ value: "Seçilen option'ın value'su — ilişki alanlarında etiket değil id yazılır/okunur. Kutuda ancak aynı value'lu bir option listede varken metin görünür ve karşılaştırma tipe duyarlıdır (sayı 34 ile metin '34' eşleşmez).",
332
+ options: '[{ label, value }] dizisi; akışla doldurulacaksa setter hedefi budur. Ek alanlar: caption, icon/prefixImage/prefixText, color, tooltip, isDisabled, isHidden ve grouped modda children/isSelectable/isExpanded.',
333
+ optionType: "'single' düz liste, 'grouped' children ile ağaç. single'da children ve yanındaki iki bayrak hiç okunmaz.",
334
+ clearable: 'Seçimi temizleyen X düğmesi (varsayılan açık). Temizleme change yayar, ayrı bir olay yoktur.',
335
+ emptyText: 'Liste boşken gösterilen metin; boş bırakılırsa arayüz dilinden gelen "sonuç yok" metni kullanılır.',
336
+ placeholder: 'Seçim yokken kutuda duran metin; aynı zamanda yükleniyor satırının metnidir.',
337
+ searchText: "Gizli durum prop'u: bileşen OKUMAZ, `search` olayıyla yazar. Uzak aramada sorguyu akışta self.searchText ile oku.",
338
+ selectedLabel: "Gizli durum prop'u: `change` seçilen option'ın label metnini buraya yazar (temizlemede boş metin). Yalnız kullanıcı seçimiyle dolar — value'yu akıştan yazmak burayı GÜNCELLEMEZ.",
339
+ isLoading: 'Uzak arama/doldurma sürerken akıştan açılır; alan kilitlenmez, yalnız spinner ve yükleniyor satırı çizilir.'
294
340
  }
295
341
  },
296
342
  'multi-select': {
297
- summary: 'Aranabilir çoklu seçim; value bir değer dizisidir, search olayı sunucu taraflı arama kurmaya yarar.'
343
+ summary: 'Aranabilir çoklu seçim; value bir değer dizisidir, seçilenler etiket (chip) olarak görünür, search olayı sunucu taraflı arama kurmaya yarar.',
344
+ behavior: [
345
+ "value bir DİZİDİR ve üç biçimi de okunur: düz değer (['policies', 7]), şemanın biçimi ([{ value, label }]) ve eski ikizler ([{ id, text }]). Düz değer yazmak 2026-09-11'e kadar etiketi 'undefined' gösteriyordu; artık değer etiketin kendisi olur ve doğru metin options yüklenince gelir.",
346
+ "Etiketin metni options'tan tazelenir: aynı value'lu option listede varsa onun label'ı yazılır. Bu arama METİNLEŞTİREREK karşılaştırır (String(a) === String(b)), AMA yalnız etiket metni için: satırın işaretli görünmesi ve seçimin kaldırılması KATI karşılaştırma kullanır. Yani value'da metin '34', options'ta sayı 34 varsa çip doğru etiketle çizilir ama liste satırı işaretsiz kalır ve tıklamak hiçbir şey yapmaz — eşlemeyi akış katmanında aynı tipe getir (CQ-208).",
347
+ "change yükü { value: [{ value, label, id, text }] } taşır ve düğümün value prop'una yazılır: akışta self.value ile okunur. id/text, value/label'ın eski adlı ikizleridir — kayıtlı sayfalar onlarla okuduğu için bilerek korunuyor.",
348
+ 'Her seçimden sonra arama kutusu TEMİZLENİR ve tam liste geri gelir (bilinçli davranış); liste kapanınca da temizlenir ve bir kez boş search yayılır.',
349
+ "Arama VARSAYILAN OLARAK YERELDİR (label üzerinde bulanık eşleme). Sayfa bu bileşene bir `search` olayı bağlarsa yerel süzme KAPANIR ve tamamen akışın sorumluluğuna geçer: bileşen searchText'i yazıp olayı atar, akış options'ı yeniden yazmazsa liste değişmez. Uzak aramada isLoading'i akıştan aç/kapa.",
350
+ 'isLoading KİLİT DEĞİLDİR (2026-09-11): alan odaklanabilir kalır, açık liste yükleniyor satırını gösterir ve kullanıcı yazmayı sürdürebilir. Öncesinde isLoading alanı disabled yapıyordu, yani uzak arama her tuşta odağı düşürüyordu. Tek şart: liste KAPALIYKEN isLoading açıksa kutuya tıklamak listeyi açmaz (arama kutusuna odaklanmak açar).',
351
+ 'Olaylar: mount (render katmanı atar) · change · search · focus · blur. blur 2026-09-11’de eklendi ve odak alanın TAMAMINI terk edince yayılır: etikete, X’e ya da chevron’a basmak odağı alandan çıkarmaz ve liste içinde gezinmek blur yaymaz. Alan terk edilince açık liste de kapanır.',
352
+ 'Liste açıldığında seçili olanlar (ve seçili çocuğu olan başlıklar) başa alınır; sıra liste AÇILDIĞI ANDA dondurulur, seçim değiştikçe satırlar zıplamaz.',
353
+ "optionType='grouped' iken children alt satırları çizer; çocuğu olan satır VARSAYILAN OLARAK SEÇİLEMEZ: kutusu çizilmez ve satırın kendisi disabled'dır, açıp kapatmak yalnız sağdaki ok düğmesiyle (ya da klavyede Enter/ok tuşlarıyla) olur — başlık da seçilebilsin isteniyorsa o option'a isSelectable ver. optionType='single' iken children/isExpanded/isSelectable okunmaz.",
354
+ 'Arama kutusu boşken Backspace son etiketi siler; etiketler tek satıra sığmazsa fazlası "+n" rozetinde toplanır (kilitli/viewmode alanda rozet tıklanınca kalanları listeler).',
355
+ "Doğrulama kuralları: required · minItems · maxItems (2026-09-11; `pattern` bildirimi kaldırıldı — değeri dizi olan alanda uygulanacak metin yok ve panelde hiç çizilemiyordu). Panel bu iki sayı kuralını 'Min length' / 'Max length' adıyla çizer; dizide uzunluk = SEÇİLİ ELEMAN SAYISI."
356
+ ],
357
+ propNotes: {
358
+ value: "Seçili değerlerin dizisi — ilişki alanlarında etiket değil id yazılır/okunur. Düz değer dizisi de (['a', 'b']) geçerlidir; etiketler options yüklendiğinde tazelenir.",
359
+ options: '[{ label, value }] dizisi; akışla doldurulacaksa setter hedefi budur. Ek alanlar: caption, icon/prefixImage/prefixText, color, tooltip, isDisabled, isHidden ve grouped modda children/isSelectable/isExpanded.',
360
+ optionType: "'single' düz liste, 'grouped' children ile ağaç. single'da children ve yanındaki iki bayrak hiç okunmaz.",
361
+ clearable: 'Tüm seçimi temizleyen X düğmesi (varsayılan açık, yalnız seçim varken çizilir). Temizleme change yayar, ayrı bir olay yoktur.',
362
+ emptyText: 'Liste boşken gösterilen metin; boş bırakılırsa arayüz dilinden gelen "sonuç yok" metni kullanılır.',
363
+ placeholder: 'Hiç seçim yokken kutuda duran metin; aynı zamanda yükleniyor satırının metnidir.',
364
+ searchText: "Gizli durum prop'u: bileşen OKUMAZ, `search` olayıyla yazar. Uzak aramada sorguyu akışta self.searchText ile oku.",
365
+ isLoading: 'Uzak arama/doldurma sürerken akıştan açılır; alan kilitlenmez, yalnız spinner ve yükleniyor satırı çizilir.'
366
+ }
367
+ },
368
+ 'tag-input': {
369
+ summary: 'Etiket listesi girişi; value etiket dizisidir, renkli etiket destekler.',
370
+ behavior: [
371
+ 'value bir DİZİdir: [{ value, color? }]. Akıştan gelen liste çizilmeden önce SÜZÜLÜR: null giriş, metin olmayan ya da boş value düşer, aynı etiket (kırpılmış+küçük harf ölçüsüyle) ikinci kez gelirse ilk geçen bütünüyle kalır. Geçen giriş DEĞİŞTİRİLMEZ — kırpılmaz ve fazladan alanları atılmaz, yani veri kaynağından gelen ek alanlar change ile geri yazılırken korunur. Düz metin dizisi de geçerlidir: ["billing","critical"] renksiz iki etiket çizer (tags tablo hücresiyle aynı süzme).',
372
+ 'Kullanıcı listede olmayan metni Enter ile ya da listenin sonundaki "oluştur" satırıyla etikete çevirir; strict:true bunu kapatır ve yalnız options içindeki etiketler eklenebilir (metin kutuda kalır, sessizce silinmez). strict YAPIŞTIRMAYI da kapsar: çok parçalı bir yapıştırmada eşleşmeyen parçalar düşer.',
373
+ "Seçenekler iki kaynaktan gelir: statik options prop'u yerel olarak süzülür; komponente search olayına akış bağlıysa süzme SUNUCUDADIR ve options akıştan geldiği gibi gösterilir (dropdown/autocomplete deseninin aynısı). Eklenmiş etiketler her iki modda da listeden düşer.",
374
+ 'Olaylar: mount (render katmanı atar) · change (etiket eklenince/silinince/rengi değişince, setter) · search · focus · blur. Etiketin rengini değiştirmek de change yayar — renk değerin parçasıdır.',
375
+ 'Yinelenen etiket eklenemez: ölçü kırpılmış + küçük harftir ("Ankara" varken "ankara" eklenmez). Yapıştırma , ve satır sonundan böler, her parça ayrı etiket olur; options ile eşleşen parça seçeneğin RENGİYLE eklenir.',
376
+ "Zorunluluk ve eleman SAYISI sınırı Validations'tan kurulur: Required · Min length · Max length. Dizi alanında 'length' eleman sayısını ölçer (CQ-226 ad ikiliği). Bileşen bu sınırı kendisi GÖRMEZ, yani sınır dolunca giriş kapanmaz, kural gönderimde işler (CQ-093)."
377
+ ],
378
+ propNotes: {
379
+ value: 'Seçili etiketler: [{ value, color? }]. Renk hex (#rrggbb); verilmezse etiket gri çizilir.',
380
+ options: '[{ value, color?, isDisabled? }] — kullanıcıya önerilen hazır etiketler; akışla doldurulacaksa setter hedefi budur.',
381
+ colors: "Yeni etikete verilebilecek hazır renk paleti ([{ color }]). Palet ayrıca options ve value üstündeki renklerle zenginleşir; kullanıcı HSV seçiciyle palet dışı renk de verebilir.",
382
+ strict: 'Serbest metni kapatır: yalnız options içindeki etiketler eklenebilir (yazarak da yapıştırarak da), "oluştur" satırı çizilmez.',
383
+ clearable: 'Alanın sağındaki × düğmesi (hepsini siler). Varsayılan AÇIK.',
384
+ createNewLabel: 'Listede olmayan metin yazılınca çıkan "oluştur" satırının başındaki metin; satır bu metni ve tırnak içinde yazılanı gösterir.',
385
+ debounce: "Yalnız akış tabanlı search'i geciktirir (ms); yerel süzme senkrondur ve debounce'u yok sayar. Etiket seçilince bekleyen arama iptal edilir.",
386
+ searchText: "Gizli durum prop'u: bileşen OKUMAZ, `search` olayıyla YAZAR. Uzak aramada sorguyu akışta self.searchText ile oku.",
387
+ autofocus: 'Sayfa açılınca odak metin kutusuna gelir (kilitli/yükleniyor alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.'
388
+ }
389
+ },
390
+ textinput: {
391
+ summary: 'Tek satır metin girişi; value prop’u yazılabilir, change olayı { value } taşır.',
392
+ behavior: [
393
+ "change HER TUŞTA yayılır; değer kesinleşince (blur/Enter) changed yayılır — arama sorgusu ya da kayıt gibi pahalı akışı changed'e (ya da enter'a) bağla, change'e değil.",
394
+ "enter yalnız Enter'da yayılır; textinput bir form içindeyse Enter aynı anda formun submit akışını da tetikler — kaydetmeyi forma bağla, enter'a bağlarsan iki kez çalışır.",
395
+ "inputMask seçiliyse yazılan metin anında maskeye biçimlenir ve value biçimli halidir ('0(555) 123 45 67' gibi); ham rakam istiyorsan akışta ayıkla. Maske dışı karakterler sessizce düşer."
396
+ ],
397
+ propNotes: {
398
+ clearable: 'Değer varken alanın sağında × düğmesi çizer; tıklanınca value boşalır ve change + changed yayılır. Kilitli (disabled/readonly/viewmode/loading) alanda çizilmez.',
399
+ inputMask: "Hazır maske anahtarı (pattern:/date:/time:/regex:…); serbest desen için 'custom:' öneki ('custom:(###) ###-####').",
400
+ prefixIcon: "Alanın İÇİNDE solda çizilen salt görsel ikon ({ name: 'search' }); value'ya karışmaz. Renk verilmezse ikincil metin rengi. Viewmode'da hiç çizilmez: alan düz metne döner ve ikon yuvası kadar girinti bırakmaz.",
401
+ suffixIcon: "Alanın içinde sağda çizilen ikon; × ve spinner'ın sağında durur. Viewmode'da hiç çizilmez.",
402
+ maxChars: "SERT sınır: fazlası YAZILAMAZ (maskesizde tarayıcı maxlength'i, maskelide biçimlenmiş değer kesilir). Akıştan gelen daha uzun değer aynen gösterilir, yeniden yazılmaz (sayaç 45/40 okur). validations.maxLength'ten FARKLIDIR: o yalnız doğrular. 0/boş = sınırsız.",
403
+ showCounter: "Alanın altında sağa dayalı sayaç: maxChars varsa '12/40', yoksa '12'.",
404
+ autofocus: 'Sayfa açılınca odak bu alana gelir (kilitli alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
405
+ isLoading: "Alanı dondurur (readonly, gri değil) ve sağda dönen spinner çizer (× gizlenir, olay yayılmaz); changed'e bağlı sorgu sürerken aç, tamamlanınca kapat."
406
+ }
407
+ },
408
+ textarea: {
409
+ summary: 'Çok satırlı metin girişi; textinput ile aynı olay sözleşmesi (enter hariç — Enter satır ekler).',
410
+ behavior: [
411
+ "change HER TUŞTA, changed değer kesinleşince (blur) yayılır — pahalı akışı changed'e bağla.",
412
+ "autoGrow:true (varsayılan) kutuyu içerikle büyütür: minLines/maxLines sınırlar; minLines yoksa lines taban satır sayısı olur (panelde gizli olsa da). autoGrow:false sabit lines yüksekliği, fazlası kaydırılır."
413
+ ],
414
+ propNotes: {
415
+ maxChars: "SERT sınır (tarayıcı maxlength): fazlası yazılamaz. Akıştan gelen daha uzun değer aynen gösterilir (sayaç 45/40 okur). validations.maxLength'ten FARKLIDIR: o yalnız doğrular. 0/boş = sınırsız.",
416
+ showCounter: "Kutunun altında sağa dayalı sayaç: maxChars varsa '12/40', yoksa '12'.",
417
+ autofocus: 'Sayfa açılınca odak bu alana gelir (dondurulmuş alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
418
+ isLoading: "Alanı dondurur (readonly, gri değil) ve sağ üstte spinner çizer; changed'e bağlı sorgu sürerken aç, tamamlanınca kapat."
419
+ }
420
+ },
421
+ texteditor: {
422
+ summary: 'Zengin metin editörü (Quill); value HTML string, change her tuşta / changed odak çıkışında yayılır.',
423
+ behavior: [
424
+ "change HER TUŞTA yayılır (zengin metinde her karakter bir akış koşusu demektir); değer odak çıkışında kesinleşince changed yayılır — sorgu ya da kayıt gibi pahalı akışı changed'e bağla.",
425
+ 'BOŞ editör boş metin yayar: Quill kullanıcı içeriği sildiğinde <p><br></p> tutar, bileşen bunu akışa boş metin olarak yazar ki validations.required ("değer doluysa geç") gerçekten düşsün.',
426
+ "isDisabled, isReadonly ve isViewmode üçü de editörü GERÇEKTEN kilitler (2026-09-11 düzeltmesi; öncesinde readonly/viewmode yalnız CSS sınıfıydı ve alan yazmaya açık kalıyordu). isViewmode ayrıca toolbar'ı gizler ve çerçeveyi kaldırır — salt okuma gösterimi budur.",
427
+ 'Kilitliyken bile akıştan gelen value yazılır; kilit yalnız kullanıcının klavyesini kapatır.'
428
+ ],
429
+ propNotes: {
430
+ value: 'HTML string. Salt gösterim için HTML ya da Text bileşeni de kullanılabilir; burada saklanan biçimlendirmenin kendisidir.',
431
+ placeholder: 'Yalnız editör boşken çizilir (Quill kendi .ql-blank kapısını kullanır). Biçimlendirilmiş içerik girildiği anda kaybolur.',
432
+ autofocus: 'Sayfa açılınca imleç editörün içine gelir (kilitli/yükleniyor editörde ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
433
+ size: "Etiketin ve editör gövdesinin ölçüsü: sm | md | lg; boş bırakılırsa temanın form ölçüsü kullanılır.",
434
+ isLoading: "Editörü kapatır (zengin metinde tık iptali yok, Quill'in kendi kapısı kullanılır) ama disabled görünümünü almaz: alan soluklaşır, etiketin yanında spinner döner ve alan aria-busy taşır.",
435
+ style: "Alt yuvalar: &__label · &__container (editör gövdesi) · &__description · &__error. Toolbar yuvası YOKTUR — Quill onu kabın dışına, kardeş düğüm olarak çizer."
436
+ }
298
437
  },
299
- 'tag-input': { summary: 'Etiket listesi girişi; value etiket dizisidir, renkli etiket destekler.' },
300
- textinput: { summary: 'Tek satır metin girişi; value prop’u yazılabilir, change olayı { value } taşır.' },
301
- textarea: { summary: 'Çok satırlı metin girişi.' },
302
- texteditor: { summary: 'Zengin metin editörü; onChange değeri HTML string’dir. Olay adları istisnadır: onMount/onChange (on önekli).' },
303
438
  numberinput: {
304
- summary: 'Sayı girişi; change olayı number taşır.',
439
+ summary: 'Sayı girişi; value number, change her tuşta / changed kesinleşince { value: number } taşır.',
440
+ behavior: [
441
+ "change HER TUŞTA ve artı/eksi düğmesinde yayılır; değer kesinleşince (blur/Enter, düğme tıklaması) changed yayılır — sorgu ya da kayıt gibi pahalı akışı changed'e (ya da enter'a) bağla.",
442
+ "minValue/maxValue yazarken değil KESİNLEŞİNCE kırpar: min 10 alanına '15' yazılabilir (ilk tuşta 1 → 10'a çekilmez); blur/Enter'da aralık dışı değer sınıra çekilir ve change+changed yayılır. 0 gerçek sınırdır, boş = sınırsız.",
443
+ "Boşaltılan alan 0 sayılır: silinince change 0 yayılır, blur'da alan 0 gösterir; null/boş değer durumu yoktur. placeholder yalnız value akıştan null/boş yazıldığında görünür.",
444
+ "allowDemicalPoints kapalıyken tarayıcının native number alanıdır (tam sayı kullanımı; step tam sayı ver), açıkken locale'e göre biçimlenen metin alanıdır (tr 1.250,50 / en 1,250.50) — decimalPlaces, useThousandsSeparator ve locale yalnız açıkken okunur. Modu kapatıp açmak kesri düşürür."
445
+ ],
305
446
  propNotes: {
306
- prefix: "Girdinin içinde SOLDA çizilen salt görsel ek (₺, $ gibi); value'ya karışmaz.",
307
- suffix: "Girdinin içinde SAĞDA çizilen salt görsel ek (%, kg gibi); value'ya karışmaz.",
308
- useThousandsSeparator: "Binlik ayracı YALNIZ ondalık (metin) modda çalışır — allowDemicalPoints kapalıyken native number girişi ayraç gösteremez, prop sessizce etkisizdir. Odakta ayraçlar soyulur, blur'da yeniden gruplanır; ayraç yerelden gelir (tr: 1.250,50 / en: 1,250.50)."
447
+ prefix: "Girdinin içinde SOLDA çizilen salt görsel ek (₺, $ gibi); value'ya karışmaz. Viewmode'da da çizilir — değerin anlamını taşır.",
448
+ suffix: "Girdinin içinde SAĞDA çizilen salt görsel ek (%, kg gibi); value'ya karışmaz. Viewmode'da da çizilir — değerin anlamını taşır.",
449
+ prefixIcon: "Alanın içinde en solda çizilen salt görsel ikon ({ name: 'payments' }); prefix metni ikonun sağında durur. value'ya karışmaz. Viewmode'da çizilmez (metin eklerinin aksine).",
450
+ suffixIcon: "Alanın içinde sağda, suffix metninin sağında ve artı/eksi düğmelerinin solunda çizilen ikon; yükleniyor spinner'ı onun sağına gelir. Viewmode'da çizilmez.",
451
+ useThousandsSeparator: "Binlik ayracı YALNIZ ondalık (metin) modda çalışır — allowDemicalPoints kapalıyken native number girişi ayraç gösteremez, prop sessizce etkisizdir. Odakta ayraçlar soyulur, blur'da yeniden gruplanır; ayraç yerelden gelir (tr: 1.250,50 / en: 1,250.50).",
452
+ autofocus: 'Sayfa açılınca odak bu alana gelir (kilitli/yükleniyor alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
453
+ 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."
309
454
  }
310
455
  },
311
456
  incrementalinput: { summary: 'Otomatik kod üretici (önek + ayraç + sayaç); bir sonraki kodu runtime’da çeker.' },
312
- password: { summary: 'Parola girişi; textinput ile aynı olay sözleşmesi.' },
313
- checkbox: { summary: 'İki durumlu kutu; change/checked/unchecked olayları boolean taşır.' },
314
- switch: { summary: 'Anahtar; checkbox ile aynı sözleşme, görsel fark.' },
315
- radio: { summary: 'Tek seçim düğme grubu; change seçilen değeri taşır.' },
316
- datepicker: { summary: 'Tarih seçici; change yükü { value, HH, mm }.', propNotes: { locale: LOCALE_FOLLOWS_APP_NOTE } },
317
- datetimepicker: { summary: 'Tarih+saat seçici; değer event.data’da değil self.value’dadır.', propNotes: { locale: LOCALE_FOLLOWS_APP_NOTE } },
318
- daterangepicker: { summary: 'Tarih aralığı; change yükü { valueFrom, valueTo, HH, mm }.', propNotes: { locale: LOCALE_FOLLOWS_APP_NOTE } },
319
- datetimerangepicker: { summary: 'Tarih+saat aralığı; daterangepicker ile aynı yük.', propNotes: { locale: LOCALE_FOLLOWS_APP_NOTE } },
457
+ password: {
458
+ 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
+ behavior: [
460
+ "change HER TUŞTA, changed değer kesinleşince (blur/Enter) yayılır — giriş denemesi gibi pahalı akışı changed'e ya da enter'a bağla, change'e değil.",
461
+ "enter yalnız Enter'da yayılır; alan bir form içindeyse Enter aynı anda formun submit akışını da tetikler — girişi forma bağla, enter'a bağlarsan iki kez çalışır.",
462
+ "Parola alan alanı gösterir ama okumaz: value akışa düz metin gider, log ve bildirime yazma.",
463
+ "'Parola tekrar' gibi alanlar arası kural Form component'inin Custom Validations alanında tanımlanır; alanın kendi validations bloğu (required/minLength/maxLength/pattern) tek alanı doğrular."
464
+ ],
465
+ propNotes: {
466
+ revealable: 'Sağdaki göz düğmesini çizer (varsayılan açık); kapatılırsa parola hiçbir şekilde gösterilemez. Alan kilitlenince ya da isLoading açılınca açık olan parola kendiliğinden yeniden maskelenir.',
467
+ prefixIcon: "Alanın İÇİNDE solda çizilen salt görsel ikon ({ name: 'lock' }); value'ya karışmaz.",
468
+ suffixIcon: 'Alanın içinde sağda, spinner ve göz düğmesinin solunda çizilen ikon.',
469
+ maxChars: "SERT sınır (tarayıcı maxlength): fazlası YAZILAMAZ. Akıştan gelen daha uzun değer aynen gösterilir. validations.maxLength'ten FARKLIDIR: o yalnız doğrular. 0/boş = sınırsız.",
470
+ showCounter: "Alanın altında sağa dayalı sayaç: maxChars varsa '12/40', yoksa '12'. Parola UZUNLUĞUNU ekranda gösterir — PIN gibi sabit uzunluklu alanlarda aç.",
471
+ autofill: "Tarayıcı/parola yöneticisi davranışı: 'off' (varsayılan, doldurma yok), 'current-password' (giriş ekranı — kayıtlı parolayı doldurur), 'new-password' (parola belirleme/değiştirme — kaydetmeyi ve üretmeyi önerir). Giriş ekranı kuruyorsan current-password ver, yoksa tarayıcı alanı doldurmaz.",
472
+ autofocus: 'Sayfa açılınca odak bu alana gelir (kilitli/yükleniyor alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
473
+ isLoading: "Alanı dondurur (readonly, gri değil; göz düğmesi pasif, olay yayılmaz) ve sağda dönen spinner çizer; giriş isteği sürerken aç, yanıt gelince kapat.",
474
+ isViewmode: 'Salt okunur düz metin görünümü: göz düğmesi ve ikonlar çizilmez, değer maskeli kalır.'
475
+ }
476
+ },
477
+ checkbox: {
478
+ summary: 'Tek bir seçeneği işaretleten iki durumlu kutu; değeri boolean, change/checked/unchecked olayları aynı tıkta yayılır.',
479
+ behavior: [
480
+ 'Bir tık İKİ olay yayar: önce change, sonra yeni duruma göre checked ya da unchecked. Üçü de setter’dır (self.value yazılır) — kaydı yalnız BİRİNE bağla, yoksa akış iki kez koşar. checked/unchecked yalnız "işaretlenince şunu yap" gibi tek yönlü işler için vardır.',
481
+ 'Kilitli (isDisabled/isReadonly/isViewmode) ya da isLoading olan kutu hiçbir olay yaymaz; focus/blur de susar.',
482
+ 'value akıştan METİN gelirse: "false" · "0" · "no" · "off" · "null" · "undefined" · "nan" · boş metin YANLIŞ sayılır, kalan dolu metin doğru. Yine de alana boolean yaz — sözleşme boolean’dır.',
483
+ 'Zorunluluk prop değil, Form’un doğrulama listesinden gelir (`required`). checkbox’ın TEK doğrulama kuralı odur — panel boolean tipinin listesini çizer, desen/uzunluk kuralı yoktur.',
484
+ 'Birden çok seçenek gerekiyorsa checkbox yığmak yerine checkboxgroup kullan: değeri string[] ve seç-tümü/sayaç onda hazır.'
485
+ ],
486
+ propNotes: {
487
+ labelPosition: "Etiketin kutuya göre yeri: 'right' (varsayılan, kutu solda) ya da 'left'. Kutu her iki yerleşimde de etikete yapışır; ayrı bir hizalama prop’u yoktur, satırın hizası düğümün appearance kanalından gelir.",
488
+ isIndeterminate: 'Üçüncü (belirsiz) durum: kutu ne işaretli ne boş, içinde çizgi çizilir — "alt seçeneklerin bir kısmı seçili" demektir. value’yu DEĞİŞTİRMEZ, yalnız görünümü değiştirir ve HTML gereği işaretli durumu görsel olarak bastırır. Kullanıcı kutuya tıkladığı anda tarayıcı bu durumu kendisi düşürür; bileşen her render turunda prop’u DOM’a yeniden yazdığı için akış aynı değeri geri hesapladığında çizgi geri gelir (seç-tümü kutusunu her seçim değişiminde yeniden hesapla).',
489
+ isLoading: 'Kutuyu dondurur (tık iptal edilir, olay yayılmaz) ama GRİLEŞTİRMEZ ve `disabled` YAPMAZ — kilit kipi değildir: odak ve tab sırası korunur, alan `aria-busy` ile "meşgul" duyurulur. Etiketin yanında dönen bir spinner çizilir; change’e bağlı kayıt sürerken aç, yanıt gelince kapat. Kilitli bir alanda spinner yine çizilir ama kutu kilit görünümünde kalır.',
490
+ autofocus: 'Sayfa açılınca odak bu kutuya gelir (kilitli/yükleniyor kutuda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
491
+ isViewmode: 'Salt okunur görünüm: kutu çerçevesiz/zeminsiz kalır, işaretliyse tık görünür, tıklanamaz.',
492
+ value: 'Kutunun işaretli olup olmadığı (boolean). Akıştan yazılınca kutu yansıtır; kullanıcı değiştirince change setter’ı geri yazar.'
493
+ }
494
+ },
495
+ switch: {
496
+ summary: 'Anahtar; iki durumlu boolean değer, checkbox ile AYNI sözleşme (change/checked/unchecked + mount + focus/blur, üç değer olayı da setter).',
497
+ behavior: [
498
+ 'Bir flip İKİ olay yayar: önce change, sonra yeni duruma göre checked ya da unchecked. Üçü de setter’dır (self.value yazılır) — kaydı yalnız BİRİNE bağla, yoksa akış iki kez koşar.',
499
+ 'Kilitli (isDisabled/isReadonly/isViewmode) ya da isLoading olan anahtar hiçbir olay yaymaz; focus/blur de susar.',
500
+ 'value akıştan METİN gelirse: "false" · "0" · "no" · "off" · "null" · "undefined" · "nan" · boş metin YANLIŞ sayılır, kalan dolu metin doğru (checkbox ile ortak normalizasyon). Yine de alana boolean yaz — sözleşme boolean’dır.',
501
+ 'Zorunluluk prop değil, Form’un doğrulama listesinden gelir (`required`). switch’in TEK doğrulama kuralı odur — panel boolean tipinin listesini çizer, desen/uzunluk kuralı yoktur.',
502
+ 'isIndeterminate YOKTUR ve bilerek eklenmedi: anahtar tanımı gereği ikili, "kısmen açık" diye bir durumu yok. Üçüncü durum gerekiyorsa checkbox kullan.',
503
+ 'Anahtarın rengi TEMANIN vurgu renginden gelir; renk prop’u yoktur ve style düğümün KÖKÜNE yazılır (kolun kendisine ulaşmaz) — "yeşil anahtar" gibi bir istek tema ayarıdır, prop değil.'
504
+ ],
505
+ propNotes: {
506
+ labelPosition: "Etiketin anahtara göre yeri: 'right' (varsayılan, anahtar solda) ya da 'left'. Anahtar her iki yerleşimde de etikete yapışır; yükleniyor spinner'ı kolla etiketin ARASINDA durur — 'right'ta kolun sağında, 'left'te satırın sonunda.",
507
+ isLoading: 'Anahtarı dondurur (tık iptal edilir, olay yayılmaz) ama GRİLEŞTİRMEZ ve `disabled` YAPMAZ — kilit kipi değildir: odak ve tab sırası korunur, alan `aria-busy` ile "meşgul" duyurulur. Anahtarla etiketin arasında dönen bir spinner çizilir; change’e bağlı kayıt sürerken aç, yanıt gelince kapat.',
508
+ autofocus: 'Sayfa açılınca odak bu anahtara gelir (kilitli/yükleniyor anahtarda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
509
+ isViewmode: 'Salt okunur görünüm: kol sönük çerçeveyle çizilir, açıksa açık görünür, tıklanamaz.',
510
+ value: 'Anahtarın açık olup olmadığı (boolean). Akıştan yazılınca anahtar yansıtır; kullanıcı değiştirince change setter’ı geri yazar.'
511
+ }
512
+ },
513
+ radio: {
514
+ summary: 'Tek seçim düğme grubu; change seçilen değeri taşır.',
515
+ behavior: [
516
+ 'change YALNIZ seçilen değer gerçekten değişince yayılır (aynı seçeneğe tekrar tıklamak olay üretmez) ve setter’dır — self.value yazılır.',
517
+ 'Zorunluluk prop değil, Form’un doğrulama listesinden gelir (`required`). radio’nun TEK doğrulama kuralı odur — panel boolean tipinin listesini çizer, desen/uzunluk kuralı yoktur.',
518
+ 'radio’da isReadonly ve isViewmode YOKTUR — standart giriş sözleşmesinin üç kilidinden yalnız isDisabled var. Salt okunur gösterim gerekiyorsa başka bir bileşen kullan.',
519
+ 'focus/blur olayı da yoktur (checkbox/checkboxgroup’tan farkı).'
520
+ ],
521
+ propNotes: {
522
+ options: '[{ label, value }]; tek seçim, gruplama native name üzerinden — ok tuşlarıyla gezinti tarayıcınındır.',
523
+ autofocus: 'Sayfa açılınca odak gruba gelir (kilitli/yükleniyor grupta ve tasarım kanvasında çalışmaz). Grubun tek alanı olmadığı için odak ilk kilitsiz seçeneğe düşer. Sayfada tek alana ver.',
524
+ isLoading: 'Grubu KİLİTLER (checkboxgroup deseni): seçenek listesi soluklaşır, tık yutulur, change yayılmaz ve grup aria-busy taşır; etiketin yanında dönen spinner çizilir. Seçenekleri getiren sorgu sürerken aç, gelince kapat.'
525
+ }
526
+ },
527
+ datepicker: {
528
+ summary: 'Tarih seçici; change yükü { value, HH, mm }.',
529
+ behavior: [
530
+ "Kutu salt okunurdur (elle yazma çift tıkla açılır) ama programdan gelen change'i DİNLER: page_screenshot 'set' ile ISO tarih ('2026-08-01') ya da gösterim biçimi yazılabilir, değer takvimden seçilmiş gibi yayılır. 2026-09-15 öncesi olay dinlenmiyordu: kutu dolu görünüyor, prop boş kalıyordu (G-14)."
531
+ ],
532
+ propNotes: { value: DATE_VALUE_FORMAT_NOTE, locale: LOCALE_FOLLOWS_APP_NOTE }
533
+ },
534
+ datetimepicker: { summary: 'Tarih+saat seçici; değer event.data’da değil self.value’dadır.', propNotes: { value: DATE_VALUE_FORMAT_NOTE, locale: LOCALE_FOLLOWS_APP_NOTE } },
535
+ daterangepicker: {
536
+ summary: 'Tarih aralığı; change yükü { valueFrom, valueTo, HH, mm }.',
537
+ behavior: [
538
+ "İki kutu ayrı adreslenir: '<elementId>__start' (valueFrom) ve '<elementId>__end' (valueTo). page_screenshot 'set' kökü REDDEDER (tek değer yok); kutuya ISO tarih ('2026-08-01') ya da gösterim biçimi ('1 Ağu 2026') yazılır, kutu değeri kendi change yoluna sokar ve prop'a yazar. Okunamayan metin kutuyu tutulan değere geri çevirir; actionsReport propWritten:false döner (G-14, 2026-09-15)."
539
+ ],
540
+ propNotes: { valueFrom: DATE_VALUE_FORMAT_NOTE, valueTo: DATE_VALUE_FORMAT_NOTE, locale: LOCALE_FOLLOWS_APP_NOTE }
541
+ },
542
+ datetimerangepicker: {
543
+ summary: 'Tarih+saat aralığı: değer valueFrom/valueTo İKİLİSİDİR (tek value yok); her yarı bir takvim + dakika adımlı saat listesi; change yükü { valueFrom, valueTo }.',
544
+ behavior: [
545
+ "İki uç da YEREL duvar saati 'yyyy-MM-ddTHH:mm:ss' metnidir (dilim eki yok) ya da null. change her iki anahtarı birden taşır ve düğümün prop'una yazar: akış self.valueFrom / self.valueTo ile okur. Form aralığı { valueFrom, valueTo } nesnesi olarak görür; required ancak İKİSİ de doluyken geçer.",
546
+ "Bir yarının değeri ancak TARİH + SAAT ikisi de seçilince yazılır: takvimden yalnız gün seçmek change YAYMAZ — gün ekranda taslak olarak kalır (kutu günü ve 00:00'ı gösterir, CQ-237), günü yeniden seçmek de, diğer yarıyı tamamlamak da o taslağı YAZMAZ; saat listesi kendiliğinden açılır ve saat seçilince yayılır (tek datetimepicker ile aynı kural). Yarı zaten bir değer tutuyorsa (kullanıcı seçmiş ya da akış yazmış) tarihi değiştirmek TUTULAN saati koruyup hemen yayar — 2026-09-12'de düzeltildi, öncesinde listeden saat seçildikten sonra tarih değişikliği ekranda görünüp değere hiç yazılmıyordu. Akıştan gelen değer taslağı düşürür.",
547
+ "Saat listeleri minutesStep adımıyla o yarının GÜNÜ üstünde üretilir; minDate/maxDate DIŞI ve karşı ucun ÖTESİNDEKİ saatler (başlangıç için bitişten sonrası, bitiş için başlangıçtan öncesi) listede KALIR ama pasiftir. Takvimler de karşılıklı sınırlanır: bitiş takvimi başlangıç gününden önceye, başlangıç takvimi bitiş gününden sonraya izin vermez.",
548
+ "Yayma öncesi sarmalayıcı sınırlar: her uç [minDate, maxDate] içine çekilir, bitiş başlangıçtan önce kalırsa bitiş başlangıca eşitlenir. Sınır dışı bir seçim hata VERMEZ, sınıra yapışır. Akıştan yazılan değerler bu kapıdan GEÇMEZ, olduğu gibi gösterilir.",
549
+ "Doğrulama kuralları: required · min · max (2026-09-12; pattern bildirimi kaldırıldı — panel tarih-saat alanına regex kuralı hiç çizmiyordu, yazılan satırı düğüm seçilince siliyordu). min/max değeri 'yyyy-MM-ddTHH:mm' tarih-saat metnidir ve Form aralığın İKİ ucunu da sınırla karşılaştırır.",
550
+ "focus/blur ALAN düzeyindedir (2026-09-12): iki tarih girdisi, iki saat girdisi, takvim ve saat listesi arasında dolaşmak olay yaymaz; yalnız alana girmek ve alandan çıkmak yayar. Kilitli alan (isDisabled/isReadonly/isViewmode) hiçbir olay yaymaz.",
551
+ "isLoading KİLİT DEĞİLDİR (2026-09-12): alan odaklanabilir kalır, sağ uçta dönen spinner çizilir, kök aria-busy taşır (478px altındaki dikey yığılmada spinner çizilmez, aria-busy kalır). Kilit için isDisabled kullan.",
552
+ "Her yarının kendi X'i vardır ve yalnız o yarıyı boşaltır (change o yarı null, diğeri olduğu gibi). İkisini birden boşaltmanın yolu iki X ya da akıştan iki prop'u null yazmaktır.",
553
+ "Gösterim dili locale'den (boşsa uygulama dili): tarih tr'de 'd MMM yyyy', diğer dillerde 'MMM d, yyyy'; saat en'de 12 saat (01:00 PM), diğer dillerde 24 saat. Değer her dilde aynı 24 saatlik metindir. Biçim prop'u YOK (ARC-071).",
554
+ "Tarih kutuları '<elementId>__start' / '<elementId>__end' ile adreslenir (G-14, 2026-09-15). page_screenshot 'set' kökü reddeder; kutuya ISO tarih yazmak takvimden gün seçmekle AYNI kuraldır: yarı değer tutmuyorsa yalnız taslak olur ve propWritten:false döner — saat kutusu ayrıca hedeflenemez, önce akıştan değer yazın ya da saati tıklamayla seçin."
555
+ ],
556
+ propNotes: {
557
+ valueFrom: "Başlangıç: 'yyyy-MM-ddTHH:mm:ss' ya da null. Akıştan yazarken bu biçimi (ya da Date'in okuduğu bir ISO metnini) kullan; okunamayan metin yarıyı BOŞ gösterir, hata vermez.",
558
+ valueTo: "Bitiş; valueFrom ile aynı biçim. Akıştan başlangıçtan önce bir bitiş yazılırsa olduğu gibi gösterilir — sıra kuralı yalnız kullanıcı seçiminde uygulanır.",
559
+ minutesStep: "Saat listelerinin adımı, METİN enum: '1' | '2' | '3' | '4' | '5' | '6' | '10' | '12' | '15' | '30' | '60' (varsayılan '15'). 0, negatif ya da okunamayan değer 15'e düşer; 1 dakika 1440 satır demektir.",
560
+ minDate: "En erken tarih-saat ('yyyy-MM-ddTHH:mm:ss'); öncesi takvimde ve saat listesinde pasif kalır, yine de sınır dışına düşen seçim sınıra çekilir.",
561
+ maxDate: 'En geç tarih-saat; sonrası pasif, sınır dışı seçim sınıra çekilir.',
562
+ displayOffset: 'GÖSTERİMİ kaydıran saat sayısı (+3: saklanan değeri üç saat ileri göster); saklanan değer değişmez.',
563
+ valueOffset: 'YAZILAN değeri kaydıran saat sayısı; gösterim değişmez. Bir dilim farkını sabit tutmak için displayOffset ile ters işaretli kullanılır (+3 / -3): kullanıcının gördüğü saat seçtiği saattir, saklanan değer sabit kalır.',
564
+ locale: LOCALE_FOLLOWS_APP_NOTE,
565
+ isLoading: 'Akıştan açılır; alan kilitlenmez, yalnız spinner çizilir ve kök aria-busy taşır.'
566
+ }
567
+ },
320
568
  fileUpload: { summary: 'Sürükle-bırak dosya yükleme (dropzone); seçim self.value’dan okunur.' },
321
569
  fileInput: { summary: 'Dosya seç girişi; change yükü { value: [{ type, value }], fileName }.' },
322
570
  filebutton: { summary: 'Buton görünümlü dosya seçici; fileInput ile aynı yük.' },
@@ -387,7 +635,7 @@ export const componentKnowledge = {
387
635
  summary: 'Sayfa içi geri bildirim kutusu; akışlarda alert adımı yerine bu komponent kullanılır.',
388
636
  behavior: [
389
637
  "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.",
390
- "appearance.isHidden bir çözüm DEĞİLDİR: kaydedilir ama runtime hiçbir yerde okumaz (renderer yalnız props.isHidden'a bakar).",
638
+ "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.",
391
639
  "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.",
392
640
  'Başlangıçta gizli bir bildirim: şemaya props.isHidden:true yaz, açılışı akıştaki setter ile yap; timeout verilirse kendini kapatır.'
393
641
  ],
@@ -449,6 +697,7 @@ export const componentKnowledge = {
449
697
  ],
450
698
  propNotes: {
451
699
  surfaceStyle: NODE_SURFACE_NOTE,
700
+ navigationStyle: NAVIGATION_STYLE_NOTE,
452
701
  activeHref: "Vurgulanacak menü satırının adresi; boşken adres çubuğu karar verir (sidebar ile aynı davranış). YENİ prop — platform kataloğuna CI senkronuyla iner.",
453
702
  layout: "'flex' (katalog varsayılanı; akış) | 'grid' (12 kolonluk ızgara). Prop hiç yazılmamışsa renderer IZGARA çizer. Diğer altı yerleşim prop'u yalnız 'flex' iken etkilidir; anlamları container kaydındakiyle birebir aynı."
454
703
  }
@@ -459,14 +708,15 @@ export const componentKnowledge = {
459
708
  'Ağacı layout ve sidebar ile ORTAK renderer çizer (Navigations/NavigationsItem) — üçünün menü davranışı birebir aynıdır; ayrıntı sidebar kaydında.',
460
709
  "Öğe bazlı isHidden BU şemada VARDIR: canlıda elenir, Studio'nun düzenleyici kipinde görünmeye devam eder (Navigations.svelte: {#if isEditorMode || item.isHidden !== true}).",
461
710
  "activeHref boşken menü tarayıcıdaki adrese uyan satırı kendi bulur; adres mount'ta BİR KEZ okunur (bağlantılar tam sayfa yükler).",
462
- "style PROP'U ÖLÜDÜR: şema &__item ve &__item--active parçalarını sunuyor ama Navigations.svelte style diye bir prop KABUL ETMİYOR (yalnız navigations ve activeHref alır) ve satırları NavigationsItem kendi scoped .nav-btn sınıfıyla çizer. Panelden yazılan hiçbir şey uygulanmaz — sidebar'daki aynı kusurun ikizi (zeyrek-frontend docs/issues.md CQ-143 / CQ-132).",
711
+ "Satır görünümü TİPLİ navigationStyle grubuyla verilir (2026-09-15, layout ile aynı grup); serbest style'ın &__item, &__item--active ve &__icon parçaları da artık gerçek elemanlara basılır ve gruptan SONRA gelir (son söz).",
463
712
  'Menü olay YAYMAZ (şemada yalnız mount); gezinme ham <a href> ile tam sayfa yükleyerek olur.'
464
713
  ],
465
714
  propNotes: {
466
715
  navigations: "Ağaç: { title, href, icon, isHidden, isExpandable, isExpanded, children }. href düz metin ya da bağlantı seçicisinin nesnesi ({ type:'page', data, ref }) olabilir; ikisini de getHref çözer.",
467
716
  activeHref: 'Vurgulanacak satırın adresi; boş bırakılırsa tarayıcıdaki adres karar verir.',
468
717
  isHidden: 'Komponentin tamamını gizler (ortak katman prop’u); öğe bazlı gizleme navigations[].isHidden’dır.',
469
- style: 'ÖLÜ — hiçbir etkisi yok (bkz. davranış). Menü biçimini değiştirmek bugün mümkün değil.'
718
+ navigationStyle: NAVIGATION_STYLE_NOTE,
719
+ style: "Kaçış kanalı: &__item (her satır), &__item--active (seçili satır), &__icon (satır ikonu). Önce navigationStyle'ı kullan; burada yalnız grubun karşılamadığı CSS yazılır."
470
720
  }
471
721
  },
472
722
  'layout-shell': {
@@ -505,7 +755,8 @@ export const componentKnowledge = {
505
755
  summary: 'Layout’ta sayfa içeriğinin yerleştiği delik — slot’suz layout’a bağlanan sayfa BOŞ görünür.',
506
756
  behavior: [
507
757
  "Layout'ta TEK slot olmalı. Enjeksiyon HER slot'a ayrı ayrı kopyalar (layout.functions.ts injectPageSchemaIntoSlots ağacı dolaşır ve type==='slot' gören her düğümün children'ına sayfa şemasının klonunu yazar; önizleme tarafında page.mappers.mapPageLayoutToPreview aynısını yapar): iki slot = sayfa iki kez çizilir, elementId'ler çakışır. Doğrulama: page_state.layoutSlots.",
508
- "Slot'un yerleşimi ızgara bloğundan gelir ve satır yüksekliği AÇIK UÇLUDUR — runtime slot için grid-row'u `y / auto` yazar (render.functions.ts), yani sayfa içeriği ne kadar uzarsa slot o kadar uzar. Slot'a sabit yükseklik vermeye çalışmak anlamsızdır."
758
+ "Slot'un yerleşimi ızgara bloğundan gelir ve satır yüksekliği AÇIK UÇLUDUR — runtime slot için grid-row'u `y / auto` yazar (render.functions.ts), yani sayfa içeriği ne kadar uzarsa slot o kadar uzar. Slot'a sabit yükseklik vermeye çalışmak anlamsızdır.",
759
+ "Blok boyu yine de katalog sınırının içinde kalmalı: maxSize.h 200 (2026-09-12'den önce 80'di ve katalog varsayılanı 110 bile sınırın dışındaydı). Sınırı aşan TEK blok bütün yerleşimi/sayfayı PageSchemaValidationException + `invalid-size` ile düşürür."
509
760
  ]
510
761
  },
511
762
  view: { summary: 'Tabs/switcher altındaki görünüm kapsayıcısı; children gruplamaya yarar.' },
@@ -538,17 +789,30 @@ export const componentKnowledge = {
538
789
  summary: "Öneri listeli SERBEST METİN girişi. dropdown'dan farkı: value seçilen option'ın değeri değil, KULLANICININ YAZDIĞI metindir.",
539
790
  behavior: [
540
791
  "Öneriler iki kaynaktan gelir: statik options prop'u yerel olarak süzülür; komponente search olayına akış bağlıysa liste akıştan geldiği gibi gösterilir (dropdown deseninin aynısı).",
541
- "Seçilen option'ın ID'sine ihtiyacın varsa select olayını dinle: value prop'una ETİKET yazılır, id yalnız select yükünde gelir.",
792
+ "Seçilen option'ın ID'sine ihtiyacın varsa select olayını dinle: alanın value'suna ETİKET yazılır, option'ın kendi değeri yalnız select yükünde gelir. Yük 2026-09-11'de { value, label } iken { selectedValue, selectedLabel } oldu ve akışta self.selectedValue / self.selectedLabel ile okunur — eski adlar alanın KENDİ value ve label prop'larını eziyordu (seçim yapılınca kutuda option'ın değeri beliriyor, alanın etiketi de option'ın metnine dönüyordu). select'e bağlı eski akışlar yeni adlarla güncellenmeli.",
542
793
  "strict:true serbest metni bulanıklaştırmaz, blur'da eşleşmeyen metni BOŞALTIR — şehir/ülke gibi yalnız geçerli değer isteyen alanlar içindir.",
543
- "debounce yalnız akış tabanlı search'i geciktirir; yerel süzme senkrondur ve debounce'u yok sayar."
794
+ "debounce yalnız akış tabanlı search'i geciktirir; yerel süzme senkrondur ve debounce'u yok sayar. Öneri seçilince ya da alan temizlenince bekleyen arama iptal edilir.",
795
+ "minChars hem listeyi hem İSTEĞİ geciktirir (2026-09-11): eşiğin altında akışa search GİTMEZ. Eşik 0 olduğu sürece davranış değişmez.",
796
+ "Liste ne zaman açılırsa açılsın (openOnFocus dahil) GÖSTERDİĞİ öneriler yazılan metne göre süzülür; eşiğin altında ham tüm liste gösterilmez.",
797
+ "Temizleme (×) ve strict geri alma change olayını { value: '', selectedValue: '', selectedLabel: '' } ile yayar: alan boşalınca seçim durumu da boşalır. Seçimin ÜSTÜNE serbest metin yazmak ise selectedValue/selectedLabel'ı sıfırlamaz — o ikisi 'kullanıcının listeden en son seçtiği şey'dir, value'nun türevi değil.",
798
+ "Olaylar: mount (render katmanı atar) · change (her tuş vuruşu, setter) · select · search · enter · focus · blur. focus ve blur KİLİTLİ alanda (isDisabled/isReadonly/isViewmode) yayılmaz — ikisi de aynı muhafızın arkasında, yani eşleşmeyen bir focus gelmez.",
799
+ "isViewmode alanı düz metne çevirir: kenarlık, zemin ve ikonlar çizilmez, liste açılmaz (textinput/password ile aynı görünüm kuralı)."
544
800
  ],
545
801
  propNotes: {
546
802
  value: "Yazılan metin (change her tuş vuruşunda yayılır). Option değeri DEĞİLDİR.",
547
803
  options: '[{ label, value, caption?, icon? }] — akışla doldurulacaksa setter hedefi budur.',
548
- minChars: 'Liste bu karakter sayısından önce açılmaz (openOnFocus zaten açtıysa yok sayılır).',
549
- openOnFocus: 'Odakta mevcut options listesini gösterir; YENİ bir search tetiklemez.',
804
+ minChars: 'Liste bu karakter sayısından önce açılmaz ve akışa search gönderilmez (openOnFocus listeyi yine de açar, ama arama yine gitmez).',
805
+ openOnFocus: 'Odakta mevcut options listesini (yazılan metne göre süzülmüş hâliyle) gösterir; YENİ bir search tetiklemez.',
550
806
  strict: 'Blur’da options ile eşleşmeyen metni siler.',
551
- maxSuggestions: 'Listede gösterilecek azami öneri (iki modda da geçerli).'
807
+ maxSuggestions: 'Listede gösterilecek azami öneri (iki modda da geçerli).',
808
+ emptyText: 'Sonuç yokken listede duran metin; boş bırakılırsa arayüz dilinden gelen "sonuç bulunamadı" metni kullanılır.',
809
+ loadingText: 'isLoading açıkken listede duran metin; boş bırakılırsa arayüz dilinden gelen "yükleniyor" metni kullanılır.',
810
+ prefixIcon: "Alanın İÇİNDE solda çizilen salt görsel ikon ({ name: 'search' }); value'ya karışmaz. Viewmode'da hiç çizilmez.",
811
+ suffixIcon: "Alanın içinde sağda çizilen ikon; temizle düğmesinin sağında durur. Viewmode'da hiç çizilmez.",
812
+ autofocus: 'Sayfa açılınca odak bu alana gelir (kilitli alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
813
+ searchText: "Gizli durum prop'u: bileşen OKUMAZ, `search` olayıyla yazar. Uzak aramada sorguyu akışta self.searchText ile oku.",
814
+ selectedValue: "Gizli durum prop'u: `select` seçilen option'ın DEĞERİNİ buraya yazar. Yalnız kullanıcı öneriye tıklayınca/Enter'layınca dolar; serbest metin yazmak burayı güncellemez, yani value ile eşleşmesi garanti değildir.",
815
+ selectedLabel: "Gizli durum prop'u: `select` seçilen option'ın METNİNİ buraya yazar (aynı anda value'ya da yazılır). Adı `label` olamaz, alanın kendi etiketini ezerdi."
552
816
  }
553
817
  },
554
818
  avatar: {
@@ -618,6 +882,7 @@ export const componentKnowledge = {
618
882
  categoryField: 'Kategori ekseni alan adı (varsayılan "label").',
619
883
  series: "[{ valueField, type?, axis?, color?, stack?, lowField/highField?, targetField? }] — yFields'ın yerini aldı.",
620
884
  stackMode: 'none | stacked | percent.',
885
+ 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.",
621
886
  isDrillDown: 'Veri noktası tıklamasını kırıntı seviyesine çevirir; sorguyu akış yeniler.'
622
887
  }
623
888
  },
@@ -625,11 +890,23 @@ export const componentKnowledge = {
625
890
  summary: 'Değeri DİZİ olan çoklu kutu grubu (multi-select’in liste hâlinde açılmış hâli).',
626
891
  behavior: [
627
892
  'Zorunluluk/en az-en çok seçim kuralları formun validations’ından gelir (required · minItems · maxItems).',
628
- "focus/blur GRUP düzeyindedir: kutular arasında Tab'lamak ayrı olay üretmez, yalnız grubun dışına çıkılınca/girilince bir kez yayılır (otpinput deseniyle aynı)."
893
+ "focus/blur GRUP düzeyindedir: kutular arasında Tab'lamak ayrı olay üretmez, yalnız grubun dışına çıkılınca/girilince bir kez yayılır (otpinput deseniyle aynı).",
894
+ 'DEĞER MODELİ düz bir string[]’dir, seçenek→boolean haritası DEĞİL: bir seçenek, değeri listede olduğu için işaretli görünür. Bu yüzden options içindeki value’lar BENZERSİZ olmalıdır — liste value ile anahtarlandığı için aynı value’yu iki seçeneğe vermek desteklenmez (geliştirme derlemesinde “duplicate keys” hatası fırlatır, üretimde liste bozulur).',
895
+ 'Seçenek listesinin TANIMADIĞI değerler korunur: tek tık da seç-tümü de listede karşılığı olmayan bir değeri silmez (sorguyla filtrelenmiş listede önceki seçimler kaybolmasın diye).',
896
+ 'Seç-tümü YALNIZ seçilebilir seçenekleri hareket ettirir: options[].isDisabled olan bir seçenek akıştan işaretli geldiyse öyle kalır, temizlemede de elenmez. Kutu üç durumludur; bir kısmı seçiliyken tik değil ÇİZGİ çizer.',
897
+ 'Sayacın (showCounter) paydası SEÇENEK SAYISIDIR, Max items değil — bileşen kendi doğrulama değerlerini göremez (CQ-093), yani "2/5" beş seçenekten ikisi demektir.',
898
+ 'Dört kilit de (isDisabled · isReadonly · isViewmode · isLoading) tıkı yutar, change yaymaz ve focus/blur’u susturur. isDisabled dışındakiler kutuyu odaklanabilir bırakır (textinput deseni); salt okunur soluk zeminle, görüntüleme kipi zeminsiz kutuyla ayrışır.'
629
899
  ],
630
900
  propNotes: {
631
- value: 'string[] — akıştan gelen dizide string olmayan öğeler elenir.',
632
- options: '[{ label, value }]; direction ile dikey/yatay dizilir.'
901
+ value: 'string[] — akıştan gelen dizide string olmayan öğeler elenir; dizi olmayan bir değer boş liste sayılır.',
902
+ options: '[{ label, value, caption, icon, isDisabled }] — caption ikinci satıra küçük punto ile, icon kutunun sağına çizilir (dropdown/multi-select ile aynı alan adları). Diziliş direction/columnCount’tan gelir.',
903
+ columnCount: '0 = ızgara yok (diziliş direction’dan gelir), 1..4 = eşit sütunlu ızgara ve direction panelde GİZLENİR. Sayı bir ÜST SINIRDIR: hücre dar olduğunda sütun sayısı taşmak yerine kendiliğinden düşer.',
904
+ showSelectAll: 'Listenin üstüne hepsini seçen/temizleyen kutuyu koyar; metni selectAllText’tir (yalnız bu açıkken panelde görünür).',
905
+ showCounter: 'Listenin üstünde "seçili/toplam" sayacı çizer; payda seçenek sayısıdır.',
906
+ emptyText: 'Seçenek listesi boşken yazılan metin (varsayılan "No options yet"); boş bırakılırsa o durumda hiçbir şey çizilmez. Seç-tümü/sayaç şeridinin çizilmemesi ise emptyText’e DEĞİL, listenin boş olmasına bağlıdır — seçilecek/sayılacak bir şey yoktur.',
907
+ variant: 'default = kutu + metin; card = her seçenek çerçeveli kart, işaretli olanın kenarlığı vurgulanır (caption/ikon kullanılan listelerde okunur).',
908
+ isLoading: 'Grubu KİLİTLER: liste soluklaşır, tık yutulur, change yayılmaz ve grup aria-busy taşır. Seçenekleri getiren sorgu sürerken aç, gelince kapat.',
909
+ autofocus: 'Sayfa açılınca odak gruba gelir (kilitli/yükleniyor grupta ve tasarım kanvasında çalışmaz). Grubun tek alanı olmadığı için odak ilk kilitsiz kutuya düşer: seç-tümü çiziliyse o, yoksa ilk seçenek. Sayfada tek alana ver.'
633
910
  }
634
911
  },
635
912
  emptystate: {
@@ -708,12 +985,18 @@ export const componentKnowledge = {
708
985
  behavior: [
709
986
  'Bütün kutular dolduğunda change’e EK olarak complete olayı yayılır — doğrulama akışını buna bağla.',
710
987
  "resend yalnız resendSeconds>0 iken görünen düğmeden gelir ve geri sayım bitmeden tıklanamaz; tetiklenince kendi geri sayımını yeniden başlatır.",
711
- "focus/blur GRUP düzeyindedir (checkboxgroup deseniyle aynı): kutular arasında Tab'lamak olay üretmez, yalnız gruba giriş/çıkışta bir kez yayılır."
988
+ "focus/blur GRUP düzeyindedir (checkboxgroup deseniyle aynı): kutular arasında Tab'lamak olay üretmez, yalnız gruba giriş/çıkışta bir kez yayılır.",
989
+ 'change ve complete yalnız değer GERÇEKTEN değiştiğinde yayılır: reddedilen bir tuş (numeric alanda harf), boş alanda backspace ya da aynı kodun yeniden yapıştırılması hiçbir olay üretmez. Yani complete kenar tetiklidir — complete’e bağlanan doğrulama akışı tek kod için iki kez koşmaz.',
990
+ 'Bunun bedeli: alan doluyken complete bir daha yayılmaz, yani AYNI kod yeniden denenemez. Doğrulama başarısız olan akış value’yu boşaltmalı (change setter olduğu için düğümün value’suna yazmak yeter); yoksa kullanıcı kutuları elle silmeden yeni bir deneme tetikleyemez.',
991
+ 'Dört kilit ayrı davranır: yalnız isDisabled alanı Tab sırasından düşürür. isReadonly/isViewmode/isLoading alanı odaklanabilir bırakır (kutular arası ok tuşuyla gezinme açıktır) ama değiştirmeyi kapatır; isViewmode ayrıca “kodu tekrar gönder” düğmesini hiç çizmez.'
712
992
  ],
713
993
  propNotes: {
714
- value: 'Birleşik string; ortadaki kutu silinince sonraki haneler sola kayar.',
994
+ value: 'Birleşik string; ortadaki kutu silinince sonraki haneler sola kayar. Backspace dolu kutuyu yerinde siler, boş kutuda bir geri adım atar; Delete her zaman bulunduğu kutuyu siler.',
715
995
  digitCount: '2–12 arası kutu sayısı.',
716
- isMasked: 'Haneleri nokta olarak gösterir.'
996
+ isMasked: 'Haneleri nokta olarak gösterir.',
997
+ isReadonly: 'Kutular kendi zeminini alır (okunur tonu) ve yazma kapanır; alan odaklanabilir kalır.',
998
+ isViewmode: 'Alan düz metne iner — kutu çerçevesi ve zemini çizilmez, resend düğmesi görünmez.',
999
+ autofocus: 'Sayfa açılınca odak İLK kutuya gelir; yazdıkça kutular kendiliğinden ilerler (kilitli/yükleniyor alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.'
717
1000
  }
718
1001
  },
719
1002
  pagination: {
@@ -745,9 +1028,13 @@ export const componentKnowledge = {
745
1028
  summary: 'Yıldız (ya da seçilen ikon) ile puanlama girişi.',
746
1029
  behavior: [
747
1030
  'Mevcut değere yeniden tıklamak puanı 0’a düşürür; allowHalf açıkken yıldızın sol yarısı yarım puan verir.',
748
- "focus/blur yıldız GRUBUNUN tamamı için bir kez yayılır (tek bir role=\"slider\" kapsayıcıda dinlenir), yıldız başına değil."
1031
+ "focus/blur yıldız GRUBUNUN tamamı için bir kez yayılır (kapsayıcıda focusin/focusout dinlenir), yıldız başına değil: yıldıza TIKLAMAK da alana girmek sayılır ve focus yayar, yıldızlar arasında gezinmek yeniden yaymaz, blur yalnız odak şeritten büsbütün çıkınca gelir. Kilitli (isDisabled/isReadonly/isViewmode) ya da yükleniyor alan hiçbir odak olayı yaymaz."
749
1032
  ],
750
- propNotes: { value: '0..max arası sayı; akıştan gelen değer bu aralığa kırpılır.' }
1033
+ propNotes: {
1034
+ value: '0..max arası sayı; akıştan gelen değer bu aralığa kırpılır.',
1035
+ isViewmode: 'isReadonly ile AYNI sonucu verir: puan kilitlenir, imleç düz kalır, odak alınmaz. Yıldızın zemini olmadığı için ikisini ayıran görsel bir fark yoktur (zemine dayanan checkbox/checkboxgroup ayrımı burada uygulanamaz); "yasak" imleci yalnız isDisabled ile çıkar. Kilitli olduğunu söylemek yetiyorsa ikisinden birini seç, ekranda fark aranmasın.',
1036
+ autofocus: 'Sayfa açılınca odak yıldız şeridine gelir — şerit tek tab durağıdır, tek tek yıldızlar odak almaz (kilitli/yükleniyor alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.'
1037
+ }
751
1038
  },
752
1039
  result: {
753
1040
  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.',
@@ -757,11 +1044,14 @@ export const componentKnowledge = {
757
1044
  summary: 'minValue–maxValue arasında sayısal kaydırıcı (tek değer; iki tutamaklı aralık YOKTUR).',
758
1045
  behavior: [
759
1046
  'change sürüklerken sürekli, changed yalnız bırakıldığında yayılır — pahalı akışı changed’e bağla.',
760
- "focus/blur GRUP düzeyindedir (checkboxgroup/otpinput deseni): input'un kendisi değil dıştaki kapsayıcı dinler, tek giriş/çıkışta bir kez yayılır."
1047
+ "focus/blur GRUP düzeyindedir (checkboxgroup/otpinput deseni): input'un kendisi değil dıştaki kapsayıcı dinler, tek giriş/çıkışta bir kez yayılır.",
1048
+ 'isReadonly/isViewmode/isLoading rayı değiştirilemez yapar ama alanı ODAKLANABİLİR bırakır (değer klavyeyle ve ekran okuyucuyla okunur) ve kilitli alan focus/blur/change YAYMAZ; native disabled ve “yasak” imleci yalnız isDisabled’dan gelir.'
761
1049
  ],
762
1050
  propNotes: {
763
- value: 'Sayı; akıştan gelen değer [minValue, maxValue] aralığına kırpılır (0 geçerli sınırdır).',
764
- showTicks: 'datalist ile çentik gösterir (yalnız ≤50 çentikte).'
1051
+ value: 'Sayı; akıştan gelen değer [minValue, maxValue] aralığına kırpılır (0 geçerli sınırdır) ve adıma oturmuyorsa en yakın geçerli adımda GÖSTERİLİR (tutamağın gittiği yer) — akışa yazılan sayı bundan etkilenmez, ekrandaki ile aynı olması isteniyorsa adıma oturan bir değer yaz.',
1052
+ step: '0/negatif → 1. Ondalık adımda (0.5) gösterilen sayının basamak sayısı adımdan türer; valueFormat.decimals yazılıysa o kazanır.',
1053
+ showTicks: 'datalist ile çentik gösterir (yalnız ≤50 çentikte).',
1054
+ autofocus: 'Sayfa açılınca odak kaydırıcıya gelir (kilitli/yükleniyor alanda ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.'
765
1055
  }
766
1056
  },
767
1057
  statcard: {
@@ -780,9 +1070,24 @@ export const componentKnowledge = {
780
1070
  switcher: {
781
1071
  summary: 'İki durumu YAN YANA gösteren boolean kontrol (switch’in kolu yerine iki segment); aktif olan vurgulanır.',
782
1072
  behavior: [
783
- 'Olay sözleşmesi switch ile aynıdır: change · checked · unchecked, hepsi boolean taşır.',
784
- 'Yan etiket (label) ve description YOKTUR — içerik iki segmentin kendi trueLabel/trueIcon ve falseLabel/falseIcon alanlarıdır.'
785
- ]
1073
+ 'Olay sözleşmesi switch ile aynıdır: change · checked · unchecked + mount + focus/blur; üç değer olayı da boolean taşır ve setter’dır — kaydı yalnız BİRİNE bağla, yoksa akış iki kez koşar.',
1074
+ 'Alan etiketi (label) ve description 2026-09-11’de EKLENDİ ve boş doğar: yazılırsa etiket track’in ÜSTÜNDE, açıklama ALTINDA çizilir. Segmentlerin kendi metni ayrıdır (trueLabel/trueIcon · falseLabel/falseIcon) — "Aylık / Yıllık" segmentlere, "Fatura dönemi" label’a yazılır. isInvalid açıkken açıklamanın yerini invalidText alır.',
1075
+ 'Kilitli (isDisabled/isReadonly/isViewmode) ya da isLoading olan kontrol hiçbir DEĞER olayı yaymaz; focus/blur de susar. `mount` bunun dışındadır: onu bileşen değil render katmanı atar, kilitli kontrolde de yayılır.',
1076
+ 'value akıştan METİN gelirse: "false" · "0" · "no" · "off" · "null" · "undefined" · "nan" · boş metin YANLIŞ sayılır, kalan dolu metin doğru (checkbox/switch ile ortak normalizasyon, 2026-09-11). Yine de alana boolean yaz — sözleşme boolean’dır.',
1077
+ 'Zorunluluk prop değil, Form’un doğrulama listesinden gelir (`required`) — switcher’ın TEK doğrulama kuralı odur. 2026-09-11’e kadar panel bu bileşen için hiç liste çizmiyordu (slug `ComponentValidationTypes` sözlüğünde yoktu), artık boolean tipinin listesi çiziliyor.',
1078
+ 'Form içindeki switcher artık boolean bir alan olarak davranır: submit’te değeri boolean şemayla doğrulanır (önce metin tipine düşüyordu, yani kural yokken bile tip hatası veriyordu) ve formun Reset’i onu da başlangıç değerine döndürür (önce sıfırlamadan muaftı). 2026-09-11.',
1079
+ 'Vurgulu segmentin rengi TEMANIN vurgu renginden gelir; renk prop’u yoktur ve style düğümün KÖKÜNE yazılır (segmentlere ulaşmaz).'
1080
+ ],
1081
+ propNotes: {
1082
+ label: 'Alanın adı, track’in üstünde. Boş bırakılırsa hiç çizilmez ve kontrolün ekran okuyucudaki adı iki segmentin metninden okunur — form içindeki switcher’a etiket yaz.',
1083
+ description: 'Track’in altındaki yardım metni; isInvalid açıkken yerini invalidText alır (ikisi aynı anda çizilmez).',
1084
+ value: 'Hangi segmentin seçili olduğu (boolean; true = sağdaki/trueLabel segmenti). Akıştan yazılınca kontrol yansıtır, kullanıcı değiştirince change setter’ı geri yazar.',
1085
+ trueLabel: 'Sağdaki (true) segmentin metni; varsayılan "On". trueIcon ile birlikte ya da tek başına kullanılır — ikisi de boşsa segment boş bir kutu olarak çizilir.',
1086
+ falseLabel: 'Soldaki (false) segmentin metni; varsayılan "Off". falseIcon ile birlikte ya da tek başına kullanılır.',
1087
+ autofocus: 'Sayfa açılınca odak bu kontrole gelir (kilitli/yükleniyor kontrolde ve tasarım kanvasında çalışmaz). Sayfada tek alana ver.',
1088
+ isViewmode: 'Salt okunur görünüm: vurgu sönük renge düşer, seçili segment seçili görünür, tıklanamaz.',
1089
+ isLoading: 'Kontrolü dondurur (tık iptal edilir, olay yayılmaz) ama GRİLEŞTİRMEZ ve `disabled` YAPMAZ — kilit kipi değildir: odak ve tab sırası korunur, alan `aria-busy` taşır. Track’in sağında dönen spinner çizilir.'
1090
+ }
786
1091
  },
787
1092
  'theme-toggle': {
788
1093
  summary: 'Uygulamayı açık/koyu temaya çeviren tek düğme; tercih tarayıcıda kalıcıdır. Olay YAYMAZ.',
@@ -813,9 +1118,25 @@ export const componentKnowledge = {
813
1118
  summary: 'Bağımsız saat seçici; değer tam olarak HH:mm biçimindedir.',
814
1119
  behavior: [
815
1120
  'minTime/maxTime dışındaki seçenekler listeden ATILMAZ, pasifleştirilir; minutesStep seçenek adımını belirler.',
816
- "focus/blur GRUP düzeyindedir: paylaşılan Select kendi focus'unu yayar ama blur'ü yok, o yüzden ikisi de kapsayıcı üstünden köklendi — checkboxgroup/otpinput/slider ile aynı desen."
1121
+ "Liste adımdan ÜRETİLİR, ama alanın TUTTUĞU saat adıma düşmese bile listede kalır (2026-09-11): minutesStep=15 iken 09:07 kendi yerine eklenir ve kutuda görünür. Öncesinde eşleşen seçenek olmadığı için alan BOŞ görünüyordu — veritabanından gelen saatlerin olağan hâli. Şart, değerin KATI 'HH:mm' olmasıdır: '9:07' ya da '09:07:00' hiçbir seçenekle eşleşmez ve kutu yine boş kalır.",
1122
+ "change yükü { value, selectedLabel } taşır ve ikisi de düğümün prop'una yazılır: akışta self.value ve self.selectedLabel ile okunur. selectedLabel 2026-09-11'de eklendi — 12h kipinde etiket '01:00 PM' iken value '13:00' kalır, gösterilen metnin tek kaynağı budur. Temizleme (X) de change yayar, ikisi de boş metin olur.",
1123
+ "isLoading KİLİT DEĞİLDİR (2026-09-11): alan odaklanabilir kalır, kök aria-busy taşır ve açık liste yükleniyor satırını gösterir. Öncesinde isLoading alanı disabled yapıyordu; ortak Select'i kullanan üç bileşenden en son bu düzeltildi. Tek şart: liste KAPALIYKEN isLoading açıksa chevron'a tıklamak listeyi açmaz (metin alanına tıklamak ve klavye açar) — ortak Select'in kuralı.",
1124
+ "focus/blur GRUP düzeyindedir: paylaşılan Select kendi focus'unu yayar ama blur'ü yok, o yüzden ikisi de kapsayıcı üstünden köklendi — checkboxgroup/otpinput/slider ile aynı desen. Alanın kendi kromuna (chevron, X) basmak artık SAHTE blur yaymaz: sarmalayıcı mousedown'ı iptal edip odağı alanda tutuyor, yani blur yalnız alan gerçekten terk edilince gelir. (Odaksız alanda chevron'a basmak listeyi açar ve normal focus'unu yayar.)",
1125
+ 'Doğrulama kuralları: required · min · max (2026-09-11; pattern bildirimi kaldırıldı — panel saat alanına regex kuralı hiç çizmiyor, yazılan satırı düğüm seçilince siliyordu). min/max değerleri de HH:mm metnidir ve saniye taşıyan bir değer karşılaştırmadan sessizce düşer (CQ-095).',
1126
+ 'format YALNIZ GÖSTERİMDİR: 12h etiketleri 01:00 PM biçiminde çizer, saklanan value her iki kipte de HH:mm kalır. Liste içi arama DEĞERİ değil ETİKETİ arar, yani 12h kipinde "13" yazmak saat 13:00\'ü BULMAZ (etiketi "01:00 PM"), "01" bulur.'
817
1127
  ],
818
- propNotes: { value: "'HH:mm' — Time doğrulamaları ve formun saat karşılaştırmaları bu biçimi bekler." }
1128
+ propNotes: {
1129
+ value: "'HH:mm' — Time doğrulamaları ve formun saat karşılaştırmaları bu biçimi bekler. Adıma düşmeyen bir saat de gösterilir (listeye kendi yerinde eklenir); biçimi bozuk bir değer gösterilmez, kutu boş görünür.",
1130
+ minutesStep: "Liste adımı, METİN enum: '1' | '5' | '10' | '15' | '30' | '60'. 1 dakika 1440 satır demektir.",
1131
+ minTime: "Bu saatten öncesi listede KALIR ama seçilemez. Serbest metin alanı, bağışlayıcı okunur: '9', '9:00', '9.00', '0900' hepsi 09:00'dır; okunamayan metin sınır KOYMAZ (sessizce sınırsız).",
1132
+ maxTime: 'Bu saatten sonrası listede kalır ama seçilemez; minTime ile aynı bağışlayıcı okuma.',
1133
+ disabledTimes: "[{ time: 'HH:mm' }] — aralığın içinde olsalar bile seçilemeyen saatler. Okunamayan satır hiçbir saati engellemez. Zaten seçili olan bir saati engellemek onu TEMİZLEMEZ: alan değeri pasif hâlde tutmayı sürdürür, gerekiyorsa akıştan boşalt.",
1134
+ clearable: 'Seçili saatin yanındaki X (varsayılan açık). Temizleme change yayar, ayrı bir olay yoktur.',
1135
+ emptyText: 'Liste içinde arama hiçbir saati bulamayınca yazılacak metin; boş bırakılırsa arayüz dilinden gelen "sonuç yok" metni kullanılır.',
1136
+ format: "'24h' (varsayılan) | '12h'. Yalnız etiketleri değiştirir; tarih/saat bileşenleri 24 saatlik gösterime sabit olduğu için aynı sayfada ikisi ayrışır (CQ-098).",
1137
+ selectedLabel: "Gizli durum prop'u: `change` seçilen saatin GÖSTERİLEN metnini buraya yazar (temizlemede boş metin). Yalnız kullanıcı seçimiyle dolar — value'yu akıştan yazmak burayı GÜNCELLEMEZ.",
1138
+ isLoading: 'Akıştan açılır; alan kilitlenmez, yalnız spinner çizilir ve kök aria-busy taşır.'
1139
+ }
819
1140
  },
820
1141
  toast: {
821
1142
  summary: 'Geçici bildirim TETİKLEYİCİSİ: sayfada yer kaplamaz (0×0), isOpen true’ya çekildiğinde bir toast atar.',
@@ -866,13 +1187,14 @@ export const componentKnowledge = {
866
1187
  "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.",
867
1188
  "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).",
868
1189
  "defaultDate ve defaultView yalnız İLK kurulumda okunur — sonradan prop değişse de takvim kımıldamaz.",
869
- "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."
1190
+ "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.",
1191
+ "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."
870
1192
  ],
871
1193
  propNotes: {
872
1194
  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).',
873
1195
  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.",
874
1196
  maxVisibleEvents: 'Ay hücresinde görünen çip sayısı (varsayılan 3); fazlası +n olur.',
875
- defaultDate: "Açılış ayı (yyyy-MM-dd; katalog varsayılanı örnek veriyle aynı ay olan '2026-08-01'). YALNIZ ilk kurulumda okunur.",
1197
+ 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.",
876
1198
  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).'
877
1199
  }
878
1200
  },
@@ -901,7 +1223,8 @@ export const componentKnowledge = {
901
1223
  "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.",
902
1224
  "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.",
903
1225
  "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).",
904
- "Sürükleme yerel HTML5 DnD'dir; klavyeyle taşıma yolu yoktur (Enter yalnız cardClick yayar). isLoading sürüklemeyi de kilitler."
1226
+ "Sürükleme yerel HTML5 DnD'dir; klavyeyle taşıma yolu yoktur (Enter yalnız cardClick yayar). isLoading sürüklemeyi de kilitler.",
1227
+ "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."
905
1228
  ],
906
1229
  propNotes: {
907
1230
  rows: 'Kart satırları; alan adları columnField/titleField/subtitleField/idField/colorField ile çözülür (nokta ayraçlı iç içe yol çalışır).',
@@ -914,15 +1237,20 @@ export const componentKnowledge = {
914
1237
  behavior: [
915
1238
  "change her tamamlanan ÇİZGİDE (pointer bırakılınca) yayılır, hareket sırasında değil; value hem self.value'ya yazılır (setter) hem event.data.value ile gelir. Temizleme önce change('') sonra clear (veri taşımaz) yayar.",
916
1239
  "outputFormat 'png' (varsayılan) base64 data-URL üretir; 'svg' HAM SVG işaretlemesi döner (data-URL DEĞİL) — kaydederken/gömerken ayrımı gözet. PNG üretimi başarısız olursa sessizce SVG metnine düşer.",
917
- "Mevcut value yeniden düzenlemeye YÜKLENMEZ: data:image… ya da <svg ile başlayan değer arka planda resim olarak gösterilir, ilk yeni çizgi onu tamamen değiştirir — ekleme/undo yoktur.",
1240
+ "Mevcut value yeniden düzenlemeye VEKTÖR olarak yüklenmez: data:image… ya da <svg ile başlayan değer arka planda resim olarak gösterilir, ilk yeni çizgi onu tamamen değiştirir — ekleme/undo yoktur. Tanınmayan metin hiç çizilmez.",
1241
+ "DIŞARIDAN yazılan value pedi sıfırlar: akış setter'ı value'yu '' yaparsa çizim ekrandan da silinir, başka bir imza yazarsa o arka plana geçer. Bileşenin kendi yazdığı değerin yankısı dış yazma sayılmaz, yani imza her vuruşta süpürülmez. Akıştan temizlemenin yolu budur; ayrı bir clear aksiyonu yoktur.",
1242
+ "outputFormat / penColor / penWidth değişince EKRANDAKİ vuruşlar yeni ayarlarla yeniden dışa aktarılır ve change yayılır — panelden biçimi çevirmek değeri de çevirir. Vuruşu olmayan kayıtlı value yeniden üretilemez, ona dokunulmaz.",
918
1243
  "Yeniden boyutlanma çizimi silmez ama mürekkep sol üst köşeye çapalı kalır (ölçeklenmez); bir sonraki çizgi güncel boyutla dışa aktarır.",
919
- "Zorunluluk formun validations'ıyla kurulur (şemada isRequired yoktur). Ekran rengi penColor || tema metni, dışa aktarım rengi penColor || #111111 — tema değişkeni dışa aktarıma taşınmaz.",
1244
+ "Zorunluluk formun validations'ıyla kurulur (şemada isRequired yoktur). Ekran rengi penColor || tema metni, dışa aktarım rengi penColor || #111111 — tema değişkeni dışa aktarıma taşınmaz, yani koyu temada ekranda açık görünen mürekkep koyu olarak dışa aktarılır.",
920
1245
  "isDisabled/isReadonly/isViewmode üçü de kilitler; kilitliyken Clear düğmesi hiç çizilmez."
921
1246
  ],
922
1247
  propNotes: {
923
1248
  value: "İmza string'i (PNG data-URL ya da SVG işaretlemesi); boş imza ''dir, null değil.",
1249
+ placeholder: "Boş pedin ortasındaki çağrı metni ('İmzanızı buraya atın'); yazılmazsa ✒️ simgesi çizilir. Yalnız ped boşken ve kayıtlı imza yokken görünür.",
924
1250
  outputFormat: "'png' | 'svg' — svg dışındaki her değer png sayılır.",
925
- penWidth: "En az 1'e kırpılır; geçersiz değer 2'ye düşer."
1251
+ penWidth: "En az 1'e kırpılır; geçersiz değer 2'ye düşer.",
1252
+ size: "sm | md | lg; boş bırakılırsa temanın form ölçüsü. YALNIZ pedin kendi yazısını (placeholder ve Clear düğmesi) ve pedin TABAN yüksekliğini değiştirir; etiketin ve açıklama satırının puntosuna DOKUNMAZ (ikisi de ortak bileşen, kendi tokenlarını okur). Pedin gerçek yüksekliğini kanvastaki düğüm belirler.",
1253
+ clearText: "Clear düğmesinin metni; boşsa 'Clear'. Düğme yalnız değer varken ve alan kilitli değilken çizilir."
926
1254
  }
927
1255
  },
928
1256
  stepper: {
@@ -1022,7 +1350,26 @@ export const INTERNAL_ROLES_BY_TYPE = {
1022
1350
  'pager-refresh',
1023
1351
  "sort-<kolon slug'ı>",
1024
1352
  'colmenu',
1353
+ 'search (arama kutusu, isSearchable)',
1025
1354
  'row-<0 tabanlı sıra; sayfa değişince yeniden numaralanır>'
1355
+ ],
1356
+ kanban: [
1357
+ "card-<kart id'si (idField; yoksa card-<sıra>)>",
1358
+ "col-<kolon value'su> (bırakma hedefi)"
1359
+ ],
1360
+ eventcalendar: [
1361
+ "event-<etkinlik id'si (idField; yoksa event-<sıra>)>",
1362
+ 'day-<yyyy-MM-dd> (ay hücresi / hafta-gün kolonu, bırakma hedefi)',
1363
+ 'allday-<yyyy-MM-dd> (tüm gün hücresi, bırakma hedefi)',
1364
+ 'slot-<yyyy-MM-dd>T<HH> (saat dilimi, bırakma hedefi)'
1365
+ ],
1366
+ daterangepicker: [
1367
+ 'start (başlangıç tarihi kutusu, valueFrom)',
1368
+ 'end (bitiş tarihi kutusu, valueTo)'
1369
+ ],
1370
+ datetimerangepicker: [
1371
+ 'start (başlangıç tarihi kutusu, valueFrom)',
1372
+ 'end (bitiş tarihi kutusu, valueTo)'
1026
1373
  ]
1027
1374
  };
1028
1375
  /** Hedefteki `__` ayracından sonrası bir iç roldür; gateway bulunamayan hedefte listeyi basar. */