domet 1.0.0 → 1.0.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.
@@ -1,17 +1,24 @@
1
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
1
+ import { useMemo, useState, useRef, useCallback, useLayoutEffect, useEffect } from 'react';
2
+
2
3
  const DEFAULT_VISIBILITY_THRESHOLD = 0.6;
3
4
  const DEFAULT_HYSTERESIS_MARGIN = 150;
4
5
  const SCROLL_IDLE_MS = 100;
5
6
  const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
6
- export function useDomet(sectionIds, containerRef = null, options = {}) {
7
- const { offset = 0, offsetRatio = 0.08, debounceMs = 10, visibilityThreshold = DEFAULT_VISIBILITY_THRESHOLD, hysteresisMargin = DEFAULT_HYSTERESIS_MARGIN, behavior = "auto", onActiveChange, onSectionEnter, onSectionLeave, onScrollStart, onScrollEnd, } = options;
8
- const _sectionIdsKey = JSON.stringify(sectionIds);
9
- const stableSectionIds = useMemo(() => sectionIds, [sectionIds]);
10
- const sectionIndexMap = useMemo(() => {
7
+ function useDomet(sectionIds, containerRef = null, options = {}) {
8
+ const { offset = 0, offsetRatio = 0.08, debounceMs = 10, visibilityThreshold = DEFAULT_VISIBILITY_THRESHOLD, hysteresisMargin = DEFAULT_HYSTERESIS_MARGIN, behavior = "auto", onActiveChange, onSectionEnter, onSectionLeave, onScrollStart, onScrollEnd } = options;
9
+ JSON.stringify(sectionIds);
10
+ const stableSectionIds = useMemo(()=>sectionIds, [
11
+ sectionIds
12
+ ]);
13
+ const sectionIndexMap = useMemo(()=>{
11
14
  const map = new Map();
12
- stableSectionIds.forEach((id, i) => map.set(id, i));
15
+ for(let i = 0; i < stableSectionIds.length; i++){
16
+ map.set(stableSectionIds[i], i);
17
+ }
13
18
  return map;
14
- }, [stableSectionIds]);
19
+ }, [
20
+ stableSectionIds
21
+ ]);
15
22
  const [activeId, setActiveId] = useState(stableSectionIds[0] || null);
16
23
  const [scroll, setScroll] = useState({
17
24
  y: 0,
@@ -21,7 +28,7 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
21
28
  isScrolling: false,
22
29
  maxScroll: 0,
23
30
  viewportHeight: 0,
24
- offset: 0,
31
+ offset: 0
25
32
  });
26
33
  const [sections, setSections] = useState({});
27
34
  const [containerElement, setContainerElement] = useState(null);
@@ -39,56 +46,61 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
39
46
  const isScrollingRef = useRef(false);
40
47
  const scrollIdleTimeoutRef = useRef(null);
41
48
  const prevSectionsInViewport = useRef(new Set());
42
- const recalculateRef = useRef(() => { });
49
+ const recalculateRef = useRef(()=>{});
43
50
  const scrollCleanupRef = useRef(null);
44
51
  const callbackRefs = useRef({
45
52
  onActiveChange,
46
53
  onSectionEnter,
47
54
  onSectionLeave,
48
55
  onScrollStart,
49
- onScrollEnd,
56
+ onScrollEnd
50
57
  });
51
58
  callbackRefs.current = {
52
59
  onActiveChange,
53
60
  onSectionEnter,
54
61
  onSectionLeave,
55
62
  onScrollStart,
56
- onScrollEnd,
63
+ onScrollEnd
57
64
  };
58
- const getEffectiveOffset = useCallback(() => {
65
+ const getEffectiveOffset = useCallback(()=>{
59
66
  return offset;
60
- }, [offset]);
61
- const getScrollBehavior = useCallback(() => {
67
+ }, [
68
+ offset
69
+ ]);
70
+ const getScrollBehavior = useCallback(()=>{
62
71
  if (behavior === "auto") {
63
- if (typeof window === "undefined")
64
- return "instant";
72
+ if (typeof window === "undefined") return "instant";
65
73
  const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
66
74
  return prefersReducedMotion ? "instant" : "smooth";
67
75
  }
68
76
  return behavior;
69
- }, [behavior]);
70
- useIsomorphicLayoutEffect(() => {
71
- const nextContainer = containerRef?.current ?? null;
77
+ }, [
78
+ behavior
79
+ ]);
80
+ useIsomorphicLayoutEffect(()=>{
81
+ var _ref;
82
+ const nextContainer = (_ref = containerRef == null ? void 0 : containerRef.current) != null ? _ref : null;
72
83
  if (nextContainer !== containerElement) {
73
84
  setContainerElement(nextContainer);
74
85
  }
75
- }, [containerRef, containerElement]);
76
- const registerRef = useCallback((id) => {
86
+ }, [
87
+ containerRef,
88
+ containerElement
89
+ ]);
90
+ const registerRef = useCallback((id)=>{
77
91
  const existing = refCallbacks.current[id];
78
- if (existing)
79
- return existing;
80
- const callback = (el) => {
92
+ if (existing) return existing;
93
+ const callback = (el)=>{
81
94
  if (el) {
82
95
  refs.current[id] = el;
83
- }
84
- else {
96
+ } else {
85
97
  delete refs.current[id];
86
98
  }
87
99
  };
88
100
  refCallbacks.current[id] = callback;
89
101
  return callback;
90
102
  }, []);
91
- const scrollToSection = useCallback((id) => {
103
+ const scrollToSection = useCallback((id)=>{
92
104
  if (!stableSectionIds.includes(id)) {
93
105
  if (process.env.NODE_ENV !== "production") {
94
106
  console.warn(`[domet] scrollToSection: id "${id}" not in sectionIds`);
@@ -96,12 +108,11 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
96
108
  return;
97
109
  }
98
110
  const element = refs.current[id];
99
- if (!element)
100
- return;
111
+ if (!element) return;
101
112
  if (programmaticScrollTimeoutId.current) {
102
113
  clearTimeout(programmaticScrollTimeoutId.current);
103
114
  }
104
- scrollCleanupRef.current?.();
115
+ scrollCleanupRef.current == null ? void 0 : scrollCleanupRef.current.call(scrollCleanupRef);
105
116
  isProgrammaticScrolling.current = true;
106
117
  activeIdRef.current = id;
107
118
  setActiveId(id);
@@ -109,19 +120,19 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
109
120
  const elementRect = element.getBoundingClientRect();
110
121
  const effectiveOffset = getEffectiveOffset() + 10;
111
122
  const scrollTarget = container || window;
112
- const unlockScroll = () => {
123
+ const unlockScroll = ()=>{
113
124
  isProgrammaticScrolling.current = false;
114
125
  if (programmaticScrollTimeoutId.current) {
115
126
  clearTimeout(programmaticScrollTimeoutId.current);
116
127
  programmaticScrollTimeoutId.current = null;
117
128
  }
118
- requestAnimationFrame(() => {
129
+ requestAnimationFrame(()=>{
119
130
  recalculateRef.current();
120
131
  });
121
132
  };
122
133
  let debounceTimer = null;
123
134
  let isUnlocked = false;
124
- const cleanup = () => {
135
+ const cleanup = ()=>{
125
136
  if (debounceTimer) {
126
137
  clearTimeout(debounceTimer);
127
138
  debounceTimer = null;
@@ -132,31 +143,30 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
132
143
  }
133
144
  scrollCleanupRef.current = null;
134
145
  };
135
- const doUnlock = () => {
136
- if (isUnlocked)
137
- return;
146
+ const doUnlock = ()=>{
147
+ if (isUnlocked) return;
138
148
  isUnlocked = true;
139
149
  cleanup();
140
150
  unlockScroll();
141
151
  };
142
- const resetDebounce = () => {
152
+ const resetDebounce = ()=>{
143
153
  if (debounceTimer) {
144
154
  clearTimeout(debounceTimer);
145
155
  }
146
156
  debounceTimer = setTimeout(doUnlock, SCROLL_IDLE_MS);
147
157
  };
148
- const handleScrollActivity = () => {
158
+ const handleScrollActivity = ()=>{
149
159
  resetDebounce();
150
160
  };
151
- const handleScrollEnd = () => {
161
+ const handleScrollEnd = ()=>{
152
162
  doUnlock();
153
163
  };
154
164
  scrollTarget.addEventListener("scroll", handleScrollActivity, {
155
- passive: true,
165
+ passive: true
156
166
  });
157
167
  if ("onscrollend" in scrollTarget) {
158
168
  scrollTarget.addEventListener("scrollend", handleScrollEnd, {
159
- once: true,
169
+ once: true
160
170
  });
161
171
  }
162
172
  scrollCleanupRef.current = cleanup;
@@ -166,121 +176,117 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
166
176
  const relativeTop = elementRect.top - containerRect.top + container.scrollTop;
167
177
  container.scrollTo({
168
178
  top: relativeTop - effectiveOffset,
169
- behavior: scrollBehavior,
179
+ behavior: scrollBehavior
170
180
  });
171
- }
172
- else {
181
+ } else {
173
182
  const absoluteTop = elementRect.top + window.scrollY;
174
183
  window.scrollTo({
175
184
  top: absoluteTop - effectiveOffset,
176
- behavior: scrollBehavior,
185
+ behavior: scrollBehavior
177
186
  });
178
187
  }
179
188
  if (scrollBehavior === "instant") {
180
189
  doUnlock();
181
- }
182
- else {
190
+ } else {
183
191
  resetDebounce();
184
192
  }
185
- }, [stableSectionIds, containerElement, getEffectiveOffset, getScrollBehavior]);
186
- const sectionProps = useCallback((id) => ({
187
- id,
188
- ref: registerRef(id),
189
- "data-domet": id,
190
- }), [registerRef]);
191
- const navProps = useCallback((id) => ({
192
- onClick: () => scrollToSection(id),
193
- "aria-current": activeId === id ? "page" : undefined,
194
- "data-active": activeId === id,
195
- }), [activeId, scrollToSection]);
196
- useEffect(() => {
193
+ }, [
194
+ stableSectionIds,
195
+ containerElement,
196
+ getEffectiveOffset,
197
+ getScrollBehavior
198
+ ]);
199
+ const sectionProps = useCallback((id)=>({
200
+ id,
201
+ ref: registerRef(id),
202
+ "data-domet": id
203
+ }), [
204
+ registerRef
205
+ ]);
206
+ const navProps = useCallback((id)=>({
207
+ onClick: ()=>scrollToSection(id),
208
+ "aria-current": activeId === id ? "page" : undefined,
209
+ "data-active": activeId === id
210
+ }), [
211
+ activeId,
212
+ scrollToSection
213
+ ]);
214
+ useEffect(()=>{
215
+ var _stableSectionIds_;
197
216
  const idsSet = new Set(stableSectionIds);
198
- for (const id of Object.keys(refs.current)) {
217
+ for (const id of Object.keys(refs.current)){
199
218
  if (!idsSet.has(id)) {
200
219
  delete refs.current[id];
201
220
  }
202
221
  }
203
- for (const id of Object.keys(refCallbacks.current)) {
222
+ for (const id of Object.keys(refCallbacks.current)){
204
223
  if (!idsSet.has(id)) {
205
224
  delete refCallbacks.current[id];
206
225
  }
207
226
  }
208
227
  const currentActive = activeIdRef.current;
209
- const nextActive = currentActive && idsSet.has(currentActive)
210
- ? currentActive
211
- : (stableSectionIds[0] ?? null);
228
+ const nextActive = currentActive && idsSet.has(currentActive) ? currentActive : (_stableSectionIds_ = stableSectionIds[0]) != null ? _stableSectionIds_ : null;
212
229
  if (nextActive !== currentActive) {
213
230
  activeIdRef.current = nextActive;
214
231
  }
215
- setActiveId((prev) => (prev !== nextActive ? nextActive : prev));
216
- }, [stableSectionIds]);
217
- const getSectionBounds = useCallback(() => {
232
+ setActiveId((prev)=>prev !== nextActive ? nextActive : prev);
233
+ }, [
234
+ stableSectionIds
235
+ ]);
236
+ const getSectionBounds = useCallback(()=>{
218
237
  const container = containerElement;
219
238
  const scrollTop = container ? container.scrollTop : window.scrollY;
220
239
  const containerTop = container ? container.getBoundingClientRect().top : 0;
221
- return stableSectionIds
222
- .map((id) => {
240
+ return stableSectionIds.map((id)=>{
223
241
  const el = refs.current[id];
224
- if (!el)
225
- return null;
242
+ if (!el) return null;
226
243
  const rect = el.getBoundingClientRect();
227
- const relativeTop = container
228
- ? rect.top - containerTop + scrollTop
229
- : rect.top + window.scrollY;
244
+ const relativeTop = container ? rect.top - containerTop + scrollTop : rect.top + window.scrollY;
230
245
  return {
231
246
  id,
232
247
  top: relativeTop,
233
248
  bottom: relativeTop + rect.height,
234
- height: rect.height,
249
+ height: rect.height
235
250
  };
236
- })
237
- .filter((bounds) => bounds !== null);
238
- }, [stableSectionIds, containerElement]);
239
- const calculateActiveSection = useCallback(() => {
240
- if (isProgrammaticScrolling.current)
241
- return;
251
+ }).filter((bounds)=>bounds !== null);
252
+ }, [
253
+ stableSectionIds,
254
+ containerElement
255
+ ]);
256
+ const calculateActiveSection = useCallback(()=>{
257
+ if (isProgrammaticScrolling.current) return;
242
258
  const container = containerElement;
243
259
  const currentActiveId = activeIdRef.current;
244
260
  const now = Date.now();
245
261
  const scrollY = container ? container.scrollTop : window.scrollY;
246
- const viewportHeight = container
247
- ? container.clientHeight
248
- : window.innerHeight;
249
- const scrollHeight = container
250
- ? container.scrollHeight
251
- : document.documentElement.scrollHeight;
262
+ const viewportHeight = container ? container.clientHeight : window.innerHeight;
263
+ const scrollHeight = container ? container.scrollHeight : document.documentElement.scrollHeight;
252
264
  const maxScroll = Math.max(0, scrollHeight - viewportHeight);
253
265
  const scrollProgress = maxScroll > 0 ? scrollY / maxScroll : 0;
254
- const scrollDirection = scrollY === lastScrollY.current
255
- ? null
256
- : scrollY > lastScrollY.current
257
- ? "down"
258
- : "up";
266
+ const scrollDirection = scrollY === lastScrollY.current ? null : scrollY > lastScrollY.current ? "down" : "up";
259
267
  const deltaTime = now - lastScrollTime.current;
260
268
  const deltaY = scrollY - lastScrollY.current;
261
269
  const velocity = deltaTime > 0 ? Math.abs(deltaY) / deltaTime : 0;
262
270
  lastScrollY.current = scrollY;
263
271
  lastScrollTime.current = now;
264
272
  const sectionBounds = getSectionBounds();
265
- if (sectionBounds.length === 0)
266
- return;
273
+ if (sectionBounds.length === 0) return;
267
274
  const baseOffset = getEffectiveOffset();
268
275
  const effectiveOffset = Math.max(baseOffset, viewportHeight * offsetRatio);
269
276
  const triggerLine = scrollY + effectiveOffset;
270
277
  const viewportTop = scrollY;
271
278
  const viewportBottom = scrollY + viewportHeight;
272
- const scores = sectionBounds.map((section) => {
279
+ const scores = sectionBounds.map((section)=>{
280
+ var _sectionIndexMap_get;
273
281
  const visibleTop = Math.max(section.top, viewportTop);
274
282
  const visibleBottom = Math.min(section.bottom, viewportBottom);
275
283
  const visibleHeight = Math.max(0, visibleBottom - visibleTop);
276
284
  const visibilityRatio = section.height > 0 ? visibleHeight / section.height : 0;
277
285
  const visibleInViewportRatio = viewportHeight > 0 ? visibleHeight / viewportHeight : 0;
278
286
  const isInViewport = section.bottom > viewportTop && section.top < viewportBottom;
279
- const sectionProgress = (() => {
280
- if (section.height === 0)
281
- return 0;
287
+ const sectionProgress = (()=>{
288
+ if (section.height === 0) return 0;
282
289
  const entryPoint = viewportBottom;
283
- const _exitPoint = viewportTop;
284
290
  const totalTravel = viewportHeight + section.height;
285
291
  const traveled = entryPoint - section.top;
286
292
  return Math.max(0, Math.min(1, traveled / totalTravel));
@@ -288,15 +294,11 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
288
294
  let score = 0;
289
295
  if (visibilityRatio >= visibilityThreshold) {
290
296
  score += 1000 + visibilityRatio * 500;
291
- }
292
- else if (isInViewport) {
297
+ } else if (isInViewport) {
293
298
  score += visibleInViewportRatio * 800;
294
299
  }
295
- const sectionIndex = sectionIndexMap.get(section.id) ?? 0;
296
- if (scrollDirection &&
297
- isInViewport &&
298
- section.top <= triggerLine &&
299
- section.bottom > triggerLine) {
300
+ const sectionIndex = (_sectionIndexMap_get = sectionIndexMap.get(section.id)) != null ? _sectionIndexMap_get : 0;
301
+ if (scrollDirection && isInViewport && section.top <= triggerLine && section.bottom > triggerLine) {
300
302
  score += 200;
301
303
  }
302
304
  score -= sectionIndex * 0.1;
@@ -306,47 +308,43 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
306
308
  visibilityRatio,
307
309
  isInViewport,
308
310
  bounds: section,
309
- progress: sectionProgress,
311
+ progress: sectionProgress
310
312
  };
311
313
  });
312
- const isAtBottom = scrollY + viewportHeight >= scrollHeight - 5;
313
- const isAtTop = scrollY <= 5;
314
+ const hasScroll = maxScroll > 10;
315
+ const isAtBottom = hasScroll && scrollY + viewportHeight >= scrollHeight - 5;
316
+ const isAtTop = hasScroll && scrollY <= 5;
314
317
  let newActiveId = null;
315
318
  if (isAtBottom && stableSectionIds.length > 0) {
316
319
  newActiveId = stableSectionIds[stableSectionIds.length - 1];
317
- }
318
- else if (isAtTop && stableSectionIds.length > 0) {
320
+ } else if (isAtTop && stableSectionIds.length > 0) {
319
321
  newActiveId = stableSectionIds[0];
320
- }
321
- else {
322
- const visibleScores = scores.filter((s) => s.isInViewport);
322
+ } else {
323
+ const visibleScores = scores.filter((s)=>s.isInViewport);
323
324
  const candidates = visibleScores.length > 0 ? visibleScores : scores;
324
- candidates.sort((a, b) => b.score - a.score);
325
+ candidates.sort((a, b)=>b.score - a.score);
325
326
  if (candidates.length > 0) {
326
327
  const bestCandidate = candidates[0];
327
- const currentScore = scores.find((s) => s.id === currentActiveId);
328
- const shouldSwitch = !currentScore ||
329
- !currentScore.isInViewport ||
330
- bestCandidate.score > currentScore.score + hysteresisMargin ||
331
- bestCandidate.id === currentActiveId;
328
+ const currentScore = scores.find((s)=>s.id === currentActiveId);
329
+ const shouldSwitch = !currentScore || !currentScore.isInViewport || bestCandidate.score > currentScore.score + hysteresisMargin || bestCandidate.id === currentActiveId;
332
330
  newActiveId = shouldSwitch ? bestCandidate.id : currentActiveId;
333
331
  }
334
332
  }
335
333
  if (newActiveId !== currentActiveId) {
336
334
  activeIdRef.current = newActiveId;
337
335
  setActiveId(newActiveId);
338
- callbackRefs.current.onActiveChange?.(newActiveId, currentActiveId);
336
+ callbackRefs.current.onActiveChange == null ? void 0 : callbackRefs.current.onActiveChange.call(callbackRefs.current, newActiveId, currentActiveId);
339
337
  }
340
- const currentInViewport = new Set(scores.filter((s) => s.isInViewport).map((s) => s.id));
338
+ const currentInViewport = new Set(scores.filter((s)=>s.isInViewport).map((s)=>s.id));
341
339
  const prevInViewport = prevSectionsInViewport.current;
342
- for (const id of currentInViewport) {
340
+ for (const id of currentInViewport){
343
341
  if (!prevInViewport.has(id)) {
344
- callbackRefs.current.onSectionEnter?.(id);
342
+ callbackRefs.current.onSectionEnter == null ? void 0 : callbackRefs.current.onSectionEnter.call(callbackRefs.current, id);
345
343
  }
346
344
  }
347
- for (const id of prevInViewport) {
345
+ for (const id of prevInViewport){
348
346
  if (!currentInViewport.has(id)) {
349
- callbackRefs.current.onSectionLeave?.(id);
347
+ callbackRefs.current.onSectionLeave == null ? void 0 : callbackRefs.current.onSectionLeave.call(callbackRefs.current, id);
350
348
  }
351
349
  }
352
350
  prevSectionsInViewport.current = currentInViewport;
@@ -358,20 +356,20 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
358
356
  isScrolling: isScrollingRef.current,
359
357
  maxScroll,
360
358
  viewportHeight,
361
- offset: effectiveOffset,
359
+ offset: effectiveOffset
362
360
  };
363
361
  const newSections = {};
364
- for (const s of scores) {
362
+ for (const s of scores){
365
363
  newSections[s.id] = {
366
364
  bounds: {
367
365
  top: s.bounds.top,
368
366
  bottom: s.bounds.bottom,
369
- height: s.bounds.height,
367
+ height: s.bounds.height
370
368
  },
371
369
  visibility: Math.round(s.visibilityRatio * 100) / 100,
372
370
  progress: Math.round(s.progress * 100) / 100,
373
371
  isInViewport: s.isInViewport,
374
- isActive: s.id === newActiveId,
372
+ isActive: s.id === newActiveId
375
373
  };
376
374
  }
377
375
  setScroll(newScrollState);
@@ -384,31 +382,37 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
384
382
  visibilityThreshold,
385
383
  hysteresisMargin,
386
384
  getSectionBounds,
387
- containerElement,
385
+ containerElement
388
386
  ]);
389
387
  recalculateRef.current = calculateActiveSection;
390
- useEffect(() => {
388
+ useEffect(()=>{
391
389
  const container = containerElement;
392
390
  const scrollTarget = container || window;
393
- const scheduleCalculate = () => {
391
+ const scheduleCalculate = ()=>{
394
392
  if (rafId.current) {
395
393
  cancelAnimationFrame(rafId.current);
396
394
  }
397
- rafId.current = requestAnimationFrame(() => {
395
+ rafId.current = requestAnimationFrame(()=>{
398
396
  rafId.current = null;
399
397
  calculateActiveSection();
400
398
  });
401
399
  };
402
- const handleScrollEnd = () => {
400
+ const handleScrollEnd = ()=>{
403
401
  isScrollingRef.current = false;
404
- setScroll((prev) => ({ ...prev, isScrolling: false }));
405
- callbackRefs.current.onScrollEnd?.();
402
+ setScroll((prev)=>({
403
+ ...prev,
404
+ isScrolling: false
405
+ }));
406
+ callbackRefs.current.onScrollEnd == null ? void 0 : callbackRefs.current.onScrollEnd.call(callbackRefs.current);
406
407
  };
407
- const handleScroll = () => {
408
+ const handleScroll = ()=>{
408
409
  if (!isScrollingRef.current) {
409
410
  isScrollingRef.current = true;
410
- setScroll((prev) => ({ ...prev, isScrolling: true }));
411
- callbackRefs.current.onScrollStart?.();
411
+ setScroll((prev)=>({
412
+ ...prev,
413
+ isScrolling: true
414
+ }));
415
+ callbackRefs.current.onScrollStart == null ? void 0 : callbackRefs.current.onScrollStart.call(callbackRefs.current);
412
416
  }
413
417
  if (scrollIdleTimeoutRef.current) {
414
418
  clearTimeout(scrollIdleTimeoutRef.current);
@@ -424,7 +428,7 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
424
428
  clearTimeout(throttleTimeoutId.current);
425
429
  }
426
430
  scheduleCalculate();
427
- throttleTimeoutId.current = setTimeout(() => {
431
+ throttleTimeoutId.current = setTimeout(()=>{
428
432
  isThrottled.current = false;
429
433
  throttleTimeoutId.current = null;
430
434
  if (hasPendingScroll.current) {
@@ -433,16 +437,20 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
433
437
  }
434
438
  }, debounceMs);
435
439
  };
436
- const handleResize = () => {
440
+ const handleResize = ()=>{
437
441
  scheduleCalculate();
438
442
  };
439
443
  calculateActiveSection();
440
- const deferredRecalcId = setTimeout(() => {
444
+ const deferredRecalcId = setTimeout(()=>{
441
445
  calculateActiveSection();
442
446
  }, 0);
443
- scrollTarget.addEventListener("scroll", handleScroll, { passive: true });
444
- window.addEventListener("resize", handleResize, { passive: true });
445
- return () => {
447
+ scrollTarget.addEventListener("scroll", handleScroll, {
448
+ passive: true
449
+ });
450
+ window.addEventListener("resize", handleResize, {
451
+ passive: true
452
+ });
453
+ return ()=>{
446
454
  clearTimeout(deferredRecalcId);
447
455
  scrollTarget.removeEventListener("scroll", handleScroll);
448
456
  window.removeEventListener("resize", handleResize);
@@ -462,18 +470,25 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
462
470
  clearTimeout(scrollIdleTimeoutRef.current);
463
471
  scrollIdleTimeoutRef.current = null;
464
472
  }
465
- scrollCleanupRef.current?.();
473
+ scrollCleanupRef.current == null ? void 0 : scrollCleanupRef.current.call(scrollCleanupRef);
466
474
  isThrottled.current = false;
467
475
  hasPendingScroll.current = false;
468
476
  isProgrammaticScrolling.current = false;
469
477
  isScrollingRef.current = false;
470
478
  };
471
- }, [calculateActiveSection, debounceMs, containerElement]);
472
- const activeIndex = useMemo(() => {
473
- if (!activeId)
474
- return -1;
475
- return sectionIndexMap.get(activeId) ?? -1;
476
- }, [activeId, sectionIndexMap]);
479
+ }, [
480
+ calculateActiveSection,
481
+ debounceMs,
482
+ containerElement
483
+ ]);
484
+ const activeIndex = useMemo(()=>{
485
+ var _sectionIndexMap_get;
486
+ if (!activeId) return -1;
487
+ return (_sectionIndexMap_get = sectionIndexMap.get(activeId)) != null ? _sectionIndexMap_get : -1;
488
+ }, [
489
+ activeId,
490
+ sectionIndexMap
491
+ ]);
477
492
  return {
478
493
  activeId,
479
494
  activeIndex,
@@ -482,7 +497,8 @@ export function useDomet(sectionIds, containerRef = null, options = {}) {
482
497
  registerRef,
483
498
  scrollToSection,
484
499
  sectionProps,
485
- navProps,
500
+ navProps
486
501
  };
487
502
  }
488
- export default useDomet;
503
+
504
+ export { useDomet as default, useDomet };
@@ -1,10 +1,11 @@
1
- import type { RefObject } from "react";
2
- export type SectionBounds = {
1
+ import { RefObject } from 'react';
2
+
3
+ type SectionBounds = {
3
4
  top: number;
4
5
  bottom: number;
5
6
  height: number;
6
7
  };
7
- export type ScrollState = {
8
+ type ScrollState = {
8
9
  y: number;
9
10
  progress: number;
10
11
  direction: "up" | "down" | null;
@@ -14,15 +15,15 @@ export type ScrollState = {
14
15
  viewportHeight: number;
15
16
  offset: number;
16
17
  };
17
- export type SectionState = {
18
+ type SectionState = {
18
19
  bounds: SectionBounds;
19
20
  visibility: number;
20
21
  progress: number;
21
22
  isInViewport: boolean;
22
23
  isActive: boolean;
23
24
  };
24
- export type ScrollBehavior = "smooth" | "instant" | "auto";
25
- export type DometOptions = {
25
+ type ScrollBehavior = "smooth" | "instant" | "auto";
26
+ type DometOptions = {
26
27
  offset?: number;
27
28
  offsetRatio?: number;
28
29
  debounceMs?: number;
@@ -35,17 +36,17 @@ export type DometOptions = {
35
36
  onScrollStart?: () => void;
36
37
  onScrollEnd?: () => void;
37
38
  };
38
- export type SectionProps = {
39
+ type SectionProps = {
39
40
  id: string;
40
41
  ref: (el: HTMLElement | null) => void;
41
42
  "data-domet": string;
42
43
  };
43
- export type NavProps = {
44
+ type NavProps = {
44
45
  onClick: () => void;
45
46
  "aria-current": "page" | undefined;
46
47
  "data-active": boolean;
47
48
  };
48
- export type UseDometReturn = {
49
+ type UseDometReturn = {
49
50
  activeId: string | null;
50
51
  activeIndex: number;
51
52
  scroll: ScrollState;
@@ -55,6 +56,7 @@ export type UseDometReturn = {
55
56
  sectionProps: (id: string) => SectionProps;
56
57
  navProps: (id: string) => NavProps;
57
58
  };
58
- export declare function useDomet(sectionIds: string[], containerRef?: RefObject<HTMLElement> | null, options?: DometOptions): UseDometReturn;
59
- export default useDomet;
60
- //# sourceMappingURL=useScrowl.d.ts.map
59
+ declare function useDomet(sectionIds: string[], containerRef?: RefObject<HTMLElement> | null, options?: DometOptions): UseDometReturn;
60
+
61
+ export { useDomet as default, useDomet };
62
+ export type { DometOptions, NavProps, ScrollBehavior, ScrollState, SectionBounds, SectionProps, SectionState, UseDometReturn };