Skip to content

Commit 88ecfb5

Browse files
Merge pull request #12 from Zhang-JiahangH/feat/simplified-diff-viewer
feat: add a simplified version of virtualized diff viewer
2 parents 7b84ac4 + e0997a4 commit 88ecfb5

9 files changed

Lines changed: 356 additions & 15 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ The format is based on Keep a Changelog, and this project follows Semantic Versi
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Introduced API tiering with a new minimal `SimpleDiffViewer` export for common use cases, while keeping `DiffViewer` (and `AdvancedDiffViewer` alias) for advanced customization scenarios.
12+
- Added `docs/api-tiering.md` with persona-oriented guidance and three practical examples: basic diff, large-file virtualization, and commentable line embedding.
13+
- Added TypeScript JSDoc examples for advanced API types (`DiffViewerProps`, `RenderContent`, and `DiffViewerHandle`).
14+
15+
### Changed
16+
17+
- Updated README (EN/ZH), package README, and `llms.txt` to document minimal-vs-advanced API tiers and recommended adoption path.
18+
919
### Docs
1020

1121
- Reorganized root README files for clearer scanning (quick overview + positioning block), clarified the purpose of `docs/positioning.md`, and aligned `packages/react/README.md` so npm package docs reflect the same positioning updates.

README.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ pnpm add react-virtualized-diff
5151
## Quick Start
5252

5353
```tsx
54-
import { DiffViewer } from 'react-virtualized-diff';
54+
import { SimpleDiffViewer } from 'react-virtualized-diff';
5555

5656
const original = `line 1\nline 2\nline 3`;
5757
const modified = `line 1\nline 2 changed\nline 3\nline 4`;
5858

5959
export function App() {
6060
return (
61-
<DiffViewer
61+
<SimpleDiffViewer
6262
original={original}
6363
modified={modified}
6464
contextLines={2}
@@ -70,7 +70,23 @@ export function App() {
7070

7171
## API
7272

73-
### `DiffViewer`
73+
API tiering guide: [docs/api-tiering.md](./docs/api-tiering.md).
74+
75+
### `SimpleDiffViewer` (recommended for 80% of cases)
76+
77+
| Prop | Type | Default | Description |
78+
| --- | --- | --- | --- |
79+
| `original` | `string` | - | Original text content (left) |
80+
| `modified` | `string` | - | Modified text content (right) |
81+
| `height` | `number \| string` | `500` | Viewport height of the virtual list |
82+
| `splitView` | `boolean` | `true` | `true` for side-by-side, `false` for unified/inline |
83+
| `showDiffOnly` | `boolean` | `true` | Show only changed lines with collapsible unchanged blocks |
84+
| `contextLines` | `number` | `2` | Number of unchanged lines kept around diff hunks |
85+
| `hideLineNumbers` | `boolean` | `false` | Hide line number columns |
86+
| `useDarkTheme` | `boolean` | `false` | Built-in dark theme |
87+
| `locale` | `DiffViewerLocale` | - | UI text localization |
88+
89+
### `DiffViewer` / `AdvancedDiffViewer` (deep customization)
7490

7591
| Prop | Type | Default | Description |
7692
| --- | --- | --- | --- |

README.zh-CN.md

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ pnpm add react-virtualized-diff
5151
## 快速开始
5252

5353
```tsx
54-
import { DiffViewer } from 'react-virtualized-diff';
54+
import { SimpleDiffViewer } from 'react-virtualized-diff';
5555

5656
const original = `line 1\nline 2\nline 3`;
5757
const modified = `line 1\nline 2 changed\nline 3\nline 4`;
5858

5959
export function App() {
6060
return (
61-
<DiffViewer
61+
<SimpleDiffViewer
6262
original={original}
6363
modified={modified}
6464
contextLines={2}
@@ -70,13 +70,46 @@ export function App() {
7070

7171
## API
7272

73-
### `DiffViewer`
73+
API 分层说明文档:[docs/api-tiering.md](./docs/api-tiering.md)
74+
75+
### `SimpleDiffViewer`(推荐,覆盖 80% 场景)
76+
77+
| 属性 | 类型 | 默认值 | 说明 |
78+
| --- | --- | --- | --- |
79+
| `original` | `string` | - | 原始文本(左侧) |
80+
| `modified` | `string` | - | 修改后文本(右侧) |
81+
| `height` | `number \| string` | `500` | 虚拟列表可视区域高度 |
82+
| `splitView` | `boolean` | `true` | `true` 为左右并排,`false` 为统一视图 |
83+
| `showDiffOnly` | `boolean` | `true` | 仅展示变更块并折叠未变更区块 |
84+
| `contextLines` | `number` | `2` | 每个变更块周围保留的未变更行数 |
85+
| `hideLineNumbers` | `boolean` | `false` | 是否隐藏行号列 |
86+
| `useDarkTheme` | `boolean` | `false` | 内置暗色主题 |
87+
| `locale` | `DiffViewerLocale` | - | 组件文案本地化 |
88+
89+
### `DiffViewer` / `AdvancedDiffViewer`(高级定制)
7490

7591
| 属性 | 类型 | 默认值 | 说明 |
7692
| --- | --- | --- | --- |
77-
| `original` | `string` | - | 原始文本 |
78-
| `modified` | `string` | - | 修改后文本 |
93+
| `original` | `string` | - | 原始文本(新 API) |
94+
| `modified` | `string` | - | 修改后文本(新 API) |
95+
| `oldValue` | `string` | - | 兼容 API:等同 `original` |
96+
| `newValue` | `string` | - | 兼容 API:等同 `modified` |
97+
| `splitView` | `boolean` | `true` | `true` 为左右并排,`false` 为统一视图 |
98+
| `showDiffOnly` | `boolean` | `true` | 仅展示变更块并折叠未变更区块 |
7999
| `contextLines` | `number` | `2` | 每个变更块周围保留的未变更行数 |
100+
| `extraLinesSurroundingDiff` | `number` | - | 兼容 API:`contextLines` 别名 |
101+
| `hideLineNumbers` | `boolean` | `false` | 是否隐藏行号列 |
102+
| `highlightLines` | `Array<'L-n' \| 'R-n' \| range>` | - | 高亮指定行(如 `L-3``R-5``L-10-15`|
103+
| `onLineNumberClick` | `(lineId) => void` | - | 点击行号回调 |
104+
| `renderContent` | `(line: string) => ReactNode` | - | 自定义行内容渲染(语法高亮等) |
105+
| `compareMethod` | `"CHARS" \| "WORDS" \| "WORDS_WITH_SPACE" \| "LINES" \| "TRIMMED_LINES" \| "SENTENCES" \| "CSS"` | `"LINES"` | Diff 比较策略 |
106+
| `disableWordDiff` | `boolean` | `false` | 关闭词级高亮 |
107+
| `leftTitle` | `ReactNode` | - | 左侧标题(并排模式) |
108+
| `rightTitle` | `ReactNode` | - | 右侧标题(并排模式) |
109+
| `linesOffset` | `number` | `0` | 行号显示偏移量 |
110+
| `useDarkTheme` | `boolean` | `false` | 内置暗色主题 |
111+
| `styles` | `Partial<DiffViewerStyles>` | - | 样式槽位覆盖 |
112+
| `codeFoldMessageRenderer` | `({ hiddenCount, expanded }) => ReactNode` | - | 自定义折叠按钮文案渲染 |
80113
| `height` | `number \| string` | `500` | 虚拟列表可视区域高度 |
81114
| `locale` | `DiffViewerLocale` | - | 组件文案本地化 |
82115
| `language` | `string` | - | 预留字段(未来语言相关扩展) |

docs/api-tiering.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# API Tiering Guide
2+
3+
This document groups `react-virtualized-diff` APIs into usage tiers so teams can pick the right abstraction level quickly.
4+
5+
## Tier 1: Minimal API (`SimpleDiffViewer`)
6+
7+
**Best for**
8+
9+
- Product teams that need a reliable diff view fast.
10+
- Typical PR/MR preview pages.
11+
- Apps where defaults are good enough and maintainability matters more than customization.
12+
13+
**Use this when**
14+
15+
- You only need to pass two texts and a few basic display options.
16+
- You want the smallest cognitive load for contributors.
17+
18+
**Primary API**
19+
20+
- `original`
21+
- `modified`
22+
- `height`
23+
- `splitView`
24+
- `showDiffOnly`
25+
- `contextLines`
26+
- `hideLineNumbers`
27+
- `useDarkTheme`
28+
- `locale`
29+
30+
### Minimal example 1: 基础对比
31+
32+
```tsx
33+
import { SimpleDiffViewer } from 'react-virtualized-diff';
34+
35+
export function BasicDiffExample() {
36+
return (
37+
<SimpleDiffViewer
38+
original={'line 1\nline 2\nline 3'}
39+
modified={'line 1\nline 2 changed\nline 3'}
40+
height={360}
41+
/>
42+
);
43+
}
44+
```
45+
46+
### Minimal example 2: 大文件虚拟化
47+
48+
```tsx
49+
import { SimpleDiffViewer } from 'react-virtualized-diff';
50+
51+
function buildLargeText(size: number, changedAt: number) {
52+
return Array.from({ length: size }, (_, i) =>
53+
i === changedAt ? `line ${i + 1} (changed)` : `line ${i + 1}`,
54+
).join('\n');
55+
}
56+
57+
export function VirtualizedLargeFileExample() {
58+
const original = buildLargeText(50000, -1);
59+
const modified = buildLargeText(50000, 24567);
60+
61+
return (
62+
<SimpleDiffViewer
63+
original={original}
64+
modified={modified}
65+
height={640}
66+
contextLines={1}
67+
showDiffOnly
68+
/>
69+
);
70+
}
71+
```
72+
73+
## Tier 2: Advanced API (`DiffViewer` / `AdvancedDiffViewer`)
74+
75+
**Best for**
76+
77+
- Code review platforms with domain-specific behaviors.
78+
- Teams needing tight design-system integration.
79+
- Scenarios requiring interaction hooks and custom rendering.
80+
81+
**Use this when**
82+
83+
- You need custom line rendering (syntax highlighting, inline widgets).
84+
- You need line-number gutter interactions.
85+
- You need custom fold/collapse messaging or styling.
86+
87+
**Primary advanced extension points**
88+
89+
- 自定义行渲染: `renderContent`
90+
- 语法高亮集成: `renderContent`
91+
- 行号 gutter 交互: `onLineNumberClick`, `highlightLines`, `linesOffset`
92+
- 折叠策略: `showDiffOnly`, `contextLines`, `extraLinesSurroundingDiff`, `codeFoldMessageRenderer`
93+
- 深度样式定制: `styles`, `useDarkTheme`
94+
95+
### Minimal example 3: 可评论行组件嵌入
96+
97+
```tsx
98+
import { DiffViewer } from 'react-virtualized-diff';
99+
100+
function CommentableLine({ line }: { line: string }) {
101+
return (
102+
<span style={{ display: 'inline-flex', gap: 8 }}>
103+
<span>{line}</span>
104+
<button type="button">Comment</button>
105+
</span>
106+
);
107+
}
108+
109+
export function CommentableDiffExample() {
110+
return (
111+
<DiffViewer
112+
original={'const a = 1\nconst b = 2'}
113+
modified={'const a = 1\nconst b = 3'}
114+
renderContent={(line) => <CommentableLine line={line} />}
115+
onLineNumberClick={(lineId) => {
116+
// open comment panel by line id
117+
console.log('comment target:', lineId);
118+
}}
119+
height={420}
120+
/>
121+
);
122+
}
123+
```
124+
125+
## Recommendation matrix
126+
127+
- Start with `SimpleDiffViewer` for most application pages.
128+
- Move to `DiffViewer` (`AdvancedDiffViewer`) only after a concrete customization requirement appears.
129+
- Keep one internal wrapper in your codebase if your product repeatedly uses the same advanced options.

llms.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,19 @@ npm install react-virtualized-diff
3131
## Minimum usage
3232

3333
```jsx
34-
import { DiffViewer } from 'react-virtualized-diff';
34+
import { SimpleDiffViewer } from 'react-virtualized-diff';
3535

36-
<DiffViewer original={oldText} modified={newText} />
36+
<SimpleDiffViewer original={oldText} modified={newText} />
3737
```
3838

3939
Two strings are the complete minimum API. This produces a side-by-side diff with collapsed unchanged blocks and virtualized scrolling.
4040

41+
## API tiers
42+
43+
- **Tier 1 (recommended):** `SimpleDiffViewer` for most product pages. Minimal props: `original`, `modified`, `height`, `splitView`, `showDiffOnly`, `contextLines`, `hideLineNumbers`, `useDarkTheme`, `locale`.
44+
- **Tier 2 (advanced):** `DiffViewer` (also exported as `AdvancedDiffViewer`) when you need deep customization such as `renderContent`, line-gutter interactions, fold-message customization, and style slot overrides.
45+
- See tiering guide: `docs/api-tiering.md`.
46+
4147
## Commonly used props
4248

4349
- `original` (string): base/left content — new API name

packages/react/README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ pnpm add react-virtualized-diff
3131
## Usage
3232

3333
```tsx
34-
import { DiffViewer } from 'react-virtualized-diff';
34+
import { SimpleDiffViewer } from 'react-virtualized-diff';
3535

3636
export function App() {
3737
return (
38-
<DiffViewer
38+
<SimpleDiffViewer
3939
original={'line 1\nline 2'}
4040
modified={'line 1\nline 2 changed'}
4141
contextLines={2}
@@ -47,7 +47,19 @@ export function App() {
4747

4848
## API
4949

50-
### `DiffViewer` props
50+
### `SimpleDiffViewer` props (recommended for 80% of cases)
51+
52+
- `original: string`
53+
- `modified: string`
54+
- `height?: number | string` (default `500`)
55+
- `splitView?: boolean` (default `true`)
56+
- `showDiffOnly?: boolean` (default `true`)
57+
- `contextLines?: number` (default `2`)
58+
- `hideLineNumbers?: boolean` (default `false`)
59+
- `useDarkTheme?: boolean` (default `false`)
60+
- `locale?: DiffViewerLocale`
61+
62+
### `DiffViewer` / `AdvancedDiffViewer` props
5163

5264
- `original?: string`
5365
- `modified?: string`

0 commit comments

Comments
 (0)