Core Props
Every prop <DataEditor /> accepts.
| Prop | Type | Default |
|---|---|---|
apiKey |
string |
Required |
blockSubmitOnError |
boolean |
false |
chat |
DataEditorChat |
— |
className |
string |
— |
columns |
DataEditorColumn[] |
Required |
enableAddRow |
boolean |
true |
enableAddSource |
boolean |
true |
enableCreateColumn |
boolean |
true |
enableDeleteRow |
"all" | "new" | false |
false |
exportFormats |
DataEditorFormat[] | false |
All formats |
headerHeight |
number |
36 |
importFormats |
DataEditorFormat[] | false |
All formats |
loadData |
(onChunk) => Promise<void> |
— |
locale |
string |
"en" |
localStorage |
false | { licenseGrant?: boolean } |
{ licenseGrant: true } |
mode |
"modal" | "inline" |
"modal" |
onClose |
() => void |
Modal mode only |
onColumnMatch |
(headers, columns) => map |
— |
onComplete |
(result) => void | Promise<void> |
— |
onError |
(error: UpdogError) => void |
— |
onValueMatch |
(valuesToMatch) => map |
— |
open |
boolean |
Modal mode only |
primaryKey |
keyof TRow | readonly (keyof TRow)[] |
Required |
readonly |
boolean |
false |
remoteSources |
RemoteSource[] |
— |
rowHeight |
number |
34 |
rtl |
boolean |
false |
sampleData |
Record<string, unknown>[] |
— |
synonyms |
{ columns?, values? } |
— |
translations |
DataEditorTranslations |
— |
variant |
"editor" | "uploader" | "viewer" |
"editor" |
apiKey
Section titled “apiKey”| Type | string |
| Required | Yes |
Your Updog license key. The SDK validates it every time the editor opens.
<DataEditor apiKey="your-license-key" ... />blockSubmitOnError
Section titled “blockSubmitOnError”| Type | boolean |
| Default | false |
Disables the submit button while any row has a validation error. When false, errors are flagged but the user can still submit.
When set, submission is also blocked while remote checks are in flight (isAsyncValidating), so a value that is about to come back “already exists” cannot slip through. Remote checks give up after 60 seconds without activity, so this gating always releases. When unset (the default), in-flight checks never block submission and unresolved cells pass through as unverified.
<DataEditor blockSubmitOnError ... />| Type | DataEditorChat<TRow> |
Bring-your-own-AI chat. When provided, the editor shows a chat panel alongside the grid. You own the AI integration. The SDK hands you dataset context and renders the streamed response.
See Bring Your Own AI.
className
Section titled “className”| Type | string |
CSS class added to the wrapper element. Use for scoped styling overrides.
columns
Section titled “columns”| Type | DataEditorColumn[] |
| Required | Yes |
The schema your app expects. Each column defines an id, a title, and optionally an editor, validators, a transformer, a formatter, and a filter.
See Columns for every column-level prop.
enableAddRow
Section titled “enableAddRow”| Type | boolean |
| Default | true |
Controls whether users can add rows by hand. When true, the data sources panel shows an “Add row” button, and the row context menu offers Insert row above, Insert row below, and Duplicate row. When false, every one of those entry points is hidden, and the user edits existing rows or imports data instead.
<DataEditor enableAddRow={false} ... />enableAddSource
Section titled “enableAddSource”| Type | boolean |
| Default | true |
Controls whether the “Add data source” button appears in the data sources panel. When false, the button is hidden, and the panel no longer opens the add-source menu (import data, add row).
<DataEditor enableAddSource={false} ... />enableCreateColumn
Section titled “enableCreateColumn”| Type | boolean |
| Default | true |
Allow creating new columns for unmatched headers during import. When enabled, users can keep data from file columns that do not match your schema.
See enableCreateColumn.
enableDeleteRow
Section titled “enableDeleteRow”| Type | "all" | "new" | false |
| Default | false |
Controls row deletion through the right-click context menu.
falsedisables deletion."new"allows deleting rows the user added by hand or imported."all"allows deleting any row.
<DataEditor enableDeleteRow="all" ... />exportFormats
Section titled “exportFormats”| Type | DataEditorFormat[] | false |
| Default | All formats |
Which file formats the user can export to. Set to false to disable export entirely.
<DataEditor exportFormats={["csv", "xlsx"]} ... />See DataEditorFormat for the full list of formats.
headerHeight
Section titled “headerHeight”| Type | number |
| Default | 36 |
Header row height in pixels.
importFormats
Section titled “importFormats”| Type | DataEditorFormat[] | false |
| Default | All formats |
Which file formats the user can import. Set to false to disable import entirely.
See importFormats.
loadData
Section titled “loadData”| Type | (onChunk) => Promise<void> |
Async function that feeds existing data into the editor. Called once when the editor opens. Call onChunk one or more times to stream rows in batches.
See Loading Data.
locale
Section titled “locale”| Type | string |
| Default | "en" |
BCP 47 locale tag used to pick plural forms. It does not load translations and it does not switch the language.
See locale.
localStorage
Section titled “localStorage”| Type | false | { licenseGrant?: boolean } |
| Default | { licenseGrant: true } |
Controls what the editor stores in localStorage. Set to false to switch off local storage entirely.
licenseGrant caches the license validation result so the editor skips re-validation on reload. It defaults to true. The grant is a signed token stored under the key updog_license_grant. See Data and Privacy for what it contains and what turning it off costs you.
| Type | "modal" | "inline" |
| Default | "modal" |
Rendering mode. "modal" wraps the editor in a full-screen dialog overlay. "inline" renders it directly in the DOM.
onClose
Section titled “onClose”| Type | () => void |
| Required | Modal mode only |
Called when the user closes the modal (X button or Escape key). If the user has unsaved changes, the SDK shows a confirmation dialog before calling onClose.
onColumnMatch
Section titled “onColumnMatch”| Type | (headers: string[], columns: DataEditorColumn[]) => Record<string, string | null> |
Override column matching during import. Return a map of fileHeader to column ID. Unmapped or null entries fall back to built-in matching.
See onColumnMatch.
onComplete
Section titled “onComplete”| Type | (result: DataEditorResult<TRow>) => void | Promise<void> |
Called when the user clicks Submit. Receives the edited data grouped by source.
See Submitting.
onError
Section titled “onError”| Type | (error: UpdogError) => void |
Called when the SDK catches an internal error. The SDK recovers where it can. Use this for logging and monitoring.
See Error Handling.
onValueMatch
Section titled “onValueMatch”| Type | (valuesToMatch: Record<string, ValueMatchInput>) => ValueMatchOutput |
Override value matching for select columns during import. Return a map of column ID to imported-value pairs.
See onValueMatch.
| Type | boolean |
| Required | Modal mode only |
Controls modal visibility. You own the state.
primaryKey
Section titled “primaryKey”| Type | keyof TRow | readonly (keyof TRow)[] |
| Required | Yes |
The column that uniquely identifies each row, like id or email.
<DataEditor<Employee> primaryKey="id" ... />Pass a list when identity takes several columns together, such as a customer number that repeats across branches or a SKU that repeats across suppliers. An imported row merges into an existing row only when every listed column matches. A row with an empty value in any part of the key merges with nothing and is added as new.
<DataEditor<Customer> primaryKey={["branch", "customerNo"]} ... />Values are compared after trimming surrounding whitespace. The comparison keeps case, so [email protected] and [email protected] are two different keys. Fold the case in a transformer on that column when the two should merge.
readonly
Section titled “readonly”| Type | boolean |
| Default | false |
When true, hides all editing UI. The grid becomes view-only.
remoteSources
Section titled “remoteSources”| Type | RemoteSource[] |
Your own remote data sources, rendered as buttons on the upload step. You own the integration. The SDK renders the button and processes the result of fetch().
See remoteSources.
rowHeight
Section titled “rowHeight”| Type | number |
| Default | 34 |
Row height in pixels.
| Type | boolean |
| Default | false |
Enable right-to-left layout. Affects grid direction, text alignment, scrollbar position, and the column order in exported files.
See rtl.
sampleData
Section titled “sampleData”| Type | Record<string, unknown>[] |
Sample rows included in the Download Example file offered by the import wizard. When omitted, the SDK generates one generic example row from your column definitions.
See sampleData.
synonyms
Section titled “synonyms”| Type | { columns?: Record<string, string[]>; values?: Record<string, string[]> } |
Extra aliases layered on top of the built-ins, in two tables. columns feeds column matching, values feeds value matching. Each key is the canonical target, and the array lists the aliases.
See synonyms.
translations
Section titled “translations”| Type | DataEditorTranslations |
Override any UI string. Pass a partial object. Only the keys you provide are replaced. This is the prop that changes the language.
See Localization.
variant
Section titled “variant”| Type | "editor" | "uploader" | "viewer" |
| Default | "editor" |
Controls the initial view. "editor" opens directly to the spreadsheet grid. "uploader" opens the file import wizard first, where the user uploads one or more files, maps columns, and fixes errors before continuing to the grid. "viewer" renders the grid on its own, with no filters sidebar, footer, or chat. It stays read-only whatever you pass to readonly.
