@versini/ui-datagrid 0.3.7 → 0.4.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 (46) hide show
  1. package/README.md +106 -29
  2. package/dist/DataGrid/DataGrid.js +7 -7
  3. package/dist/DataGrid/DataGridContext.js +1 -1
  4. package/dist/DataGrid/index.js +1 -1
  5. package/dist/DataGridAnimated/AnimatedWrapper.d.ts +11 -7
  6. package/dist/DataGridAnimated/AnimatedWrapper.js +12 -8
  7. package/dist/DataGridAnimated/index.js +1 -1
  8. package/dist/DataGridAnimated/useAnimatedHeight.js +1 -1
  9. package/dist/DataGridBody/DataGridBody.js +12 -54
  10. package/dist/DataGridBody/getBodyClass.d.ts +9 -0
  11. package/dist/DataGridBody/getBodyClass.js +23 -0
  12. package/dist/DataGridBody/index.js +1 -1
  13. package/dist/DataGridBody/useColumnMeasurement.d.ts +10 -0
  14. package/dist/DataGridBody/useColumnMeasurement.js +67 -0
  15. package/dist/DataGridCell/DataGridCell.d.ts +0 -10
  16. package/dist/DataGridCell/DataGridCell.js +4 -58
  17. package/dist/DataGridCell/index.js +1 -1
  18. package/dist/DataGridCellSort/DataGridCellSort.js +3 -3
  19. package/dist/DataGridCellSort/index.js +1 -1
  20. package/dist/DataGridConstants/DataGridConstants.js +1 -1
  21. package/dist/DataGridConstants/index.js +1 -1
  22. package/dist/DataGridFooter/DataGridFooter.d.ts +0 -15
  23. package/dist/DataGridFooter/DataGridFooter.js +6 -42
  24. package/dist/DataGridFooter/index.js +1 -1
  25. package/dist/DataGridHeader/DataGridHeader.d.ts +0 -27
  26. package/dist/DataGridHeader/DataGridHeader.js +6 -54
  27. package/dist/DataGridHeader/index.js +1 -1
  28. package/dist/DataGridInfinite/DataGridInfiniteBody.d.ts +52 -0
  29. package/dist/DataGridInfinite/DataGridInfiniteBody.js +309 -0
  30. package/dist/DataGridInfinite/index.d.ts +2 -4
  31. package/dist/DataGridInfinite/index.js +4 -8
  32. package/dist/DataGridRow/DataGridRow.js +10 -34
  33. package/dist/DataGridRow/index.js +1 -1
  34. package/dist/DataGridSorting/index.js +1 -1
  35. package/dist/DataGridSorting/sortingUtils.js +1 -1
  36. package/dist/utilities/classes.d.ts +150 -0
  37. package/dist/utilities/classes.js +249 -0
  38. package/package.json +2 -2
  39. package/dist/DataGrid/utilities.d.ts +0 -44
  40. package/dist/DataGrid/utilities.js +0 -92
  41. package/dist/DataGridInfinite/InfiniteScrollMarker.d.ts +0 -31
  42. package/dist/DataGridInfinite/InfiniteScrollMarker.js +0 -54
  43. package/dist/DataGridInfinite/useInfiniteScroll.d.ts +0 -92
  44. package/dist/DataGridInfinite/useInfiniteScroll.js +0 -136
  45. package/dist/common/utilities.d.ts +0 -15
  46. package/dist/common/utilities.js +0 -48
@@ -1,31 +0,0 @@
1
- export type InfiniteScrollMarkerProps = {
2
- /**
3
- * Custom class name for the row.
4
- */
5
- className?: string;
6
- /**
7
- * Whether to show the marker (for debugging). In production, the marker is
8
- * invisible.
9
- */
10
- debug?: boolean;
11
- };
12
- /**
13
- * Invisible marker row for infinite scroll. Place this at the end of your
14
- * DataGridBody.
15
- *
16
- * @example
17
- * ```tsx
18
- * const { hasMore, markerRef } = useInfiniteScroll({ totalItems: data.length });
19
- *
20
- * return (
21
- * <DataGridBody>
22
- * {data.slice(0, visibleCount).map((item) => (
23
- * <DataGridRow key={item.id}>...</DataGridRow>
24
- * ))}
25
- * {hasMore && <InfiniteScrollMarker ref={markerRef} />}
26
- * </DataGridBody>
27
- * );
28
- * ```
29
- *
30
- */
31
- export declare const InfiniteScrollMarker: import("react").ForwardRefExoticComponent<InfiniteScrollMarkerProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,54 +0,0 @@
1
- /*!
2
- @versini/ui-datagrid v0.3.7
3
- © 2026 gizmette.com
4
- */
5
-
6
- import { jsx } from "react/jsx-runtime";
7
- import { forwardRef } from "react";
8
-
9
- ;// CONCATENATED MODULE: external "react/jsx-runtime"
10
-
11
- ;// CONCATENATED MODULE: external "react"
12
-
13
- ;// CONCATENATED MODULE: ./src/DataGridInfinite/InfiniteScrollMarker.tsx
14
-
15
-
16
- /**
17
- * Invisible marker row for infinite scroll. Place this at the end of your
18
- * DataGridBody.
19
- *
20
- * @example
21
- * ```tsx
22
- * const { hasMore, markerRef } = useInfiniteScroll({ totalItems: data.length });
23
- *
24
- * return (
25
- * <DataGridBody>
26
- * {data.slice(0, visibleCount).map((item) => (
27
- * <DataGridRow key={item.id}>...</DataGridRow>
28
- * ))}
29
- * {hasMore && <InfiniteScrollMarker ref={markerRef} />}
30
- * </DataGridBody>
31
- * );
32
- * ```
33
- *
34
- */ const InfiniteScrollMarker_InfiniteScrollMarker = /*#__PURE__*/ forwardRef(function InfiniteScrollMarker({ className, debug = false }, ref) {
35
- return /*#__PURE__*/ jsx("div", {
36
- ref: ref,
37
- role: "row",
38
- className: className,
39
- "aria-hidden": "true",
40
- style: {
41
- height: debug ? "40px" : "1px",
42
- background: debug ? "red" : "transparent"
43
- },
44
- children: /*#__PURE__*/ jsx("div", {
45
- role: "gridcell",
46
- style: {
47
- padding: 0,
48
- border: 0
49
- }
50
- })
51
- });
52
- });
53
-
54
- export { InfiniteScrollMarker_InfiniteScrollMarker as InfiniteScrollMarker };
@@ -1,92 +0,0 @@
1
- /**
2
- * Finds the nearest scrollable ancestor of an element. Returns null if no
3
- * scrollable ancestor is found (uses viewport).
4
- */
5
- export declare function findScrollableAncestor(element: HTMLElement): Element | null;
6
- export type UseInfiniteScrollOptions = {
7
- /**
8
- * Number of items to show initially and to add on each scroll.
9
- * @default 20
10
- */
11
- batchSize?: number;
12
- /**
13
- * How many items before the end to trigger loading more.
14
- * @default 5
15
- */
16
- threshold?: number;
17
- /**
18
- * IntersectionObserver root margin.
19
- * @default "20px"
20
- */
21
- rootMargin?: string;
22
- /**
23
- * Total number of items in the dataset. Used to determine if more items can be
24
- * loaded.
25
- */
26
- totalItems: number;
27
- /**
28
- * Initial number of visible items (optional). If not provided, uses batchSize.
29
- * + threshold.
30
- */
31
- initialVisibleCount?: number;
32
- /**
33
- * Callback when more items are loaded.
34
- */
35
- onLoadMore?: (newVisibleCount: number) => void;
36
- /**
37
- * The scroll container element for IntersectionObserver root. Required when
38
- * the DataGrid is inside a scrollable container (e.g., with maxHeight). Pass
39
- * null to use the viewport as root.
40
- */
41
- scrollContainer?: Element | null;
42
- };
43
- export type UseInfiniteScrollReturn = {
44
- /**
45
- * Current number of visible items.
46
- */
47
- visibleCount: number;
48
- /**
49
- * Whether there are more items to load.
50
- */
51
- hasMore: boolean;
52
- /**
53
- * Callback ref to attach to the marker element.
54
- */
55
- markerRef: (node: HTMLElement | null) => void;
56
- /**
57
- * Reset visible count to initial value.
58
- */
59
- reset: () => void;
60
- /**
61
- * Manually set the visible count (useful for scroll-to-item).
62
- */
63
- setVisibleCount: React.Dispatch<React.SetStateAction<number>>;
64
- /**
65
- * Expand visible count to include a specific index.
66
- */
67
- expandToInclude: (index: number) => void;
68
- };
69
- /**
70
- * Hook for implementing infinite scroll with IntersectionObserver.
71
- *
72
- * @example
73
- * ```tsx
74
- * const { visibleCount, hasMore, markerRef } = useInfiniteScroll({
75
- * totalItems: data.length,
76
- * batchSize: 25,
77
- * });
78
- *
79
- * return (
80
- * <DataGrid>
81
- * <DataGridBody>
82
- * {data.slice(0, visibleCount).map((item, index) => (
83
- * <DataGridRow key={item.id}>...</DataGridRow>
84
- * ))}
85
- * {hasMore && <InfiniteScrollMarker ref={markerRef} />}
86
- * </DataGridBody>
87
- * </DataGrid>
88
- * );
89
- * ```
90
- *
91
- */
92
- export declare function useInfiniteScroll({ batchSize, threshold, rootMargin, totalItems, initialVisibleCount, onLoadMore, scrollContainer, }: UseInfiniteScrollOptions): UseInfiniteScrollReturn;
@@ -1,136 +0,0 @@
1
- /*!
2
- @versini/ui-datagrid v0.3.7
3
- © 2026 gizmette.com
4
- */
5
-
6
- import { useCallback, useEffect, useRef, useState } from "react";
7
-
8
- ;// CONCATENATED MODULE: external "react"
9
-
10
- ;// CONCATENATED MODULE: ./src/DataGridInfinite/useInfiniteScroll.ts
11
-
12
- const DEFAULT_BATCH_SIZE = 20;
13
- const DEFAULT_THRESHOLD = 5;
14
- const DEFAULT_ROOT_MARGIN = "20px";
15
- /**
16
- * Finds the nearest scrollable ancestor of an element. Returns null if no
17
- * scrollable ancestor is found (uses viewport).
18
- */ function findScrollableAncestor(element) {
19
- let parent = element.parentElement;
20
- while(parent){
21
- const style = getComputedStyle(parent);
22
- const overflowY = style.overflowY;
23
- if (overflowY === "auto" || overflowY === "scroll") {
24
- return parent;
25
- }
26
- parent = parent.parentElement;
27
- }
28
- return null;
29
- }
30
- /**
31
- * Hook for implementing infinite scroll with IntersectionObserver.
32
- *
33
- * @example
34
- * ```tsx
35
- * const { visibleCount, hasMore, markerRef } = useInfiniteScroll({
36
- * totalItems: data.length,
37
- * batchSize: 25,
38
- * });
39
- *
40
- * return (
41
- * <DataGrid>
42
- * <DataGridBody>
43
- * {data.slice(0, visibleCount).map((item, index) => (
44
- * <DataGridRow key={item.id}>...</DataGridRow>
45
- * ))}
46
- * {hasMore && <InfiniteScrollMarker ref={markerRef} />}
47
- * </DataGridBody>
48
- * </DataGrid>
49
- * );
50
- * ```
51
- *
52
- */ function useInfiniteScroll({ batchSize = DEFAULT_BATCH_SIZE, threshold = DEFAULT_THRESHOLD, rootMargin = DEFAULT_ROOT_MARGIN, totalItems, initialVisibleCount, onLoadMore, scrollContainer }) {
53
- const observerRef = useRef(null);
54
- const initialCount = initialVisibleCount ?? batchSize + threshold;
55
- const [visibleCount, setVisibleCount] = useState(Math.min(initialCount, totalItems));
56
- const hasMore = visibleCount < totalItems;
57
- /**
58
- * IntersectionObserver callback - triggered when marker becomes visible.
59
- */ const handleIntersection = useCallback((entries)=>{
60
- const target = entries[0];
61
- if (target?.isIntersecting) {
62
- setVisibleCount((prev)=>{
63
- const newCount = Math.min(prev + batchSize, totalItems);
64
- if (onLoadMore && newCount > prev) {
65
- onLoadMore(newCount);
66
- }
67
- return newCount;
68
- });
69
- }
70
- }, [
71
- batchSize,
72
- totalItems,
73
- onLoadMore
74
- ]);
75
- /**
76
- * Callback ref for the marker element. Creates/disconnects observer as needed.
77
- */ const markerRef = useCallback((node)=>{
78
- // Disconnect previous observer.
79
- if (observerRef.current) {
80
- observerRef.current.disconnect();
81
- observerRef.current = null;
82
- }
83
- if (node && typeof IntersectionObserver !== "undefined") {
84
- // Find the scrollable ancestor if not explicitly provided.
85
- const root = scrollContainer ?? findScrollableAncestor(node);
86
- const options = {
87
- root,
88
- rootMargin
89
- };
90
- observerRef.current = new IntersectionObserver(handleIntersection, options);
91
- observerRef.current.observe(node);
92
- }
93
- }, [
94
- handleIntersection,
95
- rootMargin,
96
- scrollContainer
97
- ]);
98
- /**
99
- * Reset to initial count.
100
- */ const reset = useCallback(()=>{
101
- setVisibleCount(Math.min(initialCount, totalItems));
102
- }, [
103
- initialCount,
104
- totalItems
105
- ]);
106
- /**
107
- * Expand visible count to include a specific index. Useful for scroll-to-row
108
- * functionality.
109
- */ const expandToInclude = useCallback((index)=>{
110
- if (index >= visibleCount) {
111
- setVisibleCount(index + threshold);
112
- }
113
- }, [
114
- visibleCount,
115
- threshold
116
- ]);
117
- /**
118
- * Cleanup observer on unmount.
119
- */ useEffect(()=>{
120
- return ()=>{
121
- if (observerRef.current) {
122
- observerRef.current.disconnect();
123
- }
124
- };
125
- }, []);
126
- return {
127
- visibleCount,
128
- hasMore,
129
- markerRef,
130
- reset,
131
- setVisibleCount,
132
- expandToInclude
133
- };
134
- }
135
-
136
- export { findScrollableAncestor, useInfiniteScroll };
@@ -1,15 +0,0 @@
1
- import { type BlurEffect, type ThemeMode } from "../DataGridConstants/DataGridConstants";
2
- export declare const getHeaderFooterBackgroundClasses: ({ mode, hasBlur, sticky, }: {
3
- mode: ThemeMode;
4
- hasBlur: boolean;
5
- sticky: boolean;
6
- }) => string;
7
- export declare const getHeaderFooterCopyClasses: ({ mode }: {
8
- mode: ThemeMode;
9
- }) => string;
10
- /**
11
- * Common classes for sticky header/footer with optional blur effect.
12
- */
13
- export declare const getStickyBlurClasses: ({ blurEffect, }: {
14
- blurEffect?: BlurEffect;
15
- }) => string;
@@ -1,48 +0,0 @@
1
- /*!
2
- @versini/ui-datagrid v0.3.7
3
- © 2026 gizmette.com
4
- */
5
-
6
- import clsx from "clsx";
7
- import { BlurEffects } from "../DataGridConstants/DataGridConstants.js";
8
-
9
- ;// CONCATENATED MODULE: external "clsx"
10
-
11
- ;// CONCATENATED MODULE: external "../DataGridConstants/DataGridConstants.js"
12
-
13
- ;// CONCATENATED MODULE: ./src/common/utilities.ts
14
-
15
-
16
- const getHeaderFooterBackgroundClasses = ({ mode, hasBlur, sticky })=>{
17
- return clsx({
18
- // Semi-transparent backgrounds for blur effect.
19
- "bg-surface-darkest/50": hasBlur && sticky && (mode === "dark" || mode === "system"),
20
- "bg-surface-light/50": hasBlur && sticky && (mode === "light" || mode === "alt-system"),
21
- "dark:bg-surface-light/50": hasBlur && sticky && mode === "system",
22
- "dark:bg-surface-darkest/50": hasBlur && sticky && mode === "alt-system",
23
- // Solid backgrounds when no blur effect.
24
- "bg-surface-darkest": !hasBlur && (mode === "dark" || mode === "system"),
25
- "bg-surface-light": !hasBlur && (mode === "light" || mode === "alt-system"),
26
- "dark:bg-surface-light": !hasBlur && mode === "system",
27
- "dark:bg-surface-darkest": !hasBlur && mode === "alt-system"
28
- });
29
- };
30
- const getHeaderFooterCopyClasses = ({ mode })=>{
31
- return clsx({
32
- "text-copy-light": mode === "dark",
33
- "text-copy-dark": mode === "light",
34
- "text-copy-light dark:text-copy-dark": mode === "system",
35
- "text-copy-dark dark:text-copy-light": mode === "alt-system"
36
- });
37
- };
38
- /**
39
- * Common classes for sticky header/footer with optional blur effect.
40
- */ const getStickyBlurClasses = ({ blurEffect })=>{
41
- return clsx({
42
- "backdrop-blur-sm": blurEffect === BlurEffects.SMALL,
43
- "backdrop-blur-md": blurEffect === BlurEffects.MEDIUM,
44
- "backdrop-blur-lg": blurEffect === BlurEffects.LARGE
45
- });
46
- };
47
-
48
- export { getHeaderFooterBackgroundClasses, getHeaderFooterCopyClasses, getStickyBlurClasses };