@staticbolt/docs 0.0.1-beta.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 (94) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +148 -0
  3. package/lib/collapsible-plugin-Bwt7dmKE.mjs +132 -0
  4. package/lib/ec-config.mjs +59 -0
  5. package/lib/ec.config.d.mts +5 -0
  6. package/lib/index.d.mts +371 -0
  7. package/lib/plugins.mjs +0 -0
  8. package/package.json +113 -0
  9. package/sources/assets/fonts/KaTeX_AMS-Regular.ttf +0 -0
  10. package/sources/assets/fonts/KaTeX_AMS-Regular.woff +0 -0
  11. package/sources/assets/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  12. package/sources/assets/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  13. package/sources/assets/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  14. package/sources/assets/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  15. package/sources/assets/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  16. package/sources/assets/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  17. package/sources/assets/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  18. package/sources/assets/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  19. package/sources/assets/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  20. package/sources/assets/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  21. package/sources/assets/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  22. package/sources/assets/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  23. package/sources/assets/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  24. package/sources/assets/fonts/KaTeX_Main-Bold.ttf +0 -0
  25. package/sources/assets/fonts/KaTeX_Main-Bold.woff +0 -0
  26. package/sources/assets/fonts/KaTeX_Main-Bold.woff2 +0 -0
  27. package/sources/assets/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  28. package/sources/assets/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  29. package/sources/assets/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  30. package/sources/assets/fonts/KaTeX_Main-Italic.ttf +0 -0
  31. package/sources/assets/fonts/KaTeX_Main-Italic.woff +0 -0
  32. package/sources/assets/fonts/KaTeX_Main-Italic.woff2 +0 -0
  33. package/sources/assets/fonts/KaTeX_Main-Regular.ttf +0 -0
  34. package/sources/assets/fonts/KaTeX_Main-Regular.woff +0 -0
  35. package/sources/assets/fonts/KaTeX_Main-Regular.woff2 +0 -0
  36. package/sources/assets/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  37. package/sources/assets/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  38. package/sources/assets/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  39. package/sources/assets/fonts/KaTeX_Math-Italic.ttf +0 -0
  40. package/sources/assets/fonts/KaTeX_Math-Italic.woff +0 -0
  41. package/sources/assets/fonts/KaTeX_Math-Italic.woff2 +0 -0
  42. package/sources/assets/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  43. package/sources/assets/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  44. package/sources/assets/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  45. package/sources/assets/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  46. package/sources/assets/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  47. package/sources/assets/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  48. package/sources/assets/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  49. package/sources/assets/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  50. package/sources/assets/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  51. package/sources/assets/fonts/KaTeX_Script-Regular.ttf +0 -0
  52. package/sources/assets/fonts/KaTeX_Script-Regular.woff +0 -0
  53. package/sources/assets/fonts/KaTeX_Script-Regular.woff2 +0 -0
  54. package/sources/assets/fonts/KaTeX_Size1-Regular.ttf +0 -0
  55. package/sources/assets/fonts/KaTeX_Size1-Regular.woff +0 -0
  56. package/sources/assets/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  57. package/sources/assets/fonts/KaTeX_Size2-Regular.ttf +0 -0
  58. package/sources/assets/fonts/KaTeX_Size2-Regular.woff +0 -0
  59. package/sources/assets/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  60. package/sources/assets/fonts/KaTeX_Size3-Regular.ttf +0 -0
  61. package/sources/assets/fonts/KaTeX_Size3-Regular.woff +0 -0
  62. package/sources/assets/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  63. package/sources/assets/fonts/KaTeX_Size4-Regular.ttf +0 -0
  64. package/sources/assets/fonts/KaTeX_Size4-Regular.woff +0 -0
  65. package/sources/assets/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  66. package/sources/assets/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  67. package/sources/assets/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  68. package/sources/assets/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  69. package/sources/parts/badge/badge.part.html +3 -0
  70. package/sources/parts/badge/badge.style.css +44 -0
  71. package/sources/parts/callouts/callouts.part.html +30 -0
  72. package/sources/parts/color-scheme-switch/color-scheme-switch.part.html +111 -0
  73. package/sources/parts/color-scheme-switch/color-scheme-switch.style.css +77 -0
  74. package/sources/parts/document/document.part.html +66 -0
  75. package/sources/parts/header/header.part.html +62 -0
  76. package/sources/parts/header/header.style.css +123 -0
  77. package/sources/parts/mermaid/mermaid.part.html +15 -0
  78. package/sources/parts/pagefind/pagefind.part.html +75 -0
  79. package/sources/parts/pagefind/pagefind.style.css +57 -0
  80. package/sources/parts/pagination-links/pagination-links.part.html +81 -0
  81. package/sources/parts/pagination-links/pagination-links.style.css +58 -0
  82. package/sources/parts/sidebar/directory.part.html +13 -0
  83. package/sources/parts/sidebar/item.part.html +9 -0
  84. package/sources/parts/sidebar/sidebar.part.html +106 -0
  85. package/sources/parts/sidebar/sidebar.style.css +202 -0
  86. package/sources/parts/table-of-content/table-of-content-desktop.part.html +122 -0
  87. package/sources/parts/table-of-content/table-of-content-mobile.part.html +24 -0
  88. package/sources/parts/table-of-content/table-of-content.style.css +189 -0
  89. package/sources/scripts/global.d.ts +27 -0
  90. package/sources/scripts/mermaid.ts +75 -0
  91. package/sources/styles/docs.css +9 -0
  92. package/sources/styles/document.css +579 -0
  93. package/sources/styles/global.css +149 -0
  94. package/sources/styles/katex.css +1445 -0
@@ -0,0 +1,81 @@
1
+ <div class="pagination-links">
2
+ <a class="pagination-link-prev" href="#" rel="prev">
3
+ <span class="link-label">
4
+ <svg aria-hidden="true" viewBox="0 0 24 24">
5
+ <path
6
+ d="M17 11H9.41l3.3-3.29a1.004 1.004 0 1 0-1.42-1.42l-5 5a1 1 0 0 0-.21.33 1 1 0 0 0 0 .76 1 1 0 0 0 .21.33l5 5a1.002 1.002 0 0 0 1.639-.325 1 1 0 0 0-.219-1.095L9.41 13H17a1 1 0 0 0 0-2Z"
7
+ ></path>
8
+ </svg>
9
+ Previous
10
+ </span>
11
+ <span class="link-title"></span>
12
+ </a>
13
+
14
+ <a class="pagination-link-next" href="#" rel="next">
15
+ <span class="link-label">
16
+ Next
17
+ <svg aria-hidden="true" viewBox="0 0 24 24">
18
+ <path
19
+ d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"
20
+ ></path>
21
+ </svg>
22
+ </span>
23
+ <span class="link-title"></span>
24
+ </a>
25
+ </div>
26
+
27
+ <!-- This script will run once at build time for each page -->
28
+ <script type="module" build-time>
29
+ // ::: Get current link and populate previous/next links :::
30
+ import { join, dirname, normalize } from "node:path";
31
+
32
+ const paginationPrev = document.querySelector(".pagination-link-prev");
33
+ const paginationPrevTitle = paginationPrev.querySelector(".link-title");
34
+
35
+ const paginationNext = document.querySelector(".pagination-link-next");
36
+ const paginationNextTitle = paginationNext.querySelector(".link-title");
37
+
38
+ // You can find `.sidebar` in the documentation layout
39
+ const navigationLinks = document.querySelectorAll(".sidebar a.sidebar-link");
40
+ const currentFile = normalize(__filepath);
41
+
42
+ let nextLinkFound = false;
43
+ let previousLinkFound = false;
44
+
45
+ for (const [linkIndex, link] of navigationLinks.entries()) {
46
+ const linkPath = join(dirname(__filepath), link.attributes.href, "index.html");
47
+ if (linkPath !== currentFile) continue;
48
+
49
+ // Previous
50
+ const previousLink = navigationLinks[linkIndex - 1];
51
+ if (previousLink) {
52
+ const prevHref = previousLink.getAttribute("href");
53
+ paginationPrev.setAttribute("href", prevHref);
54
+
55
+ const prevTitle = previousLink.getAttribute("data-title") || previousLink.textContent;
56
+ paginationPrevTitle.textContent = prevTitle;
57
+
58
+ previousLinkFound = true;
59
+ }
60
+
61
+ // Next
62
+ const nextLink = navigationLinks[linkIndex + 1];
63
+ if (nextLink) {
64
+ const nextHref = nextLink.getAttribute("href");
65
+ paginationNext.setAttribute("href", nextHref);
66
+
67
+ const nextTitle = nextLink.getAttribute("data-title") || nextLink.textContent;
68
+ paginationNextTitle.textContent = nextTitle;
69
+
70
+ nextLinkFound = true;
71
+ }
72
+ }
73
+
74
+ if (!nextLinkFound) {
75
+ paginationNext.remove();
76
+ }
77
+
78
+ if (!previousLinkFound) {
79
+ paginationPrev.remove();
80
+ }
81
+ </script>
@@ -0,0 +1,58 @@
1
+ .pagination-links {
2
+ display: flex;
3
+ flex-flow: row wrap;
4
+ gap: 0.5em;
5
+ justify-content: space-between;
6
+ padding-block-start: 1.5em;
7
+ margin-block-start: 3em;
8
+ border-block-start: solid 1px var(--sb-color-gray-5);
9
+
10
+ @media print {
11
+ display: none;
12
+ }
13
+
14
+ .pagination-link-prev,
15
+ .pagination-link-next {
16
+ display: flex;
17
+ flex: 1;
18
+ flex-direction: column;
19
+ min-inline-size: 200px;
20
+ text-decoration: none;
21
+
22
+ &[rel="next"] {
23
+ align-items: flex-end;
24
+ }
25
+
26
+ &[rel="prev"] {
27
+ align-items: flex-start;
28
+ }
29
+
30
+ .link-label {
31
+ display: flex;
32
+ gap: 0.15rem;
33
+ align-items: center;
34
+ font-size: var(--sb-text-sm);
35
+ color: var(--sb-color-gray-3);
36
+
37
+ svg {
38
+ inline-size: 1em;
39
+ block-size: 1em;
40
+ fill: currentcolor;
41
+
42
+ [dir="rtl"] & {
43
+ transform: rotate(180deg);
44
+ }
45
+ }
46
+ }
47
+
48
+ .link-title {
49
+ margin-inline: 0.25rem;
50
+ font-weight: 600;
51
+ color: var(--sb-color-gray-2);
52
+ }
53
+ }
54
+ }
55
+
56
+ [data-pagefind-announcer] {
57
+ margin: -1px;
58
+ }
@@ -0,0 +1,13 @@
1
+ <sv-accordion class="sidebar-accordion" add-attr-opened="{{ !$data.collapsed }}" heading-level="none" marker="start">
2
+ <span slot="summary">
3
+ {{ $data.iconSrc ? `
4
+ <icon src="${ $data.iconSrc }"></icon>
5
+ ` : ""}}
6
+
7
+ <!-- Title -->
8
+ {{ $data.title }}
9
+ </span>
10
+
11
+ <!-- Items -->
12
+ <slot></slot>
13
+ </sv-accordion>
@@ -0,0 +1,9 @@
1
+ <a class="sidebar-link" data-title="{{ $data.fullTitle }}" href="{{ $data.href }}">
2
+ {{ $data.iconSrc ? `
3
+ <icon src="${ $data.iconSrc }"></icon>
4
+ ` : ""}}
5
+ <!-- Title -->
6
+ {{ $data.title }} {{ ($data.badgeVariant && $data.badgeText) ? `
7
+ <part src="../badge/badge.part.html" text="${$data.badgeText}" variant="${$data.badgeVariant}"></part>
8
+ ` : "" }}
9
+ </a>
@@ -0,0 +1,106 @@
1
+ <div class="sidebar">
2
+ <nav aria-label="Sidebar navigation">
3
+ <slot name="sidebar"></slot>
4
+ </nav>
5
+
6
+ <div class="sidebar-footer">
7
+ <div class="sidebar-social-icons">
8
+ <slot name="icons"></slot>
9
+ </div>
10
+
11
+ <div class="sidebar-color-scheme-switcher">
12
+ <part src="../color-scheme-switch/color-scheme-switch.part.html"></part>
13
+ </div>
14
+ </div>
15
+ </div>
16
+
17
+ <script type="module" build-time>
18
+ import { join, dirname, normalize } from "node:path";
19
+
20
+ // ::: Mark current page links as active and expand matching accordions. :::
21
+
22
+ const navigationLinks = document.querySelectorAll(".sidebar a");
23
+ const currentFile = normalize(__filepath);
24
+
25
+ for (const [linkIndex, link] of navigationLinks.entries()) {
26
+ const linkPath = join(dirname(__filepath), link.attributes.href, "index.html");
27
+ if (linkPath !== currentFile) continue;
28
+
29
+ link.classList.add("active");
30
+ link.setAttribute("aria-current", "page");
31
+
32
+ // Open all parent accordions
33
+ let parent = link.parentNode;
34
+ while (parent) {
35
+ if (parent.classList?.contains("sidebar-accordion")) {
36
+ parent.setAttribute("opened", "");
37
+ }
38
+
39
+ parent = parent.parentNode;
40
+ }
41
+ }
42
+ </script>
43
+
44
+ <!-- ::: Persist sidebar navigation state across page loads. ::: -->
45
+ <script>
46
+ (() => {
47
+ /** @type {NodeListOf<HTMLDivElement>} */
48
+ const accordions = document.querySelectorAll(".sidebar-accordion");
49
+
50
+ // ::: Restore the accordion's previous open state. :::
51
+ try {
52
+ const state = JSON.parse(sessionStorage.getItem("sidebar-state") ?? {});
53
+
54
+ for (const [accordionIndex, opened] of Object.entries(state)) {
55
+ const accordion = /** @type {HTMLDivElement} */ (accordions[accordionIndex]);
56
+ if (!accordion) continue;
57
+
58
+ // Keep accordions containing the active link expanded by default
59
+ // to preserve navigation context and visibility of the current page.
60
+ if (accordion.matches(":has(a.active)")) continue;
61
+
62
+ // Toggle the accordion instantly without animation.
63
+ accordion[opened ? "open" : "close"](true);
64
+ }
65
+ } catch {
66
+ // ignore
67
+ }
68
+
69
+ // ::: Save accordion open state when toggled. :::
70
+ const accordionToggleHandler = () => {
71
+ const state = {};
72
+
73
+ for (const [accordionIndex, accordion] of accordions.entries()) {
74
+ state[accordionIndex] = accordion.opened;
75
+ }
76
+
77
+ sessionStorage.setItem("sidebar-state", JSON.stringify(state));
78
+ };
79
+
80
+ for (const accordion of accordions) {
81
+ accordion.addEventListener("toggled", accordionToggleHandler);
82
+ }
83
+
84
+ // ::: Restore sidebar scroll position. :::
85
+ const sidebar = document.querySelector(".sidebar");
86
+
87
+ const onReady = () => {
88
+ // First rAF: end of current task, second rAF: after first paint
89
+ requestAnimationFrame(() => {
90
+ requestAnimationFrame(() => {
91
+ const saved = sessionStorage.getItem("sidebar-scroll");
92
+ if (saved) sidebar.scrollTop = +saved;
93
+ });
94
+ });
95
+ };
96
+
97
+ document.addEventListener("DOMContentLoaded", onReady, { once: true });
98
+
99
+ // ::: Save sidebar scroll position. :::
100
+ const sidebarScrollHandler = () => {
101
+ sessionStorage.setItem("sidebar-scroll", sidebar.scrollTop);
102
+ };
103
+
104
+ sidebar.addEventListener("scroll", sidebarScrollHandler, { passive: true });
105
+ })();
106
+ </script>
@@ -0,0 +1,202 @@
1
+ .sidebar {
2
+ position: sticky;
3
+ inset-block-start: var(--sb-header-height);
4
+ display: flex;
5
+ flex-direction: column;
6
+ align-items: flex-end;
7
+ justify-content: space-between;
8
+ min-inline-size: 18rem;
9
+ block-size: 100%;
10
+ max-block-size: calc(100svh - var(--sb-header-height));
11
+ padding-inline: 0.8em 0.1em;
12
+ overflow-y: auto;
13
+ scrollbar-gutter: stable;
14
+ overscroll-behavior: contain;
15
+ scrollbar-color: var(--sb-color-gray-5) transparent;
16
+ scrollbar-width: thin;
17
+ background-color: var(--sb-color-black);
18
+ border-inline-end: solid 1px var(--sb-color-gray-5);
19
+
20
+ & > nav {
21
+ flex: 1;
22
+ }
23
+
24
+ .sidebar-item-icon {
25
+ display: block;
26
+ inline-size: 1em;
27
+ block-size: 1em;
28
+
29
+ &:not(.no-fill) {
30
+ fill: var(--sb-color-gray-4);
31
+ }
32
+ }
33
+
34
+ .sidebar-list {
35
+ padding: 0;
36
+ margin: 0;
37
+ list-style: none;
38
+ }
39
+
40
+ .sidebar-accordion {
41
+ --sv-toggle-dur: 200ms;
42
+ --sv-gray-6: transparent;
43
+ --sv-gray-5: transparent;
44
+
45
+ &::part(trigger) {
46
+ padding-block: 0.35em;
47
+ font-family: var(--sb-md-font);
48
+ font-size: var(--sb-text-base);
49
+ font-weight: 600;
50
+ color: var(--sb-color-gray-0);
51
+ }
52
+
53
+ &::part(marker) {
54
+ color: var(--sb-color-gray-2);
55
+ }
56
+
57
+ &::part(content) {
58
+ padding-inline: 0;
59
+ margin-inline-start: calc(1lh - 2px);
60
+ border-inline-start: solid 1px var(--sb-color-gray-5);
61
+ }
62
+
63
+ &:has(.sidebar-link.active) {
64
+ & > span[slot="summary"] {
65
+ &::before {
66
+ position: absolute;
67
+ inset-inline-start: 0;
68
+ inline-size: 4px;
69
+ block-size: 4px;
70
+ content: "";
71
+ background-color: var(--sb-color-accent);
72
+ border-radius: 50%;
73
+ }
74
+
75
+ .sidebar-item-icon:not(.no-fill) {
76
+ fill: var(--sb-color-accent-high);
77
+ }
78
+ }
79
+ }
80
+
81
+ span[slot="summary"] {
82
+ position: relative;
83
+ display: flex;
84
+ flex-direction: row;
85
+ gap: 0.5em;
86
+ align-items: center;
87
+ }
88
+
89
+ @media (pointer: fine) {
90
+ &::part(trigger):hover {
91
+ color: var(--sb-color-accent-high);
92
+ }
93
+
94
+ &:hover:not(:has(&:hover))::part(content) {
95
+ border-inline-start: solid 1px var(--sb-color-accent-high);
96
+ }
97
+ }
98
+ }
99
+
100
+ .sidebar-link {
101
+ display: flex;
102
+ flex-direction: row;
103
+ gap: 0.5em;
104
+ align-items: center;
105
+ padding: 0.3em 1.4em;
106
+ margin-inline-start: -0.5px;
107
+ font-family: var(--sb-md-font);
108
+ font-size: var(--sb-text-sm);
109
+ line-height: 1.4;
110
+ color: var(--sb-color-gray-2);
111
+ text-decoration: none;
112
+ border-inline-start: solid 1px transparent;
113
+ border-start-end-radius: 5px;
114
+ border-end-end-radius: 5px;
115
+
116
+ @media (pointer: fine) {
117
+ &:hover {
118
+ color: var(--sb-color-accent-high);
119
+ }
120
+ }
121
+
122
+ &.active {
123
+ color: var(--sb-color-accent-high);
124
+ background-color: var(--sb-color-gray-6);
125
+ border-inline-start: solid 1px var(--sb-color-accent-high);
126
+ }
127
+ }
128
+
129
+ .sidebar-list:first-child {
130
+ align-self: flex-start;
131
+ padding-block: 1em;
132
+
133
+ /** First level .sidebar-list-item */
134
+ > .sidebar-list-item:not(:first-child) {
135
+ margin-block-start: 1rem;
136
+ }
137
+
138
+ /** First level .sidebar-link */
139
+ > .sidebar-list-item > .sidebar-link {
140
+ padding-inline-start: 2em;
141
+ font-family: var(--sb-md-font);
142
+ font-size: var(--sb-text-base);
143
+ font-weight: 600;
144
+ color: var(--sb-color-gray-0);
145
+ }
146
+ }
147
+
148
+ .sidebar-footer {
149
+ display: none;
150
+ flex-direction: row;
151
+ align-items: center;
152
+ justify-content: space-between;
153
+ min-inline-size: 18rem;
154
+ padding: 1em 0.5em;
155
+ border-block-start: solid 1px var(--sb-color-gray-5);
156
+ }
157
+
158
+ @media print {
159
+ display: none;
160
+ }
161
+ }
162
+
163
+ @media (max-width: 900px) {
164
+ .sidebar {
165
+ position: fixed;
166
+ inset-block: var(--sb-header-height) 0;
167
+ inset-inline: 0;
168
+ z-index: 200;
169
+ visibility: hidden;
170
+ align-items: unset;
171
+ justify-content: stretch;
172
+ opacity: 0;
173
+ translate: -100% 0;
174
+ transition:
175
+ translate 200ms cubic-bezier(0.7, 0, 0.84, 0),
176
+ opacity 200ms linear,
177
+ visibility 200ms linear;
178
+ transition-behavior: allow-discrete;
179
+
180
+ [dir="rtl"] & {
181
+ translate: 100% 0;
182
+ }
183
+
184
+ &.open {
185
+ visibility: visible;
186
+ opacity: 1;
187
+ translate: 0 0;
188
+ transition:
189
+ translate 200ms cubic-bezier(0.16, 1, 0.3, 1),
190
+ opacity 200ms linear,
191
+ visibility 200ms linear;
192
+ }
193
+
194
+ @media (prefers-reduced-motion: reduce) {
195
+ transition: none;
196
+ }
197
+
198
+ .sidebar-footer {
199
+ display: flex;
200
+ }
201
+ }
202
+ }
@@ -0,0 +1,122 @@
1
+ <aside class="toc desktop">
2
+ <div class="toc-nav-container">
3
+ <nav class="toc-nav toc-content" aria-labelledby="toc-title">
4
+ <h2 id="toc-title" class="toc-title" data-ignore-toc>On this page</h2>
5
+ </nav>
6
+ </div>
7
+ </aside>
8
+
9
+ <script build-time>
10
+ const tocContents = document.querySelectorAll(".toc-content");
11
+ const headings = document
12
+ .querySelectorAll("h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]")
13
+ .filter(el => !el.closest(".not-content"));
14
+
15
+ const maxHeading = +"{{ $data.maxHeading }}";
16
+ const minHeading = +"{{ $data.minHeading }}";
17
+
18
+ const ul = document.createElement("ul");
19
+ ul.classList.add("toc-list");
20
+
21
+ const title = document.querySelector("h1[id]");
22
+
23
+ // Overview
24
+ const overviewItem = document.createElement("li");
25
+ overviewItem.style.setProperty("--depth", "0");
26
+
27
+ const overviewLink = document.createElement("a");
28
+ overviewLink.classList.add("toc-link");
29
+ overviewLink.setAttribute("href", `#${title?.id || ""}`);
30
+ overviewLink.textContent = "Overview";
31
+
32
+ overviewItem.appendChild(overviewLink);
33
+ ul.appendChild(overviewItem);
34
+
35
+ for (const heading of headings) {
36
+ const level = +heading.tagName.slice(1);
37
+
38
+ if (heading.hasAttribute("data-ignore-toc")) {
39
+ heading.removeAttribute("data-ignore-toc");
40
+ continue;
41
+ }
42
+
43
+ if (level < minHeading || level > maxHeading) {
44
+ continue;
45
+ }
46
+
47
+ const id = heading.getAttribute("id");
48
+ const content = heading.textContent;
49
+ const depth = Math.max(level - minHeading, 0);
50
+
51
+ const listItem = document.createElement("li");
52
+ listItem.style.setProperty("--depth", String(depth));
53
+
54
+ const link = document.createElement("a");
55
+ link.classList.add("toc-link");
56
+ link.setAttribute("href", `#${id}`);
57
+ link.textContent = content;
58
+
59
+ listItem.appendChild(link);
60
+ ul.appendChild(listItem);
61
+ }
62
+
63
+ for (const tocContent of tocContents) {
64
+ tocContent.appendChild(ul.cloneNode(true));
65
+ }
66
+ </script>
67
+
68
+ <script>
69
+ (() => {
70
+ // All links in the mobile and desktop TOC
71
+ const links = document.querySelectorAll(".toc-list a");
72
+
73
+ // Mobile TOC current title
74
+ const currentTitle = document.querySelector(".toc-current-title");
75
+
76
+ const headings = Array.from(links)
77
+ .map(a => document.getElementById(a.getAttribute("href").slice(1)))
78
+ .filter(Boolean);
79
+
80
+ function setActive(id) {
81
+ for (const link of links) {
82
+ const active = link.getAttribute("href") === "#" + id;
83
+ link.classList.toggle("active", active);
84
+ if (active) {
85
+ currentTitle.textContent = link.textContent;
86
+ }
87
+ }
88
+ }
89
+
90
+ function update() {
91
+ if (!headings.length) return;
92
+
93
+ let scrollPaddingTop = getComputedStyle(document.documentElement).getPropertyValue("scroll-padding-top");
94
+ scrollPaddingTop = parseFloat(scrollPaddingTop.replace("px", "").trim());
95
+ scrollPaddingTop = !isFinite(scrollPaddingTop) ? 50 : scrollPaddingTop + 2;
96
+
97
+ let active = headings[0];
98
+
99
+ for (const heading of headings) {
100
+ if (heading.getBoundingClientRect().top <= scrollPaddingTop) {
101
+ active = heading;
102
+ }
103
+
104
+ // headings are in document order, so we can stop early
105
+ else {
106
+ break;
107
+ }
108
+ }
109
+
110
+ const nearBottom = window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 100;
111
+ if (nearBottom) {
112
+ active = headings[headings.length - 1];
113
+ }
114
+
115
+ setActive(active.id);
116
+ }
117
+
118
+ window.addEventListener("scroll", update, { passive: true });
119
+
120
+ update(); // set correct state on page load / hash navigation
121
+ })();
122
+ </script>
@@ -0,0 +1,24 @@
1
+ <div class="toc mobile">
2
+ <nav class="toc-nav-mobile">
3
+ <sv-accordion class="toc-accordion" heading-level="none" marker="start">
4
+ <span slot="summary">
5
+ <span class="toc-accordion-summary">On this page</span>
6
+ <span class="toc-current-title"></span>
7
+ </span>
8
+
9
+ <div class="toc-content"></div>
10
+ </sv-accordion>
11
+ </nav>
12
+ </div>
13
+
14
+ <!-- ::: Close the accordion when a link is clicked ::: -->
15
+ <script type="module">
16
+ const tocAccordion = document.querySelector(".toc-accordion");
17
+ const tocLinks = document.querySelectorAll(".toc-accordion a");
18
+
19
+ for (const link of tocLinks) {
20
+ link.addEventListener("click", () => {
21
+ tocAccordion.opened = false;
22
+ });
23
+ }
24
+ </script>