mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-13 00:03:57 +02:00
feat(v2): add filename in CodeBlock (#2346)
* feat: add filename in CodeBlock * Fix code to use Regex to find title from markdown and Update style * Fix reviewed point - Delete unnecessary template literals - Delete unnecessary "important!" from css * Add title in live codeblock * Just edit code order * Add demo for code title * Add docs about code title in markdown-features.mdx * Make code title height scalable * Rename codeBlockWrapper to codeBlockContent * Make copyButton appear when hovering codeTitle * Fix docs description about code title
This commit is contained in:
parent
201c663318
commit
5e0d11dbaf
6 changed files with 166 additions and 60 deletions
|
@ -17,6 +17,7 @@ import useThemeContext from '@theme/hooks/useThemeContext';
|
|||
import styles from './styles.module.css';
|
||||
|
||||
const highlightLinesRangeRegex = /{([\d,-]+)}/;
|
||||
const codeBlockTitleRegex = /title=".*"/;
|
||||
|
||||
export default ({children, className: languageClassName, metastring}) => {
|
||||
const {
|
||||
|
@ -41,6 +42,7 @@ export default ({children, className: languageClassName, metastring}) => {
|
|||
const target = useRef(null);
|
||||
const button = useRef(null);
|
||||
let highlightLines = [];
|
||||
let codeBlockTitle = '';
|
||||
|
||||
const {isDarkTheme} = useThemeContext();
|
||||
const lightModeTheme = prism.theme || defaultTheme;
|
||||
|
@ -52,6 +54,13 @@ export default ({children, className: languageClassName, metastring}) => {
|
|||
highlightLines = rangeParser.parse(highlightLinesRange).filter(n => n > 0);
|
||||
}
|
||||
|
||||
if (metastring && codeBlockTitleRegex.test(metastring)) {
|
||||
codeBlockTitle = metastring
|
||||
.match(codeBlockTitleRegex)[0]
|
||||
.split('title=')[1]
|
||||
.replace(/"+/g, '');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let clipboard;
|
||||
|
||||
|
@ -90,38 +99,51 @@ export default ({children, className: languageClassName, metastring}) => {
|
|||
code={children.replace(/\n$/, '')}
|
||||
language={language}>
|
||||
{({className, style, tokens, getLineProps, getTokenProps}) => (
|
||||
<pre className={classnames(className, styles.codeBlock)}>
|
||||
<button
|
||||
ref={button}
|
||||
type="button"
|
||||
aria-label="Copy code to clipboard"
|
||||
className={styles.copyButton}
|
||||
onClick={handleCopyCode}>
|
||||
{showCopied ? 'Copied' : 'Copy'}
|
||||
</button>
|
||||
<>
|
||||
{codeBlockTitle && (
|
||||
<div style={style} className={styles.codeBlockTitle}>
|
||||
{codeBlockTitle}
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.codeBlockContent}>
|
||||
<button
|
||||
ref={button}
|
||||
type="button"
|
||||
aria-label="Copy code to clipboard"
|
||||
className={classnames(styles.copyButton, {
|
||||
[styles.copyButtonWithTitle]: codeBlockTitle,
|
||||
})}
|
||||
onClick={handleCopyCode}>
|
||||
{showCopied ? 'Copied' : 'Copy'}
|
||||
</button>
|
||||
<pre
|
||||
className={classnames(className, styles.codeBlock, {
|
||||
[styles.codeBlockWithTitle]: codeBlockTitle,
|
||||
})}>
|
||||
<div ref={target} className={styles.codeBlockLines} style={style}>
|
||||
{tokens.map((line, i) => {
|
||||
if (line.length === 1 && line[0].content === '') {
|
||||
line[0].content = '\n'; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
|
||||
<div ref={target} className={styles.codeBlockLines} style={style}>
|
||||
{tokens.map((line, i) => {
|
||||
if (line.length === 1 && line[0].content === '') {
|
||||
line[0].content = '\n'; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
const lineProps = getLineProps({line, key: i});
|
||||
|
||||
const lineProps = getLineProps({line, key: i});
|
||||
if (highlightLines.includes(i + 1)) {
|
||||
lineProps.className = `${lineProps.className} docusaurus-highlight-code-line`;
|
||||
}
|
||||
|
||||
if (highlightLines.includes(i + 1)) {
|
||||
lineProps.className = `${lineProps.className} docusaurus-highlight-code-line`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={i} {...lineProps}>
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({token, key})} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
return (
|
||||
<div key={i} {...lineProps}>
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({token, key})} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</pre>
|
||||
</div>
|
||||
</pre>
|
||||
</>
|
||||
)}
|
||||
</Highlight>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue