diff --git a/packages/tui/src/feature-plugins/system/diff-viewer-file-tree.tsx b/packages/tui/src/feature-plugins/system/diff-viewer-file-tree.tsx index 53bea203fddb..2a34f7375547 100644 --- a/packages/tui/src/feature-plugins/system/diff-viewer-file-tree.tsx +++ b/packages/tui/src/feature-plugins/system/diff-viewer-file-tree.tsx @@ -1,31 +1,19 @@ /** @jsxImportSource @opentui/solid */ -import type { ColorInput, RGBA, ScrollBoxRenderable } from "@opentui/core" +import type { ScrollBoxRenderable } from "@opentui/core" import { Locale } from "../../util/locale" import { tint } from "../../theme/color" import { createEffect, createMemo, For, Match, Switch } from "solid-js" import { buildFileTree, flattenFileTree, type FileTreeItem, type FileTreeRow } from "./diff-viewer-file-tree-utils" import { Panel } from "./diff-viewer-ui" +import { useTheme } from "../../context/theme" const FILE_TREE_STATUS_WIDTH = 2 -export type DiffViewerFileTreeTheme = { - readonly background: RGBA - readonly backgroundPanel: ColorInput - readonly backgroundElement: ColorInput - readonly primary: ColorInput - readonly secondary: ColorInput - readonly selectedListItemText: ColorInput - readonly text: RGBA - readonly textMuted: RGBA - readonly error: ColorInput -} - export type DiffViewerFileTreeProps = { readonly width: number readonly files: readonly FileTreeItem[] readonly loading: boolean readonly error: unknown - readonly theme: DiffViewerFileTreeTheme readonly focused?: boolean readonly highlightedNode?: number readonly selectedFileIndex?: number @@ -35,6 +23,7 @@ export type DiffViewerFileTreeProps = { } export function DiffViewerFileTree(props: DiffViewerFileTreeProps) { + const { themeV2 } = useTheme() const tree = createMemo(() => buildFileTree(props.files)) const rows = createMemo(() => flattenFileTree(tree(), props.expandedNodes)) let scroll: ScrollBoxRenderable | undefined @@ -49,7 +38,7 @@ export function DiffViewerFileTree(props: DiffViewerFileTreeProps) { requestAnimationFrame(scrollSelectedIntoView) }) - const fadedColor = () => tint(props.theme.text, props.theme.background, 0.75) + const fadedColor = () => tint(themeV2.text.default, themeV2.background.default, 0.75) return ( @@ -63,7 +52,7 @@ export function DiffViewerFileTree(props: DiffViewerFileTreeProps) { - No files + No files 0}> @@ -82,22 +71,26 @@ export function DiffViewerFileTree(props: DiffViewerFileTreeProps) { props.onRowClick?.(row)} > - + {prefix()} @@ -105,7 +98,7 @@ export function DiffViewerFileTree(props: DiffViewerFileTreeProps) { diff --git a/packages/tui/src/feature-plugins/system/diff-viewer.tsx b/packages/tui/src/feature-plugins/system/diff-viewer.tsx index cf69650202c8..380a5035bdab 100644 --- a/packages/tui/src/feature-plugins/system/diff-viewer.tsx +++ b/packages/tui/src/feature-plugins/system/diff-viewer.tsx @@ -85,7 +85,7 @@ function DiffViewer(props: { context: Plugin.Context }) { const config = useConfig() const dialog = useDialog() const themeState = useTheme() - const theme = () => themeState.theme + const themeV2 = themeState.themeV2 const params = () => { const route = props.context.ui.router.current() return (route.type === "plugin" ? route.data : undefined) as @@ -741,11 +741,11 @@ function DiffViewer(props: { context: Plugin.Context }) { - Diff - {diffSourceLabel(mode())} + Diff + {diffSourceLabel(mode())} - + {files().length} {files().length === 1 ? "file" : "files"} @@ -756,19 +756,21 @@ function DiffViewer(props: { context: Plugin.Context }) { - Loading diff… + Loading diff… - Could not load diff. Reopen the diff viewer to try again. + + Could not load diff. Reopen the diff viewer to try again. + - No changes to show + No changes to show @@ -778,7 +780,6 @@ function DiffViewer(props: { context: Plugin.Context }) { files={files()} loading={diff.loading} error={diff.error} - theme={theme()} focused={focus() === "files"} width={FILE_TREE_WIDTH} highlightedNode={highlightedFileNode()} @@ -812,24 +813,26 @@ function DiffViewer(props: { context: Plugin.Context }) { paddingLeft={1} paddingRight={1} border={patchLeftBorder()} - borderColor={theme().border} + borderColor={themeV2.border.default} > - {entry.file.file} + + {entry.file.file} + - + +{entry.file.additions} - + -{entry.file.deletions} No patch available for this file.} + fallback={No patch available for this file.} > {(patch) => ( - + diffNodeByFileIndex.set(entry.fileIndex, element)} diff={patch()} @@ -839,17 +842,27 @@ function DiffViewer(props: { context: Plugin.Context }) { showLineNumbers={true} width="100%" wrapMode="char" - fg={reviewed() ? theme().textMuted : theme().text} - addedBg={reviewed() ? theme().backgroundElement : theme().diffAddedBg} - removedBg={reviewed() ? theme().backgroundElement : theme().diffRemovedBg} - addedSignColor={reviewed() ? theme().textMuted : theme().diffHighlightAdded} - removedSignColor={reviewed() ? theme().textMuted : theme().diffHighlightRemoved} - lineNumberFg={theme().diffLineNumber} + fg={reviewed() ? themeV2.text.subdued : themeV2.text.default} + addedBg={ + reviewed() ? themeV2.background.surface.overlay : themeV2.diff.background.added + } + removedBg={ + reviewed() ? themeV2.background.surface.overlay : themeV2.diff.background.removed + } + addedSignColor={reviewed() ? themeV2.text.subdued : themeV2.diff.highlight.added} + removedSignColor={ + reviewed() ? themeV2.text.subdued : themeV2.diff.highlight.removed + } + lineNumberFg={themeV2.diff.lineNumber.text} addedLineNumberBg={ - reviewed() ? theme().backgroundElement : theme().diffAddedLineNumberBg + reviewed() + ? themeV2.background.surface.overlay + : themeV2.diff.lineNumber.background.added } removedLineNumberBg={ - reviewed() ? theme().backgroundElement : theme().diffRemovedLineNumberBg + reviewed() + ? themeV2.background.surface.overlay + : themeV2.diff.lineNumber.background.removed } /> @@ -860,7 +873,11 @@ function DiffViewer(props: { context: Plugin.Context }) { }} 0}> - + @@ -873,57 +890,57 @@ function DiffViewer(props: { context: Plugin.Context }) { {(shortcut) => ( - - {shortcut()} focus file tree + + {shortcut()} focus file tree )} {(shortcut) => ( - - {shortcut()} next file + + {shortcut()} next file )} {(shortcut) => ( - - {shortcut()} next hunk + + {shortcut()} next hunk )} {(shortcut) => ( - - {shortcut()} previous hunk + + {shortcut()} previous hunk )} {(shortcut) => ( - - {shortcut()} previous file + + {shortcut()} previous file )} {(shortcut) => ( - - {shortcut()} switch source + + {shortcut()} switch source )} {(shortcut) => ( - - {shortcut()} mark reviewed + + {shortcut()} mark reviewed )} {(shortcut) => ( - - {shortcut()} all + + {shortcut()} all )} @@ -934,7 +951,7 @@ function DiffViewer(props: { context: Plugin.Context }) { } function DiffViewerHelpDialog(props: { context: Plugin.Context }) { - const { theme } = useTheme() + const { themeV2 } = useTheme().contextual("elevated") const shortcut = (id: string) => () => props.context.keymap.shortcut(id) const rows = [ { @@ -1002,30 +1019,30 @@ function DiffViewerHelpDialog(props: { context: Plugin.Context }) { return ( - + Diff shortcuts - esc + esc - + Key - + Action - Description + Description {(row) => ( - + {row.shortcut() || "-"} - + {row.action} - {row.description} + {row.description} )} diff --git a/packages/tui/test/cli/tui/diff-viewer-file-tree.test.tsx b/packages/tui/test/cli/tui/diff-viewer-file-tree.test.tsx index 0eb993f79bfa..68113f65b415 100644 --- a/packages/tui/test/cli/tui/diff-viewer-file-tree.test.tsx +++ b/packages/tui/test/cli/tui/diff-viewer-file-tree.test.tsx @@ -1,6 +1,5 @@ /** @jsxImportSource @opentui/solid */ import { describe, expect, test } from "bun:test" -import { RGBA } from "@opentui/core" import { testRender } from "@opentui/solid" import type { JSX } from "solid-js" import { onMount, type ParentProps } from "solid-js" @@ -14,18 +13,6 @@ import { buildFileTree, } from "../../../src/feature-plugins/system/diff-viewer-file-tree-utils" -const theme = { - background: RGBA.fromHex("#000000"), - backgroundPanel: RGBA.fromHex("#111111"), - backgroundElement: RGBA.fromHex("#333333"), - primary: RGBA.fromHex("#00ffff"), - secondary: RGBA.fromHex("#0088ff"), - selectedListItemText: RGBA.fromHex("#ffffff"), - text: RGBA.fromHex("#ffffff"), - textMuted: RGBA.fromHex("#888888"), - error: RGBA.fromHex("#ff0000"), -} - describe("DiffViewerFileTree", () => { test.skip("renders sorted hierarchical file rows", async () => { const lines = visibleLines( @@ -41,7 +28,6 @@ describe("DiffViewerFileTree", () => { ]} loading={false} error={undefined} - theme={theme} focused={true} /> )), @@ -59,13 +45,13 @@ describe("DiffViewerFileTree", () => { test("keeps loading and error quiet while rendering an empty settled state", async () => { const loading = await renderFrame(() => ( - + )) const failed = await renderFrame(() => ( - + )) const empty = await renderFrame(() => ( - + )) expect(loading).not.toContain("Loading diff...") @@ -86,16 +72,13 @@ describe("DiffViewerFileTree", () => { files={files} loading={false} error={undefined} - theme={theme} focused highlightedNode={src.id} /> )), ) const unfocused = visibleLines( - await renderFrame(() => ( - - )), + await renderFrame(() => ), ) expect(focused).toContain("▾ src/config") @@ -114,14 +97,7 @@ describe("DiffViewerFileTree", () => { expect( visibleLines( await renderFrame(() => ( - + )), ), ).toEqual(["▸ src/config"]) @@ -134,7 +110,6 @@ describe("DiffViewerFileTree", () => { width={32} loading={false} error={undefined} - theme={theme} expandedNodes={allExpandedFileTreeDirectories(tree)} /> )),