@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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +294 -0
  3. package/dist/DataGrid/DataGrid.d.ts +2 -0
  4. package/dist/DataGrid/DataGrid.js +132 -0
  5. package/dist/DataGrid/DataGridContext.d.ts +2 -0
  6. package/dist/DataGrid/DataGridContext.js +16 -0
  7. package/dist/DataGrid/index.d.ts +2 -0
  8. package/dist/DataGrid/index.js +17 -0
  9. package/dist/DataGrid/utilities.d.ts +36 -0
  10. package/dist/DataGrid/utilities.js +99 -0
  11. package/dist/DataGridAnimated/AnimatedWrapper.d.ts +47 -0
  12. package/dist/DataGridAnimated/AnimatedWrapper.js +49 -0
  13. package/dist/DataGridAnimated/index.d.ts +4 -0
  14. package/dist/DataGridAnimated/index.js +17 -0
  15. package/dist/DataGridAnimated/useAnimatedHeight.d.ts +49 -0
  16. package/dist/DataGridAnimated/useAnimatedHeight.js +131 -0
  17. package/dist/DataGridBody/DataGridBody.d.ts +2 -0
  18. package/dist/DataGridBody/DataGridBody.js +38 -0
  19. package/dist/DataGridBody/index.d.ts +1 -0
  20. package/dist/DataGridBody/index.js +13 -0
  21. package/dist/DataGridCell/DataGridCell.d.ts +14 -0
  22. package/dist/DataGridCell/DataGridCell.js +77 -0
  23. package/dist/DataGridCell/index.d.ts +1 -0
  24. package/dist/DataGridCell/index.js +13 -0
  25. package/dist/DataGridCellSort/DataGridCellSort.d.ts +2 -0
  26. package/dist/DataGridCellSort/DataGridCellSort.js +107 -0
  27. package/dist/DataGridCellSort/index.d.ts +1 -0
  28. package/dist/DataGridCellSort/index.js +13 -0
  29. package/dist/DataGridConstants/DataGridConstants.d.ts +37 -0
  30. package/dist/DataGridConstants/DataGridConstants.js +38 -0
  31. package/dist/DataGridConstants/index.d.ts +1 -0
  32. package/dist/DataGridConstants/index.js +13 -0
  33. package/dist/DataGridFooter/DataGridFooter.d.ts +12 -0
  34. package/dist/DataGridFooter/DataGridFooter.js +81 -0
  35. package/dist/DataGridFooter/index.d.ts +1 -0
  36. package/dist/DataGridFooter/index.js +13 -0
  37. package/dist/DataGridHeader/DataGridHeader.d.ts +13 -0
  38. package/dist/DataGridHeader/DataGridHeader.js +80 -0
  39. package/dist/DataGridHeader/index.d.ts +1 -0
  40. package/dist/DataGridHeader/index.js +13 -0
  41. package/dist/DataGridInfinite/InfiniteScrollMarker.d.ts +35 -0
  42. package/dist/DataGridInfinite/InfiniteScrollMarker.js +53 -0
  43. package/dist/DataGridInfinite/index.d.ts +4 -0
  44. package/dist/DataGridInfinite/index.js +17 -0
  45. package/dist/DataGridInfinite/useInfiniteScroll.d.ts +81 -0
  46. package/dist/DataGridInfinite/useInfiniteScroll.js +117 -0
  47. package/dist/DataGridRow/DataGridRow.d.ts +2 -0
  48. package/dist/DataGridRow/DataGridRow.js +75 -0
  49. package/dist/DataGridRow/index.d.ts +1 -0
  50. package/dist/DataGridRow/index.js +13 -0
  51. package/dist/DataGridSorting/index.d.ts +2 -0
  52. package/dist/DataGridSorting/index.js +18 -0
  53. package/dist/DataGridSorting/sortingUtils.d.ts +138 -0
  54. package/dist/DataGridSorting/sortingUtils.js +234 -0
  55. package/dist/DataGridVirtual/VirtualDataGrid.d.ts +114 -0
  56. package/dist/DataGridVirtual/VirtualDataGrid.js +181 -0
  57. package/dist/DataGridVirtual/index.d.ts +6 -0
  58. package/dist/DataGridVirtual/index.js +22 -0
  59. package/dist/DataGridVirtual/useVirtualDataGrid.d.ts +112 -0
  60. package/dist/DataGridVirtual/useVirtualDataGrid.js +89 -0
  61. 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
+ }