@san-siva/blogkit 1.1.0 → 1.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"BlogDynamic.d.ts","sourceRoot":"","sources":["../../../src/dynamicComponents/BlogDynamic.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAc,SAAS,EAAiB,MAAM,OAAO,CAAC;AAIlE,UAAU,cAAc;IACvB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,cAAc,EAAE,CAAC;CAC5B;AAkBD,QAAA,MAAM,IAAI,GAAI,qBAAyC,cAAc,4CAoNpE,CAAC;AAEF,eAAe,IAAI,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;AAIlE,UAAU,cAAc;IACvB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,cAAc,EAAE,CAAC;CAC5B;AAgBD,QAAA,MAAM,IAAI,GAAI,qBAAyC,cAAc,4CA4NpE,CAAC;AAEF,eAAe,IAAI,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@san-siva/blogkit",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
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",
@@ -9,6 +9,7 @@ import {
9
9
  useRef,
10
10
  useState,
11
11
  } from 'react';
12
+ import { useSpring, animated } from '@react-spring/web';
12
13
 
13
14
  import type { MouseEvent, ReactNode, RefAttributes } from 'react';
14
15
 
@@ -38,34 +39,22 @@ interface CategoryTitleValue extends SectionReferenceValue {
38
39
 
39
40
  type CategoryTitle = Map<string, CategoryTitleValue>;
40
41
 
41
- type AddPaddingTopTimerReference = ReturnType<typeof setTimeout> | null;
42
-
43
42
  const Blog = ({ children, title = 'In this article' }: BlogProperties) => {
44
- const addPaddingTopTimerReference = useRef<AddPaddingTopTimerReference>(null);
45
- const highlightCategoryTimerReference =
46
- useRef<AddPaddingTopTimerReference>(null);
47
-
48
- const clearTimers = (
49
- addPaddingTopTimerReference_: AddPaddingTopTimerReference,
50
- highlightCategoryTimerReference_: AddPaddingTopTimerReference
51
- ) => {
52
- if (addPaddingTopTimerReference_) {
53
- clearTimeout(addPaddingTopTimerReference_);
54
- }
55
- if (highlightCategoryTimerReference_) {
56
- clearTimeout(highlightCategoryTimerReference_);
57
- }
58
- };
59
-
60
43
  const sectionReferences = useRef<SectionReference>(new Map());
61
44
  const [categoryTitles, setCategoryTitles] = useState<CategoryTitle>(
62
45
  new Map()
63
46
  );
64
47
  const [visibleTitle, setVisibleTitle] = useState<string | null>(null);
48
+ const [showTOC, setShowTOC] = useState(false);
49
+
65
50
  const updateTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
51
+ const showTOCTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
66
52
 
67
53
  const sortByDomPosition = useCallback(
68
- ([, a]: [string, SectionReferenceValue], [, b]: [string, SectionReferenceValue]) => {
54
+ (
55
+ [, a]: [string, SectionReferenceValue],
56
+ [, b]: [string, SectionReferenceValue]
57
+ ) => {
69
58
  const position = a.el.compareDocumentPosition(b.el);
70
59
  if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
71
60
  return -1; // a comes before b
@@ -77,6 +66,16 @@ const Blog = ({ children, title = 'In this article' }: BlogProperties) => {
77
66
  []
78
67
  );
79
68
 
69
+ const debounceShowTOC = useCallback(() => {
70
+ if (showTOC) return;
71
+ if (showTOCTimerRef.current) {
72
+ clearTimeout(showTOCTimerRef.current);
73
+ }
74
+ showTOCTimerRef.current = setTimeout(() => {
75
+ setShowTOC(true);
76
+ }, 200);
77
+ }, [showTOC]);
78
+
80
79
  const updateCategoryTitles = useCallback(() => {
81
80
  const now = Date.now();
82
81
  const newCategoryTitles = new Map<string, CategoryTitleValue>();
@@ -98,12 +97,13 @@ const Blog = ({ children, title = 'In this article' }: BlogProperties) => {
98
97
  });
99
98
  }
100
99
 
101
- if (newCategoryTitles.size > 0) {
102
- setCategoryTitles(newCategoryTitles);
103
- if (!visibleTitle) {
104
- setVisibleTitle(firstSectionId);
105
- }
106
- }
100
+ if (newCategoryTitles.size === 0) return;
101
+
102
+ setCategoryTitles(newCategoryTitles);
103
+ debounceShowTOC();
104
+
105
+ if (visibleTitle) return;
106
+ setVisibleTitle(firstSectionId);
107
107
  }, [visibleTitle, sortByDomPosition]);
108
108
 
109
109
  const debounceUpdateCategoryTitles = useCallback(() => {
@@ -142,51 +142,53 @@ const Blog = ({ children, title = 'In this article' }: BlogProperties) => {
142
142
 
143
143
  useEffect(() => {
144
144
  return () => {
145
- clearTimers(
146
- addPaddingTopTimerReference.current,
147
- highlightCategoryTimerReference.current
148
- );
149
145
  if (updateTimerRef.current) {
150
146
  clearTimeout(updateTimerRef.current);
151
147
  }
148
+ if (showTOCTimerRef.current) {
149
+ clearTimeout(showTOCTimerRef.current);
150
+ }
152
151
  };
153
152
  }, []);
154
153
 
155
- const handleSectionReference = useCallback((element: ForwardedReference) => {
156
- if (!element) return;
157
- const { parentRef, childRefs } = element;
158
-
159
- // Add parent section reference
160
- if (parentRef) {
161
- const id = parentRef.dataset.id;
162
- const title = parentRef.dataset.title;
163
- if (id && title) {
164
- sectionReferences.current.set(id, {
165
- el: parentRef,
166
- title,
167
- isSubSection: false,
168
- });
169
- }
170
- }
154
+ const handleSectionReference = useCallback(
155
+ (element: ForwardedReference) => {
156
+ if (!element) return;
157
+ const { parentRef, childRefs } = element;
171
158
 
172
- // Add child section references
173
- if (Array.isArray(childRefs)) {
174
- for (const childRef of childRefs) {
175
- if (!childRef) continue;
176
- const id = childRef.dataset.id;
177
- const title = childRef.dataset.title;
159
+ // Add parent section reference
160
+ if (parentRef) {
161
+ const id = parentRef.dataset.id;
162
+ const title = parentRef.dataset.title;
178
163
  if (id && title) {
179
164
  sectionReferences.current.set(id, {
180
- el: childRef,
165
+ el: parentRef,
181
166
  title,
182
- isSubSection: true,
167
+ isSubSection: false,
183
168
  });
184
169
  }
185
170
  }
186
- }
187
171
 
188
- debounceUpdateCategoryTitles();
189
- }, [debounceUpdateCategoryTitles]);
172
+ // Add child section references
173
+ if (Array.isArray(childRefs)) {
174
+ for (const childRef of childRefs) {
175
+ if (!childRef) continue;
176
+ const id = childRef.dataset.id;
177
+ const title = childRef.dataset.title;
178
+ if (id && title) {
179
+ sectionReferences.current.set(id, {
180
+ el: childRef,
181
+ title,
182
+ isSubSection: true,
183
+ });
184
+ }
185
+ }
186
+ }
187
+
188
+ debounceUpdateCategoryTitles();
189
+ },
190
+ [debounceUpdateCategoryTitles]
191
+ );
190
192
 
191
193
  const handleClickCategoryTitle = (
192
194
  error: MouseEvent<HTMLParagraphElement>
@@ -210,6 +212,11 @@ const Blog = ({ children, title = 'In this article' }: BlogProperties) => {
210
212
  }, 1000);
211
213
  };
212
214
 
215
+ const sidebarStyle = useSpring({
216
+ opacity: showTOC ? 1 : 0,
217
+ transform: showTOC ? 'translateX(0)' : 'translateX(80px)',
218
+ config: { tension: 280, friction: 60 },
219
+ });
213
220
 
214
221
  return (
215
222
  <div className={styles.blog}>
@@ -221,7 +228,7 @@ const Blog = ({ children, title = 'In this article' }: BlogProperties) => {
221
228
  } as RefAttributes<ForwardedReference>);
222
229
  })}
223
230
  </div>
224
- <div className={styles['blog__sidebar']}>
231
+ <animated.div className={styles['blog__sidebar']} style={sidebarStyle}>
225
232
  <p
226
233
  className={`${styles['margin-bottom--3']} ${styles['category__header']}`}
227
234
  >
@@ -249,7 +256,7 @@ const Blog = ({ children, title = 'In this article' }: BlogProperties) => {
249
256
  );
250
257
  }
251
258
  )}
252
- </div>
259
+ </animated.div>
253
260
  </div>
254
261
  );
255
262
  };
@@ -21,11 +21,13 @@
21
21
  top: calc(var(--topbar-height) + #{styles.space(6)});
22
22
  padding: styles.space(6);
23
23
  min-width: calc(
24
- #{styles.rem(380)} - #{styles.space(6)} - #{styles.space(6)}
24
+ #{styles.rem(320)} - #{styles.space(6)} - #{styles.space(6)}
25
25
  );
26
26
  border-radius: styles.$border-radius--1;
27
27
  background-color: styles.$color--code;
28
- box-shadow: 0 0 0 1px styles.$color--border, 0 styles.space(1) styles.space(2) 0 styles.$color--border;
28
+ box-shadow:
29
+ 0 0 0 1px styles.$color--border,
30
+ 0 styles.space(1) styles.space(2) 0 styles.$color--border;
29
31
 
30
32
  margin-left: styles.space(9);
31
33