@forgeroute/ui 0.4.60 → 0.4.61

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.
@@ -35243,6 +35243,13 @@ function sanitizeRichTextHtml(html, options = {}) {
35243
35243
  walkChildren(parsed.body, out, ctx);
35244
35244
  return out.innerHTML;
35245
35245
  }
35246
+ function normalizeLinkUrl(raw) {
35247
+ const text = (raw ?? "").trim();
35248
+ if (!text || /\s/.test(text)) return null;
35249
+ if (/^(https?:\/\/|mailto:|tel:)\S+$/i.test(text)) return text;
35250
+ if (/^[a-z][a-z0-9+.-]*:/i.test(text) || /^[\/\\]{2}/.test(text)) return null;
35251
+ return /^[^\s/@]+\.[^\s/@]+/.test(text) ? `https://${text}` : null;
35252
+ }
35246
35253
  function plainTextToHtml(text) {
35247
35254
  return text.replace(/\r\n?/g, "\n").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, "<br>");
35248
35255
  }
@@ -35251,6 +35258,7 @@ const RICH_TEXT_OPTIONS = [
35251
35258
  "italic",
35252
35259
  "underline",
35253
35260
  "strikethrough",
35261
+ "link",
35254
35262
  "heading",
35255
35263
  "fontSize",
35256
35264
  "fontFamily",
@@ -35270,7 +35278,8 @@ const GROUPS = [
35270
35278
  "bold",
35271
35279
  "italic",
35272
35280
  "underline",
35273
- "strikethrough"
35281
+ "strikethrough",
35282
+ "link"
35274
35283
  ]
35275
35284
  },
35276
35285
  {
@@ -35312,6 +35321,7 @@ const OPTION_TAGS = {
35312
35321
  "STRIKE",
35313
35322
  "DEL"
35314
35323
  ],
35324
+ link: ["A"],
35315
35325
  heading: [
35316
35326
  "H1",
35317
35327
  "H2",
@@ -35571,6 +35581,10 @@ var RichTextEditorComponent = class RichTextEditorComponent {
35571
35581
  this.activeFont = signal("Default", ...ngDevMode ? [{ debugName: "activeFont" }] : /* istanbul ignore next */ []);
35572
35582
  this.active = signal(Object.fromEntries(STATE_COMMANDS.map((c) => [c, false])), ...ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []);
35573
35583
  this.empty = signal(true, ...ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []);
35584
+ this.linkUrl = signal("", ...ngDevMode ? [{ debugName: "linkUrl" }] : /* istanbul ignore next */ []);
35585
+ this.linkError = signal("", ...ngDevMode ? [{ debugName: "linkError" }] : /* istanbul ignore next */ []);
35586
+ this.hasLink = signal(false, ...ngDevMode ? [{ debugName: "hasLink" }] : /* istanbul ignore next */ []);
35587
+ this._linkId = `rte-${++nextId$2}-link`;
35574
35588
  this.hidden = computed(() => new Set(this.hide()), ...ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []);
35575
35589
  this.groupVisible = computed(() => {
35576
35590
  const hidden = this.hidden();
@@ -35752,6 +35766,62 @@ var RichTextEditorComponent = class RichTextEditorComponent {
35752
35766
  this.openMenu.set(null);
35753
35767
  this.execWithArg("fontName", value);
35754
35768
  }
35769
+ _anchorAtSelection() {
35770
+ const el = this.editor()?.nativeElement;
35771
+ const sel = window.getSelection();
35772
+ const node = sel && sel.rangeCount > 0 && el?.contains(sel.anchorNode) ? sel.anchorNode : this._savedRange?.startContainer ?? null;
35773
+ const a = (node && node.nodeType === Node.TEXT_NODE ? node.parentElement : node)?.closest("a") ?? null;
35774
+ return a && el?.contains(a) ? a : null;
35775
+ }
35776
+ toggleLink() {
35777
+ if (this.openMenu() === "link") {
35778
+ this.openMenu.set(null);
35779
+ return;
35780
+ }
35781
+ this._saveSelection();
35782
+ const a = this._anchorAtSelection();
35783
+ this.hasLink.set(!!a);
35784
+ this.linkUrl.set(a?.getAttribute("href") ?? "");
35785
+ this.linkError.set("");
35786
+ this.openMenu.set("link");
35787
+ }
35788
+ closeLink() {
35789
+ this.openMenu.set(null);
35790
+ this._restoreSelection();
35791
+ }
35792
+ applyLink() {
35793
+ if (this.inert()) return;
35794
+ const url = normalizeLinkUrl(this.linkUrl());
35795
+ if (!url) {
35796
+ this.linkError.set("Enter a web address like example.com.");
35797
+ return;
35798
+ }
35799
+ this.openMenu.set(null);
35800
+ this._restoreSelection();
35801
+ const sel = window.getSelection();
35802
+ const existing = this._anchorAtSelection();
35803
+ if (existing) existing.setAttribute("href", url);
35804
+ else if (!sel || sel.isCollapsed) {
35805
+ const text = url.replace(/^(mailto:|tel:|https?:\/\/)/i, "");
35806
+ document.execCommand("insertHTML", false, `<a href="${url.replace(/&/g, "&amp;").replace(/"/g, "&quot;")}">${plainTextToHtml(text)}</a>`);
35807
+ } else document.execCommand("createLink", false, url);
35808
+ this.onInput();
35809
+ }
35810
+ removeLink() {
35811
+ if (this.inert()) return;
35812
+ this.openMenu.set(null);
35813
+ this._restoreSelection();
35814
+ const a = this._anchorAtSelection();
35815
+ if (a) {
35816
+ const range = document.createRange();
35817
+ range.selectNodeContents(a);
35818
+ const sel = window.getSelection();
35819
+ sel?.removeAllRanges();
35820
+ sel?.addRange(range);
35821
+ }
35822
+ document.execCommand("unlink", false);
35823
+ this.onInput();
35824
+ }
35755
35825
  exec(command) {
35756
35826
  if (this.inert()) return;
35757
35827
  this._restoreSelection();
@@ -35892,7 +35962,7 @@ var RichTextEditorComponent = class RichTextEditorComponent {
35892
35962
  @if (toolbarVisible()) {
35893
35963
  <div class="rte-toolbar" role="toolbar" aria-label="Text formatting" [attr.aria-controls]="_editorId"
35894
35964
  (mousedown)="onToolbarMouseDown($event)">
35895
- @if (show('bold') || show('italic') || show('underline') || show('strikethrough')) {
35965
+ @if (show('bold') || show('italic') || show('underline') || show('strikethrough') || show('link')) {
35896
35966
  @if (show('bold')) {
35897
35967
  <button type="button" class="rte-btn" data-option="bold" [class.active]="active()['bold']"
35898
35968
  [attr.aria-pressed]="active()['bold']" [disabled]="inert()"
@@ -35921,6 +35991,29 @@ var RichTextEditorComponent = class RichTextEditorComponent {
35921
35991
  <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="4" y1="12" x2="20" y2="12"/><path d="M6 4h8a4 4 0 010 8H6"/><path d="M10 12v8"/></svg>
35922
35992
  </button>
35923
35993
  }
35994
+ @if (show('link')) {
35995
+ <span class="rte-menu-wrap" (click)="$event.stopPropagation()">
35996
+ <button type="button" class="rte-btn rte-menu-btn" data-option="link" [class.active]="openMenu() === 'link'"
35997
+ [disabled]="inert()" aria-label="Link" title="Link"
35998
+ aria-haspopup="dialog" [attr.aria-expanded]="openMenu() === 'link'" (click)="toggleLink()">
35999
+ <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/></svg>
36000
+ </button>
36001
+ @if (openMenu() === 'link') {
36002
+ <div class="rte-dropdown rte-link-panel" role="dialog" aria-label="Link" (keydown.escape)="closeLink()">
36003
+ <label class="rte-link-label" [for]="_linkId">Web address</label>
36004
+ <input class="rte-link-input" type="url" inputmode="url" autocomplete="off" spellcheck="false" placeholder="example.com"
36005
+ [id]="_linkId" [value]="linkUrl()" [attr.aria-invalid]="linkError() ? 'true' : null"
36006
+ [attr.aria-describedby]="linkError() ? _linkId + '-error' : null"
36007
+ (input)="linkUrl.set($any($event.target).value); linkError.set('')" (keydown.enter)="$event.preventDefault(); applyLink()" />
36008
+ @if (linkError()) { <p class="rte-link-error" role="alert" [id]="_linkId + '-error'">{{ linkError() }}</p> }
36009
+ <div class="rte-link-actions">
36010
+ <button type="button" class="rte-link-btn rte-link-apply" data-testid="rte-link-apply" (click)="applyLink()">Apply</button>
36011
+ @if (hasLink()) { <button type="button" class="rte-link-btn" data-testid="rte-link-remove" (click)="removeLink()">Remove link</button> }
36012
+ </div>
36013
+ </div>
36014
+ }
36015
+ </span>
36016
+ }
35924
36017
  }
35925
36018
 
35926
36019
  @if (divider()['text']) { <div class="rte-divider" role="separator" aria-orientation="vertical"></div> }
@@ -36091,7 +36184,7 @@ var RichTextEditorComponent = class RichTextEditorComponent {
36091
36184
  </div>
36092
36185
  `,
36093
36186
  isInline: true,
36094
- styles: [":host{display:block}.rte-field{display:flex;flex-direction:column;gap:6px}.rte-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rte-required{color:#dc2626;margin-left:2px}.rte-hint-inline{font-size:.75rem;color:#94a3b8;font-weight:400;margin-left:4px}.rte-box{border:1px solid #7c8ba1;border-radius:8px;background:#fff;transition:border-color .15s,box-shadow .15s}.rte-box:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.rte-error .rte-box{border-color:#ef4444}.rte-error .rte-box:focus-within{box-shadow:0 0 0 3px #ef44441f}.rte-disabled .rte-box{opacity:.5;cursor:not-allowed}.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0}.rte-divider{width:1px;height:20px;background:#cbd5e1;margin:0 4px}.rte-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:none;color:#64748b;cursor:pointer;transition:background .15s,color .15s}.rte-btn svg{width:16px;height:16px}.rte-btn:hover:not(:disabled){background:#e2e8f0;color:#1e293b}.rte-btn:focus-visible,.rte-btn:focus-within{outline:2px solid #3b82f6;outline-offset:1px}.rte-btn.active{background:#dbeafe;color:#2563eb}.rte-btn:disabled,.rte-btn-disabled{cursor:not-allowed;opacity:.5}.rte-menu-wrap{position:relative;display:inline-flex}.rte-menu-btn{width:auto;padding:0 6px;gap:3px}.rte-menu-btn .rte-chevron{width:10px;height:10px;color:#64748b;flex-shrink:0}.rte-dropdown{position:absolute;top:calc(100% + 4px);left:0;z-index:100;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 12px #0000001f;padding:4px;overflow-y:auto;max-height:260px}.rte-font-panel{min-width:180px}.rte-item{display:block;width:100%;text-align:left;padding:5px 10px;font-size:12px;color:#374151;border:none;background:none;border-radius:4px;cursor:pointer;white-space:nowrap}.rte-item:hover{background:#f1f5f9}.rte-item.selected{background:#dbeafe;color:#2563eb;font-weight:600}.rte-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:6px 10px 2px}.di-h1{font-size:18px;font-weight:700}.di-h2{font-size:15px;font-weight:600}.di-h3{font-size:13px;font-weight:600}.rte-color{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.rte-editor{padding:12px;outline:none;overflow-y:auto;box-sizing:border-box;font-size:.875rem;line-height:1.6;color:#1e293b;background:#fff;border-radius:0 0 8px 8px;word-break:break-word}.rte-editor[data-empty=true]:before{content:attr(data-placeholder);color:#64748b;pointer-events:none;float:left;height:0}.rte-editor ul,.rte-editor ol{padding-left:1.5em;margin:.25em 0}.rte-editor li{margin:.15em 0}.rte-editor h1{font-size:1.75em;font-weight:700;margin:.5em 0 .25em}.rte-editor h2{font-size:1.4em;font-weight:600;margin:.5em 0 .25em}.rte-editor h3{font-size:1.15em;font-weight:600;margin:.5em 0 .25em}.rte-editor a{color:#2563eb;text-decoration:underline}.rte-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rte-desc-error{color:#dc2626}@media(max-width:480px){.rte-editor{font-size:1rem}}@media(pointer:coarse),(max-width:480px){.rte-btn{width:44px;height:44px}.rte-menu-btn{width:auto;min-width:44px}.rte-divider{height:28px}}\n"],
36187
+ styles: [":host{display:block}.rte-field{display:flex;flex-direction:column;gap:6px}.rte-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rte-required{color:#dc2626;margin-left:2px}.rte-hint-inline{font-size:.75rem;color:#94a3b8;font-weight:400;margin-left:4px}.rte-box{border:1px solid #7c8ba1;border-radius:8px;background:#fff;transition:border-color .15s,box-shadow .15s}.rte-box:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.rte-error .rte-box{border-color:#ef4444}.rte-error .rte-box:focus-within{box-shadow:0 0 0 3px #ef44441f}.rte-disabled .rte-box{opacity:.5;cursor:not-allowed}.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0}.rte-divider{width:1px;height:20px;background:#cbd5e1;margin:0 4px}.rte-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:none;color:#64748b;cursor:pointer;transition:background .15s,color .15s}.rte-btn svg{width:16px;height:16px}.rte-btn:hover:not(:disabled){background:#e2e8f0;color:#1e293b}.rte-btn:focus-visible,.rte-btn:focus-within{outline:2px solid #3b82f6;outline-offset:1px}.rte-btn.active{background:#dbeafe;color:#2563eb}.rte-btn:disabled,.rte-btn-disabled{cursor:not-allowed;opacity:.5}.rte-menu-wrap{position:relative;display:inline-flex}.rte-menu-btn{width:auto;padding:0 6px;gap:3px}.rte-menu-btn .rte-chevron{width:10px;height:10px;color:#64748b;flex-shrink:0}.rte-dropdown{position:absolute;top:calc(100% + 4px);left:0;z-index:100;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 12px #0000001f;padding:4px;overflow-y:auto;max-height:260px}.rte-font-panel{min-width:180px}.rte-link-panel{display:flex;flex-direction:column;gap:6px;min-width:240px;padding:10px;overflow:visible}.rte-link-label{font-size:12px;font-weight:600;color:#374151}.rte-link-input{box-sizing:border-box;width:100%;padding:6px 8px;font:inherit;font-size:14px;border:1px solid #cbd5e1;border-radius:6px}.rte-link-input:focus-visible{outline:2px solid #2563eb;outline-offset:1px}.rte-link-error{margin:0;font-size:12px;color:#dc2626}.rte-link-actions{display:flex;gap:6px}.rte-link-btn{padding:5px 10px;font-size:12px;border:1px solid #cbd5e1;border-radius:6px;background:#fff;color:#374151;cursor:pointer}.rte-link-apply{background:#2563eb;border-color:#2563eb;color:#fff}.rte-item{display:block;width:100%;text-align:left;padding:5px 10px;font-size:12px;color:#374151;border:none;background:none;border-radius:4px;cursor:pointer;white-space:nowrap}.rte-item:hover{background:#f1f5f9}.rte-item.selected{background:#dbeafe;color:#2563eb;font-weight:600}.rte-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:6px 10px 2px}.di-h1{font-size:18px;font-weight:700}.di-h2{font-size:15px;font-weight:600}.di-h3{font-size:13px;font-weight:600}.rte-color{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.rte-editor{padding:12px;outline:none;overflow-y:auto;box-sizing:border-box;font-size:.875rem;line-height:1.6;color:#1e293b;background:#fff;border-radius:0 0 8px 8px;word-break:break-word}.rte-editor[data-empty=true]:before{content:attr(data-placeholder);color:#64748b;pointer-events:none;float:left;height:0}.rte-editor ul,.rte-editor ol{padding-left:1.5em;margin:.25em 0}.rte-editor li{margin:.15em 0}.rte-editor h1{font-size:1.75em;font-weight:700;margin:.5em 0 .25em}.rte-editor h2{font-size:1.4em;font-weight:600;margin:.5em 0 .25em}.rte-editor h3{font-size:1.15em;font-weight:600;margin:.5em 0 .25em}.rte-editor a{color:#2563eb;text-decoration:underline}.rte-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rte-desc-error{color:#dc2626}@media(max-width:480px){.rte-editor{font-size:1rem}}@media(pointer:coarse),(max-width:480px){.rte-btn{width:44px;height:44px}.rte-menu-btn{width:auto;min-width:44px}.rte-divider{height:28px}}\n"],
36095
36188
  changeDetection: i0.ChangeDetectionStrategy.OnPush
36096
36189
  });
36097
36190
  }
@@ -36130,7 +36223,7 @@ i0.ɵɵngDeclareClassMetadata({
36130
36223
  @if (toolbarVisible()) {
36131
36224
  <div class="rte-toolbar" role="toolbar" aria-label="Text formatting" [attr.aria-controls]="_editorId"
36132
36225
  (mousedown)="onToolbarMouseDown($event)">
36133
- @if (show('bold') || show('italic') || show('underline') || show('strikethrough')) {
36226
+ @if (show('bold') || show('italic') || show('underline') || show('strikethrough') || show('link')) {
36134
36227
  @if (show('bold')) {
36135
36228
  <button type="button" class="rte-btn" data-option="bold" [class.active]="active()['bold']"
36136
36229
  [attr.aria-pressed]="active()['bold']" [disabled]="inert()"
@@ -36159,6 +36252,29 @@ i0.ɵɵngDeclareClassMetadata({
36159
36252
  <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="4" y1="12" x2="20" y2="12"/><path d="M6 4h8a4 4 0 010 8H6"/><path d="M10 12v8"/></svg>
36160
36253
  </button>
36161
36254
  }
36255
+ @if (show('link')) {
36256
+ <span class="rte-menu-wrap" (click)="$event.stopPropagation()">
36257
+ <button type="button" class="rte-btn rte-menu-btn" data-option="link" [class.active]="openMenu() === 'link'"
36258
+ [disabled]="inert()" aria-label="Link" title="Link"
36259
+ aria-haspopup="dialog" [attr.aria-expanded]="openMenu() === 'link'" (click)="toggleLink()">
36260
+ <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/></svg>
36261
+ </button>
36262
+ @if (openMenu() === 'link') {
36263
+ <div class="rte-dropdown rte-link-panel" role="dialog" aria-label="Link" (keydown.escape)="closeLink()">
36264
+ <label class="rte-link-label" [for]="_linkId">Web address</label>
36265
+ <input class="rte-link-input" type="url" inputmode="url" autocomplete="off" spellcheck="false" placeholder="example.com"
36266
+ [id]="_linkId" [value]="linkUrl()" [attr.aria-invalid]="linkError() ? 'true' : null"
36267
+ [attr.aria-describedby]="linkError() ? _linkId + '-error' : null"
36268
+ (input)="linkUrl.set($any($event.target).value); linkError.set('')" (keydown.enter)="$event.preventDefault(); applyLink()" />
36269
+ @if (linkError()) { <p class="rte-link-error" role="alert" [id]="_linkId + '-error'">{{ linkError() }}</p> }
36270
+ <div class="rte-link-actions">
36271
+ <button type="button" class="rte-link-btn rte-link-apply" data-testid="rte-link-apply" (click)="applyLink()">Apply</button>
36272
+ @if (hasLink()) { <button type="button" class="rte-link-btn" data-testid="rte-link-remove" (click)="removeLink()">Remove link</button> }
36273
+ </div>
36274
+ </div>
36275
+ }
36276
+ </span>
36277
+ }
36162
36278
  }
36163
36279
 
36164
36280
  @if (divider()['text']) { <div class="rte-divider" role="separator" aria-orientation="vertical"></div> }
@@ -36328,7 +36444,7 @@ i0.ɵɵngDeclareClassMetadata({
36328
36444
  }
36329
36445
  </div>
36330
36446
  `,
36331
- styles: [":host{display:block}.rte-field{display:flex;flex-direction:column;gap:6px}.rte-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rte-required{color:#dc2626;margin-left:2px}.rte-hint-inline{font-size:.75rem;color:#94a3b8;font-weight:400;margin-left:4px}.rte-box{border:1px solid #7c8ba1;border-radius:8px;background:#fff;transition:border-color .15s,box-shadow .15s}.rte-box:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.rte-error .rte-box{border-color:#ef4444}.rte-error .rte-box:focus-within{box-shadow:0 0 0 3px #ef44441f}.rte-disabled .rte-box{opacity:.5;cursor:not-allowed}.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0}.rte-divider{width:1px;height:20px;background:#cbd5e1;margin:0 4px}.rte-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:none;color:#64748b;cursor:pointer;transition:background .15s,color .15s}.rte-btn svg{width:16px;height:16px}.rte-btn:hover:not(:disabled){background:#e2e8f0;color:#1e293b}.rte-btn:focus-visible,.rte-btn:focus-within{outline:2px solid #3b82f6;outline-offset:1px}.rte-btn.active{background:#dbeafe;color:#2563eb}.rte-btn:disabled,.rte-btn-disabled{cursor:not-allowed;opacity:.5}.rte-menu-wrap{position:relative;display:inline-flex}.rte-menu-btn{width:auto;padding:0 6px;gap:3px}.rte-menu-btn .rte-chevron{width:10px;height:10px;color:#64748b;flex-shrink:0}.rte-dropdown{position:absolute;top:calc(100% + 4px);left:0;z-index:100;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 12px #0000001f;padding:4px;overflow-y:auto;max-height:260px}.rte-font-panel{min-width:180px}.rte-item{display:block;width:100%;text-align:left;padding:5px 10px;font-size:12px;color:#374151;border:none;background:none;border-radius:4px;cursor:pointer;white-space:nowrap}.rte-item:hover{background:#f1f5f9}.rte-item.selected{background:#dbeafe;color:#2563eb;font-weight:600}.rte-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:6px 10px 2px}.di-h1{font-size:18px;font-weight:700}.di-h2{font-size:15px;font-weight:600}.di-h3{font-size:13px;font-weight:600}.rte-color{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.rte-editor{padding:12px;outline:none;overflow-y:auto;box-sizing:border-box;font-size:.875rem;line-height:1.6;color:#1e293b;background:#fff;border-radius:0 0 8px 8px;word-break:break-word}.rte-editor[data-empty=true]:before{content:attr(data-placeholder);color:#64748b;pointer-events:none;float:left;height:0}.rte-editor ul,.rte-editor ol{padding-left:1.5em;margin:.25em 0}.rte-editor li{margin:.15em 0}.rte-editor h1{font-size:1.75em;font-weight:700;margin:.5em 0 .25em}.rte-editor h2{font-size:1.4em;font-weight:600;margin:.5em 0 .25em}.rte-editor h3{font-size:1.15em;font-weight:600;margin:.5em 0 .25em}.rte-editor a{color:#2563eb;text-decoration:underline}.rte-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rte-desc-error{color:#dc2626}@media(max-width:480px){.rte-editor{font-size:1rem}}@media(pointer:coarse),(max-width:480px){.rte-btn{width:44px;height:44px}.rte-menu-btn{width:auto;min-width:44px}.rte-divider{height:28px}}\n"]
36447
+ styles: [":host{display:block}.rte-field{display:flex;flex-direction:column;gap:6px}.rte-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rte-required{color:#dc2626;margin-left:2px}.rte-hint-inline{font-size:.75rem;color:#94a3b8;font-weight:400;margin-left:4px}.rte-box{border:1px solid #7c8ba1;border-radius:8px;background:#fff;transition:border-color .15s,box-shadow .15s}.rte-box:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.rte-error .rte-box{border-color:#ef4444}.rte-error .rte-box:focus-within{box-shadow:0 0 0 3px #ef44441f}.rte-disabled .rte-box{opacity:.5;cursor:not-allowed}.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0}.rte-divider{width:1px;height:20px;background:#cbd5e1;margin:0 4px}.rte-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:none;color:#64748b;cursor:pointer;transition:background .15s,color .15s}.rte-btn svg{width:16px;height:16px}.rte-btn:hover:not(:disabled){background:#e2e8f0;color:#1e293b}.rte-btn:focus-visible,.rte-btn:focus-within{outline:2px solid #3b82f6;outline-offset:1px}.rte-btn.active{background:#dbeafe;color:#2563eb}.rte-btn:disabled,.rte-btn-disabled{cursor:not-allowed;opacity:.5}.rte-menu-wrap{position:relative;display:inline-flex}.rte-menu-btn{width:auto;padding:0 6px;gap:3px}.rte-menu-btn .rte-chevron{width:10px;height:10px;color:#64748b;flex-shrink:0}.rte-dropdown{position:absolute;top:calc(100% + 4px);left:0;z-index:100;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 12px #0000001f;padding:4px;overflow-y:auto;max-height:260px}.rte-font-panel{min-width:180px}.rte-link-panel{display:flex;flex-direction:column;gap:6px;min-width:240px;padding:10px;overflow:visible}.rte-link-label{font-size:12px;font-weight:600;color:#374151}.rte-link-input{box-sizing:border-box;width:100%;padding:6px 8px;font:inherit;font-size:14px;border:1px solid #cbd5e1;border-radius:6px}.rte-link-input:focus-visible{outline:2px solid #2563eb;outline-offset:1px}.rte-link-error{margin:0;font-size:12px;color:#dc2626}.rte-link-actions{display:flex;gap:6px}.rte-link-btn{padding:5px 10px;font-size:12px;border:1px solid #cbd5e1;border-radius:6px;background:#fff;color:#374151;cursor:pointer}.rte-link-apply{background:#2563eb;border-color:#2563eb;color:#fff}.rte-item{display:block;width:100%;text-align:left;padding:5px 10px;font-size:12px;color:#374151;border:none;background:none;border-radius:4px;cursor:pointer;white-space:nowrap}.rte-item:hover{background:#f1f5f9}.rte-item.selected{background:#dbeafe;color:#2563eb;font-weight:600}.rte-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:6px 10px 2px}.di-h1{font-size:18px;font-weight:700}.di-h2{font-size:15px;font-weight:600}.di-h3{font-size:13px;font-weight:600}.rte-color{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.rte-editor{padding:12px;outline:none;overflow-y:auto;box-sizing:border-box;font-size:.875rem;line-height:1.6;color:#1e293b;background:#fff;border-radius:0 0 8px 8px;word-break:break-word}.rte-editor[data-empty=true]:before{content:attr(data-placeholder);color:#64748b;pointer-events:none;float:left;height:0}.rte-editor ul,.rte-editor ol{padding-left:1.5em;margin:.25em 0}.rte-editor li{margin:.15em 0}.rte-editor h1{font-size:1.75em;font-weight:700;margin:.5em 0 .25em}.rte-editor h2{font-size:1.4em;font-weight:600;margin:.5em 0 .25em}.rte-editor h3{font-size:1.15em;font-weight:600;margin:.5em 0 .25em}.rte-editor a{color:#2563eb;text-decoration:underline}.rte-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rte-desc-error{color:#dc2626}@media(max-width:480px){.rte-editor{font-size:1rem}}@media(pointer:coarse),(max-width:480px){.rte-btn{width:44px;height:44px}.rte-menu-btn{width:auto;min-width:44px}.rte-divider{height:28px}}\n"]
36332
36448
  }]
36333
36449
  }],
36334
36450
  ctorParameters: () => [],
@@ -50274,6 +50390,115 @@ function conversationMessageStatusMark(status) {
50274
50390
  if (status === "sent") return "✓";
50275
50391
  return conversationMessageStatusLabel(status);
50276
50392
  }
50393
+ function conversationHtmlToText(html) {
50394
+ if (!html) return "";
50395
+ const doc = new DOMParser().parseFromString(`<body>${html}</body>`, "text/html");
50396
+ const out = [];
50397
+ const walk = (node) => {
50398
+ node.childNodes.forEach((child) => {
50399
+ if (child.nodeType === Node.TEXT_NODE) {
50400
+ out.push(child.nodeValue ?? "");
50401
+ return;
50402
+ }
50403
+ if (child.nodeType !== Node.ELEMENT_NODE) return;
50404
+ const el = child;
50405
+ if (el.tagName === "BR") {
50406
+ out.push("\n");
50407
+ return;
50408
+ }
50409
+ if (/^(SCRIPT|STYLE|NOSCRIPT|TEMPLATE)$/.test(el.tagName)) return;
50410
+ const block = /^(P|DIV|LI|UL|OL|BLOCKQUOTE|H[1-6])$/.test(el.tagName);
50411
+ if (block && out.length && !/\n$/.test(out[out.length - 1])) out.push("\n");
50412
+ walk(el);
50413
+ if (block && !/\n$/.test(out[out.length - 1] ?? "")) out.push("\n");
50414
+ });
50415
+ };
50416
+ walk(doc.body);
50417
+ return out.join("").replace(/\u00a0/g, " ").replace(/\n{3,}/g, "\n\n").trim();
50418
+ }
50419
+ var ConversationRichBodyComponent = class ConversationRichBodyComponent {
50420
+ constructor() {
50421
+ this.html = input("", ...ngDevMode ? [{ debugName: "html" }] : /* istanbul ignore next */ []);
50422
+ this.safe = computed(() => sanitizeRichTextHtml(this.html(), { mode: "paste" }), ...ngDevMode ? [{ debugName: "safe" }] : /* istanbul ignore next */ []);
50423
+ }
50424
+ static {
50425
+ this.ɵfac = i0.ɵɵngDeclareFactory({
50426
+ minVersion: "12.0.0",
50427
+ version: "22.2.2",
50428
+ ngImport: i0,
50429
+ type: ConversationRichBodyComponent,
50430
+ deps: [],
50431
+ target: i0.ɵɵFactoryTarget.Component
50432
+ });
50433
+ }
50434
+ static {
50435
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
50436
+ minVersion: "17.1.0",
50437
+ version: "22.2.2",
50438
+ type: ConversationRichBodyComponent,
50439
+ isStandalone: true,
50440
+ selector: "ui-conversation-rich-body",
50441
+ inputs: { html: {
50442
+ classPropertyName: "html",
50443
+ publicName: "html",
50444
+ isSignal: true,
50445
+ isRequired: false,
50446
+ transformFunction: null
50447
+ } },
50448
+ host: {
50449
+ properties: { "innerHTML": "safe()" },
50450
+ classAttribute: "cv-rich"
50451
+ },
50452
+ ngImport: i0,
50453
+ template: "",
50454
+ isInline: true,
50455
+ styles: [".cv-rich{display:block;font-size:.875rem;line-height:1.45;word-break:break-word}.cv-rich p,.cv-rich div{margin:0}.cv-rich ul,.cv-rich ol{margin:0;padding-inline-start:1.25rem}.cv-rich a{color:inherit;text-decoration:underline}\n"],
50456
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
50457
+ encapsulation: i0.ViewEncapsulation.None
50458
+ });
50459
+ }
50460
+ };
50461
+ i0.ɵɵngDeclareClassMetadata({
50462
+ minVersion: "12.0.0",
50463
+ version: "22.2.2",
50464
+ ngImport: i0,
50465
+ type: ConversationRichBodyComponent,
50466
+ decorators: [{
50467
+ type: Component,
50468
+ args: [{
50469
+ selector: "ui-conversation-rich-body",
50470
+ standalone: true,
50471
+ changeDetection: ChangeDetectionStrategy.OnPush,
50472
+ encapsulation: ViewEncapsulation.None,
50473
+ host: {
50474
+ class: "cv-rich",
50475
+ "[innerHTML]": "safe()"
50476
+ },
50477
+ template: "",
50478
+ styles: [".cv-rich{display:block;font-size:.875rem;line-height:1.45;word-break:break-word}.cv-rich p,.cv-rich div{margin:0}.cv-rich ul,.cv-rich ol{margin:0;padding-inline-start:1.25rem}.cv-rich a{color:inherit;text-decoration:underline}\n"]
50479
+ }]
50480
+ }],
50481
+ propDecorators: { html: [{
50482
+ type: i0.Input,
50483
+ args: [{
50484
+ isSignal: true,
50485
+ alias: "html",
50486
+ required: false
50487
+ }]
50488
+ }] }
50489
+ });
50490
+ const RICH_COMPOSER_HIDE = [
50491
+ "strikethrough",
50492
+ "heading",
50493
+ "fontSize",
50494
+ "fontFamily",
50495
+ "textColor",
50496
+ "highlight",
50497
+ "align",
50498
+ "indent",
50499
+ "outdent",
50500
+ "clearFormat"
50501
+ ];
50277
50502
  const SINGLE_COLUMN_QUERY = "(max-width: 768px)";
50278
50503
  const NEAR_BOTTOM_PX = 120;
50279
50504
  const PREVIEW_LENGTH = 60;
@@ -50308,6 +50533,7 @@ var ConversationsComponent = class ConversationsComponent {
50308
50533
  this.allowNew = input(true, ...ngDevMode ? [{ debugName: "allowNew" }] : /* istanbul ignore next */ []);
50309
50534
  this.allowDelete = input(true, ...ngDevMode ? [{ debugName: "allowDelete" }] : /* istanbul ignore next */ []);
50310
50535
  this.showRowArrow = input(false, ...ngDevMode ? [{ debugName: "showRowArrow" }] : /* istanbul ignore next */ []);
50536
+ this.selectable = input(true, ...ngDevMode ? [{ debugName: "selectable" }] : /* istanbul ignore next */ []);
50311
50537
  this.newLabel = input("Start new message", ...ngDevMode ? [{ debugName: "newLabel" }] : /* istanbul ignore next */ []);
50312
50538
  this.newTooltip = input("New message", ...ngDevMode ? [{ debugName: "newTooltip" }] : /* istanbul ignore next */ []);
50313
50539
  this.deleteRowLabel = input("Delete conversation with", ...ngDevMode ? [{ debugName: "deleteRowLabel" }] : /* istanbul ignore next */ []);
@@ -50349,6 +50575,7 @@ var ConversationsComponent = class ConversationsComponent {
50349
50575
  this.composerStatus = input("", ...ngDevMode ? [{ debugName: "composerStatus" }] : /* istanbul ignore next */ []);
50350
50576
  this.composerError = input("", ...ngDevMode ? [{ debugName: "composerError" }] : /* istanbul ignore next */ []);
50351
50577
  this.maxLength = input(1600, ...ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []);
50578
+ this.richText = input(false, ...ngDevMode ? [{ debugName: "richText" }] : /* istanbul ignore next */ []);
50352
50579
  this.attachment = input(null, ...ngDevMode ? [{ debugName: "attachment" }] : /* istanbul ignore next */ []);
50353
50580
  this.uploading = input(false, ...ngDevMode ? [{ debugName: "uploading" }] : /* istanbul ignore next */ []);
50354
50581
  this.attachEnabled = input(true, ...ngDevMode ? [{ debugName: "attachEnabled" }] : /* istanbul ignore next */ []);
@@ -50409,7 +50636,9 @@ var ConversationsComponent = class ConversationsComponent {
50409
50636
  this.emptyText = computed(() => this.filtering() ? this.filteredEmptyMessage() : this.canWrite() ? this.emptyMessage() : this.emptyReadOnlyMessage(), ...ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []);
50410
50637
  this.messageRows = computed(() => groupMessagesByDay(this.messages(), this.clock()), ...ngDevMode ? [{ debugName: "messageRows" }] : /* istanbul ignore next */ []);
50411
50638
  this.contextVisible = computed(() => this.hasContext() && this.contextOpen() && !!this.selected(), ...ngDevMode ? [{ debugName: "contextVisible" }] : /* istanbul ignore next */ []);
50412
- this.canSend = computed(() => !this.composerDisabled() && !this.sendBlocked() && !this.sending() && (this.draft().trim().length > 0 || !!this.attachment()), ...ngDevMode ? [{ debugName: "canSend" }] : /* istanbul ignore next */ []);
50639
+ this.canSend = computed(() => !this.composerDisabled() && !this.sendBlocked() && !this.sending() && (this.draftText().length > 0 || !!this.attachment()), ...ngDevMode ? [{ debugName: "canSend" }] : /* istanbul ignore next */ []);
50640
+ this.draftText = computed(() => this.richText() ? conversationHtmlToText(this.draft()) : this.draft().trim(), ...ngDevMode ? [{ debugName: "draftText" }] : /* istanbul ignore next */ []);
50641
+ this.richHide = RICH_COMPOSER_HIDE;
50413
50642
  effect(() => {
50414
50643
  const id = this.selected()?.id ?? null;
50415
50644
  const count = this.messages().length;
@@ -50472,7 +50701,10 @@ var ConversationsComponent = class ConversationsComponent {
50472
50701
  }
50473
50702
  sendMessage() {
50474
50703
  if (!this.canSend()) return;
50475
- this.send.emit({ text: this.draft().trim() });
50704
+ this.send.emit(this.richText() ? {
50705
+ text: this.draftText(),
50706
+ html: sanitizeRichTextHtml(this.draft(), { mode: "paste" })
50707
+ } : { text: this.draft().trim() });
50476
50708
  }
50477
50709
  clock() {
50478
50710
  return this.now() ?? /* @__PURE__ */ new Date();
@@ -50700,6 +50932,13 @@ var ConversationsComponent = class ConversationsComponent {
50700
50932
  isRequired: false,
50701
50933
  transformFunction: null
50702
50934
  },
50935
+ selectable: {
50936
+ classPropertyName: "selectable",
50937
+ publicName: "selectable",
50938
+ isSignal: true,
50939
+ isRequired: false,
50940
+ transformFunction: null
50941
+ },
50703
50942
  newLabel: {
50704
50943
  classPropertyName: "newLabel",
50705
50944
  publicName: "newLabel",
@@ -50987,6 +51226,13 @@ var ConversationsComponent = class ConversationsComponent {
50987
51226
  isRequired: false,
50988
51227
  transformFunction: null
50989
51228
  },
51229
+ richText: {
51230
+ classPropertyName: "richText",
51231
+ publicName: "richText",
51232
+ isSignal: true,
51233
+ isRequired: false,
51234
+ transformFunction: null
51235
+ },
50990
51236
  attachment: {
50991
51237
  classPropertyName: "attachment",
50992
51238
  publicName: "attachment",
@@ -51192,7 +51438,7 @@ var ConversationsComponent = class ConversationsComponent {
51192
51438
  <ui-empty-state iconType="message" data-testid="conv-empty" [title]="filtering() ? filteredEmptyTitle() : emptyTitle()" [message]="emptyText()" />
51193
51439
  } @else {
51194
51440
  <div class="cv-list">
51195
- <ui-list [ariaLabel]="listAriaLabel()" [items]="conversations()" [trackBy]="trackConversation" [navigable]="true" [arrow]="false" (itemClick)="onRowOpen($event)">
51441
+ <ui-list [ariaLabel]="listAriaLabel()" [items]="conversations()" [trackBy]="trackConversation" [navigable]="selectable()" [arrow]="false" (itemClick)="onRowOpen($event)">
51196
51442
  <ng-template let-conv>
51197
51443
  <div class="cv-item" data-testid="conv-item" [attr.data-conversation-id]="conv.id"
51198
51444
  [class.selected]="selected()?.id === conv.id" [class.unread]="(conv.unreadCount ?? 0) > 0">
@@ -51234,9 +51480,11 @@ var ConversationsComponent = class ConversationsComponent {
51234
51480
  <section class="cv-thread-panel" [class.cv-hidden-mobile]="!selected()" [attr.aria-label]="threadAriaLabel()">
51235
51481
  @if (selected(); as conv) {
51236
51482
  <div class="cv-thread-header">
51237
- <ui-button class="cv-back-btn" variant="secondary" size="sm" [ariaLabel]="backLabel()" (click)="onBack()" data-testid="back-to-list">
51238
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
51239
- </ui-button>
51483
+ @if (selectable()) {
51484
+ <ui-button class="cv-back-btn" variant="secondary" size="sm" [ariaLabel]="backLabel()" (click)="onBack()" data-testid="back-to-list">
51485
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
51486
+ </ui-button>
51487
+ }
51240
51488
  <div class="cv-thread-header-info">
51241
51489
  <ui-avatar [initials]="initial(conv.name)" [name]="conv.name" [size]="40" />
51242
51490
  <div class="cv-thread-header-text">
@@ -51314,7 +51562,8 @@ var ConversationsComponent = class ConversationsComponent {
51314
51562
  }
51315
51563
  </div>
51316
51564
  }
51317
- @if (row.message.body) { <p class="cv-body">{{ row.message.body }}</p> }
51565
+ @if (row.message.bodyHtml) { <ui-conversation-rich-body [html]="row.message.bodyHtml" data-testid="msg-rich-body" /> }
51566
+ @else if (row.message.body) { <p class="cv-body">{{ row.message.body }}</p> }
51318
51567
  <span class="cv-meta">
51319
51568
  @if (row.message.direction === 'outbound' && row.message.sender) { <span class="cv-sender" data-testid="msg-sender">{{ row.message.sender }}</span> }
51320
51569
  {{ time(row.message) }}
@@ -51355,9 +51604,15 @@ var ConversationsComponent = class ConversationsComponent {
51355
51604
  <ui-file-input [showField]="false" [accept]="acceptedFiles()" [maxSize]="maxFileSize()" [toastOnReject]="true"
51356
51605
  [typeMessage]="typeMessage()" [sizeMessage]="sizeMessage()" (filesSelected)="filesSelected.emit($event)" data-testid="attach-input" />
51357
51606
  }
51358
- <ui-textarea-input class="cv-compose-input" [ariaLabel]="composeLabel()" [placeholder]="composePlaceholder()" [rows]="1" [maxlength]="maxLength()"
51607
+ @if (richText()) {
51608
+ <ui-rich-text-editor class="cv-compose-input cv-compose-rich" [ariaLabel]="composeLabel()" [placeholder]="composePlaceholder()" [hide]="richHide"
51609
+ [minHeight]="44" [maxHeight]="160" [ngModel]="draft()" (ngModelChange)="draft.set($event)" [disabled]="composerDisabled()" [error]="composerError()"
51610
+ (keydown)="onComposeKeydown($event)" data-testid="compose-input" />
51611
+ } @else {
51612
+ <ui-textarea-input class="cv-compose-input" [ariaLabel]="composeLabel()" [placeholder]="composePlaceholder()" [rows]="1" [maxlength]="maxLength()"
51359
51613
  [ngModel]="draft()" (ngModelChange)="draft.set($event)" [disabled]="composerDisabled()" [error]="composerError()"
51360
51614
  (keydown)="onComposeKeydown($event)" data-testid="compose-input" />
51615
+ }
51361
51616
  <ui-button class="cv-send-btn" variant="primary" [ariaLabel]="sendLabel()" [disabled]="!canSend()" [loading]="sending()" (click)="sendMessage()" data-testid="send-btn">
51362
51617
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
51363
51618
  </ui-button>
@@ -51389,7 +51644,7 @@ var ConversationsComponent = class ConversationsComponent {
51389
51644
  </div>
51390
51645
  `,
51391
51646
  isInline: true,
51392
- styles: [":host{display:flex;flex:1;min-height:0;min-width:0}.cv-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.cv-layout{display:grid;grid-template-columns:340px 1fr;flex:1;min-height:0;min-width:0;background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 1px 3px #0000000f;border:1px solid #e2e8f0}.cv-layout.has-context{grid-template-columns:340px 1fr 280px}.cv-list-panel{display:flex;flex-direction:column;min-height:0;border-right:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cv-list-header{display:flex;align-items:center;justify-content:space-between;padding:20px 20px 12px}.cv-list-title{margin:0;font-size:1.125rem;font-weight:700;color:#1e293b}.cv-search,.cv-filters{padding:0 16px 12px}.cv-list{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}.cv-item{display:flex;gap:12px;padding:14px 16px;border-bottom:1px solid #f1f5f9;transition:background .15s}.cv-item.unread{background:#fffbeb}.cv-item.selected{background:#eff6ff;box-shadow:inset 3px 0 #2563eb}.cv-item-info{flex:1;min-width:0}.cv-row-arrow{flex:0 0 auto;align-self:center;color:#94a3b8}.cv-item-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.cv-name{font-size:.875rem;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cv-time{font-size:.6875rem;color:#64748b;flex-shrink:0;margin-left:8px}.cv-subtitle{font-size:.6875rem;color:#64748b;display:block;margin-bottom:2px}.cv-item-bottom{display:flex;justify-content:space-between;align-items:center;gap:8px}.cv-preview{margin:0;font-size:.8125rem;color:#64748b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.cv-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.cv-delete-btn{opacity:0;transition:opacity .15s}.cv-item:hover .cv-delete-btn,.cv-item:focus-within .cv-delete-btn,.cv-delete-btn:focus-within{opacity:1}@media(hover:none){.cv-delete-btn{opacity:1}}.cv-loading{padding:8px 0}.cv-skeleton{display:flex;gap:12px;align-items:flex-start;padding:14px 16px;border-bottom:1px solid #f1f5f9}.cv-skel-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;padding-top:2px}.cv-skel-row{display:flex;justify-content:space-between;gap:8px}.cv-error{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px;text-align:center}.cv-thread-panel{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:hidden;background:#fff}.cv-thread-header{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid #e2e8f0;background:#fff}.cv-back-btn{display:none}.cv-thread-header-info{display:flex;align-items:center;gap:12px;flex:1;min-width:0}.cv-thread-header-text{min-width:0;display:flex;flex-direction:column}.cv-thread-name{margin:0;font-size:.9375rem;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cv-thread-name:focus{outline:none}.cv-thread-name:focus-visible{outline:2px solid #2563eb;outline-offset:2px;border-radius:4px}.cv-thread-subtitle{font-size:.75rem;color:#64748b}.cv-thread-actions{display:flex;align-items:center;gap:8px}.cv-messages{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;padding:20px 24px;display:flex;flex-direction:column;gap:4px;background:#f8fafc}.cv-messages:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.cv-messages-loading{display:flex;flex-direction:column;gap:12px;padding:20px 0}.cv-msg-skeleton{display:flex}.cv-msg-skeleton.outbound{justify-content:flex-end}.cv-messages-error{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px;text-align:center}.cv-load-earlier{display:flex;justify-content:center;padding:4px 0 12px}.cv-sender{font-weight:600}.cv-msg-action{padding:0;border:0;background:none;color:inherit;font:inherit;text-decoration:underline;cursor:pointer}.cv-msg-action:focus-visible{outline:2px solid currentColor;outline-offset:2px;border-radius:2px}.cv-messages-empty{display:flex;align-items:center;justify-content:center;flex:1}.cv-messages-empty p{margin:0;font-size:.875rem;color:#64748b;text-align:center}.cv-date-separator{display:flex;align-items:center;justify-content:center;padding:16px 0 8px}.cv-date-separator span{padding:4px 14px;border-radius:12px;background:#e2e8f0;font-size:.6875rem;font-weight:600;color:#475569;text-transform:uppercase;letter-spacing:.3px}.cv-bubble{max-width:70%;padding:10px 14px;border-radius:16px;position:relative;word-break:break-word;overflow-wrap:break-word}.cv-bubble.inbound{align-self:flex-start;background:#fff;border:1px solid #e2e8f0;border-bottom-left-radius:4px}.cv-bubble.inbound .cv-body{color:#1e293b}.cv-bubble.inbound .cv-meta{color:#64748b}.cv-bubble.outbound{align-self:flex-end;background:#2563eb;border-bottom-right-radius:4px}.cv-bubble.outbound .cv-body,.cv-bubble.outbound .cv-meta{color:#fff}@media(prefers-reduced-motion:no-preference){.cv-bubble{animation:cv-appear .2s ease}.cv-context{animation:cv-slide-in .25s ease}}.cv-body{margin:0;font-size:.875rem;line-height:1.45;word-break:break-word;white-space:pre-wrap}.cv-media{margin-bottom:6px}.cv-image-btn{display:block;padding:0;border:0;background:none;cursor:pointer;border-radius:8px}.cv-image-btn:focus-visible{outline:2px solid #fff;outline-offset:2px;box-shadow:0 0 0 4px #2563eb}.cv-image{display:block;max-width:240px;max-height:240px;border-radius:8px;object-fit:cover}.cv-video{max-width:240px;max-height:200px;border-radius:8px}.cv-file-link{font-size:.8125rem;color:#fff;text-decoration:underline}.cv-bubble.inbound .cv-file-link{color:#2563eb}.cv-meta{display:flex;align-items:center;gap:6px;justify-content:flex-end;font-size:.6875rem;margin-top:4px}.cv-status{font-weight:500}.cv-status.failed{color:#fff;font-weight:700}.cv-bubble.inbound .cv-status.failed{color:#dc2626}.cv-compose{display:flex;flex-direction:column;padding:12px 20px 16px;padding-bottom:calc(16px + env(safe-area-inset-bottom,0px));border-top:1px solid #e2e8f0;background:#fff}.cv-compose-row{display:flex;align-items:flex-end;gap:10px}.cv-compose-input{flex:1;min-width:0}.cv-attach-btn,.cv-send-btn{flex-shrink:0}.cv-attachment{display:flex;align-items:center;gap:8px;padding:8px 12px;margin-bottom:8px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px}.cv-attachment-thumb{width:48px;height:48px;object-fit:cover;border-radius:6px}.cv-attachment-name{font-size:.8125rem;color:#475569;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cv-attachment-remove{flex-shrink:0}.cv-compose-status{margin:4px 0 0;font-size:.8125rem;color:#64748b}.cv-compose-status:empty{margin:0}.cv-context-backdrop{display:none}.cv-context{width:100%;min-width:0;border-left:1px solid #e2e8f0;background:#fff;display:flex;flex-direction:column;overflow-y:auto}.cv-context-header{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid #e2e8f0}.cv-context-header h3{margin:0;font-size:.875rem;font-weight:700;color:#1e293b}.cv-context-body{padding:20px;display:flex;flex-direction:column;gap:16px}@keyframes cv-appear{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes cv-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}@media(max-width:1100px){.cv-layout.has-context{grid-template-columns:280px 1fr 240px}}@media(max-width:768px){.cv-layout,.cv-layout.has-context{grid-template-columns:1fr;height:100%}.cv-hidden-mobile{display:none!important}.cv-back-btn{display:inline-flex}.cv-context-backdrop{display:block;position:fixed;inset:0;background:#00000059;z-index:99}.cv-context{position:fixed;top:0;right:0;bottom:0;width:300px;max-width:85vw;z-index:100;box-shadow:-4px 0 20px #0000001a}.cv-bubble{max-width:85%}.cv-messages,.cv-thread-header{padding:12px 16px}}@media(max-width:480px){.cv-thread-subtitle{display:none}.cv-compose{padding:8px 12px 12px;padding-bottom:calc(12px + env(safe-area-inset-bottom,0px))}.cv-list-header{padding:12px 16px 10px}.cv-context{width:100%;max-width:100vw}}\n"],
51647
+ styles: [":host{display:flex;flex:1;min-height:0;min-width:0}.cv-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.cv-layout{display:grid;grid-template-columns:340px 1fr;flex:1;min-height:0;min-width:0;background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 1px 3px #0000000f;border:1px solid #e2e8f0}.cv-layout.has-context{grid-template-columns:340px 1fr 280px}.cv-list-panel{display:flex;flex-direction:column;min-height:0;border-right:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cv-list-header{display:flex;align-items:center;justify-content:space-between;padding:20px 20px 12px}.cv-list-title{margin:0;font-size:1.125rem;font-weight:700;color:#1e293b}.cv-search,.cv-filters{padding:0 16px 12px}.cv-list{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}.cv-item{display:flex;gap:12px;padding:14px 16px;border-bottom:1px solid #f1f5f9;transition:background .15s}.cv-item.unread{background:#fffbeb}.cv-item.selected{background:#eff6ff;box-shadow:inset 3px 0 #2563eb}.cv-item-info{flex:1;min-width:0}.cv-row-arrow{flex:0 0 auto;align-self:center;color:#94a3b8}.cv-item-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.cv-name{font-size:.875rem;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cv-time{font-size:.6875rem;color:#64748b;flex-shrink:0;margin-left:8px}.cv-subtitle{font-size:.6875rem;color:#64748b;display:block;margin-bottom:2px}.cv-item-bottom{display:flex;justify-content:space-between;align-items:center;gap:8px}.cv-preview{margin:0;font-size:.8125rem;color:#64748b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.cv-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.cv-delete-btn{opacity:0;transition:opacity .15s}.cv-item:hover .cv-delete-btn,.cv-item:focus-within .cv-delete-btn,.cv-delete-btn:focus-within{opacity:1}@media(hover:none){.cv-delete-btn{opacity:1}}.cv-loading{padding:8px 0}.cv-skeleton{display:flex;gap:12px;align-items:flex-start;padding:14px 16px;border-bottom:1px solid #f1f5f9}.cv-skel-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;padding-top:2px}.cv-skel-row{display:flex;justify-content:space-between;gap:8px}.cv-error{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px;text-align:center}.cv-thread-panel{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:hidden;background:#fff}.cv-thread-header{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid #e2e8f0;background:#fff}.cv-back-btn{display:none}.cv-thread-header-info{display:flex;align-items:center;gap:12px;flex:1;min-width:0}.cv-thread-header-text{min-width:0;display:flex;flex-direction:column}.cv-thread-name{margin:0;font-size:.9375rem;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cv-thread-name:focus{outline:none}.cv-thread-name:focus-visible{outline:2px solid #2563eb;outline-offset:2px;border-radius:4px}.cv-thread-subtitle{font-size:.75rem;color:#64748b}.cv-thread-actions{display:flex;align-items:center;gap:8px}.cv-messages{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;padding:20px 24px;display:flex;flex-direction:column;gap:4px;background:#f8fafc}.cv-messages:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.cv-messages-loading{display:flex;flex-direction:column;gap:12px;padding:20px 0}.cv-msg-skeleton{display:flex}.cv-msg-skeleton.outbound{justify-content:flex-end}.cv-messages-error{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px;text-align:center}.cv-load-earlier{display:flex;justify-content:center;padding:4px 0 12px}.cv-sender{font-weight:600}.cv-msg-action{padding:0;border:0;background:none;color:inherit;font:inherit;text-decoration:underline;cursor:pointer}.cv-msg-action:focus-visible{outline:2px solid currentColor;outline-offset:2px;border-radius:2px}.cv-messages-empty{display:flex;align-items:center;justify-content:center;flex:1}.cv-messages-empty p{margin:0;font-size:.875rem;color:#64748b;text-align:center}.cv-date-separator{display:flex;align-items:center;justify-content:center;padding:16px 0 8px}.cv-date-separator span{padding:4px 14px;border-radius:12px;background:#e2e8f0;font-size:.6875rem;font-weight:600;color:#475569;text-transform:uppercase;letter-spacing:.3px}.cv-bubble{max-width:70%;padding:10px 14px;border-radius:16px;position:relative;word-break:break-word;overflow-wrap:break-word}.cv-bubble.inbound{align-self:flex-start;background:#fff;border:1px solid #e2e8f0;border-bottom-left-radius:4px}.cv-bubble.inbound .cv-body,.cv-bubble.inbound .cv-rich{color:#1e293b}.cv-bubble.inbound .cv-meta{color:#64748b}.cv-bubble.outbound{align-self:flex-end;background:#2563eb;border-bottom-right-radius:4px}.cv-bubble.outbound .cv-body,.cv-bubble.outbound .cv-rich,.cv-bubble.outbound .cv-meta{color:#fff}@media(prefers-reduced-motion:no-preference){.cv-bubble{animation:cv-appear .2s ease}.cv-context{animation:cv-slide-in .25s ease}}.cv-body{margin:0;font-size:.875rem;line-height:1.45;word-break:break-word;white-space:pre-wrap}.cv-media{margin-bottom:6px}.cv-image-btn{display:block;padding:0;border:0;background:none;cursor:pointer;border-radius:8px}.cv-image-btn:focus-visible{outline:2px solid #fff;outline-offset:2px;box-shadow:0 0 0 4px #2563eb}.cv-image{display:block;max-width:240px;max-height:240px;border-radius:8px;object-fit:cover}.cv-video{max-width:240px;max-height:200px;border-radius:8px}.cv-file-link{font-size:.8125rem;color:#fff;text-decoration:underline}.cv-bubble.inbound .cv-file-link{color:#2563eb}.cv-meta{display:flex;align-items:center;gap:6px;justify-content:flex-end;font-size:.6875rem;margin-top:4px}.cv-status{font-weight:500}.cv-status.failed{color:#fff;font-weight:700}.cv-bubble.inbound .cv-status.failed{color:#dc2626}.cv-compose{display:flex;flex-direction:column;padding:12px 20px 16px;padding-bottom:calc(16px + env(safe-area-inset-bottom,0px));border-top:1px solid #e2e8f0;background:#fff}.cv-compose-row{display:flex;align-items:flex-end;gap:10px}.cv-compose-input{flex:1;min-width:0}.cv-attach-btn,.cv-send-btn{flex-shrink:0}.cv-attachment{display:flex;align-items:center;gap:8px;padding:8px 12px;margin-bottom:8px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px}.cv-attachment-thumb{width:48px;height:48px;object-fit:cover;border-radius:6px}.cv-attachment-name{font-size:.8125rem;color:#475569;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cv-attachment-remove{flex-shrink:0}.cv-compose-status{margin:4px 0 0;font-size:.8125rem;color:#64748b}.cv-compose-status:empty{margin:0}.cv-context-backdrop{display:none}.cv-context{width:100%;min-width:0;border-left:1px solid #e2e8f0;background:#fff;display:flex;flex-direction:column;overflow-y:auto}.cv-context-header{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid #e2e8f0}.cv-context-header h3{margin:0;font-size:.875rem;font-weight:700;color:#1e293b}.cv-context-body{padding:20px;display:flex;flex-direction:column;gap:16px}@keyframes cv-appear{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes cv-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}@media(max-width:1100px){.cv-layout.has-context{grid-template-columns:280px 1fr 240px}}@media(max-width:768px){.cv-layout,.cv-layout.has-context{grid-template-columns:1fr;height:100%}.cv-hidden-mobile{display:none!important}.cv-back-btn{display:inline-flex}.cv-context-backdrop{display:block;position:fixed;inset:0;background:#00000059;z-index:99}.cv-context{position:fixed;top:0;right:0;bottom:0;width:300px;max-width:85vw;z-index:100;box-shadow:-4px 0 20px #0000001a}.cv-bubble{max-width:85%}.cv-messages,.cv-thread-header{padding:12px 16px}}@media(max-width:480px){.cv-thread-subtitle{display:none}.cv-compose{padding:8px 12px 12px;padding-bottom:calc(12px + env(safe-area-inset-bottom,0px))}.cv-list-header{padding:12px 16px 10px}.cv-context{width:100%;max-width:100vw}}\n"],
51393
51648
  dependencies: [
51394
51649
  {
51395
51650
  kind: "ngmodule",
@@ -51594,6 +51849,24 @@ var ConversationsComponent = class ConversationsComponent {
51594
51849
  ],
51595
51850
  outputs: ["tabChange"]
51596
51851
  },
51852
+ {
51853
+ kind: "component",
51854
+ type: RichTextEditorComponent,
51855
+ selector: "ui-rich-text-editor",
51856
+ inputs: [
51857
+ "label",
51858
+ "ariaLabel",
51859
+ "placeholder",
51860
+ "required",
51861
+ "readonly",
51862
+ "hint",
51863
+ "error",
51864
+ "minHeight",
51865
+ "maxHeight",
51866
+ "hide",
51867
+ "disabled"
51868
+ ]
51869
+ },
51597
51870
  {
51598
51871
  kind: "component",
51599
51872
  type: SearchInputComponent,
@@ -51651,6 +51924,12 @@ var ConversationsComponent = class ConversationsComponent {
51651
51924
  type: TooltipDirective,
51652
51925
  selector: "[uiTooltip]",
51653
51926
  inputs: ["uiTooltip", "tooltipPosition"]
51927
+ },
51928
+ {
51929
+ kind: "component",
51930
+ type: ConversationRichBodyComponent,
51931
+ selector: "ui-conversation-rich-body",
51932
+ inputs: ["html"]
51654
51933
  }
51655
51934
  ],
51656
51935
  changeDetection: i0.ChangeDetectionStrategy.OnPush
@@ -51679,10 +51958,12 @@ i0.ɵɵngDeclareClassMetadata({
51679
51958
  ListComponent,
51680
51959
  PaginationComponent,
51681
51960
  QuickFilterTabsComponent,
51961
+ RichTextEditorComponent,
51682
51962
  SearchInputComponent,
51683
51963
  SkeletonComponent,
51684
51964
  TextareaInputComponent,
51685
- TooltipDirective
51965
+ TooltipDirective,
51966
+ ConversationRichBodyComponent
51686
51967
  ],
51687
51968
  template: `
51688
51969
  <div class="cv-layout" [class.has-context]="contextVisible()" data-testid="conversations">
@@ -51737,7 +52018,7 @@ i0.ɵɵngDeclareClassMetadata({
51737
52018
  <ui-empty-state iconType="message" data-testid="conv-empty" [title]="filtering() ? filteredEmptyTitle() : emptyTitle()" [message]="emptyText()" />
51738
52019
  } @else {
51739
52020
  <div class="cv-list">
51740
- <ui-list [ariaLabel]="listAriaLabel()" [items]="conversations()" [trackBy]="trackConversation" [navigable]="true" [arrow]="false" (itemClick)="onRowOpen($event)">
52021
+ <ui-list [ariaLabel]="listAriaLabel()" [items]="conversations()" [trackBy]="trackConversation" [navigable]="selectable()" [arrow]="false" (itemClick)="onRowOpen($event)">
51741
52022
  <ng-template let-conv>
51742
52023
  <div class="cv-item" data-testid="conv-item" [attr.data-conversation-id]="conv.id"
51743
52024
  [class.selected]="selected()?.id === conv.id" [class.unread]="(conv.unreadCount ?? 0) > 0">
@@ -51779,9 +52060,11 @@ i0.ɵɵngDeclareClassMetadata({
51779
52060
  <section class="cv-thread-panel" [class.cv-hidden-mobile]="!selected()" [attr.aria-label]="threadAriaLabel()">
51780
52061
  @if (selected(); as conv) {
51781
52062
  <div class="cv-thread-header">
51782
- <ui-button class="cv-back-btn" variant="secondary" size="sm" [ariaLabel]="backLabel()" (click)="onBack()" data-testid="back-to-list">
51783
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
51784
- </ui-button>
52063
+ @if (selectable()) {
52064
+ <ui-button class="cv-back-btn" variant="secondary" size="sm" [ariaLabel]="backLabel()" (click)="onBack()" data-testid="back-to-list">
52065
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
52066
+ </ui-button>
52067
+ }
51785
52068
  <div class="cv-thread-header-info">
51786
52069
  <ui-avatar [initials]="initial(conv.name)" [name]="conv.name" [size]="40" />
51787
52070
  <div class="cv-thread-header-text">
@@ -51859,7 +52142,8 @@ i0.ɵɵngDeclareClassMetadata({
51859
52142
  }
51860
52143
  </div>
51861
52144
  }
51862
- @if (row.message.body) { <p class="cv-body">{{ row.message.body }}</p> }
52145
+ @if (row.message.bodyHtml) { <ui-conversation-rich-body [html]="row.message.bodyHtml" data-testid="msg-rich-body" /> }
52146
+ @else if (row.message.body) { <p class="cv-body">{{ row.message.body }}</p> }
51863
52147
  <span class="cv-meta">
51864
52148
  @if (row.message.direction === 'outbound' && row.message.sender) { <span class="cv-sender" data-testid="msg-sender">{{ row.message.sender }}</span> }
51865
52149
  {{ time(row.message) }}
@@ -51900,9 +52184,15 @@ i0.ɵɵngDeclareClassMetadata({
51900
52184
  <ui-file-input [showField]="false" [accept]="acceptedFiles()" [maxSize]="maxFileSize()" [toastOnReject]="true"
51901
52185
  [typeMessage]="typeMessage()" [sizeMessage]="sizeMessage()" (filesSelected)="filesSelected.emit($event)" data-testid="attach-input" />
51902
52186
  }
51903
- <ui-textarea-input class="cv-compose-input" [ariaLabel]="composeLabel()" [placeholder]="composePlaceholder()" [rows]="1" [maxlength]="maxLength()"
52187
+ @if (richText()) {
52188
+ <ui-rich-text-editor class="cv-compose-input cv-compose-rich" [ariaLabel]="composeLabel()" [placeholder]="composePlaceholder()" [hide]="richHide"
52189
+ [minHeight]="44" [maxHeight]="160" [ngModel]="draft()" (ngModelChange)="draft.set($event)" [disabled]="composerDisabled()" [error]="composerError()"
52190
+ (keydown)="onComposeKeydown($event)" data-testid="compose-input" />
52191
+ } @else {
52192
+ <ui-textarea-input class="cv-compose-input" [ariaLabel]="composeLabel()" [placeholder]="composePlaceholder()" [rows]="1" [maxlength]="maxLength()"
51904
52193
  [ngModel]="draft()" (ngModelChange)="draft.set($event)" [disabled]="composerDisabled()" [error]="composerError()"
51905
52194
  (keydown)="onComposeKeydown($event)" data-testid="compose-input" />
52195
+ }
51906
52196
  <ui-button class="cv-send-btn" variant="primary" [ariaLabel]="sendLabel()" [disabled]="!canSend()" [loading]="sending()" (click)="sendMessage()" data-testid="send-btn">
51907
52197
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
51908
52198
  </ui-button>
@@ -51933,7 +52223,7 @@ i0.ɵɵngDeclareClassMetadata({
51933
52223
  }
51934
52224
  </div>
51935
52225
  `,
51936
- styles: [":host{display:flex;flex:1;min-height:0;min-width:0}.cv-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.cv-layout{display:grid;grid-template-columns:340px 1fr;flex:1;min-height:0;min-width:0;background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 1px 3px #0000000f;border:1px solid #e2e8f0}.cv-layout.has-context{grid-template-columns:340px 1fr 280px}.cv-list-panel{display:flex;flex-direction:column;min-height:0;border-right:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cv-list-header{display:flex;align-items:center;justify-content:space-between;padding:20px 20px 12px}.cv-list-title{margin:0;font-size:1.125rem;font-weight:700;color:#1e293b}.cv-search,.cv-filters{padding:0 16px 12px}.cv-list{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}.cv-item{display:flex;gap:12px;padding:14px 16px;border-bottom:1px solid #f1f5f9;transition:background .15s}.cv-item.unread{background:#fffbeb}.cv-item.selected{background:#eff6ff;box-shadow:inset 3px 0 #2563eb}.cv-item-info{flex:1;min-width:0}.cv-row-arrow{flex:0 0 auto;align-self:center;color:#94a3b8}.cv-item-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.cv-name{font-size:.875rem;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cv-time{font-size:.6875rem;color:#64748b;flex-shrink:0;margin-left:8px}.cv-subtitle{font-size:.6875rem;color:#64748b;display:block;margin-bottom:2px}.cv-item-bottom{display:flex;justify-content:space-between;align-items:center;gap:8px}.cv-preview{margin:0;font-size:.8125rem;color:#64748b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.cv-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.cv-delete-btn{opacity:0;transition:opacity .15s}.cv-item:hover .cv-delete-btn,.cv-item:focus-within .cv-delete-btn,.cv-delete-btn:focus-within{opacity:1}@media(hover:none){.cv-delete-btn{opacity:1}}.cv-loading{padding:8px 0}.cv-skeleton{display:flex;gap:12px;align-items:flex-start;padding:14px 16px;border-bottom:1px solid #f1f5f9}.cv-skel-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;padding-top:2px}.cv-skel-row{display:flex;justify-content:space-between;gap:8px}.cv-error{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px;text-align:center}.cv-thread-panel{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:hidden;background:#fff}.cv-thread-header{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid #e2e8f0;background:#fff}.cv-back-btn{display:none}.cv-thread-header-info{display:flex;align-items:center;gap:12px;flex:1;min-width:0}.cv-thread-header-text{min-width:0;display:flex;flex-direction:column}.cv-thread-name{margin:0;font-size:.9375rem;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cv-thread-name:focus{outline:none}.cv-thread-name:focus-visible{outline:2px solid #2563eb;outline-offset:2px;border-radius:4px}.cv-thread-subtitle{font-size:.75rem;color:#64748b}.cv-thread-actions{display:flex;align-items:center;gap:8px}.cv-messages{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;padding:20px 24px;display:flex;flex-direction:column;gap:4px;background:#f8fafc}.cv-messages:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.cv-messages-loading{display:flex;flex-direction:column;gap:12px;padding:20px 0}.cv-msg-skeleton{display:flex}.cv-msg-skeleton.outbound{justify-content:flex-end}.cv-messages-error{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px;text-align:center}.cv-load-earlier{display:flex;justify-content:center;padding:4px 0 12px}.cv-sender{font-weight:600}.cv-msg-action{padding:0;border:0;background:none;color:inherit;font:inherit;text-decoration:underline;cursor:pointer}.cv-msg-action:focus-visible{outline:2px solid currentColor;outline-offset:2px;border-radius:2px}.cv-messages-empty{display:flex;align-items:center;justify-content:center;flex:1}.cv-messages-empty p{margin:0;font-size:.875rem;color:#64748b;text-align:center}.cv-date-separator{display:flex;align-items:center;justify-content:center;padding:16px 0 8px}.cv-date-separator span{padding:4px 14px;border-radius:12px;background:#e2e8f0;font-size:.6875rem;font-weight:600;color:#475569;text-transform:uppercase;letter-spacing:.3px}.cv-bubble{max-width:70%;padding:10px 14px;border-radius:16px;position:relative;word-break:break-word;overflow-wrap:break-word}.cv-bubble.inbound{align-self:flex-start;background:#fff;border:1px solid #e2e8f0;border-bottom-left-radius:4px}.cv-bubble.inbound .cv-body{color:#1e293b}.cv-bubble.inbound .cv-meta{color:#64748b}.cv-bubble.outbound{align-self:flex-end;background:#2563eb;border-bottom-right-radius:4px}.cv-bubble.outbound .cv-body,.cv-bubble.outbound .cv-meta{color:#fff}@media(prefers-reduced-motion:no-preference){.cv-bubble{animation:cv-appear .2s ease}.cv-context{animation:cv-slide-in .25s ease}}.cv-body{margin:0;font-size:.875rem;line-height:1.45;word-break:break-word;white-space:pre-wrap}.cv-media{margin-bottom:6px}.cv-image-btn{display:block;padding:0;border:0;background:none;cursor:pointer;border-radius:8px}.cv-image-btn:focus-visible{outline:2px solid #fff;outline-offset:2px;box-shadow:0 0 0 4px #2563eb}.cv-image{display:block;max-width:240px;max-height:240px;border-radius:8px;object-fit:cover}.cv-video{max-width:240px;max-height:200px;border-radius:8px}.cv-file-link{font-size:.8125rem;color:#fff;text-decoration:underline}.cv-bubble.inbound .cv-file-link{color:#2563eb}.cv-meta{display:flex;align-items:center;gap:6px;justify-content:flex-end;font-size:.6875rem;margin-top:4px}.cv-status{font-weight:500}.cv-status.failed{color:#fff;font-weight:700}.cv-bubble.inbound .cv-status.failed{color:#dc2626}.cv-compose{display:flex;flex-direction:column;padding:12px 20px 16px;padding-bottom:calc(16px + env(safe-area-inset-bottom,0px));border-top:1px solid #e2e8f0;background:#fff}.cv-compose-row{display:flex;align-items:flex-end;gap:10px}.cv-compose-input{flex:1;min-width:0}.cv-attach-btn,.cv-send-btn{flex-shrink:0}.cv-attachment{display:flex;align-items:center;gap:8px;padding:8px 12px;margin-bottom:8px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px}.cv-attachment-thumb{width:48px;height:48px;object-fit:cover;border-radius:6px}.cv-attachment-name{font-size:.8125rem;color:#475569;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cv-attachment-remove{flex-shrink:0}.cv-compose-status{margin:4px 0 0;font-size:.8125rem;color:#64748b}.cv-compose-status:empty{margin:0}.cv-context-backdrop{display:none}.cv-context{width:100%;min-width:0;border-left:1px solid #e2e8f0;background:#fff;display:flex;flex-direction:column;overflow-y:auto}.cv-context-header{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid #e2e8f0}.cv-context-header h3{margin:0;font-size:.875rem;font-weight:700;color:#1e293b}.cv-context-body{padding:20px;display:flex;flex-direction:column;gap:16px}@keyframes cv-appear{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes cv-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}@media(max-width:1100px){.cv-layout.has-context{grid-template-columns:280px 1fr 240px}}@media(max-width:768px){.cv-layout,.cv-layout.has-context{grid-template-columns:1fr;height:100%}.cv-hidden-mobile{display:none!important}.cv-back-btn{display:inline-flex}.cv-context-backdrop{display:block;position:fixed;inset:0;background:#00000059;z-index:99}.cv-context{position:fixed;top:0;right:0;bottom:0;width:300px;max-width:85vw;z-index:100;box-shadow:-4px 0 20px #0000001a}.cv-bubble{max-width:85%}.cv-messages,.cv-thread-header{padding:12px 16px}}@media(max-width:480px){.cv-thread-subtitle{display:none}.cv-compose{padding:8px 12px 12px;padding-bottom:calc(12px + env(safe-area-inset-bottom,0px))}.cv-list-header{padding:12px 16px 10px}.cv-context{width:100%;max-width:100vw}}\n"]
52226
+ styles: [":host{display:flex;flex:1;min-height:0;min-width:0}.cv-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.cv-layout{display:grid;grid-template-columns:340px 1fr;flex:1;min-height:0;min-width:0;background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 1px 3px #0000000f;border:1px solid #e2e8f0}.cv-layout.has-context{grid-template-columns:340px 1fr 280px}.cv-list-panel{display:flex;flex-direction:column;min-height:0;border-right:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cv-list-header{display:flex;align-items:center;justify-content:space-between;padding:20px 20px 12px}.cv-list-title{margin:0;font-size:1.125rem;font-weight:700;color:#1e293b}.cv-search,.cv-filters{padding:0 16px 12px}.cv-list{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}.cv-item{display:flex;gap:12px;padding:14px 16px;border-bottom:1px solid #f1f5f9;transition:background .15s}.cv-item.unread{background:#fffbeb}.cv-item.selected{background:#eff6ff;box-shadow:inset 3px 0 #2563eb}.cv-item-info{flex:1;min-width:0}.cv-row-arrow{flex:0 0 auto;align-self:center;color:#94a3b8}.cv-item-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.cv-name{font-size:.875rem;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cv-time{font-size:.6875rem;color:#64748b;flex-shrink:0;margin-left:8px}.cv-subtitle{font-size:.6875rem;color:#64748b;display:block;margin-bottom:2px}.cv-item-bottom{display:flex;justify-content:space-between;align-items:center;gap:8px}.cv-preview{margin:0;font-size:.8125rem;color:#64748b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.cv-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.cv-delete-btn{opacity:0;transition:opacity .15s}.cv-item:hover .cv-delete-btn,.cv-item:focus-within .cv-delete-btn,.cv-delete-btn:focus-within{opacity:1}@media(hover:none){.cv-delete-btn{opacity:1}}.cv-loading{padding:8px 0}.cv-skeleton{display:flex;gap:12px;align-items:flex-start;padding:14px 16px;border-bottom:1px solid #f1f5f9}.cv-skel-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;padding-top:2px}.cv-skel-row{display:flex;justify-content:space-between;gap:8px}.cv-error{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px;text-align:center}.cv-thread-panel{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:hidden;background:#fff}.cv-thread-header{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid #e2e8f0;background:#fff}.cv-back-btn{display:none}.cv-thread-header-info{display:flex;align-items:center;gap:12px;flex:1;min-width:0}.cv-thread-header-text{min-width:0;display:flex;flex-direction:column}.cv-thread-name{margin:0;font-size:.9375rem;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cv-thread-name:focus{outline:none}.cv-thread-name:focus-visible{outline:2px solid #2563eb;outline-offset:2px;border-radius:4px}.cv-thread-subtitle{font-size:.75rem;color:#64748b}.cv-thread-actions{display:flex;align-items:center;gap:8px}.cv-messages{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;padding:20px 24px;display:flex;flex-direction:column;gap:4px;background:#f8fafc}.cv-messages:focus-visible{outline:2px solid #2563eb;outline-offset:-2px}.cv-messages-loading{display:flex;flex-direction:column;gap:12px;padding:20px 0}.cv-msg-skeleton{display:flex}.cv-msg-skeleton.outbound{justify-content:flex-end}.cv-messages-error{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px;text-align:center}.cv-load-earlier{display:flex;justify-content:center;padding:4px 0 12px}.cv-sender{font-weight:600}.cv-msg-action{padding:0;border:0;background:none;color:inherit;font:inherit;text-decoration:underline;cursor:pointer}.cv-msg-action:focus-visible{outline:2px solid currentColor;outline-offset:2px;border-radius:2px}.cv-messages-empty{display:flex;align-items:center;justify-content:center;flex:1}.cv-messages-empty p{margin:0;font-size:.875rem;color:#64748b;text-align:center}.cv-date-separator{display:flex;align-items:center;justify-content:center;padding:16px 0 8px}.cv-date-separator span{padding:4px 14px;border-radius:12px;background:#e2e8f0;font-size:.6875rem;font-weight:600;color:#475569;text-transform:uppercase;letter-spacing:.3px}.cv-bubble{max-width:70%;padding:10px 14px;border-radius:16px;position:relative;word-break:break-word;overflow-wrap:break-word}.cv-bubble.inbound{align-self:flex-start;background:#fff;border:1px solid #e2e8f0;border-bottom-left-radius:4px}.cv-bubble.inbound .cv-body,.cv-bubble.inbound .cv-rich{color:#1e293b}.cv-bubble.inbound .cv-meta{color:#64748b}.cv-bubble.outbound{align-self:flex-end;background:#2563eb;border-bottom-right-radius:4px}.cv-bubble.outbound .cv-body,.cv-bubble.outbound .cv-rich,.cv-bubble.outbound .cv-meta{color:#fff}@media(prefers-reduced-motion:no-preference){.cv-bubble{animation:cv-appear .2s ease}.cv-context{animation:cv-slide-in .25s ease}}.cv-body{margin:0;font-size:.875rem;line-height:1.45;word-break:break-word;white-space:pre-wrap}.cv-media{margin-bottom:6px}.cv-image-btn{display:block;padding:0;border:0;background:none;cursor:pointer;border-radius:8px}.cv-image-btn:focus-visible{outline:2px solid #fff;outline-offset:2px;box-shadow:0 0 0 4px #2563eb}.cv-image{display:block;max-width:240px;max-height:240px;border-radius:8px;object-fit:cover}.cv-video{max-width:240px;max-height:200px;border-radius:8px}.cv-file-link{font-size:.8125rem;color:#fff;text-decoration:underline}.cv-bubble.inbound .cv-file-link{color:#2563eb}.cv-meta{display:flex;align-items:center;gap:6px;justify-content:flex-end;font-size:.6875rem;margin-top:4px}.cv-status{font-weight:500}.cv-status.failed{color:#fff;font-weight:700}.cv-bubble.inbound .cv-status.failed{color:#dc2626}.cv-compose{display:flex;flex-direction:column;padding:12px 20px 16px;padding-bottom:calc(16px + env(safe-area-inset-bottom,0px));border-top:1px solid #e2e8f0;background:#fff}.cv-compose-row{display:flex;align-items:flex-end;gap:10px}.cv-compose-input{flex:1;min-width:0}.cv-attach-btn,.cv-send-btn{flex-shrink:0}.cv-attachment{display:flex;align-items:center;gap:8px;padding:8px 12px;margin-bottom:8px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px}.cv-attachment-thumb{width:48px;height:48px;object-fit:cover;border-radius:6px}.cv-attachment-name{font-size:.8125rem;color:#475569;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cv-attachment-remove{flex-shrink:0}.cv-compose-status{margin:4px 0 0;font-size:.8125rem;color:#64748b}.cv-compose-status:empty{margin:0}.cv-context-backdrop{display:none}.cv-context{width:100%;min-width:0;border-left:1px solid #e2e8f0;background:#fff;display:flex;flex-direction:column;overflow-y:auto}.cv-context-header{display:flex;justify-content:space-between;align-items:center;padding:20px;border-bottom:1px solid #e2e8f0}.cv-context-header h3{margin:0;font-size:.875rem;font-weight:700;color:#1e293b}.cv-context-body{padding:20px;display:flex;flex-direction:column;gap:16px}@keyframes cv-appear{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes cv-slide-in{0%{transform:translate(100%)}to{transform:translate(0)}}@media(max-width:1100px){.cv-layout.has-context{grid-template-columns:280px 1fr 240px}}@media(max-width:768px){.cv-layout,.cv-layout.has-context{grid-template-columns:1fr;height:100%}.cv-hidden-mobile{display:none!important}.cv-back-btn{display:inline-flex}.cv-context-backdrop{display:block;position:fixed;inset:0;background:#00000059;z-index:99}.cv-context{position:fixed;top:0;right:0;bottom:0;width:300px;max-width:85vw;z-index:100;box-shadow:-4px 0 20px #0000001a}.cv-bubble{max-width:85%}.cv-messages,.cv-thread-header{padding:12px 16px}}@media(max-width:480px){.cv-thread-subtitle{display:none}.cv-compose{padding:8px 12px 12px;padding-bottom:calc(12px + env(safe-area-inset-bottom,0px))}.cv-list-header{padding:12px 16px 10px}.cv-context{width:100%;max-width:100vw}}\n"]
51937
52227
  }]
51938
52228
  }],
51939
52229
  ctorParameters: () => [],
@@ -52165,6 +52455,14 @@ i0.ɵɵngDeclareClassMetadata({
52165
52455
  required: false
52166
52456
  }]
52167
52457
  }],
52458
+ selectable: [{
52459
+ type: i0.Input,
52460
+ args: [{
52461
+ isSignal: true,
52462
+ alias: "selectable",
52463
+ required: false
52464
+ }]
52465
+ }],
52168
52466
  newLabel: [{
52169
52467
  type: i0.Input,
52170
52468
  args: [{
@@ -52499,6 +52797,14 @@ i0.ɵɵngDeclareClassMetadata({
52499
52797
  required: false
52500
52798
  }]
52501
52799
  }],
52800
+ richText: [{
52801
+ type: i0.Input,
52802
+ args: [{
52803
+ isSignal: true,
52804
+ alias: "richText",
52805
+ required: false
52806
+ }]
52807
+ }],
52502
52808
  attachment: [{
52503
52809
  type: i0.Input,
52504
52810
  args: [{
@@ -52697,6 +53003,6 @@ i0.ɵɵngDeclareClassMetadata({
52697
53003
  }]
52698
53004
  }
52699
53005
  });
52700
- export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BankAccountFormComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, ConversationsComponent, DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS, DEFAULT_BANK_HOLDER_TYPE_OPTIONS, DEFAULT_BANK_MANDATE_TEXT, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FixedFooterComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OfflineBannerComponent, OptionCardComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, ReminderAlertsComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShareMenuComponent, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, SnackbarComponent, SnackbarService, StackComponent, StarComponent, StepperComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextTemplatePickerComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildPreviewDocument, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, conversationDateLabel, conversationInitial, conversationMessageStatusLabel, conversationMessageStatusMark, createFieldReveal, decodeFilterValues, digitsOnly, downloadBlob, emailShareUrl, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, facebookShareUrl, fileMatchesAccept, formatAddress, formatCategoryLabel, formatConversationPhone, formatConversationTime, formatCurrency, formatFileSize, formatIsoDate, formatIsoDateTime, formatMessageTime, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, gmailShareUrl, groupMessagesByDay, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isValidEmailAddress, isWebUrl, isoKey, issueToErrors, linkedInShareUrl, maxLengthIssue, mergeDescribedBy, normalizeHexColor, outlookShareUrl, parseBizHours, parseIso, parseTime, passwordMeetsRules, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, serializedTextLength, setupIntegrations, splitIntro, truncateConversationText, xShareUrl };
53006
+ export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BankAccountFormComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, ConversationRichBodyComponent, ConversationsComponent, DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS, DEFAULT_BANK_HOLDER_TYPE_OPTIONS, DEFAULT_BANK_MANDATE_TEXT, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FixedFooterComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OfflineBannerComponent, OptionCardComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, ReminderAlertsComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShareMenuComponent, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, SnackbarComponent, SnackbarService, StackComponent, StarComponent, StepperComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextTemplatePickerComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildPreviewDocument, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, conversationDateLabel, conversationHtmlToText, conversationInitial, conversationMessageStatusLabel, conversationMessageStatusMark, createFieldReveal, decodeFilterValues, digitsOnly, downloadBlob, emailShareUrl, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, facebookShareUrl, fileMatchesAccept, formatAddress, formatCategoryLabel, formatConversationPhone, formatConversationTime, formatCurrency, formatFileSize, formatIsoDate, formatIsoDateTime, formatMessageTime, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, gmailShareUrl, groupMessagesByDay, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isValidEmailAddress, isWebUrl, isoKey, issueToErrors, linkedInShareUrl, maxLengthIssue, mergeDescribedBy, normalizeHexColor, outlookShareUrl, parseBizHours, parseIso, parseTime, passwordMeetsRules, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, serializedTextLength, setupIntegrations, splitIntro, truncateConversationText, xShareUrl };
52701
53007
 
52702
53008
  //# sourceMappingURL=forgeroute-ui.mjs.map