Plus 组件

代码高亮

根据语法高亮页面中的代码块

使用场景

Semi 代码高亮组件基于 Shiki 封装,使用与 VS Code 相同的 TextMate 语法。要高亮的语言由使用方注册,产物中只包含注册过的语法;未注册的语言按纯文本显示。高亮配色默认使用 Shiki 内置的 github-light 与 github-dark 主题,并随 Semi 的亮色、暗色模式自动切换,也可以换成其他主题。
需要展示代码片段时推荐使用 CodeHighlight 组件

代码演示

如何引入

import { CodeHighlight } from '@fibrous/semi-ui-solid';

注册语言与主题

语法与主题文件来自 shiki 包,使用前先在项目中安装 shiki。在应用入口调用一次 CodeHighlight.register,注册之后所有 CodeHighlight 都能使用这些语言。

MarkdownRender、Chat、AIChatDialogue、Sidebar 中的代码块同样生效。

语言以 () => import(...) 的形式传入时,语法文件在首次高亮任一代码块时加载,且会加载全部已注册的语言,而不只是该代码块用到的那一种。可用的语言及其名称、别名见 Shiki 语言列表,主题见 Shiki 主题列表。注册晚于代码块挂载时,已挂载的代码块会重新高亮

import { CodeHighlight } from '@fibrous/semi-ui-solid';

CodeHighlight.register({
    languages: [() => import('shiki/langs/javascript.mjs'), () => import('shiki/langs/css.mjs')],
    // 可选,替换默认的 github-light 与 github-dark
    themes: { light: () => import('shiki/themes/min-light.mjs'), dark: () => import('shiki/themes/nord.mjs') },
});

基本用法

向 code props 传入代码纯文本,并在 language 传入已注册语言的名称或别名


import * as React from 'react'
const Test = ()=>{
    const handleClick = ()=>{
        alert("Click")
    }
    return <div onClick={handleClick}>test</div>
}
代码
import { CodeHighlight } from '@fibrous/semi-ui-solid';

export default function CodeHighlightDemo() {
    return (
        <CodeHighlight
            language="javascript"
            code={`
import * as React from 'react'
const Test = ()=>{
    const handleClick = ()=>{
        alert("Click")
    }
    return <div onClick={handleClick}>test</div>
}`}
        />
    );
}

CSS

.grid {
    .semi-row,
    .semi-row-flex {
        text-align: center;
        .semi-col {
            min-height: 30px;
            line-height: 30px;
            background: var(--semi-color-primary-light-default);
            outline: 1px solid var(--semi-color-primary-light-active);
        }
    }
}
代码
import { CodeHighlight } from '@fibrous/semi-ui-solid';

export default function CodeHighlightDemo() {
    return (
        <CodeHighlight
            language="css"
            code={`.grid {
    .semi-row,
    .semi-row-flex {
        text-align: center;
        .semi-col {
            min-height: 30px;
            line-height: 30px;
            background: var(--semi-color-primary-light-default);
            outline: 1px solid var(--semi-color-primary-light-active);
        }
    }
}
`}
        />
    );
}

单个代码块使用的语言

只有个别代码块用到的语言,可以通过 languages 传给该代码块,不必全局注册;themes 同样可以只替换该代码块的主题。这两个值请写在组件外部,避免每次渲染都换成新的数组或对象而重新高亮。例如高亮用于编写 GTK 程序前端 UI 的 Vala 语言

public class ExampleApp : Gtk.Application {
    public ExampleApp () {
        Object (application_id: "com.example.App");
    }

    public override void activate () {
        var win = new Gtk.ApplicationWindow (this);

        var btn = new Gtk.Button.with_label ("Hello World");
        btn.clicked.connect (win.close);

        win.child = btn;
        win.present ();
    }

    public static int main (string[] args) {
        var app = new ExampleApp ();
        return app.run (args);
    }
}
代码
import { CodeHighlight } from '@fibrous/semi-ui-solid';

const languages = [() => import('shiki/langs/vala.mjs')];

export default function CodeHighlightDemo() {
    return (
        <CodeHighlight
            languages={languages}
            language="vala"
            code={`public class ExampleApp : Gtk.Application {
    public ExampleApp () {
        Object (application_id: "com.example.App");
    }

    public override void activate () {
        var win = new Gtk.ApplicationWindow (this);

        var btn = new Gtk.Button.with_label ("Hello World");
        btn.clicked.connect (win.close);

        win.child = btn;
        win.present ();
    }

    public static int main (string[] args) {
        var app = new ExampleApp ();
        return app.run (args);
    }
}
`}
        />
    );
}

API

Props

属性说明类型默认值
code代码纯文本,未传时按空字符串处理。code 变化后先显示新文本,高亮完成后再替换。string-
language语言类型,需已注册或经 languages 传入。string-
languages该代码块额外使用的 Shiki 语法,加载后其他代码块也可使用。替换为新的数组引用会重新高亮。LanguageInput[]-
lineNumber是否开启行数显示。booleantrue
themes替换该代码块亮色、暗色模式下的 Shiki 主题。CodeHighlightThemes-

class、style、ref 与原生属性(如 id、aria-label)落在根元素(div)上,高亮前后根元素保持不变。

静态方法

方法说明类型
CodeHighlight.register注册所有 CodeHighlight 可用的语言,并替换默认主题;可多次调用,语言累加、主题覆盖(options: { languages?: LanguageInput[]; themes?: { light?: ThemeInput; dark?: ThemeInput } }) => void

Accessibility

  • 根元素传入 aria-label 或 aria-labelledby 且未传 role 时,自动带 role="group"(通用元素不能被命名);传入的 role 优先

设计变量