@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 +21 -0
- package/README.md +206 -2
- package/dist/bottom-sheet-NHUT908D.js +1123 -0
- package/dist/bottom-sheet-NHUT908D.js.map +1 -0
- package/dist/columns-dialog-COcldc3X.js +419 -0
- package/dist/columns-dialog-COcldc3X.js.map +1 -0
- package/dist/date-editor-CJFd5YEo.js +378 -0
- package/dist/date-editor-CJFd5YEo.js.map +1 -0
- package/dist/filters-sheet-CWzMaMFo.js +298 -0
- package/dist/filters-sheet-CWzMaMFo.js.map +1 -0
- package/dist/index.d.ts +736 -0
- package/dist/index.js +4769 -0
- package/dist/index.js.map +1 -0
- package/dist/model-RkRyfM7C.js +288 -0
- package/dist/model-RkRyfM7C.js.map +1 -0
- package/dist/provider-CTTHEpE3.js +884 -0
- package/dist/provider-CTTHEpE3.js.map +1 -0
- package/dist/shadcn-bridge-hsl.css +24 -0
- package/dist/shadcn-bridge.css +25 -0
- package/dist/style.css +2 -0
- package/dist/switch-B8TN4kJ-.js +23 -0
- package/dist/switch-B8TN4kJ-.js.map +1 -0
- package/docs/backend-integration.md +596 -0
- package/package.json +95 -4
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
|
-
#
|
|
1
|
+
# @medyat/react-data-table
|
|
2
2
|
|
|
3
|
-
|
|
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
|