mischief
exampleannotation-layer-demosource: ok · hit
Annotation Layer Demo
A worked example of Annotation Layer: Notes attached to regions of a page. Drag to add one, select to read it, and the coordinates stay relative to the page rather than the screen.
npx shadcn add "https://ui.tinkererslabs.com/r/annotation-layer-demo.json"free
Interaction
dragdropdown
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lightRegistry dependencies
https://ui.tinkererslabs.com/r/annotation-layer.json
Files2 · source cached 10/14/2026, 2:39:14 PM
components/demos/annotation-layer-demo.tsx
"use client"
import * as React from "react"
import { pageImage, paymentRegion } from "@/components/demos/document-fixtures"
import {
AnnotationLayer,
type Annotation,
} from "@/registry/default/annotation-layer/annotation-layer"
export function AnnotationLayerDemo() {
const [notes, setNotes] = React.useState<Annotation[]>([
{
id: "net30",
...paymentRegion,
note: "Finance asked whether this should be net 45.",
author: "Priya",
},
])
return (
<AnnotationLayer
className="w-full max-w-sm"
alt="Master Services Agreement, page 1"
annotations={notes}
src={pageImage}
onCreate={(rect) =>
setNotes((current) => [
...current,
{ id: `note-${current.length + 1}`, ...rect, note: "New note" },
])
}
onDelete={(id) =>
setNotes((current) => current.filter((note) => note.id !== id))
}
/>
)
}
components/demos/document-fixtures.ts
/** Generated from public/demo/documents/master-services-agreement.pdf. */
export const SAMPLE_PDF = "/demo/documents/master-services-agreement.pdf"
export const SAMPLE_DOCX = "/demo/documents/master-services-agreement.docx"
export const SAMPLE_CSV = "/demo/documents/invoices.csv"
export const PDF_WORKER = "/demo/pdf.worker.min.mjs"
export const PAGE_COUNT = 3
export const samplePages = Array.from({ length: PAGE_COUNT }, (_, index) => ({
number: index + 1,
src: `/demo/documents/page-${index + 1}.png`,
}))
export const pageImage = samplePages[0]!.src
/**
* Read out of the PDF text layer and checked by drawing them back onto the
* exported page, so every region sits on the value it names.
*/
export const invoiceBoxes = [
{
id: "customer",
label: "Customer",
x: 0.2979,
y: 0.1893,
width: 0.1397,
height: 0.022,
},
{
id: "agreement-no",
label: "Agreement number",
x: 0.2979,
y: 0.2484,
width: 0.125,
height: 0.022,
tone: "accent" as const,
},
{
id: "net30",
label: "Payment window",
x: 0.3247,
y: 0.6301,
width: 0.0553,
height: 0.0214,
},
{
id: "late-fee",
label: "Late payment",
x: 0.3247,
y: 0.6876,
width: 0.1011,
height: 0.0214,
tone: "warning" as const,
},
]
export const customerRegion = {
x: 0.2979,
y: 0.1893,
width: 0.1397,
height: 0.022,
}
export const agreementRegion = {
x: 0.2979,
y: 0.2484,
width: 0.125,
height: 0.022,
}
export const paymentRegion = {
x: 0.3247,
y: 0.6301,
width: 0.0553,
height: 0.0214,
}