@ai-matrx/records-ui 0.93.30 → 0.93.37

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/index.js CHANGED
@@ -597,7 +597,7 @@ import {
597
597
 
598
598
  // src/editors.tsx
599
599
  import { useCallback as useCallback3, useEffect as useEffect7, useRef as useRef5, useState as useState9 } from "react";
600
- import { allowsOtherValues, choiceValuesOf, coerceTypedAnswer, decideTypedChoice, isTheChosen, optionKey } from "@ai-matrx/records";
600
+ import { allowsOtherValues, choiceValuesOf, coerceTypedAnswer, decideTypedChoice, isTheChosen, optionKey as optionKey2 } from "@ai-matrx/records";
601
601
  import { useOptionalRecordsClient as useOptionalRecordsClient5 } from "@ai-matrx/records/react";
602
602
  import {
603
603
  BasicInput as BasicInput5,
@@ -1325,6 +1325,7 @@ import { Badge, Button as Button5 } from "@ai-matrx/design-system";
1325
1325
  // src/labels.tsx
1326
1326
  import { createContext as createContext2, useCallback, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo4, useRef, useState as useState4 } from "react";
1327
1327
  import { useRecordsClient } from "@ai-matrx/records/react";
1328
+ import { optionKey } from "@ai-matrx/records";
1328
1329
  import { jsx as jsx6 } from "react/jsx-runtime";
1329
1330
  var LabelContext = createContext2({
1330
1331
  // With no provider the resolver is ABSENT, not silently empty: a caller gets
@@ -1345,6 +1346,9 @@ function idsOf(value) {
1345
1346
  return [];
1346
1347
  }
1347
1348
  var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1349
+ function choiceKeyName(fieldId, key) {
1350
+ return `${fieldId}\0key\0${key}`;
1351
+ }
1348
1352
  function isId(value) {
1349
1353
  return typeof value === "string" && UUID.test(value);
1350
1354
  }
@@ -1411,7 +1415,10 @@ function RecordLabelProvider({ children }) {
1411
1415
  setNames((current) => {
1412
1416
  const next = { ...current };
1413
1417
  for (const option of result.data ?? []) {
1414
- next[option.id] = recordName(option.data, null, "Unnamed choice");
1418
+ const words2 = recordName(option.data, null, "Unnamed choice");
1419
+ next[option.id] = words2;
1420
+ const key = optionKey(option);
1421
+ if (key) next[choiceKeyName(field2.id, key)] = words2;
1415
1422
  }
1416
1423
  return next;
1417
1424
  });
@@ -1475,14 +1482,26 @@ function RecordLabelProvider({ children }) {
1475
1482
  },
1476
1483
  []
1477
1484
  );
1485
+ const rereadFor = useRef(/* @__PURE__ */ new Set());
1478
1486
  const lookup = useCallback(
1479
1487
  (field2, id) => {
1488
+ if (field2.type === "list" && !isId(id)) {
1489
+ const named = names[choiceKeyName(field2.id, id)];
1490
+ if (named !== void 0) return named;
1491
+ const once = choiceKeyName(field2.id, id);
1492
+ if (settled[field2.id] && !rereadFor.current.has(once)) {
1493
+ rereadFor.current.add(once);
1494
+ asked2.current.delete(field2.id);
1495
+ want(field2);
1496
+ }
1497
+ return null;
1498
+ }
1480
1499
  const known = names[id];
1481
1500
  if (known !== void 0) return known;
1482
1501
  if (settled[field2.id]) chase(field2, id);
1483
1502
  return null;
1484
1503
  },
1485
- [names, settled, chase]
1504
+ [names, settled, chase, want]
1486
1505
  );
1487
1506
  const waiting = useCallback((field2) => waitingLines[field2.id] ?? null, [waitingLines]);
1488
1507
  const value = useMemo4(() => ({ lookup, want, waiting }), [lookup, want, waiting]);
@@ -2564,7 +2583,7 @@ function TypedTextControl({ field: field2, value, onChange, disabled, id, onComm
2564
2583
  " ",
2565
2584
  needsChoices ? String(
2566
2585
  (Array.isArray(withoutAddition(judged.value).value) ? withoutAddition(judged.value).value : [withoutAddition(judged.value).value]).map((k) => {
2567
- const option = choices?.find((o) => optionKey(o) === k);
2586
+ const option = choices?.find((o) => optionKey2(o) === k);
2568
2587
  return option ? recordName(option.data, null, String(k)) : String(k);
2569
2588
  }).join(", ")
2570
2589
  ) : (() => {
@@ -2836,18 +2855,18 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
2836
2855
  const titleOf = (option) => recordName(option.data, null, "Unnamed choice");
2837
2856
  if (field2.multi) {
2838
2857
  const chosen = options.filter((option) => choiceValuesOf(value).some((v) => isTheChosen(option, v)));
2839
- const picked = new Set(chosen.map((option) => optionKey(option)));
2858
+ const picked = new Set(chosen.map((option) => optionKey2(option)));
2840
2859
  const toggles = /* @__PURE__ */ jsx12("div", { id: autoOpen ? void 0 : id, className: "flex flex-wrap gap-1", children: options.map((option) => /* @__PURE__ */ jsx12(
2841
2860
  Button6,
2842
2861
  {
2843
2862
  type: "button",
2844
2863
  size: "sm",
2845
- variant: picked.has(optionKey(option)) ? "default" : "outline",
2864
+ variant: picked.has(optionKey2(option)) ? "default" : "outline",
2846
2865
  disabled,
2847
2866
  onClick: () => {
2848
2867
  const next = new Set(picked);
2849
- if (next.has(optionKey(option))) next.delete(optionKey(option));
2850
- else next.add(optionKey(option));
2868
+ if (next.has(optionKey2(option))) next.delete(optionKey2(option));
2869
+ else next.add(optionKey2(option));
2851
2870
  onChange(next.size === 0 ? null : [...next]);
2852
2871
  },
2853
2872
  children: titleOf(option)
@@ -2873,7 +2892,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
2873
2892
  return /* @__PURE__ */ jsxs10(
2874
2893
  Select2,
2875
2894
  {
2876
- value: current ? optionKey(current) : "",
2895
+ value: current ? optionKey2(current) : "",
2877
2896
  disabled: disabled ?? false,
2878
2897
  onValueChange: (next) => onChange(next === "" ? null : next),
2879
2898
  ...autoOpen ? {
@@ -2885,7 +2904,7 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
2885
2904
  } : {},
2886
2905
  children: [
2887
2906
  /* @__PURE__ */ jsx12(SelectTrigger2, { id, size: "sm", children: /* @__PURE__ */ jsx12(SelectValue2, { placeholder: "Choose" }) }),
2888
- /* @__PURE__ */ jsx12(SelectContent2, { children: options.map((option) => /* @__PURE__ */ jsx12(SelectItem2, { value: optionKey(option), children: titleOf(option) }, option.id)) })
2907
+ /* @__PURE__ */ jsx12(SelectContent2, { children: options.map((option) => /* @__PURE__ */ jsx12(SelectItem2, { value: optionKey2(option), children: titleOf(option) }, option.id)) })
2889
2908
  ]
2890
2909
  }
2891
2910
  );
@@ -2933,7 +2952,7 @@ function OpenChoicePicker({
2933
2952
  if (field2.multi) {
2934
2953
  const existing = current.map((v) => {
2935
2954
  const option = options.find((o) => isTheChosen(o, v));
2936
- return option ? optionKey(option) : String(v);
2955
+ return option ? optionKey2(option) : String(v);
2937
2956
  });
2938
2957
  const has = existing.some((v) => v.toLowerCase() === word.toLowerCase());
2939
2958
  const list = has ? existing.filter((v) => v.toLowerCase() !== word.toLowerCase()) : [...existing, word];
@@ -3006,7 +3025,7 @@ function OpenChoicePicker({
3006
3025
  })),
3007
3026
  onPick: (optionId) => {
3008
3027
  const option = options.find((o) => o.id === optionId);
3009
- if (option) choose(optionKey(option));
3028
+ if (option) choose(optionKey2(option));
3010
3029
  },
3011
3030
  empty: q === "" ? /* @__PURE__ */ jsx12("p", { className: "p-2 text-xs text-muted-foreground", children: "No choices yet \u2014 type one to add it." }) : null,
3012
3031
  add,
@@ -3933,6 +3952,10 @@ function scalarText(field2, value, labels, stillWaitingFor) {
3933
3952
  if (isId(value) && (field2.type === "list" || field2.type === "relation")) {
3934
3953
  return labels?.(field2, String(value)) ?? stillWaitingFor ?? "Loading\u2026";
3935
3954
  }
3955
+ if (field2.type === "list" && typeof value === "string" && labels) {
3956
+ const words2 = labels(field2, value);
3957
+ if (words2) return words2;
3958
+ }
3936
3959
  const shownAs = shownAsOf(field2);
3937
3960
  if (shownAs) {
3938
3961
  const said = formatFieldValue3(value, shownAs);
@@ -4533,6 +4556,13 @@ function GridCell({
4533
4556
  onAskWhoChanged
4534
4557
  }) {
4535
4558
  const ui = useRecordsUi();
4559
+ const saidAt = useRef8(0);
4560
+ const sayWhyNot = () => {
4561
+ if (Date.now() - saidAt.current < 4e3) return;
4562
+ saidAt.current = Date.now();
4563
+ const why = fieldIsEditable(field2) ? `${fieldName(field2)} \u2014 ${whyNot ?? "you cannot change this record"}` : `${fieldName(field2)} is worked out by the system, so it cannot be typed in`;
4564
+ ui.notify?.error(why);
4565
+ };
4536
4566
  const open = Boolean(
4537
4567
  editing && editing.editing?.rowId === row.id && editing.editing.key === field2.key
4538
4568
  );
@@ -4651,6 +4681,7 @@ function GridCell({
4651
4681
  event.preventDefault();
4652
4682
  event.stopPropagation();
4653
4683
  if (editable) editing?.begin({ rowId: row.id, key: field2.key });
4684
+ else sayWhyNot();
4654
4685
  },
4655
4686
  onKeyDown: (event) => {
4656
4687
  if (editable && (event.key === "Enter" || event.key === "F2")) {
@@ -4666,7 +4697,9 @@ function GridCell({
4666
4697
  if (editable && isTypedCharacter(event) && typingOpens(field2) !== "none") {
4667
4698
  event.preventDefault();
4668
4699
  editing?.begin({ rowId: row.id, key: field2.key }, event.key);
4700
+ return;
4669
4701
  }
4702
+ if (!editable && (event.key === "Enter" || event.key === "F2" || isTypedCharacter(event))) sayWhyNot();
4670
4703
  },
4671
4704
  tabIndex: editable || onAskWhoChanged ? 0 : void 0,
4672
4705
  children: /* @__PURE__ */ jsx18(
@@ -5425,16 +5458,26 @@ import { tableShapeChanged, useRecordsClient as useRecordsClient6 } from "@ai-ma
5425
5458
  import { Button as Button12, Select as Select3, SelectContent as SelectContent3, SelectItem as SelectItem3, SelectTrigger as SelectTrigger3, SelectValue as SelectValue3 } from "@ai-matrx/design-system";
5426
5459
  import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
5427
5460
  var RETYPE_TARGETS = [
5428
- { behaviour: "text", label: "Text", holds: "words" },
5429
- { behaviour: "range", label: "Number", holds: "a number" },
5430
- { behaviour: "boolean", label: "Yes / no", holds: "a yes or a no" }
5461
+ { id: "text", behaviour: "text", kind: null, label: "Text", holds: "words" },
5462
+ { id: "number", behaviour: "range", kind: "number", label: "Number", holds: "a number" },
5463
+ // A DATE is a `range` of kind date: `migrate_retype` alone cannot say "date" (it keeps the old
5464
+ // kind, so every date would be kept aside), so this one goes through `custom.field_update`'s own
5465
+ // retype arm (`parity_type: datetime`), which converts on the SAME trigger and keeps what does not
5466
+ // fit in `_retired` with the reason — measured on the live store 2026-09-28.
5467
+ { id: "date", behaviour: "range", kind: "date", label: "Date", holds: "a date" },
5468
+ { id: "checkbox", behaviour: "boolean", kind: null, label: "Yes / no", holds: "a yes or a no" }
5431
5469
  ];
5432
5470
  var PREVIEW_GROUPS = 1e3;
5433
5471
  function retypeableFrom(field2) {
5434
5472
  const behaviour = String(field2.type);
5435
- if (behaviour !== "text" && behaviour !== "range" && behaviour !== "boolean") return false;
5473
+ return behaviour === "text" || behaviour === "range" || behaviour === "boolean";
5474
+ }
5475
+ function currentTarget(field2) {
5436
5476
  const kind = String(editorKindFor(field2));
5437
- return kind !== "datetime" && kind !== "date";
5477
+ if (String(field2.type) === "boolean") return "checkbox";
5478
+ if (kind === "datetime" || kind === "date") return "date";
5479
+ if (String(field2.type) === "range") return "number";
5480
+ return "text";
5438
5481
  }
5439
5482
  function FieldRetype({ field: field2, tableId, onRetyped }) {
5440
5483
  const client = useRecordsClient6();
@@ -5445,7 +5488,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
5445
5488
  const [busy, setBusy] = useState17(false);
5446
5489
  const [said, setSaid] = useState17(null);
5447
5490
  const name = fieldName(field2);
5448
- const targets = RETYPE_TARGETS.filter((t) => t.behaviour !== String(field2.type));
5491
+ const targets = RETYPE_TARGETS.filter((t) => t.id !== currentTarget(field2));
5449
5492
  useEffect14(() => {
5450
5493
  if (!to) return;
5451
5494
  let cancelled = false;
@@ -5460,7 +5503,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
5460
5503
  return;
5461
5504
  }
5462
5505
  const groups = answer.data.map((row) => ({ value: row.groups[field2.key] ?? null, count: row.row_count }));
5463
- setPreview(previewRetype({ type: to.behaviour }, groups, answer.data.length >= PREVIEW_GROUPS));
5506
+ setPreview(previewRetype({ type: to.behaviour, kind: to.kind }, groups, answer.data.length >= PREVIEW_GROUPS));
5464
5507
  });
5465
5508
  return () => {
5466
5509
  cancelled = true;
@@ -5470,22 +5513,35 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
5470
5513
  return /* @__PURE__ */ jsxs18("p", { className: "text-[11px] text-muted-foreground", "data-records-retype": "not-here", children: [
5471
5514
  name,
5472
5515
  " holds ",
5473
- String(editorKindFor(field2)) === "datetime" ? "dates" : "records picked from a list or another table",
5474
- ", so what it holds is not changed here \u2014 add a new column and move the values across."
5516
+ String(field2.type) === "formula" ? "a value the table works out" : "records picked from a list or another table",
5517
+ ", and the store keeps those as record ids \u2014 turned into words or numbers they would read as ids, so it is not changed here."
5475
5518
  ] });
5476
5519
  }
5477
5520
  const change = async () => {
5478
5521
  if (!to) return;
5479
5522
  setBusy(true);
5480
5523
  setRefusal(null);
5481
- const done = await client.migrateRetype({ field_id: field2.id, to: to.behaviour });
5482
- setBusy(false);
5483
- if (!done.ok) {
5484
- setRefusal(done.error);
5485
- return;
5524
+ let holding;
5525
+ let aside;
5526
+ if (to.id === "date") {
5527
+ const done = await client.fieldUpdate({ field_id: field2.id, patch: { parity_type: "datetime" } });
5528
+ setBusy(false);
5529
+ if (!done.ok) {
5530
+ setRefusal(done.error);
5531
+ return;
5532
+ }
5533
+ holding = preview?.converts ?? 0;
5534
+ aside = preview?.keptAside ?? 0;
5535
+ } else {
5536
+ const done = await client.migrateRetype({ field_id: field2.id, to: to.behaviour });
5537
+ setBusy(false);
5538
+ if (!done.ok) {
5539
+ setRefusal(done.error);
5540
+ return;
5541
+ }
5542
+ holding = done.data.records_still_holding_a_value ?? 0;
5543
+ aside = done.data.values_in_retired_for_this_field ?? 0;
5486
5544
  }
5487
- const holding = done.data.records_still_holding_a_value ?? 0;
5488
- const aside = done.data.values_in_retired_for_this_field ?? 0;
5489
5545
  setSaid(
5490
5546
  `${name} now holds ${to.holds}. ${holding} ${holding === 1 ? "record holds" : "records hold"} a value` + (aside > 0 ? `; ${aside} ${aside === 1 ? "value that did not fit was" : "values that did not fit were"} kept with ${aside === 1 ? "its record" : "their records"}, with the reason.` : ".")
5491
5547
  );
@@ -5496,9 +5552,9 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
5496
5552
  };
5497
5553
  return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1.5", "data-records-retype": "", children: [
5498
5554
  /* @__PURE__ */ jsxs18("div", { className: "flex flex-wrap items-center gap-2", children: [
5499
- /* @__PURE__ */ jsxs18(Select3, { value: to?.behaviour ?? "", onValueChange: (next) => setTo(targets.find((t) => t.behaviour === next) ?? null), children: [
5555
+ /* @__PURE__ */ jsxs18(Select3, { value: to?.id ?? "", onValueChange: (next) => setTo(targets.find((t) => t.id === next) ?? null), children: [
5500
5556
  /* @__PURE__ */ jsx22(SelectTrigger3, { size: "sm", "aria-label": "Change what this column holds", className: "w-auto min-w-[12rem]", children: /* @__PURE__ */ jsx22(SelectValue3, { placeholder: "Change what this column holds" }) }),
5501
- /* @__PURE__ */ jsx22(SelectContent3, { children: targets.map((t) => /* @__PURE__ */ jsx22(SelectItem3, { value: t.behaviour, children: t.label }, t.behaviour)) })
5557
+ /* @__PURE__ */ jsx22(SelectContent3, { children: targets.map((t) => /* @__PURE__ */ jsx22(SelectItem3, { value: t.id, children: t.label }, t.id)) })
5502
5558
  ] }),
5503
5559
  to ? /* @__PURE__ */ jsx22(Button12, { size: "sm", disabled: busy || asking || preview === null, onClick: () => void change(), "data-records-retype-go": "", children: busy ? "Changing\u2026" : `Change to ${to.label}` }) : null,
5504
5560
  to ? /* @__PURE__ */ jsx22(Button12, { size: "sm", variant: "ghost", onClick: () => setTo(null), disabled: busy, children: "Cancel" }) : null
@@ -7317,7 +7373,7 @@ function entityReferenceKindsOf(field2) {
7317
7373
 
7318
7374
  // src/gridColors.tsx
7319
7375
  import { useCallback as useCallback8, useEffect as useEffect18, useMemo as useMemo12, useState as useState21 } from "react";
7320
- import { optionKey as optionKey2, optionLabel as optionLabel2 } from "@ai-matrx/records";
7376
+ import { optionKey as optionKey3, optionLabel as optionLabel2 } from "@ai-matrx/records";
7321
7377
  import { useRecordsClient as useRecordsClient10 } from "@ai-matrx/records/react";
7322
7378
  import {
7323
7379
  Button as Button15,
@@ -7392,7 +7448,7 @@ function useChoiceOptions(fields, keys) {
7392
7448
  function lookOf(option) {
7393
7449
  const raw = option.data?.["color"];
7394
7450
  const color = typeof raw === "string" && STYLE_COLORS4.includes(raw) ? raw : void 0;
7395
- return { id: String(option.id), key: optionKey2(option), label: optionLabel2(option), ...color ? { color } : {} };
7451
+ return { id: String(option.id), key: optionKey3(option), label: optionLabel2(option), ...color ? { color } : {} };
7396
7452
  }
7397
7453
  function paintByOption(style, fields, index, lookup) {
7398
7454
  if (index.size === 0) return { style, documentOf: (doc) => doc, choiceColorFor: lookup };
@@ -8074,7 +8130,7 @@ function SummarySheetControls({
8074
8130
 
8075
8131
  // src/pasteValues.ts
8076
8132
  import { predictValueRefusals } from "@ai-matrx/records/core";
8077
- import { coerceTypedAnswer as coerceTypedAnswer2, optionKey as optionKey3 } from "@ai-matrx/records";
8133
+ import { coerceTypedAnswer as coerceTypedAnswer2, optionKey as optionKey4 } from "@ai-matrx/records";
8078
8134
  function wordForStoredChoice(options, value) {
8079
8135
  if (options === void 0 || typeof value !== "string" || value === "") return null;
8080
8136
  for (const label of options.labels) {
@@ -8087,7 +8143,7 @@ function choiceOptionsOf(options) {
8087
8143
  const labels = [];
8088
8144
  for (const option of options) {
8089
8145
  const id = option.id;
8090
- const key = optionKey3(option);
8146
+ const key = optionKey4(option);
8091
8147
  const label = recordName(option.data, null, "");
8092
8148
  if (label) {
8093
8149
  labels.push(label);
@@ -9492,7 +9548,10 @@ function columnForField(field2, editing, mayWriteRow, whyNotRow, look, onAskWhoC
9492
9548
  // The type is in the header's tooltip rather than a second header row: one
9493
9549
  // row of headers, always — and it is the parity type's own WORD, not a
9494
9550
  // token (`Long text`, never `long_text`).
9495
- className: "align-top",
9551
+ // Top-aligned where a value may wrap to several lines; on a phone a cell never wraps (one line,
9552
+ // scrolled sideways) and the row is as tall as its 44 px tick box, so the value sits in the
9553
+ // middle beside the box — top-aligned it sat ~10 px above it (merged-grid review 2, 390 px).
9554
+ className: "sm:align-top max-sm:align-middle",
9496
9555
  ...{ title: fieldTypeLabel(field2) }
9497
9556
  };
9498
9557
  }
@@ -9522,6 +9581,12 @@ function PastePreview({
9522
9581
  "aria-label": "What this paste will write",
9523
9582
  "data-matrx-paste-preview": true,
9524
9583
  className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",
9584
+ onKeyDown: (event) => {
9585
+ if (event.key !== "Escape") return;
9586
+ event.preventDefault();
9587
+ event.stopPropagation();
9588
+ if (!busy) onCancel();
9589
+ },
9525
9590
  children: /* @__PURE__ */ jsxs30("div", { className: "flex max-h-[80vh] w-full max-w-2xl flex-col gap-3 overflow-auto rounded-lg border bg-background p-4 shadow-lg", children: [
9526
9591
  /* @__PURE__ */ jsxs30("div", { className: "flex items-baseline justify-between gap-3", children: [
9527
9592
  /* @__PURE__ */ jsx34("h2", { className: "text-sm font-medium", children: outcome ? "What was written" : "Before this is written" }),
@@ -9597,11 +9662,13 @@ function PastePreview({
9597
9662
  ". Add the columns first and paste again."
9598
9663
  ] }) : null,
9599
9664
  /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-end gap-2 pt-1", children: [
9600
- /* @__PURE__ */ jsx34(Button22, { size: "sm", variant: "ghost", onClick: onCancel, disabled: busy, children: "Cancel" }),
9665
+ /* @__PURE__ */ jsx34(Button22, { size: "sm", variant: "ghost", onClick: onCancel, disabled: busy, autoFocus: nothingToDo, children: "Cancel" }),
9601
9666
  /* @__PURE__ */ jsx34(
9602
9667
  Button22,
9603
9668
  {
9604
9669
  size: "sm",
9670
+ autoFocus: !nothingToDo,
9671
+ "data-matrx-paste-confirm": "",
9605
9672
  disabled: busy || nothingToDo,
9606
9673
  onClick: () => {
9607
9674
  setBusy(true);
@@ -9621,7 +9688,7 @@ function Outcome({ outcome, onClose }) {
9621
9688
  return /* @__PURE__ */ jsxs30(Fragment11, { children: [
9622
9689
  /* @__PURE__ */ jsx34("p", { className: "text-sm", "data-matrx-paste-outcome": whole ? "whole" : "partial", children: whole ? `All ${outcome.readBack} ${outcome.readBack === 1 ? "value is" : "values are"} in the table \u2014 read back out of it, not just accepted.` : `${outcome.readBack} of ${outcome.readBack + outcome.missing} values are in the table. The rest are not, and nothing was lost from what you copied \u2014 it is still on your clipboard.` }),
9623
9690
  outcome.refusals.length > 0 ? /* @__PURE__ */ jsx34("ul", { className: "flex flex-col gap-1", children: outcome.refusals.slice(0, 8).map((why, index) => /* @__PURE__ */ jsx34("li", { className: "text-xs text-muted-foreground", children: why }, index)) }) : null,
9624
- /* @__PURE__ */ jsx34("div", { className: "flex justify-end pt-1", children: /* @__PURE__ */ jsx34(Button22, { size: "sm", onClick: onClose, children: "Close" }) })
9691
+ /* @__PURE__ */ jsx34("div", { className: "flex justify-end pt-1", children: /* @__PURE__ */ jsx34(Button22, { size: "sm", onClick: onClose, autoFocus: true, children: "Close" }) })
9625
9692
  ] });
9626
9693
  }
9627
9694
  function PlanTable({ plan }) {