You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带行号折叠功能的React源码展示组件以适配Solidity代码

基于React17 + MUI4实现可折叠Solidity源码查看面板方案

1. 基础源码展示组件实现

不需要自行编写Solidity代码解析逻辑,直接使用成熟的第三方语法高亮库react-syntax-highlighter即可,该库内置Solidity语法支持,可直接完成代码高亮、行号展示等基础能力,和你当前的技术栈完全兼容。

实现步骤:

  • 安装兼容版本依赖:
npm install react-syntax-highlighter@15.4.5
# 若需要TS类型支持可以额外装 @types/react-syntax-highlighter
  • 基础组件示例代码:
import React from 'react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { atomOneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { solidity } from 'react-syntax-highlighter/dist/esm/languages/prism';
import { Card, CardContent, Typography } from '@material-ui/core';
// 注册Solidity语言
SyntaxHighlighter.registerLanguage('solidity', solidity);

const SolidityCodeViewer = ({ code, contractName }) => {
  return (
    <Card variant="outlined">
      <CardContent>
        <Typography variant="h6" gutterBottom>
          {contractName} 源码
        </Typography>
        <SyntaxHighlighter
          language="solidity"
          style={atomOneDark}
          showLineNumbers
          customStyle={{
            margin: 0,
            borderRadius: '4px',
            maxHeight: '800px',
          }}
        >
          {code}
        </SyntaxHighlighter>
      </CardContent>
    </Card>
  );
};

export default SolidityCodeViewer;

你可以根据项目的MUI主题调整customStyle里的样式参数,和整体设计保持统一。

2. 代码折叠功能实现

分两种实现程度,你可以根据需求选择:

方案1:行级手动折叠(轻量实现,无需额外解析)

利用MUI自带的Collapse组件 + 自定义行渲染能力,实现指定行范围的折叠,适合只需要简单折叠整段代码的场景:

import React, { useState } from 'react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { atomOneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { solidity } from 'react-syntax-highlighter/dist/esm/languages/prism';
import { Card, CardContent, Typography, IconButton } from '@material-ui/core';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
SyntaxHighlighter.registerLanguage('solidity', solidity);

const SolidityCodeViewer = ({ code, contractName }) => {
  // 示例:控制第10-25行的折叠状态,实际场景可以动态绑定多个折叠区间
  const [isBlockCollapsed, setIsBlockCollapsed] = useState(false);
  const codeLines = code.split('\n');
  const visibleLines = [
    ...codeLines.slice(0, 9),
    ...(isBlockCollapsed ? [] : codeLines.slice(9, 25)),
    ...codeLines.slice(25)
  ];

  return (
    <Card variant="outlined">
      <CardContent>
        <Typography variant="h6" gutterBottom>
          {contractName} 源码
        </Typography>
        <IconButton 
          size="small" 
          onClick={() => setIsBlockCollapsed(!isBlockCollapsed)}
          style={{ position: 'absolute', left: '20px', top: '80px' }}
        >
          {isBlockCollapsed ? <ExpandMoreIcon /> : <ExpandLessIcon />}
        </IconButton>
        <SyntaxHighlighter
          language="solidity"
          style={atomOneDark}
          showLineNumbers
          customStyle={{
            margin: 0,
            borderRadius: '4px',
            maxHeight: '800px',
            paddingLeft: '50px'
          }}
        >
          {visibleLines.join('\n')}
        </SyntaxHighlighter>
      </CardContent>
    </Card>
  );
};

export default SolidityCodeViewer;

方案2:按语法块自动折叠(和ftmscan效果一致)

如果需要实现点击函数、合约定义旁的箭头自动折叠整个语法块,只需要额外引入solidity-parser-antlr库解析Solidity源码的AST,自动提取每个合约、函数、结构体的行起止范围,动态生成折叠控制点即可,不需要自行写语法解析逻辑。

  • 安装依赖:npm install solidity-parser-antlr@0.4.11
  • 解析逻辑核心:调用parse方法传入源码,遍历AST节点拿到每个可折叠块的loc.start.line和loc.end.line属性,和上面的折叠状态绑定即可。

内容的提问来源于stack exchange,提问作者kimiro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 14:06:05