@superleapai/flow-ui 2.5.2 → 2.5.3

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.5.1
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-25T15:52:26.090Z
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
@@ -15,7 +15,7 @@
15
15
  'use strict';
16
16
 
17
17
  // ============================================
18
- // File 1/41: node_modules/superleap-sdk/superleap.js
18
+ // File 1/37: node_modules/superleap-sdk/superleap.js
19
19
  // ============================================
20
20
 
21
21
  /**
@@ -2642,7 +2642,7 @@
2642
2642
 
2643
2643
 
2644
2644
  // ============================================
2645
- // File 2/41: core/superleapClient.js
2645
+ // File 2/37: core/superleapClient.js
2646
2646
  // ============================================
2647
2647
 
2648
2648
  /**
@@ -2783,23 +2783,11 @@
2783
2783
  return mergeConfig({}, DEFAULT_CONFIG);
2784
2784
  }
2785
2785
 
2786
- /**
2787
- * Return the current base URL (from merged config after init).
2788
- * Used by file-input and other components that build API URLs.
2789
- *
2790
- * @returns {string|null} baseUrl or null if not initialized
2791
- */
2792
- function getBaseUrl() {
2793
- if (_config && _config.baseUrl) return _config.baseUrl;
2794
- return null;
2795
- }
2796
-
2797
2786
  var superleapClient = {
2798
2787
  init: init,
2799
2788
  getSdk: getSdk,
2800
2789
  isAvailable: isAvailable,
2801
2790
  getDefaultConfig: getDefaultConfig,
2802
- getBaseUrl: getBaseUrl,
2803
2791
  };
2804
2792
 
2805
2793
  if (global) {
@@ -2810,7 +2798,7 @@
2810
2798
 
2811
2799
 
2812
2800
  // ============================================
2813
- // File 3/41: core/bridge.js
2801
+ // File 3/37: core/bridge.js
2814
2802
  // ============================================
2815
2803
 
2816
2804
  /**
@@ -3338,7 +3326,7 @@
3338
3326
 
3339
3327
 
3340
3328
  // ============================================
3341
- // File 4/41: core/crm.js
3329
+ // File 4/37: core/crm.js
3342
3330
  // ============================================
3343
3331
 
3344
3332
  /**
@@ -3681,7 +3669,7 @@
3681
3669
 
3682
3670
 
3683
3671
  // ============================================
3684
- // File 5/41: components/label.js
3672
+ // File 5/37: components/label.js
3685
3673
  // ============================================
3686
3674
 
3687
3675
  /**
@@ -3798,7 +3786,7 @@
3798
3786
 
3799
3787
 
3800
3788
  // ============================================
3801
- // File 6/41: core/flow.js
3789
+ // File 6/37: core/flow.js
3802
3790
  // ============================================
3803
3791
 
3804
3792
  /**
@@ -4050,48 +4038,6 @@
4050
4038
  return field;
4051
4039
  }
4052
4040
 
4053
- /**
4054
- * Create a rich text editor field
4055
- * @param {Object} config - Configuration object
4056
- * @param {string} config.label - Field label
4057
- * @param {string} config.fieldId - State key for this field
4058
- * @param {string} [config.placeholder] - Placeholder when empty
4059
- * @param {boolean} [config.required] - Whether field is required
4060
- * @param {string} [config.helpText] - Optional help text for tooltip
4061
- * @param {number} [config.minHeightPx] - Min height of editor area in pixels (default 400)
4062
- * @param {boolean} [config.disabled] - Whether editor is disabled
4063
- * @returns {HTMLElement} Field element
4064
- */
4065
- function createRichTextEditor(config) {
4066
- const { label, fieldId, placeholder, required = false, helpText = null, minHeightPx = 400, disabled = false } = config;
4067
-
4068
- const field = createFieldWrapper(label, required, helpText);
4069
- field.setAttribute("data-field-id", fieldId);
4070
-
4071
- if (getComponent("RichTextEditorComponent") && getComponent("RichTextEditorComponent").create) {
4072
- const currentValue = get(fieldId) || "";
4073
- const editorEl = getComponent("RichTextEditorComponent").create({
4074
- value: currentValue,
4075
- placeholder: placeholder || "",
4076
- minHeightPx,
4077
- disabled,
4078
- onChange: (html) => set(fieldId, html),
4079
- });
4080
- editorEl._fieldId = fieldId;
4081
- field.appendChild(editorEl);
4082
- return field;
4083
- }
4084
-
4085
- const fallback = document.createElement("textarea");
4086
- fallback.className = "textarea min-h-[400px]";
4087
- fallback.placeholder = placeholder || `Enter ${label.toLowerCase()}`;
4088
- fallback.value = get(fieldId) || "";
4089
- fallback.disabled = disabled;
4090
- fallback.addEventListener("change", (e) => set(fieldId, e.target.value));
4091
- field.appendChild(fallback);
4092
- return field;
4093
- }
4094
-
4095
4041
  /**
4096
4042
  * Create a select dropdown field (using custom select component)
4097
4043
  * @param {Object} config - Configuration object
@@ -4502,7 +4448,6 @@
4502
4448
  size,
4503
4449
  canClear,
4504
4450
  initialLimit,
4505
- initialFilter,
4506
4451
  helpText = null,
4507
4452
  } = config;
4508
4453
 
@@ -4522,7 +4467,6 @@
4522
4467
  size: size || "default",
4523
4468
  canClear: !!canClear,
4524
4469
  initialLimit,
4525
- initialFilter,
4526
4470
  onChange: (value, record) => {
4527
4471
  set(fieldId, value);
4528
4472
  if (onChange) onChange(value, record);
@@ -4572,7 +4516,6 @@
4572
4516
  variant,
4573
4517
  size,
4574
4518
  initialLimit,
4575
- initialFilter,
4576
4519
  displayFields,
4577
4520
  helpText = null,
4578
4521
  } = config;
@@ -4591,7 +4534,6 @@
4591
4534
  variant: variant || "default",
4592
4535
  size: size || "default",
4593
4536
  initialLimit,
4594
- initialFilter,
4595
4537
  displayFields: displayFields || [],
4596
4538
  onValuesChange: (values, records) => {
4597
4539
  set(fieldId, values);
@@ -5149,40 +5091,6 @@
5149
5091
  return field;
5150
5092
  }
5151
5093
 
5152
- /**
5153
- * Create a checkbox group field (multiselect-like: options array, value array, onValuesChange)
5154
- * @param {Object} config - { label, fieldId, options, required, helpText, variant, size, layout, disabled, onChange }
5155
- * @returns {HTMLElement} Field wrapper containing checkbox group
5156
- */
5157
- function createCheckboxGroup(config) {
5158
- const { label, fieldId, options = [], required = false, helpText = null, variant, size, layout = "vertical", disabled = false, onChange } = config;
5159
-
5160
- const field = createFieldWrapper(label, required, helpText);
5161
- field.setAttribute("data-field-id", fieldId);
5162
-
5163
- if (getComponent("CheckboxGroup") && getComponent("CheckboxGroup").create) {
5164
- const currentValues = get(fieldId) || [];
5165
- const groupEl = getComponent("CheckboxGroup").create({
5166
- fieldId,
5167
- options,
5168
- value: currentValues,
5169
- variant: variant || "default",
5170
- size: size || "default",
5171
- layout,
5172
- disabled,
5173
- onValuesChange: (values) => {
5174
- set(fieldId, values);
5175
- if (onChange) onChange(values);
5176
- },
5177
- });
5178
- groupEl._fieldId = fieldId;
5179
- field.appendChild(groupEl);
5180
- return field;
5181
- }
5182
-
5183
- return field;
5184
- }
5185
-
5186
5094
  // ============================================================================
5187
5095
  // STEPPER COMPONENT
5188
5096
  // ============================================================================
@@ -5214,38 +5122,6 @@
5214
5122
  });
5215
5123
  }
5216
5124
 
5217
- /**
5218
- * Create a Tabs component (list + triggers + content panels)
5219
- * @param {Object} config - { defaultValue?, value?, onChange?, tabs: [{ value, label, content }], size?, variant?, listClassName?, contentClassName? }
5220
- * @returns {HTMLElement} Tabs root element
5221
- */
5222
- function createTabs(config) {
5223
- const Tabs = getComponent("Tabs");
5224
- if (Tabs && typeof Tabs.create === "function") {
5225
- return Tabs.create(config);
5226
- }
5227
- const fallback = document.createElement("div");
5228
- fallback.className = "tabs-root";
5229
- fallback.textContent = "Tabs component not loaded.";
5230
- return fallback;
5231
- }
5232
-
5233
- /**
5234
- * Create a Steps component (numbered step triggers + optional content panels)
5235
- * @param {Object} config - { steps: [{ id, label, content? }], defaultValue?, value?, onChange?, size?, variant?, listClassName?, contentClassName?, showContent? }
5236
- * @returns {HTMLElement} Steps root element
5237
- */
5238
- function createSteps(config) {
5239
- const Steps = getComponent("Steps");
5240
- if (Steps && typeof Steps.create === "function") {
5241
- return Steps.create(config);
5242
- }
5243
- const fallback = document.createElement("div");
5244
- fallback.className = "steps-root";
5245
- fallback.textContent = "Steps component not loaded.";
5246
- return fallback;
5247
- }
5248
-
5249
5125
  // ============================================================================
5250
5126
  // TABLE COMPONENT
5251
5127
  // ============================================================================
@@ -5408,34 +5284,6 @@
5408
5284
  return field;
5409
5285
  }
5410
5286
 
5411
- // ============================================================================
5412
- // ALERTS
5413
- // ============================================================================
5414
-
5415
- /**
5416
- * Render multiple alert messages into a container
5417
- * @param {HTMLElement} container - Container to append alerts to
5418
- * @param {string[]} messages - Array of message strings
5419
- * @param {string} [variant='default'] - 'default' | 'error' | 'warning' | 'success' | 'info' | 'destructive'
5420
- */
5421
- function renderAlerts(container, messages, variant = "default") {
5422
- if (!container || !Array.isArray(messages)) return;
5423
- const Alert = getComponent("Alert");
5424
- if (Alert && typeof Alert.simple === "function") {
5425
- messages.forEach((msg) => {
5426
- const el = Alert.simple(msg, variant);
5427
- if (el) container.appendChild(el);
5428
- });
5429
- } else {
5430
- messages.forEach((msg) => {
5431
- const div = document.createElement("div");
5432
- div.className = "rounded border p-2 text-sm " + (variant === "error" ? "bg-red-50 border-red-200 text-red-800" : "bg-gray-50 border-gray-200");
5433
- div.textContent = msg;
5434
- container.appendChild(div);
5435
- });
5436
- }
5437
- }
5438
-
5439
5287
  // ============================================================================
5440
5288
  // TOAST NOTIFICATIONS
5441
5289
  // ============================================================================
@@ -5572,7 +5420,6 @@
5572
5420
  // Form components
5573
5421
  createInput,
5574
5422
  createTextarea,
5575
- createRichTextEditor,
5576
5423
  createSelect,
5577
5424
  createTimePicker,
5578
5425
  createDateTimePicker,
@@ -5588,7 +5435,6 @@
5588
5435
  createCurrency,
5589
5436
  createPhoneInput,
5590
5437
  createCheckbox,
5591
- createCheckboxGroup,
5592
5438
 
5593
5439
  // Button (delegates to Button component when available; resolved at call time via getComponent)
5594
5440
  createButton: function (config) {
@@ -5609,11 +5455,8 @@
5609
5455
 
5610
5456
  // Stepper
5611
5457
  renderStepper,
5612
- createTabs,
5613
- createSteps,
5614
5458
 
5615
5459
  // Alerts
5616
- renderAlerts,
5617
5460
  showToast,
5618
5461
 
5619
5462
  // Table
@@ -5641,7 +5484,7 @@
5641
5484
 
5642
5485
 
5643
5486
  // ============================================
5644
- // File 7/41: components/toast.js
5487
+ // File 7/37: components/toast.js
5645
5488
  // ============================================
5646
5489
 
5647
5490
  /**
@@ -5990,7 +5833,7 @@
5990
5833
 
5991
5834
 
5992
5835
  // ============================================
5993
- // File 8/41: components/alert.js
5836
+ // File 8/37: components/alert.js
5994
5837
  // ============================================
5995
5838
 
5996
5839
  /**
@@ -6278,7 +6121,7 @@
6278
6121
 
6279
6122
 
6280
6123
  // ============================================
6281
- // File 9/41: components/button.js
6124
+ // File 9/37: components/button.js
6282
6125
  // ============================================
6283
6126
 
6284
6127
  /**
@@ -6485,7 +6328,7 @@
6485
6328
 
6486
6329
 
6487
6330
  // ============================================
6488
- // File 10/41: components/spinner.js
6331
+ // File 10/37: components/spinner.js
6489
6332
  // ============================================
6490
6333
 
6491
6334
  /**
@@ -6627,7 +6470,7 @@
6627
6470
 
6628
6471
 
6629
6472
  // ============================================
6630
- // File 11/41: components/badge.js
6473
+ // File 11/37: components/badge.js
6631
6474
  // ============================================
6632
6475
 
6633
6476
  /**
@@ -6768,7 +6611,7 @@
6768
6611
 
6769
6612
 
6770
6613
  // ============================================
6771
- // File 12/41: components/avatar.js
6614
+ // File 12/37: components/avatar.js
6772
6615
  // ============================================
6773
6616
 
6774
6617
  /**
@@ -6969,7 +6812,7 @@
6969
6812
 
6970
6813
 
6971
6814
  // ============================================
6972
- // File 13/41: components/icon.js
6815
+ // File 13/37: components/icon.js
6973
6816
  // ============================================
6974
6817
 
6975
6818
  /**
@@ -7050,40 +6893,6 @@
7050
6893
  /** Filled circle for "just color" mode (IconOrColor when only icon_color is set) */
7051
6894
  IconCircleFilled:
7052
6895
  '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="10" fill="currentColor"/></svg>',
7053
-
7054
- // Rich text editor / toolbar (Tabler Icons outline, stroke 2)
7055
- IconBold:
7056
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-bold"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 5h6a3.5 3.5 0 0 1 0 7h-6l0 -7" /><path d="M13 12h1a3.5 3.5 0 0 1 0 7h-7v-7" /></svg>',
7057
- IconItalic:
7058
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-italic"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11 5l6 0" /><path d="M7 19l6 0" /><path d="M14 5l-4 14" /></svg>',
7059
- IconUnderline:
7060
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-underline"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 5v5a5 5 0 0 0 10 0v-5" /><path d="M5 19h14" /></svg>',
7061
- IconH1:
7062
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-h-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M19 18v-8l-2 2" /><path d="M4 6v12" /><path d="M12 6v12" /><path d="M11 18h2" /><path d="M3 18h2" /><path d="M4 12h8" /><path d="M3 6h2" /><path d="M11 6h2" /></svg>',
7063
- IconH2:
7064
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-h-2"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M17 12a2 2 0 1 1 4 0c0 .591 -.417 1.318 -.816 1.858l-3.184 4.143l4 0" /><path d="M4 6v12" /><path d="M12 6v12" /><path d="M11 18h2" /><path d="M3 18h2" /><path d="M4 12h8" /><path d="M3 6h2" /><path d="M11 6h2" /></svg>',
7065
- IconH3:
7066
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-h-3"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M19 14a2 2 0 1 0 -2 -2" /><path d="M17 16a2 2 0 1 0 2 -2" /><path d="M4 6v12" /><path d="M12 6v12" /><path d="M11 18h2" /><path d="M3 18h2" /><path d="M4 12h8" /><path d="M3 6h2" /><path d="M11 6h2" /></svg>',
7067
- IconList:
7068
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-list"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 6l11 0" /><path d="M9 12l11 0" /><path d="M9 18l11 0" /><path d="M5 6l0 .01" /><path d="M5 12l0 .01" /><path d="M5 18l0 .01" /></svg>',
7069
- IconListNumbers:
7070
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-list-numbers"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11 6h9" /><path d="M11 12h9" /><path d="M12 18h8" /><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4" /><path d="M6 10v-6l-2 2" /></svg>',
7071
- IconAlignLeft:
7072
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-align-left"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6l16 0" /><path d="M4 12l10 0" /><path d="M4 18l14 0" /></svg>',
7073
- IconAlignCenter:
7074
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-align-center"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6l16 0" /><path d="M8 12l8 0" /><path d="M6 18l12 0" /></svg>',
7075
- IconAlignRight:
7076
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-align-right"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6l16 0" /><path d="M10 12l10 0" /><path d="M6 18l14 0" /></svg>',
7077
- IconCode:
7078
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-code"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 8l-4 4l4 4" /><path d="M17 8l4 4l-4 4" /><path d="M14 4l-4 16" /></svg>',
7079
- IconLink:
7080
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-link"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 15l6 -6" /><path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" /><path d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" /></svg>',
7081
- IconPhoto:
7082
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-photo"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 8h.01" /><path d="M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12" /><path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5" /><path d="M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3" /></svg>',
7083
- IconArrowBackUp:
7084
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-arrow-back-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 14l-4 -4l4 -4" /><path d="M5 10h11a4 4 0 1 1 0 8h-1" /></svg>',
7085
- IconArrowForwardUp:
7086
- '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-arrow-forward-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 14l4 -4l-4 -4" /><path d="M19 10h-11a4 4 0 1 0 0 8h1" /></svg>',
7087
6896
  };
7088
6897
 
7089
6898
  function join() {
@@ -7209,7 +7018,7 @@
7209
7018
 
7210
7019
 
7211
7020
  // ============================================
7212
- // File 14/41: components/popover.js
7021
+ // File 14/37: components/popover.js
7213
7022
  // ============================================
7214
7023
 
7215
7024
  /**
@@ -7232,7 +7041,6 @@
7232
7041
  * @param {Function} [config.onOpen] - Called when popover opens (before positioning)
7233
7042
  * @param {string} [config.bodyClassName] - Optional class for body wrapper (overrides default padding)
7234
7043
  * @param {string} [config.panelClassName] - Optional class to add to panel (e.g. for width)
7235
- * @param {boolean} [config.modal=false] - If true, lock body scroll and show backdrop; only popover and trigger are interactive
7236
7044
  * @returns {Object} Popover API {show, hide, destroy, element}
7237
7045
  */
7238
7046
  function create(config = {}) {
@@ -7247,7 +7055,6 @@
7247
7055
  onOpen = null,
7248
7056
  bodyClassName = "",
7249
7057
  panelClassName = "",
7250
- modal = true,
7251
7058
  } = config;
7252
7059
 
7253
7060
  const triggerEl =
@@ -7257,7 +7064,7 @@
7257
7064
  return { show: noop, hide: noop, destroy: noop, element: null };
7258
7065
  }
7259
7066
 
7260
- // Wrap trigger in a relative container for layout (full width); popover is portaled to body
7067
+ // Wrap trigger in a relative container so popover can be absolute relative to it (full width so parent controls it)
7261
7068
  const container = document.createElement("div");
7262
7069
  container.className = "relative w-full";
7263
7070
  const triggerParent = triggerEl.parentNode;
@@ -7268,7 +7075,7 @@
7268
7075
 
7269
7076
  const wrapper = document.createElement("div");
7270
7077
  wrapper.className =
7271
- "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";
7272
7079
  wrapper.setAttribute("aria-hidden", "true");
7273
7080
 
7274
7081
  const panel = document.createElement("div");
@@ -7292,11 +7099,7 @@
7292
7099
  const body = document.createElement("div");
7293
7100
  body.className =
7294
7101
  bodyClassName ||
7295
- "text-reg-14 text-typography-secondary-text leading-5 [&_p]:mb-2 [&_p:last-child]:mb-0 max-h-[90vh] overflow-y-auto overflow-x-hidden min-h-0";
7296
- body.style.maxHeight = "90vh";
7297
- body.style.overflowY = "auto";
7298
- body.style.overflowX = "hidden";
7299
- body.style.minHeight = "0";
7102
+ "text-reg-14 text-typography-secondary-text leading-5 [&_p]:mb-2 [&_p:last-child]:mb-0";
7300
7103
  if (panelClassName) {
7301
7104
  panel.className = panel.className + " " + panelClassName;
7302
7105
  }
@@ -7308,40 +7111,7 @@
7308
7111
  panel.appendChild(body);
7309
7112
 
7310
7113
  wrapper.appendChild(panel);
7311
- document.body.appendChild(wrapper);
7312
-
7313
- var backdropEl = null;
7314
- var resizeObserver = null;
7315
-
7316
- function onBackdropWheel(e) {
7317
- e.preventDefault();
7318
- }
7319
-
7320
- function applyModalOpen() {
7321
- if (!modal) return;
7322
- if (!backdropEl) {
7323
- backdropEl = document.createElement("div");
7324
- backdropEl.className =
7325
- "fixed inset-0 z-40 bg-transparent pointer-events-auto";
7326
- backdropEl.setAttribute("aria-hidden", "true");
7327
- backdropEl.addEventListener("click", function () {
7328
- hide();
7329
- });
7330
- backdropEl.addEventListener("wheel", onBackdropWheel, {
7331
- passive: false,
7332
- });
7333
- }
7334
- document.body.appendChild(backdropEl);
7335
- wrapper.style.zIndex = "999";
7336
- }
7337
-
7338
- function applyModalClose() {
7339
- if (!modal) return;
7340
- if (backdropEl && backdropEl.parentNode) {
7341
- backdropEl.parentNode.removeChild(backdropEl);
7342
- }
7343
- wrapper.style.zIndex = "";
7344
- }
7114
+ container.appendChild(wrapper);
7345
7115
 
7346
7116
  function noop() {}
7347
7117
 
@@ -7349,80 +7119,33 @@
7349
7119
  const triggerRect = triggerEl.getBoundingClientRect();
7350
7120
  const panelRect = panel.getBoundingClientRect();
7351
7121
  const gap = 8;
7352
- const viewportHeight =
7353
- window.innerHeight || document.documentElement.clientHeight;
7354
- const viewportWidth =
7355
- window.innerWidth || document.documentElement.clientWidth;
7356
- const spaceBelow = viewportHeight - triggerRect.bottom;
7357
- const spaceAbove = triggerRect.top;
7358
- const spaceRight = viewportWidth - triggerRect.right;
7359
- const spaceLeft = triggerRect.left;
7360
-
7361
- // Flip placement when there is not enough space (prefer requested side, flip only when needed)
7362
- let effectivePlacement = placement;
7363
- if (
7364
- placement === "bottom" &&
7365
- spaceBelow < panelRect.height + gap &&
7366
- spaceAbove >= panelRect.height + gap
7367
- ) {
7368
- effectivePlacement = "top";
7369
- } else if (
7370
- placement === "top" &&
7371
- spaceAbove < panelRect.height + gap &&
7372
- spaceBelow >= panelRect.height + gap
7373
- ) {
7374
- effectivePlacement = "bottom";
7375
- } else if (
7376
- placement === "right" &&
7377
- spaceRight < panelRect.width + gap &&
7378
- spaceLeft >= panelRect.width + gap
7379
- ) {
7380
- effectivePlacement = "left";
7381
- } else if (
7382
- placement === "left" &&
7383
- spaceLeft < panelRect.width + gap &&
7384
- spaceRight >= panelRect.width + gap
7385
- ) {
7386
- effectivePlacement = "right";
7387
- }
7388
-
7389
- panel.setAttribute("data-side", effectivePlacement);
7390
-
7391
7122
  let top = 0;
7392
7123
  let left = 0;
7393
- const alignLeft =
7394
- align === "center"
7395
- ? (triggerRect.width - panelRect.width) / 2
7396
- : align === "end"
7397
- ? triggerRect.width - panelRect.width
7398
- : 0;
7399
- const alignTop =
7400
- align === "center"
7401
- ? (triggerRect.height - panelRect.height) / 2
7402
- : align === "end"
7403
- ? triggerRect.height - panelRect.height
7404
- : 0;
7405
-
7406
- switch (effectivePlacement) {
7124
+
7125
+ // Alignment offset: start = 0, center = half diff, end = full diff
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);
7128
+
7129
+ switch (placement) {
7407
7130
  case "bottom":
7408
- top = triggerRect.bottom + gap;
7409
- left = triggerRect.left + alignLeft;
7131
+ top = triggerRect.height + gap;
7132
+ left = alignLeft;
7410
7133
  break;
7411
7134
  case "top":
7412
- top = triggerRect.top - panelRect.height - gap;
7413
- left = triggerRect.left + alignLeft;
7135
+ top = -panelRect.height - gap;
7136
+ left = alignLeft;
7414
7137
  break;
7415
7138
  case "right":
7416
- top = triggerRect.top + alignTop;
7417
- left = triggerRect.right + gap;
7139
+ top = alignTop;
7140
+ left = triggerRect.width + gap;
7418
7141
  break;
7419
7142
  case "left":
7420
- top = triggerRect.top + alignTop;
7421
- left = triggerRect.left - panelRect.width - gap;
7143
+ top = alignTop;
7144
+ left = -panelRect.width - gap;
7422
7145
  break;
7423
7146
  default:
7424
- top = triggerRect.bottom + gap;
7425
- left = triggerRect.left + alignLeft;
7147
+ top = triggerRect.height + gap;
7148
+ left = alignLeft;
7426
7149
  }
7427
7150
 
7428
7151
  wrapper.style.transform = "";
@@ -7436,41 +7159,16 @@
7436
7159
  wrapper.classList.add("invisible", "opacity-0", "pointer-events-none");
7437
7160
  wrapper.classList.remove("visible", "opacity-100", "pointer-events-auto");
7438
7161
  wrapper.setAttribute("aria-hidden", "true");
7439
- window.removeEventListener("scroll", onScrollOrResize, true);
7440
- window.removeEventListener("resize", onScrollOrResize);
7441
- if (resizeObserver && panel) {
7442
- resizeObserver.disconnect();
7443
- resizeObserver = null;
7444
- }
7445
- applyModalClose();
7446
7162
  if (onClose) onClose();
7447
7163
  }
7448
7164
 
7449
- function onScrollOrResize() {
7450
- if (wrapper.classList.contains("visible")) position();
7451
- }
7452
-
7453
7165
  function show() {
7454
7166
  if (onOpen) onOpen();
7455
- applyModalOpen();
7456
7167
  requestAnimationFrame(function () {
7457
7168
  position();
7458
- wrapper.classList.remove(
7459
- "invisible",
7460
- "opacity-0",
7461
- "pointer-events-none",
7462
- );
7169
+ wrapper.classList.remove("invisible", "opacity-0", "pointer-events-none");
7463
7170
  wrapper.classList.add("visible", "opacity-100", "pointer-events-auto");
7464
7171
  wrapper.setAttribute("aria-hidden", "false");
7465
- window.addEventListener("scroll", onScrollOrResize, true);
7466
- window.addEventListener("resize", onScrollOrResize);
7467
- // Re-position when panel content size changes (e.g. async record list load in record-select)
7468
- if (typeof ResizeObserver !== "undefined" && !resizeObserver) {
7469
- resizeObserver = new ResizeObserver(function () {
7470
- if (wrapper.classList.contains("visible")) position();
7471
- });
7472
- resizeObserver.observe(panel);
7473
- }
7474
7172
  requestAnimationFrame(function () {
7475
7173
  requestAnimationFrame(function () {
7476
7174
  panel.setAttribute("data-state", "open");
@@ -7481,16 +7179,6 @@
7481
7179
 
7482
7180
  function destroy() {
7483
7181
  hide();
7484
- applyModalClose();
7485
- if (resizeObserver && panel) {
7486
- resizeObserver.disconnect();
7487
- resizeObserver = null;
7488
- }
7489
- if (backdropEl && backdropEl.parentNode) {
7490
- backdropEl.parentNode.removeChild(backdropEl);
7491
- }
7492
- window.removeEventListener("scroll", onScrollOrResize, true);
7493
- window.removeEventListener("resize", onScrollOrResize);
7494
7182
  if (wrapper.parentNode) {
7495
7183
  wrapper.parentNode.removeChild(wrapper);
7496
7184
  }
@@ -7540,8 +7228,6 @@
7540
7228
  show,
7541
7229
  hide,
7542
7230
  destroy,
7543
- /** Re-run positioning (e.g. after async content load). Call when panel size changes. */
7544
- updatePosition: position,
7545
7231
  setContent(newContent) {
7546
7232
  body.innerHTML = "";
7547
7233
  if (typeof newContent === "string") {
@@ -7563,7 +7249,7 @@
7563
7249
 
7564
7250
 
7565
7251
  // ============================================
7566
- // File 15/41: components/select.js
7252
+ // File 15/37: components/select.js
7567
7253
  // ============================================
7568
7254
 
7569
7255
  /**
@@ -7760,11 +7446,11 @@
7760
7446
 
7761
7447
  var content = document.createElement("div");
7762
7448
  content.setAttribute("role", "listbox");
7763
- content.className = "custom-select-content w-full max-h-[45vh] overflow-hidden flex flex-col";
7449
+ content.className = "custom-select-content w-full max-h-[200px] overflow-hidden flex flex-col";
7764
7450
 
7765
7451
  var optionsList = document.createElement("div");
7766
7452
  optionsList.className =
7767
- "overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white";
7453
+ "overflow-y-auto max-h-[200px] p-2 w-full rounded-4 bg-fill-quarternary-fill-white";
7768
7454
 
7769
7455
  if (options.length === 0) {
7770
7456
  var noOpt = document.createElement("div");
@@ -7823,7 +7509,7 @@
7823
7509
  align: "start",
7824
7510
  closeOnClickOutside: true,
7825
7511
  bodyClassName: "p-0 overflow-hidden",
7826
- panelClassName: "min-w-[var(--trigger-width)] max-h-[45vh] overflow-hidden",
7512
+ panelClassName: "min-w-[var(--trigger-width)] max-h-[200px] overflow-hidden",
7827
7513
  onOpen: function () {
7828
7514
  if (disabled) {
7829
7515
  popover.hide();
@@ -8121,7 +7807,7 @@
8121
7807
 
8122
7808
 
8123
7809
  // ============================================
8124
- // File 16/41: components/enum-select.js
7810
+ // File 16/37: components/enum-select.js
8125
7811
  // ============================================
8126
7812
 
8127
7813
  /**
@@ -8355,7 +8041,7 @@
8355
8041
  // Create dropdown content
8356
8042
  var content = document.createElement("div");
8357
8043
  content.setAttribute("role", "listbox");
8358
- content.className = "w-full min-w-[200px] max-h-[45vh] overflow-hidden flex flex-col";
8044
+ content.className = "w-full min-w-[200px] max-h-[30vh] overflow-hidden flex flex-col";
8359
8045
 
8360
8046
  // Search input (using InputComponent like phone-input)
8361
8047
  var searchContainer = document.createElement("div");
@@ -8416,7 +8102,7 @@
8416
8102
  // Options list
8417
8103
  var optionsList = document.createElement("div");
8418
8104
  optionsList.className =
8419
- "overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white flex-1 min-h-0";
8105
+ "overflow-y-auto max-h-[30vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white flex-1 min-h-0";
8420
8106
 
8421
8107
  content.appendChild(searchContainer);
8422
8108
  content.appendChild(optionsList);
@@ -8904,7 +8590,7 @@
8904
8590
 
8905
8591
 
8906
8592
  // ============================================
8907
- // File 17/41: components/record-select.js
8593
+ // File 17/37: components/record-select.js
8908
8594
  // ============================================
8909
8595
 
8910
8596
  /**
@@ -8918,20 +8604,9 @@
8918
8604
 
8919
8605
  (function (global) {
8920
8606
 
8921
- function getDep(name) {
8922
- if (
8923
- typeof global.FlowUI !== "undefined" &&
8924
- typeof global.FlowUI._getComponent === "function"
8925
- ) {
8926
- var c = global.FlowUI._getComponent(name);
8927
- if (c) return c;
8928
- }
8929
- return global[name];
8930
- }
8931
-
8932
- var Popover = getDep("Popover");
8933
- var InputComponent = getDep("InputComponent");
8934
- var Spinner = getDep("Spinner");
8607
+ var Popover = global.Popover;
8608
+ var InputComponent = global.InputComponent;
8609
+ var Spinner = global.Spinner;
8935
8610
 
8936
8611
  /** When objectSlug === USERS, show Vivid Avatar (name-based color) instead of static icon */
8937
8612
  var STANDARD_OBJECT_SLUGS_USERS = "user";
@@ -8953,7 +8628,7 @@
8953
8628
  '<svg width="16" height="16" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"/></svg>';
8954
8629
  var X_SVG =
8955
8630
  '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18M6 6l12 12"/></svg>';
8956
-
8631
+
8957
8632
  var SEARCH_ICON =
8958
8633
  '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>';
8959
8634
 
@@ -8968,8 +8643,7 @@
8968
8643
  "border-error-border hover:border-error-border-hover focus:border-1/2 focus:border-error-border-hover",
8969
8644
  warning:
8970
8645
  "border-warning-border hover:border-warning-border-hover focus:border-1/2 focus:border-warning-border-hover",
8971
- borderless:
8972
- "border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
8646
+ borderless: "border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
8973
8647
  inline:
8974
8648
  "focus:border-transparent border border-transparent shadow-none rounded-0 bg-fill-quarternary-fill-white hover:bg-fill-tertiary-fill-light-gray hover:border-transparent",
8975
8649
  };
@@ -8978,9 +8652,7 @@
8978
8652
  large: "px-12 py-8",
8979
8653
  small: "px-8 py-4",
8980
8654
  };
8981
- var placeholderClass = placeholder
8982
- ? " text-typography-quaternary-text"
8983
- : "";
8655
+ var placeholderClass = placeholder ? " text-typography-quaternary-text" : "";
8984
8656
  var disabledClass = disabled
8985
8657
  ? " pointer-events-none cursor-not-allowed bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary"
8986
8658
  : "";
@@ -9036,27 +8708,15 @@
9036
8708
  function getObjectIconInfo(slug, objectSchema) {
9037
8709
  var color = "neutral";
9038
8710
  var iconStr = "IconDatabase";
9039
- if (
9040
- objectSchema &&
9041
- objectSchema.properties &&
9042
- objectSchema.properties.icon_data
9043
- ) {
8711
+ if (objectSchema && objectSchema.properties && objectSchema.properties.icon_data) {
9044
8712
  var iconData = objectSchema.properties.icon_data;
9045
- if (typeof iconData.color === "string" && iconData.color)
9046
- color = iconData.color;
9047
- if (typeof iconData.icon === "string" && iconData.icon)
9048
- iconStr = iconData.icon;
8713
+ if (typeof iconData.color === "string" && iconData.color) color = iconData.color;
8714
+ if (typeof iconData.icon === "string" && iconData.icon) iconStr = iconData.icon;
9049
8715
  }
9050
- if (
9051
- !objectSchema ||
9052
- !objectSchema.properties ||
9053
- !objectSchema.properties.icon_data ||
9054
- !objectSchema.properties.icon_data.icon
9055
- ) {
8716
+ if (!objectSchema || !objectSchema.properties || !objectSchema.properties.icon_data || !objectSchema.properties.icon_data.icon) {
9056
8717
  if (OBJECT_SLUG_TO_ICON[slug]) {
9057
8718
  iconStr = OBJECT_SLUG_TO_ICON[slug].iconStr;
9058
- if (OBJECT_SLUG_TO_ICON[slug].color)
9059
- color = OBJECT_SLUG_TO_ICON[slug].color;
8719
+ if (OBJECT_SLUG_TO_ICON[slug].color) color = OBJECT_SLUG_TO_ICON[slug].color;
9060
8720
  } else {
9061
8721
  iconStr = "IconDatabase";
9062
8722
  color = "neutral";
@@ -9079,7 +8739,6 @@
9079
8739
  * @param {string} [config.size] - 'default' | 'large' | 'small'
9080
8740
  * @param {boolean} [config.canClear] - Show clear button when value is set
9081
8741
  * @param {number} [config.initialLimit] - Initial fetch limit (default 50)
9082
- * @param {Object} [config.initialFilter] - Optional filter object to merge with search (e.g. { field: "status", operator: "exact", value: "active" } or { and: [...] })
9083
8742
  * @param {Object} [config.objectSchema] - Optional object type/schema; properties.icon_data { svg?, color? } used for static icon (not used for user; user shows Vivid Avatar)
9084
8743
  * @returns {HTMLElement} Record select container element
9085
8744
  */
@@ -9088,14 +8747,12 @@
9088
8747
  var objectSlug = config.objectSlug;
9089
8748
  var objectSchema = config.objectSchema || null;
9090
8749
  var placeholder = config.placeholder || "Select a record";
9091
- var searchPlaceholder =
9092
- config.searchPlaceholder || "Search " + (objectSlug || "") + "...";
8750
+ var searchPlaceholder = config.searchPlaceholder || "Search " + (objectSlug || "") + "...";
9093
8751
  var onChange = config.onChange;
9094
8752
  var variant = config.variant || "default";
9095
8753
  var size = config.size || "default";
9096
8754
  var canClear = !!config.canClear;
9097
8755
  var initialLimit = config.initialLimit != null ? config.initialLimit : 50;
9098
- var initialFilter = config.initialFilter || null; // Can be array, object, or function returning either
9099
8756
 
9100
8757
  var disabled = config.disabled === true;
9101
8758
  var value =
@@ -9143,7 +8800,7 @@
9143
8800
  size,
9144
8801
  disabled,
9145
8802
  !value,
9146
- canClear && !!value && !disabled,
8803
+ canClear && !!value && !disabled
9147
8804
  );
9148
8805
  trigger.disabled = disabled;
9149
8806
  trigger.setAttribute("aria-haspopup", "listbox");
@@ -9152,8 +8809,7 @@
9152
8809
  trigger.classList.add("record-select-trigger");
9153
8810
 
9154
8811
  var triggerContent = document.createElement("div");
9155
- triggerContent.className =
9156
- "record-select-trigger-content flex items-center gap-8 flex-1 min-w-0";
8812
+ triggerContent.className = "record-select-trigger-content flex items-center gap-8 flex-1 min-w-0";
9157
8813
 
9158
8814
  var triggerIcon = document.createElement("span");
9159
8815
  triggerIcon.className = "record-select-trigger-icon shrink-0 hidden";
@@ -9196,9 +8852,7 @@
9196
8852
  // Dropdown content: search + list (same content pattern as Select)
9197
8853
  var content = document.createElement("div");
9198
8854
  content.setAttribute("role", "listbox");
9199
- content.setAttribute("data-field-id", fieldId);
9200
- content.className =
9201
- "record-select-content max-h-[45vh] overflow-hidden flex flex-col";
8855
+ content.className = "record-select-content max-h-[30vh] overflow-hidden flex flex-col";
9202
8856
 
9203
8857
  var searchWrap = document.createElement("div");
9204
8858
  searchWrap.className = "py-8 border-b-1/2 border-border-primary";
@@ -9229,12 +8883,12 @@
9229
8883
  } else {
9230
8884
  var fallbackWrapper = document.createElement("div");
9231
8885
  fallbackWrapper.className = "flex items-center gap-8 px-12";
9232
-
8886
+
9233
8887
  var searchIconSpan = document.createElement("span");
9234
8888
  searchIconSpan.className = "shrink-0 text-typography-tertiary-text";
9235
8889
  searchIconSpan.innerHTML = SEARCH_ICON;
9236
8890
  fallbackWrapper.appendChild(searchIconSpan);
9237
-
8891
+
9238
8892
  var searchInput = document.createElement("input");
9239
8893
  searchInput.type = "text";
9240
8894
  searchInput.className =
@@ -9248,22 +8902,21 @@
9248
8902
  content.appendChild(searchWrap);
9249
8903
 
9250
8904
  var optionsList = document.createElement("div");
9251
- optionsList.className =
9252
- "overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white record-select-options";
9253
-
8905
+ optionsList.className = "overflow-y-auto max-h-[200px] p-2 w-full rounded-4 bg-fill-quarternary-fill-white record-select-options";
8906
+
9254
8907
  // Add scroll listener for infinite scroll
9255
8908
  optionsList.addEventListener("scroll", function () {
9256
8909
  if (isFetchingMore || !hasMoreRecords) return;
9257
8910
  var scrollHeight = optionsList.scrollHeight;
9258
8911
  var scrollTop = optionsList.scrollTop;
9259
8912
  var clientHeight = optionsList.clientHeight;
9260
-
8913
+
9261
8914
  // Trigger load more when scrolled to bottom (with 50px threshold)
9262
8915
  if (scrollTop + clientHeight >= scrollHeight - 50) {
9263
8916
  loadMoreRecords();
9264
8917
  }
9265
8918
  });
9266
-
8919
+
9267
8920
  content.appendChild(optionsList);
9268
8921
 
9269
8922
  popover = Popover.create({
@@ -9273,41 +8926,30 @@
9273
8926
  align: "start",
9274
8927
  closeOnClickOutside: true,
9275
8928
  bodyClassName: "p-0 overflow-hidden",
9276
- panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
8929
+ panelClassName: "max-h-[30vh] overflow-hidden",
9277
8930
  onOpen: function () {
9278
8931
  if (disabled) {
9279
8932
  popover.hide();
9280
8933
  return;
9281
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");
8940
+ }
8941
+ });
9282
8942
  isOpen = true;
9283
8943
  container.classList.add("open");
9284
8944
  trigger.setAttribute("aria-expanded", "true");
9285
8945
  searchTerm = "";
9286
8946
  if (searchInputWrapper) searchInputWrapper.setValue("");
9287
8947
  else if (searchInputEl) searchInputEl.value = "";
9288
- if (popover.panel) {
9289
- var triggerWidthPx = trigger.offsetWidth + "px";
9290
- popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
9291
- popover.panel.style.minWidth = triggerWidthPx;
9292
- popover.panel.style.width = triggerWidthPx;
9293
- }
8948
+ content.style.minWidth = trigger.offsetWidth + "px";
9294
8949
  loadInitialAndRender();
9295
8950
  setTimeout(function () {
9296
8951
  if (searchInputEl) searchInputEl.focus();
9297
8952
  }, 0);
9298
- // Let consumers (e.g. BANT Questions "Add Contact") inject content into the dropdown
9299
- try {
9300
- var doc =
9301
- global.document ||
9302
- (typeof document !== "undefined" ? document : null);
9303
- if (doc && typeof global.CustomEvent !== "undefined") {
9304
- doc.dispatchEvent(
9305
- new global.CustomEvent("record-select:opened", {
9306
- detail: { fieldId: fieldId, content: content },
9307
- }),
9308
- );
9309
- }
9310
- } catch (e) {}
9311
8953
  },
9312
8954
  onClose: function () {
9313
8955
  isOpen = false;
@@ -9323,8 +8965,7 @@
9323
8965
  },
9324
8966
  });
9325
8967
 
9326
- if (clearBtn)
9327
- clearBtn.style.display = canClear && value && !disabled ? "" : "none";
8968
+ if (clearBtn) clearBtn.style.display = canClear && value && !disabled ? "" : "none";
9328
8969
 
9329
8970
  function setValue(newVal) {
9330
8971
  value = newVal !== undefined && newVal !== null ? newVal : "";
@@ -9338,18 +8979,16 @@
9338
8979
 
9339
8980
  function updateTriggerDisplay() {
9340
8981
  if (selectedRecord) {
9341
- triggerText.textContent =
9342
- selectedRecord.name || selectedRecord.label || value;
8982
+ triggerText.textContent = selectedRecord.name || selectedRecord.label || value;
9343
8983
  trigger.classList.remove("placeholder");
9344
8984
  trigger.className = triggerClasses(
9345
8985
  variant,
9346
8986
  size,
9347
8987
  disabled,
9348
8988
  false,
9349
- canClear && !!value && !disabled,
8989
+ canClear && !!value && !disabled
9350
8990
  );
9351
- triggerIcon.className =
9352
- "record-select-trigger-icon shrink-0 flex items-center justify-center size-20 rounded-4 overflow-hidden";
8991
+ triggerIcon.className = "record-select-trigger-icon shrink-0 flex items-center justify-center size-20 rounded-4 overflow-hidden";
9353
8992
  triggerIcon.innerHTML = "";
9354
8993
  if (objectSlug === STANDARD_OBJECT_SLUGS_USERS) {
9355
8994
  var Avatar = getAvatar();
@@ -9361,9 +9000,7 @@
9361
9000
  });
9362
9001
  triggerIcon.appendChild(vividEl);
9363
9002
  } else {
9364
- renderStaticIconPlaceholder(
9365
- selectedRecord.name || selectedRecord.label,
9366
- );
9003
+ renderStaticIconPlaceholder(selectedRecord.name || selectedRecord.label);
9367
9004
  }
9368
9005
  } else {
9369
9006
  renderStaticObjectIcon();
@@ -9376,13 +9013,12 @@
9376
9013
  size,
9377
9014
  disabled,
9378
9015
  true,
9379
- canClear && !!value && !disabled,
9016
+ canClear && !!value && !disabled
9380
9017
  );
9381
9018
  triggerIcon.className = "record-select-trigger-icon shrink-0 hidden";
9382
9019
  triggerIcon.innerHTML = "";
9383
9020
  }
9384
- if (clearBtn)
9385
- clearBtn.style.display = canClear && value && !disabled ? "" : "none";
9021
+ if (clearBtn) clearBtn.style.display = canClear && value && !disabled ? "" : "none";
9386
9022
  }
9387
9023
 
9388
9024
  function renderStaticObjectIcon() {
@@ -9419,39 +9055,18 @@
9419
9055
  var fields = ["id", "name"];
9420
9056
  var actualLimit = limit || initialLimit;
9421
9057
  var offset = page ? (page - 1) * actualLimit : 0;
9422
-
9058
+
9423
9059
  try {
9424
9060
  if (model && typeof model.select === "function") {
9425
9061
  var q = model.select.apply(model, fields);
9426
- var filters = [];
9427
- var resolvedFilter =
9428
- typeof initialFilter === "function"
9429
- ? initialFilter()
9430
- : initialFilter;
9431
- console.log(
9432
- "[RecordSelect] initialFilter:",
9433
- resolvedFilter,
9434
- "| search:",
9435
- search,
9436
- );
9437
- if (resolvedFilter) {
9438
- filters = filters.concat(
9439
- Array.isArray(resolvedFilter) ? resolvedFilter : [resolvedFilter],
9440
- );
9441
- }
9442
9062
  if (search && search.trim()) {
9443
- filters.push({
9063
+ q = q.filterBy({
9444
9064
  or: [
9445
9065
  { field: "name", operator: "contains", value: search.trim() },
9446
9066
  { field: "id", operator: "eq", value: search.trim() },
9447
9067
  ],
9448
9068
  });
9449
9069
  }
9450
- if (filters.length > 0) {
9451
- q = q.filterBy(
9452
- filters.length === 1 ? filters[0] : { and: filters },
9453
- );
9454
- }
9455
9070
  var orderBy = ["name"];
9456
9071
  if (objectSlug === "account") orderBy.push("-ParentId");
9457
9072
  return q
@@ -9514,12 +9129,7 @@
9514
9129
  updateTriggerDisplay();
9515
9130
  })
9516
9131
  .catch(function () {
9517
- selectedRecord = {
9518
- id: value,
9519
- value: value,
9520
- name: value,
9521
- label: value,
9522
- };
9132
+ selectedRecord = { id: value, value: value, name: value, label: value };
9523
9133
  updateTriggerDisplay();
9524
9134
  });
9525
9135
  }
@@ -9530,9 +9140,7 @@
9530
9140
  loadWrap.className =
9531
9141
  "flex flex-row items-center justify-center gap-8 py-12 px-12 w-full text-reg-12 text-typography-quaternary-text record-select-loading";
9532
9142
  if (Spinner && typeof Spinner.create === "function") {
9533
- loadWrap.appendChild(
9534
- Spinner.create({ size: "small", text: "Loading..." }),
9535
- );
9143
+ loadWrap.appendChild(Spinner.create({ size: "small", text: "Loading..." }));
9536
9144
  } else {
9537
9145
  var loadText = document.createElement("span");
9538
9146
  loadText.textContent = "Loading...";
@@ -9540,12 +9148,12 @@
9540
9148
  }
9541
9149
  optionsList.appendChild(loadWrap);
9542
9150
  }
9543
-
9151
+
9544
9152
  function showLoadingMore() {
9545
9153
  // Remove existing loading more indicator
9546
9154
  var existing = optionsList.querySelector(".record-select-loading-more");
9547
9155
  if (existing) existing.remove();
9548
-
9156
+
9549
9157
  var loadWrap = document.createElement("div");
9550
9158
  loadWrap.className =
9551
9159
  "flex flex-row items-center justify-center gap-8 py-8 px-12 w-full text-reg-12 text-typography-quaternary-text record-select-loading-more";
@@ -9558,11 +9166,9 @@
9558
9166
  }
9559
9167
  optionsList.appendChild(loadWrap);
9560
9168
  }
9561
-
9169
+
9562
9170
  function removeLoadingMore() {
9563
- var loadingMore = optionsList.querySelector(
9564
- ".record-select-loading-more",
9565
- );
9171
+ var loadingMore = optionsList.querySelector(".record-select-loading-more");
9566
9172
  if (loadingMore) loadingMore.remove();
9567
9173
  }
9568
9174
 
@@ -9581,15 +9187,13 @@
9581
9187
  existingOptions.forEach(function (opt) {
9582
9188
  opt.remove();
9583
9189
  });
9584
-
9190
+
9585
9191
  // Remove old loading/empty states
9586
- var oldStates = optionsList.querySelectorAll(
9587
- ".record-select-loading, .record-select-empty",
9588
- );
9192
+ var oldStates = optionsList.querySelectorAll(".record-select-loading, .record-select-empty");
9589
9193
  oldStates.forEach(function (el) {
9590
9194
  el.remove();
9591
9195
  });
9592
-
9196
+
9593
9197
  filteredRecords.forEach(function (rec) {
9594
9198
  var optionValue = rec.id || rec.value;
9595
9199
  var optionLabel = rec.name || rec.label || rec.value;
@@ -9604,7 +9208,7 @@
9604
9208
  "hover:bg-fill-tertiary-fill-light-gray focus:bg-fill-tertiary-fill-light-gray",
9605
9209
  isSelected
9606
9210
  ? "bg-primary-surface hover:!bg-primary-surface-hover"
9607
- : "",
9211
+ : ""
9608
9212
  );
9609
9213
 
9610
9214
  var optContent = document.createElement("span");
@@ -9662,93 +9266,70 @@
9662
9266
 
9663
9267
  optionsList.appendChild(option);
9664
9268
  });
9665
-
9269
+
9666
9270
  // Add loading more indicator at the bottom if fetching
9667
9271
  if (isFetchingMore) {
9668
9272
  showLoadingMore();
9669
9273
  }
9670
9274
  }
9671
9275
 
9672
- function scheduleUpdatePosition() {
9673
- if (popover && typeof popover.updatePosition === "function") {
9674
- requestAnimationFrame(function () {
9675
- requestAnimationFrame(function () {
9676
- popover.updatePosition();
9677
- });
9678
- });
9679
- }
9680
- }
9681
-
9682
9276
  function loadInitialAndRender() {
9683
9277
  showLoading();
9684
9278
  currentPage = 1;
9685
9279
  hasMoreRecords = true;
9686
9280
  totalFetched = 0;
9687
-
9688
- fetchRecords(searchTerm, initialLimit, 1)
9689
- .then(function (result) {
9690
- allRecords = result.records;
9691
- filteredRecords = result.records;
9692
- hasMoreRecords = result.hasMore;
9693
- totalFetched = result.records.length;
9694
- currentPage = 1;
9695
-
9696
- if (
9697
- value &&
9698
- !result.records.some(function (r) {
9699
- return (r.id || r.value) === value;
9700
- })
9701
- ) {
9702
- loadSelectedRecord();
9703
- } else if (value && result.records.length) {
9704
- var sel = result.records.find(function (r) {
9705
- return (r.id || r.value) === value;
9706
- });
9707
- if (sel) selectedRecord = sel;
9708
- updateTriggerDisplay();
9709
- }
9710
- if (filteredRecords.length === 0) {
9711
- showEmpty(searchTerm ? "No results found" : "No records available");
9712
- } else {
9713
- renderOptions();
9714
- }
9715
- scheduleUpdatePosition();
9716
- })
9717
- .catch(function () {
9718
- showEmpty("Failed to load records");
9719
- hasMoreRecords = false;
9720
- scheduleUpdatePosition();
9721
- });
9281
+
9282
+ fetchRecords(searchTerm, initialLimit, 1).then(function (result) {
9283
+ allRecords = result.records;
9284
+ filteredRecords = result.records;
9285
+ hasMoreRecords = result.hasMore;
9286
+ totalFetched = result.records.length;
9287
+ currentPage = 1;
9288
+
9289
+ if (value && !result.records.some(function (r) { return (r.id || r.value) === value; })) {
9290
+ loadSelectedRecord();
9291
+ } else if (value && result.records.length) {
9292
+ var sel = result.records.find(function (r) { return (r.id || r.value) === value; });
9293
+ if (sel) selectedRecord = sel;
9294
+ updateTriggerDisplay();
9295
+ }
9296
+ if (filteredRecords.length === 0) {
9297
+ showEmpty(searchTerm ? "No results found" : "No records available");
9298
+ } else {
9299
+ renderOptions();
9300
+ }
9301
+ }).catch(function () {
9302
+ showEmpty("Failed to load records");
9303
+ hasMoreRecords = false;
9304
+ });
9722
9305
  }
9723
-
9306
+
9724
9307
  function loadMoreRecords() {
9725
9308
  if (isFetchingMore || !hasMoreRecords) return;
9726
-
9309
+
9727
9310
  isFetchingMore = true;
9728
9311
  currentPage += 1;
9729
9312
  showLoadingMore();
9730
-
9731
- fetchRecords(searchTerm, initialLimit, currentPage)
9732
- .then(function (result) {
9733
- isFetchingMore = false;
9734
- removeLoadingMore();
9735
-
9736
- if (result.records.length > 0) {
9737
- allRecords = allRecords.concat(result.records);
9738
- filteredRecords = filteredRecords.concat(result.records);
9739
- totalFetched += result.records.length;
9740
- hasMoreRecords = result.hasMore;
9741
- renderOptions();
9742
- } else {
9743
- hasMoreRecords = false;
9744
- }
9745
- })
9746
- .catch(function (err) {
9747
- console.error("[RecordSelect] loadMoreRecords error:", err);
9748
- isFetchingMore = false;
9749
- removeLoadingMore();
9313
+
9314
+ fetchRecords(searchTerm, initialLimit, currentPage).then(function (result) {
9315
+ isFetchingMore = false;
9316
+ removeLoadingMore();
9317
+
9318
+ if (result.records.length > 0) {
9319
+ allRecords = allRecords.concat(result.records);
9320
+ filteredRecords = filteredRecords.concat(result.records);
9321
+ totalFetched += result.records.length;
9322
+ hasMoreRecords = result.hasMore;
9323
+ renderOptions();
9324
+ } else {
9750
9325
  hasMoreRecords = false;
9751
- });
9326
+ }
9327
+ }).catch(function (err) {
9328
+ console.error("[RecordSelect] loadMoreRecords error:", err);
9329
+ isFetchingMore = false;
9330
+ removeLoadingMore();
9331
+ hasMoreRecords = false;
9332
+ });
9752
9333
  }
9753
9334
 
9754
9335
  function debouncedSearch() {
@@ -9759,26 +9340,22 @@
9759
9340
  currentPage = 1;
9760
9341
  hasMoreRecords = true;
9761
9342
  totalFetched = 0;
9762
-
9763
- fetchRecords(searchTerm, initialLimit, 1)
9764
- .then(function (result) {
9765
- allRecords = result.records;
9766
- filteredRecords = result.records;
9767
- hasMoreRecords = result.hasMore;
9768
- totalFetched = result.records.length;
9769
-
9770
- if (result.records.length === 0) {
9771
- showEmpty("No results found");
9772
- } else {
9773
- renderOptions();
9774
- }
9775
- scheduleUpdatePosition();
9776
- })
9777
- .catch(function () {
9778
- showEmpty("Search failed");
9779
- hasMoreRecords = false;
9780
- scheduleUpdatePosition();
9781
- });
9343
+
9344
+ fetchRecords(searchTerm, initialLimit, 1).then(function (result) {
9345
+ allRecords = result.records;
9346
+ filteredRecords = result.records;
9347
+ hasMoreRecords = result.hasMore;
9348
+ totalFetched = result.records.length;
9349
+
9350
+ if (result.records.length === 0) {
9351
+ showEmpty("No results found");
9352
+ } else {
9353
+ renderOptions();
9354
+ }
9355
+ }).catch(function () {
9356
+ showEmpty("Search failed");
9357
+ hasMoreRecords = false;
9358
+ });
9782
9359
  }, 500);
9783
9360
  }
9784
9361
 
@@ -9823,7 +9400,7 @@
9823
9400
  size,
9824
9401
  disabled,
9825
9402
  !value,
9826
- canClear && !!value && !disabled,
9403
+ canClear && !!value && !disabled
9827
9404
  );
9828
9405
  if (disabled && isOpen) closeDropdown();
9829
9406
  };
@@ -9842,7 +9419,7 @@
9842
9419
 
9843
9420
 
9844
9421
  // ============================================
9845
- // File 18/41: components/multiselect.js
9422
+ // File 18/37: components/multiselect.js
9846
9423
  // ============================================
9847
9424
 
9848
9425
  /**
@@ -10000,11 +9577,11 @@
10000
9577
  var content = document.createElement("div");
10001
9578
  content.setAttribute("role", "listbox");
10002
9579
  content.setAttribute("aria-multiselectable", "true");
10003
- content.className = "custom-multiselect-content w-full max-h-[45vh] overflow-hidden flex flex-col";
9580
+ content.className = "custom-multiselect-content w-full max-h-[200px] overflow-hidden flex flex-col";
10004
9581
 
10005
9582
  var optionsList = document.createElement("div");
10006
9583
  optionsList.className =
10007
- "overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white";
9584
+ "overflow-y-auto max-h-[200px] p-2 w-full rounded-4 bg-fill-quarternary-fill-white";
10008
9585
 
10009
9586
  function isSelected(optionValue) {
10010
9587
  return values.some(function (v) {
@@ -10109,7 +9686,7 @@
10109
9686
  align: "start",
10110
9687
  closeOnClickOutside: true,
10111
9688
  bodyClassName: "p-0 overflow-hidden",
10112
- panelClassName: "min-w-[var(--trigger-width)] max-h-[45vh] overflow-hidden",
9689
+ panelClassName: "min-w-[var(--trigger-width)] max-h-[200px] overflow-hidden",
10113
9690
  onOpen: function () {
10114
9691
  if (disabled) {
10115
9692
  popover.hide();
@@ -10223,7 +9800,7 @@
10223
9800
 
10224
9801
 
10225
9802
  // ============================================
10226
- // File 19/41: components/enum-multiselect.js
9803
+ // File 19/37: components/enum-multiselect.js
10227
9804
  // ============================================
10228
9805
 
10229
9806
  /**
@@ -10484,7 +10061,7 @@
10484
10061
  var content = document.createElement("div");
10485
10062
  content.setAttribute("role", "listbox");
10486
10063
  content.setAttribute("aria-multiselectable", "true");
10487
- content.className = "w-full min-w-[200px] max-h-[45vh] overflow-hidden flex flex-col";
10064
+ content.className = "w-full min-w-[200px] max-h-[30vh] overflow-hidden flex flex-col";
10488
10065
 
10489
10066
  // Search input (using InputComponent like enum-select)
10490
10067
  var searchContainer = document.createElement("div");
@@ -10545,7 +10122,7 @@
10545
10122
  // Options list
10546
10123
  var optionsList = document.createElement("div");
10547
10124
  optionsList.className =
10548
- "overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white flex-1 min-h-0";
10125
+ "overflow-y-auto max-h-[30vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white flex-1 min-h-0";
10549
10126
 
10550
10127
  content.appendChild(searchContainer);
10551
10128
  content.appendChild(optionsList);
@@ -11047,7 +10624,7 @@
11047
10624
 
11048
10625
 
11049
10626
  // ============================================
11050
- // File 20/41: components/record-multiselect.js
10627
+ // File 20/37: components/record-multiselect.js
11051
10628
  // ============================================
11052
10629
 
11053
10630
  /**
@@ -11203,7 +10780,6 @@
11203
10780
  * @param {string} [config.size] - 'default' | 'large' | 'small'
11204
10781
  * @param {number} [config.initialLimit] - Initial fetch limit (default 50)
11205
10782
  * @param {Array<string>} [config.displayFields] - Fields to display as secondary info (e.g. ["email", "phone"])
11206
- * @param {Object} [config.initialFilter] - Optional filter object to merge with search (e.g. { field: "status", operator: "exact", value: "active" } or { and: [...] })
11207
10783
  * @param {Object} [config.objectSchema] - Optional object type/schema; properties.icon_data { icon?, color? } used for static icon (not used for user; user shows Vivid Avatar)
11208
10784
  * @returns {HTMLElement} Record multiselect container element
11209
10785
  */
@@ -11218,7 +10794,6 @@
11218
10794
  var variant = config.variant || "default";
11219
10795
  var size = config.size || "default";
11220
10796
  var initialLimit = config.initialLimit != null ? config.initialLimit : 50;
11221
- var initialFilter = config.initialFilter || null; // Can be array, object, or function returning either
11222
10797
  var displayFields = config.displayFields || [];
11223
10798
 
11224
10799
  var disabled = config.disabled === true;
@@ -11344,7 +10919,7 @@
11344
10919
  var content = document.createElement("div");
11345
10920
  content.setAttribute("role", "listbox");
11346
10921
  content.setAttribute("aria-multiselectable", "true");
11347
- content.className = "record-multiselect-content max-h-[45vh] overflow-hidden flex flex-col";
10922
+ content.className = "record-multiselect-content max-h-[30vh] overflow-hidden flex flex-col";
11348
10923
 
11349
10924
  var searchWrap = document.createElement("div");
11350
10925
  searchWrap.className = "p-8 pb-4 border-b-1/2 border-border-primary ";
@@ -11394,7 +10969,7 @@
11394
10969
  content.appendChild(searchWrap);
11395
10970
 
11396
10971
  var optionsList = document.createElement("div");
11397
- optionsList.className = "overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white record-multiselect-options";
10972
+ optionsList.className = "overflow-y-auto max-h-[200px] p-2 w-full rounded-4 bg-fill-quarternary-fill-white record-multiselect-options";
11398
10973
 
11399
10974
  // Add scroll listener for infinite scroll
11400
10975
  optionsList.addEventListener("scroll", function () {
@@ -11422,22 +10997,28 @@
11422
10997
  align: "start",
11423
10998
  closeOnClickOutside: true,
11424
10999
  bodyClassName: "p-0 overflow-hidden",
11425
- panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
11000
+ panelClassName: "max-h-[30vh] overflow-hidden",
11426
11001
  onOpen: function () {
11427
11002
  if (disabled) {
11428
11003
  popover.hide();
11429
11004
  return;
11430
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();
11009
+ }
11010
+ });
11431
11011
  container.classList.add("open");
11432
11012
  trigger.setAttribute("aria-expanded", "true");
11433
11013
  searchTerm = "";
11434
11014
  if (searchInputWrapper) searchInputWrapper.setValue("");
11435
11015
  else if (searchInputEl) searchInputEl.value = "";
11016
+ var triggerWidthPx = trigger.offsetWidth + "px";
11017
+ content.style.minWidth = triggerWidthPx;
11018
+ content.style.width = triggerWidthPx;
11436
11019
  if (popover.panel) {
11437
- var triggerWidthPx = trigger.offsetWidth + "px";
11438
- popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
11439
- popover.panel.style.minWidth = triggerWidthPx;
11440
11020
  popover.panel.style.width = triggerWidthPx;
11021
+ popover.panel.style.minWidth = triggerWidthPx;
11441
11022
  }
11442
11023
  loadInitialAndRender();
11443
11024
  setTimeout(function () {
@@ -11516,23 +11097,14 @@
11516
11097
  try {
11517
11098
  if (model && typeof model.select === "function") {
11518
11099
  var q = model.select.apply(model, fields);
11519
- var filters = [];
11520
- var resolvedFilter = typeof initialFilter === 'function' ? initialFilter() : initialFilter;
11521
- console.log('[RecordMultiselect] initialFilter:', resolvedFilter, '| search:', search);
11522
- if (resolvedFilter) {
11523
- filters = filters.concat(Array.isArray(resolvedFilter) ? resolvedFilter : [resolvedFilter]);
11524
- }
11525
11100
  if (search && search.trim()) {
11526
- filters.push({
11101
+ q = q.filterBy({
11527
11102
  or: [
11528
11103
  { field: "name", operator: "contains", value: search.trim() },
11529
11104
  { field: "id", operator: "eq", value: search.trim() },
11530
11105
  ],
11531
11106
  });
11532
11107
  }
11533
- if (filters.length > 0) {
11534
- q = q.filterBy(filters.length === 1 ? filters[0] : { and: filters });
11535
- }
11536
11108
  var orderBy = ["name"];
11537
11109
  if (objectSlug === "account") orderBy.push("-ParentId");
11538
11110
  return q
@@ -11791,16 +11363,6 @@
11791
11363
  }
11792
11364
  }
11793
11365
 
11794
- function scheduleUpdatePosition() {
11795
- if (popover && typeof popover.updatePosition === "function") {
11796
- requestAnimationFrame(function () {
11797
- requestAnimationFrame(function () {
11798
- popover.updatePosition();
11799
- });
11800
- });
11801
- }
11802
- }
11803
-
11804
11366
  function loadInitialAndRender() {
11805
11367
  showLoading();
11806
11368
  currentPage = 1;
@@ -11819,11 +11381,9 @@
11819
11381
  } else {
11820
11382
  renderOptions();
11821
11383
  }
11822
- scheduleUpdatePosition();
11823
11384
  }).catch(function () {
11824
11385
  showEmpty("Failed to load records");
11825
11386
  hasMoreRecords = false;
11826
- scheduleUpdatePosition();
11827
11387
  });
11828
11388
  }
11829
11389
 
@@ -11875,11 +11435,9 @@
11875
11435
  } else {
11876
11436
  renderOptions();
11877
11437
  }
11878
- scheduleUpdatePosition();
11879
11438
  }).catch(function () {
11880
11439
  showEmpty("Search failed");
11881
11440
  hasMoreRecords = false;
11882
- scheduleUpdatePosition();
11883
11441
  });
11884
11442
  }, 500);
11885
11443
  }
@@ -11949,7 +11507,7 @@
11949
11507
 
11950
11508
 
11951
11509
  // ============================================
11952
- // File 21/41: components/input.js
11510
+ // File 21/37: components/input.js
11953
11511
  // ============================================
11954
11512
 
11955
11513
  /**
@@ -11976,7 +11534,7 @@
11976
11534
 
11977
11535
  var WRAPPER_CLASS = {
11978
11536
  base:
11979
- "group flex items-center border-1/2 border-border-primary rounded-4 text-typography-primary-text gap-x-8 w-full transition-all ease-in-out group-has-[:disabled]:cursor-not-allowed group-has-[:disabled]:border-border-primary group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:text-typography-quaternary-text group-has-[:disabled]:hover:border-border-primary group-has-[:disabled]:[&_input]:cursor-not-allowed group-has-[:disabled]:[&_input]:text-typography-quaternary-text",
11537
+ "group flex items-center border-1/2 border-border-primary rounded-4 text-typography-primary-text gap-x-8 w-full transition-all ease-in-out",
11980
11538
  default:
11981
11539
  "bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
11982
11540
  error:
@@ -12051,16 +11609,13 @@
12051
11609
  var isPassword = type === "password";
12052
11610
 
12053
11611
  var wrapper = document.createElement("div");
12054
- var sizeClass = inputSize === "large" ? WRAPPER_CLASS.sizeLarge : inputSize === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault;
12055
- function applyWrapperClasses() {
12056
- wrapper.className = join(
12057
- WRAPPER_CLASS.base,
12058
- disabled ? WRAPPER_CLASS.disabled : (WRAPPER_CLASS[variant] || WRAPPER_CLASS.default),
12059
- sizeClass,
12060
- config.className || ""
12061
- );
12062
- }
12063
- applyWrapperClasses();
11612
+ wrapper.className = join(
11613
+ WRAPPER_CLASS.base,
11614
+ WRAPPER_CLASS[variant] || WRAPPER_CLASS.default,
11615
+ inputSize === "large" ? WRAPPER_CLASS.sizeLarge : inputSize === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault,
11616
+ disabled ? WRAPPER_CLASS.disabled : "",
11617
+ config.className || ""
11618
+ );
12064
11619
  wrapper.setAttribute("data-input-variant", variant);
12065
11620
 
12066
11621
  if (config.prefixNode) {
@@ -12190,12 +11745,19 @@
12190
11745
  wrapper.setVariant = function (v) {
12191
11746
  variant = v;
12192
11747
  wrapper.setAttribute("data-input-variant", v);
12193
- applyWrapperClasses();
11748
+ wrapper.className = join(
11749
+ WRAPPER_CLASS.base,
11750
+ WRAPPER_CLASS[variant] || WRAPPER_CLASS.default,
11751
+ inputSize === "large" ? WRAPPER_CLASS.sizeLarge : inputSize === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault,
11752
+ disabled ? WRAPPER_CLASS.disabled : "",
11753
+ config.className || ""
11754
+ );
12194
11755
  };
12195
11756
  wrapper.setDisabled = function (d) {
12196
11757
  disabled = !!d;
12197
11758
  input.disabled = disabled;
12198
- applyWrapperClasses();
11759
+ wrapper.classList.toggle("cursor-not-allowed", disabled);
11760
+ wrapper.classList.toggle("opacity-60", disabled);
12199
11761
  };
12200
11762
 
12201
11763
  return wrapper;
@@ -12210,7 +11772,7 @@
12210
11772
 
12211
11773
 
12212
11774
  // ============================================
12213
- // File 22/41: components/currency.js
11775
+ // File 22/37: components/currency.js
12214
11776
  // ============================================
12215
11777
 
12216
11778
  /**
@@ -12240,7 +11802,7 @@
12240
11802
  sizeLarge: "",
12241
11803
  sizeSmall: "",
12242
11804
  disabled:
12243
- "pointer-events-none cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
11805
+ "cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
12244
11806
  };
12245
11807
 
12246
11808
  // Currency type label: fit-content, separator (border-r) on type only, full height
@@ -12427,12 +11989,7 @@
12427
11989
  wrapper.setDisabled = function (d) {
12428
11990
  disabled = !!d;
12429
11991
  input.disabled = disabled;
12430
- wrapper.className = join(
12431
- WRAPPER_CLASS.base,
12432
- WRAPPER_CLASS[variant] != null ? WRAPPER_CLASS[variant] : WRAPPER_CLASS.default,
12433
- disabled ? WRAPPER_CLASS.disabled : "",
12434
- config.className || ""
12435
- );
11992
+ wrapper.classList.toggle("cursor-not-allowed", disabled);
12436
11993
  };
12437
11994
 
12438
11995
  return wrapper;
@@ -12448,7 +12005,7 @@
12448
12005
 
12449
12006
 
12450
12007
  // ============================================
12451
- // File 23/41: components/textarea.js
12008
+ // File 23/37: components/textarea.js
12452
12009
  // ============================================
12453
12010
 
12454
12011
  /**
@@ -12473,7 +12030,7 @@
12473
12030
  warning:
12474
12031
  "min-h-[80px] border-warning-base hover:border-warning-base focus:border-warning-base",
12475
12032
  disabled:
12476
- "pointer-events-none cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
12033
+ "cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
12477
12034
  };
12478
12035
 
12479
12036
  function join() {
@@ -12568,347 +12125,7 @@
12568
12125
 
12569
12126
 
12570
12127
  // ============================================
12571
- // File 24/41: components/richtext-editor.js
12572
- // ============================================
12573
-
12574
- /**
12575
- * Rich Text Editor Component (vanilla JS)
12576
- * Toolbar + contenteditable area with formatting (bold, italic, underline, headings, lists, alignment, link, image, code block, undo/redo).
12577
- * Styling matches design: rounded-12, toolbar bg-fill-tertiary-fill-light-gray, content area with min-height.
12578
- */
12579
-
12580
- (function (global) {
12581
-
12582
- var RICH_TEXT_CONTENT_STYLES =
12583
- ".rich-text-editor-content ul{list-style-type:disc;padding-left:1.5em;margin:0.5em 0}" +
12584
- ".rich-text-editor-content ol{list-style-type:decimal;padding-left:1.5em;margin:0.5em 0}" +
12585
- ".rich-text-editor-content li{margin:0.25em 0}" +
12586
- ".rich-text-editor-content li p{margin:0}" +
12587
- ".rich-text-editor-content h1{font-size:1.5rem;font-weight:700;line-height:1.3;margin:0.75em 0 0.5em}" +
12588
- ".rich-text-editor-content h2{font-size:1.25rem;font-weight:600;line-height:1.3;margin:0.75em 0 0.5em}" +
12589
- ".rich-text-editor-content h3{font-size:1.125rem;font-weight:600;line-height:1.3;margin:0.75em 0 0.5em}" +
12590
- ".rich-text-editor-content p{margin:0.5em 0}" +
12591
- ".rich-text-editor-content a{color:var(--color-primary-500);text-decoration:underline;cursor:pointer}" +
12592
- ".rich-text-editor-content pre{background:var(--color-neutral-100);border-radius:var(--sizes-size-8);padding:0.75em 1em;margin:0.5em 0;overflow-x:auto}" +
12593
- ".rich-text-editor-content code{font-family:ui-monospace,monospace;font-size:0.875em}" +
12594
- ".rich-text-editor-content img{max-width:100%;height:auto;margin:0.5em 0}" +
12595
- ".rich-text-editor-content blockquote{border-left:3px solid var(--color-neutral-200);padding-left:1em;margin:0.5em 0;color:var(--color-neutral-600)}" +
12596
- ".rich-text-editor-content hr{border:none;border-top:1px solid var(--color-neutral-150);margin:1em 0}" +
12597
- ".rich-text-editor-content .ProseMirror,.rich-text-editor-content [contenteditable]{outline:none}";
12598
-
12599
- function join() {
12600
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
12601
- }
12602
-
12603
- function getDep(name) {
12604
- if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
12605
- var c = global.FlowUI._getComponent(name);
12606
- if (c) return c;
12607
- }
12608
- return global[name];
12609
- }
12610
-
12611
- /** Get Tabler icon element (16px) from Icon component for toolbar. */
12612
- function getTablerIcon(iconName) {
12613
- var Icon = getDep("Icon");
12614
- if (!Icon || !Icon.iconMap || !Icon.iconMap[iconName]) return null;
12615
- var svgStr = Icon.iconMap[iconName];
12616
- var s16 = svgStr.replace(/width="24"/, 'width="16"').replace(/height="24"/, 'height="16"').replace(/width="20"/, 'width="16"').replace(/height="20"/, 'height="16"');
12617
- var span = document.createElement("span");
12618
- span.className = "flex items-center justify-center size-16";
12619
- span.innerHTML = s16;
12620
- return span;
12621
- }
12622
-
12623
- function createToolbarButton(opts) {
12624
- var Button = getDep("Button");
12625
- if (!Button || typeof Button.create !== "function") {
12626
- throw new Error("RichTextEditor requires Button");
12627
- }
12628
- var icon = opts.iconStr ? getTablerIcon(opts.iconStr) : null;
12629
- return Button.create({
12630
- variant: "outline",
12631
- size: "default",
12632
- title: opts.title,
12633
- icon: icon,
12634
- onClick: opts.onClick,
12635
- disabled: opts.disabled,
12636
- });
12637
- }
12638
-
12639
- function createSeparator() {
12640
- var sep = document.createElement("div");
12641
- sep.className = "w-px h-16 bg-border-primary mx-4";
12642
- sep.setAttribute("aria-hidden", "true");
12643
- return sep;
12644
- }
12645
-
12646
- /**
12647
- * Create a rich text editor
12648
- * @param {Object} config
12649
- * @param {string} [config.value] - Initial HTML content
12650
- * @param {string} [config.placeholder] - Placeholder when empty
12651
- * @param {number} [config.minHeightPx] - Min height of editor area (default 400)
12652
- * @param {boolean} [config.disabled]
12653
- * @param {Function} [config.onChange] - (html: string) => void
12654
- * @returns {HTMLElement} Wrapper element with getValue/setValue/setDisabled/getInput
12655
- */
12656
- function create(config) {
12657
- var value = config.value != null ? String(config.value) : "";
12658
- var placeholder = config.placeholder != null ? config.placeholder : "";
12659
- var minHeightPx = config.minHeightPx != null ? config.minHeightPx : 400;
12660
- var disabled = !!config.disabled;
12661
- var onChange = config.onChange;
12662
-
12663
- var wrapper = document.createElement("div");
12664
- wrapper.className = "w-full rounded-12 border border-borderColor-border-primary shadow-soft-2x-small";
12665
-
12666
- var styleEl = document.createElement("style");
12667
- styleEl.textContent = RICH_TEXT_CONTENT_STYLES;
12668
- wrapper.appendChild(styleEl);
12669
-
12670
- var toolbar = document.createElement("div");
12671
- toolbar.className =
12672
- "flex flex-wrap gap-4 rounded-t-12 border-borderColor-border-primary bg-fill-tertiary-fill-light-gray p-6";
12673
- toolbar.setAttribute("role", "toolbar");
12674
-
12675
- var editorEl = document.createElement("div");
12676
- editorEl.contentEditable = !disabled;
12677
- editorEl.className = join(
12678
- "rich-text-editor-content max-w-none rounded-b-12 border-t border-borderColor-border-primary p-8 text-reg-14 text-typography-primary-text"
12679
- );
12680
- editorEl.style.minHeight = minHeightPx + "px";
12681
- if (value) editorEl.innerHTML = value;
12682
- editorEl.setAttribute("data-placeholder", placeholder);
12683
-
12684
- function isEmpty() {
12685
- var text = (editorEl.textContent || "").trim();
12686
- if (text) return false;
12687
- var html = (editorEl.innerHTML || "").replace(/<br\s*\/?>/gi, "\n").replace(/<[^>]+>/g, "");
12688
- return !html.trim();
12689
- }
12690
- function updatePlaceholder() {
12691
- if (placeholder && isEmpty()) {
12692
- editorEl.classList.add("empty");
12693
- editorEl.setAttribute("data-placeholder", placeholder);
12694
- } else {
12695
- editorEl.classList.remove("empty");
12696
- editorEl.removeAttribute("data-placeholder");
12697
- }
12698
- }
12699
- updatePlaceholder();
12700
-
12701
- function getHtml() {
12702
- return editorEl.innerHTML;
12703
- }
12704
- function setHtml(html) {
12705
- editorEl.innerHTML = html || "";
12706
- updatePlaceholder();
12707
- }
12708
- function notifyChange() {
12709
- if (typeof onChange === "function") onChange(getHtml());
12710
- }
12711
-
12712
- function isActive(cmd, val) {
12713
- try {
12714
- return document.queryCommandState(cmd);
12715
- } catch (e) {
12716
- return false;
12717
- }
12718
- }
12719
- function blockTag() {
12720
- var sel = window.getSelection();
12721
- if (!sel || sel.rangeCount === 0) return null;
12722
- var node = sel.anchorNode;
12723
- while (node && node !== editorEl) {
12724
- if (node.nodeType === 1) {
12725
- var n = node.nodeName.toLowerCase();
12726
- if (["h1", "h2", "h3", "p", "div", "pre", "blockquote"].indexOf(n) !== -1) return n;
12727
- }
12728
- node = node.parentNode;
12729
- }
12730
- return null;
12731
- }
12732
- function isAlignment(align) {
12733
- try {
12734
- if (align === "left") return document.queryCommandState("justifyLeft");
12735
- if (align === "center") return document.queryCommandState("justifyCenter");
12736
- if (align === "right") return document.queryCommandState("justifyRight");
12737
- } catch (e) {}
12738
- return false;
12739
- }
12740
-
12741
- function refreshToolbar() {
12742
- toolbar.querySelectorAll("button").forEach(function (btn) {
12743
- var cmd = btn.getAttribute("data-command");
12744
- var val = btn.getAttribute("data-value");
12745
- if (!cmd) return;
12746
- var active = false;
12747
- if (cmd === "formatBlock") active = blockTag() === val;
12748
- else if (cmd === "justifyLeft" && val === "left") active = isAlignment("left");
12749
- else if (cmd === "justifyCenter" && val === "center") active = isAlignment("center");
12750
- else if (cmd === "justifyRight" && val === "right") active = isAlignment("right");
12751
- else active = isActive(cmd);
12752
- btn.classList.toggle("bg-primary-base", active);
12753
- btn.classList.toggle("border-primary-base", active);
12754
- btn.classList.toggle("text-typography-invert-text", active);
12755
- btn.classList.toggle("bg-fill-quarternary-fill-white", !active);
12756
- btn.classList.toggle("border-border-primary", !active);
12757
- btn.classList.toggle("text-typography-primary-text", !active);
12758
- });
12759
- }
12760
-
12761
- function exec(cmd, value) {
12762
- editorEl.focus();
12763
- document.execCommand(cmd, false, value != null ? value : null);
12764
- refreshToolbar();
12765
- notifyChange();
12766
- }
12767
-
12768
- function insertCodeBlock() {
12769
- editorEl.focus();
12770
- var sel = window.getSelection();
12771
- if (sel && sel.rangeCount) {
12772
- var range = sel.getRangeAt(0);
12773
- var pre = document.createElement("pre");
12774
- var code = document.createElement("code");
12775
- code.textContent = "code here";
12776
- pre.appendChild(code);
12777
- range.insertNode(pre);
12778
- range.setStart(code, 0);
12779
- range.setEnd(code, 0);
12780
- sel.removeAllRanges();
12781
- sel.addRange(range);
12782
- }
12783
- refreshToolbar();
12784
- notifyChange();
12785
- }
12786
-
12787
- function addLink() {
12788
- var url = window.prompt("Enter the URL:", "https://");
12789
- if (url) {
12790
- exec("createLink", url);
12791
- }
12792
- }
12793
-
12794
- function addImage() {
12795
- var input = document.createElement("input");
12796
- input.type = "file";
12797
- input.accept = "image/*";
12798
- input.onchange = function (e) {
12799
- var file = e.target && e.target.files && e.target.files[0];
12800
- if (file) {
12801
- var reader = new FileReader();
12802
- reader.onload = function (ev) {
12803
- var src = ev.target && ev.target.result;
12804
- if (src) {
12805
- editorEl.focus();
12806
- document.execCommand("insertImage", false, src);
12807
- notifyChange();
12808
- }
12809
- };
12810
- reader.readAsDataURL(file);
12811
- }
12812
- };
12813
- input.click();
12814
- }
12815
-
12816
- function undo() {
12817
- editorEl.focus();
12818
- document.execCommand("undo", false, null);
12819
- refreshToolbar();
12820
- notifyChange();
12821
- }
12822
- function redo() {
12823
- editorEl.focus();
12824
- document.execCommand("redo", false, null);
12825
- refreshToolbar();
12826
- notifyChange();
12827
- }
12828
-
12829
- function addBtn(iconStr, title, onClick, dataCommand, dataValue) {
12830
- var btn = createToolbarButton({
12831
- iconStr: iconStr,
12832
- title: title,
12833
- onClick: function () {
12834
- if (disabled) return;
12835
- onClick();
12836
- }});
12837
- if (dataCommand) btn.setAttribute("data-command", dataCommand);
12838
- if (dataValue != null) btn.setAttribute("data-value", dataValue);
12839
- toolbar.appendChild(btn);
12840
- }
12841
-
12842
- addBtn("IconBold", "Bold (Ctrl+B)", function () { exec("bold"); }, "bold");
12843
- addBtn("IconItalic", "Italic (Ctrl+I)", function () { exec("italic"); }, "italic");
12844
- addBtn("IconUnderline", "Underline (Ctrl+U)", function () { exec("underline"); }, "underline");
12845
- toolbar.appendChild(createSeparator());
12846
- addBtn("IconH1", "Heading 1", function () { exec("formatBlock", "h1"); }, "formatBlock", "h1");
12847
- addBtn("IconH2", "Heading 2", function () { exec("formatBlock", "h2"); }, "formatBlock", "h2");
12848
- addBtn("IconH3", "Heading 3", function () { exec("formatBlock", "h3"); }, "formatBlock", "h3");
12849
- toolbar.appendChild(createSeparator());
12850
- addBtn("IconList", "Bullet List", function () { exec("insertUnorderedList"); }, "insertUnorderedList");
12851
- addBtn("IconListNumbers", "Ordered List", function () { exec("insertOrderedList"); }, "insertOrderedList");
12852
- toolbar.appendChild(createSeparator());
12853
- addBtn("IconAlignLeft", "Align Left", function () { exec("justifyLeft"); }, "justifyLeft", "left");
12854
- addBtn("IconAlignCenter", "Align Center", function () { exec("justifyCenter"); }, "justifyCenter", "center");
12855
- addBtn("IconAlignRight", "Align Right", function () { exec("justifyRight"); }, "justifyRight", "right");
12856
- toolbar.appendChild(createSeparator());
12857
- addBtn("IconCode", "Code Block", insertCodeBlock, "formatBlock", "pre");
12858
- addBtn("IconLink", "Add Link", addLink, "link");
12859
- addBtn("IconPhoto", "Insert Image", addImage);
12860
- toolbar.appendChild(createSeparator());
12861
- addBtn("IconArrowBackUp", "Undo", undo);
12862
- addBtn("IconArrowForwardUp", "Redo", redo);
12863
-
12864
- editorEl.addEventListener("input", function () {
12865
- updatePlaceholder();
12866
- refreshToolbar();
12867
- notifyChange();
12868
- });
12869
- editorEl.addEventListener("keyup", refreshToolbar);
12870
- editorEl.addEventListener("mouseup", refreshToolbar);
12871
- editorEl.addEventListener("focus", refreshToolbar);
12872
-
12873
- if (placeholder) {
12874
- var placeholderStyles = document.createElement("style");
12875
- placeholderStyles.textContent =
12876
- ".rich-text-editor-content.empty:before{content:attr(data-placeholder);color:var(--color-neutral-400);pointer-events:none}";
12877
- wrapper.appendChild(placeholderStyles);
12878
- }
12879
-
12880
- wrapper.appendChild(toolbar);
12881
- wrapper.appendChild(editorEl);
12882
-
12883
- wrapper.getInput = function () {
12884
- return editorEl;
12885
- };
12886
- wrapper.getValue = function () {
12887
- return getHtml();
12888
- };
12889
- wrapper.setValue = function (v) {
12890
- setHtml(v);
12891
- };
12892
- wrapper.setDisabled = function (d) {
12893
- disabled = !!d;
12894
- editorEl.contentEditable = !disabled;
12895
- toolbar.querySelectorAll("button").forEach(function (b) {
12896
- b.disabled = disabled;
12897
- });
12898
- };
12899
-
12900
- return wrapper;
12901
- }
12902
-
12903
- global.RichTextEditorComponent = {
12904
- create: create,
12905
- };
12906
- })(typeof window !== "undefined" ? window : undefined);
12907
-
12908
-
12909
-
12910
- // ============================================
12911
- // File 25/41: components/checkbox.js
12128
+ // File 24/37: components/checkbox.js
12912
12129
  // ============================================
12913
12130
 
12914
12131
  /**
@@ -12947,18 +12164,10 @@
12947
12164
  };
12948
12165
 
12949
12166
  var CHECKBOX_BASE_CLASS =
12950
- "flex items-center justify-center rounded-2 border-1/2 border-borderColor-border-primary bg-fill-quarternary-fill-white p-4 transition-all";
12951
-
12952
- var CHECKBOX_ACTIVE_CLASS =
12953
- "hover:border-primary-base hover:shadow-primary-focused cursor-pointer";
12954
-
12955
- var CHECKBOX_DISABLED_CLASS =
12956
- "cursor-not-allowed opacity-50";
12167
+ "flex items-center justify-center rounded-2 border-1/2 border-borderColor-border-primary bg-fill-quarternary-fill-white p-4 transition-all hover:border-primary-base hover:shadow-primary-focused disabled:cursor-not-allowed disabled:border-borderColor-border-primary disabled:opacity-50 disabled:hover:shadow-none";
12957
12168
 
12958
12169
  var CHECKBOX_CHECKED_CLASS =
12959
- "data-checked:border-transparent data-checked:bg-primary-base";
12960
- var CHECKBOX_CHECKED_ACTIVE_CLASS =
12961
- "data-checked:hover:border-primary-base data-checked:hover:shadow-primary-focused";
12170
+ "data-checked:border-transparent data-checked:bg-primary-base data-checked:hover:border-primary-base data-checked:hover:shadow-primary-focused data-checked:disabled:border-borderColor-border-primary";
12962
12171
 
12963
12172
  var LABEL_BASE_CLASS =
12964
12173
  "cursor-pointer pb-0 text-reg-12 leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70";
@@ -13022,16 +12231,12 @@
13022
12231
 
13023
12232
  // Custom checkbox visual
13024
12233
  var checkboxBox = document.createElement("div");
13025
- function applyCheckboxBoxClasses() {
13026
- var sizeClass = CHECKBOX_SIZES[size] || CHECKBOX_SIZES.default;
13027
- checkboxBox.className = join(
13028
- CHECKBOX_BASE_CLASS,
13029
- disabled ? CHECKBOX_DISABLED_CLASS : join(CHECKBOX_ACTIVE_CLASS, CHECKBOX_CHECKED_ACTIVE_CLASS),
13030
- CHECKBOX_CHECKED_CLASS,
13031
- sizeClass
13032
- );
13033
- }
13034
- applyCheckboxBoxClasses();
12234
+ checkboxBox.className = join(
12235
+ CHECKBOX_BASE_CLASS,
12236
+ CHECKBOX_CHECKED_CLASS,
12237
+ CHECKBOX_SIZES[size] || CHECKBOX_SIZES.default,
12238
+ "cursor-pointer"
12239
+ );
13035
12240
  checkboxBox.setAttribute("role", "checkbox");
13036
12241
  checkboxBox.setAttribute("tabindex", disabled ? "-1" : "0");
13037
12242
  checkboxBox.setAttribute("aria-checked", indeterminate ? "mixed" : checked ? "true" : "false");
@@ -13148,7 +12353,6 @@
13148
12353
  } else {
13149
12354
  checkboxBox.removeAttribute("aria-disabled");
13150
12355
  }
13151
- applyCheckboxBoxClasses();
13152
12356
  updateCheckedState();
13153
12357
  };
13154
12358
 
@@ -13181,210 +12385,7 @@
13181
12385
 
13182
12386
 
13183
12387
  // ============================================
13184
- // File 26/41: components/checkbox-group.js
13185
- // ============================================
13186
-
13187
- /**
13188
- * CheckboxGroup Component (vanilla JS)
13189
- * Multi-select via checkboxes; same API as MultiSelect (options, value array, onValuesChange).
13190
- * Uses input.js-style variants and sizes for the group wrapper.
13191
- */
13192
-
13193
- (function (global) {
13194
-
13195
- // Wrapper classes aligned with input.js variants
13196
- var WRAPPER_CLASS = {
13197
- base:
13198
- "group flex flex-col border-1/2 border-border-primary rounded-4 text-typography-primary-text w-full transition-all ease-in-out group-has-[:disabled]:cursor-not-allowed group-has-[:disabled]:border-border-primary group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:text-typography-quaternary-text",
13199
- default:
13200
- "bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
13201
- error:
13202
- "border-error-base bg-fill-quarternary-fill-white hover:border-error-base focus-within:border-error-base",
13203
- warning:
13204
- "border-warning-base bg-fill-quarternary-fill-white hover:border-warning-base focus-within:border-warning-base",
13205
- success:
13206
- "border-success-base bg-fill-quarternary-fill-white hover:border-success-base focus-within:border-success-base",
13207
- borderless:
13208
- "border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
13209
- inline:
13210
- "border-transparent shadow-none rounded-0 bg-fill-quarternary-fill-white hover:bg-fill-tertiary-fill-light-gray focus-within:border-transparent focus:bg-fill-tertiary-fill-light-gray focus-within:bg-fill-tertiary-fill-light-gray",
13211
- sizeDefault: "px-12 py-6 gap-6",
13212
- sizeLarge: "px-12 py-8 gap-8",
13213
- sizeSmall: "px-12 py-4 gap-4",
13214
- disabled:
13215
- "cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
13216
- };
13217
-
13218
- function join() {
13219
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
13220
- }
13221
-
13222
- function getOptionValue(opt) {
13223
- return opt.value !== undefined && opt.value !== null
13224
- ? opt.value
13225
- : opt.slug || opt.id;
13226
- }
13227
-
13228
- function getOptionLabel(opt) {
13229
- return opt.label || opt.name || opt.display_name || opt.value;
13230
- }
13231
-
13232
- function getDep(name) {
13233
- if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
13234
- var c = global.FlowUI._getComponent(name);
13235
- if (c) return c;
13236
- }
13237
- return global[name];
13238
- }
13239
-
13240
- /**
13241
- * Create a checkbox group component (multiselect-like: multiple values, options array)
13242
- * @param {Object} config
13243
- * @param {string} [config.fieldId] - Field ID for state management
13244
- * @param {Array} config.options - Array of { value, label } or { slug, display_name }
13245
- * @param {Array} [config.value] - Current selected values (array)
13246
- * @param {Function} config.onValuesChange - Change handler (values: string[])
13247
- * @param {boolean} [config.disabled] - Whether all checkboxes are disabled
13248
- * @param {string} [config.variant] - 'default' | 'error' | 'warning' | 'success' | 'borderless' | 'inline'
13249
- * @param {string} [config.size] - 'default' | 'large' | 'small'
13250
- * @param {string} [config.layout] - 'vertical' | 'horizontal'
13251
- * @param {string} [config.className] - Extra class on wrapper
13252
- * @returns {HTMLElement} CheckboxGroup container element
13253
- */
13254
- function createCheckboxGroup(config) {
13255
- var fieldId = config.fieldId;
13256
- var options = config.options || [];
13257
- var onValuesChange = config.onValuesChange;
13258
- var variant = config.variant || "default";
13259
- var size = config.size || "default";
13260
- var disabled = config.disabled === true;
13261
- var layout = config.layout || "vertical";
13262
- var className = config.className || "";
13263
-
13264
- var values = Array.isArray(config.value)
13265
- ? config.value.slice()
13266
- : Array.isArray(config.values)
13267
- ? config.values.slice()
13268
- : [];
13269
-
13270
- var Checkbox = getDep("Checkbox");
13271
- if (!Checkbox || typeof Checkbox.create !== "function") {
13272
- throw new Error("CheckboxGroup requires the Checkbox component. Load checkbox.js before checkbox-group.js.");
13273
- }
13274
-
13275
- var container = document.createElement("div");
13276
- container.setAttribute("role", "group");
13277
- container.setAttribute("aria-label", config.ariaLabel || "Checkbox group");
13278
- if (fieldId) container.setAttribute("data-field-id", fieldId);
13279
-
13280
- var sizeClass = size === "large" ? WRAPPER_CLASS.sizeLarge : size === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault;
13281
- function applyWrapperClasses() {
13282
- container.className = join(
13283
- WRAPPER_CLASS.base,
13284
- disabled ? WRAPPER_CLASS.disabled : (WRAPPER_CLASS[variant] || WRAPPER_CLASS.default),
13285
- sizeClass,
13286
- layout === "horizontal" ? "flex-row flex-wrap" : "flex-col",
13287
- "custom-checkbox-group",
13288
- className
13289
- );
13290
- }
13291
- applyWrapperClasses();
13292
- container.setAttribute("data-checkbox-group-variant", variant);
13293
-
13294
- function isSelected(optionValue) {
13295
- return values.some(function (v) {
13296
- return v === optionValue || String(v) === String(optionValue);
13297
- });
13298
- }
13299
-
13300
- var optionsContainer = document.createElement("div");
13301
- optionsContainer.className = join(
13302
- "flex gap-8",
13303
- layout === "horizontal" ? "flex-row flex-wrap" : "flex-col"
13304
- );
13305
-
13306
- function buildOptions() {
13307
- optionsContainer.innerHTML = "";
13308
- if (options.length === 0) {
13309
- var empty = document.createElement("div");
13310
- empty.className = "!text-reg-13 text-typography-quaternary-text py-4";
13311
- empty.textContent = "No options available";
13312
- optionsContainer.appendChild(empty);
13313
- return;
13314
- }
13315
-
13316
- options.forEach(function (opt, index) {
13317
- var optionValue = getOptionValue(opt);
13318
- var optionLabel = getOptionLabel(opt);
13319
- var optionDisabled = disabled || !!opt.disabled;
13320
- var checked = isSelected(optionValue);
13321
-
13322
- var cb = Checkbox.create({
13323
- id: (fieldId || "cbg") + "-" + index,
13324
- name: fieldId ? fieldId + "[]" : "checkbox-group-" + index,
13325
- checked: checked,
13326
- disabled: optionDisabled,
13327
- label: optionLabel,
13328
- align: "left",
13329
- size: size === "large" ? "large" : size === "small" ? "small" : "default",
13330
- onChange: function (isChecked) {
13331
- if (optionDisabled) return;
13332
- if (isChecked) {
13333
- if (!values.some(function (v) { return v === optionValue || String(v) === String(optionValue); })) {
13334
- values.push(optionValue);
13335
- }
13336
- } else {
13337
- var idx = values.findIndex(function (v) {
13338
- return v === optionValue || String(v) === String(optionValue);
13339
- });
13340
- if (idx >= 0) values.splice(idx, 1);
13341
- }
13342
- if (onValuesChange) onValuesChange(values.slice());
13343
- },
13344
- });
13345
- optionsContainer.appendChild(cb);
13346
- });
13347
- }
13348
-
13349
- buildOptions();
13350
- container.appendChild(optionsContainer);
13351
-
13352
- container.updateValues = function (newValues) {
13353
- values = Array.isArray(newValues) ? newValues.slice() : [];
13354
- buildOptions();
13355
- };
13356
-
13357
- container.setDisabled = function (isDisabled) {
13358
- disabled = !!isDisabled;
13359
- applyWrapperClasses();
13360
- var wrappers = optionsContainer.querySelectorAll(":scope > div");
13361
- for (var i = 0; i < wrappers.length; i++) {
13362
- if (typeof wrappers[i].setDisabled === "function") wrappers[i].setDisabled(disabled);
13363
- }
13364
- };
13365
-
13366
- container.setVariant = function (v) {
13367
- variant = v;
13368
- container.setAttribute("data-checkbox-group-variant", v);
13369
- applyWrapperClasses();
13370
- };
13371
-
13372
- container.getValues = function () {
13373
- return values.slice();
13374
- };
13375
-
13376
- return container;
13377
- }
13378
-
13379
- global.CheckboxGroup = {
13380
- create: createCheckboxGroup,
13381
- };
13382
- })(typeof window !== "undefined" ? window : undefined);
13383
-
13384
-
13385
-
13386
- // ============================================
13387
- // File 27/41: components/radio-group.js
12388
+ // File 25/37: components/radio-group.js
13388
12389
  // ============================================
13389
12390
 
13390
12391
  /**
@@ -13795,7 +12796,7 @@
13795
12796
 
13796
12797
 
13797
12798
  // ============================================
13798
- // File 28/41: components/enumeration.js
12799
+ // File 26/37: components/enumeration.js
13799
12800
  // ============================================
13800
12801
 
13801
12802
  /**
@@ -13807,7 +12808,7 @@
13807
12808
  (function (global) {
13808
12809
 
13809
12810
  var BASE_CLASS =
13810
- "flex items-center border-1/2 rounded-4 text-typography-primary-text gap-4 !text-reg-13";
12811
+ "flex items-center border rounded-4 text-typography-primary-text gap-4 !text-reg-13";
13811
12812
 
13812
12813
  var VARIANTS = {
13813
12814
  default:
@@ -13831,7 +12832,7 @@
13831
12832
  };
13832
12833
 
13833
12834
  var DISABLED_CLASS =
13834
- "pointer-events-none !cursor-not-allowed opacity-50 bg-fill-tertiary-fill-light-gray";
12835
+ "pointer-events-none !cursor-not-allowed opacity-50";
13835
12836
  var READONLY_CLASS = "pointer-events-none";
13836
12837
 
13837
12838
  var ITEM_BASE_CLASS =
@@ -13892,21 +12893,18 @@
13892
12893
  var disabled = opts.disabled === true;
13893
12894
  var readOnly = opts.readOnly === true;
13894
12895
  var className = opts.className || "";
13895
- var onValueChange = opts.onValueChange;
13896
- var children = opts.children;
13897
-
13898
- var wrapper = document.createElement("div");
13899
- function applyWrapperClasses() {
13900
- wrapper.className = join(
13901
- BASE_CLASS,
13902
- VARIANTS[variant] != null ? VARIANTS[variant] : VARIANTS.default,
13903
- SIZES[size] != null ? SIZES[size] : SIZES.default,
13904
- disabled ? DISABLED_CLASS : "",
13905
- readOnly ? READONLY_CLASS : "",
13906
- className
13907
- );
13908
- }
13909
- applyWrapperClasses();
12896
+ var onValueChange = opts.onValueChange;
12897
+ var children = opts.children;
12898
+
12899
+ var wrapper = document.createElement("div");
12900
+ wrapper.className = join(
12901
+ BASE_CLASS,
12902
+ VARIANTS[variant] != null ? VARIANTS[variant] : VARIANTS.default,
12903
+ SIZES[size] != null ? SIZES[size] : SIZES.default,
12904
+ disabled ? DISABLED_CLASS : "",
12905
+ readOnly ? READONLY_CLASS : "",
12906
+ className
12907
+ );
13910
12908
  wrapper.setAttribute("data-enumeration-variant", variant);
13911
12909
 
13912
12910
  var count =
@@ -13976,22 +12974,6 @@
13976
12974
  }
13977
12975
  }
13978
12976
 
13979
- wrapper.setDisabled = function (d) {
13980
- disabled = d === true;
13981
- for (var j = 0; j < itemElements.length; j++) {
13982
- itemElements[j].setAttribute("tabindex", disabled || readOnly ? "-1" : "0");
13983
- }
13984
- applyWrapperClasses();
13985
- };
13986
-
13987
- wrapper.setReadOnly = function (r) {
13988
- readOnly = r === true;
13989
- for (var j = 0; j < itemElements.length; j++) {
13990
- itemElements[j].setAttribute("tabindex", disabled || readOnly ? "-1" : "0");
13991
- }
13992
- applyWrapperClasses();
13993
- };
13994
-
13995
12977
  return wrapper;
13996
12978
  }
13997
12979
 
@@ -14033,7 +13015,7 @@
14033
13015
 
14034
13016
 
14035
13017
  // ============================================
14036
- // File 29/41: components/time-picker.js
13018
+ // File 27/37: components/time-picker.js
14037
13019
  // ============================================
14038
13020
 
14039
13021
  /**
@@ -14394,7 +13376,7 @@
14394
13376
 
14395
13377
 
14396
13378
  // ============================================
14397
- // File 30/41: components/duration/duration-utils.js
13379
+ // File 28/37: components/duration/duration-utils.js
14398
13380
  // ============================================
14399
13381
 
14400
13382
  /**
@@ -14564,7 +13546,7 @@
14564
13546
 
14565
13547
 
14566
13548
  // ============================================
14567
- // File 31/41: components/duration/duration-constants.js
13549
+ // File 29/37: components/duration/duration-constants.js
14568
13550
  // ============================================
14569
13551
 
14570
13552
  /**
@@ -14616,7 +13598,7 @@
14616
13598
 
14617
13599
 
14618
13600
  // ============================================
14619
- // File 32/41: components/duration/duration.js
13601
+ // File 30/37: components/duration/duration.js
14620
13602
  // ============================================
14621
13603
 
14622
13604
  /**
@@ -14660,7 +13642,7 @@
14660
13642
  sizeLarge: "px-12 py-8",
14661
13643
  sizeSmall: "px-12 py-4",
14662
13644
  disabled:
14663
- "pointer-events-none cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
13645
+ "cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary opacity-60",
14664
13646
  };
14665
13647
 
14666
13648
  function join() {
@@ -15053,13 +14035,8 @@
15053
14035
  };
15054
14036
  container.setDisabled = function (d) {
15055
14037
  disabled = !!d;
15056
- triggerWrapper.className = join(
15057
- TRIGGER_CLASS.base,
15058
- TRIGGER_CLASS[variant] != null ? TRIGGER_CLASS[variant] : TRIGGER_CLASS.default,
15059
- size === "large" ? TRIGGER_CLASS.sizeLarge : size === "small" ? TRIGGER_CLASS.sizeSmall : TRIGGER_CLASS.sizeDefault,
15060
- disabled ? TRIGGER_CLASS.disabled : "",
15061
- className
15062
- );
14038
+ triggerWrapper.classList.toggle("cursor-not-allowed", disabled);
14039
+ triggerWrapper.classList.toggle("opacity-60", disabled);
15063
14040
  triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
15064
14041
  if (disabled) popoverApi.hide();
15065
14042
  };
@@ -15075,7 +14052,7 @@
15075
14052
 
15076
14053
 
15077
14054
  // ============================================
15078
- // File 33/41: components/date-time-picker/date-time-picker-utils.js
14055
+ // File 31/37: components/date-time-picker/date-time-picker-utils.js
15079
14056
  // ============================================
15080
14057
 
15081
14058
  /**
@@ -15334,7 +14311,7 @@
15334
14311
 
15335
14312
 
15336
14313
  // ============================================
15337
- // File 34/41: components/date-time-picker/date-time-picker.js
14314
+ // File 32/37: components/date-time-picker/date-time-picker.js
15338
14315
  // ============================================
15339
14316
 
15340
14317
  /**
@@ -15579,15 +14556,13 @@
15579
14556
  var displayMonth = validDate ? new Date(validDate.getTime()) : new Date();
15580
14557
 
15581
14558
  var triggerWrapper = document.createElement("div");
15582
- function getTriggerClassName(disabledState) {
15583
- return join(
15584
- "group flex items-center border-1/2 border-border-primary rounded-4 text-typography-primary-text gap-x-8 w-full transition-all ease-in-out",
15585
- "bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
15586
- size === "large" ? "px-12 py-8" : size === "small" ? "px-12 py-4" : "px-12 py-6",
15587
- disabledState ? "pointer-events-none cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary" : "cursor-pointer"
15588
- );
15589
- }
15590
- triggerWrapper.className = getTriggerClassName(disabled);
14559
+ var triggerClasses = join(
14560
+ "group flex items-center border-1/2 border-border-primary rounded-4 text-typography-primary-text gap-x-8 w-full transition-all ease-in-out",
14561
+ "bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
14562
+ size === "large" ? "px-12 py-8" : size === "small" ? "px-12 py-4" : "px-12 py-6",
14563
+ disabled ? "cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary" : "cursor-pointer"
14564
+ );
14565
+ triggerWrapper.className = triggerClasses;
15591
14566
  triggerWrapper.setAttribute("role", "button");
15592
14567
  triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
15593
14568
  triggerWrapper.setAttribute("aria-haspopup", "dialog");
@@ -15855,7 +14830,8 @@
15855
14830
  };
15856
14831
  container.setDisabled = function (d) {
15857
14832
  disabled = !!d;
15858
- triggerWrapper.className = getTriggerClassName(disabled);
14833
+ triggerWrapper.classList.toggle("cursor-not-allowed", disabled);
14834
+ triggerWrapper.classList.toggle("opacity-60", disabled);
15859
14835
  triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
15860
14836
  if (disabled) popoverApi.hide();
15861
14837
  };
@@ -15871,7 +14847,7 @@
15871
14847
 
15872
14848
 
15873
14849
  // ============================================
15874
- // File 35/41: components/phone-input/phone-utils.js
14850
+ // File 33/37: components/phone-input/phone-utils.js
15875
14851
  // ============================================
15876
14852
 
15877
14853
  /**
@@ -16034,7 +15010,7 @@
16034
15010
 
16035
15011
 
16036
15012
  // ============================================
16037
- // File 36/41: components/phone-input/phone-input.js
15013
+ // File 34/37: components/phone-input/phone-input.js
16038
15014
  // ============================================
16039
15015
 
16040
15016
  /**
@@ -16432,7 +15408,7 @@
16432
15408
 
16433
15409
 
16434
15410
  // ============================================
16435
- // File 37/41: components/file-input.js
15411
+ // File 35/37: components/file-input.js
16436
15412
  // ============================================
16437
15413
 
16438
15414
  /**
@@ -16476,15 +15452,6 @@
16476
15452
  return ICONS.file;
16477
15453
  }
16478
15454
 
16479
- /** Resolve client: use FlowUI._getComponent when bundle has captured globals, else global.superleapClient (same as enum-select) */
16480
- function getClient() {
16481
- if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
16482
- var c = global.FlowUI._getComponent("superleapClient");
16483
- if (c) return c;
16484
- }
16485
- return global.superleapClient;
16486
- }
16487
-
16488
15455
  /**
16489
15456
  * Upload file to S3
16490
15457
  * @param {File} file - File to upload
@@ -16496,31 +15463,26 @@
16496
15463
  formData.append("file", file, file.name);
16497
15464
  formData.append("is_private", String(!!isPrivate));
16498
15465
 
16499
- // Get upload path - can be configured via global.S3_UPLOAD_URL
15466
+ // Get upload URL - can be configured via global.S3_UPLOAD_URL
16500
15467
  const uploadUrl = global.S3_UPLOAD_URL || "/org/file/upload";
15468
+ const baseUrl = global.SUPERLEAP_BASE_URL || "https://app.superleap.com/api/v1";
15469
+ const fullUrl = uploadUrl.startsWith("http") ? uploadUrl : `${baseUrl}${uploadUrl}`;
16501
15470
 
16502
- // Base URL and API key from superleapClient only (same pattern as enum-select)
16503
- var client = getClient();
16504
- var baseUrl = null;
16505
- var apiKey = null;
15471
+ // Get API key: use FlowUI._getComponent when globals were captured (index.js), else global.superleapClient
15472
+ let apiKey = null;
16506
15473
  try {
16507
- if (client && typeof client.getBaseUrl === "function") {
16508
- baseUrl = client.getBaseUrl();
16509
- }
15474
+ const client =
15475
+ global.FlowUI && typeof global.FlowUI._getComponent === "function"
15476
+ ? global.FlowUI._getComponent("superleapClient")
15477
+ : global.superleapClient;
16510
15478
  if (client && typeof client.getSdk === "function") {
16511
- var sdk = client.getSdk();
16512
- apiKey = sdk ? sdk.apiKey : null;
15479
+ const sdk = client.getSdk();
15480
+ apiKey = sdk?.apiKey;
16513
15481
  }
16514
15482
  } catch (e) {
16515
- console.warn("[S3FileUpload] Could not get client:", e);
16516
- }
16517
-
16518
- if (!baseUrl) {
16519
- throw new Error("SuperLeap client not initialized. Call superleapClient.init({ baseUrl, apiKey }) first.");
15483
+ console.warn("[S3FileUpload] Could not get API key:", e);
16520
15484
  }
16521
15485
 
16522
- const fullUrl = uploadUrl.startsWith("http") ? uploadUrl : baseUrl.replace(/\/$/, "") + (uploadUrl.startsWith("/") ? uploadUrl : "/" + uploadUrl);
16523
-
16524
15486
  const headers = {};
16525
15487
  if (apiKey) {
16526
15488
  headers.Authorization = `Bearer ${apiKey}`;
@@ -16564,36 +15526,8 @@
16564
15526
  * @param {boolean} config.isPrivate - Whether files should be private
16565
15527
  * @param {number} config.maxFiles - Maximum number of files (for multiple mode)
16566
15528
  * @param {number} config.maxFileSize - Maximum file size in bytes
16567
- * @param {boolean} [config.disabled] - Whether the file upload is disabled
16568
- * @param {string} [config.variant] - 'default' | 'error' | 'warning' | 'success' | 'borderless' | 'inline'
16569
- * @param {string} [config.inputSize] - 'default' | 'large' | 'small'
16570
- * @param {string} [config.className] - Extra class on upload wrapper
16571
15529
  * @returns {HTMLElement} Field element
16572
15530
  */
16573
- var UPLOAD_WRAPPER_CLASS = {
16574
- base:
16575
- "group relative flex w-full items-center justify-between border-1/2 rounded-4 text-typography-primary-text w-full transition-all ease-in-out focus-within:outline-none group-has-[:disabled]:cursor-not-allowed group-has-[:disabled]:border-border-primary group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:text-typography-quaternary-text group-has-[:disabled]:hover:border-border-primary",
16576
- default:
16577
- "border-border-primary bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
16578
- error:
16579
- "border-error-base bg-fill-quarternary-fill-white hover:border-error-base focus-within:border-error-base",
16580
- warning:
16581
- "border-warning-base bg-fill-quarternary-fill-white hover:border-warning-base focus-within:border-warning-base",
16582
- success:
16583
- "border-success-base bg-fill-quarternary-fill-white hover:border-success-base focus-within:border-success-base",
16584
- borderless:
16585
- "border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
16586
- inline:
16587
- "border-transparent shadow-none rounded-0 bg-fill-quarternary-fill-white hover:bg-fill-tertiary-fill-light-gray focus-within:border-transparent focus-within:bg-fill-tertiary-fill-light-gray",
16588
- sizeDefault: "px-12 py-4",
16589
- sizeLarge: "px-12 py-6",
16590
- sizeSmall: "px-12 py-2",
16591
- };
16592
-
16593
- function joinClasses() {
16594
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
16595
- }
16596
-
16597
15531
  function create(config) {
16598
15532
  const {
16599
15533
  label,
@@ -16605,14 +15539,7 @@
16605
15539
  isPrivate = false,
16606
15540
  maxFiles = null,
16607
15541
  maxFileSize = 10 * 1024 * 1024, // 10MB default
16608
- disabled = false,
16609
- variant = "default",
16610
- inputSize = "default",
16611
- className = "",
16612
15542
  } = config;
16613
- let disabledState = !!disabled;
16614
- let currentVariant = variant;
16615
- let currentInputSize = inputSize;
16616
15543
 
16617
15544
  if (!global.FlowUI) {
16618
15545
  throw new Error("FlowUI not available");
@@ -16630,33 +15557,12 @@
16630
15557
 
16631
15558
  // Upload row: button + status + optional end spinner (match Select/MultiSelect trigger)
16632
15559
  const uploadWrapper = document.createElement("div");
16633
- var sizeClass =
16634
- currentInputSize === "large"
16635
- ? UPLOAD_WRAPPER_CLASS.sizeLarge
16636
- : currentInputSize === "small"
16637
- ? UPLOAD_WRAPPER_CLASS.sizeSmall
16638
- : UPLOAD_WRAPPER_CLASS.sizeDefault;
16639
- function applyWrapperClasses() {
16640
- uploadWrapper.className = joinClasses(
16641
- UPLOAD_WRAPPER_CLASS.base,
16642
- UPLOAD_WRAPPER_CLASS[currentVariant] || UPLOAD_WRAPPER_CLASS.default,
16643
- sizeClass,
16644
- className
16645
- );
16646
- }
16647
- applyWrapperClasses();
16648
- uploadWrapper.setAttribute("data-file-input-variant", currentVariant);
16649
- uploadWrapper.setAttribute("data-file-input-size", currentInputSize);
16650
- uploadWrapper.setAttribute("data-disabled", disabledState ? "true" : "false");
15560
+ uploadWrapper.className = "relative flex w-full items-center justify-between rounded-4 border-1/2 border-border-primary bg-fill-quarternary-fill-white px-8 py-4 hover:border-primary-border focus-within:outline-none focus-within:border-1/2 focus-within:border-primary-border";
16651
15561
 
16652
15562
  // Left content (button + status) – pointer-events-none so overlay input receives clicks
16653
15563
  const leftContent = document.createElement("div");
16654
15564
  leftContent.className = "pointer-events-none flex min-w-0 flex-1 items-center gap-8 truncate";
16655
15565
 
16656
- var disabledChildClasses =
16657
- "group-has-[:disabled]:text-typography-quaternary-text group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:hover:bg-fill-tertiary-fill-light-gray";
16658
- var statusTextBaseClass = "text-reg-13 min-w-0 flex-1 truncate";
16659
- var statusTextDisabledClass = " group-has-[:disabled]:text-typography-quaternary-text";
16660
15566
  const useButtonComponent = global.Button && typeof global.Button.create === "function";
16661
15567
  const initialButtonText = multiple ? "Choose files" : "Choose a file";
16662
15568
  const btn = useButtonComponent
@@ -16664,41 +15570,31 @@
16664
15570
  variant: "outline",
16665
15571
  size: "small",
16666
15572
  text: initialButtonText,
16667
- className: "shrink-0 truncate " + disabledChildClasses,
15573
+ className: "shrink-0 truncate",
16668
15574
  })
16669
15575
  : (function () {
16670
15576
  const el = document.createElement("div");
16671
- el.className =
16672
- "shrink-0 truncate rounded-2 border-1/2 border-border-primary bg-fill-tertiary-fill-light-gray px-8 py-1 text-reg-13 text-typography-primary-text transition-colors duration-150 hover:bg-fill-secondary-fill-gray " +
16673
- disabledChildClasses;
15577
+ el.className = "shrink-0 truncate rounded-2 border-1/2 border-border-primary bg-fill-tertiary-fill-light-gray px-8 py-1 text-reg-13 text-typography-primary-text transition-colors duration-150 hover:bg-fill-secondary-fill-gray";
16674
15578
  el.textContent = initialButtonText;
16675
15579
  return el;
16676
15580
  })();
16677
15581
 
16678
15582
  // Status text: "No files chosen" (quaternary) or "X file(s) selected"
16679
15583
  const statusText = document.createElement("p");
16680
- statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
15584
+ statusText.className = "text-reg-13 min-w-0 flex-1 truncate text-typography-quaternary-text";
16681
15585
 
16682
15586
  // Hidden file input – overlays row, high z-index so it receives clicks
16683
15587
  const input = document.createElement("input");
16684
15588
  input.type = "file";
16685
- const inputBaseClass = "absolute inset-0 z-10 w-full opacity-0";
16686
- function applyInputClasses() {
16687
- input.className =
16688
- inputBaseClass +
16689
- (disabledState ? " !pointer-events-none !cursor-not-allowed" : " cursor-pointer");
16690
- }
16691
- applyInputClasses();
15589
+ input.className = "absolute inset-0 z-10 w-full cursor-pointer opacity-0";
16692
15590
  input.multiple = multiple;
16693
- input.disabled = disabledState;
16694
15591
  if (accept !== "*") {
16695
15592
  input.accept = accept;
16696
15593
  }
16697
15594
 
16698
15595
  // End icon slot: spinner when uploading (match Select chevron position)
16699
15596
  const endIconSlot = document.createElement("div");
16700
- endIconSlot.className =
16701
- "ml-4 flex size-16 items-center justify-center shrink-0 text-typography-quaternary-text group-has-[:disabled]:text-typography-quaternary-text";
15597
+ endIconSlot.className = "ml-4 flex size-16 items-center justify-center shrink-0 text-typography-quaternary-text";
16702
15598
  endIconSlot.style.display = "none";
16703
15599
 
16704
15600
  // Uploaded files: badge list (match UploadedFilePreviewer – flex-wrap gap-2)
@@ -16879,13 +15775,13 @@
16879
15775
 
16880
15776
  if (!filesChosen) {
16881
15777
  statusText.textContent = "No files chosen";
16882
- statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
15778
+ statusText.className = "text-reg-13 min-w-0 flex-1 truncate text-typography-quaternary-text";
16883
15779
  } else if (uploadingCount > 0) {
16884
15780
  statusText.textContent = "Uploading…";
16885
- statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
15781
+ statusText.className = "text-reg-13 min-w-0 flex-1 truncate text-typography-quaternary-text";
16886
15782
  } else {
16887
15783
  statusText.textContent = `${uploadedCount} file${uploadedCount !== 1 ? "s" : ""} selected`;
16888
- statusText.className = statusTextBaseClass + " text-typography-primary-text" + statusTextDisabledClass;
15784
+ statusText.className = "text-reg-13 min-w-0 flex-1 truncate text-typography-primary-text";
16889
15785
  }
16890
15786
 
16891
15787
  endIconSlot.style.display = uploadingCount > 0 ? "flex" : "none";
@@ -17022,32 +15918,6 @@
17022
15918
  loadExistingFiles();
17023
15919
  updateStatus();
17024
15920
 
17025
- field.setDisabled = function (d) {
17026
- disabledState = !!d;
17027
- input.disabled = disabledState;
17028
- applyInputClasses();
17029
- applyWrapperClasses();
17030
- uploadWrapper.setAttribute("data-disabled", disabledState ? "true" : "false");
17031
- };
17032
-
17033
- field.setVariant = function (v) {
17034
- currentVariant = v || "default";
17035
- uploadWrapper.setAttribute("data-file-input-variant", currentVariant);
17036
- applyWrapperClasses();
17037
- };
17038
-
17039
- field.setInputSize = function (s) {
17040
- currentInputSize = s || "default";
17041
- sizeClass =
17042
- currentInputSize === "large"
17043
- ? UPLOAD_WRAPPER_CLASS.sizeLarge
17044
- : currentInputSize === "small"
17045
- ? UPLOAD_WRAPPER_CLASS.sizeSmall
17046
- : UPLOAD_WRAPPER_CLASS.sizeDefault;
17047
- uploadWrapper.setAttribute("data-file-input-size", currentInputSize);
17048
- applyWrapperClasses();
17049
- };
17050
-
17051
15921
  return field;
17052
15922
  }
17053
15923
 
@@ -17062,7 +15932,7 @@
17062
15932
 
17063
15933
 
17064
15934
  // ============================================
17065
- // File 38/41: components/table.js
15935
+ // File 36/37: components/table.js
17066
15936
  // ============================================
17067
15937
 
17068
15938
  /**
@@ -17403,455 +16273,7 @@
17403
16273
 
17404
16274
 
17405
16275
  // ============================================
17406
- // File 39/41: components/tabs.js
17407
- // ============================================
17408
-
17409
- /**
17410
- * Tabs Component (vanilla JS)
17411
- * Tabbed interface with list, triggers, and content panels.
17412
- * Ref: Radix-style Tabs; design tokens match design system.
17413
- */
17414
-
17415
- (function (global) {
17416
-
17417
- function getComponent(name) {
17418
- if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
17419
- var c = global.FlowUI._getComponent(name);
17420
- if (c) return c;
17421
- }
17422
- return global[name];
17423
- }
17424
-
17425
- var LIST_BASE_CLASS =
17426
- "inline-flex items-center justify-center gap-2 rounded-4 bg-fill-tertiary-fill-light-gray p-4";
17427
-
17428
- /** Button variant classes for active (outline) vs inactive (ghost) */
17429
- var BUTTON_OUTLINE =
17430
- "shadow-soft-extra-small group bg-fill-quarternary-fill-white border-1/2 border-border-primary text-typography-primary-text hover:bg-fill-tertiary-fill-light-gray active:bg-fill-secondary-fill-gray disabled:opacity-50 disabled:border-fill-secondary-fill-gray";
17431
- var BUTTON_GHOST =
17432
- "group text-typography-primary-text hover:bg-fill-tertiary-fill-light-gray active:bg-fill-secondary-fill-gray disabled:text-typography-quaternary-text";
17433
- var BUTTON_BASE =
17434
- "inline-flex items-center justify-center whitespace-nowrap !text-med-12 transition-colors disabled:pointer-events-none hover:cursor-pointer h-fit";
17435
- var BUTTON_SIZES = {
17436
- default: "px-8 py-4 gap-4 rounded-4",
17437
- small: "px-8 py-4 gap-4 rounded-4",
17438
- large: "px-16 py-8 gap-4 rounded-4",
17439
- };
17440
-
17441
- var CONTENT_BASE_CLASS =
17442
- "ring-offset-background focus-visible:ring-ring h-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2";
17443
-
17444
- function join() {
17445
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
17446
- }
17447
-
17448
- /**
17449
- * Create a full Tabs component (list + triggers + content panels)
17450
- * @param {Object} config
17451
- * @param {string} [config.defaultValue] - initial active tab value
17452
- * @param {string} [config.value] - controlled active value
17453
- * @param {Function} [config.onChange] - (value) => void when tab changes
17454
- * @param {Array<{value: string, label: string, content: HTMLElement|string}>} config.tabs - tab definitions
17455
- * @param {string} [config.size] - 'default' | 'small' | 'large'
17456
- * @param {string} [config.listClassName] - extra class on list
17457
- * @param {string} [config.contentClassName] - extra class on content wrapper
17458
- * @returns {HTMLElement} root element (wrapper containing list + content area)
17459
- */
17460
- function create(config) {
17461
- var opts = config || {};
17462
- var defaultValue = opts.defaultValue;
17463
- var controlledValue = opts.value;
17464
- var onChange = opts.onChange;
17465
- var tabs = opts.tabs || [];
17466
- var size = opts.size || "default";
17467
- var listClassName = opts.listClassName || "";
17468
- var contentClassName = opts.contentClassName || "";
17469
-
17470
- var sizeClass = BUTTON_SIZES[size] || BUTTON_SIZES.default;
17471
-
17472
- var root = document.createElement("div");
17473
- root.className = "tabs-root w-full";
17474
-
17475
- var activeValue = controlledValue !== undefined ? controlledValue : defaultValue !== undefined ? defaultValue : (tabs[0] && tabs[0].value) || "";
17476
-
17477
- // List container
17478
- var list = document.createElement("div");
17479
- list.setAttribute("role", "tablist");
17480
- list.className = join(LIST_BASE_CLASS, listClassName);
17481
-
17482
- // Content container (holds all panels; we show/hide by value)
17483
- var contentWrapper = document.createElement("div");
17484
- contentWrapper.className = join("tabs-content-wrapper mt-4", contentClassName);
17485
-
17486
- var triggerEls = [];
17487
- var contentPanels = [];
17488
-
17489
- var Button = getComponent("Button");
17490
-
17491
- tabs.forEach(function (tab, index) {
17492
- var value = tab.value;
17493
- var label = tab.label != null ? tab.label : value;
17494
- var content = tab.content;
17495
-
17496
- var isActive = value === activeValue;
17497
- var trigger = Button.create({
17498
- variant: isActive ? "outline" : "ghost",
17499
- size: size === "small" ? "small" : size === "large" ? "large" : "default",
17500
- text: label,
17501
- type: "button",
17502
- className: "mx-2",
17503
- onClick: function () {
17504
- if (activeValue === value) return;
17505
- if (controlledValue === undefined) {
17506
- activeValue = value;
17507
- updateActiveState();
17508
- }
17509
- if (typeof onChange === "function") {
17510
- onChange(value);
17511
- }
17512
- },
17513
- });
17514
-
17515
- trigger.setAttribute("role", "tab");
17516
- trigger.setAttribute("aria-selected", value === activeValue ? "true" : "false");
17517
- trigger.setAttribute("data-state", value === activeValue ? "active" : "inactive");
17518
- trigger.setAttribute("data-value", value);
17519
- trigger.tabIndex = value === activeValue ? 0 : -1;
17520
-
17521
- trigger.addEventListener("keydown", function (e) {
17522
- if (e.key === "Enter" || e.key === " ") {
17523
- e.preventDefault();
17524
- trigger.click();
17525
- }
17526
- if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
17527
- e.preventDefault();
17528
- var nextIndex = e.key === "ArrowRight" ? index + 1 : index - 1;
17529
- if (nextIndex >= 0 && nextIndex < tabs.length) {
17530
- var nextTrigger = triggerEls[nextIndex];
17531
- if (nextTrigger) {
17532
- nextTrigger.focus();
17533
- nextTrigger.click();
17534
- }
17535
- }
17536
- }
17537
- });
17538
-
17539
- list.appendChild(trigger);
17540
- triggerEls.push(trigger);
17541
-
17542
- var panel = document.createElement("div");
17543
- panel.setAttribute("role", "tabpanel");
17544
- panel.setAttribute("aria-hidden", value !== activeValue ? "true" : "false");
17545
- panel.setAttribute("data-value", value);
17546
- panel.className = join(CONTENT_BASE_CLASS, value !== activeValue ? "hidden" : "");
17547
- if (typeof content === "string") {
17548
- panel.innerHTML = content;
17549
- } else if (content && content.nodeType === 1) {
17550
- panel.appendChild(content);
17551
- }
17552
- contentWrapper.appendChild(panel);
17553
- contentPanels.push(panel);
17554
- });
17555
-
17556
- function updateActiveState() {
17557
- triggerEls.forEach(function (t, i) {
17558
- var val = tabs[i] && tabs[i].value;
17559
- var isActive = val === activeValue;
17560
- t.setAttribute("aria-selected", isActive ? "true" : "false");
17561
- t.setAttribute("data-state", isActive ? "active" : "inactive");
17562
- t.tabIndex = isActive ? 0 : -1;
17563
- t.className = join(BUTTON_BASE, isActive ? BUTTON_OUTLINE : BUTTON_GHOST, sizeClass, "mx-2");
17564
- });
17565
- contentPanels.forEach(function (p, i) {
17566
- var val = tabs[i] && tabs[i].value;
17567
- var isActive = val === activeValue;
17568
- p.setAttribute("aria-hidden", isActive ? "false" : "true");
17569
- p.classList.toggle("hidden", !isActive);
17570
- });
17571
- }
17572
-
17573
- root.appendChild(list);
17574
- root.appendChild(contentWrapper);
17575
-
17576
- root.getValue = function () {
17577
- return activeValue;
17578
- };
17579
-
17580
- root.setValue = function (newValue) {
17581
- if (newValue === activeValue) return;
17582
- activeValue = newValue;
17583
- updateActiveState();
17584
- };
17585
-
17586
- return root;
17587
- }
17588
-
17589
- var Tabs = {
17590
- create: create,
17591
- };
17592
-
17593
- if (typeof module !== "undefined" && module.exports) {
17594
- module.exports = Tabs;
17595
- } else {
17596
- global.Tabs = Tabs;
17597
- }
17598
- })(typeof window !== "undefined" ? window : undefined);
17599
-
17600
-
17601
-
17602
- // ============================================
17603
- // File 40/41: components/steps.js
17604
- // ============================================
17605
-
17606
- /**
17607
- * Steps Component (vanilla JS)
17608
- * Multi-step flow with numbered step triggers and optional content panels.
17609
- * Use for wizards / step-by-step forms (e.g. "1 Step One", "2 Step Two").
17610
- */
17611
-
17612
- (function (global) {
17613
-
17614
- function getComponent(name) {
17615
- if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
17616
- var c = global.FlowUI._getComponent(name);
17617
- if (c) return c;
17618
- }
17619
- return global[name];
17620
- }
17621
-
17622
- var LIST_BASE_CLASS =
17623
- "flex items-center flex-wrap gap-0 rounded-4 border border-border-primary bg-fill-quarternary-fill-white p-4";
17624
-
17625
- /** Inactive step: muted label color only (button stays ghost large) */
17626
- var INACTIVE_LABEL_CLASS = "!text-typography-quaternary-text";
17627
-
17628
- /** Box around step number: active = dark fill + invert text, inactive = dark gray fill + tertiary text */
17629
- var NUMBER_BOX_ACTIVE =
17630
- "flex h-16 w-16 items-center justify-center rounded-4 bg-typography-primary-text text-typography-invert-text shrink-0";
17631
- var NUMBER_BOX_INACTIVE =
17632
- "flex h-16 w-16 items-center justify-center rounded-4 bg-fill-primary-fill-dark-gray text-typography-tertiary-text shrink-0";
17633
-
17634
- /** Horizontal line between steps (step1 ——— step2) */
17635
- var CONNECTOR_CLASS = "flex-1 min-w-12 max-w-32 h-0 border-t border-border-primary shrink-0 mx-2 self-center";
17636
-
17637
- var CONTENT_BASE_CLASS =
17638
- "ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2 h-full";
17639
-
17640
- function join() {
17641
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
17642
- }
17643
-
17644
- /**
17645
- * Create a Steps component (numbered step triggers + optional content)
17646
- * Design: ghost large Button for all steps; inactive steps use muted label color. Connectors between steps. Optional title/description above.
17647
- * @param {Object} config
17648
- * @param {Array<{id: string, label: string, content?: HTMLElement|string}>} config.steps - step definitions
17649
- * @param {string} [config.defaultValue] - initial active step id
17650
- * @param {string} [config.value] - controlled active step id
17651
- * @param {Function} [config.onChange] - (stepId) => void when step changes
17652
- * @param {string} [config.title] - optional title above steps
17653
- * @param {string} [config.description] - optional description above steps
17654
- * @param {string} [config.listClassName] - extra class on step list
17655
- * @param {string} [config.contentClassName] - extra class on content wrapper
17656
- * @param {boolean} [config.showContent=true] - whether to render content panels (if steps have content)
17657
- * @returns {HTMLElement} root element
17658
- */
17659
- function create(config) {
17660
- var opts = config || {};
17661
- var steps = opts.steps || [];
17662
- var defaultValue = opts.defaultValue;
17663
- var controlledValue = opts.value;
17664
- var onChange = opts.onChange;
17665
- var title = opts.title;
17666
- var description = opts.description;
17667
- var listClassName = opts.listClassName || "";
17668
- var contentClassName = opts.contentClassName || "";
17669
- var showContent = opts.showContent !== false;
17670
-
17671
- var root = document.createElement("div");
17672
- root.className = "steps-root w-full";
17673
-
17674
- var activeId =
17675
- controlledValue !== undefined
17676
- ? controlledValue
17677
- : defaultValue !== undefined
17678
- ? defaultValue
17679
- : (steps[0] && steps[0].id) || "";
17680
-
17681
- if (title != null && title !== "") {
17682
- var titleEl = document.createElement("h3");
17683
- titleEl.className = "text-typography-primary-text";
17684
- titleEl.textContent = title;
17685
- root.appendChild(titleEl);
17686
- }
17687
- if (description != null && description !== "") {
17688
- var descEl = document.createElement("p");
17689
- descEl.className = "text-typography-secondary-text";
17690
- descEl.textContent = description;
17691
- root.appendChild(descEl);
17692
- }
17693
-
17694
- // Step list (horizontal: step, connector, step, connector, ...)
17695
- var list = document.createElement("div");
17696
- list.setAttribute("role", "tablist");
17697
- list.setAttribute("aria-label", "Steps");
17698
- list.className = join(LIST_BASE_CLASS, listClassName);
17699
-
17700
- var triggerEls = [];
17701
- var numberBoxEls = [];
17702
- var contentPanels = [];
17703
- var contentWrapper = null;
17704
-
17705
- if (showContent && steps.some(function (s) { return s.content != null; })) {
17706
- contentWrapper = document.createElement("div");
17707
- contentWrapper.className = join("steps-content-wrapper mt-4", contentClassName);
17708
- }
17709
-
17710
- var Button = getComponent("Button");
17711
-
17712
- steps.forEach(function (step, index) {
17713
- var stepId = step.id;
17714
- var label = step.label != null ? step.label : stepId;
17715
- var content = step.content;
17716
- var stepNumber = index + 1;
17717
- var isActive = stepId === activeId;
17718
-
17719
- var trigger = Button.create({
17720
- variant: "ghost",
17721
- size: "large",
17722
- text: "\u00A0",
17723
- type: "button",
17724
- className: isActive ? "" : INACTIVE_LABEL_CLASS,
17725
- onClick: function () {
17726
- if (activeId === stepId) return;
17727
- if (controlledValue === undefined) {
17728
- activeId = stepId;
17729
- updateActiveState();
17730
- }
17731
- if (typeof onChange === "function") {
17732
- onChange(stepId);
17733
- }
17734
- },
17735
- });
17736
-
17737
- var numberBox = document.createElement("span");
17738
- numberBox.setAttribute("aria-hidden", "true");
17739
- numberBox.className = isActive ? NUMBER_BOX_ACTIVE : NUMBER_BOX_INACTIVE;
17740
- numberBox.textContent = String(stepNumber);
17741
-
17742
- trigger.innerHTML = "";
17743
- trigger.appendChild(numberBox);
17744
- trigger.appendChild(document.createTextNode(" " + label));
17745
-
17746
- trigger.setAttribute("role", "tab");
17747
- trigger.setAttribute("aria-selected", isActive ? "true" : "false");
17748
- trigger.setAttribute("data-state", isActive ? "active" : "inactive");
17749
- trigger.setAttribute("data-step-id", stepId);
17750
- trigger.tabIndex = isActive ? 0 : -1;
17751
-
17752
- numberBoxEls.push(numberBox);
17753
-
17754
- trigger.addEventListener("keydown", function (e) {
17755
- if (e.key === "Enter" || e.key === " ") {
17756
- e.preventDefault();
17757
- trigger.click();
17758
- }
17759
- if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
17760
- e.preventDefault();
17761
- var nextIndex = e.key === "ArrowRight" ? index + 1 : index - 1;
17762
- if (nextIndex >= 0 && nextIndex < steps.length) {
17763
- var nextTrigger = triggerEls[nextIndex];
17764
- if (nextTrigger) {
17765
- nextTrigger.focus();
17766
- nextTrigger.click();
17767
- }
17768
- }
17769
- }
17770
- });
17771
-
17772
- list.appendChild(trigger);
17773
- triggerEls.push(trigger);
17774
-
17775
- if (index < steps.length - 1) {
17776
- var connector = document.createElement("span");
17777
- connector.className = CONNECTOR_CLASS;
17778
- connector.setAttribute("aria-hidden", "true");
17779
- list.appendChild(connector);
17780
- }
17781
-
17782
- if (contentWrapper && content != null) {
17783
- var panel = document.createElement("div");
17784
- panel.setAttribute("role", "tabpanel");
17785
- panel.setAttribute("aria-hidden", stepId !== activeId ? "true" : "false");
17786
- panel.setAttribute("data-step-id", stepId);
17787
- panel.className = join(CONTENT_BASE_CLASS, stepId !== activeId ? "hidden" : "");
17788
- if (typeof content === "string") {
17789
- panel.innerHTML = content;
17790
- } else if (content && content.nodeType === 1) {
17791
- panel.appendChild(content);
17792
- }
17793
- contentWrapper.appendChild(panel);
17794
- contentPanels.push(panel);
17795
- }
17796
- });
17797
-
17798
- function updateActiveState() {
17799
- triggerEls.forEach(function (t, i) {
17800
- var step = steps[i];
17801
- var id = step && step.id;
17802
- var isActive = id === activeId;
17803
- t.setAttribute("aria-selected", isActive ? "true" : "false");
17804
- t.setAttribute("data-state", isActive ? "active" : "inactive");
17805
- t.tabIndex = isActive ? 0 : -1;
17806
- if (isActive) {
17807
- t.classList.remove(INACTIVE_LABEL_CLASS);
17808
- } else {
17809
- t.classList.add(INACTIVE_LABEL_CLASS);
17810
- }
17811
- numberBoxEls[i].className = isActive ? NUMBER_BOX_ACTIVE : NUMBER_BOX_INACTIVE;
17812
- });
17813
- contentPanels.forEach(function (p, i) {
17814
- var step = steps[i];
17815
- var id = step && step.id;
17816
- var isActive = id === activeId;
17817
- p.setAttribute("aria-hidden", isActive ? "false" : "true");
17818
- p.classList.toggle("hidden", !isActive);
17819
- });
17820
- }
17821
-
17822
- root.appendChild(list);
17823
- if (contentWrapper) {
17824
- root.appendChild(contentWrapper);
17825
- }
17826
-
17827
- root.getValue = function () {
17828
- return activeId;
17829
- };
17830
-
17831
- root.setValue = function (newId) {
17832
- if (newId === activeId) return;
17833
- activeId = newId;
17834
- updateActiveState();
17835
- };
17836
-
17837
- return root;
17838
- }
17839
-
17840
- var Steps = {
17841
- create: create,
17842
- };
17843
-
17844
- if (typeof module !== "undefined" && module.exports) {
17845
- module.exports = Steps;
17846
- } else {
17847
- global.Steps = Steps;
17848
- }
17849
- })(typeof window !== "undefined" ? window : undefined);
17850
-
17851
-
17852
-
17853
- // ============================================
17854
- // File 41/41: index.js
16276
+ // File 37/37: index.js
17855
16277
  // ============================================
17856
16278
 
17857
16279
  /**
@@ -17927,7 +16349,6 @@
17927
16349
  require("./components/input.js");
17928
16350
  require("./components/currency.js");
17929
16351
  require("./components/textarea.js");
17930
- require("./components/richtext-editor.js");
17931
16352
  require("./components/duration/duration-utils.js");
17932
16353
  require("./components/duration/duration-constants.js");
17933
16354
  require("./components/duration/duration.js");
@@ -17943,11 +16364,8 @@
17943
16364
  require("./components/phone-input/phone-utils.js");
17944
16365
  require("./components/phone-input/phone-input.js");
17945
16366
  require("./components/checkbox.js");
17946
- require("./components/checkbox-group.js");
17947
16367
  require("./components/radio-group.js");
17948
16368
  require("./components/table.js");
17949
- require("./components/tabs.js");
17950
- require("./components/steps.js");
17951
16369
 
17952
16370
  // Export FlowUI and SuperLeap from global scope
17953
16371
  if (typeof global !== "undefined" && global.FlowUI) {
@@ -17958,7 +16376,6 @@
17958
16376
  getSdk: global.superleapClient.getSdk,
17959
16377
  isAvailable: global.superleapClient.isAvailable,
17960
16378
  getDefaultConfig: global.superleapClient.getDefaultConfig,
17961
- getBaseUrl: global.superleapClient.getBaseUrl,
17962
16379
  }
17963
16380
  : null;
17964
16381
 
@@ -17974,7 +16391,6 @@
17974
16391
  getSdk: window.superleapClient.getSdk,
17975
16392
  isAvailable: window.superleapClient.isAvailable,
17976
16393
  getDefaultConfig: window.superleapClient.getDefaultConfig,
17977
- getBaseUrl: window.superleapClient.getBaseUrl,
17978
16394
  }
17979
16395
  : null;
17980
16396
 
@@ -18010,7 +16426,6 @@
18010
16426
  "InputComponent",
18011
16427
  "CurrencyComponent",
18012
16428
  "TextareaComponent",
18013
- "RichTextEditorComponent",
18014
16429
  "Duration",
18015
16430
  "DateTimePicker",
18016
16431
  "Enumeration",
@@ -18022,11 +16437,8 @@
18022
16437
  "FileInput",
18023
16438
  "PhoneInput",
18024
16439
  "Checkbox",
18025
- "CheckboxGroup",
18026
16440
  "RadioGroup",
18027
16441
  "SuperleapTable",
18028
- "Tabs",
18029
- "Steps",
18030
16442
  ];
18031
16443
 
18032
16444
  componentNames.forEach((name) => {
@@ -18056,7 +16468,6 @@
18056
16468
  getSdk: client.getSdk.bind(client),
18057
16469
  isAvailable: client.isAvailable.bind(client),
18058
16470
  getDefaultConfig: client.getDefaultConfig.bind(client),
18059
- getBaseUrl: client.getBaseUrl.bind(client),
18060
16471
  // Bridge methods (from crm.js)
18061
16472
  connect: client.connect ? client.connect.bind(client) : undefined,
18062
16473
  isConnected: client.isConnected
@@ -18115,7 +16526,7 @@
18115
16526
  },
18116
16527
  });
18117
16528
  document.dispatchEvent(event);
18118
- console.log("[Superleap-Flow] Library ready - v2.5.1");
16529
+ console.log("[Superleap-Flow] Library ready - v2.3.4");
18119
16530
  }
18120
16531
 
18121
16532
  // Wait for DOM to be ready before dispatching event