boltdocs 1.3.0 → 1.3.2

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 (103) hide show
  1. package/dist/{cache-EHR7SXRU.mjs → cache-GQHF6BXI.mjs} +1 -1
  2. package/dist/{chunk-GSYECEZY.mjs → chunk-CYBWLFOG.mjs} +5 -1
  3. package/dist/node/index.js +36 -20
  4. package/dist/node/index.mjs +34 -22
  5. package/package.json +1 -1
  6. package/src/client/app/index.tsx +344 -344
  7. package/src/client/app/preload.tsx +56 -56
  8. package/src/client/index.ts +40 -40
  9. package/src/client/ssr.tsx +51 -51
  10. package/src/client/theme/components/CodeBlock/CodeBlock.tsx +76 -76
  11. package/src/client/theme/components/CodeBlock/index.ts +1 -1
  12. package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +154 -154
  13. package/src/client/theme/components/PackageManagerTabs/index.ts +1 -1
  14. package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +64 -64
  15. package/src/client/theme/components/Playground/Playground.tsx +124 -124
  16. package/src/client/theme/components/Playground/index.ts +1 -1
  17. package/src/client/theme/components/Playground/playground.css +168 -168
  18. package/src/client/theme/components/Video/Video.tsx +84 -84
  19. package/src/client/theme/components/Video/index.ts +1 -1
  20. package/src/client/theme/components/Video/video.css +41 -41
  21. package/src/client/theme/components/mdx/Admonition.tsx +80 -80
  22. package/src/client/theme/components/mdx/Badge.tsx +31 -31
  23. package/src/client/theme/components/mdx/Button.tsx +50 -50
  24. package/src/client/theme/components/mdx/Card.tsx +80 -80
  25. package/src/client/theme/components/mdx/List.tsx +57 -57
  26. package/src/client/theme/components/mdx/Tabs.tsx +94 -94
  27. package/src/client/theme/components/mdx/index.ts +18 -18
  28. package/src/client/theme/components/mdx/mdx-components.css +424 -424
  29. package/src/client/theme/icons/bun.tsx +62 -62
  30. package/src/client/theme/icons/deno.tsx +20 -20
  31. package/src/client/theme/icons/discord.tsx +12 -12
  32. package/src/client/theme/icons/github.tsx +15 -15
  33. package/src/client/theme/icons/npm.tsx +13 -13
  34. package/src/client/theme/icons/pnpm.tsx +72 -72
  35. package/src/client/theme/icons/twitter.tsx +12 -12
  36. package/src/client/theme/styles/markdown.css +343 -343
  37. package/src/client/theme/styles/variables.css +162 -162
  38. package/src/client/theme/styles.css +37 -37
  39. package/src/client/theme/ui/BackgroundGradient/BackgroundGradient.tsx +10 -10
  40. package/src/client/theme/ui/BackgroundGradient/index.ts +1 -1
  41. package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +68 -68
  42. package/src/client/theme/ui/Breadcrumbs/index.ts +1 -1
  43. package/src/client/theme/ui/Footer/footer.css +32 -32
  44. package/src/client/theme/ui/Head/Head.tsx +69 -69
  45. package/src/client/theme/ui/Head/index.ts +1 -1
  46. package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +125 -125
  47. package/src/client/theme/ui/LanguageSwitcher/index.ts +1 -1
  48. package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +98 -98
  49. package/src/client/theme/ui/Layout/Layout.tsx +202 -202
  50. package/src/client/theme/ui/Layout/base.css +76 -76
  51. package/src/client/theme/ui/Layout/index.ts +2 -2
  52. package/src/client/theme/ui/Layout/pagination.css +72 -72
  53. package/src/client/theme/ui/Layout/responsive.css +36 -36
  54. package/src/client/theme/ui/Link/Link.tsx +254 -254
  55. package/src/client/theme/ui/Link/index.ts +2 -2
  56. package/src/client/theme/ui/Loading/Loading.tsx +10 -10
  57. package/src/client/theme/ui/Loading/index.ts +1 -1
  58. package/src/client/theme/ui/Loading/loading.css +30 -30
  59. package/src/client/theme/ui/Navbar/GithubStars.tsx +27 -27
  60. package/src/client/theme/ui/Navbar/Navbar.tsx +145 -145
  61. package/src/client/theme/ui/Navbar/index.ts +2 -2
  62. package/src/client/theme/ui/Navbar/navbar.css +233 -233
  63. package/src/client/theme/ui/NotFound/NotFound.tsx +19 -19
  64. package/src/client/theme/ui/NotFound/index.ts +1 -1
  65. package/src/client/theme/ui/NotFound/not-found.css +64 -64
  66. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +235 -235
  67. package/src/client/theme/ui/OnThisPage/index.ts +1 -1
  68. package/src/client/theme/ui/OnThisPage/toc.css +132 -132
  69. package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +18 -18
  70. package/src/client/theme/ui/PoweredBy/index.ts +1 -1
  71. package/src/client/theme/ui/PoweredBy/powered-by.css +76 -76
  72. package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +199 -199
  73. package/src/client/theme/ui/SearchDialog/index.ts +1 -1
  74. package/src/client/theme/ui/SearchDialog/search.css +152 -152
  75. package/src/client/theme/ui/Sidebar/Sidebar.tsx +204 -204
  76. package/src/client/theme/ui/Sidebar/index.ts +1 -1
  77. package/src/client/theme/ui/Sidebar/sidebar.css +236 -236
  78. package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +69 -69
  79. package/src/client/theme/ui/ThemeToggle/index.ts +1 -1
  80. package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +136 -136
  81. package/src/client/theme/ui/VersionSwitcher/index.ts +1 -1
  82. package/src/client/types.ts +50 -50
  83. package/src/client/utils.ts +26 -26
  84. package/src/node/cache.ts +408 -408
  85. package/src/node/config.ts +192 -192
  86. package/src/node/index.ts +21 -21
  87. package/src/node/mdx.ts +120 -120
  88. package/src/node/plugin/entry.ts +58 -58
  89. package/src/node/plugin/html.ts +55 -55
  90. package/src/node/plugin/index.ts +193 -193
  91. package/src/node/plugin/types.ts +11 -11
  92. package/src/node/routes/cache.ts +28 -28
  93. package/src/node/routes/index.ts +167 -167
  94. package/src/node/routes/parser.ts +153 -127
  95. package/src/node/routes/sorter.ts +42 -42
  96. package/src/node/routes/types.ts +49 -49
  97. package/src/node/ssg/index.ts +114 -114
  98. package/src/node/ssg/meta.ts +33 -34
  99. package/src/node/ssg/options.ts +13 -13
  100. package/src/node/ssg/sitemap.ts +55 -54
  101. package/src/node/utils.ts +145 -134
  102. package/tsconfig.json +20 -20
  103. package/tsup.config.ts +22 -22
@@ -1,204 +1,204 @@
1
- import React, { useState } from "react";
2
- import { useLocation } from "react-router-dom";
3
- import { Link } from "../Link";
4
- import { BoltdocsConfig } from "../../../../node/config";
5
- import { PoweredBy } from "../PoweredBy";
6
- import { ChevronRight, ChevronLeft, PanelLeft } from "lucide-react";
7
-
8
- interface RouteItem {
9
- path: string;
10
- title: string;
11
- group?: string;
12
- groupTitle?: string;
13
- sidebarPosition?: number;
14
- badge?: string | { text: string; expires?: string };
15
- }
16
-
17
- interface SidebarGroup {
18
- slug: string;
19
- title: string;
20
- routes: RouteItem[];
21
- }
22
-
23
- /**
24
- * Renders a small badge next to sidebar items if one exists and hasn't expired.
25
- */
26
- function renderBadge(badgeRaw: RouteItem["badge"]) {
27
- if (!badgeRaw) return null;
28
-
29
- let text = "";
30
- let expires = "";
31
-
32
- if (typeof badgeRaw === "string") {
33
- text = badgeRaw;
34
- } else {
35
- text = badgeRaw.text;
36
- expires = badgeRaw.expires || "";
37
- }
38
-
39
- // Check expiration
40
- if (expires) {
41
- const expireDate = new Date(expires);
42
- const now = new Date();
43
- // Reset time components for accurate day comparison
44
- expireDate.setHours(0, 0, 0, 0);
45
- now.setHours(0, 0, 0, 0);
46
- if (now > expireDate) {
47
- return null;
48
- }
49
- }
50
-
51
- if (!text) return null;
52
-
53
- if (!text) return null;
54
-
55
- let typeClass = "badge-default";
56
- const lowerText = text.toLowerCase();
57
- if (lowerText === "new") {
58
- typeClass = "badge-new";
59
- } else if (lowerText === "experimental") {
60
- typeClass = "badge-experimental";
61
- } else if (lowerText === "updated") {
62
- typeClass = "badge-updated";
63
- }
64
-
65
- return <span className={`sidebar-badge ${typeClass}`}>{text}</span>;
66
- }
67
-
68
- /**
69
- * The sidebar navigation component.
70
- * Groups documentation routes logically based on the `group` property.
71
- * Highlights the active link based on the current URL path.
72
- *
73
- * @param routes - Array of all generated routes to be displayed
74
- * @param config - Global configuration (which can contain sidebar overrides)
75
- */
76
- export function Sidebar({
77
- routes,
78
- config,
79
- isCollapsed,
80
- onToggle,
81
- }: {
82
- routes: RouteItem[];
83
- config: BoltdocsConfig;
84
- isCollapsed?: boolean;
85
- onToggle?: () => void;
86
- }) {
87
- const location = useLocation();
88
-
89
- const ungrouped: RouteItem[] = [];
90
- const groupMap = new Map<string, SidebarGroup>();
91
-
92
- for (const route of routes) {
93
- if (!route.group) {
94
- ungrouped.push(route);
95
- } else {
96
- if (!groupMap.has(route.group)) {
97
- groupMap.set(route.group, {
98
- slug: route.group,
99
- title: route.groupTitle || route.group,
100
- routes: [],
101
- });
102
- }
103
- groupMap.get(route.group)!.routes.push(route);
104
- }
105
- }
106
-
107
- const groups = Array.from(groupMap.values());
108
-
109
- return (
110
- <aside className="boltdocs-sidebar">
111
- {onToggle && (
112
- <div className="sidebar-collapse">
113
- <button
114
- className="sidebar-collapse-btn"
115
- onClick={onToggle}
116
- aria-label={isCollapsed ? "Expand Sidebar" : "Collapse Sidebar"}
117
- title={isCollapsed ? "Expand Sidebar" : "Collapse Sidebar"}
118
- >
119
- <PanelLeft size={18} />
120
- </button>
121
- </div>
122
- )}
123
-
124
- {!isCollapsed && (
125
- <>
126
- <nav aria-label="Main Navigation">
127
- <ul className="sidebar-list">
128
- {ungrouped.map((route) => (
129
- <li key={route.path}>
130
- <Link
131
- to={route.path === "" ? "/" : route.path}
132
- className={`sidebar-link ${location.pathname === route.path ? "active" : ""}`}
133
- aria-current={
134
- location.pathname === route.path ? "page" : undefined
135
- }
136
- >
137
- <div className="sidebar-link-content">
138
- <span>{route.title}</span>
139
- {renderBadge(route.badge)}
140
- </div>
141
- </Link>
142
- </li>
143
- ))}
144
- </ul>
145
-
146
- {groups.map((group) => (
147
- <SidebarGroupSection
148
- key={group.slug}
149
- group={group}
150
- currentPath={location.pathname}
151
- />
152
- ))}
153
- </nav>
154
- {config.themeConfig?.poweredBy !== false && <PoweredBy />}
155
- </>
156
- )}
157
- </aside>
158
- );
159
- }
160
-
161
- function SidebarGroupSection({
162
- group,
163
- currentPath,
164
- }: {
165
- group: SidebarGroup;
166
- currentPath: string;
167
- }) {
168
- const isActive = group.routes.some((r) => currentPath === r.path);
169
- const [open, setOpen] = useState(true);
170
-
171
- return (
172
- <div className="sidebar-group">
173
- <button
174
- className={`sidebar-group-header ${isActive ? "active" : ""}`}
175
- onClick={() => setOpen(!open)}
176
- aria-expanded={open}
177
- aria-controls={`sidebar-group-${group.slug}`}
178
- >
179
- <span className="sidebar-group-title">{group.title}</span>
180
- <span className={`sidebar-group-chevron ${open ? "open" : ""}`}>
181
- <ChevronRight size={16} />
182
- </span>
183
- </button>
184
- {open && (
185
- <ul className="sidebar-group-list" id={`sidebar-group-${group.slug}`}>
186
- {group.routes.map((route) => (
187
- <li key={route.path}>
188
- <Link
189
- to={route.path === "" ? "/" : route.path}
190
- className={`sidebar-link sidebar-link-nested ${currentPath === route.path ? "active" : ""}`}
191
- aria-current={currentPath === route.path ? "page" : undefined}
192
- >
193
- <div className="sidebar-link-content">
194
- <span>{route.title}</span>
195
- {renderBadge(route.badge)}
196
- </div>
197
- </Link>
198
- </li>
199
- ))}
200
- </ul>
201
- )}
202
- </div>
203
- );
204
- }
1
+ import React, { useState } from "react";
2
+ import { useLocation } from "react-router-dom";
3
+ import { Link } from "../Link";
4
+ import { BoltdocsConfig } from "../../../../node/config";
5
+ import { PoweredBy } from "../PoweredBy";
6
+ import { ChevronRight, ChevronLeft, PanelLeft } from "lucide-react";
7
+
8
+ interface RouteItem {
9
+ path: string;
10
+ title: string;
11
+ group?: string;
12
+ groupTitle?: string;
13
+ sidebarPosition?: number;
14
+ badge?: string | { text: string; expires?: string };
15
+ }
16
+
17
+ interface SidebarGroup {
18
+ slug: string;
19
+ title: string;
20
+ routes: RouteItem[];
21
+ }
22
+
23
+ /**
24
+ * Renders a small badge next to sidebar items if one exists and hasn't expired.
25
+ */
26
+ function renderBadge(badgeRaw: RouteItem["badge"]) {
27
+ if (!badgeRaw) return null;
28
+
29
+ let text = "";
30
+ let expires = "";
31
+
32
+ if (typeof badgeRaw === "string") {
33
+ text = badgeRaw;
34
+ } else {
35
+ text = badgeRaw.text;
36
+ expires = badgeRaw.expires || "";
37
+ }
38
+
39
+ // Check expiration
40
+ if (expires) {
41
+ const expireDate = new Date(expires);
42
+ const now = new Date();
43
+ // Reset time components for accurate day comparison
44
+ expireDate.setHours(0, 0, 0, 0);
45
+ now.setHours(0, 0, 0, 0);
46
+ if (now > expireDate) {
47
+ return null;
48
+ }
49
+ }
50
+
51
+ if (!text) return null;
52
+
53
+ if (!text) return null;
54
+
55
+ let typeClass = "badge-default";
56
+ const lowerText = text.toLowerCase();
57
+ if (lowerText === "new") {
58
+ typeClass = "badge-new";
59
+ } else if (lowerText === "experimental") {
60
+ typeClass = "badge-experimental";
61
+ } else if (lowerText === "updated") {
62
+ typeClass = "badge-updated";
63
+ }
64
+
65
+ return <span className={`sidebar-badge ${typeClass}`}>{text}</span>;
66
+ }
67
+
68
+ /**
69
+ * The sidebar navigation component.
70
+ * Groups documentation routes logically based on the `group` property.
71
+ * Highlights the active link based on the current URL path.
72
+ *
73
+ * @param routes - Array of all generated routes to be displayed
74
+ * @param config - Global configuration (which can contain sidebar overrides)
75
+ */
76
+ export function Sidebar({
77
+ routes,
78
+ config,
79
+ isCollapsed,
80
+ onToggle,
81
+ }: {
82
+ routes: RouteItem[];
83
+ config: BoltdocsConfig;
84
+ isCollapsed?: boolean;
85
+ onToggle?: () => void;
86
+ }) {
87
+ const location = useLocation();
88
+
89
+ const ungrouped: RouteItem[] = [];
90
+ const groupMap = new Map<string, SidebarGroup>();
91
+
92
+ for (const route of routes) {
93
+ if (!route.group) {
94
+ ungrouped.push(route);
95
+ } else {
96
+ if (!groupMap.has(route.group)) {
97
+ groupMap.set(route.group, {
98
+ slug: route.group,
99
+ title: route.groupTitle || route.group,
100
+ routes: [],
101
+ });
102
+ }
103
+ groupMap.get(route.group)!.routes.push(route);
104
+ }
105
+ }
106
+
107
+ const groups = Array.from(groupMap.values());
108
+
109
+ return (
110
+ <aside className="boltdocs-sidebar">
111
+ {onToggle && (
112
+ <div className="sidebar-collapse">
113
+ <button
114
+ className="sidebar-collapse-btn"
115
+ onClick={onToggle}
116
+ aria-label={isCollapsed ? "Expand Sidebar" : "Collapse Sidebar"}
117
+ title={isCollapsed ? "Expand Sidebar" : "Collapse Sidebar"}
118
+ >
119
+ <PanelLeft size={18} />
120
+ </button>
121
+ </div>
122
+ )}
123
+
124
+ {!isCollapsed && (
125
+ <>
126
+ <nav aria-label="Main Navigation">
127
+ <ul className="sidebar-list">
128
+ {ungrouped.map((route) => (
129
+ <li key={route.path}>
130
+ <Link
131
+ to={route.path === "" ? "/" : route.path}
132
+ className={`sidebar-link ${location.pathname === route.path ? "active" : ""}`}
133
+ aria-current={
134
+ location.pathname === route.path ? "page" : undefined
135
+ }
136
+ >
137
+ <div className="sidebar-link-content">
138
+ <span>{route.title}</span>
139
+ {renderBadge(route.badge)}
140
+ </div>
141
+ </Link>
142
+ </li>
143
+ ))}
144
+ </ul>
145
+
146
+ {groups.map((group) => (
147
+ <SidebarGroupSection
148
+ key={group.slug}
149
+ group={group}
150
+ currentPath={location.pathname}
151
+ />
152
+ ))}
153
+ </nav>
154
+ {config.themeConfig?.poweredBy !== false && <PoweredBy />}
155
+ </>
156
+ )}
157
+ </aside>
158
+ );
159
+ }
160
+
161
+ function SidebarGroupSection({
162
+ group,
163
+ currentPath,
164
+ }: {
165
+ group: SidebarGroup;
166
+ currentPath: string;
167
+ }) {
168
+ const isActive = group.routes.some((r) => currentPath === r.path);
169
+ const [open, setOpen] = useState(true);
170
+
171
+ return (
172
+ <div className="sidebar-group">
173
+ <button
174
+ className={`sidebar-group-header ${isActive ? "active" : ""}`}
175
+ onClick={() => setOpen(!open)}
176
+ aria-expanded={open}
177
+ aria-controls={`sidebar-group-${group.slug}`}
178
+ >
179
+ <span className="sidebar-group-title">{group.title}</span>
180
+ <span className={`sidebar-group-chevron ${open ? "open" : ""}`}>
181
+ <ChevronRight size={16} />
182
+ </span>
183
+ </button>
184
+ {open && (
185
+ <ul className="sidebar-group-list" id={`sidebar-group-${group.slug}`}>
186
+ {group.routes.map((route) => (
187
+ <li key={route.path}>
188
+ <Link
189
+ to={route.path === "" ? "/" : route.path}
190
+ className={`sidebar-link sidebar-link-nested ${currentPath === route.path ? "active" : ""}`}
191
+ aria-current={currentPath === route.path ? "page" : undefined}
192
+ >
193
+ <div className="sidebar-link-content">
194
+ <span>{route.title}</span>
195
+ {renderBadge(route.badge)}
196
+ </div>
197
+ </Link>
198
+ </li>
199
+ ))}
200
+ </ul>
201
+ )}
202
+ </div>
203
+ );
204
+ }
@@ -1 +1 @@
1
- export { Sidebar } from "./Sidebar";
1
+ export { Sidebar } from "./Sidebar";