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,84 +1,84 @@
1
- import React, { useRef, useState, useEffect } from "react";
2
-
3
- interface VideoProps {
4
- /** Video source URL */
5
- src?: string;
6
- /** Poster/thumbnail image URL */
7
- poster?: string;
8
- /** Alt text for accessibility */
9
- alt?: string;
10
- /** Show native video controls (default: true) */
11
- controls?: boolean;
12
- /** Preload strategy (default: 'none') */
13
- preload?: string;
14
- /** Children (e.g. <source> elements) */
15
- children?: React.ReactNode;
16
- /** Allow any additional HTML video attributes */
17
- [key: string]: any;
18
- }
19
-
20
- /**
21
- * Optimized video component with lazy loading via IntersectionObserver.
22
- * The `<video>` element is only rendered once it enters the viewport,
23
- * preventing unnecessary network downloads on initial page load.
24
- *
25
- * Usage in MDX:
26
- * ```mdx
27
- * <video src="/demo.mp4" poster="/demo-thumb.jpg" />
28
- * ```
29
- */
30
- export function Video({
31
- src,
32
- poster,
33
- alt,
34
- children,
35
- controls,
36
- preload = "metadata",
37
- ...rest
38
- }: VideoProps) {
39
- const containerRef = useRef<HTMLDivElement>(null);
40
- const [isVisible, setIsVisible] = useState(false);
41
-
42
- useEffect(() => {
43
- const el = containerRef.current;
44
- if (!el) return;
45
-
46
- const observer = new IntersectionObserver(
47
- ([entry]) => {
48
- if (entry.isIntersecting) {
49
- setIsVisible(true);
50
- observer.disconnect();
51
- }
52
- },
53
- { rootMargin: "200px" },
54
- );
55
-
56
- observer.observe(el);
57
- return () => observer.disconnect();
58
- }, []);
59
-
60
- return (
61
- <div ref={containerRef} className="boltdocs-video-wrapper">
62
- {isVisible ? (
63
- <video
64
- className="boltdocs-video"
65
- src={src}
66
- poster={poster}
67
- controls={true}
68
- preload={preload}
69
- playsInline
70
- {...rest}
71
- >
72
- {children}
73
- Your browser does not support the video tag.
74
- </video>
75
- ) : (
76
- <div
77
- className="boltdocs-video-placeholder"
78
- role="img"
79
- aria-label={alt || "Video"}
80
- />
81
- )}
82
- </div>
83
- );
84
- }
1
+ import React, { useRef, useState, useEffect } from "react";
2
+
3
+ interface VideoProps {
4
+ /** Video source URL */
5
+ src?: string;
6
+ /** Poster/thumbnail image URL */
7
+ poster?: string;
8
+ /** Alt text for accessibility */
9
+ alt?: string;
10
+ /** Show native video controls (default: true) */
11
+ controls?: boolean;
12
+ /** Preload strategy (default: 'none') */
13
+ preload?: string;
14
+ /** Children (e.g. <source> elements) */
15
+ children?: React.ReactNode;
16
+ /** Allow any additional HTML video attributes */
17
+ [key: string]: any;
18
+ }
19
+
20
+ /**
21
+ * Optimized video component with lazy loading via IntersectionObserver.
22
+ * The `<video>` element is only rendered once it enters the viewport,
23
+ * preventing unnecessary network downloads on initial page load.
24
+ *
25
+ * Usage in MDX:
26
+ * ```mdx
27
+ * <video src="/demo.mp4" poster="/demo-thumb.jpg" />
28
+ * ```
29
+ */
30
+ export function Video({
31
+ src,
32
+ poster,
33
+ alt,
34
+ children,
35
+ controls,
36
+ preload = "metadata",
37
+ ...rest
38
+ }: VideoProps) {
39
+ const containerRef = useRef<HTMLDivElement>(null);
40
+ const [isVisible, setIsVisible] = useState(false);
41
+
42
+ useEffect(() => {
43
+ const el = containerRef.current;
44
+ if (!el) return;
45
+
46
+ const observer = new IntersectionObserver(
47
+ ([entry]) => {
48
+ if (entry.isIntersecting) {
49
+ setIsVisible(true);
50
+ observer.disconnect();
51
+ }
52
+ },
53
+ { rootMargin: "200px" },
54
+ );
55
+
56
+ observer.observe(el);
57
+ return () => observer.disconnect();
58
+ }, []);
59
+
60
+ return (
61
+ <div ref={containerRef} className="boltdocs-video-wrapper">
62
+ {isVisible ? (
63
+ <video
64
+ className="boltdocs-video"
65
+ src={src}
66
+ poster={poster}
67
+ controls={true}
68
+ preload={preload}
69
+ playsInline
70
+ {...rest}
71
+ >
72
+ {children}
73
+ Your browser does not support the video tag.
74
+ </video>
75
+ ) : (
76
+ <div
77
+ className="boltdocs-video-placeholder"
78
+ role="img"
79
+ aria-label={alt || "Video"}
80
+ />
81
+ )}
82
+ </div>
83
+ );
84
+ }
@@ -1 +1 @@
1
- export { Video } from "./Video";
1
+ export { Video } from "./Video";
@@ -1,41 +1,41 @@
1
- /* ─── Video ──────────────────────────────────────────────── */
2
- .boltdocs-video-wrapper {
3
- margin: 1.5rem 0;
4
- max-width: 100%;
5
- width: 100%;
6
- box-sizing: border-box;
7
- border-radius: var(--ld-radius-md);
8
- overflow: hidden;
9
- border: 1px solid var(--ld-border-subtle);
10
- background-color: var(--ld-surface);
11
- }
12
-
13
- .boltdocs-video {
14
- display: block;
15
- width: 100%;
16
- max-width: 100%;
17
- height: auto;
18
- border-radius: 0;
19
- animation: ld-video-fade-in 0.4s ease-out;
20
- }
21
-
22
- .boltdocs-video-placeholder {
23
- width: 100%;
24
- aspect-ratio: 16 / 9;
25
- background-color: var(--ld-surface);
26
- }
27
-
28
- /* Ensure video doesn't overflow boltdocs-page container */
29
- .boltdocs-page video {
30
- max-width: 100%;
31
- height: auto;
32
- }
33
-
34
- @keyframes ld-video-fade-in {
35
- from {
36
- opacity: 0;
37
- }
38
- to {
39
- opacity: 1;
40
- }
41
- }
1
+ /* ─── Video ──────────────────────────────────────────────── */
2
+ .boltdocs-video-wrapper {
3
+ margin: 1.5rem 0;
4
+ max-width: 100%;
5
+ width: 100%;
6
+ box-sizing: border-box;
7
+ border-radius: var(--ld-radius-md);
8
+ overflow: hidden;
9
+ border: 1px solid var(--ld-border-subtle);
10
+ background-color: var(--ld-surface);
11
+ }
12
+
13
+ .boltdocs-video {
14
+ display: block;
15
+ width: 100%;
16
+ max-width: 100%;
17
+ height: auto;
18
+ border-radius: 0;
19
+ animation: ld-video-fade-in 0.4s ease-out;
20
+ }
21
+
22
+ .boltdocs-video-placeholder {
23
+ width: 100%;
24
+ aspect-ratio: 16 / 9;
25
+ background-color: var(--ld-surface);
26
+ }
27
+
28
+ /* Ensure video doesn't overflow boltdocs-page container */
29
+ .boltdocs-page video {
30
+ max-width: 100%;
31
+ height: auto;
32
+ }
33
+
34
+ @keyframes ld-video-fade-in {
35
+ from {
36
+ opacity: 0;
37
+ }
38
+ to {
39
+ opacity: 1;
40
+ }
41
+ }
@@ -1,80 +1,80 @@
1
- import React from "react";
2
- import {
3
- Info,
4
- Lightbulb,
5
- AlertTriangle,
6
- ShieldAlert,
7
- Bookmark,
8
- } from "lucide-react";
9
-
10
- const ICON_MAP: Record<string, React.ReactNode> = {
11
- note: <Bookmark size={18} />,
12
- tip: <Lightbulb size={18} />,
13
- info: <Info size={18} />,
14
- warning: <AlertTriangle size={18} />,
15
- danger: <ShieldAlert size={18} />,
16
- };
17
-
18
- const LABEL_MAP: Record<string, string> = {
19
- note: "Note",
20
- tip: "Tip",
21
- info: "Info",
22
- warning: "Warning",
23
- danger: "Danger",
24
- };
25
-
26
- export interface AdmonitionProps extends React.HTMLAttributes<HTMLDivElement> {
27
- /** Admonition type — controls color and icon */
28
- type?: "note" | "tip" | "info" | "warning" | "danger";
29
- /** Override the default title */
30
- title?: string;
31
- children: React.ReactNode;
32
- }
33
-
34
- /**
35
- * Callout / admonition box for notes, warnings, etc.
36
- *
37
- * ```mdx
38
- * <Admonition type="warning" title="Breaking Change">
39
- * This API has changed in v2.
40
- * </Admonition>
41
- * ```
42
- */
43
- export function Admonition({
44
- type = "note",
45
- title,
46
- children,
47
- className = "",
48
- ...rest
49
- }: AdmonitionProps) {
50
- return (
51
- <div
52
- className={`ld-admonition ld-admonition--${type} ${className}`.trim()}
53
- role={type === "warning" || type === "danger" ? "alert" : "note"}
54
- {...rest}
55
- >
56
- <div className="ld-admonition__header">
57
- <span className="ld-admonition__icon">{ICON_MAP[type]}</span>
58
- <span className="ld-admonition__title">{title || LABEL_MAP[type]}</span>
59
- </div>
60
- <div className="ld-admonition__body">{children}</div>
61
- </div>
62
- );
63
- }
64
-
65
- /* ─── Convenience aliases ─────────────────────────────────── */
66
- export const Note = (props: Omit<AdmonitionProps, "type">) => (
67
- <Admonition type="note" {...props} />
68
- );
69
- export const Tip = (props: Omit<AdmonitionProps, "type">) => (
70
- <Admonition type="tip" {...props} />
71
- );
72
- export const Warning = (props: Omit<AdmonitionProps, "type">) => (
73
- <Admonition type="warning" {...props} />
74
- );
75
- export const Danger = (props: Omit<AdmonitionProps, "type">) => (
76
- <Admonition type="danger" {...props} />
77
- );
78
- export const InfoBox = (props: Omit<AdmonitionProps, "type">) => (
79
- <Admonition type="info" {...props} />
80
- );
1
+ import React from "react";
2
+ import {
3
+ Info,
4
+ Lightbulb,
5
+ AlertTriangle,
6
+ ShieldAlert,
7
+ Bookmark,
8
+ } from "lucide-react";
9
+
10
+ const ICON_MAP: Record<string, React.ReactNode> = {
11
+ note: <Bookmark size={18} />,
12
+ tip: <Lightbulb size={18} />,
13
+ info: <Info size={18} />,
14
+ warning: <AlertTriangle size={18} />,
15
+ danger: <ShieldAlert size={18} />,
16
+ };
17
+
18
+ const LABEL_MAP: Record<string, string> = {
19
+ note: "Note",
20
+ tip: "Tip",
21
+ info: "Info",
22
+ warning: "Warning",
23
+ danger: "Danger",
24
+ };
25
+
26
+ export interface AdmonitionProps extends React.HTMLAttributes<HTMLDivElement> {
27
+ /** Admonition type — controls color and icon */
28
+ type?: "note" | "tip" | "info" | "warning" | "danger";
29
+ /** Override the default title */
30
+ title?: string;
31
+ children: React.ReactNode;
32
+ }
33
+
34
+ /**
35
+ * Callout / admonition box for notes, warnings, etc.
36
+ *
37
+ * ```mdx
38
+ * <Admonition type="warning" title="Breaking Change">
39
+ * This API has changed in v2.
40
+ * </Admonition>
41
+ * ```
42
+ */
43
+ export function Admonition({
44
+ type = "note",
45
+ title,
46
+ children,
47
+ className = "",
48
+ ...rest
49
+ }: AdmonitionProps) {
50
+ return (
51
+ <div
52
+ className={`ld-admonition ld-admonition--${type} ${className}`.trim()}
53
+ role={type === "warning" || type === "danger" ? "alert" : "note"}
54
+ {...rest}
55
+ >
56
+ <div className="ld-admonition__header">
57
+ <span className="ld-admonition__icon">{ICON_MAP[type]}</span>
58
+ <span className="ld-admonition__title">{title || LABEL_MAP[type]}</span>
59
+ </div>
60
+ <div className="ld-admonition__body">{children}</div>
61
+ </div>
62
+ );
63
+ }
64
+
65
+ /* ─── Convenience aliases ─────────────────────────────────── */
66
+ export const Note = (props: Omit<AdmonitionProps, "type">) => (
67
+ <Admonition type="note" {...props} />
68
+ );
69
+ export const Tip = (props: Omit<AdmonitionProps, "type">) => (
70
+ <Admonition type="tip" {...props} />
71
+ );
72
+ export const Warning = (props: Omit<AdmonitionProps, "type">) => (
73
+ <Admonition type="warning" {...props} />
74
+ );
75
+ export const Danger = (props: Omit<AdmonitionProps, "type">) => (
76
+ <Admonition type="danger" {...props} />
77
+ );
78
+ export const InfoBox = (props: Omit<AdmonitionProps, "type">) => (
79
+ <Admonition type="info" {...props} />
80
+ );
@@ -1,31 +1,31 @@
1
- import React from "react";
2
-
3
- export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
4
- /** Color variant */
5
- variant?: "default" | "primary" | "success" | "warning" | "danger" | "info";
6
- children: React.ReactNode;
7
- }
8
-
9
- /**
10
- * Inline badge / pill for labels, statuses, or tags.
11
- *
12
- * ```mdx
13
- * <Badge variant="success">Stable</Badge>
14
- * <Badge variant="warning">Beta</Badge>
15
- * ```
16
- */
17
- export function Badge({
18
- variant = "default",
19
- children,
20
- className = "",
21
- ...rest
22
- }: BadgeProps) {
23
- return (
24
- <span
25
- className={`ld-badge ld-badge--${variant} ${className}`.trim()}
26
- {...rest}
27
- >
28
- {children}
29
- </span>
30
- );
31
- }
1
+ import React from "react";
2
+
3
+ export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
4
+ /** Color variant */
5
+ variant?: "default" | "primary" | "success" | "warning" | "danger" | "info";
6
+ children: React.ReactNode;
7
+ }
8
+
9
+ /**
10
+ * Inline badge / pill for labels, statuses, or tags.
11
+ *
12
+ * ```mdx
13
+ * <Badge variant="success">Stable</Badge>
14
+ * <Badge variant="warning">Beta</Badge>
15
+ * ```
16
+ */
17
+ export function Badge({
18
+ variant = "default",
19
+ children,
20
+ className = "",
21
+ ...rest
22
+ }: BadgeProps) {
23
+ return (
24
+ <span
25
+ className={`ld-badge ld-badge--${variant} ${className}`.trim()}
26
+ {...rest}
27
+ >
28
+ {children}
29
+ </span>
30
+ );
31
+ }
@@ -1,50 +1,50 @@
1
- import React from "react";
2
-
3
- export type ButtonProps = React.AnchorHTMLAttributes<HTMLAnchorElement> &
4
- React.ButtonHTMLAttributes<HTMLButtonElement> & {
5
- /** Visual variant */
6
- variant?: "primary" | "secondary" | "outline" | "ghost";
7
- /** Size */
8
- size?: "sm" | "md" | "lg";
9
- /** If provided, renders as a link */
10
- href?: string;
11
- children: React.ReactNode;
12
- };
13
-
14
- /**
15
- * A versatile button/link component for use in MDX pages and the home page.
16
- *
17
- * ```mdx
18
- * <Button variant="primary" href="/docs/getting-started">Get Started →</Button>
19
- * <Button variant="secondary" href="https://github.com">GitHub</Button>
20
- * ```
21
- */
22
- export function Button({
23
- variant = "primary",
24
- size = "md",
25
- href,
26
- children,
27
- className = "",
28
- ...rest
29
- }: ButtonProps) {
30
- const cls = `ld-btn ld-btn--${variant} ld-btn--${size} ${className}`.trim();
31
-
32
- if (href) {
33
- return (
34
- <a
35
- href={href}
36
- style={{ textDecoration: "none" }}
37
- className={cls}
38
- {...(rest as any)}
39
- >
40
- {children}
41
- </a>
42
- );
43
- }
44
-
45
- return (
46
- <button className={cls} {...(rest as any)}>
47
- {children}
48
- </button>
49
- );
50
- }
1
+ import React from "react";
2
+
3
+ export type ButtonProps = React.AnchorHTMLAttributes<HTMLAnchorElement> &
4
+ React.ButtonHTMLAttributes<HTMLButtonElement> & {
5
+ /** Visual variant */
6
+ variant?: "primary" | "secondary" | "outline" | "ghost";
7
+ /** Size */
8
+ size?: "sm" | "md" | "lg";
9
+ /** If provided, renders as a link */
10
+ href?: string;
11
+ children: React.ReactNode;
12
+ };
13
+
14
+ /**
15
+ * A versatile button/link component for use in MDX pages and the home page.
16
+ *
17
+ * ```mdx
18
+ * <Button variant="primary" href="/docs/getting-started">Get Started →</Button>
19
+ * <Button variant="secondary" href="https://github.com">GitHub</Button>
20
+ * ```
21
+ */
22
+ export function Button({
23
+ variant = "primary",
24
+ size = "md",
25
+ href,
26
+ children,
27
+ className = "",
28
+ ...rest
29
+ }: ButtonProps) {
30
+ const cls = `ld-btn ld-btn--${variant} ld-btn--${size} ${className}`.trim();
31
+
32
+ if (href) {
33
+ return (
34
+ <a
35
+ href={href}
36
+ style={{ textDecoration: "none" }}
37
+ className={cls}
38
+ {...(rest as any)}
39
+ >
40
+ {children}
41
+ </a>
42
+ );
43
+ }
44
+
45
+ return (
46
+ <button className={cls} {...(rest as any)}>
47
+ {children}
48
+ </button>
49
+ );
50
+ }