@trackunit/react-components 1.9.19 → 1.9.21
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/index.cjs.js +472 -63
- package/index.esm.js +467 -64
- package/package.json +8 -8
- package/src/components/List/List.d.ts +64 -85
- package/src/components/List/useList.d.ts +171 -0
- package/src/components/ListItem/useListItemHeight.d.ts +35 -0
- package/src/components/index.d.ts +2 -0
- package/src/hooks/index.d.ts +3 -0
- package/src/hooks/noPagination.d.ts +2 -0
- package/src/hooks/useInfiniteScroll.d.ts +36 -0
- package/src/hooks/useRelayPagination.d.ts +43 -0
|
@@ -1,112 +1,48 @@
|
|
|
1
1
|
import { VariantProps } from "@trackunit/css-class-variance-utilities";
|
|
2
|
-
import {
|
|
3
|
-
import { CSSProperties, ReactElement, Ref } from "react";
|
|
2
|
+
import { ReactElement } from "react";
|
|
4
3
|
import { CommonProps } from "../../common/CommonProps";
|
|
5
4
|
import { cvaListItem } from "./List.variants";
|
|
6
|
-
import {
|
|
5
|
+
import { UseListResult, VirtualizationListItemProps } from "./useList";
|
|
7
6
|
type Separator = NonNullable<VariantProps<typeof cvaListItem>["separator"]>;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* These handle positioning, measurement, accessibility, and interaction.
|
|
11
|
-
*
|
|
12
|
-
* **Important**: Consumers must add a `key` prop to their list items using the index parameter.
|
|
13
|
-
*/ export interface VirtualizationListItemProps {
|
|
14
|
-
/** CSS classes for list styling and separators */
|
|
15
|
-
className: string;
|
|
16
|
-
/** Critical positioning styles for virtual scrolling */
|
|
17
|
-
style: CSSProperties;
|
|
18
|
-
/** Element ref for virtualization measurement */
|
|
19
|
-
ref?: Ref<any>;
|
|
20
|
-
/** Click handler for row-level interactions */
|
|
21
|
-
onClick?: () => void;
|
|
22
|
-
/** Data attribute for accessibility and debugging */
|
|
23
|
-
"data-index": number;
|
|
24
|
-
/** Tab index for keyboard navigation */
|
|
25
|
-
tabIndex: number;
|
|
26
|
-
}
|
|
27
|
-
export interface ListProps<TItem = unknown> extends CommonProps {
|
|
28
|
-
/**
|
|
29
|
-
* Number of items in the list (excluding header if provided).
|
|
30
|
-
*/
|
|
31
|
-
count: number;
|
|
32
|
-
/**
|
|
33
|
-
* Pagination configuration for infinite scrolling.
|
|
34
|
-
*/
|
|
35
|
-
pagination?: RelayPagination;
|
|
36
|
-
/**
|
|
37
|
-
* Optional header element displayed at the top of the list.
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```tsx
|
|
41
|
-
* <List header={<KPI title="Total" value={42} />} ... />
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
header?: ReactElement;
|
|
7
|
+
export type { VirtualizationListItemProps } from "./useList";
|
|
8
|
+
export interface ListProps<TItem = unknown> extends CommonProps, UseListResult<TItem> {
|
|
45
9
|
/**
|
|
46
|
-
* Function that
|
|
10
|
+
* Function that renders each list item. Must spread `listItemProps` onto your element
|
|
11
|
+
* and use the provided `key` prop for React's reconciliation.
|
|
47
12
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* getItem={index => items[index]}
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
getItem: (index: number) => TItem;
|
|
54
|
-
/**
|
|
55
|
-
* Function that renders each list item. Must spread `listItemProps` onto your element and apply a `key` prop.
|
|
13
|
+
* **Note**: `item` may be undefined if `getItem` returns undefined (legacy pattern).
|
|
14
|
+
* Consumers are responsible for handling this case.
|
|
56
15
|
*
|
|
57
16
|
* @example
|
|
58
17
|
* ```tsx
|
|
59
|
-
* {(listItemProps, item, index) => (
|
|
60
|
-
* <ListItem key={
|
|
18
|
+
* {({ key, listItemProps, item, index }) => (
|
|
19
|
+
* <ListItem key={key} {...listItemProps} title={item?.name} />
|
|
61
20
|
* )}
|
|
62
21
|
* ```
|
|
63
22
|
*/
|
|
64
|
-
children: (
|
|
23
|
+
children: (params: {
|
|
24
|
+
key: string | number | bigint;
|
|
25
|
+
listItemProps: VirtualizationListItemProps;
|
|
26
|
+
item: TItem | undefined;
|
|
27
|
+
index: number;
|
|
28
|
+
}) => ReactElement | null;
|
|
65
29
|
/**
|
|
66
30
|
* Separator style between list items.
|
|
67
31
|
*/
|
|
68
32
|
separator?: Separator;
|
|
69
|
-
/**
|
|
70
|
-
* Loading indicator configuration for pagination loading.
|
|
71
|
-
*/
|
|
72
|
-
loadingIndicator?: ListLoadingIndicatorProps;
|
|
73
|
-
/**
|
|
74
|
-
* Callback fired when a row is clicked.
|
|
75
|
-
*/
|
|
76
|
-
onRowClick?: (item: TItem, index: number) => void;
|
|
77
|
-
/**
|
|
78
|
-
* Callback for scroll state changes.
|
|
79
|
-
*/
|
|
80
|
-
onScrollStateChange?: (scrollOffset: number, isScrolling: boolean) => void;
|
|
81
33
|
/**
|
|
82
34
|
* Show a top separator when the list is scrolled.
|
|
83
35
|
*/
|
|
84
36
|
topSeparatorOnScroll?: boolean;
|
|
85
|
-
/**
|
|
86
|
-
* Function to estimate item height for scroll performance.
|
|
87
|
-
*
|
|
88
|
-
* **Best Practice:** Always provide this function, even for fixed-height items.
|
|
89
|
-
* Measure the actual height in browser DevTools and return that value for optimal scrolling.
|
|
90
|
-
*
|
|
91
|
-
* The virtualizer uses these estimates for scroll calculations and viewport positioning.
|
|
92
|
-
* More accurate estimates result in smoother scrolling.
|
|
93
|
-
*
|
|
94
|
-
* @example Fixed height
|
|
95
|
-
* ```tsx
|
|
96
|
-
* estimateItemSize={() => 61} // Measured ListItem height
|
|
97
|
-
* ```
|
|
98
|
-
* @example Variable height
|
|
99
|
-
* ```tsx
|
|
100
|
-
* estimateItemSize={(index) => items[index]?.hasDescription ? 80 : 50}
|
|
101
|
-
* ```
|
|
102
|
-
*/
|
|
103
|
-
estimateItemSize?: (index: number) => number;
|
|
104
37
|
}
|
|
105
38
|
/**
|
|
106
39
|
* A performant virtualized list component with infinite scrolling support.
|
|
107
40
|
*
|
|
108
41
|
* ⚠️ **Important**: Requires a container with defined height to work properly.
|
|
109
42
|
*
|
|
43
|
+
* **Usage Pattern**: Always use the `useList` hook in your component and spread the result into this component.
|
|
44
|
+
* This gives you access to the virtualizer state (scroll position, isScrolling, etc.) in the parent.
|
|
45
|
+
*
|
|
110
46
|
* Features:
|
|
111
47
|
* - Virtualized rendering using TanStack Virtual for performance with large datasets
|
|
112
48
|
* - Automatic infinite scroll loading when approaching the end of the list
|
|
@@ -115,10 +51,53 @@ export interface ListProps<TItem = unknown> extends CommonProps {
|
|
|
115
51
|
* - Configurable loading indicators (skeleton, spinner, or custom)
|
|
116
52
|
* - Scroll state detection and callbacks
|
|
117
53
|
* - Variable-height item support via `estimateItemSize`
|
|
54
|
+
* - Dynamic measurement for accurate positioning of variable-height items
|
|
118
55
|
*
|
|
119
56
|
* The component automatically loads more data when:
|
|
120
57
|
* - User scrolls to the last visible item
|
|
121
58
|
* - Content height is insufficient to fill the container
|
|
59
|
+
*
|
|
60
|
+
* **Headers with Different Heights**: When using a header that differs in height from list items,
|
|
61
|
+
* provide `estimateHeaderSize` for optimal initial rendering. The list automatically measures
|
|
62
|
+
* actual heights on mount to ensure correct positioning.
|
|
63
|
+
*
|
|
64
|
+
* @example Basic usage
|
|
65
|
+
* ```tsx
|
|
66
|
+
* const list = useList({
|
|
67
|
+
* count: items.length,
|
|
68
|
+
* getItem: index => items[index],
|
|
69
|
+
* estimateItemSize: () => 61,
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* return (
|
|
73
|
+
* <List {...list}>
|
|
74
|
+
* {({ key, listItemProps, item }) => (
|
|
75
|
+
* <ListItem key={key} {...listItemProps} title={item?.name} />
|
|
76
|
+
* )}
|
|
77
|
+
* </List>
|
|
78
|
+
* );
|
|
79
|
+
* ```
|
|
80
|
+
* @example With header
|
|
81
|
+
* ```tsx
|
|
82
|
+
* const list = useList({
|
|
83
|
+
* count: items.length,
|
|
84
|
+
* getItem: index => items[index],
|
|
85
|
+
* header: <KPI title="Total" value={42} />,
|
|
86
|
+
* estimateHeaderSize: () => 72, // Actual KPI height
|
|
87
|
+
* estimateItemSize: () => 61, // Actual ListItem height
|
|
88
|
+
* });
|
|
89
|
+
*
|
|
90
|
+
* // Access virtualizer state in parent
|
|
91
|
+
* console.log('Scroll position:', list.scrollOffset);
|
|
92
|
+
* console.log('Is scrolling:', list.isScrolling);
|
|
93
|
+
*
|
|
94
|
+
* return (
|
|
95
|
+
* <List {...list}>
|
|
96
|
+
* {({ key, listItemProps, item }) => (
|
|
97
|
+
* <ListItem key={key} {...listItemProps} title={item?.name} />
|
|
98
|
+
* )}
|
|
99
|
+
* </List>
|
|
100
|
+
* );
|
|
101
|
+
* ```
|
|
122
102
|
*/
|
|
123
|
-
export declare const List: <TItem = unknown>({
|
|
124
|
-
export {};
|
|
103
|
+
export declare const List: <TItem = unknown>({ children, className, dataTestId, topSeparatorOnScroll, separator, containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, scrollOffset, getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }: ListProps<TItem>) => ReactElement;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import type { VirtualItem, Virtualizer } from "@tanstack/react-virtual";
|
|
2
|
+
import { ReactElement, RefObject } from "react";
|
|
3
|
+
import { RelayPagination } from "../../hooks";
|
|
4
|
+
import { ListLoadingIndicatorProps } from "./ListLoadingIndicator";
|
|
5
|
+
/**
|
|
6
|
+
* Props that must be spread onto list items for proper virtualization.
|
|
7
|
+
* These handle positioning, measurement, accessibility, and interaction.
|
|
8
|
+
*
|
|
9
|
+
* **Important**: Consumers must add a `key` prop to their list items using the index parameter.
|
|
10
|
+
*/
|
|
11
|
+
export interface VirtualizationListItemProps {
|
|
12
|
+
/** CSS classes for list styling and separators */
|
|
13
|
+
className: string;
|
|
14
|
+
/** Element ref for virtualization measurement and setting positioning transform styles */
|
|
15
|
+
ref?: (node: HTMLLIElement | null) => void;
|
|
16
|
+
/** Click handler for row-level interactions */
|
|
17
|
+
onClick?: () => void;
|
|
18
|
+
/** Data attribute for accessibility and debugging */
|
|
19
|
+
"data-index": number;
|
|
20
|
+
/** Tab index for keyboard navigation */
|
|
21
|
+
tabIndex: number;
|
|
22
|
+
}
|
|
23
|
+
export interface UseListOptions<TItem = unknown> {
|
|
24
|
+
/**
|
|
25
|
+
* Number of data items in the list (excluding header if provided).
|
|
26
|
+
*/
|
|
27
|
+
count: number;
|
|
28
|
+
/**
|
|
29
|
+
* Pagination configuration for infinite scrolling.
|
|
30
|
+
*/
|
|
31
|
+
pagination?: RelayPagination;
|
|
32
|
+
/**
|
|
33
|
+
* Optional header element displayed at the top of the list.
|
|
34
|
+
*/
|
|
35
|
+
header?: ReactElement;
|
|
36
|
+
/**
|
|
37
|
+
* Function that returns the item data for a given data index.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* getItem={index => items[index]}
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
getItem: (index: number) => TItem;
|
|
45
|
+
/**
|
|
46
|
+
* Loading indicator configuration for pagination loading.
|
|
47
|
+
*/
|
|
48
|
+
loadingIndicator?: ListLoadingIndicatorProps;
|
|
49
|
+
/**
|
|
50
|
+
* Callback fired when a row is clicked.
|
|
51
|
+
*/
|
|
52
|
+
onRowClick?: (params: {
|
|
53
|
+
item: TItem;
|
|
54
|
+
index: number;
|
|
55
|
+
}) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Callback for scroll state changes.
|
|
58
|
+
*/
|
|
59
|
+
onChange?: (virtualizer: Virtualizer<HTMLDivElement, HTMLLIElement>) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Function to estimate item height for scroll performance.
|
|
62
|
+
*
|
|
63
|
+
* Measure the actual height in browser DevTools and return that value for optimal scrolling.
|
|
64
|
+
*
|
|
65
|
+
* The virtualizer uses these estimates for scroll calculations and viewport positioning.
|
|
66
|
+
* More accurate estimates result in smoother scrolling.
|
|
67
|
+
*
|
|
68
|
+
* **Important**: If providing a header, also provide `estimateHeaderSize` to avoid overlap issues.
|
|
69
|
+
*
|
|
70
|
+
* @example Fixed height
|
|
71
|
+
* ```tsx
|
|
72
|
+
* estimateItemSize={() => 61} // Measured ListItem height
|
|
73
|
+
* ```
|
|
74
|
+
* @example Variable height
|
|
75
|
+
* ```tsx
|
|
76
|
+
* estimateItemSize={(index) => items[index]?.hasDescription ? 80 : 50}
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
estimateItemSize: (index: number) => number;
|
|
80
|
+
/**
|
|
81
|
+
* Function to estimate the header height for scroll performance.
|
|
82
|
+
*
|
|
83
|
+
* Only used when `header` is provided. If not specified, falls back to `estimateItemSize(0)`.
|
|
84
|
+
*
|
|
85
|
+
* Measure the actual header height in browser DevTools for optimal positioning.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```tsx
|
|
89
|
+
* header: <KPI title="Total" value={42} />,
|
|
90
|
+
* estimateHeaderSize: () => 72, // Measured KPI height
|
|
91
|
+
* estimateItemSize: () => 61, // Measured ListItem height
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
estimateHeaderSize?: () => number;
|
|
95
|
+
/**
|
|
96
|
+
* Additional overscan for virtualization (items to render outside viewport).
|
|
97
|
+
* Higher values reduce blank areas during fast scrolling but increase memory usage.
|
|
98
|
+
*/
|
|
99
|
+
overscan?: number;
|
|
100
|
+
}
|
|
101
|
+
export type ListRowType = "header" | "data" | "loader";
|
|
102
|
+
export type ListRow<TItem> = {
|
|
103
|
+
type: "header";
|
|
104
|
+
virtualRow: VirtualItem;
|
|
105
|
+
item?: never;
|
|
106
|
+
dataIndex: -1;
|
|
107
|
+
} | {
|
|
108
|
+
type: "loader";
|
|
109
|
+
virtualRow: VirtualItem;
|
|
110
|
+
item?: never;
|
|
111
|
+
dataIndex: -1;
|
|
112
|
+
} | {
|
|
113
|
+
type: "data";
|
|
114
|
+
virtualRow: VirtualItem;
|
|
115
|
+
item: TItem | undefined;
|
|
116
|
+
dataIndex: number;
|
|
117
|
+
};
|
|
118
|
+
export interface UseListResult<TItem> extends Pick<Virtualizer<HTMLDivElement, HTMLLIElement>, "scrollOffset" | "isScrolling" | "getTotalSize" | "getVirtualItems" | "scrollToOffset" | "scrollToIndex" | "measure"> {
|
|
119
|
+
/** Reference to attach to the scrollable container */
|
|
120
|
+
containerRef: RefObject<HTMLDivElement | null>;
|
|
121
|
+
/** Reference to attach to the list */
|
|
122
|
+
listRef: RefObject<HTMLUListElement | null>;
|
|
123
|
+
/** Array of row data to render */
|
|
124
|
+
readonly rows: ReadonlyArray<ListRow<TItem>>;
|
|
125
|
+
/** Helper to create list item props for a given row */
|
|
126
|
+
readonly getListItemProps: (row: ListRow<TItem>, options: {
|
|
127
|
+
className: string;
|
|
128
|
+
onClick?: () => void;
|
|
129
|
+
}) => VirtualizationListItemProps;
|
|
130
|
+
/** Header element (if provided) */
|
|
131
|
+
readonly header?: ReactElement;
|
|
132
|
+
/** Loading indicator configuration */
|
|
133
|
+
readonly loadingIndicator?: ListLoadingIndicatorProps;
|
|
134
|
+
/** Helper to determine if a specific loader index should be shown */
|
|
135
|
+
readonly shouldShowLoaderAtIndex: (loaderIndex: number) => boolean;
|
|
136
|
+
/** Total number of data items (for consistent calculations) */
|
|
137
|
+
readonly count: number;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* A hook for managing virtualized list state and behavior.
|
|
141
|
+
*
|
|
142
|
+
* This hook encapsulates the logic for:
|
|
143
|
+
* - Virtualizing list items using TanStack Virtual
|
|
144
|
+
* - Managing infinite scroll pagination
|
|
145
|
+
* - Handling header, data, and loading rows
|
|
146
|
+
* - Calculating proper indices and measurements
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```tsx
|
|
150
|
+
* const list = useList({
|
|
151
|
+
* count: items.length,
|
|
152
|
+
* getItem: index => items[index],
|
|
153
|
+
* pagination,
|
|
154
|
+
* header: <KPI title="Total" value={42} />,
|
|
155
|
+
* estimateHeaderSize: () => 72, // Measure actual KPI height
|
|
156
|
+
* estimateItemSize: () => 61, // Measure actual ListItem height
|
|
157
|
+
* });
|
|
158
|
+
*
|
|
159
|
+
* return (
|
|
160
|
+
* <div ref={list.containerRef}>
|
|
161
|
+
* <ul style={{ height: `${list.getTotalSize()}px` }}>
|
|
162
|
+
* {list.rows.map(row => {
|
|
163
|
+
* const props = list.getListItemProps(row, { className: 'list-item' });
|
|
164
|
+
* return <li {...props}>{row.item?.title}</li>;
|
|
165
|
+
* })}
|
|
166
|
+
* </ul>
|
|
167
|
+
* </div>
|
|
168
|
+
* );
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
export declare const useList: <TItem = unknown>({ count, pagination, header, getItem, loadingIndicator, onRowClick, onChange, estimateItemSize, estimateHeaderSize, overscan, }: UseListOptions<TItem>) => UseListResult<TItem>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for calculating ListItem height based on visible content.
|
|
3
|
+
* These props match the optional content sections of ListItem.
|
|
4
|
+
*/
|
|
5
|
+
export interface ListItemHeightConfig {
|
|
6
|
+
/** Whether the item has a thumbnail (icon or image) */
|
|
7
|
+
hasThumbnail?: boolean;
|
|
8
|
+
/** Whether the item has a description line */
|
|
9
|
+
hasDescription?: boolean;
|
|
10
|
+
/** Whether the item has a meta line */
|
|
11
|
+
hasMeta?: boolean;
|
|
12
|
+
/** Whether the item has details on the right side (doesn't affect height) */
|
|
13
|
+
hasDetails?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Hook that provides a memoized getListItemHeight function.
|
|
17
|
+
*
|
|
18
|
+
* Calculates the estimated height of a ListItem based on its configuration.
|
|
19
|
+
* This function adds up the heights of each visible line plus gaps between them.
|
|
20
|
+
* Height values are placeholders and need to be measured in browser DevTools.
|
|
21
|
+
*
|
|
22
|
+
* @returns {object} An object containing the memoized getListItemHeight function
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* const { getListItemHeight } = useListItemHeight();
|
|
26
|
+
*
|
|
27
|
+
* const estimateItemSize = () => getListItemHeight({
|
|
28
|
+
* hasThumbnail: true,
|
|
29
|
+
* hasDescription: true,
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const useListItemHeight: () => {
|
|
34
|
+
getListItemHeight: (config: ListItemHeightConfig) => number;
|
|
35
|
+
};
|
|
@@ -20,6 +20,8 @@ export * from "./KPI/KPI";
|
|
|
20
20
|
export * from "./KPICard/KPICard";
|
|
21
21
|
export * from "./List/List";
|
|
22
22
|
export * from "./List/List.variants";
|
|
23
|
+
export * from "./List/useList";
|
|
24
|
+
export * from "./ListItem/useListItemHeight";
|
|
23
25
|
export * from "./ListItem/ListItem";
|
|
24
26
|
export * from "./Menu";
|
|
25
27
|
export * from "./Notice";
|
package/src/hooks/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from "./noPagination";
|
|
1
2
|
export * from "./useClickOutside";
|
|
2
3
|
export * from "./useContainerBreakpoints";
|
|
3
4
|
export * from "./useContinuousTimeout";
|
|
@@ -7,10 +8,12 @@ export * from "./useElevatedReducer";
|
|
|
7
8
|
export * from "./useElevatedState";
|
|
8
9
|
export * from "./useGeometry";
|
|
9
10
|
export * from "./useHover";
|
|
11
|
+
export * from "./useInfiniteScroll";
|
|
10
12
|
export * from "./useIsFirstRender";
|
|
11
13
|
export * from "./useIsFullScreen";
|
|
12
14
|
export * from "./useIsTextTruncated";
|
|
13
15
|
export * from "./useModifierKey";
|
|
16
|
+
export * from "./useRelayPagination";
|
|
14
17
|
export * from "./useResize";
|
|
15
18
|
export * from "./useScrollDetection";
|
|
16
19
|
export * from "./useSelfUpdatingRef";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Virtualizer } from "@tanstack/react-virtual";
|
|
2
|
+
import { RefObject } from "react";
|
|
3
|
+
import { RelayPagination } from "./useRelayPagination";
|
|
4
|
+
interface InfiniteScrollProps<TScrollElement extends Element, TItemElement extends Element> {
|
|
5
|
+
pagination: RelayPagination;
|
|
6
|
+
scrollElementRef: RefObject<TScrollElement | null>;
|
|
7
|
+
count: number;
|
|
8
|
+
estimateSize?: (index: number) => number;
|
|
9
|
+
overscan?: number;
|
|
10
|
+
onChange?: (virtualizer: Virtualizer<TScrollElement, TItemElement>) => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Custom hook for implementing infinite scrolling in a table using TanStack Virtual.
|
|
14
|
+
*
|
|
15
|
+
* @param props - The configuration object for the infinite scroll hook.
|
|
16
|
+
* @param props.pagination - The relay pagination object for managing data loading.
|
|
17
|
+
* @param props.scrollElementRef - Reference to the scrollable container element.
|
|
18
|
+
* @param props.count - Total number of items to virtualize.
|
|
19
|
+
* @param props.estimateSize - Optional function to estimate item height.
|
|
20
|
+
* @param props.overscan - Optional number of items to render outside the visible area.
|
|
21
|
+
* @param props.onChange - Optional callback when virtualizer changes.
|
|
22
|
+
* @returns {Virtualizer} The virtualizer instance with all its properties and methods.
|
|
23
|
+
* @description
|
|
24
|
+
* This hook is used to implement infinite scrolling in a table. It uses TanStack Virtual's
|
|
25
|
+
* built-in capabilities for virtualization and automatically loads more data when scrolling
|
|
26
|
+
* approaches the end of the available content.
|
|
27
|
+
* @example
|
|
28
|
+
* const virtualizer = useInfiniteScroll<HTMLDivElement, HTMLDivElement>({
|
|
29
|
+
* pagination: relayPaginationObject,
|
|
30
|
+
* scrollElementRef: tableScrollElementRef,
|
|
31
|
+
* count: 50,
|
|
32
|
+
* estimateSize: () => 35,
|
|
33
|
+
* });
|
|
34
|
+
*/
|
|
35
|
+
export declare const useInfiniteScroll: <TScrollElement extends Element, TItemElement extends Element>({ pagination, scrollElementRef, count, estimateSize, overscan, onChange, }: InfiniteScrollProps<TScrollElement, TItemElement>) => Virtualizer<TScrollElement, TItemElement>;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from "react";
|
|
2
|
+
export interface RelayPaginationProps {
|
|
3
|
+
pageSize?: number;
|
|
4
|
+
onReset?: () => void;
|
|
5
|
+
}
|
|
6
|
+
export interface RelayPaginationQueryVariables {
|
|
7
|
+
first?: number | null;
|
|
8
|
+
last?: number | null;
|
|
9
|
+
before?: string | null;
|
|
10
|
+
after?: string | null;
|
|
11
|
+
}
|
|
12
|
+
export interface RelayPageInfo {
|
|
13
|
+
count?: number | null;
|
|
14
|
+
endCursor?: string | null;
|
|
15
|
+
hasNextPage?: boolean;
|
|
16
|
+
hasPreviousPage?: boolean;
|
|
17
|
+
startCursor?: string | null;
|
|
18
|
+
isCountCapped?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface RelayPagination {
|
|
21
|
+
nextPage: () => void;
|
|
22
|
+
previousPage: () => void;
|
|
23
|
+
pageInfo?: RelayPageInfo;
|
|
24
|
+
isLoading: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface RelayTableSupport extends RelayPagination {
|
|
27
|
+
isLoading: boolean;
|
|
28
|
+
setIsLoading: Dispatch<SetStateAction<boolean>>;
|
|
29
|
+
reset: () => void;
|
|
30
|
+
setPageInfo: Dispatch<SetStateAction<RelayPageInfo | null | undefined>>;
|
|
31
|
+
}
|
|
32
|
+
export interface RelayPaginationSupport {
|
|
33
|
+
variables: RelayPaginationQueryVariables;
|
|
34
|
+
table: RelayTableSupport;
|
|
35
|
+
}
|
|
36
|
+
export declare const defaultPageSize = 50;
|
|
37
|
+
/**
|
|
38
|
+
* Custom hook for handling Relay pagination in tables.
|
|
39
|
+
*
|
|
40
|
+
* @param {RelayPaginationProps} props - The props object containing pagination configuration.
|
|
41
|
+
* @returns {RelayPaginationSupport} An object containing functions and state for managing Relay pagination.
|
|
42
|
+
*/
|
|
43
|
+
export declare const useRelayPagination: ({ onReset, pageSize }?: RelayPaginationProps) => RelayPaginationSupport;
|