@ai-matrx/records-ui 0.102.8 → 0.102.9

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.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  SelectItem as SelectItem2,
59
59
  SelectTrigger as SelectTrigger2,
60
60
  SelectValue as SelectValue2,
61
- cn as cn12
61
+ cn as cn13
62
62
  } from "@ai-matrx/design-system";
63
63
 
64
64
  // src/dates.ts
@@ -553,14 +553,54 @@ var UNREAD_RECORD_LABEL = "Couldn't load this name";
553
553
  import { useCallback, useEffect as useEffect3, useMemo, useRef as useRef3, useState as useState3 } from "react";
554
554
  import { rankTypedMatches } from "@ai-matrx/records";
555
555
  import { useOptionalRecordsClient } from "@ai-matrx/records/react";
556
- import { BasicInput as BasicInput3, Button as Button2, cn as cn4 } from "@ai-matrx/design-system";
556
+ import { BasicInput as BasicInput3, Button as Button2, cn as cn5 } from "@ai-matrx/design-system";
557
557
 
558
558
  // src/PickOrAdd.tsx
559
559
  import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
560
- import { BasicInput as BasicInput2, Button, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ScrollArea, cn as cn2 } from "@ai-matrx/design-system";
560
+
561
+ // src/personChip.tsx
562
+ import { cn as cn2 } from "@ai-matrx/design-system";
561
563
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
564
+ function initialsOf(name) {
565
+ const words = name.replace(/@.*$/, "").split(/[\s._-]+/).filter((w) => /\p{L}|\d/u.test(w));
566
+ const letters = words.filter((w) => !/^(dr|mr|mrs|ms|prof)\.?$/i.test(w)).slice(0, 2).map((w) => (w.match(/[\p{L}\d]/u)?.[0] ?? "").toUpperCase());
567
+ return letters.join("") || "?";
568
+ }
569
+ function PersonAvatar({ name, size = "sm" }) {
570
+ return /* @__PURE__ */ jsx2(
571
+ "span",
572
+ {
573
+ "aria-hidden": "true",
574
+ "data-records-person-avatar": "",
575
+ className: cn2(
576
+ "inline-flex shrink-0 items-center justify-center rounded-full bg-foreground/10 font-medium text-foreground/80",
577
+ size === "md" ? "size-5 text-[10px]" : "size-4 text-[9px]"
578
+ ),
579
+ children: initialsOf(name)
580
+ }
581
+ );
582
+ }
583
+ function PersonChip({ name, onRemove, className }) {
584
+ return /* @__PURE__ */ jsxs2(
585
+ "span",
586
+ {
587
+ "data-records-person-chip": "",
588
+ title: name,
589
+ className: cn2("inline-flex min-w-0 max-w-full items-center gap-1 rounded-full bg-muted py-0.5 pl-0.5 pr-2 text-[11px] text-foreground", className),
590
+ children: [
591
+ /* @__PURE__ */ jsx2(PersonAvatar, { name }),
592
+ /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: name }),
593
+ onRemove ? /* @__PURE__ */ jsx2("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${name}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
594
+ ]
595
+ }
596
+ );
597
+ }
598
+
599
+ // src/PickOrAdd.tsx
600
+ import { BasicInput as BasicInput2, Button, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ScrollArea, cn as cn3 } from "@ai-matrx/design-system";
601
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
562
602
  function Glyph({ d, className }) {
563
- return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, className, children: /* @__PURE__ */ jsx2("path", { d }) });
603
+ return /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, className, children: /* @__PURE__ */ jsx3("path", { d }) });
564
604
  }
565
605
  var TICK = "m5 12 4 4L19 6";
566
606
  var CROSS = "M18 6 6 18M6 6l12 12";
@@ -610,6 +650,7 @@ function PickRow({
610
650
  disabled,
611
651
  attrs,
612
652
  icon,
653
+ person,
613
654
  onPick,
614
655
  onPoint
615
656
  }) {
@@ -617,7 +658,7 @@ function PickRow({
617
658
  useEffect2(() => {
618
659
  if (highlighted) ref.current?.scrollIntoView?.({ block: "nearest" });
619
660
  }, [highlighted]);
620
- return /* @__PURE__ */ jsxs2(
661
+ return /* @__PURE__ */ jsxs3(
621
662
  "button",
622
663
  {
623
664
  ref,
@@ -630,18 +671,19 @@ function PickRow({
630
671
  title: title ?? label,
631
672
  ...attrs ?? {},
632
673
  "data-pick-highlighted": highlighted ? "" : void 0,
633
- className: cn2(
674
+ className: cn3(
634
675
  "flex w-full min-w-0 items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none disabled:opacity-50",
635
676
  highlighted ? "bg-accent text-accent-foreground" : ""
636
677
  ),
637
678
  children: [
638
- /* @__PURE__ */ jsxs2("span", { className: "flex size-3.5 shrink-0 items-center justify-center", children: [
639
- picked ? /* @__PURE__ */ jsx2("span", { "data-pick-tick": "", className: "contents", children: /* @__PURE__ */ jsx2(Glyph, { d: TICK, className: "size-3.5" }) }) : null,
640
- icon === "plus" ? /* @__PURE__ */ jsx2(Glyph, { d: PLUS, className: "size-3.5 text-muted-foreground" }) : null
679
+ /* @__PURE__ */ jsxs3("span", { className: "flex size-3.5 shrink-0 items-center justify-center", children: [
680
+ picked ? /* @__PURE__ */ jsx3("span", { "data-pick-tick": "", className: "contents", children: /* @__PURE__ */ jsx3(Glyph, { d: TICK, className: "size-3.5" }) }) : null,
681
+ icon === "plus" ? /* @__PURE__ */ jsx3(Glyph, { d: PLUS, className: "size-3.5 text-muted-foreground" }) : null
641
682
  ] }),
642
- /* @__PURE__ */ jsxs2("span", { className: "min-w-0 flex-1", children: [
643
- chip ? /* @__PURE__ */ jsx2("span", { className: cn2("inline-flex max-w-full truncate rounded-md border px-1.5 py-0.5 text-xs font-medium", chip), "data-records-choice-chip": "", children: label }) : /* @__PURE__ */ jsx2("span", { className: "block truncate", children: label }),
644
- detail ? /* @__PURE__ */ jsx2("span", { className: "block truncate text-xs text-muted-foreground", "data-tell-apart": "", children: detail }) : null
683
+ person ? /* @__PURE__ */ jsx3(PersonAvatar, { name: label, size: "md" }) : null,
684
+ /* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1", children: [
685
+ chip ? /* @__PURE__ */ jsx3("span", { className: cn3("inline-flex max-w-full truncate rounded-md border px-1.5 py-0.5 text-xs font-medium", chip), "data-records-choice-chip": "", children: label }) : /* @__PURE__ */ jsx3("span", { className: "block truncate", children: label }),
686
+ detail ? /* @__PURE__ */ jsx3("span", { className: "block truncate text-xs text-muted-foreground", "data-tell-apart": "", children: detail }) : null
645
687
  ] })
646
688
  ]
647
689
  }
@@ -649,31 +691,33 @@ function PickRow({
649
691
  }
650
692
  function PickChips({ chips }) {
651
693
  if (chips.length === 0) return null;
652
- return /* @__PURE__ */ jsx2("div", { className: "flex flex-wrap gap-1 px-1 pb-1", "data-pick-chips": "", children: chips.map((c) => /* @__PURE__ */ jsxs2(
653
- "span",
654
- {
655
- "data-pick-chip": "",
656
- title: c.label,
657
- className: cn2(
658
- "inline-flex max-w-full items-center gap-1 rounded-md border px-1.5 py-0.5 text-xs font-medium",
659
- c.chip ?? "bg-secondary text-secondary-foreground"
660
- ),
661
- children: [
662
- /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: c.label }),
663
- c.onRemove ? /* @__PURE__ */ jsx2(
664
- "button",
665
- {
666
- type: "button",
667
- "aria-label": `Remove ${c.label}`,
668
- onClick: c.onRemove,
669
- className: "shrink-0 rounded-sm opacity-60 hover:opacity-100",
670
- children: /* @__PURE__ */ jsx2(Glyph, { d: CROSS, className: "size-3" })
671
- }
672
- ) : null
673
- ]
674
- },
675
- c.id
676
- )) });
694
+ return /* @__PURE__ */ jsx3("div", { className: "flex flex-wrap gap-1 px-1 pb-1", "data-pick-chips": "", children: chips.map(
695
+ (c) => c.person ? /* @__PURE__ */ jsx3(PersonChip, { name: c.label, onRemove: c.onRemove }, c.id) : /* @__PURE__ */ jsxs3(
696
+ "span",
697
+ {
698
+ "data-pick-chip": "",
699
+ title: c.label,
700
+ className: cn3(
701
+ "inline-flex max-w-full items-center gap-1 rounded-md border px-1.5 py-0.5 text-xs font-medium",
702
+ c.chip ?? "bg-secondary text-secondary-foreground"
703
+ ),
704
+ children: [
705
+ /* @__PURE__ */ jsx3("span", { className: "min-w-0 truncate", children: c.label }),
706
+ c.onRemove ? /* @__PURE__ */ jsx3(
707
+ "button",
708
+ {
709
+ type: "button",
710
+ "aria-label": `Remove ${c.label}`,
711
+ onClick: c.onRemove,
712
+ className: "shrink-0 rounded-sm opacity-60 hover:opacity-100",
713
+ children: /* @__PURE__ */ jsx3(Glyph, { d: CROSS, className: "size-3" })
714
+ }
715
+ ) : null
716
+ ]
717
+ },
718
+ c.id
719
+ )
720
+ ) });
677
721
  }
678
722
  function PickOrAdd({
679
723
  triggerLabel,
@@ -694,19 +738,24 @@ function PickOrAdd({
694
738
  anchored,
695
739
  children,
696
740
  chips,
697
- multi
741
+ multi,
742
+ addFirst
698
743
  }) {
699
744
  const addRow = add && !foot ? add : null;
700
745
  const count = items.length + (addRow ? 1 : 0);
746
+ const addAt = addRow ? addFirst ? 0 : items.length : -1;
747
+ const itemAt = (index) => addRow && addFirst ? index - 1 : index;
701
748
  const removable = (chips ?? []).filter((c) => c.onRemove);
702
749
  const keys = useListKeys({
703
750
  count,
704
751
  resetOn: search,
705
752
  onPick: (index) => {
706
- const item = items[index];
707
- if (item) {
708
- if (!item.disabled) onPick(item.id);
709
- } else if (addRow && !addRow.disabled) addRow.onAdd();
753
+ if (index === addAt) {
754
+ if (addRow && !addRow.disabled) addRow.onAdd();
755
+ return;
756
+ }
757
+ const item = items[itemAt(index)];
758
+ if (item && !item.disabled) onPick(item.id);
710
759
  },
711
760
  onNothing: onEnterWithNoMatch ?? (add && !add.disabled ? add.onAdd : void 0),
712
761
  onClose: () => onOpenChange(false),
@@ -715,9 +764,22 @@ function PickOrAdd({
715
764
  searchEmpty: search === ""
716
765
  });
717
766
  const hasFoot = Boolean(foot) || Boolean(footNote);
718
- return /* @__PURE__ */ jsxs2(Popover, { open, onOpenChange, children: [
719
- anchored ? /* @__PURE__ */ jsx2(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx2("div", { className: "flex min-h-6 w-full min-w-0 flex-wrap items-center gap-1", "aria-label": triggerLabel, children }) }) : /* @__PURE__ */ jsx2(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx2(Button, { id: triggerId, type: "button", size: "sm", variant: "outline", "aria-label": triggerLabel, children: triggerText }) }),
720
- /* @__PURE__ */ jsxs2(
767
+ const addRowNode = addRow ? /* @__PURE__ */ jsx3(
768
+ PickRow,
769
+ {
770
+ label: addRow.label,
771
+ picked: false,
772
+ icon: "plus",
773
+ disabled: addRow.disabled,
774
+ attrs: { "data-pick-add": "" },
775
+ highlighted: addAt === keys.highlight,
776
+ onPick: addRow.onAdd,
777
+ onPoint: () => keys.setHighlight(addAt)
778
+ }
779
+ ) : null;
780
+ return /* @__PURE__ */ jsxs3(Popover, { open, onOpenChange, children: [
781
+ anchored ? /* @__PURE__ */ jsx3(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx3("div", { className: "flex min-h-6 w-full min-w-0 flex-wrap items-center gap-1", "aria-label": triggerLabel, children }) }) : /* @__PURE__ */ jsx3(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx3(Button, { id: triggerId, type: "button", size: "sm", variant: "outline", "aria-label": triggerLabel, children: triggerText }) }),
782
+ /* @__PURE__ */ jsxs3(
721
783
  PopoverContent,
722
784
  {
723
785
  sizing: "content",
@@ -734,8 +796,8 @@ function PickOrAdd({
734
796
  if (anchored) event.preventDefault();
735
797
  },
736
798
  children: [
737
- chips ? /* @__PURE__ */ jsx2(PickChips, { chips }) : null,
738
- /* @__PURE__ */ jsx2(
799
+ chips ? /* @__PURE__ */ jsx3(PickChips, { chips }) : null,
800
+ /* @__PURE__ */ jsx3(
739
801
  BasicInput2,
740
802
  {
741
803
  value: search,
@@ -749,9 +811,10 @@ function PickOrAdd({
749
811
  }
750
812
  ),
751
813
  notice,
752
- /* @__PURE__ */ jsxs2(ScrollArea, { className: "max-h-64", children: [
753
- /* @__PURE__ */ jsxs2("div", { role: "listbox", "aria-label": triggerLabel, "aria-multiselectable": multi ? true : void 0, children: [
754
- items.map((item, index) => /* @__PURE__ */ jsx2(
814
+ /* @__PURE__ */ jsxs3(ScrollArea, { className: "max-h-64", children: [
815
+ /* @__PURE__ */ jsxs3("div", { role: "listbox", "aria-label": triggerLabel, "aria-multiselectable": multi ? true : void 0, children: [
816
+ addFirst ? addRowNode : null,
817
+ items.map((item, index) => /* @__PURE__ */ jsx3(
755
818
  PickRow,
756
819
  {
757
820
  label: item.label,
@@ -761,29 +824,18 @@ function PickOrAdd({
761
824
  picked: item.picked,
762
825
  disabled: item.disabled,
763
826
  attrs: item.attrs,
764
- highlighted: index === keys.highlight,
827
+ person: item.person,
828
+ highlighted: (addRow && addFirst ? index + 1 : index) === keys.highlight,
765
829
  onPick: () => onPick(item.id),
766
- onPoint: () => keys.setHighlight(index)
830
+ onPoint: () => keys.setHighlight(addRow && addFirst ? index + 1 : index)
767
831
  },
768
832
  item.id
769
833
  )),
770
- addRow ? /* @__PURE__ */ jsx2(
771
- PickRow,
772
- {
773
- label: addRow.label,
774
- picked: false,
775
- icon: "plus",
776
- disabled: addRow.disabled,
777
- attrs: { "data-pick-add": "" },
778
- highlighted: items.length === keys.highlight,
779
- onPick: addRow.onAdd,
780
- onPoint: () => keys.setHighlight(items.length)
781
- }
782
- ) : null
834
+ addFirst ? null : addRowNode
783
835
  ] }),
784
836
  items.length === 0 && empty ? empty : null
785
837
  ] }),
786
- hasFoot ? /* @__PURE__ */ jsxs2("div", { className: "mt-1 border-t pt-1", children: [
838
+ hasFoot ? /* @__PURE__ */ jsxs3("div", { className: "mt-1 border-t pt-1", children: [
787
839
  foot,
788
840
  footNote
789
841
  ] }) : null
@@ -794,7 +846,7 @@ function PickOrAdd({
794
846
  }
795
847
 
796
848
  // src/Refusal.tsx
797
- import { Alert, AlertDescription, AlertTitle, ErrorBox, cn as cn3 } from "@ai-matrx/design-system";
849
+ import { Alert, AlertDescription, AlertTitle, ErrorBox, cn as cn4 } from "@ai-matrx/design-system";
798
850
 
799
851
  // src/plainWords.ts
800
852
  var MACHINE_IDENTITY = [
@@ -978,7 +1030,7 @@ function refusalLineForAPerson(error) {
978
1030
  }
979
1031
 
980
1032
  // src/Refusal.tsx
981
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1033
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
982
1034
  function RefusalNotice({
983
1035
  error,
984
1036
  className,
@@ -987,8 +1039,8 @@ function RefusalNotice({
987
1039
  onDiscard
988
1040
  }) {
989
1041
  const plain = refusalForAPerson(error);
990
- const doors = onKeepEditing || onDiscard ? /* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center gap-1 pt-0.5", "data-refusal-doors": "", children: [
991
- onKeepEditing ? /* @__PURE__ */ jsx3(
1042
+ const doors = onKeepEditing || onDiscard ? /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-1 pt-0.5", "data-refusal-doors": "", children: [
1043
+ onKeepEditing ? /* @__PURE__ */ jsx4(
992
1044
  "button",
993
1045
  {
994
1046
  type: "button",
@@ -998,7 +1050,7 @@ function RefusalNotice({
998
1050
  children: "Keep editing"
999
1051
  }
1000
1052
  ) : null,
1001
- onDiscard ? /* @__PURE__ */ jsx3(
1053
+ onDiscard ? /* @__PURE__ */ jsx4(
1002
1054
  "button",
1003
1055
  {
1004
1056
  type: "button",
@@ -1009,21 +1061,21 @@ function RefusalNotice({
1009
1061
  }
1010
1062
  ) : null
1011
1063
  ] }) : null;
1012
- return /* @__PURE__ */ jsxs3(
1064
+ return /* @__PURE__ */ jsxs4(
1013
1065
  Alert,
1014
1066
  {
1015
1067
  variant: "destructive",
1016
1068
  role: "alert",
1017
1069
  "data-refusal-notice": "",
1018
- className: cn3("text-xs", className),
1070
+ className: cn4("text-xs", className),
1019
1071
  errorFacts: { message: plain.sentence, title: plain.title, error, origin: "records-ui/RefusalNotice" },
1020
1072
  ...plain.forEngineers ? { "data-for-engineers": plain.forEngineers } : {},
1021
1073
  ...error.sqlstate ? { "data-sqlstate": error.sqlstate } : {},
1022
1074
  children: [
1023
- /* @__PURE__ */ jsx3(AlertTitle, { className: "text-xs font-medium", children: plain.storeSaid ? plain.sentence : plain.title }),
1024
- /* @__PURE__ */ jsxs3(AlertDescription, { className: "space-y-1 text-xs", children: [
1025
- plain.storeSaid || plain.sentence.replace(/\.$/, "") === plain.title ? null : /* @__PURE__ */ jsx3("p", { children: plain.sentence }),
1026
- /* @__PURE__ */ jsx3("p", { className: "opacity-80", children: plain.remedy }),
1075
+ /* @__PURE__ */ jsx4(AlertTitle, { className: "text-xs font-medium", children: plain.storeSaid ? plain.sentence : plain.title }),
1076
+ /* @__PURE__ */ jsxs4(AlertDescription, { className: "space-y-1 text-xs", children: [
1077
+ plain.storeSaid || plain.sentence.replace(/\.$/, "") === plain.title ? null : /* @__PURE__ */ jsx4("p", { children: plain.sentence }),
1078
+ /* @__PURE__ */ jsx4("p", { className: "opacity-80", children: plain.remedy }),
1027
1079
  actions,
1028
1080
  doors
1029
1081
  ] })
@@ -1033,11 +1085,11 @@ function RefusalNotice({
1033
1085
  }
1034
1086
  function RefusalLine({ error, className }) {
1035
1087
  const plain = refusalForAPerson(error);
1036
- return /* @__PURE__ */ jsx3(
1088
+ return /* @__PURE__ */ jsx4(
1037
1089
  ErrorBox,
1038
1090
  {
1039
1091
  "data-refusal-line": "",
1040
- className: cn3("text-xs text-destructive", className),
1092
+ className: cn4("text-xs text-destructive", className),
1041
1093
  message: refusalLineForAPerson(error),
1042
1094
  error,
1043
1095
  origin: "records-ui/RefusalLine",
@@ -1098,7 +1150,7 @@ function tellApart(rows, nameOf2) {
1098
1150
  }
1099
1151
 
1100
1152
  // src/RelationPicker.tsx
1101
- import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1153
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1102
1154
  var NO_STORE_ON_THIS_SCREEN_REASON = "This question points at a record in somebody's own data, and a page answered without an account is never allowed to search that. Leave it blank \u2014 whoever receives your answer will fill it in.";
1103
1155
  function RelationPicker({ field, value, onChange, disabled, id, className, allowCreate = true, onPicked, autoOpen, onClose }) {
1104
1156
  const client = useOptionalRecordsClient();
@@ -1185,11 +1237,11 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1185
1237
  return (
1186
1238
  // The Field's own name is already printed above this control by
1187
1239
  // `FieldLabel`, so the sentence does not say it a second time.
1188
- /* @__PURE__ */ jsx4("p", { id, className: cn4("text-xs text-muted-foreground", className), children: NO_STORE_ON_THIS_SCREEN_REASON })
1240
+ /* @__PURE__ */ jsx5("p", { id, className: cn5("text-xs text-muted-foreground", className), children: NO_STORE_ON_THIS_SCREEN_REASON })
1189
1241
  );
1190
1242
  }
1191
1243
  if (!field.relation_target) {
1192
- return /* @__PURE__ */ jsxs4("p", { className: "text-xs text-muted-foreground", children: [
1244
+ return /* @__PURE__ */ jsxs5("p", { className: "text-xs text-muted-foreground", children: [
1193
1245
  fieldName(field),
1194
1246
  " points at records, but it does not say which Table yet, so there is nothing to pick from. A table admin sets its target in the field editor."
1195
1247
  ] });
@@ -1249,7 +1301,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1249
1301
  const apart = tellApart(rows ?? [], titleOf);
1250
1302
  const visible = rankTypedMatches(rows ?? [], search, (row) => [titleOf(row.id), apart.get(row.id) ?? ""]);
1251
1303
  const anchored = autoOpen === true;
1252
- const cellChips = picked.map((recordId) => /* @__PURE__ */ jsx4(
1304
+ const cellChips = picked.map((recordId) => /* @__PURE__ */ jsx5(
1253
1305
  RecordChip,
1254
1306
  {
1255
1307
  title: titleOf(recordId),
@@ -1259,12 +1311,12 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1259
1311
  ));
1260
1312
  return (
1261
1313
  // Never wider than where it is drawn (a grid cell beside a sticky column: B3-07) — chips truncate, the button wraps.
1262
- /* @__PURE__ */ jsxs4("div", { className: cn4("flex min-w-0 max-w-full flex-wrap items-center gap-1", className), children: [
1314
+ /* @__PURE__ */ jsxs5("div", { className: cn5("flex min-w-0 max-w-full flex-wrap items-center gap-1", className), children: [
1263
1315
  anchored && !disabled ? null : cellChips,
1264
1316
  disabled ? null : (
1265
1317
  // THE ONE "PICK OR ADD" BUILDER (PickOrAdd.tsx) — the choice editor draws the same one.
1266
1318
  // In a grid cell it hangs from the cell's own chips; what is picked heads the list with its ×.
1267
- /* @__PURE__ */ jsx4(
1319
+ /* @__PURE__ */ jsx5(
1268
1320
  PickOrAdd,
1269
1321
  {
1270
1322
  anchored,
@@ -1286,17 +1338,17 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1286
1338
  attrs: { "data-relation-candidate": row.id }
1287
1339
  })),
1288
1340
  onPick: toggle,
1289
- notice: /* @__PURE__ */ jsxs4(Fragment2, { children: [
1290
- refusal2 ? /* @__PURE__ */ jsx4(RefusalLine, { error: refusal2, className: "p-2" }) : null,
1291
- !rows && !refusal2 ? /* @__PURE__ */ jsx4("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading\u2026" }) : null,
1292
- full ? /* @__PURE__ */ jsxs4("p", { className: "p-2 text-xs text-muted-foreground", children: [
1341
+ notice: /* @__PURE__ */ jsxs5(Fragment2, { children: [
1342
+ refusal2 ? /* @__PURE__ */ jsx5(RefusalLine, { error: refusal2, className: "p-2" }) : null,
1343
+ !rows && !refusal2 ? /* @__PURE__ */ jsx5("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading\u2026" }) : null,
1344
+ full ? /* @__PURE__ */ jsxs5("p", { className: "p-2 text-xs text-muted-foreground", children: [
1293
1345
  fieldName(field),
1294
1346
  " can point at ",
1295
1347
  field.relation_max,
1296
1348
  " at most. Remove one to add another."
1297
1349
  ] }) : null
1298
1350
  ] }),
1299
- empty: rows ? /* @__PURE__ */ jsx4("p", { className: "p-2 text-xs text-muted-foreground", children: "Nothing in that table matches." }) : null,
1351
+ empty: rows ? /* @__PURE__ */ jsx5("p", { className: "p-2 text-xs text-muted-foreground", children: "Nothing in that table matches." }) : null,
1300
1352
  add: allowCreate && !full && !targetRefusal && target && !creating ? {
1301
1353
  label: search.trim() !== "" ? `Create \u201C${search.trim()}\u201D` : `New ${targetWord}`,
1302
1354
  disabled: busy,
@@ -1311,8 +1363,8 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1311
1363
  }
1312
1364
  }
1313
1365
  } : null,
1314
- foot: !allowCreate || full ? void 0 : targetRefusal ? /* @__PURE__ */ jsx4(RefusalLine, { error: targetRefusal, className: "p-2" }) : !target ? /* @__PURE__ */ jsx4("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading that table\u2026" }) : creating ? /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1 p-1", children: [
1315
- /* @__PURE__ */ jsx4(
1366
+ foot: !allowCreate || full ? void 0 : targetRefusal ? /* @__PURE__ */ jsx5(RefusalLine, { error: targetRefusal, className: "p-2" }) : !target ? /* @__PURE__ */ jsx5("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading that table\u2026" }) : creating ? /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1 p-1", children: [
1367
+ /* @__PURE__ */ jsx5(
1316
1368
  BasicInput3,
1317
1369
  {
1318
1370
  autoFocus: true,
@@ -1329,7 +1381,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1329
1381
  "aria-label": `Name the new ${targetWord}`
1330
1382
  }
1331
1383
  ),
1332
- /* @__PURE__ */ jsx4(
1384
+ /* @__PURE__ */ jsx5(
1333
1385
  Button2,
1334
1386
  {
1335
1387
  type: "button",
@@ -1344,7 +1396,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
1344
1396
  footNote: allowCreate && !full && createRefusal ? (
1345
1397
  // The typed title is still in the search box: the notice owns the
1346
1398
  // two doors out (lane REFUSAL-SWEEP).
1347
- /* @__PURE__ */ jsx4(
1399
+ /* @__PURE__ */ jsx5(
1348
1400
  RefusalNotice,
1349
1401
  {
1350
1402
  error: createRefusal,
@@ -1428,7 +1480,7 @@ function whatYouMayDo(level, known = true) {
1428
1480
  var NOT_ANSWERED_YET = whatYouMayDo(null, false);
1429
1481
 
1430
1482
  // src/host.tsx
1431
- import { jsx as jsx5 } from "react/jsx-runtime";
1483
+ import { jsx as jsx6 } from "react/jsx-runtime";
1432
1484
  function tableRights(may, overallReason) {
1433
1485
  return {
1434
1486
  ...may,
@@ -1452,9 +1504,9 @@ import { isUuidShape as isUuidShape2 } from "@ai-matrx/kit/uuid";
1452
1504
 
1453
1505
  // src/signature.tsx
1454
1506
  import { useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
1455
- import { Button as Button3, ErrorBox as ErrorBox2, cn as cn5 } from "@ai-matrx/design-system";
1507
+ import { Button as Button3, ErrorBox as ErrorBox2, cn as cn6 } from "@ai-matrx/design-system";
1456
1508
  import { useOptionalRecordsClient as useOptionalRecordsClient2 } from "@ai-matrx/records/react";
1457
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1509
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1458
1510
  var DRAWN = /^data:image\/(png|jpeg);base64,[A-Za-z0-9+/=]{64,}$/;
1459
1511
  function drawnSignatureOf(value) {
1460
1512
  return typeof value === "string" && DRAWN.test(value) ? value : null;
@@ -1511,13 +1563,13 @@ function drawingOf(client, fileId) {
1511
1563
  return asked3;
1512
1564
  }
1513
1565
  function DrawnImage({ src, inCell }) {
1514
- return /* @__PURE__ */ jsx6(
1566
+ return /* @__PURE__ */ jsx7(
1515
1567
  "img",
1516
1568
  {
1517
1569
  src,
1518
1570
  alt: SIGNED_WORD,
1519
1571
  "data-records-signature": "",
1520
- className: cn5("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
1572
+ className: cn6("max-w-[12rem] object-contain object-left dark:invert", inCell ? "h-7" : "h-12")
1521
1573
  }
1522
1574
  );
1523
1575
  }
@@ -1545,11 +1597,11 @@ function SignatureDrawing({
1545
1597
  cancelled = true;
1546
1598
  };
1547
1599
  }, [client, recordId, fieldKey, knownFile]);
1548
- if (drawing?.src) return /* @__PURE__ */ jsx6(DrawnImage, { src: drawing.src, inCell });
1600
+ if (drawing?.src) return /* @__PURE__ */ jsx7(DrawnImage, { src: drawing.src, inCell });
1549
1601
  if (drawing?.hostFileId && host.fileImage) {
1550
- return /* @__PURE__ */ jsx6("span", { className: cn5("inline-block max-w-[12rem] dark:invert", inCell ? "h-7" : "h-12"), "data-records-signature": "", children: host.fileImage({ fileId: drawing.hostFileId, alt: SIGNED_WORD }) });
1602
+ return /* @__PURE__ */ jsx7("span", { className: cn6("inline-block max-w-[12rem] dark:invert", inCell ? "h-7" : "h-12"), "data-records-signature": "", children: host.fileImage({ fileId: drawing.hostFileId, alt: SIGNED_WORD }) });
1551
1603
  }
1552
- return /* @__PURE__ */ jsx6("span", { className: "font-serif italic", children: String(value) });
1604
+ return /* @__PURE__ */ jsx7("span", { className: "font-serif italic", children: String(value) });
1553
1605
  }
1554
1606
  function SignatureValue({
1555
1607
  value,
@@ -1559,12 +1611,12 @@ function SignatureValue({
1559
1611
  document: document2
1560
1612
  }) {
1561
1613
  const drawn = drawnSignatureOf(value);
1562
- if (drawn) return /* @__PURE__ */ jsx6(DrawnImage, { src: drawn, inCell });
1614
+ if (drawn) return /* @__PURE__ */ jsx7(DrawnImage, { src: drawn, inCell });
1563
1615
  const fileId = fieldKey ? signatureFileIn(document2, fieldKey) : null;
1564
1616
  if (value === SIGNED_WORD && (fileId || recordId && fieldKey)) {
1565
- return /* @__PURE__ */ jsx6(SignatureDrawing, { recordId: recordId ?? null, fieldKey: fieldKey ?? null, fileId, value, inCell });
1617
+ return /* @__PURE__ */ jsx7(SignatureDrawing, { recordId: recordId ?? null, fieldKey: fieldKey ?? null, fileId, value, inCell });
1566
1618
  }
1567
- return /* @__PURE__ */ jsx6("span", { className: "font-serif italic", children: String(value) });
1619
+ return /* @__PURE__ */ jsx7("span", { className: "font-serif italic", children: String(value) });
1568
1620
  }
1569
1621
  var INK = "#111827";
1570
1622
  var SIGNATURE_BUDGET_BYTES = 6e4;
@@ -1647,14 +1699,14 @@ function SignaturePad({
1647
1699
  onChange(null);
1648
1700
  };
1649
1701
  if (!showPad) {
1650
- return /* @__PURE__ */ jsxs5("div", { id, className: cn5("flex items-center justify-between gap-2 rounded-md border px-3 py-2", className), children: [
1651
- /* @__PURE__ */ jsx6(SignatureValue, { value }),
1652
- !disabled ? /* @__PURE__ */ jsx6(Button3, { type: "button", variant: "ghost", size: "sm", onClick: clear, children: "Sign again" }) : null
1702
+ return /* @__PURE__ */ jsxs6("div", { id, className: cn6("flex items-center justify-between gap-2 rounded-md border px-3 py-2", className), children: [
1703
+ /* @__PURE__ */ jsx7(SignatureValue, { value }),
1704
+ !disabled ? /* @__PURE__ */ jsx7(Button3, { type: "button", variant: "ghost", size: "sm", onClick: clear, children: "Sign again" }) : null
1653
1705
  ] });
1654
1706
  }
1655
- return /* @__PURE__ */ jsxs5("div", { className: cn5("flex w-full flex-col gap-1", className), children: [
1656
- /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
1657
- /* @__PURE__ */ jsx6(
1707
+ return /* @__PURE__ */ jsxs6("div", { className: cn6("flex w-full flex-col gap-1", className), children: [
1708
+ /* @__PURE__ */ jsxs6("div", { className: "relative", children: [
1709
+ /* @__PURE__ */ jsx7(
1658
1710
  "canvas",
1659
1711
  {
1660
1712
  id,
@@ -1667,16 +1719,16 @@ function SignaturePad({
1667
1719
  onPointerUp: end,
1668
1720
  onPointerLeave: end,
1669
1721
  onPointerCancel: end,
1670
- className: cn5(
1722
+ className: cn6(
1671
1723
  "block h-36 w-full touch-none rounded-md border border-border bg-white",
1672
1724
  disabled ? "cursor-not-allowed opacity-60" : "cursor-crosshair"
1673
1725
  )
1674
1726
  }
1675
1727
  ),
1676
- !dirty ? /* @__PURE__ */ jsx6("span", { className: "pointer-events-none absolute inset-x-0 bottom-3 text-center text-xs text-neutral-400", children: "Sign here" }) : null
1728
+ !dirty ? /* @__PURE__ */ jsx7("span", { className: "pointer-events-none absolute inset-x-0 bottom-3 text-center text-xs text-neutral-400", children: "Sign here" }) : null
1677
1729
  ] }),
1678
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-end gap-2", children: [
1679
- tooBig ? /* @__PURE__ */ jsx6(
1730
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-end gap-2", children: [
1731
+ tooBig ? /* @__PURE__ */ jsx7(
1680
1732
  ErrorBox2,
1681
1733
  {
1682
1734
  as: "span",
@@ -1686,7 +1738,7 @@ function SignaturePad({
1686
1738
  origin: "records-ui/signature"
1687
1739
  }
1688
1740
  ) : null,
1689
- /* @__PURE__ */ jsx6(Button3, { type: "button", variant: "ghost", size: "sm", onClick: clear, disabled: disabled || !dirty, children: "Clear" })
1741
+ /* @__PURE__ */ jsx7(Button3, { type: "button", variant: "ghost", size: "sm", onClick: clear, disabled: disabled || !dirty, children: "Clear" })
1690
1742
  ] })
1691
1743
  ] });
1692
1744
  }
@@ -1721,7 +1773,7 @@ function encodeAt(canvas, type, maxWidth, quality) {
1721
1773
  }
1722
1774
 
1723
1775
  // src/labels.tsx
1724
- import { jsx as jsx7 } from "react/jsx-runtime";
1776
+ import { jsx as jsx8 } from "react/jsx-runtime";
1725
1777
  var LabelContext = createContext2({
1726
1778
  // With no provider the resolver is ABSENT, not silently empty: a caller gets
1727
1779
  // null and says "Loading…" forever, which is visible. The mount always
@@ -1909,7 +1961,7 @@ function RecordLabelProvider({ children }) {
1909
1961
  );
1910
1962
  const waiting = useCallback2((field) => waitingLines[field.id] ?? null, [waitingLines]);
1911
1963
  const value = useMemo3(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
1912
- return /* @__PURE__ */ jsx7(LabelContext.Provider, { value, children });
1964
+ return /* @__PURE__ */ jsx8(LabelContext.Provider, { value, children });
1913
1965
  }
1914
1966
  function useRecordLabels(fields) {
1915
1967
  const { lookup, want } = useContext2(LabelContext);
@@ -1921,8 +1973,8 @@ function useRecordLabels(fields) {
1921
1973
 
1922
1974
  // src/FilePicker.tsx
1923
1975
  import { useCallback as useCallback3, useId, useRef as useRef6, useState as useState6 } from "react";
1924
- import { Button as Button4, cn as cn6 } from "@ai-matrx/design-system";
1925
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1976
+ import { Button as Button4, cn as cn7 } from "@ai-matrx/design-system";
1977
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1926
1978
  function FilePicker({
1927
1979
  label,
1928
1980
  accept,
@@ -1952,11 +2004,11 @@ function FilePicker({
1952
2004
  },
1953
2005
  [take]
1954
2006
  );
1955
- return /* @__PURE__ */ jsxs6(
2007
+ return /* @__PURE__ */ jsxs7(
1956
2008
  "div",
1957
2009
  {
1958
2010
  "data-matrx-file-picker": true,
1959
- className: cn6("flex min-w-0 flex-col gap-1", className),
2011
+ className: cn7("flex min-w-0 flex-col gap-1", className),
1960
2012
  onDragOver: (e) => {
1961
2013
  if (disabled) return;
1962
2014
  e.preventDefault();
@@ -1965,16 +2017,16 @@ function FilePicker({
1965
2017
  onDragLeave: () => setOver(false),
1966
2018
  onDrop,
1967
2019
  children: [
1968
- /* @__PURE__ */ jsxs6(
2020
+ /* @__PURE__ */ jsxs7(
1969
2021
  "div",
1970
2022
  {
1971
- className: cn6(
2023
+ className: cn7(
1972
2024
  "flex min-w-0 flex-wrap items-center gap-2 rounded-md border border-dashed px-2 py-1.5",
1973
2025
  over ? "border-primary bg-primary/5" : "border-border",
1974
2026
  disabled && "opacity-60"
1975
2027
  ),
1976
2028
  children: [
1977
- /* @__PURE__ */ jsx8(
2029
+ /* @__PURE__ */ jsx9(
1978
2030
  "input",
1979
2031
  {
1980
2032
  ref: input,
@@ -1991,7 +2043,7 @@ function FilePicker({
1991
2043
  }
1992
2044
  }
1993
2045
  ),
1994
- /* @__PURE__ */ jsx8(
2046
+ /* @__PURE__ */ jsx9(
1995
2047
  Button4,
1996
2048
  {
1997
2049
  type: "button",
@@ -2002,19 +2054,19 @@ function FilePicker({
2002
2054
  children: chosenName ? "Choose a different file" : label
2003
2055
  }
2004
2056
  ),
2005
- chosenName ? /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 truncate text-xs", title: chosenName, children: chosenName }) : /* @__PURE__ */ jsx8("span", { className: "text-xs text-muted-foreground", children: "or drop it here" }),
2006
- chosenName && onClear ? /* @__PURE__ */ jsx8(Button4, { type: "button", size: "sm", variant: "ghost", disabled, onClick: onClear, children: "Cancel" }) : null
2057
+ chosenName ? /* @__PURE__ */ jsx9("span", { className: "min-w-0 flex-1 truncate text-xs", title: chosenName, children: chosenName }) : /* @__PURE__ */ jsx9("span", { className: "text-xs text-muted-foreground", children: "or drop it here" }),
2058
+ chosenName && onClear ? /* @__PURE__ */ jsx9(Button4, { type: "button", size: "sm", variant: "ghost", disabled, onClick: onClear, children: "Cancel" }) : null
2007
2059
  ]
2008
2060
  }
2009
2061
  ),
2010
- hint && !chosenName ? /* @__PURE__ */ jsx8("p", { className: "text-xs text-muted-foreground", children: hint }) : null
2062
+ hint && !chosenName ? /* @__PURE__ */ jsx9("p", { className: "text-xs text-muted-foreground", children: hint }) : null
2011
2063
  ]
2012
2064
  }
2013
2065
  );
2014
2066
  }
2015
2067
 
2016
2068
  // src/gridAttachments.tsx
2017
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
2069
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
2018
2070
  function attachmentIdsOf(value) {
2019
2071
  return idsOf(value);
2020
2072
  }
@@ -2068,8 +2120,8 @@ function AttachmentChip({ id, onRemove }) {
2068
2120
  const words = read?.name ?? (read ? FILE_CHIP_UNREAD : "\u2026");
2069
2121
  const href = read?.fileId ? host.hrefForFile?.({ fileId: read.fileId }) : void 0;
2070
2122
  const title = href ? `Open ${words}` : read?.why ?? FILE_CHIP_NO_PAGE;
2071
- return /* @__PURE__ */ jsxs7(Badge, { variant: "secondary", className: "max-w-[14rem] gap-1 text-[11px]", "data-records-file-chip": id, title, children: [
2072
- href ? /* @__PURE__ */ jsx9(
2123
+ return /* @__PURE__ */ jsxs8(Badge, { variant: "secondary", className: "max-w-[14rem] gap-1 text-[11px]", "data-records-file-chip": id, title, children: [
2124
+ href ? /* @__PURE__ */ jsx10(
2073
2125
  "a",
2074
2126
  {
2075
2127
  href,
@@ -2081,8 +2133,8 @@ function AttachmentChip({ id, onRemove }) {
2081
2133
  onMouseDown: (event) => event.stopPropagation(),
2082
2134
  children: words
2083
2135
  }
2084
- ) : /* @__PURE__ */ jsx9("span", { className: "truncate", children: words }),
2085
- onRemove ? /* @__PURE__ */ jsx9(
2136
+ ) : /* @__PURE__ */ jsx10("span", { className: "truncate", children: words }),
2137
+ onRemove ? /* @__PURE__ */ jsx10(
2086
2138
  "button",
2087
2139
  {
2088
2140
  type: "button",
@@ -2100,7 +2152,7 @@ function AttachmentChip({ id, onRemove }) {
2100
2152
  function AttachmentChips({ value, onRemove }) {
2101
2153
  const ids = attachmentIdsOf(value);
2102
2154
  if (ids.length === 0) return null;
2103
- return /* @__PURE__ */ jsx9("span", { className: "flex flex-wrap gap-1", "data-records-file-chips": "", children: ids.map((id) => /* @__PURE__ */ jsx9(AttachmentChip, { id, ...onRemove ? { onRemove: () => onRemove(id) } : {} }, id)) });
2155
+ return /* @__PURE__ */ jsx10("span", { className: "flex flex-wrap gap-1", "data-records-file-chips": "", children: ids.map((id) => /* @__PURE__ */ jsx10(AttachmentChip, { id, ...onRemove ? { onRemove: () => onRemove(id) } : {} }, id)) });
2104
2156
  }
2105
2157
  function hostTakesFiles(host) {
2106
2158
  return Boolean(host.pickFiles || host.upload);
@@ -2145,19 +2197,19 @@ function AttachmentControl({
2145
2197
  void pick();
2146
2198
  }, [autoOpen]);
2147
2199
  if (!hostTakesFiles(host)) {
2148
- return /* @__PURE__ */ jsx9("p", { id, className: "rounded border border-dashed px-2 py-1 text-xs text-muted-foreground", "data-records-no-file-door": "", children: NO_UPLOAD_REASON });
2200
+ return /* @__PURE__ */ jsx10("p", { id, className: "rounded border border-dashed px-2 py-1 text-xs text-muted-foreground", "data-records-no-file-door": "", children: NO_UPLOAD_REASON });
2149
2201
  }
2150
- return /* @__PURE__ */ jsxs7("span", { id, className: "flex flex-col gap-1", "data-records-attachment-editor": "", children: [
2151
- /* @__PURE__ */ jsx9(
2202
+ return /* @__PURE__ */ jsxs8("span", { id, className: "flex flex-col gap-1", "data-records-attachment-editor": "", children: [
2203
+ /* @__PURE__ */ jsx10(
2152
2204
  AttachmentChips,
2153
2205
  {
2154
2206
  value,
2155
2207
  ...disabled ? {} : { onRemove: (removed) => onChange(withoutAttached(field, latest.current, removed)) }
2156
2208
  }
2157
2209
  ),
2158
- /* @__PURE__ */ jsxs7("span", { className: "flex flex-wrap items-center gap-1", children: [
2159
- host.pickFiles ? /* @__PURE__ */ jsx9(Button5, { size: "sm", variant: "outline", disabled: disabled || busy, onClick: () => void pick(), "data-records-attach-files": "", children: busy ? "Choosing\u2026" : attachmentIdsOf(value).length > 0 ? "Add files\u2026" : "Attach files\u2026" }) : null,
2160
- host.upload ? /* @__PURE__ */ jsx9(
2210
+ /* @__PURE__ */ jsxs8("span", { className: "flex flex-wrap items-center gap-1", children: [
2211
+ host.pickFiles ? /* @__PURE__ */ jsx10(Button5, { size: "sm", variant: "outline", disabled: disabled || busy, onClick: () => void pick(), "data-records-attach-files": "", children: busy ? "Choosing\u2026" : attachmentIdsOf(value).length > 0 ? "Add files\u2026" : "Attach files\u2026" }) : null,
2212
+ host.upload ? /* @__PURE__ */ jsx10(
2161
2213
  FilePicker,
2162
2214
  {
2163
2215
  label: "Upload a file",
@@ -2177,7 +2229,7 @@ function AttachmentControl({
2177
2229
  }
2178
2230
  ) : null
2179
2231
  ] }),
2180
- why ? /* @__PURE__ */ jsx9(RefusalLine, { error: refusal("invalid_argument", why, "Pick another file, or try this one again.") }) : null
2232
+ why ? /* @__PURE__ */ jsx10(RefusalLine, { error: refusal("invalid_argument", why, "Pick another file, or try this one again.") }) : null
2181
2233
  ] });
2182
2234
  }
2183
2235
 
@@ -2185,12 +2237,12 @@ function AttachmentControl({
2185
2237
  import { useMemo as useMemo4, useState as useState9 } from "react";
2186
2238
  import { entityRefsOf, entityRefsToWrite } from "@ai-matrx/records";
2187
2239
  import { useEntityReferenceKinds, useEntityReferenceSearch, useEntityReferenceWords, useOptionalRecordsClient as useOptionalRecordsClient4 } from "@ai-matrx/records/react";
2188
- import { Badge as Badge2, Button as Button6, cn as cn8 } from "@ai-matrx/design-system";
2240
+ import { Badge as Badge2, Button as Button6, cn as cn9 } from "@ai-matrx/design-system";
2189
2241
 
2190
2242
  // src/PickOne.tsx
2191
2243
  import { useState as useState8 } from "react";
2192
- import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, cn as cn7 } from "@ai-matrx/design-system";
2193
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
2244
+ import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, cn as cn8 } from "@ai-matrx/design-system";
2245
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
2194
2246
  var PICK_ONE_SEARCH_AFTER = 7;
2195
2247
  var EMPTY = "__records_pick_one_empty__";
2196
2248
  var inner = (v) => v === "" ? EMPTY : v;
@@ -2212,7 +2264,7 @@ function PickOne({
2212
2264
  if (options.length > PICK_ONE_SEARCH_AFTER) {
2213
2265
  const q = search.trim().toLowerCase();
2214
2266
  const shown2 = q === "" ? options : options.filter((o) => o.label.toLowerCase().includes(q));
2215
- return /* @__PURE__ */ jsx10("span", { className: cn7("inline-flex min-w-0", className), "data-records-pick-one": "search", "data-pick-value": value, ...attrs ?? {}, children: /* @__PURE__ */ jsx10(
2267
+ return /* @__PURE__ */ jsx11("span", { className: cn8("inline-flex min-w-0", className), "data-records-pick-one": "search", "data-pick-value": value, ...attrs ?? {}, children: /* @__PURE__ */ jsx11(
2216
2268
  PickOrAdd,
2217
2269
  {
2218
2270
  triggerLabel: label,
@@ -2237,29 +2289,29 @@ function PickOne({
2237
2289
  setOpen(false);
2238
2290
  setSearch("");
2239
2291
  },
2240
- empty: /* @__PURE__ */ jsx10("p", { className: "p-2 text-xs text-muted-foreground", children: "No match" })
2292
+ empty: /* @__PURE__ */ jsx11("p", { className: "p-2 text-xs text-muted-foreground", children: "No match" })
2241
2293
  }
2242
2294
  ) });
2243
2295
  }
2244
- return /* @__PURE__ */ jsxs8(Select, { value: current ? inner(current.value) : "", onValueChange: (v) => onChange(outer(v)), disabled: disabled ?? false, children: [
2245
- /* @__PURE__ */ jsx10(
2296
+ return /* @__PURE__ */ jsxs9(Select, { value: current ? inner(current.value) : "", onValueChange: (v) => onChange(outer(v)), disabled: disabled ?? false, children: [
2297
+ /* @__PURE__ */ jsx11(
2246
2298
  SelectTrigger,
2247
2299
  {
2248
2300
  id,
2249
2301
  size: "sm",
2250
2302
  "aria-label": label,
2251
- className: cn7("h-7 w-auto min-w-[7rem] text-xs", className),
2303
+ className: cn8("h-7 w-auto min-w-[7rem] text-xs", className),
2252
2304
  "data-records-pick-one": "list",
2253
2305
  "data-pick-value": value,
2254
2306
  ...attrs ?? {},
2255
- children: /* @__PURE__ */ jsx10(SelectValue, { placeholder })
2307
+ children: /* @__PURE__ */ jsx11(SelectValue, { placeholder })
2256
2308
  }
2257
2309
  ),
2258
- /* @__PURE__ */ jsx10(SelectContent, { children: groupsOf(options).map(
2259
- ([group, items]) => group ? /* @__PURE__ */ jsxs8(SelectGroup, { children: [
2260
- /* @__PURE__ */ jsx10(SelectLabel, { children: group }),
2261
- items.map((o) => /* @__PURE__ */ jsx10(SelectItem, { value: inner(o.value), "data-pick-value": o.value, "data-pick-group": group, children: o.label }, inner(o.value)))
2262
- ] }, group) : items.map((o) => /* @__PURE__ */ jsx10(SelectItem, { value: inner(o.value), "data-pick-value": o.value, children: o.label }, inner(o.value)))
2310
+ /* @__PURE__ */ jsx11(SelectContent, { children: groupsOf(options).map(
2311
+ ([group, items]) => group ? /* @__PURE__ */ jsxs9(SelectGroup, { children: [
2312
+ /* @__PURE__ */ jsx11(SelectLabel, { children: group }),
2313
+ items.map((o) => /* @__PURE__ */ jsx11(SelectItem, { value: inner(o.value), "data-pick-value": o.value, "data-pick-group": group, children: o.label }, inner(o.value)))
2314
+ ] }, group) : items.map((o) => /* @__PURE__ */ jsx11(SelectItem, { value: inner(o.value), "data-pick-value": o.value, children: o.label }, inner(o.value)))
2263
2315
  ) })
2264
2316
  ] });
2265
2317
  }
@@ -2274,7 +2326,7 @@ function groupsOf(options) {
2274
2326
  }
2275
2327
 
2276
2328
  // src/EntityReferenceControl.tsx
2277
- import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
2329
+ import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2278
2330
  var WITHHELD_ENTITY_LABEL = "Something you have not been given access to";
2279
2331
  var ENTITY_REFERENCE_EMPTY = "Nothing is pointed at yet.";
2280
2332
  function entityReferenceText(value) {
@@ -2289,7 +2341,7 @@ function allowedKindsOf(field) {
2289
2341
  }
2290
2342
  function EntityReferenceControl(props) {
2291
2343
  const client = useOptionalRecordsClient4();
2292
- return client ? /* @__PURE__ */ jsx11(WithWords, { ...props }) : /* @__PURE__ */ jsx11(Chips, { ...props, words: null, picker: null });
2344
+ return client ? /* @__PURE__ */ jsx12(WithWords, { ...props }) : /* @__PURE__ */ jsx12(Chips, { ...props, words: null, picker: null });
2293
2345
  }
2294
2346
  function WithWords(props) {
2295
2347
  const refs = useMemo4(() => entityRefsOf(props.value), [props.value]);
@@ -2301,7 +2353,7 @@ function WithWords(props) {
2301
2353
  [JSON.stringify(withKnown)]
2302
2354
  );
2303
2355
  const words = useEntityReferenceWords(unlabelled);
2304
- const picker = props.disabled ? null : /* @__PURE__ */ jsx11(
2356
+ const picker = props.disabled ? null : /* @__PURE__ */ jsx12(
2305
2357
  EntityReferencePicker,
2306
2358
  {
2307
2359
  field: props.field,
@@ -2314,7 +2366,7 @@ function WithWords(props) {
2314
2366
  }
2315
2367
  }
2316
2368
  );
2317
- return /* @__PURE__ */ jsx11(Chips, { ...props, value: withKnown, words, picker });
2369
+ return /* @__PURE__ */ jsx12(Chips, { ...props, value: withKnown, words, picker });
2318
2370
  }
2319
2371
  function EntityReferencePicker({
2320
2372
  field,
@@ -2337,7 +2389,7 @@ function EntityReferencePicker({
2337
2389
  picked: refs.some((x) => x.token === r.token && x.id === r.id),
2338
2390
  attrs: { "data-entity-reference-candidate": `${r.token}:${r.id}` }
2339
2391
  }));
2340
- const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ jsx11("div", { className: "mb-1 flex flex-wrap gap-1", role: "group", "aria-label": `Which kind \u2014 ${field.label}`, children: [null, ...allowed].map((token) => /* @__PURE__ */ jsx11(
2392
+ const kindChoice = allowed.length > 1 ? allowed.length <= 4 ? /* @__PURE__ */ jsx12("div", { className: "mb-1 flex flex-wrap gap-1", role: "group", "aria-label": `Which kind \u2014 ${field.label}`, children: [null, ...allowed].map((token) => /* @__PURE__ */ jsx12(
2341
2393
  Button6,
2342
2394
  {
2343
2395
  type: "button",
@@ -2349,7 +2401,7 @@ function EntityReferencePicker({
2349
2401
  children: token ? labelOfKind(token) : "Any"
2350
2402
  },
2351
2403
  token ?? "any"
2352
- )) }) : /* @__PURE__ */ jsx11(
2404
+ )) }) : /* @__PURE__ */ jsx12(
2353
2405
  PickOne,
2354
2406
  {
2355
2407
  label: `Which kind \u2014 ${field.label}`,
@@ -2359,13 +2411,13 @@ function EntityReferencePicker({
2359
2411
  options: [{ value: "", label: "Any kind" }, ...allowed.map((token) => ({ value: token, label: labelOfKind(token) }))]
2360
2412
  }
2361
2413
  ) : null;
2362
- const notice = /* @__PURE__ */ jsxs9(Fragment3, { children: [
2414
+ const notice = /* @__PURE__ */ jsxs10(Fragment3, { children: [
2363
2415
  kindChoice,
2364
- found.error ? /* @__PURE__ */ jsx11(RefusalLine, { error: found.error, className: "px-2 py-1 text-[11px]" }) : null,
2365
- found.loading && !found.data ? /* @__PURE__ */ jsx11("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: "Searching\u2026" }) : null
2416
+ found.error ? /* @__PURE__ */ jsx12(RefusalLine, { error: found.error, className: "px-2 py-1 text-[11px]" }) : null,
2417
+ found.loading && !found.data ? /* @__PURE__ */ jsx12("p", { className: "px-2 py-1 text-[11px] text-muted-foreground", children: "Searching\u2026" }) : null
2366
2418
  ] });
2367
2419
  const kindWords = allowed.length === 1 ? labelOfKind(allowed[0]).toLowerCase() : "thing";
2368
- return /* @__PURE__ */ jsx11(
2420
+ return /* @__PURE__ */ jsx12(
2369
2421
  PickOrAdd,
2370
2422
  {
2371
2423
  triggerLabel: `Pick for ${field.label}`,
@@ -2379,7 +2431,7 @@ function EntityReferencePicker({
2379
2431
  onSearch: setSearch,
2380
2432
  items,
2381
2433
  notice,
2382
- empty: found.loading ? null : /* @__PURE__ */ jsx11("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.` }),
2434
+ empty: found.loading ? null : /* @__PURE__ */ jsx12("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.` }),
2383
2435
  onPick: (key) => {
2384
2436
  const r = (found.data ?? []).find((x) => `${x.token}:${x.id}` === key);
2385
2437
  if (!r) return;
@@ -2409,13 +2461,13 @@ function Chips({
2409
2461
  return WITHHELD_ENTITY_LABEL;
2410
2462
  };
2411
2463
  const multi = Boolean(field.multi);
2412
- return /* @__PURE__ */ jsxs9("div", { id, className: cn8("flex flex-wrap items-center gap-1", className), "aria-label": `What ${field.label} points at`, children: [
2413
- refs.length === 0 && !picker ? /* @__PURE__ */ jsx11("span", { className: "text-[11px] text-muted-foreground", children: ENTITY_REFERENCE_EMPTY }) : null,
2464
+ return /* @__PURE__ */ jsxs10("div", { id, className: cn9("flex flex-wrap items-center gap-1", className), "aria-label": `What ${field.label} points at`, children: [
2465
+ refs.length === 0 && !picker ? /* @__PURE__ */ jsx12("span", { className: "text-[11px] text-muted-foreground", children: ENTITY_REFERENCE_EMPTY }) : null,
2414
2466
  refs.map((r) => {
2415
2467
  const label = labelOf(r.token, r.id, r.label);
2416
- return /* @__PURE__ */ jsxs9(Badge2, { variant: "secondary", className: "gap-1 text-[11px]", "data-entity-reference-chip": `${r.token}:${r.id}`, children: [
2468
+ return /* @__PURE__ */ jsxs10(Badge2, { variant: "secondary", className: "gap-1 text-[11px]", "data-entity-reference-chip": `${r.token}:${r.id}`, children: [
2417
2469
  label,
2418
- disabled ? null : /* @__PURE__ */ jsx11(
2470
+ disabled ? null : /* @__PURE__ */ jsx12(
2419
2471
  "button",
2420
2472
  {
2421
2473
  type: "button",
@@ -2438,8 +2490,8 @@ function Chips({
2438
2490
  import { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo5, useRef as useRef8, useState as useState10 } from "react";
2439
2491
  import { rankTypedMatches as rankTypedMatches2 } from "@ai-matrx/records";
2440
2492
  import { useOptionalRecordsClient as useOptionalRecordsClient5 } from "@ai-matrx/records/react";
2441
- import { cn as cn9 } from "@ai-matrx/design-system";
2442
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2493
+ import { cn as cn10 } from "@ai-matrx/design-system";
2494
+ import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
2443
2495
  function personFromRow(row) {
2444
2496
  const data = row.document ?? {};
2445
2497
  const userId = data["user_id"];
@@ -2520,10 +2572,10 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2520
2572
  }, [client, personTable, picked.length, people.length]);
2521
2573
  const listed = rankTypedMatches2(members ?? [], search, memberName);
2522
2574
  if (!membersPort || !client) {
2523
- return /* @__PURE__ */ jsx12("p", { className: cn9("text-xs text-muted-foreground", className), children: NO_MEMBERS_REASON });
2575
+ return /* @__PURE__ */ jsx13("p", { className: cn10("text-xs text-muted-foreground", className), children: NO_MEMBERS_REASON });
2524
2576
  }
2525
2577
  if (!personTable) {
2526
- return /* @__PURE__ */ jsxs10("p", { className: cn9("text-xs text-muted-foreground", className), children: [
2578
+ return /* @__PURE__ */ jsxs11("p", { className: cn10("text-xs text-muted-foreground", className), children: [
2527
2579
  fieldName(field),
2528
2580
  " 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."
2529
2581
  ] });
@@ -2573,21 +2625,14 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2573
2625
  picked.map((recordId) => people.find((p) => p.id === recordId)?.userId).filter(Boolean)
2574
2626
  );
2575
2627
  const anchored = autoOpen === true;
2576
- const cellChips = picked.map((recordId) => /* @__PURE__ */ jsx12(
2577
- RecordChip,
2578
- {
2579
- title: nameOfRecord(recordId),
2580
- ...disabled || anchored ? {} : { onRemove: () => drop(recordId) }
2581
- },
2582
- recordId
2583
- ));
2584
- return /* @__PURE__ */ jsxs10("div", { className: cn9("flex flex-wrap items-center gap-1", className), children: [
2628
+ const cellChips = picked.map((recordId) => /* @__PURE__ */ jsx13(PersonChip, { name: nameOfRecord(recordId), ...disabled || anchored ? {} : { onRemove: () => drop(recordId) } }, recordId));
2629
+ return /* @__PURE__ */ jsxs11("div", { className: cn10("flex flex-wrap items-center gap-1", className), children: [
2585
2630
  anchored && !disabled ? null : cellChips,
2586
2631
  disabled ? null : (
2587
2632
  // THE ONE "PICK OR ADD" BUILDER (lane CELL-EDITORS, 2026-10-06): the person list used to carry
2588
2633
  // its own copy of the list's layout and keys; it now draws the same rows, ticks, highlight and
2589
2634
  // head chips as every other picker, and in a grid cell hangs from the cell.
2590
- /* @__PURE__ */ jsx12(
2635
+ /* @__PURE__ */ jsx13(
2591
2636
  PickOrAdd,
2592
2637
  {
2593
2638
  anchored,
@@ -2599,7 +2644,7 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2599
2644
  onOpenChange: setOpen,
2600
2645
  search,
2601
2646
  onSearch: setSearch,
2602
- chips: picked.map((recordId) => ({ id: recordId, label: nameOfRecord(recordId), onRemove: () => drop(recordId) })),
2647
+ chips: picked.map((recordId) => ({ id: recordId, label: nameOfRecord(recordId), person: true, onRemove: () => drop(recordId) })),
2603
2648
  items: visible.map((member) => ({
2604
2649
  id: member.userId,
2605
2650
  label: displayNameOf(member.userId) ?? memberName(member),
@@ -2607,17 +2652,18 @@ function PersonPicker({ field, value, onChange, disabled, id, className, autoOpe
2607
2652
  // 19 September). They are two facts, so they are drawn as two.
2608
2653
  detail: displayNameOf(member.userId) !== null && member.email ? member.email : null,
2609
2654
  picked: pickedUserIds.has(member.userId),
2655
+ person: true,
2610
2656
  disabled: busy
2611
2657
  })),
2612
2658
  onPick: (userId) => {
2613
2659
  const member = visible.find((m) => m.userId === userId);
2614
2660
  if (member && !busy) void pick(member);
2615
2661
  },
2616
- notice: /* @__PURE__ */ jsxs10(Fragment4, { children: [
2617
- error ? /* @__PURE__ */ jsx12(RefusalLine, { error, className: "p-2" }) : null,
2618
- members === null ? /* @__PURE__ */ jsx12("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading the members\u2026" }) : null
2662
+ notice: /* @__PURE__ */ jsxs11(Fragment4, { children: [
2663
+ error ? /* @__PURE__ */ jsx13(RefusalLine, { error, className: "p-2" }) : null,
2664
+ members === null ? /* @__PURE__ */ jsx13("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading the members\u2026" }) : null
2619
2665
  ] }),
2620
- empty: members !== null ? /* @__PURE__ */ jsx12("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,
2666
+ empty: members !== null ? /* @__PURE__ */ jsx13("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,
2621
2667
  children: anchored ? cellChips : null
2622
2668
  }
2623
2669
  )
@@ -2700,8 +2746,8 @@ import { getFieldFormat as getFieldFormat3, parseFieldInput } from "@ai-matrx/de
2700
2746
  import { useRef as useRef9 } from "react";
2701
2747
  import { FormattedCell } from "@ai-matrx/design-system/data-table";
2702
2748
  import { formatFieldValue as formatFieldValue2, formatPhone, getFieldFormat as getFieldFormat2 } from "@ai-matrx/design-system/field-formats";
2703
- import { cn as cn10 } from "@ai-matrx/design-system";
2704
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
2749
+ import { cn as cn11 } from "@ai-matrx/design-system";
2750
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2705
2751
  var LINK = "inline-flex min-w-0 items-center gap-1 text-primary hover:underline";
2706
2752
  var own2 = (event) => event.stopPropagation();
2707
2753
  function numberOf(value) {
@@ -2723,7 +2769,7 @@ function RatingStars({
2723
2769
  const score = numberOf(value) ?? 0;
2724
2770
  const shown2 = Math.round(score);
2725
2771
  const said = `${shown2} out of ${max}`;
2726
- return /* @__PURE__ */ jsx13(
2772
+ return /* @__PURE__ */ jsx14(
2727
2773
  "span",
2728
2774
  {
2729
2775
  "data-records-rating": "",
@@ -2735,8 +2781,8 @@ function RatingStars({
2735
2781
  children: Array.from({ length: max }, (_, i) => {
2736
2782
  const n = i + 1;
2737
2783
  const lit = n <= shown2;
2738
- const star = /* @__PURE__ */ jsx13("span", { "aria-hidden": true, className: cn10("text-sm leading-none", lit ? "text-amber-400" : "text-muted-foreground/40"), children: "\u2605" });
2739
- return onRate ? /* @__PURE__ */ jsx13(
2784
+ const star = /* @__PURE__ */ jsx14("span", { "aria-hidden": true, className: cn11("text-sm leading-none", lit ? "text-amber-400" : "text-muted-foreground/40"), children: "\u2605" });
2785
+ return onRate ? /* @__PURE__ */ jsx14(
2740
2786
  "button",
2741
2787
  {
2742
2788
  type: "button",
@@ -2761,7 +2807,7 @@ function RatingStars({
2761
2807
  children: star
2762
2808
  },
2763
2809
  n
2764
- ) : /* @__PURE__ */ jsx13("span", { children: star }, n);
2810
+ ) : /* @__PURE__ */ jsx14("span", { children: star }, n);
2765
2811
  })
2766
2812
  }
2767
2813
  );
@@ -2769,13 +2815,13 @@ function RatingStars({
2769
2815
  function rich(id, text, raw, format) {
2770
2816
  switch (id) {
2771
2817
  case "email":
2772
- return /* @__PURE__ */ jsx13("a", { href: `mailto:${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ jsx13("span", { className: "truncate", children: text }) });
2818
+ return /* @__PURE__ */ jsx14("a", { href: `mailto:${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ jsx14("span", { className: "truncate", children: text }) });
2773
2819
  case "url":
2774
- return /* @__PURE__ */ jsx13("a", { href: text.includes("://") ? text : `https://${text}`, target: "_blank", rel: "noopener noreferrer", className: LINK, onClick: own2, children: /* @__PURE__ */ jsx13("span", { className: "truncate", children: text }) });
2820
+ return /* @__PURE__ */ jsx14("a", { href: text.includes("://") ? text : `https://${text}`, target: "_blank", rel: "noopener noreferrer", className: LINK, onClick: own2, children: /* @__PURE__ */ jsx14("span", { className: "truncate", children: text }) });
2775
2821
  case "phone":
2776
- return /* @__PURE__ */ jsx13("a", { href: `tel:${text.replace(/[^\d+]/g, "")}`, className: LINK, onClick: own2, title: text, children: /* @__PURE__ */ jsx13("span", { className: "truncate tabular-nums", children: formatPhone(text) }) });
2822
+ return /* @__PURE__ */ jsx14("a", { href: `tel:${text.replace(/[^\d+]/g, "")}`, className: LINK, onClick: own2, title: text, children: /* @__PURE__ */ jsx14("span", { className: "truncate tabular-nums", children: formatPhone(text) }) });
2777
2823
  case "address":
2778
- return /* @__PURE__ */ jsx13(
2824
+ return /* @__PURE__ */ jsx14(
2779
2825
  "a",
2780
2826
  {
2781
2827
  href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(text)}`,
@@ -2784,7 +2830,7 @@ function rich(id, text, raw, format) {
2784
2830
  className: LINK,
2785
2831
  title: "Open in maps",
2786
2832
  onClick: own2,
2787
- children: /* @__PURE__ */ jsx13("span", { className: "truncate", children: text })
2833
+ children: /* @__PURE__ */ jsx14("span", { className: "truncate", children: text })
2788
2834
  }
2789
2835
  );
2790
2836
  case "progress": {
@@ -2792,8 +2838,8 @@ function rich(id, text, raw, format) {
2792
2838
  if (n === null) return void 0;
2793
2839
  const pct = format.options?.percentScale === "fraction" ? n * 100 : n;
2794
2840
  const clamped = Math.max(0, Math.min(100, pct));
2795
- return /* @__PURE__ */ jsxs11("span", { className: "inline-flex w-full min-w-0 items-center gap-2", title: text, children: [
2796
- /* @__PURE__ */ jsx13(
2841
+ return /* @__PURE__ */ jsxs12("span", { className: "inline-flex w-full min-w-0 items-center gap-2", title: text, children: [
2842
+ /* @__PURE__ */ jsx14(
2797
2843
  "span",
2798
2844
  {
2799
2845
  role: "progressbar",
@@ -2801,24 +2847,24 @@ function rich(id, text, raw, format) {
2801
2847
  "aria-valuemax": 100,
2802
2848
  "aria-valuenow": Math.round(clamped),
2803
2849
  className: "h-1.5 min-w-8 flex-1 overflow-hidden rounded-full bg-muted",
2804
- children: /* @__PURE__ */ jsx13("span", { className: cn10("block h-full rounded-full", pct >= 100 ? "bg-emerald-500" : "bg-primary"), style: { width: `${clamped}%` } })
2850
+ children: /* @__PURE__ */ jsx14("span", { className: cn11("block h-full rounded-full", pct >= 100 ? "bg-emerald-500" : "bg-primary"), style: { width: `${clamped}%` } })
2805
2851
  }
2806
2852
  ),
2807
- /* @__PURE__ */ jsx13("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: text })
2853
+ /* @__PURE__ */ jsx14("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: text })
2808
2854
  ] });
2809
2855
  }
2810
2856
  case "color":
2811
- return /* @__PURE__ */ jsxs11("span", { className: "inline-flex items-center gap-1.5", children: [
2812
- /* @__PURE__ */ jsx13("span", { className: "h-4 w-4 shrink-0 rounded border border-border", style: { backgroundColor: text } }),
2813
- /* @__PURE__ */ jsx13("code", { className: "font-mono text-xs", children: text })
2857
+ return /* @__PURE__ */ jsxs12("span", { className: "inline-flex items-center gap-1.5", children: [
2858
+ /* @__PURE__ */ jsx14("span", { className: "h-4 w-4 shrink-0 rounded border border-border", style: { backgroundColor: text } }),
2859
+ /* @__PURE__ */ jsx14("code", { className: "font-mono text-xs", children: text })
2814
2860
  ] });
2815
2861
  case "tags": {
2816
2862
  const items = Array.isArray(raw) ? raw.map(String) : text.split(",").map((s) => s.trim()).filter(Boolean);
2817
2863
  if (items.length === 0) return void 0;
2818
- return /* @__PURE__ */ jsx13("span", { className: "flex flex-wrap items-center gap-1", children: items.map((item, i) => /* @__PURE__ */ jsx13("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}`)) });
2864
+ return /* @__PURE__ */ jsx14("span", { className: "flex flex-wrap items-center gap-1", children: items.map((item, i) => /* @__PURE__ */ jsx14("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}`)) });
2819
2865
  }
2820
2866
  case "rating":
2821
- return numberOf(raw) === null ? void 0 : /* @__PURE__ */ jsx13(RatingStars, { value: raw, max: format.options?.ratingMax ?? 5 });
2867
+ return numberOf(raw) === null ? void 0 : /* @__PURE__ */ jsx14(RatingStars, { value: raw, max: format.options?.ratingMax ?? 5 });
2822
2868
  default:
2823
2869
  return void 0;
2824
2870
  }
@@ -2833,11 +2879,11 @@ function FormattedValue({
2833
2879
  const score = numberOf(value);
2834
2880
  const max = format.options?.ratingMax ?? 5;
2835
2881
  if (def?.id === "rating" && onRate && (value === null || value === void 0 || value === "" || score !== null && score >= 0 && score <= max)) {
2836
- return /* @__PURE__ */ jsx13(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
2882
+ return /* @__PURE__ */ jsx14(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
2837
2883
  }
2838
2884
  const result = formatFieldValue2(value, format);
2839
- if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ jsx13(FormattedCell, { result });
2840
- return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ jsx13(FormattedCell, { result });
2885
+ if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ jsx14(FormattedCell, { result });
2886
+ return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ jsx14(FormattedCell, { result });
2841
2887
  }
2842
2888
  function linkChipText(raw) {
2843
2889
  try {
@@ -2851,7 +2897,7 @@ function linkChipText(raw) {
2851
2897
  }
2852
2898
 
2853
2899
  // src/formatControls.tsx
2854
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2900
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2855
2901
  var TYPED_NUMBERS = /* @__PURE__ */ new Set(["currency", "percent", "progress", "decimal", "duration", "file_size", "integer"]);
2856
2902
  function scaled(format) {
2857
2903
  return (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction";
@@ -2874,7 +2920,7 @@ function NumberInFormat({ format, value, onChange, disabled, id }) {
2874
2920
  if (value === lastSent.current) return;
2875
2921
  setText(typedText(format, value));
2876
2922
  }, [value, format]);
2877
- return /* @__PURE__ */ jsx14(
2923
+ return /* @__PURE__ */ jsx15(
2878
2924
  BasicInput4,
2879
2925
  {
2880
2926
  id,
@@ -2899,16 +2945,16 @@ function formatControl(args) {
2899
2945
  const text = value === null || value === void 0 ? "" : String(value);
2900
2946
  const commit = (raw) => onChange(raw === "" ? null : parseFieldInput(raw, format));
2901
2947
  if (def.id === "rating") {
2902
- return disabled ? /* @__PURE__ */ jsx14(RatingStars, { value, max: format.options?.ratingMax ?? 5, label }) : /* @__PURE__ */ jsx14("span", { id, className: "inline-flex", children: /* @__PURE__ */ jsx14(RatingStars, { value, max: format.options?.ratingMax ?? 5, label, onRate: (n) => onChange(n) }) });
2948
+ return disabled ? /* @__PURE__ */ jsx15(RatingStars, { value, max: format.options?.ratingMax ?? 5, label }) : /* @__PURE__ */ jsx15("span", { id, className: "inline-flex", children: /* @__PURE__ */ jsx15(RatingStars, { value, max: format.options?.ratingMax ?? 5, label, onRate: (n) => onChange(n) }) });
2903
2949
  }
2904
- if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ jsx14(NumberInFormat, { ...args });
2950
+ if (TYPED_NUMBERS.has(def.id)) return /* @__PURE__ */ jsx15(NumberInFormat, { ...args });
2905
2951
  switch (def.editor) {
2906
2952
  // A TIME OF DAY is not this file's: `FieldControl` draws the typed box and its helper
2907
2953
  // (`TypedWordsControl`), never the browser's time control (grids review 3, 2026-09-30).
2908
2954
  case "email":
2909
2955
  case "url":
2910
2956
  case "tel":
2911
- return /* @__PURE__ */ jsx14(
2957
+ return /* @__PURE__ */ jsx15(
2912
2958
  BasicInput4,
2913
2959
  {
2914
2960
  id,
@@ -2920,8 +2966,8 @@ function formatControl(args) {
2920
2966
  }
2921
2967
  );
2922
2968
  case "color":
2923
- return /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-2", children: [
2924
- /* @__PURE__ */ jsx14(
2969
+ return /* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-2", children: [
2970
+ /* @__PURE__ */ jsx15(
2925
2971
  BasicInput4,
2926
2972
  {
2927
2973
  id: `${id}-swatch`,
@@ -2933,10 +2979,10 @@ function formatControl(args) {
2933
2979
  onChange: (e) => commit(e.target.value)
2934
2980
  }
2935
2981
  ),
2936
- /* @__PURE__ */ jsx14(BasicInput4, { id, value: text, placeholder: "#3b82f6", disabled, onChange: (e) => commit(e.target.value) })
2982
+ /* @__PURE__ */ jsx15(BasicInput4, { id, value: text, placeholder: "#3b82f6", disabled, onChange: (e) => commit(e.target.value) })
2937
2983
  ] });
2938
2984
  case "textarea":
2939
- return /* @__PURE__ */ jsx14(BasicTextarea, { id, rows: 4, value: text, disabled, onChange: (e) => commit(e.target.value) });
2985
+ return /* @__PURE__ */ jsx15(BasicTextarea, { id, rows: 4, value: text, disabled, onChange: (e) => commit(e.target.value) });
2940
2986
  default:
2941
2987
  return null;
2942
2988
  }
@@ -2944,9 +2990,9 @@ function formatControl(args) {
2944
2990
 
2945
2991
  // src/typedDateHelper.tsx
2946
2992
  import { useState as useState12 } from "react";
2947
- import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2, cn as cn11 } from "@ai-matrx/design-system";
2993
+ import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2, cn as cn12 } from "@ai-matrx/design-system";
2948
2994
  import { readTypedDate, readTypedTime, typedDateText, typedTimeText } from "@ai-matrx/records";
2949
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2995
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2950
2996
  var WEEK = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
2951
2997
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
2952
2998
  function pad(n) {
@@ -2975,15 +3021,15 @@ function wordsFor(kind, day, time) {
2975
3021
  }
2976
3022
  var keepFocus = { onMouseDown: (e) => e.preventDefault(), tabIndex: -1 };
2977
3023
  function CalendarGlyph() {
2978
- return /* @__PURE__ */ jsxs13("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2979
- /* @__PURE__ */ jsx15("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
2980
- /* @__PURE__ */ jsx15("path", { d: "M16 2v4M8 2v4M3 10h18" })
3024
+ return /* @__PURE__ */ jsxs14("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3025
+ /* @__PURE__ */ jsx16("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
3026
+ /* @__PURE__ */ jsx16("path", { d: "M16 2v4M8 2v4M3 10h18" })
2981
3027
  ] });
2982
3028
  }
2983
3029
  function ClockGlyph() {
2984
- return /* @__PURE__ */ jsxs13("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2985
- /* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "10" }),
2986
- /* @__PURE__ */ jsx15("path", { d: "M12 6v6l4 2" })
3030
+ return /* @__PURE__ */ jsxs14("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
3031
+ /* @__PURE__ */ jsx16("circle", { cx: "12", cy: "12", r: "10" }),
3032
+ /* @__PURE__ */ jsx16("path", { d: "M12 6v6l4 2" })
2987
3033
  ] });
2988
3034
  }
2989
3035
  function TypedDateHelper({ kind, text, onText, label }) {
@@ -3012,8 +3058,8 @@ function TypedDateHelper({ kind, text, onText, label }) {
3012
3058
  const at = new Date(shown2.y, shown2.m + by, 1);
3013
3059
  setMonth({ y: at.getFullYear(), m: at.getMonth() });
3014
3060
  };
3015
- return /* @__PURE__ */ jsxs13(Popover2, { open, onOpenChange: setOpen, children: [
3016
- /* @__PURE__ */ jsx15(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx15(
3061
+ return /* @__PURE__ */ jsxs14(Popover2, { open, onOpenChange: setOpen, children: [
3062
+ /* @__PURE__ */ jsx16(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx16(
3017
3063
  "button",
3018
3064
  {
3019
3065
  type: "button",
@@ -3022,10 +3068,10 @@ function TypedDateHelper({ kind, text, onText, label }) {
3022
3068
  "aria-label": kind === "time" ? `Pick a time for ${label}` : `Pick a date for ${label}`,
3023
3069
  title: kind === "time" ? "Pick a time" : "Pick a date",
3024
3070
  className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
3025
- children: kind === "time" ? /* @__PURE__ */ jsx15(ClockGlyph, {}) : /* @__PURE__ */ jsx15(CalendarGlyph, {})
3071
+ children: kind === "time" ? /* @__PURE__ */ jsx16(ClockGlyph, {}) : /* @__PURE__ */ jsx16(CalendarGlyph, {})
3026
3072
  }
3027
3073
  ) }),
3028
- /* @__PURE__ */ jsx15(
3074
+ /* @__PURE__ */ jsx16(
3029
3075
  PopoverContent2,
3030
3076
  {
3031
3077
  sizing: "content",
@@ -3035,29 +3081,29 @@ function TypedDateHelper({ kind, text, onText, label }) {
3035
3081
  "data-records-date-helper-panel": "",
3036
3082
  onOpenAutoFocus: (e) => e.preventDefault(),
3037
3083
  onCloseAutoFocus: (e) => e.preventDefault(),
3038
- children: /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
3039
- kind === "time" ? null : /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1", role: "grid", "aria-label": `${MONTHS[shown2.m]} ${shown2.y}`, children: [
3040
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between text-xs font-medium", children: [
3041
- /* @__PURE__ */ jsx15("button", { type: "button", ...keepFocus, "aria-label": "Previous month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(-1), children: "\u2039" }),
3042
- /* @__PURE__ */ jsxs13("span", { children: [
3084
+ children: /* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
3085
+ kind === "time" ? null : /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", role: "grid", "aria-label": `${MONTHS[shown2.m]} ${shown2.y}`, children: [
3086
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between text-xs font-medium", children: [
3087
+ /* @__PURE__ */ jsx16("button", { type: "button", ...keepFocus, "aria-label": "Previous month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(-1), children: "\u2039" }),
3088
+ /* @__PURE__ */ jsxs14("span", { children: [
3043
3089
  MONTHS[shown2.m],
3044
3090
  " ",
3045
3091
  shown2.y
3046
3092
  ] }),
3047
- /* @__PURE__ */ jsx15("button", { type: "button", ...keepFocus, "aria-label": "Next month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(1), children: "\u203A" })
3093
+ /* @__PURE__ */ jsx16("button", { type: "button", ...keepFocus, "aria-label": "Next month", className: "rounded px-1.5 hover:bg-muted", onClick: () => turn(1), children: "\u203A" })
3048
3094
  ] }),
3049
- /* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-7 gap-0.5 text-center text-[11px]", children: [
3050
- WEEK.map((w) => /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: w }, w)),
3095
+ /* @__PURE__ */ jsxs14("div", { className: "grid grid-cols-7 gap-0.5 text-center text-[11px]", children: [
3096
+ WEEK.map((w) => /* @__PURE__ */ jsx16("span", { className: "text-muted-foreground", children: w }, w)),
3051
3097
  cells.map((d, i) => {
3052
- if (d === null) return /* @__PURE__ */ jsx15("span", {}, `blank-${i}`);
3098
+ if (d === null) return /* @__PURE__ */ jsx16("span", {}, `blank-${i}`);
3053
3099
  const key = `${shown2.y}-${pad(shown2.m + 1)}-${pad(d)}`;
3054
- return /* @__PURE__ */ jsx15(
3100
+ return /* @__PURE__ */ jsx16(
3055
3101
  "button",
3056
3102
  {
3057
3103
  type: "button",
3058
3104
  ...keepFocus,
3059
3105
  "data-records-date-helper-day": key,
3060
- className: cn11(
3106
+ className: cn12(
3061
3107
  "h-6 w-6 rounded tabular-nums hover:bg-muted",
3062
3108
  key === held.day ? "bg-primary text-primary-foreground hover:bg-primary" : "",
3063
3109
  key === todayKey && key !== held.day ? "ring-1 ring-ring" : ""
@@ -3070,13 +3116,13 @@ function TypedDateHelper({ kind, text, onText, label }) {
3070
3116
  })
3071
3117
  ] })
3072
3118
  ] }),
3073
- kind === "date" ? null : /* @__PURE__ */ jsx15("div", { className: "flex max-h-48 flex-col overflow-y-auto pr-1 text-[11px]", "aria-label": "Times", children: times.map((t) => /* @__PURE__ */ jsx15(
3119
+ kind === "date" ? null : /* @__PURE__ */ jsx16("div", { className: "flex max-h-48 flex-col overflow-y-auto pr-1 text-[11px]", "aria-label": "Times", children: times.map((t) => /* @__PURE__ */ jsx16(
3074
3120
  "button",
3075
3121
  {
3076
3122
  type: "button",
3077
3123
  ...keepFocus,
3078
3124
  "data-records-date-helper-time": `${pad(t.h)}:${pad(t.m)}`,
3079
- className: cn11(
3125
+ className: cn12(
3080
3126
  "whitespace-nowrap rounded px-2 py-0.5 text-left tabular-nums hover:bg-muted",
3081
3127
  held.time && held.time.h === t.h && held.time.m === t.m ? "bg-primary text-primary-foreground" : ""
3082
3128
  ),
@@ -3124,7 +3170,7 @@ function useChoiceNudge(enabled = true) {
3124
3170
  }
3125
3171
 
3126
3172
  // src/editors.tsx
3127
- import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3173
+ import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
3128
3174
  var CHOICE_EDITOR_ADDS_WHAT_IS_TYPED = true;
3129
3175
  function isChoiceAddition(value) {
3130
3176
  return typeof value === "object" && value !== null && value.addingChoices === true;
@@ -3154,12 +3200,12 @@ function ChoiceAskButtons({
3154
3200
  onCancel,
3155
3201
  busy
3156
3202
  }) {
3157
- return /* @__PURE__ */ jsxs14("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field, words), className: "flex flex-col gap-1", children: [
3158
- /* @__PURE__ */ jsx16("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field, words) }),
3159
- /* @__PURE__ */ jsxs14("span", { className: "flex flex-wrap items-center gap-1", children: [
3160
- /* @__PURE__ */ jsx16(Button7, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
3161
- keepOffered ? /* @__PURE__ */ jsx16(Button7, { type: "button", size: "sm", variant: "outline", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onKeep, children: "Keep as typed" }) : null,
3162
- /* @__PURE__ */ jsx16(Button7, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onCancel, children: "Cancel" })
3203
+ return /* @__PURE__ */ jsxs15("span", { "data-records-choice-ask": "", role: "group", "aria-label": choiceAskSentence(field, words), className: "flex flex-col gap-1", children: [
3204
+ /* @__PURE__ */ jsx17("span", { className: "text-[11px] leading-snug", children: choiceAskSentence(field, words) }),
3205
+ /* @__PURE__ */ jsxs15("span", { className: "flex flex-wrap items-center gap-1", children: [
3206
+ /* @__PURE__ */ jsx17(Button7, { type: "button", size: "sm", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onAdd, children: "Add" }),
3207
+ keepOffered ? /* @__PURE__ */ jsx17(Button7, { type: "button", size: "sm", variant: "outline", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onKeep, children: "Keep as typed" }) : null,
3208
+ /* @__PURE__ */ jsx17(Button7, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", disabled: busy ?? false, onClick: onCancel, children: "Cancel" })
3163
3209
  ] })
3164
3210
  ] });
3165
3211
  }
@@ -3167,6 +3213,11 @@ var FORMAT_BLIND_KINDS = /* @__PURE__ */ new Set(["formula", "lookup", "rollup",
3167
3213
  function isTypedDraft(value) {
3168
3214
  return typeof value === "object" && value !== null && value.typedDraft === true;
3169
3215
  }
3216
+ var SHORT_REFUSAL = {
3217
+ email: "Enter a valid email",
3218
+ url: "Enter a valid link",
3219
+ phone: "Enter a valid phone number"
3220
+ };
3170
3221
  function judgeTyped(field, text, choices, nudge) {
3171
3222
  const trimmed = text.trim();
3172
3223
  const kind = String(editorKindFor(field));
@@ -3214,9 +3265,14 @@ function judgeTyped(field, text, choices, nudge) {
3214
3265
  const max = format.options?.ratingMax ?? 5;
3215
3266
  return Number.isInteger(n) && n >= 0 && n <= max ? { value: n === 0 ? null : n } : { refusal: `${fieldName(field)} is a rating from 1 to ${max}, and \u201C${text}\u201D is not one.` };
3216
3267
  }
3268
+ if (kind === "phone" || format && format.id === "phone") {
3269
+ const digits = trimmed.replace(/\D/g, "");
3270
+ const usual = /^\+?[\d\s().-]+(\s*(x|ext\.?)\s*\d+)?$/i.test(trimmed);
3271
+ return usual && digits.length >= 7 && digits.length <= 20 ? { value: trimmed } : { refusal: SHORT_REFUSAL.phone };
3272
+ }
3217
3273
  const showsAsPercent = Boolean(format && (format.id === "percent" || format.id === "progress"));
3218
3274
  const read = coerceTypedAnswer(field, text, { label: fieldName(field), showsAsPercent });
3219
- if ("refusal" in read) return { refusal: read.refusal };
3275
+ if ("refusal" in read) return { refusal: kind === "email" || kind === "url" ? SHORT_REFUSAL[kind] : read.refusal };
3220
3276
  if (typeof read.value === "number" && format && (format.id === "percent" || format.id === "progress") && format.options?.percentScale === "fraction") {
3221
3277
  return { value: Math.round(read.value / 100 * 1e9) / 1e9 };
3222
3278
  }
@@ -3269,7 +3325,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
3269
3325
  judged: judgeTyped(field, text, needsChoices ? choices : void 0, needsChoices ? nudge : void 0),
3270
3326
  ...value.openedAs !== void 0 ? { openedAs: value.openedAs } : {}
3271
3327
  });
3272
- const box = /* @__PURE__ */ jsx16(
3328
+ const box = /* @__PURE__ */ jsx17(
3273
3329
  BasicInput5,
3274
3330
  {
3275
3331
  id,
@@ -3281,16 +3337,16 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
3281
3337
  onChange: (e) => retype(e.target.value)
3282
3338
  }
3283
3339
  );
3284
- return /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-0.5", children: [
3285
- helper && !disabled ? /* @__PURE__ */ jsxs14("span", { className: "flex min-w-0 items-center gap-0.5", children: [
3340
+ return /* @__PURE__ */ jsxs15("span", { className: "flex flex-col gap-0.5", children: [
3341
+ helper && !disabled ? /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-0.5", children: [
3286
3342
  box,
3287
- /* @__PURE__ */ jsx16(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field) })
3343
+ /* @__PURE__ */ jsx17(TypedDateHelper, { kind: helper, text: value.text, onText: retype, label: fieldName(field) })
3288
3344
  ] }) : box,
3289
- judged === null ? /* @__PURE__ */ jsxs14("span", { className: "text-[10px] text-muted-foreground", children: [
3345
+ judged === null ? /* @__PURE__ */ jsxs15("span", { className: "text-[10px] text-muted-foreground", children: [
3290
3346
  "Reading ",
3291
3347
  fieldName(field),
3292
3348
  "'s choices\u2026"
3293
- ] }) : "ask" in judged ? /* @__PURE__ */ jsx16(
3349
+ ] }) : "ask" in judged ? /* @__PURE__ */ jsx17(
3294
3350
  ChoiceAskButtons,
3295
3351
  {
3296
3352
  field,
@@ -3306,10 +3362,10 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
3306
3362
  },
3307
3363
  onCancel: () => onCancel?.()
3308
3364
  }
3309
- ) : "refusal" in judged ? /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-1", children: [
3310
- /* @__PURE__ */ jsx16("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
3311
- judged.cancelOnly && onCancel ? /* @__PURE__ */ jsx16("span", { "data-records-choice-ask": "", children: /* @__PURE__ */ jsx16(Button7, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => onCancel(), children: "Cancel" }) }) : null
3312
- ] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ jsxs14("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
3365
+ ) : "refusal" in judged ? /* @__PURE__ */ jsxs15("span", { className: "flex flex-col gap-1", children: [
3366
+ /* @__PURE__ */ jsx17("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: judged.refusal }),
3367
+ judged.cancelOnly && onCancel ? /* @__PURE__ */ jsx17("span", { "data-records-choice-ask": "", children: /* @__PURE__ */ jsx17(Button7, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => onCancel(), children: "Cancel" }) }) : null
3368
+ ] }) : judged.value === null || judged.value === void 0 ? null : /* @__PURE__ */ jsxs15("span", { "data-records-typed-reads-as": "", className: "text-[10px] text-muted-foreground", children: [
3313
3369
  isChoiceAddition(judged.value) ? `Adds ${quoted(judged.value.add)} to the choices for ${fieldName(field)}. ` : null,
3314
3370
  "Reads as",
3315
3371
  " ",
@@ -3320,7 +3376,7 @@ function TypedTextControl({ field, value, onChange, disabled, id, onCommit, onCa
3320
3376
  }).join(", ")
3321
3377
  ) : (() => {
3322
3378
  const shown2 = format ?? (kind === "datetime" ? { id: carriesTimeOfDay(field, judged.value) ? "datetime" : "date" } : void 0);
3323
- return shown2 ? /* @__PURE__ */ jsx16(FormattedValue, { value: judged.value, format: shown2 }) : String(judged.value);
3379
+ return shown2 ? /* @__PURE__ */ jsx17(FormattedValue, { value: judged.value, format: shown2 }) : String(judged.value);
3324
3380
  })()
3325
3381
  ] })
3326
3382
  ] });
@@ -3334,12 +3390,12 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3334
3390
  const kind = editorKindFor(field);
3335
3391
  const inputId = id ?? `field-${field.key}`;
3336
3392
  const ownDetails = useOptionalRecordsClient7() === null;
3337
- if (isTypedDraft(value)) return /* @__PURE__ */ jsx16(TypedTextControl, { field, value, onChange, disabled, id: inputId, onCommit, onCancel });
3338
- if (isSignatureField(field)) return /* @__PURE__ */ jsx16(SignaturePad, { id: inputId, value, onChange, disabled });
3393
+ if (isTypedDraft(value)) return /* @__PURE__ */ jsx17(TypedTextControl, { field, value, onChange, disabled, id: inputId, onCommit, onCancel });
3394
+ if (isSignatureField(field)) return /* @__PURE__ */ jsx17(SignaturePad, { id: inputId, value, onChange, disabled });
3339
3395
  const newerControl = newerKindControl({ field, value, onChange, disabled, id: inputId });
3340
3396
  if (newerControl !== void 0) return newerControl;
3341
3397
  const format = formatForField(field);
3342
- if (format && format.id === "time") return /* @__PURE__ */ jsx16(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
3398
+ if (format && format.id === "time") return /* @__PURE__ */ jsx17(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
3343
3399
  if (format && !FORMAT_BLIND_KINDS.has(String(kind))) {
3344
3400
  const own3 = formatControl({ format, value, onChange, disabled, id: inputId, label: fieldName(field), ownDetails });
3345
3401
  if (own3) return own3;
@@ -3348,17 +3404,17 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3348
3404
  case "formula":
3349
3405
  case "lookup":
3350
3406
  case "rollup":
3351
- return /* @__PURE__ */ jsxs14("div", { id: inputId, className: "rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground", children: [
3407
+ return /* @__PURE__ */ jsxs15("div", { id: inputId, className: "rounded border border-dashed px-2 py-1.5 text-xs text-muted-foreground", children: [
3352
3408
  value === null || value === void 0 ? "\u2014" : String(value),
3353
- /* @__PURE__ */ jsxs14("span", { className: "ml-2 italic", children: [
3409
+ /* @__PURE__ */ jsxs15("span", { className: "ml-2 italic", children: [
3354
3410
  fieldName(field),
3355
3411
  " is worked out by the system, so it cannot be typed in"
3356
3412
  ] })
3357
3413
  ] });
3358
3414
  case "json":
3359
- return /* @__PURE__ */ jsx16(JsonControl, { field, value, onChange, disabled, id: inputId });
3415
+ return /* @__PURE__ */ jsx17(JsonControl, { field, value, onChange, disabled, id: inputId });
3360
3416
  case "long_text":
3361
- return /* @__PURE__ */ jsx16(
3417
+ return /* @__PURE__ */ jsx17(
3362
3418
  BasicTextarea2,
3363
3419
  {
3364
3420
  id: inputId,
@@ -3371,7 +3427,7 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3371
3427
  case "number":
3372
3428
  case "currency":
3373
3429
  case "percent":
3374
- return /* @__PURE__ */ jsx16(
3430
+ return /* @__PURE__ */ jsx17(
3375
3431
  BasicInput5,
3376
3432
  {
3377
3433
  id: inputId,
@@ -3384,11 +3440,11 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3384
3440
  }
3385
3441
  );
3386
3442
  case "datetime":
3387
- return /* @__PURE__ */ jsx16(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
3443
+ return /* @__PURE__ */ jsx17(TypedWordsControl, { field, value, onChange, disabled, id: inputId });
3388
3444
  case "email":
3389
3445
  case "phone":
3390
3446
  case "url":
3391
- return /* @__PURE__ */ jsx16(
3447
+ return /* @__PURE__ */ jsx17(
3392
3448
  BasicInput5,
3393
3449
  {
3394
3450
  id: inputId,
@@ -3400,24 +3456,24 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3400
3456
  }
3401
3457
  );
3402
3458
  case "checkbox":
3403
- return /* @__PURE__ */ jsx16(CheckboxControl, { field, value, onChange, disabled, id: inputId });
3459
+ return /* @__PURE__ */ jsx17(CheckboxControl, { field, value, onChange, disabled, id: inputId });
3404
3460
  case "select":
3405
3461
  case "multi_select":
3406
- return /* @__PURE__ */ jsx16(OptionControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
3462
+ return /* @__PURE__ */ jsx17(OptionControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, addsChoices, initialSearch, asForm });
3407
3463
  case "member":
3408
- return /* @__PURE__ */ jsx16(PersonPicker, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
3464
+ return /* @__PURE__ */ jsx17(PersonPicker, { field, value, onChange, disabled, id: inputId, autoOpen, onClose, initialSearch });
3409
3465
  case "entity_reference":
3410
- return /* @__PURE__ */ jsx16(EntityReferenceControl, { field, value, onChange, disabled, id: inputId });
3466
+ return /* @__PURE__ */ jsx17(EntityReferenceControl, { field, value, onChange, disabled, id: inputId });
3411
3467
  case "attachment":
3412
3468
  if (hostTakesFiles(host)) {
3413
- return /* @__PURE__ */ jsx16(AttachmentControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose });
3469
+ return /* @__PURE__ */ jsx17(AttachmentControl, { field, value, onChange, disabled, id: inputId, autoOpen, onClose });
3414
3470
  }
3415
- return /* @__PURE__ */ jsx16(RelationPicker, { field, value, onChange, disabled, id: inputId });
3471
+ return /* @__PURE__ */ jsx17(RelationPicker, { field, value, onChange, disabled, id: inputId });
3416
3472
  case "relation":
3417
- return /* @__PURE__ */ jsx16(RelationPicker, { field, value, onChange, disabled, id: inputId, onPicked: onCommit, autoOpen, onClose });
3473
+ return /* @__PURE__ */ jsx17(RelationPicker, { field, value, onChange, disabled, id: inputId, onPicked: onCommit, autoOpen, onClose });
3418
3474
  default:
3419
3475
  if (typeof value === "boolean" || field.config?.["kind"] === "boolean") {
3420
- return /* @__PURE__ */ jsx16(
3476
+ return /* @__PURE__ */ jsx17(
3421
3477
  Checkbox,
3422
3478
  {
3423
3479
  id: inputId,
@@ -3427,7 +3483,7 @@ function FieldControl({ field, value, onChange, disabled, id, autoOpen, onClose,
3427
3483
  }
3428
3484
  );
3429
3485
  }
3430
- return /* @__PURE__ */ jsx16(
3486
+ return /* @__PURE__ */ jsx17(
3431
3487
  BasicInput5,
3432
3488
  {
3433
3489
  id: inputId,
@@ -3461,9 +3517,9 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
3461
3517
  setRefusal(judged.refusal);
3462
3518
  }
3463
3519
  };
3464
- return /* @__PURE__ */ jsxs14("span", { className: "flex flex-col gap-0.5", children: [
3465
- /* @__PURE__ */ jsxs14("span", { className: "flex min-w-0 items-center gap-0.5", children: [
3466
- /* @__PURE__ */ jsx16(
3520
+ return /* @__PURE__ */ jsxs15("span", { className: "flex flex-col gap-0.5", children: [
3521
+ /* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-0.5", children: [
3522
+ /* @__PURE__ */ jsx17(
3467
3523
  BasicInput5,
3468
3524
  {
3469
3525
  id,
@@ -3480,15 +3536,15 @@ function TypedWordsControl({ field, value, onChange, disabled, id }) {
3480
3536
  }
3481
3537
  }
3482
3538
  ),
3483
- helper && !disabled ? /* @__PURE__ */ jsx16(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field) }) : null
3539
+ helper && !disabled ? /* @__PURE__ */ jsx17(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field) }) : null
3484
3540
  ] }),
3485
- refusal2 ? /* @__PURE__ */ jsx16("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal2 }) : null
3541
+ refusal2 ? /* @__PURE__ */ jsx17("span", { "data-records-typed-refusal": "", role: "status", className: "text-[11px] leading-snug text-amber-700 dark:text-amber-400", children: refusal2 }) : null
3486
3542
  ] });
3487
3543
  }
3488
3544
  function CheckboxControl({ field, value, onChange, disabled, id }) {
3489
3545
  const unanswered = value === null || value === void 0;
3490
- return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
3491
- /* @__PURE__ */ jsx16(
3546
+ return /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
3547
+ /* @__PURE__ */ jsx17(
3492
3548
  Checkbox,
3493
3549
  {
3494
3550
  id,
@@ -3498,9 +3554,9 @@ function CheckboxControl({ field, value, onChange, disabled, id }) {
3498
3554
  onCheckedChange: (next) => onChange(next === true)
3499
3555
  }
3500
3556
  ),
3501
- unanswered ? /* @__PURE__ */ jsx16("span", { className: "text-xs italic text-muted-foreground", children: "not answered yet" }) : /* @__PURE__ */ jsxs14(Fragment5, { children: [
3502
- /* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground", children: value === true ? "Yes" : "No" }),
3503
- field.required ? null : /* @__PURE__ */ jsx16(
3557
+ unanswered ? /* @__PURE__ */ jsx17("span", { className: "text-xs italic text-muted-foreground", children: "not answered yet" }) : /* @__PURE__ */ jsxs15(Fragment5, { children: [
3558
+ /* @__PURE__ */ jsx17("span", { className: "text-xs text-muted-foreground", children: value === true ? "Yes" : "No" }),
3559
+ field.required ? null : /* @__PURE__ */ jsx17(
3504
3560
  Button7,
3505
3561
  {
3506
3562
  size: "sm",
@@ -3518,8 +3574,8 @@ function JsonControl({ field, value, onChange, disabled, id }) {
3518
3574
  const initial = value === null || value === void 0 ? "" : typeof value === "string" ? value : JSON.stringify(value, null, 2);
3519
3575
  const [text, setText] = useState14(initial);
3520
3576
  const [broken, setBroken] = useState14(null);
3521
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
3522
- /* @__PURE__ */ jsx16(
3577
+ return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
3578
+ /* @__PURE__ */ jsx17(
3523
3579
  BasicTextarea2,
3524
3580
  {
3525
3581
  id,
@@ -3553,7 +3609,7 @@ function JsonControl({ field, value, onChange, disabled, id }) {
3553
3609
  ),
3554
3610
  broken ? (
3555
3611
  // The typed text is still in the box: the notice owns the two doors out.
3556
- /* @__PURE__ */ jsx16(
3612
+ /* @__PURE__ */ jsx17(
3557
3613
  RefusalNotice,
3558
3614
  {
3559
3615
  error: broken,
@@ -3595,11 +3651,11 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3595
3651
  }, [client, field.id, reread]);
3596
3652
  const handed = publicChoicesOf(field);
3597
3653
  if (!client && handed.length > 0) {
3598
- return /* @__PURE__ */ jsx16(ChoiceAnswer, { field, choices: handed, value, onChange, disabled, id });
3654
+ return /* @__PURE__ */ jsx17(ChoiceAnswer, { field, choices: handed, value, onChange, disabled, id });
3599
3655
  }
3600
3656
  if (!client) {
3601
- return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
3602
- /* @__PURE__ */ jsx16(
3657
+ return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
3658
+ /* @__PURE__ */ jsx17(
3603
3659
  BasicInput5,
3604
3660
  {
3605
3661
  id,
@@ -3608,15 +3664,15 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3608
3664
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value)
3609
3665
  }
3610
3666
  ),
3611
- /* @__PURE__ */ jsx16("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." })
3667
+ /* @__PURE__ */ jsx17("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." })
3612
3668
  ] });
3613
3669
  }
3614
3670
  if (refusal2)
3615
- return /* @__PURE__ */ jsx16("div", { id, children: /* @__PURE__ */ jsx16(RefusalLine, { error: refusal2 }) });
3616
- if (!options) return /* @__PURE__ */ jsx16("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
3671
+ return /* @__PURE__ */ jsx17("div", { id, children: /* @__PURE__ */ jsx17(RefusalLine, { error: refusal2 }) });
3672
+ if (!options) return /* @__PURE__ */ jsx17("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
3617
3673
  if (asForm && options.length > 0) {
3618
3674
  const titled = (option) => recordName(option.data, null, "Unnamed choice");
3619
- return /* @__PURE__ */ jsx16(
3675
+ return /* @__PURE__ */ jsx17(
3620
3676
  ChoiceAnswer,
3621
3677
  {
3622
3678
  field,
@@ -3633,7 +3689,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3633
3689
  );
3634
3690
  }
3635
3691
  if (CHOICE_EDITOR_ADDS_WHAT_IS_TYPED) {
3636
- return /* @__PURE__ */ jsx16(
3692
+ return /* @__PURE__ */ jsx17(
3637
3693
  OpenChoicePicker,
3638
3694
  {
3639
3695
  field,
@@ -3655,13 +3711,13 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3655
3711
  );
3656
3712
  }
3657
3713
  if (options.length === 0) {
3658
- return /* @__PURE__ */ jsx16("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.` });
3714
+ return /* @__PURE__ */ jsx17("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.` });
3659
3715
  }
3660
3716
  const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
3661
3717
  if (field.multi) {
3662
3718
  const chosen = options.filter((option) => choiceValuesOf(value).some((v) => isTheChosen(option, v)));
3663
3719
  const picked = new Set(chosen.map((option) => optionKey2(option)));
3664
- const toggles = /* @__PURE__ */ jsx16("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ jsx16(
3720
+ const toggles = /* @__PURE__ */ jsx17("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ jsx17(
3665
3721
  Button7,
3666
3722
  {
3667
3723
  type: "button",
@@ -3679,7 +3735,7 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3679
3735
  option.id
3680
3736
  )) });
3681
3737
  if (!autoOpen) return toggles;
3682
- return /* @__PURE__ */ jsxs14(
3738
+ return /* @__PURE__ */ jsxs15(
3683
3739
  Popover3,
3684
3740
  {
3685
3741
  defaultOpen: true,
@@ -3687,14 +3743,14 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3687
3743
  if (!open) onClose?.();
3688
3744
  },
3689
3745
  children: [
3690
- /* @__PURE__ */ jsx16(PopoverTrigger3, { asChild: true, children: /* @__PURE__ */ jsx16(Button7, { id, type: "button", size: "sm", variant: "outline", className: "h-6 max-w-full truncate", children: chosen.length === 0 ? "Choose" : chosen.map(titleOf).join(", ") }) }),
3691
- /* @__PURE__ */ jsx16(PopoverContent3, { sizing: "content", className: "max-w-[20rem] p-2", align: "start", children: toggles })
3746
+ /* @__PURE__ */ jsx17(PopoverTrigger3, { asChild: true, children: /* @__PURE__ */ jsx17(Button7, { id, type: "button", size: "sm", variant: "outline", className: "h-6 max-w-full truncate", children: chosen.length === 0 ? "Choose" : chosen.map(titleOf).join(", ") }) }),
3747
+ /* @__PURE__ */ jsx17(PopoverContent3, { sizing: "content", className: "max-w-[20rem] p-2", align: "start", children: toggles })
3692
3748
  ]
3693
3749
  }
3694
3750
  );
3695
3751
  }
3696
3752
  const current = options.find((option) => isTheChosen(option, value));
3697
- return /* @__PURE__ */ jsxs14(
3753
+ return /* @__PURE__ */ jsxs15(
3698
3754
  Select2,
3699
3755
  {
3700
3756
  value: current ? optionKey2(current) : "",
@@ -3708,8 +3764,8 @@ function OptionControl({ field, value, onChange, disabled, id, autoOpen, onClose
3708
3764
  }
3709
3765
  } : {},
3710
3766
  children: [
3711
- /* @__PURE__ */ jsx16(SelectTrigger2, { id, size: "sm", children: /* @__PURE__ */ jsx16(SelectValue2, { placeholder: "Choose" }) }),
3712
- /* @__PURE__ */ jsx16(SelectContent2, { children: options.map((option) => /* @__PURE__ */ jsx16(SelectItem2, { value: optionKey2(option), children: titleOf(option) }, option.id)) })
3767
+ /* @__PURE__ */ jsx17(SelectTrigger2, { id, size: "sm", children: /* @__PURE__ */ jsx17(SelectValue2, { placeholder: "Choose" }) }),
3768
+ /* @__PURE__ */ jsx17(SelectContent2, { children: options.map((option) => /* @__PURE__ */ jsx17(SelectItem2, { value: optionKey2(option), children: titleOf(option) }, option.id)) })
3713
3769
  ]
3714
3770
  }
3715
3771
  );
@@ -3791,29 +3847,14 @@ function OpenChoicePicker({
3791
3847
  });
3792
3848
  };
3793
3849
  const offList = q !== "" && decided.decision !== "chosen" && decided.decision !== "empty";
3794
- const [askingFor, setAskingFor] = useState14(null);
3795
- const asks = offList && decided.decision === "ask" && (visible.length === 0 || askingFor === q);
3796
- const foot = asks ? /* @__PURE__ */ jsx16(
3797
- ChoiceAskButtons,
3798
- {
3799
- field,
3800
- words: [q],
3801
- keepOffered: decided.keepOffered,
3802
- busy: adding,
3803
- onAdd: addTyped,
3804
- onKeep: () => choose(q),
3805
- onCancel: () => {
3806
- setSearch("");
3807
- setAddRefused(null);
3808
- if (autoOpen) setOpen(false);
3809
- }
3810
- }
3811
- ) : null;
3812
- const add = offList && decided.decision === "ask" && !asks ? { label: `Add \u201C${q}\u201D\u2026`, onAdd: () => setAskingFor(q) } : 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;
3850
+ const nothingMatches = q !== "" && visible.length === 0;
3851
+ const foot = null;
3852
+ const add = offList && (decided.decision === "ask" || decided.decision === "add") ? { label: `Create \u201C${q}\u201D`, onAdd: addTyped, disabled: adding } : offList && decided.decision === "keep_as_typed" ? { label: `Use \u201C${q}\u201D`, onAdd: () => choose(q) } : null;
3853
+ const listed = nothingMatches && add ? options : visible;
3813
3854
  const pickedOptions = current.map((v) => options.find((o) => isTheChosen(o, v)));
3814
3855
  const cellChips = pickedWords.map((word, i) => {
3815
3856
  const chip = chipOf(pickedOptions[i], word);
3816
- return /* @__PURE__ */ jsx16(Badge3, { variant: "outline", className: cn12("text-[11px]", chip.className), "data-records-choice-chip": "", children: word }, word);
3857
+ return /* @__PURE__ */ jsx17(Badge3, { variant: "outline", className: cn13("text-[11px]", chip.className), "data-records-choice-chip": "", children: word }, word);
3817
3858
  });
3818
3859
  const headChips = pickedWords.map((word, i) => {
3819
3860
  const option = pickedOptions[i];
@@ -3828,12 +3869,12 @@ function OpenChoicePicker({
3828
3869
  };
3829
3870
  });
3830
3871
  const anchored = autoOpen === true;
3831
- return /* @__PURE__ */ jsxs14("div", { id, className: "flex flex-wrap items-center gap-1", children: [
3872
+ return /* @__PURE__ */ jsxs15("div", { id, className: "flex flex-wrap items-center gap-1", children: [
3832
3873
  anchored || disabled ? null : cellChips,
3833
3874
  disabled ? cellChips : (
3834
3875
  // THE ONE "PICK OR ADD" BUILDER (PickOrAdd.tsx) — the relation picker draws the same one.
3835
3876
  // In a grid cell it hangs from the cell's own chips; no button is drawn in the cell.
3836
- /* @__PURE__ */ jsx16(
3877
+ /* @__PURE__ */ jsx17(
3837
3878
  PickOrAdd,
3838
3879
  {
3839
3880
  anchored,
@@ -3847,9 +3888,9 @@ function OpenChoicePicker({
3847
3888
  onSearch: (next) => {
3848
3889
  setSearch(next);
3849
3890
  setAddRefused(null);
3850
- setAskingFor(null);
3851
3891
  },
3852
- items: visible.map((option) => ({
3892
+ addFirst: nothingMatches,
3893
+ items: listed.map((option) => ({
3853
3894
  id: option.id,
3854
3895
  label: titleOf(option),
3855
3896
  chip: chipOf(option, titleOf(option)).className,
@@ -3859,15 +3900,14 @@ function OpenChoicePicker({
3859
3900
  const option = options.find((o) => o.id === optionId);
3860
3901
  if (option) choose(optionKey2(option));
3861
3902
  },
3862
- empty: q === "" ? /* @__PURE__ */ jsx16("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
3903
+ empty: q === "" ? /* @__PURE__ */ jsx17("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
3863
3904
  add,
3864
3905
  foot,
3865
- ...asks && !adding ? { onEnterWithNoMatch: addTyped } : {},
3866
- footNote: addRefused ? /* @__PURE__ */ jsx16(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
3906
+ footNote: addRefused ? /* @__PURE__ */ jsx17(RefusalLine, { error: addRefused }) : offList && decided.decision === "not_a_choice" ? (
3867
3907
  // never_add on a column that takes only its choices: said, never a silent nothing.
3868
- /* @__PURE__ */ jsxs14(Fragment5, { children: [
3869
- /* @__PURE__ */ jsx16("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field, [q]) }),
3870
- autoOpen ? /* @__PURE__ */ jsx16("span", { "data-records-choice-ask": "", className: "px-2 pb-1", children: /* @__PURE__ */ jsx16(Button7, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => setOpen(false), children: "Cancel" }) }) : null
3908
+ /* @__PURE__ */ jsxs15(Fragment5, { children: [
3909
+ /* @__PURE__ */ jsx17("p", { "data-records-typed-refusal": "", className: "p-2 text-xs text-muted-foreground", children: notAChoiceSentence(field, [q]) }),
3910
+ autoOpen ? /* @__PURE__ */ jsx17("span", { "data-records-choice-ask": "", className: "px-2 pb-1", children: /* @__PURE__ */ jsx17(Button7, { type: "button", size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => setOpen(false), children: "Cancel" }) }) : null
3871
3911
  ] })
3872
3912
  ) : null,
3873
3913
  children: anchored ? cellChips : null
@@ -3887,9 +3927,9 @@ function RecordChip({
3887
3927
  // name. So it caps at its container and ends in an ellipsis with the whole name in
3888
3928
  // its tooltip, rather than being cut mid-word by whatever box it landed in
3889
3929
  // (lane FIX-14, 2026-09-22).
3890
- /* @__PURE__ */ jsxs14(Badge3, { variant: "secondary", className: cn12("max-w-full gap-1 text-[11px]", className), title, children: [
3891
- /* @__PURE__ */ jsx16("span", { className: "min-w-0 truncate", children: title }),
3892
- onRemove ? /* @__PURE__ */ jsx16("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${title}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
3930
+ /* @__PURE__ */ jsxs15(Badge3, { variant: "secondary", className: cn13("max-w-full gap-1 text-[11px]", className), title, children: [
3931
+ /* @__PURE__ */ jsx17("span", { className: "min-w-0 truncate", children: title }),
3932
+ onRemove ? /* @__PURE__ */ jsx17("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${title}`, className: "shrink-0 opacity-60 hover:opacity-100", children: "\xD7" }) : null
3893
3933
  ] })
3894
3934
  );
3895
3935
  }
@@ -3927,7 +3967,7 @@ function ChoiceAnswer({
3927
3967
  const option = (choice) => {
3928
3968
  const chosen = on(choice);
3929
3969
  const letter = lettered ? CHOICE_LETTERS[choices.indexOf(choice)] : null;
3930
- return /* @__PURE__ */ jsxs14(
3970
+ return /* @__PURE__ */ jsxs15(
3931
3971
  "button",
3932
3972
  {
3933
3973
  type: "button",
@@ -3937,24 +3977,24 @@ function ChoiceAnswer({
3937
3977
  disabled,
3938
3978
  onClick: () => press(choice),
3939
3979
  "data-records-choice-answer": choice.key,
3940
- className: cn12(
3980
+ className: cn13(
3941
3981
  "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",
3942
3982
  chosen ? "border-primary bg-primary/10" : "border-primary/30 bg-primary/[0.03] hover:bg-primary/10"
3943
3983
  ),
3944
3984
  children: [
3945
- letter ? /* @__PURE__ */ jsx16(
3985
+ letter ? /* @__PURE__ */ jsx17(
3946
3986
  "kbd",
3947
3987
  {
3948
3988
  "aria-hidden": "true",
3949
- className: cn12(
3989
+ className: cn13(
3950
3990
  "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded border font-sans text-xs font-semibold",
3951
3991
  chosen ? "border-primary bg-primary text-primary-foreground" : "border-primary/40 text-primary"
3952
3992
  ),
3953
3993
  children: letter
3954
3994
  }
3955
3995
  ) : null,
3956
- /* @__PURE__ */ jsx16("span", { className: "min-w-0 flex-1 break-words", children: choice.label }),
3957
- chosen ? /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: "shrink-0 text-primary", children: "\u2713" }) : null
3996
+ /* @__PURE__ */ jsx17("span", { className: "min-w-0 flex-1 break-words", children: choice.label }),
3997
+ chosen ? /* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: "shrink-0 text-primary", children: "\u2713" }) : null
3958
3998
  ]
3959
3999
  },
3960
4000
  choice.key
@@ -3970,12 +4010,12 @@ function ChoiceAnswer({
3970
4010
  };
3971
4011
  const group = { role: field.multi ? "group" : "radiogroup", "aria-label": fieldName(field), onKeyDown };
3972
4012
  if (choices.length <= FORM_SEARCH_AFTER) {
3973
- return /* @__PURE__ */ jsx16("div", { id, className: "flex w-full flex-col gap-2", ...group, children: choices.map(option) });
4013
+ return /* @__PURE__ */ jsx17("div", { id, className: "flex w-full flex-col gap-2", ...group, children: choices.map(option) });
3974
4014
  }
3975
4015
  const q = search.trim().toLowerCase();
3976
4016
  const shown2 = q === "" ? choices : choices.filter((c) => c.label.toLowerCase().includes(q));
3977
- return /* @__PURE__ */ jsxs14("div", { id, className: "flex w-full flex-col gap-2", onKeyDown, children: [
3978
- /* @__PURE__ */ jsx16(
4017
+ return /* @__PURE__ */ jsxs15("div", { id, className: "flex w-full flex-col gap-2", onKeyDown, children: [
4018
+ /* @__PURE__ */ jsx17(
3979
4019
  BasicInput5,
3980
4020
  {
3981
4021
  value: search,
@@ -3986,9 +4026,9 @@ function ChoiceAnswer({
3986
4026
  className: "h-11 text-base sm:h-9 sm:text-sm"
3987
4027
  }
3988
4028
  ),
3989
- /* @__PURE__ */ jsxs14("div", { className: "flex max-h-80 w-full flex-col gap-2 overflow-y-auto", role: group.role, "aria-label": group["aria-label"], children: [
4029
+ /* @__PURE__ */ jsxs15("div", { className: "flex max-h-80 w-full flex-col gap-2 overflow-y-auto", role: group.role, "aria-label": group["aria-label"], children: [
3990
4030
  shown2.map(option),
3991
- shown2.length === 0 ? /* @__PURE__ */ jsx16("p", { className: "text-xs text-muted-foreground", children: "No match" }) : null
4031
+ shown2.length === 0 ? /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground", children: "No match" }) : null
3992
4032
  ] })
3993
4033
  ] });
3994
4034
  }
@@ -3996,7 +4036,7 @@ function ChoiceAnswer({
3996
4036
  // src/RecordsMount.tsx
3997
4037
  import { useRef as useRef12 } from "react";
3998
4038
  import { RecordsProvider } from "@ai-matrx/records/react";
3999
- import { jsx as jsx17 } from "react/jsx-runtime";
4039
+ import { jsx as jsx18 } from "react/jsx-runtime";
4000
4040
  function personActor(userId) {
4001
4041
  return userId ? { actor: "user", user_id: userId } : { actor: "user" };
4002
4042
  }
@@ -4005,8 +4045,8 @@ function personActor(userId) {
4005
4045
  import { useCallback as useCallback6, useEffect as useEffect11, useMemo as useMemo6, useState as useState15 } from "react";
4006
4046
  import { withTablePlacement } from "@ai-matrx/records";
4007
4047
  import { useRecordsClient as useRecordsClient2, useTables } from "@ai-matrx/records/react";
4008
- import { Checkbox as Checkbox2, cn as cn13 } from "@ai-matrx/design-system";
4009
- import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
4048
+ import { Checkbox as Checkbox2, cn as cn14 } from "@ai-matrx/design-system";
4049
+ import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
4010
4050
  var APP_TABLE_PREFIX = "records_ui_";
4011
4051
  function isValueSet(table) {
4012
4052
  if (table.kept_for === "choices") return true;
@@ -4049,7 +4089,7 @@ function madeOn(stamp) {
4049
4089
  }
4050
4090
 
4051
4091
  // src/TablePickers.tsx
4052
- import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
4092
+ import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
4053
4093
  var SHARED_FOR_MS = 5e3;
4054
4094
  var sharedReads = /* @__PURE__ */ new WeakMap();
4055
4095
  function readTablesAnywhere(dataSource) {
@@ -4119,16 +4159,16 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
4119
4159
  hint: t.organization_name,
4120
4160
  keywords: t.organization_name,
4121
4161
  ...twin && second ? {
4122
- render: /* @__PURE__ */ jsxs16("span", { className: "flex min-w-0 flex-col", children: [
4123
- /* @__PURE__ */ jsx19("span", { className: "truncate", children: t.table_name }),
4124
- /* @__PURE__ */ jsx19("span", { className: "truncate text-[11px] text-muted-foreground", children: second })
4162
+ render: /* @__PURE__ */ jsxs17("span", { className: "flex min-w-0 flex-col", children: [
4163
+ /* @__PURE__ */ jsx20("span", { className: "truncate", children: t.table_name }),
4164
+ /* @__PURE__ */ jsx20("span", { className: "truncate text-[11px] text-muted-foreground", children: second })
4125
4165
  ] })
4126
4166
  } : {}
4127
4167
  };
4128
4168
  });
4129
4169
  const missing = Boolean(value) && !list.loading && !list.error && !list.rows.some((t) => t.table_id === value);
4130
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
4131
- /* @__PURE__ */ jsx19(
4170
+ return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
4171
+ /* @__PURE__ */ jsx20(
4132
4172
  CreatablePicker,
4133
4173
  {
4134
4174
  value: value || null,
@@ -4142,17 +4182,17 @@ function TablePicker({ dataSource, value, onChange, disabled, tables }) {
4142
4182
  ariaLabel: "Table"
4143
4183
  }
4144
4184
  ),
4145
- list.error && /* @__PURE__ */ jsx19(RefusalLine, { error: refusal("door", list.error, "Try again in a moment.") }),
4146
- missing && /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-destructive", children: "This table is archived or not shared with you." })
4185
+ list.error && /* @__PURE__ */ jsx20(RefusalLine, { error: refusal("door", list.error, "Try again in a moment.") }),
4186
+ missing && /* @__PURE__ */ jsx20("p", { className: "text-[11px] text-destructive", children: "This table is archived or not shared with you." })
4147
4187
  ] });
4148
4188
  }
4149
4189
  function TableScope({ dataSource, userId, tableId, children, fallback = null, unavailable, tables }) {
4150
4190
  const own3 = useTablesAnywhere(dataSource);
4151
4191
  const list = tables ?? own3;
4152
4192
  const organizationId = list.rows.find((t) => t.table_id === tableId)?.organization_id ?? null;
4153
- if (tableId && !organizationId && !list.loading) return /* @__PURE__ */ jsx19(Fragment6, { children: unavailable ?? fallback });
4154
- if (!tableId || !organizationId) return /* @__PURE__ */ jsx19(Fragment6, { children: fallback });
4155
- return /* @__PURE__ */ jsx19(RecordsProvider2, { config: { dataSource, actor: personActor(userId), organizationId }, children });
4193
+ if (tableId && !organizationId && !list.loading) return /* @__PURE__ */ jsx20(Fragment6, { children: unavailable ?? fallback });
4194
+ if (!tableId || !organizationId) return /* @__PURE__ */ jsx20(Fragment6, { children: fallback });
4195
+ return /* @__PURE__ */ jsx20(RecordsProvider2, { config: { dataSource, actor: personActor(userId), organizationId }, children });
4156
4196
  }
4157
4197
  function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
4158
4198
  const fields = useFields(tableId);
@@ -4172,11 +4212,11 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
4172
4212
  void _gone;
4173
4213
  onChange(rest);
4174
4214
  };
4175
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-2", children: [
4176
- fields.error && /* @__PURE__ */ jsx19(RefusalLine, { error: fields.error }),
4215
+ return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
4216
+ fields.error && /* @__PURE__ */ jsx20(RefusalLine, { error: fields.error }),
4177
4217
  keys.map((key) => {
4178
4218
  const field = byKey.get(key);
4179
- return /* @__PURE__ */ jsx19(
4219
+ return /* @__PURE__ */ jsx20(
4180
4220
  ColumnValueRow,
4181
4221
  {
4182
4222
  columnKey: key,
@@ -4192,7 +4232,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
4192
4232
  key
4193
4233
  );
4194
4234
  }),
4195
- adding && /* @__PURE__ */ jsx19(
4235
+ adding && /* @__PURE__ */ jsx20(
4196
4236
  ColumnValueRow,
4197
4237
  {
4198
4238
  columnKey: null,
@@ -4209,7 +4249,7 @@ function ColumnValuesEditor({ tableId, value, onChange, disabled, addLabel }) {
4209
4249
  onRemove: () => setAdding(false)
4210
4250
  }
4211
4251
  ),
4212
- !disabled && !adding && keys.length < all.length && /* @__PURE__ */ jsx19(Button8, { type: "button", variant: "outline", size: "sm", className: "self-start", onClick: () => setAdding(true), children: addLabel })
4252
+ !disabled && !adding && keys.length < all.length && /* @__PURE__ */ jsx20(Button8, { type: "button", variant: "outline", size: "sm", className: "self-start", onClick: () => setAdding(true), children: addLabel })
4213
4253
  ] });
4214
4254
  }
4215
4255
  function ColumnValueRow({
@@ -4225,9 +4265,9 @@ function ColumnValueRow({
4225
4265
  }) {
4226
4266
  const orphan = columnKey !== null && !loading && field === void 0;
4227
4267
  const shown2 = orphan ? [{ value: columnKey, label: columnKey, hint: "Not a column" }, ...options] : options;
4228
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1 rounded-md border border-border/60 p-2", children: [
4229
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
4230
- /* @__PURE__ */ jsx19("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx19(
4268
+ return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1 rounded-md border border-border/60 p-2", children: [
4269
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
4270
+ /* @__PURE__ */ jsx20("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx20(
4231
4271
  CreatablePicker,
4232
4272
  {
4233
4273
  value: columnKey,
@@ -4241,9 +4281,9 @@ function ColumnValueRow({
4241
4281
  ariaLabel: "Column"
4242
4282
  }
4243
4283
  ) }),
4244
- !disabled && /* @__PURE__ */ jsx19(Button8, { type: "button", variant: "ghost", size: "sm", "aria-label": "Remove", onClick: onRemove, children: "\u2715" })
4284
+ !disabled && /* @__PURE__ */ jsx20(Button8, { type: "button", variant: "ghost", size: "sm", "aria-label": "Remove", onClick: onRemove, children: "\u2715" })
4245
4285
  ] }),
4246
- field ? /* @__PURE__ */ jsx19(FieldControl, { field, value, onChange: onValue, disabled }) : orphan ? /* @__PURE__ */ jsx19("p", { className: "text-[11px] text-muted-foreground", children: value === null || value === void 0 ? "\u2014" : String(value) }) : null
4286
+ field ? /* @__PURE__ */ jsx20(FieldControl, { field, value, onChange: onValue, disabled }) : orphan ? /* @__PURE__ */ jsx20("p", { className: "text-[11px] text-muted-foreground", children: value === null || value === void 0 ? "\u2014" : String(value) }) : null
4247
4287
  ] });
4248
4288
  }
4249
4289
  function RecordPicker({ tableId, value, onChange, disabled }) {
@@ -4255,8 +4295,8 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
4255
4295
  label: rowNameIn(table.data ?? null, row)
4256
4296
  }));
4257
4297
  const missing = Boolean(value) && !records.loading && !records.error && !rows.some((r) => r.id === value);
4258
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
4259
- /* @__PURE__ */ jsx19(
4298
+ return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
4299
+ /* @__PURE__ */ jsx20(
4260
4300
  CreatablePicker,
4261
4301
  {
4262
4302
  value: value || null,
@@ -4270,7 +4310,7 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
4270
4310
  ariaLabel: "Record"
4271
4311
  }
4272
4312
  ),
4273
- records.error && /* @__PURE__ */ jsx19(RefusalLine, { error: records.error })
4313
+ records.error && /* @__PURE__ */ jsx20(RefusalLine, { error: records.error })
4274
4314
  ] });
4275
4315
  }
4276
4316
 
@@ -4278,8 +4318,8 @@ function RecordPicker({ tableId, value, onChange, disabled }) {
4278
4318
  import { useEffect as useEffect13, useMemo as useMemo8 } from "react";
4279
4319
  import { isEntityReferenceConfig } from "@ai-matrx/records";
4280
4320
  import { useFields as useFields2, useTable as useTable2 } from "@ai-matrx/records/react";
4281
- import { BasicInput as BasicInput6, Button as Button9, CreatablePicker as CreatablePicker2, cn as cn14 } from "@ai-matrx/design-system";
4282
- import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
4321
+ import { BasicInput as BasicInput6, Button as Button9, CreatablePicker as CreatablePicker2, cn as cn15 } from "@ai-matrx/design-system";
4322
+ import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
4283
4323
  var DATA_BINDING_SHAPES = [
4284
4324
  { value: "collection", label: "The whole table" },
4285
4325
  { value: "reference", label: "One record" },
@@ -4346,9 +4386,9 @@ function DataBindingPicker({ dataSource, userId, binding, onChange, disabled, de
4346
4386
  ...binding.semantic_type === "collection" && defaultRowLimit ? { limit: defaultRowLimit } : {}
4347
4387
  });
4348
4388
  };
4349
- return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
4350
- /* @__PURE__ */ jsx20(TablePicker, { dataSource, value: tableId, onChange: selectTable, disabled: Boolean(disabled), tables }),
4351
- /* @__PURE__ */ jsx20(TableScope, { dataSource, userId, tableId, tables, children: tableId && /* @__PURE__ */ jsx20(
4389
+ return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
4390
+ /* @__PURE__ */ jsx21(TablePicker, { dataSource, value: tableId, onChange: selectTable, disabled: Boolean(disabled), tables }),
4391
+ /* @__PURE__ */ jsx21(TableScope, { dataSource, userId, tableId, tables, children: tableId && /* @__PURE__ */ jsx21(
4352
4392
  BindingDetails,
4353
4393
  {
4354
4394
  tableId,
@@ -4412,8 +4452,8 @@ function BindingDetails({
4412
4452
  const fieldOptions = fieldList.map((f) => ({ value: f.key, label: fieldName(f) }));
4413
4453
  const template = binding.transform?.template ?? "";
4414
4454
  const setTemplate = (next) => onChange({ ...binding, transform: { join: "\n", ...binding.transform, name: "list", template: next } });
4415
- return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
4416
- /* @__PURE__ */ jsx20("div", { className: "flex flex-wrap gap-1", role: "radiogroup", "aria-label": "What to read", children: DATA_BINDING_SHAPES.map((s) => /* @__PURE__ */ jsx20(
4455
+ return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
4456
+ /* @__PURE__ */ jsx21("div", { className: "flex flex-wrap gap-1", role: "radiogroup", "aria-label": "What to read", children: DATA_BINDING_SHAPES.map((s) => /* @__PURE__ */ jsx21(
4417
4457
  Button9,
4418
4458
  {
4419
4459
  type: "button",
@@ -4427,7 +4467,7 @@ function BindingDetails({
4427
4467
  },
4428
4468
  s.value
4429
4469
  )) }),
4430
- shape !== "collection" && /* @__PURE__ */ jsx20(
4470
+ shape !== "collection" && /* @__PURE__ */ jsx21(
4431
4471
  RecordPicker,
4432
4472
  {
4433
4473
  tableId,
@@ -4436,7 +4476,7 @@ function BindingDetails({
4436
4476
  disabled: Boolean(disabled)
4437
4477
  }
4438
4478
  ),
4439
- shape === "value" && /* @__PURE__ */ jsx20(
4479
+ shape === "value" && /* @__PURE__ */ jsx21(
4440
4480
  CreatablePicker2,
4441
4481
  {
4442
4482
  value: binding.field_key ?? null,
@@ -4450,11 +4490,11 @@ function BindingDetails({
4450
4490
  ariaLabel: "Column"
4451
4491
  }
4452
4492
  ),
4453
- shape !== "value" && /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
4454
- /* @__PURE__ */ jsx20(
4493
+ shape !== "value" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
4494
+ /* @__PURE__ */ jsx21(
4455
4495
  "textarea",
4456
4496
  {
4457
- className: cn14(
4497
+ className: cn15(
4458
4498
  "min-h-[3.5rem] w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs"
4459
4499
  ),
4460
4500
  "aria-label": "Each row reads as",
@@ -4463,7 +4503,7 @@ function BindingDetails({
4463
4503
  onChange: (e) => setTemplate(e.target.value)
4464
4504
  }
4465
4505
  ),
4466
- !disabled && /* @__PURE__ */ jsx20("div", { className: "flex flex-wrap gap-1", children: fieldList.flatMap(bindingPlaceholdersFor).map((p) => /* @__PURE__ */ jsx20(
4506
+ !disabled && /* @__PURE__ */ jsx21("div", { className: "flex flex-wrap gap-1", children: fieldList.flatMap(bindingPlaceholdersFor).map((p) => /* @__PURE__ */ jsx21(
4467
4507
  Button9,
4468
4508
  {
4469
4509
  type: "button",
@@ -4476,9 +4516,9 @@ function BindingDetails({
4476
4516
  p.token
4477
4517
  )) })
4478
4518
  ] }),
4479
- shape === "collection" && /* @__PURE__ */ jsxs17("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
4519
+ shape === "collection" && /* @__PURE__ */ jsxs18("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
4480
4520
  "Up to",
4481
- /* @__PURE__ */ jsx20(
4521
+ /* @__PURE__ */ jsx21(
4482
4522
  BasicInput6,
4483
4523
  {
4484
4524
  type: "number",
@@ -4495,9 +4535,9 @@ function BindingDetails({
4495
4535
  ),
4496
4536
  "rows"
4497
4537
  ] }),
4498
- /* @__PURE__ */ jsxs17("div", { className: "flex flex-wrap items-center gap-1", role: "radiogroup", "aria-label": "If nothing is found", children: [
4499
- /* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "If nothing is found" }),
4500
- DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ jsx20(
4538
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-wrap items-center gap-1", role: "radiogroup", "aria-label": "If nothing is found", children: [
4539
+ /* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground", children: "If nothing is found" }),
4540
+ DATA_BINDING_MISSING.map((m) => /* @__PURE__ */ jsx21(
4501
4541
  Button9,
4502
4542
  {
4503
4543
  type: "button",
@@ -4521,7 +4561,7 @@ import { useFields as useFields3, useRecord, useTable as useTable3 } from "@ai-m
4521
4561
  // src/values.tsx
4522
4562
  import { SWATCH_CLASS, formatColumnValue } from "@ai-matrx/design-system/data-table";
4523
4563
  import { formatFieldValue as formatFieldValue3 } from "@ai-matrx/design-system/field-formats";
4524
- import { Badge as Badge5, cn as cn16 } from "@ai-matrx/design-system";
4564
+ import { Badge as Badge5, cn as cn17 } from "@ai-matrx/design-system";
4525
4565
 
4526
4566
  // src/embeddedLook.tsx
4527
4567
  import { createContext as createContext3, useContext as useContext3 } from "react";
@@ -4579,7 +4619,7 @@ import { wholeValueOf } from "@ai-matrx/records/core";
4579
4619
  import { useEffect as useEffect14, useState as useState17 } from "react";
4580
4620
  import { wholeValueSize } from "@ai-matrx/records/core";
4581
4621
  import { BasicTextarea as BasicTextarea3 } from "@ai-matrx/design-system";
4582
- import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
4622
+ import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
4583
4623
  var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
4584
4624
  function wholeValueLine(pointer) {
4585
4625
  return `Open the whole text (${wholeValueSize(pointer)})`;
@@ -4588,12 +4628,12 @@ function WholeValueCell({ words, pointer }) {
4588
4628
  const host = useRecordsUi();
4589
4629
  const href = host.hrefForFile?.({ fileId: pointer.file_id });
4590
4630
  const line = wholeValueLine(pointer);
4591
- return /* @__PURE__ */ jsxs18("span", { className: "flex min-w-0 items-baseline gap-2", "data-whole-value-file": pointer.file_id, children: [
4592
- /* @__PURE__ */ jsxs18("span", { className: "truncate", title: `The first ${pointer.shown_chars} of ${pointer.chars} characters`, children: [
4631
+ return /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-baseline gap-2", "data-whole-value-file": pointer.file_id, children: [
4632
+ /* @__PURE__ */ jsxs19("span", { className: "truncate", title: `The first ${pointer.shown_chars} of ${pointer.chars} characters`, children: [
4593
4633
  words,
4594
4634
  "\u2026"
4595
4635
  ] }),
4596
- href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ jsx21("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ jsx21("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${wholeValueSize(pointer)} in a file` })
4636
+ href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ jsx22("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${wholeValueSize(pointer)} in a file` })
4597
4637
  ] });
4598
4638
  }
4599
4639
 
@@ -4602,7 +4642,7 @@ import { formatPhone as formatPhone2 } from "@ai-matrx/design-system/field-forma
4602
4642
 
4603
4643
  // src/ReferenceChips.tsx
4604
4644
  import { entityRefsOf as entityRefsOf2 } from "@ai-matrx/records";
4605
- import { Badge as Badge4, cn as cn15 } from "@ai-matrx/design-system";
4645
+ import { Badge as Badge4, cn as cn16 } from "@ai-matrx/design-system";
4606
4646
 
4607
4647
  // src/kindValues.ts
4608
4648
  import { tryDecodeDirective } from "@ai-matrx/content-ir/directives";
@@ -4656,7 +4696,7 @@ function kindLabel(kind) {
4656
4696
  }
4657
4697
 
4658
4698
  // src/ReferenceChips.tsx
4659
- import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
4699
+ import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
4660
4700
  function glyphOf(icon) {
4661
4701
  const text = (icon ?? "").trim();
4662
4702
  return text !== "" && text.length <= 8 && /[^\u0000-\u007f]/.test(text) ? text : null;
@@ -4689,11 +4729,11 @@ function referencesOf(field, value, kind, labels) {
4689
4729
  var ARCHIVED_REFERENCE_WORD = "Archived";
4690
4730
  var ARCHIVED_REFERENCE_TIP = "In the Archived view; restore it to use it again";
4691
4731
  function PageGlyph() {
4692
- return /* @__PURE__ */ jsxs19("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: 14, height: 14, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "data-records-page-glyph": "", children: [
4693
- /* @__PURE__ */ jsx22("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
4694
- /* @__PURE__ */ jsx22("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
4695
- /* @__PURE__ */ jsx22("path", { d: "M10 13H8" }),
4696
- /* @__PURE__ */ jsx22("path", { d: "M16 17H8" })
4732
+ return /* @__PURE__ */ jsxs20("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: 14, height: 14, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "data-records-page-glyph": "", children: [
4733
+ /* @__PURE__ */ jsx23("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
4734
+ /* @__PURE__ */ jsx23("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
4735
+ /* @__PURE__ */ jsx23("path", { d: "M10 13H8" }),
4736
+ /* @__PURE__ */ jsx23("path", { d: "M16 17H8" })
4697
4737
  ] });
4698
4738
  }
4699
4739
  function ReferenceChip({ reference, waiting }) {
@@ -4702,10 +4742,10 @@ function ReferenceChip({ reference, waiting }) {
4702
4742
  const drawn = host.renderReference ? host.renderReference({ ...reference, label: reference.label ?? words }) : null;
4703
4743
  const look = useEmbeddedLook();
4704
4744
  if (look?.plainRelation) {
4705
- return /* @__PURE__ */ jsxs19(
4745
+ return /* @__PURE__ */ jsxs20(
4706
4746
  "span",
4707
4747
  {
4708
- className: cn15(
4748
+ className: cn16(
4709
4749
  "inline-flex max-w-full min-w-0 items-center gap-1.5 text-sm text-foreground hover:underline [&_a]:text-inherit [&_a]:no-underline [&_a:hover]:underline",
4710
4750
  reference.archived && "opacity-70"
4711
4751
  ),
@@ -4714,18 +4754,18 @@ function ReferenceChip({ reference, waiting }) {
4714
4754
  "data-records-reference-archived": reference.archived ? "" : void 0,
4715
4755
  title: reference.archived ? ARCHIVED_REFERENCE_TIP : words,
4716
4756
  children: [
4717
- /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", "data-records-reference-icon": "", className: "inline-flex size-4 shrink-0 items-center justify-center text-muted-foreground", children: glyphOf(reference.icon) ? /* @__PURE__ */ jsx22("span", { className: "text-sm leading-none", children: reference.icon }) : reference.icon && host.renderIcon?.(reference.icon) || /* @__PURE__ */ jsx22(PageGlyph, {}) }),
4718
- drawn ?? /* @__PURE__ */ jsx22("span", { className: "truncate", children: words }),
4719
- reference.archived ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
4757
+ /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", "data-records-reference-icon": "", className: "inline-flex size-4 shrink-0 items-center justify-center text-muted-foreground", children: glyphOf(reference.icon) ? /* @__PURE__ */ jsx23("span", { className: "text-sm leading-none", children: reference.icon }) : reference.icon && host.renderIcon?.(reference.icon) || /* @__PURE__ */ jsx23(PageGlyph, {}) }),
4758
+ drawn ?? /* @__PURE__ */ jsx23("span", { className: "truncate", children: words }),
4759
+ reference.archived ? /* @__PURE__ */ jsx23("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
4720
4760
  ]
4721
4761
  }
4722
4762
  );
4723
4763
  }
4724
- return /* @__PURE__ */ jsxs19(
4764
+ return /* @__PURE__ */ jsxs20(
4725
4765
  Badge4,
4726
4766
  {
4727
4767
  variant: "secondary",
4728
- className: cn15(
4768
+ className: cn16(
4729
4769
  "max-w-full min-w-0 gap-1 px-1.5 py-0 text-[11px] font-normal",
4730
4770
  reference.archived && "opacity-70"
4731
4771
  ),
@@ -4733,15 +4773,15 @@ function ReferenceChip({ reference, waiting }) {
4733
4773
  "data-records-reference-archived": reference.archived ? "" : void 0,
4734
4774
  title: reference.archived ? ARCHIVED_REFERENCE_TIP : words,
4735
4775
  children: [
4736
- drawn ?? /* @__PURE__ */ jsx22("span", { className: "truncate", children: words }),
4737
- reference.archived ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
4776
+ drawn ?? /* @__PURE__ */ jsx23("span", { className: "truncate", children: words }),
4777
+ reference.archived ? /* @__PURE__ */ jsx23("span", { className: "shrink-0 text-muted-foreground", children: ARCHIVED_REFERENCE_WORD }) : null
4738
4778
  ]
4739
4779
  }
4740
4780
  );
4741
4781
  }
4742
4782
  function ReferenceChips({ refs, waiting }) {
4743
- if (refs.length === 0) return /* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "\u2014" });
4744
- return /* @__PURE__ */ jsx22("span", { className: "flex min-w-0 flex-wrap gap-1", "data-records-reference-chips": "", children: refs.map((r) => /* @__PURE__ */ jsx22(ReferenceChip, { reference: r, waiting }, `${r.token}:${r.id}`)) });
4783
+ if (refs.length === 0) return /* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", children: "\u2014" });
4784
+ return /* @__PURE__ */ jsx23("span", { className: "flex min-w-0 flex-wrap gap-1", "data-records-reference-chips": "", children: refs.map((r) => /* @__PURE__ */ jsx23(ReferenceChip, { reference: r, waiting }, `${r.token}:${r.id}`)) });
4745
4785
  }
4746
4786
  function KindValueCell({
4747
4787
  kv,
@@ -4750,10 +4790,10 @@ function KindValueCell({
4750
4790
  }) {
4751
4791
  const host = useRecordsUi();
4752
4792
  if (host.renderKind) {
4753
- return /* @__PURE__ */ jsx22("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 }) });
4793
+ return /* @__PURE__ */ jsx23("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 }) });
4754
4794
  }
4755
4795
  const named = kv.items.map(kindItemWords).filter((w) => w !== null);
4756
- return /* @__PURE__ */ jsx22("span", { className: cn15("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__ */ jsx22(Badge4, { variant: "secondary", className: "px-1.5 py-0 text-[11px] font-normal", children: w }, `${w}-${i}`)) : /* @__PURE__ */ jsx22(Badge4, { variant: "outline", className: "px-1.5 py-0 text-[11px] font-normal", children: kindLabel(kv.kind) }) });
4796
+ return /* @__PURE__ */ jsx23("span", { className: cn16("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__ */ jsx23(Badge4, { variant: "secondary", className: "px-1.5 py-0 text-[11px] font-normal", children: w }, `${w}-${i}`)) : /* @__PURE__ */ jsx23(Badge4, { variant: "outline", className: "px-1.5 py-0 text-[11px] font-normal", children: kindLabel(kv.kind) }) });
4757
4797
  }
4758
4798
 
4759
4799
  // src/formulaNames.ts
@@ -4771,10 +4811,10 @@ function formulaSourceArchived(field, document2) {
4771
4811
 
4772
4812
  // src/values.tsx
4773
4813
  import { newerKindWords, sourceArchivedOf as sourceArchivedOf2 } from "@ai-matrx/records";
4774
- import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
4814
+ import { Fragment as Fragment7, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
4775
4815
  function statusMark(field, item, document2) {
4776
4816
  const mark = statusMarkOf(field, item, document2);
4777
- return mark ? /* @__PURE__ */ jsx23("span", { "aria-label": mark.words, title: mark.words, className: "mr-1", "data-records-status-group": mark.group, children: mark.mark }) : null;
4817
+ return mark ? /* @__PURE__ */ jsx24("span", { "aria-label": mark.words, title: mark.words, className: "mr-1", "data-records-status-group": mark.group, children: mark.mark }) : null;
4778
4818
  }
4779
4819
  function envelopeFor(document2, key) {
4780
4820
  const block = document2?._values;
@@ -4820,43 +4860,47 @@ function sourceArchivedSentence(state) {
4820
4860
  return state.table ? `${state.label} on ${state.table} is archived` : `${state.label} is archived`;
4821
4861
  }
4822
4862
  function SourceArchivedValue({ state }) {
4823
- return /* @__PURE__ */ jsx23("span", { className: "text-xs italic text-muted-foreground", title: sourceArchivedSentence(state), "data-records-source-archived": state.field_id ?? "", children: SOURCE_ARCHIVED_WORDS });
4863
+ return /* @__PURE__ */ jsx24("span", { className: "text-xs italic text-muted-foreground", title: sourceArchivedSentence(state), "data-records-source-archived": state.field_id ?? "", children: SOURCE_ARCHIVED_WORDS });
4824
4864
  }
4825
4865
  var ABSENCE_WORDS = ABSENCE_WORD_LABEL;
4826
4866
  function renderValue(field, value, document2, labels, stillWaitingFor, look) {
4827
4867
  const archivedSource = sourceArchivedOf2(value);
4828
- if (archivedSource) return /* @__PURE__ */ jsx23(SourceArchivedValue, { state: archivedSource });
4868
+ if (archivedSource) return /* @__PURE__ */ jsx24(SourceArchivedValue, { state: archivedSource });
4829
4869
  const envelope = envelopeFor(document2, field.key);
4830
4870
  if (envelope?.absent) {
4831
- return /* @__PURE__ */ jsx23("span", { className: "text-xs italic text-muted-foreground", title: `VAL-2: ${envelope.absent}`, children: ABSENCE_WORDS[String(envelope.absent)] ?? String(envelope.absent) });
4871
+ return /* @__PURE__ */ jsx24("span", { className: "text-xs italic text-muted-foreground", title: `VAL-2: ${envelope.absent}`, children: ABSENCE_WORDS[String(envelope.absent)] ?? String(envelope.absent) });
4832
4872
  }
4833
4873
  if (value === null || value === void 0 || value === "") {
4834
4874
  const gone = unresolvedFor(document2, field.key);
4835
4875
  if (gone) {
4836
- return /* @__PURE__ */ jsx23("span", { className: "text-xs italic text-muted-foreground", title: `It pointed at ${gone}`, children: "The record this pointed at no longer exists" });
4876
+ return /* @__PURE__ */ jsx24("span", { className: "text-xs italic text-muted-foreground", title: `It pointed at ${gone}`, children: "The record this pointed at no longer exists" });
4837
4877
  }
4838
4878
  const archivedInput = formulaSourceArchived(field, document2);
4839
- if (archivedInput) return /* @__PURE__ */ jsx23(SourceArchivedValue, { state: archivedInput });
4879
+ if (archivedInput) return /* @__PURE__ */ jsx24(SourceArchivedValue, { state: archivedInput });
4840
4880
  const computed = computedEmptyOf(field, document2);
4841
- if (computed?.sentence) return /* @__PURE__ */ jsx23("span", { className: "text-xs italic text-muted-foreground", children: computed.sentence });
4842
- if (computed?.words) return /* @__PURE__ */ jsx23("span", { "data-records-empty-why": computed.kind, children: computed.words });
4881
+ if (computed?.sentence) return /* @__PURE__ */ jsx24("span", { className: "text-xs italic text-muted-foreground", children: computed.sentence });
4882
+ if (computed?.words) return /* @__PURE__ */ jsx24("span", { "data-records-empty-why": computed.kind, children: computed.words });
4843
4883
  if (computed?.why) {
4844
- return /* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", title: computed.why, "data-records-empty-why": computed.kind, children: "\u2014" });
4884
+ return /* @__PURE__ */ jsx24("span", { className: "text-muted-foreground", title: computed.why, "data-records-empty-why": computed.kind, children: "\u2014" });
4845
4885
  }
4846
4886
  if (look?.blankEmpty) return null;
4847
- return /* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", children: "\u2014" });
4887
+ return /* @__PURE__ */ jsx24("span", { className: "text-muted-foreground", children: "\u2014" });
4848
4888
  }
4849
- if (isSignatureField(field)) return /* @__PURE__ */ jsx23(SignatureValue, { value, fieldKey: field.key, document: document2 });
4889
+ if (isSignatureField(field)) return /* @__PURE__ */ jsx24(SignatureValue, { value, fieldKey: field.key, document: document2 });
4850
4890
  const newer = newerKindValue(field, value);
4851
4891
  if (newer !== void 0) return newer;
4852
4892
  const whole = typeof value === "string" ? wholeValueOf(document2, field.key) : null;
4853
- if (whole) return /* @__PURE__ */ jsx23(WholeValueCell, { words: value, pointer: whole });
4893
+ if (whole) return /* @__PURE__ */ jsx24(WholeValueCell, { words: value, pointer: whole });
4854
4894
  const kind = editorKindFor(field);
4855
4895
  if (kind === "relation" || kind === "entity_reference") {
4856
- return /* @__PURE__ */ jsx23(ReferenceChips, { refs: referencesOf(field, value, kind, labels), waiting: stillWaitingFor });
4896
+ return /* @__PURE__ */ jsx24(ReferenceChips, { refs: referencesOf(field, value, kind, labels), waiting: stillWaitingFor });
4897
+ }
4898
+ if (kind === "member") {
4899
+ const ids = (Array.isArray(value) ? value : [value]).filter((v) => v !== null && v !== void 0 && v !== "");
4900
+ return /* @__PURE__ */ jsx24("span", { className: "flex min-w-0 flex-wrap gap-1", "data-records-person-chips": "", children: ids.map((id, i) => /* @__PURE__ */ jsx24(PersonChip, { name: scalarText(field, id, labels, stillWaitingFor) }, `${String(id)}-${i}`)) });
4857
4901
  }
4858
- const kv = kind === "attachment" || kind === "member" ? null : kindValueOf(value);
4859
- if (kv) return /* @__PURE__ */ jsx23(KindValueCell, { kv, where: "cell", title: field.label });
4902
+ const kv = kind === "attachment" ? null : kindValueOf(value);
4903
+ if (kv) return /* @__PURE__ */ jsx24(KindValueCell, { kv, where: "cell", title: field.label });
4860
4904
  const chosen = kind === "select" || kind === "multi_select";
4861
4905
  const chipOf = (item) => {
4862
4906
  const chipLook = choiceChipLookOf(field, item, scalarText(field, item, labels));
@@ -4864,17 +4908,17 @@ function renderValue(field, value, document2, labels, stillWaitingFor, look) {
4864
4908
  };
4865
4909
  if (chosen) {
4866
4910
  const items = Array.isArray(value) ? value : [value];
4867
- return /* @__PURE__ */ jsx23("span", { className: "flex flex-wrap gap-1", "data-records-choice-chips": "", children: items.map((item, i) => {
4911
+ return /* @__PURE__ */ jsx24("span", { className: "flex flex-wrap gap-1", "data-records-choice-chips": "", children: items.map((item, i) => {
4868
4912
  const chip = chipOf(item);
4869
- return /* @__PURE__ */ jsxs20(
4913
+ return /* @__PURE__ */ jsxs21(
4870
4914
  Badge5,
4871
4915
  {
4872
4916
  variant: "outline",
4873
- className: cn16("text-[11px]", chip.className),
4917
+ className: cn17("text-[11px]", chip.className),
4874
4918
  "data-records-choice-chip": "",
4875
4919
  ...chip.tinted ? { "data-records-choice-tint": "" } : {},
4876
4920
  children: [
4877
- look?.choiceDot ? /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", "data-matrx-pill-ink": "", "data-records-choice-dot": "", className: cn16("mr-1.5 inline-block size-1.5 shrink-0 rounded-full", chip.dot) }) : null,
4921
+ look?.choiceDot ? /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", "data-matrx-pill-ink": "", "data-records-choice-dot": "", className: cn17("mr-1.5 inline-block size-1.5 shrink-0 rounded-full", chip.dot) }) : null,
4878
4922
  statusMark(field, item, Array.isArray(value) ? void 0 : document2),
4879
4923
  scalarText(field, item, labels, Array.isArray(value) ? void 0 : stillWaitingFor)
4880
4924
  ]
@@ -4883,13 +4927,13 @@ function renderValue(field, value, document2, labels, stillWaitingFor, look) {
4883
4927
  );
4884
4928
  }) });
4885
4929
  }
4886
- if (kind === "attachment") return /* @__PURE__ */ jsx23(AttachmentChips, { value });
4930
+ if (kind === "attachment") return /* @__PURE__ */ jsx24(AttachmentChips, { value });
4887
4931
  if (Array.isArray(value)) {
4888
- return /* @__PURE__ */ jsx23("span", { className: "flex flex-wrap gap-1", children: value.map((item, i) => /* @__PURE__ */ jsx23(Badge5, { variant: "secondary", className: "text-[11px]", children: scalarText(field, item, labels) }, `${String(item)}-${i}`)) });
4932
+ return /* @__PURE__ */ jsx24("span", { className: "flex flex-wrap gap-1", children: value.map((item, i) => /* @__PURE__ */ jsx24(Badge5, { variant: "secondary", className: "text-[11px]", children: scalarText(field, item, labels) }, `${String(item)}-${i}`)) });
4889
4933
  }
4890
4934
  if (kind === "url" && typeof value === "string") {
4891
4935
  const href = value.includes("://") ? value : `https://${value}`;
4892
- return /* @__PURE__ */ jsxs20(
4936
+ return /* @__PURE__ */ jsxs21(
4893
4937
  "a",
4894
4938
  {
4895
4939
  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",
@@ -4900,14 +4944,14 @@ function renderValue(field, value, document2, labels, stillWaitingFor, look) {
4900
4944
  "data-records-link-chip": "",
4901
4945
  onClick: (event) => event.stopPropagation(),
4902
4946
  children: [
4903
- /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2197" }),
4904
- /* @__PURE__ */ jsx23("span", { className: "truncate", children: linkChipText(value) })
4947
+ /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2197" }),
4948
+ /* @__PURE__ */ jsx24("span", { className: "truncate", children: linkChipText(value) })
4905
4949
  ]
4906
4950
  }
4907
4951
  );
4908
4952
  }
4909
4953
  if (kind === "phone" && typeof value === "string" && value.trim() !== "") {
4910
- return /* @__PURE__ */ jsx23(
4954
+ return /* @__PURE__ */ jsx24(
4911
4955
  "a",
4912
4956
  {
4913
4957
  className: "truncate tabular-nums text-primary underline-offset-2 hover:underline",
@@ -4920,12 +4964,12 @@ function renderValue(field, value, document2, labels, stillWaitingFor, look) {
4920
4964
  );
4921
4965
  }
4922
4966
  if (kind === "email" && typeof value === "string") {
4923
- return /* @__PURE__ */ jsx23("a", { className: "truncate text-primary underline-offset-2 hover:underline", href: `mailto:${value}`, children: value });
4967
+ return /* @__PURE__ */ jsx24("a", { className: "truncate text-primary underline-offset-2 hover:underline", href: `mailto:${value}`, children: value });
4924
4968
  }
4925
4969
  if (typeof value === "boolean") {
4926
- return /* @__PURE__ */ jsx23("span", { className: kind === "checkbox" ? "text-sm" : "", title: value ? "Yes" : "No", children: value ? "\u2713" : "\u2014" });
4970
+ return /* @__PURE__ */ jsx24("span", { className: kind === "checkbox" ? "text-sm" : "", title: value ? "Yes" : "No", children: value ? "\u2713" : "\u2014" });
4927
4971
  }
4928
- return /* @__PURE__ */ jsx23("span", { className: cn16("truncate", kind === "number" || kind === "currency" || kind === "percent" ? "tabular-nums" : ""), children: scalarText(field, value, labels, stillWaitingFor) });
4972
+ return /* @__PURE__ */ jsx24("span", { className: cn17("truncate", kind === "number" || kind === "currency" || kind === "percent" ? "tabular-nums" : ""), children: scalarText(field, value, labels, stillWaitingFor) });
4929
4973
  }
4930
4974
  function scalarText(field, value, labels, stillWaitingFor) {
4931
4975
  if (value === null || value === void 0) return "\u2014";
@@ -4967,13 +5011,13 @@ function scalarText(field, value, labels, stillWaitingFor) {
4967
5011
  }
4968
5012
 
4969
5013
  // src/PickedSummaries.tsx
4970
- import { Fragment as Fragment8, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5014
+ import { Fragment as Fragment8, jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
4971
5015
  function TableNameText({ dataSource, tableId }) {
4972
5016
  const tables = useTablesAnywhere(dataSource);
4973
- if (!tableId) return /* @__PURE__ */ jsx24(Fragment8, { children: "\u2014" });
4974
- if (tables.loading) return /* @__PURE__ */ jsx24(Fragment8, { children: "\u2026" });
4975
- if (tables.error) return /* @__PURE__ */ jsx24(Fragment8, { children: "Couldn't load the table's name" });
4976
- return /* @__PURE__ */ jsx24(Fragment8, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
5017
+ if (!tableId) return /* @__PURE__ */ jsx25(Fragment8, { children: "\u2014" });
5018
+ if (tables.loading) return /* @__PURE__ */ jsx25(Fragment8, { children: "\u2026" });
5019
+ if (tables.error) return /* @__PURE__ */ jsx25(Fragment8, { children: "Couldn't load the table's name" });
5020
+ return /* @__PURE__ */ jsx25(Fragment8, { children: tables.rows.find((t) => t.table_id === tableId)?.table_name ?? "\u2014" });
4977
5021
  }
4978
5022
  function ColumnValuesText({
4979
5023
  dataSource,
@@ -4981,38 +5025,38 @@ function ColumnValuesText({
4981
5025
  tableId,
4982
5026
  value
4983
5027
  }) {
4984
- if (!tableId) return /* @__PURE__ */ jsx24(Fragment8, { children: "\u2014" });
4985
- return /* @__PURE__ */ jsx24(
5028
+ if (!tableId) return /* @__PURE__ */ jsx25(Fragment8, { children: "\u2014" });
5029
+ return /* @__PURE__ */ jsx25(
4986
5030
  TableScope,
4987
5031
  {
4988
5032
  dataSource,
4989
5033
  userId,
4990
5034
  tableId,
4991
- fallback: /* @__PURE__ */ jsx24(Fragment8, { children: "\u2026" }),
4992
- unavailable: /* @__PURE__ */ jsx24(Fragment8, { children: "Couldn't load this table's columns" }),
4993
- children: /* @__PURE__ */ jsx24(RecordLabelProvider, { children: /* @__PURE__ */ jsx24(ColumnValuesWords, { tableId, value }) })
5035
+ fallback: /* @__PURE__ */ jsx25(Fragment8, { children: "\u2026" }),
5036
+ unavailable: /* @__PURE__ */ jsx25(Fragment8, { children: "Couldn't load this table's columns" }),
5037
+ children: /* @__PURE__ */ jsx25(RecordLabelProvider, { children: /* @__PURE__ */ jsx25(ColumnValuesWords, { tableId, value }) })
4994
5038
  }
4995
5039
  );
4996
5040
  }
4997
5041
  function ColumnValuesWords({ tableId, value }) {
4998
5042
  const fields = useFields3(tableId);
4999
5043
  const labels = useRecordLabels(fields.data ?? void 0);
5000
- if (fields.loading) return /* @__PURE__ */ jsx24(Fragment8, { children: "\u2026" });
5001
- if (fields.error) return /* @__PURE__ */ jsx24(Fragment8, { children: "Couldn't load this table's columns" });
5044
+ if (fields.loading) return /* @__PURE__ */ jsx25(Fragment8, { children: "\u2026" });
5045
+ if (fields.error) return /* @__PURE__ */ jsx25(Fragment8, { children: "Couldn't load this table's columns" });
5002
5046
  const parts = [];
5003
5047
  for (const [key, stored] of Object.entries(value)) {
5004
5048
  if (key.startsWith("_")) continue;
5005
5049
  const field = (fields.data ?? []).find((f) => f.key === key);
5006
- if (parts.length) parts.push(/* @__PURE__ */ jsx24("span", { children: ", " }, `${key}-sep`));
5050
+ if (parts.length) parts.push(/* @__PURE__ */ jsx25("span", { children: ", " }, `${key}-sep`));
5007
5051
  parts.push(
5008
- /* @__PURE__ */ jsxs21("span", { children: [
5052
+ /* @__PURE__ */ jsxs22("span", { children: [
5009
5053
  field ? fieldName(field) : "A removed column",
5010
5054
  " is ",
5011
5055
  field ? renderValue(field, stored, void 0, labels) : "\u2014"
5012
5056
  ] }, key)
5013
5057
  );
5014
5058
  }
5015
- return parts.length ? /* @__PURE__ */ jsx24(Fragment8, { children: parts }) : /* @__PURE__ */ jsx24(Fragment8, { children: "\u2014" });
5059
+ return parts.length ? /* @__PURE__ */ jsx25(Fragment8, { children: parts }) : /* @__PURE__ */ jsx25(Fragment8, { children: "\u2014" });
5016
5060
  }
5017
5061
  function RecordNameText({
5018
5062
  dataSource,
@@ -5020,35 +5064,35 @@ function RecordNameText({
5020
5064
  tableId,
5021
5065
  recordId
5022
5066
  }) {
5023
- if (!tableId || !recordId) return /* @__PURE__ */ jsx24(Fragment8, { children: "\u2014" });
5024
- return /* @__PURE__ */ jsx24(
5067
+ if (!tableId || !recordId) return /* @__PURE__ */ jsx25(Fragment8, { children: "\u2014" });
5068
+ return /* @__PURE__ */ jsx25(
5025
5069
  TableScope,
5026
5070
  {
5027
5071
  dataSource,
5028
5072
  userId,
5029
5073
  tableId,
5030
- fallback: /* @__PURE__ */ jsx24(Fragment8, { children: "\u2026" }),
5031
- unavailable: /* @__PURE__ */ jsx24(Fragment8, { children: "Couldn't load this record" }),
5032
- children: /* @__PURE__ */ jsx24(RecordNameWords, { tableId, recordId })
5074
+ fallback: /* @__PURE__ */ jsx25(Fragment8, { children: "\u2026" }),
5075
+ unavailable: /* @__PURE__ */ jsx25(Fragment8, { children: "Couldn't load this record" }),
5076
+ children: /* @__PURE__ */ jsx25(RecordNameWords, { tableId, recordId })
5033
5077
  }
5034
5078
  );
5035
5079
  }
5036
5080
  function RecordNameWords({ tableId, recordId }) {
5037
5081
  const table = useTable3(tableId);
5038
5082
  const record = useRecord(recordId);
5039
- if (record.loading || table.loading) return /* @__PURE__ */ jsx24(Fragment8, { children: "\u2026" });
5040
- if (record.error) return /* @__PURE__ */ jsx24(Fragment8, { children: "Couldn't load this record" });
5041
- if (!record.data) return /* @__PURE__ */ jsx24(Fragment8, { children: "A record you cannot open" });
5042
- return /* @__PURE__ */ jsx24(Fragment8, { children: recordName(record.data.document, table.data?.title_field ?? null) });
5083
+ if (record.loading || table.loading) return /* @__PURE__ */ jsx25(Fragment8, { children: "\u2026" });
5084
+ if (record.error) return /* @__PURE__ */ jsx25(Fragment8, { children: "Couldn't load this record" });
5085
+ if (!record.data) return /* @__PURE__ */ jsx25(Fragment8, { children: "A record you cannot open" });
5086
+ return /* @__PURE__ */ jsx25(Fragment8, { children: recordName(record.data.document, table.data?.title_field ?? null) });
5043
5087
  }
5044
5088
 
5045
5089
  // src/HeldChangeDecision.tsx
5046
5090
  import { useEffect as useEffect15, useState as useState18 } from "react";
5047
5091
  import { RecordsProvider as RecordsProvider3, useRecordsClient as useRecordsClient3 } from "@ai-matrx/records/react";
5048
5092
  import { Button as Button10 } from "@ai-matrx/design-system";
5049
- import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
5093
+ import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
5050
5094
  function HeldChangeDecision({ dataSource, userId, organizationId, approvalId, onDecided }) {
5051
- return /* @__PURE__ */ jsx25(RecordsProvider3, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ jsx25(Decision, { approvalId, onDecided }) });
5095
+ return /* @__PURE__ */ jsx26(RecordsProvider3, { config: { dataSource, actor: personActor(userId), organizationId }, children: /* @__PURE__ */ jsx26(Decision, { approvalId, onDecided }) });
5052
5096
  }
5053
5097
  function Decision({ approvalId, onDecided }) {
5054
5098
  const client = useRecordsClient3();
@@ -5077,13 +5121,13 @@ function Decision({ approvalId, onDecided }) {
5077
5121
  if (res.ok) onDecided(approve);
5078
5122
  else setError(res.error);
5079
5123
  };
5080
- if (may === null) return /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
5081
- return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-1.5", children: [
5082
- may ? /* @__PURE__ */ jsxs22("div", { className: "flex gap-2", children: [
5083
- /* @__PURE__ */ jsx25(Button10, { type: "button", size: "sm", disabled: busy !== null, onClick: () => void decide(true), children: busy === "approve" ? "Approving\u2026" : "Approve" }),
5084
- /* @__PURE__ */ jsx25(Button10, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void decide(false), children: busy === "refuse" ? "Refusing\u2026" : "Refuse" })
5085
- ] }) : !error && /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
5086
- error ? /* @__PURE__ */ jsx25(RefusalLine, { error }) : null
5124
+ if (may === null) return /* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: "Checking who can decide\u2026" });
5125
+ return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-1.5", children: [
5126
+ may ? /* @__PURE__ */ jsxs23("div", { className: "flex gap-2", children: [
5127
+ /* @__PURE__ */ jsx26(Button10, { type: "button", size: "sm", disabled: busy !== null, onClick: () => void decide(true), children: busy === "approve" ? "Approving\u2026" : "Approve" }),
5128
+ /* @__PURE__ */ jsx26(Button10, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void decide(false), children: busy === "refuse" ? "Refusing\u2026" : "Refuse" })
5129
+ ] }) : !error && /* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: "An owner or admin of this organization decides this." }),
5130
+ error ? /* @__PURE__ */ jsx26(RefusalLine, { error }) : null
5087
5131
  ] });
5088
5132
  }
5089
5133
  export {