Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ The format is based on Keep a Changelog, and this project follows Semantic Versi

## [Unreleased]

### Added

- Introduced API tiering with a new minimal `SimpleDiffViewer` export for common use cases, while keeping `DiffViewer` (and `AdvancedDiffViewer` alias) for advanced customization scenarios.
- Added `docs/api-tiering.md` with persona-oriented guidance and three practical examples: basic diff, large-file virtualization, and commentable line embedding.
- Added TypeScript JSDoc examples for advanced API types (`DiffViewerProps`, `RenderContent`, and `DiffViewerHandle`).

### Changed

- Updated README (EN/ZH), package README, and `llms.txt` to document minimal-vs-advanced API tiers and recommended adoption path.

### Docs

- 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.
Expand Down
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ pnpm add react-virtualized-diff
## Quick Start

```tsx
import { DiffViewer } from 'react-virtualized-diff';
import { SimpleDiffViewer } from 'react-virtualized-diff';

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

export function App() {
return (
<DiffViewer
<SimpleDiffViewer
original={original}
modified={modified}
contextLines={2}
Expand All @@ -70,7 +70,23 @@ export function App() {

## API

### `DiffViewer`
API tiering guide: [docs/api-tiering.md](./docs/api-tiering.md).

### `SimpleDiffViewer` (recommended for 80% of cases)

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `original` | `string` | - | Original text content (left) |
| `modified` | `string` | - | Modified text content (right) |
| `height` | `number \| string` | `500` | Viewport height of the virtual list |
| `splitView` | `boolean` | `true` | `true` for side-by-side, `false` for unified/inline |
| `showDiffOnly` | `boolean` | `true` | Show only changed lines with collapsible unchanged blocks |
| `contextLines` | `number` | `2` | Number of unchanged lines kept around diff hunks |
| `hideLineNumbers` | `boolean` | `false` | Hide line number columns |
| `useDarkTheme` | `boolean` | `false` | Built-in dark theme |
| `locale` | `DiffViewerLocale` | - | UI text localization |

### `DiffViewer` / `AdvancedDiffViewer` (deep customization)

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
Expand Down
43 changes: 38 additions & 5 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ pnpm add react-virtualized-diff
## 快速开始

```tsx
import { DiffViewer } from 'react-virtualized-diff';
import { SimpleDiffViewer } from 'react-virtualized-diff';

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

export function App() {
return (
<DiffViewer
<SimpleDiffViewer
original={original}
modified={modified}
contextLines={2}
Expand All @@ -70,13 +70,46 @@ export function App() {

## API

### `DiffViewer`
API 分层说明文档:[docs/api-tiering.md](./docs/api-tiering.md)。

### `SimpleDiffViewer`(推荐,覆盖 80% 场景)

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `original` | `string` | - | 原始文本(左侧) |
| `modified` | `string` | - | 修改后文本(右侧) |
| `height` | `number \| string` | `500` | 虚拟列表可视区域高度 |
| `splitView` | `boolean` | `true` | `true` 为左右并排,`false` 为统一视图 |
| `showDiffOnly` | `boolean` | `true` | 仅展示变更块并折叠未变更区块 |
| `contextLines` | `number` | `2` | 每个变更块周围保留的未变更行数 |
| `hideLineNumbers` | `boolean` | `false` | 是否隐藏行号列 |
| `useDarkTheme` | `boolean` | `false` | 内置暗色主题 |
| `locale` | `DiffViewerLocale` | - | 组件文案本地化 |

### `DiffViewer` / `AdvancedDiffViewer`(高级定制)

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `original` | `string` | - | 原始文本 |
| `modified` | `string` | - | 修改后文本 |
| `original` | `string` | - | 原始文本(新 API) |
| `modified` | `string` | - | 修改后文本(新 API) |
| `oldValue` | `string` | - | 兼容 API:等同 `original` |
| `newValue` | `string` | - | 兼容 API:等同 `modified` |
| `splitView` | `boolean` | `true` | `true` 为左右并排,`false` 为统一视图 |
| `showDiffOnly` | `boolean` | `true` | 仅展示变更块并折叠未变更区块 |
| `contextLines` | `number` | `2` | 每个变更块周围保留的未变更行数 |
| `extraLinesSurroundingDiff` | `number` | - | 兼容 API:`contextLines` 别名 |
| `hideLineNumbers` | `boolean` | `false` | 是否隐藏行号列 |
| `highlightLines` | `Array<'L-n' \| 'R-n' \| range>` | - | 高亮指定行(如 `L-3`、`R-5`、`L-10-15`) |
| `onLineNumberClick` | `(lineId) => void` | - | 点击行号回调 |
| `renderContent` | `(line: string) => ReactNode` | - | 自定义行内容渲染(语法高亮等) |
| `compareMethod` | `"CHARS" \| "WORDS" \| "WORDS_WITH_SPACE" \| "LINES" \| "TRIMMED_LINES" \| "SENTENCES" \| "CSS"` | `"LINES"` | Diff 比较策略 |
| `disableWordDiff` | `boolean` | `false` | 关闭词级高亮 |
| `leftTitle` | `ReactNode` | - | 左侧标题(并排模式) |
| `rightTitle` | `ReactNode` | - | 右侧标题(并排模式) |
| `linesOffset` | `number` | `0` | 行号显示偏移量 |
| `useDarkTheme` | `boolean` | `false` | 内置暗色主题 |
| `styles` | `Partial<DiffViewerStyles>` | - | 样式槽位覆盖 |
| `codeFoldMessageRenderer` | `({ hiddenCount, expanded }) => ReactNode` | - | 自定义折叠按钮文案渲染 |
| `height` | `number \| string` | `500` | 虚拟列表可视区域高度 |
| `locale` | `DiffViewerLocale` | - | 组件文案本地化 |
| `language` | `string` | - | 预留字段(未来语言相关扩展) |
Expand Down
129 changes: 129 additions & 0 deletions docs/api-tiering.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# API Tiering Guide

This document groups `react-virtualized-diff` APIs into usage tiers so teams can pick the right abstraction level quickly.

## Tier 1: Minimal API (`SimpleDiffViewer`)

**Best for**

- Product teams that need a reliable diff view fast.
- Typical PR/MR preview pages.
- Apps where defaults are good enough and maintainability matters more than customization.

**Use this when**

- You only need to pass two texts and a few basic display options.
- You want the smallest cognitive load for contributors.

**Primary API**

- `original`
- `modified`
- `height`
- `splitView`
- `showDiffOnly`
- `contextLines`
- `hideLineNumbers`
- `useDarkTheme`
- `locale`

### Minimal example 1: 基础对比

```tsx
import { SimpleDiffViewer } from 'react-virtualized-diff';

export function BasicDiffExample() {
return (
<SimpleDiffViewer
original={'line 1\nline 2\nline 3'}
modified={'line 1\nline 2 changed\nline 3'}
height={360}
/>
);
}
```

### Minimal example 2: 大文件虚拟化

```tsx
import { SimpleDiffViewer } from 'react-virtualized-diff';

function buildLargeText(size: number, changedAt: number) {
return Array.from({ length: size }, (_, i) =>
i === changedAt ? `line ${i + 1} (changed)` : `line ${i + 1}`,
).join('\n');
}

export function VirtualizedLargeFileExample() {
const original = buildLargeText(50000, -1);
const modified = buildLargeText(50000, 24567);

return (
<SimpleDiffViewer
original={original}
modified={modified}
height={640}
contextLines={1}
showDiffOnly
/>
);
}
```

## Tier 2: Advanced API (`DiffViewer` / `AdvancedDiffViewer`)

**Best for**

- Code review platforms with domain-specific behaviors.
- Teams needing tight design-system integration.
- Scenarios requiring interaction hooks and custom rendering.

**Use this when**

- You need custom line rendering (syntax highlighting, inline widgets).
- You need line-number gutter interactions.
- You need custom fold/collapse messaging or styling.

**Primary advanced extension points**

- 自定义行渲染: `renderContent`
- 语法高亮集成: `renderContent`
- 行号 gutter 交互: `onLineNumberClick`, `highlightLines`, `linesOffset`
- 折叠策略: `showDiffOnly`, `contextLines`, `extraLinesSurroundingDiff`, `codeFoldMessageRenderer`
- 深度样式定制: `styles`, `useDarkTheme`

### Minimal example 3: 可评论行组件嵌入

```tsx
import { DiffViewer } from 'react-virtualized-diff';

function CommentableLine({ line }: { line: string }) {
return (
<span style={{ display: 'inline-flex', gap: 8 }}>
<span>{line}</span>
<button type="button">Comment</button>
</span>
);
}

export function CommentableDiffExample() {
return (
<DiffViewer
original={'const a = 1\nconst b = 2'}
modified={'const a = 1\nconst b = 3'}
renderContent={(line) => <CommentableLine line={line} />}
onLineNumberClick={(lineId) => {
// open comment panel by line id
console.log('comment target:', lineId);
}}
height={420}
/>
);
}
```

## Recommendation matrix

- Start with `SimpleDiffViewer` for most application pages.
- Move to `DiffViewer` (`AdvancedDiffViewer`) only after a concrete customization requirement appears.
- Keep one internal wrapper in your codebase if your product repeatedly uses the same advanced options.
10 changes: 8 additions & 2 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@ npm install react-virtualized-diff
## Minimum usage

```jsx
import { DiffViewer } from 'react-virtualized-diff';
import { SimpleDiffViewer } from 'react-virtualized-diff';

<DiffViewer original={oldText} modified={newText} />
<SimpleDiffViewer original={oldText} modified={newText} />
```

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

## API tiers

- **Tier 1 (recommended):** `SimpleDiffViewer` for most product pages. Minimal props: `original`, `modified`, `height`, `splitView`, `showDiffOnly`, `contextLines`, `hideLineNumbers`, `useDarkTheme`, `locale`.
- **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.
- See tiering guide: `docs/api-tiering.md`.

## Commonly used props

- `original` (string): base/left content — new API name
Expand Down
18 changes: 15 additions & 3 deletions packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ pnpm add react-virtualized-diff
## Usage

```tsx
import { DiffViewer } from 'react-virtualized-diff';
import { SimpleDiffViewer } from 'react-virtualized-diff';

export function App() {
return (
<DiffViewer
<SimpleDiffViewer
original={'line 1\nline 2'}
modified={'line 1\nline 2 changed'}
contextLines={2}
Expand All @@ -47,7 +47,19 @@ export function App() {

## API

### `DiffViewer` props
### `SimpleDiffViewer` props (recommended for 80% of cases)

- `original: string`
- `modified: string`
- `height?: number | string` (default `500`)
- `splitView?: boolean` (default `true`)
- `showDiffOnly?: boolean` (default `true`)
- `contextLines?: number` (default `2`)
- `hideLineNumbers?: boolean` (default `false`)
- `useDarkTheme?: boolean` (default `false`)
- `locale?: DiffViewerLocale`

### `DiffViewer` / `AdvancedDiffViewer` props

- `original?: string`
- `modified?: string`
Expand Down
Loading
Loading