@humain/ui 2.1.62 → 2.1.65

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 (160) hide show
  1. package/dist/components/organisms/ai/AIToolCall/AIToolCall.d.ts +9 -3
  2. package/dist/components/organisms/ai/AIToolRun/index.d.ts +1 -1
  3. package/dist/components/organisms/ai/AIToolRun/validation.d.ts +24 -3
  4. package/dist/components/organisms/ai/_shared/format-ai-duration.d.ts +1 -0
  5. package/dist/components/organisms/ai/_shared/workflow-step-renderer.d.ts +1 -0
  6. package/dist/index.js +52 -52
  7. package/dist/index151.js +1 -1
  8. package/dist/index174.js +10 -333
  9. package/dist/index174.js.map +1 -1
  10. package/dist/index175.js +310 -137
  11. package/dist/index175.js.map +1 -1
  12. package/dist/index176.js +148 -174
  13. package/dist/index176.js.map +1 -1
  14. package/dist/index177.js +186 -78
  15. package/dist/index177.js.map +1 -1
  16. package/dist/index178.js +74 -124
  17. package/dist/index178.js.map +1 -1
  18. package/dist/index179.js +133 -1
  19. package/dist/index179.js.map +1 -0
  20. package/dist/index180.js +2 -201
  21. package/dist/index181.js +201 -0
  22. package/dist/{index180.js.map → index181.js.map} +1 -1
  23. package/dist/index183.js +130 -166
  24. package/dist/index183.js.map +1 -1
  25. package/dist/index184.js +195 -983
  26. package/dist/index184.js.map +1 -1
  27. package/dist/index185.js +1069 -369
  28. package/dist/index185.js.map +1 -1
  29. package/dist/index186.js +395 -197
  30. package/dist/index186.js.map +1 -1
  31. package/dist/index187.js +198 -243
  32. package/dist/index187.js.map +1 -1
  33. package/dist/index188.js +263 -3
  34. package/dist/index188.js.map +1 -1
  35. package/dist/index189.js +3 -209
  36. package/dist/index189.js.map +1 -1
  37. package/dist/index190.js +190 -777
  38. package/dist/index190.js.map +1 -1
  39. package/dist/index191.js +771 -252
  40. package/dist/index191.js.map +1 -1
  41. package/dist/index192.js +250 -65
  42. package/dist/index192.js.map +1 -1
  43. package/dist/index193.js +72 -523
  44. package/dist/index193.js.map +1 -1
  45. package/dist/index194.js +537 -144
  46. package/dist/index194.js.map +1 -1
  47. package/dist/index195.js +139 -720
  48. package/dist/index195.js.map +1 -1
  49. package/dist/index196.js +707 -167
  50. package/dist/index196.js.map +1 -1
  51. package/dist/index197.js +175 -151
  52. package/dist/index197.js.map +1 -1
  53. package/dist/index198.js +152 -487
  54. package/dist/index198.js.map +1 -1
  55. package/dist/index199.js +472 -225
  56. package/dist/index199.js.map +1 -1
  57. package/dist/index200.js +236 -260
  58. package/dist/index200.js.map +1 -1
  59. package/dist/index201.js +265 -215
  60. package/dist/index201.js.map +1 -1
  61. package/dist/index202.js +207 -307
  62. package/dist/index202.js.map +1 -1
  63. package/dist/index203.js +302 -135
  64. package/dist/index203.js.map +1 -1
  65. package/dist/index204.js +140 -271
  66. package/dist/index204.js.map +1 -1
  67. package/dist/index205.js +263 -253
  68. package/dist/index205.js.map +1 -1
  69. package/dist/index206.js +244 -137
  70. package/dist/index206.js.map +1 -1
  71. package/dist/index207.js +100 -238
  72. package/dist/index207.js.map +1 -1
  73. package/dist/index208.js +278 -74
  74. package/dist/index208.js.map +1 -1
  75. package/dist/index209.js +56 -97
  76. package/dist/index209.js.map +1 -1
  77. package/dist/index210.js +142 -47
  78. package/dist/index210.js.map +1 -1
  79. package/dist/index211.js +38 -84
  80. package/dist/index211.js.map +1 -1
  81. package/dist/index212.js +72 -252
  82. package/dist/index212.js.map +1 -1
  83. package/dist/index213.js +274 -26
  84. package/dist/index213.js.map +1 -1
  85. package/dist/index214.js +29 -94
  86. package/dist/index214.js.map +1 -1
  87. package/dist/index215.js +98 -25
  88. package/dist/index215.js.map +1 -1
  89. package/dist/index216.js +20 -565
  90. package/dist/index216.js.map +1 -1
  91. package/dist/index217.js +564 -17
  92. package/dist/index217.js.map +1 -1
  93. package/dist/index218.js +20 -23
  94. package/dist/index218.js.map +1 -1
  95. package/dist/index219.js +20 -95
  96. package/dist/index219.js.map +1 -1
  97. package/dist/index220.js +92 -88
  98. package/dist/index220.js.map +1 -1
  99. package/dist/index221.js +97 -29
  100. package/dist/index221.js.map +1 -1
  101. package/dist/index222.js +24 -470
  102. package/dist/index222.js.map +1 -1
  103. package/dist/index223.js +446 -196
  104. package/dist/index223.js.map +1 -1
  105. package/dist/index224.js +199 -729
  106. package/dist/index224.js.map +1 -1
  107. package/dist/index225.js +750 -61
  108. package/dist/index225.js.map +1 -1
  109. package/dist/index226.js +58 -181
  110. package/dist/index226.js.map +1 -1
  111. package/dist/index227.js +175 -259
  112. package/dist/index227.js.map +1 -1
  113. package/dist/index228.js +246 -172
  114. package/dist/index228.js.map +1 -1
  115. package/dist/index229.js +195 -32
  116. package/dist/index229.js.map +1 -1
  117. package/dist/index230.js +12 -40
  118. package/dist/index230.js.map +1 -1
  119. package/dist/index231.js +23 -26
  120. package/dist/index231.js.map +1 -1
  121. package/dist/index232.js +45 -22
  122. package/dist/index232.js.map +1 -1
  123. package/dist/index233.js +27 -48
  124. package/dist/index233.js.map +1 -1
  125. package/dist/index234.js +52 -26
  126. package/dist/index234.js.map +1 -1
  127. package/dist/index235.js +40 -225
  128. package/dist/index235.js.map +1 -1
  129. package/dist/index236.js +217 -39
  130. package/dist/index236.js.map +1 -1
  131. package/dist/index237.js +50 -0
  132. package/dist/index237.js.map +1 -0
  133. package/dist/styles.css +1 -1
  134. package/dist/wc/AIToolCall.js +218 -0
  135. package/dist/wc/AIToolCall.js.map +1 -0
  136. package/dist/wc/hf-ai-tool-call.js +34 -219
  137. package/dist/wc/hf-ai-tool-call.js.map +1 -1
  138. package/dist/wc/hf-ai-tool-run.js +673 -576
  139. package/dist/wc/hf-ai-tool-run.js.map +1 -1
  140. package/dist/wc/workflow-step-renderer.js +94 -86
  141. package/dist/wc/workflow-step-renderer.js.map +1 -1
  142. package/dist/wc-react/AIToolCall.js +218 -0
  143. package/dist/wc-react/AIToolCall.js.map +1 -0
  144. package/dist/wc-react/hf-ai-tool-call.js +32 -217
  145. package/dist/wc-react/hf-ai-tool-call.js.map +1 -1
  146. package/dist/wc-react/hf-ai-tool-run.js +698 -601
  147. package/dist/wc-react/hf-ai-tool-run.js.map +1 -1
  148. package/dist/wc-react/workflow-step-renderer.js +76 -68
  149. package/dist/wc-react/workflow-step-renderer.js.map +1 -1
  150. package/package.json +1 -1
  151. package/skills/humain-ui/SKILL.md +1 -1
  152. package/skills/humain-ui-wc/SKILL.md +1 -1
  153. package/skills/humain-ui-wc.skill +0 -0
  154. package/skills/humain-ui.skill +0 -0
  155. package/dist/index182.js +0 -143
  156. package/dist/index182.js.map +0 -1
  157. package/dist/wc/wrench.js +0 -10
  158. package/dist/wc/wrench.js.map +0 -1
  159. package/dist/wc-react/wrench.js +0 -10
  160. package/dist/wc-react/wrench.js.map +0 -1
package/dist/index183.js CHANGED
@@ -1,179 +1,143 @@
1
1
  import { cn } from "./index2.js";
2
- import { useControllableState } from "./index12.js";
3
- import { AICodeBlock } from "./index146.js";
4
- import { cva } from "class-variance-authority";
5
- import { AlertCircle, Check, ChevronDown, ChevronRight, Clock, Code, Wrench } from "lucide-react";
2
+ /* empty css */
3
+ import * as React from "react";
6
4
  import { jsx, jsxs } from "react/jsx-runtime";
7
- import { AnimatePresence, motion } from "motion/react";
8
- //#region src/components/organisms/ai/AIToolCall/AIToolCall.tsx
9
- var toolCallVariants = cva("overflow-hidden rounded-xl border transition-colors", {
10
- variants: { status: {
11
- pending: "border-border bg-muted",
12
- running: "border-primary bg-primary/10",
13
- success: "border-success/50 bg-success/10",
14
- error: "border-destructive/50 bg-destructive/10"
15
- } },
16
- defaultVariants: { status: "pending" }
17
- });
18
- var statusIconVariants = cva("size-4", {
19
- variants: { status: {
20
- pending: "text-muted-foreground",
21
- running: "text-primary animate-spin motion-reduce:animate-none",
22
- success: "text-success",
23
- error: "text-destructive"
24
- } },
25
- defaultVariants: { status: "pending" }
26
- });
27
- function StatusIcon({ status, className }) {
28
- const iconClass = cn(statusIconVariants({ status }), className);
29
- switch (status) {
30
- case "running": return /* @__PURE__ */ jsx(Clock, { className: iconClass });
31
- case "success": return /* @__PURE__ */ jsx(Check, { className: cn(iconClass, "delight-check-bounce motion-reduce:!animate-none") });
32
- case "error": return /* @__PURE__ */ jsx(AlertCircle, { className: cn(iconClass, "delight-shake motion-reduce:!animate-none") });
33
- default: return /* @__PURE__ */ jsx(Wrench, { className: iconClass });
34
- }
35
- }
36
- StatusIcon.displayName = "StatusIcon";
37
- function AIToolCallHeader({ toolName, status, isOpen, onToggle, className }) {
38
- return /* @__PURE__ */ jsxs("button", {
39
- type: "button",
40
- onClick: onToggle,
41
- "aria-expanded": isOpen,
42
- className: cn("flex items-center justify-between w-full px-4 py-3 transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring", className),
43
- children: [/* @__PURE__ */ jsxs("div", {
44
- className: "flex items-center gap-3",
45
- children: [/* @__PURE__ */ jsx(StatusIcon, {
46
- status,
47
- "aria-hidden": "true"
48
- }), /* @__PURE__ */ jsxs("div", {
49
- className: "flex flex-col items-start",
50
- children: [/* @__PURE__ */ jsx("span", {
51
- className: "text-sm font-medium text-foreground",
52
- children: toolName
53
- }), /* @__PURE__ */ jsx("span", {
54
- className: "text-xs text-text-quaternary",
55
- children: {
56
- pending: "Pending",
57
- running: "Running...",
58
- success: "Completed",
59
- error: "Failed"
60
- }[status]
61
- })]
62
- })]
63
- }), isOpen ? /* @__PURE__ */ jsx(ChevronDown, {
64
- className: "size-4 text-muted-foreground",
65
- "aria-hidden": "true"
66
- }) : /* @__PURE__ */ jsx(ChevronRight, {
67
- className: "size-4 text-muted-foreground rtl:rotate-180",
68
- "aria-hidden": "true"
69
- })]
70
- });
71
- }
72
- AIToolCallHeader.displayName = "AIToolCallHeader";
73
- function ToolCallSection({ title, icon, children, className }) {
5
+ import { useAnimate, useReducedMotion } from "motion/react";
6
+ //#region src/components/organisms/ai/AIThinkingLoader/AIThinkingLoader.tsx
7
+ function AnimatedProgressOvals({ className, animationDuration = 3e3, easing = "ease-in-out" }) {
8
+ const prefersReducedMotion = useReducedMotion();
74
9
  return /* @__PURE__ */ jsxs("div", {
75
- className: cn("space-y-2", className),
76
- children: [/* @__PURE__ */ jsxs("div", {
77
- className: "flex items-center gap-2 text-xs font-medium text-text-quaternary uppercase tracking-wide",
78
- children: [icon, title]
79
- }), children]
10
+ "data-slot": "thinking-oval",
11
+ "aria-hidden": "true",
12
+ className: cn("absolute top-0 bottom-0 pointer-events-none", className),
13
+ style: prefersReducedMotion ? void 0 : {
14
+ left: 0,
15
+ right: "100%",
16
+ animationName: "thinking-grow-empty",
17
+ animationDuration: `${animationDuration}ms`,
18
+ animationTimingFunction: easing,
19
+ animationIterationCount: "infinite",
20
+ willChange: "left, right, transform"
21
+ },
22
+ children: [
23
+ /* @__PURE__ */ jsx("div", {
24
+ className: "absolute rounded-full bg-air-200 opacity-20",
25
+ style: { inset: -40 }
26
+ }),
27
+ /* @__PURE__ */ jsx("div", {
28
+ className: "absolute rounded-full bg-air-200 opacity-50",
29
+ style: { inset: -20 }
30
+ }),
31
+ /* @__PURE__ */ jsx("div", {
32
+ className: "absolute rounded-full bg-air-200 opacity-70",
33
+ style: { inset: 0 }
34
+ })
35
+ ]
80
36
  });
81
37
  }
82
- ToolCallSection.displayName = "ToolCallSection";
83
- function formatValue(value) {
84
- if (typeof value === "string") return value;
85
- return JSON.stringify(value, null, 2);
86
- }
87
- function AIToolCall({ toolPart, defaultOpen = false, open: controlledOpen, onOpenChange, className }) {
88
- const [isOpen, setIsOpen] = useControllableState({
89
- value: controlledOpen,
90
- defaultValue: defaultOpen,
91
- onChange: onOpenChange
38
+ AnimatedProgressOvals.displayName = "AnimatedProgressOvals";
39
+ function CountdownTimer({ initialTime = 5, isActive = true, onComplete, className }) {
40
+ const [timeLeft, setTimeLeft] = React.useState(initialTime);
41
+ const [scope, animate] = useAnimate();
42
+ const prefersReducedMotion = useReducedMotion();
43
+ const isFirstTick = React.useRef(true);
44
+ React.useEffect(() => {
45
+ setTimeLeft(initialTime);
46
+ }, [initialTime]);
47
+ React.useEffect(() => {
48
+ if (!isActive) return;
49
+ const timer = setInterval(() => {
50
+ setTimeLeft((prev) => {
51
+ if (prev <= 1) {
52
+ onComplete?.();
53
+ return initialTime;
54
+ }
55
+ return prev - 1;
56
+ });
57
+ }, 1e3);
58
+ return () => clearInterval(timer);
59
+ }, [
60
+ isActive,
61
+ initialTime,
62
+ onComplete
63
+ ]);
64
+ React.useEffect(() => {
65
+ if (isFirstTick.current) {
66
+ isFirstTick.current = false;
67
+ return;
68
+ }
69
+ if (!prefersReducedMotion && scope.current) animate(scope.current, {
70
+ scale: [1.12, 1],
71
+ y: [-2, 0]
72
+ }, {
73
+ duration: .3,
74
+ ease: [
75
+ .25,
76
+ 1,
77
+ .5,
78
+ 1
79
+ ]
80
+ });
81
+ }, [
82
+ timeLeft,
83
+ animate,
84
+ prefersReducedMotion,
85
+ scope
86
+ ]);
87
+ return /* @__PURE__ */ jsx("div", {
88
+ ref: scope,
89
+ role: "timer",
90
+ "aria-label": `${timeLeft} seconds remaining`,
91
+ className: cn("flex items-center justify-center px-3 py-2 rounded-full bg-card/20 shrink-0", !prefersReducedMotion && "animate-[thinking-pop-in_0.3s_ease-out_0.3s_both]", className),
92
+ children: /* @__PURE__ */ jsxs("span", {
93
+ className: "text-sm text-foreground tabular-nums",
94
+ children: [timeLeft, "s"]
95
+ })
92
96
  });
93
- const status = toolPart.status || "pending";
94
- const handleToggle = () => {
95
- setIsOpen(!isOpen);
96
- };
97
+ }
98
+ CountdownTimer.displayName = "CountdownTimer";
99
+ function AIThinkingLoader({ loadingText = "Transferring to AI Agent: Meeting Manager", easing = "ease-in-out", showCountdown = true, countdownTime = 5, animationDuration = 3e3, onAnimationComplete, className }) {
100
+ const clipRef = React.useRef(null);
101
+ const prefersReducedMotion = useReducedMotion();
102
+ React.useEffect(() => {
103
+ if (!onAnimationComplete) return;
104
+ const oval = clipRef.current?.querySelector("[data-slot=\"thinking-oval\"]");
105
+ if (!oval) return;
106
+ const handler = () => onAnimationComplete();
107
+ oval.addEventListener("animationiteration", handler);
108
+ return () => oval.removeEventListener("animationiteration", handler);
109
+ }, [onAnimationComplete]);
97
110
  return /* @__PURE__ */ jsxs("div", {
98
- "data-slot": "ai-tool-call",
99
- className: cn(toolCallVariants({ status }), className),
100
- children: [/* @__PURE__ */ jsx(AIToolCallHeader, {
101
- toolName: toolPart.toolName,
102
- status,
103
- isOpen,
104
- onToggle: handleToggle
105
- }), /* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsx(motion.div, {
106
- initial: {
107
- height: 0,
108
- opacity: 0
109
- },
110
- animate: {
111
- height: "auto",
112
- opacity: 1
113
- },
114
- exit: {
115
- height: 0,
116
- opacity: 0
117
- },
118
- transition: { duration: .2 },
119
- className: "overflow-hidden",
120
- children: /* @__PURE__ */ jsxs("div", {
121
- className: "px-4 pb-4 space-y-4",
122
- children: [
123
- /* @__PURE__ */ jsxs("div", {
124
- className: "text-xs text-muted-foreground font-mono",
125
- children: ["ID: ", toolPart.toolCallId]
126
- }),
127
- toolPart.args && Object.keys(toolPart.args).length > 0 && /* @__PURE__ */ jsx(ToolCallSection, {
128
- title: "Input",
129
- icon: /* @__PURE__ */ jsx(Code, { className: "size-3" }),
130
- children: /* @__PURE__ */ jsx(AICodeBlock, {
131
- code: formatValue(toolPart.args),
132
- language: "json",
133
- showHeader: false,
134
- showCopyButton: true,
135
- size: "sm"
136
- })
137
- }),
138
- toolPart.result !== void 0 && /* @__PURE__ */ jsx(ToolCallSection, {
139
- title: "Output",
140
- icon: /* @__PURE__ */ jsx(Code, { className: "size-3" }),
141
- children: /* @__PURE__ */ jsx(AICodeBlock, {
142
- code: formatValue(toolPart.result),
143
- language: "json",
144
- showHeader: false,
145
- showCopyButton: true,
146
- size: "sm"
147
- })
148
- }),
149
- toolPart.error && /* @__PURE__ */ jsx("div", {
150
- className: "p-3 rounded-lg bg-destructive/20 border border-destructive/50",
151
- children: /* @__PURE__ */ jsxs("div", {
152
- className: "flex items-start gap-2",
153
- children: [/* @__PURE__ */ jsx(AlertCircle, { className: "size-4 text-destructive mt-0.5 shrink-0" }), /* @__PURE__ */ jsx("p", {
154
- className: "text-sm text-destructive",
155
- children: toolPart.error
156
- })]
157
- })
158
- })
159
- ]
111
+ "data-slot": "ai-thinking-loader",
112
+ role: "status",
113
+ "aria-live": "polite",
114
+ "aria-busy": "true",
115
+ "aria-label": loadingText,
116
+ className: cn("relative flex items-center justify-center gap-2 min-h-[3.25rem] px-4 py-2 rounded-full border border-border bg-card/60", className),
117
+ style: prefersReducedMotion ? void 0 : { animation: "thinking-fade-in 0.5s ease-out forwards, thinking-glow 4s ease-in-out 0.5s infinite" },
118
+ children: [
119
+ /* @__PURE__ */ jsx("div", {
120
+ ref: clipRef,
121
+ className: "absolute inset-0 overflow-clip rounded-full",
122
+ children: /* @__PURE__ */ jsx(AnimatedProgressOvals, {
123
+ easing,
124
+ animationDuration
125
+ })
126
+ }),
127
+ /* @__PURE__ */ jsx("span", {
128
+ className: cn("relative z-10 text-sm text-foreground whitespace-nowrap truncate font-medium", !prefersReducedMotion && "animate-[thinking-slide-in_0.35s_ease-out_0.15s_both]"),
129
+ children: loadingText
130
+ }),
131
+ showCountdown && /* @__PURE__ */ jsx(CountdownTimer, {
132
+ initialTime: countdownTime,
133
+ isActive: true,
134
+ className: "relative z-10"
160
135
  })
161
- }) })]
162
- });
163
- }
164
- AIToolCall.displayName = "AIToolCall";
165
- function AIToolCallList({ toolCalls, defaultAllOpen = false, className }) {
166
- return /* @__PURE__ */ jsx("div", {
167
- "data-slot": "ai-tool-call-list",
168
- className: cn("space-y-2", className),
169
- children: toolCalls.map((toolCall) => /* @__PURE__ */ jsx(AIToolCall, {
170
- toolPart: toolCall,
171
- defaultOpen: defaultAllOpen
172
- }, toolCall.toolCallId))
136
+ ]
173
137
  });
174
138
  }
175
- AIToolCallList.displayName = "AIToolCallList";
139
+ AIThinkingLoader.displayName = "AIThinkingLoader";
176
140
  //#endregion
177
- export { AIToolCall, AIToolCallHeader, AIToolCallList, StatusIcon, ToolCallSection, statusIconVariants, toolCallVariants };
141
+ export { AIThinkingLoader, CountdownTimer };
178
142
 
179
143
  //# sourceMappingURL=index183.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index183.js","names":[],"sources":["../src/components/organisms/ai/AIToolCall/AIToolCall.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n AlertCircle,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Code,\n Wrench,\n} from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport type * as React from 'react';\nimport { AICodeBlock } from '@/components/organisms/ai/AICodeBlock';\nimport { useControllableState } from '@/hooks/use-controllable-state';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst toolCallVariants = cva(\n 'overflow-hidden rounded-xl border transition-colors',\n {\n variants: {\n status: {\n pending: 'border-border bg-muted',\n running: 'border-primary bg-primary/10',\n success: 'border-success/50 bg-success/10',\n error: 'border-destructive/50 bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n },\n);\n\nconst statusIconVariants = cva('size-4', {\n variants: {\n status: {\n pending: 'text-muted-foreground',\n running: 'text-primary animate-spin motion-reduce:animate-none',\n success: 'text-success',\n error: 'text-destructive',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ToolCallStatus = 'pending' | 'running' | 'success' | 'error';\n\nexport interface ToolCallPart {\n /** Unique tool call ID */\n toolCallId: string;\n /** Tool name */\n toolName: string;\n /** Tool input/arguments */\n args?: Record<string, unknown>;\n /** Tool output/result */\n result?: unknown;\n /** Tool status */\n status?: ToolCallStatus;\n /** Error message if status is error */\n error?: string;\n}\n\n// =============================================================================\n// Status Icon Component\n// =============================================================================\n\ninterface StatusIconProps {\n status: ToolCallStatus;\n className?: string;\n}\n\nfunction StatusIcon({ status, className }: StatusIconProps) {\n const iconClass = cn(statusIconVariants({ status }), className);\n\n switch (status) {\n case 'running':\n return <Clock className={iconClass} />;\n case 'success':\n return (\n <Check\n className={cn(\n iconClass,\n 'delight-check-bounce motion-reduce:!animate-none',\n )}\n />\n );\n case 'error':\n return (\n <AlertCircle\n className={cn(iconClass, 'delight-shake motion-reduce:!animate-none')}\n />\n );\n default:\n return <Wrench className={iconClass} />;\n }\n}\n\nStatusIcon.displayName = 'StatusIcon';\n\n// =============================================================================\n// Tool Call Header\n// =============================================================================\n\ninterface AIToolCallHeaderProps {\n toolName: string;\n status: ToolCallStatus;\n isOpen: boolean;\n onToggle: () => void;\n className?: string;\n}\n\nfunction AIToolCallHeader({\n toolName,\n status,\n isOpen,\n onToggle,\n className,\n}: AIToolCallHeaderProps) {\n const statusLabel = {\n pending: 'Pending',\n running: 'Running...',\n success: 'Completed',\n error: 'Failed',\n };\n\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={isOpen}\n className={cn(\n 'flex items-center justify-between w-full px-4 py-3 transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',\n className,\n )}\n >\n <div className=\"flex items-center gap-3\">\n <StatusIcon status={status} aria-hidden=\"true\" />\n <div className=\"flex flex-col items-start\">\n <span className=\"text-sm font-medium text-foreground\">\n {toolName}\n </span>\n <span className=\"text-xs text-text-quaternary\">\n {statusLabel[status]}\n </span>\n </div>\n </div>\n {isOpen ? (\n <ChevronDown\n className=\"size-4 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n ) : (\n <ChevronRight\n className=\"size-4 text-muted-foreground rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n}\n\nAIToolCallHeader.displayName = 'AIToolCallHeader';\n\n// =============================================================================\n// Tool Call Section\n// =============================================================================\n\ninterface ToolCallSectionProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nfunction ToolCallSection({\n title,\n icon,\n children,\n className,\n}: ToolCallSectionProps) {\n return (\n <div className={cn('space-y-2', className)}>\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-quaternary uppercase tracking-wide\">\n {icon}\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nToolCallSection.displayName = 'ToolCallSection';\n\n// =============================================================================\n// Main AIToolCall Component\n// =============================================================================\n\nexport interface AIToolCallProps extends VariantProps<typeof toolCallVariants> {\n /** Tool call data */\n toolPart: ToolCallPart;\n /** Whether to expand by default */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value, null, 2);\n}\n\nfunction AIToolCall({\n toolPart,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n className,\n}: AIToolCallProps) {\n const [isOpen, setIsOpen] = useControllableState({\n value: controlledOpen,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const status = toolPart.status || 'pending';\n\n const handleToggle = () => {\n setIsOpen(!isOpen);\n };\n\n return (\n <div\n data-slot=\"ai-tool-call\"\n className={cn(toolCallVariants({ status }), className)}\n >\n <AIToolCallHeader\n toolName={toolPart.toolName}\n status={status}\n isOpen={isOpen}\n onToggle={handleToggle}\n />\n\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Tool Call ID */}\n <div className=\"text-xs text-muted-foreground font-mono\">\n ID: {toolPart.toolCallId}\n </div>\n\n {/* Input Section */}\n {toolPart.args && Object.keys(toolPart.args).length > 0 && (\n <ToolCallSection\n title=\"Input\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.args)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Output Section */}\n {toolPart.result !== undefined && (\n <ToolCallSection\n title=\"Output\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.result)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Error Section */}\n {toolPart.error && (\n <div className=\"p-3 rounded-lg bg-destructive/20 border border-destructive/50\">\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"size-4 text-destructive mt-0.5 shrink-0\" />\n <p className=\"text-sm text-destructive\">{toolPart.error}</p>\n </div>\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n\nAIToolCall.displayName = 'AIToolCall';\n\n// =============================================================================\n// Tool Call List Component\n// =============================================================================\n\nexport interface AIToolCallListProps {\n /** Array of tool calls */\n toolCalls: ToolCallPart[];\n /** Whether to expand all by default */\n defaultAllOpen?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIToolCallList({\n toolCalls,\n defaultAllOpen = false,\n className,\n}: AIToolCallListProps) {\n return (\n <div data-slot=\"ai-tool-call-list\" className={cn('space-y-2', className)}>\n {toolCalls.map((toolCall) => (\n <AIToolCall\n key={toolCall.toolCallId}\n toolPart={toolCall}\n defaultOpen={defaultAllOpen}\n />\n ))}\n </div>\n );\n}\n\nAIToolCallList.displayName = 'AIToolCallList';\n\nexport {\n AIToolCall,\n AIToolCallHeader,\n AIToolCallList,\n StatusIcon,\n statusIconVariants,\n ToolCallSection,\n toolCallVariants,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index183.js","names":[],"sources":["../src/components/organisms/ai/AIThinkingLoader/AIThinkingLoader.tsx"],"sourcesContent":["import './AIThinkingLoader.css';\n\nimport { useAnimate, useReducedMotion } from 'motion/react';\nimport * as React from 'react';\nimport { cn } from '@/lib/utils';\n\n// Animated Progress Ovals\n\ninterface AnimatedProgressOvalsProps {\n className?: string;\n animationDuration?: number;\n easing?: string;\n}\n\nfunction AnimatedProgressOvals({\n className,\n animationDuration = 3000,\n easing = 'ease-in-out',\n}: AnimatedProgressOvalsProps) {\n const prefersReducedMotion = useReducedMotion();\n\n return (\n <div\n data-slot=\"thinking-oval\"\n aria-hidden=\"true\"\n className={cn('absolute top-0 bottom-0 pointer-events-none', className)}\n style={\n prefersReducedMotion\n ? undefined\n : {\n left: 0,\n right: '100%',\n animationName: 'thinking-grow-empty',\n animationDuration: `${animationDuration}ms`,\n animationTimingFunction: easing,\n animationIterationCount: 'infinite',\n willChange: 'left, right, transform',\n }\n }\n >\n <div\n className=\"absolute rounded-full bg-air-200 opacity-20\"\n style={{ inset: -40 }}\n />\n <div\n className=\"absolute rounded-full bg-air-200 opacity-50\"\n style={{ inset: -20 }}\n />\n <div\n className=\"absolute rounded-full bg-air-200 opacity-70\"\n style={{ inset: 0 }}\n />\n </div>\n );\n}\n\nAnimatedProgressOvals.displayName = 'AnimatedProgressOvals';\n\n// Countdown Timer\n\nexport interface CountdownTimerProps {\n initialTime?: number;\n isActive?: boolean;\n onComplete?: () => void;\n className?: string;\n}\n\nfunction CountdownTimer({\n initialTime = 5,\n isActive = true,\n onComplete,\n className,\n}: CountdownTimerProps) {\n const [timeLeft, setTimeLeft] = React.useState(initialTime);\n const [scope, animate] = useAnimate();\n const prefersReducedMotion = useReducedMotion();\n const isFirstTick = React.useRef(true);\n\n React.useEffect(() => {\n setTimeLeft(initialTime);\n }, [initialTime]);\n\n React.useEffect(() => {\n if (!isActive) return;\n\n const timer = setInterval(() => {\n setTimeLeft((prev) => {\n if (prev <= 1) {\n onComplete?.();\n return initialTime;\n }\n return prev - 1;\n });\n }, 1000);\n\n return () => clearInterval(timer);\n }, [isActive, initialTime, onComplete]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: timeLeft is an intentional trigger — re-run pulse animation on each tick\n React.useEffect(() => {\n if (isFirstTick.current) {\n isFirstTick.current = false;\n return;\n }\n if (!prefersReducedMotion && scope.current) {\n animate(\n scope.current,\n { scale: [1.12, 1], y: [-2, 0] },\n { duration: 0.3, ease: [0.25, 1, 0.5, 1] },\n );\n }\n }, [timeLeft, animate, prefersReducedMotion, scope]);\n\n return (\n <div\n ref={scope}\n role=\"timer\"\n aria-label={`${timeLeft} seconds remaining`}\n className={cn(\n 'flex items-center justify-center px-3 py-2 rounded-full bg-card/20 shrink-0',\n !prefersReducedMotion &&\n 'animate-[thinking-pop-in_0.3s_ease-out_0.3s_both]',\n className,\n )}\n >\n <span className=\"text-sm text-foreground tabular-nums\">{timeLeft}s</span>\n </div>\n );\n}\n\nCountdownTimer.displayName = 'CountdownTimer';\n\n// Main AIThinkingLoader Component\n\nexport interface AIThinkingLoaderProps {\n loadingText?: string;\n easing?: string;\n showCountdown?: boolean;\n countdownTime?: number;\n animationDuration?: number;\n onAnimationComplete?: () => void;\n className?: string;\n}\n\nfunction AIThinkingLoader({\n loadingText = 'Transferring to AI Agent: Meeting Manager',\n easing = 'ease-in-out',\n showCountdown = true,\n countdownTime = 5,\n animationDuration = 3000,\n onAnimationComplete,\n className,\n}: AIThinkingLoaderProps) {\n const clipRef = React.useRef<HTMLDivElement>(null);\n const prefersReducedMotion = useReducedMotion();\n\n React.useEffect(() => {\n if (!onAnimationComplete) return;\n\n const oval = clipRef.current?.querySelector('[data-slot=\"thinking-oval\"]');\n if (!oval) return;\n\n const handler = () => onAnimationComplete();\n oval.addEventListener('animationiteration', handler);\n return () => oval.removeEventListener('animationiteration', handler);\n }, [onAnimationComplete]);\n\n return (\n <div\n data-slot=\"ai-thinking-loader\"\n role=\"status\"\n aria-live=\"polite\"\n aria-busy=\"true\"\n aria-label={loadingText}\n className={cn(\n 'relative flex items-center justify-center gap-2 min-h-[3.25rem] px-4 py-2 rounded-full border border-border bg-card/60',\n className,\n )}\n style={\n prefersReducedMotion\n ? undefined\n : {\n animation:\n 'thinking-fade-in 0.5s ease-out forwards, thinking-glow 4s ease-in-out 0.5s infinite',\n }\n }\n >\n <div\n ref={clipRef}\n className=\"absolute inset-0 overflow-clip rounded-full\"\n >\n <AnimatedProgressOvals\n easing={easing}\n animationDuration={animationDuration}\n />\n </div>\n\n <span\n className={cn(\n 'relative z-10 text-sm text-foreground whitespace-nowrap truncate font-medium',\n !prefersReducedMotion &&\n 'animate-[thinking-slide-in_0.35s_ease-out_0.15s_both]',\n )}\n >\n {loadingText}\n </span>\n\n {showCountdown && (\n <CountdownTimer\n initialTime={countdownTime}\n isActive={true}\n className=\"relative z-10\"\n />\n )}\n </div>\n );\n}\n\nAIThinkingLoader.displayName = 'AIThinkingLoader';\n\nexport { AIThinkingLoader, CountdownTimer };\n"],"mappings":";;;;;;AAcA,SAAS,sBAAsB,EAC7B,WACA,oBAAoB,KACpB,SAAS,iBACoB;CAC7B,MAAM,uBAAuB,iBAAiB;CAE9C,OACE,qBAAC,OAAD;EACE,aAAU;EACV,eAAY;EACZ,WAAW,GAAG,+CAA+C,SAAS;EACtE,OACE,uBACI,KAAA,IACA;GACE,MAAM;GACN,OAAO;GACP,eAAe;GACf,mBAAmB,GAAG,kBAAkB;GACxC,yBAAyB;GACzB,yBAAyB;GACzB,YAAY;EACd;YAfR;GAkBE,oBAAC,OAAD;IACE,WAAU;IACV,OAAO,EAAE,OAAO,IAAI;GACrB,CAAA;GACD,oBAAC,OAAD;IACE,WAAU;IACV,OAAO,EAAE,OAAO,IAAI;GACrB,CAAA;GACD,oBAAC,OAAD;IACE,WAAU;IACV,OAAO,EAAE,OAAO,EAAE;GACnB,CAAA;EACE;;AAET;AAEA,sBAAsB,cAAc;AAWpC,SAAS,eAAe,EACtB,cAAc,GACd,WAAW,MACX,YACA,aACsB;CACtB,MAAM,CAAC,UAAU,eAAe,MAAM,SAAS,WAAW;CAC1D,MAAM,CAAC,OAAO,WAAW,WAAW;CACpC,MAAM,uBAAuB,iBAAiB;CAC9C,MAAM,cAAc,MAAM,OAAO,IAAI;CAErC,MAAM,gBAAgB;EACpB,YAAY,WAAW;CACzB,GAAG,CAAC,WAAW,CAAC;CAEhB,MAAM,gBAAgB;EACpB,IAAI,CAAC,UAAU;EAEf,MAAM,QAAQ,kBAAkB;GAC9B,aAAa,SAAS;IACpB,IAAI,QAAQ,GAAG;KACb,aAAa;KACb,OAAO;IACT;IACA,OAAO,OAAO;GAChB,CAAC;EACH,GAAG,GAAI;EAEP,aAAa,cAAc,KAAK;CAClC,GAAG;EAAC;EAAU;EAAa;CAAU,CAAC;CAGtC,MAAM,gBAAgB;EACpB,IAAI,YAAY,SAAS;GACvB,YAAY,UAAU;GACtB;EACF;EACA,IAAI,CAAC,wBAAwB,MAAM,SACjC,QACE,MAAM,SACN;GAAE,OAAO,CAAC,MAAM,CAAC;GAAG,GAAG,CAAC,IAAI,CAAC;EAAE,GAC/B;GAAE,UAAU;GAAK,MAAM;IAAC;IAAM;IAAG;IAAK;GAAC;EAAE,CAC3C;CAEJ,GAAG;EAAC;EAAU;EAAS;EAAsB;CAAK,CAAC;CAEnD,OACE,oBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,cAAY,GAAG,SAAS;EACxB,WAAW,GACT,+EACA,CAAC,wBACC,qDACF,SACF;YAEA,qBAAC,QAAD;GAAM,WAAU;aAAhB,CAAwD,UAAS,GAAO;;CACrE,CAAA;AAET;AAEA,eAAe,cAAc;AAc7B,SAAS,iBAAiB,EACxB,cAAc,6CACd,SAAS,eACT,gBAAgB,MAChB,gBAAgB,GAChB,oBAAoB,KACpB,qBACA,aACwB;CACxB,MAAM,UAAU,MAAM,OAAuB,IAAI;CACjD,MAAM,uBAAuB,iBAAiB;CAE9C,MAAM,gBAAgB;EACpB,IAAI,CAAC,qBAAqB;EAE1B,MAAM,OAAO,QAAQ,SAAS,cAAc,+BAA6B;EACzE,IAAI,CAAC,MAAM;EAEX,MAAM,gBAAgB,oBAAoB;EAC1C,KAAK,iBAAiB,sBAAsB,OAAO;EACnD,aAAa,KAAK,oBAAoB,sBAAsB,OAAO;CACrE,GAAG,CAAC,mBAAmB,CAAC;CAExB,OACE,qBAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,aAAU;EACV,aAAU;EACV,cAAY;EACZ,WAAW,GACT,0HACA,SACF;EACA,OACE,uBACI,KAAA,IACA,EACE,WACE,sFACJ;YAhBR;GAmBE,oBAAC,OAAD;IACE,KAAK;IACL,WAAU;cAEV,oBAAC,uBAAD;KACU;KACW;IACpB,CAAA;GACE,CAAA;GAEL,oBAAC,QAAD;IACE,WAAW,GACT,gFACA,CAAC,wBACC,uDACJ;cAEC;GACG,CAAA;GAEL,iBACC,oBAAC,gBAAD;IACE,aAAa;IACb,UAAU;IACV,WAAU;GACX,CAAA;EAEA;;AAET;AAEA,iBAAiB,cAAc"}