boltdocs 1.0.4 → 1.3.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.
Files changed (121) hide show
  1. package/dist/{SearchDialog-R36WKAQ7.mjs → SearchDialog-5EDRACEG.mjs} +1 -1
  2. package/dist/{SearchDialog-PYF3QMYG.css → SearchDialog-X57WPTNN.css} +54 -126
  3. package/dist/cache-EHR7SXRU.mjs +12 -0
  4. package/dist/chunk-GSYECEZY.mjs +381 -0
  5. package/dist/{chunk-TWSRXUFF.mjs → chunk-NS7WHDYA.mjs} +229 -418
  6. package/dist/client/index.css +54 -126
  7. package/dist/client/index.d.mts +5 -4
  8. package/dist/client/index.d.ts +5 -4
  9. package/dist/client/index.js +555 -580
  10. package/dist/client/index.mjs +304 -16
  11. package/dist/client/ssr.css +54 -126
  12. package/dist/client/ssr.js +257 -580
  13. package/dist/client/ssr.mjs +1 -1
  14. package/dist/{config-D2XmHJYe.d.mts → config-BD5ZHz15.d.mts} +7 -0
  15. package/dist/{config-D2XmHJYe.d.ts → config-BD5ZHz15.d.ts} +7 -0
  16. package/dist/node/index.d.mts +2 -2
  17. package/dist/node/index.d.ts +2 -2
  18. package/dist/node/index.js +477 -123
  19. package/dist/node/index.mjs +114 -142
  20. package/package.json +2 -2
  21. package/src/client/app/index.tsx +344 -373
  22. package/src/client/app/preload.tsx +56 -56
  23. package/src/client/index.ts +40 -40
  24. package/src/client/ssr.tsx +51 -51
  25. package/src/client/theme/components/CodeBlock/CodeBlock.tsx +76 -76
  26. package/src/client/theme/components/CodeBlock/index.ts +1 -1
  27. package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +154 -154
  28. package/src/client/theme/components/PackageManagerTabs/index.ts +1 -1
  29. package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +64 -64
  30. package/src/client/theme/components/Playground/Playground.tsx +124 -124
  31. package/src/client/theme/components/Playground/index.ts +1 -1
  32. package/src/client/theme/components/Playground/playground.css +168 -168
  33. package/src/client/theme/components/Video/Video.tsx +84 -84
  34. package/src/client/theme/components/Video/index.ts +1 -1
  35. package/src/client/theme/components/Video/video.css +41 -41
  36. package/src/client/theme/components/mdx/Admonition.tsx +80 -80
  37. package/src/client/theme/components/mdx/Badge.tsx +31 -31
  38. package/src/client/theme/components/mdx/Button.tsx +50 -50
  39. package/src/client/theme/components/mdx/Card.tsx +80 -80
  40. package/src/client/theme/components/mdx/List.tsx +57 -57
  41. package/src/client/theme/components/mdx/Tabs.tsx +94 -94
  42. package/src/client/theme/components/mdx/index.ts +18 -18
  43. package/src/client/theme/components/mdx/mdx-components.css +424 -405
  44. package/src/client/theme/icons/bun.tsx +62 -62
  45. package/src/client/theme/icons/deno.tsx +20 -20
  46. package/src/client/theme/icons/discord.tsx +12 -12
  47. package/src/client/theme/icons/github.tsx +15 -15
  48. package/src/client/theme/icons/npm.tsx +13 -13
  49. package/src/client/theme/icons/pnpm.tsx +72 -72
  50. package/src/client/theme/icons/twitter.tsx +12 -12
  51. package/src/client/theme/styles/markdown.css +343 -343
  52. package/src/client/theme/styles/variables.css +162 -162
  53. package/src/client/theme/styles.css +37 -38
  54. package/src/client/theme/ui/BackgroundGradient/BackgroundGradient.tsx +10 -10
  55. package/src/client/theme/ui/BackgroundGradient/index.ts +1 -1
  56. package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +68 -68
  57. package/src/client/theme/ui/Breadcrumbs/index.ts +1 -1
  58. package/src/client/theme/ui/Footer/footer.css +32 -32
  59. package/src/client/theme/ui/Head/Head.tsx +69 -69
  60. package/src/client/theme/ui/Head/index.ts +1 -1
  61. package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +125 -125
  62. package/src/client/theme/ui/LanguageSwitcher/index.ts +1 -1
  63. package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +98 -98
  64. package/src/client/theme/ui/Layout/Layout.tsx +202 -213
  65. package/src/client/theme/ui/Layout/base.css +76 -76
  66. package/src/client/theme/ui/Layout/index.ts +2 -2
  67. package/src/client/theme/ui/Layout/pagination.css +72 -72
  68. package/src/client/theme/ui/Layout/responsive.css +36 -40
  69. package/src/client/theme/ui/Link/Link.tsx +254 -202
  70. package/src/client/theme/ui/Link/index.ts +2 -2
  71. package/src/client/theme/ui/Loading/Loading.tsx +10 -10
  72. package/src/client/theme/ui/Loading/index.ts +1 -1
  73. package/src/client/theme/ui/Loading/loading.css +30 -30
  74. package/src/client/theme/ui/Navbar/GithubStars.tsx +27 -27
  75. package/src/client/theme/ui/Navbar/Navbar.tsx +145 -145
  76. package/src/client/theme/ui/Navbar/index.ts +2 -2
  77. package/src/client/theme/ui/Navbar/navbar.css +233 -233
  78. package/src/client/theme/ui/NotFound/NotFound.tsx +19 -20
  79. package/src/client/theme/ui/NotFound/index.ts +1 -1
  80. package/src/client/theme/ui/NotFound/not-found.css +64 -64
  81. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +235 -192
  82. package/src/client/theme/ui/OnThisPage/index.ts +1 -1
  83. package/src/client/theme/ui/OnThisPage/toc.css +132 -132
  84. package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +18 -18
  85. package/src/client/theme/ui/PoweredBy/index.ts +1 -1
  86. package/src/client/theme/ui/PoweredBy/powered-by.css +76 -76
  87. package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +199 -199
  88. package/src/client/theme/ui/SearchDialog/index.ts +1 -1
  89. package/src/client/theme/ui/SearchDialog/search.css +152 -152
  90. package/src/client/theme/ui/Sidebar/Sidebar.tsx +204 -200
  91. package/src/client/theme/ui/Sidebar/index.ts +1 -1
  92. package/src/client/theme/ui/Sidebar/sidebar.css +236 -269
  93. package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +69 -69
  94. package/src/client/theme/ui/ThemeToggle/index.ts +1 -1
  95. package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +136 -136
  96. package/src/client/theme/ui/VersionSwitcher/index.ts +1 -1
  97. package/src/client/types.ts +50 -50
  98. package/src/client/utils.ts +26 -26
  99. package/src/node/cache.ts +408 -94
  100. package/src/node/config.ts +192 -185
  101. package/src/node/index.ts +21 -21
  102. package/src/node/mdx.ts +120 -41
  103. package/src/node/plugin/entry.ts +58 -58
  104. package/src/node/plugin/html.ts +55 -55
  105. package/src/node/plugin/index.ts +193 -190
  106. package/src/node/plugin/types.ts +11 -11
  107. package/src/node/routes/cache.ts +28 -24
  108. package/src/node/routes/index.ts +167 -152
  109. package/src/node/routes/parser.ts +153 -127
  110. package/src/node/routes/sorter.ts +42 -42
  111. package/src/node/routes/types.ts +49 -49
  112. package/src/node/ssg/index.ts +114 -110
  113. package/src/node/ssg/meta.ts +34 -34
  114. package/src/node/ssg/options.ts +13 -13
  115. package/src/node/ssg/sitemap.ts +54 -54
  116. package/src/node/utils.ts +134 -134
  117. package/tsconfig.json +20 -20
  118. package/tsup.config.ts +22 -22
  119. package/dist/Playground-B2FA34BC.mjs +0 -6
  120. package/dist/chunk-WPT4MWTQ.mjs +0 -89
  121. package/src/client/theme/styles/home.css +0 -60
@@ -1,192 +1,235 @@
1
- import React, { useEffect, useState, useRef, useCallback } from "react";
2
- import { useLocation } from "react-router-dom";
3
- import { Pencil, CircleHelp } from "lucide-react";
4
-
5
- interface TocHeading {
6
- id: string;
7
- text: string;
8
- level: number;
9
- }
10
-
11
- export function OnThisPage({
12
- headings = [],
13
- editLink,
14
- communityHelp,
15
- filePath,
16
- }: {
17
- headings?: TocHeading[];
18
- editLink?: string;
19
- communityHelp?: string;
20
- filePath?: string;
21
- }) {
22
- const [activeId, setActiveId] = useState<string>("");
23
- const [indicatorStyle, setIndicatorStyle] = useState<React.CSSProperties>({});
24
- const observerRef = useRef<IntersectionObserver | null>(null);
25
- const location = useLocation();
26
- const listRef = useRef<HTMLUListElement>(null);
27
-
28
- // Reset active ID when path changes
29
- useEffect(() => {
30
- if (headings.length > 0) {
31
- // Check if there's a hash in the URL
32
- const hash = window.location.hash.substring(1);
33
- if (hash && headings.some((h) => h.id === hash)) {
34
- setActiveId(hash);
35
- } else {
36
- setActiveId(headings[0].id);
37
- }
38
- }
39
- }, [location.pathname, headings]);
40
-
41
- // Update indicator position
42
- useEffect(() => {
43
- if (!activeId || !listRef.current) return;
44
-
45
- const activeElement = listRef.current.querySelector(
46
- `a[href="#${activeId}"]`,
47
- ) as HTMLElement;
48
-
49
- if (activeElement) {
50
- const { offsetTop, offsetHeight } = activeElement;
51
- setIndicatorStyle({
52
- transform: `translateY(${offsetTop}px)`,
53
- height: `${offsetHeight}px`,
54
- opacity: 1,
55
- });
56
- }
57
- }, [activeId, headings]);
58
-
59
- // IntersectionObserver for active heading tracking
60
- useEffect(() => {
61
- if (headings.length === 0) return;
62
-
63
- if (observerRef.current) {
64
- observerRef.current.disconnect();
65
- }
66
-
67
- const callback: IntersectionObserverCallback = (entries) => {
68
- // Find all entries that are intersecting
69
- const visibleEntries = entries.filter((entry) => entry.isIntersecting);
70
-
71
- if (visibleEntries.length > 0) {
72
- // If we have visible entries, find the one closest to the top of the viewport
73
- // But with a priority for ones that just entered from the top
74
- const closest = visibleEntries.reduce((prev, curr) => {
75
- return Math.abs(curr.boundingClientRect.top - 100) <
76
- Math.abs(prev.boundingClientRect.top - 100)
77
- ? curr
78
- : prev;
79
- });
80
- setActiveId(closest.target.id);
81
- }
82
- };
83
-
84
- observerRef.current = new IntersectionObserver(callback, {
85
- rootMargin: "-100px 0px -70% 0px",
86
- threshold: [0, 1],
87
- });
88
-
89
- const observeHeadings = () => {
90
- headings.forEach(({ id }) => {
91
- const el = document.getElementById(id);
92
- if (el) {
93
- observerRef.current!.observe(el);
94
- }
95
- });
96
- };
97
-
98
- // Initial observation
99
- observeHeadings();
100
-
101
- // Re-observe if content changes (e.g. after some delay to ensure rendering)
102
- const timeoutId = setTimeout(observeHeadings, 1000);
103
-
104
- return () => {
105
- observerRef.current?.disconnect();
106
- clearTimeout(timeoutId);
107
- };
108
- }, [headings, location.pathname]);
109
-
110
- const handleClick = useCallback(
111
- (e: React.MouseEvent<HTMLAnchorElement>, id: string) => {
112
- e.preventDefault();
113
- const el = document.getElementById(id);
114
- if (el) {
115
- const offset = 80;
116
- const bodyRect = document.body.getBoundingClientRect().top;
117
- const elementRect = el.getBoundingClientRect().top;
118
- const elementPosition = elementRect - bodyRect;
119
- const offsetPosition = elementPosition - offset;
120
-
121
- window.scrollTo({
122
- top: offsetPosition,
123
- behavior: "smooth",
124
- });
125
-
126
- setActiveId(id);
127
- window.history.pushState(null, "", `#${id}`);
128
- }
129
- },
130
- [],
131
- );
132
-
133
- if (headings.length === 0) return null;
134
-
135
- return (
136
- <nav className="boltdocs-on-this-page" aria-label="Table of contents">
137
- <p className="on-this-page-title">On this page</p>
138
- <div className="on-this-page-container">
139
- <div className="toc-indicator" style={indicatorStyle} />
140
- <ul className="on-this-page-list" ref={listRef}>
141
- {headings.map((h) => (
142
- <li key={h.id} className={h.level === 3 ? "toc-indent" : ""}>
143
- <a
144
- href={`#${h.id}`}
145
- className={`toc-link ${activeId === h.id ? "active" : ""}`}
146
- aria-current={activeId === h.id ? "true" : undefined}
147
- onClick={(e) => handleClick(e, h.id)}
148
- >
149
- {h.text}
150
- </a>
151
- </li>
152
- ))}
153
- </ul>
154
- </div>
155
-
156
- {/* Need help? section */}
157
- {(editLink || communityHelp) && (
158
- <div className="toc-help">
159
- <p className="toc-help-title">Need help?</p>
160
- <ul className="toc-help-links">
161
- {editLink && filePath && (
162
- <li>
163
- <a
164
- href={editLink.replace(":path", filePath)}
165
- target="_blank"
166
- rel="noopener noreferrer"
167
- className="toc-help-link"
168
- >
169
- <Pencil size={16} />
170
- Edit this page
171
- </a>
172
- </li>
173
- )}
174
- {communityHelp && (
175
- <li>
176
- <a
177
- href={communityHelp}
178
- target="_blank"
179
- rel="noopener noreferrer"
180
- className="toc-help-link"
181
- >
182
- <CircleHelp size={16} />
183
- Community help
184
- </a>
185
- </li>
186
- )}
187
- </ul>
188
- </div>
189
- )}
190
- </nav>
191
- );
192
- }
1
+ import React, { useEffect, useState, useRef, useCallback } from "react";
2
+ import { useLocation } from "react-router-dom";
3
+ import { Pencil, CircleHelp } from "lucide-react";
4
+
5
+ interface TocHeading {
6
+ id: string;
7
+ text: string;
8
+ level: number;
9
+ }
10
+
11
+ export function OnThisPage({
12
+ headings = [],
13
+ editLink,
14
+ communityHelp,
15
+ filePath,
16
+ }: {
17
+ headings?: TocHeading[];
18
+ editLink?: string;
19
+ communityHelp?: string;
20
+ filePath?: string;
21
+ }) {
22
+ const [activeId, setActiveId] = useState<string>("");
23
+ const [indicatorStyle, setIndicatorStyle] = useState<React.CSSProperties>({});
24
+ const observerRef = useRef<IntersectionObserver | null>(null);
25
+ const location = useLocation();
26
+ const listRef = useRef<HTMLUListElement>(null);
27
+
28
+ // Reset active ID when path changes
29
+ useEffect(() => {
30
+ if (headings.length > 0) {
31
+ // Check if there's a hash in the URL
32
+ const hash = window.location.hash.substring(1);
33
+ if (hash && headings.some((h) => h.id === hash)) {
34
+ setActiveId(hash);
35
+ } else {
36
+ setActiveId(headings[0].id);
37
+ }
38
+ }
39
+ }, [location.pathname, headings]);
40
+
41
+ // Update indicator position
42
+ useEffect(() => {
43
+ if (!activeId || !listRef.current) return;
44
+
45
+ const activeElement = listRef.current.querySelector(
46
+ `a[href="#${activeId}"]`,
47
+ ) as HTMLElement;
48
+
49
+ if (activeElement) {
50
+ const { offsetTop, offsetHeight } = activeElement;
51
+ setIndicatorStyle({
52
+ transform: `translateY(${offsetTop}px)`,
53
+ height: `${offsetHeight}px`,
54
+ opacity: 1,
55
+ });
56
+ }
57
+ }, [activeId, headings]);
58
+
59
+ // IntersectionObserver for active heading tracking
60
+ useEffect(() => {
61
+ if (headings.length === 0) return;
62
+
63
+ if (observerRef.current) {
64
+ observerRef.current.disconnect();
65
+ }
66
+
67
+ const callback: IntersectionObserverCallback = (entries) => {
68
+ // Find all entries that are intersecting
69
+ const visibleEntries = entries.filter((entry) => entry.isIntersecting);
70
+
71
+ if (visibleEntries.length > 0) {
72
+ // If we have visible entries, find the one closest to the top of the viewport
73
+ const closest = visibleEntries.reduce((prev, curr) => {
74
+ return Math.abs(curr.boundingClientRect.top - 100) <
75
+ Math.abs(prev.boundingClientRect.top - 100)
76
+ ? curr
77
+ : prev;
78
+ });
79
+ setActiveId(closest.target.id);
80
+ }
81
+ };
82
+
83
+ observerRef.current = new IntersectionObserver(callback, {
84
+ rootMargin: "-100px 0px -70% 0px",
85
+ threshold: [0, 1],
86
+ });
87
+
88
+ const observeHeadings = () => {
89
+ headings.forEach(({ id }) => {
90
+ const el = document.getElementById(id);
91
+ if (el) {
92
+ observerRef.current!.observe(el);
93
+ }
94
+ });
95
+ };
96
+
97
+ // Initial observation
98
+ observeHeadings();
99
+
100
+ // Re-observe if content changes
101
+ const timeoutId = setTimeout(observeHeadings, 1000);
102
+
103
+ // Scroll listener to detect bottom of page
104
+ const handleScroll = () => {
105
+ const scrollPosition = window.innerHeight + window.pageYOffset;
106
+ const bodyHeight = document.documentElement.scrollHeight;
107
+
108
+ // If we're within 50px of the bottom, activate the last heading
109
+ if (scrollPosition >= bodyHeight - 50) {
110
+ setActiveId(headings[headings.length - 1].id);
111
+ }
112
+ };
113
+
114
+ window.addEventListener("scroll", handleScroll, { passive: true });
115
+
116
+ return () => {
117
+ observerRef.current?.disconnect();
118
+ clearTimeout(timeoutId);
119
+ window.removeEventListener("scroll", handleScroll);
120
+ };
121
+ }, [headings, location.pathname]);
122
+
123
+ // Autoscroll TOC list when activeId changes
124
+ useEffect(() => {
125
+ if (!activeId || !listRef.current) return;
126
+
127
+ const activeLink = listRef.current.querySelector(
128
+ `a[href="#${activeId}"]`,
129
+ ) as HTMLElement;
130
+
131
+ if (activeLink) {
132
+ const container = listRef.current.closest(
133
+ ".boltdocs-on-this-page",
134
+ ) as HTMLElement;
135
+ if (!container) return;
136
+
137
+ const linkRect = activeLink.getBoundingClientRect();
138
+ const containerRect = container.getBoundingClientRect();
139
+
140
+ const isVisible =
141
+ linkRect.top >= containerRect.top &&
142
+ linkRect.bottom <= containerRect.bottom;
143
+
144
+ if (!isVisible) {
145
+ activeLink.scrollIntoView({
146
+ behavior: "smooth",
147
+ block: "nearest",
148
+ });
149
+ }
150
+ }
151
+ }, [activeId]);
152
+
153
+ const handleClick = useCallback(
154
+ (e: React.MouseEvent<HTMLAnchorElement>, id: string) => {
155
+ e.preventDefault();
156
+ const el = document.getElementById(id);
157
+ if (el) {
158
+ const offset = 80;
159
+ const bodyRect = document.body.getBoundingClientRect().top;
160
+ const elementRect = el.getBoundingClientRect().top;
161
+ const elementPosition = elementRect - bodyRect;
162
+ const offsetPosition = elementPosition - offset;
163
+
164
+ window.scrollTo({
165
+ top: offsetPosition,
166
+ behavior: "smooth",
167
+ });
168
+
169
+ setActiveId(id);
170
+ window.history.pushState(null, "", `#${id}`);
171
+ }
172
+ },
173
+ [],
174
+ );
175
+
176
+ if (headings.length === 0) return null;
177
+
178
+ return (
179
+ <nav className="boltdocs-on-this-page" aria-label="Table of contents">
180
+ <p className="on-this-page-title">On this page</p>
181
+ <div className="on-this-page-container">
182
+ <div className="toc-indicator" style={indicatorStyle} />
183
+ <ul className="on-this-page-list" ref={listRef}>
184
+ {headings.map((h) => (
185
+ <li key={h.id} className={h.level === 3 ? "toc-indent" : ""}>
186
+ <a
187
+ href={`#${h.id}`}
188
+ className={`toc-link ${activeId === h.id ? "active" : ""}`}
189
+ aria-current={activeId === h.id ? "true" : undefined}
190
+ onClick={(e) => handleClick(e, h.id)}
191
+ >
192
+ {h.text}
193
+ </a>
194
+ </li>
195
+ ))}
196
+ </ul>
197
+ </div>
198
+
199
+ {/* Need help? section */}
200
+ {(editLink || communityHelp) && (
201
+ <div className="toc-help">
202
+ <p className="toc-help-title">Need help?</p>
203
+ <ul className="toc-help-links">
204
+ {editLink && filePath && (
205
+ <li>
206
+ <a
207
+ href={editLink.replace(":path", filePath)}
208
+ target="_blank"
209
+ rel="noopener noreferrer"
210
+ className="toc-help-link"
211
+ >
212
+ <Pencil size={16} />
213
+ Edit this page
214
+ </a>
215
+ </li>
216
+ )}
217
+ {communityHelp && (
218
+ <li>
219
+ <a
220
+ href={communityHelp}
221
+ target="_blank"
222
+ rel="noopener noreferrer"
223
+ className="toc-help-link"
224
+ >
225
+ <CircleHelp size={16} />
226
+ Community help
227
+ </a>
228
+ </li>
229
+ )}
230
+ </ul>
231
+ </div>
232
+ )}
233
+ </nav>
234
+ );
235
+ }
@@ -1 +1 @@
1
- export { OnThisPage } from "./OnThisPage";
1
+ export { OnThisPage } from "./OnThisPage";