mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
markdown preview
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
.markdown {
|
||||
color: var(--main-color);
|
||||
font-family: var(--markdown-font);
|
||||
font-size: 14px;
|
||||
overflow-wrap: break-word;
|
||||
|
||||
&.bottom-margin {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--main-color);
|
||||
margin-top: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--main-color);
|
||||
}
|
||||
|
||||
a {
|
||||
color: #32afff;
|
||||
}
|
||||
|
||||
table {
|
||||
tr th {
|
||||
color: var(--main-color);
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
list-style-position: outside;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style-position: outside;
|
||||
margin-left: 19px;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 4px 10px 4px 10px;
|
||||
border-radius: 3px;
|
||||
background-color: var(--panel-bg-color);
|
||||
padding: 2px 4px 2px 6px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: var(--panel-bg-color);
|
||||
margin: 4px 10px 4px 10px;
|
||||
padding: 0.7em;
|
||||
border-radius: 4px;
|
||||
|
||||
code {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
font: var(--fixed-font);
|
||||
color: var(--main-color);
|
||||
border-radius: 4px;
|
||||
background-color: var(--panel-bg-color);
|
||||
padding: 0.15em 0.5em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: semibold;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.title.is-1 {
|
||||
border-bottom: 1px solid #777;
|
||||
padding-bottom: 6px;
|
||||
font-size: 2em;
|
||||
}
|
||||
.title.is-2 {
|
||||
border-bottom: 1px solid #777;
|
||||
padding-bottom: 6px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.title.is-3 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
.title.is-4 {
|
||||
font-size: 1em;
|
||||
}
|
||||
.title.is-5 {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
.title.is-6 {
|
||||
font-size: 0.85em;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown > *:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import * as React from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import { clsx } from "clsx";
|
||||
|
||||
import "./markdown.less";
|
||||
|
||||
function LinkRenderer(props: any): any {
|
||||
let newUrl = "https://extern?" + encodeURIComponent(props.href);
|
||||
return (
|
||||
<a href={newUrl} target="_blank" rel={"noopener"}>
|
||||
{props.children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
function HeaderRenderer(props: any, hnum: number): any {
|
||||
return <div className={clsx("title", "is-" + hnum)}>{props.children}</div>;
|
||||
}
|
||||
|
||||
function Markdown(props: { text: string; style?: any; extraClassName?: string; codeSelect?: boolean }) {
|
||||
let text = props.text;
|
||||
let markdownComponents = {
|
||||
a: LinkRenderer,
|
||||
h1: (props) => HeaderRenderer(props, 1),
|
||||
h2: (props) => HeaderRenderer(props, 2),
|
||||
h3: (props) => HeaderRenderer(props, 3),
|
||||
h4: (props) => HeaderRenderer(props, 4),
|
||||
h5: (props) => HeaderRenderer(props, 5),
|
||||
h6: (props) => HeaderRenderer(props, 6),
|
||||
};
|
||||
return (
|
||||
<div className={clsx("markdown", props.extraClassName)} style={props.style}>
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]} components={markdownComponents}>
|
||||
{text}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export { Markdown };
|
||||
@@ -24,7 +24,7 @@ const blockAtomFamily = atomFamily<string, jotai.Atom<BlockData>>((blockId: stri
|
||||
return jotai.atom({ blockid: blockId1, view: "term" });
|
||||
}
|
||||
if (blockId === blockId2) {
|
||||
return jotai.atom({ blockid: blockId2, view: "preview" });
|
||||
return jotai.atom({ blockid: blockId2, view: "preview", meta: { mimetype: "text/markdown" } });
|
||||
}
|
||||
if (blockId === blockId3) {
|
||||
return jotai.atom({ blockid: blockId3, view: "term" });
|
||||
|
||||
@@ -22,10 +22,4 @@
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.block1 {
|
||||
}
|
||||
|
||||
.block2 {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,37 @@
|
||||
|
||||
import * as React from "react";
|
||||
import * as jotai from "jotai";
|
||||
import { atoms } from "@/store/global";
|
||||
import { Markdown } from "@/element/markdown";
|
||||
|
||||
import "./view.less";
|
||||
|
||||
const markdownText = `
|
||||
# Markdown Preview
|
||||
|
||||
* list item 1
|
||||
* list item 2
|
||||
* item 3
|
||||
|
||||
\`\`\`
|
||||
let foo = "bar";
|
||||
console.log(foo);
|
||||
\`\`\`
|
||||
`;
|
||||
|
||||
const MarkdownPreview = ({ blockData }: { blockData: BlockData }) => {
|
||||
return (
|
||||
<div className="view-preview view-preview-markdown">
|
||||
<Markdown text={markdownText} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const PreviewView = ({ blockId }: { blockId: string }) => {
|
||||
const blockData: BlockData = jotai.useAtomValue(atoms.blockAtomFamily(blockId));
|
||||
if (blockData.meta?.mimetype === "text/markdown") {
|
||||
return <MarkdownPreview blockData={blockData} />;
|
||||
}
|
||||
return (
|
||||
<div className="view-preview">
|
||||
<div>Preview</div>
|
||||
|
||||
@@ -18,4 +18,9 @@
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.view-preview-markdown {
|
||||
align-items: start;
|
||||
justify-content: start;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -11,6 +11,7 @@ declare global {
|
||||
type BlockData = {
|
||||
blockid: string;
|
||||
view: string;
|
||||
meta?: Record<string, any>;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user