@nivaro/react 0.3.36 → 0.3.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.
Files changed (102) hide show
  1. package/dist/components/slots/CommentsSlot.js +44 -36
  2. package/dist/full.css +1 -1
  3. package/dist/hooks/useSessionRecorder.js +1 -1
  4. package/dist/index.d.ts +9 -1
  5. package/dist/shared/components/AgentBadge.js +26 -0
  6. package/dist/shared/components/AgentQuestionsCard.js +198 -0
  7. package/dist/shared/components/ItemEditForm.js +3329 -3263
  8. package/dist/shared/components/McpConnectionScope.js +480 -0
  9. package/dist/shared/components/MyWorkView.js +223 -208
  10. package/dist/shared/components/RecordReadView.js +620 -575
  11. package/dist/shared/components/chat/ChatPanel.js +683 -671
  12. package/dist/shared/components/imports/DownloadSampleButton.js +69 -0
  13. package/dist/shared/components/imports/ImportConsole.js +106 -104
  14. package/dist/shared/components/imports/RunDetailSheet.js +11 -10
  15. package/dist/shared/components/item-edit/FieldAffordances.js +32 -32
  16. package/dist/shared/components/item-edit/FormTour.js +279 -0
  17. package/dist/shared/components/item-edit/GroupSection.js +377 -360
  18. package/dist/shared/components/item-edit/PersonalDefaultControl.js +28 -28
  19. package/dist/shared/components/item-edit/entry/EntryStrip.js +30 -26
  20. package/dist/shared/components/item-edit/form-density.js +36 -0
  21. package/dist/shared/components/item-edit/useFormUsageBeacon.js +59 -46
  22. package/dist/shared/components/item-edit/usePersonalDefaults.js +312 -296
  23. package/dist/shared/components/layout-editor/AddPanel.js +349 -192
  24. package/dist/shared/components/layout-editor/DesignNode.js +126 -112
  25. package/dist/shared/components/layout-editor/EditorTopBar.js +123 -103
  26. package/dist/shared/components/layout-editor/LayoutEditor.js +829 -751
  27. package/dist/shared/components/layout-editor/PlaceTools.js +334 -0
  28. package/dist/shared/components/layout-editor/SlashInsert.js +252 -0
  29. package/dist/shared/components/layout-editor/StructureMenu.js +285 -242
  30. package/dist/shared/components/layout-editor/add-target.js +54 -43
  31. package/dist/shared/components/layout-editor/ai-forms/AiComposer.js +238 -155
  32. package/dist/shared/components/layout-editor/ai-forms/AiFormsButton.js +1 -1
  33. package/dist/shared/components/layout-editor/ai-forms/ai-forms-api.js +15 -12
  34. package/dist/shared/components/layout-editor/dnd/LayoutDndProvider.js +347 -189
  35. package/dist/shared/components/layout-editor/dnd/TrashZone.js +60 -32
  36. package/dist/shared/components/layout-editor/dnd/UndoChip.js +76 -0
  37. package/dist/shared/components/layout-editor/dnd/merge-drop.js +33 -0
  38. package/dist/shared/components/layout-editor/dnd/multi-drop.js +87 -0
  39. package/dist/shared/components/layout-editor/dnd/node.js +115 -105
  40. package/dist/shared/components/layout-editor/dnd/sensors.js +23 -0
  41. package/dist/shared/components/layout-editor/dnd/trash-drop.js +34 -28
  42. package/dist/shared/components/layout-editor/dnd/trash-links.js +97 -0
  43. package/dist/shared/components/layout-editor/even-row.js +86 -0
  44. package/dist/shared/components/layout-editor/field-list.js +99 -0
  45. package/dist/shared/components/layout-editor/format-painter.js +102 -0
  46. package/dist/shared/components/layout-editor/grid-guides.js +15 -13
  47. package/dist/shared/components/layout-editor/inspector/BehaviourSettings.js +150 -132
  48. package/dist/shared/components/layout-editor/inspector/BulkInspector.js +57 -53
  49. package/dist/shared/components/layout-editor/inspector/EvenRowAction.js +31 -0
  50. package/dist/shared/components/layout-editor/inspector/GroupInspector.js +154 -141
  51. package/dist/shared/components/layout-editor/inspector/Inspector.js +209 -178
  52. package/dist/shared/components/layout-editor/inspector/LookTab.js +106 -98
  53. package/dist/shared/components/layout-editor/inspector/RulesTab.js +38 -37
  54. package/dist/shared/components/layout-editor/inspector/kit.js +280 -223
  55. package/dist/shared/components/layout-editor/keyboard-move.js +15 -15
  56. package/dist/shared/components/layout-editor/lint/LabelStyle.js +201 -0
  57. package/dist/shared/components/layout-editor/lint/LintPanel.js +132 -84
  58. package/dist/shared/components/layout-editor/lint/lint-api.js +65 -28
  59. package/dist/shared/components/layout-editor/nav/NavTools.js +14 -12
  60. package/dist/shared/components/layout-editor/nav/ZoomControls.js +145 -0
  61. package/dist/shared/components/layout-editor/nav/useEditorNav.js +34 -32
  62. package/dist/shared/components/layout-editor/nav/view-prefs.js +100 -15
  63. package/dist/shared/components/layout-editor/outputs/LayoutFile.js +89 -0
  64. package/dist/shared/components/layout-editor/outputs/OutputsButton.js +272 -195
  65. package/dist/shared/components/layout-editor/outputs/layout-file-plan.js +176 -0
  66. package/dist/shared/components/layout-editor/outputs/output-api.js +71 -37
  67. package/dist/shared/components/layout-editor/overview/describe-conditions.js +16 -11
  68. package/dist/shared/components/layout-editor/overview/purpose.js +5 -5
  69. package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
  70. package/dist/shared/components/layout-editor/pin.js +37 -19
  71. package/dist/shared/components/layout-editor/place-clip.js +257 -0
  72. package/dist/shared/components/layout-editor/preview/PreviewModes.js +27 -26
  73. package/dist/shared/components/layout-editor/preview/PreviewPanes.js +148 -117
  74. package/dist/shared/components/layout-editor/preview/SampleRecord.js +113 -0
  75. package/dist/shared/components/layout-editor/preview/preview-model.js +79 -60
  76. package/dist/shared/components/layout-editor/preview/sample-record.js +105 -0
  77. package/dist/shared/components/layout-editor/removed-log.js +151 -0
  78. package/dist/shared/components/layout-editor/reuse/LibraryRows.js +109 -78
  79. package/dist/shared/components/layout-editor/reuse/linked-sections.js +373 -0
  80. package/dist/shared/components/layout-editor/revert-element.js +140 -0
  81. package/dist/shared/components/layout-editor/section-structure.js +193 -170
  82. package/dist/shared/components/layout-editor/settings/EntrySection.js +63 -45
  83. package/dist/shared/components/layout-editor/settings/LayoutSection.js +63 -32
  84. package/dist/shared/components/layout-editor/settings/ResolveSettings.js +179 -137
  85. package/dist/shared/components/layout-editor/settings/WhoSection.js +18 -17
  86. package/dist/shared/components/layout-editor/settings/settings-registry.js +24 -0
  87. package/dist/shared/components/layout-editor/shortcuts.js +21 -16
  88. package/dist/shared/components/layout-editor/structure-ops.js +221 -195
  89. package/dist/shared/components/layout-editor/usage/UsagePanel.js +133 -85
  90. package/dist/shared/components/layout-editor/usage/refusal-lens.js +130 -0
  91. package/dist/shared/components/layout-editor/usage/usage-api.js +12 -11
  92. package/dist/shared/components/panels/CommentPanel.js +47 -45
  93. package/dist/shared/components/panels/RevisionsPanel.js +66 -64
  94. package/dist/shared/components/panels/TaskPanel.js +395 -332
  95. package/dist/shared/components/profile/AgentsPanel.js +196 -147
  96. package/dist/shared/components/profile/ConnectionRollback.js +329 -0
  97. package/dist/shared/components/profile/MyDefaultsCard.js +526 -520
  98. package/dist/shared/lib/entry-config.js +22 -22
  99. package/dist/shared/lib/form-usage-beacon.js +91 -55
  100. package/dist/shared/lib/layout-lint.js +530 -284
  101. package/dist/shared/lib/layout-resolve.js +58 -44
  102. package/package.json +1 -1
@@ -1,52 +1,58 @@
1
- import { UNGROUPED_KEY as p, HEADER_GROUP_KEY as d } from "../../../lib/layout-ops.js";
2
- import { nodeData as f, TABLE_FORM_ZONES as k } from "./collision.js";
3
- const g = "layout-trash";
4
- function y(o) {
5
- const e = o;
1
+ import { UNGROUPED_KEY as f, HEADER_GROUP_KEY as d } from "../../../lib/layout-ops.js";
2
+ import { nodeData as h, TABLE_FORM_ZONES as k } from "./collision.js";
3
+ const D = "layout-trash";
4
+ function y(n) {
5
+ const e = n;
6
6
  return (e == null ? void 0 : e.layoutTrash) === !0 ? e : null;
7
7
  }
8
- function D(o, e) {
9
- if (!o || !e || e.add) return null;
8
+ function s(n, e) {
9
+ if (!n || !e || e.add) return null;
10
10
  const t = e.target;
11
11
  if (t.kind === "group") {
12
- if (t.key === p || k.includes(t.key) || !o.groups.some((r) => r.key === t.key)) return null;
13
- const n = [], l = (r) => {
14
- for (const a of o.groups) a.parent_key === r && l(a.key);
15
- n.push(r);
12
+ if (t.key === f || k.includes(t.key) || !n.groups.some((l) => l.key === t.key)) return null;
13
+ const r = [], u = (l) => {
14
+ for (const a of n.groups) a.parent_key === l && u(a.key);
15
+ r.push(l);
16
16
  };
17
- l(t.key);
18
- const u = new Set(n), c = o.placements.filter((r) => r.group_key && u.has(r.group_key)).length;
17
+ u(t.key);
18
+ const p = new Set(r), c = n.placements.filter((l) => l.group_key && p.has(l.group_key)).length;
19
19
  return {
20
- ops: n.map((r) => ({ op: "group_remove", key: r, placements: "delete" })),
20
+ ops: r.map((l) => ({ op: "group_remove", key: l, placements: "delete" })),
21
21
  kind: "section",
22
22
  holds: c
23
23
  };
24
24
  }
25
- const s = t.kind === "header" ? d : t.group_key ?? null;
26
- return o.placements.some(
27
- (n) => n.field === t.field && (n.group_key ?? null) === s
25
+ const o = t.kind === "header" ? d : t.group_key ?? null;
26
+ return n.placements.some(
27
+ (r) => r.field === t.field && (r.group_key ?? null) === o
28
28
  ) ? {
29
- ops: [{ op: "remove", at: { field: t.field, group_key: s } }],
29
+ ops: [{ op: "remove", at: { field: t.field, group_key: o } }],
30
30
  kind: "field",
31
31
  holds: 0
32
32
  } : null;
33
33
  }
34
- const _ = (o, e) => e.x >= o.left && e.x <= o.right && e.y >= o.top && e.y <= o.bottom;
35
- function E(o, e) {
34
+ function E(n, e) {
35
+ if (e.length <= 1) return s(n, e[0] ?? null);
36
+ const t = e.map((o) => s(n, o)).filter((o) => o != null);
37
+ return t.length === 0 ? null : t.length === 1 ? t[0] : { ops: t.flatMap((o) => o.ops), kind: "field", holds: 0, count: t.length };
38
+ }
39
+ const g = (n, e) => e.x >= n.left && e.x <= n.right && e.y >= n.top && e.y <= n.bottom;
40
+ function R(n, e) {
36
41
  return (t) => {
37
- const s = t.pointerCoordinates;
38
- if (s && e(f(t.active.data.current)))
42
+ const o = t.pointerCoordinates;
43
+ if (o && e(h(t.active.data.current)))
39
44
  for (const i of t.droppableContainers) {
40
45
  if (i.disabled || !y(i.data.current)) continue;
41
- const n = t.droppableRects.get(i.id);
42
- if (n && _(n, s)) return [{ id: i.id, data: { droppableContainer: i } }];
46
+ const r = t.droppableRects.get(i.id);
47
+ if (r && g(r, o)) return [{ id: i.id, data: { droppableContainer: i } }];
43
48
  }
44
- return o(t);
49
+ return n(t);
45
50
  };
46
51
  }
47
52
  export {
48
- g as TRASH_DROP_ID,
49
- E as trashAwareCollision,
53
+ D as TRASH_DROP_ID,
54
+ R as trashAwareCollision,
50
55
  y as trashDropData,
51
- D as trashPlan
56
+ s as trashPlan,
57
+ E as trashPlanMany
52
58
  };
@@ -0,0 +1,97 @@
1
+ import { useMemo as y, useCallback as _ } from "react";
2
+ import { applyLayoutOps as w } from "../../../lib/layout-ops.js";
3
+ import { useCollectionBody as v } from "../collection-meta.js";
4
+ function h(e) {
5
+ if (typeof e != "string" || !e) return [];
6
+ const s = /* @__PURE__ */ new Set();
7
+ for (const r of e.matchAll(/\bitem\.([A-Za-z_][A-Za-z0-9_]*)/g)) s.add(r[1]);
8
+ for (const r of e.matchAll(/\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g)) s.add(r[1]);
9
+ return [...s];
10
+ }
11
+ function A(e) {
12
+ const s = [];
13
+ for (const r of e)
14
+ if (r != null && r.field) {
15
+ if (r.computed_type !== "rollup")
16
+ for (const n of h(r.computed_formula))
17
+ n !== r.field && s.push({ driver: n, kind: "formula", target: { kind: "field", field: r.field } });
18
+ for (const n of h(r.default_formula))
19
+ n !== r.field && s.push({ driver: n, kind: "default", target: { kind: "field", field: r.field } });
20
+ }
21
+ return s;
22
+ }
23
+ const p = [
24
+ "visibility",
25
+ "skip",
26
+ "field_rule",
27
+ "formula",
28
+ "cascade",
29
+ "default",
30
+ "parent_cascade",
31
+ "row_rule"
32
+ ], S = (e) => !!e && !e.startsWith("__") && !e.startsWith("$"), m = (e) => new Set(e.placements.map((s) => s.field).filter(S)), O = (e, s) => `${e} ${s}${e === 1 ? "" : "s"}`;
33
+ function b(e, s, r) {
34
+ const n = e.target.kind === "group" ? r(e.target.key) : s(e.target.field);
35
+ switch (e.kind) {
36
+ case "visibility":
37
+ return `shows or hides ${n}`;
38
+ case "skip":
39
+ return `skips ${n}`;
40
+ case "field_rule":
41
+ return `fills ${n}`;
42
+ case "formula":
43
+ return `calculates ${n}`;
44
+ case "default":
45
+ return `sets the starting value of ${n}`;
46
+ case "cascade":
47
+ return e.filterOnly ? `narrows the choices of ${n}` : `filters and clears ${n}`;
48
+ case "parent_cascade":
49
+ return `filters the rows of ${n}`;
50
+ case "row_rule":
51
+ return `drives row rules in ${n}`;
52
+ }
53
+ }
54
+ function z(e) {
55
+ let s;
56
+ try {
57
+ s = w(e.bundle, e.ops);
58
+ } catch {
59
+ return null;
60
+ }
61
+ const r = m(s), n = [...m(e.bundle)].filter((t) => !r.has(t));
62
+ if (n.length === 0) return null;
63
+ const l = new Set(n), f = new Set(s.groups.map((t) => t.key)), o = new Set(
64
+ e.bundle.groups.map((t) => t.key).filter((t) => !f.has(t))
65
+ ), c = /* @__PURE__ */ new Set(), i = [];
66
+ for (const t of e.links) {
67
+ if (!l.has(t.driver) || t.target.kind === "group" && o.has(t.target.key) || t.target.kind === "field" && (l.has(t.target.field) || t.target.field === t.driver))
68
+ continue;
69
+ const a = `${t.kind}|${t.target.kind}:${t.target.kind === "group" ? t.target.key : t.target.field}`;
70
+ c.has(a) || (c.add(a), i.push(t));
71
+ }
72
+ if (i.length === 0) return null;
73
+ i.sort((t, a) => p.indexOf(t.kind) - p.indexOf(a.kind));
74
+ const d = [...new Set(i.map((t) => t.driver))], u = O(i.length, "rule"), k = d.length === 1 ? `${e.label(d[0])} drives ${u}` : `${d.length} of these fields drive ${u}`, $ = i.map((t) => {
75
+ const a = b(t, e.label, e.groupLabel), g = d.length === 1 ? a : `${e.label(t.driver)} ${a}`;
76
+ return g.charAt(0).toUpperCase() + g.slice(1);
77
+ });
78
+ return { headline: k, effects: $, count: i.length };
79
+ }
80
+ function C(e, s, r, n) {
81
+ const { data: l = [] } = v(e, {
82
+ select: (o) => Array.isArray(o == null ? void 0 : o.fields) ? o.fields : []
83
+ }), f = y(
84
+ () => [...s.map((o) => ({ ...o })), ...A(l)],
85
+ [s, l]
86
+ );
87
+ return _(
88
+ (o, c) => z({ bundle: o, ops: c, links: f, label: r, groupLabel: n }),
89
+ [f, r, n]
90
+ );
91
+ }
92
+ export {
93
+ A as formulaLinks,
94
+ h as formulaRefs,
95
+ z as trashWarning,
96
+ C as useTrashWarning
97
+ };
@@ -0,0 +1,86 @@
1
+ import { readGroupStructure as _, isFolded as v } from "../../lib/form-structure.js";
2
+ import { HEADER_GROUP_KEY as b } from "../../lib/layout-ops.js";
3
+ import { gridRows as S } from "./auto-arrange.js";
4
+ import { selectedPlacements as g, widthOf as y, storedWidth as E, keyOf as R, WIDTH_LABELS as T, plural as O, normalizedBundle as $, zoneItems as D, GRID_WIDTHS as G, flagOn as H } from "./field-zones.js";
5
+ import { refuse as m, checked as I } from "./structure-ops.js";
6
+ const p = 12, w = (e) => !H(e, "hidden") && e.is_visible !== !1 && !v(e.overrides);
7
+ function P(e, t) {
8
+ if (t.group_key === b || !w(t)) return null;
9
+ const s = $(e), o = D(s, t.group_key), r = t.group_key ? s.groups.find((n) => n.key === t.group_key) : null, i = _(r == null ? void 0 : r.swap_config).rows, f = new Set(o.filter(w).map((n) => n.field)), a = i.filter((n) => n.fields.filter((c) => f.has(c)).length >= 2), l = a.find((n) => n.fields.includes(t.field));
10
+ if (l) return o.filter((n) => w(n) && l.fields.includes(n.field));
11
+ const d = [], h = /* @__PURE__ */ new Set();
12
+ for (const n of o) {
13
+ if (!w(n)) continue;
14
+ const c = a.find((u) => u.fields.includes(n.field));
15
+ if (c) {
16
+ if (h.has(c.key)) continue;
17
+ h.add(c.key), d.push({ width: p, members: [] });
18
+ continue;
19
+ }
20
+ d.push({ width: y(n), members: [n] });
21
+ }
22
+ const k = S(d.map((n) => n.width));
23
+ for (const n of k) {
24
+ const c = n.flatMap((u) => d[u].members);
25
+ if (c.some((u) => u.field === t.field && u.group_key === t.group_key))
26
+ return n.some((u) => d[u].members.length === 0) ? [t] : c;
27
+ }
28
+ return null;
29
+ }
30
+ function W(e) {
31
+ if (e < 1 || p % e !== 0) return null;
32
+ const t = p / e;
33
+ return G.includes(t) ? t : null;
34
+ }
35
+ const z = (e) => e.map((t) => `${t.group_key ?? ""}:${t.field}`).join("|");
36
+ function B(e, t) {
37
+ if (e.layout.layout_type === "table") return [];
38
+ const s = [], o = /* @__PURE__ */ new Set();
39
+ for (const r of g(e, t)) {
40
+ const i = P(e, r);
41
+ if (!i) continue;
42
+ const f = z(i);
43
+ if (o.has(f)) continue;
44
+ o.add(f);
45
+ const a = W(i.length) ?? 4;
46
+ s.push({ zone: r.group_key, members: i, width: a });
47
+ }
48
+ return s;
49
+ }
50
+ function F(e, t) {
51
+ const s = L(e, t);
52
+ return s.ok ? null : s.reason;
53
+ }
54
+ function L(e, t) {
55
+ if (e.layout.layout_type === "table") return m("Table columns have no rows");
56
+ if (g(e, t).length === 0)
57
+ return m("Select a field in the row first");
58
+ const s = B(e, t), o = s.filter((l) => l.members.length > 1);
59
+ if (o.length === 0)
60
+ return m(
61
+ s.length ? "The field is alone in its row" : "Hidden and folded fields take no row"
62
+ );
63
+ const r = [];
64
+ let i = 0;
65
+ for (const l of o) {
66
+ const d = r.length;
67
+ for (const h of l.members)
68
+ (y(h) !== l.width || l.width === p && h.col_span != null) && r.push({
69
+ op: "update_placement",
70
+ at: R(h),
71
+ patch: { col_span: E(l.width) }
72
+ });
73
+ r.length > d && i++;
74
+ }
75
+ if (r.length === 0)
76
+ return m(o.length === 1 ? "This row is already even" : "These rows are already even");
77
+ const f = o.length === 1 ? o[0] : null, a = f ? `Even out a row: ${f.members.length} fields at ${T[f.width]}` : `Even out ${O(i, "row")}`;
78
+ return I(e, { ok: !0, ops: r, label: a, notes: [] });
79
+ }
80
+ export {
81
+ F as evenRowBlocked,
82
+ L as evenRowPlan,
83
+ W as evenWidth,
84
+ P as rowOfPlacement,
85
+ B as rowsToEven
86
+ };
@@ -0,0 +1,99 @@
1
+ import { applyLayoutOps as N, HEADER_GROUP_KEY as j } from "../../lib/layout-ops.js";
2
+ import { titleCase as S } from "../../lib/utils.js";
3
+ import { fieldSpot as A } from "./add-target.js";
4
+ import { sectionLabel as M } from "./canvas-diff.js";
5
+ import { normalizedBundle as P, plural as q } from "./field-zones.js";
6
+ import { refuse as $ } from "./structure-ops.js";
7
+ import { humanizeOpError as z } from "./useLayoutDraft.js";
8
+ const F = 200;
9
+ function E(r) {
10
+ const o = [], n = /* @__PURE__ */ new Set();
11
+ for (const f of r.split(/[\n\r,;\t]+/)) {
12
+ const i = f.trim().replace(/^(?:[-*•·]|\d+[.)])\s+/, "").replace(/^["'`“‘]+|["'`”’]+$/g, "").trim();
13
+ if (!i) continue;
14
+ const p = i.toLowerCase();
15
+ if (!n.has(p) && (n.add(p), o.push(i), o.length >= F))
16
+ break;
17
+ }
18
+ return o;
19
+ }
20
+ function H(r) {
21
+ const o = r.trim();
22
+ if (!o || o.length > 2e4 || o.startsWith("{") || o.startsWith("[")) return !1;
23
+ const n = E(o);
24
+ return n.length === 0 ? !1 : n.every((f) => f.length <= 80 && f.split(/\s+/).length <= 8);
25
+ }
26
+ const C = (r) => r.toLowerCase().replace(/[^a-z0-9]+/g, "");
27
+ function K(r, o) {
28
+ const n = o.filter((e) => e.field && !e.field.startsWith("__")), f = new Map(n.map((e) => [e.field, e.field])), i = (e) => {
29
+ const l = /* @__PURE__ */ new Map();
30
+ for (const s of n) {
31
+ const t = e(s);
32
+ t && l.set(t, l.has(t) && l.get(t) !== s.field ? null : s.field);
33
+ }
34
+ return l;
35
+ }, p = i((e) => e.field.toLowerCase()), k = i((e) => (e.label || S(e.field)).toLowerCase()), a = i((e) => C(e.field)), b = i((e) => C(e.label || S(e.field))), m = [], u = [], c = /* @__PURE__ */ new Set();
36
+ for (const e of r) {
37
+ const l = e.toLowerCase(), s = C(e), t = f.get(e) ?? p.get(l) ?? k.get(l) ?? (s ? a.get(s) ?? b.get(s) : void 0) ?? null;
38
+ t ? c.has(t) || (c.add(t), m.push({ name: e, field: t })) : u.push(e);
39
+ }
40
+ return { matched: m, unmatched: u };
41
+ }
42
+ function U(r, o, n, f, i = "form") {
43
+ const p = E(o), { matched: k, unmatched: a } = K(p, n), b = (d) => {
44
+ var y;
45
+ return ((y = n.find((h) => h.field === d)) == null ? void 0 : y.label) || S(d);
46
+ }, m = { unmatched: a, already: [], placed: [] };
47
+ if (p.length === 0) return { ...$("Paste or type field names first"), ...m };
48
+ if (k.length === 0)
49
+ return {
50
+ ...$(
51
+ `No field matches ${a.slice(0, 3).join(", ")}${a.length > 3 ? "…" : ""}`
52
+ ),
53
+ ...m
54
+ };
55
+ const u = P(r), c = A(u, f, i);
56
+ let e = u, l = c.index;
57
+ const s = [], t = [], g = [], L = [];
58
+ for (const d of k) {
59
+ if (e.placements.some((h) => h.field === d.field && h.group_key === c.group_key)) {
60
+ t.push(b(d.field));
61
+ continue;
62
+ }
63
+ const y = { op: "place", field: d.field, group_key: c.group_key, index: l };
64
+ try {
65
+ e = N(e, [y]), s.push(y), g.push(d.field), l++;
66
+ } catch (h) {
67
+ L.push(`${b(d.field)}: ${z(h.message)}`);
68
+ }
69
+ }
70
+ const _ = M(u.groups, c.group_key);
71
+ if (s.length === 0)
72
+ return {
73
+ ...$(
74
+ t.length ? `${t.join(", ")} ${t.length === 1 ? "is" : "are"} already in ${_}` : L[0] ?? "Nothing to place"
75
+ ),
76
+ unmatched: a,
77
+ already: t,
78
+ placed: g
79
+ };
80
+ const w = [];
81
+ t.length && w.push(`Already in ${_}: ${t.join(", ")}`), a.length && w.push(`No field matches: ${a.join(", ")}`), w.push(...L);
82
+ const x = g[0];
83
+ return {
84
+ ok: !0,
85
+ ops: s,
86
+ label: `Place ${q(g.length, "field")} in ${_}`,
87
+ notes: w,
88
+ select: c.group_key === j ? { kind: "header", field: x } : { kind: "field", field: x, group_key: c.group_key },
89
+ unmatched: a,
90
+ already: t,
91
+ placed: g
92
+ };
93
+ }
94
+ export {
95
+ H as looksLikeFieldList,
96
+ K as matchFieldNames,
97
+ E as parseFieldList,
98
+ U as placeListPlan
99
+ };
@@ -0,0 +1,102 @@
1
+ import { HEADER_GROUP_KEY as O } from "../../lib/layout-ops.js";
2
+ import { titleCase as N } from "../../lib/utils.js";
3
+ import { sameValue as P } from "./canvas-diff.js";
4
+ import { plural as a } from "./field-zones.js";
5
+ import { asObject as $ } from "./inspector/model.js";
6
+ import { refuse as g, checked as T } from "./structure-ops.js";
7
+ const w = [
8
+ "label",
9
+ "note",
10
+ "placeholder",
11
+ "i18n",
12
+ "display_formula",
13
+ "editor_note",
14
+ "help_video"
15
+ ], y = ["interface", "options"], R = [
16
+ "is_visible",
17
+ "default_expanded",
18
+ "col_span",
19
+ "show_row_revisions",
20
+ "allow_revision_restore",
21
+ "lock_conditions",
22
+ "show_approval_chain"
23
+ ];
24
+ function x(o) {
25
+ const e = {}, r = o;
26
+ for (const l of R) e[l] = r[l] ?? null;
27
+ const i = { ...$(o.overrides) };
28
+ for (const l of w) delete i[l];
29
+ return { field: o.field, group_key: o.group_key, columns: e, overrides: i };
30
+ }
31
+ const D = (o) => !o.startsWith("__");
32
+ function A(o) {
33
+ return !o || o.kind === "group" ? "Select a field first" : D(o.field) ? null : "Panels, widgets and formulas keep their own look";
34
+ }
35
+ const S = (o, e) => {
36
+ if (e.kind === "group") return null;
37
+ const r = e.kind === "header" ? O : e.group_key;
38
+ return o.placements.find((i) => i.field === e.field && i.group_key === r) ?? null;
39
+ };
40
+ function B(o, e) {
41
+ if (A(e)) return null;
42
+ const r = S(o, e);
43
+ return r ? x(r) : null;
44
+ }
45
+ function F(o, e, r, i = {}) {
46
+ var b;
47
+ const l = i.fieldLabel ?? N, u = [], s = [];
48
+ let c = 0, f = 0, p = 0;
49
+ const j = e.group_key === O;
50
+ let k = 0;
51
+ for (const v of r) {
52
+ if (v.kind === "group") continue;
53
+ if (!D(v.field)) {
54
+ c++;
55
+ continue;
56
+ }
57
+ const t = S(o, v);
58
+ if (!t || t.field === e.field && t.group_key === e.group_key) continue;
59
+ if (t.group_key === O !== j) {
60
+ k++;
61
+ continue;
62
+ }
63
+ const E = t.field === e.field || (((b = i.sameKind) == null ? void 0 : b.call(i, e.field, t.field)) ?? !1), h = $(t.overrides), d = {};
64
+ for (const n of w) h[n] !== void 0 && (d[n] = h[n]);
65
+ for (const n of y) {
66
+ const _ = E ? e.overrides[n] : h[n];
67
+ _ !== void 0 && (d[n] = _);
68
+ }
69
+ !E && y.some((n) => e.overrides[n] !== void 0) && p++;
70
+ for (const [n, _] of Object.entries(e.overrides))
71
+ !w.includes(n) && !y.includes(n) && (d[n] = _);
72
+ const m = {}, K = t;
73
+ for (const n of R)
74
+ P(K[n] ?? null, e.columns[n] ?? null) || (m[n] = e.columns[n] ?? null);
75
+ const I = Object.keys(d).length ? d : null;
76
+ if (P(h, I ?? {}) || (m.overrides = I), Object.keys(m).length === 0) {
77
+ f++;
78
+ continue;
79
+ }
80
+ u.push({
81
+ op: "update_placement",
82
+ at: { field: t.field, group_key: t.group_key },
83
+ patch: m
84
+ });
85
+ }
86
+ return u.length === 0 ? f ? g(f === 1 ? "It already looks the same" : "They already look the same") : k ? g("Header tiles and form fields have different settings") : c ? g("Panels, widgets and formulas keep their own look") : g("Select the fields to paint onto") : (f && s.push(`${a(f, "field")} already looked the same`), c && s.push(`${a(c, "panel")} skipped: panels keep their own look`), k && s.push(`${a(k, "field")} skipped: header tiles and form fields differ`), p && s.push(
87
+ `${a(p, "field")} of another kind kept ${p === 1 ? "its" : "their"} own input and options`
88
+ ), T(o, {
89
+ ok: !0,
90
+ ops: u,
91
+ label: `Paint the look of ${l(e.field)} onto ${a(u.length, "field")}`,
92
+ notes: s
93
+ }));
94
+ }
95
+ export {
96
+ w as IDENTITY_OVERRIDES,
97
+ y as KIND_OVERRIDES,
98
+ B as lookFrom,
99
+ x as lookOf,
100
+ A as paintBlocked,
101
+ F as paintPlan
102
+ };
@@ -40,22 +40,22 @@ function W(t, r, i) {
40
40
  for (const o of R) Math.abs(o - l) < Math.abs(c - l) && (c = o);
41
41
  return c;
42
42
  }
43
- const h = [...R].sort((t, r) => t - r), P = (t) => {
43
+ const v = [...R].sort((t, r) => t - r), P = (t) => {
44
44
  const r = /span\s+(\d+)/.exec(t.style.gridColumn);
45
45
  return r ? Number(r[1]) : 12;
46
46
  }, _ = (t) => !!t && getComputedStyle(t).display === "grid" && getComputedStyle(t).gridTemplateColumns.trim().split(/\s+/).length === 12;
47
47
  function Q({ onCommit: t }) {
48
- const r = E(N), i = C(null), a = C(null), [l, c] = S(!1), [o, g] = S(null), p = () => {
48
+ const r = E(N), i = C(null), a = C(null), [l, c] = S(!1), [o, p] = S(null), g = () => {
49
49
  var e;
50
50
  return ((e = i.current) == null ? void 0 : e.closest("[data-design-target]")) ?? null;
51
51
  };
52
52
  T(() => {
53
53
  var e;
54
- c(_(((e = p()) == null ? void 0 : e.parentElement) ?? null));
54
+ c(_(((e = g()) == null ? void 0 : e.parentElement) ?? null));
55
55
  }, []);
56
56
  const u = (e) => {
57
57
  const n = a.current;
58
- n && (a.current = null, n.cell.style.gridColumn = n.original, r == null || r.setResizing(!1), g(null), e && n.span !== n.start && t(n.span));
58
+ n && (a.current = null, n.cell.style.gridColumn = n.original, r == null || r.setResizing(!1), p(null), e && n.span !== n.start && t(n.span));
59
59
  };
60
60
  k(() => {
61
61
  if (o === null) return;
@@ -64,30 +64,30 @@ function Q({ onCommit: t }) {
64
64
  };
65
65
  return window.addEventListener("keydown", e, !0), () => window.removeEventListener("keydown", e, !0);
66
66
  }), k(() => () => u(!1), []);
67
- const y = p(), f = y ? P(y) : 12, z = (e) => {
67
+ const y = g(), f = y ? P(y) : 12, z = (e) => {
68
68
  var b, w;
69
- const n = p(), s = n == null ? void 0 : n.parentElement;
69
+ const n = g(), s = n == null ? void 0 : n.parentElement;
70
70
  if (!n || !s || e.button !== 0) return;
71
71
  e.preventDefault(), e.stopPropagation(), (w = (b = e.currentTarget).setPointerCapture) == null || w.call(b, e.pointerId);
72
- const I = getComputedStyle(s), v = P(n);
72
+ const I = getComputedStyle(s), h = P(n);
73
73
  a.current = {
74
74
  cell: n,
75
75
  left: n.getBoundingClientRect().left,
76
76
  width: s.getBoundingClientRect().width,
77
77
  gap: Number.parseFloat(I.columnGap) || 0,
78
- start: v,
79
- span: v,
78
+ start: h,
79
+ span: h,
80
80
  original: n.style.gridColumn
81
- }, r == null || r.setResizing(!0), g(v);
81
+ }, r == null || r.setResizing(!0), p(h);
82
82
  }, A = (e) => {
83
83
  const n = a.current;
84
84
  if (!n) return;
85
85
  const s = W(e.clientX - n.left, n.width, n.gap);
86
- s !== n.span && (n.span = s, n.cell.style.gridColumn = `span ${s}`, g(s));
86
+ s !== n.span && (n.span = s, n.cell.style.gridColumn = `span ${s}`, p(s));
87
87
  }, G = (e) => {
88
88
  if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
89
89
  e.preventDefault(), e.stopPropagation();
90
- const n = h.indexOf(f), s = h[Math.max(0, Math.min(h.length - 1, n + (e.key === "ArrowRight" ? 1 : -1)))];
90
+ const n = v.indexOf(f), s = v[Math.max(0, Math.min(v.length - 1, n + (e.key === "ArrowRight" ? 1 : -1)))];
91
91
  s !== void 0 && s !== f && t(s);
92
92
  }, m = o ?? f;
93
93
  return /* @__PURE__ */ x(M, { children: [
@@ -113,7 +113,9 @@ function Q({ onCommit: t }) {
113
113
  onKeyDown: G,
114
114
  onClick: (e) => e.stopPropagation(),
115
115
  className: L(
116
- "absolute -right-[7px] top-1/2 z-20 flex h-7 w-3 -translate-y-1/2 cursor-col-resize items-center justify-center gap-[2px] rounded-sm bg-white ring-1 ring-nvr-cyan transition-colors hover:bg-nvr-cyan/10 focus-visible:outline focus-visible:outline-2 focus-visible:outline-nvr-cyan dark:bg-card motion-reduce:transition-none",
116
+ "absolute -right-[7px] top-1/2 z-20 flex h-7 w-3 -translate-y-1/2 cursor-col-resize touch-none items-center justify-center gap-[2px] rounded-sm bg-white ring-1 ring-nvr-cyan transition-colors hover:bg-nvr-cyan/10 focus-visible:outline focus-visible:outline-2 focus-visible:outline-nvr-cyan dark:bg-card motion-reduce:transition-none",
117
+ // #3193: a finger-sized handle on touch screens (the page does not scroll from it).
118
+ "[@media(pointer:coarse)]:-right-3 [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:w-6",
117
119
  o !== null && "bg-nvr-cyan/10",
118
120
  !l && "hidden"
119
121
  ),