@versini/ui-datagrid 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +294 -0
- package/dist/DataGrid/DataGrid.d.ts +2 -0
- package/dist/DataGrid/DataGrid.js +132 -0
- package/dist/DataGrid/DataGridContext.d.ts +2 -0
- package/dist/DataGrid/DataGridContext.js +16 -0
- package/dist/DataGrid/index.d.ts +2 -0
- package/dist/DataGrid/index.js +17 -0
- package/dist/DataGrid/utilities.d.ts +36 -0
- package/dist/DataGrid/utilities.js +99 -0
- package/dist/DataGridAnimated/AnimatedWrapper.d.ts +47 -0
- package/dist/DataGridAnimated/AnimatedWrapper.js +49 -0
- package/dist/DataGridAnimated/index.d.ts +4 -0
- package/dist/DataGridAnimated/index.js +17 -0
- package/dist/DataGridAnimated/useAnimatedHeight.d.ts +49 -0
- package/dist/DataGridAnimated/useAnimatedHeight.js +131 -0
- package/dist/DataGridBody/DataGridBody.d.ts +2 -0
- package/dist/DataGridBody/DataGridBody.js +38 -0
- package/dist/DataGridBody/index.d.ts +1 -0
- package/dist/DataGridBody/index.js +13 -0
- package/dist/DataGridCell/DataGridCell.d.ts +14 -0
- package/dist/DataGridCell/DataGridCell.js +77 -0
- package/dist/DataGridCell/index.d.ts +1 -0
- package/dist/DataGridCell/index.js +13 -0
- package/dist/DataGridCellSort/DataGridCellSort.d.ts +2 -0
- package/dist/DataGridCellSort/DataGridCellSort.js +107 -0
- package/dist/DataGridCellSort/index.d.ts +1 -0
- package/dist/DataGridCellSort/index.js +13 -0
- package/dist/DataGridConstants/DataGridConstants.d.ts +37 -0
- package/dist/DataGridConstants/DataGridConstants.js +38 -0
- package/dist/DataGridConstants/index.d.ts +1 -0
- package/dist/DataGridConstants/index.js +13 -0
- package/dist/DataGridFooter/DataGridFooter.d.ts +12 -0
- package/dist/DataGridFooter/DataGridFooter.js +81 -0
- package/dist/DataGridFooter/index.d.ts +1 -0
- package/dist/DataGridFooter/index.js +13 -0
- package/dist/DataGridHeader/DataGridHeader.d.ts +13 -0
- package/dist/DataGridHeader/DataGridHeader.js +80 -0
- package/dist/DataGridHeader/index.d.ts +1 -0
- package/dist/DataGridHeader/index.js +13 -0
- package/dist/DataGridInfinite/InfiniteScrollMarker.d.ts +35 -0
- package/dist/DataGridInfinite/InfiniteScrollMarker.js +53 -0
- package/dist/DataGridInfinite/index.d.ts +4 -0
- package/dist/DataGridInfinite/index.js +17 -0
- package/dist/DataGridInfinite/useInfiniteScroll.d.ts +81 -0
- package/dist/DataGridInfinite/useInfiniteScroll.js +117 -0
- package/dist/DataGridRow/DataGridRow.d.ts +2 -0
- package/dist/DataGridRow/DataGridRow.js +75 -0
- package/dist/DataGridRow/index.d.ts +1 -0
- package/dist/DataGridRow/index.js +13 -0
- package/dist/DataGridSorting/index.d.ts +2 -0
- package/dist/DataGridSorting/index.js +18 -0
- package/dist/DataGridSorting/sortingUtils.d.ts +138 -0
- package/dist/DataGridSorting/sortingUtils.js +234 -0
- package/dist/DataGridVirtual/VirtualDataGrid.d.ts +114 -0
- package/dist/DataGridVirtual/VirtualDataGrid.js +181 -0
- package/dist/DataGridVirtual/index.d.ts +6 -0
- package/dist/DataGridVirtual/index.js +22 -0
- package/dist/DataGridVirtual/useVirtualDataGrid.d.ts +112 -0
- package/dist/DataGridVirtual/useVirtualDataGrid.js +89 -0
- package/package.json +103 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { type Virtualizer } from "@tanstack/react-virtual";
|
|
2
|
+
export type UseVirtualDataGridOptions<T = unknown> = {
|
|
3
|
+
/**
|
|
4
|
+
* Array of data items.
|
|
5
|
+
*/
|
|
6
|
+
data: T[];
|
|
7
|
+
/**
|
|
8
|
+
* Estimated height of each row in pixels.
|
|
9
|
+
* @default 40
|
|
10
|
+
*/
|
|
11
|
+
estimateSize?: number | ((index: number) => number);
|
|
12
|
+
/**
|
|
13
|
+
* Number of rows to render above/below the visible area.
|
|
14
|
+
* @default 5
|
|
15
|
+
*/
|
|
16
|
+
overscan?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Function to get a unique key for each item.
|
|
19
|
+
*/
|
|
20
|
+
getItemKey: (index: number) => string | number;
|
|
21
|
+
/**
|
|
22
|
+
* Whether virtualization is enabled.
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Whether to use React's flushSync for synchronous updates. Set to false for
|
|
28
|
+
* React 19 compatibility.
|
|
29
|
+
* @default true
|
|
30
|
+
*/
|
|
31
|
+
useFlushSync?: boolean;
|
|
32
|
+
};
|
|
33
|
+
export type UseVirtualDataGridReturn<T = unknown> = {
|
|
34
|
+
/**
|
|
35
|
+
* Ref to attach to the scroll container.
|
|
36
|
+
*/
|
|
37
|
+
scrollContainerRef: React.RefObject<HTMLDivElement | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Total height of all rows (for container sizing).
|
|
40
|
+
*/
|
|
41
|
+
totalSize: number;
|
|
42
|
+
/**
|
|
43
|
+
* Virtual items to render.
|
|
44
|
+
*/
|
|
45
|
+
virtualItems: {
|
|
46
|
+
index: number;
|
|
47
|
+
key: string | number | bigint;
|
|
48
|
+
size: number;
|
|
49
|
+
start: number;
|
|
50
|
+
data: T;
|
|
51
|
+
}[];
|
|
52
|
+
/**
|
|
53
|
+
* Scroll to a specific row index.
|
|
54
|
+
*/
|
|
55
|
+
scrollToIndex: (index: number, options?: {
|
|
56
|
+
align?: "start" | "center" | "end" | "auto";
|
|
57
|
+
behavior?: "auto" | "smooth";
|
|
58
|
+
}) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Whether the list is currently being scrolled.
|
|
61
|
+
*/
|
|
62
|
+
isScrolling: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* The virtualizer instance for advanced usage.
|
|
65
|
+
*/
|
|
66
|
+
virtualizer: Virtualizer<HTMLDivElement, Element>;
|
|
67
|
+
/**
|
|
68
|
+
* Measure a row element (for dynamic sizing).
|
|
69
|
+
*/
|
|
70
|
+
measureElement: (element: Element | null) => void;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Hook for virtualizing a data grid with TanStack Virtual.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* const {
|
|
78
|
+
* scrollContainerRef,
|
|
79
|
+
* totalSize,
|
|
80
|
+
* virtualItems,
|
|
81
|
+
* scrollToIndex,
|
|
82
|
+
* } = useVirtualDataGrid({
|
|
83
|
+
* data: items,
|
|
84
|
+
* estimateSize: 48,
|
|
85
|
+
* overscan: 10,
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* return (
|
|
89
|
+
* <div ref={scrollContainerRef} style={{ height: '500px', overflow: 'auto' }}>
|
|
90
|
+
* <div style={{ height: totalSize }}>
|
|
91
|
+
* <table>
|
|
92
|
+
* <tbody>
|
|
93
|
+
* {virtualItems.map((virtualRow) => (
|
|
94
|
+
* <tr
|
|
95
|
+
* key={virtualRow.key}
|
|
96
|
+
* style={{
|
|
97
|
+
* height: virtualRow.size,
|
|
98
|
+
* transform: `translateY(${virtualRow.start}px)`,
|
|
99
|
+
* }}
|
|
100
|
+
* >
|
|
101
|
+
* {renderCells(virtualRow.data)}
|
|
102
|
+
* </tr>
|
|
103
|
+
* ))}
|
|
104
|
+
* </tbody>
|
|
105
|
+
* </table>
|
|
106
|
+
* </div>
|
|
107
|
+
* </div>
|
|
108
|
+
* );
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
*/
|
|
112
|
+
export declare function useVirtualDataGrid<T>({ data, estimateSize, overscan, getItemKey, enabled, useFlushSync, }: UseVirtualDataGridOptions<T>): UseVirtualDataGridReturn<T>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
@versini/ui-datagrid v0.1.0
|
|
3
|
+
© 2026 gizmette.com
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
7
|
+
import { useCallback, useRef } from "react";
|
|
8
|
+
|
|
9
|
+
;// CONCATENATED MODULE: external "@tanstack/react-virtual"
|
|
10
|
+
|
|
11
|
+
;// CONCATENATED MODULE: external "react"
|
|
12
|
+
|
|
13
|
+
;// CONCATENATED MODULE: ./src/DataGridVirtual/useVirtualDataGrid.ts
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const DEFAULT_ESTIMATE_SIZE = 40;
|
|
17
|
+
const DEFAULT_OVERSCAN = 5;
|
|
18
|
+
/**
|
|
19
|
+
* Hook for virtualizing a data grid with TanStack Virtual.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* const {
|
|
24
|
+
* scrollContainerRef,
|
|
25
|
+
* totalSize,
|
|
26
|
+
* virtualItems,
|
|
27
|
+
* scrollToIndex,
|
|
28
|
+
* } = useVirtualDataGrid({
|
|
29
|
+
* data: items,
|
|
30
|
+
* estimateSize: 48,
|
|
31
|
+
* overscan: 10,
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* return (
|
|
35
|
+
* <div ref={scrollContainerRef} style={{ height: '500px', overflow: 'auto' }}>
|
|
36
|
+
* <div style={{ height: totalSize }}>
|
|
37
|
+
* <table>
|
|
38
|
+
* <tbody>
|
|
39
|
+
* {virtualItems.map((virtualRow) => (
|
|
40
|
+
* <tr
|
|
41
|
+
* key={virtualRow.key}
|
|
42
|
+
* style={{
|
|
43
|
+
* height: virtualRow.size,
|
|
44
|
+
* transform: `translateY(${virtualRow.start}px)`,
|
|
45
|
+
* }}
|
|
46
|
+
* >
|
|
47
|
+
* {renderCells(virtualRow.data)}
|
|
48
|
+
* </tr>
|
|
49
|
+
* ))}
|
|
50
|
+
* </tbody>
|
|
51
|
+
* </table>
|
|
52
|
+
* </div>
|
|
53
|
+
* </div>
|
|
54
|
+
* );
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
*/ function useVirtualDataGrid({ data, estimateSize = DEFAULT_ESTIMATE_SIZE, overscan = DEFAULT_OVERSCAN, getItemKey, enabled = true, useFlushSync = true }) {
|
|
58
|
+
const scrollContainerRef = useRef(null);
|
|
59
|
+
const estimateSizeFn = useCallback((index)=>typeof estimateSize === "function" ? estimateSize(index) : estimateSize, [
|
|
60
|
+
estimateSize
|
|
61
|
+
]);
|
|
62
|
+
const virtualizer = useVirtualizer({
|
|
63
|
+
count: data.length,
|
|
64
|
+
getScrollElement: ()=>scrollContainerRef.current,
|
|
65
|
+
estimateSize: estimateSizeFn,
|
|
66
|
+
overscan,
|
|
67
|
+
getItemKey,
|
|
68
|
+
enabled,
|
|
69
|
+
useFlushSync
|
|
70
|
+
});
|
|
71
|
+
const virtualItems = virtualizer.getVirtualItems().map((virtualItem)=>({
|
|
72
|
+
index: virtualItem.index,
|
|
73
|
+
key: virtualItem.key,
|
|
74
|
+
size: virtualItem.size,
|
|
75
|
+
start: virtualItem.start,
|
|
76
|
+
data: data[virtualItem.index]
|
|
77
|
+
}));
|
|
78
|
+
return {
|
|
79
|
+
scrollContainerRef,
|
|
80
|
+
totalSize: virtualizer.getTotalSize(),
|
|
81
|
+
virtualItems,
|
|
82
|
+
scrollToIndex: virtualizer.scrollToIndex,
|
|
83
|
+
isScrolling: virtualizer.isScrolling,
|
|
84
|
+
virtualizer,
|
|
85
|
+
measureElement: virtualizer.measureElement
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { useVirtualDataGrid };
|
package/package.json
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@versini/ui-datagrid",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": "Arno Versini",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://www.npmjs.com/package/@versini/ui-datagrid",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git@github.com:aversini/ui-components.git"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"exports": {
|
|
16
|
+
"./animated": {
|
|
17
|
+
"types": "./dist/DataGridAnimated/index.d.ts",
|
|
18
|
+
"import": "./dist/DataGridAnimated/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./body": {
|
|
21
|
+
"types": "./dist/DataGridBody/index.d.ts",
|
|
22
|
+
"import": "./dist/DataGridBody/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./cell": {
|
|
25
|
+
"types": "./dist/DataGridCell/index.d.ts",
|
|
26
|
+
"import": "./dist/DataGridCell/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./cell-sort": {
|
|
29
|
+
"types": "./dist/DataGridCellSort/index.d.ts",
|
|
30
|
+
"import": "./dist/DataGridCellSort/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./constants": {
|
|
33
|
+
"types": "./dist/DataGridConstants/index.d.ts",
|
|
34
|
+
"import": "./dist/DataGridConstants/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./datagrid": {
|
|
37
|
+
"types": "./dist/DataGrid/index.d.ts",
|
|
38
|
+
"import": "./dist/DataGrid/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./footer": {
|
|
41
|
+
"types": "./dist/DataGridFooter/index.d.ts",
|
|
42
|
+
"import": "./dist/DataGridFooter/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./header": {
|
|
45
|
+
"types": "./dist/DataGridHeader/index.d.ts",
|
|
46
|
+
"import": "./dist/DataGridHeader/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./infinite": {
|
|
49
|
+
"types": "./dist/DataGridInfinite/index.d.ts",
|
|
50
|
+
"import": "./dist/DataGridInfinite/index.js"
|
|
51
|
+
},
|
|
52
|
+
"./row": {
|
|
53
|
+
"types": "./dist/DataGridRow/index.d.ts",
|
|
54
|
+
"import": "./dist/DataGridRow/index.js"
|
|
55
|
+
},
|
|
56
|
+
"./sorting": {
|
|
57
|
+
"types": "./dist/DataGridSorting/index.d.ts",
|
|
58
|
+
"import": "./dist/DataGridSorting/index.js"
|
|
59
|
+
},
|
|
60
|
+
"./virtual": {
|
|
61
|
+
"types": "./dist/DataGridVirtual/index.d.ts",
|
|
62
|
+
"import": "./dist/DataGridVirtual/index.js"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"files": [
|
|
66
|
+
"dist",
|
|
67
|
+
"README.md"
|
|
68
|
+
],
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build:check": "tsc",
|
|
71
|
+
"build:js": "rslib build",
|
|
72
|
+
"build:types": "echo 'Types now built with rslib'",
|
|
73
|
+
"build": "npm-run-all --serial clean build:check build:js",
|
|
74
|
+
"clean": "rimraf dist tmp coverage",
|
|
75
|
+
"dev:js": "rslib build --watch",
|
|
76
|
+
"dev:types": "echo 'Types now watched with rslib'",
|
|
77
|
+
"dev": "rslib build --watch",
|
|
78
|
+
"lint": "biome lint src",
|
|
79
|
+
"lint:fix": "biome check src --write --no-errors-on-unmatched",
|
|
80
|
+
"prettier": "biome check --write --no-errors-on-unmatched",
|
|
81
|
+
"start": "static-server dist --port 5173",
|
|
82
|
+
"test:coverage:ui": "vitest --coverage --ui",
|
|
83
|
+
"test:coverage": "vitest run --coverage",
|
|
84
|
+
"test:watch": "vitest",
|
|
85
|
+
"test": "vitest run"
|
|
86
|
+
},
|
|
87
|
+
"devDependencies": {
|
|
88
|
+
"@testing-library/jest-dom": "6.9.1",
|
|
89
|
+
"@versini/ui-types": "8.3.0"
|
|
90
|
+
},
|
|
91
|
+
"dependencies": {
|
|
92
|
+
"@tailwindcss/typography": "0.5.19",
|
|
93
|
+
"@tanstack/react-virtual": "3.13.16",
|
|
94
|
+
"@versini/ui-button": "11.3.2",
|
|
95
|
+
"@versini/ui-icons": "4.16.1",
|
|
96
|
+
"clsx": "2.1.1",
|
|
97
|
+
"tailwindcss": "4.1.18"
|
|
98
|
+
},
|
|
99
|
+
"sideEffects": [
|
|
100
|
+
"**/*.css"
|
|
101
|
+
],
|
|
102
|
+
"gitHead": "d88af405285c38faec12d7cb52e575207b99173f"
|
|
103
|
+
}
|