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
2 changes: 0 additions & 2 deletions apps/docs/app/(diffs)/_edit/EditHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
import { IconArrowRight, IconBook } from '@pierre/icons';
import Link from 'next/link';

import { BetaBadge } from '@/components/BetaBadge';
import { Button } from '@/components/ui/button';

export function EditHero() {
return (
<section className="mb-8 flex flex-col items-center justify-between gap-6 border-b pt-16 pb-8 md:mb-12 md:flex-row md:gap-12 md:pb-12">
<div className="flex max-w-3xl flex-col gap-3 lg:max-w-4xl">
<BetaBadge className="self-start" size="large" />
<h1 className="text-3xl font-semibold tracking-tight text-balance md:text-4xl lg:text-5xl">
Edit files and diffs
</h1>
Expand Down
1 change: 0 additions & 1 deletion apps/docs/app/(diffs)/_home/AgentDemoSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export function AgentDemoSection({ prerenderedDiffs }: AgentDemoSectionProps) {
<div className="space-y-5">
<FeatureHeader
id="edit"
isBeta
title="Edit diffs and code"
description={
<>
Expand Down
100 changes: 100 additions & 0 deletions apps/docs/app/(diffs)/_home/HighlightsBanner.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
.banner {
--highlights-banner-surface: var(--background);

display: grid;
min-width: 0;
padding: calc(var(--spacing) * 6);
padding-bottom: 0;
margin-bottom: calc(var(--spacing) * 16);
overflow: hidden;
color: var(--color-foreground);
border-radius: var(--radius-xl);
box-shadow:
var(--tw-inset-shadow), var(--tw-inset-ring-shadow),
var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--shadow-sm);
gap: calc(var(--spacing) * 8);
}

/* Match the shared card's translucent dark-page surface after compositing it. */
/* stylelint-disable-next-line selector-pseudo-class-no-unknown */
:global(:root.dark) .banner {
--highlights-banner-surface: color-mix(
in oklch,
var(--muted) 50%,
var(--background)
);
}

@media (width >= 640px) {
.banner {
padding: calc(var(--spacing) * 8);
padding-bottom: 0;
}
}

@media (width >= 768px) {
.banner {
grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
align-items: center;
gap: calc(var(--spacing) * 6);
}
}

@media (width >= 1024px) {
.banner {
grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
padding-top: calc(var(--spacing) * 12);
padding-inline: calc(var(--spacing) * 12);
gap: calc(var(--spacing) * 10);
}
}

.benchmarkStage {
position: relative;
min-width: 0;
padding: 0.5rem;
overflow: hidden;
border-radius: var(--radius);
}

.benchmarkCard {
position: relative;
z-index: 1;
inline-size: 100%;
max-inline-size: 33.75rem;
margin-inline: auto;
background-color: color-mix(in oklch, var(--background) 82%, transparent);
box-shadow:
0 24px 48px -24px rgb(0 0 0 / 95%),
inset 0 1px 0 rgb(255 255 255 / 5%);
}

.benchmarkStage::after {
position: absolute;
z-index: 2;
inset-inline: 0.5rem;
bottom: 0;
block-size: 10rem;
pointer-events: none;
content: '';
background: linear-gradient(
to bottom,
transparent,
color-mix(in oklch, var(--highlights-banner-surface) 55%, transparent) 58%,
var(--highlights-banner-surface) 90%
);
-webkit-backdrop-filter: blur(0.375rem);
backdrop-filter: blur(0.375rem);
-webkit-mask-image: linear-gradient(
to bottom,
transparent,
rgb(0 0 0 / 35%) 38%,
black 78%
);
mask-image: linear-gradient(
to bottom,
transparent,
rgb(0 0 0 / 35%) 38%,
black 78%
);
}
103 changes: 103 additions & 0 deletions apps/docs/app/(diffs)/_home/HighlightsBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { IconArrowRight } from '@pierre/icons';
import Link from 'next/link';

import { BenchmarkBar } from '../highlights/BenchmarkBar';
import cardStyles from '../highlights/HighlightsBenchmarkCard.module.css';
import rainbowStyles from '../highlights/HighlightsRainbow.module.css';
import {
HIGHLIGHTS_LARGE_FILE_RESULTS,
HIGHLIGHTS_THROUGHPUT_MAXIMUM,
} from '../highlights/performanceBenchmarkData';
import styles from './HighlightsBanner.module.css';
import { Button } from '@/components/ui/button';

export function HighlightsBanner() {
return (
<div className={`${cardStyles.card} ${styles.banner} dark`}>
<div className="min-w-0 md:pb-12">
<p className="mb-1 text-xl leading-tight font-medium tracking-tight sm:text-2xl md:text-xl lg:text-2xl">
Introducing
</p>
<h2 className="text-4xl leading-none font-semibold tracking-tight sm:text-5xl md:text-4xl lg:text-5xl">
<span className="relative block w-fit">
<span
aria-hidden="true"
className={`${rainbowStyles.heroRainbow} pointer-events-none absolute inset-0 bg-clip-text text-transparent opacity-20 blur-[16px] select-none dark:opacity-60`}
>
Highlights
</span>
<span
className={`${rainbowStyles.heroRainbow} relative bg-clip-text text-transparent`}
>
Highlights
</span>
</span>
</h2>
<p className="text-muted-foreground text-md mt-2 mb-0 max-w-3xl text-pretty lg:text-lg">
Super-fast syntax highlighting for code and diffs, written from the
ground up to be nearly 300× faster than Shiki. Now in beta.
</p>
<Button
asChild
size="lg"
className="group text-md mt-5 h-10 px-4 md:h-12 md:px-6 lg:text-lg"
variant="inverse"
>
<Link href="/highlights">
Get started
<IconArrowRight className="-mr-1 transition-transform duration-150 ease-out group-hover:translate-x-0.5 motion-reduce:transform-none motion-reduce:transition-none" />
</Link>
</Button>
</div>

<CompactPerformancePreview />
</div>
);
}

// Keeps the benchmark recognizable while hiding duplicate chart data from
// assistive technology; the promo copy and button carry the actionable content.
function CompactPerformancePreview() {
return (
<div aria-hidden="true" className={styles.benchmarkStage}>
<figure
className={`${cardStyles.card} ${styles.benchmarkCard} dark text-foreground -mb-4 min-w-0 rounded-lg border border-white/10 p-4 sm:p-5 md:-mb-6`}
>
<figcaption className="mb-4">
<h3 className="text-sm font-semibold tracking-tight sm:text-base">
Super-fast HTML generation
</h3>
<p className="text-muted-foreground mt-1 mb-0 max-w-md text-xs leading-5 text-pretty">
Highlights generates HTML at up to 294 times faster than Shiki’s
throughput across these fixtures.
</p>
</figcaption>
<dl className="space-y-3">
{HIGHLIGHTS_LARGE_FILE_RESULTS.map(({ language, size, speedup }) => (
<div
key={language}
className="grid grid-cols-[minmax(0,1fr)_3.5rem] items-center gap-x-3 gap-y-1"
>
<dt className="text-muted-foreground col-start-1 row-start-2 flex items-baseline gap-1.5 text-xs">
<span className="text-foreground font-medium">{language}</span>
<span>{size}</span>
</dt>
<dd className="contents">
<div className="col-start-1 row-start-1">
<BenchmarkBar
value={speedup}
maximum={HIGHLIGHTS_THROUGHPUT_MAXIMUM}
highlighted
/>
</div>
<span className="tabular-num col-start-2 row-span-2 row-start-1 -mt-1.75 self-start text-right text-lg font-semibold">
{speedup}×
</span>
</dd>
</div>
))}
</dl>
</figure>
</div>
);
}
2 changes: 2 additions & 0 deletions apps/docs/app/(diffs)/_home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { SplitUnified } from '../_examples/SplitUnified/SplitUnified';
import { TOKEN_HOVER_EXAMPLE } from '../_examples/TokenHover/constants';
import { TokenHover } from '../_examples/TokenHover/TokenHover';
import { AgentDemoSection } from './AgentDemoSection';
import { HighlightsBanner } from './HighlightsBanner';
import { preloadAuiPrerenderedDiffs } from './preloadAuiDiffs';
import { HeadingAnchors } from '@/components/docs/HeadingAnchors';
import Footer from '@/components/Footer';
Expand All @@ -48,6 +49,7 @@ export default function Home() {
<Hero productId={PRODUCT_ID} />
<HeadingAnchors />
<section className="space-y-12 pb-8">
<HighlightsBanner />
<EditSection />
<SplitUnifiedSection />
<DiffStylesSection />
Expand Down
4 changes: 0 additions & 4 deletions apps/docs/app/(diffs)/docs/Edit/content.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
## Edit mode

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove Edit mode from the beta heading set

On /docs, this heading is still matched by BETA_DOC_HEADING_IDS in apps/docs/lib/mdx.tsx, which continues to append a Beta badge to the heading; DocsSidebar detects that badge and mirrors it in navigation. As a result, removing this warning and the other badges does not actually graduate Edit across the docs UI, so remove edit-mode from that set as part of this change.

Useful? React with 👍 / 👎.


<Notice variant="warning" icon={<IconCiWarningFill />}>
Edit mode is experimental and subject to change.
</Notice>

Edit mode adds text editing, multiple selections, undo and redo, search and
replace, remote carets, markers, and custom selection actions to Pierre file and
diff components. The existing component continues to own syntax highlighting,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,18 @@ import type { ReactNode } from 'react';

import { BenchmarkBar } from './BenchmarkBar';
import styles from './HighlightsBenchmarkCard.module.css';
import {
HIGHLIGHTS_LARGE_FILE_RESULTS,
HIGHLIGHTS_THROUGHPUT_MAXIMUM,
} from './performanceBenchmarkData';
import { cn } from '@/lib/utils';

// Published string-I/O results from packages/highlights/benchmark/README.md,
// recorded September 25, 2026. Keep the reported ratios rather than deriving
// them from the table's independently rounded throughput values.
const largeFileResults = [
{
language: 'TypeScript',
size: '517 KiB',
speedup: 294,
},
{
language: 'HTML',
size: '474 KiB',
speedup: 237,
},
{
language: 'CSS',
size: '379 KiB',
speedup: 248,
},
{
language: 'JSONC',
size: '292 KiB',
speedup: 148,
},
];

const memoryResults = [
{ name: 'Highlights', peakRss: 49 },
{ name: 'Shiki JS', peakRss: 155 },
{ name: 'Shiki Wasm', peakRss: 346 },
];

const throughputMaximum = 300;
const memoryMaximum = 400;

// Renders different benchmark units against an explicit zero-based maximum.
Expand Down Expand Up @@ -117,24 +94,26 @@ export function HighlightsPerformanceBenchmarks() {
</p>
</figcaption>
<div className="space-y-5">
{largeFileResults.map(({ language, size, speedup }) => (
<dl key={language}>
<PerformanceBar
name={
<span className="flex items-baseline gap-2 text-sm">
<span className="text-foreground font-medium">
{language}
{HIGHLIGHTS_LARGE_FILE_RESULTS.map(
({ language, size, speedup }) => (
<dl key={language}>
<PerformanceBar
name={
<span className="flex items-baseline gap-2 text-sm">
<span className="text-foreground font-medium">
{language}
</span>
<span>{size}</span>
</span>
<span>{size}</span>
</span>
}
value={speedup}
maximum={throughputMaximum}
formatValue={(value) => `${value}×`}
highlights
/>
</dl>
))}
}
value={speedup}
maximum={HIGHLIGHTS_THROUGHPUT_MAXIMUM}
formatValue={(value) => `${value}×`}
highlights
/>
</dl>
)
)}
</div>
</figure>

Expand Down
27 changes: 27 additions & 0 deletions apps/docs/app/(diffs)/highlights/performanceBenchmarkData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Published string-I/O results from packages/highlights/benchmark/README.md,
// recorded September 25, 2026. Keep the reported ratios rather than deriving
// them from the table's independently rounded throughput values.
export const HIGHLIGHTS_LARGE_FILE_RESULTS = [
{
language: 'TypeScript',
size: '517 KiB',
speedup: 294,
},
{
language: 'HTML',
size: '474 KiB',
speedup: 237,
},
{
language: 'CSS',
size: '379 KiB',
speedup: 248,
},
{
language: 'JSONC',
size: '292 KiB',
speedup: 148,
},
] as const;

export const HIGHLIGHTS_THROUGHPUT_MAXIMUM = 300;
2 changes: 2 additions & 0 deletions apps/docs/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const buttonVariants = cva(
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
inverse:
'bg-white text-neutral-950 hover:bg-neutral-200 active:bg-neutral-300 focus-visible:border-white focus-visible:ring-white/50 dark:bg-white dark:text-neutral-950 dark:hover:bg-neutral-200 dark:active:bg-neutral-300 dark:focus-visible:border-white dark:focus-visible:ring-white/50',
success:
'bg-teal-500 text-white hover:bg-teal-500/90 focus-visible:ring-teal-500/20 dark:focus-visible:ring-green-500/40 dark:bg-green-500/60',
destructive:
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/lib/product-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export const PRODUCTS: Record<ProductId, ProductConfig> = {
name: 'Diffs',
tagline: 'Render diffs and\u00A0code, now with edit',
description:
'@pierre/diffs is an open source diff and code rendering library. Built on Shiki for syntax highlighting and theming, super customizable, and packed with features.',
'@pierre/diffs is an open source diff and code rendering library. Rich syntax highlighting, edit mode, support for custom and Shiki themes, virtualization, and more.',
llmsDescription:
'An open source diff and code rendering library for the web. Built on Shiki for syntax highlighting, with React and vanilla JS APIs, virtualization, SSR support, and extensive theming.',
'An open source diff and code rendering library with rich syntax highlighting, edit mode, support for custom and Shiki themes, virtualization, and more. Available with React and vanilla JS APIs',
basePath: '',
docsPath: '/docs',
themePath: '/theme',
Expand Down