Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { For, Show, createMemo, onCleanup, onMount, type Component } from "solid-js"
import { For, Show, createEffect, createMemo, onCleanup, onMount, type Component } from "solid-js"
import { createStore } from "solid-js/store"
import { Button } from "@opencode-ai/ui/button"
import { DockPrompt } from "@opencode-ai/ui/dock-prompt"
Expand All @@ -20,6 +20,8 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
answers: [] as QuestionAnswer[],
custom: [] as string[],
customOn: [] as boolean[],
expanded: {} as Record<string, boolean>,
clipped: {} as Record<string, boolean>,
editing: false,
sending: false,
})
Expand Down Expand Up @@ -81,13 +83,35 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
root.style.setProperty("--question-prompt-max-height", `${max}px`)
}

const clip = () => {
if (!root) return

root.querySelectorAll(`[data-slot="option-description"][data-tab="${store.tab}"]`).forEach((item) => {
if (!(item instanceof HTMLElement)) return
if (item.dataset.expanded === "true") return
if (!item.dataset.opt) return
const opt = Number(item.dataset.opt)
if (Number.isNaN(opt)) return
const key = `${store.tab}:${opt}`
setStore("clipped", key, item.scrollWidth > item.clientWidth + 1)
// if content width is bigger than visible width, it is clipped/truncated.
})
}

createEffect(() => {
store.tab
options()
requestAnimationFrame(() => clip())
})

onMount(() => {
let raf: number | undefined
const update = () => {
if (raf !== undefined) cancelAnimationFrame(raf)
raf = requestAnimationFrame(() => {
raf = undefined
measure()
clip()
})
}

Expand Down Expand Up @@ -203,6 +227,15 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
pick(opt.label)
}

const expand = (event: MouseEvent, opt: number) => {
event.preventDefault()
event.stopPropagation()
if (store.sending) return
const key = `${store.tab}:${opt}`
setStore("expanded", key, (value) => !value)
requestAnimationFrame(() => clip())
}

const commitCustom = () => {
setStore("editing", false)
customUpdate(input())
Expand Down Expand Up @@ -287,6 +320,10 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
<For each={options()}>
{(opt, i) => {
const picked = () => store.answers[store.tab]?.includes(opt.label) ?? false
const text = opt.description?.trim() ?? ""
const key = () => `${store.tab}:${i()}`
const opened = () => store.expanded[key()] === true
const clipped = () => store.clipped[key()] === true
return (
<button
data-slot="question-option"
Expand All @@ -309,8 +346,23 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
</span>
<span data-slot="question-option-main">
<span data-slot="option-label">{opt.label}</span>
<Show when={opt.description}>
<span data-slot="option-description">{opt.description}</span>
<Show when={text}>
<span data-slot="option-description" data-expanded={opened()} data-tab={store.tab} data-opt={i()}>
{text}
</span>
<Show when={clipped() || opened()}>
<span
data-slot="option-description-toggle"
data-expanded={opened()}
onMouseDown={(e) => {
e.preventDefault()
e.stopPropagation()
}}
onClick={(e) => expand(e, i())}
>
{opened() ? language.t("ui.question.readLess") : language.t("ui.question.readMore")}
</span>
</Show>
</Show>
</span>
</button>
Expand Down
22 changes: 22 additions & 0 deletions packages/ui/src/components/message-part.css
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,28 @@
white-space: nowrap;
}

[data-slot="option-description"][data-expanded="true"] {
overflow: visible;
text-overflow: clip;
white-space: normal;
overflow-wrap: anywhere;
}

[data-slot="option-description-toggle"] {
font-family: var(--font-family-sans);
font-size: 12px;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large);
color: var(--text-interactive-base);
cursor: pointer;
width: fit-content;
user-select: none;

&:hover {
text-decoration: underline;
}
}

[data-slot="question-option"][data-custom="true"] {
[data-slot="option-description"] {
overflow: visible;
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,6 @@ export const dict = {
"ui.question.multiHint": "حدد كل ما ينطبق",
"ui.question.singleHint": "حدد إجابة واحدة",
"ui.question.custom.placeholder": "اكتب إجابتك...",
"ui.question.readMore": "اقرأ المزيد",
"ui.question.readLess": "اقرأ أقل",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,6 @@ export const dict = {
"ui.question.multiHint": "Selecione todas que se aplicam",
"ui.question.singleHint": "Selecione uma resposta",
"ui.question.custom.placeholder": "Digite sua resposta...",
"ui.question.readMore": "Ler mais",
"ui.question.readLess": "Ler menos",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/bs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,6 @@ export const dict = {
"ui.question.multiHint": "Odaberi sve što važi",
"ui.question.singleHint": "Odaberi jedan odgovor",
"ui.question.custom.placeholder": "Unesi svoj odgovor...",
"ui.question.readMore": "Pročitaj više",
"ui.question.readLess": "Pročitaj manje",
} satisfies Partial<Record<Keys, string>>
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ export const dict = {
"ui.question.multiHint": "Vælg alle der gælder",
"ui.question.singleHint": "Vælg ét svar",
"ui.question.custom.placeholder": "Skriv dit svar...",
"ui.question.readMore": "Læs mere",
"ui.question.readLess": "Læs mindre",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,6 @@ export const dict = {
"ui.question.multiHint": "Alle zutreffenden auswählen",
"ui.question.singleHint": "Eine Antwort auswählen",
"ui.question.custom.placeholder": "Geben Sie Ihre Antwort ein...",
"ui.question.readMore": "Mehr lesen",
"ui.question.readLess": "Weniger lesen",
} satisfies Partial<Record<Keys, string>>
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,6 @@ export const dict = {
"ui.question.multiHint": "Select all answers that apply",
"ui.question.singleHint": "Select one answer",
"ui.question.custom.placeholder": "Type your answer...",
"ui.question.readMore": "Read more",
"ui.question.readLess": "Read less",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,6 @@ export const dict = {
"ui.question.multiHint": "Selecciona todas las que correspondan",
"ui.question.singleHint": "Selecciona una respuesta",
"ui.question.custom.placeholder": "Escribe tu respuesta...",
"ui.question.readMore": "Leer más",
"ui.question.readLess": "Leer menos",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,6 @@ export const dict = {
"ui.question.multiHint": "Sélectionnez tout ce qui s'applique",
"ui.question.singleHint": "Sélectionnez une réponse",
"ui.question.custom.placeholder": "Tapez votre réponse...",
"ui.question.readMore": "Lire plus",
"ui.question.readLess": "Lire moins",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ export const dict = {
"ui.question.multiHint": "該当するものをすべて選択",
"ui.question.singleHint": "1 つ選択",
"ui.question.custom.placeholder": "回答を入力...",
"ui.question.readMore": "続きを読む",
"ui.question.readLess": "表示を減らす",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,6 @@ export const dict = {
"ui.question.multiHint": "해당하는 항목 모두 선택",
"ui.question.singleHint": "하나의 답변을 선택",
"ui.question.custom.placeholder": "답변 입력...",
"ui.question.readMore": "더 보기",
"ui.question.readLess": "접기",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/no.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,6 @@ export const dict: Record<Keys, string> = {
"ui.question.multiHint": "Velg alle som gjelder",
"ui.question.singleHint": "Velg ett svar",
"ui.question.custom.placeholder": "Skriv svaret ditt...",
"ui.question.readMore": "Les mer",
"ui.question.readLess": "Les mindre",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ export const dict = {
"ui.question.multiHint": "Zaznacz wszystkie pasujące",
"ui.question.singleHint": "Wybierz jedną odpowiedź",
"ui.question.custom.placeholder": "Wpisz swoją odpowiedź...",
"ui.question.readMore": "Czytaj więcej",
"ui.question.readLess": "Czytaj mniej",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ export const dict = {
"ui.question.multiHint": "Выберите все подходящие",
"ui.question.singleHint": "Выберите один ответ",
"ui.question.custom.placeholder": "Введите ваш ответ...",
"ui.question.readMore": "Читать дальше",
"ui.question.readLess": "Читать меньше",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/th.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,6 @@ export const dict = {
"ui.question.multiHint": "เลือกทั้งหมดที่ใช้",
"ui.question.singleHint": "เลือกหนึ่งคำตอบ",
"ui.question.custom.placeholder": "พิมพ์คำตอบของคุณ...",
"ui.question.readMore": "อ่านเพิ่มเติม",
"ui.question.readLess": "อ่านน้อยลง",
}
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,6 @@ export const dict = {
"ui.question.multiHint": "可多选",
"ui.question.singleHint": "选择一个答案",
"ui.question.custom.placeholder": "输入你的答案...",
"ui.question.readMore": "阅读更多",
"ui.question.readLess": "阅读更少",
} satisfies Partial<Record<Keys, string>>
2 changes: 2 additions & 0 deletions packages/ui/src/i18n/zht.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,6 @@ export const dict = {
"ui.question.multiHint": "可多選",
"ui.question.singleHint": "選擇一個答案",
"ui.question.custom.placeholder": "輸入你的答案...",
"ui.question.readMore": "閱讀更多",
"ui.question.readLess": "閱讀更少",
} satisfies Partial<Record<Keys, string>>
Loading