igniteui-webcomponents 6.3.0-beta.1 → 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 (129) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/components/chat/chat-input.d.ts +5 -17
  3. package/components/chat/chat-input.js +49 -27
  4. package/components/chat/chat-input.js.map +1 -1
  5. package/components/chat/chat-message.d.ts +3 -3
  6. package/components/chat/chat-message.js +96 -52
  7. package/components/chat/chat-message.js.map +1 -1
  8. package/components/chat/chat-state.d.ts +43 -45
  9. package/components/chat/chat-state.js +67 -74
  10. package/components/chat/chat-state.js.map +1 -1
  11. package/components/chat/chat.d.ts +66 -20
  12. package/components/chat/chat.js +82 -91
  13. package/components/chat/chat.js.map +1 -1
  14. package/components/chat/extras/markdown-renderer.d.ts +2 -2
  15. package/components/chat/extras/markdown-renderer.js +6 -1
  16. package/components/chat/extras/markdown-renderer.js.map +1 -1
  17. package/components/chat/message-attachments.d.ts +2 -2
  18. package/components/chat/message-attachments.js +17 -14
  19. package/components/chat/message-attachments.js.map +1 -1
  20. package/components/chat/themes/chat.base.css.js +1 -1
  21. package/components/chat/themes/chat.base.css.js.map +1 -1
  22. package/components/chat/themes/dark/chat.bootstrap.css.js +1 -1
  23. package/components/chat/themes/dark/chat.bootstrap.css.js.map +1 -1
  24. package/components/chat/themes/dark/chat.fluent.css.js +1 -1
  25. package/components/chat/themes/dark/chat.fluent.css.js.map +1 -1
  26. package/components/chat/themes/dark/chat.indigo.css.js +1 -1
  27. package/components/chat/themes/dark/chat.indigo.css.js.map +1 -1
  28. package/components/chat/themes/dark/chat.material.css.js +1 -1
  29. package/components/chat/themes/dark/chat.material.css.js.map +1 -1
  30. package/components/chat/themes/input.base.css.js +1 -1
  31. package/components/chat/themes/input.base.css.js.map +1 -1
  32. package/components/chat/themes/light/chat.bootstrap.css.js +1 -1
  33. package/components/chat/themes/light/chat.bootstrap.css.js.map +1 -1
  34. package/components/chat/themes/light/chat.indigo.css.js +1 -1
  35. package/components/chat/themes/light/chat.indigo.css.js.map +1 -1
  36. package/components/chat/themes/light/chat.shared.css.js +1 -1
  37. package/components/chat/themes/light/chat.shared.css.js.map +1 -1
  38. package/components/chat/themes/message-attachments.base.css.js +1 -1
  39. package/components/chat/themes/message-attachments.base.css.js.map +1 -1
  40. package/components/chat/themes/message.base.css.js +1 -1
  41. package/components/chat/themes/message.base.css.js.map +1 -1
  42. package/components/chat/themes/shared/chat.bootstrap.css.js +1 -1
  43. package/components/chat/themes/shared/chat.bootstrap.css.js.map +1 -1
  44. package/components/chat/themes/shared/chat.fluent.css.js +1 -1
  45. package/components/chat/themes/shared/chat.fluent.css.js.map +1 -1
  46. package/components/chat/themes/shared/chat.indigo.css.js +1 -1
  47. package/components/chat/themes/shared/chat.indigo.css.js.map +1 -1
  48. package/components/chat/themes/shared/message-attachments/message-attachments.common.css.js +1 -1
  49. package/components/chat/themes/shared/message-attachments/message-attachments.common.css.js.map +1 -1
  50. package/components/chat/types.d.ts +164 -30
  51. package/components/chat/types.js.map +1 -1
  52. package/components/chat/utils.d.ts +3 -4
  53. package/components/chat/utils.js +0 -12
  54. package/components/chat/utils.js.map +1 -1
  55. package/components/checkbox/themes/checkbox.base.css.js +1 -1
  56. package/components/checkbox/themes/checkbox.base.css.js.map +1 -1
  57. package/components/checkbox/themes/switch.base.css.js +1 -1
  58. package/components/checkbox/themes/switch.base.css.js.map +1 -1
  59. package/components/common/i18n/chat.resources.d.ts +3 -0
  60. package/components/common/i18n/chat.resources.js +3 -0
  61. package/components/common/i18n/chat.resources.js.map +1 -1
  62. package/components/common/util.d.ts +3 -0
  63. package/components/common/util.js +9 -1
  64. package/components/common/util.js.map +1 -1
  65. package/components/input/themes/shared/input.bootstrap.css.js +1 -1
  66. package/components/input/themes/shared/input.bootstrap.css.js.map +1 -1
  67. package/components/input/themes/shared/input.indigo.css.js +1 -1
  68. package/components/input/themes/shared/input.indigo.css.js.map +1 -1
  69. package/components/list/themes/header.js +2 -28
  70. package/components/list/themes/header.js.map +1 -1
  71. package/components/list/themes/item.js +6 -20
  72. package/components/list/themes/item.js.map +1 -1
  73. package/components/textarea/themes/shared/textarea.bootstrap.css.js +1 -1
  74. package/components/textarea/themes/shared/textarea.bootstrap.css.js.map +1 -1
  75. package/components/tile-manager/themes/tile-manager.base.css.js +1 -1
  76. package/components/tile-manager/themes/tile-manager.base.css.js.map +1 -1
  77. package/custom-elements.json +2110 -2045
  78. package/igniteui-webcomponents.css-data.json +1 -1
  79. package/igniteui-webcomponents.html-data.json +1 -1
  80. package/package.json +24 -2
  81. package/web-types.json +2 -2
  82. package/components/list/themes/dark/header/list-header.bootstrap.css.d.ts +0 -1
  83. package/components/list/themes/dark/header/list-header.bootstrap.css.js +0 -3
  84. package/components/list/themes/dark/header/list-header.bootstrap.css.js.map +0 -1
  85. package/components/list/themes/dark/header/list-header.fluent.css.d.ts +0 -1
  86. package/components/list/themes/dark/header/list-header.fluent.css.js +0 -3
  87. package/components/list/themes/dark/header/list-header.fluent.css.js.map +0 -1
  88. package/components/list/themes/dark/header/list-header.indigo.css.d.ts +0 -1
  89. package/components/list/themes/dark/header/list-header.indigo.css.js +0 -3
  90. package/components/list/themes/dark/header/list-header.indigo.css.js.map +0 -1
  91. package/components/list/themes/dark/header/list-header.material.css.d.ts +0 -1
  92. package/components/list/themes/dark/header/list-header.material.css.js +0 -3
  93. package/components/list/themes/dark/header/list-header.material.css.js.map +0 -1
  94. package/components/list/themes/dark/item/list-item.bootstrap.css.d.ts +0 -1
  95. package/components/list/themes/dark/item/list-item.bootstrap.css.js +0 -3
  96. package/components/list/themes/dark/item/list-item.bootstrap.css.js.map +0 -1
  97. package/components/list/themes/dark/item/list-item.fluent.css.d.ts +0 -1
  98. package/components/list/themes/dark/item/list-item.fluent.css.js +0 -3
  99. package/components/list/themes/dark/item/list-item.fluent.css.js.map +0 -1
  100. package/components/list/themes/dark/item/list-item.indigo.css.d.ts +0 -1
  101. package/components/list/themes/dark/item/list-item.indigo.css.js +0 -3
  102. package/components/list/themes/dark/item/list-item.indigo.css.js.map +0 -1
  103. package/components/list/themes/dark/item/list-item.material.css.d.ts +0 -1
  104. package/components/list/themes/dark/item/list-item.material.css.js +0 -3
  105. package/components/list/themes/dark/item/list-item.material.css.js.map +0 -1
  106. package/components/list/themes/light/header/list-header.bootstrap.css.d.ts +0 -1
  107. package/components/list/themes/light/header/list-header.bootstrap.css.js +0 -3
  108. package/components/list/themes/light/header/list-header.bootstrap.css.js.map +0 -1
  109. package/components/list/themes/light/header/list-header.fluent.css.d.ts +0 -1
  110. package/components/list/themes/light/header/list-header.fluent.css.js +0 -3
  111. package/components/list/themes/light/header/list-header.fluent.css.js.map +0 -1
  112. package/components/list/themes/light/header/list-header.indigo.css.d.ts +0 -1
  113. package/components/list/themes/light/header/list-header.indigo.css.js +0 -3
  114. package/components/list/themes/light/header/list-header.indigo.css.js.map +0 -1
  115. package/components/list/themes/light/header/list-header.material.css.d.ts +0 -1
  116. package/components/list/themes/light/header/list-header.material.css.js +0 -3
  117. package/components/list/themes/light/header/list-header.material.css.js.map +0 -1
  118. package/components/list/themes/light/item/list-item.bootstrap.css.d.ts +0 -1
  119. package/components/list/themes/light/item/list-item.bootstrap.css.js +0 -3
  120. package/components/list/themes/light/item/list-item.bootstrap.css.js.map +0 -1
  121. package/components/list/themes/light/item/list-item.fluent.css.d.ts +0 -1
  122. package/components/list/themes/light/item/list-item.fluent.css.js +0 -3
  123. package/components/list/themes/light/item/list-item.fluent.css.js.map +0 -1
  124. package/components/list/themes/light/item/list-item.indigo.css.d.ts +0 -1
  125. package/components/list/themes/light/item/list-item.indigo.css.js +0 -3
  126. package/components/list/themes/light/item/list-item.indigo.css.js.map +0 -1
  127. package/components/list/themes/light/item/list-item.material.css.d.ts +0 -1
  128. package/components/list/themes/light/item/list-item.material.css.js +0 -3
  129. package/components/list/themes/light/item/list-item.material.css.js.map +0 -1
@@ -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,11 +78,52 @@ 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";
@@ -90,25 +134,29 @@ export default class IgcChatComponent extends IgcChatComponent_base {
90
134
  private readonly _slots;
91
135
  private readonly _context;
92
136
  private readonly _userInputContext;
137
+ private readonly _input?;
138
+ private readonly _typingIndicator?;
139
+ private readonly _suggestionsContainer?;
140
+ private readonly _scrollContainer;
93
141
  private _updateContext;
94
142
  private _updateUserInputContext;
95
143
  /**
96
144
  * The list of chat messages currently displayed.
97
145
  * Use this property to set or update the message history.
98
146
  */
99
- set messages(value: IgcMessage[]);
100
- get messages(): IgcMessage[];
147
+ set messages(value: IgcChatMessage[]);
148
+ get messages(): IgcChatMessage[];
101
149
  /**
102
150
  * The chat message currently being composed but not yet sent.
103
151
  * Includes the draft text and any attachments.
104
152
  */
105
153
  set draftMessage(value: {
106
154
  text: string;
107
- attachments?: IgcMessageAttachment[];
155
+ attachments?: IgcChatMessageAttachment[];
108
156
  });
109
157
  get draftMessage(): {
110
158
  text: string;
111
- attachments?: IgcMessageAttachment[];
159
+ attachments?: IgcChatMessageAttachment[];
112
160
  };
113
161
  /**
114
162
  * Controls the chat behavior and appearance through a configuration object.
@@ -122,13 +170,11 @@ export default class IgcChatComponent extends IgcChatComponent_base {
122
170
  resourceStrings: import("../common/i18n/chat.resources.js").IgcChatResourceStrings;
123
171
  constructor();
124
172
  private _getRenderer;
173
+ private _handleSuggestionClick;
125
174
  /**
126
175
  * Scrolls the view to a specific message by id.
127
- * @param messageId - The id of the message to scroll to
128
176
  */
129
177
  scrollToMessage(messageId: string): void;
130
- addMessage(message: Partial<IgcMessage>): IgcMessage;
131
- updateMessage(message: IgcMessage, data: Partial<IgcMessage>, scrollIntoView?: boolean): void;
132
178
  protected updated(properties: PropertyValues<this>): void;
133
179
  private _scrollToBottom;
134
180
  private _renderHeader;
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { ContextProvider } from '@lit/context';
8
8
  import { html, LitElement, nothing } from 'lit';
9
- import { property } from 'lit/decorators.js';
9
+ import { property, query } from 'lit/decorators.js';
10
10
  import { cache } from 'lit/directives/cache.js';
11
11
  import { repeat } from 'lit/directives/repeat.js';
12
12
  import { addThemingController } from '../../theming/theming-controller.js';
@@ -16,9 +16,11 @@ import { addSlotController, setSlots } from '../common/controllers/slot.js';
16
16
  import { registerComponent } from '../common/definitions/register.js';
17
17
  import { IgcChatResourceStringEN } from '../common/i18n/chat.resources.js';
18
18
  import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
19
- import { isEmpty, last } from '../common/util.js';
19
+ import { isEmpty } from '../common/util.js';
20
20
  import IgcIconComponent from '../icon/icon.js';
21
21
  import IgcListComponent from '../list/list.js';
22
+ import IgcToastComponent from '../toast/toast.js';
23
+ import IgcTooltipComponent from '../tooltip/tooltip.js';
22
24
  import IgcChatInputComponent from './chat-input.js';
23
25
  import IgcChatMessageComponent from './chat-message.js';
24
26
  import { ChatState } from './chat-state.js';
@@ -30,7 +32,7 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
30
32
  static { this.tagName = 'igc-chat'; }
31
33
  static { this.styles = [styles, shared]; }
32
34
  static register() {
33
- registerComponent(IgcChatComponent, IgcChatInputComponent, IgcChatMessageComponent, IgcButtonComponent, IgcIconComponent, IgcListComponent);
35
+ registerComponent(IgcChatComponent, IgcChatInputComponent, IgcChatMessageComponent, IgcButtonComponent, IgcIconComponent, IgcListComponent, IgcTooltipComponent, IgcToastComponent);
34
36
  }
35
37
  _updateContext() {
36
38
  this._context.setValue(this._state, true);
@@ -89,41 +91,34 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
89
91
  ? (this._state.options.renderers[name] ?? this._defaults[name])
90
92
  : this._defaults[name];
91
93
  }
94
+ _handleSuggestionClick(text) {
95
+ this._state.addMessageWithEvent({ text });
96
+ this._input?.focusInput();
97
+ }
92
98
  scrollToMessage(messageId) {
93
99
  if (!isEmpty(this.messages)) {
94
100
  const message = this.renderRoot.querySelector(`#message-${messageId}`);
95
101
  message?.scrollIntoView({ block: 'end', inline: 'end' });
96
102
  }
97
103
  }
98
- addMessage(message) {
99
- this._state.addMessage(message);
100
- return last(this.messages);
101
- }
102
- updateMessage(message, data, scrollIntoView = false) {
103
- Object.assign(message, data);
104
- const messageElement = this.renderRoot.querySelector(`#message-${message.id}`);
105
- if (messageElement) {
106
- messageElement.requestUpdate();
107
- if (scrollIntoView) {
108
- messageElement.updateComplete.then(() => messageElement.scrollIntoView({ block: 'end', inline: 'end' }));
109
- }
110
- }
111
- else {
112
- this.requestUpdate('messages');
113
- }
114
- }
115
104
  updated(properties) {
116
- if (properties.has('messages') && !this._state.disableAutoScroll) {
105
+ if ((properties.has('messages') ||
106
+ this._typingIndicator ||
107
+ this._suggestionsContainer) &&
108
+ !this._state.disableAutoScroll) {
117
109
  this._scrollToBottom();
118
110
  }
119
111
  }
120
112
  _scrollToBottom() {
121
- if (!isEmpty(this.messages)) {
122
- const lastMessage = this.renderRoot
123
- .querySelectorAll(IgcChatMessageComponent.tagName)
124
- .item(this.messages.length - 1);
125
- requestAnimationFrame(() => lastMessage.scrollIntoView({ block: 'end', inline: 'end' }));
126
- }
113
+ const current = this._scrollContainer.scrollTop;
114
+ requestAnimationFrame(() => {
115
+ const scrollHeight = this._scrollContainer.scrollHeight;
116
+ if (current < scrollHeight) {
117
+ this._scrollContainer.scrollBy({
118
+ top: Math.abs(scrollHeight - current),
119
+ });
120
+ }
121
+ });
127
122
  }
128
123
  _renderHeader() {
129
124
  const hasContent = this._slots.hasAssignedElements('prefix') ||
@@ -134,18 +129,15 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
134
129
  <div part="header" ?hidden=${!hasContent}>
135
130
  <slot
136
131
  name="prefix"
137
- part="prefix"
138
132
  ?hidden=${!this._slots.hasAssignedElements('prefix')}
139
133
  ></slot>
140
- <slot name="title" part="title"
141
- >${this._state.options?.headerText}</slot
142
- >
143
- <slot name="actions" part="actions"></slot>
134
+ <slot name="title">${this._state.options?.headerText}</slot>
135
+ <slot name="actions"></slot>
144
136
  </div>
145
137
  `;
146
138
  }
147
139
  _renderMessages() {
148
- const ctx = { defaults: this._defaults, instance: this };
140
+ const ctx = { instance: this };
149
141
  return html `
150
142
  <div part="message-list" tabindex="0">
151
143
  ${repeat(this._state.messages, (message) => message.id, (message) => {
@@ -154,26 +146,40 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
154
146
  id=${`message-${message.id}`}
155
147
  part="message-item"
156
148
  .message=${message}
157
- exportparts="message-container, message-text, message-attachments, message-actions,
158
- attachments-container, attachment, attachment-header, attachment-content, attachment-icon, file-name, actions: attachment-actions"
149
+ exportparts="
150
+ message-container,
151
+ message-list,
152
+ message-header,
153
+ plain-text: message-content,
154
+ message-attachments: message-attachments-container,
155
+ attachment: message-attachment,
156
+ message-actions: message-actions-container,
157
+ sent: message-sent,
158
+ attachment-header,
159
+ attachment-content,
160
+ attachment-icon,
161
+ file-name,
162
+ "
159
163
  >
160
164
  </igc-chat-message>
161
165
  `;
162
166
  })}
163
167
  ${this._state.options?.isTyping
164
- ? this._getRenderer('typingIndicator')(ctx)
168
+ ? html `
169
+ <div part="typing-indicator">
170
+ ${this._getRenderer('typingIndicator')(ctx)}
171
+ </div>
172
+ `
165
173
  : nothing}
166
174
  </div>
167
175
  `;
168
176
  }
169
177
  _renderLoadingTemplate() {
170
178
  return html `
171
- <div part="typing-indicator">
172
- <div part="typing-dot"></div>
173
- <div part="typing-dot"></div>
174
- <div part="typing-dot"></div>
175
- <div part="typing-dot"></div>
176
- </div>
179
+ <div part="typing-dot"></div>
180
+ <div part="typing-dot"></div>
181
+ <div part="typing-dot"></div>
182
+ <div part="typing-dot"></div>
177
183
  `;
178
184
  }
179
185
  _renderSuggestionPrefix() {
@@ -182,10 +188,7 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
182
188
  _renderSuggestions() {
183
189
  const hasContent = this._slots.hasAssignedElements('suggestions-header');
184
190
  const suggestions = this._state.options?.suggestions ?? [];
185
- const ctx = {
186
- defaults: this._defaults,
187
- instance: this,
188
- };
191
+ const ctx = { instance: this };
189
192
  return html `
190
193
  <div part="suggestions-container">
191
194
  <igc-list>
@@ -195,21 +198,24 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
195
198
  </span>
196
199
  <slot name="suggestions-header"></slot>
197
200
  </igc-list-header>
198
- <slot name="suggestions" part="suggestions">
201
+ <slot name="suggestions">
199
202
  ${suggestions.map((suggestion) => html `
200
- <slot name="suggestion" part="suggestion">
203
+ <slot name="suggestion">
201
204
  <igc-list-item
202
- @click=${() => this._state?.handleSuggestionClick(suggestion)}
205
+ part="suggestion"
206
+ @click=${() => this._handleSuggestionClick(suggestion)}
203
207
  >
204
- <span slot="start">
208
+ <span slot="start" part="suggestion-prefix">
205
209
  ${this._getRenderer('suggestionPrefix')(ctx)}
206
210
  </span>
207
- <span slot="title">${suggestion}</span>
211
+ <span slot="title" part="suggestion-title"
212
+ >${suggestion}</span
213
+ >
208
214
  </igc-list-item>
209
215
  </slot>
210
216
  `)}
211
217
  </slot>
212
- <slot name="suggestions-actions" part="suggestions-actions"></slot>
218
+ <slot name="suggestions-actions"></slot>
213
219
  </igc-list>
214
220
  </div>
215
221
  `;
@@ -227,42 +233,10 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
227
233
  ? nothing
228
234
  : this._renderSuggestions();
229
235
  return html `
230
- <div
231
- part="chat-container"
232
- exportparts="
233
- chat-container,
234
- header,
235
- prefix,
236
- title,
237
- actions,
238
- chat-wrapper,
239
- chat-messages,
240
- empty-state,
241
- suggestions-container,
242
- suggestions-header,
243
- suggestions,
244
- suggestions-actions,
245
- suggestion,
246
- message-container,
247
- message-list,
248
- message-item,
249
- message,
250
- message-text,
251
- message-attachments,
252
- message-actions,
253
- typing-indicator,
254
- attachments-container,
255
- attachment,
256
- attachment-header,
257
- attachment-content,
258
- attachment-icon,
259
- file-name,
260
- attachment-actions
261
- "
262
- >
236
+ <div part="chat-container">
263
237
  ${this._renderHeader()}
264
238
 
265
- <div part="chat-wrapper">
239
+ <div part="message-area-container">
266
240
  ${cache(hasMessages || this._state.options?.isTyping
267
241
  ? this._renderMessages()
268
242
  : this._renderEmptyState())}
@@ -273,14 +247,19 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
273
247
 
274
248
  <igc-chat-input
275
249
  exportparts="
276
- input-container,
277
- input-wrapper,
250
+ input-container: input-area-container,
251
+ input-wrapper: input-container,
278
252
  attachments: input-attachments-container,
279
- attachments-wrapper: input-attachment,
253
+ attachment-wrapper: input-attachment-container,
280
254
  attachment-name: input-attachment-name,
255
+ attachment-icon: input-attachment-icon,
281
256
  text-input,
282
- buttons-container: input-buttons-container,
283
- upload-button,
257
+ actions-container: input-actions-container,
258
+ input-actions-start,
259
+ input-actions-end,
260
+ file-upload-container,
261
+ file-upload,
262
+ send-button-container,
284
263
  send-button"
285
264
  >
286
265
  </igc-chat-input>
@@ -291,6 +270,18 @@ export default class IgcChatComponent extends EventEmitterMixin(LitElement) {
291
270
  `;
292
271
  }
293
272
  }
273
+ __decorate([
274
+ query(IgcChatInputComponent.tagName)
275
+ ], IgcChatComponent.prototype, "_input", void 0);
276
+ __decorate([
277
+ query('[part="typing-indicator"]')
278
+ ], IgcChatComponent.prototype, "_typingIndicator", void 0);
279
+ __decorate([
280
+ query('[part="suggestions-container"]')
281
+ ], IgcChatComponent.prototype, "_suggestionsContainer", void 0);
282
+ __decorate([
283
+ query('[part="message-area-container"]', true)
284
+ ], IgcChatComponent.prototype, "_scrollContainer", void 0);
294
285
  __decorate([
295
286
  property({ attribute: false })
296
287
  ], IgcChatComponent.prototype, "messages", null);
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/components/chat/chat.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContextProvider } from '@lit/context';\nimport { html, LitElement, nothing, type PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { cache } from 'lit/directives/cache.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { addThemingController } from '../../theming/theming-controller.js';\nimport IgcButtonComponent from '../button/button.js';\nimport { chatContext, chatUserInputContext } from '../common/context.js';\nimport { addSlotController, setSlots } from '../common/controllers/slot.js';\nimport { registerComponent } from '../common/definitions/register.js';\nimport { IgcChatResourceStringEN } from '../common/i18n/chat.resources.js';\nimport type { Constructor } from '../common/mixins/constructor.js';\nimport { EventEmitterMixin } from '../common/mixins/event-emitter.js';\nimport { isEmpty, last } from '../common/util.js';\nimport IgcIconComponent from '../icon/icon.js';\nimport IgcListComponent from '../list/list.js';\nimport IgcChatInputComponent from './chat-input.js';\nimport IgcChatMessageComponent from './chat-message.js';\nimport { ChatState } from './chat-state.js';\nimport { styles } from './themes/chat.base.css.js';\nimport { styles as shared } from './themes/shared/chat.common.css.js';\nimport { all } from './themes/themes.js';\nimport type {\n ChatRendererContext,\n ChatTemplateRenderer,\n IgcChatOptions,\n IgcMessage,\n IgcMessageAttachment,\n} from './types.js';\n\ntype DefaultChatRenderers = {\n typingIndicator: ChatTemplateRenderer<ChatRendererContext>;\n suggestionPrefix: ChatTemplateRenderer<ChatRendererContext>;\n};\n\n/**\n * Defines the custom events dispatched by the `<igc-chat>` component.\n */\nexport interface IgcChatComponentEventMap {\n /**\n * Dispatched when a new chat message is created (sent).\n */\n igcMessageCreated: CustomEvent<IgcMessage>;\n\n /**\n * Dispatched when a message is reacted to.\n */\n igcMessageReact: CustomEvent<{ message: IgcMessage; reaction: string }>;\n\n /**\n * Dispatched when a chat message attachment is clicked.\n */\n igcAttachmentClick: CustomEvent<IgcMessageAttachment>;\n\n /**\n * Dispatched when an attachment is changed (e.g., updated or removed).\n */\n igcAttachmentChange: CustomEvent<IgcMessageAttachment>;\n\n /**\n * Dispatched during an attachment drag operation.\n */\n igcAttachmentDrag: CustomEvent<void>;\n\n /**\n * Dispatched when an attachment is dropped (e.g., in a drag-and-drop operation).\n */\n igcAttachmentDrop: CustomEvent<void>;\n\n /**\n * Dispatched when the typing status changes (e.g., user starts or stops typing).\n */\n igcTypingChange: CustomEvent<boolean>;\n\n /**\n * Dispatched when the chat input field gains focus.\n */\n igcInputFocus: CustomEvent<void>;\n\n /**\n * Dispatched when the chat input field loses focus.\n */\n igcInputBlur: CustomEvent<void>;\n\n /**\n * Dispatched when the content of the chat input changes.\n */\n igcInputChange: CustomEvent<string>;\n}\n\nconst Slots = setSlots(\n 'prefix',\n 'title',\n 'actions',\n 'suggestions-header',\n 'suggestions',\n 'suggestions-actions',\n 'suggestion',\n 'empty-state'\n);\n\n/**\n * A chat UI component for displaying messages, attachments, and input interaction.\n *\n * @element igc-chat\n *\n * @fires igcMessageCreated - Dispatched when a new chat message is created (sent).\n * @fires igcMessageReact - Dispatched when a message is reacted to.\n * @fires igcAttachmentClick - Dispatched when a chat message attachment is clicked.\n * @fires igcAttachmentChange - Dispatched when a message attachment is changed (e.g., updated or removed).\n * @fires igcAttachmentDrag - Dispatched during an attachment drag operation.\n * @fires igcAttachmentDrop - Dispatched when an attachment is dropped (e.g., in a drag-and-drop operation).\n * @fires igcTypingChange - Dispatched when the typing status changes (e.g., user starts or stops typing).\n * @fires igcInputFocus - Dispatched when the chat input field gains focus.\n * @fires igcInputBlur - Dispatched when the chat input field loses focus.\n * @fires igcInputChange - Dispatched when the content of the chat input changes.\n *\n * @slot prefix - Slot for injecting content (e.g., avatar or icon) before the chat title.\n * @slot title - Slot for overriding the chat title content.\n * @slot actions - Slot for injecting header actions (e.g., buttons, menus).\n * @slot suggestions-header - Slot for rendering a custom header for the suggestions list.\n * @slot suggestions - Slot for rendering a custom list of quick reply suggestions.\n * @slot suggestions-actions - Slot for rendering additional actions.\n * @slot suggestion - Slot for rendering a single suggestion item.\n * @slot empty-state - Slot shown when there are no messages.\n *\n * @csspart header - Styles the header container.\n * @csspart prefix - Styles the element before the title (e.g., avatar).\n * @csspart title - Styles the chat header title.\n * @csspart suggestions - Styles the suggestion container.\n * @csspart suggestion - Styles each suggestion item.\n */\nexport default class IgcChatComponent extends EventEmitterMixin<\n IgcChatComponentEventMap,\n Constructor<LitElement>\n>(LitElement) {\n public static readonly tagName = 'igc-chat';\n\n public static styles = [styles, shared];\n\n /* blazorSuppress */\n public static register(): void {\n registerComponent(\n IgcChatComponent,\n IgcChatInputComponent,\n IgcChatMessageComponent,\n IgcButtonComponent,\n IgcIconComponent,\n IgcListComponent\n );\n }\n\n private readonly _state = new ChatState(\n this,\n this._updateContext,\n this._updateUserInputContext\n );\n\n private readonly _defaults = Object.freeze<DefaultChatRenderers>({\n typingIndicator: () => this._renderLoadingTemplate(),\n suggestionPrefix: () => this._renderSuggestionPrefix(),\n });\n\n private readonly _slots = addSlotController(this, {\n slots: Slots,\n });\n\n private readonly _context = new ContextProvider(this, {\n context: chatContext,\n initialValue: this._state,\n });\n\n private readonly _userInputContext = new ContextProvider(this, {\n context: chatUserInputContext,\n initialValue: this._state,\n });\n\n private _updateContext(): void {\n this._context.setValue(this._state, true);\n }\n\n private _updateUserInputContext(): void {\n this._userInputContext.setValue(this._state, true);\n }\n\n /**\n * The list of chat messages currently displayed.\n * Use this property to set or update the message history.\n */\n @property({ attribute: false })\n public set messages(value: IgcMessage[]) {\n this._state.messages = value;\n }\n\n public get messages(): IgcMessage[] {\n return this._state.messages;\n }\n\n /**\n * The chat message currently being composed but not yet sent.\n * Includes the draft text and any attachments.\n */\n @property({ attribute: false })\n public set draftMessage(value: {\n text: string;\n attachments?: IgcMessageAttachment[];\n }) {\n if (this._state && value) {\n this._state.inputValue = value.text;\n this._state.inputAttachments = value.attachments || [];\n this.requestUpdate();\n }\n }\n\n public get draftMessage(): {\n text: string;\n attachments?: IgcMessageAttachment[];\n } {\n return {\n text: this._state.inputValue,\n attachments: this._state.inputAttachments,\n };\n }\n\n /**\n * Controls the chat behavior and appearance through a configuration object.\n * Use this to toggle UI options, provide suggestions, templates, etc.\n */\n @property({ attribute: false })\n public set options(value: IgcChatOptions) {\n this._state.options = value;\n }\n\n public get options(): IgcChatOptions | undefined {\n return this._state.options;\n }\n\n /**\n * The resource strings of the chat.\n */\n @property({ attribute: false })\n public resourceStrings = IgcChatResourceStringEN;\n\n constructor() {\n super();\n addThemingController(this, all);\n }\n\n private _getRenderer<U extends keyof DefaultChatRenderers>(\n name: U\n ): DefaultChatRenderers[U] {\n return this._state.options?.renderers\n ? (this._state.options.renderers[name] ?? this._defaults[name])\n : this._defaults[name];\n }\n\n // REVIEW: Maybe accept an `IgcMessage` type as well?\n /**\n * Scrolls the view to a specific message by id.\n * @param messageId - The id of the message to scroll to\n */\n public scrollToMessage(messageId: string): void {\n if (!isEmpty(this.messages)) {\n const message = this.renderRoot.querySelector(`#message-${messageId}`);\n message?.scrollIntoView({ block: 'end', inline: 'end' });\n }\n }\n\n // REVIEW\n public addMessage(message: Partial<IgcMessage>): IgcMessage {\n this._state.addMessage(message);\n return last(this.messages);\n }\n\n // REVIEW\n public updateMessage(\n message: IgcMessage,\n data: Partial<IgcMessage>,\n scrollIntoView = false\n ) {\n Object.assign(message, data);\n const messageElement =\n this.renderRoot.querySelector<IgcChatMessageComponent>(\n `#message-${message.id}`\n );\n\n if (messageElement) {\n messageElement.requestUpdate();\n if (scrollIntoView) {\n messageElement.updateComplete.then(() =>\n messageElement.scrollIntoView({ block: 'end', inline: 'end' })\n );\n }\n } else {\n this.requestUpdate('messages');\n }\n }\n\n protected override updated(properties: PropertyValues<this>): void {\n if (properties.has('messages') && !this._state.disableAutoScroll) {\n this._scrollToBottom();\n }\n }\n\n private _scrollToBottom(): void {\n if (!isEmpty(this.messages)) {\n const lastMessage = this.renderRoot\n .querySelectorAll(IgcChatMessageComponent.tagName)\n .item(this.messages.length - 1);\n\n requestAnimationFrame(() =>\n lastMessage.scrollIntoView({ block: 'end', inline: 'end' })\n );\n }\n }\n\n private _renderHeader() {\n const hasContent =\n this._slots.hasAssignedElements('prefix') ||\n this._slots.hasAssignedElements('title') ||\n this._slots.hasAssignedElements('actions') ||\n this._state.options?.headerText;\n\n return html`\n <div part=\"header\" ?hidden=${!hasContent}>\n <slot\n name=\"prefix\"\n part=\"prefix\"\n ?hidden=${!this._slots.hasAssignedElements('prefix')}\n ></slot>\n <slot name=\"title\" part=\"title\"\n >${this._state.options?.headerText}</slot\n >\n <slot name=\"actions\" part=\"actions\"></slot>\n </div>\n `;\n }\n\n private _renderMessages() {\n const ctx = { defaults: this._defaults, instance: this };\n\n return html`\n <div part=\"message-list\" tabindex=\"0\">\n ${repeat(\n this._state.messages,\n (message) => message.id,\n (message) => {\n return html`\n <igc-chat-message\n id=${`message-${message.id}`}\n part=\"message-item\"\n .message=${message}\n exportparts=\"message-container, message-text, message-attachments, message-actions,\n attachments-container, attachment, attachment-header, attachment-content, attachment-icon, file-name, actions: attachment-actions\"\n >\n </igc-chat-message>\n `;\n }\n )}\n ${this._state.options?.isTyping\n ? this._getRenderer('typingIndicator')(ctx)\n : nothing}\n </div>\n `;\n }\n\n private _renderLoadingTemplate() {\n return html`\n <div part=\"typing-indicator\">\n <div part=\"typing-dot\"></div>\n <div part=\"typing-dot\"></div>\n <div part=\"typing-dot\"></div>\n <div part=\"typing-dot\"></div>\n </div>\n `;\n }\n\n private _renderSuggestionPrefix() {\n return html`<igc-icon name=\"auto_suggest\"></igc-icon>`;\n }\n\n private _renderSuggestions() {\n const hasContent = this._slots.hasAssignedElements('suggestions-header');\n const suggestions = this._state.options?.suggestions ?? [];\n const ctx = {\n defaults: this._defaults,\n instance: this,\n };\n\n return html`\n <div part=\"suggestions-container\">\n <igc-list>\n <igc-list-header part=\"suggestions-header\">\n <span ?hidden=${hasContent}>\n ${this.resourceStrings.suggestionsHeader}\n </span>\n <slot name=\"suggestions-header\"></slot>\n </igc-list-header>\n <slot name=\"suggestions\" part=\"suggestions\">\n ${suggestions.map(\n (suggestion) => html`\n <slot name=\"suggestion\" part=\"suggestion\">\n <igc-list-item\n @click=${() =>\n this._state?.handleSuggestionClick(suggestion)}\n >\n <span slot=\"start\">\n ${this._getRenderer('suggestionPrefix')(ctx)}\n </span>\n <span slot=\"title\">${suggestion}</span>\n </igc-list-item>\n </slot>\n `\n )}\n </slot>\n <slot name=\"suggestions-actions\" part=\"suggestions-actions\"></slot>\n </igc-list>\n </div>\n `;\n }\n\n private _renderEmptyState() {\n return html`\n <div part=\"empty-state\">\n <slot name=\"empty-state\"></slot>\n </div>\n `;\n }\n\n protected override render() {\n const hasMessages = !isEmpty(this.messages);\n const suggestions = isEmpty(this._state.options?.suggestions ?? [])\n ? nothing\n : this._renderSuggestions();\n\n return html`\n <div\n part=\"chat-container\"\n exportparts=\"\n chat-container,\n header,\n prefix,\n title,\n actions,\n chat-wrapper,\n chat-messages,\n empty-state,\n suggestions-container,\n suggestions-header,\n suggestions,\n suggestions-actions,\n suggestion,\n message-container,\n message-list,\n message-item,\n message,\n message-text,\n message-attachments,\n message-actions,\n typing-indicator,\n attachments-container,\n attachment,\n attachment-header,\n attachment-content,\n attachment-icon,\n file-name,\n attachment-actions\n \"\n >\n ${this._renderHeader()}\n\n <div part=\"chat-wrapper\">\n ${cache(\n hasMessages || this._state.options?.isTyping\n ? this._renderMessages()\n : this._renderEmptyState()\n )}\n ${this._state.suggestionsPosition === 'below-messages'\n ? suggestions\n : nothing}\n </div>\n\n <igc-chat-input\n exportparts=\"\n input-container,\n input-wrapper,\n attachments: input-attachments-container,\n attachments-wrapper: input-attachment,\n attachment-name: input-attachment-name,\n text-input,\n buttons-container: input-buttons-container,\n upload-button,\n send-button\"\n >\n </igc-chat-input>\n ${this._state.suggestionsPosition === 'below-input'\n ? suggestions\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'igc-chat': IgcChatComponent;\n }\n}\n"]}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/components/chat/chat.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContextProvider } from '@lit/context';\nimport { html, LitElement, nothing, type PropertyValues } from 'lit';\nimport { property, query } from 'lit/decorators.js';\nimport { cache } from 'lit/directives/cache.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { addThemingController } from '../../theming/theming-controller.js';\nimport IgcButtonComponent from '../button/button.js';\nimport { chatContext, chatUserInputContext } from '../common/context.js';\nimport { addSlotController, setSlots } from '../common/controllers/slot.js';\nimport { registerComponent } from '../common/definitions/register.js';\nimport { IgcChatResourceStringEN } from '../common/i18n/chat.resources.js';\nimport type { Constructor } from '../common/mixins/constructor.js';\nimport { EventEmitterMixin } from '../common/mixins/event-emitter.js';\nimport { isEmpty } from '../common/util.js';\nimport IgcIconComponent from '../icon/icon.js';\nimport IgcListComponent from '../list/list.js';\nimport IgcToastComponent from '../toast/toast.js';\nimport IgcTooltipComponent from '../tooltip/tooltip.js';\nimport IgcChatInputComponent from './chat-input.js';\nimport IgcChatMessageComponent from './chat-message.js';\nimport { ChatState } from './chat-state.js';\nimport { styles } from './themes/chat.base.css.js';\nimport { styles as shared } from './themes/shared/chat.common.css.js';\nimport { all } from './themes/themes.js';\nimport type {\n ChatRenderContext,\n ChatTemplateRenderer,\n IgcChatMessage,\n IgcChatMessageAttachment,\n IgcChatMessageReaction,\n IgcChatOptions,\n} from './types.js';\n\ntype DefaultChatRenderers = {\n typingIndicator: ChatTemplateRenderer<ChatRenderContext>;\n suggestionPrefix: ChatTemplateRenderer<ChatRenderContext>;\n};\n\n/**\n * Defines the custom events dispatched by the `<igc-chat>` component.\n */\nexport interface IgcChatComponentEventMap {\n /**\n * Dispatched when a new chat message is created (sent).\n */\n igcMessageCreated: CustomEvent<IgcChatMessage>;\n\n /**\n * Dispatched when a message is reacted to.\n */\n igcMessageReact: CustomEvent<IgcChatMessageReaction>;\n\n /**\n * Dispatched when a chat message attachment is clicked.\n */\n igcAttachmentClick: CustomEvent<IgcChatMessageAttachment>;\n\n /**\n * Dispatched when attachment(s) are added either through drag & drop or through\n * the default file input.\n */\n igcAttachmentAdded: CustomEvent<IgcChatMessageAttachment[]>;\n\n /**\n * Dispatched when an attachment is removed by the user.\n */\n igcAttachmentRemoved: CustomEvent<IgcChatMessageAttachment>;\n\n /**\n * Dispatched during an attachment drag operation.\n */\n igcAttachmentDrag: CustomEvent<void>;\n\n /**\n * Dispatched when an attachment is dropped (e.g., in a drag-and-drop operation).\n */\n igcAttachmentDrop: CustomEvent<void>;\n\n /**\n * Dispatched when the typing status changes (e.g., user starts or stops typing).\n */\n igcTypingChange: CustomEvent<boolean>;\n\n /**\n * Dispatched when the chat input field gains focus.\n */\n igcInputFocus: CustomEvent<void>;\n\n /**\n * Dispatched when the chat input field loses focus.\n */\n igcInputBlur: CustomEvent<void>;\n\n /**\n * Dispatched when the content of the chat input changes.\n */\n igcInputChange: CustomEvent<string>;\n}\n\nconst Slots = setSlots(\n 'prefix',\n 'title',\n 'actions',\n 'suggestions-header',\n 'suggestions',\n 'suggestions-actions',\n 'suggestion',\n 'empty-state'\n);\n\n/**\n * A chat UI component for displaying messages, attachments, and input interaction.\n *\n * @element igc-chat\n *\n * @fires igcMessageCreated - Dispatched when a new chat message is created (sent).\n * @fires igcMessageReact - Dispatched when a message is reacted to.\n * @fires igcAttachmentClick - Dispatched when a chat message attachment is clicked.\n * @fires igcAttachmentAdded - Dispatched when attachment(s) are added either through drag & drop or through the default file input.\n * @fires igcAttachmentRemoved - Dispatched when an attachment is removed by the user.\n * @fires igcAttachmentDrag - Dispatched during an attachment drag operation.\n * @fires igcAttachmentDrop - Dispatched when an attachment is dropped (e.g., in a drag-and-drop operation).\n * @fires igcTypingChange - Dispatched when the typing status changes (e.g., user starts or stops typing).\n * @fires igcInputFocus - Dispatched when the chat input field gains focus.\n * @fires igcInputBlur - Dispatched when the chat input field loses focus.\n * @fires igcInputChange - Dispatched when the content of the chat input changes.\n *\n * @slot prefix - Slot for injecting content (e.g., avatar or icon) before the chat title.\n * @slot title - Slot for overriding the chat title content.\n * @slot actions - Slot for injecting header actions (e.g., buttons, menus).\n * @slot suggestions-header - Slot for rendering a custom header for the suggestions list.\n * @slot suggestions - Slot for rendering a custom list of quick reply suggestions.\n * @slot suggestions-actions - Slot for rendering additional actions.\n * @slot suggestion - Slot for rendering a single suggestion item.\n * @slot empty-state - Slot shown when there are no messages.\n *\n * @csspart chat-container - Styles the main chat container.\n * @csspart header - Styles the chat header container.\n * @csspart prefix - Styles the element before the chat title (e.g., avatar).\n * @csspart title - Styles the chat header title.\n *\n * @csspart message-area-container - Styles the container holding the messages and (optional) suggestions.\n * @csspart message-list - Styles the message list container.\n * @csspart message-item - Styles each message wrapper.\n * @csspart typing-indicator - Styles the typing indicator container.\n * @csspart typing-dot - Styles individual typing indicator dots.\n *\n * @csspart suggestions-container - Styles the container holding all suggestions.\n * @csspart suggestions-header - Styles the suggestions header.\n * @csspart suggestion - Styles each suggestion item.\n * @csspart suggestion-prefix - Styles the icon or prefix in a suggestion.\n * @csspart suggestion-title - Styles the text/title of a suggestion.\n *\n * @csspart empty-state - Styles the empty state container when there are no messages.\n *\n * @csspart input-area-container - Styles the wrapper around the chat input area.\n * @csspart input-container - Styles the main input container.\n * @csspart input-attachments-container - Styles the container for attachments in the input.\n * @csspart input-attachment-container - Styles a single attachment in the input area.\n * @csspart input-attachment-name - Styles the file name of an attachment.\n * @csspart input-attachment-icon - Styles the icon of an attachment.\n * @csspart text-input - Styles the text input field for typing messages.\n * @csspart input-actions-container - Styles the container for input actions.\n * @csspart input-actions-start - Styles the group of actions at the start of the input after the default file upload.\n * @csspart input-actions-end - Styles the group of actions at the end of the input.\n * @csspart file-upload-container - Styles the container for the file upload input.\n * @csspart file-upload - Styles the file upload input itself.\n * @csspart send-button-container - Styles the container around the send button.\n * @csspart send-button - Styles the send button.\n *\n * @csspart message-container - Styles the container of a single message.\n * @csspart message-list (forwarded) - Styles the internal list of messages.\n * @csspart message-header - Styles the header of a message (e.g., sender, timestamp).\n * @csspart message-content - Styles the text content of a message.\n * @csspart message-attachments-container - Styles the container for message attachments.\n * @csspart message-attachment - Styles a single message attachment.\n * @csspart message-actions-container - Styles the container holding message actions.\n * @csspart message-sent - Styles messages marked as sent by the current user.\n * @csspart attachment-header - Styles the header of an attachment block.\n * @csspart attachment-content - Styles the content of an attachment block.\n * @csspart attachment-icon - Styles the icon of an attachment.\n * @csspart file-name - Styles the file name shown in an attachment.\n */\nexport default class IgcChatComponent extends EventEmitterMixin<\n IgcChatComponentEventMap,\n Constructor<LitElement>\n>(LitElement) {\n public static readonly tagName = 'igc-chat';\n\n public static styles = [styles, shared];\n\n /* blazorSuppress */\n public static register(): void {\n registerComponent(\n IgcChatComponent,\n IgcChatInputComponent,\n IgcChatMessageComponent,\n IgcButtonComponent,\n IgcIconComponent,\n IgcListComponent,\n IgcTooltipComponent,\n IgcToastComponent\n );\n }\n\n private readonly _state = new ChatState(\n this,\n this._updateContext,\n this._updateUserInputContext\n );\n\n private readonly _defaults = Object.freeze<DefaultChatRenderers>({\n typingIndicator: () => this._renderLoadingTemplate(),\n suggestionPrefix: () => this._renderSuggestionPrefix(),\n });\n\n private readonly _slots = addSlotController(this, {\n slots: Slots,\n });\n\n private readonly _context = new ContextProvider(this, {\n context: chatContext,\n initialValue: this._state,\n });\n\n private readonly _userInputContext = new ContextProvider(this, {\n context: chatUserInputContext,\n initialValue: this._state,\n });\n\n @query(IgcChatInputComponent.tagName)\n private readonly _input?: IgcChatInputComponent;\n\n @query('[part=\"typing-indicator\"]')\n private readonly _typingIndicator?: HTMLElement;\n\n @query('[part=\"suggestions-container\"]')\n private readonly _suggestionsContainer?: HTMLElement;\n\n @query('[part=\"message-area-container\"]', true)\n private readonly _scrollContainer!: HTMLElement;\n\n private _updateContext(): void {\n this._context.setValue(this._state, true);\n }\n\n private _updateUserInputContext(): void {\n this._userInputContext.setValue(this._state, true);\n }\n\n /**\n * The list of chat messages currently displayed.\n * Use this property to set or update the message history.\n */\n @property({ attribute: false })\n public set messages(value: IgcChatMessage[]) {\n this._state.messages = value;\n }\n\n public get messages(): IgcChatMessage[] {\n return this._state.messages;\n }\n\n /**\n * The chat message currently being composed but not yet sent.\n * Includes the draft text and any attachments.\n */\n @property({ attribute: false })\n public set draftMessage(value: {\n text: string;\n attachments?: IgcChatMessageAttachment[];\n }) {\n if (this._state && value) {\n this._state.inputValue = value.text;\n this._state.inputAttachments = value.attachments || [];\n this.requestUpdate();\n }\n }\n\n public get draftMessage(): {\n text: string;\n attachments?: IgcChatMessageAttachment[];\n } {\n return {\n text: this._state.inputValue,\n attachments: this._state.inputAttachments,\n };\n }\n\n /**\n * Controls the chat behavior and appearance through a configuration object.\n * Use this to toggle UI options, provide suggestions, templates, etc.\n */\n @property({ attribute: false })\n public set options(value: IgcChatOptions) {\n this._state.options = value;\n }\n\n public get options(): IgcChatOptions | undefined {\n return this._state.options;\n }\n\n /**\n * The resource strings of the chat.\n */\n @property({ attribute: false })\n public resourceStrings = IgcChatResourceStringEN;\n\n constructor() {\n super();\n addThemingController(this, all);\n }\n\n private _getRenderer<U extends keyof DefaultChatRenderers>(\n name: U\n ): DefaultChatRenderers[U] {\n return this._state.options?.renderers\n ? (this._state.options.renderers[name] ?? this._defaults[name])\n : this._defaults[name];\n }\n\n private _handleSuggestionClick(text: string): void {\n this._state.addMessageWithEvent({ text });\n this._input?.focusInput();\n }\n\n /**\n * Scrolls the view to a specific message by id.\n */\n public scrollToMessage(messageId: string): void {\n if (!isEmpty(this.messages)) {\n const message = this.renderRoot.querySelector(`#message-${messageId}`);\n message?.scrollIntoView({ block: 'end', inline: 'end' });\n }\n }\n\n protected override updated(properties: PropertyValues<this>): void {\n if (\n (properties.has('messages') ||\n this._typingIndicator ||\n this._suggestionsContainer) &&\n !this._state.disableAutoScroll\n ) {\n this._scrollToBottom();\n }\n }\n\n private _scrollToBottom(): void {\n const current = this._scrollContainer.scrollTop;\n\n requestAnimationFrame(() => {\n const scrollHeight = this._scrollContainer.scrollHeight;\n if (current < scrollHeight) {\n this._scrollContainer.scrollBy({\n top: Math.abs(scrollHeight - current),\n });\n }\n });\n }\n\n private _renderHeader() {\n const hasContent =\n this._slots.hasAssignedElements('prefix') ||\n this._slots.hasAssignedElements('title') ||\n this._slots.hasAssignedElements('actions') ||\n this._state.options?.headerText;\n\n return html`\n <div part=\"header\" ?hidden=${!hasContent}>\n <slot\n name=\"prefix\"\n ?hidden=${!this._slots.hasAssignedElements('prefix')}\n ></slot>\n <slot name=\"title\">${this._state.options?.headerText}</slot>\n <slot name=\"actions\"></slot>\n </div>\n `;\n }\n\n private _renderMessages() {\n const ctx = { instance: this };\n\n return html`\n <div part=\"message-list\" tabindex=\"0\">\n ${repeat(\n this._state.messages,\n (message) => message.id,\n (message) => {\n return html`\n <igc-chat-message\n id=${`message-${message.id}`}\n part=\"message-item\"\n .message=${message}\n exportparts=\"\n message-container,\n message-list,\n message-header,\n plain-text: message-content,\n message-attachments: message-attachments-container,\n attachment: message-attachment,\n message-actions: message-actions-container,\n sent: message-sent,\n attachment-header,\n attachment-content,\n attachment-icon,\n file-name,\n \"\n >\n </igc-chat-message>\n `;\n }\n )}\n ${this._state.options?.isTyping\n ? html`\n <div part=\"typing-indicator\">\n ${this._getRenderer('typingIndicator')(ctx)}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n private _renderLoadingTemplate() {\n return html`\n <div part=\"typing-dot\"></div>\n <div part=\"typing-dot\"></div>\n <div part=\"typing-dot\"></div>\n <div part=\"typing-dot\"></div>\n `;\n }\n\n private _renderSuggestionPrefix() {\n return html`<igc-icon name=\"auto_suggest\"></igc-icon>`;\n }\n\n private _renderSuggestions() {\n const hasContent = this._slots.hasAssignedElements('suggestions-header');\n const suggestions = this._state.options?.suggestions ?? [];\n const ctx = { instance: this };\n\n return html`\n <div part=\"suggestions-container\">\n <igc-list>\n <igc-list-header part=\"suggestions-header\">\n <span ?hidden=${hasContent}>\n ${this.resourceStrings.suggestionsHeader}\n </span>\n <slot name=\"suggestions-header\"></slot>\n </igc-list-header>\n <slot name=\"suggestions\">\n ${suggestions.map(\n (suggestion) => html`\n <slot name=\"suggestion\">\n <igc-list-item\n part=\"suggestion\"\n @click=${() => this._handleSuggestionClick(suggestion)}\n >\n <span slot=\"start\" part=\"suggestion-prefix\">\n ${this._getRenderer('suggestionPrefix')(ctx)}\n </span>\n <span slot=\"title\" part=\"suggestion-title\"\n >${suggestion}</span\n >\n </igc-list-item>\n </slot>\n `\n )}\n </slot>\n <slot name=\"suggestions-actions\"></slot>\n </igc-list>\n </div>\n `;\n }\n\n private _renderEmptyState() {\n return html`\n <div part=\"empty-state\">\n <slot name=\"empty-state\"></slot>\n </div>\n `;\n }\n\n protected override render() {\n const hasMessages = !isEmpty(this.messages);\n const suggestions = isEmpty(this._state.options?.suggestions ?? [])\n ? nothing\n : this._renderSuggestions();\n\n return html`\n <div part=\"chat-container\">\n ${this._renderHeader()}\n\n <div part=\"message-area-container\">\n ${cache(\n hasMessages || this._state.options?.isTyping\n ? this._renderMessages()\n : this._renderEmptyState()\n )}\n ${this._state.suggestionsPosition === 'below-messages'\n ? suggestions\n : nothing}\n </div>\n\n <igc-chat-input\n exportparts=\"\n input-container: input-area-container,\n input-wrapper: input-container,\n attachments: input-attachments-container,\n attachment-wrapper: input-attachment-container,\n attachment-name: input-attachment-name,\n attachment-icon: input-attachment-icon,\n text-input,\n actions-container: input-actions-container,\n input-actions-start,\n input-actions-end,\n file-upload-container,\n file-upload,\n send-button-container,\n send-button\"\n >\n </igc-chat-input>\n ${this._state.suggestionsPosition === 'below-input'\n ? suggestions\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'igc-chat': IgcChatComponent;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { IgcMessage } from '../types.js';
1
+ import type { IgcChatMessage } from '../types.js';
2
2
  /**
3
3
  * Options to configure the MarkdownMessageRenderer.
4
4
  */
@@ -23,4 +23,4 @@ export interface MarkdownRendererOptions {
23
23
  */
24
24
  sanitizer?: (html: string) => string;
25
25
  }
26
- export declare function createMarkdownRenderer(options?: MarkdownRendererOptions): Promise<(message: IgcMessage) => Promise<unknown>>;
26
+ export declare function createMarkdownRenderer(options?: MarkdownRendererOptions): Promise<(message: IgcChatMessage) => Promise<unknown>>;
@@ -31,7 +31,12 @@ export async function createMarkdownRenderer(options) {
31
31
  });
32
32
  markdown.use(markedShiki({
33
33
  highlight(code, lang, _) {
34
- return highlighter.codeToHtml(code, { lang, themes });
34
+ try {
35
+ return highlighter.codeToHtml(code, { lang, themes });
36
+ }
37
+ catch {
38
+ return `<pre><code>${sanitizer(code)}</code></pre>`;
39
+ }
35
40
  },
36
41
  }));
37
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-renderer.js","sourceRoot":"","sources":["../../../../src/components/chat/extras/markdown-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGpE,MAAM,iBAAiB,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AACtE,MAAM,aAAa,GAAG;IACpB,KAAK,EAAE,cAAc;IACrB,IAAI,EAAE,aAAa;CACpB,CAAC;AA8BF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAAiC;IAEjC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC;IAE3D,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC;QAC1B,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,IAAI;QACT,UAAU,EAAE;YACV;gBACE,IAAI,EAAE,MAAM;gBACZ,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC5B,OAAO,YAAY,IAAI,+CAA+C,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC;gBACtH,CAAC;aACF;SACF;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,OAAO,EAAE,KAAK,IAAI,aAAa,CAAC;QAC/C,MAAM,KAAK,GAAG,OAAO,EAAE,SAAS,IAAI,iBAAiB,CAAC;QAEtD,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC;YAC1C,KAAK;YACL,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;SACnC,CAAC,CAAC;QAEH,QAAQ,CAAC,GAAG,CACV,WAAW,CAAC;YACV,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;gBACrB,OAAO,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACxD,CAAC;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,EAAE,OAAmB,EAAoB,EAAE;QACrD,OAAO,OAAO,CAAC,IAAI;YACjB,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3D,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import DOMPurify from 'dompurify';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { Marked } from 'marked';\nimport markedShiki from 'marked-shiki';\nimport { bundledThemes, createHighlighter } from 'shiki/bundle/web';\nimport type { IgcMessage } from '../types.js';\n\nconst DEFAULT_LANGUAGES = ['javascript', 'typescript', 'html', 'css'];\nconst DEFAULT_THEME = {\n light: 'github-light',\n dark: 'github-dark',\n};\n\n/**\n * Options to configure the MarkdownMessageRenderer.\n */\nexport interface MarkdownRendererOptions {\n /**\n * If true, disables syntax highlighting entirely.\n */\n noHighlighter?: boolean;\n\n /**\n * List of programming languages to support in syntax highlighting.\n */\n languages?: string[];\n\n /**\n * The theme used by the syntax highlighter (e.g., 'github-light').\n */\n theme?: {\n light?: string;\n dark?: string;\n };\n\n /**\n * A custom HTML sanitization function. Defaults to DOMPurify.sanitize.\n */\n sanitizer?: (html: string) => string;\n}\n\nexport async function createMarkdownRenderer(\n options?: MarkdownRendererOptions\n) {\n const sanitizer = options?.sanitizer ?? DOMPurify.sanitize;\n\n const markdown = new Marked({\n breaks: true,\n gfm: true,\n extensions: [\n {\n name: 'link',\n renderer({ href, title, text }) {\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\" ${title ? `title=\"${title}\"` : ''}>${text}</a>`;\n },\n },\n ],\n });\n\n if (!options?.noHighlighter) {\n const themes = options?.theme ?? DEFAULT_THEME;\n const langs = options?.languages ?? DEFAULT_LANGUAGES;\n\n const highlighter = await createHighlighter({\n langs,\n themes: Object.keys(bundledThemes),\n });\n\n markdown.use(\n markedShiki({\n highlight(code, lang, _) {\n return highlighter.codeToHtml(code, { lang, themes });\n },\n })\n );\n }\n\n return async (message: IgcMessage): Promise<unknown> => {\n return message.text\n ? unsafeHTML(sanitizer(await markdown.parse(message.text)))\n : '';\n };\n}\n"]}
1
+ {"version":3,"file":"markdown-renderer.js","sourceRoot":"","sources":["../../../../src/components/chat/extras/markdown-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGpE,MAAM,iBAAiB,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AACtE,MAAM,aAAa,GAAG;IACpB,KAAK,EAAE,cAAc;IACrB,IAAI,EAAE,aAAa;CACpB,CAAC;AA8BF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAAiC;IAEjC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC;IAE3D,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC;QAC1B,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,IAAI;QACT,UAAU,EAAE;YACV;gBACE,IAAI,EAAE,MAAM;gBACZ,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC5B,OAAO,YAAY,IAAI,+CAA+C,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC;gBACtH,CAAC;aACF;SACF;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,OAAO,EAAE,KAAK,IAAI,aAAa,CAAC;QAC/C,MAAM,KAAK,GAAG,OAAO,EAAE,SAAS,IAAI,iBAAiB,CAAC;QAEtD,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC;YAC1C,KAAK;YACL,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;SACnC,CAAC,CAAC;QAEH,QAAQ,CAAC,GAAG,CACV,WAAW,CAAC;YACV,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;gBACrB,IAAI,CAAC;oBACH,OAAO,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACxD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,cAAc,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC;gBACtD,CAAC;YACH,CAAC;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,EAAE,OAAuB,EAAoB,EAAE;QACzD,OAAO,OAAO,CAAC,IAAI;YACjB,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3D,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import DOMPurify from 'dompurify';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { Marked } from 'marked';\nimport markedShiki from 'marked-shiki';\nimport { bundledThemes, createHighlighter } from 'shiki/bundle/web';\nimport type { IgcChatMessage } from '../types.js';\n\nconst DEFAULT_LANGUAGES = ['javascript', 'typescript', 'html', 'css'];\nconst DEFAULT_THEME = {\n light: 'github-light',\n dark: 'github-dark',\n};\n\n/**\n * Options to configure the MarkdownMessageRenderer.\n */\nexport interface MarkdownRendererOptions {\n /**\n * If true, disables syntax highlighting entirely.\n */\n noHighlighter?: boolean;\n\n /**\n * List of programming languages to support in syntax highlighting.\n */\n languages?: string[];\n\n /**\n * The theme used by the syntax highlighter (e.g., 'github-light').\n */\n theme?: {\n light?: string;\n dark?: string;\n };\n\n /**\n * A custom HTML sanitization function. Defaults to DOMPurify.sanitize.\n */\n sanitizer?: (html: string) => string;\n}\n\nexport async function createMarkdownRenderer(\n options?: MarkdownRendererOptions\n) {\n const sanitizer = options?.sanitizer ?? DOMPurify.sanitize;\n\n const markdown = new Marked({\n breaks: true,\n gfm: true,\n extensions: [\n {\n name: 'link',\n renderer({ href, title, text }) {\n return `<a href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\" ${title ? `title=\"${title}\"` : ''}>${text}</a>`;\n },\n },\n ],\n });\n\n if (!options?.noHighlighter) {\n const themes = options?.theme ?? DEFAULT_THEME;\n const langs = options?.languages ?? DEFAULT_LANGUAGES;\n\n const highlighter = await createHighlighter({\n langs,\n themes: Object.keys(bundledThemes),\n });\n\n markdown.use(\n markedShiki({\n highlight(code, lang, _) {\n try {\n return highlighter.codeToHtml(code, { lang, themes });\n } catch {\n return `<pre><code>${sanitizer(code)}</code></pre>`;\n }\n },\n })\n );\n }\n\n return async (message: IgcChatMessage): Promise<unknown> => {\n return message.text\n ? unsafeHTML(sanitizer(await markdown.parse(message.text)))\n : '';\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { LitElement } from 'lit';
2
- import type { IgcMessage } from './types.js';
2
+ import type { IgcChatMessage } from './types.js';
3
3
  /**
4
4
  * A component that renders message attachments within a chat.
5
5
  *
@@ -28,7 +28,7 @@ export default class IgcMessageAttachmentsComponent extends LitElement {
28
28
  /**
29
29
  * The array of attachments to render.
30
30
  */
31
- message?: IgcMessage;
31
+ message?: IgcChatMessage;
32
32
  constructor();
33
33
  private _getRenderer;
34
34
  private _handleHeaderClick;