@uipath/apollo-wind 2.68.0 → 2.69.0

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 (35) hide show
  1. package/dist/components/ui/code-block.cjs +375 -0
  2. package/dist/components/ui/code-block.d.ts +38 -0
  3. package/dist/components/ui/code-block.js +307 -0
  4. package/dist/components/ui/index.cjs +254 -188
  5. package/dist/components/ui/index.d.ts +6 -0
  6. package/dist/components/ui/index.js +6 -0
  7. package/dist/components/ui/json-tree-view/JsonTree.cjs +2 -2
  8. package/dist/components/ui/json-tree-view/JsonTree.js +1 -1
  9. package/dist/components/ui/json-tree-view/index.cjs +26 -23
  10. package/dist/components/ui/json-tree-view/index.d.ts +2 -2
  11. package/dist/components/ui/json-tree-view/index.js +2 -2
  12. package/dist/components/ui/live-region.cjs +106 -0
  13. package/dist/components/ui/live-region.d.ts +31 -0
  14. package/dist/components/ui/live-region.js +72 -0
  15. package/dist/components/ui/loading-dots.cjs +95 -0
  16. package/dist/components/ui/loading-dots.d.ts +21 -0
  17. package/dist/components/ui/loading-dots.js +55 -0
  18. package/dist/components/ui/markdown.cjs +428 -0
  19. package/dist/components/ui/markdown.d.ts +55 -0
  20. package/dist/components/ui/markdown.js +378 -0
  21. package/dist/components/ui/thinking-indicator.cjs +146 -0
  22. package/dist/components/ui/thinking-indicator.d.ts +38 -0
  23. package/dist/components/ui/thinking-indicator.js +106 -0
  24. package/dist/components/ui/tool-call.cjs +359 -0
  25. package/dist/components/ui/tool-call.d.ts +75 -0
  26. package/dist/components/ui/tool-call.js +301 -0
  27. package/dist/index.cjs +321 -252
  28. package/dist/index.d.ts +12 -0
  29. package/dist/index.js +7 -1
  30. package/dist/styles.css +206 -0
  31. package/dist/tailwind.utilities.css +21 -0
  32. package/package.json +7 -1
  33. /package/dist/{components/ui/json-tree-view → lib}/clipboard.cjs +0 -0
  34. /package/dist/{components/ui/json-tree-view → lib}/clipboard.d.ts +0 -0
  35. /package/dist/{components/ui/json-tree-view → lib}/clipboard.js +0 -0
@@ -0,0 +1,378 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { createContext, forwardRef, useContext, useId, useMemo } from "react";
3
+ import react_markdown from "react-markdown";
4
+ import rehype_katex from "rehype-katex";
5
+ import remark_gfm from "remark-gfm";
6
+ import remark_math from "remark-math";
7
+ import { CodeBlock, DEFAULT_CODE_BLOCK_STRINGS } from "./code-block.js";
8
+ import { cn } from "../../lib/index.js";
9
+ function hastText(node) {
10
+ if ('text' === node.type) return node.value ?? '';
11
+ return (node.children ?? []).map(hastText).join('');
12
+ }
13
+ function languageOf(node) {
14
+ const className = node.properties?.className;
15
+ const classes = Array.isArray(className) ? className.map(String) : [];
16
+ return classes.find((name)=>name.startsWith('language-'))?.slice('language-'.length);
17
+ }
18
+ const opensInNewTab = (href)=>!!href && !/^(#|mailto:|tel:)/i.test(href);
19
+ const BR_TAG = /^<br\s*\/?>$/i;
20
+ function remarkHtmlBreaks() {
21
+ const visit = (node)=>{
22
+ if (!node.children) return;
23
+ node.children = node.children.map((child)=>'html' === child.type && BR_TAG.test(child.value?.trim() ?? '') ? {
24
+ type: 'break'
25
+ } : child);
26
+ node.children.forEach(visit);
27
+ };
28
+ return (tree)=>visit(tree);
29
+ }
30
+ const CURSOR_CONTAINERS = new Set([
31
+ 'ul',
32
+ 'ol',
33
+ 'li',
34
+ 'blockquote',
35
+ 'table',
36
+ 'thead',
37
+ 'tbody',
38
+ 'tr'
39
+ ]);
40
+ const CURSOR_TEXT_BLOCKS = new Set([
41
+ 'p',
42
+ 'h1',
43
+ 'h2',
44
+ 'h3',
45
+ 'h4',
46
+ 'h5',
47
+ 'h6',
48
+ 'td',
49
+ 'th'
50
+ ]);
51
+ const CURSOR_CLASS = 'ml-0.5 inline-block h-[1.1em] w-[0.45em] translate-y-[0.2em] rounded-[1px] bg-foreground animate-pulse motion-reduce:animate-none';
52
+ function lastContent(node) {
53
+ const children = node.children ?? [];
54
+ for(let i = children.length - 1; i >= 0; i--){
55
+ const child = children[i];
56
+ if ('element' === child.type) return child;
57
+ if ('text' === child.type && child.value?.trim()) return child;
58
+ }
59
+ }
60
+ function findCursorHost(root) {
61
+ let node = root;
62
+ for(;;){
63
+ const last = lastContent(node);
64
+ if (last?.type !== 'element' || !last.tagName) return node;
65
+ if (CURSOR_TEXT_BLOCKS.has(last.tagName)) return last;
66
+ if (!CURSOR_CONTAINERS.has(last.tagName)) return node;
67
+ node = last;
68
+ }
69
+ }
70
+ function rehypeStreamingCursor() {
71
+ return (tree)=>{
72
+ const host = findCursorHost(tree);
73
+ host.children = [
74
+ ...host.children ?? [],
75
+ {
76
+ type: 'element',
77
+ tagName: 'span',
78
+ properties: {
79
+ dataSlot: 'markdown-cursor',
80
+ ariaHidden: 'true',
81
+ className: [
82
+ CURSOR_CLASS
83
+ ]
84
+ },
85
+ children: []
86
+ }
87
+ ];
88
+ };
89
+ }
90
+ function rehypeScopeFootnoteLabel(options) {
91
+ const LABEL = 'footnote-label';
92
+ const scoped = `${options.prefix}${LABEL}`;
93
+ const visit = (node)=>{
94
+ const properties = node.properties;
95
+ if (properties?.id === LABEL) properties.id = scoped;
96
+ if (properties && Array.isArray(properties.ariaDescribedBy)) properties.ariaDescribedBy = properties.ariaDescribedBy.map((ref)=>ref === LABEL ? scoped : ref);
97
+ node.children?.forEach(visit);
98
+ };
99
+ return (tree)=>visit(tree);
100
+ }
101
+ const DEFAULT_MARKDOWN_STRINGS = {
102
+ ...DEFAULT_CODE_BLOCK_STRINGS,
103
+ footnotes: 'Footnotes',
104
+ footnoteBack: 'Back to content',
105
+ taskDone: 'Done',
106
+ taskOpen: 'Not done'
107
+ };
108
+ function isAllowedImageSrc(src, policy) {
109
+ if ('none' === policy) return false;
110
+ if ('all' === policy) return true;
111
+ if ('function' == typeof policy) return policy(src);
112
+ try {
113
+ const base = "u" < typeof window ? 'https://relative.invalid' : window.location.href;
114
+ return new URL(src, base).origin === new URL(base).origin;
115
+ } catch {
116
+ return false;
117
+ }
118
+ }
119
+ const MarkdownContext = /*#__PURE__*/ createContext({
120
+ strings: DEFAULT_MARKDOWN_STRINGS,
121
+ images: 'none',
122
+ codeWrap: false
123
+ });
124
+ const InsideLinkContext = /*#__PURE__*/ createContext(false);
125
+ const LINK_CLASS = 'font-medium text-foreground-link underline underline-offset-2 hover:no-underline';
126
+ function MarkdownLink({ node: _node, className, href, children, ...rest }) {
127
+ return /*#__PURE__*/ jsx("a", {
128
+ href: href,
129
+ className: cn(LINK_CLASS, className),
130
+ ...opensInNewTab(href) ? {
131
+ target: '_blank',
132
+ rel: 'noreferrer'
133
+ } : {},
134
+ ...rest,
135
+ children: /*#__PURE__*/ jsx(InsideLinkContext.Provider, {
136
+ value: true,
137
+ children: children
138
+ })
139
+ });
140
+ }
141
+ function MarkdownImage({ node: _node, className, alt, src, ...rest }) {
142
+ const { images } = useContext(MarkdownContext);
143
+ const insideLink = useContext(InsideLinkContext);
144
+ const source = 'string' == typeof src ? src : '';
145
+ if (source && isAllowedImageSrc(source, images)) return /*#__PURE__*/ jsx("img", {
146
+ alt: alt ?? '',
147
+ src: source,
148
+ loading: "lazy",
149
+ referrerPolicy: "no-referrer",
150
+ className: cn('h-auto max-w-full rounded-md', className),
151
+ ...rest
152
+ });
153
+ const label = alt || source;
154
+ if (insideLink || !source) return /*#__PURE__*/ jsx("span", {
155
+ "data-slot": "markdown-image-text",
156
+ children: label
157
+ });
158
+ return /*#__PURE__*/ jsx("a", {
159
+ "data-slot": "markdown-image-link",
160
+ href: source,
161
+ target: "_blank",
162
+ rel: "noreferrer",
163
+ className: LINK_CLASS,
164
+ children: label
165
+ });
166
+ }
167
+ function MarkdownInput({ node: _node, className, type, checked, ...rest }) {
168
+ const { strings } = useContext(MarkdownContext);
169
+ if ('checkbox' !== type) return /*#__PURE__*/ jsx("input", {
170
+ type: type,
171
+ className: className,
172
+ ...rest
173
+ });
174
+ return /*#__PURE__*/ jsxs(Fragment, {
175
+ children: [
176
+ /*#__PURE__*/ jsx("input", {
177
+ type: "checkbox",
178
+ checked: checked,
179
+ "aria-hidden": "true",
180
+ tabIndex: -1,
181
+ className: cn('mr-2 size-3.5 translate-y-0.5 accent-primary', className),
182
+ ...rest
183
+ }),
184
+ /*#__PURE__*/ jsxs("span", {
185
+ "data-slot": "markdown-task-state",
186
+ className: "sr-only",
187
+ children: [
188
+ checked ? strings.taskDone : strings.taskOpen,
189
+ ' '
190
+ ]
191
+ })
192
+ ]
193
+ });
194
+ }
195
+ function MarkdownPre({ node, children, ...rest }) {
196
+ const { strings, codeWrap, renderCodeActions } = useContext(MarkdownContext);
197
+ const codeNode = node?.children?.find((child)=>'element' === child.type && 'code' === child.tagName);
198
+ if (!codeNode) return /*#__PURE__*/ jsx("pre", {
199
+ ...rest,
200
+ children: children
201
+ });
202
+ const block = {
203
+ code: hastText(codeNode).replace(/\n$/, ''),
204
+ language: languageOf(codeNode)
205
+ };
206
+ return /*#__PURE__*/ jsx(CodeBlock, {
207
+ code: block.code,
208
+ language: block.language,
209
+ wrap: codeWrap,
210
+ actions: renderCodeActions?.(block),
211
+ strings: strings
212
+ });
213
+ }
214
+ const BUILT_IN_COMPONENTS = {
215
+ h1: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("h1", {
216
+ className: cn('text-xl font-semibold tracking-tight', className),
217
+ ...rest
218
+ }),
219
+ h2: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("h2", {
220
+ className: cn('text-lg font-semibold tracking-tight', className),
221
+ ...rest
222
+ }),
223
+ h3: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("h3", {
224
+ className: cn('text-base font-semibold', className),
225
+ ...rest
226
+ }),
227
+ h4: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("h4", {
228
+ className: cn('text-sm font-semibold', className),
229
+ ...rest
230
+ }),
231
+ h5: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("h5", {
232
+ className: cn('text-sm font-semibold', className),
233
+ ...rest
234
+ }),
235
+ h6: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("h6", {
236
+ className: cn('text-sm font-semibold text-muted-foreground', className),
237
+ ...rest
238
+ }),
239
+ p: ({ node: _node, ...rest })=>/*#__PURE__*/ jsx("p", {
240
+ ...rest
241
+ }),
242
+ a: MarkdownLink,
243
+ ul: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("ul", {
244
+ className: cn('flex flex-col gap-1 pl-6', className?.includes('contains-task-list') ? 'list-none pl-1' : 'list-disc', 'marker:text-muted-foreground', className),
245
+ ...rest
246
+ }),
247
+ ol: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("ol", {
248
+ className: cn('flex list-decimal flex-col gap-1 pl-6 marker:text-muted-foreground', className),
249
+ ...rest
250
+ }),
251
+ li: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("li", {
252
+ className: cn('pl-1 [&>ol]:mt-1 [&>p+p]:mt-2 [&>ul]:mt-1 [&>ul.contains-task-list]:pl-6', className),
253
+ ...rest
254
+ }),
255
+ input: MarkdownInput,
256
+ blockquote: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("blockquote", {
257
+ className: cn('flex flex-col gap-2 border-l-2 border-border pl-4 text-muted-foreground', className),
258
+ ...rest
259
+ }),
260
+ hr: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("hr", {
261
+ className: cn('border-border-subtle', className),
262
+ ...rest
263
+ }),
264
+ img: MarkdownImage,
265
+ table: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("div", {
266
+ "data-slot": "markdown-table",
267
+ tabIndex: 0,
268
+ className: "max-w-full overflow-x-auto rounded-lg border border-border-subtle outline-none focus-visible:ring-2 focus-visible:ring-ring",
269
+ children: /*#__PURE__*/ jsx("table", {
270
+ className: cn('w-full border-collapse text-left [&_tr:last-child>td]:border-b-0', className),
271
+ ...rest
272
+ })
273
+ }),
274
+ th: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("th", {
275
+ className: cn('border-b border-border-subtle bg-surface-overlay px-3 py-2 font-semibold', className),
276
+ ...rest
277
+ }),
278
+ td: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("td", {
279
+ className: cn('border-b border-border-subtle px-3 py-2 align-top', className),
280
+ ...rest
281
+ }),
282
+ code: ({ node: _node, className, ...rest })=>/*#__PURE__*/ jsx("code", {
283
+ className: cn('rounded-md bg-surface-overlay px-1.5 py-0.5 font-mono text-[0.875em]', className),
284
+ ...rest
285
+ }),
286
+ pre: MarkdownPre
287
+ };
288
+ const Markdown = /*#__PURE__*/ forwardRef(({ children, components, remarkPlugins, rehypePlugins, streaming = false, images = 'none', codeWrap = false, renderCodeActions, strings, className, ...props }, ref)=>{
289
+ const context = useMemo(()=>({
290
+ strings: {
291
+ ...DEFAULT_MARKDOWN_STRINGS,
292
+ ...strings
293
+ },
294
+ images,
295
+ codeWrap,
296
+ renderCodeActions
297
+ }), [
298
+ strings,
299
+ images,
300
+ codeWrap,
301
+ renderCodeActions
302
+ ]);
303
+ const { footnotes, footnoteBack } = context.strings;
304
+ const footnotePrefix = `markdown${useId().replace(/[^\w-]/g, '')}-`;
305
+ const mergedComponents = useMemo(()=>components ? {
306
+ ...BUILT_IN_COMPONENTS,
307
+ ...components
308
+ } : BUILT_IN_COMPONENTS, [
309
+ components
310
+ ]);
311
+ const mergedRemarkPlugins = useMemo(()=>[
312
+ remark_gfm,
313
+ [
314
+ remark_math,
315
+ {
316
+ singleDollarTextMath: false
317
+ }
318
+ ],
319
+ remarkHtmlBreaks,
320
+ ...remarkPlugins ?? []
321
+ ], [
322
+ remarkPlugins
323
+ ]);
324
+ const mergedRehypePlugins = useMemo(()=>[
325
+ [
326
+ rehypeScopeFootnoteLabel,
327
+ {
328
+ prefix: footnotePrefix
329
+ }
330
+ ],
331
+ [
332
+ rehype_katex,
333
+ {
334
+ output: 'mathml',
335
+ throwOnError: false,
336
+ trust: false,
337
+ strict: 'ignore'
338
+ }
339
+ ],
340
+ ...rehypePlugins ?? [],
341
+ ...streaming ? [
342
+ rehypeStreamingCursor
343
+ ] : []
344
+ ], [
345
+ rehypePlugins,
346
+ streaming,
347
+ footnotePrefix
348
+ ]);
349
+ const remarkRehypeOptions = useMemo(()=>({
350
+ clobberPrefix: footnotePrefix,
351
+ footnoteLabel: footnotes,
352
+ footnoteBackLabel: footnoteBack
353
+ }), [
354
+ footnotePrefix,
355
+ footnotes,
356
+ footnoteBack
357
+ ]);
358
+ return /*#__PURE__*/ jsx("div", {
359
+ ref: ref,
360
+ "data-slot": "markdown",
361
+ "data-streaming": streaming || void 0,
362
+ "aria-busy": streaming || void 0,
363
+ className: cn('flex min-w-0 flex-col gap-3 text-sm leading-relaxed break-words text-foreground [&_math]:text-[1.15em] [&>.katex]:overflow-x-auto [&>.katex]:py-1', className),
364
+ ...props,
365
+ children: /*#__PURE__*/ jsx(MarkdownContext.Provider, {
366
+ value: context,
367
+ children: /*#__PURE__*/ jsx(react_markdown, {
368
+ components: mergedComponents,
369
+ remarkPlugins: mergedRemarkPlugins,
370
+ rehypePlugins: mergedRehypePlugins,
371
+ remarkRehypeOptions: remarkRehypeOptions,
372
+ children: children
373
+ })
374
+ })
375
+ });
376
+ });
377
+ Markdown.displayName = 'Markdown';
378
+ export { DEFAULT_MARKDOWN_STRINGS, Markdown };
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ "use client";
3
+ var __webpack_require__ = {};
4
+ (()=>{
5
+ __webpack_require__.d = (exports1, definition)=>{
6
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ get: definition[key]
9
+ });
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.r = (exports1)=>{
17
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
18
+ value: 'Module'
19
+ });
20
+ Object.defineProperty(exports1, '__esModule', {
21
+ value: true
22
+ });
23
+ };
24
+ })();
25
+ var __webpack_exports__ = {};
26
+ __webpack_require__.r(__webpack_exports__);
27
+ __webpack_require__.d(__webpack_exports__, {
28
+ thinkingIndicatorVariants: ()=>thinkingIndicatorVariants,
29
+ DEFAULT_THINKING_INDICATOR_STRINGS: ()=>DEFAULT_THINKING_INDICATOR_STRINGS,
30
+ ThinkingIndicator: ()=>ThinkingIndicator
31
+ });
32
+ const jsx_runtime_namespaceObject = require("react/jsx-runtime");
33
+ const external_class_variance_authority_namespaceObject = require("class-variance-authority");
34
+ const external_lucide_react_namespaceObject = require("lucide-react");
35
+ const external_react_namespaceObject = require("react");
36
+ const index_cjs_namespaceObject = require("../../lib/index.cjs");
37
+ const REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)';
38
+ function getPrefersReducedMotion() {
39
+ if ("u" < typeof window || 'function' != typeof window.matchMedia) return false;
40
+ return window.matchMedia(REDUCED_MOTION_QUERY).matches;
41
+ }
42
+ function usePrefersReducedMotion() {
43
+ const [reduced, setReduced] = external_react_namespaceObject.useState(getPrefersReducedMotion);
44
+ external_react_namespaceObject.useEffect(()=>{
45
+ if ('function' != typeof window.matchMedia) return;
46
+ const mql = window.matchMedia(REDUCED_MOTION_QUERY);
47
+ const onChange = ()=>setReduced(mql.matches);
48
+ mql.addEventListener('change', onChange);
49
+ return ()=>mql.removeEventListener('change', onChange);
50
+ }, []);
51
+ return reduced;
52
+ }
53
+ const thinkingIndicatorVariants = (0, external_class_variance_authority_namespaceObject.cva)('inline-flex max-w-full min-w-0 items-center text-muted-foreground', {
54
+ variants: {
55
+ size: {
56
+ sm: 'gap-1.5 text-xs [&_[data-slot=thinking-indicator-icon]]:size-3.5',
57
+ md: 'gap-2 text-sm [&_[data-slot=thinking-indicator-icon]]:size-4'
58
+ }
59
+ },
60
+ defaultVariants: {
61
+ size: 'md'
62
+ }
63
+ });
64
+ const DEFAULT_THINKING_INDICATOR_STRINGS = {
65
+ label: 'Thinking'
66
+ };
67
+ const ThinkingIndicator = /*#__PURE__*/ external_react_namespaceObject.forwardRef(({ className, size = 'md', label, messages, interval = 2500, strings, icon, 'aria-label': ariaLabel, ...props }, ref)=>{
68
+ const text = {
69
+ ...DEFAULT_THINKING_INDICATOR_STRINGS,
70
+ ...strings
71
+ };
72
+ const staticLabel = label ?? text.label;
73
+ const name = ariaLabel ?? staticLabel;
74
+ const labels = messages && messages.length > 0 ? messages : [
75
+ staticLabel
76
+ ];
77
+ const reducedMotion = usePrefersReducedMotion();
78
+ const rotates = labels.length > 1 && !reducedMotion && interval > 0;
79
+ const rotationKey = `${rotates}\u0000${labels.join('\u0000')}`;
80
+ const [index, setIndex] = external_react_namespaceObject.useState(0);
81
+ const [prevRotationKey, setPrevRotationKey] = external_react_namespaceObject.useState(rotationKey);
82
+ if (rotationKey !== prevRotationKey) {
83
+ setPrevRotationKey(rotationKey);
84
+ setIndex(0);
85
+ }
86
+ external_react_namespaceObject.useEffect(()=>{
87
+ if (!rotates) return;
88
+ const id = window.setInterval(()=>{
89
+ setIndex((current)=>(current + 1) % labels.length);
90
+ }, interval);
91
+ return ()=>window.clearInterval(id);
92
+ }, [
93
+ rotates,
94
+ labels.length,
95
+ interval,
96
+ rotationKey
97
+ ]);
98
+ const activeIndex = index < labels.length ? index : 0;
99
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
100
+ ref: ref,
101
+ "data-slot": "thinking-indicator",
102
+ "data-size": size,
103
+ role: "status",
104
+ "aria-label": name,
105
+ className: (0, index_cjs_namespaceObject.cn)(thinkingIndicatorVariants({
106
+ size
107
+ }), className),
108
+ ...props,
109
+ children: [
110
+ null !== icon && false !== icon && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
111
+ "data-slot": "thinking-indicator-icon",
112
+ "aria-hidden": "true",
113
+ className: "inline-flex shrink-0 items-center justify-center [&>svg]:size-full",
114
+ children: icon ?? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_lucide_react_namespaceObject.Sparkles, {
115
+ className: "text-primary animate-pulse motion-reduce:animate-none"
116
+ })
117
+ }),
118
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
119
+ "data-slot": "thinking-indicator-label",
120
+ "aria-hidden": "true",
121
+ className: "grid min-w-0",
122
+ children: labels.map((item, i)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
123
+ "data-active": i === activeIndex,
124
+ className: "shimmer col-start-1 row-start-1 truncate transition-opacity duration-300 data-[active=false]:opacity-0 motion-reduce:transition-none",
125
+ children: item
126
+ }, i))
127
+ }),
128
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
129
+ className: "sr-only",
130
+ children: name
131
+ })
132
+ ]
133
+ });
134
+ });
135
+ ThinkingIndicator.displayName = 'ThinkingIndicator';
136
+ exports.DEFAULT_THINKING_INDICATOR_STRINGS = __webpack_exports__.DEFAULT_THINKING_INDICATOR_STRINGS;
137
+ exports.ThinkingIndicator = __webpack_exports__.ThinkingIndicator;
138
+ exports.thinkingIndicatorVariants = __webpack_exports__.thinkingIndicatorVariants;
139
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
140
+ "DEFAULT_THINKING_INDICATOR_STRINGS",
141
+ "ThinkingIndicator",
142
+ "thinkingIndicatorVariants"
143
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
144
+ Object.defineProperty(exports, '__esModule', {
145
+ value: true
146
+ });
@@ -0,0 +1,38 @@
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ import * as React from 'react';
3
+ declare const thinkingIndicatorVariants: (props?: ({
4
+ size?: "sm" | "md" | null | undefined;
5
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
+ export interface ThinkingIndicatorStrings {
7
+ /** Default visible label, and the accessible name unless `label` or `aria-label` is set. */
8
+ label: string;
9
+ }
10
+ export declare const DEFAULT_THINKING_INDICATOR_STRINGS: ThinkingIndicatorStrings;
11
+ export interface ThinkingIndicatorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>, VariantProps<typeof thinkingIndicatorVariants> {
12
+ /** A single label. Also the accessible name when `messages` rotate. */
13
+ label?: string;
14
+ /** Labels to cycle through. The first shows immediately; reduced motion keeps it there. */
15
+ messages?: string[];
16
+ /** Milliseconds each of `messages` stays on screen. */
17
+ interval?: number;
18
+ /** Overrides for any subset of the English strings. An explicit `aria-label` wins over both. */
19
+ strings?: Partial<ThinkingIndicatorStrings>;
20
+ /**
21
+ * Replaces the pulsing sparkle; `null` or `false` shows the label alone. A custom icon brings
22
+ * its own colour and animation and is sized by the indicator's `size`.
23
+ */
24
+ icon?: React.ReactNode;
25
+ }
26
+ /**
27
+ * A "the assistant is working" row for a conversation: a pulsing sparkle and a shimmering label.
28
+ * Pass `messages` to cycle through progress labels ("Searching", "Reading files") every
29
+ * `interval` ms with a crossfade.
30
+ *
31
+ * Screen readers get one stable name (`label`, else `strings.label`) on a `role="status"` root,
32
+ * and the visual label is `aria-hidden`. Rotating labels are decoration, so announcing each one
33
+ * would only add noise. Announce real progress with `LiveRegion` instead.
34
+ *
35
+ * Under `prefers-reduced-motion` the icon and shimmer are static and the labels do not rotate.
36
+ */
37
+ declare const ThinkingIndicator: React.ForwardRefExoticComponent<ThinkingIndicatorProps & React.RefAttributes<HTMLDivElement>>;
38
+ export { ThinkingIndicator, thinkingIndicatorVariants };
@@ -0,0 +1,106 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { cva } from "class-variance-authority";
4
+ import { Sparkles } from "lucide-react";
5
+ import { forwardRef, useEffect, useState } from "react";
6
+ import { cn } from "../../lib/index.js";
7
+ const REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)';
8
+ function getPrefersReducedMotion() {
9
+ if ("u" < typeof window || 'function' != typeof window.matchMedia) return false;
10
+ return window.matchMedia(REDUCED_MOTION_QUERY).matches;
11
+ }
12
+ function usePrefersReducedMotion() {
13
+ const [reduced, setReduced] = useState(getPrefersReducedMotion);
14
+ useEffect(()=>{
15
+ if ('function' != typeof window.matchMedia) return;
16
+ const mql = window.matchMedia(REDUCED_MOTION_QUERY);
17
+ const onChange = ()=>setReduced(mql.matches);
18
+ mql.addEventListener('change', onChange);
19
+ return ()=>mql.removeEventListener('change', onChange);
20
+ }, []);
21
+ return reduced;
22
+ }
23
+ const thinkingIndicatorVariants = cva('inline-flex max-w-full min-w-0 items-center text-muted-foreground', {
24
+ variants: {
25
+ size: {
26
+ sm: 'gap-1.5 text-xs [&_[data-slot=thinking-indicator-icon]]:size-3.5',
27
+ md: 'gap-2 text-sm [&_[data-slot=thinking-indicator-icon]]:size-4'
28
+ }
29
+ },
30
+ defaultVariants: {
31
+ size: 'md'
32
+ }
33
+ });
34
+ const DEFAULT_THINKING_INDICATOR_STRINGS = {
35
+ label: 'Thinking'
36
+ };
37
+ const ThinkingIndicator = /*#__PURE__*/ forwardRef(({ className, size = 'md', label, messages, interval = 2500, strings, icon, 'aria-label': ariaLabel, ...props }, ref)=>{
38
+ const text = {
39
+ ...DEFAULT_THINKING_INDICATOR_STRINGS,
40
+ ...strings
41
+ };
42
+ const staticLabel = label ?? text.label;
43
+ const name = ariaLabel ?? staticLabel;
44
+ const labels = messages && messages.length > 0 ? messages : [
45
+ staticLabel
46
+ ];
47
+ const reducedMotion = usePrefersReducedMotion();
48
+ const rotates = labels.length > 1 && !reducedMotion && interval > 0;
49
+ const rotationKey = `${rotates}\u0000${labels.join('\u0000')}`;
50
+ const [index, setIndex] = useState(0);
51
+ const [prevRotationKey, setPrevRotationKey] = useState(rotationKey);
52
+ if (rotationKey !== prevRotationKey) {
53
+ setPrevRotationKey(rotationKey);
54
+ setIndex(0);
55
+ }
56
+ useEffect(()=>{
57
+ if (!rotates) return;
58
+ const id = window.setInterval(()=>{
59
+ setIndex((current)=>(current + 1) % labels.length);
60
+ }, interval);
61
+ return ()=>window.clearInterval(id);
62
+ }, [
63
+ rotates,
64
+ labels.length,
65
+ interval,
66
+ rotationKey
67
+ ]);
68
+ const activeIndex = index < labels.length ? index : 0;
69
+ return /*#__PURE__*/ jsxs("div", {
70
+ ref: ref,
71
+ "data-slot": "thinking-indicator",
72
+ "data-size": size,
73
+ role: "status",
74
+ "aria-label": name,
75
+ className: cn(thinkingIndicatorVariants({
76
+ size
77
+ }), className),
78
+ ...props,
79
+ children: [
80
+ null !== icon && false !== icon && /*#__PURE__*/ jsx("span", {
81
+ "data-slot": "thinking-indicator-icon",
82
+ "aria-hidden": "true",
83
+ className: "inline-flex shrink-0 items-center justify-center [&>svg]:size-full",
84
+ children: icon ?? /*#__PURE__*/ jsx(Sparkles, {
85
+ className: "text-primary animate-pulse motion-reduce:animate-none"
86
+ })
87
+ }),
88
+ /*#__PURE__*/ jsx("span", {
89
+ "data-slot": "thinking-indicator-label",
90
+ "aria-hidden": "true",
91
+ className: "grid min-w-0",
92
+ children: labels.map((item, i)=>/*#__PURE__*/ jsx("span", {
93
+ "data-active": i === activeIndex,
94
+ className: "shimmer col-start-1 row-start-1 truncate transition-opacity duration-300 data-[active=false]:opacity-0 motion-reduce:transition-none",
95
+ children: item
96
+ }, i))
97
+ }),
98
+ /*#__PURE__*/ jsx("span", {
99
+ className: "sr-only",
100
+ children: name
101
+ })
102
+ ]
103
+ });
104
+ });
105
+ ThinkingIndicator.displayName = 'ThinkingIndicator';
106
+ export { DEFAULT_THINKING_INDICATOR_STRINGS, ThinkingIndicator, thinkingIndicatorVariants };