@appaflytech/zeyrek-ai-mcp 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +15 -0
- package/dist/config.js +9 -0
- package/dist/index.js +2 -0
- package/dist/knowledge/componentCatalog.js +4 -2
- package/dist/knowledge/componentEvents.js +3 -3
- package/dist/knowledge/mobileComponentCatalog.js +308 -50
- package/dist/knowledge/mobileComponentEvents.js +130 -3
- package/dist/knowledge/normalize.js +16 -6
- package/dist/knowledge/platform/lint.js +110 -3
- package/dist/knowledge/platform/mobile.js +1 -1
- package/dist/knowledge/platform/mobileRules.js +70 -11
- package/dist/knowledge/platform/web.js +1 -1
- package/dist/knowledge/rules.js +106 -11
- package/dist/knowledge/styleResolve.js +49 -3
- package/dist/knowledge/styleResolveNative.js +104 -4
- package/dist/observability/trace.js +1 -1
- package/dist/platform/argumentAliases.js +128 -0
- package/dist/platform/bodyFile.js +103 -0
- package/dist/platform/capture/capture.js +29 -5
- package/dist/platform/capture/console-log.js +80 -0
- package/dist/platform/capture/index.js +1 -0
- package/dist/platform/diagnostics.js +10 -4
- package/dist/platform/http.js +23 -7
- package/dist/platform/responses.js +6 -2
- package/dist/platform/schemaReadMemory.js +60 -0
- package/dist/platform/secrets.js +9 -0
- package/dist/platform/strictArguments.js +68 -12
- package/dist/platform/tokenVault.js +187 -4
- package/dist/resources/guides/expressions.md +1 -1
- package/dist/resources/guides/microservice.md +9 -2
- package/dist/resources/guides/middleware.md +5 -1
- package/dist/resources/guides/mobile.md +165 -10
- package/dist/resources/guides/page.md +161 -41
- package/dist/resources/guides/theme.md +4 -1
- package/dist/resources/guides/workflow.md +7 -1
- package/dist/resources/schema-fingerprint.json +2 -2
- package/dist/server.js +1 -1
- package/dist/tools/datasources.js +1 -1
- package/dist/tools/designSchemaPatch.js +4 -3
- package/dist/tools/externalComponents.js +1 -1
- package/dist/tools/flows.js +70 -4
- package/dist/tools/layouts.js +5 -5
- package/dist/tools/microservices.js +26 -10
- package/dist/tools/pages.js +192 -36
- package/dist/tools/platformInfo.js +4 -1
- package/dist/tools/rows.js +7 -1
- package/dist/tools/schemaOps.js +1 -1
- package/dist/tools/screenWrite.js +4 -3
- package/dist/tools/screens.js +81 -0
- package/package.json +1 -1
|
@@ -25,7 +25,9 @@ export const mobileComponentKnowledge = {
|
|
|
25
25
|
"`layout` düşer (flex-only), `hoverStyle` düşer (dokunmatikte hover durumu yoktur), `style` düşer.",
|
|
26
26
|
'Yüzey (zemin, köşe, kenarlık, gölge) düğüm kabuğunda derlenir; kabın kendisi yalnız yön, hizalama ve aralık (`gap`) taşır.',
|
|
27
27
|
"Hiza adları web ile aynı eşlenir: `verticalAlign: 'middle'` ve `horizontalAlign: 'center'` ortalar. Dikey hizanın kullanacağı boşluk kabın boyundan gelir — `heightType` `fill`, `fixed` ya da en-boy oranlı kapta akış kabuğun boyunu doldurur; boyu içerikten gelen SÜTUN kapta dikey hiza etkisizdir (satır kapta farklı boydaki kardeşleri yine hizalar). `stretch` de web gibi: ana eksende (sütunda `verticalAlign`, satırda `horizontalAlign`) çocukları eksen boyunca yayar, çapraz eksende gerer.",
|
|
28
|
-
'Kutu modeli web ile AYNI kural ve varsayılanlarla çizilir (`appearance.marginType/paddingType`, `normal` = 4 / 10 dp, `custom` kenar kenar): tipi yazılmamış düğüm `normal` dış boşluk, bırakılabilir kap `normal` iç boşluk alır — kenara yaslanacak kapta `none` yazın. `wrap: true` iken satırlar çapraz hizayı izler (web `flex-layout` ile aynı: `stretch` kabı doldurur, `top`/`left` üstten dizer).'
|
|
28
|
+
'Kutu modeli web ile AYNI kural ve varsayılanlarla çizilir (`appearance.marginType/paddingType`, `normal` = 4 / 10 dp, `custom` kenar kenar): tipi yazılmamış düğüm `normal` dış boşluk, bırakılabilir kap `normal` iç boşluk alır — kenara yaslanacak kapta `none` yazın. `wrap: true` iken satırlar çapraz hizayı izler (web `flex-layout` ile aynı: `stretch` kabı doldurur, `top`/`left` üstten dizer).',
|
|
29
|
+
"`title`/`description` web gibi gövdenin üstünde başlık bandı çizer (sarmalayıcı kapta hiç); görünümü `headerStyle`tan (başlık rengi/boyu/kalınlığı, ayraç, dolgu, dış boşluk, asgari boy, hiza — token ve `calc` çözülür). `size: grow` her doğrudan çocuğa ana eksende pay verir (web `flex: 1 1 auto`; içerik boyundan büyür, eşit değil — eşit karo için çocuğa `widthType: fixed` + yüzde).",
|
|
30
|
+
"`click` (mobile-only olay, K1): bir akışa bağlıysa kap runtime'da basılır — bileşik kart (`card` çocuk almaz, kap alır). Basılı his soluklaşma + küçülme; içteki düğmenin basışı kabın `click`ini tetiklemez. Bağsız kap dokunuşu yutmaz. `ariaLabel` basılabilir kabın ekran okuyucu adıdır; cihazda rol `button`, web'de rol yazılmaz (react-native-web `button` rolünü `<button>` öğesine çevirir, içteki düğme iç içe `<button>` olurdu)."
|
|
29
31
|
]
|
|
30
32
|
},
|
|
31
33
|
'widget-area': {
|
|
@@ -50,7 +52,10 @@ export const mobileComponentKnowledge = {
|
|
|
50
52
|
'Web`de karşılığı YOKTUR — mobil ekran kendiliğinden kaymaz; `heightType: fill` ile ekranın kalanını kaplatın.',
|
|
51
53
|
'`horizontal` yatay kaydırır; yerleşim alanları içerik kabına uygulanır. Sona varınca `scrollEnd` yayılır.',
|
|
52
54
|
'`refreshable` YALNIZ dikey kaydırmada ve yalnız runtime kipinde çekerek yenileyi açar (`refresh` olayı); tasarım kanvasında jest çizilmez. Barındırıcı (Expo) kendi çekerek yenilesini bu durumda KAPATIR, yoksa iki gösterge üst üste biner.',
|
|
53
|
-
'`stickyHeader` (FlutterFlow StickyHeader) İLK çocuğu kaydırırken üstte tutar — tasarım kanvasında da; yalnız dikey kaydırmada (RN `stickyHeaderIndices`), `horizontal` açıkken yok sayılır ve panel alanı gizler.'
|
|
55
|
+
'`stickyHeader` (FlutterFlow StickyHeader) İLK çocuğu kaydırırken üstte tutar — tasarım kanvasında da; yalnız dikey kaydırmada (RN `stickyHeaderIndices`), `horizontal` açıkken yok sayılır ve panel alanı gizler.',
|
|
56
|
+
'Yapışkan çocuk bir `tabs` ise runtime`da yalnız ŞERİDİ yapışır, gövde kayan içerikle akar (bitki detayı: görsel, sekme şeridi, uzun gövde) — `tabs`a `states: { isSticky: true }` verin, kaydırıcıya `heightType: fixed`. Tasarım kanvasında sekme bölünmez.',
|
|
57
|
+
'`scroll { y, contentHeight, viewportHeight }` 100 ms seyreltmeyle YALNIZ `scroll` olayına akış bağlıyken yayılır; konum düğüme `scrollY` olarak da yazılır (bağ: `{{ kaydirici.scrollY }}`, şemada ilan edilmez). Akış bağlı değilken `scrollY` güncellenmez.',
|
|
58
|
+
'İlk çocuk dışındaki DOĞRUDAN çocuklar düğüm durumu `states.isSticky: true` ile yapışır (ör. listenin ortasındaki bölüm başlıkları; `stickyHeader` ile birlikte de çalışır). Studio panelinde bu bayrağın alanı YOKTUR — şemaya MCP yazar (`add_component` gövdesinde `states: { isSticky: true }`). Yalnız dikey; kaydırıcının boyu sınırlı olmalı (`heightType: fill` sayfa kaydırıcısı içinde içerik kadar uzar — `fixed` verin). Web önizlemede sonraki başlık öncekini itmez, üstüne biner; iOS`ta iter.'
|
|
54
59
|
],
|
|
55
60
|
propNotes: {
|
|
56
61
|
refreshable: 'Çekerek yenile; akış bir söz döndürürse gösterge onu bekler, döndürmezse 600 ms döner.',
|
|
@@ -61,19 +66,22 @@ export const mobileComponentKnowledge = {
|
|
|
61
66
|
summary: 'Metin; punto temanın tip ölçeğinden gelir.',
|
|
62
67
|
differences: [
|
|
63
68
|
'`wordBreak` düşer: React Native metni `numberOfLines`/`ellipsizeMode` ile sınırlar, CSS kırma kuralının karşılığı yoktur.',
|
|
69
|
+
"`lineClamp` (1–10) `numberOfLines` + sonda üç nokta olarak uygulanır (2026-09-27, f-05). Mobile-only `highlight`: aramaya bağlanan metin — eşleşen parçalar `font-semibold text-primary`; karşılaştırma uygulama diline göre katlanır (`tr`'de `I`↔`ı`, `İ`↔`i`). Satır içi bağlantı için `markdown` + `linkClick` kullanın.",
|
|
64
70
|
"Seviyenin mobil karşılığı varsa (`--ng-font-size-<seviye>-mobile`) o kullanılır; metin stili ATA KAPTAN MİRAS ALINMAZ (RN'de miras yoktur), kabuk tipografiyi bağlama yazar."
|
|
65
71
|
]
|
|
66
72
|
},
|
|
67
73
|
button: {
|
|
68
|
-
summary: "Tıklama kaynağı; shadcn `Button` ilkeli. `kind` semantik rengi, `variant` o rengin kullanımını seçer; mobil kırılım shadcn'in `secondary`/`ghost`/`link` varyantlarını ve `icon` boyunu ekler (web şeması değişmez).",
|
|
74
|
+
summary: "Tıklama kaynağı; shadcn `Button` ilkeli. `kind` semantik rengi, `variant` o rengin kullanımını seçer; mobil kırılım shadcn'in `secondary`/`ghost`/`link` varyantlarını ve `icon` boyunu, `tonal` varyantını, `iconPosition: top`u ve `ariaLabel`i ekler (web şeması değişmez).",
|
|
69
75
|
differences: [
|
|
70
76
|
'`isNewTabLink` düşer: mobilde sekme yoktur, bağlantı sistem tarayıcısına ya da derin bağlantıya gider (F5/F6).',
|
|
71
|
-
'`isLoading` açıkken
|
|
72
|
-
"`icon
|
|
77
|
+
'`isLoading` açıkken `ActivityIndicator` ikonun yerinde döner (ikonsuz düğmede etiketin önünde).',
|
|
78
|
+
"İkon (`icon` + `iconPosition`) Material Symbols glifidir, etiketin ton rengini alır; `iconPosition: top` (mobile-only) ikonu etiketin üstüne koyar — `appearance` boyuyla (`heightType: fixed`) dikey karo, `variant: tonal` ile D01 hızlı eylem satırı. Rozet (`badgeValue`, `badgeColor` varsayılan `error`) `badge` ilkeliyle sağ üst köşede; `'•'` nokta, boş değer çizilmez. 2026-09-27'ye dek ikon ve rozet çizilmiyordu (f-04).",
|
|
79
|
+
"`size: icon` kare düğmedir (kenarı `md` yüksekliği), yalnız glif çizilir, `text` çizilmez. Ekran okuyucu adı sırayla `ariaLabel` → `text` → ikonun adı; ad vermeyen ikon düğmesi MOB-013 bilgi satırı üretir.",
|
|
80
|
+
"`type: link`: dokunuş `click` yayar ve dış `href` (http(s), mailto, tel, nokta taşıyan alan adı) sistem tarayıcısında açılır; uygulama içi yol (`/sayfa`) açılmaz — gezinme `click` akışında `redirect` ile.",
|
|
73
81
|
"Etiketin rengi düğmenin kendi kararıdır (`kind`/`variant` kontrastı): ata kabın `typographyStyle.color`ı etikete İNMEZ, punto da temanın form ölçüsünden gelir; aile ve kalınlık gibi öteki tipografi alanları iner."
|
|
74
82
|
],
|
|
75
83
|
propNotes: {
|
|
76
|
-
variant: "shadcn varyantına çevrilir: `solid` → `default` (`kind: error` iken `destructive`) · `outline` → `outline` (`--background` zemin, `--border` kenar) · `text` (web'in adı) ve `ghost` → `ghost` (zeminsiz) · `secondary` → `secondary` (nötr `--secondary` dolgu) · `link` → `link` (zeminsiz, etiket `--primary`). `secondary`, `ghost` ve `
|
|
84
|
+
variant: "shadcn varyantına çevrilir: `solid` → `default` (`kind: error` iken `destructive`) · `outline` → `outline` (`--background` zemin, `--border` kenar) · `text` (web'in adı) ve `ghost` → `ghost` (zeminsiz) · `secondary` → `secondary` (nötr `--secondary` dolgu) · `link` → `link` (zeminsiz, etiket `--primary`). `tonal` (mobile-only) rolün açık zemini + rolün kendisinde etiket (`primary` → `--primary`/15, `error` → `--destructive`/15, `success`/`warning` → `--status-*`/15; `info` yüzey rengi olduğu için dolu zemin + ön plan etiketi). `secondary`, `ghost`, `link` ve `tonal` YALNIZ mobil şemada seçenektir.",
|
|
77
85
|
kind: "Rengin nerede göründüğü varyanta bağlıdır. `solid`: zemin `primary` → `--primary`, `error` → `--destructive`, `info`/`success`/`warning` → `--status-*`. `outline`: `primary` NÖTR kalır (`--border` kenar, ön plan rengi etiket), `error` ve durum renkleri kenarı ve etiketi boyar. `text`: `primary` nötr ön plan etiketi, `error` ve durum renkleri etiketi boyar (`ghost` `primary`/`error`'da aynı). `secondary`: nötr dolgu, `error` etiketi `--destructive` yapar. `link`: etiket `--primary`, `error` iken `--destructive`. BİLİNEN HATA: `info`/`success`/`warning` `ghost`, `secondary` ya da `link` ile verilirse zemin de etiket de aynı durum rengine boyanır ve etiket okunmaz — bu üç varyantta `kind`'ı `primary` ya da `error` bırakın.",
|
|
78
86
|
size: "`sm` → shadcn `sm`, `md` → `default`, `lg` → `lg`, boş (`''`) temanın varsayılanı (`--ng-form-default-size`); bu kademelerde yükseklik, punto ve yatay iç boşluk sınıftan değil temanın `--ng-form-height-*`/`--ng-form-font-size-*`/`--ng-form-padding-x-*` değişkenlerinden gelir. `icon` (yalnız mobil) için temada `--ng-form-*-icon` değişkeni YOKTUR: satır içi yükseklik tanımsız kalır, iç boşluk `spacing.md`'ye, punto taban puntoya düşer ve düğme ikon da çizmez — bu kademe bugün kullanışlı değildir."
|
|
79
87
|
}
|
|
@@ -95,21 +103,23 @@ export const mobileComponentKnowledge = {
|
|
|
95
103
|
textinput: {
|
|
96
104
|
summary: 'Tek satırlık metin alanı; etiket/açıklama/hata kabuğu bütün alanlarda ortaktır.',
|
|
97
105
|
differences: [
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
"`inputMask` web'in `input-mask` modülüyle girişte uygulanır (`pattern:`/`date:`/`time:`… biçimlenir, `regex:`/`iban:` yalnız doğrulanır); değer MASKELİ yazılır (web gibi), imleç sonda. Telefon deseni (`(` ya da `+` taşıyan) klavyeyi telefon tuş takımına, rakamlı aileler sayı klavyesine çevirir.",
|
|
107
|
+
"`clearable`: değer doluyken ve alan düzenlenebilirken sağda × (`<elementId>__clear`); basış `change('')` + `changed('')`, odak alanda kalır.",
|
|
108
|
+
"Mobile-only (D11): `keyboardType` (`default|email|phone|number|decimal|url`; boşsa maskeden), `autoComplete` (`off|email|name|tel|username|postal-code|one-time-code` → iOS `textContentType`), `variant: search` (hap köşe, başta arama ikonu, odaktayken sağda uygulama dilinde \"Vazgeç\" `<elementId>__cancel`: değeri temizler, klavyeyi kapatır, `cancel` yayar), `isValid` (yeşil kenar + ✓; geçersizlik kazanır).",
|
|
109
|
+
'`prefixIcon`/`suffixIcon` alanın içinde glif olarak çizilir (ortak `FieldBox`); `autofocus` runtime\'da klavyeyi açar. 2026-09-27\'ye dek dördü de çizilmiyordu (f-05).',
|
|
100
110
|
'Sayaç kuralı web ile aynı: yalnız `showCounter` açık VE `maxChars` > 0 iken çizilir.'
|
|
101
111
|
]
|
|
102
112
|
},
|
|
103
113
|
textarea: {
|
|
104
114
|
summary: 'Çok satırlı metin alanı.',
|
|
105
115
|
differences: [
|
|
106
|
-
'Yükseklik
|
|
116
|
+
'Yükseklik açıkça verilir (React Native `TextInput` satır sayısını kendi ölçmez): `autoGrow` (web varsayılanı AÇIK) iken içerikle `minLines`–`maxLines` arasında büyür, kapalıyken sabit `lines`. 2026-09-27\'ye dek hep sabit boydu (f-05). `autofocus` runtime\'da klavyeyi açar.'
|
|
107
117
|
]
|
|
108
118
|
},
|
|
109
119
|
numberinput: {
|
|
110
120
|
summary: 'Sayısal klavye açan alan; değer `Intl.NumberFormat` ile biçimlenir.',
|
|
111
121
|
differences: [
|
|
112
|
-
'Klavye `allowDemicalPoints` açıkken `decimal-pad`, kapalıyken `number-pad`. Yazılan değer ayrıştırılabildiği anda `minValue`/`maxValue` aralığına kırpılarak yazılır.',
|
|
122
|
+
'Klavye `allowDemicalPoints` açıkken `decimal-pad`, kapalıyken `number-pad`. Yazılan değer ayrıştırılabildiği anda `minValue`/`maxValue` aralığına kırpılarak yazılır. `prefixIcon`/`suffixIcon` alanın içinde, `autofocus` runtime\'da (f-05).',
|
|
113
123
|
'Web alanı artı/eksi düğmelerini HEP çizer; mobilde düz alan varsayılandır. Düğmeler `variant: stepper` ile gelir — YALNIZ mobil şemada (web şeması değişmez; FlutterFlow Count Controller): alanın iki yanında `-`/`+` (shadcn `outline` `icon`), alana elle yazmak açık kalır; web gibi salt okunur ve görüntüleme kipinde çizilmez, yüklenirken pasiftir. İç roller `<elementId>__decrement` / `<elementId>__increment` — `page_screenshot` `click` onlarla basar.'
|
|
114
124
|
],
|
|
115
125
|
propNotes: {
|
|
@@ -119,8 +129,9 @@ export const mobileComponentKnowledge = {
|
|
|
119
129
|
password: {
|
|
120
130
|
summary: 'Gizli metin alanı; göster/gizle düğmesi alanın içindedir.',
|
|
121
131
|
differences: [
|
|
122
|
-
"`autofill`
|
|
123
|
-
'Göster/gizle
|
|
132
|
+
"`autofill` web değerleriyle çalışır: `current-password` → iOS `password` (Anahtar Zinciri), `new-password` → `newPassword` + parola kuralı (\"Güçlü parola\" önerisi), `off`.",
|
|
133
|
+
'Göster/gizle göz ikonudur (`visibility`/`visibility_off`), ekran okuyucu adı uygulama dilinden ("Göster"/"Gizle"). Kimliği `<elementId>__reveal` — `page_screenshot` `click` onunla basar. 2026-09-27\'ye dek sabit İngilizce "Show"/"Hide" metniydi.',
|
|
134
|
+
"Mobile-only: `showStrength` (altta dört parça + Zayıf/Orta/İyi/Güçlü; ölçütler: 8+ karakter, büyük+küçük harf, rakam, sembol; 8'den kısa parola en çok Zayıf), `isValid`. `maxChars`/`showCounter`/`prefixIcon`/`suffixIcon`/`autofocus` `textinput` kuralıyla uygulanır."
|
|
124
135
|
]
|
|
125
136
|
},
|
|
126
137
|
checkbox: {
|
|
@@ -128,20 +139,24 @@ export const mobileComponentKnowledge = {
|
|
|
128
139
|
differences: [
|
|
129
140
|
'`isIndeterminate` `value`yu bastırır ve tire (`remove` glifi) çizer; belirsiz kutuya dokunmak onu seçili yapar.',
|
|
130
141
|
'Etikete dokunmak da kutuyu çevirir (basış satırın `Pressable`ında toplanır).',
|
|
131
|
-
'`labelPosition` yalnız `left`/`right`; `left` seçilince etiket ile kutu satırın iki ucuna yaslanır.'
|
|
142
|
+
'`labelPosition` yalnız `left`/`right`; `left` seçilince etiket ile kutu satırın iki ucuna yaslanır.',
|
|
143
|
+
'Düşenler: `autofocus` ve `focus`/`blur` olayları (onay kutusunun klavye odağı yok, tek sinyal değer değişimidir).'
|
|
132
144
|
]
|
|
133
145
|
},
|
|
134
146
|
switch: {
|
|
135
147
|
summary: 'Açma/kapama anahtarı; shadcn `Switch` ilkeli (`@rn-primitives/switch`) — üç barındırıcıda AYNI görünüm.',
|
|
136
148
|
differences: [
|
|
137
149
|
'Platformun kendi anahtarı (iOS/Android `Switch`) KULLANILMAZ: açıkken zemin `--primary`, kapalıyken `--input`, baş `--background`; kanvas, önizleme ve cihaz aynı bileşeni çizer.',
|
|
138
|
-
'`isReadonly` ve `isDisabled` anahtarı kilitler ve soldurur; `isDisabled` etiketi de soldurur. Tasarım kanvasında anahtar basılamaz olduğu için HER anahtar soluk çizilir — önizlemede ve cihazda değil.'
|
|
150
|
+
'`isReadonly` ve `isDisabled` anahtarı kilitler ve soldurur; `isDisabled` etiketi de soldurur. Tasarım kanvasında anahtar basılamaz olduğu için HER anahtar soluk çizilir — önizlemede ve cihazda değil.',
|
|
151
|
+
'Düşenler: `autofocus` ve `focus`/`blur` olayları (anahtarın klavye odağı yok, tek sinyal değer değişimidir).'
|
|
139
152
|
]
|
|
140
153
|
},
|
|
141
154
|
dropdown: {
|
|
142
|
-
summary: 'Seçim listesi; liste
|
|
155
|
+
summary: 'Seçim listesi; kısa liste alanın altında, uzun ya da aramalı liste alttan açılan sayfada açılır.',
|
|
143
156
|
differences: [
|
|
144
|
-
'
|
|
157
|
+
'`presentation` (mobile özgü): `auto` (varsayılan) sekiz ve daha az seçenekli, aramasız listeyi alanın hemen ALTINDA açar (altta yer yoksa ya da klavye açıksa üstte), öbürünü ekranın altından açılan sayfada; `sheet` hep sayfa, `inline` hep alan altı (arama varsa sayfa).',
|
|
158
|
+
'Sayfada dokuz ve daha çok seçenek ya da `search` akışa bağlıyken tepede arama kutusu durur (iç rol `<elementId>__search`): bağlıysa `search { searchText }` yayar ve listeyi akış yazar, değilse yerelde süzer. Açılış `focus`, kapanış `blur` yayar.',
|
|
159
|
+
'Seçenek görseli web `SelectItem` önceliğiyle: `prefixImage` > `prefixText` (zemini `color`) > `icon` (rengi `color`); seçiliyken kutuda da çizilir. Gizli seçenek (`isHidden`) çizilmez. `isViewmode` kutuyu kilitler, ok ve temizleme düğmesini kaldırır. Düşenler: `options[].tooltip`, `isExpanded`, `isSelectable` (ağaç ve üzerine gelme yok).',
|
|
145
160
|
'Tetikleyici shadcn `Input` görünümündedir (`--input` kenarı; yükseklik, köşe ve punto öteki alanlarla aynı `--ng-form-*` ölçüsü); liste `--popover` yüzeyinde, seçili satırda `check` glifi. Tetikleyici `role="combobox"` taşır (iç rol `<elementId>__trigger`, temizleme düğmesi `<elementId>__clear`), seçilebilir satırlar `role="option"` + `data-value`; liste katmanda açıldığı için `page_screenshot` `select` seçeneği belgede arar ve değerle ya da görünen metinle seçer.',
|
|
146
161
|
'Seçenekler normalize edilir: düz metin dizisi, nesne dizisi ve `optionType: "grouped"` çocukları tek biçime iner; grup başlığı seçilemez, etiketi olmayan seçenek değerini gösterir.'
|
|
147
162
|
]
|
|
@@ -152,6 +167,7 @@ export const mobileComponentKnowledge = {
|
|
|
152
167
|
"Çizim `dropdown`un kendisidir (plans/mobil-coklu-dil K4): tetikleyici `role=\"combobox\"` (iç rol `<elementId>__trigger`), liste tam ekran `Modal`da `role=\"option\"` + `data-value` satırları; temizleme düğmesi YOK (dil boş olamaz). `page_screenshot` `select: '<elementId>', value: 'en'` ile seçilir, seçenek metni dilin yerel adıdır (`LANGUAGE_NAMES`: `tr` → Türkçe, `en` → English).",
|
|
153
168
|
"Diller ve aktif dil makineden enjekte edilir (web `RenderComponent` ile aynı): `languages` = projenin dil listesi (`project_update(languages)`), `value` = `machine.getLanguage()`. Seçim `machine.setLanguage(value)` ile bütün düğümlere `reload` yayar (çeviriye bağlı prop'lar yerinde çözülür), sonra `change { value, selectedLabel }` sayfa akışına gider.",
|
|
154
169
|
"Seçim makineye VERİLEN depoya `zeyrek:<app>:lang` anahtarıyla yazılır: `/preview` ve `/dev|/view`'da tarayıcı `localStorage`, cihazda uygulamanın kv-store'u — uygulama yeniden açılınca o dille başlar. Cihazda barındırıcı seçimi uygulama çapında yayar (`onLanguageChange`): öteki sekmelerin ekranları ve sekme etiketleri de değişir; `?lang` yalnız web barındırıcısında vardır.",
|
|
170
|
+
"`displayMode` web'in etiket kuralıyla çizilir: `native` dilin yerel adı, `code` büyük harf kod (`TR`), `both` `Türkçe (TR)`; sözlükte olmayan kod büyük harfle kendisidir. Açılış/kapanış `focus`/`blur` yayar (`dropdown`dan).",
|
|
155
171
|
"Projede dil tanımlı değilse (`languages` boş) liste boş çizilir — önce `project_update(languages, defaultLanguage)`; `project_get` yanıtındaki `localization` bloğu runtime'ın çevirileri çözüp çözemeyeceğini söyler."
|
|
156
172
|
],
|
|
157
173
|
propNotes: {
|
|
@@ -175,8 +191,11 @@ export const mobileComponentKnowledge = {
|
|
|
175
191
|
summary: 'Görsel; kaynak düz URL ya da platformun dosya nesnesi olabilir.',
|
|
176
192
|
differences: [
|
|
177
193
|
'RN `Image` kullanılır (expo-image değil): paket üç barındırıcıda da aynı kodla çalışır.',
|
|
194
|
+
"Kayıttan okunan FILE alanı `{ id, type: 'ref', value: <dosya id>, absolute_path: <url>, fileName }` döner: prop'a NESNENİN KENDİSİNİ verin (`{{ item.foto }}`) ya da `.absolute_path` yazın — `.value` dosya kimliğidir (GUID), görsel çizilmez (MOB-011). Çözüm web `getfileUrl` ile aynı: metin olduğu gibi, `type: 'file'` nesnede `data`/`value` (base64), öteki nesnelerde `absolute_path`/`url`.",
|
|
178
195
|
'Kaynak çözülemezse (boş prop, tanınmayan nesne) YER TUTUCU çizilir — boş kutu tasarımcıya "kaynak boş" demenin tek yolu.',
|
|
179
|
-
'
|
|
196
|
+
'Görselin boyu (`imageFrameStyle`, `video`/`lottie` ile aynı sıra): (1) boy kabuktan geliyorsa görsel kabuğu DOLDURUR — `heightType: fixed` + `px` boyda tam, `fixed` + `%` boyda ve `fill`de 96 dp taban boyun altına inmeden (ata içerik boyundaysa yüzde ve `fill` boy vermez); (2) değilse `appearance.aspectRatio` görselin kendisine yazılır: boy `auto` ve genişlik `fill`/`fixed` iken boy genişlikten türer; (3) ikisi de yoksa 96 dp taban boy (MOB-012 bilgi satırı). 2026-09-27\'ye dek (1) yoktu: `fixed` verilen görsel 96 dp çizilip altında boşluk bırakıyordu.',
|
|
197
|
+
'Düşenler: `isZoomable`, `isRotatable` (görsel kendisi büyütmez; tam ekran görüntüleyici ayrı iş, plans/mobil-plantcare-acigi f-14).',
|
|
198
|
+
'Mobile özgü alanlar: `fit` (`cover` varsayılan — web kuralı: `widthType: contain` sığdırır; `contain` sığdırır, `fill` gerer), `fallbackSrc` (kaynak boşsa ya da yüklenemezse çizilir; o da yoksa yer tutucu) ve `surfaceStyle` (köşe, kenar, gölge, opaklık; köşe görselin kendisine de yazılır, grupta köşe yoksa tema köşesi). Yuvarlak küçük resim: `surfaceStyle: { radius: "14px" }` + `appearance.aspectRatio: 1` — sarmalayıcı kap gerekmez.'
|
|
180
199
|
]
|
|
181
200
|
},
|
|
182
201
|
icon: {
|
|
@@ -184,21 +203,25 @@ export const mobileComponentKnowledge = {
|
|
|
184
203
|
differences: [
|
|
185
204
|
'Glif bir metindir: ad (`home`) yazı tipi tarafından glife çevrilir, ayrı svg seti taşınmaz. Studio sayfası yazı tipini yüklü tutar; Expo uygulaması `expo-font` ile yükler (F6).',
|
|
186
205
|
'`isSpinning` düşer: dönen ikon `Animated` döngüsü ister, v1`de animasyon yok.',
|
|
187
|
-
'`isNewTabLink` düşer (button ile aynı gerekçe).'
|
|
206
|
+
'`isNewTabLink` düşer (button ile aynı gerekçe).',
|
|
207
|
+
"Etkileşim web `resolveIconInteraction`'ın karşılığı: dış `href` ikonu bağlantı, bağlı `click` düğme yapar; dokunuş `click` yayar, dış adres sistem tarayıcısında açılır, uygulama içi yol akışa kalır. `isDisabled` soldurur ve etkileşimi keser. Etkileşimli ikonun ekran okuyucu adı `ariaLabel`, yoksa ikonun adı. 2026-09-27'ye dek ikon basılamıyordu (f-04)."
|
|
188
208
|
]
|
|
189
209
|
},
|
|
190
210
|
card: {
|
|
191
211
|
summary: 'Görsel + başlık + açıklama + düğme.',
|
|
192
212
|
differences: [
|
|
193
213
|
'`imageFit` RN `resizeMode`a çevrilir: cover→cover, contain→contain, fill→stretch, none→center.',
|
|
194
|
-
'
|
|
214
|
+
'`surfaceStyle` (mobile özgü) kartın ÇERÇEVESİDİR: köşe, kenar, zemin, gölge sınıf tabanını ezer (`radius: "28px 28px 0 0"` üstü yuvarlak kart). Kabuk grubu ikinci kez çizmez.',
|
|
215
|
+
"`image` `image` bileşeniyle aynı çözümden geçer: kayıttaki FILE alanını nesne olarak verin (`{{ item.foto }}`) ya da `.absolute_path` yazın; `.value` dosya kimliğidir (GUID), görsel çizilmez (MOB-011).",
|
|
216
|
+
'Kartın TAMAMI dokunulabilir: gövdeye dokunmak `click` yayar. Kartın düğmesi (`buttonText`) web `Card.svelte` sırasıyla önce kendi `buttonClick`ini, ardından kartın `click`ini yayar (2026-09-27, f-02 H10) — düğmeye ayrı akış bağlamak için `buttonClick`i kullanın; `click` akışı iki dokunuşta da koşar. Liste satırına dokunmak repeater şablonundaki kartın `click`idir. Kart çocuk ALMAZ — satırın alanlarını `title`/`description` kod bağıyla (`{ type: \'code\', ref: \'{{ item.alan }}\' }`) verin.'
|
|
195
217
|
]
|
|
196
218
|
},
|
|
197
219
|
emptystate: {
|
|
198
220
|
summary: 'Liste boşken çizilen ikon + başlık + açıklama + eylemler.',
|
|
199
221
|
differences: [
|
|
200
|
-
'İkon `icon` komponentiyle aynı ligatür yolunu kullanır.',
|
|
201
|
-
'Metni olmayan eylem kaydı çizilmez; eylem kimlikleri `__action-<sıra>`.'
|
|
222
|
+
'İkon `icon` komponentiyle aynı ligatür yolunu kullanır. `image` verilirse ikonun yerine görsel çizilir (web): kutu `size`a göre sm 140×100, md 220×160, lg 320×240, sığdırarak.',
|
|
223
|
+
'Metni olmayan ve gizli (`isHidden`) eylem kaydı çizilmez; kilitli (`isDisabled`) eylem basılmaz; eylem kimlikleri `__action-<sıra>`.',
|
|
224
|
+
"Eylemin dış `href`'i `actionClick` yayıldıktan sonra sistem tarayıcısında açılır (web: bağlantı gezinir ve olay yine yayılır); uygulama içi yol akışa kalır. Düşenler: `actions[].isNewTabLink` (mobilde sekme yoktur)."
|
|
202
225
|
]
|
|
203
226
|
},
|
|
204
227
|
slot: {
|
|
@@ -211,15 +234,29 @@ export const mobileComponentKnowledge = {
|
|
|
211
234
|
summary: 'Şablon düğümlerini satır başına tekrarlar; satır kimlikleri `__row-<i>`.',
|
|
212
235
|
differences: [
|
|
213
236
|
'`FlatList` v1`de KULLANILMAZ: sanallaştırma yalnız gerçek veriyle anlamlı, tasarım kipinde ölçüm haritasını bozar (kaplama görünmeyen satırın kutusunu bulamaz).',
|
|
214
|
-
'Tasarım kipinde şablon BİR kez çizilir. Runtime`da her satır web ile AYNI makine parametresiyle (`index`, `row`, `repeaterId`) çizilir: bağlı prop`lar
|
|
215
|
-
'Satırdaki bir düğümün olayı ÖNCE tekrarlayıcıya `change { selectedIndex }` yazar (aynı satırsa yazmaz), sonra kendi akışını koşar (web sırası)
|
|
237
|
+
'Tasarım kipinde şablon BİR kez çizilir. Runtime`da her satır web ile AYNI makine parametresiyle (`index`, `row`, `repeaterId`) çizilir: bağlı prop`lar `Row` / `RowIndex` / `item` okur. Satır yoksa (`rows` boş dizi ya da `null`) `emptyTitle`/`emptyDescription` doluysa `emptystate` çizilir; ikisi de boşsa hiçbir şey çizilmez (web ile aynı).',
|
|
238
|
+
'Satırdaki bir düğümün olayı ÖNCE tekrarlayıcıya `change { selectedIndex }` yazar (aynı satırsa yazmaz), sonra kendi akışını koşar (web sırası), çocuğun `click`inden sonra da `select` yayar. Akışta tıklanan satırın iki yolu var: `<tekrarlayıcı>.selectedItem` / `.selectedIndex` HER runtime sürümünde çalışır (önerilen); `Row` / `RowIndex` / `item` ARC-121 düzeltmesini (2026-09-27) taşıyan runtime`da da satırı verir ve `item`a yazmak YALNIZ o satırı günceller — daha eski runtime`da akış ifadesinde boştu (ölçüldü 2026-09-19).',
|
|
239
|
+
'Satır bağlamındaki bir akışın setter hedefi satırın şablonu DIŞINDAysa (bir modal, sayfa düzeyi bir metin) yazım SAYFA kapsamında olur; İÇİNDEyse satır bazlı depoya (`_repeaterValues`) yazılır — kapsamı olayın kaynağı değil hedefin AĞAÇTAKİ yeri belirler, `flow-trigger` üzerinden koşan aynı akış için de değişmez (ZM-08, `isElementInRepeaterTemplate`, 2026-09-26).',
|
|
240
|
+
'İç içe repeater zaten MCP tarafından reddedilir (`PAGE-013`) — başlıklar altında gruplu liste (güne göre görevler) için `grouped-list` kullanın; yoksa bir DIŞ repeater\'ın şablonuna İÇ satırdan yazan bir akışın yazımı dış satırın değil İÇ satırın kimliğiyle anahtarlanırdı — bilinen açık, `PAGE-013` riski düşük tutar.',
|
|
216
241
|
'`columnCount` > 1 iken satırlar yüzde genişlikle sarılır (RN`de CSS grid yok).',
|
|
217
|
-
'`
|
|
218
|
-
'
|
|
242
|
+
'`direction: horizontal` (MOBİLE ÖZGÜ) satırları tek satırlı, göstergesiz yatay kaydırıcıda dizer — ana sayfanın bitki kartı şeridi. Öğe genişliği `itemWidth` (px; boşsa şablonun kendi `appearance` genişliği), aralık `horizontalSpacing`; `snap: item` kaydırmayı kart başına oturtur (web önizlemesinde CSS scroll-snap). `columnCount` yatayda yok sayılır. Şablon kabına `widthType: fill` verin ki kart `itemWidth`i doldursun.',
|
|
243
|
+
'GRUPLAMA bu bileşende YOKTUR: başlıklar altında liste (türe/zamana göre görevler) `grouped-list`tir — sayaç başlık şablonunda `Section.count`, toplu eylem başlıktaki bir `button` (akışı `Section.items` okur).',
|
|
244
|
+
'Çoklu seçim (MOBİLE ÖZGÜ): `selectionMode: multiple` satır başına onay kutusu çizer, dokunuş seçimi değiştirir ve `itemPress`/`change`/`select` YAYILMAZ; `selectionChange { selectedIndices, count }` yayılır. Seçim düğüme yazılır: `{{ <liste>.selectedItems.length }} seçildi`, `<liste>.selectedIndices`. `longPressSelects: true` uzun basışla kipi açar (basılan satır seçili). Kipi kapatmak: setter ile `selectionMode: \'single\'` + `selectedIndices: []` + `selectedItems: []`. Seçim başlığı ayrı bir `app-bar`dır, iki çubuk `isHidden` bağıyla yer değiştirir.',
|
|
245
|
+
'`swipeActions` (eylemin `icon`u etiketin üstünde glif olarak çizilir) ve `itemPressable` MOBİLE ÖZGÜDÜR (webde yok). Jest RN `Animated` + `PanResponder` ile kurulur — paket v1`de `reanimated`/`gesture-handler` yok — ve yalnız YATAY harekette yakalanır, böylece dikey kaydırma kaba kalır. Tasarım kipinde satırlar şablon olarak çizildiği için jest hiç bağlanmaz.',
|
|
246
|
+
'`swipe` ve `itemPress` yükleri satırı `row` alanında TAŞIR; akış ifadesindeki `Row`/`RowIndex` bağı ayrı bir konudur (ARC-121).',
|
|
247
|
+
'Düşenler: `autoRowSize` (mobil satır her zaman içeriğinin boyundadır).'
|
|
219
248
|
],
|
|
220
249
|
propNotes: {
|
|
221
250
|
itemPressable: 'Satıra dokunulabilir yapar; dokunuş önce `change { selectedIndex }`, sonra `itemPress` yayar.',
|
|
222
|
-
swipeActions: 'Sola kaydırınca açılan eylemler: `key` (zorunlu), `label`, `tone` (default · danger), `icon`. Her eylem 72 pt genişliktedir.'
|
|
251
|
+
swipeActions: 'Sola kaydırınca açılan eylemler: `key` (zorunlu), `label`, `tone` (default · danger), `icon`. Her eylem 72 pt genişliktedir.',
|
|
252
|
+
direction: '`vertical` (varsayılan) · `horizontal` — yatay şerit; `columnCount` orada yok sayılır.',
|
|
253
|
+
itemWidth: 'Yatay öğenin genişliği (px). Boşsa şablonun kendi genişliği.',
|
|
254
|
+
snap: '`none` · `item` — kaydırma kart + aralık adımına oturur.',
|
|
255
|
+
emptyTitle: 'Satır yokken çizilen boş durumun başlığı (`emptystate` görünümü). Başlık da açıklama da boşsa boş durum çizilmez.',
|
|
256
|
+
emptyDescription: 'Boş durumun açıklaması.',
|
|
257
|
+
emptyIcon: 'Boş durumun ikonu (`{ name }`, varsayılan `package_2`).',
|
|
258
|
+
selectionMode: '`single` (varsayılan, bugünkü `selectedIndex`) · `multiple` (onay kutulu çoklu seçim, `selectionChange`) · `none` (seçim izlenmez).',
|
|
259
|
+
longPressSelects: 'Uzun basış çoklu seçim kipini açar ve basılan satırı seçer.'
|
|
223
260
|
}
|
|
224
261
|
},
|
|
225
262
|
modal: {
|
|
@@ -229,7 +266,8 @@ export const mobileComponentKnowledge = {
|
|
|
229
266
|
'Görünüm temanın shadcn token`larından: perde `--overlay` yarı saydam, gövde `--background` zemin + `--border` kenar + büyük köşe + gölge. Açılış, kapanış ve olaylar değişmedi.',
|
|
230
267
|
'Gövdenin kapatma (×) düğmesinin iç rol kimliği `<elementId>__overlay` (adı tarihsel; `isDismissDisabled` açıkken çizilmez) — `page_screenshot` `click` onunla kapatır.',
|
|
231
268
|
'Tasarım kipinde HER ZAMAN açık ve YERİNDE (sayfa akışında) çizilir: kapalı bir widget`ın içi düzenlenemez; RN `Modal` react-native-web`de sayfanın tamamını kaplayan bir portal açtığı için kanvasta kullanılmaz.',
|
|
232
|
-
'`presentation` YALNIZ mobil şemadadır (web şeması değişmez; FlutterFlow BottomSheet): `center` ortadaki kutu, `sheet` alt sayfa, `fullscreen` tam ekran. Tasarım kipinde üçü de yerinde, kendi görünümüyle çizilir.'
|
|
269
|
+
'`presentation` YALNIZ mobil şemadadır (web şeması değişmez; FlutterFlow BottomSheet): `center` ortadaki kutu, `sheet` alt sayfa, `fullscreen` tam ekran. Tasarım kipinde üçü de yerinde, kendi görünümüyle çizilir.',
|
|
270
|
+
"`actions` gövdenin altında düğme satırı olarak çizilir (web `ModalActions`; 2026-09-27'ye dek mobilde hiç yoktu, f-04): basılan eylem düğümün `action` olayını eylemin akışıyla yayar, `currentItem` eylemin kaydıdır; `type: submit` eylem `action` yaymaz, `formId`'deki formu gönderir; gizli eylem çizilmez, kilitli/yükleniyor eylem basılmaz. İç rol `<elementId>__action-<key>`. `isLoading` açıkken gövdenin yerinde gösterge döner ve eylem satırı gizlenir (web)."
|
|
233
271
|
],
|
|
234
272
|
propNotes: {
|
|
235
273
|
presentation: "`center` (varsayılan; kayıtlı modallar böyle kalır) web ile aynı kutu, genişlik `size`dan. `sheet`: ekranın altına yapışık, tam genişlik, üst köşeleri yuvarlak ve tutamaçlı; cihazda alttan kayarak açılır. Tutamaç + başlık şeridinden aşağı sürükleyince — boyunun üçte biri ya da hızlı savurma — `change { isOpen: false }` ile kapanır; `isDismissDisabled` açıkken yerine döner. İçerik kendi kaydırmasını korur (sürükleme yalnız şeritte); alt sayfa en çok ekranın %90'ıdır, uzun içerik kesilir — kaydırmak için içine `scroll-view` koyun. Kapanış isteği tutmazsa (bir bağ `isOpen`'ı geri yazarsa) sayfa 300 ms sonra yerine döner. `fullscreen`: perdesiz tam ekran, çentik ve ev göstergesi payı dolguda; cihazda kayarak açılır. `size` yalnız `center`da anlamlıdır, panel diğer ikisinde gizler."
|
|
@@ -243,7 +281,8 @@ export const mobileComponentKnowledge = {
|
|
|
243
281
|
'`size` kademeleri ekran oranına iner (default 0.72 … full 1); `position` yalnız left/right.',
|
|
244
282
|
'Kaplamaya dokunuş kapatır (`__overlay` iç rolü), `isDismissDisabled` açıkken dokunuş yutulur.',
|
|
245
283
|
'`app-bar.menuTarget` bu widget`ı açar (`host.shell.openMenu` → makinede `isOpen: true`); kapanış `change { isOpen: false }` yazar, geçişte `open`/`close` yayılır.',
|
|
246
|
-
'Tasarım kipinde yerinde çizilir (modal ile aynı gerekçe).'
|
|
284
|
+
'Tasarım kipinde yerinde çizilir (modal ile aynı gerekçe).',
|
|
285
|
+
"`actions` panelin dibinde sol ve sağ grup olarak çizilir (`position: left` sola, yazılmamış ya da `right` sağa — web `filterActionsByPosition`) — olay sözleşmesi `modal` ile aynı. Seçenekli eylem (`options`) satırın altında bir liste açar; seçenek ANA eylemin akışını `currentItem` = seçenekle koşturur (web). İç roller `<elementId>__action-<key>` ve `<elementId>__action-<key>-<seçenek>`. `isLoading` açıkken gövde yerine gösterge döner, eylem satırı gizlenir."
|
|
247
286
|
]
|
|
248
287
|
},
|
|
249
288
|
'app-bar': {
|
|
@@ -252,8 +291,15 @@ export const mobileComponentKnowledge = {
|
|
|
252
291
|
'Web`de karşılığı YOKTUR — mobile özgü şema (web `header` sayfa akışının parçasıdır, bu ekranın kabuğudur).',
|
|
253
292
|
'`leading: auto` runtime`da `host.shell.canGoBack`tan çözülür: geri gidilebiliyorsa geri, gidilemiyorsa `menuTarget` varsa menü, yoksa boş. Tasarım kipinde çubuk boş kalmasın diye menü/geri çizilir.',
|
|
254
293
|
'İç roller `__back`, `__menu`, `__action-<key>` (K2 kalıbı); `page_screenshot` eylemleri bunları kullanır.',
|
|
255
|
-
'Üst güvenli alan payı çubuğun işi DEĞİLDİR: düz kanvas kararından (D15) sonra payı kullanıcı `SafeAreaView` ile kurar.'
|
|
256
|
-
|
|
294
|
+
'Üst güvenli alan payı çubuğun işi DEĞİLDİR: düz kanvas kararından (D15) sonra payı kullanıcı `SafeAreaView` ile kurar.',
|
|
295
|
+
'`subtitle` başlığın altındaki ikinci satırdır ("12 bitki · 3 oda"). `actions[].badge` eylemin köşe rozetidir: `•` okunmamış noktası, sayı ya da kısa metin; ton `badgeKind` (varsayılan error).',
|
|
296
|
+
'`variant: transparent` görselin üstünde yüzen çubuktur (bitki detayı): zemin/kenar yok, düğmeler 44 px yarı saydam yuvarlak, glif ve başlık beyaz. Çubuk kendi katmanını KURMAZ: `stack` → çocuk 0 görsel, çocuk 1 `fill`×`fill` `container` → içinde `app-bar`.',
|
|
297
|
+
'Seçim kipi başlığı ayrı bir `app-bar`dır: başlık `{{ (liste.selectedItems || []).length + \' seçildi\' }}`, normal çubukla `isHidden` bağıyla yer değiştirir. Selamlama başlığı (tarih + "Günaydın" + avatar) çubuğa değil sayfa içeriğine konur; çubuğun çocuk yuvası yoktur.'
|
|
298
|
+
],
|
|
299
|
+
propNotes: {
|
|
300
|
+
subtitle: 'Başlığın altındaki ikinci satır.',
|
|
301
|
+
variant: '`default` · `transparent` (görsel üstünde, `stack` ile).'
|
|
302
|
+
}
|
|
257
303
|
},
|
|
258
304
|
badge: {
|
|
259
305
|
summary: 'Sayaç ya da durum rozeti; taşma (99+) ve nokta kipi var.',
|
|
@@ -262,28 +308,39 @@ export const mobileComponentKnowledge = {
|
|
|
262
308
|
'İkon İSTEĞE BAĞLIDIR ve verilmediğinde ÇİZİLMEZ — ortak ikon çözücü boş prop`ta `star`a düştüğü için bu slug prop`un gerçekten verilip verilmediğine kendisi bakar.'
|
|
263
309
|
],
|
|
264
310
|
propNotes: {
|
|
265
|
-
color: 'Renk SINIFTAN gelir (`bg-status-*`); `custom` seçilirse `customColor` ham renktir.',
|
|
311
|
+
color: 'Renk SINIFTAN gelir (`bg-status-*`); `custom` seçilirse `customColor` ham renktir (dolu rozette zemin, çerçevelide kenar + metin). `textColor`/`customTextColor` metni boyar. `click` bağlıysa rozet düğmedir.',
|
|
266
312
|
maxCount: 'Aşıldığında metin `<maxCount>+` olur (99 → `99+`). Web ikiziyle aynı beş altın vaka `badge-logic.spec.ts`te kilitli.'
|
|
267
313
|
}
|
|
268
314
|
},
|
|
269
315
|
avatar: {
|
|
270
316
|
summary: 'Kullanıcı avatarı: görsel, baş harf yedeği ve `+N` grup kipi.',
|
|
271
317
|
differences: [
|
|
272
|
-
'Grup kipinde üst üste binme `spacing`
|
|
318
|
+
'Grup kipinde üst üste binme `spacing` YÜZDESİdir (web "Group overlap (%)"; boşsa %30) ve negatif kenar boşluğuyla çizilir; web`in `z-index` katmanı yerine çizim SIRASI belirler. 2026-09-28`e dek mobil `spacing`i okumuyordu.',
|
|
319
|
+
'Web anlamıyla (2026-09-28): baş harf zemini `color` (ya da `isColorful` ile addan deterministik), `hasRing` 2 px halka (`ringColor`), `status` (online · away · busy · offline) sağ altta nokta, köşe rozeti `badgeValue` (99+) ya da MOBİLE ÖZGÜ `badgeIcon` (glif, ör. `photo_camera` — profil fotoğrafı düzenleme rozeti; doluysa metne üstündür, renk `badgeColor`). `click` bağlıysa avatar düğmedir. Grup boşsa `emptyText`.',
|
|
320
|
+
"`src` (ve grup kipinde öğelerin görseli) `image` ile aynı çözümden geçer: kayıttaki FILE alanını nesne olarak verin (`{{ item.foto }}`) ya da `.absolute_path` yazın; `.value` dosya kimliğidir, görsel yerine baş harfler çizilir (MOB-011)."
|
|
273
321
|
]
|
|
274
322
|
},
|
|
275
323
|
progress: {
|
|
276
|
-
summary: '
|
|
324
|
+
summary: 'İlerleme göstergesi: çubuk, halka ya da parçalı çubuk; eşiklere göre renk değiştirir.',
|
|
277
325
|
differences: [
|
|
278
|
-
'`variant` (
|
|
326
|
+
'`variant: bar | circle | segmented`. `circle` halkadır (ana sayfa "3/5 görev" özeti): çap `size`dan, çizgi `thickness` (px); ortada değer (`labelFormat: fraction` → "3 / 5") ve MOBİLE ÖZGÜ `circleCaption` alt satırı. `segmented` MOBİLE ÖZGÜ: `segments` (2–10) parçadan `floor(yüzde × parça)` kadarı dolu, aralık `segmentGap` — sihirbaz adımları, parola gücü.',
|
|
327
|
+
'Renk: eşik listesi (`thresholds`) web kuralıyla — yüzdeyi geçmeyen EN YÜKSEK eşik kazanır, liste sırası değil; liste boşsa gizli `colorMap`. `color: custom` + `customColor` ham renk, `trackColor`/`customTrackColor` iz, `thickness` çubuk/parça boyu. Parçalı çubukta dolu parçalar da eşik rengini alır (parola gücü: kırmızı → sarı → yeşil).',
|
|
328
|
+
'Olaylar web ile aynı: `click` bağlıysa gösterge düğmedir; `complete` değer en üste İLK ulaşınca bir kez (düşüp yeniden ulaşınca yine bir kez).',
|
|
329
|
+
'`isStriped` ve `isIndeterminate` DÜŞÜRÜLDÜ: ikisi de sürekli hareket ister (bileşen içi hareket ayrı iş).',
|
|
279
330
|
'Kutu satırın tamamını kaplar (`width: 12`).'
|
|
280
|
-
]
|
|
331
|
+
],
|
|
332
|
+
propNotes: {
|
|
333
|
+
variant: '`bar` (varsayılan) · `circle` · `segmented` (mobile).',
|
|
334
|
+
segments: 'Parçalı çubukta parça sayısı (2–10, varsayılan 5).',
|
|
335
|
+
circleCaption: 'Halkada değerin altındaki satır ("görev").'
|
|
336
|
+
}
|
|
281
337
|
},
|
|
282
338
|
radio: {
|
|
283
339
|
summary: 'Tek seçimli seçenek listesi.',
|
|
284
340
|
differences: [
|
|
285
341
|
'`autofocus` DÜŞÜRÜLDÜ: mobilde odak kavramı yoktur.',
|
|
286
|
-
'
|
|
342
|
+
'Dizilim mobile özgü alanlarla: `columns` 2–5 ızgaradır (üç ve daha çok sütunda kart karo olur: görsel/ikon üstte, gösterge yok, seçim kenardan okunur), yoksa `direction: horizontal` sarar, varsayılan alt alta.',
|
|
343
|
+
'`variant: card` kenarlıklı karo (seçili kenar vurgu rengi). Seçenek alanları (mobil): `caption` ikinci satır, `icon`, `image` (76 px küçük resim), `isDisabled`. Seçim seçeneği ÖZGÜN tipinde yayar (`34` sayı kalır).',
|
|
287
344
|
'Seçeneğin iç rol kimliği `<elementId>__option-<değer>` (runtime\'da `data-element-id`) — `page_screenshot` `click` seçeneğe onunla basar.'
|
|
288
345
|
]
|
|
289
346
|
},
|
|
@@ -292,15 +349,18 @@ export const mobileComponentKnowledge = {
|
|
|
292
349
|
differences: [
|
|
293
350
|
'`autofocus` ve `columnCount` DÜŞÜRÜLDÜ: çok sütun telefon genişliğinde dokunma hedefini bozar; yerine `direction: horizontal` sarmalı kullanılır.',
|
|
294
351
|
'Kutu satırın tamamını kaplar (`width: 12`).',
|
|
295
|
-
'
|
|
352
|
+
'`variant: card`, `options[].caption`/`icon`, `gap`, `align` ve `isViewmode` web gibi çizilir (radyonun kart parçası ortak). Seçim seçenekleri ÖZGÜN tipinde yayar.',
|
|
353
|
+
'İç roller `<elementId>__option-<değer>` ve (`showSelectAll` açıkken) `<elementId>__select-all` — `page_screenshot` `click` onlarla basar.',
|
|
354
|
+
'Düşenler: `focus`/`blur` olayları (grubun klavye odağı yok, tek sinyal değer değişimidir).'
|
|
296
355
|
]
|
|
297
356
|
},
|
|
298
357
|
'choice-chips': {
|
|
299
358
|
summary: 'Dokunma için boyutlandırılmış, satır sarmalı seçilebilir çip dizisi. Web`de karşılığı YOKTUR.',
|
|
300
359
|
differences: [
|
|
301
360
|
'Mobile özgü şema: web`de bu işi `checkboxgroup`/`radio` görür; dokunmatikte çip dizisi daha az yer kaplar.',
|
|
302
|
-
'`multiple` açıkken `value`
|
|
303
|
-
'
|
|
361
|
+
'`multiple` açıkken `value` DİZİDİR (akış dizi yazar ve okur); panelde virgüllü metin (`"a, b"`) yazılabilir, okunurken diziye açılır. Kapalıyken tek değer. Seçim seçeneği ÖZGÜN tipinde yayar (`34` sayı kalır).',
|
|
362
|
+
'`variant: segmented` aynı seçenekleri hap şeritte çizer (ml | L, İç / Dış); `chips` (varsayılan) çip dizisidir. `scrollable` çipleri tek satırda yatay kaydırır (göstergesiz), kapalıyken sarar. Seçili çipte ✓ (`showCheck`, varsayılan açık). `kind: neutral` seçili çipi ön plan renginde doldurur (koyu filtre şeridi).',
|
|
363
|
+
'Seçenek alanları: `icon` (isteğe bağlı, verilmezse çizilmez), `badge` (sayaç; `99+` sınırlı, `0` çizilmez) + `badgeKind`, `isDisabled` (soluk, seçilemez).',
|
|
304
364
|
'Çipin iç rol kimliği `<elementId>__chip-<değer>` — `page_screenshot` `click` çipe onunla basar.'
|
|
305
365
|
]
|
|
306
366
|
},
|
|
@@ -309,7 +369,8 @@ export const mobileComponentKnowledge = {
|
|
|
309
369
|
differences: [
|
|
310
370
|
'Bırakılabilir bir KAPTIR (`isDroppable`), gövdesi çocuklardır.',
|
|
311
371
|
'Açılma animasyonu YOKTUR: yükseklik anında değişir (düzen animasyonu bu dalgada kullanılmadı).',
|
|
312
|
-
'Başlığa basmak web ile AYNI olayı yayar (`expanded`/`collapsed { isOpen }`); makine `isOpen`\'ı yazar ve gövde açılıp kapanır. Tetikleyicinin iç rol kimliği `<elementId>__trigger` — `page_screenshot` `click` onunla basar.'
|
|
372
|
+
'Başlığa basmak web ile AYNI olayı yayar (`expanded`/`collapsed { isOpen }`); makine `isOpen`\'ı yazar ve gövde açılıp kapanır. Tetikleyicinin iç rol kimliği `<elementId>__trigger` — `page_screenshot` `click` onunla basar.',
|
|
373
|
+
'Düşenler: `openButtonVariant`, `closeButtonVariant` (mobil başlığın tamamı dokunulur ve ok çizer, ayrı aç/kapat düğmesi yok).'
|
|
313
374
|
]
|
|
314
375
|
},
|
|
315
376
|
slider: {
|
|
@@ -317,7 +378,9 @@ export const mobileComponentKnowledge = {
|
|
|
317
378
|
differences: [
|
|
318
379
|
'`marks`, `showTicks` ve `autofocus` DÜŞÜRÜLDÜ.',
|
|
319
380
|
'Jest `PanResponder` ile çözülür ve YALNIZ YATAY sürüklemeyi yakalar: dokunuşu başlangıçta yakalasaydı sayfa kaydırması değeri değiştirirdi (ölçüldü — kaydırma 40`ı 100 yapıyordu).',
|
|
320
|
-
'Sürüklerken `change`, parmak kalkınca `changed` yayılır; akış genelde `changed`e bağlanır. İze dokunuş değeri o noktaya getirir (`change` + `changed`). Jest `modal`/çekmece içinde de çalışır.'
|
|
381
|
+
'Sürüklerken `change`, parmak kalkınca `changed` yayılır; akış genelde `changed`e bağlanır. İze dokunuş değeri o noktaya getirir (`change` + `changed`). Jest `modal`/çekmece içinde de çalışır.',
|
|
382
|
+
'Düşenler: `focus`/`blur` olayları (sürgünün klavye odağı yok; sürükleme ve bırakma olayları yeter).',
|
|
383
|
+
'`color`/`customColor` dolguyu ve başın kenarını boyar (web `--slider-color`).'
|
|
321
384
|
]
|
|
322
385
|
},
|
|
323
386
|
tabs: {
|
|
@@ -325,7 +388,9 @@ export const mobileComponentKnowledge = {
|
|
|
325
388
|
differences: [
|
|
326
389
|
'İçerik modeli web ile AYNI: her sekmenin gövdesi SIRADAKİ çocuk düğümdür — etkin sekmenin (`selected` anahtarı) `tabs` dizisindeki sırası hangi çocuğun çizileceğini seçer; gizli/pasif sekme sırayı kaydırmaz.',
|
|
327
390
|
'Basılan sekme web ile AYNI olayı yayar (`tab { selected }`); makine `selected`\'ı yazar ve gövde değişir. Sekmenin iç rol kimliği `<elementId>__tab-<anahtar>` (runtime\'da `data-element-id`) — `page_screenshot` `tab` onu anahtarla bulur.',
|
|
328
|
-
'Sekme başlıkları taşarsa yatay kaydırılır; telefonda sarmalanmaz.'
|
|
391
|
+
'Sekme başlıkları taşarsa yatay kaydırılır; telefonda sarmalanmaz.',
|
|
392
|
+
'`variant` web gibi çizilir: `default` alt çizgi, `container` (varsayılan) kutulu şerit + çerçeveli gövde; mobile özgü `segmented` hap şerittir (Bugün / Yaklaşan / Geciken). `headerAlign` sola/ortaya/sağa yaslar, `stretch` sekmeleri eşit yayar.',
|
|
393
|
+
'Sekme sayaç rozeti taşır (`tabs[].badge` + `badgeKind`; `99+` sınırlı, `0` çizilmez) — "Geciken 3" için rozeti akışın sayısına bağla.'
|
|
329
394
|
]
|
|
330
395
|
},
|
|
331
396
|
tooltip: {
|
|
@@ -383,7 +448,8 @@ export const mobileComponentKnowledge = {
|
|
|
383
448
|
differences: [
|
|
384
449
|
'Matris `toqr` ile üretilir ve düz görünümlerle çizilir (`react-native-svg` yok); hata düzeltme `M` sabittir ve web\'in `errorCorrectionLevel` prop\'u mobil şemadan düşer; renk web gibi siyah üstüne beyaz — koyu temada da (okuyucular ters kodu her zaman okumaz).',
|
|
385
450
|
'Kare kutunun kenarı: genişliği belli düğümde (`widthType: fill` ya da `fixed`) düğümün genişliği, içerik genişliğinde (`auto` ya da `widthType` hiç yazılmamış) 200 dp; genişlik ölçülemezse de (kanvasta satır kabındaki `fill`) 200 dp — cihaz o düğümü tam genişlik çizer. Sabit px boy kenarı sınırlar. Modül ölçüsü tam sayıya iner, artan birkaç piksel ortalanır. Belirli boy için `appearance.widthType: fixed` + `widthString`.',
|
|
386
|
-
'Veri boşsa ya da QR`a sığmıyorsa (yaklaşık 2,3 KB üstü) yer tutucu çizilir. `quietZone` web ile aynı `common` grubundadır (eski adı `padding` ortak çizim katmanının CSS boşluğuyla çakışıyordu, CQ-272).'
|
|
451
|
+
'Veri boşsa ya da QR`a sığmıyorsa (yaklaşık 2,3 KB üstü) yer tutucu çizilir. `quietZone` web ile aynı `common` grubundadır (eski adı `padding` ortak çizim katmanının CSS boşluğuyla çakışıyordu, CQ-272).',
|
|
452
|
+
"`click` bir akışa bağlıysa kod runtime'da basılır (web gibi); bağlı değilse dokunuşu yutmaz. QR'a sığmayan veri `error { errorText }`ü makine başına bir kez yayar (satırdaki seçim değişimi yeniden yaydırmaz)."
|
|
387
453
|
],
|
|
388
454
|
propNotes: {
|
|
389
455
|
quietZone: 'Sessiz bölge, MODÜL birimiyle (piksel değil); varsayılan 1, panel aralığı web şemasıyla aynı 1–10 (çizer 16\'ya kadar kabul eder). Okuyucular için 2–4 önerilir.'
|
|
@@ -395,7 +461,8 @@ export const mobileComponentKnowledge = {
|
|
|
395
461
|
'İLK çocuk taban katmandır: akışta durur ve yığının boyunu verir. Sonraki her çocuk onun ÜSTÜNE biner; dizi sırası çizim sırasıdır (sonraki üstte).',
|
|
396
462
|
'Üst katmanlar yığının `alignment`ıyla (9 nokta) hizalanır; kaydırmayı çocuğun kendi kenar boşluğu verir (ör. `bottom-right` + sağ/alt margin 8). Hizalama ÇOCUKTA değil yığındadır — `appearance.stackAlign` diye bir alan YOKTUR.',
|
|
397
463
|
'Farklı köşelerde katman için çocuk kap iki eksende `fill` olur (yığını kaplar) ve içeriğini kendi `horizontalAlign`/`verticalAlign`ı ile yerleştirir.',
|
|
398
|
-
'Katmanın boş alanı dokunuşu alttaki katmana geçirir. Çocuklar `blocks` taşımaz (MOB-001 aynen geçerli).'
|
|
464
|
+
'Katmanın boş alanı dokunuşu alttaki katmana geçirir. Çocuklar `blocks` taşımaz (MOB-001 aynen geçerli).',
|
|
465
|
+
'Bindirme tarifleri (ölçüldü f-08, oyun alanı `bindirme`): sağlık rozeti = `alignment: top-right` + oranlı görsel taban + rozet (margin 8); görsel üstü düğmeler ve alttaki hap = iki `fill`×`fill` kap katmanı (biri `verticalAlign: top` + satır `space-between`, öbürü `bottom`/`right`); açıklama bandı = `bottom-left` + yarı saydam zeminli `fill` genişlikte kap; arka plan görseli = `fit: fill` sabit boylu görsel taban + ortalanmış içerik. Taban oranlı görselse (`aspectRatio`) yığının boyu doğru çıkar.'
|
|
399
466
|
],
|
|
400
467
|
propNotes: {
|
|
401
468
|
alignment: "Üst katmanların yeri: `top-left` (varsayılan) · `top-center` · `top-right` · `center-left` · `center` · `center-right` · `bottom-left` · `bottom-center` · `bottom-right`. Yığının boyu kutudan geliyorsa (`fixed`, `fill`, oran) taban da bu noktaya hizalanır."
|
|
@@ -406,6 +473,7 @@ export const mobileComponentKnowledge = {
|
|
|
406
473
|
differences: [
|
|
407
474
|
'Satıra dokunuş `click` yayar (yük yok). Pasifken soluk ve basılamaz; tasarım kipinde basış kanvasın seçim jestidir.',
|
|
408
475
|
'Baş tarafta `leadingImage` `leadingIcon`dan önce gelir (40 dp yuvarlak görsel; yüklenmezse başlığın baş harfleri). Boş ikon çizilmez.',
|
|
476
|
+
"`leadingImage` `image` ile aynı çözümden geçer: kayıttaki FILE alanını nesne olarak verin (`{{ item.foto }}`) ya da `.absolute_path` yazın; `.value` dosya kimliğidir (GUID), görsel çizilmez (MOB-011).",
|
|
409
477
|
'Ölçüler Material liste satırı: tek satır 56, alt başlıklı 72; `dense` 48 / 60. Renkler token sınıflarından (başlık `--foreground`, alt başlık ve son taraf `--muted-foreground`, basılıyken `--accent`).',
|
|
410
478
|
'Son tarafta anahtar YOKTUR: anahtarlı satır `container` (satır) + `text` + `switch` ile kurulur. Tekrarlayıcı içinde satır olarak kullanılır — `repeater` satırının akışı tıklanan satırı `<tekrarlayıcı>.selectedItem` ile okur.'
|
|
411
479
|
]
|
|
@@ -417,7 +485,8 @@ export const mobileComponentKnowledge = {
|
|
|
417
485
|
'Mobilde bırakılabilir: çocuğu varsa her ÇOCUK bir sayfadır ve `items` okunmaz (`tabs` gövde modeli); çocuksuz kaydırıcı `items` görsellerini çizer. Kanvasta yalnız `activeIndex` sayfası çizilir — sayfa seçici paneldeki bu alandır.',
|
|
418
486
|
'Görsel sayfaya dokunuş web gibi yalnız bağlantısı ya da akışı olan sayfada `slideClick { currentItem, index }` yayar; dış adres (http(s), mailto, tel, alan adı) sistem tarayıcısında açılır, uygulama içi yol (`/sayfa`) açılmaz — gezinmeyi `slideClick` akışı yapar.',
|
|
419
487
|
'Düşenler: `style`, `pauseOnHover` (sürükleme oynatmayı zaten durdurur), `transition` (sayfalar kayar). Ek: `peek`. Oklar `<elementId>__prev`/`__next`, noktalar `<elementId>__dot-<n>` iç rolleri — `page_screenshot` `click` onlarla basar.',
|
|
420
|
-
'Boy kutudan gelmiyorsa görsel sayfa 16:9, çocuk sayfalar en uzununun boyunda. Genişlik belli değilse (Studio`dan bırakılan düğümün `widthType`ı yok) cihaz genişliği kullanılır; kaydırıcıya `widthType: fill` verin.'
|
|
488
|
+
'Boy kutudan gelmiyorsa görsel sayfa 16:9, çocuk sayfalar en uzununun boyunda. Genişlik belli değilse (Studio`dan bırakılan düğümün `widthType`ı yok) cihaz genişliği kullanılır; kaydırıcıya `widthType: fill` verin.',
|
|
489
|
+
'Düşenler: `slidesPerView`, `slidesToScroll`, `isCentered`, `autoWidth`, `orientation` (mobil kaydırıcı tek sayfa kaydırır, komşu sayfa `peek` ile görünür), `lazyLoad`, `lazyLoadEager` (RN görseli görünür olunca yükler).'
|
|
421
490
|
],
|
|
422
491
|
propNotes: {
|
|
423
492
|
peek: 'Komşu sayfaların kenardan görünen payı (dp); en çok genişliğin dörtte biri, sayfalar araya küçük boşluk alır. 0 (varsayılan) tam genişlik sayfa.'
|
|
@@ -428,7 +497,7 @@ export const mobileComponentKnowledge = {
|
|
|
428
497
|
differences: [
|
|
429
498
|
'Sayfanın NERESİNE konursa konsun runtime`da barındırıcının ekran katmanına taşınır: kenardan 16 dp, sekme çubuğu varsa onun üstünde, yoksa ev göstergesinin üstünde. Düğümün kendi yeri akışta boş kalır — sayfa kök kabının sonuna koyun.',
|
|
430
499
|
'Dokunuş `click` yayar. `page_screenshot` düğmeyi `<elementId>__press` ile bulur (düğüm kabuğu runtime`da boştur).',
|
|
431
|
-
'Renk `kind`den, `button` ile aynı eşleme (dolu varyant); 56 dp
|
|
500
|
+
'Renk `kind`den, `button` ile aynı eşleme (dolu varyant); yuvarlak, kenarı `size`dan (`default` 56 · `large` 60 dp). `extended` açık ve `label` doluysa etiket ikonun yanında yazılır. Ekran okuyucu adı sırayla `ariaLabel` → `label` → ikonun adı.',
|
|
432
501
|
'Kanvasta yerinde, kesikli bir halka içinde çizilir ve basılamaz.'
|
|
433
502
|
],
|
|
434
503
|
propNotes: {
|
|
@@ -436,6 +505,64 @@ export const mobileComponentKnowledge = {
|
|
|
436
505
|
icon: 'Material Symbols adı; boşsa `add`.'
|
|
437
506
|
}
|
|
438
507
|
},
|
|
508
|
+
eventcalendar: {
|
|
509
|
+
summary: 'Etkinlik takvimi (web ikizi): satırları ay ızgarasında renkli nokta, hafta şeridinde gün ve gün çizelgesinde saat bloğu olarak çizer.',
|
|
510
|
+
differences: [
|
|
511
|
+
'Alan adları web ile AYNI: `rows` + eşleme alanları (`titleField`, `startField`, `endField`, `colorField`, `idField`, `allDayField`); eşleme, gün süzme ve gün yerleşimi web modüllerinden gelir. Renk anlamsal ad (`primary`, `success`, `warning`, `error`) ya da ham renk. Varsayılan temada `info` bir renk değil nötr yüzeydir (#F8F8F8) — etkinlikte görünmez, kullanmayın.',
|
|
512
|
+
'`defaultView: month | week | day`. Ay: günde en çok `maxVisibleEvents` (varsayılan 3) nokta, fazlası `+`; seçili gün dolgulu, altında `dayCountLabel` sayacı (`{n} görev`); geçmiş günler `pastDimmed` ile soluk. Hafta: 7 günlük şerit, yatay kaydırma haftayı değiştirir. Gün: `startHour`–`endHour` saat satırları, çakışan bloklar yan yana, süresiz satır 30 dk, `doneField` doluysa blok soluk, bugünde "şimdi" çizgisi.',
|
|
513
|
+
'MOBİLE ÖZGÜ: `pastDimmed`, `showTodayButton`, `legend` (açık `{label, color}` listesi — satırlardan türetilmez), `dayCountLabel`, `doneField`.',
|
|
514
|
+
'Olaylar web sözleşmesiyle, yük `event.data`da (düğüme yazılmaz): `dateClick { date, rows }` (mobilde günün satırları da gelir — seçili günün görevlerini alttaki `repeater`a setter ile `event.data.rows` yazın), `eventClick { id, title, row }` (gün çizelgesinde), `monthChange { month, year, view, start, end }` (oklar, kaydırma ve Bugün — her görünümde), `viewChange { view, start, end }`.',
|
|
515
|
+
'Düşenler: `isEditable`/`isCreatable` ve `eventMove`/`eventCreate` (sürükleme jesti), `agendaDays` (liste görünümü `grouped-list` ile), `isLoading`.'
|
|
516
|
+
],
|
|
517
|
+
propNotes: {
|
|
518
|
+
rows: 'Etkinlik satırları; genelde sorguya kod bağıyla: `{ type: \'code\', ref: \'{{ q_gorevler.data }}\' }`.',
|
|
519
|
+
defaultDate: '`yyyy-MM-dd`; açılışta seçili gün ve görünen dönem.',
|
|
520
|
+
legend: 'Renk açıklaması: `[{ label: \'Sulama\', color: \'primary\' }]`.',
|
|
521
|
+
dayCountLabel: 'Seçili günün sayaç kalıbı, `{n}` sayıdır. Boşsa uygulama dilinde "{n} etkinlik".'
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
'grouped-list': {
|
|
525
|
+
summary: 'Gruplu liste (FlutterFlow GroupedListView): düz `rows`u `groupBy` alanına göre bölümlere ayırır, her bölümü bir başlık ve öğeleriyle çizer. İç içe repeater (PAGE-013) yerine gün/kategori başlıklı liste budur. Web`de karşılığı YOKTUR.',
|
|
526
|
+
differences: [
|
|
527
|
+
'Çocuklar KONUMSAL şablondur: çocuk 0 bölüm başlığı, çocuk 1 öğe şablonu; fazlası çizilmez. Tasarım kanvasında iki şablon bir kez, alt alta çizilir.',
|
|
528
|
+
'Öğe repeater satırıyla AYNI params`ı alır (`index` = `rows` içindeki DÜZ indeks, `row`, `repeaterId`): bağlı prop`larda `Row`, `RowIndex`, `{{ item.<alan> }}` iki yönlü bağ; akışta tıklanan satır `<liste>.selectedItem`; satır kapsamlı yazım (`_repeaterValues`) repeater`daki gibi.',
|
|
529
|
+
'Başlık ifadelerde `Section` okur: `{ key, title, count, items }` — ör. `{{ Section.title }} · {{ Section.count }}`. Başlık satır kapsamı TAŞIMAZ (salt okunur, `Row`/`item` boş). `Section` ayrılmış addır: aynı adlı komponent ifade bağlamından süzülür.',
|
|
530
|
+
'Gruplama: tarih/saat değeri cihazın yerel gününe (`YYYY-AA-GG`) indirgenir, diğer değer metne; başlık = anahtar (biçimli başlık için `Section.key` ile ifade yazın). Alanı boş/eksik satırlar en sondaki `otherSectionTitle` bölümüne düşer.',
|
|
531
|
+
'Yapışkan başlık (`stickySectionHeaders`) yalnız boyu kabuktan gelen listede çalışır ve cihazda/önizlemede SINIRLI boy ister: `appearance.heightType: fixed` + `heightString` verin. `auto`da liste düz akıştır; sayfanın kaydırıcısı içindeki `fill` içerik kadar uzar, iç kaydırıcı oluşmaz, başlık yapışmaz.',
|
|
532
|
+
'Öğe şablonu basılabilir bir bileşense (`list-item`, `button`) dokunuş onun `click`ine gider ve `itemPress` yayılmaz (repeater ile aynı); `itemPress` için şablonu basılamayan bir kap yapın ya da akışı `list-item.click`e bağlayın (satır seçimi yine olur).',
|
|
533
|
+
'Çoklu seçim `repeater` ile AYNI sözleşmedir: `selectionMode: multiple` (onay kutusu, dokunuş seçer, `itemPress` yayılmaz), `longPressSelects`, `selectionChange { selectedIndices, count }`, düğümde `selectedIndices`/`selectedItems` — gruplu görev listesinde toplu Ertele/Tamamla.',
|
|
534
|
+
'v1`de yok: `columnCount`, sanallaştırma, başlıktan yazan akış. Studio`nun satır farkında yerleri (Bind modalı `Row` önerisi, setter satır hedefi) yalnız `repeater`ı tanır — `grouped-list` içinde `Row`/`item` ifadesini elle yazın.'
|
|
535
|
+
],
|
|
536
|
+
propNotes: {
|
|
537
|
+
rows: 'Düz satır dizisi (repeater `rows` ile aynı biçim); genellikle bir sorgu/microservice sonucuna kod bağıyla verilir: `{ type: \'code\', ref: \'{{ q_tasks.data }}\' }`.',
|
|
538
|
+
groupBy: 'Bölüm anahtarının alan yolu, noktalı olabilir (`dueDate`, `plant.room`). Boşsa tek bölüm.',
|
|
539
|
+
sectionOrder: '`asc` (varsayılan, sayısal farkında) · `desc` · `asis` (verideki ilk görülme sırası).',
|
|
540
|
+
otherSectionTitle: 'Alanı boş satırların bölüm başlığı; varsayılan `Other`.',
|
|
541
|
+
stickySectionHeaders: 'Başlıklar kaydırırken üstte kalır — yalnız `heightType: fixed` (ya da sınırlı boylu `fill`/oran) listede; başlık kabına kendi zeminini verin.',
|
|
542
|
+
itemPressable: 'Öğeye dokunulabilir yapar; dokunuş önce `change { selectedIndex }`, sonra `itemPress { index, row }` yayar.',
|
|
543
|
+
swipeActions: 'repeater ile aynı: `key` (zorunlu), `label`, `tone` (default · danger), `icon`; sola kaydırınca açılır, `swipe { key, index, row }` yayar.',
|
|
544
|
+
itemSpacing: 'Öğeler arası dikey boşluk (dp), varsayılan 0.',
|
|
545
|
+
selectionMode: 'repeater ile aynı: `single` · `multiple` · `none`.',
|
|
546
|
+
longPressSelects: 'Uzun basış çoklu seçim kipini açar.'
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
'floating-container': {
|
|
550
|
+
summary: 'Ekrana sabit kap: çocuklarını ekranın dokuz noktasından birine sabitler, sayfa kayarken yerinde kalır (FAB`dan fazlası: alt eylem çubuğu, üst şerit, köşe rozeti). Web`de karşılığı YOKTUR.',
|
|
551
|
+
differences: [
|
|
552
|
+
'Mobil şemalarda `style.position`/`zIndex` yoktur (MOB-002); ekrana sabit içerik bu kapla kurulur. Sayfanın NERESİNE konursa konsun runtime`da çocukları barındırıcının ekran katmanına taşınır; kapsayıcının (`scroll-view`, `card`) kırpmasından etkilenmez. Düğümün kendi yeri akışta boş kalır — sayfa kök kabının sonuna koyun.',
|
|
553
|
+
'Katmanın dibi sekme çubuğunun tepesidir (çubuk yoksa alt güvenli alan); üst çapa üst güvenli alandan ölçülür. `aboveTabBar` diye bir prop YOKTUR — kap sekme çubuğunun üstüne çıkamaz.',
|
|
554
|
+
'App-bar sayfa içeriğidir ve sayfayla kayar: üst çapalı kap app-bar`ın üstüne biner. App-bar`ı sabit (kaydırmayı alttaki `scroll-view` yapan) sayfada app-bar`ın altına `offsetY` ile inin (ör. 72).',
|
|
555
|
+
'Yüzey ve kenar boşluğu prop`u YOKTUR: zemin, köşe, gölge ve iç boşluğu İÇERİDEKİ kaba verin (ör. `container` + `surfaceStyle`). Çerçevenin boş alanı dokunuşu alttaki sayfaya geçirir.',
|
|
556
|
+
'Kanvasta yerinde, kesikli çerçeve içinde sütun olarak çizilir. Yalnız alt köşede tek bir yuvarlak düğme için hazır `fab` yeter; etiketli çubuk, birden çok düğme ya da üst/orta çapa için `floating-container`.'
|
|
557
|
+
],
|
|
558
|
+
propNotes: {
|
|
559
|
+
anchor: '9 nokta (`stack.alignment` sözlüğü): `top-left` · `top-center` · `top-right` · `center-left` · `center` · `center-right` · `bottom-left` · `bottom-center` · `bottom-right` (varsayılan).',
|
|
560
|
+
offsetX: 'Çapalı kenardan içeri yatay pay (dp), varsayılan 16; orta eksende +sağa. `fullWidth` açıkken yok sayılır ve panelde gizlenir.',
|
|
561
|
+
offsetY: 'Çapalı kenardan içeri dikey pay (dp), varsayılan 16; orta eksende +aşağı.',
|
|
562
|
+
fullWidth: 'Çerçeve yan güvenli alanlar arasında satırı kaplar — alt eylem çubuğu (`bottom-center`) ya da üst şerit (`top-center`) için.',
|
|
563
|
+
respectSafeArea: 'Varsayılan açık: çentik/ev göstergesi payı bırakılır. Kapatınca çerçeve ekran kenarına kadar iner.'
|
|
564
|
+
}
|
|
565
|
+
},
|
|
439
566
|
timer: {
|
|
440
567
|
summary: 'Geri sayım ya da kronometre (FlutterFlow Timer). Web`de karşılığı YOKTUR.',
|
|
441
568
|
differences: [
|
|
@@ -454,7 +581,7 @@ export const mobileComponentKnowledge = {
|
|
|
454
581
|
'Yıldıza dokunuş `change { value }` yayar; `allowHalf` açıkken yıldızın SOL yarısı ayrı dokunma alanıdır ve yarım puan verir. İç roller: `<elementId>__star-<n>` (1`den; tam puan — yarım açıkken yıldızın sağ yarısı) ve `<elementId>__star-<n>-half` (sol yarı) — `page_screenshot` `click` onlarla basar.',
|
|
455
582
|
'Ekran okuyucuda yıldız şeridi TEK ayarlanabilir öğedir: değeri okunur, yukarı/aşağı kaydırma web`in ok tuşu adımıyla arttırır/azaltır (yarım açıkken 0,5). Pasif (`isDisabled`) soluk çizilir.',
|
|
456
583
|
'Cihazın ikon yazı tipi dolgusuzdur: varsayılan yıldız Unicode ★ ile iki hâlde de dolu çizilir, hâl RENKLE ayrışır (`inactiveColor` `default` kenar rengi, öteki tonlar soluk). Seçilen `icon` glif olarak kalır ve dolu/boş yalnız renkle ayrışır.',
|
|
457
|
-
'`focus`/`blur`
|
|
584
|
+
'Düşenler: `style`, `autofocus` ve `focus`/`blur` olayları (yıldız şeridinin klavye odağı yok, tek sinyal değer değişimidir).'
|
|
458
585
|
]
|
|
459
586
|
},
|
|
460
587
|
'multi-select': {
|
|
@@ -462,7 +589,8 @@ export const mobileComponentKnowledge = {
|
|
|
462
589
|
differences: [
|
|
463
590
|
'Değer `{ label, value }` DİZİSİDİR (düz değer ve `{ id, text }` de okunur); her dokunuş `change { value }` yayar, yük `id`/`text` ikizlerini taşır — web `multi-select.functions.ts`in kuralları mobilde ikizlendi.',
|
|
464
591
|
'Liste alttan açılır (`dropdown` emsali): gruplu listede (`optionType: grouped`) çocuklu satır `isSelectable` değilse başlıktır, gruplar hep açıktır (`isExpanded` okunmaz). Arama kutusu `search` olayına akış bağlıysa `search { searchText }` yayar ve listeyi akış yazar, değilse yerelde süzer. Liste açılınca `focus`, kapanınca (`Done` ya da perde) `blur`; arama doluyken kapanırsa ve `search` akışa bağlıysa web gibi `search { searchText: "" }` de yayılır (yeniden açılan liste eski sonuçla kalmasın).',
|
|
465
|
-
'Üst sınır web gibi formun `maxItems` doğrulamasıdır, seçim kesilmez. Alanda en çok üç çip, gerisi "+n". İç roller `__trigger`, `__clear`, `__done`; satırlar `role="option"` + `data-value`.'
|
|
592
|
+
'Üst sınır web gibi formun `maxItems` doğrulamasıdır, seçim kesilmez. Alanda en çok üç çip, gerisi "+n". İç roller `__trigger`, `__clear`, `__done`; satırlar `role="option"` + `data-value`.',
|
|
593
|
+
'Satırın görseli web `SelectItem` önceliğiyle: `prefixImage` > `prefixText` (zemini `color`) > `icon` (rengi `color`). Düşenler: `options[].tooltip`, `isExpanded` (gruplar hep açık, üzerine gelme yok).'
|
|
466
594
|
]
|
|
467
595
|
},
|
|
468
596
|
toast: {
|
|
@@ -520,7 +648,7 @@ export const mobileComponentKnowledge = {
|
|
|
520
648
|
'Vuruş sürerken sayfanın ve `scroll-view`un kaydırması kilitlidir: dikey vuruş sayfayı sürüklemez (web`de pedin `touch-action: none`ı); parmak kalkınca sayfa normal kayar.',
|
|
521
649
|
'Temizle düğmesi (`<elementId>__clear`, `clearText`, boşsa "Clear") çizim ya da değer varken ve alan kilitsizken görünür; basınca önce `change { value: \'\' }`, sonra `clear`. Ped `<elementId>__pad`. Tasarım kipinde çizilmez, Temizle basılmaz.',
|
|
522
650
|
'Boyu kabuktan gelen düğümde (`heightType: fixed` ya da `fill`) ped kabuğu doldurur; yoksa taban yükseklik boya göre 72/96/128 dp. Kayıtlı `value` PNG ise görsel, SVG (ham işaretleme ya da `data:image/svg+xml`) ise vektör olarak çizilir; tanınmayan metin çizilmez. Düşen: `style`.',
|
|
523
|
-
'iOS`ta sistem jesti imzadan önce gelir: iOS 26`da yığına itilmiş sayfada pede SAĞA atılan vuruş sayfayı kapatır (
|
|
651
|
+
'iOS`ta sistem jesti imzadan önce gelir: iOS 26`da yığına itilmiş sayfada pede SAĞA atılan vuruş sayfayı kapatır (iOS 26`nın içerikten geri kaydırması — platform davranışı, ölçüldü), `modal` sunumlu sayfada aşağı vuruş sayfayı kapatabilir (ölçülmedi). İmzayı sekme kökündeki ya da itilmemiş sayfaya koyun.'
|
|
524
652
|
]
|
|
525
653
|
},
|
|
526
654
|
webview: {
|
|
@@ -529,7 +657,7 @@ export const mobileComponentKnowledge = {
|
|
|
529
657
|
'Cihazda `react-native-webview`; kanvas ve önizlemede web `iframe`inin korumalı alanıyla `<iframe>` (betik, form, açılır pencere; `allow-same-origin` yok — çerez ya da depolama isteyen site önizlemede eksik çalışabilir, cihazda tam). Kanvasta dokunuş almaz. Android`de görünüm kendi içeriğini sayfanın kaydırma kabı içinde de kaydırır.',
|
|
530
658
|
'Gezinme varsayılan KAPALI (güvenlik kararı): ilk yükleme ve yönlendirmeleri (ilk `load`a kadar), alt çerçeveler ve aynı belgedeki çapalar serbesttir; yüklemeden sonra başka belgeye giden gezinme `navigate { url }` yayar ve ENGELLENİR. Adres sistemde (http(s) tarayıcıda, `mailto:`/`tel:`/`sms:` ilgili uygulamada) YALNIZ kullanıcının dokunduğu bağlantıda açılır — betiğin gezinmesi (`location`, zamanlayıcı, programla tıklama) ve form gönderimi yalnız olay yayar, uygulama şemaları (ör. `whatsapp://`) hiç açılmaz. `allowNavigation: true` gezinmeyi görünümün içinde yapar, `navigate` yine yayılır. Yeni pencere (`target="_blank"`, `window.open`) görünümde açılmaz: `navigate` yayılır, kullanıcının dokunduğu bağlantıysa (izin açıkken de) sistemde açılır.',
|
|
531
659
|
'Kuralın bilinen boşlukları: ilk `load`dan ÖNCE her gezinme serbesttir (betik ya da hızlı dokunuş dahil); aynı adrese yapılan form gönderimi aynı belge sayılır; Android POST isteğini kurala hiç getirmez ve karar 250 ms içinde verilemezse yüklemeye izin verir (olay yine yayılır). Web`de köprü yalnız `html` içeriğinde ve yalnız gerçek bağlantı dokunuşunu görür: betiğin gezinmesi, form gönderimi ve açılır pencere çerçevenin içinde ya da yeni sekmede kalır; başka kökenli `src` sayfasında köprü hiç yoktur.',
|
|
532
|
-
'Sayfadan akışa: `window.ReactNativeWebView.postMessage(metin)` → `message { data }` (metin olduğu gibi
|
|
660
|
+
'Sayfadan akışa: `window.ReactNativeWebView.postMessage(metin)` → `message { data }` (metin olduğu gibi, `self.data`; JSON`u akış ayrıştırır). İki yönlü köprü (`html` ile ortak, 2026-09-28): `window.ngApps.emit(name, data)` → `message` olayı, akış `event.name`/`event.data` alır; akışın setter`la yazdığı `message` prop`u sayfada `window.ngApps.on(name, fn)` ile alınır (`{ name, data }` nesnesi olduğu gibi, başka değer `name: \'message\'` ile). Cihazda köprü `src` sayfasına da girer; web`de yalnız `html` içeriğinde çalışır, başka kökenli `src` sayfasında YOKTUR.',
|
|
533
661
|
'Kutu `lottie` kuralından: kabuktan gelen boy ya da (genişlik belliyken) panelin `aspectRatio`su, yoksa 300 dp. `load` her tamamlanan yüklemede (izin verilen gezinmeden sonra da) yayılır. Cihazda yüklenemeyen sayfa (ağ hatası) `error` yayar ve yer tutucu çizer; web`de tarayıcı engellenen ya da bulunamayan çerçevede de `load` atar, `error` pratikte gelmez (web `iframe` gibi).'
|
|
534
662
|
],
|
|
535
663
|
propNotes: {
|
|
@@ -537,7 +665,137 @@ export const mobileComponentKnowledge = {
|
|
|
537
665
|
html: 'Satır içi HTML belgesi; doluysa `src`nin önüne geçer. Cihazda `about:blank` kökeninde, web`de kökensiz korumalı `srcdoc` olarak çizilir; sayfa içi çapa (`#bolum`) yerinde kaydırır.',
|
|
538
666
|
allowNavigation: 'Açıkken bağlantılar görünümün İÇİNDE açılır; kapalıyken (varsayılan) gezinme engellenir ve kullanıcının dokunduğu bağlantı sistemde açılır. İki durumda da `navigate { url }` yayılır.',
|
|
539
667
|
injectedJs: 'Belge yüklenince koşan JavaScript (ör. `window.ReactNativeWebView.postMessage(document.title)`); cihazda iki içerikte, web`de yalnız `html`de. Gömülen sayfada tam yetkiyle koşar — yalnız güvenilen içerikte kullanın.',
|
|
668
|
+
message: 'Akıştan sayfaya ileti: setter ile yazılır, sayfa `window.ngApps.on(name, fn)` ile dinler (`\'*\'` hepsini alır). `{ name, data }` nesnesi olduğu gibi gider, başka değer `name: \'message\'` ile; aynı değer bir kez iletilir, belge yeniden yüklenince son değer yeniden gider.',
|
|
540
669
|
title: 'Erişilebilirlik etiketi (ekran okuyucu; web`de `<iframe title>`).'
|
|
541
670
|
}
|
|
671
|
+
},
|
|
672
|
+
html: {
|
|
673
|
+
summary: 'Web `html`in ikizi: katalogda karşılığı olmayan küçük görünüm (özel rozet, SVG, biçimli metin) için mobildeki geçici çözüm kapısı. `content` `context` ile Mustache`tan geçer; belge kendi korumalı çerçevesinde çizilir.',
|
|
674
|
+
differences: [
|
|
675
|
+
'İçerik sayfanın DOM`unda değil KENDİ belgesinde çizilir: cihazda `react-native-webview` (`about:blank` kökeni), kanvas ve önizlemede `<iframe srcdoc sandbox="allow-scripts">` (`allow-same-origin` yok). Belge uygulamanın çerezine, jetonuna ve sayfanın bileşenlerine ULAŞAMAZ — güvenlik kararı. Kanvasta çizilir ama dokunuş almaz.',
|
|
676
|
+
'Tema belgenin `:root`una yazılır: shadcn değişkenleri (`--primary`, `--foreground`, `--border`, `--muted-foreground` … HSL üçlüsü, `hsl(var(--primary))` ile okunur), `--radius-sm|md|lg` ve platformun `--ng-*` değişkenleri. Açık/koyu kip değişince belge yeniden kurulur. Gövde tema yazı yığınıyla, `color: hsl(var(--foreground))` ve saydam zeminle gelir.',
|
|
677
|
+
'Boy içeriğe göre: belge içerik kutusunu `ResizeObserver` ile bildirir, kabuk o boyu alır (bildirim gelene kadar 48 dp). `heightType: fill` ya da `px`/`%`/sayı ölçülü `fixed` kabuk boyunu korur, içerik belgede kayar. Studio`nun ölçüsüz `fixed`i içeriğe göre boy alır. `100vh` ile boylanan içerikte büyüme döngüsü durdurulur — o içerikte boyu `fixed` verin.',
|
|
678
|
+
'Bağlantılar görünümde AÇILMAZ: kullanıcının dokunduğu `<a href>` sistem tarayıcısında (`mailto:`/`tel:`/`sms:` ilgili uygulamada) açılır, betiğin gezinmesi hiçbir şey açmaz (`webview`in `allowNavigation: false` kuralı).',
|
|
679
|
+
'Akışla iki yön: belgede `fireEvent(key, data)` web gibi `actions` satırının akışını koşturur (akış `event.name` = key, `event.data` = veri; eşleşmeyen anahtar ve akışsız satır console uyarısıdır). `window.ngApps.emit(name, data)` → `message` olayı (`event.name`/`event.data`). Akışın setter`la yazdığı `message` prop`u belgede `window.ngApps.on(name, fn)` ile alınır.',
|
|
680
|
+
'Web`in belge içi yardımcıları: `loadScript` web gibi çalışır, `onCleanup` tanımlı ama boş (içerik değişince belge baştan kurulur), `fireEvent`in üçüncü argümanı yok sayılır (her belge tek bileşendir). `style` web anlamıyla içerik sarmalayıcısına kapsamlıdır (üst düzey bildirim sarmalayıcıya, `.hucre{…}` gibi iç kural onun altına); nesne biçimli `style` çizilmez.',
|
|
681
|
+
'Kapsam dışı: React Native harici bileşen protokolü v2 (çalışma anında JS paketi, Hermes, imza) — MOB-006; kalıcı ihtiyaç ayrı iştir.'
|
|
682
|
+
],
|
|
683
|
+
propNotes: {
|
|
684
|
+
content: 'Belgenin gövdesi (HTML, `<script>` ve `<style>` serbest). `{{ … }}` taşıyorsa `context` ile Mustache`tan geçer; hata olursa ham içerik çizilir.',
|
|
685
|
+
style: 'Belgenin stil bloğuna eklenen CSS; tema değişkenlerini okuyabilir (`.rozet{background:hsl(var(--primary))}`).',
|
|
686
|
+
message: 'Akıştan belgeye ileti: setter ile yazılır, belge `window.ngApps.on(name, fn)` ile dinler (`\'*\'` hepsini alır). `{ name, data }` nesnesi olduğu gibi gider, başka değer `name: \'message\'` ile. DURUMDUR: aynı değer ikinci kez iletilmez (tekrar için veriye sayaç koyun), belge yeniden kurulunca son değer yeniden iletilir.',
|
|
687
|
+
actions: 'Web ile aynı: `key` + akış. Belgedeki `fireEvent(key, data)` satırın akışını koşturur; `text` panelin satır etiketidir.'
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
chart: {
|
|
691
|
+
summary: 'Grafik; prop`lar, on altı tip (scatter dahil) ve kalan olaylar web ikizininki. Seçenek ve olay eşlemesi web`in modülünden gelir (`buildChartOption`, `chart-events.ts`): iki platform aynı ECharts seçeneğini çizer, aynı olayları yayar.',
|
|
692
|
+
differences: [
|
|
693
|
+
'Cihazda ECharts `@wuba/react-native-echarts`in SVG motoruyla (`react-native-svg`) çizilir, kanvas ve önizlemede ECharts`ın kendi tuvaliyle. Tema renkleri ve yazı ailesi temanın `--ng-*` değişkenlerinden; cihazda yazı yığının ilk ailesidir, yüklü değilse platform yazı tipi.',
|
|
694
|
+
'Düşenler: `style`; `isExportable` ve `exportFileName` (CSV/PNG indirme, tablo görünümü, tam ekran — dosya kaydetmek ayrı native modül ister); `showTypeSwitcher` ve `showRefresh` ile `refresh` olayı (tip akışla `chartType` yazılarak, yenileme sayfanın kaydırarak yenilemesiyle); `isDrillDown` ile `breadcrumbClick` (tıklanan noktanın satırı `dataPointClick { row }` ile yine gelir).',
|
|
695
|
+
'Kutu: kabuktan gelen boy (`heightType: fixed` ölçülü ya da `fill`) ya da panelin `aspectRatio`su, yoksa 240 dp; `caption` web`deki gibi kutunun altında metindir ve grafik alanından pay alır. Durum web`in sırasıyla: yükleniyor (ortada dönen gösterge — web kutuyu boş bırakır, ARC-127), hata (`errorText` + Yeniden dene düğmesi `<elementId>__retry`, `retry` yayar), veri yok (`emptyText`).',
|
|
696
|
+
'Dokunuş: noktaya dokunmak YALNIZ `dataPointClick` (seri), kategori ekseninin etiketine dokunmak YALNIZ `axisLabelClick` (yatay çubukta etiketler y ekseninde), legend maddesi `legendClick`; hedef çizgisi, bant ve eksen başlığı olay değildir, `selectionChange` yalnız `selectionMode` açıkken gelir (web ile aynı). Dokunulan noktada ipucu açılır; sayfa kaydırılınca açık kalır, grafiğin başka yerine dokununca yer değiştirir. Grafiğin üstünden dikey kaydırma sayfayı kaydırır; 4 px`ten uzun sürükleme tıklama sayılmaz.',
|
|
697
|
+
'Olay yükü düğüme yazılınca grafik yeniden KURULMAZ: seçim, gizlenen legend serisi ve yakınlaştırma korunur; seçenek girdinin içeriği değişince yeniden uygulanır ve legend seçimi sıfırlanır (web onu korur — ARC-131). Bozuk bağlı veri bileşeni düşürmez: çözülemezse `emptyText`, seçenek kurulamazsa önceki çizim kalır. Başlıklı kartezyen grafikte başlık çizim alanının tepesine biner (ARC-126), eksen başlığı tuvalden taşar (ARC-129) — ikisi web ile aynı.'
|
|
698
|
+
]
|
|
699
|
+
},
|
|
700
|
+
datepicker: {
|
|
701
|
+
summary: 'Tek gün seçici; kutuya dokununca cihazda işletim sisteminin seçicisi (iOS satır içi takvim, Android iletişim kutusu), önizlemede (`/preview`, `/dev`) tarayıcının seçicisi açılır — kanvasta alan kilitlidir. Değer, sınır ve olaylar web ikizininki.',
|
|
702
|
+
differences: [
|
|
703
|
+
'Kutu `dropdown` tetikleyicisinin görünümündedir (`role="combobox"`, iç rol `<elementId>__trigger`, temizleme `<elementId>__clear`); X değer varken, alan kilitli değilken ve yüklenmiyorken çizilir. `isLoading` ikonun yerinde dönen gösterge çizer, kilit değildir (kutu açılır — web gibi).',
|
|
704
|
+
'Seçici: iOS`ta alttan açılan sayfada satır içi takvim — gün seçilip Tamam/Done (`<elementId>__done`) ile yazılır, dışına dokunmak vazgeçer (seçimde yazılmaz: seçili güne yeniden dokunmak değer bildirmez, takvimin ay/yıl çarkı bildirir — ikisi iOS 26.2 simülatöründe ölçüldü, 09 adım 4); Android`de sistem iletişim kutusu (Android cihazda ölçülmedi). Önizlemede kutunun içindeki görünmez `<input type="date">` tarayıcının seçicisini açar (`showPicker()`).',
|
|
705
|
+
'Otomasyon: `page_screenshot` `set` KÖKE değil `<elementId>__input`a yazılır, HTML biçimiyle — `yyyy-MM-dd` (`2026-08-01`). Kök `set` kutunun `role="combobox"`u yüzünden açılır kutu yoluna girer ve "açılır kutu AÇILMADI" der; biçimsiz değer (`1 Ağu 2026`, saatli metin) tarayıcıda boşalır ve yok sayılır — alan yalnız X`le (`__clear`) boşalır.',
|
|
706
|
+
'Değer web gibi yerel duvar saati `yyyy-MM-ddTHH:mm:ss` (seçimde `T00:00:00`); `minDate`/`maxDate` gün sınırıdır — seçici dışını kapatır, yazılan değer sınır gününe çekilir; `valueOffset`/`displayOffset` web kuralı. `focus` seçici açılınca, `blur` kapanınca gelir.',
|
|
707
|
+
'Kutu metni web`in deseniyle (`tr` `d MMM yyyy`, diğerleri `MMM d, yyyy`); dil alanın `locale`i, yoksa uygulama dili. Düşen: `style`.',
|
|
708
|
+
'Mobile özgü alanlar (f-11): `presentation: calendar` kutuya basınca alttan TAKVİM SAYFASI açar (işletim sistemi seçicisi değil — Pazartesi başlangıcı, dolu seçili gün, halkalı bugün, sınır dışı pasif gün koddan; iç roller `__prev`, `__next`, `__day-yyyy-MM-dd`, `__done`); `closeOnSelect` (varsayılan açık) seçimle kapatır. `quickPicks` gün ofseti çipleri (`[{ days: 0 }, { days: -1 }, { days: -2 }]` → Bugün / Dün / 2 gün önce; iç rol `__pick-<ofset>`), sınır dışı çip pasif; `system` kipinde alanın altında satırdır. `displayFormat` kutudaki kalıptır (`dd.MM.yyyy` → `24.09.2026`), değer ISO kalır. Android sistem seçicisi cihaz dilini izler — dil denetimi gerekiyorsa `presentation: calendar`.'
|
|
709
|
+
]
|
|
710
|
+
},
|
|
711
|
+
daterangepicker: {
|
|
712
|
+
summary: 'Tarih aralığı seçici (web ikizi): tek kutuda iki uç, basış alttan takvim sayfası açar ve iki güne basılarak aralık seçilir. `change` web gibi `{ valueFrom, valueTo }`.',
|
|
713
|
+
differences: [
|
|
714
|
+
'İşletim sisteminin seçicisi aralık seçmediği için her zaman takvim sayfasıdır (`datepicker` `presentation: calendar` ile aynı sayfa ve iç roller: `__trigger`, `__clear`, `__prev`, `__next`, `__day-yyyy-MM-dd`, `__done`).',
|
|
715
|
+
'İlk basış başlangıç (`valueTo: null` yazılır), ikinci basış bitiş; başlangıçtan önceki gün seçilirse uçlar YER DEĞİŞTİRİR, tamamlanmış aralığa basış yeniden başlatır. Uçlar `minDate`/`maxDate` gün sınırına çekilir, `valueOffset` eklenir; aralık tamamlanınca dokunulmayan uç web `toRangeValue` gibi SAKLANDIĞI GİBİ yazılır (akışın yazdığı saat korunur). Takvim `displayOffset`le gösterilen günü işaretler. `closeOnSelect` (varsayılan açık) bitişte kapatır.',
|
|
716
|
+
'Kutu metni `başlangıç – bitiş` (`displayFormat` ya da dilin kalıbı), boşken `startPlaceholder – endPlaceholder`; X iki ucu birden `null` yapar. Düşen: `style`.'
|
|
717
|
+
]
|
|
718
|
+
},
|
|
719
|
+
timepicker: {
|
|
720
|
+
summary: 'Saat seçici (`HH:mm`); cihazda işletim sisteminin saat çarkı/kutusu, önizlemede tarayıcının seçicisi. `change` web gibi `{ value, selectedLabel }`.',
|
|
721
|
+
differences: [
|
|
722
|
+
'Web`in listesi yerine işletim sisteminin seçicisi: iOS`ta alttan açılan sayfada çark + Tamam/Done, Android`de sistem saat kutusu; önizlemede `<input type="time">` tarayıcı seçicisi. Çark izinli en yakın saatte açılır — kaydırmadan Tamam yazılanı görünenle aynı tutar. Kutu, temizleme ve otomasyon `datepicker` ile aynı (`set` `<elementId>__input`a `HH:mm`). Web listesi gibi `isLoading` iken açılmaz.',
|
|
723
|
+
'Sistem seçicisi tek tek saati KAPATAMAZ: `minTime`/`maxTime` dışındaki, `disabledTimes`taki ya da adım dışı seçim İZİNLİ EN YAKIN saate yaslanır (eşitlikte erken olan; iOS çarkı sınırı zaten uygular); izinli saat yoksa hiçbir şey yazılmaz. Web`de bu saatler listede kapalı görünür. Ters sınır (`22:00`–`06:00`) seçiciye verilmez — her saat kapalı sayılır, web gibi.',
|
|
724
|
+
'`format: 12h` web gibi yalnız gösterimdir (kutu ve `selectedLabel` `01:00 PM`, değer `13:00`); iOS çarkı dilin kendi saat düzeniyle açılır (Türkçe 24, İngilizce 12 saat); Android saat kutusuna `format` verilir (Android cihazda ölçülmedi). `clearable: false` X`i kaldırır.',
|
|
725
|
+
'Düşenler: `style`, `emptyText` (web listesinin aramasındaki "sonuç yok" metni; sistem seçicisinde arama yok).'
|
|
726
|
+
],
|
|
727
|
+
propNotes: {
|
|
728
|
+
minutesStep: 'Çarkın adımı, adımı bölen en büyük desteklenen aralıktır (60 → 30`luk çark); seçim yine adıma yaslanır.'
|
|
729
|
+
}
|
|
730
|
+
},
|
|
731
|
+
datetimepicker: {
|
|
732
|
+
summary: 'Tarih + saat tek kutuda; cihazda iOS satır içi takvim + saat tek sayfada (Tamam/Done ile gösterilen an yazılır — boş alan şimdiyle, adımın ızgarasında açılır), Android önce tarih sonra saat (saatten vazgeçmek hiçbir şey yazmaz — kodla, Android cihazda ölçülmedi); önizlemede `<input type="datetime-local">`.',
|
|
733
|
+
differences: [
|
|
734
|
+
'Web`in iki kutusu (tarih + saat) mobilde TEK kutudur: metin tarih ve saati birlikte gösterir (İngilizcede 12 saat, diğer dillerde 24; saat metni platformun Intl`iyle — cihaz `3:00 PM`, web `03:00 PM`); boşken `placeholder` görünür.',
|
|
735
|
+
'Seçilen an saniyesi sıfırlanıp web`in saat başı ızgarasına (`minutesStep`; 45 dakikada :00 ve :45, saatten uzun adımda saat başları) ve `minDate`/`maxDate` an sınırına çekilir, `valueOffset` eklenir: `yyyy-MM-ddTHH:mm:ss`. Android`de saat kutusundan vazgeçmek hiçbir şey yazmaz (web: boş alanda yalnız gün seçmek yaymaz, CQ-237).',
|
|
736
|
+
'Kutu, temizleme, otomasyon (`set` `<elementId>__input`a `yyyy-MM-ddTHH:mm`) ve `focus`/`blur` `datepicker` ile aynı. Düşenler: `style`, `timePlaceholder` (web`in ayrı saat kutusunun metni).'
|
|
737
|
+
]
|
|
738
|
+
},
|
|
739
|
+
fileInput: {
|
|
740
|
+
summary: 'Dosya alanı; kutuya ya da Gözat`a dokununca cihazda `source`un seçicisi (varsayılan belge seçici), önizlemede tarayıcının dosya penceresi açılır — kanvasta alan kilitlidir. Değer, kapılar ve `change` web ikizininki: base64 veri URL`si düğüme yazılır ve Table microservice`in FILE parametresiyle kaydedilir (değeri olduğu gibi gövdeye verin — platform_guide(\'mobile\') §Dosya ve fotoğraf); fotoğrafı istemci küçültür (`maxImageDimension`), `maxFileSizeMb` varsayılanı 10.',
|
|
741
|
+
differences: [
|
|
742
|
+
'Seçici `source` ile seçilir (yalnız mobilde): `files` belge seçicisi (bütün türleri gösterir; izin listesi seçimden SONRA uygulanır ve web`in tür uyarısını çizer), `library` fotoğraf arşivi, `camera` kamera (izin istenir, verilmezse hiçbir şey olmaz), `ask` her seferinde sorar. Önizlemede görünmez `<input type="file">` açılır (`library`/`camera` `accept="image/*"`); otomasyon `<elementId>__input`a dosya verir. Seçici açıkken ve okuma sürerken alan meşguldür: ikinci seçici açılmaz, satır silme ve temizleme bekler.',
|
|
743
|
+
'Değer web gibi `{ value: base64 veri URL`si, fileName, type: "file" }` (çoklu kipte dizi, yeni seçim üstüne eklenir; boşaltma `{ type: "ref", value: null }`, çoklu kipte `[{ type: "ref", value: null }]`) — backend `TableFileParameter { value, type: ref|file|document, fileName }` biçiminin aynısı: `file` depoya yazılır, `ref` var olan dosyayı bağlar, `null` alanı boşaltır. Base64 sayfa durumunda ve istek gövdesinde taşındığı için `maxFileSizeMb` (mobil varsayılan 10) sıfırlanmaz. Kamera/galeri fotoğrafı uzun kenarı `maxImageDimension`a (varsayılan 1600 px; 0 = kapalı) indirilip JPEG olarak yeniden kodlanır — boyut kapısı küçültülmüş dosyaya bakar; belge seçiciden gelen dosyaya dokunulmaz. Fotoğraf arşivinden gelen HEIC iOS`ta JPEG`e çevrilir (`.jpg` — web`de Safari`nin yaptığı gibi), fotoğraflar `quality` ile sıkıştırılır. Görsel seçimler alanda küçük resimle görünür.',
|
|
744
|
+
'Tür/boyut/adet kapısı web kuralıdır (tek uyarı, tür ihlali önce; uyarı metni uygulama dilinde). İç roller: kutu `<elementId>__field`, Gözat `__browse`, temizle `__clear`, çoklu kipte satır silme `__file-<n>__delete`. `isReadonly`/`isViewmode` Gözat`ı ve X`i gizler.',
|
|
745
|
+
'Düşen: `style`.',
|
|
746
|
+
'f-13 (mobile özgü görünüm ve düzenleme): görsel dosya satırda 48 px küçük resimdir; tekli değerde satır "Değiştir" (`__file-0__change`, seçici yeniden açılır, değer yerinde değişir) ve kaldır taşır. `variant: tile` 1:1 kesikli "+ Ekle" karosu (`__add`) ve üç sütunlu küçük resim ızgarasıdır: dolu karoya basış değiştirir (`__file-<n>__change`), köşedeki × siler (`__file-<n>__delete`). `enableCrop` + `cropAspectRatio` cihazda sistem kırpıcısını açar (yalnız tek seçimde; iOS serbest oranı kesin uygulamaz; önizlemede kırpma yok), `rotateOnPick` (0/90/180/270) seçilen fotoğrafı döndürür. Kamera izni verilmezse değer değişmez, alanın altında Ayarlar bağlantılı not çıkar (`__settings`); alan geçersiz sayılmaz. Fotoğraf arşivi izin istemez (iOS PHPicker, Android sistem seçicisi).'
|
|
747
|
+
],
|
|
748
|
+
propNotes: {
|
|
749
|
+
source: 'Dosyanın geldiği yer: `files` (belgeler, varsayılan), `library` (fotoğraf arşivi), `camera`, `ask` (Kamera / Fotoğraflar / Dosyalar sorulur). `library` ve `camera` yalnız fotoğraf verir.',
|
|
750
|
+
quality: 'Fotoğrafın JPEG sıkıştırma kalitesi, 0,1–1 (varsayılan 0,8); `source: files` iken panelde gizlidir. Belgeye dokunmaz.',
|
|
751
|
+
maxImageDimension: 'Kamera/galeri fotoğrafının uzun kenarı için üst sınır, px (varsayılan 1600; 0 = küçültme yok). Küçük görsel büyütülmez; belge seçici dosyalarına uygulanmaz. YALNIZ mobil şemadadır.'
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
filebutton: {
|
|
755
|
+
summary: 'Ataşlı dosya düğmesi; dokununca varsayılan olarak kaynak sorulur (Kamera / Fotoğraflar / Dosyalar), önizlemede tarayıcının dosya penceresi açılır — kanvasta düğme kilitlidir. Değer, kapılar ve `change` web ikizininki: Table microservice`in FILE parametresiyle kaydedilir (değeri olduğu gibi gövdeye verin — platform_guide(\'mobile\') §Dosya ve fotoğraf); fotoğrafı istemci küçültür (`maxImageDimension`), `maxFileSizeMb` varsayılanı 10.',
|
|
756
|
+
differences: [
|
|
757
|
+
'`source` varsayılanı `ask`: iOS`ta eylem sayfası, Android`de üç düğmeli uyarı (dışına dokunmak vazgeçer; Android cihazda ölçülmedi); `files`/`library`/`camera` doğrudan açar. Vazgeçmek değeri değiştirmez; seçici açıkken ve okuma sürerken düğme meşguldür (ikinci seçici açılmaz, satır silme bekler). Simülatörde kamera açılır ama görüntü üretmez — çekim gerçek cihazda sınanır.',
|
|
758
|
+
'Değer web gibi `{ type: "file", value: base64 veri URL`si, fileName, ref: "" }` (çoklu kipte dizi, yeni seçim üstüne eklenir; boşaltma `null`, çoklu kipte `[]`) — backend `TableFileParameter` biçimi, FILE parametresine dönüştürmeden verilir. Tür ve sınır web gibi İKİ bağımsız uyarıdır; `maxFileSizeMb` mobil varsayılanı 10. Kamera/galeri fotoğrafı `maxImageDimension`a (varsayılan 1600 px; 0 = kapalı) küçültülüp JPEG olarak yeniden kodlanır, sınır küçültülmüş dosyaya bakar. HEIC fotoğraf iOS`ta JPEG`e çevrilir (`.jpg`); kameradan gelen fotoğrafın özgün adı olmadığı için geçici dosya adıyla yazılır. Görsel seçimler küçük resimle listelenir.',
|
|
759
|
+
'İç roller: düğme `<elementId>__button`, satır silme `__file-<n>__delete`, çoklu kipte "Tümünü temizle" `__clear`. Açıklama yalnız dosya yokken görünür (web gibi).',
|
|
760
|
+
'Düşen: `style`.',
|
|
761
|
+
'f-13 (mobile özgü): `fileInput` ile aynı 48 px önizleme, tekli "Değiştir", `variant: tile` karo ızgarası, `enableCrop` + `cropAspectRatio`, `rotateOnPick` ve izin notu. `size: icon` yalnız ikonlu yuvarlak düğmedir (`icon`, yoksa kaynağa göre `photo_camera`/`attach_file`) — avatar kamera rozeti: `stack` (`alignment: bottom-right`) + `avatar` taban + `size: icon` `filebutton` katmanı; `change` akışı setter ile değeri `avatar.src`e yazar.'
|
|
762
|
+
],
|
|
763
|
+
propNotes: {
|
|
764
|
+
source: 'Dosyanın geldiği yer: `ask` (varsayılan; Kamera / Fotoğraflar / Dosyalar sorulur), `files`, `library`, `camera`. `library` ve `camera` yalnız fotoğraf verir.',
|
|
765
|
+
quality: 'Fotoğrafın JPEG sıkıştırma kalitesi, 0,1–1 (varsayılan 0,8); `source: files` iken panelde gizlidir.',
|
|
766
|
+
maxImageDimension: 'Kamera/galeri fotoğrafının uzun kenarı için üst sınır, px (varsayılan 1600; 0 = küçültme yok). Belge seçici dosyalarına uygulanmaz. YALNIZ mobil şemadadır.'
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
map: {
|
|
770
|
+
summary: 'Harita ve işaretçiler (FlutterFlow GoogleMap). Web`de karşılığı YOKTUR.',
|
|
771
|
+
differences: [
|
|
772
|
+
'Cihazda `react-native-maps`: iOS Apple Haritalar, Android Google Haritalar (Expo Go`da anahtarsız; geliştirme/EAS derlemesinde Android Google anahtarı ve konum izin metinleri gerekir — ARC-128). Kanvas ve önizlemede Leaflet + OpenStreetMap karoları (anahtarsız, köşede OSM atfı; OSM`nin ortak karo sunucusu yoğun trafiğe açık değildir). Kanvasta dokunuş almaz ve sürüklenmez; karolar ve işaretçiler çizilir.',
|
|
773
|
+
'Görünüm üç sayıdır: `latitude`, `longitude`, `zoom` (web harita ölçeği 1–19, kesirli olabilir; cihazda Apple/Google bölgesine çevrilir). Nesne `center` prop`u YOKTUR: bağlanan düz nesne runtime`da bozulur (ARC-117).',
|
|
774
|
+
'Akış `latitude`/`longitude`/`zoom` yazınca harita oraya gider (web`de anında, cihazda kısa canlandırmayla) ve `regionChange` YAYMAZ. Kullanıcı sürükleyip yakınlaştırınca bıraktığı görünüm `regionChange { latitude, longitude, zoom }` ile düğüme geri yazılır (`carousel.activeIndex` gibi: prop`a bağlı ifade o an ezilir). Kutu ya da pencere boyunun değişmesi olay sayılmaz.',
|
|
775
|
+
'İşaretçiye dokunmak `markerClick { markerId }` yayar ve başlığı ya da açıklaması varsa balon açar. Harita işaretçiye ORTALANMAZ; kenardaki işaretçinin balonu sığmazsa harita sığdıracak kadar kayar ve bu kayma `regionChange` yayar (iOS ve web`de ölçüldü). Üst üste binen işaretçilerde iOS`ta `markerId` açılan balonunkinden farklı olabilir (ARC-130). İşaretçi rengi temanın ana rengidir. Döndürme ve eğme kapalıdır (ölçek kuzey yukarı görünümün ölçeğidir).',
|
|
776
|
+
'`interactive: false` sürüklemeyi ve yakınlaştırmayı kapatır, işaretçiler dokunulabilir kalır ve sayfa haritanın üstünden kayar. Açıkken haritanın üstündeki dikey sürükleme haritayı kaydırır, sayfayı değil.',
|
|
777
|
+
'Kutu `webview` kuralından: kabuktan gelen boy ya da panelin `aspectRatio`su, yoksa 300 dp.'
|
|
778
|
+
],
|
|
779
|
+
propNotes: {
|
|
780
|
+
latitude: 'Merkezin enlemi (−90…90; Mercator sınırı ±85,05`e kırpılır). Sayı metni de okunur (`41,0082`); geçersiz ya da boş değer varsayılana (İstanbul) düşer.',
|
|
781
|
+
longitude: 'Merkezin boylamı; −180…180 dışındaki değer sarılır (190 → −170).',
|
|
782
|
+
zoom: 'Web harita ölçeği: 1 kıtalar, 19 bina; kesirli olabilir, aralık dışı kırpılır. Dünyadan geniş görünüm cihazda sığdırılır (iOS 180°/360°`ten geniş bölgeyi reddeder) ve Apple Haritalar küçük kutuda daha uzağa açılmaz: 402×300 kutuda `zoom: 1`, kullanıcı hareketinden sonra `zoom: 2` olarak yazılır (yazılan her zaman gerçek ölçektir).',
|
|
783
|
+
markers: '[{ id, latitude, longitude, title, description }] — bağlı sorgunun satırları da olur; `latitude`/`longitude`u sayı (ya da sayı metni) olmayan satır çizilmez. `id` boşsa sırası kimliktir (`markerClick { markerId }`).',
|
|
784
|
+
interactive: 'Sürükleme ve yakınlaştırma (varsayılan açık); kapalıyken işaretçiler yine dokunulur.',
|
|
785
|
+
showUser: 'Kullanıcının konumunu çizer. Cihazda iOS izni MapKit sorar, Android`de bileşen çalışma anı izni ister; web`de tarayıcı konum izni. Yalnız runtime`da. "Konumum" düğmesi yoktur (Android`inki kamerayı `regionChange` yaymadan taşırdı); konuma gitmek akışın `latitude`/`longitude` yazmasıdır.'
|
|
786
|
+
}
|
|
787
|
+
},
|
|
788
|
+
datatable: {
|
|
789
|
+
summary: 'Veri tablosu (FlutterFlow DataTable); prop`lar ve akış sözleşmesi web ikizininki: sıralama ya da sayfa değişince sorgu prop`ları (`sortField`/`sortType`/`offset`) düğüme yazılır ve `mount` yeniden koşar, satır eylemi önce `selectedRow`u yazar sonra eylemin kendi akışını koşturur (web`den farklı olarak yazım sessiz değildir: tablo bir kez yeniden çizilir). Hücre biçimi, görünür kolonlar, sıralama döngüsü ve sayfa hesabı web`in modülünden gelir (`renderCell`, `buildViewColumns`, `nextSort`, `computePageState`): iki platform aynı veriden aynı metni üretir.',
|
|
790
|
+
differences: [
|
|
791
|
+
'`variant: table` (varsayılan) yatay kaydırılan tablodur: başlık satırı, sıralanabilir kolonda başlığa dokunuş (`<elementId>__sort-<kolon>`, yön oku başlıkta), eylem sütunu satırın sonunda; dikey kaydırma sayfanındır, tablonun üstünden başlayan dikey kaydırma sayfayı kaydırır; kolonların toplamı çerçeveden darsa kolonlar web gibi çerçeveye yayılır (`table-layout: fixed`). `variant: cards` satır başına kart çizer: ilk görünür görsel kolon kartın başına, ilk görsel olmayan kolon başlığa, kalanlar etiket-değer satırlarına; kart kipinde sıralama başlığı yoktur (sıralama akışla yazılır).',
|
|
792
|
+
'Eylemler web paletiyle (`solid` birincil, `information` kenarlı, `transparent` hayalet, `error`/`danger` yıkıcı, `warning`, `dark`): `actionType: button` satırda düğmeler (`<elementId>__action-<satır>-<sıra>`), `dropdown` ⋯ düğmesi (`<elementId>__more-<satır>`) alttan açılan eylem sayfası (`<elementId>__sheet-action-<sıra>`; cihazda `modal` ile aynı katman). Satırın `_actions` dizisi web gibi eylemi ezer, `isHidden` gizler, `isDisabled` kilitler.',
|
|
793
|
+
'Sayfalama (`isPaginated`): ‹ `1–10 / 57` › çubuğu (`<elementId>__page-prev`, `__page-next`); metin dil bağımsızdır. Web`in sayfa numarası kutusu ve sayfa başına satır seçimi yok (`limit` panelden ya da akıştan; düğümde hiç yazılmamışsa web gibi 10). Başlık doluyken yanındaki yenile düğmesi (`<elementId>__refresh`) `mount`u koşturur.',
|
|
794
|
+
'Düşenler: `style`, `actionsPinned` (sabit eylem sütunu). Okunmayanlar: kolonların `isFilterable`ı ve gizli `filters` — filtre düzenleyicisi mobilde yok, akışın yazdığı `filters` sorguya olduğu gibi gider; özet satırı yok. Satır sanallaştırma yok: uzun veri için yol `limit`tir (100 satır × 6 kolon cihazda geliştirme kipinde ~0,7 sn`de çizildi).',
|
|
795
|
+
'Hücre: metin tablo kipinde tek satırda kırpılır (`multiLine` ise `lineClamp` kadar satır), kart kipinde sarar; etiket rengi temadan çözülür, üstündeki metin koyu/açık seçilir; `image` kolonu `imageHeight` karesi; `file` ve `url` dokunuşla sistemde açılır (kanvasta kilitli); `progress` her zaman çubuktur (daire kipi çubuk çizilir). Yükleniyor (`isLoading`) satırların yerine ortada dönen gösterge; satır yokken gövde web`in boş satırı kadar (120) boş kalır, ileti yazılmaz. Bırakılamaz — web ikizi bırakılabilir bildirir ama çocuk çizmez.'
|
|
796
|
+
],
|
|
797
|
+
propNotes: {
|
|
798
|
+
variant: 'Mobile özgü: `table` (varsayılan) ya da `cards`. Web şemasında yoktur; adı kapların `layout` prop`uyla karışmasın diye `variant`.'
|
|
799
|
+
}
|
|
542
800
|
}
|
|
543
801
|
};
|