@devslab/dds-table-solid 0.0.0-stage → 0.22.1

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/dist/server.js ADDED
@@ -0,0 +1,312 @@
1
+ import { createComponent, escape, memo, ssr, ssrAttribute, ssrHydrationKey, ssrStyleProperty } from "solid-js/web";
2
+ import { For, Show, createMemo, createSignal, onCleanup, onMount } from "solid-js";
3
+ import { coreCellsFeature, coreColumnsFeature, coreHeadersFeature, coreRowModelsFeature, coreRowsFeature, coreTablesFeature, createColumnHelper, createSortedRowModel, createTable, rowSortingFeature, sortFn_alphanumeric, sortFn_text, tableFeatures } from "@tanstack/solid-table";
4
+ /**
5
+ * Registering `rowSortingFeature` alone is not enough for sorting to reach
6
+ * the screen — `sortedRowModel` is the factory `table.getRowModel()` actually
7
+ * calls to produce sorted rows; without it, `state.sorting` changes but the
8
+ * rendered row order never does. Added here, after `TableFeatureSet` is
9
+ * already named, so its function type closes over the narrow type instead of
10
+ * over itself.
11
+ *
12
+ * `sortFns` registers the names `sortFn: "auto"` (the default every column
13
+ * gets — see `toColumnDefs`) can actually resolve to for a `Column<T>` whose
14
+ * `sortBy` returns `string | number | null`: plain strings resolve to
15
+ * `"text"`, strings containing digit runs (`"Row 10"`, `"SKU100"`) resolve to
16
+ * `"alphanumeric"`, and numbers/`null` never set a name at all and fall
17
+ * straight to the always-available `sortFn_basic` — so `"datetime"` is never
18
+ * reachable and is deliberately not registered. Leaving either reachable name
19
+ * unregistered means `"auto"` silently falls back to `sortFn_basic`, which
20
+ * compares raw values instead of lowercasing first: a case-sensitive sort
21
+ * that also warns on every column in development
22
+ * (`rowSortingFeature.utils.js`'s `column_getAutoSortFn`). Importing the two
23
+ * named functions (rather than the `sortFns` barrel export, whose own
24
+ * docstring says registering it "opts out of tree-shaking") keeps every
25
+ * other built-in sorting function — including the case-sensitive and
26
+ * datetime variants this component never produces — out of the bundle.
27
+ */
28
+ var tableFeatureSet = {
29
+ ...tableFeatures({
30
+ coreTablesFeature,
31
+ coreRowsFeature,
32
+ coreColumnsFeature,
33
+ coreHeadersFeature,
34
+ coreCellsFeature,
35
+ coreRowModelsFeature,
36
+ rowSortingFeature
37
+ }),
38
+ sortedRowModel: createSortedRowModel(),
39
+ sortFns: {
40
+ text: sortFn_text,
41
+ alphanumeric: sortFn_alphanumeric
42
+ }
43
+ };
44
+ /** Turns our declarations into TanStack column defs. Sorting is enabled per
45
+ * column by the presence of `sortBy`; everything visual stays in our own
46
+ * markup, so the def carries only what the model needs.
47
+ *
48
+ * `Column<T>` deliberately leaves `T` unconstrained (any row shape a
49
+ * consumer wants to render), but TanStack's `RowData` requires
50
+ * `Record<string, any> | Array<any>`. Every real row is one of those at
51
+ * runtime, so the helper is instantiated at `Record<string, unknown>` and
52
+ * the accessor casts its parameter back to `T` — a boundary cast, not a
53
+ * behavior change. */
54
+ function toColumnDefs(columns) {
55
+ const helper = createColumnHelper();
56
+ return columns.map((column) => helper.accessor((row) => column.sortBy ? column.sortBy(row) ?? void 0 : void 0, {
57
+ id: column.id,
58
+ enableSorting: Boolean(column.sortBy),
59
+ sortUndefined: "last"
60
+ }));
61
+ }
62
+ //#endregion
63
+ //#region src/data-table.tsx
64
+ var _tmpl$ = ["<col", ">"];
65
+ var _tmpl$2 = [
66
+ "<colgroup",
67
+ "><!--$-->",
68
+ "<!--/--><!--$-->",
69
+ "<!--/--></colgroup>"
70
+ ];
71
+ var _tmpl$3 = [
72
+ "<th",
73
+ " scope=\"col\"><span class=\"dds-visually-hidden\">",
74
+ "</span></th>"
75
+ ];
76
+ var _tmpl$4 = [
77
+ "<div",
78
+ "><table class=\"",
79
+ "\" style=\"",
80
+ "\"><caption class=\"dds-visually-hidden\">",
81
+ "</caption><!--$-->",
82
+ "<!--/--><thead><tr><!--$-->",
83
+ "<!--/--><!--$-->",
84
+ "<!--/--></tr></thead><tbody>",
85
+ "</tbody></table></div>"
86
+ ];
87
+ var _tmpl$5 = [
88
+ "<nav",
89
+ " class=\"dds-table__pagination\"",
90
+ ">",
91
+ "</nav>"
92
+ ];
93
+ var _tmpl$6 = [
94
+ "<p",
95
+ " class=\"dds-table__order\">",
96
+ "</p>"
97
+ ];
98
+ var _tmpl$7 = [
99
+ "<col",
100
+ " style=\"",
101
+ "\">"
102
+ ];
103
+ var _tmpl$8 = [
104
+ "<button",
105
+ " type=\"button\" class=\"dds-table__sort\" data-action=\"sort\"",
106
+ "><!--$-->",
107
+ "<!--/--><span class=\"dds-table__sort-mark\" aria-hidden=\"true\"",
108
+ "></span></button>"
109
+ ];
110
+ var _tmpl$9 = [
111
+ "<span",
112
+ " role=\"separator\" tabindex=\"0\" class=\"dds-table__resize\" aria-orientation=\"vertical\"",
113
+ "></span>"
114
+ ];
115
+ var _tmpl$0 = [
116
+ "<th",
117
+ " scope=\"col\"",
118
+ "><!--$-->",
119
+ "<!--/--><!--$-->",
120
+ "<!--/--></th>"
121
+ ];
122
+ var _tmpl$1 = [
123
+ "<tr",
124
+ "><!--$-->",
125
+ "<!--/--><!--$-->",
126
+ "<!--/--></tr>"
127
+ ];
128
+ var _tmpl$10 = [
129
+ "<th",
130
+ " scope=\"row\"",
131
+ ">",
132
+ "</th>"
133
+ ];
134
+ var _tmpl$11 = [
135
+ "<td",
136
+ ">",
137
+ "</td>"
138
+ ];
139
+ var _tmpl$12 = [
140
+ "<td",
141
+ "><div class=\"dds-table__actions\">",
142
+ "</div></td>"
143
+ ];
144
+ var _tmpl$13 = [
145
+ "<tr",
146
+ "><td",
147
+ ">",
148
+ "</td></tr>"
149
+ ];
150
+ var _tmpl$14 = [
151
+ "<a",
152
+ " class=\"dds-btn dds-btn--secondary\"",
153
+ ">",
154
+ "</a>"
155
+ ];
156
+ /** Fills the `{column}` placeholder in a consumer-supplied label template.
157
+ * A function replacer, not `template.replace("{column}", value)` — a
158
+ * string replacement value is subject to special `$&`/`$$`/`` $` ``/`$'`
159
+ * patterns, and this console has currency columns whose labels can contain
160
+ * a literal `$`. */
161
+ function fillLabel(template, value) {
162
+ return template.replace("{column}", () => value);
163
+ }
164
+ function DataTable(props) {
165
+ const clientSorted = () => props.sort === "client";
166
+ const controlledSort = () => typeof props.sort === "object" && "onChange" in props.sort ? props.sort : void 0;
167
+ const sortable = () => clientSorted() || Boolean(controlledSort());
168
+ const statedOrder = () => typeof props.sort === "object" ? props.sort.statedOrder : void 0;
169
+ const [widths, setWidths] = createSignal({});
170
+ const fixed = () => Boolean(props.resizing) || props.columns.some((column) => column.width !== void 0);
171
+ const headers = /* @__PURE__ */ new Map();
172
+ const [measurements, setMeasurements] = createSignal({});
173
+ onMount(() => {
174
+ if (!props.resizing || typeof ResizeObserver === "undefined") return;
175
+ const measure = () => setMeasurements(Object.fromEntries([...headers].map(([id, node]) => [id, node.getBoundingClientRect().width])));
176
+ const observer = new ResizeObserver(measure);
177
+ headers.forEach((node) => observer.observe(node));
178
+ measure();
179
+ onCleanup(() => observer.disconnect());
180
+ });
181
+ const minWidth = () => props.resizing?.minWidth ?? 80;
182
+ const maxWidth = () => Math.max(minWidth(), props.resizing?.maxWidth ?? 1200);
183
+ const clamp = (width) => Math.max(minWidth(), Math.min(maxWidth(), width));
184
+ const measuredWidth = (column) => widths()[column.id] ?? clamp(measurements()[column.id] || headers.get(column.id)?.getBoundingClientRect().width || (column.width?.endsWith("px") ? Number.parseFloat(column.width) : minWidth()));
185
+ const columnWidth = (column) => widths()[column.id] !== void 0 ? `${widths()[column.id]}px` : column.width;
186
+ onCleanup(() => void 0);
187
+ const columnDefs = createMemo(() => toColumnDefs(props.columns));
188
+ const table = createTable({
189
+ features: tableFeatureSet,
190
+ get data() {
191
+ return props.rows;
192
+ },
193
+ get columns() {
194
+ return columnDefs();
195
+ },
196
+ enableSorting: true
197
+ });
198
+ const ordered = createMemo(() => clientSorted() ? table.getRowModel().rows.map((row) => row.original) : [...props.rows]);
199
+ const sortState = (id) => {
200
+ const external = controlledSort();
201
+ const current = external ? external.value : table.store.state.sorting?.[0];
202
+ if (!current || current.id !== id) return "none";
203
+ return current.desc ? "descending" : "ascending";
204
+ };
205
+ return [
206
+ createComponent(Show, {
207
+ get when() {
208
+ return statedOrder();
209
+ },
210
+ children: (order) => ssr(_tmpl$6, ssrHydrationKey(), escape(order()))
211
+ }),
212
+ createComponent(Show, {
213
+ get when() {
214
+ return props.rows.length > 0;
215
+ },
216
+ get fallback() {
217
+ return props.empty;
218
+ },
219
+ get children() {
220
+ return ssr(_tmpl$4, ssrHydrationKey() + ssrAttribute("class", props.scroll === "tall" ? "dds-table-wrap dds-table-wrap--tall" : "dds-table-wrap", false), `dds-table${props.density === "dense" ? " dds-table--dense" : ""}${fixed() ? " dds-table--fixed" : ""}`, ssrStyleProperty("min-inline-size:", escape(props.minWidth, true)) + ssrStyleProperty(";table-layout:", props.resizing ? "fixed" : escape(void 0, true)) + ssrStyleProperty(";width:", Object.keys(widths()).length === props.columns.length && !props.actions ? `${escape(Object.values(widths()).reduce((a, b) => a + b, 0), true)}px` : escape(void 0, true)), escape(props.caption), escape(createComponent(Show, {
221
+ get when() {
222
+ return fixed();
223
+ },
224
+ get children() {
225
+ return ssr(_tmpl$2, ssrHydrationKey(), escape(createComponent(For, {
226
+ get each() {
227
+ return props.columns;
228
+ },
229
+ children: (column) => ssr(_tmpl$7, ssrHydrationKey() + ssrAttribute("data-fold", column.fold ? "" : escape(void 0, true), false), ssrStyleProperty("width:", escape(columnWidth(column), true)))
230
+ })), escape(createComponent(Show, {
231
+ get when() {
232
+ return props.actions;
233
+ },
234
+ get children() {
235
+ return ssr(_tmpl$, ssrHydrationKey());
236
+ }
237
+ })));
238
+ }
239
+ })), escape(createComponent(For, {
240
+ get each() {
241
+ return props.columns;
242
+ },
243
+ children: (column) => ssr(_tmpl$0, ssrHydrationKey(), ssrAttribute("data-column", escape(column.id, true), false) + ssrAttribute("data-fold", column.fold ? "" : escape(void 0, true), false) + ssrAttribute("data-numeric", column.numeric ? "" : escape(void 0, true), false) + ssrAttribute("aria-sort", sortable() && column.sortBy ? escape(sortState(column.id), true) : escape(void 0, true), false), escape(createComponent(Show, {
244
+ get when() {
245
+ return memo(() => !!sortable())() && column.sortBy;
246
+ },
247
+ get fallback() {
248
+ return column.label;
249
+ },
250
+ get children() {
251
+ return ssr(_tmpl$8, ssrHydrationKey(), ssrAttribute("aria-label", escape(fillLabel(props.labels.sortBy, column.label), true), false), escape(column.label), ssrAttribute("data-sort-state", escape(sortState(column.id), true), false));
252
+ }
253
+ })), escape(createComponent(Show, {
254
+ get when() {
255
+ return memo(() => !!props.resizing)() && column.resizable !== false;
256
+ },
257
+ get children() {
258
+ return ssr(_tmpl$9, ssrHydrationKey(), ssrAttribute("aria-label", escape(fillLabel(props.resizing.label, column.label), true), false) + ssrAttribute("aria-valuemin", escape(minWidth(), true), false) + ssrAttribute("aria-valuemax", escape(maxWidth(), true), false) + ssrAttribute("aria-valuenow", escape(measuredWidth(column), true), false));
259
+ }
260
+ })))
261
+ })), escape(createComponent(Show, {
262
+ get when() {
263
+ return props.actions;
264
+ },
265
+ get children() {
266
+ return ssr(_tmpl$3, ssrHydrationKey(), escape(props.labels.actions));
267
+ }
268
+ })), escape(createComponent(For, {
269
+ get each() {
270
+ return ordered();
271
+ },
272
+ children: (row) => [ssr(_tmpl$1, ssrHydrationKey() + ssrAttribute("tabindex", props.selection ? 0 : escape(void 0, true), false) + ssrAttribute("aria-selected", props.selection ? escape(props.selection.selectedId, true) === escape(props.selection.rowId(row), true) : escape(void 0, true), false), escape(createComponent(For, {
273
+ get each() {
274
+ return props.columns;
275
+ },
276
+ children: (column) => createComponent(Show, {
277
+ get when() {
278
+ return column.rowHeader;
279
+ },
280
+ get fallback() {
281
+ return ssr(_tmpl$11, ssrHydrationKey() + ssrAttribute("data-fold", column.fold ? "" : escape(void 0, true), false) + ssrAttribute("data-numeric", column.numeric ? "" : escape(void 0, true), false), escape(column.cell(row)));
282
+ },
283
+ get children() {
284
+ return ssr(_tmpl$10, ssrHydrationKey(), ssrAttribute("data-fold", column.fold ? "" : escape(void 0, true), false) + ssrAttribute("data-numeric", column.numeric ? "" : escape(void 0, true), false), escape(column.cell(row)));
285
+ }
286
+ })
287
+ })), escape(createComponent(Show, {
288
+ get when() {
289
+ return props.actions;
290
+ },
291
+ children: (actions) => ssr(_tmpl$12, ssrHydrationKey(), escape(actions()(row)))
292
+ }))), createComponent(Show, {
293
+ get when() {
294
+ return props.detail?.(row);
295
+ },
296
+ children: (node) => ssr(_tmpl$13, ssrHydrationKey(), ssrAttribute("colspan", escape(props.columns.length, true) + (props.actions ? 1 : 0), false), escape(node()))
297
+ })]
298
+ })));
299
+ }
300
+ }),
301
+ ssr(_tmpl$5, ssrHydrationKey(), ssrAttribute("hidden", !props.page?.nextHref, true) + ssrAttribute("aria-label", escape(props.labels.nextPage, true), false), escape(createComponent(Show, {
302
+ get when() {
303
+ return props.page?.nextHref;
304
+ },
305
+ children: (href) => ssr(_tmpl$14, ssrHydrationKey(), ssrAttribute("href", escape(href(), true), false), escape(props.labels.nextPage))
306
+ })))
307
+ ];
308
+ }
309
+ //#endregion
310
+ export { DataTable };
311
+
312
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","names":["createMemo","createSignal","onCleanup","onMount","For","Show","JSX","createTable","tableFeatureSet","toColumnDefs","Column","DataTableLabels","TableFeatureSet","SortValue","id","desc","SortMode","statedOrder","value","onChange","ColumnResizing","label","minWidth","maxWidth","widths","Readonly","Record","reason","RowSelection","rowId","row","T","selectedId","onSelect","fillLabel","template","replace","DataTable","props","rows","columns","caption","labels","sort","density","scroll","actions","Element","detail","page","nextHref","empty","resizing","selection","clientSorted","controlledSort","undefined","sortable","Boolean","setWidths","fixed","some","column","width","headers","Map","HTMLTableCellElement","measurements","setMeasurements","ResizeObserver","measure","Object","fromEntries","map","node","getBoundingClientRect","observer","forEach","observe","disconnect","Math","max","clamp","min","measuredWidth","get","endsWith","Number","parseFloat","columnWidth","cancelDrag","resetWidths","resizeKey","event","KeyboardEvent","step","shiftKey","next","key","preventDefault","stopPropagation","updated","beginResize","PointerEvent","button","before","initial","c","start","clientX","pointerId","rtl","getComputedStyle","direction","cleanup","window","removeEventListener","move","finish","cancel","e","addEventListener","interactive","Event","target","closest","columnDefs","table","features","data","enableSorting","ordered","getRowModel","original","sortState","external","current","store","state","sorting","toggleSort","getColumn","toggleSorting","_$createComponent","when","children","order","_$ssr","_tmpl$6","_$ssrHydrationKey","_$escape","length","fallback","_tmpl$4","_$ssrAttribute","_$ssrStyleProperty","keys","values","reduce","a","b","_tmpl$2","each","_tmpl$7","fold","_tmpl$","_tmpl$0","numeric","sortBy","_$memo","_tmpl$8","resizable","_tmpl$9","_tmpl$3","_tmpl$1","rowHeader","_tmpl$11","cell","_tmpl$10","_tmpl$12","_tmpl$13","_tmpl$5","nextPage","href","_tmpl$14"],"sources":["../src/columns.ts","../src/data-table.tsx"],"sourcesContent":["import type { JSX } from \"solid-js\";\nimport {\n coreCellsFeature,\n coreColumnsFeature,\n coreHeadersFeature,\n coreRowModelsFeature,\n coreRowsFeature,\n coreTablesFeature,\n createColumnHelper,\n createSortedRowModel,\n rowSortingFeature,\n sortFn_alphanumeric,\n sortFn_text,\n tableFeatures,\n type ColumnDef,\n} from \"@tanstack/solid-table\";\n\nexport type Column<T> = {\n id: string;\n label: string;\n cell: (row: T) => JSX.Element;\n sortBy?: (row: T) => string | number | null;\n width?: string;\n resizable?: boolean;\n fold?: boolean;\n numeric?: boolean;\n rowHeader?: boolean;\n};\n\nexport type DataTableLabels = {\n /** Accessible name for a sort button; `{column}` is replaced with the column label. */\n sortBy: string;\n /** Header of the trailing actions column, rendered visually hidden. */\n actions: string;\n /** Label of the next-page link. */\n nextPage: string;\n};\n\n/**\n * The feature set every `DataTable` instance is built from: the core row\n * model plus client-side sorting. Built once (per `tableFeatures`'\n * recommendation to use it statically outside a component) so `toColumnDefs`\n * and `createTable` agree on the same `TFeatures` type.\n */\nconst baseFeatures = tableFeatures({\n coreTablesFeature,\n coreRowsFeature,\n coreColumnsFeature,\n coreHeadersFeature,\n coreCellsFeature,\n coreRowModelsFeature,\n rowSortingFeature,\n});\n\n/** The `TFeatures` type used everywhere a table/column type needs one. Kept\n * separate from the `sortedRowModel` factory below: `createSortedRowModel`'s\n * return type embeds `Table<TFeatures, TData>`, so folding it into the very\n * type it closes over makes `TFeatures` self-referential — TypeScript's\n * structural comparison of that recursive shape (observed while wiring this\n * up) reports unrelated `ColumnDef`/`Column`/`HeaderContext` instantiations\n * a few frames down a completely unrelated diff, because it can't resolve\n * the cycle. Naming the narrower, non-recursive type here and using it as\n * the explicit `TFeatures` argument everywhere avoids that. */\nexport type TableFeatureSet = typeof baseFeatures;\n\n/**\n * Registering `rowSortingFeature` alone is not enough for sorting to reach\n * the screen — `sortedRowModel` is the factory `table.getRowModel()` actually\n * calls to produce sorted rows; without it, `state.sorting` changes but the\n * rendered row order never does. Added here, after `TableFeatureSet` is\n * already named, so its function type closes over the narrow type instead of\n * over itself.\n *\n * `sortFns` registers the names `sortFn: \"auto\"` (the default every column\n * gets — see `toColumnDefs`) can actually resolve to for a `Column<T>` whose\n * `sortBy` returns `string | number | null`: plain strings resolve to\n * `\"text\"`, strings containing digit runs (`\"Row 10\"`, `\"SKU100\"`) resolve to\n * `\"alphanumeric\"`, and numbers/`null` never set a name at all and fall\n * straight to the always-available `sortFn_basic` — so `\"datetime\"` is never\n * reachable and is deliberately not registered. Leaving either reachable name\n * unregistered means `\"auto\"` silently falls back to `sortFn_basic`, which\n * compares raw values instead of lowercasing first: a case-sensitive sort\n * that also warns on every column in development\n * (`rowSortingFeature.utils.js`'s `column_getAutoSortFn`). Importing the two\n * named functions (rather than the `sortFns` barrel export, whose own\n * docstring says registering it \"opts out of tree-shaking\") keeps every\n * other built-in sorting function — including the case-sensitive and\n * datetime variants this component never produces — out of the bundle.\n */\nexport const tableFeatureSet: TableFeatureSet & {\n sortedRowModel: ReturnType<typeof createSortedRowModel<TableFeatureSet, Record<string, unknown>>>;\n sortFns: { text: typeof sortFn_text; alphanumeric: typeof sortFn_alphanumeric };\n} = {\n ...baseFeatures,\n sortedRowModel: createSortedRowModel<TableFeatureSet, Record<string, unknown>>(),\n sortFns: { text: sortFn_text, alphanumeric: sortFn_alphanumeric },\n};\n\n/** Turns our declarations into TanStack column defs. Sorting is enabled per\n * column by the presence of `sortBy`; everything visual stays in our own\n * markup, so the def carries only what the model needs.\n *\n * `Column<T>` deliberately leaves `T` unconstrained (any row shape a\n * consumer wants to render), but TanStack's `RowData` requires\n * `Record<string, any> | Array<any>`. Every real row is one of those at\n * runtime, so the helper is instantiated at `Record<string, unknown>` and\n * the accessor casts its parameter back to `T` — a boundary cast, not a\n * behavior change. */\nexport function toColumnDefs<T>(columns: readonly Column<T>[]): ColumnDef<TableFeatureSet, Record<string, unknown>, unknown>[] {\n const helper = createColumnHelper<TableFeatureSet, Record<string, unknown>>();\n return columns.map((column) =>\n // `TValue` is invariant on `ColumnDef` (it shows up contravariantly via\n // `footer`'s `HeaderContext`, covariantly via `accessorFn`'s return), so\n // a heterogeneous array of columns can only be typed uniformly at\n // `unknown` — the array element type `ColumnDef<..., unknown>` is not a\n // supertype of `ColumnDef<..., string | number | null>`. The return type\n // annotation below is what makes TanStack infer `TValue = unknown`\n // instead of narrowing to the ternary's actual `string | number | null`.\n //\n // `?? undefined` is the adapter boundary translating our declared\n // contract (`sortBy` returns `null` for \"no value\") into TanStack's:\n // `createSortedRowModel`'s comparator only consults `sortUndefined`\n // after testing `=== void 0`, so a bare `null` would never trigger it —\n // `sortUndefined: \"last\"` would be a promise the code doesn't keep.\n helper.accessor((row): unknown => (column.sortBy ? column.sortBy(row as T) ?? undefined : undefined), {\n id: column.id,\n enableSorting: Boolean(column.sortBy),\n sortUndefined: \"last\",\n }),\n );\n}\n","import { createMemo, createSignal, onCleanup, onMount, For, Show, type JSX } from \"solid-js\";\nimport { createTable } from \"@tanstack/solid-table\";\nimport { tableFeatureSet, toColumnDefs, type Column, type DataTableLabels, type TableFeatureSet } from \"./columns\";\n\nexport type SortValue = { id: string; desc: boolean } | null;\nexport type SortMode = \"client\" | { statedOrder: string } | { value: SortValue; onChange: (value: SortValue) => void; statedOrder?: string };\nexport type ColumnResizing = {\n label: string;\n minWidth?: number;\n maxWidth?: number;\n onChange?: (widths: Readonly<Record<string, number>>, reason: \"resize\" | \"reset\") => void;\n};\nexport type RowSelection<T> = { rowId: (row: T) => string; selectedId?: string | null; onSelect: (row: T) => void };\n\n/** Fills the `{column}` placeholder in a consumer-supplied label template.\n * A function replacer, not `template.replace(\"{column}\", value)` — a\n * string replacement value is subject to special `$&`/`$$`/`` $` ``/`$'`\n * patterns, and this console has currency columns whose labels can contain\n * a literal `$`. */\nfunction fillLabel(template: string, value: string): string {\n return template.replace(\"{column}\", () => value);\n}\n\nexport function DataTable<T>(props: {\n rows: readonly T[];\n columns: readonly Column<T>[];\n caption: string;\n labels: DataTableLabels;\n sort?: SortMode;\n density?: \"comfortable\" | \"dense\";\n scroll?: \"auto\" | \"tall\";\n minWidth?: string;\n actions?: (row: T) => JSX.Element;\n detail?: (row: T) => JSX.Element;\n page?: { nextHref?: string | undefined };\n empty?: JSX.Element;\n resizing?: ColumnResizing;\n selection?: RowSelection<T>;\n}): JSX.Element {\n const clientSorted = () => props.sort === \"client\";\n const controlledSort = () => typeof props.sort === \"object\" && \"onChange\" in props.sort ? props.sort : undefined;\n const sortable = () => clientSorted() || Boolean(controlledSort());\n const statedOrder = () => (typeof props.sort === \"object\" ? props.sort.statedOrder : undefined);\n const [widths, setWidths] = createSignal<Record<string, number>>({});\n const fixed = () => Boolean(props.resizing) || props.columns.some((column) => column.width !== undefined);\n const headers = new Map<string, HTMLTableCellElement>();\n const [measurements, setMeasurements] = createSignal<Record<string, number>>({});\n onMount(() => {\n if (!props.resizing || typeof ResizeObserver === \"undefined\") return;\n const measure = () => setMeasurements(Object.fromEntries([...headers].map(([id, node]) => [id, node.getBoundingClientRect().width])));\n const observer = new ResizeObserver(measure);\n headers.forEach(node => observer.observe(node)); measure();\n onCleanup(() => observer.disconnect());\n });\n const minWidth = () => props.resizing?.minWidth ?? 80;\n const maxWidth = () => Math.max(minWidth(), props.resizing?.maxWidth ?? 1200);\n const clamp = (width: number) => Math.max(minWidth(), Math.min(maxWidth(), width));\n const measuredWidth = (column: Column<T>) => widths()[column.id] ?? clamp(measurements()[column.id] || headers.get(column.id)?.getBoundingClientRect().width ||\n (column.width?.endsWith(\"px\") ? Number.parseFloat(column.width) : minWidth()));\n const columnWidth = (column: Column<T>) => widths()[column.id] !== undefined ? `${widths()[column.id]}px` : column.width;\n let cancelDrag: (() => void) | undefined;\n onCleanup(() => cancelDrag?.());\n function resetWidths() {\n cancelDrag?.(); setWidths({}); props.resizing?.onChange?.({}, \"reset\");\n }\n function resizeKey(event: KeyboardEvent, column: Column<T>) {\n const step = event.shiftKey ? 50 : 12;\n const next = event.key === \"ArrowLeft\" ? measuredWidth(column) - step : event.key === \"ArrowRight\" ? measuredWidth(column) + step\n : event.key === \"Home\" ? minWidth() : event.key === \"End\" ? maxWidth() : undefined;\n if (next === undefined && event.key !== \"Escape\") return;\n event.preventDefault(); event.stopPropagation();\n if (event.key === \"Escape\") resetWidths();\n else { cancelDrag?.(); const updated = { ...widths(), [column.id]: clamp(next!) }; setWidths(updated); props.resizing?.onChange?.(updated, \"resize\"); }\n }\n function beginResize(event: PointerEvent, column: Column<T>) {\n if (event.button !== 0 || !props.resizing) return;\n event.preventDefault(); event.stopPropagation(); cancelDrag?.();\n const before = widths();\n const initial = Object.fromEntries(props.columns.map(c => [c.id, measuredWidth(c)]));\n const start = event.clientX; const pointerId = event.pointerId;\n const rtl = getComputedStyle(headers.get(column.id)!).direction === \"rtl\";\n const cleanup = () => { window.removeEventListener(\"pointermove\", move); window.removeEventListener(\"pointerup\", finish); window.removeEventListener(\"pointercancel\", cancel); cancelDrag = undefined; };\n const move = (e: PointerEvent) => { if (e.pointerId === pointerId) setWidths({ ...initial, [column.id]: clamp(initial[column.id]! + (e.clientX - start) * (rtl ? -1 : 1)) }); };\n const finish = (e: PointerEvent) => { if (e.pointerId !== pointerId) return; move(e); cleanup(); props.resizing?.onChange?.(widths(), \"resize\"); };\n const cancel = (e?: PointerEvent) => { if (e && e.pointerId !== pointerId) return; cleanup(); setWidths(before); };\n cancelDrag = cancel;\n window.addEventListener(\"pointermove\", move); window.addEventListener(\"pointerup\", finish); window.addEventListener(\"pointercancel\", cancel);\n }\n const interactive = (event: Event) => event.target instanceof Element && Boolean(event.target.closest('button,a,input,select,textarea,summary,[contenteditable],[role=\"button\"],[role=\"link\"]'));\n\n /* `toColumnDefs` builds fresh column objects on every read; a table model\n that sees a new column identity on every access can lose sorting state\n or re-render in a loop, so the defs are memoized on `props.columns`. */\n const columnDefs = createMemo(() => toColumnDefs(props.columns));\n\n /* TanStack's `RowData` requires `Record<string, any> | Array<any>`, which\n an unconstrained `T` can't satisfy structurally. Every row is one of\n those at runtime, so the table is instantiated at `Record<string,\n unknown>` and cast back to `T` where rows come back out (in `ordered`). */\n const table = createTable<TableFeatureSet, Record<string, unknown>>({\n features: tableFeatureSet,\n get data() { return props.rows as readonly Record<string, unknown>[]; },\n get columns() { return columnDefs(); },\n enableSorting: true,\n });\n\n /* The model sorts; our own markup renders. A server-ordered table never\n reaches this path — `sort` is then an object and no header is a button. */\n const ordered = createMemo(() => (clientSorted() ? table.getRowModel().rows.map((row) => row.original as T) : [...props.rows]));\n\n const sortState = (id: string) => {\n const external = controlledSort();\n const current = external ? external.value : table.store.state.sorting?.[0];\n if (!current || current.id !== id) return \"none\";\n return current.desc ? \"descending\" : \"ascending\";\n };\n function toggleSort(id: string) {\n const external = controlledSort();\n if (!external) { table.getColumn(id)?.toggleSorting(); return; }\n const current = external.value?.id === id ? external.value : null;\n external.onChange(current?.desc ? null : { id, desc: current !== null });\n }\n\n return (\n <>\n {/* The stated order and the pagination link are not part of the \"is\n there a table to show\" question — a cursor-paged list can land on\n an empty page and still needs to say what order it was in and\n offer a way forward. Only the table itself (and its wrap) falls\n back to `empty` when there are no rows. */}\n <Show when={statedOrder()}>{(order) => <p class=\"dds-table__order\">{order()}</p>}</Show>\n <Show when={props.rows.length > 0} fallback={props.empty}>\n <div class={props.scroll === \"tall\" ? \"dds-table-wrap dds-table-wrap--tall\" : \"dds-table-wrap\"}>\n <table\n class={`dds-table${props.density === \"dense\" ? \" dds-table--dense\" : \"\"}${fixed() ? \" dds-table--fixed\" : \"\"}`}\n style={{ \"min-inline-size\": props.minWidth, \"table-layout\": props.resizing ? \"fixed\" : undefined,\n width: Object.keys(widths()).length === props.columns.length && !props.actions ? `${Object.values(widths()).reduce((a, b) => a + b, 0)}px` : undefined }}\n >\n <caption class=\"dds-visually-hidden\">{props.caption}</caption>\n <Show when={fixed()}>\n <colgroup>\n <For each={props.columns}>{(column) => <col data-fold={column.fold ? \"\" : undefined} style={{ width: columnWidth(column) }} />}</For>\n <Show when={props.actions}><col /></Show>\n </colgroup>\n </Show>\n <thead>\n <tr>\n <For each={props.columns}>{(column) => (\n <th ref={node => headers.set(column.id, node)} scope=\"col\" data-column={column.id} data-fold={column.fold ? \"\" : undefined} data-numeric={column.numeric ? \"\" : undefined} aria-sort={sortable() && column.sortBy ? sortState(column.id) : undefined}>\n <Show when={sortable() && column.sortBy} fallback={column.label}>\n <button\n type=\"button\"\n class=\"dds-table__sort\"\n data-action=\"sort\"\n aria-label={fillLabel(props.labels.sortBy, column.label)}\n onClick={() => toggleSort(column.id)}\n >\n {column.label}\n <span class=\"dds-table__sort-mark\" aria-hidden=\"true\" data-sort-state={sortState(column.id)} />\n </button>\n </Show>\n <Show when={props.resizing && column.resizable !== false}>\n <span role=\"separator\" tabindex={0} class=\"dds-table__resize\" aria-orientation=\"vertical\"\n aria-label={fillLabel(props.resizing!.label, column.label)} aria-valuemin={minWidth()} aria-valuemax={maxWidth()}\n aria-valuenow={measuredWidth(column)} onPointerDown={event => beginResize(event, column)}\n onDblClick={event => { event.preventDefault(); event.stopPropagation(); resetWidths(); }}\n onKeyDown={event => resizeKey(event, column)} />\n </Show>\n </th>\n )}</For>\n <Show when={props.actions}>\n <th scope=\"col\"><span class=\"dds-visually-hidden\">{props.labels.actions}</span></th>\n </Show>\n </tr>\n </thead>\n <tbody>\n <For each={ordered()}>{(row) => (\n <>\n <tr tabindex={props.selection ? 0 : undefined}\n aria-selected={props.selection ? props.selection.selectedId === props.selection.rowId(row) : undefined}\n onClick={event => { if (!interactive(event)) props.selection?.onSelect(row); }}\n onKeyDown={event => { if (props.selection && (event.key === \"Enter\" || event.key === \" \") && !interactive(event)) { event.preventDefault(); props.selection.onSelect(row); } }}>\n <For each={props.columns}>{(column) => (\n <Show\n when={column.rowHeader}\n fallback={<td data-fold={column.fold ? \"\" : undefined} data-numeric={column.numeric ? \"\" : undefined}>{column.cell(row)}</td>}\n >\n <th scope=\"row\" data-fold={column.fold ? \"\" : undefined} data-numeric={column.numeric ? \"\" : undefined}>{column.cell(row)}</th>\n </Show>\n )}</For>\n <Show when={props.actions}>{(actions) => <td><div class=\"dds-table__actions\">{actions()(row)}</div></td>}</Show>\n </tr>\n {/* Test the detail CONTENT, not the prop: a caller renders\n an expandable panel as\n `detail={(row) => expanded() === row.id ? <Panel/> : null}`,\n so a non-expanded row must produce no detail <tr> at\n all rather than a blank bordered one. */}\n <Show when={props.detail?.(row)}>{(node) => (\n <tr><td colSpan={props.columns.length + (props.actions ? 1 : 0)}>{node()}</td></tr>\n )}</Show>\n </>\n )}</For>\n </tbody>\n </table>\n </div>\n </Show>\n <nav class=\"dds-table__pagination\" hidden={!props.page?.nextHref} aria-label={props.labels.nextPage}>\n <Show when={props.page?.nextHref}>{(href) => <a class=\"dds-btn dds-btn--secondary\" href={href()}>{props.labels.nextPage}</a>}</Show>\n </nav>\n </>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,69 @@
1
1
  {
2
2
  "name": "@devslab/dds-table-solid",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.22.1",
4
+ "description": "Declarative data table for the DevsLab Design System",
5
+ "type": "module",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/devslab-kr/dds.git",
10
+ "directory": "packages/dds-table-solid"
11
+ },
12
+ "publishConfig": {
13
+ "registry": "https://registry.npmjs.org",
14
+ "access": "public",
15
+ "provenance": true
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "README.ko.md"
21
+ ],
22
+ "main": "./dist/index.js",
23
+ "types": "./dist/index.d.ts",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "worker": "./dist/server.js",
28
+ "workerd": "./dist/server.js",
29
+ "browser": "./dist/index.js",
30
+ "node": "./dist/server.js",
31
+ "default": "./dist/index.js"
32
+ }
33
+ },
34
+ "dependencies": {
35
+ "@devslab/dds-css": "0.22.1",
36
+ "@devslab/dds-tokens": "0.22.1",
37
+ "@tanstack/solid-table": "9.2.4"
38
+ },
39
+ "peerDependencies": {
40
+ "solid-js": "1.9.15"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "26.3.0",
44
+ "axe-core": "4.13.0",
45
+ "jsdom": "30.0.1",
46
+ "solid-js": "1.9.15",
47
+ "@testing-library/jest-dom": "6.9.1",
48
+ "typescript": "7.0.2",
49
+ "vite": "8.2.1",
50
+ "vite-plugin-solid": "2.11.14",
51
+ "vitest": "4.1.1"
52
+ },
53
+ "homepage": "https://devslab.kr/brand/",
54
+ "bugs": {
55
+ "url": "https://github.com/devslab-kr/dds/issues"
56
+ },
57
+ "keywords": [
58
+ "solidjs",
59
+ "table",
60
+ "design-system",
61
+ "devslab"
62
+ ],
63
+ "scripts": {
64
+ "build": "vite build && vite build --config vite.server.config.ts && tsc -p tsconfig.build.json --emitDeclarationOnly",
65
+ "check": "tsc -p tsconfig.json --noEmit",
66
+ "test": "vitest run --config vitest.config.ts && vitest run --config vitest.ssr.config.ts",
67
+ "test:a11y": "vitest run --config vitest.config.ts src/__tests__/a11y.test.tsx"
68
+ }
6
69
  }