@medyat/react-data-table 0.0.0-stage → 0.1.0

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/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,207 @@
1
- # Temporary Holding Version
1
+ # @medyat/react-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
+ React 19 için liste tablosu (`DataTable`). Davranış ve tasarım `@medyat/vue-data-table` ile aynı sözleşmeye dayanır;
4
+ spesifikasyon Vue paketinin `docs/data-table/` klasöründedir, React'e özgü kararlar ve Vue'dan sapmalar
5
+ `docs/react-kararlar.md`'de. Toplu düzenleme (`DataSheet`) ve içe aktarma bu pakette yok (R1).
6
+
7
+ Paket veri çekmez ve kaydetmez (D18): istek nesnesini üretir, uygulama onu kendi sorgu katmanıyla (önerilen TanStack Query)
8
+ çalıştırır ve sonucu tabloya verir.
9
+
10
+ ## Kurulum
11
+
12
+ ```bash
13
+ pnpm add @medyat/react-data-table @base-ui/react @phosphor-icons/react write-excel-file
14
+ ```
15
+
16
+ ```tsx
17
+ import { createLocalStoragePreferences, createLocalStorageViews, DataTableProvider } from '@medyat/react-data-table'
18
+ import '@medyat/react-data-table/style.css'
19
+ import '@medyat/react-data-table/shadcn-bridge.css' // shadcn teması kullanılıyorsa, style.css'ten sonra (HSL tema: shadcn-bridge-hsl.css)
20
+
21
+ ;<DataTableProvider
22
+ locale="tr" // en · tr · ru; verilmezse navigator.language
23
+ viewsAdapter={createLocalStorageViews({ scope: tenantId })} // kişisel görünümler; backend için kendi ViewsAdapter'ınız
24
+ preferences={createLocalStoragePreferences({ scope: tenantId })} // yoğunluk, dikey çizgiler, sayfa boyutu, varsayılan görünüm
25
+ >
26
+ <App />
27
+ </DataTableProvider>
28
+ ```
29
+
30
+ Sağlayıcı isteğe bağlıdır; yoksa paket metinleri ve tarayıcı dili kullanılır, görünüm ve tercih kaydedilmez. `messages`
31
+ ile tek tek metin anahtarı ezilebilir.
32
+
33
+ Backend'e bağlamak (Laravel + Laraql: liste sorgusu, kişisel görünümler, kullanıcı tercihleri) için
34
+ [`docs/backend-integration.md`](docs/backend-integration.md).
35
+
36
+ ## Kullanım
37
+
38
+ `useDataTable` durumu ve isteği tutar, `<DataTable>` çizer (R3). Sütun tanımları feature'ın kendi dosyasında yaşar.
39
+
40
+ ```tsx
41
+ import { keepPreviousData, useQuery } from '@tanstack/react-query'
42
+ import { DataTable, useDataTable, type ColumnDef } from '@medyat/react-data-table'
43
+
44
+ const columns: Array<ColumnDef<Order>> = [
45
+ { id: 'number', header: 'Order no.', type: 'id', primary: true, href: (r) => `/orders/${r.id}` },
46
+ { id: 'customer', header: 'Customer', type: 'string' },
47
+ { id: 'status', header: 'Status', type: 'select', options: statusOptions, suggested: true },
48
+ { id: 'dueAt', header: 'Due date', type: 'date', overdue: (r) => r.status !== 'done' },
49
+ { id: 'value', header: 'Value', type: 'currency', currency: 'TRY' },
50
+ ]
51
+
52
+ export function OrdersScreen() {
53
+ const table = useDataTable({
54
+ id: 'production-orders', // görünümler ve tercihler bu kimlikle saklanır
55
+ columns,
56
+ entityName: { one: 'order', other: 'orders' },
57
+ views: systemViews, // kodda tanımlı system görünümleri; kişisel olanlar viewsAdapter'dan
58
+ count: (query, signal) => api.countOrders(query, signal), // footer'da "Count total"
59
+ })
60
+ const result = useQuery({
61
+ queryKey: ['orders', table.request],
62
+ queryFn: ({ signal }) => api.listOrders(table.request, signal), // → { rows, hasMore, total? }
63
+ placeholderData: keepPreviousData, // yükleme geçişleri için önerilir
64
+ })
65
+ return <DataTable table={table} result={result} toolbarEnd={<NewOrderButton />} />
66
+ }
67
+ ```
68
+
69
+ `table.request` (`TableQuery`): `search`, `filters` (`FilterCondition[]`), `sort` (`[{ column, dir }]`), `page`
70
+ (`{ number, size }`) ve `fields`. Sütun gizlemek, taşımak ya da genişletmek yeni istek üretmez. `result`, `useQuery`
71
+ sonucunun kendisidir; paket TanStack Query'ye bağımlı değildir, aynı alanları (`status`, `data`, `error`,
72
+ `isFetching`, `isPlaceholderData`, `dataUpdatedAt`, `refetch`) taşıyan herhangi bir nesneyi kabul eder. Hata
73
+ nesnesinin `message` ve `id` alanları hata ekranında gösterilir; `refetch` yoksa Refresh ve Retry görünmez.
74
+
75
+ İstemci modu: `useDataTable({ rows })` verilirse paket kendisi süzer, sıralar ve sayfalar; `result` verilmez.
76
+
77
+ ### Durumu adrese bağlamak
78
+
79
+ Durum varsayılan olarak tablonun içindedir. `state` + `onStateChange` ile alan alan dışarı açılır (R5); paket adrese
80
+ kendisi dokunmaz. TanStack Router ile:
81
+
82
+ ```tsx
83
+ const search = Route.useSearch()
84
+ const navigate = Route.useNavigate()
85
+ const table = useDataTable({
86
+ id: 'production-orders',
87
+ columns,
88
+ state: { search: search.q ?? '', filters: search.filters ?? [], sort: search.sort ?? [], page: search.page ?? 1 },
89
+ onStateChange: (s) =>
90
+ navigate({ search: { q: s.search, filters: s.filters, sort: s.sort, page: s.page }, replace: true }),
91
+ })
92
+ ```
93
+
94
+ Yalnızca tam filtre koşulları duruma girer; değeri seçilmemiş çip ekranda kalır. Sütun düzeni durumda değildir, görünüme
95
+ ve tercihe gider.
96
+
97
+ ### Satırı açmak
98
+
99
+ Birincil hücre gerçek bir `<a href>`'tir (D6): ⌘/orta tık tarayıcıya kalır, düz tık `onRowOpen`'ı çağırır. Dinleyici
100
+ `preventDefault` yapmazsa tarayıcı bağlantıya gider.
101
+
102
+ ```tsx
103
+ <DataTable
104
+ table={table}
105
+ result={result}
106
+ rowClick="open" // satırın boş yerine tık da açar; "expand" detayı açar; varsayılan "none"
107
+ onRowOpen={({ href, event }) => {
108
+ event.preventDefault()
109
+ navigate({ to: href })
110
+ }}
111
+ />
112
+ ```
113
+
114
+ ### Seçim, aksiyonlar, detay
115
+
116
+ ```tsx
117
+ <DataTable
118
+ table={table}
119
+ result={result}
120
+ selectable // seçim sayfa kapsamlı (D19); durum table.selection, temizlemek için table.clearSelection()
121
+ bulkActions={[
122
+ { id: 'release', label: 'Release', icon: PlayIcon, inBar: true, run: (rows) => release(rows) },
123
+ {
124
+ id: 'cancel',
125
+ label: 'Cancel orders…',
126
+ destructive: true,
127
+ disabled: (rows) => (rows.every(isDone) ? 'All already done' : false), // metin döndürülürse gerekçe olarak gösterilir
128
+ run: (rows) => confirmCancel(rows),
129
+ },
130
+ ]}
131
+ rowActions={[
132
+ { id: 'edit', label: 'Edit', icon: PencilSimpleIcon, inline: true, run: (row) => edit(row) },
133
+ { id: 'archive', label: 'Archive', when: (row) => row.status === 'done', run: (row) => archive(row) }, // yoksa görünmez
134
+ ]}
135
+ renderExpanded={({ row }) => <OrderOperations order={row} />} // detay verisini bileşen kendisi çeker
136
+ rowError={(row) => failures.get(row.id)} // satır hatası (D35): zemin, uyarı ikonu, tooltip
137
+ />
138
+ ```
139
+
140
+ `run` beklenmez (D20): uzun işlemin onayı, ilerlemesi ve sonucu uygulamanındır. Seçim çubuğu varsayılan olarak kartın
141
+ altında yüzer; `bulkActions` ve `selectionActions` yoksa hiç çizilmez (seçim Export'ta ve header checkbox'ında kalır); `selectionBar="toolbar"` onu araç çubuğunun yerine koyar, `selectionActions` içeriğini tümüyle uygulamaya
142
+ bırakır. Seçili satırlar `onSelectionChange` ile de okunabilir.
143
+
144
+ ### Diğer
145
+
146
+ - `toolbar`: `'auto'` (varsayılan; görünümler, arama, Filter, Display, ⋯), `'minimal'` (yalnızca arama ve
147
+ `toolbarEnd`) ya da `false`.
148
+ - `autoRefresh={30}`: ⋯ menüsünde Auto-refresh anahtarı; açıkken footer "Live". `onPrint` verilirse ⋯ menüsünde Print.
149
+ - `empty`: hiç kayıt yokken (filtre ve arama da yokken) gövdede gösterilecek içerik.
150
+ - `notice`: araç çubuğu ile sütun başlıkları arasında uygulamanın şeridi (R16), ör. "Yalnızca arşivlenmiş
151
+ kayıtlar listeleniyor". İçerik, rengi ve rolü uygulamanın; paket yer, yatay hiza ve alt çizgiyi verir.
152
+ - Dışa aktarma (D46): ⋯ › **Export 100 rows** › CSV / Excel (.xlsx). Ekranda görünen sütunlar ve satırlar yazılır: seçim
153
+ varsa seçili satırlar, yoksa sayfadaki satırlar (sunucu modunda yüklü sayfa; "tüm eşleşenler" yok). .xlsx için
154
+ `write-excel-file` peer'ı gerekir (`pnpm add write-excel-file`); ilk dışa aktarmada yüklenir. `exportable={false}`
155
+ gizler; `onExport` verilirse paket dosya yazmaz, `{ format, query, selection, rows, visibleColumns }` ile uygulama
156
+ üretir.
157
+
158
+ ## Telefon
159
+
160
+ Kartın kendi genişliği 640 px'in altındaysa (ekranın değil) telefon düzeni açılır: yalnızca birincil sütun sabit, 48 px
161
+ satırlar; filtreler, görünümler, ⋯ ve toplu aksiyonlar alt sayfada. Filters sayfası değişiklikleri taslakta biriktirir,
162
+ **Show results** filtreyi ve sıralamayı tek istekte uygular.
163
+
164
+ ## Erişilebilirlik ve klavye
165
+
166
+ - Kısayollar: `/` arama, `F` filtre, `V` görünümler, `R` yenile, `⌘S` görünümü kaydet, `Alt ←/→` sayfa, `Esc` seçimi
167
+ temizler. Odak bir metin alanındayken tek harfli kısayollar çalışmaz; `shortcuts={false}` onları kapatır.
168
+ - Duyurular `aria-live` bölgelerinden; `forced-colors` ve `prefers-reduced-motion` desteklenir.
169
+ - Playwright'ta axe-core taraması (`e2e/a11y.spec.ts`): WCAG 2.1 A/AA'da kritik ya da ciddi ihlal kabul edilmez.
170
+
171
+ Ayrıntılar Vue spesifikasyonunun `08-accessibility-keyboard.md`'sinde; React'teki farklar `docs/react-kararlar.md`'de.
172
+
173
+ ## Stil
174
+
175
+ Tüm CSS `@layer medyat-dt` içindedir. Tailwind v4'te katmanı `utilities`'den önce bildirin; uygulamanın sınıfları
176
+ paketi ezsin:
177
+
178
+ ```css
179
+ @layer theme, base, medyat-dt, components, utilities;
180
+ ```
181
+
182
+ Tema `.dark` sınıfı ya da `data-theme="dark"` ile değişir. Yoğunluk kullanıcının Display › Density seçiminden gelir;
183
+ `useDataTable({ density })` onu sabitler ve seçiciyi gizler.
184
+
185
+ ## Geliştirme
186
+
187
+ Node 22+ ve pnpm (corepack ile): `corepack enable` bir kez, sonra `pnpm install`. Vue paketi kardeş klasörde
188
+ (`../data-table`) bulunmalıdır: token ve metinler oradaki belgelerden üretilir, karşılaştırma testleri oradan okur
189
+ (yoksa atlanır; başka yerdeyse `DT_SPEC`).
190
+
191
+ | Komut | Ne yapar |
192
+ | ------------------------------ | ------------------------------------------------------------------------------------------- |
193
+ | `pnpm dev` | Playground (`playground/`, http://localhost:5175); sahte API `/api/orders` |
194
+ | `pnpm test` | Vitest: bileşenler, token ↔ 02, kontrast, i18n ↔ 09 |
195
+ | `pnpm test:e2e` | Playwright, kendi playground'una karşı (port 5179); axe taraması |
196
+ | `pnpm typecheck` · `pnpm lint` | tsc, ESLint |
197
+ | `pnpm format` | Prettier |
198
+ | `pnpm build` | `dist/`: `index.js`, `style.css`, köprü CSS'leri, `.d.ts` |
199
+ | `pnpm gen:docs` | 02 → `src/styles/tokens.css`, 09 → `src/core/i18n/{en,tr}.ts` (üretilmiş, elle düzenlenmez) |
200
+ | `pnpm check` | typecheck + lint + format kontrolü + test + build |
201
+
202
+ Token ve metin değişikliği Vue belgesinde yapılır, sonra `pnpm gen:docs`. React'e özgü metin sapmaları
203
+ `scripts/docs.ts` içindeki `REACT_MESSAGES`'tadır; `ru` elle yazılır.
204
+
205
+ ## Lisans
206
+
207
+ MIT · © 2026 Medyat