@gridkitjs/react 0.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Blagoja Blazhevski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # @gridkitjs/react
2
+
3
+ React data-grid components built on
4
+ [`@gridkitjs/core`](https://www.npmjs.com/package/@gridkitjs/core).
5
+
6
+ > **Early development.** The API is still moving and may break between minor
7
+ > versions.
8
+
9
+ ```bash
10
+ pnpm add @gridkitjs/react
11
+ ```
12
+
13
+ ```tsx
14
+ import { defineColumnsFromRows } from "@gridkitjs/core";
15
+ import { DataGridComponent, type ColumnDefinition } from "@gridkitjs/react";
16
+
17
+ const rows = [
18
+ { Id: 1, Application: { Id: 9, Name: "Portal" }, Cost: 1250.5 },
19
+ { Id: 2, Application: { Id: 4, Name: "Admin" }, Cost: 87.25 },
20
+ ];
21
+
22
+ type Row = (typeof rows)[number];
23
+
24
+ const columns: readonly ColumnDefinition<Row>[] = [
25
+ ...defineColumnsFromRows(rows),
26
+ { field: "Cost", id: "Cost.currency", type: "currency", header: "Cost" },
27
+ ];
28
+
29
+ <DataGridComponent
30
+ dataSource={rows}
31
+ columns={columns}
32
+ resizableColumns
33
+ resizeMode="fit"
34
+ />;
35
+ ```
36
+
37
+ Columns can be inferred from the data or declared outright — a column's `type`
38
+ drives its default alignment. With `resizableColumns`, a column edge can be
39
+ dragged to resize or double-clicked to fit its content. `resizeMode="fit"`
40
+ keeps columns filling the grid; `"fixed"` lets each keep its own width.
41
+
42
+ Requires React 19.
43
+
44
+ Full documentation: [github.com/blagojablazhevski/gridkit](https://github.com/blagojablazhevski/gridkit#readme)
45
+
46
+ ## License
47
+
48
+ MIT © Blagoja Blazhevski
@@ -0,0 +1,59 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { ColumnDefinition as ColumnDefinition$1, ColumnSizingState, ColumnSizeDefaults, ColumnResizeEvent, ResolvedColumn as ResolvedColumn$1 } from '@gridkitjs/core';
4
+ export { ColumnResizeEvent, ColumnSizeDefaults, ColumnSizingState } from '@gridkitjs/core';
5
+
6
+ /**
7
+ * A column whose header may render arbitrary React content. @gridkitjs/core
8
+ * stays framework-agnostic and so leaves that output type open; this is the
9
+ * binding React consumers want, and the one they should import.
10
+ */
11
+ type ColumnDefinition<Row> = ColumnDefinition$1<Row, ReactNode>;
12
+ /** A column paired with the width it renders at. */
13
+ type ResolvedColumn<Row> = ResolvedColumn$1<Row, ReactNode>;
14
+ type Borders = "horizontal" | "vertical" | "all" | "none";
15
+ /**
16
+ * How a column's width relates to the grid's.
17
+ *
18
+ * `"fit"` keeps the columns filling the grid: the space a column gives up is
19
+ * handed to the others, and the space it takes comes out of them. `"fixed"`
20
+ * lets every column keep its own width, so a resize moves one column and
21
+ * nothing else, and the grid scrolls or leaves a gap accordingly.
22
+ */
23
+ type ResizeMode = "fit" | "fixed";
24
+ interface HoverableConfig {
25
+ rows?: boolean;
26
+ columns?: boolean;
27
+ cells?: boolean;
28
+ }
29
+ interface DataGridProps<Row> {
30
+ columns?: readonly ColumnDefinition<Row>[] | undefined;
31
+ dataSource?: readonly Row[] | undefined;
32
+ borders?: Borders | undefined;
33
+ hoverable?: HoverableConfig | undefined;
34
+ /** Whether columns can be dragged wider, unless a column says otherwise. */
35
+ resizableColumns?: boolean | undefined;
36
+ /**
37
+ * Whether columns fill the grid's width or sit at their own. Defaults to
38
+ * `"fit"`, under which columns the user has sized keep their width and the
39
+ * rest share what is left.
40
+ */
41
+ resizeMode?: ResizeMode | undefined;
42
+ /** Column widths to start from, keyed by column id. Uncontrolled. */
43
+ defaultColumnSizing?: ColumnSizingState | undefined;
44
+ /**
45
+ * Sizes applied to columns that do not set their own — the width they start
46
+ * at and the bounds they may be resized between. Distinct from
47
+ * `defaultColumnSizing`, which sets specific columns' starting widths.
48
+ */
49
+ columnSizeDefaults?: Partial<ColumnSizeDefaults> | undefined;
50
+ /**
51
+ * Called as the user resizes a column. Fires continuously with
52
+ * `phase: "move"` and once on release with `phase: "end"` — the latter being
53
+ * the one to persist. Auto-fit does not call it; it reports user intent only.
54
+ */
55
+ onColumnResize?: ((event: ColumnResizeEvent) => void) | undefined;
56
+ }
57
+ declare function DataGridComponent<Row>({ dataSource, columns, borders, hoverable, resizableColumns, resizeMode, defaultColumnSizing, columnSizeDefaults, onColumnResize, }: DataGridProps<Row>): react.JSX.Element;
58
+
59
+ export { type ColumnDefinition, DataGridComponent, type DataGridProps, type ResizeMode, type ResolvedColumn };
package/dist/index.js ADDED
@@ -0,0 +1,328 @@
1
+ // src/DataGrid/DataGrid.tsx
2
+ import { useMemo, useRef, useState as useState3 } from "react";
3
+ import {
4
+ defineColumnsFromRows,
5
+ fitColumnsToWidth,
6
+ resolveColumnWidths,
7
+ totalColumnWidth
8
+ } from "@gridkitjs/core";
9
+
10
+ // src/DataGrid/components/GridHeader.tsx
11
+ import { KEYBOARD_STEP } from "@gridkitjs/core";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ function GridHeader({
14
+ columns,
15
+ resize
16
+ }) {
17
+ return /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: "grid-header", children: columns.map((entry) => {
18
+ const { column } = entry;
19
+ const resizing = resize.activeColumnId === entry.id;
20
+ return /* @__PURE__ */ jsxs(
21
+ "th",
22
+ {
23
+ "data-gridkit-column": entry.id,
24
+ className: resizing ? "header-cell is-resizing" : "header-cell",
25
+ children: [
26
+ entry.label,
27
+ entry.resizable && /* @__PURE__ */ jsx(
28
+ "span",
29
+ {
30
+ className: "header-resize-handle",
31
+ role: "separator",
32
+ "aria-orientation": "vertical",
33
+ "aria-label": `Resize ${column.field}`,
34
+ tabIndex: 0,
35
+ onPointerDown: (event) => {
36
+ resize.startResize(entry, event);
37
+ },
38
+ onDoubleClick: () => {
39
+ resize.sizeToContent(entry);
40
+ },
41
+ onKeyDown: (event) => {
42
+ if (event.key !== "ArrowLeft" && event.key !== "ArrowRight")
43
+ return;
44
+ event.preventDefault();
45
+ resize.nudge(
46
+ entry,
47
+ event.key === "ArrowLeft" ? -KEYBOARD_STEP : KEYBOARD_STEP
48
+ );
49
+ },
50
+ children: /* @__PURE__ */ jsxs(
51
+ "svg",
52
+ {
53
+ className: "header-resize-grip",
54
+ viewBox: "0 0 6 14",
55
+ width: "6",
56
+ height: "14",
57
+ "aria-hidden": "true",
58
+ children: [
59
+ /* @__PURE__ */ jsx("circle", { cx: "1.5", cy: "4", r: "1" }),
60
+ /* @__PURE__ */ jsx("circle", { cx: "1.5", cy: "7", r: "1" }),
61
+ /* @__PURE__ */ jsx("circle", { cx: "1.5", cy: "10", r: "1" }),
62
+ /* @__PURE__ */ jsx("circle", { cx: "4.5", cy: "4", r: "1" }),
63
+ /* @__PURE__ */ jsx("circle", { cx: "4.5", cy: "7", r: "1" }),
64
+ /* @__PURE__ */ jsx("circle", { cx: "4.5", cy: "10", r: "1" })
65
+ ]
66
+ }
67
+ )
68
+ }
69
+ )
70
+ ]
71
+ },
72
+ entry.id
73
+ );
74
+ }) }) });
75
+ }
76
+
77
+ // src/DataGrid/components/GridBody.tsx
78
+ import { accessDotted } from "@gridkitjs/core";
79
+ import "react";
80
+ import { jsx as jsx2 } from "react/jsx-runtime";
81
+ function GridBody({
82
+ columns,
83
+ dataSource,
84
+ activeColumnId
85
+ }) {
86
+ return /* @__PURE__ */ jsx2("tbody", { className: "grid-body", children: dataSource?.map((row, index) => /* @__PURE__ */ jsx2("tr", { className: "grid-row", children: columns.map(({ id, column, alignment }) => /* @__PURE__ */ jsx2(
87
+ "td",
88
+ {
89
+ "data-gridkit-column": id,
90
+ className: id === activeColumnId ? "grid-cell is-resizing" : "grid-cell",
91
+ style: { textAlign: alignment },
92
+ children: accessDotted(row, column.field)
93
+ },
94
+ id
95
+ )) }, index)) });
96
+ }
97
+
98
+ // src/DataGrid/useColumnResize.ts
99
+ import {
100
+ useState
101
+ } from "react";
102
+ import {
103
+ applyColumnResize,
104
+ beginColumnResize,
105
+ clampColumnWidth,
106
+ resolveColumnConstraints,
107
+ sizeColumnToContent
108
+ } from "@gridkitjs/core";
109
+
110
+ // src/DataGrid/measureColumnContent.ts
111
+ function measureColumnContent(table, columnId) {
112
+ const cells = table.querySelectorAll(
113
+ `[data-gridkit-column="${CSS.escape(columnId)}"]`
114
+ );
115
+ const range = document.createRange();
116
+ let widest = null;
117
+ for (const cell of cells) {
118
+ range.selectNodeContents(cell);
119
+ const style = getComputedStyle(cell);
120
+ const width = range.getBoundingClientRect().width + parseFloat(style.paddingLeft) + parseFloat(style.paddingRight) + parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
121
+ if (widest === null || width > widest) {
122
+ widest = width;
123
+ }
124
+ }
125
+ return widest;
126
+ }
127
+
128
+ // src/DataGrid/useColumnResize.ts
129
+ function useColumnResize({
130
+ tableRef,
131
+ sizing,
132
+ setSizing,
133
+ columnSizeDefaults,
134
+ onColumnResize
135
+ }) {
136
+ const [activeColumnId, setActiveColumnId] = useState(null);
137
+ function commit(base, columnId, width, phase) {
138
+ const next = { ...base, [columnId]: width };
139
+ setSizing(next);
140
+ onColumnResize?.({ columnId, width, sizing: next, phase });
141
+ }
142
+ function startResize(entry, event) {
143
+ const handle = event.currentTarget;
144
+ const { pointerId } = event;
145
+ const session = beginColumnResize(
146
+ entry.column,
147
+ entry.width,
148
+ event.clientX,
149
+ columnSizeDefaults
150
+ );
151
+ const base = sizing;
152
+ let width = session.startWidth;
153
+ event.preventDefault();
154
+ event.stopPropagation();
155
+ handle.setPointerCapture(pointerId);
156
+ setActiveColumnId(session.columnId);
157
+ function move(moveEvent) {
158
+ width = applyColumnResize(session, moveEvent.clientX);
159
+ commit(base, session.columnId, width, "move");
160
+ }
161
+ function stop() {
162
+ handle.removeEventListener("pointermove", move);
163
+ handle.removeEventListener("pointerup", end);
164
+ handle.removeEventListener("pointercancel", cancel);
165
+ window.removeEventListener("keydown", onKeyDown);
166
+ if (handle.hasPointerCapture(pointerId)) {
167
+ handle.releasePointerCapture(pointerId);
168
+ }
169
+ setActiveColumnId(null);
170
+ }
171
+ function end() {
172
+ stop();
173
+ commit(base, session.columnId, width, "end");
174
+ }
175
+ function cancel() {
176
+ stop();
177
+ setSizing(base);
178
+ onColumnResize?.({
179
+ columnId: session.columnId,
180
+ width: session.startWidth,
181
+ sizing: base,
182
+ phase: "end"
183
+ });
184
+ }
185
+ function onKeyDown(keyEvent) {
186
+ if (keyEvent.key === "Escape") {
187
+ cancel();
188
+ }
189
+ }
190
+ handle.addEventListener("pointermove", move);
191
+ handle.addEventListener("pointerup", end);
192
+ handle.addEventListener("pointercancel", cancel);
193
+ window.addEventListener("keydown", onKeyDown);
194
+ }
195
+ function sizeToContent(entry) {
196
+ const table = tableRef.current;
197
+ if (table === null) {
198
+ return;
199
+ }
200
+ const measured = measureColumnContent(table, entry.id);
201
+ if (measured === null) {
202
+ return;
203
+ }
204
+ commit(
205
+ sizing,
206
+ entry.id,
207
+ sizeColumnToContent(
208
+ measured,
209
+ resolveColumnConstraints(entry.column, columnSizeDefaults)
210
+ ),
211
+ "end"
212
+ );
213
+ }
214
+ function nudge(entry, delta) {
215
+ commit(
216
+ sizing,
217
+ entry.id,
218
+ clampColumnWidth(
219
+ entry.width + delta,
220
+ resolveColumnConstraints(entry.column, columnSizeDefaults)
221
+ ),
222
+ "end"
223
+ );
224
+ }
225
+ return { activeColumnId, startResize, sizeToContent, nudge };
226
+ }
227
+
228
+ // src/DataGrid/useElementWidth.ts
229
+ import { useLayoutEffect, useState as useState2 } from "react";
230
+ function useElementWidth(ref, enabled) {
231
+ const [width, setWidth] = useState2(null);
232
+ useLayoutEffect(() => {
233
+ const element = ref.current;
234
+ if (element === null || !enabled) {
235
+ return void 0;
236
+ }
237
+ setWidth(element.clientWidth);
238
+ const observer = new ResizeObserver(() => {
239
+ setWidth(element.clientWidth);
240
+ });
241
+ observer.observe(element);
242
+ return () => {
243
+ observer.disconnect();
244
+ };
245
+ }, [ref, enabled]);
246
+ return width;
247
+ }
248
+
249
+ // src/DataGrid/DataGrid.tsx
250
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
251
+ function DataGridComponent({
252
+ dataSource,
253
+ columns,
254
+ borders,
255
+ hoverable,
256
+ resizableColumns = false,
257
+ resizeMode = "fit",
258
+ defaultColumnSizing,
259
+ columnSizeDefaults,
260
+ onColumnResize
261
+ }) {
262
+ const hoverRows = hoverable?.rows ?? true;
263
+ const hoverColumns = hoverable?.columns ?? true;
264
+ const hoverCells = hoverable?.cells ?? true;
265
+ const viewportRef = useRef(null);
266
+ const tableRef = useRef(null);
267
+ const viewportWidth = useElementWidth(viewportRef, resizeMode === "fit");
268
+ const [sizing, setSizing] = useState3(
269
+ defaultColumnSizing ?? {}
270
+ );
271
+ const definedColumns = useMemo(() => {
272
+ if (columns && columns.length !== 0) return columns;
273
+ if (dataSource && dataSource.length > 0)
274
+ return defineColumnsFromRows(dataSource);
275
+ return [];
276
+ }, [columns, dataSource]);
277
+ const resolved = useMemo(() => {
278
+ const widths = resolveColumnWidths(definedColumns, sizing, {
279
+ sizes: columnSizeDefaults,
280
+ resizable: resizableColumns
281
+ });
282
+ return resizeMode === "fit" && viewportWidth !== null ? fitColumnsToWidth(widths, viewportWidth, columnSizeDefaults) : widths;
283
+ }, [
284
+ definedColumns,
285
+ sizing,
286
+ resizeMode,
287
+ viewportWidth,
288
+ columnSizeDefaults,
289
+ resizableColumns
290
+ ]);
291
+ const resize = useColumnResize({
292
+ tableRef,
293
+ sizing,
294
+ setSizing,
295
+ columnSizeDefaults,
296
+ onColumnResize
297
+ });
298
+ return /* @__PURE__ */ jsx3("div", { className: "gridkit-data-grid-viewport", ref: viewportRef, children: /* @__PURE__ */ jsxs2(
299
+ "table",
300
+ {
301
+ ref: tableRef,
302
+ style: { width: totalColumnWidth(resolved) },
303
+ className: [
304
+ "gridkit-data-grid",
305
+ borders ? `borders-${borders}` : "",
306
+ hoverRows ? "" : "no-hover-rows",
307
+ hoverColumns ? "" : "no-hover-columns",
308
+ hoverCells ? "" : "no-hover-cells"
309
+ ].filter(Boolean).join(" "),
310
+ children: [
311
+ /* @__PURE__ */ jsx3("colgroup", { children: resolved.map((entry) => /* @__PURE__ */ jsx3("col", { style: { width: entry.width } }, entry.id)) }),
312
+ /* @__PURE__ */ jsx3(GridHeader, { columns: resolved, resize }),
313
+ /* @__PURE__ */ jsx3(
314
+ GridBody,
315
+ {
316
+ columns: resolved,
317
+ dataSource,
318
+ activeColumnId: resize.activeColumnId
319
+ }
320
+ )
321
+ ]
322
+ }
323
+ ) });
324
+ }
325
+ export {
326
+ DataGridComponent
327
+ };
328
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/DataGrid/DataGrid.tsx","../src/DataGrid/components/GridHeader.tsx","../src/DataGrid/components/GridBody.tsx","../src/DataGrid/useColumnResize.ts","../src/DataGrid/measureColumnContent.ts","../src/DataGrid/useElementWidth.ts"],"sourcesContent":["import { useMemo, useRef, useState, type ReactNode } from \"react\";\nimport {\n defineColumnsFromRows,\n fitColumnsToWidth,\n resolveColumnWidths,\n totalColumnWidth,\n type ColumnDefinition as CoreColumnDefinition,\n type ResolvedColumn as CoreResolvedColumn,\n type ColumnResizeEvent,\n type ColumnSizeDefaults,\n type ColumnSizingState,\n} from \"@gridkitjs/core\";\nimport GridHeader from \"./components/GridHeader\";\nimport GridBody from \"./components/GridBody\";\nimport useColumnResize from \"./useColumnResize\";\nimport useElementWidth from \"./useElementWidth\";\n\n/**\n * A column whose header may render arbitrary React content. @gridkitjs/core\n * stays framework-agnostic and so leaves that output type open; this is the\n * binding React consumers want, and the one they should import.\n */\nexport type ColumnDefinition<Row> = CoreColumnDefinition<Row, ReactNode>;\n\n/** A column paired with the width it renders at. */\nexport type ResolvedColumn<Row> = CoreResolvedColumn<Row, ReactNode>;\n\nexport type Borders = \"horizontal\" | \"vertical\" | \"all\" | \"none\";\n\n/**\n * How a column's width relates to the grid's.\n *\n * `\"fit\"` keeps the columns filling the grid: the space a column gives up is\n * handed to the others, and the space it takes comes out of them. `\"fixed\"`\n * lets every column keep its own width, so a resize moves one column and\n * nothing else, and the grid scrolls or leaves a gap accordingly.\n */\nexport type ResizeMode = \"fit\" | \"fixed\";\n\nexport interface HoverableConfig {\n rows?: boolean;\n columns?: boolean;\n cells?: boolean;\n}\n\nexport interface DataGridProps<Row> {\n columns?: readonly ColumnDefinition<Row>[] | undefined;\n dataSource?: readonly Row[] | undefined;\n borders?: Borders | undefined;\n hoverable?: HoverableConfig | undefined;\n /** Whether columns can be dragged wider, unless a column says otherwise. */\n resizableColumns?: boolean | undefined;\n /**\n * Whether columns fill the grid's width or sit at their own. Defaults to\n * `\"fit\"`, under which columns the user has sized keep their width and the\n * rest share what is left.\n */\n resizeMode?: ResizeMode | undefined;\n /** Column widths to start from, keyed by column id. Uncontrolled. */\n defaultColumnSizing?: ColumnSizingState | undefined;\n /**\n * Sizes applied to columns that do not set their own — the width they start\n * at and the bounds they may be resized between. Distinct from\n * `defaultColumnSizing`, which sets specific columns' starting widths.\n */\n columnSizeDefaults?: Partial<ColumnSizeDefaults> | undefined;\n /**\n * Called as the user resizes a column. Fires continuously with\n * `phase: \"move\"` and once on release with `phase: \"end\"` — the latter being\n * the one to persist. Auto-fit does not call it; it reports user intent only.\n */\n onColumnResize?: ((event: ColumnResizeEvent) => void) | undefined;\n}\n\nexport function DataGridComponent<Row>({\n dataSource,\n columns,\n borders,\n hoverable,\n resizableColumns = false,\n resizeMode = \"fit\",\n defaultColumnSizing,\n columnSizeDefaults,\n onColumnResize,\n}: DataGridProps<Row>) {\n const hoverRows = hoverable?.rows ?? true;\n const hoverColumns = hoverable?.columns ?? true;\n const hoverCells = hoverable?.cells ?? true;\n\n const viewportRef = useRef<HTMLDivElement>(null);\n const tableRef = useRef<HTMLTableElement>(null);\n const viewportWidth = useElementWidth(viewportRef, resizeMode === \"fit\");\n const [sizing, setSizing] = useState<ColumnSizingState>(\n defaultColumnSizing ?? {},\n );\n\n const definedColumns = useMemo<readonly ColumnDefinition<Row>[]>(() => {\n if (columns && columns.length !== 0) return columns;\n if (dataSource && dataSource.length > 0)\n return defineColumnsFromRows(dataSource);\n return [];\n }, [columns, dataSource]);\n\n /**\n * Auto-fit is a derivation rather than a write back into `sizing`, so that a\n * `width` set in a column definition is never overwritten and the effect\n * cannot chase its own output. `\"fixed\"` is then simply the absence of it.\n */\n const resolved = useMemo(() => {\n const widths = resolveColumnWidths(definedColumns, sizing, {\n sizes: columnSizeDefaults,\n resizable: resizableColumns,\n });\n return resizeMode === \"fit\" && viewportWidth !== null\n ? fitColumnsToWidth(widths, viewportWidth, columnSizeDefaults)\n : widths;\n }, [\n definedColumns,\n sizing,\n resizeMode,\n viewportWidth,\n columnSizeDefaults,\n resizableColumns,\n ]);\n\n const resize = useColumnResize<Row>({\n tableRef,\n sizing,\n setSizing,\n columnSizeDefaults,\n onColumnResize,\n });\n\n return (\n <div className=\"gridkit-data-grid-viewport\" ref={viewportRef}>\n <table\n ref={tableRef}\n // Widths are only honoured exactly when the table is as wide as its\n // columns; at `100%` the fixed layout redistributes the difference.\n style={{ width: totalColumnWidth(resolved) }}\n className={[\n \"gridkit-data-grid\",\n borders ? `borders-${borders}` : \"\",\n hoverRows ? \"\" : \"no-hover-rows\",\n hoverColumns ? \"\" : \"no-hover-columns\",\n hoverCells ? \"\" : \"no-hover-cells\",\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n <colgroup>\n {resolved.map((entry) => (\n <col key={entry.id} style={{ width: entry.width }} />\n ))}\n </colgroup>\n <GridHeader<Row> columns={resolved} resize={resize} />\n <GridBody<Row>\n columns={resolved}\n dataSource={dataSource}\n activeColumnId={resize.activeColumnId}\n />\n </table>\n </div>\n );\n}\n","import { KEYBOARD_STEP } from \"@gridkitjs/core\";\nimport type { ResolvedColumn } from \"../DataGrid\";\nimport type { ColumnResizeApi } from \"../useColumnResize\";\n\ninterface GridHeaderProps<Row> {\n columns: readonly ResolvedColumn<Row>[];\n resize: ColumnResizeApi<Row>;\n}\n\nexport default function GridHeader<Row>({\n columns,\n resize,\n}: GridHeaderProps<Row>) {\n return (\n <thead>\n <tr className=\"grid-header\">\n {columns.map((entry) => {\n const { column } = entry;\n const resizing = resize.activeColumnId === entry.id;\n\n return (\n <th\n key={entry.id}\n data-gridkit-column={entry.id}\n className={resizing ? \"header-cell is-resizing\" : \"header-cell\"}\n >\n {entry.label}\n {entry.resizable && (\n <span\n className=\"header-resize-handle\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={`Resize ${column.field}`}\n tabIndex={0}\n onPointerDown={(event) => {\n resize.startResize(entry, event);\n }}\n onDoubleClick={() => {\n resize.sizeToContent(entry);\n }}\n onKeyDown={(event) => {\n if (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\")\n return;\n event.preventDefault();\n resize.nudge(\n entry,\n event.key === \"ArrowLeft\"\n ? -KEYBOARD_STEP\n : KEYBOARD_STEP,\n );\n }}\n >\n <svg\n className=\"header-resize-grip\"\n viewBox=\"0 0 6 14\"\n width=\"6\"\n height=\"14\"\n aria-hidden=\"true\"\n >\n <circle cx=\"1.5\" cy=\"4\" r=\"1\" />\n <circle cx=\"1.5\" cy=\"7\" r=\"1\" />\n <circle cx=\"1.5\" cy=\"10\" r=\"1\" />\n <circle cx=\"4.5\" cy=\"4\" r=\"1\" />\n <circle cx=\"4.5\" cy=\"7\" r=\"1\" />\n <circle cx=\"4.5\" cy=\"10\" r=\"1\" />\n </svg>\n </span>\n )}\n </th>\n );\n })}\n </tr>\n </thead>\n );\n}\n","import { accessDotted } from \"@gridkitjs/core\";\nimport { type ReactNode } from \"react\";\nimport type { ResolvedColumn } from \"../DataGrid\";\n\ninterface GridBodyProps<Row> {\n columns: readonly ResolvedColumn<Row>[];\n dataSource?: readonly Row[] | undefined;\n /** The column being resized, so its cells outline with its header. */\n activeColumnId: string | null;\n}\n\nexport default function GridBody<Row>({\n columns,\n dataSource,\n activeColumnId,\n}: GridBodyProps<Row>) {\n return (\n <tbody className=\"grid-body\">\n {dataSource?.map((row, index) => (\n <tr key={index} className=\"grid-row\">\n {columns.map(({ id, column, alignment }) => (\n <td\n key={id}\n data-gridkit-column={id}\n className={\n id === activeColumnId ? \"grid-cell is-resizing\" : \"grid-cell\"\n }\n style={{ textAlign: alignment }}\n >\n {accessDotted(row, column.field) as ReactNode}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n );\n}\n","import {\n useState,\n type Dispatch,\n type PointerEvent as ReactPointerEvent,\n type RefObject,\n type SetStateAction,\n} from \"react\";\nimport {\n applyColumnResize,\n beginColumnResize,\n clampColumnWidth,\n resolveColumnConstraints,\n sizeColumnToContent,\n type ColumnResizeEvent,\n type ColumnSizeDefaults,\n type ColumnSizingState,\n} from \"@gridkitjs/core\";\nimport type { ResolvedColumn } from \"./DataGrid\";\nimport measureColumnContent from \"./measureColumnContent\";\n\ninterface UseColumnResizeOptions {\n tableRef: RefObject<HTMLTableElement | null>;\n sizing: ColumnSizingState;\n setSizing: Dispatch<SetStateAction<ColumnSizingState>>;\n columnSizeDefaults?: Partial<ColumnSizeDefaults> | undefined;\n onColumnResize?: ((event: ColumnResizeEvent) => void) | undefined;\n}\n\nexport interface ColumnResizeApi<Row> {\n /** The column being dragged, for as long as the drag lasts. */\n activeColumnId: string | null;\n startResize: (\n entry: ResolvedColumn<Row>,\n event: ReactPointerEvent<HTMLElement>,\n ) => void;\n sizeToContent: (entry: ResolvedColumn<Row>) => void;\n nudge: (entry: ResolvedColumn<Row>, delta: number) => void;\n}\n\n/**\n * Turns pointer and keyboard input into column widths. Every width it produces\n * comes from `@gridkitjs/core`; this hook only supplies the coordinates.\n */\nexport default function useColumnResize<Row>({\n tableRef,\n sizing,\n setSizing,\n columnSizeDefaults,\n onColumnResize,\n}: UseColumnResizeOptions): ColumnResizeApi<Row> {\n const [activeColumnId, setActiveColumnId] = useState<string | null>(null);\n\n function commit(\n base: ColumnSizingState,\n columnId: string,\n width: number,\n phase: \"move\" | \"end\",\n ): void {\n const next = { ...base, [columnId]: width };\n setSizing(next);\n onColumnResize?.({ columnId, width, sizing: next, phase });\n }\n\n function startResize(\n entry: ResolvedColumn<Row>,\n event: ReactPointerEvent<HTMLElement>,\n ): void {\n const handle = event.currentTarget;\n const { pointerId } = event;\n const session = beginColumnResize(\n entry.column,\n entry.width,\n event.clientX,\n columnSizeDefaults,\n );\n /**\n * Only the dragged column can change while the drag lasts, so the state as\n * it was when the drag opened stays a correct base to merge into — no ref\n * mirror is needed to dodge a stale closure.\n */\n const base = sizing;\n let width = session.startWidth;\n\n // Otherwise the drag selects the header text it started on.\n event.preventDefault();\n event.stopPropagation();\n handle.setPointerCapture(pointerId);\n setActiveColumnId(session.columnId);\n\n function move(moveEvent: PointerEvent): void {\n width = applyColumnResize(session, moveEvent.clientX);\n commit(base, session.columnId, width, \"move\");\n }\n\n function stop(): void {\n handle.removeEventListener(\"pointermove\", move);\n handle.removeEventListener(\"pointerup\", end);\n handle.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"keydown\", onKeyDown);\n if (handle.hasPointerCapture(pointerId)) {\n handle.releasePointerCapture(pointerId);\n }\n setActiveColumnId(null);\n }\n\n function end(): void {\n stop();\n commit(base, session.columnId, width, \"end\");\n }\n\n /**\n * Escape puts back the state the drag started from, which correctly covers\n * a column that had no stored width at all — merging `startWidth` back in\n * would instead leave it pinned and hidden from auto-fit.\n */\n function cancel(): void {\n stop();\n setSizing(base);\n onColumnResize?.({\n columnId: session.columnId,\n width: session.startWidth,\n sizing: base,\n phase: \"end\",\n });\n }\n\n function onKeyDown(keyEvent: KeyboardEvent): void {\n if (keyEvent.key === \"Escape\") {\n cancel();\n }\n }\n\n handle.addEventListener(\"pointermove\", move);\n handle.addEventListener(\"pointerup\", end);\n handle.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"keydown\", onKeyDown);\n }\n\n function sizeToContent(entry: ResolvedColumn<Row>): void {\n const table = tableRef.current;\n if (table === null) {\n return;\n }\n\n const measured = measureColumnContent(table, entry.id);\n if (measured === null) {\n return;\n }\n\n commit(\n sizing,\n entry.id,\n sizeColumnToContent(\n measured,\n resolveColumnConstraints(entry.column, columnSizeDefaults),\n ),\n \"end\",\n );\n }\n\n function nudge(entry: ResolvedColumn<Row>, delta: number): void {\n commit(\n sizing,\n entry.id,\n clampColumnWidth(\n entry.width + delta,\n resolveColumnConstraints(entry.column, columnSizeDefaults),\n ),\n \"end\",\n );\n }\n\n // Deliberately a new object each render: the handlers close over `sizing` to\n // merge into, and a stable identity would need either `sizing` in a\n // `useCallback` dep list (no gain) or the ref mirror avoided above.\n return { activeColumnId, startResize, sizeToContent, nudge };\n}\n","/**\n * The width the widest cell in `columnId` needs to show its content in full,\n * or `null` when the column has no cells.\n *\n * Measured with a `Range` over each cell's contents rather than the cell's own\n * `scrollWidth`. A range shrink-wraps what is actually laid out, so a column\n * far wider than its content reports the content width and can be sized *down*;\n * `scrollWidth` never reports less than the cell it is read from and so can\n * only ever grow a column.\n *\n * Only rendered rows are measured — once paging or virtualisation lands, that\n * means the visible ones.\n */\nexport default function measureColumnContent(\n table: HTMLTableElement,\n columnId: string,\n): number | null {\n const cells = table.querySelectorAll<HTMLElement>(\n `[data-gridkit-column=\"${CSS.escape(columnId)}\"]`,\n );\n const range = document.createRange();\n let widest: number | null = null;\n\n for (const cell of cells) {\n range.selectNodeContents(cell);\n const style = getComputedStyle(cell);\n // The range covers the content box only, so the cell's own spacing has to\n // be added back or the column would clip by exactly its padding.\n const width =\n range.getBoundingClientRect().width +\n parseFloat(style.paddingLeft) +\n parseFloat(style.paddingRight) +\n parseFloat(style.borderLeftWidth) +\n parseFloat(style.borderRightWidth);\n\n if (widest === null || width > widest) {\n widest = width;\n }\n }\n\n return widest;\n}\n","import { useLayoutEffect, useState, type RefObject } from \"react\";\n\n/**\n * The inner width of `ref`'s element, tracked as it changes.\n *\n * A layout effect rather than an effect so the first measurement lands before\n * paint — otherwise columns show at their natural width for a frame and then\n * visibly jump once auto-fit runs. Server rendering would want the usual\n * isomorphic-layout-effect shim here.\n *\n * Reads `clientWidth` rather than the observer entry's `contentRect` so the\n * first measurement and every later one come from the same, already-rounded,\n * source.\n *\n * @param enabled Whether to observe at all. A caller that does not read the\n * width passes `false` rather than paying a re-render of the whole grid on\n * every frame of a window resize.\n */\nexport default function useElementWidth(\n ref: RefObject<HTMLElement | null>,\n enabled: boolean,\n): number | null {\n const [width, setWidth] = useState<number | null>(null);\n\n useLayoutEffect(() => {\n const element = ref.current;\n if (element === null || !enabled) {\n return undefined;\n }\n\n setWidth(element.clientWidth);\n\n const observer = new ResizeObserver(() => {\n setWidth(element.clientWidth);\n });\n observer.observe(element);\n\n return () => {\n observer.disconnect();\n };\n }, [ref, enabled]);\n\n return width;\n}\n"],"mappings":"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","names":["useState","jsx","useState","jsx","jsxs","useState"]}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@gridkitjs/react",
3
+ "version": "0.0.1",
4
+ "description": "React data-grid components built on @gridkitjs/core.",
5
+ "license": "MIT",
6
+ "author": "Blagoja Blazhevski",
7
+ "homepage": "https://github.com/blagojablazhevski/gridkit#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/blagojablazhevski/gridkit.git",
11
+ "directory": "packages/react"
12
+ },
13
+ "keywords": [
14
+ "datagrid",
15
+ "grid",
16
+ "table",
17
+ "react",
18
+ "headless",
19
+ "typescript"
20
+ ],
21
+ "type": "module",
22
+ "engines": {
23
+ "node": ">=22"
24
+ },
25
+ "main": "./src/index.ts",
26
+ "types": "./src/index.ts",
27
+ "exports": {
28
+ ".": "./src/index.ts"
29
+ },
30
+ "publishConfig": {
31
+ "main": "./dist/index.js",
32
+ "types": "./dist/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js"
37
+ }
38
+ }
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "LICENSE",
43
+ "README.md"
44
+ ],
45
+ "scripts": {
46
+ "build": "tsup",
47
+ "typecheck": "tsc --noEmit",
48
+ "lint": "eslint src",
49
+ "test": "vitest run --passWithNoTests"
50
+ },
51
+ "peerDependencies": {
52
+ "react": "^19.0.0",
53
+ "react-dom": "^19.0.0"
54
+ },
55
+ "dependencies": {
56
+ "@gridkitjs/core": "workspace:*"
57
+ },
58
+ "devDependencies": {
59
+ "@types/react": "^19.2.18",
60
+ "@types/react-dom": "^19.2.4",
61
+ "react": "^19.2.8",
62
+ "react-dom": "^19.2.8",
63
+ "tsup": "^8.5.1",
64
+ "typescript": "^6.0.3",
65
+ "vitest": "^4.1.10"
66
+ }
67
+ }