@tomny-dev/uzi 0.6.3 → 0.7.0-pr.78.214.1.87d1ede

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.
Files changed (118) hide show
  1. package/dist/components/conversation/Conversation.d.ts +18 -0
  2. package/dist/components/conversation/Conversation.d.ts.map +1 -0
  3. package/dist/components/conversation/Conversation.test.d.ts +2 -0
  4. package/dist/components/conversation/Conversation.test.d.ts.map +1 -0
  5. package/dist/components/multi-select/MultiSelect.d.ts +9 -0
  6. package/dist/components/multi-select/MultiSelect.d.ts.map +1 -1
  7. package/dist/components/multi-select/MultiSelect.test.d.ts +2 -0
  8. package/dist/components/multi-select/MultiSelect.test.d.ts.map +1 -0
  9. package/dist/index.cjs +19 -11
  10. package/dist/index.d.ts +2 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +13 -12
  13. package/dist/index26.js +10 -2
  14. package/dist/index26.js.map +1 -1
  15. package/dist/index27.cjs +13 -1
  16. package/dist/index27.cjs.map +1 -1
  17. package/dist/index27.js +74 -37
  18. package/dist/index27.js.map +1 -1
  19. package/dist/index28.cjs +74 -37
  20. package/dist/index28.cjs.map +1 -1
  21. package/dist/index53.js +26 -16
  22. package/dist/index53.js.map +1 -1
  23. package/dist/index54.cjs +37 -20
  24. package/dist/index54.cjs.map +1 -1
  25. package/dist/index54.js +57 -23
  26. package/dist/index54.js.map +1 -1
  27. package/dist/index55.cjs +63 -24
  28. package/dist/index55.cjs.map +1 -1
  29. package/dist/index55.js +16 -16
  30. package/dist/index55.js.map +1 -1
  31. package/dist/index56.cjs +19 -20
  32. package/dist/index56.cjs.map +1 -1
  33. package/dist/index56.js +24 -21
  34. package/dist/index56.js.map +1 -1
  35. package/dist/index57.cjs +25 -22
  36. package/dist/index57.cjs.map +1 -1
  37. package/dist/index57.js +17 -10
  38. package/dist/index57.js.map +1 -1
  39. package/dist/index58.cjs +23 -11
  40. package/dist/index58.cjs.map +1 -1
  41. package/dist/index58.js +25 -14
  42. package/dist/index58.js.map +1 -1
  43. package/dist/index59.cjs +25 -13
  44. package/dist/index59.cjs.map +1 -1
  45. package/dist/index59.js +10 -11
  46. package/dist/index59.js.map +1 -1
  47. package/dist/index60.cjs +11 -13
  48. package/dist/index60.cjs.map +1 -1
  49. package/dist/index60.js +13 -16
  50. package/dist/index60.js.map +1 -1
  51. package/dist/index61.cjs +13 -16
  52. package/dist/index61.cjs.map +1 -1
  53. package/dist/index61.js +10 -8
  54. package/dist/index61.js.map +1 -1
  55. package/dist/index62.cjs +11 -10
  56. package/dist/index62.cjs.map +1 -1
  57. package/dist/index62.js +15 -87
  58. package/dist/index62.js.map +1 -1
  59. package/dist/index63.cjs +15 -89
  60. package/dist/index63.cjs.map +1 -1
  61. package/dist/index63.js +9 -21
  62. package/dist/index63.js.map +1 -1
  63. package/dist/index64.cjs +12 -30
  64. package/dist/index64.cjs.map +1 -1
  65. package/dist/index64.js +89 -43
  66. package/dist/index64.js.map +1 -1
  67. package/dist/index65.cjs +88 -42
  68. package/dist/index65.cjs.map +1 -1
  69. package/dist/index65.js +14 -50
  70. package/dist/index65.js.map +1 -1
  71. package/dist/index66.cjs +15 -69
  72. package/dist/index66.cjs.map +1 -1
  73. package/dist/index66.js +25 -414
  74. package/dist/index66.js.map +1 -1
  75. package/dist/index67.cjs +25 -416
  76. package/dist/index67.cjs.map +1 -1
  77. package/dist/index67.js +56 -58
  78. package/dist/index67.js.map +1 -1
  79. package/dist/index68.cjs +82 -85
  80. package/dist/index68.cjs.map +1 -1
  81. package/dist/index68.js +419 -226
  82. package/dist/index68.js.map +1 -1
  83. package/dist/index69.cjs +420 -225
  84. package/dist/index69.cjs.map +1 -1
  85. package/dist/index69.js +58 -42
  86. package/dist/index69.js.map +1 -1
  87. package/dist/index70.cjs +85 -61
  88. package/dist/index70.cjs.map +1 -1
  89. package/dist/index70.js +236 -76
  90. package/dist/index70.js.map +1 -1
  91. package/dist/index71.cjs +235 -75
  92. package/dist/index71.cjs.map +1 -1
  93. package/dist/index71.js +42 -20
  94. package/dist/index71.js.map +1 -1
  95. package/dist/index72.cjs +60 -27
  96. package/dist/index72.cjs.map +1 -1
  97. package/dist/index72.js +73 -88
  98. package/dist/index72.js.map +1 -1
  99. package/dist/index73.cjs +73 -90
  100. package/dist/index73.cjs.map +1 -1
  101. package/dist/index73.js +17 -15
  102. package/dist/index73.js.map +1 -1
  103. package/dist/index74.cjs +22 -19
  104. package/dist/index74.cjs.map +1 -1
  105. package/dist/index74.js +85 -143
  106. package/dist/index74.js.map +1 -1
  107. package/dist/index75.cjs +87 -143
  108. package/dist/index75.cjs.map +1 -1
  109. package/dist/index75.js +23 -0
  110. package/dist/index75.js.map +1 -0
  111. package/dist/index76.cjs +31 -0
  112. package/dist/index76.cjs.map +1 -0
  113. package/dist/index76.js +159 -0
  114. package/dist/index76.js.map +1 -0
  115. package/dist/index77.cjs +161 -0
  116. package/dist/index77.cjs.map +1 -0
  117. package/dist/style.css +150 -0
  118. package/package.json +1 -1
package/dist/index70.js CHANGED
@@ -1,86 +1,246 @@
1
+ "use client";
1
2
  import { cx } from "./index3.js";
2
- import settings_page_module_default from "./index69.js";
3
- import "react";
3
+ import data_table_module_default from "./index69.js";
4
+ import * as React from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
- //#region src/components/settings-page/SettingsPage.tsx
6
- /**
7
- * SettingsPage — a settings layout with sections, a danger zone, and a sticky save footer.
8
- *
9
- * Layout:
10
- * Header (title + description)
11
- * Scrollable content:
12
- * Section group with headings and descriptions
13
- * Danger zone with red visual distinction
14
- * Sticky footer: save/cancel buttons
15
- */
16
- function SettingsPage({ title, description, sections, dangerZone, dangerZoneTitle, dangerZoneDescription, footer, saving = false, className }) {
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));
17
82
  return /* @__PURE__ */ jsxs("div", {
18
- className: cx(settings_page_module_default.wrapper, className),
19
- children: [
20
- /* @__PURE__ */ jsx("header", {
21
- className: settings_page_module_default.header,
22
- children: /* @__PURE__ */ jsxs("div", {
23
- className: settings_page_module_default.headerContent,
24
- children: [/* @__PURE__ */ jsx("h1", {
25
- className: settings_page_module_default.title,
26
- children: title
27
- }), description && /* @__PURE__ */ jsx("p", {
28
- className: settings_page_module_default.description,
29
- children: description
30
- })]
31
- })
32
- }),
33
- /* @__PURE__ */ jsxs("div", {
34
- className: settings_page_module_default.content,
35
- children: [/* @__PURE__ */ jsx("div", {
36
- className: settings_page_module_default.sections,
37
- children: sections.map((section, index) => /* @__PURE__ */ jsxs("section", {
38
- className: settings_page_module_default.section,
39
- children: [/* @__PURE__ */ jsxs("div", {
40
- className: settings_page_module_default.sectionHeader,
41
- children: [/* @__PURE__ */ jsx("h2", {
42
- className: settings_page_module_default.sectionTitle,
43
- children: section.title
44
- }), section.description && /* @__PURE__ */ jsx("p", {
45
- className: settings_page_module_default.sectionDescription,
46
- children: section.description
47
- })]
48
- }), /* @__PURE__ */ jsx("div", {
49
- className: settings_page_module_default.sectionBody,
50
- children: section.children
51
- })]
52
- }, index))
53
- }), dangerZone && /* @__PURE__ */ jsxs("div", {
54
- className: settings_page_module_default.dangerZone,
55
- children: [(dangerZoneTitle || dangerZoneDescription) && /* @__PURE__ */ jsxs("div", {
56
- className: settings_page_module_default.dangerZoneHeader,
57
- children: [dangerZoneTitle && /* @__PURE__ */ jsx("h2", {
58
- className: settings_page_module_default.dangerZoneTitle,
59
- children: dangerZoneTitle
60
- }), dangerZoneDescription && /* @__PURE__ */ jsx("p", {
61
- className: settings_page_module_default.dangerZoneDescription,
62
- children: dangerZoneDescription
63
- })]
64
- }), /* @__PURE__ */ jsx("div", {
65
- className: settings_page_module_default.dangerZoneBody,
66
- children: dangerZone
67
- })]
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
+ })
68
210
  })]
69
- }),
70
- /* @__PURE__ */ jsx("footer", {
71
- className: settings_page_module_default.footer,
72
- children: /* @__PURE__ */ jsxs("div", {
73
- className: settings_page_module_default.footerContent,
74
- children: [footer, saving && /* @__PURE__ */ jsx("span", {
75
- className: settings_page_module_default.savingIndicator,
76
- children: "Saving..."
77
- })]
78
- })
79
211
  })
80
- ]
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
+ })]
81
241
  });
82
242
  }
83
243
  //#endregion
84
- export { SettingsPage };
244
+ export { DataTable };
85
245
 
86
246
  //# sourceMappingURL=index70.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index70.js","names":[],"sources":["../src/components/settings-page/SettingsPage.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./settings-page.module.css\";\n\nexport interface SettingsSection {\n title: React.ReactNode;\n description?: React.ReactNode;\n children: React.ReactNode;\n}\n\nexport interface SettingsPageProps {\n /** Page title */\n title: React.ReactNode;\n /** Page subtitle / description */\n description?: React.ReactNode;\n /** Form sections rendered in the main content area */\n sections: SettingsSection[];\n /** Content rendered in the danger zone (red visual distinction) */\n dangerZone?: React.ReactNode;\n /** Danger zone title */\n dangerZoneTitle?: React.ReactNode;\n /** Danger zone description */\n dangerZoneDescription?: React.ReactNode;\n /** Sticky footer content (e.g., Save / Cancel buttons) */\n footer: React.ReactNode;\n /** Whether the page is saving */\n saving?: boolean;\n /** Additional class name for the outer wrapper */\n className?: string;\n}\n\n/**\n * SettingsPage — a settings layout with sections, a danger zone, and a sticky save footer.\n *\n * Layout:\n * Header (title + description)\n * Scrollable content:\n * Section group with headings and descriptions\n * Danger zone with red visual distinction\n * Sticky footer: save/cancel buttons\n */\nexport function SettingsPage({\n title,\n description,\n sections,\n dangerZone,\n dangerZoneTitle,\n dangerZoneDescription,\n footer,\n saving = false,\n className,\n}: SettingsPageProps) {\n return (\n <div className={cx(styles.wrapper, className)}>\n <header className={styles.header}>\n <div className={styles.headerContent}>\n <h1 className={styles.title}>{title}</h1>\n {description && <p className={styles.description}>{description}</p>}\n </div>\n </header>\n\n <div className={styles.content}>\n <div className={styles.sections}>\n {sections.map((section, index) => (\n <section key={index} className={styles.section}>\n <div className={styles.sectionHeader}>\n <h2 className={styles.sectionTitle}>{section.title}</h2>\n {section.description && (\n <p className={styles.sectionDescription}>{section.description}</p>\n )}\n </div>\n <div className={styles.sectionBody}>{section.children}</div>\n </section>\n ))}\n </div>\n\n {dangerZone && (\n <div className={styles.dangerZone}>\n {(dangerZoneTitle || dangerZoneDescription) && (\n <div className={styles.dangerZoneHeader}>\n {dangerZoneTitle && <h2 className={styles.dangerZoneTitle}>{dangerZoneTitle}</h2>}\n {dangerZoneDescription && (\n <p className={styles.dangerZoneDescription}>{dangerZoneDescription}</p>\n )}\n </div>\n )}\n <div className={styles.dangerZoneBody}>{dangerZone}</div>\n </div>\n )}\n </div>\n\n <footer className={styles.footer}>\n <div className={styles.footerContent}>\n {footer}\n {saving && <span className={styles.savingIndicator}>Saving...</span>}\n </div>\n </footer>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAyCA,SAAgB,aAAa,EAC3B,OACA,aACA,UACA,YACA,iBACA,uBACA,QACA,SAAS,OACT,aACoB;CACpB,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,6BAAO,SAAS,SAAS;YAA5C;GACE,oBAAC,UAAD;IAAQ,WAAW,6BAAO;cACxB,qBAAC,OAAD;KAAK,WAAW,6BAAO;eAAvB,CACE,oBAAC,MAAD;MAAI,WAAW,6BAAO;gBAAQ;KAAU,CAAA,GACvC,eAAe,oBAAC,KAAD;MAAG,WAAW,6BAAO;gBAAc;KAAe,CAAA,CAC/D;;GACC,CAAA;GAER,qBAAC,OAAD;IAAK,WAAW,6BAAO;cAAvB,CACE,oBAAC,OAAD;KAAK,WAAW,6BAAO;eACpB,SAAS,KAAK,SAAS,UACtB,qBAAC,WAAD;MAAqB,WAAW,6BAAO;gBAAvC,CACE,qBAAC,OAAD;OAAK,WAAW,6BAAO;iBAAvB,CACE,oBAAC,MAAD;QAAI,WAAW,6BAAO;kBAAe,QAAQ;OAAU,CAAA,GACtD,QAAQ,eACP,oBAAC,KAAD;QAAG,WAAW,6BAAO;kBAAqB,QAAQ;OAAe,CAAA,CAEhE;UACL,oBAAC,OAAD;OAAK,WAAW,6BAAO;iBAAc,QAAQ;MAAc,CAAA,CACpD;QARK,KAQL,CACV;IACE,CAAA,GAEJ,cACC,qBAAC,OAAD;KAAK,WAAW,6BAAO;eAAvB,EACI,mBAAmB,0BACnB,qBAAC,OAAD;MAAK,WAAW,6BAAO;gBAAvB,CACG,mBAAmB,oBAAC,MAAD;OAAI,WAAW,6BAAO;iBAAkB;MAAoB,CAAA,GAC/E,yBACC,oBAAC,KAAD;OAAG,WAAW,6BAAO;iBAAwB;MAAyB,CAAA,CAErE;SAEP,oBAAC,OAAD;MAAK,WAAW,6BAAO;gBAAiB;KAAgB,CAAA,CACrD;MAEJ;;GAEL,oBAAC,UAAD;IAAQ,WAAW,6BAAO;cACxB,qBAAC,OAAD;KAAK,WAAW,6BAAO;eAAvB,CACG,QACA,UAAU,oBAAC,QAAD;MAAM,WAAW,6BAAO;gBAAiB;KAAe,CAAA,CAChE;;GACC,CAAA;EACL;;AAET"}
1
+ {"version":3,"file":"index70.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 &larr;\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 &rarr;\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}