diff --git a/apps/docs/app/(diffs)/_docs/DocsPage.tsx b/apps/docs/app/(diffs)/_docs/DocsPage.tsx
index 5bc46d92a..19f419271 100644
--- a/apps/docs/app/(diffs)/_docs/DocsPage.tsx
+++ b/apps/docs/app/(diffs)/_docs/DocsPage.tsx
@@ -89,6 +89,14 @@ import {
VIRTUALIZATION_REACT_CONFIG,
VIRTUALIZATION_VANILLA_DIFF,
} from '../docs/Virtualization/constants';
+import {
+ VUE_API_MULTI_FILE_DIFF,
+ VUE_API_PATCH_DIFF,
+ VUE_API_SLOTS,
+ VUE_API_SSR,
+ VUE_API_VIRTUALIZER,
+ VUE_API_WORKER_POOL,
+} from '../docs/VueAPI/constants';
import {
WORKER_POOL_API_REFERENCE,
WORKER_POOL_ARCHITECTURE_ASCII,
@@ -117,7 +125,7 @@ import { renderMDX } from '@/lib/mdx';
const docsTitle = 'Diffs docs';
const docsDescription =
- 'Documentation for @pierre/diffs: React and vanilla APIs, virtualization, theming, token hooks, the worker pool, and SSR hydration.';
+ 'Documentation for @pierre/diffs: React, Vue, and vanilla APIs, virtualization, theming, token hooks, the worker pool, and SSR hydration.';
// Next.js replaces (does not deep-merge) nested metadata objects like
// `openGraph` and `twitter` from parent segments. Re-declare `images` here
@@ -149,6 +157,7 @@ export default function DocsPage() {
+
@@ -324,6 +333,36 @@ async function VanillaAPISection() {
return {content};
}
+async function VueAPISection() {
+ const [
+ vueAPIMultiFileDiff,
+ vueAPIPatchDiff,
+ vueAPISlots,
+ vueAPIVirtualizer,
+ vueAPIWorkerPool,
+ vueAPISsr,
+ ] = await Promise.all([
+ preloadFile(VUE_API_MULTI_FILE_DIFF),
+ preloadFile(VUE_API_PATCH_DIFF),
+ preloadFile(VUE_API_SLOTS),
+ preloadFile(VUE_API_VIRTUALIZER),
+ preloadFile(VUE_API_WORKER_POOL),
+ preloadFile(VUE_API_SSR),
+ ]);
+ const content = await renderMDX({
+ filePath: '(diffs)/docs/VueAPI/content.mdx',
+ scope: {
+ vueAPIMultiFileDiff,
+ vueAPIPatchDiff,
+ vueAPISlots,
+ vueAPISsr,
+ vueAPIVirtualizer,
+ vueAPIWorkerPool,
+ },
+ });
+ return {content};
+}
+
async function VirtualizationSection() {
const [
reactVirtualizerBasic,
diff --git a/apps/docs/app/(diffs)/docs/Installation/content.mdx b/apps/docs/app/(diffs)/docs/Installation/content.mdx
index 037838c91..e9efc9b68 100644
--- a/apps/docs/app/(diffs)/docs/Installation/content.mdx
+++ b/apps/docs/app/(diffs)/docs/Installation/content.mdx
@@ -14,5 +14,6 @@ The package provides several entry points for different use cases:
| ---------------------- | ------------------------------------------------------------------------------------------------------------ |
| `@pierre/diffs` | [Vanilla JS components](#vanilla-js-api) and [utility functions](#utilities) for parsing and rendering diffs |
| `@pierre/diffs/react` | [React components](#react-api) for rendering diffs with full interactivity |
+| `@pierre/diffs/vue` | [Vue components](#vue-api) for rendering diffs with full interactivity |
| `@pierre/diffs/ssr` | [Server-side rendering utilities](#ssr) for pre-rendering diffs with syntax highlighting |
| `@pierre/diffs/worker` | [Worker pool utilities](#worker-pool) for offloading syntax highlighting to background threads |
diff --git a/apps/docs/app/(diffs)/docs/Overview/content.mdx b/apps/docs/app/(diffs)/docs/Overview/content.mdx
index 1ca3402a5..31fb355ac 100644
--- a/apps/docs/app/(diffs)/docs/Overview/content.mdx
+++ b/apps/docs/app/(diffs)/docs/Overview/content.mdx
@@ -19,17 +19,17 @@ We have an opinionated stance in our architecture: **browsers are rather
efficient at rendering raw HTML**. We lean into this by having all the lower
level APIs purely rendering strings (the raw HTML) that are then consumed by
higher-order components and utilities. This gives us great performance and
-flexibility to support popular libraries like React as well as provide great
-tools if you want to stick to vanilla JavaScript and HTML. The higher-order
-components render all this out into Shadow DOM and CSS grid layout.
+flexibility to support popular libraries like React and Vue as well as provide
+great tools if you want to stick to vanilla JavaScript and HTML. The
+higher-order components render all this out into Shadow DOM and CSS grid layout.
Generally speaking, you're probably going to want to use the higher level
components since they provide an easy-to-use API that you can get started with
-rather quickly. We currently only have components for vanilla JavaScript and
-React, but will add more if there's demand.
+rather quickly. Diffs includes runtime lanes for React, Vue, and vanilla
+JavaScript.
For this overview, we'll talk about the vanilla JavaScript components for now
-but there are React equivalents for all of these.
+but there are React and Vue equivalents for all of these.
## Rendering Diffs
@@ -43,6 +43,7 @@ There are two ways to render diffs with `FileDiff`:
2. Consume a patch file
You can see examples of these approaches below, in both JavaScript and React.
+For Vue usage, see the [Vue API](#vue-api).
}>
Inputs used for pre-rendering must exactly match what's rendered in the client
- component. We recommend spreading the entire result object into your File or
- Diff component to ensure the client receives the same inputs that were used to
- generate the pre-rendered HTML.
+ component. Keep the client props aligned with the preload result so the client
+ receives the same inputs that were used to generate the pre-rendered HTML.
#### Server Component
diff --git a/apps/docs/app/(diffs)/docs/Virtualization/content.mdx b/apps/docs/app/(diffs)/docs/Virtualization/content.mdx
index 232650cfc..d8b945728 100644
--- a/apps/docs/app/(diffs)/docs/Virtualization/content.mdx
+++ b/apps/docs/app/(diffs)/docs/Virtualization/content.mdx
@@ -27,11 +27,10 @@ window). Directly inside that container, add a content wrapper that holds all
diff/file instances and any other content you render. The virtualizer uses this
wrapper to track content size changes.
-Inside that scroll container, render the `VirtualizedFile` and
-`VirtualizedFileDiff` components. In React, this is handled automatically by the
-built-in `Virtualizer` context. In vanilla JS, you manage this explicitly by
-creating a `Virtualizer` instance and wiring it to `VirtualizedFile` /
-`VirtualizedFileDiff` instead of the traditional APIs.
+Inside that scroll container, render file and diff components. In React and Vue,
+this is handled automatically by the built-in `Virtualizer` provider. In vanilla
+JS, you manage this explicitly by creating a `Virtualizer` instance and wiring
+it to `VirtualizedFile` / `VirtualizedFileDiff` instead of the traditional APIs.
}>
These APIs are still early and are subject to change. We may merge related
@@ -39,14 +38,13 @@ creating a `Virtualizer` instance and wiring it to `VirtualizedFile` /
components before shipping, so please share feedback as you test these APIs.
-### React
+### React and Vue
In React, wrap your diff/file components in `Virtualizer` from
-`@pierre/diffs/react`. The `Virtualizer` component is your scroll container.
-Currently, the React wrapper does not support window scrolling unless you
-orchestrate your own provider via `VirtualizerContext.Provider` (from
-`@pierre/diffs/react`) and pass a manually created `Virtualizer` instance (from
-`@pierre/diffs`).
+`@pierre/diffs/react`. In Vue, use `Virtualizer` from `@pierre/diffs/vue`. The
+`Virtualizer` component is your scroll container. Currently, framework wrappers
+do not support window scrolling unless you orchestrate your own provider and
+pass a manually created `Virtualizer` instance from `@pierre/diffs`.
@@ -61,6 +59,9 @@ You can tune virtualization behavior with the `config` prop.
- `className` / `style`: applied to the outer scroll root
- `contentClassName` / `contentStyle`: applied to the inner content wrapper
+In Vue templates, use `class` / `style` on the outer component and
+`content-class` / `content-style` for the inner content wrapper.
+
### Vanilla JavaScript
In vanilla JS, create a `Virtualizer` instance and pass it into
diff --git a/apps/docs/app/(diffs)/docs/VueAPI/constants.ts b/apps/docs/app/(diffs)/docs/VueAPI/constants.ts
new file mode 100644
index 000000000..11a846968
--- /dev/null
+++ b/apps/docs/app/(diffs)/docs/VueAPI/constants.ts
@@ -0,0 +1,149 @@
+import type { PreloadFileOptions } from '@pierre/diffs/ssr';
+
+export const VUE_API_MULTI_FILE_DIFF: PreloadFileOptions = {
+ file: {
+ name: 'multi-file-diff.vue',
+ contents: `
+
+
+
+`,
+ },
+};
+
+export const VUE_API_PATCH_DIFF: PreloadFileOptions = {
+ file: {
+ name: 'patch-diff.vue',
+ contents: `
+
+
+
+`,
+ },
+};
+
+export const VUE_API_SLOTS: PreloadFileOptions = {
+ file: {
+ name: 'annotated-diff.vue',
+ contents: `
+
+
+
+
+ {{ fileDiff.name }}
+
+
+