Blocks

File Diff

A unified diff viewer with a file top bar, change counts, and highlighted rows.

Installation

pnpm dlx @mielui/svelte add file-diff

The component depends on highlight.js for syntax highlighting. Install it if your project doesn't have it yet:

pnpm add highlight.js

Usage

The theme setting chrome.borders chooses single framing, the default, or double framing. The filename and change counts always stay above the diff.

Pass a diff array for the high-level form, or compose TopBar, Content, and Row by hand. A bare TopBar renders the filename and counts; pass children to take over the row with Filename, PlusMinus, and your own actions. Counts are derived from the diff unless you pass additions and deletions.

Code Block and File Diff share the same language aliases, syntax rules, package-manager command highlighting, and escaped fallback for unsupported languages.

Each row announces whether its code was added, removed, or unchanged. When line numbers are shown, the announcement includes the relevant source line.

<script lang="ts">
    import type { FileDiffLine } from '@mielui/svelte/components/file-diff';
    import * as FileDiff from '@mielui/svelte/components/file-diff';

    const diff: FileDiffLine[] = [
        {
            type: 'remove',
            oldLineNumber: 13,
            content: '  return localStorage.token;'
        },
        {
            type: 'add',
            newLineNumber: 13,
            content: '  return cookies.get("session");'
        }
    ];
</script>

<FileDiff.Root file="src/auth.ts" lang="ts" {diff} />

Examples

Changing a diff

Replace the diff array when a new patch arrives. The filename, highlighted rows, and derived counts update from Root. Explicit additions and deletions continue to override the calculated counts until you remove those props.

Compound API

Drop down to rows when you need a custom top-bar action or explicit counts. Recompose the header from Filename and PlusMinus parts.

Without line numbers

Hide both gutters for compact embeds. The sign column stays so additions and deletions remain distinguishable without color.

Stacked files

Render one Root per file for pull-request style views. Each diff keeps its own language and counts.

Labels

Built-in text is English. Pass a labels object to Root to translate the change type and line number that screen readers announce on each row. FileDiffLabels types it; every key is optional, and line is a function that receives the line number.

<FileDiff.Root
    {diff}
    labels={{
        added: 'Ajoutรฉe',
        removed: 'Supprimรฉe',
        unchanged: 'Inchangรฉe',
        line: (line) => `ligne ${line}`
    }}
/>

Custom line numbers

When you compose rows yourself, LineNumber draws one gutter cell. value is the number to show, and a null value renders an empty cell, which is what the old-side gutter needs on an added line. tone colors the number as context, add or remove. Rows pass their own type, so you only set it for a number used on its own.

API reference

FileDiff.Root

Provides diff state and layout.

  • labels
    FileDiffLabels

    Overrides the built-in text and accessible names. Every key is optional and English is the fallback.

  • file
    string

    File path shown in the top bar, e.g. "src/auth.ts".

    Default ''

  • lang
    string

    Highlight.js language id used for every row unless a row overrides it.

    Default ''

  • additions
    number

    Addition count. Defaults to the number of add lines in diff.

  • deletions
    number

    Deletion count. Defaults to the number of remove lines in diff.

  • diff
    FileDiffLine[]

    High-level unified lines. When set, Root renders TopBar and Content itself.

  • showLineNumbers
    boolean

    Render the old/new line-number gutters.

    Default true

  • theme
    FileDiffTheme

    Syntax paint: - mielui (default): the built-in GitHub palette. - custom: no token colors; load any highlight.js/styles/* theme instead.

    Default 'mielui'

  • children
    Snippet<[]>

    Content rendered inside.

  • class
    (string & (ClassValue | null))

    Classes added to the element.

FileDiff.Content

Contains the scrollable diff rows.

  • children
    Snippet<[]>

    Content rendered inside.

  • class
    (string & (ClassValue | null))

    Classes added to the element.

FileDiff.Filename

  • file
    string

    File path. Falls back to the Root file when omitted.

  • class
    (string & (ClassValue | null))

    Classes added to the element.

  • children
    Snippet<[]>

    Content rendered inside.

FileDiff.LineNumber

Renders one gutter line number.

  • value
    number | null

    Line number. Renders an empty gutter cell when nullish.

  • tone
    FileDiffChangeType

    Number tone. Rows pass their own type; standalone use defaults to context.

    Default 'context'

  • class
    (string & (ClassValue | null))

    Classes added to the element.

  • children
    Snippet<[]>

    Content rendered inside.

FileDiff.PlusMinus

  • additions
    number

    Addition count. Falls back to the Root count when omitted.

  • deletions
    number

    Deletion count. Falls back to the Root count when omitted.

  • class
    (string & (ClassValue | null))

    Classes added to the element.

  • children
    Snippet<[]>

    Content rendered inside.

FileDiff.Row

Renders one highlighted diff row.

  • type
    FileDiffChangeType

    Row kind. Drives the tint, line-number tone, and sign.

    Default 'context'

  • oldLine
    number | null

    Old-file line number. Empty when nullish.

  • newLine
    number | null

    New-file line number. Empty when nullish.

  • code
    string

    Raw source for the row. Highlighted with the Root (or row) language.

    Default ''

  • lang
    string

    Row-level language override.

  • children
    Snippet<[]>

    Content rendered inside.

  • class
    (string & (ClassValue | null))

    Classes added to the element.

FileDiff.TopBar

Renders the file path and change counts.

  • file
    string

    File path. Falls back to the Root file when omitted.

  • additions
    number

    Addition count. Falls back to the Root count when omitted.

  • deletions
    number

    Deletion count. Falls back to the Root count when omitted.

  • children
    Snippet<[]>

    Replaces the default row. The filename and counts are omitted, so compose them back with Filename and PlusMinus around any actions. Content rendered inside.

  • class
    (string & (ClassValue | null))

    Classes added to the element.