Skip to content
NewService Map: 30 components for hosts, ports and routes
<hf-diff>Custom elementAgentFree

Diff review

Unified diff reviewer with dithered add and remove tints and a minimap; accepting or rejecting a hunk dissolves the dropped lines.

View as Markdown
<hf-diff>

Tryaccept one hunk and reject the other.

Installation

pnpm dlx shadcn@latest add @lumesec/hf-diff
First timeRegister the @lumesec registry once, or install by URL+

Adds @lumesec to your components.json:

pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json

Or skip the setup and install by URL:

npx shadcn@latest add https://elements.lumesec.ai/r/hf-diff.json

Usage

import { HfDiff } from "@/components/lumesec/hf-diff";

export function Example() {
  return (
    <HfDiff>
      {`--- a/src/auth/session.ts
+++ b/src/auth/session.ts
@@ -12,7 +12,9 @@ export async function refresh(session) {
-  return login();
+  return rotate(token);`}
    </HfDiff>
  );
}

Behaviour

Takes a unified diff as its text content. Added and removed lines get dithered tints and a minimap on the right; accepting a hunk dissolves the dropped lines to the right.

API reference

Events

Events bubble and cross the shadow boundary unless the description says otherwise.

resolveReact proponResolveDetail{ hunk: number, accepted: boolean }

Fires when a hunk is accepted or rejected. hunk is its zero-based index. Accept all fires once per open hunk.

Methods

Call them on the element, for example through a React ref.

resolve(index: number, accept: boolean)

Accepts or rejects a hunk by index, as its buttons do. Ignored if the hunk is already resolved.

Accessibility

  • The code area has role="table", and each hunk header and line has role="row"; there are no cell roles.
  • Each hunk has native Accept and Reject buttons; the button names repeat for every hunk.
  • Resolved hunk headers read ✓ Accepted · … or ✕ Rejected · …. The added and removed counters are not a live region.
  • Line tints and the minimap are drawn on an aria-hidden canvas; the + and − markers remain in the text.
  • Reduced motion: dropped lines collapse without the dissolve particles and the counters change without rolling.

Theming

The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from --lumesec. See Theming.

This component reads --border, --card, --destructive, --foreground, --lumesec, --lumesec-success, --muted and --muted-foreground.

To restyle only LumeSec elements, set the matching --ui-* overrides: --ui-accent, --ui-border, --ui-danger, --ui-fg, --ui-mono, --ui-muted, --ui-ok, --ui-raised and --ui-surface.

Notes

  • Pass a unified diff as the element's text content. It is read once on connect; without text a built-in sample diff is shown.
  • One file per element: the header shows the last +++ path with b/ removed, and hunks start at @@ -a,b +c,d @@ lines. Line numbers count from the hunk headers.
  • In React, pass the diff as a string expression such as {diff} so line breaks survive; plain JSX text collapses newlines and the diff does not parse.
  • Accept all accepts every open hunk. The code area scrolls horizontally for long lines; hunk headers with their buttons, the tints and the minimap stay in view.

Was this page helpful?