@codesinger0/shared-components 1.1.12 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -1
- package/dist/utils/ScrollManager.jsx +85 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29,4 +29,5 @@ export { CartProvider, useCart } from './context/CartContext'
|
|
|
29
29
|
export { default as useScrollLock } from './hooks/useScrollLock'
|
|
30
30
|
|
|
31
31
|
// Utils
|
|
32
|
-
export { default as ScrollToTop } from './utils/ScrollToTop'
|
|
32
|
+
export { default as ScrollToTop } from './utils/ScrollToTop'
|
|
33
|
+
export { useScrollToAnchor } from './utils/ScrollManager'
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook for smooth scrolling to anchors
|
|
5
|
+
* @param {Object} options - Configuration options
|
|
6
|
+
* @param {string} options.behavior - Scroll behavior ('smooth', 'instant', 'auto')
|
|
7
|
+
* @param {string} options.block - Vertical alignment ('start', 'center', 'end', 'nearest')
|
|
8
|
+
* @param {number} options.offset - Additional offset in pixels (useful for fixed headers)
|
|
9
|
+
* @returns {Function} scrollToAnchor function
|
|
10
|
+
*/
|
|
11
|
+
export const useScrollToAnchor = (options = {}) => {
|
|
12
|
+
const {
|
|
13
|
+
behavior = 'smooth',
|
|
14
|
+
block = 'start',
|
|
15
|
+
offset = 0
|
|
16
|
+
} = options;
|
|
17
|
+
|
|
18
|
+
const scrollToAnchor = useCallback((anchorId) => {
|
|
19
|
+
// Remove # if provided
|
|
20
|
+
const cleanAnchorId = anchorId.replace('#', '');
|
|
21
|
+
|
|
22
|
+
// Find the element
|
|
23
|
+
const element = document.getElementById(cleanAnchorId);
|
|
24
|
+
|
|
25
|
+
if (!element) {
|
|
26
|
+
console.warn(`Element with id "${cleanAnchorId}" not found`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// If offset is needed, calculate position manually
|
|
31
|
+
if (offset !== 0) {
|
|
32
|
+
const elementPosition = element.getBoundingClientRect().top;
|
|
33
|
+
const offsetPosition = elementPosition + window.pageYOffset - offset;
|
|
34
|
+
|
|
35
|
+
window.scrollTo({
|
|
36
|
+
top: offsetPosition,
|
|
37
|
+
behavior: behavior
|
|
38
|
+
});
|
|
39
|
+
} else {
|
|
40
|
+
// Use native scrollIntoView
|
|
41
|
+
element.scrollIntoView({
|
|
42
|
+
behavior: behavior,
|
|
43
|
+
block: block,
|
|
44
|
+
inline: 'nearest'
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}, [behavior, block, offset]);
|
|
48
|
+
|
|
49
|
+
return scrollToAnchor;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Alternative hook that also handles URL hash updates
|
|
53
|
+
export const useScrollToAnchorWithHash = (options = {}) => {
|
|
54
|
+
const scrollToAnchor = useScrollToAnchor(options);
|
|
55
|
+
|
|
56
|
+
const scrollToAnchorWithHash = useCallback((anchorId) => {
|
|
57
|
+
const cleanAnchorId = anchorId.replace('#', '');
|
|
58
|
+
|
|
59
|
+
// Update URL hash without triggering page reload
|
|
60
|
+
history.pushState(null, null, `#${cleanAnchorId}`);
|
|
61
|
+
|
|
62
|
+
// Scroll to the element
|
|
63
|
+
scrollToAnchor(cleanAnchorId);
|
|
64
|
+
}, [scrollToAnchor]);
|
|
65
|
+
|
|
66
|
+
return scrollToAnchorWithHash;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Hook that automatically scrolls to hash on page load
|
|
70
|
+
export const useScrollToHashOnLoad = (options = {}) => {
|
|
71
|
+
const scrollToAnchor = useScrollToAnchor(options);
|
|
72
|
+
|
|
73
|
+
React.useEffect(() => {
|
|
74
|
+
// Check if there's a hash in the URL when component mounts
|
|
75
|
+
const hash = window.location.hash;
|
|
76
|
+
if (hash) {
|
|
77
|
+
// Small delay to ensure page is fully loaded
|
|
78
|
+
setTimeout(() => {
|
|
79
|
+
scrollToAnchor(hash);
|
|
80
|
+
}, 100);
|
|
81
|
+
}
|
|
82
|
+
}, [scrollToAnchor]);
|
|
83
|
+
|
|
84
|
+
return scrollToAnchor;
|
|
85
|
+
};
|