@san-siva/blogkit 1.0.12 → 1.1.0

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.
Files changed (196) hide show
  1. package/README.md +64 -13
  2. package/dist/cjs/components/Blog.js +3 -118
  3. package/dist/cjs/components/Blog.js.map +1 -1
  4. package/dist/cjs/components/BlogHeader.js +4 -4
  5. package/dist/cjs/components/BlogHeader.js.map +1 -1
  6. package/dist/cjs/components/BlogLink.js +4 -23
  7. package/dist/cjs/components/BlogLink.js.map +1 -1
  8. package/dist/cjs/components/BlogSection.js +4 -29
  9. package/dist/cjs/components/BlogSection.js.map +1 -1
  10. package/dist/cjs/components/Callout.js +3 -4
  11. package/dist/cjs/components/Callout.js.map +1 -1
  12. package/dist/cjs/components/CodeBlock.js +3 -25
  13. package/dist/cjs/components/CodeBlock.js.map +1 -1
  14. package/dist/cjs/components/Mermaid.js +3 -46
  15. package/dist/cjs/components/Mermaid.js.map +1 -1
  16. package/dist/cjs/components/Table.js +2 -7
  17. package/dist/cjs/components/Table.js.map +1 -1
  18. package/dist/cjs/dynamicComponents/BlogDynamic.js +167 -0
  19. package/dist/cjs/dynamicComponents/BlogDynamic.js.map +1 -0
  20. package/dist/cjs/dynamicComponents/BlogHeaderDynamic.js +13 -0
  21. package/dist/cjs/dynamicComponents/BlogHeaderDynamic.js.map +1 -0
  22. package/dist/cjs/dynamicComponents/BlogLinkDynamic.js +35 -0
  23. package/dist/cjs/dynamicComponents/BlogLinkDynamic.js.map +1 -0
  24. package/dist/cjs/dynamicComponents/BlogSectionDynamic.js +50 -0
  25. package/dist/cjs/dynamicComponents/BlogSectionDynamic.js.map +1 -0
  26. package/dist/cjs/dynamicComponents/CalloutDynamic.js +14 -0
  27. package/dist/cjs/dynamicComponents/CalloutDynamic.js.map +1 -0
  28. package/dist/cjs/dynamicComponents/CodeBlockDynamic.js +38 -0
  29. package/dist/cjs/dynamicComponents/CodeBlockDynamic.js.map +1 -0
  30. package/dist/cjs/dynamicComponents/MermaidDynamic.js +59 -0
  31. package/dist/cjs/dynamicComponents/MermaidDynamic.js.map +1 -0
  32. package/dist/cjs/dynamicComponents/TableDynamic.js +18 -0
  33. package/dist/cjs/dynamicComponents/TableDynamic.js.map +1 -0
  34. package/dist/cjs/index.css +2 -0
  35. package/dist/cjs/index.css.map +1 -0
  36. package/dist/cjs/staticComponents/BlogLinkStatic.js +17 -0
  37. package/dist/cjs/staticComponents/BlogLinkStatic.js.map +1 -0
  38. package/dist/cjs/staticComponents/BlogSectionStatic.js +19 -0
  39. package/dist/cjs/staticComponents/BlogSectionStatic.js.map +1 -0
  40. package/dist/cjs/staticComponents/BlogStatic.js +13 -0
  41. package/dist/cjs/staticComponents/BlogStatic.js.map +1 -0
  42. package/dist/cjs/staticComponents/CodeBlockStatic.js +13 -0
  43. package/dist/cjs/staticComponents/CodeBlockStatic.js.map +1 -0
  44. package/dist/cjs/staticComponents/MermaidStatic.js +13 -0
  45. package/dist/cjs/staticComponents/MermaidStatic.js.map +1 -0
  46. package/dist/cjs/styles/Blog.module.scss.js +0 -4
  47. package/dist/cjs/styles/Blog.module.scss.js.map +1 -1
  48. package/dist/cjs/styles/BlogHeader.module.scss.js +0 -4
  49. package/dist/cjs/styles/BlogHeader.module.scss.js.map +1 -1
  50. package/dist/cjs/styles/BlogLink.module.scss.js +0 -4
  51. package/dist/cjs/styles/BlogLink.module.scss.js.map +1 -1
  52. package/dist/cjs/styles/BlogSection.module.scss.js +0 -4
  53. package/dist/cjs/styles/BlogSection.module.scss.js.map +1 -1
  54. package/dist/cjs/styles/Callout.module.scss.js +0 -4
  55. package/dist/cjs/styles/Callout.module.scss.js.map +1 -1
  56. package/dist/cjs/styles/CodeBlock.module.scss.js +1 -5
  57. package/dist/cjs/styles/CodeBlock.module.scss.js.map +1 -1
  58. package/dist/cjs/styles/Mermaid.module.scss.js +0 -4
  59. package/dist/cjs/styles/Mermaid.module.scss.js.map +1 -1
  60. package/dist/cjs/styles/Table.module.scss.js +0 -4
  61. package/dist/cjs/styles/Table.module.scss.js.map +1 -1
  62. package/dist/esm/components/Blog.js +5 -120
  63. package/dist/esm/components/Blog.js.map +1 -1
  64. package/dist/esm/components/BlogHeader.js +5 -5
  65. package/dist/esm/components/BlogHeader.js.map +1 -1
  66. package/dist/esm/components/BlogLink.js +6 -25
  67. package/dist/esm/components/BlogLink.js.map +1 -1
  68. package/dist/esm/components/BlogSection.js +6 -31
  69. package/dist/esm/components/BlogSection.js.map +1 -1
  70. package/dist/esm/components/Callout.js +4 -5
  71. package/dist/esm/components/Callout.js.map +1 -1
  72. package/dist/esm/components/CodeBlock.js +5 -27
  73. package/dist/esm/components/CodeBlock.js.map +1 -1
  74. package/dist/esm/components/Mermaid.js +5 -48
  75. package/dist/esm/components/Mermaid.js.map +1 -1
  76. package/dist/esm/components/Table.js +3 -8
  77. package/dist/esm/components/Table.js.map +1 -1
  78. package/dist/esm/dynamicComponents/BlogDynamic.js +163 -0
  79. package/dist/esm/dynamicComponents/BlogDynamic.js.map +1 -0
  80. package/dist/esm/dynamicComponents/BlogHeaderDynamic.js +9 -0
  81. package/dist/esm/dynamicComponents/BlogHeaderDynamic.js.map +1 -0
  82. package/dist/esm/dynamicComponents/BlogLinkDynamic.js +31 -0
  83. package/dist/esm/dynamicComponents/BlogLinkDynamic.js.map +1 -0
  84. package/dist/esm/dynamicComponents/BlogSectionDynamic.js +46 -0
  85. package/dist/esm/dynamicComponents/BlogSectionDynamic.js.map +1 -0
  86. package/dist/esm/dynamicComponents/CalloutDynamic.js +10 -0
  87. package/dist/esm/dynamicComponents/CalloutDynamic.js.map +1 -0
  88. package/dist/esm/dynamicComponents/CodeBlockDynamic.js +34 -0
  89. package/dist/esm/dynamicComponents/CodeBlockDynamic.js.map +1 -0
  90. package/dist/esm/dynamicComponents/MermaidDynamic.js +55 -0
  91. package/dist/esm/dynamicComponents/MermaidDynamic.js.map +1 -0
  92. package/dist/esm/dynamicComponents/TableDynamic.js +14 -0
  93. package/dist/esm/dynamicComponents/TableDynamic.js.map +1 -0
  94. package/dist/esm/index.css +2 -0
  95. package/dist/esm/index.css.map +1 -0
  96. package/dist/esm/staticComponents/BlogLinkStatic.js +13 -0
  97. package/dist/esm/staticComponents/BlogLinkStatic.js.map +1 -0
  98. package/dist/esm/staticComponents/BlogSectionStatic.js +15 -0
  99. package/dist/esm/staticComponents/BlogSectionStatic.js.map +1 -0
  100. package/dist/esm/staticComponents/BlogStatic.js +9 -0
  101. package/dist/esm/staticComponents/BlogStatic.js.map +1 -0
  102. package/dist/esm/staticComponents/CodeBlockStatic.js +9 -0
  103. package/dist/esm/staticComponents/CodeBlockStatic.js.map +1 -0
  104. package/dist/esm/staticComponents/MermaidStatic.js +9 -0
  105. package/dist/esm/staticComponents/MermaidStatic.js.map +1 -0
  106. package/dist/esm/styles/Blog.module.scss.js +0 -4
  107. package/dist/esm/styles/Blog.module.scss.js.map +1 -1
  108. package/dist/esm/styles/BlogHeader.module.scss.js +0 -4
  109. package/dist/esm/styles/BlogHeader.module.scss.js.map +1 -1
  110. package/dist/esm/styles/BlogLink.module.scss.js +0 -4
  111. package/dist/esm/styles/BlogLink.module.scss.js.map +1 -1
  112. package/dist/esm/styles/BlogSection.module.scss.js +0 -4
  113. package/dist/esm/styles/BlogSection.module.scss.js.map +1 -1
  114. package/dist/esm/styles/Callout.module.scss.js +0 -4
  115. package/dist/esm/styles/Callout.module.scss.js.map +1 -1
  116. package/dist/esm/styles/CodeBlock.module.scss.js +1 -5
  117. package/dist/esm/styles/CodeBlock.module.scss.js.map +1 -1
  118. package/dist/esm/styles/Mermaid.module.scss.js +0 -4
  119. package/dist/esm/styles/Mermaid.module.scss.js.map +1 -1
  120. package/dist/esm/styles/Table.module.scss.js +0 -4
  121. package/dist/esm/styles/Table.module.scss.js.map +1 -1
  122. package/dist/types/components/Blog.d.ts +0 -4
  123. package/dist/types/components/Blog.d.ts.map +1 -1
  124. package/dist/types/components/BlogHeader.d.ts +2 -2
  125. package/dist/types/components/BlogHeader.d.ts.map +1 -1
  126. package/dist/types/components/BlogLink.d.ts +2 -2
  127. package/dist/types/components/BlogLink.d.ts.map +1 -1
  128. package/dist/types/components/BlogSection.d.ts +5 -4
  129. package/dist/types/components/BlogSection.d.ts.map +1 -1
  130. package/dist/types/components/Callout.d.ts +1 -1
  131. package/dist/types/components/Callout.d.ts.map +1 -1
  132. package/dist/types/components/CodeBlock.d.ts +2 -3
  133. package/dist/types/components/CodeBlock.d.ts.map +1 -1
  134. package/dist/types/components/Mermaid.d.ts.map +1 -1
  135. package/dist/types/components/Table.d.ts.map +1 -1
  136. package/dist/types/components/index.d.ts +0 -1
  137. package/dist/types/components/index.d.ts.map +1 -1
  138. package/dist/types/dynamicComponents/BlogDynamic.d.ts +12 -0
  139. package/dist/types/dynamicComponents/BlogDynamic.d.ts.map +1 -0
  140. package/dist/types/dynamicComponents/BlogHeaderDynamic.d.ts +8 -0
  141. package/dist/types/dynamicComponents/BlogHeaderDynamic.d.ts.map +1 -0
  142. package/dist/types/dynamicComponents/BlogLinkDynamic.d.ts +9 -0
  143. package/dist/types/dynamicComponents/BlogLinkDynamic.d.ts.map +1 -0
  144. package/dist/types/dynamicComponents/BlogSectionDynamic.d.ts +11 -0
  145. package/dist/types/dynamicComponents/BlogSectionDynamic.d.ts.map +1 -0
  146. package/dist/types/dynamicComponents/CalloutDynamic.d.ts +10 -0
  147. package/dist/types/dynamicComponents/CalloutDynamic.d.ts.map +1 -0
  148. package/dist/types/dynamicComponents/CodeBlockDynamic.d.ts +10 -0
  149. package/dist/types/dynamicComponents/CodeBlockDynamic.d.ts.map +1 -0
  150. package/dist/types/dynamicComponents/MermaidDynamic.d.ts +9 -0
  151. package/dist/types/dynamicComponents/MermaidDynamic.d.ts.map +1 -0
  152. package/dist/types/dynamicComponents/TableDynamic.d.ts +10 -0
  153. package/dist/types/dynamicComponents/TableDynamic.d.ts.map +1 -0
  154. package/dist/types/index.d.ts +0 -1
  155. package/dist/types/index.d.ts.map +1 -1
  156. package/dist/types/staticComponents/BlogLinkStatic.d.ts +9 -0
  157. package/dist/types/staticComponents/BlogLinkStatic.d.ts.map +1 -0
  158. package/dist/types/staticComponents/BlogSectionStatic.d.ts +10 -0
  159. package/dist/types/staticComponents/BlogSectionStatic.d.ts.map +1 -0
  160. package/dist/types/staticComponents/BlogStatic.d.ts +7 -0
  161. package/dist/types/staticComponents/BlogStatic.d.ts.map +1 -0
  162. package/dist/types/staticComponents/CodeBlockStatic.d.ts +9 -0
  163. package/dist/types/staticComponents/CodeBlockStatic.d.ts.map +1 -0
  164. package/dist/types/staticComponents/MermaidStatic.d.ts +9 -0
  165. package/dist/types/staticComponents/MermaidStatic.d.ts.map +1 -0
  166. package/package.json +8 -2
  167. package/src/components/Blog.tsx +7 -195
  168. package/src/components/BlogHeader.tsx +10 -23
  169. package/src/components/BlogLink.tsx +28 -58
  170. package/src/components/BlogSection.tsx +32 -57
  171. package/src/components/Callout.tsx +12 -11
  172. package/src/components/CodeBlock.tsx +23 -55
  173. package/src/components/Mermaid.tsx +21 -55
  174. package/src/components/Table.tsx +7 -34
  175. package/src/components/index.ts +0 -2
  176. package/src/dynamicComponents/BlogDynamic.tsx +257 -0
  177. package/src/dynamicComponents/BlogHeaderDynamic.tsx +32 -0
  178. package/src/dynamicComponents/BlogLinkDynamic.tsx +74 -0
  179. package/src/dynamicComponents/BlogSectionDynamic.tsx +90 -0
  180. package/src/dynamicComponents/CalloutDynamic.tsx +27 -0
  181. package/src/dynamicComponents/CodeBlockDynamic.tsx +76 -0
  182. package/src/dynamicComponents/MermaidDynamic.tsx +78 -0
  183. package/src/dynamicComponents/TableDynamic.tsx +54 -0
  184. package/src/index.ts +0 -3
  185. package/src/staticComponents/BlogLinkStatic.tsx +45 -0
  186. package/src/staticComponents/BlogSectionStatic.tsx +40 -0
  187. package/src/staticComponents/BlogStatic.tsx +16 -0
  188. package/src/staticComponents/CodeBlockStatic.tsx +34 -0
  189. package/src/staticComponents/MermaidStatic.tsx +26 -0
  190. package/src/styles/Blog.module.scss +17 -7
  191. package/src/styles/CodeBlock.module.scss +46 -41
  192. package/src/styles/CodeBlock.module.scss.d.ts +1 -0
  193. package/dist/cjs/node_modules/style-inject/dist/style-inject.es.js +0 -33
  194. package/dist/cjs/node_modules/style-inject/dist/style-inject.es.js.map +0 -1
  195. package/dist/esm/node_modules/style-inject/dist/style-inject.es.js +0 -29
  196. package/dist/esm/node_modules/style-inject/dist/style-inject.es.js.map +0 -1
@@ -1,209 +1,21 @@
1
1
  'use client';
2
2
 
3
- import {
4
- Children,
5
- cloneElement,
6
- isValidElement,
7
- useEffect,
8
- useRef,
9
- useState,
10
- } from 'react';
3
+ import { lazy, Suspense } from 'react';
4
+ import type { ReactNode } from 'react';
5
+ import BlogStatic from '../staticComponents/BlogStatic';
11
6
 
12
- import type { MouseEvent, ReactNode, RefAttributes } from 'react';
13
-
14
- import styles from '../styles/Blog.module.scss';
7
+ const BlogDynamic = lazy(() => import('../dynamicComponents/BlogDynamic'));
15
8
 
16
9
  interface BlogProperties {
17
10
  children: ReactNode;
18
11
  title?: string;
19
12
  }
20
13
 
21
- export interface ForwardedReference {
22
- parentRef: HTMLDivElement;
23
- childRefs: HTMLDivElement[];
24
- }
25
-
26
- interface SectionReferenceValue {
27
- el: HTMLElement;
28
- title: string;
29
- isSubSection: boolean;
30
- }
31
-
32
- type SectionReference = Map<string, SectionReferenceValue>;
33
-
34
- interface CategoryTitleValue extends SectionReferenceValue {
35
- lastUpdatedAt: number;
36
- }
37
-
38
- type CategoryTitle = Map<string, CategoryTitleValue>;
39
-
40
- type AddPaddingTopTimerReference = ReturnType<typeof setTimeout> | null;
41
-
42
14
  const Blog = ({ children, title = 'In this article' }: BlogProperties) => {
43
- const addPaddingTopTimerReference = useRef<AddPaddingTopTimerReference>(null);
44
- const highlightCategoryTimerReference =
45
- useRef<AddPaddingTopTimerReference>(null);
46
-
47
- const clearTimers = (
48
- addPaddingTopTimerReference_: AddPaddingTopTimerReference,
49
- highlightCategoryTimerReference_: AddPaddingTopTimerReference
50
- ) => {
51
- if (addPaddingTopTimerReference_) {
52
- clearTimeout(addPaddingTopTimerReference_);
53
- }
54
- if (highlightCategoryTimerReference_) {
55
- clearTimeout(highlightCategoryTimerReference_);
56
- }
57
- };
58
-
59
- const sectionReferences = useRef<SectionReference>(new Map());
60
- const [categoryTitles, setCategoryTitles] = useState<CategoryTitle>(
61
- new Map()
62
- );
63
- const [visibleTitle, setVisibleTitle] = useState<string | null>(null);
64
-
65
- useEffect(() => {
66
- let firstSectionId: string | null = null;
67
- const now = Date.now();
68
- for (const [id, { title, el, isSubSection }] of sectionReferences.current) {
69
- if (!firstSectionId) {
70
- firstSectionId = id;
71
- }
72
- setCategoryTitles((previous: CategoryTitle) => {
73
- const newState = new Map(previous);
74
- newState.set(id, {
75
- el,
76
- title,
77
- lastUpdatedAt: now,
78
- isSubSection,
79
- });
80
- return newState;
81
- });
82
- }
83
- setVisibleTitle(firstSectionId);
84
- }, []);
85
-
86
- useEffect(() => {
87
- const observers = new Map<string, IntersectionObserver>();
88
- for (const [id, { el }] of categoryTitles) {
89
- const observer = new IntersectionObserver(
90
- ([entry]) => {
91
- if (!entry.isIntersecting) return;
92
- setVisibleTitle(visibleId => {
93
- if (visibleId === id && !entry.isIntersecting) return null;
94
- if (entry.isIntersecting) return id;
95
- return visibleId;
96
- });
97
- },
98
- { threshold: 0.1 }
99
- );
100
- observers.set(id, observer);
101
- observer.observe(el);
102
- }
103
- return () => {
104
- for (const observer of observers.values()) {
105
- observer.disconnect();
106
- }
107
- };
108
- }, [categoryTitles.size]);
109
-
110
- useEffect(
111
- () =>
112
- clearTimers(
113
- addPaddingTopTimerReference.current,
114
- highlightCategoryTimerReference.current
115
- ),
116
- [addPaddingTopTimerReference, highlightCategoryTimerReference]
117
- );
118
-
119
- const addSectionReferences = (element: HTMLElement, isSubSection = false) => {
120
- if (!element) return;
121
- const id = element.dataset.id;
122
- if (!id) return;
123
- const title = element.dataset.title;
124
- if (!title) return;
125
-
126
- sectionReferences.current.set(id, {
127
- el: element,
128
- title,
129
- isSubSection,
130
- });
131
- };
132
-
133
- const handleSectionReference = (element: ForwardedReference) => {
134
- if (!element) return;
135
- const { parentRef, childRefs } = element;
136
- if (!parentRef) return;
137
- addSectionReferences(parentRef);
138
- if (!Array.isArray(childRefs)) return;
139
- for (const childReference of childRefs) {
140
- if (!childReference) continue;
141
- addSectionReferences(childReference, true);
142
- }
143
- };
144
-
145
- const handleClickCategoryTitle = (
146
- error: MouseEvent<HTMLParagraphElement>
147
- ) => {
148
- const id = error.currentTarget.dataset.id;
149
- const index = error.currentTarget.dataset.idx;
150
- if (!id || !index) return;
151
-
152
- const { el } = categoryTitles.get(id) || {};
153
- if (!el) return;
154
-
155
- const top = el.getBoundingClientRect().top + document.body.scrollTop - 100;
156
- document.body.scrollTo({
157
- top,
158
- behavior: 'smooth',
159
- });
160
-
161
- const timer = setTimeout(() => {
162
- setVisibleTitle(id);
163
- clearTimeout(timer);
164
- }, 1000);
165
- };
166
-
167
15
  return (
168
- <div className={styles.blog}>
169
- <div className={styles['blog__content']}>
170
- {Children.map(children, child => {
171
- if (!isValidElement(child)) return child;
172
- return cloneElement(child, {
173
- ref: handleSectionReference,
174
- } as RefAttributes<ForwardedReference>);
175
- })}
176
- </div>
177
- <div className={styles['blog__sidebar']}>
178
- <p
179
- className={`${styles['margin-bottom--3']} ${styles['category__header']}`}
180
- >
181
- {title}
182
- </p>
183
- {[...categoryTitles].map(
184
- ([id, { title, isSubSection }], index, array) => {
185
- const isNextSectionSubSection = array[index + 1]?.[1]?.isSubSection;
186
- return (
187
- <p
188
- key={id}
189
- data-idx={index}
190
- data-id={id}
191
- className={`${styles['category__title']} ${
192
- id === visibleTitle ? styles['category__title--active'] : ''
193
- } ${isSubSection ? styles['category__title--sub'] : ''} ${
194
- isSubSection && !isNextSectionSubSection
195
- ? styles['margin-bottom-imp--2']
196
- : ''
197
- }`}
198
- onClick={handleClickCategoryTitle}
199
- >
200
- {title}
201
- </p>
202
- );
203
- }
204
- )}
205
- </div>
206
- </div>
16
+ <Suspense fallback={<BlogStatic>{children}</BlogStatic>}>
17
+ <BlogDynamic title={title}>{children}</BlogDynamic>
18
+ </Suspense>
207
19
  );
208
20
  };
209
21
 
@@ -1,32 +1,19 @@
1
- import { Fragment } from 'react';
1
+ import BlogHeaderDynamic from '../dynamicComponents/BlogHeaderDynamic';
2
2
 
3
- import styles from '../styles/BlogHeader.module.scss';
4
-
5
- interface BlogProperties {
3
+ interface BlogHeaderProperties {
6
4
  title: string[];
7
5
  desc: string[];
8
6
  isDescCite?: boolean;
9
7
  }
10
8
 
11
- const renderLineBreaks = (array: string[]) =>
12
- array.map((element, index, array) => (
13
- <Fragment key={element}>
14
- {element}
15
- {index === array.length - 1 ? null : <br />}
16
- </Fragment>
17
- ));
18
-
19
- const BlogHeader = ({ title, desc, isDescCite = true }: BlogProperties) => (
20
- <>
21
- <h1 className={`${styles['blog-header']}`}>{renderLineBreaks(title)}</h1>
22
- {isDescCite ? (
23
- <cite className={`${styles['blog-date']}`}>
24
- {renderLineBreaks(desc)}
25
- </cite>
26
- ) : (
27
- <p className={`${styles['blog-date']}`}>{renderLineBreaks(desc)}</p>
28
- )}
29
- </>
9
+ const BlogHeader = ({
10
+ title,
11
+ desc,
12
+ isDescCite = true,
13
+ }: BlogHeaderProperties) => {
14
+ return (
15
+ <BlogHeaderDynamic title={title} desc={desc} isDescCite={isDescCite} />
30
16
  );
17
+ };
31
18
 
32
19
  export default BlogHeader;
@@ -1,73 +1,43 @@
1
1
  'use client';
2
2
 
3
- import { useState } from 'react';
3
+ import { lazy, Suspense } from 'react';
4
+ import BlogLinkStatic from '../staticComponents/BlogLinkStatic';
4
5
 
5
- import { animated, useSpring } from '@react-spring/web';
6
+ const BlogLinkDynamic = lazy(
7
+ () => import('../dynamicComponents/BlogLinkDynamic')
8
+ );
6
9
 
7
- import styles from '../styles/BlogLink.module.scss';
8
-
9
- import { generateUrlForBlogTitle } from '../utils';
10
-
11
- interface Properties {
10
+ interface BlogLinkProperties {
12
11
  title: string;
13
12
  desc?: string;
14
13
  isInProgress?: boolean;
15
14
  href?: string;
16
15
  }
17
16
 
18
- const DEFAULT_LINE_END = 18;
19
- const DEFAULT_POLYLINE_POINTS = '12 5, 19 12, 12 19';
20
- const MOVED_POLYLINE_POINTS = '15 5, 22 12, 15 19';
21
-
22
- const BlogLink = ({ title = '', desc = '', isInProgress = false, href }: Properties) => {
23
- const [isHovered, setIsHovered] = useState(false);
24
-
25
- const link = href || `/blog/${generateUrlForBlogTitle(title)}`;
26
-
27
- const svgColor = useSpring({
28
- stroke: isHovered ? '#4242fa' : 'transparent',
29
- });
30
-
31
- const polyLine = useSpring({
32
- points: isHovered ? MOVED_POLYLINE_POINTS : DEFAULT_POLYLINE_POINTS,
33
- config: { duration: 200 },
34
- });
35
-
36
- const lineEnd = useSpring({
37
- x2: isHovered ? `${DEFAULT_LINE_END + 2}` : `${DEFAULT_LINE_END}`,
38
- config: { duration: 200 },
39
- });
40
-
41
- if (isInProgress) return null;
42
-
17
+ const BlogLink = ({
18
+ title = '',
19
+ desc = '',
20
+ isInProgress = false,
21
+ href,
22
+ }: BlogLinkProperties) => {
43
23
  return (
44
- <a
45
- className={styles['blog-link']}
46
- onMouseEnter={() => setIsHovered(true)}
47
- onMouseLeave={() => setIsHovered(false)}
48
- href={link}
49
- rel="noopener noreferrer"
24
+ <Suspense
25
+ fallback={
26
+ <BlogLinkStatic
27
+ title={title}
28
+ desc={desc}
29
+ isInProgress={isInProgress}
30
+ href={href}
31
+ />
32
+ }
50
33
  >
51
- <h6 className={styles['blog-link__title']}>{title}</h6>
52
- <p className={styles['blog-link__description']}>{desc}</p>
53
- <div className={styles['blog-link__read-more']}>
54
- <p>Read More</p>
55
- <animated.svg
56
- xmlns="http://www.w3.org/2000/svg"
57
- width="18px"
58
- height="18px"
59
- viewBox="0 0 24 24"
60
- fill="none"
61
- strokeWidth="2"
62
- strokeLinecap="round"
63
- strokeLinejoin="round"
64
- style={svgColor as any}
65
- >
66
- <animated.line x1="5" y1="12" y2="12" x2={lineEnd.x2 as any}></animated.line>
67
- <animated.polyline points={polyLine.points as any} />
68
- </animated.svg>
69
- </div>
70
- </a>
34
+ <BlogLinkDynamic
35
+ title={title}
36
+ desc={desc}
37
+ isInProgress={isInProgress}
38
+ href={href}
39
+ />
40
+ </Suspense>
71
41
  );
72
42
  };
73
43
 
@@ -1,78 +1,53 @@
1
1
  'use client';
2
2
 
3
- import {
4
- Children,
5
- cloneElement,
6
- forwardRef,
7
- isValidElement,
8
- useImperativeHandle,
9
- useRef,
10
- } from 'react';
11
-
12
- import type { ReactNode, RefAttributes } from 'react';
13
-
14
- import styles from '../styles/BlogSection.module.scss';
15
-
16
- import type { ForwardedReference } from './Blog';
17
- import { generateIdForBlogTitle } from '../utils';
3
+ import { forwardRef, lazy, Suspense } from 'react';
4
+ import type { ReactNode } from 'react';
5
+ import BlogSectionStatic from '../staticComponents/BlogSectionStatic';
6
+ import type { ForwardedReference } from '../dynamicComponents/BlogDynamic';
7
+ export type { ForwardedReference };
8
+
9
+ const BlogSectionDynamic = lazy(
10
+ () => import('../dynamicComponents/BlogSectionDynamic')
11
+ );
18
12
 
19
- interface BlogProperties {
13
+ interface BlogSectionProperties {
20
14
  title?: string;
21
15
  category?: string;
22
16
  children?: ReactNode;
23
17
  increaseMarginBottom?: boolean;
24
18
  }
25
19
 
26
- const BlogSection = forwardRef<ForwardedReference, BlogProperties>(
20
+ const BlogSection = forwardRef<ForwardedReference, BlogSectionProperties>(
27
21
  (
28
22
  {
29
23
  title = '',
30
24
  category = '',
31
25
  children = null,
32
26
  increaseMarginBottom = false,
33
- }: BlogProperties,
34
- forwardedReference
27
+ },
28
+ ref
35
29
  ) => {
36
- const titleWithCategory = category ? `${category} - ${title}` : title;
37
- const id = generateIdForBlogTitle(titleWithCategory);
38
-
39
- const parentReference = useRef<ForwardedReference['parentRef']>(null);
40
- const childReferences = useRef<ForwardedReference['childRefs']>([]);
41
-
42
- useImperativeHandle(forwardedReference, () => ({
43
- parentRef: parentReference.current!,
44
- childRefs: childReferences.current!,
45
- }));
46
-
47
- const handleChildReferences = (element: ForwardedReference | null) => {
48
- if (!element) return;
49
- const { parentRef: subParentReference } = element;
50
- if (!subParentReference) return;
51
- childReferences.current.push(subParentReference);
52
- };
53
-
54
30
  return (
55
- <div
56
- className={`${styles['blog-section']}
57
- ${
58
- increaseMarginBottom
59
- ? styles['margin-bottom--9']
60
- : styles['margin-bottom--6']
61
- }`}
62
- data-title={title}
63
- data-id={id}
64
- ref={parentReference}
31
+ <Suspense
32
+ fallback={
33
+ <BlogSectionStatic
34
+ title={title}
35
+ category={category}
36
+ increaseMarginBottom={increaseMarginBottom}
37
+ >
38
+ {children}
39
+ </BlogSectionStatic>
40
+ }
65
41
  >
66
- {title ? (
67
- <h4 className={styles['blog-section__title']}>{title}</h4>
68
- ) : null}
69
- {Children.map(children, child => {
70
- if (!isValidElement(child)) return child;
71
- return cloneElement(child, {
72
- ref: handleChildReferences,
73
- } as RefAttributes<ForwardedReference>);
74
- })}
75
- </div>
42
+ <BlogSectionDynamic
43
+ ref={ref}
44
+ title={title}
45
+ category={category}
46
+ increaseMarginBottom={increaseMarginBottom}
47
+ >
48
+ {children}
49
+ </BlogSectionDynamic>
50
+ </Suspense>
76
51
  );
77
52
  }
78
53
  );
@@ -1,6 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
-
3
- import styles from '../styles/Callout.module.scss';
2
+ import CalloutDynamic from '../dynamicComponents/CalloutDynamic';
4
3
 
5
4
  interface CalloutProperties {
6
5
  children?: ReactNode;
@@ -9,18 +8,20 @@ interface CalloutProperties {
9
8
  hasMarginDown?: boolean;
10
9
  }
11
10
 
12
- const Callout = ({ children, type = 'info',
11
+ const Callout = ({
12
+ children,
13
+ type = 'info',
13
14
  hasMarginUp = false,
14
- hasMarginDown = false
15
+ hasMarginDown = false,
15
16
  }: CalloutProperties) => {
16
- const className = `${styles.callout} ${styles[`callout--${type}`]} ${
17
- hasMarginUp ? styles['margin-top--1'] : ''
18
- } ${hasMarginDown ? styles['margin-bottom--2'] : ''}`;
19
17
  return (
20
- <div className={className}>
21
- <div className={styles.callout__icon}/>
22
- <div className={styles.callout__wrapper}>{children}</div>
23
- </div>
18
+ <CalloutDynamic
19
+ type={type}
20
+ hasMarginUp={hasMarginUp}
21
+ hasMarginDown={hasMarginDown}
22
+ >
23
+ {children}
24
+ </CalloutDynamic>
24
25
  );
25
26
  };
26
27
 
@@ -1,16 +1,13 @@
1
1
  'use client';
2
2
 
3
- import { useState } from 'react';
4
- import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
5
- import { dracula } from 'react-syntax-highlighter/dist/esm/styles/prism';
3
+ import { lazy, Suspense } from 'react';
4
+ import CodeBlockStatic from '../staticComponents/CodeBlockStatic';
6
5
 
7
- import 'prismjs/themes/prism-tomorrow.css';
6
+ const CodeBlockDynamic = lazy(
7
+ () => import('../dynamicComponents/CodeBlockDynamic')
8
+ );
8
9
 
9
- const SH = SyntaxHighlighter as any;
10
-
11
- import styles from '../styles/CodeBlock.module.scss';
12
-
13
- interface Properties {
10
+ interface CodeBlockProperties {
14
11
  hasMarginUp?: boolean;
15
12
  hasMarginDown?: boolean;
16
13
  language?: string;
@@ -22,54 +19,25 @@ const CodeBlock = ({
22
19
  code = '',
23
20
  hasMarginUp = false,
24
21
  hasMarginDown = false,
25
- }: Properties) => {
26
- const [isCopyMode, setCopyMode] = useState(false);
27
-
28
- const copyToClipboard = async () => {
29
- try {
30
- await navigator.clipboard.writeText(code);
31
- setCopyMode(true);
32
- setTimeout(() => {
33
- setCopyMode(false);
34
- }, 1000);
35
- } catch (error) {
36
- console.error('Failed to copy:', error);
37
- }
38
- };
39
-
40
- const lineNumberStyle = {
41
- color: '#95a1b1',
42
- fontSize: '0.9em',
43
- paddingRight: '1em',
44
- marginRight: '8px',
45
- };
46
-
22
+ }: CodeBlockProperties) => {
47
23
  return (
48
- <div
49
- className={`${styles['code-block']} ${hasMarginUp ? styles['margin-top--1'] : ''} ${
50
- hasMarginDown ? styles['margin-bottom--2'] : ''
51
- }`}
52
- >
53
- <div className={styles['code-block__header']}>
54
- <div className={styles['code-block__header__title']}>{language}</div>
55
- <div
56
- className={`${styles['code-block__header__copy']} ${
57
- isCopyMode ? styles['code-block__header__copy--active'] : ''
58
- }`}
59
- onClick={copyToClipboard}
60
- />
61
- </div>
62
- <div className={styles['code-block__wrapper']}>
63
- <SH
24
+ <Suspense
25
+ fallback={
26
+ <CodeBlockStatic
64
27
  language={language}
65
- style={dracula}
66
- showLineNumbers
67
- lineNumberStyle={lineNumberStyle}
68
- >
69
- {code}
70
- </SH>
71
- </div>
72
- </div>
28
+ code={code}
29
+ hasMarginUp={hasMarginUp}
30
+ hasMarginDown={hasMarginDown}
31
+ />
32
+ }
33
+ >
34
+ <CodeBlockDynamic
35
+ language={language}
36
+ code={code}
37
+ hasMarginUp={hasMarginUp}
38
+ hasMarginDown={hasMarginDown}
39
+ />
40
+ </Suspense>
73
41
  );
74
42
  };
75
43