@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
@@ -8289,25 +8289,146 @@ var createElementInDocument = (documentRef, tag, className) => {
8289
8289
  };
8290
8290
 
8291
8291
  // src/utils/icons.ts
8292
- var icons = __toESM(require("lucide"), 1);
8292
+ var import_lucide = require("lucide");
8293
+ var LUCIDE_ICONS = {
8294
+ // Mandatory
8295
+ "activity": import_lucide.Activity,
8296
+ "arrow-down": import_lucide.ArrowDown,
8297
+ "arrow-up": import_lucide.ArrowUp,
8298
+ "arrow-up-right": import_lucide.ArrowUpRight,
8299
+ "bot": import_lucide.Bot,
8300
+ "chevron-down": import_lucide.ChevronDown,
8301
+ "chevron-up": import_lucide.ChevronUp,
8302
+ "chevron-right": import_lucide.ChevronRight,
8303
+ "chevron-left": import_lucide.ChevronLeft,
8304
+ "check": import_lucide.Check,
8305
+ "clipboard": import_lucide.Clipboard,
8306
+ "clipboard-copy": import_lucide.ClipboardCopy,
8307
+ "copy": import_lucide.Copy,
8308
+ "file": import_lucide.File,
8309
+ "file-code": import_lucide.FileCode,
8310
+ "file-spreadsheet": import_lucide.FileSpreadsheet,
8311
+ "file-text": import_lucide.FileText,
8312
+ "image-plus": import_lucide.ImagePlus,
8313
+ "loader": import_lucide.Loader,
8314
+ "loader-circle": import_lucide.LoaderCircle,
8315
+ "mic": import_lucide.Mic,
8316
+ "paperclip": import_lucide.Paperclip,
8317
+ "refresh-cw": import_lucide.RefreshCw,
8318
+ "search": import_lucide.Search,
8319
+ "send": import_lucide.Send,
8320
+ "shield-alert": import_lucide.ShieldAlert,
8321
+ "shield-check": import_lucide.ShieldCheck,
8322
+ "shield-x": import_lucide.ShieldX,
8323
+ "square": import_lucide.Square,
8324
+ "thumbs-down": import_lucide.ThumbsDown,
8325
+ "thumbs-up": import_lucide.ThumbsUp,
8326
+ "upload": import_lucide.Upload,
8327
+ "volume-2": import_lucide.Volume2,
8328
+ "x": import_lucide.X,
8329
+ // Forms / inputs
8330
+ "user": import_lucide.User,
8331
+ "mail": import_lucide.Mail,
8332
+ "phone": import_lucide.Phone,
8333
+ "calendar": import_lucide.Calendar,
8334
+ "clock": import_lucide.Clock,
8335
+ "building": import_lucide.Building,
8336
+ "map-pin": import_lucide.MapPin,
8337
+ "lock": import_lucide.Lock,
8338
+ "key": import_lucide.Key,
8339
+ "credit-card": import_lucide.CreditCard,
8340
+ "at-sign": import_lucide.AtSign,
8341
+ "hash": import_lucide.Hash,
8342
+ "globe": import_lucide.Globe,
8343
+ "link": import_lucide.Link,
8344
+ // Status / feedback
8345
+ "circle-check": import_lucide.CircleCheck,
8346
+ "circle-x": import_lucide.CircleX,
8347
+ "triangle-alert": import_lucide.TriangleAlert,
8348
+ "info": import_lucide.Info,
8349
+ "ban": import_lucide.Ban,
8350
+ "shield": import_lucide.Shield,
8351
+ // Navigation
8352
+ "arrow-left": import_lucide.ArrowLeft,
8353
+ "arrow-right": import_lucide.ArrowRight,
8354
+ "external-link": import_lucide.ExternalLink,
8355
+ "ellipsis": import_lucide.Ellipsis,
8356
+ "ellipsis-vertical": import_lucide.EllipsisVertical,
8357
+ "menu": import_lucide.Menu,
8358
+ "house": import_lucide.House,
8359
+ // Actions
8360
+ "plus": import_lucide.Plus,
8361
+ "minus": import_lucide.Minus,
8362
+ "pencil": import_lucide.Pencil,
8363
+ "trash": import_lucide.Trash,
8364
+ "trash-2": import_lucide.Trash2,
8365
+ "save": import_lucide.Save,
8366
+ "download": import_lucide.Download,
8367
+ "share": import_lucide.Share,
8368
+ "funnel": import_lucide.Funnel,
8369
+ "settings": import_lucide.Settings,
8370
+ "rotate-cw": import_lucide.RotateCw,
8371
+ "maximize": import_lucide.Maximize,
8372
+ "minimize": import_lucide.Minimize,
8373
+ // Commerce
8374
+ "shopping-cart": import_lucide.ShoppingCart,
8375
+ "shopping-bag": import_lucide.ShoppingBag,
8376
+ "package": import_lucide.Package,
8377
+ "truck": import_lucide.Truck,
8378
+ "tag": import_lucide.Tag,
8379
+ "gift": import_lucide.Gift,
8380
+ "receipt": import_lucide.Receipt,
8381
+ "wallet": import_lucide.Wallet,
8382
+ "store": import_lucide.Store,
8383
+ "dollar-sign": import_lucide.DollarSign,
8384
+ "percent": import_lucide.Percent,
8385
+ // Media
8386
+ "play": import_lucide.Play,
8387
+ "pause": import_lucide.Pause,
8388
+ "volume-x": import_lucide.VolumeX,
8389
+ "camera": import_lucide.Camera,
8390
+ "image": import_lucide.Image,
8391
+ "film": import_lucide.Film,
8392
+ "headphones": import_lucide.Headphones,
8393
+ // Social / Comms
8394
+ "message-circle": import_lucide.MessageCircle,
8395
+ "message-square": import_lucide.MessageSquare,
8396
+ "bell": import_lucide.Bell,
8397
+ "heart": import_lucide.Heart,
8398
+ "star": import_lucide.Star,
8399
+ "eye": import_lucide.Eye,
8400
+ "eye-off": import_lucide.EyeOff,
8401
+ "bookmark": import_lucide.Bookmark,
8402
+ // Time
8403
+ "calendar-days": import_lucide.CalendarDays,
8404
+ "history": import_lucide.History,
8405
+ "timer": import_lucide.Timer,
8406
+ // Files
8407
+ "folder": import_lucide.Folder,
8408
+ "folder-open": import_lucide.FolderOpen,
8409
+ "files": import_lucide.Files,
8410
+ // Decorative
8411
+ "sparkles": import_lucide.Sparkles,
8412
+ "zap": import_lucide.Zap,
8413
+ "sun": import_lucide.Sun,
8414
+ "moon": import_lucide.Moon,
8415
+ "flag": import_lucide.Flag,
8416
+ // Devices
8417
+ "monitor": import_lucide.Monitor,
8418
+ "smartphone": import_lucide.Smartphone
8419
+ };
8293
8420
  var renderLucideIcon = (iconName, size = 24, color = "currentColor", strokeWidth = 2) => {
8294
- try {
8295
- const pascalName = iconName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
8296
- const iconData = icons[pascalName];
8297
- if (!iconData) {
8298
- console.warn(`Lucide icon "${iconName}" not found (tried "${pascalName}"). Available icons: https://lucide.dev/icons`);
8299
- return null;
8300
- }
8301
- return createSvgFromIconData(iconData, size, color, strokeWidth);
8302
- } catch (error) {
8303
- console.warn(`Failed to render Lucide icon "${iconName}":`, error);
8421
+ const iconData = LUCIDE_ICONS[iconName];
8422
+ if (!iconData) {
8423
+ console.warn(
8424
+ `Lucide icon "${iconName}" is not in the Persona registry. Add it to packages/widget/src/utils/icons.ts (see docs/icon-registry-shortlist.md).`
8425
+ );
8304
8426
  return null;
8305
8427
  }
8428
+ return createSvgFromIconData(iconData, size, color, strokeWidth);
8306
8429
  };
8307
8430
  function createSvgFromIconData(iconData, size, color, strokeWidth) {
8308
- if (!iconData || !Array.isArray(iconData)) {
8309
- return null;
8310
- }
8431
+ if (!Array.isArray(iconData)) return null;
8311
8432
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
8312
8433
  svg.setAttribute("width", String(size));
8313
8434
  svg.setAttribute("height", String(size));
@@ -8319,19 +8440,15 @@ function createSvgFromIconData(iconData, size, color, strokeWidth) {
8319
8440
  svg.setAttribute("stroke-linejoin", "round");
8320
8441
  svg.setAttribute("aria-hidden", "true");
8321
8442
  iconData.forEach((elementData) => {
8322
- if (Array.isArray(elementData) && elementData.length >= 2) {
8323
- const tagName = elementData[0];
8324
- const attrs = elementData[1];
8325
- if (attrs) {
8326
- const element = document.createElementNS("http://www.w3.org/2000/svg", tagName);
8327
- Object.entries(attrs).forEach(([key, value]) => {
8328
- if (key !== "stroke") {
8329
- element.setAttribute(key, String(value));
8330
- }
8331
- });
8332
- svg.appendChild(element);
8333
- }
8334
- }
8443
+ if (!Array.isArray(elementData) || elementData.length < 2) return;
8444
+ const tagName = elementData[0];
8445
+ const attrs = elementData[1];
8446
+ if (!attrs) return;
8447
+ const element = document.createElementNS("http://www.w3.org/2000/svg", tagName);
8448
+ Object.entries(attrs).forEach(([key, value]) => {
8449
+ if (key !== "stroke") element.setAttribute(key, String(value));
8450
+ });
8451
+ svg.appendChild(element);
8335
8452
  });
8336
8453
  return svg;
8337
8454
  }
@@ -8351,7 +8468,7 @@ function getFileIconName(mimeType) {
8351
8468
  if (mimeType.startsWith("text/")) return "file-text";
8352
8469
  if (mimeType.includes("word")) return "file-text";
8353
8470
  if (mimeType.includes("excel") || mimeType.includes("spreadsheet")) return "file-spreadsheet";
8354
- if (mimeType === "application/json") return "file-json";
8471
+ if (mimeType === "application/json") return "file-code";
8355
8472
  return "file";
8356
8473
  }
8357
8474
  var AttachmentManager = class _AttachmentManager {
@@ -8913,7 +9030,7 @@ var wrapTextNodeWords = (textNode, messageId, counterRef) => {
8913
9030
  parent.replaceChild(fragment, textNode);
8914
9031
  };
8915
9032
  var wrapStreamAnimation = (html, mode, messageId, options) => {
8916
- var _a;
9033
+ var _a, _b;
8917
9034
  if (!html) return html;
8918
9035
  if (typeof document === "undefined") return html;
8919
9036
  const scratch = document.createElement("div");
@@ -8928,7 +9045,7 @@ var wrapStreamAnimation = (html, mode, messageId, options) => {
8928
9045
  }
8929
9046
  node = walker.nextNode();
8930
9047
  }
8931
- const counterRef = { value: 0 };
9048
+ const counterRef = { value: (_b = options == null ? void 0 : options.startIndex) != null ? _b : 0 };
8932
9049
  const wrap = mode === "char" ? wrapTextNodeChars : wrapTextNodeWords;
8933
9050
  for (const textNode of textNodes) {
8934
9051
  wrap(textNode, messageId, counterRef);
@@ -9074,6 +9191,10 @@ var isDockedMountMode = (config) => {
9074
9191
  var _a, _b;
9075
9192
  return ((_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.mountMode) != null ? _b : "floating") === "docked";
9076
9193
  };
9194
+ var isComposerBarMountMode = (config) => {
9195
+ var _a, _b;
9196
+ return ((_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.mountMode) != null ? _b : "floating") === "composer-bar";
9197
+ };
9077
9198
  var resolveDockConfig = (config) => {
9078
9199
  var _a, _b, _c, _d, _e;
9079
9200
  const dock = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.dock;
@@ -9260,6 +9381,226 @@ var createLauncherButton = (config, onToggle) => {
9260
9381
  };
9261
9382
  };
9262
9383
 
9384
+ // src/components/header-parts.ts
9385
+ var DEFAULT_WRAPPER_CLASS = "persona-relative persona-ml-auto persona-inline-flex persona-items-center persona-justify-center";
9386
+ var createCloseButton = (config, options = {}) => {
9387
+ var _a, _b, _c, _d, _e, _f;
9388
+ const {
9389
+ showClose = true,
9390
+ wrapperClassName = DEFAULT_WRAPPER_CLASS,
9391
+ buttonSize,
9392
+ iconSize = "28px"
9393
+ } = options;
9394
+ const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9395
+ const closeButtonSize = (_b = buttonSize != null ? buttonSize : launcher.closeButtonSize) != null ? _b : "32px";
9396
+ const wrapper = createElement("div", wrapperClassName);
9397
+ const button = createElement(
9398
+ "button",
9399
+ "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9400
+ );
9401
+ button.style.height = closeButtonSize;
9402
+ button.style.width = closeButtonSize;
9403
+ button.type = "button";
9404
+ const closeButtonTooltipText = (_c = launcher.closeButtonTooltipText) != null ? _c : "Close chat";
9405
+ const closeButtonShowTooltip = (_d = launcher.closeButtonShowTooltip) != null ? _d : true;
9406
+ button.setAttribute("aria-label", closeButtonTooltipText);
9407
+ button.style.display = showClose ? "" : "none";
9408
+ const closeButtonIconName = (_e = launcher.closeButtonIconName) != null ? _e : "x";
9409
+ const closeButtonIconText = (_f = launcher.closeButtonIconText) != null ? _f : "\xD7";
9410
+ button.style.color = launcher.closeButtonColor || HEADER_THEME_CSS.actionIconColor;
9411
+ const closeIconSvg = renderLucideIcon(closeButtonIconName, iconSize, "currentColor", 1);
9412
+ if (closeIconSvg) {
9413
+ closeIconSvg.style.display = "block";
9414
+ button.appendChild(closeIconSvg);
9415
+ } else {
9416
+ button.textContent = closeButtonIconText;
9417
+ }
9418
+ if (launcher.closeButtonBackgroundColor) {
9419
+ button.style.backgroundColor = launcher.closeButtonBackgroundColor;
9420
+ button.classList.remove("hover:persona-bg-gray-100");
9421
+ } else {
9422
+ button.style.backgroundColor = "";
9423
+ button.classList.add("hover:persona-bg-gray-100");
9424
+ }
9425
+ if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {
9426
+ const borderWidth = launcher.closeButtonBorderWidth || "0px";
9427
+ const borderColor = launcher.closeButtonBorderColor || "transparent";
9428
+ button.style.border = `${borderWidth} solid ${borderColor}`;
9429
+ button.classList.remove("persona-border-none");
9430
+ } else {
9431
+ button.style.border = "";
9432
+ button.classList.add("persona-border-none");
9433
+ }
9434
+ if (launcher.closeButtonBorderRadius) {
9435
+ button.style.borderRadius = launcher.closeButtonBorderRadius;
9436
+ button.classList.remove("persona-rounded-full");
9437
+ } else {
9438
+ button.style.borderRadius = "";
9439
+ button.classList.add("persona-rounded-full");
9440
+ }
9441
+ if (launcher.closeButtonPaddingX) {
9442
+ button.style.paddingLeft = launcher.closeButtonPaddingX;
9443
+ button.style.paddingRight = launcher.closeButtonPaddingX;
9444
+ } else {
9445
+ button.style.paddingLeft = "";
9446
+ button.style.paddingRight = "";
9447
+ }
9448
+ if (launcher.closeButtonPaddingY) {
9449
+ button.style.paddingTop = launcher.closeButtonPaddingY;
9450
+ button.style.paddingBottom = launcher.closeButtonPaddingY;
9451
+ } else {
9452
+ button.style.paddingTop = "";
9453
+ button.style.paddingBottom = "";
9454
+ }
9455
+ wrapper.appendChild(button);
9456
+ if (closeButtonShowTooltip && closeButtonTooltipText) {
9457
+ let portaledTooltip = null;
9458
+ const showTooltip = () => {
9459
+ if (portaledTooltip) return;
9460
+ const tooltipDocument = button.ownerDocument;
9461
+ const tooltipContainer = tooltipDocument.body;
9462
+ if (!tooltipContainer) return;
9463
+ portaledTooltip = createElementInDocument(
9464
+ tooltipDocument,
9465
+ "div",
9466
+ "persona-clear-chat-tooltip"
9467
+ );
9468
+ portaledTooltip.textContent = closeButtonTooltipText;
9469
+ const arrow = createElementInDocument(tooltipDocument, "div");
9470
+ arrow.className = "persona-clear-chat-tooltip-arrow";
9471
+ portaledTooltip.appendChild(arrow);
9472
+ const buttonRect = button.getBoundingClientRect();
9473
+ portaledTooltip.style.position = "fixed";
9474
+ portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9475
+ portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9476
+ portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9477
+ portaledTooltip.style.transform = "translate(-50%, -100%)";
9478
+ tooltipContainer.appendChild(portaledTooltip);
9479
+ };
9480
+ const hideTooltip = () => {
9481
+ if (portaledTooltip && portaledTooltip.parentNode) {
9482
+ portaledTooltip.parentNode.removeChild(portaledTooltip);
9483
+ portaledTooltip = null;
9484
+ }
9485
+ };
9486
+ wrapper.addEventListener("mouseenter", showTooltip);
9487
+ wrapper.addEventListener("mouseleave", hideTooltip);
9488
+ button.addEventListener("focus", showTooltip);
9489
+ button.addEventListener("blur", hideTooltip);
9490
+ wrapper._cleanupTooltip = () => {
9491
+ hideTooltip();
9492
+ wrapper.removeEventListener("mouseenter", showTooltip);
9493
+ wrapper.removeEventListener("mouseleave", hideTooltip);
9494
+ button.removeEventListener("focus", showTooltip);
9495
+ button.removeEventListener("blur", hideTooltip);
9496
+ };
9497
+ }
9498
+ return { button, wrapper };
9499
+ };
9500
+ var DEFAULT_CLEAR_CHAT_WRAPPER_CLASS = "persona-relative persona-ml-auto persona-clear-chat-button-wrapper";
9501
+ var createClearChatButton = (config, options = {}) => {
9502
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
9503
+ const {
9504
+ wrapperClassName = DEFAULT_CLEAR_CHAT_WRAPPER_CLASS,
9505
+ buttonSize,
9506
+ iconSize = "20px"
9507
+ } = options;
9508
+ const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9509
+ const clearChatConfig = (_b = launcher.clearChat) != null ? _b : {};
9510
+ const clearChatSize = (_c = buttonSize != null ? buttonSize : clearChatConfig.size) != null ? _c : "32px";
9511
+ const clearChatIconName = (_d = clearChatConfig.iconName) != null ? _d : "refresh-cw";
9512
+ const clearChatIconColor = (_e = clearChatConfig.iconColor) != null ? _e : "";
9513
+ const clearChatBgColor = (_f = clearChatConfig.backgroundColor) != null ? _f : "";
9514
+ const clearChatBorderWidth = (_g = clearChatConfig.borderWidth) != null ? _g : "";
9515
+ const clearChatBorderColor = (_h = clearChatConfig.borderColor) != null ? _h : "";
9516
+ const clearChatBorderRadius = (_i = clearChatConfig.borderRadius) != null ? _i : "";
9517
+ const clearChatPaddingX = (_j = clearChatConfig.paddingX) != null ? _j : "";
9518
+ const clearChatPaddingY = (_k = clearChatConfig.paddingY) != null ? _k : "";
9519
+ const clearChatTooltipText = (_l = clearChatConfig.tooltipText) != null ? _l : "Clear chat";
9520
+ const clearChatShowTooltip = (_m = clearChatConfig.showTooltip) != null ? _m : true;
9521
+ const wrapper = createElement("div", wrapperClassName);
9522
+ const button = createElement(
9523
+ "button",
9524
+ "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9525
+ );
9526
+ button.style.height = clearChatSize;
9527
+ button.style.width = clearChatSize;
9528
+ button.type = "button";
9529
+ button.setAttribute("aria-label", clearChatTooltipText);
9530
+ button.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
9531
+ const iconSvg = renderLucideIcon(clearChatIconName, iconSize, "currentColor", 1);
9532
+ if (iconSvg) {
9533
+ iconSvg.style.display = "block";
9534
+ button.appendChild(iconSvg);
9535
+ }
9536
+ if (clearChatBgColor) {
9537
+ button.style.backgroundColor = clearChatBgColor;
9538
+ button.classList.remove("hover:persona-bg-gray-100");
9539
+ }
9540
+ if (clearChatBorderWidth || clearChatBorderColor) {
9541
+ const borderWidth = clearChatBorderWidth || "0px";
9542
+ const borderColor = clearChatBorderColor || "transparent";
9543
+ button.style.border = `${borderWidth} solid ${borderColor}`;
9544
+ button.classList.remove("persona-border-none");
9545
+ }
9546
+ if (clearChatBorderRadius) {
9547
+ button.style.borderRadius = clearChatBorderRadius;
9548
+ button.classList.remove("persona-rounded-full");
9549
+ }
9550
+ if (clearChatPaddingX) {
9551
+ button.style.paddingLeft = clearChatPaddingX;
9552
+ button.style.paddingRight = clearChatPaddingX;
9553
+ }
9554
+ if (clearChatPaddingY) {
9555
+ button.style.paddingTop = clearChatPaddingY;
9556
+ button.style.paddingBottom = clearChatPaddingY;
9557
+ }
9558
+ wrapper.appendChild(button);
9559
+ if (clearChatShowTooltip && clearChatTooltipText) {
9560
+ let portaledTooltip = null;
9561
+ const showTooltip = () => {
9562
+ if (portaledTooltip) return;
9563
+ const tooltipDocument = button.ownerDocument;
9564
+ const tooltipContainer = tooltipDocument.body;
9565
+ if (!tooltipContainer) return;
9566
+ portaledTooltip = createElementInDocument(
9567
+ tooltipDocument,
9568
+ "div",
9569
+ "persona-clear-chat-tooltip"
9570
+ );
9571
+ portaledTooltip.textContent = clearChatTooltipText;
9572
+ const arrow = createElementInDocument(tooltipDocument, "div");
9573
+ arrow.className = "persona-clear-chat-tooltip-arrow";
9574
+ portaledTooltip.appendChild(arrow);
9575
+ const buttonRect = button.getBoundingClientRect();
9576
+ portaledTooltip.style.position = "fixed";
9577
+ portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9578
+ portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9579
+ portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9580
+ portaledTooltip.style.transform = "translate(-50%, -100%)";
9581
+ tooltipContainer.appendChild(portaledTooltip);
9582
+ };
9583
+ const hideTooltip = () => {
9584
+ if (portaledTooltip && portaledTooltip.parentNode) {
9585
+ portaledTooltip.parentNode.removeChild(portaledTooltip);
9586
+ portaledTooltip = null;
9587
+ }
9588
+ };
9589
+ wrapper.addEventListener("mouseenter", showTooltip);
9590
+ wrapper.addEventListener("mouseleave", hideTooltip);
9591
+ button.addEventListener("focus", showTooltip);
9592
+ button.addEventListener("blur", hideTooltip);
9593
+ wrapper._cleanupTooltip = () => {
9594
+ hideTooltip();
9595
+ wrapper.removeEventListener("mouseenter", showTooltip);
9596
+ wrapper.removeEventListener("mouseleave", hideTooltip);
9597
+ button.removeEventListener("focus", showTooltip);
9598
+ button.removeEventListener("blur", hideTooltip);
9599
+ };
9600
+ }
9601
+ return { button, wrapper };
9602
+ };
9603
+
9263
9604
  // src/components/header-builder.ts
9264
9605
  var HEADER_THEME_CSS = {
9265
9606
  titleColor: "var(--persona-header-title-fg, var(--persona-primary, #0f0f0f))",
@@ -9267,7 +9608,7 @@ var HEADER_THEME_CSS = {
9267
9608
  actionIconColor: "var(--persona-header-action-icon-fg, var(--persona-muted, #9ca3af))"
9268
9609
  };
9269
9610
  var buildHeader = (context) => {
9270
- 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;
9611
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
9271
9612
  const { config, showClose = true } = context;
9272
9613
  const header = createElement(
9273
9614
  "div",
@@ -9280,9 +9621,8 @@ var buildHeader = (context) => {
9280
9621
  header.style.borderBottom = "var(--persona-header-border-bottom, 1px solid var(--persona-header-border, var(--persona-divider, #f1f5f9)))";
9281
9622
  const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9282
9623
  const headerIconSize = (_b = launcher.headerIconSize) != null ? _b : "48px";
9283
- const closeButtonSize = (_c = launcher.closeButtonSize) != null ? _c : "32px";
9284
- const closeButtonPlacement = (_d = launcher.closeButtonPlacement) != null ? _d : "inline";
9285
- const headerIconHidden = (_e = launcher.headerIconHidden) != null ? _e : false;
9624
+ const closeButtonPlacement = (_c = launcher.closeButtonPlacement) != null ? _c : "inline";
9625
+ const headerIconHidden = (_d = launcher.headerIconHidden) != null ? _d : false;
9286
9626
  const headerIconName = launcher.headerIconName;
9287
9627
  const iconHolder = createElement(
9288
9628
  "div",
@@ -9299,9 +9639,9 @@ var buildHeader = (context) => {
9299
9639
  if (iconSvg) {
9300
9640
  iconHolder.replaceChildren(iconSvg);
9301
9641
  } else {
9302
- iconHolder.textContent = (_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.agentIconText) != null ? _g : "\u{1F4AC}";
9642
+ iconHolder.textContent = (_f = (_e = config == null ? void 0 : config.launcher) == null ? void 0 : _e.agentIconText) != null ? _f : "\u{1F4AC}";
9303
9643
  }
9304
- } else if ((_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.iconUrl) {
9644
+ } else if ((_g = config == null ? void 0 : config.launcher) == null ? void 0 : _g.iconUrl) {
9305
9645
  const img = createElement("img");
9306
9646
  img.src = config.launcher.iconUrl;
9307
9647
  img.alt = "";
@@ -9310,244 +9650,44 @@ var buildHeader = (context) => {
9310
9650
  img.style.width = headerIconSize;
9311
9651
  iconHolder.replaceChildren(img);
9312
9652
  } else {
9313
- iconHolder.textContent = (_j = (_i = config == null ? void 0 : config.launcher) == null ? void 0 : _i.agentIconText) != null ? _j : "\u{1F4AC}";
9653
+ iconHolder.textContent = (_i = (_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.agentIconText) != null ? _i : "\u{1F4AC}";
9314
9654
  }
9315
9655
  }
9316
9656
  const headerCopy = createElement("div", "persona-flex persona-flex-col persona-flex-1 persona-min-w-0");
9317
9657
  const title = createElement("span", "persona-text-base persona-font-semibold");
9318
9658
  title.style.color = HEADER_THEME_CSS.titleColor;
9319
- title.textContent = (_l = (_k = config == null ? void 0 : config.launcher) == null ? void 0 : _k.title) != null ? _l : "Chat Assistant";
9659
+ title.textContent = (_k = (_j = config == null ? void 0 : config.launcher) == null ? void 0 : _j.title) != null ? _k : "Chat Assistant";
9320
9660
  const subtitle = createElement("span", "persona-text-xs");
9321
9661
  subtitle.style.color = HEADER_THEME_CSS.subtitleColor;
9322
- subtitle.textContent = (_n = (_m = config == null ? void 0 : config.launcher) == null ? void 0 : _m.subtitle) != null ? _n : "Here to help you get answers fast";
9662
+ subtitle.textContent = (_m = (_l = config == null ? void 0 : config.launcher) == null ? void 0 : _l.subtitle) != null ? _m : "Here to help you get answers fast";
9323
9663
  headerCopy.append(title, subtitle);
9324
9664
  if (!headerIconHidden) {
9325
9665
  header.append(iconHolder, headerCopy);
9326
9666
  } else {
9327
9667
  header.append(headerCopy);
9328
9668
  }
9329
- const clearChatConfig = (_o = launcher.clearChat) != null ? _o : {};
9330
- const clearChatEnabled = (_p = clearChatConfig.enabled) != null ? _p : true;
9331
- const clearChatPlacement = (_q = clearChatConfig.placement) != null ? _q : "inline";
9669
+ const clearChatConfig = (_n = launcher.clearChat) != null ? _n : {};
9670
+ const clearChatEnabled = (_o = clearChatConfig.enabled) != null ? _o : true;
9671
+ const clearChatPlacement = (_p = clearChatConfig.placement) != null ? _p : "inline";
9332
9672
  let clearChatButton = null;
9333
9673
  let clearChatButtonWrapper = null;
9334
9674
  if (clearChatEnabled) {
9335
- const clearChatSize = (_r = clearChatConfig.size) != null ? _r : "32px";
9336
- const clearChatIconName = (_s = clearChatConfig.iconName) != null ? _s : "refresh-cw";
9337
- const clearChatIconColor = (_t = clearChatConfig.iconColor) != null ? _t : "";
9338
- const clearChatBgColor = (_u = clearChatConfig.backgroundColor) != null ? _u : "";
9339
- const clearChatBorderWidth = (_v = clearChatConfig.borderWidth) != null ? _v : "";
9340
- const clearChatBorderColor = (_w = clearChatConfig.borderColor) != null ? _w : "";
9341
- const clearChatBorderRadius = (_x = clearChatConfig.borderRadius) != null ? _x : "";
9342
- const clearChatPaddingX = (_y = clearChatConfig.paddingX) != null ? _y : "";
9343
- const clearChatPaddingY = (_z = clearChatConfig.paddingY) != null ? _z : "";
9344
- const clearChatTooltipText = (_A = clearChatConfig.tooltipText) != null ? _A : "Clear chat";
9345
- const clearChatShowTooltip = (_B = clearChatConfig.showTooltip) != null ? _B : true;
9346
- clearChatButtonWrapper = createElement(
9347
- "div",
9348
- clearChatPlacement === "top-right" ? "persona-absolute persona-top-4 persona-z-50" : "persona-relative persona-ml-auto persona-clear-chat-button-wrapper"
9349
- );
9675
+ const wrapperClassName = clearChatPlacement === "top-right" ? "persona-absolute persona-top-4 persona-z-50" : "persona-relative persona-ml-auto persona-clear-chat-button-wrapper";
9676
+ const parts = createClearChatButton(config, { wrapperClassName });
9677
+ clearChatButton = parts.button;
9678
+ clearChatButtonWrapper = parts.wrapper;
9350
9679
  if (clearChatPlacement === "top-right") {
9351
9680
  clearChatButtonWrapper.style.right = "48px";
9352
9681
  }
9353
- clearChatButton = createElement(
9354
- "button",
9355
- "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9356
- );
9357
- clearChatButton.style.height = clearChatSize;
9358
- clearChatButton.style.width = clearChatSize;
9359
- clearChatButton.type = "button";
9360
- clearChatButton.setAttribute("aria-label", clearChatTooltipText);
9361
- clearChatButton.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
9362
- const iconSvg = renderLucideIcon(clearChatIconName, "20px", "currentColor", 1);
9363
- if (iconSvg) {
9364
- iconSvg.style.display = "block";
9365
- clearChatButton.appendChild(iconSvg);
9366
- }
9367
- if (clearChatBgColor) {
9368
- clearChatButton.style.backgroundColor = clearChatBgColor;
9369
- clearChatButton.classList.remove("hover:persona-bg-gray-100");
9370
- }
9371
- if (clearChatBorderWidth || clearChatBorderColor) {
9372
- const borderWidth = clearChatBorderWidth || "0px";
9373
- const borderColor = clearChatBorderColor || "transparent";
9374
- clearChatButton.style.border = `${borderWidth} solid ${borderColor}`;
9375
- clearChatButton.classList.remove("persona-border-none");
9376
- }
9377
- if (clearChatBorderRadius) {
9378
- clearChatButton.style.borderRadius = clearChatBorderRadius;
9379
- clearChatButton.classList.remove("persona-rounded-full");
9380
- }
9381
- if (clearChatPaddingX) {
9382
- clearChatButton.style.paddingLeft = clearChatPaddingX;
9383
- clearChatButton.style.paddingRight = clearChatPaddingX;
9384
- } else {
9385
- clearChatButton.style.paddingLeft = "";
9386
- clearChatButton.style.paddingRight = "";
9387
- }
9388
- if (clearChatPaddingY) {
9389
- clearChatButton.style.paddingTop = clearChatPaddingY;
9390
- clearChatButton.style.paddingBottom = clearChatPaddingY;
9391
- } else {
9392
- clearChatButton.style.paddingTop = "";
9393
- clearChatButton.style.paddingBottom = "";
9394
- }
9395
- clearChatButtonWrapper.appendChild(clearChatButton);
9396
- if (clearChatShowTooltip && clearChatTooltipText && clearChatButton && clearChatButtonWrapper) {
9397
- let portaledTooltip = null;
9398
- const showTooltip = () => {
9399
- if (portaledTooltip || !clearChatButton) return;
9400
- const tooltipDocument = clearChatButton.ownerDocument;
9401
- const tooltipContainer = tooltipDocument.body;
9402
- if (!tooltipContainer) return;
9403
- portaledTooltip = createElementInDocument(
9404
- tooltipDocument,
9405
- "div",
9406
- "persona-clear-chat-tooltip"
9407
- );
9408
- portaledTooltip.textContent = clearChatTooltipText;
9409
- const arrow = createElementInDocument(tooltipDocument, "div");
9410
- arrow.className = "persona-clear-chat-tooltip-arrow";
9411
- portaledTooltip.appendChild(arrow);
9412
- const buttonRect = clearChatButton.getBoundingClientRect();
9413
- portaledTooltip.style.position = "fixed";
9414
- portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9415
- portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9416
- portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9417
- portaledTooltip.style.transform = "translate(-50%, -100%)";
9418
- tooltipContainer.appendChild(portaledTooltip);
9419
- };
9420
- const hideTooltip = () => {
9421
- if (portaledTooltip && portaledTooltip.parentNode) {
9422
- portaledTooltip.parentNode.removeChild(portaledTooltip);
9423
- portaledTooltip = null;
9424
- }
9425
- };
9426
- clearChatButtonWrapper.addEventListener("mouseenter", showTooltip);
9427
- clearChatButtonWrapper.addEventListener("mouseleave", hideTooltip);
9428
- clearChatButton.addEventListener("focus", showTooltip);
9429
- clearChatButton.addEventListener("blur", hideTooltip);
9430
- clearChatButtonWrapper._cleanupTooltip = () => {
9431
- hideTooltip();
9432
- if (clearChatButtonWrapper) {
9433
- clearChatButtonWrapper.removeEventListener("mouseenter", showTooltip);
9434
- clearChatButtonWrapper.removeEventListener("mouseleave", hideTooltip);
9435
- }
9436
- if (clearChatButton) {
9437
- clearChatButton.removeEventListener("focus", showTooltip);
9438
- clearChatButton.removeEventListener("blur", hideTooltip);
9439
- }
9440
- };
9441
- }
9442
9682
  if (clearChatPlacement === "inline") {
9443
9683
  header.appendChild(clearChatButtonWrapper);
9444
9684
  }
9445
9685
  }
9446
- const closeButtonWrapper = createElement(
9447
- "div",
9448
- 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"
9449
- );
9450
- const closeButton = createElement(
9451
- "button",
9452
- "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9686
+ 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";
9687
+ const { button: closeButton, wrapper: closeButtonWrapper } = createCloseButton(
9688
+ config,
9689
+ { showClose, wrapperClassName: closeButtonWrapperClass }
9453
9690
  );
9454
- closeButton.style.height = closeButtonSize;
9455
- closeButton.style.width = closeButtonSize;
9456
- closeButton.type = "button";
9457
- const closeButtonTooltipText = (_C = launcher.closeButtonTooltipText) != null ? _C : "Close chat";
9458
- const closeButtonShowTooltip = (_D = launcher.closeButtonShowTooltip) != null ? _D : true;
9459
- closeButton.setAttribute("aria-label", closeButtonTooltipText);
9460
- closeButton.style.display = showClose ? "" : "none";
9461
- const closeButtonIconName = (_E = launcher.closeButtonIconName) != null ? _E : "x";
9462
- const closeButtonIconText = (_F = launcher.closeButtonIconText) != null ? _F : "\xD7";
9463
- closeButton.style.color = launcher.closeButtonColor || HEADER_THEME_CSS.actionIconColor;
9464
- const closeIconSvg = renderLucideIcon(closeButtonIconName, "28px", "currentColor", 1);
9465
- if (closeIconSvg) {
9466
- closeIconSvg.style.display = "block";
9467
- closeButton.appendChild(closeIconSvg);
9468
- } else {
9469
- closeButton.textContent = closeButtonIconText;
9470
- }
9471
- if (launcher.closeButtonBackgroundColor) {
9472
- closeButton.style.backgroundColor = launcher.closeButtonBackgroundColor;
9473
- closeButton.classList.remove("hover:persona-bg-gray-100");
9474
- } else {
9475
- closeButton.style.backgroundColor = "";
9476
- closeButton.classList.add("hover:persona-bg-gray-100");
9477
- }
9478
- if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {
9479
- const borderWidth = launcher.closeButtonBorderWidth || "0px";
9480
- const borderColor = launcher.closeButtonBorderColor || "transparent";
9481
- closeButton.style.border = `${borderWidth} solid ${borderColor}`;
9482
- closeButton.classList.remove("persona-border-none");
9483
- } else {
9484
- closeButton.style.border = "";
9485
- closeButton.classList.add("persona-border-none");
9486
- }
9487
- if (launcher.closeButtonBorderRadius) {
9488
- closeButton.style.borderRadius = launcher.closeButtonBorderRadius;
9489
- closeButton.classList.remove("persona-rounded-full");
9490
- } else {
9491
- closeButton.style.borderRadius = "";
9492
- closeButton.classList.add("persona-rounded-full");
9493
- }
9494
- if (launcher.closeButtonPaddingX) {
9495
- closeButton.style.paddingLeft = launcher.closeButtonPaddingX;
9496
- closeButton.style.paddingRight = launcher.closeButtonPaddingX;
9497
- } else {
9498
- closeButton.style.paddingLeft = "";
9499
- closeButton.style.paddingRight = "";
9500
- }
9501
- if (launcher.closeButtonPaddingY) {
9502
- closeButton.style.paddingTop = launcher.closeButtonPaddingY;
9503
- closeButton.style.paddingBottom = launcher.closeButtonPaddingY;
9504
- } else {
9505
- closeButton.style.paddingTop = "";
9506
- closeButton.style.paddingBottom = "";
9507
- }
9508
- closeButtonWrapper.appendChild(closeButton);
9509
- if (closeButtonShowTooltip && closeButtonTooltipText) {
9510
- let portaledTooltip = null;
9511
- const showTooltip = () => {
9512
- if (portaledTooltip) return;
9513
- const tooltipDocument = closeButton.ownerDocument;
9514
- const tooltipContainer = tooltipDocument.body;
9515
- if (!tooltipContainer) return;
9516
- portaledTooltip = createElementInDocument(
9517
- tooltipDocument,
9518
- "div",
9519
- "persona-clear-chat-tooltip"
9520
- );
9521
- portaledTooltip.textContent = closeButtonTooltipText;
9522
- const arrow = createElementInDocument(tooltipDocument, "div");
9523
- arrow.className = "persona-clear-chat-tooltip-arrow";
9524
- portaledTooltip.appendChild(arrow);
9525
- const buttonRect = closeButton.getBoundingClientRect();
9526
- portaledTooltip.style.position = "fixed";
9527
- portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9528
- portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9529
- portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9530
- portaledTooltip.style.transform = "translate(-50%, -100%)";
9531
- tooltipContainer.appendChild(portaledTooltip);
9532
- };
9533
- const hideTooltip = () => {
9534
- if (portaledTooltip && portaledTooltip.parentNode) {
9535
- portaledTooltip.parentNode.removeChild(portaledTooltip);
9536
- portaledTooltip = null;
9537
- }
9538
- };
9539
- closeButtonWrapper.addEventListener("mouseenter", showTooltip);
9540
- closeButtonWrapper.addEventListener("mouseleave", hideTooltip);
9541
- closeButton.addEventListener("focus", showTooltip);
9542
- closeButton.addEventListener("blur", hideTooltip);
9543
- closeButtonWrapper._cleanupTooltip = () => {
9544
- hideTooltip();
9545
- closeButtonWrapper.removeEventListener("mouseenter", showTooltip);
9546
- closeButtonWrapper.removeEventListener("mouseleave", hideTooltip);
9547
- closeButton.removeEventListener("focus", showTooltip);
9548
- closeButton.removeEventListener("blur", hideTooltip);
9549
- };
9550
- }
9551
9691
  if (closeButtonPlacement !== "top-right") {
9552
9692
  header.appendChild(closeButtonWrapper);
9553
9693
  }
@@ -10084,25 +10224,9 @@ var buildHeaderWithLayout = (config, layoutConfig, context) => {
10084
10224
  return headerElements;
10085
10225
  };
10086
10226
 
10087
- // src/components/composer-builder.ts
10088
- var buildComposer = (context) => {
10089
- 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;
10090
- const { config } = context;
10091
- const footer = createElement(
10092
- "div",
10093
- "persona-widget-footer persona-border-t-persona-divider persona-bg-persona-surface persona-px-6 persona-py-4"
10094
- );
10095
- footer.setAttribute("data-persona-theme-zone", "composer");
10096
- const suggestions = createElement(
10097
- "div",
10098
- "persona-mb-3 persona-flex persona-flex-wrap persona-gap-2"
10099
- );
10100
- const composerForm = createElement(
10101
- "form",
10102
- `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`
10103
- );
10104
- composerForm.setAttribute("data-persona-composer-form", "");
10105
- composerForm.style.outline = "none";
10227
+ // src/components/composer-parts.ts
10228
+ var createComposerTextarea = (config) => {
10229
+ var _a, _b;
10106
10230
  const textarea = createElement("textarea");
10107
10231
  textarea.setAttribute("data-persona-composer-input", "");
10108
10232
  textarea.placeholder = (_b = (_a = config == null ? void 0 : config.copy) == null ? void 0 : _a.inputPlaceholder) != null ? _b : "Type your message\u2026";
@@ -10110,17 +10234,21 @@ var buildComposer = (context) => {
10110
10234
  textarea.rows = 1;
10111
10235
  textarea.style.fontFamily = 'var(--persona-input-font-family, var(--persona-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif))';
10112
10236
  textarea.style.fontWeight = "var(--persona-input-font-weight, var(--persona-font-weight, 400))";
10113
- const maxLines = 3;
10237
+ const defaultMaxLines = 3;
10114
10238
  const lineHeight = 20;
10115
- const maxHeight = maxLines * lineHeight;
10116
- textarea.style.maxHeight = `${maxHeight}px`;
10239
+ textarea.style.maxHeight = `${defaultMaxLines * lineHeight}px`;
10117
10240
  textarea.style.overflowY = "auto";
10118
- const autoResize = () => {
10119
- textarea.style.height = "auto";
10120
- const newHeight = Math.min(textarea.scrollHeight, maxHeight);
10121
- textarea.style.height = `${newHeight}px`;
10241
+ const readMaxHeight = () => {
10242
+ const parsed = parseFloat(textarea.style.maxHeight);
10243
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultMaxLines * lineHeight;
10244
+ };
10245
+ const attachAutoResize = () => {
10246
+ textarea.addEventListener("input", () => {
10247
+ textarea.style.height = "auto";
10248
+ const newHeight = Math.min(textarea.scrollHeight, readMaxHeight());
10249
+ textarea.style.height = `${newHeight}px`;
10250
+ });
10122
10251
  };
10123
- textarea.addEventListener("input", autoResize);
10124
10252
  textarea.style.border = "none";
10125
10253
  textarea.style.outline = "none";
10126
10254
  textarea.style.borderWidth = "0";
@@ -10138,333 +10266,474 @@ var buildComposer = (context) => {
10138
10266
  textarea.style.border = "none";
10139
10267
  textarea.style.outline = "none";
10140
10268
  });
10141
- const sendButtonConfig = (_c = config == null ? void 0 : config.sendButton) != null ? _c : {};
10142
- const useIcon = (_d = sendButtonConfig.useIcon) != null ? _d : false;
10143
- const iconText = (_e = sendButtonConfig.iconText) != null ? _e : "\u2191";
10269
+ return { textarea, attachAutoResize };
10270
+ };
10271
+ var createSendButton = (config) => {
10272
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
10273
+ const sendButtonConfig = (_a = config == null ? void 0 : config.sendButton) != null ? _a : {};
10274
+ const useIcon = (_b = sendButtonConfig.useIcon) != null ? _b : false;
10275
+ const iconText = (_c = sendButtonConfig.iconText) != null ? _c : "\u2191";
10144
10276
  const iconName = sendButtonConfig.iconName;
10145
- const stopIconName = (_f = sendButtonConfig.stopIconName) != null ? _f : "square";
10146
- const tooltipText = (_g = sendButtonConfig.tooltipText) != null ? _g : "Send message";
10147
- const stopTooltipText = (_h = sendButtonConfig.stopTooltipText) != null ? _h : "Stop generating";
10148
- const sendLabel = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.sendButtonLabel) != null ? _j : "Send";
10149
- const stopLabel = (_l = (_k = config == null ? void 0 : config.copy) == null ? void 0 : _k.stopButtonLabel) != null ? _l : "Stop";
10150
- const showTooltip = (_m = sendButtonConfig.showTooltip) != null ? _m : false;
10151
- const buttonSize = (_n = sendButtonConfig.size) != null ? _n : "40px";
10277
+ const stopIconName = (_d = sendButtonConfig.stopIconName) != null ? _d : "square";
10278
+ const tooltipText = (_e = sendButtonConfig.tooltipText) != null ? _e : "Send message";
10279
+ const stopTooltipText = (_f = sendButtonConfig.stopTooltipText) != null ? _f : "Stop generating";
10280
+ const sendLabel = (_h = (_g = config == null ? void 0 : config.copy) == null ? void 0 : _g.sendButtonLabel) != null ? _h : "Send";
10281
+ const stopLabel = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.stopButtonLabel) != null ? _j : "Stop";
10282
+ const showTooltip = (_k = sendButtonConfig.showTooltip) != null ? _k : false;
10283
+ const buttonSize = (_l = sendButtonConfig.size) != null ? _l : "40px";
10152
10284
  const backgroundColor = sendButtonConfig.backgroundColor;
10153
10285
  const textColor = sendButtonConfig.textColor;
10154
- const sendButtonWrapper = createElement("div", "persona-send-button-wrapper");
10155
- const sendButton = createElement(
10286
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10287
+ const button = createElement(
10156
10288
  "button",
10157
10289
  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"
10158
10290
  );
10159
- sendButton.type = "submit";
10160
- sendButton.setAttribute("data-persona-composer-submit", "");
10291
+ button.type = "submit";
10292
+ button.setAttribute("data-persona-composer-submit", "");
10161
10293
  let sendIcon = null;
10162
10294
  let stopIcon = null;
10163
10295
  if (useIcon) {
10164
- sendButton.style.width = buttonSize;
10165
- sendButton.style.height = buttonSize;
10166
- sendButton.style.minWidth = buttonSize;
10167
- sendButton.style.minHeight = buttonSize;
10168
- sendButton.style.fontSize = "18px";
10169
- sendButton.style.lineHeight = "1";
10170
- sendButton.innerHTML = "";
10296
+ button.style.width = buttonSize;
10297
+ button.style.height = buttonSize;
10298
+ button.style.minWidth = buttonSize;
10299
+ button.style.minHeight = buttonSize;
10300
+ button.style.fontSize = "18px";
10301
+ button.style.lineHeight = "1";
10302
+ button.innerHTML = "";
10171
10303
  if (textColor) {
10172
- sendButton.style.color = textColor;
10304
+ button.style.color = textColor;
10173
10305
  } else {
10174
- sendButton.style.color = "var(--persona-button-primary-fg, #ffffff)";
10306
+ button.style.color = "var(--persona-button-primary-fg, #ffffff)";
10175
10307
  }
10176
10308
  const iconSize = parseFloat(buttonSize) || 24;
10177
10309
  const iconColor = (textColor == null ? void 0 : textColor.trim()) || "currentColor";
10178
10310
  if (iconName) {
10179
10311
  sendIcon = renderLucideIcon(iconName, iconSize, iconColor, 2);
10180
10312
  if (sendIcon) {
10181
- sendButton.appendChild(sendIcon);
10313
+ button.appendChild(sendIcon);
10182
10314
  } else {
10183
- sendButton.textContent = iconText;
10315
+ button.textContent = iconText;
10184
10316
  }
10185
10317
  } else {
10186
- sendButton.textContent = iconText;
10318
+ button.textContent = iconText;
10187
10319
  }
10188
10320
  stopIcon = renderLucideIcon(stopIconName, iconSize, iconColor, 2);
10189
10321
  if (backgroundColor) {
10190
- sendButton.style.backgroundColor = backgroundColor;
10322
+ button.style.backgroundColor = backgroundColor;
10191
10323
  } else {
10192
- sendButton.classList.add("persona-bg-persona-primary");
10324
+ button.classList.add("persona-bg-persona-primary");
10193
10325
  }
10194
10326
  } else {
10195
- sendButton.textContent = sendLabel;
10327
+ button.textContent = sendLabel;
10196
10328
  if (textColor) {
10197
- sendButton.style.color = textColor;
10329
+ button.style.color = textColor;
10198
10330
  } else {
10199
- sendButton.classList.add("persona-text-white");
10331
+ button.classList.add("persona-text-white");
10200
10332
  }
10201
10333
  }
10202
10334
  if (sendButtonConfig.borderWidth) {
10203
- sendButton.style.borderWidth = sendButtonConfig.borderWidth;
10204
- sendButton.style.borderStyle = "solid";
10335
+ button.style.borderWidth = sendButtonConfig.borderWidth;
10336
+ button.style.borderStyle = "solid";
10205
10337
  }
10206
10338
  if (sendButtonConfig.borderColor) {
10207
- sendButton.style.borderColor = sendButtonConfig.borderColor;
10339
+ button.style.borderColor = sendButtonConfig.borderColor;
10208
10340
  }
10209
10341
  if (sendButtonConfig.paddingX) {
10210
- sendButton.style.paddingLeft = sendButtonConfig.paddingX;
10211
- sendButton.style.paddingRight = sendButtonConfig.paddingX;
10342
+ button.style.paddingLeft = sendButtonConfig.paddingX;
10343
+ button.style.paddingRight = sendButtonConfig.paddingX;
10212
10344
  } else {
10213
- sendButton.style.paddingLeft = "";
10214
- sendButton.style.paddingRight = "";
10345
+ button.style.paddingLeft = "";
10346
+ button.style.paddingRight = "";
10215
10347
  }
10216
10348
  if (sendButtonConfig.paddingY) {
10217
- sendButton.style.paddingTop = sendButtonConfig.paddingY;
10218
- sendButton.style.paddingBottom = sendButtonConfig.paddingY;
10349
+ button.style.paddingTop = sendButtonConfig.paddingY;
10350
+ button.style.paddingBottom = sendButtonConfig.paddingY;
10219
10351
  } else {
10220
- sendButton.style.paddingTop = "";
10221
- sendButton.style.paddingBottom = "";
10352
+ button.style.paddingTop = "";
10353
+ button.style.paddingBottom = "";
10222
10354
  }
10223
- let sendTooltip = null;
10355
+ let tooltip = null;
10224
10356
  if (showTooltip && tooltipText) {
10225
- sendTooltip = createElement("div", "persona-send-button-tooltip");
10226
- sendTooltip.textContent = tooltipText;
10227
- sendButtonWrapper.appendChild(sendTooltip);
10357
+ tooltip = createElement("div", "persona-send-button-tooltip");
10358
+ tooltip.textContent = tooltipText;
10359
+ wrapper.appendChild(tooltip);
10228
10360
  }
10229
- sendButton.setAttribute("aria-label", tooltipText);
10230
- sendButtonWrapper.appendChild(sendButton);
10361
+ button.setAttribute("aria-label", tooltipText);
10362
+ wrapper.appendChild(button);
10231
10363
  let currentMode = "send";
10232
- const setSendButtonMode = (mode) => {
10364
+ const setMode = (mode) => {
10233
10365
  if (mode === currentMode) return;
10234
10366
  currentMode = mode;
10235
10367
  const label = mode === "stop" ? stopTooltipText : tooltipText;
10236
- sendButton.setAttribute("aria-label", label);
10237
- if (sendTooltip) {
10238
- sendTooltip.textContent = label;
10368
+ button.setAttribute("aria-label", label);
10369
+ if (tooltip) {
10370
+ tooltip.textContent = label;
10239
10371
  }
10240
10372
  if (useIcon) {
10241
10373
  if (sendIcon && stopIcon) {
10242
10374
  const next = mode === "stop" ? stopIcon : sendIcon;
10243
10375
  const prev = mode === "stop" ? sendIcon : stopIcon;
10244
- if (prev.parentNode === sendButton) {
10245
- sendButton.replaceChild(next, prev);
10376
+ if (prev.parentNode === button) {
10377
+ button.replaceChild(next, prev);
10246
10378
  } else {
10247
- sendButton.appendChild(next);
10379
+ button.appendChild(next);
10248
10380
  }
10249
10381
  }
10250
10382
  } else {
10251
- sendButton.textContent = mode === "stop" ? stopLabel : sendLabel;
10383
+ button.textContent = mode === "stop" ? stopLabel : sendLabel;
10252
10384
  }
10253
10385
  };
10254
- const voiceRecognitionConfig = (_o = config == null ? void 0 : config.voiceRecognition) != null ? _o : {};
10386
+ return { button, wrapper, setMode };
10387
+ };
10388
+ var createMicButton = (config) => {
10389
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
10390
+ const voiceRecognitionConfig = (_a = config == null ? void 0 : config.voiceRecognition) != null ? _a : {};
10255
10391
  const voiceRecognitionEnabled = voiceRecognitionConfig.enabled === true;
10256
- let micButton = null;
10257
- let micButtonWrapper = null;
10392
+ if (!voiceRecognitionEnabled) return null;
10258
10393
  const hasSpeechRecognition = typeof window !== "undefined" && (typeof window.webkitSpeechRecognition !== "undefined" || typeof window.SpeechRecognition !== "undefined");
10259
- const hasRuntypeProvider = ((_p = voiceRecognitionConfig.provider) == null ? void 0 : _p.type) === "runtype";
10394
+ const hasRuntypeProvider = ((_b = voiceRecognitionConfig.provider) == null ? void 0 : _b.type) === "runtype";
10260
10395
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
10261
- if (voiceRecognitionEnabled && hasVoiceInput) {
10262
- micButtonWrapper = createElement("div", "persona-send-button-wrapper");
10263
- micButton = createElement(
10264
- "button",
10265
- "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer"
10266
- );
10267
- micButton.type = "button";
10268
- micButton.setAttribute("data-persona-composer-mic", "");
10269
- micButton.setAttribute("aria-label", "Start voice recognition");
10270
- const micIconName = (_q = voiceRecognitionConfig.iconName) != null ? _q : "mic";
10271
- const micIconSize = (_r = voiceRecognitionConfig.iconSize) != null ? _r : buttonSize;
10272
- const micIconSizeNum = parseFloat(micIconSize) || 24;
10273
- const micBackgroundColor = (_s = voiceRecognitionConfig.backgroundColor) != null ? _s : backgroundColor;
10274
- const micIconColor = (_t = voiceRecognitionConfig.iconColor) != null ? _t : textColor;
10275
- micButton.style.width = micIconSize;
10276
- micButton.style.height = micIconSize;
10277
- micButton.style.minWidth = micIconSize;
10278
- micButton.style.minHeight = micIconSize;
10279
- micButton.style.fontSize = "18px";
10280
- micButton.style.lineHeight = "1";
10281
- if (micIconColor) {
10282
- micButton.style.color = micIconColor;
10283
- } else {
10284
- micButton.style.color = "var(--persona-text, #111827)";
10285
- }
10286
- const iconColorValue = micIconColor || "currentColor";
10287
- const micIconSvg = renderLucideIcon(
10288
- micIconName,
10289
- micIconSizeNum,
10290
- iconColorValue,
10291
- 1.5
10292
- );
10293
- if (micIconSvg) {
10294
- micButton.appendChild(micIconSvg);
10295
- } else {
10296
- micButton.textContent = "\u{1F3A4}";
10297
- }
10298
- if (micBackgroundColor) {
10299
- micButton.style.backgroundColor = micBackgroundColor;
10300
- }
10301
- if (voiceRecognitionConfig.borderWidth) {
10302
- micButton.style.borderWidth = voiceRecognitionConfig.borderWidth;
10303
- micButton.style.borderStyle = "solid";
10304
- }
10305
- if (voiceRecognitionConfig.borderColor) {
10306
- micButton.style.borderColor = voiceRecognitionConfig.borderColor;
10307
- }
10308
- if (voiceRecognitionConfig.paddingX) {
10309
- micButton.style.paddingLeft = voiceRecognitionConfig.paddingX;
10310
- micButton.style.paddingRight = voiceRecognitionConfig.paddingX;
10311
- }
10312
- if (voiceRecognitionConfig.paddingY) {
10313
- micButton.style.paddingTop = voiceRecognitionConfig.paddingY;
10314
- micButton.style.paddingBottom = voiceRecognitionConfig.paddingY;
10315
- }
10316
- micButtonWrapper.appendChild(micButton);
10317
- const micTooltipText = (_u = voiceRecognitionConfig.tooltipText) != null ? _u : "Start voice recognition";
10318
- const showMicTooltip = (_v = voiceRecognitionConfig.showTooltip) != null ? _v : false;
10319
- if (showMicTooltip && micTooltipText) {
10320
- const tooltip = createElement("div", "persona-send-button-tooltip");
10321
- tooltip.textContent = micTooltipText;
10322
- micButtonWrapper.appendChild(tooltip);
10323
- }
10324
- }
10325
- const attachmentsConfig = (_w = config == null ? void 0 : config.attachments) != null ? _w : {};
10326
- const attachmentsEnabled = attachmentsConfig.enabled === true;
10327
- let attachmentButton = null;
10328
- let attachmentButtonWrapper = null;
10329
- let attachmentInput = null;
10330
- let attachmentPreviewsContainer = null;
10331
- if (attachmentsEnabled) {
10332
- attachmentPreviewsContainer = createElement(
10333
- "div",
10334
- "persona-attachment-previews persona-flex persona-flex-wrap persona-gap-2 persona-mb-2"
10335
- );
10336
- attachmentPreviewsContainer.style.display = "none";
10337
- attachmentInput = createElement("input");
10338
- attachmentInput.type = "file";
10339
- attachmentInput.accept = ((_x = attachmentsConfig.allowedTypes) != null ? _x : ALL_SUPPORTED_MIME_TYPES).join(",");
10340
- attachmentInput.multiple = ((_y = attachmentsConfig.maxFiles) != null ? _y : 4) > 1;
10341
- attachmentInput.style.display = "none";
10342
- attachmentInput.setAttribute("aria-label", "Attach files");
10343
- attachmentButtonWrapper = createElement("div", "persona-send-button-wrapper");
10344
- attachmentButton = createElement(
10345
- "button",
10346
- "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
10347
- );
10348
- attachmentButton.type = "button";
10349
- attachmentButton.setAttribute("aria-label", (_z = attachmentsConfig.buttonTooltipText) != null ? _z : "Attach file");
10350
- const attachIconName = (_A = attachmentsConfig.buttonIconName) != null ? _A : "paperclip";
10351
- const attachIconSize = buttonSize;
10352
- const buttonSizeNum = parseFloat(attachIconSize) || 40;
10353
- const attachIconSizeNum = Math.round(buttonSizeNum * 0.6);
10354
- attachmentButton.style.width = attachIconSize;
10355
- attachmentButton.style.height = attachIconSize;
10356
- attachmentButton.style.minWidth = attachIconSize;
10357
- attachmentButton.style.minHeight = attachIconSize;
10358
- attachmentButton.style.fontSize = "18px";
10359
- attachmentButton.style.lineHeight = "1";
10360
- attachmentButton.style.backgroundColor = "transparent";
10361
- attachmentButton.style.color = "var(--persona-primary, #111827)";
10362
- attachmentButton.style.border = "none";
10363
- attachmentButton.style.borderRadius = "6px";
10364
- attachmentButton.style.transition = "background-color 0.15s ease";
10365
- attachmentButton.addEventListener("mouseenter", () => {
10366
- attachmentButton.style.backgroundColor = "var(--persona-palette-colors-black-alpha-50, rgba(0, 0, 0, 0.05))";
10367
- });
10368
- attachmentButton.addEventListener("mouseleave", () => {
10369
- attachmentButton.style.backgroundColor = "transparent";
10370
- });
10371
- const attachIconSvg = renderLucideIcon(
10372
- attachIconName,
10373
- attachIconSizeNum,
10374
- "currentColor",
10375
- 1.5
10376
- );
10377
- if (attachIconSvg) {
10378
- attachmentButton.appendChild(attachIconSvg);
10379
- } else {
10380
- attachmentButton.textContent = "\u{1F4CE}";
10381
- }
10382
- attachmentButton.addEventListener("click", (e) => {
10383
- e.preventDefault();
10384
- attachmentInput == null ? void 0 : attachmentInput.click();
10385
- });
10386
- attachmentButtonWrapper.appendChild(attachmentButton);
10387
- const attachTooltipText = (_B = attachmentsConfig.buttonTooltipText) != null ? _B : "Attach file";
10396
+ if (!hasVoiceInput) return null;
10397
+ const buttonSize = (_d = (_c = config == null ? void 0 : config.sendButton) == null ? void 0 : _c.size) != null ? _d : "40px";
10398
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10399
+ const button = createElement(
10400
+ "button",
10401
+ "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer"
10402
+ );
10403
+ button.type = "button";
10404
+ button.setAttribute("data-persona-composer-mic", "");
10405
+ button.setAttribute("aria-label", "Start voice recognition");
10406
+ const micIconName = (_e = voiceRecognitionConfig.iconName) != null ? _e : "mic";
10407
+ const micIconSize = (_f = voiceRecognitionConfig.iconSize) != null ? _f : buttonSize;
10408
+ const micIconSizeNum = parseFloat(micIconSize) || 24;
10409
+ const micBackgroundColor = (_h = voiceRecognitionConfig.backgroundColor) != null ? _h : (_g = config == null ? void 0 : config.sendButton) == null ? void 0 : _g.backgroundColor;
10410
+ const micIconColor = (_j = voiceRecognitionConfig.iconColor) != null ? _j : (_i = config == null ? void 0 : config.sendButton) == null ? void 0 : _i.textColor;
10411
+ button.style.width = micIconSize;
10412
+ button.style.height = micIconSize;
10413
+ button.style.minWidth = micIconSize;
10414
+ button.style.minHeight = micIconSize;
10415
+ button.style.fontSize = "18px";
10416
+ button.style.lineHeight = "1";
10417
+ if (micIconColor) {
10418
+ button.style.color = micIconColor;
10419
+ } else {
10420
+ button.style.color = "var(--persona-text, #111827)";
10421
+ }
10422
+ const iconColorValue = micIconColor || "currentColor";
10423
+ const micIconSvg = renderLucideIcon(micIconName, micIconSizeNum, iconColorValue, 1.5);
10424
+ if (micIconSvg) {
10425
+ button.appendChild(micIconSvg);
10426
+ } else {
10427
+ button.textContent = "\u{1F3A4}";
10428
+ }
10429
+ if (micBackgroundColor) {
10430
+ button.style.backgroundColor = micBackgroundColor;
10431
+ }
10432
+ if (voiceRecognitionConfig.borderWidth) {
10433
+ button.style.borderWidth = voiceRecognitionConfig.borderWidth;
10434
+ button.style.borderStyle = "solid";
10435
+ }
10436
+ if (voiceRecognitionConfig.borderColor) {
10437
+ button.style.borderColor = voiceRecognitionConfig.borderColor;
10438
+ }
10439
+ if (voiceRecognitionConfig.paddingX) {
10440
+ button.style.paddingLeft = voiceRecognitionConfig.paddingX;
10441
+ button.style.paddingRight = voiceRecognitionConfig.paddingX;
10442
+ }
10443
+ if (voiceRecognitionConfig.paddingY) {
10444
+ button.style.paddingTop = voiceRecognitionConfig.paddingY;
10445
+ button.style.paddingBottom = voiceRecognitionConfig.paddingY;
10446
+ }
10447
+ wrapper.appendChild(button);
10448
+ const micTooltipText = (_k = voiceRecognitionConfig.tooltipText) != null ? _k : "Start voice recognition";
10449
+ const showMicTooltip = (_l = voiceRecognitionConfig.showTooltip) != null ? _l : false;
10450
+ if (showMicTooltip && micTooltipText) {
10388
10451
  const tooltip = createElement("div", "persona-send-button-tooltip");
10389
- tooltip.textContent = attachTooltipText;
10390
- attachmentButtonWrapper.appendChild(tooltip);
10452
+ tooltip.textContent = micTooltipText;
10453
+ wrapper.appendChild(tooltip);
10454
+ }
10455
+ return { button, wrapper };
10456
+ };
10457
+ var createAttachmentControls = (config) => {
10458
+ var _a, _b, _c, _d, _e, _f, _g, _h;
10459
+ const attachmentsConfig = (_a = config == null ? void 0 : config.attachments) != null ? _a : {};
10460
+ if (attachmentsConfig.enabled !== true) return null;
10461
+ const buttonSize = (_c = (_b = config == null ? void 0 : config.sendButton) == null ? void 0 : _b.size) != null ? _c : "40px";
10462
+ const previewsContainer = createElement(
10463
+ "div",
10464
+ "persona-attachment-previews persona-flex persona-flex-wrap persona-gap-2 persona-mb-2"
10465
+ );
10466
+ previewsContainer.style.display = "none";
10467
+ const input = createElement("input");
10468
+ input.type = "file";
10469
+ input.accept = ((_d = attachmentsConfig.allowedTypes) != null ? _d : ALL_SUPPORTED_MIME_TYPES).join(",");
10470
+ input.multiple = ((_e = attachmentsConfig.maxFiles) != null ? _e : 4) > 1;
10471
+ input.style.display = "none";
10472
+ input.setAttribute("aria-label", "Attach files");
10473
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10474
+ const button = createElement(
10475
+ "button",
10476
+ "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
10477
+ );
10478
+ button.type = "button";
10479
+ button.setAttribute("aria-label", (_f = attachmentsConfig.buttonTooltipText) != null ? _f : "Attach file");
10480
+ const attachIconName = (_g = attachmentsConfig.buttonIconName) != null ? _g : "paperclip";
10481
+ const attachIconSize = buttonSize;
10482
+ const buttonSizeNum = parseFloat(attachIconSize) || 40;
10483
+ const attachIconSizeNum = Math.round(buttonSizeNum * 0.6);
10484
+ button.style.width = attachIconSize;
10485
+ button.style.height = attachIconSize;
10486
+ button.style.minWidth = attachIconSize;
10487
+ button.style.minHeight = attachIconSize;
10488
+ button.style.fontSize = "18px";
10489
+ button.style.lineHeight = "1";
10490
+ button.style.backgroundColor = "transparent";
10491
+ button.style.color = "var(--persona-primary, #111827)";
10492
+ button.style.border = "none";
10493
+ button.style.borderRadius = "6px";
10494
+ button.style.transition = "background-color 0.15s ease";
10495
+ button.addEventListener("mouseenter", () => {
10496
+ button.style.backgroundColor = "var(--persona-palette-colors-black-alpha-50, rgba(0, 0, 0, 0.05))";
10497
+ });
10498
+ button.addEventListener("mouseleave", () => {
10499
+ button.style.backgroundColor = "transparent";
10500
+ });
10501
+ const attachIconSvg = renderLucideIcon(attachIconName, attachIconSizeNum, "currentColor", 1.5);
10502
+ if (attachIconSvg) {
10503
+ button.appendChild(attachIconSvg);
10504
+ } else {
10505
+ button.textContent = "\u{1F4CE}";
10506
+ }
10507
+ button.addEventListener("click", (e) => {
10508
+ e.preventDefault();
10509
+ input.click();
10510
+ });
10511
+ wrapper.appendChild(button);
10512
+ const attachTooltipText = (_h = attachmentsConfig.buttonTooltipText) != null ? _h : "Attach file";
10513
+ const tooltip = createElement("div", "persona-send-button-tooltip");
10514
+ tooltip.textContent = attachTooltipText;
10515
+ wrapper.appendChild(tooltip);
10516
+ return { button, wrapper, input, previewsContainer };
10517
+ };
10518
+ var createStatusText = (config) => {
10519
+ var _a, _b, _c;
10520
+ const statusConfig = (_a = config == null ? void 0 : config.statusIndicator) != null ? _a : {};
10521
+ const alignClass = statusConfig.align === "left" ? "persona-text-left" : statusConfig.align === "center" ? "persona-text-center" : "persona-text-right";
10522
+ const statusText = createElement(
10523
+ "div",
10524
+ `persona-mt-2 ${alignClass} persona-text-xs persona-text-persona-muted`
10525
+ );
10526
+ statusText.setAttribute("data-persona-composer-status", "");
10527
+ const isVisible = (_b = statusConfig.visible) != null ? _b : true;
10528
+ statusText.style.display = isVisible ? "" : "none";
10529
+ const idleLabel = (_c = statusConfig.idleText) != null ? _c : "Online";
10530
+ if (statusConfig.idleLink) {
10531
+ const link = createElement("a");
10532
+ link.href = statusConfig.idleLink;
10533
+ link.target = "_blank";
10534
+ link.rel = "noopener noreferrer";
10535
+ link.textContent = idleLabel;
10536
+ link.style.color = "inherit";
10537
+ link.style.textDecoration = "none";
10538
+ statusText.appendChild(link);
10539
+ } else {
10540
+ statusText.textContent = idleLabel;
10541
+ }
10542
+ return statusText;
10543
+ };
10544
+ var createSuggestionsRow = () => createElement("div", "persona-mb-3 persona-flex persona-flex-wrap persona-gap-2");
10545
+
10546
+ // src/components/composer-builder.ts
10547
+ var buildComposer = (context) => {
10548
+ var _a, _b, _c, _d, _e, _f;
10549
+ const { config } = context;
10550
+ const footer = createElement(
10551
+ "div",
10552
+ "persona-widget-footer persona-border-t-persona-divider persona-bg-persona-surface persona-px-6 persona-py-4"
10553
+ );
10554
+ footer.setAttribute("data-persona-theme-zone", "composer");
10555
+ const suggestions = createSuggestionsRow();
10556
+ const composerForm = createElement(
10557
+ "form",
10558
+ "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"
10559
+ );
10560
+ composerForm.setAttribute("data-persona-composer-form", "");
10561
+ composerForm.style.outline = "none";
10562
+ const { textarea, attachAutoResize } = createComposerTextarea(config);
10563
+ attachAutoResize();
10564
+ const send = createSendButton(config);
10565
+ const mic = createMicButton(config);
10566
+ const attachment = createAttachmentControls(config);
10567
+ const statusText = createStatusText(config);
10568
+ if (attachment) {
10569
+ attachment.previewsContainer.style.gap = "8px";
10570
+ composerForm.append(attachment.previewsContainer, attachment.input);
10571
+ }
10572
+ composerForm.append(textarea);
10573
+ const actionsRow = createElement(
10574
+ "div",
10575
+ "persona-widget-composer__actions persona-flex persona-items-center persona-justify-between persona-w-full"
10576
+ );
10577
+ const leftActions = createElement(
10578
+ "div",
10579
+ "persona-widget-composer__left-actions persona-flex persona-items-center persona-gap-2"
10580
+ );
10581
+ const rightActions = createElement(
10582
+ "div",
10583
+ "persona-widget-composer__right-actions persona-flex persona-items-center persona-gap-1"
10584
+ );
10585
+ if (attachment) leftActions.append(attachment.wrapper);
10586
+ if (mic) rightActions.append(mic.wrapper);
10587
+ rightActions.append(send.wrapper);
10588
+ actionsRow.append(leftActions, rightActions);
10589
+ composerForm.append(actionsRow);
10590
+ composerForm.addEventListener("click", (e) => {
10591
+ 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)) {
10592
+ textarea.focus();
10593
+ }
10594
+ });
10595
+ footer.append(suggestions, composerForm, statusText);
10596
+ return {
10597
+ footer,
10598
+ suggestions,
10599
+ composerForm,
10600
+ textarea,
10601
+ sendButton: send.button,
10602
+ sendButtonWrapper: send.wrapper,
10603
+ micButton: (_a = mic == null ? void 0 : mic.button) != null ? _a : null,
10604
+ micButtonWrapper: (_b = mic == null ? void 0 : mic.wrapper) != null ? _b : null,
10605
+ statusText,
10606
+ attachmentButton: (_c = attachment == null ? void 0 : attachment.button) != null ? _c : null,
10607
+ attachmentButtonWrapper: (_d = attachment == null ? void 0 : attachment.wrapper) != null ? _d : null,
10608
+ attachmentInput: (_e = attachment == null ? void 0 : attachment.input) != null ? _e : null,
10609
+ attachmentPreviewsContainer: (_f = attachment == null ? void 0 : attachment.previewsContainer) != null ? _f : null,
10610
+ actionsRow,
10611
+ leftActions,
10612
+ rightActions,
10613
+ setSendButtonMode: send.setMode
10614
+ };
10615
+ };
10616
+
10617
+ // src/components/pill-composer-builder.ts
10618
+ var buildPillPeekBanner = () => {
10619
+ const root = createElement("button", "persona-pill-peek");
10620
+ root.type = "button";
10621
+ root.setAttribute("data-persona-pill-peek", "");
10622
+ root.setAttribute("aria-label", "Show conversation");
10623
+ root.setAttribute("tabindex", "-1");
10624
+ const iconHolder = createElement("span", "persona-pill-peek__icon");
10625
+ const messageIcon = renderLucideIcon("message-square", 16, "currentColor", 1.5);
10626
+ if (messageIcon) {
10627
+ iconHolder.appendChild(messageIcon);
10628
+ }
10629
+ const textNode = createElement("span", "persona-pill-peek__text");
10630
+ const caret = createElement("span", "persona-pill-peek__caret");
10631
+ const caretIcon = renderLucideIcon("chevron-up", 16, "currentColor", 1.5);
10632
+ if (caretIcon) {
10633
+ caret.appendChild(caretIcon);
10634
+ }
10635
+ root.append(iconHolder, textNode, caret);
10636
+ return { root, textNode };
10637
+ };
10638
+ var buildPillComposer = (context) => {
10639
+ var _a, _b, _c, _d, _e, _f;
10640
+ const { config } = context;
10641
+ const footer = createElement("div", "persona-widget-footer persona-widget-footer--pill");
10642
+ footer.setAttribute("data-persona-theme-zone", "composer");
10643
+ const suggestions = createSuggestionsRow();
10644
+ suggestions.style.display = "none";
10645
+ const statusText = createStatusText(config);
10646
+ statusText.style.display = "none";
10647
+ const { textarea, attachAutoResize } = createComposerTextarea(config);
10648
+ textarea.style.maxHeight = "100px";
10649
+ attachAutoResize();
10650
+ const send = createSendButton(config);
10651
+ const mic = createMicButton(config);
10652
+ const attachment = createAttachmentControls(config);
10653
+ if (attachment) {
10654
+ attachment.previewsContainer.classList.add("persona-pill-composer__previews");
10391
10655
  }
10656
+ const composerForm = createElement(
10657
+ "form",
10658
+ "persona-widget-composer persona-pill-composer"
10659
+ );
10660
+ composerForm.setAttribute("data-persona-composer-form", "");
10661
+ composerForm.style.outline = "none";
10662
+ const leftActions = createElement(
10663
+ "div",
10664
+ "persona-widget-composer__left-actions persona-pill-composer__left"
10665
+ );
10666
+ if (attachment) leftActions.append(attachment.wrapper);
10667
+ const rightActions = createElement(
10668
+ "div",
10669
+ "persona-widget-composer__right-actions persona-pill-composer__right"
10670
+ );
10671
+ if (mic) rightActions.append(mic.wrapper);
10672
+ rightActions.append(send.wrapper);
10392
10673
  composerForm.addEventListener("click", (e) => {
10393
- if (e.target !== sendButton && e.target !== sendButtonWrapper && e.target !== micButton && e.target !== micButtonWrapper && e.target !== attachmentButton && e.target !== attachmentButtonWrapper) {
10674
+ 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)) {
10394
10675
  textarea.focus();
10395
10676
  }
10396
10677
  });
10397
- if (attachmentPreviewsContainer) {
10398
- attachmentPreviewsContainer.style.gap = "8px";
10399
- composerForm.append(attachmentPreviewsContainer);
10400
- }
10401
- if (attachmentInput) {
10402
- composerForm.append(attachmentInput);
10403
- }
10404
- composerForm.append(textarea);
10405
- const actionsRow = createElement("div", "persona-flex persona-items-center persona-justify-between persona-w-full");
10406
- const leftActions = createElement("div", "persona-flex persona-items-center persona-gap-2");
10407
- if (attachmentButtonWrapper) {
10408
- leftActions.append(attachmentButtonWrapper);
10409
- }
10410
- const rightActions = createElement("div", "persona-flex persona-items-center persona-gap-1");
10411
- if (micButtonWrapper) {
10412
- rightActions.append(micButtonWrapper);
10413
- }
10414
- rightActions.append(sendButtonWrapper);
10415
- actionsRow.append(leftActions, rightActions);
10416
- composerForm.append(actionsRow);
10417
- const statusConfig = (_C = config == null ? void 0 : config.statusIndicator) != null ? _C : {};
10418
- const alignClass = statusConfig.align === "left" ? "persona-text-left" : statusConfig.align === "center" ? "persona-text-center" : "persona-text-right";
10419
- const statusText = createElement(
10420
- "div",
10421
- `persona-mt-2 ${alignClass} persona-text-xs persona-text-persona-muted`
10422
- );
10423
- statusText.setAttribute("data-persona-composer-status", "");
10424
- const isVisible = (_D = statusConfig.visible) != null ? _D : true;
10425
- statusText.style.display = isVisible ? "" : "none";
10426
- const idleLabel = (_E = statusConfig.idleText) != null ? _E : "Online";
10427
- if (statusConfig.idleLink) {
10428
- const link = createElement("a");
10429
- link.href = statusConfig.idleLink;
10430
- link.target = "_blank";
10431
- link.rel = "noopener noreferrer";
10432
- link.textContent = idleLabel;
10433
- link.style.color = "inherit";
10434
- link.style.textDecoration = "none";
10435
- statusText.appendChild(link);
10436
- } else {
10437
- statusText.textContent = idleLabel;
10438
- }
10439
- footer.append(suggestions, composerForm, statusText);
10678
+ if (attachment) composerForm.append(attachment.input);
10679
+ composerForm.append(leftActions, textarea, rightActions);
10680
+ if (attachment) footer.append(attachment.previewsContainer);
10681
+ footer.append(composerForm, suggestions, statusText);
10682
+ const actionsRow = composerForm;
10440
10683
  return {
10441
10684
  footer,
10442
10685
  suggestions,
10443
10686
  composerForm,
10444
10687
  textarea,
10445
- sendButton,
10446
- sendButtonWrapper,
10447
- micButton,
10448
- micButtonWrapper,
10688
+ sendButton: send.button,
10689
+ sendButtonWrapper: send.wrapper,
10690
+ micButton: (_a = mic == null ? void 0 : mic.button) != null ? _a : null,
10691
+ micButtonWrapper: (_b = mic == null ? void 0 : mic.wrapper) != null ? _b : null,
10449
10692
  statusText,
10450
- // Attachment elements
10451
- attachmentButton,
10452
- attachmentButtonWrapper,
10453
- attachmentInput,
10454
- attachmentPreviewsContainer,
10455
- // Actions row layout elements
10693
+ attachmentButton: (_c = attachment == null ? void 0 : attachment.button) != null ? _c : null,
10694
+ attachmentButtonWrapper: (_d = attachment == null ? void 0 : attachment.wrapper) != null ? _d : null,
10695
+ attachmentInput: (_e = attachment == null ? void 0 : attachment.input) != null ? _e : null,
10696
+ attachmentPreviewsContainer: (_f = attachment == null ? void 0 : attachment.previewsContainer) != null ? _f : null,
10456
10697
  actionsRow,
10457
10698
  leftActions,
10458
10699
  rightActions,
10459
- setSendButtonMode
10700
+ setSendButtonMode: send.setMode
10460
10701
  };
10461
10702
  };
10462
10703
 
10463
10704
  // src/components/panel.ts
10464
10705
  var createWrapper = (config) => {
10465
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10706
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
10466
10707
  const launcherEnabled = (_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.enabled) != null ? _b : true;
10467
10708
  const dockedMode = isDockedMountMode(config);
10709
+ const composerBarMode = isComposerBarMountMode(config);
10710
+ if (composerBarMode) {
10711
+ const cb = (_d = (_c = config == null ? void 0 : config.launcher) == null ? void 0 : _c.composerBar) != null ? _d : {};
10712
+ const wrapper2 = createElement(
10713
+ "div",
10714
+ "persona-widget-wrapper persona-fixed persona-transition"
10715
+ );
10716
+ wrapper2.setAttribute("data-persona-composer-bar", "");
10717
+ wrapper2.dataset.state = "collapsed";
10718
+ wrapper2.dataset.expandedSize = (_e = cb.expandedSize) != null ? _e : "anchored";
10719
+ wrapper2.style.zIndex = String(
10720
+ (_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.zIndex) != null ? _g : DEFAULT_OVERLAY_Z_INDEX
10721
+ );
10722
+ const panel2 = createElement(
10723
+ "div",
10724
+ "persona-widget-panel persona-relative persona-flex persona-flex-1 persona-min-h-0 persona-flex-col"
10725
+ );
10726
+ panel2.style.width = "100%";
10727
+ wrapper2.appendChild(panel2);
10728
+ const pillRoot = createElement("div", "persona-widget-pill-root");
10729
+ pillRoot.setAttribute("data-persona-composer-bar", "");
10730
+ pillRoot.dataset.state = "collapsed";
10731
+ pillRoot.dataset.expandedSize = (_h = cb.expandedSize) != null ? _h : "anchored";
10732
+ pillRoot.style.zIndex = String(
10733
+ (_j = (_i = config == null ? void 0 : config.launcher) == null ? void 0 : _i.zIndex) != null ? _j : DEFAULT_OVERLAY_Z_INDEX
10734
+ );
10735
+ return { wrapper: wrapper2, panel: panel2, pillRoot };
10736
+ }
10468
10737
  if (dockedMode) {
10469
10738
  const wrapper2 = createElement(
10470
10739
  "div",
@@ -10486,35 +10755,171 @@ var createWrapper = (config) => {
10486
10755
  "div",
10487
10756
  "persona-relative persona-flex-1 persona-flex persona-flex-col persona-min-h-0"
10488
10757
  );
10489
- const inlineWidth = (_d = (_c = config == null ? void 0 : config.launcher) == null ? void 0 : _c.width) != null ? _d : "100%";
10758
+ const inlineWidth = (_l = (_k = config == null ? void 0 : config.launcher) == null ? void 0 : _k.width) != null ? _l : "100%";
10490
10759
  wrapper2.style.width = inlineWidth;
10491
10760
  panel2.style.width = "100%";
10492
10761
  wrapper2.appendChild(panel2);
10493
10762
  return { wrapper: wrapper2, panel: panel2 };
10494
10763
  }
10495
- const launcher = (_e = config == null ? void 0 : config.launcher) != null ? _e : {};
10764
+ const launcher = (_m = config == null ? void 0 : config.launcher) != null ? _m : {};
10496
10765
  const position = launcher.position && positionMap[launcher.position] ? positionMap[launcher.position] : positionMap["bottom-right"];
10497
10766
  const wrapper = createElement(
10498
10767
  "div",
10499
10768
  `persona-widget-wrapper persona-fixed ${position} persona-transition`
10500
10769
  );
10501
- wrapper.style.zIndex = String((_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.zIndex) != null ? _g : DEFAULT_OVERLAY_Z_INDEX);
10770
+ wrapper.style.zIndex = String((_o = (_n = config == null ? void 0 : config.launcher) == null ? void 0 : _n.zIndex) != null ? _o : DEFAULT_OVERLAY_Z_INDEX);
10502
10771
  const panel = createElement(
10503
10772
  "div",
10504
10773
  "persona-widget-panel persona-relative persona-min-h-[320px]"
10505
10774
  );
10506
- const launcherWidth = (_i = (_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.width) != null ? _i : config == null ? void 0 : config.launcherWidth;
10775
+ const launcherWidth = (_q = (_p = config == null ? void 0 : config.launcher) == null ? void 0 : _p.width) != null ? _q : config == null ? void 0 : config.launcherWidth;
10507
10776
  const width = launcherWidth != null ? launcherWidth : DEFAULT_FLOATING_LAUNCHER_WIDTH;
10508
10777
  panel.style.width = width;
10509
10778
  panel.style.maxWidth = width;
10510
10779
  wrapper.appendChild(panel);
10511
10780
  return { wrapper, panel };
10512
10781
  };
10782
+ var buildComposerBarPanel = (config, showClose) => {
10783
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10784
+ const container = createElement(
10785
+ "div",
10786
+ "persona-widget-container persona-relative persona-flex persona-flex-1 persona-min-h-0 persona-flex-col persona-text-persona-primary"
10787
+ );
10788
+ container.setAttribute("data-persona-theme-zone", "container");
10789
+ const { button: closeButton, wrapper: closeButtonWrapper } = createCloseButton(
10790
+ config,
10791
+ {
10792
+ showClose,
10793
+ wrapperClassName: "persona-composer-bar-close",
10794
+ buttonSize: "16px",
10795
+ iconSize: "14px"
10796
+ }
10797
+ );
10798
+ closeButtonWrapper.style.position = "absolute";
10799
+ closeButtonWrapper.style.top = "8px";
10800
+ closeButtonWrapper.style.right = "8px";
10801
+ closeButtonWrapper.style.zIndex = "10";
10802
+ const clearChatEnabled = (_c = (_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.clearChat) == null ? void 0 : _b.enabled) != null ? _c : true;
10803
+ let clearChatButton = null;
10804
+ let clearChatButtonWrapper = null;
10805
+ if (clearChatEnabled) {
10806
+ const parts = createClearChatButton(config, {
10807
+ wrapperClassName: "persona-composer-bar-clear-chat",
10808
+ buttonSize: "16px",
10809
+ iconSize: "14px"
10810
+ });
10811
+ clearChatButton = parts.button;
10812
+ clearChatButtonWrapper = parts.wrapper;
10813
+ clearChatButtonWrapper.style.position = "absolute";
10814
+ clearChatButtonWrapper.style.top = "8px";
10815
+ clearChatButtonWrapper.style.right = "32px";
10816
+ clearChatButtonWrapper.style.zIndex = "10";
10817
+ }
10818
+ const headerPlaceholder = createElement("span", "persona-widget-header");
10819
+ headerPlaceholder.setAttribute("data-persona-theme-zone", "header");
10820
+ headerPlaceholder.style.display = "none";
10821
+ const body = createElement(
10822
+ "div",
10823
+ "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"
10824
+ );
10825
+ body.style.paddingTop = "48px";
10826
+ body.id = "persona-scroll-container";
10827
+ body.setAttribute("data-persona-theme-zone", "messages");
10828
+ const introCard = createElement(
10829
+ "div",
10830
+ "persona-rounded-2xl persona-bg-persona-surface persona-p-6"
10831
+ );
10832
+ introCard.style.boxShadow = "var(--persona-intro-card-shadow, 0 5px 15px rgba(15, 23, 42, 0.08))";
10833
+ introCard.setAttribute("data-persona-intro-card", "");
10834
+ const introTitle = createElement(
10835
+ "h2",
10836
+ "persona-text-lg persona-font-semibold persona-text-persona-primary"
10837
+ );
10838
+ introTitle.textContent = (_e = (_d = config == null ? void 0 : config.copy) == null ? void 0 : _d.welcomeTitle) != null ? _e : "Hello \u{1F44B}";
10839
+ const introSubtitle = createElement(
10840
+ "p",
10841
+ "persona-mt-2 persona-text-sm persona-text-persona-muted"
10842
+ );
10843
+ introSubtitle.textContent = (_g = (_f = config == null ? void 0 : config.copy) == null ? void 0 : _f.welcomeSubtitle) != null ? _g : "Ask anything about your account or products.";
10844
+ introCard.append(introTitle, introSubtitle);
10845
+ const messagesWrapper = createElement(
10846
+ "div",
10847
+ "persona-flex persona-flex-col persona-gap-3"
10848
+ );
10849
+ const contentMaxWidth = (_h = config == null ? void 0 : config.layout) == null ? void 0 : _h.contentMaxWidth;
10850
+ if (contentMaxWidth) {
10851
+ messagesWrapper.style.maxWidth = contentMaxWidth;
10852
+ messagesWrapper.style.marginLeft = "auto";
10853
+ messagesWrapper.style.marginRight = "auto";
10854
+ messagesWrapper.style.width = "100%";
10855
+ }
10856
+ const showWelcomeCard = ((_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.showWelcomeCard) !== false;
10857
+ if (!showWelcomeCard) {
10858
+ introCard.style.display = "none";
10859
+ body.classList.remove("persona-gap-6");
10860
+ body.classList.add("persona-gap-3");
10861
+ }
10862
+ body.append(introCard, messagesWrapper);
10863
+ const composerOverlay = createElement(
10864
+ "div",
10865
+ "persona-composer-overlay persona-pointer-events-none"
10866
+ );
10867
+ composerOverlay.setAttribute("data-persona-composer-overlay", "");
10868
+ composerOverlay.style.position = "absolute";
10869
+ composerOverlay.style.left = "0";
10870
+ composerOverlay.style.right = "0";
10871
+ composerOverlay.style.bottom = "0";
10872
+ composerOverlay.style.zIndex = "20";
10873
+ const composerElements = buildPillComposer({ config });
10874
+ const { root: peekBanner, textNode: peekTextNode } = buildPillPeekBanner();
10875
+ container.append(headerPlaceholder, closeButtonWrapper, body, composerOverlay);
10876
+ if (clearChatButtonWrapper) {
10877
+ container.appendChild(clearChatButtonWrapper);
10878
+ }
10879
+ return {
10880
+ container,
10881
+ body,
10882
+ messagesWrapper,
10883
+ composerOverlay,
10884
+ suggestions: composerElements.suggestions,
10885
+ textarea: composerElements.textarea,
10886
+ sendButton: composerElements.sendButton,
10887
+ sendButtonWrapper: composerElements.sendButtonWrapper,
10888
+ micButton: composerElements.micButton,
10889
+ micButtonWrapper: composerElements.micButtonWrapper,
10890
+ composerForm: composerElements.composerForm,
10891
+ statusText: composerElements.statusText,
10892
+ introTitle,
10893
+ introSubtitle,
10894
+ closeButton,
10895
+ closeButtonWrapper,
10896
+ clearChatButton,
10897
+ clearChatButtonWrapper,
10898
+ iconHolder: createElement("span"),
10899
+ headerTitle: createElement("span"),
10900
+ headerSubtitle: createElement("span"),
10901
+ header: headerPlaceholder,
10902
+ footer: composerElements.footer,
10903
+ attachmentButton: composerElements.attachmentButton,
10904
+ attachmentButtonWrapper: composerElements.attachmentButtonWrapper,
10905
+ attachmentInput: composerElements.attachmentInput,
10906
+ attachmentPreviewsContainer: composerElements.attachmentPreviewsContainer,
10907
+ actionsRow: composerElements.actionsRow,
10908
+ leftActions: composerElements.leftActions,
10909
+ rightActions: composerElements.rightActions,
10910
+ setSendButtonMode: composerElements.setSendButtonMode,
10911
+ peekBanner,
10912
+ peekTextNode
10913
+ };
10914
+ };
10513
10915
  var buildPanel = (config, showClose = true) => {
10514
10916
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10917
+ if (isComposerBarMountMode(config)) {
10918
+ return buildComposerBarPanel(config, showClose);
10919
+ }
10515
10920
  const container = createElement(
10516
10921
  "div",
10517
- "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"
10922
+ "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"
10518
10923
  );
10519
10924
  container.setAttribute("data-persona-theme-zone", "container");
10520
10925
  const headerLayoutConfig = (_a = config == null ? void 0 : config.layout) == null ? void 0 : _a.header;
@@ -15365,7 +15770,7 @@ function buildDropOverlay(dropCfg) {
15365
15770
  return overlay;
15366
15771
  }
15367
15772
  var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15368
- 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;
15773
+ 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;
15369
15774
  if (mount == null) {
15370
15775
  throw new Error(
15371
15776
  'createAgentExperience: mount must be a non-null HTMLElement (e.g. pass document.getElementById("my-root") after the node exists).'
@@ -15383,7 +15788,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15383
15788
  componentRegistry.registerAll(config.components);
15384
15789
  }
15385
15790
  const eventBus = createEventBus();
15386
- const storageAdapter = (_a = config.storageAdapter) != null ? _a : createLocalStorageAdapter();
15791
+ const messagePersistenceDisabled = config.persistState === false;
15792
+ const storageAdapter = messagePersistenceDisabled ? null : (_a = config.storageAdapter) != null ? _a : createLocalStorageAdapter();
15387
15793
  let persistentMetadata = {};
15388
15794
  let pendingStoredState = null;
15389
15795
  let shouldOpenAfterStateLoaded = false;
@@ -15474,7 +15880,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15474
15880
  let prevLauncherEnabled = launcherEnabled;
15475
15881
  let prevHeaderLayout = (_l = (_k = config.layout) == null ? void 0 : _k.header) == null ? void 0 : _l.layout;
15476
15882
  let wasMobileFullscreen = false;
15477
- let open = launcherEnabled ? autoExpand : true;
15883
+ const isComposerBar = () => isComposerBarMountMode(config);
15884
+ const isPanelToggleable = () => launcherEnabled || isComposerBar();
15885
+ let open = isComposerBar() ? false : launcherEnabled ? autoExpand : true;
15478
15886
  let pendingResubmit = false;
15479
15887
  let pendingResubmitTimeout = null;
15480
15888
  const handleResubmitRequested = () => {
@@ -15560,8 +15968,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15560
15968
  el.textContent = text;
15561
15969
  }
15562
15970
  }
15563
- const { wrapper, panel } = createWrapper(config);
15564
- const panelElements = buildPanel(config, launcherEnabled);
15971
+ const { wrapper, panel, pillRoot } = createWrapper(config);
15972
+ const panelElements = buildPanel(config, isPanelToggleable());
15565
15973
  let {
15566
15974
  container,
15567
15975
  body,
@@ -15644,7 +16052,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15644
16052
  const customHeader = headerPlugin.renderHeader({
15645
16053
  config,
15646
16054
  defaultRenderer: () => {
15647
- const headerElements = buildHeader({ config, showClose: launcherEnabled });
16055
+ const headerElements = buildHeader({ config, showClose: isPanelToggleable() });
15648
16056
  attachHeaderToContainer(container, headerElements, config);
15649
16057
  return headerElements.header;
15650
16058
  },
@@ -15787,6 +16195,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15787
16195
  const value = text.trim();
15788
16196
  const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
15789
16197
  if (!value && !hasAttachments) return;
16198
+ maybeExpandComposerBar();
15790
16199
  let contentParts;
15791
16200
  if (hasAttachments) {
15792
16201
  contentParts = [];
@@ -15852,23 +16261,29 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15852
16261
  };
15853
16262
  ensureComposerAttachmentSurface(footer);
15854
16263
  bindComposerRefsFromFooter(footer);
15855
- const contentMaxWidth = (_D = config.layout) == null ? void 0 : _D.contentMaxWidth;
15856
- if (contentMaxWidth && composerForm) {
16264
+ 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;
16265
+ if (contentMaxWidth) {
16266
+ messagesWrapper.style.maxWidth = contentMaxWidth;
16267
+ messagesWrapper.style.marginLeft = "auto";
16268
+ messagesWrapper.style.marginRight = "auto";
16269
+ messagesWrapper.style.width = "100%";
16270
+ }
16271
+ if (contentMaxWidth && composerForm && !isComposerBar()) {
15857
16272
  composerForm.style.maxWidth = contentMaxWidth;
15858
16273
  composerForm.style.marginLeft = "auto";
15859
16274
  composerForm.style.marginRight = "auto";
15860
16275
  }
15861
- if (contentMaxWidth && suggestions) {
16276
+ if (contentMaxWidth && suggestions && !isComposerBar()) {
15862
16277
  suggestions.style.maxWidth = contentMaxWidth;
15863
16278
  suggestions.style.marginLeft = "auto";
15864
16279
  suggestions.style.marginRight = "auto";
15865
16280
  }
15866
- if (contentMaxWidth && attachmentPreviewsContainer) {
16281
+ if (contentMaxWidth && attachmentPreviewsContainer && !isComposerBar()) {
15867
16282
  attachmentPreviewsContainer.style.maxWidth = contentMaxWidth;
15868
16283
  attachmentPreviewsContainer.style.marginLeft = "auto";
15869
16284
  attachmentPreviewsContainer.style.marginRight = "auto";
15870
16285
  }
15871
- if (((_E = config.attachments) == null ? void 0 : _E.enabled) && attachmentInput && attachmentPreviewsContainer) {
16286
+ if (((_I = config.attachments) == null ? void 0 : _I.enabled) && attachmentInput && attachmentPreviewsContainer) {
15872
16287
  attachmentManager = AttachmentManager.fromConfig(config.attachments);
15873
16288
  attachmentManager.setPreviewsContainer(attachmentPreviewsContainer);
15874
16289
  attachmentInput.addEventListener("change", (e) => {
@@ -16678,29 +17093,70 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16678
17093
  }
16679
17094
  } else {
16680
17095
  panel.appendChild(container);
17096
+ if (isComposerBar() && pillRoot) {
17097
+ if (panelElements.peekBanner) {
17098
+ pillRoot.appendChild(panelElements.peekBanner);
17099
+ }
17100
+ pillRoot.appendChild(footer);
17101
+ }
16681
17102
  }
16682
17103
  mount.appendChild(wrapper);
17104
+ if (pillRoot) {
17105
+ mount.appendChild(pillRoot);
17106
+ }
16683
17107
  const applyFullHeightStyles = () => {
16684
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2;
17108
+ 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;
17109
+ if (isComposerBar()) {
17110
+ panel.style.width = "100%";
17111
+ panel.style.maxWidth = "100%";
17112
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
17113
+ const isExpanded = wrapper.dataset.state === "expanded";
17114
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
17115
+ const wantsChrome = isExpanded && expandedSize !== "fullscreen";
17116
+ if (!wantsChrome) {
17117
+ container.style.background = "";
17118
+ container.style.border = "";
17119
+ container.style.borderRadius = "";
17120
+ container.style.overflow = "";
17121
+ container.style.boxShadow = "";
17122
+ return;
17123
+ }
17124
+ const panelPartial2 = (_e2 = (_d2 = config.theme) == null ? void 0 : _d2.components) == null ? void 0 : _e2.panel;
17125
+ const activeTheme2 = getActiveTheme(config);
17126
+ const resolveCb = (raw, fallback) => {
17127
+ var _a3;
17128
+ if (raw == null || raw === "") return fallback;
17129
+ return (_a3 = resolveTokenValue(activeTheme2, raw)) != null ? _a3 : raw;
17130
+ };
17131
+ const defaultBorder = "1px solid var(--persona-border)";
17132
+ const defaultShadow = "var(--persona-palette-shadows-xl, 0 25px 50px -12px rgba(0, 0, 0, 0.25))";
17133
+ const defaultRadius = "var(--persona-panel-radius, var(--persona-radius-xl, 0.75rem))";
17134
+ container.style.background = "var(--persona-surface, #ffffff)";
17135
+ container.style.border = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.border, defaultBorder);
17136
+ container.style.borderRadius = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.borderRadius, defaultRadius);
17137
+ container.style.boxShadow = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.shadow, defaultShadow);
17138
+ container.style.overflow = "hidden";
17139
+ return;
17140
+ }
16685
17141
  const dockedMode = isDockedMountMode(config);
16686
- const sidebarMode = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.sidebarMode) != null ? _b2 : false;
16687
- const fullHeight = dockedMode || sidebarMode || ((_d2 = (_c2 = config.launcher) == null ? void 0 : _c2.fullHeight) != null ? _d2 : false);
16688
- const isInlineEmbed = ((_e2 = config.launcher) == null ? void 0 : _e2.enabled) === false;
16689
- const panelPartial = (_g2 = (_f2 = config.theme) == null ? void 0 : _f2.components) == null ? void 0 : _g2.panel;
17142
+ const sidebarMode = (_g2 = (_f2 = config.launcher) == null ? void 0 : _f2.sidebarMode) != null ? _g2 : false;
17143
+ const fullHeight = dockedMode || sidebarMode || ((_i2 = (_h2 = config.launcher) == null ? void 0 : _h2.fullHeight) != null ? _i2 : false);
17144
+ const isInlineEmbed = ((_j2 = config.launcher) == null ? void 0 : _j2.enabled) === false;
17145
+ const panelPartial = (_l2 = (_k2 = config.theme) == null ? void 0 : _k2.components) == null ? void 0 : _l2.panel;
16690
17146
  const activeTheme = getActiveTheme(config);
16691
17147
  const resolvePanelChrome = (raw, fallback) => {
16692
17148
  var _a3;
16693
17149
  if (raw == null || raw === "") return fallback;
16694
17150
  return (_a3 = resolveTokenValue(activeTheme, raw)) != null ? _a3 : raw;
16695
17151
  };
16696
- const ownerWindow2 = (_h2 = mount.ownerDocument.defaultView) != null ? _h2 : window;
16697
- const mobileFullscreen = (_j2 = (_i2 = config.launcher) == null ? void 0 : _i2.mobileFullscreen) != null ? _j2 : true;
16698
- const mobileBreakpoint = (_l2 = (_k2 = config.launcher) == null ? void 0 : _k2.mobileBreakpoint) != null ? _l2 : 640;
17152
+ const ownerWindow2 = (_m2 = mount.ownerDocument.defaultView) != null ? _m2 : window;
17153
+ const mobileFullscreen = (_o2 = (_n2 = config.launcher) == null ? void 0 : _n2.mobileFullscreen) != null ? _o2 : true;
17154
+ const mobileBreakpoint = (_q2 = (_p2 = config.launcher) == null ? void 0 : _p2.mobileBreakpoint) != null ? _q2 : 640;
16699
17155
  const isMobileViewport = ownerWindow2.innerWidth <= mobileBreakpoint;
16700
17156
  const shouldGoFullscreen = mobileFullscreen && isMobileViewport && launcherEnabled;
16701
- const position = (_n2 = (_m2 = config.launcher) == null ? void 0 : _m2.position) != null ? _n2 : "bottom-left";
17157
+ const position = (_s2 = (_r2 = config.launcher) == null ? void 0 : _r2.position) != null ? _s2 : "bottom-left";
16702
17158
  const isLeftSidebar = position === "bottom-left" || position === "top-left";
16703
- const overlayZIndex = (_p2 = (_o2 = config.launcher) == null ? void 0 : _o2.zIndex) != null ? _p2 : DEFAULT_OVERLAY_Z_INDEX;
17159
+ const overlayZIndex = (_u2 = (_t2 = config.launcher) == null ? void 0 : _t2.zIndex) != null ? _u2 : DEFAULT_OVERLAY_Z_INDEX;
16704
17160
  let defaultPanelBorder = sidebarMode || shouldGoFullscreen ? "none" : "1px solid var(--persona-border)";
16705
17161
  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))";
16706
17162
  if (dockedMode && !shouldGoFullscreen) {
@@ -16787,7 +17243,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16787
17243
  restoreBodyScrollTop();
16788
17244
  return;
16789
17245
  }
16790
- const launcherWidth = (_r2 = (_q2 = config == null ? void 0 : config.launcher) == null ? void 0 : _q2.width) != null ? _r2 : config == null ? void 0 : config.launcherWidth;
17246
+ const launcherWidth = (_w2 = (_v2 = config == null ? void 0 : config.launcher) == null ? void 0 : _v2.width) != null ? _w2 : config == null ? void 0 : config.launcherWidth;
16791
17247
  const width = launcherWidth != null ? launcherWidth : DEFAULT_FLOATING_LAUNCHER_WIDTH;
16792
17248
  if (!sidebarMode && !dockedMode) {
16793
17249
  if (isInlineEmbed && fullHeight) {
@@ -16868,11 +17324,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16868
17324
  "persona-top-4"
16869
17325
  );
16870
17326
  if (!sidebarMode && !isInlineEmbed && !dockedMode) {
16871
- const positionClasses = (_s2 = positionMap[position]) != null ? _s2 : positionMap["bottom-right"];
17327
+ const positionClasses = (_x2 = positionMap[position]) != null ? _x2 : positionMap["bottom-right"];
16872
17328
  positionClasses.split(" ").forEach((cls) => wrapper.classList.add(cls));
16873
17329
  }
16874
17330
  if (sidebarMode) {
16875
- const sidebarWidth = (_u2 = (_t2 = config.launcher) == null ? void 0 : _t2.sidebarWidth) != null ? _u2 : "420px";
17331
+ const sidebarWidth = (_z2 = (_y2 = config.launcher) == null ? void 0 : _y2.sidebarWidth) != null ? _z2 : "420px";
16876
17332
  wrapper.style.cssText = `
16877
17333
  position: fixed !important;
16878
17334
  top: 0 !important;
@@ -16924,7 +17380,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16924
17380
  if (!isInlineEmbed && !dockedMode) {
16925
17381
  const maxHeightStyles = "max-height: -moz-available !important; max-height: stretch !important;";
16926
17382
  const paddingStyles = sidebarMode ? "" : "padding-top: 1.25em !important;";
16927
- const zIndexStyles = !sidebarMode ? `z-index: ${(_w2 = (_v2 = config.launcher) == null ? void 0 : _v2.zIndex) != null ? _w2 : DEFAULT_OVERLAY_Z_INDEX} !important;` : "";
17383
+ const zIndexStyles = !sidebarMode ? `z-index: ${(_B2 = (_A2 = config.launcher) == null ? void 0 : _A2.zIndex) != null ? _B2 : DEFAULT_OVERLAY_Z_INDEX} !important;` : "";
16928
17384
  wrapper.style.cssText += maxHeightStyles + paddingStyles + zIndexStyles;
16929
17385
  }
16930
17386
  restoreBodyScrollTop();
@@ -16994,7 +17450,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16994
17450
  cleanupThemeObserver = null;
16995
17451
  }
16996
17452
  });
16997
- const streamAnimationConfig = (_F = config.features) == null ? void 0 : _F.streamAnimation;
17453
+ const streamAnimationConfig = (_J = config.features) == null ? void 0 : _J.streamAnimation;
16998
17454
  if ((streamAnimationConfig == null ? void 0 : streamAnimationConfig.type) && streamAnimationConfig.type !== "none") {
16999
17455
  const plugin = resolveStreamAnimationPlugin(
17000
17456
  streamAnimationConfig.type,
@@ -17011,6 +17467,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17011
17467
  let isStreaming = false;
17012
17468
  const messageCache = createMessageCache();
17013
17469
  const lastAskBubbleFingerprint = /* @__PURE__ */ new Map();
17470
+ const lastComponentDirectiveFingerprint = /* @__PURE__ */ new Map();
17014
17471
  let configVersion = 0;
17015
17472
  const autoFollow = createFollowStateController();
17016
17473
  let lastScrollTop = 0;
@@ -17027,7 +17484,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17027
17484
  lastUserMessageWasVoice: false,
17028
17485
  lastUserMessageId: null
17029
17486
  };
17030
- const voiceAutoResumeMode = (_H = (_G = config.voiceRecognition) == null ? void 0 : _G.autoResume) != null ? _H : false;
17487
+ const voiceAutoResumeMode = (_L = (_K = config.voiceRecognition) == null ? void 0 : _K.autoResume) != null ? _L : false;
17031
17488
  const emitVoiceState = (source) => {
17032
17489
  eventBus.emit("voice:state", {
17033
17490
  active: voiceState.active,
@@ -17258,13 +17715,21 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17258
17715
  const liveAskToolIds = /* @__PURE__ */ new Set();
17259
17716
  const hasAskPlugin = plugins.some((p) => p.renderAskUserQuestion);
17260
17717
  const askPluginHydrate = [];
17718
+ const componentDirectiveHydrate = [];
17719
+ const componentStreamingEnabled = config.enableComponentStreaming !== false;
17261
17720
  messages.forEach((message) => {
17262
17721
  var _a3, _b3, _c3, _d3, _e3, _f3, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
17263
17722
  activeMessageIds.add(message.id);
17264
17723
  const askWithPlugin = hasAskPlugin && isAskUserQuestionMessage(message);
17724
+ const hasDirectiveBubble = !askWithPlugin && message.role === "assistant" && !message.variant && componentStreamingEnabled && hasComponentDirective(message);
17725
+ if (!hasDirectiveBubble && lastComponentDirectiveFingerprint.has(message.id)) {
17726
+ const existing = container2.querySelector(`#wrapper-${message.id}`);
17727
+ existing == null ? void 0 : existing.removeAttribute("data-preserve-runtime");
17728
+ lastComponentDirectiveFingerprint.delete(message.id);
17729
+ }
17265
17730
  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}` : "";
17266
17731
  const fingerprint = computeMessageFingerprint(message, configVersion) + askMeta;
17267
- const cachedWrapper = askWithPlugin ? null : getCachedWrapper(messageCache, message.id, fingerprint);
17732
+ const cachedWrapper = askWithPlugin || hasDirectiveBubble ? null : getCachedWrapper(messageCache, message.id, fingerprint);
17268
17733
  if (cachedWrapper) {
17269
17734
  tempContainer.appendChild(cachedWrapper.cloneNode(true));
17270
17735
  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)) {
@@ -17403,18 +17868,20 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17403
17868
  });
17404
17869
  }
17405
17870
  }
17406
- if (!bubble && message.role === "assistant" && !message.variant) {
17407
- const enableComponentStreaming = config.enableComponentStreaming !== false;
17408
- if (enableComponentStreaming && hasComponentDirective(message)) {
17409
- const directive = extractComponentDirectiveFromMessage(message);
17410
- if (directive) {
17871
+ if (!bubble && hasDirectiveBubble) {
17872
+ const directive = extractComponentDirectiveFromMessage(message);
17873
+ if (directive) {
17874
+ const lastFp = lastComponentDirectiveFingerprint.get(message.id);
17875
+ const needsRebuild = lastFp !== fingerprint;
17876
+ const wrapChrome = config.wrapComponentDirectiveInBubble !== false;
17877
+ let liveBubble = null;
17878
+ if (needsRebuild) {
17411
17879
  const componentBubble = renderComponentDirective(directive, {
17412
17880
  config,
17413
17881
  message,
17414
17882
  transform
17415
17883
  });
17416
17884
  if (componentBubble) {
17417
- const wrapChrome = config.wrapComponentDirectiveInBubble !== false;
17418
17885
  if (wrapChrome) {
17419
17886
  const componentWrapper = document.createElement("div");
17420
17887
  componentWrapper.className = [
@@ -17440,7 +17907,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17440
17907
  componentWrapper.appendChild(textDiv);
17441
17908
  }
17442
17909
  componentWrapper.appendChild(componentBubble);
17443
- bubble = componentWrapper;
17910
+ liveBubble = componentWrapper;
17444
17911
  } else {
17445
17912
  const stack = document.createElement("div");
17446
17913
  stack.className = "persona-flex persona-flex-col persona-w-full persona-max-w-full persona-gap-3 persona-items-stretch";
@@ -17459,10 +17926,28 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17459
17926
  stack.appendChild(textDiv);
17460
17927
  }
17461
17928
  stack.appendChild(componentBubble);
17462
- bubble = stack;
17929
+ liveBubble = stack;
17463
17930
  }
17464
17931
  }
17465
17932
  }
17933
+ if (liveBubble || lastFp != null) {
17934
+ const stub = document.createElement("div");
17935
+ stub.className = "persona-flex";
17936
+ stub.id = `wrapper-${message.id}`;
17937
+ stub.setAttribute("data-wrapper-id", message.id);
17938
+ stub.setAttribute("data-component-directive-stub", "true");
17939
+ stub.setAttribute("data-preserve-runtime", "true");
17940
+ if (!wrapChrome) {
17941
+ stub.classList.add("persona-w-full");
17942
+ }
17943
+ tempContainer.appendChild(stub);
17944
+ componentDirectiveHydrate.push({
17945
+ messageId: message.id,
17946
+ fingerprint,
17947
+ bubble: liveBubble
17948
+ });
17949
+ return;
17950
+ }
17466
17951
  }
17467
17952
  }
17468
17953
  if (!bubble) {
@@ -17713,15 +18198,327 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17713
18198
  if (!activeMessageIds.has(id)) lastAskBubbleFingerprint.delete(id);
17714
18199
  }
17715
18200
  }
18201
+ if (componentDirectiveHydrate.length > 0) {
18202
+ for (const { messageId, fingerprint, bubble } of componentDirectiveHydrate) {
18203
+ const wrapper2 = container2.querySelector(`#wrapper-${messageId}`);
18204
+ if (!wrapper2) continue;
18205
+ if (bubble === null) {
18206
+ continue;
18207
+ }
18208
+ wrapper2.replaceChildren(bubble);
18209
+ wrapper2.setAttribute("data-bubble-fp", fingerprint);
18210
+ lastComponentDirectiveFingerprint.set(messageId, fingerprint);
18211
+ }
18212
+ }
18213
+ if (lastComponentDirectiveFingerprint.size > 0) {
18214
+ for (const id of lastComponentDirectiveFingerprint.keys()) {
18215
+ if (!activeMessageIds.has(id)) lastComponentDirectiveFingerprint.delete(id);
18216
+ }
18217
+ }
17716
18218
  };
17717
18219
  const renderMessagesWithPlugins = renderMessagesWithPluginsImpl;
18220
+ let composerBarOutsideClickListener = null;
18221
+ const attachComposerBarOutsideClickDismiss = () => {
18222
+ var _a2;
18223
+ if (composerBarOutsideClickListener) return;
18224
+ const listener = (event) => {
18225
+ const path = event.composedPath();
18226
+ if (path.includes(wrapper)) return;
18227
+ if (pillRoot && path.includes(pillRoot)) return;
18228
+ setOpenState(false, "user");
18229
+ };
18230
+ composerBarOutsideClickListener = listener;
18231
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18232
+ targetDoc.addEventListener("pointerdown", listener, true);
18233
+ };
18234
+ const detachComposerBarOutsideClickDismiss = () => {
18235
+ var _a2;
18236
+ if (!composerBarOutsideClickListener) return;
18237
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18238
+ targetDoc.removeEventListener(
18239
+ "pointerdown",
18240
+ composerBarOutsideClickListener,
18241
+ true
18242
+ );
18243
+ composerBarOutsideClickListener = null;
18244
+ };
18245
+ destroyCallbacks.push(() => detachComposerBarOutsideClickDismiss());
18246
+ let composerBarEscapeListener = null;
18247
+ const attachComposerBarEscapeDismiss = () => {
18248
+ var _a2;
18249
+ if (composerBarEscapeListener) return;
18250
+ const listener = (event) => {
18251
+ if (event.key !== "Escape") return;
18252
+ if (event.isComposing) return;
18253
+ setOpenState(false, "user");
18254
+ };
18255
+ composerBarEscapeListener = listener;
18256
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18257
+ targetDoc.addEventListener("keydown", listener, true);
18258
+ };
18259
+ const detachComposerBarEscapeDismiss = () => {
18260
+ var _a2;
18261
+ if (!composerBarEscapeListener) return;
18262
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18263
+ targetDoc.removeEventListener(
18264
+ "keydown",
18265
+ composerBarEscapeListener,
18266
+ true
18267
+ );
18268
+ composerBarEscapeListener = null;
18269
+ };
18270
+ destroyCallbacks.push(() => detachComposerBarEscapeDismiss());
18271
+ let composerHovered = false;
18272
+ const peekActivatedPlugins = /* @__PURE__ */ new Set();
18273
+ const resolvePeekStreamAnimationFeature = () => {
18274
+ var _a2, _b2, _c2, _d2;
18275
+ const peekFeature = (_c2 = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) == null ? void 0 : _b2.peek) == null ? void 0 : _c2.streamAnimation;
18276
+ if (peekFeature) return peekFeature;
18277
+ return (_d2 = config.features) == null ? void 0 : _d2.streamAnimation;
18278
+ };
18279
+ const syncComposerBarPeek = () => {
18280
+ var _a2, _b2, _c2, _d2;
18281
+ if (!isComposerBar()) return;
18282
+ const peekBanner = panelElements.peekBanner;
18283
+ const peekTextNode = panelElements.peekTextNode;
18284
+ if (!peekBanner || !peekTextNode) return;
18285
+ if (open) {
18286
+ peekBanner.classList.remove("persona-pill-peek--visible");
18287
+ return;
18288
+ }
18289
+ const messages = (_a2 = session == null ? void 0 : session.getMessages()) != null ? _a2 : [];
18290
+ let lastAssistant;
18291
+ for (let i = messages.length - 1; i >= 0; i--) {
18292
+ const m = messages[i];
18293
+ if (m.role === "assistant" && m.content) {
18294
+ lastAssistant = m;
18295
+ break;
18296
+ }
18297
+ }
18298
+ if (!lastAssistant) {
18299
+ peekBanner.classList.remove("persona-pill-peek--visible");
18300
+ return;
18301
+ }
18302
+ const text = lastAssistant.content;
18303
+ const streaming = Boolean(lastAssistant.streaming);
18304
+ const feature = resolvePeekStreamAnimationFeature();
18305
+ const streamAnimation = resolveStreamAnimation(feature);
18306
+ const plugin = streamAnimation.type !== "none" ? resolveStreamAnimationPlugin(streamAnimation.type, feature == null ? void 0 : feature.plugins) : null;
18307
+ const pluginStillAnimating = ((_b2 = plugin == null ? void 0 : plugin.isAnimating) == null ? void 0 : _b2.call(plugin, lastAssistant)) === true;
18308
+ const animationActive = plugin !== null && (streaming || pluginStillAnimating);
18309
+ if (animationActive && plugin && !peekActivatedPlugins.has(plugin.name)) {
18310
+ ensurePluginActive(plugin, mount);
18311
+ peekActivatedPlugins.add(plugin.name);
18312
+ }
18313
+ const desiredContainerClass = animationActive && (plugin == null ? void 0 : plugin.containerClass) ? plugin.containerClass : null;
18314
+ const currentContainerClass = (_c2 = peekTextNode.dataset.personaPeekStreamClass) != null ? _c2 : null;
18315
+ if (currentContainerClass && currentContainerClass !== desiredContainerClass) {
18316
+ peekTextNode.classList.remove(currentContainerClass);
18317
+ delete peekTextNode.dataset.personaPeekStreamClass;
18318
+ }
18319
+ if (desiredContainerClass && currentContainerClass !== desiredContainerClass) {
18320
+ peekTextNode.classList.add(desiredContainerClass);
18321
+ peekTextNode.dataset.personaPeekStreamClass = desiredContainerClass;
18322
+ }
18323
+ if (animationActive) {
18324
+ peekTextNode.style.setProperty(
18325
+ "--persona-stream-step",
18326
+ `${streamAnimation.speed}ms`
18327
+ );
18328
+ peekTextNode.style.setProperty(
18329
+ "--persona-stream-duration",
18330
+ `${streamAnimation.duration}ms`
18331
+ );
18332
+ } else {
18333
+ peekTextNode.style.removeProperty("--persona-stream-step");
18334
+ peekTextNode.style.removeProperty("--persona-stream-duration");
18335
+ }
18336
+ const buffered = animationActive ? applyStreamBuffer(text, streamAnimation.buffer, plugin, lastAssistant, streaming) : text;
18337
+ const skeletonEnabled = animationActive && streamAnimation.placeholder === "skeleton";
18338
+ const showSkeletonOnly = skeletonEnabled && streaming && (!buffered || !buffered.trim());
18339
+ if (showSkeletonOnly) {
18340
+ const tempContainer = document.createElement("div");
18341
+ const skeleton = createSkeletonPlaceholder();
18342
+ skeleton.classList.add("persona-pill-peek__skeleton");
18343
+ tempContainer.appendChild(skeleton);
18344
+ morphMessages(peekTextNode, tempContainer);
18345
+ } else {
18346
+ const sliceStart = Math.max(0, buffered.length - 100);
18347
+ const slice = buffered.length > 100 ? buffered.slice(-100) : buffered;
18348
+ const escaped = escapeHtml(slice);
18349
+ if (!animationActive || !plugin) {
18350
+ const preview = buffered.length > 100 ? `\u2026${slice}` : slice;
18351
+ if (peekTextNode.textContent !== preview) {
18352
+ peekTextNode.textContent = preview;
18353
+ }
18354
+ } else {
18355
+ let html = escaped;
18356
+ if (plugin.wrap === "char" || plugin.wrap === "word") {
18357
+ html = wrapStreamAnimation(
18358
+ escaped,
18359
+ plugin.wrap,
18360
+ // Namespace span IDs to the peek surface so they don't collide
18361
+ // with the main bubble's spans for the same message id.
18362
+ `peek-${lastAssistant.id}`,
18363
+ { skipTags: plugin.skipTags, startIndex: sliceStart }
18364
+ );
18365
+ }
18366
+ const tempContainer = document.createElement("div");
18367
+ tempContainer.innerHTML = html;
18368
+ if (plugin.useCaret && slice.length > 0) {
18369
+ const caret = createStreamCaret();
18370
+ const spans = tempContainer.querySelectorAll(
18371
+ ".persona-stream-char, .persona-stream-word"
18372
+ );
18373
+ const lastSpan = spans[spans.length - 1];
18374
+ if (lastSpan == null ? void 0 : lastSpan.parentNode) {
18375
+ lastSpan.parentNode.insertBefore(caret, lastSpan.nextSibling);
18376
+ } else {
18377
+ tempContainer.appendChild(caret);
18378
+ }
18379
+ }
18380
+ morphMessages(peekTextNode, tempContainer);
18381
+ (_d2 = plugin.onAfterRender) == null ? void 0 : _d2.call(plugin, {
18382
+ container: peekTextNode,
18383
+ bubble: peekBanner,
18384
+ messageId: lastAssistant.id,
18385
+ message: lastAssistant,
18386
+ speed: streamAnimation.speed,
18387
+ duration: streamAnimation.duration
18388
+ });
18389
+ }
18390
+ }
18391
+ const shouldShow = isStreaming || composerHovered;
18392
+ peekBanner.classList.toggle("persona-pill-peek--visible", shouldShow);
18393
+ };
18394
+ if (isComposerBar()) {
18395
+ const peekBanner = panelElements.peekBanner;
18396
+ if (peekBanner) {
18397
+ const onPeekPointerDown = (e) => {
18398
+ e.preventDefault();
18399
+ e.stopPropagation();
18400
+ setOpenState(true, "user");
18401
+ };
18402
+ peekBanner.addEventListener("pointerdown", onPeekPointerDown);
18403
+ destroyCallbacks.push(() => {
18404
+ peekBanner.removeEventListener("pointerdown", onPeekPointerDown);
18405
+ });
18406
+ }
18407
+ const onPanelPointerEnter = () => {
18408
+ if (composerHovered) return;
18409
+ composerHovered = true;
18410
+ syncComposerBarPeek();
18411
+ };
18412
+ const onPanelPointerLeave = () => {
18413
+ if (!composerHovered) return;
18414
+ composerHovered = false;
18415
+ syncComposerBarPeek();
18416
+ };
18417
+ panel.addEventListener("pointerenter", onPanelPointerEnter);
18418
+ panel.addEventListener("pointerleave", onPanelPointerLeave);
18419
+ destroyCallbacks.push(() => {
18420
+ panel.removeEventListener("pointerenter", onPanelPointerEnter);
18421
+ panel.removeEventListener("pointerleave", onPanelPointerLeave);
18422
+ });
18423
+ if (pillRoot) {
18424
+ pillRoot.addEventListener("pointerenter", onPanelPointerEnter);
18425
+ pillRoot.addEventListener("pointerleave", onPanelPointerLeave);
18426
+ destroyCallbacks.push(() => {
18427
+ pillRoot.removeEventListener("pointerenter", onPanelPointerEnter);
18428
+ pillRoot.removeEventListener("pointerleave", onPanelPointerLeave);
18429
+ });
18430
+ }
18431
+ }
18432
+ const applyComposerBarGeometry = (isOpen) => {
18433
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18434
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
18435
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
18436
+ const bottomOffset = (_d2 = cb.bottomOffset) != null ? _d2 : "16px";
18437
+ const collapsedMaxWidth = cb.collapsedMaxWidth;
18438
+ const expandedMaxWidth = (_e2 = cb.expandedMaxWidth) != null ? _e2 : "880px";
18439
+ const expandedTopOffset = (_f2 = cb.expandedTopOffset) != null ? _f2 : "5vh";
18440
+ const modalMaxWidth = (_g2 = cb.modalMaxWidth) != null ? _g2 : "880px";
18441
+ const modalMaxHeight = (_h2 = cb.modalMaxHeight) != null ? _h2 : "min(90vh, 800px)";
18442
+ const viewportClamp = "calc(100vw - 32px)";
18443
+ const pillAreaClearance = "var(--persona-pill-area-height, 80px)";
18444
+ const s = wrapper.style;
18445
+ s.left = "";
18446
+ s.right = "";
18447
+ s.top = "";
18448
+ s.bottom = "";
18449
+ s.transform = "";
18450
+ s.width = "";
18451
+ s.maxWidth = "";
18452
+ s.height = "";
18453
+ s.maxHeight = "";
18454
+ if (pillRoot) {
18455
+ const ps = pillRoot.style;
18456
+ ps.bottom = bottomOffset;
18457
+ ps.width = collapsedMaxWidth != null ? collapsedMaxWidth : "";
18458
+ }
18459
+ if (!isOpen) {
18460
+ return;
18461
+ }
18462
+ if (expandedSize === "fullscreen") {
18463
+ return;
18464
+ }
18465
+ if (expandedSize === "modal") {
18466
+ s.top = "50%";
18467
+ s.left = "50%";
18468
+ s.transform = "translate(-50%, -50%)";
18469
+ s.bottom = "auto";
18470
+ s.right = "auto";
18471
+ s.width = modalMaxWidth;
18472
+ s.maxWidth = viewportClamp;
18473
+ s.maxHeight = modalMaxHeight;
18474
+ s.height = modalMaxHeight;
18475
+ return;
18476
+ }
18477
+ s.left = "50%";
18478
+ s.transform = "translateX(-50%)";
18479
+ s.bottom = `calc(${bottomOffset} + ${pillAreaClearance})`;
18480
+ s.top = expandedTopOffset;
18481
+ s.width = expandedMaxWidth;
18482
+ s.maxWidth = viewportClamp;
18483
+ };
17718
18484
  const updateOpenState = () => {
17719
- var _a2, _b2, _c2, _d2, _e2;
17720
- if (!launcherEnabled) return;
18485
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18486
+ if (!isPanelToggleable()) return;
18487
+ if (isComposerBar()) {
18488
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
18489
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
18490
+ const nextState = open ? "expanded" : "collapsed";
18491
+ wrapper.dataset.state = nextState;
18492
+ wrapper.dataset.expandedSize = expandedSize;
18493
+ if (pillRoot) {
18494
+ pillRoot.dataset.state = nextState;
18495
+ pillRoot.dataset.expandedSize = expandedSize;
18496
+ }
18497
+ wrapper.style.removeProperty("display");
18498
+ wrapper.classList.remove("persona-pointer-events-none", "persona-opacity-0");
18499
+ panel.classList.remove(
18500
+ "persona-scale-95",
18501
+ "persona-opacity-0",
18502
+ "persona-scale-100",
18503
+ "persona-opacity-100"
18504
+ );
18505
+ applyComposerBarGeometry(open);
18506
+ container.style.display = open ? "flex" : "none";
18507
+ applyFullHeightStyles();
18508
+ if (open) {
18509
+ attachComposerBarOutsideClickDismiss();
18510
+ attachComposerBarEscapeDismiss();
18511
+ } else {
18512
+ detachComposerBarOutsideClickDismiss();
18513
+ detachComposerBarEscapeDismiss();
18514
+ }
18515
+ syncComposerBarPeek();
18516
+ return;
18517
+ }
17721
18518
  const dockedMode = isDockedMountMode(config);
17722
- const ownerWindow2 = (_a2 = mount.ownerDocument.defaultView) != null ? _a2 : window;
17723
- const mobileBreakpoint = (_c2 = (_b2 = config.launcher) == null ? void 0 : _b2.mobileBreakpoint) != null ? _c2 : 640;
17724
- const mobileFullscreen = (_e2 = (_d2 = config.launcher) == null ? void 0 : _d2.mobileFullscreen) != null ? _e2 : true;
18519
+ const ownerWindow2 = (_d2 = mount.ownerDocument.defaultView) != null ? _d2 : window;
18520
+ const mobileBreakpoint = (_f2 = (_e2 = config.launcher) == null ? void 0 : _e2.mobileBreakpoint) != null ? _f2 : 640;
18521
+ const mobileFullscreen = (_h2 = (_g2 = config.launcher) == null ? void 0 : _g2.mobileFullscreen) != null ? _h2 : true;
17725
18522
  const isMobileViewport = ownerWindow2.innerWidth <= mobileBreakpoint;
17726
18523
  const shouldGoFullscreen = mobileFullscreen && isMobileViewport && launcherEnabled;
17727
18524
  const dockReveal = resolveDockConfig(config).reveal;
@@ -17764,20 +18561,21 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17764
18561
  };
17765
18562
  const setOpenState = (nextOpen, source = "user") => {
17766
18563
  var _a2, _b2;
17767
- if (!launcherEnabled) return;
18564
+ if (!isPanelToggleable()) return;
17768
18565
  if (open === nextOpen) return;
17769
18566
  const prevOpen = open;
17770
18567
  open = nextOpen;
17771
18568
  updateOpenState();
17772
18569
  const isViewportCovering = (() => {
17773
- var _a3, _b3, _c2, _d2, _e2, _f2, _g2;
18570
+ var _a3, _b3, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2;
17774
18571
  const sm = (_b3 = (_a3 = config.launcher) == null ? void 0 : _a3.sidebarMode) != null ? _b3 : false;
17775
18572
  const ow = (_c2 = mount.ownerDocument.defaultView) != null ? _c2 : window;
17776
18573
  const mf = (_e2 = (_d2 = config.launcher) == null ? void 0 : _d2.mobileFullscreen) != null ? _e2 : true;
17777
18574
  const mb = (_g2 = (_f2 = config.launcher) == null ? void 0 : _f2.mobileBreakpoint) != null ? _g2 : 640;
17778
18575
  const isMobile = ow.innerWidth <= mb;
17779
18576
  const dockedMF = isDockedMountMode(config) && mf && isMobile;
17780
- return sm || mf && isMobile && launcherEnabled || dockedMF;
18577
+ const composerBarFS = isComposerBar() && ((_j2 = (_i2 = (_h2 = config.launcher) == null ? void 0 : _h2.composerBar) == null ? void 0 : _i2.expandedSize) != null ? _j2 : "fullscreen") === "fullscreen";
18578
+ return sm || mf && isMobile && launcherEnabled || dockedMF || composerBarFS;
17781
18579
  })();
17782
18580
  if (open && isViewportCovering) {
17783
18581
  if (!teardownHostStacking) {
@@ -17922,6 +18720,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17922
18720
  }
17923
18721
  voiceState.lastUserMessageWasVoice = Boolean(lastUserMessage == null ? void 0 : lastUserMessage.viaVoice);
17924
18722
  persistState(messages);
18723
+ syncComposerBarPeek();
17925
18724
  },
17926
18725
  onStatusChanged(status) {
17927
18726
  var _a2;
@@ -17945,6 +18744,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17945
18744
  if (!streaming) {
17946
18745
  scheduleAutoScroll(true);
17947
18746
  }
18747
+ syncComposerBarPeek();
17948
18748
  },
17949
18749
  onVoiceStatusChanged(status) {
17950
18750
  var _a2, _b2;
@@ -17981,7 +18781,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17981
18781
  }
17982
18782
  });
17983
18783
  sessionRef.current = session;
17984
- if (((_J = (_I = config.voiceRecognition) == null ? void 0 : _I.provider) == null ? void 0 : _J.type) === "runtype") {
18784
+ if (((_N = (_M = config.voiceRecognition) == null ? void 0 : _M.provider) == null ? void 0 : _N.type) === "runtype") {
17985
18785
  try {
17986
18786
  session.setupVoice();
17987
18787
  } catch (err) {
@@ -18032,6 +18832,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18032
18832
  }
18033
18833
  });
18034
18834
  }
18835
+ const maybeExpandComposerBar = () => {
18836
+ var _a2, _b2, _c2;
18837
+ if (!isComposerBar()) return;
18838
+ if (open) return;
18839
+ const expandOnSubmit = (_c2 = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) == null ? void 0 : _b2.expandOnSubmit) != null ? _c2 : true;
18840
+ if (!expandOnSubmit) return;
18841
+ setOpenState(true, "auto");
18842
+ };
18035
18843
  const handleSubmit = (event) => {
18036
18844
  var _a2;
18037
18845
  event.preventDefault();
@@ -18042,6 +18850,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18042
18850
  const value = textarea.value.trim();
18043
18851
  const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
18044
18852
  if (!value && !hasAttachments) return;
18853
+ maybeExpandComposerBar();
18045
18854
  let contentParts;
18046
18855
  if (hasAttachments) {
18047
18856
  contentParts = [];
@@ -18207,7 +19016,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18207
19016
  micButton.setAttribute("aria-label", "Start voice recognition");
18208
19017
  }
18209
19018
  };
18210
- const createMicButton = (voiceConfig, sendButtonConfig) => {
19019
+ const createMicButton2 = (voiceConfig, sendButtonConfig) => {
18211
19020
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18212
19021
  const hasSpeechRecognition = typeof window !== "undefined" && (typeof window.webkitSpeechRecognition !== "undefined" || typeof window.SpeechRecognition !== "undefined");
18213
19022
  const hasRuntypeProvider = ((_a2 = voiceConfig == null ? void 0 : voiceConfig.provider) == null ? void 0 : _a2.type) === "runtype";
@@ -18484,7 +19293,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18484
19293
  };
18485
19294
  let launcherButtonInstance = null;
18486
19295
  let customLauncherElement = null;
18487
- if (launcherEnabled) {
19296
+ if (launcherEnabled && !isComposerBar()) {
18488
19297
  const launcherPlugin = plugins.find((p) => p.renderLauncher);
18489
19298
  if (launcherPlugin == null ? void 0 : launcherPlugin.renderLauncher) {
18490
19299
  const customLauncher = launcherPlugin.renderLauncher({
@@ -18515,7 +19324,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18515
19324
  scheduleAutoScroll(true);
18516
19325
  maybeRestoreVoiceFromMetadata();
18517
19326
  if (autoFocusInput) {
18518
- if (!launcherEnabled) {
19327
+ if (!launcherEnabled || isComposerBar()) {
18519
19328
  setTimeout(() => maybeFocusInput(), 0);
18520
19329
  } else if (open) {
18521
19330
  setTimeout(() => maybeFocusInput(), 200);
@@ -18523,6 +19332,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18523
19332
  }
18524
19333
  const recalcPanelHeight = () => {
18525
19334
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2;
19335
+ if (isComposerBar()) {
19336
+ updateScrollToBottomButtonOffset();
19337
+ updateOpenState();
19338
+ return;
19339
+ }
18526
19340
  const dockedMode = isDockedMountMode(config);
18527
19341
  const sidebarMode = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.sidebarMode) != null ? _b2 : false;
18528
19342
  const fullHeight = dockedMode || sidebarMode || ((_d2 = (_c2 = config.launcher) == null ? void 0 : _c2.fullHeight) != null ? _d2 : false);
@@ -18593,7 +19407,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18593
19407
  }
18594
19408
  };
18595
19409
  recalcPanelHeight();
18596
- const ownerWindow = (_K = mount.ownerDocument.defaultView) != null ? _K : window;
19410
+ const ownerWindow = (_O = mount.ownerDocument.defaultView) != null ? _O : window;
18597
19411
  ownerWindow.addEventListener("resize", recalcPanelHeight);
18598
19412
  destroyCallbacks.push(() => ownerWindow.removeEventListener("resize", recalcPanelHeight));
18599
19413
  if (typeof ResizeObserver !== "undefined") {
@@ -18663,7 +19477,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18663
19477
  closeButton.removeEventListener("click", closeHandler);
18664
19478
  closeHandler = null;
18665
19479
  }
18666
- if (launcherEnabled) {
19480
+ if (isPanelToggleable()) {
18667
19481
  closeButton.style.display = "";
18668
19482
  closeHandler = () => {
18669
19483
  setOpenState(false, "user");
@@ -18817,7 +19631,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18817
19631
  }
18818
19632
  const controller = {
18819
19633
  update(nextConfig) {
18820
- 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;
19634
+ 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;
18821
19635
  const previousToolCallConfig = config.toolCall;
18822
19636
  const previousMessageActions = config.messageActions;
18823
19637
  const previousLayoutMessages = (_a2 = config.layout) == null ? void 0 : _a2.messages;
@@ -18947,11 +19761,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18947
19761
  const headerLayoutChanged = (headerLayoutConfig == null ? void 0 : headerLayoutConfig.layout) !== prevHeaderLayout;
18948
19762
  if (headerLayoutChanged && header) {
18949
19763
  const newHeaderElements = headerLayoutConfig ? buildHeaderWithLayout(config, headerLayoutConfig, {
18950
- showClose: launcherEnabled,
19764
+ showClose: isPanelToggleable(),
18951
19765
  onClose: () => setOpenState(false, "user")
18952
19766
  }) : buildHeader({
18953
19767
  config,
18954
- showClose: launcherEnabled,
19768
+ showClose: isPanelToggleable(),
18955
19769
  onClose: () => setOpenState(false, "user")
18956
19770
  });
18957
19771
  header.replaceWith(newHeaderElements.header);
@@ -19081,7 +19895,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19081
19895
  if (existingSvg || existingImg) {
19082
19896
  iconHolder.replaceChildren();
19083
19897
  }
19084
- iconHolder.textContent = (_R = launcher.agentIconText) != null ? _R : "\u{1F4AC}";
19898
+ iconHolder.textContent = (_R2 = launcher.agentIconText) != null ? _R2 : "\u{1F4AC}";
19085
19899
  }
19086
19900
  const img = iconHolder.querySelector("img");
19087
19901
  if (img) {
@@ -19090,8 +19904,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19090
19904
  }
19091
19905
  }
19092
19906
  }
19093
- const layoutShowTitle = (_T = (_S = config.layout) == null ? void 0 : _S.header) == null ? void 0 : _T.showTitle;
19094
- const layoutShowSubtitle = (_V = (_U = config.layout) == null ? void 0 : _U.header) == null ? void 0 : _V.showSubtitle;
19907
+ const layoutShowTitle = (_T2 = (_S2 = config.layout) == null ? void 0 : _S2.header) == null ? void 0 : _T2.showTitle;
19908
+ const layoutShowSubtitle = (_V = (_U2 = config.layout) == null ? void 0 : _U2.header) == null ? void 0 : _V.showSubtitle;
19095
19909
  if (headerTitle) {
19096
19910
  headerTitle.style.display = layoutShowTitle === false ? "none" : "";
19097
19911
  }
@@ -19241,7 +20055,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19241
20055
  if (clearChatButtonWrapper) {
19242
20056
  clearChatButtonWrapper.style.display = shouldShowClearChat ? "" : "none";
19243
20057
  const { closeButtonWrapper } = panelElements;
19244
- if (closeButtonWrapper && !closeButtonWrapper.classList.contains("persona-absolute")) {
20058
+ if (!isComposerBar() && closeButtonWrapper && !closeButtonWrapper.classList.contains("persona-absolute")) {
19245
20059
  if (shouldShowClearChat) {
19246
20060
  closeButtonWrapper.classList.remove("persona-ml-auto");
19247
20061
  } else {
@@ -19250,7 +20064,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19250
20064
  }
19251
20065
  const isTopRight = clearChatPlacement === "top-right";
19252
20066
  const currentlyTopRight = clearChatButtonWrapper.classList.contains("persona-absolute");
19253
- if (isTopRight !== currentlyTopRight && shouldShowClearChat) {
20067
+ if (!isComposerBar() && isTopRight !== currentlyTopRight && shouldShowClearChat) {
19254
20068
  clearChatButtonWrapper.remove();
19255
20069
  if (isTopRight) {
19256
20070
  clearChatButtonWrapper.className = "persona-absolute persona-top-4 persona-z-50";
@@ -19279,14 +20093,17 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19279
20093
  }
19280
20094
  }
19281
20095
  if (shouldShowClearChat) {
19282
- const clearChatSize = (_la = clearChatConfig.size) != null ? _la : "32px";
19283
- clearChatButton.style.height = clearChatSize;
19284
- clearChatButton.style.width = clearChatSize;
20096
+ if (!isComposerBar()) {
20097
+ const clearChatSize = (_la = clearChatConfig.size) != null ? _la : "32px";
20098
+ clearChatButton.style.height = clearChatSize;
20099
+ clearChatButton.style.width = clearChatSize;
20100
+ }
19285
20101
  const clearChatIconName = (_ma = clearChatConfig.iconName) != null ? _ma : "refresh-cw";
19286
20102
  const clearChatIconColor = (_na = clearChatConfig.iconColor) != null ? _na : "";
19287
20103
  clearChatButton.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
19288
20104
  clearChatButton.innerHTML = "";
19289
- const iconSvg = renderLucideIcon(clearChatIconName, "20px", "currentColor", 2);
20105
+ const clearChatIconSize = isComposerBar() ? "14px" : "20px";
20106
+ const iconSvg = renderLucideIcon(clearChatIconName, clearChatIconSize, "currentColor", 2);
19290
20107
  if (iconSvg) {
19291
20108
  clearChatButton.appendChild(iconSvg);
19292
20109
  }
@@ -19410,7 +20227,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19410
20227
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
19411
20228
  if (voiceRecognitionEnabled && hasVoiceInput) {
19412
20229
  if (!micButton || !micButtonWrapper) {
19413
- const micButtonResult = createMicButton(config.voiceRecognition, config.sendButton);
20230
+ const micButtonResult = createMicButton2(config.voiceRecognition, config.sendButton);
19414
20231
  if (micButtonResult) {
19415
20232
  micButton = micButtonResult.micButton;
19416
20233
  micButtonWrapper = micButtonResult.micButtonWrapper;
@@ -19707,7 +20524,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19707
20524
  } else if (tooltip) {
19708
20525
  tooltip.style.display = "none";
19709
20526
  }
19710
- const updatedContentMaxWidth = (__a = config.layout) == null ? void 0 : __a.contentMaxWidth;
20527
+ 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;
19711
20528
  if (updatedContentMaxWidth) {
19712
20529
  messagesWrapper.style.maxWidth = updatedContentMaxWidth;
19713
20530
  messagesWrapper.style.marginLeft = "auto";
@@ -19739,8 +20556,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19739
20556
  suggestions.style.marginRight = "";
19740
20557
  }
19741
20558
  }
19742
- const statusIndicatorConfig = (_$a = config.statusIndicator) != null ? _$a : {};
19743
- const isVisible = (_ab = statusIndicatorConfig.visible) != null ? _ab : true;
20559
+ const statusIndicatorConfig = (_db = config.statusIndicator) != null ? _db : {};
20560
+ const isVisible = (_eb = statusIndicatorConfig.visible) != null ? _eb : true;
19744
20561
  statusText.style.display = isVisible ? "" : "none";
19745
20562
  if (session) {
19746
20563
  const currentStatus = session.getStatus();
@@ -19759,15 +20576,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19759
20576
  statusText.classList.add(alignClass);
19760
20577
  },
19761
20578
  open() {
19762
- if (!launcherEnabled) return;
20579
+ if (!isPanelToggleable()) return;
19763
20580
  setOpenState(true, "api");
19764
20581
  },
19765
20582
  close() {
19766
- if (!launcherEnabled) return;
20583
+ if (!isPanelToggleable()) return;
19767
20584
  setOpenState(false, "api");
19768
20585
  },
19769
20586
  toggle() {
19770
- if (!launcherEnabled) return;
20587
+ if (!isPanelToggleable()) return;
19771
20588
  setOpenState(!open, "api");
19772
20589
  },
19773
20590
  clearChat() {
@@ -19821,7 +20638,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19821
20638
  setMessage(message) {
19822
20639
  if (!textarea) return false;
19823
20640
  if (session.isStreaming()) return false;
19824
- if (!open && launcherEnabled) {
20641
+ if (!open && isPanelToggleable()) {
19825
20642
  setOpenState(true, "system");
19826
20643
  }
19827
20644
  textarea.value = message;
@@ -19832,7 +20649,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19832
20649
  if (session.isStreaming()) return false;
19833
20650
  const valueToSubmit = (message == null ? void 0 : message.trim()) || textarea.value.trim();
19834
20651
  if (!valueToSubmit) return false;
19835
- if (!open && launcherEnabled) {
20652
+ if (!open && isPanelToggleable()) {
19836
20653
  setOpenState(true, "system");
19837
20654
  }
19838
20655
  textarea.value = "";
@@ -19845,7 +20662,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19845
20662
  if (session.isStreaming()) return false;
19846
20663
  if (((_b2 = (_a2 = config.voiceRecognition) == null ? void 0 : _a2.provider) == null ? void 0 : _b2.type) === "runtype") {
19847
20664
  if (session.isVoiceActive()) return true;
19848
- if (!open && launcherEnabled) setOpenState(true, "system");
20665
+ if (!open && isPanelToggleable()) setOpenState(true, "system");
19849
20666
  voiceState.manuallyDeactivated = false;
19850
20667
  persistVoiceMetadata();
19851
20668
  session.toggleVoice().then(() => {
@@ -19858,7 +20675,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19858
20675
  if (isRecording) return true;
19859
20676
  const SpeechRecognitionClass = getSpeechRecognitionClass();
19860
20677
  if (!SpeechRecognitionClass) return false;
19861
- if (!open && launcherEnabled) setOpenState(true, "system");
20678
+ if (!open && isPanelToggleable()) setOpenState(true, "system");
19862
20679
  voiceState.manuallyDeactivated = false;
19863
20680
  persistVoiceMetadata();
19864
20681
  startVoiceRecognition("user");
@@ -19884,13 +20701,13 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19884
20701
  return true;
19885
20702
  },
19886
20703
  injectMessage(options) {
19887
- if (!open && launcherEnabled) {
20704
+ if (!open && isPanelToggleable()) {
19888
20705
  setOpenState(true, "system");
19889
20706
  }
19890
20707
  return session.injectMessage(options);
19891
20708
  },
19892
20709
  injectAssistantMessage(options) {
19893
- if (!open && launcherEnabled) {
20710
+ if (!open && isPanelToggleable()) {
19894
20711
  setOpenState(true, "system");
19895
20712
  }
19896
20713
  const result = session.injectAssistantMessage(options);
@@ -19909,26 +20726,26 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19909
20726
  return result;
19910
20727
  },
19911
20728
  injectUserMessage(options) {
19912
- if (!open && launcherEnabled) {
20729
+ if (!open && isPanelToggleable()) {
19913
20730
  setOpenState(true, "system");
19914
20731
  }
19915
20732
  return session.injectUserMessage(options);
19916
20733
  },
19917
20734
  injectSystemMessage(options) {
19918
- if (!open && launcherEnabled) {
20735
+ if (!open && isPanelToggleable()) {
19919
20736
  setOpenState(true, "system");
19920
20737
  }
19921
20738
  return session.injectSystemMessage(options);
19922
20739
  },
19923
20740
  injectMessageBatch(optionsList) {
19924
- if (!open && launcherEnabled) {
20741
+ if (!open && isPanelToggleable()) {
19925
20742
  setOpenState(true, "system");
19926
20743
  }
19927
20744
  return session.injectMessageBatch(optionsList);
19928
20745
  },
19929
20746
  /** @deprecated Use injectMessage() instead */
19930
20747
  injectTestMessage(event) {
19931
- if (!open && launcherEnabled) {
20748
+ if (!open && isPanelToggleable()) {
19932
20749
  setOpenState(true, "system");
19933
20750
  }
19934
20751
  session.injectTestEvent(event);
@@ -19991,7 +20808,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19991
20808
  return (_a2 = session == null ? void 0 : session.getSelectedArtifactId()) != null ? _a2 : null;
19992
20809
  },
19993
20810
  focusInput() {
19994
- if (launcherEnabled && !open) return false;
20811
+ if (launcherEnabled && !open && !isComposerBar()) return false;
19995
20812
  if (!textarea) return false;
19996
20813
  textarea.focus();
19997
20814
  return true;
@@ -20029,14 +20846,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20029
20846
  },
20030
20847
  // State query methods
20031
20848
  isOpen() {
20032
- return launcherEnabled && open;
20849
+ return isPanelToggleable() && open;
20033
20850
  },
20034
20851
  isVoiceActive() {
20035
20852
  return voiceState.active;
20036
20853
  },
20037
20854
  getState() {
20038
20855
  return {
20039
- open: launcherEnabled && open,
20856
+ open: isPanelToggleable() && open,
20040
20857
  launcherEnabled,
20041
20858
  voiceActive: voiceState.active,
20042
20859
  streaming: session.isStreaming()
@@ -20044,7 +20861,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20044
20861
  },
20045
20862
  // Feedback methods (CSAT/NPS)
20046
20863
  showCSATFeedback(options) {
20047
- if (!open && launcherEnabled) {
20864
+ if (!open && isPanelToggleable()) {
20048
20865
  setOpenState(true, "system");
20049
20866
  }
20050
20867
  const existingFeedback = messagesWrapper.querySelector(".persona-feedback-container");
@@ -20066,7 +20883,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20066
20883
  feedbackEl.scrollIntoView({ behavior: "smooth", block: "end" });
20067
20884
  },
20068
20885
  showNPSFeedback(options) {
20069
- if (!open && launcherEnabled) {
20886
+ if (!open && isPanelToggleable()) {
20070
20887
  setOpenState(true, "system");
20071
20888
  }
20072
20889
  const existingFeedback = messagesWrapper.querySelector(".persona-feedback-container");
@@ -20100,6 +20917,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20100
20917
  }
20101
20918
  destroyCallbacks.forEach((cb) => cb());
20102
20919
  wrapper.remove();
20920
+ pillRoot == null ? void 0 : pillRoot.remove();
20103
20921
  launcherButtonInstance == null ? void 0 : launcherButtonInstance.destroy();
20104
20922
  customLauncherElement == null ? void 0 : customLauncherElement.remove();
20105
20923
  if (closeHandler) {
@@ -20107,7 +20925,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20107
20925
  }
20108
20926
  }
20109
20927
  };
20110
- const shouldExposeDebugApi = ((_L = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _L : false) || Boolean(config.debug);
20928
+ const shouldExposeDebugApi = ((_P = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _P : false) || Boolean(config.debug);
20111
20929
  if (shouldExposeDebugApi && typeof window !== "undefined") {
20112
20930
  const previousDebug = window.AgentWidgetBrowser;
20113
20931
  const debugApi = {
@@ -20204,15 +21022,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20204
21022
  });
20205
21023
  }
20206
21024
  const persistConfig = normalizePersistStateConfig(config.persistState);
20207
- if (persistConfig && launcherEnabled) {
21025
+ if (persistConfig && isPanelToggleable()) {
20208
21026
  const storage = getPersistStorage(persistConfig.storage);
20209
21027
  const openKey = `${persistConfig.keyPrefix}widget-open`;
20210
21028
  const voiceKey = `${persistConfig.keyPrefix}widget-voice`;
20211
21029
  const voiceModeKey = `${persistConfig.keyPrefix}widget-voice-mode`;
20212
21030
  if (storage) {
20213
- const wasOpen = ((_M = persistConfig.persist) == null ? void 0 : _M.openState) && storage.getItem(openKey) === "true";
20214
- const wasVoiceActive = ((_N = persistConfig.persist) == null ? void 0 : _N.voiceState) && storage.getItem(voiceKey) === "true";
20215
- const wasInVoiceMode = ((_O = persistConfig.persist) == null ? void 0 : _O.voiceState) && storage.getItem(voiceModeKey) === "true";
21031
+ const wasOpen = ((_Q = persistConfig.persist) == null ? void 0 : _Q.openState) && storage.getItem(openKey) === "true";
21032
+ const wasVoiceActive = ((_R = persistConfig.persist) == null ? void 0 : _R.voiceState) && storage.getItem(voiceKey) === "true";
21033
+ const wasInVoiceMode = ((_S = persistConfig.persist) == null ? void 0 : _S.voiceState) && storage.getItem(voiceModeKey) === "true";
20216
21034
  if (wasOpen) {
20217
21035
  setTimeout(() => {
20218
21036
  controller.open();
@@ -20229,7 +21047,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20229
21047
  }, 100);
20230
21048
  }, 0);
20231
21049
  }
20232
- if ((_P = persistConfig.persist) == null ? void 0 : _P.openState) {
21050
+ if ((_T = persistConfig.persist) == null ? void 0 : _T.openState) {
20233
21051
  eventBus.on("widget:opened", () => {
20234
21052
  storage.setItem(openKey, "true");
20235
21053
  });
@@ -20237,7 +21055,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20237
21055
  storage.setItem(openKey, "false");
20238
21056
  });
20239
21057
  }
20240
- if ((_Q = persistConfig.persist) == null ? void 0 : _Q.voiceState) {
21058
+ if ((_U = persistConfig.persist) == null ? void 0 : _U.voiceState) {
20241
21059
  eventBus.on("voice:state", (event) => {
20242
21060
  storage.setItem(voiceKey, event.active ? "true" : "false");
20243
21061
  });
@@ -20259,11 +21077,12 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20259
21077
  }
20260
21078
  }
20261
21079
  }
20262
- if (shouldOpenAfterStateLoaded && launcherEnabled) {
21080
+ if (shouldOpenAfterStateLoaded && isPanelToggleable()) {
20263
21081
  setTimeout(() => {
20264
21082
  controller.open();
20265
21083
  }, 0);
20266
21084
  }
21085
+ syncComposerBarPeek();
20267
21086
  return controller;
20268
21087
  };
20269
21088