@barodoc/theme-docs 7.1.0 → 7.1.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.
- package/package.json +1 -1
- package/src/components/mdx/CodeGroup.tsx +8 -107
package/package.json
CHANGED
|
@@ -1,117 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
2
|
|
|
3
3
|
interface CodeGroupProps {
|
|
4
|
-
children:
|
|
4
|
+
children: ReactNode;
|
|
5
5
|
titles?: string[];
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
function isCodeBlockLike(el: React.ReactElement): boolean {
|
|
9
|
-
if (el.type === "pre") return true;
|
|
10
|
-
const className =
|
|
11
|
-
typeof el.props?.className === "string" ? el.props.className : "";
|
|
12
|
-
if (
|
|
13
|
-
className.includes("language-") ||
|
|
14
|
-
className.includes("astro-code") ||
|
|
15
|
-
className.includes("code-block")
|
|
16
|
-
)
|
|
17
|
-
return true;
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function collectCodeBlocks(node: React.ReactNode): React.ReactElement[] {
|
|
22
|
-
const result: React.ReactElement[] = [];
|
|
23
|
-
React.Children.forEach(node, (child) => {
|
|
24
|
-
if (!React.isValidElement(child)) return;
|
|
25
|
-
if (child.type === React.Fragment && child.props?.children != null) {
|
|
26
|
-
result.push(...collectCodeBlocks(child.props.children));
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (child.type === "pre" || isCodeBlockLike(child)) {
|
|
30
|
-
result.push(child);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if (child.props?.children != null) {
|
|
34
|
-
result.push(...collectCodeBlocks(child.props.children));
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
return result;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
8
|
export function CodeGroup({ children, titles = [] }: CodeGroupProps) {
|
|
41
|
-
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
42
|
-
|
|
43
|
-
const codeBlocks = React.useMemo(() => {
|
|
44
|
-
let blocks = collectCodeBlocks(children);
|
|
45
|
-
if (blocks.length > 0) return blocks;
|
|
46
|
-
const direct = React.Children.toArray(children).filter(
|
|
47
|
-
(c): c is React.ReactElement => React.isValidElement(c) && c.type != null
|
|
48
|
-
);
|
|
49
|
-
if (direct.length > 1) return direct;
|
|
50
|
-
if (
|
|
51
|
-
direct.length === 1 &&
|
|
52
|
-
direct[0].props?.children != null
|
|
53
|
-
) {
|
|
54
|
-
const inner = React.Children.toArray(direct[0].props.children).filter(
|
|
55
|
-
(c): c is React.ReactElement =>
|
|
56
|
-
React.isValidElement(c) && c.type != null
|
|
57
|
-
);
|
|
58
|
-
if (inner.length > 0) return inner;
|
|
59
|
-
}
|
|
60
|
-
return direct;
|
|
61
|
-
}, [children]);
|
|
62
|
-
|
|
63
|
-
const tabTitles =
|
|
64
|
-
titles.length >= codeBlocks.length
|
|
65
|
-
? titles.slice(0, codeBlocks.length)
|
|
66
|
-
: [
|
|
67
|
-
...titles,
|
|
68
|
-
...codeBlocks
|
|
69
|
-
.slice(titles.length)
|
|
70
|
-
.map((_, i) => `Tab ${titles.length + i + 1}`),
|
|
71
|
-
];
|
|
72
|
-
|
|
73
|
-
if (codeBlocks.length === 0) {
|
|
74
|
-
return (
|
|
75
|
-
<div className="code-group not-prose my-4 rounded-lg border border-[var(--bd-border)] overflow-hidden p-4 text-[var(--bd-text-muted)] text-sm">
|
|
76
|
-
No code blocks found inside CodeGroup.
|
|
77
|
-
</div>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
9
|
return (
|
|
82
|
-
<div
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
<button
|
|
89
|
-
key={index}
|
|
90
|
-
type="button"
|
|
91
|
-
onClick={() => setActiveIndex(index)}
|
|
92
|
-
className={`shrink-0 px-4 py-2 text-sm font-medium transition-colors whitespace-nowrap ${
|
|
93
|
-
isActive
|
|
94
|
-
? "bg-[var(--bd-bg-subtle)] text-[var(--bd-text)] border-b-2 border-primary-500 -mb-px"
|
|
95
|
-
: "text-[var(--bd-text-muted)] hover:text-[var(--bd-text)]"
|
|
96
|
-
}`}
|
|
97
|
-
>
|
|
98
|
-
{title}
|
|
99
|
-
</button>
|
|
100
|
-
);
|
|
101
|
-
})}
|
|
102
|
-
</div>
|
|
103
|
-
|
|
104
|
-
{/* Content */}
|
|
105
|
-
<div className="bg-[var(--bd-bg-subtle)]">
|
|
106
|
-
{codeBlocks.map((block, index) => (
|
|
107
|
-
<div
|
|
108
|
-
key={index}
|
|
109
|
-
style={{ display: activeIndex === index ? "block" : "none" }}
|
|
110
|
-
>
|
|
111
|
-
{block}
|
|
112
|
-
</div>
|
|
113
|
-
))}
|
|
114
|
-
</div>
|
|
10
|
+
<div
|
|
11
|
+
className="code-group not-prose my-4 rounded-lg border border-[var(--bd-border)] overflow-hidden"
|
|
12
|
+
data-titles={JSON.stringify(titles)}
|
|
13
|
+
>
|
|
14
|
+
<div className="code-group-tabs flex flex-wrap gap-0 border-b border-[var(--bd-border)] bg-[var(--bd-bg-muted)]" />
|
|
15
|
+
<div className="code-group-content bg-[var(--bd-bg-subtle)]">{children}</div>
|
|
115
16
|
</div>
|
|
116
17
|
);
|
|
117
18
|
}
|