mirror of
https://github.com/sst/opencode.git
synced 2025-07-07 08:05:00 +00:00
docs: share improve markdown rendering of ai responses
This commit is contained in:
parent
06dba28bd6
commit
143fd8e076
6 changed files with 78 additions and 27 deletions
8
bun.lock
8
bun.lock
|
@ -31,7 +31,6 @@
|
|||
"@openauthjs/openauth": "0.4.3",
|
||||
"@standard-schema/spec": "1.0.0",
|
||||
"ai": "catalog:",
|
||||
"air": "0.4.14",
|
||||
"decimal.js": "10.5.0",
|
||||
"diff": "8.0.2",
|
||||
"env-paths": "3.0.0",
|
||||
|
@ -79,6 +78,7 @@
|
|||
"lang-map": "0.4.0",
|
||||
"luxon": "3.6.1",
|
||||
"marked": "15.0.12",
|
||||
"marked-shiki": "1.2.0",
|
||||
"rehype-autolink-headings": "7.1.0",
|
||||
"sharp": "0.32.5",
|
||||
"shiki": "3.4.2",
|
||||
|
@ -517,8 +517,6 @@
|
|||
|
||||
"ai": ["ai@4.3.16", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8", "@ai-sdk/react": "1.2.12", "@ai-sdk/ui-utils": "1.2.11", "@opentelemetry/api": "1.9.0", "jsondiffpatch": "0.6.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.23.8" }, "optionalPeers": ["react"] }, "sha512-KUDwlThJ5tr2Vw0A1ZkbDKNME3wzWhuVfAOwIvFUzl1TPVDFAXDFTXio3p+jaKneB+dKNCvFFlolYmmgHttG1g=="],
|
||||
|
||||
"air": ["air@0.4.14", "", { "dependencies": { "zephyr": "~1.3.5" } }, "sha512-E8bl9LlSGSQqjxxjeGIrpYpf8jVyJplsdK1bTobh61F7ks+3aLeXL4KbGSJIFsiaSSz5ZExLU51DGztmQSlZTQ=="],
|
||||
|
||||
"ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
|
||||
|
||||
"ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
|
||||
|
@ -1055,6 +1053,8 @@
|
|||
|
||||
"marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="],
|
||||
|
||||
"marked-shiki": ["marked-shiki@1.2.0", "", { "peerDependencies": { "marked": ">=7.0.0", "shiki": ">=1.0.0" } }, "sha512-N924hp8veE6Mc91g5/kCNVoTU7TkeJfB2G2XEWb+k1fVA0Bck2T0rVt93d39BlOYH6ohP4Q9BFlPk+UkblhXbg=="],
|
||||
|
||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
||||
"mdast-util-definitions": ["mdast-util-definitions@6.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ=="],
|
||||
|
@ -1703,8 +1703,6 @@
|
|||
|
||||
"youch": ["youch@3.3.4", "", { "dependencies": { "cookie": "^0.7.1", "mustache": "^4.2.0", "stacktracey": "^2.1.8" } }, "sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg=="],
|
||||
|
||||
"zephyr": ["zephyr@1.3.6", "", {}, "sha512-oYH52DGZzIbXNrkijskaR8YpVKnXAe8jNgH1KirglVBnTFOn6mK9/0SVCxGn+73l0Hjhr4UYNzYkO07LXSWy6w=="],
|
||||
|
||||
"zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="],
|
||||
|
||||
"zod-openapi": ["zod-openapi@4.2.4", "", { "peerDependencies": { "zod": "^3.21.4" } }, "sha512-tsrQpbpqFCXqVXUzi3TPwFhuMtLN3oNZobOtYnK6/5VkXsNdnIgyNr4r8no4wmYluaxzN3F7iS+8xCW8BmMQ8g=="],
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"lang-map": "0.4.0",
|
||||
"luxon": "3.6.1",
|
||||
"marked": "15.0.12",
|
||||
"marked-shiki": "1.2.0",
|
||||
"rehype-autolink-headings": "7.1.0",
|
||||
"sharp": "0.32.5",
|
||||
"shiki": "3.4.2",
|
||||
|
|
|
@ -1,21 +1,39 @@
|
|||
import { type JSX, splitProps, createResource } from "solid-js"
|
||||
import { marked } from "marked"
|
||||
import markedShiki from "marked-shiki"
|
||||
import { codeToHtml } from "shiki"
|
||||
import { transformerNotationDiff } from "@shikijs/transformers"
|
||||
import styles from "./markdownview.module.css"
|
||||
|
||||
interface MarkdownViewProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
||||
markdown: string
|
||||
}
|
||||
|
||||
const markedWithShiki = marked.use(
|
||||
markedShiki({
|
||||
highlight(code, lang) {
|
||||
return codeToHtml(code, {
|
||||
lang: lang || "text",
|
||||
themes: {
|
||||
light: "github-light",
|
||||
dark: "github-dark",
|
||||
},
|
||||
transformers: [transformerNotationDiff()],
|
||||
})
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
function MarkdownView(props: MarkdownViewProps) {
|
||||
const [local, rest] = splitProps(props, ["markdown"])
|
||||
const [html] = createResource(() => local.markdown, async (markdown) => {
|
||||
return marked.parse(markdown)
|
||||
})
|
||||
|
||||
return (
|
||||
<div innerHTML={html()} class={styles["markdown-body"]} {...rest} />
|
||||
const [html] = createResource(
|
||||
() => local.markdown,
|
||||
async (markdown) => {
|
||||
return markedWithShiki.parse(markdown)
|
||||
},
|
||||
)
|
||||
|
||||
return <div innerHTML={html()} class={styles["markdown-body"]} {...rest} />
|
||||
}
|
||||
|
||||
export default MarkdownView
|
||||
|
||||
|
|
|
@ -294,15 +294,11 @@ function ResultsButton(props: ResultsButtonProps) {
|
|||
interface TextPartProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
||||
text: string
|
||||
expand?: boolean
|
||||
invert?: boolean
|
||||
highlight?: boolean
|
||||
}
|
||||
function TextPart(props: TextPartProps) {
|
||||
const [local, rest] = splitProps(props, [
|
||||
"text",
|
||||
"expand",
|
||||
"invert",
|
||||
"highlight",
|
||||
])
|
||||
const [expanded, setExpanded] = createSignal(false)
|
||||
const [overflowed, setOverflowed] = createSignal(false)
|
||||
|
@ -332,8 +328,6 @@ function TextPart(props: TextPartProps) {
|
|||
return (
|
||||
<div
|
||||
class={styles["message-text"]}
|
||||
data-invert={local.invert}
|
||||
data-highlight={local.highlight}
|
||||
data-expanded={expanded() || local.expand === true}
|
||||
{...rest}
|
||||
>
|
||||
|
@ -991,9 +985,9 @@ export default function Share(props: {
|
|||
</div>
|
||||
<div data-section="content">
|
||||
<TextPart
|
||||
invert
|
||||
text={part().text}
|
||||
expand={isLastPart()}
|
||||
data-background="blue"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1021,7 +1015,6 @@ export default function Share(props: {
|
|||
</div>
|
||||
<div data-section="content">
|
||||
<MarkdownPart
|
||||
highlight
|
||||
expand={isLastPart()}
|
||||
text={stripEnclosingTag(part().text)}
|
||||
/>
|
||||
|
|
|
@ -40,11 +40,17 @@
|
|||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
border-radius: 0.25rem;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
--shiki-dark-bg: var(--sl-color-bg-surface) !important;
|
||||
background-color: var(--sl-color-bg-surface) !important;
|
||||
padding: 0.5rem 0.75rem;
|
||||
line-height: 1.6;
|
||||
font-size: 0.75rem;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
|
||||
span {
|
||||
white-space: break-spaces;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
|
@ -61,4 +67,40 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid var(--sl-color-border);
|
||||
padding: 0.5rem 0.75rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
border-bottom: 1px solid var(--sl-color-border);
|
||||
}
|
||||
|
||||
/* Remove outer borders */
|
||||
table tr:first-child th,
|
||||
table tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table th:first-child,
|
||||
table td:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
table th:last-child,
|
||||
table td:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -493,9 +493,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
&[data-highlight="true"] {
|
||||
background-color: var(--sl-color-blue-low);
|
||||
}
|
||||
&[data-background="none"] { background-color: transparent; }
|
||||
&[data-background="blue"] { background-color: var(--sl-color-blue-low); }
|
||||
|
||||
&[data-expanded="true"] {
|
||||
pre {
|
||||
|
@ -669,7 +668,7 @@
|
|||
}
|
||||
|
||||
.message-markdown {
|
||||
background-color: var(--sl-color-bg-surface);
|
||||
border: 1px solid var(--sl-color-blue-high);
|
||||
padding: 0.5rem calc(0.5rem + 3px);
|
||||
border-radius: 0.25rem;
|
||||
display: flex;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue