igniteui-webcomponents 6.3.0-beta.0 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/components/accordion/accordion.js +3 -4
  3. package/components/accordion/accordion.js.map +1 -1
  4. package/components/avatar/avatar.js +3 -4
  5. package/components/avatar/avatar.js.map +1 -1
  6. package/components/badge/badge.js +3 -4
  7. package/components/badge/badge.js.map +1 -1
  8. package/components/banner/banner.js +3 -4
  9. package/components/banner/banner.js.map +1 -1
  10. package/components/button/button-base.js +1 -1
  11. package/components/button/button-base.js.map +1 -1
  12. package/components/button/button.js +3 -4
  13. package/components/button/button.js.map +1 -1
  14. package/components/button/icon-button.js +3 -4
  15. package/components/button/icon-button.js.map +1 -1
  16. package/components/button-group/button-group.js +3 -4
  17. package/components/button-group/button-group.js.map +1 -1
  18. package/components/button-group/toggle-button.js +4 -3
  19. package/components/button-group/toggle-button.js.map +1 -1
  20. package/components/calendar/calendar.js +3 -4
  21. package/components/calendar/calendar.js.map +1 -1
  22. package/components/calendar/days-view/days-view.js +4 -3
  23. package/components/calendar/days-view/days-view.js.map +1 -1
  24. package/components/calendar/months-view/months-view.js +4 -3
  25. package/components/calendar/months-view/months-view.js.map +1 -1
  26. package/components/calendar/years-view/years-view.js +4 -3
  27. package/components/calendar/years-view/years-view.js.map +1 -1
  28. package/components/card/card.actions.js +3 -4
  29. package/components/card/card.actions.js.map +1 -1
  30. package/components/card/card.content.js +3 -4
  31. package/components/card/card.content.js.map +1 -1
  32. package/components/card/card.header.js +3 -4
  33. package/components/card/card.header.js.map +1 -1
  34. package/components/card/card.js +3 -4
  35. package/components/card/card.js.map +1 -1
  36. package/components/card/card.media.js +3 -4
  37. package/components/card/card.media.js.map +1 -1
  38. package/components/carousel/carousel-indicator-container.js +3 -4
  39. package/components/carousel/carousel-indicator-container.js.map +1 -1
  40. package/components/carousel/carousel-indicator.js +3 -4
  41. package/components/carousel/carousel-indicator.js.map +1 -1
  42. package/components/carousel/carousel-slide.js +3 -4
  43. package/components/carousel/carousel-slide.js.map +1 -1
  44. package/components/carousel/carousel.js +3 -4
  45. package/components/carousel/carousel.js.map +1 -1
  46. package/components/chat/chat-input.d.ts +8 -20
  47. package/components/chat/chat-input.js +78 -56
  48. package/components/chat/chat-input.js.map +1 -1
  49. package/components/chat/chat-message.d.ts +6 -21
  50. package/components/chat/chat-message.js +113 -71
  51. package/components/chat/chat-message.js.map +1 -1
  52. package/components/chat/chat-state.d.ts +45 -50
  53. package/components/chat/chat-state.js +82 -91
  54. package/components/chat/chat-state.js.map +1 -1
  55. package/components/chat/chat.d.ts +68 -24
  56. package/components/chat/chat.js +99 -96
  57. package/components/chat/chat.js.map +1 -1
  58. package/components/chat/extras/markdown-renderer.d.ts +6 -3
  59. package/components/chat/extras/markdown-renderer.js +19 -14
  60. package/components/chat/extras/markdown-renderer.js.map +1 -1
  61. package/components/chat/message-attachments.d.ts +5 -5
  62. package/components/chat/message-attachments.js +49 -43
  63. package/components/chat/message-attachments.js.map +1 -1
  64. package/components/chat/themes/chat.base.css.js +1 -1
  65. package/components/chat/themes/chat.base.css.js.map +1 -1
  66. package/components/chat/themes/dark/chat.bootstrap.css.js +1 -1
  67. package/components/chat/themes/dark/chat.bootstrap.css.js.map +1 -1
  68. package/components/chat/themes/dark/chat.fluent.css.js +1 -1
  69. package/components/chat/themes/dark/chat.fluent.css.js.map +1 -1
  70. package/components/chat/themes/dark/chat.indigo.css.js +1 -1
  71. package/components/chat/themes/dark/chat.indigo.css.js.map +1 -1
  72. package/components/chat/themes/dark/chat.material.css.js +1 -1
  73. package/components/chat/themes/dark/chat.material.css.js.map +1 -1
  74. package/components/chat/themes/input.base.css.js +1 -1
  75. package/components/chat/themes/input.base.css.js.map +1 -1
  76. package/components/chat/themes/light/chat.bootstrap.css.js +1 -1
  77. package/components/chat/themes/light/chat.bootstrap.css.js.map +1 -1
  78. package/components/chat/themes/light/chat.indigo.css.js +1 -1
  79. package/components/chat/themes/light/chat.indigo.css.js.map +1 -1
  80. package/components/chat/themes/light/chat.shared.css.js +1 -1
  81. package/components/chat/themes/light/chat.shared.css.js.map +1 -1
  82. package/components/chat/themes/message-attachments.base.css.js +1 -1
  83. package/components/chat/themes/message-attachments.base.css.js.map +1 -1
  84. package/components/chat/themes/message.base.css.js +1 -1
  85. package/components/chat/themes/message.base.css.js.map +1 -1
  86. package/components/chat/themes/shared/chat.bootstrap.css.js +1 -1
  87. package/components/chat/themes/shared/chat.bootstrap.css.js.map +1 -1
  88. package/components/chat/themes/shared/chat.fluent.css.js +1 -1
  89. package/components/chat/themes/shared/chat.fluent.css.js.map +1 -1
  90. package/components/chat/themes/shared/chat.indigo.css.js +1 -1
  91. package/components/chat/themes/shared/chat.indigo.css.js.map +1 -1
  92. package/components/chat/themes/shared/input/input.bootstrap.css.js +1 -1
  93. package/components/chat/themes/shared/input/input.bootstrap.css.js.map +1 -1
  94. package/components/chat/themes/shared/input/input.fluent.css.js +1 -1
  95. package/components/chat/themes/shared/input/input.fluent.css.js.map +1 -1
  96. package/components/chat/themes/shared/input/input.indigo.css.js +1 -1
  97. package/components/chat/themes/shared/input/input.indigo.css.js.map +1 -1
  98. package/components/chat/themes/shared/message-attachments/message-attachments.common.css.js +1 -1
  99. package/components/chat/themes/shared/message-attachments/message-attachments.common.css.js.map +1 -1
  100. package/components/chat/types.d.ts +173 -28
  101. package/components/chat/types.js.map +1 -1
  102. package/components/chat/utils.d.ts +3 -3
  103. package/components/chat/utils.js +7 -11
  104. package/components/chat/utils.js.map +1 -1
  105. package/components/checkbox/checkbox.js +3 -4
  106. package/components/checkbox/checkbox.js.map +1 -1
  107. package/components/checkbox/switch.js +3 -4
  108. package/components/checkbox/switch.js.map +1 -1
  109. package/components/checkbox/themes/checkbox.base.css.js +1 -1
  110. package/components/checkbox/themes/checkbox.base.css.js.map +1 -1
  111. package/components/checkbox/themes/switch.base.css.js +1 -1
  112. package/components/checkbox/themes/switch.base.css.js.map +1 -1
  113. package/components/chip/chip.js +3 -4
  114. package/components/chip/chip.js.map +1 -1
  115. package/components/combo/combo-header.js +3 -4
  116. package/components/combo/combo-header.js.map +1 -1
  117. package/components/combo/combo-item.js +3 -4
  118. package/components/combo/combo-item.js.map +1 -1
  119. package/components/combo/combo-list.js +2 -3
  120. package/components/combo/combo-list.js.map +1 -1
  121. package/components/combo/combo.js +4 -3
  122. package/components/combo/combo.js.map +1 -1
  123. package/components/common/controllers/focus-ring.js +5 -5
  124. package/components/common/controllers/focus-ring.js.map +1 -1
  125. package/components/common/controllers/key-bindings.js +4 -4
  126. package/components/common/controllers/key-bindings.js.map +1 -1
  127. package/components/common/i18n/chat.resources.d.ts +3 -0
  128. package/components/common/i18n/chat.resources.js +3 -0
  129. package/components/common/i18n/chat.resources.js.map +1 -1
  130. package/components/common/mixins/forms/associated.js +1 -1
  131. package/components/common/mixins/forms/associated.js.map +1 -1
  132. package/components/common/mixins/forms/form-value.js +1 -1
  133. package/components/common/mixins/forms/form-value.js.map +1 -1
  134. package/components/common/part-map.d.ts +1 -1
  135. package/components/common/util.d.ts +3 -0
  136. package/components/common/util.js +9 -1
  137. package/components/common/util.js.map +1 -1
  138. package/components/date-picker/date-picker.js +5 -4
  139. package/components/date-picker/date-picker.js.map +1 -1
  140. package/components/date-range-picker/date-range-picker.js +5 -4
  141. package/components/date-range-picker/date-range-picker.js.map +1 -1
  142. package/components/date-range-picker/predefined-ranges-area.js +3 -4
  143. package/components/date-range-picker/predefined-ranges-area.js.map +1 -1
  144. package/components/date-time-input/date-time-input.js +2 -3
  145. package/components/date-time-input/date-time-input.js.map +1 -1
  146. package/components/date-time-input/date-util.js +11 -11
  147. package/components/date-time-input/date-util.js.map +1 -1
  148. package/components/dialog/dialog.js +3 -4
  149. package/components/dialog/dialog.js.map +1 -1
  150. package/components/divider/divider.js +3 -4
  151. package/components/divider/divider.js.map +1 -1
  152. package/components/dropdown/dropdown-group.js +3 -4
  153. package/components/dropdown/dropdown-group.js.map +1 -1
  154. package/components/dropdown/dropdown-header.js +3 -4
  155. package/components/dropdown/dropdown-header.js.map +1 -1
  156. package/components/dropdown/dropdown-item.js +3 -4
  157. package/components/dropdown/dropdown-item.js.map +1 -1
  158. package/components/dropdown/dropdown.js +4 -3
  159. package/components/dropdown/dropdown.js.map +1 -1
  160. package/components/expansion-panel/expansion-panel.js +3 -4
  161. package/components/expansion-panel/expansion-panel.js.map +1 -1
  162. package/components/file-input/file-input.js +3 -4
  163. package/components/file-input/file-input.js.map +1 -1
  164. package/components/focus-trap/focus-trap.js +7 -8
  165. package/components/focus-trap/focus-trap.js.map +1 -1
  166. package/components/icon/icon-references.js +78 -0
  167. package/components/icon/icon-references.js.map +1 -1
  168. package/components/icon/icon-state.broadcast.js +1 -1
  169. package/components/icon/icon-state.broadcast.js.map +1 -1
  170. package/components/icon/icon.js +3 -4
  171. package/components/icon/icon.js.map +1 -1
  172. package/components/icon/internal-icons-lib.js +39 -0
  173. package/components/icon/internal-icons-lib.js.map +1 -1
  174. package/components/input/input-base.js +4 -3
  175. package/components/input/input-base.js.map +1 -1
  176. package/components/input/input.js +2 -3
  177. package/components/input/input.js.map +1 -1
  178. package/components/input/themes/shared/input.bootstrap.css.js +1 -1
  179. package/components/input/themes/shared/input.bootstrap.css.js.map +1 -1
  180. package/components/input/themes/shared/input.indigo.css.js +1 -1
  181. package/components/input/themes/shared/input.indigo.css.js.map +1 -1
  182. package/components/list/list-header.js +3 -4
  183. package/components/list/list-header.js.map +1 -1
  184. package/components/list/list-item.js +3 -4
  185. package/components/list/list-item.js.map +1 -1
  186. package/components/list/list.js +3 -4
  187. package/components/list/list.js.map +1 -1
  188. package/components/list/themes/header.js +2 -28
  189. package/components/list/themes/header.js.map +1 -1
  190. package/components/list/themes/item.js +6 -20
  191. package/components/list/themes/item.js.map +1 -1
  192. package/components/mask-input/mask-input.js +2 -3
  193. package/components/mask-input/mask-input.js.map +1 -1
  194. package/components/nav-drawer/nav-drawer-header-item.js +3 -4
  195. package/components/nav-drawer/nav-drawer-header-item.js.map +1 -1
  196. package/components/nav-drawer/nav-drawer-item.js +3 -4
  197. package/components/nav-drawer/nav-drawer-item.js.map +1 -1
  198. package/components/nav-drawer/nav-drawer.js +3 -4
  199. package/components/nav-drawer/nav-drawer.js.map +1 -1
  200. package/components/navbar/navbar.js +3 -4
  201. package/components/navbar/navbar.js.map +1 -1
  202. package/components/popover/popover.js +9 -10
  203. package/components/popover/popover.js.map +1 -1
  204. package/components/progress/circular-gradient.js +2 -3
  205. package/components/progress/circular-gradient.js.map +1 -1
  206. package/components/progress/circular-progress.js +3 -4
  207. package/components/progress/circular-progress.js.map +1 -1
  208. package/components/progress/linear-progress.js +3 -4
  209. package/components/progress/linear-progress.js.map +1 -1
  210. package/components/radio/radio.js +3 -4
  211. package/components/radio/radio.js.map +1 -1
  212. package/components/radio-group/radio-group.js +3 -4
  213. package/components/radio-group/radio-group.js.map +1 -1
  214. package/components/rating/rating-symbol.js +3 -4
  215. package/components/rating/rating-symbol.js.map +1 -1
  216. package/components/rating/rating.js +3 -4
  217. package/components/rating/rating.js.map +1 -1
  218. package/components/resize-container/resize-container.js +3 -4
  219. package/components/resize-container/resize-container.js.map +1 -1
  220. package/components/ripple/ripple.js +3 -4
  221. package/components/ripple/ripple.js.map +1 -1
  222. package/components/select/select-group.js +3 -4
  223. package/components/select/select-group.js.map +1 -1
  224. package/components/select/select-header.js +3 -4
  225. package/components/select/select-header.js.map +1 -1
  226. package/components/select/select-item.js +3 -4
  227. package/components/select/select-item.js.map +1 -1
  228. package/components/select/select.js +4 -3
  229. package/components/select/select.js.map +1 -1
  230. package/components/slider/range-slider.js +2 -3
  231. package/components/slider/range-slider.js.map +1 -1
  232. package/components/slider/slider-base.js +1 -1
  233. package/components/slider/slider-base.js.map +1 -1
  234. package/components/slider/slider-label.js +7 -8
  235. package/components/slider/slider-label.js.map +1 -1
  236. package/components/slider/slider.js +2 -3
  237. package/components/slider/slider.js.map +1 -1
  238. package/components/snackbar/snackbar.js +3 -4
  239. package/components/snackbar/snackbar.js.map +1 -1
  240. package/components/stepper/step.js +3 -4
  241. package/components/stepper/step.js.map +1 -1
  242. package/components/stepper/stepper.js +3 -4
  243. package/components/stepper/stepper.js.map +1 -1
  244. package/components/tabs/tab-dom.js +1 -1
  245. package/components/tabs/tab-dom.js.map +1 -1
  246. package/components/tabs/tab.js +4 -5
  247. package/components/tabs/tab.js.map +1 -1
  248. package/components/tabs/tabs.js +3 -4
  249. package/components/tabs/tabs.js.map +1 -1
  250. package/components/textarea/textarea.js +4 -3
  251. package/components/textarea/textarea.js.map +1 -1
  252. package/components/textarea/themes/shared/textarea.bootstrap.css.js +1 -1
  253. package/components/textarea/themes/shared/textarea.bootstrap.css.js.map +1 -1
  254. package/components/tile-manager/themes/tile-manager.base.css.js +1 -1
  255. package/components/tile-manager/themes/tile-manager.base.css.js.map +1 -1
  256. package/components/tile-manager/tile-manager.js +4 -3
  257. package/components/tile-manager/tile-manager.js.map +1 -1
  258. package/components/tile-manager/tile.js +3 -4
  259. package/components/tile-manager/tile.js.map +1 -1
  260. package/components/toast/toast.js +3 -4
  261. package/components/toast/toast.js.map +1 -1
  262. package/components/tooltip/controller.js +4 -4
  263. package/components/tooltip/controller.js.map +1 -1
  264. package/components/tooltip/tooltip.js +3 -4
  265. package/components/tooltip/tooltip.js.map +1 -1
  266. package/components/tree/tree-item.js +3 -4
  267. package/components/tree/tree-item.js.map +1 -1
  268. package/components/tree/tree.js +4 -3
  269. package/components/tree/tree.js.map +1 -1
  270. package/components/validation-container/validation-container.js +3 -4
  271. package/components/validation-container/validation-container.js.map +1 -1
  272. package/custom-elements.json +2142 -2029
  273. package/igniteui-webcomponents.css-data.json +1 -1
  274. package/igniteui-webcomponents.html-data.json +1 -1
  275. package/package.json +24 -2
  276. package/web-types.json +2 -2
  277. package/components/list/themes/dark/header/list-header.bootstrap.css.d.ts +0 -1
  278. package/components/list/themes/dark/header/list-header.bootstrap.css.js +0 -3
  279. package/components/list/themes/dark/header/list-header.bootstrap.css.js.map +0 -1
  280. package/components/list/themes/dark/header/list-header.fluent.css.d.ts +0 -1
  281. package/components/list/themes/dark/header/list-header.fluent.css.js +0 -3
  282. package/components/list/themes/dark/header/list-header.fluent.css.js.map +0 -1
  283. package/components/list/themes/dark/header/list-header.indigo.css.d.ts +0 -1
  284. package/components/list/themes/dark/header/list-header.indigo.css.js +0 -3
  285. package/components/list/themes/dark/header/list-header.indigo.css.js.map +0 -1
  286. package/components/list/themes/dark/header/list-header.material.css.d.ts +0 -1
  287. package/components/list/themes/dark/header/list-header.material.css.js +0 -3
  288. package/components/list/themes/dark/header/list-header.material.css.js.map +0 -1
  289. package/components/list/themes/dark/item/list-item.bootstrap.css.d.ts +0 -1
  290. package/components/list/themes/dark/item/list-item.bootstrap.css.js +0 -3
  291. package/components/list/themes/dark/item/list-item.bootstrap.css.js.map +0 -1
  292. package/components/list/themes/dark/item/list-item.fluent.css.d.ts +0 -1
  293. package/components/list/themes/dark/item/list-item.fluent.css.js +0 -3
  294. package/components/list/themes/dark/item/list-item.fluent.css.js.map +0 -1
  295. package/components/list/themes/dark/item/list-item.indigo.css.d.ts +0 -1
  296. package/components/list/themes/dark/item/list-item.indigo.css.js +0 -3
  297. package/components/list/themes/dark/item/list-item.indigo.css.js.map +0 -1
  298. package/components/list/themes/dark/item/list-item.material.css.d.ts +0 -1
  299. package/components/list/themes/dark/item/list-item.material.css.js +0 -3
  300. package/components/list/themes/dark/item/list-item.material.css.js.map +0 -1
  301. package/components/list/themes/light/header/list-header.bootstrap.css.d.ts +0 -1
  302. package/components/list/themes/light/header/list-header.bootstrap.css.js +0 -3
  303. package/components/list/themes/light/header/list-header.bootstrap.css.js.map +0 -1
  304. package/components/list/themes/light/header/list-header.fluent.css.d.ts +0 -1
  305. package/components/list/themes/light/header/list-header.fluent.css.js +0 -3
  306. package/components/list/themes/light/header/list-header.fluent.css.js.map +0 -1
  307. package/components/list/themes/light/header/list-header.indigo.css.d.ts +0 -1
  308. package/components/list/themes/light/header/list-header.indigo.css.js +0 -3
  309. package/components/list/themes/light/header/list-header.indigo.css.js.map +0 -1
  310. package/components/list/themes/light/header/list-header.material.css.d.ts +0 -1
  311. package/components/list/themes/light/header/list-header.material.css.js +0 -3
  312. package/components/list/themes/light/header/list-header.material.css.js.map +0 -1
  313. package/components/list/themes/light/item/list-item.bootstrap.css.d.ts +0 -1
  314. package/components/list/themes/light/item/list-item.bootstrap.css.js +0 -3
  315. package/components/list/themes/light/item/list-item.bootstrap.css.js.map +0 -1
  316. package/components/list/themes/light/item/list-item.fluent.css.d.ts +0 -1
  317. package/components/list/themes/light/item/list-item.fluent.css.js +0 -3
  318. package/components/list/themes/light/item/list-item.fluent.css.js.map +0 -1
  319. package/components/list/themes/light/item/list-item.indigo.css.d.ts +0 -1
  320. package/components/list/themes/light/item/list-item.indigo.css.js +0 -3
  321. package/components/list/themes/light/item/list-item.indigo.css.js.map +0 -1
  322. package/components/list/themes/light/item/list-item.material.css.d.ts +0 -1
  323. package/components/list/themes/light/item/list-item.material.css.js +0 -3
  324. package/components/list/themes/light/item/list-item.material.css.js.map +0 -1
@@ -1,8 +1,12 @@
1
- import { enterKey } from '../common/controllers/key-bindings.js';
2
1
  import { IgcChatResourceStringEN } from '../common/i18n/chat.resources.js';
3
2
  import { isEmpty, nanoid } from '../common/util.js';
4
- import { parseAcceptedFileTypes } from './utils.js';
3
+ import IgcToastComponent from '../toast/toast.js';
4
+ import IgcTooltipComponent from '../tooltip/tooltip.js';
5
+ import { isImageAttachment, parseAcceptedFileTypes, } from './utils.js';
5
6
  export class ChatState {
7
+ get host() {
8
+ return this._host;
9
+ }
6
10
  get acceptedFileTypes() {
7
11
  return this._acceptedTypesCache;
8
12
  }
@@ -20,22 +24,17 @@ export class ChatState {
20
24
  }
21
25
  set options(value) {
22
26
  this._options = value;
27
+ this._setAcceptedTypesCache();
23
28
  this._contextUpdateFn.call(this._host);
24
29
  }
25
30
  get currentUserId() {
26
31
  return this._options?.currentUserId ?? 'user';
27
32
  }
28
33
  get suggestionsPosition() {
29
- return this._options?.suggestionsPosition ?? this._suggestionsPosition;
34
+ return this._options?.suggestionsPosition ?? 'below-messages';
30
35
  }
31
36
  get stopTypingDelay() {
32
- return this._options?.stopTypingDelay ?? this._stopTypingDelay;
33
- }
34
- get textArea() {
35
- return this._textArea;
36
- }
37
- set textArea(value) {
38
- this._textArea = value;
37
+ return this._options?.stopTypingDelay ?? 3000;
39
38
  }
40
39
  get inputAttachments() {
41
40
  return this._inputAttachments;
@@ -52,35 +51,26 @@ export class ChatState {
52
51
  this._userInputContextUpdateFn.call(this._host);
53
52
  }
54
53
  get hasInputValue() {
55
- return this._inputValue.trim() !== '';
54
+ return !!this._inputValue.trim();
56
55
  }
57
56
  get hasInputAttachments() {
58
57
  return !isEmpty(this._inputAttachments);
59
58
  }
60
59
  constructor(chat, contextUpdateFn, userInputContextUpdateFn) {
61
- this._textArea = null;
62
60
  this._messages = [];
63
61
  this._inputAttachments = [];
64
62
  this._inputValue = '';
65
63
  this._acceptedTypesCache = null;
66
- this._suggestionsPosition = 'below-messages';
67
- this._stopTypingDelay = 3000;
68
64
  this._isTyping = false;
69
65
  this._lastTyped = Date.now();
70
66
  this.resourceStrings = IgcChatResourceStringEN;
71
- this.handleKeyDown = (e) => {
72
- if (e.key.toLowerCase() === enterKey.toLowerCase() && !e.shiftKey) {
73
- e.preventDefault();
74
- this.sendMessage();
75
- }
76
- else {
77
- this._lastTyped = Date.now();
78
- if (!this._isTyping) {
79
- this.emitEvent('igcTypingChange', {
80
- detail: { isTyping: true },
81
- });
82
- this._isTyping = true;
83
- }
67
+ this.handleKeyDown = (_) => {
68
+ this._lastTyped = Date.now();
69
+ if (!this._isTyping) {
70
+ this.emitEvent('igcTypingChange', {
71
+ detail: { isTyping: true },
72
+ });
73
+ this._isTyping = true;
84
74
  const stopTypingDelay = this.stopTypingDelay;
85
75
  setTimeout(() => {
86
76
  if (this._isTyping &&
@@ -94,36 +84,6 @@ export class ChatState {
94
84
  }, stopTypingDelay);
95
85
  }
96
86
  };
97
- this.sendMessage = () => {
98
- if (!this.inputValue.trim() && this.inputAttachments.length === 0)
99
- return;
100
- this.addMessage({
101
- text: this.inputValue,
102
- attachments: this.inputAttachments,
103
- });
104
- this.inputValue = '';
105
- if (this._textArea) {
106
- this._textArea.style.height = 'auto';
107
- }
108
- this._host.updateComplete.then(() => {
109
- this._textArea?.focus();
110
- });
111
- };
112
- this.removeAttachment = (index) => {
113
- const allowed = this.emitEvent('igcAttachmentChange', {
114
- detail: this.inputAttachments.filter((_, i) => i !== index),
115
- cancelable: true,
116
- });
117
- if (allowed) {
118
- this.inputAttachments = this.inputAttachments.filter((_, i) => i !== index);
119
- }
120
- };
121
- this.handleSuggestionClick = (suggestion) => {
122
- this.addMessage({ text: suggestion });
123
- if (this.textArea) {
124
- this.textArea.focus();
125
- }
126
- };
127
87
  this._host = chat;
128
88
  this._contextUpdateFn = contextUpdateFn;
129
89
  this._userInputContextUpdateFn = userInputContextUpdateFn;
@@ -134,63 +94,94 @@ export class ChatState {
134
94
  emitEvent(name, args) {
135
95
  return this._host.emitEvent(name, args);
136
96
  }
137
- addMessage(message) {
138
- const newMessage = {
97
+ emitMessageCreated(message) {
98
+ return this._host.emitEvent('igcMessageCreated', {
99
+ detail: message,
100
+ cancelable: true,
101
+ });
102
+ }
103
+ emitAttachmentsAdded(attachments) {
104
+ return this._host.emitEvent('igcAttachmentAdded', {
105
+ detail: attachments,
106
+ cancelable: true,
107
+ });
108
+ }
109
+ emitAttachmentRemoved(attachment) {
110
+ return this._host.emitEvent('igcAttachmentRemoved', {
111
+ detail: attachment,
112
+ cancelable: true,
113
+ });
114
+ }
115
+ emitMessageReaction(reaction) {
116
+ return this._host.emitEvent('igcMessageReact', { detail: reaction });
117
+ }
118
+ showActionsTooltip(target, message) {
119
+ if (!this._actionsTooltip) {
120
+ this._actionsTooltip = document.createElement(IgcTooltipComponent.tagName);
121
+ this._actionsTooltip.hideTriggers = 'pointerleave,click,blur';
122
+ this._actionsTooltip.hideDelay = 100;
123
+ this._host.renderRoot.appendChild(this._actionsTooltip);
124
+ }
125
+ this._actionsTooltip.message = message;
126
+ this._actionsTooltip.show(target);
127
+ }
128
+ showActionToast(content) {
129
+ if (!this._actionToast) {
130
+ this._actionToast = document.createElement(IgcToastComponent.tagName);
131
+ this._actionToast.displayTime = 3000;
132
+ this._host.renderRoot.appendChild(this._actionToast);
133
+ }
134
+ this._actionToast.textContent = content;
135
+ this._actionToast.show();
136
+ }
137
+ _setAcceptedTypesCache() {
138
+ this._acceptedTypesCache = this.options?.acceptedFiles
139
+ ? parseAcceptedFileTypes(this.options.acceptedFiles)
140
+ : null;
141
+ }
142
+ _createMessage(message) {
143
+ return {
139
144
  id: message.id ?? nanoid(),
140
145
  text: message.text ?? '',
141
146
  sender: message.sender ?? this.currentUserId,
142
- timestamp: message.timestamp ?? new Date(),
147
+ timestamp: message.timestamp ?? Date.now().toString(),
143
148
  attachments: message.attachments || [],
144
149
  };
145
- const allowed = this.emitEvent('igcMessageCreated', {
146
- detail: newMessage,
147
- cancelable: true,
148
- });
149
- if (allowed) {
150
- if (!this.messages.some((msg) => msg.id === newMessage.id)) {
151
- this.messages = [...this.messages, newMessage];
152
- }
153
- this._host.requestUpdate('messages');
150
+ }
151
+ addMessage(message) {
152
+ this.messages.push(this._createMessage(message));
153
+ this._host.requestUpdate('messages');
154
+ }
155
+ addMessageWithEvent(message) {
156
+ const newMessage = this._createMessage(message);
157
+ if (this.emitMessageCreated(newMessage)) {
158
+ this.addMessage(newMessage);
154
159
  this.inputValue = '';
155
160
  this.inputAttachments = [];
156
161
  }
157
162
  }
158
- attachFiles(files) {
163
+ attachFilesWithEvent(files) {
159
164
  const newAttachments = [];
160
165
  const fileNames = new Set(this.inputAttachments.map((attachment) => attachment.file?.name ?? ''));
161
166
  for (const file of files) {
162
167
  if (fileNames.has(file.name)) {
163
168
  continue;
164
169
  }
165
- const isImage = file.type.startsWith('image/');
166
170
  const url = URL.createObjectURL(file);
167
- newAttachments.push({
171
+ const attachment = {
168
172
  id: nanoid(),
169
173
  url,
170
174
  name: file.name,
171
175
  file,
172
- thumbnail: isImage ? url : undefined,
173
- });
176
+ };
177
+ if (isImageAttachment(file)) {
178
+ attachment.thumbnail = url;
179
+ }
180
+ newAttachments.push(attachment);
174
181
  }
175
- const allowed = this.emitEvent('igcAttachmentChange', {
176
- detail: [...this.inputAttachments, ...newAttachments],
177
- cancelable: true,
178
- });
179
- if (allowed) {
182
+ if (this.emitAttachmentsAdded(newAttachments)) {
180
183
  this.inputAttachments = [...this.inputAttachments, ...newAttachments];
181
184
  }
182
185
  }
183
- isImageAttachment(attachment) {
184
- return (attachment.type === 'image' ||
185
- !!attachment.file?.type.startsWith('image/'));
186
- }
187
- updateOptions(options) {
188
- this.options = { ...this.options, ...options };
189
- }
190
- updateAcceptedTypesCache() {
191
- this._acceptedTypesCache = this.options?.acceptedFiles
192
- ? parseAcceptedFileTypes(this.options.acceptedFiles)
193
- : null;
194
- }
195
186
  }
196
187
  //# sourceMappingURL=chat-state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-state.js","sourceRoot":"","sources":["../../../src/components/chat/chat-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AASpD,OAAO,EAA8B,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAOhF,MAAM,OAAO,SAAS;IAqCpB,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;IAED,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,QAAQ,EAAE,iBAAiB,IAAI,KAAK,CAAC;IACnD,CAAC;IAKD,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAKD,IAAW,QAAQ,CAAC,KAAmB;QACrC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAKD,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAKD,IAAW,OAAO,CAAC,KAAqB;QACtC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAKD,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,QAAQ,EAAE,aAAa,IAAI,MAAM,CAAC;IAChD,CAAC;IAKD,IAAW,mBAAmB;QAC5B,OAAO,IAAI,CAAC,QAAQ,EAAE,mBAAmB,IAAI,IAAI,CAAC,oBAAoB,CAAC;IACzE,CAAC;IAKD,IAAW,eAAe;QACxB,OAAO,IAAI,CAAC,QAAQ,EAAE,eAAe,IAAI,IAAI,CAAC,gBAAgB,CAAC;IACjE,CAAC;IAKD,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAKD,IAAW,QAAQ,CAAC,KAA2B;QAC7C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAKD,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAKD,IAAW,gBAAgB,CAAC,KAA6B;QACvD,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAKD,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAKD,IAAW,UAAU,CAAC,KAAa;QACjC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED,IAAW,mBAAmB;QAC5B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC1C,CAAC;IAID,YACE,IAAsB,EACtB,eAA8B,EAC9B,wBAAuC;QAhJjC,cAAS,GAAgC,IAAI,CAAC;QAE9C,cAAS,GAAiB,EAAE,CAAC;QAK7B,sBAAiB,GAA2B,EAAE,CAAC;QAE/C,gBAAW,GAAG,EAAE,CAAC;QAIjB,wBAAmB,GAAiC,IAAI,CAAC;QAEzD,yBAAoB,GAC1B,gBAAgB,CAAC;QAEX,qBAAgB,GAAG,IAAI,CAAC;QAEzB,cAAS,GAAG,KAAK,CAAC;QACjB,eAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,oBAAe,GAAG,uBAAuB,CAAC;QAyN1C,kBAAa,GAAG,CAAC,CAAgB,EAAE,EAAE;YAC1C,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAClE,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE;wBAChC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;qBAC3B,CAAC,CAAC;oBACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACxB,CAAC;gBAED,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;gBAC7C,UAAU,CAAC,GAAG,EAAE;oBACd,IACE,IAAI,CAAC,SAAS;wBACd,eAAe;wBACf,IAAI,CAAC,UAAU,GAAG,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,EAC9C,CAAC;wBACD,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE;4BAChC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;yBAC5B,CAAC,CAAC;wBACH,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;oBACzB,CAAC;gBACH,CAAC,EAAE,eAAe,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC;QAEK,gBAAW,GAAG,GAAG,EAAE;YACxB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAE1E,IAAI,CAAC,UAAU,CAAC;gBACd,IAAI,EAAE,IAAI,CAAC,UAAU;gBACrB,WAAW,EAAE,IAAI,CAAC,gBAAgB;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;YAErB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;YACvC,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE;gBAClC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAOK,qBAAgB,GAAG,CAAC,KAAa,EAAQ,EAAE;YAChD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE;gBACpD,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC;gBAC3D,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;YACH,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAClD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CACtB,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;QAOK,0BAAqB,GAAG,CAAC,UAAkB,EAAQ,EAAE;YAC1D,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YACtC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;QACH,CAAC,CAAC;QAxKA,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;QACxC,IAAI,CAAC,yBAAyB,GAAG,wBAAwB,CAAC;IAC5D,CAAC;IAEM,oBAAoB,CAAC,OAAoB;QAC9C,OAAO,IAAI,CAAC,aAAa,KAAK,OAAO,EAAE,MAAM,CAAC;IAChD,CAAC;IAIM,SAAS,CAAC,IAAoC,EAAE,IAAU;QAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IAYM,UAAU,CAAC,OAA4B;QAC5C,MAAM,UAAU,GAAe;YAC7B,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,MAAM,EAAE;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa;YAC5C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE;YAC1C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;SACvC,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE;YAClD,MAAM,EAAE,UAAU;YAClB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QAEH,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC3D,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACjD,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YAErC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC;IAOM,WAAW,CAAC,KAAa;QAC9B,MAAM,cAAc,GAA2B,EAAE,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CACvE,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,SAAS;YACX,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAEtC,cAAc,CAAC,IAAI,CAAC;gBAClB,EAAE,EAAE,MAAM,EAAE;gBACZ,GAAG;gBACH,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI;gBACJ,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;aACrC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE;YACpD,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,cAAc,CAAC;YACrD,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QACH,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,cAAc,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAEM,iBAAiB,CAAC,UAAgC;QACvD,OAAO,CACL,UAAU,CAAC,IAAI,KAAK,OAAO;YAC3B,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAC7C,CAAC;IACJ,CAAC;IAkFM,aAAa,CAAC,OAAgC;QACnD,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IACjD,CAAC;IAMM,wBAAwB;QAC7B,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa;YACpD,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;YACpD,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;CAGF","sourcesContent":["import { enterKey } from '../common/controllers/key-bindings.js';\nimport { IgcChatResourceStringEN } from '../common/i18n/chat.resources.js';\nimport { isEmpty, nanoid } from '../common/util.js';\nimport type IgcTextareaComponent from '../textarea/textarea.js';\nimport type IgcChatComponent from './chat.js';\nimport type { IgcChatComponentEventMap } from './chat.js';\nimport type {\n IgcChatOptions,\n IgcMessage,\n IgcMessageAttachment,\n} from './types.js';\nimport { type ChatAcceptedFileTypes, parseAcceptedFileTypes } from './utils.js';\n\n/**\n * Internal state manager for the `<igc-chat>` component.\n *\n * Manages messages, input value, attachments, options, and event emissions.\n */\nexport class ChatState {\n //#region Internal properties and state /** The host `<igc-chat>` component instance */\n private readonly _host: IgcChatComponent;\n\n private readonly _contextUpdateFn: () => unknown;\n private readonly _userInputContextUpdateFn: () => unknown;\n\n /** Reference to the text area input component */\n private _textArea: IgcTextareaComponent | null = null;\n /** The current list of messages */\n private _messages: IgcMessage[] = [];\n /** Chat options/configuration */\n private _options?: IgcChatOptions;\n\n /** List of current input attachments */\n private _inputAttachments: IgcMessageAttachment[] = [];\n /** Current input text */\n private _inputValue = '';\n /**\n * Cache of accepted file types, organized into extensions, mimeTypes, and wildcardTypes\n */\n private _acceptedTypesCache: ChatAcceptedFileTypes | null = null;\n /** Default position of the suggestions */\n private _suggestionsPosition: 'below-input' | 'below-messages' =\n 'below-messages';\n /** Default time in milliseconds before dispatching stop typing event */\n private _stopTypingDelay = 3000;\n\n public _isTyping = false;\n private _lastTyped = Date.now();\n\n public resourceStrings = IgcChatResourceStringEN;\n\n //#endregion\n\n //#region Public properties\n\n public get acceptedFileTypes() {\n return this._acceptedTypesCache;\n }\n\n public get disableAutoScroll(): boolean {\n return this._options?.disableAutoScroll ?? false;\n }\n\n /**\n * Gets the list of chat messages.\n */\n public get messages(): IgcMessage[] {\n return this._messages;\n }\n\n /**\n * Sets the list of chat messages.\n */\n public set messages(value: IgcMessage[]) {\n this._messages = value;\n }\n\n /**\n * Gets current chat options.\n */\n public get options(): IgcChatOptions | undefined {\n return this._options;\n }\n\n /**\n * Sets chat options and requests host update.\n */\n public set options(value: IgcChatOptions) {\n this._options = value;\n this._contextUpdateFn.call(this._host);\n }\n\n /**\n * Gets the current user ID from options or returns 'user' as fallback.\n */\n public get currentUserId(): string {\n return this._options?.currentUserId ?? 'user';\n }\n\n /**\n * Gets the current suggestionsPosition from options or returns the default value 'below-messages'.\n */\n public get suggestionsPosition(): string {\n return this._options?.suggestionsPosition ?? this._suggestionsPosition;\n }\n\n /**\n * Gets the current stopTypingDelay from options or returns the default value `3000`.\n */\n public get stopTypingDelay(): number {\n return this._options?.stopTypingDelay ?? this._stopTypingDelay;\n }\n\n /**\n * Gets the text area component.\n */\n public get textArea(): IgcTextareaComponent | null {\n return this._textArea;\n }\n\n /**\n * Sets the text area component.\n */\n public set textArea(value: IgcTextareaComponent) {\n this._textArea = value;\n }\n\n /**\n * Gets the list of attachments currently attached to input.\n */\n public get inputAttachments(): IgcMessageAttachment[] {\n return this._inputAttachments;\n }\n\n /**\n * Sets the input attachments and requests host update.\n */\n public set inputAttachments(value: IgcMessageAttachment[]) {\n this._inputAttachments = value;\n this._userInputContextUpdateFn.call(this._host);\n }\n\n /**\n * Gets the current input value.\n */\n public get inputValue(): string {\n return this._inputValue;\n }\n\n /**\n * Sets the current input value and requests host update.\n */\n public set inputValue(value: string) {\n this._inputValue = value;\n this._userInputContextUpdateFn.call(this._host);\n }\n\n public get hasInputValue(): boolean {\n return this._inputValue.trim() !== '';\n }\n\n public get hasInputAttachments(): boolean {\n return !isEmpty(this._inputAttachments);\n }\n\n //#endregion\n\n constructor(\n chat: IgcChatComponent,\n contextUpdateFn: () => unknown,\n userInputContextUpdateFn: () => unknown\n ) {\n this._host = chat;\n this._contextUpdateFn = contextUpdateFn;\n this._userInputContextUpdateFn = userInputContextUpdateFn;\n }\n\n public isCurrentUserMessage(message?: IgcMessage): boolean {\n return this.currentUserId === message?.sender;\n }\n\n //#region Event handlers\n\n public emitEvent(name: keyof IgcChatComponentEventMap, args?: any): boolean {\n return this._host.emitEvent(name, args);\n }\n\n //#endregion\n\n //#region Public API\n\n /**\n * Adds a new chat message.\n * Emits 'igcMessageCreated' event which can be canceled to prevent adding.\n * Clears input value and attachments on success.\n * @param message Partial message object with optional id, sender, timestamp\n */\n public addMessage(message: Partial<IgcMessage>): void {\n const newMessage: IgcMessage = {\n id: message.id ?? nanoid(),\n text: message.text ?? '',\n sender: message.sender ?? this.currentUserId,\n timestamp: message.timestamp ?? new Date(),\n attachments: message.attachments || [],\n };\n\n const allowed = this.emitEvent('igcMessageCreated', {\n detail: newMessage,\n cancelable: true,\n });\n\n if (allowed) {\n if (!this.messages.some((msg) => msg.id === newMessage.id)) {\n this.messages = [...this.messages, newMessage];\n }\n this._host.requestUpdate('messages');\n\n this.inputValue = '';\n this.inputAttachments = [];\n }\n }\n\n /**\n * Adds files as attachments to the input.\n * Emits 'igcAttachmentChange' event which can be canceled to prevent adding.\n * @param files Array of File objects to attach\n */\n public attachFiles(files: File[]) {\n const newAttachments: IgcMessageAttachment[] = [];\n const fileNames = new Set(\n this.inputAttachments.map((attachment) => attachment.file?.name ?? '')\n );\n\n for (const file of files) {\n if (fileNames.has(file.name)) {\n continue;\n }\n\n const isImage = file.type.startsWith('image/');\n const url = URL.createObjectURL(file);\n\n newAttachments.push({\n id: nanoid(),\n url,\n name: file.name,\n file,\n thumbnail: isImage ? url : undefined,\n });\n }\n\n const allowed = this.emitEvent('igcAttachmentChange', {\n detail: [...this.inputAttachments, ...newAttachments],\n cancelable: true,\n });\n if (allowed) {\n this.inputAttachments = [...this.inputAttachments, ...newAttachments];\n }\n }\n\n public isImageAttachment(attachment: IgcMessageAttachment): boolean {\n return (\n attachment.type === 'image' ||\n !!attachment.file?.type.startsWith('image/')\n );\n }\n\n public handleKeyDown = (e: KeyboardEvent) => {\n if (e.key.toLowerCase() === enterKey.toLowerCase() && !e.shiftKey) {\n e.preventDefault();\n this.sendMessage();\n } else {\n this._lastTyped = Date.now();\n if (!this._isTyping) {\n this.emitEvent('igcTypingChange', {\n detail: { isTyping: true },\n });\n this._isTyping = true;\n }\n\n const stopTypingDelay = this.stopTypingDelay;\n setTimeout(() => {\n if (\n this._isTyping &&\n stopTypingDelay &&\n this._lastTyped + stopTypingDelay < Date.now()\n ) {\n this.emitEvent('igcTypingChange', {\n detail: { isTyping: false },\n });\n this._isTyping = false;\n }\n }, stopTypingDelay);\n }\n };\n\n public sendMessage = () => {\n if (!this.inputValue.trim() && this.inputAttachments.length === 0) return;\n\n this.addMessage({\n text: this.inputValue,\n attachments: this.inputAttachments,\n });\n this.inputValue = '';\n\n if (this._textArea) {\n this._textArea.style.height = 'auto';\n }\n\n this._host.updateComplete.then(() => {\n this._textArea?.focus();\n });\n };\n\n /**\n * Removes an attachment by index.\n * Emits 'igcAttachmentChange' event which can be canceled to prevent removal.\n * @param index Index of the attachment to remove\n */\n public removeAttachment = (index: number): void => {\n const allowed = this.emitEvent('igcAttachmentChange', {\n detail: this.inputAttachments.filter((_, i) => i !== index),\n cancelable: true,\n });\n if (allowed) {\n this.inputAttachments = this.inputAttachments.filter(\n (_, i) => i !== index\n );\n }\n };\n\n /**\n * Handles when a suggestion is clicked.\n * Adds the suggestion as a new message and focuses the text area.\n * @param suggestion The suggestion string clicked\n */\n public handleSuggestionClick = (suggestion: string): void => {\n this.addMessage({ text: suggestion });\n if (this.textArea) {\n this.textArea.focus();\n }\n };\n\n /**\n * Updates the chat options partially.\n * @param options Partial options to merge with current options\n */\n public updateOptions(options: Partial<IgcChatOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Updates the internal cache for accepted file types.\n * Parses the acceptedFiles string option into extensions, mimeTypes, and wildcard types.\n */\n public updateAcceptedTypesCache(): void {\n this._acceptedTypesCache = this.options?.acceptedFiles\n ? parseAcceptedFileTypes(this.options.acceptedFiles)\n : null;\n }\n\n //#endregion\n}\n"]}
1
+ {"version":3,"file":"chat-state.js","sourceRoot":"","sources":["../../../src/components/chat/chat-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,iBAAiB,MAAM,mBAAmB,CAAC;AAClD,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AAUxD,OAAO,EAEL,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAOpB,MAAM,OAAO,SAAS;IAiCpB,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;IAED,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,QAAQ,EAAE,iBAAiB,IAAI,KAAK,CAAC;IACnD,CAAC;IAKD,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAKD,IAAW,QAAQ,CAAC,KAAuB;QACzC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAKD,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAKD,IAAW,OAAO,CAAC,KAAqB;QACtC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAKD,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,QAAQ,EAAE,aAAa,IAAI,MAAM,CAAC;IAChD,CAAC;IAKD,IAAW,mBAAmB;QAC5B,OAAO,IAAI,CAAC,QAAQ,EAAE,mBAAmB,IAAI,gBAAgB,CAAC;IAChE,CAAC;IAKD,IAAW,eAAe;QACxB,OAAO,IAAI,CAAC,QAAQ,EAAE,eAAe,IAAI,IAAI,CAAC;IAChD,CAAC;IAKD,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAKD,IAAW,gBAAgB,CAAC,KAAiC;QAC3D,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAKD,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAKD,IAAW,UAAU,CAAC,KAAa;QACjC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAMD,IAAW,aAAa;QACtB,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAMD,IAAW,mBAAmB;QAC5B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC1C,CAAC;IAID,YACE,IAAsB,EACtB,eAA8B,EAC9B,wBAAuC;QAxIjC,cAAS,GAAqB,EAAE,CAAC;QAKjC,sBAAiB,GAA+B,EAAE,CAAC;QAEnD,gBAAW,GAAG,EAAE,CAAC;QAIjB,wBAAmB,GAAiC,IAAI,CAAC;QAE1D,cAAS,GAAG,KAAK,CAAC;QACjB,eAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,oBAAe,GAAG,uBAAuB,CAAC;QAqR1C,kBAAa,GAAG,CAAC,CAAgB,EAAE,EAAE;YAC1C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE;oBAChC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;iBAC3B,CAAC,CAAC;gBACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBAEtB,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;gBAC7C,UAAU,CAAC,GAAG,EAAE;oBACd,IACE,IAAI,CAAC,SAAS;wBACd,eAAe;wBACf,IAAI,CAAC,UAAU,GAAG,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,EAC9C,CAAC;wBACD,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE;4BAChC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;yBAC5B,CAAC,CAAC;wBACH,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;oBACzB,CAAC;gBACH,CAAC,EAAE,eAAe,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC;QAjLA,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;QACxC,IAAI,CAAC,yBAAyB,GAAG,wBAAwB,CAAC;IAC5D,CAAC;IAEM,oBAAoB,CAAC,OAAwB;QAClD,OAAO,IAAI,CAAC,aAAa,KAAK,OAAO,EAAE,MAAM,CAAC;IAChD,CAAC;IAIM,SAAS,CAAC,IAAoC,EAAE,IAAU;QAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IAGM,kBAAkB,CAAC,OAAuB;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,mBAAmB,EAAE;YAC/C,MAAM,EAAE,OAAO;YACf,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAGM,oBAAoB,CACzB,WAAuC;QAEvC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,oBAAoB,EAAE;YAChD,MAAM,EAAE,WAAW;YACnB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAGM,qBAAqB,CAAC,UAAoC;QAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,sBAAsB,EAAE;YAClD,MAAM,EAAE,UAAU;YAClB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAGM,mBAAmB,CAAC,QAAgC;QACzD,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,iBAAiB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;IAKM,kBAAkB,CAAC,MAAe,EAAE,OAAe;QACxD,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAC3C,mBAAmB,CAAC,OAAO,CAC5B,CAAC;YACF,IAAI,CAAC,eAAe,CAAC,YAAY,GAAG,yBAAyB,CAAC;YAC9D,IAAI,CAAC,eAAe,CAAC,SAAS,GAAG,GAAG,CAAC;YACrC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,OAAO,GAAG,OAAO,CAAC;QACvC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAKM,eAAe,CAAC,OAAe;QACpC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;YACtE,IAAI,CAAC,YAAY,CAAC,WAAW,GAAG,IAAI,CAAC;YACrC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,WAAW,GAAG,OAAO,CAAC;QACxC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAQO,sBAAsB;QAC5B,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa;YACpD,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;YACpD,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAES,cAAc,CAAC,OAAgC;QACvD,OAAO;YACL,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,MAAM,EAAE;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa;YAC5C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YACrD,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;SACvC,CAAC;IACJ,CAAC;IAEM,UAAU,CAAC,OAAgC;QAChD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAUM,mBAAmB,CAAC,OAAgC;QACzD,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEhD,IAAI,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC;IAOM,oBAAoB,CAAC,KAAa;QACvC,MAAM,cAAc,GAA+B,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CACvE,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,SAAS;YACX,CAAC;YAED,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,UAAU,GAA6B;gBAC3C,EAAE,EAAE,MAAM,EAAE;gBACZ,GAAG;gBACH,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI;aACL,CAAC;YAEF,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC;YAC7B,CAAC;YACD,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,cAAc,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;CA2BF","sourcesContent":["import { IgcChatResourceStringEN } from '../common/i18n/chat.resources.js';\nimport { isEmpty, nanoid } from '../common/util.js';\nimport IgcToastComponent from '../toast/toast.js';\nimport IgcTooltipComponent from '../tooltip/tooltip.js';\nimport type IgcChatComponent from './chat.js';\nimport type { IgcChatComponentEventMap } from './chat.js';\nimport type {\n ChatSuggestionsPosition,\n IgcChatMessage,\n IgcChatMessageAttachment,\n IgcChatMessageReaction,\n IgcChatOptions,\n} from './types.js';\nimport {\n type ChatAcceptedFileTypes,\n isImageAttachment,\n parseAcceptedFileTypes,\n} from './utils.js';\n\n/**\n * Internal state manager for the `<igc-chat>` component.\n *\n * Manages messages, input value, attachments, options, and event emissions.\n */\nexport class ChatState {\n //#region Internal properties and state /** The host `<igc-chat>` component instance */\n private readonly _host: IgcChatComponent;\n\n private readonly _contextUpdateFn: () => unknown;\n private readonly _userInputContextUpdateFn: () => unknown;\n\n private _actionsTooltip?: IgcTooltipComponent;\n private _actionToast?: IgcToastComponent;\n\n /** The current list of messages */\n private _messages: IgcChatMessage[] = [];\n /** Chat options/configuration */\n private _options?: IgcChatOptions;\n\n /** List of current input attachments */\n private _inputAttachments: IgcChatMessageAttachment[] = [];\n /** Current input text */\n private _inputValue = '';\n /**\n * Cache of accepted file types, organized into extensions, mimeTypes, and wildcardTypes\n */\n private _acceptedTypesCache: ChatAcceptedFileTypes | null = null;\n\n public _isTyping = false;\n private _lastTyped = Date.now();\n\n public resourceStrings = IgcChatResourceStringEN;\n\n //#endregion\n\n //#region Public properties\n\n public get host(): IgcChatComponent {\n return this._host;\n }\n\n public get acceptedFileTypes(): ChatAcceptedFileTypes | null {\n return this._acceptedTypesCache;\n }\n\n public get disableAutoScroll(): boolean {\n return this._options?.disableAutoScroll ?? false;\n }\n\n /**\n * Gets the list of chat messages.\n */\n public get messages(): IgcChatMessage[] {\n return this._messages;\n }\n\n /**\n * Sets the list of chat messages.\n */\n public set messages(value: IgcChatMessage[]) {\n this._messages = value;\n }\n\n /**\n * Gets current chat options.\n */\n public get options(): IgcChatOptions | undefined {\n return this._options;\n }\n\n /**\n * Sets chat options and requests host update.\n */\n public set options(value: IgcChatOptions) {\n this._options = value;\n this._setAcceptedTypesCache();\n this._contextUpdateFn.call(this._host);\n }\n\n /**\n * Gets the current user ID from options or returns 'user' as fallback.\n */\n public get currentUserId(): string {\n return this._options?.currentUserId ?? 'user';\n }\n\n /**\n * Gets the current suggestionsPosition from options or returns the default value 'below-messages'.\n */\n public get suggestionsPosition(): ChatSuggestionsPosition {\n return this._options?.suggestionsPosition ?? 'below-messages';\n }\n\n /**\n * Gets the current stopTypingDelay from options or returns the default value `3000`.\n */\n public get stopTypingDelay(): number {\n return this._options?.stopTypingDelay ?? 3000;\n }\n\n /**\n * Gets the list of attachments currently attached to input.\n */\n public get inputAttachments(): IgcChatMessageAttachment[] {\n return this._inputAttachments;\n }\n\n /**\n * Sets the input attachments and requests host update.\n */\n public set inputAttachments(value: IgcChatMessageAttachment[]) {\n this._inputAttachments = value;\n this._userInputContextUpdateFn.call(this._host);\n }\n\n /**\n * Gets the current input value.\n */\n public get inputValue(): string {\n return this._inputValue;\n }\n\n /**\n * Sets the current input value and requests host update.\n */\n public set inputValue(value: string) {\n this._inputValue = value;\n this._userInputContextUpdateFn.call(this._host);\n }\n\n /**\n * Returns whether the default chat input textarea has a trimmed value payload.\n * @internal\n */\n public get hasInputValue(): boolean {\n return !!this._inputValue.trim();\n }\n\n /**\n * Returns whether the default file input of the chat has any attached files.\n * @internal\n */\n public get hasInputAttachments(): boolean {\n return !isEmpty(this._inputAttachments);\n }\n\n //#endregion\n\n constructor(\n chat: IgcChatComponent,\n contextUpdateFn: () => unknown,\n userInputContextUpdateFn: () => unknown\n ) {\n this._host = chat;\n this._contextUpdateFn = contextUpdateFn;\n this._userInputContextUpdateFn = userInputContextUpdateFn;\n }\n\n public isCurrentUserMessage(message?: IgcChatMessage): boolean {\n return this.currentUserId === message?.sender;\n }\n\n //#region Event handlers\n\n public emitEvent(name: keyof IgcChatComponentEventMap, args?: any): boolean {\n return this._host.emitEvent(name, args);\n }\n\n /** @internal */\n public emitMessageCreated(message: IgcChatMessage): boolean {\n return this._host.emitEvent('igcMessageCreated', {\n detail: message,\n cancelable: true,\n });\n }\n\n /** @internal */\n public emitAttachmentsAdded(\n attachments: IgcChatMessageAttachment[]\n ): boolean {\n return this._host.emitEvent('igcAttachmentAdded', {\n detail: attachments,\n cancelable: true,\n });\n }\n\n /** @internal */\n public emitAttachmentRemoved(attachment: IgcChatMessageAttachment): boolean {\n return this._host.emitEvent('igcAttachmentRemoved', {\n detail: attachment,\n cancelable: true,\n });\n }\n\n /** @internal */\n public emitMessageReaction(reaction: IgcChatMessageReaction): boolean {\n return this._host.emitEvent('igcMessageReact', { detail: reaction });\n }\n\n /**\n * @internal\n */\n public showActionsTooltip(target: Element, message: string): void {\n if (!this._actionsTooltip) {\n this._actionsTooltip = document.createElement(\n IgcTooltipComponent.tagName\n );\n this._actionsTooltip.hideTriggers = 'pointerleave,click,blur';\n this._actionsTooltip.hideDelay = 100;\n this._host.renderRoot.appendChild(this._actionsTooltip);\n }\n this._actionsTooltip.message = message;\n this._actionsTooltip.show(target);\n }\n\n /**\n * @internal\n */\n public showActionToast(content: string): void {\n if (!this._actionToast) {\n this._actionToast = document.createElement(IgcToastComponent.tagName);\n this._actionToast.displayTime = 3000;\n this._host.renderRoot.appendChild(this._actionToast);\n }\n this._actionToast.textContent = content;\n this._actionToast.show();\n }\n\n //#endregion\n\n /**\n * Updates the internal cache for accepted file types.\n * Parses the acceptedFiles string option into extensions, mimeTypes, and wildcard types.\n */\n private _setAcceptedTypesCache(): void {\n this._acceptedTypesCache = this.options?.acceptedFiles\n ? parseAcceptedFileTypes(this.options.acceptedFiles)\n : null;\n }\n\n protected _createMessage(message: Partial<IgcChatMessage>): IgcChatMessage {\n return {\n id: message.id ?? nanoid(),\n text: message.text ?? '',\n sender: message.sender ?? this.currentUserId,\n timestamp: message.timestamp ?? Date.now().toString(),\n attachments: message.attachments || [],\n };\n }\n\n public addMessage(message: Partial<IgcChatMessage>) {\n this.messages.push(this._createMessage(message));\n this._host.requestUpdate('messages');\n }\n\n //#region Public API\n\n /**\n * Adds a new chat message.\n * Emits 'igcMessageCreated' event which can be canceled to prevent adding.\n * Clears input value and attachments on success.\n * @internal\n */\n public addMessageWithEvent(message: Partial<IgcChatMessage>): void {\n const newMessage = this._createMessage(message);\n\n if (this.emitMessageCreated(newMessage)) {\n this.addMessage(newMessage);\n this.inputValue = '';\n this.inputAttachments = [];\n }\n }\n\n /**\n * Adds files as attachments to the input.\n * Emits 'igcAttachmentChange' event which can be canceled to prevent adding.\n * @internal\n */\n public attachFilesWithEvent(files: File[]): void {\n const newAttachments: IgcChatMessageAttachment[] = [];\n const fileNames = new Set(\n this.inputAttachments.map((attachment) => attachment.file?.name ?? '')\n );\n\n for (const file of files) {\n if (fileNames.has(file.name)) {\n continue;\n }\n\n const url = URL.createObjectURL(file);\n const attachment: IgcChatMessageAttachment = {\n id: nanoid(),\n url,\n name: file.name,\n file,\n };\n\n if (isImageAttachment(file)) {\n attachment.thumbnail = url;\n }\n newAttachments.push(attachment);\n }\n\n if (this.emitAttachmentsAdded(newAttachments)) {\n this.inputAttachments = [...this.inputAttachments, ...newAttachments];\n }\n }\n\n public handleKeyDown = (_: KeyboardEvent) => {\n this._lastTyped = Date.now();\n if (!this._isTyping) {\n this.emitEvent('igcTypingChange', {\n detail: { isTyping: true },\n });\n this._isTyping = true;\n\n const stopTypingDelay = this.stopTypingDelay;\n setTimeout(() => {\n if (\n this._isTyping &&\n stopTypingDelay &&\n this._lastTyped + stopTypingDelay < Date.now()\n ) {\n this.emitEvent('igcTypingChange', {\n detail: { isTyping: false },\n });\n this._isTyping = false;\n }\n }, stopTypingDelay);\n }\n };\n\n //#endregion\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { LitElement, type PropertyValues } from 'lit';
2
2
  import type { Constructor } from '../common/mixins/constructor.js';
3
- import type { IgcChatOptions, IgcMessage, IgcMessageAttachment } from './types.js';
3
+ import type { IgcChatMessage, IgcChatMessageAttachment, IgcChatMessageReaction, IgcChatOptions } from './types.js';
4
4
  /**
5
5
  * Defines the custom events dispatched by the `<igc-chat>` component.
6
6
  */
@@ -8,22 +8,24 @@ export interface IgcChatComponentEventMap {
8
8
  /**
9
9
  * Dispatched when a new chat message is created (sent).
10
10
  */
11
- igcMessageCreated: CustomEvent<IgcMessage>;
11
+ igcMessageCreated: CustomEvent<IgcChatMessage>;
12
12
  /**
13
13
  * Dispatched when a message is reacted to.
14
14
  */
15
- igcMessageReact: CustomEvent<{
16
- message: IgcMessage;
17
- reaction: string;
18
- }>;
15
+ igcMessageReact: CustomEvent<IgcChatMessageReaction>;
19
16
  /**
20
17
  * Dispatched when a chat message attachment is clicked.
21
18
  */
22
- igcAttachmentClick: CustomEvent<IgcMessageAttachment>;
19
+ igcAttachmentClick: CustomEvent<IgcChatMessageAttachment>;
23
20
  /**
24
- * Dispatched when an attachment is changed (e.g., updated or removed).
21
+ * Dispatched when attachment(s) are added either through drag & drop or through
22
+ * the default file input.
25
23
  */
26
- igcAttachmentChange: CustomEvent<IgcMessageAttachment>;
24
+ igcAttachmentAdded: CustomEvent<IgcChatMessageAttachment[]>;
25
+ /**
26
+ * Dispatched when an attachment is removed by the user.
27
+ */
28
+ igcAttachmentRemoved: CustomEvent<IgcChatMessageAttachment>;
27
29
  /**
28
30
  * Dispatched during an attachment drag operation.
29
31
  */
@@ -58,7 +60,8 @@ declare const IgcChatComponent_base: Constructor<import("../common/mixins/event-
58
60
  * @fires igcMessageCreated - Dispatched when a new chat message is created (sent).
59
61
  * @fires igcMessageReact - Dispatched when a message is reacted to.
60
62
  * @fires igcAttachmentClick - Dispatched when a chat message attachment is clicked.
61
- * @fires igcAttachmentChange - Dispatched when a message attachment is changed (e.g., updated or removed).
63
+ * @fires igcAttachmentAdded - Dispatched when attachment(s) are added either through drag & drop or through the default file input.
64
+ * @fires igcAttachmentRemoved - Dispatched when an attachment is removed by the user.
62
65
  * @fires igcAttachmentDrag - Dispatched during an attachment drag operation.
63
66
  * @fires igcAttachmentDrop - Dispatched when an attachment is dropped (e.g., in a drag-and-drop operation).
64
67
  * @fires igcTypingChange - Dispatched when the typing status changes (e.g., user starts or stops typing).
@@ -75,39 +78,85 @@ declare const IgcChatComponent_base: Constructor<import("../common/mixins/event-
75
78
  * @slot suggestion - Slot for rendering a single suggestion item.
76
79
  * @slot empty-state - Slot shown when there are no messages.
77
80
  *
78
- * @csspart header - Styles the header container.
79
- * @csspart prefix - Styles the element before the title (e.g., avatar).
81
+ * @csspart chat-container - Styles the main chat container.
82
+ * @csspart header - Styles the chat header container.
83
+ * @csspart prefix - Styles the element before the chat title (e.g., avatar).
80
84
  * @csspart title - Styles the chat header title.
81
- * @csspart suggestions - Styles the suggestion container.
85
+ *
86
+ * @csspart message-area-container - Styles the container holding the messages and (optional) suggestions.
87
+ * @csspart message-list - Styles the message list container.
88
+ * @csspart message-item - Styles each message wrapper.
89
+ * @csspart typing-indicator - Styles the typing indicator container.
90
+ * @csspart typing-dot - Styles individual typing indicator dots.
91
+ *
92
+ * @csspart suggestions-container - Styles the container holding all suggestions.
93
+ * @csspart suggestions-header - Styles the suggestions header.
82
94
  * @csspart suggestion - Styles each suggestion item.
95
+ * @csspart suggestion-prefix - Styles the icon or prefix in a suggestion.
96
+ * @csspart suggestion-title - Styles the text/title of a suggestion.
97
+ *
98
+ * @csspart empty-state - Styles the empty state container when there are no messages.
99
+ *
100
+ * @csspart input-area-container - Styles the wrapper around the chat input area.
101
+ * @csspart input-container - Styles the main input container.
102
+ * @csspart input-attachments-container - Styles the container for attachments in the input.
103
+ * @csspart input-attachment-container - Styles a single attachment in the input area.
104
+ * @csspart input-attachment-name - Styles the file name of an attachment.
105
+ * @csspart input-attachment-icon - Styles the icon of an attachment.
106
+ * @csspart text-input - Styles the text input field for typing messages.
107
+ * @csspart input-actions-container - Styles the container for input actions.
108
+ * @csspart input-actions-start - Styles the group of actions at the start of the input after the default file upload.
109
+ * @csspart input-actions-end - Styles the group of actions at the end of the input.
110
+ * @csspart file-upload-container - Styles the container for the file upload input.
111
+ * @csspart file-upload - Styles the file upload input itself.
112
+ * @csspart send-button-container - Styles the container around the send button.
113
+ * @csspart send-button - Styles the send button.
114
+ *
115
+ * @csspart message-container - Styles the container of a single message.
116
+ * @csspart message-list (forwarded) - Styles the internal list of messages.
117
+ * @csspart message-header - Styles the header of a message (e.g., sender, timestamp).
118
+ * @csspart message-content - Styles the text content of a message.
119
+ * @csspart message-attachments-container - Styles the container for message attachments.
120
+ * @csspart message-attachment - Styles a single message attachment.
121
+ * @csspart message-actions-container - Styles the container holding message actions.
122
+ * @csspart message-sent - Styles messages marked as sent by the current user.
123
+ * @csspart attachment-header - Styles the header of an attachment block.
124
+ * @csspart attachment-content - Styles the content of an attachment block.
125
+ * @csspart attachment-icon - Styles the icon of an attachment.
126
+ * @csspart file-name - Styles the file name shown in an attachment.
83
127
  */
84
128
  export default class IgcChatComponent extends IgcChatComponent_base {
85
129
  static readonly tagName = "igc-chat";
86
130
  static styles: import("lit").CSSResult[];
87
131
  static register(): void;
88
132
  private readonly _state;
133
+ private readonly _defaults;
89
134
  private readonly _slots;
90
135
  private readonly _context;
91
136
  private readonly _userInputContext;
137
+ private readonly _input?;
138
+ private readonly _typingIndicator?;
139
+ private readonly _suggestionsContainer?;
140
+ private readonly _scrollContainer;
92
141
  private _updateContext;
93
142
  private _updateUserInputContext;
94
143
  /**
95
144
  * The list of chat messages currently displayed.
96
145
  * Use this property to set or update the message history.
97
146
  */
98
- set messages(value: IgcMessage[]);
99
- get messages(): IgcMessage[];
147
+ set messages(value: IgcChatMessage[]);
148
+ get messages(): IgcChatMessage[];
100
149
  /**
101
150
  * The chat message currently being composed but not yet sent.
102
151
  * Includes the draft text and any attachments.
103
152
  */
104
153
  set draftMessage(value: {
105
154
  text: string;
106
- attachments?: IgcMessageAttachment[];
155
+ attachments?: IgcChatMessageAttachment[];
107
156
  });
108
157
  get draftMessage(): {
109
158
  text: string;
110
- attachments?: IgcMessageAttachment[];
159
+ attachments?: IgcChatMessageAttachment[];
111
160
  };
112
161
  /**
113
162
  * Controls the chat behavior and appearance through a configuration object.
@@ -120,17 +169,12 @@ export default class IgcChatComponent extends IgcChatComponent_base {
120
169
  */
121
170
  resourceStrings: import("../common/i18n/chat.resources.js").IgcChatResourceStrings;
122
171
  constructor();
123
- protected contextChanged(): void;
172
+ private _getRenderer;
173
+ private _handleSuggestionClick;
124
174
  /**
125
175
  * Scrolls the view to a specific message by id.
126
- * @param messageId - The id of the message to scroll to
127
176
  */
128
177
  scrollToMessage(messageId: string): void;
129
- /**
130
- * Updates the context value to notify all consumers that the chat state has changed.
131
- * This ensures that components consuming the chat context will re-render.
132
- */
133
- updateContextValue(): void;
134
178
  protected updated(properties: PropertyValues<this>): void;
135
179
  private _scrollToBottom;
136
180
  private _renderHeader;