@memberjunction/ng-composer 6.2.0-edge.0 → 6.2.0-edge.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.
@@ -20,7 +20,11 @@ import * as i0 from "@angular/core";
20
20
  * - Conversation management
21
21
  */
22
22
  export declare class MessageInputBoxComponent {
23
- mentionEditor?: MentionEditorComponent;
23
+ MentionEditor?: MentionEditorComponent;
24
+ /** @deprecated Use {@link MentionEditor}. */
25
+ get mentionEditor(): MentionEditorComponent | undefined;
26
+ /** @deprecated Use {@link MentionEditor}. */
27
+ set mentionEditor(value: MentionEditorComponent | undefined);
24
28
  Placeholder: string;
25
29
  Disabled: boolean;
26
30
  Value: string;
@@ -171,6 +175,8 @@ export declare class MessageInputBoxComponent {
171
175
  InsertMention(suggestion: MentionSuggestion, focus?: boolean): boolean;
172
176
  /** Focus with the caret at the end of content (see MentionEditorComponent.FocusCaretAtEnd). */
173
177
  FocusCaretAtEnd(): boolean;
178
+ Focus(): void;
179
+ /** @deprecated Use {@link Focus}. */
174
180
  focus(): void;
175
181
  /**
176
182
  * Get mention chip data including configuration presets
@@ -1 +1 @@
1
- {"version":3,"file":"message-input-box.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/message/message-input-box.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-input-box.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/message/message-input-box.component.ts"],"names":[],"mappings":"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"}
@@ -89,7 +89,15 @@ function MessageInputBoxComponent_Conditional_4_Template(rf, ctx) { if (rf & 1)
89
89
  * - Conversation management
90
90
  */
91
91
  export class MessageInputBoxComponent {
92
- mentionEditor;
92
+ MentionEditor;
93
+ /** @deprecated Use {@link MentionEditor}. */
94
+ get mentionEditor() {
95
+ return this.MentionEditor;
96
+ }
97
+ /** @deprecated Use {@link MentionEditor}. */
98
+ set mentionEditor(value) {
99
+ this.MentionEditor = value;
100
+ }
93
101
  Placeholder = 'Type your message to start a new conversation...';
94
102
  Disabled = false;
95
103
  Value = '';
@@ -141,7 +149,7 @@ export class MessageInputBoxComponent {
141
149
  * and would leave the button permanently unpressed if nobody bound it.
142
150
  */
143
151
  get SkillsActive() {
144
- return this.mentionEditor?.IsTriggerOpen('/') ?? false;
152
+ return this.MentionEditor?.IsTriggerOpen('/') ?? false;
145
153
  }
146
154
  /** Composer lost focus — hosts persist drafts on this. */
147
155
  Blurred = new EventEmitter();
@@ -203,7 +211,7 @@ export class MessageInputBoxComponent {
203
211
  // counting opens over-counted) and re-captured the trigger's baseline at the new caret, which
204
212
  // corrupts the query offset once anything has been typed.
205
213
  if (this.SkillsActive) {
206
- this.mentionEditor?.closeMentionDropdown();
214
+ this.MentionEditor?.closeMentionDropdown();
207
215
  return;
208
216
  }
209
217
  const args = new BeforeSkillsOpenedEventArgs();
@@ -212,7 +220,7 @@ export class MessageInputBoxComponent {
212
220
  return;
213
221
  }
214
222
  const anchor = event?.currentTarget ?? null;
215
- if (this.mentionEditor?.OpenTrigger('/', anchor)) {
223
+ if (this.MentionEditor?.OpenTrigger('/', anchor)) {
216
224
  this.AfterSkillsOpened.emit();
217
225
  }
218
226
  }
@@ -224,7 +232,7 @@ export class MessageInputBoxComponent {
224
232
  }
225
233
  get CanSend() {
226
234
  const hasText = this.Value.trim().length > 0;
227
- const hasAttachments = this.mentionEditor?.hasAttachments() || false;
235
+ const hasAttachments = this.MentionEditor?.hasAttachments() || false;
228
236
  return !this.Disabled && (hasText || hasAttachments);
229
237
  }
230
238
  /**
@@ -273,12 +281,12 @@ export class MessageInputBoxComponent {
273
281
  OnSendClick() {
274
282
  if (this.CanSend) {
275
283
  // Get plain text with JSON-encoded mentions (preserves configuration info)
276
- const textToSend = this.mentionEditor?.getPlainTextWithJsonMentions() || this.Value.trim();
284
+ const textToSend = this.MentionEditor?.getPlainTextWithJsonMentions() || this.Value.trim();
277
285
  this.TextSubmitted.emit(textToSend);
278
286
  this.Value = ''; // Clear input after sending
279
287
  // Clear the editor content
280
- if (this.mentionEditor) {
281
- this.mentionEditor.clear();
288
+ if (this.MentionEditor) {
289
+ this.MentionEditor.clear();
282
290
  }
283
291
  this.ValueChange.emit(this.Value);
284
292
  }
@@ -293,7 +301,7 @@ export class MessageInputBoxComponent {
293
301
  if (target.closest('.send-button-icon')) {
294
302
  return;
295
303
  }
296
- const editor = this.mentionEditor?.editorRef?.nativeElement;
304
+ const editor = this.MentionEditor?.editorRef?.nativeElement;
297
305
  if (!editor)
298
306
  return;
299
307
  // If clicking directly on the editor or its children, let the browser handle cursor placement
@@ -316,48 +324,52 @@ export class MessageInputBoxComponent {
316
324
  */
317
325
  /** Inserts a resolved mention chip + space and focuses (see MentionEditorComponent.InsertMention). */
318
326
  InsertMention(suggestion, focus = true) {
319
- return this.mentionEditor?.InsertMention(suggestion, focus) ?? false;
327
+ return this.MentionEditor?.InsertMention(suggestion, focus) ?? false;
320
328
  }
321
329
  /** Focus with the caret at the end of content (see MentionEditorComponent.FocusCaretAtEnd). */
322
330
  FocusCaretAtEnd() {
323
- return this.mentionEditor?.FocusCaretAtEnd() ?? false;
331
+ return this.MentionEditor?.FocusCaretAtEnd() ?? false;
324
332
  }
325
- focus() {
326
- const editor = this.mentionEditor?.editorRef?.nativeElement;
333
+ Focus() {
334
+ const editor = this.MentionEditor?.editorRef?.nativeElement;
327
335
  if (editor) {
328
336
  editor.focus();
329
337
  }
330
338
  }
339
+ /** @deprecated Use {@link Focus}. */
340
+ focus() {
341
+ return this.Focus();
342
+ }
331
343
  /**
332
344
  * Get mention chip data including configuration presets
333
345
  */
334
346
  GetMentionChipsData() {
335
- return this.mentionEditor?.getMentionChipsData() || [];
347
+ return this.MentionEditor?.getMentionChipsData() || [];
336
348
  }
337
349
  /**
338
350
  * Get pending attachments from the editor
339
351
  */
340
352
  GetPendingAttachments() {
341
- return this.mentionEditor?.getPendingAttachments() || [];
353
+ return this.MentionEditor?.getPendingAttachments() || [];
342
354
  }
343
355
  /**
344
356
  * Open file picker programmatically
345
357
  */
346
358
  OpenFilePicker() {
347
- this.mentionEditor?.openFilePicker();
359
+ this.MentionEditor?.openFilePicker();
348
360
  }
349
361
  /**
350
362
  * Add an artifact as a pending attachment (called by parent after artifact selection)
351
363
  */
352
364
  AddArtifactAttachment(artifact) {
353
- return this.mentionEditor?.AddArtifactAttachment(artifact);
365
+ return this.MentionEditor?.AddArtifactAttachment(artifact);
354
366
  }
355
367
  static ɵfac = function MessageInputBoxComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MessageInputBoxComponent)(); };
356
368
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MessageInputBoxComponent, selectors: [["mj-message-input-box"]], viewQuery: function MessageInputBoxComponent_Query(rf, ctx) { if (rf & 1) {
357
369
  i0.ɵɵviewQuery(_c0, 5);
358
370
  } if (rf & 2) {
359
371
  let _t;
360
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.mentionEditor = _t.first);
372
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.MentionEditor = _t.first);
361
373
  } }, inputs: { Placeholder: "Placeholder", Disabled: "Disabled", Value: "Value", ShowCharacterCount: "ShowCharacterCount", EnableMentions: "EnableMentions", TriggerProviders: "TriggerProviders", ExcludedTriggerKeys: "ExcludedTriggerKeys", Provider: "Provider", CurrentUser: "CurrentUser", Rows: "Rows", EnableAttachments: "EnableAttachments", MaxAttachments: "MaxAttachments", MaxAttachmentSizeBytes: "MaxAttachmentSizeBytes", AcceptedFileTypes: "AcceptedFileTypes", EnableRealtime: "EnableRealtime", VoiceActive: "VoiceActive", CanStartRealtime: "CanStartRealtime", EnablePlanMode: "EnablePlanMode", PlanModeActive: "PlanModeActive", EnableSkills: "EnableSkills" }, outputs: { Blurred: "Blurred", TextSubmitted: "TextSubmitted", ValueChange: "ValueChange", AttachmentsChanged: "AttachmentsChanged", AttachmentError: "AttachmentError", AttachmentClicked: "AttachmentClicked", VoiceRequested: "VoiceRequested", VoiceOptionsRequested: "VoiceOptionsRequested", PlanModeToggle: "PlanModeToggle", BeforeSkillsOpened: "BeforeSkillsOpened", AfterSkillsOpened: "AfterSkillsOpened" }, standalone: false, decls: 7, vars: 14, consts: [["mentionEditor", ""], [1, "message-input-box-container", 3, "click"], [1, "input-wrapper"], [3, "ngModelChange", "valueChange", "enterPressed", "mentionSelected", "attachmentsChanged", "attachmentError", "attachmentClicked", "editorBlurred", "placeholder", "disabled", "currentUser", "enableMentions", "TriggerProviders", "ExcludedTriggerKeys", "Provider", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "ngModel"], [1, "attach-buttons"], ["title", "Send message (Enter)", 1, "send-button-icon", 3, "click", "disabled"], [1, "fa-solid", "fa-paper-plane"], ["aria-haspopup", "true", "title", "Skills, or type / in the message box", "aria-label", "Show skills", 1, "attach-button-icon", "skills-button-icon", 3, "skills-button-icon--active", "disabled"], ["aria-label", "Toggle Plan Mode", 1, "attach-button-icon", "plan-mode-button-icon", 3, "plan-mode-button-icon--active", "disabled", "title"], ["title", "Attach file", 1, "attach-button-icon", 3, "disabled"], ["aria-haspopup", "true", "title", "Skills, or type / in the message box", "aria-label", "Show skills", 1, "attach-button-icon", "skills-button-icon", 3, "mousedown", "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-wand-magic-sparkles"], ["aria-label", "Toggle Plan Mode", 1, "attach-button-icon", "plan-mode-button-icon", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-route"], ["title", "Attach file", 1, "attach-button-icon", 3, "click", "disabled"], [1, "fa-solid", "fa-paperclip"], ["aria-label", "Start a voice call", 1, "attach-button-icon", "voice-button-icon", 3, "click", "disabled", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-phone"], ["title", "Voice call options (choose agent and voice model)", "aria-label", "Voice call options", 1, "attach-button-icon", "voice-options-button-icon", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"]], template: function MessageInputBoxComponent_Template(rf, ctx) { if (rf & 1) {
362
374
  const _r1 = i0.ɵɵgetCurrentView();
363
375
  i0.ɵɵelementStart(0, "div", 1);
@@ -384,7 +396,7 @@ export class MessageInputBoxComponent {
384
396
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MessageInputBoxComponent, [{
385
397
  type: Component,
386
398
  args: [{ standalone: false, selector: 'mj-message-input-box', template: "<div class=\"message-input-box-container\" (click)=\"OnContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"Placeholder\"\n [disabled]=\"Disabled\"\n [currentUser]=\"CurrentUser\"\n [enableMentions]=\"EnableMentions\"\n [TriggerProviders]=\"TriggerProviders\"\n [ExcludedTriggerKeys]=\"ExcludedTriggerKeys\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"EnableAttachments\"\n [maxAttachments]=\"MaxAttachments\"\n [maxAttachmentSizeBytes]=\"MaxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"AcceptedFileTypes\"\n [(ngModel)]=\"Value\"\n (valueChange)=\"OnValueChange($event)\"\n (enterPressed)=\"OnEnterPressed($event)\"\n (mentionSelected)=\"OnMentionSelected($event)\"\n (attachmentsChanged)=\"OnAttachmentsChanged($event)\"\n (attachmentError)=\"OnAttachmentError($event)\"\n (attachmentClicked)=\"OnAttachmentClicked($event)\"\n (editorBlurred)=\"Blurred.emit()\">\n </mj-mention-editor>\n\n <!-- Attach + voice + plan-mode buttons - Positioned over editor -->\n @if (EnableAttachments || EnableRealtime || EnablePlanMode || EnableSkills) {\n <div class=\"attach-buttons\">\n @if (EnableSkills) {\n <button\n class=\"attach-button-icon skills-button-icon\"\n [class.skills-button-icon--active]=\"SkillsActive\"\n [disabled]=\"Disabled\"\n [attr.aria-expanded]=\"SkillsActive\"\n aria-haspopup=\"true\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"OnSkillsClick($event); $event.stopPropagation()\"\n title=\"Skills, or type / in the message box\"\n aria-label=\"Show skills\"\n >\n <i class=\"fa-solid fa-wand-magic-sparkles\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (EnablePlanMode) {\n <button\n class=\"attach-button-icon plan-mode-button-icon\"\n [class.plan-mode-button-icon--active]=\"PlanModeActive\"\n [disabled]=\"Disabled\"\n [attr.aria-pressed]=\"PlanModeActive\"\n (click)=\"PlanModeToggle.emit(); $event.stopPropagation()\"\n [title]=\"PlanModeActive ? 'Plan Mode ON \u2014 the agent presents a plan for your approval before it acts' : 'Plan Mode: have the agent present a plan for your approval before it acts'\"\n aria-label=\"Toggle Plan Mode\"\n >\n <i class=\"fa-solid fa-route\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (EnableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"Disabled\"\n (click)=\"OpenFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n }\n @if (EnableRealtime) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"VoiceActive\"\n [disabled]=\"!CanStartRealtime\"\n (click)=\"OnRealtimeClick(); $event.stopPropagation()\"\n [title]=\"VoiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!CanStartRealtime\"\n (click)=\"OnRealtimeOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!CanSend\"\n (click)=\"OnSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n", styles: [".message-input-box-container {\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-border-default);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-sm);\n transition: all 0.2s ease;\n overflow: visible;\n position: relative;\n cursor: text;\n}\n.message-input-box-container:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 4px 16px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.input-wrapper {\n position: relative;\n display: flex;\n align-items: flex-end;\n padding: 5px;\n}\n.input-wrapper mj-mention-editor {\n flex: 1;\n display: block;\n}\n\n.message-input-box-textarea {\n flex: 1;\n min-height: 100px;\n padding: 1rem;\n padding-right: 3.5rem;\n border: 0 !important;\n outline: 0 !important;\n box-shadow: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n appearance: none !important;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n resize: vertical;\n background: transparent;\n color: var(--mj-text-primary);\n border: 0 !important;\n}\n.message-input-box-textarea::placeholder {\n color: var(--mj-text-muted);\n}\n.message-input-box-textarea:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n background: var(--mj-bg-surface-sunken);\n}\n.message-input-box-textarea:focus, .message-input-box-textarea:active, .message-input-box-textarea:focus-visible {\n outline: 0 !important;\n box-shadow: none !important;\n}\n\n.send-button-icon {\n position: absolute;\n bottom: 0.75rem;\n right: 0.75rem;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.send-button-icon i {\n font-size: 1rem;\n}\n.send-button-icon:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n}\n.send-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.send-button-icon:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Attach buttons container */\n.attach-buttons {\n position: absolute;\n bottom: 0.75rem;\n right: 3rem;\n display: flex;\n gap: 2px;\n}\n.attach-button-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n color: var(--mj-text-secondary);\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n.attach-button-icon i {\n font-size: 1rem;\n}\n.attach-button-icon:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n color: var(--mj-brand-primary);\n transform: scale(1.05);\n}\n.attach-button-icon:active:not(:disabled) {\n transform: scale(0.95);\n}\n.attach-button-icon:disabled {\n color: var(--mj-text-muted);\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Plan Mode toggle \u2014 inherits .attach-button-icon; when active it fills with the brand color\n so the on/off state reads clearly at a glance (parallels the voice button's active state). */\n.plan-mode-button-icon--active:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.plan-mode-button-icon--active:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n/* Same active treatment as Plan Mode \u2014 the two are peers in the strip, so a different one would\n read as a different KIND of control. Everything else comes from .attach-button-icon. */\n.skills-button-icon--active:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n.skills-button-icon--active:not(:disabled):hover {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n color: var(--mj-text-inverse);\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .message-input-box-container {\n border-radius: 10px;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-text-primary) 6%, transparent);\n }\n .message-input-box-textarea {\n min-height: 80px;\n padding: 0.75rem;\n padding-right: 3rem;\n font-size: 16px;\n line-height: 1.4;\n }\n .send-button-icon {\n width: 32px;\n height: 32px;\n bottom: 0.625rem;\n right: 0.625rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.625rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .message-input-box-container {\n border-radius: 8px;\n border-width: 1.5px;\n }\n .message-input-box-textarea {\n min-height: 60px;\n padding: 0.625rem;\n padding-right: 2.75rem;\n font-size: 16px;\n line-height: 1.3;\n }\n .send-button-icon {\n width: 36px;\n height: 36px;\n bottom: 0.5rem;\n right: 0.5rem;\n border-radius: 6px;\n }\n .send-button-icon i {\n font-size: 0.875rem;\n }\n .attach-buttons {\n bottom: 0.5rem;\n right: 2.75rem;\n }\n .attach-button-icon {\n width: 32px;\n height: 32px;\n }\n .attach-button-icon i {\n font-size: 0.875rem;\n }\n}\n\n/* Voice call button \u2014 a phone icon in the attach-buttons cluster, left of send.\n Inherits .attach-button-icon base. Subtle brand glow on hover; active state (call\n live) renders a brand-color tint. The orb visual now lives ONLY inside the call\n overlay's banner. */\n.voice-button-icon i {\n color: var(--mj-brand-primary);\n}\n.voice-button-icon:hover:not(:disabled) i {\n filter: drop-shadow(0 0 4px color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n}\n.voice-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n.voice-button-icon--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n.voice-button-icon--active:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n\n/* Voice OPTIONS caret \u2014 a slim chevron hugging the phone button. Opens the agent/model\n picker; intentionally quieter (smaller icon, narrower hit area) than the phone so the\n common instant-start click stays the visual primary. */\n.voice-options-button-icon {\n width: 20px;\n margin-left: -4px;\n}\n.voice-options-button-icon i {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n.voice-options-button-icon:hover:not(:disabled) i {\n color: var(--mj-brand-primary);\n}\n.voice-options-button-icon:disabled i {\n color: var(--mj-text-disabled);\n}\n"] }]
387
- }], null, { mentionEditor: [{
399
+ }], null, { MentionEditor: [{
388
400
  type: ViewChild,
389
401
  args: ['mentionEditor']
390
402
  }], Placeholder: [{
@@ -1 +1 @@
1
- {"version":3,"file":"message-input-box.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/message-input-box.component.ts","../../../../src/lib/components/message/message-input-box.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';\nimport { IMetadataProvider, UserInfo } from '@memberjunction/core';\nimport { ComposerTriggerProvider, MentionSuggestion } from '../../composer-trigger-provider';\nimport { MentionEditorComponent, PendingAttachment } from '../mention/mention-editor.component';\nimport { BeforeSkillsOpenedEventArgs } from '../../events/composer-events';\n\n/**\n * Reusable message input box component (presentational)\n * Now uses MentionEditorComponent for rich @mention functionality with chips\n *\n * Handles:\n * - Text input with keyboard shortcuts via MentionEditorComponent\n * - @mention autocomplete with visual chips (contentEditable)\n * - Send button\n *\n * Does NOT handle:\n * - Saving messages to database\n * - Agent invocation\n * - Artifact creation\n * - Conversation management\n */\n@Component({\n standalone: false,\n selector: 'mj-message-input-box',\n templateUrl: './message-input-box.component.html',\n styleUrls: ['./message-input-box.component.css']\n})\nexport class MessageInputBoxComponent {\n @ViewChild('mentionEditor') mentionEditor?: MentionEditorComponent;\n\n @Input() Placeholder: string = 'Type your message to start a new conversation...';\n @Input() Disabled: boolean = false;\n @Input() Value: string = '';\n @Input() ShowCharacterCount: boolean = false;\n /** Master switch for all mention/command triggers (pass-through to the mention editor). */\n @Input() EnableMentions: boolean = true;\n /** Explicit trigger-provider list (pass-through to the mention editor; explicit list wins over discovery). */\n @Input() TriggerProviders: ComposerTriggerProvider[] | null = null;\n /** Discovery-mode filter: provider Keys to skip (pass-through to the mention editor). */\n @Input() ExcludedTriggerKeys: string[] = [];\n /** Optional metadata provider scoping this composer (pass-through to the mention editor). */\n @Input() Provider: IMetadataProvider | null = null;\n @Input() CurrentUser?: UserInfo;\n @Input() Rows: number = 3;\n\n // Attachment settings\n @Input() EnableAttachments: boolean = true;\n @Input() MaxAttachments: number = 10;\n @Input() MaxAttachmentSizeBytes: number = 20 * 1024 * 1024; // 20MB\n @Input() AcceptedFileTypes: string = 'image/*';\n\n /** Shows the in-composer mic button when true. */\n @Input() EnableRealtime: boolean = false;\n /** Whether a realtime voice session is currently active (mic renders in its active state). */\n @Input() VoiceActive: boolean = false;\n /** Whether a voice session can be started right now (mic Disabled when false). */\n @Input() CanStartRealtime: boolean = true;\n /** Shows the in-composer Plan Mode toggle button when true. */\n @Input() EnablePlanMode: boolean = false;\n /** Current Plan Mode toggle state (renders the button in its active state). */\n @Input() PlanModeActive: boolean = false;\n /**\n * Shows the in-composer Skills button when true.\n *\n * Gated separately from `EnableMentions` because a host can have the `/` trigger active and\n * still not want the button — but the common case is that a composer offering skill commands\n * should advertise them, since `/` is otherwise invisible.\n */\n @Input() EnableSkills: boolean = false;\n /**\n * True while the skill dropdown is open, driving the button's expanded state.\n *\n * Note the ARIA differs from Plan Mode next to it, deliberately: Plan Mode is a toggle BUTTON\n * (a mode that stays on), so `aria-pressed` is right there. This one opens a popup, so it is\n * `aria-expanded` + `aria-haspopup`. Using `aria-pressed` here would have a screen reader\n * announce \"pressed\" for something that actually just revealed a list.\n *\n * DERIVED, not an @Input, and this is the difference from Plan Mode. Plan Mode's active state is\n * a persisted user preference the host owns and threads down. \"Is the skill dropdown open\" is\n * intrinsic to this composer, so an @Input would be an API the host cannot meaningfully answer\n * and would leave the button permanently unpressed if nobody bound it.\n */\n get SkillsActive(): boolean {\n return this.mentionEditor?.IsTriggerOpen('/') ?? false;\n }\n\n /** Composer lost focus — hosts persist drafts on this. */\n @Output() Blurred = new EventEmitter<void>();\n @Output() TextSubmitted = new EventEmitter<string>();\n @Output() ValueChange = new EventEmitter<string>();\n @Output() AttachmentsChanged = new EventEmitter<PendingAttachment[]>();\n @Output() AttachmentError = new EventEmitter<string>();\n @Output() AttachmentClicked = new EventEmitter<PendingAttachment>();\n /** Emitted when the user clicks the mic button to start/stop a voice session. */\n @Output() VoiceRequested = new EventEmitter<void>();\n /**\n * Emitted when the user clicks the small caret next to the phone button — the host opens the\n * voice agent/model picker so call options (which agent, which voice model) stay reachable\n * without adding friction to the plain phone click's instant-start path.\n */\n @Output() VoiceOptionsRequested = new EventEmitter<void>();\n /** Emitted when the user clicks the in-composer Plan Mode toggle button. */\n @Output() PlanModeToggle = new EventEmitter<void>();\n /**\n * Fired BEFORE the Skills button opens the dropdown. Flip `Cancel` to veto — a host gating\n * skills by entitlement, or surfacing them elsewhere, blocks it here.\n *\n * A pair rather than a lone emitter because this is an ACTION a host might reasonably refuse\n * (UI_LAYERING_GUIDE section 6, rule 1). Handlers must be synchronous; `Cancel` travels back\n * through EventEmitter's synchronous dispatch.\n */\n @Output() BeforeSkillsOpened = new EventEmitter<BeforeSkillsOpenedEventArgs>();\n /**\n * Fired AFTER the dropdown actually opened. Not emitted on the canceled path, and not emitted\n * when no active provider owns the trigger — so a host counting this counts dropdowns the user\n * saw, rather than clicks.\n */\n @Output() AfterSkillsOpened = new EventEmitter<void>();\n\n /**\n * Open the skill-command dropdown, the same one `/` opens.\n *\n * Routed through the editor's OpenTrigger rather than a parallel menu so permission filtering,\n * per-skill icons and chip insertion all stay in one implementation.\n */\n /**\n * NOTE: the template pairs this with\n * `(mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"`, and BOTH halves are\n * load-bearing.\n *\n * `preventDefault` — a <button> takes focus on mousedown, which blurs the editor, and the editor\n * closes its dropdown 200ms after losing focus. Without it the menu opened and then shut itself.\n *\n * `stopPropagation` — the editor's click-away listener is on `document:mousedown` and exempts only\n * presses inside the EDITOR's host. This button is a sibling of `<mj-mention-editor>`, so a press\n * on it read as an outside press: mousedown closed the dropdown, then click saw `SkillsActive`\n * already false and reopened it. The menu blinked, could not be dismissed by the button that\n * opened it, and the Before/After pair fired on every click — the exact over-counting the toggle\n * branch below exists to prevent. Stopping propagation states that this press belongs to the\n * dropdown machinery.\n */\n OnSkillsClick(event?: Event): void {\n // Toggle closed first. A disclosure button has to be able to close what it opened, and without\n // this a second click re-ran the open path: it re-emitted the Before/After pair (so a host\n // counting opens over-counted) and re-captured the trigger's baseline at the new caret, which\n // corrupts the query offset once anything has been typed.\n if (this.SkillsActive) {\n this.mentionEditor?.closeMentionDropdown();\n return;\n }\n const args = new BeforeSkillsOpenedEventArgs();\n this.BeforeSkillsOpened.emit(args);\n if (args.Cancel) {\n return;\n }\n const anchor = (event?.currentTarget as HTMLElement | undefined) ?? null;\n if (this.mentionEditor?.OpenTrigger('/', anchor)) {\n this.AfterSkillsOpened.emit();\n }\n }\n\n OnRealtimeClick(): void {\n this.VoiceRequested.emit();\n }\n\n OnRealtimeOptionsClick(): void {\n this.VoiceOptionsRequested.emit();\n }\n\n get CanSend(): boolean {\n const hasText = this.Value.trim().length > 0;\n const hasAttachments = this.mentionEditor?.hasAttachments() || false;\n return !this.Disabled && (hasText || hasAttachments);\n }\n\n /**\n * Handle Value changes from MentionEditorComponent\n */\n OnValueChange(newValue: string): void {\n this.Value = newValue;\n this.ValueChange.emit(this.Value);\n }\n\n /**\n * Handle attachment changes from MentionEditorComponent\n */\n OnAttachmentsChanged(attachments: PendingAttachment[]): void {\n this.AttachmentsChanged.emit(attachments);\n }\n\n /**\n * Handle attachment errors from MentionEditorComponent\n */\n OnAttachmentError(error: string): void {\n this.AttachmentError.emit(error);\n }\n\n /**\n * Handle attachment click from MentionEditorComponent\n */\n OnAttachmentClicked(attachment: PendingAttachment): void {\n this.AttachmentClicked.emit(attachment);\n }\n\n /**\n * Handle Enter key from MentionEditorComponent\n * Extracts plain text with JSON-encoded mentions for message submission\n */\n OnEnterPressed(_text: string): void {\n this.OnSendClick();\n }\n\n /**\n * Handle mention selection from MentionEditorComponent\n */\n OnMentionSelected(suggestion: MentionSuggestion): void {\n // MentionEditorComponent already inserts the mention chip\n // This is just for additional tracking/analytics if needed\n }\n\n /**\n * Send the message\n * Extracts plain text with JSON-encoded mentions for proper persistence\n */\n OnSendClick(): void {\n if (this.CanSend) {\n // Get plain text with JSON-encoded mentions (preserves configuration info)\n const textToSend = this.mentionEditor?.getPlainTextWithJsonMentions() || this.Value.trim();\n this.TextSubmitted.emit(textToSend);\n this.Value = ''; // Clear input after sending\n\n // Clear the editor content\n if (this.mentionEditor) {\n this.mentionEditor.clear();\n }\n\n this.ValueChange.emit(this.Value);\n }\n }\n\n /**\n * Handle clicks on the container - focus the mention editor\n * Only moves cursor to end if clicking outside the contentEditable area\n */\n OnContainerClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n\n // Don't handle clicks on the send button\n if (target.closest('.send-button-icon')) {\n return;\n }\n\n const editor = this.mentionEditor?.editorRef?.nativeElement;\n if (!editor) return;\n\n // If clicking directly on the editor or its children, let the browser handle cursor placement\n if (target === editor || editor.contains(target)) {\n return;\n }\n\n // Only if clicking on the container (empty space), focus and move cursor to end\n editor.focus();\n const selection = window.getSelection();\n const range = document.createRange();\n\n if (selection) {\n range.selectNodeContents(editor);\n range.collapse(false); // Collapse to end\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n\n /**\n * Public method to focus the input programmatically\n */\n /** Inserts a resolved mention chip + space and focuses (see MentionEditorComponent.InsertMention). */\n InsertMention(suggestion: MentionSuggestion, focus: boolean = true): boolean {\n return this.mentionEditor?.InsertMention(suggestion, focus) ?? false;\n }\n\n /** Focus with the caret at the end of content (see MentionEditorComponent.FocusCaretAtEnd). */\n FocusCaretAtEnd(): boolean {\n return this.mentionEditor?.FocusCaretAtEnd() ?? false;\n }\n\n focus(): void {\n const editor = this.mentionEditor?.editorRef?.nativeElement;\n if (editor) {\n editor.focus();\n }\n }\n\n /**\n * Get mention chip data including configuration presets\n */\n GetMentionChipsData(): Array<{ id: string; type: string; name: string; presetId?: string; presetName?: string }> {\n return this.mentionEditor?.getMentionChipsData() || [];\n }\n\n /**\n * Get pending attachments from the editor\n */\n GetPendingAttachments(): PendingAttachment[] {\n return this.mentionEditor?.getPendingAttachments() || [];\n }\n\n /**\n * Open file picker programmatically\n */\n OpenFilePicker(): void {\n this.mentionEditor?.openFilePicker();\n }\n\n /**\n * Add an artifact as a pending attachment (called by parent after artifact selection)\n */\n AddArtifactAttachment(artifact: {\n fileID: string; fileName: string; mimeType: string;\n sizeBytes: number; artifactVersionId?: string;\n }): PendingAttachment | undefined {\n return this.mentionEditor?.AddArtifactAttachment(artifact);\n }\n}\n","<div class=\"message-input-box-container\" (click)=\"OnContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"Placeholder\"\n [disabled]=\"Disabled\"\n [currentUser]=\"CurrentUser\"\n [enableMentions]=\"EnableMentions\"\n [TriggerProviders]=\"TriggerProviders\"\n [ExcludedTriggerKeys]=\"ExcludedTriggerKeys\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"EnableAttachments\"\n [maxAttachments]=\"MaxAttachments\"\n [maxAttachmentSizeBytes]=\"MaxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"AcceptedFileTypes\"\n [(ngModel)]=\"Value\"\n (valueChange)=\"OnValueChange($event)\"\n (enterPressed)=\"OnEnterPressed($event)\"\n (mentionSelected)=\"OnMentionSelected($event)\"\n (attachmentsChanged)=\"OnAttachmentsChanged($event)\"\n (attachmentError)=\"OnAttachmentError($event)\"\n (attachmentClicked)=\"OnAttachmentClicked($event)\"\n (editorBlurred)=\"Blurred.emit()\">\n </mj-mention-editor>\n\n <!-- Attach + voice + plan-mode buttons - Positioned over editor -->\n @if (EnableAttachments || EnableRealtime || EnablePlanMode || EnableSkills) {\n <div class=\"attach-buttons\">\n @if (EnableSkills) {\n <button\n class=\"attach-button-icon skills-button-icon\"\n [class.skills-button-icon--active]=\"SkillsActive\"\n [disabled]=\"Disabled\"\n [attr.aria-expanded]=\"SkillsActive\"\n aria-haspopup=\"true\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"OnSkillsClick($event); $event.stopPropagation()\"\n title=\"Skills, or type / in the message box\"\n aria-label=\"Show skills\"\n >\n <i class=\"fa-solid fa-wand-magic-sparkles\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (EnablePlanMode) {\n <button\n class=\"attach-button-icon plan-mode-button-icon\"\n [class.plan-mode-button-icon--active]=\"PlanModeActive\"\n [disabled]=\"Disabled\"\n [attr.aria-pressed]=\"PlanModeActive\"\n (click)=\"PlanModeToggle.emit(); $event.stopPropagation()\"\n [title]=\"PlanModeActive ? 'Plan Mode ON — the agent presents a plan for your approval before it acts' : 'Plan Mode: have the agent present a plan for your approval before it acts'\"\n aria-label=\"Toggle Plan Mode\"\n >\n <i class=\"fa-solid fa-route\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (EnableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"Disabled\"\n (click)=\"OpenFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n }\n @if (EnableRealtime) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"VoiceActive\"\n [disabled]=\"!CanStartRealtime\"\n (click)=\"OnRealtimeClick(); $event.stopPropagation()\"\n [title]=\"VoiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!CanStartRealtime\"\n (click)=\"OnRealtimeOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!CanSend\"\n (click)=\"OnSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"message-input-box.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/message-input-box.component.ts","../../../../src/lib/components/message/message-input-box.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';\nimport { IMetadataProvider, UserInfo } from '@memberjunction/core';\nimport { ComposerTriggerProvider, MentionSuggestion } from '../../composer-trigger-provider';\nimport { MentionEditorComponent, PendingAttachment } from '../mention/mention-editor.component';\nimport { BeforeSkillsOpenedEventArgs } from '../../events/composer-events';\n\n/**\n * Reusable message input box component (presentational)\n * Now uses MentionEditorComponent for rich @mention functionality with chips\n *\n * Handles:\n * - Text input with keyboard shortcuts via MentionEditorComponent\n * - @mention autocomplete with visual chips (contentEditable)\n * - Send button\n *\n * Does NOT handle:\n * - Saving messages to database\n * - Agent invocation\n * - Artifact creation\n * - Conversation management\n */\n@Component({\n standalone: false,\n selector: 'mj-message-input-box',\n templateUrl: './message-input-box.component.html',\n styleUrls: ['./message-input-box.component.css']\n})\nexport class MessageInputBoxComponent {\n @ViewChild('mentionEditor') MentionEditor?: MentionEditorComponent;\n\n /** @deprecated Use {@link MentionEditor}. */\n get mentionEditor(): MentionEditorComponent | undefined {\n return this.MentionEditor;\n }\n /** @deprecated Use {@link MentionEditor}. */\n set mentionEditor(value: MentionEditorComponent | undefined) {\n this.MentionEditor = value;\n }\n\n @Input() Placeholder: string = 'Type your message to start a new conversation...';\n @Input() Disabled: boolean = false;\n @Input() Value: string = '';\n @Input() ShowCharacterCount: boolean = false;\n /** Master switch for all mention/command triggers (pass-through to the mention editor). */\n @Input() EnableMentions: boolean = true;\n /** Explicit trigger-provider list (pass-through to the mention editor; explicit list wins over discovery). */\n @Input() TriggerProviders: ComposerTriggerProvider[] | null = null;\n /** Discovery-mode filter: provider Keys to skip (pass-through to the mention editor). */\n @Input() ExcludedTriggerKeys: string[] = [];\n /** Optional metadata provider scoping this composer (pass-through to the mention editor). */\n @Input() Provider: IMetadataProvider | null = null;\n @Input() CurrentUser?: UserInfo;\n @Input() Rows: number = 3;\n\n // Attachment settings\n @Input() EnableAttachments: boolean = true;\n @Input() MaxAttachments: number = 10;\n @Input() MaxAttachmentSizeBytes: number = 20 * 1024 * 1024; // 20MB\n @Input() AcceptedFileTypes: string = 'image/*';\n\n /** Shows the in-composer mic button when true. */\n @Input() EnableRealtime: boolean = false;\n /** Whether a realtime voice session is currently active (mic renders in its active state). */\n @Input() VoiceActive: boolean = false;\n /** Whether a voice session can be started right now (mic Disabled when false). */\n @Input() CanStartRealtime: boolean = true;\n /** Shows the in-composer Plan Mode toggle button when true. */\n @Input() EnablePlanMode: boolean = false;\n /** Current Plan Mode toggle state (renders the button in its active state). */\n @Input() PlanModeActive: boolean = false;\n /**\n * Shows the in-composer Skills button when true.\n *\n * Gated separately from `EnableMentions` because a host can have the `/` trigger active and\n * still not want the button — but the common case is that a composer offering skill commands\n * should advertise them, since `/` is otherwise invisible.\n */\n @Input() EnableSkills: boolean = false;\n /**\n * True while the skill dropdown is open, driving the button's expanded state.\n *\n * Note the ARIA differs from Plan Mode next to it, deliberately: Plan Mode is a toggle BUTTON\n * (a mode that stays on), so `aria-pressed` is right there. This one opens a popup, so it is\n * `aria-expanded` + `aria-haspopup`. Using `aria-pressed` here would have a screen reader\n * announce \"pressed\" for something that actually just revealed a list.\n *\n * DERIVED, not an @Input, and this is the difference from Plan Mode. Plan Mode's active state is\n * a persisted user preference the host owns and threads down. \"Is the skill dropdown open\" is\n * intrinsic to this composer, so an @Input would be an API the host cannot meaningfully answer\n * and would leave the button permanently unpressed if nobody bound it.\n */\n get SkillsActive(): boolean {\n return this.MentionEditor?.IsTriggerOpen('/') ?? false;\n }\n\n /** Composer lost focus — hosts persist drafts on this. */\n @Output() Blurred = new EventEmitter<void>();\n @Output() TextSubmitted = new EventEmitter<string>();\n @Output() ValueChange = new EventEmitter<string>();\n @Output() AttachmentsChanged = new EventEmitter<PendingAttachment[]>();\n @Output() AttachmentError = new EventEmitter<string>();\n @Output() AttachmentClicked = new EventEmitter<PendingAttachment>();\n /** Emitted when the user clicks the mic button to start/stop a voice session. */\n @Output() VoiceRequested = new EventEmitter<void>();\n /**\n * Emitted when the user clicks the small caret next to the phone button — the host opens the\n * voice agent/model picker so call options (which agent, which voice model) stay reachable\n * without adding friction to the plain phone click's instant-start path.\n */\n @Output() VoiceOptionsRequested = new EventEmitter<void>();\n /** Emitted when the user clicks the in-composer Plan Mode toggle button. */\n @Output() PlanModeToggle = new EventEmitter<void>();\n /**\n * Fired BEFORE the Skills button opens the dropdown. Flip `Cancel` to veto — a host gating\n * skills by entitlement, or surfacing them elsewhere, blocks it here.\n *\n * A pair rather than a lone emitter because this is an ACTION a host might reasonably refuse\n * (UI_LAYERING_GUIDE section 6, rule 1). Handlers must be synchronous; `Cancel` travels back\n * through EventEmitter's synchronous dispatch.\n */\n @Output() BeforeSkillsOpened = new EventEmitter<BeforeSkillsOpenedEventArgs>();\n /**\n * Fired AFTER the dropdown actually opened. Not emitted on the canceled path, and not emitted\n * when no active provider owns the trigger — so a host counting this counts dropdowns the user\n * saw, rather than clicks.\n */\n @Output() AfterSkillsOpened = new EventEmitter<void>();\n\n /**\n * Open the skill-command dropdown, the same one `/` opens.\n *\n * Routed through the editor's OpenTrigger rather than a parallel menu so permission filtering,\n * per-skill icons and chip insertion all stay in one implementation.\n */\n /**\n * NOTE: the template pairs this with\n * `(mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"`, and BOTH halves are\n * load-bearing.\n *\n * `preventDefault` — a <button> takes focus on mousedown, which blurs the editor, and the editor\n * closes its dropdown 200ms after losing focus. Without it the menu opened and then shut itself.\n *\n * `stopPropagation` — the editor's click-away listener is on `document:mousedown` and exempts only\n * presses inside the EDITOR's host. This button is a sibling of `<mj-mention-editor>`, so a press\n * on it read as an outside press: mousedown closed the dropdown, then click saw `SkillsActive`\n * already false and reopened it. The menu blinked, could not be dismissed by the button that\n * opened it, and the Before/After pair fired on every click — the exact over-counting the toggle\n * branch below exists to prevent. Stopping propagation states that this press belongs to the\n * dropdown machinery.\n */\n OnSkillsClick(event?: Event): void {\n // Toggle closed first. A disclosure button has to be able to close what it opened, and without\n // this a second click re-ran the open path: it re-emitted the Before/After pair (so a host\n // counting opens over-counted) and re-captured the trigger's baseline at the new caret, which\n // corrupts the query offset once anything has been typed.\n if (this.SkillsActive) {\n this.MentionEditor?.closeMentionDropdown();\n return;\n }\n const args = new BeforeSkillsOpenedEventArgs();\n this.BeforeSkillsOpened.emit(args);\n if (args.Cancel) {\n return;\n }\n const anchor = (event?.currentTarget as HTMLElement | undefined) ?? null;\n if (this.MentionEditor?.OpenTrigger('/', anchor)) {\n this.AfterSkillsOpened.emit();\n }\n }\n\n OnRealtimeClick(): void {\n this.VoiceRequested.emit();\n }\n\n OnRealtimeOptionsClick(): void {\n this.VoiceOptionsRequested.emit();\n }\n\n get CanSend(): boolean {\n const hasText = this.Value.trim().length > 0;\n const hasAttachments = this.MentionEditor?.hasAttachments() || false;\n return !this.Disabled && (hasText || hasAttachments);\n }\n\n /**\n * Handle Value changes from MentionEditorComponent\n */\n OnValueChange(newValue: string): void {\n this.Value = newValue;\n this.ValueChange.emit(this.Value);\n }\n\n /**\n * Handle attachment changes from MentionEditorComponent\n */\n OnAttachmentsChanged(attachments: PendingAttachment[]): void {\n this.AttachmentsChanged.emit(attachments);\n }\n\n /**\n * Handle attachment errors from MentionEditorComponent\n */\n OnAttachmentError(error: string): void {\n this.AttachmentError.emit(error);\n }\n\n /**\n * Handle attachment click from MentionEditorComponent\n */\n OnAttachmentClicked(attachment: PendingAttachment): void {\n this.AttachmentClicked.emit(attachment);\n }\n\n /**\n * Handle Enter key from MentionEditorComponent\n * Extracts plain text with JSON-encoded mentions for message submission\n */\n OnEnterPressed(_text: string): void {\n this.OnSendClick();\n }\n\n /**\n * Handle mention selection from MentionEditorComponent\n */\n OnMentionSelected(suggestion: MentionSuggestion): void {\n // MentionEditorComponent already inserts the mention chip\n // This is just for additional tracking/analytics if needed\n }\n\n /**\n * Send the message\n * Extracts plain text with JSON-encoded mentions for proper persistence\n */\n OnSendClick(): void {\n if (this.CanSend) {\n // Get plain text with JSON-encoded mentions (preserves configuration info)\n const textToSend = this.MentionEditor?.getPlainTextWithJsonMentions() || this.Value.trim();\n this.TextSubmitted.emit(textToSend);\n this.Value = ''; // Clear input after sending\n\n // Clear the editor content\n if (this.MentionEditor) {\n this.MentionEditor.clear();\n }\n\n this.ValueChange.emit(this.Value);\n }\n }\n\n /**\n * Handle clicks on the container - focus the mention editor\n * Only moves cursor to end if clicking outside the contentEditable area\n */\n OnContainerClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n\n // Don't handle clicks on the send button\n if (target.closest('.send-button-icon')) {\n return;\n }\n\n const editor = this.MentionEditor?.editorRef?.nativeElement;\n if (!editor) return;\n\n // If clicking directly on the editor or its children, let the browser handle cursor placement\n if (target === editor || editor.contains(target)) {\n return;\n }\n\n // Only if clicking on the container (empty space), focus and move cursor to end\n editor.focus();\n const selection = window.getSelection();\n const range = document.createRange();\n\n if (selection) {\n range.selectNodeContents(editor);\n range.collapse(false); // Collapse to end\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n\n /**\n * Public method to focus the input programmatically\n */\n /** Inserts a resolved mention chip + space and focuses (see MentionEditorComponent.InsertMention). */\n InsertMention(suggestion: MentionSuggestion, focus: boolean = true): boolean {\n return this.MentionEditor?.InsertMention(suggestion, focus) ?? false;\n }\n\n /** Focus with the caret at the end of content (see MentionEditorComponent.FocusCaretAtEnd). */\n FocusCaretAtEnd(): boolean {\n return this.MentionEditor?.FocusCaretAtEnd() ?? false;\n }\n\n Focus(): void {\n const editor = this.MentionEditor?.editorRef?.nativeElement;\n if (editor) {\n editor.focus();\n }\n }\n\n /** @deprecated Use {@link Focus}. */\n focus(): void {\n return this.Focus();\n }\n\n /**\n * Get mention chip data including configuration presets\n */\n GetMentionChipsData(): Array<{ id: string; type: string; name: string; presetId?: string; presetName?: string }> {\n return this.MentionEditor?.getMentionChipsData() || [];\n }\n\n /**\n * Get pending attachments from the editor\n */\n GetPendingAttachments(): PendingAttachment[] {\n return this.MentionEditor?.getPendingAttachments() || [];\n }\n\n /**\n * Open file picker programmatically\n */\n OpenFilePicker(): void {\n this.MentionEditor?.openFilePicker();\n }\n\n /**\n * Add an artifact as a pending attachment (called by parent after artifact selection)\n */\n AddArtifactAttachment(artifact: {\n fileID: string; fileName: string; mimeType: string;\n sizeBytes: number; artifactVersionId?: string;\n }): PendingAttachment | undefined {\n return this.MentionEditor?.AddArtifactAttachment(artifact);\n }\n}\n","<div class=\"message-input-box-container\" (click)=\"OnContainerClick($event)\">\n <div class=\"input-wrapper\">\n <mj-mention-editor\n #mentionEditor\n [placeholder]=\"Placeholder\"\n [disabled]=\"Disabled\"\n [currentUser]=\"CurrentUser\"\n [enableMentions]=\"EnableMentions\"\n [TriggerProviders]=\"TriggerProviders\"\n [ExcludedTriggerKeys]=\"ExcludedTriggerKeys\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"EnableAttachments\"\n [maxAttachments]=\"MaxAttachments\"\n [maxAttachmentSizeBytes]=\"MaxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"AcceptedFileTypes\"\n [(ngModel)]=\"Value\"\n (valueChange)=\"OnValueChange($event)\"\n (enterPressed)=\"OnEnterPressed($event)\"\n (mentionSelected)=\"OnMentionSelected($event)\"\n (attachmentsChanged)=\"OnAttachmentsChanged($event)\"\n (attachmentError)=\"OnAttachmentError($event)\"\n (attachmentClicked)=\"OnAttachmentClicked($event)\"\n (editorBlurred)=\"Blurred.emit()\">\n </mj-mention-editor>\n\n <!-- Attach + voice + plan-mode buttons - Positioned over editor -->\n @if (EnableAttachments || EnableRealtime || EnablePlanMode || EnableSkills) {\n <div class=\"attach-buttons\">\n @if (EnableSkills) {\n <button\n class=\"attach-button-icon skills-button-icon\"\n [class.skills-button-icon--active]=\"SkillsActive\"\n [disabled]=\"Disabled\"\n [attr.aria-expanded]=\"SkillsActive\"\n aria-haspopup=\"true\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"OnSkillsClick($event); $event.stopPropagation()\"\n title=\"Skills, or type / in the message box\"\n aria-label=\"Show skills\"\n >\n <i class=\"fa-solid fa-wand-magic-sparkles\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (EnablePlanMode) {\n <button\n class=\"attach-button-icon plan-mode-button-icon\"\n [class.plan-mode-button-icon--active]=\"PlanModeActive\"\n [disabled]=\"Disabled\"\n [attr.aria-pressed]=\"PlanModeActive\"\n (click)=\"PlanModeToggle.emit(); $event.stopPropagation()\"\n [title]=\"PlanModeActive ? 'Plan Mode ON — the agent presents a plan for your approval before it acts' : 'Plan Mode: have the agent present a plan for your approval before it acts'\"\n aria-label=\"Toggle Plan Mode\"\n >\n <i class=\"fa-solid fa-route\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (EnableAttachments) {\n <button\n class=\"attach-button-icon\"\n [disabled]=\"Disabled\"\n (click)=\"OpenFilePicker(); $event.stopPropagation()\"\n title=\"Attach file\"\n >\n <i class=\"fa-solid fa-paperclip\"></i>\n </button>\n }\n @if (EnableRealtime) {\n <button\n class=\"attach-button-icon voice-button-icon\"\n [class.voice-button-icon--active]=\"VoiceActive\"\n [disabled]=\"!CanStartRealtime\"\n (click)=\"OnRealtimeClick(); $event.stopPropagation()\"\n [title]=\"VoiceActive ? 'Voice call active' : 'Start a voice call'\"\n aria-label=\"Start a voice call\"\n >\n <i class=\"fa-solid fa-phone\" aria-hidden=\"true\"></i>\n </button>\n <!-- Caret beside the phone: opens the agent/model picker so call OPTIONS stay one\n click away while the plain phone click keeps its instant-start behavior. -->\n <button\n class=\"attach-button-icon voice-options-button-icon\"\n [disabled]=\"!CanStartRealtime\"\n (click)=\"OnRealtimeOptionsClick(); $event.stopPropagation()\"\n title=\"Voice call options (choose agent and voice model)\"\n aria-label=\"Voice call options\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Send Button (Icon Only) - Positioned over editor -->\n <button\n class=\"send-button-icon\"\n [disabled]=\"!CanSend\"\n (click)=\"OnSendClick()\"\n title=\"Send message (Enter)\"\n >\n <i class=\"fa-solid fa-paper-plane\"></i>\n </button>\n </div>\n</div>\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-composer",
3
- "version": "6.2.0-edge.0",
3
+ "version": "6.2.0-edge.1",
4
4
  "description": "MemberJunction: Generic message composer components — mention editor with pluggable trigger providers (ComposerTriggerProvider), mention dropdown, and send-button input box wrapper. Ships zero AI knowledge; trigger plugins are supplied by hosts (see @memberjunction/ng-conversations).",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -13,7 +13,7 @@
13
13
  "devDependencies": {
14
14
  "@angular/compiler": "21.2.22",
15
15
  "@angular/compiler-cli": "21.2.22",
16
- "@memberjunction/ng-test-utils": "6.2.0-edge.0",
16
+ "@memberjunction/ng-test-utils": "6.2.0-edge.1",
17
17
  "vitest": "^4.0.18"
18
18
  },
19
19
  "peerDependencies": {
@@ -22,9 +22,9 @@
22
22
  "@angular/forms": "^21.2.22"
23
23
  },
24
24
  "dependencies": {
25
- "@memberjunction/core": "6.2.0-edge.0",
26
- "@memberjunction/global": "6.2.0-edge.0",
27
- "@memberjunction/ng-ui-components": "6.2.0-edge.0",
25
+ "@memberjunction/core": "6.2.0-edge.1",
26
+ "@memberjunction/global": "6.2.0-edge.1",
27
+ "@memberjunction/ng-ui-components": "6.2.0-edge.1",
28
28
  "tslib": "^2.8.1"
29
29
  },
30
30
  "sideEffects": false,