boltdocs 1.7.1 → 1.9.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 (38) hide show
  1. package/dist/{SearchDialog-GOZ6X53X.css → SearchDialog-BEVZQ74P.css} +202 -15
  2. package/dist/{SearchDialog-6Z7CUAYJ.mjs → SearchDialog-MEWGAONO.mjs} +1 -1
  3. package/dist/{chunk-SFVOGJ2W.mjs → chunk-OZLYRXAD.mjs} +228 -149
  4. package/dist/client/index.css +202 -15
  5. package/dist/client/index.d.mts +25 -4
  6. package/dist/client/index.d.ts +25 -4
  7. package/dist/client/index.js +439 -309
  8. package/dist/client/index.mjs +29 -1
  9. package/dist/client/ssr.css +202 -15
  10. package/dist/client/ssr.d.mts +1 -1
  11. package/dist/client/ssr.d.ts +1 -1
  12. package/dist/client/ssr.js +276 -175
  13. package/dist/client/ssr.mjs +1 -1
  14. package/dist/{config-D68h41CA.d.ts → config-BsFQ-ErD.d.mts} +9 -0
  15. package/dist/{config-D68h41CA.d.mts → config-BsFQ-ErD.d.ts} +9 -0
  16. package/dist/node/index.d.mts +4 -2
  17. package/dist/node/index.d.ts +4 -2
  18. package/dist/node/index.js +2 -1
  19. package/dist/node/index.mjs +2 -1
  20. package/dist/{types-BbceAHA0.d.mts → types-Dj-bfnC3.d.mts} +2 -0
  21. package/dist/{types-BbceAHA0.d.ts → types-Dj-bfnC3.d.ts} +2 -0
  22. package/package.json +1 -1
  23. package/src/client/index.ts +2 -0
  24. package/src/client/theme/components/mdx/Field.tsx +60 -0
  25. package/src/client/theme/components/mdx/index.ts +3 -0
  26. package/src/client/theme/components/mdx/mdx-components.css +95 -0
  27. package/src/client/theme/styles/variables.css +1 -1
  28. package/src/client/theme/styles.css +1 -0
  29. package/src/client/theme/ui/CopyMarkdown/CopyMarkdown.tsx +82 -0
  30. package/src/client/theme/ui/CopyMarkdown/copy-markdown.css +114 -0
  31. package/src/client/theme/ui/CopyMarkdown/index.ts +1 -0
  32. package/src/client/theme/ui/Layout/Layout.tsx +7 -0
  33. package/src/client/theme/ui/Layout/base.css +18 -1
  34. package/src/client/theme/ui/Link/link-preview.css +1 -20
  35. package/src/client/types.ts +2 -0
  36. package/src/node/config.ts +6 -0
  37. package/src/node/routes/parser.ts +1 -0
  38. package/src/node/routes/types.ts +2 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AppShell
3
- } from "../chunk-SFVOGJ2W.mjs";
3
+ } from "../chunk-OZLYRXAD.mjs";
4
4
  import "../chunk-FMTOYQLO.mjs";
5
5
 
6
6
  // src/client/ssr.tsx
@@ -93,6 +93,15 @@ interface BoltdocsThemeConfig {
93
93
  * Default: 'one-dark-pro'
94
94
  */
95
95
  codeTheme?: string | Record<string, string>;
96
+ /**
97
+ * Configuration for the 'Copy Markdown' button.
98
+ * Can be a boolean or an object with text and icon.
99
+ * Default: true
100
+ */
101
+ copyMarkdown?: boolean | {
102
+ text?: string;
103
+ icon?: string;
104
+ };
96
105
  }
97
106
  /**
98
107
  * Configuration for internationalization (i18n).
@@ -93,6 +93,15 @@ interface BoltdocsThemeConfig {
93
93
  * Default: 'one-dark-pro'
94
94
  */
95
95
  codeTheme?: string | Record<string, string>;
96
+ /**
97
+ * Configuration for the 'Copy Markdown' button.
98
+ * Can be a boolean or an object with text and icon.
99
+ * Default: true
100
+ */
101
+ copyMarkdown?: boolean | {
102
+ text?: string;
103
+ icon?: string;
104
+ };
96
105
  }
97
106
  /**
98
107
  * Configuration for internationalization (i18n).
@@ -1,6 +1,6 @@
1
1
  import { Plugin } from 'vite';
2
- import { B as BoltdocsConfig } from '../config-D68h41CA.mjs';
3
- export { a as BoltdocsThemeConfig } from '../config-D68h41CA.mjs';
2
+ import { B as BoltdocsConfig } from '../config-BsFQ-ErD.mjs';
3
+ export { a as BoltdocsThemeConfig } from '../config-BsFQ-ErD.mjs';
4
4
 
5
5
  /**
6
6
  * Configuration options specifically for the Boltdocs Vite plugin.
@@ -82,6 +82,8 @@ interface RouteMeta {
82
82
  tab?: string;
83
83
  /** The extracted plain-text content of the page for search indexing */
84
84
  _content?: string;
85
+ /** The raw markdown content of the page */
86
+ _rawContent?: string;
85
87
  }
86
88
 
87
89
  declare function boltdocs(options?: BoltdocsPluginOptions): Promise<Plugin[]>;
@@ -1,6 +1,6 @@
1
1
  import { Plugin } from 'vite';
2
- import { B as BoltdocsConfig } from '../config-D68h41CA.js';
3
- export { a as BoltdocsThemeConfig } from '../config-D68h41CA.js';
2
+ import { B as BoltdocsConfig } from '../config-BsFQ-ErD.js';
3
+ export { a as BoltdocsThemeConfig } from '../config-BsFQ-ErD.js';
4
4
 
5
5
  /**
6
6
  * Configuration options specifically for the Boltdocs Vite plugin.
@@ -82,6 +82,8 @@ interface RouteMeta {
82
82
  tab?: string;
83
83
  /** The extracted plain-text content of the page for search indexing */
84
84
  _content?: string;
85
+ /** The raw markdown content of the page */
86
+ _rawContent?: string;
85
87
  }
86
88
 
87
89
  declare function boltdocs(options?: BoltdocsPluginOptions): Promise<Plugin[]>;
@@ -544,7 +544,8 @@ function parseDocFile(file, docsDir, basePath, config) {
544
544
  badge: sanitizedBadge,
545
545
  icon,
546
546
  tab: inferredTab,
547
- _content: plainText
547
+ _content: plainText,
548
+ _rawContent: content
548
549
  },
549
550
  relativeDir: cleanDirName,
550
551
  isGroupIndex,
@@ -126,7 +126,8 @@ function parseDocFile(file, docsDir, basePath, config) {
126
126
  badge: sanitizedBadge,
127
127
  icon,
128
128
  tab: inferredTab,
129
- _content: plainText
129
+ _content: plainText,
130
+ _rawContent: content
130
131
  },
131
132
  relativeDir: cleanDirName,
132
133
  isGroupIndex,
@@ -46,6 +46,8 @@ interface ComponentRoute {
46
46
  groupIcon?: string;
47
47
  /** The extracted plain-text content of the page for search indexing */
48
48
  _content?: string;
49
+ /** The raw markdown content of the page */
50
+ _rawContent?: string;
49
51
  }
50
52
  /**
51
53
  * Configuration options for initializing the Boltdocs client app.
@@ -46,6 +46,8 @@ interface ComponentRoute {
46
46
  groupIcon?: string;
47
47
  /** The extracted plain-text content of the page for search indexing */
48
48
  _content?: string;
49
+ /** The raw markdown content of the page */
50
+ _rawContent?: string;
49
51
  }
50
52
  /**
51
53
  * Configuration options for initializing the Boltdocs client app.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "boltdocs",
3
- "version": "1.7.1",
3
+ "version": "1.9.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",
@@ -30,6 +30,7 @@ export {
30
30
  List,
31
31
  FileTree,
32
32
  Table,
33
+ Field,
33
34
  } from "./theme/components/mdx";
34
35
  export type {
35
36
  ButtonProps,
@@ -42,4 +43,5 @@ export type {
42
43
  ListProps,
43
44
  FileTreeProps,
44
45
  TableProps,
46
+ FieldProps,
45
47
  } from "./theme/components/mdx";
@@ -0,0 +1,60 @@
1
+ import React from "react";
2
+
3
+ export interface FieldProps {
4
+ /** The name of the property or field */
5
+ name: string;
6
+ /** The data type of the field (e.g., "string", "number", "boolean") */
7
+ type?: string;
8
+ /** The default value if not provided */
9
+ defaultValue?: string;
10
+ /** Whether the field is required */
11
+ required?: boolean;
12
+ /** Description or additional content */
13
+ children: React.ReactNode;
14
+ /** Optional anchor ID for linking */
15
+ id?: string;
16
+ /** Optional extra class name */
17
+ className?: string;
18
+ }
19
+
20
+ /**
21
+ * A highly aesthetic and readable component for documenting API fields/properties.
22
+ */
23
+ export function Field({
24
+ name,
25
+ type,
26
+ defaultValue,
27
+ required = false,
28
+ children,
29
+ id,
30
+ className = "",
31
+ }: FieldProps) {
32
+ return (
33
+ <div className={`ld-field ${className}`.trim()} id={id}>
34
+ <div className="ld-field__header">
35
+ <div className="ld-field__signature">
36
+ <code className="ld-field__name">{name}</code>
37
+ {type && (
38
+ <span className="ld-field__type-badge">
39
+ {type}
40
+ </span>
41
+ )}
42
+ {required && (
43
+ <span className="ld-field__required-badge">required</span>
44
+ )}
45
+ </div>
46
+
47
+ {defaultValue && (
48
+ <div className="ld-field__default">
49
+ <span className="ld-field__default-label">Default:</span>
50
+ <code className="ld-field__default-value">{defaultValue}</code>
51
+ </div>
52
+ )}
53
+ </div>
54
+
55
+ <div className="ld-field__content">
56
+ {children}
57
+ </div>
58
+ </div>
59
+ );
60
+ }
@@ -22,3 +22,6 @@ export type { FileTreeProps } from "./FileTree";
22
22
 
23
23
  export { Table } from "./Table";
24
24
  export type { TableProps } from "./Table";
25
+
26
+ export { Field } from "./Field";
27
+ export type { FieldProps } from "./Field";
@@ -667,3 +667,98 @@
667
667
  opacity: 0.4;
668
668
  cursor: not-allowed;
669
669
  }
670
+ /* ─── Field ───────────────────────────────────────────────── */
671
+ .ld-field {
672
+ margin: 1.5rem 0;
673
+ padding: 1.25rem;
674
+ border-radius: var(--ld-radius-lg);
675
+ border: 1px solid var(--ld-border-subtle);
676
+ background: var(--ld-bg-soft);
677
+ position: relative;
678
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
679
+ }
680
+
681
+ .ld-field:hover {
682
+ border-color: var(--ld-color-primary);
683
+ box-shadow: 0 4px 20px -8px rgba(127, 19, 236, 0.15);
684
+ }
685
+
686
+ .ld-field__header {
687
+ display: flex;
688
+ flex-wrap: wrap;
689
+ align-items: center;
690
+ justify-content: space-between;
691
+ gap: 1rem;
692
+ margin-bottom: 0.85rem;
693
+ padding-bottom: 0.85rem;
694
+ border-bottom: 1px solid var(--ld-border-subtle);
695
+ }
696
+
697
+ .ld-field__signature {
698
+ display: flex;
699
+ align-items: center;
700
+ gap: 0.75rem;
701
+ }
702
+
703
+ .ld-field__name {
704
+ font-family: var(--ld-font-mono);
705
+ font-size: 0.95rem;
706
+ font-weight: 700;
707
+ color: var(--ld-text-main);
708
+ background: rgba(127, 19, 236, 0.08);
709
+ padding: 0.2rem 0.6rem;
710
+ border-radius: var(--ld-radius-sm);
711
+ letter-spacing: -0.01em;
712
+ }
713
+
714
+ .ld-field__type-badge {
715
+ font-family: var(--ld-font-mono);
716
+ font-size: 0.75rem;
717
+ font-weight: 500;
718
+ color: var(--ld-color-primary);
719
+ background: var(--ld-color-primary-muted);
720
+ padding: 0.15rem 0.5rem;
721
+ border-radius: var(--ld-radius-full);
722
+ border: 1px solid rgba(127, 19, 236, 0.2);
723
+ }
724
+
725
+ .ld-field__required-badge {
726
+ font-size: 0.7rem;
727
+ font-weight: 700;
728
+ text-transform: uppercase;
729
+ color: var(--ld-ui-danger-text);
730
+ background: var(--ld-ui-danger-bg);
731
+ padding: 0.1rem 0.4rem;
732
+ border-radius: var(--ld-radius-sm);
733
+ letter-spacing: 0.05em;
734
+ }
735
+
736
+ .ld-field__default {
737
+ display: flex;
738
+ align-items: center;
739
+ gap: 0.5rem;
740
+ font-size: 0.8rem;
741
+ }
742
+
743
+ .ld-field__default-label {
744
+ color: var(--ld-text-dim);
745
+ font-weight: 500;
746
+ }
747
+
748
+ .ld-field__default-value {
749
+ font-family: var(--ld-font-mono);
750
+ color: var(--ld-text-main);
751
+ background: var(--ld-bg-mute);
752
+ padding: 0.15rem 0.4rem;
753
+ border-radius: var(--ld-radius-sm);
754
+ }
755
+
756
+ .ld-field__content {
757
+ font-size: 0.875rem;
758
+ line-height: 1.6;
759
+ color: var(--ld-text-muted);
760
+ }
761
+
762
+ .ld-field__content p {
763
+ margin: 0;
764
+ }
@@ -41,7 +41,7 @@
41
41
  --ld-code-text: #1f2937;
42
42
 
43
43
  /* ─ Customization ─ */
44
- --ld-navbar-bg: rgba(255, 255, 255, 0.82);
44
+ --ld-navbar-bg: #ffffff;
45
45
  --ld-navbar-blur: 12px;
46
46
  --ld-sidebar-bg: transparent;
47
47
  --ld-sidebar-blur: 0px;
@@ -13,6 +13,7 @@
13
13
  @import "./ui/Footer/footer.css";
14
14
  @import "./ui/LanguageSwitcher/language-switcher.css";
15
15
  @import "./ui/PoweredBy/powered-by.css";
16
+ @import "./ui/CopyMarkdown/copy-markdown.css";
16
17
 
17
18
  /* Markdown Content */
18
19
  @import "./styles/markdown.css";
@@ -0,0 +1,82 @@
1
+ import React, { useState, useRef, useEffect } from "react";
2
+ import { Copy, ChevronDown, Check, ExternalLink } from "lucide-react";
3
+ import "./copy-markdown.css";
4
+
5
+ export interface CopyMarkdownProps {
6
+ content?: string;
7
+ config?: boolean | { text?: string; icon?: string };
8
+ }
9
+
10
+ export function CopyMarkdown({ content, config }: CopyMarkdownProps) {
11
+ const [isOpen, setIsOpen] = useState(false);
12
+ const [copied, setCopied] = useState(false);
13
+ const dropdownRef = useRef<HTMLDivElement>(null);
14
+
15
+ const isEnabled = config !== false;
16
+ const buttonText = typeof config === "object" ? config.text || "Copy Markdown" : "Copy Markdown";
17
+
18
+ useEffect(() => {
19
+ function handleClickOutside(event: MouseEvent) {
20
+ if (
21
+ dropdownRef.current &&
22
+ !dropdownRef.current.contains(event.target as Node)
23
+ ) {
24
+ setIsOpen(false);
25
+ }
26
+ }
27
+ document.addEventListener("mousedown", handleClickOutside);
28
+ return () => document.removeEventListener("mousedown", handleClickOutside);
29
+ }, []);
30
+
31
+ if (!isEnabled || !content) return null;
32
+
33
+ const handleCopy = () => {
34
+ navigator.clipboard.writeText(content);
35
+ setCopied(true);
36
+ setIsOpen(false);
37
+ setTimeout(() => setCopied(false), 2000);
38
+ };
39
+
40
+ const handleOpenRaw = () => {
41
+ const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
42
+ const url = URL.createObjectURL(blob);
43
+ window.open(url, "_blank");
44
+ setIsOpen(false);
45
+ };
46
+
47
+ return (
48
+ <div className="boltdocs-copy-markdown" ref={dropdownRef}>
49
+ <div className="copy-btn-group">
50
+ <button
51
+ className="copy-btn"
52
+ onClick={handleCopy}
53
+ aria-label="Copy Markdown"
54
+ >
55
+ {copied ? <Check size={16} /> : <Copy size={16} />}
56
+ <span className="copy-label">{copied ? "Copied!" : buttonText}</span>
57
+ </button>
58
+ <button
59
+ className={`copy-dropdown-toggle ${isOpen ? "is-active" : ""}`}
60
+ onClick={() => setIsOpen(!isOpen)}
61
+ aria-label="More options"
62
+ aria-expanded={isOpen}
63
+ >
64
+ <ChevronDown size={14} className="arrow-icon" />
65
+ </button>
66
+ </div>
67
+
68
+ {isOpen && (
69
+ <div className="copy-dropdown">
70
+ <button className="copy-option" onClick={handleCopy}>
71
+ <Copy size={14} />
72
+ Copy Markdown
73
+ </button>
74
+ <button className="copy-option" onClick={handleOpenRaw}>
75
+ <ExternalLink size={14} />
76
+ View as Markdown
77
+ </button>
78
+ </div>
79
+ )}
80
+ </div>
81
+ );
82
+ }
@@ -0,0 +1,114 @@
1
+ .boltdocs-copy-markdown {
2
+ position: relative;
3
+ display: inline-block;
4
+ z-index: 100;
5
+ }
6
+
7
+ .copy-btn-group {
8
+ display: flex;
9
+ align-items: stretch;
10
+ background-color: var(--ld-bg-mute);
11
+ border: 1px solid var(--ld-border-subtle);
12
+ border-radius: var(--ld-radius-full);
13
+ overflow: hidden;
14
+ transition: all 0.2s ease;
15
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
16
+ }
17
+
18
+ .copy-btn-group:hover {
19
+ border-color: var(--ld-color-primary-hover);
20
+ box-shadow: 0 4px 20px rgba(59, 130, 246, 0.15);
21
+ }
22
+
23
+ .copy-btn {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 8px;
27
+ padding: 8px 16px;
28
+ background: transparent;
29
+ border: none;
30
+ color: var(--ld-text-main);
31
+ font-size: 14px;
32
+ font-weight: 500;
33
+ cursor: pointer;
34
+ transition: background 0.2s ease;
35
+ }
36
+
37
+ .copy-btn:hover {
38
+ background-color: var(--ld-bg-soft);
39
+ }
40
+
41
+ .copy-label {
42
+ white-space: nowrap;
43
+ }
44
+
45
+ .copy-dropdown-toggle {
46
+ display: flex;
47
+ align-items: center;
48
+ justify-content: center;
49
+ padding: 0 10px;
50
+ background: rgba(255, 255, 255, 0.03);
51
+ border: none;
52
+ border-left: 1px solid var(--ld-border-subtle);
53
+ color: var(--ld-text-muted);
54
+ cursor: pointer;
55
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
56
+ }
57
+
58
+ .copy-dropdown-toggle:hover {
59
+ background: rgba(255, 255, 255, 0.1);
60
+ color: var(--ld-text-main);
61
+ }
62
+
63
+ .copy-dropdown-toggle .arrow-icon {
64
+ transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
65
+ }
66
+
67
+ .copy-dropdown-toggle.is-active .arrow-icon {
68
+ transform: rotate(180deg);
69
+ }
70
+
71
+ .copy-dropdown {
72
+ position: absolute;
73
+ top: calc(100% + 8px);
74
+ right: 0;
75
+ width: 200px;
76
+ background: var(--ld-bg-main);
77
+ border: 1px solid var(--ld-border-subtle);
78
+ border-radius: var(--ld-radius-lg);
79
+ padding: 4px;
80
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
81
+ overflow: hidden;
82
+ animation: boltdocs-fade-in 0.2s ease;
83
+ }
84
+
85
+ .copy-option {
86
+ display: flex;
87
+ align-items: center;
88
+ gap: 10px;
89
+ width: 100%;
90
+ padding: 10px 12px;
91
+ background: transparent;
92
+ border: none;
93
+ border-radius: 8px;
94
+ color: var(--ld-text-main);
95
+ font-size: 14px;
96
+ text-align: left;
97
+ cursor: pointer;
98
+ transition: background 0.2s ease;
99
+ }
100
+
101
+ .copy-option:hover {
102
+ background-color: var(--ld-bg-soft);
103
+ }
104
+
105
+ @keyframes boltdocs-fade-in {
106
+ from {
107
+ opacity: 0;
108
+ transform: translateY(-4px);
109
+ }
110
+ to {
111
+ opacity: 1;
112
+ transform: translateY(0);
113
+ }
114
+ }
@@ -0,0 +1 @@
1
+ export * from "./CopyMarkdown";
@@ -20,6 +20,7 @@ import { Breadcrumbs } from "../Breadcrumbs";
20
20
  import { BackgroundGradient } from "../BackgroundGradient";
21
21
  import { ProgressBar } from "../ProgressBar";
22
22
  import { ErrorBoundary } from "../ErrorBoundary";
23
+ import { CopyMarkdown } from "../CopyMarkdown";
23
24
  import "../../styles.css";
24
25
 
25
26
  export interface ThemeLayoutProps {
@@ -146,6 +147,12 @@ export function ThemeLayout({
146
147
  <Breadcrumbs routes={filteredRoutes} config={config} />
147
148
  )}
148
149
  <div className="boltdocs-page">
150
+ <div className="boltdocs-page-header">
151
+ <CopyMarkdown
152
+ content={routes[currentIndex]?._rawContent}
153
+ config={config.themeConfig?.copyMarkdown}
154
+ />
155
+ </div>
149
156
  <ErrorBoundary>
150
157
  {children}
151
158
  </ErrorBoundary>
@@ -83,6 +83,23 @@ a {
83
83
  width: 800px;
84
84
  height: 800px;
85
85
  background: var(--ld-glow-2-bg);
86
- right: -300px;
87
86
  top: -200px;
88
87
  }
88
+
89
+ .boltdocs-page {
90
+ position: relative;
91
+ }
92
+
93
+ .boltdocs-page-header {
94
+ position: absolute;
95
+ top: 0;
96
+ right: 0;
97
+ display: flex;
98
+ justify-content: flex-end;
99
+ padding: 1rem 0;
100
+ pointer-events: none;
101
+ }
102
+
103
+ .boltdocs-page-header > * {
104
+ pointer-events: auto;
105
+ }
@@ -19,11 +19,9 @@
19
19
  .boltdocs-link-preview-content {
20
20
  padding: 0.85rem 1rem;
21
21
  background-color: var(--ld-navbar-bg);
22
- backdrop-filter: blur(20px);
23
- -webkit-backdrop-filter: blur(20px);
24
22
  border: 1px solid var(--ld-border-subtle);
25
23
  border-radius: var(--ld-radius-lg);
26
- box-shadow:
24
+ box-shadow:
27
25
  0 10px 30px -10px rgba(0, 0, 0, 0.2),
28
26
  0 4px 10px -5px rgba(0, 0, 0, 0.1);
29
27
  }
@@ -48,20 +46,3 @@
48
46
  -webkit-box-orient: vertical;
49
47
  overflow: hidden;
50
48
  }
51
-
52
- /* Dark mode refinements */
53
- [data-theme="dark"] .boltdocs-link-preview-content {
54
- background-color: rgba(15, 15, 20, 0.8);
55
- border-color: rgba(255, 255, 255, 0.08);
56
- box-shadow:
57
- 0 20px 40px -15px rgba(0, 0, 0, 0.5),
58
- 0 8px 16px -8px rgba(0, 0, 0, 0.3);
59
- }
60
-
61
- [data-theme="dark"] .boltdocs-link-preview-title {
62
- color: #fff;
63
- }
64
-
65
- [data-theme="dark"] .boltdocs-link-preview-summary {
66
- color: #94a3b8;
67
- }
@@ -39,6 +39,8 @@ export interface ComponentRoute {
39
39
  groupIcon?: string;
40
40
  /** The extracted plain-text content of the page for search indexing */
41
41
  _content?: string;
42
+ /** The raw markdown content of the page */
43
+ _rawContent?: string;
42
44
  }
43
45
 
44
46
  /**
@@ -91,6 +91,12 @@ export interface BoltdocsThemeConfig {
91
91
  * Default: 'one-dark-pro'
92
92
  */
93
93
  codeTheme?: string | Record<string, string>;
94
+ /**
95
+ * Configuration for the 'Copy Markdown' button.
96
+ * Can be a boolean or an object with text and icon.
97
+ * Default: true
98
+ */
99
+ copyMarkdown?: boolean | { text?: string; icon?: string };
94
100
  }
95
101
 
96
102
  /**
@@ -176,6 +176,7 @@ export function parseDocFile(
176
176
  icon,
177
177
  tab: inferredTab,
178
178
  _content: plainText,
179
+ _rawContent: content,
179
180
  },
180
181
  relativeDir: cleanDirName,
181
182
  isGroupIndex,
@@ -37,6 +37,8 @@ export interface RouteMeta {
37
37
  tab?: string;
38
38
  /** The extracted plain-text content of the page for search indexing */
39
39
  _content?: string;
40
+ /** The raw markdown content of the page */
41
+ _rawContent?: string;
40
42
  }
41
43
 
42
44
  /**