@tomny-dev/uzi 0.3.0 → 0.4.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 +28 -0
- package/dist/components/data-table/DataTable.d.ts +36 -0
- package/dist/components/data-table/DataTable.d.ts.map +1 -0
- package/dist/components/data-table/DataTable.test.d.ts +2 -0
- package/dist/components/data-table/DataTable.test.d.ts.map +1 -0
- package/dist/components/empty-state-page/EmptyStatePage.d.ts +26 -0
- package/dist/components/empty-state-page/EmptyStatePage.d.ts.map +1 -0
- package/dist/components/empty-state-page/EmptyStatePage.test.d.ts +2 -0
- package/dist/components/empty-state-page/EmptyStatePage.test.d.ts.map +1 -0
- package/dist/components/error-page/ErrorPage.d.ts +32 -0
- package/dist/components/error-page/ErrorPage.d.ts.map +1 -0
- package/dist/components/error-page/ErrorPage.test.d.ts +2 -0
- package/dist/components/error-page/ErrorPage.test.d.ts.map +1 -0
- package/dist/components/settings-page/SettingsPage.d.ts +38 -0
- package/dist/components/settings-page/SettingsPage.d.ts.map +1 -0
- package/dist/components/settings-page/SettingsPage.test.d.ts +2 -0
- package/dist/components/settings-page/SettingsPage.test.d.ts.map +1 -0
- package/dist/index.cjs +10 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index63.js +63 -0
- package/dist/index63.js.map +1 -0
- package/dist/index64.cjs +91 -0
- package/dist/index64.cjs.map +1 -0
- package/dist/index64.js +246 -0
- package/dist/index64.js.map +1 -0
- package/dist/index65.cjs +248 -0
- package/dist/index65.cjs.map +1 -0
- package/dist/index65.js +47 -0
- package/dist/index65.js.map +1 -0
- package/dist/index66.cjs +67 -0
- package/dist/index66.cjs.map +1 -0
- package/dist/index66.js +86 -0
- package/dist/index66.js.map +1 -0
- package/dist/index67.cjs +88 -0
- package/dist/index67.cjs.map +1 -0
- package/dist/index67.js +25 -0
- package/dist/index67.js.map +1 -0
- package/dist/index68.cjs +34 -0
- package/dist/index68.cjs.map +1 -0
- package/dist/index68.js +101 -0
- package/dist/index68.js.map +1 -0
- package/dist/index69.cjs +105 -0
- package/dist/index69.cjs.map +1 -0
- package/dist/index69.js +23 -0
- package/dist/index69.js.map +1 -0
- package/dist/index70.cjs +31 -0
- package/dist/index70.cjs.map +1 -0
- package/dist/index70.js +159 -0
- package/dist/index70.js.map +1 -0
- package/dist/index71.cjs +161 -0
- package/dist/index71.cjs.map +1 -0
- package/dist/style.css +532 -0
- package/package.json +9 -1
package/dist/index64.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "./index3.js";
|
|
3
|
+
import data_table_module_default from "./index63.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/data-table/DataTable.tsx
|
|
7
|
+
function DataTable({ data, columns, onRowAction, onSelectionChange, loading = false, emptyMessage = "No data found", pageSize = 10, selectable = false, rowKey = (row) => String(row.id ?? ""), className }) {
|
|
8
|
+
const [sortKey, setSortKey] = React.useState(null);
|
|
9
|
+
const [sortDir, setSortDir] = React.useState("asc");
|
|
10
|
+
const [page, setPage] = React.useState(1);
|
|
11
|
+
const [selected, setSelected] = React.useState(/* @__PURE__ */ new Set());
|
|
12
|
+
const handleSort = (key) => {
|
|
13
|
+
if (key === sortKey) setSortDir((d) => d === "asc" ? "desc" : "asc");
|
|
14
|
+
else {
|
|
15
|
+
setSortKey(key);
|
|
16
|
+
setSortDir("asc");
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const toggleRow = (id) => {
|
|
20
|
+
const next = new Set(selected);
|
|
21
|
+
if (next.has(id)) next.delete(id);
|
|
22
|
+
else next.add(id);
|
|
23
|
+
setSelected(next);
|
|
24
|
+
onSelectionChange?.(Array.from(next));
|
|
25
|
+
};
|
|
26
|
+
const toggleAll = () => {
|
|
27
|
+
const allKeys = displayedData.map((r) => rowKey(r));
|
|
28
|
+
const allSelected = allKeys.every((k) => selected.has(k));
|
|
29
|
+
const next = new Set(selected);
|
|
30
|
+
if (allSelected) allKeys.forEach((k) => next.delete(k));
|
|
31
|
+
else allKeys.forEach((k) => next.add(k));
|
|
32
|
+
setSelected(next);
|
|
33
|
+
onSelectionChange?.(Array.from(next));
|
|
34
|
+
};
|
|
35
|
+
const totalPages = Math.max(1, Math.ceil(data.length / pageSize));
|
|
36
|
+
const safePage = Math.min(page, totalPages);
|
|
37
|
+
const columnSpan = columns.length + (selectable ? 1 : 0) + (onRowAction && onRowAction.length > 0 ? 1 : 0);
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
if (page > totalPages) setPage(totalPages);
|
|
40
|
+
}, [
|
|
41
|
+
data.length,
|
|
42
|
+
page,
|
|
43
|
+
totalPages
|
|
44
|
+
]);
|
|
45
|
+
const sortedData = React.useMemo(() => {
|
|
46
|
+
if (!sortKey) return data;
|
|
47
|
+
const sortColumn = columns.find((column) => column.key === sortKey);
|
|
48
|
+
const getSortValue = (row) => {
|
|
49
|
+
if (sortColumn?.accessor) {
|
|
50
|
+
const accessed = sortColumn.accessor(row);
|
|
51
|
+
if (typeof accessed === "string" || typeof accessed === "number") return accessed;
|
|
52
|
+
}
|
|
53
|
+
return row[sortKey];
|
|
54
|
+
};
|
|
55
|
+
return [...data].sort((a, b) => {
|
|
56
|
+
const aVal = getSortValue(a);
|
|
57
|
+
const bVal = getSortValue(b);
|
|
58
|
+
if (aVal == null) return 1;
|
|
59
|
+
if (bVal == null) return -1;
|
|
60
|
+
let cmp = 0;
|
|
61
|
+
if (typeof aVal === "number" && typeof bVal === "number") cmp = aVal - bVal;
|
|
62
|
+
else cmp = String(aVal).localeCompare(String(bVal));
|
|
63
|
+
return sortDir === "asc" ? cmp : -cmp;
|
|
64
|
+
});
|
|
65
|
+
}, [
|
|
66
|
+
columns,
|
|
67
|
+
data,
|
|
68
|
+
sortKey,
|
|
69
|
+
sortDir
|
|
70
|
+
]);
|
|
71
|
+
const displayedData = React.useMemo(() => {
|
|
72
|
+
const start = (safePage - 1) * pageSize;
|
|
73
|
+
return sortedData.slice(start, start + pageSize);
|
|
74
|
+
}, [
|
|
75
|
+
sortedData,
|
|
76
|
+
safePage,
|
|
77
|
+
pageSize
|
|
78
|
+
]);
|
|
79
|
+
const displayedKeys = React.useMemo(() => displayedData.map(rowKey), [displayedData, rowKey]);
|
|
80
|
+
const allPageSelected = displayedKeys.length > 0 && displayedKeys.every((k) => selected.has(k));
|
|
81
|
+
const somePageSelected = displayedKeys.length > 0 && displayedKeys.some((k) => selected.has(k));
|
|
82
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
83
|
+
className: cx(data_table_module_default.wrapper, className),
|
|
84
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
85
|
+
className: data_table_module_default.tableContainer,
|
|
86
|
+
children: /* @__PURE__ */ jsxs("table", {
|
|
87
|
+
className: data_table_module_default.table,
|
|
88
|
+
children: [/* @__PURE__ */ jsx("thead", {
|
|
89
|
+
className: data_table_module_default.thead,
|
|
90
|
+
children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
91
|
+
selectable && /* @__PURE__ */ jsx("th", {
|
|
92
|
+
className: data_table_module_default.headerCell,
|
|
93
|
+
"aria-label": "Select all",
|
|
94
|
+
children: /* @__PURE__ */ jsx("input", {
|
|
95
|
+
type: "checkbox",
|
|
96
|
+
checked: allPageSelected,
|
|
97
|
+
ref: (el) => {
|
|
98
|
+
if (el) el.indeterminate = somePageSelected && !allPageSelected;
|
|
99
|
+
},
|
|
100
|
+
onChange: toggleAll,
|
|
101
|
+
className: data_table_module_default.checkbox,
|
|
102
|
+
"aria-label": "Select all rows on this page"
|
|
103
|
+
})
|
|
104
|
+
}),
|
|
105
|
+
columns.map((col) => {
|
|
106
|
+
const ariaSort = col.sortable ? sortKey === col.key ? sortDir === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
107
|
+
return /* @__PURE__ */ jsx("th", {
|
|
108
|
+
className: cx(data_table_module_default.headerCell, col.width && data_table_module_default.headerCellFixed, col.align && data_table_module_default[`align${col.align.charAt(0).toUpperCase() + col.align.slice(1)}`]),
|
|
109
|
+
style: col.width ? { width: col.width } : void 0,
|
|
110
|
+
"aria-sort": ariaSort,
|
|
111
|
+
children: col.sortable ? /* @__PURE__ */ jsxs("button", {
|
|
112
|
+
type: "button",
|
|
113
|
+
className: cx(data_table_module_default.sortableHeader, data_table_module_default.clickableHeader),
|
|
114
|
+
onClick: () => handleSort(col.key),
|
|
115
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
116
|
+
className: data_table_module_default.headerLabel,
|
|
117
|
+
children: col.label
|
|
118
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
119
|
+
className: data_table_module_default.sortIcon,
|
|
120
|
+
"aria-hidden": "true",
|
|
121
|
+
children: sortKey === col.key ? sortDir === "asc" ? "▲" : "▼" : "▲▼"
|
|
122
|
+
})]
|
|
123
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
124
|
+
className: data_table_module_default.headerLabel,
|
|
125
|
+
children: col.label
|
|
126
|
+
})
|
|
127
|
+
}, col.key);
|
|
128
|
+
}),
|
|
129
|
+
onRowAction && onRowAction.length > 0 && /* @__PURE__ */ jsx("th", {
|
|
130
|
+
className: data_table_module_default.headerCell,
|
|
131
|
+
style: { width: "5rem" },
|
|
132
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
133
|
+
className: data_table_module_default.headerLabel,
|
|
134
|
+
children: "Actions"
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
] })
|
|
138
|
+
}), /* @__PURE__ */ jsx("tbody", {
|
|
139
|
+
className: data_table_module_default.tbody,
|
|
140
|
+
children: loading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs("td", {
|
|
141
|
+
colSpan: columnSpan,
|
|
142
|
+
className: data_table_module_default.loadingCell,
|
|
143
|
+
children: [
|
|
144
|
+
/* @__PURE__ */ jsxs("div", {
|
|
145
|
+
className: data_table_module_default.loadingRow,
|
|
146
|
+
"aria-busy": "true",
|
|
147
|
+
children: [
|
|
148
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar }),
|
|
149
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar }),
|
|
150
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar })
|
|
151
|
+
]
|
|
152
|
+
}),
|
|
153
|
+
/* @__PURE__ */ jsxs("div", {
|
|
154
|
+
className: data_table_module_default.loadingRow,
|
|
155
|
+
"aria-busy": "true",
|
|
156
|
+
children: [
|
|
157
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar }),
|
|
158
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar }),
|
|
159
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar })
|
|
160
|
+
]
|
|
161
|
+
}),
|
|
162
|
+
/* @__PURE__ */ jsxs("div", {
|
|
163
|
+
className: data_table_module_default.loadingRow,
|
|
164
|
+
"aria-busy": "true",
|
|
165
|
+
children: [
|
|
166
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar }),
|
|
167
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar }),
|
|
168
|
+
/* @__PURE__ */ jsx("div", { className: data_table_module_default.skeletonBar })
|
|
169
|
+
]
|
|
170
|
+
})
|
|
171
|
+
]
|
|
172
|
+
}) }) : data.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
|
|
173
|
+
colSpan: columnSpan,
|
|
174
|
+
className: data_table_module_default.emptyCell,
|
|
175
|
+
children: emptyMessage
|
|
176
|
+
}) }) : displayedData.map((row) => {
|
|
177
|
+
const id = rowKey(row);
|
|
178
|
+
return /* @__PURE__ */ jsxs("tr", {
|
|
179
|
+
className: cx(data_table_module_default.row, selected.has(id) && data_table_module_default.rowSelected),
|
|
180
|
+
children: [
|
|
181
|
+
selectable && /* @__PURE__ */ jsx("td", {
|
|
182
|
+
className: data_table_module_default.cell,
|
|
183
|
+
children: /* @__PURE__ */ jsx("input", {
|
|
184
|
+
type: "checkbox",
|
|
185
|
+
checked: selected.has(id),
|
|
186
|
+
onChange: () => toggleRow(id),
|
|
187
|
+
className: data_table_module_default.checkbox,
|
|
188
|
+
"aria-label": `Select row ${id}`
|
|
189
|
+
})
|
|
190
|
+
}),
|
|
191
|
+
columns.map((col) => /* @__PURE__ */ jsx("td", {
|
|
192
|
+
className: cx(data_table_module_default.cell, col.align && data_table_module_default[`align${col.align.charAt(0).toUpperCase() + col.align.slice(1)}`]),
|
|
193
|
+
children: col.accessor ? col.accessor(row) : String(row[col.key] ?? "")
|
|
194
|
+
}, `${id}-${col.key}`)),
|
|
195
|
+
onRowAction && onRowAction.length > 0 && /* @__PURE__ */ jsx("td", {
|
|
196
|
+
className: data_table_module_default.cell,
|
|
197
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
198
|
+
className: data_table_module_default.rowActions,
|
|
199
|
+
children: onRowAction.map((action) => /* @__PURE__ */ jsx("button", {
|
|
200
|
+
type: "button",
|
|
201
|
+
className: data_table_module_default.actionBtn,
|
|
202
|
+
onClick: () => action.onClick(row),
|
|
203
|
+
children: action.label
|
|
204
|
+
}, action.label))
|
|
205
|
+
})
|
|
206
|
+
})
|
|
207
|
+
]
|
|
208
|
+
}, id);
|
|
209
|
+
})
|
|
210
|
+
})]
|
|
211
|
+
})
|
|
212
|
+
}), data.length > pageSize && /* @__PURE__ */ jsxs("div", {
|
|
213
|
+
className: data_table_module_default.pagination,
|
|
214
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
215
|
+
className: data_table_module_default.paginationInfo,
|
|
216
|
+
children: [
|
|
217
|
+
"Page ",
|
|
218
|
+
safePage,
|
|
219
|
+
" of ",
|
|
220
|
+
totalPages
|
|
221
|
+
]
|
|
222
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
223
|
+
className: data_table_module_default.paginationButtons,
|
|
224
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
225
|
+
type: "button",
|
|
226
|
+
className: data_table_module_default.pageBtn,
|
|
227
|
+
disabled: safePage <= 1,
|
|
228
|
+
onClick: () => setPage((p) => Math.max(1, p - 1)),
|
|
229
|
+
"aria-label": "Previous page",
|
|
230
|
+
children: "←"
|
|
231
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
232
|
+
type: "button",
|
|
233
|
+
className: data_table_module_default.pageBtn,
|
|
234
|
+
disabled: safePage >= totalPages,
|
|
235
|
+
onClick: () => setPage((p) => Math.min(totalPages, p + 1)),
|
|
236
|
+
"aria-label": "Next page",
|
|
237
|
+
children: "→"
|
|
238
|
+
})]
|
|
239
|
+
})]
|
|
240
|
+
})]
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
export { DataTable };
|
|
245
|
+
|
|
246
|
+
//# sourceMappingURL=index64.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index64.js","names":[],"sources":["../src/components/data-table/DataTable.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./data-table.module.css\";\n\nexport type SortDirection = \"asc\" | \"desc\";\n\nexport interface Column<T = Record<string, unknown>> {\n key: string;\n label: React.ReactNode;\n accessor?: (row: T) => React.ReactNode;\n sortable?: boolean;\n width?: string;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport type DataTableRowAction = {\n label: string;\n onClick: (row: Record<string, unknown>) => void;\n};\n\nexport interface DataTableProps<T = Record<string, unknown>> {\n data: T[];\n columns: readonly Column<T>[];\n /** Array of action buttons to render per row */\n onRowAction?: DataTableRowAction[];\n /** Called when rows are selected; receives selected row IDs */\n onSelectionChange?: (selectedIds: string[]) => void;\n /** Whether the table is in a loading state */\n loading?: boolean;\n /** Message displayed when data is empty */\n emptyMessage?: string;\n /** Number of rows per page */\n pageSize?: number;\n /** Whether rows are selectable via checkbox */\n selectable?: boolean;\n /** Custom row key extractor (defaults to row.id) */\n rowKey?: (row: T) => string;\n /** Additional class name for the table wrapper */\n className?: string;\n}\n\nexport function DataTable<T extends Record<string, unknown> = Record<string, unknown>>({\n data,\n columns,\n onRowAction,\n onSelectionChange,\n loading = false,\n emptyMessage = \"No data found\",\n pageSize = 10,\n selectable = false,\n rowKey = (row: T) => String(row.id ?? \"\"),\n className,\n}: DataTableProps<T>) {\n const [sortKey, setSortKey] = React.useState<string | null>(null);\n const [sortDir, setSortDir] = React.useState<SortDirection>(\"asc\");\n const [page, setPage] = React.useState(1);\n const [selected, setSelected] = React.useState<Set<string>>(new Set());\n\n const handleSort = (key: string) => {\n if (key === sortKey) {\n setSortDir((d) => (d === \"asc\" ? \"desc\" : \"asc\"));\n } else {\n setSortKey(key);\n setSortDir(\"asc\");\n }\n };\n\n const toggleRow = (id: string) => {\n const next = new Set(selected);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n setSelected(next);\n onSelectionChange?.(Array.from(next));\n };\n\n const toggleAll = () => {\n const allKeys = displayedData.map((r) => rowKey(r));\n const allSelected = allKeys.every((k) => selected.has(k));\n const next = new Set(selected);\n if (allSelected) {\n allKeys.forEach((k) => next.delete(k));\n } else {\n allKeys.forEach((k) => next.add(k));\n }\n setSelected(next);\n onSelectionChange?.(Array.from(next));\n };\n\n const totalPages = Math.max(1, Math.ceil(data.length / pageSize));\n const safePage = Math.min(page, totalPages);\n const columnSpan =\n columns.length + (selectable ? 1 : 0) + (onRowAction && onRowAction.length > 0 ? 1 : 0);\n\n React.useEffect(() => {\n if (page > totalPages) {\n setPage(totalPages);\n }\n }, [data.length, page, totalPages]);\n\n const sortedData = React.useMemo(() => {\n if (!sortKey) return data;\n\n const sortColumn = columns.find((column) => column.key === sortKey);\n const getSortValue = (row: T): unknown => {\n if (sortColumn?.accessor) {\n const accessed = sortColumn.accessor(row);\n if (typeof accessed === \"string\" || typeof accessed === \"number\") {\n return accessed;\n }\n }\n return row[sortKey as keyof T];\n };\n\n return [...data].sort((a, b) => {\n const aVal = getSortValue(a);\n const bVal = getSortValue(b);\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n let cmp = 0;\n if (typeof aVal === \"number\" && typeof bVal === \"number\") {\n cmp = aVal - bVal;\n } else {\n cmp = String(aVal).localeCompare(String(bVal));\n }\n return sortDir === \"asc\" ? cmp : -cmp;\n });\n }, [columns, data, sortKey, sortDir]);\n\n const displayedData = React.useMemo(() => {\n const start = (safePage - 1) * pageSize;\n return sortedData.slice(start, start + pageSize);\n }, [sortedData, safePage, pageSize]);\n\n const displayedKeys = React.useMemo(() => displayedData.map(rowKey), [displayedData, rowKey]);\n const allPageSelected =\n displayedKeys.length > 0 && displayedKeys.every((k) => selected.has(k));\n const somePageSelected =\n displayedKeys.length > 0 && displayedKeys.some((k) => selected.has(k));\n\n return (\n <div className={cx(styles.wrapper, className)}>\n <div className={styles.tableContainer}>\n <table className={styles.table}>\n <thead className={styles.thead}>\n <tr>\n {selectable && (\n <th className={styles.headerCell} aria-label=\"Select all\">\n <input\n type=\"checkbox\"\n checked={allPageSelected}\n ref={(el) => {\n if (el) el.indeterminate = somePageSelected && !allPageSelected;\n }}\n onChange={toggleAll}\n className={styles.checkbox}\n aria-label=\"Select all rows on this page\"\n />\n </th>\n )}\n {columns.map((col) => {\n const ariaSort = col.sortable\n ? sortKey === col.key\n ? sortDir === \"asc\"\n ? \"ascending\"\n : \"descending\"\n : \"none\"\n : undefined;\n\n return (\n <th\n key={col.key}\n className={cx(\n styles.headerCell,\n col.width && styles.headerCellFixed,\n col.align && styles[`align${col.align.charAt(0).toUpperCase() + col.align.slice(1)}`],\n )}\n style={col.width ? { width: col.width } : undefined}\n aria-sort={ariaSort}\n >\n {col.sortable ? (\n <button\n type=\"button\"\n className={cx(styles.sortableHeader, styles.clickableHeader)}\n onClick={() => handleSort(col.key)}\n >\n <span className={styles.headerLabel}>{col.label}</span>\n <span className={styles.sortIcon} aria-hidden=\"true\">\n {sortKey === col.key ? (\n sortDir === \"asc\" ? (\n \"\\u25B2\"\n ) : (\n \"\\u25BC\"\n )\n ) : (\n \"\\u25B2\\u25BC\"\n )}\n </span>\n </button>\n ) : (\n <span className={styles.headerLabel}>{col.label}</span>\n )}\n </th>\n );\n })}\n {onRowAction && onRowAction.length > 0 && (\n <th className={styles.headerCell} style={{ width: \"5rem\" }}>\n <span className={styles.headerLabel}>Actions</span>\n </th>\n )}\n </tr>\n </thead>\n <tbody className={styles.tbody}>\n {loading ? (\n <tr>\n <td colSpan={columnSpan} className={styles.loadingCell}>\n <div className={styles.loadingRow} aria-busy=\"true\">\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n </div>\n <div className={styles.loadingRow} aria-busy=\"true\">\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n </div>\n <div className={styles.loadingRow} aria-busy=\"true\">\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n </div>\n </td>\n </tr>\n ) : data.length === 0 ? (\n <tr>\n <td colSpan={columnSpan} className={styles.emptyCell}>\n {emptyMessage}\n </td>\n </tr>\n ) : (\n displayedData.map((row) => {\n const id = rowKey(row);\n return (\n <tr key={id} className={cx(styles.row, selected.has(id) && styles.rowSelected)}>\n {selectable && (\n <td className={styles.cell}>\n <input\n type=\"checkbox\"\n checked={selected.has(id)}\n onChange={() => toggleRow(id)}\n className={styles.checkbox}\n aria-label={`Select row ${id}`}\n />\n </td>\n )}\n {columns.map((col) => (\n <td\n key={`${id}-${col.key}`}\n className={cx(\n styles.cell,\n col.align && styles[`align${col.align.charAt(0).toUpperCase() + col.align.slice(1)}`],\n )}\n >\n {col.accessor ? col.accessor(row) : String(row[col.key as keyof T] ?? \"\")}\n </td>\n ))}\n {onRowAction && onRowAction.length > 0 && (\n <td className={styles.cell}>\n <div className={styles.rowActions}>\n {onRowAction.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n className={styles.actionBtn}\n onClick={() => action.onClick(row)}\n >\n {action.label}\n </button>\n ))}\n </div>\n </td>\n )}\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {data.length > pageSize && (\n <div className={styles.pagination}>\n <span className={styles.paginationInfo}>\n Page {safePage} of {totalPages}\n </span>\n <div className={styles.paginationButtons}>\n <button\n type=\"button\"\n className={styles.pageBtn}\n disabled={safePage <= 1}\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n aria-label=\"Previous page\"\n >\n ←\n </button>\n <button\n type=\"button\"\n className={styles.pageBtn}\n disabled={safePage >= totalPages}\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\n aria-label=\"Next page\"\n >\n →\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
package/dist/index65.cjs
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("./index2.cjs");
|
|
3
|
+
const require_cx = require("./index4.cjs");
|
|
4
|
+
const require_data_table_module = require("./index64.cjs");
|
|
5
|
+
let react = require("react");
|
|
6
|
+
react = require_runtime.__toESM(react, 1);
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
//#region src/components/data-table/DataTable.tsx
|
|
9
|
+
function DataTable({ data, columns, onRowAction, onSelectionChange, loading = false, emptyMessage = "No data found", pageSize = 10, selectable = false, rowKey = (row) => String(row.id ?? ""), className }) {
|
|
10
|
+
const [sortKey, setSortKey] = react.useState(null);
|
|
11
|
+
const [sortDir, setSortDir] = react.useState("asc");
|
|
12
|
+
const [page, setPage] = react.useState(1);
|
|
13
|
+
const [selected, setSelected] = react.useState(/* @__PURE__ */ new Set());
|
|
14
|
+
const handleSort = (key) => {
|
|
15
|
+
if (key === sortKey) setSortDir((d) => d === "asc" ? "desc" : "asc");
|
|
16
|
+
else {
|
|
17
|
+
setSortKey(key);
|
|
18
|
+
setSortDir("asc");
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const toggleRow = (id) => {
|
|
22
|
+
const next = new Set(selected);
|
|
23
|
+
if (next.has(id)) next.delete(id);
|
|
24
|
+
else next.add(id);
|
|
25
|
+
setSelected(next);
|
|
26
|
+
onSelectionChange?.(Array.from(next));
|
|
27
|
+
};
|
|
28
|
+
const toggleAll = () => {
|
|
29
|
+
const allKeys = displayedData.map((r) => rowKey(r));
|
|
30
|
+
const allSelected = allKeys.every((k) => selected.has(k));
|
|
31
|
+
const next = new Set(selected);
|
|
32
|
+
if (allSelected) allKeys.forEach((k) => next.delete(k));
|
|
33
|
+
else allKeys.forEach((k) => next.add(k));
|
|
34
|
+
setSelected(next);
|
|
35
|
+
onSelectionChange?.(Array.from(next));
|
|
36
|
+
};
|
|
37
|
+
const totalPages = Math.max(1, Math.ceil(data.length / pageSize));
|
|
38
|
+
const safePage = Math.min(page, totalPages);
|
|
39
|
+
const columnSpan = columns.length + (selectable ? 1 : 0) + (onRowAction && onRowAction.length > 0 ? 1 : 0);
|
|
40
|
+
react.useEffect(() => {
|
|
41
|
+
if (page > totalPages) setPage(totalPages);
|
|
42
|
+
}, [
|
|
43
|
+
data.length,
|
|
44
|
+
page,
|
|
45
|
+
totalPages
|
|
46
|
+
]);
|
|
47
|
+
const sortedData = react.useMemo(() => {
|
|
48
|
+
if (!sortKey) return data;
|
|
49
|
+
const sortColumn = columns.find((column) => column.key === sortKey);
|
|
50
|
+
const getSortValue = (row) => {
|
|
51
|
+
if (sortColumn?.accessor) {
|
|
52
|
+
const accessed = sortColumn.accessor(row);
|
|
53
|
+
if (typeof accessed === "string" || typeof accessed === "number") return accessed;
|
|
54
|
+
}
|
|
55
|
+
return row[sortKey];
|
|
56
|
+
};
|
|
57
|
+
return [...data].sort((a, b) => {
|
|
58
|
+
const aVal = getSortValue(a);
|
|
59
|
+
const bVal = getSortValue(b);
|
|
60
|
+
if (aVal == null) return 1;
|
|
61
|
+
if (bVal == null) return -1;
|
|
62
|
+
let cmp = 0;
|
|
63
|
+
if (typeof aVal === "number" && typeof bVal === "number") cmp = aVal - bVal;
|
|
64
|
+
else cmp = String(aVal).localeCompare(String(bVal));
|
|
65
|
+
return sortDir === "asc" ? cmp : -cmp;
|
|
66
|
+
});
|
|
67
|
+
}, [
|
|
68
|
+
columns,
|
|
69
|
+
data,
|
|
70
|
+
sortKey,
|
|
71
|
+
sortDir
|
|
72
|
+
]);
|
|
73
|
+
const displayedData = react.useMemo(() => {
|
|
74
|
+
const start = (safePage - 1) * pageSize;
|
|
75
|
+
return sortedData.slice(start, start + pageSize);
|
|
76
|
+
}, [
|
|
77
|
+
sortedData,
|
|
78
|
+
safePage,
|
|
79
|
+
pageSize
|
|
80
|
+
]);
|
|
81
|
+
const displayedKeys = react.useMemo(() => displayedData.map(rowKey), [displayedData, rowKey]);
|
|
82
|
+
const allPageSelected = displayedKeys.length > 0 && displayedKeys.every((k) => selected.has(k));
|
|
83
|
+
const somePageSelected = displayedKeys.length > 0 && displayedKeys.some((k) => selected.has(k));
|
|
84
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
85
|
+
className: require_cx.cx(require_data_table_module.default.wrapper, className),
|
|
86
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
87
|
+
className: require_data_table_module.default.tableContainer,
|
|
88
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
|
|
89
|
+
className: require_data_table_module.default.table,
|
|
90
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", {
|
|
91
|
+
className: require_data_table_module.default.thead,
|
|
92
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
93
|
+
selectable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
94
|
+
className: require_data_table_module.default.headerCell,
|
|
95
|
+
"aria-label": "Select all",
|
|
96
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
97
|
+
type: "checkbox",
|
|
98
|
+
checked: allPageSelected,
|
|
99
|
+
ref: (el) => {
|
|
100
|
+
if (el) el.indeterminate = somePageSelected && !allPageSelected;
|
|
101
|
+
},
|
|
102
|
+
onChange: toggleAll,
|
|
103
|
+
className: require_data_table_module.default.checkbox,
|
|
104
|
+
"aria-label": "Select all rows on this page"
|
|
105
|
+
})
|
|
106
|
+
}),
|
|
107
|
+
columns.map((col) => {
|
|
108
|
+
const ariaSort = col.sortable ? sortKey === col.key ? sortDir === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
109
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
110
|
+
className: require_cx.cx(require_data_table_module.default.headerCell, col.width && require_data_table_module.default.headerCellFixed, col.align && require_data_table_module.default[`align${col.align.charAt(0).toUpperCase() + col.align.slice(1)}`]),
|
|
111
|
+
style: col.width ? { width: col.width } : void 0,
|
|
112
|
+
"aria-sort": ariaSort,
|
|
113
|
+
children: col.sortable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
114
|
+
type: "button",
|
|
115
|
+
className: require_cx.cx(require_data_table_module.default.sortableHeader, require_data_table_module.default.clickableHeader),
|
|
116
|
+
onClick: () => handleSort(col.key),
|
|
117
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
118
|
+
className: require_data_table_module.default.headerLabel,
|
|
119
|
+
children: col.label
|
|
120
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
121
|
+
className: require_data_table_module.default.sortIcon,
|
|
122
|
+
"aria-hidden": "true",
|
|
123
|
+
children: sortKey === col.key ? sortDir === "asc" ? "▲" : "▼" : "▲▼"
|
|
124
|
+
})]
|
|
125
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
126
|
+
className: require_data_table_module.default.headerLabel,
|
|
127
|
+
children: col.label
|
|
128
|
+
})
|
|
129
|
+
}, col.key);
|
|
130
|
+
}),
|
|
131
|
+
onRowAction && onRowAction.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
132
|
+
className: require_data_table_module.default.headerCell,
|
|
133
|
+
style: { width: "5rem" },
|
|
134
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
135
|
+
className: require_data_table_module.default.headerLabel,
|
|
136
|
+
children: "Actions"
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
] })
|
|
140
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", {
|
|
141
|
+
className: require_data_table_module.default.tbody,
|
|
142
|
+
children: loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", {
|
|
143
|
+
colSpan: columnSpan,
|
|
144
|
+
className: require_data_table_module.default.loadingCell,
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
147
|
+
className: require_data_table_module.default.loadingRow,
|
|
148
|
+
"aria-busy": "true",
|
|
149
|
+
children: [
|
|
150
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar }),
|
|
151
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar }),
|
|
152
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar })
|
|
153
|
+
]
|
|
154
|
+
}),
|
|
155
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
156
|
+
className: require_data_table_module.default.loadingRow,
|
|
157
|
+
"aria-busy": "true",
|
|
158
|
+
children: [
|
|
159
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar }),
|
|
160
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar }),
|
|
161
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar })
|
|
162
|
+
]
|
|
163
|
+
}),
|
|
164
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
165
|
+
className: require_data_table_module.default.loadingRow,
|
|
166
|
+
"aria-busy": "true",
|
|
167
|
+
children: [
|
|
168
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar }),
|
|
169
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar }),
|
|
170
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: require_data_table_module.default.skeletonBar })
|
|
171
|
+
]
|
|
172
|
+
})
|
|
173
|
+
]
|
|
174
|
+
}) }) : data.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
175
|
+
colSpan: columnSpan,
|
|
176
|
+
className: require_data_table_module.default.emptyCell,
|
|
177
|
+
children: emptyMessage
|
|
178
|
+
}) }) : displayedData.map((row) => {
|
|
179
|
+
const id = rowKey(row);
|
|
180
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
|
|
181
|
+
className: require_cx.cx(require_data_table_module.default.row, selected.has(id) && require_data_table_module.default.rowSelected),
|
|
182
|
+
children: [
|
|
183
|
+
selectable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
184
|
+
className: require_data_table_module.default.cell,
|
|
185
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
186
|
+
type: "checkbox",
|
|
187
|
+
checked: selected.has(id),
|
|
188
|
+
onChange: () => toggleRow(id),
|
|
189
|
+
className: require_data_table_module.default.checkbox,
|
|
190
|
+
"aria-label": `Select row ${id}`
|
|
191
|
+
})
|
|
192
|
+
}),
|
|
193
|
+
columns.map((col) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
194
|
+
className: require_cx.cx(require_data_table_module.default.cell, col.align && require_data_table_module.default[`align${col.align.charAt(0).toUpperCase() + col.align.slice(1)}`]),
|
|
195
|
+
children: col.accessor ? col.accessor(row) : String(row[col.key] ?? "")
|
|
196
|
+
}, `${id}-${col.key}`)),
|
|
197
|
+
onRowAction && onRowAction.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
198
|
+
className: require_data_table_module.default.cell,
|
|
199
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
200
|
+
className: require_data_table_module.default.rowActions,
|
|
201
|
+
children: onRowAction.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
202
|
+
type: "button",
|
|
203
|
+
className: require_data_table_module.default.actionBtn,
|
|
204
|
+
onClick: () => action.onClick(row),
|
|
205
|
+
children: action.label
|
|
206
|
+
}, action.label))
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
]
|
|
210
|
+
}, id);
|
|
211
|
+
})
|
|
212
|
+
})]
|
|
213
|
+
})
|
|
214
|
+
}), data.length > pageSize && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
215
|
+
className: require_data_table_module.default.pagination,
|
|
216
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
217
|
+
className: require_data_table_module.default.paginationInfo,
|
|
218
|
+
children: [
|
|
219
|
+
"Page ",
|
|
220
|
+
safePage,
|
|
221
|
+
" of ",
|
|
222
|
+
totalPages
|
|
223
|
+
]
|
|
224
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
225
|
+
className: require_data_table_module.default.paginationButtons,
|
|
226
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
227
|
+
type: "button",
|
|
228
|
+
className: require_data_table_module.default.pageBtn,
|
|
229
|
+
disabled: safePage <= 1,
|
|
230
|
+
onClick: () => setPage((p) => Math.max(1, p - 1)),
|
|
231
|
+
"aria-label": "Previous page",
|
|
232
|
+
children: "←"
|
|
233
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
234
|
+
type: "button",
|
|
235
|
+
className: require_data_table_module.default.pageBtn,
|
|
236
|
+
disabled: safePage >= totalPages,
|
|
237
|
+
onClick: () => setPage((p) => Math.min(totalPages, p + 1)),
|
|
238
|
+
"aria-label": "Next page",
|
|
239
|
+
children: "→"
|
|
240
|
+
})]
|
|
241
|
+
})]
|
|
242
|
+
})]
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
//#endregion
|
|
246
|
+
exports.DataTable = DataTable;
|
|
247
|
+
|
|
248
|
+
//# sourceMappingURL=index65.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index65.cjs","names":[],"sources":["../src/components/data-table/DataTable.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./data-table.module.css\";\n\nexport type SortDirection = \"asc\" | \"desc\";\n\nexport interface Column<T = Record<string, unknown>> {\n key: string;\n label: React.ReactNode;\n accessor?: (row: T) => React.ReactNode;\n sortable?: boolean;\n width?: string;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport type DataTableRowAction = {\n label: string;\n onClick: (row: Record<string, unknown>) => void;\n};\n\nexport interface DataTableProps<T = Record<string, unknown>> {\n data: T[];\n columns: readonly Column<T>[];\n /** Array of action buttons to render per row */\n onRowAction?: DataTableRowAction[];\n /** Called when rows are selected; receives selected row IDs */\n onSelectionChange?: (selectedIds: string[]) => void;\n /** Whether the table is in a loading state */\n loading?: boolean;\n /** Message displayed when data is empty */\n emptyMessage?: string;\n /** Number of rows per page */\n pageSize?: number;\n /** Whether rows are selectable via checkbox */\n selectable?: boolean;\n /** Custom row key extractor (defaults to row.id) */\n rowKey?: (row: T) => string;\n /** Additional class name for the table wrapper */\n className?: string;\n}\n\nexport function DataTable<T extends Record<string, unknown> = Record<string, unknown>>({\n data,\n columns,\n onRowAction,\n onSelectionChange,\n loading = false,\n emptyMessage = \"No data found\",\n pageSize = 10,\n selectable = false,\n rowKey = (row: T) => String(row.id ?? \"\"),\n className,\n}: DataTableProps<T>) {\n const [sortKey, setSortKey] = React.useState<string | null>(null);\n const [sortDir, setSortDir] = React.useState<SortDirection>(\"asc\");\n const [page, setPage] = React.useState(1);\n const [selected, setSelected] = React.useState<Set<string>>(new Set());\n\n const handleSort = (key: string) => {\n if (key === sortKey) {\n setSortDir((d) => (d === \"asc\" ? \"desc\" : \"asc\"));\n } else {\n setSortKey(key);\n setSortDir(\"asc\");\n }\n };\n\n const toggleRow = (id: string) => {\n const next = new Set(selected);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n setSelected(next);\n onSelectionChange?.(Array.from(next));\n };\n\n const toggleAll = () => {\n const allKeys = displayedData.map((r) => rowKey(r));\n const allSelected = allKeys.every((k) => selected.has(k));\n const next = new Set(selected);\n if (allSelected) {\n allKeys.forEach((k) => next.delete(k));\n } else {\n allKeys.forEach((k) => next.add(k));\n }\n setSelected(next);\n onSelectionChange?.(Array.from(next));\n };\n\n const totalPages = Math.max(1, Math.ceil(data.length / pageSize));\n const safePage = Math.min(page, totalPages);\n const columnSpan =\n columns.length + (selectable ? 1 : 0) + (onRowAction && onRowAction.length > 0 ? 1 : 0);\n\n React.useEffect(() => {\n if (page > totalPages) {\n setPage(totalPages);\n }\n }, [data.length, page, totalPages]);\n\n const sortedData = React.useMemo(() => {\n if (!sortKey) return data;\n\n const sortColumn = columns.find((column) => column.key === sortKey);\n const getSortValue = (row: T): unknown => {\n if (sortColumn?.accessor) {\n const accessed = sortColumn.accessor(row);\n if (typeof accessed === \"string\" || typeof accessed === \"number\") {\n return accessed;\n }\n }\n return row[sortKey as keyof T];\n };\n\n return [...data].sort((a, b) => {\n const aVal = getSortValue(a);\n const bVal = getSortValue(b);\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n let cmp = 0;\n if (typeof aVal === \"number\" && typeof bVal === \"number\") {\n cmp = aVal - bVal;\n } else {\n cmp = String(aVal).localeCompare(String(bVal));\n }\n return sortDir === \"asc\" ? cmp : -cmp;\n });\n }, [columns, data, sortKey, sortDir]);\n\n const displayedData = React.useMemo(() => {\n const start = (safePage - 1) * pageSize;\n return sortedData.slice(start, start + pageSize);\n }, [sortedData, safePage, pageSize]);\n\n const displayedKeys = React.useMemo(() => displayedData.map(rowKey), [displayedData, rowKey]);\n const allPageSelected =\n displayedKeys.length > 0 && displayedKeys.every((k) => selected.has(k));\n const somePageSelected =\n displayedKeys.length > 0 && displayedKeys.some((k) => selected.has(k));\n\n return (\n <div className={cx(styles.wrapper, className)}>\n <div className={styles.tableContainer}>\n <table className={styles.table}>\n <thead className={styles.thead}>\n <tr>\n {selectable && (\n <th className={styles.headerCell} aria-label=\"Select all\">\n <input\n type=\"checkbox\"\n checked={allPageSelected}\n ref={(el) => {\n if (el) el.indeterminate = somePageSelected && !allPageSelected;\n }}\n onChange={toggleAll}\n className={styles.checkbox}\n aria-label=\"Select all rows on this page\"\n />\n </th>\n )}\n {columns.map((col) => {\n const ariaSort = col.sortable\n ? sortKey === col.key\n ? sortDir === \"asc\"\n ? \"ascending\"\n : \"descending\"\n : \"none\"\n : undefined;\n\n return (\n <th\n key={col.key}\n className={cx(\n styles.headerCell,\n col.width && styles.headerCellFixed,\n col.align && styles[`align${col.align.charAt(0).toUpperCase() + col.align.slice(1)}`],\n )}\n style={col.width ? { width: col.width } : undefined}\n aria-sort={ariaSort}\n >\n {col.sortable ? (\n <button\n type=\"button\"\n className={cx(styles.sortableHeader, styles.clickableHeader)}\n onClick={() => handleSort(col.key)}\n >\n <span className={styles.headerLabel}>{col.label}</span>\n <span className={styles.sortIcon} aria-hidden=\"true\">\n {sortKey === col.key ? (\n sortDir === \"asc\" ? (\n \"\\u25B2\"\n ) : (\n \"\\u25BC\"\n )\n ) : (\n \"\\u25B2\\u25BC\"\n )}\n </span>\n </button>\n ) : (\n <span className={styles.headerLabel}>{col.label}</span>\n )}\n </th>\n );\n })}\n {onRowAction && onRowAction.length > 0 && (\n <th className={styles.headerCell} style={{ width: \"5rem\" }}>\n <span className={styles.headerLabel}>Actions</span>\n </th>\n )}\n </tr>\n </thead>\n <tbody className={styles.tbody}>\n {loading ? (\n <tr>\n <td colSpan={columnSpan} className={styles.loadingCell}>\n <div className={styles.loadingRow} aria-busy=\"true\">\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n </div>\n <div className={styles.loadingRow} aria-busy=\"true\">\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n </div>\n <div className={styles.loadingRow} aria-busy=\"true\">\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n <div className={styles.skeletonBar} />\n </div>\n </td>\n </tr>\n ) : data.length === 0 ? (\n <tr>\n <td colSpan={columnSpan} className={styles.emptyCell}>\n {emptyMessage}\n </td>\n </tr>\n ) : (\n displayedData.map((row) => {\n const id = rowKey(row);\n return (\n <tr key={id} className={cx(styles.row, selected.has(id) && styles.rowSelected)}>\n {selectable && (\n <td className={styles.cell}>\n <input\n type=\"checkbox\"\n checked={selected.has(id)}\n onChange={() => toggleRow(id)}\n className={styles.checkbox}\n aria-label={`Select row ${id}`}\n />\n </td>\n )}\n {columns.map((col) => (\n <td\n key={`${id}-${col.key}`}\n className={cx(\n styles.cell,\n col.align && styles[`align${col.align.charAt(0).toUpperCase() + col.align.slice(1)}`],\n )}\n >\n {col.accessor ? col.accessor(row) : String(row[col.key as keyof T] ?? \"\")}\n </td>\n ))}\n {onRowAction && onRowAction.length > 0 && (\n <td className={styles.cell}>\n <div className={styles.rowActions}>\n {onRowAction.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n className={styles.actionBtn}\n onClick={() => action.onClick(row)}\n >\n {action.label}\n </button>\n ))}\n </div>\n </td>\n )}\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {data.length > pageSize && (\n <div className={styles.pagination}>\n <span className={styles.paginationInfo}>\n Page {safePage} of {totalPages}\n </span>\n <div className={styles.paginationButtons}>\n <button\n type=\"button\"\n className={styles.pageBtn}\n disabled={safePage <= 1}\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n aria-label=\"Previous page\"\n >\n ←\n </button>\n <button\n type=\"button\"\n className={styles.pageBtn}\n disabled={safePage >= totalPages}\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\n aria-label=\"Next page\"\n >\n →\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
package/dist/index65.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//#region src/components/settings-page/settings-page.module.css
|
|
2
|
+
var wrapper = "uzi-settings-page-module__wrapper__G7OOt";
|
|
3
|
+
var header = "uzi-settings-page-module__header__ao-nv";
|
|
4
|
+
var headerContent = "uzi-settings-page-module__headerContent__xwP9V";
|
|
5
|
+
var title = "uzi-settings-page-module__title__anF9l";
|
|
6
|
+
var description = "uzi-settings-page-module__description__Qw6EQ";
|
|
7
|
+
var content = "uzi-settings-page-module__content__MBz6q";
|
|
8
|
+
var sections = "uzi-settings-page-module__sections__HV2n4";
|
|
9
|
+
var section = "uzi-settings-page-module__section__Vjoe3";
|
|
10
|
+
var sectionHeader = "uzi-settings-page-module__sectionHeader__XiOWN";
|
|
11
|
+
var sectionTitle = "uzi-settings-page-module__sectionTitle__bN5lO";
|
|
12
|
+
var sectionDescription = "uzi-settings-page-module__sectionDescription__3wjhy";
|
|
13
|
+
var sectionBody = "uzi-settings-page-module__sectionBody__zraHK";
|
|
14
|
+
var dangerZone = "uzi-settings-page-module__dangerZone__GD8XX";
|
|
15
|
+
var dangerZoneHeader = "uzi-settings-page-module__dangerZoneHeader__2d3R1";
|
|
16
|
+
var dangerZoneTitle = "uzi-settings-page-module__dangerZoneTitle__ljU2k";
|
|
17
|
+
var dangerZoneDescription = "uzi-settings-page-module__dangerZoneDescription__Z3Ohe";
|
|
18
|
+
var dangerZoneBody = "uzi-settings-page-module__dangerZoneBody__zAQbu";
|
|
19
|
+
var footer = "uzi-settings-page-module__footer__dO4Xo";
|
|
20
|
+
var footerContent = "uzi-settings-page-module__footerContent__pPOdb";
|
|
21
|
+
var savingIndicator = "uzi-settings-page-module__savingIndicator__ujaC5";
|
|
22
|
+
var settings_page_module_default = {
|
|
23
|
+
wrapper,
|
|
24
|
+
header,
|
|
25
|
+
headerContent,
|
|
26
|
+
title,
|
|
27
|
+
description,
|
|
28
|
+
content,
|
|
29
|
+
sections,
|
|
30
|
+
section,
|
|
31
|
+
sectionHeader,
|
|
32
|
+
sectionTitle,
|
|
33
|
+
sectionDescription,
|
|
34
|
+
sectionBody,
|
|
35
|
+
dangerZone,
|
|
36
|
+
dangerZoneHeader,
|
|
37
|
+
dangerZoneTitle,
|
|
38
|
+
dangerZoneDescription,
|
|
39
|
+
dangerZoneBody,
|
|
40
|
+
footer,
|
|
41
|
+
footerContent,
|
|
42
|
+
savingIndicator
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
export { content, dangerZone, dangerZoneBody, dangerZoneDescription, dangerZoneHeader, dangerZoneTitle, settings_page_module_default as default, description, footer, footerContent, header, headerContent, savingIndicator, section, sectionBody, sectionDescription, sectionHeader, sectionTitle, sections, title, wrapper };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=index65.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index65.js","names":[],"sources":["../src/components/settings-page/settings-page.module.css"],"sourcesContent":[".wrapper {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n background: var(--background);\n color: var(--foreground);\n}\n\n.header {\n padding: 2rem 2rem 0;\n flex-shrink: 0;\n}\n\n.headerContent {\n max-width: 64rem;\n margin: 0 auto;\n}\n\n.title {\n margin: 0 0 0.25rem;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--foreground);\n line-height: 1.3;\n}\n\n.description {\n margin: 0;\n font-size: 0.9rem;\n color: var(--muted-foreground);\n line-height: 1.5;\n}\n\n.content {\n flex: 1;\n padding: 1.5rem 2rem 6rem;\n max-width: 64rem;\n margin: 0 auto;\n width: 100%;\n overflow-y: auto;\n}\n\n.sections {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n}\n\n.section {\n border-bottom: 1px solid var(--border);\n padding-bottom: 1.5rem;\n}\n\n.section:last-of-type {\n border-bottom: none;\n}\n\n.sectionHeader {\n margin-bottom: 1.25rem;\n}\n\n.sectionTitle {\n margin: 0 0 0.25rem;\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--foreground);\n}\n\n.sectionDescription {\n margin: 0;\n font-size: 0.85rem;\n color: var(--muted-foreground);\n line-height: 1.5;\n}\n\n.sectionBody {\n display: flex;\n flex-direction: column;\n gap: 1.25rem;\n}\n\n.dangerZone {\n margin-top: 2rem;\n border: 1px solid var(--ts-danger-border, var(--destructive));\n border-radius: 8px;\n background: var(--ts-danger-bg, color-mix(in srgb, var(--destructive) 8%, transparent));\n padding: 1.5rem;\n}\n\n.dangerZoneHeader {\n margin-bottom: 1rem;\n}\n\n.dangerZoneTitle {\n margin: 0 0 0.25rem;\n font-size: 1rem;\n font-weight: 600;\n color: var(--ts-danger-text, var(--destructive));\n}\n\n.dangerZoneDescription {\n margin: 0;\n font-size: 0.85rem;\n color: var(--muted-foreground);\n line-height: 1.5;\n}\n\n.dangerZoneBody {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.footer {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n border-top: 1px solid var(--border);\n background: var(--background);\n z-index: 10;\n padding: 0.75rem 2rem;\n}\n\n.footerContent {\n max-width: 64rem;\n margin: 0 auto;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n}\n\n.savingIndicator {\n font-size: 0.85rem;\n color: var(--muted-foreground);\n}\n\n@media (max-width: 48rem) {\n .header {\n padding: 1.5rem 1rem 0;\n }\n\n .content {\n padding: 1rem 1rem 6rem;\n }\n\n .footer {\n padding: 0.75rem 1rem;\n }\n\n .footerContent {\n flex-direction: column;\n align-items: stretch;\n gap: 0.5rem;\n }\n}\n"],"mappings":""}
|