summaryrefslogtreecommitdiffhomepage
path: root/packages/web
diff options
context:
space:
mode:
authorJay V <[email protected]>2025-07-08 18:00:08 -0400
committerJay V <[email protected]>2025-07-08 18:00:08 -0400
commitf99e2b3429fd04d46250d6c9ca80bccdceaa1eee (patch)
tree64805f625bf00769e754d1b4efdf43fafc97a2dd /packages/web
parent7e4e6f6e51876406a72531687bbbd70c86d05463 (diff)
downloadopencode-f99e2b3429fd04d46250d6c9ca80bccdceaa1eee.tar.gz
opencode-f99e2b3429fd04d46250d6c9ca80bccdceaa1eee.zip
docs: share error part
Diffstat (limited to 'packages/web')
-rw-r--r--packages/web/src/components/share/content-code.module.css1
-rw-r--r--packages/web/src/components/share/content-error.module.css66
-rw-r--r--packages/web/src/components/share/content-error.tsx31
-rw-r--r--packages/web/src/components/share/part.tsx37
4 files changed, 123 insertions, 12 deletions
diff --git a/packages/web/src/components/share/content-code.module.css b/packages/web/src/components/share/content-code.module.css
index b95f936da..9fa105673 100644
--- a/packages/web/src/components/share/content-code.module.css
+++ b/packages/web/src/components/share/content-code.module.css
@@ -13,6 +13,7 @@
pre {
--shiki-dark-bg: var(--sl-color-bg-surface) !important;
+ background-color: var(--sl-color-bg-surface) !important;
line-height: 1.6;
font-size: 0.75rem;
white-space: pre-wrap;
diff --git a/packages/web/src/components/share/content-error.module.css b/packages/web/src/components/share/content-error.module.css
new file mode 100644
index 000000000..70645d6b4
--- /dev/null
+++ b/packages/web/src/components/share/content-error.module.css
@@ -0,0 +1,66 @@
+.root {
+ background-color: var(--sl-color-bg-surface);
+ padding: 0.5rem calc(0.5rem + 3px);
+ border-radius: 0.25rem;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 1rem;
+ align-self: flex-start;
+ max-width: var(--md-tool-width);
+
+ [data-section="content"] {
+ pre {
+ 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"] {
+ [data-section="content"] {
+ display: block;
+ }
+ }
+ &[data-expanded="false"] {
+ [data-section="content"] {
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 7;
+ overflow: hidden;
+ }
+ }
+
+ button {
+ flex: 0 0 auto;
+ padding: 2px 0;
+ font-size: 0.75rem;
+ }
+
+}
diff --git a/packages/web/src/components/share/content-error.tsx b/packages/web/src/components/share/content-error.tsx
new file mode 100644
index 000000000..b6d7023b2
--- /dev/null
+++ b/packages/web/src/components/share/content-error.tsx
@@ -0,0 +1,31 @@
+import style from "./content-error.module.css"
+import { type JSX, createSignal } from "solid-js"
+import { createOverflow } from "./common"
+
+interface Props extends JSX.HTMLAttributes<HTMLDivElement> {
+ expand?: boolean
+}
+export function ContentError(props: Props) {
+ const [expanded, setExpanded] = createSignal(false)
+ const overflow = createOverflow()
+
+ return (
+ <div
+ class={style.root}
+ data-expanded={expanded() || props.expand === true ? true : undefined}
+ >
+ <div data-section="content" ref={overflow.ref}>
+ {props.children}
+ </div>
+ {((!props.expand && overflow.status) || expanded()) && (
+ <button
+ type="button"
+ data-element-button-text
+ onClick={() => setExpanded((e) => !e)}
+ >
+ {expanded() ? "Show less" : "Show more"}
+ </button>
+ )}
+ </div>
+ )
+}
diff --git a/packages/web/src/components/share/part.tsx b/packages/web/src/components/share/part.tsx
index cff9b42b0..6f76660a1 100644
--- a/packages/web/src/components/share/part.tsx
+++ b/packages/web/src/components/share/part.tsx
@@ -1,4 +1,15 @@
-import { For, Show, Match, Switch, type JSX, createMemo, createSignal, type ParentProps } from "solid-js"
+import map from "lang-map"
+import { DateTime } from "luxon"
+import {
+ For,
+ Show,
+ Match,
+ Switch,
+ type JSX,
+ createMemo,
+ createSignal,
+ type ParentProps
+} from "solid-js"
import {
IconHashtag,
IconSparkles,
@@ -17,17 +28,16 @@ import {
IconDocumentMagnifyingGlass,
} from "../icons"
import { IconMeta, IconOpenAI, IconGemini, IconAnthropic } from "../icons/custom"
-import styles from "./part.module.css"
-import type { MessageV2 } from "opencode/session/message-v2"
+import CodeBlock from "../CodeBlock"
+import { ContentCode } from "./content-code"
+import { ContentDiff } from "./content-diff"
import { ContentText } from "./content-text"
+import { ContentError } from "./content-error"
import { ContentMarkdown } from "./content-markdown"
-import { DateTime } from "luxon"
-import CodeBlock from "../CodeBlock"
-import map from "lang-map"
+import type { MessageV2 } from "opencode/session/message-v2"
import type { Diagnostic } from "vscode-languageserver-types"
-import { ContentCode } from "./content-code"
-import { ContentDiff } from "./content-diff"
+import styles from "./part.module.css"
export interface PartProps {
index: number
@@ -439,7 +449,7 @@ export function WebFetchTool(props: ToolProps) {
<div data-component="tool-result">
<Switch>
<Match when={props.state.metadata?.error}>
- <div data-component="error">{formatErrorString(props.state.output)}</div>
+ <ContentError>{formatErrorString(props.state.output)}</ContentError>
</Match>
<Match when={props.state.output}>
<ResultsButton>
@@ -466,7 +476,7 @@ export function ReadTool(props: ToolProps) {
<div data-component="tool-result">
<Switch>
<Match when={props.state.metadata?.error}>
- <div data-component="error">{formatErrorString(props.state.output)}</div>
+ <ContentError>{formatErrorString(props.state.output)}</ContentError>
</Match>
<Match when={typeof props.state.metadata?.preview === "string"}>
<ResultsButton showCopy="Show preview" hideCopy="Hide preview">
@@ -502,7 +512,7 @@ export function WriteTool(props: ToolProps) {
<div data-component="tool-result">
<Switch>
<Match when={props.state.metadata?.error}>
- <div data-component="error">{formatErrorString(props.state.output)}</div>
+ <ContentError>{formatErrorString(props.state.output)}</ContentError>
</Match>
<Match when={props.state.input?.content}>
<ResultsButton showCopy="Show contents" hideCopy="Hide contents">
@@ -530,7 +540,7 @@ export function EditTool(props: ToolProps) {
<div data-component="tool-result">
<Switch>
<Match when={props.state.metadata?.error}>
- <div data-component="error">{formatErrorString(props.state.metadata?.message || "")}</div>
+ <ContentError>{formatErrorString(props.state.metadata?.message || "")}</ContentError>
</Match>
<Match when={props.state.metadata?.diff}>
<div data-component="diff">
@@ -707,6 +717,9 @@ export function ProviderIcon(props: { model: string; size?: number }) {
<Match when={provider === "gemini"}>
<IconGemini width={size} height={size} />
</Match>
+ <Match when={provider === "meta"}>
+ <IconMeta width={size} height={size} />
+ </Match>
</Switch>
)
}