@san-siva/blogkit 1.1.20 → 1.1.21
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 +31 -181
- package/dist/cjs/dynamicComponents/BlogDynamic.js.map +1 -1
- package/dist/cjs/dynamicComponents/BlogSectionDynamic.js +11 -2
- package/dist/cjs/dynamicComponents/BlogSectionDynamic.js.map +1 -1
- package/dist/cjs/hooks/useCategoryTitles.js +104 -0
- package/dist/cjs/hooks/useCategoryTitles.js.map +1 -0
- package/dist/cjs/hooks/useSectionObserver.js +89 -0
- package/dist/cjs/hooks/useSectionObserver.js.map +1 -0
- package/dist/cjs/index.css +1 -1
- package/dist/cjs/index.css.map +1 -1
- package/dist/cjs/staticComponents/TocNodeStatic.js +16 -0
- package/dist/cjs/staticComponents/TocNodeStatic.js.map +1 -0
- package/dist/cjs/styles/Blog.module.scss.js +1 -1
- package/dist/cjs/styles/Callout.module.scss.js +1 -1
- package/dist/cjs/styles/TocNode.module.scss.js +8 -0
- package/dist/cjs/styles/TocNode.module.scss.js.map +1 -0
- package/dist/esm/dynamicComponents/BlogDynamic.js +32 -182
- package/dist/esm/dynamicComponents/BlogDynamic.js.map +1 -1
- package/dist/esm/dynamicComponents/BlogSectionDynamic.js +12 -3
- package/dist/esm/dynamicComponents/BlogSectionDynamic.js.map +1 -1
- package/dist/esm/hooks/useCategoryTitles.js +102 -0
- package/dist/esm/hooks/useCategoryTitles.js.map +1 -0
- package/dist/esm/hooks/useSectionObserver.js +87 -0
- package/dist/esm/hooks/useSectionObserver.js.map +1 -0
- package/dist/esm/index.css +1 -1
- package/dist/esm/index.css.map +1 -1
- package/dist/esm/staticComponents/TocNodeStatic.js +12 -0
- package/dist/esm/staticComponents/TocNodeStatic.js.map +1 -0
- package/dist/esm/styles/Blog.module.scss.js +1 -1
- package/dist/esm/styles/Callout.module.scss.js +1 -1
- package/dist/esm/styles/TocNode.module.scss.js +4 -0
- package/dist/esm/styles/TocNode.module.scss.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/BlogSectionDynamic.d.ts.map +1 -1
- package/dist/types/hooks/useCategoryTitles.d.ts +22 -0
- package/dist/types/hooks/useCategoryTitles.d.ts.map +1 -0
- package/dist/types/hooks/useSectionObserver.d.ts +11 -0
- package/dist/types/hooks/useSectionObserver.d.ts.map +1 -0
- package/dist/types/staticComponents/TocNodeStatic.d.ts +16 -0
- package/dist/types/staticComponents/TocNodeStatic.d.ts.map +1 -0
- package/package.json +5 -3
- package/src/dynamicComponents/BlogDynamic.tsx +42 -253
- package/src/dynamicComponents/BlogSectionDynamic.tsx +16 -2
- package/src/hooks/useCategoryTitles.ts +148 -0
- package/src/hooks/useSectionObserver.ts +102 -0
- package/src/staticComponents/TocNodeStatic.tsx +52 -0
- package/src/styles/Blog.module.scss +0 -30
- package/src/styles/Blog.module.scss.d.ts +0 -4
- package/src/styles/BlogLink.module.scss +1 -1
- package/src/styles/BlogSection.module.scss +36 -13
- package/src/styles/CodeBlock.module.scss +2 -2
- package/src/styles/Table.module.scss +1 -1
- package/src/styles/TocNode.module.scss +49 -0
- package/src/styles/TocNode.module.scss.d.ts +11 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import type { Dispatch, SetStateAction } from 'react';
|
|
6
|
+
|
|
7
|
+
import type { ForwardedReference } from '../dynamicComponents/BlogDynamic';
|
|
8
|
+
|
|
9
|
+
export interface SectionReferenceValue {
|
|
10
|
+
el: HTMLElement;
|
|
11
|
+
title: string;
|
|
12
|
+
depth: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface CategoryTitleValue extends SectionReferenceValue {
|
|
16
|
+
lastUpdatedAt: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type CategoryTitle = Map<string, CategoryTitleValue>;
|
|
20
|
+
|
|
21
|
+
type SectionReference = Map<string, SectionReferenceValue>;
|
|
22
|
+
|
|
23
|
+
interface Options {
|
|
24
|
+
visibleTitle: string | null;
|
|
25
|
+
setVisibleTitle: Dispatch<SetStateAction<string | null>>;
|
|
26
|
+
setShowTOC: Dispatch<SetStateAction<boolean>>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function useCategoryTitles({
|
|
30
|
+
visibleTitle,
|
|
31
|
+
setVisibleTitle,
|
|
32
|
+
setShowTOC,
|
|
33
|
+
}: Options) {
|
|
34
|
+
const sectionReferences = useRef<SectionReference>(new Map());
|
|
35
|
+
const [categoryTitles, setCategoryTitles] = useState<CategoryTitle>(
|
|
36
|
+
new Map()
|
|
37
|
+
);
|
|
38
|
+
const updateTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
39
|
+
|
|
40
|
+
const sortByDomPosition = useCallback(
|
|
41
|
+
(
|
|
42
|
+
[, a]: [string, SectionReferenceValue],
|
|
43
|
+
[, b]: [string, SectionReferenceValue]
|
|
44
|
+
) => {
|
|
45
|
+
const position = a.el.compareDocumentPosition(b.el);
|
|
46
|
+
if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
47
|
+
return -1;
|
|
48
|
+
} else if (position & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
49
|
+
return 1;
|
|
50
|
+
}
|
|
51
|
+
return 0;
|
|
52
|
+
},
|
|
53
|
+
[]
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const updateCategoryTitles = useCallback(() => {
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
const newCategoryTitles = new Map<string, CategoryTitleValue>();
|
|
59
|
+
|
|
60
|
+
const sectionsArray = Array.from(sectionReferences.current.entries());
|
|
61
|
+
sectionsArray.sort(sortByDomPosition);
|
|
62
|
+
|
|
63
|
+
let firstSectionId: string | null = null;
|
|
64
|
+
for (const [id, { title, el, depth }] of sectionsArray) {
|
|
65
|
+
if (!firstSectionId) {
|
|
66
|
+
firstSectionId = id;
|
|
67
|
+
}
|
|
68
|
+
newCategoryTitles.set(id, {
|
|
69
|
+
el,
|
|
70
|
+
title,
|
|
71
|
+
lastUpdatedAt: now,
|
|
72
|
+
depth,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (newCategoryTitles.size === 0) return;
|
|
77
|
+
|
|
78
|
+
setCategoryTitles(newCategoryTitles);
|
|
79
|
+
setShowTOC(true);
|
|
80
|
+
|
|
81
|
+
if (visibleTitle) return;
|
|
82
|
+
setVisibleTitle(firstSectionId);
|
|
83
|
+
}, [visibleTitle, sortByDomPosition, setShowTOC, setVisibleTitle]);
|
|
84
|
+
|
|
85
|
+
const debounceUpdateCategoryTitles = useCallback(() => {
|
|
86
|
+
if (updateTimerRef.current) {
|
|
87
|
+
clearTimeout(updateTimerRef.current);
|
|
88
|
+
}
|
|
89
|
+
updateTimerRef.current = setTimeout(() => {
|
|
90
|
+
updateCategoryTitles();
|
|
91
|
+
}, 200);
|
|
92
|
+
}, [updateCategoryTitles]);
|
|
93
|
+
|
|
94
|
+
const removeStaleRefs = (ref: HTMLDivElement) => {
|
|
95
|
+
for (const [existingId, { el }] of sectionReferences.current) {
|
|
96
|
+
if (el !== ref) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
sectionReferences.current.delete(existingId);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const handleCategoryTitle = (ref: HTMLDivElement) => {
|
|
105
|
+
const id = ref.dataset.id;
|
|
106
|
+
const title = ref.dataset.title;
|
|
107
|
+
if (!id || !title) return;
|
|
108
|
+
|
|
109
|
+
let depth = 0;
|
|
110
|
+
let parent = ref.parentElement;
|
|
111
|
+
while (parent) {
|
|
112
|
+
if (parent.hasAttribute('data-id')) depth++;
|
|
113
|
+
parent = parent.parentElement;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
removeStaleRefs(ref);
|
|
117
|
+
sectionReferences.current.set(id, { el: ref, title, depth });
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const processSection = (element: ForwardedReference) => {
|
|
121
|
+
const { parentRef, childRefs } = element;
|
|
122
|
+
if (parentRef) handleCategoryTitle(parentRef);
|
|
123
|
+
if (Array.isArray(childRefs)) {
|
|
124
|
+
for (const childRef of childRefs) {
|
|
125
|
+
processSection(childRef);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const handleSectionReference = useCallback(
|
|
131
|
+
(element: ForwardedReference) => {
|
|
132
|
+
if (!element) return;
|
|
133
|
+
processSection(element);
|
|
134
|
+
debounceUpdateCategoryTitles();
|
|
135
|
+
},
|
|
136
|
+
[debounceUpdateCategoryTitles]
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
return () => {
|
|
141
|
+
if (updateTimerRef.current) {
|
|
142
|
+
clearTimeout(updateTimerRef.current);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}, []);
|
|
146
|
+
|
|
147
|
+
return { categoryTitles, handleSectionReference };
|
|
148
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
4
|
+
|
|
5
|
+
import type { Dispatch, MouseEvent, SetStateAction } from 'react';
|
|
6
|
+
|
|
7
|
+
import lockScrollUpdates from '../utils/lockScrollUpdates';
|
|
8
|
+
import type { CategoryTitle } from './useCategoryTitles';
|
|
9
|
+
|
|
10
|
+
const getSectionFromUrl = () => {
|
|
11
|
+
const url = new URL(window.location.href);
|
|
12
|
+
return url.searchParams.get('section');
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const updateUrl = (id: string) => {
|
|
16
|
+
const url = new URL(window.location.href);
|
|
17
|
+
url.searchParams.set('section', id);
|
|
18
|
+
window.history.replaceState({}, '', url.toString());
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const scrollIntoView = (element: HTMLElement) => {
|
|
22
|
+
if (!element) return;
|
|
23
|
+
const top =
|
|
24
|
+
element.getBoundingClientRect().top + document.body.scrollTop - 100;
|
|
25
|
+
document.body.scrollTo({ top, behavior: 'smooth' });
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
interface Options {
|
|
29
|
+
categoryTitles: CategoryTitle;
|
|
30
|
+
setVisibleTitle: Dispatch<SetStateAction<string | null>>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function useSectionObserver({ categoryTitles, setVisibleTitle }: Options) {
|
|
34
|
+
const isClickScrolling = useRef(false);
|
|
35
|
+
const scrollEndHandlerRef = useRef<(() => void) | null>(null);
|
|
36
|
+
const intersectionObserversRef = useRef<Map<string, IntersectionObserver>>(
|
|
37
|
+
new Map()
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Set up IntersectionObservers whenever the set of sections changes
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
for (const [id, { el }] of categoryTitles) {
|
|
43
|
+
const observer = new IntersectionObserver(
|
|
44
|
+
([entry]) => {
|
|
45
|
+
if (!entry.isIntersecting) return;
|
|
46
|
+
if (isClickScrolling.current) return;
|
|
47
|
+
if (document.body.scrollTop === 0) return;
|
|
48
|
+
setVisibleTitle(visibleId => {
|
|
49
|
+
if (visibleId === id && !entry.isIntersecting) return null;
|
|
50
|
+
if (entry.isIntersecting) return id;
|
|
51
|
+
return visibleId;
|
|
52
|
+
});
|
|
53
|
+
updateUrl(id);
|
|
54
|
+
},
|
|
55
|
+
{ threshold: 0.1 }
|
|
56
|
+
);
|
|
57
|
+
intersectionObserversRef.current.set(id, observer);
|
|
58
|
+
observer.observe(el as HTMLElement);
|
|
59
|
+
}
|
|
60
|
+
}, [categoryTitles.size, setVisibleTitle]);
|
|
61
|
+
|
|
62
|
+
// On initial load, scroll to section specified in URL
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (categoryTitles.size === 0) return;
|
|
65
|
+
const section = getSectionFromUrl();
|
|
66
|
+
if (!section) return;
|
|
67
|
+
const entry = categoryTitles.get(section);
|
|
68
|
+
if (!entry) return;
|
|
69
|
+
scrollIntoView(entry.el);
|
|
70
|
+
lockScrollUpdates(section, isClickScrolling, scrollEndHandlerRef, setVisibleTitle);
|
|
71
|
+
}, [categoryTitles.size, setVisibleTitle]);
|
|
72
|
+
|
|
73
|
+
// Cleanup observers on unmount
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
return () => {
|
|
76
|
+
if (scrollEndHandlerRef.current) {
|
|
77
|
+
document.body.removeEventListener('scrollend', scrollEndHandlerRef.current);
|
|
78
|
+
}
|
|
79
|
+
for (const observer of intersectionObserversRef.current.values()) {
|
|
80
|
+
observer.disconnect();
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}, []);
|
|
84
|
+
|
|
85
|
+
const handleClickCategoryTitle = useCallback(
|
|
86
|
+
(event: MouseEvent<HTMLParagraphElement>) => {
|
|
87
|
+
const id = event.currentTarget.dataset.id;
|
|
88
|
+
const index = event.currentTarget.dataset.idx;
|
|
89
|
+
if (!id || !index) return;
|
|
90
|
+
|
|
91
|
+
const { el } = categoryTitles.get(id) || {};
|
|
92
|
+
if (!el) return;
|
|
93
|
+
|
|
94
|
+
updateUrl(id);
|
|
95
|
+
scrollIntoView(el);
|
|
96
|
+
lockScrollUpdates(id, isClickScrolling, scrollEndHandlerRef, setVisibleTitle);
|
|
97
|
+
},
|
|
98
|
+
[categoryTitles, setVisibleTitle]
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
return { handleClickCategoryTitle };
|
|
102
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { MouseEvent } from 'react';
|
|
2
|
+
|
|
3
|
+
import styles from '../styles/TocNode.module.scss';
|
|
4
|
+
|
|
5
|
+
export interface TocNode {
|
|
6
|
+
id: string;
|
|
7
|
+
title: string;
|
|
8
|
+
depth: number;
|
|
9
|
+
children: TocNode[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface TocNodeProperties {
|
|
13
|
+
node: TocNode;
|
|
14
|
+
index: number;
|
|
15
|
+
visibleTitle: string | null;
|
|
16
|
+
onClick: (e: MouseEvent<HTMLParagraphElement>) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const TocNode = ({ node, index, visibleTitle, onClick }: TocNodeProperties) => (
|
|
20
|
+
<div>
|
|
21
|
+
<p
|
|
22
|
+
data-idx={index}
|
|
23
|
+
data-id={node.id}
|
|
24
|
+
className={[
|
|
25
|
+
styles['toc-node__title'],
|
|
26
|
+
node.id === visibleTitle ? styles['toc-node__title--active'] : '',
|
|
27
|
+
node.depth === 1 ? styles['toc-node__title--sub'] : '',
|
|
28
|
+
node.depth === 2 ? styles['toc-node__title--sub-sub'] : '',
|
|
29
|
+
].join(' ')}
|
|
30
|
+
onClick={onClick}
|
|
31
|
+
>
|
|
32
|
+
{node.title}
|
|
33
|
+
</p>
|
|
34
|
+
{node.children.length > 0 && (
|
|
35
|
+
<div
|
|
36
|
+
className={`${styles['toc-node__children']} ${styles[`toc-node__children--${node.depth === 0 ? 'sub' : 'sub-sub'}`]}`}
|
|
37
|
+
>
|
|
38
|
+
{node.children.map((child, i) => (
|
|
39
|
+
<TocNode
|
|
40
|
+
key={child.id}
|
|
41
|
+
node={child}
|
|
42
|
+
index={i}
|
|
43
|
+
visibleTitle={visibleTitle}
|
|
44
|
+
onClick={onClick}
|
|
45
|
+
/>
|
|
46
|
+
))}
|
|
47
|
+
</div>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
export default TocNode;
|
|
@@ -22,36 +22,6 @@
|
|
|
22
22
|
padding-top: $top;
|
|
23
23
|
padding-right: 0;
|
|
24
24
|
border-radius: styles.$border-radius--1;
|
|
25
|
-
|
|
26
|
-
> .category__title {
|
|
27
|
-
display: block;
|
|
28
|
-
margin-bottom: styles.space(1);
|
|
29
|
-
font-size: styles.$font-size--p-small;
|
|
30
|
-
font-weight: styles.$font-weight--500;
|
|
31
|
-
cursor: pointer;
|
|
32
|
-
|
|
33
|
-
animation: fadeInDown 0.3s ease-in-out;
|
|
34
|
-
transition: all 0.3s ease-in-out;
|
|
35
|
-
|
|
36
|
-
&--active,
|
|
37
|
-
&:hover {
|
|
38
|
-
text-decoration: underline;
|
|
39
|
-
text-decoration-color: styles.$color--primary;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
&--active {
|
|
43
|
-
color: styles.$color--primary;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
&--sub {
|
|
47
|
-
font-size: styles.$font-size--small;
|
|
48
|
-
font-weight: styles.$font-weight--400;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
&:last-child {
|
|
52
|
-
margin-bottom: 0;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
25
|
}
|
|
56
26
|
}
|
|
57
27
|
|
|
@@ -3,11 +3,7 @@ declare const styles: {
|
|
|
3
3
|
readonly 'blog__content': string;
|
|
4
4
|
readonly 'blog__sidebar': string;
|
|
5
5
|
readonly 'margin-bottom--3': string;
|
|
6
|
-
readonly 'margin-bottom-imp--2': string;
|
|
7
6
|
readonly 'category__header': string;
|
|
8
|
-
readonly 'category__title': string;
|
|
9
|
-
readonly 'category__title--active': string;
|
|
10
|
-
readonly 'category__title--sub': string;
|
|
11
7
|
};
|
|
12
8
|
|
|
13
9
|
export default styles;
|
|
@@ -18,23 +18,46 @@
|
|
|
18
18
|
text-decoration-color: stylekit.$color--primary;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
}
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
// Sub-section (depth 1)
|
|
23
|
+
.blog-section {
|
|
24
|
+
> .blog-section__title {
|
|
25
|
+
font-size: stylekit.$font-size--h6;
|
|
26
|
+
margin-bottom: stylekit.space(2);
|
|
27
|
+
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
29
|
+
> *:first-child {
|
|
30
|
+
margin-top: stylekit.space(4);
|
|
31
|
+
}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
33
|
+
&:not(:last-child) {
|
|
34
|
+
margin-bottom: stylekit.space(4);
|
|
35
|
+
}
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
&:last-child {
|
|
38
|
+
margin-bottom: stylekit.space(8);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Sub-sub-section (depth 2)
|
|
42
|
+
.blog-section {
|
|
43
|
+
> .blog-section__title {
|
|
44
|
+
font-size: stylekit.$font-size--p;
|
|
45
|
+
margin-bottom: stylekit.space(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
> *:first-child {
|
|
49
|
+
margin-top: stylekit.space(2);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&:not(:last-child) {
|
|
53
|
+
margin-bottom: stylekit.space(2);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&:last-child {
|
|
57
|
+
margin-bottom: stylekit.space(4);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
38
61
|
}
|
|
39
62
|
|
|
40
63
|
.margin-bottom--6 {
|
|
@@ -62,7 +62,7 @@ $code-block-background-color: #282a36;
|
|
|
62
62
|
> code,
|
|
63
63
|
> code > * {
|
|
64
64
|
font-family: stylekit.$font-family--code;
|
|
65
|
-
font-size: stylekit.$font-size--
|
|
65
|
+
font-size: stylekit.$font-size--small;
|
|
66
66
|
font-weight: unset;
|
|
67
67
|
font-style: unset;
|
|
68
68
|
line-height: stylekit.$line-height--normal;
|
|
@@ -120,5 +120,5 @@ $code-block-background-color: #282a36;
|
|
|
120
120
|
.code-block--static code {
|
|
121
121
|
color: stylekit.$color--base !important;
|
|
122
122
|
font-family: stylekit.$font-family--code !important;
|
|
123
|
-
font-size: stylekit.$font-size--
|
|
123
|
+
font-size: stylekit.$font-size--small !important;
|
|
124
124
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
@use '@san-siva/stylekit/styles/index.module.scss' as styles;
|
|
2
|
+
|
|
3
|
+
.toc-node {
|
|
4
|
+
&__title {
|
|
5
|
+
display: block;
|
|
6
|
+
margin-bottom: styles.space(1);
|
|
7
|
+
font-size: styles.$font-size--small;
|
|
8
|
+
font-weight: styles.$font-weight--500;
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
|
|
11
|
+
animation: fadeInDown 0.3s ease-in-out;
|
|
12
|
+
transition: all 0.3s ease-in-out;
|
|
13
|
+
|
|
14
|
+
&--active,
|
|
15
|
+
&:hover {
|
|
16
|
+
text-decoration: underline;
|
|
17
|
+
text-decoration-color: styles.$color--primary;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&--active {
|
|
21
|
+
color: styles.$color--primary;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&--sub {
|
|
25
|
+
font-size: styles.$font-size--very-small;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&--sub-sub {
|
|
29
|
+
font-size: styles.$font-size--very-small;
|
|
30
|
+
font-weight: styles.$font-weight--400;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&:not(:last-child) {
|
|
34
|
+
margin-bottom: 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&__children {
|
|
39
|
+
&--sub-sub,
|
|
40
|
+
&--sub {
|
|
41
|
+
padding: styles.space(1) styles.space(2);
|
|
42
|
+
margin: styles.space(1);
|
|
43
|
+
border-left: 1px solid styles.$color--border;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&--sub-sub {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const styles: {
|
|
2
|
+
readonly 'toc-node__title': string;
|
|
3
|
+
readonly 'toc-node__title--active': string;
|
|
4
|
+
readonly 'toc-node__title--sub': string;
|
|
5
|
+
readonly 'toc-node__title--sub-sub': string;
|
|
6
|
+
readonly 'toc-node__children': string;
|
|
7
|
+
readonly 'toc-node__children--sub': string;
|
|
8
|
+
readonly 'toc-node__children--sub-sub': string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default styles;
|