mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-29 09:44:47 +00:00
new framwork
This commit is contained in:
279
client/src/components/Markdown/codeLight.ts
Normal file
279
client/src/components/Markdown/codeLight.ts
Normal file
@@ -0,0 +1,279 @@
|
||||
import React from 'react';
|
||||
export const codeLight: { [key: string]: React.CSSProperties } = {
|
||||
'code[class*=language-]': {
|
||||
color: '#d4d4d4',
|
||||
textShadow: 'none',
|
||||
direction: 'ltr',
|
||||
textAlign: 'left',
|
||||
whiteSpace: 'pre',
|
||||
wordSpacing: 'normal',
|
||||
wordBreak: 'normal',
|
||||
lineHeight: '1.5',
|
||||
MozTabSize: '4',
|
||||
OTabSize: '4',
|
||||
tabSize: '4',
|
||||
WebkitHyphens: 'none',
|
||||
MozHyphens: 'none',
|
||||
msHyphens: 'none',
|
||||
hyphens: 'none'
|
||||
},
|
||||
'pre[class*=language-]': {
|
||||
color: '#d4d4d4',
|
||||
textShadow: 'none',
|
||||
direction: 'ltr',
|
||||
textAlign: 'left',
|
||||
whiteSpace: 'pre',
|
||||
wordSpacing: 'normal',
|
||||
wordBreak: 'normal',
|
||||
lineHeight: '1.5',
|
||||
MozTabSize: '4',
|
||||
OTabSize: '4',
|
||||
tabSize: '4',
|
||||
WebkitHyphens: 'none',
|
||||
MozHyphens: 'none',
|
||||
msHyphens: 'none',
|
||||
hyphens: 'none',
|
||||
padding: '1em',
|
||||
margin: '.5em 0',
|
||||
overflow: 'auto',
|
||||
background: '#1e1e1e'
|
||||
},
|
||||
'code[class*=language-] ::selection': {
|
||||
textShadow: 'none',
|
||||
background: '#264f78'
|
||||
},
|
||||
'code[class*=language-]::selection': {
|
||||
textShadow: 'none',
|
||||
background: '#264f78'
|
||||
},
|
||||
'pre[class*=language-] ::selection': {
|
||||
textShadow: 'none',
|
||||
background: '#264f78'
|
||||
},
|
||||
'pre[class*=language-]::selection': {
|
||||
textShadow: 'none',
|
||||
background: '#264f78'
|
||||
},
|
||||
':not(pre)>code[class*=language-]': {
|
||||
padding: '.1em .3em',
|
||||
borderRadius: '.3em',
|
||||
color: '#db4c69',
|
||||
background: '#1e1e1e'
|
||||
},
|
||||
'.namespace': {
|
||||
opacity: '0.7'
|
||||
},
|
||||
'doctype.doctype-tag': {
|
||||
color: '#569cd6'
|
||||
},
|
||||
'doctype.name': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
comment: {
|
||||
color: '#6a9955'
|
||||
},
|
||||
prolog: {
|
||||
color: '#6a9955'
|
||||
},
|
||||
'.language-html .language-css .token.punctuation': {
|
||||
color: '#d4d4d4'
|
||||
},
|
||||
'.language-html .language-javascript .token.punctuation': {
|
||||
color: '#d4d4d4'
|
||||
},
|
||||
punctuation: {
|
||||
color: '#d4d4d4'
|
||||
},
|
||||
boolean: {
|
||||
color: '#569cd6'
|
||||
},
|
||||
constant: {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
inserted: {
|
||||
color: '#b5cea8'
|
||||
},
|
||||
number: {
|
||||
color: '#b5cea8'
|
||||
},
|
||||
property: {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
symbol: {
|
||||
color: '#b5cea8'
|
||||
},
|
||||
tag: {
|
||||
color: '#569cd6'
|
||||
},
|
||||
unit: {
|
||||
color: '#b5cea8'
|
||||
},
|
||||
'attr-name': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
builtin: {
|
||||
color: '#ce9178'
|
||||
},
|
||||
char: {
|
||||
color: '#ce9178'
|
||||
},
|
||||
deleted: {
|
||||
color: '#ce9178'
|
||||
},
|
||||
selector: {
|
||||
color: '#d7ba7d'
|
||||
},
|
||||
string: {
|
||||
color: '#ce9178'
|
||||
},
|
||||
'.language-css .token.string.url': {
|
||||
textDecoration: 'underline'
|
||||
},
|
||||
entity: {
|
||||
color: '#569cd6'
|
||||
},
|
||||
operator: {
|
||||
color: '#d4d4d4'
|
||||
},
|
||||
'operator.arrow': {
|
||||
color: '#569cd6'
|
||||
},
|
||||
atrule: {
|
||||
color: '#ce9178'
|
||||
},
|
||||
'atrule.rule': {
|
||||
color: '#c586c0'
|
||||
},
|
||||
'atrule.url': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'atrule.url.function': {
|
||||
color: '#dcdcaa'
|
||||
},
|
||||
'atrule.url.punctuation': {
|
||||
color: '#d4d4d4'
|
||||
},
|
||||
keyword: {
|
||||
color: '#569cd6'
|
||||
},
|
||||
'keyword.control-flow': {
|
||||
color: '#c586c0'
|
||||
},
|
||||
'keyword.module': {
|
||||
color: '#c586c0'
|
||||
},
|
||||
function: {
|
||||
color: '#dcdcaa'
|
||||
},
|
||||
'function.maybe-class-name': {
|
||||
color: '#dcdcaa'
|
||||
},
|
||||
regex: {
|
||||
color: '#d16969'
|
||||
},
|
||||
important: {
|
||||
color: '#569cd6'
|
||||
},
|
||||
italic: {
|
||||
fontStyle: 'italic'
|
||||
},
|
||||
'class-name': {
|
||||
color: '#4ec9b0'
|
||||
},
|
||||
'maybe-class-name': {
|
||||
color: '#4ec9b0'
|
||||
},
|
||||
console: {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
parameter: {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
interpolation: {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'punctuation.interpolation-punctuation': {
|
||||
color: '#569cd6'
|
||||
},
|
||||
'exports.maybe-class-name': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'imports.maybe-class-name': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
variable: {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
escape: {
|
||||
color: '#d7ba7d'
|
||||
},
|
||||
'tag.punctuation': {
|
||||
color: 'grey'
|
||||
},
|
||||
cdata: {
|
||||
color: 'grey'
|
||||
},
|
||||
'attr-value': {
|
||||
color: '#ce9178'
|
||||
},
|
||||
'attr-value.punctuation': {
|
||||
color: '#ce9178'
|
||||
},
|
||||
'attr-value.punctuation.attr-equals': {
|
||||
color: '#d4d4d4'
|
||||
},
|
||||
namespace: {
|
||||
color: '#4ec9b0'
|
||||
},
|
||||
'code[class*=language-javascript]': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'code[class*=language-jsx]': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'code[class*=language-tsx]': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'code[class*=language-typescript]': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'pre[class*=language-javascript]': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'pre[class*=language-jsx]': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'pre[class*=language-tsx]': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'pre[class*=language-typescript]': {
|
||||
color: '#9cdcfe'
|
||||
},
|
||||
'code[class*=language-css]': {
|
||||
color: '#ce9178'
|
||||
},
|
||||
'pre[class*=language-css]': {
|
||||
color: '#ce9178'
|
||||
},
|
||||
'code[class*=language-html]': {
|
||||
color: '#d4d4d4'
|
||||
},
|
||||
'pre[class*=language-html]': {
|
||||
color: '#d4d4d4'
|
||||
},
|
||||
'.language-regex .token.anchor': {
|
||||
color: '#dcdcaa'
|
||||
},
|
||||
'.language-html .token.punctuation': {
|
||||
color: 'grey'
|
||||
},
|
||||
'pre[class*=language-]>code[class*=language-]': {
|
||||
position: 'relative',
|
||||
zIndex: '1'
|
||||
},
|
||||
'.line-highlight.line-highlight': {
|
||||
background: '#f7ebc6',
|
||||
boxShadow: 'inset 5px 0 0 #f7d87c',
|
||||
zIndex: '0'
|
||||
}
|
||||
};
|
418
client/src/components/Markdown/index.module.scss
Normal file
418
client/src/components/Markdown/index.module.scss
Normal file
@@ -0,0 +1,418 @@
|
||||
.waitingAnimation::after {
|
||||
display: inline-block;
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 14px;
|
||||
transform: translate(4px, 2px) scaleY(1.3);
|
||||
background-color: var(--chakra-colors-chakra-body-text);
|
||||
animation: blink 0.6s infinite;
|
||||
}
|
||||
.animation {
|
||||
> :last-child::after {
|
||||
display: inline-block;
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 14px;
|
||||
transform: translate(4px, 2px) scaleY(1.3);
|
||||
background-color: var(--chakra-colors-chakra-body-text);
|
||||
animation: blink 0.6s infinite;
|
||||
}
|
||||
}
|
||||
@keyframes blink {
|
||||
from,
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown > *:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
.markdown > *:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.markdown a.absent {
|
||||
color: #cc0000;
|
||||
}
|
||||
.markdown a.anchor {
|
||||
bottom: 0;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
left: 0;
|
||||
margin-left: -30px;
|
||||
padding-left: 30px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.markdown h1,
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
cursor: text;
|
||||
font-weight: bold;
|
||||
margin: 10px 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
.markdown h1 .mini-icon-link,
|
||||
.markdown h2 .mini-icon-link,
|
||||
.markdown h3 .mini-icon-link,
|
||||
.markdown h4 .mini-icon-link,
|
||||
.markdown h5 .mini-icon-link,
|
||||
.markdown h6 .mini-icon-link {
|
||||
display: none;
|
||||
}
|
||||
.markdown h1:hover a.anchor,
|
||||
.markdown h2:hover a.anchor,
|
||||
.markdown h3:hover a.anchor,
|
||||
.markdown h4:hover a.anchor,
|
||||
.markdown h5:hover a.anchor,
|
||||
.markdown h6:hover a.anchor {
|
||||
line-height: 1;
|
||||
margin-left: -22px;
|
||||
padding-left: 0;
|
||||
text-decoration: none;
|
||||
top: 15%;
|
||||
}
|
||||
.markdown h1:hover a.anchor .mini-icon-link,
|
||||
.markdown h2:hover a.anchor .mini-icon-link,
|
||||
.markdown h3:hover a.anchor .mini-icon-link,
|
||||
.markdown h4:hover a.anchor .mini-icon-link,
|
||||
.markdown h5:hover a.anchor .mini-icon-link,
|
||||
.markdown h6:hover a.anchor .mini-icon-link {
|
||||
display: inline-block;
|
||||
}
|
||||
.markdown h1 tt,
|
||||
.markdown h1 code,
|
||||
.markdown h2 tt,
|
||||
.markdown h2 code,
|
||||
.markdown h3 tt,
|
||||
.markdown h3 code,
|
||||
.markdown h4 tt,
|
||||
.markdown h4 code,
|
||||
.markdown h5 tt,
|
||||
.markdown h5 code,
|
||||
.markdown h6 tt,
|
||||
.markdown h6 code {
|
||||
font-size: inherit;
|
||||
}
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
.markdown h2 {
|
||||
font-size: 24px;
|
||||
}
|
||||
.markdown h3 {
|
||||
font-size: 18px;
|
||||
}
|
||||
.markdown h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
.markdown h5 {
|
||||
font-size: 14px;
|
||||
}
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
.markdown p,
|
||||
.markdown blockquote,
|
||||
.markdown ul,
|
||||
.markdown ol,
|
||||
.markdown dl,
|
||||
.markdown table,
|
||||
.markdown pre {
|
||||
margin: 10px 0;
|
||||
}
|
||||
.markdown > h2:first-child,
|
||||
.markdown > h1:first-child,
|
||||
.markdown > h1:first-child + h2,
|
||||
.markdown > h3:first-child,
|
||||
.markdown > h4:first-child,
|
||||
.markdown > h5:first-child,
|
||||
.markdown > h6:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
.markdown a:first-child h1,
|
||||
.markdown a:first-child h2,
|
||||
.markdown a:first-child h3,
|
||||
.markdown a:first-child h4,
|
||||
.markdown a:first-child h5,
|
||||
.markdown a:first-child h6 {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
.markdown h1 + p,
|
||||
.markdown h2 + p,
|
||||
.markdown h3 + p,
|
||||
.markdown h4 + p,
|
||||
.markdown h5 + p,
|
||||
.markdown h6 + p {
|
||||
margin-top: 0;
|
||||
}
|
||||
.markdown li p.first {
|
||||
display: inline-block;
|
||||
}
|
||||
.markdown ul,
|
||||
.markdown ol {
|
||||
padding-left: 2em;
|
||||
}
|
||||
.markdown ul.no-list,
|
||||
.markdown ol.no-list {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
.markdown ul li > *:first-child,
|
||||
.markdown ol li > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.markdown ul ul,
|
||||
.markdown ul ol,
|
||||
.markdown ol ol,
|
||||
.markdown ol ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.markdown dl {
|
||||
padding: 0;
|
||||
}
|
||||
.markdown dl dt {
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
margin: 15px 0 5px;
|
||||
padding: 0;
|
||||
}
|
||||
.markdown dl dt:first-child {
|
||||
padding: 0;
|
||||
}
|
||||
.markdown dl dt > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.markdown dl dt > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.markdown dl dd {
|
||||
margin: 0 0 15px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
.markdown dl dd > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.markdown dl dd > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.markdown blockquote {
|
||||
border-left: 4px solid #dddddd;
|
||||
color: #777777;
|
||||
padding: 0 15px;
|
||||
}
|
||||
.markdown blockquote > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.markdown blockquote > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.markdown table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
.markdown table th,
|
||||
.markdown table td {
|
||||
padding: 6px 13px;
|
||||
}
|
||||
.markdown table tr {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.markdown table tr:nth-child(2n) {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
.markdown img {
|
||||
max-width: 100%;
|
||||
}
|
||||
.markdown span.frame {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
.markdown span.frame > span {
|
||||
border: 1px solid #dddddd;
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 13px 0 0;
|
||||
overflow: hidden;
|
||||
padding: 7px;
|
||||
width: auto;
|
||||
}
|
||||
.markdown span.frame span img {
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
.markdown span.frame span span {
|
||||
clear: both;
|
||||
color: #333333;
|
||||
display: block;
|
||||
padding: 5px 0 0;
|
||||
}
|
||||
.markdown span.align-center {
|
||||
clear: both;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
.markdown span.align-center > span {
|
||||
display: block;
|
||||
margin: 13px auto 0;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
.markdown span.align-center span img {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
.markdown span.align-right {
|
||||
clear: both;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
.markdown span.align-right > span {
|
||||
display: block;
|
||||
margin: 13px 0 0;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
.markdown span.align-right span img {
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
.markdown span.float-left {
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 13px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.markdown span.float-left span {
|
||||
margin: 13px 0 0;
|
||||
}
|
||||
.markdown span.float-right {
|
||||
display: block;
|
||||
float: right;
|
||||
margin-left: 13px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.markdown span.float-right > span {
|
||||
display: block;
|
||||
margin: 13px auto 0;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
.markdown code,
|
||||
.markdown tt {
|
||||
border: 1px solid #eaeaea;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
margin: 0 2px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.markdown pre > code {
|
||||
background: none repeat scroll 0 0 transparent;
|
||||
border: medium none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
white-space: pre;
|
||||
}
|
||||
.markdown .highlight pre,
|
||||
.markdown pre {
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
font-size: max(0.9em, 14px);
|
||||
line-height: 19px;
|
||||
overflow: auto;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
.markdown pre code,
|
||||
.markdown pre tt {
|
||||
background-color: transparent;
|
||||
border: medium none;
|
||||
}
|
||||
.markdown {
|
||||
text-align: justify;
|
||||
tab-size: 4;
|
||||
word-spacing: normal;
|
||||
width: 100%;
|
||||
|
||||
* {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
p {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: #292b33 !important;
|
||||
overflow-x: auto;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background-color: #292b33 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: var(--chakra-colors-blue-600);
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0px;
|
||||
color: var(--chakra-colors-gray-700);
|
||||
|
||||
thead tr:first-child th {
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-width: 1px;
|
||||
border-color: #ccc;
|
||||
background-color: rgba(236, 236, 241, 0.2);
|
||||
overflow: hidden;
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: 0.375rem;
|
||||
}
|
||||
&:last-child {
|
||||
border-right-width: 1px;
|
||||
border-top-right-radius: 0.375rem;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-color: #ccc;
|
||||
|
||||
&:last-of-type {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
tbody tr:last-child {
|
||||
overflow: hidden;
|
||||
td {
|
||||
&:first-child {
|
||||
border-bottom-left-radius: 0.375rem;
|
||||
}
|
||||
&:last-child {
|
||||
border-bottom-right-radius: 0.375rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
83
client/src/components/Markdown/index.tsx
Normal file
83
client/src/components/Markdown/index.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import React, { memo, useMemo } from 'react';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { Box, Flex, useColorModeValue } from '@chakra-ui/react';
|
||||
import { useCopyData, formatLinkText } from '@/utils/tools';
|
||||
import Icon from '@/components/Icon';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkMath from 'remark-math';
|
||||
import rehypeKatex from 'rehype-katex';
|
||||
|
||||
import 'katex/dist/katex.min.css';
|
||||
import styles from './index.module.scss';
|
||||
import { codeLight } from './codeLight';
|
||||
|
||||
const Markdown = ({
|
||||
source,
|
||||
isChatting = false,
|
||||
formatLink
|
||||
}: {
|
||||
source: string;
|
||||
formatLink?: boolean;
|
||||
isChatting?: boolean;
|
||||
}) => {
|
||||
const { copyData } = useCopyData();
|
||||
|
||||
const formatSource = useMemo(() => {
|
||||
return formatLink ? formatLinkText(source) : source;
|
||||
}, [source, formatLink]);
|
||||
|
||||
return (
|
||||
<ReactMarkdown
|
||||
className={`markdown ${styles.markdown} ${
|
||||
isChatting ? (source === '' ? styles.waitingAnimation : styles.animation) : ''
|
||||
}`}
|
||||
remarkPlugins={[remarkMath]}
|
||||
rehypePlugins={[remarkGfm, rehypeKatex]}
|
||||
components={{
|
||||
pre: 'div',
|
||||
code({ node, inline, className, children, ...props }) {
|
||||
const match = /language-(\w+)/.exec(className || '');
|
||||
const code = String(children);
|
||||
|
||||
return !inline || match ? (
|
||||
<Box my={3} borderRadius={'md'} overflow={'overlay'} backgroundColor={'#222'}>
|
||||
<Flex
|
||||
className="code-header"
|
||||
py={2}
|
||||
px={5}
|
||||
backgroundColor={useColorModeValue('#323641', 'gray.600')}
|
||||
color={'#fff'}
|
||||
fontSize={'sm'}
|
||||
userSelect={'none'}
|
||||
>
|
||||
<Box flex={1}>{match?.[1]}</Box>
|
||||
<Flex cursor={'pointer'} onClick={() => copyData(code)} alignItems={'center'}>
|
||||
<Icon name={'copy'} width={15} height={15} fill={'#fff'}></Icon>
|
||||
<Box ml={1}>复制代码</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<SyntaxHighlighter
|
||||
style={codeLight as any}
|
||||
language={match?.[1]}
|
||||
PreTag="pre"
|
||||
{...props}
|
||||
>
|
||||
{code}
|
||||
</SyntaxHighlighter>
|
||||
</Box>
|
||||
) : (
|
||||
<code className={className} {...props}>
|
||||
{code}
|
||||
</code>
|
||||
);
|
||||
}
|
||||
}}
|
||||
linkTarget="_blank"
|
||||
>
|
||||
{formatSource}
|
||||
</ReactMarkdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(Markdown);
|
Reference in New Issue
Block a user