Skip to content

React

Terminal window
npm install @updog/data-editor

Import the component and its styles:

import { DataEditor } from "@updog/data-editor";
import "@updog/data-editor/styles.css";
import { useState } from "react";
import { DataEditor } from "@updog/data-editor";
import "@updog/data-editor/styles.css";
import type { DataEditorColumn } from "@updog/data-editor";
type Employee = {
id: string;
name: string;
email: string;
role: string;
};
const columns: DataEditorColumn[] = [
{ id: "name", title: "Full Name", size: 200, validators: [{ type: "required", message: "Name is required" }] },
{ id: "email", title: "Email", size: 250, validators: [{ type: "required", message: "Email is required" }, { type: "email", message: "Invalid email" }] },
{ id: "role", title: "Role", editor: { type: "select", options: ["Admin", "Editor", "Viewer"] } },
];
export function App() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Open Editor</button>
<DataEditor<Employee>
apiKey="your-license-key"
open={open}
onClose={() => setOpen(false)}
columns={columns}
primaryKey="id"
loadData={async (onChunk) => {
const res = await fetch("/api/employees");
const rows = await res.json();
onChunk(rows);
}}
onComplete={async (result) => {
console.log("Sources:", result.sources);
console.log("Counts:", result.counts);
}}
/>
</>
);
}

DataEditor accepts a generic type parameter for row data. This gives you type-safe access to primaryKey and the result rows in onComplete.

type Employee = { id: string; name: string; email: string };
<DataEditor<Employee>
primaryKey="id"
// ...
/>

When you omit the generic, rows are typed as Record<string, unknown>.