@runtypelabs/persona 3.18.0 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +47 -47
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +281 -4
  5. package/dist/index.d.ts +281 -4
  6. package/dist/index.global.js +102 -1636
  7. package/dist/index.global.js.map +1 -1
  8. package/dist/index.js +47 -47
  9. package/dist/index.js.map +1 -1
  10. package/dist/theme-editor.cjs +1438 -619
  11. package/dist/theme-editor.d.cts +119 -1
  12. package/dist/theme-editor.d.ts +119 -1
  13. package/dist/theme-editor.js +1552 -619
  14. package/dist/widget.css +348 -0
  15. package/package.json +1 -1
  16. package/src/components/composer-builder.test.ts +52 -0
  17. package/src/components/composer-builder.ts +67 -490
  18. package/src/components/composer-parts.test.ts +152 -0
  19. package/src/components/composer-parts.ts +452 -0
  20. package/src/components/header-builder.ts +22 -299
  21. package/src/components/header-parts.ts +360 -0
  22. package/src/components/panel.test.ts +61 -0
  23. package/src/components/panel.ts +262 -5
  24. package/src/components/pill-composer-builder.test.ts +85 -0
  25. package/src/components/pill-composer-builder.ts +183 -0
  26. package/src/index.ts +4 -0
  27. package/src/runtime/init.ts +4 -2
  28. package/src/runtime/persist-state.test.ts +152 -0
  29. package/src/styles/widget.css +348 -0
  30. package/src/types.ts +121 -1
  31. package/src/ui.component-directive.test.ts +183 -0
  32. package/src/ui.composer-bar.test.ts +1009 -0
  33. package/src/ui.ts +809 -72
  34. package/src/utils/attachment-manager.ts +1 -1
  35. package/src/utils/dock.test.ts +45 -0
  36. package/src/utils/dock.ts +3 -0
  37. package/src/utils/icons.ts +314 -58
  38. package/src/utils/stream-animation.ts +7 -2
@@ -8178,25 +8178,260 @@ var createElementInDocument = (documentRef, tag, className) => {
8178
8178
  };
8179
8179
 
8180
8180
  // src/utils/icons.ts
8181
- import * as icons from "lucide";
8181
+ import {
8182
+ Activity,
8183
+ ArrowDown,
8184
+ ArrowUp,
8185
+ ArrowUpRight,
8186
+ Bot,
8187
+ ChevronDown,
8188
+ ChevronUp,
8189
+ ChevronRight,
8190
+ ChevronLeft,
8191
+ Check,
8192
+ Clipboard,
8193
+ ClipboardCopy,
8194
+ Copy,
8195
+ File as FileIcon,
8196
+ FileCode,
8197
+ FileSpreadsheet,
8198
+ FileText,
8199
+ ImagePlus,
8200
+ Loader,
8201
+ LoaderCircle,
8202
+ Mic,
8203
+ Paperclip,
8204
+ RefreshCw,
8205
+ Search,
8206
+ Send,
8207
+ ShieldAlert,
8208
+ ShieldCheck,
8209
+ ShieldX,
8210
+ Square,
8211
+ ThumbsDown,
8212
+ ThumbsUp,
8213
+ Upload,
8214
+ Volume2,
8215
+ X,
8216
+ User,
8217
+ Mail,
8218
+ Phone,
8219
+ Calendar,
8220
+ Clock,
8221
+ Building,
8222
+ MapPin,
8223
+ Lock,
8224
+ Key,
8225
+ CreditCard,
8226
+ AtSign,
8227
+ Hash,
8228
+ Globe,
8229
+ Link,
8230
+ CircleCheck,
8231
+ CircleX,
8232
+ TriangleAlert,
8233
+ Info,
8234
+ Ban,
8235
+ Shield,
8236
+ ArrowLeft,
8237
+ ArrowRight,
8238
+ ExternalLink,
8239
+ Ellipsis,
8240
+ EllipsisVertical,
8241
+ Menu,
8242
+ House,
8243
+ Plus,
8244
+ Minus,
8245
+ Pencil,
8246
+ Trash,
8247
+ Trash2,
8248
+ Save,
8249
+ Download,
8250
+ Share,
8251
+ Funnel,
8252
+ Settings,
8253
+ RotateCw,
8254
+ Maximize,
8255
+ Minimize,
8256
+ ShoppingCart,
8257
+ ShoppingBag,
8258
+ Package,
8259
+ Truck,
8260
+ Tag,
8261
+ Gift,
8262
+ Receipt,
8263
+ Wallet,
8264
+ Store,
8265
+ DollarSign,
8266
+ Percent,
8267
+ Play,
8268
+ Pause,
8269
+ VolumeX,
8270
+ Camera,
8271
+ Image as ImageIcon,
8272
+ Film,
8273
+ Headphones,
8274
+ MessageCircle,
8275
+ MessageSquare,
8276
+ Bell,
8277
+ Heart,
8278
+ Star,
8279
+ Eye,
8280
+ EyeOff,
8281
+ Bookmark,
8282
+ CalendarDays,
8283
+ History,
8284
+ Timer,
8285
+ Folder,
8286
+ FolderOpen,
8287
+ Files,
8288
+ Sparkles,
8289
+ Zap,
8290
+ Sun,
8291
+ Moon,
8292
+ Flag,
8293
+ Monitor,
8294
+ Smartphone
8295
+ } from "lucide";
8296
+ var LUCIDE_ICONS = {
8297
+ // Mandatory
8298
+ "activity": Activity,
8299
+ "arrow-down": ArrowDown,
8300
+ "arrow-up": ArrowUp,
8301
+ "arrow-up-right": ArrowUpRight,
8302
+ "bot": Bot,
8303
+ "chevron-down": ChevronDown,
8304
+ "chevron-up": ChevronUp,
8305
+ "chevron-right": ChevronRight,
8306
+ "chevron-left": ChevronLeft,
8307
+ "check": Check,
8308
+ "clipboard": Clipboard,
8309
+ "clipboard-copy": ClipboardCopy,
8310
+ "copy": Copy,
8311
+ "file": FileIcon,
8312
+ "file-code": FileCode,
8313
+ "file-spreadsheet": FileSpreadsheet,
8314
+ "file-text": FileText,
8315
+ "image-plus": ImagePlus,
8316
+ "loader": Loader,
8317
+ "loader-circle": LoaderCircle,
8318
+ "mic": Mic,
8319
+ "paperclip": Paperclip,
8320
+ "refresh-cw": RefreshCw,
8321
+ "search": Search,
8322
+ "send": Send,
8323
+ "shield-alert": ShieldAlert,
8324
+ "shield-check": ShieldCheck,
8325
+ "shield-x": ShieldX,
8326
+ "square": Square,
8327
+ "thumbs-down": ThumbsDown,
8328
+ "thumbs-up": ThumbsUp,
8329
+ "upload": Upload,
8330
+ "volume-2": Volume2,
8331
+ "x": X,
8332
+ // Forms / inputs
8333
+ "user": User,
8334
+ "mail": Mail,
8335
+ "phone": Phone,
8336
+ "calendar": Calendar,
8337
+ "clock": Clock,
8338
+ "building": Building,
8339
+ "map-pin": MapPin,
8340
+ "lock": Lock,
8341
+ "key": Key,
8342
+ "credit-card": CreditCard,
8343
+ "at-sign": AtSign,
8344
+ "hash": Hash,
8345
+ "globe": Globe,
8346
+ "link": Link,
8347
+ // Status / feedback
8348
+ "circle-check": CircleCheck,
8349
+ "circle-x": CircleX,
8350
+ "triangle-alert": TriangleAlert,
8351
+ "info": Info,
8352
+ "ban": Ban,
8353
+ "shield": Shield,
8354
+ // Navigation
8355
+ "arrow-left": ArrowLeft,
8356
+ "arrow-right": ArrowRight,
8357
+ "external-link": ExternalLink,
8358
+ "ellipsis": Ellipsis,
8359
+ "ellipsis-vertical": EllipsisVertical,
8360
+ "menu": Menu,
8361
+ "house": House,
8362
+ // Actions
8363
+ "plus": Plus,
8364
+ "minus": Minus,
8365
+ "pencil": Pencil,
8366
+ "trash": Trash,
8367
+ "trash-2": Trash2,
8368
+ "save": Save,
8369
+ "download": Download,
8370
+ "share": Share,
8371
+ "funnel": Funnel,
8372
+ "settings": Settings,
8373
+ "rotate-cw": RotateCw,
8374
+ "maximize": Maximize,
8375
+ "minimize": Minimize,
8376
+ // Commerce
8377
+ "shopping-cart": ShoppingCart,
8378
+ "shopping-bag": ShoppingBag,
8379
+ "package": Package,
8380
+ "truck": Truck,
8381
+ "tag": Tag,
8382
+ "gift": Gift,
8383
+ "receipt": Receipt,
8384
+ "wallet": Wallet,
8385
+ "store": Store,
8386
+ "dollar-sign": DollarSign,
8387
+ "percent": Percent,
8388
+ // Media
8389
+ "play": Play,
8390
+ "pause": Pause,
8391
+ "volume-x": VolumeX,
8392
+ "camera": Camera,
8393
+ "image": ImageIcon,
8394
+ "film": Film,
8395
+ "headphones": Headphones,
8396
+ // Social / Comms
8397
+ "message-circle": MessageCircle,
8398
+ "message-square": MessageSquare,
8399
+ "bell": Bell,
8400
+ "heart": Heart,
8401
+ "star": Star,
8402
+ "eye": Eye,
8403
+ "eye-off": EyeOff,
8404
+ "bookmark": Bookmark,
8405
+ // Time
8406
+ "calendar-days": CalendarDays,
8407
+ "history": History,
8408
+ "timer": Timer,
8409
+ // Files
8410
+ "folder": Folder,
8411
+ "folder-open": FolderOpen,
8412
+ "files": Files,
8413
+ // Decorative
8414
+ "sparkles": Sparkles,
8415
+ "zap": Zap,
8416
+ "sun": Sun,
8417
+ "moon": Moon,
8418
+ "flag": Flag,
8419
+ // Devices
8420
+ "monitor": Monitor,
8421
+ "smartphone": Smartphone
8422
+ };
8182
8423
  var renderLucideIcon = (iconName, size = 24, color = "currentColor", strokeWidth = 2) => {
8183
- try {
8184
- const pascalName = iconName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
8185
- const iconData = icons[pascalName];
8186
- if (!iconData) {
8187
- console.warn(`Lucide icon "${iconName}" not found (tried "${pascalName}"). Available icons: https://lucide.dev/icons`);
8188
- return null;
8189
- }
8190
- return createSvgFromIconData(iconData, size, color, strokeWidth);
8191
- } catch (error) {
8192
- console.warn(`Failed to render Lucide icon "${iconName}":`, error);
8424
+ const iconData = LUCIDE_ICONS[iconName];
8425
+ if (!iconData) {
8426
+ console.warn(
8427
+ `Lucide icon "${iconName}" is not in the Persona registry. Add it to packages/widget/src/utils/icons.ts (see docs/icon-registry-shortlist.md).`
8428
+ );
8193
8429
  return null;
8194
8430
  }
8431
+ return createSvgFromIconData(iconData, size, color, strokeWidth);
8195
8432
  };
8196
8433
  function createSvgFromIconData(iconData, size, color, strokeWidth) {
8197
- if (!iconData || !Array.isArray(iconData)) {
8198
- return null;
8199
- }
8434
+ if (!Array.isArray(iconData)) return null;
8200
8435
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
8201
8436
  svg.setAttribute("width", String(size));
8202
8437
  svg.setAttribute("height", String(size));
@@ -8208,19 +8443,15 @@ function createSvgFromIconData(iconData, size, color, strokeWidth) {
8208
8443
  svg.setAttribute("stroke-linejoin", "round");
8209
8444
  svg.setAttribute("aria-hidden", "true");
8210
8445
  iconData.forEach((elementData) => {
8211
- if (Array.isArray(elementData) && elementData.length >= 2) {
8212
- const tagName = elementData[0];
8213
- const attrs = elementData[1];
8214
- if (attrs) {
8215
- const element = document.createElementNS("http://www.w3.org/2000/svg", tagName);
8216
- Object.entries(attrs).forEach(([key, value]) => {
8217
- if (key !== "stroke") {
8218
- element.setAttribute(key, String(value));
8219
- }
8220
- });
8221
- svg.appendChild(element);
8222
- }
8223
- }
8446
+ if (!Array.isArray(elementData) || elementData.length < 2) return;
8447
+ const tagName = elementData[0];
8448
+ const attrs = elementData[1];
8449
+ if (!attrs) return;
8450
+ const element = document.createElementNS("http://www.w3.org/2000/svg", tagName);
8451
+ Object.entries(attrs).forEach(([key, value]) => {
8452
+ if (key !== "stroke") element.setAttribute(key, String(value));
8453
+ });
8454
+ svg.appendChild(element);
8224
8455
  });
8225
8456
  return svg;
8226
8457
  }
@@ -8240,7 +8471,7 @@ function getFileIconName(mimeType) {
8240
8471
  if (mimeType.startsWith("text/")) return "file-text";
8241
8472
  if (mimeType.includes("word")) return "file-text";
8242
8473
  if (mimeType.includes("excel") || mimeType.includes("spreadsheet")) return "file-spreadsheet";
8243
- if (mimeType === "application/json") return "file-json";
8474
+ if (mimeType === "application/json") return "file-code";
8244
8475
  return "file";
8245
8476
  }
8246
8477
  var AttachmentManager = class _AttachmentManager {
@@ -8802,7 +9033,7 @@ var wrapTextNodeWords = (textNode, messageId, counterRef) => {
8802
9033
  parent.replaceChild(fragment, textNode);
8803
9034
  };
8804
9035
  var wrapStreamAnimation = (html, mode, messageId, options) => {
8805
- var _a;
9036
+ var _a, _b;
8806
9037
  if (!html) return html;
8807
9038
  if (typeof document === "undefined") return html;
8808
9039
  const scratch = document.createElement("div");
@@ -8817,7 +9048,7 @@ var wrapStreamAnimation = (html, mode, messageId, options) => {
8817
9048
  }
8818
9049
  node = walker.nextNode();
8819
9050
  }
8820
- const counterRef = { value: 0 };
9051
+ const counterRef = { value: (_b = options == null ? void 0 : options.startIndex) != null ? _b : 0 };
8821
9052
  const wrap = mode === "char" ? wrapTextNodeChars : wrapTextNodeWords;
8822
9053
  for (const textNode of textNodes) {
8823
9054
  wrap(textNode, messageId, counterRef);
@@ -8963,6 +9194,10 @@ var isDockedMountMode = (config) => {
8963
9194
  var _a, _b;
8964
9195
  return ((_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.mountMode) != null ? _b : "floating") === "docked";
8965
9196
  };
9197
+ var isComposerBarMountMode = (config) => {
9198
+ var _a, _b;
9199
+ return ((_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.mountMode) != null ? _b : "floating") === "composer-bar";
9200
+ };
8966
9201
  var resolveDockConfig = (config) => {
8967
9202
  var _a, _b, _c, _d, _e;
8968
9203
  const dock = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.dock;
@@ -9149,6 +9384,226 @@ var createLauncherButton = (config, onToggle) => {
9149
9384
  };
9150
9385
  };
9151
9386
 
9387
+ // src/components/header-parts.ts
9388
+ var DEFAULT_WRAPPER_CLASS = "persona-relative persona-ml-auto persona-inline-flex persona-items-center persona-justify-center";
9389
+ var createCloseButton = (config, options = {}) => {
9390
+ var _a, _b, _c, _d, _e, _f;
9391
+ const {
9392
+ showClose = true,
9393
+ wrapperClassName = DEFAULT_WRAPPER_CLASS,
9394
+ buttonSize,
9395
+ iconSize = "28px"
9396
+ } = options;
9397
+ const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9398
+ const closeButtonSize = (_b = buttonSize != null ? buttonSize : launcher.closeButtonSize) != null ? _b : "32px";
9399
+ const wrapper = createElement("div", wrapperClassName);
9400
+ const button = createElement(
9401
+ "button",
9402
+ "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9403
+ );
9404
+ button.style.height = closeButtonSize;
9405
+ button.style.width = closeButtonSize;
9406
+ button.type = "button";
9407
+ const closeButtonTooltipText = (_c = launcher.closeButtonTooltipText) != null ? _c : "Close chat";
9408
+ const closeButtonShowTooltip = (_d = launcher.closeButtonShowTooltip) != null ? _d : true;
9409
+ button.setAttribute("aria-label", closeButtonTooltipText);
9410
+ button.style.display = showClose ? "" : "none";
9411
+ const closeButtonIconName = (_e = launcher.closeButtonIconName) != null ? _e : "x";
9412
+ const closeButtonIconText = (_f = launcher.closeButtonIconText) != null ? _f : "\xD7";
9413
+ button.style.color = launcher.closeButtonColor || HEADER_THEME_CSS.actionIconColor;
9414
+ const closeIconSvg = renderLucideIcon(closeButtonIconName, iconSize, "currentColor", 1);
9415
+ if (closeIconSvg) {
9416
+ closeIconSvg.style.display = "block";
9417
+ button.appendChild(closeIconSvg);
9418
+ } else {
9419
+ button.textContent = closeButtonIconText;
9420
+ }
9421
+ if (launcher.closeButtonBackgroundColor) {
9422
+ button.style.backgroundColor = launcher.closeButtonBackgroundColor;
9423
+ button.classList.remove("hover:persona-bg-gray-100");
9424
+ } else {
9425
+ button.style.backgroundColor = "";
9426
+ button.classList.add("hover:persona-bg-gray-100");
9427
+ }
9428
+ if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {
9429
+ const borderWidth = launcher.closeButtonBorderWidth || "0px";
9430
+ const borderColor = launcher.closeButtonBorderColor || "transparent";
9431
+ button.style.border = `${borderWidth} solid ${borderColor}`;
9432
+ button.classList.remove("persona-border-none");
9433
+ } else {
9434
+ button.style.border = "";
9435
+ button.classList.add("persona-border-none");
9436
+ }
9437
+ if (launcher.closeButtonBorderRadius) {
9438
+ button.style.borderRadius = launcher.closeButtonBorderRadius;
9439
+ button.classList.remove("persona-rounded-full");
9440
+ } else {
9441
+ button.style.borderRadius = "";
9442
+ button.classList.add("persona-rounded-full");
9443
+ }
9444
+ if (launcher.closeButtonPaddingX) {
9445
+ button.style.paddingLeft = launcher.closeButtonPaddingX;
9446
+ button.style.paddingRight = launcher.closeButtonPaddingX;
9447
+ } else {
9448
+ button.style.paddingLeft = "";
9449
+ button.style.paddingRight = "";
9450
+ }
9451
+ if (launcher.closeButtonPaddingY) {
9452
+ button.style.paddingTop = launcher.closeButtonPaddingY;
9453
+ button.style.paddingBottom = launcher.closeButtonPaddingY;
9454
+ } else {
9455
+ button.style.paddingTop = "";
9456
+ button.style.paddingBottom = "";
9457
+ }
9458
+ wrapper.appendChild(button);
9459
+ if (closeButtonShowTooltip && closeButtonTooltipText) {
9460
+ let portaledTooltip = null;
9461
+ const showTooltip = () => {
9462
+ if (portaledTooltip) return;
9463
+ const tooltipDocument = button.ownerDocument;
9464
+ const tooltipContainer = tooltipDocument.body;
9465
+ if (!tooltipContainer) return;
9466
+ portaledTooltip = createElementInDocument(
9467
+ tooltipDocument,
9468
+ "div",
9469
+ "persona-clear-chat-tooltip"
9470
+ );
9471
+ portaledTooltip.textContent = closeButtonTooltipText;
9472
+ const arrow = createElementInDocument(tooltipDocument, "div");
9473
+ arrow.className = "persona-clear-chat-tooltip-arrow";
9474
+ portaledTooltip.appendChild(arrow);
9475
+ const buttonRect = button.getBoundingClientRect();
9476
+ portaledTooltip.style.position = "fixed";
9477
+ portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9478
+ portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9479
+ portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9480
+ portaledTooltip.style.transform = "translate(-50%, -100%)";
9481
+ tooltipContainer.appendChild(portaledTooltip);
9482
+ };
9483
+ const hideTooltip = () => {
9484
+ if (portaledTooltip && portaledTooltip.parentNode) {
9485
+ portaledTooltip.parentNode.removeChild(portaledTooltip);
9486
+ portaledTooltip = null;
9487
+ }
9488
+ };
9489
+ wrapper.addEventListener("mouseenter", showTooltip);
9490
+ wrapper.addEventListener("mouseleave", hideTooltip);
9491
+ button.addEventListener("focus", showTooltip);
9492
+ button.addEventListener("blur", hideTooltip);
9493
+ wrapper._cleanupTooltip = () => {
9494
+ hideTooltip();
9495
+ wrapper.removeEventListener("mouseenter", showTooltip);
9496
+ wrapper.removeEventListener("mouseleave", hideTooltip);
9497
+ button.removeEventListener("focus", showTooltip);
9498
+ button.removeEventListener("blur", hideTooltip);
9499
+ };
9500
+ }
9501
+ return { button, wrapper };
9502
+ };
9503
+ var DEFAULT_CLEAR_CHAT_WRAPPER_CLASS = "persona-relative persona-ml-auto persona-clear-chat-button-wrapper";
9504
+ var createClearChatButton = (config, options = {}) => {
9505
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
9506
+ const {
9507
+ wrapperClassName = DEFAULT_CLEAR_CHAT_WRAPPER_CLASS,
9508
+ buttonSize,
9509
+ iconSize = "20px"
9510
+ } = options;
9511
+ const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9512
+ const clearChatConfig = (_b = launcher.clearChat) != null ? _b : {};
9513
+ const clearChatSize = (_c = buttonSize != null ? buttonSize : clearChatConfig.size) != null ? _c : "32px";
9514
+ const clearChatIconName = (_d = clearChatConfig.iconName) != null ? _d : "refresh-cw";
9515
+ const clearChatIconColor = (_e = clearChatConfig.iconColor) != null ? _e : "";
9516
+ const clearChatBgColor = (_f = clearChatConfig.backgroundColor) != null ? _f : "";
9517
+ const clearChatBorderWidth = (_g = clearChatConfig.borderWidth) != null ? _g : "";
9518
+ const clearChatBorderColor = (_h = clearChatConfig.borderColor) != null ? _h : "";
9519
+ const clearChatBorderRadius = (_i = clearChatConfig.borderRadius) != null ? _i : "";
9520
+ const clearChatPaddingX = (_j = clearChatConfig.paddingX) != null ? _j : "";
9521
+ const clearChatPaddingY = (_k = clearChatConfig.paddingY) != null ? _k : "";
9522
+ const clearChatTooltipText = (_l = clearChatConfig.tooltipText) != null ? _l : "Clear chat";
9523
+ const clearChatShowTooltip = (_m = clearChatConfig.showTooltip) != null ? _m : true;
9524
+ const wrapper = createElement("div", wrapperClassName);
9525
+ const button = createElement(
9526
+ "button",
9527
+ "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9528
+ );
9529
+ button.style.height = clearChatSize;
9530
+ button.style.width = clearChatSize;
9531
+ button.type = "button";
9532
+ button.setAttribute("aria-label", clearChatTooltipText);
9533
+ button.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
9534
+ const iconSvg = renderLucideIcon(clearChatIconName, iconSize, "currentColor", 1);
9535
+ if (iconSvg) {
9536
+ iconSvg.style.display = "block";
9537
+ button.appendChild(iconSvg);
9538
+ }
9539
+ if (clearChatBgColor) {
9540
+ button.style.backgroundColor = clearChatBgColor;
9541
+ button.classList.remove("hover:persona-bg-gray-100");
9542
+ }
9543
+ if (clearChatBorderWidth || clearChatBorderColor) {
9544
+ const borderWidth = clearChatBorderWidth || "0px";
9545
+ const borderColor = clearChatBorderColor || "transparent";
9546
+ button.style.border = `${borderWidth} solid ${borderColor}`;
9547
+ button.classList.remove("persona-border-none");
9548
+ }
9549
+ if (clearChatBorderRadius) {
9550
+ button.style.borderRadius = clearChatBorderRadius;
9551
+ button.classList.remove("persona-rounded-full");
9552
+ }
9553
+ if (clearChatPaddingX) {
9554
+ button.style.paddingLeft = clearChatPaddingX;
9555
+ button.style.paddingRight = clearChatPaddingX;
9556
+ }
9557
+ if (clearChatPaddingY) {
9558
+ button.style.paddingTop = clearChatPaddingY;
9559
+ button.style.paddingBottom = clearChatPaddingY;
9560
+ }
9561
+ wrapper.appendChild(button);
9562
+ if (clearChatShowTooltip && clearChatTooltipText) {
9563
+ let portaledTooltip = null;
9564
+ const showTooltip = () => {
9565
+ if (portaledTooltip) return;
9566
+ const tooltipDocument = button.ownerDocument;
9567
+ const tooltipContainer = tooltipDocument.body;
9568
+ if (!tooltipContainer) return;
9569
+ portaledTooltip = createElementInDocument(
9570
+ tooltipDocument,
9571
+ "div",
9572
+ "persona-clear-chat-tooltip"
9573
+ );
9574
+ portaledTooltip.textContent = clearChatTooltipText;
9575
+ const arrow = createElementInDocument(tooltipDocument, "div");
9576
+ arrow.className = "persona-clear-chat-tooltip-arrow";
9577
+ portaledTooltip.appendChild(arrow);
9578
+ const buttonRect = button.getBoundingClientRect();
9579
+ portaledTooltip.style.position = "fixed";
9580
+ portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9581
+ portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9582
+ portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9583
+ portaledTooltip.style.transform = "translate(-50%, -100%)";
9584
+ tooltipContainer.appendChild(portaledTooltip);
9585
+ };
9586
+ const hideTooltip = () => {
9587
+ if (portaledTooltip && portaledTooltip.parentNode) {
9588
+ portaledTooltip.parentNode.removeChild(portaledTooltip);
9589
+ portaledTooltip = null;
9590
+ }
9591
+ };
9592
+ wrapper.addEventListener("mouseenter", showTooltip);
9593
+ wrapper.addEventListener("mouseleave", hideTooltip);
9594
+ button.addEventListener("focus", showTooltip);
9595
+ button.addEventListener("blur", hideTooltip);
9596
+ wrapper._cleanupTooltip = () => {
9597
+ hideTooltip();
9598
+ wrapper.removeEventListener("mouseenter", showTooltip);
9599
+ wrapper.removeEventListener("mouseleave", hideTooltip);
9600
+ button.removeEventListener("focus", showTooltip);
9601
+ button.removeEventListener("blur", hideTooltip);
9602
+ };
9603
+ }
9604
+ return { button, wrapper };
9605
+ };
9606
+
9152
9607
  // src/components/header-builder.ts
9153
9608
  var HEADER_THEME_CSS = {
9154
9609
  titleColor: "var(--persona-header-title-fg, var(--persona-primary, #0f0f0f))",
@@ -9156,7 +9611,7 @@ var HEADER_THEME_CSS = {
9156
9611
  actionIconColor: "var(--persona-header-action-icon-fg, var(--persona-muted, #9ca3af))"
9157
9612
  };
9158
9613
  var buildHeader = (context) => {
9159
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F;
9614
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
9160
9615
  const { config, showClose = true } = context;
9161
9616
  const header = createElement(
9162
9617
  "div",
@@ -9169,9 +9624,8 @@ var buildHeader = (context) => {
9169
9624
  header.style.borderBottom = "var(--persona-header-border-bottom, 1px solid var(--persona-header-border, var(--persona-divider, #f1f5f9)))";
9170
9625
  const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9171
9626
  const headerIconSize = (_b = launcher.headerIconSize) != null ? _b : "48px";
9172
- const closeButtonSize = (_c = launcher.closeButtonSize) != null ? _c : "32px";
9173
- const closeButtonPlacement = (_d = launcher.closeButtonPlacement) != null ? _d : "inline";
9174
- const headerIconHidden = (_e = launcher.headerIconHidden) != null ? _e : false;
9627
+ const closeButtonPlacement = (_c = launcher.closeButtonPlacement) != null ? _c : "inline";
9628
+ const headerIconHidden = (_d = launcher.headerIconHidden) != null ? _d : false;
9175
9629
  const headerIconName = launcher.headerIconName;
9176
9630
  const iconHolder = createElement(
9177
9631
  "div",
@@ -9188,9 +9642,9 @@ var buildHeader = (context) => {
9188
9642
  if (iconSvg) {
9189
9643
  iconHolder.replaceChildren(iconSvg);
9190
9644
  } else {
9191
- iconHolder.textContent = (_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.agentIconText) != null ? _g : "\u{1F4AC}";
9645
+ iconHolder.textContent = (_f = (_e = config == null ? void 0 : config.launcher) == null ? void 0 : _e.agentIconText) != null ? _f : "\u{1F4AC}";
9192
9646
  }
9193
- } else if ((_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.iconUrl) {
9647
+ } else if ((_g = config == null ? void 0 : config.launcher) == null ? void 0 : _g.iconUrl) {
9194
9648
  const img = createElement("img");
9195
9649
  img.src = config.launcher.iconUrl;
9196
9650
  img.alt = "";
@@ -9199,244 +9653,44 @@ var buildHeader = (context) => {
9199
9653
  img.style.width = headerIconSize;
9200
9654
  iconHolder.replaceChildren(img);
9201
9655
  } else {
9202
- iconHolder.textContent = (_j = (_i = config == null ? void 0 : config.launcher) == null ? void 0 : _i.agentIconText) != null ? _j : "\u{1F4AC}";
9656
+ iconHolder.textContent = (_i = (_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.agentIconText) != null ? _i : "\u{1F4AC}";
9203
9657
  }
9204
9658
  }
9205
9659
  const headerCopy = createElement("div", "persona-flex persona-flex-col persona-flex-1 persona-min-w-0");
9206
9660
  const title = createElement("span", "persona-text-base persona-font-semibold");
9207
9661
  title.style.color = HEADER_THEME_CSS.titleColor;
9208
- title.textContent = (_l = (_k = config == null ? void 0 : config.launcher) == null ? void 0 : _k.title) != null ? _l : "Chat Assistant";
9662
+ title.textContent = (_k = (_j = config == null ? void 0 : config.launcher) == null ? void 0 : _j.title) != null ? _k : "Chat Assistant";
9209
9663
  const subtitle = createElement("span", "persona-text-xs");
9210
9664
  subtitle.style.color = HEADER_THEME_CSS.subtitleColor;
9211
- subtitle.textContent = (_n = (_m = config == null ? void 0 : config.launcher) == null ? void 0 : _m.subtitle) != null ? _n : "Here to help you get answers fast";
9665
+ subtitle.textContent = (_m = (_l = config == null ? void 0 : config.launcher) == null ? void 0 : _l.subtitle) != null ? _m : "Here to help you get answers fast";
9212
9666
  headerCopy.append(title, subtitle);
9213
9667
  if (!headerIconHidden) {
9214
9668
  header.append(iconHolder, headerCopy);
9215
9669
  } else {
9216
9670
  header.append(headerCopy);
9217
9671
  }
9218
- const clearChatConfig = (_o = launcher.clearChat) != null ? _o : {};
9219
- const clearChatEnabled = (_p = clearChatConfig.enabled) != null ? _p : true;
9220
- const clearChatPlacement = (_q = clearChatConfig.placement) != null ? _q : "inline";
9672
+ const clearChatConfig = (_n = launcher.clearChat) != null ? _n : {};
9673
+ const clearChatEnabled = (_o = clearChatConfig.enabled) != null ? _o : true;
9674
+ const clearChatPlacement = (_p = clearChatConfig.placement) != null ? _p : "inline";
9221
9675
  let clearChatButton = null;
9222
9676
  let clearChatButtonWrapper = null;
9223
9677
  if (clearChatEnabled) {
9224
- const clearChatSize = (_r = clearChatConfig.size) != null ? _r : "32px";
9225
- const clearChatIconName = (_s = clearChatConfig.iconName) != null ? _s : "refresh-cw";
9226
- const clearChatIconColor = (_t = clearChatConfig.iconColor) != null ? _t : "";
9227
- const clearChatBgColor = (_u = clearChatConfig.backgroundColor) != null ? _u : "";
9228
- const clearChatBorderWidth = (_v = clearChatConfig.borderWidth) != null ? _v : "";
9229
- const clearChatBorderColor = (_w = clearChatConfig.borderColor) != null ? _w : "";
9230
- const clearChatBorderRadius = (_x = clearChatConfig.borderRadius) != null ? _x : "";
9231
- const clearChatPaddingX = (_y = clearChatConfig.paddingX) != null ? _y : "";
9232
- const clearChatPaddingY = (_z = clearChatConfig.paddingY) != null ? _z : "";
9233
- const clearChatTooltipText = (_A = clearChatConfig.tooltipText) != null ? _A : "Clear chat";
9234
- const clearChatShowTooltip = (_B = clearChatConfig.showTooltip) != null ? _B : true;
9235
- clearChatButtonWrapper = createElement(
9236
- "div",
9237
- clearChatPlacement === "top-right" ? "persona-absolute persona-top-4 persona-z-50" : "persona-relative persona-ml-auto persona-clear-chat-button-wrapper"
9238
- );
9678
+ const wrapperClassName = clearChatPlacement === "top-right" ? "persona-absolute persona-top-4 persona-z-50" : "persona-relative persona-ml-auto persona-clear-chat-button-wrapper";
9679
+ const parts = createClearChatButton(config, { wrapperClassName });
9680
+ clearChatButton = parts.button;
9681
+ clearChatButtonWrapper = parts.wrapper;
9239
9682
  if (clearChatPlacement === "top-right") {
9240
9683
  clearChatButtonWrapper.style.right = "48px";
9241
9684
  }
9242
- clearChatButton = createElement(
9243
- "button",
9244
- "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9245
- );
9246
- clearChatButton.style.height = clearChatSize;
9247
- clearChatButton.style.width = clearChatSize;
9248
- clearChatButton.type = "button";
9249
- clearChatButton.setAttribute("aria-label", clearChatTooltipText);
9250
- clearChatButton.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
9251
- const iconSvg = renderLucideIcon(clearChatIconName, "20px", "currentColor", 1);
9252
- if (iconSvg) {
9253
- iconSvg.style.display = "block";
9254
- clearChatButton.appendChild(iconSvg);
9255
- }
9256
- if (clearChatBgColor) {
9257
- clearChatButton.style.backgroundColor = clearChatBgColor;
9258
- clearChatButton.classList.remove("hover:persona-bg-gray-100");
9259
- }
9260
- if (clearChatBorderWidth || clearChatBorderColor) {
9261
- const borderWidth = clearChatBorderWidth || "0px";
9262
- const borderColor = clearChatBorderColor || "transparent";
9263
- clearChatButton.style.border = `${borderWidth} solid ${borderColor}`;
9264
- clearChatButton.classList.remove("persona-border-none");
9265
- }
9266
- if (clearChatBorderRadius) {
9267
- clearChatButton.style.borderRadius = clearChatBorderRadius;
9268
- clearChatButton.classList.remove("persona-rounded-full");
9269
- }
9270
- if (clearChatPaddingX) {
9271
- clearChatButton.style.paddingLeft = clearChatPaddingX;
9272
- clearChatButton.style.paddingRight = clearChatPaddingX;
9273
- } else {
9274
- clearChatButton.style.paddingLeft = "";
9275
- clearChatButton.style.paddingRight = "";
9276
- }
9277
- if (clearChatPaddingY) {
9278
- clearChatButton.style.paddingTop = clearChatPaddingY;
9279
- clearChatButton.style.paddingBottom = clearChatPaddingY;
9280
- } else {
9281
- clearChatButton.style.paddingTop = "";
9282
- clearChatButton.style.paddingBottom = "";
9283
- }
9284
- clearChatButtonWrapper.appendChild(clearChatButton);
9285
- if (clearChatShowTooltip && clearChatTooltipText && clearChatButton && clearChatButtonWrapper) {
9286
- let portaledTooltip = null;
9287
- const showTooltip = () => {
9288
- if (portaledTooltip || !clearChatButton) return;
9289
- const tooltipDocument = clearChatButton.ownerDocument;
9290
- const tooltipContainer = tooltipDocument.body;
9291
- if (!tooltipContainer) return;
9292
- portaledTooltip = createElementInDocument(
9293
- tooltipDocument,
9294
- "div",
9295
- "persona-clear-chat-tooltip"
9296
- );
9297
- portaledTooltip.textContent = clearChatTooltipText;
9298
- const arrow = createElementInDocument(tooltipDocument, "div");
9299
- arrow.className = "persona-clear-chat-tooltip-arrow";
9300
- portaledTooltip.appendChild(arrow);
9301
- const buttonRect = clearChatButton.getBoundingClientRect();
9302
- portaledTooltip.style.position = "fixed";
9303
- portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9304
- portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9305
- portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9306
- portaledTooltip.style.transform = "translate(-50%, -100%)";
9307
- tooltipContainer.appendChild(portaledTooltip);
9308
- };
9309
- const hideTooltip = () => {
9310
- if (portaledTooltip && portaledTooltip.parentNode) {
9311
- portaledTooltip.parentNode.removeChild(portaledTooltip);
9312
- portaledTooltip = null;
9313
- }
9314
- };
9315
- clearChatButtonWrapper.addEventListener("mouseenter", showTooltip);
9316
- clearChatButtonWrapper.addEventListener("mouseleave", hideTooltip);
9317
- clearChatButton.addEventListener("focus", showTooltip);
9318
- clearChatButton.addEventListener("blur", hideTooltip);
9319
- clearChatButtonWrapper._cleanupTooltip = () => {
9320
- hideTooltip();
9321
- if (clearChatButtonWrapper) {
9322
- clearChatButtonWrapper.removeEventListener("mouseenter", showTooltip);
9323
- clearChatButtonWrapper.removeEventListener("mouseleave", hideTooltip);
9324
- }
9325
- if (clearChatButton) {
9326
- clearChatButton.removeEventListener("focus", showTooltip);
9327
- clearChatButton.removeEventListener("blur", hideTooltip);
9328
- }
9329
- };
9330
- }
9331
9685
  if (clearChatPlacement === "inline") {
9332
9686
  header.appendChild(clearChatButtonWrapper);
9333
9687
  }
9334
9688
  }
9335
- const closeButtonWrapper = createElement(
9336
- "div",
9337
- closeButtonPlacement === "top-right" ? "persona-absolute persona-top-4 persona-right-4 persona-z-50" : clearChatEnabled && clearChatPlacement === "inline" ? "persona-relative persona-inline-flex persona-items-center persona-justify-center" : "persona-relative persona-ml-auto persona-inline-flex persona-items-center persona-justify-center"
9338
- );
9339
- const closeButton = createElement(
9340
- "button",
9341
- "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9689
+ const closeButtonWrapperClass = closeButtonPlacement === "top-right" ? "persona-absolute persona-top-4 persona-right-4 persona-z-50" : clearChatEnabled && clearChatPlacement === "inline" ? "persona-relative persona-inline-flex persona-items-center persona-justify-center" : "persona-relative persona-ml-auto persona-inline-flex persona-items-center persona-justify-center";
9690
+ const { button: closeButton, wrapper: closeButtonWrapper } = createCloseButton(
9691
+ config,
9692
+ { showClose, wrapperClassName: closeButtonWrapperClass }
9342
9693
  );
9343
- closeButton.style.height = closeButtonSize;
9344
- closeButton.style.width = closeButtonSize;
9345
- closeButton.type = "button";
9346
- const closeButtonTooltipText = (_C = launcher.closeButtonTooltipText) != null ? _C : "Close chat";
9347
- const closeButtonShowTooltip = (_D = launcher.closeButtonShowTooltip) != null ? _D : true;
9348
- closeButton.setAttribute("aria-label", closeButtonTooltipText);
9349
- closeButton.style.display = showClose ? "" : "none";
9350
- const closeButtonIconName = (_E = launcher.closeButtonIconName) != null ? _E : "x";
9351
- const closeButtonIconText = (_F = launcher.closeButtonIconText) != null ? _F : "\xD7";
9352
- closeButton.style.color = launcher.closeButtonColor || HEADER_THEME_CSS.actionIconColor;
9353
- const closeIconSvg = renderLucideIcon(closeButtonIconName, "28px", "currentColor", 1);
9354
- if (closeIconSvg) {
9355
- closeIconSvg.style.display = "block";
9356
- closeButton.appendChild(closeIconSvg);
9357
- } else {
9358
- closeButton.textContent = closeButtonIconText;
9359
- }
9360
- if (launcher.closeButtonBackgroundColor) {
9361
- closeButton.style.backgroundColor = launcher.closeButtonBackgroundColor;
9362
- closeButton.classList.remove("hover:persona-bg-gray-100");
9363
- } else {
9364
- closeButton.style.backgroundColor = "";
9365
- closeButton.classList.add("hover:persona-bg-gray-100");
9366
- }
9367
- if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {
9368
- const borderWidth = launcher.closeButtonBorderWidth || "0px";
9369
- const borderColor = launcher.closeButtonBorderColor || "transparent";
9370
- closeButton.style.border = `${borderWidth} solid ${borderColor}`;
9371
- closeButton.classList.remove("persona-border-none");
9372
- } else {
9373
- closeButton.style.border = "";
9374
- closeButton.classList.add("persona-border-none");
9375
- }
9376
- if (launcher.closeButtonBorderRadius) {
9377
- closeButton.style.borderRadius = launcher.closeButtonBorderRadius;
9378
- closeButton.classList.remove("persona-rounded-full");
9379
- } else {
9380
- closeButton.style.borderRadius = "";
9381
- closeButton.classList.add("persona-rounded-full");
9382
- }
9383
- if (launcher.closeButtonPaddingX) {
9384
- closeButton.style.paddingLeft = launcher.closeButtonPaddingX;
9385
- closeButton.style.paddingRight = launcher.closeButtonPaddingX;
9386
- } else {
9387
- closeButton.style.paddingLeft = "";
9388
- closeButton.style.paddingRight = "";
9389
- }
9390
- if (launcher.closeButtonPaddingY) {
9391
- closeButton.style.paddingTop = launcher.closeButtonPaddingY;
9392
- closeButton.style.paddingBottom = launcher.closeButtonPaddingY;
9393
- } else {
9394
- closeButton.style.paddingTop = "";
9395
- closeButton.style.paddingBottom = "";
9396
- }
9397
- closeButtonWrapper.appendChild(closeButton);
9398
- if (closeButtonShowTooltip && closeButtonTooltipText) {
9399
- let portaledTooltip = null;
9400
- const showTooltip = () => {
9401
- if (portaledTooltip) return;
9402
- const tooltipDocument = closeButton.ownerDocument;
9403
- const tooltipContainer = tooltipDocument.body;
9404
- if (!tooltipContainer) return;
9405
- portaledTooltip = createElementInDocument(
9406
- tooltipDocument,
9407
- "div",
9408
- "persona-clear-chat-tooltip"
9409
- );
9410
- portaledTooltip.textContent = closeButtonTooltipText;
9411
- const arrow = createElementInDocument(tooltipDocument, "div");
9412
- arrow.className = "persona-clear-chat-tooltip-arrow";
9413
- portaledTooltip.appendChild(arrow);
9414
- const buttonRect = closeButton.getBoundingClientRect();
9415
- portaledTooltip.style.position = "fixed";
9416
- portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9417
- portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9418
- portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9419
- portaledTooltip.style.transform = "translate(-50%, -100%)";
9420
- tooltipContainer.appendChild(portaledTooltip);
9421
- };
9422
- const hideTooltip = () => {
9423
- if (portaledTooltip && portaledTooltip.parentNode) {
9424
- portaledTooltip.parentNode.removeChild(portaledTooltip);
9425
- portaledTooltip = null;
9426
- }
9427
- };
9428
- closeButtonWrapper.addEventListener("mouseenter", showTooltip);
9429
- closeButtonWrapper.addEventListener("mouseleave", hideTooltip);
9430
- closeButton.addEventListener("focus", showTooltip);
9431
- closeButton.addEventListener("blur", hideTooltip);
9432
- closeButtonWrapper._cleanupTooltip = () => {
9433
- hideTooltip();
9434
- closeButtonWrapper.removeEventListener("mouseenter", showTooltip);
9435
- closeButtonWrapper.removeEventListener("mouseleave", hideTooltip);
9436
- closeButton.removeEventListener("focus", showTooltip);
9437
- closeButton.removeEventListener("blur", hideTooltip);
9438
- };
9439
- }
9440
9694
  if (closeButtonPlacement !== "top-right") {
9441
9695
  header.appendChild(closeButtonWrapper);
9442
9696
  }
@@ -9973,25 +10227,9 @@ var buildHeaderWithLayout = (config, layoutConfig, context) => {
9973
10227
  return headerElements;
9974
10228
  };
9975
10229
 
9976
- // src/components/composer-builder.ts
9977
- var buildComposer = (context) => {
9978
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E;
9979
- const { config } = context;
9980
- const footer = createElement(
9981
- "div",
9982
- "persona-widget-footer persona-border-t-persona-divider persona-bg-persona-surface persona-px-6 persona-py-4"
9983
- );
9984
- footer.setAttribute("data-persona-theme-zone", "composer");
9985
- const suggestions = createElement(
9986
- "div",
9987
- "persona-mb-3 persona-flex persona-flex-wrap persona-gap-2"
9988
- );
9989
- const composerForm = createElement(
9990
- "form",
9991
- `persona-widget-composer persona-flex persona-flex-col persona-gap-2 persona-rounded-2xl persona-border persona-border-gray-200 persona-bg-persona-input-background persona-px-4 persona-py-3`
9992
- );
9993
- composerForm.setAttribute("data-persona-composer-form", "");
9994
- composerForm.style.outline = "none";
10230
+ // src/components/composer-parts.ts
10231
+ var createComposerTextarea = (config) => {
10232
+ var _a, _b;
9995
10233
  const textarea = createElement("textarea");
9996
10234
  textarea.setAttribute("data-persona-composer-input", "");
9997
10235
  textarea.placeholder = (_b = (_a = config == null ? void 0 : config.copy) == null ? void 0 : _a.inputPlaceholder) != null ? _b : "Type your message\u2026";
@@ -9999,17 +10237,21 @@ var buildComposer = (context) => {
9999
10237
  textarea.rows = 1;
10000
10238
  textarea.style.fontFamily = 'var(--persona-input-font-family, var(--persona-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif))';
10001
10239
  textarea.style.fontWeight = "var(--persona-input-font-weight, var(--persona-font-weight, 400))";
10002
- const maxLines = 3;
10240
+ const defaultMaxLines = 3;
10003
10241
  const lineHeight = 20;
10004
- const maxHeight = maxLines * lineHeight;
10005
- textarea.style.maxHeight = `${maxHeight}px`;
10242
+ textarea.style.maxHeight = `${defaultMaxLines * lineHeight}px`;
10006
10243
  textarea.style.overflowY = "auto";
10007
- const autoResize = () => {
10008
- textarea.style.height = "auto";
10009
- const newHeight = Math.min(textarea.scrollHeight, maxHeight);
10010
- textarea.style.height = `${newHeight}px`;
10244
+ const readMaxHeight = () => {
10245
+ const parsed = parseFloat(textarea.style.maxHeight);
10246
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultMaxLines * lineHeight;
10247
+ };
10248
+ const attachAutoResize = () => {
10249
+ textarea.addEventListener("input", () => {
10250
+ textarea.style.height = "auto";
10251
+ const newHeight = Math.min(textarea.scrollHeight, readMaxHeight());
10252
+ textarea.style.height = `${newHeight}px`;
10253
+ });
10011
10254
  };
10012
- textarea.addEventListener("input", autoResize);
10013
10255
  textarea.style.border = "none";
10014
10256
  textarea.style.outline = "none";
10015
10257
  textarea.style.borderWidth = "0";
@@ -10027,333 +10269,474 @@ var buildComposer = (context) => {
10027
10269
  textarea.style.border = "none";
10028
10270
  textarea.style.outline = "none";
10029
10271
  });
10030
- const sendButtonConfig = (_c = config == null ? void 0 : config.sendButton) != null ? _c : {};
10031
- const useIcon = (_d = sendButtonConfig.useIcon) != null ? _d : false;
10032
- const iconText = (_e = sendButtonConfig.iconText) != null ? _e : "\u2191";
10272
+ return { textarea, attachAutoResize };
10273
+ };
10274
+ var createSendButton = (config) => {
10275
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
10276
+ const sendButtonConfig = (_a = config == null ? void 0 : config.sendButton) != null ? _a : {};
10277
+ const useIcon = (_b = sendButtonConfig.useIcon) != null ? _b : false;
10278
+ const iconText = (_c = sendButtonConfig.iconText) != null ? _c : "\u2191";
10033
10279
  const iconName = sendButtonConfig.iconName;
10034
- const stopIconName = (_f = sendButtonConfig.stopIconName) != null ? _f : "square";
10035
- const tooltipText = (_g = sendButtonConfig.tooltipText) != null ? _g : "Send message";
10036
- const stopTooltipText = (_h = sendButtonConfig.stopTooltipText) != null ? _h : "Stop generating";
10037
- const sendLabel = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.sendButtonLabel) != null ? _j : "Send";
10038
- const stopLabel = (_l = (_k = config == null ? void 0 : config.copy) == null ? void 0 : _k.stopButtonLabel) != null ? _l : "Stop";
10039
- const showTooltip = (_m = sendButtonConfig.showTooltip) != null ? _m : false;
10040
- const buttonSize = (_n = sendButtonConfig.size) != null ? _n : "40px";
10280
+ const stopIconName = (_d = sendButtonConfig.stopIconName) != null ? _d : "square";
10281
+ const tooltipText = (_e = sendButtonConfig.tooltipText) != null ? _e : "Send message";
10282
+ const stopTooltipText = (_f = sendButtonConfig.stopTooltipText) != null ? _f : "Stop generating";
10283
+ const sendLabel = (_h = (_g = config == null ? void 0 : config.copy) == null ? void 0 : _g.sendButtonLabel) != null ? _h : "Send";
10284
+ const stopLabel = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.stopButtonLabel) != null ? _j : "Stop";
10285
+ const showTooltip = (_k = sendButtonConfig.showTooltip) != null ? _k : false;
10286
+ const buttonSize = (_l = sendButtonConfig.size) != null ? _l : "40px";
10041
10287
  const backgroundColor = sendButtonConfig.backgroundColor;
10042
10288
  const textColor = sendButtonConfig.textColor;
10043
- const sendButtonWrapper = createElement("div", "persona-send-button-wrapper");
10044
- const sendButton = createElement(
10289
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10290
+ const button = createElement(
10045
10291
  "button",
10046
10292
  useIcon ? "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer" : "persona-rounded-button persona-bg-persona-accent persona-px-4 persona-py-2 persona-text-sm persona-font-semibold disabled:persona-opacity-50 persona-cursor-pointer"
10047
10293
  );
10048
- sendButton.type = "submit";
10049
- sendButton.setAttribute("data-persona-composer-submit", "");
10294
+ button.type = "submit";
10295
+ button.setAttribute("data-persona-composer-submit", "");
10050
10296
  let sendIcon = null;
10051
10297
  let stopIcon = null;
10052
10298
  if (useIcon) {
10053
- sendButton.style.width = buttonSize;
10054
- sendButton.style.height = buttonSize;
10055
- sendButton.style.minWidth = buttonSize;
10056
- sendButton.style.minHeight = buttonSize;
10057
- sendButton.style.fontSize = "18px";
10058
- sendButton.style.lineHeight = "1";
10059
- sendButton.innerHTML = "";
10299
+ button.style.width = buttonSize;
10300
+ button.style.height = buttonSize;
10301
+ button.style.minWidth = buttonSize;
10302
+ button.style.minHeight = buttonSize;
10303
+ button.style.fontSize = "18px";
10304
+ button.style.lineHeight = "1";
10305
+ button.innerHTML = "";
10060
10306
  if (textColor) {
10061
- sendButton.style.color = textColor;
10307
+ button.style.color = textColor;
10062
10308
  } else {
10063
- sendButton.style.color = "var(--persona-button-primary-fg, #ffffff)";
10309
+ button.style.color = "var(--persona-button-primary-fg, #ffffff)";
10064
10310
  }
10065
10311
  const iconSize = parseFloat(buttonSize) || 24;
10066
10312
  const iconColor = (textColor == null ? void 0 : textColor.trim()) || "currentColor";
10067
10313
  if (iconName) {
10068
10314
  sendIcon = renderLucideIcon(iconName, iconSize, iconColor, 2);
10069
10315
  if (sendIcon) {
10070
- sendButton.appendChild(sendIcon);
10316
+ button.appendChild(sendIcon);
10071
10317
  } else {
10072
- sendButton.textContent = iconText;
10318
+ button.textContent = iconText;
10073
10319
  }
10074
10320
  } else {
10075
- sendButton.textContent = iconText;
10321
+ button.textContent = iconText;
10076
10322
  }
10077
10323
  stopIcon = renderLucideIcon(stopIconName, iconSize, iconColor, 2);
10078
10324
  if (backgroundColor) {
10079
- sendButton.style.backgroundColor = backgroundColor;
10325
+ button.style.backgroundColor = backgroundColor;
10080
10326
  } else {
10081
- sendButton.classList.add("persona-bg-persona-primary");
10327
+ button.classList.add("persona-bg-persona-primary");
10082
10328
  }
10083
10329
  } else {
10084
- sendButton.textContent = sendLabel;
10330
+ button.textContent = sendLabel;
10085
10331
  if (textColor) {
10086
- sendButton.style.color = textColor;
10332
+ button.style.color = textColor;
10087
10333
  } else {
10088
- sendButton.classList.add("persona-text-white");
10334
+ button.classList.add("persona-text-white");
10089
10335
  }
10090
10336
  }
10091
10337
  if (sendButtonConfig.borderWidth) {
10092
- sendButton.style.borderWidth = sendButtonConfig.borderWidth;
10093
- sendButton.style.borderStyle = "solid";
10338
+ button.style.borderWidth = sendButtonConfig.borderWidth;
10339
+ button.style.borderStyle = "solid";
10094
10340
  }
10095
10341
  if (sendButtonConfig.borderColor) {
10096
- sendButton.style.borderColor = sendButtonConfig.borderColor;
10342
+ button.style.borderColor = sendButtonConfig.borderColor;
10097
10343
  }
10098
10344
  if (sendButtonConfig.paddingX) {
10099
- sendButton.style.paddingLeft = sendButtonConfig.paddingX;
10100
- sendButton.style.paddingRight = sendButtonConfig.paddingX;
10345
+ button.style.paddingLeft = sendButtonConfig.paddingX;
10346
+ button.style.paddingRight = sendButtonConfig.paddingX;
10101
10347
  } else {
10102
- sendButton.style.paddingLeft = "";
10103
- sendButton.style.paddingRight = "";
10348
+ button.style.paddingLeft = "";
10349
+ button.style.paddingRight = "";
10104
10350
  }
10105
10351
  if (sendButtonConfig.paddingY) {
10106
- sendButton.style.paddingTop = sendButtonConfig.paddingY;
10107
- sendButton.style.paddingBottom = sendButtonConfig.paddingY;
10352
+ button.style.paddingTop = sendButtonConfig.paddingY;
10353
+ button.style.paddingBottom = sendButtonConfig.paddingY;
10108
10354
  } else {
10109
- sendButton.style.paddingTop = "";
10110
- sendButton.style.paddingBottom = "";
10355
+ button.style.paddingTop = "";
10356
+ button.style.paddingBottom = "";
10111
10357
  }
10112
- let sendTooltip = null;
10358
+ let tooltip = null;
10113
10359
  if (showTooltip && tooltipText) {
10114
- sendTooltip = createElement("div", "persona-send-button-tooltip");
10115
- sendTooltip.textContent = tooltipText;
10116
- sendButtonWrapper.appendChild(sendTooltip);
10360
+ tooltip = createElement("div", "persona-send-button-tooltip");
10361
+ tooltip.textContent = tooltipText;
10362
+ wrapper.appendChild(tooltip);
10117
10363
  }
10118
- sendButton.setAttribute("aria-label", tooltipText);
10119
- sendButtonWrapper.appendChild(sendButton);
10364
+ button.setAttribute("aria-label", tooltipText);
10365
+ wrapper.appendChild(button);
10120
10366
  let currentMode = "send";
10121
- const setSendButtonMode = (mode) => {
10367
+ const setMode = (mode) => {
10122
10368
  if (mode === currentMode) return;
10123
10369
  currentMode = mode;
10124
10370
  const label = mode === "stop" ? stopTooltipText : tooltipText;
10125
- sendButton.setAttribute("aria-label", label);
10126
- if (sendTooltip) {
10127
- sendTooltip.textContent = label;
10371
+ button.setAttribute("aria-label", label);
10372
+ if (tooltip) {
10373
+ tooltip.textContent = label;
10128
10374
  }
10129
10375
  if (useIcon) {
10130
10376
  if (sendIcon && stopIcon) {
10131
10377
  const next = mode === "stop" ? stopIcon : sendIcon;
10132
10378
  const prev = mode === "stop" ? sendIcon : stopIcon;
10133
- if (prev.parentNode === sendButton) {
10134
- sendButton.replaceChild(next, prev);
10379
+ if (prev.parentNode === button) {
10380
+ button.replaceChild(next, prev);
10135
10381
  } else {
10136
- sendButton.appendChild(next);
10382
+ button.appendChild(next);
10137
10383
  }
10138
10384
  }
10139
10385
  } else {
10140
- sendButton.textContent = mode === "stop" ? stopLabel : sendLabel;
10386
+ button.textContent = mode === "stop" ? stopLabel : sendLabel;
10141
10387
  }
10142
10388
  };
10143
- const voiceRecognitionConfig = (_o = config == null ? void 0 : config.voiceRecognition) != null ? _o : {};
10389
+ return { button, wrapper, setMode };
10390
+ };
10391
+ var createMicButton = (config) => {
10392
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
10393
+ const voiceRecognitionConfig = (_a = config == null ? void 0 : config.voiceRecognition) != null ? _a : {};
10144
10394
  const voiceRecognitionEnabled = voiceRecognitionConfig.enabled === true;
10145
- let micButton = null;
10146
- let micButtonWrapper = null;
10395
+ if (!voiceRecognitionEnabled) return null;
10147
10396
  const hasSpeechRecognition = typeof window !== "undefined" && (typeof window.webkitSpeechRecognition !== "undefined" || typeof window.SpeechRecognition !== "undefined");
10148
- const hasRuntypeProvider = ((_p = voiceRecognitionConfig.provider) == null ? void 0 : _p.type) === "runtype";
10397
+ const hasRuntypeProvider = ((_b = voiceRecognitionConfig.provider) == null ? void 0 : _b.type) === "runtype";
10149
10398
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
10150
- if (voiceRecognitionEnabled && hasVoiceInput) {
10151
- micButtonWrapper = createElement("div", "persona-send-button-wrapper");
10152
- micButton = createElement(
10153
- "button",
10154
- "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer"
10155
- );
10156
- micButton.type = "button";
10157
- micButton.setAttribute("data-persona-composer-mic", "");
10158
- micButton.setAttribute("aria-label", "Start voice recognition");
10159
- const micIconName = (_q = voiceRecognitionConfig.iconName) != null ? _q : "mic";
10160
- const micIconSize = (_r = voiceRecognitionConfig.iconSize) != null ? _r : buttonSize;
10161
- const micIconSizeNum = parseFloat(micIconSize) || 24;
10162
- const micBackgroundColor = (_s = voiceRecognitionConfig.backgroundColor) != null ? _s : backgroundColor;
10163
- const micIconColor = (_t = voiceRecognitionConfig.iconColor) != null ? _t : textColor;
10164
- micButton.style.width = micIconSize;
10165
- micButton.style.height = micIconSize;
10166
- micButton.style.minWidth = micIconSize;
10167
- micButton.style.minHeight = micIconSize;
10168
- micButton.style.fontSize = "18px";
10169
- micButton.style.lineHeight = "1";
10170
- if (micIconColor) {
10171
- micButton.style.color = micIconColor;
10172
- } else {
10173
- micButton.style.color = "var(--persona-text, #111827)";
10174
- }
10175
- const iconColorValue = micIconColor || "currentColor";
10176
- const micIconSvg = renderLucideIcon(
10177
- micIconName,
10178
- micIconSizeNum,
10179
- iconColorValue,
10180
- 1.5
10181
- );
10182
- if (micIconSvg) {
10183
- micButton.appendChild(micIconSvg);
10184
- } else {
10185
- micButton.textContent = "\u{1F3A4}";
10186
- }
10187
- if (micBackgroundColor) {
10188
- micButton.style.backgroundColor = micBackgroundColor;
10189
- }
10190
- if (voiceRecognitionConfig.borderWidth) {
10191
- micButton.style.borderWidth = voiceRecognitionConfig.borderWidth;
10192
- micButton.style.borderStyle = "solid";
10193
- }
10194
- if (voiceRecognitionConfig.borderColor) {
10195
- micButton.style.borderColor = voiceRecognitionConfig.borderColor;
10196
- }
10197
- if (voiceRecognitionConfig.paddingX) {
10198
- micButton.style.paddingLeft = voiceRecognitionConfig.paddingX;
10199
- micButton.style.paddingRight = voiceRecognitionConfig.paddingX;
10200
- }
10201
- if (voiceRecognitionConfig.paddingY) {
10202
- micButton.style.paddingTop = voiceRecognitionConfig.paddingY;
10203
- micButton.style.paddingBottom = voiceRecognitionConfig.paddingY;
10204
- }
10205
- micButtonWrapper.appendChild(micButton);
10206
- const micTooltipText = (_u = voiceRecognitionConfig.tooltipText) != null ? _u : "Start voice recognition";
10207
- const showMicTooltip = (_v = voiceRecognitionConfig.showTooltip) != null ? _v : false;
10208
- if (showMicTooltip && micTooltipText) {
10209
- const tooltip = createElement("div", "persona-send-button-tooltip");
10210
- tooltip.textContent = micTooltipText;
10211
- micButtonWrapper.appendChild(tooltip);
10212
- }
10213
- }
10214
- const attachmentsConfig = (_w = config == null ? void 0 : config.attachments) != null ? _w : {};
10215
- const attachmentsEnabled = attachmentsConfig.enabled === true;
10216
- let attachmentButton = null;
10217
- let attachmentButtonWrapper = null;
10218
- let attachmentInput = null;
10219
- let attachmentPreviewsContainer = null;
10220
- if (attachmentsEnabled) {
10221
- attachmentPreviewsContainer = createElement(
10222
- "div",
10223
- "persona-attachment-previews persona-flex persona-flex-wrap persona-gap-2 persona-mb-2"
10224
- );
10225
- attachmentPreviewsContainer.style.display = "none";
10226
- attachmentInput = createElement("input");
10227
- attachmentInput.type = "file";
10228
- attachmentInput.accept = ((_x = attachmentsConfig.allowedTypes) != null ? _x : ALL_SUPPORTED_MIME_TYPES).join(",");
10229
- attachmentInput.multiple = ((_y = attachmentsConfig.maxFiles) != null ? _y : 4) > 1;
10230
- attachmentInput.style.display = "none";
10231
- attachmentInput.setAttribute("aria-label", "Attach files");
10232
- attachmentButtonWrapper = createElement("div", "persona-send-button-wrapper");
10233
- attachmentButton = createElement(
10234
- "button",
10235
- "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
10236
- );
10237
- attachmentButton.type = "button";
10238
- attachmentButton.setAttribute("aria-label", (_z = attachmentsConfig.buttonTooltipText) != null ? _z : "Attach file");
10239
- const attachIconName = (_A = attachmentsConfig.buttonIconName) != null ? _A : "paperclip";
10240
- const attachIconSize = buttonSize;
10241
- const buttonSizeNum = parseFloat(attachIconSize) || 40;
10242
- const attachIconSizeNum = Math.round(buttonSizeNum * 0.6);
10243
- attachmentButton.style.width = attachIconSize;
10244
- attachmentButton.style.height = attachIconSize;
10245
- attachmentButton.style.minWidth = attachIconSize;
10246
- attachmentButton.style.minHeight = attachIconSize;
10247
- attachmentButton.style.fontSize = "18px";
10248
- attachmentButton.style.lineHeight = "1";
10249
- attachmentButton.style.backgroundColor = "transparent";
10250
- attachmentButton.style.color = "var(--persona-primary, #111827)";
10251
- attachmentButton.style.border = "none";
10252
- attachmentButton.style.borderRadius = "6px";
10253
- attachmentButton.style.transition = "background-color 0.15s ease";
10254
- attachmentButton.addEventListener("mouseenter", () => {
10255
- attachmentButton.style.backgroundColor = "var(--persona-palette-colors-black-alpha-50, rgba(0, 0, 0, 0.05))";
10256
- });
10257
- attachmentButton.addEventListener("mouseleave", () => {
10258
- attachmentButton.style.backgroundColor = "transparent";
10259
- });
10260
- const attachIconSvg = renderLucideIcon(
10261
- attachIconName,
10262
- attachIconSizeNum,
10263
- "currentColor",
10264
- 1.5
10265
- );
10266
- if (attachIconSvg) {
10267
- attachmentButton.appendChild(attachIconSvg);
10268
- } else {
10269
- attachmentButton.textContent = "\u{1F4CE}";
10270
- }
10271
- attachmentButton.addEventListener("click", (e) => {
10272
- e.preventDefault();
10273
- attachmentInput == null ? void 0 : attachmentInput.click();
10274
- });
10275
- attachmentButtonWrapper.appendChild(attachmentButton);
10276
- const attachTooltipText = (_B = attachmentsConfig.buttonTooltipText) != null ? _B : "Attach file";
10399
+ if (!hasVoiceInput) return null;
10400
+ const buttonSize = (_d = (_c = config == null ? void 0 : config.sendButton) == null ? void 0 : _c.size) != null ? _d : "40px";
10401
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10402
+ const button = createElement(
10403
+ "button",
10404
+ "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer"
10405
+ );
10406
+ button.type = "button";
10407
+ button.setAttribute("data-persona-composer-mic", "");
10408
+ button.setAttribute("aria-label", "Start voice recognition");
10409
+ const micIconName = (_e = voiceRecognitionConfig.iconName) != null ? _e : "mic";
10410
+ const micIconSize = (_f = voiceRecognitionConfig.iconSize) != null ? _f : buttonSize;
10411
+ const micIconSizeNum = parseFloat(micIconSize) || 24;
10412
+ const micBackgroundColor = (_h = voiceRecognitionConfig.backgroundColor) != null ? _h : (_g = config == null ? void 0 : config.sendButton) == null ? void 0 : _g.backgroundColor;
10413
+ const micIconColor = (_j = voiceRecognitionConfig.iconColor) != null ? _j : (_i = config == null ? void 0 : config.sendButton) == null ? void 0 : _i.textColor;
10414
+ button.style.width = micIconSize;
10415
+ button.style.height = micIconSize;
10416
+ button.style.minWidth = micIconSize;
10417
+ button.style.minHeight = micIconSize;
10418
+ button.style.fontSize = "18px";
10419
+ button.style.lineHeight = "1";
10420
+ if (micIconColor) {
10421
+ button.style.color = micIconColor;
10422
+ } else {
10423
+ button.style.color = "var(--persona-text, #111827)";
10424
+ }
10425
+ const iconColorValue = micIconColor || "currentColor";
10426
+ const micIconSvg = renderLucideIcon(micIconName, micIconSizeNum, iconColorValue, 1.5);
10427
+ if (micIconSvg) {
10428
+ button.appendChild(micIconSvg);
10429
+ } else {
10430
+ button.textContent = "\u{1F3A4}";
10431
+ }
10432
+ if (micBackgroundColor) {
10433
+ button.style.backgroundColor = micBackgroundColor;
10434
+ }
10435
+ if (voiceRecognitionConfig.borderWidth) {
10436
+ button.style.borderWidth = voiceRecognitionConfig.borderWidth;
10437
+ button.style.borderStyle = "solid";
10438
+ }
10439
+ if (voiceRecognitionConfig.borderColor) {
10440
+ button.style.borderColor = voiceRecognitionConfig.borderColor;
10441
+ }
10442
+ if (voiceRecognitionConfig.paddingX) {
10443
+ button.style.paddingLeft = voiceRecognitionConfig.paddingX;
10444
+ button.style.paddingRight = voiceRecognitionConfig.paddingX;
10445
+ }
10446
+ if (voiceRecognitionConfig.paddingY) {
10447
+ button.style.paddingTop = voiceRecognitionConfig.paddingY;
10448
+ button.style.paddingBottom = voiceRecognitionConfig.paddingY;
10449
+ }
10450
+ wrapper.appendChild(button);
10451
+ const micTooltipText = (_k = voiceRecognitionConfig.tooltipText) != null ? _k : "Start voice recognition";
10452
+ const showMicTooltip = (_l = voiceRecognitionConfig.showTooltip) != null ? _l : false;
10453
+ if (showMicTooltip && micTooltipText) {
10277
10454
  const tooltip = createElement("div", "persona-send-button-tooltip");
10278
- tooltip.textContent = attachTooltipText;
10279
- attachmentButtonWrapper.appendChild(tooltip);
10455
+ tooltip.textContent = micTooltipText;
10456
+ wrapper.appendChild(tooltip);
10457
+ }
10458
+ return { button, wrapper };
10459
+ };
10460
+ var createAttachmentControls = (config) => {
10461
+ var _a, _b, _c, _d, _e, _f, _g, _h;
10462
+ const attachmentsConfig = (_a = config == null ? void 0 : config.attachments) != null ? _a : {};
10463
+ if (attachmentsConfig.enabled !== true) return null;
10464
+ const buttonSize = (_c = (_b = config == null ? void 0 : config.sendButton) == null ? void 0 : _b.size) != null ? _c : "40px";
10465
+ const previewsContainer = createElement(
10466
+ "div",
10467
+ "persona-attachment-previews persona-flex persona-flex-wrap persona-gap-2 persona-mb-2"
10468
+ );
10469
+ previewsContainer.style.display = "none";
10470
+ const input = createElement("input");
10471
+ input.type = "file";
10472
+ input.accept = ((_d = attachmentsConfig.allowedTypes) != null ? _d : ALL_SUPPORTED_MIME_TYPES).join(",");
10473
+ input.multiple = ((_e = attachmentsConfig.maxFiles) != null ? _e : 4) > 1;
10474
+ input.style.display = "none";
10475
+ input.setAttribute("aria-label", "Attach files");
10476
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10477
+ const button = createElement(
10478
+ "button",
10479
+ "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
10480
+ );
10481
+ button.type = "button";
10482
+ button.setAttribute("aria-label", (_f = attachmentsConfig.buttonTooltipText) != null ? _f : "Attach file");
10483
+ const attachIconName = (_g = attachmentsConfig.buttonIconName) != null ? _g : "paperclip";
10484
+ const attachIconSize = buttonSize;
10485
+ const buttonSizeNum = parseFloat(attachIconSize) || 40;
10486
+ const attachIconSizeNum = Math.round(buttonSizeNum * 0.6);
10487
+ button.style.width = attachIconSize;
10488
+ button.style.height = attachIconSize;
10489
+ button.style.minWidth = attachIconSize;
10490
+ button.style.minHeight = attachIconSize;
10491
+ button.style.fontSize = "18px";
10492
+ button.style.lineHeight = "1";
10493
+ button.style.backgroundColor = "transparent";
10494
+ button.style.color = "var(--persona-primary, #111827)";
10495
+ button.style.border = "none";
10496
+ button.style.borderRadius = "6px";
10497
+ button.style.transition = "background-color 0.15s ease";
10498
+ button.addEventListener("mouseenter", () => {
10499
+ button.style.backgroundColor = "var(--persona-palette-colors-black-alpha-50, rgba(0, 0, 0, 0.05))";
10500
+ });
10501
+ button.addEventListener("mouseleave", () => {
10502
+ button.style.backgroundColor = "transparent";
10503
+ });
10504
+ const attachIconSvg = renderLucideIcon(attachIconName, attachIconSizeNum, "currentColor", 1.5);
10505
+ if (attachIconSvg) {
10506
+ button.appendChild(attachIconSvg);
10507
+ } else {
10508
+ button.textContent = "\u{1F4CE}";
10509
+ }
10510
+ button.addEventListener("click", (e) => {
10511
+ e.preventDefault();
10512
+ input.click();
10513
+ });
10514
+ wrapper.appendChild(button);
10515
+ const attachTooltipText = (_h = attachmentsConfig.buttonTooltipText) != null ? _h : "Attach file";
10516
+ const tooltip = createElement("div", "persona-send-button-tooltip");
10517
+ tooltip.textContent = attachTooltipText;
10518
+ wrapper.appendChild(tooltip);
10519
+ return { button, wrapper, input, previewsContainer };
10520
+ };
10521
+ var createStatusText = (config) => {
10522
+ var _a, _b, _c;
10523
+ const statusConfig = (_a = config == null ? void 0 : config.statusIndicator) != null ? _a : {};
10524
+ const alignClass = statusConfig.align === "left" ? "persona-text-left" : statusConfig.align === "center" ? "persona-text-center" : "persona-text-right";
10525
+ const statusText = createElement(
10526
+ "div",
10527
+ `persona-mt-2 ${alignClass} persona-text-xs persona-text-persona-muted`
10528
+ );
10529
+ statusText.setAttribute("data-persona-composer-status", "");
10530
+ const isVisible = (_b = statusConfig.visible) != null ? _b : true;
10531
+ statusText.style.display = isVisible ? "" : "none";
10532
+ const idleLabel = (_c = statusConfig.idleText) != null ? _c : "Online";
10533
+ if (statusConfig.idleLink) {
10534
+ const link = createElement("a");
10535
+ link.href = statusConfig.idleLink;
10536
+ link.target = "_blank";
10537
+ link.rel = "noopener noreferrer";
10538
+ link.textContent = idleLabel;
10539
+ link.style.color = "inherit";
10540
+ link.style.textDecoration = "none";
10541
+ statusText.appendChild(link);
10542
+ } else {
10543
+ statusText.textContent = idleLabel;
10544
+ }
10545
+ return statusText;
10546
+ };
10547
+ var createSuggestionsRow = () => createElement("div", "persona-mb-3 persona-flex persona-flex-wrap persona-gap-2");
10548
+
10549
+ // src/components/composer-builder.ts
10550
+ var buildComposer = (context) => {
10551
+ var _a, _b, _c, _d, _e, _f;
10552
+ const { config } = context;
10553
+ const footer = createElement(
10554
+ "div",
10555
+ "persona-widget-footer persona-border-t-persona-divider persona-bg-persona-surface persona-px-6 persona-py-4"
10556
+ );
10557
+ footer.setAttribute("data-persona-theme-zone", "composer");
10558
+ const suggestions = createSuggestionsRow();
10559
+ const composerForm = createElement(
10560
+ "form",
10561
+ "persona-widget-composer persona-flex persona-flex-col persona-gap-2 persona-rounded-2xl persona-border persona-border-gray-200 persona-bg-persona-input-background persona-px-4 persona-py-3"
10562
+ );
10563
+ composerForm.setAttribute("data-persona-composer-form", "");
10564
+ composerForm.style.outline = "none";
10565
+ const { textarea, attachAutoResize } = createComposerTextarea(config);
10566
+ attachAutoResize();
10567
+ const send = createSendButton(config);
10568
+ const mic = createMicButton(config);
10569
+ const attachment = createAttachmentControls(config);
10570
+ const statusText = createStatusText(config);
10571
+ if (attachment) {
10572
+ attachment.previewsContainer.style.gap = "8px";
10573
+ composerForm.append(attachment.previewsContainer, attachment.input);
10574
+ }
10575
+ composerForm.append(textarea);
10576
+ const actionsRow = createElement(
10577
+ "div",
10578
+ "persona-widget-composer__actions persona-flex persona-items-center persona-justify-between persona-w-full"
10579
+ );
10580
+ const leftActions = createElement(
10581
+ "div",
10582
+ "persona-widget-composer__left-actions persona-flex persona-items-center persona-gap-2"
10583
+ );
10584
+ const rightActions = createElement(
10585
+ "div",
10586
+ "persona-widget-composer__right-actions persona-flex persona-items-center persona-gap-1"
10587
+ );
10588
+ if (attachment) leftActions.append(attachment.wrapper);
10589
+ if (mic) rightActions.append(mic.wrapper);
10590
+ rightActions.append(send.wrapper);
10591
+ actionsRow.append(leftActions, rightActions);
10592
+ composerForm.append(actionsRow);
10593
+ composerForm.addEventListener("click", (e) => {
10594
+ if (e.target !== send.button && e.target !== send.wrapper && e.target !== (mic == null ? void 0 : mic.button) && e.target !== (mic == null ? void 0 : mic.wrapper) && e.target !== (attachment == null ? void 0 : attachment.button) && e.target !== (attachment == null ? void 0 : attachment.wrapper)) {
10595
+ textarea.focus();
10596
+ }
10597
+ });
10598
+ footer.append(suggestions, composerForm, statusText);
10599
+ return {
10600
+ footer,
10601
+ suggestions,
10602
+ composerForm,
10603
+ textarea,
10604
+ sendButton: send.button,
10605
+ sendButtonWrapper: send.wrapper,
10606
+ micButton: (_a = mic == null ? void 0 : mic.button) != null ? _a : null,
10607
+ micButtonWrapper: (_b = mic == null ? void 0 : mic.wrapper) != null ? _b : null,
10608
+ statusText,
10609
+ attachmentButton: (_c = attachment == null ? void 0 : attachment.button) != null ? _c : null,
10610
+ attachmentButtonWrapper: (_d = attachment == null ? void 0 : attachment.wrapper) != null ? _d : null,
10611
+ attachmentInput: (_e = attachment == null ? void 0 : attachment.input) != null ? _e : null,
10612
+ attachmentPreviewsContainer: (_f = attachment == null ? void 0 : attachment.previewsContainer) != null ? _f : null,
10613
+ actionsRow,
10614
+ leftActions,
10615
+ rightActions,
10616
+ setSendButtonMode: send.setMode
10617
+ };
10618
+ };
10619
+
10620
+ // src/components/pill-composer-builder.ts
10621
+ var buildPillPeekBanner = () => {
10622
+ const root = createElement("button", "persona-pill-peek");
10623
+ root.type = "button";
10624
+ root.setAttribute("data-persona-pill-peek", "");
10625
+ root.setAttribute("aria-label", "Show conversation");
10626
+ root.setAttribute("tabindex", "-1");
10627
+ const iconHolder = createElement("span", "persona-pill-peek__icon");
10628
+ const messageIcon = renderLucideIcon("message-square", 16, "currentColor", 1.5);
10629
+ if (messageIcon) {
10630
+ iconHolder.appendChild(messageIcon);
10631
+ }
10632
+ const textNode = createElement("span", "persona-pill-peek__text");
10633
+ const caret = createElement("span", "persona-pill-peek__caret");
10634
+ const caretIcon = renderLucideIcon("chevron-up", 16, "currentColor", 1.5);
10635
+ if (caretIcon) {
10636
+ caret.appendChild(caretIcon);
10637
+ }
10638
+ root.append(iconHolder, textNode, caret);
10639
+ return { root, textNode };
10640
+ };
10641
+ var buildPillComposer = (context) => {
10642
+ var _a, _b, _c, _d, _e, _f;
10643
+ const { config } = context;
10644
+ const footer = createElement("div", "persona-widget-footer persona-widget-footer--pill");
10645
+ footer.setAttribute("data-persona-theme-zone", "composer");
10646
+ const suggestions = createSuggestionsRow();
10647
+ suggestions.style.display = "none";
10648
+ const statusText = createStatusText(config);
10649
+ statusText.style.display = "none";
10650
+ const { textarea, attachAutoResize } = createComposerTextarea(config);
10651
+ textarea.style.maxHeight = "100px";
10652
+ attachAutoResize();
10653
+ const send = createSendButton(config);
10654
+ const mic = createMicButton(config);
10655
+ const attachment = createAttachmentControls(config);
10656
+ if (attachment) {
10657
+ attachment.previewsContainer.classList.add("persona-pill-composer__previews");
10280
10658
  }
10659
+ const composerForm = createElement(
10660
+ "form",
10661
+ "persona-widget-composer persona-pill-composer"
10662
+ );
10663
+ composerForm.setAttribute("data-persona-composer-form", "");
10664
+ composerForm.style.outline = "none";
10665
+ const leftActions = createElement(
10666
+ "div",
10667
+ "persona-widget-composer__left-actions persona-pill-composer__left"
10668
+ );
10669
+ if (attachment) leftActions.append(attachment.wrapper);
10670
+ const rightActions = createElement(
10671
+ "div",
10672
+ "persona-widget-composer__right-actions persona-pill-composer__right"
10673
+ );
10674
+ if (mic) rightActions.append(mic.wrapper);
10675
+ rightActions.append(send.wrapper);
10281
10676
  composerForm.addEventListener("click", (e) => {
10282
- if (e.target !== sendButton && e.target !== sendButtonWrapper && e.target !== micButton && e.target !== micButtonWrapper && e.target !== attachmentButton && e.target !== attachmentButtonWrapper) {
10677
+ if (e.target !== send.button && e.target !== send.wrapper && e.target !== (mic == null ? void 0 : mic.button) && e.target !== (mic == null ? void 0 : mic.wrapper) && e.target !== (attachment == null ? void 0 : attachment.button) && e.target !== (attachment == null ? void 0 : attachment.wrapper)) {
10283
10678
  textarea.focus();
10284
10679
  }
10285
10680
  });
10286
- if (attachmentPreviewsContainer) {
10287
- attachmentPreviewsContainer.style.gap = "8px";
10288
- composerForm.append(attachmentPreviewsContainer);
10289
- }
10290
- if (attachmentInput) {
10291
- composerForm.append(attachmentInput);
10292
- }
10293
- composerForm.append(textarea);
10294
- const actionsRow = createElement("div", "persona-flex persona-items-center persona-justify-between persona-w-full");
10295
- const leftActions = createElement("div", "persona-flex persona-items-center persona-gap-2");
10296
- if (attachmentButtonWrapper) {
10297
- leftActions.append(attachmentButtonWrapper);
10298
- }
10299
- const rightActions = createElement("div", "persona-flex persona-items-center persona-gap-1");
10300
- if (micButtonWrapper) {
10301
- rightActions.append(micButtonWrapper);
10302
- }
10303
- rightActions.append(sendButtonWrapper);
10304
- actionsRow.append(leftActions, rightActions);
10305
- composerForm.append(actionsRow);
10306
- const statusConfig = (_C = config == null ? void 0 : config.statusIndicator) != null ? _C : {};
10307
- const alignClass = statusConfig.align === "left" ? "persona-text-left" : statusConfig.align === "center" ? "persona-text-center" : "persona-text-right";
10308
- const statusText = createElement(
10309
- "div",
10310
- `persona-mt-2 ${alignClass} persona-text-xs persona-text-persona-muted`
10311
- );
10312
- statusText.setAttribute("data-persona-composer-status", "");
10313
- const isVisible = (_D = statusConfig.visible) != null ? _D : true;
10314
- statusText.style.display = isVisible ? "" : "none";
10315
- const idleLabel = (_E = statusConfig.idleText) != null ? _E : "Online";
10316
- if (statusConfig.idleLink) {
10317
- const link = createElement("a");
10318
- link.href = statusConfig.idleLink;
10319
- link.target = "_blank";
10320
- link.rel = "noopener noreferrer";
10321
- link.textContent = idleLabel;
10322
- link.style.color = "inherit";
10323
- link.style.textDecoration = "none";
10324
- statusText.appendChild(link);
10325
- } else {
10326
- statusText.textContent = idleLabel;
10327
- }
10328
- footer.append(suggestions, composerForm, statusText);
10681
+ if (attachment) composerForm.append(attachment.input);
10682
+ composerForm.append(leftActions, textarea, rightActions);
10683
+ if (attachment) footer.append(attachment.previewsContainer);
10684
+ footer.append(composerForm, suggestions, statusText);
10685
+ const actionsRow = composerForm;
10329
10686
  return {
10330
10687
  footer,
10331
10688
  suggestions,
10332
10689
  composerForm,
10333
10690
  textarea,
10334
- sendButton,
10335
- sendButtonWrapper,
10336
- micButton,
10337
- micButtonWrapper,
10691
+ sendButton: send.button,
10692
+ sendButtonWrapper: send.wrapper,
10693
+ micButton: (_a = mic == null ? void 0 : mic.button) != null ? _a : null,
10694
+ micButtonWrapper: (_b = mic == null ? void 0 : mic.wrapper) != null ? _b : null,
10338
10695
  statusText,
10339
- // Attachment elements
10340
- attachmentButton,
10341
- attachmentButtonWrapper,
10342
- attachmentInput,
10343
- attachmentPreviewsContainer,
10344
- // Actions row layout elements
10696
+ attachmentButton: (_c = attachment == null ? void 0 : attachment.button) != null ? _c : null,
10697
+ attachmentButtonWrapper: (_d = attachment == null ? void 0 : attachment.wrapper) != null ? _d : null,
10698
+ attachmentInput: (_e = attachment == null ? void 0 : attachment.input) != null ? _e : null,
10699
+ attachmentPreviewsContainer: (_f = attachment == null ? void 0 : attachment.previewsContainer) != null ? _f : null,
10345
10700
  actionsRow,
10346
10701
  leftActions,
10347
10702
  rightActions,
10348
- setSendButtonMode
10703
+ setSendButtonMode: send.setMode
10349
10704
  };
10350
10705
  };
10351
10706
 
10352
10707
  // src/components/panel.ts
10353
10708
  var createWrapper = (config) => {
10354
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10709
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
10355
10710
  const launcherEnabled = (_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.enabled) != null ? _b : true;
10356
10711
  const dockedMode = isDockedMountMode(config);
10712
+ const composerBarMode = isComposerBarMountMode(config);
10713
+ if (composerBarMode) {
10714
+ const cb = (_d = (_c = config == null ? void 0 : config.launcher) == null ? void 0 : _c.composerBar) != null ? _d : {};
10715
+ const wrapper2 = createElement(
10716
+ "div",
10717
+ "persona-widget-wrapper persona-fixed persona-transition"
10718
+ );
10719
+ wrapper2.setAttribute("data-persona-composer-bar", "");
10720
+ wrapper2.dataset.state = "collapsed";
10721
+ wrapper2.dataset.expandedSize = (_e = cb.expandedSize) != null ? _e : "anchored";
10722
+ wrapper2.style.zIndex = String(
10723
+ (_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.zIndex) != null ? _g : DEFAULT_OVERLAY_Z_INDEX
10724
+ );
10725
+ const panel2 = createElement(
10726
+ "div",
10727
+ "persona-widget-panel persona-relative persona-flex persona-flex-1 persona-min-h-0 persona-flex-col"
10728
+ );
10729
+ panel2.style.width = "100%";
10730
+ wrapper2.appendChild(panel2);
10731
+ const pillRoot = createElement("div", "persona-widget-pill-root");
10732
+ pillRoot.setAttribute("data-persona-composer-bar", "");
10733
+ pillRoot.dataset.state = "collapsed";
10734
+ pillRoot.dataset.expandedSize = (_h = cb.expandedSize) != null ? _h : "anchored";
10735
+ pillRoot.style.zIndex = String(
10736
+ (_j = (_i = config == null ? void 0 : config.launcher) == null ? void 0 : _i.zIndex) != null ? _j : DEFAULT_OVERLAY_Z_INDEX
10737
+ );
10738
+ return { wrapper: wrapper2, panel: panel2, pillRoot };
10739
+ }
10357
10740
  if (dockedMode) {
10358
10741
  const wrapper2 = createElement(
10359
10742
  "div",
@@ -10375,35 +10758,171 @@ var createWrapper = (config) => {
10375
10758
  "div",
10376
10759
  "persona-relative persona-flex-1 persona-flex persona-flex-col persona-min-h-0"
10377
10760
  );
10378
- const inlineWidth = (_d = (_c = config == null ? void 0 : config.launcher) == null ? void 0 : _c.width) != null ? _d : "100%";
10761
+ const inlineWidth = (_l = (_k = config == null ? void 0 : config.launcher) == null ? void 0 : _k.width) != null ? _l : "100%";
10379
10762
  wrapper2.style.width = inlineWidth;
10380
10763
  panel2.style.width = "100%";
10381
10764
  wrapper2.appendChild(panel2);
10382
10765
  return { wrapper: wrapper2, panel: panel2 };
10383
10766
  }
10384
- const launcher = (_e = config == null ? void 0 : config.launcher) != null ? _e : {};
10767
+ const launcher = (_m = config == null ? void 0 : config.launcher) != null ? _m : {};
10385
10768
  const position = launcher.position && positionMap[launcher.position] ? positionMap[launcher.position] : positionMap["bottom-right"];
10386
10769
  const wrapper = createElement(
10387
10770
  "div",
10388
10771
  `persona-widget-wrapper persona-fixed ${position} persona-transition`
10389
10772
  );
10390
- wrapper.style.zIndex = String((_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.zIndex) != null ? _g : DEFAULT_OVERLAY_Z_INDEX);
10773
+ wrapper.style.zIndex = String((_o = (_n = config == null ? void 0 : config.launcher) == null ? void 0 : _n.zIndex) != null ? _o : DEFAULT_OVERLAY_Z_INDEX);
10391
10774
  const panel = createElement(
10392
10775
  "div",
10393
10776
  "persona-widget-panel persona-relative persona-min-h-[320px]"
10394
10777
  );
10395
- const launcherWidth = (_i = (_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.width) != null ? _i : config == null ? void 0 : config.launcherWidth;
10778
+ const launcherWidth = (_q = (_p = config == null ? void 0 : config.launcher) == null ? void 0 : _p.width) != null ? _q : config == null ? void 0 : config.launcherWidth;
10396
10779
  const width = launcherWidth != null ? launcherWidth : DEFAULT_FLOATING_LAUNCHER_WIDTH;
10397
10780
  panel.style.width = width;
10398
10781
  panel.style.maxWidth = width;
10399
10782
  wrapper.appendChild(panel);
10400
10783
  return { wrapper, panel };
10401
10784
  };
10785
+ var buildComposerBarPanel = (config, showClose) => {
10786
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10787
+ const container = createElement(
10788
+ "div",
10789
+ "persona-widget-container persona-relative persona-flex persona-flex-1 persona-min-h-0 persona-flex-col persona-text-persona-primary"
10790
+ );
10791
+ container.setAttribute("data-persona-theme-zone", "container");
10792
+ const { button: closeButton, wrapper: closeButtonWrapper } = createCloseButton(
10793
+ config,
10794
+ {
10795
+ showClose,
10796
+ wrapperClassName: "persona-composer-bar-close",
10797
+ buttonSize: "16px",
10798
+ iconSize: "14px"
10799
+ }
10800
+ );
10801
+ closeButtonWrapper.style.position = "absolute";
10802
+ closeButtonWrapper.style.top = "8px";
10803
+ closeButtonWrapper.style.right = "8px";
10804
+ closeButtonWrapper.style.zIndex = "10";
10805
+ const clearChatEnabled = (_c = (_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.clearChat) == null ? void 0 : _b.enabled) != null ? _c : true;
10806
+ let clearChatButton = null;
10807
+ let clearChatButtonWrapper = null;
10808
+ if (clearChatEnabled) {
10809
+ const parts = createClearChatButton(config, {
10810
+ wrapperClassName: "persona-composer-bar-clear-chat",
10811
+ buttonSize: "16px",
10812
+ iconSize: "14px"
10813
+ });
10814
+ clearChatButton = parts.button;
10815
+ clearChatButtonWrapper = parts.wrapper;
10816
+ clearChatButtonWrapper.style.position = "absolute";
10817
+ clearChatButtonWrapper.style.top = "8px";
10818
+ clearChatButtonWrapper.style.right = "32px";
10819
+ clearChatButtonWrapper.style.zIndex = "10";
10820
+ }
10821
+ const headerPlaceholder = createElement("span", "persona-widget-header");
10822
+ headerPlaceholder.setAttribute("data-persona-theme-zone", "header");
10823
+ headerPlaceholder.style.display = "none";
10824
+ const body = createElement(
10825
+ "div",
10826
+ "persona-widget-body persona-flex persona-flex-1 persona-min-h-0 persona-flex-col persona-gap-6 persona-overflow-y-auto persona-bg-persona-container persona-px-6 persona-py-6"
10827
+ );
10828
+ body.style.paddingTop = "48px";
10829
+ body.id = "persona-scroll-container";
10830
+ body.setAttribute("data-persona-theme-zone", "messages");
10831
+ const introCard = createElement(
10832
+ "div",
10833
+ "persona-rounded-2xl persona-bg-persona-surface persona-p-6"
10834
+ );
10835
+ introCard.style.boxShadow = "var(--persona-intro-card-shadow, 0 5px 15px rgba(15, 23, 42, 0.08))";
10836
+ introCard.setAttribute("data-persona-intro-card", "");
10837
+ const introTitle = createElement(
10838
+ "h2",
10839
+ "persona-text-lg persona-font-semibold persona-text-persona-primary"
10840
+ );
10841
+ introTitle.textContent = (_e = (_d = config == null ? void 0 : config.copy) == null ? void 0 : _d.welcomeTitle) != null ? _e : "Hello \u{1F44B}";
10842
+ const introSubtitle = createElement(
10843
+ "p",
10844
+ "persona-mt-2 persona-text-sm persona-text-persona-muted"
10845
+ );
10846
+ introSubtitle.textContent = (_g = (_f = config == null ? void 0 : config.copy) == null ? void 0 : _f.welcomeSubtitle) != null ? _g : "Ask anything about your account or products.";
10847
+ introCard.append(introTitle, introSubtitle);
10848
+ const messagesWrapper = createElement(
10849
+ "div",
10850
+ "persona-flex persona-flex-col persona-gap-3"
10851
+ );
10852
+ const contentMaxWidth = (_h = config == null ? void 0 : config.layout) == null ? void 0 : _h.contentMaxWidth;
10853
+ if (contentMaxWidth) {
10854
+ messagesWrapper.style.maxWidth = contentMaxWidth;
10855
+ messagesWrapper.style.marginLeft = "auto";
10856
+ messagesWrapper.style.marginRight = "auto";
10857
+ messagesWrapper.style.width = "100%";
10858
+ }
10859
+ const showWelcomeCard = ((_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.showWelcomeCard) !== false;
10860
+ if (!showWelcomeCard) {
10861
+ introCard.style.display = "none";
10862
+ body.classList.remove("persona-gap-6");
10863
+ body.classList.add("persona-gap-3");
10864
+ }
10865
+ body.append(introCard, messagesWrapper);
10866
+ const composerOverlay = createElement(
10867
+ "div",
10868
+ "persona-composer-overlay persona-pointer-events-none"
10869
+ );
10870
+ composerOverlay.setAttribute("data-persona-composer-overlay", "");
10871
+ composerOverlay.style.position = "absolute";
10872
+ composerOverlay.style.left = "0";
10873
+ composerOverlay.style.right = "0";
10874
+ composerOverlay.style.bottom = "0";
10875
+ composerOverlay.style.zIndex = "20";
10876
+ const composerElements = buildPillComposer({ config });
10877
+ const { root: peekBanner, textNode: peekTextNode } = buildPillPeekBanner();
10878
+ container.append(headerPlaceholder, closeButtonWrapper, body, composerOverlay);
10879
+ if (clearChatButtonWrapper) {
10880
+ container.appendChild(clearChatButtonWrapper);
10881
+ }
10882
+ return {
10883
+ container,
10884
+ body,
10885
+ messagesWrapper,
10886
+ composerOverlay,
10887
+ suggestions: composerElements.suggestions,
10888
+ textarea: composerElements.textarea,
10889
+ sendButton: composerElements.sendButton,
10890
+ sendButtonWrapper: composerElements.sendButtonWrapper,
10891
+ micButton: composerElements.micButton,
10892
+ micButtonWrapper: composerElements.micButtonWrapper,
10893
+ composerForm: composerElements.composerForm,
10894
+ statusText: composerElements.statusText,
10895
+ introTitle,
10896
+ introSubtitle,
10897
+ closeButton,
10898
+ closeButtonWrapper,
10899
+ clearChatButton,
10900
+ clearChatButtonWrapper,
10901
+ iconHolder: createElement("span"),
10902
+ headerTitle: createElement("span"),
10903
+ headerSubtitle: createElement("span"),
10904
+ header: headerPlaceholder,
10905
+ footer: composerElements.footer,
10906
+ attachmentButton: composerElements.attachmentButton,
10907
+ attachmentButtonWrapper: composerElements.attachmentButtonWrapper,
10908
+ attachmentInput: composerElements.attachmentInput,
10909
+ attachmentPreviewsContainer: composerElements.attachmentPreviewsContainer,
10910
+ actionsRow: composerElements.actionsRow,
10911
+ leftActions: composerElements.leftActions,
10912
+ rightActions: composerElements.rightActions,
10913
+ setSendButtonMode: composerElements.setSendButtonMode,
10914
+ peekBanner,
10915
+ peekTextNode
10916
+ };
10917
+ };
10402
10918
  var buildPanel = (config, showClose = true) => {
10403
10919
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10920
+ if (isComposerBarMountMode(config)) {
10921
+ return buildComposerBarPanel(config, showClose);
10922
+ }
10404
10923
  const container = createElement(
10405
10924
  "div",
10406
- "persona-widget-container persona-flex persona-h-full persona-w-full persona-flex-1 persona-min-h-0 persona-flex-col persona-bg-persona-surface persona-text-persona-primary persona-rounded-2xl persona-overflow-hidden persona-border persona-border-persona-border"
10925
+ "persona-widget-container persona-flex persona-h-full persona-w-full persona-flex-1 persona-min-h-0 persona-flex-col persona-text-persona-primary persona-bg-persona-surface persona-rounded-2xl persona-overflow-hidden persona-border persona-border-persona-border"
10407
10926
  );
10408
10927
  container.setAttribute("data-persona-theme-zone", "container");
10409
10928
  const headerLayoutConfig = (_a = config == null ? void 0 : config.layout) == null ? void 0 : _a.header;
@@ -15254,7 +15773,7 @@ function buildDropOverlay(dropCfg) {
15254
15773
  return overlay;
15255
15774
  }
15256
15775
  var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15257
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q;
15776
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U;
15258
15777
  if (mount == null) {
15259
15778
  throw new Error(
15260
15779
  'createAgentExperience: mount must be a non-null HTMLElement (e.g. pass document.getElementById("my-root") after the node exists).'
@@ -15272,7 +15791,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15272
15791
  componentRegistry.registerAll(config.components);
15273
15792
  }
15274
15793
  const eventBus = createEventBus();
15275
- const storageAdapter = (_a = config.storageAdapter) != null ? _a : createLocalStorageAdapter();
15794
+ const messagePersistenceDisabled = config.persistState === false;
15795
+ const storageAdapter = messagePersistenceDisabled ? null : (_a = config.storageAdapter) != null ? _a : createLocalStorageAdapter();
15276
15796
  let persistentMetadata = {};
15277
15797
  let pendingStoredState = null;
15278
15798
  let shouldOpenAfterStateLoaded = false;
@@ -15363,7 +15883,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15363
15883
  let prevLauncherEnabled = launcherEnabled;
15364
15884
  let prevHeaderLayout = (_l = (_k = config.layout) == null ? void 0 : _k.header) == null ? void 0 : _l.layout;
15365
15885
  let wasMobileFullscreen = false;
15366
- let open = launcherEnabled ? autoExpand : true;
15886
+ const isComposerBar = () => isComposerBarMountMode(config);
15887
+ const isPanelToggleable = () => launcherEnabled || isComposerBar();
15888
+ let open = isComposerBar() ? false : launcherEnabled ? autoExpand : true;
15367
15889
  let pendingResubmit = false;
15368
15890
  let pendingResubmitTimeout = null;
15369
15891
  const handleResubmitRequested = () => {
@@ -15449,8 +15971,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15449
15971
  el.textContent = text;
15450
15972
  }
15451
15973
  }
15452
- const { wrapper, panel } = createWrapper(config);
15453
- const panelElements = buildPanel(config, launcherEnabled);
15974
+ const { wrapper, panel, pillRoot } = createWrapper(config);
15975
+ const panelElements = buildPanel(config, isPanelToggleable());
15454
15976
  let {
15455
15977
  container,
15456
15978
  body,
@@ -15533,7 +16055,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15533
16055
  const customHeader = headerPlugin.renderHeader({
15534
16056
  config,
15535
16057
  defaultRenderer: () => {
15536
- const headerElements = buildHeader({ config, showClose: launcherEnabled });
16058
+ const headerElements = buildHeader({ config, showClose: isPanelToggleable() });
15537
16059
  attachHeaderToContainer(container, headerElements, config);
15538
16060
  return headerElements.header;
15539
16061
  },
@@ -15676,6 +16198,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15676
16198
  const value = text.trim();
15677
16199
  const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
15678
16200
  if (!value && !hasAttachments) return;
16201
+ maybeExpandComposerBar();
15679
16202
  let contentParts;
15680
16203
  if (hasAttachments) {
15681
16204
  contentParts = [];
@@ -15741,23 +16264,29 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15741
16264
  };
15742
16265
  ensureComposerAttachmentSurface(footer);
15743
16266
  bindComposerRefsFromFooter(footer);
15744
- const contentMaxWidth = (_D = config.layout) == null ? void 0 : _D.contentMaxWidth;
15745
- if (contentMaxWidth && composerForm) {
16267
+ const contentMaxWidth = (_H = (_D = config.layout) == null ? void 0 : _D.contentMaxWidth) != null ? _H : isComposerBar() ? (_G = (_F = (_E = config.launcher) == null ? void 0 : _E.composerBar) == null ? void 0 : _F.contentMaxWidth) != null ? _G : "720px" : void 0;
16268
+ if (contentMaxWidth) {
16269
+ messagesWrapper.style.maxWidth = contentMaxWidth;
16270
+ messagesWrapper.style.marginLeft = "auto";
16271
+ messagesWrapper.style.marginRight = "auto";
16272
+ messagesWrapper.style.width = "100%";
16273
+ }
16274
+ if (contentMaxWidth && composerForm && !isComposerBar()) {
15746
16275
  composerForm.style.maxWidth = contentMaxWidth;
15747
16276
  composerForm.style.marginLeft = "auto";
15748
16277
  composerForm.style.marginRight = "auto";
15749
16278
  }
15750
- if (contentMaxWidth && suggestions) {
16279
+ if (contentMaxWidth && suggestions && !isComposerBar()) {
15751
16280
  suggestions.style.maxWidth = contentMaxWidth;
15752
16281
  suggestions.style.marginLeft = "auto";
15753
16282
  suggestions.style.marginRight = "auto";
15754
16283
  }
15755
- if (contentMaxWidth && attachmentPreviewsContainer) {
16284
+ if (contentMaxWidth && attachmentPreviewsContainer && !isComposerBar()) {
15756
16285
  attachmentPreviewsContainer.style.maxWidth = contentMaxWidth;
15757
16286
  attachmentPreviewsContainer.style.marginLeft = "auto";
15758
16287
  attachmentPreviewsContainer.style.marginRight = "auto";
15759
16288
  }
15760
- if (((_E = config.attachments) == null ? void 0 : _E.enabled) && attachmentInput && attachmentPreviewsContainer) {
16289
+ if (((_I = config.attachments) == null ? void 0 : _I.enabled) && attachmentInput && attachmentPreviewsContainer) {
15761
16290
  attachmentManager = AttachmentManager.fromConfig(config.attachments);
15762
16291
  attachmentManager.setPreviewsContainer(attachmentPreviewsContainer);
15763
16292
  attachmentInput.addEventListener("change", (e) => {
@@ -16567,29 +17096,70 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16567
17096
  }
16568
17097
  } else {
16569
17098
  panel.appendChild(container);
17099
+ if (isComposerBar() && pillRoot) {
17100
+ if (panelElements.peekBanner) {
17101
+ pillRoot.appendChild(panelElements.peekBanner);
17102
+ }
17103
+ pillRoot.appendChild(footer);
17104
+ }
16570
17105
  }
16571
17106
  mount.appendChild(wrapper);
17107
+ if (pillRoot) {
17108
+ mount.appendChild(pillRoot);
17109
+ }
16572
17110
  const applyFullHeightStyles = () => {
16573
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2;
17111
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2;
17112
+ if (isComposerBar()) {
17113
+ panel.style.width = "100%";
17114
+ panel.style.maxWidth = "100%";
17115
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
17116
+ const isExpanded = wrapper.dataset.state === "expanded";
17117
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
17118
+ const wantsChrome = isExpanded && expandedSize !== "fullscreen";
17119
+ if (!wantsChrome) {
17120
+ container.style.background = "";
17121
+ container.style.border = "";
17122
+ container.style.borderRadius = "";
17123
+ container.style.overflow = "";
17124
+ container.style.boxShadow = "";
17125
+ return;
17126
+ }
17127
+ const panelPartial2 = (_e2 = (_d2 = config.theme) == null ? void 0 : _d2.components) == null ? void 0 : _e2.panel;
17128
+ const activeTheme2 = getActiveTheme(config);
17129
+ const resolveCb = (raw, fallback) => {
17130
+ var _a3;
17131
+ if (raw == null || raw === "") return fallback;
17132
+ return (_a3 = resolveTokenValue(activeTheme2, raw)) != null ? _a3 : raw;
17133
+ };
17134
+ const defaultBorder = "1px solid var(--persona-border)";
17135
+ const defaultShadow = "var(--persona-palette-shadows-xl, 0 25px 50px -12px rgba(0, 0, 0, 0.25))";
17136
+ const defaultRadius = "var(--persona-panel-radius, var(--persona-radius-xl, 0.75rem))";
17137
+ container.style.background = "var(--persona-surface, #ffffff)";
17138
+ container.style.border = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.border, defaultBorder);
17139
+ container.style.borderRadius = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.borderRadius, defaultRadius);
17140
+ container.style.boxShadow = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.shadow, defaultShadow);
17141
+ container.style.overflow = "hidden";
17142
+ return;
17143
+ }
16574
17144
  const dockedMode = isDockedMountMode(config);
16575
- const sidebarMode = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.sidebarMode) != null ? _b2 : false;
16576
- const fullHeight = dockedMode || sidebarMode || ((_d2 = (_c2 = config.launcher) == null ? void 0 : _c2.fullHeight) != null ? _d2 : false);
16577
- const isInlineEmbed = ((_e2 = config.launcher) == null ? void 0 : _e2.enabled) === false;
16578
- const panelPartial = (_g2 = (_f2 = config.theme) == null ? void 0 : _f2.components) == null ? void 0 : _g2.panel;
17145
+ const sidebarMode = (_g2 = (_f2 = config.launcher) == null ? void 0 : _f2.sidebarMode) != null ? _g2 : false;
17146
+ const fullHeight = dockedMode || sidebarMode || ((_i2 = (_h2 = config.launcher) == null ? void 0 : _h2.fullHeight) != null ? _i2 : false);
17147
+ const isInlineEmbed = ((_j2 = config.launcher) == null ? void 0 : _j2.enabled) === false;
17148
+ const panelPartial = (_l2 = (_k2 = config.theme) == null ? void 0 : _k2.components) == null ? void 0 : _l2.panel;
16579
17149
  const activeTheme = getActiveTheme(config);
16580
17150
  const resolvePanelChrome = (raw, fallback) => {
16581
17151
  var _a3;
16582
17152
  if (raw == null || raw === "") return fallback;
16583
17153
  return (_a3 = resolveTokenValue(activeTheme, raw)) != null ? _a3 : raw;
16584
17154
  };
16585
- const ownerWindow2 = (_h2 = mount.ownerDocument.defaultView) != null ? _h2 : window;
16586
- const mobileFullscreen = (_j2 = (_i2 = config.launcher) == null ? void 0 : _i2.mobileFullscreen) != null ? _j2 : true;
16587
- const mobileBreakpoint = (_l2 = (_k2 = config.launcher) == null ? void 0 : _k2.mobileBreakpoint) != null ? _l2 : 640;
17155
+ const ownerWindow2 = (_m2 = mount.ownerDocument.defaultView) != null ? _m2 : window;
17156
+ const mobileFullscreen = (_o2 = (_n2 = config.launcher) == null ? void 0 : _n2.mobileFullscreen) != null ? _o2 : true;
17157
+ const mobileBreakpoint = (_q2 = (_p2 = config.launcher) == null ? void 0 : _p2.mobileBreakpoint) != null ? _q2 : 640;
16588
17158
  const isMobileViewport = ownerWindow2.innerWidth <= mobileBreakpoint;
16589
17159
  const shouldGoFullscreen = mobileFullscreen && isMobileViewport && launcherEnabled;
16590
- const position = (_n2 = (_m2 = config.launcher) == null ? void 0 : _m2.position) != null ? _n2 : "bottom-left";
17160
+ const position = (_s2 = (_r2 = config.launcher) == null ? void 0 : _r2.position) != null ? _s2 : "bottom-left";
16591
17161
  const isLeftSidebar = position === "bottom-left" || position === "top-left";
16592
- const overlayZIndex = (_p2 = (_o2 = config.launcher) == null ? void 0 : _o2.zIndex) != null ? _p2 : DEFAULT_OVERLAY_Z_INDEX;
17162
+ const overlayZIndex = (_u2 = (_t2 = config.launcher) == null ? void 0 : _t2.zIndex) != null ? _u2 : DEFAULT_OVERLAY_Z_INDEX;
16593
17163
  let defaultPanelBorder = sidebarMode || shouldGoFullscreen ? "none" : "1px solid var(--persona-border)";
16594
17164
  let defaultPanelShadow = shouldGoFullscreen ? "none" : sidebarMode ? isLeftSidebar ? "var(--persona-palette-shadows-sidebar-left, 2px 0 12px rgba(0, 0, 0, 0.08))" : "var(--persona-palette-shadows-sidebar-right, -2px 0 12px rgba(0, 0, 0, 0.08))" : "var(--persona-palette-shadows-xl, 0 25px 50px -12px rgba(0, 0, 0, 0.25))";
16595
17165
  if (dockedMode && !shouldGoFullscreen) {
@@ -16676,7 +17246,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16676
17246
  restoreBodyScrollTop();
16677
17247
  return;
16678
17248
  }
16679
- const launcherWidth = (_r2 = (_q2 = config == null ? void 0 : config.launcher) == null ? void 0 : _q2.width) != null ? _r2 : config == null ? void 0 : config.launcherWidth;
17249
+ const launcherWidth = (_w2 = (_v2 = config == null ? void 0 : config.launcher) == null ? void 0 : _v2.width) != null ? _w2 : config == null ? void 0 : config.launcherWidth;
16680
17250
  const width = launcherWidth != null ? launcherWidth : DEFAULT_FLOATING_LAUNCHER_WIDTH;
16681
17251
  if (!sidebarMode && !dockedMode) {
16682
17252
  if (isInlineEmbed && fullHeight) {
@@ -16757,11 +17327,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16757
17327
  "persona-top-4"
16758
17328
  );
16759
17329
  if (!sidebarMode && !isInlineEmbed && !dockedMode) {
16760
- const positionClasses = (_s2 = positionMap[position]) != null ? _s2 : positionMap["bottom-right"];
17330
+ const positionClasses = (_x2 = positionMap[position]) != null ? _x2 : positionMap["bottom-right"];
16761
17331
  positionClasses.split(" ").forEach((cls) => wrapper.classList.add(cls));
16762
17332
  }
16763
17333
  if (sidebarMode) {
16764
- const sidebarWidth = (_u2 = (_t2 = config.launcher) == null ? void 0 : _t2.sidebarWidth) != null ? _u2 : "420px";
17334
+ const sidebarWidth = (_z2 = (_y2 = config.launcher) == null ? void 0 : _y2.sidebarWidth) != null ? _z2 : "420px";
16765
17335
  wrapper.style.cssText = `
16766
17336
  position: fixed !important;
16767
17337
  top: 0 !important;
@@ -16813,7 +17383,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16813
17383
  if (!isInlineEmbed && !dockedMode) {
16814
17384
  const maxHeightStyles = "max-height: -moz-available !important; max-height: stretch !important;";
16815
17385
  const paddingStyles = sidebarMode ? "" : "padding-top: 1.25em !important;";
16816
- const zIndexStyles = !sidebarMode ? `z-index: ${(_w2 = (_v2 = config.launcher) == null ? void 0 : _v2.zIndex) != null ? _w2 : DEFAULT_OVERLAY_Z_INDEX} !important;` : "";
17386
+ const zIndexStyles = !sidebarMode ? `z-index: ${(_B2 = (_A2 = config.launcher) == null ? void 0 : _A2.zIndex) != null ? _B2 : DEFAULT_OVERLAY_Z_INDEX} !important;` : "";
16817
17387
  wrapper.style.cssText += maxHeightStyles + paddingStyles + zIndexStyles;
16818
17388
  }
16819
17389
  restoreBodyScrollTop();
@@ -16883,7 +17453,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16883
17453
  cleanupThemeObserver = null;
16884
17454
  }
16885
17455
  });
16886
- const streamAnimationConfig = (_F = config.features) == null ? void 0 : _F.streamAnimation;
17456
+ const streamAnimationConfig = (_J = config.features) == null ? void 0 : _J.streamAnimation;
16887
17457
  if ((streamAnimationConfig == null ? void 0 : streamAnimationConfig.type) && streamAnimationConfig.type !== "none") {
16888
17458
  const plugin = resolveStreamAnimationPlugin(
16889
17459
  streamAnimationConfig.type,
@@ -16900,6 +17470,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16900
17470
  let isStreaming = false;
16901
17471
  const messageCache = createMessageCache();
16902
17472
  const lastAskBubbleFingerprint = /* @__PURE__ */ new Map();
17473
+ const lastComponentDirectiveFingerprint = /* @__PURE__ */ new Map();
16903
17474
  let configVersion = 0;
16904
17475
  const autoFollow = createFollowStateController();
16905
17476
  let lastScrollTop = 0;
@@ -16916,7 +17487,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16916
17487
  lastUserMessageWasVoice: false,
16917
17488
  lastUserMessageId: null
16918
17489
  };
16919
- const voiceAutoResumeMode = (_H = (_G = config.voiceRecognition) == null ? void 0 : _G.autoResume) != null ? _H : false;
17490
+ const voiceAutoResumeMode = (_L = (_K = config.voiceRecognition) == null ? void 0 : _K.autoResume) != null ? _L : false;
16920
17491
  const emitVoiceState = (source) => {
16921
17492
  eventBus.emit("voice:state", {
16922
17493
  active: voiceState.active,
@@ -17147,13 +17718,21 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17147
17718
  const liveAskToolIds = /* @__PURE__ */ new Set();
17148
17719
  const hasAskPlugin = plugins.some((p) => p.renderAskUserQuestion);
17149
17720
  const askPluginHydrate = [];
17721
+ const componentDirectiveHydrate = [];
17722
+ const componentStreamingEnabled = config.enableComponentStreaming !== false;
17150
17723
  messages.forEach((message) => {
17151
17724
  var _a3, _b3, _c3, _d3, _e3, _f3, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
17152
17725
  activeMessageIds.add(message.id);
17153
17726
  const askWithPlugin = hasAskPlugin && isAskUserQuestionMessage(message);
17727
+ const hasDirectiveBubble = !askWithPlugin && message.role === "assistant" && !message.variant && componentStreamingEnabled && hasComponentDirective(message);
17728
+ if (!hasDirectiveBubble && lastComponentDirectiveFingerprint.has(message.id)) {
17729
+ const existing = container2.querySelector(`#wrapper-${message.id}`);
17730
+ existing == null ? void 0 : existing.removeAttribute("data-preserve-runtime");
17731
+ lastComponentDirectiveFingerprint.delete(message.id);
17732
+ }
17154
17733
  const askMeta = isAskUserQuestionMessage(message) ? `:${((_a3 = message.agentMetadata) == null ? void 0 : _a3.askUserQuestionAnswered) ? "a" : "u"}:${((_b3 = message.agentMetadata) == null ? void 0 : _b3.askUserQuestionAnswers) ? Object.keys(message.agentMetadata.askUserQuestionAnswers).length : 0}` : "";
17155
17734
  const fingerprint = computeMessageFingerprint(message, configVersion) + askMeta;
17156
- const cachedWrapper = askWithPlugin ? null : getCachedWrapper(messageCache, message.id, fingerprint);
17735
+ const cachedWrapper = askWithPlugin || hasDirectiveBubble ? null : getCachedWrapper(messageCache, message.id, fingerprint);
17157
17736
  if (cachedWrapper) {
17158
17737
  tempContainer.appendChild(cachedWrapper.cloneNode(true));
17159
17738
  if (isAskUserQuestionMessage(message) && ((_c3 = message.toolCall) == null ? void 0 : _c3.id) && ((_d3 = message.agentMetadata) == null ? void 0 : _d3.awaitingLocalTool) === true && !((_e3 = message.agentMetadata) == null ? void 0 : _e3.askUserQuestionAnswered)) {
@@ -17292,18 +17871,20 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17292
17871
  });
17293
17872
  }
17294
17873
  }
17295
- if (!bubble && message.role === "assistant" && !message.variant) {
17296
- const enableComponentStreaming = config.enableComponentStreaming !== false;
17297
- if (enableComponentStreaming && hasComponentDirective(message)) {
17298
- const directive = extractComponentDirectiveFromMessage(message);
17299
- if (directive) {
17874
+ if (!bubble && hasDirectiveBubble) {
17875
+ const directive = extractComponentDirectiveFromMessage(message);
17876
+ if (directive) {
17877
+ const lastFp = lastComponentDirectiveFingerprint.get(message.id);
17878
+ const needsRebuild = lastFp !== fingerprint;
17879
+ const wrapChrome = config.wrapComponentDirectiveInBubble !== false;
17880
+ let liveBubble = null;
17881
+ if (needsRebuild) {
17300
17882
  const componentBubble = renderComponentDirective(directive, {
17301
17883
  config,
17302
17884
  message,
17303
17885
  transform
17304
17886
  });
17305
17887
  if (componentBubble) {
17306
- const wrapChrome = config.wrapComponentDirectiveInBubble !== false;
17307
17888
  if (wrapChrome) {
17308
17889
  const componentWrapper = document.createElement("div");
17309
17890
  componentWrapper.className = [
@@ -17329,7 +17910,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17329
17910
  componentWrapper.appendChild(textDiv);
17330
17911
  }
17331
17912
  componentWrapper.appendChild(componentBubble);
17332
- bubble = componentWrapper;
17913
+ liveBubble = componentWrapper;
17333
17914
  } else {
17334
17915
  const stack = document.createElement("div");
17335
17916
  stack.className = "persona-flex persona-flex-col persona-w-full persona-max-w-full persona-gap-3 persona-items-stretch";
@@ -17348,10 +17929,28 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17348
17929
  stack.appendChild(textDiv);
17349
17930
  }
17350
17931
  stack.appendChild(componentBubble);
17351
- bubble = stack;
17932
+ liveBubble = stack;
17352
17933
  }
17353
17934
  }
17354
17935
  }
17936
+ if (liveBubble || lastFp != null) {
17937
+ const stub = document.createElement("div");
17938
+ stub.className = "persona-flex";
17939
+ stub.id = `wrapper-${message.id}`;
17940
+ stub.setAttribute("data-wrapper-id", message.id);
17941
+ stub.setAttribute("data-component-directive-stub", "true");
17942
+ stub.setAttribute("data-preserve-runtime", "true");
17943
+ if (!wrapChrome) {
17944
+ stub.classList.add("persona-w-full");
17945
+ }
17946
+ tempContainer.appendChild(stub);
17947
+ componentDirectiveHydrate.push({
17948
+ messageId: message.id,
17949
+ fingerprint,
17950
+ bubble: liveBubble
17951
+ });
17952
+ return;
17953
+ }
17355
17954
  }
17356
17955
  }
17357
17956
  if (!bubble) {
@@ -17602,15 +18201,327 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17602
18201
  if (!activeMessageIds.has(id)) lastAskBubbleFingerprint.delete(id);
17603
18202
  }
17604
18203
  }
18204
+ if (componentDirectiveHydrate.length > 0) {
18205
+ for (const { messageId, fingerprint, bubble } of componentDirectiveHydrate) {
18206
+ const wrapper2 = container2.querySelector(`#wrapper-${messageId}`);
18207
+ if (!wrapper2) continue;
18208
+ if (bubble === null) {
18209
+ continue;
18210
+ }
18211
+ wrapper2.replaceChildren(bubble);
18212
+ wrapper2.setAttribute("data-bubble-fp", fingerprint);
18213
+ lastComponentDirectiveFingerprint.set(messageId, fingerprint);
18214
+ }
18215
+ }
18216
+ if (lastComponentDirectiveFingerprint.size > 0) {
18217
+ for (const id of lastComponentDirectiveFingerprint.keys()) {
18218
+ if (!activeMessageIds.has(id)) lastComponentDirectiveFingerprint.delete(id);
18219
+ }
18220
+ }
17605
18221
  };
17606
18222
  const renderMessagesWithPlugins = renderMessagesWithPluginsImpl;
18223
+ let composerBarOutsideClickListener = null;
18224
+ const attachComposerBarOutsideClickDismiss = () => {
18225
+ var _a2;
18226
+ if (composerBarOutsideClickListener) return;
18227
+ const listener = (event) => {
18228
+ const path = event.composedPath();
18229
+ if (path.includes(wrapper)) return;
18230
+ if (pillRoot && path.includes(pillRoot)) return;
18231
+ setOpenState(false, "user");
18232
+ };
18233
+ composerBarOutsideClickListener = listener;
18234
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18235
+ targetDoc.addEventListener("pointerdown", listener, true);
18236
+ };
18237
+ const detachComposerBarOutsideClickDismiss = () => {
18238
+ var _a2;
18239
+ if (!composerBarOutsideClickListener) return;
18240
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18241
+ targetDoc.removeEventListener(
18242
+ "pointerdown",
18243
+ composerBarOutsideClickListener,
18244
+ true
18245
+ );
18246
+ composerBarOutsideClickListener = null;
18247
+ };
18248
+ destroyCallbacks.push(() => detachComposerBarOutsideClickDismiss());
18249
+ let composerBarEscapeListener = null;
18250
+ const attachComposerBarEscapeDismiss = () => {
18251
+ var _a2;
18252
+ if (composerBarEscapeListener) return;
18253
+ const listener = (event) => {
18254
+ if (event.key !== "Escape") return;
18255
+ if (event.isComposing) return;
18256
+ setOpenState(false, "user");
18257
+ };
18258
+ composerBarEscapeListener = listener;
18259
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18260
+ targetDoc.addEventListener("keydown", listener, true);
18261
+ };
18262
+ const detachComposerBarEscapeDismiss = () => {
18263
+ var _a2;
18264
+ if (!composerBarEscapeListener) return;
18265
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18266
+ targetDoc.removeEventListener(
18267
+ "keydown",
18268
+ composerBarEscapeListener,
18269
+ true
18270
+ );
18271
+ composerBarEscapeListener = null;
18272
+ };
18273
+ destroyCallbacks.push(() => detachComposerBarEscapeDismiss());
18274
+ let composerHovered = false;
18275
+ const peekActivatedPlugins = /* @__PURE__ */ new Set();
18276
+ const resolvePeekStreamAnimationFeature = () => {
18277
+ var _a2, _b2, _c2, _d2;
18278
+ const peekFeature = (_c2 = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) == null ? void 0 : _b2.peek) == null ? void 0 : _c2.streamAnimation;
18279
+ if (peekFeature) return peekFeature;
18280
+ return (_d2 = config.features) == null ? void 0 : _d2.streamAnimation;
18281
+ };
18282
+ const syncComposerBarPeek = () => {
18283
+ var _a2, _b2, _c2, _d2;
18284
+ if (!isComposerBar()) return;
18285
+ const peekBanner = panelElements.peekBanner;
18286
+ const peekTextNode = panelElements.peekTextNode;
18287
+ if (!peekBanner || !peekTextNode) return;
18288
+ if (open) {
18289
+ peekBanner.classList.remove("persona-pill-peek--visible");
18290
+ return;
18291
+ }
18292
+ const messages = (_a2 = session == null ? void 0 : session.getMessages()) != null ? _a2 : [];
18293
+ let lastAssistant;
18294
+ for (let i = messages.length - 1; i >= 0; i--) {
18295
+ const m = messages[i];
18296
+ if (m.role === "assistant" && m.content) {
18297
+ lastAssistant = m;
18298
+ break;
18299
+ }
18300
+ }
18301
+ if (!lastAssistant) {
18302
+ peekBanner.classList.remove("persona-pill-peek--visible");
18303
+ return;
18304
+ }
18305
+ const text = lastAssistant.content;
18306
+ const streaming = Boolean(lastAssistant.streaming);
18307
+ const feature = resolvePeekStreamAnimationFeature();
18308
+ const streamAnimation = resolveStreamAnimation(feature);
18309
+ const plugin = streamAnimation.type !== "none" ? resolveStreamAnimationPlugin(streamAnimation.type, feature == null ? void 0 : feature.plugins) : null;
18310
+ const pluginStillAnimating = ((_b2 = plugin == null ? void 0 : plugin.isAnimating) == null ? void 0 : _b2.call(plugin, lastAssistant)) === true;
18311
+ const animationActive = plugin !== null && (streaming || pluginStillAnimating);
18312
+ if (animationActive && plugin && !peekActivatedPlugins.has(plugin.name)) {
18313
+ ensurePluginActive(plugin, mount);
18314
+ peekActivatedPlugins.add(plugin.name);
18315
+ }
18316
+ const desiredContainerClass = animationActive && (plugin == null ? void 0 : plugin.containerClass) ? plugin.containerClass : null;
18317
+ const currentContainerClass = (_c2 = peekTextNode.dataset.personaPeekStreamClass) != null ? _c2 : null;
18318
+ if (currentContainerClass && currentContainerClass !== desiredContainerClass) {
18319
+ peekTextNode.classList.remove(currentContainerClass);
18320
+ delete peekTextNode.dataset.personaPeekStreamClass;
18321
+ }
18322
+ if (desiredContainerClass && currentContainerClass !== desiredContainerClass) {
18323
+ peekTextNode.classList.add(desiredContainerClass);
18324
+ peekTextNode.dataset.personaPeekStreamClass = desiredContainerClass;
18325
+ }
18326
+ if (animationActive) {
18327
+ peekTextNode.style.setProperty(
18328
+ "--persona-stream-step",
18329
+ `${streamAnimation.speed}ms`
18330
+ );
18331
+ peekTextNode.style.setProperty(
18332
+ "--persona-stream-duration",
18333
+ `${streamAnimation.duration}ms`
18334
+ );
18335
+ } else {
18336
+ peekTextNode.style.removeProperty("--persona-stream-step");
18337
+ peekTextNode.style.removeProperty("--persona-stream-duration");
18338
+ }
18339
+ const buffered = animationActive ? applyStreamBuffer(text, streamAnimation.buffer, plugin, lastAssistant, streaming) : text;
18340
+ const skeletonEnabled = animationActive && streamAnimation.placeholder === "skeleton";
18341
+ const showSkeletonOnly = skeletonEnabled && streaming && (!buffered || !buffered.trim());
18342
+ if (showSkeletonOnly) {
18343
+ const tempContainer = document.createElement("div");
18344
+ const skeleton = createSkeletonPlaceholder();
18345
+ skeleton.classList.add("persona-pill-peek__skeleton");
18346
+ tempContainer.appendChild(skeleton);
18347
+ morphMessages(peekTextNode, tempContainer);
18348
+ } else {
18349
+ const sliceStart = Math.max(0, buffered.length - 100);
18350
+ const slice = buffered.length > 100 ? buffered.slice(-100) : buffered;
18351
+ const escaped = escapeHtml(slice);
18352
+ if (!animationActive || !plugin) {
18353
+ const preview = buffered.length > 100 ? `\u2026${slice}` : slice;
18354
+ if (peekTextNode.textContent !== preview) {
18355
+ peekTextNode.textContent = preview;
18356
+ }
18357
+ } else {
18358
+ let html = escaped;
18359
+ if (plugin.wrap === "char" || plugin.wrap === "word") {
18360
+ html = wrapStreamAnimation(
18361
+ escaped,
18362
+ plugin.wrap,
18363
+ // Namespace span IDs to the peek surface so they don't collide
18364
+ // with the main bubble's spans for the same message id.
18365
+ `peek-${lastAssistant.id}`,
18366
+ { skipTags: plugin.skipTags, startIndex: sliceStart }
18367
+ );
18368
+ }
18369
+ const tempContainer = document.createElement("div");
18370
+ tempContainer.innerHTML = html;
18371
+ if (plugin.useCaret && slice.length > 0) {
18372
+ const caret = createStreamCaret();
18373
+ const spans = tempContainer.querySelectorAll(
18374
+ ".persona-stream-char, .persona-stream-word"
18375
+ );
18376
+ const lastSpan = spans[spans.length - 1];
18377
+ if (lastSpan == null ? void 0 : lastSpan.parentNode) {
18378
+ lastSpan.parentNode.insertBefore(caret, lastSpan.nextSibling);
18379
+ } else {
18380
+ tempContainer.appendChild(caret);
18381
+ }
18382
+ }
18383
+ morphMessages(peekTextNode, tempContainer);
18384
+ (_d2 = plugin.onAfterRender) == null ? void 0 : _d2.call(plugin, {
18385
+ container: peekTextNode,
18386
+ bubble: peekBanner,
18387
+ messageId: lastAssistant.id,
18388
+ message: lastAssistant,
18389
+ speed: streamAnimation.speed,
18390
+ duration: streamAnimation.duration
18391
+ });
18392
+ }
18393
+ }
18394
+ const shouldShow = isStreaming || composerHovered;
18395
+ peekBanner.classList.toggle("persona-pill-peek--visible", shouldShow);
18396
+ };
18397
+ if (isComposerBar()) {
18398
+ const peekBanner = panelElements.peekBanner;
18399
+ if (peekBanner) {
18400
+ const onPeekPointerDown = (e) => {
18401
+ e.preventDefault();
18402
+ e.stopPropagation();
18403
+ setOpenState(true, "user");
18404
+ };
18405
+ peekBanner.addEventListener("pointerdown", onPeekPointerDown);
18406
+ destroyCallbacks.push(() => {
18407
+ peekBanner.removeEventListener("pointerdown", onPeekPointerDown);
18408
+ });
18409
+ }
18410
+ const onPanelPointerEnter = () => {
18411
+ if (composerHovered) return;
18412
+ composerHovered = true;
18413
+ syncComposerBarPeek();
18414
+ };
18415
+ const onPanelPointerLeave = () => {
18416
+ if (!composerHovered) return;
18417
+ composerHovered = false;
18418
+ syncComposerBarPeek();
18419
+ };
18420
+ panel.addEventListener("pointerenter", onPanelPointerEnter);
18421
+ panel.addEventListener("pointerleave", onPanelPointerLeave);
18422
+ destroyCallbacks.push(() => {
18423
+ panel.removeEventListener("pointerenter", onPanelPointerEnter);
18424
+ panel.removeEventListener("pointerleave", onPanelPointerLeave);
18425
+ });
18426
+ if (pillRoot) {
18427
+ pillRoot.addEventListener("pointerenter", onPanelPointerEnter);
18428
+ pillRoot.addEventListener("pointerleave", onPanelPointerLeave);
18429
+ destroyCallbacks.push(() => {
18430
+ pillRoot.removeEventListener("pointerenter", onPanelPointerEnter);
18431
+ pillRoot.removeEventListener("pointerleave", onPanelPointerLeave);
18432
+ });
18433
+ }
18434
+ }
18435
+ const applyComposerBarGeometry = (isOpen) => {
18436
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18437
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
18438
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
18439
+ const bottomOffset = (_d2 = cb.bottomOffset) != null ? _d2 : "16px";
18440
+ const collapsedMaxWidth = cb.collapsedMaxWidth;
18441
+ const expandedMaxWidth = (_e2 = cb.expandedMaxWidth) != null ? _e2 : "880px";
18442
+ const expandedTopOffset = (_f2 = cb.expandedTopOffset) != null ? _f2 : "5vh";
18443
+ const modalMaxWidth = (_g2 = cb.modalMaxWidth) != null ? _g2 : "880px";
18444
+ const modalMaxHeight = (_h2 = cb.modalMaxHeight) != null ? _h2 : "min(90vh, 800px)";
18445
+ const viewportClamp = "calc(100vw - 32px)";
18446
+ const pillAreaClearance = "var(--persona-pill-area-height, 80px)";
18447
+ const s = wrapper.style;
18448
+ s.left = "";
18449
+ s.right = "";
18450
+ s.top = "";
18451
+ s.bottom = "";
18452
+ s.transform = "";
18453
+ s.width = "";
18454
+ s.maxWidth = "";
18455
+ s.height = "";
18456
+ s.maxHeight = "";
18457
+ if (pillRoot) {
18458
+ const ps = pillRoot.style;
18459
+ ps.bottom = bottomOffset;
18460
+ ps.width = collapsedMaxWidth != null ? collapsedMaxWidth : "";
18461
+ }
18462
+ if (!isOpen) {
18463
+ return;
18464
+ }
18465
+ if (expandedSize === "fullscreen") {
18466
+ return;
18467
+ }
18468
+ if (expandedSize === "modal") {
18469
+ s.top = "50%";
18470
+ s.left = "50%";
18471
+ s.transform = "translate(-50%, -50%)";
18472
+ s.bottom = "auto";
18473
+ s.right = "auto";
18474
+ s.width = modalMaxWidth;
18475
+ s.maxWidth = viewportClamp;
18476
+ s.maxHeight = modalMaxHeight;
18477
+ s.height = modalMaxHeight;
18478
+ return;
18479
+ }
18480
+ s.left = "50%";
18481
+ s.transform = "translateX(-50%)";
18482
+ s.bottom = `calc(${bottomOffset} + ${pillAreaClearance})`;
18483
+ s.top = expandedTopOffset;
18484
+ s.width = expandedMaxWidth;
18485
+ s.maxWidth = viewportClamp;
18486
+ };
17607
18487
  const updateOpenState = () => {
17608
- var _a2, _b2, _c2, _d2, _e2;
17609
- if (!launcherEnabled) return;
18488
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18489
+ if (!isPanelToggleable()) return;
18490
+ if (isComposerBar()) {
18491
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
18492
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
18493
+ const nextState = open ? "expanded" : "collapsed";
18494
+ wrapper.dataset.state = nextState;
18495
+ wrapper.dataset.expandedSize = expandedSize;
18496
+ if (pillRoot) {
18497
+ pillRoot.dataset.state = nextState;
18498
+ pillRoot.dataset.expandedSize = expandedSize;
18499
+ }
18500
+ wrapper.style.removeProperty("display");
18501
+ wrapper.classList.remove("persona-pointer-events-none", "persona-opacity-0");
18502
+ panel.classList.remove(
18503
+ "persona-scale-95",
18504
+ "persona-opacity-0",
18505
+ "persona-scale-100",
18506
+ "persona-opacity-100"
18507
+ );
18508
+ applyComposerBarGeometry(open);
18509
+ container.style.display = open ? "flex" : "none";
18510
+ applyFullHeightStyles();
18511
+ if (open) {
18512
+ attachComposerBarOutsideClickDismiss();
18513
+ attachComposerBarEscapeDismiss();
18514
+ } else {
18515
+ detachComposerBarOutsideClickDismiss();
18516
+ detachComposerBarEscapeDismiss();
18517
+ }
18518
+ syncComposerBarPeek();
18519
+ return;
18520
+ }
17610
18521
  const dockedMode = isDockedMountMode(config);
17611
- const ownerWindow2 = (_a2 = mount.ownerDocument.defaultView) != null ? _a2 : window;
17612
- const mobileBreakpoint = (_c2 = (_b2 = config.launcher) == null ? void 0 : _b2.mobileBreakpoint) != null ? _c2 : 640;
17613
- const mobileFullscreen = (_e2 = (_d2 = config.launcher) == null ? void 0 : _d2.mobileFullscreen) != null ? _e2 : true;
18522
+ const ownerWindow2 = (_d2 = mount.ownerDocument.defaultView) != null ? _d2 : window;
18523
+ const mobileBreakpoint = (_f2 = (_e2 = config.launcher) == null ? void 0 : _e2.mobileBreakpoint) != null ? _f2 : 640;
18524
+ const mobileFullscreen = (_h2 = (_g2 = config.launcher) == null ? void 0 : _g2.mobileFullscreen) != null ? _h2 : true;
17614
18525
  const isMobileViewport = ownerWindow2.innerWidth <= mobileBreakpoint;
17615
18526
  const shouldGoFullscreen = mobileFullscreen && isMobileViewport && launcherEnabled;
17616
18527
  const dockReveal = resolveDockConfig(config).reveal;
@@ -17653,20 +18564,21 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17653
18564
  };
17654
18565
  const setOpenState = (nextOpen, source = "user") => {
17655
18566
  var _a2, _b2;
17656
- if (!launcherEnabled) return;
18567
+ if (!isPanelToggleable()) return;
17657
18568
  if (open === nextOpen) return;
17658
18569
  const prevOpen = open;
17659
18570
  open = nextOpen;
17660
18571
  updateOpenState();
17661
18572
  const isViewportCovering = (() => {
17662
- var _a3, _b3, _c2, _d2, _e2, _f2, _g2;
18573
+ var _a3, _b3, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2;
17663
18574
  const sm = (_b3 = (_a3 = config.launcher) == null ? void 0 : _a3.sidebarMode) != null ? _b3 : false;
17664
18575
  const ow = (_c2 = mount.ownerDocument.defaultView) != null ? _c2 : window;
17665
18576
  const mf = (_e2 = (_d2 = config.launcher) == null ? void 0 : _d2.mobileFullscreen) != null ? _e2 : true;
17666
18577
  const mb = (_g2 = (_f2 = config.launcher) == null ? void 0 : _f2.mobileBreakpoint) != null ? _g2 : 640;
17667
18578
  const isMobile = ow.innerWidth <= mb;
17668
18579
  const dockedMF = isDockedMountMode(config) && mf && isMobile;
17669
- return sm || mf && isMobile && launcherEnabled || dockedMF;
18580
+ const composerBarFS = isComposerBar() && ((_j2 = (_i2 = (_h2 = config.launcher) == null ? void 0 : _h2.composerBar) == null ? void 0 : _i2.expandedSize) != null ? _j2 : "fullscreen") === "fullscreen";
18581
+ return sm || mf && isMobile && launcherEnabled || dockedMF || composerBarFS;
17670
18582
  })();
17671
18583
  if (open && isViewportCovering) {
17672
18584
  if (!teardownHostStacking) {
@@ -17811,6 +18723,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17811
18723
  }
17812
18724
  voiceState.lastUserMessageWasVoice = Boolean(lastUserMessage == null ? void 0 : lastUserMessage.viaVoice);
17813
18725
  persistState(messages);
18726
+ syncComposerBarPeek();
17814
18727
  },
17815
18728
  onStatusChanged(status) {
17816
18729
  var _a2;
@@ -17834,6 +18747,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17834
18747
  if (!streaming) {
17835
18748
  scheduleAutoScroll(true);
17836
18749
  }
18750
+ syncComposerBarPeek();
17837
18751
  },
17838
18752
  onVoiceStatusChanged(status) {
17839
18753
  var _a2, _b2;
@@ -17870,7 +18784,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17870
18784
  }
17871
18785
  });
17872
18786
  sessionRef.current = session;
17873
- if (((_J = (_I = config.voiceRecognition) == null ? void 0 : _I.provider) == null ? void 0 : _J.type) === "runtype") {
18787
+ if (((_N = (_M = config.voiceRecognition) == null ? void 0 : _M.provider) == null ? void 0 : _N.type) === "runtype") {
17874
18788
  try {
17875
18789
  session.setupVoice();
17876
18790
  } catch (err) {
@@ -17921,6 +18835,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17921
18835
  }
17922
18836
  });
17923
18837
  }
18838
+ const maybeExpandComposerBar = () => {
18839
+ var _a2, _b2, _c2;
18840
+ if (!isComposerBar()) return;
18841
+ if (open) return;
18842
+ const expandOnSubmit = (_c2 = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) == null ? void 0 : _b2.expandOnSubmit) != null ? _c2 : true;
18843
+ if (!expandOnSubmit) return;
18844
+ setOpenState(true, "auto");
18845
+ };
17924
18846
  const handleSubmit = (event) => {
17925
18847
  var _a2;
17926
18848
  event.preventDefault();
@@ -17931,6 +18853,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17931
18853
  const value = textarea.value.trim();
17932
18854
  const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
17933
18855
  if (!value && !hasAttachments) return;
18856
+ maybeExpandComposerBar();
17934
18857
  let contentParts;
17935
18858
  if (hasAttachments) {
17936
18859
  contentParts = [];
@@ -18096,7 +19019,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18096
19019
  micButton.setAttribute("aria-label", "Start voice recognition");
18097
19020
  }
18098
19021
  };
18099
- const createMicButton = (voiceConfig, sendButtonConfig) => {
19022
+ const createMicButton2 = (voiceConfig, sendButtonConfig) => {
18100
19023
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18101
19024
  const hasSpeechRecognition = typeof window !== "undefined" && (typeof window.webkitSpeechRecognition !== "undefined" || typeof window.SpeechRecognition !== "undefined");
18102
19025
  const hasRuntypeProvider = ((_a2 = voiceConfig == null ? void 0 : voiceConfig.provider) == null ? void 0 : _a2.type) === "runtype";
@@ -18373,7 +19296,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18373
19296
  };
18374
19297
  let launcherButtonInstance = null;
18375
19298
  let customLauncherElement = null;
18376
- if (launcherEnabled) {
19299
+ if (launcherEnabled && !isComposerBar()) {
18377
19300
  const launcherPlugin = plugins.find((p) => p.renderLauncher);
18378
19301
  if (launcherPlugin == null ? void 0 : launcherPlugin.renderLauncher) {
18379
19302
  const customLauncher = launcherPlugin.renderLauncher({
@@ -18404,7 +19327,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18404
19327
  scheduleAutoScroll(true);
18405
19328
  maybeRestoreVoiceFromMetadata();
18406
19329
  if (autoFocusInput) {
18407
- if (!launcherEnabled) {
19330
+ if (!launcherEnabled || isComposerBar()) {
18408
19331
  setTimeout(() => maybeFocusInput(), 0);
18409
19332
  } else if (open) {
18410
19333
  setTimeout(() => maybeFocusInput(), 200);
@@ -18412,6 +19335,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18412
19335
  }
18413
19336
  const recalcPanelHeight = () => {
18414
19337
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2;
19338
+ if (isComposerBar()) {
19339
+ updateScrollToBottomButtonOffset();
19340
+ updateOpenState();
19341
+ return;
19342
+ }
18415
19343
  const dockedMode = isDockedMountMode(config);
18416
19344
  const sidebarMode = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.sidebarMode) != null ? _b2 : false;
18417
19345
  const fullHeight = dockedMode || sidebarMode || ((_d2 = (_c2 = config.launcher) == null ? void 0 : _c2.fullHeight) != null ? _d2 : false);
@@ -18482,7 +19410,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18482
19410
  }
18483
19411
  };
18484
19412
  recalcPanelHeight();
18485
- const ownerWindow = (_K = mount.ownerDocument.defaultView) != null ? _K : window;
19413
+ const ownerWindow = (_O = mount.ownerDocument.defaultView) != null ? _O : window;
18486
19414
  ownerWindow.addEventListener("resize", recalcPanelHeight);
18487
19415
  destroyCallbacks.push(() => ownerWindow.removeEventListener("resize", recalcPanelHeight));
18488
19416
  if (typeof ResizeObserver !== "undefined") {
@@ -18552,7 +19480,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18552
19480
  closeButton.removeEventListener("click", closeHandler);
18553
19481
  closeHandler = null;
18554
19482
  }
18555
- if (launcherEnabled) {
19483
+ if (isPanelToggleable()) {
18556
19484
  closeButton.style.display = "";
18557
19485
  closeHandler = () => {
18558
19486
  setOpenState(false, "user");
@@ -18706,7 +19634,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18706
19634
  }
18707
19635
  const controller = {
18708
19636
  update(nextConfig) {
18709
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, _I2, _J2, _K2, _L2, _M2, _N2, _O2, _P2, _Q2, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab;
19637
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, _I2, _J2, _K2, _L2, _M2, _N2, _O2, _P2, _Q2, _R2, _S2, _T2, _U2, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb;
18710
19638
  const previousToolCallConfig = config.toolCall;
18711
19639
  const previousMessageActions = config.messageActions;
18712
19640
  const previousLayoutMessages = (_a2 = config.layout) == null ? void 0 : _a2.messages;
@@ -18836,11 +19764,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18836
19764
  const headerLayoutChanged = (headerLayoutConfig == null ? void 0 : headerLayoutConfig.layout) !== prevHeaderLayout;
18837
19765
  if (headerLayoutChanged && header) {
18838
19766
  const newHeaderElements = headerLayoutConfig ? buildHeaderWithLayout(config, headerLayoutConfig, {
18839
- showClose: launcherEnabled,
19767
+ showClose: isPanelToggleable(),
18840
19768
  onClose: () => setOpenState(false, "user")
18841
19769
  }) : buildHeader({
18842
19770
  config,
18843
- showClose: launcherEnabled,
19771
+ showClose: isPanelToggleable(),
18844
19772
  onClose: () => setOpenState(false, "user")
18845
19773
  });
18846
19774
  header.replaceWith(newHeaderElements.header);
@@ -18970,7 +19898,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18970
19898
  if (existingSvg || existingImg) {
18971
19899
  iconHolder.replaceChildren();
18972
19900
  }
18973
- iconHolder.textContent = (_R = launcher.agentIconText) != null ? _R : "\u{1F4AC}";
19901
+ iconHolder.textContent = (_R2 = launcher.agentIconText) != null ? _R2 : "\u{1F4AC}";
18974
19902
  }
18975
19903
  const img = iconHolder.querySelector("img");
18976
19904
  if (img) {
@@ -18979,8 +19907,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18979
19907
  }
18980
19908
  }
18981
19909
  }
18982
- const layoutShowTitle = (_T = (_S = config.layout) == null ? void 0 : _S.header) == null ? void 0 : _T.showTitle;
18983
- const layoutShowSubtitle = (_V = (_U = config.layout) == null ? void 0 : _U.header) == null ? void 0 : _V.showSubtitle;
19910
+ const layoutShowTitle = (_T2 = (_S2 = config.layout) == null ? void 0 : _S2.header) == null ? void 0 : _T2.showTitle;
19911
+ const layoutShowSubtitle = (_V = (_U2 = config.layout) == null ? void 0 : _U2.header) == null ? void 0 : _V.showSubtitle;
18984
19912
  if (headerTitle) {
18985
19913
  headerTitle.style.display = layoutShowTitle === false ? "none" : "";
18986
19914
  }
@@ -19130,7 +20058,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19130
20058
  if (clearChatButtonWrapper) {
19131
20059
  clearChatButtonWrapper.style.display = shouldShowClearChat ? "" : "none";
19132
20060
  const { closeButtonWrapper } = panelElements;
19133
- if (closeButtonWrapper && !closeButtonWrapper.classList.contains("persona-absolute")) {
20061
+ if (!isComposerBar() && closeButtonWrapper && !closeButtonWrapper.classList.contains("persona-absolute")) {
19134
20062
  if (shouldShowClearChat) {
19135
20063
  closeButtonWrapper.classList.remove("persona-ml-auto");
19136
20064
  } else {
@@ -19139,7 +20067,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19139
20067
  }
19140
20068
  const isTopRight = clearChatPlacement === "top-right";
19141
20069
  const currentlyTopRight = clearChatButtonWrapper.classList.contains("persona-absolute");
19142
- if (isTopRight !== currentlyTopRight && shouldShowClearChat) {
20070
+ if (!isComposerBar() && isTopRight !== currentlyTopRight && shouldShowClearChat) {
19143
20071
  clearChatButtonWrapper.remove();
19144
20072
  if (isTopRight) {
19145
20073
  clearChatButtonWrapper.className = "persona-absolute persona-top-4 persona-z-50";
@@ -19168,14 +20096,17 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19168
20096
  }
19169
20097
  }
19170
20098
  if (shouldShowClearChat) {
19171
- const clearChatSize = (_la = clearChatConfig.size) != null ? _la : "32px";
19172
- clearChatButton.style.height = clearChatSize;
19173
- clearChatButton.style.width = clearChatSize;
20099
+ if (!isComposerBar()) {
20100
+ const clearChatSize = (_la = clearChatConfig.size) != null ? _la : "32px";
20101
+ clearChatButton.style.height = clearChatSize;
20102
+ clearChatButton.style.width = clearChatSize;
20103
+ }
19174
20104
  const clearChatIconName = (_ma = clearChatConfig.iconName) != null ? _ma : "refresh-cw";
19175
20105
  const clearChatIconColor = (_na = clearChatConfig.iconColor) != null ? _na : "";
19176
20106
  clearChatButton.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
19177
20107
  clearChatButton.innerHTML = "";
19178
- const iconSvg = renderLucideIcon(clearChatIconName, "20px", "currentColor", 2);
20108
+ const clearChatIconSize = isComposerBar() ? "14px" : "20px";
20109
+ const iconSvg = renderLucideIcon(clearChatIconName, clearChatIconSize, "currentColor", 2);
19179
20110
  if (iconSvg) {
19180
20111
  clearChatButton.appendChild(iconSvg);
19181
20112
  }
@@ -19299,7 +20230,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19299
20230
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
19300
20231
  if (voiceRecognitionEnabled && hasVoiceInput) {
19301
20232
  if (!micButton || !micButtonWrapper) {
19302
- const micButtonResult = createMicButton(config.voiceRecognition, config.sendButton);
20233
+ const micButtonResult = createMicButton2(config.voiceRecognition, config.sendButton);
19303
20234
  if (micButtonResult) {
19304
20235
  micButton = micButtonResult.micButton;
19305
20236
  micButtonWrapper = micButtonResult.micButtonWrapper;
@@ -19596,7 +20527,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19596
20527
  } else if (tooltip) {
19597
20528
  tooltip.style.display = "none";
19598
20529
  }
19599
- const updatedContentMaxWidth = (__a = config.layout) == null ? void 0 : __a.contentMaxWidth;
20530
+ const updatedContentMaxWidth = (_cb = (__a = config.layout) == null ? void 0 : __a.contentMaxWidth) != null ? _cb : isComposerBar() ? (_bb = (_ab = (_$a = config.launcher) == null ? void 0 : _$a.composerBar) == null ? void 0 : _ab.contentMaxWidth) != null ? _bb : "720px" : void 0;
19600
20531
  if (updatedContentMaxWidth) {
19601
20532
  messagesWrapper.style.maxWidth = updatedContentMaxWidth;
19602
20533
  messagesWrapper.style.marginLeft = "auto";
@@ -19628,8 +20559,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19628
20559
  suggestions.style.marginRight = "";
19629
20560
  }
19630
20561
  }
19631
- const statusIndicatorConfig = (_$a = config.statusIndicator) != null ? _$a : {};
19632
- const isVisible = (_ab = statusIndicatorConfig.visible) != null ? _ab : true;
20562
+ const statusIndicatorConfig = (_db = config.statusIndicator) != null ? _db : {};
20563
+ const isVisible = (_eb = statusIndicatorConfig.visible) != null ? _eb : true;
19633
20564
  statusText.style.display = isVisible ? "" : "none";
19634
20565
  if (session) {
19635
20566
  const currentStatus = session.getStatus();
@@ -19648,15 +20579,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19648
20579
  statusText.classList.add(alignClass);
19649
20580
  },
19650
20581
  open() {
19651
- if (!launcherEnabled) return;
20582
+ if (!isPanelToggleable()) return;
19652
20583
  setOpenState(true, "api");
19653
20584
  },
19654
20585
  close() {
19655
- if (!launcherEnabled) return;
20586
+ if (!isPanelToggleable()) return;
19656
20587
  setOpenState(false, "api");
19657
20588
  },
19658
20589
  toggle() {
19659
- if (!launcherEnabled) return;
20590
+ if (!isPanelToggleable()) return;
19660
20591
  setOpenState(!open, "api");
19661
20592
  },
19662
20593
  clearChat() {
@@ -19710,7 +20641,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19710
20641
  setMessage(message) {
19711
20642
  if (!textarea) return false;
19712
20643
  if (session.isStreaming()) return false;
19713
- if (!open && launcherEnabled) {
20644
+ if (!open && isPanelToggleable()) {
19714
20645
  setOpenState(true, "system");
19715
20646
  }
19716
20647
  textarea.value = message;
@@ -19721,7 +20652,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19721
20652
  if (session.isStreaming()) return false;
19722
20653
  const valueToSubmit = (message == null ? void 0 : message.trim()) || textarea.value.trim();
19723
20654
  if (!valueToSubmit) return false;
19724
- if (!open && launcherEnabled) {
20655
+ if (!open && isPanelToggleable()) {
19725
20656
  setOpenState(true, "system");
19726
20657
  }
19727
20658
  textarea.value = "";
@@ -19734,7 +20665,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19734
20665
  if (session.isStreaming()) return false;
19735
20666
  if (((_b2 = (_a2 = config.voiceRecognition) == null ? void 0 : _a2.provider) == null ? void 0 : _b2.type) === "runtype") {
19736
20667
  if (session.isVoiceActive()) return true;
19737
- if (!open && launcherEnabled) setOpenState(true, "system");
20668
+ if (!open && isPanelToggleable()) setOpenState(true, "system");
19738
20669
  voiceState.manuallyDeactivated = false;
19739
20670
  persistVoiceMetadata();
19740
20671
  session.toggleVoice().then(() => {
@@ -19747,7 +20678,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19747
20678
  if (isRecording) return true;
19748
20679
  const SpeechRecognitionClass = getSpeechRecognitionClass();
19749
20680
  if (!SpeechRecognitionClass) return false;
19750
- if (!open && launcherEnabled) setOpenState(true, "system");
20681
+ if (!open && isPanelToggleable()) setOpenState(true, "system");
19751
20682
  voiceState.manuallyDeactivated = false;
19752
20683
  persistVoiceMetadata();
19753
20684
  startVoiceRecognition("user");
@@ -19773,13 +20704,13 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19773
20704
  return true;
19774
20705
  },
19775
20706
  injectMessage(options) {
19776
- if (!open && launcherEnabled) {
20707
+ if (!open && isPanelToggleable()) {
19777
20708
  setOpenState(true, "system");
19778
20709
  }
19779
20710
  return session.injectMessage(options);
19780
20711
  },
19781
20712
  injectAssistantMessage(options) {
19782
- if (!open && launcherEnabled) {
20713
+ if (!open && isPanelToggleable()) {
19783
20714
  setOpenState(true, "system");
19784
20715
  }
19785
20716
  const result = session.injectAssistantMessage(options);
@@ -19798,26 +20729,26 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19798
20729
  return result;
19799
20730
  },
19800
20731
  injectUserMessage(options) {
19801
- if (!open && launcherEnabled) {
20732
+ if (!open && isPanelToggleable()) {
19802
20733
  setOpenState(true, "system");
19803
20734
  }
19804
20735
  return session.injectUserMessage(options);
19805
20736
  },
19806
20737
  injectSystemMessage(options) {
19807
- if (!open && launcherEnabled) {
20738
+ if (!open && isPanelToggleable()) {
19808
20739
  setOpenState(true, "system");
19809
20740
  }
19810
20741
  return session.injectSystemMessage(options);
19811
20742
  },
19812
20743
  injectMessageBatch(optionsList) {
19813
- if (!open && launcherEnabled) {
20744
+ if (!open && isPanelToggleable()) {
19814
20745
  setOpenState(true, "system");
19815
20746
  }
19816
20747
  return session.injectMessageBatch(optionsList);
19817
20748
  },
19818
20749
  /** @deprecated Use injectMessage() instead */
19819
20750
  injectTestMessage(event) {
19820
- if (!open && launcherEnabled) {
20751
+ if (!open && isPanelToggleable()) {
19821
20752
  setOpenState(true, "system");
19822
20753
  }
19823
20754
  session.injectTestEvent(event);
@@ -19880,7 +20811,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19880
20811
  return (_a2 = session == null ? void 0 : session.getSelectedArtifactId()) != null ? _a2 : null;
19881
20812
  },
19882
20813
  focusInput() {
19883
- if (launcherEnabled && !open) return false;
20814
+ if (launcherEnabled && !open && !isComposerBar()) return false;
19884
20815
  if (!textarea) return false;
19885
20816
  textarea.focus();
19886
20817
  return true;
@@ -19918,14 +20849,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19918
20849
  },
19919
20850
  // State query methods
19920
20851
  isOpen() {
19921
- return launcherEnabled && open;
20852
+ return isPanelToggleable() && open;
19922
20853
  },
19923
20854
  isVoiceActive() {
19924
20855
  return voiceState.active;
19925
20856
  },
19926
20857
  getState() {
19927
20858
  return {
19928
- open: launcherEnabled && open,
20859
+ open: isPanelToggleable() && open,
19929
20860
  launcherEnabled,
19930
20861
  voiceActive: voiceState.active,
19931
20862
  streaming: session.isStreaming()
@@ -19933,7 +20864,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19933
20864
  },
19934
20865
  // Feedback methods (CSAT/NPS)
19935
20866
  showCSATFeedback(options) {
19936
- if (!open && launcherEnabled) {
20867
+ if (!open && isPanelToggleable()) {
19937
20868
  setOpenState(true, "system");
19938
20869
  }
19939
20870
  const existingFeedback = messagesWrapper.querySelector(".persona-feedback-container");
@@ -19955,7 +20886,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19955
20886
  feedbackEl.scrollIntoView({ behavior: "smooth", block: "end" });
19956
20887
  },
19957
20888
  showNPSFeedback(options) {
19958
- if (!open && launcherEnabled) {
20889
+ if (!open && isPanelToggleable()) {
19959
20890
  setOpenState(true, "system");
19960
20891
  }
19961
20892
  const existingFeedback = messagesWrapper.querySelector(".persona-feedback-container");
@@ -19989,6 +20920,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19989
20920
  }
19990
20921
  destroyCallbacks.forEach((cb) => cb());
19991
20922
  wrapper.remove();
20923
+ pillRoot == null ? void 0 : pillRoot.remove();
19992
20924
  launcherButtonInstance == null ? void 0 : launcherButtonInstance.destroy();
19993
20925
  customLauncherElement == null ? void 0 : customLauncherElement.remove();
19994
20926
  if (closeHandler) {
@@ -19996,7 +20928,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19996
20928
  }
19997
20929
  }
19998
20930
  };
19999
- const shouldExposeDebugApi = ((_L = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _L : false) || Boolean(config.debug);
20931
+ const shouldExposeDebugApi = ((_P = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _P : false) || Boolean(config.debug);
20000
20932
  if (shouldExposeDebugApi && typeof window !== "undefined") {
20001
20933
  const previousDebug = window.AgentWidgetBrowser;
20002
20934
  const debugApi = {
@@ -20093,15 +21025,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20093
21025
  });
20094
21026
  }
20095
21027
  const persistConfig = normalizePersistStateConfig(config.persistState);
20096
- if (persistConfig && launcherEnabled) {
21028
+ if (persistConfig && isPanelToggleable()) {
20097
21029
  const storage = getPersistStorage(persistConfig.storage);
20098
21030
  const openKey = `${persistConfig.keyPrefix}widget-open`;
20099
21031
  const voiceKey = `${persistConfig.keyPrefix}widget-voice`;
20100
21032
  const voiceModeKey = `${persistConfig.keyPrefix}widget-voice-mode`;
20101
21033
  if (storage) {
20102
- const wasOpen = ((_M = persistConfig.persist) == null ? void 0 : _M.openState) && storage.getItem(openKey) === "true";
20103
- const wasVoiceActive = ((_N = persistConfig.persist) == null ? void 0 : _N.voiceState) && storage.getItem(voiceKey) === "true";
20104
- const wasInVoiceMode = ((_O = persistConfig.persist) == null ? void 0 : _O.voiceState) && storage.getItem(voiceModeKey) === "true";
21034
+ const wasOpen = ((_Q = persistConfig.persist) == null ? void 0 : _Q.openState) && storage.getItem(openKey) === "true";
21035
+ const wasVoiceActive = ((_R = persistConfig.persist) == null ? void 0 : _R.voiceState) && storage.getItem(voiceKey) === "true";
21036
+ const wasInVoiceMode = ((_S = persistConfig.persist) == null ? void 0 : _S.voiceState) && storage.getItem(voiceModeKey) === "true";
20105
21037
  if (wasOpen) {
20106
21038
  setTimeout(() => {
20107
21039
  controller.open();
@@ -20118,7 +21050,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20118
21050
  }, 100);
20119
21051
  }, 0);
20120
21052
  }
20121
- if ((_P = persistConfig.persist) == null ? void 0 : _P.openState) {
21053
+ if ((_T = persistConfig.persist) == null ? void 0 : _T.openState) {
20122
21054
  eventBus.on("widget:opened", () => {
20123
21055
  storage.setItem(openKey, "true");
20124
21056
  });
@@ -20126,7 +21058,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20126
21058
  storage.setItem(openKey, "false");
20127
21059
  });
20128
21060
  }
20129
- if ((_Q = persistConfig.persist) == null ? void 0 : _Q.voiceState) {
21061
+ if ((_U = persistConfig.persist) == null ? void 0 : _U.voiceState) {
20130
21062
  eventBus.on("voice:state", (event) => {
20131
21063
  storage.setItem(voiceKey, event.active ? "true" : "false");
20132
21064
  });
@@ -20148,11 +21080,12 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20148
21080
  }
20149
21081
  }
20150
21082
  }
20151
- if (shouldOpenAfterStateLoaded && launcherEnabled) {
21083
+ if (shouldOpenAfterStateLoaded && isPanelToggleable()) {
20152
21084
  setTimeout(() => {
20153
21085
  controller.open();
20154
21086
  }, 0);
20155
21087
  }
21088
+ syncComposerBarPeek();
20156
21089
  return controller;
20157
21090
  };
20158
21091