virtualized-ui 0.0.1 → 0.1.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/README.md +192 -0
- package/dist/index.cjs +477 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +120 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +471 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -4
- package/CLAUDE.MD +0 -54
- package/LICENSE +0 -21
package/dist/index.js
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import { useRef, useMemo, useState, useCallback } from 'react';
|
|
2
|
+
import { useReactTable, getExpandedRowModel, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
|
|
3
|
+
export { createColumnHelper } from '@tanstack/react-table';
|
|
4
|
+
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
5
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
// src/VirtualTable/VirtualTable.tsx
|
|
8
|
+
var DEFAULT_ROW_HEIGHT = 40;
|
|
9
|
+
var DEFAULT_EXPANDED_ROW_HEIGHT = 200;
|
|
10
|
+
var DEFAULT_OVERSCAN = 5;
|
|
11
|
+
var DEFAULT_SCROLL_THRESHOLD = 100;
|
|
12
|
+
function getColumnId(column) {
|
|
13
|
+
if ("id" in column && typeof column.id === "string") {
|
|
14
|
+
return column.id;
|
|
15
|
+
}
|
|
16
|
+
if ("accessorKey" in column && typeof column.accessorKey === "string") {
|
|
17
|
+
return column.accessorKey;
|
|
18
|
+
}
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
function useVirtualTable(options) {
|
|
22
|
+
const {
|
|
23
|
+
data,
|
|
24
|
+
columns,
|
|
25
|
+
rowHeight = DEFAULT_ROW_HEIGHT,
|
|
26
|
+
overscan = DEFAULT_OVERSCAN,
|
|
27
|
+
enableRowSelection = false,
|
|
28
|
+
rowSelection: controlledRowSelection,
|
|
29
|
+
onRowSelectionChange,
|
|
30
|
+
enableSorting = false,
|
|
31
|
+
sorting: controlledSorting,
|
|
32
|
+
onSortingChange,
|
|
33
|
+
enableMultiSort = false,
|
|
34
|
+
maxMultiSortColCount,
|
|
35
|
+
enableColumnResizing = false,
|
|
36
|
+
columnResizeMode = "onChange",
|
|
37
|
+
columnSizing: controlledColumnSizing,
|
|
38
|
+
onColumnSizingChange,
|
|
39
|
+
enableColumnReordering = false,
|
|
40
|
+
columnOrder: controlledColumnOrder,
|
|
41
|
+
onColumnOrderChange,
|
|
42
|
+
enableRowExpansion = false,
|
|
43
|
+
expanded: controlledExpanded,
|
|
44
|
+
onExpandedChange,
|
|
45
|
+
expandedRowHeight = DEFAULT_EXPANDED_ROW_HEIGHT,
|
|
46
|
+
getRowCanExpand,
|
|
47
|
+
getRowId,
|
|
48
|
+
enableKeyboardNavigation = false,
|
|
49
|
+
focusedRowIndex: controlledFocusedRowIndex,
|
|
50
|
+
onFocusedRowChange,
|
|
51
|
+
onScrollToBottom,
|
|
52
|
+
scrollBottomThreshold = DEFAULT_SCROLL_THRESHOLD
|
|
53
|
+
} = options;
|
|
54
|
+
const containerRef = useRef(null);
|
|
55
|
+
const defaultColumnOrder = useMemo(() => columns.map(getColumnId), [columns]);
|
|
56
|
+
const [internalRowSelection, setInternalRowSelection] = useState({});
|
|
57
|
+
const [internalSorting, setInternalSorting] = useState([]);
|
|
58
|
+
const [internalExpanded, setInternalExpanded] = useState({});
|
|
59
|
+
const [internalColumnSizing, setInternalColumnSizing] = useState({});
|
|
60
|
+
const [internalColumnOrder, setInternalColumnOrder] = useState([]);
|
|
61
|
+
const [internalFocusedRowIndex, setInternalFocusedRowIndex] = useState(-1);
|
|
62
|
+
const rowSelectionState = controlledRowSelection ?? internalRowSelection;
|
|
63
|
+
const sortingState = controlledSorting ?? internalSorting;
|
|
64
|
+
const expandedState = controlledExpanded ?? internalExpanded;
|
|
65
|
+
const columnSizingState = controlledColumnSizing ?? internalColumnSizing;
|
|
66
|
+
const columnOrderState = controlledColumnOrder ?? (internalColumnOrder.length ? internalColumnOrder : defaultColumnOrder);
|
|
67
|
+
const focusedRowIndex = controlledFocusedRowIndex ?? internalFocusedRowIndex;
|
|
68
|
+
const handleRowSelectionChange = useCallback(
|
|
69
|
+
(updater) => {
|
|
70
|
+
const newValue = typeof updater === "function" ? updater(rowSelectionState) : updater;
|
|
71
|
+
if (onRowSelectionChange) {
|
|
72
|
+
onRowSelectionChange(newValue);
|
|
73
|
+
} else {
|
|
74
|
+
setInternalRowSelection(newValue);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
[rowSelectionState, onRowSelectionChange]
|
|
78
|
+
);
|
|
79
|
+
const handleSortingChange = useCallback(
|
|
80
|
+
(updater) => {
|
|
81
|
+
const newValue = typeof updater === "function" ? updater(sortingState) : updater;
|
|
82
|
+
if (onSortingChange) {
|
|
83
|
+
onSortingChange(newValue);
|
|
84
|
+
} else {
|
|
85
|
+
setInternalSorting(newValue);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
[sortingState, onSortingChange]
|
|
89
|
+
);
|
|
90
|
+
const handleExpandedChange = useCallback(
|
|
91
|
+
(updater) => {
|
|
92
|
+
const newValue = typeof updater === "function" ? updater(expandedState) : updater;
|
|
93
|
+
if (onExpandedChange) {
|
|
94
|
+
onExpandedChange(newValue);
|
|
95
|
+
} else {
|
|
96
|
+
setInternalExpanded(newValue);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
[expandedState, onExpandedChange]
|
|
100
|
+
);
|
|
101
|
+
const handleColumnSizingChange = useCallback(
|
|
102
|
+
(updater) => {
|
|
103
|
+
const newValue = typeof updater === "function" ? updater(columnSizingState) : updater;
|
|
104
|
+
if (onColumnSizingChange) {
|
|
105
|
+
onColumnSizingChange(newValue);
|
|
106
|
+
} else {
|
|
107
|
+
setInternalColumnSizing(newValue);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
[columnSizingState, onColumnSizingChange]
|
|
111
|
+
);
|
|
112
|
+
const handleColumnOrderChange = useCallback(
|
|
113
|
+
(updater) => {
|
|
114
|
+
const newValue = typeof updater === "function" ? updater(columnOrderState) : updater;
|
|
115
|
+
if (onColumnOrderChange) {
|
|
116
|
+
onColumnOrderChange(newValue);
|
|
117
|
+
} else {
|
|
118
|
+
setInternalColumnOrder(newValue);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
[columnOrderState, onColumnOrderChange]
|
|
122
|
+
);
|
|
123
|
+
const table = useReactTable({
|
|
124
|
+
data,
|
|
125
|
+
columns,
|
|
126
|
+
getCoreRowModel: getCoreRowModel(),
|
|
127
|
+
getSortedRowModel: enableSorting ? getSortedRowModel() : void 0,
|
|
128
|
+
getExpandedRowModel: enableRowExpansion ? getExpandedRowModel() : void 0,
|
|
129
|
+
enableRowSelection,
|
|
130
|
+
enableSorting,
|
|
131
|
+
enableMultiSort,
|
|
132
|
+
maxMultiSortColCount,
|
|
133
|
+
enableColumnResizing,
|
|
134
|
+
columnResizeMode,
|
|
135
|
+
getRowCanExpand: enableRowExpansion ? getRowCanExpand ?? (() => true) : void 0,
|
|
136
|
+
state: {
|
|
137
|
+
rowSelection: rowSelectionState,
|
|
138
|
+
sorting: sortingState,
|
|
139
|
+
expanded: expandedState,
|
|
140
|
+
columnSizing: columnSizingState,
|
|
141
|
+
columnOrder: enableColumnReordering ? columnOrderState : void 0
|
|
142
|
+
},
|
|
143
|
+
onRowSelectionChange: handleRowSelectionChange,
|
|
144
|
+
onSortingChange: handleSortingChange,
|
|
145
|
+
onExpandedChange: handleExpandedChange,
|
|
146
|
+
onColumnSizingChange: handleColumnSizingChange,
|
|
147
|
+
onColumnOrderChange: enableColumnReordering ? handleColumnOrderChange : void 0,
|
|
148
|
+
getRowId
|
|
149
|
+
});
|
|
150
|
+
const { rows } = table.getRowModel();
|
|
151
|
+
const estimateSize = useCallback(
|
|
152
|
+
(index) => {
|
|
153
|
+
if (!enableRowExpansion) return rowHeight;
|
|
154
|
+
const row = rows[index];
|
|
155
|
+
return row?.getIsExpanded() ? rowHeight + expandedRowHeight : rowHeight;
|
|
156
|
+
},
|
|
157
|
+
[rows, rowHeight, expandedRowHeight, enableRowExpansion]
|
|
158
|
+
);
|
|
159
|
+
const virtualizer = useVirtualizer({
|
|
160
|
+
count: rows.length,
|
|
161
|
+
getScrollElement: () => containerRef.current,
|
|
162
|
+
estimateSize,
|
|
163
|
+
overscan
|
|
164
|
+
});
|
|
165
|
+
const virtualItems = virtualizer.getVirtualItems();
|
|
166
|
+
const totalSize = virtualizer.getTotalSize();
|
|
167
|
+
const handleScroll = useCallback(() => {
|
|
168
|
+
if (!onScrollToBottom || !containerRef.current) return;
|
|
169
|
+
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
|
|
170
|
+
const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
|
|
171
|
+
if (distanceFromBottom < scrollBottomThreshold) {
|
|
172
|
+
onScrollToBottom();
|
|
173
|
+
}
|
|
174
|
+
}, [onScrollToBottom, scrollBottomThreshold]);
|
|
175
|
+
const reorderColumn = useCallback(
|
|
176
|
+
(draggedColumnId, targetColumnId) => {
|
|
177
|
+
const newOrder = [...columnOrderState];
|
|
178
|
+
const draggedIndex = newOrder.indexOf(draggedColumnId);
|
|
179
|
+
const targetIndex = newOrder.indexOf(targetColumnId);
|
|
180
|
+
if (draggedIndex === -1 || targetIndex === -1) return;
|
|
181
|
+
newOrder.splice(draggedIndex, 1);
|
|
182
|
+
newOrder.splice(targetIndex, 0, draggedColumnId);
|
|
183
|
+
handleColumnOrderChange(newOrder);
|
|
184
|
+
},
|
|
185
|
+
[columnOrderState, handleColumnOrderChange]
|
|
186
|
+
);
|
|
187
|
+
const setFocusedRow = useCallback(
|
|
188
|
+
(index) => {
|
|
189
|
+
const clampedIndex = Math.max(-1, Math.min(index, rows.length - 1));
|
|
190
|
+
if (onFocusedRowChange) {
|
|
191
|
+
onFocusedRowChange(clampedIndex);
|
|
192
|
+
} else {
|
|
193
|
+
setInternalFocusedRowIndex(clampedIndex);
|
|
194
|
+
}
|
|
195
|
+
if (clampedIndex >= 0) {
|
|
196
|
+
virtualizer.scrollToIndex(clampedIndex, { align: "auto" });
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
[rows.length, onFocusedRowChange, virtualizer]
|
|
200
|
+
);
|
|
201
|
+
const handleKeyDown = useCallback(
|
|
202
|
+
(e) => {
|
|
203
|
+
if (!enableKeyboardNavigation) return;
|
|
204
|
+
const currentIndex = focusedRowIndex;
|
|
205
|
+
switch (e.key) {
|
|
206
|
+
case "ArrowDown":
|
|
207
|
+
e.preventDefault();
|
|
208
|
+
setFocusedRow(currentIndex + 1);
|
|
209
|
+
break;
|
|
210
|
+
case "ArrowUp":
|
|
211
|
+
e.preventDefault();
|
|
212
|
+
setFocusedRow(currentIndex - 1);
|
|
213
|
+
break;
|
|
214
|
+
case "Home":
|
|
215
|
+
e.preventDefault();
|
|
216
|
+
setFocusedRow(0);
|
|
217
|
+
break;
|
|
218
|
+
case "End":
|
|
219
|
+
e.preventDefault();
|
|
220
|
+
setFocusedRow(rows.length - 1);
|
|
221
|
+
break;
|
|
222
|
+
case "Enter":
|
|
223
|
+
if (currentIndex >= 0 && enableRowExpansion) {
|
|
224
|
+
e.preventDefault();
|
|
225
|
+
const row = rows[currentIndex];
|
|
226
|
+
if (row?.getCanExpand()) {
|
|
227
|
+
row.toggleExpanded();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
break;
|
|
231
|
+
case " ":
|
|
232
|
+
if (currentIndex >= 0 && enableRowSelection) {
|
|
233
|
+
e.preventDefault();
|
|
234
|
+
const row = rows[currentIndex];
|
|
235
|
+
row?.toggleSelected();
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
[
|
|
241
|
+
enableKeyboardNavigation,
|
|
242
|
+
focusedRowIndex,
|
|
243
|
+
rows,
|
|
244
|
+
enableRowExpansion,
|
|
245
|
+
enableRowSelection,
|
|
246
|
+
setFocusedRow
|
|
247
|
+
]
|
|
248
|
+
);
|
|
249
|
+
return {
|
|
250
|
+
table,
|
|
251
|
+
rows,
|
|
252
|
+
virtualizer,
|
|
253
|
+
virtualItems,
|
|
254
|
+
totalSize,
|
|
255
|
+
containerRef,
|
|
256
|
+
handleScroll,
|
|
257
|
+
handleKeyDown,
|
|
258
|
+
reorderColumn,
|
|
259
|
+
setFocusedRow,
|
|
260
|
+
// Expose state for consumers
|
|
261
|
+
rowSelection: rowSelectionState,
|
|
262
|
+
sorting: sortingState,
|
|
263
|
+
expanded: expandedState,
|
|
264
|
+
columnSizing: columnSizingState,
|
|
265
|
+
columnOrder: columnOrderState,
|
|
266
|
+
focusedRowIndex
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
var DEFAULT_HEIGHT = 400;
|
|
270
|
+
function VirtualTable(props) {
|
|
271
|
+
const {
|
|
272
|
+
height = DEFAULT_HEIGHT,
|
|
273
|
+
stickyHeader = true,
|
|
274
|
+
renderExpandedRow,
|
|
275
|
+
className,
|
|
276
|
+
style,
|
|
277
|
+
...tableOptions
|
|
278
|
+
} = props;
|
|
279
|
+
const {
|
|
280
|
+
rows,
|
|
281
|
+
virtualizer,
|
|
282
|
+
virtualItems,
|
|
283
|
+
totalSize,
|
|
284
|
+
containerRef,
|
|
285
|
+
handleScroll,
|
|
286
|
+
handleKeyDown,
|
|
287
|
+
table,
|
|
288
|
+
reorderColumn,
|
|
289
|
+
setFocusedRow,
|
|
290
|
+
focusedRowIndex
|
|
291
|
+
} = useVirtualTable(tableOptions);
|
|
292
|
+
const headerGroups = table.getHeaderGroups();
|
|
293
|
+
const enableRowExpansion = tableOptions.enableRowExpansion;
|
|
294
|
+
const enableColumnResizing = tableOptions.enableColumnResizing;
|
|
295
|
+
const enableColumnReordering = tableOptions.enableColumnReordering;
|
|
296
|
+
const enableKeyboardNavigation = tableOptions.enableKeyboardNavigation;
|
|
297
|
+
const [draggedColumnId, setDraggedColumnId] = useState(null);
|
|
298
|
+
return /* @__PURE__ */ jsx(
|
|
299
|
+
"div",
|
|
300
|
+
{
|
|
301
|
+
ref: containerRef,
|
|
302
|
+
className,
|
|
303
|
+
tabIndex: enableKeyboardNavigation ? 0 : void 0,
|
|
304
|
+
style: {
|
|
305
|
+
height,
|
|
306
|
+
overflow: "auto",
|
|
307
|
+
position: "relative",
|
|
308
|
+
outline: "none",
|
|
309
|
+
...style
|
|
310
|
+
},
|
|
311
|
+
onScroll: handleScroll,
|
|
312
|
+
onKeyDown: enableKeyboardNavigation ? handleKeyDown : void 0,
|
|
313
|
+
children: /* @__PURE__ */ jsxs(
|
|
314
|
+
"table",
|
|
315
|
+
{
|
|
316
|
+
style: {
|
|
317
|
+
display: "grid",
|
|
318
|
+
width: "100%"
|
|
319
|
+
},
|
|
320
|
+
children: [
|
|
321
|
+
/* @__PURE__ */ jsx(
|
|
322
|
+
"thead",
|
|
323
|
+
{
|
|
324
|
+
style: {
|
|
325
|
+
display: "grid",
|
|
326
|
+
position: stickyHeader ? "sticky" : "relative",
|
|
327
|
+
top: 0,
|
|
328
|
+
zIndex: 1
|
|
329
|
+
},
|
|
330
|
+
children: headerGroups.map((headerGroup) => /* @__PURE__ */ jsx(
|
|
331
|
+
"tr",
|
|
332
|
+
{
|
|
333
|
+
style: {
|
|
334
|
+
display: "flex",
|
|
335
|
+
width: "100%"
|
|
336
|
+
},
|
|
337
|
+
children: headerGroup.headers.map((header) => /* @__PURE__ */ jsxs(
|
|
338
|
+
"th",
|
|
339
|
+
{
|
|
340
|
+
draggable: enableColumnReordering && !header.isPlaceholder,
|
|
341
|
+
"data-dragging": draggedColumnId === header.column.id || void 0,
|
|
342
|
+
onDragStart: enableColumnReordering ? (e) => {
|
|
343
|
+
setDraggedColumnId(header.column.id);
|
|
344
|
+
e.dataTransfer.effectAllowed = "move";
|
|
345
|
+
} : void 0,
|
|
346
|
+
onDragOver: enableColumnReordering ? (e) => {
|
|
347
|
+
e.preventDefault();
|
|
348
|
+
e.dataTransfer.dropEffect = "move";
|
|
349
|
+
} : void 0,
|
|
350
|
+
onDrop: enableColumnReordering ? (e) => {
|
|
351
|
+
e.preventDefault();
|
|
352
|
+
if (draggedColumnId && draggedColumnId !== header.column.id) {
|
|
353
|
+
reorderColumn(draggedColumnId, header.column.id);
|
|
354
|
+
}
|
|
355
|
+
} : void 0,
|
|
356
|
+
onDragEnd: enableColumnReordering ? () => setDraggedColumnId(null) : void 0,
|
|
357
|
+
style: {
|
|
358
|
+
flex: `0 0 ${header.getSize()}px`,
|
|
359
|
+
cursor: enableColumnReordering ? "grab" : header.column.getCanSort() ? "pointer" : "default",
|
|
360
|
+
position: "relative",
|
|
361
|
+
opacity: draggedColumnId === header.column.id ? 0.5 : 1
|
|
362
|
+
},
|
|
363
|
+
onClick: !enableColumnReordering ? header.column.getToggleSortingHandler() : void 0,
|
|
364
|
+
children: [
|
|
365
|
+
header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()),
|
|
366
|
+
header.column.getIsSorted() === "asc" && " \u2191",
|
|
367
|
+
header.column.getIsSorted() === "desc" && " \u2193",
|
|
368
|
+
enableColumnResizing && header.column.getCanResize() && /* @__PURE__ */ jsx(
|
|
369
|
+
"div",
|
|
370
|
+
{
|
|
371
|
+
onMouseDown: header.getResizeHandler(),
|
|
372
|
+
onTouchStart: header.getResizeHandler(),
|
|
373
|
+
onClick: (e) => e.stopPropagation(),
|
|
374
|
+
className: "virtual-table-resizer",
|
|
375
|
+
"data-resizing": header.column.getIsResizing() || void 0,
|
|
376
|
+
style: {
|
|
377
|
+
position: "absolute",
|
|
378
|
+
right: 0,
|
|
379
|
+
top: 0,
|
|
380
|
+
height: "100%",
|
|
381
|
+
width: "5px",
|
|
382
|
+
cursor: "col-resize",
|
|
383
|
+
userSelect: "none",
|
|
384
|
+
touchAction: "none",
|
|
385
|
+
background: header.column.getIsResizing() ? "rgba(0, 0, 0, 0.5)" : "transparent"
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
)
|
|
389
|
+
]
|
|
390
|
+
},
|
|
391
|
+
header.id
|
|
392
|
+
))
|
|
393
|
+
},
|
|
394
|
+
headerGroup.id
|
|
395
|
+
))
|
|
396
|
+
}
|
|
397
|
+
),
|
|
398
|
+
/* @__PURE__ */ jsx(
|
|
399
|
+
"tbody",
|
|
400
|
+
{
|
|
401
|
+
style: {
|
|
402
|
+
display: "grid",
|
|
403
|
+
height: `${totalSize}px`,
|
|
404
|
+
position: "relative"
|
|
405
|
+
},
|
|
406
|
+
children: virtualItems.map((virtualRow) => {
|
|
407
|
+
const row = rows[virtualRow.index];
|
|
408
|
+
const isExpanded = row.getIsExpanded();
|
|
409
|
+
const canExpand = enableRowExpansion && row.getCanExpand();
|
|
410
|
+
const isFocused = enableKeyboardNavigation && virtualRow.index === focusedRowIndex;
|
|
411
|
+
const handleRowClick = () => {
|
|
412
|
+
if (enableKeyboardNavigation) {
|
|
413
|
+
setFocusedRow(virtualRow.index);
|
|
414
|
+
}
|
|
415
|
+
if (canExpand) {
|
|
416
|
+
row.toggleExpanded();
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
return /* @__PURE__ */ jsxs(
|
|
420
|
+
"tr",
|
|
421
|
+
{
|
|
422
|
+
"data-index": virtualRow.index,
|
|
423
|
+
"data-expanded": isExpanded || void 0,
|
|
424
|
+
"data-focused": isFocused || void 0,
|
|
425
|
+
ref: (node) => virtualizer.measureElement(node),
|
|
426
|
+
style: {
|
|
427
|
+
display: "block",
|
|
428
|
+
position: "absolute",
|
|
429
|
+
transform: `translateY(${virtualRow.start}px)`,
|
|
430
|
+
width: "100%",
|
|
431
|
+
cursor: canExpand || enableKeyboardNavigation ? "pointer" : "default"
|
|
432
|
+
},
|
|
433
|
+
onClick: handleRowClick,
|
|
434
|
+
children: [
|
|
435
|
+
/* @__PURE__ */ jsx(
|
|
436
|
+
"div",
|
|
437
|
+
{
|
|
438
|
+
style: {
|
|
439
|
+
display: "flex",
|
|
440
|
+
width: "100%"
|
|
441
|
+
},
|
|
442
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(
|
|
443
|
+
"td",
|
|
444
|
+
{
|
|
445
|
+
style: {
|
|
446
|
+
flex: `0 0 ${cell.column.getSize()}px`
|
|
447
|
+
},
|
|
448
|
+
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
449
|
+
},
|
|
450
|
+
cell.id
|
|
451
|
+
))
|
|
452
|
+
}
|
|
453
|
+
),
|
|
454
|
+
isExpanded && renderExpandedRow && /* @__PURE__ */ jsx("div", { onClick: (e) => e.stopPropagation(), style: { width: "100%" }, children: renderExpandedRow(row) })
|
|
455
|
+
]
|
|
456
|
+
},
|
|
457
|
+
row.id
|
|
458
|
+
);
|
|
459
|
+
})
|
|
460
|
+
}
|
|
461
|
+
)
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
)
|
|
465
|
+
}
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export { VirtualTable, useVirtualTable };
|
|
470
|
+
//# sourceMappingURL=index.js.map
|
|
471
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/VirtualTable/useVirtualTable.ts","../src/VirtualTable/VirtualTable.tsx"],"names":["useState"],"mappings":"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","file":"index.js","sourcesContent":["import { useRef, useCallback, useState, useMemo } from 'react';\nimport {\n useReactTable,\n getCoreRowModel,\n getSortedRowModel,\n getExpandedRowModel,\n type RowSelectionState,\n type SortingState,\n type ExpandedState,\n type ColumnSizingState,\n type ColumnOrderState,\n type Updater,\n type ColumnDef,\n} from '@tanstack/react-table';\nimport { useVirtualizer } from '@tanstack/react-virtual';\nimport type { UseVirtualTableOptions } from './types';\n\nconst DEFAULT_ROW_HEIGHT = 40;\nconst DEFAULT_EXPANDED_ROW_HEIGHT = 200;\nconst DEFAULT_OVERSCAN = 5;\nconst DEFAULT_SCROLL_THRESHOLD = 100;\n\n/** Extract column ID from a ColumnDef */\nfunction getColumnId<TData>(column: ColumnDef<TData, unknown>): string {\n // Check for explicit id first\n if ('id' in column && typeof column.id === 'string') {\n return column.id;\n }\n // Fall back to accessorKey for accessor columns\n if ('accessorKey' in column && typeof column.accessorKey === 'string') {\n return column.accessorKey;\n }\n return '';\n}\n\nexport function useVirtualTable<TData>(options: UseVirtualTableOptions<TData>) {\n const {\n data,\n columns,\n rowHeight = DEFAULT_ROW_HEIGHT,\n overscan = DEFAULT_OVERSCAN,\n enableRowSelection = false,\n rowSelection: controlledRowSelection,\n onRowSelectionChange,\n enableSorting = false,\n sorting: controlledSorting,\n onSortingChange,\n enableMultiSort = false,\n maxMultiSortColCount,\n enableColumnResizing = false,\n columnResizeMode = 'onChange',\n columnSizing: controlledColumnSizing,\n onColumnSizingChange,\n enableColumnReordering = false,\n columnOrder: controlledColumnOrder,\n onColumnOrderChange,\n enableRowExpansion = false,\n expanded: controlledExpanded,\n onExpandedChange,\n expandedRowHeight = DEFAULT_EXPANDED_ROW_HEIGHT,\n getRowCanExpand,\n getRowId,\n enableKeyboardNavigation = false,\n focusedRowIndex: controlledFocusedRowIndex,\n onFocusedRowChange,\n onScrollToBottom,\n scrollBottomThreshold = DEFAULT_SCROLL_THRESHOLD,\n } = options;\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Default column order from column definitions\n const defaultColumnOrder = useMemo(() => columns.map(getColumnId), [columns]);\n\n // Internal state for uncontrolled mode\n const [internalRowSelection, setInternalRowSelection] = useState<RowSelectionState>({});\n const [internalSorting, setInternalSorting] = useState<SortingState>([]);\n const [internalExpanded, setInternalExpanded] = useState<ExpandedState>({});\n const [internalColumnSizing, setInternalColumnSizing] = useState<ColumnSizingState>({});\n const [internalColumnOrder, setInternalColumnOrder] = useState<ColumnOrderState>([]);\n const [internalFocusedRowIndex, setInternalFocusedRowIndex] = useState<number>(-1);\n\n // Use controlled or internal state\n const rowSelectionState = controlledRowSelection ?? internalRowSelection;\n const sortingState = controlledSorting ?? internalSorting;\n const expandedState = controlledExpanded ?? internalExpanded;\n const columnSizingState = controlledColumnSizing ?? internalColumnSizing;\n const columnOrderState =\n controlledColumnOrder ??\n (internalColumnOrder.length ? internalColumnOrder : defaultColumnOrder);\n const focusedRowIndex = controlledFocusedRowIndex ?? internalFocusedRowIndex;\n\n const handleRowSelectionChange = useCallback(\n (updater: Updater<RowSelectionState>) => {\n const newValue = typeof updater === 'function' ? updater(rowSelectionState) : updater;\n if (onRowSelectionChange) {\n onRowSelectionChange(newValue);\n } else {\n setInternalRowSelection(newValue);\n }\n },\n [rowSelectionState, onRowSelectionChange]\n );\n\n const handleSortingChange = useCallback(\n (updater: Updater<SortingState>) => {\n const newValue = typeof updater === 'function' ? updater(sortingState) : updater;\n if (onSortingChange) {\n onSortingChange(newValue);\n } else {\n setInternalSorting(newValue);\n }\n },\n [sortingState, onSortingChange]\n );\n\n const handleExpandedChange = useCallback(\n (updater: Updater<ExpandedState>) => {\n const newValue = typeof updater === 'function' ? updater(expandedState) : updater;\n if (onExpandedChange) {\n onExpandedChange(newValue);\n } else {\n setInternalExpanded(newValue);\n }\n },\n [expandedState, onExpandedChange]\n );\n\n const handleColumnSizingChange = useCallback(\n (updater: Updater<ColumnSizingState>) => {\n const newValue = typeof updater === 'function' ? updater(columnSizingState) : updater;\n if (onColumnSizingChange) {\n onColumnSizingChange(newValue);\n } else {\n setInternalColumnSizing(newValue);\n }\n },\n [columnSizingState, onColumnSizingChange]\n );\n\n const handleColumnOrderChange = useCallback(\n (updater: Updater<ColumnOrderState>) => {\n const newValue = typeof updater === 'function' ? updater(columnOrderState) : updater;\n if (onColumnOrderChange) {\n onColumnOrderChange(newValue);\n } else {\n setInternalColumnOrder(newValue);\n }\n },\n [columnOrderState, onColumnOrderChange]\n );\n\n const table = useReactTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: enableSorting ? getSortedRowModel() : undefined,\n getExpandedRowModel: enableRowExpansion ? getExpandedRowModel() : undefined,\n enableRowSelection,\n enableSorting,\n enableMultiSort,\n maxMultiSortColCount,\n enableColumnResizing,\n columnResizeMode,\n getRowCanExpand: enableRowExpansion ? (getRowCanExpand ?? (() => true)) : undefined,\n state: {\n rowSelection: rowSelectionState,\n sorting: sortingState,\n expanded: expandedState,\n columnSizing: columnSizingState,\n columnOrder: enableColumnReordering ? columnOrderState : undefined,\n },\n onRowSelectionChange: handleRowSelectionChange,\n onSortingChange: handleSortingChange,\n onExpandedChange: handleExpandedChange,\n onColumnSizingChange: handleColumnSizingChange,\n onColumnOrderChange: enableColumnReordering ? handleColumnOrderChange : undefined,\n getRowId,\n });\n\n const { rows } = table.getRowModel();\n\n // Dynamic row height estimation based on expanded state\n const estimateSize = useCallback(\n (index: number) => {\n if (!enableRowExpansion) return rowHeight;\n const row = rows[index];\n return row?.getIsExpanded() ? rowHeight + expandedRowHeight : rowHeight;\n },\n [rows, rowHeight, expandedRowHeight, enableRowExpansion]\n );\n\n const virtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => containerRef.current,\n estimateSize,\n overscan,\n });\n\n const virtualItems = virtualizer.getVirtualItems();\n const totalSize = virtualizer.getTotalSize();\n\n // Handle scroll to bottom detection\n const handleScroll = useCallback(() => {\n if (!onScrollToBottom || !containerRef.current) return;\n\n const { scrollTop, scrollHeight, clientHeight } = containerRef.current;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n\n if (distanceFromBottom < scrollBottomThreshold) {\n onScrollToBottom();\n }\n }, [onScrollToBottom, scrollBottomThreshold]);\n\n // Helper to reorder columns (for drag and drop)\n const reorderColumn = useCallback(\n (draggedColumnId: string, targetColumnId: string) => {\n const newOrder = [...columnOrderState];\n const draggedIndex = newOrder.indexOf(draggedColumnId);\n const targetIndex = newOrder.indexOf(targetColumnId);\n\n if (draggedIndex === -1 || targetIndex === -1) return;\n\n newOrder.splice(draggedIndex, 1);\n newOrder.splice(targetIndex, 0, draggedColumnId);\n\n handleColumnOrderChange(newOrder);\n },\n [columnOrderState, handleColumnOrderChange]\n );\n\n // Focus row change handler\n const setFocusedRow = useCallback(\n (index: number) => {\n const clampedIndex = Math.max(-1, Math.min(index, rows.length - 1));\n if (onFocusedRowChange) {\n onFocusedRowChange(clampedIndex);\n } else {\n setInternalFocusedRowIndex(clampedIndex);\n }\n // Scroll focused row into view\n if (clampedIndex >= 0) {\n virtualizer.scrollToIndex(clampedIndex, { align: 'auto' });\n }\n },\n [rows.length, onFocusedRowChange, virtualizer]\n );\n\n // Keyboard navigation handler\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (!enableKeyboardNavigation) return;\n\n const currentIndex = focusedRowIndex;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n setFocusedRow(currentIndex + 1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n setFocusedRow(currentIndex - 1);\n break;\n case 'Home':\n e.preventDefault();\n setFocusedRow(0);\n break;\n case 'End':\n e.preventDefault();\n setFocusedRow(rows.length - 1);\n break;\n case 'Enter':\n if (currentIndex >= 0 && enableRowExpansion) {\n e.preventDefault();\n const row = rows[currentIndex];\n if (row?.getCanExpand()) {\n row.toggleExpanded();\n }\n }\n break;\n case ' ':\n if (currentIndex >= 0 && enableRowSelection) {\n e.preventDefault();\n const row = rows[currentIndex];\n row?.toggleSelected();\n }\n break;\n }\n },\n [\n enableKeyboardNavigation,\n focusedRowIndex,\n rows,\n enableRowExpansion,\n enableRowSelection,\n setFocusedRow,\n ]\n );\n\n return {\n table,\n rows,\n virtualizer,\n virtualItems,\n totalSize,\n containerRef,\n handleScroll,\n handleKeyDown,\n reorderColumn,\n setFocusedRow,\n // Expose state for consumers\n rowSelection: rowSelectionState,\n sorting: sortingState,\n expanded: expandedState,\n columnSizing: columnSizingState,\n columnOrder: columnOrderState,\n focusedRowIndex,\n };\n}\n","import { useState } from 'react';\nimport { flexRender } from '@tanstack/react-table';\nimport { useVirtualTable } from './useVirtualTable';\nimport type { VirtualTableProps } from './types';\n\nconst DEFAULT_HEIGHT = 400;\n\nexport function VirtualTable<TData>(props: VirtualTableProps<TData>) {\n const {\n height = DEFAULT_HEIGHT,\n stickyHeader = true,\n renderExpandedRow,\n className,\n style,\n ...tableOptions\n } = props;\n\n const {\n rows,\n virtualizer,\n virtualItems,\n totalSize,\n containerRef,\n handleScroll,\n handleKeyDown,\n table,\n reorderColumn,\n setFocusedRow,\n focusedRowIndex,\n } = useVirtualTable(tableOptions);\n\n const headerGroups = table.getHeaderGroups();\n const enableRowExpansion = tableOptions.enableRowExpansion;\n const enableColumnResizing = tableOptions.enableColumnResizing;\n const enableColumnReordering = tableOptions.enableColumnReordering;\n const enableKeyboardNavigation = tableOptions.enableKeyboardNavigation;\n\n // Drag state for column reordering\n const [draggedColumnId, setDraggedColumnId] = useState<string | null>(null);\n\n return (\n <div\n ref={containerRef}\n className={className}\n tabIndex={enableKeyboardNavigation ? 0 : undefined}\n style={{\n height,\n overflow: 'auto',\n position: 'relative',\n outline: 'none',\n ...style,\n }}\n onScroll={handleScroll}\n onKeyDown={enableKeyboardNavigation ? handleKeyDown : undefined}\n >\n <table\n style={{\n display: 'grid',\n width: '100%',\n }}\n >\n <thead\n style={{\n display: 'grid',\n position: stickyHeader ? 'sticky' : 'relative',\n top: 0,\n zIndex: 1,\n }}\n >\n {headerGroups.map((headerGroup) => (\n <tr\n key={headerGroup.id}\n style={{\n display: 'flex',\n width: '100%',\n }}\n >\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n draggable={enableColumnReordering && !header.isPlaceholder}\n data-dragging={draggedColumnId === header.column.id || undefined}\n onDragStart={\n enableColumnReordering\n ? (e) => {\n setDraggedColumnId(header.column.id);\n e.dataTransfer.effectAllowed = 'move';\n }\n : undefined\n }\n onDragOver={\n enableColumnReordering\n ? (e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n }\n : undefined\n }\n onDrop={\n enableColumnReordering\n ? (e) => {\n e.preventDefault();\n if (draggedColumnId && draggedColumnId !== header.column.id) {\n reorderColumn(draggedColumnId, header.column.id);\n }\n }\n : undefined\n }\n onDragEnd={enableColumnReordering ? () => setDraggedColumnId(null) : undefined}\n style={{\n flex: `0 0 ${header.getSize()}px`,\n cursor: enableColumnReordering\n ? 'grab'\n : header.column.getCanSort()\n ? 'pointer'\n : 'default',\n position: 'relative',\n opacity: draggedColumnId === header.column.id ? 0.5 : 1,\n }}\n onClick={\n !enableColumnReordering ? header.column.getToggleSortingHandler() : undefined\n }\n >\n {header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n {header.column.getIsSorted() === 'asc' && ' ↑'}\n {header.column.getIsSorted() === 'desc' && ' ↓'}\n\n {/* Column resize handle */}\n {enableColumnResizing && header.column.getCanResize() && (\n <div\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n onClick={(e) => e.stopPropagation()}\n className=\"virtual-table-resizer\"\n data-resizing={header.column.getIsResizing() || undefined}\n style={{\n position: 'absolute',\n right: 0,\n top: 0,\n height: '100%',\n width: '5px',\n cursor: 'col-resize',\n userSelect: 'none',\n touchAction: 'none',\n background: header.column.getIsResizing()\n ? 'rgba(0, 0, 0, 0.5)'\n : 'transparent',\n }}\n />\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody\n style={{\n display: 'grid',\n height: `${totalSize}px`,\n position: 'relative',\n }}\n >\n {virtualItems.map((virtualRow) => {\n const row = rows[virtualRow.index];\n const isExpanded = row.getIsExpanded();\n const canExpand = enableRowExpansion && row.getCanExpand();\n const isFocused = enableKeyboardNavigation && virtualRow.index === focusedRowIndex;\n\n const handleRowClick = () => {\n if (enableKeyboardNavigation) {\n setFocusedRow(virtualRow.index);\n }\n if (canExpand) {\n row.toggleExpanded();\n }\n };\n\n return (\n <tr\n key={row.id}\n data-index={virtualRow.index}\n data-expanded={isExpanded || undefined}\n data-focused={isFocused || undefined}\n ref={(node) => virtualizer.measureElement(node)}\n style={{\n display: 'block',\n position: 'absolute',\n transform: `translateY(${virtualRow.start}px)`,\n width: '100%',\n cursor: canExpand || enableKeyboardNavigation ? 'pointer' : 'default',\n }}\n onClick={handleRowClick}\n >\n {/* Row cells */}\n <div\n style={{\n display: 'flex',\n width: '100%',\n }}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n style={{\n flex: `0 0 ${cell.column.getSize()}px`,\n }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </div>\n\n {/* Expanded content */}\n {isExpanded && renderExpandedRow && (\n <div onClick={(e) => e.stopPropagation()} style={{ width: '100%' }}>\n {renderExpandedRow(row)}\n </div>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,18 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "virtualized-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Headless virtualized table and select components for React",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsup --watch",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:watch": "vitest"
|
|
31
|
+
},
|
|
5
32
|
"keywords": [
|
|
6
33
|
"react",
|
|
7
34
|
"virtual",
|
|
35
|
+
"virtualized",
|
|
8
36
|
"table",
|
|
9
37
|
"select",
|
|
10
38
|
"headless",
|
|
11
|
-
"tanstack"
|
|
39
|
+
"tanstack",
|
|
40
|
+
"react-table",
|
|
41
|
+
"react-virtual"
|
|
12
42
|
],
|
|
13
43
|
"license": "MIT",
|
|
14
44
|
"repository": {
|
|
15
45
|
"type": "git",
|
|
16
|
-
"url": "git+https://github.com/grishalr/virtualized-ui.git"
|
|
46
|
+
"url": "git+https://github.com/grishalr/virtualized-ui.git",
|
|
47
|
+
"directory": "packages/core"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://github.com/grishalr/virtualized-ui#readme",
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/grishalr/virtualized-ui/issues"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"react": ">=18.0.0",
|
|
55
|
+
"react-dom": ">=18.0.0"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@tanstack/react-table": "^8.20.0",
|
|
59
|
+
"@tanstack/react-virtual": "^3.10.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@testing-library/dom": "^10.4.1",
|
|
63
|
+
"@testing-library/react": "^16.3.2",
|
|
64
|
+
"@types/react": "^18.3.0",
|
|
65
|
+
"@types/react-dom": "^18.3.0",
|
|
66
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
67
|
+
"jsdom": "^27.4.0",
|
|
68
|
+
"react": "^18.3.0",
|
|
69
|
+
"react-dom": "^18.3.0",
|
|
70
|
+
"tsup": "^8.3.0",
|
|
71
|
+
"typescript": "^5.6.0",
|
|
72
|
+
"vitest": "^4.0.18"
|
|
17
73
|
}
|
|
18
|
-
}
|
|
74
|
+
}
|
package/CLAUDE.MD
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
## Project Overview
|
|
4
|
-
|
|
5
|
-
virtual-ui is a component library providing virtualized table and select primitives for React. Headless by design — logic and structure, no styles.
|
|
6
|
-
|
|
7
|
-
## Architecture
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
packages/core/ # npm package (@virtual-ui/core)
|
|
11
|
-
docs/ # Astro docs site
|
|
12
|
-
.storybook/ # Storybook config (stories live in packages/core/src/)
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Key Dependencies
|
|
16
|
-
|
|
17
|
-
- **VirtualTable**: TanStack Table + TanStack Virtual
|
|
18
|
-
- **VirtualSelect**: react-select + TanStack Virtual
|
|
19
|
-
- **Docs**: Astro + Tailwind + daisyUI
|
|
20
|
-
|
|
21
|
-
## Commands
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
pnpm dev # Storybook (development)
|
|
25
|
-
pnpm build # Build package
|
|
26
|
-
pnpm build:docs # Build docs site
|
|
27
|
-
cd docs && pnpm dev # Run docs locally
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Component Guidelines
|
|
31
|
-
|
|
32
|
-
- Single component per feature, props enable variants (no separate AsyncSelect, etc.)
|
|
33
|
-
- All features opt-in via props
|
|
34
|
-
- No default styles — render semantic HTML, let users style
|
|
35
|
-
- Export types alongside components
|
|
36
|
-
|
|
37
|
-
## File Conventions
|
|
38
|
-
|
|
39
|
-
- `ComponentName.tsx` — component implementation
|
|
40
|
-
- `ComponentName.stories.tsx` — Storybook stories
|
|
41
|
-
- `types.ts` — TypeScript types per component folder
|
|
42
|
-
|
|
43
|
-
## Testing Changes
|
|
44
|
-
|
|
45
|
-
1. Run Storybook (`pnpm dev`)
|
|
46
|
-
2. Check relevant stories
|
|
47
|
-
3. Test with 10k items to verify virtualization works
|
|
48
|
-
|
|
49
|
-
## Publishing
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pnpm build
|
|
53
|
-
cd packages/core && npm publish --access public
|
|
54
|
-
```
|