@ai-matrx/design-system 0.14.3 → 0.15.2
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/CHANGELOG.md +54 -0
- package/README.md +32 -0
- package/dist/data-table/copy-helpers.cjs +149 -0
- package/dist/data-table/copy-helpers.cjs.map +1 -0
- package/dist/data-table/copy-helpers.d.cts +31 -0
- package/dist/data-table/copy-helpers.d.ts +31 -0
- package/dist/data-table/copy-helpers.js +127 -0
- package/dist/data-table/copy-helpers.js.map +1 -0
- package/dist/data-table/copy-types.cjs +19 -0
- package/dist/data-table/copy-types.cjs.map +1 -0
- package/dist/data-table/copy-types.d.cts +137 -0
- package/dist/data-table/copy-types.d.ts +137 -0
- package/dist/data-table/copy-types.js +1 -0
- package/dist/data-table/copy-types.js.map +1 -0
- package/dist/data-table/data-row-inspector.cjs +1016 -0
- package/dist/data-table/data-row-inspector.cjs.map +1 -0
- package/dist/data-table/data-row-inspector.d.cts +34 -0
- package/dist/data-table/data-row-inspector.d.ts +34 -0
- package/dist/data-table/data-row-inspector.js +988 -0
- package/dist/data-table/data-row-inspector.js.map +1 -0
- package/dist/data-table/data-row-window.cjs +1136 -0
- package/dist/data-table/data-row-window.cjs.map +1 -0
- package/dist/data-table/data-row-window.d.cts +29 -0
- package/dist/data-table/data-row-window.d.ts +29 -0
- package/dist/data-table/data-row-window.js +1110 -0
- package/dist/data-table/data-row-window.js.map +1 -0
- package/dist/data-table/filter-engine.cjs +314 -0
- package/dist/data-table/filter-engine.cjs.map +1 -0
- package/dist/data-table/filter-engine.d.cts +35 -0
- package/dist/data-table/filter-engine.d.ts +35 -0
- package/dist/data-table/filter-engine.js +292 -0
- package/dist/data-table/filter-engine.js.map +1 -0
- package/dist/data-table/host.cjs +40 -0
- package/dist/data-table/host.cjs.map +1 -0
- package/dist/data-table/host.d.cts +73 -0
- package/dist/data-table/host.d.ts +73 -0
- package/dist/data-table/host.js +20 -0
- package/dist/data-table/host.js.map +1 -0
- package/dist/data-table/index.cjs +7198 -0
- package/dist/data-table/index.cjs.map +1 -0
- package/dist/data-table/index.d.cts +27 -0
- package/dist/data-table/index.d.ts +27 -0
- package/dist/data-table/index.js +7202 -0
- package/dist/data-table/index.js.map +1 -0
- package/dist/data-table/infer-filter.cjs +111 -0
- package/dist/data-table/infer-filter.cjs.map +1 -0
- package/dist/data-table/infer-filter.d.cts +17 -0
- package/dist/data-table/infer-filter.d.ts +17 -0
- package/dist/data-table/infer-filter.js +89 -0
- package/dist/data-table/infer-filter.js.map +1 -0
- package/dist/data-table/layered-filters.cjs +249 -0
- package/dist/data-table/layered-filters.cjs.map +1 -0
- package/dist/data-table/layered-filters.d.cts +3 -0
- package/dist/data-table/layered-filters.d.ts +3 -0
- package/dist/data-table/layered-filters.js +229 -0
- package/dist/data-table/layered-filters.js.map +1 -0
- package/dist/data-table/pagination.cjs +595 -0
- package/dist/data-table/pagination.cjs.map +1 -0
- package/dist/data-table/pagination.d.cts +34 -0
- package/dist/data-table/pagination.d.ts +34 -0
- package/dist/data-table/pagination.js +563 -0
- package/dist/data-table/pagination.js.map +1 -0
- package/dist/data-table/query-control.cjs +126 -0
- package/dist/data-table/query-control.cjs.map +1 -0
- package/dist/data-table/query-control.d.cts +32 -0
- package/dist/data-table/query-control.d.ts +32 -0
- package/dist/data-table/query-control.js +104 -0
- package/dist/data-table/query-control.js.map +1 -0
- package/dist/data-table/scroll-pagination.cjs +222 -0
- package/dist/data-table/scroll-pagination.cjs.map +1 -0
- package/dist/data-table/scroll-pagination.d.cts +37 -0
- package/dist/data-table/scroll-pagination.d.ts +37 -0
- package/dist/data-table/scroll-pagination.js +202 -0
- package/dist/data-table/scroll-pagination.js.map +1 -0
- package/dist/data-table/types.cjs +19 -0
- package/dist/data-table/types.cjs.map +1 -0
- package/dist/data-table/types.d.cts +3 -0
- package/dist/data-table/types.d.ts +3 -0
- package/dist/data-table/types.js +1 -0
- package/dist/data-table/types.js.map +1 -0
- package/dist/data-table/url-state.cjs +201 -0
- package/dist/data-table/url-state.cjs.map +1 -0
- package/dist/data-table/url-state.d.cts +33 -0
- package/dist/data-table/url-state.d.ts +33 -0
- package/dist/data-table/url-state.js +184 -0
- package/dist/data-table/url-state.js.map +1 -0
- package/dist/data-table/uuid-cell.cjs +371 -0
- package/dist/data-table/uuid-cell.cjs.map +1 -0
- package/dist/data-table/uuid-cell.d.cts +31 -0
- package/dist/data-table/uuid-cell.d.ts +31 -0
- package/dist/data-table/uuid-cell.js +345 -0
- package/dist/data-table/uuid-cell.js.map +1 -0
- package/dist/data-table/xlsx.cjs +100 -0
- package/dist/data-table/xlsx.cjs.map +1 -0
- package/dist/data-table/xlsx.d.cts +16 -0
- package/dist/data-table/xlsx.d.ts +16 -0
- package/dist/data-table/xlsx.js +70 -0
- package/dist/data-table/xlsx.js.map +1 -0
- package/dist/index.cjs +9 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/styles.css +22 -0
- package/dist/types-ClaxTaXq.d.ts +798 -0
- package/dist/types-XXbVB1sh.d.cts +798 -0
- package/package.json +164 -1
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
"use client";
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
|
|
22
|
+
// src/data-table/useScrollPagination.ts
|
|
23
|
+
var useScrollPagination_exports = {};
|
|
24
|
+
__export(useScrollPagination_exports, {
|
|
25
|
+
useScrollPagination: () => useScrollPagination
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(useScrollPagination_exports);
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
var DEFAULT_THRESHOLD_PX = 96;
|
|
30
|
+
var DEFAULT_INTENT_TIMEOUT_MS = 1200;
|
|
31
|
+
function resolveContainer(container) {
|
|
32
|
+
if (!container) return null;
|
|
33
|
+
return container instanceof HTMLElement ? container : container.current;
|
|
34
|
+
}
|
|
35
|
+
function isVisibleContainer(container) {
|
|
36
|
+
if (!container.isConnected) return false;
|
|
37
|
+
for (let node = container; node; node = node.parentElement) {
|
|
38
|
+
const style = window.getComputedStyle(node);
|
|
39
|
+
if (style.display === "none" || style.visibility === "hidden") return false;
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
function isEditableTarget(target) {
|
|
44
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
45
|
+
return target.isContentEditable || Boolean(target.closest("input, textarea, select, [contenteditable='true']"));
|
|
46
|
+
}
|
|
47
|
+
function isDownwardKeyboardInput(event) {
|
|
48
|
+
if (isEditableTarget(event.target)) return false;
|
|
49
|
+
return ["ArrowDown", "PageDown", "End", " ", "Spacebar"].includes(event.key);
|
|
50
|
+
}
|
|
51
|
+
function isNearBottom(container, thresholdPx) {
|
|
52
|
+
return container.scrollHeight - container.clientHeight - container.scrollTop <= thresholdPx;
|
|
53
|
+
}
|
|
54
|
+
function isNativeScrollbarPointer(event, container) {
|
|
55
|
+
if (event.pointerType !== "mouse" || event.button !== 0 || !event.isPrimary) return false;
|
|
56
|
+
const gutterWidth = container.offsetWidth - container.clientWidth;
|
|
57
|
+
if (gutterWidth <= 0 || container.scrollHeight <= container.clientHeight) return false;
|
|
58
|
+
const rect = container.getBoundingClientRect();
|
|
59
|
+
return event.clientX >= rect.right - gutterWidth && event.clientX <= rect.right;
|
|
60
|
+
}
|
|
61
|
+
function useScrollPagination({
|
|
62
|
+
containers,
|
|
63
|
+
queryKey,
|
|
64
|
+
hasNextPage,
|
|
65
|
+
isFetchingNextPage,
|
|
66
|
+
loading,
|
|
67
|
+
error,
|
|
68
|
+
loadNextPage,
|
|
69
|
+
mode = "scroll",
|
|
70
|
+
thresholdPx = DEFAULT_THRESHOLD_PX,
|
|
71
|
+
intentTimeoutMs = DEFAULT_INTENT_TIMEOUT_MS,
|
|
72
|
+
enabled = true
|
|
73
|
+
}) {
|
|
74
|
+
const [requestError, setRequestError] = (0, import_react.useState)(null);
|
|
75
|
+
const latestRef = (0, import_react.useRef)({
|
|
76
|
+
queryKey,
|
|
77
|
+
hasNextPage,
|
|
78
|
+
isFetchingNextPage,
|
|
79
|
+
loading,
|
|
80
|
+
error,
|
|
81
|
+
loadNextPage,
|
|
82
|
+
mode,
|
|
83
|
+
thresholdPx,
|
|
84
|
+
enabled
|
|
85
|
+
});
|
|
86
|
+
latestRef.current = {
|
|
87
|
+
queryKey,
|
|
88
|
+
hasNextPage,
|
|
89
|
+
isFetchingNextPage,
|
|
90
|
+
loading,
|
|
91
|
+
error,
|
|
92
|
+
loadNextPage,
|
|
93
|
+
mode,
|
|
94
|
+
thresholdPx,
|
|
95
|
+
enabled
|
|
96
|
+
};
|
|
97
|
+
const intentRef = (0, import_react.useRef)(null);
|
|
98
|
+
const inputSequenceRef = (0, import_react.useRef)(0);
|
|
99
|
+
const consumedSequenceRef = (0, import_react.useRef)(0);
|
|
100
|
+
const requestGenerationRef = (0, import_react.useRef)(0);
|
|
101
|
+
const inFlightGenerationRef = (0, import_react.useRef)(null);
|
|
102
|
+
const requestErrorRef = (0, import_react.useRef)(null);
|
|
103
|
+
const mountedRef = (0, import_react.useRef)(false);
|
|
104
|
+
const effectiveError = error ?? requestError;
|
|
105
|
+
(0, import_react.useEffect)(() => {
|
|
106
|
+
mountedRef.current = true;
|
|
107
|
+
return () => {
|
|
108
|
+
mountedRef.current = false;
|
|
109
|
+
};
|
|
110
|
+
}, []);
|
|
111
|
+
const requestNextPage = async () => {
|
|
112
|
+
const current = latestRef.current;
|
|
113
|
+
if (!current.enabled || !current.hasNextPage && effectiveError === null || current.loading || current.isFetchingNextPage || inFlightGenerationRef.current !== null) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const generation = ++requestGenerationRef.current;
|
|
117
|
+
inFlightGenerationRef.current = generation;
|
|
118
|
+
requestErrorRef.current = null;
|
|
119
|
+
setRequestError(null);
|
|
120
|
+
try {
|
|
121
|
+
await current.loadNextPage();
|
|
122
|
+
} catch (raw) {
|
|
123
|
+
const nextError = raw instanceof Error ? raw : new Error(String(raw));
|
|
124
|
+
if (inFlightGenerationRef.current === generation && latestRef.current.queryKey === current.queryKey) {
|
|
125
|
+
requestErrorRef.current = nextError;
|
|
126
|
+
if (mountedRef.current) setRequestError(nextError);
|
|
127
|
+
}
|
|
128
|
+
} finally {
|
|
129
|
+
if (inFlightGenerationRef.current === generation) {
|
|
130
|
+
inFlightGenerationRef.current = null;
|
|
131
|
+
intentRef.current = null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
(0, import_react.useEffect)(() => {
|
|
136
|
+
intentRef.current = null;
|
|
137
|
+
consumedSequenceRef.current = inputSequenceRef.current;
|
|
138
|
+
requestErrorRef.current = null;
|
|
139
|
+
setRequestError(null);
|
|
140
|
+
inFlightGenerationRef.current = null;
|
|
141
|
+
requestGenerationRef.current += 1;
|
|
142
|
+
}, [queryKey]);
|
|
143
|
+
(0, import_react.useEffect)(() => {
|
|
144
|
+
if (mode !== "scroll" || !enabled || typeof window === "undefined") return;
|
|
145
|
+
const attachable = containers.map(resolveContainer).filter((container) => container !== null);
|
|
146
|
+
const setIntent = (container) => {
|
|
147
|
+
const current = latestRef.current;
|
|
148
|
+
if (!isVisibleContainer(container) || current.loading || current.isFetchingNextPage || inFlightGenerationRef.current !== null) return;
|
|
149
|
+
inputSequenceRef.current += 1;
|
|
150
|
+
intentRef.current = {
|
|
151
|
+
queryKey: latestRef.current.queryKey,
|
|
152
|
+
container,
|
|
153
|
+
startTop: container.scrollTop,
|
|
154
|
+
sequence: inputSequenceRef.current,
|
|
155
|
+
expiresAt: Date.now() + intentTimeoutMs
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
const handleScroll = (container) => {
|
|
159
|
+
const intent = intentRef.current;
|
|
160
|
+
const current = latestRef.current;
|
|
161
|
+
if (!intent || intent.queryKey !== current.queryKey || intent.container !== container || Date.now() > intent.expiresAt || container.scrollTop <= intent.startTop || intent.sequence <= consumedSequenceRef.current || !isVisibleContainer(container) || !isNearBottom(container, current.thresholdPx) || !current.hasNextPage || current.loading || current.isFetchingNextPage || current.error !== null || requestErrorRef.current !== null || inFlightGenerationRef.current !== null) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
consumedSequenceRef.current = intent.sequence;
|
|
165
|
+
void requestNextPage();
|
|
166
|
+
};
|
|
167
|
+
const cleanups = attachable.map((container) => {
|
|
168
|
+
const onWheel = (event) => {
|
|
169
|
+
if (event.deltaY > 0 && Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
|
|
170
|
+
setIntent(container);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const onTouchStart = (event) => {
|
|
174
|
+
const touch = event.touches.item(0);
|
|
175
|
+
if (touch) container.dataset.matrxPaginationTouchY = String(touch.clientY);
|
|
176
|
+
};
|
|
177
|
+
const onTouchMove = (event) => {
|
|
178
|
+
const touch = event.touches.item(0);
|
|
179
|
+
const startY = Number(container.dataset.matrxPaginationTouchY);
|
|
180
|
+
if (touch && Number.isFinite(startY) && startY - touch.clientY > 0) {
|
|
181
|
+
setIntent(container);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const onTouchEnd = () => {
|
|
185
|
+
delete container.dataset.matrxPaginationTouchY;
|
|
186
|
+
};
|
|
187
|
+
const onKeyDown = (event) => {
|
|
188
|
+
if (isDownwardKeyboardInput(event)) setIntent(container);
|
|
189
|
+
};
|
|
190
|
+
const onPointerDown = (event) => {
|
|
191
|
+
if (isNativeScrollbarPointer(event, container)) setIntent(container);
|
|
192
|
+
};
|
|
193
|
+
const onScroll = () => handleScroll(container);
|
|
194
|
+
container.addEventListener("wheel", onWheel, { passive: true });
|
|
195
|
+
container.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
196
|
+
container.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
197
|
+
container.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
198
|
+
container.addEventListener("touchcancel", onTouchEnd, { passive: true });
|
|
199
|
+
container.addEventListener("keydown", onKeyDown);
|
|
200
|
+
container.addEventListener("pointerdown", onPointerDown, { passive: true });
|
|
201
|
+
container.addEventListener("scroll", onScroll, { passive: true });
|
|
202
|
+
return () => {
|
|
203
|
+
delete container.dataset.matrxPaginationTouchY;
|
|
204
|
+
container.removeEventListener("wheel", onWheel);
|
|
205
|
+
container.removeEventListener("touchstart", onTouchStart);
|
|
206
|
+
container.removeEventListener("touchmove", onTouchMove);
|
|
207
|
+
container.removeEventListener("touchend", onTouchEnd);
|
|
208
|
+
container.removeEventListener("touchcancel", onTouchEnd);
|
|
209
|
+
container.removeEventListener("keydown", onKeyDown);
|
|
210
|
+
container.removeEventListener("pointerdown", onPointerDown);
|
|
211
|
+
container.removeEventListener("scroll", onScroll);
|
|
212
|
+
};
|
|
213
|
+
});
|
|
214
|
+
return () => cleanups.forEach((cleanup) => cleanup());
|
|
215
|
+
}, [containers, enabled, intentTimeoutMs, mode]);
|
|
216
|
+
return {
|
|
217
|
+
requestNextPage,
|
|
218
|
+
canLoadMore: enabled && !loading && !isFetchingNextPage && (hasNextPage || effectiveError !== null),
|
|
219
|
+
error: effectiveError
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=scroll-pagination.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/data-table/useScrollPagination.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport type { RefObject } from \"react\";\n\nexport type ScrollPaginationContainer =\n | HTMLElement\n | RefObject<HTMLElement | null>\n | null;\n\nexport interface UseScrollPaginationOptions {\n /** Every visible desktop/mobile scroll container that may present this table. */\n containers: readonly ScrollPaginationContainer[];\n /** Immutable identity of every source-affecting query value. */\n queryKey: string;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n loading: boolean;\n /** Automatic scrolling never retries a failed append. */\n error: Error | null;\n loadNextPage: () => Promise<void> | void;\n /** Manual mode exposes the explicit request only; it installs no listeners. */\n mode?: \"scroll\" | \"manual\";\n /** Distance from the bottom at which a qualifying user scroll may append. */\n thresholdPx?: number;\n /** How long an input may authorize the following real scroll movement. */\n intentTimeoutMs?: number;\n enabled?: boolean;\n}\n\nexport interface UseScrollPaginationResult {\n /** For the table's accessible Load more / Retry control. */\n requestNextPage: () => Promise<void>;\n canLoadMore: boolean;\n /** Includes an unexpected loader rejection until the person explicitly retries. */\n error: Error | null;\n}\n\ninterface ScrollIntent {\n queryKey: string;\n container: HTMLElement;\n startTop: number;\n sequence: number;\n expiresAt: number;\n}\n\nconst DEFAULT_THRESHOLD_PX = 96;\nconst DEFAULT_INTENT_TIMEOUT_MS = 1_200;\n\nfunction resolveContainer(container: ScrollPaginationContainer): HTMLElement | null {\n if (!container) return null;\n return container instanceof HTMLElement ? container : container.current;\n}\n\nfunction isVisibleContainer(container: HTMLElement): boolean {\n if (!container.isConnected) return false;\n for (let node: HTMLElement | null = container; node; node = node.parentElement) {\n const style = window.getComputedStyle(node);\n if (style.display === \"none\" || style.visibility === \"hidden\") return false;\n }\n return true;\n}\n\nfunction isEditableTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n return target.isContentEditable || Boolean(target.closest(\"input, textarea, select, [contenteditable='true']\"));\n}\n\nfunction isDownwardKeyboardInput(event: KeyboardEvent): boolean {\n if (isEditableTarget(event.target)) return false;\n return [\"ArrowDown\", \"PageDown\", \"End\", \" \", \"Spacebar\"].includes(event.key);\n}\n\nfunction isNearBottom(container: HTMLElement, thresholdPx: number): boolean {\n return container.scrollHeight - container.clientHeight - container.scrollTop <= thresholdPx;\n}\n\nfunction isNativeScrollbarPointer(event: PointerEvent, container: HTMLElement): boolean {\n // Overlay scrollbars expose no measurable gutter. Do not guess: Load more is\n // the accessible, reliable fallback there. A content click must never grant\n // permission for a later programmatic scroll to append rows.\n if (event.pointerType !== \"mouse\" || event.button !== 0 || !event.isPrimary) return false;\n const gutterWidth = container.offsetWidth - container.clientWidth;\n if (gutterWidth <= 0 || container.scrollHeight <= container.clientHeight) return false;\n const rect = container.getBoundingClientRect();\n return event.clientX >= rect.right - gutterWidth && event.clientX <= rect.right;\n}\n\n/**\n * Gates automatic append behind a fresh, real downward user scroll. The hook\n * owns neither fetching nor row state: callers feed it the data hook receipt\n * and render its explicit request as the accessible fallback control.\n */\nexport function useScrollPagination({\n containers,\n queryKey,\n hasNextPage,\n isFetchingNextPage,\n loading,\n error,\n loadNextPage,\n mode = \"scroll\",\n thresholdPx = DEFAULT_THRESHOLD_PX,\n intentTimeoutMs = DEFAULT_INTENT_TIMEOUT_MS,\n enabled = true,\n}: UseScrollPaginationOptions): UseScrollPaginationResult {\n const [requestError, setRequestError] = useState<Error | null>(null);\n const latestRef = useRef({\n queryKey,\n hasNextPage,\n isFetchingNextPage,\n loading,\n error,\n loadNextPage,\n mode,\n thresholdPx,\n enabled,\n });\n latestRef.current = {\n queryKey,\n hasNextPage,\n isFetchingNextPage,\n loading,\n error,\n loadNextPage,\n mode,\n thresholdPx,\n enabled,\n };\n\n const intentRef = useRef<ScrollIntent | null>(null);\n const inputSequenceRef = useRef(0);\n const consumedSequenceRef = useRef(0);\n const requestGenerationRef = useRef(0);\n const inFlightGenerationRef = useRef<number | null>(null);\n const requestErrorRef = useRef<Error | null>(null);\n const mountedRef = useRef(false);\n const effectiveError = error ?? requestError;\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const requestNextPage = async () => {\n const current = latestRef.current;\n if (\n !current.enabled ||\n (!current.hasNextPage && effectiveError === null) ||\n current.loading ||\n current.isFetchingNextPage ||\n inFlightGenerationRef.current !== null\n ) {\n return;\n }\n const generation = ++requestGenerationRef.current;\n inFlightGenerationRef.current = generation;\n requestErrorRef.current = null;\n setRequestError(null);\n try {\n await current.loadNextPage();\n } catch (raw) {\n const nextError = raw instanceof Error ? raw : new Error(String(raw));\n if (inFlightGenerationRef.current === generation && latestRef.current.queryKey === current.queryKey) {\n requestErrorRef.current = nextError;\n if (mountedRef.current) setRequestError(nextError);\n }\n } finally {\n if (inFlightGenerationRef.current === generation) {\n inFlightGenerationRef.current = null;\n intentRef.current = null;\n }\n }\n };\n\n useEffect(() => {\n intentRef.current = null;\n consumedSequenceRef.current = inputSequenceRef.current;\n requestErrorRef.current = null;\n setRequestError(null);\n // A query change makes every existing completion stale. Its finally block\n // cannot clear a new request because generations are monotonically unique.\n inFlightGenerationRef.current = null;\n requestGenerationRef.current += 1;\n }, [queryKey]);\n\n useEffect(() => {\n if (mode !== \"scroll\" || !enabled || typeof window === \"undefined\") return;\n\n const attachable = containers\n .map(resolveContainer)\n .filter((container): container is HTMLElement => container !== null);\n\n const setIntent = (container: HTMLElement) => {\n const current = latestRef.current;\n if (!isVisibleContainer(container) || current.loading || current.isFetchingNextPage || inFlightGenerationRef.current !== null) return;\n inputSequenceRef.current += 1;\n intentRef.current = {\n queryKey: latestRef.current.queryKey,\n container,\n startTop: container.scrollTop,\n sequence: inputSequenceRef.current,\n expiresAt: Date.now() + intentTimeoutMs,\n };\n };\n\n const handleScroll = (container: HTMLElement) => {\n const intent = intentRef.current;\n const current = latestRef.current;\n if (\n !intent ||\n intent.queryKey !== current.queryKey ||\n intent.container !== container ||\n Date.now() > intent.expiresAt ||\n container.scrollTop <= intent.startTop ||\n intent.sequence <= consumedSequenceRef.current ||\n !isVisibleContainer(container) ||\n !isNearBottom(container, current.thresholdPx) ||\n !current.hasNextPage ||\n current.loading ||\n current.isFetchingNextPage ||\n current.error !== null ||\n requestErrorRef.current !== null ||\n inFlightGenerationRef.current !== null\n ) {\n return;\n }\n consumedSequenceRef.current = intent.sequence;\n void requestNextPage();\n };\n\n const cleanups = attachable.map((container) => {\n const onWheel = (event: WheelEvent) => {\n if (event.deltaY > 0 && Math.abs(event.deltaY) > Math.abs(event.deltaX)) {\n setIntent(container);\n }\n };\n const onTouchStart = (event: TouchEvent) => {\n const touch = event.touches.item(0);\n if (touch) container.dataset.matrxPaginationTouchY = String(touch.clientY);\n };\n const onTouchMove = (event: TouchEvent) => {\n const touch = event.touches.item(0);\n const startY = Number(container.dataset.matrxPaginationTouchY);\n if (touch && Number.isFinite(startY) && startY - touch.clientY > 0) {\n setIntent(container);\n }\n };\n const onTouchEnd = () => {\n delete container.dataset.matrxPaginationTouchY;\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (isDownwardKeyboardInput(event)) setIntent(container);\n };\n const onPointerDown = (event: PointerEvent) => {\n if (isNativeScrollbarPointer(event, container)) setIntent(container);\n };\n const onScroll = () => handleScroll(container);\n\n container.addEventListener(\"wheel\", onWheel, { passive: true });\n container.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n container.addEventListener(\"touchmove\", onTouchMove, { passive: true });\n container.addEventListener(\"touchend\", onTouchEnd, { passive: true });\n container.addEventListener(\"touchcancel\", onTouchEnd, { passive: true });\n container.addEventListener(\"keydown\", onKeyDown);\n container.addEventListener(\"pointerdown\", onPointerDown, { passive: true });\n container.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => {\n delete container.dataset.matrxPaginationTouchY;\n container.removeEventListener(\"wheel\", onWheel);\n container.removeEventListener(\"touchstart\", onTouchStart);\n container.removeEventListener(\"touchmove\", onTouchMove);\n container.removeEventListener(\"touchend\", onTouchEnd);\n container.removeEventListener(\"touchcancel\", onTouchEnd);\n container.removeEventListener(\"keydown\", onKeyDown);\n container.removeEventListener(\"pointerdown\", onPointerDown);\n container.removeEventListener(\"scroll\", onScroll);\n };\n });\n return () => cleanups.forEach((cleanup) => cleanup());\n }, [containers, enabled, intentTimeoutMs, mode]);\n\n return {\n requestNextPage,\n canLoadMore: enabled && !loading && !isFetchingNextPage && (hasNextPage || effectiveError !== null),\n error: effectiveError,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
type ScrollPaginationContainer = HTMLElement | RefObject<HTMLElement | null> | null;
|
|
4
|
+
interface UseScrollPaginationOptions {
|
|
5
|
+
/** Every visible desktop/mobile scroll container that may present this table. */
|
|
6
|
+
containers: readonly ScrollPaginationContainer[];
|
|
7
|
+
/** Immutable identity of every source-affecting query value. */
|
|
8
|
+
queryKey: string;
|
|
9
|
+
hasNextPage: boolean;
|
|
10
|
+
isFetchingNextPage: boolean;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
/** Automatic scrolling never retries a failed append. */
|
|
13
|
+
error: Error | null;
|
|
14
|
+
loadNextPage: () => Promise<void> | void;
|
|
15
|
+
/** Manual mode exposes the explicit request only; it installs no listeners. */
|
|
16
|
+
mode?: "scroll" | "manual";
|
|
17
|
+
/** Distance from the bottom at which a qualifying user scroll may append. */
|
|
18
|
+
thresholdPx?: number;
|
|
19
|
+
/** How long an input may authorize the following real scroll movement. */
|
|
20
|
+
intentTimeoutMs?: number;
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
}
|
|
23
|
+
interface UseScrollPaginationResult {
|
|
24
|
+
/** For the table's accessible Load more / Retry control. */
|
|
25
|
+
requestNextPage: () => Promise<void>;
|
|
26
|
+
canLoadMore: boolean;
|
|
27
|
+
/** Includes an unexpected loader rejection until the person explicitly retries. */
|
|
28
|
+
error: Error | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Gates automatic append behind a fresh, real downward user scroll. The hook
|
|
32
|
+
* owns neither fetching nor row state: callers feed it the data hook receipt
|
|
33
|
+
* and render its explicit request as the accessible fallback control.
|
|
34
|
+
*/
|
|
35
|
+
declare function useScrollPagination({ containers, queryKey, hasNextPage, isFetchingNextPage, loading, error, loadNextPage, mode, thresholdPx, intentTimeoutMs, enabled, }: UseScrollPaginationOptions): UseScrollPaginationResult;
|
|
36
|
+
|
|
37
|
+
export { type ScrollPaginationContainer, type UseScrollPaginationOptions, type UseScrollPaginationResult, useScrollPagination };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
type ScrollPaginationContainer = HTMLElement | RefObject<HTMLElement | null> | null;
|
|
4
|
+
interface UseScrollPaginationOptions {
|
|
5
|
+
/** Every visible desktop/mobile scroll container that may present this table. */
|
|
6
|
+
containers: readonly ScrollPaginationContainer[];
|
|
7
|
+
/** Immutable identity of every source-affecting query value. */
|
|
8
|
+
queryKey: string;
|
|
9
|
+
hasNextPage: boolean;
|
|
10
|
+
isFetchingNextPage: boolean;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
/** Automatic scrolling never retries a failed append. */
|
|
13
|
+
error: Error | null;
|
|
14
|
+
loadNextPage: () => Promise<void> | void;
|
|
15
|
+
/** Manual mode exposes the explicit request only; it installs no listeners. */
|
|
16
|
+
mode?: "scroll" | "manual";
|
|
17
|
+
/** Distance from the bottom at which a qualifying user scroll may append. */
|
|
18
|
+
thresholdPx?: number;
|
|
19
|
+
/** How long an input may authorize the following real scroll movement. */
|
|
20
|
+
intentTimeoutMs?: number;
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
}
|
|
23
|
+
interface UseScrollPaginationResult {
|
|
24
|
+
/** For the table's accessible Load more / Retry control. */
|
|
25
|
+
requestNextPage: () => Promise<void>;
|
|
26
|
+
canLoadMore: boolean;
|
|
27
|
+
/** Includes an unexpected loader rejection until the person explicitly retries. */
|
|
28
|
+
error: Error | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Gates automatic append behind a fresh, real downward user scroll. The hook
|
|
32
|
+
* owns neither fetching nor row state: callers feed it the data hook receipt
|
|
33
|
+
* and render its explicit request as the accessible fallback control.
|
|
34
|
+
*/
|
|
35
|
+
declare function useScrollPagination({ containers, queryKey, hasNextPage, isFetchingNextPage, loading, error, loadNextPage, mode, thresholdPx, intentTimeoutMs, enabled, }: UseScrollPaginationOptions): UseScrollPaginationResult;
|
|
36
|
+
|
|
37
|
+
export { type ScrollPaginationContainer, type UseScrollPaginationOptions, type UseScrollPaginationResult, useScrollPagination };
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
// src/data-table/useScrollPagination.ts
|
|
5
|
+
import { useEffect, useRef, useState } from "react";
|
|
6
|
+
var DEFAULT_THRESHOLD_PX = 96;
|
|
7
|
+
var DEFAULT_INTENT_TIMEOUT_MS = 1200;
|
|
8
|
+
function resolveContainer(container) {
|
|
9
|
+
if (!container) return null;
|
|
10
|
+
return container instanceof HTMLElement ? container : container.current;
|
|
11
|
+
}
|
|
12
|
+
function isVisibleContainer(container) {
|
|
13
|
+
if (!container.isConnected) return false;
|
|
14
|
+
for (let node = container; node; node = node.parentElement) {
|
|
15
|
+
const style = window.getComputedStyle(node);
|
|
16
|
+
if (style.display === "none" || style.visibility === "hidden") return false;
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
function isEditableTarget(target) {
|
|
21
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
22
|
+
return target.isContentEditable || Boolean(target.closest("input, textarea, select, [contenteditable='true']"));
|
|
23
|
+
}
|
|
24
|
+
function isDownwardKeyboardInput(event) {
|
|
25
|
+
if (isEditableTarget(event.target)) return false;
|
|
26
|
+
return ["ArrowDown", "PageDown", "End", " ", "Spacebar"].includes(event.key);
|
|
27
|
+
}
|
|
28
|
+
function isNearBottom(container, thresholdPx) {
|
|
29
|
+
return container.scrollHeight - container.clientHeight - container.scrollTop <= thresholdPx;
|
|
30
|
+
}
|
|
31
|
+
function isNativeScrollbarPointer(event, container) {
|
|
32
|
+
if (event.pointerType !== "mouse" || event.button !== 0 || !event.isPrimary) return false;
|
|
33
|
+
const gutterWidth = container.offsetWidth - container.clientWidth;
|
|
34
|
+
if (gutterWidth <= 0 || container.scrollHeight <= container.clientHeight) return false;
|
|
35
|
+
const rect = container.getBoundingClientRect();
|
|
36
|
+
return event.clientX >= rect.right - gutterWidth && event.clientX <= rect.right;
|
|
37
|
+
}
|
|
38
|
+
function useScrollPagination({
|
|
39
|
+
containers,
|
|
40
|
+
queryKey,
|
|
41
|
+
hasNextPage,
|
|
42
|
+
isFetchingNextPage,
|
|
43
|
+
loading,
|
|
44
|
+
error,
|
|
45
|
+
loadNextPage,
|
|
46
|
+
mode = "scroll",
|
|
47
|
+
thresholdPx = DEFAULT_THRESHOLD_PX,
|
|
48
|
+
intentTimeoutMs = DEFAULT_INTENT_TIMEOUT_MS,
|
|
49
|
+
enabled = true
|
|
50
|
+
}) {
|
|
51
|
+
const [requestError, setRequestError] = useState(null);
|
|
52
|
+
const latestRef = useRef({
|
|
53
|
+
queryKey,
|
|
54
|
+
hasNextPage,
|
|
55
|
+
isFetchingNextPage,
|
|
56
|
+
loading,
|
|
57
|
+
error,
|
|
58
|
+
loadNextPage,
|
|
59
|
+
mode,
|
|
60
|
+
thresholdPx,
|
|
61
|
+
enabled
|
|
62
|
+
});
|
|
63
|
+
latestRef.current = {
|
|
64
|
+
queryKey,
|
|
65
|
+
hasNextPage,
|
|
66
|
+
isFetchingNextPage,
|
|
67
|
+
loading,
|
|
68
|
+
error,
|
|
69
|
+
loadNextPage,
|
|
70
|
+
mode,
|
|
71
|
+
thresholdPx,
|
|
72
|
+
enabled
|
|
73
|
+
};
|
|
74
|
+
const intentRef = useRef(null);
|
|
75
|
+
const inputSequenceRef = useRef(0);
|
|
76
|
+
const consumedSequenceRef = useRef(0);
|
|
77
|
+
const requestGenerationRef = useRef(0);
|
|
78
|
+
const inFlightGenerationRef = useRef(null);
|
|
79
|
+
const requestErrorRef = useRef(null);
|
|
80
|
+
const mountedRef = useRef(false);
|
|
81
|
+
const effectiveError = error ?? requestError;
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
mountedRef.current = true;
|
|
84
|
+
return () => {
|
|
85
|
+
mountedRef.current = false;
|
|
86
|
+
};
|
|
87
|
+
}, []);
|
|
88
|
+
const requestNextPage = async () => {
|
|
89
|
+
const current = latestRef.current;
|
|
90
|
+
if (!current.enabled || !current.hasNextPage && effectiveError === null || current.loading || current.isFetchingNextPage || inFlightGenerationRef.current !== null) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const generation = ++requestGenerationRef.current;
|
|
94
|
+
inFlightGenerationRef.current = generation;
|
|
95
|
+
requestErrorRef.current = null;
|
|
96
|
+
setRequestError(null);
|
|
97
|
+
try {
|
|
98
|
+
await current.loadNextPage();
|
|
99
|
+
} catch (raw) {
|
|
100
|
+
const nextError = raw instanceof Error ? raw : new Error(String(raw));
|
|
101
|
+
if (inFlightGenerationRef.current === generation && latestRef.current.queryKey === current.queryKey) {
|
|
102
|
+
requestErrorRef.current = nextError;
|
|
103
|
+
if (mountedRef.current) setRequestError(nextError);
|
|
104
|
+
}
|
|
105
|
+
} finally {
|
|
106
|
+
if (inFlightGenerationRef.current === generation) {
|
|
107
|
+
inFlightGenerationRef.current = null;
|
|
108
|
+
intentRef.current = null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
intentRef.current = null;
|
|
114
|
+
consumedSequenceRef.current = inputSequenceRef.current;
|
|
115
|
+
requestErrorRef.current = null;
|
|
116
|
+
setRequestError(null);
|
|
117
|
+
inFlightGenerationRef.current = null;
|
|
118
|
+
requestGenerationRef.current += 1;
|
|
119
|
+
}, [queryKey]);
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
if (mode !== "scroll" || !enabled || typeof window === "undefined") return;
|
|
122
|
+
const attachable = containers.map(resolveContainer).filter((container) => container !== null);
|
|
123
|
+
const setIntent = (container) => {
|
|
124
|
+
const current = latestRef.current;
|
|
125
|
+
if (!isVisibleContainer(container) || current.loading || current.isFetchingNextPage || inFlightGenerationRef.current !== null) return;
|
|
126
|
+
inputSequenceRef.current += 1;
|
|
127
|
+
intentRef.current = {
|
|
128
|
+
queryKey: latestRef.current.queryKey,
|
|
129
|
+
container,
|
|
130
|
+
startTop: container.scrollTop,
|
|
131
|
+
sequence: inputSequenceRef.current,
|
|
132
|
+
expiresAt: Date.now() + intentTimeoutMs
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
const handleScroll = (container) => {
|
|
136
|
+
const intent = intentRef.current;
|
|
137
|
+
const current = latestRef.current;
|
|
138
|
+
if (!intent || intent.queryKey !== current.queryKey || intent.container !== container || Date.now() > intent.expiresAt || container.scrollTop <= intent.startTop || intent.sequence <= consumedSequenceRef.current || !isVisibleContainer(container) || !isNearBottom(container, current.thresholdPx) || !current.hasNextPage || current.loading || current.isFetchingNextPage || current.error !== null || requestErrorRef.current !== null || inFlightGenerationRef.current !== null) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
consumedSequenceRef.current = intent.sequence;
|
|
142
|
+
void requestNextPage();
|
|
143
|
+
};
|
|
144
|
+
const cleanups = attachable.map((container) => {
|
|
145
|
+
const onWheel = (event) => {
|
|
146
|
+
if (event.deltaY > 0 && Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
|
|
147
|
+
setIntent(container);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const onTouchStart = (event) => {
|
|
151
|
+
const touch = event.touches.item(0);
|
|
152
|
+
if (touch) container.dataset.matrxPaginationTouchY = String(touch.clientY);
|
|
153
|
+
};
|
|
154
|
+
const onTouchMove = (event) => {
|
|
155
|
+
const touch = event.touches.item(0);
|
|
156
|
+
const startY = Number(container.dataset.matrxPaginationTouchY);
|
|
157
|
+
if (touch && Number.isFinite(startY) && startY - touch.clientY > 0) {
|
|
158
|
+
setIntent(container);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const onTouchEnd = () => {
|
|
162
|
+
delete container.dataset.matrxPaginationTouchY;
|
|
163
|
+
};
|
|
164
|
+
const onKeyDown = (event) => {
|
|
165
|
+
if (isDownwardKeyboardInput(event)) setIntent(container);
|
|
166
|
+
};
|
|
167
|
+
const onPointerDown = (event) => {
|
|
168
|
+
if (isNativeScrollbarPointer(event, container)) setIntent(container);
|
|
169
|
+
};
|
|
170
|
+
const onScroll = () => handleScroll(container);
|
|
171
|
+
container.addEventListener("wheel", onWheel, { passive: true });
|
|
172
|
+
container.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
173
|
+
container.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
174
|
+
container.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
175
|
+
container.addEventListener("touchcancel", onTouchEnd, { passive: true });
|
|
176
|
+
container.addEventListener("keydown", onKeyDown);
|
|
177
|
+
container.addEventListener("pointerdown", onPointerDown, { passive: true });
|
|
178
|
+
container.addEventListener("scroll", onScroll, { passive: true });
|
|
179
|
+
return () => {
|
|
180
|
+
delete container.dataset.matrxPaginationTouchY;
|
|
181
|
+
container.removeEventListener("wheel", onWheel);
|
|
182
|
+
container.removeEventListener("touchstart", onTouchStart);
|
|
183
|
+
container.removeEventListener("touchmove", onTouchMove);
|
|
184
|
+
container.removeEventListener("touchend", onTouchEnd);
|
|
185
|
+
container.removeEventListener("touchcancel", onTouchEnd);
|
|
186
|
+
container.removeEventListener("keydown", onKeyDown);
|
|
187
|
+
container.removeEventListener("pointerdown", onPointerDown);
|
|
188
|
+
container.removeEventListener("scroll", onScroll);
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
return () => cleanups.forEach((cleanup) => cleanup());
|
|
192
|
+
}, [containers, enabled, intentTimeoutMs, mode]);
|
|
193
|
+
return {
|
|
194
|
+
requestNextPage,
|
|
195
|
+
canLoadMore: enabled && !loading && !isFetchingNextPage && (hasNextPage || effectiveError !== null),
|
|
196
|
+
error: effectiveError
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
export {
|
|
200
|
+
useScrollPagination
|
|
201
|
+
};
|
|
202
|
+
//# sourceMappingURL=scroll-pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/data-table/useScrollPagination.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport type { RefObject } from \"react\";\n\nexport type ScrollPaginationContainer =\n | HTMLElement\n | RefObject<HTMLElement | null>\n | null;\n\nexport interface UseScrollPaginationOptions {\n /** Every visible desktop/mobile scroll container that may present this table. */\n containers: readonly ScrollPaginationContainer[];\n /** Immutable identity of every source-affecting query value. */\n queryKey: string;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n loading: boolean;\n /** Automatic scrolling never retries a failed append. */\n error: Error | null;\n loadNextPage: () => Promise<void> | void;\n /** Manual mode exposes the explicit request only; it installs no listeners. */\n mode?: \"scroll\" | \"manual\";\n /** Distance from the bottom at which a qualifying user scroll may append. */\n thresholdPx?: number;\n /** How long an input may authorize the following real scroll movement. */\n intentTimeoutMs?: number;\n enabled?: boolean;\n}\n\nexport interface UseScrollPaginationResult {\n /** For the table's accessible Load more / Retry control. */\n requestNextPage: () => Promise<void>;\n canLoadMore: boolean;\n /** Includes an unexpected loader rejection until the person explicitly retries. */\n error: Error | null;\n}\n\ninterface ScrollIntent {\n queryKey: string;\n container: HTMLElement;\n startTop: number;\n sequence: number;\n expiresAt: number;\n}\n\nconst DEFAULT_THRESHOLD_PX = 96;\nconst DEFAULT_INTENT_TIMEOUT_MS = 1_200;\n\nfunction resolveContainer(container: ScrollPaginationContainer): HTMLElement | null {\n if (!container) return null;\n return container instanceof HTMLElement ? container : container.current;\n}\n\nfunction isVisibleContainer(container: HTMLElement): boolean {\n if (!container.isConnected) return false;\n for (let node: HTMLElement | null = container; node; node = node.parentElement) {\n const style = window.getComputedStyle(node);\n if (style.display === \"none\" || style.visibility === \"hidden\") return false;\n }\n return true;\n}\n\nfunction isEditableTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n return target.isContentEditable || Boolean(target.closest(\"input, textarea, select, [contenteditable='true']\"));\n}\n\nfunction isDownwardKeyboardInput(event: KeyboardEvent): boolean {\n if (isEditableTarget(event.target)) return false;\n return [\"ArrowDown\", \"PageDown\", \"End\", \" \", \"Spacebar\"].includes(event.key);\n}\n\nfunction isNearBottom(container: HTMLElement, thresholdPx: number): boolean {\n return container.scrollHeight - container.clientHeight - container.scrollTop <= thresholdPx;\n}\n\nfunction isNativeScrollbarPointer(event: PointerEvent, container: HTMLElement): boolean {\n // Overlay scrollbars expose no measurable gutter. Do not guess: Load more is\n // the accessible, reliable fallback there. A content click must never grant\n // permission for a later programmatic scroll to append rows.\n if (event.pointerType !== \"mouse\" || event.button !== 0 || !event.isPrimary) return false;\n const gutterWidth = container.offsetWidth - container.clientWidth;\n if (gutterWidth <= 0 || container.scrollHeight <= container.clientHeight) return false;\n const rect = container.getBoundingClientRect();\n return event.clientX >= rect.right - gutterWidth && event.clientX <= rect.right;\n}\n\n/**\n * Gates automatic append behind a fresh, real downward user scroll. The hook\n * owns neither fetching nor row state: callers feed it the data hook receipt\n * and render its explicit request as the accessible fallback control.\n */\nexport function useScrollPagination({\n containers,\n queryKey,\n hasNextPage,\n isFetchingNextPage,\n loading,\n error,\n loadNextPage,\n mode = \"scroll\",\n thresholdPx = DEFAULT_THRESHOLD_PX,\n intentTimeoutMs = DEFAULT_INTENT_TIMEOUT_MS,\n enabled = true,\n}: UseScrollPaginationOptions): UseScrollPaginationResult {\n const [requestError, setRequestError] = useState<Error | null>(null);\n const latestRef = useRef({\n queryKey,\n hasNextPage,\n isFetchingNextPage,\n loading,\n error,\n loadNextPage,\n mode,\n thresholdPx,\n enabled,\n });\n latestRef.current = {\n queryKey,\n hasNextPage,\n isFetchingNextPage,\n loading,\n error,\n loadNextPage,\n mode,\n thresholdPx,\n enabled,\n };\n\n const intentRef = useRef<ScrollIntent | null>(null);\n const inputSequenceRef = useRef(0);\n const consumedSequenceRef = useRef(0);\n const requestGenerationRef = useRef(0);\n const inFlightGenerationRef = useRef<number | null>(null);\n const requestErrorRef = useRef<Error | null>(null);\n const mountedRef = useRef(false);\n const effectiveError = error ?? requestError;\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const requestNextPage = async () => {\n const current = latestRef.current;\n if (\n !current.enabled ||\n (!current.hasNextPage && effectiveError === null) ||\n current.loading ||\n current.isFetchingNextPage ||\n inFlightGenerationRef.current !== null\n ) {\n return;\n }\n const generation = ++requestGenerationRef.current;\n inFlightGenerationRef.current = generation;\n requestErrorRef.current = null;\n setRequestError(null);\n try {\n await current.loadNextPage();\n } catch (raw) {\n const nextError = raw instanceof Error ? raw : new Error(String(raw));\n if (inFlightGenerationRef.current === generation && latestRef.current.queryKey === current.queryKey) {\n requestErrorRef.current = nextError;\n if (mountedRef.current) setRequestError(nextError);\n }\n } finally {\n if (inFlightGenerationRef.current === generation) {\n inFlightGenerationRef.current = null;\n intentRef.current = null;\n }\n }\n };\n\n useEffect(() => {\n intentRef.current = null;\n consumedSequenceRef.current = inputSequenceRef.current;\n requestErrorRef.current = null;\n setRequestError(null);\n // A query change makes every existing completion stale. Its finally block\n // cannot clear a new request because generations are monotonically unique.\n inFlightGenerationRef.current = null;\n requestGenerationRef.current += 1;\n }, [queryKey]);\n\n useEffect(() => {\n if (mode !== \"scroll\" || !enabled || typeof window === \"undefined\") return;\n\n const attachable = containers\n .map(resolveContainer)\n .filter((container): container is HTMLElement => container !== null);\n\n const setIntent = (container: HTMLElement) => {\n const current = latestRef.current;\n if (!isVisibleContainer(container) || current.loading || current.isFetchingNextPage || inFlightGenerationRef.current !== null) return;\n inputSequenceRef.current += 1;\n intentRef.current = {\n queryKey: latestRef.current.queryKey,\n container,\n startTop: container.scrollTop,\n sequence: inputSequenceRef.current,\n expiresAt: Date.now() + intentTimeoutMs,\n };\n };\n\n const handleScroll = (container: HTMLElement) => {\n const intent = intentRef.current;\n const current = latestRef.current;\n if (\n !intent ||\n intent.queryKey !== current.queryKey ||\n intent.container !== container ||\n Date.now() > intent.expiresAt ||\n container.scrollTop <= intent.startTop ||\n intent.sequence <= consumedSequenceRef.current ||\n !isVisibleContainer(container) ||\n !isNearBottom(container, current.thresholdPx) ||\n !current.hasNextPage ||\n current.loading ||\n current.isFetchingNextPage ||\n current.error !== null ||\n requestErrorRef.current !== null ||\n inFlightGenerationRef.current !== null\n ) {\n return;\n }\n consumedSequenceRef.current = intent.sequence;\n void requestNextPage();\n };\n\n const cleanups = attachable.map((container) => {\n const onWheel = (event: WheelEvent) => {\n if (event.deltaY > 0 && Math.abs(event.deltaY) > Math.abs(event.deltaX)) {\n setIntent(container);\n }\n };\n const onTouchStart = (event: TouchEvent) => {\n const touch = event.touches.item(0);\n if (touch) container.dataset.matrxPaginationTouchY = String(touch.clientY);\n };\n const onTouchMove = (event: TouchEvent) => {\n const touch = event.touches.item(0);\n const startY = Number(container.dataset.matrxPaginationTouchY);\n if (touch && Number.isFinite(startY) && startY - touch.clientY > 0) {\n setIntent(container);\n }\n };\n const onTouchEnd = () => {\n delete container.dataset.matrxPaginationTouchY;\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (isDownwardKeyboardInput(event)) setIntent(container);\n };\n const onPointerDown = (event: PointerEvent) => {\n if (isNativeScrollbarPointer(event, container)) setIntent(container);\n };\n const onScroll = () => handleScroll(container);\n\n container.addEventListener(\"wheel\", onWheel, { passive: true });\n container.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n container.addEventListener(\"touchmove\", onTouchMove, { passive: true });\n container.addEventListener(\"touchend\", onTouchEnd, { passive: true });\n container.addEventListener(\"touchcancel\", onTouchEnd, { passive: true });\n container.addEventListener(\"keydown\", onKeyDown);\n container.addEventListener(\"pointerdown\", onPointerDown, { passive: true });\n container.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => {\n delete container.dataset.matrxPaginationTouchY;\n container.removeEventListener(\"wheel\", onWheel);\n container.removeEventListener(\"touchstart\", onTouchStart);\n container.removeEventListener(\"touchmove\", onTouchMove);\n container.removeEventListener(\"touchend\", onTouchEnd);\n container.removeEventListener(\"touchcancel\", onTouchEnd);\n container.removeEventListener(\"keydown\", onKeyDown);\n container.removeEventListener(\"pointerdown\", onPointerDown);\n container.removeEventListener(\"scroll\", onScroll);\n };\n });\n return () => cleanups.forEach((cleanup) => cleanup());\n }, [containers, enabled, intentTimeoutMs, mode]);\n\n return {\n requestNextPage,\n canLoadMore: enabled && !loading && !isFetchingNextPage && (hasNextPage || effectiveError !== null),\n error: effectiveError,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/data-table/types.ts
|
|
17
|
+
var types_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(types_exports);
|
|
19
|
+
//# sourceMappingURL=types.cjs.map
|