@appaflytech/zeyrek-ai-mcp 0.0.36 → 0.0.37

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 (210) hide show
  1. package/.env.example +15 -0
  2. package/README.md +5 -5
  3. package/dist/config.js +37 -0
  4. package/dist/index.js +2 -0
  5. package/dist/knowledge/access.js +802 -0
  6. package/dist/knowledge/backendConstraints.js +18 -1
  7. package/dist/knowledge/case.js +41 -0
  8. package/dist/knowledge/componentCatalog.js +655 -424
  9. package/dist/knowledge/componentEvents.js +140 -23
  10. package/dist/knowledge/connectDataBind.js +843 -0
  11. package/dist/knowledge/connectDataDefinition.js +344 -0
  12. package/dist/knowledge/connectDataExecute.js +93 -0
  13. package/dist/knowledge/connectDataRules.js +128 -0
  14. package/dist/knowledge/decision.js +121 -0
  15. package/dist/knowledge/expressionPrelude.js +59 -0
  16. package/dist/knowledge/layoutSummary.js +140 -2
  17. package/dist/knowledge/microserviceParameters.js +58 -0
  18. package/dist/knowledge/mining.js +94 -0
  19. package/dist/knowledge/mobileComponentCatalog.js +864 -0
  20. package/dist/knowledge/mobileComponentEvents.js +239 -0
  21. package/dist/knowledge/mobileStore.js +321 -0
  22. package/dist/knowledge/normalize.js +235 -84
  23. package/dist/knowledge/outlines.js +36 -0
  24. package/dist/knowledge/platform/lint.js +385 -0
  25. package/dist/knowledge/platform/mobile.js +142 -0
  26. package/dist/knowledge/platform/mobileLayoutLint.js +324 -0
  27. package/dist/knowledge/platform/mobileRules.js +231 -0
  28. package/dist/knowledge/platform/mobileSpacing.js +82 -0
  29. package/dist/knowledge/platform/mobileTabs.js +108 -0
  30. package/dist/knowledge/platform/nativeBoxModel.js +44 -0
  31. package/dist/knowledge/platform/profile.js +25 -0
  32. package/dist/knowledge/platform/resolve.js +122 -0
  33. package/dist/knowledge/platform/web.js +39 -0
  34. package/dist/knowledge/policy.js +18 -4
  35. package/dist/knowledge/process.js +510 -0
  36. package/dist/knowledge/reservedTables.js +79 -0
  37. package/dist/knowledge/rowFilter.js +43 -0
  38. package/dist/knowledge/rules.js +423 -37
  39. package/dist/knowledge/schemaGuard.js +11 -0
  40. package/dist/knowledge/styleResolve.js +53 -19
  41. package/dist/knowledge/styleResolveNative.js +527 -0
  42. package/dist/knowledge/themeResolve.js +4 -4
  43. package/dist/knowledge/themeSchema.js +1 -2
  44. package/dist/observability/trace.js +6 -3
  45. package/dist/platform/argumentAliases.js +128 -0
  46. package/dist/platform/bodyFile.js +103 -0
  47. package/dist/platform/capture/actions.js +398 -0
  48. package/dist/platform/capture/browser.js +1 -0
  49. package/dist/platform/capture/capture.js +683 -0
  50. package/dist/platform/capture/console-log.js +122 -0
  51. package/dist/platform/capture/index.js +11 -0
  52. package/dist/platform/capture/readiness.js +103 -0
  53. package/dist/platform/capture/summary.js +77 -0
  54. package/dist/platform/capture/target.js +5 -0
  55. package/dist/platform/capture/targets/studio-mobile.js +15 -0
  56. package/dist/platform/capture/targets/studio-web.js +5 -0
  57. package/dist/platform/diagnostics.js +10 -4
  58. package/dist/platform/domSummary.js +1 -1
  59. package/dist/platform/errors.js +163 -10
  60. package/dist/platform/http.js +29 -8
  61. package/dist/platform/impersonation.js +45 -0
  62. package/dist/platform/jsonArray.js +24 -0
  63. package/dist/platform/responses.js +39 -5
  64. package/dist/platform/schemaReadMemory.js +60 -0
  65. package/dist/platform/secrets.js +19 -1
  66. package/dist/platform/strictArguments.js +68 -12
  67. package/dist/platform/tokenVault.js +187 -4
  68. package/dist/resources/examples/bpm-gorev-kontrol.json +294 -0
  69. package/dist/resources/examples/bpm-iso-dokuman.json +228 -0
  70. package/dist/resources/examples/bpm-satinalma.json +376 -0
  71. package/dist/resources/examples/connect-data-convert-verify.json +107 -0
  72. package/dist/resources/examples/connect-data-dropdown-roles.json +66 -0
  73. package/dist/resources/examples/connect-data-edit-m2m.json +73 -0
  74. package/dist/resources/examples/connect-data-query-params.json +50 -0
  75. package/dist/resources/examples/connect-data-table-entity.json +147 -0
  76. package/dist/resources/examples/connect-data-workflow-microservice.json +65 -0
  77. package/dist/resources/examples/middleware-authenticate.json +1 -1
  78. package/dist/resources/examples/mobile-app-shell-drawer.json +244 -0
  79. package/dist/resources/examples/mobile-app-shell-stack.json +157 -0
  80. package/dist/resources/examples/mobile-app-shell-tab.json +208 -0
  81. package/dist/resources/examples/mobile-form-screen.json +365 -0
  82. package/dist/resources/examples/mobile-list-detail-form.json +703 -0
  83. package/dist/resources/examples/page-detail-profile.json +2 -1
  84. package/dist/resources/examples/page-dynamic-form.json +3 -2
  85. package/dist/resources/examples/page-flex-sections.json +1 -1
  86. package/dist/resources/examples/page-html-embed.json +1 -1
  87. package/dist/resources/examples/workflow-basic.json +8 -2
  88. package/dist/resources/guides/access.md +810 -0
  89. package/dist/resources/guides/bpm.md +691 -0
  90. package/dist/resources/guides/case.md +153 -0
  91. package/dist/resources/guides/component.md +93 -6
  92. package/dist/resources/guides/decision.md +185 -0
  93. package/dist/resources/guides/entity.md +50 -8
  94. package/dist/resources/guides/expressions.md +14 -5
  95. package/dist/resources/guides/functions.md +1 -1
  96. package/dist/resources/guides/getting-started.md +38 -1
  97. package/dist/resources/guides/layout.md +11 -7
  98. package/dist/resources/guides/merge.md +37 -3
  99. package/dist/resources/guides/microservice.md +87 -2
  100. package/dist/resources/guides/middleware.md +68 -4
  101. package/dist/resources/guides/mobile-layout.md +193 -0
  102. package/dist/resources/guides/mobile-publish.md +124 -0
  103. package/dist/resources/guides/mobile.md +549 -0
  104. package/dist/resources/guides/page.md +463 -83
  105. package/dist/resources/guides/theme.md +8 -3
  106. package/dist/resources/guides/translation.md +1 -1
  107. package/dist/resources/guides/workflow.md +58 -1
  108. package/dist/resources/read.js +41 -0
  109. package/dist/resources/rules.js +11 -5
  110. package/dist/resources/schema-fingerprint.json +7 -5
  111. package/dist/resources/schemas/AccessExplanationDto.json +144 -0
  112. package/dist/resources/schemas/AccessMatrixDto.json +170 -0
  113. package/dist/resources/schemas/AccessPermissionDto.json +57 -0
  114. package/dist/resources/schemas/AccessPolicyDto.json +223 -0
  115. package/dist/resources/schemas/AccessResourceDto.json +86 -0
  116. package/dist/resources/schemas/AppSessionDto.json +53 -0
  117. package/dist/resources/schemas/ConnectDataDescribeDto.json +344 -0
  118. package/dist/resources/schemas/ConnectDataRequestModel.json +202 -0
  119. package/dist/resources/schemas/ConnectDataResultDto.json +421 -0
  120. package/dist/resources/schemas/ConnectorCredentialDto.json +70 -0
  121. package/dist/resources/schemas/ConvertConnectDataToMicroserviceCommand.json +37 -0
  122. package/dist/resources/schemas/CreateAccessPolicyCommand.json +209 -0
  123. package/dist/resources/schemas/CreateDecisionCommand.json +221 -0
  124. package/dist/resources/schemas/CreateEntityCommand.json +118 -0
  125. package/dist/resources/schemas/CreateMicroserviceCommand.json +13 -1
  126. package/dist/resources/schemas/CreateProcessDefinitionCommand.json +1337 -0
  127. package/dist/resources/schemas/CreateQueryCommand.json +4 -0
  128. package/dist/resources/schemas/CreateWorkflowCommand.json +146 -1
  129. package/dist/resources/schemas/DataJobDto.json +6 -1
  130. package/dist/resources/schemas/DecisionDto.json +302 -0
  131. package/dist/resources/schemas/DetachConnectDataMicroserviceCommand.json +28 -0
  132. package/dist/resources/schemas/ExplainAccessQuery.json +33 -0
  133. package/dist/resources/schemas/GenerateProcessDocumentCommand.json +116 -0
  134. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +24 -1
  135. package/dist/resources/schemas/MicroserviceDto.json +15 -3
  136. package/dist/resources/schemas/OrganizationProjectDto.json +335 -0
  137. package/dist/resources/schemas/OrganizationSchemaDto.json +196 -0
  138. package/dist/resources/schemas/OrganizationSchemaVersionDto.json +207 -0
  139. package/dist/resources/schemas/PatchProcessDefinitionCommand.json +76 -0
  140. package/dist/resources/schemas/PreviewMicroserviceCommand.json +10 -1
  141. package/dist/resources/schemas/PreviewWorkflowCommand.json +25 -1
  142. package/dist/resources/schemas/ProcessDefinitionDto.json +1480 -0
  143. package/dist/resources/schemas/ProcessSimulationDto.json +96 -0
  144. package/dist/resources/schemas/SaveConnectorCredentialCommand.json +90 -0
  145. package/dist/resources/schemas/SaveProcessEventSourceCommand.json +61 -0
  146. package/dist/resources/schemas/SaveProcessMailSourceCommand.json +89 -0
  147. package/dist/resources/schemas/SignProcessTaskCommand.json +73 -0
  148. package/dist/resources/schemas/SimulateProcessDefinitionQuery.json +92 -0
  149. package/dist/resources/schemas/StartMobileBuildCommand.json +54 -0
  150. package/dist/resources/schemas/StepDto.json +25 -1
  151. package/dist/resources/schemas/UpdateAccessPolicyCommand.json +209 -0
  152. package/dist/resources/schemas/UpdateDecisionCommand.json +216 -0
  153. package/dist/resources/schemas/UpdateEntityCommand.json +118 -0
  154. package/dist/resources/schemas/UpdateMicroserviceCommand.json +13 -1
  155. package/dist/resources/schemas/UpdateProcessDefinitionCommand.json +1357 -0
  156. package/dist/resources/schemas/UpdateQueryCommand.json +4 -0
  157. package/dist/resources/schemas/UpdateViewCommand.json +0 -2
  158. package/dist/resources/schemas/UpdateWorkflowCommand.json +146 -1
  159. package/dist/resources/schemas/UpsertMobileStoreSettingsCommand.json +274 -0
  160. package/dist/resources/schemas/ValidateProcessDefinitionQuery.json +1339 -0
  161. package/dist/server.js +31 -1
  162. package/dist/tools/access.js +369 -2
  163. package/dist/tools/accessOperations.js +135 -0
  164. package/dist/tools/accessPolicies.js +170 -0
  165. package/dist/tools/accessRuntime.js +203 -0
  166. package/dist/tools/applications.js +60 -3
  167. package/dist/tools/bpm.js +343 -0
  168. package/dist/tools/bpmGovernance.js +266 -0
  169. package/dist/tools/bpmOperations.js +230 -0
  170. package/dist/tools/bpmReporting.js +154 -0
  171. package/dist/tools/bpmRouting.js +150 -0
  172. package/dist/tools/bpmRuntime.js +396 -0
  173. package/dist/tools/case.js +178 -0
  174. package/dist/tools/caseRuntime.js +89 -0
  175. package/dist/tools/common.js +10 -1
  176. package/dist/tools/components.js +118 -14
  177. package/dist/tools/connectData.js +450 -0
  178. package/dist/tools/connectors.js +193 -0
  179. package/dist/tools/datasources.js +3 -3
  180. package/dist/tools/decisions.js +206 -0
  181. package/dist/tools/dependencies.js +1 -1
  182. package/dist/tools/deployments.js +38 -3
  183. package/dist/tools/designSchemaPatch.js +34 -9
  184. package/dist/tools/dtos.js +36 -5
  185. package/dist/tools/entities.js +79 -12
  186. package/dist/tools/externalComponents.js +26 -5
  187. package/dist/tools/flows.js +119 -17
  188. package/dist/tools/folders.js +1 -1
  189. package/dist/tools/imports.js +5 -2
  190. package/dist/tools/layouts.js +50 -17
  191. package/dist/tools/merges.js +2 -2
  192. package/dist/tools/microservices.js +77 -25
  193. package/dist/tools/mobile.js +280 -0
  194. package/dist/tools/mobileStore.js +556 -0
  195. package/dist/tools/modules.js +48 -0
  196. package/dist/tools/organizationStructure.js +137 -0
  197. package/dist/tools/pages.js +465 -98
  198. package/dist/tools/platformInfo.js +28 -8
  199. package/dist/tools/profileWrite.js +92 -0
  200. package/dist/tools/projects.js +71 -9
  201. package/dist/tools/rows.js +69 -13
  202. package/dist/tools/schemaOps.js +61 -1
  203. package/dist/tools/screenWrite.js +36 -7
  204. package/dist/tools/screens.js +95 -5
  205. package/dist/tools/templates.js +26 -1
  206. package/dist/tools/translations.js +1 -1
  207. package/dist/tools/variables.js +11 -5
  208. package/dist/tools/workflows.js +10 -5
  209. package/package.json +2 -2
  210. package/dist/platform/screenshot.js +0 -1162
@@ -18,7 +18,7 @@
18
18
  export const TABLE_COLUMN_TYPE_NOTE = "KOLON TİPİ SÖZLÜĞÜ (bekler → çizer). " +
19
19
  "text/long-text: metin → düz metin (long-text hücreye sığdırıp kırpar). " +
20
20
  "number/time: sayı ya da metin → olduğu gibi. " +
21
- "money: sayı → para biçimi, ayıraçlar dile göre (tr '₺1.250,00', en '₺1,250.00'); para birimi kolonun currency alanından gelir (ISO 4217: 'USD' → en '$1,250.00', tr '$1.250,00'), boş ya da geçersiz değer TRY'ye düşer. " +
21
+ "money: sayı → TRY para biçimi, ayıraçlar dile göre (tr '₺1.250,00', en '₺1,250.00'). " +
22
22
  "pertance: SAYI → yüzde metni; 0..1 arası değer ORAN sayılıp 100'le çarpılır, 1'den büyük değer zaten yüzdedir (tam 1 = %100). Çubuk ÇİZMEZ — çubuk için progress. " +
23
23
  "progress: ham sayı → hücrede oransal çubuk (value/max, max varsayılanı 100); progressVariant/progressLabel/progressColor/thresholds ile ayarlanır. " +
24
24
  "date/datetime: ISO metni ya da Date → dile göre biçimli tarih (locale prop'undan). " +
@@ -31,10 +31,22 @@ export const TABLE_COLUMN_TYPE_NOTE = "KOLON TİPİ SÖZLÜĞÜ (bekler → çiz
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.";
34
+ /**
35
+ * KORUMALI DEĞER (f-31, kompleks proje) — table · datatable · detailview · text ortak davranışı.
36
+ * Kaynak: `packages/ng-apps-ui/src/shared/protected-value.functions.ts`,
37
+ * `shared/components/protected-value/ProtectedValue.svelte`, `packages/ng-apps-flow/src/access/`.
38
+ */
39
+ export const PROTECTED_VALUE_NOTE = "KORUMALI DEĞER (kompleks proje, f-31): table-source uçtan gelen satır `__protected: { <alanSlug>: 'masked' | 'plain' }` metası taşır; hidden alan satırda HİÇ YOKTUR. " +
40
+ "'masked' alan kilit ikonuyla MASKE METNİNİ ('*******8901') çizer; satırın kimliği bulunursa ve runtime erişim özeti yüklüyse yanında 'Göster' çıkar: gerekçe diyaloğu → POST /{project}/runtime/{app}/reveal → değer 30 SANİYE görünür, sonra kendiliğinden yeniden maskelenir. Değeri BOŞ maskeli hücrede kilit kalır, 'Göster' ÇIKMAZ. " +
41
+ "Tasarımcı kanvasında 'View as user' ile seçilen kullanıcının özeti de yüklenir: 'Göster' o kullanıcıya sunulacağı yerde ETKİSİZ çizilir (tıklama bileşeni seçer, diyalog açılmaz; gerçek açma önizlemede); kullanıcı seçili değilken tasarımcının project.data.reveal izni karar verir. " +
42
+ "'Göster' kuralı moda göre: 'off' (basit proje HEP 'off') ya da özet yüklenemediyse ÇIKMAZ (backend her reveal'i 403 AccessRevealDeniedException ile reddeder); 'shadow'da ÇIKAR (özet her şeyi açık döner, backend reveal'i yine denetler — yetkisiz kullanıcı ret mesajını görür); 'enforce'ta yalnız entity'nin actions'ında reveal varsa. Page.can('reveal', …) bu kuralın yerini tutmaz: 'enforce' dışında hep true'dur. " +
43
+ "Açılan değer prop'a, akışa, olaya, yerel depoya ya da URL'e YAZILMAZ; olay yayılmaz, akış bağlanamaz. 403/404/422/429 mesajları bileşenin dil sözlüğündendir. 'plain' alan düz değerdir, normal çizilir. " +
44
+ "Maskeli değeri forma isMasked'sız BAĞLAMA: güncelleme formunda textinput'un value'su kaydın alanına, isMasked'ı satır metasına birlikte bağlanır (textinput.propNotes.isMasked). Gizleme arayüzdür; yetki backend'de denetlenir. Izgaralarda (bağlı datatable, Studio satır listesi) maskeli hücre politika yazma izni veriyorsa KÖR ÜZERİNE YAZILIR (ADR 0007): editör boş açılır, yalnız yazılan değer gider; table bileşeninde hâlâ düzenlenmez.";
45
+ export const REVEAL_ENTITY_NOTE = "Maskeli değerin açılacağı entity: slug ('musteriler') ya da id. BOŞSA runtime erişim özetinden bulunur — satırın korumalı alanlarını okunur alan olarak taşıyan TEK entity. İki entity aynı alan adını taşıyorsa ya da mod 'shadow' iken (özet alan listesi boş) bulunamaz ve 'Göster' ÇIKMAZ; o durumda doldur. Korumasız veride etkisizdir.";
34
46
  export const STYLE_GROUP_NOTES = {
35
- surfaceStyle: "{ background, radius, borderTop, borderRight, borderBottom, borderLeft, shadow, contentOverflow(visible|hidden|auto), opacity(0–100 yüzde; 100/boş yazılmaz) }. radius: tema kademesi ('var(--ng-radius-md)'; sm/lg 'Border radius'un oranı, md temanın kendisi), tek uzunluk ('18px') YA DA dört köşe ('90px 14px 14px 14px' — sol-üst, sağ-üst, sağ-alt, sol-alt). KENARLIK YÖN BAŞINADIR: her yön kendi CSS kısayolunu taşır ('1px solid var(--ng-border-primary)'), 'none' o kenarı kapatır; eski borderWidth/borderStyle/borderColor üçlüsü EMEKLİ (yalnız hiçbir yön yazılmamışsa okunur). shadow: çok katmanlı `box-shadow` metni ('0px 2px 5px 0px rgba(0,0,0,.2), inset 8px 5px 7px 0px #000'), tema token'ı ('var(--ng-shadow-md)') ya da eski preset anahtarı (none|sm|md|lg).",
36
- typographyStyle: "{ textColor, fontFamily('var(--ng-font)' tema gövde | 'var(--ng-font-heading)' tema başlık | 'monospace' — token tema fontunu izler; SİSTEM fontları ('Georgia, serif', 'Courier New, monospace') olduğu gibi uygulanır, serbest WEB fontu (Google) ise YÜKLENMEZ: tema yüklemediği için tarayıcı yedek yazı tipine düşer), fontSize(CSS uzunluğu: '15px'|'1.1em'; çıplak sayı px sayılır), fontWeight(400|500|600|700), fontStyle(normal|italic), textDecoration(none|underline|line-through), lineHeight(TEK alan, üç yazım: oran '1.4' | yüzde '140%' | uzunluk '24px'; eski kayıtlardaki çıplak 140 yüzde sayılır), letterSpacing(CSS uzunluğu, negatif meşru: '-0.4px'), textAlign(left|center|right|justify|start|end — left/right FİZİKSELDİR, dir=rtl'de de aynı yöne yazar; start/end MANTIKSALDIR, yazı yönüne göre döner (LTR'de sol/sağ, RTL'de sağ/sol): çok dilli ya da ar/RTL uygulamada start/end yaz) }. Komponentin içeriğine miras kalır.",
37
- hoverStyle: "{ background, borderColor, shadow(none|sm|md|lg), lift(CSS uzunluğu: '2px' — POZİTİF değer öğeyi yukarı kaldırır, '-2px' aşağı iter), transitionMs }. Hiçbir alan dolu değilse hover bloğu ve geçiş HİÇ yazılmaz.",
47
+ surfaceStyle: "{ background, radius, borderTop, borderRight, borderBottom, borderLeft, shadow, contentOverflow(visible|hidden|auto), opacity(0–100 yüzde; 100/boş yazılmaz), rotate(derece, −360…360), scale(YÜZDE 10–500; 100 aynı boy ve varsayılan — 1.1 değil 110), translateX/translateY(px, −1000…1000) }. radius: tema kademesi ('var(--ng-radius-md)'; sm/lg 'Border radius'un oranı, md temanın kendisi), tek uzunluk ('18px') YA DA dört köşe ('90px 14px 14px 14px' — sol-üst, sağ-üst, sağ-alt, sol-alt). KENARLIK YÖN BAŞINADIR: her yön kendi CSS kısayolunu taşır ('1px solid var(--ng-border-primary)'), 'none' o kenarı kapatır; eski borderWidth/borderStyle/borderColor üçlüsü EMEKLİ (yalnız hiçbir yön yazılmamışsa okunur). shadow: çok katmanlı `box-shadow` metni ('0px 2px 5px 0px rgba(0,0,0,.2), inset 8px 5px 7px 0px #000'), tema token'ı ('var(--ng-shadow-md)') ya da eski preset anahtarı (none|sm|md|lg). DÖNDÜR/ÖLÇEKLE/KAYDIR (ADR 0005): dört alan TEK transform'a derlenir — sıra kaydır → döndür → ölçekle, köken merkez, düğüm çocuklarıyla döner; nötr değer (0°, 100, 0 px) hiçbir şey yazmaz. Değer BİRİMSİZ sayıdır ('15deg', '20px', '110%' yazılmaz) ve aralık dışı yazılmaz — mobilde ikisi de nativeStyle.warnings'e düşer. Transform'lu düğümün İÇİNDEKİ portal açmayan açılır menü/liste düğümün kutusuna hapsolur. hoverStyle.lift düğümün transform'unu ezmez, önüne eklenir. Katmanlar (modal, drawer, popover) ve uygulama kabukları (layout, layout-region, layout-shell, auth-layout, qm-content, qm-sidebar) bu dört alanı TAŞIMAZ: transform'lu ata position:fixed katmanı ekrandan koparır. Döndürmeyi serbest style.transform'a yazma — mobil yalnız tipli alanı çizer (MOB-002).",
48
+ typographyStyle: "{ textColor, fontFamily('var(--ng-font)' tema gövde | 'var(--ng-font-heading)' tema başlık | 'monospace' — token tema fontunu izler; serbest Google fontu yazma, tema yüklemez ve sessizce düşer), fontSize(CSS uzunluğu: '15px'|'1.1em'; çıplak sayı px sayılır), fontWeight(400|500|600|700), fontStyle(normal|italic), textDecoration(none|underline|line-through), lineHeight(TEK alan, üç yazım: oran '1.4' | yüzde '140%' | uzunluk '24px'; eski kayıtlardaki çıplak 140 yüzde sayılır), letterSpacing(CSS uzunluğu, negatif meşru: '-0.4px'), textAlign(left|center|right|justify) }. Komponentin içeriğine miras kalır.",
49
+ hoverStyle: "{ background, borderColor, shadow(none|sm|md|lg), lift(CSS uzunluğu: '2px'), transitionMs }. Hiçbir alan dolu değilse hover bloğu ve geçiş HİÇ yazılmaz.",
38
50
  colorTokens: "RENK ALANLARI (background, textColor, borderColor, hover.background/borderColor) hex kadar tema token'ı da alır: 'var(--ng-accent-primary)', 'var(--ng-status-error)', 'var(--ng-background-inverse)'. Token yazılan alan tema değişince izler, hex yazılan kopar; tasarım sistemi renklerinde ÖNCE token'ı tercih et (studio panelinde aynı seçim tema chip'iyle yapılır).",
39
51
  styleEscape: "Kaçış kapısı ve SON SÖZ: tipli grupların/builder'ın karşılamadığı her CSS kararı buraya yazılır (custom properties alanının veri kanalı budur). Önce tipli grupları dene; grup alanı yoksa style'a yaz. Efektif sonucu görmek için page_runtime_get(resolveStyles:true)."
40
52
  };
@@ -67,25 +79,19 @@ export const componentKnowledge = {
67
79
  "Script'ler flow ifade bağlamına (Page, Steps, komponent adları) erişemez; köprü yalnız fireEvent (dışarı) ve context (içeri).",
68
80
  "Şema olayı yalnız mount'tur; aksiyonlar set_event ile DEĞİL kendi flow prop'uyla bağlanır (type:'flow', ref:<flowId>).",
69
81
  'isLoading açıkken içeriğin YERİNE nabız atan bir iskelet bloğu çizilir ve satır içi script’ler çalışmaz; kapanınca aynı içerik için baştan çalışırlar. mount + setter ile veri çeken ekranda "veri gelene kadar ne görünsün" cevabı budur.',
70
- 'Temizlenmiş prop kırmaz: content null/undefined olduğunda komponent boş çizer, sayı ve boolean metne çevrilip basılır (0 ve false dahil), context nesne değilse boş sözlük sayılır — hata atmaz.',
71
- "content HİÇ yazılmamışsa (props: {}) düğüm BOŞ çizilir: kayıttaki <p>HTML Content</p> varsayılanı yalnız Studio'da tuvale bırakılan düğüme yazılır. MCP ile eklerken content'i her zaman yaz.",
72
- "KUTU İÇERİĞİ KIRPMAZ: sabit yükseklikli düğümde uzun bir tablo ya da 300 karakterlik boşluksuz kelime kutudan taşar ve komşuyu örter (overflow: visible). Kaydırmak ya da kesmek için surfaceStyle.contentOverflow: 'auto' | 'hidden' yaz (ikisi de ölçüldü).",
73
- "Yazı rengi: markup renk yazmıyorsa tema kökünün metin rengini (--ng-text-primary) miras alır ve koyu temada da okunur; bir kabın (box/container) typographyStyle.textColor'ı bu mirası değiştirir, style'daki color (kök ya da iç seçici) her zaman kazanır. Açık temada varsayılan metin #262626'dır.",
74
- "Çıplak <p>, başlık, bağlantı ve düğme etiketleri studio'nun Carbon global stilini taşır: <p> kökün font-size/line-height'ını MİRAS ALMAZ (16px/1.5, kök 19px/1.7 olsa bile). Kök boyunu p'ye indirmek için style'a `& p { font-size: inherit; line-height: inherit }` yaz.",
75
- "@keyframes adları sayfa genelinde ORTAKTIR (kapsamlanmaz): iki html düğümü aynı adı kullanırsa çakışır — adı düğüme özgü yap (pulse-hero gibi).",
76
- "Tekrarlayıcı (repeater) içindeki html'e satır verisi context: { type: 'code', ref: '{{ item }}' } ile geçer; content'te {{ alan }} ile okunur (satırda iç içe nesne varsa o alanı bir seviye düzleştir: iç içe nesneler bileşene boş gelir, CQ-276). context'in iç değerlerine { type: 'translation', ref } da yazılabilir; dil değişince yeniden çözülür."
82
+ 'Temizlenmiş prop kırmaz: content boş ya da metin olmayan bir değer (sayı, null) olduğunda komponent boş çizer, context nesne değilse boş sözlük sayılır — hata atmaz.'
77
83
  ],
78
84
  propNotes: {
79
85
  surfaceStyle: NODE_SURFACE_NOTE,
80
- content: "Ham HTML ya da Mustache şablonu. type:'code' + {{ }} ifadesiyle dinamik de beslenebilir. HİÇ yazılmamışsa düğüm boş çizilir — her zaman yaz. {{ ad }} HTML'i kaçışlar, {{{ ad }}} kaçışsız basar (içerik güvenilir değilse üçlüyü kullanma).",
86
+ content: "Ham HTML ya da Mustache şablonu. type:'code' + {{ }} ifadesiyle dinamik de beslenebilir.",
81
87
  context: 'Mustache değişken sözlüğü (nesne). Setter ile yazmak içeriği yeniden render eder.',
82
- style: "emotion css() bloğu, DÜZ CSS METNİ olarak yazılır: iç seçiciler, &:hover, :focus-visible, ::first-letter, @media ve @keyframes çalışır; üretilen sınıf komponente scope'ludur (@keyframes adı hariç). page_schema_patch'in 'style NESNE olmalı' (PAGE-014) uyarısı html için GEÇERSİZDİR. Nesne biçiminde PascalCase Webkit* anahtarı kayıtta sessizce düşer (silentlyDropped; 2026-10-04'te ölçüldü); tarayıcı öneki gerekiyorsa düz CSS metni yaz.",
88
+ style: "emotion css() bloğu: iç seçiciler ve &:hover çalışır, üretilen sınıf komponente scope'ludur.",
83
89
  actions: "[{ key, text, flow }] — key fireEvent adıdır (text'ten snake üretilir), flow çalıştırılacak akıştır.",
84
90
  isLoading: 'Yükleme iskeleti anahtarı. Geri YAZILMAZ (komponentin change olayı yok), yalnız akış sürer: fetch öncesi setter ile aç, veriyi context’e yazan setter’dan sonra kapat.'
85
91
  }
86
92
  },
87
93
  table: {
88
- 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.',
94
+ summary: 'LEGACY (2026-09-18): paletten kaldırıldı, yeni ekranlarda datatable kullan; mevcut sayfalardaki table çizilmeye devam eder. 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.',
89
95
  behavior: [
90
96
  '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.',
91
97
  '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.',
@@ -95,11 +101,13 @@ export const componentKnowledge = {
95
101
  "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).",
96
102
  "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).",
97
103
  "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.",
98
- "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."
104
+ "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.",
105
+ PROTECTED_VALUE_NOTE + " Tabloda: maskeli hücre DÜZENLENMEZ (çift tık/Enter editör açmaz) ve hover ipucu vermez; satır kimliği `id`, yoksa isKey kolonu."
99
106
  ],
100
107
  propNotes: {
101
108
  surfaceStyle: NODE_SURFACE_NOTE,
102
109
  rows: 'Satır dizisi; mount/filter/sort/pagination akışlarının setter adımıyla doldurulur.',
110
+ revealEntity: REVEAL_ENTITY_NOTE,
103
111
  appearance: "YÜKSEKLİK/GENİŞLİK ELLE HESAPLANMAZ (ölçüldü 2026-09-05, f11-repro). heightType:'auto' tablo içeriği kadar uzar — satır sayısı × satır yüksekliği hesabı gerekmez. heightType:'fixed' gövdeyi KAYDIRIR (grid-container overflow:auto), satır kaybolmaz; kare'de görünmeyen satır kırpılmış değil kaydırılmıştır. KOLONLAR KARTI TAŞIRMAZ: genişlik toplamı kabı aşarsa tablo kendi içinde YATAY kaydırır; kabın scrollWidth'i değişmez. KAYDIRMA ÇUBUKLARI VARSAYILAN GİZLİDİR (kaydırma Shift+tekerlek, trackpad, dokunma ve klavyeyle çalışır) ve sağda gizli kolon olduğunu gösteren tek işaret sabitlenmiş aksiyon kolonunun (actionsPinned) sol çizgisidir — kolonları sağa taşan tabloda kullanıcının görmesi için showScrollbar:true yaz. Toplam kaptan KÜÇÜKSE kolonlar orantılı büyütülüp kap tam doldurulur (stretchColumns) — bu yüzden 'kolonu daraltayım da sığsın' yamalarına gerek yok. Tek gerçek tuzak yerleşim tarafındadır: FLEX ebeveynde blocks[].size yok sayılır, ölçü appearance'tan gelir; IZGARA ebeveynde tersi (gateway PAGE-019 ile uyarır).",
104
112
  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.",
105
113
  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.",
@@ -122,17 +130,53 @@ export const componentKnowledge = {
122
130
  "Liste→form geçişi satır AKSİYONUYLA kurulur: actions:[{ text, kind, icon, flow:{ type:'flow', ref:<flowId> } }]. doubleClick/select bağlamak 200 döner ama bağ ölüdür (gateway PAGE-008 keser).",
123
131
  "Aksiyona tıklanınca komponent ÖNCE tıklanan satırı kendi selectedRow prop'una yazar, SONRA akışı çalıştırır (Table.svelte:72 setNode + onEmit) — akışta satır '<elementId>.selectedRow.<alan>' ile okunur. selectedRow katalogda hidden'dır; setter ile yazılmaz, komponent doldurur.",
124
132
  "style prop'u 2026-08-27'de EKLENDİ: parçalar &__toolbar · &__title · &__head · &__th · &__body · &__row · &__td. table'ın aksine tek yazım kuralı vardır — hepsi designerCss'ten geçer, yani camelCase yazılır ve iç seçici alır. (Bu tarihten önce datatable stillendirilemiyordu; eski notlar 'style YOKTUR' diyorsa güncel değildir.)",
125
- "Satır bazlı görünüm ezmesi (_columns / _actions) da YOKTUR — o table'a özgüdür. Renklendirme burada yalnız kolonun colorMap/autoColor sözlüğüyle, yani satırdan bağımsız kurulur."
126
- ],
127
- propNotes: {
128
- surfaceStyle: NODE_SURFACE_NOTE,
129
- columns: "Kolon tipleri: text · number · date · datetime · time · switch · tag · email · url · link · image · file · progress. Her tipin ne beklediği/ne çizdiği table'ın kolon sözlüğüyle AYNIDIR (component_get('table') → knowledge.propNotes.columns), İKİ İSTİSNA dışında: burada image/file düz URL kabul etmez (aşağıdaki image notu) ve renk satır bazında değil colorMap ile kurulur. PROGRESS (2026-08-27) hücrenin içine çubuk ya da halka çizer: progressVariant bar|circle · max (varsayılan 100) · progressLabel none|percent|fraction|value · progressColor + customProgressColor · thresholds [{from,color}] (yüzdeyi geçmeyen en yüksek eşik kazanır) · captionField BAŞKA bir satır alanının metnini çubuğun ÜSTÜNE yazar, yani ad ve çubuk tek hücrede durur. Sıralama/dışa aktarım ham sayıyı görür, çizimi değil.",
133
+ "Satır bazlı _columns görünüm ezmesi YOKTUR — o table'a özgüdür; renklendirme yalnız kolonun colorMap/autoColor sözlüğüyle, satırdan bağımsız kurulur. Aksiyon ise satıra göre değişebilir: rows[i]._actions[<aksiyon index>] = { isHidden, isDisabled, text … } o satırda aksiyonun üstüne biner (rowActions).",
134
+ "SATIR KOŞULLU AKSİYON (2026-09-25): actions[i].isHidden / isDisabled bir kod ifadesi olabilir — { type:'code', ref:'{{ !item.isCustomizable }}' }; tablo onu HER SATIR için item = o satır ile çözer (machine.evaluateExpression). Connect Data'ya bağlı tabloda satırlar _actions taşıyamadığı için tek yol budur. Sıra: tanım → ifade → satırın _actions'ı. Sütun çizilen satırlardan hesaplanır: aksiyon en az bir satırda görünüyorsa sayılır, her satırda gizliyse (koşul ya da _actions) sütun hiç çizilmez (2026-10-02); satır yokken koşullu aksiyon aday sayılır. Kanvasta ifade çözülmez, aksiyon her satırda görünür.",
135
+ "HÜCRE ŞABLONU (2026-09-21): bir kolonun hücresi serbest tasarlanabilir — tablonun ÇOCUĞU olarak bir datatable-cell düğümü (props.column = o kolonun name'i) eklenir, içine bırakılan bileşenler o kolonda her satırda çizilir ve satırı item olarak okur ({{ item.title }}). Tablonun başka türde çocuğu olmaz. Ayrıntı: datatable-cell kaydı.",
136
+ "keepSampleData (gizli switch, 2026-09-21) bir TASARIMCI kararıdır: true iken studio kanvasında bağlı olmayan tablonun üstündeki 'Örnek veri gösteriliyor · Connect data' çağrısı ve perdesi çizilmez. Runtime okumaz, veriyi etkilemez; örnek satırlarla bırakılacak bir tabloda true yazılabilir, rows bağlanınca anlamı kalmaz. Kanvasta tablo kendi içinde yatay kayar ve kolon başlığı tıklaması o kolonun panelini açar (designer.interactive) — bu da yalnız studio davranışıdır.",
137
+ "KOLON GENİŞLİĞİ (2026-09-22): başlığın sağ kenarı sürüklenerek (ya da tutamaç odaktayken ←/→, 10px) kolon daraltılıp genişletilir; en dar 60px. Kanvasta bu kolonun columns[i].width değerini yazar — paneldeki Width alanıyla aynı değer, tek geri alma adımı. Runtime'da tanıma YAZILMAZ: ziyaretçinin seçimi tarayıcıda kolon tercihiyle (localStorage ZY_DataTableColumns_<elementId>.widths) saklanır, kolon menüsündeki Sıfırla onu da siler. Genişliği kalıcı vermek için width yaz.",
138
+ PROTECTED_VALUE_NOTE + " Datatable'da satır kimliği keyField alanıdır (varsayılan `id`; bağlı tabloda runtime kaynağın birincil anahtarını yazar, isKey yok); maskeli hücre biçimlendirilmez, kolon tipinden bağımsız kilitli maske çizilir. KÖR ÜZERİNE YAZMA (2026-09-26, ADR 0007): BAĞLI tabloda kolonun capability.canWrite'ı açıksa (politika canWrite ∧ tanımın editable listesi — maskeli okumak yazmayı kapatmaz) maskeli hücre satır/hücre düzenlemesinde BOŞ editörle açılır, yer tutucu 'Değiştirmek için yeni değer girin'; yalnız YAZILAN değer taslağa ve update isteğine girer, boş bırakılan ya da yazılıp silinen maske hiç gitmez. Maskeli hücre hücre seçimine girmez (yazılan değer başka satırlara yayılmaz) ve toplu düzenleme maskeli kolonu SUNMAZ. Bağlı OLMAYAN tabloda maskeli hücre düzenlenmez (değişiklik elle yazılan save akışına gider). Eski değeri görerek düzeltmek için önce 'Göster' (açılan değer editöre ön doldurulmaz).",
139
+ "DÜZENLEME (2026-09-17, f-21; satır bazlı): editMode none|row|batch. Satır ✏ düğmesi ya da çift tıkla düzenlemeye açılır ve YAZILABİLİR HÜCRELERİNİN HEPSİ aynı anda editör olur (tek hücre editörü yok); ilişki hücresi lookup panelini açar. Enter satırı bitirir, Escape vazgeçer. row kipinde satır sonundaki ✓ o satırı kaydeder (hatasızsa satır kapanır), batch'te ✓ yalnız satırı kapatır ve üst çubukta 'N değişiklik · Kaydet · Vazgeç' kalır; kapanmış ama kaydedilmemiş satırda ✓/✕ görünür. canAddRow yeni satırı açar (newRowDefaults ile dolu, düzenlemede açılır; üstteki '+ Satır' düğmesi 2026-09-18'de KALKTI — yerine addRowButton ile satırların altında/üstünde mavi '+ Satır ekle' satırı ve addRowShortcut açıkken tablo odaktayken Ctrl/Cmd+Enter; buton alttayken yeni satır da en alta eklenir), canDeleteRow satır sonunda onaylı Sil. Kaydet 'save' olayı yayar ve changeset'i self.changeset'e yazar. BAĞLI TABLODA (rows connectData, behavior.edit açık) editMode/canEditRow/canAddRow/canDeleteRow/newRowDefaults/keyField'ı runtime tanım ∧ yazma kabiliyetinden YAZAR, yazmayı connect-data ucuna kendisi yapar (create → update → delete; hatalar self.rowErrors, satır taslakta kalır) — save için AKIŞ YAZILMAZ. Hücre yalnız capability.canWrite (policy ∧ editable) açıksa düzenlenir; bağlı olmayan tabloda kolonun editable işareti (columns[].editable). image/file/progress/link hücresi, bağlı olmayan tablonun maskeli hücresi ve anahtarı (keyField; bağlı tabloda kaynağın birincil anahtarı, yoksa id) olmayan ya da sayfada tekrar eden satır düzenlenmez/silinmez. Kaydı süren satırın ✓/Sil/Kaydet düğmesi pasiftir (çift kayıt yok); atomic tanımda toplu yazmada düşen satırın komşuları 'Kaydedilmedi' işaretiyle taslakta kalır (hiçbiri yazılmadı; writeMode partial'da komşular yazılır, yalnız düşen satır kırmızı kalır); ✕ satırın hatasını da siler. Hücre seçimi (selectedCells, cellSelectionChange) yalnız düzenleme kipinde. Kanvasta düzenleme pasiftir. GÜNCELLEME (2026-09-18): tasarımcıda batch seçeneğinin etiketi 'Cell'dir (değer batch kalır). Yazılabilir ilişki hücresi TEK tıkta yalnız seçilir; ÇİFT tık düzenler: row kipinde satırın bütün yazılabilir hücreleri açılır, Cell (batch) kipinde kayıtlı satırın YALNIZ çift tıklanan hücresi editör olur (Enter ya da alandan çıkmak değeri taslakta bırakıp kapatır, Escape yalnız editörü kapatır; ✏ ve yeni satır iki kipte de bütün satırı açar); ilişki hücresinde seçim paneli açılır; düzenlenen satırda ilişki hücresi bir seçici düğmedir (değer + ok). batch kipinde çift tıklanan hücre aynı kolondaki çoklu hücre seçiminin içindeyse yazılan değer seçili BÜTÜN hücrelere gider (row kipinde yalnız o satır). batch kipinde Sil onaysızdır ve satırı 'SİL' rozetiyle, üstü çizili olarak silinecek diye İŞARETLER (↶ ile geri alınır); silme kayıtta changeset.deleted'a girer. Yeni satır 'YENİ' rozeti ve yeşil zemin alır; değişen hücrede köşe işareti ve altında üstü çizili eski değer vardır. Üst çubuk KALKTI: tablonun altında 'N değişiklik · N yeni · N silinecek · N hata' özeti, 'Tümünü geri al' ve 'Değişiklikleri kaydet (N)' durur. Filtre özetinde ve filtre çubuğunda lookup'tan seçilen ilişki değeri kimliğiyle değil görünen alanıyla yazılır; filtre çubuğunda ilişki kolonu doğrudan seçim paneliyle açılır ve seçim hemen uygulanır. GÜNCELLEME (2026-09-19): editMode'a cell (hücre başına kayıt; tanımda saveMode 'cell') eklendi; tasarımcıda batch'in etiketi artık 'Batch', 'Cell' etiketi yeni cell kipidir. cell kipinde kayıtlı satırın çift tıklanan hücresi tek başına açılır ve ✓/✕ editörün kendi çerçevesinin sağ ucunda, ayraçtan sonra iki ikon düğmedir (arama kutusunun temizle düğmesi gibi) (satır ✏ düğmesi yoktur): ✓ ya da Enter yalnız o alanı hemen kaydeder (update patch'inde tek alan), ✕ ya da Escape vazgeçer; alandan çıkmak editörü kapatmaz. Aynı anda tek hücre açıktır, başka hücreye geçmek açık hücrenin kaydedilmemiş değerini atar; kayıt hata verirse hücre açık kalır ve hata altında görünür. İlişki hücresinde panel kapanınca hücre açık kalır, seçim ✓ ile yazılır. Yeni satır, Sil (onaylı) ve toplu düzenleme row kipindeki gibi hemen kaydedilir; edit kolonu yalnız canAddRow ya da canDeleteRow açıksa görünür. Çoklu hücre seçiminin içindeki hücre açılırsa (batch ve cell) değer seçili bütün hücrelere yazılır; cell kipinde ✓ hepsini tek changeset'te kaydeder, ✕ hepsinden vazgeçer. Edit kolonu (✏ 🗑) sağa yapışıktır (sticky), genişliği boştaki düğmelere göredir; ✏/🗑 hover'da görünür. Çakışan işlemler kilitlidir: toplu satır seçimi varken çift tık/✏ düzenleme açmaz, Satır ekle (ve Ctrl+Enter) gizlenir, ✏/🗑 görünmez; düzenleme açıkken satır seçim kutuları devre dışıdır ve ✏/🗑 görünmez. Escape ilişki hücresinde (lookup paneli açıkken de) düzenlemeyi kapatır.",
140
+ "LOOKUP (2026-09-17, f-23): bağlı tabloda YAZILABİLİR relation hücresi lookup panelini açar (hedef tablo op:lookup ile, arama + 'Daha fazla'), seçim yalnız düzenlenen satırda; salt okunur tabloda, editable dışı alanda ya da güncellenemeyen satırda hücre HİÇBİR ŞEY açmaz (2026-09-21 — eski gezinme paneli kaldırıldı). Panelin 'Detaylı ara…' bağlantısı tanımın lookup.mode'una göre pencere ya da sağ çekmece açar (mode yazılmamışsa pencere, 2026-09-19) ve paneldeki arama metniyle başlar: kolonlar lookup.fields (türetilmişte anahtar dışı alanlar), arama, lookup.behavior.filterable alanlarında VE koşulları, başlıktan sıralama, sayfalar; o2m/self tekil seçim ('Seç' ya da çift tık), m2m onay kutuları + 'Uygula'; 'Temizle' alan zorunluysa (describe isRequired) gizli; yazma yetkisi yoksa panel yalnız gezinme. Seçilen hedef hücreye yerel yazılır, kayıt { alan: '<id>' } / m2m ['<id>', …] olarak gider. Filtre panelinde relation kolonunun değeri 'Seç…' ile aynı panelden seçilir (in/notin çoklu), chip'te görünen ad. Hedefin görünen alanı metin (ve korumasız) ise sunucu ilişkiye contains/icontains da sunar (2026-09-21): bu işleçte değer seçilmez, YAZILIR ve hedefin görünen alanında aranır ({ field:'city', operator:'icontains', value:'ist' } → EXISTS … title ILIKE '%ist%'); gelişmiş panelde, column modundaki işleç düğmesinde ve bar hapının editöründe (işleç seçimi + kayıt seçimi ya da metin) çıkar; bar ile gelişmiş panel birlikteyken panel çubuğun ÜSTÜNDE açılır, çubuk hep tablonun hemen üstündedir. Hedef tabloyu okuyamayan (targetReadable:false) hücre gri “—” + kilit çizer ve panel açmaz. Hedefin maskeli alanı ayrıntılı aramada maske olarak (Göster ile) çizilir.",
141
+ "TOPLU (2026-09-17, f-22): bulkActions none|edit|delete|both açık ve editMode none değilken başa onay kutusu kolonu gelir (başlıkta sayfadaki satırları seç); anahtarlı sunucu satırları seçilir, seçim self.selectedRows'a yazılır ve rowSelectionChange yayılır. Seçim çubuğu: 'N seçili · Toplu düzenle · Sil · Temizle'. Toplu düzenle bir FORMDUR ve sağdan açılan bir ÇEKMECEDE (drawer, 2026-09-19) alanlar alt alta listelenir; altta Vazgeç · Uygula, arka plan/×/Escape uygulamadan kapatır: yazılabilen her kolon için editör (anahtar üçlü seçim, ilişki alanında lookup paneli); yalnız doldurulan alanlar uygulanır, boş bırakılan değişmez; ilişki alanının ×'i temizler (o2m null, m2m boş liste — hücre editörüyle aynı); row kipinde bütün doldurulan alanlar tek save (tek update isteği, bulk), batch'te taslağa girer. Sil onaylı, tek delete. Hatasız yazılan satırlar seçimden düşer, hatalılar kırmızı ve seçili kalır; 1000 satır üstünde toplu eylem kapanır. BAĞLI TABLODA bulkActions'ı runtime yazar: tanım edit.bulk ∧ meta.write.bulk, update → edit, delete → delete. Hücre seçimi (Shift/Ctrl/Alt, selectedCells, cellSelectionChange) tek başına değer doldurmaz; batch kipinde seçimin içindeki bir hücre çift tıkla düzenlenirse değer seçili hücrelerin hepsine yazılır (2026-09-18), çok alanı birlikte değiştirmek toplu düzenle formuyla yapılır. Kilitli (yazılamayan) hücre seçime girmez.",
142
+ "YERLEŞİM VE FİLTRE MODLARI (2026-09-18; 2026-09-21'den beri gelişmiş oluşturucu filterMode değil advancedFilter anahtarıdır ve column/bar ile birlikte açılabilir): advancedFilter (koşul oluşturucu: tümü/herhangi biri, VE/VEYA, grup; kurallar tutamaçtan sürüklenip grubun içine/dışına taşınır; Uygula yalnız her kuralın kolonu ve değeri doluyken görünür, Sıfırla yalnız uygulanmış filtre ya da taslakta kural varken; ziyaretçi filtreyi adıyla kaydedebilir — tanıma yazılmaz, tarayıcıda element id'siyle saklanır (localStorage ZY_DataTableFilters_<elementId>), üst çubukta Filtre düğmesinin yanındaki 'Kayıtlı filtreler' açılır menüsünden (filterPosition left'te sağında, right'ta solunda) panel açılmadan seçilip uygulanır, kanvasta yoktur; filtre yokken panel boş bir kuralla açılır; 'Filtre (n)' düğmesiyle açılır, Ctrl+Enter uygular — düğme ARAÇ GRUBUNUN PARÇASI DEĞİLDİR (2026-09-18): araçlar nerede olursa olsun tablonun üstündeki çubukta durur, filterPosition left'te başlığın hemen ardına, right'ta sağ kenara) · column (başlığın altında kolon başına filtre satırı: metinde işleç menüsü, sayı/tarihte min–max (bağlı tablonun birincil anahtarı hariç: tek değer, eşittir; date ve datetime kolonda gün seçilir ve gte 'GÜNT00:00:00' · lte 'GÜNT23:59:59' gider — bitiş günü dahildir, 2026-10-02), boolean Tümü/Evet/Hayır, enum/tag'de çoklu seçim, relation'da lookup) · bar (tablo üstünde kolon başına açılır düğme + panel) · none. ÜÇ MOD DA AYNI filters sözleşmesini yazar ve mount'u tetikler — bağlı tabloda işleçler capability.operators'tan gelir (aralık yalnız gte+lte sunulursa), enabled:false kolon hiçbir modda çıkmaz; column/bar ekranı her zaman filters prop'undan kurulur (sunucu 422 ile reddedince geri yazılan filtre görünür). showFilterSummary aktif filtre + sıralamayı kaldırılabilir chip'ler olarak gösterir; bar modunda çizilmez (aktif filtreler barın haplarında durur ve oradan düzenlenir), sonuç sayısı ne barda ne özette yazılır — footer'daki kayıt özeti taşır. Başlık (title) boşsa üst çubuk yalnız araçlar üstteyse ya da advanced filtre düğmesi varsa çizilir; başlıksız tabloda filterMode bar iken üst köşedeki araçlar ayrı çubuk açmaz, filtre çubuğunun ucuna oturur. Araçlar (showRefresh · showExport: bu sayfanın CSV'si · showColumnManager: 'Column settings' menüsü — kolon gizle/göster ve sürükleyerek (ya da tutamaçta ↑/↓) sırala, tanıma yazılmaz; seçim tarayıcıda element id'siyle saklanır (localStorage ZY_DataTableColumns_<elementId>) ve tablo aynı kolonlarla açılır, Reset kaydı siler, kanvas okumaz; üçü de yalnız ikon + tooltip) toolsPosition ile dört köşeden birine oturur; footer (sol altta kayıt özeti '1–10 / 24 kayıt · 1 seçili' — showRecordSummary ile kapatılır —, sayfa başına, «ilk ‹önceki sayfa numaraları sonraki› son» düğmeleri) footerPosition ile tablonun altında ya da üstündedir; sayfalama paginationPosition ile kayıt sayısının ardında (left) ya da sağ kenardadır, stickyFooter footer'ı sayfa kaydırmasında görünür kenara yapıştırır. stickyHeader başlığı tablonun KENDİ kaydırmasında üstte tutar (sabit yükseklikli tablo); kolonun isPinned'i kolonu başa alıp yatay kaydırmada solda sabitler. size sm|md|lg satır yüksekliğini, hücre boşluğunu ve yazı boyunu değiştirir. YENİ BIRAKILAN TABLO (2026-09-18): başlıksız, filterMode bar, araçlar sağ üstte (filtre çubuğunun ucunda), isPaginated açık, sayfalama sağ altta, kayıt özeti sol altta, stickyHeader açık, size md, Status kolonu solid tag; bu değerler yalnız şema varsayılanıdır — prop'u hiç yazılmamış eski düğüm eski görünüşünü korur (advanced, sağ üst araçlar, sağda sayfalama, yapışkan başlık kapalı). paginationMode pages (numaralı) | infinite (gövde sona kaydırıldıkça sonraki sayfa offset=yüklenen satır sayısıyla istenir ve satırlar birikir; kendi yüksekliğiyle uzayan tabloda footer'da 'Daha fazla' düğmesi). Gövde durumları: yükleniyor (iskelet), kayıt yok, filtre sonucu boş (Filtreleri kaldır), hata (loadError; Tekrar dene mount'u yeniden çalıştırır, satır varken tablo üstünde şerit).",
143
+ "TİPE BAĞLI İLİŞKİ (2026-10-01, ADR 0012): 'Kime' gibi bir hücre satırın türüne göre farklı tabloya bağlanıyorsa (hedef başına ayrı nullable FK: hedef_user_id, hedef_pozisyon_id, hedef_birim_id) kolonu görünen adı tutan METİN alanına bağla ve columns[i].relationTypeField = türü tutan alan (ör. hedef_tipi), relationTargets = [{ value:'kullanici', field:'hedef_user_id' }, …] yaz. Hedef FK kolonları columns'ta isHidden:true durmalı ve tanımın editable listesinde olmalı (tür, ad ve üç FK). Satır düzenlemesinde hücre o satırın (taslaktaki) türünün gizli ilişki kolonunun lookup'ını açar; seçim TEK YAMAYLA seçilen FK'yi, öbür FK'leri null'u ve görünen adı (hedefin görünen alanı) yazar; tür değişince FK'ler ve ad boşalır. Tür boşken hücre salt okunurdur. Toplu düzenleme bu kolonu sunmaz. Birden çok türün paylaştığı hedef tabloda (birimler: departman/firma/grup) relationTargets öğesine filterField + filterValues ('holding, company') ve isteğe bağlı excludeField + excludeValues yazılır; alanlar tanımda o FK'nin lookup.behavior.filterable listesinde olmalı. Tür değişince Kime seçicisi hemen açılır; seçimsiz kapanırsa tür ve Kime eski hâline döner. Kayıt satırın kaydıdır — editMode row önerilir.",
144
+ "SÜRÜKLE-SIRALA (2026-10-01, ADR 0012): canReorderRows:true + orderField:'<sayı alanı>' (editMode none değilken ve sıra kolonu yazılabilirken) satır başına tutamaç kolonu açar; satırlar orderField'a göre çizilir (boşlar sonda). Sürükle ya da tutamaç odaktayken ↑/↓. Bırakılan satır kendi adımı olur, aynı sıradaki satırlar grup kalır (iki eş sıralı satırın arasına bırakılan o gruba katılır), adımlar 1..n yeniden numaralanır; yalnız değeri değişen satırlar yazılır. row/cell kipinde hemen tek save (operation rowReorder), batch'te taslakta bekler. Yeni ve anahtarsız satır taşınmaz; açık düzenleme, toplu seçim ya da süren kayıt varken tutamaç pasiftir. Eş sıra vermek için sıra hücresi elle düzenlenir.",
145
+ ],
146
+ propNotes: {
147
+ searchText: "Gizli, AKIŞIN yazdığı arama metni (2026-10-02, web ve mobil). Tablonun kendi arama kutusu yoktur; ayrı bir textinput'un değeri setter ile <tablo>.searchText'e yazılır. Bağlı tabloda setter bu yazımdan sonra listeyi YENİDEN OKUR (sayfa başa döner) ve istek search taşır: sunucu tanımın behavior.searchable alanlarında içerir (icontains) koşuluyla arar — entity kaynağında ve dinamik filtreli Table kaynaklı microservice'te. Searchable boşsa istek 422 ConnectDataFilterNotAllowed. Aynı yol filters / sortField / sortType / offset / limit için de geçerlidir: setter bunlardan birini yazınca bağlı liste yeniden okunur.",
148
+ canReorderRows: 'boolean (varsayılan false) — satırları tutamaçtan sürükleyerek sıralama; orderField olmadan ya da editMode none iken etkisiz.',
149
+ orderField: "Sırayı tutan sayı alanının adı (ör. 'sira'); canReorderRows açıkken satırlar buna göre çizilir ve sürükleme buraya yazar.",
150
+ surfaceStyle: NODE_SURFACE_NOTE + " Datatable'ın kabı VARSAYILAN olarak kendi 1px çerçevesini, 6px köşesini ve yüzey zeminini çizer (filtre çubuğu + ızgara + footer'ı saran çerçeve). Grupta bir kenarlık yazılınca (borderTop/Right/Bottom/Left — 'none' dahil) kap KENDİ çerçevesini bırakır: çerçeveyi kaldırmak için dört yöne 'none' yaz; düz çizgi yazmak ikinci çerçeve eklemez. radius yazılınca kap köşeyi düğüm kutusundan alır, background yazılınca kabın zemini saydamlaşır (2026-09-18).",
151
+ editMode: "none | row | cell | batch (tasarımcı etiketleri Row / Cell / Batch). Bağlı tabloda runtime tanımın behavior.edit.saveMode'undan yazar; elle yazmak bağlı tabloda etkisizdir. Bağlı olmayan tabloda save olayındaki self.changeset'i akış yazar.",
152
+ operation: "Salt okunur, save'den ÖNCE yazılır (2026-09-21): kaydı doğuran işlem — rowAdd · rowEdit · cellEdit · rowDelete · bulkEdit · bulkDelete · batchSave (batch kipinin 'Değişiklikleri kaydet'i, karışık changeset) · rowReorder (sürükle-sırala). Ayrı olay YOKTUR: tek save akışı Condition'da self.operation ile ayırır.",
153
+ editedRows: "Salt okunur, save'den önce yazılır: eklenen/düzenlenen satırların TAM hâli (sunucu satırı + yama; yeni satırda girilen değerler) — changeset.updated yalnız yamayı taşır. Kolonlara bağlıdır: akış editörü self.editedRows[0].<kolon> önerir.",
154
+ deletedRows: "Salt okunur, save'den önce yazılır: silinen satırların TAM hâli (tek silmede bir öğe) — changeset.deleted yalnız { rowId, id } taşır.",
155
+ editedCell: "Salt okunur, save'den önce yazılır: yalnız operation cellEdit iken { rowId, field, value, previousValue }, diğer işlemlerde null.",
156
+ bulkPatch: "Salt okunur, save'den önce yazılır: yalnız operation bulkEdit iken toplu formun seçili satırlara yazdığı { <kolon>: değer }, diğerlerinde null.",
157
+ rowErrors: "Salt okunur: [{ rowId, field?, message }] — bağlantı son kaydın satır hatalarını yazar; field varsa o hücre kırmızı çerçeve + mesaj.",
158
+ selectedCells: "Salt okunur: { column, rowIds[], anchorRowId } — aynı kolonda çoklu hücre seçimi (D-25); farklı kolona tıklamak seçimi sıfırlar. Doldurma f-22.",
159
+ revealEntity: REVEAL_ENTITY_NOTE,
160
+ columns: "Kolon tipleri: text · number · date · datetime · time · switch · tag · email · url · link · image · file · progress · relation · html. HTML (2026-09-18) html bileşeninin modelini hücreye taşır: satır değeri { content, style } — content ham HTML'dir ve SATIRIN alanlarıyla Mustache'ten geçer ('<b>{{name}}</b>'), style o hücreye scoped CSS bloğudur (emotion; 'color:red; b { … }' iç seçici alır, designerCss/!important YOK); bağlı kaynaktan düz metin gelirse content sayılır. İşaretleme TEMİZLENMEDEN basılır (html bileşeniyle aynı güven modeli; <script> hücrede ÇALIŞMAZ, satır içi on* handler'lar çalışır) — son kullanıcının yazdığı bir alanı html kolonuna eşleme. Satır içi düzenlenmez (editable gizli); sıralama/filtre/CSV etiketsiz metni görür. Studio Rows editöründe html kolonu için 'HTML content' + 'Style' iki metin alanı çıkar. RELATION (Connect Data) ilişki alanının hedef nesnesini ({ id, ad }) görünen alanıyla metin olarak, m2m dizisini ilk 3 chip + “+N” olarak çizer; hedef tabloyu okuyamayan kullanıcıya gri “—” + kilit basar. BAĞLI TABLO: rows connectData ile bağlıysa runtime her kolona gizli capability yazar (işleçler, sortable, enabled, relation, enum) — sıralama/filtre anahtarını ve filtre işleç listesini sunucu belirler, enum değerleri etiket+renkle çizilir; capability elle yazılmaz. Her tipin ne beklediği/ne çizdiği table'ın kolon sözlüğüyle AYNIDIR (component_get('table') → knowledge.propNotes.columns), İKİ İSTİSNA dışında: burada image/file düz URL kabul etmez (aşağıdaki image notu) ve renk satır bazında değil colorMap ile kurulur. PROGRESS (2026-08-27) hücrenin içine çubuk ya da halka çizer: progressVariant bar|circle · max (varsayılan 100) · progressLabel none|percent|fraction|value · progressColor + customProgressColor · thresholds [{from,color}] (yüzdeyi geçmeyen en yüksek eşik kazanır) · captionField BAŞKA bir satır alanının metnini çubuğun ÜSTÜNE yazar, yani ad ve çubuk tek hücrede durur. Sıralama/dışa aktarım ham sayıyı görür, çizimi değil. KİŞİ HÜCRESİ (2026-09-18): text kolonunda showAvatar metnin önüne baş harfli renkli daire çizer (renk addan türer, aynı ad hep aynı renk); avatarField BAŞKA bir satır alanından görsel okur (dosya nesnesi ya da URL; yüklenemezse baş harfe düşer) — ayrı image kolonu açmadan 'avatar + ad' tek hücrede durur. TAG appearance subtle: açık zemin + koyu yazı + renkli nokta (durum rozeti); colorMap'te semantik ad (success/warning/info) tema token'ına çözülür — DİKKAT: temalarda info neredeyse beyazdır (#F8F8F8), mavi için primary kullan; çok açık bir renk subtle'da gri rozete sınırlanır; colorMap satırının mode'u solid ise o değer kolonun görünümünden bağımsız renkli zemin + beyaz yazıyla çizilir (varsayılan soft = kolonun appearance'ı). SWITCH kolonu (2026-09-18) kontrol değil durum işaretidir: booleanStyle icon (varsayılan; true yeşil dolu daire + ✓, false kırmızı dolu daire + ×) · text (dile göre Evet/Hayır, Hayır kırmızı) · switch (eski toggle görünümü); booleanFalseColor muted false'u sönük griye çeker (varsayılan error/kırmızı — false'un sorun olmadığı alanlarda muted kullan). number kolonu eşit genişlikli rakamla çizilir; url kolonu adresi protokolsüz gösterir. HİZA (2026-09-18): kolonun align alanı left|center|right başlığı ve hücreyi birlikte hizalar (avatar+metin ve halka progress da kayar); boş = her tipte solda (number dahil — tutarları sağa yaslamak için align:right yaz); bağlı tablonun birincil anahtar kolonu (capability.isKey) yeni bağlamada 80px dar gelir.",
130
161
  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.",
131
162
  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.",
132
163
  selectedRow: "Salt okunur: satır aksiyonu tıklanınca komponentin kendisi doldurur; akış ifadesinde '<elementId>.selectedRow' ile okunur.",
133
- 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.",
164
+ colorMap: "Kolon içi değer→renk sözlüğü: [{ value:'Active', color:'#16a34a' }]. ETİKET (2026-10-01): satıra label yazılırsa hücre ham değer yerine onu çizer — [{ value:'Approved', label:'Onaylandı', color:'success' }] veritabanındaki İngilizce durumu Türkçe rozetle gösterir; filtre seçenekleri de etiketi gösterir, sıralama/filtre ham değerle çalışır. Bağlı kolonda aynı değerin enum etiketini EZER. Etiketli değerin solid modu etikete göre uygulanır. 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ısı BEYAZDIR, yalnız gerçekten açık zeminde (sarı/amber, açık gri; LCH açıklığı > 70) siyah seçilir — token'da CSS ile, hex'te ölçülerek. SATIR MODU (2026-09-18): [{ value, color, mode:'solid' }] o değeri kolonun appearance'ı (subtle/outline) ne olursa olsun dolu zemin + BEYAZ yazıyla çizer; mode yazılmazsa ya da 'soft' ise kolonun görünümü geçerlidir. Renksiz satırın solid modu yok sayılır.",
134
165
  tableStyle: "zebra | plain — satır zemini varyantı; CSS DEĞİL. Serbest CSS için ayrı `style` prop'u vardır (parça bazlı).",
135
- 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."
166
+ style: "Parça bazlı CSS: &__toolbar · &__title · &__footer · &__summary · &__filter-bar · &__filter-panel · &__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.",
167
+ filterMode: "column | bar | none — satır içi filtre arayüzü; gelişmiş koşul oluşturucu ondan bağımsız advancedFilter anahtarıdır, ikisi birlikte açılabilir. Hepsi aynı filters dizisini yazar, akış/bağlantı farkı görmez. column/bar modunda VE/VEYA ve grup kurulamaz (kök kurallar and ile bağlanır); oradan uygulanan filtre yalnız o kolonun kök kurallarını değiştirir, gelişmiş paneldeki grup/or kuralları KORUNUR ve kolon/bar kuralları panelde kural olarak görünür. Bar'ın 'Filtreleri temizle'si yalnız bar kurallarını kaldırır. Eski düğümdeki filterMode=advanced (advancedFilter yazılmamışken) gelişmiş oluşturucu olarak okunur.",
168
+ advancedFilter: "boolean (şema varsayılanı false) — gelişmiş koşul oluşturucu ('Filtre (n)' düğmesi + panel), filterMode'dan bağımsız. Yazılmamış eski düğümde filterMode=advanced ya da boşsa açık sayılır.",
169
+ paginationMode: "pages | infinite — yalnız isPaginated açıkken. infinite'te akış/bağlantı yine TEK sayfa döner; birikimi komponent yapar (offset 0 sıfırlar). totalRows yazılmazsa 'daha var mı' bilinemez ve yükleme durur.",
170
+ toolsPosition: "top-right | top-left | bottom-right | bottom-left — yenile/dışa aktar/kolon menüsü grubunun köşesi (advanced Filtre düğmesi bu grupta DEĞİLDİR, bkz. filterPosition). Alt köşede footer alttaysa onun içine, üstteyse tablonun altındaki ayrı çubuğa oturur.",
171
+ filterPosition: "left | right — yalnız advancedFilter açıkken: 'Filtre (n)' düğmesi hep tablonun üstündeki çubuktadır; left'te başlığın hemen sağına (başlık yoksa sol kenara), right'ta sağ kenara (üstteki araçlardan önce) oturur.",
172
+ paginationPosition: "left | right — footer'da sayfa başına + sayfa numaralarının yeri: left kayıt sayısının ardı (yeni tablonun varsayılanı), right sağ kenar (prop yazılmamış eski düğüm).",
173
+ stickyHeader: "Başlık satırı (ve column modundaki filtre satırı) tablonun KENDİ dikey kaydırmasında üstte kalır — tablo sabit yükseklikliyken anlamlıdır; kendi yüksekliğiyle uzayan tablo sayfayla kaydığından etkisizdir.",
174
+ stickyFooter: "Footer sayfa kaydırmasında görünür kenara yapışır (footerPosition top'ta üste, bottom'da alta) — kendi yüksekliğiyle uzayan uzun tabloda sayfalamayı erişilir tutar.",
175
+ size: "sm | md | lg — satır yüksekliği (hücre dikey boşluğu 6/12/16px), gövde yazısı (12/13/14px) ve başlık yüksekliği (32/40/48px). Varsayılan md.",
176
+ footerPosition: "bottom | top — toplam kayıt + sayfalama çubuğu; üstteyken stickyFooter ile sayfa kaydırmasında üstte kalabilir.",
177
+ addRowButton: "bottom | top | none — canAddRow açıkken '+ Satır ekle' satırının yeri; none'da yeni satır yalnız Ctrl/Cmd+Enter (addRowShortcut) ile açılır.",
178
+ showExport: "Görünen kolonlar × eldeki satırlar CSV'si (bu sayfa; infinite'te o ana kadar yüklenenler) — sunucudaki tüm sonuç DEĞİL.",
179
+ loadError: "Salt okunur: Connect Data bağlantısının son okuma hatası (başarılı okuma temizler). Satır yoksa gövde hata durumu + 'Tekrar dene', satır varsa üstte şerit. Bağlı olmayan tabloda akış yazabilir."
136
180
  }
137
181
  },
138
182
  form: {
@@ -144,6 +188,7 @@ export const componentKnowledge = {
144
188
  "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).",
145
189
  "Alan doğrulaması komponentin kendi validations dizisindedir: [{ type: 'required'|'email'|'max-length'…, message, value, isActive }] — dördü de zorunlu, eski 'maxLength' yazımı kaydedilir ama runtime doğrulayıcı onu TANIMAZ ve sessizce hiçbir şey doğrulamaz. min-value/max-value tarih kuralının çıplak 'yyyy-MM-dd' değeri YEREL gün okunur (2026-09-18): sınır gününe eşit bir alan değeri her saat diliminde geçer (eskiden UTC okunup Türkiye'de 3 saat kayıyordu, CQ-252).",
146
190
  "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.",
191
+ "KORUMALI ALAN (f-31): maskeli değer forma ASLA isMasked'sız value olarak bağlanmaz — güncelleme formunda korumalı alanın textinput'u value'yu kaydın alanına, isMasked'ı satır metasına birlikte bağlar (textinput.propNotes.isMasked). isMasked:true iken BOŞ bırakılan alan required doğrulamasına TAKILMAZ; kullanıcı yazarsa sıradan alan gibi doğrulanır. Boş değerin GÖNDERİLMEMESİ submit akışının isteği nasıl kurduğuna bağlıdır: microservice çağrısının parametre bağı null/'' değeri gövdeye koymaz (saklı değer korunur); gövde akış kodunda ya da setter göreviyle elle kuruluyorsa null GİDER — canWrite yoksa 403 AccessFieldWriteDeniedException, varsa saklı değer SİLİNİR. O durumda boş maskeli alanı gövdeden çıkar.",
147
192
  "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.",
148
193
  "isLoading AÇIKKEN alanlar DOM'dan kalkar, yerine yükleme animasyonu çizilir: kapanınca çocuklar yeniden mount olur ve onların mount olayları İKİNCİ kez çalışır; makinedeki değerler korunur. title boş bırakılırsa başlık bandı hiç çizilmez. Kanvas toolbar'ı (2026-09-18): isClearFormInputsAfterSubmit · isLoading · isHidden — yerleşim grubunu container toolbar'ı zaten çizer."
149
194
  ],
@@ -159,7 +204,7 @@ export const componentKnowledge = {
159
204
  }
160
205
  },
161
206
  box: {
162
- summary: "Evrensel bırakma kutusu: container'dan farkı kutu modelinin border-box olması ve isteğe bağlı başlık/altlık bölgeleridir; yerleşim değer kümesi 2026-09-02'den beri container'ınkiyle aynıdır.",
207
+ summary: "Evrensel bırakma kutusu: container'dan farkı kutu modelinin border-box olması, tabanında ÇERÇEVE OLMAMASI ve isteğe bağlı başlık/altlık bölgeleridir; yerleşim değer kümesi 2026-09-02'den beri container'ınkiyle aynıdır. Tasarımda çerçevesi olmayan her düzen kutusu (satır, sütun, şerit, buton grubu) box ile kurulur.",
163
208
  behavior: [
164
209
  LAYOUT_ABSENT_NOTE,
165
210
  "layout iki değer alır: 'flex' (akış) ve 'grid' — ve 'grid' container'ınkiyle AYNI ŞEYDİR: mutlak koordinatlı 12 kolon canvas (kullanıcı kararı 2026-09-02, tek grid kavramı). Şemadaki eski 'cssgrid' değeri (akan GERÇEK display:grid) seçenek olmaktan çıktı: yeni yazımda geçmez (invalid-enum-value), yalnız o değerle KAYITLI eski düğümler çizilmeye devam eder (screen-builder/grid-layout.ts isCssGridLayout yalnız 'cssgrid'e bakar).",
@@ -200,7 +245,7 @@ export const componentKnowledge = {
200
245
  'Yüzeysiz sarmalayıcıdır: kendi zemini/kenarlığı yoktur, yalnız bölge ayracını çizer (header altına, footer üstüne).',
201
246
  "Palette GÖRÜNMEZ (isHide) ve SİLİNEMEZ (isDeletable:false) — kaldırmanın tek yolu box'ın ilgili anahtarını kapatmaktır.",
202
247
  "isLoading prop'u YOKTUR: yükleniyor durumu kutunun kendisindedir, bölge onu hiç görmez — dolayısıyla CQ-308'in bırakma alanını öldüren kalıbı bu düğümde hiç oluşmaz.",
203
- "Kendi yerleşimini panelden değil ELEMENT AĞACINDAN seçilerek düzenler (palette gizli, ağaçta görünür); gap alanı hâlâ eski gap+gapCustom ikilisini taşır (box'ta tek alan allowCustom ile birleşti).",
248
+ "Kendi yerleşimini panelden değil ELEMENT AĞACINDAN seçilerek düzenler (palette gizli, ağaçta görünür); gap alanı hâlâ eski gap+gapCustom ikilisini taşır (box'ta tek preset alanına indi; liste dışı değer platformda 422).",
204
249
  "role prop'u ('header' | 'footer') bölgenin kimliğidir ve gizlidir; elle değiştirmek yerleşimi bozar.",
205
250
  "Ayraç rengi ve bölge dolgusu artık kutunun 'sectionStyle' grubundan yönetilir (bölge düğümünün kendi şemasından değil): headerDivider/footerDivider/dividerColor/sectionPadding."
206
251
  ],
@@ -249,22 +294,21 @@ export const componentKnowledge = {
249
294
  behavior: [
250
295
  "trigger 'click' ya da 'hover' olabilir; editör kipinde tetikleme çalışmaz ve panel HER ZAMAN açık, akış içinde çizilir (tasarımcı içeriği düzenleyebilsin diye) — gerçek konumlanma yalnız önizleme/çalışma anındadır.",
251
296
  "isOpen çift yönlüdür: tetikleyici yolu open/close olayını setter'la yayar (self.isOpen yazılır); akış isOpen'ı yazınca da (2026-09-18'den beri) aynı open/close olayı çıkar, bu kez setter'sız. İlk çizimde olay yok. Yani open'a bağlı bir akış (örn. detay yükle) panel nasıl açılırsa açılsın çalışır.",
252
- "Panel çocukları panelWidth px genişliğinde bir kutuda 12 sütunlu ızgaraya dizer (varsayılan 320). Eskiden genişlik içeriğe göre 200–320 arası büzülüyordu; editördeki yerleşim çalışma anıyla uyuşmuyordu. Panel `position: fixed` ile konumlanır (2026-10-05, ADR 0017): position TERCİHTİR — yer yoksa panel karşı yöne ÇEVRİLİR, viewport'a sığması için kaydırılır ve genişlik/yükseklik kalan yerle sınırlanır (375 px'te 480'lik panel 359'a iner, uzun içerik panelin İÇİNDE kayar). Tetikleyiciden 10 px uzakta, tetikleyicinin başlangıç kenarına hizalı açılır; ok panelin gerçekte indiği yöne ve tetikleyicinin ortasına bakar.",
253
- "Panel fixed olduğu için overflow veren atalar (sayfa kökü, modal gövdesi, overflow:hidden kart, container) onu KIRPMAZ; kırpabilecek tek ata transform/filter/contain taşıyan bir kaptır (böyle bir kabın içine koyma). Editörde panel akış içindedir ve kapsayıcıya göre kırpılabilir; gerçek konum yalnız önizleme/çalışma anındadır.",
254
- "closeOnOutside panelde yalnız trigger 'click' iken gösterilir (hover kipinde gizlidir; runtime kayıtlı değeri her kipte okur). Kapatılırsa panel yalnız tetikleyici, Escape ya da akışla kapanır. Escape her zaman kapatır: aynı anda açık birden çok popover'da (iç içe dahil) yalnız EN SON AÇILAN kapanır, panelin içindeki açık bir seçim listesi Escape'i önce kendisi alır, modal/drawer içindeyse modal'ı DEĞİL popover'ı kapatır ve odak panelin içindeyse tetikleyiciye döner. Hover kipinde 250 ms tolerans vardır (tetikleyiciden panele geçerken kapanmaz); klavye odağı da hover kipinde açar/kapatır.",
297
+ "Panel çocukları panelWidth px genişliğinde bir kutuda 12 sütunlu ızgaraya dizer (varsayılan 320). Eskiden genişlik içeriğe göre 200–320 arası büzülüyordu; editördeki yerleşim çalışma anıyla uyuşmuyordu. Panel tetikleyicinin yanında SAF CSS ile durur: ekran kenarına sığmazsa ÇEVRİLMEZ/kaydırılmaz, taşar; position'ı yerleşime göre seç.",
298
+ "Panel portal'a taşınmaz: overflow:hidden bir atada ya da düğümün kendi surfaceStyle taşması 'hidden' iken kırpılır. Popover'ı taşan kapsayıcının dışına koy, düğümün Surface taşmasını açık bırak.",
299
+ "closeOnOutside panelde yalnız trigger 'click' iken gösterilir (hover kipinde gizlidir; runtime kayıtlı değeri her kipte okur). Kapatılırsa panel yalnız tetikleyici, Escape ya da akışla kapanır. Escape her zaman kapatır. Hover kipinde 250 ms tolerans vardır (tetikleyiciden panele geçerken kapanmaz); klavye odağı da hover kipinde açar/kapatır.",
255
300
  "isDisabled tetikleyiciyi kilitler (tıklama/hover açmaz, düğme disabled); akışın isOpen yazması etkilenmez. triggerText boş ve triggerIcon dolu ise düğme yalnız ikon çizer; ikisi de boşsa sözlükteki 'Toggle/Aç-kapat' metni yazılır.",
256
- "Akıştan isOpen=true yazan bir düğmenin kendi tıklaması paneli kapatmaz (dışarı-tıklama yalnız panelin açıldığı andan SONRAKİ tıklamalarda çalışır). Erişilebilirlik: panel role=dialog'dur ve adını tetikleyici düğmeden alır (aria-labelledby), tetikleyicide aria-controls vardır; tetikleyiciye ikon+metin verilse ikon ekran okuyucuya okunmaz. Bir repeater satırının içindeki popover'ın open/close olayları satırı SEÇMEZ (satır seçimi yalnız tıklamayla olur).",
257
301
  "Panel yeniden yerleştirilmez: modal'daki gibi overlay/odak kapanı yoktur, arka plan tıklanabilir kalır. Sayfa akışını kesecek bir onay için modal kullan; satır detayı/hızlı form için popover."
258
302
  ],
259
303
  propNotes: {
260
304
  surfaceStyle: NODE_SURFACE_NOTE,
261
- triggerText: "Tetikleyici düğme metni; yalnız metin ve sayı yazılır — nesne/dizi/boş/boşluk-yalnız/çözülmemiş {{ }} yerel 'Toggle/Aç-kapat' yazısına düşer (düğmeye [object Object] basılmaz). Boş bırakılıp triggerIcon verilirse yalnız ikon çizilir. Uzun/boşluksuz metin düğmeyi büyütmez, satır kırılır.",
305
+ triggerText: "Tetikleyici düğme metni. Boş bırakılıp triggerIcon verilirse yalnız ikon çizilir.",
262
306
  trigger: "'click' (tıkla aç/kapat) | 'hover' (üzerine gelince açılır, ayrılınca 250 ms sonra kapanır).",
263
- position: "'bottom' | 'top' | 'right' | 'left' — panelin tetikleyiciye göre TERCİH EDİLEN yönü; yer yoksa çevrilir (kenardaki 'top' 'bottom'a dönebilir). bottom/top mantıksaldır (RTL'de tetikleyicinin sağ kenarına hizalanır); right/left FİZİKSELDİR (RTL'de aynalanmaz). Geçersiz/boş değer 'bottom'.",
307
+ position: "'bottom' | 'top' | 'right' | 'left' — panelin tetikleyiciye göre yönü. Saf CSS: yer yoksa çevrilmez, taşar.",
264
308
  panelWidth: 'Panel kutusunun genişliği px (160–1200, varsayılan 320; aralık dışı değer kırpılır, sayı olmayan/boş değer 320). Çocuklar bu genişlik içinde 12 sütuna dizilir; kart için 320–400, küçük form için 400–560 iyi başlangıçtır.',
265
309
  isDisabled: 'Tetikleyici kilidi; açık paneli kapatmaz, akışın isOpen yazmasını engellemez.',
266
310
  closeOnOutside: "Panelde yalnız trigger 'click' iken gösterilir; kapalıysa dışarı tıklamak paneli kapatmaz.",
267
- style: "Köke uygulanır; parça seçicileri '&__trigger' (düğme) ve '&__panel' (kutu) ile düğme ve panel ayrı boyanır. Kökteki color/fontFamily/fontSize tetikleyiciye ve panele iner (panelin içindeki text bileşeni kendi rengini taşır: koyu panelde text'e açık renk yaz). Ok panelin zeminini ve kenarlık rengini devralır; `&__panel::after` ile ayrıca boyanır/boyutlanır. `&__arrow` ve `&__content` parçası YOKTUR (etkisiz). Hover/odak/açık durumu için '&__trigger:hover', '&__trigger:focus-visible', '&__trigger[aria-expanded=\"true\"]', '&__trigger:disabled', '&__panel:focus-within' çalışır; @media ve @keyframes çalışır. Panelin konumunu left/top ile ezmeye çalışma: fixed ve ölçülür (ezmek için !important gerekir ve çevirmeyi kırar).",
311
+ style: "Köke uygulanır; parça seçicileri '&__trigger' (düğme) ve '&__panel' (kutu) ile düğme ve panel ayrı boyanır.",
268
312
  isOpen: "Açık/kapalı durumu; open/close olaylarıyla geri yazılır, akıştan yazılınca da olay çıkar. Editörde etkisizdir (panel hep açık), önizlemenin başlangıç durumunu belirler."
269
313
  }
270
314
  },
@@ -293,44 +337,41 @@ export const componentKnowledge = {
293
337
  behavior: [
294
338
  "change olayının yükünde iki alan vardır: 'value' (ağaç) ve 'jexl' (aynı ağacın ifadesi). setter YALNIZ value'yi self'e yazar; jexl yalnız event.data'dadır — sorguya bağlanacak alan odur.",
295
339
  'fields dizisi kullanıcıya sunulan alan sözlüğüdür; tipi operatör listesini belirler (ağaçta operatör ANAHTARI durur, ekrandaki etiket değil): text → eq, neq, contains, notContains, empty, notEmpty · number → eq, neq, gt, gte, lt, lte, between, empty, notEmpty · date → on, before, after, between, empty, notEmpty · select → eq, neq, empty, notEmpty. Sayı alanında operatörler sembolle çizilir (= ≠ > ≥ < ≤ ⟷), doluluk ikilisi metinle.',
296
- 'Her kural değişikliğinde change yayılır — sorguyu her tuşta yeniden koşturmak istemiyorsan akışta gecikme kur — gecikmeyi State’e geri yazan adımın önüne değil, sorguyu koşturan adımın önüne koy (geç gelen eski ağaç yeni tuşu geçici ezer).',
297
- 'Yarım bırakılan kural ekranda kalır ama jexl çıktısına girmez; sayı alanına sayı olmayan bir değer, tipe uymayan bir operatör ya da fields’ta olmayan bir alan adı (seçici ekranda boş kalır) yazılırsa da girmez. Boş ağaç boş string üretir (filtre yok) — sorguda "jexl boşsa filtre uygulama" dalını kur.',
298
- 'Kural ağacı çalışma anı durumudur, sayfa tasarımının parçası değil: preview yenilenince sıfırlanır. Kalıcılık için value prop’unu bir State’e bağla VE change akışında ağacı geri yaz (state.page.<ad> = event.data.value): value State’e bağlıyken içeriği değişmediği sürece kullanıcının düzenlemesi ekranda korunur, ama State ağacı ancak bu geri yazmayla öğrenir.'
340
+ 'Her kural değişikliğinde change yayılır — sorguyu her tuşta yeniden koşturmak istemiyorsan akışta gecikme kur.',
341
+ 'Yarım bırakılan kural ekranda kalır ama jexl çıktısına girmez; sayı alanına sayı olmayan bir değer ya da tipe uymayan bir operatör yazılırsa da girmez. Boş ağaç boş string üretir (filtre yok) — sorguda "jexl boşsa filtre uygulama" dalını kur.',
342
+ 'Kural ağacı çalışma anı durumudur, sayfa tasarımının parçası değil: preview yenilenince sıfırlanır. Kalıcılık için value prop’unu bir State’e bağla.'
299
343
  ],
300
344
  propNotes: {
301
345
  fields: '[{ label, field, type, options }] — type: text|number|date|select (varsayılan text); options yalnız select tipinde okunur, virgülle ayrılmış metin. Aynı field iki satırda tekrarlanırsa ikincisi yok sayılır.',
302
- value: 'Kural ağacı; gizlidir ve setter ile yazılır. Düğüm kimlikleri (id) ağaçta korunur; aynı kimliği iki düğüme verirsen ikincisine yenisi atanır. Başlangıç ağacı için value’ya static bir ağaç da verilebilir; State’e bağlarsan aynı içerik yeniden çözümlenince ekrandaki düzenleme ezilmez.',
346
+ value: 'Kural ağacı; gizlidir ve setter ile yazılır. Düğüm kimlikleri (id) ağaçta korunur; aynı kimliği iki düğüme verirsen ikincisine yenisi atanır.',
303
347
  showClear: 'Kuralların altına "Tümünü temizle" düğmesi koyar (varsayılan açık); basıldığında ağaç boşalır ve boş jexl ile change yayılır. Ağaç zaten boşken düğme pasiftir.',
304
348
  size: 'Kural satırlarının puntosu (sm|md|lg); boş bırakılırsa md.',
305
349
  isReadonly: 'Kurallar görünür kalır, hepsi kilitlenir; olay yayılmaz.',
306
- isViewmode: 'Kurallar çerçevesiz düz metne iner (kayıt görüntüleme ekranı): VE/VEYA düğme çifti yerini etkin birleştiricinin düz metnine bırakır, ekle/kaldır ve temizle düğmeleri çizilmez.',
307
- style: 'Parçalar: &__group (kök grup da dahil; iç gruba ayrı parça yok), &__rule, &__combinator (VE/VEYA kabı), &__input (alan, operatör ve değer kutularının üçü), &__add, &__remove, &__clear. Etkin VE/VEYA seçeneği adlı parça DEĞİL: `& button[aria-pressed="true"]` ile hedefle, ikisi için `& button`.'
350
+ isViewmode: 'Kurallar çerçevesiz düz metne iner (kayıt görüntüleme ekranı): VE/VEYA düğme çifti yerini etkin birleştiricinin düz metnine bırakır, ekle/kaldır ve temizle düğmeleri çizilmez.'
308
351
  }
309
352
  },
310
353
  comments: {
311
354
  summary: '@bahsetmeli, iç içe yanıtlı yorum akışı; gönderilen her yorumu akışa devreder.',
312
355
  behavior: [
313
356
  'İYİMSER KATMAN: gönderilen yorum, beğeni, DÜZENLEME ve silme ANINDA arayüze yansır ama HİÇBİRİ kalıcı değildir — uca yazmak akışın işidir. Düzenlenen yorum yeni metinle, soluk ve "düzenlendi" işaretiyle görünür.',
314
- 'BEKLEYEN YORUM yalnız karşılığı rows’a gelince kalkar: gönderimden SONRA beliren, aynı üst yoruma (parentId), aynı metne (boşluklar sadeleştirilir) ve — currentUser doluysa — aynı yazara sahip yeni bir satır. Akışın rows’u başka bir sebeple tazelemesi (geç dönen önceki gönderim) bekleyeni silmez. Akış yorumu hiç kaydetmezse ya da metni değiştirerek (kırpma, temizleme) kaydederse bekleyen "gönderiliyor…" kalır; kaydettiğin metni olduğu gibi yaz. Beğeni, düzenleme ve silme katmanları ise rows İÇERİĞİ değişince temizlenir (referans değişimi yetmez).',
357
+ 'Bekleyen katman yalnız rows İÇERİĞİ değiştiğinde temizlenir (referans değişimi yetmez). Akış kaydettikten sonra rows tazelenmezse bekleyen satır bir sonraki içerik değişiminde kaybolur.',
315
358
  'Yorum silinince altındaki her yanıt da ekrandan gizlenir; delete yükü yalnız kök id taşır — yanıtları silmek (ya da bırakmak) akışın/servisin kararıdır.',
316
359
  'Yanıt tek seviyedir: yanıt düğmesi yalnız kök yorumda çıkar, yanıtın yanıtı yoktur.',
317
360
  'people listesi @bahsetme önerilerini besler; submit yükündeki mentions bu listeye göre çözülmüş adlardır. Listede olmayan @ad düz metin kalır.',
318
361
  'ownOnly açıkken düzenleme/silme yalnız currentUser’ın kendi yorumlarında görünür — yetki KONTROLÜ değil, arayüz filtresidir; asıl kontrol uçtadır.',
319
362
  'Kilitler: isDisabled yazma kutusunu soluk (yazılamaz) gösterir; isReadonly ve isViewmode kutuyu hiç çizmez. Üçünde de yanıtla/düzenle/sil gizlenir, beğeni sayacı görünür ama tıklanmaz (like yayılmaz).',
320
363
  'Tekrarlanan id’de ilk satır id’sini korur, sonrakiler "<id>#<sıra>" olur ve olay yükleri bu uydurma id’yi taşır (uç tanımaz) — id benzersiz verilmeli.',
321
- 'OLAY YÜKÜ YALNIZ event.data’DADIR: submit/like/edit/delete bileşenin prop’larına yazılmaz, self.text · self.id · self.mentions gibi okumalar boş/undefined gelir ve akış adımı 400 verebilir. Akışta {{ event.data.text }}, {{ event.data.parentId }}, {{ event.data.id }} yaz.',
322
- 'Tek submit yükündeki mentions yalnız ekranda vurgulanan adlardır: @ bir kelimenin sonuna yapışık olmamalı ("foo@Ayşe" bahsetme sayılmaz, "(@Ayşe Kaya)" ve "Selam,@Ali" sayılır) ve ad, daha uzun bir kelimenin başı olmamalı ("@Ayşe Kayalı" sayılmaz). Birden çok sözcüklü ad ("Ayşe Kaya") yazılırken öneri boşluktan sonra da açık kalır; adın tamamı yazılıp boşluk basılınca ("@Ali " ve listede "Ali" varsa) kapanır, Enter gönderir.',
323
- 'createdAt çözülemezse (dün, 2026-13-45, 2026-02-30, 2026-02-30T10:00:00, tek başına 0 ya da 12345) tarih HAM metin olarak görünür; yeni bir gün uydurulmaz. Tarih biçimi seçilemez, yerele göre sabittir.',
324
- 'Kök yazı tipi/rengi içe iner: style.fontSize, fontFamily ve color yazar adı, metin, tarih ve yazma kutusuna ulaşır (iç boyutlar kökün oranıdır; tarih rengi yazı renginin %72’sidir). Bağlantı gibi çizilen eylem düğmeleri ve @bahsetme vurgusu vurgu rengini korur.',
325
- 'Klavye: yazma kutusunda @ ile açılan öneri ↑/↓ ile gezilir, Enter seçer (liste kapalıysa gönderir), Esc listeyi kapatır (IME bileşimi sırasındaki Esc de üst katmanı kapatmaz); gezilen satır kaydırılan listenin görünür bölümünde kalır; yanıt/düzenleme kutusu Esc ile kapanır ve çekmece/modal gibi üst katmanı KAPATMAZ. Yanıt ve düzenleme kutusu açılınca odak kutuya gelir, kapanınca açan düğmeye döner. IME bileşimi sırasında Enter göndermez. Öneri listesi altta sığmıyorsa kutunun üstüne açılır.',
326
- 'Yorumlar liste yapısındadır (role="list", her konu listitem); yazma kutusunun adı "Yorum yaz", yanıt kutusunun "Yanıt yaz", düzenleme kutusunun "Yorumu düzenle" (dile göre). Avatar süs görseldir; kırık ya da yüklenemeyen avatar adın baş harflerine düşer.'
364
+ "Süreç kapsamı (scope task | instance, targetId): rows platform yorumlarıdır (Page.bpm.instance(id).comments() — { id, body, authorUserId, postedAt }) ve users listesiyle adlara çevrilir. submit yükündeki process alanı { scope, targetId, visibility, body, mentionUserIds } taşır: @Ad metinde @<kullanıcı id>'sine çevrilmiştir — bahsetme metnin başında ya da boşluktan sonra başlar, ad tam kelime olarak eşleşir (@Alican, Ali değildir), büyük/küçük harf Türkçe kuralla yok sayılır, uzun ad önce; iki kullanıcının paylaştığı ad çevrilmez. Akış Page.bpm.instance(targetId).comment(process.body, process.visibility) ya da Page.bpm.task(targetId).comment(...) çağırır. Bahsedilen kişiye platform metinsiz bildirim yollar (iç yorumda yalnız dış katılımcı olan kişiye hiç). visibility boşsa sürecin commentVisibility'si uygulanır; internal dış katılımcıdan gizler. Süreç kapsamında yanıt, beğeni, düzenleme ve silme kapalıdır (platformda karşılığı yok)."
327
365
  ],
328
366
  propNotes: {
329
367
  rows: '[{ id, author, text, createdAt, parentId, avatar, likeCount, likedByMe }] — parentId dolu olan satır yanıttır. createdAt ISO metni, "YYYY-AA-GG" ya da Unix zaman damgası (10 hane saniye / 13 hane milisaniye) olabilir; boş author+text satırı atlanır.',
330
368
  currentUser: 'Yorum sahipliğini ve ownOnly filtresini belirleyen ad; tüm olay yüklerindeki author budur (yorumun sahibi DEĞİL, işlemi yapan). Boşsa düzenleme/silme ownOnly açıkken gizlenir.',
331
369
  people: '@bahsetme önerileri: virgülle ayrılmış metin ya da ad dizisi ({{ users.map((u) => u.name) }}).',
332
- placeholder: 'Boşsa dile göre "Yorum yaz… (@ ile birini an)" gösterilir; yanıt kutusu da aynı metni kullanır. Erişilebilir ad ayrıdır ve dile göre sabittir.',
333
- style: STYLE_GROUP_NOTES.styleEscape + " PARÇALAR (19): '&__list' · '&__thread' (bir kök yorum + yanıtları) · '&__comment' · '&__avatar' · '&__body' · '&__meta' · '&__author' · '&__date' · '&__text' · '&__mention' · '&__actions' · '&__action' · '&__reply-composer' · '&__composer' · '&__textarea' · '&__button' · '&__suggestions' · '&__suggestion' · '&__empty'. Durum hedefleri parçaya EK olarak yazılır: '&__comment--reply' (yanıt) · '&__comment--pending' (gönderiliyor) · '&__action--danger' (Sil) · '&__button--ghost' (Vazgeç); beğeni düğmesi için '&__action[aria-pressed=\"true\"]'; '&__textarea:focus-visible', '&__action:hover', '&__suggestion:hover', '::before/::after' ve '@media' çalışır. Hepsi ilk adayda tutar. Yanıt girintisi mantıksaldır (margin-inline-start): RTL'de sağdan gelir; özelleştirirken marginLeft değil marginInlineStart yaz."
370
+ placeholder: 'Boşsa dile göre "Yorum yaz… (@ ile birini an)" gösterilir; yanıt kutusu da aynı metni kullanır.',
371
+ users: "[{ id, name }] — süreç yorumunda bahsedilebilecek kullanıcılar; öneriler people ile birleşir.",
372
+ scope: "'' (serbest) | task | instance — süreç görevine ya da örneğine yorum.",
373
+ targetId: 'Süreç kapsamında görev ya da örnek kimliği; submit yükünün process.targetId alanına geçer.',
374
+ visibility: "'' (sürecin commentVisibility'si, varsayılan) | all | internal — süreç yorumunun görünürlüğü."
334
375
  }
335
376
  },
336
377
  aibox: {
@@ -358,6 +399,7 @@ export const componentKnowledge = {
358
399
  container: {
359
400
  summary: "Genel kapsayıcı (TİPLİ stil modeli: surfaceStyle · typographyStyle · hoverStyle · headerStyle); children'ını ya FLEX akışıyla (yeni kapsayıcıların varsayılanı) ya da 12 kolonluk IZGARA ile dizer. Her sayfanın kökünde silinemeyen page_container bundandır ve o da aynı düzen prop'larını alır.",
360
401
  behavior: [
402
+ "ÇERÇEVE TABANDA VARDIR: tema her container'a kart yüzeyi (1px --ng-border-primary çerçeve) verir. Tasarımda çerçevesi olmayan kutu için container DEĞİL box kullan. container zorunluysa çerçeveyi surfaceStyle ile kapat — { borderTop:'none', borderRight:'none', borderBottom:'none', borderLeft:'none' } (zemin de istenmiyorsa background:'transparent'); style'a ham border yazma. Düzen kaplarında bu yapılmazsa ekran iç içe çerçevelerle çizilir (kullanıcı bildirimi, qm qms-dokumanlar 2026-09-30; platform_guide('page') §Kap seçimi).",
361
403
  "states.isWrapper:true iken salt düzen elemanıdır: title ve __header bloğu ÇİZİLMEZ, zemin/çerçeve taşımaz ve gövdesi dolgusuzdur — kart başlığı gerekiyorsa içine text komponenti koy (platform_guide('page') Bilinen sınırlar). Bu kip artık bileşenin kendi CSS'inde: tipli alanlar (surfaceStyle) sayfa köküne de zemin/çerçeve verebilir.",
362
404
  "KATMAN SIRASI (K4): tema componentStyles → $preset TABANDIR; tipli grup alanları temayı alan alan EZER; düğümün serbest style'ı SON SÖZDÜR. Yüzey/tipografi/hover/başlık kararlarını style'a ham CSS olarak yazma — alanı varsa gruba yaz.",
363
405
  "BAŞLIK BANDI title YA DA description doluyken çizilir (2026-09-18): description başlığın altındaki ikinci satırdır (ikincil metin rengi, küçük punto) ve yalnız açıklama yazmak da bandı açar. İki alan da KIRPILIR: yalnız boşluktan ibaret bir başlık/açıklama doldurulmamış sayılır ve bant açılmaz. states.isWrapper:true iken ikisi de çizilmez.",
@@ -371,7 +413,7 @@ export const componentKnowledge = {
371
413
  "layout:'grid' iken diğer altı prop okunmaz — Studio panelinde de gizlenir. Katalogda tanımlı oldukları için doğrulama duvarı susar: ızgara kapsayıcıya direction yazmak sessizce hiçbir şey yapmaz (gateway PAGE-015 ile uyarır).",
372
414
  "Katalog varsayılanı 2026-08-25'te grid → FLEX oldu ama varsayılan düğüm KURULURKEN props'a yazılır (Studio bırakma yolu definition.defaults'u kopyalar), renderer'da geriye dönük bir etkisi YOKTUR: layout prop'u hiç olmayan düğüm — bütün eski kayıtlar — ızgara çizilmeye devam eder. Yani şemayı sen kuruyorsan varsayılana güvenme, layout'u açıkça yaz.",
373
415
  "YERLEŞİM (layout) KURARKEN DE TERCİH EDİLEN KAPTIR: layout views'ü sıradan bir komponent ağacıdır ve kökü container'dır — Studio'nun VARSAYILAN layout iskeleti (getDefaultLayout, 2026-09-29) kökü böyle kurar: states.isWrapper:true + appearance.heightType:'fill' + block x0/w12 (sayfanın page_container'ının yerleşim ikizi: çerçevesiz, başlıksız, ekranı dolduran); içinde navigations sol menü, menünün İÇİNDE ana sütun container'ı (column) → üst şerit container'ı + içerik container'ı → slot. Yeni kabukta önce ngapps://examples/layout-app-shell'i kullan, sonra özelleştir. layout monoliti ve layout-shell/layout-region ikilisi emekliye ayrıldı (platform_guide('layout')).",
374
- "MOBİL TUZAĞI — flex çocukları telefonda ALT ALTA DÜŞMEZ: runtime'ın mobil kuralı yalnız ızgara özelliklerini ezer (RenderComponent.svelte, @media max-width:767px → grid-row/grid-column/height), flex çocuğu genişliğini getFlexChildStyle'ın flex-basis'inden alır ve flex-wrap:nowrap altında satır bozulmaz. 375px'te ölçüldü: aynı span'lerle ızgara kabın çocukları 375/375px alt alta, flex kabınkiler 49/310px yan yana. Telefonda yığılması gereken satır için layout:'grid' kullan; wrap artık varsayılan açık (2026-09-01) ama sarma yalnız sığmayan çocuğu alta atar, ızgara yığılmasının yerini tutmaz (zeyrek-frontend docs/issues.md ARC-031)."
416
+ "DAR EKRAN TUZAĞI — flex çocukları telefon genişliğinde ALT ALTA DÜŞMEZ: runtime'ın dar ekran kuralı yalnız ızgara özelliklerini ezer (RenderComponent.svelte, @media max-width:767px → grid-row/grid-column/height), flex çocuğu genişliğini getFlexChildStyle'ın flex-basis'inden alır ve flex-wrap:nowrap altında satır bozulmaz. 375px'te ölçüldü: aynı span'lerle ızgara kabın çocukları 375/375px alt alta, flex kabınkiler 49/310px yan yana. Telefonda yığılması gereken satır için layout:'grid' kullan; wrap artık varsayılan açık (2026-09-01) ama sarma yalnız sığmayan çocuğu alta atar, ızgara yığılmasının yerini tutmaz (zeyrek-frontend docs/issues.md ARC-031)."
375
417
  ],
376
418
  propNotes: {
377
419
  surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens + " Kapsayıcının TABANI tema token'larıdır (--ng-background-surface zemin, 1px --ng-border-primary çerçeve, --ng-rounded köşe); alan boş bırakılırsa tema izlenir. contentOverflow gövdeye ('&__body') yazılır.",
@@ -396,24 +438,20 @@ export const componentKnowledge = {
396
438
  repeater: {
397
439
  summary: 'Kart listesi: rows dizisindeki her satır için children şablonunu yineler, satırları columnCount kolonlu bir ızgaraya dizer; satır bağlamı item/Row (sırası RowIndex) olarak çocuklara iner.',
398
440
  behavior: [
399
- "SEÇİM İKİ YOLDAN YAZILIR, ikisi de self.selectedIndex'e: (1) satırın HERHANGİ bir yerine tıklama — her tıklamada `select`, satır değiştiyse önce `change`; (2) satırdaki bir çocuğun yaydığı olay (buton click, girdi change/focus…) — satır değiştiyse `change`. Yalnız text/image taşıyan kart da tıklamayla seçilir (2026-09-15'ten önce ancak olay yayan bir çocukla seçilebiliyordu). İSTİSNA: tıklamayı kendisi yutan etkileşimli çocuklar (dropdown-button, collapsible-container, tarih seçici, dosya girdileri, tree-view, table; tag-input'ta yalnız çipler, çip silme ve temizle düğmesi — metin alanına tıklamak satırı SEÇER) satıra ulaştırmaz — orada select gelmez, seçim yalnız o çocuk olay yayarsa change ile yazılır. Etikete tıklamak (switch/checkbox/radio) tek tıklama sayılır. select ya da change olayına bir akış bağlıysa satırlar cursor:pointer gösterir (akışsız olayda ya da hiç olay yoksa imleç değişmez); tasarımcının style'ı ezer. Satırdaki butona tıklanınca akışların BAŞLAMA sırası: repeater `change` → butonun click akışı → repeater `select` (akışlar asenkron, bitiş sırası garanti değil); butonun akışında <repeater>.selectedIndex zaten o satırdır. Butonun akışı satırı SİLER ya da selectedIndex'e null yazarsa, ardından gelen select eski sırayla yayılır ve selectedIndex'i yeniden yazar — silme/temizleme akışını butona bağla, repeater'ın select'ine iş bağlama.",
400
- "SEÇİLİ SATIRIN VERİSİ `selectedItem`'dır (şema prop'u DEĞİL, runtime türetir): `{{ <repeater>.selectedItem.<alan> }}` ve akışta self.selectedItem. selectedIndex yazılmamışken İLK SATIRI (rows[0]) döndürür — 'henüz seçim yok' ile 'ilk satır seçili'yi ayırmak için selectedIndex'e bak (sayı değilse seçim yok). selectedIndex bir sayıdır; bir girdiden gelen \"1\" gibi tam sayı metni de sayı sayılır (ölçüldü: \"1\" → rows[1]). Boş, \"abc\", \"1.5\" ve ondalık/üslü metin 'seçim yok'tur ve rows[0] döner. rows yenilenince selectedIndex SIFIRLANMAZ; eski sıra yeni listede başka satırı gösterebilir, gerekiyorsa sorgu akışında selectedIndex'i null yaz. Silme akışı son satırı silerse selectedIndex artık listenin dışında kalır ve selectedItem TANIMSIZ olur (ilk satıra düşmez): silmeden sonra selectedIndex'i düzelt ya da null yaz.",
441
+ "SEÇİM İKİ YOLDAN YAZILIR, ikisi de self.selectedIndex'e: (1) satırın HERHANGİ bir yerine tıklama — her tıklamada `select`, satır değiştiyse önce `change`; (2) satırdaki bir çocuğun yaydığı olay (buton click, girdi change/focus…) — satır değiştiyse `change`. Yalnız text/image taşıyan kart da tıklamayla seçilir (2026-09-15'ten önce ancak olay yayan bir çocukla seçilebiliyordu). İSTİSNA: tıklamayı kendisi yutan etkileşimli çocuklar (dropdown-button, collapsible-container, tag-input, tarih seçici, dosya girdileri, tree-view, table) satıra ulaştırmaz — orada select gelmez, seçim yalnız o çocuk olay yayarsa change ile yazılır. Etikete tıklamak (switch/checkbox/radio) tek tıklama sayılır. Satırdaki butona tıklanınca akışların BAŞLAMA sırası: repeater `change` → butonun click akışı → repeater `select` (akışlar asenkron, bitiş sırası garanti değil); butonun akışında <repeater>.selectedIndex zaten o satırdır. Butonun akışı satırı SİLER ya da selectedIndex'e null yazarsa, ardından gelen select eski sırayla yayılır ve selectedIndex'i yeniden yazar — silme/temizleme akışını butona bağla, repeater'ın select'ine iş bağlama.",
442
+ "SEÇİLİ SATIRIN VERİSİ `selectedItem`'dır (şema prop'u DEĞİL, runtime türetir): `{{ <repeater>.selectedItem.<alan> }}` ve akışta self.selectedItem. selectedIndex yazılmamışken İLK SATIRI (rows[0]) döndürür — 'henüz seçim yok' ile 'ilk satır seçili'yi ayırmak için selectedIndex'e bak (sayı değilse seçim yok). rows yenilenince selectedIndex SIFIRLANMAZ; eski sıra yeni listede başka satırı gösterebilir, gerekiyorsa sorgu akışında selectedIndex'i null yaz.",
401
443
  "rows dizi DEĞİLSE (henüz koşmamış sorgu, null yazan akış) liste boş çizilir, sayfa düşmez; aynı _id/id'yi taşıyan satırlar da çizilir AMA çocuk girdilerin satır başına değerleri o kimliğe göre tutulduğu için bu satırlar yazılan değeri PAYLAŞIR — girdi taşıyan kartlarda id'ler benzersiz olmalı. Boş liste için ayrı bir emptystate bileşeni koy ve isHidden'ını `{{ (<repeater>.rows || []).length > 0 }}` yap — repeater'ın kendi boş durum metni yok.",
402
- "Izgara: columnCount kolon (en az 1; katalog varsayılanı 5, yazılmamış eski düğüm 1), kartlar arası dikey boşluk verticalSpacing (px; katalog varsayılanı 12, yazılmazsa 20), yatay boşluk horizontalSpacing (px; katalog varsayılanı 12, yazılmazsa 0). autoRowSize:false iken bütün satırlar EN UZUN kart kadar yüksek (1fr); true iken her satır kendi içeriği kadar. Boş/null boşluk varsayılana düşer. Kolonlar eşit paydır (minmax(0, 1fr)): uzun bir başlık kolonu genişletmez, taşarsa Text'in kendi wordBreak / lineClamp prop'uyla kes.",
444
+ "Izgara: columnCount kolon (en az 1; katalog varsayılanı 5, yazılmamış eski düğüm 1), kartlar arası dikey boşluk verticalSpacing (px; katalog varsayılanı 12, yazılmazsa 20), yatay boşluk horizontalSpacing (px; katalog varsayılanı 12, yazılmazsa 0). autoRowSize:false iken bütün satırlar EN UZUN kart kadar yüksek (1fr); true iken her satır kendi içeriği kadar. Boş/null boşluk varsayılana düşer.",
403
445
  "KARTIN İÇİ container ailesiyle AYNI yedi yerleşim prop'uyla dizilir (2026-09-29): layout ('flex' | 'grid', katalog varsayılanı 'flex') + direction/horizontalAlign/verticalAlign/size/gap/wrap — anlamları container kaydındakiyle birebir; TEK FARK direction varsayılanının 'column' olması (kart dikey yığındır). Satır (row) akışında heightType:'fill' yalnız align-self:stretch'tir ve wrap açıkken kısa kart hücreyi doldurmaz — eşit boylu kartlar için column kullan. Her satırın kartı ayrı bir .ng-app__node-children sarmalıdır ve bu düzeni giyer; çocuklar blocks[].position sırasıyla (önce y, sonra x) akar ve flex çocuk sözleşmesini (appearance.widthType/heightType, spacer mode) alır. Kartların KENDİ dizilişi (kaç kolon, aralarındaki boşluk) hâlâ columnCount/verticalSpacing/horizontalSpacing'tir. layout prop'u hiç yazılmamış eski repeater'ın kartı 12 kolon ızgara kalır.",
404
- "KART İÇERİĞİ HÜCREYİ VARSAYILANDA DOLDURMAZ: hücre en uzun kart kadardır ama karttaki container kendi yüksekliğinde kalır (heightType:fill etkisiz), kısa kartın altında boşluk kalır. Arka planı/gölgesi/kenarlığı olan kartlarda cardFill:true yaz: satır sarmalayıcısını flex yapıp düğümü ve kutusunu hücreye yayar (ölçüldü: kısa kart 146px → hücre kadar 326px). cardFill kapalıyken hiçbir şey değişmez.",
405
- "SEÇİLİ SATIR GÖRÜNÜMÜ: seçili satırın sarmalayıcısı aria-current=\"true\" ve data-selected=\"true\" taşır (seçim yokken hiçbir satırda yok — selectedItem rows[0] dönse de ilk satır işaretlenmez). Repeater'ın style'ında `& > [data-selected=true]` ile stille: zemin, kenarlık, outline, opacity (ölçüldü: yalnız tıklanan satırda outline 4px + opacity 0.6). Kartın İÇİNDEKİ bir bileşen seçiliyi bilmek zorundaysa isHidden'ı `{{ typeof <repeater>.selectedIndex === 'number' && <repeater>.selectedItem.id === item.id }}` yaz (bu koruma yalnız selectedIndex gerçek sayı olarak yazılıyorsa doğrudur; akış metin yazıyorsa orada Number(...) ile çevir — satır işaretleri ikisini de kabul eder).",
406
446
  "Studio'ya bırakılan YENİ repeater dolu doğar: 10 görselli örnek satır (id, image, title, category, price, description; satırda 5 kart, iki tam sıra) ve tek bir kart şablonu — tema yüzeyli bir container (layout flex, direction column, gap small; appearance widthType/heightType 'fill') içinde image (240px kapak), kategori, başlık (1 satır), açıklama (2 satır), esnek spacer (mode 'flex' — fiyatı ve butonu kartın tabanına iter), fiyat ('{{ item.price }} ₺') ve buton (kind 'info'). Şemayı sen kuruyorsan bu şablon GELMEZ: kartı children olarak yaz; kartın içindeki her parçaya appearance.widthType:'fill' ver — sütun akışında genişliği yazılmamış çocuk 12 kolon payına düşer ve o pay sütunda yükseklik anlamına gelir."
407
447
  ],
408
448
  propNotes: {
409
449
  surfaceStyle: NODE_SURFACE_NOTE,
410
- rows: "Yinelenen veri; çocuk komponent ifadelerinde satıra item / Row ile, satırın sırasına RowIndex ile (0'dan başlar) erişilir. Satırlara kalıcı ve BENZERSİZ bir id ya da _id ver: girilen değerler ve kart örnekleri ona göre eşlenir. Düz tipli öğeler (null, sayı, metin, iç içe dizi) statik rows olarak yazılamaz (platform 500) — `{{ }}` ifadesiyle ver; bozuk öğe kartı boş çizer, sayfa düşmez.",
411
- style: "Repeater'da `&__parça` YOKTUR; `style` ızgara elemanının kendisine yazılır (kök özellikler: background, padding, border, borderRadius, maxWidth, overflow…). Kartlar için satır sarmalayıcısını hedefle: `& > div` (= `& > .ng-app__node-children`), `& > div:nth-child(odd)`, `& > div:hover`, `& > div:focus-within`, `& > div::before` (içerik kartın içinde yer tutar; ölçüldü: `content: '>>'` kartı 48px'ten 62px'e uzattı), `&:hover`. `gap` yazmak verticalSpacing ve horizontalSpacing'i birlikte ezer; `display:flex` ızgarayı düşürür — boşluk ve kolon için kendi prop'larını kullan. @media içindeki kural taban kuralın önüne düşebilir (aynı özgüllükte taban kazanır): medya içinde `&&` ile özgüllüğü artır (`@media (max-width: 480px)` > `&&` > { gridTemplateColumns: 'repeat(2, minmax(0, 1fr))' }).",
450
+ rows: "Yinelenen veri; çocuk komponent ifadelerinde satıra item / Row ile, satırın sırasına RowIndex ile (0'dan başlar) erişilir. Satırlara kalıcı bir id ya da _id ver: girilen değerler ve kart örnekleri ona göre eşlenir.",
412
451
  columns: "YALNIZ Studio'daki Rows düzenleyicisinin alanlarını tanımlar; runtime OKUMAZ. Kartta ne görüneceğini repeater'ın children'ı ve onların `{{ item.<alan> }}` ifadeleri belirler — columns yazmak kartı değiştirmez.",
413
452
  columnCount: 'Bir satırdaki kart sayısı (tam sayı, en az 1; 0/boş 1 sayılır). Katalog varsayılanı 5 (2026-09-29).',
414
453
  verticalSpacing: 'Kart satırları arası boşluk, px. Yazılmazsa 20 (bileşen varsayılanı; 2026-09-15 öncesi yazılmamış düğüm 0 çiziyordu); yeni düğümün katalog varsayılanı 12 (2026-09-29).',
415
454
  horizontalSpacing: 'Yan yana kartlar arası boşluk, px. Yazılmazsa 0; katalog varsayılanı 12 (2026-09-29).',
416
- cardFill: 'Kart içeriği (container) hücrenin tamamını doldursun: kısa kartın altında boşluk kalmaz. Varsayılan kapalı; arka planı/gölgesi/kenarlığı olan kartlarda aç. autoRowSize ile birlikte de çalışır (hücre yüksekliği satırın en uzun kartıdır).',
417
455
  layout: "KARTIN İÇİ: '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 aynı.",
418
456
  selectedIndex: "Tıklanan/olay yayan satırın sırası (0'dan). Runtime `change` ve `select` ile yazar; akışta self.selectedIndex, başka bileşende `{{ <repeater>.selectedIndex }}`. Şemada gizli durum prop'udur (panelde çizilmez); akış yazarak seçimi değiştirebilir ya da null yazıp temizleyebilir. Seçili satırın verisi için behavior'daki selectedItem maddesine bak."
419
457
  }
@@ -421,98 +459,69 @@ export const componentKnowledge = {
421
459
  modal: {
422
460
  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.',
423
461
  behavior: [
424
- "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). Kapat düğmesi, perdeye tıklama ve Esc isOpen'ı KENDİSİ false yapar; close bu yollardan ve akıştan yazılan isOpen=false'tan BİR KEZ çalışır (2026-10-05'e kadar kullanıcı kapatışında iki kez çalışıyordu). open yalnız açılışta çalışır: sayfa yüklenirken isOpen zaten true ise open koşmaz. isOpen hiç yazılmadıysa {{ modal.isOpen }} ilk açılışa kadar undefined okur — {{ !!modal.isOpen }} yaz.",
425
- "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ı blocks[].size'ı hiçbir eksende DENETLEMEZ (boyut sınırı kanvasın kuralıdır) — 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.",
426
- "Panel PORTAL ile düğüm kutusunun DIŞINA çizilir: surfaceStyle ve style panelin kendisine (.ng-modal) uygulanır, düğüm kutusuna değil. Kullanılabilir style parçaları: &__header, &__title, &__description, &__close (kapat düğmesi), &__body, &__footer, &__actions (düğme grubu), &__overlay (arkadaki perde); kökte :hover, :focus-within, ::before/::after, @media çalışır. Alta yapışık sayfa gibi yerleşim için kökte top/left/bottom/transform/width yaz (kök left:50% top:50% translate(-50%,-50%) ile ortalanır; 767 px ve altındaki %90 genişlik kuralı style.width'e yenilir). Altlık düğmelerini boyamak için '&__actions button' ve '& .ng-button--outline' gibi iç içe seçiciler çalışır (actions[]'ta düğme stili alanı yok); odak halkası için '&__actions button.ng-button:focus-visible' yaz, bileşenin kendi odak kuralı yoksa yeniler. style/surfaceStyle ve eski appearance alanları 2026-10-05'ten önce modalda HİÇBİR ŞEYE inmiyordu; kayıt defteri eski kalmışsa page_schema_patch style'ı unknown-prop diye reddeder (components-sync çalıştır).",
427
- "Boyut: size small 600, medium 800, large 1400 px; panel ekrandan en fazla iki kenar boşluğu kadar dar tutulur (large 1280 px'te ekrana sığar) ve yüksekliği ekranı aşmaz — gövde (max 600 px) kendi içinde kayar, başlık ve aksiyonlar görünür kalır. 767 px ve altında genişlik %90 (style.width ile ezilebilir). Başlık ve açıklama boşluksuz uzun metinde satıra kırılır; bu başlık sütunu ekran yüksekliğinin %40'ında durur ve kendi içinde kayar (çok uzun başlık kısa ekranda gövdeyi ve altlığı dışarı itmez; kapat düğmesi sütunun yanında sabittir); açıklamadaki satır sonları (\\n) korunur; aksiyon düğmesi metni uzunsa düğme içinde sarılır. title/description metin değilse (nesne, dizi, true/false, NaN) ya da çözülmemiş {{ }} ise BOŞ sayılır; boş başlıkta başlık satırı çizilmez.",
428
- "isLoading gövdeyi bir yükleniyor göstergesiyle örter ve aksiyonları kilitler ama çocukları SÖKMEZ: yazılmış form değerleri kalır, pencere boyu zıplamaz, yükleme bitince odak yüklemeden önceki elemana döner. (2026-10-05'ten önce gövde ve altlık DOM'dan sökülüyordu.) Yükleme bir aksiyonun düğmesinde gösterilecekse aksiyonun kendi isLoading'ini kullan.",
429
- "Çocuklar 12 kolonlu ızgarada konumlanır (blocks.position), akış değil: add_component ile birden çok çocuk eklerken hepsi y:0 alır ve üst üste biner. İçeriği tek bir flex container (ya da form) içine koyup onu ekle; modalın doğrudan çocuğu bir container olsun.",
430
- "Klavye ve erişilebilirlik: role=dialog, adı title; aria-modal bilerek YOK (portal'daki seçim listeleri pencerenin dışında kalır). Açılışta odak kapat düğmesine (yoksa ilk odaklanabilir öğeye) gelir, Tab pencere içinde döner, kapanınca odak açan öğeye döner; Esc yalnız EN ÜSTTEKİ katmanı kapatır (iç içe modal/drawer'da sırayla). Pencere içinde açık bir dropdown/multi-select varken ilk Esc yalnız listeyi kapatır, sonraki Esc pencereyi kapatır (2026-10-05'e kadar alan kapalı listede de her Esc'yi tüketiyor, pencere klavyeyle kapanmıyordu). Açıkken sayfa kaydırması kilitlenir ve kapanınca sayfanın önceki değeri geri gelir.",
431
- "Altlık aksiyonları pencerenin BİTİŞ kenarına yaslanır (LTR'de sağ, ar/RTL'de sol); RTL'de başlangıca almak için style &__footer { justifyContent: 'flex-start' } yaz. Aksiyonlarda flow değeri { type: 'flow', ref: <akış kimliği> } sarmalıdır; type: 'submit' aksiyonu formId'deki formu gönderir ve kendi flow'unu ÇALIŞTIRMAZ (akışı formun submit olayına bağla), type: 'button' kendi flow'unu çalıştırır."
462
+ "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).",
463
+ "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ı blocks[].size'ı hiçbir eksende DENETLEMEZ (boyut sınırı kanvasın kuralıdır) — 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."
432
464
  ],
433
- propNotes: {
434
- surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens +
435
- " Modalda yüzey PANELİN kökünde derlenir (portal'dan dolayı düğüm kutusu yoktur); contentOverflow panelin KÖKÜNE iner (hidden → başlık bandı gibi taşan çocuklar panelin yuvarlak köşelerinde kırpılır); gövde zaten kendi içinde kayar (max 600 px), başlık ve aksiyonlar kaydırılmaz.",
436
- style: STYLE_GROUP_NOTES.styleEscape +
437
- " Modalda parçalar: &__header, &__title, &__description, &__close, &__body, &__footer, &__actions, &__overlay. Sınıf adları ng-modal / ng-modal__header / ng-modal-body / ng-modal-footer / ng-modal__overlay olduğundan '& .ng-modal-body p' gibi iç içe seçici de yazılabilir ama parça adları kalıcı sözleşmedir.",
438
- size: "small 600 · medium 800 · large 1400 px; ekran dar ise ekrana sığar, 767 px ve altında %90.",
439
- isLoading: 'Gövdeyi yükleniyor göstergesiyle örter ve aksiyonları kilitler; çocuklar yerinde kalır (form değerleri silinmez). Pencere boyu değişmez.',
440
- isDismissDisabled: 'Kapat düğmesini gizler; perdeye tıklama ve Esc de kapatmaz — pencereden yalnız aksiyonlarla çıkılır. close olayı bu yollardan yayılmaz.'
441
- }
465
+ propNotes: { surfaceStyle: NODE_SURFACE_NOTE }
442
466
  },
443
467
  drawer: {
444
468
  summary: 'Yandan açılan katman; modal ile aynı kurallar: şema kökünde yaşar, kendi children ve akışlarını taşır.',
445
- behavior: [
446
- "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). Kapat düğmesi, perdeye tıklama ve Esc isOpen'ı KENDİSİ false yapar; close bu yollardan ve akıştan yazılan isOpen=false'tan TAM BİR KEZ çalışır. open yalnız açılışta çalışır: sayfa yüklenirken isOpen zaten true ise open koşmaz. isOpen hiç yazılmadıysa {{ drawer.isOpen }} ilk açılışa kadar undefined okur — {{ !!drawer.isOpen }} yaz.",
447
- "Kaplama çerçevesidir (isFrame): kanvasta blok tutmaz, kökte (parent null) herhangi bir { w, h } ile eklenir; boyut denetimi modal ile aynıdır.",
448
- "Panel PORTAL ile düğüm kutusunun DIŞINA çizilir (kök drawer düğümünün kendi kutusu DOM'da YOKTUR): surfaceStyle ve style panelin kendisine (.ng-drawer) uygulanır. 2026-10-05'ten önce ikisi de HİÇBİR ŞEYE inmiyordu ve style şemada yoktu; kayıt defteri eski kalmışsa page_schema_patch style'ı unknown-prop diye reddeder (components-sync çalıştır). Kullanılabilir style parçaları: &__header, &__title, &__description, &__close (kapat düğmesi), &__body, &__footer, &__actions (düğme grubu; sol ve sağ grup ikisi de), &__overlay (arkadaki perde); kökte :hover, :focus-within, ::before/::after, @media çalışır. Kenardan boşluklu yüzen panel için kökte top/right/bottom/height yaz (kök left:0 top:0 height:100vh ile sabittir). Altlık düğmelerini boyamak için '&__actions button' ve '& .ng-button--outline' gibi iç içe seçiciler çalışır (actions[]'ta düğme stili alanı yok); odak halkası için '&__actions button.ng-button:focus-visible' yaz. Altlık düğmelerinin sınıfları: .ng-button--solid / --text / --outline ve kind için .ng-button--primary|info|success|warning|error; menülü aksiyonun düğmesi '.dropdown-menu__button'. Yalnız sağ kenarda açılan panele özel stil için '&.ng-drawer--right' yaz ('&--right' tutmaz). Kökün varsayılan padding'i 20px'tir (padding: 0 ile başlık bandı kenardan kenara alınır); kapat düğmesi varsayılan 35x35 px'tir (dokunma hedefi için &__close ile büyüt). Harf aralığı (letterSpacing) altlık düğmesinin ikon ligatürünü bozabilir (ikon adı harf harf görünür): onu '&__title' gibi yalnız metin parçasına yaz, '&__actions button'a değil. PascalCase Webkit* anahtarları sessizce düşer (kebab/camelCase backdropFilter yaz).",
449
- "Boyut: size default 400, medium 600, large 800, x-large 1120, 2x-large 1280 px, full tüm ekran; panel ekrandan GENİŞ olmaz (1024 px'te 2x-large 1024'e iner; 2026-10-05'e kadar 256 px taşıyor, kapat düğmesi ekran dışında kalıyordu). 767 px ve altında genişlik %90 (style.width ile ezilebilir). Yükseklik her zaman ekranın tamamıdır; gövde kendi içinde kayar, başlık ve altlık sabit kalır. Başlık ve açıklama boşluksuz uzun metinde satıra kırılır; açıklamadaki satır sonları (\n) korunur; aksiyon düğmesi metni uzunsa düğme içinde sarılır. title/description metin değilse (nesne, dizi, true/false, NaN) ya da çözülmemiş {{ }} ise BOŞ sayılır; sayı yazı olarak çizilir (0 → '0'); boş başlıkta başlık satırı çizilmez.",
450
- "position fiziksel kenardır: left sol, right sağ; geçersiz/boş değer left'tir. Arapça/RTL sayfada panel AYNALANMAZ (left yine soldan açılır); kapat düğmesi ve altlık grupları ise mantıksaldır. RTL'de panelin başlangıç kenarından açılmasını istiyorsan position'ı dile göre sen seç.",
451
- "isLoading gövdeyi bir yükleniyor göstergesiyle örter ve aksiyonları kilitler ama çocukları SÖKMEZ: yazılmış form değerleri kalır, panel düzeni zıplamaz, altlık yerinde durur (görünmez + kilitli), yükleme bitince odak yüklemeden önceki elemana döner. (2026-10-05'ten önce gövde ve altlık DOM'dan sökülüyor, gövde 200 px'e düşüyordu.) Yükleme bir aksiyonun düğmesinde gösterilecekse aksiyonun kendi isLoading'ini kullan.",
452
- "Çocuklar 12 kolonlu ızgarada konumlanır (blocks.position), akış değil: add_component ile birden çok çocuk eklerken hepsi y:0 alır ve üst üste biner. İçeriği tek bir flex container (ya da form) içine koyup onu ekle.",
453
- "Klavye ve erişilebilirlik: role=dialog, adı title; aria-modal bilerek YOK (portal'daki seçim listeleri panelin dışında kalır). Açılışta odak kapat düğmesine gelir, Tab panel içinde döner (Select/MultiSelect girdisinden de çıkmaz), kapanınca odak açan öğeye döner; Esc yalnız EN ÜSTTEKİ katmanı kapatır. Panel içinde açık bir dropdown/multi-select listesi ya da açılır menülü aksiyonun menüsü varken ilk Esc yalnız onu kapatır, sonraki Esc paneli kapatır. Menülü aksiyondan bir seçenek seçilince menü kapanır ve odak o aksiyonun menü düğmesine döner (panel dışına, sayfaya düşmez). Perdede mousedown odağı çalmaz. prefers-reduced-motion: reduce iken kayma animasyonu (giriş ve çıkış) çalışmaz. Açıkken sayfa kaydırması kilitlenir ve kapanınca sayfanın önceki değeri geri gelir. Perde panelle birlikte gider ve arkadaki sayfaya tıklamayı yutar: panel açıkken başka bir satıra tıklamak yalnız paneli kapatır.",
454
- "Altlık aksiyonları position'a göre iki gruba ayrılır: position 'left' olan sol, DİĞERLERİ (yazılmayan dahil) sağ grupta çizilir; aksiyonun bildirilen varsayılanı 'right'tır (2026-10-05'e kadar sözlük 'left' diyordu ama çalışma anı yazılmayanı sağa koyuyordu). Sola almak için position: 'left' yaz. Sarma olursa sağ grup kendi satırında sağa yaslanır. Aksiyonlarda flow değeri { type: 'flow', ref: <akış kimliği> } sarmalıdır; type: 'submit' aksiyonu formId'deki formu gönderir (formId bir bileşen adı ya da elementId'dir; düğümün iç GUID'i çözülmez) ve kendi flow'unu ÇALIŞTIRMAZ, type: 'button' kendi flow'unu çalıştırır.",
455
- "options dolu aksiyon açılır menü olur (optionsTitle başlık): seçilen SEÇENEĞİN kendi flow'u çalışır, seçenekte flow yoksa aksiyonun flow'u; currentItem seçenektir (key ile dallanabilirsin). 2026-10-05'e kadar seçeneğin flow'u HİÇ çalışmıyor, hep aksiyonunki çalışıyordu. isDisabled seçenek tıklanmaz, isHidden çizilmez, isDanger kırmızı çizer. Menü panelin üstünde açılır ve kırpılmaz."
456
- ],
457
- propNotes: {
458
- surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens +
459
- " Drawer'da yüzey PANELİN kökünde derlenir (portal'dan dolayı düğüm kutusu yoktur); contentOverflow panelin KÖKÜNE iner (hidden → başlık bandı gibi taşan çocuklar panelin yuvarlak köşelerinde kırpılır); gövde zaten kendi içinde kayar, başlık ve aksiyonlar kaydırılmaz.",
460
- style: STYLE_GROUP_NOTES.styleEscape +
461
- " Drawer'da parçalar: &__header, &__title, &__description, &__close, &__body, &__footer, &__actions, &__overlay. Sınıf adları ng-drawer / ng-drawer__header / ng-drawer-body / ng-drawer-footer / ng-drawer__overlay olduğundan '& .ng-drawer-body p' gibi iç içe seçici de yazılabilir ama parça adları kalıcı sözleşmedir.",
462
- size: "default 400 · medium 600 · large 800 · x-large 1120 · 2x-large 1280 px · full tüm ekran; ekran dar ise ekrana sığar, 767 px ve altında %90.",
463
- position: "Fiziksel kenar: left | right (varsayılan left). RTL'de aynalanmaz.",
464
- isLoading: 'Gövdeyi yükleniyor göstergesiyle örter ve aksiyonları kilitler; çocuklar yerinde kalır (form değerleri silinmez). Panel düzeni değişmez.',
465
- isDismissDisabled: 'Kapat düğmesini gizler; perdeye tıklama ve Esc de kapatmaz — panelden yalnız aksiyonlarla çıkılır. close olayı bu yollardan yayılmaz.'
466
- }
469
+ propNotes: { surfaceStyle: NODE_SURFACE_NOTE }
467
470
  },
468
471
  dropdown: {
469
472
  summary: 'Tek seçim listesi; options statik verilebilir ya da mount/search akışıyla uzaktan doldurulur.',
470
473
  behavior: [
471
474
  "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.",
472
475
  "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.",
473
- "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.",
476
+ "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 (panelin 'Seçimi temizle' düğmesi) de change yayar, ikisi de boş metin olur.",
474
477
  "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.",
475
- "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ı.",
478
+ "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. 2026-10-05'ten beri liste kapalıyken de tıklama ya da tuş paneli açar ve yükleniyor satırı görünür.",
476
479
  '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.',
480
+ "ALAN VE PANEL (2026-10-05, datatable'ın Connect Data ilişki alanıyla aynı görünüm): alan yazılan bir girdi DEĞİL, odaklanabilir bir kutudur — Tab ile gelinir, Enter/Space/↓/↑ paneli açar. Arama kutusu açılan panelin ÜSTÜNDEDİR ve açılınca odaklanır; 'Seçimi temizle' panelin altındadır (değer varken ve clearable açıkken). Seçim, Escape ve temizleme paneli kapatıp odağı alana geri verir; odak alandan (panel dahil) çıkınca panel kapanır. Alanda X yoktur ve Backspace değeri silmez. Tab ile alana gelmek focus yayar (bir kez); panelde Tab seçeneklerden geçmez (ok tuşları gezer); dışarı tıklamak paneli kapatır ve blur yayar. Salt okunur, görüntüleme ve devre dışı alan odak almaz.",
477
481
  "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.",
478
- "Tek doğrulama kuralı `required`'dır (2026-09-11; `pattern` bildirimi kaldırıldı, panelde hiç çizilemiyordu)."
482
+ "Tek doğrulama kuralı `required`'dır (2026-09-11; `pattern` bildirimi kaldırıldı, panelde hiç çizilemiyordu).",
483
+ "LOOKUP (2026-10-05, ADR 0007): Connect Data ile entity'ye bağlı ve tanımın kök `lookup`'ı açıkken (bağlama `lookupMode` yazar) alanın sağında, chevron'un solunda ↗ çizilir; tıklayınca bileşenin KENDİ kaynağı lookup penceresinde (modal ya da sağ çekmece, `lookup.mode`) kolonlar, filtre çipleri, başlık sıralaması ve sayfalarla açılır. Satıra tıklamak seçer ve kapatır; yük normal seçimle aynı change { value, selectedLabel } (value, değer rolünün HAM değeri). Seçilen kayıt yüklü options'ta yoksa kutu etiketini yine gösterir. Ana tanımın filtresi pencerede de geçerlidir. Kanvasta, salt okunur/görüntüleme/devre dışı kipte ↗ yoktur; pencere açıkken blur yayılmaz, kapanınca odak ↗'ye döner. Açmak/kapatmak: connect_data_bind { lookup } ya da studio çekmecesi; yeni bağlamada açık gelir."
479
484
  ],
480
485
  propNotes: {
481
486
  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).",
482
487
  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.',
483
488
  optionType: "'single' düz liste, 'grouped' children ile ağaç. single'da children ve yanındaki iki bayrak hiç okunmaz.",
484
- clearable: 'Seçimi temizleyen X düğmesi (varsayılan açık). Temizleme change yayar, ayrı bir olay yoktur.',
489
+ clearable: "Panelin altındaki 'Seçimi temizle' düğmesi (varsayılan açık, yalnız değer varken çizilir). Temizleme change yayar, ayrı bir olay yoktur.",
485
490
  emptyText: 'Liste boşken gösterilen metin; boş bırakılırsa arayüz dilinden gelen "sonuç yok" metni kullanılır.',
486
491
  placeholder: 'Seçim yokken kutuda duran metin; aynı zamanda yükleniyor satırının metnidir.',
487
492
  searchText: "Gizli durum prop'u: bileşen OKUMAZ, `search` olayıyla yazar. Uzak aramada sorguyu akışta self.searchText ile oku.",
488
493
  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.",
489
- isLoading: 'Uzak arama/doldurma sürerken akıştan açılır; alan kilitlenmez, yalnız spinner ve yükleniyor satırı çizilir.'
494
+ lookupMode: "Gizli durum prop'u: Connect Data bağlaması her okumada yazar — tanımın kök `lookup`'ı açıksa 'modal' ya da 'drawer', kapalıysa 'none'. Bileşen alanın sağındaki ↗ lookup düğmesini yalnız bu 'none' değilken çizer; elle yazılmaz, lookup'ı tanımdaki kök `lookup` açar/kapatır.",
495
+ isLoading: 'Uzak arama/doldurma sürerken akıştan açılır; alan kilitlenmez, yalnız spinner ve yükleniyor satırı çizilir.',
496
+ loadError: "Salt okunur: Connect Data bağlantısının son okuma hatası (başarılı okuma temizler). Doluyken açılan liste 'sonuç yok' yerine bu metni gösterir — okuma izni yoksa (403) platformun yerelleştirilmiş 'Bu kaynağa erişim izniniz yok.' metni (39/02 U-2). Bağlı olmayan dropdown'da akış yazabilir."
490
497
  }
491
498
  },
492
499
  'multi-select': {
493
500
  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.',
494
501
  behavior: [
495
- "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.",
502
+ "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 (2026-10-01'e kadar gelmiyordu: akışın yazdığı id dizisi seçenekler yüklense de çipte id olarak kalıyordu).",
496
503
  "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).",
497
504
  "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.",
498
505
  '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.',
499
506
  "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.",
500
- '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).',
501
- '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.',
507
+ '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. 2026-10-05’ten beri liste kapalıyken de tıklama ya da tuş paneli açar ve yükleniyor satırı görünür.',
508
+ '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: çipe ya da chevron’a basmak odağı alandan çıkarmaz ve liste içinde gezinmek blur yaymaz. Alan terk edilince açık liste de kapanır.',
502
509
  '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.',
503
510
  "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.",
504
- '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).',
505
- "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. minItems/maxItems yazılırsa gateway min-length/max-length'e çevirir."
511
+ "ÇİPLER SARAR (2026-10-05, datatable'ın Connect Data ilişki alanıyla aynı görünüm): etiketin tamamı görünür, sığmayan çip alt satıra geçer ve alan büyür; '+n' rozeti, çipte X ve alanda X YOKTUR, Backspace bir şey silmez. Seçim panelde kutunun işareti kaldırılarak ya da panelin altındaki 'Seçimi temizle' ile kaldırılır. Arama kutusu panelin üstündedir ve açılınca odaklanır; her tıklama hemen yazar ve panel açık kalır (Uygula yok). Escape ve temizleme paneli kapatıp odağı alana verir. Tab ile alana gelmek focus yayar (bir kez); panelde Tab seçeneklerden geçmez (ok tuşları gezer); dışarı tıklamak paneli kapatır ve blur yayar. Salt okunur, görüntüleme ve devre dışı alan odak almaz.",
512
+ "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. minItems/maxItems yazılırsa gateway min-length/max-length'e çevirir.",
513
+ "LOOKUP (2026-10-05, ADR 0007): kök `lookup`'ı açık bağlı multi-select'te ↗ pencereyi ÇOKLU kipte açar — satıra tıklamak soldaki kutuyu işaretler, pencere açık kalır, Uygula tüm seçimi change { value: [{ value, label, id, text }] } olarak yazar (işaretlenme sırasıyla). Önceden seçilenler işaretli gelir ve ilk açılışta (süzülmeden, sıralanmadan, ilk sayfada) `ids` ile ayrıca okunup EN ÜSTTE durur. Escape değişikliği yazmadan kapatır. Kanvasta, salt okunur/görüntüleme/devre dışı kipte ↗ yoktur."
506
514
  ],
507
515
  propNotes: {
508
516
  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.",
509
517
  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.',
510
518
  optionType: "'single' düz liste, 'grouped' children ile ağaç. single'da children ve yanındaki iki bayrak hiç okunmaz.",
511
- 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.',
519
+ clearable: "Tüm seçimi temizleyen, panelin altındaki 'Seçimi temizle' düğmesi (varsayılan açık, yalnız seçim varken çizilir). Temizleme change yayar, ayrı bir olay yoktur.",
512
520
  emptyText: 'Liste boşken gösterilen metin; boş bırakılırsa arayüz dilinden gelen "sonuç yok" metni kullanılır.',
513
521
  placeholder: 'Hiç seçim yokken kutuda duran metin; aynı zamanda yükleniyor satırının metnidir.',
514
522
  searchText: "Gizli durum prop'u: bileşen OKUMAZ, `search` olayıyla yazar. Uzak aramada sorguyu akışta self.searchText ile oku.",
515
- isLoading: 'Uzak arama/doldurma sürerken akıştan açılır; alan kilitlenmez, yalnız spinner ve yükleniyor satırı çizilir.'
523
+ isLoading: 'Uzak arama/doldurma sürerken akıştan açılır; alan kilitlenmez, yalnız spinner ve yükleniyor satırı çizilir.',
524
+ lookupMode: "Gizli durum prop'u: Connect Data bağlaması her okumada yazar — tanımın kök `lookup`'ı açıksa 'modal' ya da 'drawer', kapalıysa 'none'. Bileşen alanın sağındaki ↗ lookup düğmesini yalnız bu 'none' değilken çizer; elle yazılmaz, lookup'ı tanımdaki kök `lookup` açar/kapatır."
516
525
  }
517
526
  },
518
527
  'tag-input': {
@@ -545,6 +554,7 @@ export const componentKnowledge = {
545
554
  "inputMask seçiliyse KULLANICININ yazdığı metin anında maskeye biçimlenir ve value biçimli hâlidir ('0(555) 123 45 67'); kullanıcı yazarken maske dışı karakterler sessizce düşer. Akıştan/kayıttan yazılan değer ise OLDUĞU GİBİ kalır (ekranda biçimli görünür). Form, biçimlenince hiçbir karakter kaybetmeyen ham değeri ('5551234567') kabul eder ve akışa HAM gönderir; karakter kaybettiren değer ('+905551234567', fazla hane, küçük harf) ile tarih/saat/son kullanma maskelerindeki ayraçsız değer 'Value does not match the selected input mask.' ile formu kilitler — o maskelere akıştan biçimli yaz. Ham rakam istiyorsan akışta ayıkla (2026-10-03)."
546
555
  ],
547
556
  propNotes: {
557
+ isMasked: "KORUMALI ALAN (f-31): value her zamanki gibi kaydın alanına bağlanır, isMasked yanına satır metasına: {{ Steps.<satırıOkuyanAdım>.data.__protected?.<alan> === 'masked' }}. true iken bağlı value maske metni sayılır ve GÖSTERİLMEZ: alan BOŞ başlar, yer tutucu uygulama dilinde 'Değiştirmek için yeni değer girin' olur (placeholder prop'u o sürece gösterilmez) ve mount SONRASI value null'a yazılır, maske metni düğümde kalmaz (tasarım kanvasında yazılmaz). Bu yazım şemada OLMAYAN 'maskCleared' emit'iyle yapılır — akış bağlanamaz, change/changed ÇALIŞMAZ. Kullanıcı yazınca sıradan girdidir; value girdinin yazmadığı bir değere dönerse (forma başka satır seçildi, akış alanı sıfırladı) yeni kaydın maskesi yine gizlenir ve null'a çekilir. Yalnız isMasked bağlamak da çalışır ama plain satırda da alan boş kalır. Boş değer yalnız microservice parametre bağında gövdeden DÜŞER (saklı değer korunur); akış kodunda ya da setter göreviyle elle kurulan gövdede null GİDER — canWrite yoksa 403 AccessFieldWriteDeniedException, varsa saklı değer SİLİNİR. Formda boş bırakılan maskeli alan required'a takılmaz. value'yu maskeli kayda bağlayıp isMasked vermemek maskeyi geri gönderir — yapma.",
548
558
  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.',
549
559
  inputMask: "Hazır maske anahtarı (pattern:/date:/time:/regex:…); serbest desen için 'custom:' öneki ('custom:(###) ###-####'). IBAN anahtarı 'iban:TR## #### #### #### #### #### #### ##' dizesi 28 # okunur ama deseni TR + 24 rakamdır (26 karakter); geçerli TR IBAN biçimlenir ve Form maske denetiminden geçer (2026-10-03).",
550
560
  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.",
@@ -858,7 +868,7 @@ export const componentKnowledge = {
858
868
  value: "Seçili dosya(lar). Panelde ÇİZİLİR ve akıştan yazılabilir (2026-09-17'ye kadar gizliydi, bu yüzden AI sözlüğünde de görünmüyordu): kayıtlı bir dosyayı forma geri basmanın yolu budur. Tekli kipte nesne, çoklu kipte dizi; boşaltmak için null (çoklu kipte []). Kipiyle uyuşmayan şekil de OKUNUR: çoklu kipte yazılan tek nesne listelenir, tekli kipte yazılan dizinin ilk dosyası çizilir (2026-09-17'ye kadar ikisi de sessizce hiçbir şey göstermiyordu). İçeriği olmayan kayıt (ne value ne data ne absolute_path) hiç çizilmez. Tasarımda value'ya drive dosyası BAĞLAMA ({ type:'file', ref:<fileId> } — Studio panelinin dosya seçicisi de bunu yazar): çalışma anı değeri { type:'file', ref, data:<URL> } olur, çip dosya adı yerine URL yazar ve kullanıcı dokunmadan kaydederse backend type:'file' kaydında yalnız value'yu okuduğu için tekil alan sessizce NULL'lanır (200 döner, mevcut dosya silinir; NOT NULL alanda 400 InvalidParameterException). Varsayılan dosya gerekiyorsa value'yu static ref nesnesi olarak ver: { type:'static', data:{ type:'ref', value:'<fileId>', fileName, absolute_path } } — çip adıyla çizilir, dokunmadan kayıt dosyayı yazar (ölçüldü 2026-10-02).",
859
869
  text: 'Butonun üzerindeki metin (varsayılan "Attach File"); ikon sabittir. Alanın başlığı ayrı bir prop\'tur: label.',
860
870
  description: 'Butonun altındaki yardım metni. Dosya seçilir seçilmez yerini dosya listesi alır, seçim temizlenince geri gelir (fileInput ile aynı kural).',
861
- allowedFiletypes: 'İzin verilen uzantılar (çoklu seçim, kapalı liste). Hem dosya diyaloğunun accept süzgecini hem de seçimden SONRAKİ denetimi besler: liste dışı bir dosya seçilirse değere girmez ve komponentin içinde "desteklenmiyor" uyarısı çizilir (2026-09-17; öncesinde yalnız diyalog süzgeciydi, "Tüm dosyalar" ile aşılabiliyordu). Hem allowedFiletypes hem customFiletypes boşsa her tür serbesttir.',
871
+ allowedFiletypes: 'İzin verilen uzantılar (çoklu seçim, kapalı liste). Hem dosya diyaloğunun accept süzgecini hem de seçimden SONRAKİ denetimi besler: liste dışı bir dosya seçilirse değere girmez ve komponentin içinde "desteklenmiyor" uyarısı çizilir (2026-09-17; öncesinde yalnız diyalog süzgeciydi, "Tüm dosyalar" ile aşılabiliyordu). Hem allowedFiletypes hem customFiletypes boşsa her tür serbesttir. Akış prop\'a düz metin yazabilir ("pdf,png", customFiletypes ile aynı ayraçlar) — 2026-09-25`e kadar bu komponenti `input.map is not a function` ile düşürüyordu (fileInput okuyordu).',
862
872
  customFiletypes: 'Listede olmayan uzantılar, serbest metin ("heic, dwg;psd"). Virgül, noktalı virgül ve boşluk ayraçtır; baştaki nokta ve yıldız atılır, büyük/küçük harf fark etmez. allowedFiletypes ile BİRLEŞİR, onun yerine geçmez (fileInput ile aynı ad ve aynı kural). Çok parçalı uzantı da yazılabilir ("tar.gz"): eşleşme adın SONUNA bakar, son noktadan sonrasına değil.',
863
873
  maxFileSizeMb: 'Dosya BAŞINA en büyük boyut (MB). Boş/0/negatif değer sınırsız demektir; aşan dosya değere girmez, uyarı komponentin içinde çizilir.',
864
874
  maxFileCount: "Çoklu kipte toplam dosya sayısı sınırı — zaten seçili olanlar da sayılır. Boş/0/negatif sınırsız. Tekli kipte hiç okunmaz ve panelde de gizlidir (isMultiple'a bağlı).",
@@ -873,10 +883,6 @@ export const componentKnowledge = {
873
883
  'Adresi ÇÖZÜLEMEYEN kaynak önizleme değil HATA kutusu çizer ve error yayar: yalnız kimliğini taşıyan kayıtlı referans ({ type: "ref", value: "abc" }, absolute_path yok) "dosya var" sayılır ama adresi yoktur. 2026-09-17 öncesinde boş src ile bir çerçeve çiziliyor, tarayıcı about:blank yüklüyor ve hiçbir şey gösterilmediği hâlde load yayılıyordu.',
874
884
  'Adres ŞEMA SÜZGECİNDEN geçer: http(s), göreli yol, blob: ve gerçekten çizilen gömülü türler (data:application/pdf · data:image/* · data:text/*) geçer; javascript:, vbscript:, file: ve sayfa gibi açılabilen gömülü türler (data:text/html, application/xhtml+xml, image/svg+xml) boşa düşer ve hata kutusu çizilir. Gerekçe: aynı adres hem PDF çerçevesine hem de programatik tıklanan indirme bağlantısına yazılıyor, javascript: ikisinde de uygulamanın origin’inde çalışırdı — üstelik son yol parçası .pdf ile biten bir javascript: metni uzantı kuralından PDF dalına giriyordu.',
875
885
  'Tür MIME’den, MIME yoksa UZANTIDAN okunur (drive dosyası ve düz URL MIME taşımaz): görsel · pdf · düz metin (txt md csv tsv log json xml yml yaml) önizlenir, gerisi unsupportedTitle/unsupportedText kutusuna düşer. 2026-09-17 öncesi yalnız bellekteki Blob çizilebiliyordu; URL ya da drive dosyası bağlanan her viewer "desteklenmeyen tür" gösteriyordu.',
876
- 'Adres UZANTISIZSA (indirme ucu: /api/invoices/42/download) tür ipucu olarak fileName’e bakılır: fileName: "fatura.pdf" yazılırsa PDF çizilir ve başlık/indirme adı da o olur (adresin kendi adı uzantısızsa). Görsel ve metinde bu yeter; PDF’te sunucunun Content-Type’ı da application/pdf olmalı — application/octet-stream tarayıcının PDF çerçevesinde açılmaz (boş çerçeve, yine de load yayılır). fileName’de de uzantı yoksa kutu "desteklenmeyen tür"dür.',
877
- 'Metin prop’larının (emptyTitle · emptyText · unsupportedTitle · unsupportedText · downloadText · errorText) şema varsayılanı BOŞTUR: yazılmazsa uygulama dilinin (tr · en · ar) kendi metni çizilir, yazılan metin her dilde aynen kalır. 2026-10-02 öncesi varsayılanlar sabit İngilizce idi ve tr/ar uygulamada bile İngilizce çıkıyordu. Uzun ve boşluksuz metin kutuyu taşırmaz (satırlara bölünür), kısa kutuda içerik kaydırılır. Bir metni boş yazarak SUSTURAMAZSIN (boş = dilin metni); gizlemek için style: { "&__card-text": { display: "none" } }.',
878
- 'Durumlar: yükleniyor (role=status, kökte aria-busy), boş, desteklenmeyen, hata (role=alert) kutuları ve önizleme. Hata KALICI değildir: value/file başka bir dosyaya geçince hata kutusu kalkar, aynı adrese dönülürse yeniden denenir ve her deneme kendi load/error’unu yayar (2026-10-02 öncesi bir kez hata alan viewer sonraki geçerli dosyada da hata kutusunda kalıyor ve load yaymıyordu). Metin önizlemesi klavyeyle odaklanır (region, adı dosya adı); simgeler ekran okuyucuya kapalıdır.',
879
- 'PDF çerçevesi HTTP durumunu bilmez: 404/403 dönen bir PDF adresinde hata kutusu çizilmez, sunucunun hata sayfası çerçevede görünür ve error yerine load yayılır. Görsel (img) ve metin (fetch) HTTP hatasında doğru şekilde error yayar. PDF adresinin varlığından emin değilsen önce akışta kontrol et.',
880
886
  'isDownloadable bileşenin ÇİZDİĞİ bütün indirme yüzeylerini yönetir: önizlemenin köşesindeki düğme, desteklenmeyen tür kutusundaki düğme ve hata kutusundaki düğme. Kapalıyken (varsayılan) bunların hiçbiri çizilmez — 2026-09-17 öncesi desteklenmeyen tür kutusu bu anahtardan bağımsız indirme sunuyordu.',
881
887
  'controls YALNIZ PDF’te iş yapar: tarayıcının yerleşik araç çubuğunu (sayfa gezinme, yakınlaştırma, yazdırma) açar; kapalıyken çerçeveye #toolbar=0 yazılır. DİKKAT: o araç çubuğu tarayıcının KENDİ indirme ve yazdırma düğmelerini de getirir ve isDownloadable ona ulaşamaz — indirmeyi gerçekten kapatmak isteyen controls’u da kapalı tutar (yalnız indirmeyi gizleyen bir çapa parametresi yoktur).',
882
888
  'Başlık, alt metni ve indirme adı dosyanın KENDİ adından gelir; dosya ad taşımıyorsa fileName kullanılır. fileName runtime’a geri YAZILMAZ, yalnız yedek addır.',
@@ -886,10 +892,8 @@ export const componentKnowledge = {
886
892
  file: 'Tasarımcının seçtiği dosya. Drive nesnesi ya da düz URL metni geçerlidir (CQ-267: şema tipi object görünür).',
887
893
  value: 'Akışın setter ile yazdığı dosya; panelde çizilmez ve file’ı ezer.',
888
894
  controls: 'PDF dışındaki türlerde etkisizdir. Açıkken tarayıcının kendi indirme/yazdırma düğmeleri de gelir; isDownloadable onları kapatamaz.',
889
- errorText: 'Yalnız error hâlindeki kutunun başlığı; unsupported kutusu unsupportedTitle kullanır. Boşsa dilin kendi metni çizilir.',
890
- fileName: 'Dosya kendi adını taşımıyorsa yedek ad; adres uzantısızsa aynı zamanda TÜR İPUCUDUR ("fatura.pdf"). Runtime’a geri yazılmaz.',
891
- style: "Serbest CSS. KÖK özellikleri iç yazıya iner: fontSize/color/fontFamily başlık, metin, düğme ve metin önizlemesini (kâğıdı kökün renginden türeyen %5’lik bir ton) boyar. Parçalar bildirilmiştir: &__loader, &__fab (köşedeki indirme düğmesi; &__fab { insetInlineStart: 0.5rem; insetInlineEnd: auto } ile karşı köşeye taşınır), &__content (önizleme alanı), &__image, &__pdf, &__text (metin önizlemesi), &__card (boş/hata/desteklenmeyen kartı), &__card-icon (simge rengi tema tokenı; &__card-icon { color } ile ezilir), &__card-title, &__card-text, &__download-btn (&__download-btn:hover ve :focus-visible çalışır). Hangi ekranın çizildiği parça adından anlaşılır: &__card yalnız boş/hata/desteklenmeyen varken, &__text yalnız metin dosyasında vardır.",
892
- surfaceStyle: NODE_SURFACE_NOTE + ' Bu bileşenin kökü SAYDAMDIR: surfaceStyle.background (gradyan dahil) ve style.background iç ekranların altında görünür; 2026-10-02 öncesi opak iç zemin ikisini de örtüyordu.'
895
+ errorText: 'Yalnız error hâlindeki kutunun başlığı; unsupported kutusu unsupportedTitle kullanır.',
896
+ surfaceStyle: NODE_SURFACE_NOTE
893
897
  }
894
898
  },
895
899
  button: {
@@ -918,10 +922,7 @@ export const componentKnowledge = {
918
922
  "Bir öğeye tıklanınca ikisi birden olur: öğenin kendi flow'u (options[].flow doluysa) çalışır VE clickItem olayına bağlı akışlar çalışır. İkisinde de tıklanan öğenin TAMAMI self.currentItem'a yazılıdır ({ key, text, icon, flow, isDanger… }). Aynı işi iki kez yapmamak için ya öğelere flow bağla ya da clickItem'a tek akış bağlayıp içinde self.currentItem.key ile dallan.",
919
923
  "click olayı BUTONUN KENDİSİNE basılınca yayılır (menüyü açan/kapatan tıklama) — menü hiç açılmasa bile. isDisabled ya da isLoading açıkken hiç yayılmaz. Öğe tıklamasıyla karıştırma: menü satırı click YAYMAZ, clickItem yayar.",
920
924
  "Görünür öğe kalmadıysa (options boş, dizi değil ya da hepsi isHidden) buton devre dışı GÖRÜNÜR ve menü açılmaz — ama click yine yayılır. Menüyü akışla kurarken options'ı yazmadan butonu ekran açılışında ölü göstermemek için bir başlangıç listesi bırak.",
921
- "Aynı sayfada tek menü açık kalır (ortak popover kaydı): bir menü açılınca diğeri kapanır. Menü kutusu ekrana SIĞAR: yükseklik viewport'a göre sınırlanır ve 50 satırlık liste kutunun İÇİNDE kayar; yatayda en geniş viewport − 16 px olur, düğme ekranın kenarındaysa menü kenara kayar (taşmaz), boşluksuz 300 karakterlik satır üç noktayla kesilir. Çok uzun listeyi yine de dropdown/table gibi bir listeleyene taşı (arama yok).",
922
- "Menü, buton kilitlenince (isLoading/isDisabled) ya da görünür satır kalmayınca (options boşalınca) AÇIKSA KENDİLİĞİNDEN KAPANIR. Boş/gizli seçenekli ve yükleniyor düğme native disabled DEĞİLDİR (click yine yayılır, Tab odaklanır) ama aria-disabled=true taşır; isLoading ayrıca aria-busy=true yazar. Düğme aria-expanded taşır (aria-haspopup YAZILMAZ: menü rolü ve ok tuşu gezintisi yok, ARC-156), ikon glifi ekran okuyucudan gizlidir.",
923
- "ERİŞİLEBİLİR AD: metin doluysa metnin kendisi (ariaLabel varsa metnin SONUNA eklenir: text 'Aç' + ariaLabel 'Sipariş 12' → 'Aç Sipariş 12'; etiket metni zaten içeriyorsa tek başına); metin BOŞSA (kebab) sırasıyla ariaLabel → optionsTitle → dilin 'Daha fazla'sı. Satırı tarif eden ad için ('Sipariş 12 işlemleri') kebab'da ariaLabel yaz. Spinner prefers-reduced-motion altında durur.",
924
- "STİL PARÇALARI: style'a &__button · &__icon · &__text · &__chevron · &__menu · &__title · &__item yazılır (eskiden hiçbiri tutmuyordu, `& .dropdown-menu__button` gibi torun seçicilerle çalışılırdı — onlar HÂLÂ çalışır). &__menu açılan menü kutusu, &__title menü başlığı, &__item her menü satırı. Kökün fontSize/color/fontFamily'si düğmeye, ikonlara, başlığa ve satırlara İNER (size 'sm' düğmenin kendi küçük puntosunu korur: onu &__button { fontSize } ile ez). Açık durum için `&.dropdown-menu--open &__button`, odak için `&__button:focus-visible`.",
925
+ "Aynı sayfada tek menü açık kalır (ortak popover kaydı): bir menü açılınca diğeri kapanır. Menü kutusu KAYDIRILMAZ — 15-20'yi geçen öğe listesi ekrandan taşar, uzun listeyi dropdown/table gibi bir listeleyene taşı.",
925
926
  "İpucu (tooltip) prop'u YOKTUR: düğümün ortak appearance.tooltip alanı (+ tooltipPosition) her komponentte ipucu çizer. Aynı bileşen drawer'ın alt şeridinde de kullanılır (actions[].options dolu olan aksiyon); orada prop'ları aksiyon tanımından gelir, sayfa şemasından değil."
926
927
  ],
927
928
  propNotes: {
@@ -930,9 +931,7 @@ export const componentKnowledge = {
930
931
  optionsTitle: "Menü kutusunun üstündeki başlık; boşsa başlık satırı hiç çizilmez.",
931
932
  icon: "{ name: 'more_vert', color? } nesnesi; düz 'more_vert' metni de okunur (CQ-164). Adı boş ya da temizlenmiş ikon HİÇ çizilmez (2026-09-17 öncesi boş ikon nesnesi 'home' glifi çiziyordu).",
932
933
  iconPosition: "'left' (varsayılan) | 'right' — ikonun metnin hangi yanında durduğu; chevron her zaman en sağda kalır. İkon yokken etkisiz (panelde de gizlidir).",
933
- text: "Butonun metni. BOŞ bırakılırsa chevron da çizilmez: buton yalnız ikondan oluşan bir menü düğmesine (kebab) döner. O kipte yükleniyor durumu ikonun yerinde spinner olarak görünür. Uzun metin düğmeyi büyütmez: tek satırda üç noktayla kesilir, tamamı title'dadır. Nesne/dizi/çözülmemiş {{ }} boş sayılır ([object Object] basmaz). Aynı kural menü satırı text'i ve optionsTitle için geçerli.",
934
- ariaLabel: "Düğmenin ekran okuyucu adı. Metin doluyken ad metindir ve bu alan SONUNA bağlam ekler (görünen etiket adın içinde kalır, WCAG 2.5.3); metin boşken (kebab) yazılmazsa optionsTitle, o da boşsa dilin 'Daha fazla'sı okunur. Ortak appearance'ta değil bu bileşenin kendi alanıdır.",
935
- style: "Kök CSS + parçalar: &__button · &__icon · &__text · &__chevron · &__menu · &__title · &__item. Kök fontSize/color/fontFamily içe iner (sm düğme hariç, bkz. behavior). Menü kutusu DOM'da kökün içindedir: `& .ng-popover__content` hâlâ çalışır.",
934
+ text: "Butonun metni. BOŞ bırakılırsa chevron da çizilmez: buton yalnız ikondan oluşan bir menü düğmesine (kebab) döner. O kipte yükleniyor durumu ikonun yerinde spinner olarak görünür.",
936
935
  size: "sm | md (varsayılan 'md') — lg YOKTUR. sm satır yüksekliğini içeriğe indirir ve menüyü butonun SAĞ kenarına yaslar (bottom-end), md ortalar.",
937
936
  isLoading: "Butonu kilitler (tıklama ve olay yok) ve chevron'un yerinde — metin yoksa ikonun yerinde — spinner döndürür. Devre dışı görünümüyle aynı soluklukta çizilir.",
938
937
  currentItem: "Panelde YOKTUR, yalnız runtime yazar: tıklanan öğenin tamamı. Akışta YALNIZ self.currentItem ile okunur — event.data.currentItem BOŞTUR: event.data'yı yalnız params geçen emit'ler doldurur (flow-execution.functions.ts), clickItem ise yalnız data gönderir ve o da setNode'a gider (CQ-077)."
@@ -968,24 +967,17 @@ export const componentKnowledge = {
968
967
  "Aksiyona flow bağlanabilir (actions[].flow) ya da şeridin click olayına akış bağlanabilir; İKİSİ birden bağlıysa tek tıklamada ikisi de koşar — aksiyonun akışı önce. Yalnız biri istensin diye diğerini boş bırakın.",
969
968
  "Aksiyona href yazılırsa o aksiyon LİNK olur (Button type:'link'): tarayıcı adrese gider ve click YAYILMAZ, dolayısıyla akış koşmaz. isNewTabLink yeni sekmede açar ve yalnız href doluyken iş görür. Adres NESNE biçiminde data alanından okunur — iç sayfa için { data: '<sayfanın yolu>', ref: '<pageId>' } yazın; data'sı boş bir nesne (yalnız ref) adres saymaz ve aksiyon normal buton olarak çizilir.",
970
969
  'showCloseButton:true iken aksiyonların sağında bir kapatma düğmesi çizilir; basılınca close olayı yayılır ve şerit KENDİNİ gizler (isHidden:true kendi prop’una yazılır). Varsayılan kapalıdır — kayıtlı sayfalarda düğme kendiliğinden çıkmaz.',
971
- 'Yükseklik 1-5 aralığındadır (varsayılan 5), genişlik 1-12 (varsayılan 12): tek satırlık tam genişlik şerittir.',
972
- "DÜZEN kendiliğinden uyum sağlar: ikon + metin solda, aksiyonlar sağda tek satırdır; sığmayınca aksiyonlar metnin altına iner (sağa yaslı, sarar), uzun ya da boşluksuz başlık/alt metin ve uzun düğme metni kabı aşmaz, 375 px'te yatay kaydırma olmaz. 8-20 aksiyon da satır satır sarar. Bu yüzden style'a flexWrap / minWidth / overflowWrap hilesi YAZMA.",
973
- "TON (zemin + 1px halka + ikon dairesi) tema YÜZEYİNDEN türetilir: koyu temada şerit koyu yüzeyle karışır ve başlık/alt metin her tonda ≥ 6.7:1 okunur; info nötr gri bir şerittir (tema info rengi neredeyse beyaz olduğundan şeridi ayırt ettirmez, kullanılmaz). primary tam vurgu halkası, öbürleri %40 halka taşır; transparent zemin ve halkayı boş bırakır. Yazı rengi kökten MİRAS alınır: style'ın kök color / fontSize / fontFamily'si başlığa, alt metne ve ikona iner (başlık 1.15em, alt metin .85em, ikon dairesi 2.85em).",
974
- "title ve subtle YALNIZ metin ve sonlu sayı çizer; nesne, dizi, true, NaN ve çözülmemiş {{ }} boş sayılır (satır hiç çizilmez) — [object Object] basılmaz. Aksiyon text'i de aynı kuralla çizilir.",
975
- "Aksiyonun kind'ı listede (primary|info|success|warning|error; eski sayfalardaki transparent de çizilir) yoksa primary, variant'ı yoksa solid çizilir (gri yerel düğme çıkmaz). YALNIZ-İKON aksiyonun (text boş) erişilebilir adı YOKTUR: okuyucu ikonun adını okur ('delete') ve aksiyonda ariaLabel alanı yoktur — metin yaz. Süs ikonu ekran okuyucudan gizlidir.",
976
- 'Kapatma düğmesi 24×24 px, klavye odağında 2 px vurgu halkası; forced-colors (yüksek karşıtlık) kipinde şerit 1px sistem kenarlığı çizer.'
970
+ 'Yükseklik 1-5 aralığındadır (varsayılan 5), genişlik 1-12 (varsayılan 12): tek satırlık tam genişlik şerittir.'
977
971
  ],
978
972
  propNotes: {
979
973
  title: 'Şeridin ana metni; boş bırakılırsa başlık satırı hiç çizilmez.',
980
974
  subtle: 'Başlığın altındaki ikincil metin; boşsa çizilmez.',
981
- icon: "{ name: 'lock_open_right', color? } nesnesi; düz 'check' metni de okunur. Adı boş, temizlenmiş ya da ikon fontunda olmayan (yazım hatası) ikonda checklist çizilir — ikonsuz şerit YOKTUR, boş daire de çıkmaz.",
975
+ icon: "{ name: 'lock_open_right', color? } nesnesi; düz 'check' metni de okunur. Adı boş/temizlenmiş ikonda checklist çizilir — ikonsuz şerit YOKTUR.",
982
976
  kind: "primary | info | success | warning | error | transparent — şeridin tonu (zemin + kenarlık + ikon dairesi). Temizlenirse ya da sözlükte olmayan bir değer yazılırsa info çizilir. transparent zemini boş bırakır.",
983
977
  showCloseButton: 'Kapatma düğmesini çizer (varsayılan false). Basılınca close olayı + isHidden:true.',
984
978
  actions: "Buton listesi. Alanlar: key (text'ten snake_case türetilir, currentItem'da geri gelir) · text · kind · variant · icon · flow · href · isNewTabLink · isHidden · isDisabled · isLoading. Sıra dizinin sırasıdır.",
985
979
  currentItem: "AI YAZMAZ: şeridin click olayında runtime'ın geri yazdığı durum prop'u — tıklanan aksiyonun tamamı. Akışta self.currentItem (ör. self.currentItem.key) ile okunur.",
986
- isHidden: 'Şeridi söker. Kapatma düğmesi de bunu yazar; şeridi geri getirmek için akışta isHidden:false yazın.',
987
- style: STYLE_GROUP_NOTES.styleEscape +
988
- " PARÇALAR (7): '&__content' (ikon + metin satırı) · '&__icon' (ikon dairesi) · '&__text' (başlık + alt metin sütunu) · '&__title' · '&__subtle' · '&__actions' (düğme satırı) · '&__close' (kapatma düğmesi). '&__close:hover' ve '&__close:focus-visible' çalışır. Kök anahtarlar (padding, borderRadius, border, boxShadow, background gradyanı, fontFamily, flexDirection) bileşenin varsayılanını ezer; ton halkası inset box-shadow'dur (border yazmak onu kaldırmaz, boxShadow: 'none' yaz). Aksiyon düğmeleri Button'dur: '& .ng-button' ile hedeflenir, parçası yoktur."
980
+ isHidden: 'Şeridi söker. Kapatma düğmesi de bunu yazar; şeridi geri getirmek için akışta isHidden:false yazın.'
989
981
  }
990
982
  },
991
983
  card: {
@@ -1070,31 +1062,25 @@ export const componentKnowledge = {
1070
1062
  "key satırın kimliğidir ve METİN olarak karşılaştırılır (selected '7' ile data key 7 eşleşir). key'i boş/eksik satır hiç seçili çizilmez ve onay kutusu kilitlidir (yalnız ebeveyninden durum alır); aynı seviyede key tekrar ederse ya da eksikse ağaç kırılmaz ama selected/checkedKeys o satırları ayırt edemez — sorgudan kurarken benzersiz id'yi key'e eşle.",
1071
1063
  'selected akıştan yazıldığında o düğüme giden dallar KENDİLİĞİNDEN açılır (yalnız açar; kullanıcının elle açtıklarını kapatmaz). Satır verisindeki isExpanded:true de kendi başına açar.',
1072
1064
  "isCheckable:true her satırın soluna onay kutusu koyar; işaretli key'ler checkedKeys dizisidir. Bir üst satırın key'i TÜM dalı temsil eder: checkedKeys'e yalnız ebeveyn yazmak altındaki bütün etkin satırları işaretler; etkin çocuklarının hepsi işaretli ebeveyn işaretli, bir kısmı işaretliyse yarım (—) çizilir. Kutuya tıklamak dalı birlikte işaretler/kaldırır. isDisabled satırın kutusu kilitlidir ve zincir onda durur: ebeveynin işareti ona ve altına inmez, o da ebeveynin durumuna sayılmaz (altındaki etkin satırlar tek tek işaretlenebilir).",
1073
- "change yalnız kullanıcı kutuya tıklayınca yayılır (akışın checkedKeys yazması yaymaz). Yazılan checkedKeys normalize edilmiştir: tam işaretli her satır belge sırasıyla (tamamlanan ebeveyn dahil); ağaçta çizilmeyen key'ler (gizli satır, henüz yüklenmemiş veri) sona olduğu gibi eklenir. Satır tıklaması (click/selected) ile kutu (change/checkedKeys) birbirinden bağımsızdır. checkedKeys'i (ve selected'ı) {{ }} İFADESİNE BAĞLAMA: kullanıcı yazması ifadeli prop'u bozar ve değişiklik kaybolur (platform kusuru CQ-247) — başlangıç listesi STATİK yazılamaz (skaler dizi 500 verir, ARC-157): tree'nin mount akışında self.checkedKeys = [...] ile ver.",
1065
+ "change yalnız kullanıcı kutuya tıklayınca yayılır (akışın checkedKeys yazması yaymaz). Yazılan checkedKeys normalize edilmiştir: tam işaretli her satır belge sırasıyla (tamamlanan ebeveyn dahil); ağaçta çizilmeyen key'ler (gizli satır, henüz yüklenmemiş veri) sona olduğu gibi eklenir. Satır tıklaması (click/selected) ile kutu (change/checkedKeys) birbirinden bağımsızdır. checkedKeys (ya da selected) {{ }} ifadesine bağlıysa kullanıcının tıklaması ifadeyi o düğümde ezer ve kalır; ifadede adı geçen bir düğüm değişince bağ yeniden koşar ve seçimi ifadenin sonucuyla değiştirir (ARC-147, 2026-09-29'dan önce prop bozuluyordu). Seçimin kalıcı olması gerekiyorsa başlangıç listesini statik yaz ya da akıştan self.checkedKeys = [...] ile ver.",
1074
1066
  "actions komponent düzeyinde BİR KEZ tanımlanır, her satır aynı menüyü çizer; bir satır farklılaşacaksa veri öğesine _actions dizisi konur ve SIRA numarasıyla şablonun üstüne biner (o satırda gizleme / etiket değiştirme).",
1075
1067
  "Aksiyonlar set_event ile DEĞİL her aksiyonun kendi flow prop'uyla bağlanır; şema olayı yayılmaz. Aksiyonun akışında satır self.currentItem'da, event.data'da { currentItem, actionKey } (actionKey: aksiyonun key'i) gelir. flow'u boş aksiyon hiçbir şey yapmaz.",
1068
+ "BAĞLI VERİ (2026-09-17, f-32): data connectData'ya bağlanabilir; children rolü ÜST KAYIT alanıdır (parent_id ya da self ilişki). Runtime satırları toTree ile iç içe children'a çevirir (üstü boş/listede yok → kök, döngüdeki satır köke, derinlik 10), sayfalamayı kapatır ve ilk 1000 satırı okur (CD-009). Anahtar kaynağın birincil anahtarıdır; query/workflow kaynağında yoktur, o zaman key (yoksa value) rolünün alanı kullanılır — anahtarsız satırlar köke düşer. Bağlantı yazmaz; seçim yine click olayıdır.",
1076
1069
  'isSearchable:true arama kutusunu + tümünü aç/kapat düğmelerini açar. Süzme text ve subtle alanlarında geçer, eşleşenin ataları yerinde kalır, eşleşenin alt ağacı bütün görünür ve süzme sürerken dallar açık çizilir (chevron o sırada etkisizdir). Süzme İSTEMCİ tarafındadır: sunucuda arama gerekiyorsa kutuyu kapatıp kendi textinput + akış çiftini kur. Arama sürerken onay durumu TAM ağaçtan hesaplanır ve bir ebeveyni işaretlemek aramanın gizlediği çocuklarını da işaretler.',
1077
1070
  'isLoading iskelet satır çizer; veri (ya da arama sonucu) boşsa emptyText basılır. data içindeki null / düz değer öğeler atlanır.',
1078
- 'Satır ikonu icon > image > varsayılan klasör ikonu sırasıyla seçilir; satırdaki isHidden satırı hiç çizmez, isDisabled satır tıklamasını ve kutusunu kilitler (dalı yine açılıp gezilebilir).',
1079
- "Dallar chevron'la açılıp kapanır — seçili satırın atasını da kapatabilirsin (seçim DEĞİŞİNCE ilgili dallar yeniden açılır, kapattığın dal kendiliğinden geri açılmaz; seçili satıra giden dallar 'tümünü kapat'tan sonra da açık kalır). Arama kutusundaki 'tümünü aç' TÜM derinliği açar, 'tümünü kapat' hepsini kapatır; ikisinden sonra elle açılan dalın çocukları son işarete uyar. Satır text'i yoksa boş çizilir.",
1080
- "Arama I/İ/ı/i'yi aynı harf sayar (ISPARTA = ısparta = İsparta) ve tarayıcı diline bağlı değildir; ç, ş, ü gibi diğer aksanlı harfler ayrı harftir.",
1081
- "Sağdan sola (dir rtl / ar): girinti sağ kenardan başlar, açma oku aynalanır, klavyede ← dalı açar ve → kapatır (soldan sağa tersi). Ağaç kök öğesi role=tree, dallar aria-expanded taşır; arama kutusunun adı searchPlaceholder, chevron adı \"Aç/kapat: <satır>\".",
1082
- "YÜKSEKLİK: ağaç satır sayısı kadar uzar ve kendi içinde KAYDIRMAZ. Düğümde sabit yükseklik (heightType fixed / heightString) verirsen ağaç kutudan taşar ve alttaki komşuları örter: düğümde states.isScrollable:true aç (ya da style { maxHeight, overflowY: 'auto' }). 375px'te mobil kural düğüm yüksekliğini ezer; orada style'daki maxHeight + overflowY yazılır.",
1083
- "add_component'e props vermezsen katalog varsayılan verisi (Paper/Card/List) GELMEZ: ağaç 'No items' basar — data'yı kendin yaz. icon bir NESNEdir ({ name: 'folder' }); düz metin ('folder') beklenen simgeyi vermez.",
1084
- "currentItem son tıklanan / kutusu değişen / aksiyon alınan satırdır: kutuya tıklamak da onu yazar. Seçili satırı akışta selected'tan oku; akışın yazdığı selected currentItem'ı doldurmaz."
1071
+ 'Satır ikonu icon > image > varsayılan klasör ikonu sırasıyla seçilir; satırdaki isHidden satırı hiç çizmez, isDisabled satır tıklamasını ve kutusunu kilitler (dalı yine açılıp gezilebilir).'
1085
1072
  ],
1086
1073
  propNotes: {
1087
- data: '[{ key, text, subtle, icon, image, isExpanded, isHidden, isDisabled, children[], _actions[] }] — key satırın kimliğidir (metin olarak karşılaştırılır), selected ve checkedKeys onunla eşleşir. icon nesnedir: { name: "folder" }.',
1074
+ data: '[{ key, text, subtle, icon, image, isExpanded, isHidden, isDisabled, children[], _actions[] }] — key satırın kimliğidir (metin olarak karşılaştırılır), selected ve checkedKeys onunla eşleşir.',
1088
1075
  selected: 'Seçili satırın key’i; setter ile dışarıdan da sürülebilir (o dala kadar ağaç açılır).',
1089
- checkedKeys: "İşaretli satırların key dizisi (yalnız isCheckable:true iken çizilir ve panelde görünür). Ebeveyn key'i tüm dalı işaretler. Kullanıcı kutuya tıklayınca normalize edilmiş diziyle geri yazılır. Akışın yazdığı liste NORMALİZE EDİLMEZ: kutular dal kuralıyla çizilir ama self.checkedKeys ham kalır — sayı gerekiyorsa tam listeyi yaz.",
1076
+ checkedKeys: "İşaretli satırların key dizisi (yalnız isCheckable:true iken çizilir ve panelde görünür). Ebeveyn key'i tüm dalı işaretler. Kullanıcı kutuya tıklayınca normalize edilmiş diziyle geri yazılır.",
1090
1077
  isCheckable: 'Satırlara onay kutusu koyar (çoklu seçim, dal zinciri, yarım durum); change olayını açar.',
1091
1078
  currentItem: 'Gizli prop: son tıklanan / kutusu değişen / aksiyon alınan satırın tamamı (arama sürerken children süzülmüş hâliyle).',
1092
1079
  isSearchable: 'İstemci tarafı arama kutusu + tümünü aç/kapat araçları.',
1093
1080
  searchPlaceholder: 'Arama kutusunun ipucu metni (yalnız isSearchable:true iken).',
1094
1081
  emptyText: 'Veri ya da arama sonucu boşken basılan metin.',
1095
1082
  actionsTitle: 'Aksiyon düğmesinin ipucu (üstüne gelince görünen metin) ve ekran okuyucu adı; menü başlık çizmez.',
1096
- isActionsShowAlways: 'Aksiyon düğmesi sürekli görünür (varsayılan: satırın üstüne gelince).',
1097
- style: "Kökteki fontFamily, fontSize ve color satır yazısına iner (seçili satırın yazı rengi ve alt metin kendi parçasından — &__text, &__subtle — yazılır; simge ve alt metin boyutu tema jetonundan hesaplanır). Parçalar (&__parça): &__search · &__search-input · &__search-tool · &__list · &__item (satır + alt dalı) · &__row · &__checkbox · &__icon · &__text · &__subtle · &__chevron · &__actions · &__actions-button · &__sublist · &__empty · &__loading. Seçili satır: `&__item[aria-selected=\"true\"] > &__row` (`>` şart: alt dal item'ın içindedir, yoksa seçili olmayan iç satırlar da boyanır) ve yazısı için `... > &__row &__text`. :hover ve :focus-visible parçalara yazılır. surfaceStyle ortak katmandır."
1083
+ isActionsShowAlways: 'Aksiyon düğmesi sürekli görünür (varsayılan: satırın üstüne gelince).'
1098
1084
  }
1099
1085
  },
1100
1086
  text: {
@@ -1102,15 +1088,12 @@ export const componentKnowledge = {
1102
1088
  behavior: [
1103
1089
  "Yükseklik SABİTTİR: maxSize.h = 1 (katalog varsayılanı 8'dir ve olduğu gibi kopyalanırsa kanvasta boyutlandırılamaz; gateway 1'e çeker ve gatewayNormalized ile bildirir). Çok satırlı metin için textarea ya da html kullanın.",
1104
1090
  "type HTML etiketi + ölçek seviyesidir (h1|h2|h3|h4|label|p|small; a11y için doğru seviyeyi seç; h4 2026-09-16'da açıldı — runtime ve tema ölçeği onu zaten tanıyordu, yalnız şemada yoktu). Punto/kalınlık/renk/hiza kararı typographyStyle'dadır: fontSize seviyenin puntosunu ezer, boş bırakılırsa seviye ölçeği (tema --ng-font-size-*) geçerlidir.",
1105
- "type DOM etiketidir ve {{ }} ile veriden de gelebilir: yedi seviyenin (h1|h2|h3|h4|label|p|small) DIŞINDAKİ her değer çalışma anında label'a düşer (2026-10-02'ye dek veri 'script' döndürünce gerçek bir <script> kuruluyor ve çalışıyordu). Statik yazımda doğrulayıcı zaten reddeder; type'ı veriye bağlıyorsan yalnız bu yedi değeri döndür.",
1106
- "content SAYISAL SIFIRI ve false'ı artık BASAR (2026-09-16'da düzeltildi): şablon content ?? '' okuyor. Öncesinde || kullanılıyordu ve {{ <düğüm>.total }} gibi bir bağlamada değer 0 olduğunda metin BOŞ çiziliyordu — sayaç/toplam basan her ekranda bağlama kopmuş gibi görünüyordu. NESNE okunur JSON olarak basılır ({\"a\":1}), nesne taşıyan dizi de; eskiden '[object Object]' çıkıyordu. Yalnız skaler içeren dizi eski virgüllü çıktısını korur ('kırmızı,mavi'); bigint sayı, tarih ISO metni olarak yazılır. Satır sonu (\\n) boşluğa çöker: metin tek satırdır, çok satırlı metin için textarea ya da html.",
1107
- "HİZA: typographyStyle.textAlign yazılmazsa varsayılan 'start'tır (LTR'de sol, RTL'de sağ; 2026-10-02'ye dek fiziksel 'left' idi ve ar/RTL'de metin kutunun soluna yaslı kalıyordu). Açıkça 'left'/'right' yazarsan RTL'de de aynı yöne yazar; çok dilli uygulamada start/end yaz.",
1108
- "SATIR YÜKSEKLİĞİ seviyeye göre sabit pikseldir (h1 40 · h2 35 · h3 30 · h4 25 · label/p 20 · small 15) ve yazı boyutuyla ölçeklenmez; typographyStyle.fontSize ile büyütülen metinde satır yüksekliği yazı boyunun en az 1.25 katına çıkar (h1 + 48px → 60px); taban punto 14px'ten büyük bir temada başlık seviyeleri de bu tabana çıkar (16px tabanda h1 40 → 45). Kendi satır aralığını istiyorsan typographyStyle.lineHeight yaz — o her zaman kazanır.",
1109
- "isLoading ifadeye bağlanabilir: bir listenin satırında {{ item.yukleniyor }} yazılır, akıştan setter ile açılıp kapatılır. Yükleniyor durumunda iskelet gizlidir ama kök, ekran okuyucuya görünmez 'Yükleniyor' metni taşır (başlık etiketi boş okunmasın); prefers-reduced-motion'da iskelet nabız atmaz.",
1091
+ "content SAYISAL SIFIRI ve false'ı artık BASAR (2026-09-16'da düzeltildi): şablon content ?? '' okuyor. Öncesinde || kullanılıyordu ve {{ <düğüm>.total }} gibi bir bağlamada değer 0 olduğunda metin BOŞ çiziliyordu — sayaç/toplam basan her ekranda bağlama kopmuş gibi görünüyordu.",
1110
1092
  "EMEKLİ prop'lar: isBold, align, color, customColor şemada YOK — yazılırsa unknown-prop ile reddedilir. Karşılıkları: typographyStyle.fontWeight ('600'), textAlign, textColor (semantik renk için tema token'ı: var(--ng-status-success) gibi). Kayıtlı eski sayfalarda bu prop'lar render anında takma adla çözülür (resolvedStyle bunu gösterir), yeni yazımda kullanılmaz.",
1111
1093
  "Hover grubu yok (metnin hover semantiği yok); surfaceStyle etiket/vurgulu paragraf içindir (zemin, köşe, çerçeve, gölge) ve contentOverflow alanı yoktur (taşma hedefi yok). METNİN taşması surfaceStyle'ın işi değildir, lineClamp prop'unundur.",
1112
1094
  "Olay YOKTUR: şema events sözlüğü boştur, componentEvents kaydı da yoktur. Metne tıklamayı akışa bağlamak isteyen düğümü button ya da bir kaba sarar.",
1113
- "KATMAN SIRASI (K4): tema componentStyles → $preset TABANDIR; tipli grup alanları temayı alan alan EZER; düğümün serbest style'ı SON SÖZDÜR. Grubun karşılamadığı kararı style kanalına (custom properties) yaz."
1095
+ "KATMAN SIRASI (K4): tema componentStyles → $preset TABANDIR; tipli grup alanları temayı alan alan EZER; düğümün serbest style'ı SON SÖZDÜR. Grubun karşılamadığı kararı style kanalına (custom properties) yaz.",
1096
+ PROTECTED_VALUE_NOTE + " Metinde: yalnız record + recordField birlikte verilince devreye girer; maskeliyken content YOK SAYILIR ve record[recordField] (maske metni) çizilir."
1114
1097
  ],
1115
1098
  propNotes: {
1116
1099
  content: "Düz metin; {{ }} ile ifadeye bağlanır. 0 ve false BASILIR (bkz. behavior). Biçimli içerik (kalın parça, liste, link) metnin içinde DEĞİL ayrı komponentte kurulur: html ya da texteditor.",
@@ -1118,56 +1101,50 @@ export const componentKnowledge = {
1118
1101
  isLoading: 'Metnin yerine nabız atan bir iskelet çubuğu çizer ve aria-busy yazar; content hiç basılmaz. Veri gelene kadar gösterilecek yer tutucu içindir, akıştan setter ile açılıp kapatılır.',
1119
1102
  surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens,
1120
1103
  typographyStyle: STYLE_GROUP_NOTES.typographyStyle + ' ' + STYLE_GROUP_NOTES.colorTokens,
1121
- style: STYLE_GROUP_NOTES.styleEscape +
1122
- " text'in TEK iç parçası yükleniyor çubuğudur: &__skeleton (isLoading açıkken). Başka &__parça YOKTUR; &__text, &__content gibi adaylar sessizce etkisizdir (kök tek bir etikettir: kök özellikleri, :hover, :active, ::before/::after, ::first-letter, ::first-line, ::selection, @media ve @supports kökte çalışır). Text odaklanamaz (tabindex yok), yani &:focus-visible hedefi hiç tetiklenmez. @keyframes style içinde ÇALIŞIR (2026-10-02'den beri; animation adı + keyframe gövdesi birlikte yazılır), PascalCase 'Webkit*' anahtarlarını platform kayıtta DÜŞÜRÜR (yanıttaki silentlyDropped bildirir; ölçüldü): kebab yaz ('-webkit-text-fill-color', '-webkit-background-clip')."
1104
+ style: STYLE_GROUP_NOTES.styleEscape,
1105
+ record: "KORUMALI DEĞER İÇİN: content'in bağlandığı SATIR nesnesi ({{ musteriTablosu.selectedRow }}); recordField ile birlikte verilir. Korumasız metinde boş bırak.",
1106
+ recordField: "record içindeki alan slug'ı ('tckn'). Satırın __protected metası bu alanı 'masked' işaretlerse metin kilitli maske olarak çizilir.",
1107
+ revealEntity: REVEAL_ENTITY_NOTE
1123
1108
  }
1124
1109
  },
1125
1110
  image: {
1126
1111
  summary: 'Görsel; mount ve click yayar, src ifadeyle beslenebilir. Büyütülmüş önizleme (isZoomable) ve önizlemenin içinde döndürme (isRotatable) vardır.',
1127
1112
  behavior: [
1128
- "ÖLÇEKLEME KİPİ PROP DEĞİL, düğümün appearance kanalındadır: appearance.widthType 'cover' (kutuyu doldurur, taşanı kırpar) ya da 'contain' (tamamını sığdırır ve appearance.alignType ile sola/ortaya/sağa hizalanır); appearance.heightType 'fixed' | 'auto' (appearance.aspectRatio ile oran) | 'fill'. Studio bir image düğümünü bırakırken heightType:'fixed', widthType:'contain', alignType:'center' yazar. 2026-09-16 öncesinde heightType:'fill' ve flex çocuğunun widthType:'fixed'/'fill' kipleri HİÇBİR sınıf üretmiyordu; object-fit tarayıcı varsayılanına düşüp görsel esneyerek bozuluyordu. Artık ikisi de varsayılan kiple (cover) kutuyu kaplar. 2026-10-04'ten beri widthType:'auto' da görseli GERDİRMEZ (taban kip cover; öncesinde heightType:'fill' + widthType:'auto' 400x200 görseli 400x400'e esnetiyordu) ve heightType:'auto' + widthType:'contain' gerçekten contain'dir (aspectRatio verilmiş kutuda önceden sessizce cover olup kırpıyordu; alignType de artık auto yükseklikte uygulanır).",
1113
+ "ÖLÇEKLEME KİPİ PROP DEĞİL, düğümün appearance kanalındadır: appearance.widthType 'cover' (kutuyu doldurur, taşanı kırpar) ya da 'contain' (tamamını sığdırır ve appearance.alignType ile sola/ortaya/sağa hizalanır); appearance.heightType 'fixed' | 'auto' (appearance.aspectRatio ile oran) | 'fill'. Studio bir image düğümünü bırakırken heightType:'fixed', widthType:'contain', alignType:'center' yazar. 2026-09-16 öncesinde heightType:'fill' ve flex çocuğunun widthType:'fixed'/'fill' kipleri HİÇBİR sınıf üretmiyordu; object-fit tarayıcı varsayılanına düşüp görsel esneyerek bozuluyordu. Artık ikisi de varsayılan kiple (cover) kutuyu kaplar.",
1129
1114
  "Kaynak boşsa ya da yüklenemezse GÖRÜNÜR bir yedek kutu çizilir (ikon + alt metni). 2026-09-16 öncesinde <img> etiketinin kendi alt metni .ng-image kuralındaki color: transparent yüzünden gizleniyordu, yani kırık görsel boş bir dikdörtgenden ayırt edilemiyordu.",
1130
1115
  'isLoading açıkken görselin yerine parıltılı iskelet çizilir; akıştan setter ile açılıp kapatılabilir, görselin kendi yükleme iskeletinden bağımsızdır.',
1131
1116
  "isZoomable açıkken görsele tıklamak tam ekran önizleme açar (Escape, kapatma düğmesi ve zemine tıklama kapatır). Bağlı bir click akışı VARSA o da çalışır; ikisi birbirini iptal etmez, önizleme istenmiyorsa anahtar kapalı bırakılır. Kanvasta (tasarımcı yüzeyinde) önizleme hiç açılmaz. isRotatable yalnız önizlemenin içine 90 derecelik döndürme düğmeleri ekler ve kaydedilen hiçbir değeri değiştirmez.",
1132
- 'Görünürlük ortak katmandadır (props.isHidden); ipucu, köşe, gölge, kenarlık ve boşluk düğümün appearance kanalından gelir, bu komponentin prop yüzeyinde yoktur.',
1133
- "src ANAHTARI HİÇ YAZILMAZSA (MCP'nin kurduğu düğümde) görsel çizilmez, yedek kutu 'image' ikonu + alt metniyle çizilir; panelin gösterdiği '/images/default.webp' ekranda ÇİZİLMEZ (yalnız studio'nun bıraktığı düğümde src açıkça yazılıdır). STATİK yazımda skaler değerler (sayı, true, ['a']) platformda 500 verir ('Dictionary<String,Prop>', yol bilgisiz) — veri değişkenle taşınır; dosya nesnesi ({type:'file', data}) statik yazılamaz (platform data'yı kendi dosya uç adresiyle ezer ve silentlyDropped bildirir): nesne yalnız sayfa değişkeni ya da setter ile gelir. URL metni her zaman çalışır.",
1134
- "alt ANAHTARI YAZILMAZSA alt BOŞTUR (2026-10-04'ten beri; öncesinde 'Image' olurdu: ekran okuyucu 'Image' okur ve görsel yüklenemezse son kullanıcıya İngilizce 'Image' yazısı çıkardı): <img alt=\"\"> dekoratif sayılır, ekran okuyucu atlar, yedek kutuda yalnız simge çizilir. ANLAMLI görsele (ürün, kapak, logo) mutlaka alt YAZ. Boş, null ve yalnız boşluk metni aynıdır; tıklanabilir/büyütülebilir düğümün erişilebilir adı alt boşken yerel 'zoom' metninden gelir: tr 'Yakınlaştırma', ar 'التكبير'.",
1135
- "Yükleniyor (isLoading) iskeleti de tıklanabilir: bağlı click akışı varken iskelet üstüne tıklamak akışı koşturur (ölçüldü); yükleme sürerken tıklamanın bir şey yapmaması gerekiyorsa akışa koşul yaz. İskelet ve görsel yükleme animasyonu prefers-reduced-motion altında durur (2026-10-04'ten beri)."
1117
+ 'Görünürlük ortak katmandadır (props.isHidden); ipucu, köşe, gölge, kenarlık ve boşluk düğümün appearance kanalından gelir, bu komponentin prop yüzeyinde yoktur.'
1136
1118
  ],
1137
1119
  propNotes: {
1138
- src: "Yüklenen dosya alanının nesnesi (uçtan geldiği gibi) YA DA URL metni; ikisi de kabul edilir. Varsayılan '/images/default.webp' (yalnız panelde; anahtar yazılmazsa ekranda çizilmez).",
1139
- alt: "Erişilebilirlik metni; görsel yüklenemediğinde yedek kutuda GÖRÜNÜR olarak da basılır. Anahtar yazılmazsa BOŞ (dekoratif); anlamlı görselde mutlaka yaz. Yalnız boşluktan oluşan metin boş sayılır.",
1120
+ src: "Yüklenen dosya alanının nesnesi (uçtan geldiği gibi) YA DA URL metni; ikisi de kabul edilir. Varsayılan '/images/default.webp'.",
1121
+ alt: 'Erişilebilirlik metni; görsel yüklenemediğinde yedek kutuda GÖRÜNÜR olarak da basılır.',
1140
1122
  isZoomable: 'Tıklayınca tam ekran önizleme açar (rakiplerdeki zoom/lightbox karşılığı).',
1141
1123
  isRotatable: 'Önizlemeye sola/sağa 90 derece döndürme düğmeleri ekler; isZoomable kapalıyken panelde çizilmez.',
1142
- isLoading: 'Görselin yerine iskelet çizer; veri gelene kadar bekletmek için akıştan yazılır.',
1143
- style: STYLE_GROUP_NOTES.styleEscape +
1144
- " KÖK anahtarlar (kenarlık, köşe, gölge, filtre, dönüş, opacity) görselin kendisine (<img>) iner; kaynak boş/kırıksa yedek kutuya, isLoading iken iskelete de aynı kural iner. Sarmalayıcıya İNMEZ. PARÇALAR (hepsi ilk adayda tutar, 2026-10-04): '&__wrapper' (tıklanabilir ya da büyütülebilirse <button>, değilse <div>: TAM kutu), '&__skeleton' (isLoading), '&__fallback' + '&__fallback-icon' + '&__fallback-text' (kırık/boş kaynak), büyütülmüş önizleme: '&__preview' (tam ekran zemin), '&__bar' (düğme çubuğu), '&__button' (✕ ve döndürme düğmeleri), '&__zoomed' (büyütülmüş görsel). Önizleme portal ile sayfa kökünün altına taşınır ama sınıflar elemandadır, parçalar yine tutar. ODAK: <img> odak almaz, yani kök '&:focus-visible' HİÇ tetiklenmez; halka için '&__wrapper:focus-visible' yaz (varsayılan: UA halkası). '&:hover' ve '&:active' kökte (img) çalışır. <img> bir replaced element'tir: kökte '::before/::after' ÇİZİLMEZ — alttan örtü (scrim) için '&__wrapper' {position:'relative'} + '&__wrapper::after' {content:\"''\", position:'absolute', inset:0, background:'linear-gradient(...)', pointerEvents:'none'} yaz (ölçüldü: wrapper kutusunun tamamını kaplar). '@media', '@keyframes' (shared designerStyle) ve '!important' çalışır; kök 'objectFit' appearance.widthType'ı yener. Olmayan parça adı (ör. '&__image', '&__root') sessizce etkisizdir (silentlyDropped'a düşmez)."
1124
+ isLoading: 'Görselin yerine iskelet çizer; veri gelene kadar bekletmek için akıştan yazılır.'
1145
1125
  }
1146
1126
  },
1147
1127
  video: {
1148
- summary: 'HTML5 video oynatıcı: src + poster, autoplay/loop/muted/controls anahtarları, akıştan sürülebilen isPlaying kolu ve play/pause/ended/load/error olayları. Tarayıcının kendi kontrollerini çizer — özel oynatıcı arayüzü yoktur.',
1149
- behavior: [
1150
- "src hem DOSYA ALANI NESNESİ hem DÜZ URL METNİ kabul eder (getfileUrl: metin olduğu gibi kullanılır, nesnede type:'file' ise data/value, değilse absolute_path okunur). Katalog tipi 'object' görünür çünkü şemada FileProp'tur; metin yazmak geçerlidir ve akıştan gelen uç FILE alanı olduğu gibi taşınabilir. Boş src'de src özniteliği HİÇ yazılmaz (boş istek atılmaz), poster varsa yalnız kapak görünür. Adres sanitize EDİLMEZ (javascript:/data: özniteliğe yazılır) ama <video> bunları çalıştırmaz (ölçüldü 2026-10-05: betik koşmadı).",
1151
- "KAYNAK YÜKLENDİ / YÜKLENEMEDİ: 'load' ilk kare hazır olunca yayılır, event.data = { duration (sn; sonsuz/bilinmiyorsa 0), width, height (kaynağın kendi piksel boyu) }. İkisi de YALNIZ oynatıcı çizilirken yayılır: isLoading:true iken <video> hiç kurulmadığından load/error gelmez — kaynağı beklerken iskelet istiyorsan isLoading'i kapalı bırak, ayrı bir yer tutucu göster ve load/error'da gizle (ya da isLoading'i kaynağı çözen sorgudan kapat). Repeater satırı içindeki bir videoda mount/load/error ve sökülme geri yazımı satırı SEÇMEZ. 'error' kaynak yüklenemediğinde (404, video olmayan dosya, desteklenmeyen biçim) yayılır, event.data = { code (1 iptal · 2 ağ · 3 çözümleme · 4 kaynak yok/desteklenmiyor), message }. error olmadan bileşen bozuk kaynağı SESSİZCE siyah bir kutu olarak bırakır (kutu ölçüsünü korur, sayfa çökmez): kullanıcıya göstermek için error akışında bir yedek metin/ikon aç. error geldiğinde isPlaying true ise false'a düşer (bu yüzden doğan pause olayı yayılmaz).",
1152
- "OYNATMAYI AKIŞTAN SÜRME: props.isPlaying true yazmak play(), false yazmak pause() demektir; bileşen de play/pause/ended olaylarında aynı prop'a geri yazar (popover isOpen deseninin aynısı). isPlaying NİYETTİR: kaynak değişirse (src yeni değer) tarayıcı eski klibi sessizce durdurur ama isPlaying true ise YENİ klip yüklenince kendiliğinden oynar — oynatma listesinde yalnız src'yi yazman yeter (2026-10-05'ten önce video duruyor ve isPlaying true takılı kalıyordu). Tarayıcı jest politikası burada da geçerlidir: SESLİ bir videoyu kullanıcı etkileşimi olmadan başlatmak REDDEDİLİR ve isPlaying hemen false'a geri yazılır (play/pause olayı YAYILMAZ); kullanıcı jesti sonrası akışın true yazması oynatır. Akıştan başlatılacak video için muted:true yaz.",
1153
- 'AUTOPLAY üç şart ister: autoplay:true + muted:true + tarayıcının izin vermesi. muted olmadan autoplay hemen hemen her tarayıcıda engellenir. Eleman her zaman playsinline ile çizilir, yani iOS Safari videoyu tam ekrana almaz. Ekranda duran bir videoda autoplay\'i sonradan açmak oynatmayı BAŞLATMAZ (ölçüldü 2026-10-05: el.autoplay true oldu, paused true kaldı).',
1154
- "loop:true iken 'ended' HİÇ yayılmaz (döngü videosu bitmez; pause da yayılmaz); 'bittiğinde şunu yap' akışı loop kapalı ister. Video bittiğinde tarayıcı HTML spesifikasyonuna göre ÖNCE 'pause' SONRA 'ended' yayar — yani 'pause'a bağlı akış, kullanıcı duraklatmasa da bitişte koşar; ikisi de isPlaying'i false yazdığı için durum aynı kalır. 'Kullanıcı duraklattı' ile 'bitti'yi ayırmak gerekiyorsa event.data.currentTime ile duration'ı karşılaştır (ölçüldü: bitişte currentTime = duration).",
1155
- "'click' olayı ancak akışa BAĞLIYSA çalışır. Sarmalayıcı HER ZAMAN <div>dir (2026-10-05'ten önce <button> idi ve controls:true iken içindeki <video controls> ikinci bir Tab durağıydı). controls:false iken sarmalayıcı role=button + tabindex=0 alır ve Enter/Boşluk da click üretir; controls:true iken düz kutu kalır: videonun kendisi tek Tab durağıdır ve klavyeyle oynat/duraklat click ÜRETMEZ. controls:true iken videonun YÜZEYİNE tıklamak hem oynatır/duraklatır hem click üretir; kontrol çubuğundaki yerel oynat/duraklat düğmesine basmak ise videoyu oynatır AMA click'i TETİKLEMEZ (ölçüldü 2026-10-05: yerel denetim çubuğu olayı sarmalayıcıya yükseltmiyor; eski 'düğmeye basmak da click tetikler' notu yanlıştı). Tıklamayı 'videoyu aç' gibi bir aksiyon için kullanacaksan controls:false ile kullan. controls:false + click bağlıyken odak sarmalayıcıdadır (video odak almaz): odak halkası için '&__wrapper:focus-visible' yaz.",
1156
- "ERİŞİLEBİLİR AD: ariaLabel <video aria-label> olur ve controls:false + click bağlıyken düğme rolündeki sarmalayıcıya da yazılır (boşsa ad yoktur; adsız düğme ekran okuyucuda yalnız 'düğme' okunur). Altyazı (<track>) desteği YOKTUR: sesli içerikte altyazıyı başka bir bileşenle (metin) ver.",
1157
- "isHidden:true iken bileşen hiç çizilmez; isLoading:true iken oynatıcı yerine nabız atan bir iskelet kutusu çizilir (src akıştan gelene kadar; prefers-reduced-motion altında nabız durur, sarmalayıcı aria-busy taşır). Oynatıcı bu iki yoldan ya da bileşenin sökülmesiyle (modal kapanışı, sekme değişimi) kalkarsa isPlaying false'a düşer; geri geldiğinde yeni eleman currentTime 0'dan başlar ve kendiliğinden BAŞLAMAZ. mount OLAYI bileşenin kendisinden DEĞİL, ortak render katmanından gelir ve bir kez yayılır (2026-09-16 turuna kadar bileşen ayrıca yayıyordu ve mount'a bağlı akış İKİ KEZ koşuyordu — ARC-006).",
1158
- "Ölçü/uyum kararı düğümün appearance kanalındadır, prop değil: widthType cover|contain elemanın object-fit'ini seçer, alignType contain'de object-position'ı (heightType auto iken de), heightType:'auto' + aspectRatio en-boy oranını verir. aspectRatio bir SAYIDIR (1.7778): '16/9' metni 'System.Double' hatasıyla reddedilir; 0 ve negatif yok sayılır. heightType auto + widthType contain artık letterbox'lar (2026-10-05'ten önce object-fit cover kalıp oranı verilmiş kutuda sessizce kırpıyordu; contain'e eşlenen fixed/fill genişlikler de aynı değişimi alır). Flex kabında appearance aynı alanda YERLEŞİM kipi taşır (fill/fixed); bunlar contain'e eşlenir: flex/fill kutusundaki video LETTERBOX'lanır; kırpmak istiyorsan widthType'ı açıkça cover yap (ARC-079). heightType:'fill' sabit yükseklikli bir container içinde DOLDURMAZ: container'ın çocuk sarmalayıcısı içerikle büyür ve gövdesi kaydırır (container tasarımı, image'de de aynı), 'doldur' kesin yükseklik zinciri ister — sabit kutu için heightType:'fixed' + heightString yaz."
1159
- ],
1160
- propNotes: {
1161
- ariaLabel: "Videonun erişilebilir adı (ekran okuyucu): <video aria-label> ve click bağlıyken sarmalayıcı <button aria-label>. Görünür bir etiket çizmez. Boşsa ad verilmez.",
1162
- src: 'Dosya alanı nesnesi YA DA mutlak/göreli URL metni. Boş bırakılırsa oynatıcı kaynaksız çizilir (poster varsa kapak görünür). Yüklenemezse error, yüklenince load olayı yayılır.',
1163
- poster: 'Oynatmadan önce görünen kapak görseli (URL metni ya da görsel alanı). Oynatma başlayınca kaybolur. Kırık bir kapak sayfayı bozmaz ama kutu oynatmaya kadar boş görünür.',
1164
- autoplay: 'Tarayıcı otomatik oynatma bayrağını kaynak İLK yüklenirken okur; ekranda duran bir videoda bu anahtarı sonradan açmak oynatmayı BAŞLATMAZ (ölçüldü 2026-10-05). muted ile birlikte kullan; akıştan başlatmak için isPlaying.',
1165
- muted: 'Sessiz oynatma. autoplay ve akıştan başlatma için pratikte zorunludur. Çalışma anında akıştan değiştirilebilir.',
1166
- controls: "Tarayıcının kendi oynatıcı kontrolleri. false iken tek oynatma yolu akıştan isPlaying'dir ve video odak almaz (Tab düşmez).",
1167
- loop: "Bitince başa sarar; açıkken 'ended' ve 'pause' olayları yayılmaz.",
1168
- isPlaying: "Çift yönlü NİYET kolu: akış yazınca oynatır/duraklatır, bileşen play/pause/ended'de geri yazar (self.isPlaying). Jestsiz sesli oynatma reddedilirse hemen false'a döner. src değişince yeni klip kendiliğinden oynar (true iken); oynatıcı sökülünce (isLoading/isHidden/modal kapanışı) ve error'da false'a düşer. Aynı değeri art arda yazmak (true iken true) bir şey yapmaz — başlatmak için önce durumun false olması gerekir.",
1169
- isLoading: "Oynatıcının YERİNE iskelet kutusu çizer — <video> elemanı hiç kurulmaz (sarmalayıcı aria-busy taşır, prefers-reduced-motion altında nabız durur). Bu sırada click olayı çalışmaz ve oynayan bir video sökülür; isPlaying false'a düşer. isLoading kapanınca yeni eleman currentTime 0'dan başlar ve kendiliğinden başlamaz. Kök style'daki köşe/kenarlık iskelete de iner; iskeleti ayrıca '&__skeleton' ile boya. isLoading açıkken load/error yayılmaz (eleman yok); kaynağı çözen sorgudan kapat.",
1170
- style: STYLE_GROUP_NOTES.styleEscape + " KÖK anahtarlar (köşe, kenarlık, gölge, filtre, opacity, objectFit, outline, transition, aspectRatio) <video> elemanına iner; sarmalayıcıya İNMEZ. PARÇALAR (iki tane, ilk adayda tutar, 2026-10-05): '&__wrapper' (<div>; controls:false + click bağlıyken role=button: TAM kutu — dolgu, zemin, gradyan çerçeve, köşe buradan verilir) ve '&__skeleton' (isLoading iskeleti). Olmayan parça adı ('&__video', '&__poster', '&__player', '&__root') sessizce etkisizdir (silentlyDropped'a düşmez). ODAK: video yalnız controls:true iken odak alır (click bağlı olsa da); controls:false + click bağlıyken odak sarmalayıcıdadır — halka için '&__wrapper:focus-visible' yaz (kök '&:focus-visible' orada tetiklenmez). '&:hover' ve '&:active' kökte (video) çalışır. <video> bir replaced element'tir: kökte '::before/::after' ÇİZİLMEZ — alttan karartma için '&__wrapper' {position:'relative'} + '&__wrapper::after' {content:\"''\", position:'absolute', inset:0, background:'linear-gradient(...)', pointerEvents:'none'} yaz. Yerel denetim çubuğu Chromium'da '&::-webkit-media-controls-panel' {background} ile boyanır (yalnız Chromium/Safari, shadow DOM: hesaplanmış değeri okunamaz). '@media', '@keyframes' (shared designerStyle) ve '!important' çalışır. Webkit önekli özellikleri kebab-case yaz ('-webkit-mask-image'); PascalCase 'WebkitMaskImage' sessizce DÜŞER (silentlyDropped). İç içe seçici ('&:hover &__wrapper') tutmaz."
1128
+ summary: 'HTML5 video oynatıcı: src + poster, autoplay/loop/muted/controls anahtarları, akıştan sürülebilen isPlaying kolu ve play/pause/ended olayları. Tarayıcının kendi kontrollerini çizer — özel oynatıcı arayüzü yoktur.',
1129
+ behavior: [
1130
+ "src hem DOSYA ALANI NESNESİ hem DÜZ URL METNİ kabul eder (getfileUrl: metin olduğu gibi kullanılır, nesnede type:'file' ise data/value, değilse absolute_path okunur). Katalog tipi 'object' görünür çünkü şemada FileProp'tur; metin yazmak geçerlidir ve akıştan gelen uç FILE alanı olduğu gibi taşınabilir. Boş src'de src özniteliği HİÇ yazılmaz (boş istek atılmaz), poster varsa yalnız kapak görünür.",
1131
+ 'OYNATMAYI AKIŞTAN SÜRME: props.isPlaying true yazmak play(), false yazmak pause() demektir; bileşen de play/pause/ended olaylarında aynı prop\'a geri yazar (popover isOpen deseninin aynısı). Tarayıcı jest politikası burada da geçerlidir — SESLİ bir videoyu kullanıcı etkileşimi olmadan başlatmak REDDEDİLİR, söz sessizce yutulur ve isPlaying bir sonraki gerçek olayda düzelir. Akıştan başlatılacak video için muted:true yaz.',
1132
+ 'AUTOPLAY üç şart ister: autoplay:true + muted:true + tarayıcının izin vermesi. muted olmadan autoplay hemen hemen her tarayıcıda engellenir. Eleman her zaman playsinline ile çizilir, yani iOS Safari videoyu tam ekrana almaz.',
1133
+ "loop:true iken 'ended' HİÇ yayılmaz (döngü videosu bitmez); 'bittiğinde şunu yap' akışı loop kapalı ister. Video bittiğinde tarayıcı HTML spesifikasyonuna göre ÖNCE 'pause' SONRA 'ended' yayar — yani 'pause'a bağlı akış, kullanıcı duraklatmasa da bitişte koşar; ikisi de isPlaying'i false yazdığı için durum aynı kalır. 'Kullanıcı duraklattı' ile 'bitti'yi ayırmak gerekiyorsa event.data.currentTime ile duration'ı karşılaştır.",
1134
+ "'click' olayı ancak akışa BAĞLIYSA sarmalayıcı <button> olur; controls:true iken oynat/duraklat düğmesine basmak da bu click'i tetikler (tıklama sarmalayıcıya kabarır). Tıklamayı 'videoyu aç' gibi bir aksiyon için kullanacaksan controls:false ile kullan.",
1135
+ "isHidden:true iken bileşen hiç çizilmez; isLoading:true iken oynatıcı yerine nabız atan bir iskelet kutusu çizilir (src akıştan gelene kadar). mount OLAYI bileşenin kendisinden DEĞİL, ortak render katmanından gelir ve bir kez yayılır (2026-09-16 turuna kadar bileşen ayrıca yayıyordu ve mount'a bağlı akış İKİ KEZ koşuyordu — ARC-006).",
1136
+ "Ölçü/uyum kararı düğümün appearance kanalındadır, prop değil: widthType cover|contain elemanın object-fit'ini seçer, alignType contain'de object-position'ı, heightType:'auto' + aspectRatio en-boy oranını verir. Flex kabında appearance aynı alanda YERLEŞİM kipi taşır (fill/fixed); bunlar 2026-09-16'dan beri contain'e eşlenir — öncesinde sınıfsız kalıp tarayıcının <video> UA varsayılanına (object-fit: contain) düşüyorlardı, yani seçim kayboluyordu ama görüntü bozulmuyordu. Pratik sonuç: flex/fill kutusundaki video LETTERBOX'lanır; kırpmak istiyorsan widthType'ı açıkça cover yap (ARC-079)."
1137
+ ],
1138
+ propNotes: {
1139
+ src: 'Dosya alanı nesnesi YA DA mutlak/göreli URL metni. Boş bırakılırsa oynatıcı kaynaksız çizilir (poster varsa kapak görünür).',
1140
+ poster: 'Oynatmadan önce görünen kapak görseli (URL metni ya da görsel alanı). Oynatma başlayınca kaybolur.',
1141
+ autoplay: 'Tarayıcı otomatik oynatma bayrağını kaynak İLK yüklenirken okur; ekranda duran bir videoda bu anahtarı sonradan açmak oynatmayı başlatmaz (bilinen tarayıcı davranışı, 2026-09-16 turunda ölçülmedi). muted ile birlikte kullan; akıştan başlatmak için isPlaying.',
1142
+ muted: 'Sessiz oynatma. autoplay ve akıştan başlatma için pratikte zorunludur.',
1143
+ controls: "Tarayıcının kendi oynatıcı kontrolleri. false iken tek oynatma yolu akıştan isPlaying'dir.",
1144
+ loop: "Bitince başa sarar; açıkken 'ended' olayı yayılmaz.",
1145
+ isPlaying: "Çift yönlü: akış yazınca oynatır/duraklatır, bileşen play/pause/ended'de geri yazar (self.isPlaying). Başlangıç değeri olarak true yazmak SESLİ videoda çalışmayabilir (jest politikası).",
1146
+ isLoading: "Oynatıcının YERİNE iskelet kutusu çizer — <video> elemanı hiç kurulmaz. Bu sırada click olayı çalışmaz ve oynayan bir video sökülür; sökülme anındaki pause yakalanamadığı için self.isPlaying true KALIR (hiçbir şey oynamadığı hâlde). isLoading kapanınca yeni eleman currentTime 0'dan başlar. Aynısı isHidden için de geçerli. src bir akıştan gelirken kullanılır.",
1147
+ style: 'Serbest CSS kaçışı; ölçü/uyum kararı appearance kanalındadır (widthType/heightType/aspectRatio).'
1171
1148
  }
1172
1149
  },
1173
1150
  qrcode: {
@@ -1193,20 +1170,17 @@ export const componentKnowledge = {
1193
1170
  tags: {
1194
1171
  summary: 'Salt gösterim etiket listesi (tag-input’un okunur akrabası); tıklanan etiketi akışa verir.',
1195
1172
  behavior: [
1196
- "values bir DİZİdir: [{ label, icon?, color?, customColor?, variant?, isActive? }]. Akıştan gelen liste çizilmeden önce süzülür: dizi olmayan değer (null, düz metin) boş liste; metin/sayı öğe renksiz etiket olur (['billing','critical'] geçerli); label yoksa öğenin value alanı okunur (tag-input değeri doğrudan bağlanabilir, hex rengi de çizilir); boş metinli ya da metinsiz öğe atlanır.",
1197
- "RENK: color bir status adıdır (primary|info|success|warning|error, tema renkleri) YA DA doğrudan çizilebilir bir CSS rengi (#hex, rgb()/hsl(), var(--ng-*) token, renk adı) — bir tag-input değerinin { value, color: '#3b82f6' } öğesi olduğu gibi bağlanınca rengiyle çizilir. Ayrıca customColor (panelde Custom color) doluysa o, color'ın (status adı olsa bile) önüne geçer. Çizilemeyen değer ('zzz', 'red; x:y', '#12345', 'rgb(zzz)', 'transparent', 'currentcolor', boş) yok sayılır: customColor geçersizse color okunur, ikisi de geçersizse etiket nötr gri çizilir. Serbest renk de status etiketi gibi açık bir ton zemin + rengin metin rengine çekilmiş hâli yazı olarak çizilir (opak renklerde, saf beyaz ve siyah dahil, açık ve koyu temada yazı ≥ 4.5:1 ölçüldü; alfa kanallı renkler ölçülmedi), outline'da kenarlık seçilen renktir; seçilen renk zemin tonunda ve kenarlıkta kalır, yazı rengini TEMA belirler. Hex renk temayı izlemez: koyu temada okunan tonu tema yazı rengi sağlar ama 'tam bu renk' beklenmez. SİMGE: icon (panelde Icon) etiket metninin önüne konur: Material Symbols adı ('star') ya da { name: 'star' } nesnesi; simge etiketin yazı rengini devralır, boş/adsız simge çizilmez. Simge dekoratiftir (ekran okuyucuya okunmaz, etiket metni adı verir). variant: solid (varsayılan, açık zemin) | outline (renkli kenarlık). isActive:true zemini belirginleştirir (hover seçili etiketi değiştirmez) — filtre çipi gibi seçili etiketi göstermek için akıştan yaz.",
1173
+ "values bir DİZİdir: [{ label, color?, variant?, isActive? }]. Akıştan gelen liste çizilmeden önce süzülür: dizi olmayan değer (null, düz metin) boş liste; metin/sayı öğe renksiz etiket olur (['billing','critical'] geçerli); label yoksa öğenin value alanı okunur (tag-input değeri doğrudan bağlanabilir, ama hex rengi burada GEÇMEZ); boş metinli ya da metinsiz öğe atlanır.",
1174
+ 'color yalnız status adıdır: primary|info|success|warning|error; başka her şey (hex dahil) nötr gri çizer. variant: solid (varsayılan, açık zemin) | outline (renkli kenarlık). isActive:true zemini belirginleştirir (hover seçili etiketi değiştirmez) — filtre çipi gibi seçili etiketi göstermek için akıştan yaz.',
1198
1175
  "Düğümün olaylarında clickItem satırı varsa etiketler düğme olur (el imleci, hover, klavyeyle odak) — satıra akış seçilmemiş olsa bile; clickItem satırı yoksa salt metindir. Yayında event.data = { currentItem, index }, öğe ayrıca self.currentItem'a yazılır. index values dizisindeki GERÇEK yerdir (atlanan öğeler kaydırmaz) — akış values[index].isActive'i değiştirip values'u geri yazarak seçimi çevirebilir. Bileşen isActive'i kendisi DEĞİŞTİRMEZ.",
1199
1176
  "Eski şemada öğe anahtarı active'di ve runtime okumuyordu (2026-09-16 düzeltildi); kayıtlı sayfalardaki active:true artık etkilidir ama paneldeki Active anahtarı onu KAPALI gösterir (isActive okur); yeni yazımda isActive kullan, eski öğeyi kapatmak için isActive:false yaz.",
1200
1177
  'Etiket eklemek/silmek gereken ekranda tag-input kullan; tags değer yazmaz, change yaymaz.',
1201
- "UZUN METİN: boşluksuz 300 karakterlik etiket de kabın içinde satır kırar; etiket en çok kabın genişliği kadar olur — &__tag'a maxWidth/overflowWrap yazmak GEREKMEZ. Etiketler satır sonunda alt satıra sarar; kökte flexWrap:'nowrap' verirsen etiketler yine sözcüğün genişliğine kadar daralır (sözcük ortasından kırılmaz, yalnız kabı aşan tek etiket kırılır).",
1202
- "ERİŞİLEBİLİRLİK: isActive olan etiket aria-current='true' taşır; seçili durumu ekran okuyucuya iletmesi tıklanabilir (button) etikette güvenilirdir, salt metin (span) etikette öznitelik taşınır ama okunması ekran okuyucuya bağlıdır — durumu başka bir yolla da anlatmak istersen etiket metnine yaz. Tıklanabilir etiket kendi metniyle adlanan bir button'dır; basılı tutulan Enter olayı BİR kez tetikler. Kök bir liste değildir (rolsüz div).",
1203
- "VERİ YAZIMI: values'a statik düz metin/sayı dizisi (['billing','critical']) ve karışık dizi KAYDEDİLEMEZ (500) — values'u kod tipinde bağla: {{ ['billing','critical'] }}. Statik öğenin label'ında {{ }} yorumlanmaz, ham basılır; ifade gerekiyorsa values'un kendisini ifade olarak yaz ({{ [{ label: state.page.x }] }}). Akış values'ı okuyup geri yazarsa label'daki çeviri sarmalı boşalır: akışta t(anahtar) ile çözülmüş metni yaz.",
1204
- "STİL HEDEFLERİ: kök CSS (gap, justifyContent, flexDirection, padding, border, fontSize, fontFamily, color…) çalışır; kökün fontSize/fontFamily'si etiketlere iner, color'ı yalnız renksiz (nötr) etikete iner — durum renkleri kendi rengini korur. '&__tag' HER etiketi hedefler (backgroundColor, color, border, borderRadius, padding, fontFamily, fontSize, fontWeight, textTransform, letterSpacing, boxShadow, textShadow, maxWidth ve linear-gradient çalışır; varyantın ve rengin zeminini ezer). Etiketin öznitelikleri durum hedefidir: &__tag[data-active='true'] (seçili), &__tag[data-color='success'] (renk), &__tag[data-variant='outline'] (varyant); bunlarla :hover, :focus-visible, ::before, :nth-child(n) ve @media birlikte yazılır. '&__tag:hover' salt metin (span) etiketine de uygulanır; YALNIZ tıklanabilirleri hedeflemek için '&__tag.ng-tag--clickable:hover'. Çakışan durum kuralları (aktif + hover aynı özellik) için kazanan anahtar sırasına bağlıdır: aynı özelliği tek seçicide ver. Etiket başına simge icon, etiket başına renk customColor/color ile verilir; renkli nokta isteniyorsa '&__tag[data-custom]::before' ile content:'', display:inline-block, width/height:8px, borderRadius:50%, marginInlineEnd:6px ve background:'var(--ng-tag-color)' yazılır (serbest renkli etiket CSS değişkeni --ng-tag-color taşır, data-custom='true' alır). Etiket başına GRADYAN özelliği YOKTUR: ':nth-child' ile yazılır (veriye bağlı değil)."
1178
+ "isDisabled:true (yalnız boolean true) etiketi soluk çizer ve tıklanamaz yapar: düğme disabled olur, clickItem çalışmaz. Sayısı 0 olan süzgeç çipi için akıştan yaz (2026-09-30)."
1205
1179
  ],
1206
1180
  propNotes: {
1207
- values: "[{ label, icon?, color?, customColor?, variant?, isActive? }] ya da düz metin dizisi (kod tipinde bağla). color: primary|info|success|warning|error ya da doğrudan CSS rengi (#hex, rgb(), var(--token), renk adı); customColor (CSS rengi) doluysa color'ı ezer; çizilemeyen renk nötr. icon: Material Symbols adı ya da { name }. variant: solid|outline.",
1181
+ values: "[{ label, color?, variant?, isActive?, isDisabled? }] ya da düz metin dizisi. color: primary|info|success|warning|error; variant: solid|outline.",
1208
1182
  currentItem: "Gizli prop: son tıklanan öğe (values'taki nesnenin tamamı, düz metin dizisinde metnin kendisi). index yalnız event.data'da.",
1209
- style: "Kök düğüm ve '&__tag' alt anahtarı (her etiket). Durum hedefleri etiketin data-active / data-color / data-variant öznitelikleridir; tıklanabilir etiketin ek sınıfı ng-tag--clickable (davranış maddesi STİL HEDEFLERİ)."
1183
+ style: "Kök düğüm ve '&__tag' alt anahtarı (her etiket)."
1210
1184
  }
1211
1185
  },
1212
1186
  notification: {
@@ -1427,7 +1401,7 @@ export const componentKnowledge = {
1427
1401
  sidebarSide: "Panelin ekranın hangi kenarında duracağı: 'left' | 'right'. sidebar, hybrid ve dual düzenlerinde anlamlı; diğerlerinde panel yoktur.",
1428
1402
  sidebarStyle: "'docked' panel kenara yapışır ve tek kenarlık taşır; 'floating' onu dört yanı boşluklu, köşeli ve gölgeli bir karta çevirir. sidebar, hybrid ve dual düzenlerinde anlamlı.",
1429
1403
  width: "Panel genişliği (px, 160–480). Rail modunda YOK SAYILIR — orada genişlik satır yüksekliği ve ikon kutusundan hesaplanır (navigation-tokens.ts railWidth). Drawer menü tipinde de okunmaz; onun genişliği drawerWidth’tir.",
1430
- collapsible: "Panelin başlığına daraltma düğmesi koyar; ziyaretçi menüyü rail’e indirip geri açabilir. Rail zaten daraltılmış olduğu için orada, drawer’da da anlamsızdır.",
1404
+ collapsible: "Panelin başlığına daraltma düğmesi koyar; ziyaretçi menüyü rail’e indirip geri açabilir; drawer’da anlamsızdır. KAPALI BAŞLAYAN MENÜ (2026-09-30): collapsible:true + displayMode:'rail' birlikte yazılırsa menü ŞERİT olarak açılır ve kenardaki chevron'la tam görünüme (width genişliğinde ikon + metin ağaç) açılır — ayrı bir 'kapalı başla' prop'u yoktur. Ziyaretçinin tercihi tarayıcıda düğüm başına saklanır (localStorage ng-nav-collapsed:<elementId>, '1' kapalı / '0' açık); kayıt yoksa bu varsayılan okunur. Tasarımcı tuvali menüyü her zaman açık çizer.",
1431
1405
  levelStyle: "Derin seviyelerin TİPOGRAFİSİ: 'uniform' her seviye aynı punto; 'tapered' 2. seviyeden itibaren satır kısalır ve yazı bir tık küçülüp soluklaşır, böylece derinlik göz kararıyla okunur. Girintiyi DEĞİŞTİRMEZ (o indent/maxIndent’in işi). Rail’de karşılığı yoktur.",
1432
1406
  nestedStyle: "Çocuğu olan satır nasıl çizilsin: 'indent' normal bir satırdır (açılır/kapanır); 'subheader' küçük bir BÖLÜM BAŞLIĞI olur ve çocukları hep açık durur. Düz menüde her dal böyledir. Akordiyonda (2026-09-25) yalnız ADRESSİZ ve isExpandable İŞARETLENMEMİŞ iç öğe başlığa döner, çocukları başlıkla aynı hizada çizilir — «Yetki yönetimi» (isExpandable: true) açılır modül kalır, içindeki «Organizasyon» etikettir. Varsayılan 'indent' kayıtlı menüleri değiştirmez.",
1433
1407
  hMenuStyle: "Header’da bir üst öğenin alt menüsü nasıl açılır: 'dropdown' altında küçük panel; 'mega' çubuğun tamamı boyunca çok kolonlu panel; 'tabs' alt öğeler ikinci bir satırda sekme çubuğu olur (açılır panel yok). Yalnız header düzeninde geçerlidir.",
@@ -1522,16 +1496,16 @@ export const componentKnowledge = {
1522
1496
  behavior: [
1523
1497
  "Gövdesi BLOK akışındadır ve çocukları 12 kolonluk IZGARA yerleştirir — hem runtime'da hem Studio tuvalinde. Gövde satır flex'i olsaydı renderer'ın çocuk sarmalayıcısı içerik genişliğine çökerdi (ölçüldü: runtime'da 1200px yerine 213px, tuvalde 0). Yani bölgelerin konumu dock prop'undan DEĞİL, blocks[]'ten gelir.",
1524
1498
  "RUNTIME'DA İZLER KABUKTAN GELİR (SHELL-002/003, 2026-09-29): çocukların blocks[] çizgilerine dokunulmaz, yalnız satır/kolon ölçüleri değişir — fill bölgesinin kapladığı satırlar kabuğun kalan yüksekliğini paylaşır (üst/alt şerit satırları sabit kalır), yalnız KAPALI bölgelerin kapladığı kolonlar 0'a iner ve fill o alanı devralır. Fill bölgesi yoksa ızgara olduğu gibi kalır. Studio tuvali bu kuralı UYGULAMAZ: tuvalde tasarımcının ızgarası görünür.",
1525
- "Mobilde (≤767px) kabuk en az ekran yüksekliğindedir; drawer bölgesi ve overlay ekrana SABİTTİR (position: fixed, çekmece min(300px, 85vw) genişlikte) — 2026-09-29'a kadar kabuk 0px'e çöküp çekmeceyi görünmez kılıyordu (SHELL-001). Açık çekmece role=dialog + aria-modal taşır; Escape kapatır.",
1526
- "sidebarOpen CANLI DURUMDUR: prop'un kendisi durumdur, toggle onu doğrudan yazar (qm-sidebar'ın isCollapsed deseni). Bir Durum değişkenine bağlanabilir ya da change-property akışıyla çevrilebilir. Mobil drawer'ın kapalı açılışı motora da yazılır (SHELL-005, 2026-09-29): ilk '!sidebarOpen' akışı artık çekmeceyi açar.",
1499
+ "Dar ekranda (≤767px) kabuk en az ekran yüksekliğindedir; drawer bölgesi ve overlay ekrana SABİTTİR (position: fixed, çekmece min(300px, 85vw) genişlikte) — 2026-09-29'a kadar kabuk 0px'e çöküp çekmeceyi görünmez kılıyordu (SHELL-001). Açık çekmece role=dialog + aria-modal taşır; Escape kapatır.",
1500
+ "sidebarOpen CANLI DURUMDUR: prop'un kendisi durumdur, toggle onu doğrudan yazar (qm-sidebar'ın isCollapsed deseni). Bir Durum değişkenine bağlanabilir ya da change-property akışıyla çevrilebilir. Dar ekranda drawer'ın kapalı açılışı motora da yazılır (SHELL-005, 2026-09-29): ilk '!sidebarOpen' akışı artık çekmeceyi açar.",
1527
1501
  "toggle olayı DURUM DEĞİŞİKLİĞİNİ bildirir (SHELL-009, 2026-09-29): overlay, Escape, bir akışın ya da Durum bağlamasının yazdığı yeni değer aynı olayı doğurur; açılıştaki çözümleme olay sayılmaz. toggle'a bağlı bir akış sidebarOpen'ı çevirirse sonsuz döngü kurar — yapmayın.",
1528
- "mobileBehavior yalnız yan panelin mobilde AÇIK BAŞLAYIP başlamayacağını belirler (resolveInitialSidebarOpen: drawer → kapalı, stack → açık). 2026-08-28'e kadar var olan 'stack ise gövdeyi column yap' CSS kuralı, gövde blok akışına geçtiği için KALDIRILDI — artık yerleşimi ızgara belirliyor.",
1502
+ "mobileBehavior yalnız yan panelin dar ekranda AÇIK BAŞLAYIP başlamayacağını belirler (resolveInitialSidebarOpen: drawer → kapalı, stack → açık). 2026-08-28'e kadar var olan 'stack ise gövdeyi column yap' CSS kuralı, gövde blok akışına geçtiği için KALDIRILDI — artık yerleşimi ızgara belirliyor.",
1529
1503
  "isViewportFilling / isShellRoot yetenekleri ve states.isShell bayrağı BACKEND'DE SAKLANMAZ (components tablosunda sütun yok, States kaydında isShell yok — zeyrek-frontend docs/issues.md BE-002). Davranışı tip adına düşen yedek listeler taşır; şema yazarken bu bayraklara güvenme."
1530
1504
  ],
1531
1505
  propNotes: {
1532
1506
  surfaceStyle: STYLE_GROUP_NOTES.surfaceStyle + ' ' + STYLE_GROUP_NOTES.colorTokens + ' Kabuk KENDİ derler (SHELL-006, 2026-09-29): değer .ng-layout-shell KÖKÜNE iner, contentOverflow da köke.',
1533
1507
  sidebarOpen: 'Yan panelin açık olup olmadığı; canlı durumdur, bağlanabilir.',
1534
- mobileBehavior: "'drawer' (varsayılan; mobilde kapalı başlar) | 'stack' (mobilde açık başlar).",
1508
+ mobileBehavior: "'drawer' (varsayılan; dar ekranda kapalı başlar) | 'stack' (dar ekranda açık başlar).",
1535
1509
  style: "&__body ve &__overlay parçaları uygulanır."
1536
1510
  }
1537
1511
  },
@@ -1565,6 +1539,20 @@ export const componentKnowledge = {
1565
1539
  ]
1566
1540
  },
1567
1541
  view: { summary: 'Tabs/switcher altındaki görünüm kapsayıcısı; children gruplamaya yarar.' },
1542
+ 'datatable-cell': {
1543
+ summary: 'datatable kolonunun HÜCRE ŞABLONU: tablonun çocuğu olan çerçevesiz kapsayıcı; içindeki bileşenler o kolonun hücresine HER SATIRDA çizilir ve satırı item olarak okur.',
1544
+ behavior: [
1545
+ "YALNIZ bir datatable'ın DOĞRUDAN çocuğu olarak anlamlıdır ve toolbox'ta yoktur (isHide). column prop'u tablonun columns[].name değerlerinden biri olmalıdır; eşleşmeyen ya da boş column ile düğüm hiçbir yerde çizilmez. Aynı column ile iki şablon varsa yalnız İLKİ çizilir.",
1546
+ "Şablonu olan kolonun hücresinde kolonun type/format ayarları (tag, progress, tarih biçimi…) ÇİZİLMEZ — hücreyi şablon doldurur; sıralama, filtre ve CSV yine satırın ham değerini kullanır. O hücre satır içi düzenlemeye açılmaz; maskeli (korumalı) hücrede şablon değil kilitli maske çizilir.",
1547
+ "İçindeki düğümlerin KOD bağlamalarında item o satırdır: {{ item.title }}. item SALT OKUNURDUR (repeater'daki gibi satıra geri yazmaz). Bağlı (connectData) tabloda item sunucudan gelen satırdır; ilişki alanı nesnedir ({{ item.kategori.ad }}).",
1548
+ 'Kapsayıcıdır (isDroppable): içine text, image, tag, button, container… bırakılır. Satır başına bir kopya çizildiği için ağır bileşen (chart, iç içe tablo) koyma; sayfa boyu × kolon sayısı kadar örnek oluşur.',
1549
+ "HÜCRENİN KAPSAYICISIDIR (2026-09-21): container'ın yerleşim prop'larını taşır — layout flex (varsayılan, 2026-09-22; direction row) | grid (12 kolonluk ızgara); flex'te direction/horizontalAlign/verticalAlign/gap/wrap. Kapsayıcısı çerçevesiz ve SAYDAMDIR (satırın zemini görünür; style.background ezer). Tasarımcı yarattığında iç/dış boşluğu yoktur (appearance paddingType/marginType none) ve element id'si kolon adıyla başlar (<kolon>-cell…). Tek başına silinemez (isDeletable false); şablonu kaldırmak kolonu kendi biçimine (tag, progress…) döndürür. Tasarımcı yeni hücreye kolonun değerine kodla bağlı bir text koyar ({{ item.<kolon> }}, ilişkide {{ item.<kolon>.<görünen alan> }})."
1550
+ ],
1551
+ propNotes: {
1552
+ column: "Şablonun ait olduğu kolonun name'i (columns[].name). Zorunlu; tasarımcıda kolon başlığındaki tasarım düğmesi yazar.",
1553
+ layout: "flex (varsayılan, direction row) | grid — container'ınkiyle aynı anlam; flex'te direction, horizontalAlign, verticalAlign, gap ve wrap açıktır, grid'de gizlenir."
1554
+ }
1555
+ },
1568
1556
  'widget-area': {
1569
1557
  summary: 'Widget’ların yerleştirildiği alan: widget şemasının KÖK düğümü (widgetType: container).',
1570
1558
  behavior: [
@@ -1577,26 +1565,23 @@ export const componentKnowledge = {
1577
1565
  summary: 'Kayıt künyesi: oluşturan/son güncelleyen ve ne zaman. Tek setter ile meta prop’una kaydın meta nesnesi bağlanır.',
1578
1566
  behavior: [
1579
1567
  "meta, kaydı getiren get servisi adımının (get_service) data.meta'sıdır: createdAt, createdUserId, createdUserEmail, createdUserFirstName, createdUserLastName, createdUserFullName ve aynı updated* alanları. Ad önce *UserFullName, yoksa FirstName + LastName, o da yoksa e-posta; e-posta ad değilse alt satırda (createdSubtle/updatedSubtle doluysa onun yerine) basılır.",
1580
- 'Kaynak kararı meta’nın bütününe göre verilir: meta iki taraftan (created/updated) HERHANGİ birine ait bir alan taşıyorsa İKİ taraf da TAMAMEN meta’dan okunur — createdBy/createdAt gibi statik prop’lar (şema varsayılanı John Doe, Erick Gallagher) hiçbir tarafa karışmaz; meta’nın anmadığı taraf (hiç güncellenmemiş kayıt) çizilmez. Statik prop’lar yalnız meta hiç denetim alanı taşımıyorsa (yok, boş nesne, nesne değil) çizilir; kayıt yüklenene dek demo adın görünmemesi için createdBy/updatedBy’ı boş yaz.',
1581
- 'data.meta İKİ koşul birlikte sağlanınca gelir: entity’de denetim izi açık (isAuditTrailActive: true, auditTrailType: basic) VE get servisi adımının kaynak ayarında includeHistory: true. Denetim izi tek başına yetmez — includeHistory’siz data.meta hiç oluşmaz ve iki taraf da statik prop’ları (John Doe…) çizer, hata görünmez. Gerçek sayfada createdBy/updatedBy/createdAt/updatedAt’i boşalt.',
1582
- 'Denetim izi asenkron yazılır: kaydı güncelleyen akış hemen ardından get servisini koşarsa eski updatedAt gelir; künyeyi tazelemek için kısa bir bekleme ya da ikinci okuma gerekir. Sayfa akışı anonim güncellerse updatedUserId boştur ve güncelleyen satırı adsız, yalnız tarihle çizilir.',
1568
+ 'Taraf başına karar: meta o tarafın (created/updated) HERHANGİ bir alanını taşıyorsa o taraf TAMAMEN meta’dan okunur — createdBy/createdAt gibi statik prop’lar (şema varsayılanı John Doe) karışmaz. Meta tarafı hiç anmıyorsa statik prop’lar çizilir; kayıt yüklenene dek demo adın görünmemesi için createdBy/updatedBy’ı boş yaz.',
1569
+ 'Backend meta’yı YALNIZ entity’de denetim izi (AuditTrailType) açıksa ya da istekte history isteniyorsa ekler; değilse data.meta yoktur ve iki taraf da statik prop’ları (John Doe…) çizer — gerçek sayfada createdBy/updatedBy/createdAt/updatedAt’i boşalt ya da entity’de denetim izini aç.',
1583
1570
  'Bir taraf ad ya da tarih taşımıyorsa hiç çizilmez; ikisi de boşsa yalnız title kalır. meta nesne değilse (null, metin, dizi) boş sayılır.',
1584
- 'Tarih ISO metin (ya da Date) olmalı; başka biçim olduğu gibi basılır — takvimde olmayan gün de (2026-02-30, 2026-13-45) ham kalır, başka bir güne kaymaz. Saatsiz tarih (2026-02-13) yalnız tarih olarak basılır. relative gelecekteki zamanı şimdi sayar ve canlı güncellenmez. Dil uygulama dilidir (locale prop’u yok).',
1585
- 'Etiketler (createText/updateText boşken) tr, en ve ar sözlüğünden gelir; başka dil İngilizce okur. Boşluksuz uzun ad, e-posta, başlık ve etiket satıra bölünür, künyeyi taşırmaz.',
1586
- 'isLoading açıkken iki satırlık iskelet çizilir (ekran okuyucuya gizli, aria-busy kapta). Runtime kendisi yazmaz: kaydı getiren akış başta true, meta’yı yazarken false yazar. prefers-reduced-motion açıkken iskelet nabız atmaz.',
1587
- 'Erişilebilirlik: satırlar liste (list/listitem), ikon süs (aria-hidden) — okunan metin "Oluşturan Ayşe Kaya … 25 Ağu 2026". Künye tıklanabilir değildir, odak almaz.'
1571
+ 'Tarih ISO metin (ya da Date) olmalı; başka biçim olduğu gibi basılır. Saatsiz tarih (2026-02-13) yalnız tarih olarak basılır. relative gelecekteki zamanı şimdi sayar ve canlı güncellenmez. Dil uygulama dilidir (locale prop’u yok).',
1572
+ 'isLoading açıkken iki satırlık iskelet çizilir. Runtime kendisi yazmaz: kaydı getiren akış başta true, meta’yı yazarken false yazar.'
1588
1573
  ],
1589
1574
  propNotes: {
1590
1575
  meta: "Kaydın meta nesnesi; değer {type:'storage', ref:'<adım ADI>.data.meta'}. Alanları behavior’da.",
1591
- createdBy: 'Meta hiç denetim alanı (created*/updated*) taşımadığında basılan statik ad (varsayılan John Doe — gerçek sayfada boşalt).',
1592
- updatedBy: 'Meta hiç denetim alanı (created*/updated*) taşımadığında basılan statik ad (varsayılan Erick Gallagher — gerçek sayfada boşalt).',
1593
- createText: 'Oluşturan satırının etiketi; boşsa uygulama dilinde "Oluşturan"/"Created by"/"تم الإنشاء بواسطة".',
1594
- updateText: 'Güncelleyen satırının etiketi; boşsa uygulama dilinde "Güncelleyen"/"Updated by"/"تم التحديث بواسطة".',
1595
- createIcon: 'Ad (person_add varsayılan) ya da IconProp nesnesi; boşluk-yalnız ad varsayılana düşer. İkon rengi yoktur (renk seçici kapalı): rengi style ile &__icon { color } yaz. Geçersiz ad ikon kutusunda kırpılır, kutuyu aşmaz.',
1596
- updateIcon: 'Ad (person_edit varsayılan) ya da IconProp nesnesi; createIcon ile aynı kurallar.',
1576
+ createdBy: 'Meta created* alanı taşımadığında basılan statik ad (varsayılan John Doe — gerçek sayfada boşalt).',
1577
+ updatedBy: 'Meta updated* alanı taşımadığında basılan statik ad (varsayılan Erick Gallagher — gerçek sayfada boşalt).',
1578
+ createText: 'Oluşturan satırının etiketi; boşsa uygulama dilinde "Oluşturan"/"Created by".',
1579
+ updateText: 'Güncelleyen satırının etiketi; boşsa uygulama dilinde "Güncelleyen"/"Updated by".',
1580
+ createIcon: 'Ad (person_add varsayılan) ya da IconProp nesnesi.',
1581
+ updateIcon: 'Ad (person_edit varsayılan) ya da IconProp nesnesi.',
1597
1582
  dateFormat: 'absolute (varsayılan; dilin kısa tarih + saat biçimi) | relative ("3 gün önce").',
1598
1583
  isLoading: 'true iken içerik yerine iskelet.',
1599
- style: 'Kök + parçalar: &__title, &__items (satırların kabı; aralık gap), &__item (her satır), &__icon (yuvarlak ikon kutusu; boyut width/height, fontSize hem kutuyu hem glifi ölçekler), &__text (etiket-ad-alt metin-tarih sütunu), &__label, &__value (ad), &__subtle (e-posta/alt metin), &__date. Satır durumları: &__item--created ve &__item--updated (hangi satır olduğu; iki satırı farklı boyamak için :nth-child yerine bunu kullan; satırda ayrıca data-side="created|updated"), &__item--skeleton (isLoading). Kök fontSize, color ve fontFamily içe iner: parçalar boyutlarını em ile kökten alır, ikincil metin rengi kökün rengidir (%72). Üst kabın yazı tipi künyeye geçmez (tema jetonu), gerekirse künyenin kendi style kökünde ver.'
1584
+ style: 'Kök + &__item (her satır) + &__icon (yuvarlak ikon kutusu).'
1600
1585
  }
1601
1586
  },
1602
1587
  'audit-history': {
@@ -1604,48 +1589,24 @@ export const componentKnowledge = {
1604
1589
  behavior: [
1605
1590
  "histories iki kayıt biçimini aynı kuralla okur. (1) Backend geçmişi — kaydı getiren get servisi adımının data.meta.history'si: { id, occurredAt, userId, userEmail, userFirstName, userLastName, action: CREATE|UPDATE|DELETE, ipAddress, changedFields: [{ fieldId, fieldSlug, fieldName, previousValue, currentValue }] }. (2) Kart alanları — { type, title, username, createdAt, status, statusLabel, icon, previousValue, currentValue }. Kart alanı doluysa kazanır, boşsa backend alanından türetilir: username ← userFirstName + userLastName ← userEmail; createdAt ← occurredAt; status/statusLabel/title/icon ← action (CREATE success 'Oluşturuldu'/'kaydı oluşturdu.', UPDATE primary 'Güncellendi', DELETE danger 'Silindi'; dil bileşenin dili).",
1606
1591
  'changedFields’ın her satırı kartta "fieldName: önceki → şimdiki" satırı olur (fieldName yoksa fieldSlug); iki değeri de boş satır çizilmez. Değer nesneyse JSON basılır. Üst düzey previousValue/currentValue etiketsiz tek satırdır.',
1607
- 'meta.history İKİ şartla gelir: (1) kaydı getiren get servisi adımının kaynak ayarında includeHistory: true (microservice kaydında sourceParameters.includeHistory; kapalıysa data.meta hiç oluşmaz), (2) entity’de denetim izi: isAuditTrailActive true ve auditTrailType (Basic ya da Detailed) (ya da adımın requestedHistoryType’ı; entity türünü aşarsa istek hata verir). Simple’da history null’dır; changedFields yalnız Detailed’da dolar. Tek ya da liste getirmede kayıt başına EN YENİ 5 işlem gelir ve eskisini sayfa sayfa getiren bir akış yolu yoktur (meta.historyTotalCount toplamı söyler).',
1592
+ 'meta.history İKİ şartla gelir: (1) kaydı getiren get servisi adımının kaynak ayarında includeHistory: true (kapalıysa data.meta hiç oluşmaz), (2) entity’de denetim izi (AuditTrailType) Basic ya da Detailed (ya da adımın requestedHistoryType’ı; entity türünü aşarsa istek hata verir). Simple’da history null’dır; changedFields yalnız Detailed’da dolar. Tek ya da liste getirmede kayıt başına EN YENİ 5 işlem gelir ve eskisini sayfa sayfa getiren bir akış yolu yoktur (meta.historyTotalCount toplamı söyler).',
1608
1593
  'Sıralama yapılmaz: dizi geldiği sırayla çizilir (backend en yeniyi başa koyar). Nesne olmayan öğe (null, metin) atlanır; histories dizi değilse boş durum çizilir.',
1609
- 'visibleLogCount üstü kayıtlar atılmaz: altta "Daha fazla göster (N)" çıkar, her basış sınırı visibleLogCount kadar büyütür ve showMore yayar. Boş/0 = hepsi görünür. Backend en fazla 5 işlem verdiği için meta.history bağlıyken düğme ancak visibleLogCount 5’ten küçükken görünür; showMore veri çekmez. Açılan sınır, listenin EN YENİ (ilk) girdisi değişince (başka kayda geçince ya da yeni işlem gelince) başa döner; aynı veri yeniden gelince, yalnız eski girdiler değişince ya da dil değişince açık kalır. İlk girdinin en yeni olduğu varsayılır (backend böyle verir; dizi tersse yeni işlem sınırı sıfırlamaz) ve aynı saniyede, aynı tür ve kullanıcıyla başlayan iki kayıt aynı kimlik sayılır.',
1594
+ 'visibleLogCount üstü kayıtlar atılmaz: altta "Daha fazla göster (N)" çıkar, her basış sınırı visibleLogCount kadar büyütür ve showMore yayar. Boş/0 = hepsi görünür. Backend en fazla 5 işlem verdiği için meta.history bağlıyken düğme ancak visibleLogCount 5’ten küçükken görünür; showMore veri çekmez. Açılan sınır histories değişince (başka kayda geçince de) SIFIRLANMAZ.',
1610
1595
  'Şema varsayılanı 5 demo kayıttır (James Anderson…): gerçek sayfada histories’i akışa bağla; kayıt gelene dek demo görünmesin istiyorsan başlangıçta isLoading true ya da histories [] yaz.',
1611
- 'isLoading açıkken 5 satırlık iskelet çizilir; runtime kendisi yazmaz, akış yazar.',
1612
- "Detailed denetim izinde bir UPDATE girdisinin changedFields'ı DEĞİŞMEYEN alanları da taşır (yalnız currentValue ile, kaydın şimdiki değerinin kopyası; gerçek değişimde previousValue de vardır): her güncelleme kartı kayıttaki alan sayısı kadar satır basar. Bileşen bir alanın 'değişmedi' mi 'boştan doldu' mu olduğunu ayırt edemediği için süzmez (backend kaydı: BE-015). Kalabalığı azaltmak için akışta histories'i bir code ifadesiyle süzüp (ör. changedFields içinde previousValue'su olanlar) yaz.",
1613
- "Geçmiş girdisi kullanıcı adı olarak userFirstName + userLastName'i, yoksa userEmail'i okur; çalışan backend meta.history girdilerinde ad/soyad döndürmüyorsa kartta e-posta görünür (BE-016) — kart alanıyla (username) elle verilen ad bunu ezer.",
1614
- "Dil: locale boşken uygulama dili. tr, en ve ar için tarih, boş durum, 'Daha fazla göster' ve CREATE/UPDATE/DELETE etiketleri o dilde çıkar; başka dil İngilizce okur. locale seçeneği tr, en ve ar listeler; başka dil için locale'i boş bırak ve uygulama dilini o yap, metinler İngilizce okunur.",
1615
- "Kayıt tarihi takvimde olmayan gün (2026-02-30, 2026-13-45) ya da 1900’den eski yıl (0001-01-01, .NET DateTime.MinValue “tarih yok” değeri) ise başka güne kaydırılmaz, metin olduğu gibi basılır; saat içermeyen tarih takvim günüdür.",
1616
- "Erişilebilirlik: liste role=list, kart role=listitem; ikonlar ve ok ekran okuyucudan gizlidir; eski → yeni değer del/ins ile işaretlidir. Daha fazla göster'e basınca odak ilk yeni karta geçer (düğme kalksa da odak kaybolmaz). RTL'de bağlantı çizgisi, ayırıcı ve ok yönü otomatik döner; prefers-reduced-motion altında iskelet durur. Yüklenirken dilde \"Geçmiş yükleniyor\" metni görünmez bir canlı bölgeye (role=status) yazılır, iskelet satırları ekran okuyucudan gizlidir; connector rail iskeletin çizgisini de kesintisiz çizer, none çizgisiz bırakır, iconStyle dot iskelette de nokta boyunu uygular."
1596
+ 'isLoading açıkken 5 satırlık iskelet çizilir; runtime kendisi yazmaz, akış yazar.'
1617
1597
  ],
1618
1598
  propNotes: {
1619
1599
  histories: "Değer {type:'storage', ref:'<adım ADI>.data.meta.history'} ya da kart alanlarıyla dizi; iki biçim behavior’da.",
1620
1600
  visibleLogCount: 'İlk görünen kayıt sayısı (varsayılan 15); aşılınca "Daha fazla göster" çıkar. Boş/0 = hepsi.',
1621
1601
  showMoreText: 'Düğme metni; boşsa dilde "Daha fazla göster"/"Show more". Yanına gizli kayıt sayısı eklenir. Panelde yalnız visibleLogCount doluyken görünür.',
1622
1602
  emptyText: 'Liste boşken başlık; boşsa dilde "Geçmiş kaydı bulunmuyor" + açıklama. Doluysa açıklama çizilmez.',
1623
- dateFormat: 'absolute (varsayılan; "11 Mart 2026 09:24") | relative ("3 gün önce", canlı güncellenmez, gelecek zaman şimdi sayılır). ISO olmayan metin ve takvimde olmayan gün (2026-02-30) olduğu gibi basılır.',
1624
- connector: 'Kartlar arası dikey çizgi: stub (varsayılan; ikon daireleri arasında kısa çizgi, eski görünüm) | rail (ikonun üstünden ve altından kartın kenarına, komşu kartlarla kesintisiz birleşen çizgi; her kart yüksekliğinde ve ikon boyutunda çalışır) | none (çizgisiz). Tanınmayan değer stub okunur. İkonu küçültüp nokta yapmak için ikon boyutunu &__item { "--audit-hst-icon": "14px" } ile ver (daire ve çizgi birlikte uyar); &__icon width/height çizgiyi taşımaz. rail çizgisi &__connector ile boyanır (width, background; her kartta iki parça olduğu için gradyan her kartta yeniden başlar, tek parça gradyan olmaz). Kartı start tarafında kaydıracaksan padding yerine border-inline-start ya da margin ver: çizgi kartın kenarından ikonun yarısı kadar içeride durur, padding ikonu iter ama çizgiyi itmez. Kartlar bitişik olmalı ve ikon kartın dikey ortasında durmalı: &__list ya da &__item ile dikey margin/gap ve asimetrik padding-top/bottom rail çizgisini böler.',
1625
- locale: 'Tarih, işlem etiketi, düğme ve boş durum dili; boşsa uygulama dili (ar dahil). Listede tr, en ve ar var; başka dil için boş bırak ve uygulama dilini o yap (metinler İngilizce okunur).',
1626
- iconStyle: 'Kartın işaretçisi: icon (varsayılan; durum ikonu) | dot (ikonsuz dolu nokta, durumun renginde, çevresinde 3 px açık halka; zaman çizgisi görünümü). dot boyutunu &__item { "--audit-hst-icon": "18px" } ile ayarla; connector rail ile birlikte nokta ve çizgi aynı eksende durur. Tanınmayan değer icon okunur. Noktayı &__icon ile boya (background, border); glifi gizlemek için fontSize: 0 numarasına gerek kalmaz.',
1603
+ dateFormat: 'absolute (varsayılan; "11 Mart 2026 09:24") | relative ("3 gün önce", canlı güncellenmez, gelecek zaman şimdi sayılır). ISO olmayan metin olduğu gibi basılır.',
1604
+ locale: 'Tarih, işlem etiketi ve boş durum dili; boşsa uygulama dili.',
1627
1605
  isLoading: 'true iken içerik yerine iskelet.',
1628
- style: 'Kök + parçalar: &__title (başlık), &__list (kartların kabı), &__connector (yalnız connector rail: ikonun üstündeki ve altındaki çizgi parçaları), &__item (her kart; ayrıca data-status="primary|success|danger|warning|info" — durum başına farklı boyamak için [data-status="danger"] hedefle, :nth-child yerine), &__icon (yuvarlak ikon kutusu ya da iconStyle dot noktası; boyut --audit-hst-icon, glif fontSize ile ölçeklenir), &__type (tür etiketi), &__name (kullanıcı adı + mesaj satırı), &__message (yalnız mesaj), &__date, &__diff (her alan değişikliği satırı), &__status (durum rozeti), &__more (Daha fazla göster düğmesi; :hover ve :focus-visible alır), &__empty (boş durum kutusu). Durumlar: &__item:hover, &__item:last-child, &__item:nth-child(odd), @media. &__item::before (yatay ayırıcı) ve &__item::after (kısa çizgi) bileşenin kendi çizgileridir: display, background, width, height, border yazılır (connector none ya da rail ile kapatılır), content YAZILAMAZ (bileşenin kendi content kuralı kazanır, yazdığın sessizce etkisiz kalır). Kök fontSize, color ve fontFamily içe iner: parçalar boyutlarını em ile kökten alır, ikincil metin (tarih, tür, önceki değer) kökün renginin %72 oranındadır; kökte color verince durum rozetinin metni yine durumun rengine karışır (okunur kalır). Üst kabın yazı tipi kartlara geçmez (tema jetonu), gerekirse bu bileşenin kendi style kökünde ver.'
1606
+ style: 'Kök + &__title, &__item (her kart), &__icon (yuvarlak ikon), &__status (durum rozeti), &__empty (boş durum kutusu).'
1629
1607
  }
1630
1608
  },
1631
- 'document-editor': {
1632
- summary: 'Office belgesini (docx · xlsx · pptx · txt) sayfa içinde görüntüler ve düzenler; dosya yokken düzenleme kipi yeni belge oluşturma düğmelerini gösterir.',
1633
- behavior: [
1634
- "Dört durum çizer: dosya yok + mode 'view' → 📄 ve emptyText; dosya yok + mode 'edit' → başlık (emptyText) ve Word · Excel · PowerPoint · Metin Belgesi düğmeleri; açılış sürerken ya da isLoading true iken yükleyici; hata → ⚠, errorText ve ikinci satırda ayrıntı. Belge açıkken editör kutuyu doldurur.",
1635
- "file üç biçim kabul eder: Drive dosyası, FileInput/Dropzone'dan gelen inline base64 dosya, düz URL metni. URL açılamazsa (404, ağ hatası, geçersiz adres) hata durumu çizilir; ayrıntı satırı dosya servisi hatasında 'Belge alınamadı (404)' (dile göre), ağ hatasında yalnız 'Belge alınamadı' olur. mode 'view' | 'edit' dışındaki değer şema doğrulamasında REDDEDİLİR (422); bağlı ifade null dönerse view gibi davranır.",
1636
- "emptyText ve errorText BOŞ ya da yalnız boşluk bırakılırsa dilin varsayılanı çıkar (tr 'Yeni bir döküman oluşturun' · 'Döküman yüklenemedi.', en 'Create a new document' · 'The document could not be loaded.', ar). Şema varsayılanı artık BOŞTUR; eski kayıtta Türkçe metin yazılı kalmış sayfa o metinde kalır. Edit kipinde emptyText düğmelerin başlığıdır ve boşsa 'Yeni belge oluştur' çıkar.",
1637
- "Düzenleme sonrası değişiklikler 400 ms debounce ile hidden value prop'una (base64) yazılır, kaydederken hidden isSaving true olur — ikisi de setter ile bağlanır. value doluyken file değişse bile kullanıcının düzenlemesi korunur, dosya yeniden indirilmez.",
1638
- "EDİTÖR MOTORU DIŞ HİZMETTİR: belgeyi açan/oluşturan iframe, studio kök layout'unun yüklediği editor-sdk.js üzerinden uzak ofis sunucusunda çalışır (VITE_DOCS_API_JS_URL). Belge açma, oluşturma, düzenleme ve mode geçişi bu hizmete ulaşılabilirken çalışır; boş / hata / yükleniyor durumları yerelde tamdır. Editör dili şimdilik hep 'tr' gönderilir.",
1639
- "İç ekranlar (boş · oluştur · hata · yükleniyor) SAYDAMDIR: style ve surfaceStyle zemini (gradyan dahil) altından görünür. Kök fontSize, color ve fontFamily iç metinlere iner (em / currentColor; düğme rengi ayrıdır, &__button ile); uzun ve boşluksuz metin satırlara bölünür, taşan içerik kırpılmaz kaydırılır. Düğme simgeleri sabit Office marka renklerindedir (Word mavi, Excel yeşil, PowerPoint kırmızı): koyu ya da canlı zeminde simge kontrastı düşer, style ile boyanmaz.",
1640
- "Kapsayıcı değildir: katalog droppable diyor ama çocuk slot'u çizilmez (CQ-278) — içine bileşen koyma.",
1641
- ],
1642
- propNotes: {
1643
- style: "style PARÇALARI (hepsi bildirilmiştir ve kendi öğesini boyar): &__empty (view'da boş durum kutusu) · &__create (edit'te oluştur kutusu) · &__title (oluştur başlığı) · &__button (Word/Excel/PowerPoint/Metin düğmesi; :hover ve :focus-visible bunda) · &__error (hata kutusu) · &__text (boş durum ve hata metni) · &__detail (hata ayrıntı satırı) · &__loading (yükleniyor katmanı). Kök fontSize, color ve fontFamily iç metinlere iner (düğme etiketi fontSize ve fontFamily'i izler; düğme rengi &__button ile verilir); border · borderRadius · background kök kutuyu boyar. Durum sınıfı yoktur: hangi ekranın çizildiği parça adından anlaşılır (örn. '&__error { border: ... }' yalnız hata varken boyar).",
1644
- emptyText: "Boş bırakırsan dilin varsayılanı çıkar. view kipinde 📄'in altındaki metindir; edit kipinde düğmelerin başlığıdır.",
1645
- errorText: "Boş bırakırsan dilin varsayılanı çıkar. Altındaki ayrıntı satırı ('Belge alınamadı (404)') ayrıdır, errorText ile değişmez; &__detail ile boyanır.",
1646
- surfaceStyle: NODE_SURFACE_NOTE,
1647
- },
1648
- },
1609
+ 'document-editor': { summary: 'Office şablon doldurma/görüntüleme editörü; file prop’una drive dosyası bağlanır.', propNotes: { surfaceStyle: NODE_SURFACE_NOTE } },
1649
1610
  'qm-header': {
1650
1611
  summary: 'QM uygulama başlığı: global arama, bildirimler, hesap menüsü, çok seviyeli mega menü.',
1651
1612
  behavior: [
@@ -1695,24 +1656,16 @@ export const componentKnowledge = {
1695
1656
  behavior: [
1696
1657
  'click olayı yalnız bağlıysa komponent tıklanabilir hâle gelir (image deseni); isLoading açıkken tıklanmaz.',
1697
1658
  'İçerik önceliği HER kipte aynı: src → name baş harfleri → fallbackIcon. Yani name doluyken ikon çizilmez; ikonun görünmesi için name boş olmalı.',
1698
- 'Baş harfler ilk ve son kelimenin ilk HARF ya da RAKAMIDIR: noktalama, tırnak ve emoji atlanır (\'John (Admin)\' → JA), vekil çiftli karakter (𠮷) bölünmez, büyütme uygulama diliyle yapılır (tr: ilker → İ). Arapça gibi bitişik yazılan yazılarda iki harfin arasına birleştirmeyi kesen sıfır genişlikli ayırıcı girer. name metin ya da sayı değilse (nesne, dizi) ya da çözülmemiş bir {{ }} ise boş sayılır, ikona düşer.',
1699
- "ERİŞİLEBİLİR AD: açık ariaLabel doluysa o okunur; değilse ad + durum (yerelleştirilmiş: Çevrimiçi/Online…) + rozet değeri virgülle birleşir. Tıklanabilirde bu düğmenin adıdır; tıklanamayan tekil avatarda role=img adıdır; grupta her kişi kendi adıyla bir görseldir. Tıklanabilir grubun adı yalnız GÖRÜNEN adlar + taşan sayı ('Ali, Can, +3'); '+N' çipinin etiketi '+3: Ece, Mert, Zeynep'. Hesap menüsü gibi bir EYLEM avatarında ariaLabel'a eylemi yaz ('Hesap menüsü'), kişi adını değil. Ad yoksa tıklanabilir avatar 'Profil görseli' diye okunur.",
1700
1659
  'Akıştan boş dizi gelirse emptyText yazılır. emptyText VERİLMEMİŞSE bileşen tekil avatara düşer (src/name, ikisi de boşsa person ikonu) — yani "kimse yok" demenin tek yolu emptyText doldurmaktır; grup bağlarken onu da ver.',
1701
1660
  'mount akış tetikler: items’ı dolduran sorgu buradan koşulur, yükleniyor süresince isLoading ile nabız atan daire çizilir.'
1702
1661
  ],
1703
1662
  propNotes: {
1704
1663
  src: 'Görsel URL’i ya da drive dosyası; yüklenemezse baş harflere düşer.',
1705
- name: "Baş harflerin üretildiği ad; VARSAYILANI YOKTUR ve yazmak şart değil — adsız avatar fallbackIcon çizer. Doluyken fallbackIcon çizilmez. Metin ya da sayı olmayan değer boş sayılır.",
1706
- ariaLabel: "Ekran okuyucunun okuyacağı ad (kişi adının, durumun ve rozetin yerine geçer). Boşsa ad + durum + rozet okunur. Eylem avatarında ('Hesap menüsü') doldur.",
1707
- fallbackIcon: "Ne görsel ne ad varken çizilen ikon; varsayılanı { name: 'person' } ve düğümde hiç yazılı olmasa da çizilir (null ya da {} ikonu kapatır). Ekran okuyucudan gizlidir.",
1664
+ name: 'Baş harflerin üretildiği ad; VARSAYILANI YOKTUR. Doluyken fallbackIcon çizilmez.',
1665
+ fallbackIcon: "Ne görsel ne ad varken çizilen ikon; varsayılanı { name: 'person' }.",
1708
1666
  items: 'Grup kipi: her öğe kendi src/name’ini taşır, maxCount üstü "+N" olur. Boş dizi = emptyText.',
1709
1667
  emptyText: 'items DİZİ olarak gelip boş olduğunda yazılır; src/name bunu engellemez. Boş bırakılırsa boş grup tekil avatar gibi çizilir.',
1710
- status: 'Alt uç köşedeki durum noktası (LTR sağ alt, RTL sol alt); yalnız TEKİL avatarda çizilir (grupta kimin olduğu belirsiz olurdu). Erişilebilir adın parçasıdır, ayrıca okunmaz.',
1711
- size: "xs sm md lg xl; bilinmeyen/boş değer md olur. xs'te baş harf 9 px altına inmez.",
1712
- spacing: "Grupta binme yüzdesi. 0 ve boş = %30 varsayılanı (0 'binmesiz' DEMEK DEĞİLDİR); kenar kenara için 1 yaz. Negatif/geçersiz = %30.",
1713
- badgeValue: "Köşe sayaç rozeti (RTL'de sol üst). 0 ve boş metin gizler (Badge ile aynı sayaç kuralı), 99 üstü '99+', uzun metin kırpılır ve tamamı title'dadır. Metin ya da sayı olmayan değer çizilmez.",
1714
- badgeColor: 'Rozet zemini; yazı rengi zeminden otomatik seçilir (warning/info koyu, öbürleri açık). Geçersiz değer error olur.',
1715
- style: "Serbest CSS; kök kutuya iner. Parçalar: &__item (avatar dairesi, iskelet dahil), &__status (nokta), &__overflow (+N çipi), &__badge (sayaç rozeti), &__empty (boş grup yazısı). {{ }} ile BAĞLANAN style uygulanmaz; parça içine @keyframes yazma, üst düzeye yaz.",
1668
+ status: 'Sağ alt köşedeki durum noktası; yalnız TEKİL avatarda çizilir (grupta kimin olduğu belirsiz olurdu).',
1716
1669
  hasRing: 'Avatarın çevresindeki halka — tekil ve grup kipinde de çizilir; grupta üst üste binen avatarları ayıran şey odur.',
1717
1670
  ringColor: 'Halkanın rengi; boş bırakılırsa yüzey rengi kullanılır (kart içinde görünmez, renkli zeminde bunu doldur).',
1718
1671
  isLoading: 'İçerik yerine nabız atan nötr daire(ler) çizer; rozet, durum noktası ve tıklama kapanır.'
@@ -1721,27 +1674,19 @@ export const componentKnowledge = {
1721
1674
  badge: {
1722
1675
  summary: 'Sayaç/durum rozeti: maxCount üstü "99+" olur, 0 showZero verilmedikçe gizlenir, isDot ile salt nokta çizer.',
1723
1676
  behavior: [
1724
- 'value YALNIZ düz ondalık sayıysa ("12", "-3", "12.5") sayaçtır: 0 gizlenir (showZero açıkken yazıldığı gibi çizilir, "00" → "00"), maxCount aşılırsa "99+". Başka her şey METİN olarak aynen basılır: "Yeni", "Beta", "007", "1e3", "0x1F", "+5", ".5" — durum rozeti böyle kurulur. Metin ya da sonlu sayı olmayan değer (nesne, dizi, true, NaN, Infinity) ve çözülmemiş "{{ }}" rozeti GİZLER; "[object Object]" ya da "NaN" basılmaz.',
1725
- 'Uzun metin, rozet doldurma genişlikli bir hücredeyse kapta üç noktayla kesilir ve kırpıldığı sürece tamamı fare ipucunda (title) görünür (kap genişleyince ipucu kalkar); sarmasını istiyorsan kök style\'a whiteSpace: normal yaz (rozet uzar). `flex-wrap` bir satırdaki auto genişlikli düğümde ise düğüm sarmalayıcısı metin kadar açılır ve kap rozeti görünmez biçimde keser (ARC-174). 99+ gibi kısaltılan sayının gerçek değeri de title\'a kendiliğinden yazılır; bu alana daha önce ortak appearance.tooltip yazılmışsa ikisi birden görünür, ortak ipucunu temizle.',
1726
- 'Rozet kendi yazı boyutuna göre ölçeklenir: size yazıyı seçer, kök style\'daki fontSize rozeti (yükseklik, ikon) birlikte büyütür. Yalnız rakam ve işaretten oluşan metin (sayaç: "99+") RTL sayfada bile soldan sağa okunur ("+99" çizilmez); harf içeren metin ("Yeni", "مرحبا") sayfanın yönünü izler.',
1727
- 'Yazı rengi zeminin ÇÖZÜLMÜŞ renginden seçilir: solid\'de ton (özel açık renkte — sarı, #fff — ve koyu temadaki warning\'de koyu yazı), soft\'ta tonun %15\'inin yüzeye karışmış hâli, outline\'da yüzey. Soft/outline yazısı ton rengini koyulaştırarak/açarak okunur kılar (warning, info, açık custom). textColor verirsen bu devre dışı kalır. Outline halkası ve nokta ton renginde kalır (info tonu #F8F8F8 olduğu için açık temada görünmez — token sorunu).',
1677
+ 'value SAYIYSA sayaç kuralları işler (0 gizlenir, maxCount aşılırsa "99+"); sayıya çevrilemeyen metin ("Yeni", "Beta") olduğu gibi basılır — durum rozeti böyle kurulur.',
1728
1678
  'isDot:true iken value · icon · maxCount · showZero · variant · shape · textColor OKUNMAZ, yalnız renkli nokta çizilir (color ve size okunur); nokta tek başına anlam taşıyorsa dotLabel doldurulmalı (yoksa ekran okuyucuya aria-hidden geçilir).',
1729
1679
  'isPulsing YALNIZ nokta kipinde çizilir (panelde de yalnız isDot açıkken görünür): sayaç/metin rozetine verilmesi hiçbir şey yapmaz. prefers-reduced-motion açık kullanıcıda animasyon kendiliğinden durur.',
1730
1680
  "click yalnız şemada bağlıysa yayılır (avatar/image deseni): bağlıyken rozet <button> olur, tıklanabilir görünür ve odak sırasına girer; bağlı değilken salt görsel <span>'dir.",
1731
1681
  'TIKLANABİLİR NOKTA İÇİN dotLabel ZORUNLU: nokta kipinde rozetin metni yoktur, click bağlıyken aria-hidden da basılmaz — dotLabel boşsa ekranda adsız bir düğme kalır ve ekran okuyucu onu "düğme" diye okur.',
1732
1682
  'Rozet kendi başına durur; başka bir bileşenin köşesine yapışmaz — saydığı şeyin yanına yerleştirilir (button ve icon kendi köşe rozetlerini kendileri çizer).',
1733
- 'Rozetin kendi ipucu prop’u YOKTUR ve gerekmez: 99+ ve kesilen metin title\'a kendiliğinden yazılır (nokta kipinde dotLabel title olur). Düğümün ortak appearance.tooltip kanalı rozet için BAĞLANAMAZ ("{{ item.count }}" harfi harfine basılır) ve ekran okuyucuya ulaşmaz (yalnız data-tooltip + CSS) — kullanma (CQ-249).',
1734
- 'Erişilebilir ad: ariaLabel doluysa rozetin okunan adı odur ("3 okunmamış mesaj"). Tıklanamayan chip tek bir görsel (role=img) olarak okunur ve içindeki sayı ayrıca okunmaz; tıklanabilir chip düğme kalır ve adı etiket olur (etiketsiz tıklanabilir sayaç yalnız "99+" gibi bir sayıyı okur ve ne yaptığını söylemez — sayaca tıklama bağlıyorsan ariaLabel yaz). Nokta kipinde dotLabel etiketin yedeğidir, ariaLabel onu ezer; etiketsiz tıklanabilir nokta adsız düğme kalır.',
1735
- 'Tıklanabilir NOKTANIN tıklama alanı görünmez bir 24×24 px\'e genişler (WCAG 2.5.8; nokta ve yerleşim aynı); bunu ::after kurar, noktada style\'a &::after yazma. Nokta başka bir tıklanabilir öğenin ~7 px yanındaysa o bölgedeki tıklamaları nokta alır: yan yana tıklanabilir nokta/düğme koyacaksan aralarını 14 px üstü bırak. Kendi başına hâlâ adsız bir düğme olabilir: dotLabel yaz.',
1736
- 'Köşe rozeti (bir düğme ya da avatarın köşesinde sayaç) için bileşen yok, style var: kabın style\'ına position: relative, rozetin style\'ına position: absolute; top: -4px; inset-inline-end: -6px (RTL\'de kendiliğinden aynalanır) ve kabın surfaceStyle\'ında contentOverflow: visible yaz — yoksa kap rozeti kırpar. Tıklanabilir köşe rozeti için rozetin kendisi click\'i taşır.',
1737
- 'Zorlanmış renkler modunda (forced-colors) nokta ve outline rozet sistem renginde 1 px çerçeve alır (zemin ve halka sistem rengine ezilince kaybolurdu).',
1683
+ 'Rozetin kendi hover ipucu prop’u YOKTUR: maxCount sayıyı kısalttığında gerçek değeri göstermek için düğümün ortak appearance.tooltip kanalını kullan — panelde Properties sekmesinin "Görünürlük ve kimlik" bölümündedir, Görünüm sekmesinde değil (nokta kipinde dotLabel zaten title olur).',
1684
+ 'Chip kipinde tıklanabilir rozetin erişilebilir adı çizilen metnin kendisidir: sayaç rozetinde bu yalnız "99+" gibi bir sayıdır ve tek başına ne yaptığını söylemez — sayaca tıklama bağlıyorsan düğümün ortak ipucu alanını da doldur.',
1738
1685
  'mount düğüm çizilince bir kez yayılır (sayaç sorgusunu buradan başlat).'
1739
1686
  ],
1740
1687
  propNotes: {
1741
1688
  value: 'Sayı ya da metin; boş string (ve showZero kapalıyken 0) rozeti tamamen gizler — icon dolu olsa bile hiçbir şey çizilmez. Şemadaki 5 varsayılanı TASARIM ANI değeridir: paletten bırakılan düğüme yazılır, ama düğüm value taşımıyorsa runtime varsayılanı boş stringtir ve rozet HİÇ çizilmez. Rozeti buradan kurarken value’yu açıkça yaz (CQ-265).',
1742
- maxCount: 'Sayaç bu sayıyı aşınca "99+" biçimine kısalır. Geçersiz değer (0, negatif, sayı olmayan, boş) 99\'a döner, kesirli değer aşağı yuvarlanır (1.5 → 1); panel en az 1 kabul eder.',
1743
- ariaLabel: 'Ekran okuyucunun okuyacağı ad; boşsa chip çizilen metni okur, nokta kipinde dotLabel okunur. Doluysa rozetin metni/sayısı ayrıca okunmaz, yerine bu ad gelir; tıklanabilir rozette düğmenin adı olur. Sayaç ve tıklanabilir rozetlerde ne saydığını/ne yaptığını söyleyen bir metin yaz ("Okunmamış mesaj: 3", "Bildirimleri aç").',
1744
- icon: 'Metnin başlangıç tarafına küçük ikon (RTL\'de sağda); yazıyla orantılı çizilir. Nokta kipinde ve value boşken çizilmez.',
1689
+ icon: 'Metnin soluna küçük ikon; nokta kipinde ve value boşken çizilmez.',
1745
1690
  dotLabel: 'Nokta kipinin erişilebilir etiketi (title + aria-label). Nokta tıklanabilirse zorunludur; yalnız isDot açıkken panelde görünür.',
1746
1691
  isPulsing: 'Nabız animasyonu — yalnız nokta kipinde etkilidir (canlı/bekleyen durum vurgusu).',
1747
1692
  color: "Rozetin zemin/çerçeve rengi. custom seçilip customColor geçersiz bir renkse semantik varsayılana (primary) düşer, siyaha boyamaz.",
@@ -1749,7 +1694,7 @@ export const componentKnowledge = {
1749
1694
  shape: 'pill | rounded | square — köşe yarıçapı; nokta kipinde okunmaz.',
1750
1695
  textColor: "Boş bırakılırsa metin rengi zemine göre OTOMATİK seçilir (warning/info gibi açık zeminde koyu metin) ve doğru olan genelde budur. Doldurulursa otomatik kontrast devre dışı kalır; custom + geçersiz renk primary değerine DÜŞMEZ, otomatiğe geri döner.",
1751
1696
  size: 'sm | md | lg — yalnız ölçü değişir, sayaç kuralları aynı kalır.',
1752
- style: "Özel CSS, rozetin kendisine iner; parçalar &__icon ve &__text (nokta kipinde ikisi de yoktur, style yalnız köke iner). Kök fontSize rozeti büyütür; whiteSpace: normal uzun metni saralar; maxWidth ile üç nokta çalışır. {{ }} ile BAĞLANAN style uygulanmaz."
1697
+ style: "Özel CSS; parçalar &__icon ve &__text (nokta kipinde ikisi de yoktur, style yalnız köke iner)."
1753
1698
  }
1754
1699
  },
1755
1700
  'breadcrumb-title': {
@@ -1815,55 +1760,39 @@ export const componentKnowledge = {
1815
1760
  }
1816
1761
  },
1817
1762
  chart: {
1818
- summary: 'ECharts tabanlı grafik (bar/line/area/pie/donut + waterfall, histogram, pareto, bullet, tornado, radial, funnel, gauge, radar, funnelflow, scatter). VERİ ÇEKMEZ: satırlar rows prop’una akışla yazılır.',
1763
+ summary: 'ECharts tabanlı grafik (bar/line/area/pie/donut + waterfall, histogram, pareto, bullet, tornado, radial, funnel, gauge, radar, funnelflow, scatter). Satırlar ya tabloya/query’ye/workflow’a/uca BAĞLANIR (rows ya da series.N.data → connect_data_bind, akışsız; kategori/değer rolleri, CD-015 aggregate) ya da akışla rows prop’una yazılır (bağlı prop’a setter yazılmaz, CD-005).',
1819
1764
  behavior: [
1820
1765
  "Veri prop'u data DEĞİL rows'tur (data eski adıdır, yalnız geriye uyumluluk için duruyor). Kategori categoryField, değerler series[].valueField ile çözülür.",
1821
1766
  'seriesField + valueField birlikte verilirse satırlar "kategori+seri başına bir satır" sayılıp geniş biçime pivotlanır; series dizisi o zaman prop’tan değil veriden türetilir.',
1822
1767
  'aggregate/sort/topN/nullMode veriyi çizimden ÖNCE dönüştürür — aynı işi akışta yapmana gerek yok.',
1823
1768
  'isDrillDown:true iken veri noktasına tıklamak kırıntı seviyesi ekler; dataPointClick yükü kaynak satırın TAMAMINI (row) taşır, böylece alt seviye sorgusu tek olayla kurulur. Geri dönüş breadcrumbClick ile bildirilir ve yeniden sorgulamak akışın işidir.',
1824
1769
  'isExportable "tablo olarak gör" + dışa aktarma araç çubuğunu açar; showRefresh refresh olayını yayan bir yenile düğmesi ekler.',
1770
+ "BAĞLI VERİ (2026-09-17, f-31): rows birincil bağlanabilir prop (fieldProps: rol seçimi categoryField/seriesField/valueField'a da yazılır). Ham tablo satırlarında seriesField + valueField + aggregate: toplama pivottan ÖNCE kategori+seri çifti başına yapılır (yığın grafik doğru toplam). funnelSources ikinci yuva (name, count). SERİ BAŞINA KAYNAK: series[i].data kendi başına bağlanır (prop yolu series.<i>.data, roller category + value); noktalar kategoriye göre rows'a birleşir, değer serinin valueField'ına (boşsa series_<i>). aggregate birleşmeden önce BİR kez uygulanır (count nokta sayısı); aggregate yoksa aynı kategorinin son noktası kazanır. Seri öğesi bağlanınca statik örnek rows aynı commit'te boşalır. rows da bağlıysa iki kaynak birleşir, uyarı yok; ilk bağlantı (rows) birincildir, series okumaları yükleniyor durumuna dokunmaz.",
1771
+ "OLAYLAR (2026-09-25 düzeltmesi): nokta tıklaması YALNIZ dataPointClick, kategori ekseninin etiketine basış YALNIZ axisLabelClick yayar (yatay çubukta etiketler y eksenindedir). Öncesinde axisLabelClick her nokta tıklamasında noktanın değeriyle geliyor, etikete basış ise hiç gelmiyordu: triggerEvent eksen yerine axisLabel altındaydı ve olay sorgusu nesne olduğu için süzmüyordu. Hedef çizgisi, bant ve eksen başlığı tıklaması olay değildir; selectionChange yalnız selectionMode açıkken gelir (kapalıyken ECharts'ın boş seçimi self.selected'ı eziyordu); dataPointClick.row kategori adıyla bulunur (nullMode skip sonrası kayan dataIndex yanlış satırı veriyordu). Eşleme mobil chart ile ortak (chart-events.ts).",
1772
+ 'BOZUK BAĞLI VERİ (2026-09-25): series/rows beklenmedik şekilde gelirse (dizi yerine metin, okunamayan alan) grafik düşmez — veri çözülemezse emptyText, seçenek kurulamazsa önceki çizim kalır. Eksen başlığı (categoryAxis.title / valueAxis.title) eksenin ortasına, etiketlerin dışına yazılır; ızgara etiket + başlığa yer ayırır (2026-09-29). title/subtitle doluyken çizim alanı başlığın altına iner (radar/radyalde merkez aşağı kayar).',
1825
1773
  "PASTA/HALKA ETİKETİ (2026-08-27 düzeltmesi): dataLabels.show artık pie/donut'a da geçiyor. Öncesinde prop bu dala hiç ulaşmıyordu ve dilim etiketleri HİÇBİR ayarla kapatılamıyordu — çekme çizgileri legend'in üstüne bindiği için halka fiilen kullanılamıyordu. Temiz halka için dataLabels:{ show:false } yaz.",
1826
1774
  'LEGENDDEN SERİ GİZLEME ÇALIŞIYOR (2026-09-16 düzeltmesi): legend tıklaması artık kalıcı. Öncesinde tıklama ~8 ms sonra kendiliğinden geri alınıyordu — olay yükü prop’lara yazılıyor, tepkime notMerge çizim yapıyor ve ECharts’ın legend.selected durumu siliniyordu. Seçim çizimden önce option’a geri yazılıyor; listede olmayan seri adları elenir.',
1827
1775
  'YATAY + İKİNCİL EKSEN ÇİZİLİYOR (2026-09-16 düzeltmesi): orientation:"horizontal" ile bir seride axis:"secondary" birlikte verilince grafik SESSİZCE boş çiziliyordu — yatayda değer eksenleri xAxis dizisindedir, yAxis tek kategori eksenidir. Kombo grafiği artık iki yönelimde de kurulabilir.',
1828
1776
  'RENK KURALLARI (colorRules) artık waterfall, histogram, pareto ve bullet’ta da uygulanıyor. Panelde görünüp hiçbir şey yapmıyorlardı. Kural neyi sınar: waterfall’da İŞARETLİ delta, histogram’da kutunun frekansı, pareto/bullet/scatter’da barın/noktanın kendi değeri, pie/donut ve kartezyende dilim değeri, gauge’de tek sayı.',
1829
1777
  'ANIMATION her tipte okunuyor (2026-09-16): animation:{ enabled,duration,easing } önceden yalnız bar/line/area/tornado dalına yazılıyordu, pie/gauge/waterfall/… için ölü bir proptu.',
1830
- 'PANELDE GÖRÜNMEYEN AYAR ÖLÜ AYAR DEĞİL: barStyle, useDecalPatterns, sampling, isLarge, isZoomable, selectionMode, dataLabels ve legend artık yalnız kendi builder’larının OKUDUĞU tiplerde görünür. Bir ayarı panelde bulamıyorsan seçtiğin chartType onu okumuyor demektir — zorlamak yerine tipi değiştir.',
1831
- 'KÖK ÖZELLİK VE PARÇA SEÇİCİLERİ (2026-09-30): style kökü çizer; parçalar &__toolbar (araç çubuğu), &__actions (düğme grubu), &__breadcrumb (drill-down kırıntısı), &__body (grafik gövdesi), &__state (yükleme/hata/boş kutusu), &__caption (alt yazı), &__table ("tablo olarak gör" görünümü). Öncesinde bu seçiciler kabul ediliyor ama HİÇBİR şeyi boyamıyordu. Hover/odak için "& button:hover" ve "& button:focus-visible" yazılır; kanvasın İÇİNDEKİ çizim (çubuk, eksen, legend) CSS ile değil paletteten, barStyle, valueFormat gibi prop lardan gelir.',
1832
- 'ETKİLEŞİM DURUMU KORUNUR (2026-09-30): yakınlaştırma aralığı (isZoomable) ve seçili noktalar (selectionMode) olay yükü prop lara yazıldıktan sonra da kalır; selectionMode:"multi" noktaları biriktirir. Öncesinde her yeniden çizim ikisini de siliyordu (zoom kendiliğinden tam aralığa dönüyor, multi tek noktaya iniyordu).',
1833
- 'axisLabelClick GERÇEKTEN YAYILIR (2026-09-30): kategori ekseni etiketine tıklamak dikey ve yatay yönelimde { value } yayar ve dataPointClick üretmez. Öncesinde ECharts anahtarı yanlış yere yazıldığı için olay hiç çıkmıyordu.',
1834
- 'BAŞLIK / LEGEND YER AYIRIR (2026-09-30): title, subtitle ve üstte duran legend çizim alanını aşağı iter (öncesinde çubukların ve eksen etiketlerinin üstüne biniyordu); kabı aşan başlık satır kırar; 32 karakteri aşan legend adı "…" ile kısalır ve tam adı imleç kutusunda görünür.',
1835
- 'IMLEÇ KUTUSU valueFormat UYGULAR (2026-09-30): prefix, suffix, ayraç, decimals ve abbreviate eksen ve etiketle aynı biçimde ipucuna da yazılır. Öncesinde ipucu ham sayıyı basıyordu.',
1836
- 'TORNADO (2026-09-30): ilk seri değeri ne yazılırsa yazılsın (30 ya da -30) SOLA, ikinci seri sağa çizilir ve iki seri aynı kategori satırında yığılır; yatay yönelim (orientation:"horizontal") klasik tornado görünümünü verir.',
1837
- 'VARSAYILANLAR ÇALIŞMA ANINDA DA GEÇERLİ (2026-09-30): categoryField boşsa "label", series boşsa value alanı okunur; tanınmayan chartType bar çizilir. YİNE DE MCP ile eklediğin düğümde categoryField ve series u açıkça yaz: add_component katalogun varsayılanlarını düğüme yazmıyor, ve kendi alan adların ("ay", "gelir") varsayılanla eşleşmez.',
1838
- 'SAĞDAN SOLA (2026-09-30): kap okuma yönü rtl ise (tema direction ya da dir) kartezyen grafik aynalanır: kategori ekseni ters (ilk kategori sağda), dikey eksen sağda (ikincil eksen solda), legend karşı yana yaslanır (giriş sırası değişmez); yatay yığın toplamı etiketi ters eksenin dışına yazılır. Pasta/radar/gösterge/radyal eksensizdir, olduğu gibi kalır. Yön dil değişince de izlenir.',
1839
- 'BULLET plotBands (2026-09-30): plotBands verilince bullet nitel bantları ([{ from, to, label, color }]) arka planda çizer, otomatik gri aralık çubuğu kalkar ve değer ekseni en büyük bant ucuna kadar açılır. Bant yokken davranış aynı.',
1840
- 'TORNADO ARALIĞI (2026-09-30): series[].lowField/highField tornado ve bar ile çalışır; sıfırı aşan aralık (-30..40) iki yana bölünür, tamamen negatif ya da pozitif aralık da doğru çizilir (öncesinde -30..40 çubuğu 0..70 çiziliyordu).',
1841
- 'DURUM KUTULARI (2026-09-30): isLoading bir iskelet çizer (öncesinde alan boş kalıyordu); hata kutusu role="alert", boş kutu role="status" taşır; emptyText/errorText yalnız boşluktan oluşuyorsa varsayılan metin yazılır. Tam ekran (isExportable) bir kaplamadır: Esc kapatır, Tab kaplamanın dışına kaçmaz.'
1842
- ],
1843
- propNotes: {
1844
- rows: 'Satır dizisi; mount/filter akışlarının setter hedefi.',
1778
+ 'PANELDE GÖRÜNMEYEN AYAR ÖLÜ AYAR DEĞİL: barStyle, useDecalPatterns, sampling, isLarge, isZoomable, selectionMode, dataLabels ve legend artık yalnız kendi builder’larının OKUDUĞU tiplerde görünür. Bir ayarı panelde bulamıyorsan seçtiğin chartType onu okumuyor demektir — zorlamak yerine tipi değiştir.'
1779
+ ],
1780
+ propNotes: {
1781
+ rows: 'Satır dizisi. Bağlanabilir prop (connectData.props.rows): veri kaynağından okunuyorsa connect_data_bind; akışla doldurulacaksa mount/filter akışlarının setter hedefi — ikisi birden değil (CD-005).',
1845
1782
  legend: "{ show, position, orient, showValues }. position artık DÖRT yön: top | bottom | left | right (2026-08-27). Yana yaslanan legend her zaman dikey çizilir — yatay seçilse bile ezilir, çünkü yandaki yatay legend grafiğin üstüne biner. showValues YALNIZ pasta/halkada iş görür: seri adının yanına dilim değerini yazar.",
1846
1783
  centerLabel: "{ show, text, subtext } — YALNIZ donut. text boş bırakılırsa dilim değerlerinin TOPLAMI yazılır (valueFormat uygulanır), yani 'ortadaki toplam' için ayrı bir setter gerekmez. Pastada delik olmadığı için görünmez ve panelde gizlidir.",
1847
1784
  categoryField: 'Kategori ekseni alan adı (varsayılan "label"). SCATTER’DA x ekseninin SAYISAL kolonudur (y = series[0].valueField) — eski xField adı geriye uyumluluk için ayrılmış durumda, onu kullanma.',
1848
1785
  series: "[{ valueField, type?, axis?, color?, stack?, lowField/highField?, targetField? }] — yFields'ın yerini aldı.",
1849
1786
  stackMode: 'none | stacked | percent.',
1850
- dataLabels: "{ show, position, content, showTotal }. showTotal YALNIZ stackMode:'stacked' iken iş görür: her yığının tepesine (yatayda sağına) dilimlerin toplamını yazar, valueFormat uygulanır; toplam EKSENE ve LEGEND'e GİRMEZ. 2026-09-15 düzeltmesi — öncesinde toplam şeffaf bir seri olarak yığına ekleniyordu: değer ekseni gerçek en yüksek yığının İKİ KATINA çıkıyor, toplam etiketi barın çok üstünde boşlukta duruyor ve legend'de '<grup>__total' diye dördüncü bir madde beliriyordu (S-18). İŞARETİ KARIŞIK yığın İKİ etiket yazar (2026-09-16): ECharts pozitifleri yukarı, negatifleri aşağı ayrı yığar, o yüzden pozitif dilimlerin toplamı üstte, negatiflerinki altta durur — tek bir 'net' sayı yanlış barın ucuna düşüyordu. percent modunda etkisizdir. content:'percentage' bar/çizgi/alanda serinin toplamındaki payı, pasta/halkada dilim payını yazar; yüzde yığında (stackMode:'percent') değerin kendisi zaten yüzdedir. fontSize etiket puntosunu px yazar; çubuğun dışındaki etiket temanın metin rengini alır (koyu zeminde okunur).",
1851
- isDrillDown: 'Veri noktası tıklamasını kırıntı seviyesine çevirir; sorguyu akış yeniler. scatter’da yoktur: noktanın kategori adı yok. Kırıntının kök etiketi "Başlangıç" (tr) / "Home" (en); tıklayınca breadcrumbClick filterValue:undefined yayar.',
1787
+ dataLabels: "{ show, position, content, showTotal }. showTotal YALNIZ stackMode:'stacked' iken iş görür: her yığının tepesine (yatayda sağına) dilimlerin toplamını yazar, valueFormat uygulanır; toplam EKSENE ve LEGEND'e GİRMEZ. 2026-09-15 düzeltmesi — öncesinde toplam şeffaf bir seri olarak yığına ekleniyordu: değer ekseni gerçek en yüksek yığının İKİ KATINA çıkıyor, toplam etiketi barın çok üstünde boşlukta duruyor ve legend'de '<grup>__total' diye dördüncü bir madde beliriyordu (S-18). İŞARETİ KARIŞIK yığın İKİ etiket yazar (2026-09-16): ECharts pozitifleri yukarı, negatifleri aşağı ayrı yığar, o yüzden pozitif dilimlerin toplamı üstte, negatiflerinki altta durur — tek bir 'net' sayı yanlış barın ucuna düşüyordu. percent modunda etkisizdir.",
1788
+ isDrillDown: 'Veri noktası tıklamasını kırıntı seviyesine çevirir; sorguyu akış yeniler. scatter’da yoktur: noktanın kategori adı yok.',
1852
1789
  caption: 'Grafiğin ALTINA yazılan açıklama satırı (DOM metni, kanvasın parçası değil). 2026-09-16 öncesinde prop panelde vardı ama hiçbir yere çizilmiyordu.',
1853
1790
  subtitle: 'Başlığın altına yazılır. Başlık boş bırakılsa da çizilir (2026-09-16 öncesinde title boşken subtitle kayboluyordu).',
1854
1791
  chartType: "bar | line | area | pie | donut | waterfall | histogram | pareto | bullet | tornado | radial | funnel | gauge | radar | funnelflow | scatter. SEÇİLEN TİP hangi ayarların OKUNDUĞUNU belirler; panel de ona göre gizler.",
1855
1792
  sizeField: 'YALNIZ scatter: nokta çapını ölçekleyen sayısal kolon (kabarcık grafiği). Boş bırakılırsa bütün noktalar aynı boyda çizilir.',
1856
1793
  barStyle: '{ barWidth, maxBarWidth, barGap, categoryGap, borderRadius, minBarSize } — YALNIZ bar ve tornado okur. minBarSize çok küçük değerlerin görünmez kalmasını engeller (ECharts barMinHeight); 2026-09-16 öncesinde şemada duruyor ama hiçbir yerde okunmuyordu. borderRadius yığılmış modda (stackMode stacked/percent) YALNIZ yığının dış ucuna iner (2026-09-29): son bar serisi [r,r,0,0] (yatayda [0,r,r,0]), alttaki dilimler köşesiz — eskiden her dilimin dört köşesi yuvarlanıyor ve yığın ayrık çubuklar gibi görünüyordu.',
1857
1794
  categoryAxis: '{ title, isReversed, labelRotate, gridLines }. Kategori ekseni HER ZAMAN kategori eksenidir; bir zaman ekseni anahtarı vardı, çizilemeyen bir option ürettiği için 2026-09-16’da kaldırıldı. scatter’da bu prop x (değer) eksenini ayarlar.',
1858
- colorRules: '[{ operator, value, valueTo, color }] — ilk eşleşen kural kazanır. radial/funnel/radar/funnelflow dışındaki her tipte uygulanır.',
1859
- sort: 'by:"value" hangi serinin değerine göre dizer: seriesRef bir serinin VALUE FIELD adı ya da seri ADI olabilir, boşsa ilk seri. (2026-09-30 öncesi boş seriesRef sıralamayı sessizce etkisiz bırakıyordu.) by:"category" kategori adına göre dizer.',
1860
- topN: 'topN sıralamadan BAĞIMSIZDIR: veri sırasındaki ilk N kategoriyi tutar, gerisini "otherLabel" satırında toplar. EN BÜYÜK N için önce sort:{ by:"value", direction:"desc" } ver.',
1861
- annotations: 'x ve y yüzde ("62%") ya da piksel ("200px") olarak yazılır; kategori adı ("Haz") konumu bozar. Metin grafiğin arkasında soluk (opaklık 0.5) durur ve tıklanamaz.',
1862
- locale: 'Yalnız "tr" ve "en" sözlüğü vardır; boş bırakılırsa uygulama dili izlenir, sözlükte olmayan dil (ar…) İngilizceye düşer. Araç çubuğu düğmeleri, tip seçici seçenekleri, boş/hata metni ve erişilebilirlik özeti aynı dili kullanır.',
1863
- referenceLines: 'axis:"secondary" çizgi, ikinci değer eksenine bağlı bir seri VARSA o eksende çizilir (yoksa birincil eksende kalır); etiket çizginin ucunda, ızgaranın içindedir. plotBands yalnız birincil eksendedir.',
1864
- plotBands: '[{ from, to, label, color }] — kartezyen tiplerde (bar/line/area/tornado) değer ekseni üstünde soluk bant, bullet\'ta nitel arka plan bantları. YALNIZ birincil eksende.',
1865
- targetField: 'bullet: hedef işareti. Üst düzey targetField kazanır; boşsa ilk serinin series[].targetField alanı okunur.',
1866
- style: 'Parça seçicileri: &__toolbar · &__actions · &__breadcrumb · &__body · &__state · &__caption · &__table; kökte doğrudan CSS ve "& button:hover" / "& button:focus-visible" çalışır. Kanvasın içindeki çubuk/eksen/legend CSS ile değil prop ile biçimlenir.'
1795
+ colorRules: '[{ operator, value, valueTo, color }] — ilk eşleşen kural kazanır. radial/funnel/radar/funnelflow dışındaki her tipte uygulanır.'
1867
1796
  }
1868
1797
  },
1869
1798
  checkboxgroup: {
@@ -1922,23 +1851,13 @@ export const componentKnowledge = {
1922
1851
  "srcdoc YAZILIYSA src YOK SAYILIR (HTML’in kendi sırası): üçüncü parti 'embed kodu' adres uydurmadan yapıştırılır. html bileşeninden farkı: içerik sayfaya değil sandbox'lı çerçeveye girer, yani uygulamanın origin'ine dokunamaz — ama isSandboxed KAPATILIRSA srcdoc belgesi gömen sayfanın origin'ini devralır, ikisini birlikte kapatmak bilinçli bir karardır. Yalnız boşluktan oluşan srcdoc boş sayılır ve src'ye düşülür.",
1923
1852
  "load/error native <iframe> DOM olaylarından gelir. load ÇAPRAZ KAYNAKTA da güvenilir tetiklenir (tarayıcı frame'i okuyamasa bile yükleme bitince ateşler) ve 'yükleniyor' örtüsünü kapatır. error ise pratikte neredeyse hiç tetiklenmez — engellenen (X-Frame-Options/CSP) ya da 404 çapraz-kaynak sayfalar tarayıcıda genelde sessiz bir load'a döner; ağ hatası yakalamak için güvenilmez. Örtüyü error de kapatır (2026-09-17 öncesinde kapatmıyordu, 'Loading…' sonsuza dek duruyordu).",
1924
1853
  "message: gömülü sayfanın window.parent.postMessage(...) çağrısı bu olayı çalıştırır. YALNIZ bu çerçeveden gelen mesaj kabul edilir (event.source karşılaştırması); sayfadaki başka bir iframe ya da uygulamanın kendi postMessage çağrısı tetiklemez. Yük yalnız event.data'dadır ({ message, origin }), hiçbir prop yazılmaz. ORIGIN SÜZGECİ YOK: sandbox açıkken gömülü belgenin origin'i opak olduğu için event.data.origin 'null' gelir — hangi origin'e güvenileceğine akış karar verir.",
1925
- "Kanvas toolbar'ı: showBorder · isSandboxed · allowFullscreen · isLazy · referrerPolicy · isHidden.",
1926
- "AYAR DEĞİŞİMİ ÇERÇEVEYİ YENİDEN KURAR (2026-10-05): tarayıcı sandbox, allow, referrerPolicy ve allowFullscreen'ı yüklü çerçevede değişse de yalnız bir SONRAKİ gezintide uygular; bu yüzden isSandboxed (ya da allow/referrerPolicy/allowFullscreen) bir akışla çevrilince çerçeve baştan kurulur, yükleme örtüsü yeniden görünür ve gömülü sayfa yeni ayarla açılır (load bir kez daha yayılır). Eskiden öznitelik değişir ama belge eski opak origin'de kalırdı: anahtar 'kapalı' görünür, depolama hâlâ engelliydi. Daha önce yüklenmiş bir kaynağa (ya da ayara) geri dönülünce de örtü yeniden görünür. src'den srcdoc'a geçiş de artık tek load verir.",
1927
- "SRC SÜZGECİ tarayıcının gördüğü hâli sınar: javascript:/data:/vbscript:/file: şemaları, aralarına sekme/satır sonu konsa (java<TAB>script:) ya da başına kontrol karakteri eklense de boşa düşer ve yedek metin çizilir. Tarayıcılar bu karakterleri URL ayrıştırırken siler; eskiden bu yazımlar süzgeci geçip, isSandboxed KAPALIYKEN gömenin sayfasında script çalıştırıyordu.",
1928
- "YÜKLEME ÖRTÜSÜ YALNIZ load OLAYINDA KALKAR: tarayıcının load vermediği hedefler örtüyü sonsuza dek bırakır — indirme tetikleyen adres (Content-Disposition: attachment, Content-Type'sız ikili yanıt, örn. /favicon.ico), about:blank ve geçersiz blob:. Böyle bir adres gömme; gömüyorsan loadingText'i boş bırak (örtü hiç çizilmez). Engellenen (X-Frame-Options/CSP), 404 ve bağlantısı reddedilen sayfalar load verir (örtü kalkar, çerçevede tarayıcının kendi hata sayfası görünür), error yayılmaz.",
1929
- "SANDBOX AÇIKKEN ZEYREK SAYFASI GÖMÜLMEZ: aynı uygulamanın (ya da başka bir Zeyrek uygulamasının) sayfasını gömerken isSandboxed'ı KAPAT. Sandbox'ta çerçeve opak origin'dedir; Zeyrek runtime'ı çerez/depolamaya erişemez ve gömülen sayfa boş beyaz kalır — hata ekranı da çıkmaz. Kapalıyken sayfa tam çizilir (ölçüldü 2026-10-05). Çerez ya da depolama isteyen üçüncü parti gömüler de sandbox'ta çalışmayabilir (ölçülmedi); sandbox'ı kapatmak gömülene gömenin origin'ini verir, bilinçli karar.",
1930
- "BOYUT: çerçeve içeriğine göre BÜYÜMEZ — çapraz belgenin yüksekliğini bilemez. heightType 'auto' iken kök ~150 px (tarayıcının iframe varsayılanı) kalır, uzun içerik kırpılır; gömülen içeriğe yetecek yüksekliği heightType 'fixed' + heightString ile ver. Mobilde (≤ 767 px) yazılı sabit yükseklik 'auto'ya düşer; korumak için appearance.className'e ng-keep-height-mobile yaz.",
1931
- "KÖK style'daki fontSize ve color yükleme örtüsüne ve yedek metne İNER (2026-10-05'ten önce örtü kendi 14 px'ini ve sabit rengini kullanıyordu); yedek metin varsayılan olarak ikincil metin rengindedir (kontrast ≥ 4.5). Örtüyü ayrıca &__loading, yedek kutuyu &__empty ile boya.",
1932
- "ERİŞİLEBİLİRLİK: yükleme örtüsü role='status'tur (ekran okuyucuya loadingText'i duyurması için; gerçek bir ekran okuyucuyla doğrulanmadı). Kök aria-busy taşımaz — meşgul bir atanın içindeki canlı bölge duyurusu beklemeye alınırdı. Örtü load gelmeyen hedeflerde (indirme, about:blank) sonsuza dek kalır. title boş ya da boşluk-yalnız bırakılırsa çerçeve adsız kalmasın diye İngilizce 'Embedded content'e düşer (yerelleşmez; yedek metin de fallbackText boşken title'dır) — anlamlı ve dile uygun bir title yaz.",
1933
- "STİL HEDEFLERİ (ölçüldü): kök sınıfı .ng-iframe; &__frame gömülen <iframe>, &__loading örtü, &__empty yedek kutu; metin <span> içindedir. '& > iframe', '& .ng-iframe__loading', '&__loading span', kök ::before/::after, @media, @keyframes (adları sayfa-geneli: benzersiz önek ver) ve backdropFilter çalışır; WebkitBackdropFilter reddedilir (silentlyDropped), önek yazma. &:hover ve &:focus-within yedek kutu/örtü/kök dolgusu üstünde çalışır; imleç çapraz belge çerçevesinin üstündeyken tarayıcı kök :hover'ı eşlemeyebilir (headless ölçümde eşlemedi) — hover'a ihtiyaç duyan görünümü dolgu/çerçeve kenarına kur. Olmayan parça (&__bogus) hata vermeden kaydolur ve hiçbir şeye basılmaz.",
1934
- "SEKME İÇİNDE: tabs keepAlways KAPALIYKEN sekmeye her dönüşte çerçeve söküp yeniden kurulur ve baştan yüklenir (load her dönüşte yeniden yayılır); keepAlways AÇIKKEN gizli sekmelerdeki çerçeveler açılışta birlikte yüklenir — isLazy gizli sekmede erteleme yapmaz (ölçüldü 2026-10-05). 'Yalnız görünen sekme yüklensin ve dönüşte yeniden yüklenmesin' birlikte kurulamaz; ağır gömüyü sekmeye koyma ya da sayaçları buna göre kur.",
1935
- "allow değeri ham string[] olarak yazılınca page_schema_patch 500 verir; çoklu seçim değerini [{ data: 'camera' }] nesne dizisi olarak yaz (bileşen ikisini de okur)."
1854
+ "Kanvas toolbar'ı: showBorder · isSandboxed · allowFullscreen · isLazy · referrerPolicy · isHidden."
1936
1855
  ]
1937
1856
  },
1938
1857
  icon: {
1939
1858
  summary: 'Tek glif çizer (TİPLİ stil modeli: yalnız hoverStyle): Material Symbols ya da Phosphor setinden ikon + boyut + semantik renk + isteğe bağlı arka plan çipi, köşe rozeti, döndürme/çevirme, spin animasyonu, isDisabled kilidi ve click/href etkileşimi.',
1940
1859
  behavior: [
1941
- "İKON ADI iki biçim alır: Material Symbols snake_case adı ('shopping_cart', 'progress_activity', 'account_circle') ya da Phosphor 'ph-<ağırlık> ph-<ad>' çifti ('ph-bold ph-heart'; ağırlıklar: ph-light|ph-bold|ph-duotone|ph-fill|ph-thin|'ph-regular ph'). BİLİNMEYEN Material adı (yazım hatası, uydurma ad) hata vermez ama HİÇBİR ŞEY çizmez: glif 0×0 kalır (çip açıksa boş çip görünür) — adı uydurma, bilinen bir addan emin ol.",
1860
+ "İKON ADI iki biçim alır: Material Symbols snake_case adı ('shopping_cart', 'progress_activity', 'account_circle') ya da Phosphor 'ph-<ağırlık> ph-<ad>' çifti ('ph-bold ph-heart'; ağırlıklar: ph-light|ph-bold|ph-duotone|ph-fill|ph-thin|'ph-regular ph'). BİLİNMEYEN Material adı hata vermez, ligature çözülmediği için adın METNİ görünür — adı uydurma, bilinen bir addan emin ol.",
1942
1861
  "RENK TEK KANALDIR: icon.color OKUNMAZ (yazma). Çip kapalıyken glif rengini color/customColor çifti verir; çip açıkken renk sahibi chipColor'dur — solid varyantta glif otomatik kontrast rengini, soft varyantta çip renginin kendisini alır ve panel glif renk satırlarını gizler.",
1943
1862
  "SPIN ile döndürme/çevirme AYRIKTIR: isSpinning açıkken rotation/flipHorizontal/flipVertical uygulanmaz (ikisi aynı CSS transform'unu paylaşamaz); değerler silinmez, spin kapanınca geri döner.",
1944
1863
  "ETKİLEŞİM: href doluysa kök gerçek <a> olur (isNewTabLink yeni sekmede açar) ve click olayı (kilitli değilken) YİNE yayılır; href boş ama click olayı bağlıysa kök <button>tur; ikisi de yoksa salt görsel <div> kalır.",
@@ -1946,25 +1865,18 @@ export const componentKnowledge = {
1946
1865
  'OLAYLAR: mount düğüm ilk çizildiğinde bir kez yayılır (salt görsel ikonda da; isHidden açıkken yayılmaz), click yalnız etkileşimli kökten (href ya da bağlı click) çıkar. İkisi de veri taşımaz.',
1947
1866
  "İPUCU (tooltip) prop'u YOKTUR: düğümün ortak appearance.tooltip alanı (+ tooltipPosition: top · bottom · left · right) her komponentte ipucu çizer — ikon düğmesinin adını orada yaz.",
1948
1867
  "ERİŞİLEBİLİRLİK: ariaLabel doluysa okuyucular onu okur (salt görselde role=img). Boşsa salt görsel ikon okuyuculardan GİZLENİR; tıklanabilir/bağlantılı ikon ise adsız kalmasın diye ikon adından türetilen etiketi okur. Anlam taşıyan her ikona ariaLabel yaz.",
1949
- 'BOYUT tema puntosunun katıdır: sm|md|lg|xl kademeleri --ng-font-size ile ölçeklenir (md varsayılan temada ~24px) ya da elle CSS değeri yazılır — çıplak sayı px sayılır; px/em/rem/%/vh…, calc()/var()/clamp() olduğu gibi geçer. Elle değer tema yazı ölçeğini izlemez. Geçersiz uzunluk ("abc"), sıfır ya da negatif değer md\'ye düşer (ikon kaybolmaz, miras boyuta kalmaz); calc()/var() İÇİNDEKİ ifade denetlenmez.',
1950
- "ROZET köşesi çipin BAŞLANGIÇ kenarına bağlıdır: tek haneli rozet köşede durur, geniş sayı ('99+', '12500') glife değil DIŞARI büyür; RTL\'de köşe aynalanır (sağdan sola düzende sol üst). warning/info rozetinde yazı rengi zemin parlaklığından seçilir (her iki temada), öteki renklerde tema token\'ı kullanılır. Rozeti kaydırmak için &__badge içine inset-inline-start (RTL\'de kendiliğinden aynalanır) yaz; fiziksel right/left yazarsan başlangıç kenarı da dolu kaldığı için rozet gerilir — onlarla birlikte inset-inline-start: auto yaz.",
1951
- "HAREKET AZALTMA: kullanıcı prefers-reduced-motion tercih ediyorsa isSpinning dönüşü DURUR (glif yine meşgul işaretidir) — bunun için style\'a medya kuralı yazmaya gerek yok.",
1952
- "RENK UYARISI: info varsayılan temada neredeyse beyazdır (#F8F8F8, CQ-087) ve warning açık zeminde ~1.9:1 kalır — çip KAPALIYKEN bu iki renk okunmaz. Okunur ikon için primary/success/error, ya da çip + soft/solid, ya da color=custom kullan. Çip açıkken glif rengi zeminin parlaklığından otomatik seçilir (custom çip rengi dahil, koyu tema dahil).",
1953
- 'STİL HEDEFLERİ: kök öğenin sınıfı .ng-icon\'dur; kök style/hoverStyle/&:hover/&:active/&:focus-visible/@media doğrudan köke yazılır. &:focus-visible yalnız ETKİLEŞİMLİ ikonda (href dolu ya da bağlı click) tetiklenir — salt görsel ikon odak almaz. Parçaya durum vermek için "&__chip:hover", ".ng-icon:focus-visible &__chip", ".ng-icon[aria-disabled=true] &__chip" yazımları çalışır (aria-disabled yalnız ETKİLEŞİMLİ kilitli ikonda vardır; salt görsel kilitli ikon için ".ng-icon--disabled" kullan). Platformun varsayılan odak halkası (2px outline) kökte "&:focus-visible { outline: none }" ile kapatılıp yerine kendi halkan konabilir.',
1954
- "ALIGN left/right MANTIKSALDIR: RTL'de left = başa hizalı (sağda), right = sona hizalı (solda). Arapça sayfada ikonu fiziksel sola koymak için right yaz; yön işaretli ikonlarda (arrow_forward) ise ikon adını dile göre değiştir ya da flipHorizontal kullan.",
1955
- "REPEATER İÇİNDE: satır içindeki ikona click/mount bağlanabilir; ikon satırda da <button>/<a> olur ve olay satır başına koşar (event.data'da satır yok, akışın satır bağlamı params'tadır). Akıştaki setter ile satır DIŞINDAKİ bir bileşene (sayaç metni gibi) yazmak satır bağlamında şu an değer değiştirmiyor (ARC-172) — sonucu satırı ya da sayfa değişkenini güncelleyen bir kod adımıyla yaz ya da olayı repeater'ın select olayına bağla.",
1956
- "BİLİNMEYEN AD: yazım hatalı/uydurma Material adı sessizce BOŞ çizilir (hata, uyarı ve ham metin yok; glif 0×0) — ikon görünmüyorsa önce adı kontrol et. Kullanıcı girdisinden gelen adı doğrudan icon'a bağlama: tanınan küme fontun çizdiği Material Symbols ligatürleri (3961 ad; eski adlar `expand_more`, `done`, `email` dahil) ve Phosphor adlarıdır, gerisi boş kalır."
1868
+ 'BOYUT tema puntosunun katıdır: sm|md|lg|xl kademeleri --ng-font-size ile ölçeklenir (md varsayılan temada ~24px) ya da elle CSS değeri yazılır — çıplak sayı px sayılır. Elle değer tema yazı ölçeğini izlemez.'
1957
1869
  ],
1958
1870
  propNotes: {
1959
1871
  icon: "İKİ biçim de geçer: { name: 'shopping_cart' } nesnesi ya da düz metin ('shopping_cart'). Yalnız AD okunur; renk color/chipColor kanallarından gelir (picker'ın renk bölümü bu komponentte kapalıdır). Boş/çözülmemiş değer varsayılan 'star' glifine düşer.",
1960
1872
  isDisabled: 'Kilit: ikon solar, bağlantı adressiz kalır, düğme disabled olur ve click olayı yayılmaz.',
1961
- size: "sm|md|lg|xl (tema puntosuna oransal) YA DA CSS uzunluğu ('40px', '2.5em', 'calc(…)'); çıplak sayı px sayılır. Geçersiz/sıfır/negatif → md.",
1873
+ size: "sm|md|lg|xl (tema puntosuna oransal) YA DA CSS uzunluğu ('40px', '2.5em'); çıplak sayı px sayılır.",
1962
1874
  color: "primary|info|success|warning|error|custom — çip kapalıyken glifin rengi; custom seçilirse customColor okunur. Semantik değer temayı izler, custom izlemez.",
1963
1875
  chipShape: "none|circle|rounded|square — none dışında glifin arkasına renkli kutu açılır ve renk yönetimi chipColor'a geçer.",
1964
1876
  chipVariant: 'solid (tam renkli zemin + otomatik kontrast glif) | soft (soluk zemin + renkli glif).',
1965
1877
  badgeValue: "Köşe rozetinin metni ('3', '99+'); boşsa rozet çizilmez. badgeDot açıkken okunmaz — sayısız nokta çizilir.",
1966
1878
  rotation: "0|90|180|270 (derece, metin değer). flipHorizontal/flipVertical ile birleşir; isSpinning açıkken üçü de uygulanmaz.",
1967
- href: "Adres ya da sayfa yolu — dolu ise ikon gerçek bağlantıdır; click olayı da yayılmaya devam eder. '#bolum' aynı sayfa çapası olarak kalır; çözülmemiş {{ }} ifadesi bağlantı OLMAZ (ikon salt görsel kalır); javascript:/data:/vbscript: şemaları yazılmaz.",
1879
+ href: "Adres ya da sayfa yolu — dolu ise ikon gerçek bağlantıdır; click olayı da yayılmaya devam eder.",
1968
1880
  hoverStyle: STYLE_GROUP_NOTES.hoverStyle + ' borderColor alanı bu komponentte YOKTUR (kökte kenarlık yok).',
1969
1881
  style: STYLE_GROUP_NOTES.styleEscape + " Parçalar: '&__chip' (zemin kutusu — 'none' kipinde de vardır) · '&__glyph' (glifin sarmalı) · '&__badge' (rozet)."
1970
1882
  }
@@ -1981,14 +1893,7 @@ export const componentKnowledge = {
1981
1893
  '60 karakteri aşan string yaprakları önizlemede kırpılır ("…"); yaprağa tıklamak tam değeri açar.',
1982
1894
  "nodeClick HER satırda (yaprak ya da object/array) tıklanınca yayılır; aç/kapa oku ve satırın kopyala düğmesi nodeClick YAYMAZ. Yük akışta event.data.{ path, key, kind, value }; self.currentItem'a (gizli prop) value'SUZ { path, key, kind } yazılır — ham değeri event.data.value'dan oku. Kırpılmış string'e tıklamak hem tam değeri açar hem nodeClick yayar.",
1983
1895
  "copy iki kaynaktan gelir: araç çubuğundaki 'tümünü kopyala' event.data = { path:'', key:'', kind:'root', value: normalize edilmiş TÜM veri }; düğümün kendi kopyala düğmesi o düğümün { path, key, kind, value }'suyla. copy hiçbir prop YAZMAZ, yalnız event.data taşır; pano izni yoksa olay da yayılmaz.",
1984
- "Dizi elemanlarının anahtarı indekstir: quotesOnKeys açıkken yalnız obje anahtarları tırnaklanır (ham JSON'daki gibi). path noktalı/köşeli yol üretir; nokta ya da boşluk içeren anahtar yolda kaçırılmaz (a.b anahtarı ile a→b aynı yolu verir).",
1985
- 'Uzun anahtar ve değerler SATIRDA SARILIR (overflow-wrap:anywhere): sayfa/gövde yatay kaymaz, boşluksuz 300 karakterlik anahtar da kutuyu taşırmaz. Değer anahtarın yanında en az ~12 karakter yer bulamazsa alt satıra iner (dar sütunda harf harf ezilmez). Satır kopyala düğmesi satırın sağ ucunda sabit durur; fare olmayan (dokunmatik) cihazda soluk de olsa HEP görünür.',
1986
- "title, emptyText, searchPlaceholder BOŞ ya da yalnız boşluk yazılırsa dilin varsayılanı çıkar (başlık şeridi hiç çizilmez; boş durum 'Veri yok'/'No data'/'لا توجد بيانات'; yer tutucu 'Ara'/'Search'/'بحث'). Uzun başlık satırlara bölünür. Şema varsayılanı artık BOŞTUR: hiç yazmazsan uygulama diline göre çıkar (tr 'Veri yok'/'Ara', en 'No data'/'Search', ar). Eski kayıtta 'No data'/'Search' diye yazılı kalmış sayfa İngilizce kalır — Türkçe/Arapça istiyorsan o alanı boşalt.",
1987
- "isSearchable KAPANIRSA (panel ya da akış) kutudaki yazı süzgeç olmaktan çıkar, ağaç tam görünür; kutuya yazılı metin yeniden açılınca geri gelir. Aramada büyük/küçük harf duyarsız ve Türkçe katlamalıdır: i, I, ı, İ dördü eşittir ('ist' araması 'İstanbul'u, 'ısp' araması 'ISPARTA'yı bulur; vurgu özgün harfleri korur). Şu an tek tuşta 2000+ satır eşleşen aramalar (2000 öğeli dizide '1') yarım saniye sürer; çok büyük diziyi ham bağlama.",
1988
- "size yazı boyutunu KÖK yazı boyutuna ORANLA verir (küçük 0.85×, orta 1×, büyük 1.15×): Style kökünde fontSize yazdıysan size onun üstüne biner, onu ezmez. Kökte yazılan color başlığa da iner; fontFamily ağaca iner ama başlık ve arama kutusu arayüz yazı tipinde kalır — onlar için '&__title' / '&__search' içine fontFamily yaz.",
1989
- "style PARÇALARI (hepsi bildirilmiştir ve kendi öğesini boyar): &__title · &__toolbar · &__search (arama kutusu) · &__tool (araç çubuğu düğmesi) · &__body (kaydırılan gövde) · &__node (her düğümün kabı; girinti burada) · &__row · &__toggle (aç/kapa oku) · &__key · &__type (tür etiketi) · &__value · &__match (arama vurgusu) · &__copy · &__empty. Türe göre renk için &__value DEĞİL iç içe seçici: '& .ng-jsonviewer__value--string' / '--number' / '--boolean' / '--null' / '--object' / '--array'; tür etiketine '& .ng-jsonviewer__type--<tür>'. Satırda data-kind (object|array|string|number|boolean|null); tıklanan satırda data-selected='true' ve aria-current='true' — '&__row[data-selected]' ya da '&__row[aria-current]' ile boya (hâlâ tıklanan tek satır vardır). &__row:nth-child ile ZEBRA YAPILAMAZ: her satır kendi düğümünün ilk çocuğudur, hepsi eşleşir.",
1990
- "Boş anahtar (\"\") görünür kalır: quotesOnKeys kapalıyken de '\"\":' diye tırnaklı çizilir. sortKeys kod noktası sırasıdır (büyük harf önce: 'Alpha2' 'alpha'dan, '10' '2'den önce) — dil sıralaması değil.",
1991
- "Ağaç KLAVYEYLE gezilir (ARIA tree): gövde role=tree, satırlar role=treeitem (aria-level, genişletilebilirse aria-expanded, aria-selected); ağaç TEK Tab durağıdır (son odaklanan satır), Tab ağaçtan çıkarır. ↑/↓ komşu satır, Home/End uçlar, → kapalı dalı açar (açıksa ilk çocuğa geçer), ← açık dalı kapatır (değilse üst satıra çıkar), Enter ya da Space nodeClick yayar (fareyle tıklamayla aynı yük; kırpılmış değerde onu da açar), Ctrl/Cmd+C satırın kopyala işini yapar (copy yayar; metin seçiliyse tarayıcıya bırakılır). Sağdan sola düzende → ile ← yer değiştirir. Alt'lı tuşlar ve Ctrl/Shift'li gezinti tuşları işlenmez. Aç/kapa oku, satır kopyala düğmesi ve kırpılmış değer düğmesi Tab durağı DEĞİL (fareyle tıklanır; tıklama odağı o satıra alır), araç çubuğu düğmeleri ve arama kutusu Tab ile erişilir. Satırın erişilebilir adı 'anahtar: önizleme'dir (örn. 'user: {3}')."
1896
+ "Dizi elemanlarının anahtarı indekstir: quotesOnKeys açıkken yalnız obje anahtarları tırnaklanır (ham JSON'daki gibi). path noktalı/köşeli yol üretir; nokta ya da boşluk içeren anahtar yolda kaçırılmaz (a.b anahtarı ile a→b aynı yolu verir)."
1992
1897
  ],
1993
1898
  propNotes: {
1994
1899
  data: 'Nesne/dizi ya da JSON metni; döngüsel referanslar "[Circular]" yaprağına düşer.',
@@ -2054,27 +1959,20 @@ export const componentKnowledge = {
2054
1959
  ],
2055
1960
  propNotes: {
2056
1961
  totalRows: 'Toplam kayıt; sayfa sayısı bundan hesaplanır. isTotalUnknown açıkken okunmaz (panelde gizlenir).',
2057
- variant: 'numbers (numaralı düğmeler) | simple (varsayılan; numarasız, sayfa kutusu showJumper ile) | compact (salt "3 / 12", kutu yok) | dots (sayı yerine noktalar, etkin nokta uzun; carousel gibi, pencere siblingCount ile). showJumper numbers, simple ve dots’ta kutuyu ekler. compact yalnız göstergeyi değiştirir: bilgi metni (showPageInfo) ve satır seçici (showLimitSelector) varsayılan açıktır ve göstergenin yanında çizilmeye devam eder — yalnız "3 / 12" istiyorsan ikisini de kapat.',
2058
- siblingCount: 'numbers ve dots’ta mevcut sayfanın iki yanındaki komşu sayısı; ilk ve son sayfa hep görünür, atlananlar "…".',
1962
+ variant: 'numbers (numaralı düğmeler) | simple (varsayılan; numarasız, sayfa kutusu showJumper ile) | compact (salt "3 / 12", kutu yok). showJumper numbers ve simple’da kutuyu ekler.',
1963
+ siblingCount: 'numbers’ta mevcut sayfanın iki yanındaki komşu sayısı; ilk ve son sayfa hep görünür, atlananlar "…".',
2059
1964
  align: 'left (varsayılan) | center | right barı doğal genişliğinde konumlar; none hücreyi doldurur.',
2060
1965
  limitOptions: 'Sayfa boyu seçenekleri; geçersizler elenir, hiçbiri kalmazsa [10,20,30,40,50] kullanılır. Listede olmayan limit seçiciye kendiliğinden eklenir.',
2061
- infoTemplate: '{from} {to} {total} {page} {pages} yer tutucuları; {fromText} {toText} {totalText} aynı sayılar ama dile göre binlik ayraçlı ("1,000" / "1.000"), {total} ham kalır. Boşsa yerelin varsayılan metni ("30 / 57", en: "30 of 57", ar: "30 / 57"). Etiketler tr, en ve ar\'de yerelleşir; başka dil İngilizceye düşer.',
2062
- previousLabel: 'Önceki düğmesinin simgesinin yanına yazılan metin ("Previous", "Geri"); boşsa yalnız simge. Doluysa düğmenin erişilebilir adı da bu metin olur. Metin sabittir (locale ile değişmez): çok dilli istiyorsan translation değeri ver. CSS content: ile ok metni yazma — dile bağlı olmaz.',
2063
- nextLabel: 'Sonraki düğmesinin simgesinin soluna yazılan metin ("Next"); boşsa yalnız simge. previousLabel ile aynı kurallar.',
2064
- limitOptionTemplate: 'Satır seçicisindeki her seçeneğin etiketi; {count} sayıyla dolar ("{count} / page" → "10 / page"). Boşsa yerelin varsayılanı ("10 satır", en: "10 rows"). Tanınmayan yer tutucu olduğu gibi kalır; {count} içermeyen şablon her seçeneğe aynı etiketi basar. Yalnız showLimitSelector açıkken görünür.',
2065
- jumperPrefixLabel: 'Sayfa numarası kutusunun soluna yazılan metin ("Go to"); yalnız showJumper açıkken ve compact dışında çizilir. Sabit metindir; CSS content: ile yazma. Stil için style `&__label`.',
2066
- jumperSuffixLabel: 'Sayfa numarası kutusunun sağına yazılan metin ("Page"); jumperPrefixLabel ile aynı kurallar. Kutunun yanına yerleşimi `order` ile ayarlanır (örn. &__limit {order:1}, &__label ve &__page {order:2}).',
2067
- showLastPage: 'Yalnız variant numbers ve dots: sağ "…" sonrası son sayfa (numara ya da nokta). false → "…" kalır, son sayfa basılmaz; CSS ile son numarayı gizleme. isTotalUnknown açıkken etkisizdir (panelde gizli).',
1966
+ infoTemplate: '{from} {to} {total} {page} {pages} yer tutucuları; boşsa yerelin varsayılan metni ("30 / 57", en: "to 30 of 57").',
2068
1967
  isTotalUnknown: 'Toplam kayıt sayısı dönmeyen (cursor/"daha fazla var mı" tarzı) veri için; açıkken ileri gitmeyi hasNextPage belirler.',
2069
- hasNextPage: 'Metin gelirse yalnız true/"true" açık sayılır. Yalnız isTotalUnknown açıkken okunur (panelde yalnız o zaman görünür); false → ileri düğmesi kapalı. Varsayılan true.',
2070
- style: "Görünümü (yuvarlak aktif sayfa, hap kap, düz kutulu, chip'li…) style ile kurarsın; variant/size görünümü değil yalnız yapıyı seçer. style KÖK CSS özelliklerini çubuğa yazar (background, borderRadius, boxShadow, padding, width…) ve parça anahtarları alır: &__nav (ok SARMALAYICI div'i — düğmenin kendisi değil: ok düğmesinin ölçüsü/rengi için '&__nav button' yaz), &__number (sayı düğmeleri), &__page (sayfa kutusu — input, ::before/::after almaz), &__label (jumperPrefixLabel/SuffixLabel metinleri), &__info, &__limit (seçici sarmalayıcısı). AKTİF SAYFA ayrı parça DEĞİLDİR: &__number[aria-current='page'] ile hedeflenir (--active/--current gibi sınıf adları tutmaz). Bileşenin kendi kuralları daha özgül: platform her değere !important ekler, o yüzden border/background/borderRadius yazılınca ezer. Çubuğun yüksekliği sabittir (size'a göre 26–36px, varsayılan yazı boyutunda; dikey taşan içerik kırpılır, yatay taşan çubuğun içinde kayar): düğmeleri büyütecek ya da gölge/dikey yerleşim isteyen tasarımda köke height:'auto' ver. İç içe seçici (&__nav:first-child, &__number:not(:last-child), sıradaki-kardeş ~), kökte &::before/&::after + order ve @media çalışır. SINIR: ok simgesinin kendisi prop ile değişmez. Ok yanındaki metin için previousLabel/nextLabel, seçici etiketi için limitOptionTemplate kullan — &__nav::after { content: 'Next' } gibi CSS metni SABİTTİR (locale ve değerle değişmez, çevrilmez). Dinamik bilgi metni yalnız infoTemplate'ten gelir (binlik ayraç için {totalText}); 'Go to … Page' için jumperPrefixLabel/jumperSuffixLabel, son numarayı gizlemek için showLastPage:false kullan."
1968
+ hasNextPage: 'Metin gelirse yalnız true/"true" açık sayılır. Yalnız isTotalUnknown açıkken okunur (panelde yalnız o zaman görünür); false → ileri düğmesi kapalı. Varsayılan true.'
2071
1969
  }
2072
1970
  },
2073
1971
  progress: {
2074
1972
  summary: 'Çubuk ya da daire biçiminde ilerleme göstergesi; eşiğe göre renk değiştirir. label neyin ilerlediğini yazar, showLabel değer okumasını açar.',
2075
1973
  behavior: [
2076
1974
  "complete yalnız yüzde 100'e İLK ULAŞTIĞINDA (kenar tetiklemesi) bir kez yayılır — her render'da değil; değer 100'ün altına inip yeniden çıkarsa tekrar yayılır. isIndeterminate:true iken hiç yayılmaz (belirsiz modda 'tamamlanma' tanımsızdır). Sayfa açılışta zaten %100 olan gösterge de YAYMAZ: olay 'ulaşma' anıdır, açılışta ulaşılmış bir şey yoktur (2026-10-01, QA PG-005) — açılışta tamamlanmış durumu yakalamak için mount akışında değeri kendin sına.",
2077
- 'click yalnız akış BAĞLIYSA çalışır: bağlıyken sarmalayıcı <button> olur ve odak sırasına girer, bağlı değilken düz <div> kalır (badge/avatar/icon/image/statcard ile aynı desen; videoda sarmalayıcı her zaman <div>, kontrolsüzken role=button). role="progressbar" içteki elemanda kalır.',
1975
+ 'click yalnız akış BAĞLIYSA çalışır: bağlıyken sarmalayıcı <button> olur ve odak sırasına girer, bağlı değilken düz <div> kalır (badge/avatar/icon/image/video/statcard ile aynı desen). role="progressbar" içteki elemanda kalır.',
2078
1976
  'max alanı TEMİZLENİRSE 100 sayılır (şema varsayılanı), 0 değil — boş sayı alanı panelde null olarak saklanır ve 0 gibi okunsaydı bar tamamen boşalırdı. Prop .min(1) olduğu için kaybedilen bir "0" hâli yoktur.'
2079
1977
  ],
2080
1978
  propNotes: {
@@ -2158,21 +2056,18 @@ export const componentKnowledge = {
2158
2056
  'invertTrend yalnız RENGİ ters çevirir (hata oranı gibi "azalan iyidir" metrikleri için); ok yönü değişmez. trendFormat yalnız METNİ değiştirir: percent "+12%", value "+340".',
2159
2057
  'Kartın kendisi click (yalnız bir akış bağlıysa; bağlıyken ana yüzey <button> olur), alt bilgi satırı ayrı footerClick yayar. footerHref ile footerFlow BİRLİKTE çalışır: satır bağlantı olur ve tıklamada footerClick yine yayılır — gezinme akışı yarıda kesebilir; ikisini birlikte kullanacaksan isNewTabLink aç.',
2160
2058
  'İkon rengi TEK kanaldır: iconColor + customIconColor. Icon picker\'ın gömülü renk alanı kapalıdır (colorless); çip zemini custom olduğunda glifin rengi zeminin ÖLÇÜLEN parlaklığından seçilir, açık renkte koyu glif çizilir.',
2161
- 'Tipli stil grupları kartın PARÇALARINA iner: typographyStyle.textColor başlık + değer + alt başlığı birlikte boyar (trend anlam rengini, alt satır bağlantı rengini korur), fontSize kartın bütün puntolarını orantılı ölçekler, hoverStyle.background tıklanabilir yüzeyde ve alt satırda da geçerlidir. Kartın ipucu için prop yoktur; düğümün ortak appearance.tooltip alanı kullanılır.',
2162
- "MCP ile eklenen kartta çerçeve, gölge ve köşe KENDİLİĞİNDEN GELMEZ: bu varsayılanlar component_get.defaults.surfaceStyle'da yaşar ve sayfaya YAZILMAZSA kart çerçevesiz ve gölgesiz çizilir. Kısmî surfaceStyle (yalnız borderTop) ötekileri varsayılanda TUTMAZ — dört kenarı da, shadow ve radius'u birlikte yaz.",
2163
- 'valueFormat.decimals YAZILMAZSA sayının kendi ondalığı (en çok iki) gösterilir: 3.1 "3,1", -45.5 "-45,5", 1250 "1.250"; açıkça yazılan decimals (0 dahil) bunu ezer ve yuvarlar. abbreviate açıkken basamak 0 kalır (1500 "2K"; decimals:1 ile "1,5K"). Aralık dışı decimals 0..20\'ye kenetlenir (eskiden negatif decimals tüm sayfayı çökertirdi). Trend metni değerle AYNI dilin ayraçlarıyla ve en çok iki ondalıkla yazılır (tr: "+12,5%").',
2164
- 'trendLabel yalnız trend VARKEN çizilir (trend boş/geçersizse etiket de çizilmez): trend ve etiket birlikte bağlanır.',
2165
- 'style parçaları: &__title · &__value · &__trend · &__subtitle · &__icon · &__sparkline · &__footer. Trend etiketi ve ana yüzey için parça YOKTUR; iç içe seçici yaz: "& .ng-statcard__trend-label", "& .ng-statcard__main:focus-visible", "& .ng-statcard__footer:hover". Odak halkası varsayılan olarak içeride, 2px vurgu renginde çizilir.',
2166
- 'Uzun başlık, altyazı, trend etiketi ve alt satır metni satır kırar, kırpılmaz; değer tek satırdır ve sığmazsa "…" ile biter (title tam metni taşır). 999px gibi büyük köşe yarıçapı alt satırın köşesini kırpar.'
2059
+ 'Tipli stil grupları kartın PARÇALARINA iner: typographyStyle.textColor başlık + değer + alt başlığı birlikte boyar (trend anlam rengini, alt satır bağlantı rengini korur), fontSize kartın bütün puntolarını orantılı ölçekler, hoverStyle.background tıklanabilir yüzeyde ve alt satırda da geçerlidir. Kartın ipucu için prop yoktur; düğümün ortak appearance.tooltip alanı kullanılır.'
2167
2060
  ],
2168
2061
  propNotes: {
2169
- value: 'Sayı ya da metin; sayıysa valueFormat uygulanır.',
2170
- valueFormat: 'decimals yazılmazsa sayının kendi ondalığı (en çok 2; 3.1 → "3,1"), abbreviate açıkken 0; thousandsSep kapalıyken ondalık ayracı DEĞİŞMEZ (1250,00); abbreviate basamaktan önce yuvarlar (1500 → "2K", decimals:1 ile "1,5K").',
2171
- sparkline: 'Sayı dizisi; kendi min/max’ına göre ölçeklenir (sıfır tabanlı değil).',
2062
+ value: 'Sayı ya da metin; sayıysa valueFormat uygulanır. rows Connect Data ile bağlıyken basılmaz — yerine rows özeti gelir.',
2063
+ rows: "Ana değerin Connect Data kaynağı (39/03 U-13, 2026-09-21): birincil bağlanabilir prop (connectData.primary: rows, rol value: number zorunlu); connect_data_bind { prop: 'rows', roles: { value: '<sayı alanı>' } }. Bağlıyken kart value yerine valueAggregate özetini basar. Sayfalamaz: tanımın sayfa boyu 1000 yazılır (connect_data_bind pageSize vermezseniz) — kaynak 1000'i aşarsa sum/avg/min/max kesiktir ve runtimeErrors'a ConnectDataRowsTruncated düşer.",
2064
+ valueAggregate: "Bağlı rows'tan ana değer: first (varsayılan; ilk satırın value'su — tek değer döndüren query/microservice), count (kaynağın meta.total'ı → totalRows, 1000'i aşan kaynakta da tam), sum · avg · min · max (okunan satırlar). Bağlama bu prop'u yazmaz; page_schema_patch set_prop ile seçilir.",
2065
+ totalRows: 'Gizli; runtime bağlantısı yazar (count özeti okur). Elle yazılmaz.',
2066
+ sparkline: 'Sayı dizisi; kendi min/max’ına göre ölçeklenir (sıfır tabanlı değil). Connect Data ile de bağlanır (ikincil prop, prop: sparkline) — araç çubuğundaki Connect data artık ana değeri (rows) bağlar.',
2172
2067
  trend: 'Değişim miktarı; işareti yönü ve rengi belirler, birimini trendFormat söyler. 0 nötrdür ve panelden temizlenemez.',
2173
2068
  trendFormat: 'percent (varsayılan) yüzde işaretiyle yazar; value işareti korur, birim yazmaz — mutlak değişim gösteren KPI için.',
2174
2069
  isNewTabLink: 'Yalnız footerHref doluyken anlamlı: target="_blank" + rel="noreferrer noopener". Yeni sekmede footerFlow akışı da tamamlanır.',
2175
- isLoading: 'Kartı soldurur ve etkileşimi keser — fare VE klavye: düğmeler disabled olur, Tab\'a girmez, click/footerClick yayılmaz; alt satır bağlantısıysa tıklama yutulur. İçerik yerinde kalır, iskelet çizilmez.'
2070
+ isLoading: 'Kartı soldurur ve etkileşimi keser; içerik yerinde kalır, iskelet çizilmez.'
2176
2071
  }
2177
2072
  },
2178
2073
  switcher: {
@@ -2224,24 +2119,16 @@ export const componentKnowledge = {
2224
2119
  'maxCount üstü kayıtlar atılmaz: "Show more" çıkar, showMore olayı yayılır ve kalanların tamamı açılır; items yeni bir diziyle değişince (akışın items[index] alanını yazması DAHİL) görünüm kırpılmış hâline döner.',
2225
2120
  "Her satır tıklaması clickItem yayar: event.data = { currentItem, index }, öğe ayrıca self.currentItem'a yazılır. index items dizisindeki GERÇEK yerdir (reverse/maxCount'tan etkilenmez) — akış items[index]'i güncelleyebilir.",
2226
2121
  "Öğede flow varsa panelde bağlı clickItem akışı da öğenin kendi flow'u da çalışır — bağlı olay önce başlatılır ama biri diğerini BEKLEMEZ; ikisi de aynı event.data'yı ve self.currentItem'ı görür. Aynı akışı hem olaya hem öğenin flow alanına bağlama: İKİ KEZ çalışır. href'li satır gerçek bağlantıdır (sayfa değişir); flow'lu satır klavyeyle (Enter/Space) de tetiklenir, imleç yalnız href/flow'lu satırda el olur.",
2227
- 'orientation:horizontal yalnız öğe listesini yatay kayan şerit yapar; title üstte, "Show more" altta kalır. Bağlantı çizgisi noktaları birleştirir ve yöne uyar: sağdan sola (ar) sayfada nokta sağda, çizgi noktanın altında/bir sonraki öğeye (solda) uzanır.',
2228
- 'Nesne olmayan öğe (null, düz metin) atlanır; tanınmayan status primary rengine düşer. İçeriği aynı yeni dizi ("Show more" açıkken) görünümü KAPATMAZ — items bir {{ }} ifadesinden her çizimde yeniden üretilse de.',
2229
- "dateFormat 'relative' tarihi Intl ile PROJE DİLİNDE yazar (uygulama dili ar ise Arapça, de ise Almanca; 'yaklaşık' ön eki yok, 1 dakikadan azı 'şimdi'; saatsiz tarih takvim günüyle: 'bugün', '1 gün önce', saat farkı yazılmaz). 'absolute' uzun ay adıyla basar (12 Ekim 2026) ve tarayıcının yerel saatini kullanır (2026-09-28T09:00:00Z, +03'te 12:00); biçimi (kısa ay, saatsiz) denetleyen bir prop YOK.",
2230
- 'Dil: locale yalnız tr/en seçtirir; başka bir dil (ar, de…) için locale\'ı BOŞ bırak, uygulama dili izlenir. showMoreText ve emptyText BOŞ (ya da yalnız boşluk) ise ekran diline göre sözlük metni yazılır; her ikisi de YENİ düğümde BOŞ başlar (ekran diline uyar: "Daha fazla göster", "Henüz olay yok", ar); daha önce kaydedilmiş sayfalarda düğüme yazılı İngilizce metin ("Show more", "No events yet") olduğu gibi kalır ve ÇEVRİLMEZ — çok dilli sayfada onları boşalt ya da kendi metnini ver.',
2231
- 'Erişilebilirlik: liste ol/li ile bir liste olarak okunur; nokta ve ikon ekran okuyucudan gizlidir (ikon adı okunmaz); status (info, success, warning, error) ve isPending ekran okuyucuya metin olarak da verilir (renk tek başına anlam taşımaz); isLoading kök aria-busy taşır ve iskelet satırlar gizlidir; odak halkası 2px; prefers-reduced-motion altında nabız animasyonu durur. Klavye: yalnız flow\'lu satır (Enter/Space) ve href\'li satır (Tab) odaklanır — flow\'suz, href\'siz ama panelde clickItem bağlı satır isClickable açılmadıkça YALNIZ fareyle tetiklenir — isClickable: true ise her satır Tab durağı, role=button olur, imleç el olur ve Enter/Space clickItem yayar.',
2232
- 'Uzun metin: başlık, öğe başlığı, alt başlık, açıklama, boş metin ve "Show more" boşluksuz 300 karakterde bile satır kırar; yatay şeritte öğe en çok 280px genişler.',
2233
- 'href yalnız http(s), mailto, tel, /yol, site adresi ve göreli yol kabul eder; javascript:, data: ve vbscript: adresi bağlantıya ÇEVRİLMEZ (satır düz satır olur, tıklayınca yalnız clickItem yayılır).'
2122
+ 'orientation:horizontal yalnız öğe listesini yatay kayan şerit yapar; title üstte, "Show more" altta kalır.',
2123
+ 'Nesne olmayan öğe (null, düz metin) atlanır; tanınmayan status primary rengine düşer.'
2234
2124
  ],
2235
2125
  propNotes: {
2236
- items: '[{ title, subtitle, description, date, status, color, icon, avatar, href, flow, isPending }] — boş alanlar çizilmez (alanı olmayan öğe yine de bir nokta çizer). date ISO metin ("2026-01-02" ya da "2026-01-02T14:30:00Z"); başka biçim olduğu gibi basılır. status: primary|info|success|warning|error (info nötr gri, primary mavi). color doluysa status rengini ezer: #hex (3/4/6/8 hane), rgb()/hsl()/oklch() gibi renk fonksiyonu, var(--token), TARAYICININ tanıdığı düz renk adı ya da status adı; başka her şey (tanınmayan sözcük "zzz", iç içe parantez, ; taşıyan metin) sessizce yok sayılır ve status rengi kullanılır. flow alanı olan öğede currentItem içinde flow depolama şeklinde ({ ref, type }) gelir — akışta kullanma, flow kendiliğinden çalışır. Statik items dizisine null/düz metin yazılamaz (platform 500 verir); karışık veri için items\'ı {{ }} ifadesine bağla.',
2237
- dateFormat: 'absolute (varsayılan) | relative ("2 gün önce", proje dilinde).',
2126
+ items: '[{ title, subtitle, description, date, status, color, icon, avatar, href, flow, isPending }] — boş alanlar çizilmez. date ISO metin ("2026-01-02" ya da "2026-01-02T14:30:00Z"); başka biçim olduğu gibi basılır. status: primary|info|success|warning|error. color doluysa status rengini ezer: #hex (3/4/6/8 hane), rgb()/hsl()/oklch() gibi renk fonksiyonu, var(--token), düz renk adı ya da status adı; başka her şey (iç içe parantez, ; taşıyan metin) sessizce yok sayılır.',
2127
+ dateFormat: 'absolute (varsayılan) | relative ("2 gün önce").',
2238
2128
  maxCount: 'Görünür kayıt sınırı; boş/0 = hepsi. Aşıldığında Show more çıkar (showMoreText yalnız maxCount doluyken panelde görünür).',
2239
2129
  currentItem: "Gizli prop: son tıklanan öğenin tamamı (self.currentItem). index yalnız event.data'da.",
2240
- locale: 'Tarih dili (yalnız tr | en); boşsa uygulama dili — ar, de gibi diller için BOŞ bırak.',
2241
- showMoreText: 'Boşsa (yeni düğümde varsayılan) ekran diline göre ("Daha fazla göster"); eski kayıtlı sayfalarda yazılı "Show more" çevrilmez.',
2242
- emptyText: 'items boşken basılan metin; boşsa (yeni düğümde varsayılan) ekran diline göre ("Henüz olay yok"); eski kayıtlı sayfalarda yazılı "No events yet" çevrilmez.',
2243
- isClickable: 'Varsayılan kapalı. Açıkken flow\'suz ve href\'siz satır da klavyeyle odaklanır (Tab, role=button), Enter/Space clickItem yayar ve imleç el olur — panelde clickItem akışı bağlayıp klavye erişimi isteyen için.',
2244
- style: 'Kök CSS özellikleri (fontFamily, fontSize, color, backgroundColor, padding, border…) çalışır; fontFamily ve color liste başlığına ve öğe başlığına, fontSize yalnız öğe başlığına İNER (liste başlığı kendi ölçüsünü taşır: &__title { fontSize }). Kökte maxHeight TEK BAŞINA kırpmaz (CSS gereği içerik taşar): kaydırmak için overflowY: auto da yaz. gap kökte etkisiz; satırlar arasına boşluk (gap, margin) bağlantı çizgisini KOPARIR çünkü çizgi satırın kendi dolgusuna göre çizilir — boşluk istiyorsan showConnector kapat ya da &__row::after top/height değerini kendin ayarla. PARÇA SÖZLÜĞÜ (&__parça): title (listenin BAŞLIĞI), row, dot, content, date, description, item-title (HER ÖĞENİN başlığı), subtitle, header (başlık+tarih satırı), avatar, more ("Show more" düğmesi), empty (boş metin), list, item (li). Durum hedefi: satırda data-status="success|warning|…" var → &__row[data-status="error"] { … }; bekleyen nokta .ng-timeline__dot--pending, bağlantısız mod .ng-timeline--no-connector, yatay mod .ng-timeline--horizontal. Bağlantı çizgisi satırın ::after\'ı (yatayda ayrıca ::before — önceki öğeye uzanan yarı); rengi için &__row::after { background } (yatayda &__row::before da yaz, yoksa çizgi iki renkli olur). :hover, :focus-visible, iç içe seçici, ::before/::after ve @media çalışır; @media içinde && yazma (geçersiz seçici üretir). Her satır bir <li> içindedir: &__row:nth-child(…), :first-child ve :last-child HER satırı eşler — dönüşümlü/zebra için &__item:nth-child(odd) &__row yaz; yatayda &__row min-width li sınırını (280px) aşar.'
2130
+ locale: 'Tarih dili; boşsa uygulama dili.',
2131
+ emptyText: 'items boşken basılan metin.'
2245
2132
  }
2246
2133
  },
2247
2134
  timepicker: {
@@ -2249,8 +2136,8 @@ export const componentKnowledge = {
2249
2136
  behavior: [
2250
2137
  'minTime/maxTime dışındaki seçenekler listeden ATILMAZ, pasifleştirilir; minutesStep seçenek adımını belirler.',
2251
2138
  "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.",
2252
- "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.",
2253
- "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ı.",
2139
+ "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 (panelin 'Seçimi temizle' düğmesi) de change yayar, ikisi de boş metin olur.",
2140
+ "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. 2026-10-05'ten beri liste kapalıyken de tıklama ya da tuş paneli açar ve yükleniyor satırı görünür.",
2254
2141
  "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.)",
2255
2142
  '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).',
2256
2143
  '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.'
@@ -2261,7 +2148,7 @@ export const componentKnowledge = {
2261
2148
  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).",
2262
2149
  maxTime: 'Bu saatten sonrası listede kalır ama seçilemez; minTime ile aynı bağışlayıcı okuma.',
2263
2150
  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.",
2264
- clearable: 'Seçili saatin yanındaki X (varsayılan açık). Temizleme change yayar, ayrı bir olay yoktur.',
2151
+ clearable: "Panelin altındaki 'Seçimi temizle' düğmesi (varsayılan açık, yalnız değer varken; 2026-10-05'e kadar alandaki X idi). Temizleme change yayar, ayrı bir olay yoktur.",
2265
2152
  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.',
2266
2153
  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).",
2267
2154
  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.",
@@ -2319,22 +2206,18 @@ export const componentKnowledge = {
2319
2206
  "Veri tek yönlü girer: record prop'u {{ }} ifadesiyle (sorgu çıktısı ya da tablonun selectedRow'u) ya da akıştaki setter ile beslenir; tıklama/seçim olayı yoktur — satır tıklaması gerekiyorsa tıklanabilir bir kapsayıcıya sar. Tek olay mount'tur (yük yok).",
2320
2207
  "Boş nesne ({}) 'kayıt yok' sayılır ve emptyText basılır; geçerli kayıt olsa da fields boşsa (ya da tüm alanlar isHidden ise) yine boş durum çizilir. isLoading her dalı ezer ve alan başına iskelet gösterir.",
2321
2208
  "fields[].field nokta ayraçlı iç içe yol alır (department.title, items.0.name); yol kopuksa hücre '-' basar, patlamaz. Aynı alanı iki satırda iki ayrı formatla göstermek geçerlidir (2026-09-16'dan önce sayfayı düşürüyordu).",
2322
- "format: money/pertance/date/datetime/number biçimlenir, 'text' ham String basar. number dilin ayıraçlarını kullanır (tr 84.500), sayıya çevrilemezse ham metne düşer; money fields[].currency'den (ISO 4217: 'USD', 'EUR') para birimini alır, boş ya da geçersiz değer TRY'dir; pertance (yazımı böyle) <=1'i oran, >1'i yüzde sayar; geçersiz tarih ham metne düşer. boolean değeri ✓/✗ işaretine çevirir — yalnız false/0/'false'/'0' hayırdır, tanınmayan dolu metin evettir (table'ın 'switch' kolon tipinin detailview'daki adı 'boolean').",
2209
+ "format: money/pertance/date/datetime/number biçimlenir, 'text' ham String basar. number dilin ayıraçlarını kullanır (tr 84.500), sayıya çevrilemezse ham metne düşer; money her zaman TRY'dir; pertance (yazımı böyle) <=1'i oran, >1'i yüzde sayar; geçersiz tarih ham metne düşer. boolean değeri ✓/✗ işaretine çevirir — yalnız false/0/'false'/'0' hayırdır, tanınmayan dolu metin evettir (table'ın 'switch' kolon tipinin detailview'daki adı 'boolean').",
2323
2210
  "locale boşken uygulama diline CANLI bağlıdır (dil değişince yeniden biçimler); size boş kaydedilir ve 'md' varsayılanı komponentin içinde çözülür.",
2324
2211
  "columns 1-4'tür ama sınırı zorlayan tek yüzey kanvas toolbar'ıdır: sağ panel büyük değeri uyarı ikonuyla KABUL EDER ve öyle kaydeder, runtime yine 1-4'e kırpar ve kesirli değeri tam sayıya indirir — yani 8 yazılmış bir sayfa 4 kolon çizer. link formatı görünen metni ham bırakır ama href'i düzeltir: şemasız değer https:// alır, e-posta gibi duran değer mailto: olur, '/...' ve '#...' olduğu gibi kalır; BEYAZ LİSTE dışındaki şema (javascript:, data:…) hiç bağlantı olmaz, değer düz metin basılır.",
2325
- "style parçaları: &__grid (ızgara), &__item (alan satırı), &__label, &__value, &__empty (boş durum) ve biçim işaretleri &__badge, &__tag, &__link, &__boolean, &__image ayrı ayrı hedeflenir. Rozetin değere göre rengi için fields[].colorMap kullan (aşağıda), style ile değer→renk yazılmaz. tag kendi açık zemini ve kendi yazı jetonuyla çizilir (kökte color vermek onu okunmaz yapmaz); koyu ya da gradyan zeminde istersen &__tag ile boya.",
2326
- "columns bir ÜST SINIRDIR: kap her kolona en az 8rem (labelPosition left iken 14rem) bırakamıyorsa kolon sayısı kendiliğinden düşer — 375px'te columns 4 iki kolon (left etiketle tek kolon) çizer, 628px ve üstünde aynen kalır. Dar ekran için ayrıca @media yazmana gerek yok.",
2327
- "badge rengi değere göre verilir: fields[].colorMap = [{ value: 'active', color: 'success' }, { value: 'pending', color: 'warning' }, { value: 'failed', color: 'error' }]. Tonlu rozet tonun tintli zemininde ve tonla kökten devralınan rengin karışımı yazıyla çizilir (iki temada da ≥ 5.7 kontrast ölçüldü). Sınır: info tonu açık temada neredeyse beyazdır, hap görünmez — durum ayrımı için success/warning/error tercih et.",
2328
- "tarih ve saat tr/en dışı dilde (ar, de…) o dilin Intl biçimiyle yazılır (ar: 14 مارس 2022); tr ve en date-fns desenleriyle aynen (14 Mar 2022 / Mar 14, 2022). Eskiden bu diller Türkçe ay adına düşüyordu.",
2329
- "mount ilk görünür olduğunda BİR kez yayılır: isHidden açık açılan sayfada çıkmaz, gösterilince çıkar; sonradan gizleyip göstermek yeniden yaymaz."
2212
+ PROTECTED_VALUE_NOTE + " Künyede: kaydın __protected metası bir alanı maskeli işaretlerse o alanın format'ı UYGULANMAZ, kilitli maske çizilir; nokta ayraçlı iç içe yollar metaya bakılmadan normal çizilir (meta kök alan slug'ı taşır)."
2330
2213
  ],
2331
2214
  propNotes: {
2332
2215
  record: 'Gösterilecek TEK kayıt (nesne); akıştan beslenecekse setter hedefi budur. Boş nesne = boş durum.',
2333
- fields: "[{ label, field, format, currency, colorMap, icon, isHidden }] — field boş satırlar elenir, isHidden satır çizilmez (table kolonlarındaki isHidden ile aynı iş), label boşsa field kullanılır, icon ETİKETİN yanına çizilir. colorMap: [{ value, color }] YALNIZ badge biçiminde okunur — value alanın değeriyle (metin olarak, kırpılmış, büyük/küçük harfe DUYARLI) eşleşir, color primary | info | success | warning | error tonlarından biridir (ham renk kabul edilmez, tema jetonuna çözülür); eşleşmeyen değer eski vurgu renginde kalır; tanınan ton taşımayan (color boş ya da geçersiz) satır atlanır, aynı değerli sonraki geçerli satır kazanır; tag biçimi tonlanmaz.",
2216
+ revealEntity: REVEAL_ENTITY_NOTE,
2217
+ fields: "[{ label, field, format, icon, isHidden }] — field boş satırlar elenir, isHidden satır çizilmez (table kolonlarındaki isHidden ile aynı iş), label boşsa field kullanılır, icon ETİKETİN yanına çizilir.",
2334
2218
  labelPosition: "top (varsayılan) | left — left'te etiket sütunu minmax(96px, %38) ile ayrılır.",
2335
- columns: "Izgara kolon sayısı ÜST SINIRI, 1-4. Kanvas toolbar'ı sınıra çeker; sağ panel büyük değeri uyarı ikonuyla kabul eder, runtime yine 1-4'e kırpar. Dar kapta kolon sayısı kendiliğinden düşer (her kolona en az 8rem, left etiketle 14rem).",
2336
- emptyText: "Kayıt ya da geçerli alan yokken basılır; boşsa '—'.",
2337
- style: "Kök özellikler + &__grid · &__item · &__label · &__value · &__empty · &__badge · &__tag · &__link · &__boolean · &__image. &__label::after, @media, :hover, :nth-child, & a:hover çalışır."
2219
+ columns: "Izgara kolon sayısı, 1-4. Kanvas toolbar'ı sınıra çeker; sağ panel büyük değeri uyarı ikonuyla kabul eder, runtime yine 1-4'e kırpar.",
2220
+ emptyText: "Kayıt ya da geçerli alan yokken basılır; boşsa '—'."
2338
2221
  }
2339
2222
  },
2340
2223
  eventcalendar: {
@@ -2345,23 +2228,21 @@ export const componentKnowledge = {
2345
2228
  "startField'ı geçersiz/boş satır SESSİZCE atılır; end geçersizse start'a eşitlenir, ters aralık start'a kırpılır; id yoksa event-<index> üretilir.",
2346
2229
  "Taşıma ve boyutlandırma iyimserdir: eventMove sonrası komponent rows'u DEĞİŞTİRMEZ; akış yeni tarihi uca yazıp rows'u tazeleyince (id:start:end imzası değişince) iyimser katman sıfırlanır — kalıcılaştırılmayan değişiklik, veri değiştiği anda geri döner (kanban ile aynı sözleşme).",
2347
2230
  "Veri tazeleme kancası monthChange (oklar/Bugün, HER görünümde) ve viewChange'dir; ikisi de görünen aralığı start/end ('yyyy-MM-dd', iki uç dahil) olarak taşır — sorguyu month/year'a değil start/end'e bağla: ajanda ve hafta ay sınırını aşar, ay ızgarası da komşu ayların günlerini gösterir. end TARİH-YALNIZ ve DAHİLDİR: filtreyi KESİŞİM olarak yaz — etkinlikBaşlangıç < (end + 1 gün) VE etkinlikBitiş >= start; `başlangıç <= end` saatli kolonda son günün saatli kayıtlarını, `başlangıç >= start VE bitiş <= end` kenardan taşan kayıtları düşürür. İlk mount'ta yayılmazlar; açılış aralığını defaultDate/defaultView belirler. month 1-TABANLIDIR.",
2231
+ "BAĞLI VERİ (2026-09-17, f-31): rows bağlıysa (roller title, start, end, color, id; start/end tarih rolü) runtime listeyi görünen ayın çevresiyle okur — yalnız start alanı behavior.filterable'daysa (değilse süzmeden ilk sayfa): start gte ayın 1'i − 7 gün, lt sonraki ayın 1'i + max(7, agendaDays) gün; sayfalanmaz, en çok 1000 olay. İlk okuma defaultDate'in ayıyla (boşsa bugün), monthChange aralık değişince yeniden okur. Aralıktan önce başlayan olay gelmez. Akış yazmak gerekmez.",
2348
2232
  "isCreatable:true iken tıklama dateClick YERİNE eventCreate yayar: ay hücresi tek günlük allDay:true, hafta/gün boş slotu 60 dakikalık saatli taslak. Basılı tutup sürüklemek aralık seçer: ayda birden çok gün (allDay:true, end son gün dahil), hafta/gün kolonunda aynı günün birden çok saat slotu, etkinlik bloklarının üstünden de (end son slotun sonu) — bırakınca TEK eventCreate. Sürükleyerek seçim fare/kalemle çalışır; dokunmatikte yalnız tek hücre tıklaması oluşturur. Basış sürerken isLoading açılır ya da isCreatable kapanırsa bırakış olay yaymaz. isCreatable kapalıyken slot tıklaması hiçbir şey yapmaz.",
2349
2233
  "isEditable ile sürükleyerek taşıma: ay görünümünde ve tüm-gün şeridinde gün kayar (saat korunur), hafta/gün kolonunda saat 30 dakikaya yuvarlanır; tüm-gün etkinlik saat KAZANMAZ. Hafta/gün görünümünde saatli bloğun üst/alt kenarından boyutlandırma da vardır (30 dk adım, en az 30 dk) ve AYNI eventMove olayını yayar. Ajanda listesinde sürükleme yoktur.",
2350
2234
  "Tüm-gün kararı: satırın allDayField (varsayılan 'allDay') bayrağı true ise her zaman tüm gün; false ise yalnız aralıkta saat bilgisi varsa saatli sayılır (tarih-yalnız / 00:00→00:00 satır false'la da şeritte kalır, görünmez olmaz); değer true/false, 'true'/'false', 1/0; bayrak yoksa süresi >=24 saat ya da 00:00→00:00 olan etkinlik tüm gün sayılır. Tüm gün etkinlik saat ızgarası yerine üst şeride çizilir; çok günlü etkinlik ay görünümünde kapladığı HER güne ayrı çip düşer (sürekli bant yok).",
2351
2235
  "eventMove ve eventCreate tarihleri iki biçimdedir: tüm-gün aralık yerel 'yyyy-MM-dd', saatli aralık ISO-Z (toISOString) — uca yazarken ikisini de karşıla.",
2352
2236
  "defaultDate ve defaultView DEĞİŞTİKÇE uygulanır (panelde ya da akıştan yazınca takvim o tarihe/görünüme gider, olay yaymaz); aynı değerle tekrar gelen render kullanıcının gezindiği yeri sıfırlamaz — aynı tarihe tekrar gitmek için değerin değişmesi gerekir.",
2353
- "isLoading: takvim soluklaşır, üstte yükleyici; etkinlik tıklaması (Enter dahil), gün/slot tıklaması, aralık seçimi, taşıma ve boyutlandırma OLAY YAYMAZ. Gezinme okları ve görünüm düğmeleri açık kalır (monthChange/viewChange yayılır) — ay değiştirirken yeniden çekme sürebilir. Kök aria-busy=true taşır.",
2237
+ "isLoading: takvim soluklaşır, üstte yükleyici; etkinlik tıklaması (Enter dahil), gün/slot tıklaması, aralık seçimi, taşıma ve boyutlandırma OLAY YAYMAZ. Gezinme okları ve görünüm düğmeleri açık kalır (monthChange/viewChange yayılır) — ay değiştirirken yeniden çekme sürebilir.",
2354
2238
  "Hafta başlangıcı dile bağlıdır: en Pazar, diğer her dil (tr dahil) Pazartesi — ay ızgarası, gün başlıkları ve hafta görünümü aynı kuralı izler; locale boşsa uygulama dili. startHour/endHour saat penceresini belirler (0–23 / 1–24, endHour en az startHour+1'e kırpılır); pencereye kısmen taşan blok en az 15 dakikalık yükseklikle çizilir.",
2355
2239
  "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.",
2356
- "Klavye ve ekran okuyucu: ay hücresi odaklanmaz — içindeki gün numarası düğmesi odaklanır (adı 'tarih, n etkinlik'; Enter/Space isCreatable açıkken eventCreate, kapalıyken dateClick). Etkinlik (çip, blok, ajanda satırı) role=button'dır; Enter VE Space eventClick yayar, olay hücreye sızmaz (hücrenin dateClick/eventCreate'i ayrıca tetiklenmez). Saat dilimi düğmeleri yalnız isCreatable açıkken odaklanır ve tarih+saat adı taşır; bugünün hücresi aria-current=date, görünüm düğmeleri 'Takvim görünümü' adlı tablist içinde, odak halkası 2px. Klavyeyle taşıma/boyutlandırma ve aralık seçimi YOKTUR — onlar yalnız fare/kalem.",
2357
- "Dil: Bugün, görünüm adları, 'Etkinlik yok', 'Tüm gün' ve ok adları tr/en/ar sözlüğünden gelir; ay/gün adları da aynı üç dilde (başka dil İngilizceye düşer, Türkçeye değil). RTL'de çip şeridi ve ok yönü mantıksaldır (şerit sağda, önceki oku sağa bakar), çakışan bloklar sağdan dizilir.",
2358
- "Etkinlik rengi her zeminde okunur: yazı rengi etkinlik renginin ~%35'i + tema yazı renginin karışımıdır (açık sarı, beyaz, 'info' dahil kontrast ≥ 4.5, açık ve koyu tema); kenar şeridi ve zemin tonu ham renktir. Yani ham rengi yazıda aynen bekleme — renk kimliğini şerit ve zemin taşır.",
2359
- "Aynı kimlikli iki satır ÇÖKERTMEZ: ikisi de çizilir, yükte id aynen gider; iyimser taşıma kopyaları ayrı tutar (sürüklenen kopya kendi anahtarıyla kayar), ama data-element-id'leri aynıdır ve page_screenshot eylemi ilk eşleşmeye gider — id'leri benzersiz tut. Takvimde olmayan tarih ('2026-02-30', saatli '2026-02-30T10:00' dahil) satırı düşürür, defaultDate'te bugüne düşer (sessizce ertesi aya kaymaz); sayıya çevrilemeyen, boş ya da null startHour/endHour 8–18'e, maxVisibleEvents 3'e döner.",
2360
- "Dar ekranda başlık ve düğme grubu iki satıra bölünür (başlık kırpılmaz); tüm-gün şeridi ~8em'de kayar, çok sayıda tüm-gün etkinlik saat ızgarasını ezmez; 8+ çakışan blok dar sütunda yalnız renkli şerit gösterir — gün görünümüne geç."
2240
+ "source 'bpm-tasks' iken rows süreç görevleridir (Page.bpm.tasks.calendar(from, to).data): alan eşlemesi okunmaz; state planned görev plannedStartAt'tan dueAt'e uzanır (bilgi rengi), açık görev termin gününde gün boyu kayıt olur — saat penceresi dışındaki termin de hafta/gün görünümünde gün boyu şeridinde görünür (termini geçmişse hata, değilse uyarı rengi; renk dakikada bir tazelenir). Başlık name'in uygulama dilidir. Süreç görevleri sürüklenmez/boyutlanmaz (isEditable yok sayılır). eventClick satırı taskId ile taşır; akış Page.bpm.task(taskId) açar. Aralık en çok 92 gün."
2361
2241
  ],
2362
2242
  propNotes: {
2363
2243
  rows: 'Etkinlik satırları; monthChange/viewChange akışlarının setter hedefi. Alan adları titleField/startField/endField/colorField/idField/allDayField ile çözülür (nokta ayraçlı iç içe yol çalışır; boşsa title/start/end/color/id/allDay).',
2364
2244
  allDayField: "Tüm-gün bayrağının kolonu (boşsa 'allDay'). Tanınan değer true/false, 'true'/'false', 1/0; başka değer ya da kolon yoksa aralıktan çıkarılır. true saatli kaydı şeride alır; false 24 saati aşan saatli kaydı ızgarada tutar ama saatsiz (gece yarısı → gece yarısı) kaydı ızgaraya ALMAZ — şeritte kalır.",
2245
+ source: "rows (varsayılan, alan eşlemesi) | bpm-tasks (süreç görevleri: { id, name, dueAt, plannedStartAt, state }).",
2365
2246
  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.",
2366
2247
  maxVisibleEvents: 'Ay hücresinde görünen çip sayısı (varsayılan 3); fazlası +n olur (+n ayrı tıklanmaz, hücre tıklaması sayılır).',
2367
2248
  defaultDate: "Açılış tarihi (yyyy-MM-dd; katalog varsayılanı örnek veriyle aynı ay olan '2026-08-01'). Gün korunur: hafta/gün/ajanda o günden açılır. Değiştikçe takvim oraya gider; boşsa bugün. 'bugün' için sabit tarih YAZMAYIN, boş bırakın; ifadeyle bağlanacaksa code prop'u '{{ }}' içinde yazılır: { type: 'code', ref: \"{{ new Date().toISOString().slice(0, 10) }}\" } — parantezsiz ifade metin olarak gelir (PAGE-032 reddeder).",
@@ -2369,9 +2250,7 @@ export const componentKnowledge = {
2369
2250
  agendaDays: 'Ajanda listesinin gün sayısı (varsayılan 14); boş günler listelenmez, oklar haftalık kayar. Panelde yalnız ajandaya ulaşılabiliyorsa görünür (defaultView agenda ya da showViewSwitcher açık).',
2370
2251
  isEditable: 'Sürükleyerek taşıma + hafta/gün kenarından boyutlandırma; ikisi de eventMove.',
2371
2252
  isCreatable: 'Tıklama ve sürükleyerek aralık seçimiyle eventCreate; açıkken ay görünümünde dateClick YAYILMAZ.',
2372
- startHour: 'Hafta/gün görünümünün ilk saati (0–23, varsayılan 8); endHour (1–24, varsayılan 18) en az startHour+1 olacak biçimde kırpılır.',
2373
- locale: "tr | en | boş (uygulama dili). Etiketler ve tarih adları tr/en/ar için yerelleşir; başka dil kodu (de, fr…) İngilizce metinle çalışır, hafta başı Pazartesi kalır.",
2374
- style: "Kök (CSS özellikleri doğrudan style'da) takvim kabıdır: backgroundColor · padding · border · borderRadius · color · fontFamily · fontSize içeri MİRAS iner (parçaların boyutu köke göre orantılıdır: kök 20px ise çip ≈ 15.8px; tek parçayı değiştirmek için ilgili parçaya yaz); maxHeight kökü kırpar ve ızgara İÇİNDE kayar. Parçalar: &__header · &__title · &__nav · &__views · &__view-button · &__nav-button · &__weekdays · &__weekday · &__grid · &__day · &__day-number · &__chips · &__chip · &__more · &__timegrid · &__timegrid-header · &__timegrid-day · &__allday · &__allday-cell · &__gutter · &__timegrid-body · &__hours · &__hour-label · &__day-column · &__slot · &__block · &__resize · &__agenda · &__agenda-group · &__agenda-day · &__agenda-row · &__agenda-time · &__agenda-title · &__agenda-empty · &__loader. Durumlar iç içe yazılır: '&__chip': { '&:hover': {…}, '&:focus-visible': {…} }, aktif görünüm düğmesi '&__view-button[aria-selected=\"true\"]', bugünün hücresi '&__day--today' ya da gün numarası '&__day-number[aria-current=\"date\"]'. Etkinlik rengi --chip-color değişkenidir: color-mix(in srgb, var(--chip-color) 20%, #fff) yazılabilir. @media kuralı iç parçaya tek '&' ile bağlanmaz — '@media (max-width: 500px)': { '&&': { '& &__title': {…} } } biçiminde yaz. Parça seçicileri 2026-10-01'e kadar yalnız &__header için çalışıyordu; eski notlar '& .ng-eventcalendar__chip' yazıyorsa o biçim de çalışır ama gereksizdir."
2253
+ startHour: 'Hafta/gün görünümünün ilk saati (0–23, varsayılan 8); endHour (1–24, varsayılan 18) en az startHour+1 olacak biçimde kırpılır.'
2375
2254
  }
2376
2255
  },
2377
2256
  importwizard: {
@@ -2386,21 +2265,12 @@ export const componentKnowledge = {
2386
2265
  "Ayrıştırma yalnız UTF-8'dir (encoding seçeneği yok); BOM soyulur, tırnak/çift-tırnak kuralları ve tırnak içi ayraç/satır sonu desteklenir. delimiter 'auto' ilk satırdan tahmin eder; tamamen boş satırlar atılır, ilk kalan satır başlıktır.",
2387
2266
  "Geri düğmesi durumu KORUR (parsed/mapping silinmez); ✕ düğmesi (cancel olayı) her şeyi sıfırlar — rows/errors/fileName/total/currentStep düğümde de boşaltılır.",
2388
2267
  "change olayı her adım değişiminde yayılır (dosya okundu → 1, önizleme → 2, geri → 1/0); iptal change yaymaz, cancel yayar.",
2389
- "Değerler her zaman STRING'dir — sayı/tarih dönüşümü akışta yapılır. total temiz satır + hata KAYDI sayısıdır: iki zorunlu alanı boş tek satır total'i iki artırır.",
2390
- "Reddedilen dosya (tür, boyut, boş dosya, yalnız başlıklı dosya, okunamayan xlsx) hiçbir olay yaymaz ve adımı, önceki dosya adını DEĞİŞTİRMEZ: neden yalnız bileşenin içinde drop alanının altındaki uyarıdır (role=alert). Sayfa akışı reddi göremez; boş dosya ('Dosya boş') ve yalnız başlıklı dosya ('başlıktan sonra veri satırı yok') artık ayrı iletiyle reddedilir, eskiden '0 satır' diye eşlemeye geçiyordu. Ayrıştırma yalnız UTF-8'dir: windows-1254 dosyada okunan metinde yedek karakter (U+FFFD) kalır; kolon eşleme adımında engellemeyen bir uyarı çıkar ('Dosya UTF-8 değil gibi görünüyor') ve içe aktarma yine yapılabilir — harfleri düzeltmek için dosyayı UTF-8 kaydedip yeniden yüklemek gerekir.",
2391
- "Hepsi hatalı dosyada (temiz satır 0) İçe aktar (0) ETKİN kalır: complete rows: [] ve dolu errors ile yayılır (hatalı satırlar akışa ulaşır; akış boş rows'u döngüde 0 kez işler). Hem temiz hem hatasız satır yoksa (başlıksız/boş dosya zaten reddedilir) düğme kilitlidir.",
2392
- "complete sonrası sihirbaz varsayılan olarak 3. adımda kalır ve İçe aktar etkin durur (aynı dosya ikinci kez aktarılabilir); currentStep salt okunurdur. resetAfterComplete: true ise complete yayıldıktan sonra sihirbaz ilk adıma döner: rows/errors/total/fileName çıktıları düğümde KALIR (akış okumaya devam eder), cancel yayılmaz, ama change { currentStep: 0, fileName: tamamlanan dosya, rowCount: 0 } yayılır (currentStep düğümde bayat kalmasın). Akış sürerken yine isDisabled (ya da isLoading) ile sar, bitince kullanıcıya sonucu ayrı bir metinle göster.",
2393
- "Geri ile dosya adımına dönünce ayrıştırılmış dosya KAYBOLMAZ ve artık görünür: bırakma alanının üstünde 'dosya adı — N satır' satırı ve 'Bu dosyayla devam et' düğmesi çıkar (eşlemeye döner, eşleme korunur, change currentStep 1 yayılır). Yeni geçerli dosya bırakılırsa onun yerine geçer; reddedilen dosya satırı bozmaz.",
2394
- "Önizleme tablosu yalnız ilk 10 temiz satırı gösterir (10'dan fazlaysa 'İlk 10 satır gösteriliyor' notu çıkar) ve hata listesi ilk 20 satırı ('… +N' ile); complete yükünde tam listeler vardır. errors[].message makine metnidir (code ile aynı: 'required' ya da 'maxRows (N)') — kullanıcıya okunur metin göstermek için code'dan türet; rowIndex dosya satır numarasıdır (başlık 1, ilk veri satırı 2).",
2395
- "Metin prop'larında (uploadText, mapText, previewText, importText, backText) {{ }} yalnız code tipinde çözülür; statik değerde ham yazılır. previewText hem 3. adım başlığıdır hem Önizleme düğmesinin metni, mapText 2. adım başlığı, uploadText bırakma alanı metni (1. adım başlığı da dil sözlüğünden gelir). Boş bırakılırsa metinler uygulama diline göre tr/en/ar çizilir.",
2396
- "Erişilebilirlik: her eşleme kutusunun adı hedef alanın etiketidir, ✕ düğmesi 'İçe aktarmayı iptal et' adını taşır, aktif adım aria-current='step' taşır, uyarılar role=alert/status ile duyurulur, isLoading kökte aria-busy yazar ve adım değişince odak yeni adımın ilk kullanılabilir öğesine gider. isDisabled görünümü yalnız soluklaşmadır (bırakma alanı 0.6, düğme ve kutular 0.5; ekran okuyucuya aria-disabled ve pasif öğeler)."
2397
- ],
2398
- propNotes: {
2399
- style: "Kök (CSS özellikleri doğrudan style'da) sihirbaz kabıdır: backgroundColor · padding · border · borderRadius · boxShadow · gap · maxHeight (kökü kırpar, gövde İÇİNDE kayar) · fontSize · fontFamily · color. fontSize ve color içerideki metinlere İNER (adım başlıkları, dosya satırı, eşleme ve önizleme tabloları, uyarı, hata listesi kökün boyutuna göre orantılıdır; ikincil metin kök renginin %75'idir); düğmeler ve eşleme kutuları kendi yüzeyini taşır, rengi inmez. Şemada bildirilen altı parça: &__steps (adım şeridi) · &__drop (bırakma alanı, yalnız 1. adım) · &__mapping (eşleme tablosu) · &__preview (önizleme kabı) · &__errors (hata listesi) · &__button (Geri, ✕, Önizleme, İçe aktar). Geri kalan parçalar için iç içe SINIF seçicisi yaz — '&__step-marker' gibi yazım kabul edilir ama ETKİSİZDİR: '& .ng-importwizard__step' (adım öğesi) · '& .ng-importwizard__step--active' (aktif adım; aria-current seçicisi de çalışır: '& .ng-importwizard__step[aria-current=\"step\"]') · '& .ng-importwizard__step--done' · '& .ng-importwizard__step-marker' · '& .ng-importwizard__file' (dosya/sayı satırı) · '& .ng-importwizard__note' (önizleme notu) · '& .ng-importwizard__resume' (geri dönünce yüklü dosya satırı) · '& .ng-importwizard__warning' · '& .ng-importwizard__req' (zorunlu yıldızı) · '& .ng-importwizard__error-count' · '& .ng-importwizard__nav' (düğme satırı) · '& .ng-importwizard__body'. Birincil düğme: '&__button.ng-importwizard__button--primary'. Durumlar: '&__button': { '&:hover': {…}, '&:disabled': {…}, '&:focus-visible': {…} }, '&__drop:focus-visible'. @media kuralı iç parçaya tek '&' ile bağlanmaz — '@media (max-width: 480px)': { '&&': { '&__steps': {…} } } biçiminde yaz. Koyu zeminde kontrast için sabit renkli '& .ng-importwizard__req' ve '& .ng-importwizard__error-count' ayrıca yazılır; $preset anahtarı kabul edilir ama etkisizdir.",
2400
- targetFields: '[{ label, field, required }] — hedef şema; field boş satırlar ve TEKRARLI field adının ikinci satırı elenir, otomatik eşleme label/field üzerinden yürür. MCP ile düğüm eklerken HER ZAMAN yaz: varsayılan dört alan yalnız panelden bırakınca kopyalanır; yazılmayan ya da boş dizi olan düğmede eşleme tablosu boştur, Önizleme kilitli kalır ve "Hedef alan tanımlı değil" uyarısı çıkar.',
2268
+ "Değerler her zaman STRING'dir — sayı/tarih dönüşümü akışta yapılır. total temiz satır + hata KAYDI sayısıdır: iki zorunlu alanı boş tek satır total'i iki artırır."
2269
+ ],
2270
+ propNotes: {
2271
+ targetFields: '[{ label, field, required }] — hedef şema; field boş satırlar ve TEKRARLI field adının ikinci satırı elenir, otomatik eşleme label/field üzerinden yürür.',
2401
2272
  maxRows: '0 = sınırsız; aşan TEMİZ satırlar hata kaydına dönüşür.',
2402
- maxFileSize: 'MB cinsinden dosya sınırı; 0 = sınırsız; kesirli değer geçerlidir (0.5 = yarım MB, eskiden 0 gibi sınırsız sayılıyordu). Aşan dosya hiç okunmaz, uyarı çizilir.',
2403
- resetAfterComplete: "Varsayılan kapalı. Açıkken complete yayıldıktan sonra sihirbaz ilk adıma döner (rows/errors/total/fileName düğümde KALIR, cancel yayılmaz, change { currentStep: 0, … } yayılır). Kayıtlı sayfaların davranışı kapalıyken değişmez.",
2273
+ maxFileSize: 'MB cinsinden dosya sınırı; 0 = sınırsız. Aşan dosya hiç okunmaz, uyarı çizilir.',
2404
2274
  isDisabled: 'Dosya seçimi, sürükle-bırak, eşleme kutuları ve bütün düğmeler kilitlenir; sihirbaz bulunduğu adımda durur.',
2405
2275
  isLoading: "Gövdeyi soluklaştırır ama düğmeleri kilitlemez; complete akışı sürerken setter ile true yaz. Akış boyunca tıklamayı da engellemek için isDisabled kullan.",
2406
2276
  currentStep: 'Salt OKUNUR çıktı (0 dosya, 1 eşleme, 2 önizleme); change ve cancel geri yazar, yazmak sihirbazı taşımaz.',
@@ -2414,32 +2284,27 @@ export const componentKnowledge = {
2414
2284
  summary: 'Satırları durum kolonlarında sürüklenebilir kart olarak dizen pano; taşıma (cardMove), ekleme isteği (cardAdd) ve silme isteği (cardRemove) akışa bildirilir, kalıcılık akışın işidir.',
2415
2285
  behavior: [
2416
2286
  "cardMove/cardClick/cardAdd/cardRemove yükü BİLİNÇLİ olarak yalnız params ile gider (self'e yazılsa id/from/to çöp prop olur ve tetiklenen render iyimser katmanı aynı karede silerdi): akışta event.data.id / .row / .from / .to / .column ile okunur.",
2417
- "Taşıma iyimserdir: komponent rows'u DEĞİŞTİRMEZ; cardMove akışı yeni kolonu uca yazıp rows'u tazeler — (id:kolon) imzası değişince iyimser katman sıfırlanır. Kalıcılaştırılmayan taşıma, veri değiştiği anda ya da isLoading kapandığı anda eski kolonuna döner.",
2287
+ "Taşıma iyimserdir: komponent rows'u DEĞİŞTİRMEZ; cardMove akışı yeni kolonu uca yazıp rows'u tazeler — (id:kolon) imzası değişince iyimser katman sıfırlanır. Kalıcılaştırılmayan taşıma, veri değiştiği anda eski kolonuna döner.",
2288
+ "BAĞLI VERİ (2026-09-17, f-31): rows bağlıysa (roller title, subtitle, column, color, id) cardMove'da runtime kolon alanını kendisi yazar: tek update { <column rolü alanı>: to, <birincil anahtar> } — tanımda edit.update açık, kolon alanı editable'da ve describe write.update true ise; akış yazılmaz. Yazılamayan ya da reddedilen taşımada liste yeniden okunur ve kart kayıtlı kolonuna döner. id rolü başka alana eşlense de satırın birincil anahtarı ezilmez. columns ikinci yuva (value, label): aynı ya da başka tabloya ayrı bağlanır; ikincil okuma kanbanın isLoading durumuna dokunmaz.",
2418
2289
  "Ekleme ve silme İYİMSER DEĞİLDİR: isAddable kolon altına '+ addText' düğmesi koyar ve yalnız cardAdd { column } yayar; isRemovable karta × düğmesi koyar ve yalnız cardRemove { id, row, column } yayar (cardClick yaymaz). Kart ancak akış satırı yazıp/silip rows'u tazeleyince eklenir/kaybolur — silmeden önce onay sormak akışın elindedir.",
2419
- "Kolon eşleşmesi columns[].value ile TAM string eşitliğidir; sayı value metne çevrilir (2 ile '2' eşleşir). Eşleşmeyen satır ilk kolona değil 'atanmamış' kuyruğuna düşer (kesikli kenarlık; yalnız doluyken çizilir, başlığı unassignedText, boşsa uygulama diline göre 'Atanmamış' / 'Unassigned' / 'غير مُسنَد', ekleme düğmesi yok). Aynı value'lu ikinci kolon ve value'su boş kolon çizilmez.",
2290
+ "Kolon eşleşmesi columns[].value ile TAM string eşitliğidir; sayı value metne çevrilir (2 ile '2' eşleşir). Eşleşmeyen satır ilk kolona değil 'atanmamış' kuyruğuna düşer (kesikli kenarlık; yalnız doluyken çizilir, başlığı unassignedText, ekleme düğmesi yok). Aynı value'lu ikinci kolon ve value'su boş kolon çizilmez.",
2420
2291
  "emptyText iki yerde çizilir: kartı olmayan her kolonun içinde (yalnız doluysa) ve hiç kolon yokken panonun yerinde (boşsa '—').",
2421
2292
  "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.",
2422
2293
  "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.",
2423
- "Kart iki kiptedir: cardFields BOŞSA sabit şablon — titleField + subtitleField; cardFields DOLUYSA her satır bir alanı (iç içe yol) etiketiyle title/subtitle/meta/badge yuvasına ve text/number/date/datetime/money/pertance biçimine yerleştirir (biçim table/detailview ile ortak, dili locale ya da boşsa uygulama dili). Baş harf rozeti (showAvatar, varsayılan açık) İKİ kipte de çizilir ve harfini her zaman titleField'dan alır — cardFields kullanıp title alanı olmayan satırlarda rozet '?' olur: titleField'ı eşle ya da showAvatar:false yaz. Resim avatarı ve serbest component şablonu yoktur. Renk karta BAŞLANGIÇ kenarı şeridi (LTR'de sol, RTL'de sağ; atanmamış kuyruktaki kartlar dahil), kolona üst şerit olarak iner (ham CSS, semantik ad ya da token; tanınmayan değer sessizce birincil renge düşer). Baş harf rozeti ilk KARAKTERİ (emoji dahil) etkin dilin büyük harf kuralıyla yazar (tr: i→İ; diğer diller: i→I).",
2424
- "Erişilebilirlik: her kolon role='group' ve aria-label=kolon etiketi taşır (atanmamış kuyruk: unassignedText, boşsa dile göre 'Atanmamış'). Odaklanan öğe kartın İÇİNDEKİ gövdedir (role='button', tabindex=0; kartın kendisi odaklanmaz) ve × düğmesi gövdenin KARDEŞİdir — iç içe etkileşimli öğe yoktur; Enter ve Space cardClick yayar, odakta 2px vurgu halkası çizilir. Avatar harfi ekran okuyucudan gizlidir. ekleme düğmesinin metni (addText boşsa) ile × düğmesinin aria-label/title'ı uygulama diline (locale boşsa) göre tr/en/ar çizilir.",
2425
- "Klavyeyle taşıma (2026-10-01): odaktaki kartta Shift + Sol/Sağ ok kartı bitişik kolona taşır ve sürüklemeyle AYNI cardMove { id, row, from, to } yükünü yayar (iyimser katman da aynı). Ok GÖRSEL yöndür: sağdan sola yazılan panoda Shift+Sağ bir ÖNCEKİ kolona gider. Atanmamış kuyruk kolonların SONUNDA çizilir: kuyruktaki kart yalnız geri adımla (LTR'de Shift+Sol) SON kolona alınır, ileri adım yoktur; uçlarda hareket olmaz. Taşıma sonrası odak kartta kalır ve sonuç canlı bölgeye (role='status', aria-live='polite') '<başlık> kartı <kolon> kolonuna taşındı' olarak yazılır (tr/en/ar). Gövde aria-keyshortcuts='Shift+ArrowLeft Shift+ArrowRight' taşır; isDraggable:false ya da isLoading:true iken taşıma ve bu öznitelik YOKTUR. Alt/Ctrl/Meta ile birlikte ok tuşları taşıma sayılmaz.",
2426
- "Uzun metin: kolon başlığı, kart başlığı ve alt başlığı, rozet ve ekleme düğmesi tek satırda ELİPSLE kesilir (başlıkta title tam metni taşır); meta öğeleri, kolon içi emptyText ve atanmamış metni satır kaydırır. Sayaç sağda kalır, uzun etiket onu itmez.",
2427
- "Taşıma KALICILANMAZSA (akış hata verir, yazma reddedilir): iyimser katman iki durumda sıfırlanır — rows'un (id, kolon) imzası değişince ve isLoading true → false dönünce. Kalıcılama akışını isLoading true / false ile sar: yazma başarısız olup aynı veri yeniden okunsa bile (imza değişmez) kart yükleme kapanınca gerçek kolonuna döner; başarılı yazmada kart zaten yeni kolondadır. isLoading kullanmıyorsan geri almanın yolu hata dalında rows'u önce boş diziye, sonra gerçek listeye yazmaktır (iki ardışık yazma imzayı değiştirir). DİKKAT: yükleme bayrağını rows tazelenmeden ÖNCE kapatan bir akış kartı bir an eski kolonunda gösterir.",
2428
- "Sürükleme yerel HTML5 DnD'dir; klavye yolu Shift+ok'tur (yukarı). isLoading:true iken sürükleme, klavyeyle taşıma, kart tıklaması, ekleme ve silme kilitlenir, hiçbir olay yayılmaz; kök aria-busy taşır, kart gövdeleri tabindex -1 + aria-disabled olur (klavye odağına girmez), ekleme düğmesi pasif, × aria-disabled'dır — yükleme bayrağını her dalda false'a döndür.",
2429
- "Kart <elementId>__card-<id>, kolon <elementId>__col-<value> data-element-id'si taşır (id = idField değeri; idField yoksa ya da değeri boşsa id 'card-<sıra>' olur, yani adres '__card-card-<sıra>'; atanmamış kuyruk bölümünün, ekleme ve × düğmelerinin kimliği YOKTUR — onlar için sayfa adresi page_screenshot actions ile verilemez): 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."
2294
+ "Kart iki kiptedir: cardFields BOŞSA sabit şablon — titleField + subtitleField; cardFields DOLUYSA her satır bir alanı (iç içe yol) etiketiyle title/subtitle/meta/badge yuvasına ve text/number/date/datetime/money/pertance biçimine yerleştirir (biçim table/detailview ile ortak, dili locale ya da boşsa uygulama dili). Baş harf rozeti (showAvatar, varsayılan açık) İKİ kipte de çizilir ve harfini her zaman titleField'dan alır — cardFields kullanıp title alanı olmayan satırlarda rozet '?' olur: titleField'ı eşle ya da showAvatar:false yaz. Resim avatarı ve serbest component şablonu yoktur. Renk karta sol şerit (atanmamış kuyruktaki kartlar dahil), kolona üst şerit olarak iner (ham CSS ya da semantik ad).",
2295
+ "Sürükleme yerel HTML5 DnD'dir; klavyeyle taşıma yolu yoktur (Enter yalnız cardClick yayar). isLoading:true iken sürükleme, kart tıklaması, ekleme ve silme kilitlenir, hiçbir olay yayılmaz — yükleme bayrağını her dalda false'a döndür.",
2296
+ "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."
2430
2297
  ],
2431
2298
  propNotes: {
2432
2299
  rows: 'Kart satırları; alan adları columnField/titleField/subtitleField/idField/colorField ile çözülür (boşsa column/title/subtitle/id/color; nokta ayraçlı iç içe yol çalışır).',
2433
2300
  columns: "[{ label, value, color, wipLimit }] — value boş ya da yinelenen kolonlar elenir (ilki kalır); value satır eşleşmesinin anahtarıdır, sayı olabilir.",
2434
- cardFields: "[{ field, label, slot: title|subtitle|meta|badge, format: text|number|date|datetime|money|pertance, currency }] — boş dizi sabit kartı korur; alanı ya da değeri boş satır atlanır, slot'suz alan meta'ya düşer. currency yalnız money biçiminde okunur: ISO 4217 kodu ('USD', 'EUR'; büyük/küçük harf fark etmez); boş ya da geçersiz değer TRY'ye düşer (₺, eski davranış). Simgenin yeri ve ayıraçlar locale'e göre kalır ($1,250.00 en · €1.250,00 tr).",
2435
- unassignedText: "Atanmamış kuyruğunun başlığı; boşsa uygulama diline göre 'Atanmamış' / 'Unassigned' / 'غير مُسنَد' (eskiden '?' idi). Kuyruk yalnız bilinmeyen kolonlu kart varken çizilir.",
2301
+ cardFields: "[{ field, label, slot: title|subtitle|meta|badge, format: text|number|date|datetime|money|pertance }] — boş dizi sabit kartı korur; alanı ya da değeri boş satır atlanır, slot'suz alan meta'ya düşer.",
2436
2302
  emptyText: "Kartsız kolonun içindeki metin (boşsa hiçbir şey) ve kolon yokken pano metni (boşsa '—').",
2437
- addText: "Ekleme düğmesinin metni ('+ ' önekiyle); boşsa uygulama diline göre 'Kart ekle' / 'Add card' / 'إضافة بطاقة'. Yalnız isAddable açıkken panelde görünür.",
2303
+ addText: "Ekleme düğmesinin metni ('+ ' önekiyle); boşsa 'Add card'. Yalnız isAddable açıkken panelde görünür.",
2438
2304
  isAddable: 'Varsayılan kapalı; açınca her kolonun altında ekleme düğmesi, basınca cardAdd { column }.',
2439
- isRemovable: 'Varsayılan kapalı; açınca her kartın başlangıç-karşıtı üst köşesinde (LTR sağ, RTL sol) × düğmesi, basınca cardRemove { id, row, column }. Erişilebilir adı uygulama diline göre yazılır; isLoading iken pasiftir.',
2305
+ isRemovable: 'Varsayılan kapalı; açınca her kartın sağ üstünde × düğmesi, basınca cardRemove { id, row, column }.',
2440
2306
  isDraggable: 'Varsayılan açık; kapatınca taşıma kapanır (kart tıklaması, ekleme ve silme bağımsızdır).',
2441
- locale: "cardFields'in money/date/number biçim dili, baş harf rozetinin büyük harf kuralı ve varsayılan ekleme/silme metinleri (tr/en/ar); boşsa uygulama dili. Para birimi locale'den değil cardFields[].currency'den gelir (boşsa ₺).",
2442
- style: "Kök (CSS özellikleri doğrudan style'da) pano kabıdır: backgroundColor · padding · border · color · fontFamily · fontSize kartlara MİRAS iner (parçaların boyutu köke göre orantılıdır: kök 20px ise başlık ≈ 18.6px; tek parçayı değiştirmek için &__card-title/&__card-subtitle/&__card-meta'ya yaz). maxHeight kökü kırpar ve kartlar kolon İÇİNDE kayar; gap kökte etkisizdir, kolonlar arası boşluk '&__board' { gap }. Parçalar: &__board · &__column · &__column-header · &__column-title · &__count · &__cards · &__card · &__avatar · &__card-text · &__card-title · &__card-subtitle · &__card-meta · &__card-meta-item · &__card-meta-label · &__card-main (odaklanan gövde: role=button) · &__card-badges · &__badge · &__add · &__remove · &__column-empty · &__empty (kolon yokken pano metni) · &__loader. Durumlar iç içe yazılır: '&__card': { '&:hover': {…}, '&[draggable=\"true\"]': {…} }, odak halkası '&__card-main': { '&:focus-visible': {…}, '&[aria-disabled=\"true\"]': {…} } (kartın kendisi odaklanmaz, :focus-visible orada eşleşmez). Kolon ve kart rengi --column-color (kolon ve başlığında) ve --card-color (kartta) değişkenleridir. Kolon varsayılanı flex 1 0 200px, genişlik 200–320px: dikey şeritler için '&__board' { flexDirection: 'column' } ve '&__column' { maxWidth: 'none' }. Parça seçicileri 2026-10-01'e kadar HİÇBİR elemana bağlanmıyordu; eski notlar '& .ng-kanban__card' yazıyorsa o biçim de çalışır ama gereksizdir."
2307
+ locale: "cardFields'in money/date biçim dili; boşsa uygulama dili."
2443
2308
  }
2444
2309
  },
2445
2310
  signature: {
@@ -2470,27 +2335,238 @@ export const componentKnowledge = {
2470
2335
  "Adım tanımındaki canProceed bağı çalışma anında undefined çözülür (frontend CQ-117) — kapıyı ÜST DÜZEY canProceed prop'una bağla, adım tanımına statik değer dışında bir şey yazma.",
2471
2336
  "stepChange {currentStep, previous} taşır ve currentStep self'e yazılır; validationFail YALNIZ İleri düğmesinden yayılır (engellenen başlık tıklaması sessiz kalır); finish son adımda kapı açıkken yayılır ve adımı DEĞİŞTİRMEZ.",
2472
2337
  "Başlık tıklaması allowClickNavigation'a bağlıdır: none | backward (varsayılan; yalnız geri) | all. isLinear:true iken ileri sıçramak aradaki HER görünür adımın optional olmasını ister.",
2473
- "Akıştan adım sürme: setter ile currentStep yaz — değer aralığa kırpılır, gizli bir adımı gösteriyorsa sonraki (yoksa önceki) görünür adım açılır; bu çözüm geri yazılmaz ve olay yaymaz. DİKKAT: gizli adım varken 'currentStep - 1' yazmak takılır (gizli adıma düşen değer yeniden ileri, bulunduğun adıma çözülür) — akıştan geri/ileri giderken hedefi görünür bir adımın indeksi olarak kendin hesapla. Görünür adım hiç yoksa başlık, düğmeler VE içerik çizilmez. Hatalı/başarısız adım görseli yoktur; engellenmişken İleri düğmesi soluk zeminli ve ikincil metinli çizilir, aria-disabled=\"true\" taşır (tıklanabilir kalır: tıklama validationFail yayar; Playwright gibi 'enabled' bekleyen araçlar aria-disabled düğmeye click'te zaman aşımına düşer — force:true ver). Tamamlanma işareti (✓ ve ekran okuyucuya 'Tamamlandı') aktif adımdan ÖNCEKİ her görünür adımdadır: ileri sıçramada atlanan optional adım da ✓ alır (✓ = 'geçildi', 'ziyaret edildi' değil).",
2338
+ "Akıştan adım sürme: setter ile currentStep yaz — değer aralığa kırpılır, gizli bir adımı gösteriyorsa sonraki (yoksa önceki) görünür adım açılır; bu çözüm geri yazılmaz ve olay yaymaz. DİKKAT: gizli adım varken 'currentStep - 1' yazmak takılır (gizli adıma düşen değer yeniden ileri, bulunduğun adıma çözülür) — akıştan geri/ileri giderken hedefi görünür bir adımın indeksi olarak kendin hesapla. Görünür adım hiç yoksa başlık, düğmeler VE içerik çizilmez. Hatalı/başarısız adım görseli yoktur; tek gösterge engellenmişken soluklaşan İleri düğmesidir.",
2474
2339
  "Adım i'nin içeriği children[i]'dir (type:'view'); steps öğe sayısı ile view sayısı eşit olmalı. Adım içeriği adımdan çıkınca SÖKÜLÜR ve dönünce yeniden kurulur: içindeki component'lerin mount akışları HER girişte yeniden koşar — Geri ile dönülen adımda mount'ta değer yazan bir akış kullanıcının girdiğini EZER. Değerini makineye geri yazan girdiler değeri korur; kaydırma, tablo sayfası gibi yerel durum kaybolur. Adım girdilerini mount'ta doldurma; ilk değeri stepper'ın mount'unda ya da önceki adımın İleri akışında yaz.",
2475
2340
  "Koşullu adım: steps[].isHidden:true adımı başlıkta çizmez, numaralandırmaz ve İleri/Geri/başlık gezinmesinde atlar (İleri son görünür adımda Bitir olur). Öğe alanlarında {{ }} çözülmediği için (CQ-117) koşula bağlamak için akışta setter ile steps dizisinin TAMAMINI yeniden yaz.",
2476
- "isLoading:true iken İleri/Geri/Bitir ve başlık tıklamaları devre dışıdır (kaydetme akışında çift finish önlenir) — gönderim akışının başında isLoading'i true, sonunda (hata dalında da) false yaz; true kalırsa sihirbaz kilitli kalır. steps dizi değilse (null yazan akış) başlık ve düğmeler çizilmez, sayfa düşmez. Yüklenirken kök aria-busy=\"true\" taşır ve adım içeriği inert'tir: tıklanmaz VE Tab ile girdilerine inilmez.",
2477
- "Varsayılan metinler dile göre gelir: previousText/nextText/finishText/optionalText BOŞ bırakılırsa ekran diline göre sözlükten (tr: Geri · İleri · Bitir · İsteğe bağlı; en: Back · Next · Finish · Optional; ar: السابق · التالي · إنهاء · اختياري) çizilir — metni her dil için elle yazma. Dolu metin her zaman kazanır.",
2478
- "showNavigation:false iken Geri/İleri/Bitir hiç çizilmez; Bitir de yoktur, yani finish olayı kullanıcı arayüzünden TETİKLENEMEZ — kendi düğmenle akışı sür ya da gezinmeyi açık bırak. Başlık tıklaması allowClickNavigation'a göre sürer. allowClickNavigation'ın tanınmayan değeri backward sayılır.",
2479
- "Yerleşim: çok adımda ya da dar ekranda başlık şeridi ezilmez, kendi içinde yatay kayar ve açık adım şeritte ortalanır (sayfa taşmaz). Dikey yönde içerik başlıkların ALTINDA durur; başlıklar solda, içerik sağda isteniyorsa kök style'a display:grid + gridTemplateColumns yaz ve '&__list' ile '&__panel'e gridColumn/gridRow ver ('&__nav' içerik sütununa).",
2341
+ "isLoading:true iken İleri/Geri/Bitir ve başlık tıklamaları devre dışıdır (kaydetme akışında çift finish önlenir) — gönderim akışının başında isLoading'i true, sonunda (hata dalında da) false yaz; true kalırsa sihirbaz kilitli kalır. steps dizi değilse (null yazan akış) başlık ve düğmeler çizilmez, sayfa düşmez.",
2480
2342
  "Form validations sistemiyle entegrasyonu YOKTUR (kapı yalnız çözülen ifade değeridir). Studio kanvasında adımlar arası geçiş sağ paneldeki Steps listesinin yuvarlak işaretiyle ya da Element Tree'den yapılır (satırın kendisine tıklamak düzenleme çekmecesini açar)."
2481
2343
  ],
2482
2344
  propNotes: {
2483
2345
  surfaceStyle: NODE_SURFACE_NOTE,
2484
2346
  steps: "[{ title, description, icon, optional, isHidden, canProceed }] — tabs'ın views deseni; her adım children'da AYNI SIRADA kendi view'ını taşır. canProceed yalnız statik 'true'/'false'; bağlanabilir kapı üst düzey canProceed.",
2485
- optionalText: "optional:true adımın başlığındaki rozet metni; boşsa ekran diline göre sözlük metni (tr 'İsteğe bağlı', en 'Optional', ar 'اختياري').",
2486
- previousText: "Geri düğmesinin metni; boşsa ekran diline göre (Geri · Back · السابق). Uzun metin satır kırar, düğme satırı taşırmaz.",
2487
- nextText: "İleri düğmesinin metni; boşsa ekran diline göre (İleri · Next · التالي). Son adımda finishText çizilir.",
2488
- finishText: "Son adımdaki düğmenin metni; boşsa ekran diline göre (Bitir · Finish · إنهاء).",
2489
- allowClickNavigation: "none | backward | all; tanınmayan değer backward sayılır. all + isLinear:true iken ileri sıçrama yalnız aradaki her görünür adım optional ve kapıları açıksa; isLinear:false her adımı serbest bırakır.",
2490
- style: "Kök CSS özellikleri (fontFamily, fontSize, color, backgroundColor, padding, border, borderRadius…) çalışır; fontFamily ve fontSize başlık, açıklama, rozet, marker ve düğmelere İNER (parçaların boyutu köke göre orantılıdır: kök 20px ise açıklama ≈ 17px), color başlığa ve Geri düğmesine iner — açıklama ve rozet ikincil renkte kalır (tek parçayı boyamak için &__description / &__optional). Kökte maxHeight TEK BAŞINA kırpmaz (CSS gereği içerik taşar): kaydırmak için overflowY: auto da yaz. gap kökte etkisiz; başlıklar arası boşluk '&__list' { gap }. PARÇA SÖZLÜĞÜ (&__parça): list (başlık şeridi) · step (her adımın <li>'si) · head (adım düğmesi) · marker (numara/ikon dairesi) · text (başlık+açıklama bloğu) · title · optional (isteğe bağlı rozeti) · description · connector (adımlar arası çizgi) · panel (içerik kabı) · slot (içerik) · nav (Geri/İleri satırı) · nav-button (iki düğme; yalnız biri için '&__nav-button--previous' / '&__nav-button--next'). DURUM HEDEFLERİ: aktif/tamamlanan adım için '&__step--active' ve '&__step--done' (ya da '&__step[data-state=\"active\" | \"done\" | \"upcoming\"]', '[aria-current=\"step\"]'); '&__head:hover', '&__head:focus-visible', '&__head:disabled', '&__nav-button:hover' çalışır; engelli İleri için '&__nav-button[aria-disabled=\"true\"]'. İç içe seçici ('& .ng-stepper__marker'), '::before/::after' ve '@media' çalışır. Odak halkası varsayılan 2px (koyuda da görünür); değiştirirsen kontrastı ≥ 3:1 tut.",
2347
+ optionalText: "optional:true adımın başlığındaki rozet metni; boşsa 'optional' (Türkçe arayüzde ör. 'İsteğe bağlı' yaz).",
2491
2348
  canProceed: "Aktif adımın kapısı; ifadeye bağlanır. Yalnız false/'false' engeller.",
2492
2349
  currentStep: "0 tabanlı aktif adım; setter hedefi, aralık dışı değer kırpılır. Studio'dan yeni bırakılan düğümde 0 yerine null KAYDEDİLİR (frontend CQ-091, ortak mapper falsy varsayılanı düşürüyor): bileşen null'ı ilk adım sayar ama {{ <stepper>.currentStep }} / self.currentStep kullanıcı ilk kez adım değiştirene kadar null okur — ifadede {{ <stepper>.currentStep || 0 }} yaz. Şemayı kendin yazıyorsan currentStep: 0'ı açıkça ver."
2493
2350
  }
2351
+ },
2352
+ 'task-inbox': {
2353
+ summary: 'Süreç görev kutusu: sekmeler (bana atanan · grubumun · vekâleten · başlattıklarım · tamamladıklarım · planlı), SLA renk çipi, satır/toplu üstlenme; veriyi KENDİSİ çekmez, rows akıştan (process.task.list sistem ucu, microservice adımı) gelir.',
2354
+ guide: 'bpm',
2355
+ behavior: [
2356
+ "Veri yolu: mount/tabChange akışı `process.task.list` sistem ucunu ({ tab, applicationSlug }) microservice adımıyla çağırır ve Steps.<adım>.data'yı rows'a yazar; sekme sayacı dizinin uzunluğudur (sistem ucu totalData döndürmez). Komponent uç çağırmaz.",
2357
+ "tabChange setter'dır: activeTab self'e yazılır; akış event.data.tab ile yeni sekmeyi okur ve rows'u tazeler. Seçim sekme değişince sıfırlanır.",
2358
+ "SLA çipi dueAt varsa çizilir: createdAt→dueAt penceresinin %50'sine kadar yeşil, %90'a kadar sarı, sonrası kırmızı; süre geçince metin 'Süresi geçti' olur. createdAt yoksa yalnız geçti/geçmedi ayrımı yapılır.",
2359
+ "Üstlen düğmesi ve toplu seçim YALNIZ group sekmesinde, isClaimable !== false ve state open olan satırlarda görünür; claim yükünde version gider — akış process.task.claim { id, version } çağırır, 409'da (TaskAlreadyClaimed) rows'u tazeler.",
2360
+ "claim/bulkClaim/taskClick yükü BİLİNÇLİ olarak yalnız params ile gider (self'e yazılmaz): akışta event.data.taskId / .row / .taskIds ile okunur.",
2361
+ "Satırlarda sekme (tab) alanı varsa yalnız aktif sekmenin satırları gösterilir; yoksa bütün rows aktif sekmeye ait sayılır. pageSize ilk N satırı keser (sayfalama yok).",
2362
+ "Sekme başlıkları tabs boşsa uygulama dilinden gelir; tabs doluysa id/label/count aynen kullanılır (sayaçlar akışın işidir, canlı soket sayacı b-24 ile gelir).",
2363
+ "planned sekmesi plannedStart'ı gelmemiş görevleri listeler; satır state planned iken 'Başlangıç: 3 gün sonra' yazar (açılmış görevde plannedStartAt kalsa da yazı çıkmaz). Planlı görev üstlenilemez/tamamlanamaz, eylem listesi boştur; tarihi gelince platform açar.",
2364
+ "scope realm iken satırda applicationName rozeti çizilir (üç uygulamanın görevleri tek listede); akış process.task.list { tab, scope: 'realm' } okur. 'app' kapsamı platformda 'application'dır: applicationId verilmezse akış sayfanın uygulama slug'ını applicationSlug olarak gönderir (machine.context.state.appName) ve kutu o uygulamanın görevleriyle uygulamasız (proje düzeyi) süreçlerin görevlerini gösterir. Realm kutusu yalnız okumadır; eylemler aynı process.task.* uçlarından.",
2365
+ "Sekmeler rol tablist'tir: sağ/sol ok bir sonraki/önceki sekmeyi ister (tabChange) ve odağı o sekmeye taşır; yalnız etkin sekme Tab sırasındadır.",
2366
+ "Doğal dil araması (showSearch:true): kutu 'bu ay geciken satınalmalar' gibi metni search { q } olayıyla yayar; akış process.task.list { tab, q } sonucunu rows'a yazar; sistem ucu appliedFilter DÖNDÜRMEZ — rozetler gerekiyorsa appliedFilter Page.bpm.tasks(tab, { q }) yanıtından okunur. Rozetler platformun anladığı süzgeçtir: süreç (processNames ile adı), termini geçmiş, açılış aralığı (bitiş günü dahil gösterilir), öncelik ≥ N. 'Süzgeci kaldır' clearFilter yayar ve kutuyu boşaltır; tek rozet kaldırılamaz (sunucu yalnız q kabul eder)."
2367
+ ],
2368
+ propNotes: {
2369
+ rows: "[{ id, title, processName, subjectLabel, subjectHref, from, createdAt, dueAt, state, nextStep, isClaimable, version, applicationName?, plannedStartAt?, tab? }] — bpm/tasks satırının düzleştirilmiş hâli (applicationName ← applicationName, plannedStartAt ← plannedStartAt); version claim için gerekir.",
2370
+ activeTab: "mine | group | delegated | started | done | planned; tabChange'in setter hedefi.",
2371
+ tabs: '[{ id, label, count }] — boşsa altı varsayılan sekme uygulama dilinde çizilir.',
2372
+ scope: "app | realm — tabChange yüküyle akışa geçer; realm'de satırda uygulama rozeti çizilir.",
2373
+ timeZone: "IANA saat dilimi (ör. 'Europe/Istanbul') — süzgeç rozetlerindeki açılış aralığı bu dilimde yazılır; boşken tarayıcının dilimi kullanılır. Platform appliedFilter'ın from/to alanlarını UTC gönderir."
2374
+ }
2375
+ },
2376
+ 'task-actions': {
2377
+ summary: "İş nesnesinin açık süreç görevi için karar çubuğu: approval'da Onayla/Reddet, user-task'ta düğümün özel eylemleri ya da Tamamla, izin varsa Bilgi iste ve Yeniden ata. Görev yoksa ya da kapalıysa hiç çizilmez.",
2378
+ guide: 'bpm',
2379
+ behavior: [
2380
+ "task akıştan gelir (process.task.get { id } sonucu); state open/claimed/unassigned dışındaysa (waiting-info dahil) çubuk görünmez. kind 'provide-info' görevde yalnız Bilgi gönder çıkar.",
2381
+ "Eylem düğmesi yorum penceresini açar (showComment:true ya da eylem yorum isterse). reject, request-info, provide-info, reassign ve isCommentRequired:true eylemlerde yorum boşken Gönder kilitlidir; reassign yeni atanan kimliğini de ister.",
2382
+ "action yükü YALNIZ params ile gider: event.data = { action, taskId, version, comment?, payload?, targetUserId? }. Akış eylemi sistem ucuna yönlendirir: claim → process.task.claim, unclaim → process.task.unclaim, request-info → process.task.request-info { question: comment }, provide-info → process.task.provide-info { answer: comment }, reassign → process.task.reassign { targetUserId, reason: comment }, start-assessment → process.task.assessment.start, sign → process.task.sign, diğerleri → process.task.complete { action, payload, version, comment }.",
2383
+ "Hata gösterimi error prop'udur: akış 409/422 sonrası error'a { status, code, message } yazar; 409 ya da TaskAlreadyClaimed her zaman 'başkası üstlendi — görev yenilendi' cümlesiyle çizilir, TaskCommentRequired ve UndoWindowClosed kendi cümleleriyle.",
2384
+ "Özel eylemler actions[] ile verilir ({ id, label, completes, isCommentRequired, tone }); approval görevinde Onayla/Reddet'in ardına eklenir. actions boşken task'a bağlı get() yanıtının customActions'ı ({ id, label: { tr, en }, completes }) etiketiyle kullanılır — genel sayfada akış eşleme yazmaz.",
2385
+ "Görev formu: fields ([{ key, label, type, isRequired }]) ya da boşken get() yanıtının formFields'i (düğüm form.dtoId DTO'sunun alanları) çubuğun üstünde çizilir; tip string/textarea → metin, number/float → sayı, bool → onay kutusu, date/datetime/time → tarih. Zorunlu alan boşken karar veren düğmeler (reject, request-info, reassign, provide-info dışındakiler) kilitlidir; değerler action yükünün payload'una key adıyla (sayılar sayı olarak) girer. Görev kapalıyken form çizilmez.",
2386
+ "İmzalı adım (task.signature ya da get() yanıtındaki signature): tamamlayan eylem 'İmzala' (approval'da 'İmzala ve onayla') olur, Reddet ve completes:false özel eylemler kalır. Pencere anlamı salt okunur gösterir, parola zorunlu, e-posta oturumdaki ilk imza için; yük payload.signature = { meaning, email?, password }. Akış process.task.sign { id, meaning, password, email, fileId, comment, payload (signature dışındaki form), version } çağırır — parola parametre ifadesinde event.data.payload.signature'dan okunur, state'e yazılmaz; imzasız tamamlama 422 SignatureRequired, yanlış parola 401 ReauthenticationRequired.",
2387
+ "Çevrimdışı: bağlantı yokken offline 'disabled' adımda ve imzalı adımda düğmeler kilitlenir ve nedeni yazılır; diğer eylemler Page.bpm.task(id).complete ile kuyruğa alınır ({ queued: true }) ve Page.bpm.offline.sync() ile POST bpm/tasks/sync'e gider. pendingCount (Page.bpm.offline.count()) 'Gönderilecek: N' satırını çizer; çakışma satırları Page.bpm.offline.list() ve resolve(clientActionId, 'retry' | 'discard') ile çözülür.",
2388
+ "Yardımcı (showAssistant:true): 'Özetle' assistantSummary { taskId }, 'Sor' kutusu assistantAsk { taskId, question } yayar; akış Page.bpm.task(taskId).assistant(question?) sonucunu assistant'a yazar (istek sürerken { isLoading: true }, hata { error } — ikisi de panelde görünür). Panel 'AI önerisi' rozeti, özet/yanıt, yalnız çubuğun sunduğu önerilen eylem (düğme adıyla), gerekçe ve adımdaki önceki sonuç sayılarını çizer; KARAR DÜĞMESİ YOKTUR (K-33). 'Gerekçeyi yorum taslağına al' yalnız yorum penceresinin başlangıç metnini doldurur; kararı kullanıcı çubuktan verir.",
2389
+ "Okuma sınavı (assessment prop'u doluyken ya da get() yanıtı assessment kuralı taşırken): yalnız Bilgi iste / Yeniden ata düğmeleri kalır, okuma kanıtı eylemi geçen denemeyi bekler. Sınav YALNIZ görev eyleme açıkken çizilir (state open/claimed/unassigned); kapalı ya da bilgi bekleyen görevde sınav bölümü hiç görünmez. questions boşken 'Sınava başla' action { action: 'start-assessment', taskId } yayar — akış process.task.assessment.start { id } sonucunu assessment'e OLDUĞU GİBİ yazar: cevapsız sorular, passScore (soru sayısına kırpılmış), attempts (adımın izin verdiği hak) ve bu kullanıcının son denemesinin lastScore/isPassed'i sunucudan gelir. Sorular kart olarak çizilir (options doluysa seçenek, boşsa metin), 'Deneme N / M · geçme notu P / T' ve cevap sayacı görünür; tüm sorular cevaplanınca 'Cevapları gönder' action { action: 'submit-assessment', taskId, payload: { answers } } yayar — akış process.task.complete { action, payload } çağırır. YÜKTE version YOKTUR: sınavı açmak görevi üstlenir ve sürümü ilerletir, panelin çizildiği sürüm bayattır. Geçerse görev kapanır; kalırsa hak varsa görev açık kalır ve sonraki başlatma yeni denemeyi verir. Denemeler kullanıcı başına sayılır; sınavı yalnız görevin atandığı kişi açıp gönderebilir (başkası 403)."
2390
+ ],
2391
+ propNotes: {
2392
+ task: "process.task.get sonucu olduğu gibi ({ task, actions, signature, offline }: düğmeler sunucunun actions listesini izler) ya da görev satırı { id, kind: user-task | approval | provide-info, state, version, requestInfo, allowReassign, signature: { meaning, level, reauth }, offline: allowed | disabled }. signature.meaning yoksa diyalog anlam seçtirir; reauth:false ise parola sorulmaz.",
2393
+ pendingCount: "Çevrimdışı kuyrukta bekleyen eylem sayısı (Page.bpm.offline.count()); 0 iken satır çizilmez.",
2394
+ actions: '[{ id, label, completes, isCommentRequired, tone }] — tanımdaki actions[] ile aynı id. Boş bırakılırsa get() yanıtının customActions\'ı kullanılır.',
2395
+ fields: "[{ key, label, type: string | textarea | number | date | datetime | time | bool, isRequired }] — boşsa get() yanıtının formFields'i (DTO alanları: key = slug, label = ad).",
2396
+ error: "{ status, code, message } — akışın son eylem hatası; boşken mesaj çizilmez.",
2397
+ showAssistant: 'Yardımcı paneli; varsayılan false.',
2398
+ assistant: "{ text, suggestedAction, rationale, similarOutcomes: { sonuç: sayı }, isLoading, error } — Page.bpm.task(id).assistant(question?) yanıtı (sunucu isAiSuggestion taşır) ve akışın yükleniyor/hata bayrakları.",
2399
+ assessment: "Okuma sınavı denemesi: null ise sınav yok; {} ise 'Sınava başla'; process.task.assessment.start sonucu { id, number, passScore, questions: [{ id, text, options }], attempts, lastScore, isPassed } olduğu gibi — attempts/lastScore/isPassed SUNUCUDAN gelir, akış kendi sayacını tutmaz. Adımın sınav isteyip istemediği ayrıca get() yanıtının assessment alanıdır ({ count, passScore, attempts }); deneme açılmadan önce paneli o kural açar. Cevaplar yeni deneme id'sinde sıfırlanır."
2400
+ }
2401
+ },
2402
+ 'read-proof-matrix': {
2403
+ summary: 'Kontrollü dokümanın okuma kanıtı matrisi: okuyucu × revizyon; okudu · bekliyor · sınavı geçemedi · atlandı · geçersiz (eskiyen revizyonun okuması) · ayrıldı rozetleri süreç defterinden hesaplanır; revizyon başına sayılar ve bekleyenlere hatırlatma. Veriyi KENDİSİ çekmez.',
2404
+ guide: 'bpm',
2405
+ behavior: [
2406
+ "Veri yolu: her revizyonun dağıtım süreç örneği için akış process.instance.timeline { id: instanceId } çağırır ve revisions'a [{ label, number, state: effective | superseded | draft, instanceId, events }] setter yazar; readers'a kullanıcı listesinden [{ userId, name, isActive }].",
2407
+ "Hücre durumu defterden: task-created payload.assignee dağıtımı verir; havuz görevinde assignee boştur (yalnız candidates yazılır) ve kopyayı task-claimed olayının aktörü (actorUserId) sahiplenir; task-reassigned kopyayı payload.from'dan payload.to'ya taşır — devreden kişi o kopyadan düşer, devralan bekleyen olur. read-proof payload.userId (ya da aktör, yoksa kopyanın o anki sahibi) okumayı ve payload.at tarihini verir; outcome assessment-failed ile kapanan görev 'sınavı geçemedi', task-cancelled/task-superseded 'atlandı'; state superseded revizyondaki okuma 'geçersiz'; dağıtımda olup okumayan isActive:false kişi 'ayrıldı', diğerleri 'bekliyor'; dağıtımda olmayan 'dağıtımda değil'.",
2408
+ "Satır sırası readers listesidir; defterde görünüp listede olmayanlar kimlikleriyle sona (alfabetik) eklenir. Sütun başlığı revizyon etiketi, durum rozeti ve 'X okudu · Y bekliyor · Z geçersiz' özetidir.",
2409
+ "showRemind:true ve bekleyen okuyucu varken sütunda 'Okumayanlara hatırlat (N)' düğmesi remind yayar: event.data = { revision, instanceId, userIds }; akış bildirim gönderir. Ayrılanlar userIds'e girmez.",
2410
+ "revisions ya da okuyucu yoksa emptyText (varsayılan 'Okuma kaydı yok'); isLoading iken 'Yükleniyor…' role=status."
2411
+ ],
2412
+ propNotes: {
2413
+ revisions: "[{ label, number, state, instanceId, events: [{ kind, taskId, actorUserId, payload, occurredAt }] }] — events process.instance.timeline yanıtının events'i olduğu gibi.",
2414
+ readers: '[{ userId, name, isActive }] — isActive:false okumayanı ayrıldı sayar.',
2415
+ showRemind: 'Hatırlat düğmesi; varsayılan true.'
2416
+ }
2417
+ },
2418
+ 'process-timeline': {
2419
+ summary: 'Süreç örneğinin defteri (kim, ne, hangi karar, yorum) ardından sıradaki ve gelecek adımlar; bölge yeniden başlatma turları ve geçersizleşen görevler işaretli.',
2420
+ guide: 'bpm',
2421
+ behavior: [
2422
+ "Veri process.instance.timeline { id } yanıtından bağlanır: rows ← events, currentNodes ← currentNodes, nextNodes ← nextNodes. Defter satırı adımı sunucunun eklediği nodeName ile (düz metin) gösterir, adı olmayan adımda nodeId kalır. actorName akışta kullanıcı adıyla (process.user.list) doldurulmazsa actorUserId gösterilir.",
2423
+ 'Olaylar sequence sırasıyla çizilir; region-restarted her görüldüğünde yeni tur başlar ve "N. tur" ayırıcısı basılır.',
2424
+ 'task-superseded olan görevin bütün satırları üstü çizili "Geçersizleşti" etiketiyle çizilir; showSuperseded:false iken listeden çıkar.',
2425
+ 'currentNodes "Sırada", nextNodes "Gelecek adım" rozetiyle çizilir; sıradaki bir adım gelecekler arasında tekrar edilmez. showFuture:false gelecek adımları gizler.',
2426
+ 'clickItem yükü yalnız params ile gider: event.data = { currentItem, index }.',
2427
+ "showVerify:true 'Hash doğrula' düğmesini çizer ve verifyLedger olayını yayar; akış process.instance.ledger.verify { id } sonucunun isValid'ini ledgerStatus ('valid' | 'broken'), brokenAtSequence'ini brokenAtSequence'e yazar, rozet 'Defter geçerli' ya da 'Defter N. satırda bozuk' olur. showExport:true 'Defteri indir (CSV)' düğmesiyle exportLedger yayar; akış Page.bpm.instance(id).exportLedger() sonucunu ({ fileName, contentType, text (BOM'lu), dataUrl }) dataUrl ile dosyaya kaydeder. Komponent uç çağırmaz."
2428
+ ],
2429
+ propNotes: {
2430
+ ledgerStatus: "'' (denetlenmedi, rozet yok) | 'valid' | 'broken' — verifyLedger akışının yazdığı sonuç.",
2431
+ brokenAtSequence: "number | null — ledgerStatus 'broken' iken ilk bozuk satırın sequence'i.",
2432
+ rows: '[{ sequence, kind, nodeId, nodeName, taskId, actorName, occurredAt, payload: { outcome, comment, body } }] — bpm/instances/{id}/timeline events dizisi; nodeName düz metin (eski kayıtlardan çok dilli sözlük de gelebilir; komponent ikisini de okur). comment-added satırının metni yanıtın comments dizisindedir: akış payload.commentId ile eşleyip payload.body olarak ekler (okunamayan iç yorum comments içinde gelmez).',
2433
+ users: '[{ id, name }] — yorum metnindeki @<kullanıcı id> bahsetmelerini adla gösterir; boşsa id kalır.',
2434
+ currentNodes: "[{ id, name }] — name çok dilli sözlük ({ tr, en }) ya da düz metin olabilir.",
2435
+ nextNodes: "[{ id, name, adaptationLabel }] — adaptationLabel uyarlamanın eklediği/değiştirdiği adımı işaretler."
2436
+ }
2437
+ },
2438
+ 'process-monitor': {
2439
+ summary: 'Süreç izleme panosu: açık · SLA geçen · hatalı · sahipsiz · askıda · son 30 günde kapanan sayaçları, örnek tablosu, hatalı satırda Yeniden dene/Adımı atla, sahipsiz satırda Ata, seçili örneklerde toplu yeniden ata · termin uzat · askıya al · adıma atla · iptal ve son toplu işlem için Geri al. Veriyi KENDİSİ çekmez.',
2440
+ guide: 'bpm',
2441
+ behavior: [
2442
+ "Veri yolu: mount/filter akışı process.instance.list (query alanları) ile örnekleri okuyup rows'a setter yazar. bpm/instances özet satırı id, definitionId, definitionSlug, state, subjectRowId, initiatorUserId, priority, startedAt, completedAt, outcome, slaDueAt yanında definitionName (düz metin) ve currentNodes ([{ id, name }] — bekleyen adımlar, düz metin adıyla çizilir) taşır. tokens, lastError, versionNumber/overrideId akışta process.instance.get { id } ile, assigneeName/unitId kendi okumalarıyla, openTaskIds/unassignedTaskIds process.task.list { tab: 'all' } ile eklenir. tokens eklenmezse atla/adıma atla yükünde nodeId/fromNodeIds olmaz. Komponent uç çağırmaz.",
2443
+ "Sayaç kutuları tıklanınca filter'a yazar ve filter olayını yayar; tablo kutunun saydığı satırları gösterir (Açık: yalnız açıklar, Kapanan 30g: son 30 günde kapananlar — scope). Kutuların altındaki süzgeç çubuğu durum, süreç, birim (satırlarda varsa), öncelik ve yalnız gecikenleri yazar. Yükteki query yalnız sunucu alanlarını (definitionId, applicationId, state, subjectRowId, initiatorUserId) taşır; unitId, priority, slaBreached, unassigned ve scope sayfada süzülür.",
2444
+ "SLA durumu slaDueAt'ten hesaplanır: açık örnekte termin geçtiyse 'SLA geçti', değilse 'Süresinde'; kapalı örnekte ve terminsiz örnekte gösterilmez.",
2445
+ "Satır eylemleri: state faulted → Yeniden dene + Adımı atla; açık ve unassignedTaskIds dolu → Ata. Adımı atla, askıya al, adıma atla ve iptal gerekçesiz gönderilemez; yeniden ata ve ata hedef kullanıcı, termin uzat yeni tarih, adıma atla hedef adım ister.",
2446
+ "Toplu eylem yalnız uygun durumdaki seçili örneklere gider: yeniden ata/termin uzat açık görevi olan açık örnekler (taskIds dolar), askıya al yalnız running (sunucu başkasını askıya almaz), adıma atla running/faulted, iptal bütün açık örnekler. Uygun örnek yoksa düğme kilitlidir.",
2447
+ "Geri al bandı lastBatchOperation kind reassign ya da extend-due, state completed ve undoneAt boşken çizilir; undo olayı batchOperationId taşır, akış process.batch.undo { id } çağırır.",
2448
+ "instanceAction/bulkAction/undo/clickItem/filter yükleri YALNIZ params ile gider (self'e yazılmaz; filter prop'u komponent içinde de güncellenir)."
2449
+ ],
2450
+ propNotes: {
2451
+ rows: "[{ id, definitionSlug, definitionName, currentNodes, state, priority, startedAt, completedAt, slaDueAt } (bpm/instances özet satırı) + akışın eklediği { definitionName, versionNumber, overrideId, lastError, tokens:[{ nodeId, state }] (instance(id).get()), unitId, assigneeName, openTaskIds, unassignedTaskIds }].",
2452
+ filter: "{ definitionId, applicationId, state (all | running | suspended | faulted | completed), subjectRowId, initiatorUserId, unitId, priority, slaBreached, unassigned }. Sayaç kutusu durumu ve slaBreached/unassigned anahtarlarını birlikte yazar; süreç, birim ve öncelik korunur.",
2453
+ lastBatchOperation: "{ id, kind, state, undoneAt } — akışın son toplu işlem yanıtı (process.batch.execute ya da process.batch.undo sonucu).",
2454
+ allowBulk: "false iken seçim kutuları ve toplu çubuk çizilmez; satır eylemleri kalır.",
2455
+ holds: "[{ scope: process | instance | user, scopeKey, isActive }] — Page.bpm.legalHolds() sonucu; etkin örnek (kimlik) ya da süreç (definitionSlug) bekletmesi satıra 'Yasal bekletmede' rozeti koyar. Kişi bekletmesi satırda işaretlenmez (katılımcılar satırda yok).",
2456
+ predictedRemaining: "[{ instanceId, remainingHours, sampleSize }] — Page.bpm.analytics(slug, 'prediction', { from, to }).prediction; açık örnekte sampleSize > 0 ve remainingHours doluysa satıra '~N sa kaldı' rozeti (tam saate yuvarlanır; 0 — süre aşılmış tahmin — '1 saatten az kaldı'). Kapanmış örnekte ve örneksiz tahminde rozet yok. Tahmin süreç başınadır: akış panodaki her süreç için ayrı çağırır; tahmin görünümü pencereden önce başlayıp hâlâ açık olan örnekleri de kapsar."
2457
+ }
2458
+ },
2459
+ 'process-variants': {
2460
+ summary: 'Süreç madenciliği varyant listesi: yol (adım zinciri), örnek sayısı ve payı (en sık varyanta göre çubuk), ortalama çevrim saati; seçili varyant vurgulu; tanım dışı geçişler (adıma atlama, adım atlama, sürüme taşıma) listesi ve XES / OCEL indir düğmeleri. Veriyi KENDİSİ çekmez.',
2461
+ guide: 'bpm',
2462
+ behavior: [
2463
+ "Veri yolu: mount akışı Page.bpm.analytics(slug, 'variants', { from, to }).variants sonucunu variants'a, Page.bpm.analytics(slug, 'conformance', …).conformance sonucunu conformance'a setter yazar. Heatmap bu komponentte değil: Page.bpm.analytics(slug, 'heatmap', …).chart.heatmapSeries / visitSeries chart rows'una bağlanır (yanıtın view alanı görünüm adıdır).",
2464
+ "Varyant satırı path dizisini (ya da tasarımcı örneğinde 'a, b, c' / 'a → b' metnini) okur; boş yol çizilmez. Çubuk genişliği payın en sık varyanta oranıdır (en sık 100%).",
2465
+ "Satıra tıklamak value'yu yolun '>' ile birleşmiş anahtarına yazar (setter) ve select olayını yayar; aynı anahtar kayıtlı sayfada vurguyu geri getirir.",
2466
+ "Sapma satırları zaman sırasıyla (metin değil zaman karşılaştırılır, eşitlikte sunucu sırası); instance-jumped 'kontrol → onay' biçiminde hedefi gösterir. Örnek kimliği düğmesi clickInstance yayar.",
2467
+ "download olayı yalnız { format: xes | ocel } taşır; akış Page.bpm.exportLog(slug, format, { from, to }) ile { fileName, contentType, text, dataUrl } alır ve dataUrl'den kaydeder. showDownload false iken düğmeler çizilmez."
2468
+ ],
2469
+ propNotes: {
2470
+ value: "string — seçili varyantın anahtarı: düğüm kimlikleri '>' ile birleşik (ör. 'baslangic>kontrol>bitis').",
2471
+ variants: "[{ path: string[], instanceCount, sharePercent, averageCycleHours, sampleInstanceIds }] — bpm/analytics/{slug}/variants yanıtının variants listesi olduğu gibi.",
2472
+ conformance: "[{ instanceId, kind: instance-jumped | node-skipped | instance-migrated, nodeId, targetNodeId, actorUserId, reason, occurredAt }] — bpm/analytics/{slug}/conformance yanıtının conformance listesi.",
2473
+ showDownload: "XES indir / OCEL indir düğmeleri; varsayılan true."
2474
+ }
2475
+ },
2476
+ 'case-view': {
2477
+ summary: 'Çalışan vaka (CMMN) görünümü: kök aşama şeridi (bekleyen aşama kesik çizgili, sürenin vurgulu), sunucunun şu an izin verdiği eylemler (isteğe bağlı öğe ekleme, öğe başlatma / tamamlama / devre dışı bırakma), açık plan öğeleri ve görevleri, kilometre taşları, vaka dosyası ve vaka defteri. Veriyi KENDİSİ çekmez.',
2478
+ guide: 'bpm',
2479
+ behavior: [
2480
+ "Veri yolu: mount akışı Page.bpm.cases.get(caseInstanceId) çağırır ve yanıtın view alanını (state, planItems, availableActions, caseFile, events) aynı adlı prop'lara setter yazar; view adları vaka tanımından doldurur, tanım okunamazsa öğe kimliği görünür.",
2481
+ "Aşama şeridi yalnız kök aşamaları TANIMIN plan sırasıyla ve her aşamanın son tekrarıyla çizer: sıra planItems satırlarındaki index alanıdır (Page.bpm.cases.get view'i tanımdan doldurur), motorun öğeleri açtığı sıra değil; tanımda artık olmayan aşama (index null) sona gider. available (giriş koşulu bekleyen) aşama kesik çizgili ve pasiftir, active olan aria-current=step taşır, completed üstü çizili.",
2482
+ "Eylem düğmeleri yalnız availableActions satırlarıdır (sunucu hesaplar): discretionary 'Eylem ekle' altında, start / complete / disable / enable 'Eylemler' altında. Bilinmeyen eylem ya da plan öğesi kimliği olmayan öğe eylemi çizilmez. 'Kapanış'ı enable etmek sentry sağlanmadan 422 CaseSentryNotSatisfied döner; sunucu enable'ı zaten listelemez.",
2483
+ "action olayı { action, itemId, planItemId } taşır; akış Page.bpm.cases.act(caseInstanceId, event.data) ile güncel örneği alır ve view'i yeniden setter yazar. Açık öğenin görevi varsa 'Görevi aç' clickTask { taskId, planItemId, itemId } yayar; görev task-inbox / task-actions ile aynı görevdir (kind case-task).",
2484
+ "caseFile nesne ({ alan: değer }) ya da [{ id, value }] satırları olabilir; metin olmayan değer JSON olarak yazılır. showTimeline false iken defter çizilmez."
2485
+ ],
2486
+ propNotes: {
2487
+ state: 'active | completed | terminated — vaka durumu rozeti.',
2488
+ planItems: "[{ id, itemId, name, type: stage | human-task | milestone, parentId, state: available | enabled | active | completed | terminated | disabled, taskId, occurrence, endedAt, index }] — bpm/case-instances/{id} planItems'ı; name metin ya da { tr, en } olabilir. index tanımın plan sırasıdır ve view ile gelir (tanımda olmayan öğede null); şerit onu izler.",
2489
+ availableActions: "[{ action: discretionary | start | complete | disable | enable, itemId, planItemId, name }] — sunucunun availableActions listesi; discretionary satırında planItemId yok.",
2490
+ caseFile: "{ alan: değer } ya da [{ id, value }] — vaka dosyası.",
2491
+ events: "[{ sequence, kind, itemId, actorUserId, occurredAt }] — case_instance_events defteri; kind case-started | plan-item-* | milestone-reached | discretionary-added | case-file-updated | case-completed.",
2492
+ showTimeline: 'Defter bölümü; varsayılan true.'
2493
+ }
2494
+ },
2495
+ 'delegation-editor': {
2496
+ summary: 'Vekalet editörü: kendim ya da astım adına vekil, tarih aralığı ve isteğe bağlı süreç filtresiyle vekalet verir; etkin · başlayacak · biten vekaletleri kaynak rozetiyle (manuel · izin süreci · yönetici) listeler ve sonlandırır. Veriyi KENDİSİ çekmez.',
2497
+ guide: 'bpm',
2498
+ behavior: [
2499
+ "Veri yolu: mount akışı process.delegation.list { userId? } ile delegations'a, kullanıcı listesiyle users'a, süreç listesiyle processes'e setter yazar. subordinateUserIds doluysa 'Kimin adına' seçicisi çıkar (akış closure alt ağacından doldurur).",
2500
+ "save yükü: { fromUserId? (yalnız başkası adına), toUserId, startsAt (ISO), endsAt? (ISO), processSlugs (boş = tüm süreçler), reason? }; akış process.delegation.create (event.data alanları; boş processSlugs gönderilmez) çağırır, 409 DelegationOverlap / 422 DelegationChainNotAllowed mesajını error prop'una yazar.",
2501
+ "İstemci doğrulaması sunucu kuralını izler: vekil zorunlu, kişi kendine vekalet veremez, başlangıç zorunlu, bitiş başlangıçtan sonra; bunlar geçerliyse aynı kişi için kesişen aralık ve kesişen süreç (boş liste = hepsi) çakışma sayılır. Hatalar ilk Kaydet denemesinden sonra görünür.",
2502
+ "Satır sırası: etkin, başlayacak (başlangıca göre), biten (en yeni önce). Biten satırda Sonlandır yoktur; end yükü { delegationId } → process.delegation.end { id }.",
2503
+ "'Vekil yönetim yetkilerini devralmaz; başlatanın vekili o talebi onaylayamaz' notu her zaman görünür."
2504
+ ],
2505
+ propNotes: {
2506
+ delegations: "[{ id, fromUserId, toUserId, startsAt, endsAt, processSlugs, source (manual | leave-process | manager), reason, endedAt }] — bpm/delegations yanıtı olduğu gibi.",
2507
+ users: "[{ id, name }] — vekil seçici ve satır adları; bulunmayan kimlik olduğu gibi yazılır.",
2508
+ subordinateUserIds: "string[] — yöneticinin adına vekalet verebileceği astlar; boşsa yalnız 'kendim'.",
2509
+ processes: "[{ slug, name }] — süreç filtresi onay kutuları; boşsa filtre çizilmez (vekalet tüm süreçleri kapsar).",
2510
+ error: "{ status, code, message } — akışın son kayıt hatası."
2511
+ }
2512
+ },
2513
+ 'handover-wizard': {
2514
+ summary: 'Devir sihirbazı (3 adım): açık görev grupları ve grup başına hedef (üst yönetici · kişi · gruba geri bırak · yönetici kuyruğu) → başlattığı süreçler, yönettiği birimler, tuttuğu pozisyonlar, vekaletler → onay (zorla devret, devret ve pasifleştir). Veriyi KENDİSİ çekmez.',
2515
+ guide: 'bpm',
2516
+ behavior: [
2517
+ "Veri yolu: mount akışı process.handover.preview { userId } yanıtını preview'a yazar. preview değişince kararlar önerilen hedeften yeniden kurulur ve sihirbaz ilk adıma döner.",
2518
+ "Varsayılan hedef: suggestedTarget seçeneklerde varsa o; yoksa aday görevde group, atanmış görevde managerUserId varsa manager, yoksa admin-queue. Atanmış görevde manager seçeneği yalnız managerUserId doluyken çıkar; group yalnız aday görevlerde.",
2519
+ "Hedef 'user' seçilen grupta kişi seçilmeden İleri/Devret kilitlidir (zorla modda da). Zorla devret işaretliyken karar verilmeyen atanmış görev grupları sunucuda üst yöneticiye (yoksa yönetici kuyruğuna), aday görev grupları gruba gider (kişi adaylıktan çıkar; aday kalmazsa yönetici kuyruğu).",
2520
+ "apply yükü: { userId, decisions: [{ kind, key, target, targetUserId? (yalnız user) }], force, deactivate }; akış process.handover.apply { userId, decisions, force } çağırır. deactivate:true 'Devret ve pasifleştir' düğmesidir — platformda uygulama kullanıcısı pasifleştirme ucu henüz yok, akış bu bayrağı kendi adımına bağlar.",
2521
+ "stepChange yükü { step: tasks | ownership | confirm, index }. Adım başlıkları aria-current='step' taşır. İkinci adım bilgi amaçlıdır: başlattığı süreçler açık kalır, birim/pozisyon organizasyon ekranından atanır, vekaletler devirle sonlanır."
2522
+ ],
2523
+ propNotes: {
2524
+ preview: "{ userId, managerUserId, items: [{ kind (assigned-tasks | candidate-tasks | started-instances | managed-units | held-positions | delegations), key (süreç slug'ı, birim/pozisyon kodu ya da *), count, suggestedTarget }] } — bpm/handovers/preview/{userId} yanıtı.",
2525
+ users: "[{ id, name }] — 'kişi' hedefi seçicisi; devredilen kullanıcı listeden çıkarılır.",
2526
+ lastHandover: "{ id, completedAt } — dolu olduğunda 'Devir tamamlandı' bandı çizilir.",
2527
+ allowDeactivate: "true iken son adımda 'Devret ve pasifleştir' düğmesi çıkar."
2528
+ }
2529
+ },
2530
+ 'notification-center': {
2531
+ summary: 'Süreç bildirim merkezi: bildirim listesi (okunmamış kalın, okundu onayı gerekenler rozetli), okundu say · okudum · tümünü okundu say, bağlantıya git ve gönderim tercihleri (anında · günlük özet · yalnız SLA, sessiz saatler, saat dilimi). Veriyi KENDİSİ çekmez.',
2532
+ guide: 'bpm',
2533
+ behavior: [
2534
+ "Veri yolu: mount akışı process.notification.list sonucunu notifications'a, process.notification-preference.get sonucunu preference'a yazar. Liste en yeni önce sıralanır.",
2535
+ "Sayaç: okunmamışlar + okunmuş ama onay (ack) bekleyenler. Okundu onayı gereken satırda yalnız 'Okudum' (ack) düğmesi, okunmamış sıradan satırda 'Okundu say' (read) düğmesi çıkar.",
2536
+ "open yükü { notificationId, link?, taskId?, instanceId?, markRead }: markRead okunmamış satırda true'dur; akış gerekirse process.notification.read { id } çağırıp bağlantıya gider. read/ack yükü { notificationId }, markAllRead yükü { notificationIds } (yalnız okunmamışlar).",
2537
+ "Tercih formu preference'tan kurulur (HH:mm:ss → HH:mm); savePreference yükü sunucu biçimindedir: { mode, digestAt 'HH:mm:00', quietFrom/quietTo 'HH:mm:00' ya da sessiz saat kapalıyken null, timeZone }. Saat dilimi boşken, sessiz saatin bir ucu eksikken ya da saat SS:DD değilken Kaydet kilitlidir.",
2538
+ "Kanal seçimi ve üst çubuk soket rozeti bu bileşende yok: backend tercihinde kanal alanı yok; canlı sayaç için akış process-notifications hub'ına abone olmalı (runtime aboneliği henüz yok)."
2539
+ ],
2540
+ propNotes: {
2541
+ notifications: "[{ id, title, body, link, category (task | sla | watch | mention …), taskId, instanceId, ackRequired, readAt, acknowledgedAt, createdAt }] — bpm/notifications data dizisi.",
2542
+ preference: "{ mode (immediate | digest | sla-only), digestAt, quietFrom, quietTo, timeZone } — bpm/notification-preferences yanıtı.",
2543
+ defaultTimeZone: "preference.timeZone boşken forma yazılan saat dilimi (IANA ya da sunucunun tanıdığı kimlik).",
2544
+ showPreferences: "false iken Tercihler düğmesi ve formu çizilmez."
2545
+ }
2546
+ },
2547
+ 'approval-chain-editor': {
2548
+ summary: "Onay zinciri editörü (uygulama yöneticisi uyarlaması): Üstte sürüm · uyarlama (rev) · açık örnek çipleri; 'Onay zinciri' sekmesinde zaman çizelgesi: başlangıç olayı, bölgeden önceki tekil yol, 'Uyarlamaya açık bölge' kutusu (sayaç, adım kartları), bölgeden sonra ilk dallanmaya kadar kilitli adımlar (gri, kilit ikonlu) ve bitiş. Kartta ad + 'Kısmen açık'/'Eklendi' rozeti, kişi · politika · süre özeti, ↑ ↓ sıralama ve eklenen adımda × kaldır; adıma basınca host drawer'ın üstünde overlay'li ikinci drawer (medium) açılır: kim onaylar · referans kişi · politika · SLA · hatırlatma · aşılınca · kendi talebini onaylama (butonsuz, × ya da overlay ile kapanır). Tür başına '<tür> adımı ekle'; uyarlama varken açık örnek bandı; 'Simülasyon' sekmesinde kuralları simüle et ve sonuç kartı; alt çubukta varsayılana dön (yalnız kayıtlı uyarlama varken) · kaydedilmemiş değişiklik göstergesi · kaydet. Veriyi KENDİSİ çekmez.",
2549
+ guide: 'bpm',
2550
+ behavior: [
2551
+ "Veri yolu: mount akışı process.override.get { id: definitionId } yanıtını view'e yazar (baseModel = aktif sürüm, effectiveModel = uyarlama uygulanmış, editableScopes, override.patch/conflictState). Rol/pozisyon/birim/kullanıcı listeleri roles · positions · units · users prop'larına; açık örnek sayısı openInstanceCount'a.",
2552
+ "Zincir yalnız editable: open bölgeden kurulur (regionId boşsa ilk açık bölge). Kenarları sıralı zincir olmayan bölgede ekleme ve sıralama kapanır. Kural seçicisi bölgenin limits.assigneeRules kümesinden, adım türü limits.nodeTypes kümesinden gelir; limits.maxSteps dolunca ekleme kilitlenir.",
2553
+ "save yükü { definitionId, baseVersion, overrideRevision, patch }: patch aktif sürüme karşı TAM uyarlamadır — bu bölgenin işlemleri yeniden kurulur (değişen alanlar add/replace/remove, eklenen adım 'nodes/-', sıra değişince bölgenin edges'i replace); kayıtlı uyarlamanın bölge dışındaki ve editörün düzenlemediği alanlara ait işlemleri korunur (uyarlama çatışmalıysa ya da başka sürüme yazılmışsa korunmaz). Akış process.override.save { id: definitionId, baseVersion, overrideRevision, patch } çağırır, ardından process.override.get ile view'i tazeler. İstemci doğrulaması (ad, kim onaylar, izinli kural, ISO SLA, adım sınırı) geçmeden yayılmaz.",
2554
+ "simulate yükü { definitionId, subjectRowId?, overridePatch } — kaydedilmemiş uyarlamayla kuru koşu: process.override.simulate { id, subjectRowId, overridePatch } sonucunu simulation'a yazın; satırlar 'adım · kişiler · vekil' olarak çizilir.",
2555
+ "reset ve migrateOpen yükü { definitionId } → process.override.reset / process.override.migrate-open { id }. Kayıtlı uyarlama varken ve openInstanceCount > 0 iken zincir sekmesinde 'N açık örnek hâlâ eski zincirle ilerliyor' bandı çıkar; 'Yeni zincire taşı' düğmesi (migrateOpen) yalnız showFooter iken bandın içindedir; view.isReadOnly (Studio görünümü) iken alt düğmeler ve düzenleme kapalıdır.",
2556
+ "422 satırları insan diline çevrilir: error prop'una sistem ucunun hata kaydından kurulan nesne ({ status, code, message, data, errors } — Steps.<adım>.error doluyken gövde .data'dadır) ya da mapBpmError sonucu yazılır ({ errors: [{ code, path, message }] } ya da { data: { errors } }); RuleNotAllowed 'Sabit kişi kuralı bu süreçte izinli değil. İzinli kurallar: …', RegionLocked, ParamNotEditable, MaxStepsExceeded, NodeTypeNotAllowed. Diğer hatalarda error.message, yoksa ham reddin reason'ı ya da data.message'ı yazılır (409 bayat sürüm/revizyon, 403); akış get() ile yeniden okumalı. conflictState conflicted iken çatışma bandı ve conflictDetail çizilir."
2557
+ ],
2558
+ propNotes: {
2559
+ view: "bpm/definitions/{id}/override yanıtı: { definitionId, slug, activeVersionNumber, overrideRevision, isReadOnly, override { revision, patch, conflictState, conflictDetail }, baseModel, effectiveModel, editableScopes [{ nodeId, parentRegionId, degree, editableParams, limits }] }.",
2560
+ regionId: 'Düzenlenecek açık bölgenin id\'si; boşsa ilk açık bölge (birden çok bölgede seçici çıkar).',
2561
+ roles: "[{ slug, name }] — role:<slug> kuralının değer seçicisi.",
2562
+ positions: "[{ code, name }] — position:<kod> kuralının değer seçicisi.",
2563
+ units: "[{ code, name }] — unit-members:<kod> ve ancestor-manager:<tip> değer seçicisi.",
2564
+ users: "[{ id, name }] — user:<id> değer seçicisi.",
2565
+ simulation: "{ steps: [{ nodeId, name, assignees [{ userId, name }], candidates, source (delegation → 'vekil'), note }] } — simulate sonucu.",
2566
+ openInstanceCount: "Uyarlamaya taşınabilecek açık örnek sayısı; üstteki çipte ve taşı bandında görünür, 0 iken ikisi de yok.",
2567
+ showFooter: "false iken alt çubuk (varsayılana dön · kaydedilmemiş göstergesi · kaydet) ve bandın taşı düğmesi çizilmez, kaydedilmemiş göstergesi üst çip satırına geçer; düğmeleri çevreleyen drawer/modal'ın actions'ı verir. Kaydet = drawer aksiyonu { type: 'submit', formId: <bu bileşenin elementId'si> } — editör gizli bir <form id=elementId> taşır, submit kendi doğrulamasıyla save olayını yayar. Varsayılana dön / taşı aksiyonları reset / migrate-open akışını definitionId'yi sayfa durumundan alarak doğrudan çağırır.",
2568
+ error: "Akışın son kayıt/simülasyon hatası: mapBpmError sonucu { status, code, message, errors? } ya da sistem ucunun hata kaydından kurulan { status, code, message, reason, data, errors } (eski Page.bpm reddi { code, reason, data } de okunur)."
2569
+ }
2494
2570
  }
2495
2571
  };
2496
2572
  /**
@@ -2509,6 +2585,24 @@ export const componentKnowledge = {
2509
2585
  * `ComponentHeightType` · `ComponentAlignType`) — platformun kabul ettiği kümenin tek tanımı
2510
2586
  * orasıdır ve backend artık tanımadığı jetonu 400 ile reddeder.
2511
2587
  */
2588
+ /**
2589
+ * SATIR İÇİ stil alanları — `style` prop'unun KEBAB-CASE isteyen dalları (TB-129 · S2-39).
2590
+ *
2591
+ * Kural tek komponente özgü değil bir YAZIM SÖZLEŞMESİDİR: `style.root` emotion `css()` bloğudur ve
2592
+ * camelCase okur, `style.thead|th|tr|td` ise satır içi `style` attribute'una basılır
2593
+ * (`column-view.ts` `toStyleString` anahtarı OLDUĞU GİBİ yazar) — orada `fontSize` sessizce düşer,
2594
+ * `font-size` çalışır. Gateway'in F-06 çevirisi bu dalları da camelCase yapıp stili öldürüyordu
2595
+ * (ölçüm: otomotiv liste tablosu, 2026-09-20); artık bu sözlükteki alanların ALTINA hiç dokunulmaz.
2596
+ *
2597
+ * Sözlüğe yeni satır eklerken ölçüt: alanın değeri DOM'un `style` attribute'una string olarak mı
2598
+ * yazılıyor? Öyleyse buraya girer; emotion bloğuysa girmez.
2599
+ */
2600
+ export const INLINE_STYLE_FIELDS_BY_TYPE = {
2601
+ table: ['thead', 'th', 'tr', 'td']
2602
+ };
2603
+ export function inlineStyleFields(componentType) {
2604
+ return componentType === undefined ? undefined : INLINE_STYLE_FIELDS_BY_TYPE[componentType];
2605
+ }
2512
2606
  export const APPEARANCE_TOKEN_SETS = {
2513
2607
  paddingType: {
2514
2608
  values: ['none', 'normal', 'custom'],
@@ -2524,7 +2618,7 @@ export const APPEARANCE_TOKEN_SETS = {
2524
2618
  },
2525
2619
  heightType: {
2526
2620
  values: ['fixed', 'auto', 'fill'],
2527
- note: "'fixed' heightString'i okur, yoksa size.h×10px kullanır; 'fill' yüksekliği ebeveynin bıraktığı yerden alır. MOBİLDE (≤ 767 px) mobil bloğu olmayan her düğüme 'height: auto !important' yazılır (toplu mobil kural): yüksekliği satıra 'height' olarak yazılan 'fixed' düğüm (flex ya da CSS grid ebeveyninde, stretch yokken) 200 px yazılı olsa da 375 px'te içeriğine göre çizilir; stretch'li satırda yazılan 'min-height' etkilenmez; 12 kolonlu eski ebeveynde yükseklik grid-row aralığındandır. Yazılı yüksekliği mobilde de istiyorsan, yalnız heightType:'fixed' iken, appearance.className'e AYRILMIŞ 'ng-keep-height-mobile' belirtecini yaz (diğer sınıfları koru: className: 'hero ng-keep-height-mobile'); belirteç yoksa ya da heightType 'fixed' değilse davranış eskisi gibidir. Bu bir şema alanı değil serbest sınıf belirtecidir, doğrulayıcı ve veritabanı değişmez."
2621
+ note: "'fixed' heightString'i okur, yoksa size.h×10px kullanır; 'fill' yüksekliği ebeveynin bıraktığı yerden alır."
2528
2622
  },
2529
2623
  alignType: {
2530
2624
  values: ['left', 'center', 'right'],
@@ -2576,7 +2670,7 @@ export const INTERNAL_ROLES_BY_TYPE = {
2576
2670
  'row-<0 tabanlı sıra; sayfa değişince yeniden numaralanır>'
2577
2671
  ],
2578
2672
  kanban: [
2579
- "card-<kart id'si (idField değeri; yoksa 'card-<sıra>' yani '__card-card-<sıra>')>",
2673
+ "card-<kart id'si (idField; yoksa card-<sıra>)>",
2580
2674
  "col-<kolon value'su> (bırakma hedefi)"
2581
2675
  ],
2582
2676
  eventcalendar: [
@@ -2608,3 +2702,140 @@ export const knowledgeNote = 'knowledge alanı elle doğrulanmış davranış bi
2608
2702
  export function knowledgeFor(slug) {
2609
2703
  return slug ? componentKnowledge[slug] : undefined;
2610
2704
  }
2705
+ /* ─────────────────────────── TB-123 · katalog doğrulaması ─────────────────────────── */
2706
+ /**
2707
+ * ENUM TİPLERİ — seçenek listesi gerçekten bir DEĞER KÜMESİ olan prop tipleri.
2708
+ *
2709
+ * Ölçüm (2026-09-20, 101 komponentlik uygulama sözlüğü): `dropdown` (180/180), `radio` (85/85) ve
2710
+ * `switcher` (78/78) prop'larının HEPSİ seçenek taşır ve seçeneklerin hepsi string'dir. `number`
2711
+ * tipinde ise `options` bir ENUM DEĞİL sınır çiftidir (`opacity` → [0, 100], `transitionMs` →
2712
+ * [0, 1000]) ve `component` tipinde izinli komponent tipi filtresidir — ikisi de denetlenmez.
2713
+ * `multiselect` kapalı bir küme taşır ama değeri dizidir; bilerek dışarıda bırakıldı (gateway'in
2714
+ * eksik denetimi platformun kendi duvarına düşer, fazla denetimi geçerli yazmayı bloklardı).
2715
+ */
2716
+ const ENUM_PROP_TYPES = new Set(['dropdown', 'radio', 'switcher']);
2717
+ /**
2718
+ * Platformun komponent sözlüğünü (`GET /components/{app}`) doğrulama kurallarına indirger:
2719
+ * tip → (prop adı → enum değerleri | undefined). YALNIZ ÜST DÜZEY prop'lar girer; platformun
2720
+ * duvarı da yalnız onları denetliyor (ölçüm: `surfaceStyle.contentOverflow: 'clip'` geçti).
2721
+ */
2722
+ export function catalogTypeRules(components) {
2723
+ const rules = new Map();
2724
+ for (const component of components) {
2725
+ const slug = typeof component.slug === 'string' ? component.slug : undefined;
2726
+ const declared = component.definition?.props;
2727
+ if (slug === undefined || !Array.isArray(declared))
2728
+ continue;
2729
+ const props = new Map();
2730
+ for (const entry of declared) {
2731
+ const name = typeof entry?.name === 'string' ? entry.name : undefined;
2732
+ if (name === undefined || name === '')
2733
+ continue;
2734
+ const options = ENUM_PROP_TYPES.has(String(entry.type ?? '')) && Array.isArray(entry.options)
2735
+ ? entry.options.map(option => option?.value).filter((value) => typeof value === 'string')
2736
+ : undefined;
2737
+ props.set(name, options !== undefined && options.length > 0 ? options : undefined);
2738
+ }
2739
+ if (props.size > 0)
2740
+ rules.set(slug, { props });
2741
+ }
2742
+ return rules;
2743
+ }
2744
+ /**
2745
+ * Prop değerinin DENETLENEBİLİR hâli. Şemada prop'lar `{ type, ref, data }` sarmalında yaşar;
2746
+ * `static` sarmalın taşıdığı değer denetlenir, `code`/`translation`/`flow`/`property` sarmalları
2747
+ * çalışma zamanında çözülür ve sabit bir değerleri yoktur — onlara dokunulmaz.
2748
+ */
2749
+ function staticPropValue(value) {
2750
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
2751
+ return value;
2752
+ const record = value;
2753
+ if (typeof record.type !== 'string')
2754
+ return value;
2755
+ if (record.type !== 'static')
2756
+ return undefined;
2757
+ return record.data ?? record.ref;
2758
+ }
2759
+ /**
2760
+ * TB-123 / S2-33 — tam şema yazan yolların (page_update · layout_update) katalog denetimi.
2761
+ *
2762
+ * Platformun doğrulama duvarı yalnız micro-op ucunda koşuyor: aynı geçersiz değer
2763
+ * `page_schema_patch`'te `invalid-enum-value` ile reddedilirken `page_update`'te 200 dönüyor ve
2764
+ * kusur ancak EKRANDA görülüyordu. Burası aynı kararı aynı kural kimlikleriyle, istek gitmeden
2765
+ * verir. Kural kimlikleri platformun kendi yanıtından alındı (ölçüm 2026-09-20).
2766
+ *
2767
+ * Katalog okunamazsa (`rules` boş) doğrulama SUSAR: bilinmeyen sözlük yüzünden geçerli bir yazmayı
2768
+ * bloklamak, denetimi atlamaktan kötüdür.
2769
+ */
2770
+ export function schemaCatalogErrors(nodes, rules) {
2771
+ const errors = [];
2772
+ if (rules.size === 0)
2773
+ return errors;
2774
+ const visit = (node) => {
2775
+ if (!node || typeof node !== 'object')
2776
+ return;
2777
+ const record = node;
2778
+ const componentId = String(record.elementId ?? record.name ?? record.id ?? '?');
2779
+ const type = typeof record.type === 'string' ? record.type : undefined;
2780
+ const typeRules = type === undefined ? undefined : rules.get(type);
2781
+ if (typeRules !== undefined && record.props && typeof record.props === 'object' && !Array.isArray(record.props)) {
2782
+ for (const [name, raw] of Object.entries(record.props)) {
2783
+ if (!typeRules.props.has(name)) {
2784
+ errors.push({
2785
+ componentId,
2786
+ path: `props.${name}`,
2787
+ rule: 'unknown-prop',
2788
+ message: `'${type}' komponentinin '${name}' diye bir prop'u yok.`,
2789
+ suggestions: [...typeRules.props.keys()].sort()
2790
+ });
2791
+ continue;
2792
+ }
2793
+ const options = typeRules.props.get(name);
2794
+ const value = staticPropValue(raw);
2795
+ if (options === undefined || value === undefined || value === null || value === '')
2796
+ continue;
2797
+ if (options.includes(String(value)))
2798
+ continue;
2799
+ errors.push({
2800
+ componentId,
2801
+ path: `props.${name}`,
2802
+ rule: 'invalid-enum-value',
2803
+ message: `'${String(value)}' '${name}' için geçerli bir değer değil.`,
2804
+ suggestions: [...options]
2805
+ });
2806
+ }
2807
+ }
2808
+ if (record.appearance && typeof record.appearance === 'object' && !Array.isArray(record.appearance)) {
2809
+ for (const [name, value] of Object.entries(record.appearance)) {
2810
+ const tokens = APPEARANCE_TOKEN_SETS[name];
2811
+ if (tokens === undefined || value === undefined || value === null || value === '')
2812
+ continue;
2813
+ if (tokens.values.includes(String(value)))
2814
+ continue;
2815
+ errors.push({
2816
+ componentId,
2817
+ path: `appearance.${name}`,
2818
+ rule: 'invalid-appearance',
2819
+ message: `'${name}' için geçerli bir değer kullanın: ${tokens.values.join(', ')}. Gelen: '${String(value)}'.`,
2820
+ suggestions: [...tokens.values]
2821
+ });
2822
+ }
2823
+ }
2824
+ for (const child of Array.isArray(record.children) ? record.children : [])
2825
+ visit(child);
2826
+ };
2827
+ for (const node of Array.isArray(nodes) ? nodes : [])
2828
+ visit(node);
2829
+ return errors;
2830
+ }
2831
+ export function schemaCatalogMessage(errors, tool) {
2832
+ const lines = errors.map(error => {
2833
+ const accepted = error.suggestions === undefined || error.suggestions.length === 0
2834
+ ? ''
2835
+ : ` → kabul edilenler: ${error.suggestions.join(' · ')}`;
2836
+ return `${error.componentId} ${error.path} [${error.rule}] ${error.message}${accepted}`;
2837
+ });
2838
+ return `${tool}: şema katalog doğrulamasından geçmedi (istek gönderilmedi) — ${lines.join(' | ')}. `
2839
+ + 'Bu denetim page_schema_patch yolundaki platform duvarının aynısıdır (TB-123): geçersiz değer sessizce kaydedilip ekranda kaybolmasın diye tam şema yolunda da koşar. '
2840
+ + "Değer kümelerini component_get('<tip>') ile doğrulayın.";
2841
+ }