diff --git a/packages/web/src/components/Share.tsx b/packages/web/src/components/Share.tsx index ff2d4e82..3d392d88 100644 --- a/packages/web/src/components/Share.tsx +++ b/packages/web/src/components/Share.tsx @@ -172,13 +172,29 @@ function flattenToolArgs(obj: any, prefix: string = ""): Array<[string, any]> { return entries } -export function getDiagnostics( +function formatErrorString(error: string): JSX.Element { + const errorMarker = "Error: " + const startsWithError = error.startsWith(errorMarker) + + return startsWithError ? ( +

+ + Error + + {error.slice(errorMarker.length)} +

+ ) : ( +

{error}

+ ) +} + +function getDiagnostics( diagnosticsByFile: Record, currentFile: string -): string[] { +): JSX.Element[] { // Return a flat array of error diagnostics, in the format: - // "ERROR [65:20] Property 'x' does not exist on type 'Y'" - const result: string[] = [] + // "Error [65:20] Property 'x' does not exist on type 'Y'" + const result: JSX.Element[] = [] if ( diagnosticsByFile === undefined || diagnosticsByFile[currentFile] === undefined @@ -192,7 +208,15 @@ export function getDiagnostics( const line = d.range.start.line + 1 // 1-based const column = d.range.start.character + 1 // 1-based - result.push(`\x1b[31mERROR\x1b[0m \x1b[2m[${line}:${column}]\x1b[0m ${d.message}`) + result.push( +

+ Error + + [{line}:{column}] + + {d.message} +

+ ) } } @@ -324,46 +348,44 @@ function TextPart(props: TextPartProps) { ) } -interface LspPartProps extends JSX.HTMLAttributes { - text: string +interface ErrorPartProps extends JSX.HTMLAttributes { expand?: boolean } -function LspPart(props: LspPartProps) { - const [local, rest] = splitProps(props, ["text", "expand"]) +function ErrorPart(props: ErrorPartProps) { + const [local, rest] = splitProps(props, ["expand", "children"]) const [expanded, setExpanded] = createSignal(false) const [overflowed, setOverflowed] = createSignal(false) let preEl: HTMLElement | undefined function checkOverflow() { - if (!preEl) return - - const code = preEl.getElementsByTagName("code")[0] - - if (code && !local.expand) { - setOverflowed(preEl.clientHeight < code.offsetHeight) + if (preEl && !local.expand) { + setOverflowed(preEl.scrollHeight > preEl.clientHeight + 1) } } onMount(() => { + checkOverflow() window.addEventListener("resize", checkOverflow) }) + createEffect(() => { + local.children + setTimeout(checkOverflow, 0) + }) + onCleanup(() => { window.removeEventListener("resize", checkOverflow) }) return (
- (preEl = el)} - /> +
(preEl = el)}> + {local.children} +
{((!local.expand && overflowed()) || expanded()) && (
0}> - + {diagnostics()}
- + + {formatErrorString(toolData()?.result)} +
@@ -1429,12 +1445,9 @@ export default function Share(props: {
- + + {formatErrorString(message())} +
@@ -1448,9 +1461,7 @@ export default function Share(props: {
0}> - + {diagnostics()} @@ -1601,12 +1612,9 @@ export default function Share(props: {
- + + {formatErrorString(toolData()?.result)} +
diff --git a/packages/web/src/components/share.module.css b/packages/web/src/components/share.module.css index bcac0054..b216dbaf 100644 --- a/packages/web/src/components/share.module.css +++ b/packages/web/src/components/share.module.css @@ -421,7 +421,7 @@ } } -.message-lsp { +.message-error { background-color: var(--sl-color-bg-surface); padding: 0.5rem calc(0.5rem + 3px); border-radius: 0.25rem; @@ -432,24 +432,47 @@ align-self: flex-start; max-width: var(--md-tool-width); - padding: 0.5rem calc(0.5rem + 3px); - - pre { - --shiki-dark-bg: var(--sl-color-bg-surface) !important; - background-color: var(--sl-color-bg-surface) !important; - line-height: 1.4; + [data-section="content"] { + p { + margin-bottom: 0.5rem; + line-height: 1.5; font-size: 0.75rem; white-space: pre-wrap; word-break: break-word; + + &:last-child { + margin-bottom: 0; + } + + span { + margin-right: 0.25rem; + &:last-child { + margin-right: 0; + } + } + span[data-color="red"] { + color: var(--sl-color-red); + } + span[data-color="dimmed"] { + color: var(--sl-color-text-dimmed); + } + span[data-marker="label"] { + text-transform: uppercase; + letter-spacing: -0.5px; + } + span[data-separator] { + margin-right: 0.375rem; + } } + } &[data-expanded="true"] { - pre { + [data-section="content"] { display: block; } } &[data-expanded="false"] { - pre { + [data-section="content"] { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 7;