Diff
ViteHub provides Vue lifecycle adapters for Pierre's six code and diff views. They use Nuxt UI backgrounds, borders, radius, typography, and semantic colors by default while Pierre continues to own parsing, syntax highlighting, selection, and rendering.
<script setup lang="ts">
import { getSingularPatch, type CodeViewItem } from "@vite-hub/ui";
import { ref } from "vue";
const patch = `diff --git a/src/status.ts b/src/status.ts
index 0f62a11..12b7409 100644
--- a/src/status.ts
+++ b/src/status.ts
@@ -1,3 +1,4 @@
export function statusLabel(running: boolean) {
- return running ? 'Running' : 'Done'
+ if (running) return 'Working'
+ return 'Completed'
}`;
const oldFile = {
contents: "export const status = 'running'\n",
name: "src/status.ts",
};
const newFile = {
contents: "export const status = 'completed'\n",
name: "src/status.ts",
};
const conflictStart = "<".repeat(7);
const conflictSeparator = "=".repeat(7);
const conflictEnd = ">".repeat(7);
const unresolvedFile = {
contents: `${conflictStart} current
export const status = 'running'
${conflictSeparator}
export const status = 'completed'
${conflictEnd} incoming
`,
name: "src/status.ts",
};
const fileDiff = getSingularPatch(patch);
const codeViewItems: CodeViewItem[] = [
{ file: newFile, id: "file", type: "file" },
{ fileDiff, id: "diff", type: "diff" },
];
const views = ["CodeView", "MultiFileDiff", "PatchDiff", "FileDiff", "File", "UnresolvedFile"] as const;
const activeView = ref<(typeof views)[number]>("PatchDiff");
</script>
<template>
<div class="min-w-0">
<div class="mb-3 flex gap-1 overflow-x-auto rounded-md border border-default bg-muted p-1">
<UButton
v-for="view in views"
:key="view"
:label="view"
color="neutral"
size="xs"
:variant="activeView === view ? 'solid' : 'ghost'"
@click="activeView = view"
/>
</div>
<AgentCodeView
v-if="activeView === 'CodeView'"
class="h-80"
:items="codeViewItems"
/>
<AgentMultiFileDiff
v-else-if="activeView === 'MultiFileDiff'"
:new-file="newFile"
:old-file="oldFile"
/>
<AgentPatchDiff
v-else-if="activeView === 'PatchDiff'"
:patch="patch"
/>
<AgentFileDiff
v-else-if="activeView === 'FileDiff'"
:file-diff="fileDiff"
/>
<AgentFile
v-else-if="activeView === 'File'"
:file="newFile"
/>
<AgentUnresolvedFile
v-else
:file="unresolvedFile"
/>
</div>
</template>
Components
| Component | Purpose |
|---|---|
AgentCodeView | Render a virtualized list containing files and diffs. |
AgentMultiFileDiff | Compare two FileContents values directly. |
AgentPatchDiff | Render one file change from a unified patch string. |
AgentFileDiff | Render pre-parsed FileDiffMetadata. |
AgentFile | Render one syntax-highlighted file without a diff. |
AgentUnresolvedFile | Render conflict markers with resolution controls. |
Nuxt registers every component automatically. In Vue with Vite, import them from @vite-hub/ui.
Usage
Render a unified patch:
<AgentPatchDiff :patch="patch" />
Compare two files without creating a patch first:
<AgentMultiFileDiff :old-file="before" :new-file="after" />
Pass null for the missing side of an added or deleted file.
Use a parsed diff when the application already owns parsing or partial diff hydration:
<AgentFileDiff :file-diff="fileDiff" />
Render a mixed virtualized view. Give the component a height so it can own scrolling:
<AgentCodeView class="h-[32rem]" :items="items" />
Shared diff props
AgentMultiFileDiff, AgentPatchDiff, and AgentFileDiff share these props:
| Prop | Type | Purpose |
|---|---|---|
options | FileDiffOptions | Configure layout, themes, headers, interactions, and hydration. |
lineAnnotations | DiffLineAnnotation[] | Render application-owned content on diff lines. |
selectedLines | SelectedLineRange | null | Control the selected line range. |
AgentFile uses FileOptions and LineAnnotation[]. AgentUnresolvedFile uses UnresolvedFileOptions. AgentCodeView accepts CodeViewItem[], CodeViewOptions, and a CodeViewLineSelection.
The package also exports Pierre's getSingularPatch, parseDiffFromFile, and parsePatchFiles helpers plus the public types used by these components.
Styling
The default theme maps Pierre's inherited CSS properties to Nuxt UI's --ui-* properties. Override a ViteHub property on one view when a product needs a different treatment:
.review-diff {
--vh-ui-bg: var(--ui-bg-elevated);
--vh-ui-success: var(--ui-primary);
}
Pass Pierre's theme option when you need different syntax token colors. The surrounding backgrounds and semantic diff colors still follow the application theme.