feat: work on highlighting and displaying language snippets

This commit is contained in:
Stevan Freeborn
2023-04-11 22:45:48 -05:00
parent c87b2a39e8
commit 5f4d4f656e
8 changed files with 202 additions and 27 deletions
@@ -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>
);
+24
View File
@@ -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>
);
}
+115
View File
@@ -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;
}