igniteui-webcomponents 6.3.0-beta.0 → 6.3.0-beta.1

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 (230) hide show
  1. package/components/accordion/accordion.js +3 -4
  2. package/components/accordion/accordion.js.map +1 -1
  3. package/components/avatar/avatar.js +3 -4
  4. package/components/avatar/avatar.js.map +1 -1
  5. package/components/badge/badge.js +3 -4
  6. package/components/badge/badge.js.map +1 -1
  7. package/components/banner/banner.js +3 -4
  8. package/components/banner/banner.js.map +1 -1
  9. package/components/button/button-base.js +1 -1
  10. package/components/button/button-base.js.map +1 -1
  11. package/components/button/button.js +3 -4
  12. package/components/button/button.js.map +1 -1
  13. package/components/button/icon-button.js +3 -4
  14. package/components/button/icon-button.js.map +1 -1
  15. package/components/button-group/button-group.js +3 -4
  16. package/components/button-group/button-group.js.map +1 -1
  17. package/components/button-group/toggle-button.js +4 -3
  18. package/components/button-group/toggle-button.js.map +1 -1
  19. package/components/calendar/calendar.js +3 -4
  20. package/components/calendar/calendar.js.map +1 -1
  21. package/components/calendar/days-view/days-view.js +4 -3
  22. package/components/calendar/days-view/days-view.js.map +1 -1
  23. package/components/calendar/months-view/months-view.js +4 -3
  24. package/components/calendar/months-view/months-view.js.map +1 -1
  25. package/components/calendar/years-view/years-view.js +4 -3
  26. package/components/calendar/years-view/years-view.js.map +1 -1
  27. package/components/card/card.actions.js +3 -4
  28. package/components/card/card.actions.js.map +1 -1
  29. package/components/card/card.content.js +3 -4
  30. package/components/card/card.content.js.map +1 -1
  31. package/components/card/card.header.js +3 -4
  32. package/components/card/card.header.js.map +1 -1
  33. package/components/card/card.js +3 -4
  34. package/components/card/card.js.map +1 -1
  35. package/components/card/card.media.js +3 -4
  36. package/components/card/card.media.js.map +1 -1
  37. package/components/carousel/carousel-indicator-container.js +3 -4
  38. package/components/carousel/carousel-indicator-container.js.map +1 -1
  39. package/components/carousel/carousel-indicator.js +3 -4
  40. package/components/carousel/carousel-indicator.js.map +1 -1
  41. package/components/carousel/carousel-slide.js +3 -4
  42. package/components/carousel/carousel-slide.js.map +1 -1
  43. package/components/carousel/carousel.js +3 -4
  44. package/components/carousel/carousel.js.map +1 -1
  45. package/components/chat/chat-input.d.ts +3 -3
  46. package/components/chat/chat-input.js +38 -38
  47. package/components/chat/chat-input.js.map +1 -1
  48. package/components/chat/chat-message.d.ts +3 -18
  49. package/components/chat/chat-message.js +28 -30
  50. package/components/chat/chat-message.js.map +1 -1
  51. package/components/chat/chat-state.d.ts +5 -8
  52. package/components/chat/chat-state.js +20 -22
  53. package/components/chat/chat-state.js.map +1 -1
  54. package/components/chat/chat.d.ts +4 -6
  55. package/components/chat/chat.js +44 -32
  56. package/components/chat/chat.js.map +1 -1
  57. package/components/chat/extras/markdown-renderer.d.ts +4 -1
  58. package/components/chat/extras/markdown-renderer.js +14 -14
  59. package/components/chat/extras/markdown-renderer.js.map +1 -1
  60. package/components/chat/message-attachments.d.ts +3 -3
  61. package/components/chat/message-attachments.js +35 -32
  62. package/components/chat/message-attachments.js.map +1 -1
  63. package/components/chat/themes/input.base.css.js +1 -1
  64. package/components/chat/themes/input.base.css.js.map +1 -1
  65. package/components/chat/themes/message.base.css.js +1 -1
  66. package/components/chat/themes/message.base.css.js.map +1 -1
  67. package/components/chat/themes/shared/chat.bootstrap.css.js +1 -1
  68. package/components/chat/themes/shared/chat.bootstrap.css.js.map +1 -1
  69. package/components/chat/themes/shared/chat.fluent.css.js +1 -1
  70. package/components/chat/themes/shared/chat.fluent.css.js.map +1 -1
  71. package/components/chat/themes/shared/chat.indigo.css.js +1 -1
  72. package/components/chat/themes/shared/chat.indigo.css.js.map +1 -1
  73. package/components/chat/themes/shared/input/input.bootstrap.css.js +1 -1
  74. package/components/chat/themes/shared/input/input.bootstrap.css.js.map +1 -1
  75. package/components/chat/themes/shared/input/input.fluent.css.js +1 -1
  76. package/components/chat/themes/shared/input/input.fluent.css.js.map +1 -1
  77. package/components/chat/themes/shared/input/input.indigo.css.js +1 -1
  78. package/components/chat/themes/shared/input/input.indigo.css.js.map +1 -1
  79. package/components/chat/types.d.ts +32 -21
  80. package/components/chat/types.js.map +1 -1
  81. package/components/chat/utils.d.ts +1 -0
  82. package/components/chat/utils.js +9 -1
  83. package/components/chat/utils.js.map +1 -1
  84. package/components/checkbox/checkbox.js +3 -4
  85. package/components/checkbox/checkbox.js.map +1 -1
  86. package/components/checkbox/switch.js +3 -4
  87. package/components/checkbox/switch.js.map +1 -1
  88. package/components/chip/chip.js +3 -4
  89. package/components/chip/chip.js.map +1 -1
  90. package/components/combo/combo-header.js +3 -4
  91. package/components/combo/combo-header.js.map +1 -1
  92. package/components/combo/combo-item.js +3 -4
  93. package/components/combo/combo-item.js.map +1 -1
  94. package/components/combo/combo-list.js +2 -3
  95. package/components/combo/combo-list.js.map +1 -1
  96. package/components/combo/combo.js +4 -3
  97. package/components/combo/combo.js.map +1 -1
  98. package/components/common/controllers/focus-ring.js +5 -5
  99. package/components/common/controllers/focus-ring.js.map +1 -1
  100. package/components/common/controllers/key-bindings.js +4 -4
  101. package/components/common/controllers/key-bindings.js.map +1 -1
  102. package/components/common/mixins/forms/associated.js +1 -1
  103. package/components/common/mixins/forms/associated.js.map +1 -1
  104. package/components/common/mixins/forms/form-value.js +1 -1
  105. package/components/common/mixins/forms/form-value.js.map +1 -1
  106. package/components/common/part-map.d.ts +1 -1
  107. package/components/date-picker/date-picker.js +5 -4
  108. package/components/date-picker/date-picker.js.map +1 -1
  109. package/components/date-range-picker/date-range-picker.js +5 -4
  110. package/components/date-range-picker/date-range-picker.js.map +1 -1
  111. package/components/date-range-picker/predefined-ranges-area.js +3 -4
  112. package/components/date-range-picker/predefined-ranges-area.js.map +1 -1
  113. package/components/date-time-input/date-time-input.js +2 -3
  114. package/components/date-time-input/date-time-input.js.map +1 -1
  115. package/components/date-time-input/date-util.js +11 -11
  116. package/components/date-time-input/date-util.js.map +1 -1
  117. package/components/dialog/dialog.js +3 -4
  118. package/components/dialog/dialog.js.map +1 -1
  119. package/components/divider/divider.js +3 -4
  120. package/components/divider/divider.js.map +1 -1
  121. package/components/dropdown/dropdown-group.js +3 -4
  122. package/components/dropdown/dropdown-group.js.map +1 -1
  123. package/components/dropdown/dropdown-header.js +3 -4
  124. package/components/dropdown/dropdown-header.js.map +1 -1
  125. package/components/dropdown/dropdown-item.js +3 -4
  126. package/components/dropdown/dropdown-item.js.map +1 -1
  127. package/components/dropdown/dropdown.js +4 -3
  128. package/components/dropdown/dropdown.js.map +1 -1
  129. package/components/expansion-panel/expansion-panel.js +3 -4
  130. package/components/expansion-panel/expansion-panel.js.map +1 -1
  131. package/components/file-input/file-input.js +3 -4
  132. package/components/file-input/file-input.js.map +1 -1
  133. package/components/focus-trap/focus-trap.js +7 -8
  134. package/components/focus-trap/focus-trap.js.map +1 -1
  135. package/components/icon/icon-references.js +78 -0
  136. package/components/icon/icon-references.js.map +1 -1
  137. package/components/icon/icon-state.broadcast.js +1 -1
  138. package/components/icon/icon-state.broadcast.js.map +1 -1
  139. package/components/icon/icon.js +3 -4
  140. package/components/icon/icon.js.map +1 -1
  141. package/components/icon/internal-icons-lib.js +39 -0
  142. package/components/icon/internal-icons-lib.js.map +1 -1
  143. package/components/input/input-base.js +4 -3
  144. package/components/input/input-base.js.map +1 -1
  145. package/components/input/input.js +2 -3
  146. package/components/input/input.js.map +1 -1
  147. package/components/list/list-header.js +3 -4
  148. package/components/list/list-header.js.map +1 -1
  149. package/components/list/list-item.js +3 -4
  150. package/components/list/list-item.js.map +1 -1
  151. package/components/list/list.js +3 -4
  152. package/components/list/list.js.map +1 -1
  153. package/components/mask-input/mask-input.js +2 -3
  154. package/components/mask-input/mask-input.js.map +1 -1
  155. package/components/nav-drawer/nav-drawer-header-item.js +3 -4
  156. package/components/nav-drawer/nav-drawer-header-item.js.map +1 -1
  157. package/components/nav-drawer/nav-drawer-item.js +3 -4
  158. package/components/nav-drawer/nav-drawer-item.js.map +1 -1
  159. package/components/nav-drawer/nav-drawer.js +3 -4
  160. package/components/nav-drawer/nav-drawer.js.map +1 -1
  161. package/components/navbar/navbar.js +3 -4
  162. package/components/navbar/navbar.js.map +1 -1
  163. package/components/popover/popover.js +9 -10
  164. package/components/popover/popover.js.map +1 -1
  165. package/components/progress/circular-gradient.js +2 -3
  166. package/components/progress/circular-gradient.js.map +1 -1
  167. package/components/progress/circular-progress.js +3 -4
  168. package/components/progress/circular-progress.js.map +1 -1
  169. package/components/progress/linear-progress.js +3 -4
  170. package/components/progress/linear-progress.js.map +1 -1
  171. package/components/radio/radio.js +3 -4
  172. package/components/radio/radio.js.map +1 -1
  173. package/components/radio-group/radio-group.js +3 -4
  174. package/components/radio-group/radio-group.js.map +1 -1
  175. package/components/rating/rating-symbol.js +3 -4
  176. package/components/rating/rating-symbol.js.map +1 -1
  177. package/components/rating/rating.js +3 -4
  178. package/components/rating/rating.js.map +1 -1
  179. package/components/resize-container/resize-container.js +3 -4
  180. package/components/resize-container/resize-container.js.map +1 -1
  181. package/components/ripple/ripple.js +3 -4
  182. package/components/ripple/ripple.js.map +1 -1
  183. package/components/select/select-group.js +3 -4
  184. package/components/select/select-group.js.map +1 -1
  185. package/components/select/select-header.js +3 -4
  186. package/components/select/select-header.js.map +1 -1
  187. package/components/select/select-item.js +3 -4
  188. package/components/select/select-item.js.map +1 -1
  189. package/components/select/select.js +4 -3
  190. package/components/select/select.js.map +1 -1
  191. package/components/slider/range-slider.js +2 -3
  192. package/components/slider/range-slider.js.map +1 -1
  193. package/components/slider/slider-base.js +1 -1
  194. package/components/slider/slider-base.js.map +1 -1
  195. package/components/slider/slider-label.js +7 -8
  196. package/components/slider/slider-label.js.map +1 -1
  197. package/components/slider/slider.js +2 -3
  198. package/components/slider/slider.js.map +1 -1
  199. package/components/snackbar/snackbar.js +3 -4
  200. package/components/snackbar/snackbar.js.map +1 -1
  201. package/components/stepper/step.js +3 -4
  202. package/components/stepper/step.js.map +1 -1
  203. package/components/stepper/stepper.js +3 -4
  204. package/components/stepper/stepper.js.map +1 -1
  205. package/components/tabs/tab-dom.js +1 -1
  206. package/components/tabs/tab-dom.js.map +1 -1
  207. package/components/tabs/tab.js +4 -5
  208. package/components/tabs/tab.js.map +1 -1
  209. package/components/tabs/tabs.js +3 -4
  210. package/components/tabs/tabs.js.map +1 -1
  211. package/components/textarea/textarea.js +4 -3
  212. package/components/textarea/textarea.js.map +1 -1
  213. package/components/tile-manager/tile-manager.js +4 -3
  214. package/components/tile-manager/tile-manager.js.map +1 -1
  215. package/components/tile-manager/tile.js +3 -4
  216. package/components/tile-manager/tile.js.map +1 -1
  217. package/components/toast/toast.js +3 -4
  218. package/components/toast/toast.js.map +1 -1
  219. package/components/tooltip/controller.js +4 -4
  220. package/components/tooltip/controller.js.map +1 -1
  221. package/components/tooltip/tooltip.js +3 -4
  222. package/components/tooltip/tooltip.js.map +1 -1
  223. package/components/tree/tree-item.js +3 -4
  224. package/components/tree/tree-item.js.map +1 -1
  225. package/components/tree/tree.js +4 -3
  226. package/components/tree/tree.js.map +1 -1
  227. package/components/validation-container/validation-container.js +3 -4
  228. package/components/validation-container/validation-container.js.map +1 -1
  229. package/custom-elements.json +131 -83
  230. package/package.json +1 -1
@@ -24,7 +24,9 @@ import { styles } from './themes/input.base.css.js';
24
24
  import { all } from './themes/input.js';
25
25
  import { styles as shared } from './themes/shared/input/input.common.css.js';
26
26
  import { getChatAcceptedFiles, getIconName } from './utils.js';
27
- class IgcChatInputComponent extends LitElement {
27
+ export default class IgcChatInputComponent extends LitElement {
28
+ static { this.tagName = 'igc-chat-input'; }
29
+ static { this.styles = [styles, shared]; }
28
30
  static register() {
29
31
  registerComponent(IgcChatInputComponent, IgcTextareaComponent, IgcIconButtonComponent, IgcChipComponent, IgcIconComponent);
30
32
  }
@@ -33,14 +35,14 @@ class IgcChatInputComponent extends LitElement {
33
35
  }
34
36
  constructor() {
35
37
  super();
36
- this._parts = { 'input-container': true, dragging: false };
37
38
  this._defaults = Object.freeze({
38
- input: () => this._renderTextArea(),
39
- inputActions: () => this.renderActionsArea(),
40
- inputAttachments: (ctx) => this.renderAttachmentsArea(ctx.param),
41
39
  fileUploadButton: () => this._renderFileUploadButton(),
40
+ input: () => this._renderTextArea(),
41
+ inputActions: () => this._renderActionsArea(),
42
+ inputAttachments: (ctx) => this._renderAttachmentsArea(ctx.attachments),
42
43
  sendButton: () => this._renderSendButton(),
43
44
  });
45
+ this._parts = { 'input-container': true, dragging: false };
44
46
  addThemingController(this, all);
45
47
  }
46
48
  firstUpdated() {
@@ -49,7 +51,8 @@ class IgcChatInputComponent extends LitElement {
49
51
  }
50
52
  _getRenderer(name) {
51
53
  return this._state.options?.renderers
52
- ? (this._state.options.renderers[name] ?? this._defaults[name])
54
+ ? (this._state.options.renderers[name] ??
55
+ this._defaults[name])
53
56
  : this._defaults[name];
54
57
  }
55
58
  _handleKeydown(event) {
@@ -113,7 +116,7 @@ class IgcChatInputComponent extends LitElement {
113
116
  this._state.attachFiles(Array.from(input.files));
114
117
  }
115
118
  }
116
- renderAttachmentsArea(attachments) {
119
+ _renderAttachmentsArea(attachments) {
117
120
  return html `${attachments?.map((attachment, index) => html `
118
121
  <div part="attachment-wrapper" role="listitem">
119
122
  <igc-chip
@@ -133,6 +136,7 @@ class IgcChatInputComponent extends LitElement {
133
136
  return html `
134
137
  <igc-textarea
135
138
  part="text-input"
139
+ aria-label="Chat text input"
136
140
  placeholder=${ifDefined(this._state.options?.inputPlaceholder)}
137
141
  resize="auto"
138
142
  rows="1"
@@ -152,6 +156,7 @@ class IgcChatInputComponent extends LitElement {
152
156
  : html `
153
157
  <label for="input_attachments" part="upload-button">
154
158
  <igc-icon-button
159
+ aria-label="Attach files"
155
160
  variant="flat"
156
161
  name="attach_file"
157
162
  @click=${this._handleFileInputClick}
@@ -160,6 +165,7 @@ class IgcChatInputComponent extends LitElement {
160
165
  type="file"
161
166
  id="input_attachments"
162
167
  name="input_attachments"
168
+ aria-label="Upload button"
163
169
  multiple
164
170
  accept=${bindIf(accepted, accepted)}
165
171
  @change=${this._handleFileUpload}
@@ -180,22 +186,25 @@ class IgcChatInputComponent extends LitElement {
180
186
  ></igc-icon-button>
181
187
  `;
182
188
  }
183
- renderActionsArea() {
184
- return html ` ${this._getRenderer('fileUploadButton')({
185
- param: undefined,
186
- defaults: this._defaults,
187
- options: this._state.options,
188
- })}
189
- ${this._getRenderer('sendButton')({
190
- param: undefined,
189
+ _renderActionsArea() {
190
+ const ctx = {
191
191
  defaults: this._defaults,
192
- options: this._state.options,
193
- })}`;
192
+ instance: this._state.host,
193
+ };
194
+ return html `
195
+ ${this._getRenderer('fileUploadButton')(ctx)}
196
+ ${this._getRenderer('sendButton')(ctx)}
197
+ `;
194
198
  }
195
199
  render() {
196
- const partialCtx = {
200
+ const ctx = {
197
201
  defaults: this._defaults,
198
- options: this._state.options,
202
+ instance: this._state.host,
203
+ };
204
+ const inputCtx = {
205
+ ...ctx,
206
+ attachments: this._state.inputAttachments,
207
+ value: this._state.inputValue,
199
208
  };
200
209
  return html `
201
210
  <div
@@ -205,34 +214,25 @@ class IgcChatInputComponent extends LitElement {
205
214
  @dragleave=${this._handleDragLeave}
206
215
  @drop=${this._handleDrop}
207
216
  >
208
- ${this._state.inputAttachments &&
209
- this._state.inputAttachments.length > 0
210
- ? html ` <div part="attachments" role="list" aria-label="Attachments">
211
- ${until(this._getRenderer('inputAttachments')({
212
- ...partialCtx,
213
- param: this._state.inputAttachments,
214
- }))}
215
- </div>`
217
+ ${this._state.hasInputAttachments
218
+ ? html `
219
+ <div part="attachments" role="list" aria-label="Attachments">
220
+ ${until(this._getRenderer('inputAttachments')(inputCtx))}
221
+ </div>
222
+ `
216
223
  : nothing}
224
+
217
225
  <div part="input-wrapper">
218
- ${until(this._getRenderer('input')({
219
- ...partialCtx,
220
- param: this._state.inputValue,
221
- }))}
226
+ ${until(this._getRenderer('input')(inputCtx))}
222
227
  </div>
228
+
223
229
  <div part="buttons-container">
224
- ${until(this._getRenderer('inputActions')({
225
- ...partialCtx,
226
- param: undefined,
227
- }))}
230
+ ${until(this._getRenderer('inputActions')(ctx))}
228
231
  </div>
229
232
  </div>
230
233
  `;
231
234
  }
232
235
  }
233
- IgcChatInputComponent.tagName = 'igc-chat-input';
234
- IgcChatInputComponent.styles = [styles, shared];
235
- export default IgcChatInputComponent;
236
236
  __decorate([
237
237
  consume({ context: chatContext, subscribe: true })
238
238
  ], IgcChatInputComponent.prototype, "_state", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"chat-input.js","sourceRoot":"","sources":["../../../src/components/chat/chat-input.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { query, state } from 'lit/decorators.js';\nimport { cache } from 'lit/directives/cache.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { until } from 'lit/directives/until.js';\nimport { addThemingController } from '../../theming/theming-controller.js';\nimport IgcIconButtonComponent from '../button/icon-button.js';\nimport IgcChipComponent from '../chip/chip.js';\nimport { chatContext, chatUserInputContext } from '../common/context.js';\nimport { enterKey } from '../common/controllers/key-bindings.js';\nimport { registerComponent } from '../common/definitions/register.js';\nimport { partMap } from '../common/part-map.js';\nimport { bindIf, hasFiles, isEmpty } from '../common/util.js';\nimport IgcIconComponent from '../icon/icon.js';\nimport IgcTextareaComponent from '../textarea/textarea.js';\nimport type { ChatState } from './chat-state.js';\nimport { styles } from './themes/input.base.css.js';\nimport { all } from './themes/input.js';\nimport { styles as shared } from './themes/shared/input/input.common.css.js';\nimport type { ChatTemplateRenderer, IgcMessageAttachment } from './types.js';\nimport { getChatAcceptedFiles, getIconName } from './utils.js';\n\ntype DefaultInputRenderers = {\n input: ChatTemplateRenderer<string>;\n inputActions: ChatTemplateRenderer<void>;\n inputAttachments: ChatTemplateRenderer<IgcMessageAttachment[]>;\n fileUploadButton: ChatTemplateRenderer<void>;\n sendButton: ChatTemplateRenderer<void>;\n};\n/**\n * A web component that provides the input area for the `igc-chat` interface.\n *\n * It supports:\n * - Text input with automatic resizing\n * - Sending messages on Enter key (with Shift+Enter for newlines)\n * - File attachments via file picker or drag-and-drop\n * - Customizable templates for send button, attachments, and text input\n * - Emits various chat-related events (typing, input focus/blur, attachment drop, etc.)\n *\n * @element igc-chat-input\n *\n * @slot - Default unnamed slot for rendering inside the component\n * @fires igcTypingChange - Fired when the user starts/stops typing\n * @fires igcInputFocus - Fired when the input area receives focus\n * @fires igcInputBlur - Fired when the input area loses focus\n * @fires igcAttachmentDrag - Fired when dragging a file over the input\n * @fires igcAttachmentDrop - Fired when a file is dropped into the input\n * @fires igcChange - Fired when file input changes (delegated from `<igc-file-input>`)\n *\n * @csspart input-container - Container for the input section\n * @csspart input-wrapper - Wrapper around the text input\n * @csspart text-input - The `<igc-textarea>` component\n * @csspart buttons-container - Container for file upload/send buttons\n * @csspart send-button - The send icon button\n * @csspart attachments - Container for rendering attachments\n * @csspart attachment-wrapper - Wrapper for individual attachment\n * @csspart attachment-name - Display name of an attachment\n */\nexport default class IgcChatInputComponent extends LitElement {\n public static readonly tagName = 'igc-chat-input';\n public static override styles = [styles, shared];\n\n /* blazorSuppress */\n public static register(): void {\n registerComponent(\n IgcChatInputComponent,\n IgcTextareaComponent,\n IgcIconButtonComponent,\n IgcChipComponent,\n IgcIconComponent\n );\n }\n\n @consume({ context: chatContext, subscribe: true })\n private readonly _state!: ChatState;\n\n @consume({ context: chatUserInputContext, subscribe: true })\n private readonly _userInputState!: ChatState;\n\n @query(IgcTextareaComponent.tagName)\n private readonly _textInputElement!: IgcTextareaComponent;\n\n @query('#input_attachments')\n protected readonly _fileInput!: HTMLInputElement;\n\n @state()\n private _parts = { 'input-container': true, dragging: false };\n\n private get _acceptedTypes() {\n return this._state.acceptedFileTypes;\n }\n\n private readonly _defaults: Readonly<DefaultInputRenderers> = Object.freeze({\n input: () => this._renderTextArea(),\n inputActions: () => this.renderActionsArea(),\n inputAttachments: (ctx) => this.renderAttachmentsArea(ctx.param),\n fileUploadButton: () => this._renderFileUploadButton(),\n sendButton: () => this._renderSendButton(),\n });\n\n constructor() {\n super();\n addThemingController(this, all);\n }\n\n protected override firstUpdated() {\n this._state.updateAcceptedTypesCache();\n this._state.textArea = this._textInputElement;\n }\n\n private _getRenderer(\n name: keyof DefaultInputRenderers\n ): ChatTemplateRenderer<any> {\n return this._state.options?.renderers\n ? (this._state.options.renderers[name] ?? this._defaults[name])\n : this._defaults[name];\n }\n\n private _handleKeydown(event: KeyboardEvent): void {\n const isSend = event.key === enterKey && !event.shiftKey;\n\n if (isSend) {\n event.preventDefault();\n this._state.sendMessage();\n } else {\n // TODO:\n this._state.handleKeyDown(event);\n }\n }\n\n private _handleFileInputClick(): void {\n this._fileInput.showPicker();\n }\n\n private _handleFocusState(event: FocusEvent): void {\n this._state.emitEvent(\n event.type === 'focus' ? 'igcInputFocus' : 'igcInputBlur'\n );\n }\n\n private _handleDragEnter(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const validFiles = getChatAcceptedFiles(event, this._acceptedTypes);\n this._parts = { 'input-container': true, dragging: !isEmpty(validFiles) };\n this._state.emitEvent('igcAttachmentDrag');\n }\n\n private _handleDragOver(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n }\n\n private _handleDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n // Check if we're actually leaving the container\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n const x = event.clientX;\n const y = event.clientY;\n\n if (\n x <= rect.left ||\n x >= rect.right ||\n y <= rect.top ||\n y >= rect.bottom\n ) {\n this._parts = { 'input-container': true, dragging: false };\n }\n }\n\n private _handleDrop(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this._parts = { 'input-container': true, dragging: false };\n\n const validFiles = getChatAcceptedFiles(event, this._acceptedTypes);\n this._state.emitEvent('igcAttachmentDrop');\n this._state.attachFiles(validFiles);\n this.requestUpdate();\n }\n\n /**\n * Handles input text changes.\n * Updates internal inputValue and emits 'igcInputChange' event.\n * @param e Input event from the text area\n */\n private _handleInput({ detail }: CustomEvent<string>): void {\n if (detail === this._state.inputValue) return;\n\n this._state.inputValue = detail;\n this._state.emitEvent('igcInputChange', { detail: { value: detail } });\n }\n\n private _handleFileUpload(event: Event): void {\n const input = event.target as HTMLInputElement;\n\n if (hasFiles(input)) {\n this._state.attachFiles(Array.from(input.files!));\n }\n }\n /**\n * Default attachments area template used when no custom template is provided.\n * Renders the list of input attachments as chips.\n * @returns TemplateResult containing the attachments area\n */\n private renderAttachmentsArea(attachments: IgcMessageAttachment[]) {\n return html`${attachments?.map(\n (attachment, index) => html`\n <div part=\"attachment-wrapper\" role=\"listitem\">\n <igc-chip\n removable\n @igcRemove=${() => this._state.removeAttachment(index)}\n >\n <igc-icon\n slot=\"prefix\"\n name=${getIconName(attachment.file?.type ?? attachment.type)}\n ></igc-icon>\n <span part=\"attachment-name\">${attachment.name}</span>\n </igc-chip>\n </div>\n `\n )} `;\n }\n\n /**\n * Default text area template used when no custom template is provided.\n * Renders a text area for user input.\n * @returns TemplateResult containing the text area\n */\n private _renderTextArea() {\n return html`\n <igc-textarea\n part=\"text-input\"\n placeholder=${ifDefined(this._state.options?.inputPlaceholder)}\n resize=\"auto\"\n rows=\"1\"\n .value=${this._userInputState?.inputValue}\n @igcInput=${this._handleInput}\n @keydown=${this._handleKeydown}\n @focus=${this._handleFocusState}\n @blur=${this._handleFocusState}\n ></igc-textarea>\n `;\n }\n\n /**\n * Default file upload button template used when no custom template is provided.\n * Renders a file input for attaching files.\n * @returns TemplateResult containing the file upload button\n */\n private _renderFileUploadButton() {\n const accepted = this._state.options?.acceptedFiles;\n const attachmentsDisabled = this._state.options?.disableInputAttachments;\n\n return html`${cache(\n attachmentsDisabled\n ? nothing\n : html`\n <label for=\"input_attachments\" part=\"upload-button\">\n <igc-icon-button\n variant=\"flat\"\n name=\"attach_file\"\n @click=${this._handleFileInputClick}\n ></igc-icon-button>\n <input\n type=\"file\"\n id=\"input_attachments\"\n name=\"input_attachments\"\n multiple\n accept=${bindIf(accepted, accepted)}\n @change=${this._handleFileUpload}\n />\n </label>\n `\n )}`;\n }\n\n /**\n * Default send button template used when no custom template is provided.\n * Renders a send button that submits the current input value and attachments.\n * @returns TemplateResult containing the send button\n */\n private _renderSendButton() {\n const enabled =\n this._state.hasInputValue || this._state.hasInputAttachments;\n\n return html`\n <igc-icon-button\n aria-label=\"Send message\"\n name=\"send_message\"\n variant=\"contained\"\n part=\"send-button\"\n ?disabled=${!enabled}\n @click=${this._state.sendMessage}\n ></igc-icon-button>\n `;\n }\n\n private renderActionsArea() {\n return html` ${this._getRenderer('fileUploadButton')({\n param: undefined,\n defaults: this._defaults,\n options: this._state.options,\n })}\n ${this._getRenderer('sendButton')({\n param: undefined,\n defaults: this._defaults,\n options: this._state.options,\n })}`;\n }\n\n protected override render() {\n const partialCtx = {\n defaults: this._defaults,\n options: this._state.options,\n };\n\n return html`\n <div\n part=${partMap(this._parts)}\n @dragenter=${this._handleDragEnter}\n @dragover=${this._handleDragOver}\n @dragleave=${this._handleDragLeave}\n @drop=${this._handleDrop}\n >\n ${this._state.inputAttachments &&\n this._state.inputAttachments.length > 0\n ? html` <div part=\"attachments\" role=\"list\" aria-label=\"Attachments\">\n ${until(\n this._getRenderer('inputAttachments')({\n ...partialCtx,\n param: this._state.inputAttachments,\n })\n )}\n </div>`\n : nothing}\n <div part=\"input-wrapper\">\n ${until(\n this._getRenderer('input')({\n ...partialCtx,\n param: this._state.inputValue,\n })\n )}\n </div>\n <div part=\"buttons-container\">\n ${until(\n this._getRenderer('inputActions')({\n ...partialCtx,\n param: undefined,\n })\n )}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'igc-chat-input': IgcChatInputComponent;\n }\n}\n"]}
1
+ {"version":3,"file":"chat-input.js","sourceRoot":"","sources":["../../../src/components/chat/chat-input.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { query, state } from 'lit/decorators.js';\nimport { cache } from 'lit/directives/cache.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { until } from 'lit/directives/until.js';\nimport { addThemingController } from '../../theming/theming-controller.js';\nimport IgcIconButtonComponent from '../button/icon-button.js';\nimport IgcChipComponent from '../chip/chip.js';\nimport { chatContext, chatUserInputContext } from '../common/context.js';\nimport { enterKey } from '../common/controllers/key-bindings.js';\nimport { registerComponent } from '../common/definitions/register.js';\nimport { partMap } from '../common/part-map.js';\nimport { bindIf, hasFiles, isEmpty } from '../common/util.js';\nimport IgcIconComponent from '../icon/icon.js';\nimport IgcTextareaComponent from '../textarea/textarea.js';\nimport type { ChatState } from './chat-state.js';\nimport { styles } from './themes/input.base.css.js';\nimport { all } from './themes/input.js';\nimport { styles as shared } from './themes/shared/input/input.common.css.js';\nimport type {\n ChatRendererContext,\n ChatTemplateRenderer,\n IgcMessageAttachment,\n InputRendererContext,\n} from './types.js';\nimport { getChatAcceptedFiles, getIconName } from './utils.js';\n\ntype DefaultInputRenderers = {\n input: ChatTemplateRenderer<InputRendererContext>;\n inputActions: ChatTemplateRenderer<ChatRendererContext>;\n inputAttachments: ChatTemplateRenderer<InputRendererContext>;\n fileUploadButton: ChatTemplateRenderer<ChatRendererContext>;\n sendButton: ChatTemplateRenderer<ChatRendererContext>;\n};\n/**\n * A web component that provides the input area for the `igc-chat` interface.\n *\n * It supports:\n * - Text input with automatic resizing\n * - Sending messages on Enter key (with Shift+Enter for newlines)\n * - File attachments via file picker or drag-and-drop\n * - Customizable templates for send button, attachments, and text input\n * - Emits various chat-related events (typing, input focus/blur, attachment drop, etc.)\n *\n * @element igc-chat-input\n *\n * @slot - Default unnamed slot for rendering inside the component\n * @fires igcTypingChange - Fired when the user starts/stops typing\n * @fires igcInputFocus - Fired when the input area receives focus\n * @fires igcInputBlur - Fired when the input area loses focus\n * @fires igcAttachmentDrag - Fired when dragging a file over the input\n * @fires igcAttachmentDrop - Fired when a file is dropped into the input\n * @fires igcChange - Fired when file input changes (delegated from `<igc-file-input>`)\n *\n * @csspart input-container - Container for the input section\n * @csspart input-wrapper - Wrapper around the text input\n * @csspart text-input - The `<igc-textarea>` component\n * @csspart buttons-container - Container for file upload/send buttons\n * @csspart send-button - The send icon button\n * @csspart attachments - Container for rendering attachments\n * @csspart attachment-wrapper - Wrapper for individual attachment\n * @csspart attachment-name - Display name of an attachment\n */\nexport default class IgcChatInputComponent extends LitElement {\n public static readonly tagName = 'igc-chat-input';\n public static override styles = [styles, shared];\n\n /* blazorSuppress */\n public static register(): void {\n registerComponent(\n IgcChatInputComponent,\n IgcTextareaComponent,\n IgcIconButtonComponent,\n IgcChipComponent,\n IgcIconComponent\n );\n }\n\n private readonly _defaults: Readonly<DefaultInputRenderers> = Object.freeze({\n fileUploadButton: () => this._renderFileUploadButton(),\n input: () => this._renderTextArea(),\n inputActions: () => this._renderActionsArea(),\n inputAttachments: (ctx) => this._renderAttachmentsArea(ctx.attachments),\n sendButton: () => this._renderSendButton(),\n });\n\n @consume({ context: chatContext, subscribe: true })\n private readonly _state!: ChatState;\n\n @consume({ context: chatUserInputContext, subscribe: true })\n private readonly _userInputState!: ChatState;\n\n @query(IgcTextareaComponent.tagName)\n private readonly _textInputElement!: IgcTextareaComponent;\n\n @query('#input_attachments')\n protected readonly _fileInput!: HTMLInputElement;\n\n @state()\n private _parts = { 'input-container': true, dragging: false };\n\n private get _acceptedTypes() {\n return this._state.acceptedFileTypes;\n }\n\n constructor() {\n super();\n addThemingController(this, all);\n }\n\n protected override firstUpdated() {\n this._state.updateAcceptedTypesCache();\n this._state.textArea = this._textInputElement;\n }\n\n private _getRenderer<U extends keyof DefaultInputRenderers>(\n name: U\n ): DefaultInputRenderers[U] {\n return this._state.options?.renderers\n ? ((this._state.options.renderers[name] ??\n this._defaults[name]) as DefaultInputRenderers[U])\n : this._defaults[name];\n }\n\n private _handleKeydown(event: KeyboardEvent): void {\n const isSend = event.key === enterKey && !event.shiftKey;\n\n if (isSend) {\n event.preventDefault();\n this._state.sendMessage();\n } else {\n // TODO:\n this._state.handleKeyDown(event);\n }\n }\n\n private _handleFileInputClick(): void {\n this._fileInput.showPicker();\n }\n\n private _handleFocusState(event: FocusEvent): void {\n this._state.emitEvent(\n event.type === 'focus' ? 'igcInputFocus' : 'igcInputBlur'\n );\n }\n\n private _handleDragEnter(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n const validFiles = getChatAcceptedFiles(event, this._acceptedTypes);\n this._parts = { 'input-container': true, dragging: !isEmpty(validFiles) };\n this._state.emitEvent('igcAttachmentDrag');\n }\n\n private _handleDragOver(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n }\n\n private _handleDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n // Check if we're actually leaving the container\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n const x = event.clientX;\n const y = event.clientY;\n\n if (\n x <= rect.left ||\n x >= rect.right ||\n y <= rect.top ||\n y >= rect.bottom\n ) {\n this._parts = { 'input-container': true, dragging: false };\n }\n }\n\n private _handleDrop(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this._parts = { 'input-container': true, dragging: false };\n\n const validFiles = getChatAcceptedFiles(event, this._acceptedTypes);\n this._state.emitEvent('igcAttachmentDrop');\n this._state.attachFiles(validFiles);\n this.requestUpdate();\n }\n\n /**\n * Handles input text changes.\n * Updates internal inputValue and emits 'igcInputChange' event.\n * @param e Input event from the text area\n */\n private _handleInput({ detail }: CustomEvent<string>): void {\n if (detail === this._state.inputValue) return;\n\n this._state.inputValue = detail;\n this._state.emitEvent('igcInputChange', { detail: { value: detail } });\n }\n\n private _handleFileUpload(event: Event): void {\n const input = event.target as HTMLInputElement;\n\n if (hasFiles(input)) {\n this._state.attachFiles(Array.from(input.files!));\n }\n }\n /**\n * Default attachments area template used when no custom template is provided.\n * Renders the list of input attachments as chips.\n * @returns TemplateResult containing the attachments area\n */\n private _renderAttachmentsArea(attachments: IgcMessageAttachment[]) {\n return html`${attachments?.map(\n (attachment, index) => html`\n <div part=\"attachment-wrapper\" role=\"listitem\">\n <igc-chip\n removable\n @igcRemove=${() => this._state.removeAttachment(index)}\n >\n <igc-icon\n slot=\"prefix\"\n name=${getIconName(attachment.file?.type ?? attachment.type)}\n ></igc-icon>\n <span part=\"attachment-name\">${attachment.name}</span>\n </igc-chip>\n </div>\n `\n )} `;\n }\n\n /**\n * Default text area template used when no custom template is provided.\n * Renders a text area for user input.\n * @returns TemplateResult containing the text area\n */\n private _renderTextArea() {\n return html`\n <igc-textarea\n part=\"text-input\"\n aria-label=\"Chat text input\"\n placeholder=${ifDefined(this._state.options?.inputPlaceholder)}\n resize=\"auto\"\n rows=\"1\"\n .value=${this._userInputState?.inputValue}\n @igcInput=${this._handleInput}\n @keydown=${this._handleKeydown}\n @focus=${this._handleFocusState}\n @blur=${this._handleFocusState}\n ></igc-textarea>\n `;\n }\n\n /**\n * Default file upload button template used when no custom template is provided.\n * Renders a file input for attaching files.\n * @returns TemplateResult containing the file upload button\n */\n private _renderFileUploadButton() {\n const accepted = this._state.options?.acceptedFiles;\n const attachmentsDisabled = this._state.options?.disableInputAttachments;\n\n return html`${cache(\n attachmentsDisabled\n ? nothing\n : html`\n <label for=\"input_attachments\" part=\"upload-button\">\n <igc-icon-button\n aria-label=\"Attach files\"\n variant=\"flat\"\n name=\"attach_file\"\n @click=${this._handleFileInputClick}\n ></igc-icon-button>\n <input\n type=\"file\"\n id=\"input_attachments\"\n name=\"input_attachments\"\n aria-label=\"Upload button\"\n multiple\n accept=${bindIf(accepted, accepted)}\n @change=${this._handleFileUpload}\n />\n </label>\n `\n )}`;\n }\n\n /**\n * Default send button template used when no custom template is provided.\n * Renders a send button that submits the current input value and attachments.\n * @returns TemplateResult containing the send button\n */\n private _renderSendButton() {\n const enabled =\n this._state.hasInputValue || this._state.hasInputAttachments;\n\n return html`\n <igc-icon-button\n aria-label=\"Send message\"\n name=\"send_message\"\n variant=\"contained\"\n part=\"send-button\"\n ?disabled=${!enabled}\n @click=${this._state.sendMessage}\n ></igc-icon-button>\n `;\n }\n\n private _renderActionsArea() {\n const ctx: ChatRendererContext = {\n defaults: this._defaults,\n instance: this._state.host,\n };\n\n return html`\n ${this._getRenderer('fileUploadButton')(ctx)}\n ${this._getRenderer('sendButton')(ctx)}\n `;\n }\n\n protected override render() {\n const ctx: ChatRendererContext = {\n defaults: this._defaults,\n instance: this._state.host,\n };\n\n const inputCtx: InputRendererContext = {\n ...ctx,\n attachments: this._state.inputAttachments,\n value: this._state.inputValue,\n };\n\n return html`\n <div\n part=${partMap(this._parts)}\n @dragenter=${this._handleDragEnter}\n @dragover=${this._handleDragOver}\n @dragleave=${this._handleDragLeave}\n @drop=${this._handleDrop}\n >\n ${this._state.hasInputAttachments\n ? html`\n <div part=\"attachments\" role=\"list\" aria-label=\"Attachments\">\n ${until(this._getRenderer('inputAttachments')(inputCtx))}\n </div>\n `\n : nothing}\n\n <div part=\"input-wrapper\">\n ${until(this._getRenderer('input')(inputCtx))}\n </div>\n\n <div part=\"buttons-container\">\n ${until(this._getRenderer('inputActions')(ctx))}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'igc-chat-input': IgcChatInputComponent;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { LitElement, nothing } from 'lit';
1
+ import { LitElement } from 'lit';
2
2
  import type { IgcMessage } from './types.js';
3
3
  /**
4
4
  * A chat message component for displaying individual messages in `<igc-chat>`.
@@ -22,11 +22,8 @@ export default class IgcChatMessageComponent extends LitElement {
22
22
  static readonly tagName = "igc-chat-message";
23
23
  static styles: import("lit").CSSResult[];
24
24
  static register(): void;
25
- /**
26
- * Injected chat state context. Provides message data, user info, and options.
27
- */
28
- private readonly _state;
29
25
  private readonly _defaults;
26
+ private readonly _state;
30
27
  /**
31
28
  * The chat message to render.
32
29
  */
@@ -40,20 +37,8 @@ export default class IgcChatMessageComponent extends LitElement {
40
37
  private _renderActions;
41
38
  private _renderActionButton;
42
39
  private _renderAttachments;
43
- /**
44
- * Default message template used when no custom template is provided.
45
- * Renders the message text, sanitized for security.
46
- * @param message The chat message to render
47
- * @returns TemplateResult containing the rendered message
48
- */
49
40
  private _renderMessage;
50
- /**
51
- * Renders the chat message template.
52
- * - Applies 'sent' CSS class if the message sender matches current user.
53
- * - Uses markdown rendering if configured.
54
- * - Renders attachments and custom templates if provided.
55
- */
56
- protected render(): typeof nothing | import("lit-html").TemplateResult<1>;
41
+ protected render(): import("lit-html").TemplateResult<1>;
57
42
  }
58
43
  declare global {
59
44
  interface HTMLElementTagNameMap {
@@ -7,9 +7,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { consume } from '@lit/context';
8
8
  import { html, LitElement, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ import { cache } from 'lit/directives/cache.js';
10
11
  import { until } from 'lit/directives/until.js';
11
12
  import { addThemingController } from '../../theming/theming-controller.js';
12
- import IgcAvatarComponent from '../avatar/avatar.js';
13
+ import IgcIconButtonComponent from '../button/icon-button.js';
13
14
  import { chatContext } from '../common/context.js';
14
15
  import { registerComponent } from '../common/definitions/register.js';
15
16
  import { partMap } from '../common/part-map.js';
@@ -24,9 +25,11 @@ const LIKE_INACTIVE = 'thumb_up_inactive';
24
25
  const LIKE_ACTIVE = 'thumb_up_active';
25
26
  const DISLIKE_INACTIVE = 'thumb_down_inactive';
26
27
  const DISLIKE_ACTIVE = 'thumb_down_active';
27
- class IgcChatMessageComponent extends LitElement {
28
+ export default class IgcChatMessageComponent extends LitElement {
29
+ static { this.tagName = 'igc-chat-message'; }
30
+ static { this.styles = [styles, shared]; }
28
31
  static register() {
29
- registerComponent(IgcChatMessageComponent, IgcMessageAttachmentsComponent, IgcAvatarComponent, IgcTooltipComponent);
32
+ registerComponent(IgcChatMessageComponent, IgcMessageAttachmentsComponent, IgcIconButtonComponent, IgcTooltipComponent);
30
33
  }
31
34
  constructor() {
32
35
  super();
@@ -49,7 +52,7 @@ class IgcChatMessageComponent extends LitElement {
49
52
  }
50
53
  _handleMessageActionClick(event) {
51
54
  const targetButton = event.target;
52
- const button = targetButton.closest('igc-icon-button');
55
+ const button = targetButton.closest(IgcIconButtonComponent.tagName);
53
56
  if (!button)
54
57
  return;
55
58
  let reaction = button.getAttribute('name');
@@ -83,10 +86,11 @@ class IgcChatMessageComponent extends LitElement {
83
86
  _renderActions() {
84
87
  const isSent = this.message?.sender === this._state.currentUserId;
85
88
  const hasText = this.message?.text.trim();
89
+ const hasAttachments = this.message?.attachments && !isEmpty(this.message?.attachments);
86
90
  const isTyping = this._state._isTyping;
87
91
  const isLastMessage = this.message === this._state.messages.at(-1);
88
92
  const resourceStrings = this._state.resourceStrings;
89
- if (isSent || !hasText || (isLastMessage && isTyping)) {
93
+ if (isSent || !(hasText || hasAttachments) || (isLastMessage && isTyping)) {
90
94
  return nothing;
91
95
  }
92
96
  return html `
@@ -128,39 +132,33 @@ class IgcChatMessageComponent extends LitElement {
128
132
  : nothing;
129
133
  }
130
134
  render() {
131
- if (!this.message) {
132
- return nothing;
133
- }
135
+ const ctx = {
136
+ message: this.message,
137
+ defaults: this._defaults,
138
+ instance: this._state.host,
139
+ };
134
140
  const parts = {
135
141
  'message-container': true,
136
142
  sent: this._state.isCurrentUserMessage(this.message),
137
143
  };
138
- const options = this._state.options;
139
- const ctx = {
140
- param: this.message,
141
- defaults: this._defaults,
142
- options,
143
- };
144
- if (options?.renderers?.message) {
145
- return html `
146
- <div part=${partMap(parts)}>
147
- ${until(options.renderers.message(ctx))}
148
- </div>
149
- `;
150
- }
151
144
  return html `
152
- <div part=${partMap(parts)}>
153
- ${until(this._getRenderer('messageHeader')(ctx))}
154
- ${until(this._getRenderer('messageContent')(ctx))}
155
- ${until(this._getRenderer('messageAttachments')(ctx))}
156
- ${until(this._getRenderer('messageActions')(ctx))}
157
- </div>
145
+ ${cache(this.message
146
+ ? html `
147
+ <div part=${partMap(parts)}>
148
+ ${cache(this._state.options?.renderers?.message
149
+ ? html `${until(this._getRenderer('message')(ctx))}`
150
+ : html `
151
+ ${until(this._getRenderer('messageHeader')(ctx))}
152
+ ${until(this._getRenderer('messageContent')(ctx))}
153
+ ${until(this._getRenderer('messageAttachments')(ctx))}
154
+ ${until(this._getRenderer('messageActions')(ctx))}
155
+ `)}
156
+ </div>
157
+ `
158
+ : nothing)}
158
159
  `;
159
160
  }
160
161
  }
161
- IgcChatMessageComponent.tagName = 'igc-chat-message';
162
- IgcChatMessageComponent.styles = [styles, shared];
163
- export default IgcChatMessageComponent;
164
162
  __decorate([
165
163
  consume({ context: chatContext, subscribe: true })
166
164
  ], IgcChatMessageComponent.prototype, "_state", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message.js","sourceRoot":"","sources":["../../../src/components/chat/chat-message.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { until } from 'lit/directives/until.js';\nimport { addThemingController } from '../../theming/theming-controller.js';\nimport IgcAvatarComponent from '../avatar/avatar.js';\nimport { chatContext } from '../common/context.js';\nimport { registerComponent } from '../common/definitions/register.js';\nimport { partMap } from '../common/part-map.js';\nimport { isEmpty } from '../common/util.js';\nimport IgcTooltipComponent from '../tooltip/tooltip.js';\nimport type { ChatState } from './chat-state.js';\nimport IgcMessageAttachmentsComponent from './message-attachments.js';\nimport { styles } from './themes/message.base.css.js';\nimport { all } from './themes/message.js';\nimport { styles as shared } from './themes/shared/chat-message/chat-message.common.css.js';\nimport type { ChatTemplateRenderer, IgcMessage } from './types.js';\nimport { chatMessageAdoptPageStyles, showChatActionsTooltip } from './utils.js';\n\nconst LIKE_INACTIVE = 'thumb_up_inactive';\nconst LIKE_ACTIVE = 'thumb_up_active';\nconst DISLIKE_INACTIVE = 'thumb_down_inactive';\nconst DISLIKE_ACTIVE = 'thumb_down_active';\n\ntype DefaultMessageRenderers = {\n message: ChatTemplateRenderer<IgcMessage>;\n messageHeader: ChatTemplateRenderer<IgcMessage>;\n messageContent: ChatTemplateRenderer<IgcMessage>;\n messageAttachments: ChatTemplateRenderer<IgcMessage>;\n messageActions: ChatTemplateRenderer<IgcMessage>;\n};\n\n/**\n * A chat message component for displaying individual messages in `<igc-chat>`.\n *\n * @element igc-chat-message\n *\n * @fires igcMessageReact - Fired when a message is reacted to.\n *\n * This component renders a single chat message including:\n * - Message text (sanitized)\n * - Attachments (if any)\n * - Custom templates for message content and actions (if provided via chat options)\n *\n * It distinguishes sent messages from received messages by comparing\n * the message sender with the current user ID from chat state.\n *\n * The message text is sanitized with DOMPurify before rendering,\n * and can be rendered with a markdown renderer if provided.\n */\nexport default class IgcChatMessageComponent extends LitElement {\n public static readonly tagName = 'igc-chat-message';\n public static override styles = [styles, shared];\n\n /* blazorSuppress */\n public static register(): void {\n registerComponent(\n IgcChatMessageComponent,\n IgcMessageAttachmentsComponent,\n IgcAvatarComponent,\n IgcTooltipComponent\n );\n }\n\n /**\n * Injected chat state context. Provides message data, user info, and options.\n */\n @consume({ context: chatContext, subscribe: true })\n private readonly _state!: ChatState;\n\n private readonly _defaults = Object.freeze<DefaultMessageRenderers>({\n message: () => this._renderMessage(),\n messageHeader: () => this._renderHeader(),\n messageContent: () => this._renderContent(),\n messageAttachments: () => this._renderAttachments(),\n messageActions: () => this._renderActions(),\n });\n\n /**\n * The chat message to render.\n */\n @property({ attribute: false })\n public message?: IgcMessage;\n\n constructor() {\n super();\n addThemingController(this, all);\n }\n\n protected override firstUpdated(): void {\n chatMessageAdoptPageStyles(this);\n }\n\n private _getRenderer(name: keyof DefaultMessageRenderers) {\n return this._state.options?.renderers\n ? (this._state.options.renderers[name] ?? this._defaults[name])\n : this._defaults[name];\n }\n\n private _handleMessageActionClick(event: PointerEvent): void {\n const targetButton = event.target as HTMLElement;\n const button = targetButton.closest('igc-icon-button');\n if (!button) return;\n\n let reaction = button.getAttribute('name');\n if (this.message) {\n if (reaction === LIKE_INACTIVE) {\n reaction = LIKE_ACTIVE;\n this.message.reactions = [reaction];\n } else if (reaction === DISLIKE_INACTIVE) {\n reaction = DISLIKE_ACTIVE;\n this.message.reactions = [reaction];\n } else if (reaction === this.message.reactions?.[0]) {\n reaction = null;\n this.message.reactions = [];\n }\n\n this.requestUpdate();\n }\n\n this._state.emitEvent('igcMessageReact', {\n detail: { message: this.message, reaction },\n });\n }\n\n private _renderHeader() {\n return nothing;\n }\n\n private _renderContent() {\n return this.message?.text\n ? html`<pre part=\"plain-text\">${this.message.text}</pre>`\n : nothing;\n }\n\n private _renderActions() {\n const isSent = this.message?.sender === this._state.currentUserId;\n const hasText = this.message?.text.trim();\n const isTyping = this._state._isTyping;\n const isLastMessage = this.message === this._state.messages.at(-1);\n const resourceStrings = this._state.resourceStrings!;\n\n if (isSent || !hasText || (isLastMessage && isTyping)) {\n return nothing;\n }\n\n return html`\n <div @click=${this._handleMessageActionClick}>\n ${this._renderActionButton(\n 'copy_content',\n resourceStrings.reactionCopy\n )}\n ${this._renderActionButton(\n this.message?.reactions?.includes(LIKE_ACTIVE)\n ? LIKE_ACTIVE\n : LIKE_INACTIVE,\n resourceStrings.reactionLike\n )}\n ${this._renderActionButton(\n this.message?.reactions?.includes(DISLIKE_ACTIVE)\n ? DISLIKE_ACTIVE\n : DISLIKE_INACTIVE,\n resourceStrings.reactionDislike\n )}\n ${this._renderActionButton(\n 'regenerate',\n resourceStrings.reactionRegenerate\n )}\n </div>\n `;\n }\n\n private _renderActionButton(name: string, tooltipMessage: string) {\n return html`\n <igc-icon-button\n id=${`${name}-button`}\n name=${name}\n variant=\"flat\"\n @pointerenter=${({ target }: PointerEvent) =>\n showChatActionsTooltip(target as Element, tooltipMessage)}\n @focus=${({ target }: FocusEvent) =>\n showChatActionsTooltip(target as Element, tooltipMessage)}\n ></igc-icon-button>\n `;\n }\n\n // Default rendering logic for attachments\n private _renderAttachments() {\n return isEmpty(this.message?.attachments ?? [])\n ? nothing\n : html`\n <igc-message-attachments\n .message=${this.message}\n ></igc-message-attachments>\n `;\n }\n\n /**\n * Default message template used when no custom template is provided.\n * Renders the message text, sanitized for security.\n * @param message The chat message to render\n * @returns TemplateResult containing the rendered message\n */\n private _renderMessage() {\n return this.message\n ? html`${this._renderHeader()}${this._renderContent()}${this._renderAttachments()}${this._renderActions()}`\n : nothing;\n }\n\n /**\n * Renders the chat message template.\n * - Applies 'sent' CSS class if the message sender matches current user.\n * - Uses markdown rendering if configured.\n * - Renders attachments and custom templates if provided.\n */\n protected override render() {\n if (!this.message) {\n return nothing;\n }\n\n const parts = {\n 'message-container': true,\n sent: this._state.isCurrentUserMessage(this.message),\n };\n\n const options = this._state.options;\n const ctx = {\n param: this.message,\n defaults: this._defaults,\n options,\n };\n\n if (options?.renderers?.message) {\n return html`\n <div part=${partMap(parts)}>\n ${until(options.renderers.message(ctx))}\n </div>\n `;\n }\n\n return html`\n <div part=${partMap(parts)}>\n ${until(this._getRenderer('messageHeader')(ctx))}\n ${until(this._getRenderer('messageContent')(ctx))}\n ${until(this._getRenderer('messageAttachments')(ctx))}\n ${until(this._getRenderer('messageActions')(ctx))}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'igc-chat-message': IgcChatMessageComponent;\n }\n}\n"]}
1
+ {"version":3,"file":"chat-message.js","sourceRoot":"","sources":["../../../src/components/chat/chat-message.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { cache } from 'lit/directives/cache.js';\nimport { until } from 'lit/directives/until.js';\nimport { addThemingController } from '../../theming/theming-controller.js';\nimport IgcIconButtonComponent from '../button/icon-button.js';\nimport { chatContext } from '../common/context.js';\nimport { registerComponent } from '../common/definitions/register.js';\nimport { partMap } from '../common/part-map.js';\nimport { isEmpty } from '../common/util.js';\nimport IgcTooltipComponent from '../tooltip/tooltip.js';\nimport type { ChatState } from './chat-state.js';\nimport IgcMessageAttachmentsComponent from './message-attachments.js';\nimport { styles } from './themes/message.base.css.js';\nimport { all } from './themes/message.js';\nimport { styles as shared } from './themes/shared/chat-message/chat-message.common.css.js';\nimport type {\n ChatTemplateRenderer,\n IgcMessage,\n MessageRendererContext,\n} from './types.js';\nimport { chatMessageAdoptPageStyles, showChatActionsTooltip } from './utils.js';\n\nconst LIKE_INACTIVE = 'thumb_up_inactive';\nconst LIKE_ACTIVE = 'thumb_up_active';\nconst DISLIKE_INACTIVE = 'thumb_down_inactive';\nconst DISLIKE_ACTIVE = 'thumb_down_active';\n\ntype DefaultMessageRenderers = {\n message: ChatTemplateRenderer<MessageRendererContext>;\n messageHeader: ChatTemplateRenderer<MessageRendererContext>;\n messageContent: ChatTemplateRenderer<MessageRendererContext>;\n messageAttachments: ChatTemplateRenderer<MessageRendererContext>;\n messageActions: ChatTemplateRenderer<MessageRendererContext>;\n};\n\n/**\n * A chat message component for displaying individual messages in `<igc-chat>`.\n *\n * @element igc-chat-message\n *\n * @fires igcMessageReact - Fired when a message is reacted to.\n *\n * This component renders a single chat message including:\n * - Message text (sanitized)\n * - Attachments (if any)\n * - Custom templates for message content and actions (if provided via chat options)\n *\n * It distinguishes sent messages from received messages by comparing\n * the message sender with the current user ID from chat state.\n *\n * The message text is sanitized with DOMPurify before rendering,\n * and can be rendered with a markdown renderer if provided.\n */\nexport default class IgcChatMessageComponent extends LitElement {\n public static readonly tagName = 'igc-chat-message';\n public static override styles = [styles, shared];\n\n /* blazorSuppress */\n public static register(): void {\n registerComponent(\n IgcChatMessageComponent,\n IgcMessageAttachmentsComponent,\n IgcIconButtonComponent,\n IgcTooltipComponent\n );\n }\n\n private readonly _defaults = Object.freeze<DefaultMessageRenderers>({\n message: () => this._renderMessage(),\n messageHeader: () => this._renderHeader(),\n messageContent: () => this._renderContent(),\n messageAttachments: () => this._renderAttachments(),\n messageActions: () => this._renderActions(),\n });\n\n @consume({ context: chatContext, subscribe: true })\n private readonly _state!: ChatState;\n\n /**\n * The chat message to render.\n */\n @property({ attribute: false })\n public message?: IgcMessage;\n\n constructor() {\n super();\n addThemingController(this, all);\n }\n\n protected override firstUpdated(): void {\n chatMessageAdoptPageStyles(this);\n }\n\n private _getRenderer(name: keyof DefaultMessageRenderers) {\n return this._state.options?.renderers\n ? (this._state.options.renderers[name] ?? this._defaults[name])\n : this._defaults[name];\n }\n\n private _handleMessageActionClick(event: PointerEvent): void {\n const targetButton = event.target as HTMLElement;\n const button = targetButton.closest(IgcIconButtonComponent.tagName);\n if (!button) return;\n\n let reaction = button.getAttribute('name');\n if (this.message) {\n if (reaction === LIKE_INACTIVE) {\n reaction = LIKE_ACTIVE;\n this.message.reactions = [reaction];\n } else if (reaction === DISLIKE_INACTIVE) {\n reaction = DISLIKE_ACTIVE;\n this.message.reactions = [reaction];\n } else if (reaction === this.message.reactions?.[0]) {\n reaction = null;\n this.message.reactions = [];\n }\n\n this.requestUpdate();\n }\n\n this._state.emitEvent('igcMessageReact', {\n detail: { message: this.message, reaction },\n });\n }\n\n private _renderHeader() {\n return nothing;\n }\n\n private _renderContent() {\n return this.message?.text\n ? html`<pre part=\"plain-text\">${this.message.text}</pre>`\n : nothing;\n }\n\n private _renderActions() {\n const isSent = this.message?.sender === this._state.currentUserId;\n const hasText = this.message?.text.trim();\n const hasAttachments =\n this.message?.attachments && !isEmpty(this.message?.attachments);\n const isTyping = this._state._isTyping;\n const isLastMessage = this.message === this._state.messages.at(-1);\n const resourceStrings = this._state.resourceStrings!;\n\n if (isSent || !(hasText || hasAttachments) || (isLastMessage && isTyping)) {\n return nothing;\n }\n\n return html`\n <div @click=${this._handleMessageActionClick}>\n ${this._renderActionButton(\n 'copy_content',\n resourceStrings.reactionCopy\n )}\n ${this._renderActionButton(\n this.message?.reactions?.includes(LIKE_ACTIVE)\n ? LIKE_ACTIVE\n : LIKE_INACTIVE,\n resourceStrings.reactionLike\n )}\n ${this._renderActionButton(\n this.message?.reactions?.includes(DISLIKE_ACTIVE)\n ? DISLIKE_ACTIVE\n : DISLIKE_INACTIVE,\n resourceStrings.reactionDislike\n )}\n ${this._renderActionButton(\n 'regenerate',\n resourceStrings.reactionRegenerate\n )}\n </div>\n `;\n }\n\n private _renderActionButton(name: string, tooltipMessage: string) {\n return html`\n <igc-icon-button\n id=${`${name}-button`}\n name=${name}\n variant=\"flat\"\n @pointerenter=${({ target }: PointerEvent) =>\n showChatActionsTooltip(target as Element, tooltipMessage)}\n @focus=${({ target }: FocusEvent) =>\n showChatActionsTooltip(target as Element, tooltipMessage)}\n ></igc-icon-button>\n `;\n }\n\n // Default rendering logic for attachments\n private _renderAttachments() {\n return isEmpty(this.message?.attachments ?? [])\n ? nothing\n : html`\n <igc-message-attachments\n .message=${this.message}\n ></igc-message-attachments>\n `;\n }\n\n private _renderMessage() {\n return this.message\n ? html`${this._renderHeader()}${this._renderContent()}${this._renderAttachments()}${this._renderActions()}`\n : nothing;\n }\n\n protected override render() {\n const ctx: MessageRendererContext = {\n message: this.message!,\n defaults: this._defaults,\n instance: this._state.host,\n };\n\n const parts = {\n 'message-container': true,\n sent: this._state.isCurrentUserMessage(this.message),\n };\n\n return html`\n ${cache(\n this.message\n ? html`\n <div part=${partMap(parts)}>\n ${cache(\n this._state.options?.renderers?.message\n ? html`${until(this._getRenderer('message')(ctx))}`\n : html`\n ${until(this._getRenderer('messageHeader')(ctx))}\n ${until(this._getRenderer('messageContent')(ctx))}\n ${until(this._getRenderer('messageAttachments')(ctx))}\n ${until(this._getRenderer('messageActions')(ctx))}\n `\n )}\n </div>\n `\n : nothing\n )}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'igc-chat-message': IgcChatMessageComponent;\n }\n}\n"]}
@@ -33,6 +33,7 @@ export declare class ChatState {
33
33
  _isTyping: boolean;
34
34
  private _lastTyped;
35
35
  resourceStrings: import("../common/i18n/chat.resources.js").IgcChatResourceStrings;
36
+ get host(): IgcChatComponent;
36
37
  get acceptedFileTypes(): ChatAcceptedFileTypes | null;
37
38
  get disableAutoScroll(): boolean;
38
39
  /**
@@ -92,20 +93,21 @@ export declare class ChatState {
92
93
  constructor(chat: IgcChatComponent, contextUpdateFn: () => unknown, userInputContextUpdateFn: () => unknown);
93
94
  isCurrentUserMessage(message?: IgcMessage): boolean;
94
95
  emitEvent(name: keyof IgcChatComponentEventMap, args?: any): boolean;
96
+ protected _createMessage(message: Partial<IgcMessage>): IgcMessage;
97
+ addMessage(message: Partial<IgcMessage>): void;
95
98
  /**
96
99
  * Adds a new chat message.
97
100
  * Emits 'igcMessageCreated' event which can be canceled to prevent adding.
98
101
  * Clears input value and attachments on success.
99
- * @param message Partial message object with optional id, sender, timestamp
102
+ * @internal
100
103
  */
101
- addMessage(message: Partial<IgcMessage>): void;
104
+ addMessageWithEvent(message: Partial<IgcMessage>): void;
102
105
  /**
103
106
  * Adds files as attachments to the input.
104
107
  * Emits 'igcAttachmentChange' event which can be canceled to prevent adding.
105
108
  * @param files Array of File objects to attach
106
109
  */
107
110
  attachFiles(files: File[]): void;
108
- isImageAttachment(attachment: IgcMessageAttachment): boolean;
109
111
  handleKeyDown: (e: KeyboardEvent) => void;
110
112
  sendMessage: () => void;
111
113
  /**
@@ -120,11 +122,6 @@ export declare class ChatState {
120
122
  * @param suggestion The suggestion string clicked
121
123
  */
122
124
  handleSuggestionClick: (suggestion: string) => void;
123
- /**
124
- * Updates the chat options partially.
125
- * @param options Partial options to merge with current options
126
- */
127
- updateOptions(options: Partial<IgcChatOptions>): void;
128
125
  /**
129
126
  * Updates the internal cache for accepted file types.
130
127
  * Parses the acceptedFiles string option into extensions, mimeTypes, and wildcard types.
@@ -1,8 +1,11 @@
1
1
  import { enterKey } from '../common/controllers/key-bindings.js';
2
2
  import { IgcChatResourceStringEN } from '../common/i18n/chat.resources.js';
3
3
  import { isEmpty, nanoid } from '../common/util.js';
4
- import { parseAcceptedFileTypes } from './utils.js';
4
+ import { isImageAttachment, parseAcceptedFileTypes, } from './utils.js';
5
5
  export class ChatState {
6
+ get host() {
7
+ return this._host;
8
+ }
6
9
  get acceptedFileTypes() {
7
10
  return this._acceptedTypesCache;
8
11
  }
@@ -97,7 +100,7 @@ export class ChatState {
97
100
  this.sendMessage = () => {
98
101
  if (!this.inputValue.trim() && this.inputAttachments.length === 0)
99
102
  return;
100
- this.addMessage({
103
+ this.addMessageWithEvent({
101
104
  text: this.inputValue,
102
105
  attachments: this.inputAttachments,
103
106
  });
@@ -119,7 +122,7 @@ export class ChatState {
119
122
  }
120
123
  };
121
124
  this.handleSuggestionClick = (suggestion) => {
122
- this.addMessage({ text: suggestion });
125
+ this.addMessageWithEvent({ text: suggestion });
123
126
  if (this.textArea) {
124
127
  this.textArea.focus();
125
128
  }
@@ -134,23 +137,26 @@ export class ChatState {
134
137
  emitEvent(name, args) {
135
138
  return this._host.emitEvent(name, args);
136
139
  }
137
- addMessage(message) {
138
- const newMessage = {
140
+ _createMessage(message) {
141
+ return {
139
142
  id: message.id ?? nanoid(),
140
143
  text: message.text ?? '',
141
144
  sender: message.sender ?? this.currentUserId,
142
- timestamp: message.timestamp ?? new Date(),
145
+ timestamp: message.timestamp ?? Date.now().toString(),
143
146
  attachments: message.attachments || [],
144
147
  };
145
- const allowed = this.emitEvent('igcMessageCreated', {
148
+ }
149
+ addMessage(message) {
150
+ this.messages.push(this._createMessage(message));
151
+ this._host.requestUpdate('messages');
152
+ }
153
+ addMessageWithEvent(message) {
154
+ const newMessage = this._createMessage(message);
155
+ if (this._host.emitEvent('igcMessageCreated', {
146
156
  detail: newMessage,
147
157
  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');
158
+ })) {
159
+ this.addMessage(newMessage);
154
160
  this.inputValue = '';
155
161
  this.inputAttachments = [];
156
162
  }
@@ -162,14 +168,13 @@ export class ChatState {
162
168
  if (fileNames.has(file.name)) {
163
169
  continue;
164
170
  }
165
- const isImage = file.type.startsWith('image/');
166
171
  const url = URL.createObjectURL(file);
167
172
  newAttachments.push({
168
173
  id: nanoid(),
169
174
  url,
170
175
  name: file.name,
171
176
  file,
172
- thumbnail: isImage ? url : undefined,
177
+ thumbnail: isImageAttachment(file) ? url : undefined,
173
178
  });
174
179
  }
175
180
  const allowed = this.emitEvent('igcAttachmentChange', {
@@ -180,13 +185,6 @@ export class ChatState {
180
185
  this.inputAttachments = [...this.inputAttachments, ...newAttachments];
181
186
  }
182
187
  }
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
188
  updateAcceptedTypesCache() {
191
189
  this._acceptedTypesCache = this.options?.acceptedFiles
192
190
  ? parseAcceptedFileTypes(this.options.acceptedFiles)