@homecode/ui 5.7.8 → 5.9.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.
- package/dist/esm/index.js +7 -0
- package/dist/esm/src/components/Autocomplete/Autocomplete.js +14 -6
- package/dist/esm/src/components/Card/Card.styl.js +1 -1
- package/dist/esm/src/components/Chat/ChatFormattedText.js +323 -0
- package/dist/esm/src/components/Chat/ChatFormattedText.styl.js +7 -0
- package/dist/esm/src/components/Chat/ChatMessage.js +50 -0
- package/dist/esm/src/components/Chat/ChatMessage.styl.js +7 -0
- package/dist/esm/src/components/Chat/ChatPrompt.js +50 -0
- package/dist/esm/src/components/Chat/ChatPrompt.styl.js +7 -0
- package/dist/esm/src/components/Chat/ChatView.js +30 -0
- package/dist/esm/src/components/Chat/ChatView.styl.js +7 -0
- package/dist/esm/src/components/Chat/content.js +96 -0
- package/dist/esm/src/components/Dialogue/Dialogue.js +4 -2
- package/dist/esm/src/components/InputFile/InputFile.js +12 -4
- package/dist/esm/src/components/NestedMenu/NestedMenu.js +118 -0
- package/dist/esm/src/components/NestedMenu/NestedMenu.styl.js +7 -0
- package/dist/esm/src/components/ThinkingOutline/ThinkingOutline.js +9 -0
- package/dist/esm/src/components/ThinkingOutline/ThinkingOutline.styl.js +7 -0
- package/dist/esm/src/tiptap/slash-mention/SlashSuggestionList.styl.js +1 -1
- package/dist/esm/types/src/components/Chat/Chat.types.d.ts +78 -0
- package/dist/esm/types/src/components/Chat/ChatFormattedText.d.ts +3 -0
- package/dist/esm/types/src/components/Chat/ChatMessage.d.ts +2 -0
- package/dist/esm/types/src/components/Chat/ChatPrompt.d.ts +2 -0
- package/dist/esm/types/src/components/Chat/ChatView.d.ts +2 -0
- package/dist/esm/types/src/components/Chat/content.d.ts +8 -0
- package/dist/esm/types/src/components/Chat/index.d.ts +6 -0
- package/dist/esm/types/src/components/Chat/types.d.ts +1 -0
- package/dist/esm/types/src/components/NestedMenu/NestedMenu.d.ts +9 -0
- package/dist/esm/types/src/components/NestedMenu/NestedMenu.types.d.ts +36 -0
- package/dist/esm/types/src/components/ThinkingOutline/ThinkingOutline.d.ts +5 -0
- package/dist/esm/types/src/components/ThinkingOutline/index.d.ts +2 -0
- package/dist/esm/types/src/components/index.d.ts +4 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -6,6 +6,11 @@ export { Calendar } from './src/components/Calendar/Calendar.js';
|
|
|
6
6
|
export { Checkbox } from './src/components/Checkbox/Checkbox.js';
|
|
7
7
|
export { Chip } from './src/components/Chip/Chip.js';
|
|
8
8
|
export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, LinkCard } from './src/components/Card/Card.js';
|
|
9
|
+
export { ChatFormattedText } from './src/components/Chat/ChatFormattedText.js';
|
|
10
|
+
export { ChatMessage } from './src/components/Chat/ChatMessage.js';
|
|
11
|
+
export { ChatPrompt } from './src/components/Chat/ChatPrompt.js';
|
|
12
|
+
export { ChatView } from './src/components/Chat/ChatView.js';
|
|
13
|
+
export { getDisplayContent, getDisplayParts, isPlanMessageContent, parseSystemEvent } from './src/components/Chat/content.js';
|
|
9
14
|
export { Container } from './src/components/Container/Container.js';
|
|
10
15
|
export { DatePicker } from './src/components/DatePicker/DatePicker.js';
|
|
11
16
|
export { DatePickerInput } from './src/components/DatePickerInput/DatePickerInput.js';
|
|
@@ -28,6 +33,7 @@ export { LangSelector } from './src/components/LangSelector/LangSelector.js';
|
|
|
28
33
|
export { Lazy } from './src/components/Lazy/Lazy.js';
|
|
29
34
|
export { LightBox } from './src/components/LightBox/LightBox.js';
|
|
30
35
|
export { Menu } from './src/components/Menu/Menu.js';
|
|
36
|
+
export { NestedMenu, NestedMenuItemRow, NestedMenuLabel } from './src/components/NestedMenu/NestedMenu.js';
|
|
31
37
|
export { Notifications, NotificationsStore } from './src/components/Notifications/Notifications.js';
|
|
32
38
|
export { Paranja } from './src/components/Paranja/Paranja.js';
|
|
33
39
|
export { ANIMATION_DURATION, Popup } from './src/components/Popup/Popup.js';
|
|
@@ -51,6 +57,7 @@ export { Spinner } from './src/components/Spinner/Spinner.js';
|
|
|
51
57
|
export { Table } from './src/components/Table/Table.js';
|
|
52
58
|
export { Tabs } from './src/components/Tabs/Tabs.js';
|
|
53
59
|
export { TextShimmer } from './src/components/TextShimmer/TextShimmer.js';
|
|
60
|
+
export { ThinkingOutline } from './src/components/ThinkingOutline/ThinkingOutline.js';
|
|
54
61
|
export { TextWithDeferTooltip } from './src/components/TextWithDeferTooltip/TextWithDeferTooltip.js';
|
|
55
62
|
export { Tooltip } from './src/components/Tooltip/Tooltip.js';
|
|
56
63
|
export { H1, H2, H3, H4, H5, H6 } from './src/components/Text/Text.js';
|
|
@@ -27,6 +27,19 @@ import '../Checkbox/Checkbox.styl.js';
|
|
|
27
27
|
import '../Chip/Chip.styl.js';
|
|
28
28
|
import '../Tooltip/Tooltip.js';
|
|
29
29
|
import '../Card/Card.js';
|
|
30
|
+
import '../Router/context.js';
|
|
31
|
+
import '../Router/Link/Link.styl.js';
|
|
32
|
+
import '../Portal/Portal.js';
|
|
33
|
+
import '../Paranja/Paranja.styl.js';
|
|
34
|
+
import '../Table/Table.styl.js';
|
|
35
|
+
import '../Chat/ChatFormattedText.styl.js';
|
|
36
|
+
import '../Expand/Expand.styl.js';
|
|
37
|
+
import '../Chat/ChatMessage.styl.js';
|
|
38
|
+
import '../PromptComposer/PromptComposer.js';
|
|
39
|
+
import '../ThinkingOutline/ThinkingOutline.styl.js';
|
|
40
|
+
import '../Chat/ChatPrompt.styl.js';
|
|
41
|
+
import '../TextShimmer/TextShimmer.js';
|
|
42
|
+
import '../Chat/ChatView.styl.js';
|
|
30
43
|
import '../Container/Container.js';
|
|
31
44
|
import '../DatePicker/DatePicker.styl.js';
|
|
32
45
|
import 'moment';
|
|
@@ -35,7 +48,6 @@ import '../Dialogue/Dialogue.js';
|
|
|
35
48
|
import '../../tools/queryParams.js';
|
|
36
49
|
import '../Draggable/Draggable.styl.js';
|
|
37
50
|
import '../DropZone/DropZone.styl.js';
|
|
38
|
-
import '../Expand/Expand.styl.js';
|
|
39
51
|
import '../Flex/Flex.styl.js';
|
|
40
52
|
import '../Form/Form.styl.js';
|
|
41
53
|
import '../Form/Validator.js';
|
|
@@ -56,14 +68,12 @@ import '@tiptap/react';
|
|
|
56
68
|
import { Menu } from '../Menu/Menu.js';
|
|
57
69
|
import '../../tiptap/slash-mention/SlashSuggestionList.styl.js';
|
|
58
70
|
import '../../services/i18n.js';
|
|
59
|
-
import '../Portal/Portal.js';
|
|
60
|
-
import '../Paranja/Paranja.styl.js';
|
|
61
71
|
import '../LightBox/LightBox.styl.js';
|
|
72
|
+
import '../NestedMenu/NestedMenu.js';
|
|
62
73
|
import '../Notifications/store.js';
|
|
63
74
|
import '../Notifications/Notifications.styl.js';
|
|
64
75
|
import '../PopupMenu/PopupMenu.styl.js';
|
|
65
76
|
import '../Progress/Progress.styl.js';
|
|
66
|
-
import '../PromptComposer/PromptComposer.js';
|
|
67
77
|
import '@tiptap/extensions';
|
|
68
78
|
import '@tiptap/starter-kit';
|
|
69
79
|
import '../PromptComposer/PromptComposer.styl.js';
|
|
@@ -71,9 +81,7 @@ import '../RadioGroup/RadioGroupContext.js';
|
|
|
71
81
|
import '../RadioButton/RadioButton.styl.js';
|
|
72
82
|
import '../RadioGroup/RadioGroup.styl.js';
|
|
73
83
|
import '../Router/Router.js';
|
|
74
|
-
import '../Table/Table.styl.js';
|
|
75
84
|
import '../Tabs/Tabs.styl.js';
|
|
76
|
-
import '../TextShimmer/TextShimmer.js';
|
|
77
85
|
import '../TextWithDeferTooltip/TextWithDeferTooltip.styl.js';
|
|
78
86
|
import '../Text/Text.js';
|
|
79
87
|
import '../Theme/Theme.defaults.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".Card_root__khJ4u{background-color:var(--surface-color);border-radius:var(--border-radius-l);display:flex;flex-direction:column;gap:var(--p-5);max-height:100%;position:relative}.Card_root__khJ4u.Card_blur__VbZXN{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background-color:var(--decent-color-alpha-500)}.Card_root__khJ4u.Card_padding-xs__dd13Q{border-radius:var(--p-3);padding:var(--p-2)}.Card_root__khJ4u.Card_padding-s__S7iiZ{border-radius:var(--p-4);padding:var(--p-3)}.Card_root__khJ4u.Card_padding-m__thC3O{border-radius:var(--p-6);padding:var(--p-5)}.Card_root__khJ4u.Card_padding-l__gtTEF{border-radius:var(--p-8);padding:var(--p-8)}.Card_root__khJ4u.Card_padding-xl__y01o1{border-radius:var(--p-11);padding:var(--p-10)}.Card_header__LDTGV{align-items:flex-start;display:flex;gap:var(--p-5);justify-content:space-between}.Card_header__LDTGV:has([data-slot=card-action]){grid-template-columns:1fr auto}.Card_icon__aRlE5{align-items:center;border-radius:var(--p-2);box-shadow:inset 0 0 0 1px var(--decent-color-alpha-200);display:flex;flex-shrink:0;height:48px;justify-content:center;width:48px}.Card_icon__aRlE5.Card_withBackground__lIrjx{background-color:var(--accent-color-alpha-100);box-shadow:none}.Card_icon__aRlE5>img,.Card_icon__aRlE5>svg{height:20px;width:20px}.Card_headerText__hawuL{flex-grow:1;overflow:hidden}.Card_scroll__uDcXL{max-height:100%;overflow:hidden;padding-right:var(--p-5);width:calc(100% + var(--p-5))}.Card_scroll__uDcXL [data-slot=card-content]{padding-right:1px}.Card_centered__0YX4F,.Card_fullHeight__i3n8e{display:flex;flex-direction:column}.Card_centered__0YX4F{align-items:center;justify-content:center}.Card_fullHeight__i3n8e{flex-grow:1}.Card_description__RTQTR,.Card_title__Z1SQz{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.Card_title__Z1SQz{font-size:120%;font-weight:500;line-height:1.2}.Card_description__RTQTR{color:var(--accent-color-alpha-500);max-width:100%;word-break:break-word}.Card_action__viIuL{grid-row-span:2;align-self:start;grid-column-start:2;grid-row-start:1;justify-self:end}.Card_footer__T0DXA{align-items:center;display:flex;flex-shrink:0;justify-content:space-between;overflow:
|
|
3
|
+
var css_248z = ".Card_root__khJ4u{background-color:var(--surface-color);border-radius:var(--border-radius-l);display:flex;flex-direction:column;gap:var(--p-5);max-height:100%;position:relative}.Card_root__khJ4u.Card_blur__VbZXN{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background-color:var(--decent-color-alpha-500)}.Card_root__khJ4u.Card_padding-xs__dd13Q{border-radius:var(--p-3);padding:var(--p-2)}.Card_root__khJ4u.Card_padding-s__S7iiZ{border-radius:var(--p-4);padding:var(--p-3)}.Card_root__khJ4u.Card_padding-m__thC3O{border-radius:var(--p-6);padding:var(--p-5)}.Card_root__khJ4u.Card_padding-l__gtTEF{border-radius:var(--p-8);padding:var(--p-8)}.Card_root__khJ4u.Card_padding-xl__y01o1{border-radius:var(--p-11);padding:var(--p-10)}.Card_header__LDTGV{align-items:flex-start;display:flex;gap:var(--p-5);justify-content:space-between}.Card_header__LDTGV:has([data-slot=card-action]){grid-template-columns:1fr auto}.Card_icon__aRlE5{align-items:center;border-radius:var(--p-2);box-shadow:inset 0 0 0 1px var(--decent-color-alpha-200);display:flex;flex-shrink:0;height:48px;justify-content:center;width:48px}.Card_icon__aRlE5.Card_withBackground__lIrjx{background-color:var(--accent-color-alpha-100);box-shadow:none}.Card_icon__aRlE5>img,.Card_icon__aRlE5>svg{height:20px;width:20px}.Card_headerText__hawuL{flex-grow:1;overflow:hidden}.Card_scroll__uDcXL{max-height:100%;overflow:hidden;padding-right:var(--p-5);width:calc(100% + var(--p-5))}.Card_scroll__uDcXL [data-slot=card-content]{padding-right:1px}.Card_centered__0YX4F,.Card_fullHeight__i3n8e{display:flex;flex-direction:column}.Card_centered__0YX4F{align-items:center;justify-content:center}.Card_fullHeight__i3n8e{flex-grow:1}.Card_description__RTQTR,.Card_title__Z1SQz{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.Card_title__Z1SQz{font-size:120%;font-weight:500;line-height:1.2}.Card_description__RTQTR{color:var(--accent-color-alpha-500);max-width:100%;word-break:break-word}.Card_action__viIuL{grid-row-span:2;align-self:start;grid-column-start:2;grid-row-start:1;justify-self:end}.Card_footer__T0DXA{align-items:center;display:flex;flex-shrink:0;justify-content:space-between;overflow:visible}";
|
|
4
4
|
var S = {"root":"Card_root__khJ4u","blur":"Card_blur__VbZXN","padding-xs":"Card_padding-xs__dd13Q","padding-s":"Card_padding-s__S7iiZ","padding-m":"Card_padding-m__thC3O","padding-l":"Card_padding-l__gtTEF","padding-xl":"Card_padding-xl__y01o1","header":"Card_header__LDTGV","icon":"Card_icon__aRlE5","withBackground":"Card_withBackground__lIrjx","headerText":"Card_headerText__hawuL","scroll":"Card_scroll__uDcXL","centered":"Card_centered__0YX4F","fullHeight":"Card_fullHeight__i3n8e","title":"Card_title__Z1SQz","description":"Card_description__RTQTR","action":"Card_action__viIuL","footer":"Card_footer__T0DXA"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import { Button } from '../Button/Button.js';
|
|
4
|
+
import { Link } from '../Router/Link/Link.js';
|
|
5
|
+
import { Table } from '../Table/Table.js';
|
|
6
|
+
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
7
|
+
import S from './ChatFormattedText.styl.js';
|
|
8
|
+
|
|
9
|
+
function findJsonEndExclusive(content, start) {
|
|
10
|
+
const first = content[start];
|
|
11
|
+
if (first !== '{' && first !== '[')
|
|
12
|
+
return -1;
|
|
13
|
+
const stack = first === '{' ? ['}'] : [']'];
|
|
14
|
+
let i = start + 1;
|
|
15
|
+
let inString = false;
|
|
16
|
+
let escape = false;
|
|
17
|
+
while (i < content.length && stack.length > 0) {
|
|
18
|
+
const c = content[i];
|
|
19
|
+
if (inString) {
|
|
20
|
+
if (escape)
|
|
21
|
+
escape = false;
|
|
22
|
+
else if (c === '\\')
|
|
23
|
+
escape = true;
|
|
24
|
+
else if (c === '"')
|
|
25
|
+
inString = false;
|
|
26
|
+
i++;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (c === '"') {
|
|
30
|
+
inString = true;
|
|
31
|
+
i++;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (c === '{') {
|
|
35
|
+
stack.push('}');
|
|
36
|
+
i++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (c === '[') {
|
|
40
|
+
stack.push(']');
|
|
41
|
+
i++;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (c === '}' || c === ']') {
|
|
45
|
+
if (c !== stack[stack.length - 1])
|
|
46
|
+
return -1;
|
|
47
|
+
stack.pop();
|
|
48
|
+
i++;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
i++;
|
|
52
|
+
}
|
|
53
|
+
return stack.length > 0 ? -1 : i;
|
|
54
|
+
}
|
|
55
|
+
function applyInjectors(text, injectors) {
|
|
56
|
+
let result = [text];
|
|
57
|
+
injectors.forEach(fn => {
|
|
58
|
+
let i = 0;
|
|
59
|
+
while (i < result.length) {
|
|
60
|
+
const item = result[i];
|
|
61
|
+
if (typeof item === 'string') {
|
|
62
|
+
const res = fn(item);
|
|
63
|
+
if (!res) {
|
|
64
|
+
i++;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const { elem, index, length } = res;
|
|
68
|
+
if (index >= 0) {
|
|
69
|
+
const before = item.substring(0, index);
|
|
70
|
+
const after = item.substring(index + length);
|
|
71
|
+
result.splice(i, 1, before, elem, after);
|
|
72
|
+
if (after.length > 0)
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
i++;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
function ChatFormattedText({ text, className, onButtonClick, }) {
|
|
82
|
+
const injectLines = (content) => {
|
|
83
|
+
const matches = content.match(/\n---\n/);
|
|
84
|
+
if (!matches)
|
|
85
|
+
return null;
|
|
86
|
+
return {
|
|
87
|
+
elem: jsx("div", { className: S.line }),
|
|
88
|
+
index: matches.index,
|
|
89
|
+
length: matches[0].length,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
const injectBullet = (content) => {
|
|
93
|
+
const matches = content.match(/(\n|^)([ \t]*)(-|\*|\+)\s/);
|
|
94
|
+
if (!matches)
|
|
95
|
+
return null;
|
|
96
|
+
return {
|
|
97
|
+
elem: (jsxs(Fragment, { children: [matches[1] === '\n' && jsx("br", {}), jsx("div", { className: S.bullet })] })),
|
|
98
|
+
index: matches.index,
|
|
99
|
+
length: matches[0].length,
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
const injectNumbered = (content) => {
|
|
103
|
+
const matches = content.match(/(\n|^)([ \t]*)(\d+)\.\s+/);
|
|
104
|
+
if (!matches)
|
|
105
|
+
return null;
|
|
106
|
+
return {
|
|
107
|
+
elem: (jsxs(Fragment, { children: [matches[1] === '\n' && jsx("br", {}), jsxs("span", { className: S.numberedIndex, children: [matches[3], "."] })] })),
|
|
108
|
+
index: matches.index,
|
|
109
|
+
length: matches[0].length,
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
const injectBold = (content) => {
|
|
113
|
+
const matches = content.match(/\*\*(.*?)\*\*/);
|
|
114
|
+
if (!matches)
|
|
115
|
+
return null;
|
|
116
|
+
return {
|
|
117
|
+
elem: jsx("strong", { children: matches[1] }),
|
|
118
|
+
index: matches.index,
|
|
119
|
+
length: matches[0].length,
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
const injectItalic = (content) => {
|
|
123
|
+
const matches = content.match(/\*(.*?)\*/);
|
|
124
|
+
if (!matches)
|
|
125
|
+
return null;
|
|
126
|
+
return {
|
|
127
|
+
elem: jsx("em", { children: matches[1] }),
|
|
128
|
+
index: matches.index,
|
|
129
|
+
length: matches[0].length,
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
const injectCodeBlock = (content) => {
|
|
133
|
+
const multiline = content.match(/```(\w+)?[\s\n]*([\s\S]*?)```/);
|
|
134
|
+
if (multiline) {
|
|
135
|
+
return {
|
|
136
|
+
elem: jsx("code", { className: S.codeBlock, children: multiline[2].trim() }),
|
|
137
|
+
index: multiline.index,
|
|
138
|
+
length: multiline[0].length,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const inline = content.match(/`([^`\n]+)`/);
|
|
142
|
+
if (!inline)
|
|
143
|
+
return null;
|
|
144
|
+
return {
|
|
145
|
+
elem: jsx("code", { className: S.codeInline, children: inline[1] }),
|
|
146
|
+
index: inline.index,
|
|
147
|
+
length: inline[0].length,
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
const injectPrettyJson = (content) => {
|
|
151
|
+
let searchFrom = 0;
|
|
152
|
+
while (searchFrom < content.length) {
|
|
153
|
+
let start = -1;
|
|
154
|
+
for (let j = searchFrom; j < content.length; j++) {
|
|
155
|
+
if (content[j] === '{' || content[j] === '[') {
|
|
156
|
+
start = j;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (start < 0)
|
|
161
|
+
return null;
|
|
162
|
+
const endExclusive = findJsonEndExclusive(content, start);
|
|
163
|
+
if (endExclusive < 0) {
|
|
164
|
+
searchFrom = start + 1;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const slice = content.slice(start, endExclusive);
|
|
168
|
+
try {
|
|
169
|
+
const parsed = JSON.parse(slice);
|
|
170
|
+
return {
|
|
171
|
+
elem: (jsx("pre", { className: S.jsonPre, children: JSON.stringify(parsed, null, 2) })),
|
|
172
|
+
index: start,
|
|
173
|
+
length: slice.length,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
searchFrom = start + 1;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
};
|
|
182
|
+
const injectLinks = (content) => {
|
|
183
|
+
const markdown = content.match(/\[([^\]]+)\]\(([^)]+)\)/);
|
|
184
|
+
if (markdown) {
|
|
185
|
+
let url = markdown[2];
|
|
186
|
+
if (url.startsWith('www.'))
|
|
187
|
+
url = `https://${url}`;
|
|
188
|
+
return {
|
|
189
|
+
elem: (jsx(Tooltip, { content: url, direction: "top", children: jsx(Link, { href: url, inline: true, target: "_blank", children: markdown[1] }) })),
|
|
190
|
+
index: markdown.index,
|
|
191
|
+
length: markdown[0].length,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const bareDomainTlds = 'com|org|net|edu|gov|mil|int|info|biz|co|io|ai|app|dev|me|tv|cc|ly|sh|so|gg|fm|ws|xyz|tech|cloud|store|online|site|shop|blog|news|link|page|uk|us|ca|de|fr|jp|cn|ru|br|in|au|it|es|nl|se|no|fi|pl|ch|be|at|dk|cz|gr|hu|ie|pt|ro|tr|kr|mx|za|sg|hk|tw|nz|il|ae|ua';
|
|
195
|
+
const matches = content.match(new RegExp(`(https?:\\/\\/[^\\s<>"']+|www\\.[^\\s<>"']+|[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\\.(?:${bareDomainTlds})\\b[^\\s<>"']*)`, 'i'));
|
|
196
|
+
if (!matches)
|
|
197
|
+
return null;
|
|
198
|
+
let url = matches[0];
|
|
199
|
+
if (url.startsWith('www.'))
|
|
200
|
+
url = `https://${url}`;
|
|
201
|
+
return {
|
|
202
|
+
elem: (jsx(Tooltip, { content: url, direction: "top", children: jsx(Link, { href: url, inline: true, target: "_blank", children: matches[0] }) })),
|
|
203
|
+
index: matches.index,
|
|
204
|
+
length: matches[0].length,
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
const injectButtons = (content) => {
|
|
208
|
+
if (!onButtonClick)
|
|
209
|
+
return null;
|
|
210
|
+
const matches = content.match(/\[(.*?):(.*?)\|([^\]]+)\]/);
|
|
211
|
+
if (!matches)
|
|
212
|
+
return null;
|
|
213
|
+
const [data, label] = matches[0]
|
|
214
|
+
.replace('[', '')
|
|
215
|
+
.replace(']', '')
|
|
216
|
+
.split('|');
|
|
217
|
+
const [varName, value] = data.split(':');
|
|
218
|
+
return {
|
|
219
|
+
elem: (jsx(Button, { variant: "default", size: "s", round: true, onClick: () => onButtonClick({ text: label, [varName]: value }), children: label })),
|
|
220
|
+
index: matches.index,
|
|
221
|
+
length: matches[0].length,
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
const headingTags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
225
|
+
const processCellContent = (value, depth = 0) => applyInjectors(value, [
|
|
226
|
+
injectCodeBlock,
|
|
227
|
+
injectPrettyJson,
|
|
228
|
+
...(depth === 0
|
|
229
|
+
? [
|
|
230
|
+
(content) => {
|
|
231
|
+
const matches = content.match(/(^|\n)(#{1,6})\s+([^\n]+)/);
|
|
232
|
+
if (!matches)
|
|
233
|
+
return null;
|
|
234
|
+
const Tag = headingTags[Math.min(matches[2].length, 6) - 1];
|
|
235
|
+
return {
|
|
236
|
+
elem: React__default.createElement(Tag, {}, ...processCellContent(matches[3], depth + 1)),
|
|
237
|
+
index: matches.index,
|
|
238
|
+
length: matches[0].length,
|
|
239
|
+
};
|
|
240
|
+
},
|
|
241
|
+
]
|
|
242
|
+
: []),
|
|
243
|
+
injectLines,
|
|
244
|
+
injectLinks,
|
|
245
|
+
injectBold,
|
|
246
|
+
injectItalic,
|
|
247
|
+
injectBullet,
|
|
248
|
+
injectNumbered,
|
|
249
|
+
injectButtons,
|
|
250
|
+
]);
|
|
251
|
+
const injectHeading = (content) => {
|
|
252
|
+
const matches = content.match(/(^|\n)(#{1,6})\s+([^\n]+)/);
|
|
253
|
+
if (!matches)
|
|
254
|
+
return null;
|
|
255
|
+
const Tag = headingTags[Math.min(matches[2].length, 6) - 1];
|
|
256
|
+
return {
|
|
257
|
+
elem: React__default.createElement(Tag, {}, ...processCellContent(matches[3], 1)),
|
|
258
|
+
index: matches.index,
|
|
259
|
+
length: matches[0].length,
|
|
260
|
+
};
|
|
261
|
+
};
|
|
262
|
+
const injectTables = (content) => {
|
|
263
|
+
const withSep = content.match(/(\n|^)(\|[^\n]+\|\s*\n)(\|[\s:-]+(?:\|[\s:-]+)*\|\s*\n)((?:\|[^\n]+\|\s*\n?)+)/);
|
|
264
|
+
const withoutSep = withSep
|
|
265
|
+
? null
|
|
266
|
+
: content.match(/(\n|^)(\|[^\n]+\|\s*\n)((?:\|[^\n]+\|\s*\n?)+)/);
|
|
267
|
+
const matches = withSep || withoutSep;
|
|
268
|
+
if (!matches)
|
|
269
|
+
return null;
|
|
270
|
+
const hasSeparator = Boolean(withSep);
|
|
271
|
+
const headerRow = matches[2].trim();
|
|
272
|
+
const dataRows = (hasSeparator ? matches[4] : matches[3]).trim();
|
|
273
|
+
const headers = headerRow.split('|').map(cell => cell.trim()).slice(1, -1);
|
|
274
|
+
if (headers.length === 0)
|
|
275
|
+
return null;
|
|
276
|
+
const rows = dataRows
|
|
277
|
+
.split('\n')
|
|
278
|
+
.map(row => row.trim())
|
|
279
|
+
.filter(row => row.startsWith('|') && row.endsWith('|'))
|
|
280
|
+
.map(row => row.split('|').map(cell => cell.trim()).slice(1, -1))
|
|
281
|
+
.filter(row => row.length > 0);
|
|
282
|
+
if (rows.length === 0)
|
|
283
|
+
return null;
|
|
284
|
+
const maxCols = Math.max(headers.length, ...rows.map(row => row.length));
|
|
285
|
+
const paddedHeaders = [
|
|
286
|
+
...headers,
|
|
287
|
+
...Array(maxCols - headers.length).fill(''),
|
|
288
|
+
];
|
|
289
|
+
const columns = paddedHeaders.map((header, idx) => ({
|
|
290
|
+
id: `col-${idx}`,
|
|
291
|
+
label: processCellContent(header),
|
|
292
|
+
dataField: `col-${idx}`,
|
|
293
|
+
render: (data) => processCellContent(data[`col-${idx}`] || ''),
|
|
294
|
+
}));
|
|
295
|
+
const tableData = rows.map((row, rowIdx) => {
|
|
296
|
+
const rowData = { id: `row-${rowIdx}` };
|
|
297
|
+
paddedHeaders.forEach((_, colIdx) => {
|
|
298
|
+
rowData[`col-${colIdx}`] = row[colIdx] || '';
|
|
299
|
+
});
|
|
300
|
+
return rowData;
|
|
301
|
+
});
|
|
302
|
+
return {
|
|
303
|
+
elem: (jsx(Table, { size: "s", variant: "plain", columns: columns, data: tableData, className: S.table })),
|
|
304
|
+
index: matches.index + (matches[1]?.length || 0),
|
|
305
|
+
length: matches[0].length - (matches[1]?.length || 0),
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
return (jsx("div", { className: className, children: applyInjectors(text, [
|
|
309
|
+
injectTables,
|
|
310
|
+
injectCodeBlock,
|
|
311
|
+
injectPrettyJson,
|
|
312
|
+
injectHeading,
|
|
313
|
+
injectLines,
|
|
314
|
+
injectLinks,
|
|
315
|
+
injectBold,
|
|
316
|
+
injectItalic,
|
|
317
|
+
injectBullet,
|
|
318
|
+
injectNumbered,
|
|
319
|
+
injectButtons,
|
|
320
|
+
]) }));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export { ChatFormattedText };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".ChatFormattedText_bullet__CdKe7{display:inline-block;margin-bottom:2px;margin-left:var(--p-2);margin-right:2px}.ChatFormattedText_bullet__CdKe7:before{background-color:var(--accent-color);border-radius:50%;content:\"\";display:block;height:6px;margin:0 4px;width:6px}.ChatFormattedText_numberedIndex__bejS0{font-feature-settings:\"tnum\";color:var(--accent-color);display:inline-block;font-variant-numeric:tabular-nums;margin-left:var(--p-2);margin-right:6px;min-width:1.25em}.ChatFormattedText_line__1j8Sx{background-color:var(--accent-color-alpha-200);border-radius:2px;height:2px;margin:var(--p-2) 0;width:100%}.ChatFormattedText_codeBlock__Mm7Um,.ChatFormattedText_codeInline__gqRjp{background-color:var(--decent-color-alpha-400);border-radius:var(--p-2);box-shadow:0 1px 1px var(--accent-color-alpha-50),inset 0 1px 1px var(--decent-color-alpha-500);font-family:monospace;-webkit-user-select:text;-moz-user-select:text;user-select:text}.ChatFormattedText_codeInline__gqRjp{border-radius:3px;display:inline;font-size:90%;padding:0 4px}.ChatFormattedText_codeBlock__Mm7Um,.ChatFormattedText_jsonPre__m4NwI{display:block;font-size:90%;margin:var(--p-2) 0;overflow-x:auto;padding:var(--p-2);white-space:pre-wrap}.ChatFormattedText_jsonPre__m4NwI{background-color:var(--decent-color-alpha-300);border-radius:var(--p-2);box-shadow:0 1px 1px var(--accent-color-alpha-50),inset 0 1px 1px var(--accent-color-alpha-50);font-family:monospace;max-width:100%;-webkit-user-select:text;-moz-user-select:text;user-select:text}.ChatFormattedText_table__1rTGx{margin-bottom:10px}";
|
|
4
|
+
var S = {"bullet":"ChatFormattedText_bullet__CdKe7","numberedIndex":"ChatFormattedText_numberedIndex__bejS0","line":"ChatFormattedText_line__1j8Sx","codeInline":"ChatFormattedText_codeInline__gqRjp","codeBlock":"ChatFormattedText_codeBlock__Mm7Um","jsonPre":"ChatFormattedText_jsonPre__m4NwI","table":"ChatFormattedText_table__1rTGx"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { Expand } from '../Expand/Expand.js';
|
|
5
|
+
import { Link } from '../Router/Link/Link.js';
|
|
6
|
+
import { ChatFormattedText } from './ChatFormattedText.js';
|
|
7
|
+
import S from './ChatMessage.styl.js';
|
|
8
|
+
import { parseSystemEvent, getDisplayParts, getDisplayContent } from './content.js';
|
|
9
|
+
|
|
10
|
+
function ChatMessage({ data, isStacked, className, onButtonClick, }) {
|
|
11
|
+
const { content, role, createdAt } = data;
|
|
12
|
+
const id = data.id;
|
|
13
|
+
const isSystem = role === 'SYSTEM';
|
|
14
|
+
const date = createdAt ? new Date(createdAt) : null;
|
|
15
|
+
const systemEvent = useMemo(() => (isSystem ? parseSystemEvent(content) : null), [isSystem, content]);
|
|
16
|
+
const parts = useMemo(() => (isSystem ? null : getDisplayParts(content)), [content, isSystem]);
|
|
17
|
+
const body = useMemo(() => {
|
|
18
|
+
if (parts) {
|
|
19
|
+
return (jsx("div", { className: S.parts, children: parts.map((part, i) => {
|
|
20
|
+
if (part.type === 'text' && typeof part.text === 'string') {
|
|
21
|
+
return (jsx(ChatFormattedText, { text: part.text, onButtonClick: onButtonClick }, i));
|
|
22
|
+
}
|
|
23
|
+
if (part.type === 'image_url' && part.image_url?.url) {
|
|
24
|
+
return (jsx("img", { src: part.image_url.url, alt: "", className: S.mediaPart }, i));
|
|
25
|
+
}
|
|
26
|
+
if (part.type === 'video_url' && part.video_url?.url) {
|
|
27
|
+
return (jsx("video", { src: part.video_url.url, controls: true, className: S.mediaPart }, i));
|
|
28
|
+
}
|
|
29
|
+
if (part.type === 'file' && part.file?.url) {
|
|
30
|
+
return (jsx("div", { className: S.mediaPart, children: jsx(Link, { href: part.file.url, target: "_blank", rel: "noopener noreferrer", children: part.file.filename || 'Download' }) }, i));
|
|
31
|
+
}
|
|
32
|
+
if (part.type === 'input_audio' && part.input_audio?.data) {
|
|
33
|
+
const format = part.input_audio.format || 'mp3';
|
|
34
|
+
return (jsx("audio", { src: `data:audio/${format};base64,${part.input_audio.data}`, controls: true, className: S.mediaPart }, i));
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}) }));
|
|
38
|
+
}
|
|
39
|
+
const text = isSystem
|
|
40
|
+
? systemEvent?.body ?? content
|
|
41
|
+
: getDisplayContent(content);
|
|
42
|
+
return jsx(ChatFormattedText, { text: text, onButtonClick: onButtonClick });
|
|
43
|
+
}, [content, isSystem, onButtonClick, parts, systemEvent]);
|
|
44
|
+
return (jsxs("div", { className: cn(S.root, S[role], isStacked && S.stacked, className), "data-id": id, children: [date && !Number.isNaN(date.getTime()) && (jsx("div", { className: S.meta, children: date.toLocaleTimeString(undefined, {
|
|
45
|
+
hour: 'numeric',
|
|
46
|
+
minute: '2-digit',
|
|
47
|
+
}) })), jsx("div", { className: S.text, children: jsx("div", { className: S.textContent, children: isSystem ? (jsx(Expand, { className: S.systemFold, headerClassName: S.systemFoldTrigger, size: "s", isOpen: false, header: systemEvent?.summary || getDisplayContent(content), content: () => (jsx("div", { className: S.systemFoldContent, children: body })) })) : (body) }) })] }));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { ChatMessage };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".ChatMessage_root__JkQi6{align-items:flex-start;display:flex;flex-direction:column;max-width:100%;padding:0 var(--p-5) var(--p-2)}@media (max-width:768px){.ChatMessage_root__JkQi6{padding:0 var(--p-2) var(--p-2)}}.ChatMessage_root__JkQi6+.ChatMessage_root__JkQi6{margin-top:20px}.ChatMessage_root__JkQi6 .ChatMessage_textContent__O-pxi{padding:0}.ChatMessage_root__JkQi6.ChatMessage_USER__UEEuA{align-items:flex-end;padding-right:var(--p-5)}.ChatMessage_root__JkQi6.ChatMessage_USER__UEEuA .ChatMessage_text__CNGXE{background-color:var(--active-color-alpha-500);padding:6px var(--p-2)}.ChatMessage_root__JkQi6.ChatMessage_AGENT__fvHxv .ChatMessage_textContent__O-pxi,.ChatMessage_root__JkQi6.ChatMessage_AGENT__fvHxv .ChatMessage_text__CNGXE{width:100%!important}.ChatMessage_root__JkQi6.ChatMessage_AGENT__fvHxv .ChatMessage_text__CNGXE{padding-top:4px}.ChatMessage_root__JkQi6.ChatMessage_SYSTEM__bkOnf{align-items:stretch}.ChatMessage_root__JkQi6.ChatMessage_SYSTEM__bkOnf+.ChatMessage_root__JkQi6.ChatMessage_SYSTEM__bkOnf{margin-top:-6px!important}.ChatMessage_root__JkQi6.ChatMessage_SYSTEM__bkOnf .ChatMessage_text__CNGXE{font-size:90%;opacity:.8;padding:0;width:100%}.ChatMessage_root__JkQi6.ChatMessage_stacked__LoLL0 .ChatMessage_meta__lMww1{display:none}.ChatMessage_text__CNGXE{border-radius:14px;display:flex;flex-direction:row;max-width:100%;overflow:hidden;padding:var(--p-2);width:-moz-fit-content;width:fit-content}.ChatMessage_textContent__O-pxi{max-width:100%;text-align:left;white-space:pre-line;word-break:break-word}.ChatMessage_textContent__O-pxi h1,.ChatMessage_textContent__O-pxi h2,.ChatMessage_textContent__O-pxi h3,.ChatMessage_textContent__O-pxi h4,.ChatMessage_textContent__O-pxi h5,.ChatMessage_textContent__O-pxi h6{margin-top:1em}.ChatMessage_textContent__O-pxi a{margin-bottom:-.1em;margin-top:-.3em;padding:0 .3em .1em .4em!important}.ChatMessage_SYSTEM__bkOnf .ChatMessage_textContent__O-pxi a{margin-bottom:0;margin-top:0}.ChatMessage_meta__lMww1{font-size:11px;margin-bottom:4px;opacity:.5;padding:0 4px}.ChatMessage_parts__z7LHI{display:flex;flex-direction:column;gap:var(--p-2)}.ChatMessage_mediaPart__A67rQ{border-radius:var(--p-2);max-height:320px;max-width:100%}.ChatMessage_systemFold__FUSrL{width:100%}.ChatMessage_systemFoldTrigger__35Hnd{max-width:100%;overflow:hidden;padding:2px 10px;text-overflow:ellipsis;white-space:nowrap}.ChatMessage_systemFoldContent__0G-uw{padding:0 10px}";
|
|
4
|
+
var S = {"root":"ChatMessage_root__JkQi6","textContent":"ChatMessage_textContent__O-pxi","USER":"ChatMessage_USER__UEEuA","text":"ChatMessage_text__CNGXE","AGENT":"ChatMessage_AGENT__fvHxv","SYSTEM":"ChatMessage_SYSTEM__bkOnf","stacked":"ChatMessage_stacked__LoLL0","meta":"ChatMessage_meta__lMww1","parts":"ChatMessage_parts__z7LHI","mediaPart":"ChatMessage_mediaPart__A67rQ","systemFold":"ChatMessage_systemFold__FUSrL","systemFoldTrigger":"ChatMessage_systemFoldTrigger__35Hnd","systemFoldContent":"ChatMessage_systemFoldContent__0G-uw"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { useRef, useState } from 'react';
|
|
4
|
+
import { Button } from '../Button/Button.js';
|
|
5
|
+
import { Icon } from '../Icon/Icon.js';
|
|
6
|
+
import { PromptComposer } from '../PromptComposer/PromptComposer.js';
|
|
7
|
+
import { Select2 } from '../Select/Select2.js';
|
|
8
|
+
import { ThinkingOutline } from '../ThinkingOutline/ThinkingOutline.js';
|
|
9
|
+
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
10
|
+
import S from './ChatPrompt.styl.js';
|
|
11
|
+
|
|
12
|
+
const DEFAULT_MODELS = [
|
|
13
|
+
{ id: 'auto', label: 'Auto Router' },
|
|
14
|
+
];
|
|
15
|
+
function ChatPrompt({ value, onChange, onSubmit, disabled, isPrompting, placeholder = 'Message', className, showAttach = true, onAttach, attachAccept, showModelSelector = true, models = DEFAULT_MODELS, model, onModelChange, }) {
|
|
16
|
+
const fileInputRef = useRef(null);
|
|
17
|
+
const [uncontrolledModel, setUncontrolledModel] = useState(model ?? models[0]?.id ?? 'auto');
|
|
18
|
+
const modelId = model ?? uncontrolledModel;
|
|
19
|
+
const canSubmit = !disabled && Boolean(value.trim());
|
|
20
|
+
const setModel = (id) => {
|
|
21
|
+
if (model === undefined)
|
|
22
|
+
setUncontrolledModel(id);
|
|
23
|
+
onModelChange?.(id);
|
|
24
|
+
};
|
|
25
|
+
return (jsxs("div", { className: cn(S.root, className), children: [jsx(ThinkingOutline, { active: isPrompting }), jsx(PromptComposer, { className: S.composer, disabled: disabled, placeholder: placeholder, prefillMessage: value, allowEnterSubmit: true, onChange: onChange, onSubmit: text => {
|
|
26
|
+
const next = text.trim();
|
|
27
|
+
if (!next || disabled)
|
|
28
|
+
return;
|
|
29
|
+
onSubmit(next);
|
|
30
|
+
} }), jsxs("div", { className: S.buttons, children: [jsx(Button, { className: cn(S.button, S.submit), variant: "text", type: "submit", round: true, square: true, disabled: !canSubmit, "aria-label": "Send", onClick: () => {
|
|
31
|
+
const next = value.trim();
|
|
32
|
+
if (!next || disabled)
|
|
33
|
+
return;
|
|
34
|
+
onSubmit(next);
|
|
35
|
+
}, children: jsx(Icon, { type: "arrowUp", className: S.submitIcon }) }), showModelSelector && (jsx(Select2, { className: S.promptModelSelector, label: "", size: "s", disableLabel: true, hideRequiredStar: true, round: true, options: models, value: modelId, disabled: disabled, popupProps: {
|
|
36
|
+
direction: 'top-right',
|
|
37
|
+
round: true,
|
|
38
|
+
}, onChange: next => {
|
|
39
|
+
if (next == null || Array.isArray(next))
|
|
40
|
+
return;
|
|
41
|
+
setModel(String(next));
|
|
42
|
+
} })), jsx("div", { className: S.gap }), showAttach && (jsxs(Fragment, { children: [jsx("input", { ref: fileInputRef, type: "file", accept: attachAccept, multiple: true, className: S.fileInput, disabled: disabled, onChange: e => {
|
|
43
|
+
const files = e.target.files;
|
|
44
|
+
if (files?.length)
|
|
45
|
+
onAttach?.(Array.from(files));
|
|
46
|
+
e.target.value = '';
|
|
47
|
+
} }), jsx(Tooltip, { content: "Attach", direction: "right", children: jsx(Button, { variant: "text", className: S.attachButton, disabled: disabled, "aria-label": "Attach", onClick: () => fileInputRef.current?.click(), children: jsx(Icon, { size: "m", type: "plus" }) }) })] }))] })] }));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { ChatPrompt };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".ChatPrompt_root__jEydp{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background-color:var(--decent-color-alpha-500);background-color:var(--accent-color-alpha-50);border-radius:var(--p-5);box-shadow:0 0 0 1px var(--active-color-alpha-100);display:flex;flex-direction:column;flex-wrap:wrap;font-size:80%;font-size:calc(80%*var(--dialogue-text-scale, 1));margin:2px auto;max-width:600px;min-height:76px;min-height:calc(var(--prompt-height, 80px) - 4px);position:relative;transition:box-shadow .4s ease-out,border-top-left-radius .2s ease,border-top-right-radius .2s ease,background-color .5s ease;width:100%}.ChatPrompt_root__jEydp:after{border-radius:inherit;box-shadow:inset 0 0 0 1px var(--accent-color-alpha-100),0 0 0 2px var(--decent-color-alpha-800),0 0 30px 0 var(--decent-color-alpha-500);content:\"\";height:100%;left:0;pointer-events:none;position:absolute;top:0;transition:box-shadow .4s ease-out;width:100%;z-index:-2}.ChatPrompt_root__jEydp:focus-within:after,.ChatPrompt_root__jEydp:hover:after{box-shadow:0 0 0 2px var(--decent-color-alpha-500),0 0 50px 0 var(--decent-color-alpha-500)}.ChatPrompt_root__jEydp:focus-within,.ChatPrompt_root__jEydp:hover{box-shadow:inset 0 0 0 1px var(--decent-color-alpha-500)}.ChatPrompt_root__jEydp:hover{box-shadow:inset 0 0 0 1px var(--active-color-alpha-300)}.ChatPrompt_root__jEydp:focus-within{box-shadow:inset 0 0 0 1px var(--active-color-alpha-500)}.ChatPrompt_composer__uWvF4{background-color:transparent!important;position:relative;transition:opacity .2s ease-out;width:100%;z-index:1}.ChatPrompt_composer__uWvF4 .ProseMirror,.ChatPrompt_composer__uWvF4 .editorMount .promptComposerEditor{caret-color:var(--accent-color);font-size:16px!important;font-size:calc(16px*var(--dialogue-text-scale, 1))!important;min-height:1.5em!important;padding:10px var(--p-7) 0 14px!important}.ChatPrompt_composer__uWvF4 .ProseMirror:focus{box-shadow:inset 0 0 0 2px none}.ChatPrompt_composer__uWvF4 .promptComposerEmptyEditor .promptComposerEmptyNode:before{color:var(--accent-color-alpha-500)}.ChatPrompt_buttons__gm2Lm{align-items:center;cursor:text;display:flex;flex-direction:row-reverse;flex-shrink:0;flex-wrap:wrap;gap:6px;justify-content:flex-start;padding:0 2px 0 6px;transform:translateY(-2px);width:100%;z-index:1}.ChatPrompt_buttons__gm2Lm svg{transition:.2s ease-out;transition-property:filter,scale}.ChatPrompt_button__h1lLp{background-color:transparent!important;padding:0 var(--p-2);position:relative}.ChatPrompt_button__h1lLp:focus,.ChatPrompt_button__h1lLp:hover{opacity:1}.ChatPrompt_button__h1lLp.ChatPrompt_submit__CICZy{background-color:var(--active-color)!important;box-shadow:0 1px 1px 0 rgba(0,0,0,.6);color:var(--decent-color)!important;margin-left:var(--p-2);transition:filter .2s ease-out,opacity .5s ease-out}.ChatPrompt_button__h1lLp.ChatPrompt_submit__CICZy svg{color:var(--decent-color)!important}.ChatPrompt_button__h1lLp.ChatPrompt_submit__CICZy:focus,.ChatPrompt_button__h1lLp.ChatPrompt_submit__CICZy:focus-visible,.ChatPrompt_button__h1lLp.ChatPrompt_submit__CICZy:hover{filter:drop-shadow(0 0 14px var(--active-color))}.ChatPrompt_button__h1lLp.ChatPrompt_submit__CICZy[disabled]{background-color:inherit!important;box-shadow:none;filter:none;pointer-events:none}.ChatPrompt_button__h1lLp.ChatPrompt_submit__CICZy[disabled] svg{color:var(--accent-color-alpha-500)!important}.ChatPrompt_submitIcon__yqHzk{display:block}.ChatPrompt_gap__xkA50{flex-grow:1}.ChatPrompt_promptModelSelector__RZpMR{flex-shrink:0;max-width:calc(100% - 200px);opacity:.5;transition:opacity .2s ease-out}.ChatPrompt_promptModelSelector__RZpMR:hover{opacity:1}.ChatPrompt_fileInput__l36Lj{display:none}.ChatPrompt_attachButton__vLVfy{flex-shrink:0;margin-left:-8px;opacity:.5;position:relative;z-index:4}";
|
|
4
|
+
var S = {"root":"ChatPrompt_root__jEydp","composer":"ChatPrompt_composer__uWvF4","buttons":"ChatPrompt_buttons__gm2Lm","button":"ChatPrompt_button__h1lLp","submit":"ChatPrompt_submit__CICZy","submitIcon":"ChatPrompt_submitIcon__yqHzk","gap":"ChatPrompt_gap__xkA50","promptModelSelector":"ChatPrompt_promptModelSelector__RZpMR","fileInput":"ChatPrompt_fileInput__l36Lj","attachButton":"ChatPrompt_attachButton__vLVfy"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { useRef, useEffect } from 'react';
|
|
4
|
+
import { Scroll } from '../Scroll/Scroll.js';
|
|
5
|
+
import { TextShimmer } from '../TextShimmer/TextShimmer.js';
|
|
6
|
+
import { scrollTo } from '../../tools/scroll.js';
|
|
7
|
+
import { ChatMessage } from './ChatMessage.js';
|
|
8
|
+
import S from './ChatView.styl.js';
|
|
9
|
+
import { isPlanMessageContent } from './content.js';
|
|
10
|
+
|
|
11
|
+
function ChatView({ messages, isPrompting, promptingLabel = 'Thinking…', emptyLabel = 'Start the conversation', className, messagesClassName, footer, onButtonClick, }) {
|
|
12
|
+
const listRef = useRef(null);
|
|
13
|
+
const visible = messages.filter(message => !isPlanMessageContent(message.content));
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const scroller = listRef.current;
|
|
16
|
+
if (scroller)
|
|
17
|
+
scrollTo(scroller, 0, scroller.scrollHeight + 80);
|
|
18
|
+
}, [visible.length, isPrompting]);
|
|
19
|
+
return (jsxs("div", { className: cn(S.root, className), children: [jsxs(Scroll, { y: true, fadeSize: "l", autoHide: true, className: S.messages, innerClassName: cn(S.messagesInner, messagesClassName), onInnerRef: elem => {
|
|
20
|
+
listRef.current = elem;
|
|
21
|
+
}, children: [visible.length === 0 && jsx("div", { className: S.empty, children: emptyLabel }), visible.map((message, index) => {
|
|
22
|
+
const prev = visible[index - 1];
|
|
23
|
+
const isStacked = Boolean(prev) &&
|
|
24
|
+
prev.role === message.role &&
|
|
25
|
+
message.role !== 'SYSTEM';
|
|
26
|
+
return (jsx(ChatMessage, { data: message, isStacked: isStacked, isLastMessage: index === visible.length - 1, onButtonClick: onButtonClick }, message.id || `${message.role}-${index}`));
|
|
27
|
+
})] }), isPrompting && (jsx("div", { className: S.status, children: jsx(TextShimmer, { children: promptingLabel }) })), footer && jsx("div", { className: S.footer, children: footer })] }));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { ChatView };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".ChatView_root__fRLUe{display:flex;flex-direction:column;height:100%;min-height:0;width:100%}.ChatView_messages__XjC53{flex:1;min-height:0}.ChatView_messagesInner__oRfmN{display:flex;flex-direction:column;padding:var(--p-10) calc(50% - 300px) 0}.ChatView_empty__5yGXV{margin:auto;opacity:.6;padding:24px;text-align:center}.ChatView_status__PpDvZ{font-size:13px;padding:4px 8px 0}.ChatView_footer__huDww{flex-shrink:0;overflow:visible;padding-top:0}";
|
|
4
|
+
var S = {"root":"ChatView_root__fRLUe","messages":"ChatView_messages__XjC53","messagesInner":"ChatView_messagesInner__oRfmN","empty":"ChatView_empty__5yGXV","status":"ChatView_status__PpDvZ","footer":"ChatView_footer__huDww"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const PLAN_TYPES = new Set([
|
|
2
|
+
'planCreated',
|
|
3
|
+
'planStatusUpdate',
|
|
4
|
+
'planStepUpdate',
|
|
5
|
+
'planStepChunk',
|
|
6
|
+
]);
|
|
7
|
+
function isPlanMessageContent(content) {
|
|
8
|
+
try {
|
|
9
|
+
const parsed = JSON.parse(content);
|
|
10
|
+
if (parsed.planId)
|
|
11
|
+
return true;
|
|
12
|
+
if (typeof parsed.type === 'string' && PLAN_TYPES.has(parsed.type)) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// plain text
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
function getDisplayContent(content) {
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(content);
|
|
24
|
+
if (parsed.type === 'userPrompt' && typeof parsed.display === 'string') {
|
|
25
|
+
return parsed.display;
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(parsed.parts)) {
|
|
28
|
+
return parsed.parts
|
|
29
|
+
.filter(part => part.type === 'text' && typeof part.text === 'string')
|
|
30
|
+
.map(part => part.text)
|
|
31
|
+
.join('\n');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// plain text
|
|
36
|
+
}
|
|
37
|
+
return content;
|
|
38
|
+
}
|
|
39
|
+
function getDisplayParts(content) {
|
|
40
|
+
try {
|
|
41
|
+
const parsed = JSON.parse(content);
|
|
42
|
+
if (Array.isArray(parsed.parts) && parsed.parts.length > 0) {
|
|
43
|
+
return parsed.parts;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// plain text
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
function parseSystemEvent(content) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(content);
|
|
54
|
+
if (parsed.systemEventType && parsed.systemData) {
|
|
55
|
+
switch (parsed.systemEventType) {
|
|
56
|
+
case 'agent-selected':
|
|
57
|
+
return {
|
|
58
|
+
summary: `Agent switched to: ${parsed.systemData.agentId || 'Auto'}`,
|
|
59
|
+
body: content,
|
|
60
|
+
};
|
|
61
|
+
case 'function-call':
|
|
62
|
+
return {
|
|
63
|
+
summary: `Called function: ${parsed.systemData.functionName}`,
|
|
64
|
+
body: content,
|
|
65
|
+
};
|
|
66
|
+
case 'error':
|
|
67
|
+
return {
|
|
68
|
+
summary: `Error: ${parsed.systemData.errorMessage}`,
|
|
69
|
+
body: content,
|
|
70
|
+
};
|
|
71
|
+
case 'conversation-stopped':
|
|
72
|
+
return { summary: 'Conversation stopped', body: content };
|
|
73
|
+
default:
|
|
74
|
+
return { summary: parsed.systemEventType, body: content };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (parsed.type === 'toolInvocation' && parsed.name) {
|
|
78
|
+
if (parsed.phase === 'invoked') {
|
|
79
|
+
return { summary: `Calling ${parsed.name}…`, body: content };
|
|
80
|
+
}
|
|
81
|
+
if (parsed.ok === false) {
|
|
82
|
+
return {
|
|
83
|
+
summary: `${parsed.name} failed${parsed.error ? `: ${parsed.error}` : ''}`,
|
|
84
|
+
body: content,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return { summary: `${parsed.name} result`, body: content };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// not structured
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { getDisplayContent, getDisplayParts, isPlanMessageContent, parseSystemEvent };
|
|
@@ -16,8 +16,10 @@ function Dialogue({ open, onOpenChange, disabled, trigger, title, subtitle, icon
|
|
|
16
16
|
const [isMounted, setIsMounted] = useState(false);
|
|
17
17
|
const [isAnimating, setIsAnimating] = useState(false);
|
|
18
18
|
const dialogRef = useRef(null);
|
|
19
|
+
const onOpenChangeRef = useRef(onOpenChange);
|
|
19
20
|
const titleId = useId();
|
|
20
21
|
const descriptionId = useId();
|
|
22
|
+
onOpenChangeRef.current = onOpenChange;
|
|
21
23
|
useEffect(() => {
|
|
22
24
|
setIsMounted(true);
|
|
23
25
|
}, []);
|
|
@@ -49,7 +51,7 @@ function Dialogue({ open, onOpenChange, disabled, trigger, title, subtitle, icon
|
|
|
49
51
|
}
|
|
50
52
|
const handleKeyDown = (e) => {
|
|
51
53
|
if (e.key === 'Escape') {
|
|
52
|
-
|
|
54
|
+
onOpenChangeRef.current(false);
|
|
53
55
|
return;
|
|
54
56
|
}
|
|
55
57
|
if (e.key === 'Tab' && focusableElements.length > 0) {
|
|
@@ -72,7 +74,7 @@ function Dialogue({ open, onOpenChange, disabled, trigger, title, subtitle, icon
|
|
|
72
74
|
previousActiveElement.focus();
|
|
73
75
|
}
|
|
74
76
|
};
|
|
75
|
-
}, [open
|
|
77
|
+
}, [open]);
|
|
76
78
|
useEffect(() => {
|
|
77
79
|
if (!open)
|
|
78
80
|
return;
|
|
@@ -32,6 +32,17 @@ import '../Checkbox/Checkbox.styl.js';
|
|
|
32
32
|
import '../Chip/Chip.styl.js';
|
|
33
33
|
import '../Tooltip/Tooltip.js';
|
|
34
34
|
import '../Card/Card.js';
|
|
35
|
+
import '../Router/context.js';
|
|
36
|
+
import '../Router/Link/Link.styl.js';
|
|
37
|
+
import '../Table/Table.styl.js';
|
|
38
|
+
import '../Chat/ChatFormattedText.styl.js';
|
|
39
|
+
import '../Expand/Expand.styl.js';
|
|
40
|
+
import '../Chat/ChatMessage.styl.js';
|
|
41
|
+
import '../PromptComposer/PromptComposer.js';
|
|
42
|
+
import '../ThinkingOutline/ThinkingOutline.styl.js';
|
|
43
|
+
import '../Chat/ChatPrompt.styl.js';
|
|
44
|
+
import '../TextShimmer/TextShimmer.js';
|
|
45
|
+
import '../Chat/ChatView.styl.js';
|
|
35
46
|
import '../Container/Container.js';
|
|
36
47
|
import '../DatePicker/DatePicker.styl.js';
|
|
37
48
|
import 'moment';
|
|
@@ -39,7 +50,6 @@ import '../DatePickerInput/DatePickerInput.styl.js';
|
|
|
39
50
|
import '../Dialogue/Dialogue.js';
|
|
40
51
|
import { Draggable } from '../Draggable/Draggable.js';
|
|
41
52
|
import '../DropZone/DropZone.styl.js';
|
|
42
|
-
import '../Expand/Expand.styl.js';
|
|
43
53
|
import '../Flex/Flex.styl.js';
|
|
44
54
|
import '../Form/Form.styl.js';
|
|
45
55
|
import '../Form/Validator.js';
|
|
@@ -54,11 +64,11 @@ import '../Heading/Heading.js';
|
|
|
54
64
|
import '../../services/i18n.js';
|
|
55
65
|
import '../LightBox/LightBox.styl.js';
|
|
56
66
|
import '../Menu/Menu.js';
|
|
67
|
+
import '../NestedMenu/NestedMenu.js';
|
|
57
68
|
import '../Notifications/store.js';
|
|
58
69
|
import '../Notifications/Notifications.styl.js';
|
|
59
70
|
import '../PopupMenu/PopupMenu.styl.js';
|
|
60
71
|
import '../Progress/Progress.styl.js';
|
|
61
|
-
import '../PromptComposer/PromptComposer.js';
|
|
62
72
|
import '@tiptap/extensions';
|
|
63
73
|
import '@tiptap/react';
|
|
64
74
|
import '@tiptap/starter-kit';
|
|
@@ -71,9 +81,7 @@ import '../RadioGroup/RadioGroupContext.js';
|
|
|
71
81
|
import '../RadioButton/RadioButton.styl.js';
|
|
72
82
|
import '../RadioGroup/RadioGroup.styl.js';
|
|
73
83
|
import '../Router/Router.js';
|
|
74
|
-
import '../Table/Table.styl.js';
|
|
75
84
|
import '../Tabs/Tabs.styl.js';
|
|
76
|
-
import '../TextShimmer/TextShimmer.js';
|
|
77
85
|
import '../TextWithDeferTooltip/TextWithDeferTooltip.styl.js';
|
|
78
86
|
import '../Text/Text.js';
|
|
79
87
|
import '../Theme/Theme.defaults.js';
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { useRef, useState, useEffect, useLayoutEffect } from 'react';
|
|
4
|
+
import { Icon } from '../Icon/Icon.js';
|
|
5
|
+
import S from './NestedMenu.styl.js';
|
|
6
|
+
|
|
7
|
+
const MOBILE_MQ = '(max-width: 720px)';
|
|
8
|
+
const HOVER_MQ = '(hover: hover) and (pointer: fine)';
|
|
9
|
+
function useMedia(query) {
|
|
10
|
+
const [matches, setMatches] = useState(() => typeof window !== 'undefined' && window.matchMedia(query).matches);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const mq = window.matchMedia(query);
|
|
13
|
+
const sync = () => setMatches(mq.matches);
|
|
14
|
+
sync();
|
|
15
|
+
mq.addEventListener('change', sync);
|
|
16
|
+
return () => mq.removeEventListener('change', sync);
|
|
17
|
+
}, [query]);
|
|
18
|
+
return matches;
|
|
19
|
+
}
|
|
20
|
+
function NestedMenuLabel({ children, className }) {
|
|
21
|
+
return jsx("span", { className: cn(S.label, className), children: children });
|
|
22
|
+
}
|
|
23
|
+
function NestedMenuItemRow({ children, className, danger, disabled, href, target, rel, onClick, }) {
|
|
24
|
+
const classes = cn(S.row, danger && S.itemDanger, className);
|
|
25
|
+
if (href) {
|
|
26
|
+
return (jsx("a", { className: classes, href: href, target: target, rel: rel, onClick: onClick, children: children }));
|
|
27
|
+
}
|
|
28
|
+
return (jsx("button", { type: "button", className: classes, disabled: disabled, onClick: onClick, children: children }));
|
|
29
|
+
}
|
|
30
|
+
function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end', className, }) {
|
|
31
|
+
const rootRef = useRef(null);
|
|
32
|
+
const [activeId, setActiveId] = useState(null);
|
|
33
|
+
const [flipLeft, setFlipLeft] = useState(false);
|
|
34
|
+
const hoverTimer = useRef(0);
|
|
35
|
+
const stacked = useMedia(MOBILE_MQ);
|
|
36
|
+
const canHover = useMedia(HOVER_MQ);
|
|
37
|
+
const active = items.find(item => item.id === activeId);
|
|
38
|
+
function close() {
|
|
39
|
+
onOpenChange(false);
|
|
40
|
+
setActiveId(null);
|
|
41
|
+
}
|
|
42
|
+
function openSub(id, announce = false) {
|
|
43
|
+
setActiveId(id);
|
|
44
|
+
if (announce) {
|
|
45
|
+
items.find(item => item.id === id)?.onSubmenuOpen?.();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (!open) {
|
|
50
|
+
setActiveId(null);
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
const onKey = (e) => {
|
|
54
|
+
if (e.key === 'Escape')
|
|
55
|
+
close();
|
|
56
|
+
};
|
|
57
|
+
const onPointer = (e) => {
|
|
58
|
+
if (!rootRef.current?.contains(e.target))
|
|
59
|
+
close();
|
|
60
|
+
};
|
|
61
|
+
document.addEventListener('keydown', onKey);
|
|
62
|
+
document.addEventListener('pointerdown', onPointer);
|
|
63
|
+
return () => {
|
|
64
|
+
document.removeEventListener('keydown', onKey);
|
|
65
|
+
document.removeEventListener('pointerdown', onPointer);
|
|
66
|
+
};
|
|
67
|
+
}, [open]);
|
|
68
|
+
useLayoutEffect(() => {
|
|
69
|
+
if (!open || !rootRef.current)
|
|
70
|
+
return;
|
|
71
|
+
const rect = rootRef.current.getBoundingClientRect();
|
|
72
|
+
setFlipLeft(window.innerWidth - rect.right < 280);
|
|
73
|
+
}, [open, activeId]);
|
|
74
|
+
useEffect(() => () => window.clearTimeout(hoverTimer.current), []);
|
|
75
|
+
function onItemEnter(id) {
|
|
76
|
+
if (!canHover || stacked)
|
|
77
|
+
return;
|
|
78
|
+
window.clearTimeout(hoverTimer.current);
|
|
79
|
+
const item = items.find(entry => entry.id === id);
|
|
80
|
+
if (item?.disabled || !item?.submenu) {
|
|
81
|
+
setActiveId(null);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
openSub(id, false);
|
|
85
|
+
}
|
|
86
|
+
function onItemLeave() {
|
|
87
|
+
if (!canHover || stacked)
|
|
88
|
+
return;
|
|
89
|
+
hoverTimer.current = window.setTimeout(() => setActiveId(null), 160);
|
|
90
|
+
}
|
|
91
|
+
function onItemClick(id) {
|
|
92
|
+
const item = items.find(entry => entry.id === id);
|
|
93
|
+
if (!item || item.disabled)
|
|
94
|
+
return;
|
|
95
|
+
if (item.onClick && !item.submenu) {
|
|
96
|
+
item.onClick();
|
|
97
|
+
close();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (activeId === id && !stacked) {
|
|
101
|
+
setActiveId(null);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
openSub(id, true);
|
|
105
|
+
}
|
|
106
|
+
function renderItems() {
|
|
107
|
+
return items.map(item => (jsxs("div", { className: S.itemWrap, onMouseEnter: () => onItemEnter(item.id), onMouseLeave: onItemLeave, children: [jsxs("button", { type: "button", className: cn(S.item, activeId === item.id && S.itemActive, item.danger && S.itemDanger, item.disabled && S.itemDisabled, item.className), role: "menuitem", disabled: item.disabled, "aria-haspopup": item.submenu ? 'menu' : undefined, "aria-expanded": item.submenu ? activeId === item.id : undefined, onClick: () => onItemClick(item.id), children: [item.icon && (jsx("span", { className: S.icon, "aria-hidden": true, children: item.icon })), jsx("span", { className: S.label, children: item.label }), item.hint != null && item.hint !== '' && (jsx("span", { className: S.hint, children: item.hint })), item.submenu && (jsx(Icon, { className: S.chevron, type: "chevronRight", size: "xs" }))] }), !stacked && activeId === item.id && item.submenu && (jsx("div", { className: cn(S.submenu, flipLeft && S.submenuLeft), role: "menu", onMouseEnter: () => {
|
|
108
|
+
window.clearTimeout(hoverTimer.current);
|
|
109
|
+
}, children: item.submenu }))] }, item.id)));
|
|
110
|
+
}
|
|
111
|
+
return (jsxs("div", { ref: rootRef, className: cn(S.root, className), children: [jsx("div", { className: S.trigger, onClick: () => onOpenChange(!open), children: trigger }), open && (jsxs("div", { className: cn(S.popup, align === 'end' && S.alignEnd), role: "menu", children: [stacked && active && (jsxs("div", { className: S.stacked, children: [jsxs("button", { type: "button", className: S.back, onClick: () => setActiveId(null), children: [jsx(Icon, { type: "chevronLeft", size: "xs" }), jsx("span", { className: S.label, children: active.label })] }), jsx("div", { className: S.stackedBody, children: active.submenu })] })), (!stacked || !active) && renderItems()] }))] }));
|
|
112
|
+
}
|
|
113
|
+
const NestedMenu = Object.assign(NestedMenuComponent, {
|
|
114
|
+
Item: NestedMenuItemRow,
|
|
115
|
+
Label: NestedMenuLabel,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
export { NestedMenu, NestedMenuItemRow, NestedMenuLabel };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".NestedMenu_root__ybyGA{display:inline-flex;position:relative}.NestedMenu_trigger__zBeNI{display:inline-flex}.NestedMenu_popup__q0uYO{background:var(--decent-color);border:1px solid var(--accent-color-alpha-200);border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.45);left:0;max-width:260px;min-width:200px;padding:4px;position:absolute;top:calc(100% + 6px);z-index:20}.NestedMenu_alignEnd__L4AZi{left:auto;right:0}.NestedMenu_itemWrap__Qmc0B{position:relative}.NestedMenu_back__dNsDV,.NestedMenu_item__tgbZm,.NestedMenu_row__48g5c{align-items:center;background:none;border:none;border-radius:6px;color:inherit;cursor:pointer;display:flex;font:inherit;font-size:13px;font-weight:500;gap:8px;letter-spacing:.01em;line-height:1.3;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.NestedMenu_back__dNsDV.NestedMenu_itemActive__RfPZH,.NestedMenu_back__dNsDV:hover,.NestedMenu_item__tgbZm.NestedMenu_itemActive__RfPZH,.NestedMenu_item__tgbZm:hover,.NestedMenu_row__48g5c.NestedMenu_itemActive__RfPZH,.NestedMenu_row__48g5c:hover{background:var(--accent-color-alpha-100)}.NestedMenu_back__dNsDV.NestedMenu_itemDisabled__evVk1,.NestedMenu_back__dNsDV:disabled,.NestedMenu_item__tgbZm.NestedMenu_itemDisabled__evVk1,.NestedMenu_item__tgbZm:disabled,.NestedMenu_row__48g5c.NestedMenu_itemDisabled__evVk1,.NestedMenu_row__48g5c:disabled{cursor:default;opacity:.55;pointer-events:none}.NestedMenu_itemDanger__oAJbP{color:var(--active-color)}.NestedMenu_itemDanger__oAJbP .NestedMenu_icon__4g2Yp{color:inherit;opacity:1}.NestedMenu_icon__4g2Yp{display:inline-flex;flex-shrink:0;opacity:.55}.NestedMenu_icon__4g2Yp svg{display:block}.NestedMenu_label__Jnm6l{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.NestedMenu_hint__hotNP{flex-shrink:0;font-weight:400;opacity:.5}.NestedMenu_chevron__8i-Po{flex-shrink:0;opacity:.45}.NestedMenu_row__48g5c svg{color:var(--active-color);flex-shrink:0}.NestedMenu_submenu__Tx1Ll{background:var(--decent-color);border:1px solid var(--accent-color-alpha-200);border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.45);left:calc(100% + 6px);max-height:min(360px,calc(100vh - 24px));max-width:280px;min-width:220px;overflow-x:hidden;overflow-y:auto;padding:4px;position:absolute;top:-4px;z-index:21}.NestedMenu_submenu__Tx1Ll:before{bottom:0;content:\"\";left:-6px;position:absolute;top:0;width:6px}.NestedMenu_submenuLeft__y18Nb{left:auto;right:calc(100% + 6px)}.NestedMenu_submenuLeft__y18Nb:before{left:auto;right:-6px}.NestedMenu_stacked__rMiOi{display:flex;flex-direction:column;max-height:min(360px,calc(100vh - 24px));overflow-y:auto}.NestedMenu_back__dNsDV{font-weight:650;margin-bottom:2px}.NestedMenu_stackedBody__Fbkma{min-width:0}";
|
|
4
|
+
var S = {"root":"NestedMenu_root__ybyGA","trigger":"NestedMenu_trigger__zBeNI","popup":"NestedMenu_popup__q0uYO","alignEnd":"NestedMenu_alignEnd__L4AZi","itemWrap":"NestedMenu_itemWrap__Qmc0B","item":"NestedMenu_item__tgbZm","row":"NestedMenu_row__48g5c","back":"NestedMenu_back__dNsDV","itemActive":"NestedMenu_itemActive__RfPZH","itemDisabled":"NestedMenu_itemDisabled__evVk1","itemDanger":"NestedMenu_itemDanger__oAJbP","icon":"NestedMenu_icon__4g2Yp","label":"NestedMenu_label__Jnm6l","hint":"NestedMenu_hint__hotNP","chevron":"NestedMenu_chevron__8i-Po","submenu":"NestedMenu_submenu__Tx1Ll","submenuLeft":"NestedMenu_submenuLeft__y18Nb","stacked":"NestedMenu_stacked__rMiOi","stackedBody":"NestedMenu_stackedBody__Fbkma"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import S from './ThinkingOutline.styl.js';
|
|
4
|
+
|
|
5
|
+
function ThinkingOutline({ active, className }) {
|
|
6
|
+
return (jsx("div", { className: cn(S.root, active && S.active, className), children: jsx("div", { className: S.bloom }) }));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export { ThinkingOutline };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = "@property --promptGlowAngle{syntax:\"<angle>\";inherits:true;initial-value:0deg}.ThinkingOutline_root__rvvBG{animation:ThinkingOutline_orbitGlow__3bK-F 3.5s linear infinite;border-radius:inherit;inset:0;opacity:0;pointer-events:none;position:absolute;transition:opacity .5s ease-out}.ThinkingOutline_root__rvvBG.ThinkingOutline_active__-66iV{opacity:1}.ThinkingOutline_root__rvvBG:before{background:conic-gradient(from var(--promptGlowAngle),var(--active-color) 0deg,var(--active-color-alpha-300) 48deg,transparent 80deg,transparent 100deg,var(--active-color-alpha-300) 132deg,var(--active-color) 180deg,var(--active-color-alpha-300) 228deg,transparent 260deg,transparent 280deg,var(--active-color-alpha-300) 312deg,var(--active-color) 1turn);border-radius:inherit;content:\"\";inset:0;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;padding:1.5px;position:absolute}.ThinkingOutline_bloom__XKYD5{border-radius:inherit;filter:blur(20px);inset:0;opacity:.55;position:absolute}.ThinkingOutline_bloom__XKYD5:before{background:conic-gradient(from var(--promptGlowAngle),var(--active-color) 0deg,var(--active-color-alpha-300) 48deg,transparent 80deg,transparent 100deg,var(--active-color-alpha-300) 132deg,var(--active-color) 180deg,var(--active-color-alpha-300) 228deg,transparent 260deg,transparent 280deg,var(--active-color-alpha-300) 312deg,var(--active-color) 1turn);border-radius:inherit;content:\"\";inset:0;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;padding:6px;position:absolute}@media (prefers-reduced-motion:reduce){.ThinkingOutline_root__rvvBG{animation:none}}@keyframes ThinkingOutline_orbitGlow__3bK-F{0%{--promptGlowAngle:-30deg}25%{--promptGlowAngle:30deg}50%{--promptGlowAngle:150deg}75%{--promptGlowAngle:210deg}to{--promptGlowAngle:330deg}}";
|
|
4
|
+
var S = {"root":"ThinkingOutline_root__rvvBG","orbitGlow":"ThinkingOutline_orbitGlow__3bK-F","active":"ThinkingOutline_active__-66iV","bloom":"ThinkingOutline_bloom__XKYD5"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".SlashSuggestionList_root__9KCb1{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background-color:var(--decent-color-alpha-700);border-radius:8px;border-radius:var(--radius-lg,8px);box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 8px 24px rgba(0,0,0,.2);color:var(--foreground);max-width:90vw;min-width:220px;overflow:hidden;position:relative}.SlashSuggestionList_root__9KCb1:before{background-color:var(--accent-color-alpha-50);bottom:0;content:\"\";left:0;pointer-events:none;position:absolute;right:0;top:0}.dark .SlashSuggestionList_root__9KCb1{box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 8px 24px rgba(0,0,0,.5)}.SlashSuggestionList_menu__s-jK3{margin:0;max-height:40vh}.SlashSuggestionList_item__9JBeY{align-items:center;border-radius:var(--p-2);display:flex;flex-direction:row;gap:var(--p-2);height:auto!important;justify-content:flex-start;min-height:0;overflow:visible!important;padding:var(--p-1) var(--p-2)!important;position:relative;text-overflow:clip!important;white-space:normal!important;width:100%}.
|
|
3
|
+
var css_248z = ".SlashSuggestionList_root__9KCb1{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background-color:var(--decent-color-alpha-700);border-radius:8px;border-radius:var(--radius-lg,8px);box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 8px 24px rgba(0,0,0,.2);color:var(--foreground);max-width:90vw;min-width:220px;overflow:hidden;position:relative}.SlashSuggestionList_root__9KCb1:before{background-color:var(--accent-color-alpha-50);bottom:0;content:\"\";left:0;pointer-events:none;position:absolute;right:0;top:0}.dark .SlashSuggestionList_root__9KCb1{box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 8px 24px rgba(0,0,0,.5)}.SlashSuggestionList_menu__s-jK3{margin:0;max-height:40vh}.SlashSuggestionList_item__9JBeY{align-items:center;border-radius:var(--p-2);display:flex;flex-direction:row;gap:var(--p-2);height:auto!important;justify-content:flex-start;min-height:0;overflow:visible!important;padding:var(--p-1) var(--p-2)!important;position:relative;text-overflow:clip!important;white-space:normal!important;width:100%}.SlashSuggestionList_itemHighlighted__cStZr{box-shadow:inset 100vw 0 0 0 var(--accent-color-alpha-200)}.SlashSuggestionList_itemIcon__hTtxe{color:var(--accent-color-alpha-800);flex-shrink:0}.SlashSuggestionList_itemText__uwNbZ{align-items:flex-start;display:flex;flex-direction:column;min-width:0}.SlashSuggestionList_itemLabel__OMaov{font-weight:600}.SlashSuggestionList_itemDesc__fAdcA{color:var(--accent-color-alpha-600);font-size:80%;white-space:normal}.SlashSuggestionList_mention__aT45p{align-items:center;background:var(--muted);border-radius:var(--p-1);display:inline-flex;line-height:1.4;margin:0 var(--p-1);padding:0 var(--p-1);transition:background-color .1s ease-in-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:baseline;white-space:nowrap}.SlashSuggestionList_mention__aT45p:hover{background-color:var(--accent-color-alpha-200)}";
|
|
4
4
|
var S = {"root":"SlashSuggestionList_root__9KCb1","menu":"SlashSuggestionList_menu__s-jK3","item":"SlashSuggestionList_item__9JBeY","itemHighlighted":"SlashSuggestionList_itemHighlighted__cStZr","itemIcon":"SlashSuggestionList_itemIcon__hTtxe","itemText":"SlashSuggestionList_itemText__uwNbZ","itemLabel":"SlashSuggestionList_itemLabel__OMaov","itemDesc":"SlashSuggestionList_itemDesc__fAdcA","mention":"SlashSuggestionList_mention__aT45p"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export type ChatRole = 'USER' | 'AGENT' | 'SYSTEM';
|
|
3
|
+
export type ChatContentPart = {
|
|
4
|
+
type: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
image_url?: {
|
|
7
|
+
url?: string;
|
|
8
|
+
filePath?: string;
|
|
9
|
+
filename?: string;
|
|
10
|
+
};
|
|
11
|
+
video_url?: {
|
|
12
|
+
url?: string;
|
|
13
|
+
filePath?: string;
|
|
14
|
+
};
|
|
15
|
+
file?: {
|
|
16
|
+
url?: string;
|
|
17
|
+
filePath?: string;
|
|
18
|
+
filename?: string;
|
|
19
|
+
};
|
|
20
|
+
input_audio?: {
|
|
21
|
+
data?: string;
|
|
22
|
+
format?: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export type ChatMessageData = {
|
|
26
|
+
id?: string;
|
|
27
|
+
role: ChatRole;
|
|
28
|
+
content: string;
|
|
29
|
+
createdAt?: string | Date;
|
|
30
|
+
};
|
|
31
|
+
export type ChatFormattedTextProps = {
|
|
32
|
+
text: string;
|
|
33
|
+
className?: string;
|
|
34
|
+
onButtonClick?: (params: {
|
|
35
|
+
text: string;
|
|
36
|
+
[name: string]: string;
|
|
37
|
+
}) => void;
|
|
38
|
+
};
|
|
39
|
+
export type ChatMessageProps = {
|
|
40
|
+
data: ChatMessageData;
|
|
41
|
+
isStacked?: boolean;
|
|
42
|
+
isLastMessage?: boolean;
|
|
43
|
+
className?: string;
|
|
44
|
+
onButtonClick?: ChatFormattedTextProps['onButtonClick'];
|
|
45
|
+
};
|
|
46
|
+
export type ChatViewProps = {
|
|
47
|
+
messages: ChatMessageData[];
|
|
48
|
+
isPrompting?: boolean;
|
|
49
|
+
promptingLabel?: ReactNode;
|
|
50
|
+
emptyLabel?: ReactNode;
|
|
51
|
+
className?: string;
|
|
52
|
+
messagesClassName?: string;
|
|
53
|
+
footer?: ReactNode;
|
|
54
|
+
onButtonClick?: ChatFormattedTextProps['onButtonClick'];
|
|
55
|
+
};
|
|
56
|
+
export type ChatPromptModel = {
|
|
57
|
+
id: string;
|
|
58
|
+
label: string;
|
|
59
|
+
};
|
|
60
|
+
export type ChatPromptProps = {
|
|
61
|
+
value: string;
|
|
62
|
+
onChange: (value: string) => void;
|
|
63
|
+
onSubmit: (value: string) => void;
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
/** Orbiting glow on the prompt while the agent is generating. */
|
|
66
|
+
isPrompting?: boolean;
|
|
67
|
+
placeholder?: string;
|
|
68
|
+
className?: string;
|
|
69
|
+
/** Default true. Hidden file input + plus button (no STT / live voice). */
|
|
70
|
+
showAttach?: boolean;
|
|
71
|
+
onAttach?: (files: File[]) => void;
|
|
72
|
+
attachAccept?: string;
|
|
73
|
+
/** Default true. Compact model dropdown (e.g. Auto Router). */
|
|
74
|
+
showModelSelector?: boolean;
|
|
75
|
+
models?: ChatPromptModel[];
|
|
76
|
+
model?: string;
|
|
77
|
+
onModelChange?: (id: string) => void;
|
|
78
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { ChatPromptProps } from './types';
|
|
2
|
+
export declare function ChatPrompt({ value, onChange, onSubmit, disabled, isPrompting, placeholder, className, showAttach, onAttach, attachAccept, showModelSelector, models, model, onModelChange, }: ChatPromptProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ChatContentPart } from './types';
|
|
2
|
+
export declare function isPlanMessageContent(content: string): boolean;
|
|
3
|
+
export declare function getDisplayContent(content: string): string;
|
|
4
|
+
export declare function getDisplayParts(content: string): ChatContentPart[] | null;
|
|
5
|
+
export declare function parseSystemEvent(content: string): {
|
|
6
|
+
summary: string;
|
|
7
|
+
body: string;
|
|
8
|
+
} | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ChatFormattedText } from './ChatFormattedText';
|
|
2
|
+
export { ChatMessage } from './ChatMessage';
|
|
3
|
+
export { ChatPrompt } from './ChatPrompt';
|
|
4
|
+
export { ChatView } from './ChatView';
|
|
5
|
+
export { getDisplayContent, getDisplayParts, isPlanMessageContent, parseSystemEvent, } from './content';
|
|
6
|
+
export type { ChatContentPart, ChatFormattedTextProps, ChatMessageData, ChatMessageProps, ChatPromptModel, ChatPromptProps, ChatRole, ChatViewProps, } from './types';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { ChatContentPart, ChatFormattedTextProps, ChatMessageData, ChatMessageProps, ChatPromptModel, ChatPromptProps, ChatRole, ChatViewProps, } from './Chat.types';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as T from './NestedMenu.types';
|
|
2
|
+
export declare function NestedMenuLabel({ children, className }: T.NestedMenuLabelProps): import("react").JSX.Element;
|
|
3
|
+
export declare function NestedMenuItemRow({ children, className, danger, disabled, href, target, rel, onClick, }: T.NestedMenuRowProps): import("react").JSX.Element;
|
|
4
|
+
declare function NestedMenuComponent({ trigger, items, open, onOpenChange, align, className, }: T.Props): import("react").JSX.Element;
|
|
5
|
+
export declare const NestedMenu: typeof NestedMenuComponent & {
|
|
6
|
+
Item: typeof NestedMenuItemRow;
|
|
7
|
+
Label: typeof NestedMenuLabel;
|
|
8
|
+
};
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type NestedMenuItem = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
icon?: ReactNode;
|
|
6
|
+
hint?: ReactNode;
|
|
7
|
+
submenu?: ReactNode;
|
|
8
|
+
onSubmenuOpen?: () => void;
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
danger?: boolean;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
className?: string;
|
|
13
|
+
};
|
|
14
|
+
export type Props = {
|
|
15
|
+
trigger: ReactNode;
|
|
16
|
+
items: NestedMenuItem[];
|
|
17
|
+
open: boolean;
|
|
18
|
+
onOpenChange: (open: boolean) => void;
|
|
19
|
+
align?: 'start' | 'end';
|
|
20
|
+
className?: string;
|
|
21
|
+
};
|
|
22
|
+
export type NestedMenuProps = Props;
|
|
23
|
+
export type NestedMenuRowProps = {
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
danger?: boolean;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
href?: string;
|
|
29
|
+
target?: string;
|
|
30
|
+
rel?: string;
|
|
31
|
+
onClick?: () => void;
|
|
32
|
+
};
|
|
33
|
+
export type NestedMenuLabelProps = {
|
|
34
|
+
children: ReactNode;
|
|
35
|
+
className?: string;
|
|
36
|
+
};
|
|
@@ -6,6 +6,7 @@ export * from './Calendar/Calendar';
|
|
|
6
6
|
export * from './Checkbox/Checkbox';
|
|
7
7
|
export * from './Chip/Chip';
|
|
8
8
|
export * from './Card';
|
|
9
|
+
export * from './Chat';
|
|
9
10
|
export * from './Container/Container';
|
|
10
11
|
export * from './DatePicker/DatePicker';
|
|
11
12
|
export * from './DatePickerInput/DatePickerInput';
|
|
@@ -28,6 +29,8 @@ export * from './LangSelector/LangSelector';
|
|
|
28
29
|
export * from './Lazy/Lazy';
|
|
29
30
|
export * from './LightBox/LightBox';
|
|
30
31
|
export * from './Menu/Menu';
|
|
32
|
+
export * from './NestedMenu/NestedMenu';
|
|
33
|
+
export type { NestedMenuItem, NestedMenuProps, } from './NestedMenu/NestedMenu.types';
|
|
31
34
|
export * from './Notifications/Notifications';
|
|
32
35
|
export * from './Paranja/Paranja';
|
|
33
36
|
export * from './Popup/Popup';
|
|
@@ -49,6 +52,7 @@ export * from './Spinner/Spinner';
|
|
|
49
52
|
export * from './Table/Table';
|
|
50
53
|
export * from './Tabs/Tabs';
|
|
51
54
|
export * from './TextShimmer/TextShimmer';
|
|
55
|
+
export * from './ThinkingOutline';
|
|
52
56
|
export * from './TextWithDeferTooltip';
|
|
53
57
|
export * from './Tooltip/Tooltip';
|
|
54
58
|
export * from './Text/Text';
|