突出显示 react-syntax-highlighter 中的行

Highlight line in react-syntax-highlighter

有没有办法在 react-syntax-highlighter 组件中突出显示代码行?您可以在下图中第 43 行看到我的意思。

您可以破解生成的 spans。首先,不说 React,让我们用普通的 jQuery 来解决问题:

打开the demo,然后运行

$(".language-javascript>span:nth-child(3)").css('background-color', 'blue')

你会看到第 3 行是蓝色的!

其次,让我们让它在 React 中工作。您可以使用一些库将 css 代码如 .language-javascript>span:nth-child(3) {background-color: blue;} (其中 3 是您要突出显示的行号)注入到 React 组件树中。

可以使用 lineProps:

<SyntaxHighlighter 
  language="json"
  style={docco}
  wrapLines={true}
  showLineNumbers={true}
  lineProps={(lineNumber) => {
    const style: any = { display: "block", width: "fit-content" };
    if (this.props.data?.highlight == lineNumber) {
      style.backgroundColor = "#FFDB81";
    }
    return { style };
  }}
  className={"syntax-highlighter"}>

  {code}

</SyntaxHighlighter>

另请参阅:Is it possible to highlight specific characters in a line using react-syntax-highlighter?

扩展 kenemo 的答案,以防您想使用 typescript 使用它:

默认情况下,@types/react-syntax-highlighter 的 Typescript 定义定义需要将 React.HTMLProps<HTMLElement> 传递给 linePropslineTagsPropsFunction,后者进一步定义为

type lineTagPropsFunction = (lineNumber: number) => React.HTMLProps<HTMLElement>;

接口 HTMLPropsAllHTMLAttributes 扩展,进一步从 HTMLAttributes 扩展,实际上将样式定义为

interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
    ...
    style?: CSSProperties | undefined;
    ...
}

所以我们现在知道我们应该在函数内部使用哪种类型来为其分配属性。有了这些知识,我们可以将类型信息添加到 kenemo 提供的代码中,如下所示:

import { Light as SyntaxHighlighter } from 'react-syntax-highlighter'
import ts from 'react-syntax-highlighter/dist/esm/languages/hljs/typescript';
import { docco as style } from 'react-syntax-highlighter/dist/esm/styles/hljs';

SyntaxHighlighter.registerLanguage('typescript', ts);

...

    <SyntaxHighlighter language="typescript" style={style}
        showLineNumbers={true}
        wrapLines={true}
        lineProps={(lineNumber: number): React.HTMLProps<HTMLElement> => {
            const style: React.CSSProperties = { display: "block", width: "fit-content" };
            if (this.props.data?.highlight === lineNumber) {
                style.backgroundColor = "#FFDB81";
            }
            return { style };
        }}
    >
        {code}
    </SyntaxHighlighter>

当然,可以推断 return 类型等等,尽管我希望它在未来尽可能具有表现力,但我总是想知道实际上 return.

请注意,仅当 showLineNumberswrapLines 都启用时,行突出显示才有效。如果其中任何一个被禁用,突出显示一行或多行将不起作用。

由于我也是将此类 属性 赋值重构为自己的函数的朋友,因此我最终得到了以下代码:

const highlightLine = (lineNumber: number, markLines: number[], color: string = "#FFDB81"):
    React.HTMLProps<HTMLElement> => {

    // only works when showLineNumbers and wrapLines are both enabled
    const style: React.CSSProperties = { display: "block", width: "fit-content" };
    if (markLines.includes(lineNumber)) {
        style.backgroundColor = color;
    }
    return { style };
}

它允许提供要突出显示的行号数组以及更改突出显示行颜色的选项。此函数现在在以下形式的 lambda 表达式中使用:

    ...
    lineProps((line: number) => highlightLine(line, this.props.highlightLines, this.props.highligtColor))
    ...