Skip to content

Commit

Permalink
feat: support to show line number for SourceCode (#1654)
Browse files Browse the repository at this point in the history
* feat: add line mum for source code content(#1639)

* feat: line numbers support highlighting

* style: set highlighted souce code block width `100%`

* style: highlight the entire row

* Update docs/theme/default.md

---------

Co-authored-by: Peach <scdzwyxst@gmail.com>
  • Loading branch information
KuangPF and PeachScript authored May 19, 2023
1 parent 76260bf commit f9ba285
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 15 deletions.
7 changes: 7 additions & 0 deletions docs/theme/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ dumi 内置了一套完善的默认主题,默认主题的呈现效果与 dumi

是否开启 RTL 切换,配置为 `true` 时导航栏会展示 RTL 按钮,用于将站点文本阅读方向切换为『从右到左』,通常在站点用户群体中有使用希伯来语或阿拉伯语时启用。

### showLineNum <Badge>2.2.0+</Badge>

- 类型:`boolean`
- 默认值:`false`

是否在代码块中展示行号,配置为 `true` 时会展示代码行号。

### nprogress (v2.1.23+)

- 类型:`boolean`
Expand Down
1 change: 1 addition & 0 deletions src/client/theme-api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ export interface IThemeConfig {
nav?: IUserNavValue | NavWithMode<IUserNavValue>;
sidebar?: Record<string, ISidebarGroup[]>;
footer?: string | false;
showLineNum?: boolean;
prefersColor: {
default: 'light' | 'dark' | 'auto';
switch: boolean;
Expand Down
9 changes: 6 additions & 3 deletions src/client/theme-default/builtins/API/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,12 @@ const HANDLERS = {
const signatures = 'oneOf' in signature ? signature.oneOf : [signature];

return signatures
.map(signature => `${signature.isAsync ? 'async ' : ''}(${signature.arguments
.map((arg: any) => `${arg.key}: ${this.toString(arg)}`)
.join(', ')}) => ${this.toString(signature.returnType)}`)
.map(
(signature) =>
`${signature.isAsync ? 'async ' : ''}(${signature.arguments
.map((arg: any) => `${arg.key}: ${this.toString(arg)}`)
.join(', ')}) => ${this.toString(signature.returnType)}`,
)
.join(' | ');
},
// FIXME: extract real type
Expand Down
56 changes: 53 additions & 3 deletions src/client/theme-default/builtins/SourceCode/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,50 @@

// highlight line
& > .highlighted {
position: relative;
width: calc(100% + 24px);
background-color: shade(@bg-color, 5%);
width: calc(100% + 48px);
margin-inline-start: -24px;
padding-inline-start: 24px;

.line-cell {
position: relative;

&::after {
content: '';
position: absolute;
top: 0;
right: -24px;
bottom: 0;
width: 24px;
background-color: shade(@bg-color, 5%);
}
}

&::after {
content: '';
position: absolute;
top: 0;
left: -24px;
bottom: 0;
width: 24px;
background-color: shade(@bg-color, 5%);
}
}

& > .wrap {
display: table-row;

& > .token-line-num {
display: table-cell;
text-align: right;
padding-right: 1em;
user-select: none;
opacity: 0.5;
}

& > .line-cell {
display: table-cell;
width: 100%;
}
}
}

Expand Down Expand Up @@ -103,6 +143,16 @@

& > pre.prism-code > .highlighted {
background-color: tint(@bg-color, 10%);

&::after {
background-color: tint(@bg-color, 10%);
}

.line-cell {
&::after {
background-color: tint(@bg-color, 10%);
}
}
}
}
}
32 changes: 23 additions & 9 deletions src/client/theme-default/builtins/SourceCode/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ReactComponent as IconCheck } from '@ant-design/icons-svg/inline-svg/outlined/check.svg';
import { ReactComponent as IconCopy } from '@ant-design/icons-svg/inline-svg/outlined/copy.svg';
import classNames from 'classnames';
import { useSiteData } from 'dumi';
import Highlight, { defaultProps, type Language } from 'prism-react-renderer';
import 'prism-themes/themes/prism-one-light.css';
import React, { useRef, useState, type FC } from 'react';
Expand All @@ -25,6 +26,7 @@ const SourceCode: FC<SourceCodeProps> = (props) => {
const { children = '', lang, highlightLines = [] } = props;
const timer = useRef<number>();
const [isCopied, setIsCopied] = useState(false);
const { themeConfig } = useSiteData();

return (
<div className="dumi-default-source-code">
Expand Down Expand Up @@ -55,17 +57,29 @@ const SourceCode: FC<SourceCodeProps> = (props) => {
{tokens.map((line, i) => (
<div
key={String(i)}
{...getLineProps({
line,
key: i,
className: classNames({
highlighted: highlightLines.includes(i + 1),
}),
className={classNames({
highlighted: highlightLines.includes(i + 1),
wrap: themeConfig.showLineNum,
})}
>
{line.map((token, key) => (
<span key={String(i)} {...getTokenProps({ token, key })} />
))}
{themeConfig.showLineNum && (
<span className="token-line-num">{i + 1}</span>
)}
<div
{...getLineProps({
line,
key: i,
})}
className={classNames({
'line-cell': themeConfig.showLineNum,
})}
>
{line.map((token, key) => (
// getTokenProps 返回值包含 key
// eslint-disable-next-line react/jsx-key
<span {...getTokenProps({ token, key })} />
))}
</div>
</div>
))}
</pre>
Expand Down

0 comments on commit f9ba285

Please sign in to comment.