hanbiro-react16-sdk 1.0.22 → 1.0.24

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 (44) hide show
  1. package/dist/components/ChatAIDraft/EmptyState.d.ts +6 -0
  2. package/dist/components/ChatAIDraft/EmptyState.js +222 -0
  3. package/dist/components/ChatAIDraft/List.js +55 -18
  4. package/dist/components/ChatAIDraft/SettingPopper/ChipGroup.d.ts +11 -0
  5. package/dist/components/ChatAIDraft/SettingPopper/ChipGroup.js +62 -0
  6. package/dist/components/ChatAIDraft/SettingPopper/LanguageSelect.d.ts +21 -0
  7. package/dist/components/ChatAIDraft/SettingPopper/LanguageSelect.js +137 -0
  8. package/dist/components/ChatAIDraft/SettingPopper/icons.d.ts +3 -0
  9. package/dist/components/ChatAIDraft/SettingPopper/icons.js +30 -0
  10. package/dist/components/ChatAIDraft/{SettingPopper.d.ts → SettingPopper/index.d.ts} +5 -5
  11. package/dist/components/ChatAIDraft/{SettingPopper.js → SettingPopper/index.js} +37 -77
  12. package/dist/components/ChatAIDraft/constants.d.ts +4 -0
  13. package/dist/components/ChatAIDraft/constants.js +18 -0
  14. package/dist/components/ChatAIDraft/index.d.ts +8 -8
  15. package/dist/components/ChatAIDraft/index.js +100 -52
  16. package/dist/components/index.d.ts +1 -1
  17. package/dist/hanbiro-react16-sdk.style.css +39 -2
  18. package/dist/hanbiro-react16-sdk.umd.js +2244 -1646
  19. package/dist/index.js +2 -2
  20. package/dist/node_modules/prop-types/index.js +1 -2
  21. package/dist/node_modules/react-feather/dist/icons/align-justify.js +86 -0
  22. package/dist/node_modules/react-feather/dist/icons/{send.js → arrow-up.js} +10 -10
  23. package/dist/node_modules/react-feather/dist/icons/award.js +72 -0
  24. package/dist/node_modules/react-feather/dist/icons/check.js +68 -0
  25. package/dist/node_modules/react-feather/dist/icons/chevron-down.js +68 -0
  26. package/dist/node_modules/react-feather/dist/icons/compass.js +72 -0
  27. package/dist/node_modules/react-feather/dist/icons/file-text.js +82 -0
  28. package/dist/node_modules/react-feather/dist/icons/frown.js +82 -0
  29. package/dist/node_modules/react-feather/dist/icons/heart.js +68 -0
  30. package/dist/node_modules/react-feather/dist/icons/message-circle.js +68 -0
  31. package/dist/node_modules/react-feather/dist/icons/message-square.js +68 -0
  32. package/dist/node_modules/react-feather/dist/icons/scissors.js +89 -0
  33. package/dist/node_modules/react-feather/dist/icons/smile.js +82 -0
  34. package/dist/node_modules/react-feather/dist/icons/thumbs-up.js +68 -0
  35. package/dist/node_modules/react-feather/dist/icons/zap.js +68 -0
  36. package/package.json +1 -1
  37. package/dist/components/TinyMceEditor/index.js +0 -181
  38. package/dist/components/TinyMceEditor/scrollStyle.js +0 -40
  39. package/dist/components/TinyMceEditor/useEditor.js +0 -120
  40. package/dist/node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/ScriptLoader2.js +0 -148
  41. package/dist/node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/TinyMCE.js +0 -7
  42. package/dist/node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/Utils.js +0 -103
  43. package/dist/node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/components/Editor.js +0 -353
  44. package/dist/node_modules/@tinymce/tinymce-react/lib/es2015/main/ts/components/EditorPropTypes.js +0 -102
@@ -23,11 +23,12 @@ var __async = (__this, __arguments, generator) => {
23
23
  };
24
24
  import * as React from "react";
25
25
  import * as ReactDOM from "react-dom";
26
- import TinyMceEditor from "../TinyMceEditor/index.js";
27
- import Tooltip from "../Tooltip/index.js";
28
- import { apiGet } from "../../utils/api.js";
29
- import Settings from "../../node_modules/react-feather/dist/icons/settings.js";
30
- import Copy from "../../node_modules/react-feather/dist/icons/copy.js";
26
+ import { apiGet } from "../../../utils/api.js";
27
+ import { TONE_OPTIONS, LENGTH_OPTIONS } from "../constants.js";
28
+ import LanguageSelect from "./LanguageSelect.js";
29
+ import ChipGroup from "./ChipGroup.js";
30
+ import { TONE_ICONS, LENGTH_ICONS } from "./icons.js";
31
+ import Settings from "../../../node_modules/react-feather/dist/icons/settings.js";
31
32
  class SettingPopper extends React.Component {
32
33
  constructor(props) {
33
34
  super(props);
@@ -37,7 +38,7 @@ class SettingPopper extends React.Component {
37
38
  var _a;
38
39
  const { data } = yield apiGet("/email/ai/langlist");
39
40
  if (data == null ? void 0 : data.list) {
40
- const langs = (_a = Object.keys(data == null ? void 0 : data.list)) == null ? void 0 : _a.map((_key, i) => {
41
+ const langs = (_a = Object.keys(data == null ? void 0 : data.list)) == null ? void 0 : _a.map((_key) => {
41
42
  var _a2;
42
43
  const _item = (_a2 = data == null ? void 0 : data.list) == null ? void 0 : _a2[_key];
43
44
  return {
@@ -57,12 +58,6 @@ class SettingPopper extends React.Component {
57
58
  __publicField(this, "togglePopper", () => {
58
59
  this.setState((prevState) => ({ open: !prevState.open }));
59
60
  });
60
- __publicField(this, "handleLangChange", (e) => {
61
- const selected = this.state.languageOptions.find(
62
- (opt) => opt.value === e.target.value
63
- );
64
- this.props.setLang(selected || null);
65
- });
66
61
  this.state = { open: false, languageOptions: [] };
67
62
  this.containerRef = React.createRef();
68
63
  this.popperRef = React.createRef();
@@ -75,13 +70,7 @@ class SettingPopper extends React.Component {
75
70
  document.removeEventListener("mousedown", this.handleClickOutside);
76
71
  }
77
72
  render() {
78
- const {
79
- lang,
80
- originalEmail,
81
- setOriginalEmail,
82
- getEditorContent,
83
- parentRef
84
- } = this.props;
73
+ const { lang, tone, length, parentRef, setLang, setTone, setLength } = this.props;
85
74
  const { open, languageOptions } = this.state;
86
75
  let popperTop = 0;
87
76
  let popperLeft = 0;
@@ -139,77 +128,48 @@ class SettingPopper extends React.Component {
139
128
  /* @__PURE__ */ React.createElement(
140
129
  "div",
141
130
  {
142
- style: { display: "flex", flexDirection: "column", gap: 4 }
131
+ style: { display: "flex", flexDirection: "column", gap: 6 }
143
132
  },
133
+ /* @__PURE__ */ React.createElement("span", { style: { fontSize: 12, fontWeight: 600 } }, "Language"),
144
134
  /* @__PURE__ */ React.createElement(
145
- "span",
146
- {
147
- style: {
148
- fontSize: 12,
149
- fontWeight: 500
150
- // color: "var(--text-secondary)",
151
- }
152
- },
153
- "Language"
154
- ),
155
- /* @__PURE__ */ React.createElement(
156
- "select",
135
+ LanguageSelect,
157
136
  {
158
- name: "language",
159
- value: lang ? lang.value : "",
160
- onChange: this.handleLangChange
161
- },
162
- /* @__PURE__ */ React.createElement("option", { value: "", disabled: true }, "Select Language"),
163
- languageOptions.map((opt) => {
164
- return /* @__PURE__ */ React.createElement("option", { key: opt.value, value: opt.value }, opt.label);
165
- })
137
+ value: lang,
138
+ options: languageOptions,
139
+ onChange: (opt) => setLang(opt)
140
+ }
166
141
  )
167
142
  ),
168
143
  /* @__PURE__ */ React.createElement(
169
144
  "div",
170
145
  {
171
- style: { display: "flex", flexDirection: "column", gap: 4 }
146
+ style: { display: "flex", flexDirection: "column", gap: 6 }
172
147
  },
148
+ /* @__PURE__ */ React.createElement("span", { style: { fontSize: 12, fontWeight: 600 } }, "Tone"),
173
149
  /* @__PURE__ */ React.createElement(
174
- "div",
150
+ ChipGroup,
175
151
  {
176
- style: {
177
- display: "flex",
178
- alignItems: "center",
179
- justifyContent: "space-between"
180
- }
181
- },
182
- /* @__PURE__ */ React.createElement(
183
- "span",
184
- {
185
- style: {
186
- fontSize: 12,
187
- fontWeight: 500
188
- // color: "var(--text-secondary)",
189
- }
190
- },
191
- "AI Context"
192
- ),
193
- getEditorContent && /* @__PURE__ */ React.createElement(Tooltip, { title: "Copy from origin email" }, /* @__PURE__ */ React.createElement(
194
- "button",
195
- {
196
- type: "button",
197
- onClick: () => {
198
- const currentContent = getEditorContent();
199
- setOriginalEmail(currentContent);
200
- },
201
- className: "icon-button small"
202
- },
203
- /* @__PURE__ */ React.createElement(Copy, null)
204
- ))
205
- ),
152
+ options: TONE_OPTIONS,
153
+ selected: tone,
154
+ onSelect: (opt) => setTone(opt),
155
+ iconMap: TONE_ICONS
156
+ }
157
+ )
158
+ ),
159
+ /* @__PURE__ */ React.createElement(
160
+ "div",
161
+ {
162
+ style: { display: "flex", flexDirection: "column", gap: 6 }
163
+ },
164
+ /* @__PURE__ */ React.createElement("span", { style: { fontSize: 12, fontWeight: 600 } }, "Length"),
206
165
  /* @__PURE__ */ React.createElement(
207
- TinyMceEditor,
166
+ ChipGroup,
208
167
  {
209
- value: originalEmail,
210
- onChange: (val) => setOriginalEmail(val),
211
- height: 350,
212
- isSimple: true
168
+ options: LENGTH_OPTIONS,
169
+ selected: length,
170
+ onSelect: (opt) => setLength(opt),
171
+ iconMap: LENGTH_ICONS,
172
+ columns: 4
213
173
  }
214
174
  )
215
175
  )
@@ -0,0 +1,4 @@
1
+ import { LabelValue } from '../../types';
2
+
3
+ export declare const TONE_OPTIONS: LabelValue[];
4
+ export declare const LENGTH_OPTIONS: LabelValue[];
@@ -0,0 +1,18 @@
1
+ const TONE_OPTIONS = [
2
+ { label: "Formal", value: "formal" },
3
+ { label: "Polite", value: "polite" },
4
+ { label: "Neutral", value: "neutral" },
5
+ { label: "Friendly", value: "friendly" },
6
+ { label: "Firm", value: "firm" },
7
+ { label: "Apology", value: "apologetic" }
8
+ ];
9
+ const LENGTH_OPTIONS = [
10
+ { label: "Short", value: "short" },
11
+ { label: "Medium", value: "medium" },
12
+ { label: "Long", value: "long" },
13
+ { label: "1-liner", value: "one_liner" }
14
+ ];
15
+ export {
16
+ LENGTH_OPTIONS,
17
+ TONE_OPTIONS
18
+ };
@@ -7,10 +7,6 @@ export interface ChatAIDraftProps {
7
7
  html: string;
8
8
  }) => void;
9
9
  }
10
- /** Public imperative API exposed via ref */
11
- export interface ChatAIDraftRef {
12
- setAIContext: (html: string) => void;
13
- }
14
10
  export interface AIMessage {
15
11
  id: string;
16
12
  question: string;
@@ -24,18 +20,22 @@ interface AIPaneState {
24
20
  messages: AIMessage[];
25
21
  isSending: boolean;
26
22
  lang: LabelValue | null;
23
+ tone: LabelValue | null;
24
+ length: LabelValue | null;
27
25
  conversationId: string;
28
- originalEmail: string;
29
26
  }
30
- declare class ChatAIDraft extends React.Component<ChatAIDraftProps, AIPaneState> implements ChatAIDraftRef {
27
+ declare class ChatAIDraft extends React.Component<ChatAIDraftProps, AIPaneState> {
31
28
  private rootRef;
29
+ private textareaRef;
32
30
  constructor(props: ChatAIDraftProps);
33
- setAIContext: (html: string) => void;
31
+ adjustTextareaHeight: () => void;
34
32
  handleMessageChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
33
+ componentDidUpdate(_: ChatAIDraftProps, prevState: AIPaneState): void;
35
34
  handleSubmit: () => Promise<void>;
36
35
  handleKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void;
37
36
  setLang: (lang: LabelValue | null) => void;
38
- setOriginalEmail: (email: string) => void;
37
+ setTone: (tone: LabelValue | null) => void;
38
+ setLength: (length: LabelValue | null) => void;
39
39
  render(): React.JSX.Element;
40
40
  }
41
41
  export default ChatAIDraft;
@@ -39,27 +39,32 @@ var __async = (__this, __arguments, generator) => {
39
39
  });
40
40
  };
41
41
  import * as React from "react";
42
- import CustomAiIcon from "./CustomAIIcon.js";
43
42
  import { callAI } from "./helper.js";
44
43
  import List from "./List.js";
45
- import SettingPopper from "./SettingPopper.js";
44
+ import EmptyState from "./EmptyState.js";
45
+ import SettingPopper from "./SettingPopper/index.js";
46
+ import { LENGTH_OPTIONS, TONE_OPTIONS } from "./constants.js";
46
47
  import { AI_LANG_FLAGS } from "../../constants/index.js";
47
48
  import CountryFlag from "../CountryFlag/index.js";
48
49
  import v4 from "../../node_modules/uuid/dist/esm-browser/v4.js";
49
- import Send from "../../node_modules/react-feather/dist/icons/send.js";
50
+ import ArrowUp from "../../node_modules/react-feather/dist/icons/arrow-up.js";
50
51
  class ChatAIDraft extends React.Component {
51
52
  constructor(props) {
52
53
  var _a;
53
54
  super(props);
54
55
  __publicField(this, "rootRef");
55
- __publicField(this, "setAIContext", (html) => {
56
- this.setState({ originalEmail: html });
56
+ __publicField(this, "textareaRef");
57
+ __publicField(this, "adjustTextareaHeight", () => {
58
+ const el = this.textareaRef.current;
59
+ if (!el) return;
60
+ el.style.height = "auto";
61
+ el.style.height = `${Math.min(el.scrollHeight, 160)}px`;
57
62
  });
58
63
  __publicField(this, "handleMessageChange", (e) => {
59
- this.setState({ message: e.target.value });
64
+ this.setState({ message: e.target.value }, this.adjustTextareaHeight);
60
65
  });
61
66
  __publicField(this, "handleSubmit", () => __async(this, null, function* () {
62
- const { message, messages, lang, originalEmail, conversationId } = this.state;
67
+ const { message, messages, lang, tone, length, conversationId } = this.state;
63
68
  if (!message.trim()) return;
64
69
  const newId = v4();
65
70
  let newMessage = {
@@ -79,9 +84,14 @@ class ChatAIDraft extends React.Component {
79
84
  const params = {
80
85
  query: message,
81
86
  default_language: lang ? lang.value : "KR",
82
- original_email: originalEmail,
83
87
  debug_grpc: true
84
88
  };
89
+ if (tone) {
90
+ params.tone = tone.value;
91
+ }
92
+ if (length) {
93
+ params.length = length.value;
94
+ }
85
95
  if (conversationId) {
86
96
  params.conversation_id = conversationId;
87
97
  }
@@ -125,24 +135,36 @@ class ChatAIDraft extends React.Component {
125
135
  __publicField(this, "setLang", (lang) => {
126
136
  this.setState({ lang });
127
137
  });
128
- __publicField(this, "setOriginalEmail", (email) => {
129
- this.setState({ originalEmail: email });
138
+ __publicField(this, "setTone", (tone) => {
139
+ this.setState({ tone });
140
+ });
141
+ __publicField(this, "setLength", (length) => {
142
+ this.setState({ length });
130
143
  });
131
144
  this.rootRef = React.createRef();
145
+ this.textareaRef = React.createRef();
132
146
  const lang = ((_a = AI_LANG_FLAGS) == null ? void 0 : _a.find((_item) => (_item == null ? void 0 : _item.value) === (props == null ? void 0 : props.defaultLang))) || AI_LANG_FLAGS[0];
133
147
  this.state = {
134
148
  message: "",
135
149
  messages: [],
136
150
  isSending: false,
137
151
  lang,
138
- conversationId: "",
139
- originalEmail: ""
152
+ tone: TONE_OPTIONS[2],
153
+ // Neutral
154
+ length: LENGTH_OPTIONS[1],
155
+ // Medium
156
+ conversationId: ""
140
157
  };
141
158
  }
159
+ componentDidUpdate(_, prevState) {
160
+ if (prevState.message !== this.state.message) {
161
+ this.adjustTextareaHeight();
162
+ }
163
+ }
142
164
  render() {
143
165
  var _a, _b;
144
166
  const { onApply, getEditorContent } = this.props;
145
- const { message, messages, isSending, lang, originalEmail } = this.state;
167
+ const { message, messages, isSending, lang, tone, length } = this.state;
146
168
  const flagCode = (_b = (_a = AI_LANG_FLAGS) == null ? void 0 : _a.find(
147
169
  (_item) => (_item == null ? void 0 : _item.value) === (lang == null ? void 0 : lang.value)
148
170
  )) == null ? void 0 : _b.flagCode;
@@ -168,65 +190,46 @@ class ChatAIDraft extends React.Component {
168
190
  getEditorContent
169
191
  }
170
192
  ) : /* @__PURE__ */ React.createElement(
171
- "div",
193
+ EmptyState,
172
194
  {
173
- style: {
174
- flex: 1,
175
- minHeight: 0,
176
- display: "flex",
177
- flexDirection: "column",
178
- alignItems: "center",
179
- justifyContent: "center",
180
- color: "var(--grey-light)"
181
- }
182
- },
183
- /* @__PURE__ */ React.createElement(CustomAiIcon, { size: 46 }),
184
- /* @__PURE__ */ React.createElement(
185
- "h2",
186
- {
187
- style: {
188
- marginTop: 16,
189
- fontWeight: 600,
190
- color: "inherit",
191
- fontSize: 18
192
- }
193
- },
194
- "Build with Agent"
195
- )
195
+ onSelectPrompt: (text) => this.setState({ message: text })
196
+ }
196
197
  ),
197
198
  /* @__PURE__ */ React.createElement(
198
199
  "div",
199
200
  {
200
201
  style: {
201
202
  width: "100%",
202
- border: "1px solid var(--border-main)",
203
- borderRadius: 4,
203
+ borderRadius: 12,
204
204
  overflow: "hidden",
205
- background: "#fff",
205
+ background: "var(--background-softGrey)",
206
206
  display: "flex",
207
- flexDirection: "column"
207
+ flexDirection: "column",
208
+ border: "1px solid var(--border-light)"
208
209
  }
209
210
  },
210
211
  /* @__PURE__ */ React.createElement(
211
212
  "textarea",
212
213
  {
214
+ ref: this.textareaRef,
213
215
  value: message,
214
216
  onChange: this.handleMessageChange,
215
- placeholder: "Describe your email",
217
+ placeholder: "Describe your email...",
216
218
  name: "ai-content",
217
219
  onKeyDown: this.handleKeyDown,
218
220
  disabled: isSending,
221
+ rows: 1,
219
222
  style: {
220
223
  flex: 1,
221
224
  minWidth: 0,
222
- borderRadius: 4,
223
225
  padding: 12,
224
226
  fontSize: 13,
225
227
  border: "none",
226
228
  resize: "none",
227
229
  outline: "none",
228
- minHeight: 60,
229
- fontFamily: "inherit"
230
+ fontFamily: "inherit",
231
+ background: "transparent",
232
+ overflowY: "auto"
230
233
  }
231
234
  }
232
235
  ),
@@ -247,9 +250,10 @@ class ChatAIDraft extends React.Component {
247
250
  {
248
251
  lang,
249
252
  setLang: this.setLang,
250
- originalEmail,
251
- setOriginalEmail: this.setOriginalEmail,
252
- getEditorContent,
253
+ tone,
254
+ setTone: this.setTone,
255
+ length,
256
+ setLength: this.setLength,
253
257
  parentRef: this.rootRef
254
258
  }
255
259
  ),
@@ -260,16 +264,60 @@ class ChatAIDraft extends React.Component {
260
264
  style: { marginLeft: 4, height: 14 }
261
265
  }
262
266
  ),
267
+ (tone || length) && /* @__PURE__ */ React.createElement(
268
+ "span",
269
+ {
270
+ style: {
271
+ marginLeft: 8,
272
+ padding: "2px 8px",
273
+ borderRadius: 999,
274
+ background: "var(--primary-lighter)",
275
+ color: "var(--primary-main)",
276
+ fontSize: 11,
277
+ fontWeight: 500,
278
+ whiteSpace: "nowrap",
279
+ display: "inline-flex",
280
+ alignItems: "center",
281
+ gap: 4
282
+ }
283
+ },
284
+ (tone == null ? void 0 : tone.label) && /* @__PURE__ */ React.createElement("span", null, tone.label),
285
+ (tone == null ? void 0 : tone.label) && (length == null ? void 0 : length.label) && /* @__PURE__ */ React.createElement(
286
+ "span",
287
+ {
288
+ style: {
289
+ width: 3,
290
+ height: 3,
291
+ borderRadius: "50%",
292
+ background: "currentColor",
293
+ display: "inline-block"
294
+ }
295
+ }
296
+ ),
297
+ (length == null ? void 0 : length.label) && /* @__PURE__ */ React.createElement("span", null, length.label)
298
+ ),
263
299
  /* @__PURE__ */ React.createElement(
264
300
  "button",
265
301
  {
302
+ type: "button",
266
303
  disabled: !message.trim() || isSending,
267
304
  onClick: this.handleSubmit,
268
- className: "icon-button",
269
- color: "primary",
270
- style: { marginLeft: "auto" }
305
+ style: {
306
+ marginLeft: "auto",
307
+ width: 28,
308
+ height: 28,
309
+ borderRadius: "50%",
310
+ border: "none",
311
+ display: "flex",
312
+ alignItems: "center",
313
+ justifyContent: "center",
314
+ background: !message.trim() || isSending ? "var(--primary-lighter)" : "var(--primary-main)",
315
+ color: "var(--primary-contrasttext)",
316
+ cursor: !message.trim() || isSending ? "not-allowed" : "pointer",
317
+ transition: "background 0.15s ease-in-out"
318
+ }
271
319
  },
272
- /* @__PURE__ */ React.createElement(Send, null)
320
+ /* @__PURE__ */ React.createElement(ArrowUp, { size: 18 })
273
321
  )
274
322
  )
275
323
  )
@@ -1,4 +1,4 @@
1
- export { default as ChatAIDraft, type ChatAIDraftRef } from './ChatAIDraft';
1
+ export { default as ChatAIDraft } from './ChatAIDraft';
2
2
  export { default as LoadingCircular } from './LoadingCircular';
3
3
  export { default as LoadingContainer } from './LoadingContainer';
4
4
  export { default as Tooltip } from './Tooltip';
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * hanbiro-react16-sdk v1.0.22
3
- * Build Date: 2026-04-03
2
+ * hanbiro-react16-sdk v1.0.24
3
+ * Build Date: 2026-05-21
4
4
  */
5
5
  @charset "UTF-8";
6
6
  button.icon-button {
@@ -163,6 +163,43 @@ button.icon-button.large svg {
163
163
  border-right: 6px solid var(--grey-darker);
164
164
  }
165
165
 
166
+ .chat-ai-lang-option {
167
+ background: transparent;
168
+ }
169
+ .chat-ai-lang-option:hover {
170
+ background: var(--background-softGrey);
171
+ }
172
+
173
+ .chat-ai-dots {
174
+ display: inline-flex;
175
+ align-items: center;
176
+ gap: 3px;
177
+ }
178
+ .chat-ai-dots > span {
179
+ width: 5px;
180
+ height: 5px;
181
+ border-radius: 50%;
182
+ background: var(--grey-main);
183
+ display: inline-block;
184
+ animation: chat-ai-dot-bounce 1.2s infinite ease-in-out both;
185
+ }
186
+ .chat-ai-dots > span:nth-child(1) {
187
+ animation-delay: -0.32s;
188
+ }
189
+ .chat-ai-dots > span:nth-child(2) {
190
+ animation-delay: -0.16s;
191
+ }
192
+
193
+ @keyframes chat-ai-dot-bounce {
194
+ 0%, 80%, 100% {
195
+ transform: scale(0.6);
196
+ opacity: 0.4;
197
+ }
198
+ 40% {
199
+ transform: scale(1);
200
+ opacity: 1;
201
+ }
202
+ }
166
203
  p {
167
204
  font-size: 13px;
168
205
  }