@adoptai/genui-components 0.1.56 → 0.1.57

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 (38) hide show
  1. package/dist/builders/BuilderForm.d.ts.map +1 -1
  2. package/dist/composites/decision-card/resolver.cjs +634 -0
  3. package/dist/composites/decision-card/resolver.cjs.map +1 -0
  4. package/dist/composites/decision-card/resolver.d.ts +13 -0
  5. package/dist/composites/decision-card/resolver.d.ts.map +1 -0
  6. package/dist/composites/decision-card/resolver.js +627 -0
  7. package/dist/composites/decision-card/resolver.js.map +1 -0
  8. package/dist/composites/workflow-stepper/resolver.cjs +4 -1
  9. package/dist/composites/workflow-stepper/resolver.cjs.map +1 -1
  10. package/dist/composites/workflow-stepper/resolver.js +4 -1
  11. package/dist/composites/workflow-stepper/resolver.js.map +1 -1
  12. package/dist/index.cjs +513 -11
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +512 -12
  17. package/dist/index.js.map +1 -1
  18. package/dist/renderer.cjs +504 -8
  19. package/dist/renderer.cjs.map +1 -1
  20. package/dist/renderer.js +504 -8
  21. package/dist/renderer.js.map +1 -1
  22. package/dist/resolver.cjs +504 -8
  23. package/dist/resolver.cjs.map +1 -1
  24. package/dist/resolver.d.ts.map +1 -1
  25. package/dist/resolver.js +504 -8
  26. package/dist/resolver.js.map +1 -1
  27. package/dist/schemas/decision-card.d.ts +149 -0
  28. package/dist/schemas/decision-card.d.ts.map +1 -0
  29. package/dist/schemas/index.cjs +105 -1
  30. package/dist/schemas/index.cjs.map +1 -1
  31. package/dist/schemas/index.d.ts +149 -0
  32. package/dist/schemas/index.d.ts.map +1 -1
  33. package/dist/schemas/index.js +105 -1
  34. package/dist/schemas/index.js.map +1 -1
  35. package/dist/shared/InteractionContext.d.ts +10 -0
  36. package/dist/shared/InteractionContext.d.ts.map +1 -1
  37. package/dist/tool-definitions.json +135 -3
  38. package/package.json +1 -1
@@ -0,0 +1,627 @@
1
+ "use client";
2
+ import React4, { createContext, useContext, useState, useRef, useCallback, useEffect } from 'react';
3
+ import { toPng } from 'html-to-image';
4
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
+
6
+ // src/shared/theme.ts
7
+ var BORDER = "#dedede";
8
+ var MUTED = "#777777";
9
+ var PAPER = "#f6f6f6";
10
+ var ACCENT = "#ff5000";
11
+ var ACCENT_SOFT = "#cc4000";
12
+ var SECONDARY = "#0364ff";
13
+ var CHART_PALETTE = [
14
+ "#ff5000",
15
+ "#0364ff",
16
+ "#16a34a",
17
+ "#dc2626",
18
+ "#7c3aed",
19
+ "#0891b2",
20
+ "#f59e0b",
21
+ "#6366f1",
22
+ "#ec4899",
23
+ "#84cc16",
24
+ "#e11d48",
25
+ "#0ea5e9"
26
+ ];
27
+ function ColumnSettingsPanel({ columns, hidden, onToggle, onShowAll, onHideAll }) {
28
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px", minWidth: "180px" }, children: [
29
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", paddingBottom: "4px", borderBottom: `1px solid ${BORDER}` }, children: [
30
+ /* @__PURE__ */ jsx(
31
+ "button",
32
+ {
33
+ onClick: onShowAll,
34
+ style: { background: "none", border: "none", cursor: "pointer", fontSize: "11px", color: ACCENT, fontWeight: 500, padding: 0 },
35
+ children: "Show all"
36
+ }
37
+ ),
38
+ /* @__PURE__ */ jsx(
39
+ "button",
40
+ {
41
+ onClick: onHideAll,
42
+ style: { background: "none", border: "none", cursor: "pointer", fontSize: "11px", color: MUTED, fontWeight: 500, padding: 0 },
43
+ children: "Hide all"
44
+ }
45
+ )
46
+ ] }),
47
+ columns.map((col) => /* @__PURE__ */ jsxs(
48
+ "label",
49
+ {
50
+ style: { display: "flex", alignItems: "center", gap: "8px", cursor: "pointer", fontSize: "12px", color: "var(--foreground)" },
51
+ children: [
52
+ /* @__PURE__ */ jsx(
53
+ "input",
54
+ {
55
+ type: "checkbox",
56
+ checked: !hidden.has(col.key),
57
+ onChange: () => onToggle(col.key),
58
+ style: { accentColor: ACCENT, width: "14px", height: "14px", margin: 0, cursor: "pointer" }
59
+ }
60
+ ),
61
+ col.label
62
+ ]
63
+ },
64
+ col.key
65
+ ))
66
+ ] });
67
+ }
68
+ var DOT_COLOR = "#aaaaaa";
69
+ var DOT_HOVER = "#555555";
70
+ function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "component" }) {
71
+ const [open, setOpen] = useState(false);
72
+ const [view, setView] = useState("main");
73
+ const contentRef = useRef(null);
74
+ const menuRef = useRef(null);
75
+ const btnRef = useRef(null);
76
+ const close = useCallback(() => {
77
+ setOpen(false);
78
+ setView("main");
79
+ }, []);
80
+ useEffect(() => {
81
+ if (!open) return;
82
+ const handler = (e) => {
83
+ var _a, _b;
84
+ if ((_a = menuRef.current) == null ? void 0 : _a.contains(e.target)) return;
85
+ if ((_b = btnRef.current) == null ? void 0 : _b.contains(e.target)) return;
86
+ close();
87
+ };
88
+ document.addEventListener("mousedown", handler);
89
+ return () => document.removeEventListener("mousedown", handler);
90
+ }, [open, close]);
91
+ const handleDownloadPNG = useCallback(async () => {
92
+ if (!contentRef.current) return;
93
+ try {
94
+ const url = await toPng(contentRef.current, { backgroundColor: "white", pixelRatio: 2 });
95
+ const a = document.createElement("a");
96
+ a.href = url;
97
+ a.download = `${filename}.png`;
98
+ a.click();
99
+ } catch (e) {
100
+ }
101
+ close();
102
+ }, [filename, close]);
103
+ const handleCSV = useCallback(() => {
104
+ onDownloadCSV == null ? void 0 : onDownloadCSV();
105
+ close();
106
+ }, [onDownloadCSV, close]);
107
+ return /* @__PURE__ */ jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column" }, children: [
108
+ /* @__PURE__ */ jsx("div", { ref: contentRef, style: { width: "100%" }, children }),
109
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "flex-end", marginTop: "4px", position: "relative", zIndex: 10, flexShrink: 0 }, children: [
110
+ /* @__PURE__ */ jsx(
111
+ "button",
112
+ {
113
+ ref: btnRef,
114
+ onClick: () => {
115
+ setOpen((o) => !o);
116
+ setView("main");
117
+ },
118
+ "aria-label": "Component actions",
119
+ style: {
120
+ background: "none",
121
+ border: "none",
122
+ cursor: "pointer",
123
+ padding: "4px 8px",
124
+ display: "flex",
125
+ gap: "3px",
126
+ alignItems: "center",
127
+ borderRadius: "6px",
128
+ transition: "background 0.15s"
129
+ },
130
+ onMouseEnter: (e) => {
131
+ e.currentTarget.style.background = "#f2f2f2";
132
+ e.currentTarget.querySelectorAll("circle").forEach((c) => c.style.fill = DOT_HOVER);
133
+ },
134
+ onMouseLeave: (e) => {
135
+ e.currentTarget.style.background = "none";
136
+ e.currentTarget.querySelectorAll("circle").forEach((c) => c.style.fill = DOT_COLOR);
137
+ },
138
+ children: /* @__PURE__ */ jsxs("svg", { width: "20", height: "6", viewBox: "0 0 20 6", children: [
139
+ /* @__PURE__ */ jsx("circle", { cx: "3", cy: "3", r: "2", style: { fill: DOT_COLOR, transition: "fill 0.15s" } }),
140
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "3", r: "2", style: { fill: DOT_COLOR, transition: "fill 0.15s" } }),
141
+ /* @__PURE__ */ jsx("circle", { cx: "17", cy: "3", r: "2", style: { fill: DOT_COLOR, transition: "fill 0.15s" } })
142
+ ] })
143
+ }
144
+ ),
145
+ open && /* @__PURE__ */ jsx(
146
+ "div",
147
+ {
148
+ ref: menuRef,
149
+ style: {
150
+ position: "absolute",
151
+ bottom: "100%",
152
+ right: 0,
153
+ marginBottom: "4px",
154
+ background: "white",
155
+ border: `1px solid ${BORDER}`,
156
+ borderRadius: "0.75rem",
157
+ boxShadow: "0 4px 12px rgba(0,0,0,0.06)",
158
+ zIndex: 50,
159
+ padding: view === "columns" ? "10px" : "4px",
160
+ minWidth: view === "columns" ? "200px" : "160px"
161
+ },
162
+ children: view === "main" ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
163
+ columnConfig && /* @__PURE__ */ jsx(MenuButton, { label: "Customize columns", onClick: () => setView("columns") }),
164
+ onDownloadCSV && /* @__PURE__ */ jsx(MenuButton, { label: "Download CSV", onClick: handleCSV }),
165
+ /* @__PURE__ */ jsx(MenuButton, { label: "Download PNG", onClick: handleDownloadPNG })
166
+ ] }) : /* @__PURE__ */ jsxs("div", { children: [
167
+ /* @__PURE__ */ jsx(
168
+ "button",
169
+ {
170
+ onClick: () => setView("main"),
171
+ style: { background: "none", border: "none", cursor: "pointer", fontSize: "11px", color: MUTED, marginBottom: "6px", padding: 0 },
172
+ children: "\u2190 Back"
173
+ }
174
+ ),
175
+ /* @__PURE__ */ jsx(
176
+ ColumnSettingsPanel,
177
+ {
178
+ columns: columnConfig.columns,
179
+ hidden: columnConfig.hidden,
180
+ onToggle: columnConfig.onToggle,
181
+ onShowAll: columnConfig.onShowAll,
182
+ onHideAll: columnConfig.onHideAll
183
+ }
184
+ )
185
+ ] })
186
+ }
187
+ )
188
+ ] })
189
+ ] });
190
+ }
191
+ function MenuButton({ label, onClick }) {
192
+ return /* @__PURE__ */ jsx(
193
+ "button",
194
+ {
195
+ onClick,
196
+ style: {
197
+ background: "none",
198
+ border: "none",
199
+ cursor: "pointer",
200
+ padding: "8px 12px",
201
+ fontSize: "12.5px",
202
+ color: "var(--foreground)",
203
+ textAlign: "left",
204
+ borderRadius: "8px",
205
+ transition: "background 0.15s",
206
+ whiteSpace: "nowrap"
207
+ },
208
+ onMouseEnter: (e) => e.currentTarget.style.background = "#f2f2f2",
209
+ onMouseLeave: (e) => e.currentTarget.style.background = "none",
210
+ children: label
211
+ }
212
+ );
213
+ }
214
+ var DEFAULT_TOKENS = {
215
+ BORDER,
216
+ MUTED,
217
+ PAPER,
218
+ ACCENT,
219
+ ACCENT_SOFT,
220
+ SECONDARY,
221
+ CHART_PALETTE: [...CHART_PALETTE]
222
+ };
223
+ var GenUIThemeContext = createContext(DEFAULT_TOKENS);
224
+ function useTheme() {
225
+ return useContext(GenUIThemeContext);
226
+ }
227
+ var DEFAULT_INTERACTION = {
228
+ selectedStepId: null,
229
+ onStepSelect: void 0,
230
+ resolvedDecisions: void 0,
231
+ onDecisionResolve: void 0,
232
+ onDecisionSource: void 0
233
+ };
234
+ var GenUIInteractionContext = createContext(DEFAULT_INTERACTION);
235
+ function useGenUIInteraction() {
236
+ return useContext(GenUIInteractionContext);
237
+ }
238
+ var SEVERITY_COLORS = {
239
+ high: { color: "#dc2626", bg: "#fef2f2" },
240
+ medium: { color: "#f59e0b", bg: "#fff7ed" },
241
+ low: { color: "#777777", bg: "#f2f2f2" }
242
+ };
243
+ var GREEN = "#15803d";
244
+ var GREEN_SOFT = "#dcfce7";
245
+ var STACK_BELOW = 380;
246
+ function formatAmount(amount, currency = "USD") {
247
+ var _a, _b;
248
+ const abs = Math.abs(amount);
249
+ const sign = amount < 0 ? "-" : "";
250
+ let body;
251
+ if (abs >= 1e6) body = `${(abs / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;
252
+ else if (abs >= 1e3) body = `${(abs / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;
253
+ else body = `${abs}`;
254
+ let symbol = "$";
255
+ try {
256
+ const parts = new Intl.NumberFormat("en-US", {
257
+ style: "currency",
258
+ currency,
259
+ maximumFractionDigits: 0
260
+ }).formatToParts(0);
261
+ symbol = (_b = (_a = parts.find((p) => p.type === "currency")) == null ? void 0 : _a.value) != null ? _b : "$";
262
+ } catch (e) {
263
+ symbol = "$";
264
+ }
265
+ return `${sign}${symbol}${body}`;
266
+ }
267
+ function useContainerWidth(ref) {
268
+ const [w, setW] = React4.useState(0);
269
+ React4.useLayoutEffect(() => {
270
+ const el = ref.current;
271
+ if (!el || typeof ResizeObserver === "undefined") return;
272
+ const ro = new ResizeObserver((entries) => {
273
+ var _a;
274
+ const cr = (_a = entries[0]) == null ? void 0 : _a.contentRect;
275
+ if (cr) setW(cr.width);
276
+ });
277
+ ro.observe(el);
278
+ setW(el.getBoundingClientRect().width);
279
+ return () => ro.disconnect();
280
+ }, [ref]);
281
+ return w;
282
+ }
283
+ var KEYFRAMES = `
284
+ @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
285
+ .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
286
+ @media (prefers-reduced-motion: reduce){
287
+ .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
288
+ }`;
289
+ function SparkCheck({ size, color }) {
290
+ return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
291
+ "path",
292
+ {
293
+ d: "M5 13l4 4L19 7",
294
+ stroke: color,
295
+ strokeWidth: 2.5,
296
+ strokeLinecap: "round",
297
+ strokeLinejoin: "round"
298
+ }
299
+ ) });
300
+ }
301
+ function FlagPill({ flag }) {
302
+ var _a;
303
+ const sev = (_a = flag.severity) != null ? _a : "medium";
304
+ const { color, bg } = SEVERITY_COLORS[sev];
305
+ return /* @__PURE__ */ jsxs(
306
+ "span",
307
+ {
308
+ style: {
309
+ display: "inline-flex",
310
+ alignItems: "center",
311
+ gap: 5,
312
+ fontSize: 11,
313
+ fontWeight: 600,
314
+ padding: "3px 9px",
315
+ borderRadius: 9999,
316
+ background: bg,
317
+ color,
318
+ lineHeight: 1.2
319
+ },
320
+ children: [
321
+ /* @__PURE__ */ jsx(
322
+ "span",
323
+ {
324
+ "aria-hidden": "true",
325
+ style: { width: 6, height: 6, borderRadius: "50%", background: color, flexShrink: 0 }
326
+ }
327
+ ),
328
+ flag.field ? `${flag.field}: ${flag.issue}` : flag.issue
329
+ ]
330
+ }
331
+ );
332
+ }
333
+ function DecisionCardRenderer({
334
+ data,
335
+ resolved = null,
336
+ onResolve,
337
+ onOpenSource
338
+ }) {
339
+ var _a, _b;
340
+ const { BORDER: BORDER2, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
341
+ const rootRef = React4.useRef(null);
342
+ const width = useContainerWidth(rootRef);
343
+ const stacked = width > 0 && width < STACK_BELOW;
344
+ const options = (_a = data.options) != null ? _a : [];
345
+ const recommendedIdx = Math.max(
346
+ 0,
347
+ options.findIndex((o) => o.recommended)
348
+ );
349
+ const railColor = data.severity ? SEVERITY_COLORS[data.severity].color : ACCENT2;
350
+ const isResolved = Boolean(resolved);
351
+ const amountNode = typeof data.amount === "number" ? /* @__PURE__ */ jsxs(
352
+ "div",
353
+ {
354
+ style: {
355
+ display: "flex",
356
+ flexDirection: "column",
357
+ alignItems: stacked ? "flex-start" : "flex-end",
358
+ gap: 1,
359
+ flexShrink: 0
360
+ },
361
+ children: [
362
+ data.amount_label && /* @__PURE__ */ jsx(
363
+ "span",
364
+ {
365
+ style: {
366
+ fontSize: 10,
367
+ textTransform: "uppercase",
368
+ letterSpacing: "0.07em",
369
+ fontWeight: 700,
370
+ color: MUTED2
371
+ },
372
+ children: data.amount_label
373
+ }
374
+ ),
375
+ /* @__PURE__ */ jsx(
376
+ "span",
377
+ {
378
+ style: {
379
+ fontSize: 18,
380
+ fontWeight: 700,
381
+ color: "var(--foreground)",
382
+ fontVariantNumeric: "tabular-nums",
383
+ letterSpacing: "-0.01em",
384
+ lineHeight: 1.1
385
+ },
386
+ children: formatAmount(data.amount, data.currency)
387
+ }
388
+ )
389
+ ]
390
+ }
391
+ ) : null;
392
+ return /* @__PURE__ */ jsxs(
393
+ "div",
394
+ {
395
+ ref: rootRef,
396
+ className: "dc-rise",
397
+ "data-testid": "decision-card",
398
+ "data-resolved": isResolved || void 0,
399
+ style: {
400
+ position: "relative",
401
+ width: "100%",
402
+ minWidth: 0,
403
+ boxSizing: "border-box",
404
+ borderRadius: "0.75rem",
405
+ border: `1px solid ${isResolved ? GREEN_SOFT : BORDER2}`,
406
+ background: isResolved ? "#f6fef9" : "white",
407
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.04)",
408
+ padding: "16px 18px 16px 20px",
409
+ display: "flex",
410
+ flexDirection: "column",
411
+ gap: 12,
412
+ overflow: "hidden"
413
+ },
414
+ children: [
415
+ /* @__PURE__ */ jsx("style", { children: KEYFRAMES }),
416
+ /* @__PURE__ */ jsx(
417
+ "div",
418
+ {
419
+ "aria-hidden": "true",
420
+ style: {
421
+ position: "absolute",
422
+ top: 0,
423
+ left: 0,
424
+ bottom: 0,
425
+ width: 4,
426
+ background: isResolved ? GREEN : railColor
427
+ }
428
+ }
429
+ ),
430
+ /* @__PURE__ */ jsxs(
431
+ "div",
432
+ {
433
+ style: {
434
+ display: "flex",
435
+ flexDirection: stacked ? "column" : "row",
436
+ alignItems: stacked ? "flex-start" : "flex-start",
437
+ justifyContent: "space-between",
438
+ gap: stacked ? 6 : 12
439
+ },
440
+ children: [
441
+ /* @__PURE__ */ jsxs("div", { style: { minWidth: 0, display: "flex", flexDirection: "column", gap: 4 }, children: [
442
+ /* @__PURE__ */ jsx(
443
+ "span",
444
+ {
445
+ style: {
446
+ fontSize: 10.5,
447
+ textTransform: "uppercase",
448
+ letterSpacing: "0.07em",
449
+ fontWeight: 700,
450
+ color: ACCENT2
451
+ },
452
+ children: data.decision_type ? `Decision needs you \xB7 ${data.decision_type}` : "Decision needs you"
453
+ }
454
+ ),
455
+ /* @__PURE__ */ jsx(
456
+ "p",
457
+ {
458
+ style: {
459
+ fontFamily: "var(--font-serif)",
460
+ fontSize: 17,
461
+ fontWeight: 400,
462
+ color: "var(--foreground)",
463
+ letterSpacing: "-0.01em",
464
+ margin: 0,
465
+ lineHeight: 1.2
466
+ },
467
+ children: data.title
468
+ }
469
+ )
470
+ ] }),
471
+ amountNode
472
+ ]
473
+ }
474
+ ),
475
+ /* @__PURE__ */ jsx("p", { style: { fontSize: 13, lineHeight: 1.5, color: MUTED2, margin: 0 }, children: data.question }),
476
+ data.flags && data.flags.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: data.flags.map((flag, i) => {
477
+ var _a2;
478
+ return /* @__PURE__ */ jsx(FlagPill, { flag }, `${(_a2 = flag.field) != null ? _a2 : "flag"}-${i}`);
479
+ }) }),
480
+ isResolved ? /* @__PURE__ */ jsxs(
481
+ "div",
482
+ {
483
+ style: {
484
+ display: "inline-flex",
485
+ alignItems: "center",
486
+ gap: 7,
487
+ fontSize: 13,
488
+ fontWeight: 600,
489
+ color: GREEN
490
+ },
491
+ children: [
492
+ /* @__PURE__ */ jsx(SparkCheck, { size: 16, color: GREEN }),
493
+ "Resolved \xB7 ",
494
+ resolved
495
+ ]
496
+ }
497
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
498
+ /* @__PURE__ */ jsx(
499
+ "div",
500
+ {
501
+ style: {
502
+ display: "flex",
503
+ flexDirection: stacked ? "column" : "row",
504
+ flexWrap: stacked ? "nowrap" : "wrap",
505
+ gap: 8
506
+ },
507
+ children: options.map((opt, idx) => {
508
+ var _a2;
509
+ const primary = idx === recommendedIdx;
510
+ return /* @__PURE__ */ jsx(
511
+ "button",
512
+ {
513
+ type: "button",
514
+ onClick: () => onResolve == null ? void 0 : onResolve(opt.label),
515
+ style: {
516
+ width: stacked ? "100%" : "auto",
517
+ textAlign: stacked ? "left" : "center",
518
+ border: `1px solid ${primary ? ACCENT2 : BORDER2}`,
519
+ background: primary ? ACCENT2 : "white",
520
+ color: primary ? "white" : "var(--foreground)",
521
+ borderRadius: 8,
522
+ fontSize: 13,
523
+ fontWeight: 600,
524
+ padding: "9px 14px",
525
+ cursor: "pointer",
526
+ transition: "background 0.15s, border-color 0.15s, color 0.15s"
527
+ },
528
+ onMouseEnter: (e) => {
529
+ if (primary) {
530
+ e.currentTarget.style.background = ACCENT_SOFT2;
531
+ } else {
532
+ e.currentTarget.style.borderColor = ACCENT2;
533
+ e.currentTarget.style.background = "#fafafa";
534
+ }
535
+ },
536
+ onMouseLeave: (e) => {
537
+ if (primary) {
538
+ e.currentTarget.style.background = ACCENT2;
539
+ } else {
540
+ e.currentTarget.style.borderColor = BORDER2;
541
+ e.currentTarget.style.background = "white";
542
+ }
543
+ },
544
+ children: opt.label
545
+ },
546
+ (_a2 = opt.id) != null ? _a2 : opt.label
547
+ );
548
+ })
549
+ }
550
+ ),
551
+ data.source && /* @__PURE__ */ jsxs(
552
+ "button",
553
+ {
554
+ type: "button",
555
+ onClick: onOpenSource,
556
+ style: {
557
+ alignSelf: "flex-start",
558
+ display: "inline-flex",
559
+ alignItems: "center",
560
+ gap: 5,
561
+ border: "none",
562
+ background: "none",
563
+ padding: 0,
564
+ cursor: "pointer",
565
+ fontSize: 12,
566
+ fontWeight: 600,
567
+ color: MUTED2,
568
+ transition: "color 0.15s"
569
+ },
570
+ onMouseEnter: (e) => e.currentTarget.style.color = ACCENT2,
571
+ onMouseLeave: (e) => e.currentTarget.style.color = MUTED2,
572
+ children: [
573
+ /* @__PURE__ */ jsx("svg", { width: 13, height: 13, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
574
+ "path",
575
+ {
576
+ d: "M14 3v4a1 1 0 001 1h4M5 4a1 1 0 011-1h8l5 5v11a1 1 0 01-1 1H6a1 1 0 01-1-1V4z",
577
+ stroke: "currentColor",
578
+ strokeWidth: 1.8,
579
+ strokeLinecap: "round",
580
+ strokeLinejoin: "round"
581
+ }
582
+ ) }),
583
+ (_b = data.source.label) != null ? _b : "View source for this figure"
584
+ ]
585
+ }
586
+ )
587
+ ] })
588
+ ]
589
+ }
590
+ );
591
+ }
592
+ function DecisionCardResolver(p) {
593
+ var _a, _b, _c, _d;
594
+ const { resolvedDecisions, onDecisionResolve, onDecisionSource } = useGenUIInteraction();
595
+ const decisionId = (_a = p.id) != null ? _a : p.title;
596
+ const hostResolved = resolvedDecisions == null ? void 0 : resolvedDecisions[decisionId];
597
+ const initial = (_c = hostResolved != null ? hostResolved : (_b = p.resolved) == null ? void 0 : _b.option) != null ? _c : null;
598
+ const [localResolved, setLocalResolved] = React4.useState(initial);
599
+ React4.useEffect(() => {
600
+ if (hostResolved !== void 0) setLocalResolved(hostResolved);
601
+ }, [hostResolved]);
602
+ const resolved = hostResolved != null ? hostResolved : localResolved;
603
+ const handleResolve = (option) => {
604
+ setLocalResolved(option);
605
+ onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, option);
606
+ };
607
+ const handleSource = () => {
608
+ var _a2;
609
+ onDecisionSource == null ? void 0 : onDecisionSource(decisionId, p.source);
610
+ if (!onDecisionSource && ((_a2 = p.source) == null ? void 0 : _a2.url) && typeof window !== "undefined") {
611
+ window.open(p.source.url, "_blank", "noopener,noreferrer");
612
+ }
613
+ };
614
+ return /* @__PURE__ */ jsx(ComponentActions, { filename: (_d = p.title) != null ? _d : "decision-card", children: /* @__PURE__ */ jsx(
615
+ DecisionCardRenderer,
616
+ {
617
+ data: p,
618
+ resolved,
619
+ onResolve: handleResolve,
620
+ onOpenSource: handleSource
621
+ }
622
+ ) });
623
+ }
624
+
625
+ export { DecisionCardRenderer, DecisionCardResolver };
626
+ //# sourceMappingURL=resolver.js.map
627
+ //# sourceMappingURL=resolver.js.map