@san-siva/blogkit 1.1.15 → 1.1.17
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/cjs/dynamicComponents/BlogDynamic.js +35 -5
- package/dist/cjs/dynamicComponents/BlogDynamic.js.map +1 -1
- package/dist/cjs/dynamicComponents/BlogSectionDynamic.js +1 -1
- package/dist/cjs/dynamicComponents/BlogSectionDynamic.js.map +1 -1
- package/dist/cjs/dynamicComponents/lockScrollUpdates.js +24 -0
- package/dist/cjs/dynamicComponents/lockScrollUpdates.js.map +1 -0
- package/dist/cjs/index.css +1 -1
- package/dist/cjs/index.css.map +1 -1
- package/dist/cjs/styles/BlogSection.module.scss.js +1 -1
- package/dist/cjs/utils/index.js +2 -0
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/lockScrollUpdates.js +24 -0
- package/dist/cjs/utils/lockScrollUpdates.js.map +1 -0
- package/dist/esm/dynamicComponents/BlogDynamic.js +35 -5
- package/dist/esm/dynamicComponents/BlogDynamic.js.map +1 -1
- package/dist/esm/dynamicComponents/BlogSectionDynamic.js +2 -2
- package/dist/esm/dynamicComponents/BlogSectionDynamic.js.map +1 -1
- package/dist/esm/dynamicComponents/lockScrollUpdates.js +20 -0
- package/dist/esm/dynamicComponents/lockScrollUpdates.js.map +1 -0
- package/dist/esm/index.css +1 -1
- package/dist/esm/index.css.map +1 -1
- package/dist/esm/styles/BlogSection.module.scss.js +1 -1
- package/dist/esm/utils/index.js +2 -1
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/lockScrollUpdates.js +20 -0
- package/dist/esm/utils/lockScrollUpdates.js.map +1 -0
- package/dist/types/dynamicComponents/BlogDynamic.d.ts +1 -1
- package/dist/types/dynamicComponents/BlogDynamic.d.ts.map +1 -1
- package/dist/types/dynamicComponents/lockScrollUpdates.d.ts +4 -0
- package/dist/types/dynamicComponents/lockScrollUpdates.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/dynamicComponents/BlogDynamic.tsx +38 -5
- package/src/dynamicComponents/BlogSectionDynamic.tsx +6 -2
- package/src/styles/BlogSection.module.scss +16 -2
- package/src/utils/index.ts +2 -0
- package/src/utils/lockScrollUpdates.ts +29 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var styles = {"margin-bottom--6":"BlogSection-module_margin-bottom--6__-hlAO","margin-bottom--9":"BlogSection-module_margin-bottom--9__xU5rE","blog-section__title":"BlogSection-module_blog-section__title__5-4Oy","blog-section":"BlogSection-module_blog-section__NTDM4"};
|
|
1
|
+
var styles = {"margin-bottom--6":"BlogSection-module_margin-bottom--6__-hlAO","margin-bottom--9":"BlogSection-module_margin-bottom--9__xU5rE","blog-section__title":"BlogSection-module_blog-section__title__5-4Oy","blog-section__title-link":"BlogSection-module_blog-section__title-link__Q4R5T","blog-section":"BlogSection-module_blog-section__NTDM4"};
|
|
2
2
|
|
|
3
3
|
export { styles as default };
|
|
4
4
|
//# sourceMappingURL=BlogSection.module.scss.js.map
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const generateIdForBlogTitle = (title) => title.toLowerCase().replace(/[^\w\d]/g, '-');
|
|
2
2
|
const generateUrlForBlogTitle = (title) => encodeURIComponent(title.replace(/[^\w]+/g, '-').toLowerCase());
|
|
3
|
+
const generateSectionHref = (id) => `?section=${id}`;
|
|
3
4
|
|
|
4
|
-
export { generateIdForBlogTitle, generateUrlForBlogTitle };
|
|
5
|
+
export { generateIdForBlogTitle, generateSectionHref, generateUrlForBlogTitle };
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/utils/index.ts"],"sourcesContent":["export const generateIdForBlogTitle = (title: string) => title.toLowerCase().replace(/[^\\w\\d]/g, '-');\n\nexport const generateUrlForBlogTitle = (title: string) => encodeURIComponent(title.replace(/[^\\w]+/g, '-').toLowerCase());\n"],"names":[],"mappings":"MAAa,sBAAsB,GAAG,CAAC,KAAa,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG;MAEvF,uBAAuB,GAAG,CAAC,KAAa,KAAK,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;;;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/utils/index.ts"],"sourcesContent":["export const generateIdForBlogTitle = (title: string) => title.toLowerCase().replace(/[^\\w\\d]/g, '-');\n\nexport const generateUrlForBlogTitle = (title: string) => encodeURIComponent(title.replace(/[^\\w]+/g, '-').toLowerCase());\n\nexport const generateSectionHref = (id: string) => `?section=${id}`;\n"],"names":[],"mappings":"MAAa,sBAAsB,GAAG,CAAC,KAAa,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG;MAEvF,uBAAuB,GAAG,CAAC,KAAa,KAAK,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;AAEjH,MAAM,mBAAmB,GAAG,CAAC,EAAU,KAAK,CAAA,SAAA,EAAY,EAAE,CAAA;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const lockScrollUpdates = (id, isClickScrolling, scrollEndHandlerRef, setVisibleTitle) => {
|
|
2
|
+
if (scrollEndHandlerRef.current) {
|
|
3
|
+
document.body.removeEventListener('scrollend', scrollEndHandlerRef.current);
|
|
4
|
+
}
|
|
5
|
+
isClickScrolling.current = true;
|
|
6
|
+
scrollEndHandlerRef.current = () => {
|
|
7
|
+
isClickScrolling.current = false;
|
|
8
|
+
scrollEndHandlerRef.current = null;
|
|
9
|
+
setVisibleTitle(id);
|
|
10
|
+
const url = new URL(window.location.href);
|
|
11
|
+
url.searchParams.set('section', id);
|
|
12
|
+
window.history.replaceState({}, '', url.toString());
|
|
13
|
+
};
|
|
14
|
+
document.body.addEventListener('scrollend', scrollEndHandlerRef.current, {
|
|
15
|
+
once: true,
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { lockScrollUpdates as default };
|
|
20
|
+
//# sourceMappingURL=lockScrollUpdates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockScrollUpdates.js","sources":["../../../src/utils/lockScrollUpdates.ts"],"sourcesContent":["import type { MutableRefObject } from 'react';\n\nconst lockScrollUpdates = (\n\tid: string,\n\tisClickScrolling: MutableRefObject<boolean>,\n\tscrollEndHandlerRef: MutableRefObject<(() => void) | null>,\n\tsetVisibleTitle: (id: string) => void\n) => {\n\tif (scrollEndHandlerRef.current) {\n\t\tdocument.body.removeEventListener('scrollend', scrollEndHandlerRef.current);\n\t}\n\n\tisClickScrolling.current = true;\n\n\tscrollEndHandlerRef.current = () => {\n\t\tisClickScrolling.current = false;\n\t\tscrollEndHandlerRef.current = null;\n\t\tsetVisibleTitle(id);\n\t\tconst url = new URL(window.location.href);\n\t\turl.searchParams.set('section', id);\n\t\twindow.history.replaceState({}, '', url.toString());\n\t};\n\n\tdocument.body.addEventListener('scrollend', scrollEndHandlerRef.current, {\n\t\tonce: true,\n\t});\n};\n\nexport default lockScrollUpdates;\n"],"names":[],"mappings":"AAEA,MAAM,iBAAiB,GAAG,CACzB,EAAU,EACV,gBAA2C,EAC3C,mBAA0D,EAC1D,eAAqC,KAClC;AACH,IAAA,IAAI,mBAAmB,CAAC,OAAO,EAAE;QAChC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,mBAAmB,CAAC,OAAO,CAAC;IAC5E;AAEA,IAAA,gBAAgB,CAAC,OAAO,GAAG,IAAI;AAE/B,IAAA,mBAAmB,CAAC,OAAO,GAAG,MAAK;AAClC,QAAA,gBAAgB,CAAC,OAAO,GAAG,KAAK;AAChC,QAAA,mBAAmB,CAAC,OAAO,GAAG,IAAI;QAClC,eAAe,CAAC,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QACzC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC;AACnC,QAAA,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;AACpD,IAAA,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,mBAAmB,CAAC,OAAO,EAAE;AACxE,QAAA,IAAI,EAAE,IAAI;AACV,KAAA,CAAC;AACH;;;;"}
|
|
@@ -9,6 +9,6 @@ export interface ForwardedReference {
|
|
|
9
9
|
parentRef: HTMLDivElement;
|
|
10
10
|
childRefs: HTMLDivElement[];
|
|
11
11
|
}
|
|
12
|
-
declare const Blog: ({ children, title, jsonLd }: BlogProperties) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
declare const Blog: ({ children, title, jsonLd, }: BlogProperties) => import("react/jsx-runtime").JSX.Element;
|
|
13
13
|
export default Blog;
|
|
14
14
|
//# sourceMappingURL=BlogDynamic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlogDynamic.d.ts","sourceRoot":"","sources":["../../../src/dynamicComponents/BlogDynamic.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAc,SAAS,EAAiB,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"BlogDynamic.d.ts","sourceRoot":"","sources":["../../../src/dynamicComponents/BlogDynamic.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAc,SAAS,EAAiB,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKrD,UAAU,cAAc;IACvB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,cAAc,EAAE,CAAC;CAC5B;AAgBD,QAAA,MAAM,IAAI,GAAI,8BAIX,cAAc,4CAiPhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MutableRefObject } from 'react';
|
|
2
|
+
declare const lockScrollUpdates: (id: string, isClickScrolling: MutableRefObject<boolean>, scrollEndHandlerRef: MutableRefObject<(() => void) | null>, setVisibleTitle: (id: string) => void) => void;
|
|
3
|
+
export default lockScrollUpdates;
|
|
4
|
+
//# sourceMappingURL=lockScrollUpdates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockScrollUpdates.d.ts","sourceRoot":"","sources":["../../../src/dynamicComponents/lockScrollUpdates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAE9C,QAAA,MAAM,iBAAiB,GACtB,IAAI,MAAM,EACV,kBAAkB,gBAAgB,CAAC,OAAO,CAAC,EAC3C,qBAAqB,gBAAgB,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,EAC1D,iBAAiB,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,SAoBrC,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@san-siva/blogkit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.17",
|
|
4
4
|
"description": "A reusable blog component library for React/Next.js applications with code highlighting, diagrams, and rich content features",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -15,6 +15,7 @@ import type { MouseEvent, ReactNode, RefAttributes } from 'react';
|
|
|
15
15
|
import type { Thing, WithContext } from 'schema-dts';
|
|
16
16
|
|
|
17
17
|
import styles from '../styles/Blog.module.scss';
|
|
18
|
+
import lockScrollUpdates from '../utils/lockScrollUpdates';
|
|
18
19
|
|
|
19
20
|
interface BlogProperties {
|
|
20
21
|
children: ReactNode;
|
|
@@ -41,7 +42,11 @@ interface CategoryTitleValue extends SectionReferenceValue {
|
|
|
41
42
|
|
|
42
43
|
type CategoryTitle = Map<string, CategoryTitleValue>;
|
|
43
44
|
|
|
44
|
-
const Blog = ({
|
|
45
|
+
const Blog = ({
|
|
46
|
+
children,
|
|
47
|
+
title = 'In this article',
|
|
48
|
+
jsonLd,
|
|
49
|
+
}: BlogProperties) => {
|
|
45
50
|
const sectionReferences = useRef<SectionReference>(new Map());
|
|
46
51
|
const [categoryTitles, setCategoryTitles] = useState<CategoryTitle>(
|
|
47
52
|
new Map()
|
|
@@ -51,6 +56,9 @@ const Blog = ({ children, title = 'In this article', jsonLd }: BlogProperties) =
|
|
|
51
56
|
|
|
52
57
|
const updateTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
53
58
|
const showTOCTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
59
|
+
const hasScrolledToInitialSection = useRef(false);
|
|
60
|
+
const isClickScrolling = useRef(false);
|
|
61
|
+
const scrollEndHandlerRef = useRef<(() => void) | null>(null);
|
|
54
62
|
|
|
55
63
|
const sortByDomPosition = useCallback(
|
|
56
64
|
(
|
|
@@ -114,11 +122,15 @@ const Blog = ({ children, title = 'In this article', jsonLd }: BlogProperties) =
|
|
|
114
122
|
const observer = new IntersectionObserver(
|
|
115
123
|
([entry]) => {
|
|
116
124
|
if (!entry.isIntersecting) return;
|
|
125
|
+
if (isClickScrolling.current) return;
|
|
117
126
|
setVisibleTitle(visibleId => {
|
|
118
127
|
if (visibleId === id && !entry.isIntersecting) return null;
|
|
119
128
|
if (entry.isIntersecting) return id;
|
|
120
129
|
return visibleId;
|
|
121
130
|
});
|
|
131
|
+
const url = new URL(window.location.href);
|
|
132
|
+
url.searchParams.set('section', id);
|
|
133
|
+
window.history.replaceState({}, '', url.toString());
|
|
122
134
|
},
|
|
123
135
|
{ threshold: 0.1 }
|
|
124
136
|
);
|
|
@@ -140,9 +152,28 @@ const Blog = ({ children, title = 'In this article', jsonLd }: BlogProperties) =
|
|
|
140
152
|
if (showTOCTimerRef.current) {
|
|
141
153
|
clearTimeout(showTOCTimerRef.current);
|
|
142
154
|
}
|
|
155
|
+
if (scrollEndHandlerRef.current) {
|
|
156
|
+
document.body.removeEventListener('scrollend', scrollEndHandlerRef.current);
|
|
157
|
+
}
|
|
143
158
|
};
|
|
144
159
|
}, []);
|
|
145
160
|
|
|
161
|
+
// On initial load, scroll to section specified in URL
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
if (hasScrolledToInitialSection.current) return;
|
|
164
|
+
if (categoryTitles.size === 0) return;
|
|
165
|
+
const url = new URL(window.location.href);
|
|
166
|
+
const section = url.searchParams.get('section');
|
|
167
|
+
if (!section) return;
|
|
168
|
+
const entry = categoryTitles.get(section);
|
|
169
|
+
if (!entry) return;
|
|
170
|
+
hasScrolledToInitialSection.current = true;
|
|
171
|
+
const top =
|
|
172
|
+
entry.el.getBoundingClientRect().top + document.body.scrollTop - 100;
|
|
173
|
+
document.body.scrollTo({ top, behavior: 'smooth' });
|
|
174
|
+
lockScrollUpdates(section, isClickScrolling, scrollEndHandlerRef, setVisibleTitle);
|
|
175
|
+
}, [categoryTitles]);
|
|
176
|
+
|
|
146
177
|
const handleSectionReference = useCallback(
|
|
147
178
|
(element: ForwardedReference) => {
|
|
148
179
|
if (!element) return;
|
|
@@ -193,15 +224,17 @@ const Blog = ({ children, title = 'In this article', jsonLd }: BlogProperties) =
|
|
|
193
224
|
if (!el) return;
|
|
194
225
|
|
|
195
226
|
const top = el.getBoundingClientRect().top + document.body.scrollTop - 100;
|
|
227
|
+
|
|
228
|
+
const url = new URL(window.location.href);
|
|
229
|
+
url.searchParams.set('section', id);
|
|
230
|
+
window.history.replaceState({}, '', url.toString());
|
|
231
|
+
|
|
196
232
|
document.body.scrollTo({
|
|
197
233
|
top,
|
|
198
234
|
behavior: 'smooth',
|
|
199
235
|
});
|
|
200
236
|
|
|
201
|
-
|
|
202
|
-
setVisibleTitle(id);
|
|
203
|
-
clearTimeout(timer);
|
|
204
|
-
}, 1000);
|
|
237
|
+
lockScrollUpdates(id, isClickScrolling, scrollEndHandlerRef, setVisibleTitle);
|
|
205
238
|
};
|
|
206
239
|
|
|
207
240
|
const sidebarStyle = useSpring({
|
|
@@ -14,7 +14,7 @@ import type { ReactNode, RefAttributes } from 'react';
|
|
|
14
14
|
import styles from '../styles/BlogSection.module.scss';
|
|
15
15
|
|
|
16
16
|
import type { ForwardedReference } from './BlogDynamic';
|
|
17
|
-
import { generateIdForBlogTitle } from '../utils';
|
|
17
|
+
import { generateIdForBlogTitle, generateSectionHref } from '../utils';
|
|
18
18
|
|
|
19
19
|
interface BlogProperties {
|
|
20
20
|
title?: string;
|
|
@@ -74,7 +74,11 @@ const BlogSection = forwardRef<ForwardedReference, BlogProperties>(
|
|
|
74
74
|
ref={parentReference}
|
|
75
75
|
>
|
|
76
76
|
{title ? (
|
|
77
|
-
<h4 className={styles['blog-section__title']}>
|
|
77
|
+
<h4 className={styles['blog-section__title']}>
|
|
78
|
+
<a href={generateSectionHref(id)} className={styles['blog-section__title-link']} onClick={e => e.preventDefault()}>
|
|
79
|
+
{title}
|
|
80
|
+
</a>
|
|
81
|
+
</h4>
|
|
78
82
|
) : null}
|
|
79
83
|
{Children.map(children, child => {
|
|
80
84
|
if (!isValidElement(child)) return child;
|
|
@@ -4,6 +4,20 @@
|
|
|
4
4
|
&__title {
|
|
5
5
|
margin-bottom: stylekit.space(2);
|
|
6
6
|
}
|
|
7
|
+
|
|
8
|
+
&__title-link {
|
|
9
|
+
color: inherit;
|
|
10
|
+
text-decoration: none;
|
|
11
|
+
font-size: inherit;
|
|
12
|
+
font-weight: inherit;
|
|
13
|
+
font-family: inherit;
|
|
14
|
+
|
|
15
|
+
&:hover {
|
|
16
|
+
color: stylekit.$color--dark;
|
|
17
|
+
text-decoration: underline;
|
|
18
|
+
text-decoration-color: stylekit.$color--primary;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
7
21
|
}
|
|
8
22
|
|
|
9
23
|
.blog-section .blog-section > .blog-section__title {
|
|
@@ -24,9 +38,9 @@
|
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
.margin-bottom--6 {
|
|
27
|
-
|
|
41
|
+
margin-bottom: stylekit.space(6);
|
|
28
42
|
}
|
|
29
43
|
|
|
30
44
|
.margin-bottom--9 {
|
|
31
|
-
|
|
45
|
+
margin-bottom: stylekit.space(9);
|
|
32
46
|
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export const generateIdForBlogTitle = (title: string) => title.toLowerCase().replace(/[^\w\d]/g, '-');
|
|
2
2
|
|
|
3
3
|
export const generateUrlForBlogTitle = (title: string) => encodeURIComponent(title.replace(/[^\w]+/g, '-').toLowerCase());
|
|
4
|
+
|
|
5
|
+
export const generateSectionHref = (id: string) => `?section=${id}`;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { MutableRefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
const lockScrollUpdates = (
|
|
4
|
+
id: string,
|
|
5
|
+
isClickScrolling: MutableRefObject<boolean>,
|
|
6
|
+
scrollEndHandlerRef: MutableRefObject<(() => void) | null>,
|
|
7
|
+
setVisibleTitle: (id: string) => void
|
|
8
|
+
) => {
|
|
9
|
+
if (scrollEndHandlerRef.current) {
|
|
10
|
+
document.body.removeEventListener('scrollend', scrollEndHandlerRef.current);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
isClickScrolling.current = true;
|
|
14
|
+
|
|
15
|
+
scrollEndHandlerRef.current = () => {
|
|
16
|
+
isClickScrolling.current = false;
|
|
17
|
+
scrollEndHandlerRef.current = null;
|
|
18
|
+
setVisibleTitle(id);
|
|
19
|
+
const url = new URL(window.location.href);
|
|
20
|
+
url.searchParams.set('section', id);
|
|
21
|
+
window.history.replaceState({}, '', url.toString());
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
document.body.addEventListener('scrollend', scrollEndHandlerRef.current, {
|
|
25
|
+
once: true,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default lockScrollUpdates;
|