gridcn1.2.2

Async validation

Schemas that resolve asynchronously. Pending editor state, supersede on newer commits, and the batched bulk paths.

The demo's SKU column runs a fake uniqueness check with ~800 ms latency (a hand-rolled Standard Schema whose validate returns a Promise: the same seam as an async Zod refine). SKU-001 and SKU-002 are already taken.

  • Age must be 18 or older (sync function)
  • Email must contain an @ (sync Standard Schema)
  • SKU must be unique — SKU-001 and SKU-002 are taken; the check takes ~800ms (async Standard Schema)
  • Price must be a number — decimals commit as the rounded integer (transforming schema)
  • Notes max 12 characters, SOFT (onInvalid: 'warn') — the value commits and the cell stays flagged; a short re-commit clears it
  • Zod Score integer 0–100 — zod: z.number().int().min(0).max(100)
  • Joi Code uppercase letters, digits, or dashes — joi: .pattern(/^[A-Z0-9-]+$/)
  • Valibot Tag at least 3 characters — valibot: v.pipe(v.string(), v.minLength(3))

Type a value that breaks a rule and press Enter: the editor stays open with the message under the cell, and the Age rule also fires a toast (from inside its own validate function). Or copy a column of ages (some under 18) from any spreadsheet and paste it onto Age: valid cells commit, invalid ones drop. Notes is the opposite: onInvalid: "warn" commits the value anyway and flags the cell (hover it for the message).

Name
Age
Email
SKU
Price
Notes
Zod Score
Joi Code
Valibot Tag
Ada Lovelace
28
ada@example.com
SKU-101
42
First algorithm
87
ADA-1843
math
Grace Hopper
34
grace@example.com
SKU-102
18
Compiled it
94
GRACE-1906
compilers
Alan Turing
41
alan@example.com
SKU-103
99
Broke Enigma
99
TURING-1912
computability
Katherine Johnson
25
katherine@example.com
SKU-104
7
Trajectory math
91
KATH-1918
orbital
Margaret Hamilton
22
margaret@example.com
SKU-105
56
Apollo nav
96
MARG-1936
software
Radia Perlman
30
radia@example.com
SKU-106
31
Spanning trees
88
RADIA-1951
networking
Tim Berners-Lee
19
tim@example.com
SKU-107
64
Invented the web
98
TIM-1955
web
Barbara Liskov
45
barbara@example.com
SKU-108
12
Subtyping
93
BARB-1939
types
pnpm dlx shadcn@latest add @gridcn/data-grid-validation-demo

Single-cell edit

Type a SKU and press Enter:

  • The editor stays open while the schema resolves. The built-in text/number editors mark their input readOnly as the pending treatment. Never disabled, so Escape still cancels.
  • Resolving with issues shows the rejection message exactly like a sync rejection. Editing continues.
  • Resolving successfully commits the schema's result.value, then applies the pending cell-to-cell movement.
  • Escape, a newer commit, or unmounting the cell invalidates the in-flight validation: its resolution is dropped silently and never applied late. That is the supersede rule: a stale verdict can never land on a cell the user has already moved on from.

Bulk paths

Paste, fill, CSV/XLSX import, and updateCells hold the batch while the schema resolves:

  • The grid validates a maximum of 32 cells at the same time. A paste of 10,000 cells makes 32 concurrent calls, not 10,000.
  • Nothing changes until every verdict is in. The accepted cells then commit together as one onDataChange operations batch.
  • A rejected cell drops. One bad value never fails the batch. Paste and fill report it through onValidationError when you pass one.
  • A newer operation supersedes a held batch: a second paste over the same area, a data change, a sort/filter change, or unmounting the grid drops the older batch silently.
  • The import dialog keeps its Import button disabled while it validates. Cancel or closing aborts the build.

A slow schema makes a slow batch

A held batch is only as fast as your schema: 200 ms per cell across 10,000 cells takes about 60 s at 32 concurrent calls, and the grid gives no per-cell progress. For a large paste against a remote check, validate the block yourself with the processPaste override (Clipboard): one request for the whole block.

Trusted feeds can skip validation

actions.updateCells(patches, { skipValidation: true }) bypasses validate completely. Use it when the producer already validated the values.

Behavior reference

On this page