语言切换器

当您需要在代码块中切换语言时,添加一个语言选择器。

content.mdx
<CodeSwitcher>
```java !!
public class Main {
public static int factorial(int n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
}
```
```cpp !!
int factorial(int n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
```
```scala !!
object Main {
def factorial(n: Int): Int = {
if (n == 0) {
return 1
} else {
return n * factorial(n - 1)
}
}
}
```
```py !!
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
```
```matlab !!
function result = factorial(n)
if n == 0
result = 1;
else
result = n * factorial(n - 1);
end
end
```
```js !!
function factorial(n) {
if (n === 0) {
return 1
} else {
return n * factorial(n - 1)
}
}
```
```kotlin !!
fun factorial(n: Int): Int {
return if (n == 0) {
1
} else {
n * factorial(n - 1)
}
}
```
```go !!
func factorial(n int) int {
if n == 0 {
return 1
} else {
return n * factorial(n - 1)
}
}
```
```swift !!
func factorial(n: Int) -> Int {
if n == 0 {
return 1
} else {
return n * factorial(n: n - 1)
}
}
```
```rust !!
fn factorial(n: i32) -> i32 {
if n == 0 {
return 1;
} else {
return n * factorial(n - 1);
}
}
```
```fsharp !!
let rec factorial n =
if n = 0 then
1
else
n * factorial (n - 1)
```
</CodeSwitcher>
public class Main {
public static int factorial(int n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
}

从下拉菜单中选择不同的语言来查看代码块的变化。

Implementation

我们使用来自 shadcn/uiSelect 组件:

npx shadcn@latest add select

由于我们的组件将具有状态,我们需要一个客户端组件:

code.tsx
"use client"
import { HighlightedCode, Pre, highlight } from "codehike/code"
import { useState } from "react"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
export function Code({ highlighted }: { highlighted: HighlightedCode[] }) {
const [selectedLang, setSelectedLang] = useState(highlighted[0].lang)
const selectedCode = highlighted.find((code) => code.lang === selectedLang)!
return (
<div className="">
<Pre code={selectedCode} className="" />
<div className="">
<Select value={selectedLang} onValueChange={setSelectedLang}>
<SelectTrigger className="">
<SelectValue />
</SelectTrigger>
<SelectContent position="item-aligned">
{highlighted.map(({ lang }, index) => (
<SelectItem key={index} value={lang}>
{lang}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
)
}

如果您使用 React 服务器组件,我们还需要一个组件来高亮代码块:

language-switcher.tsx
import { RawCode, highlight } from "codehike/code"
import { Code } from "./code"
export async function CodeSwitcher(props: { code: RawCode[] }) {
const highlighted = await Promise.all(
props.code.map((codeblock) => highlight(codeblock, "github-dark")),
)
return <Code highlighted={highlighted} />
}

如果您想要为过渡添加动画效果,可以使用标记过渡处理器

如果您需要在多个代码块之间持久化和/或同步所选语言,可以将 useState 替换为 useLocalStorage 钩子,例如使用 @uidotdev/usehooks 或您自己的实现。