@runtypelabs/persona 3.18.0 → 3.20.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 (42) hide show
  1. package/README.md +45 -2
  2. package/dist/index.cjs +47 -47
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +383 -6
  5. package/dist/index.d.ts +383 -6
  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 +1514 -626
  11. package/dist/theme-editor.d.cts +192 -1
  12. package/dist/theme-editor.d.ts +192 -1
  13. package/dist/theme-editor.js +1628 -626
  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 +5 -0
  27. package/src/runtime/init.ts +4 -2
  28. package/src/runtime/persist-state.test.ts +152 -0
  29. package/src/session.test.ts +123 -0
  30. package/src/session.ts +58 -4
  31. package/src/styles/widget.css +348 -0
  32. package/src/types.ts +196 -1
  33. package/src/ui.component-directive.test.ts +183 -0
  34. package/src/ui.composer-bar.test.ts +1009 -0
  35. package/src/ui.ts +827 -72
  36. package/src/utils/attachment-manager.ts +1 -1
  37. package/src/utils/component-middleware.test.ts +134 -0
  38. package/src/utils/component-middleware.ts +44 -13
  39. package/src/utils/dock.test.ts +45 -0
  40. package/src/utils/dock.ts +3 -0
  41. package/src/utils/icons.ts +314 -58
  42. package/src/utils/stream-animation.ts +7 -2
@@ -7394,7 +7394,8 @@ var AgentWidgetSession = class _AgentWidgetSession {
7394
7394
  createdAt,
7395
7395
  sequence,
7396
7396
  streaming = false,
7397
- voiceProcessing
7397
+ voiceProcessing,
7398
+ rawContent
7398
7399
  } = options;
7399
7400
  const messageId = id != null ? id : role === "user" ? generateUserMessageId() : role === "assistant" ? generateAssistantMessageId() : `system-${Date.now()}-${Math.random().toString(16).slice(2)}`;
7400
7401
  const message = {
@@ -7407,7 +7408,8 @@ var AgentWidgetSession = class _AgentWidgetSession {
7407
7408
  // Only include optional fields if provided
7408
7409
  ...llmContent !== void 0 && { llmContent },
7409
7410
  ...contentParts !== void 0 && { contentParts },
7410
- ...voiceProcessing !== void 0 && { voiceProcessing }
7411
+ ...voiceProcessing !== void 0 && { voiceProcessing },
7412
+ ...rawContent !== void 0 && { rawContent }
7411
7413
  };
7412
7414
  this.upsertMessage(message);
7413
7415
  return message;
@@ -7472,7 +7474,9 @@ var AgentWidgetSession = class _AgentWidgetSession {
7472
7474
  id,
7473
7475
  createdAt,
7474
7476
  sequence,
7475
- streaming = false
7477
+ streaming = false,
7478
+ voiceProcessing,
7479
+ rawContent
7476
7480
  } = options;
7477
7481
  const messageId = id != null ? id : role === "user" ? generateUserMessageId() : role === "assistant" ? generateAssistantMessageId() : `system-${Date.now()}-${Math.random().toString(16).slice(2)}`;
7478
7482
  const message = {
@@ -7483,7 +7487,9 @@ var AgentWidgetSession = class _AgentWidgetSession {
7483
7487
  sequence: sequence != null ? sequence : this.nextSequence(),
7484
7488
  streaming,
7485
7489
  ...llmContent !== void 0 && { llmContent },
7486
- ...contentParts !== void 0 && { contentParts }
7490
+ ...contentParts !== void 0 && { contentParts },
7491
+ ...voiceProcessing !== void 0 && { voiceProcessing },
7492
+ ...rawContent !== void 0 && { rawContent }
7487
7493
  };
7488
7494
  results.push(message);
7489
7495
  }
@@ -7491,6 +7497,48 @@ var AgentWidgetSession = class _AgentWidgetSession {
7491
7497
  this.callbacks.onMessagesChanged([...this.messages]);
7492
7498
  return results;
7493
7499
  }
7500
+ /**
7501
+ * Convenience method for injecting a registered component directive as
7502
+ * an assistant message — the same shape Persona produces from a streamed
7503
+ * `{ "text": "...", "component": "...", "props": {...} }` payload.
7504
+ *
7505
+ * Sets `content` to `text`, `rawContent` to the JSON directive (so
7506
+ * `extractComponentDirectiveFromMessage` can find it), and forwards
7507
+ * `llmContent` / `id` / `createdAt` / `sequence`.
7508
+ *
7509
+ * @example
7510
+ * session.injectComponentDirective({
7511
+ * component: "DynamicForm",
7512
+ * props: { title: "Book a demo", fields: [...] },
7513
+ * text: "Share your details to book a demo.",
7514
+ * llmContent: "[Showed booking form]"
7515
+ * });
7516
+ */
7517
+ injectComponentDirective(options) {
7518
+ const {
7519
+ component,
7520
+ props = {},
7521
+ text = "",
7522
+ llmContent,
7523
+ id,
7524
+ createdAt,
7525
+ sequence
7526
+ } = options;
7527
+ const directive = {
7528
+ text,
7529
+ component,
7530
+ props
7531
+ };
7532
+ return this.injectMessage({
7533
+ role: "assistant",
7534
+ content: text,
7535
+ rawContent: JSON.stringify(directive),
7536
+ ...llmContent !== void 0 && { llmContent },
7537
+ ...id !== void 0 && { id },
7538
+ ...createdAt !== void 0 && { createdAt },
7539
+ ...sequence !== void 0 && { sequence }
7540
+ });
7541
+ }
7494
7542
  async sendMessage(rawInput, options) {
7495
7543
  var _a, _b, _c, _d, _e;
7496
7544
  const input = rawInput.trim();
@@ -8178,25 +8226,260 @@ var createElementInDocument = (documentRef, tag, className) => {
8178
8226
  };
8179
8227
 
8180
8228
  // src/utils/icons.ts
8181
- import * as icons from "lucide";
8229
+ import {
8230
+ Activity,
8231
+ ArrowDown,
8232
+ ArrowUp,
8233
+ ArrowUpRight,
8234
+ Bot,
8235
+ ChevronDown,
8236
+ ChevronUp,
8237
+ ChevronRight,
8238
+ ChevronLeft,
8239
+ Check,
8240
+ Clipboard,
8241
+ ClipboardCopy,
8242
+ Copy,
8243
+ File as FileIcon,
8244
+ FileCode,
8245
+ FileSpreadsheet,
8246
+ FileText,
8247
+ ImagePlus,
8248
+ Loader,
8249
+ LoaderCircle,
8250
+ Mic,
8251
+ Paperclip,
8252
+ RefreshCw,
8253
+ Search,
8254
+ Send,
8255
+ ShieldAlert,
8256
+ ShieldCheck,
8257
+ ShieldX,
8258
+ Square,
8259
+ ThumbsDown,
8260
+ ThumbsUp,
8261
+ Upload,
8262
+ Volume2,
8263
+ X,
8264
+ User,
8265
+ Mail,
8266
+ Phone,
8267
+ Calendar,
8268
+ Clock,
8269
+ Building,
8270
+ MapPin,
8271
+ Lock,
8272
+ Key,
8273
+ CreditCard,
8274
+ AtSign,
8275
+ Hash,
8276
+ Globe,
8277
+ Link,
8278
+ CircleCheck,
8279
+ CircleX,
8280
+ TriangleAlert,
8281
+ Info,
8282
+ Ban,
8283
+ Shield,
8284
+ ArrowLeft,
8285
+ ArrowRight,
8286
+ ExternalLink,
8287
+ Ellipsis,
8288
+ EllipsisVertical,
8289
+ Menu,
8290
+ House,
8291
+ Plus,
8292
+ Minus,
8293
+ Pencil,
8294
+ Trash,
8295
+ Trash2,
8296
+ Save,
8297
+ Download,
8298
+ Share,
8299
+ Funnel,
8300
+ Settings,
8301
+ RotateCw,
8302
+ Maximize,
8303
+ Minimize,
8304
+ ShoppingCart,
8305
+ ShoppingBag,
8306
+ Package,
8307
+ Truck,
8308
+ Tag,
8309
+ Gift,
8310
+ Receipt,
8311
+ Wallet,
8312
+ Store,
8313
+ DollarSign,
8314
+ Percent,
8315
+ Play,
8316
+ Pause,
8317
+ VolumeX,
8318
+ Camera,
8319
+ Image as ImageIcon,
8320
+ Film,
8321
+ Headphones,
8322
+ MessageCircle,
8323
+ MessageSquare,
8324
+ Bell,
8325
+ Heart,
8326
+ Star,
8327
+ Eye,
8328
+ EyeOff,
8329
+ Bookmark,
8330
+ CalendarDays,
8331
+ History,
8332
+ Timer,
8333
+ Folder,
8334
+ FolderOpen,
8335
+ Files,
8336
+ Sparkles,
8337
+ Zap,
8338
+ Sun,
8339
+ Moon,
8340
+ Flag,
8341
+ Monitor,
8342
+ Smartphone
8343
+ } from "lucide";
8344
+ var LUCIDE_ICONS = {
8345
+ // Mandatory
8346
+ "activity": Activity,
8347
+ "arrow-down": ArrowDown,
8348
+ "arrow-up": ArrowUp,
8349
+ "arrow-up-right": ArrowUpRight,
8350
+ "bot": Bot,
8351
+ "chevron-down": ChevronDown,
8352
+ "chevron-up": ChevronUp,
8353
+ "chevron-right": ChevronRight,
8354
+ "chevron-left": ChevronLeft,
8355
+ "check": Check,
8356
+ "clipboard": Clipboard,
8357
+ "clipboard-copy": ClipboardCopy,
8358
+ "copy": Copy,
8359
+ "file": FileIcon,
8360
+ "file-code": FileCode,
8361
+ "file-spreadsheet": FileSpreadsheet,
8362
+ "file-text": FileText,
8363
+ "image-plus": ImagePlus,
8364
+ "loader": Loader,
8365
+ "loader-circle": LoaderCircle,
8366
+ "mic": Mic,
8367
+ "paperclip": Paperclip,
8368
+ "refresh-cw": RefreshCw,
8369
+ "search": Search,
8370
+ "send": Send,
8371
+ "shield-alert": ShieldAlert,
8372
+ "shield-check": ShieldCheck,
8373
+ "shield-x": ShieldX,
8374
+ "square": Square,
8375
+ "thumbs-down": ThumbsDown,
8376
+ "thumbs-up": ThumbsUp,
8377
+ "upload": Upload,
8378
+ "volume-2": Volume2,
8379
+ "x": X,
8380
+ // Forms / inputs
8381
+ "user": User,
8382
+ "mail": Mail,
8383
+ "phone": Phone,
8384
+ "calendar": Calendar,
8385
+ "clock": Clock,
8386
+ "building": Building,
8387
+ "map-pin": MapPin,
8388
+ "lock": Lock,
8389
+ "key": Key,
8390
+ "credit-card": CreditCard,
8391
+ "at-sign": AtSign,
8392
+ "hash": Hash,
8393
+ "globe": Globe,
8394
+ "link": Link,
8395
+ // Status / feedback
8396
+ "circle-check": CircleCheck,
8397
+ "circle-x": CircleX,
8398
+ "triangle-alert": TriangleAlert,
8399
+ "info": Info,
8400
+ "ban": Ban,
8401
+ "shield": Shield,
8402
+ // Navigation
8403
+ "arrow-left": ArrowLeft,
8404
+ "arrow-right": ArrowRight,
8405
+ "external-link": ExternalLink,
8406
+ "ellipsis": Ellipsis,
8407
+ "ellipsis-vertical": EllipsisVertical,
8408
+ "menu": Menu,
8409
+ "house": House,
8410
+ // Actions
8411
+ "plus": Plus,
8412
+ "minus": Minus,
8413
+ "pencil": Pencil,
8414
+ "trash": Trash,
8415
+ "trash-2": Trash2,
8416
+ "save": Save,
8417
+ "download": Download,
8418
+ "share": Share,
8419
+ "funnel": Funnel,
8420
+ "settings": Settings,
8421
+ "rotate-cw": RotateCw,
8422
+ "maximize": Maximize,
8423
+ "minimize": Minimize,
8424
+ // Commerce
8425
+ "shopping-cart": ShoppingCart,
8426
+ "shopping-bag": ShoppingBag,
8427
+ "package": Package,
8428
+ "truck": Truck,
8429
+ "tag": Tag,
8430
+ "gift": Gift,
8431
+ "receipt": Receipt,
8432
+ "wallet": Wallet,
8433
+ "store": Store,
8434
+ "dollar-sign": DollarSign,
8435
+ "percent": Percent,
8436
+ // Media
8437
+ "play": Play,
8438
+ "pause": Pause,
8439
+ "volume-x": VolumeX,
8440
+ "camera": Camera,
8441
+ "image": ImageIcon,
8442
+ "film": Film,
8443
+ "headphones": Headphones,
8444
+ // Social / Comms
8445
+ "message-circle": MessageCircle,
8446
+ "message-square": MessageSquare,
8447
+ "bell": Bell,
8448
+ "heart": Heart,
8449
+ "star": Star,
8450
+ "eye": Eye,
8451
+ "eye-off": EyeOff,
8452
+ "bookmark": Bookmark,
8453
+ // Time
8454
+ "calendar-days": CalendarDays,
8455
+ "history": History,
8456
+ "timer": Timer,
8457
+ // Files
8458
+ "folder": Folder,
8459
+ "folder-open": FolderOpen,
8460
+ "files": Files,
8461
+ // Decorative
8462
+ "sparkles": Sparkles,
8463
+ "zap": Zap,
8464
+ "sun": Sun,
8465
+ "moon": Moon,
8466
+ "flag": Flag,
8467
+ // Devices
8468
+ "monitor": Monitor,
8469
+ "smartphone": Smartphone
8470
+ };
8182
8471
  var renderLucideIcon = (iconName, size = 24, color = "currentColor", strokeWidth = 2) => {
8183
- try {
8184
- const pascalName = iconName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
8185
- const iconData = icons[pascalName];
8186
- if (!iconData) {
8187
- console.warn(`Lucide icon "${iconName}" not found (tried "${pascalName}"). Available icons: https://lucide.dev/icons`);
8188
- return null;
8189
- }
8190
- return createSvgFromIconData(iconData, size, color, strokeWidth);
8191
- } catch (error) {
8192
- console.warn(`Failed to render Lucide icon "${iconName}":`, error);
8472
+ const iconData = LUCIDE_ICONS[iconName];
8473
+ if (!iconData) {
8474
+ console.warn(
8475
+ `Lucide icon "${iconName}" is not in the Persona registry. Add it to packages/widget/src/utils/icons.ts (see docs/icon-registry-shortlist.md).`
8476
+ );
8193
8477
  return null;
8194
8478
  }
8479
+ return createSvgFromIconData(iconData, size, color, strokeWidth);
8195
8480
  };
8196
8481
  function createSvgFromIconData(iconData, size, color, strokeWidth) {
8197
- if (!iconData || !Array.isArray(iconData)) {
8198
- return null;
8199
- }
8482
+ if (!Array.isArray(iconData)) return null;
8200
8483
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
8201
8484
  svg.setAttribute("width", String(size));
8202
8485
  svg.setAttribute("height", String(size));
@@ -8208,19 +8491,15 @@ function createSvgFromIconData(iconData, size, color, strokeWidth) {
8208
8491
  svg.setAttribute("stroke-linejoin", "round");
8209
8492
  svg.setAttribute("aria-hidden", "true");
8210
8493
  iconData.forEach((elementData) => {
8211
- if (Array.isArray(elementData) && elementData.length >= 2) {
8212
- const tagName = elementData[0];
8213
- const attrs = elementData[1];
8214
- if (attrs) {
8215
- const element = document.createElementNS("http://www.w3.org/2000/svg", tagName);
8216
- Object.entries(attrs).forEach(([key, value]) => {
8217
- if (key !== "stroke") {
8218
- element.setAttribute(key, String(value));
8219
- }
8220
- });
8221
- svg.appendChild(element);
8222
- }
8223
- }
8494
+ if (!Array.isArray(elementData) || elementData.length < 2) return;
8495
+ const tagName = elementData[0];
8496
+ const attrs = elementData[1];
8497
+ if (!attrs) return;
8498
+ const element = document.createElementNS("http://www.w3.org/2000/svg", tagName);
8499
+ Object.entries(attrs).forEach(([key, value]) => {
8500
+ if (key !== "stroke") element.setAttribute(key, String(value));
8501
+ });
8502
+ svg.appendChild(element);
8224
8503
  });
8225
8504
  return svg;
8226
8505
  }
@@ -8240,7 +8519,7 @@ function getFileIconName(mimeType) {
8240
8519
  if (mimeType.startsWith("text/")) return "file-text";
8241
8520
  if (mimeType.includes("word")) return "file-text";
8242
8521
  if (mimeType.includes("excel") || mimeType.includes("spreadsheet")) return "file-spreadsheet";
8243
- if (mimeType === "application/json") return "file-json";
8522
+ if (mimeType === "application/json") return "file-code";
8244
8523
  return "file";
8245
8524
  }
8246
8525
  var AttachmentManager = class _AttachmentManager {
@@ -8802,7 +9081,7 @@ var wrapTextNodeWords = (textNode, messageId, counterRef) => {
8802
9081
  parent.replaceChild(fragment, textNode);
8803
9082
  };
8804
9083
  var wrapStreamAnimation = (html, mode, messageId, options) => {
8805
- var _a;
9084
+ var _a, _b;
8806
9085
  if (!html) return html;
8807
9086
  if (typeof document === "undefined") return html;
8808
9087
  const scratch = document.createElement("div");
@@ -8817,7 +9096,7 @@ var wrapStreamAnimation = (html, mode, messageId, options) => {
8817
9096
  }
8818
9097
  node = walker.nextNode();
8819
9098
  }
8820
- const counterRef = { value: 0 };
9099
+ const counterRef = { value: (_b = options == null ? void 0 : options.startIndex) != null ? _b : 0 };
8821
9100
  const wrap = mode === "char" ? wrapTextNodeChars : wrapTextNodeWords;
8822
9101
  for (const textNode of textNodes) {
8823
9102
  wrap(textNode, messageId, counterRef);
@@ -8963,6 +9242,10 @@ var isDockedMountMode = (config) => {
8963
9242
  var _a, _b;
8964
9243
  return ((_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.mountMode) != null ? _b : "floating") === "docked";
8965
9244
  };
9245
+ var isComposerBarMountMode = (config) => {
9246
+ var _a, _b;
9247
+ return ((_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.mountMode) != null ? _b : "floating") === "composer-bar";
9248
+ };
8966
9249
  var resolveDockConfig = (config) => {
8967
9250
  var _a, _b, _c, _d, _e;
8968
9251
  const dock = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.dock;
@@ -9149,6 +9432,226 @@ var createLauncherButton = (config, onToggle) => {
9149
9432
  };
9150
9433
  };
9151
9434
 
9435
+ // src/components/header-parts.ts
9436
+ var DEFAULT_WRAPPER_CLASS = "persona-relative persona-ml-auto persona-inline-flex persona-items-center persona-justify-center";
9437
+ var createCloseButton = (config, options = {}) => {
9438
+ var _a, _b, _c, _d, _e, _f;
9439
+ const {
9440
+ showClose = true,
9441
+ wrapperClassName = DEFAULT_WRAPPER_CLASS,
9442
+ buttonSize,
9443
+ iconSize = "28px"
9444
+ } = options;
9445
+ const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9446
+ const closeButtonSize = (_b = buttonSize != null ? buttonSize : launcher.closeButtonSize) != null ? _b : "32px";
9447
+ const wrapper = createElement("div", wrapperClassName);
9448
+ const button = createElement(
9449
+ "button",
9450
+ "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9451
+ );
9452
+ button.style.height = closeButtonSize;
9453
+ button.style.width = closeButtonSize;
9454
+ button.type = "button";
9455
+ const closeButtonTooltipText = (_c = launcher.closeButtonTooltipText) != null ? _c : "Close chat";
9456
+ const closeButtonShowTooltip = (_d = launcher.closeButtonShowTooltip) != null ? _d : true;
9457
+ button.setAttribute("aria-label", closeButtonTooltipText);
9458
+ button.style.display = showClose ? "" : "none";
9459
+ const closeButtonIconName = (_e = launcher.closeButtonIconName) != null ? _e : "x";
9460
+ const closeButtonIconText = (_f = launcher.closeButtonIconText) != null ? _f : "\xD7";
9461
+ button.style.color = launcher.closeButtonColor || HEADER_THEME_CSS.actionIconColor;
9462
+ const closeIconSvg = renderLucideIcon(closeButtonIconName, iconSize, "currentColor", 1);
9463
+ if (closeIconSvg) {
9464
+ closeIconSvg.style.display = "block";
9465
+ button.appendChild(closeIconSvg);
9466
+ } else {
9467
+ button.textContent = closeButtonIconText;
9468
+ }
9469
+ if (launcher.closeButtonBackgroundColor) {
9470
+ button.style.backgroundColor = launcher.closeButtonBackgroundColor;
9471
+ button.classList.remove("hover:persona-bg-gray-100");
9472
+ } else {
9473
+ button.style.backgroundColor = "";
9474
+ button.classList.add("hover:persona-bg-gray-100");
9475
+ }
9476
+ if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {
9477
+ const borderWidth = launcher.closeButtonBorderWidth || "0px";
9478
+ const borderColor = launcher.closeButtonBorderColor || "transparent";
9479
+ button.style.border = `${borderWidth} solid ${borderColor}`;
9480
+ button.classList.remove("persona-border-none");
9481
+ } else {
9482
+ button.style.border = "";
9483
+ button.classList.add("persona-border-none");
9484
+ }
9485
+ if (launcher.closeButtonBorderRadius) {
9486
+ button.style.borderRadius = launcher.closeButtonBorderRadius;
9487
+ button.classList.remove("persona-rounded-full");
9488
+ } else {
9489
+ button.style.borderRadius = "";
9490
+ button.classList.add("persona-rounded-full");
9491
+ }
9492
+ if (launcher.closeButtonPaddingX) {
9493
+ button.style.paddingLeft = launcher.closeButtonPaddingX;
9494
+ button.style.paddingRight = launcher.closeButtonPaddingX;
9495
+ } else {
9496
+ button.style.paddingLeft = "";
9497
+ button.style.paddingRight = "";
9498
+ }
9499
+ if (launcher.closeButtonPaddingY) {
9500
+ button.style.paddingTop = launcher.closeButtonPaddingY;
9501
+ button.style.paddingBottom = launcher.closeButtonPaddingY;
9502
+ } else {
9503
+ button.style.paddingTop = "";
9504
+ button.style.paddingBottom = "";
9505
+ }
9506
+ wrapper.appendChild(button);
9507
+ if (closeButtonShowTooltip && closeButtonTooltipText) {
9508
+ let portaledTooltip = null;
9509
+ const showTooltip = () => {
9510
+ if (portaledTooltip) return;
9511
+ const tooltipDocument = button.ownerDocument;
9512
+ const tooltipContainer = tooltipDocument.body;
9513
+ if (!tooltipContainer) return;
9514
+ portaledTooltip = createElementInDocument(
9515
+ tooltipDocument,
9516
+ "div",
9517
+ "persona-clear-chat-tooltip"
9518
+ );
9519
+ portaledTooltip.textContent = closeButtonTooltipText;
9520
+ const arrow = createElementInDocument(tooltipDocument, "div");
9521
+ arrow.className = "persona-clear-chat-tooltip-arrow";
9522
+ portaledTooltip.appendChild(arrow);
9523
+ const buttonRect = button.getBoundingClientRect();
9524
+ portaledTooltip.style.position = "fixed";
9525
+ portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9526
+ portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9527
+ portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9528
+ portaledTooltip.style.transform = "translate(-50%, -100%)";
9529
+ tooltipContainer.appendChild(portaledTooltip);
9530
+ };
9531
+ const hideTooltip = () => {
9532
+ if (portaledTooltip && portaledTooltip.parentNode) {
9533
+ portaledTooltip.parentNode.removeChild(portaledTooltip);
9534
+ portaledTooltip = null;
9535
+ }
9536
+ };
9537
+ wrapper.addEventListener("mouseenter", showTooltip);
9538
+ wrapper.addEventListener("mouseleave", hideTooltip);
9539
+ button.addEventListener("focus", showTooltip);
9540
+ button.addEventListener("blur", hideTooltip);
9541
+ wrapper._cleanupTooltip = () => {
9542
+ hideTooltip();
9543
+ wrapper.removeEventListener("mouseenter", showTooltip);
9544
+ wrapper.removeEventListener("mouseleave", hideTooltip);
9545
+ button.removeEventListener("focus", showTooltip);
9546
+ button.removeEventListener("blur", hideTooltip);
9547
+ };
9548
+ }
9549
+ return { button, wrapper };
9550
+ };
9551
+ var DEFAULT_CLEAR_CHAT_WRAPPER_CLASS = "persona-relative persona-ml-auto persona-clear-chat-button-wrapper";
9552
+ var createClearChatButton = (config, options = {}) => {
9553
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
9554
+ const {
9555
+ wrapperClassName = DEFAULT_CLEAR_CHAT_WRAPPER_CLASS,
9556
+ buttonSize,
9557
+ iconSize = "20px"
9558
+ } = options;
9559
+ const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9560
+ const clearChatConfig = (_b = launcher.clearChat) != null ? _b : {};
9561
+ const clearChatSize = (_c = buttonSize != null ? buttonSize : clearChatConfig.size) != null ? _c : "32px";
9562
+ const clearChatIconName = (_d = clearChatConfig.iconName) != null ? _d : "refresh-cw";
9563
+ const clearChatIconColor = (_e = clearChatConfig.iconColor) != null ? _e : "";
9564
+ const clearChatBgColor = (_f = clearChatConfig.backgroundColor) != null ? _f : "";
9565
+ const clearChatBorderWidth = (_g = clearChatConfig.borderWidth) != null ? _g : "";
9566
+ const clearChatBorderColor = (_h = clearChatConfig.borderColor) != null ? _h : "";
9567
+ const clearChatBorderRadius = (_i = clearChatConfig.borderRadius) != null ? _i : "";
9568
+ const clearChatPaddingX = (_j = clearChatConfig.paddingX) != null ? _j : "";
9569
+ const clearChatPaddingY = (_k = clearChatConfig.paddingY) != null ? _k : "";
9570
+ const clearChatTooltipText = (_l = clearChatConfig.tooltipText) != null ? _l : "Clear chat";
9571
+ const clearChatShowTooltip = (_m = clearChatConfig.showTooltip) != null ? _m : true;
9572
+ const wrapper = createElement("div", wrapperClassName);
9573
+ const button = createElement(
9574
+ "button",
9575
+ "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9576
+ );
9577
+ button.style.height = clearChatSize;
9578
+ button.style.width = clearChatSize;
9579
+ button.type = "button";
9580
+ button.setAttribute("aria-label", clearChatTooltipText);
9581
+ button.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
9582
+ const iconSvg = renderLucideIcon(clearChatIconName, iconSize, "currentColor", 1);
9583
+ if (iconSvg) {
9584
+ iconSvg.style.display = "block";
9585
+ button.appendChild(iconSvg);
9586
+ }
9587
+ if (clearChatBgColor) {
9588
+ button.style.backgroundColor = clearChatBgColor;
9589
+ button.classList.remove("hover:persona-bg-gray-100");
9590
+ }
9591
+ if (clearChatBorderWidth || clearChatBorderColor) {
9592
+ const borderWidth = clearChatBorderWidth || "0px";
9593
+ const borderColor = clearChatBorderColor || "transparent";
9594
+ button.style.border = `${borderWidth} solid ${borderColor}`;
9595
+ button.classList.remove("persona-border-none");
9596
+ }
9597
+ if (clearChatBorderRadius) {
9598
+ button.style.borderRadius = clearChatBorderRadius;
9599
+ button.classList.remove("persona-rounded-full");
9600
+ }
9601
+ if (clearChatPaddingX) {
9602
+ button.style.paddingLeft = clearChatPaddingX;
9603
+ button.style.paddingRight = clearChatPaddingX;
9604
+ }
9605
+ if (clearChatPaddingY) {
9606
+ button.style.paddingTop = clearChatPaddingY;
9607
+ button.style.paddingBottom = clearChatPaddingY;
9608
+ }
9609
+ wrapper.appendChild(button);
9610
+ if (clearChatShowTooltip && clearChatTooltipText) {
9611
+ let portaledTooltip = null;
9612
+ const showTooltip = () => {
9613
+ if (portaledTooltip) return;
9614
+ const tooltipDocument = button.ownerDocument;
9615
+ const tooltipContainer = tooltipDocument.body;
9616
+ if (!tooltipContainer) return;
9617
+ portaledTooltip = createElementInDocument(
9618
+ tooltipDocument,
9619
+ "div",
9620
+ "persona-clear-chat-tooltip"
9621
+ );
9622
+ portaledTooltip.textContent = clearChatTooltipText;
9623
+ const arrow = createElementInDocument(tooltipDocument, "div");
9624
+ arrow.className = "persona-clear-chat-tooltip-arrow";
9625
+ portaledTooltip.appendChild(arrow);
9626
+ const buttonRect = button.getBoundingClientRect();
9627
+ portaledTooltip.style.position = "fixed";
9628
+ portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9629
+ portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9630
+ portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9631
+ portaledTooltip.style.transform = "translate(-50%, -100%)";
9632
+ tooltipContainer.appendChild(portaledTooltip);
9633
+ };
9634
+ const hideTooltip = () => {
9635
+ if (portaledTooltip && portaledTooltip.parentNode) {
9636
+ portaledTooltip.parentNode.removeChild(portaledTooltip);
9637
+ portaledTooltip = null;
9638
+ }
9639
+ };
9640
+ wrapper.addEventListener("mouseenter", showTooltip);
9641
+ wrapper.addEventListener("mouseleave", hideTooltip);
9642
+ button.addEventListener("focus", showTooltip);
9643
+ button.addEventListener("blur", hideTooltip);
9644
+ wrapper._cleanupTooltip = () => {
9645
+ hideTooltip();
9646
+ wrapper.removeEventListener("mouseenter", showTooltip);
9647
+ wrapper.removeEventListener("mouseleave", hideTooltip);
9648
+ button.removeEventListener("focus", showTooltip);
9649
+ button.removeEventListener("blur", hideTooltip);
9650
+ };
9651
+ }
9652
+ return { button, wrapper };
9653
+ };
9654
+
9152
9655
  // src/components/header-builder.ts
9153
9656
  var HEADER_THEME_CSS = {
9154
9657
  titleColor: "var(--persona-header-title-fg, var(--persona-primary, #0f0f0f))",
@@ -9156,7 +9659,7 @@ var HEADER_THEME_CSS = {
9156
9659
  actionIconColor: "var(--persona-header-action-icon-fg, var(--persona-muted, #9ca3af))"
9157
9660
  };
9158
9661
  var buildHeader = (context) => {
9159
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F;
9662
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
9160
9663
  const { config, showClose = true } = context;
9161
9664
  const header = createElement(
9162
9665
  "div",
@@ -9169,9 +9672,8 @@ var buildHeader = (context) => {
9169
9672
  header.style.borderBottom = "var(--persona-header-border-bottom, 1px solid var(--persona-header-border, var(--persona-divider, #f1f5f9)))";
9170
9673
  const launcher = (_a = config == null ? void 0 : config.launcher) != null ? _a : {};
9171
9674
  const headerIconSize = (_b = launcher.headerIconSize) != null ? _b : "48px";
9172
- const closeButtonSize = (_c = launcher.closeButtonSize) != null ? _c : "32px";
9173
- const closeButtonPlacement = (_d = launcher.closeButtonPlacement) != null ? _d : "inline";
9174
- const headerIconHidden = (_e = launcher.headerIconHidden) != null ? _e : false;
9675
+ const closeButtonPlacement = (_c = launcher.closeButtonPlacement) != null ? _c : "inline";
9676
+ const headerIconHidden = (_d = launcher.headerIconHidden) != null ? _d : false;
9175
9677
  const headerIconName = launcher.headerIconName;
9176
9678
  const iconHolder = createElement(
9177
9679
  "div",
@@ -9188,9 +9690,9 @@ var buildHeader = (context) => {
9188
9690
  if (iconSvg) {
9189
9691
  iconHolder.replaceChildren(iconSvg);
9190
9692
  } else {
9191
- iconHolder.textContent = (_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.agentIconText) != null ? _g : "\u{1F4AC}";
9693
+ iconHolder.textContent = (_f = (_e = config == null ? void 0 : config.launcher) == null ? void 0 : _e.agentIconText) != null ? _f : "\u{1F4AC}";
9192
9694
  }
9193
- } else if ((_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.iconUrl) {
9695
+ } else if ((_g = config == null ? void 0 : config.launcher) == null ? void 0 : _g.iconUrl) {
9194
9696
  const img = createElement("img");
9195
9697
  img.src = config.launcher.iconUrl;
9196
9698
  img.alt = "";
@@ -9199,244 +9701,44 @@ var buildHeader = (context) => {
9199
9701
  img.style.width = headerIconSize;
9200
9702
  iconHolder.replaceChildren(img);
9201
9703
  } else {
9202
- iconHolder.textContent = (_j = (_i = config == null ? void 0 : config.launcher) == null ? void 0 : _i.agentIconText) != null ? _j : "\u{1F4AC}";
9704
+ iconHolder.textContent = (_i = (_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.agentIconText) != null ? _i : "\u{1F4AC}";
9203
9705
  }
9204
9706
  }
9205
9707
  const headerCopy = createElement("div", "persona-flex persona-flex-col persona-flex-1 persona-min-w-0");
9206
9708
  const title = createElement("span", "persona-text-base persona-font-semibold");
9207
9709
  title.style.color = HEADER_THEME_CSS.titleColor;
9208
- title.textContent = (_l = (_k = config == null ? void 0 : config.launcher) == null ? void 0 : _k.title) != null ? _l : "Chat Assistant";
9710
+ title.textContent = (_k = (_j = config == null ? void 0 : config.launcher) == null ? void 0 : _j.title) != null ? _k : "Chat Assistant";
9209
9711
  const subtitle = createElement("span", "persona-text-xs");
9210
9712
  subtitle.style.color = HEADER_THEME_CSS.subtitleColor;
9211
- subtitle.textContent = (_n = (_m = config == null ? void 0 : config.launcher) == null ? void 0 : _m.subtitle) != null ? _n : "Here to help you get answers fast";
9713
+ subtitle.textContent = (_m = (_l = config == null ? void 0 : config.launcher) == null ? void 0 : _l.subtitle) != null ? _m : "Here to help you get answers fast";
9212
9714
  headerCopy.append(title, subtitle);
9213
9715
  if (!headerIconHidden) {
9214
9716
  header.append(iconHolder, headerCopy);
9215
9717
  } else {
9216
9718
  header.append(headerCopy);
9217
9719
  }
9218
- const clearChatConfig = (_o = launcher.clearChat) != null ? _o : {};
9219
- const clearChatEnabled = (_p = clearChatConfig.enabled) != null ? _p : true;
9220
- const clearChatPlacement = (_q = clearChatConfig.placement) != null ? _q : "inline";
9720
+ const clearChatConfig = (_n = launcher.clearChat) != null ? _n : {};
9721
+ const clearChatEnabled = (_o = clearChatConfig.enabled) != null ? _o : true;
9722
+ const clearChatPlacement = (_p = clearChatConfig.placement) != null ? _p : "inline";
9221
9723
  let clearChatButton = null;
9222
9724
  let clearChatButtonWrapper = null;
9223
9725
  if (clearChatEnabled) {
9224
- const clearChatSize = (_r = clearChatConfig.size) != null ? _r : "32px";
9225
- const clearChatIconName = (_s = clearChatConfig.iconName) != null ? _s : "refresh-cw";
9226
- const clearChatIconColor = (_t = clearChatConfig.iconColor) != null ? _t : "";
9227
- const clearChatBgColor = (_u = clearChatConfig.backgroundColor) != null ? _u : "";
9228
- const clearChatBorderWidth = (_v = clearChatConfig.borderWidth) != null ? _v : "";
9229
- const clearChatBorderColor = (_w = clearChatConfig.borderColor) != null ? _w : "";
9230
- const clearChatBorderRadius = (_x = clearChatConfig.borderRadius) != null ? _x : "";
9231
- const clearChatPaddingX = (_y = clearChatConfig.paddingX) != null ? _y : "";
9232
- const clearChatPaddingY = (_z = clearChatConfig.paddingY) != null ? _z : "";
9233
- const clearChatTooltipText = (_A = clearChatConfig.tooltipText) != null ? _A : "Clear chat";
9234
- const clearChatShowTooltip = (_B = clearChatConfig.showTooltip) != null ? _B : true;
9235
- clearChatButtonWrapper = createElement(
9236
- "div",
9237
- clearChatPlacement === "top-right" ? "persona-absolute persona-top-4 persona-z-50" : "persona-relative persona-ml-auto persona-clear-chat-button-wrapper"
9238
- );
9726
+ const wrapperClassName = clearChatPlacement === "top-right" ? "persona-absolute persona-top-4 persona-z-50" : "persona-relative persona-ml-auto persona-clear-chat-button-wrapper";
9727
+ const parts = createClearChatButton(config, { wrapperClassName });
9728
+ clearChatButton = parts.button;
9729
+ clearChatButtonWrapper = parts.wrapper;
9239
9730
  if (clearChatPlacement === "top-right") {
9240
9731
  clearChatButtonWrapper.style.right = "48px";
9241
9732
  }
9242
- clearChatButton = createElement(
9243
- "button",
9244
- "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9245
- );
9246
- clearChatButton.style.height = clearChatSize;
9247
- clearChatButton.style.width = clearChatSize;
9248
- clearChatButton.type = "button";
9249
- clearChatButton.setAttribute("aria-label", clearChatTooltipText);
9250
- clearChatButton.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
9251
- const iconSvg = renderLucideIcon(clearChatIconName, "20px", "currentColor", 1);
9252
- if (iconSvg) {
9253
- iconSvg.style.display = "block";
9254
- clearChatButton.appendChild(iconSvg);
9255
- }
9256
- if (clearChatBgColor) {
9257
- clearChatButton.style.backgroundColor = clearChatBgColor;
9258
- clearChatButton.classList.remove("hover:persona-bg-gray-100");
9259
- }
9260
- if (clearChatBorderWidth || clearChatBorderColor) {
9261
- const borderWidth = clearChatBorderWidth || "0px";
9262
- const borderColor = clearChatBorderColor || "transparent";
9263
- clearChatButton.style.border = `${borderWidth} solid ${borderColor}`;
9264
- clearChatButton.classList.remove("persona-border-none");
9265
- }
9266
- if (clearChatBorderRadius) {
9267
- clearChatButton.style.borderRadius = clearChatBorderRadius;
9268
- clearChatButton.classList.remove("persona-rounded-full");
9269
- }
9270
- if (clearChatPaddingX) {
9271
- clearChatButton.style.paddingLeft = clearChatPaddingX;
9272
- clearChatButton.style.paddingRight = clearChatPaddingX;
9273
- } else {
9274
- clearChatButton.style.paddingLeft = "";
9275
- clearChatButton.style.paddingRight = "";
9276
- }
9277
- if (clearChatPaddingY) {
9278
- clearChatButton.style.paddingTop = clearChatPaddingY;
9279
- clearChatButton.style.paddingBottom = clearChatPaddingY;
9280
- } else {
9281
- clearChatButton.style.paddingTop = "";
9282
- clearChatButton.style.paddingBottom = "";
9283
- }
9284
- clearChatButtonWrapper.appendChild(clearChatButton);
9285
- if (clearChatShowTooltip && clearChatTooltipText && clearChatButton && clearChatButtonWrapper) {
9286
- let portaledTooltip = null;
9287
- const showTooltip = () => {
9288
- if (portaledTooltip || !clearChatButton) return;
9289
- const tooltipDocument = clearChatButton.ownerDocument;
9290
- const tooltipContainer = tooltipDocument.body;
9291
- if (!tooltipContainer) return;
9292
- portaledTooltip = createElementInDocument(
9293
- tooltipDocument,
9294
- "div",
9295
- "persona-clear-chat-tooltip"
9296
- );
9297
- portaledTooltip.textContent = clearChatTooltipText;
9298
- const arrow = createElementInDocument(tooltipDocument, "div");
9299
- arrow.className = "persona-clear-chat-tooltip-arrow";
9300
- portaledTooltip.appendChild(arrow);
9301
- const buttonRect = clearChatButton.getBoundingClientRect();
9302
- portaledTooltip.style.position = "fixed";
9303
- portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9304
- portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9305
- portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9306
- portaledTooltip.style.transform = "translate(-50%, -100%)";
9307
- tooltipContainer.appendChild(portaledTooltip);
9308
- };
9309
- const hideTooltip = () => {
9310
- if (portaledTooltip && portaledTooltip.parentNode) {
9311
- portaledTooltip.parentNode.removeChild(portaledTooltip);
9312
- portaledTooltip = null;
9313
- }
9314
- };
9315
- clearChatButtonWrapper.addEventListener("mouseenter", showTooltip);
9316
- clearChatButtonWrapper.addEventListener("mouseleave", hideTooltip);
9317
- clearChatButton.addEventListener("focus", showTooltip);
9318
- clearChatButton.addEventListener("blur", hideTooltip);
9319
- clearChatButtonWrapper._cleanupTooltip = () => {
9320
- hideTooltip();
9321
- if (clearChatButtonWrapper) {
9322
- clearChatButtonWrapper.removeEventListener("mouseenter", showTooltip);
9323
- clearChatButtonWrapper.removeEventListener("mouseleave", hideTooltip);
9324
- }
9325
- if (clearChatButton) {
9326
- clearChatButton.removeEventListener("focus", showTooltip);
9327
- clearChatButton.removeEventListener("blur", hideTooltip);
9328
- }
9329
- };
9330
- }
9331
9733
  if (clearChatPlacement === "inline") {
9332
9734
  header.appendChild(clearChatButtonWrapper);
9333
9735
  }
9334
9736
  }
9335
- const closeButtonWrapper = createElement(
9336
- "div",
9337
- closeButtonPlacement === "top-right" ? "persona-absolute persona-top-4 persona-right-4 persona-z-50" : clearChatEnabled && clearChatPlacement === "inline" ? "persona-relative persona-inline-flex persona-items-center persona-justify-center" : "persona-relative persona-ml-auto persona-inline-flex persona-items-center persona-justify-center"
9338
- );
9339
- const closeButton = createElement(
9340
- "button",
9341
- "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-bg-gray-100 persona-cursor-pointer persona-border-none"
9737
+ 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";
9738
+ const { button: closeButton, wrapper: closeButtonWrapper } = createCloseButton(
9739
+ config,
9740
+ { showClose, wrapperClassName: closeButtonWrapperClass }
9342
9741
  );
9343
- closeButton.style.height = closeButtonSize;
9344
- closeButton.style.width = closeButtonSize;
9345
- closeButton.type = "button";
9346
- const closeButtonTooltipText = (_C = launcher.closeButtonTooltipText) != null ? _C : "Close chat";
9347
- const closeButtonShowTooltip = (_D = launcher.closeButtonShowTooltip) != null ? _D : true;
9348
- closeButton.setAttribute("aria-label", closeButtonTooltipText);
9349
- closeButton.style.display = showClose ? "" : "none";
9350
- const closeButtonIconName = (_E = launcher.closeButtonIconName) != null ? _E : "x";
9351
- const closeButtonIconText = (_F = launcher.closeButtonIconText) != null ? _F : "\xD7";
9352
- closeButton.style.color = launcher.closeButtonColor || HEADER_THEME_CSS.actionIconColor;
9353
- const closeIconSvg = renderLucideIcon(closeButtonIconName, "28px", "currentColor", 1);
9354
- if (closeIconSvg) {
9355
- closeIconSvg.style.display = "block";
9356
- closeButton.appendChild(closeIconSvg);
9357
- } else {
9358
- closeButton.textContent = closeButtonIconText;
9359
- }
9360
- if (launcher.closeButtonBackgroundColor) {
9361
- closeButton.style.backgroundColor = launcher.closeButtonBackgroundColor;
9362
- closeButton.classList.remove("hover:persona-bg-gray-100");
9363
- } else {
9364
- closeButton.style.backgroundColor = "";
9365
- closeButton.classList.add("hover:persona-bg-gray-100");
9366
- }
9367
- if (launcher.closeButtonBorderWidth || launcher.closeButtonBorderColor) {
9368
- const borderWidth = launcher.closeButtonBorderWidth || "0px";
9369
- const borderColor = launcher.closeButtonBorderColor || "transparent";
9370
- closeButton.style.border = `${borderWidth} solid ${borderColor}`;
9371
- closeButton.classList.remove("persona-border-none");
9372
- } else {
9373
- closeButton.style.border = "";
9374
- closeButton.classList.add("persona-border-none");
9375
- }
9376
- if (launcher.closeButtonBorderRadius) {
9377
- closeButton.style.borderRadius = launcher.closeButtonBorderRadius;
9378
- closeButton.classList.remove("persona-rounded-full");
9379
- } else {
9380
- closeButton.style.borderRadius = "";
9381
- closeButton.classList.add("persona-rounded-full");
9382
- }
9383
- if (launcher.closeButtonPaddingX) {
9384
- closeButton.style.paddingLeft = launcher.closeButtonPaddingX;
9385
- closeButton.style.paddingRight = launcher.closeButtonPaddingX;
9386
- } else {
9387
- closeButton.style.paddingLeft = "";
9388
- closeButton.style.paddingRight = "";
9389
- }
9390
- if (launcher.closeButtonPaddingY) {
9391
- closeButton.style.paddingTop = launcher.closeButtonPaddingY;
9392
- closeButton.style.paddingBottom = launcher.closeButtonPaddingY;
9393
- } else {
9394
- closeButton.style.paddingTop = "";
9395
- closeButton.style.paddingBottom = "";
9396
- }
9397
- closeButtonWrapper.appendChild(closeButton);
9398
- if (closeButtonShowTooltip && closeButtonTooltipText) {
9399
- let portaledTooltip = null;
9400
- const showTooltip = () => {
9401
- if (portaledTooltip) return;
9402
- const tooltipDocument = closeButton.ownerDocument;
9403
- const tooltipContainer = tooltipDocument.body;
9404
- if (!tooltipContainer) return;
9405
- portaledTooltip = createElementInDocument(
9406
- tooltipDocument,
9407
- "div",
9408
- "persona-clear-chat-tooltip"
9409
- );
9410
- portaledTooltip.textContent = closeButtonTooltipText;
9411
- const arrow = createElementInDocument(tooltipDocument, "div");
9412
- arrow.className = "persona-clear-chat-tooltip-arrow";
9413
- portaledTooltip.appendChild(arrow);
9414
- const buttonRect = closeButton.getBoundingClientRect();
9415
- portaledTooltip.style.position = "fixed";
9416
- portaledTooltip.style.zIndex = String(PORTALED_OVERLAY_Z_INDEX);
9417
- portaledTooltip.style.left = `${buttonRect.left + buttonRect.width / 2}px`;
9418
- portaledTooltip.style.top = `${buttonRect.top - 8}px`;
9419
- portaledTooltip.style.transform = "translate(-50%, -100%)";
9420
- tooltipContainer.appendChild(portaledTooltip);
9421
- };
9422
- const hideTooltip = () => {
9423
- if (portaledTooltip && portaledTooltip.parentNode) {
9424
- portaledTooltip.parentNode.removeChild(portaledTooltip);
9425
- portaledTooltip = null;
9426
- }
9427
- };
9428
- closeButtonWrapper.addEventListener("mouseenter", showTooltip);
9429
- closeButtonWrapper.addEventListener("mouseleave", hideTooltip);
9430
- closeButton.addEventListener("focus", showTooltip);
9431
- closeButton.addEventListener("blur", hideTooltip);
9432
- closeButtonWrapper._cleanupTooltip = () => {
9433
- hideTooltip();
9434
- closeButtonWrapper.removeEventListener("mouseenter", showTooltip);
9435
- closeButtonWrapper.removeEventListener("mouseleave", hideTooltip);
9436
- closeButton.removeEventListener("focus", showTooltip);
9437
- closeButton.removeEventListener("blur", hideTooltip);
9438
- };
9439
- }
9440
9742
  if (closeButtonPlacement !== "top-right") {
9441
9743
  header.appendChild(closeButtonWrapper);
9442
9744
  }
@@ -9973,25 +10275,9 @@ var buildHeaderWithLayout = (config, layoutConfig, context) => {
9973
10275
  return headerElements;
9974
10276
  };
9975
10277
 
9976
- // src/components/composer-builder.ts
9977
- var buildComposer = (context) => {
9978
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E;
9979
- const { config } = context;
9980
- const footer = createElement(
9981
- "div",
9982
- "persona-widget-footer persona-border-t-persona-divider persona-bg-persona-surface persona-px-6 persona-py-4"
9983
- );
9984
- footer.setAttribute("data-persona-theme-zone", "composer");
9985
- const suggestions = createElement(
9986
- "div",
9987
- "persona-mb-3 persona-flex persona-flex-wrap persona-gap-2"
9988
- );
9989
- const composerForm = createElement(
9990
- "form",
9991
- `persona-widget-composer persona-flex persona-flex-col persona-gap-2 persona-rounded-2xl persona-border persona-border-gray-200 persona-bg-persona-input-background persona-px-4 persona-py-3`
9992
- );
9993
- composerForm.setAttribute("data-persona-composer-form", "");
9994
- composerForm.style.outline = "none";
10278
+ // src/components/composer-parts.ts
10279
+ var createComposerTextarea = (config) => {
10280
+ var _a, _b;
9995
10281
  const textarea = createElement("textarea");
9996
10282
  textarea.setAttribute("data-persona-composer-input", "");
9997
10283
  textarea.placeholder = (_b = (_a = config == null ? void 0 : config.copy) == null ? void 0 : _a.inputPlaceholder) != null ? _b : "Type your message\u2026";
@@ -9999,17 +10285,21 @@ var buildComposer = (context) => {
9999
10285
  textarea.rows = 1;
10000
10286
  textarea.style.fontFamily = 'var(--persona-input-font-family, var(--persona-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif))';
10001
10287
  textarea.style.fontWeight = "var(--persona-input-font-weight, var(--persona-font-weight, 400))";
10002
- const maxLines = 3;
10288
+ const defaultMaxLines = 3;
10003
10289
  const lineHeight = 20;
10004
- const maxHeight = maxLines * lineHeight;
10005
- textarea.style.maxHeight = `${maxHeight}px`;
10290
+ textarea.style.maxHeight = `${defaultMaxLines * lineHeight}px`;
10006
10291
  textarea.style.overflowY = "auto";
10007
- const autoResize = () => {
10008
- textarea.style.height = "auto";
10009
- const newHeight = Math.min(textarea.scrollHeight, maxHeight);
10010
- textarea.style.height = `${newHeight}px`;
10292
+ const readMaxHeight = () => {
10293
+ const parsed = parseFloat(textarea.style.maxHeight);
10294
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultMaxLines * lineHeight;
10295
+ };
10296
+ const attachAutoResize = () => {
10297
+ textarea.addEventListener("input", () => {
10298
+ textarea.style.height = "auto";
10299
+ const newHeight = Math.min(textarea.scrollHeight, readMaxHeight());
10300
+ textarea.style.height = `${newHeight}px`;
10301
+ });
10011
10302
  };
10012
- textarea.addEventListener("input", autoResize);
10013
10303
  textarea.style.border = "none";
10014
10304
  textarea.style.outline = "none";
10015
10305
  textarea.style.borderWidth = "0";
@@ -10027,333 +10317,474 @@ var buildComposer = (context) => {
10027
10317
  textarea.style.border = "none";
10028
10318
  textarea.style.outline = "none";
10029
10319
  });
10030
- const sendButtonConfig = (_c = config == null ? void 0 : config.sendButton) != null ? _c : {};
10031
- const useIcon = (_d = sendButtonConfig.useIcon) != null ? _d : false;
10032
- const iconText = (_e = sendButtonConfig.iconText) != null ? _e : "\u2191";
10320
+ return { textarea, attachAutoResize };
10321
+ };
10322
+ var createSendButton = (config) => {
10323
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
10324
+ const sendButtonConfig = (_a = config == null ? void 0 : config.sendButton) != null ? _a : {};
10325
+ const useIcon = (_b = sendButtonConfig.useIcon) != null ? _b : false;
10326
+ const iconText = (_c = sendButtonConfig.iconText) != null ? _c : "\u2191";
10033
10327
  const iconName = sendButtonConfig.iconName;
10034
- const stopIconName = (_f = sendButtonConfig.stopIconName) != null ? _f : "square";
10035
- const tooltipText = (_g = sendButtonConfig.tooltipText) != null ? _g : "Send message";
10036
- const stopTooltipText = (_h = sendButtonConfig.stopTooltipText) != null ? _h : "Stop generating";
10037
- const sendLabel = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.sendButtonLabel) != null ? _j : "Send";
10038
- const stopLabel = (_l = (_k = config == null ? void 0 : config.copy) == null ? void 0 : _k.stopButtonLabel) != null ? _l : "Stop";
10039
- const showTooltip = (_m = sendButtonConfig.showTooltip) != null ? _m : false;
10040
- const buttonSize = (_n = sendButtonConfig.size) != null ? _n : "40px";
10328
+ const stopIconName = (_d = sendButtonConfig.stopIconName) != null ? _d : "square";
10329
+ const tooltipText = (_e = sendButtonConfig.tooltipText) != null ? _e : "Send message";
10330
+ const stopTooltipText = (_f = sendButtonConfig.stopTooltipText) != null ? _f : "Stop generating";
10331
+ const sendLabel = (_h = (_g = config == null ? void 0 : config.copy) == null ? void 0 : _g.sendButtonLabel) != null ? _h : "Send";
10332
+ const stopLabel = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.stopButtonLabel) != null ? _j : "Stop";
10333
+ const showTooltip = (_k = sendButtonConfig.showTooltip) != null ? _k : false;
10334
+ const buttonSize = (_l = sendButtonConfig.size) != null ? _l : "40px";
10041
10335
  const backgroundColor = sendButtonConfig.backgroundColor;
10042
10336
  const textColor = sendButtonConfig.textColor;
10043
- const sendButtonWrapper = createElement("div", "persona-send-button-wrapper");
10044
- const sendButton = createElement(
10337
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10338
+ const button = createElement(
10045
10339
  "button",
10046
10340
  useIcon ? "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer" : "persona-rounded-button persona-bg-persona-accent persona-px-4 persona-py-2 persona-text-sm persona-font-semibold disabled:persona-opacity-50 persona-cursor-pointer"
10047
10341
  );
10048
- sendButton.type = "submit";
10049
- sendButton.setAttribute("data-persona-composer-submit", "");
10342
+ button.type = "submit";
10343
+ button.setAttribute("data-persona-composer-submit", "");
10050
10344
  let sendIcon = null;
10051
10345
  let stopIcon = null;
10052
10346
  if (useIcon) {
10053
- sendButton.style.width = buttonSize;
10054
- sendButton.style.height = buttonSize;
10055
- sendButton.style.minWidth = buttonSize;
10056
- sendButton.style.minHeight = buttonSize;
10057
- sendButton.style.fontSize = "18px";
10058
- sendButton.style.lineHeight = "1";
10059
- sendButton.innerHTML = "";
10347
+ button.style.width = buttonSize;
10348
+ button.style.height = buttonSize;
10349
+ button.style.minWidth = buttonSize;
10350
+ button.style.minHeight = buttonSize;
10351
+ button.style.fontSize = "18px";
10352
+ button.style.lineHeight = "1";
10353
+ button.innerHTML = "";
10060
10354
  if (textColor) {
10061
- sendButton.style.color = textColor;
10355
+ button.style.color = textColor;
10062
10356
  } else {
10063
- sendButton.style.color = "var(--persona-button-primary-fg, #ffffff)";
10357
+ button.style.color = "var(--persona-button-primary-fg, #ffffff)";
10064
10358
  }
10065
10359
  const iconSize = parseFloat(buttonSize) || 24;
10066
10360
  const iconColor = (textColor == null ? void 0 : textColor.trim()) || "currentColor";
10067
10361
  if (iconName) {
10068
10362
  sendIcon = renderLucideIcon(iconName, iconSize, iconColor, 2);
10069
10363
  if (sendIcon) {
10070
- sendButton.appendChild(sendIcon);
10364
+ button.appendChild(sendIcon);
10071
10365
  } else {
10072
- sendButton.textContent = iconText;
10366
+ button.textContent = iconText;
10073
10367
  }
10074
10368
  } else {
10075
- sendButton.textContent = iconText;
10369
+ button.textContent = iconText;
10076
10370
  }
10077
10371
  stopIcon = renderLucideIcon(stopIconName, iconSize, iconColor, 2);
10078
10372
  if (backgroundColor) {
10079
- sendButton.style.backgroundColor = backgroundColor;
10373
+ button.style.backgroundColor = backgroundColor;
10080
10374
  } else {
10081
- sendButton.classList.add("persona-bg-persona-primary");
10375
+ button.classList.add("persona-bg-persona-primary");
10082
10376
  }
10083
10377
  } else {
10084
- sendButton.textContent = sendLabel;
10378
+ button.textContent = sendLabel;
10085
10379
  if (textColor) {
10086
- sendButton.style.color = textColor;
10380
+ button.style.color = textColor;
10087
10381
  } else {
10088
- sendButton.classList.add("persona-text-white");
10382
+ button.classList.add("persona-text-white");
10089
10383
  }
10090
10384
  }
10091
10385
  if (sendButtonConfig.borderWidth) {
10092
- sendButton.style.borderWidth = sendButtonConfig.borderWidth;
10093
- sendButton.style.borderStyle = "solid";
10386
+ button.style.borderWidth = sendButtonConfig.borderWidth;
10387
+ button.style.borderStyle = "solid";
10094
10388
  }
10095
10389
  if (sendButtonConfig.borderColor) {
10096
- sendButton.style.borderColor = sendButtonConfig.borderColor;
10390
+ button.style.borderColor = sendButtonConfig.borderColor;
10097
10391
  }
10098
10392
  if (sendButtonConfig.paddingX) {
10099
- sendButton.style.paddingLeft = sendButtonConfig.paddingX;
10100
- sendButton.style.paddingRight = sendButtonConfig.paddingX;
10393
+ button.style.paddingLeft = sendButtonConfig.paddingX;
10394
+ button.style.paddingRight = sendButtonConfig.paddingX;
10101
10395
  } else {
10102
- sendButton.style.paddingLeft = "";
10103
- sendButton.style.paddingRight = "";
10396
+ button.style.paddingLeft = "";
10397
+ button.style.paddingRight = "";
10104
10398
  }
10105
10399
  if (sendButtonConfig.paddingY) {
10106
- sendButton.style.paddingTop = sendButtonConfig.paddingY;
10107
- sendButton.style.paddingBottom = sendButtonConfig.paddingY;
10400
+ button.style.paddingTop = sendButtonConfig.paddingY;
10401
+ button.style.paddingBottom = sendButtonConfig.paddingY;
10108
10402
  } else {
10109
- sendButton.style.paddingTop = "";
10110
- sendButton.style.paddingBottom = "";
10403
+ button.style.paddingTop = "";
10404
+ button.style.paddingBottom = "";
10111
10405
  }
10112
- let sendTooltip = null;
10406
+ let tooltip = null;
10113
10407
  if (showTooltip && tooltipText) {
10114
- sendTooltip = createElement("div", "persona-send-button-tooltip");
10115
- sendTooltip.textContent = tooltipText;
10116
- sendButtonWrapper.appendChild(sendTooltip);
10408
+ tooltip = createElement("div", "persona-send-button-tooltip");
10409
+ tooltip.textContent = tooltipText;
10410
+ wrapper.appendChild(tooltip);
10117
10411
  }
10118
- sendButton.setAttribute("aria-label", tooltipText);
10119
- sendButtonWrapper.appendChild(sendButton);
10412
+ button.setAttribute("aria-label", tooltipText);
10413
+ wrapper.appendChild(button);
10120
10414
  let currentMode = "send";
10121
- const setSendButtonMode = (mode) => {
10415
+ const setMode = (mode) => {
10122
10416
  if (mode === currentMode) return;
10123
10417
  currentMode = mode;
10124
10418
  const label = mode === "stop" ? stopTooltipText : tooltipText;
10125
- sendButton.setAttribute("aria-label", label);
10126
- if (sendTooltip) {
10127
- sendTooltip.textContent = label;
10419
+ button.setAttribute("aria-label", label);
10420
+ if (tooltip) {
10421
+ tooltip.textContent = label;
10128
10422
  }
10129
10423
  if (useIcon) {
10130
10424
  if (sendIcon && stopIcon) {
10131
10425
  const next = mode === "stop" ? stopIcon : sendIcon;
10132
10426
  const prev = mode === "stop" ? sendIcon : stopIcon;
10133
- if (prev.parentNode === sendButton) {
10134
- sendButton.replaceChild(next, prev);
10427
+ if (prev.parentNode === button) {
10428
+ button.replaceChild(next, prev);
10135
10429
  } else {
10136
- sendButton.appendChild(next);
10430
+ button.appendChild(next);
10137
10431
  }
10138
10432
  }
10139
10433
  } else {
10140
- sendButton.textContent = mode === "stop" ? stopLabel : sendLabel;
10434
+ button.textContent = mode === "stop" ? stopLabel : sendLabel;
10141
10435
  }
10142
10436
  };
10143
- const voiceRecognitionConfig = (_o = config == null ? void 0 : config.voiceRecognition) != null ? _o : {};
10437
+ return { button, wrapper, setMode };
10438
+ };
10439
+ var createMicButton = (config) => {
10440
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
10441
+ const voiceRecognitionConfig = (_a = config == null ? void 0 : config.voiceRecognition) != null ? _a : {};
10144
10442
  const voiceRecognitionEnabled = voiceRecognitionConfig.enabled === true;
10145
- let micButton = null;
10146
- let micButtonWrapper = null;
10443
+ if (!voiceRecognitionEnabled) return null;
10147
10444
  const hasSpeechRecognition = typeof window !== "undefined" && (typeof window.webkitSpeechRecognition !== "undefined" || typeof window.SpeechRecognition !== "undefined");
10148
- const hasRuntypeProvider = ((_p = voiceRecognitionConfig.provider) == null ? void 0 : _p.type) === "runtype";
10445
+ const hasRuntypeProvider = ((_b = voiceRecognitionConfig.provider) == null ? void 0 : _b.type) === "runtype";
10149
10446
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
10150
- if (voiceRecognitionEnabled && hasVoiceInput) {
10151
- micButtonWrapper = createElement("div", "persona-send-button-wrapper");
10152
- micButton = createElement(
10153
- "button",
10154
- "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer"
10155
- );
10156
- micButton.type = "button";
10157
- micButton.setAttribute("data-persona-composer-mic", "");
10158
- micButton.setAttribute("aria-label", "Start voice recognition");
10159
- const micIconName = (_q = voiceRecognitionConfig.iconName) != null ? _q : "mic";
10160
- const micIconSize = (_r = voiceRecognitionConfig.iconSize) != null ? _r : buttonSize;
10161
- const micIconSizeNum = parseFloat(micIconSize) || 24;
10162
- const micBackgroundColor = (_s = voiceRecognitionConfig.backgroundColor) != null ? _s : backgroundColor;
10163
- const micIconColor = (_t = voiceRecognitionConfig.iconColor) != null ? _t : textColor;
10164
- micButton.style.width = micIconSize;
10165
- micButton.style.height = micIconSize;
10166
- micButton.style.minWidth = micIconSize;
10167
- micButton.style.minHeight = micIconSize;
10168
- micButton.style.fontSize = "18px";
10169
- micButton.style.lineHeight = "1";
10170
- if (micIconColor) {
10171
- micButton.style.color = micIconColor;
10172
- } else {
10173
- micButton.style.color = "var(--persona-text, #111827)";
10174
- }
10175
- const iconColorValue = micIconColor || "currentColor";
10176
- const micIconSvg = renderLucideIcon(
10177
- micIconName,
10178
- micIconSizeNum,
10179
- iconColorValue,
10180
- 1.5
10181
- );
10182
- if (micIconSvg) {
10183
- micButton.appendChild(micIconSvg);
10184
- } else {
10185
- micButton.textContent = "\u{1F3A4}";
10186
- }
10187
- if (micBackgroundColor) {
10188
- micButton.style.backgroundColor = micBackgroundColor;
10189
- }
10190
- if (voiceRecognitionConfig.borderWidth) {
10191
- micButton.style.borderWidth = voiceRecognitionConfig.borderWidth;
10192
- micButton.style.borderStyle = "solid";
10193
- }
10194
- if (voiceRecognitionConfig.borderColor) {
10195
- micButton.style.borderColor = voiceRecognitionConfig.borderColor;
10196
- }
10197
- if (voiceRecognitionConfig.paddingX) {
10198
- micButton.style.paddingLeft = voiceRecognitionConfig.paddingX;
10199
- micButton.style.paddingRight = voiceRecognitionConfig.paddingX;
10200
- }
10201
- if (voiceRecognitionConfig.paddingY) {
10202
- micButton.style.paddingTop = voiceRecognitionConfig.paddingY;
10203
- micButton.style.paddingBottom = voiceRecognitionConfig.paddingY;
10204
- }
10205
- micButtonWrapper.appendChild(micButton);
10206
- const micTooltipText = (_u = voiceRecognitionConfig.tooltipText) != null ? _u : "Start voice recognition";
10207
- const showMicTooltip = (_v = voiceRecognitionConfig.showTooltip) != null ? _v : false;
10208
- if (showMicTooltip && micTooltipText) {
10209
- const tooltip = createElement("div", "persona-send-button-tooltip");
10210
- tooltip.textContent = micTooltipText;
10211
- micButtonWrapper.appendChild(tooltip);
10212
- }
10213
- }
10214
- const attachmentsConfig = (_w = config == null ? void 0 : config.attachments) != null ? _w : {};
10215
- const attachmentsEnabled = attachmentsConfig.enabled === true;
10216
- let attachmentButton = null;
10217
- let attachmentButtonWrapper = null;
10218
- let attachmentInput = null;
10219
- let attachmentPreviewsContainer = null;
10220
- if (attachmentsEnabled) {
10221
- attachmentPreviewsContainer = createElement(
10222
- "div",
10223
- "persona-attachment-previews persona-flex persona-flex-wrap persona-gap-2 persona-mb-2"
10224
- );
10225
- attachmentPreviewsContainer.style.display = "none";
10226
- attachmentInput = createElement("input");
10227
- attachmentInput.type = "file";
10228
- attachmentInput.accept = ((_x = attachmentsConfig.allowedTypes) != null ? _x : ALL_SUPPORTED_MIME_TYPES).join(",");
10229
- attachmentInput.multiple = ((_y = attachmentsConfig.maxFiles) != null ? _y : 4) > 1;
10230
- attachmentInput.style.display = "none";
10231
- attachmentInput.setAttribute("aria-label", "Attach files");
10232
- attachmentButtonWrapper = createElement("div", "persona-send-button-wrapper");
10233
- attachmentButton = createElement(
10234
- "button",
10235
- "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
10236
- );
10237
- attachmentButton.type = "button";
10238
- attachmentButton.setAttribute("aria-label", (_z = attachmentsConfig.buttonTooltipText) != null ? _z : "Attach file");
10239
- const attachIconName = (_A = attachmentsConfig.buttonIconName) != null ? _A : "paperclip";
10240
- const attachIconSize = buttonSize;
10241
- const buttonSizeNum = parseFloat(attachIconSize) || 40;
10242
- const attachIconSizeNum = Math.round(buttonSizeNum * 0.6);
10243
- attachmentButton.style.width = attachIconSize;
10244
- attachmentButton.style.height = attachIconSize;
10245
- attachmentButton.style.minWidth = attachIconSize;
10246
- attachmentButton.style.minHeight = attachIconSize;
10247
- attachmentButton.style.fontSize = "18px";
10248
- attachmentButton.style.lineHeight = "1";
10249
- attachmentButton.style.backgroundColor = "transparent";
10250
- attachmentButton.style.color = "var(--persona-primary, #111827)";
10251
- attachmentButton.style.border = "none";
10252
- attachmentButton.style.borderRadius = "6px";
10253
- attachmentButton.style.transition = "background-color 0.15s ease";
10254
- attachmentButton.addEventListener("mouseenter", () => {
10255
- attachmentButton.style.backgroundColor = "var(--persona-palette-colors-black-alpha-50, rgba(0, 0, 0, 0.05))";
10256
- });
10257
- attachmentButton.addEventListener("mouseleave", () => {
10258
- attachmentButton.style.backgroundColor = "transparent";
10259
- });
10260
- const attachIconSvg = renderLucideIcon(
10261
- attachIconName,
10262
- attachIconSizeNum,
10263
- "currentColor",
10264
- 1.5
10265
- );
10266
- if (attachIconSvg) {
10267
- attachmentButton.appendChild(attachIconSvg);
10268
- } else {
10269
- attachmentButton.textContent = "\u{1F4CE}";
10270
- }
10271
- attachmentButton.addEventListener("click", (e) => {
10272
- e.preventDefault();
10273
- attachmentInput == null ? void 0 : attachmentInput.click();
10274
- });
10275
- attachmentButtonWrapper.appendChild(attachmentButton);
10276
- const attachTooltipText = (_B = attachmentsConfig.buttonTooltipText) != null ? _B : "Attach file";
10447
+ if (!hasVoiceInput) return null;
10448
+ const buttonSize = (_d = (_c = config == null ? void 0 : config.sendButton) == null ? void 0 : _c.size) != null ? _d : "40px";
10449
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10450
+ const button = createElement(
10451
+ "button",
10452
+ "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer"
10453
+ );
10454
+ button.type = "button";
10455
+ button.setAttribute("data-persona-composer-mic", "");
10456
+ button.setAttribute("aria-label", "Start voice recognition");
10457
+ const micIconName = (_e = voiceRecognitionConfig.iconName) != null ? _e : "mic";
10458
+ const micIconSize = (_f = voiceRecognitionConfig.iconSize) != null ? _f : buttonSize;
10459
+ const micIconSizeNum = parseFloat(micIconSize) || 24;
10460
+ const micBackgroundColor = (_h = voiceRecognitionConfig.backgroundColor) != null ? _h : (_g = config == null ? void 0 : config.sendButton) == null ? void 0 : _g.backgroundColor;
10461
+ const micIconColor = (_j = voiceRecognitionConfig.iconColor) != null ? _j : (_i = config == null ? void 0 : config.sendButton) == null ? void 0 : _i.textColor;
10462
+ button.style.width = micIconSize;
10463
+ button.style.height = micIconSize;
10464
+ button.style.minWidth = micIconSize;
10465
+ button.style.minHeight = micIconSize;
10466
+ button.style.fontSize = "18px";
10467
+ button.style.lineHeight = "1";
10468
+ if (micIconColor) {
10469
+ button.style.color = micIconColor;
10470
+ } else {
10471
+ button.style.color = "var(--persona-text, #111827)";
10472
+ }
10473
+ const iconColorValue = micIconColor || "currentColor";
10474
+ const micIconSvg = renderLucideIcon(micIconName, micIconSizeNum, iconColorValue, 1.5);
10475
+ if (micIconSvg) {
10476
+ button.appendChild(micIconSvg);
10477
+ } else {
10478
+ button.textContent = "\u{1F3A4}";
10479
+ }
10480
+ if (micBackgroundColor) {
10481
+ button.style.backgroundColor = micBackgroundColor;
10482
+ }
10483
+ if (voiceRecognitionConfig.borderWidth) {
10484
+ button.style.borderWidth = voiceRecognitionConfig.borderWidth;
10485
+ button.style.borderStyle = "solid";
10486
+ }
10487
+ if (voiceRecognitionConfig.borderColor) {
10488
+ button.style.borderColor = voiceRecognitionConfig.borderColor;
10489
+ }
10490
+ if (voiceRecognitionConfig.paddingX) {
10491
+ button.style.paddingLeft = voiceRecognitionConfig.paddingX;
10492
+ button.style.paddingRight = voiceRecognitionConfig.paddingX;
10493
+ }
10494
+ if (voiceRecognitionConfig.paddingY) {
10495
+ button.style.paddingTop = voiceRecognitionConfig.paddingY;
10496
+ button.style.paddingBottom = voiceRecognitionConfig.paddingY;
10497
+ }
10498
+ wrapper.appendChild(button);
10499
+ const micTooltipText = (_k = voiceRecognitionConfig.tooltipText) != null ? _k : "Start voice recognition";
10500
+ const showMicTooltip = (_l = voiceRecognitionConfig.showTooltip) != null ? _l : false;
10501
+ if (showMicTooltip && micTooltipText) {
10277
10502
  const tooltip = createElement("div", "persona-send-button-tooltip");
10278
- tooltip.textContent = attachTooltipText;
10279
- attachmentButtonWrapper.appendChild(tooltip);
10503
+ tooltip.textContent = micTooltipText;
10504
+ wrapper.appendChild(tooltip);
10280
10505
  }
10281
- composerForm.addEventListener("click", (e) => {
10282
- if (e.target !== sendButton && e.target !== sendButtonWrapper && e.target !== micButton && e.target !== micButtonWrapper && e.target !== attachmentButton && e.target !== attachmentButtonWrapper) {
10283
- textarea.focus();
10284
- }
10506
+ return { button, wrapper };
10507
+ };
10508
+ var createAttachmentControls = (config) => {
10509
+ var _a, _b, _c, _d, _e, _f, _g, _h;
10510
+ const attachmentsConfig = (_a = config == null ? void 0 : config.attachments) != null ? _a : {};
10511
+ if (attachmentsConfig.enabled !== true) return null;
10512
+ const buttonSize = (_c = (_b = config == null ? void 0 : config.sendButton) == null ? void 0 : _b.size) != null ? _c : "40px";
10513
+ const previewsContainer = createElement(
10514
+ "div",
10515
+ "persona-attachment-previews persona-flex persona-flex-wrap persona-gap-2 persona-mb-2"
10516
+ );
10517
+ previewsContainer.style.display = "none";
10518
+ const input = createElement("input");
10519
+ input.type = "file";
10520
+ input.accept = ((_d = attachmentsConfig.allowedTypes) != null ? _d : ALL_SUPPORTED_MIME_TYPES).join(",");
10521
+ input.multiple = ((_e = attachmentsConfig.maxFiles) != null ? _e : 4) > 1;
10522
+ input.style.display = "none";
10523
+ input.setAttribute("aria-label", "Attach files");
10524
+ const wrapper = createElement("div", "persona-send-button-wrapper");
10525
+ const button = createElement(
10526
+ "button",
10527
+ "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
10528
+ );
10529
+ button.type = "button";
10530
+ button.setAttribute("aria-label", (_f = attachmentsConfig.buttonTooltipText) != null ? _f : "Attach file");
10531
+ const attachIconName = (_g = attachmentsConfig.buttonIconName) != null ? _g : "paperclip";
10532
+ const attachIconSize = buttonSize;
10533
+ const buttonSizeNum = parseFloat(attachIconSize) || 40;
10534
+ const attachIconSizeNum = Math.round(buttonSizeNum * 0.6);
10535
+ button.style.width = attachIconSize;
10536
+ button.style.height = attachIconSize;
10537
+ button.style.minWidth = attachIconSize;
10538
+ button.style.minHeight = attachIconSize;
10539
+ button.style.fontSize = "18px";
10540
+ button.style.lineHeight = "1";
10541
+ button.style.backgroundColor = "transparent";
10542
+ button.style.color = "var(--persona-primary, #111827)";
10543
+ button.style.border = "none";
10544
+ button.style.borderRadius = "6px";
10545
+ button.style.transition = "background-color 0.15s ease";
10546
+ button.addEventListener("mouseenter", () => {
10547
+ button.style.backgroundColor = "var(--persona-palette-colors-black-alpha-50, rgba(0, 0, 0, 0.05))";
10285
10548
  });
10286
- if (attachmentPreviewsContainer) {
10287
- attachmentPreviewsContainer.style.gap = "8px";
10288
- composerForm.append(attachmentPreviewsContainer);
10289
- }
10290
- if (attachmentInput) {
10291
- composerForm.append(attachmentInput);
10549
+ button.addEventListener("mouseleave", () => {
10550
+ button.style.backgroundColor = "transparent";
10551
+ });
10552
+ const attachIconSvg = renderLucideIcon(attachIconName, attachIconSizeNum, "currentColor", 1.5);
10553
+ if (attachIconSvg) {
10554
+ button.appendChild(attachIconSvg);
10555
+ } else {
10556
+ button.textContent = "\u{1F4CE}";
10292
10557
  }
10293
- composerForm.append(textarea);
10294
- const actionsRow = createElement("div", "persona-flex persona-items-center persona-justify-between persona-w-full");
10295
- const leftActions = createElement("div", "persona-flex persona-items-center persona-gap-2");
10296
- if (attachmentButtonWrapper) {
10297
- leftActions.append(attachmentButtonWrapper);
10558
+ button.addEventListener("click", (e) => {
10559
+ e.preventDefault();
10560
+ input.click();
10561
+ });
10562
+ wrapper.appendChild(button);
10563
+ const attachTooltipText = (_h = attachmentsConfig.buttonTooltipText) != null ? _h : "Attach file";
10564
+ const tooltip = createElement("div", "persona-send-button-tooltip");
10565
+ tooltip.textContent = attachTooltipText;
10566
+ wrapper.appendChild(tooltip);
10567
+ return { button, wrapper, input, previewsContainer };
10568
+ };
10569
+ var createStatusText = (config) => {
10570
+ var _a, _b, _c;
10571
+ const statusConfig = (_a = config == null ? void 0 : config.statusIndicator) != null ? _a : {};
10572
+ const alignClass = statusConfig.align === "left" ? "persona-text-left" : statusConfig.align === "center" ? "persona-text-center" : "persona-text-right";
10573
+ const statusText = createElement(
10574
+ "div",
10575
+ `persona-mt-2 ${alignClass} persona-text-xs persona-text-persona-muted`
10576
+ );
10577
+ statusText.setAttribute("data-persona-composer-status", "");
10578
+ const isVisible = (_b = statusConfig.visible) != null ? _b : true;
10579
+ statusText.style.display = isVisible ? "" : "none";
10580
+ const idleLabel = (_c = statusConfig.idleText) != null ? _c : "Online";
10581
+ if (statusConfig.idleLink) {
10582
+ const link = createElement("a");
10583
+ link.href = statusConfig.idleLink;
10584
+ link.target = "_blank";
10585
+ link.rel = "noopener noreferrer";
10586
+ link.textContent = idleLabel;
10587
+ link.style.color = "inherit";
10588
+ link.style.textDecoration = "none";
10589
+ statusText.appendChild(link);
10590
+ } else {
10591
+ statusText.textContent = idleLabel;
10298
10592
  }
10299
- const rightActions = createElement("div", "persona-flex persona-items-center persona-gap-1");
10300
- if (micButtonWrapper) {
10301
- rightActions.append(micButtonWrapper);
10593
+ return statusText;
10594
+ };
10595
+ var createSuggestionsRow = () => createElement("div", "persona-mb-3 persona-flex persona-flex-wrap persona-gap-2");
10596
+
10597
+ // src/components/composer-builder.ts
10598
+ var buildComposer = (context) => {
10599
+ var _a, _b, _c, _d, _e, _f;
10600
+ const { config } = context;
10601
+ const footer = createElement(
10602
+ "div",
10603
+ "persona-widget-footer persona-border-t-persona-divider persona-bg-persona-surface persona-px-6 persona-py-4"
10604
+ );
10605
+ footer.setAttribute("data-persona-theme-zone", "composer");
10606
+ const suggestions = createSuggestionsRow();
10607
+ const composerForm = createElement(
10608
+ "form",
10609
+ "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"
10610
+ );
10611
+ composerForm.setAttribute("data-persona-composer-form", "");
10612
+ composerForm.style.outline = "none";
10613
+ const { textarea, attachAutoResize } = createComposerTextarea(config);
10614
+ attachAutoResize();
10615
+ const send = createSendButton(config);
10616
+ const mic = createMicButton(config);
10617
+ const attachment = createAttachmentControls(config);
10618
+ const statusText = createStatusText(config);
10619
+ if (attachment) {
10620
+ attachment.previewsContainer.style.gap = "8px";
10621
+ composerForm.append(attachment.previewsContainer, attachment.input);
10302
10622
  }
10303
- rightActions.append(sendButtonWrapper);
10623
+ composerForm.append(textarea);
10624
+ const actionsRow = createElement(
10625
+ "div",
10626
+ "persona-widget-composer__actions persona-flex persona-items-center persona-justify-between persona-w-full"
10627
+ );
10628
+ const leftActions = createElement(
10629
+ "div",
10630
+ "persona-widget-composer__left-actions persona-flex persona-items-center persona-gap-2"
10631
+ );
10632
+ const rightActions = createElement(
10633
+ "div",
10634
+ "persona-widget-composer__right-actions persona-flex persona-items-center persona-gap-1"
10635
+ );
10636
+ if (attachment) leftActions.append(attachment.wrapper);
10637
+ if (mic) rightActions.append(mic.wrapper);
10638
+ rightActions.append(send.wrapper);
10304
10639
  actionsRow.append(leftActions, rightActions);
10305
10640
  composerForm.append(actionsRow);
10306
- const statusConfig = (_C = config == null ? void 0 : config.statusIndicator) != null ? _C : {};
10307
- const alignClass = statusConfig.align === "left" ? "persona-text-left" : statusConfig.align === "center" ? "persona-text-center" : "persona-text-right";
10308
- const statusText = createElement(
10641
+ composerForm.addEventListener("click", (e) => {
10642
+ 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)) {
10643
+ textarea.focus();
10644
+ }
10645
+ });
10646
+ footer.append(suggestions, composerForm, statusText);
10647
+ return {
10648
+ footer,
10649
+ suggestions,
10650
+ composerForm,
10651
+ textarea,
10652
+ sendButton: send.button,
10653
+ sendButtonWrapper: send.wrapper,
10654
+ micButton: (_a = mic == null ? void 0 : mic.button) != null ? _a : null,
10655
+ micButtonWrapper: (_b = mic == null ? void 0 : mic.wrapper) != null ? _b : null,
10656
+ statusText,
10657
+ attachmentButton: (_c = attachment == null ? void 0 : attachment.button) != null ? _c : null,
10658
+ attachmentButtonWrapper: (_d = attachment == null ? void 0 : attachment.wrapper) != null ? _d : null,
10659
+ attachmentInput: (_e = attachment == null ? void 0 : attachment.input) != null ? _e : null,
10660
+ attachmentPreviewsContainer: (_f = attachment == null ? void 0 : attachment.previewsContainer) != null ? _f : null,
10661
+ actionsRow,
10662
+ leftActions,
10663
+ rightActions,
10664
+ setSendButtonMode: send.setMode
10665
+ };
10666
+ };
10667
+
10668
+ // src/components/pill-composer-builder.ts
10669
+ var buildPillPeekBanner = () => {
10670
+ const root = createElement("button", "persona-pill-peek");
10671
+ root.type = "button";
10672
+ root.setAttribute("data-persona-pill-peek", "");
10673
+ root.setAttribute("aria-label", "Show conversation");
10674
+ root.setAttribute("tabindex", "-1");
10675
+ const iconHolder = createElement("span", "persona-pill-peek__icon");
10676
+ const messageIcon = renderLucideIcon("message-square", 16, "currentColor", 1.5);
10677
+ if (messageIcon) {
10678
+ iconHolder.appendChild(messageIcon);
10679
+ }
10680
+ const textNode = createElement("span", "persona-pill-peek__text");
10681
+ const caret = createElement("span", "persona-pill-peek__caret");
10682
+ const caretIcon = renderLucideIcon("chevron-up", 16, "currentColor", 1.5);
10683
+ if (caretIcon) {
10684
+ caret.appendChild(caretIcon);
10685
+ }
10686
+ root.append(iconHolder, textNode, caret);
10687
+ return { root, textNode };
10688
+ };
10689
+ var buildPillComposer = (context) => {
10690
+ var _a, _b, _c, _d, _e, _f;
10691
+ const { config } = context;
10692
+ const footer = createElement("div", "persona-widget-footer persona-widget-footer--pill");
10693
+ footer.setAttribute("data-persona-theme-zone", "composer");
10694
+ const suggestions = createSuggestionsRow();
10695
+ suggestions.style.display = "none";
10696
+ const statusText = createStatusText(config);
10697
+ statusText.style.display = "none";
10698
+ const { textarea, attachAutoResize } = createComposerTextarea(config);
10699
+ textarea.style.maxHeight = "100px";
10700
+ attachAutoResize();
10701
+ const send = createSendButton(config);
10702
+ const mic = createMicButton(config);
10703
+ const attachment = createAttachmentControls(config);
10704
+ if (attachment) {
10705
+ attachment.previewsContainer.classList.add("persona-pill-composer__previews");
10706
+ }
10707
+ const composerForm = createElement(
10708
+ "form",
10709
+ "persona-widget-composer persona-pill-composer"
10710
+ );
10711
+ composerForm.setAttribute("data-persona-composer-form", "");
10712
+ composerForm.style.outline = "none";
10713
+ const leftActions = createElement(
10309
10714
  "div",
10310
- `persona-mt-2 ${alignClass} persona-text-xs persona-text-persona-muted`
10715
+ "persona-widget-composer__left-actions persona-pill-composer__left"
10311
10716
  );
10312
- statusText.setAttribute("data-persona-composer-status", "");
10313
- const isVisible = (_D = statusConfig.visible) != null ? _D : true;
10314
- statusText.style.display = isVisible ? "" : "none";
10315
- const idleLabel = (_E = statusConfig.idleText) != null ? _E : "Online";
10316
- if (statusConfig.idleLink) {
10317
- const link = createElement("a");
10318
- link.href = statusConfig.idleLink;
10319
- link.target = "_blank";
10320
- link.rel = "noopener noreferrer";
10321
- link.textContent = idleLabel;
10322
- link.style.color = "inherit";
10323
- link.style.textDecoration = "none";
10324
- statusText.appendChild(link);
10325
- } else {
10326
- statusText.textContent = idleLabel;
10327
- }
10328
- footer.append(suggestions, composerForm, statusText);
10717
+ if (attachment) leftActions.append(attachment.wrapper);
10718
+ const rightActions = createElement(
10719
+ "div",
10720
+ "persona-widget-composer__right-actions persona-pill-composer__right"
10721
+ );
10722
+ if (mic) rightActions.append(mic.wrapper);
10723
+ rightActions.append(send.wrapper);
10724
+ composerForm.addEventListener("click", (e) => {
10725
+ 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)) {
10726
+ textarea.focus();
10727
+ }
10728
+ });
10729
+ if (attachment) composerForm.append(attachment.input);
10730
+ composerForm.append(leftActions, textarea, rightActions);
10731
+ if (attachment) footer.append(attachment.previewsContainer);
10732
+ footer.append(composerForm, suggestions, statusText);
10733
+ const actionsRow = composerForm;
10329
10734
  return {
10330
10735
  footer,
10331
10736
  suggestions,
10332
10737
  composerForm,
10333
10738
  textarea,
10334
- sendButton,
10335
- sendButtonWrapper,
10336
- micButton,
10337
- micButtonWrapper,
10739
+ sendButton: send.button,
10740
+ sendButtonWrapper: send.wrapper,
10741
+ micButton: (_a = mic == null ? void 0 : mic.button) != null ? _a : null,
10742
+ micButtonWrapper: (_b = mic == null ? void 0 : mic.wrapper) != null ? _b : null,
10338
10743
  statusText,
10339
- // Attachment elements
10340
- attachmentButton,
10341
- attachmentButtonWrapper,
10342
- attachmentInput,
10343
- attachmentPreviewsContainer,
10344
- // Actions row layout elements
10744
+ attachmentButton: (_c = attachment == null ? void 0 : attachment.button) != null ? _c : null,
10745
+ attachmentButtonWrapper: (_d = attachment == null ? void 0 : attachment.wrapper) != null ? _d : null,
10746
+ attachmentInput: (_e = attachment == null ? void 0 : attachment.input) != null ? _e : null,
10747
+ attachmentPreviewsContainer: (_f = attachment == null ? void 0 : attachment.previewsContainer) != null ? _f : null,
10345
10748
  actionsRow,
10346
10749
  leftActions,
10347
10750
  rightActions,
10348
- setSendButtonMode
10751
+ setSendButtonMode: send.setMode
10349
10752
  };
10350
10753
  };
10351
10754
 
10352
10755
  // src/components/panel.ts
10353
10756
  var createWrapper = (config) => {
10354
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10757
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
10355
10758
  const launcherEnabled = (_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.enabled) != null ? _b : true;
10356
10759
  const dockedMode = isDockedMountMode(config);
10760
+ const composerBarMode = isComposerBarMountMode(config);
10761
+ if (composerBarMode) {
10762
+ const cb = (_d = (_c = config == null ? void 0 : config.launcher) == null ? void 0 : _c.composerBar) != null ? _d : {};
10763
+ const wrapper2 = createElement(
10764
+ "div",
10765
+ "persona-widget-wrapper persona-fixed persona-transition"
10766
+ );
10767
+ wrapper2.setAttribute("data-persona-composer-bar", "");
10768
+ wrapper2.dataset.state = "collapsed";
10769
+ wrapper2.dataset.expandedSize = (_e = cb.expandedSize) != null ? _e : "anchored";
10770
+ wrapper2.style.zIndex = String(
10771
+ (_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.zIndex) != null ? _g : DEFAULT_OVERLAY_Z_INDEX
10772
+ );
10773
+ const panel2 = createElement(
10774
+ "div",
10775
+ "persona-widget-panel persona-relative persona-flex persona-flex-1 persona-min-h-0 persona-flex-col"
10776
+ );
10777
+ panel2.style.width = "100%";
10778
+ wrapper2.appendChild(panel2);
10779
+ const pillRoot = createElement("div", "persona-widget-pill-root");
10780
+ pillRoot.setAttribute("data-persona-composer-bar", "");
10781
+ pillRoot.dataset.state = "collapsed";
10782
+ pillRoot.dataset.expandedSize = (_h = cb.expandedSize) != null ? _h : "anchored";
10783
+ pillRoot.style.zIndex = String(
10784
+ (_j = (_i = config == null ? void 0 : config.launcher) == null ? void 0 : _i.zIndex) != null ? _j : DEFAULT_OVERLAY_Z_INDEX
10785
+ );
10786
+ return { wrapper: wrapper2, panel: panel2, pillRoot };
10787
+ }
10357
10788
  if (dockedMode) {
10358
10789
  const wrapper2 = createElement(
10359
10790
  "div",
@@ -10375,35 +10806,171 @@ var createWrapper = (config) => {
10375
10806
  "div",
10376
10807
  "persona-relative persona-flex-1 persona-flex persona-flex-col persona-min-h-0"
10377
10808
  );
10378
- const inlineWidth = (_d = (_c = config == null ? void 0 : config.launcher) == null ? void 0 : _c.width) != null ? _d : "100%";
10809
+ const inlineWidth = (_l = (_k = config == null ? void 0 : config.launcher) == null ? void 0 : _k.width) != null ? _l : "100%";
10379
10810
  wrapper2.style.width = inlineWidth;
10380
10811
  panel2.style.width = "100%";
10381
10812
  wrapper2.appendChild(panel2);
10382
10813
  return { wrapper: wrapper2, panel: panel2 };
10383
10814
  }
10384
- const launcher = (_e = config == null ? void 0 : config.launcher) != null ? _e : {};
10815
+ const launcher = (_m = config == null ? void 0 : config.launcher) != null ? _m : {};
10385
10816
  const position = launcher.position && positionMap[launcher.position] ? positionMap[launcher.position] : positionMap["bottom-right"];
10386
10817
  const wrapper = createElement(
10387
10818
  "div",
10388
10819
  `persona-widget-wrapper persona-fixed ${position} persona-transition`
10389
10820
  );
10390
- wrapper.style.zIndex = String((_g = (_f = config == null ? void 0 : config.launcher) == null ? void 0 : _f.zIndex) != null ? _g : DEFAULT_OVERLAY_Z_INDEX);
10821
+ wrapper.style.zIndex = String((_o = (_n = config == null ? void 0 : config.launcher) == null ? void 0 : _n.zIndex) != null ? _o : DEFAULT_OVERLAY_Z_INDEX);
10391
10822
  const panel = createElement(
10392
10823
  "div",
10393
10824
  "persona-widget-panel persona-relative persona-min-h-[320px]"
10394
10825
  );
10395
- const launcherWidth = (_i = (_h = config == null ? void 0 : config.launcher) == null ? void 0 : _h.width) != null ? _i : config == null ? void 0 : config.launcherWidth;
10826
+ const launcherWidth = (_q = (_p = config == null ? void 0 : config.launcher) == null ? void 0 : _p.width) != null ? _q : config == null ? void 0 : config.launcherWidth;
10396
10827
  const width = launcherWidth != null ? launcherWidth : DEFAULT_FLOATING_LAUNCHER_WIDTH;
10397
10828
  panel.style.width = width;
10398
10829
  panel.style.maxWidth = width;
10399
10830
  wrapper.appendChild(panel);
10400
10831
  return { wrapper, panel };
10401
10832
  };
10833
+ var buildComposerBarPanel = (config, showClose) => {
10834
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10835
+ const container = createElement(
10836
+ "div",
10837
+ "persona-widget-container persona-relative persona-flex persona-flex-1 persona-min-h-0 persona-flex-col persona-text-persona-primary"
10838
+ );
10839
+ container.setAttribute("data-persona-theme-zone", "container");
10840
+ const { button: closeButton, wrapper: closeButtonWrapper } = createCloseButton(
10841
+ config,
10842
+ {
10843
+ showClose,
10844
+ wrapperClassName: "persona-composer-bar-close",
10845
+ buttonSize: "16px",
10846
+ iconSize: "14px"
10847
+ }
10848
+ );
10849
+ closeButtonWrapper.style.position = "absolute";
10850
+ closeButtonWrapper.style.top = "8px";
10851
+ closeButtonWrapper.style.right = "8px";
10852
+ closeButtonWrapper.style.zIndex = "10";
10853
+ const clearChatEnabled = (_c = (_b = (_a = config == null ? void 0 : config.launcher) == null ? void 0 : _a.clearChat) == null ? void 0 : _b.enabled) != null ? _c : true;
10854
+ let clearChatButton = null;
10855
+ let clearChatButtonWrapper = null;
10856
+ if (clearChatEnabled) {
10857
+ const parts = createClearChatButton(config, {
10858
+ wrapperClassName: "persona-composer-bar-clear-chat",
10859
+ buttonSize: "16px",
10860
+ iconSize: "14px"
10861
+ });
10862
+ clearChatButton = parts.button;
10863
+ clearChatButtonWrapper = parts.wrapper;
10864
+ clearChatButtonWrapper.style.position = "absolute";
10865
+ clearChatButtonWrapper.style.top = "8px";
10866
+ clearChatButtonWrapper.style.right = "32px";
10867
+ clearChatButtonWrapper.style.zIndex = "10";
10868
+ }
10869
+ const headerPlaceholder = createElement("span", "persona-widget-header");
10870
+ headerPlaceholder.setAttribute("data-persona-theme-zone", "header");
10871
+ headerPlaceholder.style.display = "none";
10872
+ const body = createElement(
10873
+ "div",
10874
+ "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"
10875
+ );
10876
+ body.style.paddingTop = "48px";
10877
+ body.id = "persona-scroll-container";
10878
+ body.setAttribute("data-persona-theme-zone", "messages");
10879
+ const introCard = createElement(
10880
+ "div",
10881
+ "persona-rounded-2xl persona-bg-persona-surface persona-p-6"
10882
+ );
10883
+ introCard.style.boxShadow = "var(--persona-intro-card-shadow, 0 5px 15px rgba(15, 23, 42, 0.08))";
10884
+ introCard.setAttribute("data-persona-intro-card", "");
10885
+ const introTitle = createElement(
10886
+ "h2",
10887
+ "persona-text-lg persona-font-semibold persona-text-persona-primary"
10888
+ );
10889
+ introTitle.textContent = (_e = (_d = config == null ? void 0 : config.copy) == null ? void 0 : _d.welcomeTitle) != null ? _e : "Hello \u{1F44B}";
10890
+ const introSubtitle = createElement(
10891
+ "p",
10892
+ "persona-mt-2 persona-text-sm persona-text-persona-muted"
10893
+ );
10894
+ introSubtitle.textContent = (_g = (_f = config == null ? void 0 : config.copy) == null ? void 0 : _f.welcomeSubtitle) != null ? _g : "Ask anything about your account or products.";
10895
+ introCard.append(introTitle, introSubtitle);
10896
+ const messagesWrapper = createElement(
10897
+ "div",
10898
+ "persona-flex persona-flex-col persona-gap-3"
10899
+ );
10900
+ const contentMaxWidth = (_h = config == null ? void 0 : config.layout) == null ? void 0 : _h.contentMaxWidth;
10901
+ if (contentMaxWidth) {
10902
+ messagesWrapper.style.maxWidth = contentMaxWidth;
10903
+ messagesWrapper.style.marginLeft = "auto";
10904
+ messagesWrapper.style.marginRight = "auto";
10905
+ messagesWrapper.style.width = "100%";
10906
+ }
10907
+ const showWelcomeCard = ((_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.showWelcomeCard) !== false;
10908
+ if (!showWelcomeCard) {
10909
+ introCard.style.display = "none";
10910
+ body.classList.remove("persona-gap-6");
10911
+ body.classList.add("persona-gap-3");
10912
+ }
10913
+ body.append(introCard, messagesWrapper);
10914
+ const composerOverlay = createElement(
10915
+ "div",
10916
+ "persona-composer-overlay persona-pointer-events-none"
10917
+ );
10918
+ composerOverlay.setAttribute("data-persona-composer-overlay", "");
10919
+ composerOverlay.style.position = "absolute";
10920
+ composerOverlay.style.left = "0";
10921
+ composerOverlay.style.right = "0";
10922
+ composerOverlay.style.bottom = "0";
10923
+ composerOverlay.style.zIndex = "20";
10924
+ const composerElements = buildPillComposer({ config });
10925
+ const { root: peekBanner, textNode: peekTextNode } = buildPillPeekBanner();
10926
+ container.append(headerPlaceholder, closeButtonWrapper, body, composerOverlay);
10927
+ if (clearChatButtonWrapper) {
10928
+ container.appendChild(clearChatButtonWrapper);
10929
+ }
10930
+ return {
10931
+ container,
10932
+ body,
10933
+ messagesWrapper,
10934
+ composerOverlay,
10935
+ suggestions: composerElements.suggestions,
10936
+ textarea: composerElements.textarea,
10937
+ sendButton: composerElements.sendButton,
10938
+ sendButtonWrapper: composerElements.sendButtonWrapper,
10939
+ micButton: composerElements.micButton,
10940
+ micButtonWrapper: composerElements.micButtonWrapper,
10941
+ composerForm: composerElements.composerForm,
10942
+ statusText: composerElements.statusText,
10943
+ introTitle,
10944
+ introSubtitle,
10945
+ closeButton,
10946
+ closeButtonWrapper,
10947
+ clearChatButton,
10948
+ clearChatButtonWrapper,
10949
+ iconHolder: createElement("span"),
10950
+ headerTitle: createElement("span"),
10951
+ headerSubtitle: createElement("span"),
10952
+ header: headerPlaceholder,
10953
+ footer: composerElements.footer,
10954
+ attachmentButton: composerElements.attachmentButton,
10955
+ attachmentButtonWrapper: composerElements.attachmentButtonWrapper,
10956
+ attachmentInput: composerElements.attachmentInput,
10957
+ attachmentPreviewsContainer: composerElements.attachmentPreviewsContainer,
10958
+ actionsRow: composerElements.actionsRow,
10959
+ leftActions: composerElements.leftActions,
10960
+ rightActions: composerElements.rightActions,
10961
+ setSendButtonMode: composerElements.setSendButtonMode,
10962
+ peekBanner,
10963
+ peekTextNode
10964
+ };
10965
+ };
10402
10966
  var buildPanel = (config, showClose = true) => {
10403
10967
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10968
+ if (isComposerBarMountMode(config)) {
10969
+ return buildComposerBarPanel(config, showClose);
10970
+ }
10404
10971
  const container = createElement(
10405
10972
  "div",
10406
- "persona-widget-container persona-flex persona-h-full persona-w-full persona-flex-1 persona-min-h-0 persona-flex-col persona-bg-persona-surface persona-text-persona-primary persona-rounded-2xl persona-overflow-hidden persona-border persona-border-persona-border"
10973
+ "persona-widget-container persona-flex persona-h-full persona-w-full persona-flex-1 persona-min-h-0 persona-flex-col persona-text-persona-primary persona-bg-persona-surface persona-rounded-2xl persona-overflow-hidden persona-border persona-border-persona-border"
10407
10974
  );
10408
10975
  container.setAttribute("data-persona-theme-zone", "container");
10409
10976
  const headerLayoutConfig = (_a = config == null ? void 0 : config.layout) == null ? void 0 : _a.header;
@@ -14810,24 +15377,39 @@ function renderComponentDirective(directive, options) {
14810
15377
  return null;
14811
15378
  }
14812
15379
  }
15380
+ function selectDirectiveSource(message) {
15381
+ if (typeof message.rawContent === "string" && message.rawContent.length > 0) {
15382
+ return message.rawContent;
15383
+ }
15384
+ if (typeof message.content === "string") {
15385
+ const trimmed = message.content.trim();
15386
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
15387
+ return message.content;
15388
+ }
15389
+ }
15390
+ return null;
15391
+ }
14813
15392
  function hasComponentDirective(message) {
14814
- if (!message.rawContent) return false;
15393
+ const source = selectDirectiveSource(message);
15394
+ if (!source) return false;
14815
15395
  try {
14816
- const parsed = JSON.parse(message.rawContent);
15396
+ const parsed = JSON.parse(source);
14817
15397
  return typeof parsed === "object" && parsed !== null && "component" in parsed && typeof parsed.component === "string";
14818
15398
  } catch {
14819
15399
  return false;
14820
15400
  }
14821
15401
  }
14822
15402
  function extractComponentDirectiveFromMessage(message) {
14823
- if (!message.rawContent) return null;
15403
+ const source = selectDirectiveSource(message);
15404
+ if (!source) return null;
14824
15405
  try {
14825
- const parsed = JSON.parse(message.rawContent);
15406
+ const parsed = JSON.parse(source);
14826
15407
  if (typeof parsed === "object" && parsed !== null && "component" in parsed && typeof parsed.component === "string") {
15408
+ const directive = parsed;
14827
15409
  return {
14828
- component: parsed.component,
14829
- props: parsed.props && typeof parsed.props === "object" && parsed.props !== null ? parsed.props : {},
14830
- raw: message.rawContent
15410
+ component: directive.component,
15411
+ props: directive.props && typeof directive.props === "object" && directive.props !== null ? directive.props : {},
15412
+ raw: source
14831
15413
  };
14832
15414
  }
14833
15415
  } catch {
@@ -15254,7 +15836,7 @@ function buildDropOverlay(dropCfg) {
15254
15836
  return overlay;
15255
15837
  }
15256
15838
  var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15257
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q;
15839
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U;
15258
15840
  if (mount == null) {
15259
15841
  throw new Error(
15260
15842
  'createAgentExperience: mount must be a non-null HTMLElement (e.g. pass document.getElementById("my-root") after the node exists).'
@@ -15272,7 +15854,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15272
15854
  componentRegistry.registerAll(config.components);
15273
15855
  }
15274
15856
  const eventBus = createEventBus();
15275
- const storageAdapter = (_a = config.storageAdapter) != null ? _a : createLocalStorageAdapter();
15857
+ const messagePersistenceDisabled = config.persistState === false;
15858
+ const storageAdapter = messagePersistenceDisabled ? null : (_a = config.storageAdapter) != null ? _a : createLocalStorageAdapter();
15276
15859
  let persistentMetadata = {};
15277
15860
  let pendingStoredState = null;
15278
15861
  let shouldOpenAfterStateLoaded = false;
@@ -15363,7 +15946,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15363
15946
  let prevLauncherEnabled = launcherEnabled;
15364
15947
  let prevHeaderLayout = (_l = (_k = config.layout) == null ? void 0 : _k.header) == null ? void 0 : _l.layout;
15365
15948
  let wasMobileFullscreen = false;
15366
- let open = launcherEnabled ? autoExpand : true;
15949
+ const isComposerBar = () => isComposerBarMountMode(config);
15950
+ const isPanelToggleable = () => launcherEnabled || isComposerBar();
15951
+ let open = isComposerBar() ? false : launcherEnabled ? autoExpand : true;
15367
15952
  let pendingResubmit = false;
15368
15953
  let pendingResubmitTimeout = null;
15369
15954
  const handleResubmitRequested = () => {
@@ -15449,8 +16034,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15449
16034
  el.textContent = text;
15450
16035
  }
15451
16036
  }
15452
- const { wrapper, panel } = createWrapper(config);
15453
- const panelElements = buildPanel(config, launcherEnabled);
16037
+ const { wrapper, panel, pillRoot } = createWrapper(config);
16038
+ const panelElements = buildPanel(config, isPanelToggleable());
15454
16039
  let {
15455
16040
  container,
15456
16041
  body,
@@ -15533,7 +16118,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15533
16118
  const customHeader = headerPlugin.renderHeader({
15534
16119
  config,
15535
16120
  defaultRenderer: () => {
15536
- const headerElements = buildHeader({ config, showClose: launcherEnabled });
16121
+ const headerElements = buildHeader({ config, showClose: isPanelToggleable() });
15537
16122
  attachHeaderToContainer(container, headerElements, config);
15538
16123
  return headerElements.header;
15539
16124
  },
@@ -15676,6 +16261,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15676
16261
  const value = text.trim();
15677
16262
  const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
15678
16263
  if (!value && !hasAttachments) return;
16264
+ maybeExpandComposerBar();
15679
16265
  let contentParts;
15680
16266
  if (hasAttachments) {
15681
16267
  contentParts = [];
@@ -15741,23 +16327,29 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15741
16327
  };
15742
16328
  ensureComposerAttachmentSurface(footer);
15743
16329
  bindComposerRefsFromFooter(footer);
15744
- const contentMaxWidth = (_D = config.layout) == null ? void 0 : _D.contentMaxWidth;
15745
- if (contentMaxWidth && composerForm) {
16330
+ 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;
16331
+ if (contentMaxWidth) {
16332
+ messagesWrapper.style.maxWidth = contentMaxWidth;
16333
+ messagesWrapper.style.marginLeft = "auto";
16334
+ messagesWrapper.style.marginRight = "auto";
16335
+ messagesWrapper.style.width = "100%";
16336
+ }
16337
+ if (contentMaxWidth && composerForm && !isComposerBar()) {
15746
16338
  composerForm.style.maxWidth = contentMaxWidth;
15747
16339
  composerForm.style.marginLeft = "auto";
15748
16340
  composerForm.style.marginRight = "auto";
15749
16341
  }
15750
- if (contentMaxWidth && suggestions) {
16342
+ if (contentMaxWidth && suggestions && !isComposerBar()) {
15751
16343
  suggestions.style.maxWidth = contentMaxWidth;
15752
16344
  suggestions.style.marginLeft = "auto";
15753
16345
  suggestions.style.marginRight = "auto";
15754
16346
  }
15755
- if (contentMaxWidth && attachmentPreviewsContainer) {
16347
+ if (contentMaxWidth && attachmentPreviewsContainer && !isComposerBar()) {
15756
16348
  attachmentPreviewsContainer.style.maxWidth = contentMaxWidth;
15757
16349
  attachmentPreviewsContainer.style.marginLeft = "auto";
15758
16350
  attachmentPreviewsContainer.style.marginRight = "auto";
15759
16351
  }
15760
- if (((_E = config.attachments) == null ? void 0 : _E.enabled) && attachmentInput && attachmentPreviewsContainer) {
16352
+ if (((_I = config.attachments) == null ? void 0 : _I.enabled) && attachmentInput && attachmentPreviewsContainer) {
15761
16353
  attachmentManager = AttachmentManager.fromConfig(config.attachments);
15762
16354
  attachmentManager.setPreviewsContainer(attachmentPreviewsContainer);
15763
16355
  attachmentInput.addEventListener("change", (e) => {
@@ -16567,29 +17159,70 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16567
17159
  }
16568
17160
  } else {
16569
17161
  panel.appendChild(container);
17162
+ if (isComposerBar() && pillRoot) {
17163
+ if (panelElements.peekBanner) {
17164
+ pillRoot.appendChild(panelElements.peekBanner);
17165
+ }
17166
+ pillRoot.appendChild(footer);
17167
+ }
16570
17168
  }
16571
17169
  mount.appendChild(wrapper);
17170
+ if (pillRoot) {
17171
+ mount.appendChild(pillRoot);
17172
+ }
16572
17173
  const applyFullHeightStyles = () => {
16573
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2;
17174
+ 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;
17175
+ if (isComposerBar()) {
17176
+ panel.style.width = "100%";
17177
+ panel.style.maxWidth = "100%";
17178
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
17179
+ const isExpanded = wrapper.dataset.state === "expanded";
17180
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
17181
+ const wantsChrome = isExpanded && expandedSize !== "fullscreen";
17182
+ if (!wantsChrome) {
17183
+ container.style.background = "";
17184
+ container.style.border = "";
17185
+ container.style.borderRadius = "";
17186
+ container.style.overflow = "";
17187
+ container.style.boxShadow = "";
17188
+ return;
17189
+ }
17190
+ const panelPartial2 = (_e2 = (_d2 = config.theme) == null ? void 0 : _d2.components) == null ? void 0 : _e2.panel;
17191
+ const activeTheme2 = getActiveTheme(config);
17192
+ const resolveCb = (raw, fallback) => {
17193
+ var _a3;
17194
+ if (raw == null || raw === "") return fallback;
17195
+ return (_a3 = resolveTokenValue(activeTheme2, raw)) != null ? _a3 : raw;
17196
+ };
17197
+ const defaultBorder = "1px solid var(--persona-border)";
17198
+ const defaultShadow = "var(--persona-palette-shadows-xl, 0 25px 50px -12px rgba(0, 0, 0, 0.25))";
17199
+ const defaultRadius = "var(--persona-panel-radius, var(--persona-radius-xl, 0.75rem))";
17200
+ container.style.background = "var(--persona-surface, #ffffff)";
17201
+ container.style.border = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.border, defaultBorder);
17202
+ container.style.borderRadius = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.borderRadius, defaultRadius);
17203
+ container.style.boxShadow = resolveCb(panelPartial2 == null ? void 0 : panelPartial2.shadow, defaultShadow);
17204
+ container.style.overflow = "hidden";
17205
+ return;
17206
+ }
16574
17207
  const dockedMode = isDockedMountMode(config);
16575
- const sidebarMode = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.sidebarMode) != null ? _b2 : false;
16576
- const fullHeight = dockedMode || sidebarMode || ((_d2 = (_c2 = config.launcher) == null ? void 0 : _c2.fullHeight) != null ? _d2 : false);
16577
- const isInlineEmbed = ((_e2 = config.launcher) == null ? void 0 : _e2.enabled) === false;
16578
- const panelPartial = (_g2 = (_f2 = config.theme) == null ? void 0 : _f2.components) == null ? void 0 : _g2.panel;
17208
+ const sidebarMode = (_g2 = (_f2 = config.launcher) == null ? void 0 : _f2.sidebarMode) != null ? _g2 : false;
17209
+ const fullHeight = dockedMode || sidebarMode || ((_i2 = (_h2 = config.launcher) == null ? void 0 : _h2.fullHeight) != null ? _i2 : false);
17210
+ const isInlineEmbed = ((_j2 = config.launcher) == null ? void 0 : _j2.enabled) === false;
17211
+ const panelPartial = (_l2 = (_k2 = config.theme) == null ? void 0 : _k2.components) == null ? void 0 : _l2.panel;
16579
17212
  const activeTheme = getActiveTheme(config);
16580
17213
  const resolvePanelChrome = (raw, fallback) => {
16581
17214
  var _a3;
16582
17215
  if (raw == null || raw === "") return fallback;
16583
17216
  return (_a3 = resolveTokenValue(activeTheme, raw)) != null ? _a3 : raw;
16584
17217
  };
16585
- const ownerWindow2 = (_h2 = mount.ownerDocument.defaultView) != null ? _h2 : window;
16586
- const mobileFullscreen = (_j2 = (_i2 = config.launcher) == null ? void 0 : _i2.mobileFullscreen) != null ? _j2 : true;
16587
- const mobileBreakpoint = (_l2 = (_k2 = config.launcher) == null ? void 0 : _k2.mobileBreakpoint) != null ? _l2 : 640;
17218
+ const ownerWindow2 = (_m2 = mount.ownerDocument.defaultView) != null ? _m2 : window;
17219
+ const mobileFullscreen = (_o2 = (_n2 = config.launcher) == null ? void 0 : _n2.mobileFullscreen) != null ? _o2 : true;
17220
+ const mobileBreakpoint = (_q2 = (_p2 = config.launcher) == null ? void 0 : _p2.mobileBreakpoint) != null ? _q2 : 640;
16588
17221
  const isMobileViewport = ownerWindow2.innerWidth <= mobileBreakpoint;
16589
17222
  const shouldGoFullscreen = mobileFullscreen && isMobileViewport && launcherEnabled;
16590
- const position = (_n2 = (_m2 = config.launcher) == null ? void 0 : _m2.position) != null ? _n2 : "bottom-left";
17223
+ const position = (_s2 = (_r2 = config.launcher) == null ? void 0 : _r2.position) != null ? _s2 : "bottom-left";
16591
17224
  const isLeftSidebar = position === "bottom-left" || position === "top-left";
16592
- const overlayZIndex = (_p2 = (_o2 = config.launcher) == null ? void 0 : _o2.zIndex) != null ? _p2 : DEFAULT_OVERLAY_Z_INDEX;
17225
+ const overlayZIndex = (_u2 = (_t2 = config.launcher) == null ? void 0 : _t2.zIndex) != null ? _u2 : DEFAULT_OVERLAY_Z_INDEX;
16593
17226
  let defaultPanelBorder = sidebarMode || shouldGoFullscreen ? "none" : "1px solid var(--persona-border)";
16594
17227
  let defaultPanelShadow = shouldGoFullscreen ? "none" : sidebarMode ? isLeftSidebar ? "var(--persona-palette-shadows-sidebar-left, 2px 0 12px rgba(0, 0, 0, 0.08))" : "var(--persona-palette-shadows-sidebar-right, -2px 0 12px rgba(0, 0, 0, 0.08))" : "var(--persona-palette-shadows-xl, 0 25px 50px -12px rgba(0, 0, 0, 0.25))";
16595
17228
  if (dockedMode && !shouldGoFullscreen) {
@@ -16676,7 +17309,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16676
17309
  restoreBodyScrollTop();
16677
17310
  return;
16678
17311
  }
16679
- const launcherWidth = (_r2 = (_q2 = config == null ? void 0 : config.launcher) == null ? void 0 : _q2.width) != null ? _r2 : config == null ? void 0 : config.launcherWidth;
17312
+ const launcherWidth = (_w2 = (_v2 = config == null ? void 0 : config.launcher) == null ? void 0 : _v2.width) != null ? _w2 : config == null ? void 0 : config.launcherWidth;
16680
17313
  const width = launcherWidth != null ? launcherWidth : DEFAULT_FLOATING_LAUNCHER_WIDTH;
16681
17314
  if (!sidebarMode && !dockedMode) {
16682
17315
  if (isInlineEmbed && fullHeight) {
@@ -16757,11 +17390,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16757
17390
  "persona-top-4"
16758
17391
  );
16759
17392
  if (!sidebarMode && !isInlineEmbed && !dockedMode) {
16760
- const positionClasses = (_s2 = positionMap[position]) != null ? _s2 : positionMap["bottom-right"];
17393
+ const positionClasses = (_x2 = positionMap[position]) != null ? _x2 : positionMap["bottom-right"];
16761
17394
  positionClasses.split(" ").forEach((cls) => wrapper.classList.add(cls));
16762
17395
  }
16763
17396
  if (sidebarMode) {
16764
- const sidebarWidth = (_u2 = (_t2 = config.launcher) == null ? void 0 : _t2.sidebarWidth) != null ? _u2 : "420px";
17397
+ const sidebarWidth = (_z2 = (_y2 = config.launcher) == null ? void 0 : _y2.sidebarWidth) != null ? _z2 : "420px";
16765
17398
  wrapper.style.cssText = `
16766
17399
  position: fixed !important;
16767
17400
  top: 0 !important;
@@ -16813,7 +17446,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16813
17446
  if (!isInlineEmbed && !dockedMode) {
16814
17447
  const maxHeightStyles = "max-height: -moz-available !important; max-height: stretch !important;";
16815
17448
  const paddingStyles = sidebarMode ? "" : "padding-top: 1.25em !important;";
16816
- const zIndexStyles = !sidebarMode ? `z-index: ${(_w2 = (_v2 = config.launcher) == null ? void 0 : _v2.zIndex) != null ? _w2 : DEFAULT_OVERLAY_Z_INDEX} !important;` : "";
17449
+ const zIndexStyles = !sidebarMode ? `z-index: ${(_B2 = (_A2 = config.launcher) == null ? void 0 : _A2.zIndex) != null ? _B2 : DEFAULT_OVERLAY_Z_INDEX} !important;` : "";
16817
17450
  wrapper.style.cssText += maxHeightStyles + paddingStyles + zIndexStyles;
16818
17451
  }
16819
17452
  restoreBodyScrollTop();
@@ -16883,7 +17516,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16883
17516
  cleanupThemeObserver = null;
16884
17517
  }
16885
17518
  });
16886
- const streamAnimationConfig = (_F = config.features) == null ? void 0 : _F.streamAnimation;
17519
+ const streamAnimationConfig = (_J = config.features) == null ? void 0 : _J.streamAnimation;
16887
17520
  if ((streamAnimationConfig == null ? void 0 : streamAnimationConfig.type) && streamAnimationConfig.type !== "none") {
16888
17521
  const plugin = resolveStreamAnimationPlugin(
16889
17522
  streamAnimationConfig.type,
@@ -16900,6 +17533,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16900
17533
  let isStreaming = false;
16901
17534
  const messageCache = createMessageCache();
16902
17535
  const lastAskBubbleFingerprint = /* @__PURE__ */ new Map();
17536
+ const lastComponentDirectiveFingerprint = /* @__PURE__ */ new Map();
16903
17537
  let configVersion = 0;
16904
17538
  const autoFollow = createFollowStateController();
16905
17539
  let lastScrollTop = 0;
@@ -16916,7 +17550,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16916
17550
  lastUserMessageWasVoice: false,
16917
17551
  lastUserMessageId: null
16918
17552
  };
16919
- const voiceAutoResumeMode = (_H = (_G = config.voiceRecognition) == null ? void 0 : _G.autoResume) != null ? _H : false;
17553
+ const voiceAutoResumeMode = (_L = (_K = config.voiceRecognition) == null ? void 0 : _K.autoResume) != null ? _L : false;
16920
17554
  const emitVoiceState = (source) => {
16921
17555
  eventBus.emit("voice:state", {
16922
17556
  active: voiceState.active,
@@ -17147,13 +17781,21 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17147
17781
  const liveAskToolIds = /* @__PURE__ */ new Set();
17148
17782
  const hasAskPlugin = plugins.some((p) => p.renderAskUserQuestion);
17149
17783
  const askPluginHydrate = [];
17784
+ const componentDirectiveHydrate = [];
17785
+ const componentStreamingEnabled = config.enableComponentStreaming !== false;
17150
17786
  messages.forEach((message) => {
17151
17787
  var _a3, _b3, _c3, _d3, _e3, _f3, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
17152
17788
  activeMessageIds.add(message.id);
17153
17789
  const askWithPlugin = hasAskPlugin && isAskUserQuestionMessage(message);
17790
+ const hasDirectiveBubble = !askWithPlugin && message.role === "assistant" && !message.variant && componentStreamingEnabled && hasComponentDirective(message);
17791
+ if (!hasDirectiveBubble && lastComponentDirectiveFingerprint.has(message.id)) {
17792
+ const existing = container2.querySelector(`#wrapper-${message.id}`);
17793
+ existing == null ? void 0 : existing.removeAttribute("data-preserve-runtime");
17794
+ lastComponentDirectiveFingerprint.delete(message.id);
17795
+ }
17154
17796
  const askMeta = isAskUserQuestionMessage(message) ? `:${((_a3 = message.agentMetadata) == null ? void 0 : _a3.askUserQuestionAnswered) ? "a" : "u"}:${((_b3 = message.agentMetadata) == null ? void 0 : _b3.askUserQuestionAnswers) ? Object.keys(message.agentMetadata.askUserQuestionAnswers).length : 0}` : "";
17155
17797
  const fingerprint = computeMessageFingerprint(message, configVersion) + askMeta;
17156
- const cachedWrapper = askWithPlugin ? null : getCachedWrapper(messageCache, message.id, fingerprint);
17798
+ const cachedWrapper = askWithPlugin || hasDirectiveBubble ? null : getCachedWrapper(messageCache, message.id, fingerprint);
17157
17799
  if (cachedWrapper) {
17158
17800
  tempContainer.appendChild(cachedWrapper.cloneNode(true));
17159
17801
  if (isAskUserQuestionMessage(message) && ((_c3 = message.toolCall) == null ? void 0 : _c3.id) && ((_d3 = message.agentMetadata) == null ? void 0 : _d3.awaitingLocalTool) === true && !((_e3 = message.agentMetadata) == null ? void 0 : _e3.askUserQuestionAnswered)) {
@@ -17292,18 +17934,20 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17292
17934
  });
17293
17935
  }
17294
17936
  }
17295
- if (!bubble && message.role === "assistant" && !message.variant) {
17296
- const enableComponentStreaming = config.enableComponentStreaming !== false;
17297
- if (enableComponentStreaming && hasComponentDirective(message)) {
17298
- const directive = extractComponentDirectiveFromMessage(message);
17299
- if (directive) {
17937
+ if (!bubble && hasDirectiveBubble) {
17938
+ const directive = extractComponentDirectiveFromMessage(message);
17939
+ if (directive) {
17940
+ const lastFp = lastComponentDirectiveFingerprint.get(message.id);
17941
+ const needsRebuild = lastFp !== fingerprint;
17942
+ const wrapChrome = config.wrapComponentDirectiveInBubble !== false;
17943
+ let liveBubble = null;
17944
+ if (needsRebuild) {
17300
17945
  const componentBubble = renderComponentDirective(directive, {
17301
17946
  config,
17302
17947
  message,
17303
17948
  transform
17304
17949
  });
17305
17950
  if (componentBubble) {
17306
- const wrapChrome = config.wrapComponentDirectiveInBubble !== false;
17307
17951
  if (wrapChrome) {
17308
17952
  const componentWrapper = document.createElement("div");
17309
17953
  componentWrapper.className = [
@@ -17329,7 +17973,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17329
17973
  componentWrapper.appendChild(textDiv);
17330
17974
  }
17331
17975
  componentWrapper.appendChild(componentBubble);
17332
- bubble = componentWrapper;
17976
+ liveBubble = componentWrapper;
17333
17977
  } else {
17334
17978
  const stack = document.createElement("div");
17335
17979
  stack.className = "persona-flex persona-flex-col persona-w-full persona-max-w-full persona-gap-3 persona-items-stretch";
@@ -17348,10 +17992,28 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17348
17992
  stack.appendChild(textDiv);
17349
17993
  }
17350
17994
  stack.appendChild(componentBubble);
17351
- bubble = stack;
17995
+ liveBubble = stack;
17352
17996
  }
17353
17997
  }
17354
17998
  }
17999
+ if (liveBubble || lastFp != null) {
18000
+ const stub = document.createElement("div");
18001
+ stub.className = "persona-flex";
18002
+ stub.id = `wrapper-${message.id}`;
18003
+ stub.setAttribute("data-wrapper-id", message.id);
18004
+ stub.setAttribute("data-component-directive-stub", "true");
18005
+ stub.setAttribute("data-preserve-runtime", "true");
18006
+ if (!wrapChrome) {
18007
+ stub.classList.add("persona-w-full");
18008
+ }
18009
+ tempContainer.appendChild(stub);
18010
+ componentDirectiveHydrate.push({
18011
+ messageId: message.id,
18012
+ fingerprint,
18013
+ bubble: liveBubble
18014
+ });
18015
+ return;
18016
+ }
17355
18017
  }
17356
18018
  }
17357
18019
  if (!bubble) {
@@ -17602,15 +18264,327 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17602
18264
  if (!activeMessageIds.has(id)) lastAskBubbleFingerprint.delete(id);
17603
18265
  }
17604
18266
  }
18267
+ if (componentDirectiveHydrate.length > 0) {
18268
+ for (const { messageId, fingerprint, bubble } of componentDirectiveHydrate) {
18269
+ const wrapper2 = container2.querySelector(`#wrapper-${messageId}`);
18270
+ if (!wrapper2) continue;
18271
+ if (bubble === null) {
18272
+ continue;
18273
+ }
18274
+ wrapper2.replaceChildren(bubble);
18275
+ wrapper2.setAttribute("data-bubble-fp", fingerprint);
18276
+ lastComponentDirectiveFingerprint.set(messageId, fingerprint);
18277
+ }
18278
+ }
18279
+ if (lastComponentDirectiveFingerprint.size > 0) {
18280
+ for (const id of lastComponentDirectiveFingerprint.keys()) {
18281
+ if (!activeMessageIds.has(id)) lastComponentDirectiveFingerprint.delete(id);
18282
+ }
18283
+ }
17605
18284
  };
17606
18285
  const renderMessagesWithPlugins = renderMessagesWithPluginsImpl;
18286
+ let composerBarOutsideClickListener = null;
18287
+ const attachComposerBarOutsideClickDismiss = () => {
18288
+ var _a2;
18289
+ if (composerBarOutsideClickListener) return;
18290
+ const listener = (event) => {
18291
+ const path = event.composedPath();
18292
+ if (path.includes(wrapper)) return;
18293
+ if (pillRoot && path.includes(pillRoot)) return;
18294
+ setOpenState(false, "user");
18295
+ };
18296
+ composerBarOutsideClickListener = listener;
18297
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18298
+ targetDoc.addEventListener("pointerdown", listener, true);
18299
+ };
18300
+ const detachComposerBarOutsideClickDismiss = () => {
18301
+ var _a2;
18302
+ if (!composerBarOutsideClickListener) return;
18303
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18304
+ targetDoc.removeEventListener(
18305
+ "pointerdown",
18306
+ composerBarOutsideClickListener,
18307
+ true
18308
+ );
18309
+ composerBarOutsideClickListener = null;
18310
+ };
18311
+ destroyCallbacks.push(() => detachComposerBarOutsideClickDismiss());
18312
+ let composerBarEscapeListener = null;
18313
+ const attachComposerBarEscapeDismiss = () => {
18314
+ var _a2;
18315
+ if (composerBarEscapeListener) return;
18316
+ const listener = (event) => {
18317
+ if (event.key !== "Escape") return;
18318
+ if (event.isComposing) return;
18319
+ setOpenState(false, "user");
18320
+ };
18321
+ composerBarEscapeListener = listener;
18322
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18323
+ targetDoc.addEventListener("keydown", listener, true);
18324
+ };
18325
+ const detachComposerBarEscapeDismiss = () => {
18326
+ var _a2;
18327
+ if (!composerBarEscapeListener) return;
18328
+ const targetDoc = (_a2 = mount.ownerDocument) != null ? _a2 : document;
18329
+ targetDoc.removeEventListener(
18330
+ "keydown",
18331
+ composerBarEscapeListener,
18332
+ true
18333
+ );
18334
+ composerBarEscapeListener = null;
18335
+ };
18336
+ destroyCallbacks.push(() => detachComposerBarEscapeDismiss());
18337
+ let composerHovered = false;
18338
+ const peekActivatedPlugins = /* @__PURE__ */ new Set();
18339
+ const resolvePeekStreamAnimationFeature = () => {
18340
+ var _a2, _b2, _c2, _d2;
18341
+ const peekFeature = (_c2 = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) == null ? void 0 : _b2.peek) == null ? void 0 : _c2.streamAnimation;
18342
+ if (peekFeature) return peekFeature;
18343
+ return (_d2 = config.features) == null ? void 0 : _d2.streamAnimation;
18344
+ };
18345
+ const syncComposerBarPeek = () => {
18346
+ var _a2, _b2, _c2, _d2;
18347
+ if (!isComposerBar()) return;
18348
+ const peekBanner = panelElements.peekBanner;
18349
+ const peekTextNode = panelElements.peekTextNode;
18350
+ if (!peekBanner || !peekTextNode) return;
18351
+ if (open) {
18352
+ peekBanner.classList.remove("persona-pill-peek--visible");
18353
+ return;
18354
+ }
18355
+ const messages = (_a2 = session == null ? void 0 : session.getMessages()) != null ? _a2 : [];
18356
+ let lastAssistant;
18357
+ for (let i = messages.length - 1; i >= 0; i--) {
18358
+ const m = messages[i];
18359
+ if (m.role === "assistant" && m.content) {
18360
+ lastAssistant = m;
18361
+ break;
18362
+ }
18363
+ }
18364
+ if (!lastAssistant) {
18365
+ peekBanner.classList.remove("persona-pill-peek--visible");
18366
+ return;
18367
+ }
18368
+ const text = lastAssistant.content;
18369
+ const streaming = Boolean(lastAssistant.streaming);
18370
+ const feature = resolvePeekStreamAnimationFeature();
18371
+ const streamAnimation = resolveStreamAnimation(feature);
18372
+ const plugin = streamAnimation.type !== "none" ? resolveStreamAnimationPlugin(streamAnimation.type, feature == null ? void 0 : feature.plugins) : null;
18373
+ const pluginStillAnimating = ((_b2 = plugin == null ? void 0 : plugin.isAnimating) == null ? void 0 : _b2.call(plugin, lastAssistant)) === true;
18374
+ const animationActive = plugin !== null && (streaming || pluginStillAnimating);
18375
+ if (animationActive && plugin && !peekActivatedPlugins.has(plugin.name)) {
18376
+ ensurePluginActive(plugin, mount);
18377
+ peekActivatedPlugins.add(plugin.name);
18378
+ }
18379
+ const desiredContainerClass = animationActive && (plugin == null ? void 0 : plugin.containerClass) ? plugin.containerClass : null;
18380
+ const currentContainerClass = (_c2 = peekTextNode.dataset.personaPeekStreamClass) != null ? _c2 : null;
18381
+ if (currentContainerClass && currentContainerClass !== desiredContainerClass) {
18382
+ peekTextNode.classList.remove(currentContainerClass);
18383
+ delete peekTextNode.dataset.personaPeekStreamClass;
18384
+ }
18385
+ if (desiredContainerClass && currentContainerClass !== desiredContainerClass) {
18386
+ peekTextNode.classList.add(desiredContainerClass);
18387
+ peekTextNode.dataset.personaPeekStreamClass = desiredContainerClass;
18388
+ }
18389
+ if (animationActive) {
18390
+ peekTextNode.style.setProperty(
18391
+ "--persona-stream-step",
18392
+ `${streamAnimation.speed}ms`
18393
+ );
18394
+ peekTextNode.style.setProperty(
18395
+ "--persona-stream-duration",
18396
+ `${streamAnimation.duration}ms`
18397
+ );
18398
+ } else {
18399
+ peekTextNode.style.removeProperty("--persona-stream-step");
18400
+ peekTextNode.style.removeProperty("--persona-stream-duration");
18401
+ }
18402
+ const buffered = animationActive ? applyStreamBuffer(text, streamAnimation.buffer, plugin, lastAssistant, streaming) : text;
18403
+ const skeletonEnabled = animationActive && streamAnimation.placeholder === "skeleton";
18404
+ const showSkeletonOnly = skeletonEnabled && streaming && (!buffered || !buffered.trim());
18405
+ if (showSkeletonOnly) {
18406
+ const tempContainer = document.createElement("div");
18407
+ const skeleton = createSkeletonPlaceholder();
18408
+ skeleton.classList.add("persona-pill-peek__skeleton");
18409
+ tempContainer.appendChild(skeleton);
18410
+ morphMessages(peekTextNode, tempContainer);
18411
+ } else {
18412
+ const sliceStart = Math.max(0, buffered.length - 100);
18413
+ const slice = buffered.length > 100 ? buffered.slice(-100) : buffered;
18414
+ const escaped = escapeHtml(slice);
18415
+ if (!animationActive || !plugin) {
18416
+ const preview = buffered.length > 100 ? `\u2026${slice}` : slice;
18417
+ if (peekTextNode.textContent !== preview) {
18418
+ peekTextNode.textContent = preview;
18419
+ }
18420
+ } else {
18421
+ let html = escaped;
18422
+ if (plugin.wrap === "char" || plugin.wrap === "word") {
18423
+ html = wrapStreamAnimation(
18424
+ escaped,
18425
+ plugin.wrap,
18426
+ // Namespace span IDs to the peek surface so they don't collide
18427
+ // with the main bubble's spans for the same message id.
18428
+ `peek-${lastAssistant.id}`,
18429
+ { skipTags: plugin.skipTags, startIndex: sliceStart }
18430
+ );
18431
+ }
18432
+ const tempContainer = document.createElement("div");
18433
+ tempContainer.innerHTML = html;
18434
+ if (plugin.useCaret && slice.length > 0) {
18435
+ const caret = createStreamCaret();
18436
+ const spans = tempContainer.querySelectorAll(
18437
+ ".persona-stream-char, .persona-stream-word"
18438
+ );
18439
+ const lastSpan = spans[spans.length - 1];
18440
+ if (lastSpan == null ? void 0 : lastSpan.parentNode) {
18441
+ lastSpan.parentNode.insertBefore(caret, lastSpan.nextSibling);
18442
+ } else {
18443
+ tempContainer.appendChild(caret);
18444
+ }
18445
+ }
18446
+ morphMessages(peekTextNode, tempContainer);
18447
+ (_d2 = plugin.onAfterRender) == null ? void 0 : _d2.call(plugin, {
18448
+ container: peekTextNode,
18449
+ bubble: peekBanner,
18450
+ messageId: lastAssistant.id,
18451
+ message: lastAssistant,
18452
+ speed: streamAnimation.speed,
18453
+ duration: streamAnimation.duration
18454
+ });
18455
+ }
18456
+ }
18457
+ const shouldShow = isStreaming || composerHovered;
18458
+ peekBanner.classList.toggle("persona-pill-peek--visible", shouldShow);
18459
+ };
18460
+ if (isComposerBar()) {
18461
+ const peekBanner = panelElements.peekBanner;
18462
+ if (peekBanner) {
18463
+ const onPeekPointerDown = (e) => {
18464
+ e.preventDefault();
18465
+ e.stopPropagation();
18466
+ setOpenState(true, "user");
18467
+ };
18468
+ peekBanner.addEventListener("pointerdown", onPeekPointerDown);
18469
+ destroyCallbacks.push(() => {
18470
+ peekBanner.removeEventListener("pointerdown", onPeekPointerDown);
18471
+ });
18472
+ }
18473
+ const onPanelPointerEnter = () => {
18474
+ if (composerHovered) return;
18475
+ composerHovered = true;
18476
+ syncComposerBarPeek();
18477
+ };
18478
+ const onPanelPointerLeave = () => {
18479
+ if (!composerHovered) return;
18480
+ composerHovered = false;
18481
+ syncComposerBarPeek();
18482
+ };
18483
+ panel.addEventListener("pointerenter", onPanelPointerEnter);
18484
+ panel.addEventListener("pointerleave", onPanelPointerLeave);
18485
+ destroyCallbacks.push(() => {
18486
+ panel.removeEventListener("pointerenter", onPanelPointerEnter);
18487
+ panel.removeEventListener("pointerleave", onPanelPointerLeave);
18488
+ });
18489
+ if (pillRoot) {
18490
+ pillRoot.addEventListener("pointerenter", onPanelPointerEnter);
18491
+ pillRoot.addEventListener("pointerleave", onPanelPointerLeave);
18492
+ destroyCallbacks.push(() => {
18493
+ pillRoot.removeEventListener("pointerenter", onPanelPointerEnter);
18494
+ pillRoot.removeEventListener("pointerleave", onPanelPointerLeave);
18495
+ });
18496
+ }
18497
+ }
18498
+ const applyComposerBarGeometry = (isOpen) => {
18499
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18500
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
18501
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
18502
+ const bottomOffset = (_d2 = cb.bottomOffset) != null ? _d2 : "16px";
18503
+ const collapsedMaxWidth = cb.collapsedMaxWidth;
18504
+ const expandedMaxWidth = (_e2 = cb.expandedMaxWidth) != null ? _e2 : "880px";
18505
+ const expandedTopOffset = (_f2 = cb.expandedTopOffset) != null ? _f2 : "5vh";
18506
+ const modalMaxWidth = (_g2 = cb.modalMaxWidth) != null ? _g2 : "880px";
18507
+ const modalMaxHeight = (_h2 = cb.modalMaxHeight) != null ? _h2 : "min(90vh, 800px)";
18508
+ const viewportClamp = "calc(100vw - 32px)";
18509
+ const pillAreaClearance = "var(--persona-pill-area-height, 80px)";
18510
+ const s = wrapper.style;
18511
+ s.left = "";
18512
+ s.right = "";
18513
+ s.top = "";
18514
+ s.bottom = "";
18515
+ s.transform = "";
18516
+ s.width = "";
18517
+ s.maxWidth = "";
18518
+ s.height = "";
18519
+ s.maxHeight = "";
18520
+ if (pillRoot) {
18521
+ const ps = pillRoot.style;
18522
+ ps.bottom = bottomOffset;
18523
+ ps.width = collapsedMaxWidth != null ? collapsedMaxWidth : "";
18524
+ }
18525
+ if (!isOpen) {
18526
+ return;
18527
+ }
18528
+ if (expandedSize === "fullscreen") {
18529
+ return;
18530
+ }
18531
+ if (expandedSize === "modal") {
18532
+ s.top = "50%";
18533
+ s.left = "50%";
18534
+ s.transform = "translate(-50%, -50%)";
18535
+ s.bottom = "auto";
18536
+ s.right = "auto";
18537
+ s.width = modalMaxWidth;
18538
+ s.maxWidth = viewportClamp;
18539
+ s.maxHeight = modalMaxHeight;
18540
+ s.height = modalMaxHeight;
18541
+ return;
18542
+ }
18543
+ s.left = "50%";
18544
+ s.transform = "translateX(-50%)";
18545
+ s.bottom = `calc(${bottomOffset} + ${pillAreaClearance})`;
18546
+ s.top = expandedTopOffset;
18547
+ s.width = expandedMaxWidth;
18548
+ s.maxWidth = viewportClamp;
18549
+ };
17607
18550
  const updateOpenState = () => {
17608
- var _a2, _b2, _c2, _d2, _e2;
17609
- if (!launcherEnabled) return;
18551
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18552
+ if (!isPanelToggleable()) return;
18553
+ if (isComposerBar()) {
18554
+ const cb = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) != null ? _b2 : {};
18555
+ const expandedSize = (_c2 = cb.expandedSize) != null ? _c2 : "anchored";
18556
+ const nextState = open ? "expanded" : "collapsed";
18557
+ wrapper.dataset.state = nextState;
18558
+ wrapper.dataset.expandedSize = expandedSize;
18559
+ if (pillRoot) {
18560
+ pillRoot.dataset.state = nextState;
18561
+ pillRoot.dataset.expandedSize = expandedSize;
18562
+ }
18563
+ wrapper.style.removeProperty("display");
18564
+ wrapper.classList.remove("persona-pointer-events-none", "persona-opacity-0");
18565
+ panel.classList.remove(
18566
+ "persona-scale-95",
18567
+ "persona-opacity-0",
18568
+ "persona-scale-100",
18569
+ "persona-opacity-100"
18570
+ );
18571
+ applyComposerBarGeometry(open);
18572
+ container.style.display = open ? "flex" : "none";
18573
+ applyFullHeightStyles();
18574
+ if (open) {
18575
+ attachComposerBarOutsideClickDismiss();
18576
+ attachComposerBarEscapeDismiss();
18577
+ } else {
18578
+ detachComposerBarOutsideClickDismiss();
18579
+ detachComposerBarEscapeDismiss();
18580
+ }
18581
+ syncComposerBarPeek();
18582
+ return;
18583
+ }
17610
18584
  const dockedMode = isDockedMountMode(config);
17611
- const ownerWindow2 = (_a2 = mount.ownerDocument.defaultView) != null ? _a2 : window;
17612
- const mobileBreakpoint = (_c2 = (_b2 = config.launcher) == null ? void 0 : _b2.mobileBreakpoint) != null ? _c2 : 640;
17613
- const mobileFullscreen = (_e2 = (_d2 = config.launcher) == null ? void 0 : _d2.mobileFullscreen) != null ? _e2 : true;
18585
+ const ownerWindow2 = (_d2 = mount.ownerDocument.defaultView) != null ? _d2 : window;
18586
+ const mobileBreakpoint = (_f2 = (_e2 = config.launcher) == null ? void 0 : _e2.mobileBreakpoint) != null ? _f2 : 640;
18587
+ const mobileFullscreen = (_h2 = (_g2 = config.launcher) == null ? void 0 : _g2.mobileFullscreen) != null ? _h2 : true;
17614
18588
  const isMobileViewport = ownerWindow2.innerWidth <= mobileBreakpoint;
17615
18589
  const shouldGoFullscreen = mobileFullscreen && isMobileViewport && launcherEnabled;
17616
18590
  const dockReveal = resolveDockConfig(config).reveal;
@@ -17653,20 +18627,21 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17653
18627
  };
17654
18628
  const setOpenState = (nextOpen, source = "user") => {
17655
18629
  var _a2, _b2;
17656
- if (!launcherEnabled) return;
18630
+ if (!isPanelToggleable()) return;
17657
18631
  if (open === nextOpen) return;
17658
18632
  const prevOpen = open;
17659
18633
  open = nextOpen;
17660
18634
  updateOpenState();
17661
18635
  const isViewportCovering = (() => {
17662
- var _a3, _b3, _c2, _d2, _e2, _f2, _g2;
18636
+ var _a3, _b3, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2;
17663
18637
  const sm = (_b3 = (_a3 = config.launcher) == null ? void 0 : _a3.sidebarMode) != null ? _b3 : false;
17664
18638
  const ow = (_c2 = mount.ownerDocument.defaultView) != null ? _c2 : window;
17665
18639
  const mf = (_e2 = (_d2 = config.launcher) == null ? void 0 : _d2.mobileFullscreen) != null ? _e2 : true;
17666
18640
  const mb = (_g2 = (_f2 = config.launcher) == null ? void 0 : _f2.mobileBreakpoint) != null ? _g2 : 640;
17667
18641
  const isMobile = ow.innerWidth <= mb;
17668
18642
  const dockedMF = isDockedMountMode(config) && mf && isMobile;
17669
- return sm || mf && isMobile && launcherEnabled || dockedMF;
18643
+ const composerBarFS = isComposerBar() && ((_j2 = (_i2 = (_h2 = config.launcher) == null ? void 0 : _h2.composerBar) == null ? void 0 : _i2.expandedSize) != null ? _j2 : "fullscreen") === "fullscreen";
18644
+ return sm || mf && isMobile && launcherEnabled || dockedMF || composerBarFS;
17670
18645
  })();
17671
18646
  if (open && isViewportCovering) {
17672
18647
  if (!teardownHostStacking) {
@@ -17811,6 +18786,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17811
18786
  }
17812
18787
  voiceState.lastUserMessageWasVoice = Boolean(lastUserMessage == null ? void 0 : lastUserMessage.viaVoice);
17813
18788
  persistState(messages);
18789
+ syncComposerBarPeek();
17814
18790
  },
17815
18791
  onStatusChanged(status) {
17816
18792
  var _a2;
@@ -17834,6 +18810,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17834
18810
  if (!streaming) {
17835
18811
  scheduleAutoScroll(true);
17836
18812
  }
18813
+ syncComposerBarPeek();
17837
18814
  },
17838
18815
  onVoiceStatusChanged(status) {
17839
18816
  var _a2, _b2;
@@ -17870,7 +18847,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17870
18847
  }
17871
18848
  });
17872
18849
  sessionRef.current = session;
17873
- if (((_J = (_I = config.voiceRecognition) == null ? void 0 : _I.provider) == null ? void 0 : _J.type) === "runtype") {
18850
+ if (((_N = (_M = config.voiceRecognition) == null ? void 0 : _M.provider) == null ? void 0 : _N.type) === "runtype") {
17874
18851
  try {
17875
18852
  session.setupVoice();
17876
18853
  } catch (err) {
@@ -17921,6 +18898,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17921
18898
  }
17922
18899
  });
17923
18900
  }
18901
+ const maybeExpandComposerBar = () => {
18902
+ var _a2, _b2, _c2;
18903
+ if (!isComposerBar()) return;
18904
+ if (open) return;
18905
+ const expandOnSubmit = (_c2 = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.composerBar) == null ? void 0 : _b2.expandOnSubmit) != null ? _c2 : true;
18906
+ if (!expandOnSubmit) return;
18907
+ setOpenState(true, "auto");
18908
+ };
17924
18909
  const handleSubmit = (event) => {
17925
18910
  var _a2;
17926
18911
  event.preventDefault();
@@ -17931,6 +18916,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17931
18916
  const value = textarea.value.trim();
17932
18917
  const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
17933
18918
  if (!value && !hasAttachments) return;
18919
+ maybeExpandComposerBar();
17934
18920
  let contentParts;
17935
18921
  if (hasAttachments) {
17936
18922
  contentParts = [];
@@ -18096,7 +19082,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18096
19082
  micButton.setAttribute("aria-label", "Start voice recognition");
18097
19083
  }
18098
19084
  };
18099
- const createMicButton = (voiceConfig, sendButtonConfig) => {
19085
+ const createMicButton2 = (voiceConfig, sendButtonConfig) => {
18100
19086
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
18101
19087
  const hasSpeechRecognition = typeof window !== "undefined" && (typeof window.webkitSpeechRecognition !== "undefined" || typeof window.SpeechRecognition !== "undefined");
18102
19088
  const hasRuntypeProvider = ((_a2 = voiceConfig == null ? void 0 : voiceConfig.provider) == null ? void 0 : _a2.type) === "runtype";
@@ -18373,7 +19359,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18373
19359
  };
18374
19360
  let launcherButtonInstance = null;
18375
19361
  let customLauncherElement = null;
18376
- if (launcherEnabled) {
19362
+ if (launcherEnabled && !isComposerBar()) {
18377
19363
  const launcherPlugin = plugins.find((p) => p.renderLauncher);
18378
19364
  if (launcherPlugin == null ? void 0 : launcherPlugin.renderLauncher) {
18379
19365
  const customLauncher = launcherPlugin.renderLauncher({
@@ -18404,7 +19390,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18404
19390
  scheduleAutoScroll(true);
18405
19391
  maybeRestoreVoiceFromMetadata();
18406
19392
  if (autoFocusInput) {
18407
- if (!launcherEnabled) {
19393
+ if (!launcherEnabled || isComposerBar()) {
18408
19394
  setTimeout(() => maybeFocusInput(), 0);
18409
19395
  } else if (open) {
18410
19396
  setTimeout(() => maybeFocusInput(), 200);
@@ -18412,6 +19398,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18412
19398
  }
18413
19399
  const recalcPanelHeight = () => {
18414
19400
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2;
19401
+ if (isComposerBar()) {
19402
+ updateScrollToBottomButtonOffset();
19403
+ updateOpenState();
19404
+ return;
19405
+ }
18415
19406
  const dockedMode = isDockedMountMode(config);
18416
19407
  const sidebarMode = (_b2 = (_a2 = config.launcher) == null ? void 0 : _a2.sidebarMode) != null ? _b2 : false;
18417
19408
  const fullHeight = dockedMode || sidebarMode || ((_d2 = (_c2 = config.launcher) == null ? void 0 : _c2.fullHeight) != null ? _d2 : false);
@@ -18482,7 +19473,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18482
19473
  }
18483
19474
  };
18484
19475
  recalcPanelHeight();
18485
- const ownerWindow = (_K = mount.ownerDocument.defaultView) != null ? _K : window;
19476
+ const ownerWindow = (_O = mount.ownerDocument.defaultView) != null ? _O : window;
18486
19477
  ownerWindow.addEventListener("resize", recalcPanelHeight);
18487
19478
  destroyCallbacks.push(() => ownerWindow.removeEventListener("resize", recalcPanelHeight));
18488
19479
  if (typeof ResizeObserver !== "undefined") {
@@ -18552,7 +19543,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18552
19543
  closeButton.removeEventListener("click", closeHandler);
18553
19544
  closeHandler = null;
18554
19545
  }
18555
- if (launcherEnabled) {
19546
+ if (isPanelToggleable()) {
18556
19547
  closeButton.style.display = "";
18557
19548
  closeHandler = () => {
18558
19549
  setOpenState(false, "user");
@@ -18706,7 +19697,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18706
19697
  }
18707
19698
  const controller = {
18708
19699
  update(nextConfig) {
18709
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, _I2, _J2, _K2, _L2, _M2, _N2, _O2, _P2, _Q2, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab;
19700
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, _I2, _J2, _K2, _L2, _M2, _N2, _O2, _P2, _Q2, _R2, _S2, _T2, _U2, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb;
18710
19701
  const previousToolCallConfig = config.toolCall;
18711
19702
  const previousMessageActions = config.messageActions;
18712
19703
  const previousLayoutMessages = (_a2 = config.layout) == null ? void 0 : _a2.messages;
@@ -18836,11 +19827,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18836
19827
  const headerLayoutChanged = (headerLayoutConfig == null ? void 0 : headerLayoutConfig.layout) !== prevHeaderLayout;
18837
19828
  if (headerLayoutChanged && header) {
18838
19829
  const newHeaderElements = headerLayoutConfig ? buildHeaderWithLayout(config, headerLayoutConfig, {
18839
- showClose: launcherEnabled,
19830
+ showClose: isPanelToggleable(),
18840
19831
  onClose: () => setOpenState(false, "user")
18841
19832
  }) : buildHeader({
18842
19833
  config,
18843
- showClose: launcherEnabled,
19834
+ showClose: isPanelToggleable(),
18844
19835
  onClose: () => setOpenState(false, "user")
18845
19836
  });
18846
19837
  header.replaceWith(newHeaderElements.header);
@@ -18970,7 +19961,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18970
19961
  if (existingSvg || existingImg) {
18971
19962
  iconHolder.replaceChildren();
18972
19963
  }
18973
- iconHolder.textContent = (_R = launcher.agentIconText) != null ? _R : "\u{1F4AC}";
19964
+ iconHolder.textContent = (_R2 = launcher.agentIconText) != null ? _R2 : "\u{1F4AC}";
18974
19965
  }
18975
19966
  const img = iconHolder.querySelector("img");
18976
19967
  if (img) {
@@ -18979,8 +19970,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18979
19970
  }
18980
19971
  }
18981
19972
  }
18982
- const layoutShowTitle = (_T = (_S = config.layout) == null ? void 0 : _S.header) == null ? void 0 : _T.showTitle;
18983
- const layoutShowSubtitle = (_V = (_U = config.layout) == null ? void 0 : _U.header) == null ? void 0 : _V.showSubtitle;
19973
+ const layoutShowTitle = (_T2 = (_S2 = config.layout) == null ? void 0 : _S2.header) == null ? void 0 : _T2.showTitle;
19974
+ const layoutShowSubtitle = (_V = (_U2 = config.layout) == null ? void 0 : _U2.header) == null ? void 0 : _V.showSubtitle;
18984
19975
  if (headerTitle) {
18985
19976
  headerTitle.style.display = layoutShowTitle === false ? "none" : "";
18986
19977
  }
@@ -19130,7 +20121,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19130
20121
  if (clearChatButtonWrapper) {
19131
20122
  clearChatButtonWrapper.style.display = shouldShowClearChat ? "" : "none";
19132
20123
  const { closeButtonWrapper } = panelElements;
19133
- if (closeButtonWrapper && !closeButtonWrapper.classList.contains("persona-absolute")) {
20124
+ if (!isComposerBar() && closeButtonWrapper && !closeButtonWrapper.classList.contains("persona-absolute")) {
19134
20125
  if (shouldShowClearChat) {
19135
20126
  closeButtonWrapper.classList.remove("persona-ml-auto");
19136
20127
  } else {
@@ -19139,7 +20130,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19139
20130
  }
19140
20131
  const isTopRight = clearChatPlacement === "top-right";
19141
20132
  const currentlyTopRight = clearChatButtonWrapper.classList.contains("persona-absolute");
19142
- if (isTopRight !== currentlyTopRight && shouldShowClearChat) {
20133
+ if (!isComposerBar() && isTopRight !== currentlyTopRight && shouldShowClearChat) {
19143
20134
  clearChatButtonWrapper.remove();
19144
20135
  if (isTopRight) {
19145
20136
  clearChatButtonWrapper.className = "persona-absolute persona-top-4 persona-z-50";
@@ -19168,14 +20159,17 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19168
20159
  }
19169
20160
  }
19170
20161
  if (shouldShowClearChat) {
19171
- const clearChatSize = (_la = clearChatConfig.size) != null ? _la : "32px";
19172
- clearChatButton.style.height = clearChatSize;
19173
- clearChatButton.style.width = clearChatSize;
20162
+ if (!isComposerBar()) {
20163
+ const clearChatSize = (_la = clearChatConfig.size) != null ? _la : "32px";
20164
+ clearChatButton.style.height = clearChatSize;
20165
+ clearChatButton.style.width = clearChatSize;
20166
+ }
19174
20167
  const clearChatIconName = (_ma = clearChatConfig.iconName) != null ? _ma : "refresh-cw";
19175
20168
  const clearChatIconColor = (_na = clearChatConfig.iconColor) != null ? _na : "";
19176
20169
  clearChatButton.style.color = clearChatIconColor || HEADER_THEME_CSS.actionIconColor;
19177
20170
  clearChatButton.innerHTML = "";
19178
- const iconSvg = renderLucideIcon(clearChatIconName, "20px", "currentColor", 2);
20171
+ const clearChatIconSize = isComposerBar() ? "14px" : "20px";
20172
+ const iconSvg = renderLucideIcon(clearChatIconName, clearChatIconSize, "currentColor", 2);
19179
20173
  if (iconSvg) {
19180
20174
  clearChatButton.appendChild(iconSvg);
19181
20175
  }
@@ -19299,7 +20293,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19299
20293
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
19300
20294
  if (voiceRecognitionEnabled && hasVoiceInput) {
19301
20295
  if (!micButton || !micButtonWrapper) {
19302
- const micButtonResult = createMicButton(config.voiceRecognition, config.sendButton);
20296
+ const micButtonResult = createMicButton2(config.voiceRecognition, config.sendButton);
19303
20297
  if (micButtonResult) {
19304
20298
  micButton = micButtonResult.micButton;
19305
20299
  micButtonWrapper = micButtonResult.micButtonWrapper;
@@ -19596,7 +20590,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19596
20590
  } else if (tooltip) {
19597
20591
  tooltip.style.display = "none";
19598
20592
  }
19599
- const updatedContentMaxWidth = (__a = config.layout) == null ? void 0 : __a.contentMaxWidth;
20593
+ const updatedContentMaxWidth = (_cb = (__a = config.layout) == null ? void 0 : __a.contentMaxWidth) != null ? _cb : isComposerBar() ? (_bb = (_ab = (_$a = config.launcher) == null ? void 0 : _$a.composerBar) == null ? void 0 : _ab.contentMaxWidth) != null ? _bb : "720px" : void 0;
19600
20594
  if (updatedContentMaxWidth) {
19601
20595
  messagesWrapper.style.maxWidth = updatedContentMaxWidth;
19602
20596
  messagesWrapper.style.marginLeft = "auto";
@@ -19628,8 +20622,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19628
20622
  suggestions.style.marginRight = "";
19629
20623
  }
19630
20624
  }
19631
- const statusIndicatorConfig = (_$a = config.statusIndicator) != null ? _$a : {};
19632
- const isVisible = (_ab = statusIndicatorConfig.visible) != null ? _ab : true;
20625
+ const statusIndicatorConfig = (_db = config.statusIndicator) != null ? _db : {};
20626
+ const isVisible = (_eb = statusIndicatorConfig.visible) != null ? _eb : true;
19633
20627
  statusText.style.display = isVisible ? "" : "none";
19634
20628
  if (session) {
19635
20629
  const currentStatus = session.getStatus();
@@ -19648,15 +20642,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19648
20642
  statusText.classList.add(alignClass);
19649
20643
  },
19650
20644
  open() {
19651
- if (!launcherEnabled) return;
20645
+ if (!isPanelToggleable()) return;
19652
20646
  setOpenState(true, "api");
19653
20647
  },
19654
20648
  close() {
19655
- if (!launcherEnabled) return;
20649
+ if (!isPanelToggleable()) return;
19656
20650
  setOpenState(false, "api");
19657
20651
  },
19658
20652
  toggle() {
19659
- if (!launcherEnabled) return;
20653
+ if (!isPanelToggleable()) return;
19660
20654
  setOpenState(!open, "api");
19661
20655
  },
19662
20656
  clearChat() {
@@ -19710,7 +20704,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19710
20704
  setMessage(message) {
19711
20705
  if (!textarea) return false;
19712
20706
  if (session.isStreaming()) return false;
19713
- if (!open && launcherEnabled) {
20707
+ if (!open && isPanelToggleable()) {
19714
20708
  setOpenState(true, "system");
19715
20709
  }
19716
20710
  textarea.value = message;
@@ -19721,7 +20715,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19721
20715
  if (session.isStreaming()) return false;
19722
20716
  const valueToSubmit = (message == null ? void 0 : message.trim()) || textarea.value.trim();
19723
20717
  if (!valueToSubmit) return false;
19724
- if (!open && launcherEnabled) {
20718
+ if (!open && isPanelToggleable()) {
19725
20719
  setOpenState(true, "system");
19726
20720
  }
19727
20721
  textarea.value = "";
@@ -19734,7 +20728,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19734
20728
  if (session.isStreaming()) return false;
19735
20729
  if (((_b2 = (_a2 = config.voiceRecognition) == null ? void 0 : _a2.provider) == null ? void 0 : _b2.type) === "runtype") {
19736
20730
  if (session.isVoiceActive()) return true;
19737
- if (!open && launcherEnabled) setOpenState(true, "system");
20731
+ if (!open && isPanelToggleable()) setOpenState(true, "system");
19738
20732
  voiceState.manuallyDeactivated = false;
19739
20733
  persistVoiceMetadata();
19740
20734
  session.toggleVoice().then(() => {
@@ -19747,7 +20741,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19747
20741
  if (isRecording) return true;
19748
20742
  const SpeechRecognitionClass = getSpeechRecognitionClass();
19749
20743
  if (!SpeechRecognitionClass) return false;
19750
- if (!open && launcherEnabled) setOpenState(true, "system");
20744
+ if (!open && isPanelToggleable()) setOpenState(true, "system");
19751
20745
  voiceState.manuallyDeactivated = false;
19752
20746
  persistVoiceMetadata();
19753
20747
  startVoiceRecognition("user");
@@ -19773,13 +20767,13 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19773
20767
  return true;
19774
20768
  },
19775
20769
  injectMessage(options) {
19776
- if (!open && launcherEnabled) {
20770
+ if (!open && isPanelToggleable()) {
19777
20771
  setOpenState(true, "system");
19778
20772
  }
19779
20773
  return session.injectMessage(options);
19780
20774
  },
19781
20775
  injectAssistantMessage(options) {
19782
- if (!open && launcherEnabled) {
20776
+ if (!open && isPanelToggleable()) {
19783
20777
  setOpenState(true, "system");
19784
20778
  }
19785
20779
  const result = session.injectAssistantMessage(options);
@@ -19798,26 +20792,32 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19798
20792
  return result;
19799
20793
  },
19800
20794
  injectUserMessage(options) {
19801
- if (!open && launcherEnabled) {
20795
+ if (!open && isPanelToggleable()) {
19802
20796
  setOpenState(true, "system");
19803
20797
  }
19804
20798
  return session.injectUserMessage(options);
19805
20799
  },
19806
20800
  injectSystemMessage(options) {
19807
- if (!open && launcherEnabled) {
20801
+ if (!open && isPanelToggleable()) {
19808
20802
  setOpenState(true, "system");
19809
20803
  }
19810
20804
  return session.injectSystemMessage(options);
19811
20805
  },
19812
20806
  injectMessageBatch(optionsList) {
19813
- if (!open && launcherEnabled) {
20807
+ if (!open && isPanelToggleable()) {
19814
20808
  setOpenState(true, "system");
19815
20809
  }
19816
20810
  return session.injectMessageBatch(optionsList);
19817
20811
  },
20812
+ injectComponentDirective(options) {
20813
+ if (!open && isPanelToggleable()) {
20814
+ setOpenState(true, "system");
20815
+ }
20816
+ return session.injectComponentDirective(options);
20817
+ },
19818
20818
  /** @deprecated Use injectMessage() instead */
19819
20819
  injectTestMessage(event) {
19820
- if (!open && launcherEnabled) {
20820
+ if (!open && isPanelToggleable()) {
19821
20821
  setOpenState(true, "system");
19822
20822
  }
19823
20823
  session.injectTestEvent(event);
@@ -19880,7 +20880,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19880
20880
  return (_a2 = session == null ? void 0 : session.getSelectedArtifactId()) != null ? _a2 : null;
19881
20881
  },
19882
20882
  focusInput() {
19883
- if (launcherEnabled && !open) return false;
20883
+ if (launcherEnabled && !open && !isComposerBar()) return false;
19884
20884
  if (!textarea) return false;
19885
20885
  textarea.focus();
19886
20886
  return true;
@@ -19918,14 +20918,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19918
20918
  },
19919
20919
  // State query methods
19920
20920
  isOpen() {
19921
- return launcherEnabled && open;
20921
+ return isPanelToggleable() && open;
19922
20922
  },
19923
20923
  isVoiceActive() {
19924
20924
  return voiceState.active;
19925
20925
  },
19926
20926
  getState() {
19927
20927
  return {
19928
- open: launcherEnabled && open,
20928
+ open: isPanelToggleable() && open,
19929
20929
  launcherEnabled,
19930
20930
  voiceActive: voiceState.active,
19931
20931
  streaming: session.isStreaming()
@@ -19933,7 +20933,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19933
20933
  },
19934
20934
  // Feedback methods (CSAT/NPS)
19935
20935
  showCSATFeedback(options) {
19936
- if (!open && launcherEnabled) {
20936
+ if (!open && isPanelToggleable()) {
19937
20937
  setOpenState(true, "system");
19938
20938
  }
19939
20939
  const existingFeedback = messagesWrapper.querySelector(".persona-feedback-container");
@@ -19955,7 +20955,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19955
20955
  feedbackEl.scrollIntoView({ behavior: "smooth", block: "end" });
19956
20956
  },
19957
20957
  showNPSFeedback(options) {
19958
- if (!open && launcherEnabled) {
20958
+ if (!open && isPanelToggleable()) {
19959
20959
  setOpenState(true, "system");
19960
20960
  }
19961
20961
  const existingFeedback = messagesWrapper.querySelector(".persona-feedback-container");
@@ -19989,6 +20989,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19989
20989
  }
19990
20990
  destroyCallbacks.forEach((cb) => cb());
19991
20991
  wrapper.remove();
20992
+ pillRoot == null ? void 0 : pillRoot.remove();
19992
20993
  launcherButtonInstance == null ? void 0 : launcherButtonInstance.destroy();
19993
20994
  customLauncherElement == null ? void 0 : customLauncherElement.remove();
19994
20995
  if (closeHandler) {
@@ -19996,7 +20997,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
19996
20997
  }
19997
20998
  }
19998
20999
  };
19999
- const shouldExposeDebugApi = ((_L = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _L : false) || Boolean(config.debug);
21000
+ const shouldExposeDebugApi = ((_P = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _P : false) || Boolean(config.debug);
20000
21001
  if (shouldExposeDebugApi && typeof window !== "undefined") {
20001
21002
  const previousDebug = window.AgentWidgetBrowser;
20002
21003
  const debugApi = {
@@ -20093,15 +21094,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20093
21094
  });
20094
21095
  }
20095
21096
  const persistConfig = normalizePersistStateConfig(config.persistState);
20096
- if (persistConfig && launcherEnabled) {
21097
+ if (persistConfig && isPanelToggleable()) {
20097
21098
  const storage = getPersistStorage(persistConfig.storage);
20098
21099
  const openKey = `${persistConfig.keyPrefix}widget-open`;
20099
21100
  const voiceKey = `${persistConfig.keyPrefix}widget-voice`;
20100
21101
  const voiceModeKey = `${persistConfig.keyPrefix}widget-voice-mode`;
20101
21102
  if (storage) {
20102
- const wasOpen = ((_M = persistConfig.persist) == null ? void 0 : _M.openState) && storage.getItem(openKey) === "true";
20103
- const wasVoiceActive = ((_N = persistConfig.persist) == null ? void 0 : _N.voiceState) && storage.getItem(voiceKey) === "true";
20104
- const wasInVoiceMode = ((_O = persistConfig.persist) == null ? void 0 : _O.voiceState) && storage.getItem(voiceModeKey) === "true";
21103
+ const wasOpen = ((_Q = persistConfig.persist) == null ? void 0 : _Q.openState) && storage.getItem(openKey) === "true";
21104
+ const wasVoiceActive = ((_R = persistConfig.persist) == null ? void 0 : _R.voiceState) && storage.getItem(voiceKey) === "true";
21105
+ const wasInVoiceMode = ((_S = persistConfig.persist) == null ? void 0 : _S.voiceState) && storage.getItem(voiceModeKey) === "true";
20105
21106
  if (wasOpen) {
20106
21107
  setTimeout(() => {
20107
21108
  controller.open();
@@ -20118,7 +21119,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20118
21119
  }, 100);
20119
21120
  }, 0);
20120
21121
  }
20121
- if ((_P = persistConfig.persist) == null ? void 0 : _P.openState) {
21122
+ if ((_T = persistConfig.persist) == null ? void 0 : _T.openState) {
20122
21123
  eventBus.on("widget:opened", () => {
20123
21124
  storage.setItem(openKey, "true");
20124
21125
  });
@@ -20126,7 +21127,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20126
21127
  storage.setItem(openKey, "false");
20127
21128
  });
20128
21129
  }
20129
- if ((_Q = persistConfig.persist) == null ? void 0 : _Q.voiceState) {
21130
+ if ((_U = persistConfig.persist) == null ? void 0 : _U.voiceState) {
20130
21131
  eventBus.on("voice:state", (event) => {
20131
21132
  storage.setItem(voiceKey, event.active ? "true" : "false");
20132
21133
  });
@@ -20148,11 +21149,12 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
20148
21149
  }
20149
21150
  }
20150
21151
  }
20151
- if (shouldOpenAfterStateLoaded && launcherEnabled) {
21152
+ if (shouldOpenAfterStateLoaded && isPanelToggleable()) {
20152
21153
  setTimeout(() => {
20153
21154
  controller.open();
20154
21155
  }, 0);
20155
21156
  }
21157
+ syncComposerBarPeek();
20156
21158
  return controller;
20157
21159
  };
20158
21160