domet 1.0.1 → 1.0.3

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