DiffTable
Presents an AI-proposed edit as a change set, tinting outgoing rows and expanding incoming ones stage by stage.
DiffTable
Basic Usage
DiffTable
Proposed menu cleanup
Plays once on mount and rests on the completed diff; the replay button runs reset() + play().
Loading demo...
Stages And Playback Modes
stageDelays is a three-part timeline of [hold, tint, expand], defaulting to [800, 1000, 1000]. The first segment is a deliberate reading pause: nothing moves until it and the second have elapsed (1.8s at the defaults), so a reader takes in the original data before the edit lands.
| Stage | On screen |
|---|---|
| 0–1 | Every row plain |
| 2 | removed / modified rows tint, recolour, and strike through |
| 3 (terminal) | added rows expand from 0fr to 1fr |
play decides who drives it: auto plays once on mount and rests on the completed diff; manual stays plain until play() is called; settled renders the finished state immediately and registers no timers at all (for docs and tests).
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
columns | DiffTableColumn[] | [] | Column configuration |
rows | DiffTableRow[] | [] | Rows, each carrying its own change kind |
title | string | - | Card bar heading; omit it and the whole bar is dropped |
play | 'auto' | 'manual' | 'settled' | 'auto' | Playback mode |
stageDelays | [number, number, number] | [800, 1000, 1000] | The three stage lengths, in milliseconds |
duration | number | 400 | Tween length for the tint and the reveal, in milliseconds |
DiffTableColumn
| Field | Type | Description |
|---|---|---|
key | string | Column key; also names the cell-<key> slot |
title | string | Header text |
dataIndex | string | Field read from row.data; defaults to key |
width | string | number | Track width; numbers are pixels, strings pass through ('34%') |
align | 'left' | 'center' | 'right' | Text alignment |
strikeOnRemove | boolean | Strikes this column through on removed rows — for the value being retired |
tintText | boolean | Whether the text follows the change tone; defaults to true. Set false on columns that carry their own colour |
format | (value, row, index) => string | Default text formatting |
DiffTableRow
| Field | Type | Description |
|---|---|---|
key | string | number | Row identity |
data | T | The record itself |
change | 'unchanged' | 'added' | 'removed' | 'modified' | Change kind, defaulting to 'unchanged'; modified uses the warning tone |
Events
| Event | Payload | Description |
|---|---|---|
stageChange | (stage: number) | Fires on every stage transition |
settled | () | Fires once the final stage is reached, whatever route got it there |
Slots
| Name | Description |
|---|---|
title | Replaces the card bar heading |
cell-<columnKey> | Custom cell; receives { row, column, value, change, index }, so the slot can react to the row's own state |
Expose
| Name | Description |
|---|---|
play() | Runs the sequence from wherever it currently rests |
reset() | Returns to the plain table and stops any pending stage |
settle() | Jumps straight to the completed diff |
stage | Current stage index; equals stageDelays.length once settled |
Interaction Contract
- The stage machine is this component's semantics, not demo choreography: the host sets the pace through
playand the exposed methods, and describes the edit throughrows[].change. - Timers are cleared in
onBeforeUnmount;play="settled"registers none at all. - Reduced motion (
prefers-reduced-motion: reduce) drops the tweens, never the state machine: stages still advance, they simply stop animating. Freezing the machine would leave the reader looking at a table that never shows the edit. - Row tints are class-driven rather than inline, so a tinted row still gives hover feedback.
- A collapsed appended row carries
aria-hiddenandinert, so it is neither announced nor in the tab order. - The appended row's inner grid and the
<colgroup>are both derived fromcolumns— one source of truth.
Best Practices
- Express meaning through
changerather than painting colours with custom classes; the tint, the strike-through, and the reveal all follow from it. - Set
tintText: falseon badge or coloured-chip columns, or the change tone repaints them wholesale. - Give columns percentage or fixed pixel widths so the appended row cannot drift out of alignment.
- Use
play="settled"for docs, snapshot tests, and anywhere the animation is unwanted — it hands you the finished state directly. - For button-triggered playback use
play="manual"withreset()+play(); do not remount the component with a changing:key.
Source
- Component source:
packages/tuffex/packages/components/src/diff-table/src/TxDiffTable.vue. - Types:
packages/tuffex/packages/components/src/diff-table/src/types.tsexportsDiffTableProps,DiffTableColumn,DiffTableRow,DiffChangeKind,DiffTablePlay, andDiffTableEmits. - Instance:
packages/tuffex/packages/components/src/diff-table/index.tswritesTxDiffTableInstanceout by hand — a generic component's expose surface is typed unwrapped, sostageis anumberrather than aRef<number>. - Test coverage:
packages/tuffex/packages/components/src/diff-table/__tests__/diff-table.test.tshas 15 cases using fake timers, covering the three-stage timeline,stageChange/settledemissions, all three playback modes, the three exposed methods, per-column tint and strike, grid-and-colgroup agreement, the collapsed row'saria-hidden/inert, unmount cleanup, andplaymode switching.
查看源码
packages/tuffex/packages/components/src/diff-table/index.ts