@adoptai/genui-components 0.1.59 → 0.1.60

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
@@ -5535,7 +5535,14 @@ var decisionCardSchema = z.object({
5535
5535
  z.object({
5536
5536
  id: z.string().optional(),
5537
5537
  label: z.string(),
5538
- recommended: z.boolean().optional()
5538
+ recommended: z.boolean().optional(),
5539
+ value: z.number().optional(),
5540
+ adjust: z.object({
5541
+ min: z.number(),
5542
+ max: z.number(),
5543
+ step: z.number().optional(),
5544
+ unit: z.string().optional()
5545
+ }).optional()
5539
5546
  })
5540
5547
  ).min(1).max(5),
5541
5548
  source: z.object({
@@ -5543,7 +5550,8 @@ var decisionCardSchema = z.object({
5543
5550
  url: z.string().optional()
5544
5551
  }).optional(),
5545
5552
  resolved: z.object({
5546
- option: z.string()
5553
+ option: z.string(),
5554
+ value: z.number().optional()
5547
5555
  }).optional()
5548
5556
  });
5549
5557
  var decisionCardTool = {
@@ -5586,13 +5594,28 @@ var decisionCardTool = {
5586
5594
  type: "array",
5587
5595
  minItems: 1,
5588
5596
  maxItems: 5,
5589
- description: "Mutually-exclusive resolution choices; mark one `recommended` to make it primary",
5597
+ description: "Mutually-exclusive resolution choices; mark one `recommended` to make it primary. An option that carries a numeric figure the user may want to tune (e.g. 'Book reserve' at 50 units) should set `value` (your suggested figure) and `adjust` ({min,max[,step,unit]}) \u2014 the card then lets the user fine-tune the number within that range before confirming.",
5590
5598
  items: {
5591
5599
  type: "object",
5592
5600
  properties: {
5593
5601
  id: { type: "string" },
5594
5602
  label: { type: "string" },
5595
- recommended: { type: "boolean" }
5603
+ recommended: { type: "boolean" },
5604
+ value: {
5605
+ type: "number",
5606
+ description: "Suggested numeric figure for this option (the starting point of the adjuster)"
5607
+ },
5608
+ adjust: {
5609
+ type: "object",
5610
+ description: "Allow the user to tune `value` within this inclusive range before resolving",
5611
+ properties: {
5612
+ min: { type: "number" },
5613
+ max: { type: "number" },
5614
+ step: { type: "number", description: "Increment granularity; defaults to a sensible step for the range" },
5615
+ unit: { type: "string", description: "Short unit suffix shown after the number, e.g. 'units', '%', 'hrs'" }
5616
+ },
5617
+ required: ["min", "max"]
5618
+ }
5596
5619
  },
5597
5620
  required: ["label"]
5598
5621
  }
@@ -5609,7 +5632,8 @@ var decisionCardTool = {
5609
5632
  type: "object",
5610
5633
  description: "Pre-resolved state for transcript replay",
5611
5634
  properties: {
5612
- option: { type: "string" }
5635
+ option: { type: "string" },
5636
+ value: { type: "number", description: "Adjusted figure the user confirmed, when the option was adjustable" }
5613
5637
  },
5614
5638
  required: ["option"]
5615
5639
  }
@@ -20051,8 +20075,15 @@ function useContainerWidth2(ref) {
20051
20075
  var KEYFRAMES2 = `
20052
20076
  @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
20053
20077
  .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
20078
+ .dc-range{-webkit-appearance:none;appearance:none;width:100%;height:4px;border-radius:9999px;outline:none;cursor:pointer;background:transparent}
20079
+ .dc-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;border-radius:50%;background:white;border:2px solid var(--dc-thumb,#ff5000);box-shadow:0 1px 3px rgba(0,0,0,0.18);cursor:grab;transition:transform 0.12s}
20080
+ .dc-range::-webkit-slider-thumb:hover{transform:scale(1.12)}
20081
+ .dc-range:active::-webkit-slider-thumb{cursor:grabbing}
20082
+ .dc-range::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:white;border:2px solid var(--dc-thumb,#ff5000);box-shadow:0 1px 3px rgba(0,0,0,0.18);cursor:grab}
20083
+ .dc-range::-moz-range-track{height:4px;border-radius:9999px;background:transparent}
20054
20084
  @media (prefers-reduced-motion: reduce){
20055
20085
  .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
20086
+ .dc-range::-webkit-slider-thumb{transition:none}
20056
20087
  }`;
20057
20088
  function SparkCheck({ size, color }) {
20058
20089
  return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
@@ -20098,17 +20129,239 @@ function FlagPill({ flag }) {
20098
20129
  }
20099
20130
  );
20100
20131
  }
20132
+ function formatFigure(value, unit) {
20133
+ const body = Number.isInteger(value) ? `${value}` : `${Math.round(value * 100) / 100}`;
20134
+ if (!unit) return body;
20135
+ return unit === "%" ? `${body}%` : `${body} ${unit}`;
20136
+ }
20137
+ function clampToRange(raw, adjust) {
20138
+ var _a2;
20139
+ const step = (_a2 = adjust.step) != null ? _a2 : Number.isInteger(adjust.min) && Number.isInteger(adjust.max) ? 1 : (adjust.max - adjust.min) / 100;
20140
+ const snapped = Math.round((raw - adjust.min) / step) * step + adjust.min;
20141
+ const fixed = Math.round(snapped * 1e6) / 1e6;
20142
+ return Math.min(adjust.max, Math.max(adjust.min, fixed));
20143
+ }
20144
+ function ValueAdjuster({
20145
+ option,
20146
+ accent,
20147
+ border,
20148
+ muted,
20149
+ onConfirm,
20150
+ onBack
20151
+ }) {
20152
+ var _a2, _b;
20153
+ const adjust = option.adjust;
20154
+ const suggested = clampToRange((_a2 = option.value) != null ? _a2 : adjust.min, adjust);
20155
+ const [value, setValue] = React45.useState(suggested);
20156
+ const [text, setText] = React45.useState(String(suggested));
20157
+ const step = (_b = adjust.step) != null ? _b : Number.isInteger(adjust.min) && Number.isInteger(adjust.max) ? 1 : (adjust.max - adjust.min) / 100;
20158
+ const pct = adjust.max > adjust.min ? (value - adjust.min) / (adjust.max - adjust.min) * 100 : 0;
20159
+ const suggestedPct = adjust.max > adjust.min ? (suggested - adjust.min) / (adjust.max - adjust.min) * 100 : 0;
20160
+ const moved = value !== suggested;
20161
+ const commit = (raw) => {
20162
+ const v = clampToRange(raw, adjust);
20163
+ setValue(v);
20164
+ setText(String(v));
20165
+ };
20166
+ return /* @__PURE__ */ jsxs(
20167
+ "div",
20168
+ {
20169
+ className: "dc-rise",
20170
+ "data-testid": "decision-card-adjuster",
20171
+ style: {
20172
+ display: "flex",
20173
+ flexDirection: "column",
20174
+ gap: 12,
20175
+ border: `1px solid ${border}`,
20176
+ borderRadius: 10,
20177
+ padding: "12px 14px",
20178
+ background: "#fafafa"
20179
+ },
20180
+ children: [
20181
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 8 }, children: [
20182
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.06em", color: muted }, children: [
20183
+ "Adjust \xB7 ",
20184
+ option.label
20185
+ ] }),
20186
+ /* @__PURE__ */ jsx("span", { style: { flex: 1 } }),
20187
+ /* @__PURE__ */ jsx(
20188
+ "button",
20189
+ {
20190
+ type: "button",
20191
+ onClick: onBack,
20192
+ "data-testid": "decision-card-adjust-back",
20193
+ style: { border: "none", background: "none", padding: 0, cursor: "pointer", fontSize: 12, fontWeight: 600, color: muted },
20194
+ children: "Back"
20195
+ }
20196
+ )
20197
+ ] }),
20198
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 6 }, children: [
20199
+ /* @__PURE__ */ jsx(
20200
+ "input",
20201
+ {
20202
+ value: text,
20203
+ onChange: (e) => {
20204
+ setText(e.target.value);
20205
+ const n = Number(e.target.value);
20206
+ if (Number.isFinite(n)) setValue(clampToRange(n, adjust));
20207
+ },
20208
+ onBlur: () => commit(Number(text) || suggested),
20209
+ onKeyDown: (e) => {
20210
+ if (e.key === "Enter") {
20211
+ const v = clampToRange(Number(text) || suggested, adjust);
20212
+ commit(v);
20213
+ onConfirm(v);
20214
+ } else if (e.key === "ArrowUp") {
20215
+ e.preventDefault();
20216
+ commit(value + step);
20217
+ } else if (e.key === "ArrowDown") {
20218
+ e.preventDefault();
20219
+ commit(value - step);
20220
+ }
20221
+ },
20222
+ inputMode: "decimal",
20223
+ "aria-label": `${option.label} value`,
20224
+ "data-testid": "decision-card-adjust-input",
20225
+ style: {
20226
+ width: `${Math.max(3, String(text).length + 1)}ch`,
20227
+ fontSize: 26,
20228
+ fontWeight: 700,
20229
+ fontVariantNumeric: "tabular-nums",
20230
+ letterSpacing: "-0.02em",
20231
+ color: "var(--foreground)",
20232
+ border: "none",
20233
+ borderBottom: `2px solid ${accent}`,
20234
+ background: "transparent",
20235
+ outline: "none",
20236
+ padding: 0
20237
+ }
20238
+ }
20239
+ ),
20240
+ adjust.unit && /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: muted }, children: adjust.unit }),
20241
+ moved && /* @__PURE__ */ jsxs(
20242
+ "button",
20243
+ {
20244
+ type: "button",
20245
+ onClick: () => commit(suggested),
20246
+ "data-testid": "decision-card-adjust-reset",
20247
+ style: {
20248
+ marginLeft: 8,
20249
+ border: "none",
20250
+ background: "none",
20251
+ padding: 0,
20252
+ cursor: "pointer",
20253
+ fontSize: 11.5,
20254
+ fontWeight: 600,
20255
+ color: muted,
20256
+ textDecoration: "underline",
20257
+ textUnderlineOffset: 2
20258
+ },
20259
+ children: [
20260
+ "Reset to suggested (",
20261
+ formatFigure(suggested, adjust.unit),
20262
+ ")"
20263
+ ]
20264
+ }
20265
+ )
20266
+ ] }),
20267
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
20268
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative", height: 16, display: "flex", alignItems: "center" }, children: [
20269
+ /* @__PURE__ */ jsx(
20270
+ "div",
20271
+ {
20272
+ "aria-hidden": "true",
20273
+ style: {
20274
+ position: "absolute",
20275
+ left: 0,
20276
+ right: 0,
20277
+ height: 4,
20278
+ borderRadius: 9999,
20279
+ background: `linear-gradient(to right, ${accent} ${pct}%, #e8e8e8 ${pct}%)`
20280
+ }
20281
+ }
20282
+ ),
20283
+ moved && /* @__PURE__ */ jsx(
20284
+ "div",
20285
+ {
20286
+ "aria-hidden": "true",
20287
+ title: `Suggested: ${formatFigure(suggested, adjust.unit)}`,
20288
+ style: {
20289
+ position: "absolute",
20290
+ left: `${suggestedPct}%`,
20291
+ transform: "translateX(-50%)",
20292
+ width: 2,
20293
+ height: 10,
20294
+ borderRadius: 1,
20295
+ background: muted,
20296
+ opacity: 0.55
20297
+ }
20298
+ }
20299
+ ),
20300
+ /* @__PURE__ */ jsx(
20301
+ "input",
20302
+ {
20303
+ type: "range",
20304
+ className: "dc-range",
20305
+ min: adjust.min,
20306
+ max: adjust.max,
20307
+ step,
20308
+ value,
20309
+ onChange: (e) => commit(Number(e.target.value)),
20310
+ "aria-label": `${option.label} slider`,
20311
+ "data-testid": "decision-card-adjust-slider",
20312
+ style: { position: "relative", ["--dc-thumb"]: accent }
20313
+ }
20314
+ )
20315
+ ] }),
20316
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 10.5, fontWeight: 600, color: muted, fontVariantNumeric: "tabular-nums" }, children: [
20317
+ /* @__PURE__ */ jsx("span", { children: formatFigure(adjust.min, adjust.unit) }),
20318
+ /* @__PURE__ */ jsx("span", { children: formatFigure(adjust.max, adjust.unit) })
20319
+ ] })
20320
+ ] }),
20321
+ /* @__PURE__ */ jsxs(
20322
+ "button",
20323
+ {
20324
+ type: "button",
20325
+ onClick: () => onConfirm(value),
20326
+ "data-testid": "decision-card-adjust-confirm",
20327
+ style: {
20328
+ alignSelf: "flex-start",
20329
+ border: `1px solid ${accent}`,
20330
+ background: accent,
20331
+ color: "white",
20332
+ borderRadius: 8,
20333
+ fontSize: 13,
20334
+ fontWeight: 600,
20335
+ padding: "9px 16px",
20336
+ cursor: "pointer",
20337
+ fontVariantNumeric: "tabular-nums",
20338
+ transition: "opacity 0.15s"
20339
+ },
20340
+ onMouseEnter: (e) => e.currentTarget.style.opacity = "0.88",
20341
+ onMouseLeave: (e) => e.currentTarget.style.opacity = "1",
20342
+ children: [
20343
+ option.label,
20344
+ " \xB7 ",
20345
+ formatFigure(value, adjust.unit)
20346
+ ]
20347
+ }
20348
+ )
20349
+ ]
20350
+ }
20351
+ );
20352
+ }
20101
20353
  function DecisionCardRenderer({
20102
20354
  data,
20103
20355
  resolved = null,
20104
20356
  onResolve,
20105
20357
  onOpenSource
20106
20358
  }) {
20107
- var _a2, _b;
20359
+ var _a2, _b, _c;
20108
20360
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
20109
20361
  const rootRef = React45.useRef(null);
20110
20362
  const width = useContainerWidth2(rootRef);
20111
20363
  const stacked = width > 0 && width < STACK_BELOW;
20364
+ const [adjustingIdx, setAdjustingIdx] = React45.useState(null);
20112
20365
  const options = (_a2 = data.options) != null ? _a2 : [];
20113
20366
  const recommendedIdx = Math.max(
20114
20367
  0,
@@ -20263,7 +20516,20 @@ function DecisionCardRenderer({
20263
20516
  ]
20264
20517
  }
20265
20518
  ) : /* @__PURE__ */ jsxs(Fragment, { children: [
20266
- /* @__PURE__ */ jsx(
20519
+ adjustingIdx != null && ((_b = options[adjustingIdx]) == null ? void 0 : _b.adjust) ? /* @__PURE__ */ jsx(
20520
+ ValueAdjuster,
20521
+ {
20522
+ option: options[adjustingIdx],
20523
+ accent: ACCENT2,
20524
+ border: BORDER4,
20525
+ muted: MUTED2,
20526
+ onBack: () => setAdjustingIdx(null),
20527
+ onConfirm: (value) => {
20528
+ setAdjustingIdx(null);
20529
+ onResolve == null ? void 0 : onResolve(options[adjustingIdx].label, value);
20530
+ }
20531
+ }
20532
+ ) : /* @__PURE__ */ jsx(
20267
20533
  "div",
20268
20534
  {
20269
20535
  style: {
@@ -20273,15 +20539,21 @@ function DecisionCardRenderer({
20273
20539
  gap: 8
20274
20540
  },
20275
20541
  children: options.map((opt, idx) => {
20276
- var _a3;
20542
+ var _a3, _b2;
20277
20543
  const primary = idx === recommendedIdx;
20278
- return /* @__PURE__ */ jsx(
20544
+ const adjustable = Boolean(opt.adjust);
20545
+ return /* @__PURE__ */ jsxs(
20279
20546
  "button",
20280
20547
  {
20281
20548
  type: "button",
20282
- onClick: () => onResolve == null ? void 0 : onResolve(opt.label),
20549
+ onClick: () => adjustable ? setAdjustingIdx(idx) : onResolve == null ? void 0 : onResolve(opt.label),
20550
+ "data-adjustable": adjustable || void 0,
20283
20551
  style: {
20284
20552
  width: stacked ? "100%" : "auto",
20553
+ display: "inline-flex",
20554
+ alignItems: "center",
20555
+ justifyContent: stacked ? "flex-start" : "center",
20556
+ gap: 7,
20285
20557
  textAlign: stacked ? "left" : "center",
20286
20558
  border: `1px solid ${primary ? ACCENT2 : BORDER4}`,
20287
20559
  background: primary ? ACCENT2 : "white",
@@ -20309,7 +20581,28 @@ function DecisionCardRenderer({
20309
20581
  e.currentTarget.style.background = "white";
20310
20582
  }
20311
20583
  },
20312
- children: opt.label
20584
+ children: [
20585
+ opt.label,
20586
+ adjustable && typeof opt.value === "number" && /* @__PURE__ */ jsxs(
20587
+ "span",
20588
+ {
20589
+ style: {
20590
+ fontSize: 11.5,
20591
+ fontWeight: 700,
20592
+ fontVariantNumeric: "tabular-nums",
20593
+ padding: "1px 7px",
20594
+ borderRadius: 9999,
20595
+ background: primary ? "rgba(255,255,255,0.22)" : "#f2f2f2",
20596
+ color: primary ? "white" : MUTED2,
20597
+ lineHeight: 1.5
20598
+ },
20599
+ children: [
20600
+ formatFigure(opt.value, (_b2 = opt.adjust) == null ? void 0 : _b2.unit),
20601
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { marginLeft: 4, opacity: 0.8 }, children: "\u270E" })
20602
+ ]
20603
+ }
20604
+ )
20605
+ ]
20313
20606
  },
20314
20607
  (_a3 = opt.id) != null ? _a3 : opt.label
20315
20608
  );
@@ -20348,7 +20641,7 @@ function DecisionCardRenderer({
20348
20641
  strokeLinejoin: "round"
20349
20642
  }
20350
20643
  ) }),
20351
- (_b = data.source.label) != null ? _b : "View source for this figure"
20644
+ (_c = data.source.label) != null ? _c : "View source for this figure"
20352
20645
  ]
20353
20646
  }
20354
20647
  )
@@ -20357,20 +20650,27 @@ function DecisionCardRenderer({
20357
20650
  }
20358
20651
  );
20359
20652
  }
20653
+ function composeResolution(p, option, value) {
20654
+ var _a2, _b, _c;
20655
+ if (value == null) return option;
20656
+ const unit = (_c = (_b = ((_a2 = p.options) != null ? _a2 : []).find((o) => o.label === option)) == null ? void 0 : _b.adjust) == null ? void 0 : _c.unit;
20657
+ return `${option} \xB7 ${formatFigure(value, unit)}`;
20658
+ }
20360
20659
  function DecisionCardResolver(p) {
20361
- var _a2, _b, _c, _d;
20660
+ var _a2, _b;
20362
20661
  const { resolvedDecisions, onDecisionResolve, onDecisionSource } = useGenUIInteraction();
20363
20662
  const decisionId = (_a2 = p.id) != null ? _a2 : p.title;
20364
20663
  const hostResolved = resolvedDecisions == null ? void 0 : resolvedDecisions[decisionId];
20365
- const initial = (_c = hostResolved != null ? hostResolved : (_b = p.resolved) == null ? void 0 : _b.option) != null ? _c : null;
20664
+ const initial = hostResolved != null ? hostResolved : p.resolved ? composeResolution(p, p.resolved.option, p.resolved.value) : null;
20366
20665
  const [localResolved, setLocalResolved] = React45.useState(initial);
20367
20666
  React45.useEffect(() => {
20368
20667
  if (hostResolved !== void 0) setLocalResolved(hostResolved);
20369
20668
  }, [hostResolved]);
20370
20669
  const resolved = hostResolved != null ? hostResolved : localResolved;
20371
- const handleResolve = (option) => {
20372
- setLocalResolved(option);
20373
- onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, option);
20670
+ const handleResolve = (option, value) => {
20671
+ const resolution = composeResolution(p, option, value);
20672
+ setLocalResolved(resolution);
20673
+ onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, resolution);
20374
20674
  };
20375
20675
  const handleSource = () => {
20376
20676
  var _a3;
@@ -20379,7 +20679,7 @@ function DecisionCardResolver(p) {
20379
20679
  window.open(p.source.url, "_blank", "noopener,noreferrer");
20380
20680
  }
20381
20681
  };
20382
- return /* @__PURE__ */ jsx(ComponentActions, { filename: (_d = p.title) != null ? _d : "decision-card", children: /* @__PURE__ */ jsx(
20682
+ return /* @__PURE__ */ jsx(ComponentActions, { filename: (_b = p.title) != null ? _b : "decision-card", children: /* @__PURE__ */ jsx(
20383
20683
  DecisionCardRenderer,
20384
20684
  {
20385
20685
  data: p,
@@ -22176,7 +22476,9 @@ function BlockForm({
22176
22476
  onEntityCreate,
22177
22477
  hideActions,
22178
22478
  dense,
22179
- variant = "form"
22479
+ variant = "form",
22480
+ fieldSuggestions,
22481
+ onApplySuggestion
22180
22482
  }) {
22181
22483
  var _a2;
22182
22484
  const t = useTheme();
@@ -22207,20 +22509,85 @@ function BlockForm({
22207
22509
  }
22208
22510
  ),
22209
22511
  ((_a2 = block.context) == null ? void 0 : _a2.type) && /* @__PURE__ */ jsx(ContextSlot, { payload: block.context }),
22210
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: dense ? "8px" : isEscalation ? "10px" : "12px" }, children: (block.fields || []).map((field) => /* @__PURE__ */ jsx("div", { "data-field-key": fieldKey(block.id, field.name), children: /* @__PURE__ */ jsx(
22211
- FieldRenderer,
22212
- {
22213
- field,
22214
- value: state.getValue(block.id, field.name),
22215
- onChange: (v) => state.setFieldValue(block.id, field.name, v),
22216
- disabled,
22217
- error: state.getError(block.id, field.name),
22218
- dense,
22219
- onFileUpload,
22220
- onEntitySearch,
22221
- onEntityCreate
22222
- }
22223
- ) }, `${block.id}:${field.name}`)) }),
22512
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: dense ? "8px" : isEscalation ? "10px" : "12px" }, children: (block.fields || []).map((field) => {
22513
+ var _a3;
22514
+ const suggestion = (fieldSuggestions || []).filter((sg) => {
22515
+ var _a4;
22516
+ return sg.field === field.name && ((_a4 = sg.block_id) != null ? _a4 : block.id) === block.id;
22517
+ }).slice(-1)[0];
22518
+ const current = state.getValue(block.id, field.name);
22519
+ const showSuggestion = suggestion != null && current !== suggestion.value;
22520
+ return /* @__PURE__ */ jsxs("div", { "data-field-key": fieldKey(block.id, field.name), children: [
22521
+ /* @__PURE__ */ jsx(
22522
+ FieldRenderer,
22523
+ {
22524
+ field,
22525
+ value: current,
22526
+ onChange: (v) => state.setFieldValue(block.id, field.name, v),
22527
+ disabled,
22528
+ error: state.getError(block.id, field.name),
22529
+ dense,
22530
+ onFileUpload,
22531
+ onEntitySearch,
22532
+ onEntityCreate
22533
+ }
22534
+ ),
22535
+ showSuggestion && !disabled ? /* @__PURE__ */ jsxs(
22536
+ "div",
22537
+ {
22538
+ "data-testid": `builder-suggestion-${field.name}`,
22539
+ style: {
22540
+ display: "flex",
22541
+ alignItems: "center",
22542
+ flexWrap: "wrap",
22543
+ gap: "6px",
22544
+ marginTop: "5px",
22545
+ padding: "5px 9px",
22546
+ borderRadius: "8px",
22547
+ border: `1px dashed ${t.BORDER}`,
22548
+ background: "#fafafa",
22549
+ fontSize: "11.5px",
22550
+ lineHeight: 1.4
22551
+ },
22552
+ children: [
22553
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { color: t.ACCENT, fontSize: "11px" }, children: "\u2726" }),
22554
+ /* @__PURE__ */ jsxs("span", { style: { color: t.MUTED, fontWeight: 600 }, children: [
22555
+ "Suggested:",
22556
+ " ",
22557
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--foreground)", fontVariantNumeric: "tabular-nums" }, children: (_a3 = suggestion.label) != null ? _a3 : String(suggestion.value) })
22558
+ ] }),
22559
+ suggestion.note ? /* @__PURE__ */ jsxs("span", { style: { color: t.MUTED }, children: [
22560
+ "\xB7 ",
22561
+ suggestion.note
22562
+ ] }) : null,
22563
+ /* @__PURE__ */ jsx("span", { style: { flex: 1 } }),
22564
+ /* @__PURE__ */ jsx(
22565
+ "button",
22566
+ {
22567
+ type: "button",
22568
+ "data-testid": `builder-suggestion-apply-${field.name}`,
22569
+ onClick: () => {
22570
+ state.setFieldValue(block.id, field.name, suggestion.value);
22571
+ onApplySuggestion == null ? void 0 : onApplySuggestion(suggestion);
22572
+ },
22573
+ style: {
22574
+ font: "inherit",
22575
+ fontSize: "11.5px",
22576
+ fontWeight: 700,
22577
+ color: t.ACCENT,
22578
+ background: "transparent",
22579
+ border: "none",
22580
+ padding: 0,
22581
+ cursor: "pointer"
22582
+ },
22583
+ children: "Apply"
22584
+ }
22585
+ )
22586
+ ]
22587
+ }
22588
+ ) : null
22589
+ ] }, `${block.id}:${field.name}`);
22590
+ }) }),
22224
22591
  hideActions ? null : /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px", paddingTop: isEscalation ? "2px" : "4px" }, children: [
22225
22592
  errorCount > 0 ? /* @__PURE__ */ jsxs("div", { style: { fontSize: "11px", fontWeight: 600, color: "#dc2626" }, children: [
22226
22593
  errorCount,
@@ -22508,7 +22875,9 @@ function BuilderFormResolver({
22508
22875
  submitRef,
22509
22876
  hideActions,
22510
22877
  dense,
22511
- onValidationError
22878
+ onValidationError,
22879
+ fieldSuggestions,
22880
+ onApplySuggestion
22512
22881
  }) {
22513
22882
  var _a2;
22514
22883
  const state = useBuilderState(builder.blocks);
@@ -22585,7 +22954,9 @@ function BuilderFormResolver({
22585
22954
  onEntitySearch,
22586
22955
  onEntityCreate,
22587
22956
  hideActions,
22588
- dense
22957
+ dense,
22958
+ fieldSuggestions,
22959
+ onApplySuggestion
22589
22960
  }
22590
22961
  );
22591
22962
  default:
@@ -22602,7 +22973,9 @@ function BuilderFormResolver({
22602
22973
  onEntitySearch,
22603
22974
  onEntityCreate,
22604
22975
  dense,
22605
- hideActions
22976
+ hideActions,
22977
+ fieldSuggestions,
22978
+ onApplySuggestion
22606
22979
  }
22607
22980
  );
22608
22981
  }