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:
Kohhee Peace 2020-03-26 01:05:18 +08:00 committed by GitHub
parent 201c663318
commit 5e0d11dbaf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 166 additions and 60 deletions

View file

@ -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>
);