@ai-matrx/records-ui 0.90.1 → 0.92.0
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 +58 -0
- package/dist/index.cjs +1426 -834
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -8
- package/dist/index.d.ts +40 -8
- package/dist/index.js +2608 -2012
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1192,6 +1192,10 @@ interface PersonPickerProps {
|
|
|
1192
1192
|
disabled?: boolean | undefined;
|
|
1193
1193
|
id?: string | undefined;
|
|
1194
1194
|
className?: string | undefined;
|
|
1195
|
+
/** A grid cell's picker opens at once (`FieldEditorControlProps.autoOpen`). */
|
|
1196
|
+
autoOpen?: boolean | undefined;
|
|
1197
|
+
/** The list closed: the cell commits who is picked. */
|
|
1198
|
+
onClose?: (() => void) | undefined;
|
|
1195
1199
|
}
|
|
1196
1200
|
/** A Person record in the kernel Table, as this picker needs to read it. */
|
|
1197
1201
|
interface PersonRecord {
|
|
@@ -1213,7 +1217,7 @@ declare function personRecordForMember(client: RecordsClient, personTableId: Uui
|
|
|
1213
1217
|
ok: false;
|
|
1214
1218
|
error: RecordsError;
|
|
1215
1219
|
}>;
|
|
1216
|
-
declare function PersonPicker({ field, value, onChange, disabled, id, className }: PersonPickerProps): react.JSX.Element;
|
|
1220
|
+
declare function PersonPicker({ field, value, onChange, disabled, id, className, autoOpen, onClose }: PersonPickerProps): react.JSX.Element;
|
|
1217
1221
|
|
|
1218
1222
|
/** Which cell is open. A grid opens exactly one at a time, like every other grid. */
|
|
1219
1223
|
interface CellAddress {
|
|
@@ -1246,14 +1250,16 @@ interface GridEditing {
|
|
|
1246
1250
|
* exactly that, replacing the value, as every spreadsheet does; a picker column opens as usual.
|
|
1247
1251
|
*/
|
|
1248
1252
|
begin: (address: CellAddress, seed?: string | null) => void;
|
|
1249
|
-
|
|
1253
|
+
/** `via`: a key (Escape) or a pointer (the picker's own close) — how the grid gets its keys back. */
|
|
1254
|
+
cancel: (via?: EditVia) => void;
|
|
1250
1255
|
/**
|
|
1251
1256
|
* Commit the open cell — whatever is in `draft`. `move` opens the
|
|
1252
1257
|
* next/previous editable cell after it. It takes NO value: a caller that
|
|
1253
1258
|
* passed one would be a second copy of the typed value, which is the defect
|
|
1254
1259
|
* this file's header describes.
|
|
1255
1260
|
*/
|
|
1256
|
-
|
|
1261
|
+
/** Answers `false` when the cell stayed open: typed words that are not a value (editors.tsx). */
|
|
1262
|
+
commit: (move?: "next" | "previous" | null, via?: EditVia) => boolean | void;
|
|
1257
1263
|
/**
|
|
1258
1264
|
* WRITE ONE CELL OUTRIGHT, with no editor ever opening.
|
|
1259
1265
|
*
|
|
@@ -1330,8 +1336,18 @@ interface Options {
|
|
|
1330
1336
|
before: unknown;
|
|
1331
1337
|
after: unknown;
|
|
1332
1338
|
}) => void) | undefined;
|
|
1339
|
+
/**
|
|
1340
|
+
* THE GRID GETS ITS KEYS BACK (merged-grid review 2026-09-26, A1). Bound, an editor that closes
|
|
1341
|
+
* by a key or a pick says so — Enter `down`, Tab `right` (Shift-Tab `left`), Escape and a pick
|
|
1342
|
+
* `stay` — and Tab no longer opens the next cell's editor: it commits and the CURSOR moves right,
|
|
1343
|
+
* as in Sheets and Airtable. A blur (a click elsewhere) says nothing: the click has the focus.
|
|
1344
|
+
* Unbound (the classic grid), Tab chains editors as before.
|
|
1345
|
+
*/
|
|
1346
|
+
onEnded?: ((exit: "down" | "right" | "left" | "stay", from: CellAddress, how: "keyboard" | "pointer") => void) | undefined;
|
|
1333
1347
|
}
|
|
1334
|
-
|
|
1348
|
+
/** How an open cell was closed: a key (Enter, Tab, Escape), the picker's own close, or a blur. */
|
|
1349
|
+
type EditVia = "key" | "pick" | "blur";
|
|
1350
|
+
declare function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWriteRow, onWritten, onEnded }: Options): GridEditing;
|
|
1335
1351
|
/**
|
|
1336
1352
|
* ONE CELL. Read, until somebody asks to change it; then the Field's own
|
|
1337
1353
|
* editor, in place, with the keys a person expects from a grid.
|
|
@@ -1805,8 +1821,14 @@ interface GridProps {
|
|
|
1805
1821
|
* the store compiles both into the one WHERE clause.
|
|
1806
1822
|
*/
|
|
1807
1823
|
filter?: StoreFilter$1 | undefined;
|
|
1808
|
-
/** Opened
|
|
1824
|
+
/** Opened from a row's handle, Space or the row menu. A host that has a record page passes its own. */
|
|
1809
1825
|
onOpenRecord?: ((recordId: Uuid) => void) | undefined;
|
|
1826
|
+
/**
|
|
1827
|
+
* THE RECORD THE HOST HAS OPEN BESIDE THE GRID, if any (merged grid). While one is open the panel
|
|
1828
|
+
* FOLLOWS the cursor: arrowing to another row opens that row (Airtable's expanded record walks
|
|
1829
|
+
* with the arrows), so the panel always shows the row the person is on.
|
|
1830
|
+
*/
|
|
1831
|
+
openRecordId?: Uuid | null | undefined;
|
|
1810
1832
|
/** SCR-2. Called when an admin clicks the "+" at the end of the headers. */
|
|
1811
1833
|
onAddField?: (() => void) | undefined;
|
|
1812
1834
|
/**
|
|
@@ -1867,7 +1889,7 @@ interface GridProps {
|
|
|
1867
1889
|
footer?: FooterPlacement | undefined;
|
|
1868
1890
|
className?: string | undefined;
|
|
1869
1891
|
}
|
|
1870
|
-
declare function Grid({ tableId, pageSize, filter, onOpenRecord, onAddField, onNewRecordForm, toolbarActions, editable, presentation, onPresentationChange, viewOrder, footer, className, onAskWhoChanged, }: GridProps): react.JSX.Element;
|
|
1892
|
+
declare function Grid({ tableId, pageSize, filter, onOpenRecord, openRecordId, onAddField, onNewRecordForm, toolbarActions, editable, presentation, onPresentationChange, viewOrder, footer, className, onAskWhoChanged, }: GridProps): react.JSX.Element;
|
|
1871
1893
|
|
|
1872
1894
|
/** Answers "what is the record with this id called", for one Field's values. */
|
|
1873
1895
|
type LabelLookup = (field: Field$1, id: string) => string | null;
|
|
@@ -2354,6 +2376,14 @@ interface FieldEditorControlProps {
|
|
|
2354
2376
|
onChange: (value: unknown) => void;
|
|
2355
2377
|
disabled?: boolean | undefined;
|
|
2356
2378
|
id?: string | undefined;
|
|
2379
|
+
/**
|
|
2380
|
+
* A GRID CELL'S PICKER OPENS AT ONCE (merged-grid review 2026-09-26, A2). One click on a selected
|
|
2381
|
+
* choice, multi-choice or person cell opens its list directly — no inline Save/Cancel form that
|
|
2382
|
+
* grows the row. Honoured by the choice and person pickers; every other control ignores it.
|
|
2383
|
+
*/
|
|
2384
|
+
autoOpen?: boolean | undefined;
|
|
2385
|
+
/** The picker's list closed (a pick, Escape, a click away): the cell commits what is chosen. */
|
|
2386
|
+
onClose?: (() => void) | undefined;
|
|
2357
2387
|
}
|
|
2358
2388
|
/** The label row every editor shares: one line, the label, the unit, the required mark. */
|
|
2359
2389
|
declare function FieldLabel({ field, htmlFor, children }: {
|
|
@@ -2361,7 +2391,7 @@ declare function FieldLabel({ field, htmlFor, children }: {
|
|
|
2361
2391
|
htmlFor: string;
|
|
2362
2392
|
children?: ReactNode;
|
|
2363
2393
|
}): react.JSX.Element;
|
|
2364
|
-
declare function FieldControl({ field, value, onChange, disabled, id }: FieldEditorControlProps): string | number | bigint | true | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element;
|
|
2394
|
+
declare function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose }: FieldEditorControlProps): string | number | bigint | true | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element;
|
|
2365
2395
|
/** The chip a picked record shows as — REC-2's "a record is a chip" in one place. */
|
|
2366
2396
|
declare function RecordChip({ title, onRemove, className, }: {
|
|
2367
2397
|
title: string;
|
|
@@ -2711,6 +2741,8 @@ interface ViewSwitcherProps {
|
|
|
2711
2741
|
*/
|
|
2712
2742
|
onViewChange?: ((patch: Partial<SavedViewSpec>) => void) | undefined;
|
|
2713
2743
|
onOpenRecord?: ((recordId: Uuid) => void) | undefined;
|
|
2744
|
+
/** The record the host has open beside a grid, which the grid's panel then follows (`Grid.openRecordId`). */
|
|
2745
|
+
openRecordId?: Uuid | null | undefined;
|
|
2714
2746
|
/**
|
|
2715
2747
|
* Called after a card moves between columns, so the host re-reads the rows it owns. A
|
|
2716
2748
|
* board that moved a card and left the row list alone would show the card in two places
|
|
@@ -2794,7 +2826,7 @@ declare function useViewRecords(view: SavedViewSpec, pageSize?: number, filter?:
|
|
|
2794
2826
|
*/
|
|
2795
2827
|
membership: string;
|
|
2796
2828
|
};
|
|
2797
|
-
declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, onMoved, onNewRecordForm, onAskWhoChanged, pageSize, titleField, filter, hostLayout, onHostLayoutChange, chooser, openExport, viewId, onOrderPlaced, footer, className, }: ViewSwitcherProps): react.JSX.Element;
|
|
2829
|
+
declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, openRecordId, onMoved, onNewRecordForm, onAskWhoChanged, pageSize, titleField, filter, hostLayout, onHostLayoutChange, chooser, openExport, viewId, onOrderPlaced, footer, className, }: ViewSwitcherProps): react.JSX.Element;
|
|
2798
2830
|
|
|
2799
2831
|
/** What the screen says above the list, so nobody has to be told twice that nothing was destroyed. */
|
|
2800
2832
|
declare const ARCHIVE_MEANS = "Archiving never destroys anything. A record you remove from the grid waits here until somebody brings it back.";
|
package/dist/index.d.ts
CHANGED
|
@@ -1192,6 +1192,10 @@ interface PersonPickerProps {
|
|
|
1192
1192
|
disabled?: boolean | undefined;
|
|
1193
1193
|
id?: string | undefined;
|
|
1194
1194
|
className?: string | undefined;
|
|
1195
|
+
/** A grid cell's picker opens at once (`FieldEditorControlProps.autoOpen`). */
|
|
1196
|
+
autoOpen?: boolean | undefined;
|
|
1197
|
+
/** The list closed: the cell commits who is picked. */
|
|
1198
|
+
onClose?: (() => void) | undefined;
|
|
1195
1199
|
}
|
|
1196
1200
|
/** A Person record in the kernel Table, as this picker needs to read it. */
|
|
1197
1201
|
interface PersonRecord {
|
|
@@ -1213,7 +1217,7 @@ declare function personRecordForMember(client: RecordsClient, personTableId: Uui
|
|
|
1213
1217
|
ok: false;
|
|
1214
1218
|
error: RecordsError;
|
|
1215
1219
|
}>;
|
|
1216
|
-
declare function PersonPicker({ field, value, onChange, disabled, id, className }: PersonPickerProps): react.JSX.Element;
|
|
1220
|
+
declare function PersonPicker({ field, value, onChange, disabled, id, className, autoOpen, onClose }: PersonPickerProps): react.JSX.Element;
|
|
1217
1221
|
|
|
1218
1222
|
/** Which cell is open. A grid opens exactly one at a time, like every other grid. */
|
|
1219
1223
|
interface CellAddress {
|
|
@@ -1246,14 +1250,16 @@ interface GridEditing {
|
|
|
1246
1250
|
* exactly that, replacing the value, as every spreadsheet does; a picker column opens as usual.
|
|
1247
1251
|
*/
|
|
1248
1252
|
begin: (address: CellAddress, seed?: string | null) => void;
|
|
1249
|
-
|
|
1253
|
+
/** `via`: a key (Escape) or a pointer (the picker's own close) — how the grid gets its keys back. */
|
|
1254
|
+
cancel: (via?: EditVia) => void;
|
|
1250
1255
|
/**
|
|
1251
1256
|
* Commit the open cell — whatever is in `draft`. `move` opens the
|
|
1252
1257
|
* next/previous editable cell after it. It takes NO value: a caller that
|
|
1253
1258
|
* passed one would be a second copy of the typed value, which is the defect
|
|
1254
1259
|
* this file's header describes.
|
|
1255
1260
|
*/
|
|
1256
|
-
|
|
1261
|
+
/** Answers `false` when the cell stayed open: typed words that are not a value (editors.tsx). */
|
|
1262
|
+
commit: (move?: "next" | "previous" | null, via?: EditVia) => boolean | void;
|
|
1257
1263
|
/**
|
|
1258
1264
|
* WRITE ONE CELL OUTRIGHT, with no editor ever opening.
|
|
1259
1265
|
*
|
|
@@ -1330,8 +1336,18 @@ interface Options {
|
|
|
1330
1336
|
before: unknown;
|
|
1331
1337
|
after: unknown;
|
|
1332
1338
|
}) => void) | undefined;
|
|
1339
|
+
/**
|
|
1340
|
+
* THE GRID GETS ITS KEYS BACK (merged-grid review 2026-09-26, A1). Bound, an editor that closes
|
|
1341
|
+
* by a key or a pick says so — Enter `down`, Tab `right` (Shift-Tab `left`), Escape and a pick
|
|
1342
|
+
* `stay` — and Tab no longer opens the next cell's editor: it commits and the CURSOR moves right,
|
|
1343
|
+
* as in Sheets and Airtable. A blur (a click elsewhere) says nothing: the click has the focus.
|
|
1344
|
+
* Unbound (the classic grid), Tab chains editors as before.
|
|
1345
|
+
*/
|
|
1346
|
+
onEnded?: ((exit: "down" | "right" | "left" | "stay", from: CellAddress, how: "keyboard" | "pointer") => void) | undefined;
|
|
1333
1347
|
}
|
|
1334
|
-
|
|
1348
|
+
/** How an open cell was closed: a key (Enter, Tab, Escape), the picker's own close, or a blur. */
|
|
1349
|
+
type EditVia = "key" | "pick" | "blur";
|
|
1350
|
+
declare function useGridEditing({ tableId, fields, rows, reload, canWrite, mayWriteRow, onWritten, onEnded }: Options): GridEditing;
|
|
1335
1351
|
/**
|
|
1336
1352
|
* ONE CELL. Read, until somebody asks to change it; then the Field's own
|
|
1337
1353
|
* editor, in place, with the keys a person expects from a grid.
|
|
@@ -1805,8 +1821,14 @@ interface GridProps {
|
|
|
1805
1821
|
* the store compiles both into the one WHERE clause.
|
|
1806
1822
|
*/
|
|
1807
1823
|
filter?: StoreFilter$1 | undefined;
|
|
1808
|
-
/** Opened
|
|
1824
|
+
/** Opened from a row's handle, Space or the row menu. A host that has a record page passes its own. */
|
|
1809
1825
|
onOpenRecord?: ((recordId: Uuid) => void) | undefined;
|
|
1826
|
+
/**
|
|
1827
|
+
* THE RECORD THE HOST HAS OPEN BESIDE THE GRID, if any (merged grid). While one is open the panel
|
|
1828
|
+
* FOLLOWS the cursor: arrowing to another row opens that row (Airtable's expanded record walks
|
|
1829
|
+
* with the arrows), so the panel always shows the row the person is on.
|
|
1830
|
+
*/
|
|
1831
|
+
openRecordId?: Uuid | null | undefined;
|
|
1810
1832
|
/** SCR-2. Called when an admin clicks the "+" at the end of the headers. */
|
|
1811
1833
|
onAddField?: (() => void) | undefined;
|
|
1812
1834
|
/**
|
|
@@ -1867,7 +1889,7 @@ interface GridProps {
|
|
|
1867
1889
|
footer?: FooterPlacement | undefined;
|
|
1868
1890
|
className?: string | undefined;
|
|
1869
1891
|
}
|
|
1870
|
-
declare function Grid({ tableId, pageSize, filter, onOpenRecord, onAddField, onNewRecordForm, toolbarActions, editable, presentation, onPresentationChange, viewOrder, footer, className, onAskWhoChanged, }: GridProps): react.JSX.Element;
|
|
1892
|
+
declare function Grid({ tableId, pageSize, filter, onOpenRecord, openRecordId, onAddField, onNewRecordForm, toolbarActions, editable, presentation, onPresentationChange, viewOrder, footer, className, onAskWhoChanged, }: GridProps): react.JSX.Element;
|
|
1871
1893
|
|
|
1872
1894
|
/** Answers "what is the record with this id called", for one Field's values. */
|
|
1873
1895
|
type LabelLookup = (field: Field$1, id: string) => string | null;
|
|
@@ -2354,6 +2376,14 @@ interface FieldEditorControlProps {
|
|
|
2354
2376
|
onChange: (value: unknown) => void;
|
|
2355
2377
|
disabled?: boolean | undefined;
|
|
2356
2378
|
id?: string | undefined;
|
|
2379
|
+
/**
|
|
2380
|
+
* A GRID CELL'S PICKER OPENS AT ONCE (merged-grid review 2026-09-26, A2). One click on a selected
|
|
2381
|
+
* choice, multi-choice or person cell opens its list directly — no inline Save/Cancel form that
|
|
2382
|
+
* grows the row. Honoured by the choice and person pickers; every other control ignores it.
|
|
2383
|
+
*/
|
|
2384
|
+
autoOpen?: boolean | undefined;
|
|
2385
|
+
/** The picker's list closed (a pick, Escape, a click away): the cell commits what is chosen. */
|
|
2386
|
+
onClose?: (() => void) | undefined;
|
|
2357
2387
|
}
|
|
2358
2388
|
/** The label row every editor shares: one line, the label, the unit, the required mark. */
|
|
2359
2389
|
declare function FieldLabel({ field, htmlFor, children }: {
|
|
@@ -2361,7 +2391,7 @@ declare function FieldLabel({ field, htmlFor, children }: {
|
|
|
2361
2391
|
htmlFor: string;
|
|
2362
2392
|
children?: ReactNode;
|
|
2363
2393
|
}): react.JSX.Element;
|
|
2364
|
-
declare function FieldControl({ field, value, onChange, disabled, id }: FieldEditorControlProps): string | number | bigint | true | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element;
|
|
2394
|
+
declare function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose }: FieldEditorControlProps): string | number | bigint | true | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react.JSX.Element;
|
|
2365
2395
|
/** The chip a picked record shows as — REC-2's "a record is a chip" in one place. */
|
|
2366
2396
|
declare function RecordChip({ title, onRemove, className, }: {
|
|
2367
2397
|
title: string;
|
|
@@ -2711,6 +2741,8 @@ interface ViewSwitcherProps {
|
|
|
2711
2741
|
*/
|
|
2712
2742
|
onViewChange?: ((patch: Partial<SavedViewSpec>) => void) | undefined;
|
|
2713
2743
|
onOpenRecord?: ((recordId: Uuid) => void) | undefined;
|
|
2744
|
+
/** The record the host has open beside a grid, which the grid's panel then follows (`Grid.openRecordId`). */
|
|
2745
|
+
openRecordId?: Uuid | null | undefined;
|
|
2714
2746
|
/**
|
|
2715
2747
|
* Called after a card moves between columns, so the host re-reads the rows it owns. A
|
|
2716
2748
|
* board that moved a card and left the row list alone would show the card in two places
|
|
@@ -2794,7 +2826,7 @@ declare function useViewRecords(view: SavedViewSpec, pageSize?: number, filter?:
|
|
|
2794
2826
|
*/
|
|
2795
2827
|
membership: string;
|
|
2796
2828
|
};
|
|
2797
|
-
declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, onMoved, onNewRecordForm, onAskWhoChanged, pageSize, titleField, filter, hostLayout, onHostLayoutChange, chooser, openExport, viewId, onOrderPlaced, footer, className, }: ViewSwitcherProps): react.JSX.Element;
|
|
2829
|
+
declare function ViewSwitcher({ view, onLayoutChange, onViewChange, onOpenRecord, openRecordId, onMoved, onNewRecordForm, onAskWhoChanged, pageSize, titleField, filter, hostLayout, onHostLayoutChange, chooser, openExport, viewId, onOrderPlaced, footer, className, }: ViewSwitcherProps): react.JSX.Element;
|
|
2798
2830
|
|
|
2799
2831
|
/** What the screen says above the list, so nobody has to be told twice that nothing was destroyed. */
|
|
2800
2832
|
declare const ARCHIVE_MEANS = "Archiving never destroys anything. A record you remove from the grid waits here until somebody brings it back.";
|