@rowakit/table 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/README.md +1073 -0
- package/dist/index.cjs +385 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +389 -0
- package/dist/index.d.ts +389 -0
- package/dist/index.js +380 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
- package/src/styles/index.css +18 -0
- package/src/styles/table.css +319 -0
- package/src/styles/tokens.css +177 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// src/column-helpers.ts
|
|
7
|
+
function text(field, options) {
|
|
8
|
+
return {
|
|
9
|
+
id: field,
|
|
10
|
+
kind: "text",
|
|
11
|
+
field,
|
|
12
|
+
header: options?.header,
|
|
13
|
+
sortable: options?.sortable ?? false,
|
|
14
|
+
format: options?.format
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function date(field, options) {
|
|
18
|
+
return {
|
|
19
|
+
id: field,
|
|
20
|
+
kind: "date",
|
|
21
|
+
field,
|
|
22
|
+
header: options?.header,
|
|
23
|
+
sortable: options?.sortable ?? false,
|
|
24
|
+
format: options?.format
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function boolean(field, options) {
|
|
28
|
+
return {
|
|
29
|
+
id: field,
|
|
30
|
+
kind: "boolean",
|
|
31
|
+
field,
|
|
32
|
+
header: options?.header,
|
|
33
|
+
sortable: options?.sortable ?? false,
|
|
34
|
+
format: options?.format
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function actions(actions2) {
|
|
38
|
+
return {
|
|
39
|
+
id: "actions",
|
|
40
|
+
kind: "actions",
|
|
41
|
+
actions: actions2
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function custom(options) {
|
|
45
|
+
return {
|
|
46
|
+
id: options.id,
|
|
47
|
+
kind: "custom",
|
|
48
|
+
header: options.header,
|
|
49
|
+
field: options.field,
|
|
50
|
+
render: options.render
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
var col = {
|
|
54
|
+
text,
|
|
55
|
+
date,
|
|
56
|
+
boolean,
|
|
57
|
+
actions,
|
|
58
|
+
custom
|
|
59
|
+
};
|
|
60
|
+
function getRowKey(row, rowKey) {
|
|
61
|
+
if (typeof rowKey === "function") {
|
|
62
|
+
return rowKey(row);
|
|
63
|
+
}
|
|
64
|
+
if (rowKey) {
|
|
65
|
+
return String(row[rowKey]);
|
|
66
|
+
}
|
|
67
|
+
if (row && typeof row === "object" && "id" in row) {
|
|
68
|
+
return String(row.id);
|
|
69
|
+
}
|
|
70
|
+
return String(row);
|
|
71
|
+
}
|
|
72
|
+
function getHeaderLabel(column) {
|
|
73
|
+
return column.header ?? column.id;
|
|
74
|
+
}
|
|
75
|
+
function renderCell(column, row, isLoading, setConfirmState) {
|
|
76
|
+
switch (column.kind) {
|
|
77
|
+
case "text": {
|
|
78
|
+
const value = row[column.field];
|
|
79
|
+
if (column.format) {
|
|
80
|
+
return column.format(value);
|
|
81
|
+
}
|
|
82
|
+
return String(value ?? "");
|
|
83
|
+
}
|
|
84
|
+
case "date": {
|
|
85
|
+
const value = row[column.field];
|
|
86
|
+
if (column.format) {
|
|
87
|
+
return column.format(value);
|
|
88
|
+
}
|
|
89
|
+
if (value instanceof Date) {
|
|
90
|
+
return value.toLocaleDateString();
|
|
91
|
+
}
|
|
92
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
93
|
+
return new Date(value).toLocaleDateString();
|
|
94
|
+
}
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
case "boolean": {
|
|
98
|
+
const value = row[column.field];
|
|
99
|
+
if (column.format) {
|
|
100
|
+
return column.format(Boolean(value));
|
|
101
|
+
}
|
|
102
|
+
return value ? "Yes" : "No";
|
|
103
|
+
}
|
|
104
|
+
case "actions": {
|
|
105
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rowakit-table-actions", children: column.actions.map((action) => {
|
|
106
|
+
const isDisabled = isLoading || action.disabled === true || typeof action.disabled === "function" && action.disabled(row);
|
|
107
|
+
const handleClick = () => {
|
|
108
|
+
if (isDisabled || action.loading) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (action.confirm) {
|
|
112
|
+
setConfirmState({ action, row });
|
|
113
|
+
} else {
|
|
114
|
+
void action.onClick(row);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
118
|
+
"button",
|
|
119
|
+
{
|
|
120
|
+
onClick: handleClick,
|
|
121
|
+
disabled: isDisabled || action.loading,
|
|
122
|
+
type: "button",
|
|
123
|
+
className: "rowakit-button rowakit-button-secondary",
|
|
124
|
+
children: [
|
|
125
|
+
action.icon && typeof action.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: action.icon }) : action.icon,
|
|
126
|
+
action.label
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
action.id
|
|
130
|
+
);
|
|
131
|
+
}) });
|
|
132
|
+
}
|
|
133
|
+
case "custom": {
|
|
134
|
+
return column.render(row);
|
|
135
|
+
}
|
|
136
|
+
default: {
|
|
137
|
+
const _exhaustive = column;
|
|
138
|
+
return _exhaustive;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function RowaKitTable({
|
|
143
|
+
fetcher,
|
|
144
|
+
columns,
|
|
145
|
+
defaultPageSize = 20,
|
|
146
|
+
pageSizeOptions = [10, 20, 50],
|
|
147
|
+
rowKey,
|
|
148
|
+
className = ""
|
|
149
|
+
}) {
|
|
150
|
+
const [dataState, setDataState] = react.useState({
|
|
151
|
+
state: "idle",
|
|
152
|
+
items: [],
|
|
153
|
+
total: 0
|
|
154
|
+
});
|
|
155
|
+
const [query, setQuery] = react.useState({
|
|
156
|
+
page: 1,
|
|
157
|
+
pageSize: defaultPageSize
|
|
158
|
+
});
|
|
159
|
+
const [confirmState, setConfirmState] = react.useState(null);
|
|
160
|
+
const requestIdRef = react.useRef(0);
|
|
161
|
+
react.useEffect(() => {
|
|
162
|
+
const currentRequestId = ++requestIdRef.current;
|
|
163
|
+
setDataState((prev) => ({ ...prev, state: "loading" }));
|
|
164
|
+
fetcher(query).then((result) => {
|
|
165
|
+
if (currentRequestId !== requestIdRef.current) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (result.items.length === 0) {
|
|
169
|
+
setDataState({
|
|
170
|
+
state: "empty",
|
|
171
|
+
items: [],
|
|
172
|
+
total: result.total
|
|
173
|
+
});
|
|
174
|
+
} else {
|
|
175
|
+
setDataState({
|
|
176
|
+
state: "success",
|
|
177
|
+
items: result.items,
|
|
178
|
+
total: result.total
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}).catch((error) => {
|
|
182
|
+
if (currentRequestId !== requestIdRef.current) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
setDataState({
|
|
186
|
+
state: "error",
|
|
187
|
+
items: [],
|
|
188
|
+
total: 0,
|
|
189
|
+
error: error instanceof Error ? error.message : "Failed to load data"
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}, [fetcher, query]);
|
|
193
|
+
const handleRetry = () => {
|
|
194
|
+
setQuery({ ...query });
|
|
195
|
+
};
|
|
196
|
+
const handlePreviousPage = () => {
|
|
197
|
+
if (query.page > 1) {
|
|
198
|
+
setQuery((prev) => ({ ...prev, page: prev.page - 1 }));
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const handleNextPage = () => {
|
|
202
|
+
const totalPages2 = Math.ceil(dataState.total / query.pageSize);
|
|
203
|
+
if (query.page < totalPages2) {
|
|
204
|
+
setQuery((prev) => ({ ...prev, page: prev.page + 1 }));
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
const handlePageSizeChange = (newPageSize) => {
|
|
208
|
+
setQuery({ ...query, pageSize: newPageSize, page: 1 });
|
|
209
|
+
};
|
|
210
|
+
const handleSort = (field) => {
|
|
211
|
+
setQuery((prev) => {
|
|
212
|
+
if (prev.sort?.field !== field) {
|
|
213
|
+
return { ...prev, sort: { field, direction: "asc" }, page: 1 };
|
|
214
|
+
}
|
|
215
|
+
if (prev.sort.direction === "asc") {
|
|
216
|
+
return { ...prev, sort: { field, direction: "desc" }, page: 1 };
|
|
217
|
+
}
|
|
218
|
+
const { sort: _sort, ...rest } = prev;
|
|
219
|
+
return { ...rest, page: 1 };
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
const getSortIndicator = (field) => {
|
|
223
|
+
if (!query.sort || query.sort.field !== field) {
|
|
224
|
+
return "";
|
|
225
|
+
}
|
|
226
|
+
return query.sort.direction === "asc" ? " \u2191" : " \u2193";
|
|
227
|
+
};
|
|
228
|
+
const isLoading = dataState.state === "loading";
|
|
229
|
+
const isError = dataState.state === "error";
|
|
230
|
+
const isEmpty = dataState.state === "empty";
|
|
231
|
+
const totalPages = Math.ceil(dataState.total / query.pageSize);
|
|
232
|
+
const canGoPrevious = query.page > 1 && !isLoading;
|
|
233
|
+
const canGoNext = query.page < totalPages && !isLoading;
|
|
234
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `rowakit-table${className ? ` ${className}` : ""}`, children: [
|
|
235
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { children: [
|
|
236
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((column) => {
|
|
237
|
+
const isSortable = column.kind !== "actions" && (column.kind === "custom" ? false : column.sortable === true);
|
|
238
|
+
const field = column.kind === "actions" ? "" : column.kind === "custom" ? column.field : column.field;
|
|
239
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
240
|
+
"th",
|
|
241
|
+
{
|
|
242
|
+
onClick: isSortable ? () => handleSort(String(field)) : void 0,
|
|
243
|
+
role: isSortable ? "button" : void 0,
|
|
244
|
+
tabIndex: isSortable ? 0 : void 0,
|
|
245
|
+
onKeyDown: isSortable ? (e) => {
|
|
246
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
247
|
+
e.preventDefault();
|
|
248
|
+
handleSort(String(field));
|
|
249
|
+
}
|
|
250
|
+
} : void 0,
|
|
251
|
+
"aria-sort": isSortable && query.sort?.field === String(field) ? query.sort.direction === "asc" ? "ascending" : "descending" : void 0,
|
|
252
|
+
children: [
|
|
253
|
+
getHeaderLabel(column),
|
|
254
|
+
isSortable && getSortIndicator(String(field))
|
|
255
|
+
]
|
|
256
|
+
},
|
|
257
|
+
column.id
|
|
258
|
+
);
|
|
259
|
+
}) }) }),
|
|
260
|
+
/* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
|
|
261
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsxs("td", { colSpan: columns.length, className: "rowakit-table-loading", children: [
|
|
262
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rowakit-table-loading-spinner" }),
|
|
263
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading..." })
|
|
264
|
+
] }) }),
|
|
265
|
+
isError && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsxs("td", { colSpan: columns.length, className: "rowakit-table-error", children: [
|
|
266
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rowakit-table-error-message", children: dataState.error ?? "An error occurred" }),
|
|
267
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
268
|
+
"button",
|
|
269
|
+
{
|
|
270
|
+
onClick: handleRetry,
|
|
271
|
+
className: "rowakit-button rowakit-button-primary",
|
|
272
|
+
type: "button",
|
|
273
|
+
children: "Retry"
|
|
274
|
+
}
|
|
275
|
+
)
|
|
276
|
+
] }) }),
|
|
277
|
+
isEmpty && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: columns.length, className: "rowakit-table-empty", children: "No data" }) }),
|
|
278
|
+
dataState.state === "success" && dataState.items.map((row) => {
|
|
279
|
+
const key = getRowKey(row, rowKey);
|
|
280
|
+
return /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx("td", { children: renderCell(column, row, isLoading, setConfirmState) }, column.id)) }, key);
|
|
281
|
+
})
|
|
282
|
+
] })
|
|
283
|
+
] }),
|
|
284
|
+
dataState.total > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rowakit-table-pagination", children: [
|
|
285
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rowakit-table-pagination-left", children: [
|
|
286
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "page-size", children: "Rows per page:" }),
|
|
287
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
288
|
+
"select",
|
|
289
|
+
{
|
|
290
|
+
id: "page-size",
|
|
291
|
+
value: query.pageSize,
|
|
292
|
+
onChange: (e) => handlePageSizeChange(Number(e.target.value)),
|
|
293
|
+
disabled: isLoading,
|
|
294
|
+
children: pageSizeOptions.map((size) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: size, children: size }, size))
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
] }),
|
|
298
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rowakit-table-pagination-center", children: [
|
|
299
|
+
"Page ",
|
|
300
|
+
query.page,
|
|
301
|
+
" of ",
|
|
302
|
+
totalPages,
|
|
303
|
+
" (",
|
|
304
|
+
dataState.total,
|
|
305
|
+
" total)"
|
|
306
|
+
] }),
|
|
307
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rowakit-table-pagination-right", children: [
|
|
308
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
309
|
+
"button",
|
|
310
|
+
{
|
|
311
|
+
onClick: handlePreviousPage,
|
|
312
|
+
disabled: !canGoPrevious,
|
|
313
|
+
className: "rowakit-button rowakit-button-primary rowakit-button-pagination",
|
|
314
|
+
type: "button",
|
|
315
|
+
"aria-label": "Previous page",
|
|
316
|
+
children: "Previous"
|
|
317
|
+
}
|
|
318
|
+
),
|
|
319
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
320
|
+
"button",
|
|
321
|
+
{
|
|
322
|
+
onClick: handleNextPage,
|
|
323
|
+
disabled: !canGoNext,
|
|
324
|
+
className: "rowakit-button rowakit-button-primary rowakit-button-pagination",
|
|
325
|
+
type: "button",
|
|
326
|
+
"aria-label": "Next page",
|
|
327
|
+
children: "Next"
|
|
328
|
+
}
|
|
329
|
+
)
|
|
330
|
+
] })
|
|
331
|
+
] }),
|
|
332
|
+
confirmState && /* @__PURE__ */ jsxRuntime.jsx(
|
|
333
|
+
"div",
|
|
334
|
+
{
|
|
335
|
+
className: "rowakit-modal-backdrop",
|
|
336
|
+
onClick: () => setConfirmState(null),
|
|
337
|
+
role: "dialog",
|
|
338
|
+
"aria-modal": "true",
|
|
339
|
+
"aria-labelledby": "confirm-dialog-title",
|
|
340
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rowakit-modal", onClick: (e) => e.stopPropagation(), children: [
|
|
341
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: "confirm-dialog-title", className: "rowakit-modal-title", children: "Confirm Action" }),
|
|
342
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "rowakit-modal-content", children: [
|
|
343
|
+
"Are you sure you want to ",
|
|
344
|
+
confirmState.action.label.toLowerCase(),
|
|
345
|
+
"? This action cannot be undone."
|
|
346
|
+
] }),
|
|
347
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rowakit-modal-actions", children: [
|
|
348
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
349
|
+
"button",
|
|
350
|
+
{
|
|
351
|
+
onClick: () => setConfirmState(null),
|
|
352
|
+
className: "rowakit-button rowakit-button-secondary",
|
|
353
|
+
type: "button",
|
|
354
|
+
children: "Cancel"
|
|
355
|
+
}
|
|
356
|
+
),
|
|
357
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
358
|
+
"button",
|
|
359
|
+
{
|
|
360
|
+
onClick: () => {
|
|
361
|
+
void confirmState.action.onClick(confirmState.row);
|
|
362
|
+
setConfirmState(null);
|
|
363
|
+
},
|
|
364
|
+
className: "rowakit-button rowakit-button-danger",
|
|
365
|
+
type: "button",
|
|
366
|
+
children: "Confirm"
|
|
367
|
+
}
|
|
368
|
+
)
|
|
369
|
+
] })
|
|
370
|
+
] })
|
|
371
|
+
}
|
|
372
|
+
)
|
|
373
|
+
] });
|
|
374
|
+
}
|
|
375
|
+
var SmartTable = RowaKitTable;
|
|
376
|
+
|
|
377
|
+
// src/index.ts
|
|
378
|
+
var VERSION = "0.1.0";
|
|
379
|
+
|
|
380
|
+
exports.RowaKitTable = RowaKitTable;
|
|
381
|
+
exports.SmartTable = SmartTable;
|
|
382
|
+
exports.VERSION = VERSION;
|
|
383
|
+
exports.col = col;
|
|
384
|
+
//# sourceMappingURL=index.cjs.map
|
|
385
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/column-helpers.ts","../src/components/SmartTable.tsx","../src/index.ts"],"names":["actions","jsx","jsxs","useState","useRef","useEffect","totalPages"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Column helper factory functions\r\n *\r\n * These helpers provide a clean, type-safe API for defining table columns.\r\n * They reduce boilerplate and enforce conventions while maintaining flexibility\r\n * through the `col.custom` escape hatch.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport type { ReactNode } from 'react';\r\nimport type {\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n ActionDef,\r\n} from './types';\r\n\r\n// ============================================================================\r\n// HELPER OPTIONS\r\n// ============================================================================\r\n\r\ninterface TextOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional formatter function */\r\n format?: (value: unknown) => string;\r\n}\r\n\r\ninterface DateOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional date formatter function */\r\n format?: (value: Date | string | number) => string;\r\n}\r\n\r\ninterface BooleanOptions {\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Enable sorting for this column */\r\n sortable?: boolean;\r\n /** Optional boolean formatter function */\r\n format?: (value: boolean) => string;\r\n}\r\n\r\n// ============================================================================\r\n// COLUMN HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Create a text column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.text('name')\r\n * col.text('email', { header: 'Email Address', sortable: true })\r\n * col.text('status', { format: (val) => val.toUpperCase() })\r\n * ```\r\n */\r\nfunction text<T>(\r\n field: keyof T & string,\r\n options?: TextOptions\r\n): TextColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'text',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n };\r\n}\r\n\r\n/**\r\n * Create a date column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.date('createdAt')\r\n * col.date('updatedAt', { header: 'Last Modified', sortable: true })\r\n * col.date('birthday', {\r\n * format: (date) => new Date(date).toLocaleDateString()\r\n * })\r\n * ```\r\n */\r\nfunction date<T>(\r\n field: keyof T & string,\r\n options?: DateOptions\r\n): DateColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'date',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n };\r\n}\r\n\r\n/**\r\n * Create a boolean column definition.\r\n *\r\n * @example\r\n * ```ts\r\n * col.boolean('active')\r\n * col.boolean('isPublished', { header: 'Published', sortable: true })\r\n * col.boolean('enabled', {\r\n * format: (val) => val ? 'Yes' : 'No'\r\n * })\r\n * ```\r\n */\r\nfunction boolean<T>(\r\n field: keyof T & string,\r\n options?: BooleanOptions\r\n): BooleanColumnDef<T> {\r\n return {\r\n id: field,\r\n kind: 'boolean',\r\n field,\r\n header: options?.header,\r\n sortable: options?.sortable ?? false,\r\n format: options?.format,\r\n };\r\n}\r\n\r\n/**\r\n * Create an actions column definition.\r\n *\r\n * The actions column displays a set of actions (buttons/links) that can be\r\n * performed on each row.\r\n *\r\n * @example\r\n * ```ts\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => editUser(row) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (row) => deleteUser(row) }\r\n * ])\r\n * ```\r\n */\r\nfunction actions<T>(actions: ActionDef<T>[]): ActionsColumnDef<T> {\r\n return {\r\n id: 'actions',\r\n kind: 'actions',\r\n actions,\r\n };\r\n}\r\n\r\n/**\r\n * Create a custom column definition with full rendering control.\r\n *\r\n * This is the escape hatch for any column that doesn't fit the standard types.\r\n * Use this for badges, avatars, complex formatting, or any custom UI.\r\n *\r\n * @example\r\n * ```ts\r\n * col.custom({\r\n * id: 'avatar',\r\n * header: 'User',\r\n * render: (row) => <img src={row.avatar} alt={row.name} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'price',\r\n * field: 'price',\r\n * render: (row) => <Money amount={row.price} currency={row.currency} />\r\n * })\r\n *\r\n * col.custom({\r\n * id: 'status',\r\n * render: (row) => (\r\n * <Badge color={row.status === 'active' ? 'green' : 'gray'}>\r\n * {row.status}\r\n * </Badge>\r\n * )\r\n * })\r\n * ```\r\n */\r\nfunction custom<T>(options: {\r\n /** Unique column identifier */\r\n id: string;\r\n /** Optional custom header label */\r\n header?: string;\r\n /** Optional field name for sorting/filtering */\r\n field?: keyof T & string;\r\n /** Render function for cell content */\r\n render: (row: T) => ReactNode;\r\n}): CustomColumnDef<T> {\r\n return {\r\n id: options.id,\r\n kind: 'custom',\r\n header: options.header,\r\n field: options.field,\r\n render: options.render,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// EXPORTS\r\n// ============================================================================\r\n\r\n/**\r\n * Column helper factory object.\r\n *\r\n * Provides convenient helper functions for creating column definitions.\r\n *\r\n * @example\r\n * ```tsx\r\n * import { col } from '@rowakit/table';\r\n *\r\n * const columns = [\r\n * col.text('name', { sortable: true }),\r\n * col.date('createdAt'),\r\n * col.boolean('active'),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (row) => {} }\r\n * ]),\r\n * col.custom({ id: 'badge', render: (row) => <Badge>{row.status}</Badge> })\r\n * ];\r\n * ```\r\n */\r\nexport const col = {\r\n text,\r\n date,\r\n boolean,\r\n actions,\r\n custom,\r\n} as const;\r\n","/**\r\n * RowaKit Table Component\r\n *\r\n * Core table rendering component that maps columns to table cells.\r\n * Handles all column types: text, date, boolean, actions, and custom.\r\n * Includes data fetching state machine with loading/error/empty states.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport { useState, useEffect, useRef } from 'react';\r\nimport type { ReactNode } from 'react';\r\nimport type { Fetcher, ColumnDef, FetcherQuery, ActionDef } from '../types';\r\n\r\n// ============================================================================\r\n// COMPONENT PROPS\r\n// ============================================================================\r\n\r\nexport interface SmartTableProps<T> {\r\n /** Server-side data fetcher function */\r\n fetcher: Fetcher<T>;\r\n\r\n /** Array of column definitions */\r\n columns: ColumnDef<T>[];\r\n\r\n /** Available page size options (default: [10, 20, 50]) */\r\n pageSizeOptions?: number[];\r\n\r\n /** Initial page size (default: 20) */\r\n defaultPageSize?: number;\r\n\r\n /** Function or field name to extract row key (default: uses 'id' field) */\r\n rowKey?: keyof T | ((row: T) => string | number);\r\n\r\n /** Optional CSS class name for the table container */\r\n className?: string;\r\n}\r\n\r\n// ============================================================================\r\n// STATE MANAGEMENT\r\n// ============================================================================\r\n\r\ntype FetchState = 'idle' | 'loading' | 'success' | 'empty' | 'error';\r\n\r\ninterface DataState<T> {\r\n state: FetchState;\r\n items: T[];\r\n total: number;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Confirmation state for actions that require confirmation.\r\n */\r\ninterface ConfirmState<T> {\r\n action: ActionDef<T>;\r\n row: T;\r\n}\r\n\r\n// ============================================================================\r\n// HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Extract unique key from a row.\r\n */\r\nfunction getRowKey<T>(row: T, rowKey?: keyof T | ((row: T) => string | number)): string | number {\r\n if (typeof rowKey === 'function') {\r\n return rowKey(row);\r\n }\r\n if (rowKey) {\r\n return String(row[rowKey]);\r\n }\r\n // Fallback to 'id' field if available\r\n if (row && typeof row === 'object' && 'id' in row) {\r\n return String(row.id);\r\n }\r\n // Last resort: use object reference (not ideal but safe)\r\n return String(row);\r\n}\r\n\r\n/**\r\n * Get header label for a column.\r\n */\r\nfunction getHeaderLabel<T>(column: ColumnDef<T>): string {\r\n return column.header ?? column.id;\r\n}\r\n\r\n/**\r\n * Render cell content based on column kind.\r\n */\r\nfunction renderCell<T>(\r\n column: ColumnDef<T>,\r\n row: T,\r\n isLoading: boolean,\r\n setConfirmState: (state: ConfirmState<T> | null) => void\r\n): ReactNode {\r\n switch (column.kind) {\r\n case 'text': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value);\r\n }\r\n return String(value ?? '');\r\n }\r\n\r\n case 'date': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(value as Date | string | number);\r\n }\r\n // Default date formatting\r\n if (value instanceof Date) {\r\n return value.toLocaleDateString();\r\n }\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n return new Date(value).toLocaleDateString();\r\n }\r\n return '';\r\n }\r\n\r\n case 'boolean': {\r\n const value = row[column.field];\r\n if (column.format) {\r\n return column.format(Boolean(value));\r\n }\r\n // Default boolean formatting\r\n return value ? 'Yes' : 'No';\r\n }\r\n\r\n case 'actions': {\r\n return (\r\n <div className=\"rowakit-table-actions\">\r\n {column.actions.map((action) => {\r\n const isDisabled =\r\n isLoading ||\r\n action.disabled === true ||\r\n (typeof action.disabled === 'function' && action.disabled(row));\r\n\r\n const handleClick = () => {\r\n if (isDisabled || action.loading) {\r\n return;\r\n }\r\n\r\n // If action requires confirmation, show modal\r\n if (action.confirm) {\r\n setConfirmState({ action, row });\r\n } else {\r\n // Execute action directly\r\n void action.onClick(row);\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n key={action.id}\r\n onClick={handleClick}\r\n disabled={isDisabled || action.loading}\r\n type=\"button\"\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n >\r\n {action.icon && typeof action.icon === 'string' ? (\r\n <span>{action.icon}</span>\r\n ) : (\r\n action.icon\r\n )}\r\n {action.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n case 'custom': {\r\n return column.render(row);\r\n }\r\n\r\n default: {\r\n // Exhaustive check\r\n const _exhaustive: never = column;\r\n return _exhaustive;\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// MAIN COMPONENT\r\n// ============================================================================\r\n\r\n/**\r\n * RowaKitTable - Server-side table component for internal/business apps.\r\n *\r\n * This component renders a table with headers and body based on column definitions.\r\n * It handles all column types (text, date, boolean, actions, custom) and provides\r\n * a clean API for defining table structure.\r\n *\r\n * Features:\r\n * - Automatic data fetching on mount and query changes\r\n * - Loading, error, and empty states\r\n * - Stale request handling\r\n * - Retry on error\r\n *\r\n * @example\r\n * ```tsx\r\n * import { RowaKitTable, col } from '@rowakit/table';\r\n *\r\n * interface User {\r\n * id: string;\r\n * name: string;\r\n * email: string;\r\n * createdAt: Date;\r\n * active: boolean;\r\n * }\r\n *\r\n * const fetchUsers: Fetcher<User> = async (query) => {\r\n * const response = await fetch(`/api/users?page=${query.page}&pageSize=${query.pageSize}`);\r\n * return response.json();\r\n * };\r\n *\r\n * function UsersTable() {\r\n * return (\r\n * <RowaKitTable\r\n * fetcher={fetchUsers}\r\n * columns={[\r\n * col.text('name', { header: 'Name', sortable: true }),\r\n * col.text('email', { header: 'Email' }),\r\n * col.date('createdAt', { header: 'Created' }),\r\n * col.boolean('active', { header: 'Active' }),\r\n * col.actions([\r\n * { id: 'edit', label: 'Edit', onClick: (user) => editUser(user) },\r\n * { id: 'delete', label: 'Delete', confirm: true, onClick: (user) => deleteUser(user) }\r\n * ])\r\n * ]}\r\n * defaultPageSize={20}\r\n * rowKey=\"id\"\r\n * />\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function RowaKitTable<T>({\r\n fetcher,\r\n columns,\r\n defaultPageSize = 20,\r\n pageSizeOptions = [10, 20, 50],\r\n rowKey,\r\n className = '',\r\n}: SmartTableProps<T>) {\r\n // State management\r\n const [dataState, setDataState] = useState<DataState<T>>({\r\n state: 'idle',\r\n items: [],\r\n total: 0,\r\n });\r\n\r\n const [query, setQuery] = useState<FetcherQuery>({\r\n page: 1,\r\n pageSize: defaultPageSize,\r\n });\r\n\r\n // Confirmation state for actions that require confirmation\r\n const [confirmState, setConfirmState] = useState<ConfirmState<T> | null>(null);\r\n\r\n // Request tracking to ignore stale responses\r\n const requestIdRef = useRef(0);\r\n\r\n // Fetch data effect\r\n useEffect(() => {\r\n const currentRequestId = ++requestIdRef.current;\r\n\r\n setDataState((prev) => ({ ...prev, state: 'loading' }));\r\n\r\n fetcher(query)\r\n .then((result) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n if (result.items.length === 0) {\r\n setDataState({\r\n state: 'empty',\r\n items: [],\r\n total: result.total,\r\n });\r\n } else {\r\n setDataState({\r\n state: 'success',\r\n items: result.items,\r\n total: result.total,\r\n });\r\n }\r\n })\r\n .catch((error: unknown) => {\r\n // Ignore stale responses\r\n if (currentRequestId !== requestIdRef.current) {\r\n return;\r\n }\r\n\r\n setDataState({\r\n state: 'error',\r\n items: [],\r\n total: 0,\r\n error: error instanceof Error ? error.message : 'Failed to load data',\r\n });\r\n });\r\n }, [fetcher, query]);\r\n\r\n // Retry handler\r\n const handleRetry = () => {\r\n // Force re-fetch by updating query reference\r\n setQuery({ ...query });\r\n };\r\n\r\n // Pagination handlers\r\n const handlePreviousPage = () => {\r\n if (query.page > 1) {\r\n setQuery((prev) => ({ ...prev, page: prev.page - 1 }));\r\n }\r\n };\r\n\r\n const handleNextPage = () => {\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n if (query.page < totalPages) {\r\n setQuery((prev) => ({ ...prev, page: prev.page + 1 }));\r\n }\r\n };\r\n\r\n const handlePageSizeChange = (newPageSize: number) => {\r\n setQuery({ ...query, pageSize: newPageSize, page: 1 });\r\n };\r\n\r\n // Sorting handler\r\n const handleSort = (field: string) => {\r\n setQuery((prev) => {\r\n // If sorting by a different field, start with ascending\r\n if (prev.sort?.field !== field) {\r\n return { ...prev, sort: { field, direction: 'asc' }, page: 1 };\r\n }\r\n\r\n // Toggle sort direction for the same field\r\n if (prev.sort.direction === 'asc') {\r\n return { ...prev, sort: { field, direction: 'desc' }, page: 1 };\r\n }\r\n\r\n // Remove sort (back to unsorted)\r\n const { sort: _sort, ...rest } = prev;\r\n return { ...rest, page: 1 };\r\n });\r\n };\r\n\r\n // Get sort indicator for a column\r\n const getSortIndicator = (field: string): string => {\r\n if (!query.sort || query.sort.field !== field) {\r\n return '';\r\n }\r\n return query.sort.direction === 'asc' ? ' ↑' : ' ↓';\r\n };\r\n\r\n const isLoading = dataState.state === 'loading';\r\n const isError = dataState.state === 'error';\r\n const isEmpty = dataState.state === 'empty';\r\n const totalPages = Math.ceil(dataState.total / query.pageSize);\r\n const canGoPrevious = query.page > 1 && !isLoading;\r\n const canGoNext = query.page < totalPages && !isLoading;\r\n\r\n return (\r\n <div className={`rowakit-table${className ? ` ${className}` : ''}`}>\r\n <table>\r\n <thead>\r\n <tr>\r\n {columns.map((column) => {\r\n const isSortable = column.kind !== 'actions' && \r\n (column.kind === 'custom' ? false : column.sortable === true);\r\n const field = column.kind === 'actions' ? '' : \r\n column.kind === 'custom' ? column.field : \r\n column.field;\r\n\r\n return (\r\n <th\r\n key={column.id}\r\n onClick={isSortable ? () => handleSort(String(field)) : undefined}\r\n role={isSortable ? 'button' : undefined}\r\n tabIndex={isSortable ? 0 : undefined}\r\n onKeyDown={isSortable ? (e) => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n handleSort(String(field));\r\n }\r\n } : undefined}\r\n aria-sort={\r\n isSortable && query.sort?.field === String(field)\r\n ? query.sort.direction === 'asc' ? 'ascending' : 'descending'\r\n : undefined\r\n }\r\n >\r\n {getHeaderLabel(column)}{isSortable && getSortIndicator(String(field))}\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {isLoading && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-loading\">\r\n <div className=\"rowakit-table-loading-spinner\"></div>\r\n <span>Loading...</span>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isError && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-error\">\r\n <div className=\"rowakit-table-error-message\">\r\n {dataState.error ?? 'An error occurred'}\r\n </div>\r\n <button\r\n onClick={handleRetry}\r\n className=\"rowakit-button rowakit-button-primary\"\r\n type=\"button\"\r\n >\r\n Retry\r\n </button>\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {isEmpty && (\r\n <tr>\r\n <td colSpan={columns.length} className=\"rowakit-table-empty\">\r\n No data\r\n </td>\r\n </tr>\r\n )}\r\n\r\n {dataState.state === 'success' &&\r\n dataState.items.map((row) => {\r\n const key = getRowKey(row, rowKey);\r\n return (\r\n <tr key={key}>\r\n {columns.map((column) => (\r\n <td key={column.id}>\r\n {renderCell(column, row, isLoading, setConfirmState)}\r\n </td>\r\n ))}\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n\r\n {/* Pagination Controls */}\r\n {dataState.total > 0 && (\r\n <div className=\"rowakit-table-pagination\">\r\n {/* Left: Page size selector */}\r\n <div className=\"rowakit-table-pagination-left\">\r\n <label htmlFor=\"page-size\">\r\n Rows per page:\r\n </label>\r\n <select\r\n id=\"page-size\"\r\n value={query.pageSize}\r\n onChange={(e) => handlePageSizeChange(Number(e.target.value))}\r\n disabled={isLoading}\r\n >\r\n {pageSizeOptions.map((size) => (\r\n <option key={size} value={size}>\r\n {size}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n {/* Center: Page info */}\r\n <div className=\"rowakit-table-pagination-center\">\r\n Page {query.page} of {totalPages} ({dataState.total} total)\r\n </div>\r\n\r\n {/* Right: Previous/Next buttons */}\r\n <div className=\"rowakit-table-pagination-right\">\r\n <button\r\n onClick={handlePreviousPage}\r\n disabled={!canGoPrevious}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Previous page\"\r\n >\r\n Previous\r\n </button>\r\n <button\r\n onClick={handleNextPage}\r\n disabled={!canGoNext}\r\n className=\"rowakit-button rowakit-button-primary rowakit-button-pagination\"\r\n type=\"button\"\r\n aria-label=\"Next page\"\r\n >\r\n Next\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Confirmation Modal */}\r\n {confirmState && (\r\n <div\r\n className=\"rowakit-modal-backdrop\"\r\n onClick={() => setConfirmState(null)}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby=\"confirm-dialog-title\"\r\n >\r\n <div className=\"rowakit-modal\" onClick={(e) => e.stopPropagation()}>\r\n <h2 id=\"confirm-dialog-title\" className=\"rowakit-modal-title\">\r\n Confirm Action\r\n </h2>\r\n <p className=\"rowakit-modal-content\">\r\n Are you sure you want to {confirmState.action.label.toLowerCase()}? This action cannot be\r\n undone.\r\n </p>\r\n <div className=\"rowakit-modal-actions\">\r\n <button\r\n onClick={() => setConfirmState(null)}\r\n className=\"rowakit-button rowakit-button-secondary\"\r\n type=\"button\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n onClick={() => {\r\n void confirmState.action.onClick(confirmState.row);\r\n setConfirmState(null);\r\n }}\r\n className=\"rowakit-button rowakit-button-danger\"\r\n type=\"button\"\r\n >\r\n Confirm\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/**\r\n * @deprecated Use RowaKitTable instead. SmartTable is kept as an alias for backward compatibility.\r\n */\r\nexport const SmartTable = RowaKitTable;\r\n","/**\r\n * @rowakit/table\r\n *\r\n * Opinionated, server-side-first table component for internal/business apps.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\n// Core types\r\nexport type {\r\n // Fetcher types\r\n Fetcher,\r\n FetcherQuery,\r\n FetcherResult,\r\n // Column types\r\n ColumnDef,\r\n ColumnKind,\r\n BaseColumnDef,\r\n TextColumnDef,\r\n DateColumnDef,\r\n BooleanColumnDef,\r\n ActionsColumnDef,\r\n CustomColumnDef,\r\n // Action types\r\n ActionDef,\r\n} from './types';\r\n\r\n// Column helper factory\r\nexport { col } from './column-helpers';\r\n\r\n// Components\r\nexport { RowaKitTable, SmartTable } from './components/SmartTable';\r\nexport type { SmartTableProps } from './components/SmartTable';\r\n\r\nexport const VERSION = '0.1.0';\r\n"]}
|