mvc-kit 2.12.4 → 2.13.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/agent-config/bin/postinstall.mjs +4 -3
- package/agent-config/bin/setup.mjs +5 -1
- package/agent-config/claude-code/agents/mvc-kit-architect.md +11 -8
- package/agent-config/claude-code/skills/guide/SKILL.md +20 -7
- package/agent-config/claude-code/skills/guide/patterns.md +12 -0
- package/agent-config/claude-code/skills/guide/recipes.md +510 -0
- package/agent-config/claude-code/skills/guide/testing.md +297 -0
- package/agent-config/claude-code/skills/review/SKILL.md +3 -13
- package/agent-config/claude-code/skills/review/checklist.md +30 -5
- package/agent-config/claude-code/skills/scaffold/SKILL.md +4 -13
- package/agent-config/lib/install-claude.mjs +84 -25
- package/dist/Channel.cjs +276 -300
- package/dist/Channel.cjs.map +1 -1
- package/dist/Channel.js +275 -299
- package/dist/Channel.js.map +1 -1
- package/dist/Collection.cjs +424 -504
- package/dist/Collection.cjs.map +1 -1
- package/dist/Collection.js +423 -503
- package/dist/Collection.js.map +1 -1
- package/dist/Controller.cjs +70 -67
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.js +69 -66
- package/dist/Controller.js.map +1 -1
- package/dist/EventBus.cjs +77 -88
- package/dist/EventBus.cjs.map +1 -1
- package/dist/EventBus.js +76 -87
- package/dist/EventBus.js.map +1 -1
- package/dist/Feed.cjs +81 -77
- package/dist/Feed.cjs.map +1 -1
- package/dist/Feed.js +80 -76
- package/dist/Feed.js.map +1 -1
- package/dist/Model.cjs +181 -207
- package/dist/Model.cjs.map +1 -1
- package/dist/Model.js +179 -205
- package/dist/Model.js.map +1 -1
- package/dist/Pagination.cjs +75 -73
- package/dist/Pagination.cjs.map +1 -1
- package/dist/Pagination.js +74 -72
- package/dist/Pagination.js.map +1 -1
- package/dist/Pending.cjs +255 -287
- package/dist/Pending.cjs.map +1 -1
- package/dist/Pending.js +253 -285
- package/dist/Pending.js.map +1 -1
- package/dist/PersistentCollection.cjs +242 -285
- package/dist/PersistentCollection.cjs.map +1 -1
- package/dist/PersistentCollection.js +241 -284
- package/dist/PersistentCollection.js.map +1 -1
- package/dist/Resource.cjs +166 -174
- package/dist/Resource.cjs.map +1 -1
- package/dist/Resource.js +164 -172
- package/dist/Resource.js.map +1 -1
- package/dist/Selection.cjs +84 -94
- package/dist/Selection.cjs.map +1 -1
- package/dist/Selection.js +83 -93
- package/dist/Selection.js.map +1 -1
- package/dist/Service.cjs +54 -55
- package/dist/Service.cjs.map +1 -1
- package/dist/Service.js +53 -54
- package/dist/Service.js.map +1 -1
- package/dist/Sorting.cjs +102 -101
- package/dist/Sorting.cjs.map +1 -1
- package/dist/Sorting.js +102 -101
- package/dist/Sorting.js.map +1 -1
- package/dist/Trackable.cjs +112 -80
- package/dist/Trackable.cjs.map +1 -1
- package/dist/Trackable.js +111 -79
- package/dist/Trackable.js.map +1 -1
- package/dist/ViewModel.cjs +528 -576
- package/dist/ViewModel.cjs.map +1 -1
- package/dist/ViewModel.js +525 -573
- package/dist/ViewModel.js.map +1 -1
- package/dist/bindPublicMethods.cjs +43 -24
- package/dist/bindPublicMethods.cjs.map +1 -1
- package/dist/bindPublicMethods.js +43 -24
- package/dist/bindPublicMethods.js.map +1 -1
- package/dist/errors.cjs +67 -68
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js +68 -71
- package/dist/errors.js.map +1 -1
- package/dist/mvc-kit.cjs +44 -46
- package/dist/mvc-kit.js +5 -32
- package/dist/produceDraft.cjs +105 -95
- package/dist/produceDraft.cjs.map +1 -1
- package/dist/produceDraft.js +106 -97
- package/dist/produceDraft.js.map +1 -1
- package/dist/react/components/CardList.cjs +30 -40
- package/dist/react/components/CardList.cjs.map +1 -1
- package/dist/react/components/CardList.js +31 -41
- package/dist/react/components/CardList.js.map +1 -1
- package/dist/react/components/DataTable.cjs +146 -169
- package/dist/react/components/DataTable.cjs.map +1 -1
- package/dist/react/components/DataTable.js +147 -170
- package/dist/react/components/DataTable.js.map +1 -1
- package/dist/react/components/InfiniteScroll.cjs +51 -42
- package/dist/react/components/InfiniteScroll.cjs.map +1 -1
- package/dist/react/components/InfiniteScroll.js +52 -43
- package/dist/react/components/InfiniteScroll.js.map +1 -1
- package/dist/react/components/types.cjs +10 -6
- package/dist/react/components/types.cjs.map +1 -1
- package/dist/react/components/types.js +11 -9
- package/dist/react/components/types.js.map +1 -1
- package/dist/react/guards.cjs +10 -6
- package/dist/react/guards.cjs.map +1 -1
- package/dist/react/guards.js +11 -9
- package/dist/react/guards.js.map +1 -1
- package/dist/react/provider.cjs +23 -20
- package/dist/react/provider.cjs.map +1 -1
- package/dist/react/provider.js +23 -21
- package/dist/react/provider.js.map +1 -1
- package/dist/react/use-event-bus.cjs +24 -20
- package/dist/react/use-event-bus.cjs.map +1 -1
- package/dist/react/use-event-bus.js +24 -21
- package/dist/react/use-event-bus.js.map +1 -1
- package/dist/react/use-instance.cjs +43 -36
- package/dist/react/use-instance.cjs.map +1 -1
- package/dist/react/use-instance.js +43 -36
- package/dist/react/use-instance.js.map +1 -1
- package/dist/react/use-local.cjs +48 -64
- package/dist/react/use-local.cjs.map +1 -1
- package/dist/react/use-local.js +47 -63
- package/dist/react/use-local.js.map +1 -1
- package/dist/react/use-model.cjs +84 -98
- package/dist/react/use-model.cjs.map +1 -1
- package/dist/react/use-model.js +84 -100
- package/dist/react/use-model.js.map +1 -1
- package/dist/react/use-singleton.cjs +19 -23
- package/dist/react/use-singleton.cjs.map +1 -1
- package/dist/react/use-singleton.js +16 -20
- package/dist/react/use-singleton.js.map +1 -1
- package/dist/react/use-subscribe-only.cjs +28 -22
- package/dist/react/use-subscribe-only.cjs.map +1 -1
- package/dist/react/use-subscribe-only.js +28 -22
- package/dist/react/use-subscribe-only.js.map +1 -1
- package/dist/react/use-teardown.cjs +20 -19
- package/dist/react/use-teardown.cjs.map +1 -1
- package/dist/react/use-teardown.js +20 -19
- package/dist/react/use-teardown.js.map +1 -1
- package/dist/react-native/NativeCollection.cjs +98 -78
- package/dist/react-native/NativeCollection.cjs.map +1 -1
- package/dist/react-native/NativeCollection.js +97 -77
- package/dist/react-native/NativeCollection.js.map +1 -1
- package/dist/react-native.cjs +2 -4
- package/dist/react-native.js +1 -4
- package/dist/react.cjs +24 -26
- package/dist/react.js +1 -17
- package/dist/singleton.cjs +28 -22
- package/dist/singleton.cjs.map +1 -1
- package/dist/singleton.js +29 -26
- package/dist/singleton.js.map +1 -1
- package/dist/walkPrototypeChain.cjs +20 -12
- package/dist/walkPrototypeChain.cjs.map +1 -1
- package/dist/walkPrototypeChain.js +21 -13
- package/dist/walkPrototypeChain.js.map +1 -1
- package/dist/web/IndexedDBCollection.cjs +53 -36
- package/dist/web/IndexedDBCollection.cjs.map +1 -1
- package/dist/web/IndexedDBCollection.js +52 -35
- package/dist/web/IndexedDBCollection.js.map +1 -1
- package/dist/web/WebStorageCollection.cjs +82 -84
- package/dist/web/WebStorageCollection.cjs.map +1 -1
- package/dist/web/WebStorageCollection.js +81 -83
- package/dist/web/WebStorageCollection.js.map +1 -1
- package/dist/web/idb.cjs +107 -99
- package/dist/web/idb.cjs.map +1 -1
- package/dist/web/idb.js +108 -105
- package/dist/web/idb.js.map +1 -1
- package/dist/web.cjs +4 -6
- package/dist/web.js +1 -5
- package/dist/wrapAsyncMethods.cjs +141 -168
- package/dist/wrapAsyncMethods.cjs.map +1 -1
- package/dist/wrapAsyncMethods.js +141 -168
- package/dist/wrapAsyncMethods.js.map +1 -1
- package/package.json +8 -8
- package/src/Pending.test.ts +1 -2
- package/src/Sorting.test.ts +1 -1
- package/src/produceDraft.test.ts +3 -3
- package/src/react/components/CardList.test.tsx +1 -1
- package/src/react/components/DataTable.test.tsx +1 -1
- package/src/react/components/InfiniteScroll.test.tsx +5 -5
- package/dist/mvc-kit.cjs.map +0 -1
- package/dist/mvc-kit.js.map +0 -1
- package/dist/react-native.cjs.map +0 -1
- package/dist/react-native.js.map +0 -1
- package/dist/react.cjs.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/web.cjs.map +0 -1
- package/dist/web.js.map +0 -1
|
@@ -1,179 +1,156 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const types = require("./types.cjs");
|
|
1
|
+
const require_types = require("./types.cjs");
|
|
2
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
|
+
//#region src/react/components/DataTable.tsx
|
|
5
4
|
function resolveSelectionProp(selection) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
onToggleAll: (allKeys) => selection.onToggleAll(allKeys)
|
|
17
|
-
};
|
|
5
|
+
if (require_types.isSelectionHelper(selection)) return {
|
|
6
|
+
selected: selection.selected,
|
|
7
|
+
onToggle: (key) => selection.toggle(key),
|
|
8
|
+
onToggleAll: (allKeys) => selection.toggleAll(allKeys)
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
selected: selection.selected,
|
|
12
|
+
onToggle: selection.onToggle,
|
|
13
|
+
onToggleAll: (allKeys) => selection.onToggleAll(allKeys)
|
|
14
|
+
};
|
|
18
15
|
}
|
|
19
16
|
function resolveSortProp(sort, onSort) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
if (require_types.isSortingHelper(sort)) return {
|
|
18
|
+
sorts: sort.sorts,
|
|
19
|
+
onSort: (key) => sort.toggle(key)
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
sorts: sort,
|
|
23
|
+
onSort
|
|
24
|
+
};
|
|
24
25
|
}
|
|
25
26
|
function resolvePaginationProp(pagination, pageSize, paginationTotal) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
27
|
+
if (require_types.isPaginationHelper(pagination)) {
|
|
28
|
+
const total = paginationTotal ?? 0;
|
|
29
|
+
const ps = pagination.pageSize;
|
|
30
|
+
const pageCount = Math.max(1, Math.ceil(total / ps));
|
|
31
|
+
const page = pagination.page;
|
|
32
|
+
return {
|
|
33
|
+
page,
|
|
34
|
+
pageCount,
|
|
35
|
+
total,
|
|
36
|
+
pageSize: ps,
|
|
37
|
+
hasPrev: page > 1,
|
|
38
|
+
hasNext: page < pageCount,
|
|
39
|
+
goToPage: (p) => pagination.setPage(p),
|
|
40
|
+
goPrev: () => pagination.setPage(page - 1),
|
|
41
|
+
goNext: () => pagination.setPage(page + 1)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const total = pagination.total;
|
|
45
|
+
const ps = pageSize ?? 10;
|
|
46
|
+
const pageCount = Math.max(1, Math.ceil(total / ps));
|
|
47
|
+
const page = pagination.page;
|
|
48
|
+
return {
|
|
49
|
+
page,
|
|
50
|
+
pageCount,
|
|
51
|
+
total,
|
|
52
|
+
pageSize: ps,
|
|
53
|
+
hasPrev: page > 1,
|
|
54
|
+
hasNext: page < pageCount,
|
|
55
|
+
goToPage: pagination.onPageChange,
|
|
56
|
+
goPrev: () => pagination.onPageChange(page - 1),
|
|
57
|
+
goNext: () => pagination.onPageChange(page + 1)
|
|
58
|
+
};
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
var defaultKeyOf = (item) => item.id;
|
|
60
61
|
function getAriaSortValue(key, sorts) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
if (!sorts) return "none";
|
|
63
|
+
const desc = sorts.find((s) => s.key === key);
|
|
64
|
+
if (!desc) return "none";
|
|
65
|
+
return desc.direction === "asc" ? "ascending" : "descending";
|
|
65
66
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const key = keyOf(item);
|
|
152
|
-
const isSelected = resolvedSelection?.selected.has(key);
|
|
153
|
-
const cells = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
154
|
-
resolvedSelection && /* @__PURE__ */ jsxRuntime.jsx("td", { "data-column": "select", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
155
|
-
"input",
|
|
156
|
-
{
|
|
157
|
-
type: "checkbox",
|
|
158
|
-
checked: !!isSelected,
|
|
159
|
-
onChange: () => resolvedSelection.onToggle(key),
|
|
160
|
-
"aria-label": `Select row ${key}`
|
|
161
|
-
}
|
|
162
|
-
) }),
|
|
163
|
-
columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
164
|
-
"td",
|
|
165
|
-
{
|
|
166
|
-
"data-align": col.align,
|
|
167
|
-
children: col.render(item, index)
|
|
168
|
-
},
|
|
169
|
-
col.key
|
|
170
|
-
))
|
|
171
|
-
] });
|
|
172
|
-
return /* @__PURE__ */ jsxRuntime.jsx("tr", { "data-selected": isSelected ? "" : void 0, children: renderRow ? renderRow(item, index, cells) : cells }, key);
|
|
173
|
-
}) })
|
|
174
|
-
] }),
|
|
175
|
-
paginationInfo && renderPagination?.(paginationInfo)
|
|
176
|
-
] });
|
|
67
|
+
/**
|
|
68
|
+
* Headless data table with sort headers, selection checkboxes, and pagination slots.
|
|
69
|
+
* Renders semantic HTML (`<table>`) with data attributes for styling.
|
|
70
|
+
* Accepts Sorting/Selection/Pagination helpers directly via duck-typing.
|
|
71
|
+
*/
|
|
72
|
+
function DataTable({ items, columns, keyOf = defaultKeyOf, pageSize, sort, onSort, selection, loading, error, pagination, paginationTotal, renderEmpty, renderLoading, renderError, renderSortIndicator, renderRow, renderPagination, className, "aria-label": ariaLabel }) {
|
|
73
|
+
if (loading && renderLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: renderLoading() });
|
|
74
|
+
if (error && renderError) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: renderError(error) });
|
|
75
|
+
if (items.length === 0 && renderEmpty) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: renderEmpty() });
|
|
76
|
+
const resolvedSelection = selection ? resolveSelectionProp(selection) : void 0;
|
|
77
|
+
let resolvedSorts;
|
|
78
|
+
let resolvedOnSort;
|
|
79
|
+
if (sort) {
|
|
80
|
+
const resolved = resolveSortProp(sort, onSort);
|
|
81
|
+
resolvedSorts = resolved.sorts;
|
|
82
|
+
resolvedOnSort = resolved.onSort;
|
|
83
|
+
}
|
|
84
|
+
let displayItems = items;
|
|
85
|
+
let paginationInfo;
|
|
86
|
+
if (pagination) paginationInfo = resolvePaginationProp(pagination, pageSize, paginationTotal);
|
|
87
|
+
else if (pageSize && !pagination) displayItems = items.slice(0, pageSize);
|
|
88
|
+
const allKeys = resolvedSelection ? displayItems.map((item) => keyOf(item)) : [];
|
|
89
|
+
const allSelected = resolvedSelection && allKeys.length > 0 && allKeys.every((k) => resolvedSelection.selected.has(k));
|
|
90
|
+
const someSelected = resolvedSelection && allKeys.some((k) => resolvedSelection.selected.has(k));
|
|
91
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
92
|
+
"data-component": "data-table",
|
|
93
|
+
className,
|
|
94
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
|
|
95
|
+
role: "grid",
|
|
96
|
+
"aria-label": ariaLabel,
|
|
97
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [resolvedSelection && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
98
|
+
"data-column": "select",
|
|
99
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
100
|
+
type: "checkbox",
|
|
101
|
+
checked: !!allSelected,
|
|
102
|
+
ref: (el) => {
|
|
103
|
+
if (el) el.indeterminate = !!someSelected && !allSelected;
|
|
104
|
+
},
|
|
105
|
+
onChange: () => resolvedSelection.onToggleAll(allKeys),
|
|
106
|
+
"aria-label": "Select all"
|
|
107
|
+
})
|
|
108
|
+
}), columns.map((col) => {
|
|
109
|
+
const isSortable = col.sortable && resolvedOnSort;
|
|
110
|
+
const sortDesc = resolvedSorts?.find((s) => s.key === col.key);
|
|
111
|
+
const isActive = !!sortDesc;
|
|
112
|
+
const sortIndex = resolvedSorts ? resolvedSorts.findIndex((s) => s.key === col.key) : -1;
|
|
113
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
114
|
+
"data-sortable": isSortable ? "" : void 0,
|
|
115
|
+
"data-sorted": isActive ? "" : void 0,
|
|
116
|
+
"data-align": col.align,
|
|
117
|
+
style: col.width ? { width: col.width } : void 0,
|
|
118
|
+
"aria-sort": isSortable ? getAriaSortValue(col.key, resolvedSorts) : void 0,
|
|
119
|
+
children: isSortable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
120
|
+
type: "button",
|
|
121
|
+
onClick: () => resolvedOnSort(col.key),
|
|
122
|
+
children: [col.header, renderSortIndicator?.({
|
|
123
|
+
active: isActive,
|
|
124
|
+
direction: sortDesc?.direction ?? "asc",
|
|
125
|
+
index: sortIndex,
|
|
126
|
+
onToggle: () => resolvedOnSort(col.key)
|
|
127
|
+
})]
|
|
128
|
+
}) : col.header
|
|
129
|
+
}, col.key);
|
|
130
|
+
})] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: displayItems.map((item, index) => {
|
|
131
|
+
const key = keyOf(item);
|
|
132
|
+
const isSelected = resolvedSelection?.selected.has(key);
|
|
133
|
+
const cells = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [resolvedSelection && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
134
|
+
"data-column": "select",
|
|
135
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
136
|
+
type: "checkbox",
|
|
137
|
+
checked: !!isSelected,
|
|
138
|
+
onChange: () => resolvedSelection.onToggle(key),
|
|
139
|
+
"aria-label": `Select row ${key}`
|
|
140
|
+
})
|
|
141
|
+
}), columns.map((col) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
142
|
+
"data-align": col.align,
|
|
143
|
+
children: col.render(item, index)
|
|
144
|
+
}, col.key))] });
|
|
145
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", {
|
|
146
|
+
"data-selected": isSelected ? "" : void 0,
|
|
147
|
+
children: renderRow ? renderRow(item, index, cells) : cells
|
|
148
|
+
}, key);
|
|
149
|
+
}) })]
|
|
150
|
+
}), paginationInfo && renderPagination?.(paginationInfo)]
|
|
151
|
+
});
|
|
177
152
|
}
|
|
153
|
+
//#endregion
|
|
178
154
|
exports.DataTable = DataTable;
|
|
179
|
-
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=DataTable.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.cjs","sources":["../../../src/react/components/DataTable.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type {\n Column,\n SortHeaderProps,\n SelectionState,\n SelectionHelper,\n PaginationState,\n PaginationHelper,\n PaginationInfo,\n SortingHelper,\n AsyncStateProps,\n} from './types';\nimport { isSelectionHelper, isPaginationHelper, isSortingHelper } from './types';\nimport type { SortDescriptor } from '../../Sorting';\n\n// ── Prop resolution helpers ──\n\ninterface ResolvedSelection {\n selected: ReadonlySet<any>;\n onToggle: (key: any) => void;\n onToggleAll: (allKeys: any[]) => void;\n}\n\nfunction resolveSelectionProp(selection: SelectionState | SelectionHelper): ResolvedSelection {\n if (isSelectionHelper(selection)) {\n return {\n selected: selection.selected,\n onToggle: (key) => selection.toggle(key),\n onToggleAll: (allKeys) => selection.toggleAll(allKeys),\n };\n }\n return {\n selected: selection.selected,\n onToggle: selection.onToggle,\n onToggleAll: (allKeys) => selection.onToggleAll(allKeys),\n };\n}\n\nfunction resolveSortProp(\n sort: readonly SortDescriptor[] | SortingHelper,\n onSort?: (key: string) => void,\n): { sorts: readonly SortDescriptor[]; onSort: ((key: string) => void) | undefined } {\n if (isSortingHelper(sort)) {\n return { sorts: sort.sorts, onSort: (key) => sort.toggle(key) };\n }\n return { sorts: sort, onSort };\n}\n\nfunction resolvePaginationProp(\n pagination: PaginationState | PaginationHelper,\n pageSize?: number,\n paginationTotal?: number,\n): PaginationInfo {\n if (isPaginationHelper(pagination)) {\n const total = paginationTotal ?? 0;\n const ps = pagination.pageSize;\n const pageCount = Math.max(1, Math.ceil(total / ps));\n const page = pagination.page;\n return {\n page,\n pageCount,\n total,\n pageSize: ps,\n hasPrev: page > 1,\n hasNext: page < pageCount,\n goToPage: (p) => pagination.setPage(p),\n goPrev: () => pagination.setPage(page - 1),\n goNext: () => pagination.setPage(page + 1),\n };\n }\n const total = pagination.total;\n const ps = pageSize ?? 10;\n const pageCount = Math.max(1, Math.ceil(total / ps));\n const page = pagination.page;\n return {\n page,\n pageCount,\n total,\n pageSize: ps,\n hasPrev: page > 1,\n hasNext: page < pageCount,\n goToPage: pagination.onPageChange,\n goPrev: () => pagination.onPageChange(page - 1),\n goNext: () => pagination.onPageChange(page + 1),\n };\n}\n\n/** Props for the DataTable headless component. */\nexport interface DataTableProps<T> extends AsyncStateProps {\n items: T[];\n columns: Column<T>[];\n keyOf?: (item: T) => string | number;\n pageSize?: number;\n\n // Controlled state — accepts object-literal OR helper instance\n sort?: readonly SortDescriptor[] | SortingHelper;\n onSort?: (key: string) => void;\n selection?: SelectionState | SelectionHelper;\n pagination?: PaginationState | PaginationHelper;\n paginationTotal?: number;\n\n // Render slots\n renderEmpty?: () => ReactNode;\n renderLoading?: () => ReactNode;\n renderError?: (error: string) => ReactNode;\n renderSortIndicator?: (props: SortHeaderProps) => ReactNode;\n renderRow?: (item: T, index: number, defaultCells: ReactNode) => ReactNode;\n renderPagination?: (info: PaginationInfo) => ReactNode;\n\n className?: string;\n 'aria-label'?: string;\n}\n\nconst defaultKeyOf = (item: any) => item.id;\n\nfunction getAriaSortValue(key: string, sorts: readonly SortDescriptor[] | undefined): 'ascending' | 'descending' | 'none' {\n if (!sorts) return 'none';\n const desc = sorts.find(s => s.key === key);\n if (!desc) return 'none';\n return desc.direction === 'asc' ? 'ascending' : 'descending';\n}\n\n/**\n * Headless data table with sort headers, selection checkboxes, and pagination slots.\n * Renders semantic HTML (`<table>`) with data attributes for styling.\n * Accepts Sorting/Selection/Pagination helpers directly via duck-typing.\n */\nexport function DataTable<T>({\n items,\n columns,\n keyOf = defaultKeyOf,\n pageSize,\n sort,\n onSort,\n selection,\n loading,\n error,\n pagination,\n paginationTotal,\n renderEmpty,\n renderLoading,\n renderError,\n renderSortIndicator,\n renderRow,\n renderPagination,\n className,\n 'aria-label': ariaLabel,\n}: DataTableProps<T>) {\n if (loading && renderLoading) return <>{renderLoading()}</>;\n if (error && renderError) return <>{renderError(error)}</>;\n if (items.length === 0 && renderEmpty) return <>{renderEmpty()}</>;\n\n // ── Resolve props ──\n const resolvedSelection = selection ? resolveSelectionProp(selection) : undefined;\n\n let resolvedSorts: readonly SortDescriptor[] | undefined;\n let resolvedOnSort: ((key: string) => void) | undefined;\n if (sort) {\n const resolved = resolveSortProp(sort, onSort);\n resolvedSorts = resolved.sorts;\n resolvedOnSort = resolved.onSort;\n }\n\n let displayItems = items;\n let paginationInfo: PaginationInfo | undefined;\n if (pagination) {\n paginationInfo = resolvePaginationProp(pagination, pageSize, paginationTotal);\n } else if (pageSize && !pagination) {\n displayItems = items.slice(0, pageSize);\n }\n\n // Selection: check indeterminate state\n const allKeys = resolvedSelection ? displayItems.map(item => keyOf(item)) : [];\n const allSelected = resolvedSelection && allKeys.length > 0 && allKeys.every(k => resolvedSelection!.selected.has(k));\n const someSelected = resolvedSelection && allKeys.some(k => resolvedSelection!.selected.has(k));\n\n return (\n <div data-component=\"data-table\" className={className}>\n <table role=\"grid\" aria-label={ariaLabel}>\n <thead>\n <tr>\n {resolvedSelection && (\n <th data-column=\"select\">\n <input\n type=\"checkbox\"\n checked={!!allSelected}\n ref={(el) => {\n if (el) el.indeterminate = !!someSelected && !allSelected;\n }}\n onChange={() => resolvedSelection!.onToggleAll(allKeys)}\n aria-label=\"Select all\"\n />\n </th>\n )}\n {columns.map((col) => {\n const isSortable = col.sortable && resolvedOnSort;\n const sortDesc = resolvedSorts?.find(s => s.key === col.key);\n const isActive = !!sortDesc;\n const sortIndex = resolvedSorts ? resolvedSorts.findIndex(s => s.key === col.key) : -1;\n\n return (\n <th\n key={col.key}\n data-sortable={isSortable ? '' : undefined}\n data-sorted={isActive ? '' : undefined}\n data-align={col.align}\n style={col.width ? { width: col.width } : undefined}\n aria-sort={isSortable ? getAriaSortValue(col.key, resolvedSorts) : undefined}\n >\n {isSortable ? (\n <button type=\"button\" onClick={() => resolvedOnSort!(col.key)}>\n {col.header}\n {renderSortIndicator?.({\n active: isActive,\n direction: sortDesc?.direction ?? 'asc',\n index: sortIndex,\n onToggle: () => resolvedOnSort!(col.key),\n })}\n </button>\n ) : (\n col.header\n )}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {displayItems.map((item, index) => {\n const key = keyOf(item);\n const isSelected = resolvedSelection?.selected.has(key);\n\n const cells = (\n <>\n {resolvedSelection && (\n <td data-column=\"select\">\n <input\n type=\"checkbox\"\n checked={!!isSelected}\n onChange={() => resolvedSelection!.onToggle(key)}\n aria-label={`Select row ${key}`}\n />\n </td>\n )}\n {columns.map((col) => (\n <td\n key={col.key}\n data-align={col.align}\n >\n {col.render(item, index)}\n </td>\n ))}\n </>\n );\n\n return (\n <tr key={key} data-selected={isSelected ? '' : undefined}>\n {renderRow ? renderRow(item, index, cells) : cells}\n </tr>\n );\n })}\n </tbody>\n </table>\n {paginationInfo && renderPagination?.(paginationInfo)}\n </div>\n );\n}\n"],"names":["isSelectionHelper","isSortingHelper","isPaginationHelper","total","ps","pageCount","page","jsx","Fragment","jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataTable.cjs","names":[],"sources":["../../../src/react/components/DataTable.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type {\n Column,\n SortHeaderProps,\n SelectionState,\n SelectionHelper,\n PaginationState,\n PaginationHelper,\n PaginationInfo,\n SortingHelper,\n AsyncStateProps,\n} from './types';\nimport { isSelectionHelper, isPaginationHelper, isSortingHelper } from './types';\nimport type { SortDescriptor } from '../../Sorting';\n\n// ── Prop resolution helpers ──\n\ninterface ResolvedSelection {\n selected: ReadonlySet<any>;\n onToggle: (key: any) => void;\n onToggleAll: (allKeys: any[]) => void;\n}\n\nfunction resolveSelectionProp(selection: SelectionState | SelectionHelper): ResolvedSelection {\n if (isSelectionHelper(selection)) {\n return {\n selected: selection.selected,\n onToggle: (key) => selection.toggle(key),\n onToggleAll: (allKeys) => selection.toggleAll(allKeys),\n };\n }\n return {\n selected: selection.selected,\n onToggle: selection.onToggle,\n onToggleAll: (allKeys) => selection.onToggleAll(allKeys),\n };\n}\n\nfunction resolveSortProp(\n sort: readonly SortDescriptor[] | SortingHelper,\n onSort?: (key: string) => void,\n): { sorts: readonly SortDescriptor[]; onSort: ((key: string) => void) | undefined } {\n if (isSortingHelper(sort)) {\n return { sorts: sort.sorts, onSort: (key) => sort.toggle(key) };\n }\n return { sorts: sort, onSort };\n}\n\nfunction resolvePaginationProp(\n pagination: PaginationState | PaginationHelper,\n pageSize?: number,\n paginationTotal?: number,\n): PaginationInfo {\n if (isPaginationHelper(pagination)) {\n const total = paginationTotal ?? 0;\n const ps = pagination.pageSize;\n const pageCount = Math.max(1, Math.ceil(total / ps));\n const page = pagination.page;\n return {\n page,\n pageCount,\n total,\n pageSize: ps,\n hasPrev: page > 1,\n hasNext: page < pageCount,\n goToPage: (p) => pagination.setPage(p),\n goPrev: () => pagination.setPage(page - 1),\n goNext: () => pagination.setPage(page + 1),\n };\n }\n const total = pagination.total;\n const ps = pageSize ?? 10;\n const pageCount = Math.max(1, Math.ceil(total / ps));\n const page = pagination.page;\n return {\n page,\n pageCount,\n total,\n pageSize: ps,\n hasPrev: page > 1,\n hasNext: page < pageCount,\n goToPage: pagination.onPageChange,\n goPrev: () => pagination.onPageChange(page - 1),\n goNext: () => pagination.onPageChange(page + 1),\n };\n}\n\n/** Props for the DataTable headless component. */\nexport interface DataTableProps<T> extends AsyncStateProps {\n items: T[];\n columns: Column<T>[];\n keyOf?: (item: T) => string | number;\n pageSize?: number;\n\n // Controlled state — accepts object-literal OR helper instance\n sort?: readonly SortDescriptor[] | SortingHelper;\n onSort?: (key: string) => void;\n selection?: SelectionState | SelectionHelper;\n pagination?: PaginationState | PaginationHelper;\n paginationTotal?: number;\n\n // Render slots\n renderEmpty?: () => ReactNode;\n renderLoading?: () => ReactNode;\n renderError?: (error: string) => ReactNode;\n renderSortIndicator?: (props: SortHeaderProps) => ReactNode;\n renderRow?: (item: T, index: number, defaultCells: ReactNode) => ReactNode;\n renderPagination?: (info: PaginationInfo) => ReactNode;\n\n className?: string;\n 'aria-label'?: string;\n}\n\nconst defaultKeyOf = (item: any) => item.id;\n\nfunction getAriaSortValue(key: string, sorts: readonly SortDescriptor[] | undefined): 'ascending' | 'descending' | 'none' {\n if (!sorts) return 'none';\n const desc = sorts.find(s => s.key === key);\n if (!desc) return 'none';\n return desc.direction === 'asc' ? 'ascending' : 'descending';\n}\n\n/**\n * Headless data table with sort headers, selection checkboxes, and pagination slots.\n * Renders semantic HTML (`<table>`) with data attributes for styling.\n * Accepts Sorting/Selection/Pagination helpers directly via duck-typing.\n */\nexport function DataTable<T>({\n items,\n columns,\n keyOf = defaultKeyOf,\n pageSize,\n sort,\n onSort,\n selection,\n loading,\n error,\n pagination,\n paginationTotal,\n renderEmpty,\n renderLoading,\n renderError,\n renderSortIndicator,\n renderRow,\n renderPagination,\n className,\n 'aria-label': ariaLabel,\n}: DataTableProps<T>) {\n if (loading && renderLoading) return <>{renderLoading()}</>;\n if (error && renderError) return <>{renderError(error)}</>;\n if (items.length === 0 && renderEmpty) return <>{renderEmpty()}</>;\n\n // ── Resolve props ──\n const resolvedSelection = selection ? resolveSelectionProp(selection) : undefined;\n\n let resolvedSorts: readonly SortDescriptor[] | undefined;\n let resolvedOnSort: ((key: string) => void) | undefined;\n if (sort) {\n const resolved = resolveSortProp(sort, onSort);\n resolvedSorts = resolved.sorts;\n resolvedOnSort = resolved.onSort;\n }\n\n let displayItems = items;\n let paginationInfo: PaginationInfo | undefined;\n if (pagination) {\n paginationInfo = resolvePaginationProp(pagination, pageSize, paginationTotal);\n } else if (pageSize && !pagination) {\n displayItems = items.slice(0, pageSize);\n }\n\n // Selection: check indeterminate state\n const allKeys = resolvedSelection ? displayItems.map(item => keyOf(item)) : [];\n const allSelected = resolvedSelection && allKeys.length > 0 && allKeys.every(k => resolvedSelection!.selected.has(k));\n const someSelected = resolvedSelection && allKeys.some(k => resolvedSelection!.selected.has(k));\n\n return (\n <div data-component=\"data-table\" className={className}>\n <table role=\"grid\" aria-label={ariaLabel}>\n <thead>\n <tr>\n {resolvedSelection && (\n <th data-column=\"select\">\n <input\n type=\"checkbox\"\n checked={!!allSelected}\n ref={(el) => {\n if (el) el.indeterminate = !!someSelected && !allSelected;\n }}\n onChange={() => resolvedSelection!.onToggleAll(allKeys)}\n aria-label=\"Select all\"\n />\n </th>\n )}\n {columns.map((col) => {\n const isSortable = col.sortable && resolvedOnSort;\n const sortDesc = resolvedSorts?.find(s => s.key === col.key);\n const isActive = !!sortDesc;\n const sortIndex = resolvedSorts ? resolvedSorts.findIndex(s => s.key === col.key) : -1;\n\n return (\n <th\n key={col.key}\n data-sortable={isSortable ? '' : undefined}\n data-sorted={isActive ? '' : undefined}\n data-align={col.align}\n style={col.width ? { width: col.width } : undefined}\n aria-sort={isSortable ? getAriaSortValue(col.key, resolvedSorts) : undefined}\n >\n {isSortable ? (\n <button type=\"button\" onClick={() => resolvedOnSort!(col.key)}>\n {col.header}\n {renderSortIndicator?.({\n active: isActive,\n direction: sortDesc?.direction ?? 'asc',\n index: sortIndex,\n onToggle: () => resolvedOnSort!(col.key),\n })}\n </button>\n ) : (\n col.header\n )}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {displayItems.map((item, index) => {\n const key = keyOf(item);\n const isSelected = resolvedSelection?.selected.has(key);\n\n const cells = (\n <>\n {resolvedSelection && (\n <td data-column=\"select\">\n <input\n type=\"checkbox\"\n checked={!!isSelected}\n onChange={() => resolvedSelection!.onToggle(key)}\n aria-label={`Select row ${key}`}\n />\n </td>\n )}\n {columns.map((col) => (\n <td\n key={col.key}\n data-align={col.align}\n >\n {col.render(item, index)}\n </td>\n ))}\n </>\n );\n\n return (\n <tr key={key} data-selected={isSelected ? '' : undefined}>\n {renderRow ? renderRow(item, index, cells) : cells}\n </tr>\n );\n })}\n </tbody>\n </table>\n {paginationInfo && renderPagination?.(paginationInfo)}\n </div>\n );\n}\n"],"mappings":"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"}
|