@ai-matrx/records-ui 0.115.69 → 0.115.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pickers.cjs CHANGED
@@ -61,11 +61,11 @@ var import_react = require("react");
61
61
  var import_records2 = require("@ai-matrx/records");
62
62
  var import_react2 = require("@ai-matrx/records/react");
63
63
  var import_design_system = require("@ai-matrx/design-system");
64
- var import_data_table2 = require("@ai-matrx/design-system/data-table");
64
+ var import_data_table = require("@ai-matrx/design-system/data-table");
65
65
 
66
66
  // src/choiceLooks.ts
67
67
  var import_records = require("@ai-matrx/records");
68
- var import_data_table = require("@ai-matrx/design-system/data-table");
68
+ var import_table_style = require("@ai-matrx/design-system/data-table/table-style");
69
69
  function displayFormatOf(field) {
70
70
  const raw = field.display_format;
71
71
  if (!raw || typeof raw !== "object") return null;
@@ -75,7 +75,7 @@ function displayFormatOf(field) {
75
75
  return { id, options: options && typeof options === "object" ? options : {} };
76
76
  }
77
77
  function isStyleColor(v) {
78
- return typeof v === "string" && import_data_table.STYLE_COLORS.includes(v);
78
+ return typeof v === "string" && import_table_style.STYLE_COLORS.includes(v);
79
79
  }
80
80
  function choiceLooksOf(field) {
81
81
  const display = displayFormatOf(field);
@@ -132,9 +132,9 @@ function nextChoiceColor(worn) {
132
132
  function choiceChipLookOf(field, ...words) {
133
133
  for (const word of words) {
134
134
  const color = storedChoiceColor(field, word);
135
- if (color) return { className: import_data_table.CHOICE_CHIP_CLASS[color], color };
135
+ if (color) return { className: import_table_style.CHOICE_CHIP_CLASS[color], color };
136
136
  }
137
- return { className: import_data_table.NEUTRAL_CHIP_CLASS, color: null };
137
+ return { className: import_table_style.NEUTRAL_CHIP_CLASS, color: null };
138
138
  }
139
139
 
140
140
  // src/plainWords.ts
@@ -536,12 +536,12 @@ function ChoiceSwatch({ words, color, onColor }) {
536
536
  "button",
537
537
  {
538
538
  type: "button",
539
- "aria-label": `Colour for ${words}: ${color ? import_data_table2.STYLE_COLOR_LABELS[color] : "none"}`,
540
- title: color ? import_data_table2.STYLE_COLOR_LABELS[color] : "No colour",
539
+ "aria-label": `Colour for ${words}: ${color ? import_data_table.STYLE_COLOR_LABELS[color] : "none"}`,
540
+ title: color ? import_data_table.STYLE_COLOR_LABELS[color] : "No colour",
541
541
  "data-records-choice-swatch": color ?? "none",
542
542
  className: (0, import_design_system.cn)(
543
543
  "h-4 w-4 shrink-0 rounded-full",
544
- color ? import_data_table2.SWATCH_CLASS[color] : "border border-border bg-background"
544
+ color ? import_data_table.SWATCH_CLASS[color] : "border border-border bg-background"
545
545
  )
546
546
  }
547
547
  ) }),
@@ -558,17 +558,17 @@ function ChoiceSwatch({ words, color, onColor }) {
558
558
  className: (0, import_design_system.cn)("h-5 w-5 rounded-full border border-border bg-background", color === null && "ring-2 ring-ring ring-offset-1")
559
559
  }
560
560
  ),
561
- import_data_table2.STYLE_COLORS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
561
+ import_data_table.STYLE_COLORS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
562
562
  "button",
563
563
  {
564
564
  type: "button",
565
565
  role: "radio",
566
566
  "aria-checked": color === c,
567
- "aria-label": import_data_table2.STYLE_COLOR_LABELS[c],
568
- title: import_data_table2.STYLE_COLOR_LABELS[c],
567
+ "aria-label": import_data_table.STYLE_COLOR_LABELS[c],
568
+ title: import_data_table.STYLE_COLOR_LABELS[c],
569
569
  "data-records-choice-color": `${words}:${c}`,
570
570
  onClick: () => pick(c),
571
- className: (0, import_design_system.cn)("h-5 w-5 rounded-full", import_data_table2.SWATCH_CLASS[c], color === c && "ring-2 ring-ring ring-offset-1")
571
+ className: (0, import_design_system.cn)("h-5 w-5 rounded-full", import_data_table.SWATCH_CLASS[c], color === c && "ring-2 ring-ring ring-offset-1")
572
572
  },
573
573
  c
574
574
  ))
@@ -667,8 +667,7 @@ function lockedStructure(base) {
667
667
  return { ...base, structure: false, why: (what) => what === "structure" ? DATABASE_LOCKED_REASON : base.why(what) };
668
668
  }
669
669
 
670
- // src/host.tsx
671
- var import_jsx_runtime2 = require("react/jsx-runtime");
670
+ // src/tableRights.ts
672
671
  function tableRights(may, overallReason) {
673
672
  return {
674
673
  ...may,
@@ -677,6 +676,9 @@ function tableRights(may, overallReason) {
677
676
  };
678
677
  }
679
678
  var NO_RIGHTS = tableRights(NOT_ANSWERED_YET);
679
+
680
+ // src/host.tsx
681
+ var import_jsx_runtime2 = require("react/jsx-runtime");
680
682
  var NO_MEMBERS_REASON = "This app cannot offer the people in your organization on this screen yet, so there is nobody to pick. Type the person's name into a text field for now, and tell us \u2014 it is on our list, not yours.";
681
683
  var NO_UPLOAD_REASON = "This screen cannot take a file yet, so there is no chooser here rather than one that loses what you pick. Put a link to the file in a text field for now. It is on our list, not yours.";
682
684
  var HostContext = (0, import_react3.createContext)(null);
@@ -937,6 +939,7 @@ var import_react8 = require("react");
937
939
  var import_source = require("@ai-matrx/content-ir/source");
938
940
  var import_records4 = require("@ai-matrx/records");
939
941
  var import_design_system5 = require("@ai-matrx/design-system");
942
+ var import_outbound_react = require("@ai-matrx/kit/outbound-react");
940
943
  var import_jsx_runtime6 = require("react/jsx-runtime");
941
944
  var own = (event) => event.stopPropagation();
942
945
  function newerKindValue(field, value, opts = {}) {
@@ -985,11 +988,9 @@ function AddressLink({ value }) {
985
988
  const href = (0, import_records4.addressMapUrl)(value);
986
989
  if (!words || !href) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-muted-foreground", children: "\u2014" });
987
990
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
988
- "a",
991
+ import_outbound_react.OutboundLink,
989
992
  {
990
993
  href,
991
- target: "_blank",
992
- rel: "noopener noreferrer",
993
994
  className: "inline-flex min-w-0 items-center gap-1 text-primary hover:underline",
994
995
  title: "Open in maps",
995
996
  "data-records-address": "",
@@ -1037,7 +1038,7 @@ function marks(text, key) {
1037
1038
  const link = /^\[([^\]]+)\]\(([^)\s]+)\)$/.exec(tok);
1038
1039
  const href = (0, import_records4.safeLinkHref)(link?.[2] ?? "");
1039
1040
  out.push(
1040
- href ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline-offset-2 hover:underline", onClick: own, children: link?.[1] }, k) : link?.[1] ?? tok
1041
+ href ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_outbound_react.OutboundLink, { href, className: "text-primary underline-offset-2 hover:underline", onClick: own, children: link?.[1] }, k) : link?.[1] ?? tok
1041
1042
  );
1042
1043
  } else out.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: tok.slice(1, -1) }, k));
1043
1044
  last = at + tok.length;
@@ -2025,7 +2026,7 @@ function RelationPicker({ field, value, onChange, disabled, id, className, allow
2025
2026
  // src/buttonCell.tsx
2026
2027
  var import_react46 = require("react");
2027
2028
  var import_design_system30 = require("@ai-matrx/design-system");
2028
- var import_data_table8 = require("@ai-matrx/design-system/data-table");
2029
+ var import_data_table6 = require("@ai-matrx/design-system/data-table");
2029
2030
  var import_records26 = require("@ai-matrx/records");
2030
2031
  var import_react47 = require("@ai-matrx/records/react");
2031
2032
 
@@ -2083,7 +2084,8 @@ var import_react12 = require("react");
2083
2084
  var import_records9 = require("@ai-matrx/records");
2084
2085
  var import_react13 = require("@ai-matrx/records/react");
2085
2086
  var import_design_system9 = require("@ai-matrx/design-system");
2086
- var import_jsx_runtime10 = require("react/jsx-runtime");
2087
+
2088
+ // src/tablePickerEntries.ts
2087
2089
  var PLATFORM_TABLE_PREFIX = "records_ui_";
2088
2090
  function keptByPlatform(table) {
2089
2091
  return table.platform_owned === true || table.kept_by_the_app === true;
@@ -2127,6 +2129,9 @@ function madeOn(stamp) {
2127
2129
  if (Number.isNaN(at.getTime())) return null;
2128
2130
  return new Intl.DateTimeFormat(void 0, { month: "short", day: "numeric", year: "numeric" }).format(at);
2129
2131
  }
2132
+
2133
+ // src/tablePicking.tsx
2134
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2130
2135
  function usePickerTables() {
2131
2136
  const client = (0, import_react13.useRecordsClient)();
2132
2137
  const tables = (0, import_react13.useTables)();
@@ -2772,7 +2777,7 @@ var import_design_system22 = require("@ai-matrx/design-system");
2772
2777
  var import_react34 = require("@ai-matrx/records/react");
2773
2778
 
2774
2779
  // src/values.tsx
2775
- var import_data_table5 = require("@ai-matrx/design-system/data-table");
2780
+ var import_data_table3 = require("@ai-matrx/design-system/data-table");
2776
2781
  var import_field_formats4 = require("@ai-matrx/design-system/field-formats");
2777
2782
  var import_design_system21 = require("@ai-matrx/design-system");
2778
2783
 
@@ -2780,8 +2785,7 @@ var import_design_system21 = require("@ai-matrx/design-system");
2780
2785
  var import_react20 = require("react");
2781
2786
 
2782
2787
  // src/presentation.ts
2783
- var import_table_style = require("@ai-matrx/design-system/data-table/table-style");
2784
- var import_data_table3 = require("@ai-matrx/design-system/data-table");
2788
+ var import_table_style2 = require("@ai-matrx/design-system/data-table/table-style");
2785
2789
  var import_field_formats2 = require("@ai-matrx/design-system/field-formats");
2786
2790
  var import_records11 = require("@ai-matrx/records");
2787
2791
  var DRAWN_KINDS = /* @__PURE__ */ new Set(["select", "multi_select", "relation", "member", "person", "attachment", "file", "entity_reference", "checkbox", "boolean", "signature", "json"]);
@@ -3671,6 +3675,7 @@ var import_core5 = require("@ai-matrx/records/core");
3671
3675
  var import_react28 = require("react");
3672
3676
  var import_core4 = require("@ai-matrx/records/core");
3673
3677
  var import_design_system16 = require("@ai-matrx/design-system");
3678
+ var import_outbound_react2 = require("@ai-matrx/kit/outbound-react");
3674
3679
  var import_jsx_runtime18 = require("react/jsx-runtime");
3675
3680
  var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
3676
3681
  function wholeValueLine(pointer) {
@@ -3685,7 +3690,7 @@ function WholeValueCell({ words, pointer }) {
3685
3690
  words,
3686
3691
  "\u2026"
3687
3692
  ] }),
3688
- href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0, import_core4.wholeValueSize)(pointer)} in a file` })
3693
+ href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_outbound_react2.OutboundLink, { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, children: line }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0, import_core4.wholeValueSize)(pointer)} in a file` })
3689
3694
  ] });
3690
3695
  }
3691
3696
 
@@ -3694,9 +3699,10 @@ var import_field_formats5 = require("@ai-matrx/design-system/field-formats");
3694
3699
 
3695
3700
  // src/formattedValue.tsx
3696
3701
  var import_react29 = require("react");
3697
- var import_data_table4 = require("@ai-matrx/design-system/data-table");
3702
+ var import_data_table2 = require("@ai-matrx/design-system/data-table");
3698
3703
  var import_field_formats3 = require("@ai-matrx/design-system/field-formats");
3699
3704
  var import_design_system17 = require("@ai-matrx/design-system");
3705
+ var import_outbound_react3 = require("@ai-matrx/kit/outbound-react");
3700
3706
  var import_jsx_runtime19 = require("react/jsx-runtime");
3701
3707
  var LINK = "inline-flex min-w-0 items-center gap-1 text-primary hover:underline";
3702
3708
  var own2 = (event) => event.stopPropagation();
@@ -3767,16 +3773,14 @@ function rich(id, text, raw, format) {
3767
3773
  case "email":
3768
3774
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { href: `mailto:${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate", children: text }) });
3769
3775
  case "url":
3770
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { href: text.includes("://") ? text : `https://${text}`, target: "_blank", rel: "noopener noreferrer", className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate", children: text }) });
3776
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_outbound_react3.OutboundLink, { href: text.includes("://") ? text : `https://${text}`, className: LINK, onClick: own2, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate", children: text }) });
3771
3777
  case "phone":
3772
3778
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { href: `tel:${text.replace(/[^\d+]/g, "")}`, className: LINK, onClick: own2, title: text, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate tabular-nums", children: (0, import_field_formats3.formatPhone)(text) }) });
3773
3779
  case "address":
3774
3780
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3775
- "a",
3781
+ import_outbound_react3.OutboundLink,
3776
3782
  {
3777
3783
  href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(text)}`,
3778
- target: "_blank",
3779
- rel: "noopener noreferrer",
3780
3784
  className: LINK,
3781
3785
  title: "Open in maps",
3782
3786
  onClick: own2,
@@ -3832,8 +3836,8 @@ function FormattedValue({
3832
3836
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RatingStars, { value, max: format.options?.ratingMax ?? 5, onRate, selectFirst });
3833
3837
  }
3834
3838
  const result = (0, import_field_formats3.formatFieldValue)(value, format);
3835
- if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_data_table4.FormattedCell, { result });
3836
- return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_data_table4.FormattedCell, { result });
3839
+ if (!result.ok || result.empty || !def?.rich) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_data_table2.FormattedCell, { result });
3840
+ return rich(def.id, result.text, value, format) ?? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_data_table2.FormattedCell, { result });
3837
3841
  }
3838
3842
  function linkChipText(raw) {
3839
3843
  try {
@@ -3946,6 +3950,7 @@ function FilePicker({
3946
3950
  }
3947
3951
 
3948
3952
  // src/gridAttachments.tsx
3953
+ var import_outbound_react4 = require("@ai-matrx/kit/outbound-react");
3949
3954
  var import_jsx_runtime21 = require("react/jsx-runtime");
3950
3955
  function attachmentIdsOf(value) {
3951
3956
  return idsOf(value);
@@ -4002,11 +4007,9 @@ function AttachmentChip({ id, onRemove }) {
4002
4007
  const title = href ? `Open ${words}` : read?.why ?? FILE_CHIP_NO_PAGE;
4003
4008
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_design_system19.Badge, { variant: "secondary", className: "max-w-[14rem] gap-1 text-[11px]", "data-records-file-chip": id, title, children: [
4004
4009
  href ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4005
- "a",
4010
+ import_outbound_react4.OutboundLink,
4006
4011
  {
4007
4012
  href,
4008
- target: "_blank",
4009
- rel: "noreferrer",
4010
4013
  className: "truncate underline-offset-2 hover:underline",
4011
4014
  "data-records-file-link": read?.fileId ?? "",
4012
4015
  onClick: (event) => event.stopPropagation(),
@@ -4322,14 +4325,15 @@ function formulaSourceArchived(field, document2) {
4322
4325
  const keys = (field.config ?? {})[FORMULA_INPUT_KEYS];
4323
4326
  if (!Array.isArray(keys) || !document2) return null;
4324
4327
  for (const key of keys) {
4325
- const state = (0, import_records16.sourceArchivedOf)(document2[String(key)]);
4326
- if (state) return state;
4328
+ const state2 = (0, import_records16.sourceArchivedOf)(document2[String(key)]);
4329
+ if (state2) return state2;
4327
4330
  }
4328
4331
  return null;
4329
4332
  }
4330
4333
 
4331
4334
  // src/values.tsx
4332
4335
  var import_records17 = require("@ai-matrx/records");
4336
+ var import_outbound_react5 = require("@ai-matrx/kit/outbound-react");
4333
4337
  var import_jsx_runtime23 = require("react/jsx-runtime");
4334
4338
  function statusMark(field, item, document2) {
4335
4339
  const mark = statusMarkOf(field, item, document2);
@@ -4374,12 +4378,12 @@ function computedEmptyOf(field, document2) {
4374
4378
  return { kind: "formula" };
4375
4379
  }
4376
4380
  var SOURCE_ARCHIVED_WORDS = "Source archived";
4377
- function sourceArchivedSentence(state) {
4378
- if (!state.label) return "A column it reads is archived";
4379
- return state.table ? `${state.label} on ${state.table} is archived` : `${state.label} is archived`;
4381
+ function sourceArchivedSentence(state2) {
4382
+ if (!state2.label) return "A column it reads is archived";
4383
+ return state2.table ? `${state2.label} on ${state2.table} is archived` : `${state2.label} is archived`;
4380
4384
  }
4381
- function SourceArchivedValue({ state }) {
4382
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", title: sourceArchivedSentence(state), "data-records-source-archived": state.field_id ?? "", children: SOURCE_ARCHIVED_WORDS });
4385
+ function SourceArchivedValue({ state: state2 }) {
4386
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs italic text-muted-foreground", title: sourceArchivedSentence(state2), "data-records-source-archived": state2.field_id ?? "", children: SOURCE_ARCHIVED_WORDS });
4383
4387
  }
4384
4388
  var ABSENCE_WORDS = ABSENCE_WORD_LABEL;
4385
4389
  function renderValue(field, value, document2, labels, stillWaitingFor, look) {
@@ -4424,7 +4428,7 @@ function renderValue(field, value, document2, labels, stillWaitingFor, look) {
4424
4428
  const chosen = kind === "select" || kind === "multi_select";
4425
4429
  const chipOf = (item) => {
4426
4430
  const chipLook = choiceChipLookOf(field, item, scalarText(field, item, labels));
4427
- return { className: chipLook.className, tinted: chipLook.color !== null, dot: import_data_table5.SWATCH_CLASS[chipLook.color ?? "gray"] };
4431
+ return { className: chipLook.className, tinted: chipLook.color !== null, dot: import_data_table3.SWATCH_CLASS[chipLook.color ?? "gray"] };
4428
4432
  };
4429
4433
  if (chosen) {
4430
4434
  const items = Array.isArray(value) ? value : [value];
@@ -4454,12 +4458,10 @@ function renderValue(field, value, document2, labels, stillWaitingFor, look) {
4454
4458
  if (kind === "url" && typeof value === "string") {
4455
4459
  const href = value.includes("://") ? value : `https://${value}`;
4456
4460
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4457
- "a",
4461
+ import_outbound_react5.OutboundLink,
4458
4462
  {
4459
4463
  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",
4460
4464
  href,
4461
- target: "_blank",
4462
- rel: "noreferrer",
4463
4465
  title: value,
4464
4466
  "data-records-link-chip": "",
4465
4467
  onClick: (event) => event.stopPropagation(),
@@ -4533,12 +4535,12 @@ function scalarText(field, value, labels, stillWaitingFor) {
4533
4535
 
4534
4536
  // src/SourceArchivedNotice.tsx
4535
4537
  var import_jsx_runtime24 = require("react/jsx-runtime");
4536
- function bringBackLabel(state) {
4537
- return state.label ? `Bring back ${state.label}` : "Bring it back";
4538
+ function bringBackLabel(state2) {
4539
+ return state2.label ? `Bring back ${state2.label}` : "Bring it back";
4538
4540
  }
4539
4541
  function SourceArchivedNotice({ fieldId, tableId }) {
4540
4542
  const client = (0, import_react34.useRecordsClient)();
4541
- const [state, setState] = (0, import_react33.useState)(null);
4543
+ const [state2, setState] = (0, import_react33.useState)(null);
4542
4544
  const [busy, setBusy] = (0, import_react33.useState)(false);
4543
4545
  const [refused, setRefused] = (0, import_react33.useState)(null);
4544
4546
  const read = (0, import_react33.useCallback)(async () => {
@@ -4549,19 +4551,19 @@ function SourceArchivedNotice({ fieldId, tableId }) {
4549
4551
  (0, import_react33.useEffect)(() => {
4550
4552
  void read();
4551
4553
  }, [read]);
4552
- if (refused && !state) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RefusalNotice, { error: refused });
4553
- if (!state) return null;
4554
+ if (refused && !state2) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RefusalNotice, { error: refused });
4555
+ if (!state2) return null;
4554
4556
  const restore = async () => {
4555
- if (!state.field_id) return;
4557
+ if (!state2.field_id) return;
4556
4558
  setBusy(true);
4557
4559
  setRefused(null);
4558
- const done = await client.fieldRestore({ field_id: state.field_id });
4560
+ const done = await client.fieldRestore({ field_id: state2.field_id });
4559
4561
  setBusy(false);
4560
4562
  if (!done.ok) {
4561
4563
  setRefused(done.error);
4562
4564
  return;
4563
4565
  }
4564
- if (state.table_id) (0, import_react34.tableShapeChanged)(state.table_id);
4566
+ if (state2.table_id) (0, import_react34.tableShapeChanged)(state2.table_id);
4565
4567
  (0, import_react34.tableShapeChanged)(tableId);
4566
4568
  await read();
4567
4569
  };
@@ -4570,13 +4572,13 @@ function SourceArchivedNotice({ fieldId, tableId }) {
4570
4572
  {
4571
4573
  className: "flex flex-wrap items-center gap-2 rounded-md border border-border px-3 py-2",
4572
4574
  "data-testid": "source-archived-notice",
4573
- "data-field-id": state.field_id ?? "",
4575
+ "data-field-id": state2.field_id ?? "",
4574
4576
  children: [
4575
4577
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
4576
4578
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-sm", children: SOURCE_ARCHIVED_WORDS }),
4577
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: sourceArchivedSentence(state) })
4579
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: sourceArchivedSentence(state2) })
4578
4580
  ] }),
4579
- state.field_id ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_design_system22.Button, { type: "button", size: "sm", variant: "secondary", disabled: busy, onClick: () => void restore(), children: bringBackLabel(state) }) : null,
4581
+ state2.field_id ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_design_system22.Button, { type: "button", size: "sm", variant: "secondary", disabled: busy, onClick: () => void restore(), children: bringBackLabel(state2) }) : null,
4580
4582
  refused ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RefusalNotice, { error: refused, className: "basis-full" }) : null
4581
4583
  ]
4582
4584
  }
@@ -4591,23 +4593,25 @@ var import_react37 = require("@ai-matrx/records/react");
4591
4593
 
4592
4594
  // src/personTime.ts
4593
4595
  var import_react35 = require("react");
4594
- var import_table_style2 = require("@ai-matrx/design-system/data-table/table-style");
4595
- var zone = null;
4596
- var listeners = /* @__PURE__ */ new Set();
4596
+
4597
+ // src/personZone.ts
4598
+ var import_table_style3 = require("@ai-matrx/design-system/data-table/table-style");
4599
+ var import_global_slot = require("@ai-matrx/kit/global-slot");
4600
+ var state = (0, import_global_slot.globalSlot)("ai-matrx.records-ui.person-time-zone", () => ({
4601
+ zone: null,
4602
+ listeners: /* @__PURE__ */ new Set()
4603
+ }));
4597
4604
  function getPersonTimeZone() {
4598
- return zone;
4605
+ return state.zone;
4599
4606
  }
4600
- function usePersonTimeZone() {
4601
- return (0, import_react35.useSyncExternalStore)(
4602
- (cb) => {
4603
- listeners.add(cb);
4604
- return () => listeners.delete(cb);
4605
- },
4606
- () => zone,
4607
- () => null
4608
- );
4607
+ function subscribePersonTimeZone(listener) {
4608
+ state.listeners.add(listener);
4609
+ return () => {
4610
+ state.listeners.delete(listener);
4611
+ };
4609
4612
  }
4610
4613
  function personWallNow(at = /* @__PURE__ */ new Date()) {
4614
+ const zone = state.zone;
4611
4615
  if (!zone) return at;
4612
4616
  const parts = new Intl.DateTimeFormat("en-US", {
4613
4617
  timeZone: zone,
@@ -4623,6 +4627,15 @@ function personWallNow(at = /* @__PURE__ */ new Date()) {
4623
4627
  return new Date(n("year"), n("month") - 1, n("day"), n("hour"), n("minute"), n("second"));
4624
4628
  }
4625
4629
 
4630
+ // src/personTime.ts
4631
+ function usePersonTimeZone() {
4632
+ return (0, import_react35.useSyncExternalStore)(
4633
+ subscribePersonTimeZone,
4634
+ getPersonTimeZone,
4635
+ () => null
4636
+ );
4637
+ }
4638
+
4626
4639
  // src/Condition.tsx
4627
4640
  var import_jsx_runtime25 = require("react/jsx-runtime");
4628
4641
  var CONDITION_OPS = [
@@ -4650,10 +4663,10 @@ var RELATIVE_DAY_TERMS = [
4650
4663
  { kind: "past_days", label: "is in the past \u2026 days", takesDays: true }
4651
4664
  ];
4652
4665
  function relativeDayNode(fieldId, kind, days) {
4653
- const zone2 = getPersonTimeZone();
4666
+ const zone = getPersonTimeZone();
4654
4667
  const window2 = { relative: kind };
4655
4668
  if (RELATIVE_DAY_TERMS.find((t) => t.kind === kind)?.takesDays) window2["n"] = days ?? 7;
4656
- if (zone2) window2["tz"] = zone2;
4669
+ if (zone) window2["tz"] = zone;
4657
4670
  return { op: "within", args: [{ field: fieldId }, { const: window2 }] };
4658
4671
  }
4659
4672
  function relativeDayOf(expr) {
@@ -5832,14 +5845,14 @@ var import_records24 = require("@ai-matrx/records");
5832
5845
  // src/ButtonSettings.tsx
5833
5846
  var import_react42 = require("react");
5834
5847
  var import_design_system28 = require("@ai-matrx/design-system");
5835
- var import_data_table7 = require("@ai-matrx/design-system/data-table");
5848
+ var import_data_table5 = require("@ai-matrx/design-system/data-table");
5836
5849
  var import_records23 = require("@ai-matrx/records");
5837
5850
  var import_react43 = require("@ai-matrx/records/react");
5838
5851
 
5839
5852
  // src/AccentSwatches.tsx
5840
5853
  var import_records22 = require("@ai-matrx/records");
5841
5854
  var import_design_system27 = require("@ai-matrx/design-system");
5842
- var import_data_table6 = require("@ai-matrx/design-system/data-table");
5855
+ var import_data_table4 = require("@ai-matrx/design-system/data-table");
5843
5856
  var import_jsx_runtime30 = require("react/jsx-runtime");
5844
5857
  function AccentSwatches({ value, onChange, options = import_records22.PORTAL_ACCENTS, noneLabel = "App colour" }) {
5845
5858
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap gap-1.5", role: "radiogroup", "aria-label": "Colour", children: [
@@ -5863,10 +5876,10 @@ function AccentSwatches({ value, onChange, options = import_records22.PORTAL_ACC
5863
5876
  type: "button",
5864
5877
  role: "radio",
5865
5878
  "aria-checked": value === c,
5866
- "aria-label": import_data_table6.STYLE_COLOR_LABELS[c],
5867
- title: import_data_table6.STYLE_COLOR_LABELS[c],
5879
+ "aria-label": import_data_table4.STYLE_COLOR_LABELS[c],
5880
+ title: import_data_table4.STYLE_COLOR_LABELS[c],
5868
5881
  onClick: () => onChange(c),
5869
- className: (0, import_design_system27.cn)("h-7 w-7 rounded-full border-2", import_data_table6.SWATCH_CLASS[c], value === c ? "border-foreground" : "border-transparent")
5882
+ className: (0, import_design_system27.cn)("h-7 w-7 rounded-full border-2", import_data_table4.SWATCH_CLASS[c], value === c ? "border-foreground" : "border-transparent")
5870
5883
  },
5871
5884
  c
5872
5885
  ))
@@ -5946,7 +5959,7 @@ function ButtonSettingsEditor({
5946
5959
  AccentSwatches,
5947
5960
  {
5948
5961
  value: value.color ?? "",
5949
- options: import_data_table7.STYLE_COLORS,
5962
+ options: import_data_table5.STYLE_COLORS,
5950
5963
  noneLabel: "Plain",
5951
5964
  onChange: (next) => set({ color: next === "" ? void 0 : next })
5952
5965
  }
@@ -7011,12 +7024,12 @@ function sourceKindOf(field) {
7011
7024
  if (kind === "attachment") return "file";
7012
7025
  return null;
7013
7026
  }
7014
- function whatIsMissing(state) {
7015
- const noun = state.noun ?? "column";
7016
- const { type, label, via, pick, agg, of, relations, formulaFields } = state;
7017
- const relationTarget = state.relationTarget ?? "";
7027
+ function whatIsMissing(state2) {
7028
+ const noun = state2.noun ?? "column";
7029
+ const { type, label, via, pick, agg, of, relations, formulaFields } = state2;
7030
+ const relationTarget = state2.relationTarget ?? "";
7018
7031
  if (label.trim() === "") return `Give the ${noun} a name.`;
7019
- if (type === "entity_reference") return whatIsMissingForEntityReference(state.allowedTypes ?? []);
7032
+ if (type === "entity_reference") return whatIsMissingForEntityReference(state2.allowedTypes ?? []);
7020
7033
  if (type === "relation") {
7021
7034
  if (relationTarget.trim() === "") return `Choose the table this ${noun} points at.`;
7022
7035
  return null;
@@ -7371,6 +7384,8 @@ function NewColumnDefault({
7371
7384
  }
7372
7385
 
7373
7386
  // src/buttonCell.tsx
7387
+ var import_outbound_react6 = require("@ai-matrx/kit/outbound-react");
7388
+ var import_outbound = require("@ai-matrx/kit/outbound");
7374
7389
  var import_jsx_runtime33 = require("react/jsx-runtime");
7375
7390
  function buttonPressWords(label, pressed) {
7376
7391
  if (pressed.do === "open_url") return `${label} opened ${pressed.url}`;
@@ -7389,7 +7404,7 @@ function ButtonValue({ field, recordId, inCell }) {
7389
7404
  const [said2, setSaid] = (0, import_react46.useState)(null);
7390
7405
  const [settingUp, setSettingUp] = (0, import_react46.useState)(false);
7391
7406
  if (!b) return null;
7392
- const color = (0, import_data_table8.isStyleColor)(b.color) ? import_data_table8.CHOICE_CHIP_CLASS[b.color] : import_data_table8.NEUTRAL_CHIP_CLASS;
7407
+ const color = (0, import_data_table6.isStyleColor)(b.color) ? import_data_table6.CHOICE_CHIP_CLASS[b.color] : import_data_table6.NEUTRAL_CHIP_CLASS;
7393
7408
  const needs = (0, import_records26.buttonNeeds)(b);
7394
7409
  const tableId = field.entity_definition_id;
7395
7410
  const press = async () => {
@@ -7401,7 +7416,7 @@ function ButtonValue({ field, recordId, inCell }) {
7401
7416
  if (!answered.ok) return setSaid({ kind: "refused", error: answered.error });
7402
7417
  const pressed = answered.data;
7403
7418
  if (pressed.do === "open_url") {
7404
- const opened = typeof window !== "undefined" ? window.open(pressed.url, "_blank", "noopener,noreferrer") : null;
7419
+ const opened = typeof window !== "undefined" ? (0, import_outbound.openOutbound)(pressed.url, "_blank", "noopener") : null;
7405
7420
  return setSaid({ kind: "ran", says: opened ? `${b.label} opened.` : `${b.label} is ready:`, link: pressed.url });
7406
7421
  }
7407
7422
  setSaid({ kind: "ran", says: buttonPressWords(b.label, pressed) });
@@ -7435,7 +7450,7 @@ function ButtonValue({ field, recordId, inCell }) {
7435
7450
  said2?.kind === "ran" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("p", { className: "break-words", children: [
7436
7451
  said2.says,
7437
7452
  " ",
7438
- said2.link ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("a", { href: said2.link, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline", children: said2.link }) : null
7453
+ said2.link ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_outbound_react6.OutboundLink, { href: said2.link, className: "text-primary underline", children: said2.link }) : null
7439
7454
  ] }) : null,
7440
7455
  said2?.kind === "needs" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
7441
7456
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { children: said2.says }),
@@ -8952,11 +8967,17 @@ function ChoiceAnswer({
8952
8967
 
8953
8968
  // src/RecordsMount.tsx
8954
8969
  var import_react57 = require("react");
8955
- var import_react58 = require("@ai-matrx/records/react");
8956
- var import_jsx_runtime39 = require("react/jsx-runtime");
8970
+
8971
+ // src/dataSource.ts
8972
+ var import_global_slot2 = require("@ai-matrx/kit/global-slot");
8957
8973
  function personActor(userId) {
8958
8974
  return userId ? { actor: "user", user_id: userId } : { actor: "user" };
8959
8975
  }
8976
+ var dataSources = (0, import_global_slot2.globalSlot)("ai-matrx.records-ui.data-sources", () => /* @__PURE__ */ new WeakMap());
8977
+
8978
+ // src/RecordsMount.tsx
8979
+ var import_react58 = require("@ai-matrx/records/react");
8980
+ var import_jsx_runtime39 = require("react/jsx-runtime");
8960
8981
 
8961
8982
  // src/TablePickers.tsx
8962
8983
  var import_jsx_runtime40 = require("react/jsx-runtime");
@@ -8991,7 +9012,7 @@ function readTablesAnywhere(dataSource) {
8991
9012
  return read;
8992
9013
  }
8993
9014
  function useTablesAnywhere(dataSource) {
8994
- const [state, setState] = (0, import_react59.useState)({ loading: true, error: null, rows: [] });
9015
+ const [state2, setState] = (0, import_react59.useState)({ loading: true, error: null, rows: [] });
8995
9016
  (0, import_react59.useEffect)(() => {
8996
9017
  let live = true;
8997
9018
  void readTablesAnywhere(dataSource).then((result) => {
@@ -9001,7 +9022,7 @@ function useTablesAnywhere(dataSource) {
9001
9022
  live = false;
9002
9023
  };
9003
9024
  }, [dataSource]);
9004
- return state;
9025
+ return state2;
9005
9026
  }
9006
9027
  function TablePicker({ dataSource, value, onChange, disabled, tables }) {
9007
9028
  const own3 = useTablesAnywhere(dataSource);