mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-16 00:23:23 +00:00
fix(tui): improve selected spinner contrast (#42141)
This commit is contained in:
parent
0859f77153
commit
f6aa1a67f0
4 changed files with 34 additions and 6 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { createMemo, createResource, createSignal } from "solid-js"
|
||||
import type { SessionInfo } from "@opencode-ai/client"
|
||||
import { useTerminalDimensions } from "@opentui/solid"
|
||||
import type { RGBA } from "@opentui/core"
|
||||
import { dialogWidth, useDialog } from "../ui/dialog"
|
||||
import { DialogSelect, dialogSelectContentWidth } from "../ui/dialog-select"
|
||||
import { useRoute } from "../context/route"
|
||||
|
|
@ -105,7 +106,7 @@ export function DialogOpen(props: { sessions: SessionInfo[] }) {
|
|||
footer: `${name ? `${Locale.truncate(name, 20)} · ` : ""}${timeAgo(session.time.updated)}`,
|
||||
onSelect: () => location.set(session.location),
|
||||
gutter: running
|
||||
? () => <Spinner />
|
||||
? (color: RGBA) => <Spinner color={color} />
|
||||
: tabs.has(session.id)
|
||||
? () => <text fg={theme.hue.accent[mode() === "light" ? 800 : 200]}>▪</text>
|
||||
: undefined,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { createMemo, createResource, createSignal, onMount, Show } from "solid-j
|
|||
import path from "path"
|
||||
import type { SessionInfo } from "@opencode-ai/client"
|
||||
import { TextAttributes } from "@opentui/core"
|
||||
import type { RGBA } from "@opentui/core"
|
||||
import { useDialog } from "../ui/dialog"
|
||||
import { DialogSelect } from "../ui/dialog-select"
|
||||
import { useRoute } from "../context/route"
|
||||
|
|
@ -161,7 +162,7 @@ export function DialogSessionList() {
|
|||
gutter:
|
||||
data.session.status(session.id) === "running" ||
|
||||
data.session.family(session.id).some((id) => data.session.status(id) === "running")
|
||||
? () => <Spinner />
|
||||
? (color: RGBA) => <Spinner color={color} />
|
||||
: slot === undefined
|
||||
? undefined
|
||||
: () => <text fg={theme.hue.accent[mode() === "light" ? 800 : 200]}>{slot}</text>,
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ export interface DialogSelectOption<T = any> {
|
|||
disabled?: boolean
|
||||
bg?: RGBA
|
||||
fg?: RGBA
|
||||
gutter?: () => JSX.Element
|
||||
gutter?: (color: RGBA) => JSX.Element
|
||||
margin?: JSX.Element
|
||||
onSelect?: (ctx: DialogContext) => void
|
||||
}
|
||||
|
|
@ -816,7 +816,7 @@ function Option(props: {
|
|||
footerColor?: RGBA
|
||||
titleWidth?: number
|
||||
truncateTitle?: boolean | "left"
|
||||
gutter?: () => JSX.Element
|
||||
gutter?: (color: RGBA) => JSX.Element
|
||||
activeColor?: RGBA
|
||||
onMouseOver?: () => void
|
||||
}) {
|
||||
|
|
@ -837,7 +837,7 @@ function Option(props: {
|
|||
</Show>
|
||||
<Show when={props.gutter}>
|
||||
<box flexShrink={0} marginRight={0}>
|
||||
{props.gutter?.()}
|
||||
{props.gutter?.(text())}
|
||||
</box>
|
||||
</Show>
|
||||
<text
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/** @jsxImportSource @opentui/solid */
|
||||
import { InputRenderable } from "@opentui/core"
|
||||
import { InputRenderable, type RGBA } from "@opentui/core"
|
||||
import { testRender } from "@opentui/solid"
|
||||
import { expect, test } from "bun:test"
|
||||
import { mkdir } from "node:fs/promises"
|
||||
|
|
@ -197,6 +197,32 @@ test("renders actions with a current selection", async () => {
|
|||
}
|
||||
})
|
||||
|
||||
test("passes the row foreground color to gutters", async () => {
|
||||
await using tmp = await tmpdir()
|
||||
const colors = new Map<string, RGBA>()
|
||||
const gutter = (item: string) => (color: RGBA) => {
|
||||
colors.set(item, color)
|
||||
return <text fg={color}>*</text>
|
||||
}
|
||||
const select = await mountSelect(tmp.path, [
|
||||
{ title: "Alpha", value: "alpha", gutter: gutter("alpha") },
|
||||
{ title: "Beta", value: "beta", gutter: gutter("beta") },
|
||||
])
|
||||
|
||||
try {
|
||||
await select.app.waitFor(() => colors.size === 2)
|
||||
const selected = colors.get("alpha")!.toInts()
|
||||
const idle = colors.get("beta")!.toInts()
|
||||
expect(selected).not.toEqual(idle)
|
||||
|
||||
select.app.mockInput.pressArrow("down")
|
||||
await select.app.waitFor(() => colors.get("alpha")!.toInts().every((value, index) => value === idle[index]))
|
||||
expect(colors.get("beta")!.toInts()).toEqual(selected)
|
||||
} finally {
|
||||
select.app.renderer.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test("dialog actions run without options while row actions still require a selection", async () => {
|
||||
await using tmp = await tmpdir()
|
||||
let global = 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue