boltdocs 1.7.0 → 1.7.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 (38) hide show
  1. package/dist/{SearchDialog-YOXMFGH6.mjs → SearchDialog-6Z7CUAYJ.mjs} +8 -1
  2. package/dist/{SearchDialog-UOAW6IR3.css → SearchDialog-GOZ6X53X.css} +129 -14
  3. package/dist/{chunk-MULKZFVN.mjs → chunk-SFVOGJ2W.mjs} +269 -165
  4. package/dist/client/index.css +129 -14
  5. package/dist/client/index.d.mts +5 -7
  6. package/dist/client/index.d.ts +5 -7
  7. package/dist/client/index.js +586 -337
  8. package/dist/client/index.mjs +106 -5
  9. package/dist/client/ssr.css +129 -14
  10. package/dist/client/ssr.d.mts +1 -1
  11. package/dist/client/ssr.d.ts +1 -1
  12. package/dist/client/ssr.js +378 -230
  13. package/dist/client/ssr.mjs +1 -1
  14. package/dist/node/index.d.mts +2 -0
  15. package/dist/node/index.d.ts +2 -0
  16. package/dist/node/index.js +4 -1
  17. package/dist/node/index.mjs +4 -1
  18. package/dist/{types-CviV0GbX.d.ts → types-BbceAHA0.d.mts} +2 -0
  19. package/dist/{types-CviV0GbX.d.mts → types-BbceAHA0.d.ts} +2 -0
  20. package/package.json +1 -1
  21. package/src/client/app/index.tsx +8 -7
  22. package/src/client/theme/components/mdx/Table.tsx +108 -10
  23. package/src/client/theme/components/mdx/mdx-components.css +79 -0
  24. package/src/client/theme/styles/variables.css +24 -0
  25. package/src/client/theme/ui/ErrorBoundary/ErrorBoundary.tsx +46 -0
  26. package/src/client/theme/ui/ErrorBoundary/index.ts +1 -0
  27. package/src/client/theme/ui/Layout/Layout.tsx +8 -1
  28. package/src/client/theme/ui/Navbar/Tabs.tsx +37 -12
  29. package/src/client/theme/ui/Navbar/navbar.css +26 -18
  30. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +1 -8
  31. package/src/client/theme/ui/ProgressBar/ProgressBar.css +17 -0
  32. package/src/client/theme/ui/ProgressBar/ProgressBar.tsx +51 -0
  33. package/src/client/theme/ui/ProgressBar/index.ts +1 -0
  34. package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +11 -1
  35. package/src/client/types.ts +2 -0
  36. package/src/node/routes/index.ts +1 -0
  37. package/src/node/routes/parser.ts +11 -0
  38. package/src/node/routes/types.ts +2 -0
@@ -169,14 +169,7 @@ export function OnThisPage({
169
169
  e.preventDefault();
170
170
  const el = document.getElementById(id);
171
171
  if (el) {
172
- const offset = 80;
173
- const bodyRect = document.body.getBoundingClientRect().top;
174
- const elementRect = el.getBoundingClientRect().top;
175
- const elementPosition = elementRect - bodyRect;
176
- const offsetPosition = elementPosition - offset;
177
-
178
- window.scrollTo({
179
- top: offsetPosition,
172
+ el.scrollIntoView({
180
173
  behavior: "smooth",
181
174
  });
182
175
 
@@ -0,0 +1,17 @@
1
+ .boltdocs-progress-container {
2
+ position: fixed;
3
+ top: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ height: 2px;
7
+ z-index: 1000;
8
+ pointer-events: none;
9
+ background: transparent;
10
+ }
11
+
12
+ .boltdocs-progress-bar {
13
+ height: 100%;
14
+ background: linear-gradient(90deg, var(--ld-color-primary), var(--ld-gradient-to, var(--ld-color-primary)));
15
+ box-shadow: 0 0 8px var(--ld-color-primary-glow);
16
+ transition: width 0.1s ease-out;
17
+ }
@@ -0,0 +1,51 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import "./ProgressBar.css";
3
+
4
+ export function ProgressBar() {
5
+ const [progress, setProgress] = useState(0);
6
+
7
+ useEffect(() => {
8
+ let container: Element | null = null;
9
+ let timer: any;
10
+
11
+ const handleScroll = () => {
12
+ if (!container) return;
13
+ const { scrollTop, scrollHeight, clientHeight } = container;
14
+ if (scrollHeight <= clientHeight) {
15
+ setProgress(0);
16
+ return;
17
+ }
18
+ const scrollPercent = (scrollTop / (scrollHeight - clientHeight)) * 100;
19
+ setProgress(Math.min(100, Math.max(0, scrollPercent)));
20
+ };
21
+
22
+ const attachListener = () => {
23
+ container = document.querySelector(".boltdocs-content");
24
+ if (container) {
25
+ container.addEventListener("scroll", handleScroll);
26
+ handleScroll();
27
+ if (timer) clearInterval(timer);
28
+ return true;
29
+ }
30
+ return false;
31
+ };
32
+
33
+ if (!attachListener()) {
34
+ timer = setInterval(attachListener, 100);
35
+ }
36
+
37
+ return () => {
38
+ if (container) container.removeEventListener("scroll", handleScroll);
39
+ if (timer) clearInterval(timer);
40
+ };
41
+ }, []);
42
+
43
+ return (
44
+ <div className="boltdocs-progress-container">
45
+ <div
46
+ className="boltdocs-progress-bar"
47
+ style={{ width: `${progress}%` }}
48
+ />
49
+ </div>
50
+ );
51
+ }
@@ -0,0 +1 @@
1
+ export * from "./ProgressBar";
@@ -49,7 +49,7 @@ export function SearchDialog({ routes }: { routes: ComponentRoute[] }) {
49
49
 
50
50
  const results: SearchResult[] = [];
51
51
  const lowerQuery = query.toLowerCase();
52
-
52
+
53
53
  for (const route of routes) {
54
54
  if (route.title && route.title.toLowerCase().includes(lowerQuery)) {
55
55
  results.push({
@@ -71,6 +71,16 @@ export function SearchDialog({ routes }: { routes: ComponentRoute[] }) {
71
71
  }
72
72
  }
73
73
  }
74
+
75
+ if (route._content && route._content.toLowerCase().includes(lowerQuery)) {
76
+ // If it's a content match but not a title/heading match, add it
77
+ // We only add the page itself for now
78
+ results.push({
79
+ title: route.title,
80
+ path: route.path,
81
+ groupTitle: route.groupTitle,
82
+ });
83
+ }
74
84
  }
75
85
 
76
86
  // Deduplicate results by path
@@ -37,6 +37,8 @@ export interface ComponentRoute {
37
37
  badge?: string | { text: string; expires?: string };
38
38
  /** Optional icon for the route's group */
39
39
  groupIcon?: string;
40
+ /** The extracted plain-text content of the page for search indexing */
41
+ _content?: string;
40
42
  }
41
43
 
42
44
  /**
@@ -29,6 +29,7 @@ export async function generateRoutes(
29
29
  ): Promise<RouteMeta[]> {
30
30
  // Load persistent cache on first call
31
31
  docCache.load();
32
+ docCache.invalidateAll(); // FORCE RE-PARSE to pick up new _content field
32
33
 
33
34
  const files = await fastGlob(["**/*.md", "**/*.mdx"], {
34
35
  cwd: docsDir,
@@ -151,6 +151,16 @@ export function parseDocFile(
151
151
  const sanitizedBadge = data.badge ? data.badge : undefined;
152
152
  const icon = data.icon ? String(data.icon) : undefined;
153
153
 
154
+ // Extract full content as plain text for search indexing
155
+ const plainText = content
156
+ .replace(/^#+.*$/gm, "") // Remove headers
157
+ .replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1") // Simplify links
158
+ .replace(/<[^>]+>/g, "") // Remove HTML/JSX tags
159
+ .replace(/\{[^\}]+\}/g, "") // Remove JS expressions/curly braces
160
+ .replace(/[_*`]/g, "") // Remove formatting
161
+ .replace(/\n+/g, " ") // Normalize whitespace
162
+ .trim();
163
+
154
164
  return {
155
165
  route: {
156
166
  path: finalPath,
@@ -165,6 +175,7 @@ export function parseDocFile(
165
175
  badge: sanitizedBadge,
166
176
  icon,
167
177
  tab: inferredTab,
178
+ _content: plainText,
168
179
  },
169
180
  relativeDir: cleanDirName,
170
181
  isGroupIndex,
@@ -35,6 +35,8 @@ export interface RouteMeta {
35
35
  icon?: string;
36
36
  /** The tab this route belongs to, if tabs are configured */
37
37
  tab?: string;
38
+ /** The extracted plain-text content of the page for search indexing */
39
+ _content?: string;
38
40
  }
39
41
 
40
42
  /**