boltdocs 1.0.4 → 1.3.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 (41) 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 +457 -118
  19. package/dist/node/index.mjs +93 -136
  20. package/package.json +2 -2
  21. package/src/client/app/index.tsx +25 -54
  22. package/src/client/theme/components/mdx/mdx-components.css +39 -20
  23. package/src/client/theme/styles/markdown.css +1 -1
  24. package/src/client/theme/styles.css +0 -1
  25. package/src/client/theme/ui/Layout/Layout.tsx +2 -13
  26. package/src/client/theme/ui/Layout/responsive.css +0 -4
  27. package/src/client/theme/ui/Link/Link.tsx +52 -0
  28. package/src/client/theme/ui/NotFound/NotFound.tsx +0 -1
  29. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +45 -2
  30. package/src/client/theme/ui/Sidebar/Sidebar.tsx +44 -40
  31. package/src/client/theme/ui/Sidebar/sidebar.css +25 -58
  32. package/src/node/cache.ts +360 -46
  33. package/src/node/config.ts +7 -0
  34. package/src/node/mdx.ts +83 -4
  35. package/src/node/plugin/index.ts +3 -0
  36. package/src/node/routes/cache.ts +5 -1
  37. package/src/node/routes/index.ts +17 -2
  38. package/src/node/ssg/index.ts +4 -0
  39. package/dist/Playground-B2FA34BC.mjs +0 -6
  40. package/dist/chunk-WPT4MWTQ.mjs +0 -89
  41. package/src/client/theme/styles/home.css +0 -60
@@ -1,133 +1,24 @@
1
+ import {
2
+ FileCache,
3
+ TransformCache,
4
+ capitalize,
5
+ escapeHtml,
6
+ extractNumberPrefix,
7
+ fileToRoutePath,
8
+ isDocFile,
9
+ normalizePath,
10
+ parseFrontmatter,
11
+ stripNumberPrefix
12
+ } from "../chunk-GSYECEZY.mjs";
13
+
1
14
  // src/node/plugin/index.ts
2
15
  import { loadEnv } from "vite";
3
16
 
4
17
  // src/node/routes/index.ts
5
18
  import fastGlob from "fast-glob";
6
19
 
7
- // src/node/utils.ts
8
- import fs from "fs";
9
- import matter from "gray-matter";
10
- function normalizePath(p) {
11
- return p.replace(/\\/g, "/");
12
- }
13
- function stripNumberPrefix(name) {
14
- return name.replace(/^\d+\./, "");
15
- }
16
- function extractNumberPrefix(name) {
17
- const match = name.match(/^(\d+)\./);
18
- return match ? parseInt(match[1], 10) : void 0;
19
- }
20
- function isDocFile(filePath) {
21
- return /\.mdx?$/.test(filePath);
22
- }
23
- function getFileMtime(filePath) {
24
- try {
25
- return fs.statSync(filePath).mtimeMs;
26
- } catch {
27
- return 0;
28
- }
29
- }
30
- function parseFrontmatter(filePath) {
31
- const raw = fs.readFileSync(filePath, "utf-8");
32
- const { data, content } = matter(raw);
33
- return { data, content };
34
- }
35
- function escapeHtml(str) {
36
- return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
37
- }
38
- function fileToRoutePath(relativePath) {
39
- let cleanedPath = relativePath.split("/").map(stripNumberPrefix).join("/");
40
- let routePath = cleanedPath.replace(/\.mdx?$/, "");
41
- if (routePath === "index" || routePath.endsWith("/index")) {
42
- routePath = routePath.replace(/index$/, "");
43
- }
44
- if (!routePath.startsWith("/")) {
45
- routePath = "/" + routePath;
46
- }
47
- if (routePath.length > 1 && routePath.endsWith("/")) {
48
- routePath = routePath.slice(0, -1);
49
- }
50
- return routePath;
51
- }
52
- function capitalize(str) {
53
- return str.charAt(0).toUpperCase() + str.slice(1);
54
- }
55
-
56
- // src/node/cache.ts
57
- var FileCache = class {
58
- entries = /* @__PURE__ */ new Map();
59
- /**
60
- * Retrieves parsed data for a file from the cache.
61
- * Compares the current filesystem mtime with the cached mtime.
62
- *
63
- * @param filePath - The absolute path of the file
64
- * @returns The cached data if valid, or `null` if the file has changed or doesn't exist
65
- */
66
- get(filePath) {
67
- const entry = this.entries.get(filePath);
68
- if (!entry) return null;
69
- const currentMtime = getFileMtime(filePath);
70
- if (currentMtime !== entry.mtime) return null;
71
- return entry.data;
72
- }
73
- /**
74
- * Stores parsed data for a file in the cache, recording its current mtime.
75
- *
76
- * @param filePath - The absolute path to the file
77
- * @param data - The parsed data to store
78
- */
79
- set(filePath, data) {
80
- this.entries.set(filePath, {
81
- data,
82
- mtime: getFileMtime(filePath)
83
- });
84
- }
85
- /**
86
- * Checks if a specific file's cache is still valid (based on its mtime).
87
- *
88
- * @param filePath - The absolute path to the file
89
- * @returns `true` if the cache is valid, `false` otherwise
90
- */
91
- isValid(filePath) {
92
- return this.get(filePath) !== null;
93
- }
94
- /**
95
- * Manually removes a specific file from the cache.
96
- * Useful when forcefully invalidating a single updated file.
97
- *
98
- * @param filePath - The absolute path to the file
99
- */
100
- invalidate(filePath) {
101
- this.entries.delete(filePath);
102
- }
103
- /**
104
- * Clears the entire cache, forcing all files to be re-parsed on the next request.
105
- * Useful when global dependencies (like config) change.
106
- */
107
- invalidateAll() {
108
- this.entries.clear();
109
- }
110
- /**
111
- * Removes cached entries for files that no longer exist on the filesystem.
112
- * Prevents memory leaks from deleted files.
113
- *
114
- * @param currentFiles - A Set of absolute file paths currently discovered on the disk
115
- */
116
- pruneStale(currentFiles) {
117
- for (const key of this.entries.keys()) {
118
- if (!currentFiles.has(key)) {
119
- this.entries.delete(key);
120
- }
121
- }
122
- }
123
- /** Number of cached entries */
124
- get size() {
125
- return this.entries.size;
126
- }
127
- };
128
-
129
20
  // src/node/routes/cache.ts
130
- var docCache = new FileCache();
21
+ var docCache = new FileCache({ name: "routes" });
131
22
  function invalidateRouteCache() {
132
23
  docCache.invalidateAll();
133
24
  }
@@ -240,6 +131,7 @@ function compareByGroupPosition(a, b) {
240
131
 
241
132
  // src/node/routes/index.ts
242
133
  async function generateRoutes(docsDir, config, basePath = "/docs") {
134
+ docCache.load();
243
135
  const files = await fastGlob(["**/*.md", "**/*.mdx"], {
244
136
  cwd: docsDir,
245
137
  absolute: true
@@ -248,15 +140,25 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
248
140
  if (config?.i18n) {
249
141
  docCache.invalidateAll();
250
142
  }
143
+ let cacheHits = 0;
251
144
  const parsed = await Promise.all(
252
145
  files.map(async (file) => {
253
146
  const cached = docCache.get(file);
254
- if (cached) return cached;
147
+ if (cached) {
148
+ cacheHits++;
149
+ return cached;
150
+ }
255
151
  const result = parseDocFile(file, docsDir, basePath, config);
256
152
  docCache.set(file, result);
257
153
  return result;
258
154
  })
259
155
  );
156
+ if (files.length > 0) {
157
+ console.log(
158
+ `[boltdocs] Routes generated: ${files.length} files (${cacheHits} from cache, ${files.length - cacheHits} parsed)`
159
+ );
160
+ }
161
+ docCache.save();
260
162
  const groupMeta = /* @__PURE__ */ new Map();
261
163
  for (const p of parsed) {
262
164
  if (p.relativeDir) {
@@ -336,7 +238,7 @@ import { ViteImageOptimizer } from "vite-plugin-image-optimizer";
336
238
  // src/node/config.ts
337
239
  import path2 from "path";
338
240
  import { pathToFileURL } from "url";
339
- import fs2 from "fs";
241
+ import fs from "fs";
340
242
  var CONFIG_FILES = [
341
243
  "boltdocs.config.js",
342
244
  "boltdocs.config.mjs",
@@ -357,7 +259,7 @@ async function resolveConfig(docsDir) {
357
259
  };
358
260
  for (const filename of CONFIG_FILES) {
359
261
  const configPath = path2.resolve(projectRoot, filename);
360
- if (fs2.existsSync(configPath)) {
262
+ if (fs.existsSync(configPath)) {
361
263
  try {
362
264
  const fileUrl = pathToFileURL(configPath).href + "?t=" + Date.now();
363
265
  const mod = await import(fileUrl);
@@ -383,7 +285,7 @@ async function resolveConfig(docsDir) {
383
285
  }
384
286
 
385
287
  // src/node/ssg/index.ts
386
- import fs3 from "fs";
288
+ import fs2 from "fs";
387
289
  import path3 from "path";
388
290
  import { fileURLToPath } from "url";
389
291
  import { createRequire } from "module";
@@ -456,7 +358,7 @@ async function generateStaticPages(options) {
456
358
  const siteTitle = config?.themeConfig?.title || "Boltdocs";
457
359
  const siteDescription = config?.themeConfig?.description || "";
458
360
  const ssrModulePath = path3.resolve(_dirname, "../client/ssr.js");
459
- if (!fs3.existsSync(ssrModulePath)) {
361
+ if (!fs2.existsSync(ssrModulePath)) {
460
362
  console.error(
461
363
  "[boltdocs] SSR module not found at",
462
364
  ssrModulePath,
@@ -466,11 +368,11 @@ async function generateStaticPages(options) {
466
368
  }
467
369
  const { render } = _require(ssrModulePath);
468
370
  const templatePath = path3.join(outDir, "index.html");
469
- if (!fs3.existsSync(templatePath)) {
371
+ if (!fs2.existsSync(templatePath)) {
470
372
  console.warn("[boltdocs] No index.html found in outDir, skipping SSG.");
471
373
  return;
472
374
  }
473
- const template = fs3.readFileSync(templatePath, "utf-8");
375
+ const template = fs2.readFileSync(templatePath, "utf-8");
474
376
  let homePageComp;
475
377
  if (config?._homePagePath) {
476
378
  try {
@@ -497,8 +399,8 @@ async function generateStaticPages(options) {
497
399
  description: escapeHtml(pageDescription)
498
400
  }).replace("<!--app-html-->", appHtml).replace(`<div id="root"></div>`, `<div id="root">${appHtml}</div>`);
499
401
  const routeDir = path3.join(outDir, route.path);
500
- await fs3.promises.mkdir(routeDir, { recursive: true });
501
- await fs3.promises.writeFile(
402
+ await fs2.promises.mkdir(routeDir, { recursive: true });
403
+ await fs2.promises.writeFile(
502
404
  path3.join(routeDir, "index.html"),
503
405
  html,
504
406
  "utf-8"
@@ -512,10 +414,12 @@ async function generateStaticPages(options) {
512
414
  routes.map((r) => r.path),
513
415
  config
514
416
  );
515
- fs3.writeFileSync(path3.join(outDir, "sitemap.xml"), sitemap, "utf-8");
417
+ fs2.writeFileSync(path3.join(outDir, "sitemap.xml"), sitemap, "utf-8");
516
418
  console.log(
517
419
  `[boltdocs] Generated ${routes.length} static pages + sitemap.xml`
518
420
  );
421
+ const { flushCache } = await import("../cache-EHR7SXRU.mjs");
422
+ await flushCache();
519
423
  }
520
424
 
521
425
  // src/node/plugin/index.ts
@@ -696,6 +600,8 @@ function boltdocsPlugin(options = {}, passedConfig) {
696
600
  if (!isBuild) return;
697
601
  const outDir = viteConfig?.build?.outDir ? path4.resolve(viteConfig.root, viteConfig.build.outDir) : path4.resolve(process.cwd(), "dist");
698
602
  await generateStaticPages({ docsDir, outDir, config });
603
+ const { flushCache } = await import("../cache-EHR7SXRU.mjs");
604
+ await flushCache();
699
605
  }
700
606
  },
701
607
  ViteImageOptimizer({
@@ -725,10 +631,13 @@ import remarkGfm from "remark-gfm";
725
631
  import remarkFrontmatter from "remark-frontmatter";
726
632
  import rehypeSlug from "rehype-slug";
727
633
  import rehypePrettyCode from "rehype-pretty-code";
634
+ import crypto from "crypto";
635
+ var mdxCache = new TransformCache("mdx");
636
+ var mdxCacheLoaded = false;
728
637
  function boltdocsMdxPlugin(config) {
729
638
  const extraRemarkPlugins = config?.plugins?.flatMap((p) => p.remarkPlugins || []) || [];
730
639
  const extraRehypePlugins = config?.plugins?.flatMap((p) => p.rehypePlugins || []) || [];
731
- return mdxPlugin({
640
+ const baseMdxPlugin = mdxPlugin({
732
641
  remarkPlugins: [remarkGfm, remarkFrontmatter, ...extraRemarkPlugins],
733
642
  rehypePlugins: [
734
643
  rehypeSlug,
@@ -736,16 +645,64 @@ function boltdocsMdxPlugin(config) {
736
645
  [
737
646
  rehypePrettyCode,
738
647
  {
739
- theme: "one-dark-pro",
648
+ theme: config?.themeConfig?.codeTheme || "one-dark-pro",
740
649
  keepBackground: false
741
650
  }
742
651
  ]
743
652
  ],
744
- // Provide React as default for JSX
745
653
  jsxRuntime: "automatic",
746
654
  providerImportSource: "@mdx-js/react"
747
655
  });
656
+ return {
657
+ ...baseMdxPlugin,
658
+ name: "vite-plugin-boltdocs-mdx",
659
+ async buildStart() {
660
+ hits = 0;
661
+ total = 0;
662
+ if (!mdxCacheLoaded) {
663
+ mdxCache.load();
664
+ mdxCacheLoaded = true;
665
+ }
666
+ if (baseMdxPlugin.buildStart) {
667
+ await baseMdxPlugin.buildStart.call(this);
668
+ }
669
+ },
670
+ async transform(code, id, options) {
671
+ if (!id.endsWith(".md") && !id.endsWith(".mdx")) {
672
+ return baseMdxPlugin.transform?.call(this, code, id, options);
673
+ }
674
+ total++;
675
+ const contentHash = crypto.createHash("md5").update(code).digest("hex");
676
+ const cacheKey = `${id}:${contentHash}`;
677
+ const cached = mdxCache.get(cacheKey);
678
+ if (cached) {
679
+ hits++;
680
+ return { code: cached, map: null };
681
+ }
682
+ const result = await baseMdxPlugin.transform.call(
683
+ this,
684
+ code,
685
+ id,
686
+ options
687
+ );
688
+ if (result && typeof result === "object" && result.code) {
689
+ mdxCache.set(cacheKey, result.code);
690
+ } else if (typeof result === "string") {
691
+ mdxCache.set(cacheKey, result);
692
+ }
693
+ return result;
694
+ },
695
+ async buildEnd() {
696
+ mdxCache.save();
697
+ await mdxCache.flush();
698
+ if (baseMdxPlugin.buildEnd) {
699
+ await baseMdxPlugin.buildEnd.call(this);
700
+ }
701
+ }
702
+ };
748
703
  }
704
+ var hits = 0;
705
+ var total = 0;
749
706
 
750
707
  // src/node/index.ts
751
708
  async function boltdocs(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "boltdocs",
3
- "version": "1.0.4",
3
+ "version": "1.3.0",
4
4
  "description": "A lightweight documentation generator for React projects.",
5
5
  "main": "dist/node/index.js",
6
6
  "module": "dist/node/index.mjs",
@@ -54,7 +54,7 @@
54
54
  "remark-gfm": "^4.0.1",
55
55
  "sharp": "^0.34.5",
56
56
  "shiki": "^3.23.0",
57
- "svgo": "^4.0.0",
57
+ "svgo": "^4.0.1",
58
58
  "unist-util-visit": "^5.1.0",
59
59
  "vite": "^7.3.1",
60
60
  "vite-plugin-image-optimizer": "^2.0.3"
@@ -40,27 +40,6 @@ const PackageManagerTabs = lazy(() =>
40
40
  default: m.PackageManagerTabs,
41
41
  })),
42
42
  );
43
- const Playground = lazy(() =>
44
- import("../theme/components/Playground").then((m) => ({
45
- default: m.Playground,
46
- })),
47
- );
48
-
49
- import {
50
- Button,
51
- Badge,
52
- Card,
53
- Cards,
54
- Tabs,
55
- Tab,
56
- Admonition,
57
- Note,
58
- Tip,
59
- Warning,
60
- Danger,
61
- InfoBox,
62
- List,
63
- } from "../theme/components/mdx";
64
43
  declare global {
65
44
  interface ImportMeta {
66
45
  env: Record<string, any>;
@@ -115,24 +94,6 @@ const mdxComponents = {
115
94
  <PackageManagerTabs {...props} />
116
95
  </Suspense>
117
96
  ),
118
- Playground: (props: any) => (
119
- <Suspense fallback={<div className="playground-skeleton" />}>
120
- <Playground {...props} />
121
- </Suspense>
122
- ),
123
- Button,
124
- Badge,
125
- Card,
126
- Cards,
127
- Tabs,
128
- Tab,
129
- Admonition,
130
- Note,
131
- Tip,
132
- Warning,
133
- Danger,
134
- InfoBox,
135
- List,
136
97
  };
137
98
 
138
99
  export function AppShell({
@@ -152,20 +113,9 @@ export function AppShell({
152
113
  }) {
153
114
  const [routesInfo, setRoutesInfo] = useState<ComponentRoute[]>(initialRoutes);
154
115
  const [config] = useState(initialConfig);
155
- const [resolvedRoutes, setResolvedRoutes] = useState<any[]>([]);
156
-
157
- // Subscribe to HMR events
158
- useEffect(() => {
159
- if (hot) {
160
- hot.on("boltdocs:routes-update", (newRoutes: ComponentRoute[]) => {
161
- setRoutesInfo(newRoutes);
162
- });
163
- }
164
- }, [hot]);
165
116
 
166
- // Resolve MDX components
167
- useEffect(() => {
168
- const mapped = routesInfo
117
+ const resolveRoutes = (infos: ComponentRoute[]) => {
118
+ return infos
169
119
  .filter(
170
120
  (route) => !(HomePage && (route.path === "/" || route.path === "")),
171
121
  )
@@ -184,8 +134,24 @@ export function AppShell({
184
134
  }),
185
135
  };
186
136
  });
137
+ };
138
+
139
+ const [resolvedRoutes, setResolvedRoutes] = useState<any[]>(() =>
140
+ resolveRoutes(initialRoutes),
141
+ );
142
+
143
+ // Subscribe to HMR events
144
+ useEffect(() => {
145
+ if (hot) {
146
+ hot.on("boltdocs:routes-update", (newRoutes: ComponentRoute[]) => {
147
+ setRoutesInfo(newRoutes);
148
+ });
149
+ }
150
+ }, [hot]);
187
151
 
188
- setResolvedRoutes(mapped);
152
+ // Sync resolved routes when info or modules change
153
+ useEffect(() => {
154
+ setResolvedRoutes(resolveRoutes(routesInfo));
189
155
  }, [routesInfo, modules]);
190
156
 
191
157
  return (
@@ -213,7 +179,10 @@ export function AppShell({
213
179
  )}
214
180
 
215
181
  {/* Documentation pages WITH sidebar + TOC layout */}
216
- <Route element={<DocsLayout config={config} routes={routesInfo} />}>
182
+ <Route
183
+ key="docs-layout"
184
+ element={<DocsLayout config={config} routes={routesInfo} />}
185
+ >
217
186
  {resolvedRoutes.map((route: any) => (
218
187
  <Route
219
188
  key={route.path}
@@ -255,6 +224,8 @@ function ScrollHandler() {
255
224
  const { pathname, hash } = useLocation();
256
225
 
257
226
  useLayoutEffect(() => {
227
+ // Only scroll if we are not in a pending transition state (if we were using useTransition)
228
+ // For now, we ensure the scroll happens.
258
229
  if (hash) {
259
230
  const id = hash.replace("#", "");
260
231
  const element = document.getElementById(id);
@@ -6,54 +6,77 @@
6
6
 
7
7
  /* ─── Button ──────────────────────────────────────────────── */
8
8
  .ld-btn {
9
+ /* Total Reset */
10
+ all: unset;
11
+ box-sizing: border-box !important;
9
12
  display: inline-flex;
10
13
  align-items: center;
11
- gap: 0.4rem;
14
+ justify-content: center;
15
+ gap: 0.5rem;
16
+
17
+ /* Typography */
18
+ font-family: var(--ld-font-sans);
12
19
  font-weight: 600;
20
+ font-size: 0.9375rem;
21
+ line-height: normal; /* Essential for flex centering */
22
+ letter-spacing: -0.01em;
23
+ text-align: center;
24
+ text-decoration: none !important;
25
+ white-space: nowrap;
26
+
27
+ /* Appearance */
13
28
  border-radius: var(--ld-radius-md);
14
29
  cursor: pointer;
15
- transition: all 300ms cubic-bezier(0.16, 1, 0.3, 1);
16
- font-family: var(--ld-font-sans);
30
+ transition: all 250ms cubic-bezier(0.4, 0, 0.2, 1);
17
31
  border: 1px solid transparent;
18
- line-height: 1;
19
- letter-spacing: -0.01em;
32
+ user-select: none;
33
+ position: relative;
20
34
  }
21
35
 
22
36
  .ld-btn:hover {
23
- transform: scale(1.05);
37
+ transform: translateY(-1px);
24
38
  }
25
39
 
26
40
  .ld-btn:active {
27
- transform: scale(0.95);
41
+ transform: translateY(0) scale(0.98);
28
42
  }
29
43
 
30
44
  /* sizes */
31
45
  .ld-btn--sm {
32
- padding: 0.45rem 1.1rem;
46
+ min-height: 2rem;
47
+ padding: 0 1rem;
33
48
  font-size: 0.8125rem;
34
49
  border-radius: var(--ld-radius-md);
35
50
  }
36
51
  .ld-btn--md {
37
- padding: 0.7rem 1.6rem;
52
+ min-height: 2.625rem;
53
+ padding: 0 1.6rem;
38
54
  font-size: 0.9375rem;
39
55
  }
40
56
  .ld-btn--lg {
41
- padding: 0.85rem 2.1rem;
57
+ min-height: 3.25rem;
58
+ padding: 0 2.2rem;
42
59
  font-size: 1.05rem;
43
60
  }
44
61
 
45
62
  /* variants */
46
63
  .ld-btn--primary {
47
- background-color: var(--ld-ui-btn-primary-bg, var(--ld-btn-primary-bg));
64
+ background-color: var(
65
+ --ld-ui-btn-primary-bg,
66
+ var(--ld-btn-primary-bg)
67
+ ) !important;
48
68
  color: var(--ld-ui-btn-primary-text, var(--ld-btn-primary-text)) !important;
69
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
49
70
  }
50
71
  .ld-btn--primary:hover {
51
- opacity: 0.92;
52
- color: var(--ld-ui-btn-primary-text, var(--ld-btn-primary-text)) !important;
72
+ filter: brightness(1.1);
53
73
  }
54
74
 
55
75
  .ld-btn--secondary {
56
- background-color: var(--ld-ui-btn-secondary-bg, var(--ld-btn-secondary-bg));
76
+ background-color: var(
77
+ --ld-ui-btn-secondary-bg,
78
+ var(--ld-btn-secondary-bg)
79
+ ) !important;
57
80
  color: var(
58
81
  --ld-ui-btn-secondary-text,
59
82
  var(--ld-btn-secondary-text)
@@ -63,14 +86,10 @@
63
86
  .ld-btn--secondary:hover {
64
87
  background-color: var(--ld-bg-mute);
65
88
  border-color: var(--ld-border-strong);
66
- color: var(
67
- --ld-ui-btn-secondary-text,
68
- var(--ld-btn-secondary-text)
69
- ) !important;
70
89
  }
71
90
 
72
91
  .ld-btn--outline {
73
- background: transparent;
92
+ background: transparent !important;
74
93
  color: var(--ld-text-main) !important;
75
94
  border-color: var(--ld-border-strong);
76
95
  }
@@ -80,7 +99,7 @@
80
99
  }
81
100
 
82
101
  .ld-btn--ghost {
83
- background: transparent;
102
+ background: transparent !important;
84
103
  color: var(--ld-text-muted) !important;
85
104
  }
86
105
  .ld-btn--ghost:hover {
@@ -288,7 +288,7 @@
288
288
 
289
289
  .boltdocs-page pre > code {
290
290
  display: grid;
291
- padding: 1rem 0;
291
+ padding: 1rem 1rem;
292
292
  background-color: transparent;
293
293
  border: none;
294
294
  color: inherit;
@@ -27,7 +27,6 @@
27
27
  @import "./ui/Layout/pagination.css";
28
28
 
29
29
  /* Pages */
30
- @import "./styles/home.css";
31
30
  @import "./ui/NotFound/not-found.css";
32
31
  @import "./ui/Loading/loading.css";
33
32
 
@@ -139,22 +139,11 @@ export function ThemeLayout({
139
139
  <Sidebar
140
140
  routes={filteredRoutes}
141
141
  config={config}
142
- onCollapse={() => setIsSidebarOpen(false)}
142
+ isCollapsed={!isSidebarOpen}
143
+ onToggle={() => setIsSidebarOpen(!isSidebarOpen)}
143
144
  />
144
145
  )}
145
146
 
146
- {/* Floating Expand Button when Sidebar is Collapsed */}
147
- {sidebar === undefined && (
148
- <button
149
- className="sidebar-toggle-floating"
150
- onClick={() => setIsSidebarOpen(true)}
151
- aria-label="Expand Sidebar"
152
- title="Expand Sidebar"
153
- >
154
- <Menu size={20} />
155
- </button>
156
- )}
157
-
158
147
  <main className="boltdocs-content">
159
148
  {breadcrumbs !== undefined ? (
160
149
  breadcrumbs
@@ -12,10 +12,6 @@
12
12
  display: none;
13
13
  }
14
14
 
15
- .sidebar-toggle-floating {
16
- display: none !important;
17
- }
18
-
19
15
  .boltdocs-content {
20
16
  padding: 1.5rem 1rem 3rem;
21
17
  }