@superleapai/flow-ui 2.4.6 → 2.5.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.
@@ -1,12 +1,12 @@
1
1
  /**
2
- * @superleapai/flow-ui v2.2.9
2
+ * @superleapai/flow-ui v2.3.4
3
3
  * A reusable design system for building multi-step forms
4
4
  *
5
5
  * Copyright (c) 2024-present SuperLeap
6
6
  * Licensed under MIT
7
7
  *
8
8
  * Build: development
9
- * Date: 2026-02-16T06:02:03.445Z
9
+ * Date: 2026-02-19T14:43:01.927Z
10
10
  *
11
11
  * For documentation and examples, visit:
12
12
  * https://github.com/superleap/superleap-flow
@@ -3567,12 +3567,13 @@
3567
3567
 
3568
3568
  /**
3569
3569
  * Tell the CRM to navigate to a path.
3570
- * @param {string} path
3570
+ * @param {string} url
3571
+ * @param {boolean} [newTab=false]
3571
3572
  */
3572
- function navigate(path) {
3573
+ function navigate(url, newTab) {
3573
3574
  var bridge = getBridge();
3574
3575
  if (bridge && bridge.isConnected()) {
3575
- bridge.send("crm:navigate", { path: path });
3576
+ bridge.send("crm:navigate", { url: url, new_tab: !!newTab });
3576
3577
  }
3577
3578
  }
3578
3579
 
@@ -5121,42 +5122,6 @@
5121
5122
  });
5122
5123
  }
5123
5124
 
5124
- // ============================================================================
5125
- // ALERT COMPONENT
5126
- // ============================================================================
5127
-
5128
- /**
5129
- * Render alerts/errors
5130
- * Uses Alert component when available for design-system styling.
5131
- * @param {HTMLElement} container - Container element for alerts
5132
- * @param {Array} messages - Array of error/info messages (strings) or { title?, description } objects
5133
- * @param {string} type - Alert type: "error" | "info" | "success" | "warning" | "destructive" | "default"
5134
- */
5135
- function renderAlerts(container, messages = [], type = "error") {
5136
- if (!container) {return;}
5137
- container.innerHTML = "";
5138
-
5139
- const Alert = getComponent("Alert");
5140
- const useAlertComponent = Alert && typeof Alert.create === "function";
5141
-
5142
- messages.forEach((msg) => {
5143
- const description = typeof msg === "string" ? msg : (msg.description || msg.title || "");
5144
- const title = typeof msg === "object" && msg.title ? msg.title : "";
5145
-
5146
- if (useAlertComponent && (description || title)) {
5147
- const variantMap = { error: "error", info: "info", success: "success" };
5148
- const variant = variantMap[type] || type;
5149
- const alertEl = Alert.create({ title, description, variant });
5150
- if (alertEl) container.appendChild(alertEl);
5151
- } else {
5152
- const div = document.createElement("div");
5153
- div.className = `alert alert--${type}`;
5154
- div.textContent = description || title;
5155
- container.appendChild(div);
5156
- }
5157
- });
5158
- }
5159
-
5160
5125
  // ============================================================================
5161
5126
  // TABLE COMPONENT
5162
5127
  // ============================================================================
@@ -5491,9 +5456,8 @@
5491
5456
  // Stepper
5492
5457
  renderStepper,
5493
5458
 
5494
- // Alerts (now shows toast notifications)
5459
+ // Alerts
5495
5460
  showToast,
5496
- renderAlerts, // Legacy support for static alerts
5497
5461
 
5498
5462
  // Table
5499
5463
  createDataTable,
@@ -6896,12 +6860,12 @@
6896
6860
  ' stroke-width="1.5">' +
6897
6861
  TI_PATH_NONE +
6898
6862
  '<path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0"/><path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"/></svg>',
6899
- IconCurrencyDollar:
6863
+ IconStar:
6900
6864
  "<svg" +
6901
6865
  TI +
6902
6866
  ' stroke-width="1.5">' +
6903
6867
  TI_PATH_NONE +
6904
- '<path d="M16.7 8a3 3 0 0 0 -2.7 -2h-4a3 3 0 0 0 0 6h4a3 3 0 0 1 0 6h-4a3 3 0 0 1 -2.7 -2"/><path d="M12 3v3m0 12v3"/></svg>',
6868
+ '<path d="M12 17.75l-6.172 3.245l1.179 -6.873l-5 -4.867l6.9 -1l3.086 -6.253l3.086 6.253l6.9 1l-5 4.867l1.179 6.873z"/></svg>',
6905
6869
  IconPhone:
6906
6870
  "<svg" +
6907
6871
  TI +
@@ -7100,9 +7064,18 @@
7100
7064
  return { show: noop, hide: noop, destroy: noop, element: null };
7101
7065
  }
7102
7066
 
7067
+ // Wrap trigger in a relative container so popover can be absolute relative to it (full width so parent controls it)
7068
+ const container = document.createElement("div");
7069
+ container.className = "relative w-full";
7070
+ const triggerParent = triggerEl.parentNode;
7071
+ if (triggerParent) {
7072
+ triggerParent.insertBefore(container, triggerEl);
7073
+ container.appendChild(triggerEl);
7074
+ }
7075
+
7103
7076
  const wrapper = document.createElement("div");
7104
7077
  wrapper.className =
7105
- "fixed z-50 pointer-events-none opacity-0 invisible transition-opacity duration-150 ease-out";
7078
+ "absolute z-50 pointer-events-none opacity-0 invisible transition-opacity duration-150 ease-out";
7106
7079
  wrapper.setAttribute("aria-hidden", "true");
7107
7080
 
7108
7081
  const panel = document.createElement("div");
@@ -7138,57 +7111,46 @@
7138
7111
  panel.appendChild(body);
7139
7112
 
7140
7113
  wrapper.appendChild(panel);
7114
+ container.appendChild(wrapper);
7141
7115
 
7142
7116
  function noop() {}
7143
7117
 
7144
7118
  function position() {
7145
- const rect = triggerEl.getBoundingClientRect();
7119
+ const triggerRect = triggerEl.getBoundingClientRect();
7146
7120
  const panelRect = panel.getBoundingClientRect();
7147
7121
  const gap = 8;
7148
7122
  let top = 0;
7149
7123
  let left = 0;
7150
7124
 
7151
7125
  // Alignment offset: start = 0, center = half diff, end = full diff
7152
- const alignLeft = (align === "center" ? (rect.width - panelRect.width) / 2 : align === "end" ? rect.width - panelRect.width : 0);
7153
- const alignTop = (align === "center" ? (rect.height - panelRect.height) / 2 : align === "end" ? rect.height - panelRect.height : 0);
7126
+ const alignLeft = (align === "center" ? (triggerRect.width - panelRect.width) / 2 : align === "end" ? triggerRect.width - panelRect.width : 0);
7127
+ const alignTop = (align === "center" ? (triggerRect.height - panelRect.height) / 2 : align === "end" ? triggerRect.height - panelRect.height : 0);
7154
7128
 
7155
7129
  switch (placement) {
7156
7130
  case "bottom":
7157
- top = rect.bottom + gap;
7158
- left = rect.left + alignLeft;
7131
+ top = triggerRect.height + gap;
7132
+ left = alignLeft;
7159
7133
  break;
7160
7134
  case "top":
7161
- top = rect.top - panelRect.height - gap;
7162
- left = rect.left + alignLeft;
7135
+ top = -panelRect.height - gap;
7136
+ left = alignLeft;
7163
7137
  break;
7164
7138
  case "right":
7165
- top = rect.top + alignTop;
7166
- left = rect.right + gap;
7139
+ top = alignTop;
7140
+ left = triggerRect.width + gap;
7167
7141
  break;
7168
7142
  case "left":
7169
- top = rect.top + alignTop;
7170
- left = rect.left - panelRect.width - gap;
7143
+ top = alignTop;
7144
+ left = -panelRect.width - gap;
7171
7145
  break;
7172
7146
  default:
7173
- top = rect.bottom + gap;
7174
- left = rect.left + alignLeft;
7175
- }
7176
-
7177
- // Keep within viewport
7178
- const padding = 8;
7179
- if (left < padding) left = padding;
7180
- if (left + panelRect.width > window.innerWidth - padding) {
7181
- left = window.innerWidth - panelRect.width - padding;
7182
- }
7183
- if (top < padding) top = padding;
7184
- if (top + panelRect.height > window.innerHeight - padding) {
7185
- top = window.innerHeight - panelRect.height - padding;
7147
+ top = triggerRect.height + gap;
7148
+ left = alignLeft;
7186
7149
  }
7187
7150
 
7188
- wrapper.style.left = "0";
7189
- wrapper.style.top = "0";
7190
- wrapper.style.transform = "translate(" + left + "px, " + top + "px)";
7191
- // Force reflow so transform is applied before we show (avoids flash from left/top-left)
7151
+ wrapper.style.transform = "";
7152
+ wrapper.style.top = top + "px";
7153
+ wrapper.style.left = left + "px";
7192
7154
  wrapper.offsetHeight;
7193
7155
  }
7194
7156
 
@@ -7202,24 +7164,7 @@
7202
7164
 
7203
7165
  function show() {
7204
7166
  if (onOpen) onOpen();
7205
- var justAppended = !wrapper.parentNode;
7206
- if (justAppended) {
7207
- document.body.appendChild(wrapper);
7208
- }
7209
- // On first open, wait for layout so getBoundingClientRect() is correct (avoids wrong position / "from left" look)
7210
- if (justAppended) {
7211
- requestAnimationFrame(function () {
7212
- position();
7213
- wrapper.classList.remove("invisible", "opacity-0", "pointer-events-none");
7214
- wrapper.classList.add("visible", "opacity-100", "pointer-events-auto");
7215
- wrapper.setAttribute("aria-hidden", "false");
7216
- requestAnimationFrame(function () {
7217
- requestAnimationFrame(function () {
7218
- panel.setAttribute("data-state", "open");
7219
- });
7220
- });
7221
- });
7222
- } else {
7167
+ requestAnimationFrame(function () {
7223
7168
  position();
7224
7169
  wrapper.classList.remove("invisible", "opacity-0", "pointer-events-none");
7225
7170
  wrapper.classList.add("visible", "opacity-100", "pointer-events-auto");
@@ -7229,7 +7174,7 @@
7229
7174
  panel.setAttribute("data-state", "open");
7230
7175
  });
7231
7176
  });
7232
- }
7177
+ });
7233
7178
  }
7234
7179
 
7235
7180
  function destroy() {
@@ -7237,6 +7182,10 @@
7237
7182
  if (wrapper.parentNode) {
7238
7183
  wrapper.parentNode.removeChild(wrapper);
7239
7184
  }
7185
+ if (container.parentNode && triggerEl.parentNode === container) {
7186
+ container.parentNode.insertBefore(triggerEl, container);
7187
+ container.parentNode.removeChild(container);
7188
+ }
7240
7189
  if (closeOnClickOutside) {
7241
7190
  document.removeEventListener("click", outsideClick);
7242
7191
  }
@@ -7356,6 +7305,14 @@
7356
7305
  return Array.prototype.filter.call(arguments, Boolean).join(" ");
7357
7306
  }
7358
7307
 
7308
+ function getDep(name) {
7309
+ if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
7310
+ var c = global.FlowUI._getComponent(name);
7311
+ if (c) return c;
7312
+ }
7313
+ return global[name];
7314
+ }
7315
+
7359
7316
  /**
7360
7317
  * Create a custom select component
7361
7318
  * @param {Object} config
@@ -7385,6 +7342,11 @@
7385
7342
  var value =
7386
7343
  config.value !== undefined && config.value !== null ? config.value : "";
7387
7344
 
7345
+ var Popover = getDep("Popover");
7346
+ if (!Popover || typeof Popover.create !== "function") {
7347
+ throw new Error("Select requires Popover");
7348
+ }
7349
+
7388
7350
  var selectedOption = options.find(function (opt) {
7389
7351
  var optValue =
7390
7352
  opt.value !== undefined && opt.value !== null
@@ -7484,11 +7446,7 @@
7484
7446
 
7485
7447
  var content = document.createElement("div");
7486
7448
  content.setAttribute("role", "listbox");
7487
- var contentBase =
7488
- "custom-select-content absolute left-0 right-0 z-50 max-h-[200px] min-w-[8rem] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium opacity-0 invisible transition-all duration-150 ease-out " +
7489
- "group-[.open]:opacity-100 group-[.open]:visible ";
7490
- content.className =
7491
- contentBase + "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
7449
+ content.className = "custom-select-content w-full max-h-[200px] overflow-hidden flex flex-col";
7492
7450
 
7493
7451
  var optionsList = document.createElement("div");
7494
7452
  optionsList.className =
@@ -7542,47 +7500,66 @@
7542
7500
  }
7543
7501
 
7544
7502
  content.appendChild(optionsList);
7545
- container.appendChild(content);
7546
7503
 
7547
- var isOpen = false;
7548
7504
  var highlightedIndex = -1;
7505
+ var popover = Popover.create({
7506
+ trigger: trigger,
7507
+ content: content,
7508
+ placement: "bottom",
7509
+ align: "start",
7510
+ closeOnClickOutside: true,
7511
+ bodyClassName: "p-0 overflow-hidden",
7512
+ panelClassName: "min-w-[var(--trigger-width)] max-h-[200px] overflow-hidden",
7513
+ onOpen: function () {
7514
+ if (disabled) {
7515
+ popover.hide();
7516
+ return;
7517
+ }
7518
+ document
7519
+ .querySelectorAll(".custom-select, .record-select, .enum-select, .enum-multiselect, .custom-multiselect, .record-multiselect")
7520
+ .forEach(function (other) {
7521
+ if (other !== container && other.popoverInstance) {
7522
+ other.popoverInstance.hide();
7523
+ }
7524
+ });
7525
+ trigger.setAttribute("aria-expanded", "true");
7526
+ chevron.style.transform = "rotate(180deg)";
7527
+ highlightOptionByValue(value);
7528
+ if (popover.panel) {
7529
+ var triggerWidthPx = trigger.offsetWidth + "px";
7530
+ popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
7531
+ popover.panel.style.minWidth = triggerWidthPx;
7532
+ popover.panel.style.width = triggerWidthPx;
7533
+ }
7534
+ },
7535
+ onClose: function () {
7536
+ trigger.setAttribute("aria-expanded", "false");
7537
+ chevron.style.transform = "";
7538
+ highlightedIndex = -1;
7539
+ },
7540
+ });
7541
+ container.popoverInstance = popover;
7549
7542
 
7550
7543
  function openDropdown() {
7551
7544
  if (disabled) return;
7552
- document
7553
- .querySelectorAll(".custom-select.open, .record-select.open")
7554
- .forEach(function (other) {
7555
- if (other !== container) {
7556
- other.classList.remove("open");
7557
- var t = other.querySelector(
7558
- "button, .custom-select-trigger, .record-select-trigger"
7559
- );
7560
- if (t) t.setAttribute("aria-expanded", "false");
7561
- }
7562
- });
7563
- isOpen = true;
7564
- container.classList.add("open");
7565
- trigger.setAttribute("aria-expanded", "true");
7566
- highlightOptionByValue(value);
7567
- updatePosition();
7545
+ popover.show();
7568
7546
  }
7569
7547
 
7570
7548
  function closeDropdown() {
7571
- isOpen = false;
7572
- container.classList.remove("open");
7573
- trigger.setAttribute("aria-expanded", "false");
7549
+ popover.hide();
7574
7550
  highlightedIndex = -1;
7575
7551
  }
7576
7552
 
7577
7553
  function toggleDropdown() {
7554
+ var isVisible = popover.element && popover.element.classList.contains("visible");
7578
7555
  var others = document.querySelectorAll(
7579
- ".custom-select.open, .record-select.open"
7556
+ ".custom-select, .record-select, .enum-select, .enum-multiselect, .custom-multiselect, .record-multiselect"
7580
7557
  );
7581
7558
  var hasOther = Array.from(others).some(function (s) {
7582
- return s !== container;
7559
+ return s !== container && s.popoverInstance && s.popoverInstance.element && s.popoverInstance.element.classList.contains("visible");
7583
7560
  });
7584
7561
  if (hasOther) openDropdown();
7585
- else if (isOpen) closeDropdown();
7562
+ else if (isVisible) closeDropdown();
7586
7563
  else openDropdown();
7587
7564
  }
7588
7565
 
@@ -7661,40 +7638,26 @@
7661
7638
 
7662
7639
  function scrollToOption(opt) {
7663
7640
  if (!opt) return;
7664
- var cr = content.getBoundingClientRect();
7641
+ var cr = optionsList.getBoundingClientRect();
7665
7642
  var top = opt.offsetTop;
7666
7643
  var bottom = top + opt.offsetHeight;
7667
- var st = content.scrollTop;
7644
+ var st = optionsList.scrollTop;
7668
7645
  var sb = st + cr.height;
7669
- if (top < st) content.scrollTop = top - 8;
7646
+ if (top < st) optionsList.scrollTop = top - 8;
7670
7647
  else if (bottom > sb)
7671
- content.scrollTop = bottom - cr.height + 8;
7672
- }
7673
-
7674
- function updatePosition() {
7675
- var rect = trigger.getBoundingClientRect();
7676
- var vh = window.innerHeight;
7677
- var below = vh - rect.bottom;
7678
- var above = rect.top;
7679
- if (below < 200 && above > below) {
7680
- content.className =
7681
- contentBase +
7682
- "bottom-full mb-1 translate-y-1 group-[.open]:translate-y-0";
7683
- } else {
7684
- content.className =
7685
- contentBase +
7686
- "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
7687
- }
7648
+ optionsList.scrollTop = bottom - cr.height + 8;
7688
7649
  }
7689
7650
 
7690
7651
  trigger.addEventListener("click", function (e) {
7691
- e.preventDefault();
7692
- e.stopPropagation();
7693
- toggleDropdown();
7694
- });
7652
+ if (disabled) {
7653
+ e.preventDefault();
7654
+ e.stopImmediatePropagation();
7655
+ }
7656
+ }, true);
7695
7657
 
7696
7658
  trigger.addEventListener("keydown", function (e) {
7697
7659
  if (disabled) return;
7660
+ var isVisible = popover.element && popover.element.classList.contains("visible");
7698
7661
  switch (e.key) {
7699
7662
  case "Enter":
7700
7663
  case " ":
@@ -7703,16 +7666,16 @@
7703
7666
  break;
7704
7667
  case "ArrowDown":
7705
7668
  e.preventDefault();
7706
- if (!isOpen) openDropdown();
7669
+ if (!isVisible) openDropdown();
7707
7670
  else navigateOptions(1);
7708
7671
  break;
7709
7672
  case "ArrowUp":
7710
7673
  e.preventDefault();
7711
- if (!isOpen) openDropdown();
7674
+ if (!isVisible) openDropdown();
7712
7675
  else navigateOptions(-1);
7713
7676
  break;
7714
7677
  case "Escape":
7715
- if (isOpen) {
7678
+ if (isVisible) {
7716
7679
  e.preventDefault();
7717
7680
  closeDropdown();
7718
7681
  }
@@ -7733,13 +7696,6 @@
7733
7696
  scrollToOption(opt);
7734
7697
  }
7735
7698
 
7736
- document.addEventListener("click", function (e) {
7737
- if (isOpen && !container.contains(e.target)) closeDropdown();
7738
- });
7739
- document.addEventListener("keydown", function (e) {
7740
- if (e.key === "Escape" && isOpen) closeDropdown();
7741
- });
7742
-
7743
7699
  container.updateValue = function (newValue) {
7744
7700
  value =
7745
7701
  newValue !== undefined && newValue !== null ? newValue : "";
@@ -7836,7 +7792,8 @@
7836
7792
  canClear && !!value && !disabled
7837
7793
  );
7838
7794
  updateClearButton();
7839
- if (disabled && isOpen) closeDropdown();
7795
+ var isVisible = popover.element && popover.element.classList.contains("visible");
7796
+ if (disabled && isVisible) closeDropdown();
7840
7797
  };
7841
7798
 
7842
7799
  return container;
@@ -7926,6 +7883,14 @@
7926
7883
  return Array.prototype.filter.call(arguments, Boolean).join(" ");
7927
7884
  }
7928
7885
 
7886
+ function getDep(name) {
7887
+ if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
7888
+ var c = global.FlowUI._getComponent(name);
7889
+ if (c) return c;
7890
+ }
7891
+ return global[name];
7892
+ }
7893
+
7929
7894
  /** Resolve client: use FlowUI._getComponent when bundle has captured globals, else global.superleapClient */
7930
7895
  function getClient() {
7931
7896
  if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
@@ -7989,8 +7954,10 @@
7989
7954
  var error = null;
7990
7955
  var searchQuery = "";
7991
7956
  var popover = null;
7992
- var usePopover = !!(global.Popover && typeof global.Popover.create === "function");
7993
- var isOpen = false;
7957
+ var Popover = getDep("Popover");
7958
+ if (!Popover || typeof Popover.create !== "function") {
7959
+ throw new Error("EnumSelect requires Popover");
7960
+ }
7994
7961
 
7995
7962
  var container = document.createElement("div");
7996
7963
  container.className = "enum-select relative w-full group";
@@ -8074,13 +8041,7 @@
8074
8041
  // Create dropdown content
8075
8042
  var content = document.createElement("div");
8076
8043
  content.setAttribute("role", "listbox");
8077
- var contentBase = "w-full min-w-[200px]";
8078
- if (!usePopover) {
8079
- contentBase += " absolute left-0 right-0 z-50 max-h-[30vh] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium border-1/2 border-border-primary opacity-0 invisible transition-all duration-150 ease-out group-[.open]:opacity-100 group-[.open]:visible top-full mt-1 -translate-y-1 group-[.open]:translate-y-0 flex flex-col";
8080
- } else {
8081
- contentBase += " max-h-[30vh] overflow-hidden flex flex-col";
8082
- }
8083
- content.className = contentBase;
8044
+ content.className = "w-full min-w-[200px] max-h-[30vh] overflow-hidden flex flex-col";
8084
8045
 
8085
8046
  // Search input (using InputComponent like phone-input)
8086
8047
  var searchContainer = document.createElement("div");
@@ -8146,10 +8107,6 @@
8146
8107
  content.appendChild(searchContainer);
8147
8108
  content.appendChild(optionsList);
8148
8109
 
8149
- if (!usePopover) {
8150
- container.appendChild(content);
8151
- }
8152
-
8153
8110
  var highlightedIndex = -1;
8154
8111
 
8155
8112
  function showLoading() {
@@ -8272,37 +8229,14 @@
8272
8229
 
8273
8230
  function openDropdown() {
8274
8231
  if (disabled) return;
8275
- if (popover) {
8276
- // Close other open selects
8277
- document
8278
- .querySelectorAll(".enum-select, .custom-select, .record-select")
8279
- .forEach(function (other) {
8280
- if (other !== container && other.popoverInstance) {
8281
- other.popoverInstance.hide();
8282
- }
8283
- });
8284
- popover.show();
8285
- trigger.setAttribute("aria-expanded", "true");
8286
- highlightOptionByValue(value);
8287
- if (searchInput) {
8288
- setTimeout(function () {
8289
- searchInput.focus();
8290
- }, 50);
8291
- }
8292
- return;
8293
- }
8294
- // Fallback when Popover not available
8295
8232
  document
8296
- .querySelectorAll(".enum-select.open")
8233
+ .querySelectorAll(".enum-select, .custom-select, .record-select")
8297
8234
  .forEach(function (other) {
8298
- if (other !== container) {
8299
- other.classList.remove("open");
8300
- var t = other.querySelector("button");
8301
- if (t) t.setAttribute("aria-expanded", "false");
8235
+ if (other !== container && other.popoverInstance) {
8236
+ other.popoverInstance.hide();
8302
8237
  }
8303
8238
  });
8304
- isOpen = true;
8305
- container.classList.add("open");
8239
+ popover.show();
8306
8240
  trigger.setAttribute("aria-expanded", "true");
8307
8241
  highlightOptionByValue(value);
8308
8242
  if (searchInput) {
@@ -8313,12 +8247,7 @@
8313
8247
  }
8314
8248
 
8315
8249
  function closeDropdown() {
8316
- if (popover) {
8317
- popover.hide();
8318
- } else {
8319
- isOpen = false;
8320
- container.classList.remove("open");
8321
- }
8250
+ popover.hide();
8322
8251
  trigger.setAttribute("aria-expanded", "false");
8323
8252
  highlightedIndex = -1;
8324
8253
  clearSearch();
@@ -8326,9 +8255,7 @@
8326
8255
  }
8327
8256
 
8328
8257
  function toggleDropdown() {
8329
- var isVisible = popover
8330
- ? popover.element && popover.element.classList.contains("visible")
8331
- : isOpen;
8258
+ var isVisible = popover.element && popover.element.classList.contains("visible");
8332
8259
  if (isVisible) {
8333
8260
  closeDropdown();
8334
8261
  } else {
@@ -8439,10 +8366,7 @@
8439
8366
 
8440
8367
  // Initialize Popover
8441
8368
  function initializePopover() {
8442
- if (!usePopover) {
8443
- return;
8444
- }
8445
- popover = global.Popover.create({
8369
+ popover = Popover.create({
8446
8370
  trigger: trigger,
8447
8371
  content: content,
8448
8372
  placement: "bottom",
@@ -8458,6 +8382,12 @@
8458
8382
  onOpen: function () {
8459
8383
  trigger.setAttribute("aria-expanded", "true");
8460
8384
  chevron.style.transform = "rotate(180deg)";
8385
+ if (popover.panel) {
8386
+ var triggerWidthPx = trigger.offsetWidth + "px";
8387
+ popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
8388
+ popover.panel.style.minWidth = triggerWidthPx;
8389
+ popover.panel.style.width = triggerWidthPx;
8390
+ }
8461
8391
  },
8462
8392
  bodyClassName: "p-0 overflow-hidden",
8463
8393
  panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
@@ -8465,13 +8395,6 @@
8465
8395
 
8466
8396
  // Store popover instance for cleanup
8467
8397
  container.popoverInstance = popover;
8468
-
8469
- // Set CSS variable for trigger width
8470
- var triggerWidth = trigger.offsetWidth;
8471
- if (popover.panel) {
8472
- popover.panel.style.setProperty("--trigger-width", triggerWidth + "px");
8473
- popover.panel.style.minWidth = triggerWidth + "px";
8474
- }
8475
8398
  }
8476
8399
 
8477
8400
  // Load options from SDK
@@ -8591,21 +8514,6 @@
8591
8514
  initializePopover();
8592
8515
  loadOptions();
8593
8516
 
8594
- if (!usePopover) {
8595
- trigger.addEventListener("click", function (e) {
8596
- e.preventDefault();
8597
- e.stopPropagation();
8598
- if (disabled) return;
8599
- toggleDropdown();
8600
- });
8601
- document.addEventListener("click", function (e) {
8602
- if (isOpen && !container.contains(e.target)) closeDropdown();
8603
- });
8604
- document.addEventListener("keydown", function (e) {
8605
- if (e.key === "Escape" && isOpen) closeDropdown();
8606
- });
8607
- }
8608
-
8609
8517
  // Public API
8610
8518
  container.updateValue = function (newValue) {
8611
8519
  value = newValue !== undefined && newValue !== null ? newValue : "";
@@ -8650,7 +8558,7 @@
8650
8558
  );
8651
8559
  updateClearButton();
8652
8560
  var isVisible = popover && popover.element && popover.element.classList.contains("visible");
8653
- if (disabled && (isVisible || isOpen)) closeDropdown();
8561
+ if (disabled && isVisible) closeDropdown();
8654
8562
  };
8655
8563
 
8656
8564
  container.reload = function () {
@@ -8688,7 +8596,7 @@
8688
8596
  /**
8689
8597
  * Record Select Component (superleap-flow)
8690
8598
  * Single-record select with search; same trigger/content styling as Select.
8691
- * Uses: Popover (dropdown), InputComponent (search), Spinner (loading), Avatar (vivid for user).
8599
+ * Uses Popover for dropdown (required), InputComponent (search), Spinner (loading), Avatar (vivid for user).
8692
8600
  * Fetches records via superleapClient.getSdk().model(objectSlug).
8693
8601
  * For objectSlug === 'user' shows Vivid Avatar; otherwise static icon from schema or object map (database fallback).
8694
8602
  * Does not use icon from backend payload.
@@ -8709,7 +8617,7 @@
8709
8617
  role: { iconStr: "IconShield", color: "info" },
8710
8618
  iframe: { iconStr: "IconLayout", color: "neutral" },
8711
8619
  lead: { iconStr: "IconUser", color: "primary" },
8712
- opportunity: { iconStr: "IconCurrencyDollar", color: "success" },
8620
+ opportunity: { iconStr: "IconStar", color: "success" },
8713
8621
  call_log: { iconStr: "IconPhone", color: "info" },
8714
8622
  communication: { iconStr: "IconMessage", color: "primary" },
8715
8623
  history_field: { iconStr: "IconClock", color: "neutral" },
@@ -8856,6 +8764,12 @@
8856
8764
  errEl.textContent = "Record select: objectSlug is required.";
8857
8765
  return errEl;
8858
8766
  }
8767
+ if (!Popover || typeof Popover.create !== "function") {
8768
+ var popoverErr = document.createElement("div");
8769
+ popoverErr.className = "text-reg-13 text-typography-quaternary-text";
8770
+ popoverErr.textContent = "Record select: Popover is required.";
8771
+ return popoverErr;
8772
+ }
8859
8773
 
8860
8774
  var container = document.createElement("div");
8861
8775
  container.className = "record-select relative w-full group";
@@ -8868,16 +8782,11 @@
8868
8782
  var isOpen = false;
8869
8783
  var searchTerm = "";
8870
8784
  var searchDebounceTimer = null;
8871
- var usePopover = Popover && typeof Popover.create === "function";
8872
8785
  var popover = null;
8873
8786
  var hasMoreRecords = true;
8874
8787
  var currentPage = 1;
8875
8788
  var isFetchingMore = false;
8876
8789
  var totalFetched = 0;
8877
- var contentBase = "record-select-content min-w-[8rem] ";
8878
- if (!usePopover) {
8879
- contentBase += "absolute left-0 right-0 z-50 max-h-[30vh] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium opacity-0 invisible transition-all duration-150 ease-out group-[.open]:opacity-100 group-[.open]:visible ";
8880
- }
8881
8790
 
8882
8791
  // Trigger wrapper + button (same structure as Select)
8883
8792
  var triggerWrapper = document.createElement("span");
@@ -8943,7 +8852,7 @@
8943
8852
  // Dropdown content: search + list (same content pattern as Select)
8944
8853
  var content = document.createElement("div");
8945
8854
  content.setAttribute("role", "listbox");
8946
- content.className = contentBase + (usePopover ? "max-h-[30vh] overflow-hidden flex flex-col" : "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0");
8855
+ content.className = "record-select-content max-h-[30vh] overflow-hidden flex flex-col";
8947
8856
 
8948
8857
  var searchWrap = document.createElement("div");
8949
8858
  searchWrap.className = "py-8 border-b-1/2 border-border-primary";
@@ -9010,57 +8919,51 @@
9010
8919
 
9011
8920
  content.appendChild(optionsList);
9012
8921
 
9013
- if (!usePopover) {
9014
- container.appendChild(content);
9015
- }
9016
-
9017
- if (usePopover) {
9018
- popover = Popover.create({
9019
- trigger: trigger,
9020
- content: content,
9021
- placement: "bottom",
9022
- align: "start",
9023
- closeOnClickOutside: true,
9024
- bodyClassName: "p-0 overflow-hidden",
9025
- panelClassName: "max-h-[30vh] overflow-hidden",
9026
- onOpen: function () {
9027
- if (disabled) {
9028
- popover.hide();
9029
- return;
9030
- }
9031
- document.querySelectorAll(".custom-select.open, .record-select.open").forEach(function (other) {
9032
- if (other !== container) {
9033
- other.classList.remove("open");
9034
- var t = other.querySelector("button, .custom-select-trigger, .record-select-trigger");
9035
- if (t) t.setAttribute("aria-expanded", "false");
9036
- }
9037
- });
9038
- isOpen = true;
9039
- container.classList.add("open");
9040
- trigger.setAttribute("aria-expanded", "true");
9041
- searchTerm = "";
9042
- if (searchInputWrapper) searchInputWrapper.setValue("");
9043
- else if (searchInputEl) searchInputEl.value = "";
9044
- content.style.minWidth = trigger.offsetWidth + "px";
9045
- loadInitialAndRender();
9046
- setTimeout(function () {
9047
- if (searchInputEl) searchInputEl.focus();
9048
- }, 0);
9049
- },
9050
- onClose: function () {
9051
- isOpen = false;
9052
- container.classList.remove("open");
9053
- trigger.setAttribute("aria-expanded", "false");
9054
- searchTerm = "";
9055
- if (searchInputWrapper) searchInputWrapper.setValue("");
9056
- else if (searchInputEl) searchInputEl.value = "";
9057
- if (searchDebounceTimer) {
9058
- clearTimeout(searchDebounceTimer);
9059
- searchDebounceTimer = null;
8922
+ popover = Popover.create({
8923
+ trigger: trigger,
8924
+ content: content,
8925
+ placement: "bottom",
8926
+ align: "start",
8927
+ closeOnClickOutside: true,
8928
+ bodyClassName: "p-0 overflow-hidden",
8929
+ panelClassName: "max-h-[30vh] overflow-hidden",
8930
+ onOpen: function () {
8931
+ if (disabled) {
8932
+ popover.hide();
8933
+ return;
8934
+ }
8935
+ document.querySelectorAll(".custom-select.open, .record-select.open").forEach(function (other) {
8936
+ if (other !== container) {
8937
+ other.classList.remove("open");
8938
+ var t = other.querySelector("button, .custom-select-trigger, .record-select-trigger");
8939
+ if (t) t.setAttribute("aria-expanded", "false");
9060
8940
  }
9061
- },
9062
- });
9063
- }
8941
+ });
8942
+ isOpen = true;
8943
+ container.classList.add("open");
8944
+ trigger.setAttribute("aria-expanded", "true");
8945
+ searchTerm = "";
8946
+ if (searchInputWrapper) searchInputWrapper.setValue("");
8947
+ else if (searchInputEl) searchInputEl.value = "";
8948
+ content.style.minWidth = trigger.offsetWidth + "px";
8949
+ loadInitialAndRender();
8950
+ setTimeout(function () {
8951
+ if (searchInputEl) searchInputEl.focus();
8952
+ }, 0);
8953
+ },
8954
+ onClose: function () {
8955
+ isOpen = false;
8956
+ container.classList.remove("open");
8957
+ trigger.setAttribute("aria-expanded", "false");
8958
+ searchTerm = "";
8959
+ if (searchInputWrapper) searchInputWrapper.setValue("");
8960
+ else if (searchInputEl) searchInputEl.value = "";
8961
+ if (searchDebounceTimer) {
8962
+ clearTimeout(searchDebounceTimer);
8963
+ searchDebounceTimer = null;
8964
+ }
8965
+ },
8966
+ });
9064
8967
 
9065
8968
  if (clearBtn) clearBtn.style.display = canClear && value && !disabled ? "" : "none";
9066
8969
 
@@ -9456,64 +9359,8 @@
9456
9359
  }, 500);
9457
9360
  }
9458
9361
 
9459
- function openDropdown() {
9460
- if (disabled) return;
9461
- if (usePopover && popover) {
9462
- popover.show();
9463
- return;
9464
- }
9465
- document
9466
- .querySelectorAll(".custom-select.open, .record-select.open")
9467
- .forEach(function (other) {
9468
- if (other !== container) {
9469
- other.classList.remove("open");
9470
- var t = other.querySelector(
9471
- "button, .custom-select-trigger, .record-select-trigger"
9472
- );
9473
- if (t) t.setAttribute("aria-expanded", "false");
9474
- }
9475
- });
9476
- isOpen = true;
9477
- container.classList.add("open");
9478
- trigger.setAttribute("aria-expanded", "true");
9479
- searchTerm = "";
9480
- if (searchInputWrapper) searchInputWrapper.setValue("");
9481
- else if (searchInputEl) searchInputEl.value = "";
9482
- loadInitialAndRender();
9483
- setTimeout(function () {
9484
- if (searchInputEl) searchInputEl.focus();
9485
- }, 0);
9486
- updatePosition();
9487
- }
9488
-
9489
9362
  function closeDropdown() {
9490
- if (usePopover && popover) {
9491
- popover.hide();
9492
- return;
9493
- }
9494
- isOpen = false;
9495
- container.classList.remove("open");
9496
- trigger.setAttribute("aria-expanded", "false");
9497
- searchTerm = "";
9498
- if (searchInputWrapper) searchInputWrapper.setValue("");
9499
- else if (searchInputEl) searchInputEl.value = "";
9500
- if (searchDebounceTimer) {
9501
- clearTimeout(searchDebounceTimer);
9502
- searchDebounceTimer = null;
9503
- }
9504
- }
9505
-
9506
- function updatePosition() {
9507
- if (usePopover) return;
9508
- var rect = trigger.getBoundingClientRect();
9509
- var vh = window.innerHeight;
9510
- var below = vh - rect.bottom;
9511
- var above = rect.top;
9512
- if (below < 200 && above > below) {
9513
- content.className = contentBase + "bottom-full mb-1 translate-y-1 group-[.open]:translate-y-0";
9514
- } else {
9515
- content.className = contentBase + "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
9516
- }
9363
+ popover.hide();
9517
9364
  }
9518
9365
 
9519
9366
  if (!searchInputWrapper && searchInputEl) {
@@ -9532,41 +9379,14 @@
9532
9379
  });
9533
9380
  }
9534
9381
 
9535
- if (usePopover && popover) {
9536
- trigger.addEventListener("keydown", function (e) {
9537
- if (disabled) return;
9538
- if (e.key === "Enter" || e.key === " ") {
9539
- e.preventDefault();
9540
- if (isOpen) popover.hide();
9541
- else popover.show();
9542
- }
9543
- });
9544
- } else {
9545
- trigger.addEventListener("click", function (e) {
9382
+ trigger.addEventListener("keydown", function (e) {
9383
+ if (disabled) return;
9384
+ if (e.key === "Enter" || e.key === " ") {
9546
9385
  e.preventDefault();
9547
- e.stopPropagation();
9548
- if (isOpen) closeDropdown();
9549
- else openDropdown();
9550
- });
9551
- trigger.addEventListener("keydown", function (e) {
9552
- if (disabled) return;
9553
- if (e.key === "Enter" || e.key === " ") {
9554
- e.preventDefault();
9555
- if (isOpen) closeDropdown();
9556
- else openDropdown();
9557
- }
9558
- if (e.key === "Escape" && isOpen) {
9559
- e.preventDefault();
9560
- closeDropdown();
9561
- }
9562
- });
9563
- document.addEventListener("click", function (e) {
9564
- if (isOpen && !container.contains(e.target)) closeDropdown();
9565
- });
9566
- document.addEventListener("keydown", function (e) {
9567
- if (e.key === "Escape" && isOpen) closeDropdown();
9568
- });
9569
- }
9386
+ if (isOpen) popover.hide();
9387
+ else popover.show();
9388
+ }
9389
+ });
9570
9390
 
9571
9391
  container.updateValue = function (newVal) {
9572
9392
  setValue(newVal);
@@ -9663,6 +9483,14 @@
9663
9483
  return opt.label || opt.name || opt.display_name || opt.value;
9664
9484
  }
9665
9485
 
9486
+ function getDep(name) {
9487
+ if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
9488
+ var c = global.FlowUI._getComponent(name);
9489
+ if (c) return c;
9490
+ }
9491
+ return global[name];
9492
+ }
9493
+
9666
9494
  /**
9667
9495
  * Create a multiselect dropdown component
9668
9496
  * @param {Object} config
@@ -9693,6 +9521,11 @@
9693
9521
  ? config.values.slice()
9694
9522
  : [];
9695
9523
 
9524
+ var Popover = getDep("Popover");
9525
+ if (!Popover || typeof Popover.create !== "function") {
9526
+ throw new Error("MultiSelect requires Popover");
9527
+ }
9528
+
9696
9529
  var container = document.createElement("div");
9697
9530
  container.className = "custom-multiselect relative w-full group";
9698
9531
  if (fieldId) container.setAttribute("data-field-id", fieldId);
@@ -9741,14 +9574,10 @@
9741
9574
  triggerWrapper.appendChild(trigger);
9742
9575
  container.appendChild(triggerWrapper);
9743
9576
 
9744
- var contentBase =
9745
- "custom-multiselect-content absolute left-0 right-0 z-50 max-h-[200px] min-w-[8rem] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium opacity-0 invisible transition-all duration-150 ease-out " +
9746
- "group-[.open]:opacity-100 group-[.open]:visible ";
9747
-
9748
9577
  var content = document.createElement("div");
9749
9578
  content.setAttribute("role", "listbox");
9750
9579
  content.setAttribute("aria-multiselectable", "true");
9751
- content.className = contentBase + "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
9580
+ content.className = "custom-multiselect-content w-full max-h-[200px] overflow-hidden flex flex-col";
9752
9581
 
9753
9582
  var optionsList = document.createElement("div");
9754
9583
  optionsList.className =
@@ -9849,47 +9678,68 @@
9849
9678
  buildOptionsList();
9850
9679
 
9851
9680
  content.appendChild(optionsList);
9852
- container.appendChild(content);
9853
9681
 
9854
- var isOpen = false;
9682
+ var popover = Popover.create({
9683
+ trigger: trigger,
9684
+ content: content,
9685
+ placement: "bottom",
9686
+ align: "start",
9687
+ closeOnClickOutside: true,
9688
+ bodyClassName: "p-0 overflow-hidden",
9689
+ panelClassName: "min-w-[var(--trigger-width)] max-h-[200px] overflow-hidden",
9690
+ onOpen: function () {
9691
+ if (disabled) {
9692
+ popover.hide();
9693
+ return;
9694
+ }
9695
+ document
9696
+ .querySelectorAll(".custom-select, .record-select, .custom-multiselect, .enum-select, .enum-multiselect, .record-multiselect")
9697
+ .forEach(function (other) {
9698
+ if (other !== container && other.popoverInstance) {
9699
+ other.popoverInstance.hide();
9700
+ }
9701
+ });
9702
+ trigger.setAttribute("aria-expanded", "true");
9703
+ chevron.style.transform = "rotate(180deg)";
9704
+ if (popover.panel) {
9705
+ var triggerWidthPx = trigger.offsetWidth + "px";
9706
+ popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
9707
+ popover.panel.style.minWidth = triggerWidthPx;
9708
+ popover.panel.style.width = triggerWidthPx;
9709
+ }
9710
+ },
9711
+ onClose: function () {
9712
+ trigger.setAttribute("aria-expanded", "false");
9713
+ chevron.style.transform = "";
9714
+ },
9715
+ });
9716
+ container.popoverInstance = popover;
9855
9717
 
9856
9718
  function openDropdown() {
9857
9719
  if (disabled) return;
9858
- document
9859
- .querySelectorAll(".custom-select.open, .record-select.open, .custom-multiselect.open")
9860
- .forEach(function (other) {
9861
- if (other !== container) {
9862
- other.classList.remove("open");
9863
- var t = other.querySelector(
9864
- "button, .custom-select-trigger, .record-select-trigger, .multiselect-trigger-wrapper button"
9865
- );
9866
- if (t) t.setAttribute("aria-expanded", "false");
9867
- }
9868
- });
9869
- isOpen = true;
9870
- container.classList.add("open");
9871
- trigger.setAttribute("aria-expanded", "true");
9720
+ popover.show();
9872
9721
  }
9873
9722
 
9874
9723
  function closeDropdown() {
9875
- isOpen = false;
9876
- container.classList.remove("open");
9877
- trigger.setAttribute("aria-expanded", "false");
9724
+ popover.hide();
9878
9725
  }
9879
9726
 
9880
9727
  function toggleDropdown() {
9881
- if (isOpen) closeDropdown();
9728
+ var isVisible = popover.element && popover.element.classList.contains("visible");
9729
+ if (isVisible) closeDropdown();
9882
9730
  else openDropdown();
9883
9731
  }
9884
9732
 
9885
9733
  trigger.addEventListener("click", function (e) {
9886
- e.preventDefault();
9887
- e.stopPropagation();
9888
- toggleDropdown();
9889
- });
9734
+ if (disabled) {
9735
+ e.preventDefault();
9736
+ e.stopImmediatePropagation();
9737
+ }
9738
+ }, true);
9890
9739
 
9891
9740
  trigger.addEventListener("keydown", function (e) {
9892
9741
  if (disabled) return;
9742
+ var isVisible = popover.element && popover.element.classList.contains("visible");
9893
9743
  switch (e.key) {
9894
9744
  case "Enter":
9895
9745
  case " ":
@@ -9898,14 +9748,14 @@
9898
9748
  break;
9899
9749
  case "ArrowDown":
9900
9750
  e.preventDefault();
9901
- if (!isOpen) openDropdown();
9751
+ if (!isVisible) openDropdown();
9902
9752
  break;
9903
9753
  case "ArrowUp":
9904
9754
  e.preventDefault();
9905
- if (!isOpen) openDropdown();
9755
+ if (!isVisible) openDropdown();
9906
9756
  break;
9907
9757
  case "Escape":
9908
- if (isOpen) {
9758
+ if (isVisible) {
9909
9759
  e.preventDefault();
9910
9760
  closeDropdown();
9911
9761
  }
@@ -9913,13 +9763,6 @@
9913
9763
  }
9914
9764
  });
9915
9765
 
9916
- document.addEventListener("click", function (e) {
9917
- if (isOpen && !container.contains(e.target)) closeDropdown();
9918
- });
9919
- document.addEventListener("keydown", function (e) {
9920
- if (e.key === "Escape" && isOpen) closeDropdown();
9921
- });
9922
-
9923
9766
  container.updateValues = function (newValues) {
9924
9767
  values = Array.isArray(newValues) ? newValues.slice() : [];
9925
9768
  renderTriggerContent();
@@ -9938,7 +9781,8 @@
9938
9781
  disabled = !!isDisabled;
9939
9782
  trigger.disabled = disabled;
9940
9783
  trigger.className = triggerClasses(variant, size, disabled, values.length === 0);
9941
- if (disabled && isOpen) closeDropdown();
9784
+ var isVisible = popover.element && popover.element.classList.contains("visible");
9785
+ if (disabled && isVisible) closeDropdown();
9942
9786
  };
9943
9787
 
9944
9788
  container.getValues = function () {
@@ -10036,6 +9880,14 @@
10036
9880
  return Array.prototype.filter.call(arguments, Boolean).join(" ");
10037
9881
  }
10038
9882
 
9883
+ function getDep(name) {
9884
+ if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
9885
+ var c = global.FlowUI._getComponent(name);
9886
+ if (c) return c;
9887
+ }
9888
+ return global[name];
9889
+ }
9890
+
10039
9891
  /** Resolve client: use FlowUI._getComponent when bundle has captured globals, else global.superleapClient */
10040
9892
  function getClient() {
10041
9893
  if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
@@ -10104,8 +9956,10 @@
10104
9956
  var error = null;
10105
9957
  var searchQuery = "";
10106
9958
  var popover = null;
10107
- var usePopover = !!(global.Popover && typeof global.Popover.create === "function");
10108
- var isOpen = false;
9959
+ var Popover = getDep("Popover");
9960
+ if (!Popover || typeof Popover.create !== "function") {
9961
+ throw new Error("EnumMultiSelect requires Popover");
9962
+ }
10109
9963
 
10110
9964
  var container = document.createElement("div");
10111
9965
  container.className = "enum-multiselect relative w-full group";
@@ -10207,13 +10061,7 @@
10207
10061
  var content = document.createElement("div");
10208
10062
  content.setAttribute("role", "listbox");
10209
10063
  content.setAttribute("aria-multiselectable", "true");
10210
- var contentBase = "w-full min-w-[200px]";
10211
- if (!usePopover) {
10212
- contentBase += " absolute left-0 right-0 z-50 max-h-[30vh] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium border-1/2 border-border-primary opacity-0 invisible transition-all duration-150 ease-out group-[.open]:opacity-100 group-[.open]:visible top-full mt-1 -translate-y-1 group-[.open]:translate-y-0 flex flex-col";
10213
- } else {
10214
- contentBase += " max-h-[30vh] overflow-hidden flex flex-col";
10215
- }
10216
- content.className = contentBase;
10064
+ content.className = "w-full min-w-[200px] max-h-[30vh] overflow-hidden flex flex-col";
10217
10065
 
10218
10066
  // Search input (using InputComponent like enum-select)
10219
10067
  var searchContainer = document.createElement("div");
@@ -10279,10 +10127,6 @@
10279
10127
  content.appendChild(searchContainer);
10280
10128
  content.appendChild(optionsList);
10281
10129
 
10282
- if (!usePopover) {
10283
- container.appendChild(content);
10284
- }
10285
-
10286
10130
  var highlightedIndex = -1;
10287
10131
 
10288
10132
  function showLoading() {
@@ -10455,34 +10299,14 @@
10455
10299
 
10456
10300
  function openDropdown() {
10457
10301
  if (disabled) return;
10458
- if (popover) {
10459
- document
10460
- .querySelectorAll(".enum-select, .enum-multiselect, .custom-select, .record-select, .custom-multiselect")
10461
- .forEach(function (other) {
10462
- if (other !== container && other.popoverInstance) {
10463
- other.popoverInstance.hide();
10464
- }
10465
- });
10466
- popover.show();
10467
- trigger.setAttribute("aria-expanded", "true");
10468
- if (searchInput) {
10469
- setTimeout(function () {
10470
- searchInput.focus();
10471
- }, 50);
10472
- }
10473
- return;
10474
- }
10475
10302
  document
10476
- .querySelectorAll(".enum-multiselect.open, .enum-select.open")
10303
+ .querySelectorAll(".enum-select, .enum-multiselect, .custom-select, .record-select, .custom-multiselect")
10477
10304
  .forEach(function (other) {
10478
- if (other !== container) {
10479
- other.classList.remove("open");
10480
- var t = other.querySelector("button");
10481
- if (t) t.setAttribute("aria-expanded", "false");
10305
+ if (other !== container && other.popoverInstance) {
10306
+ other.popoverInstance.hide();
10482
10307
  }
10483
10308
  });
10484
- isOpen = true;
10485
- container.classList.add("open");
10309
+ popover.show();
10486
10310
  trigger.setAttribute("aria-expanded", "true");
10487
10311
  if (searchInput) {
10488
10312
  setTimeout(function () {
@@ -10492,12 +10316,7 @@
10492
10316
  }
10493
10317
 
10494
10318
  function closeDropdown() {
10495
- if (popover) {
10496
- popover.hide();
10497
- } else {
10498
- isOpen = false;
10499
- container.classList.remove("open");
10500
- }
10319
+ popover.hide();
10501
10320
  trigger.setAttribute("aria-expanded", "false");
10502
10321
  highlightedIndex = -1;
10503
10322
  clearSearch();
@@ -10505,9 +10324,7 @@
10505
10324
  }
10506
10325
 
10507
10326
  function toggleDropdown() {
10508
- var isVisible = popover
10509
- ? popover.element && popover.element.classList.contains("visible")
10510
- : isOpen;
10327
+ var isVisible = popover.element && popover.element.classList.contains("visible");
10511
10328
  if (isVisible) {
10512
10329
  closeDropdown();
10513
10330
  } else {
@@ -10587,10 +10404,7 @@
10587
10404
 
10588
10405
  // Initialize Popover
10589
10406
  function initializePopover() {
10590
- if (!usePopover) {
10591
- return;
10592
- }
10593
- popover = global.Popover.create({
10407
+ popover = Popover.create({
10594
10408
  trigger: trigger,
10595
10409
  content: content,
10596
10410
  placement: "bottom",
@@ -10606,6 +10420,12 @@
10606
10420
  onOpen: function () {
10607
10421
  trigger.setAttribute("aria-expanded", "true");
10608
10422
  chevron.style.transform = "rotate(180deg)";
10423
+ if (popover.panel) {
10424
+ var triggerWidthPx = trigger.offsetWidth + "px";
10425
+ popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
10426
+ popover.panel.style.minWidth = triggerWidthPx;
10427
+ popover.panel.style.width = triggerWidthPx;
10428
+ }
10609
10429
  },
10610
10430
  bodyClassName: "p-0 overflow-hidden",
10611
10431
  panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
@@ -10613,13 +10433,6 @@
10613
10433
 
10614
10434
  // Store popover instance for cleanup
10615
10435
  container.popoverInstance = popover;
10616
-
10617
- // Set CSS variable for trigger width
10618
- var triggerWidth = trigger.offsetWidth;
10619
- if (popover.panel) {
10620
- popover.panel.style.setProperty("--trigger-width", triggerWidth + "px");
10621
- popover.panel.style.minWidth = triggerWidth + "px";
10622
- }
10623
10436
  }
10624
10437
 
10625
10438
  // Load options from SDK
@@ -10734,21 +10547,6 @@
10734
10547
  initializePopover();
10735
10548
  loadOptions();
10736
10549
 
10737
- if (!usePopover) {
10738
- trigger.addEventListener("click", function (e) {
10739
- e.preventDefault();
10740
- e.stopPropagation();
10741
- if (disabled) return;
10742
- toggleDropdown();
10743
- });
10744
- document.addEventListener("click", function (e) {
10745
- if (isOpen && !container.contains(e.target)) closeDropdown();
10746
- });
10747
- document.addEventListener("keydown", function (e) {
10748
- if (e.key === "Escape" && isOpen) closeDropdown();
10749
- });
10750
- }
10751
-
10752
10550
  // Public API
10753
10551
  container.updateValues = function (newValues) {
10754
10552
  values = Array.isArray(newValues) ? newValues.slice() : [];
@@ -10790,7 +10588,7 @@
10790
10588
  );
10791
10589
  updateClearButton();
10792
10590
  var isVisible = popover && popover.element && popover.element.classList.contains("visible");
10793
- if (disabled && (isVisible || isOpen)) closeDropdown();
10591
+ if (disabled && isVisible) closeDropdown();
10794
10592
  };
10795
10593
 
10796
10594
  container.reload = function () {
@@ -10840,7 +10638,14 @@
10840
10638
 
10841
10639
  (function (global) {
10842
10640
 
10843
- var Popover = global.Popover;
10641
+ function getDep(name) {
10642
+ if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
10643
+ var c = global.FlowUI._getComponent(name);
10644
+ if (c) return c;
10645
+ }
10646
+ return global[name];
10647
+ }
10648
+
10844
10649
  var InputComponent = global.InputComponent;
10845
10650
  var Spinner = global.Spinner;
10846
10651
 
@@ -10853,7 +10658,7 @@
10853
10658
  role: { iconStr: "IconShield", color: "info" },
10854
10659
  iframe: { iconStr: "IconLayout", color: "neutral" },
10855
10660
  lead: { iconStr: "IconUser", color: "primary" },
10856
- opportunity: { iconStr: "IconCurrencyDollar", color: "success" },
10661
+ opportunity: { iconStr: "IconStar", color: "success" },
10857
10662
  call_log: { iconStr: "IconPhone", color: "info" },
10858
10663
  communication: { iconStr: "IconMessage", color: "primary" },
10859
10664
  history_field: { iconStr: "IconClock", color: "neutral" },
@@ -11013,19 +10818,13 @@
11013
10818
  var selectedRecords = [];
11014
10819
  var allRecords = [];
11015
10820
  var filteredRecords = [];
11016
- var isOpen = false;
11017
10821
  var searchTerm = "";
11018
10822
  var searchDebounceTimer = null;
11019
- var usePopover = Popover && typeof Popover.create === "function";
11020
10823
  var popover = null;
11021
10824
  var hasMoreRecords = true;
11022
10825
  var currentPage = 1;
11023
10826
  var isFetchingMore = false;
11024
10827
  var totalFetched = 0;
11025
- var contentBase = "record-multiselect-content min-w-[8rem] ";
11026
- if (!usePopover) {
11027
- contentBase += "absolute left-0 right-0 z-50 max-h-[30vh] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium opacity-0 invisible transition-all duration-150 ease-out group-[.open]:opacity-100 group-[.open]:visible ";
11028
- }
11029
10828
 
11030
10829
  // Trigger wrapper + button
11031
10830
  var triggerWrapper = document.createElement("span");
@@ -11120,7 +10919,7 @@
11120
10919
  var content = document.createElement("div");
11121
10920
  content.setAttribute("role", "listbox");
11122
10921
  content.setAttribute("aria-multiselectable", "true");
11123
- content.className = contentBase + (usePopover ? "max-h-[30vh] overflow-hidden flex flex-col" : "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0");
10922
+ content.className = "record-multiselect-content max-h-[30vh] overflow-hidden flex flex-col";
11124
10923
 
11125
10924
  var searchWrap = document.createElement("div");
11126
10925
  searchWrap.className = "p-8 pb-4 border-b-1/2 border-border-primary ";
@@ -11187,57 +10986,58 @@
11187
10986
 
11188
10987
  content.appendChild(optionsList);
11189
10988
 
11190
- if (!usePopover) {
11191
- container.appendChild(content);
10989
+ var Popover = getDep("Popover");
10990
+ if (!Popover || typeof Popover.create !== "function") {
10991
+ throw new Error("RecordMultiSelect requires Popover");
11192
10992
  }
11193
-
11194
- if (usePopover) {
11195
- popover = Popover.create({
11196
- trigger: trigger,
11197
- content: content,
11198
- placement: "bottom",
11199
- align: "start",
11200
- closeOnClickOutside: true,
11201
- bodyClassName: "p-0 overflow-hidden",
11202
- panelClassName: "max-h-[30vh] overflow-hidden",
11203
- onOpen: function () {
11204
- if (disabled) {
11205
- popover.hide();
11206
- return;
11207
- }
11208
- document.querySelectorAll(".custom-select.open, .record-select.open, .custom-multiselect.open, .record-multiselect.open").forEach(function (other) {
11209
- if (other !== container) {
11210
- other.classList.remove("open");
11211
- var t = other.querySelector("button, .custom-select-trigger, .record-select-trigger, .multiselect-trigger-wrapper button, .record-multiselect-trigger");
11212
- if (t) t.setAttribute("aria-expanded", "false");
11213
- }
11214
- });
11215
- isOpen = true;
11216
- container.classList.add("open");
11217
- trigger.setAttribute("aria-expanded", "true");
11218
- searchTerm = "";
11219
- if (searchInputWrapper) searchInputWrapper.setValue("");
11220
- else if (searchInputEl) searchInputEl.value = "";
11221
- content.style.minWidth = trigger.offsetWidth + "px";
11222
- loadInitialAndRender();
11223
- setTimeout(function () {
11224
- if (searchInputEl) searchInputEl.focus();
11225
- }, 0);
11226
- },
11227
- onClose: function () {
11228
- isOpen = false;
11229
- container.classList.remove("open");
11230
- trigger.setAttribute("aria-expanded", "false");
11231
- searchTerm = "";
11232
- if (searchInputWrapper) searchInputWrapper.setValue("");
11233
- else if (searchInputEl) searchInputEl.value = "";
11234
- if (searchDebounceTimer) {
11235
- clearTimeout(searchDebounceTimer);
11236
- searchDebounceTimer = null;
10993
+ popover = Popover.create({
10994
+ trigger: trigger,
10995
+ content: content,
10996
+ placement: "bottom",
10997
+ align: "start",
10998
+ closeOnClickOutside: true,
10999
+ bodyClassName: "p-0 overflow-hidden",
11000
+ panelClassName: "max-h-[30vh] overflow-hidden",
11001
+ onOpen: function () {
11002
+ if (disabled) {
11003
+ popover.hide();
11004
+ return;
11005
+ }
11006
+ document.querySelectorAll(".custom-select.open, .record-select.open, .custom-multiselect.open, .record-multiselect.open, .enum-select, .enum-multiselect").forEach(function (other) {
11007
+ if (other !== container && other.popoverInstance) {
11008
+ other.popoverInstance.hide();
11237
11009
  }
11238
- },
11239
- });
11240
- }
11010
+ });
11011
+ container.classList.add("open");
11012
+ trigger.setAttribute("aria-expanded", "true");
11013
+ searchTerm = "";
11014
+ if (searchInputWrapper) searchInputWrapper.setValue("");
11015
+ else if (searchInputEl) searchInputEl.value = "";
11016
+ var triggerWidthPx = trigger.offsetWidth + "px";
11017
+ content.style.minWidth = triggerWidthPx;
11018
+ content.style.width = triggerWidthPx;
11019
+ if (popover.panel) {
11020
+ popover.panel.style.width = triggerWidthPx;
11021
+ popover.panel.style.minWidth = triggerWidthPx;
11022
+ }
11023
+ loadInitialAndRender();
11024
+ setTimeout(function () {
11025
+ if (searchInputEl) searchInputEl.focus();
11026
+ }, 0);
11027
+ },
11028
+ onClose: function () {
11029
+ container.classList.remove("open");
11030
+ trigger.setAttribute("aria-expanded", "false");
11031
+ searchTerm = "";
11032
+ if (searchInputWrapper) searchInputWrapper.setValue("");
11033
+ else if (searchInputEl) searchInputEl.value = "";
11034
+ if (searchDebounceTimer) {
11035
+ clearTimeout(searchDebounceTimer);
11036
+ searchDebounceTimer = null;
11037
+ }
11038
+ },
11039
+ });
11040
+ container.popoverInstance = popover;
11241
11041
 
11242
11042
  function isSelected(recordId) {
11243
11043
  return values.some(function (v) {
@@ -11642,66 +11442,6 @@
11642
11442
  }, 500);
11643
11443
  }
11644
11444
 
11645
- function openDropdown() {
11646
- if (disabled) return;
11647
- if (usePopover && popover) {
11648
- popover.show();
11649
- return;
11650
- }
11651
- document
11652
- .querySelectorAll(".custom-select.open, .record-select.open, .custom-multiselect.open, .record-multiselect.open")
11653
- .forEach(function (other) {
11654
- if (other !== container) {
11655
- other.classList.remove("open");
11656
- var t = other.querySelector(
11657
- "button, .custom-select-trigger, .record-select-trigger, .multiselect-trigger-wrapper button, .record-multiselect-trigger"
11658
- );
11659
- if (t) t.setAttribute("aria-expanded", "false");
11660
- }
11661
- });
11662
- isOpen = true;
11663
- container.classList.add("open");
11664
- trigger.setAttribute("aria-expanded", "true");
11665
- searchTerm = "";
11666
- if (searchInputWrapper) searchInputWrapper.setValue("");
11667
- else if (searchInputEl) searchInputEl.value = "";
11668
- loadInitialAndRender();
11669
- setTimeout(function () {
11670
- if (searchInputEl) searchInputEl.focus();
11671
- }, 0);
11672
- updatePosition();
11673
- }
11674
-
11675
- function closeDropdown() {
11676
- if (usePopover && popover) {
11677
- popover.hide();
11678
- return;
11679
- }
11680
- isOpen = false;
11681
- container.classList.remove("open");
11682
- trigger.setAttribute("aria-expanded", "false");
11683
- searchTerm = "";
11684
- if (searchInputWrapper) searchInputWrapper.setValue("");
11685
- else if (searchInputEl) searchInputEl.value = "";
11686
- if (searchDebounceTimer) {
11687
- clearTimeout(searchDebounceTimer);
11688
- searchDebounceTimer = null;
11689
- }
11690
- }
11691
-
11692
- function updatePosition() {
11693
- if (usePopover) return;
11694
- var rect = trigger.getBoundingClientRect();
11695
- var vh = window.innerHeight;
11696
- var below = vh - rect.bottom;
11697
- var above = rect.top;
11698
- if (below < 200 && above > below) {
11699
- content.className = contentBase + "bottom-full mb-1 translate-y-1 group-[.open]:translate-y-0";
11700
- } else {
11701
- content.className = contentBase + "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
11702
- }
11703
- }
11704
-
11705
11445
  if (!searchInputWrapper && searchInputEl) {
11706
11446
  searchInputEl.addEventListener("input", function () {
11707
11447
  searchTerm = this.value.trim();
@@ -11718,41 +11458,19 @@
11718
11458
  });
11719
11459
  }
11720
11460
 
11721
- if (usePopover && popover) {
11722
- trigger.addEventListener("keydown", function (e) {
11723
- if (disabled) return;
11724
- if (e.key === "Enter" || e.key === " ") {
11725
- e.preventDefault();
11726
- if (isOpen) popover.hide();
11727
- else popover.show();
11728
- }
11729
- });
11730
- } else {
11731
- trigger.addEventListener("click", function (e) {
11461
+ trigger.addEventListener("keydown", function (e) {
11462
+ if (disabled) return;
11463
+ var isVisible = popover.element && popover.element.classList.contains("visible");
11464
+ if (e.key === "Enter" || e.key === " ") {
11732
11465
  e.preventDefault();
11733
- e.stopPropagation();
11734
- if (isOpen) closeDropdown();
11735
- else openDropdown();
11736
- });
11737
- trigger.addEventListener("keydown", function (e) {
11738
- if (disabled) return;
11739
- if (e.key === "Enter" || e.key === " ") {
11740
- e.preventDefault();
11741
- if (isOpen) closeDropdown();
11742
- else openDropdown();
11743
- }
11744
- if (e.key === "Escape" && isOpen) {
11745
- e.preventDefault();
11746
- closeDropdown();
11747
- }
11748
- });
11749
- document.addEventListener("click", function (e) {
11750
- if (isOpen && !container.contains(e.target)) closeDropdown();
11751
- });
11752
- document.addEventListener("keydown", function (e) {
11753
- if (e.key === "Escape" && isOpen) closeDropdown();
11754
- });
11755
- }
11466
+ if (isVisible) popover.hide();
11467
+ else popover.show();
11468
+ }
11469
+ if (e.key === "Escape" && isVisible) {
11470
+ e.preventDefault();
11471
+ popover.hide();
11472
+ }
11473
+ });
11756
11474
 
11757
11475
  container.updateValues = function (newValues) {
11758
11476
  values = Array.isArray(newValues) ? newValues.slice() : [];
@@ -11763,7 +11481,8 @@
11763
11481
  disabled = !!isDisabled;
11764
11482
  trigger.disabled = disabled;
11765
11483
  trigger.className = triggerClasses(variant, size, disabled, values.length === 0);
11766
- if (disabled && isOpen) closeDropdown();
11484
+ var isVisible = popover.element && popover.element.classList.contains("visible");
11485
+ if (disabled && isVisible) popover.hide();
11767
11486
  };
11768
11487
 
11769
11488
  container.getValues = function () {
@@ -13596,12 +13315,12 @@
13596
13315
  if (periodColumn) periodColumn.scrollToSelected();
13597
13316
  }
13598
13317
 
13318
+ // Trigger must be in DOM before Popover.create() so Popover can wrap it and insert its panel into the document.
13319
+ container.appendChild(trigger);
13320
+
13599
13321
  var Popover = getDep("Popover");
13600
13322
  if (!Popover || typeof Popover.create !== "function") {
13601
- container.appendChild(trigger);
13602
- container.updateValue = function (newVal) { value = typeof newVal === "string" ? newVal : ""; };
13603
- container.setDisabled = function (isDisabled) { trigger.disabled = !!isDisabled; };
13604
- return container;
13323
+ throw new Error("TimePicker requires Popover");
13605
13324
  }
13606
13325
  var popover = Popover.create({
13607
13326
  trigger: trigger,
@@ -13622,8 +13341,6 @@
13622
13341
  });
13623
13342
  hidePopover = popover.hide;
13624
13343
 
13625
- container.appendChild(trigger);
13626
-
13627
13344
  container.updateValue = function (newVal) {
13628
13345
  value = typeof newVal === "string" ? newVal : "";
13629
13346
  var p = parseValue(value);
@@ -14771,7 +14488,7 @@
14771
14488
  variant = "outline";
14772
14489
  }
14773
14490
  var btnClassName = join(
14774
- "!text-reg-12 my-2 flex-1 !px-0 !py-0",
14491
+ "!text-reg-12 my-2 flex-1",
14775
14492
  cell.currentMonth ? "" : "text-typography-quaternary-text"
14776
14493
  );
14777
14494
  var btn = Button.create({
@@ -15916,15 +15633,13 @@
15916
15633
  e.stopPropagation();
15917
15634
  navigator.clipboard.writeText(fileUrl).then(
15918
15635
  function () {
15919
- if (global.FlowUI && global.FlowUI.renderAlerts) {
15920
- const ac = document.getElementById("alerts");
15921
- if (ac) global.FlowUI.renderAlerts(ac, ["Link copied"], "success");
15636
+ if (global.FlowUI && global.FlowUI.showToast) {
15637
+ global.FlowUI.showToast("Link copied", "success");
15922
15638
  }
15923
15639
  },
15924
15640
  function () {
15925
- if (global.FlowUI && global.FlowUI.renderAlerts) {
15926
- const ac = document.getElementById("alerts");
15927
- if (ac) global.FlowUI.renderAlerts(ac, ["Copy failed"], "error");
15641
+ if (global.FlowUI && global.FlowUI.showToast) {
15642
+ global.FlowUI.showToast("Copy failed", "error");
15928
15643
  }
15929
15644
  }
15930
15645
  );
@@ -16120,11 +15835,8 @@
16120
15835
  async function uploadFile(file) {
16121
15836
  const error = validateFile(file);
16122
15837
  if (error) {
16123
- if (global.FlowUI && global.FlowUI.renderAlerts) {
16124
- const alertsContainer = document.getElementById("alerts");
16125
- if (alertsContainer) {
16126
- global.FlowUI.renderAlerts(alertsContainer, [error], "error");
16127
- }
15838
+ if (global.FlowUI && global.FlowUI.showToast) {
15839
+ global.FlowUI.showToast(error, "error");
16128
15840
  }
16129
15841
  return;
16130
15842
  }
@@ -16152,15 +15864,8 @@
16152
15864
  uploadingFiles = uploadingFiles.filter((f) => f.file !== file);
16153
15865
  renderUploadingList();
16154
15866
  updateStatus();
16155
- if (global.FlowUI && global.FlowUI.renderAlerts) {
16156
- const alertsContainer = document.getElementById("alerts");
16157
- if (alertsContainer) {
16158
- global.FlowUI.renderAlerts(
16159
- alertsContainer,
16160
- [`Failed to upload "${file.name}": ${error.message}`],
16161
- "error"
16162
- );
16163
- }
15867
+ if (global.FlowUI && global.FlowUI.showToast) {
15868
+ global.FlowUI.showToast(`Failed to upload "${file.name}": ${error.message}`, "error");
16164
15869
  }
16165
15870
  }
16166
15871
  }
@@ -16173,11 +15878,8 @@
16173
15878
  // Check max files limit
16174
15879
  if (multiple && maxFiles && uploadedFiles.length + files.length > maxFiles) {
16175
15880
  const message = `You can only upload ${maxFiles} file${maxFiles !== 1 ? "s" : ""}`;
16176
- if (global.FlowUI && global.FlowUI.renderAlerts) {
16177
- const alertsContainer = document.getElementById("alerts");
16178
- if (alertsContainer) {
16179
- global.FlowUI.renderAlerts(alertsContainer, [message], "error");
16180
- }
15881
+ if (global.FlowUI && global.FlowUI.showToast) {
15882
+ global.FlowUI.showToast(message, "error");
16181
15883
  }
16182
15884
  input.value = "";
16183
15885
  return;
@@ -16824,7 +16526,7 @@
16824
16526
  },
16825
16527
  });
16826
16528
  document.dispatchEvent(event);
16827
- console.log("[Superleap-Flow] Library ready - v2.2.9");
16529
+ console.log("[Superleap-Flow] Library ready - v2.3.4");
16828
16530
  }
16829
16531
 
16830
16532
  // Wait for DOM to be ready before dispatching event