@ai-matrx/records-ui 0.93.146 → 0.95.2

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/dist/pickers.cjs CHANGED
@@ -42,15 +42,15 @@ __export(pickers_exports, {
42
42
  module.exports = __toCommonJS(pickers_exports);
43
43
 
44
44
  // src/TablePickers.tsx
45
- var import_react28 = require("react");
46
- var import_react29 = require("@ai-matrx/records/react");
47
- var import_design_system15 = require("@ai-matrx/design-system");
45
+ var import_react30 = require("react");
46
+ var import_react31 = require("@ai-matrx/records/react");
47
+ var import_design_system16 = require("@ai-matrx/design-system");
48
48
 
49
49
  // src/editors.tsx
50
- var import_react22 = require("react");
50
+ var import_react24 = require("react");
51
51
  var import_records10 = require("@ai-matrx/records");
52
- var import_react23 = require("@ai-matrx/records/react");
53
- var import_design_system13 = require("@ai-matrx/design-system");
52
+ var import_react25 = require("@ai-matrx/records/react");
53
+ var import_design_system14 = require("@ai-matrx/design-system");
54
54
 
55
55
  // src/dates.ts
56
56
  var import_field_formats = require("@ai-matrx/design-system/field-formats");
@@ -109,7 +109,7 @@ function newerKindValue(field, value, opts = {}) {
109
109
  }
110
110
  case "created_by":
111
111
  case "modified_by":
112
- return (0, import_records.isPersonStamp)(value) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PersonStampChip, { name: value.name }) : void 0;
112
+ return (0, import_records.isPersonStamp)(value) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PersonStampChip, { stamp: value }) : void 0;
113
113
  case "address":
114
114
  return (0, import_records.isAddressValue)(value) || typeof value === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AddressLink, { value }) : void 0;
115
115
  case "barcode":
@@ -125,10 +125,12 @@ function newerKindValue(field, value, opts = {}) {
125
125
  return void 0;
126
126
  }
127
127
  }
128
- function PersonStampChip({ name }) {
129
- const words = name && name.trim() !== "" ? name : import_records.NOT_A_MEMBER_WORDS;
130
- const initial = name && name.trim() !== "" ? name.trim()[0].toUpperCase() : "?";
131
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1.5", "data-records-person-stamp": "", children: [
128
+ function PersonStampChip({ stamp }) {
129
+ const words = (0, import_records.personStampText)(stamp) ?? import_records.NOT_A_MEMBER_WORDS;
130
+ const tier = stamp.actor ?? "user";
131
+ const name = tier === "user" ? stamp.name : null;
132
+ const initial = tier === "system" ? "\u2699" : tier === "agent" ? "\u2726" : name && name.trim() !== "" ? name.trim()[0].toUpperCase() : "?";
133
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1.5", "data-records-person-stamp": tier, children: [
132
134
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
133
135
  "span",
134
136
  {
@@ -137,7 +139,7 @@ function PersonStampChip({ name }) {
137
139
  children: initial
138
140
  }
139
141
  ),
140
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_design_system.cn)("truncate", name ? "" : "italic text-muted-foreground"), children: words })
142
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: (0, import_design_system.cn)("truncate", tier === "user" && !name ? "italic text-muted-foreground" : ""), children: words })
141
143
  ] });
142
144
  }
143
145
  function AddressLink({ value }) {
@@ -162,12 +164,13 @@ function AddressLink({ value }) {
162
164
  );
163
165
  }
164
166
  var STATUS_GROUP_MARK = { todo: "\u25CB", in_progress: "\u25D0", done: "\u25CF" };
165
- function statusMarkOf(field, value) {
167
+ function statusMarkOf(field, value, document2) {
166
168
  if ((0, import_records.newerKindOf)(field) !== "status" || typeof value !== "string") return null;
167
- const group = (0, import_records.statusGroupOf)(field, value);
169
+ const chosen = document2?.["_choices"]?.[field.key];
170
+ const key = chosen && typeof chosen === "object" && typeof chosen.key === "string" ? chosen.key : value;
171
+ const group = (0, import_records.statusGroupOf)(field, key);
168
172
  return { mark: STATUS_GROUP_MARK[group], group, words: import_records.STATUS_GROUP_WORDS[group] };
169
173
  }
170
- var SAFE_HREF = /^(https?:\/\/|mailto:)/i;
171
174
  function inline(text, key) {
172
175
  const out = [];
173
176
  let at = 0;
@@ -194,9 +197,9 @@ function marks(text, key) {
194
197
  if (tok.startsWith("**") || tok.startsWith("__")) out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: tok.slice(2, -2) }, k));
195
198
  else if (tok.startsWith("[")) {
196
199
  const link = /^\[([^\]]+)\]\(([^)\s]+)\)$/.exec(tok);
197
- const href = link?.[2] ?? "";
200
+ const href = (0, import_records.safeLinkHref)(link?.[2] ?? "");
198
201
  out.push(
199
- SAFE_HREF.test(href) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline-offset-2 hover:underline", onClick: own, children: link?.[1] }, k) : link?.[1] ?? tok
202
+ href ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline-offset-2 hover:underline", onClick: own, children: link?.[1] }, k) : link?.[1] ?? tok
200
203
  );
201
204
  } else out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { children: tok.slice(1, -1) }, k));
202
205
  last = at + tok.length;
@@ -406,6 +409,59 @@ function BarcodeControl({ value, onChange, disabled, id }) {
406
409
  ] });
407
410
  }
408
411
 
412
+ // src/choiceLooks.ts
413
+ var import_data_table = require("@ai-matrx/design-system/data-table");
414
+ function displayFormatOf(field) {
415
+ const raw = field.display_format;
416
+ if (!raw || typeof raw !== "object") return null;
417
+ const id = raw.id;
418
+ if (typeof id !== "string" || id === "") return null;
419
+ const options = raw.options;
420
+ return { id, options: options && typeof options === "object" ? options : {} };
421
+ }
422
+ function isStyleColor(v) {
423
+ return typeof v === "string" && import_data_table.STYLE_COLORS.includes(v);
424
+ }
425
+ function choiceLooksOf(field) {
426
+ const display = displayFormatOf(field);
427
+ const choices = display?.options["choices"];
428
+ if (!Array.isArray(choices)) return [];
429
+ const out = [];
430
+ for (const c of choices) {
431
+ if (!c || typeof c !== "object") continue;
432
+ const value = c.value;
433
+ if (typeof value !== "string" || value.trim() === "") continue;
434
+ const color = c.color;
435
+ const label = c.label;
436
+ out.push({
437
+ value: value.trim(),
438
+ ...typeof label === "string" && label.trim() !== "" ? { label: label.trim() } : {},
439
+ ...isStyleColor(color) ? { color } : {}
440
+ });
441
+ }
442
+ return out;
443
+ }
444
+ function choiceWord(value) {
445
+ return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
446
+ }
447
+ function storedChoiceColor(field, value) {
448
+ if (value === null || value === void 0 || value === "") return void 0;
449
+ const word = choiceWord(value);
450
+ if (word === "") return void 0;
451
+ for (const look of choiceLooksOf(field)) {
452
+ if (!look.color) continue;
453
+ if (choiceWord(look.value) === word || look.label && choiceWord(look.label) === word) return look.color;
454
+ }
455
+ return void 0;
456
+ }
457
+ function choiceChipLookOf(field, ...words) {
458
+ for (const word of words) {
459
+ const color = storedChoiceColor(field, word);
460
+ if (color) return { className: import_data_table.CHOICE_CHIP_CLASS[color], color };
461
+ }
462
+ return { className: import_data_table.NEUTRAL_CHIP_CLASS, color: null };
463
+ }
464
+
409
465
  // src/parity.ts
410
466
  var import_records2 = require("@ai-matrx/records");
411
467
  var import_text_case = require("@ai-matrx/kit/text-case");
@@ -630,7 +686,12 @@ var TITLE = {
630
686
  already_exists: "That already exists",
631
687
  not_supported: "That cannot be done here",
632
688
  store_limit: "This has got as big as it can",
633
- store_not_served: "This organization does not keep its data here",
689
+ // 🚨 NOT "THE SWITCH IS OFF" (lane 7 W1 fix round 1). PGRST202 / PGRST205 land here, and the
690
+ // commonest cause is a door this screen asks for that the database it talks to does not serve
691
+ // YET — a release in flight. Telling the person her organization has its store switched off was
692
+ // false (the switch is answered by its own door, `platform.unified_data_store_on`). Honest:
693
+ // nothing happened, and it is ours, and it passes.
694
+ store_not_served: "This isn't available right now",
634
695
  unreachable: "We could not reach your data",
635
696
  needs_approval: "This is waiting on someone's approval",
636
697
  stale_read: "Your view of this is a moment behind",
@@ -648,7 +709,7 @@ var REMEDY = {
648
709
  already_exists: "Use a different name.",
649
710
  not_supported: "There is another way to do this \u2014 ask, and we will point you at it.",
650
711
  store_limit: "Split it up, or ask us to raise the ceiling for your organization.",
651
- store_not_served: "An administrator of this organization turns the record store on from the data settings screen.",
712
+ store_not_served: "Nothing was changed. Try again in a few minutes.",
652
713
  // 🚨 NOTHING WAS WRITTEN AND NOTHING WAS REFUSED (lane TAILS-6). The call
653
714
  // never arrived, so "try again" is the honest instruction rather than a
654
715
  // consolation — and saying nothing changed is the half a person actually
@@ -1147,8 +1208,8 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1147
1208
  }
1148
1209
 
1149
1210
  // src/gridAttachments.tsx
1150
- var import_react11 = require("react");
1151
- var import_react12 = require("@ai-matrx/records/react");
1211
+ var import_react12 = require("react");
1212
+ var import_react13 = require("@ai-matrx/records/react");
1152
1213
  var import_design_system7 = require("@ai-matrx/design-system");
1153
1214
 
1154
1215
  // src/host.tsx
@@ -1226,14 +1287,15 @@ function useRecordsUi() {
1226
1287
  }
1227
1288
 
1228
1289
  // src/labels.tsx
1229
- var import_react8 = require("react");
1230
- var import_react9 = require("@ai-matrx/records/react");
1290
+ var import_react9 = require("react");
1291
+ var import_react10 = require("@ai-matrx/records/react");
1231
1292
  var import_records5 = require("@ai-matrx/records");
1232
1293
  var import_uuid2 = require("@ai-matrx/kit/uuid");
1233
1294
 
1234
1295
  // src/signature.tsx
1235
1296
  var import_react7 = require("react");
1236
1297
  var import_design_system5 = require("@ai-matrx/design-system");
1298
+ var import_react8 = require("@ai-matrx/records/react");
1237
1299
  var import_jsx_runtime6 = require("react/jsx-runtime");
1238
1300
  var DRAWN = /^data:image\/(png|jpeg);base64,[A-Za-z0-9+/=]{64,}$/;
1239
1301
  function drawnSignatureOf(value) {
@@ -1244,18 +1306,105 @@ function signatureWords(value) {
1244
1306
  if (value === null || value === void 0 || value === "") return null;
1245
1307
  return drawnSignatureOf(value) ? SIGNED_WORD : String(value);
1246
1308
  }
1247
- function SignatureValue({ value, inCell }) {
1309
+ function signatureFileOf(source) {
1310
+ if (!source || typeof source !== "object") return null;
1311
+ const src = source;
1312
+ const id = src["signature_file_id"];
1313
+ return src["kind"] === "signature" && typeof id === "string" && id !== "" ? id : null;
1314
+ }
1315
+ function signatureFileIn(document2, key) {
1316
+ const values = document2?.["_values"];
1317
+ const src = values?.[key]?.src;
1318
+ if (typeof src === "string") {
1319
+ const sources = document2?.["_sources"];
1320
+ return signatureFileOf(sources?.[src]);
1321
+ }
1322
+ return signatureFileOf(src);
1323
+ }
1324
+ var SOURCES = /* @__PURE__ */ new WeakMap();
1325
+ var FILES = /* @__PURE__ */ new WeakMap();
1326
+ function signatureFilesOf(client, recordId) {
1327
+ let held = SOURCES.get(client);
1328
+ if (!held) SOURCES.set(client, held = /* @__PURE__ */ new Map());
1329
+ let asked2 = held.get(recordId);
1330
+ if (!asked2) {
1331
+ asked2 = client.recordValuesVersioned({ record_id: recordId }).then((answered) => {
1332
+ if (!answered.ok) return {};
1333
+ return Object.fromEntries(answered.data.map((v) => [v.field_key, signatureFileOf(v.source)]));
1334
+ });
1335
+ held.set(recordId, asked2);
1336
+ }
1337
+ return asked2;
1338
+ }
1339
+ function drawingOf(client, fileId) {
1340
+ let held = FILES.get(client);
1341
+ if (!held) FILES.set(client, held = /* @__PURE__ */ new Map());
1342
+ let asked2 = held.get(fileId);
1343
+ if (!asked2) {
1344
+ asked2 = client.recordRead({ record_id: fileId }).then((answered) => {
1345
+ if (!answered.ok) return { src: null, hostFileId: null };
1346
+ const doc = answered.data.document ?? {};
1347
+ const content = drawnSignatureOf(doc["content"]);
1348
+ const hostFileId = typeof doc["file_id"] === "string" && doc["file_id"] !== "" ? doc["file_id"] : null;
1349
+ return { src: content, hostFileId };
1350
+ });
1351
+ held.set(fileId, asked2);
1352
+ }
1353
+ return asked2;
1354
+ }
1355
+ function DrawnImage({ src, inCell }) {
1356
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1357
+ "img",
1358
+ {
1359
+ src,
1360
+ alt: SIGNED_WORD,
1361
+ "data-records-signature": "",
1362
+ className: (0, import_design_system5.cn)("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
1363
+ }
1364
+ );
1365
+ }
1366
+ function SignatureDrawing({
1367
+ recordId,
1368
+ fieldKey,
1369
+ fileId: knownFile,
1370
+ value,
1371
+ inCell
1372
+ }) {
1373
+ const client = (0, import_react8.useOptionalRecordsClient)();
1374
+ const host = useRecordsUi();
1375
+ const [drawing, setDrawing] = (0, import_react7.useState)(null);
1376
+ (0, import_react7.useEffect)(() => {
1377
+ let cancelled = false;
1378
+ setDrawing(null);
1379
+ if (!client) return;
1380
+ void (async () => {
1381
+ const fileId = knownFile ?? (recordId && fieldKey ? (await signatureFilesOf(client, recordId))[fieldKey] ?? null : null);
1382
+ if (!fileId || cancelled) return;
1383
+ const read = await drawingOf(client, fileId);
1384
+ if (!cancelled) setDrawing(read);
1385
+ })();
1386
+ return () => {
1387
+ cancelled = true;
1388
+ };
1389
+ }, [client, recordId, fieldKey, knownFile]);
1390
+ if (drawing?.src) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DrawnImage, { src: drawing.src, inCell });
1391
+ if (drawing?.hostFileId && host.fileImage) {
1392
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: (0, import_design_system5.cn)("inline-block max-w-[12rem] dark:invert", inCell ? "h-7" : "h-12"), "data-records-signature": "", children: host.fileImage({ fileId: drawing.hostFileId, alt: SIGNED_WORD }) });
1393
+ }
1394
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-serif italic", children: String(value) });
1395
+ }
1396
+ function SignatureValue({
1397
+ value,
1398
+ inCell,
1399
+ recordId,
1400
+ fieldKey,
1401
+ document: document2
1402
+ }) {
1248
1403
  const drawn = drawnSignatureOf(value);
1249
- if (drawn) {
1250
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1251
- "img",
1252
- {
1253
- src: drawn,
1254
- alt: SIGNED_WORD,
1255
- "data-records-signature": "",
1256
- className: (0, import_design_system5.cn)("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
1257
- }
1258
- );
1404
+ if (drawn) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DrawnImage, { src: drawn, inCell });
1405
+ const fileId = fieldKey ? signatureFileIn(document2, fieldKey) : null;
1406
+ if (value === SIGNED_WORD && (fileId || recordId && fieldKey)) {
1407
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SignatureDrawing, { recordId: recordId ?? null, fieldKey: fieldKey ?? null, fileId, value, inCell });
1259
1408
  }
1260
1409
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-serif italic", children: String(value) });
1261
1410
  }
@@ -1415,7 +1564,7 @@ function encodeAt(canvas, type, maxWidth, quality) {
1415
1564
 
1416
1565
  // src/labels.tsx
1417
1566
  var import_jsx_runtime7 = require("react/jsx-runtime");
1418
- var LabelContext = (0, import_react8.createContext)({
1567
+ var LabelContext = (0, import_react9.createContext)({
1419
1568
  // With no provider the resolver is ABSENT, not silently empty: a caller gets
1420
1569
  // null and says "Loading…" forever, which is visible. The mount always
1421
1570
  // provides one, so this is only ever a bare unit test.
@@ -1443,15 +1592,15 @@ function pointsAtRecords(field) {
1443
1592
  return field.type === "list" || field.type === "relation";
1444
1593
  }
1445
1594
  function RecordLabelProvider({ children }) {
1446
- const client = (0, import_react9.useRecordsClient)();
1447
- const [names, setNames] = (0, import_react8.useState)({});
1448
- const [archivedRefs, setArchivedRefs] = (0, import_react8.useState)({});
1449
- const [settled, setSettled] = (0, import_react8.useState)({});
1450
- const [waitingLines, setWaitingLines] = (0, import_react8.useState)({});
1451
- const asked2 = (0, import_react8.useRef)(/* @__PURE__ */ new Set());
1452
- const chased = (0, import_react8.useRef)(/* @__PURE__ */ new Set());
1453
- const timers = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
1454
- const startWaitClock = (0, import_react8.useCallback)((field, target) => {
1595
+ const client = (0, import_react10.useRecordsClient)();
1596
+ const [names, setNames] = (0, import_react9.useState)({});
1597
+ const [archivedRefs, setArchivedRefs] = (0, import_react9.useState)({});
1598
+ const [settled, setSettled] = (0, import_react9.useState)({});
1599
+ const [waitingLines, setWaitingLines] = (0, import_react9.useState)({});
1600
+ const asked2 = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
1601
+ const chased = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
1602
+ const timers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
1603
+ const startWaitClock = (0, import_react9.useCallback)((field, target) => {
1455
1604
  if (timers.current.has(field.id)) return;
1456
1605
  timers.current.set(
1457
1606
  field.id,
@@ -1463,7 +1612,7 @@ function RecordLabelProvider({ children }) {
1463
1612
  }, SAY_WHAT_YOU_ARE_WAITING_FOR_AFTER_MS)
1464
1613
  );
1465
1614
  }, []);
1466
- const stopWaitClock = (0, import_react8.useCallback)((fieldId) => {
1615
+ const stopWaitClock = (0, import_react9.useCallback)((fieldId) => {
1467
1616
  const timer = timers.current.get(fieldId);
1468
1617
  if (timer) {
1469
1618
  clearTimeout(timer);
@@ -1476,14 +1625,14 @@ function RecordLabelProvider({ children }) {
1476
1625
  return next;
1477
1626
  });
1478
1627
  }, []);
1479
- (0, import_react8.useEffect)(
1628
+ (0, import_react9.useEffect)(
1480
1629
  () => () => {
1481
1630
  for (const timer of timers.current.values()) clearTimeout(timer);
1482
1631
  timers.current.clear();
1483
1632
  },
1484
1633
  []
1485
1634
  );
1486
- const want = (0, import_react8.useCallback)(
1635
+ const want = (0, import_react9.useCallback)(
1487
1636
  (field) => {
1488
1637
  if (!pointsAtRecords(field)) return;
1489
1638
  if (asked2.current.has(field.id)) return;
@@ -1518,9 +1667,9 @@ function RecordLabelProvider({ children }) {
1518
1667
  },
1519
1668
  [client, startWaitClock, stopWaitClock]
1520
1669
  );
1521
- const queued = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
1522
- const flushing = (0, import_react8.useRef)(null);
1523
- const flush = (0, import_react8.useCallback)(() => {
1670
+ const queued = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
1671
+ const flushing = (0, import_react9.useRef)(null);
1672
+ const flush = (0, import_react9.useCallback)(() => {
1524
1673
  flushing.current = null;
1525
1674
  const batch = [...queued.current.values()];
1526
1675
  queued.current.clear();
@@ -1547,7 +1696,7 @@ function RecordLabelProvider({ children }) {
1547
1696
  for (const { field } of batch) stopWaitClock(field.id);
1548
1697
  })();
1549
1698
  }, [client, stopWaitClock]);
1550
- const chase = (0, import_react8.useCallback)(
1699
+ const chase = (0, import_react9.useCallback)(
1551
1700
  (field, id) => {
1552
1701
  const key = `${field.id}:${id}`;
1553
1702
  if (chased.current.has(key)) return;
@@ -1560,14 +1709,14 @@ function RecordLabelProvider({ children }) {
1560
1709
  },
1561
1710
  [flush, startWaitClock]
1562
1711
  );
1563
- (0, import_react8.useEffect)(
1712
+ (0, import_react9.useEffect)(
1564
1713
  () => () => {
1565
1714
  if (flushing.current !== null) clearTimeout(flushing.current);
1566
1715
  },
1567
1716
  []
1568
1717
  );
1569
- const rereadFor = (0, import_react8.useRef)(/* @__PURE__ */ new Set());
1570
- const lookupWords = (0, import_react8.useCallback)(
1718
+ const rereadFor = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
1719
+ const lookupWords = (0, import_react9.useCallback)(
1571
1720
  (field, id) => {
1572
1721
  if (field.type === "list" && !isId(id)) {
1573
1722
  const named = names[choiceKeyName(field.id, id)];
@@ -1587,7 +1736,7 @@ function RecordLabelProvider({ children }) {
1587
1736
  },
1588
1737
  [names, settled, chase, want]
1589
1738
  );
1590
- const lookup = (0, import_react8.useMemo)(
1739
+ const lookup = (0, import_react9.useMemo)(
1591
1740
  () => {
1592
1741
  const answer = ((field, id) => lookupWords(field, id));
1593
1742
  answer.archived = (field, id) => archivedRefs[`${field.id}:${id}`] === true;
@@ -1595,20 +1744,20 @@ function RecordLabelProvider({ children }) {
1595
1744
  },
1596
1745
  [lookupWords, archivedRefs]
1597
1746
  );
1598
- const waiting = (0, import_react8.useCallback)((field) => waitingLines[field.id] ?? null, [waitingLines]);
1599
- const value = (0, import_react8.useMemo)(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
1747
+ const waiting = (0, import_react9.useCallback)((field) => waitingLines[field.id] ?? null, [waitingLines]);
1748
+ const value = (0, import_react9.useMemo)(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
1600
1749
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LabelContext.Provider, { value, children });
1601
1750
  }
1602
1751
  function useRecordLabels(fields) {
1603
- const { lookup, want } = (0, import_react8.useContext)(LabelContext);
1604
- (0, import_react8.useEffect)(() => {
1752
+ const { lookup, want } = (0, import_react9.useContext)(LabelContext);
1753
+ (0, import_react9.useEffect)(() => {
1605
1754
  for (const field of fields ?? []) want(field);
1606
1755
  }, [fields, want]);
1607
1756
  return lookup;
1608
1757
  }
1609
1758
 
1610
1759
  // src/FilePicker.tsx
1611
- var import_react10 = require("react");
1760
+ var import_react11 = require("react");
1612
1761
  var import_design_system6 = require("@ai-matrx/design-system");
1613
1762
  var import_jsx_runtime8 = require("react/jsx-runtime");
1614
1763
  function FilePicker({
@@ -1622,17 +1771,17 @@ function FilePicker({
1622
1771
  chosenName,
1623
1772
  className
1624
1773
  }) {
1625
- const inputId = (0, import_react10.useId)();
1626
- const input = (0, import_react10.useRef)(null);
1627
- const [over, setOver] = (0, import_react10.useState)(false);
1628
- const take = (0, import_react10.useCallback)(
1774
+ const inputId = (0, import_react11.useId)();
1775
+ const input = (0, import_react11.useRef)(null);
1776
+ const [over, setOver] = (0, import_react11.useState)(false);
1777
+ const take = (0, import_react11.useCallback)(
1629
1778
  (file) => {
1630
1779
  if (!file || disabled) return;
1631
1780
  onFile(file);
1632
1781
  },
1633
1782
  [disabled, onFile]
1634
1783
  );
1635
- const onDrop = (0, import_react10.useCallback)(
1784
+ const onDrop = (0, import_react11.useCallback)(
1636
1785
  (e) => {
1637
1786
  e.preventDefault();
1638
1787
  setOver(false);
@@ -1725,10 +1874,10 @@ function rememberHostFileIds(ids) {
1725
1874
  var FILE_CHIP_UNREAD = "File";
1726
1875
  var FILE_CHIP_NO_PAGE = "This screen has no way to open files yet.";
1727
1876
  function AttachmentChip({ id, onRemove }) {
1728
- const client = (0, import_react12.useOptionalRecordsClient)();
1877
+ const client = (0, import_react13.useOptionalRecordsClient)();
1729
1878
  const host = useRecordsUi();
1730
- const [read, setRead] = (0, import_react11.useState)(null);
1731
- (0, import_react11.useEffect)(() => {
1879
+ const [read, setRead] = (0, import_react12.useState)(null);
1880
+ (0, import_react12.useEffect)(() => {
1732
1881
  let cancelled = false;
1733
1882
  if (!client) {
1734
1883
  setRead({ name: null, fileId: null, why: null });
@@ -1803,9 +1952,9 @@ function AttachmentControl({
1803
1952
  onClose
1804
1953
  }) {
1805
1954
  const host = useRecordsUi();
1806
- const [busy, setBusy] = (0, import_react11.useState)(false);
1807
- const [why, setWhy] = (0, import_react11.useState)(null);
1808
- const latest = (0, import_react11.useRef)(value);
1955
+ const [busy, setBusy] = (0, import_react12.useState)(false);
1956
+ const [why, setWhy] = (0, import_react12.useState)(null);
1957
+ const latest = (0, import_react12.useRef)(value);
1809
1958
  latest.current = value;
1810
1959
  const multiple = Boolean(field.multi);
1811
1960
  const pick = async () => {
@@ -1826,8 +1975,8 @@ function AttachmentControl({
1826
1975
  setBusy(false);
1827
1976
  onClose?.();
1828
1977
  };
1829
- const opened = (0, import_react11.useRef)(false);
1830
- (0, import_react11.useEffect)(() => {
1978
+ const opened = (0, import_react12.useRef)(false);
1979
+ (0, import_react12.useEffect)(() => {
1831
1980
  if (!autoOpen || opened.current || !host.pickFiles) return;
1832
1981
  opened.current = true;
1833
1982
  void pick();
@@ -1870,11 +2019,99 @@ function AttachmentControl({
1870
2019
  }
1871
2020
 
1872
2021
  // src/EntityReferenceControl.tsx
1873
- var import_react13 = require("react");
2022
+ var import_react15 = require("react");
1874
2023
  var import_records6 = require("@ai-matrx/records");
1875
- var import_react14 = require("@ai-matrx/records/react");
2024
+ var import_react16 = require("@ai-matrx/records/react");
2025
+ var import_design_system9 = require("@ai-matrx/design-system");
2026
+
2027
+ // src/PickOne.tsx
2028
+ var import_react14 = require("react");
1876
2029
  var import_design_system8 = require("@ai-matrx/design-system");
1877
2030
  var import_jsx_runtime10 = require("react/jsx-runtime");
2031
+ var PICK_ONE_SEARCH_AFTER = 7;
2032
+ var EMPTY = "__records_pick_one_empty__";
2033
+ var inner = (v) => v === "" ? EMPTY : v;
2034
+ var outer = (v) => v === EMPTY ? "" : v;
2035
+ function PickOne({
2036
+ value,
2037
+ onChange,
2038
+ options,
2039
+ label,
2040
+ placeholder,
2041
+ id,
2042
+ className,
2043
+ disabled,
2044
+ attrs
2045
+ }) {
2046
+ const [open, setOpen] = (0, import_react14.useState)(false);
2047
+ const [search, setSearch] = (0, import_react14.useState)("");
2048
+ const current = options.find((o) => o.value === value);
2049
+ if (options.length > PICK_ONE_SEARCH_AFTER) {
2050
+ const q = search.trim().toLowerCase();
2051
+ const shown2 = q === "" ? options : options.filter((o) => o.label.toLowerCase().includes(q));
2052
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: (0, import_design_system8.cn)("inline-flex min-w-0", className), "data-records-pick-one": "search", "data-pick-value": value, ...attrs ?? {}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2053
+ PickOrAdd,
2054
+ {
2055
+ triggerLabel: label,
2056
+ triggerText: current?.label ?? placeholder ?? "",
2057
+ triggerId: id,
2058
+ open: open && !disabled,
2059
+ onOpenChange: (next) => {
2060
+ setOpen(next);
2061
+ if (!next) setSearch("");
2062
+ },
2063
+ search,
2064
+ onSearch: setSearch,
2065
+ items: shown2.map((o) => ({
2066
+ id: inner(o.value),
2067
+ label: o.label,
2068
+ detail: o.group,
2069
+ picked: o.value === value,
2070
+ attrs: { "data-pick-value": o.value, ...o.group ? { "data-pick-group": o.group } : {} }
2071
+ })),
2072
+ onPick: (picked) => {
2073
+ onChange(outer(picked));
2074
+ setOpen(false);
2075
+ setSearch("");
2076
+ },
2077
+ empty: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "No match" })
2078
+ }
2079
+ ) });
2080
+ }
2081
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_design_system8.Select, { value: current ? inner(current.value) : "", onValueChange: (v) => onChange(outer(v)), disabled: disabled ?? false, children: [
2082
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2083
+ import_design_system8.SelectTrigger,
2084
+ {
2085
+ id,
2086
+ size: "sm",
2087
+ "aria-label": label,
2088
+ className: (0, import_design_system8.cn)("h-7 w-auto min-w-[7rem] text-xs", className),
2089
+ "data-records-pick-one": "list",
2090
+ "data-pick-value": value,
2091
+ ...attrs ?? {},
2092
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectValue, { placeholder })
2093
+ }
2094
+ ),
2095
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectContent, { children: groupsOf(options).map(
2096
+ ([group, items]) => group ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_design_system8.SelectGroup, { children: [
2097
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectLabel, { children: group }),
2098
+ items.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectItem, { value: inner(o.value), "data-pick-value": o.value, "data-pick-group": group, children: o.label }, inner(o.value)))
2099
+ ] }, group) : items.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_design_system8.SelectItem, { value: inner(o.value), "data-pick-value": o.value, children: o.label }, inner(o.value)))
2100
+ ) })
2101
+ ] });
2102
+ }
2103
+ function groupsOf(options) {
2104
+ const out = [];
2105
+ for (const o of options) {
2106
+ const last = out[out.length - 1];
2107
+ if (last && last[0] === o.group) last[1].push(o);
2108
+ else out.push([o.group, [o]]);
2109
+ }
2110
+ return out;
2111
+ }
2112
+
2113
+ // src/EntityReferenceControl.tsx
2114
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1878
2115
  var WITHHELD_ENTITY_LABEL = "Something you have not been given access to";
1879
2116
  var ENTITY_REFERENCE_EMPTY = "Nothing is pointed at yet.";
1880
2117
  function entityReferenceText(value) {
@@ -1888,20 +2125,20 @@ function allowedKindsOf(field) {
1888
2125
  return kinds.map((k) => String(k).trim().toLowerCase()).filter(Boolean);
1889
2126
  }
1890
2127
  function EntityReferenceControl(props) {
1891
- const client = (0, import_react14.useOptionalRecordsClient)();
1892
- return client ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(WithWords, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Chips, { ...props, words: null, picker: null });
2128
+ const client = (0, import_react16.useOptionalRecordsClient)();
2129
+ return client ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(WithWords, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Chips, { ...props, words: null, picker: null });
1893
2130
  }
1894
2131
  function WithWords(props) {
1895
- const refs = (0, import_react13.useMemo)(() => (0, import_records6.entityRefsOf)(props.value), [props.value]);
1896
- const [known, setKnown] = (0, import_react13.useState)([]);
2132
+ const refs = (0, import_react15.useMemo)(() => (0, import_records6.entityRefsOf)(props.value), [props.value]);
2133
+ const [known, setKnown] = (0, import_react15.useState)([]);
1897
2134
  const withKnown = refs.map((r) => r.label === null ? known.find((k) => k.token === r.token && k.id === r.id) ?? r : r);
1898
- const unlabelled = (0, import_react13.useMemo)(
2135
+ const unlabelled = (0, import_react15.useMemo)(
1899
2136
  () => withKnown.filter((r) => r.label === null).map((r) => ({ token: r.token, id: r.id })),
1900
2137
  // eslint-disable-next-line react-hooks/exhaustive-deps
1901
2138
  [JSON.stringify(withKnown)]
1902
2139
  );
1903
- const words = (0, import_react14.useEntityReferenceWords)(unlabelled);
1904
- const picker = props.disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2140
+ const words = (0, import_react16.useEntityReferenceWords)(unlabelled);
2141
+ const picker = props.disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1905
2142
  EntityReferencePicker,
1906
2143
  {
1907
2144
  field: props.field,
@@ -1914,7 +2151,7 @@ function WithWords(props) {
1914
2151
  }
1915
2152
  }
1916
2153
  );
1917
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Chips, { ...props, value: withKnown, words, picker });
2154
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Chips, { ...props, value: withKnown, words, picker });
1918
2155
  }
1919
2156
  function EntityReferencePicker({
1920
2157
  field,
@@ -1922,13 +2159,13 @@ function EntityReferencePicker({
1922
2159
  onPick
1923
2160
  }) {
1924
2161
  const allowed = allowedKindsOf(field);
1925
- const kinds = (0, import_react14.useEntityReferenceKinds)();
2162
+ const kinds = (0, import_react16.useEntityReferenceKinds)();
1926
2163
  const labelOfKind = (token) => kinds.data?.find((k) => k.token === token)?.label ?? token.replace(/_/g, " ");
1927
- const [open, setOpen] = (0, import_react13.useState)(false);
1928
- const [search, setSearch] = (0, import_react13.useState)("");
1929
- const [only, setOnly] = (0, import_react13.useState)(null);
2164
+ const [open, setOpen] = (0, import_react15.useState)(false);
2165
+ const [search, setSearch] = (0, import_react15.useState)("");
2166
+ const [only, setOnly] = (0, import_react15.useState)(null);
1930
2167
  const tokens = only ? [only] : allowed;
1931
- const found = (0, import_react14.useEntityReferenceSearch)(tokens, search, open);
2168
+ const found = (0, import_react16.useEntityReferenceSearch)(tokens, search, open);
1932
2169
  const multi = Boolean(field.multi);
1933
2170
  const items = (found.data ?? []).map((r) => ({
1934
2171
  id: `${r.token}:${r.id}`,
@@ -1937,8 +2174,8 @@ function EntityReferencePicker({
1937
2174
  picked: refs.some((x) => x.token === r.token && x.id === r.id),
1938
2175
  attrs: { "data-entity-reference-candidate": `${r.token}:${r.id}` }
1939
2176
  }));
1940
- const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mb-1 flex flex-wrap gap-1", role: "group", "aria-label": `Which kind \u2014 ${field.label}`, children: [null, ...allowed].map((token) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1941
- import_design_system8.Button,
2177
+ const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-1 flex flex-wrap gap-1", role: "group", "aria-label": `Which kind \u2014 ${field.label}`, children: [null, ...allowed].map((token) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2178
+ import_design_system9.Button,
1942
2179
  {
1943
2180
  type: "button",
1944
2181
  size: "sm",
@@ -1949,26 +2186,23 @@ function EntityReferencePicker({
1949
2186
  children: token ? labelOfKind(token) : "Any"
1950
2187
  },
1951
2188
  token ?? "any"
1952
- )) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1953
- "select",
2189
+ )) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2190
+ PickOne,
1954
2191
  {
1955
- className: "mb-1 h-7 w-full rounded border border-border bg-background px-1 text-xs",
1956
- "aria-label": `Which kind \u2014 ${field.label}`,
2192
+ label: `Which kind \u2014 ${field.label}`,
2193
+ className: "mb-1 w-full",
1957
2194
  value: only ?? "",
1958
- onChange: (e) => setOnly(e.target.value || null),
1959
- children: [
1960
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "Any kind" }),
1961
- allowed.map((token) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: token, children: labelOfKind(token) }, token))
1962
- ]
2195
+ onChange: (picked) => setOnly(picked || null),
2196
+ options: [{ value: "", label: "Any kind" }, ...allowed.map((token) => ({ value: token, label: labelOfKind(token) }))]
1963
2197
  }
1964
2198
  ) : null;
1965
- const notice = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2199
+ const notice = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1966
2200
  kindChoice,
1967
- found.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RefusalLine, { error: found.error, className: "px-2 py-1 text-[11px]" }) : null,
1968
- found.loading && !found.data ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: "Searching\u2026" }) : null
2201
+ found.error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefusalLine, { error: found.error, className: "px-2 py-1 text-[11px]" }) : null,
2202
+ found.loading && !found.data ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: "Searching\u2026" }) : null
1969
2203
  ] });
1970
2204
  const kindWords = allowed.length === 1 ? labelOfKind(allowed[0]).toLowerCase() : "thing";
1971
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2205
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1972
2206
  PickOrAdd,
1973
2207
  {
1974
2208
  triggerLabel: `Pick for ${field.label}`,
@@ -1982,7 +2216,7 @@ function EntityReferencePicker({
1982
2216
  onSearch: setSearch,
1983
2217
  items,
1984
2218
  notice,
1985
- empty: found.loading ? null : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: search.trim() ? `No ${kindWords} you can open is called \u201C${search.trim()}\u201D.` : `There is no ${kindWords} you can open yet.` }),
2219
+ empty: found.loading ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: search.trim() ? `No ${kindWords} you can open is called \u201C${search.trim()}\u201D.` : `There is no ${kindWords} you can open yet.` }),
1986
2220
  onPick: (key) => {
1987
2221
  const r = (found.data ?? []).find((x) => `${x.token}:${x.id}` === key);
1988
2222
  if (!r) return;
@@ -2002,7 +2236,7 @@ function Chips({
2002
2236
  words,
2003
2237
  picker
2004
2238
  }) {
2005
- const refs = (0, import_react13.useMemo)(() => (0, import_records6.entityRefsOf)(value), [value]);
2239
+ const refs = (0, import_react15.useMemo)(() => (0, import_records6.entityRefsOf)(value), [value]);
2006
2240
  const labelOf = (token, refId, own3) => {
2007
2241
  if (own3) return own3;
2008
2242
  const read = words?.data?.find((w) => w.token === token && w.id === refId)?.label;
@@ -2012,13 +2246,13 @@ function Chips({
2012
2246
  return WITHHELD_ENTITY_LABEL;
2013
2247
  };
2014
2248
  const multi = Boolean(field.multi);
2015
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { id, className: (0, import_design_system8.cn)("flex flex-wrap items-center gap-1", className), "aria-label": `What ${field.label} points at`, children: [
2016
- refs.length === 0 && !picker ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[11px] text-muted-foreground", children: ENTITY_REFERENCE_EMPTY }) : null,
2249
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { id, className: (0, import_design_system9.cn)("flex flex-wrap items-center gap-1", className), "aria-label": `What ${field.label} points at`, children: [
2250
+ refs.length === 0 && !picker ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-[11px] text-muted-foreground", children: ENTITY_REFERENCE_EMPTY }) : null,
2017
2251
  refs.map((r) => {
2018
2252
  const label = labelOf(r.token, r.id, r.label);
2019
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_design_system8.Badge, { variant: "secondary", className: "gap-1 text-[11px]", "data-entity-reference-chip": `${r.token}:${r.id}`, children: [
2253
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_design_system9.Badge, { variant: "secondary", className: "gap-1 text-[11px]", "data-entity-reference-chip": `${r.token}:${r.id}`, children: [
2020
2254
  label,
2021
- disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2255
+ disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2022
2256
  "button",
2023
2257
  {
2024
2258
  type: "button",
@@ -2038,11 +2272,11 @@ function Chips({
2038
2272
  }
2039
2273
 
2040
2274
  // src/PersonPicker.tsx
2041
- var import_react15 = require("react");
2275
+ var import_react17 = require("react");
2042
2276
  var import_records7 = require("@ai-matrx/records");
2043
- var import_react16 = require("@ai-matrx/records/react");
2044
- var import_design_system9 = require("@ai-matrx/design-system");
2045
- var import_jsx_runtime11 = require("react/jsx-runtime");
2277
+ var import_react18 = require("@ai-matrx/records/react");
2278
+ var import_design_system10 = require("@ai-matrx/design-system");
2279
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2046
2280
  function personFromRow(row) {
2047
2281
  const data = row.document ?? {};
2048
2282
  const userId = data["user_id"];
@@ -2073,27 +2307,27 @@ async function personRecordForMember(client, personTableId, people, member) {
2073
2307
  return written;
2074
2308
  }
2075
2309
  function PersonPicker({ field, value, onChange, disabled, id, className, autoOpen, onClose, initialSearch }) {
2076
- const client = (0, import_react16.useOptionalRecordsClient)();
2310
+ const client = (0, import_react18.useOptionalRecordsClient)();
2077
2311
  const host = useRecordsUi();
2078
- const [members, setMembers] = (0, import_react15.useState)(null);
2079
- const [people, setPeople] = (0, import_react15.useState)([]);
2080
- const [error, setError] = (0, import_react15.useState)(null);
2081
- const [search, setSearch] = (0, import_react15.useState)(initialSearch ?? "");
2082
- const [open, setOpenState] = (0, import_react15.useState)(autoOpen === true);
2083
- const onCloseRef = (0, import_react15.useRef)(onClose);
2312
+ const [members, setMembers] = (0, import_react17.useState)(null);
2313
+ const [people, setPeople] = (0, import_react17.useState)([]);
2314
+ const [error, setError] = (0, import_react17.useState)(null);
2315
+ const [search, setSearch] = (0, import_react17.useState)(initialSearch ?? "");
2316
+ const [open, setOpenState] = (0, import_react17.useState)(autoOpen === true);
2317
+ const onCloseRef = (0, import_react17.useRef)(onClose);
2084
2318
  onCloseRef.current = onClose;
2085
- const setOpen = (0, import_react15.useCallback)((next) => {
2319
+ const setOpen = (0, import_react17.useCallback)((next) => {
2086
2320
  setOpenState(next);
2087
2321
  if (!next) onCloseRef.current?.();
2088
2322
  }, []);
2089
- const [busy, setBusy] = (0, import_react15.useState)(false);
2323
+ const [busy, setBusy] = (0, import_react17.useState)(false);
2090
2324
  const membersPort = host.members;
2091
2325
  const personTable = field.relation_target;
2092
- const picked = (0, import_react15.useMemo)(
2326
+ const picked = (0, import_react17.useMemo)(
2093
2327
  () => Array.isArray(value) ? value.map(String) : value === null || value === void 0 ? [] : [String(value)],
2094
2328
  [value]
2095
2329
  );
2096
- const load = (0, import_react15.useCallback)(async () => {
2330
+ const load = (0, import_react17.useCallback)(async () => {
2097
2331
  if (!membersPort || !client) return;
2098
2332
  const [roster, records] = await Promise.all([
2099
2333
  membersPort(),
@@ -2106,11 +2340,11 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2106
2340
  }
2107
2341
  setPeople(records ? records.data.rows.map(personFromRow).filter((p) => p.userId !== null) : []);
2108
2342
  }, [membersPort, client, personTable]);
2109
- (0, import_react15.useEffect)(() => {
2343
+ (0, import_react17.useEffect)(() => {
2110
2344
  if (!open) return;
2111
2345
  void load();
2112
2346
  }, [open, load]);
2113
- (0, import_react15.useEffect)(() => {
2347
+ (0, import_react17.useEffect)(() => {
2114
2348
  if (picked.length === 0 || !personTable || people.length > 0 || !client) return;
2115
2349
  let cancelled = false;
2116
2350
  void client.list({ table_id: personTable, limit: 500 }).then((result) => {
@@ -2131,12 +2365,12 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2131
2365
  },
2132
2366
  onClose: () => setOpen(false)
2133
2367
  });
2134
- const pickRef = (0, import_react15.useRef)(null);
2368
+ const pickRef = (0, import_react17.useRef)(null);
2135
2369
  if (!membersPort || !client) {
2136
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: (0, import_design_system9.cn)("text-xs text-muted-foreground", className), children: NO_MEMBERS_REASON });
2370
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: (0, import_design_system10.cn)("text-xs text-muted-foreground", className), children: NO_MEMBERS_REASON });
2137
2371
  }
2138
2372
  if (!personTable) {
2139
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: (0, import_design_system9.cn)("text-xs text-muted-foreground", className), children: [
2373
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: (0, import_design_system10.cn)("text-xs text-muted-foreground", className), children: [
2140
2374
  fieldName(field),
2141
2375
  " is a person field, but it does not say which Table the people are records of yet, so there is nothing to pick from. A table admin sets its target in the field editor."
2142
2376
  ] });
@@ -2179,8 +2413,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2179
2413
  const pickedUserIds = new Set(
2180
2414
  picked.map((recordId) => people.find((p) => p.id === recordId)?.userId).filter(Boolean)
2181
2415
  );
2182
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: (0, import_design_system9.cn)("flex flex-wrap items-center gap-1", className), children: [
2183
- picked.map((recordId) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2416
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: (0, import_design_system10.cn)("flex flex-wrap items-center gap-1", className), children: [
2417
+ picked.map((recordId) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2184
2418
  RecordChip,
2185
2419
  {
2186
2420
  title: nameOfRecord(recordId),
@@ -2188,9 +2422,9 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2188
2422
  },
2189
2423
  recordId
2190
2424
  )),
2191
- disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_design_system9.Popover, { open, onOpenChange: setOpen, children: [
2192
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_design_system9.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2193
- import_design_system9.Button,
2425
+ disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system10.Popover, { open, onOpenChange: setOpen, children: [
2426
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_design_system10.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2427
+ import_design_system10.Button,
2194
2428
  {
2195
2429
  id,
2196
2430
  type: "button",
@@ -2200,8 +2434,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2200
2434
  children: picked.length === 0 ? "Pick a person" : "Change"
2201
2435
  }
2202
2436
  ) }),
2203
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2204
- import_design_system9.PopoverContent,
2437
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2438
+ import_design_system10.PopoverContent,
2205
2439
  {
2206
2440
  sizing: "content",
2207
2441
  className: "p-1",
@@ -2209,8 +2443,8 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2209
2443
  "data-matrx-cell-editor": "",
2210
2444
  onKeyDown: (event) => event.stopPropagation(),
2211
2445
  children: [
2212
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2213
- import_design_system9.BasicInput,
2446
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2447
+ import_design_system10.BasicInput,
2214
2448
  {
2215
2449
  value: search,
2216
2450
  onChange: (e) => setSearch(e.target.value),
@@ -2222,31 +2456,31 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2222
2456
  className: "mb-1 h-7 text-xs"
2223
2457
  }
2224
2458
  ),
2225
- error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefusalLine, { error, className: "p-2" }) : null,
2226
- members === null ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading the members\u2026" }) : null,
2227
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_design_system9.ScrollArea, { className: "max-h-56", children: [
2228
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { role: "listbox", "aria-label": `People for ${fieldName(field)}`, children: visible.map((member, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2459
+ error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefusalLine, { error, className: "p-2" }) : null,
2460
+ members === null ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading the members\u2026" }) : null,
2461
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system10.ScrollArea, { className: "max-h-56", children: [
2462
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { role: "listbox", "aria-label": `People for ${fieldName(field)}`, children: visible.map((member, index) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2229
2463
  "button",
2230
2464
  {
2231
2465
  type: "button",
2232
2466
  disabled: busy,
2233
2467
  "data-pick-highlighted": index === keys.highlight ? "" : void 0,
2234
2468
  onClick: () => void pick(member),
2235
- className: (0, import_design_system9.cn)(
2469
+ className: (0, import_design_system10.cn)(
2236
2470
  "w-full truncate rounded px-2 py-1 text-left text-xs hover:bg-muted",
2237
2471
  pickedUserIds.has(member.userId) ? "bg-accent text-accent-foreground" : "",
2238
2472
  index === keys.highlight ? "ring-1 ring-ring" : ""
2239
2473
  ),
2240
2474
  children: [
2241
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: memberName(member) }),
2242
- member.email && member.email !== memberName(member) ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "ml-1.5 opacity-60", children: [
2475
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: memberName(member) }),
2476
+ member.email && member.email !== memberName(member) ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ml-1.5 opacity-60", children: [
2243
2477
  "\xB7 ",
2244
2478
  member.email
2245
2479
  ] }) : null
2246
2480
  ]
2247
2481
  }
2248
2482
  ) }, member.userId)) }),
2249
- members !== null && visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: members.length === 0 ? "This organization has no other members yet, so there is nobody to assign." : "Nobody in this organization matches." }) : null
2483
+ members !== null && visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: members.length === 0 ? "This organization has no other members yet, so there is nobody to assign." : "Nobody in this organization matches." }) : null
2250
2484
  ] })
2251
2485
  ]
2252
2486
  }
@@ -2256,7 +2490,7 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2256
2490
  }
2257
2491
 
2258
2492
  // src/presentation.ts
2259
- var import_data_table = require("@ai-matrx/design-system/data-table");
2493
+ var import_data_table2 = require("@ai-matrx/design-system/data-table");
2260
2494
  var import_field_formats2 = require("@ai-matrx/design-system/field-formats");
2261
2495
  var import_records8 = require("@ai-matrx/records");
2262
2496
  var DRAWN_KINDS = /* @__PURE__ */ new Set(["select", "multi_select", "relation", "member", "person", "attachment", "file", "entity_reference", "checkbox", "boolean", "signature", "json"]);
@@ -2318,16 +2552,16 @@ function currencyCodeFor(unit) {
2318
2552
  }
2319
2553
 
2320
2554
  // src/formatControls.tsx
2321
- var import_react18 = require("react");
2322
- var import_design_system11 = require("@ai-matrx/design-system");
2555
+ var import_react20 = require("react");
2556
+ var import_design_system12 = require("@ai-matrx/design-system");
2323
2557
  var import_field_formats4 = require("@ai-matrx/design-system/field-formats");
2324
2558
 
2325
2559
  // src/formattedValue.tsx
2326
- var import_react17 = require("react");
2327
- var import_data_table2 = require("@ai-matrx/design-system/data-table");
2560
+ var import_react19 = require("react");
2561
+ var import_data_table3 = require("@ai-matrx/design-system/data-table");
2328
2562
  var import_field_formats3 = require("@ai-matrx/design-system/field-formats");
2329
- var import_design_system10 = require("@ai-matrx/design-system");
2330
- var import_jsx_runtime12 = require("react/jsx-runtime");
2563
+ var import_design_system11 = require("@ai-matrx/design-system");
2564
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2331
2565
  var LINK = "inline-flex min-w-0 items-center gap-1 text-primary hover:underline";
2332
2566
  var own2 = (event) => event.stopPropagation();
2333
2567
  function numberOf(value) {
@@ -2345,11 +2579,11 @@ function RatingStars({
2345
2579
  label,
2346
2580
  selectFirst
2347
2581
  }) {
2348
- const armed = (0, import_react17.useRef)(true);
2582
+ const armed = (0, import_react19.useRef)(true);
2349
2583
  const score = numberOf(value) ?? 0;
2350
2584
  const shown2 = Math.round(score);
2351
2585
  const said = `${shown2} out of ${max}`;
2352
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2586
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2353
2587
  "span",
2354
2588
  {
2355
2589
  "data-records-rating": "",
@@ -2361,8 +2595,8 @@ function RatingStars({
2361
2595
  children: Array.from({ length: max }, (_, i) => {
2362
2596
  const n = i + 1;
2363
2597
  const lit = n <= shown2;
2364
- const star = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { "aria-hidden": true, className: (0, import_design_system10.cn)("text-sm leading-none", lit ? "text-amber-400" : "text-muted-foreground/40"), children: "\u2605" });
2365
- return onRate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2598
+ const star = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { "aria-hidden": true, className: (0, import_design_system11.cn)("text-sm leading-none", lit ? "text-amber-400" : "text-muted-foreground/40"), children: "\u2605" });
2599
+ return onRate ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2366
2600
  "button",
2367
2601
  {
2368
2602
  type: "button",
@@ -2387,7 +2621,7 @@ function RatingStars({
2387
2621
  children: star
2388
2622
  },
2389
2623
  n
2390
- ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: star }, n);
2624
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: star }, n);
2391
2625
  })
2392
2626
  }
2393
2627
  );
@@ -2395,13 +2629,13 @@ function RatingStars({
2395
2629
  function rich(id, text, raw, format) {
2396
2630
  switch (id) {
2397
2631
  case "email":
2398
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { href: `mailto:${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "truncate", children: text }) });
2632
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("a", { href: `mailto:${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: text }) });
2399
2633
  case "url":
2400
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { href: text.includes("://") ? text : `https://${text}`, target: "_blank", rel: "noopener noreferrer", className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "truncate", children: text }) });
2634
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("a", { href: text.includes("://") ? text : `https://${text}`, target: "_blank", rel: "noopener noreferrer", className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: text }) });
2401
2635
  case "phone":
2402
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { href: `tel:${text.replace(/[^\d+]/g, "")}`, className: LINK, onClick: own2, title: text, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "truncate tabular-nums", children: formatPhone(text) }) });
2636
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("a", { href: `tel:${text.replace(/[^\d+]/g, "")}`, className: LINK, onClick: own2, title: text, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate tabular-nums", children: (0, import_field_formats3.formatPhone)(text) }) });
2403
2637
  case "address":
2404
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2638
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2405
2639
  "a",
2406
2640
  {
2407
2641
  href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(text)}`,
@@ -2410,7 +2644,7 @@ function rich(id, text, raw, format) {
2410
2644
  className: LINK,
2411
2645
  title: "Open in maps",
2412
2646
  onClick: own2,
2413
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "truncate", children: text })
2647
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: text })
2414
2648
  }
2415
2649
  );
2416
2650
  case "progress": {
@@ -2418,8 +2652,8 @@ function rich(id, text, raw, format) {
2418
2652
  if (n === null) return void 0;
2419
2653
  const pct = format.options?.percentScale === "fraction" ? n * 100 : n;
2420
2654
  const clamped = Math.max(0, Math.min(100, pct));
2421
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "inline-flex w-full min-w-0 items-center gap-2", title: text, children: [
2422
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2655
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "inline-flex w-full min-w-0 items-center gap-2", title: text, children: [
2656
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2423
2657
  "span",
2424
2658
  {
2425
2659
  role: "progressbar",
@@ -2427,24 +2661,24 @@ function rich(id, text, raw, format) {
2427
2661
  "aria-valuemax": 100,
2428
2662
  "aria-valuenow": Math.round(clamped),
2429
2663
  className: "h-1.5 min-w-8 flex-1 overflow-hidden rounded-full bg-muted",
2430
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: (0, import_design_system10.cn)("block h-full rounded-full", pct >= 100 ? "bg-emerald-500" : "bg-primary"), style: { width: `${clamped}%` } })
2664
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: (0, import_design_system11.cn)("block h-full rounded-full", pct >= 100 ? "bg-emerald-500" : "bg-primary"), style: { width: `${clamped}%` } })
2431
2665
  }
2432
2666
  ),
2433
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: text })
2667
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: text })
2434
2668
  ] });
2435
2669
  }
2436
2670
  case "color":
2437
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
2438
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "h-4 w-4 shrink-0 rounded border border-border", style: { backgroundColor: text } }),
2439
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { className: "font-mono text-xs", children: text })
2671
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
2672
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "h-4 w-4 shrink-0 rounded border border-border", style: { backgroundColor: text } }),
2673
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("code", { className: "font-mono text-xs", children: text })
2440
2674
  ] });
2441
2675
  case "tags": {
2442
2676
  const items = Array.isArray(raw) ? raw.map(String) : text.split(",").map((s) => s.trim()).filter(Boolean);
2443
2677
  if (items.length === 0) return void 0;
2444
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "flex flex-wrap items-center gap-1", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "inline-flex items-center rounded-md border border-border bg-muted px-1.5 py-0.5 text-xs", children: item }, `${item}-${i}`)) });
2678
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "flex flex-wrap items-center gap-1", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "inline-flex items-center rounded-md border border-border bg-muted px-1.5 py-0.5 text-xs", children: item }, `${item}-${i}`)) });
2445
2679
  }
2446
2680
  case "rating":
2447
- return numberOf(raw) === null ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RatingStars, { value: raw, max: format.options?.ratingMax ?? 5 });
2681
+ return numberOf(raw) === null ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RatingStars, { value: raw, max: format.options?.ratingMax ?? 5 });
2448
2682
  default:
2449
2683
  return void 0;
2450
2684
  }
@@ -2459,21 +2693,11 @@ function FormattedValue({
2459
2693
  const score = numberOf(value);
2460
2694
  const max = format.options?.ratingMax ?? 5;
2461
2695
  if (def?.id === "rating" && onRate && (value === null || value === void 0 || value === "" || score !== null && score >= 0 && score <= max)) {
2462
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
2696
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
2463
2697
  }
2464
2698
  const result = (0, import_field_formats3.formatFieldValue)(value, format);
2465
- if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_data_table2.FormattedCell, { result });
2466
- return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_data_table2.FormattedCell, { result });
2467
- }
2468
- function formatPhone(raw) {
2469
- const text = raw.trim();
2470
- const digits = text.replace(/\D/g, "");
2471
- if (/[a-z]/i.test(text.replace(/ext\.?|x/gi, ""))) return text;
2472
- if (digits.length === 10 && !text.startsWith("+")) return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
2473
- if (digits.length === 11 && digits.startsWith("1") && (text.startsWith("+1") || text.startsWith("1") || !text.startsWith("+"))) {
2474
- return `+1 (${digits.slice(1, 4)}) ${digits.slice(4, 7)}-${digits.slice(7)}`;
2475
- }
2476
- return text;
2699
+ if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_data_table3.FormattedCell, { result });
2700
+ return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_data_table3.FormattedCell, { result });
2477
2701
  }
2478
2702
  function linkChipText(raw) {
2479
2703
  try {
@@ -2487,7 +2711,7 @@ function linkChipText(raw) {
2487
2711
  }
2488
2712
 
2489
2713
  // src/formatControls.tsx
2490
- var import_jsx_runtime13 = require("react/jsx-runtime");
2714
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2491
2715
  var TYPED_NUMBERS = /* @__PURE__ */ new Set(["currency", "percent", "progress", "decimal", "duration", "file_size", "integer"]);
2492
2716
  function scaled(format) {
2493
2717
  return (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction";
@@ -2504,14 +2728,14 @@ function keptValue(format, raw) {
2504
2728
  return parsed;
2505
2729
  }
2506
2730
  function NumberInFormat({ format, value, onChange, disabled, id }) {
2507
- const [text, setText] = (0, import_react18.useState)(() => typedText(format, value));
2508
- const lastSent = (0, import_react18.useRef)(void 0);
2509
- (0, import_react18.useEffect)(() => {
2731
+ const [text, setText] = (0, import_react20.useState)(() => typedText(format, value));
2732
+ const lastSent = (0, import_react20.useRef)(void 0);
2733
+ (0, import_react20.useEffect)(() => {
2510
2734
  if (value === lastSent.current) return;
2511
2735
  setText(typedText(format, value));
2512
2736
  }, [value, format]);
2513
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2514
- import_design_system11.BasicInput,
2737
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2738
+ import_design_system12.BasicInput,
2515
2739
  {
2516
2740
  id,
2517
2741
  inputMode: "decimal",
@@ -2535,17 +2759,17 @@ function formatControl(args) {
2535
2759
  const text = value === null || value === void 0 ? "" : String(value);
2536
2760
  const commit = (raw) => onChange(raw === "" ? null : (0, import_field_formats4.parseFieldInput)(raw, format));
2537
2761
  if (def.id === "rating") {
2538
- return disabled ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, label }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { id, className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, label, onRate: (n) => onChange(n) }) });
2762
+ return disabled ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, label }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { id, className: "inline-flex", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, label, onRate: (n) => onChange(n) }) });
2539
2763
  }
2540
- if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NumberInFormat, { ...args });
2764
+ if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NumberInFormat, { ...args });
2541
2765
  switch (def.editor) {
2542
2766
  // A TIME OF DAY is not this file's: `FieldControl` draws the typed box and its helper
2543
2767
  // (`TypedWordsControl`), never the browser's time control (grids review 3, 2026-09-30).
2544
2768
  case "email":
2545
2769
  case "url":
2546
2770
  case "tel":
2547
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2548
- import_design_system11.BasicInput,
2771
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2772
+ import_design_system12.BasicInput,
2549
2773
  {
2550
2774
  id,
2551
2775
  type: def.editor,
@@ -2556,9 +2780,9 @@ function formatControl(args) {
2556
2780
  }
2557
2781
  );
2558
2782
  case "color":
2559
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "flex items-center gap-2", children: [
2560
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2561
- import_design_system11.BasicInput,
2783
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex items-center gap-2", children: [
2784
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2785
+ import_design_system12.BasicInput,
2562
2786
  {
2563
2787
  id: `${id}-swatch`,
2564
2788
  type: "color",
@@ -2569,20 +2793,20 @@ function formatControl(args) {
2569
2793
  onChange: (e) => commit(e.target.value)
2570
2794
  }
2571
2795
  ),
2572
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system11.BasicInput, { id, value: text, placeholder: "#3b82f6", disabled, onChange: (e) => commit(e.target.value) })
2796
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system12.BasicInput, { id, value: text, placeholder: "#3b82f6", disabled, onChange: (e) => commit(e.target.value) })
2573
2797
  ] });
2574
2798
  case "textarea":
2575
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_design_system11.BasicTextarea, { id, rows: 4, value: text, disabled, onChange: (e) => commit(e.target.value) });
2799
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system12.BasicTextarea, { id, rows: 4, value: text, disabled, onChange: (e) => commit(e.target.value) });
2576
2800
  default:
2577
2801
  return null;
2578
2802
  }
2579
2803
  }
2580
2804
 
2581
2805
  // src/typedDateHelper.tsx
2582
- var import_react19 = require("react");
2583
- var import_design_system12 = require("@ai-matrx/design-system");
2806
+ var import_react21 = require("react");
2807
+ var import_design_system13 = require("@ai-matrx/design-system");
2584
2808
  var import_records9 = require("@ai-matrx/records");
2585
- var import_jsx_runtime14 = require("react/jsx-runtime");
2809
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2586
2810
  var WEEK = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
2587
2811
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
2588
2812
  function pad(n) {
@@ -2611,23 +2835,23 @@ function wordsFor(kind, day, time) {
2611
2835
  }
2612
2836
  var keepFocus = { onMouseDown: (e) => e.preventDefault(), tabIndex: -1 };
2613
2837
  function CalendarGlyph() {
2614
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2615
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
2616
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M16 2v4M8 2v4M3 10h18" })
2838
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2839
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
2840
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M16 2v4M8 2v4M3 10h18" })
2617
2841
  ] });
2618
2842
  }
2619
2843
  function ClockGlyph() {
2620
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2621
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2622
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M12 6v6l4 2" })
2844
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2845
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2846
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M12 6v6l4 2" })
2623
2847
  ] });
2624
2848
  }
2625
2849
  function TypedDateHelper({ kind, text, onText, label }) {
2626
- const [open, setOpen] = (0, import_react19.useState)(false);
2850
+ const [open, setOpen] = (0, import_react21.useState)(false);
2627
2851
  const held = readBox(text, kind);
2628
2852
  const today = /* @__PURE__ */ new Date();
2629
2853
  const start = held.day ? new Date(Number(held.day.slice(0, 4)), Number(held.day.slice(5, 7)) - 1, 1) : new Date(today.getFullYear(), today.getMonth(), 1);
2630
- const [month, setMonth] = (0, import_react19.useState)(null);
2854
+ const [month, setMonth] = (0, import_react21.useState)(null);
2631
2855
  const shown2 = month ?? { y: start.getFullYear(), m: start.getMonth() };
2632
2856
  const first = new Date(shown2.y, shown2.m, 1).getDay();
2633
2857
  const days = new Date(shown2.y, shown2.m + 1, 0).getDate();
@@ -2648,8 +2872,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
2648
2872
  const at = new Date(shown2.y, shown2.m + by, 1);
2649
2873
  setMonth({ y: at.getFullYear(), m: at.getMonth() });
2650
2874
  };
2651
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_design_system12.Popover, { open, onOpenChange: setOpen, children: [
2652
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_design_system12.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2875
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system13.Popover, { open, onOpenChange: setOpen, children: [
2876
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2653
2877
  "button",
2654
2878
  {
2655
2879
  type: "button",
@@ -2658,11 +2882,11 @@ function TypedDateHelper({ kind, text, onText, label }) {
2658
2882
  "aria-label": kind === "time" ? `Pick a time for ${label}` : `Pick a date for ${label}`,
2659
2883
  title: kind === "time" ? "Pick a time" : "Pick a date",
2660
2884
  className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
2661
- children: kind === "time" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ClockGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CalendarGlyph, {})
2885
+ children: kind === "time" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ClockGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CalendarGlyph, {})
2662
2886
  }
2663
2887
  ) }),
2664
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2665
- import_design_system12.PopoverContent,
2888
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2889
+ import_design_system13.PopoverContent,
2666
2890
  {
2667
2891
  sizing: "content",
2668
2892
  align: "start",
@@ -2671,29 +2895,29 @@ function TypedDateHelper({ kind, text, onText, label }) {
2671
2895
  "data-records-date-helper-panel": "",
2672
2896
  onOpenAutoFocus: (e) => e.preventDefault(),
2673
2897
  onCloseAutoFocus: (e) => e.preventDefault(),
2674
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-2", children: [
2675
- kind === "time" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", role: "grid", "aria-label": `${MONTHS[shown2.m]} ${shown2.y}`, children: [
2676
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between text-xs font-medium", children: [
2677
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", ...keepFocus, "aria-label": "Previous month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(-1), children: "\u2039" }),
2678
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
2898
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex gap-2", children: [
2899
+ kind === "time" ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", role: "grid", "aria-label": `${MONTHS[shown2.m]} ${shown2.y}`, children: [
2900
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center justify-between text-xs font-medium", children: [
2901
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", ...keepFocus, "aria-label": "Previous month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(-1), children: "\u2039" }),
2902
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
2679
2903
  MONTHS[shown2.m],
2680
2904
  " ",
2681
2905
  shown2.y
2682
2906
  ] }),
2683
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", ...keepFocus, "aria-label": "Next month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(1), children: "\u203A" })
2907
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", ...keepFocus, "aria-label": "Next month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(1), children: "\u203A" })
2684
2908
  ] }),
2685
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-7 gap-0.5 text-center text-[11px]", children: [
2686
- WEEK.map((w) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-muted-foreground", children: w }, w)),
2909
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "grid grid-cols-7 gap-0.5 text-center text-[11px]", children: [
2910
+ WEEK.map((w) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-muted-foreground", children: w }, w)),
2687
2911
  cells.map((d, i) => {
2688
- if (d === null) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", {}, `blank-${i}`);
2912
+ if (d === null) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", {}, `blank-${i}`);
2689
2913
  const key = `${shown2.y}-${pad(shown2.m + 1)}-${pad(d)}`;
2690
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2914
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2691
2915
  "button",
2692
2916
  {
2693
2917
  type: "button",
2694
2918
  ...keepFocus,
2695
2919
  "data-records-date-helper-day": key,
2696
- className: (0, import_design_system12.cn)(
2920
+ className: (0, import_design_system13.cn)(
2697
2921
  "h-6 w-6 rounded tabular-nums hover:bg-muted",
2698
2922
  key === held.day ? "bg-primary text-primary-foreground hover:bg-primary" : "",
2699
2923
  key === todayKey && key !== held.day ? "ring-1 ring-ring" : ""
@@ -2706,13 +2930,13 @@ function TypedDateHelper({ kind, text, onText, label }) {
2706
2930
  })
2707
2931
  ] })
2708
2932
  ] }),
2709
- kind === "date" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex max-h-48 flex-col overflow-y-auto pr-1 text-[11px]", "aria-label": "Times", children: times.map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2933
+ kind === "date" ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex max-h-48 flex-col overflow-y-auto pr-1 text-[11px]", "aria-label": "Times", children: times.map((t) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2710
2934
  "button",
2711
2935
  {
2712
2936
  type: "button",
2713
2937
  ...keepFocus,
2714
2938
  "data-records-date-helper-time": `${pad(t.h)}:${pad(t.m)}`,
2715
- className: (0, import_design_system12.cn)(
2939
+ className: (0, import_design_system13.cn)(
2716
2940
  "whitespace-nowrap rounded px-2 py-0.5 text-left tabular-nums hover:bg-muted",
2717
2941
  held.time && held.time.h === t.h && held.time.m === t.m ? "bg-primary text-primary-foreground" : ""
2718
2942
  ),
@@ -2728,8 +2952,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
2728
2952
  }
2729
2953
 
2730
2954
  // src/choiceNudge.ts
2731
- var import_react20 = require("react");
2732
- var import_react21 = require("@ai-matrx/records/react");
2955
+ var import_react22 = require("react");
2956
+ var import_react23 = require("@ai-matrx/records/react");
2733
2957
  var asked = /* @__PURE__ */ new WeakMap();
2734
2958
  function choiceNudgeOf(client) {
2735
2959
  let answer = asked.get(client);
@@ -2743,9 +2967,9 @@ function choiceNudgeOf(client) {
2743
2967
  return answer;
2744
2968
  }
2745
2969
  function useChoiceNudge(enabled = true) {
2746
- const client = (0, import_react21.useOptionalRecordsClient)();
2747
- const [nudge, setNudge] = (0, import_react20.useState)(null);
2748
- (0, import_react20.useEffect)(() => {
2970
+ const client = (0, import_react23.useOptionalRecordsClient)();
2971
+ const [nudge, setNudge] = (0, import_react22.useState)(null);
2972
+ (0, import_react22.useEffect)(() => {
2749
2973
  if (!enabled || !client) return;
2750
2974
  let live = true;
2751
2975
  void choiceNudgeOf(client).then((answer) => {
@@ -2759,61 +2983,8 @@ function useChoiceNudge(enabled = true) {
2759
2983
  return nudge;
2760
2984
  }
2761
2985
 
2762
- // src/choiceLooks.ts
2763
- var import_data_table3 = require("@ai-matrx/design-system/data-table");
2764
- function displayFormatOf(field) {
2765
- const raw = field.display_format;
2766
- if (!raw || typeof raw !== "object") return null;
2767
- const id = raw.id;
2768
- if (typeof id !== "string" || id === "") return null;
2769
- const options = raw.options;
2770
- return { id, options: options && typeof options === "object" ? options : {} };
2771
- }
2772
- function isStyleColor(v) {
2773
- return typeof v === "string" && import_data_table3.STYLE_COLORS.includes(v);
2774
- }
2775
- function choiceLooksOf(field) {
2776
- const display = displayFormatOf(field);
2777
- const choices = display?.options["choices"];
2778
- if (!Array.isArray(choices)) return [];
2779
- const out = [];
2780
- for (const c of choices) {
2781
- if (!c || typeof c !== "object") continue;
2782
- const value = c.value;
2783
- if (typeof value !== "string" || value.trim() === "") continue;
2784
- const color = c.color;
2785
- const label = c.label;
2786
- out.push({
2787
- value: value.trim(),
2788
- ...typeof label === "string" && label.trim() !== "" ? { label: label.trim() } : {},
2789
- ...isStyleColor(color) ? { color } : {}
2790
- });
2791
- }
2792
- return out;
2793
- }
2794
- function choiceWord(value) {
2795
- return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
2796
- }
2797
- function storedChoiceColor(field, value) {
2798
- if (value === null || value === void 0 || value === "") return void 0;
2799
- const word = choiceWord(value);
2800
- if (word === "") return void 0;
2801
- for (const look of choiceLooksOf(field)) {
2802
- if (!look.color) continue;
2803
- if (choiceWord(look.value) === word || look.label && choiceWord(look.label) === word) return look.color;
2804
- }
2805
- return void 0;
2806
- }
2807
- function choiceChipLookOf(field, ...words) {
2808
- for (const word of words) {
2809
- const color = storedChoiceColor(field, word);
2810
- if (color) return { className: import_data_table3.CHOICE_CHIP_CLASS[color], color };
2811
- }
2812
- return { className: import_data_table3.NEUTRAL_CHIP_CLASS, color: null };
2813
- }
2814
-
2815
2986
  // src/editors.tsx
2816
- var import_jsx_runtime15 = require("react/jsx-runtime");
2987
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2817
2988
  var CHOICE_EDITOR_ADDS_WHAT_IS_TYPED = true;
2818
2989
  function isChoiceAddition(value) {
2819
2990
  return typeof value === "object" && value !== null && value.addingChoices === true;
@@ -2843,12 +3014,12 @@ function ChoiceAskButtons({
2843
3014
  onCancel,
2844
3015
  busy
2845
3016
  }) {
2846
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field, words), className: "flex flex-col gap-1", children: [
2847
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field, words) }),
2848
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "flex flex-wrap items-center gap-1", children: [
2849
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.Button, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
2850
- keepOffered ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.Button, { type: "button", size: "sm", variant: "outline", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onKeep, children: "Keep as typed" }) : null,
2851
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onCancel, children: "Cancel" })
3017
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field, words), className: "flex flex-col gap-1", children: [
3018
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field, words) }),
3019
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-wrap items-center gap-1", children: [
3020
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
3021
+ keepOffered ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", variant: "outline", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onKeep, children: "Keep as typed" }) : null,
3022
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onCancel, children: "Cancel" })
2852
3023
  ] })
2853
3024
  ] });
2854
3025
  }
@@ -2931,12 +3102,12 @@ function openingText(field, value) {
2931
3102
  return format ? typedText(format, value) : String(value);
2932
3103
  }
2933
3104
  function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCancel }) {
2934
- const client = (0, import_react23.useOptionalRecordsClient)();
3105
+ const client = (0, import_react25.useOptionalRecordsClient)();
2935
3106
  const kind = String(editorKindFor(field));
2936
3107
  const needsChoices = kind === "select" || kind === "multi_select";
2937
3108
  const nudge = useChoiceNudge(needsChoices);
2938
- const [choices, setChoices] = (0, import_react22.useState)(null);
2939
- (0, import_react22.useEffect)(() => {
3109
+ const [choices, setChoices] = (0, import_react24.useState)(null);
3110
+ (0, import_react24.useEffect)(() => {
2940
3111
  if (!needsChoices || !client) return;
2941
3112
  let cancelled = false;
2942
3113
  void client.fieldOptions({ field_id: field.id }).then((result) => {
@@ -2946,7 +3117,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
2946
3117
  cancelled = true;
2947
3118
  };
2948
3119
  }, [client, field.id, needsChoices]);
2949
- (0, import_react22.useEffect)(() => {
3120
+ (0, import_react24.useEffect)(() => {
2950
3121
  if (choices && nudge && value.judged === null) onChange({ ...value, judged: judgeTyped(field, value.text, choices, nudge) });
2951
3122
  }, [choices, nudge, value, field, onChange]);
2952
3123
  const judged = value.judged;
@@ -2958,8 +3129,8 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
2958
3129
  judged: judgeTyped(field, text, needsChoices ? choices : void 0, needsChoices ? nudge : void 0),
2959
3130
  ...value.openedAs !== void 0 ? { openedAs: value.openedAs } : {}
2960
3131
  });
2961
- const box = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2962
- import_design_system13.BasicInput,
3132
+ const box = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3133
+ import_design_system14.BasicInput,
2963
3134
  {
2964
3135
  id,
2965
3136
  value: value.text,
@@ -2970,16 +3141,16 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
2970
3141
  onChange: (e) => retype(e.target.value)
2971
3142
  }
2972
3143
  );
2973
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
2974
- helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "flex min-w-0 items-center gap-0.5", children: [
3144
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
3145
+ helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex min-w-0 items-center gap-0.5", children: [
2975
3146
  box,
2976
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field) })
3147
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field) })
2977
3148
  ] }) : box,
2978
- judged === null ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "text-[10px] text-muted-foreground", children: [
3149
+ judged === null ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "text-[10px] text-muted-foreground", children: [
2979
3150
  "Reading ",
2980
3151
  fieldName(field),
2981
3152
  "'s choices\u2026"
2982
- ] }) : "ask" in judged ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3153
+ ] }) : "ask" in judged ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2983
3154
  ChoiceAskButtons,
2984
3155
  {
2985
3156
  field,
@@ -2995,10 +3166,10 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
2995
3166
  },
2996
3167
  onCancel: () => onCancel?.()
2997
3168
  }
2998
- ) : "refusal" in judged ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "flex flex-col gap-1", children: [
2999
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
3000
- judged.cancelOnly && onCancel ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "data-records-choice-ask": "", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => onCancel(), children: "Cancel" }) }) : null
3001
- ] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
3169
+ ) : "refusal" in judged ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-1", children: [
3170
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
3171
+ judged.cancelOnly && onCancel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "data-records-choice-ask": "", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => onCancel(), children: "Cancel" }) }) : null
3172
+ ] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
3002
3173
  isChoiceAddition(judged.value) ? `Adds ${quoted(judged.value.add)} to the choices for ${fieldName(field)}. ` : null,
3003
3174
  "Reads as",
3004
3175
  " ",
@@ -3009,7 +3180,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
3009
3180
  }).join(", ")
3010
3181
  ) : (() => {
3011
3182
  const shown2 = format ?? (kind === "datetime" ? { id: carriesTimeOfDay(field, judged.value) ? "datetime" : "date" } : void 0);
3012
- return shown2 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FormattedValue, { value: judged.value, format: shown2 }) : String(judged.value);
3183
+ return shown2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FormattedValue, { value: judged.value, format: shown2 }) : String(judged.value);
3013
3184
  })()
3014
3185
  ] })
3015
3186
  ] });
@@ -3022,13 +3193,13 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3022
3193
  const host = useRecordsUi();
3023
3194
  const kind = editorKindFor(field);
3024
3195
  const inputId = id ?? `field-${field.key}`;
3025
- const ownDetails = (0, import_react23.useOptionalRecordsClient)() === null;
3026
- if (isTypedDraft(value)) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TypedTextControl, { field, value, onChange, disabled, id: inputId, onCommit, onCancel });
3027
- if (isSignatureField(field)) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SignaturePad, { id: inputId, value, onChange, disabled });
3196
+ const ownDetails = (0, import_react25.useOptionalRecordsClient)() === null;
3197
+ if (isTypedDraft(value)) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedTextControl, { field, value, onChange, disabled, id: inputId, onCommit, onCancel });
3198
+ if (isSignatureField(field)) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SignaturePad, { id: inputId, value, onChange, disabled });
3028
3199
  const newerControl = newerKindControl({ field, value, onChange, disabled, id: inputId });
3029
3200
  if (newerControl !== void 0) return newerControl;
3030
3201
  const format = formatForField(field);
3031
- if (format && format.id === "time") return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
3202
+ if (format && format.id === "time") return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
3032
3203
  if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
3033
3204
  const own3 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field), ownDetails });
3034
3205
  if (own3) return own3;
@@ -3037,18 +3208,18 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3037
3208
  case "formula":
3038
3209
  case "lookup":
3039
3210
  case "rollup":
3040
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { id: inputId, className: "rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground", children: [
3211
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { id: inputId, className: "rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground", children: [
3041
3212
  value === null || value === void 0 ? "\u2014" : String(value),
3042
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "ml-2 italic", children: [
3213
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "ml-2 italic", children: [
3043
3214
  fieldName(field),
3044
3215
  " is worked out by the system, so it cannot be typed in"
3045
3216
  ] })
3046
3217
  ] });
3047
3218
  case "json":
3048
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(JsonControl, { field, value, onChange, disabled, id: inputId });
3219
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(JsonControl, { field, value, onChange, disabled, id: inputId });
3049
3220
  case "long_text":
3050
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3051
- import_design_system13.BasicTextarea,
3221
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3222
+ import_design_system14.BasicTextarea,
3052
3223
  {
3053
3224
  id: inputId,
3054
3225
  rows: 3,
@@ -3060,8 +3231,8 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3060
3231
  case "number":
3061
3232
  case "currency":
3062
3233
  case "percent":
3063
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3064
- import_design_system13.BasicInput,
3234
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3235
+ import_design_system14.BasicInput,
3065
3236
  {
3066
3237
  id: inputId,
3067
3238
  type: "number",
@@ -3073,12 +3244,12 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3073
3244
  }
3074
3245
  );
3075
3246
  case "datetime":
3076
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
3247
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
3077
3248
  case "email":
3078
3249
  case "phone":
3079
3250
  case "url":
3080
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3081
- import_design_system13.BasicInput,
3251
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3252
+ import_design_system14.BasicInput,
3082
3253
  {
3083
3254
  id: inputId,
3084
3255
  type: kind === "email" ? "email" : kind === "phone" ? "tel" : "url",
@@ -3089,25 +3260,25 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3089
3260
  }
3090
3261
  );
3091
3262
  case "checkbox":
3092
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CheckboxControl, { field, value, onChange, disabled, id: inputId });
3263
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CheckboxControl, { field, value, onChange, disabled, id: inputId });
3093
3264
  case "select":
3094
3265
  case "multi_select":
3095
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(OptionControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
3266
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(OptionControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
3096
3267
  case "member":
3097
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PersonPicker, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
3268
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PersonPicker, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
3098
3269
  case "entity_reference":
3099
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(EntityReferenceControl, { field, value, onChange, disabled, id: inputId });
3270
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(EntityReferenceControl, { field, value, onChange, disabled, id: inputId });
3100
3271
  case "attachment":
3101
3272
  if (hostTakesFiles(host)) {
3102
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AttachmentControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose });
3273
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AttachmentControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose });
3103
3274
  }
3104
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
3275
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
3105
3276
  case "relation":
3106
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
3277
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RelationPicker, { field, value, onChange, disabled, id: inputId });
3107
3278
  default:
3108
3279
  if (typeof value === "boolean" || field.config?.["kind"] === "boolean") {
3109
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3110
- import_design_system13.Checkbox,
3280
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3281
+ import_design_system14.Checkbox,
3111
3282
  {
3112
3283
  id: inputId,
3113
3284
  checked: value === true,
@@ -3116,8 +3287,8 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3116
3287
  }
3117
3288
  );
3118
3289
  }
3119
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3120
- import_design_system13.BasicInput,
3290
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3291
+ import_design_system14.BasicInput,
3121
3292
  {
3122
3293
  id: inputId,
3123
3294
  ...ownDetails && isPersonsName(field) ? { autoComplete: "name" } : {},
@@ -3129,10 +3300,10 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3129
3300
  }
3130
3301
  }
3131
3302
  function TypedWordsControl({ field, value, onChange, disabled, id }) {
3132
- const [text, setText] = (0, import_react22.useState)(() => openingText(field, value));
3133
- const [refusal2, setRefusal] = (0, import_react22.useState)(null);
3134
- const sent = (0, import_react22.useRef)(value);
3135
- (0, import_react22.useEffect)(() => {
3303
+ const [text, setText] = (0, import_react24.useState)(() => openingText(field, value));
3304
+ const [refusal2, setRefusal] = (0, import_react24.useState)(null);
3305
+ const sent = (0, import_react24.useRef)(value);
3306
+ (0, import_react24.useEffect)(() => {
3136
3307
  if (value === sent.current) return;
3137
3308
  sent.current = value;
3138
3309
  setText(openingText(field, value));
@@ -3150,10 +3321,10 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
3150
3321
  setRefusal(judged.refusal);
3151
3322
  }
3152
3323
  };
3153
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
3154
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "flex min-w-0 items-center gap-0.5", children: [
3155
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3156
- import_design_system13.BasicInput,
3324
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex flex-col gap-0.5", children: [
3325
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "flex min-w-0 items-center gap-0.5", children: [
3326
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3327
+ import_design_system14.BasicInput,
3157
3328
  {
3158
3329
  id,
3159
3330
  value: text,
@@ -3169,16 +3340,16 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
3169
3340
  }
3170
3341
  }
3171
3342
  ),
3172
- helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field) }) : null
3343
+ helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field) }) : null
3173
3344
  ] }),
3174
- refusal2 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal2 }) : null
3345
+ refusal2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal2 }) : null
3175
3346
  ] });
3176
3347
  }
3177
3348
  function CheckboxControl({ field, value, onChange, disabled, id }) {
3178
3349
  const unanswered = value === null || value === void 0;
3179
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2", children: [
3180
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3181
- import_design_system13.Checkbox,
3350
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
3351
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3352
+ import_design_system14.Checkbox,
3182
3353
  {
3183
3354
  id,
3184
3355
  checked: value === true,
@@ -3187,10 +3358,10 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
3187
3358
  onCheckedChange: (next) => onChange(next === true)
3188
3359
  }
3189
3360
  ),
3190
- unanswered ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-xs italic text-muted-foreground", children: "not answered yet" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3191
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-xs text-muted-foreground", children: value === true ? "Yes" : "No" }),
3192
- field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3193
- import_design_system13.Button,
3361
+ unanswered ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-xs italic text-muted-foreground", children: "not answered yet" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3362
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-xs text-muted-foreground", children: value === true ? "Yes" : "No" }),
3363
+ field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3364
+ import_design_system14.Button,
3194
3365
  {
3195
3366
  size: "sm",
3196
3367
  variant: "ghost",
@@ -3205,11 +3376,11 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
3205
3376
  }
3206
3377
  function JsonControl({ field, value, onChange, disabled, id }) {
3207
3378
  const initial = value === null || value === void 0 ? "" : typeof value === "string" ? value : JSON.stringify(value, null, 2);
3208
- const [text, setText] = (0, import_react22.useState)(initial);
3209
- const [broken, setBroken] = (0, import_react22.useState)(null);
3210
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", children: [
3211
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3212
- import_design_system13.BasicTextarea,
3379
+ const [text, setText] = (0, import_react24.useState)(initial);
3380
+ const [broken, setBroken] = (0, import_react24.useState)(null);
3381
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
3382
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3383
+ import_design_system14.BasicTextarea,
3213
3384
  {
3214
3385
  id,
3215
3386
  rows: 4,
@@ -3242,7 +3413,7 @@ function JsonControl({ field, value, onChange, disabled, id }) {
3242
3413
  ),
3243
3414
  broken ? (
3244
3415
  // The typed text is still in the box: the notice owns the two doors out.
3245
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3416
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3246
3417
  RefusalNotice,
3247
3418
  {
3248
3419
  error: broken,
@@ -3266,11 +3437,11 @@ function inTheStoresOrder(options) {
3266
3437
  return [...options].sort((a, b) => position(a) - position(b) || made(a).localeCompare(made(b)));
3267
3438
  }
3268
3439
  function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose, addsChoices, initialSearch, asForm }) {
3269
- const client = (0, import_react23.useOptionalRecordsClient)();
3270
- const [options, setOptions] = (0, import_react22.useState)(null);
3271
- const [refusal2, setRefusal] = (0, import_react22.useState)(null);
3272
- const [reread, setReread] = (0, import_react22.useState)(0);
3273
- (0, import_react22.useEffect)(() => {
3440
+ const client = (0, import_react25.useOptionalRecordsClient)();
3441
+ const [options, setOptions] = (0, import_react24.useState)(null);
3442
+ const [refusal2, setRefusal] = (0, import_react24.useState)(null);
3443
+ const [reread, setReread] = (0, import_react24.useState)(0);
3444
+ (0, import_react24.useEffect)(() => {
3274
3445
  if (!client) return;
3275
3446
  let cancelled = false;
3276
3447
  void client.fieldOptions({ field_id: field.id }).then((result) => {
@@ -3284,12 +3455,12 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3284
3455
  }, [client, field.id, reread]);
3285
3456
  const handed = publicChoicesOf(field);
3286
3457
  if (!client && handed.length > 0) {
3287
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChoiceAnswer, { field, choices: handed, value, onChange, disabled, id });
3458
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChoiceAnswer, { field, choices: handed, value, onChange, disabled, id });
3288
3459
  }
3289
3460
  if (!client) {
3290
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", children: [
3291
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3292
- import_design_system13.BasicInput,
3461
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
3462
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3463
+ import_design_system14.BasicInput,
3293
3464
  {
3294
3465
  id,
3295
3466
  value: value === null || value === void 0 ? "" : String(value),
@@ -3297,15 +3468,15 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3297
3468
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
3298
3469
  }
3299
3470
  ),
3300
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-xs text-muted-foreground", children: "This is normally picked from a list. A page answered without an account cannot read that list, so type your answer and whoever receives it will match it up." })
3471
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-muted-foreground", children: "This is normally picked from a list. A page answered without an account cannot read that list, so type your answer and whoever receives it will match it up." })
3301
3472
  ] });
3302
3473
  }
3303
3474
  if (refusal2)
3304
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RefusalLine, { error: refusal2 }) });
3305
- if (!options) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
3475
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RefusalLine, { error: refusal2 }) });
3476
+ if (!options) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
3306
3477
  if (asForm && options.length > 0) {
3307
3478
  const titled = (option) => recordName(option.data, null, "Unnamed choice");
3308
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3479
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3309
3480
  ChoiceAnswer,
3310
3481
  {
3311
3482
  field,
@@ -3322,7 +3493,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3322
3493
  );
3323
3494
  }
3324
3495
  if (CHOICE_EDITOR_ADDS_WHAT_IS_TYPED) {
3325
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3496
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3326
3497
  OpenChoicePicker,
3327
3498
  {
3328
3499
  field,
@@ -3341,14 +3512,14 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3341
3512
  );
3342
3513
  }
3343
3514
  if (options.length === 0) {
3344
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { id, className: "text-xs text-muted-foreground", children: field.options_table_id ? `${fieldName(field)} takes its choices from a Table that has no records yet \u2014 add the choices there and they appear here.` : `${fieldName(field)} does not name the Table its choices come from yet, so there is nothing to choose. A table admin sets it in the field editor.` });
3515
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { id, className: "text-xs text-muted-foreground", children: field.options_table_id ? `${fieldName(field)} takes its choices from a Table that has no records yet \u2014 add the choices there and they appear here.` : `${fieldName(field)} does not name the Table its choices come from yet, so there is nothing to choose. A table admin sets it in the field editor.` });
3345
3516
  }
3346
3517
  const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
3347
3518
  if (field.multi) {
3348
3519
  const chosen = options.filter((option) => (0, import_records10.choiceValuesOf)(value).some((v) => (0, import_records10.isTheChosen)(option, v)));
3349
3520
  const picked = new Set(chosen.map((option) => (0, import_records10.optionKey)(option)));
3350
- const toggles = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3351
- import_design_system13.Button,
3521
+ const toggles = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3522
+ import_design_system14.Button,
3352
3523
  {
3353
3524
  type: "button",
3354
3525
  size: "sm",
@@ -3365,23 +3536,23 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3365
3536
  option.id
3366
3537
  )) });
3367
3538
  if (!autoOpen) return toggles;
3368
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3369
- import_design_system13.Popover,
3539
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3540
+ import_design_system14.Popover,
3370
3541
  {
3371
3542
  defaultOpen: true,
3372
3543
  onOpenChange: (open) => {
3373
3544
  if (!open) onClose?.();
3374
3545
  },
3375
3546
  children: [
3376
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.Button, { id, type: "button", size: "sm", variant: "outline", className: "h-6 max-w-full truncate", children: chosen.length === 0 ? "Choose" : chosen.map(titleOf).join(", ") }) }),
3377
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.PopoverContent, { sizing: "content", className: "max-w-[20rem] p-2", align: "start", children: toggles })
3547
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { id, type: "button", size: "sm", variant: "outline", className: "h-6 max-w-full truncate", children: chosen.length === 0 ? "Choose" : chosen.map(titleOf).join(", ") }) }),
3548
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.PopoverContent, { sizing: "content", className: "max-w-[20rem] p-2", align: "start", children: toggles })
3378
3549
  ]
3379
3550
  }
3380
3551
  );
3381
3552
  }
3382
3553
  const current = options.find((option) => (0, import_records10.isTheChosen)(option, value));
3383
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3384
- import_design_system13.Select,
3554
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3555
+ import_design_system14.Select,
3385
3556
  {
3386
3557
  value: current ? (0, import_records10.optionKey)(current) : "",
3387
3558
  disabled: disabled ?? false,
@@ -3394,8 +3565,8 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3394
3565
  }
3395
3566
  } : {},
3396
3567
  children: [
3397
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.SelectTrigger, { id, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.SelectValue, { placeholder: "Choose" }) }),
3398
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.SelectItem, { value: (0, import_records10.optionKey)(option), children: titleOf(option) }, option.id)) })
3568
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.SelectTrigger, { id, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.SelectValue, { placeholder: "Choose" }) }),
3569
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.SelectItem, { value: (0, import_records10.optionKey)(option), children: titleOf(option) }, option.id)) })
3399
3570
  ]
3400
3571
  }
3401
3572
  );
@@ -3414,18 +3585,18 @@ function OpenChoicePicker({
3414
3585
  allowOther = true,
3415
3586
  onChoicesChanged
3416
3587
  }) {
3417
- const client = (0, import_react23.useOptionalRecordsClient)();
3588
+ const client = (0, import_react25.useOptionalRecordsClient)();
3418
3589
  const nudge = useChoiceNudge();
3419
- const [open, setOpenState] = (0, import_react22.useState)(autoOpen === true);
3420
- const onCloseRef = (0, import_react22.useRef)(onClose);
3590
+ const [open, setOpenState] = (0, import_react24.useState)(autoOpen === true);
3591
+ const onCloseRef = (0, import_react24.useRef)(onClose);
3421
3592
  onCloseRef.current = onClose;
3422
- const setOpen = (0, import_react22.useCallback)((next) => {
3593
+ const setOpen = (0, import_react24.useCallback)((next) => {
3423
3594
  setOpenState(next);
3424
3595
  if (!next) onCloseRef.current?.();
3425
3596
  }, []);
3426
- const [search, setSearch] = (0, import_react22.useState)(initialSearch ?? "");
3427
- const [adding, setAdding] = (0, import_react22.useState)(false);
3428
- const [addRefused, setAddRefused] = (0, import_react22.useState)(null);
3597
+ const [search, setSearch] = (0, import_react24.useState)(initialSearch ?? "");
3598
+ const [adding, setAdding] = (0, import_react24.useState)(false);
3599
+ const [addRefused, setAddRefused] = (0, import_react24.useState)(null);
3429
3600
  const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
3430
3601
  const held = withoutAddition(value);
3431
3602
  const current = (0, import_records10.choiceValuesOf)(held.value);
@@ -3477,7 +3648,7 @@ function OpenChoicePicker({
3477
3648
  });
3478
3649
  };
3479
3650
  const offList = q !== "" && decided.decision !== "chosen" && decided.decision !== "empty";
3480
- const foot = offList && decided.decision === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3651
+ const foot = offList && decided.decision === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3481
3652
  ChoiceAskButtons,
3482
3653
  {
3483
3654
  field,
@@ -3494,14 +3665,14 @@ function OpenChoicePicker({
3494
3665
  }
3495
3666
  ) : null;
3496
3667
  const add = offList && decided.decision === "add" ? { label: `Add \u201C${q}\u201D to the choices`, onAdd: addTyped, disabled: adding } : offList && decided.decision === "keep_as_typed" ? { label: `Keep \u201C${q}\u201D as typed`, onAdd: () => choose(q) } : null;
3497
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { id, className: "flex flex-wrap items-center gap-1", children: [
3668
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { id, className: "flex flex-wrap items-center gap-1", children: [
3498
3669
  pickedWords.map((word, i) => {
3499
3670
  const chip = chipOf(options.find((o) => (0, import_records10.isTheChosen)(o, current[i])), word);
3500
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.Badge, { variant: "outline", className: (0, import_design_system13.cn)("text-[11px]", chip.className), "data-records-choice-chip": "", children: word }, word);
3671
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Badge, { variant: "outline", className: (0, import_design_system14.cn)("text-[11px]", chip.className), "data-records-choice-chip": "", children: word }, word);
3501
3672
  }),
3502
3673
  disabled ? null : (
3503
3674
  // THE ONE "PICK OR ADD" BUILDER (PickOrAdd.tsx) — the relation picker draws the same one.
3504
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3675
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3505
3676
  PickOrAdd,
3506
3677
  {
3507
3678
  triggerLabel: `Pick for ${fieldName(field)}`,
@@ -3523,15 +3694,15 @@ function OpenChoicePicker({
3523
3694
  const option = options.find((o) => o.id === optionId);
3524
3695
  if (option) choose((0, import_records10.optionKey)(option));
3525
3696
  },
3526
- empty: q === "" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
3697
+ empty: q === "" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
3527
3698
  add,
3528
3699
  foot,
3529
3700
  ...offList && decided.decision === "ask" && !adding ? { onEnterWithNoMatch: addTyped } : {},
3530
- footNote: addRefused ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
3701
+ footNote: addRefused ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
3531
3702
  // never_add on a column that takes only its choices: said, never a silent nothing.
3532
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3533
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field, [q]) }),
3534
- autoOpen ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "data-records-choice-ask": "", className: "px-2 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_design_system13.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => setOpen(false), children: "Cancel" }) }) : null
3703
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3704
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field, [q]) }),
3705
+ autoOpen ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "data-records-choice-ask": "", className: "px-2 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_design_system14.Button, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => setOpen(false), children: "Cancel" }) }) : null
3535
3706
  ] })
3536
3707
  ) : null
3537
3708
  }
@@ -3550,9 +3721,9 @@ function RecordChip({
3550
3721
  // name. So it caps at its container and ends in an ellipsis with the whole name in
3551
3722
  // its tooltip, rather than being cut mid-word by whatever box it landed in
3552
3723
  // (lane FIX-14, 2026-09-22).
3553
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_design_system13.Badge, { variant: "secondary", className: (0, import_design_system13.cn)("max-w-full gap-1 text-[11px]", className), title, children: [
3554
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "min-w-0 truncate", children: title }),
3555
- onRemove ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${title}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
3724
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_design_system14.Badge, { variant: "secondary", className: (0, import_design_system14.cn)("max-w-full gap-1 text-[11px]", className), title, children: [
3725
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate", children: title }),
3726
+ onRemove ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${title}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
3556
3727
  ] })
3557
3728
  );
3558
3729
  }
@@ -3564,7 +3735,8 @@ function publicChoicesOf(field) {
3564
3735
  return typeof o.key === "string" && typeof o.label === "string" ? [{ key: o.key, label: o.label }] : [];
3565
3736
  });
3566
3737
  }
3567
- var FORM_PILL_LIMIT = 4;
3738
+ var FORM_SEARCH_AFTER = 8;
3739
+ var CHOICE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
3568
3740
  function ChoiceAnswer({
3569
3741
  field,
3570
3742
  choices,
@@ -3574,7 +3746,7 @@ function ChoiceAnswer({
3574
3746
  id,
3575
3747
  isChosen
3576
3748
  }) {
3577
- const [search, setSearch] = (0, import_react22.useState)("");
3749
+ const [search, setSearch] = (0, import_react24.useState)("");
3578
3750
  const held = field.multi ? (0, import_records10.choiceValuesOf)(value) : value === null || value === void 0 || value === "" ? [] : [value];
3579
3751
  const on = (choice) => held.some((v) => isChosen ? isChosen(choice, v) : String(v) === choice.key || String(v) === choice.label);
3580
3752
  const press = (choice) => {
@@ -3585,71 +3757,90 @@ function ChoiceAnswer({
3585
3757
  const keys = choices.filter((c) => c.key === choice.key ? !on(c) : on(c)).map((c) => c.key);
3586
3758
  onChange(keys.length === 0 ? null : keys);
3587
3759
  };
3588
- const pill = (choice) => {
3760
+ const lettered = choices.length <= CHOICE_LETTERS.length;
3761
+ const option = (choice) => {
3589
3762
  const chosen = on(choice);
3590
- const look = choiceChipLookOf(field, choice.key, choice.label);
3591
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3763
+ const letter = lettered ? CHOICE_LETTERS[choices.indexOf(choice)] : null;
3764
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3592
3765
  "button",
3593
3766
  {
3594
3767
  type: "button",
3595
3768
  role: field.multi ? "checkbox" : "radio",
3596
3769
  "aria-checked": chosen,
3770
+ "aria-label": choice.label,
3597
3771
  disabled,
3598
3772
  onClick: () => press(choice),
3599
- "data-records-choice-chip": "",
3600
3773
  "data-records-choice-answer": choice.key,
3601
- className: (0, import_design_system13.cn)(
3602
- "inline-flex min-h-11 max-w-full items-center gap-1 rounded-md border px-3 text-sm font-medium sm:min-h-8 sm:px-2.5 sm:text-xs",
3603
- look.className,
3604
- chosen ? "ring-2 ring-ring ring-offset-1" : "opacity-80 hover:opacity-100"
3774
+ className: (0, import_design_system14.cn)(
3775
+ "flex min-h-11 w-full items-center gap-3 rounded-md border px-3 py-2 text-left text-base font-medium text-foreground transition-colors sm:min-h-10 sm:text-sm",
3776
+ chosen ? "border-primary bg-primary/10" : "border-primary/30 bg-primary/[0.03] hover:bg-primary/10"
3605
3777
  ),
3606
3778
  children: [
3607
- chosen ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: "\u2713" }) : null,
3608
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate", children: choice.label })
3779
+ letter ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3780
+ "kbd",
3781
+ {
3782
+ "aria-hidden": "true",
3783
+ className: (0, import_design_system14.cn)(
3784
+ "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border font-sans text-xs font-semibold",
3785
+ chosen ? "border-primary bg-primary text-primary-foreground" : "border-primary/40 text-primary"
3786
+ ),
3787
+ children: letter
3788
+ }
3789
+ ) : null,
3790
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 flex-1 break-words", children: choice.label }),
3791
+ chosen ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "aria-hidden": "true", className: "shrink-0 text-primary", children: "\u2713" }) : null
3609
3792
  ]
3610
3793
  },
3611
3794
  choice.key
3612
3795
  );
3613
3796
  };
3614
- const group = { role: field.multi ? "group" : "radiogroup", "aria-label": fieldName(field) };
3615
- if (choices.length <= FORM_PILL_LIMIT) {
3616
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { id, className: "flex flex-wrap gap-1.5", ...group, children: choices.map(pill) });
3797
+ const onKeyDown = (event) => {
3798
+ if (!lettered || disabled || event.metaKey || event.ctrlKey || event.altKey) return;
3799
+ if (event.target.tagName === "INPUT") return;
3800
+ const at = CHOICE_LETTERS.indexOf(event.key.toUpperCase());
3801
+ if (event.key.length !== 1 || at < 0 || at >= choices.length) return;
3802
+ event.preventDefault();
3803
+ press(choices[at]);
3804
+ };
3805
+ const group = { role: field.multi ? "group" : "radiogroup", "aria-label": fieldName(field), onKeyDown };
3806
+ if (choices.length <= FORM_SEARCH_AFTER) {
3807
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id, className: "flex w-full flex-col gap-2", ...group, children: choices.map(option) });
3617
3808
  }
3618
3809
  const q = search.trim().toLowerCase();
3619
3810
  const shown2 = q === "" ? choices : choices.filter((c) => c.label.toLowerCase().includes(q));
3620
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { id, className: "flex flex-col gap-1.5", children: [
3621
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3622
- import_design_system13.BasicInput,
3811
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { id, className: "flex w-full flex-col gap-2", onKeyDown, children: [
3812
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3813
+ import_design_system14.BasicInput,
3623
3814
  {
3624
3815
  value: search,
3625
3816
  onChange: (e) => setSearch(e.target.value),
3626
3817
  placeholder: "Search",
3627
3818
  "aria-label": `Search \u2014 ${fieldName(field)}`,
3628
3819
  autoComplete: "off",
3629
- className: "h-11 text-base sm:h-8 sm:text-xs"
3820
+ className: "h-11 text-base sm:h-9 sm:text-sm"
3630
3821
  }
3631
3822
  ),
3632
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex max-h-56 flex-wrap content-start gap-1.5 overflow-y-auto", ...group, children: [
3633
- shown2.map(pill),
3634
- shown2.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-xs text-muted-foreground", children: "No match" }) : null
3823
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex max-h-80 w-full flex-col gap-2 overflow-y-auto", role: group.role, "aria-label": group["aria-label"], children: [
3824
+ shown2.map(option),
3825
+ shown2.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-muted-foreground", children: "No match" }) : null
3635
3826
  ] })
3636
3827
  ] });
3637
3828
  }
3638
3829
 
3639
3830
  // src/RecordsMount.tsx
3640
- var import_react24 = require("react");
3641
- var import_react25 = require("@ai-matrx/records/react");
3642
- var import_jsx_runtime16 = require("react/jsx-runtime");
3831
+ var import_react26 = require("react");
3832
+ var import_react27 = require("@ai-matrx/records/react");
3833
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3643
3834
  function personActor(userId) {
3644
3835
  return userId ? { actor: "user", user_id: userId } : { actor: "user" };
3645
3836
  }
3646
3837
 
3647
3838
  // src/tablePicking.tsx
3648
- var import_react26 = require("react");
3839
+ var import_react28 = require("react");
3649
3840
  var import_records11 = require("@ai-matrx/records");
3650
- var import_react27 = require("@ai-matrx/records/react");
3651
- var import_design_system14 = require("@ai-matrx/design-system");
3652
- var import_jsx_runtime17 = require("react/jsx-runtime");
3841
+ var import_react29 = require("@ai-matrx/records/react");
3842
+ var import_design_system15 = require("@ai-matrx/design-system");
3843
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3653
3844
  var APP_TABLE_PREFIX = "records_ui_";
3654
3845
  function isValueSet(table) {
3655
3846
  if (table.kept_for === "choices") return true;
@@ -3692,26 +3883,44 @@ function madeOn(stamp) {
3692
3883
  }
3693
3884
 
3694
3885
  // src/TablePickers.tsx
3695
- var import_jsx_runtime18 = require("react/jsx-runtime");
3886
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3887
+ var SHARED_FOR_MS = 5e3;
3888
+ var sharedReads = /* @__PURE__ */ new WeakMap();
3889
+ function readTablesAnywhere(dataSource) {
3890
+ const held = sharedReads.get(dataSource);
3891
+ if (held && Date.now() - held.at < SHARED_FOR_MS) return held.read;
3892
+ const read = Promise.resolve(dataSource.rpc("data_home_tables", {}, { schema: "custom" })).then(
3893
+ ({ data, error }) => {
3894
+ if (error) {
3895
+ return {
3896
+ loading: false,
3897
+ error: refusalSentence({ message: String(error["message"] ?? "") }) || "Tables could not be read.",
3898
+ rows: []
3899
+ };
3900
+ }
3901
+ const rows = (Array.isArray(data) ? data : []).slice();
3902
+ rows.sort((a, b) => a.table_name.localeCompare(b.table_name));
3903
+ return { loading: false, error: null, rows };
3904
+ },
3905
+ (thrown) => ({
3906
+ loading: false,
3907
+ error: String(thrown?.message ?? thrown) || "Tables could not be read.",
3908
+ rows: []
3909
+ })
3910
+ );
3911
+ sharedReads.set(dataSource, { at: Date.now(), read });
3912
+ void read.then((result) => {
3913
+ if (result.error && sharedReads.get(dataSource)?.read === read) sharedReads.delete(dataSource);
3914
+ });
3915
+ return read;
3916
+ }
3696
3917
  function useTablesAnywhere(dataSource) {
3697
- const [state, setState] = (0, import_react28.useState)({ loading: true, error: null, rows: [] });
3698
- (0, import_react28.useEffect)(() => {
3918
+ const [state, setState] = (0, import_react30.useState)({ loading: true, error: null, rows: [] });
3919
+ (0, import_react30.useEffect)(() => {
3699
3920
  let live = true;
3700
- void Promise.resolve(dataSource.rpc("data_home_tables", {}, { schema: "custom" })).then(
3701
- ({ data, error }) => {
3702
- if (!live) return;
3703
- if (error) {
3704
- setState({ loading: false, error: refusalSentence({ message: String(error["message"] ?? "") }) || "Tables could not be read.", rows: [] });
3705
- return;
3706
- }
3707
- const rows = (Array.isArray(data) ? data : []).slice();
3708
- rows.sort((a, b) => a.table_name.localeCompare(b.table_name));
3709
- setState({ loading: false, error: null, rows });
3710
- },
3711
- (thrown) => {
3712
- if (live) setState({ loading: false, error: String(thrown?.message ?? thrown), rows: [] });
3713
- }
3714
- );
3921
+ void readTablesAnywhere(dataSource).then((result) => {
3922
+ if (live) setState(result);
3923
+ });
3715
3924
  return () => {
3716
3925
  live = false;
3717
3926
  };
@@ -3732,9 +3941,9 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
3732
3941
  keywords: t.organization_name
3733
3942
  }));
3734
3943
  const missing = Boolean(value) && !list.loading && !list.error && !list.rows.some((t) => t.table_id === value);
3735
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col gap-1", children: [
3736
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3737
- import_design_system15.CreatablePicker,
3944
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1", children: [
3945
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3946
+ import_design_system16.CreatablePicker,
3738
3947
  {
3739
3948
  value: value || null,
3740
3949
  options,
@@ -3747,23 +3956,24 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
3747
3956
  ariaLabel: "Table"
3748
3957
  }
3749
3958
  ),
3750
- list.error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(RefusalLine, { error: refusal("door", list.error, "Try again in a moment.") }),
3751
- missing && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-[11px] text-destructive", children: "This table is archived or not shared with you." })
3959
+ list.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: refusal("door", list.error, "Try again in a moment.") }),
3960
+ missing && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-[11px] text-destructive", children: "This table is archived or not shared with you." })
3752
3961
  ] });
3753
3962
  }
3754
- function TableScope({ dataSource, userId, tableId, children, fallback = null, tables }) {
3963
+ function TableScope({ dataSource, userId, tableId, children, fallback = null, unavailable, tables }) {
3755
3964
  const own3 = useTablesAnywhere(dataSource);
3756
3965
  const list = tables ?? own3;
3757
3966
  const organizationId = list.rows.find((t) => t.table_id === tableId)?.organization_id ?? null;
3758
- if (!tableId || !organizationId) return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: fallback });
3759
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react29.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children });
3967
+ if (tableId && !organizationId && !list.loading) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: unavailable ?? fallback });
3968
+ if (!tableId || !organizationId) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: fallback });
3969
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react31.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children });
3760
3970
  }
3761
3971
  function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
3762
- const fields = (0, import_react29.useFields)(tableId);
3763
- const all = (0, import_react28.useMemo)(() => fields.data ?? [], [fields.data]);
3764
- const byKey = (0, import_react28.useMemo)(() => new Map(all.map((f) => [f.key, f])), [all]);
3972
+ const fields = (0, import_react31.useFields)(tableId);
3973
+ const all = (0, import_react30.useMemo)(() => fields.data ?? [], [fields.data]);
3974
+ const byKey = (0, import_react30.useMemo)(() => new Map(all.map((f) => [f.key, f])), [all]);
3765
3975
  const keys = Object.keys(value);
3766
- const [adding, setAdding] = (0, import_react28.useState)(false);
3976
+ const [adding, setAdding] = (0, import_react30.useState)(false);
3767
3977
  const optionsFor = (current) => all.filter((f) => f.key === current || !(f.key in value)).map((f) => ({ value: f.key, label: fieldName(f) }));
3768
3978
  const rename = (from, to) => {
3769
3979
  if (from === to) return;
@@ -3776,11 +3986,11 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
3776
3986
  void _gone;
3777
3987
  onChange(rest);
3778
3988
  };
3779
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col gap-2", children: [
3780
- fields.error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(RefusalLine, { error: fields.error }),
3989
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-2", children: [
3990
+ fields.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: fields.error }),
3781
3991
  keys.map((key) => {
3782
3992
  const field = byKey.get(key);
3783
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3993
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3784
3994
  ColumnValueRow,
3785
3995
  {
3786
3996
  columnKey: key,
@@ -3796,7 +4006,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
3796
4006
  key
3797
4007
  );
3798
4008
  }),
3799
- adding && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4009
+ adding && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3800
4010
  ColumnValueRow,
3801
4011
  {
3802
4012
  columnKey: null,
@@ -3813,7 +4023,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
3813
4023
  onRemove: () => setAdding(false)
3814
4024
  }
3815
4025
  ),
3816
- !disabled && !adding && keys.length < all.length && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system15.Button, { type: "button", variant: "outline", size: "sm", className: "self-start", onClick: () => setAdding(true), children: addLabel })
4026
+ !disabled && !adding && keys.length < all.length && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_design_system16.Button, { type: "button", variant: "outline", size: "sm", className: "self-start", onClick: () => setAdding(true), children: addLabel })
3817
4027
  ] });
3818
4028
  }
3819
4029
  function ColumnValueRow({
@@ -3829,10 +4039,10 @@ function ColumnValueRow({
3829
4039
  }) {
3830
4040
  const orphan = columnKey !== null && !loading && field === void 0;
3831
4041
  const shown2 = orphan ? [{ value: columnKey, label: columnKey, hint: "Not a column" }, ...options] : options;
3832
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col gap-1 rounded-md border border-border/60 p-2", children: [
3833
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-2", children: [
3834
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3835
- import_design_system15.CreatablePicker,
4042
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1 rounded-md border border-border/60 p-2", children: [
4043
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
4044
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4045
+ import_design_system16.CreatablePicker,
3836
4046
  {
3837
4047
  value: columnKey,
3838
4048
  options: shown2,
@@ -3845,23 +4055,23 @@ function ColumnValueRow({
3845
4055
  ariaLabel: "Column"
3846
4056
  }
3847
4057
  ) }),
3848
- !disabled && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system15.Button, { type: "button", variant: "ghost", size: "sm", "aria-label": "Remove", onClick: onRemove, children: "\u2715" })
4058
+ !disabled && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_design_system16.Button, { type: "button", variant: "ghost", size: "sm", "aria-label": "Remove", onClick: onRemove, children: "\u2715" })
3849
4059
  ] }),
3850
- field ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FieldControl, { field, value, onChange: onValue, disabled }) : orphan ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-[11px] text-muted-foreground", children: value === null || value === void 0 ? "\u2014" : String(value) }) : null
4060
+ field ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(FieldControl, { field, value, onChange: onValue, disabled }) : orphan ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-[11px] text-muted-foreground", children: value === null || value === void 0 ? "\u2014" : String(value) }) : null
3851
4061
  ] });
3852
4062
  }
3853
4063
  function RecordPicker({ tableId, value, onChange, disabled }) {
3854
- const table = (0, import_react29.useTable)(tableId);
3855
- const records = (0, import_react29.useRecords)(tableId, { pageSize: 200 });
4064
+ const table = (0, import_react31.useTable)(tableId);
4065
+ const records = (0, import_react31.useRecords)(tableId, { pageSize: 200 });
3856
4066
  const rows = records.data?.rows ?? [];
3857
4067
  const options = rows.map((row) => ({
3858
4068
  value: row.id,
3859
4069
  label: rowNameIn(table.data ?? null, row)
3860
4070
  }));
3861
4071
  const missing = Boolean(value) && !records.loading && !records.error && !rows.some((r) => r.id === value);
3862
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col gap-1", children: [
3863
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3864
- import_design_system15.CreatablePicker,
4072
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1", children: [
4073
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4074
+ import_design_system16.CreatablePicker,
3865
4075
  {
3866
4076
  value: value || null,
3867
4077
  options,
@@ -3874,16 +4084,16 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
3874
4084
  ariaLabel: "Record"
3875
4085
  }
3876
4086
  ),
3877
- records.error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(RefusalLine, { error: records.error })
4087
+ records.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RefusalLine, { error: records.error })
3878
4088
  ] });
3879
4089
  }
3880
4090
 
3881
4091
  // src/DataBindingPicker.tsx
3882
- var import_react30 = require("react");
4092
+ var import_react32 = require("react");
3883
4093
  var import_records12 = require("@ai-matrx/records");
3884
- var import_react31 = require("@ai-matrx/records/react");
3885
- var import_design_system16 = require("@ai-matrx/design-system");
3886
- var import_jsx_runtime19 = require("react/jsx-runtime");
4094
+ var import_react33 = require("@ai-matrx/records/react");
4095
+ var import_design_system17 = require("@ai-matrx/design-system");
4096
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3887
4097
  var DATA_BINDING_SHAPES = [
3888
4098
  { value: "collection", label: "The whole table" },
3889
4099
  { value: "reference", label: "One record" },
@@ -3950,9 +4160,9 @@ function DataBindingPicker({ dataSource, userId, binding, onChange, disabled, de
3950
4160
  ...binding.semantic_type === "collection" && defaultRowLimit ? { limit: defaultRowLimit } : {}
3951
4161
  });
3952
4162
  };
3953
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-2", children: [
3954
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TablePicker, { dataSource, value: tableId, onChange: selectTable, disabled: Boolean(disabled), tables }),
3955
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TableScope, { dataSource, userId, tableId, tables, children: tableId && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4163
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-2", children: [
4164
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TablePicker, { dataSource, value: tableId, onChange: selectTable, disabled: Boolean(disabled), tables }),
4165
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TableScope, { dataSource, userId, tableId, tables, children: tableId && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3956
4166
  BindingDetails,
3957
4167
  {
3958
4168
  tableId,
@@ -3971,11 +4181,11 @@ function BindingDetails({
3971
4181
  disabled,
3972
4182
  defaultRowLimit
3973
4183
  }) {
3974
- const table = (0, import_react31.useTable)(tableId);
3975
- const fields = (0, import_react31.useFields)(tableId);
3976
- const fieldList = (0, import_react30.useMemo)(() => fields.data ?? [], [fields.data]);
4184
+ const table = (0, import_react33.useTable)(tableId);
4185
+ const fields = (0, import_react33.useFields)(tableId);
4186
+ const fieldList = (0, import_react32.useMemo)(() => fields.data ?? [], [fields.data]);
3977
4187
  const shape = binding.semantic_type;
3978
- (0, import_react30.useEffect)(() => {
4188
+ (0, import_react32.useEffect)(() => {
3979
4189
  if (disabled || shape === "value" || binding.transform || fields.loading || fieldList.length === 0) return;
3980
4190
  onChange({
3981
4191
  ...binding,
@@ -4016,9 +4226,9 @@ function BindingDetails({
4016
4226
  const fieldOptions = fieldList.map((f) => ({ value: f.key, label: fieldName(f) }));
4017
4227
  const template = binding.transform?.template ?? "";
4018
4228
  const setTemplate = (next) => onChange({ ...binding, transform: { join: "\n", ...binding.transform, name: "list", template: next } });
4019
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-2", children: [
4020
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex flex-wrap gap-1", role: "radiogroup", "aria-label": "What to read", children: DATA_BINDING_SHAPES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4021
- import_design_system16.Button,
4229
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-2", children: [
4230
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-wrap gap-1", role: "radiogroup", "aria-label": "What to read", children: DATA_BINDING_SHAPES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4231
+ import_design_system17.Button,
4022
4232
  {
4023
4233
  type: "button",
4024
4234
  size: "sm",
@@ -4031,7 +4241,7 @@ function BindingDetails({
4031
4241
  },
4032
4242
  s.value
4033
4243
  )) }),
4034
- shape !== "collection" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4244
+ shape !== "collection" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4035
4245
  RecordPicker,
4036
4246
  {
4037
4247
  tableId,
@@ -4040,8 +4250,8 @@ function BindingDetails({
4040
4250
  disabled: Boolean(disabled)
4041
4251
  }
4042
4252
  ),
4043
- shape === "value" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4044
- import_design_system16.CreatablePicker,
4253
+ shape === "value" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4254
+ import_design_system17.CreatablePicker,
4045
4255
  {
4046
4256
  value: binding.field_key ?? null,
4047
4257
  options: fieldOptions,
@@ -4054,11 +4264,11 @@ function BindingDetails({
4054
4264
  ariaLabel: "Column"
4055
4265
  }
4056
4266
  ),
4057
- shape !== "value" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1", children: [
4058
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4267
+ shape !== "value" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-1", children: [
4268
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4059
4269
  "textarea",
4060
4270
  {
4061
- className: (0, import_design_system16.cn)(
4271
+ className: (0, import_design_system17.cn)(
4062
4272
  "min-h-[3.5rem] w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs"
4063
4273
  ),
4064
4274
  "aria-label": "Each row reads as",
@@ -4067,8 +4277,8 @@ function BindingDetails({
4067
4277
  onChange: (e) => setTemplate(e.target.value)
4068
4278
  }
4069
4279
  ),
4070
- !disabled && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex flex-wrap gap-1", children: fieldList.flatMap(bindingPlaceholdersFor).map((p) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4071
- import_design_system16.Button,
4280
+ !disabled && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-wrap gap-1", children: fieldList.flatMap(bindingPlaceholdersFor).map((p) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4281
+ import_design_system17.Button,
4072
4282
  {
4073
4283
  type: "button",
4074
4284
  size: "sm",
@@ -4080,10 +4290,10 @@ function BindingDetails({
4080
4290
  p.token
4081
4291
  )) })
4082
4292
  ] }),
4083
- shape === "collection" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
4293
+ shape === "collection" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
4084
4294
  "Up to",
4085
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4086
- import_design_system16.BasicInput,
4295
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4296
+ import_design_system17.BasicInput,
4087
4297
  {
4088
4298
  type: "number",
4089
4299
  min: 1,
@@ -4099,10 +4309,10 @@ function BindingDetails({
4099
4309
  ),
4100
4310
  "rows"
4101
4311
  ] }),
4102
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "radiogroup", "aria-label": "If nothing is found", children: [
4103
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs text-muted-foreground", children: "If nothing is found" }),
4104
- DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4105
- import_design_system16.Button,
4312
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "radiogroup", "aria-label": "If nothing is found", children: [
4313
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "If nothing is found" }),
4314
+ DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4315
+ import_design_system17.Button,
4106
4316
  {
4107
4317
  type: "button",
4108
4318
  size: "sm",
@@ -4120,12 +4330,12 @@ function BindingDetails({
4120
4330
  }
4121
4331
 
4122
4332
  // src/PickedSummaries.tsx
4123
- var import_react33 = require("@ai-matrx/records/react");
4333
+ var import_react35 = require("@ai-matrx/records/react");
4124
4334
 
4125
4335
  // src/values.tsx
4126
4336
  var import_data_table4 = require("@ai-matrx/design-system/data-table");
4127
4337
  var import_field_formats5 = require("@ai-matrx/design-system/field-formats");
4128
- var import_design_system19 = require("@ai-matrx/design-system");
4338
+ var import_design_system20 = require("@ai-matrx/design-system");
4129
4339
 
4130
4340
  // src/enumLabels.ts
4131
4341
  function exhaustiveValuesOf() {
@@ -4162,10 +4372,10 @@ var ABSENCE_WORD_LABEL = {
4162
4372
  var import_core2 = require("@ai-matrx/records/core");
4163
4373
 
4164
4374
  // src/WholeValue.tsx
4165
- var import_react32 = require("react");
4375
+ var import_react34 = require("react");
4166
4376
  var import_core = require("@ai-matrx/records/core");
4167
- var import_design_system17 = require("@ai-matrx/design-system");
4168
- var import_jsx_runtime20 = require("react/jsx-runtime");
4377
+ var import_design_system18 = require("@ai-matrx/design-system");
4378
+ var import_jsx_runtime21 = require("react/jsx-runtime");
4169
4379
  var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
4170
4380
  function wholeValueLine(pointer) {
4171
4381
  return `Open the whole text (${(0, import_core.wholeValueSize)(pointer)})`;
@@ -4174,18 +4384,21 @@ function WholeValueCell({ words, pointer }) {
4174
4384
  const host = useRecordsUi();
4175
4385
  const href = host.hrefForFile?.({ fileId: pointer.file_id });
4176
4386
  const line = wholeValueLine(pointer);
4177
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "flex min-w-0 items-baseline gap-2", "data-whole-value-file": pointer.file_id, children: [
4178
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "truncate", title: `The first ${pointer.shown_chars} of ${pointer.chars} characters`, children: [
4387
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "flex min-w-0 items-baseline gap-2", "data-whole-value-file": pointer.file_id, children: [
4388
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "truncate", title: `The first ${pointer.shown_chars} of ${pointer.chars} characters`, children: [
4179
4389
  words,
4180
4390
  "\u2026"
4181
4391
  ] }),
4182
- href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0, import_core.wholeValueSize)(pointer)} in a file` })
4392
+ href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0, import_core.wholeValueSize)(pointer)} in a file` })
4183
4393
  ] });
4184
4394
  }
4185
4395
 
4396
+ // src/values.tsx
4397
+ var import_field_formats6 = require("@ai-matrx/design-system/field-formats");
4398
+
4186
4399
  // src/ReferenceChips.tsx
4187
4400
  var import_records13 = require("@ai-matrx/records");
4188
- var import_design_system18 = require("@ai-matrx/design-system");
4401
+ var import_design_system19 = require("@ai-matrx/design-system");
4189
4402
 
4190
4403
  // src/kindValues.ts
4191
4404
  var import_directives = require("@ai-matrx/content-ir/directives");
@@ -4239,7 +4452,7 @@ function kindLabel(kind) {
4239
4452
  }
4240
4453
 
4241
4454
  // src/ReferenceChips.tsx
4242
- var import_jsx_runtime21 = require("react/jsx-runtime");
4455
+ var import_jsx_runtime22 = require("react/jsx-runtime");
4243
4456
  function referencesOf(field, value, kind, labels) {
4244
4457
  if (kind === "entity_reference") {
4245
4458
  return (0, import_records13.entityRefsOf)(value).map((r) => ({ token: r.token, id: r.id, label: r.label }));
@@ -4260,11 +4473,11 @@ function ReferenceChip({ reference, waiting }) {
4260
4473
  const host = useRecordsUi();
4261
4474
  const words = reference.label ?? (reference.token === "record" ? waiting ?? "Loading\u2026" : WITHHELD_ENTITY_LABEL);
4262
4475
  const drawn = host.renderReference ? host.renderReference({ ...reference, label: reference.label ?? words }) : null;
4263
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4264
- import_design_system18.Badge,
4476
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4477
+ import_design_system19.Badge,
4265
4478
  {
4266
4479
  variant: "secondary",
4267
- className: (0, import_design_system18.cn)(
4480
+ className: (0, import_design_system19.cn)(
4268
4481
  "max-w-full min-w-0 gap-1 px-1.5 py-0 text-[11px] font-normal",
4269
4482
  reference.archived && "opacity-70"
4270
4483
  ),
@@ -4272,15 +4485,15 @@ function ReferenceChip({ reference, waiting }) {
4272
4485
  "data-records-reference-archived": reference.archived ? "" : void 0,
4273
4486
  title: reference.archived ? ARCHIVED_REFERENCE_TIP : words,
4274
4487
  children: [
4275
- drawn ?? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "truncate", children: words }),
4276
- reference.archived ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
4488
+ drawn ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate", children: words }),
4489
+ reference.archived ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
4277
4490
  ]
4278
4491
  }
4279
4492
  );
4280
4493
  }
4281
4494
  function ReferenceChips({ refs, waiting }) {
4282
- if (refs.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
4283
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "flex min-w-0 flex-wrap gap-1", "data-records-reference-chips": "", children: refs.map((r) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ReferenceChip, { reference: r, waiting }, `${r.token}:${r.id}`)) });
4495
+ if (refs.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
4496
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex min-w-0 flex-wrap gap-1", "data-records-reference-chips": "", children: refs.map((r) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ReferenceChip, { reference: r, waiting }, `${r.token}:${r.id}`)) });
4284
4497
  }
4285
4498
  function KindValueCell({
4286
4499
  kv,
@@ -4289,18 +4502,18 @@ function KindValueCell({
4289
4502
  }) {
4290
4503
  const host = useRecordsUi();
4291
4504
  if (host.renderKind) {
4292
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "flex min-w-0 max-w-full items-center", "data-records-kind-value": kv.kind, children: host.renderKind({ value: kv.value, kind: kv.kind, where, title }) });
4505
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex min-w-0 max-w-full items-center", "data-records-kind-value": kv.kind, children: host.renderKind({ value: kv.value, kind: kv.kind, where, title }) });
4293
4506
  }
4294
4507
  const named = kv.items.map(kindItemWords).filter((w) => w !== null);
4295
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: (0, import_design_system18.cn)("flex min-w-0 flex-wrap gap-1"), "data-records-kind-value": kv.kind, title: JSON.stringify(kv.value), children: named.length > 0 ? named.map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Badge, { variant: "secondary", className: "px-1.5 py-0 text-[11px] font-normal", children: w }, `${w}-${i}`)) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_design_system18.Badge, { variant: "outline", className: "px-1.5 py-0 text-[11px] font-normal", children: kindLabel(kv.kind) }) });
4508
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: (0, import_design_system19.cn)("flex min-w-0 flex-wrap gap-1"), "data-records-kind-value": kv.kind, title: JSON.stringify(kv.value), children: named.length > 0 ? named.map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_design_system19.Badge, { variant: "secondary", className: "px-1.5 py-0 text-[11px] font-normal", children: w }, `${w}-${i}`)) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_design_system19.Badge, { variant: "outline", className: "px-1.5 py-0 text-[11px] font-normal", children: kindLabel(kv.kind) }) });
4296
4509
  }
4297
4510
 
4298
4511
  // src/values.tsx
4299
4512
  var import_records14 = require("@ai-matrx/records");
4300
- var import_jsx_runtime22 = require("react/jsx-runtime");
4301
- function statusMark(field, item) {
4302
- const mark = statusMarkOf(field, item);
4303
- return mark ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-label": mark.words, title: mark.words, className: "mr-1", "data-records-status-group": mark.group, children: mark.mark }) : null;
4513
+ var import_jsx_runtime23 = require("react/jsx-runtime");
4514
+ function statusMark(field, item, document2) {
4515
+ const mark = statusMarkOf(field, item, document2);
4516
+ return mark ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-label": mark.words, title: mark.words, className: "mr-1", "data-records-status-group": mark.group, children: mark.mark }) : null;
4304
4517
  }
4305
4518
  function envelopeFor(document2, key) {
4306
4519
  const block = document2?._values;
@@ -4344,32 +4557,32 @@ var ABSENCE_WORDS = ABSENCE_WORD_LABEL;
4344
4557
  function renderValue(field, value, document2, labels, stillWaitingFor) {
4345
4558
  const envelope = envelopeFor(document2, field.key);
4346
4559
  if (envelope?.absent) {
4347
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-xs italic text-muted-foreground", title: `VAL-2: ${envelope.absent}`, children: ABSENCE_WORDS[String(envelope.absent)] ?? String(envelope.absent) });
4560
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", title: `VAL-2: ${envelope.absent}`, children: ABSENCE_WORDS[String(envelope.absent)] ?? String(envelope.absent) });
4348
4561
  }
4349
4562
  if (value === null || value === void 0 || value === "") {
4350
4563
  const gone = unresolvedFor(document2, field.key);
4351
4564
  if (gone) {
4352
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-xs italic text-muted-foreground", title: `It pointed at ${gone}`, children: "The record this pointed at no longer exists" });
4565
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", title: `It pointed at ${gone}`, children: "The record this pointed at no longer exists" });
4353
4566
  }
4354
4567
  const computed = computedEmptyOf(field, document2);
4355
- if (computed?.sentence) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-xs italic text-muted-foreground", children: computed.sentence });
4356
- if (computed?.words) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "data-records-empty-why": computed.kind, children: computed.words });
4568
+ if (computed?.sentence) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", children: computed.sentence });
4569
+ if (computed?.words) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "data-records-empty-why": computed.kind, children: computed.words });
4357
4570
  if (computed?.why) {
4358
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-muted-foreground", title: computed.why, "data-records-empty-why": computed.kind, children: "\u2014" });
4571
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-muted-foreground", title: computed.why, "data-records-empty-why": computed.kind, children: "\u2014" });
4359
4572
  }
4360
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
4573
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
4361
4574
  }
4362
- if (isSignatureField(field)) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SignatureValue, { value });
4575
+ if (isSignatureField(field)) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SignatureValue, { value, fieldKey: field.key, document: document2 });
4363
4576
  const newer = newerKindValue(field, value);
4364
4577
  if (newer !== void 0) return newer;
4365
4578
  const whole = typeof value === "string" ? (0, import_core2.wholeValueOf)(document2, field.key) : null;
4366
- if (whole) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(WholeValueCell, { words: value, pointer: whole });
4579
+ if (whole) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(WholeValueCell, { words: value, pointer: whole });
4367
4580
  const kind = editorKindFor(field);
4368
4581
  if (kind === "relation" || kind === "entity_reference") {
4369
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ReferenceChips, { refs: referencesOf(field, value, kind, labels), waiting: stillWaitingFor });
4582
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ReferenceChips, { refs: referencesOf(field, value, kind, labels), waiting: stillWaitingFor });
4370
4583
  }
4371
4584
  const kv = kind === "attachment" || kind === "member" ? null : kindValueOf(value);
4372
- if (kv) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(KindValueCell, { kv, where: "cell", title: field.label });
4585
+ if (kv) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(KindValueCell, { kv, where: "cell", title: field.label });
4373
4586
  const chosen = kind === "select" || kind === "multi_select";
4374
4587
  const chipOf = (item) => {
4375
4588
  const look = choiceChipLookOf(field, item, scalarText(field, item, labels));
@@ -4377,17 +4590,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
4377
4590
  };
4378
4591
  if (chosen) {
4379
4592
  const items = Array.isArray(value) ? value : [value];
4380
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex flex-wrap gap-1", "data-records-choice-chips": "", children: items.map((item, i) => {
4593
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "flex flex-wrap gap-1", "data-records-choice-chips": "", children: items.map((item, i) => {
4381
4594
  const chip = chipOf(item);
4382
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4383
- import_design_system19.Badge,
4595
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4596
+ import_design_system20.Badge,
4384
4597
  {
4385
4598
  variant: "outline",
4386
- className: (0, import_design_system19.cn)("text-[11px]", chip.className),
4599
+ className: (0, import_design_system20.cn)("text-[11px]", chip.className),
4387
4600
  "data-records-choice-chip": "",
4388
4601
  ...chip.tinted ? { "data-records-choice-tint": "" } : {},
4389
4602
  children: [
4390
- statusMark(field, item),
4603
+ statusMark(field, item, Array.isArray(value) ? void 0 : document2),
4391
4604
  scalarText(field, item, labels, Array.isArray(value) ? void 0 : stillWaitingFor)
4392
4605
  ]
4393
4606
  },
@@ -4395,13 +4608,13 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
4395
4608
  );
4396
4609
  }) });
4397
4610
  }
4398
- if (kind === "attachment") return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AttachmentChips, { value });
4611
+ if (kind === "attachment") return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AttachmentChips, { value });
4399
4612
  if (Array.isArray(value)) {
4400
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex flex-wrap gap-1", children: value.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_design_system19.Badge, { variant: "secondary", className: "text-[11px]", children: scalarText(field, item, labels) }, `${String(item)}-${i}`)) });
4613
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "flex flex-wrap gap-1", children: value.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_design_system20.Badge, { variant: "secondary", className: "text-[11px]", children: scalarText(field, item, labels) }, `${String(item)}-${i}`)) });
4401
4614
  }
4402
4615
  if (kind === "url" && typeof value === "string") {
4403
4616
  const href = value.includes("://") ? value : `https://${value}`;
4404
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4617
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4405
4618
  "a",
4406
4619
  {
4407
4620
  className: "inline-flex min-w-0 max-w-full items-center gap-1 rounded-md border border-border bg-muted/60 px-1.5 py-0.5 text-[11px] text-foreground hover:bg-accent",
@@ -4412,14 +4625,14 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
4412
4625
  "data-records-link-chip": "",
4413
4626
  onClick: (event) => event.stopPropagation(),
4414
4627
  children: [
4415
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2197" }),
4416
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate", children: linkChipText(value) })
4628
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2197" }),
4629
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate", children: linkChipText(value) })
4417
4630
  ]
4418
4631
  }
4419
4632
  );
4420
4633
  }
4421
4634
  if (kind === "phone" && typeof value === "string" && value.trim() !== "") {
4422
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4635
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4423
4636
  "a",
4424
4637
  {
4425
4638
  className: "truncate tabular-nums text-primary underline-offset-2 hover:underline",
@@ -4427,17 +4640,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor) {
4427
4640
  title: value,
4428
4641
  "data-records-phone": "",
4429
4642
  onClick: (event) => event.stopPropagation(),
4430
- children: formatPhone(value)
4643
+ children: (0, import_field_formats6.formatPhone)(value)
4431
4644
  }
4432
4645
  );
4433
4646
  }
4434
4647
  if (kind === "email" && typeof value === "string") {
4435
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "truncate text-primary underline-offset-2 hover:underline", href: `mailto:${value}`, children: value });
4648
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("a", { className: "truncate text-primary underline-offset-2 hover:underline", href: `mailto:${value}`, children: value });
4436
4649
  }
4437
4650
  if (typeof value === "boolean") {
4438
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: kind === "checkbox" ? "text-sm" : "", title: value ? "Yes" : "No", children: value ? "\u2713" : "\u2014" });
4651
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: kind === "checkbox" ? "text-sm" : "", title: value ? "Yes" : "No", children: value ? "\u2713" : "\u2014" });
4439
4652
  }
4440
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: (0, import_design_system19.cn)("truncate", kind === "number" || kind === "currency" || kind === "percent" ? "tabular-nums" : ""), children: scalarText(field, value, labels, stillWaitingFor) });
4653
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: (0, import_design_system20.cn)("truncate", kind === "number" || kind === "currency" || kind === "percent" ? "tabular-nums" : ""), children: scalarText(field, value, labels, stillWaitingFor) });
4441
4654
  }
4442
4655
  function scalarText(field, value, labels, stillWaitingFor) {
4443
4656
  if (value === null || value === void 0) return "\u2014";
@@ -4478,13 +4691,13 @@ function scalarText(field, value, labels, stillWaitingFor) {
4478
4691
  }
4479
4692
 
4480
4693
  // src/PickedSummaries.tsx
4481
- var import_jsx_runtime23 = require("react/jsx-runtime");
4694
+ var import_jsx_runtime24 = require("react/jsx-runtime");
4482
4695
  function TableNameText({ dataSource, tableId }) {
4483
4696
  const tables = useTablesAnywhere(dataSource);
4484
- if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2014" });
4485
- if (tables.loading) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2026" });
4486
- if (tables.error) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "Couldn't load the table's name" });
4487
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
4697
+ if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
4698
+ if (tables.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
4699
+ if (tables.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load the table's name" });
4700
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
4488
4701
  }
4489
4702
  function ColumnValuesText({
4490
4703
  dataSource,
@@ -4492,28 +4705,38 @@ function ColumnValuesText({
4492
4705
  tableId,
4493
4706
  value
4494
4707
  }) {
4495
- if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2014" });
4496
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableScope, { dataSource, userId, tableId, fallback: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2026" }), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RecordLabelProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ColumnValuesWords, { tableId, value }) }) });
4708
+ if (!tableId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
4709
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4710
+ TableScope,
4711
+ {
4712
+ dataSource,
4713
+ userId,
4714
+ tableId,
4715
+ fallback: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" }),
4716
+ unavailable: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this table's columns" }),
4717
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RecordLabelProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ColumnValuesWords, { tableId, value }) })
4718
+ }
4719
+ );
4497
4720
  }
4498
4721
  function ColumnValuesWords({ tableId, value }) {
4499
- const fields = (0, import_react33.useFields)(tableId);
4722
+ const fields = (0, import_react35.useFields)(tableId);
4500
4723
  const labels = useRecordLabels(fields.data ?? void 0);
4501
- if (fields.loading) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2026" });
4502
- if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "Couldn't load this table's columns" });
4724
+ if (fields.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
4725
+ if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this table's columns" });
4503
4726
  const parts = [];
4504
4727
  for (const [key, stored] of Object.entries(value)) {
4505
4728
  if (key.startsWith("_")) continue;
4506
4729
  const field = (fields.data ?? []).find((f) => f.key === key);
4507
- if (parts.length) parts.push(/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: ", " }, `${key}-sep`));
4730
+ if (parts.length) parts.push(/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: ", " }, `${key}-sep`));
4508
4731
  parts.push(
4509
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { children: [
4732
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { children: [
4510
4733
  field ? fieldName(field) : "A removed column",
4511
4734
  " is ",
4512
4735
  field ? renderValue(field, stored, void 0, labels) : "\u2014"
4513
4736
  ] }, key)
4514
4737
  );
4515
4738
  }
4516
- return parts.length ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: parts }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2014" });
4739
+ return parts.length ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: parts }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
4517
4740
  }
4518
4741
  function RecordNameText({
4519
4742
  dataSource,
@@ -4521,32 +4744,42 @@ function RecordNameText({
4521
4744
  tableId,
4522
4745
  recordId
4523
4746
  }) {
4524
- if (!tableId || !recordId) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2014" });
4525
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableScope, { dataSource, userId, tableId, fallback: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2026" }), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RecordNameWords, { tableId, recordId }) });
4747
+ if (!tableId || !recordId) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2014" });
4748
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4749
+ TableScope,
4750
+ {
4751
+ dataSource,
4752
+ userId,
4753
+ tableId,
4754
+ fallback: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" }),
4755
+ unavailable: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this record" }),
4756
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RecordNameWords, { tableId, recordId })
4757
+ }
4758
+ );
4526
4759
  }
4527
4760
  function RecordNameWords({ tableId, recordId }) {
4528
- const table = (0, import_react33.useTable)(tableId);
4529
- const record = (0, import_react33.useRecord)(recordId);
4530
- if (record.loading || table.loading) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "\u2026" });
4531
- if (record.error) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "Couldn't load this record" });
4532
- if (!record.data) return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: "A record you cannot open" });
4533
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: recordName(record.data.document, table.data?.title_field ?? null) });
4761
+ const table = (0, import_react35.useTable)(tableId);
4762
+ const record = (0, import_react35.useRecord)(recordId);
4763
+ if (record.loading || table.loading) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "\u2026" });
4764
+ if (record.error) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "Couldn't load this record" });
4765
+ if (!record.data) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: "A record you cannot open" });
4766
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: recordName(record.data.document, table.data?.title_field ?? null) });
4534
4767
  }
4535
4768
 
4536
4769
  // src/HeldChangeDecision.tsx
4537
- var import_react34 = require("react");
4538
- var import_react35 = require("@ai-matrx/records/react");
4539
- var import_design_system20 = require("@ai-matrx/design-system");
4540
- var import_jsx_runtime24 = require("react/jsx-runtime");
4770
+ var import_react36 = require("react");
4771
+ var import_react37 = require("@ai-matrx/records/react");
4772
+ var import_design_system21 = require("@ai-matrx/design-system");
4773
+ var import_jsx_runtime25 = require("react/jsx-runtime");
4541
4774
  function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
4542
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react35.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Decision, { approvalId, onDecided }) });
4775
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react37.RecordsProvider, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Decision, { approvalId, onDecided }) });
4543
4776
  }
4544
4777
  function Decision({ approvalId, onDecided }) {
4545
- const client = (0, import_react35.useRecordsClient)();
4546
- const [may, setMay] = (0, import_react34.useState)(null);
4547
- const [busy, setBusy] = (0, import_react34.useState)(null);
4548
- const [error, setError] = (0, import_react34.useState)(null);
4549
- (0, import_react34.useEffect)(() => {
4778
+ const client = (0, import_react37.useRecordsClient)();
4779
+ const [may, setMay] = (0, import_react36.useState)(null);
4780
+ const [busy, setBusy] = (0, import_react36.useState)(null);
4781
+ const [error, setError] = (0, import_react36.useState)(null);
4782
+ (0, import_react36.useEffect)(() => {
4550
4783
  let live = true;
4551
4784
  void client.workApprovalMayDecide({ approval_id: approvalId }).then((res) => {
4552
4785
  if (!live) return;
@@ -4568,13 +4801,13 @@ function Decision({ approvalId, onDecided }) {
4568
4801
  if (res.ok) onDecided(approve);
4569
4802
  else setError(res.error);
4570
4803
  };
4571
- if (may === null) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
4572
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
4573
- may ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex gap-2", children: [
4574
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_design_system20.Button, { type: "button", size: "sm", disabled: busy !== null, onClick: () => void decide(true), children: busy === "approve" ? "Approving\u2026" : "Approve" }),
4575
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_design_system20.Button, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void decide(false), children: busy === "refuse" ? "Refusing\u2026" : "Refuse" })
4576
- ] }) : !error && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
4577
- error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RefusalLine, { error }) : null
4804
+ if (may === null) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
4805
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
4806
+ may ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-2", children: [
4807
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_design_system21.Button, { type: "button", size: "sm", disabled: busy !== null, onClick: () => void decide(true), children: busy === "approve" ? "Approving\u2026" : "Approve" }),
4808
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_design_system21.Button, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void decide(false), children: busy === "refuse" ? "Refusing\u2026" : "Refuse" })
4809
+ ] }) : !error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
4810
+ error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(RefusalLine, { error }) : null
4578
4811
  ] });
4579
4812
  }
4580
4813
  //# sourceMappingURL=pickers.cjs.map