@updog/data-editor 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +75 -34
- package/index.js +2329 -2326
- package/package.json +1 -1
- package/assets/chatTransform.worker-xnO1PFUC.js +0 -1
- package/assets/filter.worker-Dtii7NzO.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to `@updog/data-editor` and `@updog/data-editor-wc` are docu
|
|
|
4
4
|
|
|
5
5
|
This project follows [Semantic Versioning](https://semver.org/). While the version is `0.x`, minor version bumps may include breaking changes; we will call them out explicitly.
|
|
6
6
|
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **Workers inlined as blob URLs.** Internal change: `filter` and `chatTransform` workers now ship inlined in the main bundle and spawn via `URL.createObjectURL`. Resolves loading failures in Next.js 16 / Turbopack and other non-Vite consumers. Adds ~27 KB to the main bundle (minified worker source, no source maps). Requires `worker-src blob:` in any strict Content-Security-Policy.
|
|
12
|
+
|
|
7
13
|
## [0.1.0] — 2026-04-21
|
|
8
14
|
|
|
9
15
|
First public release.
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ npm install @updog/data-editor
|
|
|
29
29
|
|
|
30
30
|
```tsx
|
|
31
31
|
import { useState } from "react";
|
|
32
|
-
import { DataEditor
|
|
32
|
+
import { DataEditor } from "@updog/data-editor";
|
|
33
33
|
import "@updog/data-editor/styles.css";
|
|
34
34
|
import type { DataEditorColumn } from "@updog/data-editor";
|
|
35
35
|
|
|
@@ -41,9 +41,26 @@ type Employee = {
|
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
const columns: DataEditorColumn[] = [
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
{
|
|
45
|
+
id: "name",
|
|
46
|
+
title: "Full Name",
|
|
47
|
+
size: 200,
|
|
48
|
+
validators: [{ type: "required", message: "Name is required" }],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "email",
|
|
52
|
+
title: "Email",
|
|
53
|
+
size: 250,
|
|
54
|
+
validators: [
|
|
55
|
+
{ type: "required", message: "Email is required" },
|
|
56
|
+
{ type: "email", message: "Invalid email" },
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "role",
|
|
61
|
+
title: "Role",
|
|
62
|
+
editor: { type: "select", options: ["Admin", "Editor", "Viewer"] },
|
|
63
|
+
},
|
|
47
64
|
];
|
|
48
65
|
|
|
49
66
|
export function App() {
|
|
@@ -147,7 +164,6 @@ In inline mode, `open` and `onClose` don't apply.
|
|
|
147
164
|
## Column Configuration
|
|
148
165
|
|
|
149
166
|
```tsx
|
|
150
|
-
import { required, email } from "@updog/data-editor";
|
|
151
167
|
import type { DataEditorColumn } from "@updog/data-editor";
|
|
152
168
|
|
|
153
169
|
const columns: DataEditorColumn[] = [
|
|
@@ -156,8 +172,11 @@ const columns: DataEditorColumn[] = [
|
|
|
156
172
|
title: "Email",
|
|
157
173
|
size: 260,
|
|
158
174
|
|
|
159
|
-
//
|
|
160
|
-
|
|
175
|
+
// Declarative validators. See "Built-in Validators" for the full list.
|
|
176
|
+
validators: [
|
|
177
|
+
{ type: "required", message: "Email is required" },
|
|
178
|
+
{ type: "email", message: "Enter a valid email" },
|
|
179
|
+
],
|
|
161
180
|
|
|
162
181
|
// Flag duplicates in this column as errors.
|
|
163
182
|
unique: true,
|
|
@@ -189,36 +208,42 @@ const columns: DataEditorColumn[] = [
|
|
|
189
208
|
|
|
190
209
|
## Built-in Validators
|
|
191
210
|
|
|
192
|
-
Validators are
|
|
211
|
+
Validators are declarative objects passed in the `validators` array on each column. The SDK ships a TS interpreter for the client; Updog Scale ships a matching Go interpreter for server mode. Both runtimes are pinned to the same fixture set, so a column definition produces identical pass/fail results regardless of where it runs.
|
|
212
|
+
|
|
213
|
+
| `type` | Fields | Behavior |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| `"required"` | `message?` | Value must be non-empty. |
|
|
216
|
+
| `"email"` | `message?` | Value must look like an email address. |
|
|
217
|
+
| `"numeric"` | `message?` | Value must parse as a number. Commas are stripped before parsing. |
|
|
218
|
+
| `"regex"` | `pattern`, `flags?`, `message?` | Value must match the regular expression. Empty values are skipped. |
|
|
219
|
+
| `"range"` | `min?`, `max?`, `message?` | Value must be numerically within `[min, max]`. Either bound is optional. |
|
|
220
|
+
| `"oneOf"` | `values: string[]`, `message?` | Value must be one of the listed strings. |
|
|
221
|
+
| `"date"` | `format?: "YYYY-MM-DD" \| "DD/MM/YYYY"`, `message?` | Value must parse as a date in the given format. When `format` is omitted, either format is accepted. |
|
|
193
222
|
|
|
194
223
|
```tsx
|
|
195
|
-
|
|
196
|
-
required,
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
{ id: "
|
|
206
|
-
{
|
|
207
|
-
|
|
208
|
-
|
|
224
|
+
const columns: DataEditorColumn[] = [
|
|
225
|
+
{ id: "name", title: "Name", validators: [{ type: "required", message: "Required" }] },
|
|
226
|
+
{
|
|
227
|
+
id: "email",
|
|
228
|
+
title: "Email",
|
|
229
|
+
validators: [
|
|
230
|
+
{ type: "required", message: "Required" },
|
|
231
|
+
{ type: "email", message: "Invalid email" },
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
{ id: "salary", title: "Salary", validators: [{ type: "numeric", message: "Must be a number" }] },
|
|
235
|
+
{
|
|
236
|
+
id: "status",
|
|
237
|
+
title: "Status",
|
|
238
|
+
validators: [{ type: "oneOf", values: ["active", "inactive"], message: "Invalid status" }],
|
|
239
|
+
},
|
|
209
240
|
{
|
|
210
241
|
id: "startDate",
|
|
211
242
|
title: "Start",
|
|
212
|
-
|
|
243
|
+
validators: [{ type: "date", format: "YYYY-MM-DD", message: "Use YYYY-MM-DD" }],
|
|
213
244
|
editor: { type: "date" },
|
|
214
245
|
dependentFields: ["endDate"],
|
|
215
246
|
},
|
|
216
|
-
{
|
|
217
|
-
id: "endDate",
|
|
218
|
-
title: "End",
|
|
219
|
-
validate: [date("Invalid date"), endDateAfterStart("startDate", "End must be on or after start")],
|
|
220
|
-
editor: { type: "date" },
|
|
221
|
-
},
|
|
222
247
|
];
|
|
223
248
|
```
|
|
224
249
|
|
|
@@ -226,18 +251,34 @@ A `ValidationError` with `level: "error"` flags the cell in the grid but does **
|
|
|
226
251
|
|
|
227
252
|
### Custom validators
|
|
228
253
|
|
|
229
|
-
|
|
254
|
+
For cross-field checks or anything not covered by the built-ins, wrap a `CellValidator` function in `{ type: "function", fn }`. Function validators are client-mode only — they're dropped (with a one-time warning) when the SDK serializes the schema for server mode. Use `dependentFields` on the column to trigger re-validation when another column changes.
|
|
230
255
|
|
|
231
256
|
```tsx
|
|
232
|
-
import type { CellValidator } from "@updog/data-editor";
|
|
257
|
+
import type { CellValidator, DataEditorColumn } from "@updog/data-editor";
|
|
233
258
|
|
|
234
|
-
const
|
|
235
|
-
if (!value) return null;
|
|
236
|
-
if (
|
|
259
|
+
const endAfterStart: CellValidator = (value, row) => {
|
|
260
|
+
if (!value || !row.startDate) return null;
|
|
261
|
+
if (String(value) < String(row.startDate)) {
|
|
262
|
+
return { level: "error", message: "End must be on or after start" };
|
|
263
|
+
}
|
|
237
264
|
return null;
|
|
238
265
|
};
|
|
266
|
+
|
|
267
|
+
const columns: DataEditorColumn[] = [
|
|
268
|
+
{
|
|
269
|
+
id: "endDate",
|
|
270
|
+
title: "End",
|
|
271
|
+
editor: { type: "date" },
|
|
272
|
+
validators: [
|
|
273
|
+
{ type: "date", message: "Invalid date" },
|
|
274
|
+
{ type: "function", fn: endAfterStart },
|
|
275
|
+
],
|
|
276
|
+
},
|
|
277
|
+
];
|
|
239
278
|
```
|
|
240
279
|
|
|
280
|
+
The only `level` is `"error"`. Return `null` to indicate the value is valid.
|
|
281
|
+
|
|
241
282
|
## Data Loading
|
|
242
283
|
|
|
243
284
|
`loadData` is called once when the editor opens. Call `onChunk` one or more times to stream rows. The grid renders each chunk without blocking.
|