finish merge from 'main'

This commit is contained in:
Andrew 2024-10-11 17:11:44 -07:00
parent 23a42659b3
commit 29ef6b5b43
4 changed files with 32 additions and 270 deletions

View file

@ -1,85 +0,0 @@
import React, { ReactNode, useCallback, useEffect, useState } from "react"
import { getVSCodeAPI } from "../getVscodeApi"
import { classNames } from "../utils"
enum CopyButtonState {
Copy = "Copy",
Copied = "Copied!",
Error = "Could not copy",
}
const COPY_FEEDBACK_TIMEOUT = 1000
// code block with Apply button at top
const BlockCode = ({
text,
toolbar,
hideToolbar = false,
className,
}: {
text: string
toolbar?: ReactNode
hideToolbar?: boolean
className?: string
}) => {
const [copyButtonState, setCopyButtonState] = useState(CopyButtonState.Copy)
useEffect(() => {
if (copyButtonState !== CopyButtonState.Copy) {
setTimeout(() => {
setCopyButtonState(CopyButtonState.Copy)
}, COPY_FEEDBACK_TIMEOUT)
}
}, [copyButtonState])
const onCopy = useCallback(() => {
navigator.clipboard.writeText(text).then(
() => {
setCopyButtonState(CopyButtonState.Copied)
},
() => {
setCopyButtonState(CopyButtonState.Error)
}
)
}, [text])
const defaultToolbar = (
<>
<button
className="btn btn-secondary btn-sm border border-vscode-input-border rounded"
onClick={onCopy}
>
{copyButtonState}
</button>
<button
className="btn btn-secondary btn-sm border border-vscode-input-border rounded"
onClick={async () => {
getVSCodeAPI().postMessage({ type: "applyCode", code: text })
}}
>
Apply
</button>
</>
)
return (
<div className="relative group">
{!hideToolbar && (
<div className="absolute top-0 right-0 invisible group-hover:visible">
<div className="flex space-x-2 p-2">{toolbar || defaultToolbar}</div>
</div>
)}
<div
className={classNames(
"overflow-x-auto rounded-sm text-vscode-editor-fg bg-vscode-editor-bg",
!hideToolbar && "rounded-tl-none",
className
)}
>
<pre className="p-2">{text}</pre>
</div>
</div>
)
}
export default BlockCode

View file

@ -1,164 +0,0 @@
import React, { JSX, useState } from "react"
import { MarkedToken, Token, TokensList } from "marked"
import { awaitVSCodeResponse, getVSCodeAPI } from "../getVscodeApi"
import BlockCode from "./BlockCode"
const Render = ({ token }: { token: Token }) => {
// deal with built-in tokens first (assume marked token)
const t = token as MarkedToken
if (t.type === "space") {
return <span>{t.raw}</span>
}
if (t.type === "code") {
return <BlockCode text={t.text} />
}
if (t.type === "heading") {
const HeadingTag = `h${t.depth}` as keyof JSX.IntrinsicElements
return <HeadingTag>{t.text}</HeadingTag>
}
if (t.type === "table") {
return (
<table>
<thead>
<tr>
{t.header.map((cell: any, index: number) => (
<th key={index} style={{ textAlign: t.align[index] || "left" }}>
{cell.raw}
</th>
))}
</tr>
</thead>
<tbody>
{t.rows.map((row: any[], rowIndex: number) => (
<tr key={rowIndex}>
{row.map((cell: any, cellIndex: number) => (
<td
key={cellIndex}
style={{ textAlign: t.align[cellIndex] || "left" }}
>
{cell.raw}
</td>
))}
</tr>
))}
</tbody>
</table>
)
}
if (t.type === "hr") {
return <hr />
}
if (t.type === "blockquote") {
return <blockquote>{t.text}</blockquote>
}
if (t.type === "list") {
const ListTag = t.ordered ? "ol" : "ul"
return (
<ListTag
start={t.start !== "" ? t.start : undefined}
className={`list-inside ${t.ordered ? "list-decimal" : "list-disc"}`}
>
{t.items.map((item, index) => (
<li key={index}>
{item.task && (
<input type="checkbox" checked={item.checked} readOnly />
)}
{item.text}
</li>
))}
</ListTag>
)
}
if (t.type === "paragraph") {
return (
<p>
{t.tokens.map((token, index) => (
<Render key={index} token={token} />
))}
</p>
)
}
if (t.type === "html") {
return (
<pre>
{`<html>`}
{t.raw}
{`</html>`}
</pre>
)
}
if (t.type === "text" || t.type === "escape") {
return <span>{t.raw}</span>
}
if (t.type === "def") {
return null // Definitions are typically not rendered
}
if (t.type === "link") {
return (
<a href={t.href} title={t.title ?? undefined}>
{t.text}
</a>
)
}
if (t.type === "image") {
return <img src={t.href} alt={t.text} title={t.title ?? undefined} />
}
if (t.type === "strong") {
return <strong>{t.text}</strong>
}
if (t.type === "em") {
return <em>{t.text}</em>
}
// inline code
if (t.type === "codespan") {
return (
<code className="text-vscode-editor-fg bg-vscode-editor-bg px-1 rounded-sm font-mono">
{t.text}
</code>
)
}
if (t.type === "br") {
return <br />
}
if (t.type === "del") {
return <del>{t.text}</del>
}
// default
return (
<div className="bg-orange-50 rounded-sm overflow-hidden">
<span className="text-xs text-orange-500">Unknown type:</span>
{t.raw}
</div>
)
}
const MarkdownRender = ({ tokens }: { tokens: TokensList }) => {
return (
<>
{tokens.map((token, index) => (
<Render key={index} token={token} />
))}
</>
)
}
export default MarkdownRender

View file

@ -1,2 +0,0 @@
export { default as MarkdownRender } from "./MarkdownRender"
export { default as BlockCode } from "./BlockCode"

View file

@ -1,5 +1,6 @@
import React, { useCallback, useEffect, useState } from "react"
import React, { ReactNode, useCallback, useEffect, useState } from "react"
import { getVSCodeAPI } from "../getVscodeApi"
import { classNames } from "../utils"
enum CopyButtonState {
Copy = "Copy",
@ -12,10 +13,14 @@ const COPY_FEEDBACK_TIMEOUT = 1000
// code block with toolbar (Apply, Copy, etc) at top
const BlockCode = ({
text,
toolbar,
hideToolbar = false,
className,
}: {
text: string
toolbar?: ReactNode
hideToolbar?: boolean
className?: string
}) => {
const [copyButtonState, setCopyButtonState] = useState(CopyButtonState.Copy)
@ -38,32 +43,40 @@ const BlockCode = ({
)
}, [text])
const defaultToolbar = (
<>
<button
className="btn btn-secondary btn-sm border border-vscode-input-border rounded"
onClick={onCopy}
>
{copyButtonState}
</button>
<button
className="btn btn-secondary btn-sm border border-vscode-input-border rounded"
onClick={async () => {
getVSCodeAPI().postMessage({ type: "applyCode", code: text })
}}
>
Apply
</button>
</>
)
return (
<div className="relative group">
{!hideToolbar && (
<div className="absolute top-0 right-0 invisible group-hover:visible">
<div className="flex space-x-2 p-2">
<button
className="btn btn-secondary btn-sm border border-vscode-input-border rounded"
onClick={onCopy}
>
{copyButtonState}
</button>
<button
className="btn btn-secondary btn-sm border border-vscode-input-border rounded"
onClick={async () => {
getVSCodeAPI().postMessage({ type: "applyCode", code: text })
}}
>
Apply
</button>
</div>
<div className="flex space-x-2 p-2">{toolbar || defaultToolbar}</div>
</div>
)}
<div
className={`overflow-x-auto rounded-sm text-vscode-editor-fg bg-vscode-editor-bg ${hideToolbar ? "" : "rounded-tl-none"}`}
className={classNames(
"overflow-x-auto rounded-sm text-vscode-editor-fg bg-vscode-editor-bg",
!hideToolbar && "rounded-tl-none",
className
)}
>
<pre className="p-4">{text}</pre>
<pre className="p-2">{text}</pre>
</div>
</div>
)