@medyat/vue-data-table 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,65 @@
1
+ # Sürüm notları
2
+
3
+ ## 1.0.1 — 2026-10-29
4
+
5
+ ### İçe ve dışa aktarma (D46)
6
+
7
+ - **Excel ve CSV paketin içinde.** `@export` dinlenmezse DataTable ve DataSheet dosyayı kendisi yazar; DataSheet `parseFile` verilmezse .xlsx / .csv'yi kendisi okur. Yeni zorunlu peer'ler: `read-excel-file` (^9.3.13) ve `write-excel-file` (^4.1.1); ilk Import/Export'ta yüklenir. **Geçiş:** `pnpm add read-excel-file write-excel-file`; mevcut `@export` / `parseFile` kodu aynen çalışır (override), istenirse silinebilir.
8
+ - DataTable Export ekranda görüneni yazar: seçim varsa seçili satırlar, yoksa sayfadaki satırlar. Menü etiketi “Export matching rows” → “Export 100 rows” (`toolbar.export` artık `.one` / `.other`). `export` olayına `rows` eklendi.
9
+ - Export menüsü artık dinleyici olmadan da görünür; `:exportable="false"` gizler. DataSheet'te Import da varsayılan açık, `:importable="false"` gizler.
10
+ - .xlsx: yazı 16 pt; başlık kalın, dolgulu, dondurulmuş; sayı, para, yüzde ve tarih tipli hücre; `select` ve `boolean` sütunlarının seçenekleri ikinci sayfada (“Options”), hücreler o listeden açılır liste.
11
+ - Eski ikili `.xls` yerleşik okuyucuda desteklenmez (`import.xlsxOnly`); `import.drop` metninden `.xls` çıktı.
12
+
13
+ ### DataSheet
14
+
15
+ - **Yeni / Güncelle ayrımı kalktı (D47).** `lookupKeys` prop'u, New / Update etiketi ve Update satırını sunucudan doldurma yok; eklenen satır gutter'da `+` ile işaretlenir, sunucu anahtara göre upsert eder. **Geçiş:** `:lookup-keys` ve sorgu uç noktası silinebilir; `@save` yükünde `SheetChangeRow.op` yok, `values` artık değişen alanlar + `required` sütunlar + anahtar (eklenen satırda boş değer gitmez). Import özeti ve toast metinleri “listede olan / olmayan”, “added” oldu; `sheet.tag.new` / `sheet.tag.update` yerine `sheet.addedRow`.
16
+ - Büyük içe aktarma artık sayfayı dondurmuyor: listede olmayan 10.000 anahtarın içe aktarılması ~27 s'den ~1–2 s'ye indi. Yeni satırlar satır satır değil toplu ekleniyor (her satırda tüm parti yeniden doğrulanıyordu); `applyResult` da sonuçları tek seferde işliyor.
17
+ - İçe aktarmada `maxRows` sınırı eklenen satırları iki kez sayıyordu; 10.000 sınırında yalnızca 5.000 satır alınıyordu.
18
+ - `required` sütunlar gizlenemez: Columns dialog'unda kilitli, görünümde gizli kayıtlı olsa da görünür.
19
+
20
+ ### DataTable
21
+
22
+ - **Satır klavyesi kaldırıldı (D40).** Satır odağı ve çerçevesi, satır okları, satırda `↵` / `→` / `←` / `X` / `⇧↑↓` / `⌘A` / `⇧F10` ve başlıklar arası ok gezinmesi yok. Satırdaki widget'lar ve başlık düğmeleri doğal Tab sırasında; kök `role="table"`, hücreler `cell`, satırda `aria-selected` yok. Sayfa kısayolları ve başlık düğmesindeki sıralama/menü/genişlik/taşıma tuşları değişmedi. DataSheet etkilenmez.
23
+ - Toolbar sırası spesifikasyona döndü: görünüm · arama · Filter solda, Display · ⋯ · birincil aksiyon sağda.
24
+ - Odak seçim checkbox'ındayken `Esc` seçimi temizler ve tek harfli kısayollar çalışır.
25
+ - Filtre için alan seçilince (column picker, header menüsü › Filter by this column…, mevcut çip) odak doğrudan editörün ilk alanına gelir; önceden picker/menü odağı tetikleyicisine geri alıyor ya da operatör düğmesine düşüyordu.
26
+ - Popover içeriği kenarlara eşit uzaklıkta: column picker, görünüm menüsü ve Columns panelindeki arama kutuları ile filtre editörü gövdesi her yönde `--dt-pop-pad` (önceden üstte 4, yanlarda 8 px).
27
+ - Sütun sürüklenerek minimum genişliğin (80 px) altına inemez; önceden sürüklerken daralıp ilk tıklamada 80'e sıçrıyordu. Görünüme kaydedilen ve görünümden okunan genişlik de sütunun min–max aralığına kırpılır.
28
+ - **İçeriğe sığdırma kaldırıldı (D42).** Resize tutamacında çift tık ve sütun menüsündeki Fit to content yok; genişlik sürükleyerek ayarlanır. `header.fit` i18n anahtarı kaldırıldı.
29
+ - Display düğmesi her genişlikte yalnızca ikon (DataTable ve DataSheet); adı tooltip'te ve `aria-label`'da.
30
+ - **Toolbar grupları (D43).** Görünüm seçici başında ikon kutusuyla ghost (select kutusu görünümü geri alındı); arama + Filter grubu toolbar'ın tam ortasında; arama + Filter ve Display + ⋯ birleşik düğme grubu. Telefon düzeni değişmedi.
31
+ - Kaydırma hapı (Rows 41–56) kaydırma alanının köşesinden sağdan ve alttan eşit uzaklıkta; görünür kaydırma çubukları (Windows, macOS "her zaman göster") hesaba katılır; yazı dikeyde ortalı.
32
+ - Satıra sağ tık artık satır ⋯ menüsünü açmaz; tarayıcının kendi menüsü açılır.
33
+ - Header (D44): filtre işareti etiketin solunda; ⋯ her sütunda sağ uçta ve yalnızca hover, klavye odağı veya menü açıkken yer kaplar (önceden hep yer ayırıyordu; sayısal sütunlarda en soldaydı). Dokunmatikte hep görünür.
34
+ - **Ölçek büyüdü ve token'a bağlandı (D41).** Arayüz yazısı 13 → 14 px, ikonlar 16 → 18, kontroller 32 → 36, aralıklar 8 → 10, popover dolgusu 4 → 6; Comfortable satırı 52 → 56, Standard 40 → 44 (hücre yazısı 13 → 14). Toolbar, filtre satırı ve footer dolgusu dört yönde eşit. Varsayılan sütun genişlikleri hücre yazısıyla orantılı büyür. Yeni token'lar: `--dt-ui-fs`, `--dt-icon`, `--dt-control-h`, `--dt-checkbox`, `--dt-space`, `--dt-pop-pad`, `--dt-item-x` ve türevleri (02 · Ölçek); uygulama bunları ezerek paketi büyütüp küçültebilir. DataSheet'in ortak parçaları (buton, menü, popover, dialog) da büyür; Compact satır yoğunluğu değişmez.
35
+
36
+ ## 1.0.0 — 2026-10-28
37
+
38
+ İlk sürüm: Faz 0–7 (`docs/data-table/10-roadmap.md`).
39
+
40
+ ### DataTable
41
+
42
+ - 23 hücre tipi, sanal satırlar, sabit sütunlar, sütun menüsü (sırala, filtrele, sabitle, sığdır, taşı, gizle), yoğunluk ve dikey çizgiler (tercih adapter'ı).
43
+ - Sunucu ve istemci modu; `@request` / `@count`; durumlar (ilk yükleme, sorgu değişimi, yenileme, hata, stale, boş).
44
+ - Filtre çipleri (operatör + tipe göre editör, hazır tarih aralıkları), toolbar araması, sistem ve kişisel görünümler (`viewsAdapter`), Display.
45
+ - Seçim (sayfa kapsamlı), bulk bar, satır menüsü, satır detayı (expand), `row-click` / `row-open`.
46
+ - Sütun açıklaması (`description`: header tooltip'inde ikinci satır, Columns panelinde alt satır, `aria-describedby`). Satır aksiyonunda `when(row)` menüden gizler, `disabled(row)` gerekçesiyle pasifleştirir; `RowAction.inline` ⋯'nın solunda en fazla 2 ikon düğmesi; `RowAction` / `BulkAction.description` menüde ikinci satır, `BulkAction.when(rows)`. Uygulamanın satır hatası `rowError(row)` ile: kırmızı zemin, ⋯ hücresinde uyarı ikonu, satır tooltip'i.
47
+ - Telefon düzeni (kart < 640 px): birincil sütun sola sabit, 48 px satır ve seçim sütunu, 44 px dokunma hedefleri, sağ kenar solması; toolbar (görünüm · arama modu · Filter sayaçlı · ⋯); çip satırı tek düğme; alt sayfalar — Filters (taslak + Show results, değer editörü ve sütun seçici alt seviyeler, Sort), görünümler, ⋯ (Density/Columns/Sort/Export/…), bulk bar More; footer yalnızca Önceki / Sonraki.
48
+
49
+ ### DataSheet (`@medyat/vue-data-table/sheet`)
50
+
51
+ - Hücre odaklı klavye, yerinde editörler (metin, sayı/para, seçenek combobox, tarih), doğrulama (tip → required → validate → warn, çapraz kural), formül çubuğu, status bar.
52
+ - Pano (TSV + HTML, yerel ayar çıkarımı), fill handle ve ⌘D, 100 adımlık geri al/yinele, Find in grid, seçim özeti.
53
+ - Satır partisi (Add row / Insert / Remove from list), `lookupKeys` ile New / Update, anahtar tekilliği, yerel sıralama, All / Changed / Errors.
54
+ - `optionEnabled(option, row)` ile satıra göre seçenek kapatma: kapalı seçenek editörde gizlenir, yapıştırma veya doldurmayla gelirse yalnızca değişen hücrede hata verir.
55
+ - Kayıt akışı: hata dialog'u, `@save`, `saving` ilerlemesi, `applyResult`, Partly saved şeridi, Copy errors, ayrılma koruması.
56
+ - Excel/CSV içe aktarma (`parseFile`; başlık satırı tespiti, otomatik eşleme, önizleme, yeni anahtarlar; `parseFile` hata fırlatırsa sebep dialog'da görünür), Export olayı, telefonda salt okunur.
57
+
58
+ ### Erişilebilirlik
59
+
60
+ - ARIA ızgara rolleri, iki roving tabindex modeli, `aria-live` duyuruları, hata balonları `aria-describedby`, `forced-colors` ve `prefers-reduced-motion`, axe-core taraması (WCAG 2.1 AA, kritik/ciddi ihlal yok).
61
+
62
+ ### Bilinen sınırlar
63
+
64
+ - Telefonda satır ⋯ menüsü ve sütun başlığı menüsü alt sayfa değil, açılır menü olarak kalır; Filters alt sayfasındaki Sort tek kuraldır (ikincil kurallar Show results'ta düşer); kişi listesindeki Me satırında gerçek ad gösterilmez. NVDA/VoiceOver turu elle yapılmadı.
65
+ - Sheet'te `ajax`/`user` hücreleri yalnızca özel editörle düzenlenir, `multiselect` yerleşik editörle (T11); `Alt↓` seçici açma yok. `tags` sütun tipi yoktur (D37); sabit seçenekli çoklu değer `multiselect`'tir.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Medyat
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,180 @@
1
- # Temporary Holding Version
1
+ # @medyat/vue-data-table
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Vue 3 için `DataTable` (liste) ve `DataSheet` (toplu düzenleme): ortak çekirdek, iki bileşen, iki giriş noktası. Paket veri çekmez ve kaydetmez (D18): olay yayar (`@request`, `@count`, `@save`, `@export`), uygulama HTTP'yi yapar ve sonucu geri verir.
4
+
5
+ Spesifikasyon `docs/data-table/` (karar günlüğü `README.md`, bileşenler `05`/`07`, tipler `03`, filtreler/görünümler `04`, erişilebilirlik `08`, i18n `09`), tasarım teslimi `docs/handoff/`, çalışma kuralları `CLAUDE.md`.
6
+
7
+ ## Kurulum
8
+
9
+ ```bash
10
+ pnpm add @medyat/vue-data-table reka-ui vue
11
+ ```
12
+
13
+ ```ts
14
+ // main.ts
15
+ import { createDataTable, createLocalStoragePreferences, createLocalStorageViews } from '@medyat/vue-data-table'
16
+ import '@medyat/vue-data-table/style.css'
17
+
18
+ app.use(
19
+ createDataTable({
20
+ locale: 'tr',
21
+ viewsAdapter: createLocalStorageViews({ scope: 'myapp' }), // kişisel görünümler; kendi adapter'ınızı da verebilirsiniz
22
+ preferences: createLocalStoragePreferences({ scope: 'myapp' }), // yoğunluk, çizgiler, sayfa boyutu
23
+ }),
24
+ )
25
+ ```
26
+
27
+ shadcn-vue temasını devralmak için ek olarak `@medyat/vue-data-table/shadcn-bridge.css` (veya HSL tabanlı tema için `shadcn-bridge-hsl.css`) yüklenir.
28
+
29
+ ## DataTable (liste)
30
+
31
+ Sütun tanımları feature'ın kendi dosyasında yaşar (D21); hücre özelleştirmesi `cell` fonksiyonuyla, slot yok.
32
+
33
+ ```vue
34
+ <script setup lang="ts">
35
+ import { DataTable, type ColumnDef, type TableRequest } from '@medyat/vue-data-table'
36
+
37
+ const columns: Array<ColumnDef<Order>> = [
38
+ { id: 'number', header: 'Order no.', type: 'id', primary: true, pinned: 'left', href: (r) => `/orders/${r.id}` },
39
+ { id: 'customer', header: 'Customer', type: 'string' },
40
+ { id: 'status', header: 'Status', type: 'select', options: statusOptions },
41
+ { id: 'dueAt', header: 'Due date', type: 'date', overdue: true },
42
+ { id: 'value', header: 'Value', type: 'currency', currency: 'TRY' },
43
+ ]
44
+ const rows = ref<Order[]>([])
45
+ const hasMore = ref(false)
46
+
47
+ // Sunucu modu: her talep (sayfa, sıralama, arama, filtreler) buradan geçer; paket yeniden denemez, önbelleklemez.
48
+ async function onRequest({ query, signal }: TableRequest) {
49
+ const { data } = await axios.get('/api/orders', { params: toLaravelParams(query), signal })
50
+ rows.value = data.data
51
+ hasMore.value = data.next_page_url !== null
52
+ }
53
+ </script>
54
+
55
+ <template>
56
+ <DataTable
57
+ table-id="orders"
58
+ mode="server"
59
+ :columns="columns"
60
+ :rows="rows"
61
+ :has-more="hasMore"
62
+ :entity-name="{ one: 'order', other: 'orders' }"
63
+ selectable
64
+ :bulk-actions="bulkActions"
65
+ :row-actions="rowActions"
66
+ expand
67
+ @request="onRequest"
68
+ @row-open="onRowOpen"
69
+ >
70
+ <template #expanded="{ row }"><OrderOperations :order="row" /></template>
71
+ </DataTable>
72
+ </template>
73
+ ```
74
+
75
+ ### `row-open` tarifleri
76
+
77
+ Birincil hücre gerçek bir `<a href>`'tir (D6): ⌘/orta tık tarayıcıya kalır, düz tık `row-open` yayar. Dinleyici `preventDefault` yapmazsa tarayıcı gider.
78
+
79
+ ```ts
80
+ // Vue Router
81
+ const router = useRouter()
82
+ const onRowOpen = ({ href, event }: { row: Order; href: string; event: MouseEvent }) => {
83
+ event.preventDefault()
84
+ router.push(href)
85
+ }
86
+
87
+ // Inertia
88
+ import { router } from '@inertiajs/vue3'
89
+ const onRowOpen = ({ href, event }) => {
90
+ event.preventDefault()
91
+ router.visit(href)
92
+ }
93
+ ```
94
+
95
+ ### Laravel talebi
96
+
97
+ `TableRequest.query` → `page`, `size`, `sort` (`[{ column, dir }]`), `search`, `filters` (`FilterCondition[]`, JSON), `fields`. Sunucu `simplePaginate` ile `{ data, next_page_url }` döner; `@count` ayrı bir `count` ucu çağırır (`{ total }`). Playground'daki `playground/server/mock-api.ts` aynı sözleşmeyi uygular.
98
+
99
+ ## DataSheet (toplu düzenleme)
100
+
101
+ Ayrı giriş noktası: `@medyat/vue-data-table/sheet`. Sütunlar varsayılan salt okunurdur; `editable`, `required`, `validate`, `warn`, `hint`, `importAliases` ile açılır. Değişiklikler taslakta birikir, tek **Save** yeni + değişen satırları `@save` ile teslim eder; uygulama anahtara göre upsert yapar ve `applyResult()` ile sonucu bildirir (D11). Asla silmez (D12).
102
+
103
+ ```vue
104
+ <script setup lang="ts">
105
+ import { DataSheet, type DataSheetHandle, type SheetChanges } from '@medyat/vue-data-table/sheet'
106
+
107
+ const sheet = useTemplateRef<DataSheetHandle>('sheet')
108
+ const saving = ref<boolean | { done: number; total: number }>(false)
109
+
110
+ // 07 §16: 500'lük parçalar sırayla; zaman aşımı, yeniden deneme ve Stop uygulamanındır.
111
+ async function onSave({ rows }: SheetChanges) {
112
+ saving.value = { done: 0, total: rows.length }
113
+ for (const chunk of chunksOf(rows, 500)) {
114
+ const { data } = await axios.post('/api/products/bulk-upsert', {
115
+ key: 'sku',
116
+ rows: chunk.map((r) => ({ client_id: r.clientId, key: r.key, op: r.op, values: r.values })),
117
+ })
118
+ sheet.value!.applyResult(
119
+ data.results.map((r) => ({
120
+ clientId: r.client_id,
121
+ status: r.status,
122
+ fieldErrors: r.field_errors,
123
+ rowError: r.row_error,
124
+ row: r.row,
125
+ })),
126
+ )
127
+ saving.value = { done: saving.value.done + chunk.length, total: rows.length }
128
+ }
129
+ saving.value = false
130
+ }
131
+ </script>
132
+
133
+ <template>
134
+ <DataSheet
135
+ ref="sheet"
136
+ table-id="products"
137
+ key-column="sku"
138
+ :columns="columns"
139
+ :rows="rows"
140
+ :loading="loading"
141
+ :saving="saving"
142
+ :lookup-keys="(keys) => axios.post('/api/products/lookup-keys', { keys }).then((r) => r.data)"
143
+ :new-row-defaults="() => ({ unit: 'pcs', vat: 20, active: true })"
144
+ :parse-file="parseWithExceljs"
145
+ @save="onSave"
146
+ @export="writeFile"
147
+ />
148
+ </template>
149
+ ```
150
+
151
+ Dosya okuma ve yazma uygulamanındır (D18): `parseFile` dosyayı ham satırlara çevirir (başlık tespiti ve eşleme paketindedir), `@export` yalnızca satır ve sütunları verir. Hazır tarif: `playground/src/pages/T11Sheet.vue` — exceljs ile `.xlsx` okuma (formül, zengin metin ve köprü düz değere iner) ve `.xlsx` / `;` ayrılmış BOM'lu `.csv` yazıp indirme.
152
+
153
+ Sunucu notları (07 §16): her satırı bağımsız işleyin (satır başına doğrulama ve savepoint), eşleme anahtara göre (`op` ipucudur), `update` satırlarında yalnızca gelen alanları güncelleyin, benzersizlik çakışmaları alan hatası olarak dönsün (500 değil), istek başına en fazla 500 satır.
154
+
155
+ Ayrılma koruması: paket `beforeunload` uyarısını kendisi verir; yönlendirici koruması için `sheet.value.isDirty()`.
156
+
157
+ ## Erişilebilirlik ve klavye
158
+
159
+ İki roving tabindex modeli: listede satır odaklıdır (oklar satırlar arası, `→` satırın widget'larına), sheet'te hücre odaklıdır (Excel kısayolları: `F2`, `↵`, `Tab`, `⌘C/X/V`, `⌘D`, `⌘Z`, `F8`, `⇧F10`). Tam liste `docs/data-table/08-accessibility-keyboard.md`. Duyurular tek `aria-live` bölgesinden; `forced-colors` ve `prefers-reduced-motion` desteklenir; Playwright'ta axe-core taraması (`e2e/a11y.spec.ts`).
160
+
161
+ ## Geliştirme
162
+
163
+ Node 22+ ve pnpm (corepack ile): `corepack enable` bir kez, sonra `pnpm install`.
164
+
165
+ | Komut | Ne yapar |
166
+ | ----------------------------------- | --------------------------------------------------------------------------------------------------- |
167
+ | `pnpm dev` | Playground (`playground/`, http://localhost:5174); sahte API `/api/orders`, `/api/products` |
168
+ | `pnpm test` | Vitest: token ↔ 02, kontrast, i18n ↔ 09, ESLint sınırları, bileşenler, depo, pano, içe aktarma |
169
+ | `pnpm test:e2e` | Playwright (playground'a karşı; axe taraması dahil) |
170
+ | `pnpm typecheck` · `pnpm lint` | vue-tsc, ESLint (import sınırları dahil) |
171
+ | `pnpm format` · `pnpm format:check` | Prettier (biçim yalnızca Prettier'ın; ESLint biçim kuralı taşımaz) |
172
+ | `pnpm build` | `dist/`: `index.js`, `sheet.js`, `style.css`, köprü CSS'leri, `.d.ts` |
173
+ | `pnpm gen:docs` | 02 → `src/styles/tokens.css`, 09 → `src/core/i18n/{en,tr}.ts` (üretilmiş dosyalar elle düzenlenmez) |
174
+ | `pnpm check` | gen:docs + typecheck + lint + format:check + test |
175
+
176
+ Token ve metin değişikliği dokümanda yapılır, sonra `pnpm gen:docs`; testler dokümanla kodun ayrışmasını yakalar. Sürüm notları `CHANGELOG.md`.
177
+
178
+ ## Lisans
179
+
180
+ MIT · © 2026 Medyat
@@ -0,0 +1,251 @@
1
+ import { W as e } from "./query-CGNWUi2E.js";
2
+ import { Fragment as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createTextVNode as s, createVNode as c, defineComponent as l, mergeModels as u, normalizeClass as d, openBlock as f, ref as p, renderList as m, toDisplayString as h, unref as g, useModel as _, vModelText as v, watch as y, withCtx as b, withDirectives as x } from "vue";
3
+ import { PhDotsSixVertical as S, PhLock as ee, PhMagnifyingGlass as te, PhPushPin as C } from "@phosphor-icons/vue";
4
+ import { DialogClose as ne, DialogContent as re, DialogOverlay as w, DialogPortal as T, DialogRoot as E, DialogTitle as D, RadioGroupIndicator as O, RadioGroupItem as ie, RadioGroupRoot as ae, SwitchRoot as k, SwitchThumb as A } from "reka-ui";
5
+ import { Accessibility as j } from "@dnd-kit/dom";
6
+ import { DragDropProvider as oe } from "@dnd-kit/vue";
7
+ import { isSortable as M, useSortable as N } from "@dnd-kit/vue/sortable";
8
+ //#region src/core/toolbar/ColumnsDialogRow.vue?vue&type=script&setup=true&lang.ts
9
+ var P = ["data-col"], F = ["disabled", "aria-label"], I = { class: "dt-col-name" }, L = {
10
+ key: 0,
11
+ class: "dt-col-desc"
12
+ }, R = /* @__PURE__ */ l({
13
+ __name: "ColumnsDialogRow",
14
+ props: {
15
+ column: {},
16
+ index: {},
17
+ disabled: { type: Boolean },
18
+ pinned: { type: Boolean }
19
+ },
20
+ emits: ["update:visible"],
21
+ setup(t, { emit: n }) {
22
+ let l = t, u = n, { i18n: m } = e(), _ = p(null), v = p(null), { isDragSource: y } = N({
23
+ id: () => l.column.id,
24
+ index: () => l.index,
25
+ disabled: () => l.disabled,
26
+ element: _,
27
+ handle: v
28
+ });
29
+ return (e, n) => (f(), a("li", {
30
+ ref_key: "element",
31
+ ref: _,
32
+ class: d(["dt-col-row", {
33
+ "is-hidden": !t.column.visible,
34
+ "is-dragging": g(y)
35
+ }]),
36
+ "data-col": t.column.id
37
+ }, [
38
+ o("button", {
39
+ ref_key: "handle",
40
+ ref: v,
41
+ type: "button",
42
+ class: "dt-icon-btn-xs dt-col-handle",
43
+ disabled: t.disabled,
44
+ "aria-label": g(m).t("columns.reorder", { column: t.column.def.header })
45
+ }, [c(g(S), {
46
+ size: 16,
47
+ weight: "bold",
48
+ "aria-hidden": "true"
49
+ })], 8, F),
50
+ o("span", I, [o("span", null, [s(h(t.column.def.header) + " ", 1), t.pinned ? (f(), r(g(C), {
51
+ key: 0,
52
+ size: 12,
53
+ class: "dt-col-pin",
54
+ "aria-label": g(m).t("columns.pinned")
55
+ }, null, 8, ["aria-label"])) : i("", !0)]), t.column.def.description ? (f(), a("span", L, h(t.column.def.description), 1)) : i("", !0)]),
56
+ c(g(k), {
57
+ class: "dt-switch dt-col-switch",
58
+ "model-value": t.column.visible,
59
+ disabled: !t.column.canHide,
60
+ "aria-label": t.column.def.header,
61
+ "onUpdate:modelValue": n[0] ||= (e) => u("update:visible", e)
62
+ }, {
63
+ default: b(() => [c(g(A), { class: "dt-switch-thumb" })]),
64
+ _: 1
65
+ }, 8, [
66
+ "model-value",
67
+ "disabled",
68
+ "aria-label"
69
+ ])
70
+ ], 10, P));
71
+ }
72
+ }), z = { class: "dt-cols-body" }, B = {
73
+ key: 0,
74
+ class: "dt-cols-pins"
75
+ }, V = ["id"], H = { class: "dt-cols-desc" }, U = { class: "dt-cols-section dt-cols-main" }, W = { class: "dt-cols-title" }, G = { class: "dt-pop-value" }, K = { class: "dt-cols-desc" }, q = { class: "dt-input has-icon dt-cols-find" }, se = { class: "dt-input-icon" }, ce = ["placeholder", "aria-label"], le = { class: "dt-cols-list" }, ue = { class: "dt-col-name" }, de = {
76
+ key: 0,
77
+ class: "dt-col-desc"
78
+ }, fe = { class: "dt-cols-foot" }, pe = {
79
+ type: "button",
80
+ class: "dt-btn"
81
+ }, J = /* @__PURE__ */ l({
82
+ __name: "ColumnsDialog",
83
+ props: /*@__PURE__*/ u({
84
+ columns: {},
85
+ phone: { type: Boolean }
86
+ }, {
87
+ open: {
88
+ type: Boolean,
89
+ default: !1
90
+ },
91
+ openModifiers: {}
92
+ }),
93
+ emits: /*@__PURE__*/ u(["save", "closeAutoFocus"], ["update:open"]),
94
+ setup(l, { emit: u }) {
95
+ let S = l, C = u, k = _(l, "open"), { i18n: A } = e(), N = [
96
+ 0,
97
+ 1,
98
+ 2
99
+ ], P = p([]), F = p(0), I = p(0), L = p(""), J = (e) => Math.min(2, S.columns.filter((t) => t.pinned === e && t.visible && !t.fixed).length);
100
+ y(k, (e) => {
101
+ e && (P.value = S.columns.map((e) => ({ ...e })), F.value = J("start"), I.value = J("end"), L.value = "");
102
+ }, { immediate: !0 });
103
+ let Y = n(() => P.value.filter((e) => e.fixed)), me = (e) => !L.value || e.def.header.toLocaleLowerCase().includes(L.value.toLocaleLowerCase()), X = n(() => P.value.filter((e) => !e.fixed && me(e))), he = n(() => {
104
+ if (S.phone) return /* @__PURE__ */ new Set();
105
+ let e = P.value.filter((e) => e.visible && !e.fixed).map((e) => e.id), t = e.slice(0, F.value);
106
+ return /* @__PURE__ */ new Set([...t, ...I.value ? e.slice(t.length).slice(-I.value) : []]);
107
+ }), Z = n(() => P.value.filter((e) => e.canHide && !e.fixed)), Q = n(() => Z.value.every((e) => e.visible)), ge = ({ operation: { source: e }, canceled: t }) => {
108
+ if (t || !M(e) || e.initialIndex === e.index) return;
109
+ let n = [...X.value], [r] = n.splice(e.initialIndex, 1);
110
+ n.splice(e.index, 0, r), P.value = [...Y.value, ...n];
111
+ }, _e = (e) => P.value.find((t) => t.id === e)?.def.header ?? String(e), $ = ({ source: e }) => e && M(e) ? {
112
+ column: _e(e.id),
113
+ position: e.index + 1,
114
+ total: X.value.length
115
+ } : void 0, ve = (e) => [...e.filter((e) => e !== j), j.configure({
116
+ screenReaderInstructions: { draggable: A.t("columns.dragInstructions") },
117
+ announcements: {
118
+ dragstart: ({ operation: e }) => $(e) ? A.t("columns.dragStart", $(e)) : void 0,
119
+ dragover: ({ operation: e }) => $(e) && e.target?.id !== e.source?.id ? A.t("columns.dragOver", $(e)) : void 0,
120
+ dragend: ({ operation: e, canceled: t }) => $(e) ? A.t(t ? "columns.dragCancel" : "columns.dragEnd", $(e)) : void 0
121
+ }
122
+ })], ye = () => {
123
+ let e = !Q.value;
124
+ for (let t of Z.value) t.visible = e;
125
+ }, be = () => {
126
+ C("save", {
127
+ order: P.value.map((e) => e.id),
128
+ visible: P.value.filter((e) => e.visible).map((e) => e.id),
129
+ start: S.phone ? J("start") : F.value,
130
+ end: S.phone ? J("end") : I.value
131
+ }), k.value = !1;
132
+ };
133
+ return (e, n) => (f(), r(g(E), {
134
+ open: k.value,
135
+ "onUpdate:open": n[2] ||= (e) => k.value = e
136
+ }, {
137
+ default: b(() => [c(g(T), null, {
138
+ default: b(() => [c(g(w), { class: "dt-scrim" }), c(g(re), {
139
+ class: d(["dt-dialog dt-cols-dialog", { "is-phone": l.phone }]),
140
+ "aria-describedby": void 0,
141
+ onCloseAutoFocus: n[1] ||= (e) => C("closeAutoFocus", e)
142
+ }, {
143
+ default: b(() => [
144
+ c(g(D), { class: "dt-sr-only" }, {
145
+ default: b(() => [s(h(g(A).t("display.columns")), 1)]),
146
+ _: 1
147
+ }),
148
+ o("div", z, [l.phone ? i("", !0) : (f(), a("div", B, [(f(), a(t, null, m(["start", "end"], (e) => o("section", {
149
+ key: e,
150
+ class: "dt-cols-section"
151
+ }, [
152
+ o("h3", {
153
+ id: `dt-cols-${e}`,
154
+ class: "dt-cols-title"
155
+ }, h(g(A).t(`columns.pin.${e}.title`)), 9, V),
156
+ o("p", H, h(g(A).t(`columns.pin.${e}.desc`)), 1),
157
+ c(g(ae), {
158
+ class: "dt-radio-group",
159
+ "aria-labelledby": `dt-cols-${e}`,
160
+ "model-value": e === "start" ? F.value : I.value,
161
+ "onUpdate:modelValue": (t) => e === "start" ? F.value = Number(t) : I.value = Number(t)
162
+ }, {
163
+ default: b(() => [(f(), a(t, null, m(N, (t) => o("label", {
164
+ key: t,
165
+ class: "dt-radio-row"
166
+ }, [c(g(ie), {
167
+ class: "dt-radio",
168
+ value: t
169
+ }, {
170
+ default: b(() => [c(g(O), { class: "dt-radio-dot" })]),
171
+ _: 1
172
+ }, 8, ["value"]), s(" " + h(g(A).t(`columns.pin.${e}.${t}`)), 1)])), 64))]),
173
+ _: 2
174
+ }, 1032, [
175
+ "aria-labelledby",
176
+ "model-value",
177
+ "onUpdate:modelValue"
178
+ ])
179
+ ])), 64))])), o("section", U, [
180
+ o("h3", W, [s(h(g(A).t("columns.title")) + " ", 1), o("span", G, h(g(A).t("columns.shownOf", {
181
+ shown: P.value.filter((e) => e.visible).length,
182
+ total: P.value.length
183
+ })), 1)]),
184
+ o("p", K, h(g(A).t("columns.desc")), 1),
185
+ o("label", q, [o("span", se, [c(g(te), {
186
+ size: 14,
187
+ "aria-hidden": "true"
188
+ })]), x(o("input", {
189
+ "onUpdate:modelValue": n[0] ||= (e) => L.value = e,
190
+ type: "search",
191
+ placeholder: g(A).t("columns.find"),
192
+ "aria-label": g(A).t("columns.find")
193
+ }, null, 8, ce), [[v, L.value]])]),
194
+ o("ul", le, [L.value ? i("", !0) : (f(!0), a(t, { key: 0 }, m(Y.value, (e) => (f(), a("li", {
195
+ key: e.id,
196
+ class: "dt-col-row is-fixed"
197
+ }, [o("span", ue, [o("span", null, h(e.def.header), 1), e.def.description ? (f(), a("span", de, h(e.def.description), 1)) : i("", !0)]), c(g(ee), {
198
+ size: 14,
199
+ class: "dt-col-lock",
200
+ "aria-label": g(A).t("columns.alwaysShown")
201
+ }, null, 8, ["aria-label"])]))), 128)), c(g(oe), {
202
+ plugins: ve,
203
+ onDragEnd: ge
204
+ }, {
205
+ default: b(() => [(f(!0), a(t, null, m(X.value, (e, t) => (f(), r(R, {
206
+ key: e.id,
207
+ column: e,
208
+ index: t,
209
+ disabled: !!L.value,
210
+ pinned: he.value.has(e.id),
211
+ "onUpdate:visible": (t) => e.visible = t
212
+ }, null, 8, [
213
+ "column",
214
+ "index",
215
+ "disabled",
216
+ "pinned",
217
+ "onUpdate:visible"
218
+ ]))), 128))]),
219
+ _: 1
220
+ })])
221
+ ])]),
222
+ o("div", fe, [
223
+ o("button", {
224
+ type: "button",
225
+ class: "dt-btn",
226
+ onClick: ye
227
+ }, h(g(A).t(Q.value ? "columns.hideAll" : "columns.showAll")), 1),
228
+ n[3] ||= o("span", { class: "dt-pop-end" }, null, -1),
229
+ c(g(ne), { "as-child": "" }, {
230
+ default: b(() => [o("button", pe, h(g(A).t("common.cancel")), 1)]),
231
+ _: 1
232
+ }),
233
+ o("button", {
234
+ type: "button",
235
+ class: "dt-btn dt-btn-primary",
236
+ onClick: be
237
+ }, h(g(A).t("common.save")), 1)
238
+ ])
239
+ ]),
240
+ _: 1
241
+ }, 8, ["class"])]),
242
+ _: 1
243
+ })]),
244
+ _: 1
245
+ }, 8, ["open"]));
246
+ }
247
+ });
248
+ //#endregion
249
+ export { J as default };
250
+
251
+ //# sourceMappingURL=ColumnsDialog-dngip-aF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColumnsDialog-dngip-aF.js","names":["_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_createVNode","_createTextVNode","_toDisplayString","_createBlock","_createCommentVNode","_withCtx","_sfc_main","_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_normalizeClass","_createTextVNode","_toDisplayString","_createElementVNode","_createElementBlock","_Fragment","_renderList","_createCommentVNode","_withDirectives","_vModelText","ColumnsDialogRow","_sfc_main","useDataTableContext","_hoisted_1$1","_hoisted_2$1","_hoisted_3$1","_hoisted_4$1","ColumnsDialogRow_default","defineComponent","__emit","props","__props","emit","element","ref","handle","useSortable","openBlock","createElementBlock","normalizeClass","unref","isDragSource","createElementVNode","i18n","createVNode","PhDotsSixVertical","createTextVNode","toDisplayString","createBlock","PhPushPin","createCommentVNode","SwitchRoot","_cache","v","withCtx","SwitchThumb","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","ColumnsDialog_default","\"open\"","\"openModifiers\"","open","useModel","PIN_COUNTS","rows","start","end","find","pinCount","c","side","o","fixedRows","computed","matches","listed","willPin","free","left","hideable","allShown","onDragEnd","canceled","isSortable","source","list","moved","nameOf","id","at","plugins","defaults","p","Accessibility","operation","toggleAll","save","DialogRoot","$event","DialogPortal","DialogOverlay","DialogContent","DialogTitle","Fragment","renderList","RadioGroupRoot","n","RadioGroupItem","RadioGroupIndicator","PhMagnifyingGlass","withDirectives","vModelText","PhLock","DragDropProvider","i","DialogClose"],"sources":["../src/core/toolbar/ColumnsDialogRow.vue","../src/core/toolbar/ColumnsDialogRow.vue","../src/core/toolbar/ColumnsDialog.vue","../src/core/toolbar/ColumnsDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// Columns dialog'unda sıralanabilir satır (D22, D45): tutamaçtan fare/dokunmatik sürükleme ve klavye (Space al · ↑↓ · Space bırak · Esc).\n// useSortable DragDropProvider'ın alt bileşeninde çağrılmak zorunda; bu yüzden satır ayrı bileşen.\nimport { PhDotsSixVertical, PhPushPin } from '@phosphor-icons/vue'\nimport { useSortable } from '@dnd-kit/vue/sortable'\nimport { SwitchRoot, SwitchThumb } from 'reka-ui'\nimport { ref } from 'vue'\nimport { useDataTableContext } from '../plugin'\nimport type { PanelColumn } from './ColumnsDialog.vue'\n\nconst props = defineProps<{\n column: PanelColumn\n index: number\n /** Arama süzerken sıralama kapalı: süzülmüş listede taşımak gizli satırların yerini belirsizleştirir. */\n disabled: boolean\n /** Kaydedilince sabitlenecek. */\n pinned: boolean\n}>()\nconst emit = defineEmits<{ 'update:visible': [visible: boolean] }>()\nconst { i18n } = useDataTableContext()\n\nconst element = ref<HTMLElement | null>(null)\nconst handle = ref<HTMLElement | null>(null)\nconst { isDragSource } = useSortable({\n id: () => props.column.id,\n index: () => props.index,\n disabled: () => props.disabled,\n element,\n handle,\n})\n</script>\n\n<template>\n <li\n ref=\"element\"\n class=\"dt-col-row\"\n :class=\"{ 'is-hidden': !column.visible, 'is-dragging': isDragSource }\"\n :data-col=\"column.id\"\n >\n <button\n ref=\"handle\"\n type=\"button\"\n class=\"dt-icon-btn-xs dt-col-handle\"\n :disabled=\"disabled\"\n :aria-label=\"i18n.t('columns.reorder', { column: column.def.header })\"\n >\n <PhDotsSixVertical :size=\"16\" weight=\"bold\" aria-hidden=\"true\" />\n </button>\n <span class=\"dt-col-name\">\n <span>\n {{ column.def.header }}\n <PhPushPin v-if=\"pinned\" :size=\"12\" class=\"dt-col-pin\" :aria-label=\"i18n.t('columns.pinned')\" />\n </span>\n <span v-if=\"column.def.description\" class=\"dt-col-desc\">{{ column.def.description }}</span>\n </span>\n <SwitchRoot\n class=\"dt-switch dt-col-switch\"\n :model-value=\"column.visible\"\n :disabled=\"!column.canHide\"\n :aria-label=\"column.def.header\"\n @update:model-value=\"(v) => emit('update:visible', v)\"\n >\n <SwitchThumb class=\"dt-switch-thumb\" />\n </SwitchRoot>\n </li>\n</template>\n","<script setup lang=\"ts\">\n// Columns dialog'unda sıralanabilir satır (D22, D45): tutamaçtan fare/dokunmatik sürükleme ve klavye (Space al · ↑↓ · Space bırak · Esc).\n// useSortable DragDropProvider'ın alt bileşeninde çağrılmak zorunda; bu yüzden satır ayrı bileşen.\nimport { PhDotsSixVertical, PhPushPin } from '@phosphor-icons/vue'\nimport { useSortable } from '@dnd-kit/vue/sortable'\nimport { SwitchRoot, SwitchThumb } from 'reka-ui'\nimport { ref } from 'vue'\nimport { useDataTableContext } from '../plugin'\nimport type { PanelColumn } from './ColumnsDialog.vue'\n\nconst props = defineProps<{\n column: PanelColumn\n index: number\n /** Arama süzerken sıralama kapalı: süzülmüş listede taşımak gizli satırların yerini belirsizleştirir. */\n disabled: boolean\n /** Kaydedilince sabitlenecek. */\n pinned: boolean\n}>()\nconst emit = defineEmits<{ 'update:visible': [visible: boolean] }>()\nconst { i18n } = useDataTableContext()\n\nconst element = ref<HTMLElement | null>(null)\nconst handle = ref<HTMLElement | null>(null)\nconst { isDragSource } = useSortable({\n id: () => props.column.id,\n index: () => props.index,\n disabled: () => props.disabled,\n element,\n handle,\n})\n</script>\n\n<template>\n <li\n ref=\"element\"\n class=\"dt-col-row\"\n :class=\"{ 'is-hidden': !column.visible, 'is-dragging': isDragSource }\"\n :data-col=\"column.id\"\n >\n <button\n ref=\"handle\"\n type=\"button\"\n class=\"dt-icon-btn-xs dt-col-handle\"\n :disabled=\"disabled\"\n :aria-label=\"i18n.t('columns.reorder', { column: column.def.header })\"\n >\n <PhDotsSixVertical :size=\"16\" weight=\"bold\" aria-hidden=\"true\" />\n </button>\n <span class=\"dt-col-name\">\n <span>\n {{ column.def.header }}\n <PhPushPin v-if=\"pinned\" :size=\"12\" class=\"dt-col-pin\" :aria-label=\"i18n.t('columns.pinned')\" />\n </span>\n <span v-if=\"column.def.description\" class=\"dt-col-desc\">{{ column.def.description }}</span>\n </span>\n <SwitchRoot\n class=\"dt-switch dt-col-switch\"\n :model-value=\"column.visible\"\n :disabled=\"!column.canHide\"\n :aria-label=\"column.def.header\"\n @update:model-value=\"(v) => emit('update:visible', v)\"\n >\n <SwitchThumb class=\"dt-switch-thumb\" />\n </SwitchRoot>\n </li>\n</template>\n","<script setup lang=\"ts\">\n// Manage columns dialog'u (05 §5, D45): solda konumsal sabitleme (ilk / son 0–2 sütun), sağda bul · liste (tutamaç · göster/gizle).\n// Taslak üzerinde çalışır: Save tek seferde uygular, kapatmak ya da Cancel hiçbir şeyi değiştirmez. Sıralama @dnd-kit ile\n// sürükle-bırak; klavye ve ekran okuyucu duyuruları kütüphanenin Accessibility eklentisinden, metinler i18n'den (D22 revize).\nimport { Accessibility, type Draggable } from '@dnd-kit/dom'\nimport {\n DragDropProvider,\n type DragDropProviderProps,\n type DragEndEvent,\n type DragOverEvent,\n type DragStartEvent,\n} from '@dnd-kit/vue'\nimport { isSortable } from '@dnd-kit/vue/sortable'\nimport { PhLock, PhMagnifyingGlass } from '@phosphor-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n DialogOverlay,\n DialogPortal,\n DialogRoot,\n DialogTitle,\n RadioGroupIndicator,\n RadioGroupItem,\n RadioGroupRoot,\n} from 'reka-ui'\nimport { computed, ref, watch } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { useDataTableContext } from '../plugin'\nimport ColumnsDialogRow from './ColumnsDialogRow.vue'\n\nexport interface PanelColumn {\n id: string\n def: ColumnDef\n visible: boolean\n pinned: 'start' | 'end' | null\n canHide: boolean\n /** Her zaman sola sabit (birincil, sheet anahtarı): listede kilitli, taşınmaz, gizlenmez. */\n fixed: boolean\n}\nexport interface ColumnsDraft {\n order: string[]\n visible: string[]\n start: number\n end: number\n}\n\nconst props = defineProps<{\n columns: PanelColumn[]\n /** Telefonda sabitleme uygulanmaz (05 §11); sol bölüm gizlenir. */\n phone?: boolean\n}>()\nconst emit = defineEmits<{\n save: [draft: ColumnsDraft]\n /** Açan popover/sayfa kapandığı için odağı nereye döndüreceğine çağıran karar verir. */\n closeAutoFocus: [e: Event]\n}>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n } = useDataTableContext()\n\nconst PIN_COUNTS = [0, 1, 2] as const\nconst rows = ref<PanelColumn[]>([])\nconst start = ref(0)\nconst end = ref(0)\nconst find = ref('')\nconst pinCount = (side: 'start' | 'end') =>\n Math.min(2, props.columns.filter((c) => c.pinned === side && c.visible && !c.fixed).length)\nwatch(\n open,\n (o) => {\n if (!o) return\n rows.value = props.columns.map((c) => ({ ...c }))\n start.value = pinCount('start')\n end.value = pinCount('end')\n find.value = ''\n },\n { immediate: true },\n)\n\nconst fixedRows = computed(() => rows.value.filter((c) => c.fixed))\nconst matches = (c: PanelColumn) =>\n !find.value || c.def.header.toLocaleLowerCase().includes(find.value.toLocaleLowerCase())\nconst listed = computed(() => rows.value.filter((c) => !c.fixed && matches(c)))\n/** Kaydedilince sabitlenecek sütunlar: listede raptiye ile gösterilir. */\nconst willPin = computed(() => {\n if (props.phone) return new Set<string>()\n const free = rows.value.filter((c) => c.visible && !c.fixed).map((c) => c.id)\n const left = free.slice(0, start.value)\n return new Set([...left, ...(end.value ? free.slice(left.length).slice(-end.value) : [])])\n})\nconst hideable = computed(() => rows.value.filter((c) => c.canHide && !c.fixed))\nconst allShown = computed(() => hideable.value.every((c) => c.visible))\n\n/** Bırakınca taslak sırası güncellenir (arama yokken listed = sabit olmayan tüm satırlar). */\nconst onDragEnd = ({ operation: { source }, canceled }: DragEndEvent) => {\n if (canceled || !isSortable(source) || source.initialIndex === source.index) return\n const list = [...listed.value]\n const [moved] = list.splice(source.initialIndex, 1)\n list.splice(source.index, 0, moved!)\n rows.value = [...fixedRows.value, ...list]\n}\nconst nameOf = (id: unknown) => rows.value.find((c) => c.id === id)?.def.header ?? String(id)\nconst at = ({ source }: { source: Draggable | null }) =>\n source && isSortable(source)\n ? { column: nameOf(source.id), position: source.index + 1, total: listed.value.length }\n : undefined\nconst plugins: DragDropProviderProps['plugins'] = (defaults) => [\n ...defaults.filter((p) => p !== Accessibility),\n Accessibility.configure({\n screenReaderInstructions: { draggable: i18n.t('columns.dragInstructions') },\n announcements: {\n dragstart: ({ operation }: DragStartEvent) => (at(operation) ? i18n.t('columns.dragStart', at(operation)) : undefined),\n // Kütüphanenin varsayılanı gibi: hedef kaynağın kendisiyse (yer değişmedi) duyurma.\n dragover: ({ operation }: DragOverEvent) =>\n at(operation) && operation.target?.id !== operation.source?.id\n ? i18n.t('columns.dragOver', at(operation))\n : undefined,\n dragend: ({ operation, canceled }: DragEndEvent) =>\n at(operation) ? i18n.t(canceled ? 'columns.dragCancel' : 'columns.dragEnd', at(operation)) : undefined,\n },\n }),\n]\nconst toggleAll = () => {\n const v = !allShown.value\n for (const c of hideable.value) c.visible = v\n}\nconst save = () => {\n emit('save', {\n order: rows.value.map((c) => c.id),\n visible: rows.value.filter((c) => c.visible).map((c) => c.id),\n start: props.phone ? pinCount('start') : start.value,\n end: props.phone ? pinCount('end') : end.value,\n })\n open.value = false\n}\n</script>\n\n<template>\n <DialogRoot v-model:open=\"open\">\n <DialogPortal>\n <DialogOverlay class=\"dt-scrim\" />\n <DialogContent class=\"dt-dialog dt-cols-dialog\" :class=\"{ 'is-phone': phone }\" :aria-describedby=\"undefined\"\n @close-auto-focus=\"(e: Event) => emit('closeAutoFocus', e)\"\n >\n <DialogTitle class=\"dt-sr-only\">{{ i18n.t('display.columns') }}</DialogTitle>\n <div class=\"dt-cols-body\">\n <div v-if=\"!phone\" class=\"dt-cols-pins\">\n <section v-for=\"side in ['start', 'end'] as const\" :key=\"side\" class=\"dt-cols-section\">\n <h3 :id=\"`dt-cols-${side}`\" class=\"dt-cols-title\">{{ i18n.t(`columns.pin.${side}.title`) }}</h3>\n <p class=\"dt-cols-desc\">{{ i18n.t(`columns.pin.${side}.desc`) }}</p>\n <RadioGroupRoot\n class=\"dt-radio-group\"\n :aria-labelledby=\"`dt-cols-${side}`\"\n :model-value=\"side === 'start' ? start : end\"\n @update:model-value=\"(v) => (side === 'start' ? (start = Number(v)) : (end = Number(v)))\"\n >\n <label v-for=\"n in PIN_COUNTS\" :key=\"n\" class=\"dt-radio-row\">\n <RadioGroupItem class=\"dt-radio\" :value=\"n\">\n <RadioGroupIndicator class=\"dt-radio-dot\" />\n </RadioGroupItem>\n {{ i18n.t(`columns.pin.${side}.${n}`) }}\n </label>\n </RadioGroupRoot>\n </section>\n </div>\n <section class=\"dt-cols-section dt-cols-main\">\n <h3 class=\"dt-cols-title\">\n {{ i18n.t('columns.title') }}\n <span class=\"dt-pop-value\">\n {{ i18n.t('columns.shownOf', { shown: rows.filter((c) => c.visible).length, total: rows.length }) }}\n </span>\n </h3>\n <p class=\"dt-cols-desc\">{{ i18n.t('columns.desc') }}</p>\n <label class=\"dt-input has-icon dt-cols-find\">\n <span class=\"dt-input-icon\"><PhMagnifyingGlass :size=\"14\" aria-hidden=\"true\" /></span>\n <input\n v-model=\"find\"\n type=\"search\"\n :placeholder=\"i18n.t('columns.find')\"\n :aria-label=\"i18n.t('columns.find')\"\n />\n </label>\n <ul class=\"dt-cols-list\">\n <template v-if=\"!find\">\n <li v-for=\"c in fixedRows\" :key=\"c.id\" class=\"dt-col-row is-fixed\">\n <span class=\"dt-col-name\">\n <span>{{ c.def.header }}</span>\n <span v-if=\"c.def.description\" class=\"dt-col-desc\">{{ c.def.description }}</span>\n </span>\n <PhLock :size=\"14\" class=\"dt-col-lock\" :aria-label=\"i18n.t('columns.alwaysShown')\" />\n </li>\n </template>\n <DragDropProvider :plugins=\"plugins\" @drag-end=\"onDragEnd\">\n <ColumnsDialogRow\n v-for=\"(c, i) in listed\"\n :key=\"c.id\"\n :column=\"c\"\n :index=\"i\"\n :disabled=\"!!find\"\n :pinned=\"willPin.has(c.id)\"\n @update:visible=\"(v) => (c.visible = v)\"\n />\n </DragDropProvider>\n </ul>\n </section>\n </div>\n <div class=\"dt-cols-foot\">\n <button type=\"button\" class=\"dt-btn\" @click=\"toggleAll\">\n {{ i18n.t(allShown ? 'columns.hideAll' : 'columns.showAll') }}\n </button>\n <span class=\"dt-pop-end\" />\n <DialogClose as-child>\n <button type=\"button\" class=\"dt-btn\">{{ i18n.t('common.cancel') }}</button>\n </DialogClose>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" @click=\"save\">{{ i18n.t('common.save') }}</button>\n </div>\n </DialogContent>\n </DialogPortal>\n </DialogRoot>\n</template>\n","<script setup lang=\"ts\">\n// Manage columns dialog'u (05 §5, D45): solda konumsal sabitleme (ilk / son 0–2 sütun), sağda bul · liste (tutamaç · göster/gizle).\n// Taslak üzerinde çalışır: Save tek seferde uygular, kapatmak ya da Cancel hiçbir şeyi değiştirmez. Sıralama @dnd-kit ile\n// sürükle-bırak; klavye ve ekran okuyucu duyuruları kütüphanenin Accessibility eklentisinden, metinler i18n'den (D22 revize).\nimport { Accessibility, type Draggable } from '@dnd-kit/dom'\nimport {\n DragDropProvider,\n type DragDropProviderProps,\n type DragEndEvent,\n type DragOverEvent,\n type DragStartEvent,\n} from '@dnd-kit/vue'\nimport { isSortable } from '@dnd-kit/vue/sortable'\nimport { PhLock, PhMagnifyingGlass } from '@phosphor-icons/vue'\nimport {\n DialogClose,\n DialogContent,\n DialogOverlay,\n DialogPortal,\n DialogRoot,\n DialogTitle,\n RadioGroupIndicator,\n RadioGroupItem,\n RadioGroupRoot,\n} from 'reka-ui'\nimport { computed, ref, watch } from 'vue'\nimport type { ColumnDef } from '../../types/columns'\nimport { useDataTableContext } from '../plugin'\nimport ColumnsDialogRow from './ColumnsDialogRow.vue'\n\nexport interface PanelColumn {\n id: string\n def: ColumnDef\n visible: boolean\n pinned: 'start' | 'end' | null\n canHide: boolean\n /** Her zaman sola sabit (birincil, sheet anahtarı): listede kilitli, taşınmaz, gizlenmez. */\n fixed: boolean\n}\nexport interface ColumnsDraft {\n order: string[]\n visible: string[]\n start: number\n end: number\n}\n\nconst props = defineProps<{\n columns: PanelColumn[]\n /** Telefonda sabitleme uygulanmaz (05 §11); sol bölüm gizlenir. */\n phone?: boolean\n}>()\nconst emit = defineEmits<{\n save: [draft: ColumnsDraft]\n /** Açan popover/sayfa kapandığı için odağı nereye döndüreceğine çağıran karar verir. */\n closeAutoFocus: [e: Event]\n}>()\nconst open = defineModel<boolean>('open', { default: false })\nconst { i18n } = useDataTableContext()\n\nconst PIN_COUNTS = [0, 1, 2] as const\nconst rows = ref<PanelColumn[]>([])\nconst start = ref(0)\nconst end = ref(0)\nconst find = ref('')\nconst pinCount = (side: 'start' | 'end') =>\n Math.min(2, props.columns.filter((c) => c.pinned === side && c.visible && !c.fixed).length)\nwatch(\n open,\n (o) => {\n if (!o) return\n rows.value = props.columns.map((c) => ({ ...c }))\n start.value = pinCount('start')\n end.value = pinCount('end')\n find.value = ''\n },\n { immediate: true },\n)\n\nconst fixedRows = computed(() => rows.value.filter((c) => c.fixed))\nconst matches = (c: PanelColumn) =>\n !find.value || c.def.header.toLocaleLowerCase().includes(find.value.toLocaleLowerCase())\nconst listed = computed(() => rows.value.filter((c) => !c.fixed && matches(c)))\n/** Kaydedilince sabitlenecek sütunlar: listede raptiye ile gösterilir. */\nconst willPin = computed(() => {\n if (props.phone) return new Set<string>()\n const free = rows.value.filter((c) => c.visible && !c.fixed).map((c) => c.id)\n const left = free.slice(0, start.value)\n return new Set([...left, ...(end.value ? free.slice(left.length).slice(-end.value) : [])])\n})\nconst hideable = computed(() => rows.value.filter((c) => c.canHide && !c.fixed))\nconst allShown = computed(() => hideable.value.every((c) => c.visible))\n\n/** Bırakınca taslak sırası güncellenir (arama yokken listed = sabit olmayan tüm satırlar). */\nconst onDragEnd = ({ operation: { source }, canceled }: DragEndEvent) => {\n if (canceled || !isSortable(source) || source.initialIndex === source.index) return\n const list = [...listed.value]\n const [moved] = list.splice(source.initialIndex, 1)\n list.splice(source.index, 0, moved!)\n rows.value = [...fixedRows.value, ...list]\n}\nconst nameOf = (id: unknown) => rows.value.find((c) => c.id === id)?.def.header ?? String(id)\nconst at = ({ source }: { source: Draggable | null }) =>\n source && isSortable(source)\n ? { column: nameOf(source.id), position: source.index + 1, total: listed.value.length }\n : undefined\nconst plugins: DragDropProviderProps['plugins'] = (defaults) => [\n ...defaults.filter((p) => p !== Accessibility),\n Accessibility.configure({\n screenReaderInstructions: { draggable: i18n.t('columns.dragInstructions') },\n announcements: {\n dragstart: ({ operation }: DragStartEvent) => (at(operation) ? i18n.t('columns.dragStart', at(operation)) : undefined),\n // Kütüphanenin varsayılanı gibi: hedef kaynağın kendisiyse (yer değişmedi) duyurma.\n dragover: ({ operation }: DragOverEvent) =>\n at(operation) && operation.target?.id !== operation.source?.id\n ? i18n.t('columns.dragOver', at(operation))\n : undefined,\n dragend: ({ operation, canceled }: DragEndEvent) =>\n at(operation) ? i18n.t(canceled ? 'columns.dragCancel' : 'columns.dragEnd', at(operation)) : undefined,\n },\n }),\n]\nconst toggleAll = () => {\n const v = !allShown.value\n for (const c of hideable.value) c.visible = v\n}\nconst save = () => {\n emit('save', {\n order: rows.value.map((c) => c.id),\n visible: rows.value.filter((c) => c.visible).map((c) => c.id),\n start: props.phone ? pinCount('start') : start.value,\n end: props.phone ? pinCount('end') : end.value,\n })\n open.value = false\n}\n</script>\n\n<template>\n <DialogRoot v-model:open=\"open\">\n <DialogPortal>\n <DialogOverlay class=\"dt-scrim\" />\n <DialogContent class=\"dt-dialog dt-cols-dialog\" :class=\"{ 'is-phone': phone }\" :aria-describedby=\"undefined\"\n @close-auto-focus=\"(e: Event) => emit('closeAutoFocus', e)\"\n >\n <DialogTitle class=\"dt-sr-only\">{{ i18n.t('display.columns') }}</DialogTitle>\n <div class=\"dt-cols-body\">\n <div v-if=\"!phone\" class=\"dt-cols-pins\">\n <section v-for=\"side in ['start', 'end'] as const\" :key=\"side\" class=\"dt-cols-section\">\n <h3 :id=\"`dt-cols-${side}`\" class=\"dt-cols-title\">{{ i18n.t(`columns.pin.${side}.title`) }}</h3>\n <p class=\"dt-cols-desc\">{{ i18n.t(`columns.pin.${side}.desc`) }}</p>\n <RadioGroupRoot\n class=\"dt-radio-group\"\n :aria-labelledby=\"`dt-cols-${side}`\"\n :model-value=\"side === 'start' ? start : end\"\n @update:model-value=\"(v) => (side === 'start' ? (start = Number(v)) : (end = Number(v)))\"\n >\n <label v-for=\"n in PIN_COUNTS\" :key=\"n\" class=\"dt-radio-row\">\n <RadioGroupItem class=\"dt-radio\" :value=\"n\">\n <RadioGroupIndicator class=\"dt-radio-dot\" />\n </RadioGroupItem>\n {{ i18n.t(`columns.pin.${side}.${n}`) }}\n </label>\n </RadioGroupRoot>\n </section>\n </div>\n <section class=\"dt-cols-section dt-cols-main\">\n <h3 class=\"dt-cols-title\">\n {{ i18n.t('columns.title') }}\n <span class=\"dt-pop-value\">\n {{ i18n.t('columns.shownOf', { shown: rows.filter((c) => c.visible).length, total: rows.length }) }}\n </span>\n </h3>\n <p class=\"dt-cols-desc\">{{ i18n.t('columns.desc') }}</p>\n <label class=\"dt-input has-icon dt-cols-find\">\n <span class=\"dt-input-icon\"><PhMagnifyingGlass :size=\"14\" aria-hidden=\"true\" /></span>\n <input\n v-model=\"find\"\n type=\"search\"\n :placeholder=\"i18n.t('columns.find')\"\n :aria-label=\"i18n.t('columns.find')\"\n />\n </label>\n <ul class=\"dt-cols-list\">\n <template v-if=\"!find\">\n <li v-for=\"c in fixedRows\" :key=\"c.id\" class=\"dt-col-row is-fixed\">\n <span class=\"dt-col-name\">\n <span>{{ c.def.header }}</span>\n <span v-if=\"c.def.description\" class=\"dt-col-desc\">{{ c.def.description }}</span>\n </span>\n <PhLock :size=\"14\" class=\"dt-col-lock\" :aria-label=\"i18n.t('columns.alwaysShown')\" />\n </li>\n </template>\n <DragDropProvider :plugins=\"plugins\" @drag-end=\"onDragEnd\">\n <ColumnsDialogRow\n v-for=\"(c, i) in listed\"\n :key=\"c.id\"\n :column=\"c\"\n :index=\"i\"\n :disabled=\"!!find\"\n :pinned=\"willPin.has(c.id)\"\n @update:visible=\"(v) => (c.visible = v)\"\n />\n </DragDropProvider>\n </ul>\n </section>\n </div>\n <div class=\"dt-cols-foot\">\n <button type=\"button\" class=\"dt-btn\" @click=\"toggleAll\">\n {{ i18n.t(allShown ? 'columns.hideAll' : 'columns.showAll') }}\n </button>\n <span class=\"dt-pop-end\" />\n <DialogClose as-child>\n <button type=\"button\" class=\"dt-btn\">{{ i18n.t('common.cancel') }}</button>\n </DialogClose>\n <button type=\"button\" class=\"dt-btn dt-btn-primary\" @click=\"save\">{{ i18n.t('common.save') }}</button>\n </div>\n </DialogContent>\n </DialogPortal>\n </DialogRoot>\n</template>\n"],"mappings":"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"}