@actioneer/ads 0.5.6 → 0.5.8

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 (149) hide show
  1. package/bin/ads-init.mjs +6 -0
  2. package/components/accordion.js +50 -48
  3. package/components/agent-icon.d.ts +12 -0
  4. package/components/agent-icon.js +135 -121
  5. package/components/ai-elements/chain-of-thought-icon.d.ts +10 -12
  6. package/components/ai-elements/chain-of-thought-icon.js +341 -201
  7. package/components/ai-elements/chain-of-thought.d.ts +2 -2
  8. package/components/ai-elements/chain-of-thought.js +108 -108
  9. package/components/ai-elements/chart.js +16 -14
  10. package/components/ai-elements/inline-citation.js +41 -41
  11. package/components/ai-elements/message.js +4 -4
  12. package/components/ai-elements/queue.js +7 -7
  13. package/components/ai-elements/research-activity.js +114 -114
  14. package/components/ai-elements/shimmer.d.ts +2 -2
  15. package/components/ai-elements/speech-input.js +28 -28
  16. package/components/ai-elements/task-progress.js +26 -16
  17. package/components/ai-elements/task.js +17 -17
  18. package/components/ai-elements/tool.js +6 -6
  19. package/components/ai-elements/transcript.js +6 -5
  20. package/components/ai-elements/voice.js +1 -1
  21. package/components/alert.js +10 -10
  22. package/components/answer-sources.d.ts +42 -0
  23. package/components/answer-sources.js +111 -0
  24. package/components/answer.js +115 -114
  25. package/components/assistant-ui/action-bar.js +94 -48
  26. package/components/assistant-ui/attachment.js +131 -103
  27. package/components/assistant-ui/badge.d.ts +1 -1
  28. package/components/assistant-ui/badge.js +17 -17
  29. package/components/assistant-ui/chain-of-thought.d.ts +1 -1
  30. package/components/assistant-ui/composer-add-context.js +9 -9
  31. package/components/assistant-ui/composer-deep-research.js +5 -5
  32. package/components/assistant-ui/composer-harness.js +12 -9
  33. package/components/assistant-ui/composer-trigger-popover.js +45 -34
  34. package/components/assistant-ui/composer.js +59 -59
  35. package/components/assistant-ui/error.js +14 -14
  36. package/components/assistant-ui/file.d.ts +1 -1
  37. package/components/assistant-ui/image.d.ts +1 -1
  38. package/components/assistant-ui/image.js +113 -103
  39. package/components/assistant-ui/markdown-text.js +18 -18
  40. package/components/assistant-ui/message.js +46 -45
  41. package/components/assistant-ui/quote.js +1 -1
  42. package/components/assistant-ui/reasoning.d.ts +1 -1
  43. package/components/assistant-ui/reasoning.js +66 -77
  44. package/components/assistant-ui/suggestions.js +4 -4
  45. package/components/assistant-ui/thread-context.d.ts +2 -0
  46. package/components/assistant-ui/thread.js +41 -40
  47. package/components/assistant-ui/tool-fallback.js +60 -63
  48. package/components/assistant-ui/tool-group.d.ts +1 -1
  49. package/components/assistant-ui/tool-group.js +36 -42
  50. package/components/audio-waveform.js +25 -24
  51. package/components/autocomplete.d.ts +1 -0
  52. package/components/autocomplete.js +45 -43
  53. package/components/avatar.js +30 -30
  54. package/components/badge.d.ts +1 -1
  55. package/components/breadcrumbs.js +2 -2
  56. package/components/button.d.ts +2 -2
  57. package/components/button.js +22 -20
  58. package/components/card.js +8 -8
  59. package/components/carousel.js +105 -104
  60. package/components/chart.js +9 -7
  61. package/components/checkbox.js +74 -38
  62. package/components/chip.d.ts +1 -1
  63. package/components/code-block.js +3 -3
  64. package/components/collapsible.js +67 -23
  65. package/components/connector-card.js +6 -6
  66. package/components/drawer.d.ts +15 -10
  67. package/components/drawer.js +78 -77
  68. package/components/dropdown.d.ts +3 -1
  69. package/components/dropdown.js +88 -79
  70. package/components/empty-state.d.ts +4 -4
  71. package/components/empty-state.js +7 -7
  72. package/components/field.d.ts +4 -0
  73. package/components/field.js +45 -34
  74. package/components/file-dropzone.js +12 -12
  75. package/components/index.d.ts +4 -0
  76. package/components/index.js +584 -553
  77. package/components/infinite-canvas.js +1 -1
  78. package/components/input-field.js +51 -46
  79. package/components/input.js +20 -20
  80. package/components/link.js +9 -9
  81. package/components/modal.js +105 -73
  82. package/components/navbar.d.ts +1 -1
  83. package/components/navbar.js +1 -1
  84. package/components/number-field.js +38 -29
  85. package/components/page-header.js +12 -12
  86. package/components/pagination.js +19 -19
  87. package/components/panel.js +2 -2
  88. package/components/pixel-blast-svg.js +3 -3
  89. package/components/pixel-icon.d.ts +3 -1
  90. package/components/pixel-icon.js +294 -215
  91. package/components/popover.d.ts +1 -1
  92. package/components/popover.js +66 -64
  93. package/components/progress-circle.js +36 -32
  94. package/components/progress.js +28 -24
  95. package/components/radio.js +59 -49
  96. package/components/resizable-panel.js +1 -1
  97. package/components/reveal.d.ts +2 -2
  98. package/components/ripple.d.ts +3 -3
  99. package/components/scroll-area.js +17 -16
  100. package/components/segmented.d.ts +4 -1
  101. package/components/segmented.js +26 -25
  102. package/components/select.d.ts +2 -0
  103. package/components/select.js +61 -57
  104. package/components/setting-row.js +45 -42
  105. package/components/sidebar.d.ts +2 -2
  106. package/components/sidebar.js +131 -127
  107. package/components/skeleton.js +5 -5
  108. package/components/spinner.d.ts +13 -4
  109. package/components/spinner.js +42 -42
  110. package/components/stepper.js +21 -21
  111. package/components/switch.js +52 -32
  112. package/components/table.d.ts +24 -7
  113. package/components/table.js +457 -220
  114. package/components/tabs.js +149 -137
  115. package/components/textarea.js +1 -2
  116. package/components/toast.js +66 -66
  117. package/components/tooltip.js +2 -2
  118. package/components/tree.js +62 -51
  119. package/components/typography.d.ts +2 -1
  120. package/components/typography.js +33 -32
  121. package/components/ui/button.d.ts +2 -2
  122. package/components/ui/button.js +19 -19
  123. package/components/ui/collapsible.d.ts +1 -5
  124. package/components/ui/dialog.d.ts +3 -3
  125. package/components/ui/dialog.js +95 -58
  126. package/components/ui/tooltip.d.ts +2 -2
  127. package/components/ui/tooltip.js +67 -33
  128. package/components/viz-charts.js +95 -95
  129. package/demo/components/add-to-artifact.js +341 -0
  130. package/demo/lib/artifact-library.js +134 -0
  131. package/fonts/aribau-grotesk-medium.woff2 +0 -0
  132. package/fonts/aribau-grotesk-regular.woff2 +0 -0
  133. package/fonts.css +11 -11
  134. package/hooks/agents-ui/use-agent-audio-visualizer-aura.js +17 -16
  135. package/hooks/agents-ui/use-agent-audio-visualizer-wave.js +21 -20
  136. package/lib/icons.d.ts +12 -0
  137. package/lib/icons.js +107 -104
  138. package/lib/motion.d.ts +42 -39
  139. package/lib/motion.js +112 -52
  140. package/lib/spinner-mark.d.ts +9 -0
  141. package/lib/spinner-mark.js +98 -0
  142. package/llms.txt +69 -26
  143. package/manifest.json +344 -42
  144. package/package.json +1 -1
  145. package/styles.css +175 -161
  146. package/theme.css +104 -128
  147. package/components/ui/collapsible.js +0 -35
  148. package/fonts/aribau-grotesk-500.otf +0 -0
  149. package/fonts/aribau-grotesk-600.woff2 +0 -0
package/bin/ads-init.mjs CHANGED
@@ -236,6 +236,9 @@ export function providersFile(language) {
236
236
  // Required ADS providers — wrap the app root once. Without TooltipProvider the
237
237
  // vendored tooltip/attachment chips crash; ToastProvider is needed to render
238
238
  // toasts; MotionConfig reducedMotion="user" honors the OS setting everywhere.
239
+ // ADS components already ship their correct motion. Keep it intact. For any
240
+ // consumer-authored state motion, import the matching named spring/variant from
241
+ // "${PKG}"; never copy spring values or create a separate timing system.
239
242
  import { TooltipProvider, ToastProvider } from "${PKG}";
240
243
  import { MotionConfig } from "motion/react";
241
244
 
@@ -311,6 +314,9 @@ const ADS_LINT_CONFIG = `// @actioneer/ads-lint — consumer mode. Every file is
311
314
  // barrel / deep-import / external-UI rules apply everywhere. See the ADS
312
315
  // import contract: import the exact named export from "${PKG}"; never
313
316
  // deep-import, alias, or hand-roll a copy.
317
+ // Motion is part of that component contract: preserve built-in ADS motion and
318
+ // import named role presets from "${PKG}" for consumer-authored transitions.
319
+ // Raw spring parameters and legacy motion-token systems are rejected.
314
320
  export default {
315
321
  imports: {
316
322
  libraryPackage: "${PKG}",
@@ -1,91 +1,93 @@
1
1
  "use client";
2
- import { jsx as n, jsxs as h } from "react/jsx-runtime";
3
- import * as r from "react";
4
- import { ChevronRight as A } from "../lib/icons.js";
5
- import { cn as c } from "../lib/cn.js";
6
- const b = r.createContext(
2
+ import { jsx as t, jsxs as x } from "react/jsx-runtime";
3
+ import * as o from "react";
4
+ import { MotionConfig as A, AnimatePresence as I, motion as N } from "motion/react";
5
+ import { ChevronRight as C } from "../lib/icons.js";
6
+ import { cn as m } from "../lib/cn.js";
7
+ import { springDisclosure as w } from "../lib/motion.js";
8
+ const y = o.createContext(
7
9
  null
8
10
  );
9
- function N(s) {
10
- const e = r.useContext(b);
11
+ function $(s) {
12
+ const e = o.useContext(y);
11
13
  if (!e)
12
14
  throw new Error(`<${s}> must be used within <Accordion>`);
13
15
  return e;
14
16
  }
15
- const w = r.forwardRef(
16
- ({ className: s, type: e = "single", defaultValue: t, children: u, ...f }, g) => {
17
- const d = r.useId(), [a, l] = r.useState(() => t === void 0 ? [] : Array.isArray(t) ? t : [t]), i = r.useCallback(
18
- (o) => {
19
- l((x) => {
20
- const p = x.includes(o);
21
- return e === "single" ? p ? [] : [o] : p ? x.filter((I) => I !== o) : [...x, o];
17
+ const v = o.forwardRef(
18
+ ({ className: s, type: e = "single", defaultValue: i, children: u, ...f }, g) => {
19
+ const c = o.useId(), [a, d] = o.useState(() => i === void 0 ? [] : Array.isArray(i) ? i : [i]), r = o.useCallback(
20
+ (n) => {
21
+ d((h) => {
22
+ const p = h.includes(n);
23
+ return e === "single" ? p ? [] : [n] : p ? h.filter((b) => b !== n) : [...h, n];
22
24
  });
23
25
  },
24
26
  [e]
25
- ), m = r.useMemo(
26
- () => ({ openItems: a, toggle: i, baseId: d }),
27
- [a, i, d]
27
+ ), l = o.useMemo(
28
+ () => ({ openItems: a, toggle: r, baseId: c }),
29
+ [a, r, c]
28
30
  );
29
- return /* @__PURE__ */ n(b.Provider, { value: m, children: /* @__PURE__ */ n(
31
+ return /* @__PURE__ */ t(y.Provider, { value: l, children: /* @__PURE__ */ t(
30
32
  "div",
31
33
  {
32
34
  ref: g,
33
- className: c(s),
35
+ className: m(s),
34
36
  ...f,
35
37
  children: u
36
38
  }
37
39
  ) });
38
40
  }
39
41
  );
40
- w.displayName = "Accordion";
41
- const C = r.forwardRef(({ className: s, value: e, title: t, children: u, ...f }, g) => {
42
- const { openItems: d, toggle: a, baseId: l } = N("AccordionItem"), i = d.includes(e), m = `${l}-trigger-${e}`, o = `${l}-panel-${e}`;
43
- return /* @__PURE__ */ h("div", { ref: g, className: c(s), ...f, children: [
44
- /* @__PURE__ */ n("h3", { className: "flex", children: /* @__PURE__ */ h(
42
+ v.displayName = "Accordion";
43
+ const R = o.forwardRef(({ className: s, value: e, title: i, children: u, ...f }, g) => {
44
+ const { openItems: c, toggle: a, baseId: d } = $("AccordionItem"), r = c.includes(e), l = `${d}-trigger-${e}`, n = `${d}-panel-${e}`;
45
+ return /* @__PURE__ */ x("div", { ref: g, className: m(s), ...f, children: [
46
+ /* @__PURE__ */ t("h3", { className: "flex", children: /* @__PURE__ */ x(
45
47
  "button",
46
48
  {
47
49
  type: "button",
48
- id: m,
49
- "aria-expanded": i,
50
- "aria-controls": o,
50
+ id: l,
51
+ "aria-expanded": r,
52
+ "aria-controls": n,
51
53
  onClick: () => a(e),
52
- className: c(
54
+ className: m(
53
55
  "flex w-full items-center gap-2 py-4 text-left font-normal",
54
56
  "outline-none focus-visible:ring-3 focus-visible:ring-ring rounded-sm",
55
57
  "transition-colors hover:text-foreground"
56
58
  ),
57
59
  children: [
58
- /* @__PURE__ */ n(
59
- A,
60
+ /* @__PURE__ */ t(
61
+ C,
60
62
  {
61
63
  "aria-hidden": !0,
62
- className: c(
63
- "size-4 shrink-0 text-muted-foreground transition-transform duration-(--duration-normal) ease-out motion-reduce:transition-none",
64
- i && "rotate-90"
64
+ className: m(
65
+ "size-4 shrink-0 text-muted-foreground transition-transform duration-200 ease-out motion-reduce:transition-none",
66
+ r && "rotate-90"
65
67
  )
66
68
  }
67
69
  ),
68
- t
70
+ i
69
71
  ]
70
72
  }
71
73
  ) }),
72
- /* @__PURE__ */ n(
73
- "div",
74
+ /* @__PURE__ */ t(A, { reducedMotion: "user", children: /* @__PURE__ */ t(I, { initial: !1, children: r && /* @__PURE__ */ t(
75
+ N.div,
74
76
  {
75
- id: o,
76
- role: "region",
77
- "aria-labelledby": m,
78
- className: c(
79
- "grid",
80
- i ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
81
- ),
82
- children: /* @__PURE__ */ n("div", { className: "overflow-hidden", children: /* @__PURE__ */ n("div", { className: "pb-4 text-xs text-muted-foreground", children: u }) })
77
+ id: n,
78
+ "aria-labelledby": l,
79
+ initial: { height: 0, opacity: 0, y: -4 },
80
+ animate: { height: "auto", opacity: 1, y: 0 },
81
+ exit: { height: 0, opacity: 0, y: -4 },
82
+ transition: w,
83
+ className: "overflow-hidden",
84
+ children: /* @__PURE__ */ t("div", { className: "pb-4 text-xs text-muted-foreground", children: u })
83
85
  }
84
- )
86
+ ) }) })
85
87
  ] });
86
88
  });
87
- C.displayName = "AccordionItem";
89
+ R.displayName = "AccordionItem";
88
90
  export {
89
- w as Accordion,
90
- C as AccordionItem
91
+ v as Accordion,
92
+ R as AccordionItem
91
93
  };
@@ -21,6 +21,8 @@ import * as React from "react";
21
21
  */
22
22
  export type AgentIconName = "orb" | "heart" | "soft-square" | "hex" | "spark" | "clover-x" | "ripple" | "bloom" | "sun" | "pulse" | "triangle" | "quad-flower" | "hexagon" | "star" | "stack" | "butterfly" | "octagon" | "heart-drop" | "soft-scallop" | "arch" | "pentagon" | "diamond" | "leaf" | "dome";
23
23
  export type AgentIconState = "default" | "thinking" | "acting" | "sleep";
24
+ /** Named product-safe recolors. Raw palette values stay inside ADS. */
25
+ export type AgentIconColorPreset = "field";
24
26
  interface AgentConfig {
25
27
  id: AgentIconName;
26
28
  name: string;
@@ -48,12 +50,22 @@ export interface AgentIconProps extends Omit<React.HTMLAttributes<HTMLSpanElemen
48
50
  interactive?: boolean;
49
51
  /** Rendered size in px (square). Defaults to 40. */
50
52
  size?: number;
53
+ /** Number of tiles per side. Defaults to 7; larger display marks can use a denser field. */
54
+ tileGridSize?: number;
55
+ /** Scale applied to the paired eyes. Defaults to 1. */
56
+ eyeScale?: number;
57
+ /** Override the paired eye color without changing the hatch palette. */
58
+ eyeColor?: string;
59
+ /** Play the staggered tile-assembly animation when mounted. Defaults to true. */
60
+ animateOnMount?: boolean;
51
61
  /**
52
62
  * Override the mark's base hue (any CSS hex). The five-tone hatch palette is
53
63
  * re-derived from it, so the whole silhouette recolors. Defaults to the
54
64
  * form's own registry color.
55
65
  */
56
66
  color?: string;
67
+ /** Product-safe named recolor. `color` wins when both are supplied. */
68
+ colorPreset?: AgentIconColorPreset;
57
69
  /**
58
70
  * Eyes follow the cursor (the "Field Agent" greeter treatment). Tracks the
59
71
  * pointer globally; disabled under reduced motion.
@@ -1,99 +1,102 @@
1
1
  "use client";
2
- import { jsx as H } from "react/jsx-runtime";
3
- import * as i from "react";
4
- import { cn as G } from "../lib/cn.js";
5
- function x(e, t, g, l = -Math.PI / 2) {
6
- const c = [], n = e * 2;
7
- for (let o = 0; o < n; o += 1) {
8
- const f = o % 2 === 0 ? t : g, m = l + Math.PI * o / e;
9
- c.push(
10
- `${(18 + Math.cos(m) * f).toFixed(2)},${(18 + Math.sin(m) * f).toFixed(2)}`
2
+ import { jsx as L } from "react/jsx-runtime";
3
+ import * as s from "react";
4
+ import { cn as ee } from "../lib/cn.js";
5
+ const te = {
6
+ field: "#4565d5"
7
+ };
8
+ function b(e, n, c, i = -Math.PI / 2) {
9
+ const p = [], t = e * 2;
10
+ for (let a = 0; a < t; a += 1) {
11
+ const g = a % 2 === 0 ? n : c, h = i + Math.PI * a / e;
12
+ p.push(
13
+ `${(18 + Math.cos(h) * g).toFixed(2)},${(18 + Math.sin(h) * g).toFixed(2)}`
11
14
  );
12
15
  }
13
- return c.join(" ");
16
+ return p.join(" ");
14
17
  }
15
- function u(e, t, g) {
16
- const l = (n, o) => Number.parseInt(n.slice(1), 16) >> o & 255, c = (n) => Math.round(l(e, n) + (l(t, n) - l(e, n)) * g);
17
- return `#${[16, 8, 0].map((n) => c(n).toString(16).padStart(2, "0")).join("")}`;
18
+ function y(e, n, c) {
19
+ const i = (t, a) => Number.parseInt(t.slice(1), 16) >> a & 255, p = (t) => Math.round(i(e, t) + (i(n, t) - i(e, t)) * c);
20
+ return `#${[16, 8, 0].map((t) => p(t).toString(16).padStart(2, "0")).join("")}`;
18
21
  }
19
- function V(e) {
22
+ function ae(e) {
20
23
  return [
21
- u(e, "#16213f", 0.2),
22
- u(e, "#ffffff", 0.04),
23
- u(e, "#ffffff", 0.16),
24
- u(e, "#ffffff", 0.3),
25
- u(e, "#233055", 0.1)
24
+ y(e, "#16213f", 0.2),
25
+ y(e, "#ffffff", 0.04),
26
+ y(e, "#ffffff", 0.16),
27
+ y(e, "#ffffff", 0.3),
28
+ y(e, "#233055", 0.1)
26
29
  ];
27
30
  }
28
- const X = [
31
+ const j = [
29
32
  { spacing: 2.15, strokeWidth: 1.38, phase: 0 },
30
33
  { spacing: 2.65, strokeWidth: 1.72, phase: 0.38 },
31
34
  { spacing: 3.1, strokeWidth: 1.78, phase: 0.72 },
32
35
  { spacing: 3.65, strokeWidth: 2.2, phase: 1.06 }
33
36
  ];
34
- function W(e, t) {
35
- const g = V(e.color), l = u(e.color, "#4fe6ff", 0.58), c = 7, n = 36 / c, o = 0.18, f = [...e.id].reduce((s, a) => s + a.charCodeAt(0), 0), m = g.flatMap(
36
- (s, a) => X.map(
37
- (d, y) => `
38
- <pattern id="${t}-hatch-${a}-${y}" width="${d.spacing}" height="${d.spacing}" patternUnits="userSpaceOnUse" patternTransform="rotate(45) translate(${d.phase} 0)">
39
- <rect width="${d.strokeWidth}" height="${d.spacing}" fill="${s}" />
37
+ function ne(e, n, c = 7) {
38
+ const i = ae(e.color), p = y(e.color, "#4fe6ff", 0.58), t = Math.max(4, Math.min(12, Math.round(c))), a = 36 / t, g = Math.min(0.18, a * 0.05), h = (t - 1) / 2, $ = Math.max(Math.hypot(h, h), 1), v = [...e.id].reduce((l, r) => l + r.charCodeAt(0), 0), C = i.flatMap(
39
+ (l, r) => j.map(
40
+ (f, m) => `
41
+ <pattern id="${n}-hatch-${r}-${m}" width="${f.spacing}" height="${f.spacing}" patternUnits="userSpaceOnUse" patternTransform="rotate(45) translate(${f.phase} 0)">
42
+ <rect width="${f.strokeWidth}" height="${f.spacing}" fill="${l}" />
40
43
  </pattern>`
41
44
  )
42
- ).join(""), h = [];
43
- for (let s = 0; s < c; s += 1)
44
- for (let a = 0; a < c; a += 1) {
45
- const d = (a * 3 + s * 5 + f) % g.length, y = (a + s * 2 + f) % X.length, b = Math.hypot(a - 3, s - 3) / Math.hypot(3, 3), k = Math.round(b * 620);
46
- h.push(
47
- `<rect class="agent-avatar__tile" x="${(a * n + o).toFixed(3)}" y="${(s * n + o).toFixed(3)}" width="${(n - o * 2).toFixed(3)}" height="${(n - o * 2).toFixed(3)}" rx="0.18" fill="url(#${t}-hatch-${d}-${y})" style="--agent-tile-delay: ${k}ms" />`
45
+ ).join(""), k = [];
46
+ for (let l = 0; l < t; l += 1)
47
+ for (let r = 0; r < t; r += 1) {
48
+ const f = (r * 3 + l * 5 + v) % i.length, m = (r + l * 2 + v) % j.length, d = Math.hypot(r - h, l - h) / $, w = Math.round(d * 620);
49
+ k.push(
50
+ `<rect class="agent-avatar__tile" x="${(r * a + g).toFixed(3)}" y="${(l * a + g).toFixed(3)}" width="${(a - g * 2).toFixed(3)}" height="${(a - g * 2).toFixed(3)}" rx="0.18" fill="url(#${n}-hatch-${f}-${m})" style="--agent-tile-delay: ${w}ms" />`
48
51
  );
49
52
  }
50
53
  return `
51
54
  <defs>
52
- <clipPath id="${t}-shape" clipPathUnits="userSpaceOnUse">${e.shape}</clipPath>
53
- ${m}
54
- <pattern id="${t}-focus-hatch" width="2.3" height="2.3" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
55
- <rect width="1.46" height="2.3" fill="${l}" />
55
+ <clipPath id="${n}-shape" clipPathUnits="userSpaceOnUse">${e.shape}</clipPath>
56
+ ${C}
57
+ <pattern id="${n}-focus-hatch" width="2.3" height="2.3" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
58
+ <rect width="1.46" height="2.3" fill="${p}" />
56
59
  </pattern>
57
60
  </defs>
58
- <g class="agent-avatar__field" clip-path="url(#${t}-shape)">${h.join("")}</g>
59
- <rect class="agent-avatar__focus-scan" x="-8" y="1" width="7" height="34" rx="3.5" fill="url(#${t}-focus-hatch)" clip-path="url(#${t}-shape)" aria-hidden="true" />
61
+ <g class="agent-avatar__field" clip-path="url(#${n}-shape)">${k.join("")}</g>
62
+ <rect class="agent-avatar__focus-scan" x="-8" y="1" width="7" height="34" rx="3.5" fill="url(#${n}-focus-hatch)" clip-path="url(#${n}-shape)" aria-hidden="true" />
60
63
  `;
61
64
  }
62
- function Q(e) {
63
- const t = e.eyeY ?? 13;
65
+ function re(e, n = 1) {
66
+ const c = 4 * n, i = 7 * n, t = (e.eyeY ?? 13) + 3.5 - i / 2, a = Math.min(1, c * 0.25), g = 14 - c / 2, h = 22 - c / 2;
64
67
  return `
65
68
  <g class="agent-avatar__eyes" fill="${e.eyeColor}" aria-hidden="true">
66
- <rect class="agent-avatar__eye agent-avatar__eye--left" x="12" y="${t}" width="4" height="7" rx="1" />
67
- <rect class="agent-avatar__eye agent-avatar__eye--right" x="20" y="${t}" width="4" height="7" rx="1" />
69
+ <rect class="agent-avatar__eye agent-avatar__eye--left" x="${g.toFixed(3)}" y="${t.toFixed(3)}" width="${c.toFixed(3)}" height="${i.toFixed(3)}" rx="${a.toFixed(3)}" />
70
+ <rect class="agent-avatar__eye agent-avatar__eye--right" x="${h.toFixed(3)}" y="${t.toFixed(3)}" width="${c.toFixed(3)}" height="${i.toFixed(3)}" rx="${a.toFixed(3)}" />
68
71
  </g>
69
72
  `;
70
73
  }
71
- const Y = [
74
+ const E = [
72
75
  { id: "orb", name: "Orb", color: "#8b66f6", shape: '<circle cx="18" cy="18" r="15.5" />' },
73
76
  { id: "heart", name: "Heart", color: "#ff4a3d", eyeY: 12.5, shape: '<path d="M18 33 5.3 20.6C-1.3 13.7 3.2 4 11.1 4c3.1 0 5.6 1.7 6.9 4.2C19.3 5.7 21.8 4 24.9 4c7.9 0 12.4 9.7 5.8 16.6Z" />' },
74
77
  { id: "soft-square", name: "Soft square", color: "#3b94d2", shape: '<rect x="3" y="3" width="30" height="30" rx="8" />' },
75
78
  { id: "hex", name: "Hex", color: "#f28aaa", shape: '<polygon points="10,3 26,3 34,18 26,33 10,33 2,18" />' },
76
79
  { id: "spark", name: "Spark", color: "#9669ee", shape: '<path d="M18 1c3 8 9 14 17 17-8 3-14 9-17 17-3-8-9-14-17-17C9 15 15 9 18 1Z" />' },
77
80
  { id: "clover-x", name: "Clover X", color: "#118a65", shape: '<path d="M18 11C14 3 7 2 4 6c-3 4 0 9 6 12-6 3-9 8-6 12 3 4 10 3 14-5 4 8 11 9 14 5 3-4 0-9-6-12 6-3 9-8 6-12-3-4-10-3-14 5Z" />' },
78
- { id: "ripple", name: "Ripple", color: "#0d8d67", shape: `<polygon points="${x(10, 15.5, 13.8)}" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" />` },
81
+ { id: "ripple", name: "Ripple", color: "#0d8d67", shape: `<polygon points="${b(10, 15.5, 13.8)}" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" />` },
79
82
  { id: "bloom", name: "Bloom", color: "#f29ab7", shape: '<circle cx="18" cy="9.5" r="6.8"/><circle cx="25.4" cy="13.8" r="6.8"/><circle cx="25.4" cy="22.2" r="6.8"/><circle cx="18" cy="26.5" r="6.8"/><circle cx="10.6" cy="22.2" r="6.8"/><circle cx="10.6" cy="13.8" r="6.8"/>' },
80
- { id: "sun", name: "Sun", color: "#ffb51b", shape: `<polygon points="${x(10, 16, 12.2)}" />` },
81
- { id: "pulse", name: "Pulse", color: "#ff6d27", shape: `<polygon points="${x(18, 16, 14.2)}" />` },
83
+ { id: "sun", name: "Sun", color: "#ffb51b", shape: `<polygon points="${b(10, 16, 12.2)}" />` },
84
+ { id: "pulse", name: "Pulse", color: "#ff6d27", shape: `<polygon points="${b(18, 16, 14.2)}" />` },
82
85
  { id: "triangle", name: "Triangle", color: "#ffb317", eyeY: 14.5, shape: '<path d="M16.2 4.5a2.05 2.05 0 0 1 3.6 0l13.1 24.3A2.15 2.15 0 0 1 31 32H5a2.15 2.15 0 0 1-1.9-3.2Z" />' },
83
86
  { id: "quad-flower", name: "Quad flower", color: "#3f96d6", shape: '<circle cx="11" cy="11" r="8"/><circle cx="25" cy="11" r="8"/><circle cx="11" cy="25" r="8"/><circle cx="25" cy="25" r="8"/>' },
84
87
  { id: "hexagon", name: "Hexagon", color: "#3a92d1", shape: '<polygon points="18,2.5 32,10.5 32,25.5 18,33.5 4,25.5 4,10.5" />' },
85
- { id: "star", name: "Star", color: "#ffb91c", eyeY: 14, shape: `<polygon points="${x(5, 16, 7.3)}" />` },
88
+ { id: "star", name: "Star", color: "#ffb91c", eyeY: 14, shape: `<polygon points="${b(5, 16, 7.3)}" />` },
86
89
  { id: "stack", name: "Stack", color: "#ff4a42", shape: '<rect x="4" y="3" width="28" height="11" rx="5.5"/><rect x="4" y="12.5" width="28" height="11" rx="5.5"/><rect x="4" y="22" width="28" height="11" rx="5.5"/>' },
87
90
  { id: "butterfly", name: "Butterfly", color: "#ef91af", shape: '<path d="M18 18C18 8 13 3 4 3c0 9 3 14 11 15-8 1-11 6-11 15 9 0 14-5 14-15 0 10 5 15 14 15 0-9-3-14-11-15 8-1 11-6 11-15-9 0-14 5-14 15Z" />' },
88
91
  { id: "octagon", name: "Octagon", color: "#128862", shape: '<polygon points="11,3 25,3 33,11 33,25 25,33 11,33 3,25 3,11" />' },
89
92
  { id: "heart-drop", name: "Heart drop", color: "#f38dac", eyeY: 12.5, shape: '<path d="M18 34 5.8 21.4C-.8 14.6 3.1 4 11.2 4c3.2 0 5.6 1.7 6.8 4.3C19.2 5.7 21.6 4 24.8 4c8.1 0 12 10.6 5.4 17.4Z" />' },
90
- { id: "soft-scallop", name: "Soft scallop", color: "#f19bb1", shape: `<polygon points="${x(12, 15.6, 14.4)}" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />` },
93
+ { id: "soft-scallop", name: "Soft scallop", color: "#f19bb1", shape: `<polygon points="${b(12, 15.6, 14.4)}" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />` },
91
94
  { id: "arch", name: "Arch", color: "#0f8c65", shape: '<path d="M5 33V17C5 8.7 10.8 3 18 3s13 5.7 13 14v16Z" />' },
92
95
  { id: "pentagon", name: "Pentagon", color: "#936af0", eyeY: 13.5, shape: '<polygon points="18,2 33,13 27,33 9,33 3,13" />' },
93
96
  { id: "diamond", name: "Diamond", color: "#368fd0", shape: '<polygon points="18,2 34,18 18,34 2,18" />' },
94
97
  { id: "leaf", name: "Leaf", color: "#ff7028", shape: '<path d="M4 32V18C4 10.3 10.3 4 18 4h14v14c0 7.7-6.3 14-14 14Z" />' },
95
98
  { id: "dome", name: "Dome", color: "#ffb614", shape: '<path d="M4 33V18C4 9.7 10.7 3 19 3h1c7.2 0 13 5.8 13 13v17Z" />' }
96
- ].map((e) => ({ ...e, eyeColor: "#171820" })), ne = Y.map((e) => e.id), Z = "ads-agent-icon-styles", J = `
99
+ ].map((e) => ({ ...e, eyeColor: "#171820" })), de = E.map((e) => e.id), z = "ads-agent-icon-styles", ie = `
97
100
  .agent-avatar { display: inline-block; flex: none; color: var(--agent-color, #4565d5); line-height: 0; }
98
101
  .agent-avatar__svg { display: block; width: 100%; height: 100%; overflow: visible; shape-rendering: geometricPrecision; }
99
102
  .agent-avatar__character,
@@ -107,6 +110,7 @@ const Y = [
107
110
  If the animation never runs, the tile still shows its natural visible state,
108
111
  so the mark can never be trapped invisible. */
109
112
  .agent-avatar__tile { transform-box: fill-box; transform-origin: center; animation: ads-agent-tile-intro 620ms cubic-bezier(0.22, 0.72, 0.24, 1) both; animation-delay: var(--agent-tile-delay, 0ms); }
113
+ .agent-avatar[data-agent-animate-on-mount="false"] .agent-avatar__tile { animation: none; opacity: 1; transform: none; }
110
114
  /* Field Agent pointer tracking: eyes ease toward the cursor; overrides the
111
115
  state eye animation while the pointer is active. */
112
116
  .agent-avatar.is-pointer-tracking .agent-avatar__eyes { animation: none !important; transform: translate(var(--agent-pointer-eye-x, 0), var(--agent-pointer-eye-y, 0)); transition: transform 70ms linear; }
@@ -134,8 +138,8 @@ const Y = [
134
138
  blink (the Field Agent greeter behaviour). Pure CSS on :hover; the
135
139
  pointer-tracking rule above wins on the eyes when the pointer is active. */
136
140
  @media (hover: hover) and (pointer: fine) {
137
- .agent-avatar:hover .agent-avatar__svg { animation: ads-agent-cute-hello 680ms cubic-bezier(0.2, 0.82, 0.24, 1) both; }
138
- .agent-avatar[data-agent-state="default"]:hover .agent-avatar__eyes { animation: ads-agent-cute-blink 680ms ease-in-out both; }
141
+ .agent-avatar[data-agent-interactive="true"]:hover .agent-avatar__svg { animation: ads-agent-cute-hello 680ms cubic-bezier(0.2, 0.82, 0.24, 1) both; }
142
+ .agent-avatar[data-agent-interactive="true"][data-agent-state="default"]:hover .agent-avatar__eyes { animation: ads-agent-cute-blink 680ms ease-in-out both; }
139
143
  }
140
144
  @media (prefers-reduced-motion: reduce) {
141
145
  .agent-avatar__character,
@@ -145,107 +149,117 @@ const Y = [
145
149
  .agent-avatar__tile { animation: none !important; opacity: 1; transform: none; transition: none; }
146
150
  }
147
151
  `;
148
- function K() {
149
- i.useEffect(() => {
150
- if (typeof document > "u" || document.getElementById(Z)) return;
152
+ function oe() {
153
+ s.useEffect(() => {
154
+ if (typeof document > "u" || document.getElementById(z)) return;
151
155
  const e = document.createElement("style");
152
- e.id = Z, e.textContent = J, document.head.appendChild(e);
156
+ e.id = z, e.textContent = ie, document.head.appendChild(e);
153
157
  }, []);
154
158
  }
155
- const ee = i.forwardRef(
159
+ const se = s.forwardRef(
156
160
  ({
157
161
  agent: e,
158
- state: t,
159
- interactive: g,
160
- size: l = 40,
161
- color: c,
162
- trackPointer: n,
163
- className: o,
164
- style: f,
165
- ...m
166
- }, h) => {
167
- K();
168
- const s = i.useMemo(
169
- () => Y.find((r) => r.id === e) ?? Y[0],
162
+ state: n,
163
+ interactive: c,
164
+ size: i = 40,
165
+ tileGridSize: p = 7,
166
+ eyeScale: t = 1,
167
+ eyeColor: a,
168
+ animateOnMount: g = !0,
169
+ color: h,
170
+ colorPreset: $,
171
+ trackPointer: v,
172
+ className: C,
173
+ style: k,
174
+ ...l
175
+ }, r) => {
176
+ oe();
177
+ const f = s.useMemo(
178
+ () => E.find((o) => o.id === e) ?? E[0],
170
179
  [e]
171
- ), a = i.useMemo(
172
- () => c ? { ...s, color: c } : s,
173
- [s, c]
174
- ), d = i.useRef(null), y = i.useCallback(
175
- (r) => {
176
- d.current = r, typeof h == "function" ? h(r) : h && (h.current = r);
180
+ ), m = h ?? ($ ? te[$] : void 0), d = s.useMemo(() => !m && !a ? f : {
181
+ ...f,
182
+ ...m ? { color: m } : {},
183
+ ...a ? { eyeColor: a } : {}
184
+ }, [f, m, a]), w = s.useRef(null), B = s.useCallback(
185
+ (o) => {
186
+ w.current = o, typeof r == "function" ? r(o) : r && (r.current = o);
177
187
  },
178
- [h]
179
- ), b = i.useId(), k = i.useMemo(
180
- () => `agent-${a.id}-${b.replace(/[^a-zA-Z0-9]/g, "")}`,
181
- [a.id, b]
182
- ), S = t !== void 0, w = g ?? !S, [O, A] = i.useState("default"), $ = i.useRef(void 0), R = S ? t : O, z = i.useMemo(() => `-${([...a.id].reduce((M, C) => M + C.charCodeAt(0), 0) % 9 * 0.11).toFixed(2)}s`, [a.id]), L = i.useMemo(
183
- () => `<g class="agent-avatar__character">${W(a, k)}${Q(
184
- a
185
- )}</g>`,
186
- [a, k]
188
+ [r]
189
+ ), I = s.useId(), F = s.useMemo(
190
+ () => `agent-${d.id}-${I.replace(/[^a-zA-Z0-9]/g, "")}`,
191
+ [d.id, I]
192
+ ), T = n !== void 0, M = c ?? !T, [D, N] = s.useState("default"), Y = s.useRef(void 0), U = T ? n : D, W = s.useMemo(() => `-${([...d.id].reduce((S, A) => S + A.charCodeAt(0), 0) % 9 * 0.11).toFixed(2)}s`, [d.id]), q = s.useMemo(
193
+ () => `<g class="agent-avatar__character">${ne(
194
+ d,
195
+ F,
196
+ p
197
+ )}${re(d, t)}</g>`,
198
+ [t, d, F, p]
187
199
  );
188
- i.useEffect(() => () => window.clearTimeout($.current), []), i.useEffect(() => {
189
- const r = d.current;
190
- if (!n || !r || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
191
- const M = 82, C = 1.55, B = 1.05;
192
- let I = 0, E = 0, v = 0;
193
- const U = () => {
194
- v = 0;
195
- const p = r.getBoundingClientRect(), N = I - (p.left + p.width / 2), F = E - (p.top + p.height / 2), _ = Math.hypot(N, F), P = Math.min(_ / M, 1), q = _ > 0 ? N / _ : 0, D = _ > 0 ? F / _ : 0;
196
- r.style.setProperty("--agent-pointer-eye-x", `${(q * C * P).toFixed(3)}px`), r.style.setProperty("--agent-pointer-eye-y", `${(D * B * P).toFixed(3)}px`);
197
- }, T = (p) => {
198
- I = p.clientX, E = p.clientY, r.classList.add("is-pointer-tracking"), v || (v = requestAnimationFrame(U));
200
+ s.useEffect(() => () => window.clearTimeout(Y.current), []), s.useEffect(() => {
201
+ const o = w.current;
202
+ if (!v || !o || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
203
+ const S = 82, A = 1.55, V = 1.05;
204
+ let P = 0, H = 0, _ = 0;
205
+ const Q = () => {
206
+ _ = 0;
207
+ const u = o.getBoundingClientRect(), O = P - (u.left + u.width / 2), R = H - (u.top + u.height / 2), x = Math.hypot(O, R), Z = Math.min(x / S, 1), J = x > 0 ? O / x : 0, K = x > 0 ? R / x : 0;
208
+ o.style.setProperty("--agent-pointer-eye-x", `${(J * A * Z).toFixed(3)}px`), o.style.setProperty("--agent-pointer-eye-y", `${(K * V * Z).toFixed(3)}px`);
209
+ }, X = (u) => {
210
+ P = u.clientX, H = u.clientY, o.classList.add("is-pointer-tracking"), _ || (_ = requestAnimationFrame(Q));
199
211
  };
200
- return window.addEventListener("pointermove", T, { passive: !0 }), () => {
201
- window.removeEventListener("pointermove", T), v && cancelAnimationFrame(v), r.classList.remove("is-pointer-tracking"), r.style.removeProperty("--agent-pointer-eye-x"), r.style.removeProperty("--agent-pointer-eye-y");
212
+ return window.addEventListener("pointermove", X, { passive: !0 }), () => {
213
+ window.removeEventListener("pointermove", X), _ && cancelAnimationFrame(_), o.classList.remove("is-pointer-tracking"), o.style.removeProperty("--agent-pointer-eye-x"), o.style.removeProperty("--agent-pointer-eye-y");
202
214
  };
203
- }, [n]);
204
- const j = w ? {
215
+ }, [v]);
216
+ const G = M ? {
205
217
  onClick: () => {
206
- window.clearTimeout($.current), A("acting"), $.current = window.setTimeout(() => A("default"), 1500);
218
+ window.clearTimeout(Y.current), N("acting"), Y.current = window.setTimeout(() => N("default"), 1500);
207
219
  }
208
220
  } : {};
209
- return /* @__PURE__ */ H(
221
+ return /* @__PURE__ */ L(
210
222
  "span",
211
223
  {
212
- ref: y,
213
- className: G(
224
+ ref: B,
225
+ className: ee(
214
226
  "agent-avatar",
215
- w && "cursor-pointer rounded-md outline-none focus-visible:ring-3 focus-visible:ring-ring",
216
- o
227
+ M && "cursor-pointer rounded-md outline-none focus-visible:ring-3 focus-visible:ring-ring",
228
+ C
217
229
  ),
218
- "data-agent-icon": a.id,
219
- "data-agent-state": R,
230
+ "data-agent-icon": d.id,
231
+ "data-agent-state": U,
232
+ "data-agent-interactive": M ? "true" : "false",
233
+ "data-agent-animate-on-mount": g ? "true" : "false",
220
234
  role: "img",
221
- "aria-label": `${a.name} agent icon`,
222
- tabIndex: w ? 0 : void 0,
235
+ "aria-label": `${d.name} agent icon`,
236
+ tabIndex: M ? 0 : void 0,
223
237
  style: {
224
- "--agent-color": a.color,
225
- "--agent-delay": z,
226
- width: l,
227
- height: l,
228
- ...f
238
+ "--agent-color": d.color,
239
+ "--agent-delay": W,
240
+ width: i,
241
+ height: i,
242
+ ...k
229
243
  },
230
- ...j,
231
- ...m,
232
- children: /* @__PURE__ */ H(
244
+ ...G,
245
+ ...l,
246
+ children: /* @__PURE__ */ L(
233
247
  "svg",
234
248
  {
235
249
  className: "agent-avatar__svg",
236
250
  viewBox: "0 0 36 36",
237
251
  focusable: "false",
238
252
  "aria-hidden": "true",
239
- dangerouslySetInnerHTML: { __html: L }
253
+ dangerouslySetInnerHTML: { __html: q }
240
254
  }
241
255
  )
242
256
  }
243
257
  );
244
258
  }
245
259
  );
246
- ee.displayName = "AgentIcon";
260
+ se.displayName = "AgentIcon";
247
261
  export {
248
- Y as AGENT_ICONS,
249
- ne as AGENT_ICON_NAMES,
250
- ee as AgentIcon
262
+ E as AGENT_ICONS,
263
+ de as AGENT_ICON_NAMES,
264
+ se as AgentIcon
251
265
  };
@@ -12,31 +12,29 @@ export interface ChainOfThoughtIconProps extends Omit<React.SVGAttributes<SVGSVG
12
12
  state: ChainOfThoughtState;
13
13
  /** Defaults to the grid's native 16 px size. */
14
14
  size?: number | string;
15
- /** Active steps animate; complete, pending, and error steps pass `false`. */
15
+ /** Active steps animate; settled steps hold the stage's authored frame. */
16
16
  animated?: boolean;
17
- /** Accessible name. Omit to keep the icon decorative — pair with `aria-hidden` at the call site, the convention every other ADS icon follows. */
17
+ /** Accessible name. Omit when adjacent text already names the state. */
18
18
  label?: string;
19
19
  }
20
20
  /**
21
- * One animated (or, for the three lifecycle states, static) squircle-grid
22
- * icon. `currentColor`-based like every ADS icon — set its color with a
23
- * `text-*` class on an ancestor, not a prop. `prefers-reduced-motion` is
24
- * already handled inside the source markup.
21
+ * One currentColor, dependency-free trace icon. Reduced motion holds the
22
+ * same representative frame used after the stage settles.
25
23
  */
26
24
  export declare const ChainOfThoughtIcon: React.ForwardRefExoticComponent<ChainOfThoughtIconProps & React.RefAttributes<SVGSVGElement>>;
27
25
  export interface TraceStateIconProps extends Omit<ChainOfThoughtIconProps, "state"> {
28
26
  /** Explicit chain-of-thought stage, when known. */
29
27
  stage?: ActiveChainOfThoughtState;
30
- /** Tool name executed by this step — used to infer a stage when `stage` is absent. */
28
+ /** Tool name used to infer a stage when `stage` is absent. */
31
29
  toolName?: string;
32
- /** ADS 2 step status changes motion/emphasis while preserving the stage icon. */
30
+ /** Step status controls motion while preserving the semantic stage. */
33
31
  status?: "active" | "complete" | "pending" | "error";
34
- /** Whole-chain outcome. Do not use this for an individual completed step. */
32
+ /** Whole-chain outcome. Do not use this for a completed individual step. */
35
33
  outcome?: "completed" | "paused" | "incomplete";
36
34
  }
37
35
  /**
38
- * Resolves a semantic stage from an explicit state or tool name. Step status
39
- * controls motion only: active animates; complete, pending, and error freeze
40
- * the same glyph. `outcome` is reserved for the whole-chain summary.
36
+ * Resolves a semantic stage from an explicit state or tool name. An active
37
+ * stage animates; settled stages keep that same icon and hold its authored
38
+ * frame. `outcome` is reserved for the whole-chain summary.
41
39
  */
42
40
  export declare const TraceStateIcon: React.ForwardRefExoticComponent<TraceStateIconProps & React.RefAttributes<SVGSVGElement>>;