Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions demo/SiteRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default defineComponent({
<component
:is="configProvider"
class="demo"
:data-theme="themeName"
namespace="naive-ui-doc"
preflight-style-disabled
:theme-name="themeName"
Expand Down
16 changes: 16 additions & 0 deletions demo/styles/demo.css
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ body {
}
}

/*
* Keep Shiki code blocks in sync with the current site theme.
* Reference: https://shiki.style/guide/dual-themes
*/
.demo[data-theme='dark'] .shiki,
.demo[data-theme='dark'] .shiki span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
font-style: var(--shiki-dark-font-style, inherit) !important;
font-weight: var(--shiki-dark-font-weight, inherit) !important;
text-decoration: var(
--shiki-dark-text-decoration,
var(--shiki-light-text-decoration, none)
) !important;
}

@media only screen and (max-width: 639px) {
body {
overflow: visible;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
"rimraf": "^6.0.1",
"rollup": "^4.45.1",
"rollup-plugin-esbuild": "^6.2.1",
"shiki": "^3.17.0",
"superagent": "^10.2.2",
"tsx": "^4.20.3",
"typescript": "^5.9.2",
Expand Down
2 changes: 2 additions & 0 deletions src/_mixins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export { default as useHljs } from './use-hljs'
export type { Hljs } from './use-hljs'
export { default as useLocale } from './use-locale'
export { useRtl } from './use-rtl'
export { default as useShiki } from './use-shiki'
export type { Shiki } from './use-shiki'
export { default as useStyle } from './use-style'
export { createTheme, default as useTheme } from './use-theme'
export type {
Expand Down
25 changes: 25 additions & 0 deletions src/_mixins/use-shiki.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { ComputedRef } from 'vue'
import { computed, inject } from 'vue'
import { configProviderInjectionKey } from '../config-provider/src/context'

export interface Shiki {
/**
* The consumer (e.g. n-code / n-log) only cares about the rendered HTML string.
* Users may configure languages, themes or hooks when constructing the Shiki
* instance, but all those details should be hidden behind this single method.
*/
codeToHtml: (code: string) => string
}

interface UseShikiProps {
shiki?: Shiki
}

export default function useShiki(
props: UseShikiProps
): ComputedRef<Shiki | undefined> {
const NConfigProvider = inject(configProviderInjectionKey, null)
return computed(() => {
return (props.shiki as any) || NConfigProvider?.mergedShikiRef?.value
})
}
66 changes: 65 additions & 1 deletion src/code/demos/enUS/index.demo-entry.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Code

Starting from NEXT_VERSION, Shiki is supported as an alternative code highlighter.

## Prequisites

<n-alert title="Note" type="warning" style="margin-bottom: 16px;" :bordered="false">
Due to package size, Naive UI doesn't include highlight.js. If you want to use Code, make sure you have set highlightjs before using it.
Due to package size, Naive UI doesn't include highlight.js or Shiki. If you want to use Code, make sure you have set highlight.js or Shiki before using it.
</n-alert>

The following code shows how to set hljs of Code. Importing highlight.js on demand is recommonded, because it can significantly reduce bundle size of your app.
Expand Down Expand Up @@ -32,13 +34,58 @@ The following code shows how to set hljs of Code. Importing highlight.js on dema
</script>
```

The following code shows how to set Shiki for Code. For more details please check the [Shiki](https://shiki.style/) documentation.

```html
<template>
<n-config-provider :shiki="shiki">
<my-app />
</n-config-provider>
</template>

<script>
import { defineComponent } from 'vue'
import { onMounted, ref } from 'vue'
import { createHighlighter } from 'shiki'

export default defineComponent({
setup() {
const shiki = ref(null)
onMounted(async () => {
const highlighter = await createHighlighter({
themes: ['github-light', 'github-dark'],
langs: ['javascript']
})

shiki.value = {
codeToHtml(code: string) {
return highlighter.codeToHtml(code, {
lang: 'javascript',
themes: {
light: 'github-light',
dark: 'github-dark'
}
})
}
}
})

return {
shiki
}
}
})
</script>
```

## Demos

```demo
basic.vue
inline.vue
softwrap.vue
line-numbers.vue
shiki.vue
```

## API
Expand All @@ -54,3 +101,20 @@ line-numbers.vue
| show-line-numbers | `boolean` | `false` | Whether to show line numbers. Won't work if `inline` or `word-wrap` is `true`. | 2.32.0 |
| trim | `boolean` | `true` | Whether to display trimmed code. | |
| word-wrap | `boolean` | `false` | Whether to display word-wrapped code. | 2.24.0 |
| shiki | `Shiki` | `undefined` | Provide a Shiki instance if you'd like to use Shiki for highlighting. | NEXT_VERSION |

### Shiki Type

```ts
interface Shiki {
/**
* The consumer (e.g. n-code / n-log) only cares about the rendered HTML string.
* Users may configure languages, themes or hooks when constructing the Shiki
* instance, but all those details should be hidden behind this single method.
*/
codeToHtml: (
code: string,
options: { lang: string, theme?: string | object }
) => string
}
```
39 changes: 39 additions & 0 deletions src/code/demos/enUS/shiki.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<markdown>
# Use Shiki

Highlight code with `Shiki`.
</markdown>

<script lang="ts" setup>
import { createHighlighter } from 'shiki'
import { onMounted, ref } from 'vue'

const shiki = ref()
const code = `function sayHello() {
console.log('Hello Shiki')
}`

onMounted(async () => {
const highlighter = await createHighlighter({
themes: ['github-light', 'github-dark'],
langs: ['javascript']
})

shiki.value = {
codeToHtml(code: string) {
return highlighter.codeToHtml(code, {
lang: 'javascript',
themes: {
light: 'github-light',
dark: 'github-dark'
}
})
}
}
})
</script>

<template>
<n-code :shiki="shiki" :code="code" show-line-numbers />
</template>
```
64 changes: 63 additions & 1 deletion src/code/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# 代码 Code

自 NEXT_VERSION 起, 支持 Shiki 作为代码高亮的选项之一

## 预备条件

<n-alert title="注意" type="warning" style="margin-bottom: 16px;" :bordered="false">
由于包体积原因,Naive UI 不内置 highlight.js。如果你需要使用代码组件,请确保你在使用之前已经设定了 highlight.js。
由于包体积原因,Naive UI 不内置 highlight.js 或 Shiki。如果你需要使用代码组件,请确保你在使用之前已经设定了 highlight.js 或 Shiki
</n-alert>

下面的代码展示了如何为 Code 设定 hljs。比较推荐的方式是按需引入,因为它可以极大地减小打包尺寸。
Expand Down Expand Up @@ -32,6 +34,48 @@
</script>
```

下面的代码展示了如何为 Code 设定 shiki。更多内容请参考 [Shiki](https://shiki.style/) 文档。

```html
<template>
<n-config-provider :shiki="shiki">
<my-app />
</n-config-provider>
</template>

<script>
import { defineComponent } from 'vue'
import { onMounted, ref } from 'vue'
import { createHighlighter } from 'shiki'
export default defineComponent({
setup() {
const shiki = ref(null)
onMounted(async () => {
const highlighter = await createHighlighter({
themes: ['github-light', 'github-dark'],
langs: ['javascript']
})

shiki.value = {
codeToHtml(code: string) {
return highlighter.codeToHtml(code, {
lang: 'javascript',
themes: {
light: 'github-light',
dark: 'github-dark'
}
})
}
}
})
return {
shiki
}
}
})
</script>
```

## 演示

```demo
Expand All @@ -40,6 +84,7 @@ inline.vue
softwrap.vue
loop-debug.vue
line-numbers.vue
shiki.vue
```

## API
Expand All @@ -55,3 +100,20 @@ line-numbers.vue
| show-line-numbers | `boolean` | `false` | 是否显示行号,在 `inline` 或 `word-wrap` 的情况下不生效 | 2.32.0 |
| trim | `boolean` | `true` | 是否显示 trim 后的代码 | |
| word-wrap | `boolean` | `false` | 代码过长时是否自动换行 | 2.24.0 |
| shiki | `Shiki` | `undefined` | 如果你想使用 shiki 进行代码高亮,可以通过这个属性传给组件 | NEXT_VERSION |

### Shiki 类型

```ts
interface Shiki {
/**
* The consumer (e.g. n-code / n-log) only cares about the rendered HTML string.
* Users may configure languages, themes or hooks when constructing the Shiki
* instance, but all those details should be hidden behind this single method.
*/
codeToHtml: (
code: string,
options: { lang: string, theme?: string | object }
) => string
}
```
38 changes: 38 additions & 0 deletions src/code/demos/zhCN/shiki.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<markdown>
# 使用 Shiki

使用 `Shiki` 来高亮代码。
</markdown>

<script lang="ts" setup>
import { createHighlighter } from 'shiki'
import { onMounted, ref } from 'vue'

const shiki = ref()
const code = `function sayHello() {
console.log('Hello Shiki')
}`

onMounted(async () => {
const highlighter = await createHighlighter({
themes: ['github-light', 'github-dark'],
langs: ['javascript']
})

shiki.value = {
codeToHtml(code: string) {
return highlighter.codeToHtml(code, {
lang: 'javascript',
themes: {
light: 'github-light',
dark: 'github-dark'
}
})
}
}
})
</script>

<template>
<n-code :shiki="shiki" :code="code" show-line-numbers />
</template>
Loading
Loading