feat: work on highlighting and displaying language snippets
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
overflow: auto;
|
||||
padding: 1rem;
|
||||
scrollbar-color: #043160 #0b3766;
|
||||
max-height: calc(100vh - 280px);
|
||||
}
|
||||
|
||||
.snippetContent>pre::-webkit-scrollbar {
|
||||
@@ -1,13 +1,14 @@
|
||||
'use client';
|
||||
|
||||
import Prism from 'prismjs';
|
||||
import 'prismjs/components/prism-json';
|
||||
import 'prismjs/themes/prism.css';
|
||||
import {
|
||||
Children,
|
||||
MouseEvent,
|
||||
ReactElement,
|
||||
useState,
|
||||
} from 'react';
|
||||
import styles from './CodeSnippet.module.css';
|
||||
|
||||
import { MouseEvent, useEffect, useState } from 'react';
|
||||
import styles from './Code.module.css';
|
||||
|
||||
function CodeCopyButton() {
|
||||
function CodeSnippetCopyButton() {
|
||||
const [copyButtonTooltip, setCopyButtonTooltip] =
|
||||
useState<boolean>(false);
|
||||
|
||||
@@ -65,27 +66,42 @@ function CodeCopyButton() {
|
||||
);
|
||||
}
|
||||
|
||||
export default function Code({
|
||||
function SnippetLanguageDropdown() {}
|
||||
|
||||
export default function CodeSnippet({
|
||||
children,
|
||||
language,
|
||||
heading,
|
||||
defaultLanguage,
|
||||
}: {
|
||||
children: string;
|
||||
language: string;
|
||||
children: ReactElement;
|
||||
heading: string;
|
||||
defaultLanguage: string;
|
||||
}) {
|
||||
useEffect(() => {
|
||||
Prism.highlightAll();
|
||||
}, []);
|
||||
const [selectedLanguage, setSelectedLanguage] =
|
||||
useState<string>(defaultLanguage);
|
||||
|
||||
const snippetLanguages = Children.toArray(children).map(
|
||||
(child: any) => child.props.className.split('-')[1]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.snippetContainer}>
|
||||
<div className={styles.snippetHeader}>
|
||||
<div>{heading}</div>
|
||||
<CodeCopyButton />
|
||||
<CodeSnippetCopyButton />
|
||||
</div>
|
||||
<div className={styles.snippetContent}>
|
||||
{children}
|
||||
<pre>
|
||||
{Children.toArray(children)
|
||||
.filter(
|
||||
(child: any) =>
|
||||
child.props.className ===
|
||||
`language-${defaultLanguage}`
|
||||
)
|
||||
.map(child => {
|
||||
return child;
|
||||
})}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,24 @@
|
||||
import Prism from 'prismjs';
|
||||
import 'prismjs/components/prism-bash';
|
||||
import 'prismjs/components/prism-json';
|
||||
import './prism-custom.css';
|
||||
|
||||
export default function Fence({
|
||||
content,
|
||||
language,
|
||||
}: {
|
||||
content: string;
|
||||
language: string;
|
||||
}) {
|
||||
const html = Prism.highlight(
|
||||
content,
|
||||
Prism.languages[language],
|
||||
language
|
||||
);
|
||||
return (
|
||||
<code
|
||||
className={`language-${language}`}
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
></code>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #f8f8f2;
|
||||
background: none;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre)>code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #282a36;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre)>code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: #6272a4;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #ff79c6;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number {
|
||||
color: #bd93f9;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #50fa7b;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string,
|
||||
.token.variable {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #f1fa8c;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: #8be9fd;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important {
|
||||
color: #ffb86c;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
Reference in New Issue
Block a user