lkd-web-kit 0.7.31 → 0.8.1

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 (135) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  2. package/dist/components/EmptyState/index.cjs +38 -52
  3. package/dist/components/EmptyState/index.js +37 -48
  4. package/dist/components/Icon.cjs +46 -50
  5. package/dist/components/Icon.js +44 -46
  6. package/dist/components/InfinityLoadMoreButton/index.cjs +30 -42
  7. package/dist/components/InfinityLoadMoreButton/index.js +28 -38
  8. package/dist/components/InfinitySelect/index.cjs +126 -168
  9. package/dist/components/InfinitySelect/index.js +125 -164
  10. package/dist/components/MyCheckboxGroup/index.cjs +14 -22
  11. package/dist/components/MyCheckboxGroup/index.js +13 -18
  12. package/dist/components/MyDateInput/index.cjs +12 -18
  13. package/dist/components/MyDateInput/index.js +11 -14
  14. package/dist/components/MyDatePickerInput/CalendarIcon.cjs +45 -64
  15. package/dist/components/MyDatePickerInput/CalendarIcon.js +43 -61
  16. package/dist/components/MyDatePickerInput/index.cjs +12 -18
  17. package/dist/components/MyDatePickerInput/index.js +11 -14
  18. package/dist/components/MyDateTimePicker/index.cjs +12 -18
  19. package/dist/components/MyDateTimePicker/index.js +11 -14
  20. package/dist/components/MyMonthPickerInput/index.cjs +12 -18
  21. package/dist/components/MyMonthPickerInput/index.js +11 -14
  22. package/dist/components/MyMultiSelect/index.cjs +9 -9
  23. package/dist/components/MyMultiSelect/index.js +8 -5
  24. package/dist/components/MyNotifications/index.cjs +11 -16
  25. package/dist/components/MyNotifications/index.js +10 -12
  26. package/dist/components/MyNumberInput/index.cjs +9 -15
  27. package/dist/components/MyNumberInput/index.js +8 -11
  28. package/dist/components/MyRadioGroup/index.cjs +14 -22
  29. package/dist/components/MyRadioGroup/index.js +13 -18
  30. package/dist/components/MySelect/index.cjs +9 -15
  31. package/dist/components/MySelect/index.js +8 -11
  32. package/dist/components/MyTextInput/index.cjs +9 -15
  33. package/dist/components/MyTextInput/index.js +8 -11
  34. package/dist/components/MyTextarea/index.cjs +9 -15
  35. package/dist/components/MyTextarea/index.js +8 -11
  36. package/dist/components/MyTimeInput/index.cjs +9 -15
  37. package/dist/components/MyTimeInput/index.js +8 -11
  38. package/dist/components/NavItems.cjs +28 -38
  39. package/dist/components/NavItems.js +26 -34
  40. package/dist/consts/http-status.cjs +66 -69
  41. package/dist/consts/http-status.js +66 -65
  42. package/dist/consts/revalidate.cjs +10 -13
  43. package/dist/consts/revalidate.js +10 -9
  44. package/dist/contexts/NavigationHistoryContext/hook.cjs +41 -42
  45. package/dist/contexts/NavigationHistoryContext/hook.js +40 -38
  46. package/dist/contexts/NavigationHistoryContext/index.cjs +31 -28
  47. package/dist/contexts/NavigationHistoryContext/index.js +30 -24
  48. package/dist/contexts/PageDataContext/index.cjs +15 -18
  49. package/dist/contexts/PageDataContext/index.js +14 -14
  50. package/dist/form/Form.cjs +19 -28
  51. package/dist/form/Form.js +18 -24
  52. package/dist/form/FormSubmitButton.cjs +15 -27
  53. package/dist/form/FormSubmitButton.js +14 -23
  54. package/dist/form/base/FormCheckbox.cjs +15 -23
  55. package/dist/form/base/FormCheckbox.js +14 -19
  56. package/dist/form/base/FormCheckboxGroup.cjs +10 -16
  57. package/dist/form/base/FormCheckboxGroup.js +9 -12
  58. package/dist/form/base/FormDateInput.cjs +10 -16
  59. package/dist/form/base/FormDateInput.js +9 -12
  60. package/dist/form/base/FormDatePickerInput.cjs +10 -16
  61. package/dist/form/base/FormDatePickerInput.js +9 -12
  62. package/dist/form/base/FormDateTimePicker.cjs +10 -16
  63. package/dist/form/base/FormDateTimePicker.js +9 -12
  64. package/dist/form/base/FormMonthPickerInput.cjs +10 -16
  65. package/dist/form/base/FormMonthPickerInput.js +9 -12
  66. package/dist/form/base/FormMultiSelect.cjs +10 -16
  67. package/dist/form/base/FormMultiSelect.js +9 -12
  68. package/dist/form/base/FormNumberInput.cjs +12 -16
  69. package/dist/form/base/FormNumberInput.js +10 -12
  70. package/dist/form/base/FormRadioGroup.cjs +10 -16
  71. package/dist/form/base/FormRadioGroup.js +9 -12
  72. package/dist/form/base/FormSelect.cjs +10 -16
  73. package/dist/form/base/FormSelect.js +9 -12
  74. package/dist/form/base/FormSelectInfinity.cjs +15 -21
  75. package/dist/form/base/FormSelectInfinity.js +14 -17
  76. package/dist/form/base/FormTextInput.cjs +10 -16
  77. package/dist/form/base/FormTextInput.js +9 -12
  78. package/dist/form/base/FormTextarea.cjs +10 -10
  79. package/dist/form/base/FormTextarea.js +9 -6
  80. package/dist/form/base/FormTimeInput.cjs +18 -24
  81. package/dist/form/base/FormTimeInput.js +17 -20
  82. package/dist/form/utils/nullable-but-required.cjs +14 -17
  83. package/dist/form/utils/nullable-but-required.js +13 -13
  84. package/dist/form/utils/optional-but-required.cjs +14 -17
  85. package/dist/form/utils/optional-but-required.js +13 -13
  86. package/dist/form/utils/zodValidator.cjs +9 -13
  87. package/dist/form/utils/zodValidator.js +9 -9
  88. package/dist/hocs/withController.cjs +43 -54
  89. package/dist/hocs/withController.js +42 -50
  90. package/dist/hocs/withModalManager.cjs +29 -35
  91. package/dist/hocs/withModalManager.js +28 -31
  92. package/dist/hooks/useBreakpoint.cjs +8 -12
  93. package/dist/hooks/useBreakpoint.js +7 -8
  94. package/dist/hooks/useFetchNextPageOnScroll.cjs +13 -21
  95. package/dist/hooks/useFetchNextPageOnScroll.js +13 -17
  96. package/dist/hooks/useOnScrollProgress.cjs +33 -37
  97. package/dist/hooks/useOnScrollProgress.js +32 -33
  98. package/dist/hooks/useUpdateSearchParams.cjs +22 -22
  99. package/dist/hooks/useUpdateSearchParams.js +21 -18
  100. package/dist/hooks/useZodConfig.cjs +14 -19
  101. package/dist/hooks/useZodConfig.js +12 -15
  102. package/dist/index.cjs +130 -136
  103. package/dist/index.d.ts +14 -16
  104. package/dist/index.js +62 -61
  105. package/dist/mantine/breakpoints-with-px.cjs +9 -12
  106. package/dist/mantine/breakpoints-with-px.js +9 -8
  107. package/dist/mantine/my-default-theme.cjs +23 -41
  108. package/dist/mantine/my-default-theme.js +22 -37
  109. package/dist/mantine/to-tailwind-colors.cjs +9 -18
  110. package/dist/mantine/to-tailwind-colors.js +9 -14
  111. package/dist/node_modules/@tanstack/react-virtual/dist/esm/index.cjs +35 -70
  112. package/dist/node_modules/@tanstack/react-virtual/dist/esm/index.js +34 -42
  113. package/dist/node_modules/@tanstack/virtual-core/dist/esm/index.cjs +700 -811
  114. package/dist/node_modules/@tanstack/virtual-core/dist/esm/index.js +701 -804
  115. package/dist/node_modules/@tanstack/virtual-core/dist/esm/utils.cjs +44 -64
  116. package/dist/node_modules/@tanstack/virtual-core/dist/esm/utils.js +44 -60
  117. package/dist/utils/array/groupBy.cjs +30 -40
  118. package/dist/utils/array/groupBy.js +30 -36
  119. package/dist/utils/array/shuffleArray.cjs +11 -17
  120. package/dist/utils/array/shuffleArray.js +11 -13
  121. package/dist/utils/formatBytes.cjs +12 -11
  122. package/dist/utils/formatBytes.js +12 -7
  123. package/dist/utils/isInfinityEmpty.cjs +3 -6
  124. package/dist/utils/isInfinityEmpty.js +3 -2
  125. package/dist/utils/ky/addBodyJsonHook.cjs +9 -10
  126. package/dist/utils/ky/addBodyJsonHook.js +8 -6
  127. package/dist/utils/ky/parseJson.cjs +6 -9
  128. package/dist/utils/ky/parseJson.js +6 -5
  129. package/dist/utils/new-route.cjs +30 -39
  130. package/dist/utils/new-route.js +30 -35
  131. package/dist/utils/query-stringify.cjs +5 -8
  132. package/dist/utils/query-stringify.js +5 -4
  133. package/dist/utils/virtual-styles.cjs +21 -26
  134. package/dist/utils/virtual-styles.js +21 -22
  135. package/package.json +67 -65
@@ -1,813 +1,710 @@
1
- import { memo, notUndefined, approxEqual, debounce } from './utils.js';
2
-
3
- const getRect = (element) => {
4
- const { offsetWidth, offsetHeight } = element;
5
- return { width: offsetWidth, height: offsetHeight };
1
+ import { approxEqual, debounce, memo, notUndefined } from "./utils.js";
2
+ //#region node_modules/@tanstack/virtual-core/dist/esm/index.js
3
+ var getRect = (element) => {
4
+ const { offsetWidth, offsetHeight } = element;
5
+ return {
6
+ width: offsetWidth,
7
+ height: offsetHeight
8
+ };
6
9
  };
7
- const defaultKeyExtractor = (index) => index;
8
- const defaultRangeExtractor = (range) => {
9
- const start = Math.max(range.startIndex - range.overscan, 0);
10
- const end = Math.min(range.endIndex + range.overscan, range.count - 1);
11
- const arr = [];
12
- for (let i = start; i <= end; i++) {
13
- arr.push(i);
14
- }
15
- return arr;
10
+ var defaultKeyExtractor = (index) => index;
11
+ var defaultRangeExtractor = (range) => {
12
+ const start = Math.max(range.startIndex - range.overscan, 0);
13
+ const end = Math.min(range.endIndex + range.overscan, range.count - 1);
14
+ const arr = [];
15
+ for (let i = start; i <= end; i++) arr.push(i);
16
+ return arr;
16
17
  };
17
- const observeElementRect = (instance, cb) => {
18
- const element = instance.scrollElement;
19
- if (!element) {
20
- return;
21
- }
22
- const targetWindow = instance.targetWindow;
23
- if (!targetWindow) {
24
- return;
25
- }
26
- const handler = (rect) => {
27
- const { width, height } = rect;
28
- cb({ width: Math.round(width), height: Math.round(height) });
29
- };
30
- handler(getRect(element));
31
- if (!targetWindow.ResizeObserver) {
32
- return () => {
33
- };
34
- }
35
- const observer = new targetWindow.ResizeObserver((entries) => {
36
- const run = () => {
37
- const entry = entries[0];
38
- if (entry == null ? void 0 : entry.borderBoxSize) {
39
- const box = entry.borderBoxSize[0];
40
- if (box) {
41
- handler({ width: box.inlineSize, height: box.blockSize });
42
- return;
43
- }
44
- }
45
- handler(getRect(element));
46
- };
47
- instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
48
- });
49
- observer.observe(element, { box: "border-box" });
50
- return () => {
51
- observer.unobserve(element);
52
- };
18
+ var observeElementRect = (instance, cb) => {
19
+ const element = instance.scrollElement;
20
+ if (!element) return;
21
+ const targetWindow = instance.targetWindow;
22
+ if (!targetWindow) return;
23
+ const handler = (rect) => {
24
+ const { width, height } = rect;
25
+ cb({
26
+ width: Math.round(width),
27
+ height: Math.round(height)
28
+ });
29
+ };
30
+ handler(getRect(element));
31
+ if (!targetWindow.ResizeObserver) return () => {};
32
+ const observer = new targetWindow.ResizeObserver((entries) => {
33
+ const run = () => {
34
+ const entry = entries[0];
35
+ if (entry == null ? void 0 : entry.borderBoxSize) {
36
+ const box = entry.borderBoxSize[0];
37
+ if (box) {
38
+ handler({
39
+ width: box.inlineSize,
40
+ height: box.blockSize
41
+ });
42
+ return;
43
+ }
44
+ }
45
+ handler(getRect(element));
46
+ };
47
+ instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
48
+ });
49
+ observer.observe(element, { box: "border-box" });
50
+ return () => {
51
+ observer.unobserve(element);
52
+ };
53
53
  };
54
- const addEventListenerOptions = {
55
- passive: true
54
+ var addEventListenerOptions = { passive: true };
55
+ var supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
56
+ var observeElementOffset = (instance, cb) => {
57
+ const element = instance.scrollElement;
58
+ if (!element) return;
59
+ const targetWindow = instance.targetWindow;
60
+ if (!targetWindow) return;
61
+ let offset = 0;
62
+ const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(targetWindow, () => {
63
+ cb(offset, false);
64
+ }, instance.options.isScrollingResetDelay);
65
+ const createHandler = (isScrolling) => () => {
66
+ const { horizontal, isRtl } = instance.options;
67
+ offset = horizontal ? element["scrollLeft"] * (isRtl && -1 || 1) : element["scrollTop"];
68
+ fallback();
69
+ cb(offset, isScrolling);
70
+ };
71
+ const handler = createHandler(true);
72
+ const endHandler = createHandler(false);
73
+ element.addEventListener("scroll", handler, addEventListenerOptions);
74
+ const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
75
+ if (registerScrollendEvent) element.addEventListener("scrollend", endHandler, addEventListenerOptions);
76
+ return () => {
77
+ element.removeEventListener("scroll", handler);
78
+ if (registerScrollendEvent) element.removeEventListener("scrollend", endHandler);
79
+ };
56
80
  };
57
- const supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
58
- const observeElementOffset = (instance, cb) => {
59
- const element = instance.scrollElement;
60
- if (!element) {
61
- return;
62
- }
63
- const targetWindow = instance.targetWindow;
64
- if (!targetWindow) {
65
- return;
66
- }
67
- let offset = 0;
68
- const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(
69
- targetWindow,
70
- () => {
71
- cb(offset, false);
72
- },
73
- instance.options.isScrollingResetDelay
74
- );
75
- const createHandler = (isScrolling) => () => {
76
- const { horizontal, isRtl } = instance.options;
77
- offset = horizontal ? element["scrollLeft"] * (isRtl && -1 || 1) : element["scrollTop"];
78
- fallback();
79
- cb(offset, isScrolling);
80
- };
81
- const handler = createHandler(true);
82
- const endHandler = createHandler(false);
83
- element.addEventListener("scroll", handler, addEventListenerOptions);
84
- const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
85
- if (registerScrollendEvent) {
86
- element.addEventListener("scrollend", endHandler, addEventListenerOptions);
87
- }
88
- return () => {
89
- element.removeEventListener("scroll", handler);
90
- if (registerScrollendEvent) {
91
- element.removeEventListener("scrollend", endHandler);
92
- }
93
- };
81
+ var measureElement = (element, entry, instance) => {
82
+ if (entry == null ? void 0 : entry.borderBoxSize) {
83
+ const box = entry.borderBoxSize[0];
84
+ if (box) return Math.round(box[instance.options.horizontal ? "inlineSize" : "blockSize"]);
85
+ }
86
+ return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
94
87
  };
95
- const measureElement = (element, entry, instance) => {
96
- if (entry == null ? void 0 : entry.borderBoxSize) {
97
- const box = entry.borderBoxSize[0];
98
- if (box) {
99
- const size = Math.round(
100
- box[instance.options.horizontal ? "inlineSize" : "blockSize"]
101
- );
102
- return size;
103
- }
104
- }
105
- return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
88
+ var elementScroll = (offset, { adjustments = 0, behavior }, instance) => {
89
+ var _a, _b;
90
+ const toOffset = offset + adjustments;
91
+ (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null || _b.call(_a, {
92
+ [instance.options.horizontal ? "left" : "top"]: toOffset,
93
+ behavior
94
+ });
106
95
  };
107
- const elementScroll = (offset, {
108
- adjustments = 0,
109
- behavior
110
- }, instance) => {
111
- var _a, _b;
112
- const toOffset = offset + adjustments;
113
- (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {
114
- [instance.options.horizontal ? "left" : "top"]: toOffset,
115
- behavior
116
- });
96
+ var Virtualizer = class {
97
+ constructor(opts) {
98
+ this.unsubs = [];
99
+ this.scrollElement = null;
100
+ this.targetWindow = null;
101
+ this.isScrolling = false;
102
+ this.scrollState = null;
103
+ this.measurementsCache = [];
104
+ this.itemSizeCache = /* @__PURE__ */ new Map();
105
+ this.laneAssignments = /* @__PURE__ */ new Map();
106
+ this.pendingMeasuredCacheIndexes = [];
107
+ this.prevLanes = void 0;
108
+ this.lanesChangedFlag = false;
109
+ this.lanesSettling = false;
110
+ this.scrollRect = null;
111
+ this.scrollOffset = null;
112
+ this.scrollDirection = null;
113
+ this.scrollAdjustments = 0;
114
+ this.elementsCache = /* @__PURE__ */ new Map();
115
+ this.now = () => {
116
+ var _a, _b, _c;
117
+ return ((_c = (_b = (_a = this.targetWindow) == null ? void 0 : _a.performance) == null ? void 0 : _b.now) == null ? void 0 : _c.call(_b)) ?? Date.now();
118
+ };
119
+ this.observer = /* @__PURE__ */ (() => {
120
+ let _ro = null;
121
+ const get = () => {
122
+ if (_ro) return _ro;
123
+ if (!this.targetWindow || !this.targetWindow.ResizeObserver) return null;
124
+ return _ro = new this.targetWindow.ResizeObserver((entries) => {
125
+ entries.forEach((entry) => {
126
+ const run = () => {
127
+ const node = entry.target;
128
+ const index = this.indexFromElement(node);
129
+ if (!node.isConnected) {
130
+ this.observer.unobserve(node);
131
+ return;
132
+ }
133
+ if (this.shouldMeasureDuringScroll(index)) this.resizeItem(index, this.options.measureElement(node, entry, this));
134
+ };
135
+ this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
136
+ });
137
+ });
138
+ };
139
+ return {
140
+ disconnect: () => {
141
+ var _a;
142
+ (_a = get()) == null || _a.disconnect();
143
+ _ro = null;
144
+ },
145
+ observe: (target) => {
146
+ var _a;
147
+ return (_a = get()) == null ? void 0 : _a.observe(target, { box: "border-box" });
148
+ },
149
+ unobserve: (target) => {
150
+ var _a;
151
+ return (_a = get()) == null ? void 0 : _a.unobserve(target);
152
+ }
153
+ };
154
+ })();
155
+ this.range = null;
156
+ this.setOptions = (opts2) => {
157
+ Object.entries(opts2).forEach(([key, value]) => {
158
+ if (typeof value === "undefined") delete opts2[key];
159
+ });
160
+ this.options = {
161
+ debug: false,
162
+ initialOffset: 0,
163
+ overscan: 1,
164
+ paddingStart: 0,
165
+ paddingEnd: 0,
166
+ scrollPaddingStart: 0,
167
+ scrollPaddingEnd: 0,
168
+ horizontal: false,
169
+ getItemKey: defaultKeyExtractor,
170
+ rangeExtractor: defaultRangeExtractor,
171
+ onChange: () => {},
172
+ measureElement,
173
+ initialRect: {
174
+ width: 0,
175
+ height: 0
176
+ },
177
+ scrollMargin: 0,
178
+ gap: 0,
179
+ indexAttribute: "data-index",
180
+ initialMeasurementsCache: [],
181
+ lanes: 1,
182
+ isScrollingResetDelay: 150,
183
+ enabled: true,
184
+ isRtl: false,
185
+ useScrollendEvent: false,
186
+ useAnimationFrameWithResizeObserver: false,
187
+ laneAssignmentMode: "estimate",
188
+ ...opts2
189
+ };
190
+ };
191
+ this.notify = (sync) => {
192
+ var _a, _b;
193
+ (_b = (_a = this.options).onChange) == null || _b.call(_a, this, sync);
194
+ };
195
+ this.maybeNotify = memo(() => {
196
+ this.calculateRange();
197
+ return [
198
+ this.isScrolling,
199
+ this.range ? this.range.startIndex : null,
200
+ this.range ? this.range.endIndex : null
201
+ ];
202
+ }, (isScrolling) => {
203
+ this.notify(isScrolling);
204
+ }, {
205
+ key: process.env.NODE_ENV !== "production" && "maybeNotify",
206
+ debug: () => this.options.debug,
207
+ initialDeps: [
208
+ this.isScrolling,
209
+ this.range ? this.range.startIndex : null,
210
+ this.range ? this.range.endIndex : null
211
+ ]
212
+ });
213
+ this.cleanup = () => {
214
+ this.unsubs.filter(Boolean).forEach((d) => d());
215
+ this.unsubs = [];
216
+ this.observer.disconnect();
217
+ if (this.rafId != null && this.targetWindow) {
218
+ this.targetWindow.cancelAnimationFrame(this.rafId);
219
+ this.rafId = null;
220
+ }
221
+ this.scrollState = null;
222
+ this.scrollElement = null;
223
+ this.targetWindow = null;
224
+ };
225
+ this._didMount = () => {
226
+ return () => {
227
+ this.cleanup();
228
+ };
229
+ };
230
+ this._willUpdate = () => {
231
+ var _a;
232
+ const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;
233
+ if (this.scrollElement !== scrollElement) {
234
+ this.cleanup();
235
+ if (!scrollElement) {
236
+ this.maybeNotify();
237
+ return;
238
+ }
239
+ this.scrollElement = scrollElement;
240
+ if (this.scrollElement && "ownerDocument" in this.scrollElement) this.targetWindow = this.scrollElement.ownerDocument.defaultView;
241
+ else this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;
242
+ this.elementsCache.forEach((cached) => {
243
+ this.observer.observe(cached);
244
+ });
245
+ this.unsubs.push(this.options.observeElementRect(this, (rect) => {
246
+ this.scrollRect = rect;
247
+ this.maybeNotify();
248
+ }));
249
+ this.unsubs.push(this.options.observeElementOffset(this, (offset, isScrolling) => {
250
+ this.scrollAdjustments = 0;
251
+ this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? "forward" : "backward" : null;
252
+ this.scrollOffset = offset;
253
+ this.isScrolling = isScrolling;
254
+ if (this.scrollState) this.scheduleScrollReconcile();
255
+ this.maybeNotify();
256
+ }));
257
+ this._scrollToOffset(this.getScrollOffset(), {
258
+ adjustments: void 0,
259
+ behavior: void 0
260
+ });
261
+ }
262
+ };
263
+ this.rafId = null;
264
+ this.getSize = () => {
265
+ if (!this.options.enabled) {
266
+ this.scrollRect = null;
267
+ return 0;
268
+ }
269
+ this.scrollRect = this.scrollRect ?? this.options.initialRect;
270
+ return this.scrollRect[this.options.horizontal ? "width" : "height"];
271
+ };
272
+ this.getScrollOffset = () => {
273
+ if (!this.options.enabled) {
274
+ this.scrollOffset = null;
275
+ return 0;
276
+ }
277
+ this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === "function" ? this.options.initialOffset() : this.options.initialOffset);
278
+ return this.scrollOffset;
279
+ };
280
+ this.getFurthestMeasurement = (measurements, index) => {
281
+ const furthestMeasurementsFound = /* @__PURE__ */ new Map();
282
+ const furthestMeasurements = /* @__PURE__ */ new Map();
283
+ for (let m = index - 1; m >= 0; m--) {
284
+ const measurement = measurements[m];
285
+ if (furthestMeasurementsFound.has(measurement.lane)) continue;
286
+ const previousFurthestMeasurement = furthestMeasurements.get(measurement.lane);
287
+ if (previousFurthestMeasurement == null || measurement.end > previousFurthestMeasurement.end) furthestMeasurements.set(measurement.lane, measurement);
288
+ else if (measurement.end < previousFurthestMeasurement.end) furthestMeasurementsFound.set(measurement.lane, true);
289
+ if (furthestMeasurementsFound.size === this.options.lanes) break;
290
+ }
291
+ return furthestMeasurements.size === this.options.lanes ? Array.from(furthestMeasurements.values()).sort((a, b) => {
292
+ if (a.end === b.end) return a.index - b.index;
293
+ return a.end - b.end;
294
+ })[0] : void 0;
295
+ };
296
+ this.getMeasurementOptions = memo(() => [
297
+ this.options.count,
298
+ this.options.paddingStart,
299
+ this.options.scrollMargin,
300
+ this.options.getItemKey,
301
+ this.options.enabled,
302
+ this.options.lanes,
303
+ this.options.laneAssignmentMode
304
+ ], (count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode) => {
305
+ if (this.prevLanes !== void 0 && this.prevLanes !== lanes) this.lanesChangedFlag = true;
306
+ this.prevLanes = lanes;
307
+ this.pendingMeasuredCacheIndexes = [];
308
+ return {
309
+ count,
310
+ paddingStart,
311
+ scrollMargin,
312
+ getItemKey,
313
+ enabled,
314
+ lanes,
315
+ laneAssignmentMode
316
+ };
317
+ }, { key: false });
318
+ this.getMeasurements = memo(() => [this.getMeasurementOptions(), this.itemSizeCache], ({ count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode }, itemSizeCache) => {
319
+ if (!enabled) {
320
+ this.measurementsCache = [];
321
+ this.itemSizeCache.clear();
322
+ this.laneAssignments.clear();
323
+ return [];
324
+ }
325
+ if (this.laneAssignments.size > count) {
326
+ for (const index of this.laneAssignments.keys()) if (index >= count) this.laneAssignments.delete(index);
327
+ }
328
+ if (this.lanesChangedFlag) {
329
+ this.lanesChangedFlag = false;
330
+ this.lanesSettling = true;
331
+ this.measurementsCache = [];
332
+ this.itemSizeCache.clear();
333
+ this.laneAssignments.clear();
334
+ this.pendingMeasuredCacheIndexes = [];
335
+ }
336
+ if (this.measurementsCache.length === 0 && !this.lanesSettling) {
337
+ this.measurementsCache = this.options.initialMeasurementsCache;
338
+ this.measurementsCache.forEach((item) => {
339
+ this.itemSizeCache.set(item.key, item.size);
340
+ });
341
+ }
342
+ const min = this.lanesSettling ? 0 : this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
343
+ this.pendingMeasuredCacheIndexes = [];
344
+ if (this.lanesSettling && this.measurementsCache.length === count) this.lanesSettling = false;
345
+ const measurements = this.measurementsCache.slice(0, min);
346
+ const laneLastIndex = new Array(lanes).fill(void 0);
347
+ for (let m = 0; m < min; m++) {
348
+ const item = measurements[m];
349
+ if (item) laneLastIndex[item.lane] = m;
350
+ }
351
+ for (let i = min; i < count; i++) {
352
+ const key = getItemKey(i);
353
+ const cachedLane = this.laneAssignments.get(i);
354
+ let lane;
355
+ let start;
356
+ const shouldCacheLane = laneAssignmentMode === "estimate" || itemSizeCache.has(key);
357
+ if (cachedLane !== void 0 && this.options.lanes > 1) {
358
+ lane = cachedLane;
359
+ const prevIndex = laneLastIndex[lane];
360
+ const prevInLane = prevIndex !== void 0 ? measurements[prevIndex] : void 0;
361
+ start = prevInLane ? prevInLane.end + this.options.gap : paddingStart + scrollMargin;
362
+ } else {
363
+ const furthestMeasurement = this.options.lanes === 1 ? measurements[i - 1] : this.getFurthestMeasurement(measurements, i);
364
+ start = furthestMeasurement ? furthestMeasurement.end + this.options.gap : paddingStart + scrollMargin;
365
+ lane = furthestMeasurement ? furthestMeasurement.lane : i % this.options.lanes;
366
+ if (this.options.lanes > 1 && shouldCacheLane) this.laneAssignments.set(i, lane);
367
+ }
368
+ const measuredSize = itemSizeCache.get(key);
369
+ const size = typeof measuredSize === "number" ? measuredSize : this.options.estimateSize(i);
370
+ const end = start + size;
371
+ measurements[i] = {
372
+ index: i,
373
+ start,
374
+ size,
375
+ end,
376
+ key,
377
+ lane
378
+ };
379
+ laneLastIndex[lane] = i;
380
+ }
381
+ this.measurementsCache = measurements;
382
+ return measurements;
383
+ }, {
384
+ key: process.env.NODE_ENV !== "production" && "getMeasurements",
385
+ debug: () => this.options.debug
386
+ });
387
+ this.calculateRange = memo(() => [
388
+ this.getMeasurements(),
389
+ this.getSize(),
390
+ this.getScrollOffset(),
391
+ this.options.lanes
392
+ ], (measurements, outerSize, scrollOffset, lanes) => {
393
+ return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({
394
+ measurements,
395
+ outerSize,
396
+ scrollOffset,
397
+ lanes
398
+ }) : null;
399
+ }, {
400
+ key: process.env.NODE_ENV !== "production" && "calculateRange",
401
+ debug: () => this.options.debug
402
+ });
403
+ this.getVirtualIndexes = memo(() => {
404
+ let startIndex = null;
405
+ let endIndex = null;
406
+ const range = this.calculateRange();
407
+ if (range) {
408
+ startIndex = range.startIndex;
409
+ endIndex = range.endIndex;
410
+ }
411
+ this.maybeNotify.updateDeps([
412
+ this.isScrolling,
413
+ startIndex,
414
+ endIndex
415
+ ]);
416
+ return [
417
+ this.options.rangeExtractor,
418
+ this.options.overscan,
419
+ this.options.count,
420
+ startIndex,
421
+ endIndex
422
+ ];
423
+ }, (rangeExtractor, overscan, count, startIndex, endIndex) => {
424
+ return startIndex === null || endIndex === null ? [] : rangeExtractor({
425
+ startIndex,
426
+ endIndex,
427
+ overscan,
428
+ count
429
+ });
430
+ }, {
431
+ key: process.env.NODE_ENV !== "production" && "getVirtualIndexes",
432
+ debug: () => this.options.debug
433
+ });
434
+ this.indexFromElement = (node) => {
435
+ const attributeName = this.options.indexAttribute;
436
+ const indexStr = node.getAttribute(attributeName);
437
+ if (!indexStr) {
438
+ console.warn(`Missing attribute name '${attributeName}={index}' on measured element.`);
439
+ return -1;
440
+ }
441
+ return parseInt(indexStr, 10);
442
+ };
443
+ this.shouldMeasureDuringScroll = (index) => {
444
+ var _a;
445
+ if (!this.scrollState || this.scrollState.behavior !== "smooth") return true;
446
+ const scrollIndex = this.scrollState.index ?? ((_a = this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)) == null ? void 0 : _a.index);
447
+ if (scrollIndex !== void 0 && this.range) {
448
+ const bufferSize = Math.max(this.options.overscan, Math.ceil((this.range.endIndex - this.range.startIndex) / 2));
449
+ const minIndex = Math.max(0, scrollIndex - bufferSize);
450
+ const maxIndex = Math.min(this.options.count - 1, scrollIndex + bufferSize);
451
+ return index >= minIndex && index <= maxIndex;
452
+ }
453
+ return true;
454
+ };
455
+ this.measureElement = (node) => {
456
+ if (!node) {
457
+ this.elementsCache.forEach((cached, key2) => {
458
+ if (!cached.isConnected) {
459
+ this.observer.unobserve(cached);
460
+ this.elementsCache.delete(key2);
461
+ }
462
+ });
463
+ return;
464
+ }
465
+ const index = this.indexFromElement(node);
466
+ const key = this.options.getItemKey(index);
467
+ const prevNode = this.elementsCache.get(key);
468
+ if (prevNode !== node) {
469
+ if (prevNode) this.observer.unobserve(prevNode);
470
+ this.observer.observe(node);
471
+ this.elementsCache.set(key, node);
472
+ }
473
+ if ((!this.isScrolling || this.scrollState) && this.shouldMeasureDuringScroll(index)) this.resizeItem(index, this.options.measureElement(node, void 0, this));
474
+ };
475
+ this.resizeItem = (index, size) => {
476
+ var _a;
477
+ const item = this.measurementsCache[index];
478
+ if (!item) return;
479
+ const delta = size - (this.itemSizeCache.get(item.key) ?? item.size);
480
+ if (delta !== 0) {
481
+ if (((_a = this.scrollState) == null ? void 0 : _a.behavior) !== "smooth" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) : item.start < this.getScrollOffset() + this.scrollAdjustments)) {
482
+ if (process.env.NODE_ENV !== "production" && this.options.debug) console.info("correction", delta);
483
+ this._scrollToOffset(this.getScrollOffset(), {
484
+ adjustments: this.scrollAdjustments += delta,
485
+ behavior: void 0
486
+ });
487
+ }
488
+ this.pendingMeasuredCacheIndexes.push(item.index);
489
+ this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));
490
+ this.notify(false);
491
+ }
492
+ };
493
+ this.getVirtualItems = memo(() => [this.getVirtualIndexes(), this.getMeasurements()], (indexes, measurements) => {
494
+ const virtualItems = [];
495
+ for (let k = 0, len = indexes.length; k < len; k++) {
496
+ const measurement = measurements[indexes[k]];
497
+ virtualItems.push(measurement);
498
+ }
499
+ return virtualItems;
500
+ }, {
501
+ key: process.env.NODE_ENV !== "production" && "getVirtualItems",
502
+ debug: () => this.options.debug
503
+ });
504
+ this.getVirtualItemForOffset = (offset) => {
505
+ const measurements = this.getMeasurements();
506
+ if (measurements.length === 0) return;
507
+ return notUndefined(measurements[findNearestBinarySearch(0, measurements.length - 1, (index) => notUndefined(measurements[index]).start, offset)]);
508
+ };
509
+ this.getMaxScrollOffset = () => {
510
+ if (!this.scrollElement) return 0;
511
+ if ("scrollHeight" in this.scrollElement) return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;
512
+ else {
513
+ const doc = this.scrollElement.document.documentElement;
514
+ return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;
515
+ }
516
+ };
517
+ this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
518
+ if (!this.scrollElement) return 0;
519
+ const size = this.getSize();
520
+ const scrollOffset = this.getScrollOffset();
521
+ if (align === "auto") align = toOffset >= scrollOffset + size ? "end" : "start";
522
+ if (align === "center") toOffset += (itemSize - size) / 2;
523
+ else if (align === "end") toOffset -= size;
524
+ const maxOffset = this.getMaxScrollOffset();
525
+ return Math.max(Math.min(maxOffset, toOffset), 0);
526
+ };
527
+ this.getOffsetForIndex = (index, align = "auto") => {
528
+ index = Math.max(0, Math.min(index, this.options.count - 1));
529
+ const size = this.getSize();
530
+ const scrollOffset = this.getScrollOffset();
531
+ const item = this.measurementsCache[index];
532
+ if (!item) return;
533
+ if (align === "auto") if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) align = "end";
534
+ else if (item.start <= scrollOffset + this.options.scrollPaddingStart) align = "start";
535
+ else return [scrollOffset, align];
536
+ if (align === "end" && index === this.options.count - 1) return [this.getMaxScrollOffset(), align];
537
+ const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
538
+ return [this.getOffsetForAlignment(toOffset, align, item.size), align];
539
+ };
540
+ this.scrollToOffset = (toOffset, { align = "start", behavior = "auto" } = {}) => {
541
+ const offset = this.getOffsetForAlignment(toOffset, align);
542
+ const now = this.now();
543
+ this.scrollState = {
544
+ index: null,
545
+ align,
546
+ behavior,
547
+ startedAt: now,
548
+ lastTargetOffset: offset,
549
+ stableFrames: 0
550
+ };
551
+ this._scrollToOffset(offset, {
552
+ adjustments: void 0,
553
+ behavior
554
+ });
555
+ this.scheduleScrollReconcile();
556
+ };
557
+ this.scrollToIndex = (index, { align: initialAlign = "auto", behavior = "auto" } = {}) => {
558
+ index = Math.max(0, Math.min(index, this.options.count - 1));
559
+ const offsetInfo = this.getOffsetForIndex(index, initialAlign);
560
+ if (!offsetInfo) return;
561
+ const [offset, align] = offsetInfo;
562
+ const now = this.now();
563
+ this.scrollState = {
564
+ index,
565
+ align,
566
+ behavior,
567
+ startedAt: now,
568
+ lastTargetOffset: offset,
569
+ stableFrames: 0
570
+ };
571
+ this._scrollToOffset(offset, {
572
+ adjustments: void 0,
573
+ behavior
574
+ });
575
+ this.scheduleScrollReconcile();
576
+ };
577
+ this.scrollBy = (delta, { behavior = "auto" } = {}) => {
578
+ const offset = this.getScrollOffset() + delta;
579
+ const now = this.now();
580
+ this.scrollState = {
581
+ index: null,
582
+ align: "start",
583
+ behavior,
584
+ startedAt: now,
585
+ lastTargetOffset: offset,
586
+ stableFrames: 0
587
+ };
588
+ this._scrollToOffset(offset, {
589
+ adjustments: void 0,
590
+ behavior
591
+ });
592
+ this.scheduleScrollReconcile();
593
+ };
594
+ this.getTotalSize = () => {
595
+ var _a;
596
+ const measurements = this.getMeasurements();
597
+ let end;
598
+ if (measurements.length === 0) end = this.options.paddingStart;
599
+ else if (this.options.lanes === 1) end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;
600
+ else {
601
+ const endByLane = Array(this.options.lanes).fill(null);
602
+ let endIndex = measurements.length - 1;
603
+ while (endIndex >= 0 && endByLane.some((val) => val === null)) {
604
+ const item = measurements[endIndex];
605
+ if (endByLane[item.lane] === null) endByLane[item.lane] = item.end;
606
+ endIndex--;
607
+ }
608
+ end = Math.max(...endByLane.filter((val) => val !== null));
609
+ }
610
+ return Math.max(end - this.options.scrollMargin + this.options.paddingEnd, 0);
611
+ };
612
+ this._scrollToOffset = (offset, { adjustments, behavior }) => {
613
+ this.options.scrollToFn(offset, {
614
+ behavior,
615
+ adjustments
616
+ }, this);
617
+ };
618
+ this.measure = () => {
619
+ this.itemSizeCache = /* @__PURE__ */ new Map();
620
+ this.laneAssignments = /* @__PURE__ */ new Map();
621
+ this.notify(false);
622
+ };
623
+ this.setOptions(opts);
624
+ }
625
+ scheduleScrollReconcile() {
626
+ if (!this.targetWindow) {
627
+ this.scrollState = null;
628
+ return;
629
+ }
630
+ if (this.rafId != null) return;
631
+ this.rafId = this.targetWindow.requestAnimationFrame(() => {
632
+ this.rafId = null;
633
+ this.reconcileScroll();
634
+ });
635
+ }
636
+ reconcileScroll() {
637
+ if (!this.scrollState) return;
638
+ if (!this.scrollElement) return;
639
+ if (this.now() - this.scrollState.startedAt > 5e3) {
640
+ this.scrollState = null;
641
+ return;
642
+ }
643
+ const offsetInfo = this.scrollState.index != null ? this.getOffsetForIndex(this.scrollState.index, this.scrollState.align) : void 0;
644
+ const targetOffset = offsetInfo ? offsetInfo[0] : this.scrollState.lastTargetOffset;
645
+ const STABLE_FRAMES = 1;
646
+ const targetChanged = targetOffset !== this.scrollState.lastTargetOffset;
647
+ if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {
648
+ this.scrollState.stableFrames++;
649
+ if (this.scrollState.stableFrames >= STABLE_FRAMES) {
650
+ this.scrollState = null;
651
+ return;
652
+ }
653
+ } else {
654
+ this.scrollState.stableFrames = 0;
655
+ if (targetChanged) {
656
+ this.scrollState.lastTargetOffset = targetOffset;
657
+ this.scrollState.behavior = "auto";
658
+ this._scrollToOffset(targetOffset, {
659
+ adjustments: void 0,
660
+ behavior: "auto"
661
+ });
662
+ }
663
+ }
664
+ this.scheduleScrollReconcile();
665
+ }
117
666
  };
118
- class Virtualizer {
119
- constructor(opts) {
120
- this.unsubs = [];
121
- this.scrollElement = null;
122
- this.targetWindow = null;
123
- this.isScrolling = false;
124
- this.currentScrollToIndex = null;
125
- this.measurementsCache = [];
126
- this.itemSizeCache = /* @__PURE__ */ new Map();
127
- this.laneAssignments = /* @__PURE__ */ new Map();
128
- this.pendingMeasuredCacheIndexes = [];
129
- this.prevLanes = void 0;
130
- this.lanesChangedFlag = false;
131
- this.lanesSettling = false;
132
- this.scrollRect = null;
133
- this.scrollOffset = null;
134
- this.scrollDirection = null;
135
- this.scrollAdjustments = 0;
136
- this.elementsCache = /* @__PURE__ */ new Map();
137
- this.observer = /* @__PURE__ */ (() => {
138
- let _ro = null;
139
- const get = () => {
140
- if (_ro) {
141
- return _ro;
142
- }
143
- if (!this.targetWindow || !this.targetWindow.ResizeObserver) {
144
- return null;
145
- }
146
- return _ro = new this.targetWindow.ResizeObserver((entries) => {
147
- entries.forEach((entry) => {
148
- const run = () => {
149
- this._measureElement(entry.target, entry);
150
- };
151
- this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
152
- });
153
- });
154
- };
155
- return {
156
- disconnect: () => {
157
- var _a;
158
- (_a = get()) == null ? void 0 : _a.disconnect();
159
- _ro = null;
160
- },
161
- observe: (target) => {
162
- var _a;
163
- return (_a = get()) == null ? void 0 : _a.observe(target, { box: "border-box" });
164
- },
165
- unobserve: (target) => {
166
- var _a;
167
- return (_a = get()) == null ? void 0 : _a.unobserve(target);
168
- }
169
- };
170
- })();
171
- this.range = null;
172
- this.setOptions = (opts2) => {
173
- Object.entries(opts2).forEach(([key, value]) => {
174
- if (typeof value === "undefined") delete opts2[key];
175
- });
176
- this.options = {
177
- debug: false,
178
- initialOffset: 0,
179
- overscan: 1,
180
- paddingStart: 0,
181
- paddingEnd: 0,
182
- scrollPaddingStart: 0,
183
- scrollPaddingEnd: 0,
184
- horizontal: false,
185
- getItemKey: defaultKeyExtractor,
186
- rangeExtractor: defaultRangeExtractor,
187
- onChange: () => {
188
- },
189
- measureElement,
190
- initialRect: { width: 0, height: 0 },
191
- scrollMargin: 0,
192
- gap: 0,
193
- indexAttribute: "data-index",
194
- initialMeasurementsCache: [],
195
- lanes: 1,
196
- isScrollingResetDelay: 150,
197
- enabled: true,
198
- isRtl: false,
199
- useScrollendEvent: false,
200
- useAnimationFrameWithResizeObserver: false,
201
- ...opts2
202
- };
203
- };
204
- this.notify = (sync) => {
205
- var _a, _b;
206
- (_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, sync);
207
- };
208
- this.maybeNotify = memo(
209
- () => {
210
- this.calculateRange();
211
- return [
212
- this.isScrolling,
213
- this.range ? this.range.startIndex : null,
214
- this.range ? this.range.endIndex : null
215
- ];
216
- },
217
- (isScrolling) => {
218
- this.notify(isScrolling);
219
- },
220
- {
221
- key: process.env.NODE_ENV !== "production" && "maybeNotify",
222
- debug: () => this.options.debug,
223
- initialDeps: [
224
- this.isScrolling,
225
- this.range ? this.range.startIndex : null,
226
- this.range ? this.range.endIndex : null
227
- ]
228
- }
229
- );
230
- this.cleanup = () => {
231
- this.unsubs.filter(Boolean).forEach((d) => d());
232
- this.unsubs = [];
233
- this.observer.disconnect();
234
- this.scrollElement = null;
235
- this.targetWindow = null;
236
- };
237
- this._didMount = () => {
238
- return () => {
239
- this.cleanup();
240
- };
241
- };
242
- this._willUpdate = () => {
243
- var _a;
244
- const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;
245
- if (this.scrollElement !== scrollElement) {
246
- this.cleanup();
247
- if (!scrollElement) {
248
- this.maybeNotify();
249
- return;
250
- }
251
- this.scrollElement = scrollElement;
252
- if (this.scrollElement && "ownerDocument" in this.scrollElement) {
253
- this.targetWindow = this.scrollElement.ownerDocument.defaultView;
254
- } else {
255
- this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;
256
- }
257
- this.elementsCache.forEach((cached) => {
258
- this.observer.observe(cached);
259
- });
260
- this.unsubs.push(
261
- this.options.observeElementRect(this, (rect) => {
262
- this.scrollRect = rect;
263
- this.maybeNotify();
264
- })
265
- );
266
- this.unsubs.push(
267
- this.options.observeElementOffset(this, (offset, isScrolling) => {
268
- this.scrollAdjustments = 0;
269
- this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? "forward" : "backward" : null;
270
- this.scrollOffset = offset;
271
- this.isScrolling = isScrolling;
272
- this.maybeNotify();
273
- })
274
- );
275
- this._scrollToOffset(this.getScrollOffset(), {
276
- adjustments: void 0,
277
- behavior: void 0
278
- });
279
- }
280
- };
281
- this.getSize = () => {
282
- if (!this.options.enabled) {
283
- this.scrollRect = null;
284
- return 0;
285
- }
286
- this.scrollRect = this.scrollRect ?? this.options.initialRect;
287
- return this.scrollRect[this.options.horizontal ? "width" : "height"];
288
- };
289
- this.getScrollOffset = () => {
290
- if (!this.options.enabled) {
291
- this.scrollOffset = null;
292
- return 0;
293
- }
294
- this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === "function" ? this.options.initialOffset() : this.options.initialOffset);
295
- return this.scrollOffset;
296
- };
297
- this.getFurthestMeasurement = (measurements, index) => {
298
- const furthestMeasurementsFound = /* @__PURE__ */ new Map();
299
- const furthestMeasurements = /* @__PURE__ */ new Map();
300
- for (let m = index - 1; m >= 0; m--) {
301
- const measurement = measurements[m];
302
- if (furthestMeasurementsFound.has(measurement.lane)) {
303
- continue;
304
- }
305
- const previousFurthestMeasurement = furthestMeasurements.get(
306
- measurement.lane
307
- );
308
- if (previousFurthestMeasurement == null || measurement.end > previousFurthestMeasurement.end) {
309
- furthestMeasurements.set(measurement.lane, measurement);
310
- } else if (measurement.end < previousFurthestMeasurement.end) {
311
- furthestMeasurementsFound.set(measurement.lane, true);
312
- }
313
- if (furthestMeasurementsFound.size === this.options.lanes) {
314
- break;
315
- }
316
- }
317
- return furthestMeasurements.size === this.options.lanes ? Array.from(furthestMeasurements.values()).sort((a, b) => {
318
- if (a.end === b.end) {
319
- return a.index - b.index;
320
- }
321
- return a.end - b.end;
322
- })[0] : void 0;
323
- };
324
- this.getMeasurementOptions = memo(
325
- () => [
326
- this.options.count,
327
- this.options.paddingStart,
328
- this.options.scrollMargin,
329
- this.options.getItemKey,
330
- this.options.enabled,
331
- this.options.lanes
332
- ],
333
- (count, paddingStart, scrollMargin, getItemKey, enabled, lanes) => {
334
- const lanesChanged = this.prevLanes !== void 0 && this.prevLanes !== lanes;
335
- if (lanesChanged) {
336
- this.lanesChangedFlag = true;
337
- }
338
- this.prevLanes = lanes;
339
- this.pendingMeasuredCacheIndexes = [];
340
- return {
341
- count,
342
- paddingStart,
343
- scrollMargin,
344
- getItemKey,
345
- enabled,
346
- lanes
347
- };
348
- },
349
- {
350
- key: false
351
- }
352
- );
353
- this.getMeasurements = memo(
354
- () => [this.getMeasurementOptions(), this.itemSizeCache],
355
- ({ count, paddingStart, scrollMargin, getItemKey, enabled, lanes }, itemSizeCache) => {
356
- if (!enabled) {
357
- this.measurementsCache = [];
358
- this.itemSizeCache.clear();
359
- this.laneAssignments.clear();
360
- return [];
361
- }
362
- if (this.laneAssignments.size > count) {
363
- for (const index of this.laneAssignments.keys()) {
364
- if (index >= count) {
365
- this.laneAssignments.delete(index);
366
- }
367
- }
368
- }
369
- if (this.lanesChangedFlag) {
370
- this.lanesChangedFlag = false;
371
- this.lanesSettling = true;
372
- this.measurementsCache = [];
373
- this.itemSizeCache.clear();
374
- this.laneAssignments.clear();
375
- this.pendingMeasuredCacheIndexes = [];
376
- }
377
- if (this.measurementsCache.length === 0 && !this.lanesSettling) {
378
- this.measurementsCache = this.options.initialMeasurementsCache;
379
- this.measurementsCache.forEach((item) => {
380
- this.itemSizeCache.set(item.key, item.size);
381
- });
382
- }
383
- const min = this.lanesSettling ? 0 : this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
384
- this.pendingMeasuredCacheIndexes = [];
385
- if (this.lanesSettling && this.measurementsCache.length === count) {
386
- this.lanesSettling = false;
387
- }
388
- const measurements = this.measurementsCache.slice(0, min);
389
- const laneLastIndex = new Array(lanes).fill(
390
- void 0
391
- );
392
- for (let m = 0; m < min; m++) {
393
- const item = measurements[m];
394
- if (item) {
395
- laneLastIndex[item.lane] = m;
396
- }
397
- }
398
- for (let i = min; i < count; i++) {
399
- const key = getItemKey(i);
400
- const cachedLane = this.laneAssignments.get(i);
401
- let lane;
402
- let start;
403
- if (cachedLane !== void 0 && this.options.lanes > 1) {
404
- lane = cachedLane;
405
- const prevIndex = laneLastIndex[lane];
406
- const prevInLane = prevIndex !== void 0 ? measurements[prevIndex] : void 0;
407
- start = prevInLane ? prevInLane.end + this.options.gap : paddingStart + scrollMargin;
408
- } else {
409
- const furthestMeasurement = this.options.lanes === 1 ? measurements[i - 1] : this.getFurthestMeasurement(measurements, i);
410
- start = furthestMeasurement ? furthestMeasurement.end + this.options.gap : paddingStart + scrollMargin;
411
- lane = furthestMeasurement ? furthestMeasurement.lane : i % this.options.lanes;
412
- if (this.options.lanes > 1) {
413
- this.laneAssignments.set(i, lane);
414
- }
415
- }
416
- const measuredSize = itemSizeCache.get(key);
417
- const size = typeof measuredSize === "number" ? measuredSize : this.options.estimateSize(i);
418
- const end = start + size;
419
- measurements[i] = {
420
- index: i,
421
- start,
422
- size,
423
- end,
424
- key,
425
- lane
426
- };
427
- laneLastIndex[lane] = i;
428
- }
429
- this.measurementsCache = measurements;
430
- return measurements;
431
- },
432
- {
433
- key: process.env.NODE_ENV !== "production" && "getMeasurements",
434
- debug: () => this.options.debug
435
- }
436
- );
437
- this.calculateRange = memo(
438
- () => [
439
- this.getMeasurements(),
440
- this.getSize(),
441
- this.getScrollOffset(),
442
- this.options.lanes
443
- ],
444
- (measurements, outerSize, scrollOffset, lanes) => {
445
- return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({
446
- measurements,
447
- outerSize,
448
- scrollOffset,
449
- lanes
450
- }) : null;
451
- },
452
- {
453
- key: process.env.NODE_ENV !== "production" && "calculateRange",
454
- debug: () => this.options.debug
455
- }
456
- );
457
- this.getVirtualIndexes = memo(
458
- () => {
459
- let startIndex = null;
460
- let endIndex = null;
461
- const range = this.calculateRange();
462
- if (range) {
463
- startIndex = range.startIndex;
464
- endIndex = range.endIndex;
465
- }
466
- this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex]);
467
- return [
468
- this.options.rangeExtractor,
469
- this.options.overscan,
470
- this.options.count,
471
- startIndex,
472
- endIndex
473
- ];
474
- },
475
- (rangeExtractor, overscan, count, startIndex, endIndex) => {
476
- return startIndex === null || endIndex === null ? [] : rangeExtractor({
477
- startIndex,
478
- endIndex,
479
- overscan,
480
- count
481
- });
482
- },
483
- {
484
- key: process.env.NODE_ENV !== "production" && "getVirtualIndexes",
485
- debug: () => this.options.debug
486
- }
487
- );
488
- this.indexFromElement = (node) => {
489
- const attributeName = this.options.indexAttribute;
490
- const indexStr = node.getAttribute(attributeName);
491
- if (!indexStr) {
492
- console.warn(
493
- `Missing attribute name '${attributeName}={index}' on measured element.`
494
- );
495
- return -1;
496
- }
497
- return parseInt(indexStr, 10);
498
- };
499
- this._measureElement = (node, entry) => {
500
- const index = this.indexFromElement(node);
501
- const item = this.measurementsCache[index];
502
- if (!item) {
503
- return;
504
- }
505
- const key = item.key;
506
- const prevNode = this.elementsCache.get(key);
507
- if (prevNode !== node) {
508
- if (prevNode) {
509
- this.observer.unobserve(prevNode);
510
- }
511
- this.observer.observe(node);
512
- this.elementsCache.set(key, node);
513
- }
514
- if (node.isConnected) {
515
- this.resizeItem(index, this.options.measureElement(node, entry, this));
516
- }
517
- };
518
- this.resizeItem = (index, size) => {
519
- const item = this.measurementsCache[index];
520
- if (!item) {
521
- return;
522
- }
523
- const itemSize = this.itemSizeCache.get(item.key) ?? item.size;
524
- const delta = size - itemSize;
525
- if (delta !== 0) {
526
- if (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) : item.start < this.getScrollOffset() + this.scrollAdjustments) {
527
- if (process.env.NODE_ENV !== "production" && this.options.debug) {
528
- console.info("correction", delta);
529
- }
530
- this._scrollToOffset(this.getScrollOffset(), {
531
- adjustments: this.scrollAdjustments += delta,
532
- behavior: void 0
533
- });
534
- }
535
- this.pendingMeasuredCacheIndexes.push(item.index);
536
- this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));
537
- this.notify(false);
538
- }
539
- };
540
- this.measureElement = (node) => {
541
- if (!node) {
542
- this.elementsCache.forEach((cached, key) => {
543
- if (!cached.isConnected) {
544
- this.observer.unobserve(cached);
545
- this.elementsCache.delete(key);
546
- }
547
- });
548
- return;
549
- }
550
- this._measureElement(node, void 0);
551
- };
552
- this.getVirtualItems = memo(
553
- () => [this.getVirtualIndexes(), this.getMeasurements()],
554
- (indexes, measurements) => {
555
- const virtualItems = [];
556
- for (let k = 0, len = indexes.length; k < len; k++) {
557
- const i = indexes[k];
558
- const measurement = measurements[i];
559
- virtualItems.push(measurement);
560
- }
561
- return virtualItems;
562
- },
563
- {
564
- key: process.env.NODE_ENV !== "production" && "getVirtualItems",
565
- debug: () => this.options.debug
566
- }
567
- );
568
- this.getVirtualItemForOffset = (offset) => {
569
- const measurements = this.getMeasurements();
570
- if (measurements.length === 0) {
571
- return void 0;
572
- }
573
- return notUndefined(
574
- measurements[findNearestBinarySearch(
575
- 0,
576
- measurements.length - 1,
577
- (index) => notUndefined(measurements[index]).start,
578
- offset
579
- )]
580
- );
581
- };
582
- this.getMaxScrollOffset = () => {
583
- if (!this.scrollElement) return 0;
584
- if ("scrollHeight" in this.scrollElement) {
585
- return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;
586
- } else {
587
- const doc = this.scrollElement.document.documentElement;
588
- return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;
589
- }
590
- };
591
- this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
592
- if (!this.scrollElement) return 0;
593
- const size = this.getSize();
594
- const scrollOffset = this.getScrollOffset();
595
- if (align === "auto") {
596
- align = toOffset >= scrollOffset + size ? "end" : "start";
597
- }
598
- if (align === "center") {
599
- toOffset += (itemSize - size) / 2;
600
- } else if (align === "end") {
601
- toOffset -= size;
602
- }
603
- const maxOffset = this.getMaxScrollOffset();
604
- return Math.max(Math.min(maxOffset, toOffset), 0);
605
- };
606
- this.getOffsetForIndex = (index, align = "auto") => {
607
- index = Math.max(0, Math.min(index, this.options.count - 1));
608
- const item = this.measurementsCache[index];
609
- if (!item) {
610
- return void 0;
611
- }
612
- const size = this.getSize();
613
- const scrollOffset = this.getScrollOffset();
614
- if (align === "auto") {
615
- if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {
616
- align = "end";
617
- } else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {
618
- align = "start";
619
- } else {
620
- return [scrollOffset, align];
621
- }
622
- }
623
- if (align === "end" && index === this.options.count - 1) {
624
- return [this.getMaxScrollOffset(), align];
625
- }
626
- const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
627
- return [
628
- this.getOffsetForAlignment(toOffset, align, item.size),
629
- align
630
- ];
631
- };
632
- this.isDynamicMode = () => this.elementsCache.size > 0;
633
- this.scrollToOffset = (toOffset, { align = "start", behavior } = {}) => {
634
- if (behavior === "smooth" && this.isDynamicMode()) {
635
- console.warn(
636
- "The `smooth` scroll behavior is not fully supported with dynamic size."
637
- );
638
- }
639
- this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), {
640
- adjustments: void 0,
641
- behavior
642
- });
643
- };
644
- this.scrollToIndex = (index, { align: initialAlign = "auto", behavior } = {}) => {
645
- if (behavior === "smooth" && this.isDynamicMode()) {
646
- console.warn(
647
- "The `smooth` scroll behavior is not fully supported with dynamic size."
648
- );
649
- }
650
- index = Math.max(0, Math.min(index, this.options.count - 1));
651
- this.currentScrollToIndex = index;
652
- let attempts = 0;
653
- const maxAttempts = 10;
654
- const tryScroll = (currentAlign) => {
655
- if (!this.targetWindow) return;
656
- const offsetInfo = this.getOffsetForIndex(index, currentAlign);
657
- if (!offsetInfo) {
658
- console.warn("Failed to get offset for index:", index);
659
- return;
660
- }
661
- const [offset, align] = offsetInfo;
662
- this._scrollToOffset(offset, { adjustments: void 0, behavior });
663
- this.targetWindow.requestAnimationFrame(() => {
664
- if (!this.targetWindow) return;
665
- const verify = () => {
666
- if (this.currentScrollToIndex !== index) return;
667
- const currentOffset = this.getScrollOffset();
668
- const afterInfo = this.getOffsetForIndex(index, align);
669
- if (!afterInfo) {
670
- console.warn("Failed to get offset for index:", index);
671
- return;
672
- }
673
- if (!approxEqual(afterInfo[0], currentOffset)) {
674
- scheduleRetry(align);
675
- }
676
- };
677
- if (this.isDynamicMode()) {
678
- this.targetWindow.requestAnimationFrame(verify);
679
- } else {
680
- verify();
681
- }
682
- });
683
- };
684
- const scheduleRetry = (align) => {
685
- if (!this.targetWindow) return;
686
- if (this.currentScrollToIndex !== index) return;
687
- attempts++;
688
- if (attempts < maxAttempts) {
689
- if (process.env.NODE_ENV !== "production" && this.options.debug) {
690
- console.info("Schedule retry", attempts, maxAttempts);
691
- }
692
- this.targetWindow.requestAnimationFrame(() => tryScroll(align));
693
- } else {
694
- console.warn(
695
- `Failed to scroll to index ${index} after ${maxAttempts} attempts.`
696
- );
697
- }
698
- };
699
- tryScroll(initialAlign);
700
- };
701
- this.scrollBy = (delta, { behavior } = {}) => {
702
- if (behavior === "smooth" && this.isDynamicMode()) {
703
- console.warn(
704
- "The `smooth` scroll behavior is not fully supported with dynamic size."
705
- );
706
- }
707
- this._scrollToOffset(this.getScrollOffset() + delta, {
708
- adjustments: void 0,
709
- behavior
710
- });
711
- };
712
- this.getTotalSize = () => {
713
- var _a;
714
- const measurements = this.getMeasurements();
715
- let end;
716
- if (measurements.length === 0) {
717
- end = this.options.paddingStart;
718
- } else if (this.options.lanes === 1) {
719
- end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;
720
- } else {
721
- const endByLane = Array(this.options.lanes).fill(null);
722
- let endIndex = measurements.length - 1;
723
- while (endIndex >= 0 && endByLane.some((val) => val === null)) {
724
- const item = measurements[endIndex];
725
- if (endByLane[item.lane] === null) {
726
- endByLane[item.lane] = item.end;
727
- }
728
- endIndex--;
729
- }
730
- end = Math.max(...endByLane.filter((val) => val !== null));
731
- }
732
- return Math.max(
733
- end - this.options.scrollMargin + this.options.paddingEnd,
734
- 0
735
- );
736
- };
737
- this._scrollToOffset = (offset, {
738
- adjustments,
739
- behavior
740
- }) => {
741
- this.options.scrollToFn(offset, { behavior, adjustments }, this);
742
- };
743
- this.measure = () => {
744
- this.itemSizeCache = /* @__PURE__ */ new Map();
745
- this.laneAssignments = /* @__PURE__ */ new Map();
746
- this.notify(false);
747
- };
748
- this.setOptions(opts);
749
- }
750
- }
751
- const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
752
- while (low <= high) {
753
- const middle = (low + high) / 2 | 0;
754
- const currentValue = getCurrentValue(middle);
755
- if (currentValue < value) {
756
- low = middle + 1;
757
- } else if (currentValue > value) {
758
- high = middle - 1;
759
- } else {
760
- return middle;
761
- }
762
- }
763
- if (low > 0) {
764
- return low - 1;
765
- } else {
766
- return 0;
767
- }
667
+ var findNearestBinarySearch = (low, high, getCurrentValue, value) => {
668
+ while (low <= high) {
669
+ const middle = (low + high) / 2 | 0;
670
+ const currentValue = getCurrentValue(middle);
671
+ if (currentValue < value) low = middle + 1;
672
+ else if (currentValue > value) high = middle - 1;
673
+ else return middle;
674
+ }
675
+ if (low > 0) return low - 1;
676
+ else return 0;
768
677
  };
769
- function calculateRange({
770
- measurements,
771
- outerSize,
772
- scrollOffset,
773
- lanes
774
- }) {
775
- const lastIndex = measurements.length - 1;
776
- const getOffset = (index) => measurements[index].start;
777
- if (measurements.length <= lanes) {
778
- return {
779
- startIndex: 0,
780
- endIndex: lastIndex
781
- };
782
- }
783
- let startIndex = findNearestBinarySearch(
784
- 0,
785
- lastIndex,
786
- getOffset,
787
- scrollOffset
788
- );
789
- let endIndex = startIndex;
790
- if (lanes === 1) {
791
- while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {
792
- endIndex++;
793
- }
794
- } else if (lanes > 1) {
795
- const endPerLane = Array(lanes).fill(0);
796
- while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {
797
- const item = measurements[endIndex];
798
- endPerLane[item.lane] = item.end;
799
- endIndex++;
800
- }
801
- const startPerLane = Array(lanes).fill(scrollOffset + outerSize);
802
- while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {
803
- const item = measurements[startIndex];
804
- startPerLane[item.lane] = item.start;
805
- startIndex--;
806
- }
807
- startIndex = Math.max(0, startIndex - startIndex % lanes);
808
- endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));
809
- }
810
- return { startIndex, endIndex };
678
+ function calculateRange({ measurements, outerSize, scrollOffset, lanes }) {
679
+ const lastIndex = measurements.length - 1;
680
+ const getOffset = (index) => measurements[index].start;
681
+ if (measurements.length <= lanes) return {
682
+ startIndex: 0,
683
+ endIndex: lastIndex
684
+ };
685
+ let startIndex = findNearestBinarySearch(0, lastIndex, getOffset, scrollOffset);
686
+ let endIndex = startIndex;
687
+ if (lanes === 1) while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) endIndex++;
688
+ else if (lanes > 1) {
689
+ const endPerLane = Array(lanes).fill(0);
690
+ while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {
691
+ const item = measurements[endIndex];
692
+ endPerLane[item.lane] = item.end;
693
+ endIndex++;
694
+ }
695
+ const startPerLane = Array(lanes).fill(scrollOffset + outerSize);
696
+ while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {
697
+ const item = measurements[startIndex];
698
+ startPerLane[item.lane] = item.start;
699
+ startIndex--;
700
+ }
701
+ startIndex = Math.max(0, startIndex - startIndex % lanes);
702
+ endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));
703
+ }
704
+ return {
705
+ startIndex,
706
+ endIndex
707
+ };
811
708
  }
812
-
813
- export { Virtualizer, approxEqual, debounce, defaultKeyExtractor, defaultRangeExtractor, elementScroll, measureElement, memo, notUndefined, observeElementOffset, observeElementRect };
709
+ //#endregion
710
+ export { Virtualizer, defaultKeyExtractor, defaultRangeExtractor, elementScroll, measureElement, observeElementOffset, observeElementRect };