@superleapai/flow-ui 2.5.13 → 2.5.14

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.3
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-25T17:41:37.089Z
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/42: 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/42: 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/42: 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/42: 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/42: 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/42: 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
@@ -4393,81 +4339,6 @@
4393
4339
  return field;
4394
4340
  }
4395
4341
 
4396
- /**
4397
- * Create a card select field (uses CardSelect component when available, else radio fallback)
4398
- * @param {Object} config - Configuration object
4399
- * @param {string} config.label - Field label
4400
- * @param {string} config.fieldId - State key for this field
4401
- * @param {Array} config.options - Array of { value, label, description?, icon?, disabled? }
4402
- * @param {boolean} [config.required] - Whether field is required
4403
- * @param {Function} [config.onChange] - Optional change handler (receives selected value)
4404
- * @param {string} [config.helpText] - Optional help text for tooltip
4405
- * @param {boolean} [config.disabled] - Whether all cards are disabled
4406
- * @param {string} [config.className] - Extra CSS class on card container
4407
- * @returns {HTMLElement} Field wrapper element
4408
- */
4409
- function createCardSelect(config) {
4410
- const { label, fieldId, options = [], required = false, onChange, helpText = null, disabled = false, className } = config;
4411
-
4412
- const field = createFieldWrapper(label, required, helpText);
4413
-
4414
- if (getComponent("CardSelect") && getComponent("CardSelect").create) {
4415
- const currentValue = get(fieldId);
4416
- const cardSelectEl = getComponent("CardSelect").create({
4417
- name: fieldId,
4418
- options: options.map((opt) => ({
4419
- value: opt.value,
4420
- label: opt.label || opt.value,
4421
- description: opt.description,
4422
- icon: opt.icon,
4423
- disabled: opt.disabled,
4424
- })),
4425
- value: currentValue,
4426
- disabled,
4427
- className,
4428
- onChange: (value) => {
4429
- set(fieldId, value);
4430
- if (onChange) onChange(value);
4431
- },
4432
- });
4433
- cardSelectEl._fieldId = fieldId;
4434
- field.appendChild(cardSelectEl);
4435
- return field;
4436
- }
4437
-
4438
- // Fallback: native radio buttons
4439
- const radioGroup = document.createElement("div");
4440
- radioGroup.className = "card-select-fallback";
4441
-
4442
- options.forEach((opt) => {
4443
- const wrapper = document.createElement("div");
4444
- wrapper.className = "card-option";
4445
-
4446
- const radio = document.createElement("input");
4447
- radio.type = "radio";
4448
- radio.name = fieldId;
4449
- radio.value = opt.value;
4450
- radio.id = `${fieldId}-${opt.value}`;
4451
- radio.checked = get(fieldId) === opt.value;
4452
- radio.disabled = disabled || !!opt.disabled;
4453
- radio.addEventListener("change", () => {
4454
- set(fieldId, opt.value);
4455
- if (onChange) { onChange(opt.value); }
4456
- });
4457
-
4458
- const radioLabel = document.createElement("label");
4459
- radioLabel.htmlFor = `${fieldId}-${opt.value}`;
4460
- radioLabel.textContent = opt.label || opt.value;
4461
-
4462
- wrapper.appendChild(radio);
4463
- wrapper.appendChild(radioLabel);
4464
- radioGroup.appendChild(wrapper);
4465
- });
4466
-
4467
- field.appendChild(radioGroup);
4468
- return field;
4469
- }
4470
-
4471
4342
  /**
4472
4343
  * Create a multi-select field (uses MultiSelect component when available, else checkbox group)
4473
4344
  * @param {Object} config - Configuration object
@@ -4577,7 +4448,6 @@
4577
4448
  size,
4578
4449
  canClear,
4579
4450
  initialLimit,
4580
- initialFilter,
4581
4451
  helpText = null,
4582
4452
  } = config;
4583
4453
 
@@ -4597,7 +4467,6 @@
4597
4467
  size: size || "default",
4598
4468
  canClear: !!canClear,
4599
4469
  initialLimit,
4600
- initialFilter,
4601
4470
  onChange: (value, record) => {
4602
4471
  set(fieldId, value);
4603
4472
  if (onChange) onChange(value, record);
@@ -4647,7 +4516,6 @@
4647
4516
  variant,
4648
4517
  size,
4649
4518
  initialLimit,
4650
- initialFilter,
4651
4519
  displayFields,
4652
4520
  helpText = null,
4653
4521
  } = config;
@@ -4666,7 +4534,6 @@
4666
4534
  variant: variant || "default",
4667
4535
  size: size || "default",
4668
4536
  initialLimit,
4669
- initialFilter,
4670
4537
  displayFields: displayFields || [],
4671
4538
  onValuesChange: (values, records) => {
4672
4539
  set(fieldId, values);
@@ -5224,40 +5091,6 @@
5224
5091
  return field;
5225
5092
  }
5226
5093
 
5227
- /**
5228
- * Create a checkbox group field (multiselect-like: options array, value array, onValuesChange)
5229
- * @param {Object} config - { label, fieldId, options, required, helpText, variant, size, layout, disabled, onChange }
5230
- * @returns {HTMLElement} Field wrapper containing checkbox group
5231
- */
5232
- function createCheckboxGroup(config) {
5233
- const { label, fieldId, options = [], required = false, helpText = null, variant, size, layout = "vertical", disabled = false, onChange } = config;
5234
-
5235
- const field = createFieldWrapper(label, required, helpText);
5236
- field.setAttribute("data-field-id", fieldId);
5237
-
5238
- if (getComponent("CheckboxGroup") && getComponent("CheckboxGroup").create) {
5239
- const currentValues = get(fieldId) || [];
5240
- const groupEl = getComponent("CheckboxGroup").create({
5241
- fieldId,
5242
- options,
5243
- value: currentValues,
5244
- variant: variant || "default",
5245
- size: size || "default",
5246
- layout,
5247
- disabled,
5248
- onValuesChange: (values) => {
5249
- set(fieldId, values);
5250
- if (onChange) onChange(values);
5251
- },
5252
- });
5253
- groupEl._fieldId = fieldId;
5254
- field.appendChild(groupEl);
5255
- return field;
5256
- }
5257
-
5258
- return field;
5259
- }
5260
-
5261
5094
  // ============================================================================
5262
5095
  // STEPPER COMPONENT
5263
5096
  // ============================================================================
@@ -5289,38 +5122,6 @@
5289
5122
  });
5290
5123
  }
5291
5124
 
5292
- /**
5293
- * Create a Tabs component (list + triggers + content panels)
5294
- * @param {Object} config - { defaultValue?, value?, onChange?, tabs: [{ value, label, content }], size?, variant?, listClassName?, contentClassName? }
5295
- * @returns {HTMLElement} Tabs root element
5296
- */
5297
- function createTabs(config) {
5298
- const Tabs = getComponent("Tabs");
5299
- if (Tabs && typeof Tabs.create === "function") {
5300
- return Tabs.create(config);
5301
- }
5302
- const fallback = document.createElement("div");
5303
- fallback.className = "tabs-root";
5304
- fallback.textContent = "Tabs component not loaded.";
5305
- return fallback;
5306
- }
5307
-
5308
- /**
5309
- * Create a Steps component (numbered step triggers + optional content panels)
5310
- * @param {Object} config - { steps: [{ id, label, content? }], defaultValue?, value?, onChange?, size?, variant?, listClassName?, contentClassName?, showContent? }
5311
- * @returns {HTMLElement} Steps root element
5312
- */
5313
- function createSteps(config) {
5314
- const Steps = getComponent("Steps");
5315
- if (Steps && typeof Steps.create === "function") {
5316
- return Steps.create(config);
5317
- }
5318
- const fallback = document.createElement("div");
5319
- fallback.className = "steps-root";
5320
- fallback.textContent = "Steps component not loaded.";
5321
- return fallback;
5322
- }
5323
-
5324
5125
  // ============================================================================
5325
5126
  // TABLE COMPONENT
5326
5127
  // ============================================================================
@@ -5483,34 +5284,6 @@
5483
5284
  return field;
5484
5285
  }
5485
5286
 
5486
- // ============================================================================
5487
- // ALERTS
5488
- // ============================================================================
5489
-
5490
- /**
5491
- * Render multiple alert messages into a container
5492
- * @param {HTMLElement} container - Container to append alerts to
5493
- * @param {string[]} messages - Array of message strings
5494
- * @param {string} [variant='default'] - 'default' | 'error' | 'warning' | 'success' | 'info' | 'destructive'
5495
- */
5496
- function renderAlerts(container, messages, variant = "default") {
5497
- if (!container || !Array.isArray(messages)) return;
5498
- const Alert = getComponent("Alert");
5499
- if (Alert && typeof Alert.simple === "function") {
5500
- messages.forEach((msg) => {
5501
- const el = Alert.simple(msg, variant);
5502
- if (el) container.appendChild(el);
5503
- });
5504
- } else {
5505
- messages.forEach((msg) => {
5506
- const div = document.createElement("div");
5507
- 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");
5508
- div.textContent = msg;
5509
- container.appendChild(div);
5510
- });
5511
- }
5512
- }
5513
-
5514
5287
  // ============================================================================
5515
5288
  // TOAST NOTIFICATIONS
5516
5289
  // ============================================================================
@@ -5647,12 +5420,10 @@
5647
5420
  // Form components
5648
5421
  createInput,
5649
5422
  createTextarea,
5650
- createRichTextEditor,
5651
5423
  createSelect,
5652
5424
  createTimePicker,
5653
5425
  createDateTimePicker,
5654
5426
  createRadioGroup,
5655
- createCardSelect,
5656
5427
  createMultiSelect,
5657
5428
  createRecordSelect,
5658
5429
  createRecordMultiSelect,
@@ -5664,7 +5435,6 @@
5664
5435
  createCurrency,
5665
5436
  createPhoneInput,
5666
5437
  createCheckbox,
5667
- createCheckboxGroup,
5668
5438
 
5669
5439
  // Button (delegates to Button component when available; resolved at call time via getComponent)
5670
5440
  createButton: function (config) {
@@ -5685,11 +5455,8 @@
5685
5455
 
5686
5456
  // Stepper
5687
5457
  renderStepper,
5688
- createTabs,
5689
- createSteps,
5690
5458
 
5691
5459
  // Alerts
5692
- renderAlerts,
5693
5460
  showToast,
5694
5461
 
5695
5462
  // Table
@@ -5717,7 +5484,7 @@
5717
5484
 
5718
5485
 
5719
5486
  // ============================================
5720
- // File 7/42: components/toast.js
5487
+ // File 7/37: components/toast.js
5721
5488
  // ============================================
5722
5489
 
5723
5490
  /**
@@ -6066,7 +5833,7 @@
6066
5833
 
6067
5834
 
6068
5835
  // ============================================
6069
- // File 8/42: components/alert.js
5836
+ // File 8/37: components/alert.js
6070
5837
  // ============================================
6071
5838
 
6072
5839
  /**
@@ -6354,7 +6121,7 @@
6354
6121
 
6355
6122
 
6356
6123
  // ============================================
6357
- // File 9/42: components/button.js
6124
+ // File 9/37: components/button.js
6358
6125
  // ============================================
6359
6126
 
6360
6127
  /**
@@ -6561,7 +6328,7 @@
6561
6328
 
6562
6329
 
6563
6330
  // ============================================
6564
- // File 10/42: components/spinner.js
6331
+ // File 10/37: components/spinner.js
6565
6332
  // ============================================
6566
6333
 
6567
6334
  /**
@@ -6703,7 +6470,7 @@
6703
6470
 
6704
6471
 
6705
6472
  // ============================================
6706
- // File 11/42: components/badge.js
6473
+ // File 11/37: components/badge.js
6707
6474
  // ============================================
6708
6475
 
6709
6476
  /**
@@ -6844,7 +6611,7 @@
6844
6611
 
6845
6612
 
6846
6613
  // ============================================
6847
- // File 12/42: components/avatar.js
6614
+ // File 12/37: components/avatar.js
6848
6615
  // ============================================
6849
6616
 
6850
6617
  /**
@@ -7045,7 +6812,7 @@
7045
6812
 
7046
6813
 
7047
6814
  // ============================================
7048
- // File 13/42: components/icon.js
6815
+ // File 13/37: components/icon.js
7049
6816
  // ============================================
7050
6817
 
7051
6818
  /**
@@ -7126,40 +6893,6 @@
7126
6893
  /** Filled circle for "just color" mode (IconOrColor when only icon_color is set) */
7127
6894
  IconCircleFilled:
7128
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>',
7129
-
7130
- // Rich text editor / toolbar (Tabler Icons outline, stroke 2)
7131
- IconBold:
7132
- '<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>',
7133
- IconItalic:
7134
- '<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>',
7135
- IconUnderline:
7136
- '<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>',
7137
- IconH1:
7138
- '<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>',
7139
- IconH2:
7140
- '<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>',
7141
- IconH3:
7142
- '<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>',
7143
- IconList:
7144
- '<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>',
7145
- IconListNumbers:
7146
- '<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>',
7147
- IconAlignLeft:
7148
- '<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>',
7149
- IconAlignCenter:
7150
- '<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>',
7151
- IconAlignRight:
7152
- '<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>',
7153
- IconCode:
7154
- '<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>',
7155
- IconLink:
7156
- '<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>',
7157
- IconPhoto:
7158
- '<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>',
7159
- IconArrowBackUp:
7160
- '<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>',
7161
- IconArrowForwardUp:
7162
- '<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>',
7163
6896
  };
7164
6897
 
7165
6898
  function join() {
@@ -7285,7 +7018,7 @@
7285
7018
 
7286
7019
 
7287
7020
  // ============================================
7288
- // File 14/42: components/popover.js
7021
+ // File 14/37: components/popover.js
7289
7022
  // ============================================
7290
7023
 
7291
7024
  /**
@@ -7308,7 +7041,6 @@
7308
7041
  * @param {Function} [config.onOpen] - Called when popover opens (before positioning)
7309
7042
  * @param {string} [config.bodyClassName] - Optional class for body wrapper (overrides default padding)
7310
7043
  * @param {string} [config.panelClassName] - Optional class to add to panel (e.g. for width)
7311
- * @param {boolean} [config.modal=false] - If true, lock body scroll and show backdrop; only popover and trigger are interactive
7312
7044
  * @returns {Object} Popover API {show, hide, destroy, element}
7313
7045
  */
7314
7046
  function create(config = {}) {
@@ -7323,7 +7055,6 @@
7323
7055
  onOpen = null,
7324
7056
  bodyClassName = "",
7325
7057
  panelClassName = "",
7326
- modal = true,
7327
7058
  } = config;
7328
7059
 
7329
7060
  const triggerEl =
@@ -7333,7 +7064,7 @@
7333
7064
  return { show: noop, hide: noop, destroy: noop, element: null };
7334
7065
  }
7335
7066
 
7336
- // 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)
7337
7068
  const container = document.createElement("div");
7338
7069
  container.className = "relative w-full";
7339
7070
  const triggerParent = triggerEl.parentNode;
@@ -7344,7 +7075,7 @@
7344
7075
 
7345
7076
  const wrapper = document.createElement("div");
7346
7077
  wrapper.className =
7347
- "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";
7348
7079
  wrapper.setAttribute("aria-hidden", "true");
7349
7080
 
7350
7081
  const panel = document.createElement("div");
@@ -7368,11 +7099,7 @@
7368
7099
  const body = document.createElement("div");
7369
7100
  body.className =
7370
7101
  bodyClassName ||
7371
- "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";
7372
- body.style.maxHeight = "90vh";
7373
- body.style.overflowY = "auto";
7374
- body.style.overflowX = "hidden";
7375
- body.style.minHeight = "0";
7102
+ "text-reg-14 text-typography-secondary-text leading-5 [&_p]:mb-2 [&_p:last-child]:mb-0";
7376
7103
  if (panelClassName) {
7377
7104
  panel.className = panel.className + " " + panelClassName;
7378
7105
  }
@@ -7384,40 +7111,7 @@
7384
7111
  panel.appendChild(body);
7385
7112
 
7386
7113
  wrapper.appendChild(panel);
7387
- document.body.appendChild(wrapper);
7388
-
7389
- var backdropEl = null;
7390
- var resizeObserver = null;
7391
-
7392
- function onBackdropWheel(e) {
7393
- e.preventDefault();
7394
- }
7395
-
7396
- function applyModalOpen() {
7397
- if (!modal) return;
7398
- if (!backdropEl) {
7399
- backdropEl = document.createElement("div");
7400
- backdropEl.className =
7401
- "fixed inset-0 z-40 bg-transparent pointer-events-auto";
7402
- backdropEl.setAttribute("aria-hidden", "true");
7403
- backdropEl.addEventListener("click", function () {
7404
- hide();
7405
- });
7406
- backdropEl.addEventListener("wheel", onBackdropWheel, {
7407
- passive: false,
7408
- });
7409
- }
7410
- document.body.appendChild(backdropEl);
7411
- wrapper.style.zIndex = "999";
7412
- }
7413
-
7414
- function applyModalClose() {
7415
- if (!modal) return;
7416
- if (backdropEl && backdropEl.parentNode) {
7417
- backdropEl.parentNode.removeChild(backdropEl);
7418
- }
7419
- wrapper.style.zIndex = "";
7420
- }
7114
+ container.appendChild(wrapper);
7421
7115
 
7422
7116
  function noop() {}
7423
7117
 
@@ -7425,80 +7119,33 @@
7425
7119
  const triggerRect = triggerEl.getBoundingClientRect();
7426
7120
  const panelRect = panel.getBoundingClientRect();
7427
7121
  const gap = 8;
7428
- const viewportHeight =
7429
- window.innerHeight || document.documentElement.clientHeight;
7430
- const viewportWidth =
7431
- window.innerWidth || document.documentElement.clientWidth;
7432
- const spaceBelow = viewportHeight - triggerRect.bottom;
7433
- const spaceAbove = triggerRect.top;
7434
- const spaceRight = viewportWidth - triggerRect.right;
7435
- const spaceLeft = triggerRect.left;
7436
-
7437
- // Flip placement when there is not enough space (prefer requested side, flip only when needed)
7438
- let effectivePlacement = placement;
7439
- if (
7440
- placement === "bottom" &&
7441
- spaceBelow < panelRect.height + gap &&
7442
- spaceAbove >= panelRect.height + gap
7443
- ) {
7444
- effectivePlacement = "top";
7445
- } else if (
7446
- placement === "top" &&
7447
- spaceAbove < panelRect.height + gap &&
7448
- spaceBelow >= panelRect.height + gap
7449
- ) {
7450
- effectivePlacement = "bottom";
7451
- } else if (
7452
- placement === "right" &&
7453
- spaceRight < panelRect.width + gap &&
7454
- spaceLeft >= panelRect.width + gap
7455
- ) {
7456
- effectivePlacement = "left";
7457
- } else if (
7458
- placement === "left" &&
7459
- spaceLeft < panelRect.width + gap &&
7460
- spaceRight >= panelRect.width + gap
7461
- ) {
7462
- effectivePlacement = "right";
7463
- }
7464
-
7465
- panel.setAttribute("data-side", effectivePlacement);
7466
-
7467
7122
  let top = 0;
7468
7123
  let left = 0;
7469
- const alignLeft =
7470
- align === "center"
7471
- ? (triggerRect.width - panelRect.width) / 2
7472
- : align === "end"
7473
- ? triggerRect.width - panelRect.width
7474
- : 0;
7475
- const alignTop =
7476
- align === "center"
7477
- ? (triggerRect.height - panelRect.height) / 2
7478
- : align === "end"
7479
- ? triggerRect.height - panelRect.height
7480
- : 0;
7481
-
7482
- 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) {
7483
7130
  case "bottom":
7484
- top = triggerRect.bottom + gap;
7485
- left = triggerRect.left + alignLeft;
7131
+ top = triggerRect.height + gap;
7132
+ left = alignLeft;
7486
7133
  break;
7487
7134
  case "top":
7488
- top = triggerRect.top - panelRect.height - gap;
7489
- left = triggerRect.left + alignLeft;
7135
+ top = -panelRect.height - gap;
7136
+ left = alignLeft;
7490
7137
  break;
7491
7138
  case "right":
7492
- top = triggerRect.top + alignTop;
7493
- left = triggerRect.right + gap;
7139
+ top = alignTop;
7140
+ left = triggerRect.width + gap;
7494
7141
  break;
7495
7142
  case "left":
7496
- top = triggerRect.top + alignTop;
7497
- left = triggerRect.left - panelRect.width - gap;
7143
+ top = alignTop;
7144
+ left = -panelRect.width - gap;
7498
7145
  break;
7499
7146
  default:
7500
- top = triggerRect.bottom + gap;
7501
- left = triggerRect.left + alignLeft;
7147
+ top = triggerRect.height + gap;
7148
+ left = alignLeft;
7502
7149
  }
7503
7150
 
7504
7151
  wrapper.style.transform = "";
@@ -7512,41 +7159,16 @@
7512
7159
  wrapper.classList.add("invisible", "opacity-0", "pointer-events-none");
7513
7160
  wrapper.classList.remove("visible", "opacity-100", "pointer-events-auto");
7514
7161
  wrapper.setAttribute("aria-hidden", "true");
7515
- window.removeEventListener("scroll", onScrollOrResize, true);
7516
- window.removeEventListener("resize", onScrollOrResize);
7517
- if (resizeObserver && panel) {
7518
- resizeObserver.disconnect();
7519
- resizeObserver = null;
7520
- }
7521
- applyModalClose();
7522
7162
  if (onClose) onClose();
7523
7163
  }
7524
7164
 
7525
- function onScrollOrResize() {
7526
- if (wrapper.classList.contains("visible")) position();
7527
- }
7528
-
7529
7165
  function show() {
7530
7166
  if (onOpen) onOpen();
7531
- applyModalOpen();
7532
7167
  requestAnimationFrame(function () {
7533
7168
  position();
7534
- wrapper.classList.remove(
7535
- "invisible",
7536
- "opacity-0",
7537
- "pointer-events-none",
7538
- );
7169
+ wrapper.classList.remove("invisible", "opacity-0", "pointer-events-none");
7539
7170
  wrapper.classList.add("visible", "opacity-100", "pointer-events-auto");
7540
7171
  wrapper.setAttribute("aria-hidden", "false");
7541
- window.addEventListener("scroll", onScrollOrResize, true);
7542
- window.addEventListener("resize", onScrollOrResize);
7543
- // Re-position when panel content size changes (e.g. async record list load in record-select)
7544
- if (typeof ResizeObserver !== "undefined" && !resizeObserver) {
7545
- resizeObserver = new ResizeObserver(function () {
7546
- if (wrapper.classList.contains("visible")) position();
7547
- });
7548
- resizeObserver.observe(panel);
7549
- }
7550
7172
  requestAnimationFrame(function () {
7551
7173
  requestAnimationFrame(function () {
7552
7174
  panel.setAttribute("data-state", "open");
@@ -7557,16 +7179,6 @@
7557
7179
 
7558
7180
  function destroy() {
7559
7181
  hide();
7560
- applyModalClose();
7561
- if (resizeObserver && panel) {
7562
- resizeObserver.disconnect();
7563
- resizeObserver = null;
7564
- }
7565
- if (backdropEl && backdropEl.parentNode) {
7566
- backdropEl.parentNode.removeChild(backdropEl);
7567
- }
7568
- window.removeEventListener("scroll", onScrollOrResize, true);
7569
- window.removeEventListener("resize", onScrollOrResize);
7570
7182
  if (wrapper.parentNode) {
7571
7183
  wrapper.parentNode.removeChild(wrapper);
7572
7184
  }
@@ -7616,8 +7228,6 @@
7616
7228
  show,
7617
7229
  hide,
7618
7230
  destroy,
7619
- /** Re-run positioning (e.g. after async content load). Call when panel size changes. */
7620
- updatePosition: position,
7621
7231
  setContent(newContent) {
7622
7232
  body.innerHTML = "";
7623
7233
  if (typeof newContent === "string") {
@@ -7639,7 +7249,7 @@
7639
7249
 
7640
7250
 
7641
7251
  // ============================================
7642
- // File 15/42: components/select.js
7252
+ // File 15/37: components/select.js
7643
7253
  // ============================================
7644
7254
 
7645
7255
  /**
@@ -7836,11 +7446,11 @@
7836
7446
 
7837
7447
  var content = document.createElement("div");
7838
7448
  content.setAttribute("role", "listbox");
7839
- 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";
7840
7450
 
7841
7451
  var optionsList = document.createElement("div");
7842
7452
  optionsList.className =
7843
- "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";
7844
7454
 
7845
7455
  if (options.length === 0) {
7846
7456
  var noOpt = document.createElement("div");
@@ -7899,7 +7509,7 @@
7899
7509
  align: "start",
7900
7510
  closeOnClickOutside: true,
7901
7511
  bodyClassName: "p-0 overflow-hidden",
7902
- panelClassName: "min-w-[var(--trigger-width)] max-h-[45vh] overflow-hidden",
7512
+ panelClassName: "min-w-[var(--trigger-width)] max-h-[200px] overflow-hidden",
7903
7513
  onOpen: function () {
7904
7514
  if (disabled) {
7905
7515
  popover.hide();
@@ -8197,7 +7807,7 @@
8197
7807
 
8198
7808
 
8199
7809
  // ============================================
8200
- // File 16/42: components/enum-select.js
7810
+ // File 16/37: components/enum-select.js
8201
7811
  // ============================================
8202
7812
 
8203
7813
  /**
@@ -8431,7 +8041,7 @@
8431
8041
  // Create dropdown content
8432
8042
  var content = document.createElement("div");
8433
8043
  content.setAttribute("role", "listbox");
8434
- 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";
8435
8045
 
8436
8046
  // Search input (using InputComponent like phone-input)
8437
8047
  var searchContainer = document.createElement("div");
@@ -8492,7 +8102,7 @@
8492
8102
  // Options list
8493
8103
  var optionsList = document.createElement("div");
8494
8104
  optionsList.className =
8495
- "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";
8496
8106
 
8497
8107
  content.appendChild(searchContainer);
8498
8108
  content.appendChild(optionsList);
@@ -8980,7 +8590,7 @@
8980
8590
 
8981
8591
 
8982
8592
  // ============================================
8983
- // File 17/42: components/record-select.js
8593
+ // File 17/37: components/record-select.js
8984
8594
  // ============================================
8985
8595
 
8986
8596
  /**
@@ -8994,20 +8604,9 @@
8994
8604
 
8995
8605
  (function (global) {
8996
8606
 
8997
- function getDep(name) {
8998
- if (
8999
- typeof global.FlowUI !== "undefined" &&
9000
- typeof global.FlowUI._getComponent === "function"
9001
- ) {
9002
- var c = global.FlowUI._getComponent(name);
9003
- if (c) return c;
9004
- }
9005
- return global[name];
9006
- }
9007
-
9008
- var Popover = getDep("Popover");
9009
- var InputComponent = getDep("InputComponent");
9010
- var Spinner = getDep("Spinner");
8607
+ var Popover = global.Popover;
8608
+ var InputComponent = global.InputComponent;
8609
+ var Spinner = global.Spinner;
9011
8610
 
9012
8611
  /** When objectSlug === USERS, show Vivid Avatar (name-based color) instead of static icon */
9013
8612
  var STANDARD_OBJECT_SLUGS_USERS = "user";
@@ -9029,7 +8628,7 @@
9029
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>';
9030
8629
  var X_SVG =
9031
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>';
9032
-
8631
+
9033
8632
  var SEARCH_ICON =
9034
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>';
9035
8634
 
@@ -9044,8 +8643,7 @@
9044
8643
  "border-error-border hover:border-error-border-hover focus:border-1/2 focus:border-error-border-hover",
9045
8644
  warning:
9046
8645
  "border-warning-border hover:border-warning-border-hover focus:border-1/2 focus:border-warning-border-hover",
9047
- borderless:
9048
- "border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
8646
+ borderless: "border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
9049
8647
  inline:
9050
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",
9051
8649
  };
@@ -9054,9 +8652,7 @@
9054
8652
  large: "px-12 py-8",
9055
8653
  small: "px-8 py-4",
9056
8654
  };
9057
- var placeholderClass = placeholder
9058
- ? " text-typography-quaternary-text"
9059
- : "";
8655
+ var placeholderClass = placeholder ? " text-typography-quaternary-text" : "";
9060
8656
  var disabledClass = disabled
9061
8657
  ? " pointer-events-none cursor-not-allowed bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary"
9062
8658
  : "";
@@ -9112,27 +8708,15 @@
9112
8708
  function getObjectIconInfo(slug, objectSchema) {
9113
8709
  var color = "neutral";
9114
8710
  var iconStr = "IconDatabase";
9115
- if (
9116
- objectSchema &&
9117
- objectSchema.properties &&
9118
- objectSchema.properties.icon_data
9119
- ) {
8711
+ if (objectSchema && objectSchema.properties && objectSchema.properties.icon_data) {
9120
8712
  var iconData = objectSchema.properties.icon_data;
9121
- if (typeof iconData.color === "string" && iconData.color)
9122
- color = iconData.color;
9123
- if (typeof iconData.icon === "string" && iconData.icon)
9124
- 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;
9125
8715
  }
9126
- if (
9127
- !objectSchema ||
9128
- !objectSchema.properties ||
9129
- !objectSchema.properties.icon_data ||
9130
- !objectSchema.properties.icon_data.icon
9131
- ) {
8716
+ if (!objectSchema || !objectSchema.properties || !objectSchema.properties.icon_data || !objectSchema.properties.icon_data.icon) {
9132
8717
  if (OBJECT_SLUG_TO_ICON[slug]) {
9133
8718
  iconStr = OBJECT_SLUG_TO_ICON[slug].iconStr;
9134
- if (OBJECT_SLUG_TO_ICON[slug].color)
9135
- color = OBJECT_SLUG_TO_ICON[slug].color;
8719
+ if (OBJECT_SLUG_TO_ICON[slug].color) color = OBJECT_SLUG_TO_ICON[slug].color;
9136
8720
  } else {
9137
8721
  iconStr = "IconDatabase";
9138
8722
  color = "neutral";
@@ -9155,7 +8739,6 @@
9155
8739
  * @param {string} [config.size] - 'default' | 'large' | 'small'
9156
8740
  * @param {boolean} [config.canClear] - Show clear button when value is set
9157
8741
  * @param {number} [config.initialLimit] - Initial fetch limit (default 50)
9158
- * @param {Object} [config.initialFilter] - Optional filter object to merge with search (e.g. { field: "status", operator: "exact", value: "active" } or { and: [...] })
9159
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)
9160
8743
  * @returns {HTMLElement} Record select container element
9161
8744
  */
@@ -9164,14 +8747,12 @@
9164
8747
  var objectSlug = config.objectSlug;
9165
8748
  var objectSchema = config.objectSchema || null;
9166
8749
  var placeholder = config.placeholder || "Select a record";
9167
- var searchPlaceholder =
9168
- config.searchPlaceholder || "Search " + (objectSlug || "") + "...";
8750
+ var searchPlaceholder = config.searchPlaceholder || "Search " + (objectSlug || "") + "...";
9169
8751
  var onChange = config.onChange;
9170
8752
  var variant = config.variant || "default";
9171
8753
  var size = config.size || "default";
9172
8754
  var canClear = !!config.canClear;
9173
8755
  var initialLimit = config.initialLimit != null ? config.initialLimit : 50;
9174
- var initialFilter = config.initialFilter || null; // Can be array, object, or function returning either
9175
8756
 
9176
8757
  var disabled = config.disabled === true;
9177
8758
  var value =
@@ -9219,7 +8800,7 @@
9219
8800
  size,
9220
8801
  disabled,
9221
8802
  !value,
9222
- canClear && !!value && !disabled,
8803
+ canClear && !!value && !disabled
9223
8804
  );
9224
8805
  trigger.disabled = disabled;
9225
8806
  trigger.setAttribute("aria-haspopup", "listbox");
@@ -9228,8 +8809,7 @@
9228
8809
  trigger.classList.add("record-select-trigger");
9229
8810
 
9230
8811
  var triggerContent = document.createElement("div");
9231
- triggerContent.className =
9232
- "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";
9233
8813
 
9234
8814
  var triggerIcon = document.createElement("span");
9235
8815
  triggerIcon.className = "record-select-trigger-icon shrink-0 hidden";
@@ -9272,9 +8852,7 @@
9272
8852
  // Dropdown content: search + list (same content pattern as Select)
9273
8853
  var content = document.createElement("div");
9274
8854
  content.setAttribute("role", "listbox");
9275
- content.setAttribute("data-field-id", fieldId);
9276
- content.className =
9277
- "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";
9278
8856
 
9279
8857
  var searchWrap = document.createElement("div");
9280
8858
  searchWrap.className = "py-8 border-b-1/2 border-border-primary";
@@ -9305,12 +8883,12 @@
9305
8883
  } else {
9306
8884
  var fallbackWrapper = document.createElement("div");
9307
8885
  fallbackWrapper.className = "flex items-center gap-8 px-12";
9308
-
8886
+
9309
8887
  var searchIconSpan = document.createElement("span");
9310
8888
  searchIconSpan.className = "shrink-0 text-typography-tertiary-text";
9311
8889
  searchIconSpan.innerHTML = SEARCH_ICON;
9312
8890
  fallbackWrapper.appendChild(searchIconSpan);
9313
-
8891
+
9314
8892
  var searchInput = document.createElement("input");
9315
8893
  searchInput.type = "text";
9316
8894
  searchInput.className =
@@ -9324,22 +8902,21 @@
9324
8902
  content.appendChild(searchWrap);
9325
8903
 
9326
8904
  var optionsList = document.createElement("div");
9327
- optionsList.className =
9328
- "overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white record-select-options";
9329
-
8905
+ optionsList.className = "overflow-y-auto max-h-[200px] p-2 w-full rounded-4 bg-fill-quarternary-fill-white record-select-options";
8906
+
9330
8907
  // Add scroll listener for infinite scroll
9331
8908
  optionsList.addEventListener("scroll", function () {
9332
8909
  if (isFetchingMore || !hasMoreRecords) return;
9333
8910
  var scrollHeight = optionsList.scrollHeight;
9334
8911
  var scrollTop = optionsList.scrollTop;
9335
8912
  var clientHeight = optionsList.clientHeight;
9336
-
8913
+
9337
8914
  // Trigger load more when scrolled to bottom (with 50px threshold)
9338
8915
  if (scrollTop + clientHeight >= scrollHeight - 50) {
9339
8916
  loadMoreRecords();
9340
8917
  }
9341
8918
  });
9342
-
8919
+
9343
8920
  content.appendChild(optionsList);
9344
8921
 
9345
8922
  popover = Popover.create({
@@ -9349,41 +8926,30 @@
9349
8926
  align: "start",
9350
8927
  closeOnClickOutside: true,
9351
8928
  bodyClassName: "p-0 overflow-hidden",
9352
- panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
8929
+ panelClassName: "max-h-[30vh] overflow-hidden",
9353
8930
  onOpen: function () {
9354
8931
  if (disabled) {
9355
8932
  popover.hide();
9356
8933
  return;
9357
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
+ });
9358
8942
  isOpen = true;
9359
8943
  container.classList.add("open");
9360
8944
  trigger.setAttribute("aria-expanded", "true");
9361
8945
  searchTerm = "";
9362
8946
  if (searchInputWrapper) searchInputWrapper.setValue("");
9363
8947
  else if (searchInputEl) searchInputEl.value = "";
9364
- if (popover.panel) {
9365
- var triggerWidthPx = trigger.offsetWidth + "px";
9366
- popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
9367
- popover.panel.style.minWidth = triggerWidthPx;
9368
- popover.panel.style.width = triggerWidthPx;
9369
- }
8948
+ content.style.minWidth = trigger.offsetWidth + "px";
9370
8949
  loadInitialAndRender();
9371
8950
  setTimeout(function () {
9372
8951
  if (searchInputEl) searchInputEl.focus();
9373
8952
  }, 0);
9374
- // Let consumers (e.g. BANT Questions "Add Contact") inject content into the dropdown
9375
- try {
9376
- var doc =
9377
- global.document ||
9378
- (typeof document !== "undefined" ? document : null);
9379
- if (doc && typeof global.CustomEvent !== "undefined") {
9380
- doc.dispatchEvent(
9381
- new global.CustomEvent("record-select:opened", {
9382
- detail: { fieldId: fieldId, content: content },
9383
- }),
9384
- );
9385
- }
9386
- } catch (e) {}
9387
8953
  },
9388
8954
  onClose: function () {
9389
8955
  isOpen = false;
@@ -9399,8 +8965,7 @@
9399
8965
  },
9400
8966
  });
9401
8967
 
9402
- if (clearBtn)
9403
- clearBtn.style.display = canClear && value && !disabled ? "" : "none";
8968
+ if (clearBtn) clearBtn.style.display = canClear && value && !disabled ? "" : "none";
9404
8969
 
9405
8970
  function setValue(newVal) {
9406
8971
  value = newVal !== undefined && newVal !== null ? newVal : "";
@@ -9414,18 +8979,16 @@
9414
8979
 
9415
8980
  function updateTriggerDisplay() {
9416
8981
  if (selectedRecord) {
9417
- triggerText.textContent =
9418
- selectedRecord.name || selectedRecord.label || value;
8982
+ triggerText.textContent = selectedRecord.name || selectedRecord.label || value;
9419
8983
  trigger.classList.remove("placeholder");
9420
8984
  trigger.className = triggerClasses(
9421
8985
  variant,
9422
8986
  size,
9423
8987
  disabled,
9424
8988
  false,
9425
- canClear && !!value && !disabled,
8989
+ canClear && !!value && !disabled
9426
8990
  );
9427
- triggerIcon.className =
9428
- "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";
9429
8992
  triggerIcon.innerHTML = "";
9430
8993
  if (objectSlug === STANDARD_OBJECT_SLUGS_USERS) {
9431
8994
  var Avatar = getAvatar();
@@ -9437,9 +9000,7 @@
9437
9000
  });
9438
9001
  triggerIcon.appendChild(vividEl);
9439
9002
  } else {
9440
- renderStaticIconPlaceholder(
9441
- selectedRecord.name || selectedRecord.label,
9442
- );
9003
+ renderStaticIconPlaceholder(selectedRecord.name || selectedRecord.label);
9443
9004
  }
9444
9005
  } else {
9445
9006
  renderStaticObjectIcon();
@@ -9452,13 +9013,12 @@
9452
9013
  size,
9453
9014
  disabled,
9454
9015
  true,
9455
- canClear && !!value && !disabled,
9016
+ canClear && !!value && !disabled
9456
9017
  );
9457
9018
  triggerIcon.className = "record-select-trigger-icon shrink-0 hidden";
9458
9019
  triggerIcon.innerHTML = "";
9459
9020
  }
9460
- if (clearBtn)
9461
- clearBtn.style.display = canClear && value && !disabled ? "" : "none";
9021
+ if (clearBtn) clearBtn.style.display = canClear && value && !disabled ? "" : "none";
9462
9022
  }
9463
9023
 
9464
9024
  function renderStaticObjectIcon() {
@@ -9495,39 +9055,18 @@
9495
9055
  var fields = ["id", "name"];
9496
9056
  var actualLimit = limit || initialLimit;
9497
9057
  var offset = page ? (page - 1) * actualLimit : 0;
9498
-
9058
+
9499
9059
  try {
9500
9060
  if (model && typeof model.select === "function") {
9501
9061
  var q = model.select.apply(model, fields);
9502
- var filters = [];
9503
- var resolvedFilter =
9504
- typeof initialFilter === "function"
9505
- ? initialFilter()
9506
- : initialFilter;
9507
- console.log(
9508
- "[RecordSelect] initialFilter:",
9509
- resolvedFilter,
9510
- "| search:",
9511
- search,
9512
- );
9513
- if (resolvedFilter) {
9514
- filters = filters.concat(
9515
- Array.isArray(resolvedFilter) ? resolvedFilter : [resolvedFilter],
9516
- );
9517
- }
9518
9062
  if (search && search.trim()) {
9519
- filters.push({
9063
+ q = q.filterBy({
9520
9064
  or: [
9521
9065
  { field: "name", operator: "contains", value: search.trim() },
9522
9066
  { field: "id", operator: "eq", value: search.trim() },
9523
9067
  ],
9524
9068
  });
9525
9069
  }
9526
- if (filters.length > 0) {
9527
- q = q.filterBy(
9528
- filters.length === 1 ? filters[0] : { and: filters },
9529
- );
9530
- }
9531
9070
  var orderBy = ["name"];
9532
9071
  if (objectSlug === "account") orderBy.push("-ParentId");
9533
9072
  return q
@@ -9590,12 +9129,7 @@
9590
9129
  updateTriggerDisplay();
9591
9130
  })
9592
9131
  .catch(function () {
9593
- selectedRecord = {
9594
- id: value,
9595
- value: value,
9596
- name: value,
9597
- label: value,
9598
- };
9132
+ selectedRecord = { id: value, value: value, name: value, label: value };
9599
9133
  updateTriggerDisplay();
9600
9134
  });
9601
9135
  }
@@ -9606,9 +9140,7 @@
9606
9140
  loadWrap.className =
9607
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";
9608
9142
  if (Spinner && typeof Spinner.create === "function") {
9609
- loadWrap.appendChild(
9610
- Spinner.create({ size: "small", text: "Loading..." }),
9611
- );
9143
+ loadWrap.appendChild(Spinner.create({ size: "small", text: "Loading..." }));
9612
9144
  } else {
9613
9145
  var loadText = document.createElement("span");
9614
9146
  loadText.textContent = "Loading...";
@@ -9616,12 +9148,12 @@
9616
9148
  }
9617
9149
  optionsList.appendChild(loadWrap);
9618
9150
  }
9619
-
9151
+
9620
9152
  function showLoadingMore() {
9621
9153
  // Remove existing loading more indicator
9622
9154
  var existing = optionsList.querySelector(".record-select-loading-more");
9623
9155
  if (existing) existing.remove();
9624
-
9156
+
9625
9157
  var loadWrap = document.createElement("div");
9626
9158
  loadWrap.className =
9627
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";
@@ -9634,11 +9166,9 @@
9634
9166
  }
9635
9167
  optionsList.appendChild(loadWrap);
9636
9168
  }
9637
-
9169
+
9638
9170
  function removeLoadingMore() {
9639
- var loadingMore = optionsList.querySelector(
9640
- ".record-select-loading-more",
9641
- );
9171
+ var loadingMore = optionsList.querySelector(".record-select-loading-more");
9642
9172
  if (loadingMore) loadingMore.remove();
9643
9173
  }
9644
9174
 
@@ -9657,15 +9187,13 @@
9657
9187
  existingOptions.forEach(function (opt) {
9658
9188
  opt.remove();
9659
9189
  });
9660
-
9190
+
9661
9191
  // Remove old loading/empty states
9662
- var oldStates = optionsList.querySelectorAll(
9663
- ".record-select-loading, .record-select-empty",
9664
- );
9192
+ var oldStates = optionsList.querySelectorAll(".record-select-loading, .record-select-empty");
9665
9193
  oldStates.forEach(function (el) {
9666
9194
  el.remove();
9667
9195
  });
9668
-
9196
+
9669
9197
  filteredRecords.forEach(function (rec) {
9670
9198
  var optionValue = rec.id || rec.value;
9671
9199
  var optionLabel = rec.name || rec.label || rec.value;
@@ -9680,7 +9208,7 @@
9680
9208
  "hover:bg-fill-tertiary-fill-light-gray focus:bg-fill-tertiary-fill-light-gray",
9681
9209
  isSelected
9682
9210
  ? "bg-primary-surface hover:!bg-primary-surface-hover"
9683
- : "",
9211
+ : ""
9684
9212
  );
9685
9213
 
9686
9214
  var optContent = document.createElement("span");
@@ -9738,93 +9266,70 @@
9738
9266
 
9739
9267
  optionsList.appendChild(option);
9740
9268
  });
9741
-
9269
+
9742
9270
  // Add loading more indicator at the bottom if fetching
9743
9271
  if (isFetchingMore) {
9744
9272
  showLoadingMore();
9745
9273
  }
9746
9274
  }
9747
9275
 
9748
- function scheduleUpdatePosition() {
9749
- if (popover && typeof popover.updatePosition === "function") {
9750
- requestAnimationFrame(function () {
9751
- requestAnimationFrame(function () {
9752
- popover.updatePosition();
9753
- });
9754
- });
9755
- }
9756
- }
9757
-
9758
9276
  function loadInitialAndRender() {
9759
9277
  showLoading();
9760
9278
  currentPage = 1;
9761
9279
  hasMoreRecords = true;
9762
9280
  totalFetched = 0;
9763
-
9764
- fetchRecords(searchTerm, initialLimit, 1)
9765
- .then(function (result) {
9766
- allRecords = result.records;
9767
- filteredRecords = result.records;
9768
- hasMoreRecords = result.hasMore;
9769
- totalFetched = result.records.length;
9770
- currentPage = 1;
9771
-
9772
- if (
9773
- value &&
9774
- !result.records.some(function (r) {
9775
- return (r.id || r.value) === value;
9776
- })
9777
- ) {
9778
- loadSelectedRecord();
9779
- } else if (value && result.records.length) {
9780
- var sel = result.records.find(function (r) {
9781
- return (r.id || r.value) === value;
9782
- });
9783
- if (sel) selectedRecord = sel;
9784
- updateTriggerDisplay();
9785
- }
9786
- if (filteredRecords.length === 0) {
9787
- showEmpty(searchTerm ? "No results found" : "No records available");
9788
- } else {
9789
- renderOptions();
9790
- }
9791
- scheduleUpdatePosition();
9792
- })
9793
- .catch(function () {
9794
- showEmpty("Failed to load records");
9795
- hasMoreRecords = false;
9796
- scheduleUpdatePosition();
9797
- });
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
+ });
9798
9305
  }
9799
-
9306
+
9800
9307
  function loadMoreRecords() {
9801
9308
  if (isFetchingMore || !hasMoreRecords) return;
9802
-
9309
+
9803
9310
  isFetchingMore = true;
9804
9311
  currentPage += 1;
9805
9312
  showLoadingMore();
9806
-
9807
- fetchRecords(searchTerm, initialLimit, currentPage)
9808
- .then(function (result) {
9809
- isFetchingMore = false;
9810
- removeLoadingMore();
9811
-
9812
- if (result.records.length > 0) {
9813
- allRecords = allRecords.concat(result.records);
9814
- filteredRecords = filteredRecords.concat(result.records);
9815
- totalFetched += result.records.length;
9816
- hasMoreRecords = result.hasMore;
9817
- renderOptions();
9818
- } else {
9819
- hasMoreRecords = false;
9820
- }
9821
- })
9822
- .catch(function (err) {
9823
- console.error("[RecordSelect] loadMoreRecords error:", err);
9824
- isFetchingMore = false;
9825
- 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 {
9826
9325
  hasMoreRecords = false;
9827
- });
9326
+ }
9327
+ }).catch(function (err) {
9328
+ console.error("[RecordSelect] loadMoreRecords error:", err);
9329
+ isFetchingMore = false;
9330
+ removeLoadingMore();
9331
+ hasMoreRecords = false;
9332
+ });
9828
9333
  }
9829
9334
 
9830
9335
  function debouncedSearch() {
@@ -9835,26 +9340,22 @@
9835
9340
  currentPage = 1;
9836
9341
  hasMoreRecords = true;
9837
9342
  totalFetched = 0;
9838
-
9839
- fetchRecords(searchTerm, initialLimit, 1)
9840
- .then(function (result) {
9841
- allRecords = result.records;
9842
- filteredRecords = result.records;
9843
- hasMoreRecords = result.hasMore;
9844
- totalFetched = result.records.length;
9845
-
9846
- if (result.records.length === 0) {
9847
- showEmpty("No results found");
9848
- } else {
9849
- renderOptions();
9850
- }
9851
- scheduleUpdatePosition();
9852
- })
9853
- .catch(function () {
9854
- showEmpty("Search failed");
9855
- hasMoreRecords = false;
9856
- scheduleUpdatePosition();
9857
- });
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
+ });
9858
9359
  }, 500);
9859
9360
  }
9860
9361
 
@@ -9899,7 +9400,7 @@
9899
9400
  size,
9900
9401
  disabled,
9901
9402
  !value,
9902
- canClear && !!value && !disabled,
9403
+ canClear && !!value && !disabled
9903
9404
  );
9904
9405
  if (disabled && isOpen) closeDropdown();
9905
9406
  };
@@ -9918,7 +9419,7 @@
9918
9419
 
9919
9420
 
9920
9421
  // ============================================
9921
- // File 18/42: components/multiselect.js
9422
+ // File 18/37: components/multiselect.js
9922
9423
  // ============================================
9923
9424
 
9924
9425
  /**
@@ -10076,11 +9577,11 @@
10076
9577
  var content = document.createElement("div");
10077
9578
  content.setAttribute("role", "listbox");
10078
9579
  content.setAttribute("aria-multiselectable", "true");
10079
- 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";
10080
9581
 
10081
9582
  var optionsList = document.createElement("div");
10082
9583
  optionsList.className =
10083
- "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";
10084
9585
 
10085
9586
  function isSelected(optionValue) {
10086
9587
  return values.some(function (v) {
@@ -10185,7 +9686,7 @@
10185
9686
  align: "start",
10186
9687
  closeOnClickOutside: true,
10187
9688
  bodyClassName: "p-0 overflow-hidden",
10188
- panelClassName: "min-w-[var(--trigger-width)] max-h-[45vh] overflow-hidden",
9689
+ panelClassName: "min-w-[var(--trigger-width)] max-h-[200px] overflow-hidden",
10189
9690
  onOpen: function () {
10190
9691
  if (disabled) {
10191
9692
  popover.hide();
@@ -10299,7 +9800,7 @@
10299
9800
 
10300
9801
 
10301
9802
  // ============================================
10302
- // File 19/42: components/enum-multiselect.js
9803
+ // File 19/37: components/enum-multiselect.js
10303
9804
  // ============================================
10304
9805
 
10305
9806
  /**
@@ -10560,7 +10061,7 @@
10560
10061
  var content = document.createElement("div");
10561
10062
  content.setAttribute("role", "listbox");
10562
10063
  content.setAttribute("aria-multiselectable", "true");
10563
- 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";
10564
10065
 
10565
10066
  // Search input (using InputComponent like enum-select)
10566
10067
  var searchContainer = document.createElement("div");
@@ -10621,7 +10122,7 @@
10621
10122
  // Options list
10622
10123
  var optionsList = document.createElement("div");
10623
10124
  optionsList.className =
10624
- "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";
10625
10126
 
10626
10127
  content.appendChild(searchContainer);
10627
10128
  content.appendChild(optionsList);
@@ -11123,7 +10624,7 @@
11123
10624
 
11124
10625
 
11125
10626
  // ============================================
11126
- // File 20/42: components/record-multiselect.js
10627
+ // File 20/37: components/record-multiselect.js
11127
10628
  // ============================================
11128
10629
 
11129
10630
  /**
@@ -11279,7 +10780,6 @@
11279
10780
  * @param {string} [config.size] - 'default' | 'large' | 'small'
11280
10781
  * @param {number} [config.initialLimit] - Initial fetch limit (default 50)
11281
10782
  * @param {Array<string>} [config.displayFields] - Fields to display as secondary info (e.g. ["email", "phone"])
11282
- * @param {Object} [config.initialFilter] - Optional filter object to merge with search (e.g. { field: "status", operator: "exact", value: "active" } or { and: [...] })
11283
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)
11284
10784
  * @returns {HTMLElement} Record multiselect container element
11285
10785
  */
@@ -11294,7 +10794,6 @@
11294
10794
  var variant = config.variant || "default";
11295
10795
  var size = config.size || "default";
11296
10796
  var initialLimit = config.initialLimit != null ? config.initialLimit : 50;
11297
- var initialFilter = config.initialFilter || null; // Can be array, object, or function returning either
11298
10797
  var displayFields = config.displayFields || [];
11299
10798
 
11300
10799
  var disabled = config.disabled === true;
@@ -11420,7 +10919,7 @@
11420
10919
  var content = document.createElement("div");
11421
10920
  content.setAttribute("role", "listbox");
11422
10921
  content.setAttribute("aria-multiselectable", "true");
11423
- 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";
11424
10923
 
11425
10924
  var searchWrap = document.createElement("div");
11426
10925
  searchWrap.className = "p-8 pb-4 border-b-1/2 border-border-primary ";
@@ -11470,7 +10969,7 @@
11470
10969
  content.appendChild(searchWrap);
11471
10970
 
11472
10971
  var optionsList = document.createElement("div");
11473
- 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";
11474
10973
 
11475
10974
  // Add scroll listener for infinite scroll
11476
10975
  optionsList.addEventListener("scroll", function () {
@@ -11498,22 +10997,28 @@
11498
10997
  align: "start",
11499
10998
  closeOnClickOutside: true,
11500
10999
  bodyClassName: "p-0 overflow-hidden",
11501
- panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
11000
+ panelClassName: "max-h-[30vh] overflow-hidden",
11502
11001
  onOpen: function () {
11503
11002
  if (disabled) {
11504
11003
  popover.hide();
11505
11004
  return;
11506
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
+ });
11507
11011
  container.classList.add("open");
11508
11012
  trigger.setAttribute("aria-expanded", "true");
11509
11013
  searchTerm = "";
11510
11014
  if (searchInputWrapper) searchInputWrapper.setValue("");
11511
11015
  else if (searchInputEl) searchInputEl.value = "";
11016
+ var triggerWidthPx = trigger.offsetWidth + "px";
11017
+ content.style.minWidth = triggerWidthPx;
11018
+ content.style.width = triggerWidthPx;
11512
11019
  if (popover.panel) {
11513
- var triggerWidthPx = trigger.offsetWidth + "px";
11514
- popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
11515
- popover.panel.style.minWidth = triggerWidthPx;
11516
11020
  popover.panel.style.width = triggerWidthPx;
11021
+ popover.panel.style.minWidth = triggerWidthPx;
11517
11022
  }
11518
11023
  loadInitialAndRender();
11519
11024
  setTimeout(function () {
@@ -11592,23 +11097,14 @@
11592
11097
  try {
11593
11098
  if (model && typeof model.select === "function") {
11594
11099
  var q = model.select.apply(model, fields);
11595
- var filters = [];
11596
- var resolvedFilter = typeof initialFilter === 'function' ? initialFilter() : initialFilter;
11597
- console.log('[RecordMultiselect] initialFilter:', resolvedFilter, '| search:', search);
11598
- if (resolvedFilter) {
11599
- filters = filters.concat(Array.isArray(resolvedFilter) ? resolvedFilter : [resolvedFilter]);
11600
- }
11601
11100
  if (search && search.trim()) {
11602
- filters.push({
11101
+ q = q.filterBy({
11603
11102
  or: [
11604
11103
  { field: "name", operator: "contains", value: search.trim() },
11605
11104
  { field: "id", operator: "eq", value: search.trim() },
11606
11105
  ],
11607
11106
  });
11608
11107
  }
11609
- if (filters.length > 0) {
11610
- q = q.filterBy(filters.length === 1 ? filters[0] : { and: filters });
11611
- }
11612
11108
  var orderBy = ["name"];
11613
11109
  if (objectSlug === "account") orderBy.push("-ParentId");
11614
11110
  return q
@@ -11867,16 +11363,6 @@
11867
11363
  }
11868
11364
  }
11869
11365
 
11870
- function scheduleUpdatePosition() {
11871
- if (popover && typeof popover.updatePosition === "function") {
11872
- requestAnimationFrame(function () {
11873
- requestAnimationFrame(function () {
11874
- popover.updatePosition();
11875
- });
11876
- });
11877
- }
11878
- }
11879
-
11880
11366
  function loadInitialAndRender() {
11881
11367
  showLoading();
11882
11368
  currentPage = 1;
@@ -11895,11 +11381,9 @@
11895
11381
  } else {
11896
11382
  renderOptions();
11897
11383
  }
11898
- scheduleUpdatePosition();
11899
11384
  }).catch(function () {
11900
11385
  showEmpty("Failed to load records");
11901
11386
  hasMoreRecords = false;
11902
- scheduleUpdatePosition();
11903
11387
  });
11904
11388
  }
11905
11389
 
@@ -11951,11 +11435,9 @@
11951
11435
  } else {
11952
11436
  renderOptions();
11953
11437
  }
11954
- scheduleUpdatePosition();
11955
11438
  }).catch(function () {
11956
11439
  showEmpty("Search failed");
11957
11440
  hasMoreRecords = false;
11958
- scheduleUpdatePosition();
11959
11441
  });
11960
11442
  }, 500);
11961
11443
  }
@@ -12025,7 +11507,7 @@
12025
11507
 
12026
11508
 
12027
11509
  // ============================================
12028
- // File 21/42: components/input.js
11510
+ // File 21/37: components/input.js
12029
11511
  // ============================================
12030
11512
 
12031
11513
  /**
@@ -12052,7 +11534,7 @@
12052
11534
 
12053
11535
  var WRAPPER_CLASS = {
12054
11536
  base:
12055
- "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",
12056
11538
  default:
12057
11539
  "bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
12058
11540
  error:
@@ -12127,16 +11609,13 @@
12127
11609
  var isPassword = type === "password";
12128
11610
 
12129
11611
  var wrapper = document.createElement("div");
12130
- var sizeClass = inputSize === "large" ? WRAPPER_CLASS.sizeLarge : inputSize === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault;
12131
- function applyWrapperClasses() {
12132
- wrapper.className = join(
12133
- WRAPPER_CLASS.base,
12134
- disabled ? WRAPPER_CLASS.disabled : (WRAPPER_CLASS[variant] || WRAPPER_CLASS.default),
12135
- sizeClass,
12136
- config.className || ""
12137
- );
12138
- }
12139
- 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
+ );
12140
11619
  wrapper.setAttribute("data-input-variant", variant);
12141
11620
 
12142
11621
  if (config.prefixNode) {
@@ -12266,12 +11745,19 @@
12266
11745
  wrapper.setVariant = function (v) {
12267
11746
  variant = v;
12268
11747
  wrapper.setAttribute("data-input-variant", v);
12269
- 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
+ );
12270
11755
  };
12271
11756
  wrapper.setDisabled = function (d) {
12272
11757
  disabled = !!d;
12273
11758
  input.disabled = disabled;
12274
- applyWrapperClasses();
11759
+ wrapper.classList.toggle("cursor-not-allowed", disabled);
11760
+ wrapper.classList.toggle("opacity-60", disabled);
12275
11761
  };
12276
11762
 
12277
11763
  return wrapper;
@@ -12286,7 +11772,7 @@
12286
11772
 
12287
11773
 
12288
11774
  // ============================================
12289
- // File 22/42: components/currency.js
11775
+ // File 22/37: components/currency.js
12290
11776
  // ============================================
12291
11777
 
12292
11778
  /**
@@ -12316,7 +11802,7 @@
12316
11802
  sizeLarge: "",
12317
11803
  sizeSmall: "",
12318
11804
  disabled:
12319
- "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",
12320
11806
  };
12321
11807
 
12322
11808
  // Currency type label: fit-content, separator (border-r) on type only, full height
@@ -12503,12 +11989,7 @@
12503
11989
  wrapper.setDisabled = function (d) {
12504
11990
  disabled = !!d;
12505
11991
  input.disabled = disabled;
12506
- wrapper.className = join(
12507
- WRAPPER_CLASS.base,
12508
- WRAPPER_CLASS[variant] != null ? WRAPPER_CLASS[variant] : WRAPPER_CLASS.default,
12509
- disabled ? WRAPPER_CLASS.disabled : "",
12510
- config.className || ""
12511
- );
11992
+ wrapper.classList.toggle("cursor-not-allowed", disabled);
12512
11993
  };
12513
11994
 
12514
11995
  return wrapper;
@@ -12524,7 +12005,7 @@
12524
12005
 
12525
12006
 
12526
12007
  // ============================================
12527
- // File 23/42: components/textarea.js
12008
+ // File 23/37: components/textarea.js
12528
12009
  // ============================================
12529
12010
 
12530
12011
  /**
@@ -12549,7 +12030,7 @@
12549
12030
  warning:
12550
12031
  "min-h-[80px] border-warning-base hover:border-warning-base focus:border-warning-base",
12551
12032
  disabled:
12552
- "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",
12553
12034
  };
12554
12035
 
12555
12036
  function join() {
@@ -12644,347 +12125,7 @@
12644
12125
 
12645
12126
 
12646
12127
  // ============================================
12647
- // File 24/42: components/richtext-editor.js
12648
- // ============================================
12649
-
12650
- /**
12651
- * Rich Text Editor Component (vanilla JS)
12652
- * Toolbar + contenteditable area with formatting (bold, italic, underline, headings, lists, alignment, link, image, code block, undo/redo).
12653
- * Styling matches design: rounded-12, toolbar bg-fill-tertiary-fill-light-gray, content area with min-height.
12654
- */
12655
-
12656
- (function (global) {
12657
-
12658
- var RICH_TEXT_CONTENT_STYLES =
12659
- ".rich-text-editor-content ul{list-style-type:disc;padding-left:1.5em;margin:0.5em 0}" +
12660
- ".rich-text-editor-content ol{list-style-type:decimal;padding-left:1.5em;margin:0.5em 0}" +
12661
- ".rich-text-editor-content li{margin:0.25em 0}" +
12662
- ".rich-text-editor-content li p{margin:0}" +
12663
- ".rich-text-editor-content h1{font-size:1.5rem;font-weight:700;line-height:1.3;margin:0.75em 0 0.5em}" +
12664
- ".rich-text-editor-content h2{font-size:1.25rem;font-weight:600;line-height:1.3;margin:0.75em 0 0.5em}" +
12665
- ".rich-text-editor-content h3{font-size:1.125rem;font-weight:600;line-height:1.3;margin:0.75em 0 0.5em}" +
12666
- ".rich-text-editor-content p{margin:0.5em 0}" +
12667
- ".rich-text-editor-content a{color:var(--color-primary-500);text-decoration:underline;cursor:pointer}" +
12668
- ".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}" +
12669
- ".rich-text-editor-content code{font-family:ui-monospace,monospace;font-size:0.875em}" +
12670
- ".rich-text-editor-content img{max-width:100%;height:auto;margin:0.5em 0}" +
12671
- ".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)}" +
12672
- ".rich-text-editor-content hr{border:none;border-top:1px solid var(--color-neutral-150);margin:1em 0}" +
12673
- ".rich-text-editor-content .ProseMirror,.rich-text-editor-content [contenteditable]{outline:none}";
12674
-
12675
- function join() {
12676
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
12677
- }
12678
-
12679
- function getDep(name) {
12680
- if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
12681
- var c = global.FlowUI._getComponent(name);
12682
- if (c) return c;
12683
- }
12684
- return global[name];
12685
- }
12686
-
12687
- /** Get Tabler icon element (16px) from Icon component for toolbar. */
12688
- function getTablerIcon(iconName) {
12689
- var Icon = getDep("Icon");
12690
- if (!Icon || !Icon.iconMap || !Icon.iconMap[iconName]) return null;
12691
- var svgStr = Icon.iconMap[iconName];
12692
- var s16 = svgStr.replace(/width="24"/, 'width="16"').replace(/height="24"/, 'height="16"').replace(/width="20"/, 'width="16"').replace(/height="20"/, 'height="16"');
12693
- var span = document.createElement("span");
12694
- span.className = "flex items-center justify-center size-16";
12695
- span.innerHTML = s16;
12696
- return span;
12697
- }
12698
-
12699
- function createToolbarButton(opts) {
12700
- var Button = getDep("Button");
12701
- if (!Button || typeof Button.create !== "function") {
12702
- throw new Error("RichTextEditor requires Button");
12703
- }
12704
- var icon = opts.iconStr ? getTablerIcon(opts.iconStr) : null;
12705
- return Button.create({
12706
- variant: "outline",
12707
- size: "default",
12708
- title: opts.title,
12709
- icon: icon,
12710
- onClick: opts.onClick,
12711
- disabled: opts.disabled,
12712
- });
12713
- }
12714
-
12715
- function createSeparator() {
12716
- var sep = document.createElement("div");
12717
- sep.className = "w-px h-16 bg-border-primary mx-4";
12718
- sep.setAttribute("aria-hidden", "true");
12719
- return sep;
12720
- }
12721
-
12722
- /**
12723
- * Create a rich text editor
12724
- * @param {Object} config
12725
- * @param {string} [config.value] - Initial HTML content
12726
- * @param {string} [config.placeholder] - Placeholder when empty
12727
- * @param {number} [config.minHeightPx] - Min height of editor area (default 400)
12728
- * @param {boolean} [config.disabled]
12729
- * @param {Function} [config.onChange] - (html: string) => void
12730
- * @returns {HTMLElement} Wrapper element with getValue/setValue/setDisabled/getInput
12731
- */
12732
- function create(config) {
12733
- var value = config.value != null ? String(config.value) : "";
12734
- var placeholder = config.placeholder != null ? config.placeholder : "";
12735
- var minHeightPx = config.minHeightPx != null ? config.minHeightPx : 400;
12736
- var disabled = !!config.disabled;
12737
- var onChange = config.onChange;
12738
-
12739
- var wrapper = document.createElement("div");
12740
- wrapper.className = "w-full rounded-12 border border-borderColor-border-primary shadow-soft-2x-small";
12741
-
12742
- var styleEl = document.createElement("style");
12743
- styleEl.textContent = RICH_TEXT_CONTENT_STYLES;
12744
- wrapper.appendChild(styleEl);
12745
-
12746
- var toolbar = document.createElement("div");
12747
- toolbar.className =
12748
- "flex flex-wrap gap-4 rounded-t-12 border-borderColor-border-primary bg-fill-tertiary-fill-light-gray p-6";
12749
- toolbar.setAttribute("role", "toolbar");
12750
-
12751
- var editorEl = document.createElement("div");
12752
- editorEl.contentEditable = !disabled;
12753
- editorEl.className = join(
12754
- "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"
12755
- );
12756
- editorEl.style.minHeight = minHeightPx + "px";
12757
- if (value) editorEl.innerHTML = value;
12758
- editorEl.setAttribute("data-placeholder", placeholder);
12759
-
12760
- function isEmpty() {
12761
- var text = (editorEl.textContent || "").trim();
12762
- if (text) return false;
12763
- var html = (editorEl.innerHTML || "").replace(/<br\s*\/?>/gi, "\n").replace(/<[^>]+>/g, "");
12764
- return !html.trim();
12765
- }
12766
- function updatePlaceholder() {
12767
- if (placeholder && isEmpty()) {
12768
- editorEl.classList.add("empty");
12769
- editorEl.setAttribute("data-placeholder", placeholder);
12770
- } else {
12771
- editorEl.classList.remove("empty");
12772
- editorEl.removeAttribute("data-placeholder");
12773
- }
12774
- }
12775
- updatePlaceholder();
12776
-
12777
- function getHtml() {
12778
- return editorEl.innerHTML;
12779
- }
12780
- function setHtml(html) {
12781
- editorEl.innerHTML = html || "";
12782
- updatePlaceholder();
12783
- }
12784
- function notifyChange() {
12785
- if (typeof onChange === "function") onChange(getHtml());
12786
- }
12787
-
12788
- function isActive(cmd, val) {
12789
- try {
12790
- return document.queryCommandState(cmd);
12791
- } catch (e) {
12792
- return false;
12793
- }
12794
- }
12795
- function blockTag() {
12796
- var sel = window.getSelection();
12797
- if (!sel || sel.rangeCount === 0) return null;
12798
- var node = sel.anchorNode;
12799
- while (node && node !== editorEl) {
12800
- if (node.nodeType === 1) {
12801
- var n = node.nodeName.toLowerCase();
12802
- if (["h1", "h2", "h3", "p", "div", "pre", "blockquote"].indexOf(n) !== -1) return n;
12803
- }
12804
- node = node.parentNode;
12805
- }
12806
- return null;
12807
- }
12808
- function isAlignment(align) {
12809
- try {
12810
- if (align === "left") return document.queryCommandState("justifyLeft");
12811
- if (align === "center") return document.queryCommandState("justifyCenter");
12812
- if (align === "right") return document.queryCommandState("justifyRight");
12813
- } catch (e) {}
12814
- return false;
12815
- }
12816
-
12817
- function refreshToolbar() {
12818
- toolbar.querySelectorAll("button").forEach(function (btn) {
12819
- var cmd = btn.getAttribute("data-command");
12820
- var val = btn.getAttribute("data-value");
12821
- if (!cmd) return;
12822
- var active = false;
12823
- if (cmd === "formatBlock") active = blockTag() === val;
12824
- else if (cmd === "justifyLeft" && val === "left") active = isAlignment("left");
12825
- else if (cmd === "justifyCenter" && val === "center") active = isAlignment("center");
12826
- else if (cmd === "justifyRight" && val === "right") active = isAlignment("right");
12827
- else active = isActive(cmd);
12828
- btn.classList.toggle("bg-primary-base", active);
12829
- btn.classList.toggle("border-primary-base", active);
12830
- btn.classList.toggle("text-typography-invert-text", active);
12831
- btn.classList.toggle("bg-fill-quarternary-fill-white", !active);
12832
- btn.classList.toggle("border-border-primary", !active);
12833
- btn.classList.toggle("text-typography-primary-text", !active);
12834
- });
12835
- }
12836
-
12837
- function exec(cmd, value) {
12838
- editorEl.focus();
12839
- document.execCommand(cmd, false, value != null ? value : null);
12840
- refreshToolbar();
12841
- notifyChange();
12842
- }
12843
-
12844
- function insertCodeBlock() {
12845
- editorEl.focus();
12846
- var sel = window.getSelection();
12847
- if (sel && sel.rangeCount) {
12848
- var range = sel.getRangeAt(0);
12849
- var pre = document.createElement("pre");
12850
- var code = document.createElement("code");
12851
- code.textContent = "code here";
12852
- pre.appendChild(code);
12853
- range.insertNode(pre);
12854
- range.setStart(code, 0);
12855
- range.setEnd(code, 0);
12856
- sel.removeAllRanges();
12857
- sel.addRange(range);
12858
- }
12859
- refreshToolbar();
12860
- notifyChange();
12861
- }
12862
-
12863
- function addLink() {
12864
- var url = window.prompt("Enter the URL:", "https://");
12865
- if (url) {
12866
- exec("createLink", url);
12867
- }
12868
- }
12869
-
12870
- function addImage() {
12871
- var input = document.createElement("input");
12872
- input.type = "file";
12873
- input.accept = "image/*";
12874
- input.onchange = function (e) {
12875
- var file = e.target && e.target.files && e.target.files[0];
12876
- if (file) {
12877
- var reader = new FileReader();
12878
- reader.onload = function (ev) {
12879
- var src = ev.target && ev.target.result;
12880
- if (src) {
12881
- editorEl.focus();
12882
- document.execCommand("insertImage", false, src);
12883
- notifyChange();
12884
- }
12885
- };
12886
- reader.readAsDataURL(file);
12887
- }
12888
- };
12889
- input.click();
12890
- }
12891
-
12892
- function undo() {
12893
- editorEl.focus();
12894
- document.execCommand("undo", false, null);
12895
- refreshToolbar();
12896
- notifyChange();
12897
- }
12898
- function redo() {
12899
- editorEl.focus();
12900
- document.execCommand("redo", false, null);
12901
- refreshToolbar();
12902
- notifyChange();
12903
- }
12904
-
12905
- function addBtn(iconStr, title, onClick, dataCommand, dataValue) {
12906
- var btn = createToolbarButton({
12907
- iconStr: iconStr,
12908
- title: title,
12909
- onClick: function () {
12910
- if (disabled) return;
12911
- onClick();
12912
- }});
12913
- if (dataCommand) btn.setAttribute("data-command", dataCommand);
12914
- if (dataValue != null) btn.setAttribute("data-value", dataValue);
12915
- toolbar.appendChild(btn);
12916
- }
12917
-
12918
- addBtn("IconBold", "Bold (Ctrl+B)", function () { exec("bold"); }, "bold");
12919
- addBtn("IconItalic", "Italic (Ctrl+I)", function () { exec("italic"); }, "italic");
12920
- addBtn("IconUnderline", "Underline (Ctrl+U)", function () { exec("underline"); }, "underline");
12921
- toolbar.appendChild(createSeparator());
12922
- addBtn("IconH1", "Heading 1", function () { exec("formatBlock", "h1"); }, "formatBlock", "h1");
12923
- addBtn("IconH2", "Heading 2", function () { exec("formatBlock", "h2"); }, "formatBlock", "h2");
12924
- addBtn("IconH3", "Heading 3", function () { exec("formatBlock", "h3"); }, "formatBlock", "h3");
12925
- toolbar.appendChild(createSeparator());
12926
- addBtn("IconList", "Bullet List", function () { exec("insertUnorderedList"); }, "insertUnorderedList");
12927
- addBtn("IconListNumbers", "Ordered List", function () { exec("insertOrderedList"); }, "insertOrderedList");
12928
- toolbar.appendChild(createSeparator());
12929
- addBtn("IconAlignLeft", "Align Left", function () { exec("justifyLeft"); }, "justifyLeft", "left");
12930
- addBtn("IconAlignCenter", "Align Center", function () { exec("justifyCenter"); }, "justifyCenter", "center");
12931
- addBtn("IconAlignRight", "Align Right", function () { exec("justifyRight"); }, "justifyRight", "right");
12932
- toolbar.appendChild(createSeparator());
12933
- addBtn("IconCode", "Code Block", insertCodeBlock, "formatBlock", "pre");
12934
- addBtn("IconLink", "Add Link", addLink, "link");
12935
- addBtn("IconPhoto", "Insert Image", addImage);
12936
- toolbar.appendChild(createSeparator());
12937
- addBtn("IconArrowBackUp", "Undo", undo);
12938
- addBtn("IconArrowForwardUp", "Redo", redo);
12939
-
12940
- editorEl.addEventListener("input", function () {
12941
- updatePlaceholder();
12942
- refreshToolbar();
12943
- notifyChange();
12944
- });
12945
- editorEl.addEventListener("keyup", refreshToolbar);
12946
- editorEl.addEventListener("mouseup", refreshToolbar);
12947
- editorEl.addEventListener("focus", refreshToolbar);
12948
-
12949
- if (placeholder) {
12950
- var placeholderStyles = document.createElement("style");
12951
- placeholderStyles.textContent =
12952
- ".rich-text-editor-content.empty:before{content:attr(data-placeholder);color:var(--color-neutral-400);pointer-events:none}";
12953
- wrapper.appendChild(placeholderStyles);
12954
- }
12955
-
12956
- wrapper.appendChild(toolbar);
12957
- wrapper.appendChild(editorEl);
12958
-
12959
- wrapper.getInput = function () {
12960
- return editorEl;
12961
- };
12962
- wrapper.getValue = function () {
12963
- return getHtml();
12964
- };
12965
- wrapper.setValue = function (v) {
12966
- setHtml(v);
12967
- };
12968
- wrapper.setDisabled = function (d) {
12969
- disabled = !!d;
12970
- editorEl.contentEditable = !disabled;
12971
- toolbar.querySelectorAll("button").forEach(function (b) {
12972
- b.disabled = disabled;
12973
- });
12974
- };
12975
-
12976
- return wrapper;
12977
- }
12978
-
12979
- global.RichTextEditorComponent = {
12980
- create: create,
12981
- };
12982
- })(typeof window !== "undefined" ? window : undefined);
12983
-
12984
-
12985
-
12986
- // ============================================
12987
- // File 25/42: components/checkbox.js
12128
+ // File 24/37: components/checkbox.js
12988
12129
  // ============================================
12989
12130
 
12990
12131
  /**
@@ -13023,18 +12164,10 @@
13023
12164
  };
13024
12165
 
13025
12166
  var CHECKBOX_BASE_CLASS =
13026
- "flex items-center justify-center rounded-2 border-1/2 border-borderColor-border-primary bg-fill-quarternary-fill-white p-4 transition-all";
13027
-
13028
- var CHECKBOX_ACTIVE_CLASS =
13029
- "hover:border-primary-base hover:shadow-primary-focused cursor-pointer";
13030
-
13031
- var CHECKBOX_DISABLED_CLASS =
13032
- "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";
13033
12168
 
13034
12169
  var CHECKBOX_CHECKED_CLASS =
13035
- "data-checked:border-transparent data-checked:bg-primary-base";
13036
- var CHECKBOX_CHECKED_ACTIVE_CLASS =
13037
- "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";
13038
12171
 
13039
12172
  var LABEL_BASE_CLASS =
13040
12173
  "cursor-pointer pb-0 text-reg-12 leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70";
@@ -13098,16 +12231,12 @@
13098
12231
 
13099
12232
  // Custom checkbox visual
13100
12233
  var checkboxBox = document.createElement("div");
13101
- function applyCheckboxBoxClasses() {
13102
- var sizeClass = CHECKBOX_SIZES[size] || CHECKBOX_SIZES.default;
13103
- checkboxBox.className = join(
13104
- CHECKBOX_BASE_CLASS,
13105
- disabled ? CHECKBOX_DISABLED_CLASS : join(CHECKBOX_ACTIVE_CLASS, CHECKBOX_CHECKED_ACTIVE_CLASS),
13106
- CHECKBOX_CHECKED_CLASS,
13107
- sizeClass
13108
- );
13109
- }
13110
- applyCheckboxBoxClasses();
12234
+ checkboxBox.className = join(
12235
+ CHECKBOX_BASE_CLASS,
12236
+ CHECKBOX_CHECKED_CLASS,
12237
+ CHECKBOX_SIZES[size] || CHECKBOX_SIZES.default,
12238
+ "cursor-pointer"
12239
+ );
13111
12240
  checkboxBox.setAttribute("role", "checkbox");
13112
12241
  checkboxBox.setAttribute("tabindex", disabled ? "-1" : "0");
13113
12242
  checkboxBox.setAttribute("aria-checked", indeterminate ? "mixed" : checked ? "true" : "false");
@@ -13224,7 +12353,6 @@
13224
12353
  } else {
13225
12354
  checkboxBox.removeAttribute("aria-disabled");
13226
12355
  }
13227
- applyCheckboxBoxClasses();
13228
12356
  updateCheckedState();
13229
12357
  };
13230
12358
 
@@ -13257,210 +12385,7 @@
13257
12385
 
13258
12386
 
13259
12387
  // ============================================
13260
- // File 26/42: components/checkbox-group.js
13261
- // ============================================
13262
-
13263
- /**
13264
- * CheckboxGroup Component (vanilla JS)
13265
- * Multi-select via checkboxes; same API as MultiSelect (options, value array, onValuesChange).
13266
- * Uses input.js-style variants and sizes for the group wrapper.
13267
- */
13268
-
13269
- (function (global) {
13270
-
13271
- // Wrapper classes aligned with input.js variants
13272
- var WRAPPER_CLASS = {
13273
- base:
13274
- "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",
13275
- default:
13276
- "bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
13277
- error:
13278
- "border-error-base bg-fill-quarternary-fill-white hover:border-error-base focus-within:border-error-base",
13279
- warning:
13280
- "border-warning-base bg-fill-quarternary-fill-white hover:border-warning-base focus-within:border-warning-base",
13281
- success:
13282
- "border-success-base bg-fill-quarternary-fill-white hover:border-success-base focus-within:border-success-base",
13283
- borderless:
13284
- "border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
13285
- inline:
13286
- "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",
13287
- sizeDefault: "px-12 py-6 gap-6",
13288
- sizeLarge: "px-12 py-8 gap-8",
13289
- sizeSmall: "px-12 py-4 gap-4",
13290
- disabled:
13291
- "cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
13292
- };
13293
-
13294
- function join() {
13295
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
13296
- }
13297
-
13298
- function getOptionValue(opt) {
13299
- return opt.value !== undefined && opt.value !== null
13300
- ? opt.value
13301
- : opt.slug || opt.id;
13302
- }
13303
-
13304
- function getOptionLabel(opt) {
13305
- return opt.label || opt.name || opt.display_name || opt.value;
13306
- }
13307
-
13308
- function getDep(name) {
13309
- if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
13310
- var c = global.FlowUI._getComponent(name);
13311
- if (c) return c;
13312
- }
13313
- return global[name];
13314
- }
13315
-
13316
- /**
13317
- * Create a checkbox group component (multiselect-like: multiple values, options array)
13318
- * @param {Object} config
13319
- * @param {string} [config.fieldId] - Field ID for state management
13320
- * @param {Array} config.options - Array of { value, label } or { slug, display_name }
13321
- * @param {Array} [config.value] - Current selected values (array)
13322
- * @param {Function} config.onValuesChange - Change handler (values: string[])
13323
- * @param {boolean} [config.disabled] - Whether all checkboxes are disabled
13324
- * @param {string} [config.variant] - 'default' | 'error' | 'warning' | 'success' | 'borderless' | 'inline'
13325
- * @param {string} [config.size] - 'default' | 'large' | 'small'
13326
- * @param {string} [config.layout] - 'vertical' | 'horizontal'
13327
- * @param {string} [config.className] - Extra class on wrapper
13328
- * @returns {HTMLElement} CheckboxGroup container element
13329
- */
13330
- function createCheckboxGroup(config) {
13331
- var fieldId = config.fieldId;
13332
- var options = config.options || [];
13333
- var onValuesChange = config.onValuesChange;
13334
- var variant = config.variant || "default";
13335
- var size = config.size || "default";
13336
- var disabled = config.disabled === true;
13337
- var layout = config.layout || "vertical";
13338
- var className = config.className || "";
13339
-
13340
- var values = Array.isArray(config.value)
13341
- ? config.value.slice()
13342
- : Array.isArray(config.values)
13343
- ? config.values.slice()
13344
- : [];
13345
-
13346
- var Checkbox = getDep("Checkbox");
13347
- if (!Checkbox || typeof Checkbox.create !== "function") {
13348
- throw new Error("CheckboxGroup requires the Checkbox component. Load checkbox.js before checkbox-group.js.");
13349
- }
13350
-
13351
- var container = document.createElement("div");
13352
- container.setAttribute("role", "group");
13353
- container.setAttribute("aria-label", config.ariaLabel || "Checkbox group");
13354
- if (fieldId) container.setAttribute("data-field-id", fieldId);
13355
-
13356
- var sizeClass = size === "large" ? WRAPPER_CLASS.sizeLarge : size === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault;
13357
- function applyWrapperClasses() {
13358
- container.className = join(
13359
- WRAPPER_CLASS.base,
13360
- disabled ? WRAPPER_CLASS.disabled : (WRAPPER_CLASS[variant] || WRAPPER_CLASS.default),
13361
- sizeClass,
13362
- layout === "horizontal" ? "flex-row flex-wrap" : "flex-col",
13363
- "custom-checkbox-group",
13364
- className
13365
- );
13366
- }
13367
- applyWrapperClasses();
13368
- container.setAttribute("data-checkbox-group-variant", variant);
13369
-
13370
- function isSelected(optionValue) {
13371
- return values.some(function (v) {
13372
- return v === optionValue || String(v) === String(optionValue);
13373
- });
13374
- }
13375
-
13376
- var optionsContainer = document.createElement("div");
13377
- optionsContainer.className = join(
13378
- "flex gap-8",
13379
- layout === "horizontal" ? "flex-row flex-wrap" : "flex-col"
13380
- );
13381
-
13382
- function buildOptions() {
13383
- optionsContainer.innerHTML = "";
13384
- if (options.length === 0) {
13385
- var empty = document.createElement("div");
13386
- empty.className = "!text-reg-13 text-typography-quaternary-text py-4";
13387
- empty.textContent = "No options available";
13388
- optionsContainer.appendChild(empty);
13389
- return;
13390
- }
13391
-
13392
- options.forEach(function (opt, index) {
13393
- var optionValue = getOptionValue(opt);
13394
- var optionLabel = getOptionLabel(opt);
13395
- var optionDisabled = disabled || !!opt.disabled;
13396
- var checked = isSelected(optionValue);
13397
-
13398
- var cb = Checkbox.create({
13399
- id: (fieldId || "cbg") + "-" + index,
13400
- name: fieldId ? fieldId + "[]" : "checkbox-group-" + index,
13401
- checked: checked,
13402
- disabled: optionDisabled,
13403
- label: optionLabel,
13404
- align: "left",
13405
- size: size === "large" ? "large" : size === "small" ? "small" : "default",
13406
- onChange: function (isChecked) {
13407
- if (optionDisabled) return;
13408
- if (isChecked) {
13409
- if (!values.some(function (v) { return v === optionValue || String(v) === String(optionValue); })) {
13410
- values.push(optionValue);
13411
- }
13412
- } else {
13413
- var idx = values.findIndex(function (v) {
13414
- return v === optionValue || String(v) === String(optionValue);
13415
- });
13416
- if (idx >= 0) values.splice(idx, 1);
13417
- }
13418
- if (onValuesChange) onValuesChange(values.slice());
13419
- },
13420
- });
13421
- optionsContainer.appendChild(cb);
13422
- });
13423
- }
13424
-
13425
- buildOptions();
13426
- container.appendChild(optionsContainer);
13427
-
13428
- container.updateValues = function (newValues) {
13429
- values = Array.isArray(newValues) ? newValues.slice() : [];
13430
- buildOptions();
13431
- };
13432
-
13433
- container.setDisabled = function (isDisabled) {
13434
- disabled = !!isDisabled;
13435
- applyWrapperClasses();
13436
- var wrappers = optionsContainer.querySelectorAll(":scope > div");
13437
- for (var i = 0; i < wrappers.length; i++) {
13438
- if (typeof wrappers[i].setDisabled === "function") wrappers[i].setDisabled(disabled);
13439
- }
13440
- };
13441
-
13442
- container.setVariant = function (v) {
13443
- variant = v;
13444
- container.setAttribute("data-checkbox-group-variant", v);
13445
- applyWrapperClasses();
13446
- };
13447
-
13448
- container.getValues = function () {
13449
- return values.slice();
13450
- };
13451
-
13452
- return container;
13453
- }
13454
-
13455
- global.CheckboxGroup = {
13456
- create: createCheckboxGroup,
13457
- };
13458
- })(typeof window !== "undefined" ? window : undefined);
13459
-
13460
-
13461
-
13462
- // ============================================
13463
- // File 27/42: components/radio-group.js
12388
+ // File 25/37: components/radio-group.js
13464
12389
  // ============================================
13465
12390
 
13466
12391
  /**
@@ -13871,296 +12796,7 @@
13871
12796
 
13872
12797
 
13873
12798
  // ============================================
13874
- // File 28/42: components/card-select.js
13875
- // ============================================
13876
-
13877
- /**
13878
- * CardSelect Component (vanilla JS)
13879
- * Full-width clickable card selection with icon, title, description, and check indicator.
13880
- * Drop-in replacement / upgrade to RadioGroup when visual card UI is preferred.
13881
- */
13882
-
13883
- (function (global) {
13884
-
13885
- var COLORS = {
13886
- selectedBorder: "#175259",
13887
- unselectedBorder: "#e5e7eb",
13888
- selectedBg: "#f0f9f8",
13889
- unselectedBg: "#ffffff",
13890
- selectedShadow: "0px 0px 0px 2px #e9f7f5",
13891
- unselectedShadow: "0px 1.5px 4px -1px rgba(10,9,11,0.07)",
13892
- hoverBorder: "#9ca3af",
13893
- hoverShadow: "0px 5px 13px -5px rgba(10,9,11,0.05), 0px 2px 4px -1px rgba(10,9,11,0.02)",
13894
- iconSelectedBg: "#d0ede9",
13895
- iconUnselectedBg: "#f3f4f6",
13896
- iconSelectedColor: "#175259",
13897
- iconUnselectedColor: "#6b7280",
13898
- titleSelected: "#175259",
13899
- titleUnselected: "#111827",
13900
- descSelected: "#35b18b",
13901
- descUnselected: "#6b7280",
13902
- checkBorderSelected: "#175259",
13903
- checkBorderUnselected: "#d1d5db",
13904
- checkBgSelected: "#175259",
13905
- checkBgUnselected: "transparent",
13906
- };
13907
-
13908
- var CHECK_ICON =
13909
- '<svg width="10" height="10" viewBox="0 0 10 10" fill="none"><path d="M2 5l2.5 2.5L8 3" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>';
13910
-
13911
- function join() {
13912
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
13913
- }
13914
-
13915
- function applyCardStyles(card, isSelected) {
13916
- card.style.borderColor = isSelected ? COLORS.selectedBorder : COLORS.unselectedBorder;
13917
- card.style.background = isSelected ? COLORS.selectedBg : COLORS.unselectedBg;
13918
- card.style.boxShadow = isSelected ? COLORS.selectedShadow : COLORS.unselectedShadow;
13919
- }
13920
-
13921
- function applyIconStyles(iconWrapper, isSelected) {
13922
- iconWrapper.style.background = isSelected ? COLORS.iconSelectedBg : COLORS.iconUnselectedBg;
13923
- iconWrapper.style.color = isSelected ? COLORS.iconSelectedColor : COLORS.iconUnselectedColor;
13924
- }
13925
-
13926
- function applyTitleStyles(titleEl, isSelected) {
13927
- titleEl.style.color = isSelected ? COLORS.titleSelected : COLORS.titleUnselected;
13928
- }
13929
-
13930
- function applyDescStyles(descEl, isSelected) {
13931
- descEl.style.color = isSelected ? COLORS.descSelected : COLORS.descUnselected;
13932
- }
13933
-
13934
- function applyCheckStyles(checkEl, isSelected) {
13935
- checkEl.style.borderColor = isSelected ? COLORS.checkBorderSelected : COLORS.checkBorderUnselected;
13936
- checkEl.style.background = isSelected ? COLORS.checkBgSelected : COLORS.checkBgUnselected;
13937
- checkEl.innerHTML = isSelected ? CHECK_ICON : "";
13938
- }
13939
-
13940
- /**
13941
- * Create a card select component
13942
- * @param {Object} config
13943
- * @param {string} [config.name] - name attribute for the group (used for id generation)
13944
- * @param {Array} config.options - array of { value, label, description?, icon?, disabled? }
13945
- * @param {string} [config.defaultValue] - initial selected value
13946
- * @param {string} [config.value] - controlled value (takes priority over defaultValue)
13947
- * @param {boolean} [config.disabled] - disable all cards
13948
- * @param {string} [config.className] - extra class on wrapper
13949
- * @param {Function} [config.onChange] - change handler (receives selected value)
13950
- * @returns {HTMLElement} wrapper element with getValue/setValue/setDisabled API
13951
- */
13952
- function create(config) {
13953
- var opts = config || {};
13954
- var name = opts.name || "card-select-" + Math.random().toString(36).substr(2, 9);
13955
- var options = opts.options || [];
13956
- var defaultValue = opts.defaultValue;
13957
- var selectedValue = opts.value !== undefined ? opts.value : defaultValue;
13958
- var disabled = !!opts.disabled;
13959
- var className = opts.className || "";
13960
- var onChange = opts.onChange;
13961
-
13962
- // Wrapper container
13963
- var wrapper = document.createElement("div");
13964
- wrapper.setAttribute("role", "radiogroup");
13965
- wrapper.setAttribute("dir", "ltr");
13966
- wrapper.className = join("flex flex-col gap-3 w-full", className);
13967
-
13968
- function updateAllCards(newValue) {
13969
- var cards = wrapper.querySelectorAll("[data-card-value]");
13970
- cards.forEach(function (card) {
13971
- var cv = card.dataset.cardValue;
13972
- var active = cv === newValue;
13973
- applyCardStyles(card, active);
13974
- card.setAttribute("aria-checked", active ? "true" : "false");
13975
- var iw = card.querySelector("[data-icon]");
13976
- var titleEl = card.querySelector("[data-title]");
13977
- var descEl = card.querySelector("[data-desc]");
13978
- var checkEl = card.querySelector("[data-check]");
13979
- if (iw) applyIconStyles(iw, active);
13980
- if (titleEl) applyTitleStyles(titleEl, active);
13981
- if (descEl) applyDescStyles(descEl, active);
13982
- if (checkEl) applyCheckStyles(checkEl, active);
13983
- });
13984
- }
13985
-
13986
- options.forEach(function (option, index) {
13987
- var optionValue = option.value;
13988
- var optionLabel = option.label || option.value;
13989
- var optionDesc = option.description || "";
13990
- var optionIcon = option.icon || "";
13991
- var optionDisabled = disabled || !!option.disabled;
13992
- var isSelected = optionValue === selectedValue;
13993
-
13994
- // Card element
13995
- var card = document.createElement("div");
13996
- card.dataset.cardValue = optionValue;
13997
- card.id = name + "-card-" + index;
13998
- card.setAttribute("role", "radio");
13999
- card.setAttribute("aria-checked", isSelected ? "true" : "false");
14000
- card.setAttribute("tabindex", optionDisabled ? "-1" : "0");
14001
-
14002
- card.style.cssText = [
14003
- "display: flex",
14004
- "align-items: flex-start",
14005
- "gap: 16px",
14006
- "padding: 18px 20px",
14007
- "border-radius: 10px",
14008
- "border: 1.5px solid " + (isSelected ? COLORS.selectedBorder : COLORS.unselectedBorder),
14009
- "background: " + (isSelected ? COLORS.selectedBg : COLORS.unselectedBg),
14010
- "cursor: " + (optionDisabled ? "not-allowed" : "pointer"),
14011
- "transition: border-color 0.15s, background 0.15s, box-shadow 0.15s",
14012
- "box-shadow: " + (isSelected ? COLORS.selectedShadow : COLORS.unselectedShadow),
14013
- "user-select: none",
14014
- optionDisabled ? "opacity: 0.5" : "",
14015
- ].filter(Boolean).join("; ");
14016
-
14017
- // Icon wrapper (only rendered when icon is provided)
14018
- if (optionIcon) {
14019
- var iconWrapper = document.createElement("div");
14020
- iconWrapper.dataset.icon = "";
14021
- iconWrapper.style.cssText = [
14022
- "flex-shrink: 0",
14023
- "width: 44px",
14024
- "height: 44px",
14025
- "border-radius: 8px",
14026
- "background: " + (isSelected ? COLORS.iconSelectedBg : COLORS.iconUnselectedBg),
14027
- "display: flex",
14028
- "align-items: center",
14029
- "justify-content: center",
14030
- "color: " + (isSelected ? COLORS.iconSelectedColor : COLORS.iconUnselectedColor),
14031
- "transition: background 0.15s, color 0.15s",
14032
- ].join("; ");
14033
- iconWrapper.innerHTML = optionIcon;
14034
- card.appendChild(iconWrapper);
14035
- }
14036
-
14037
- // Text wrapper
14038
- var textWrapper = document.createElement("div");
14039
- textWrapper.style.cssText = "display: flex; flex-direction: column; gap: 4px; flex: 1;";
14040
-
14041
- var titleEl = document.createElement("span");
14042
- titleEl.dataset.title = "";
14043
- titleEl.textContent = optionLabel;
14044
- titleEl.style.cssText = [
14045
- "font-size: 14px",
14046
- "font-weight: 600",
14047
- "color: " + (isSelected ? COLORS.titleSelected : COLORS.titleUnselected),
14048
- "line-height: 1.4",
14049
- "transition: color 0.15s",
14050
- ].join("; ");
14051
- textWrapper.appendChild(titleEl);
14052
-
14053
- if (optionDesc) {
14054
- var descEl = document.createElement("span");
14055
- descEl.dataset.desc = "";
14056
- descEl.textContent = optionDesc;
14057
- descEl.style.cssText = [
14058
- "font-size: 12px",
14059
- "color: " + (isSelected ? COLORS.descSelected : COLORS.descUnselected),
14060
- "line-height: 1.5",
14061
- "transition: color 0.15s",
14062
- ].join("; ");
14063
- textWrapper.appendChild(descEl);
14064
- }
14065
-
14066
- card.appendChild(textWrapper);
14067
-
14068
- // Check indicator (radio circle in top-right)
14069
- var checkEl = document.createElement("div");
14070
- checkEl.dataset.check = "";
14071
- checkEl.style.cssText = [
14072
- "flex-shrink: 0",
14073
- "width: 18px",
14074
- "height: 18px",
14075
- "border-radius: 50%",
14076
- "border: 2px solid " + (isSelected ? COLORS.checkBorderSelected : COLORS.checkBorderUnselected),
14077
- "background: " + (isSelected ? COLORS.checkBgSelected : COLORS.checkBgUnselected),
14078
- "display: flex",
14079
- "align-items: center",
14080
- "justify-content: center",
14081
- "margin-top: 2px",
14082
- "transition: all 0.15s",
14083
- ].join("; ");
14084
- if (isSelected) {
14085
- checkEl.innerHTML = CHECK_ICON;
14086
- }
14087
- card.appendChild(checkEl);
14088
-
14089
- // Hover and focus styles
14090
- if (!optionDisabled) {
14091
- card.addEventListener("mouseenter", function () {
14092
- if (card.getAttribute("aria-checked") !== "true") {
14093
- card.style.borderColor = COLORS.hoverBorder;
14094
- card.style.boxShadow = COLORS.hoverShadow;
14095
- }
14096
- });
14097
- card.addEventListener("mouseleave", function () {
14098
- if (card.getAttribute("aria-checked") !== "true") {
14099
- card.style.borderColor = COLORS.unselectedBorder;
14100
- card.style.boxShadow = COLORS.unselectedShadow;
14101
- }
14102
- });
14103
-
14104
- // Click handler
14105
- card.addEventListener("click", function () {
14106
- if (optionDisabled || disabled) return;
14107
- selectedValue = optionValue;
14108
- updateAllCards(selectedValue);
14109
- if (typeof onChange === "function") {
14110
- onChange(selectedValue);
14111
- }
14112
- });
14113
-
14114
- // Keyboard support
14115
- card.addEventListener("keydown", function (e) {
14116
- if (optionDisabled || disabled) return;
14117
- if (e.key === " " || e.key === "Enter") {
14118
- e.preventDefault();
14119
- card.click();
14120
- }
14121
- });
14122
- }
14123
-
14124
- wrapper.appendChild(card);
14125
- });
14126
-
14127
- // Public API
14128
- wrapper.getValue = function () {
14129
- return selectedValue !== undefined ? selectedValue : null;
14130
- };
14131
-
14132
- wrapper.setValue = function (newValue) {
14133
- selectedValue = newValue;
14134
- updateAllCards(newValue);
14135
- };
14136
-
14137
- wrapper.setDisabled = function (isDisabled) {
14138
- disabled = !!isDisabled;
14139
- wrapper.querySelectorAll("[data-card-value]").forEach(function (card) {
14140
- card.style.cursor = disabled ? "not-allowed" : "pointer";
14141
- card.style.opacity = disabled ? "0.5" : "1";
14142
- card.setAttribute("tabindex", disabled ? "-1" : "0");
14143
- });
14144
- };
14145
-
14146
- return wrapper;
14147
- }
14148
-
14149
- var CardSelect = {
14150
- create: create,
14151
- };
14152
-
14153
- if (typeof module !== "undefined" && module.exports) {
14154
- module.exports = CardSelect;
14155
- } else {
14156
- global.CardSelect = CardSelect;
14157
- }
14158
- })(typeof window !== "undefined" ? window : undefined);
14159
-
14160
-
14161
-
14162
- // ============================================
14163
- // File 29/42: components/enumeration.js
12799
+ // File 26/37: components/enumeration.js
14164
12800
  // ============================================
14165
12801
 
14166
12802
  /**
@@ -14172,7 +12808,7 @@
14172
12808
  (function (global) {
14173
12809
 
14174
12810
  var BASE_CLASS =
14175
- "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";
14176
12812
 
14177
12813
  var VARIANTS = {
14178
12814
  default:
@@ -14196,7 +12832,7 @@
14196
12832
  };
14197
12833
 
14198
12834
  var DISABLED_CLASS =
14199
- "pointer-events-none !cursor-not-allowed opacity-50 bg-fill-tertiary-fill-light-gray";
12835
+ "pointer-events-none !cursor-not-allowed opacity-50";
14200
12836
  var READONLY_CLASS = "pointer-events-none";
14201
12837
 
14202
12838
  var ITEM_BASE_CLASS =
@@ -14257,21 +12893,18 @@
14257
12893
  var disabled = opts.disabled === true;
14258
12894
  var readOnly = opts.readOnly === true;
14259
12895
  var className = opts.className || "";
14260
- var onValueChange = opts.onValueChange;
14261
- var children = opts.children;
14262
-
14263
- var wrapper = document.createElement("div");
14264
- function applyWrapperClasses() {
14265
- wrapper.className = join(
14266
- BASE_CLASS,
14267
- VARIANTS[variant] != null ? VARIANTS[variant] : VARIANTS.default,
14268
- SIZES[size] != null ? SIZES[size] : SIZES.default,
14269
- disabled ? DISABLED_CLASS : "",
14270
- readOnly ? READONLY_CLASS : "",
14271
- className
14272
- );
14273
- }
14274
- 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
+ );
14275
12908
  wrapper.setAttribute("data-enumeration-variant", variant);
14276
12909
 
14277
12910
  var count =
@@ -14341,22 +12974,6 @@
14341
12974
  }
14342
12975
  }
14343
12976
 
14344
- wrapper.setDisabled = function (d) {
14345
- disabled = d === true;
14346
- for (var j = 0; j < itemElements.length; j++) {
14347
- itemElements[j].setAttribute("tabindex", disabled || readOnly ? "-1" : "0");
14348
- }
14349
- applyWrapperClasses();
14350
- };
14351
-
14352
- wrapper.setReadOnly = function (r) {
14353
- readOnly = r === true;
14354
- for (var j = 0; j < itemElements.length; j++) {
14355
- itemElements[j].setAttribute("tabindex", disabled || readOnly ? "-1" : "0");
14356
- }
14357
- applyWrapperClasses();
14358
- };
14359
-
14360
12977
  return wrapper;
14361
12978
  }
14362
12979
 
@@ -14398,7 +13015,7 @@
14398
13015
 
14399
13016
 
14400
13017
  // ============================================
14401
- // File 30/42: components/time-picker.js
13018
+ // File 27/37: components/time-picker.js
14402
13019
  // ============================================
14403
13020
 
14404
13021
  /**
@@ -14759,7 +13376,7 @@
14759
13376
 
14760
13377
 
14761
13378
  // ============================================
14762
- // File 31/42: components/duration/duration-utils.js
13379
+ // File 28/37: components/duration/duration-utils.js
14763
13380
  // ============================================
14764
13381
 
14765
13382
  /**
@@ -14929,7 +13546,7 @@
14929
13546
 
14930
13547
 
14931
13548
  // ============================================
14932
- // File 32/42: components/duration/duration-constants.js
13549
+ // File 29/37: components/duration/duration-constants.js
14933
13550
  // ============================================
14934
13551
 
14935
13552
  /**
@@ -14981,7 +13598,7 @@
14981
13598
 
14982
13599
 
14983
13600
  // ============================================
14984
- // File 33/42: components/duration/duration.js
13601
+ // File 30/37: components/duration/duration.js
14985
13602
  // ============================================
14986
13603
 
14987
13604
  /**
@@ -15025,7 +13642,7 @@
15025
13642
  sizeLarge: "px-12 py-8",
15026
13643
  sizeSmall: "px-12 py-4",
15027
13644
  disabled:
15028
- "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",
15029
13646
  };
15030
13647
 
15031
13648
  function join() {
@@ -15418,13 +14035,8 @@
15418
14035
  };
15419
14036
  container.setDisabled = function (d) {
15420
14037
  disabled = !!d;
15421
- triggerWrapper.className = join(
15422
- TRIGGER_CLASS.base,
15423
- TRIGGER_CLASS[variant] != null ? TRIGGER_CLASS[variant] : TRIGGER_CLASS.default,
15424
- size === "large" ? TRIGGER_CLASS.sizeLarge : size === "small" ? TRIGGER_CLASS.sizeSmall : TRIGGER_CLASS.sizeDefault,
15425
- disabled ? TRIGGER_CLASS.disabled : "",
15426
- className
15427
- );
14038
+ triggerWrapper.classList.toggle("cursor-not-allowed", disabled);
14039
+ triggerWrapper.classList.toggle("opacity-60", disabled);
15428
14040
  triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
15429
14041
  if (disabled) popoverApi.hide();
15430
14042
  };
@@ -15440,7 +14052,7 @@
15440
14052
 
15441
14053
 
15442
14054
  // ============================================
15443
- // File 34/42: components/date-time-picker/date-time-picker-utils.js
14055
+ // File 31/37: components/date-time-picker/date-time-picker-utils.js
15444
14056
  // ============================================
15445
14057
 
15446
14058
  /**
@@ -15699,7 +14311,7 @@
15699
14311
 
15700
14312
 
15701
14313
  // ============================================
15702
- // File 35/42: components/date-time-picker/date-time-picker.js
14314
+ // File 32/37: components/date-time-picker/date-time-picker.js
15703
14315
  // ============================================
15704
14316
 
15705
14317
  /**
@@ -15944,15 +14556,13 @@
15944
14556
  var displayMonth = validDate ? new Date(validDate.getTime()) : new Date();
15945
14557
 
15946
14558
  var triggerWrapper = document.createElement("div");
15947
- function getTriggerClassName(disabledState) {
15948
- return join(
15949
- "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",
15950
- "bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
15951
- size === "large" ? "px-12 py-8" : size === "small" ? "px-12 py-4" : "px-12 py-6",
15952
- 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"
15953
- );
15954
- }
15955
- 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;
15956
14566
  triggerWrapper.setAttribute("role", "button");
15957
14567
  triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
15958
14568
  triggerWrapper.setAttribute("aria-haspopup", "dialog");
@@ -16220,7 +14830,8 @@
16220
14830
  };
16221
14831
  container.setDisabled = function (d) {
16222
14832
  disabled = !!d;
16223
- triggerWrapper.className = getTriggerClassName(disabled);
14833
+ triggerWrapper.classList.toggle("cursor-not-allowed", disabled);
14834
+ triggerWrapper.classList.toggle("opacity-60", disabled);
16224
14835
  triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
16225
14836
  if (disabled) popoverApi.hide();
16226
14837
  };
@@ -16236,7 +14847,7 @@
16236
14847
 
16237
14848
 
16238
14849
  // ============================================
16239
- // File 36/42: components/phone-input/phone-utils.js
14850
+ // File 33/37: components/phone-input/phone-utils.js
16240
14851
  // ============================================
16241
14852
 
16242
14853
  /**
@@ -16399,7 +15010,7 @@
16399
15010
 
16400
15011
 
16401
15012
  // ============================================
16402
- // File 37/42: components/phone-input/phone-input.js
15013
+ // File 34/37: components/phone-input/phone-input.js
16403
15014
  // ============================================
16404
15015
 
16405
15016
  /**
@@ -16797,7 +15408,7 @@
16797
15408
 
16798
15409
 
16799
15410
  // ============================================
16800
- // File 38/42: components/file-input.js
15411
+ // File 35/37: components/file-input.js
16801
15412
  // ============================================
16802
15413
 
16803
15414
  /**
@@ -16841,15 +15452,6 @@
16841
15452
  return ICONS.file;
16842
15453
  }
16843
15454
 
16844
- /** Resolve client: use FlowUI._getComponent when bundle has captured globals, else global.superleapClient (same as enum-select) */
16845
- function getClient() {
16846
- if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
16847
- var c = global.FlowUI._getComponent("superleapClient");
16848
- if (c) return c;
16849
- }
16850
- return global.superleapClient;
16851
- }
16852
-
16853
15455
  /**
16854
15456
  * Upload file to S3
16855
15457
  * @param {File} file - File to upload
@@ -16861,31 +15463,26 @@
16861
15463
  formData.append("file", file, file.name);
16862
15464
  formData.append("is_private", String(!!isPrivate));
16863
15465
 
16864
- // Get upload path - can be configured via global.S3_UPLOAD_URL
15466
+ // Get upload URL - can be configured via global.S3_UPLOAD_URL
16865
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}`;
16866
15470
 
16867
- // Base URL and API key from superleapClient only (same pattern as enum-select)
16868
- var client = getClient();
16869
- var baseUrl = null;
16870
- var apiKey = null;
15471
+ // Get API key: use FlowUI._getComponent when globals were captured (index.js), else global.superleapClient
15472
+ let apiKey = null;
16871
15473
  try {
16872
- if (client && typeof client.getBaseUrl === "function") {
16873
- baseUrl = client.getBaseUrl();
16874
- }
15474
+ const client =
15475
+ global.FlowUI && typeof global.FlowUI._getComponent === "function"
15476
+ ? global.FlowUI._getComponent("superleapClient")
15477
+ : global.superleapClient;
16875
15478
  if (client && typeof client.getSdk === "function") {
16876
- var sdk = client.getSdk();
16877
- apiKey = sdk ? sdk.apiKey : null;
15479
+ const sdk = client.getSdk();
15480
+ apiKey = sdk?.apiKey;
16878
15481
  }
16879
15482
  } catch (e) {
16880
- console.warn("[S3FileUpload] Could not get client:", e);
16881
- }
16882
-
16883
- if (!baseUrl) {
16884
- throw new Error("SuperLeap client not initialized. Call superleapClient.init({ baseUrl, apiKey }) first.");
15483
+ console.warn("[S3FileUpload] Could not get API key:", e);
16885
15484
  }
16886
15485
 
16887
- const fullUrl = uploadUrl.startsWith("http") ? uploadUrl : baseUrl.replace(/\/$/, "") + (uploadUrl.startsWith("/") ? uploadUrl : "/" + uploadUrl);
16888
-
16889
15486
  const headers = {};
16890
15487
  if (apiKey) {
16891
15488
  headers.Authorization = `Bearer ${apiKey}`;
@@ -16929,36 +15526,8 @@
16929
15526
  * @param {boolean} config.isPrivate - Whether files should be private
16930
15527
  * @param {number} config.maxFiles - Maximum number of files (for multiple mode)
16931
15528
  * @param {number} config.maxFileSize - Maximum file size in bytes
16932
- * @param {boolean} [config.disabled] - Whether the file upload is disabled
16933
- * @param {string} [config.variant] - 'default' | 'error' | 'warning' | 'success' | 'borderless' | 'inline'
16934
- * @param {string} [config.inputSize] - 'default' | 'large' | 'small'
16935
- * @param {string} [config.className] - Extra class on upload wrapper
16936
15529
  * @returns {HTMLElement} Field element
16937
15530
  */
16938
- var UPLOAD_WRAPPER_CLASS = {
16939
- base:
16940
- "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",
16941
- default:
16942
- "border-border-primary bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
16943
- error:
16944
- "border-error-base bg-fill-quarternary-fill-white hover:border-error-base focus-within:border-error-base",
16945
- warning:
16946
- "border-warning-base bg-fill-quarternary-fill-white hover:border-warning-base focus-within:border-warning-base",
16947
- success:
16948
- "border-success-base bg-fill-quarternary-fill-white hover:border-success-base focus-within:border-success-base",
16949
- borderless:
16950
- "border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
16951
- inline:
16952
- "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",
16953
- sizeDefault: "px-12 py-4",
16954
- sizeLarge: "px-12 py-6",
16955
- sizeSmall: "px-12 py-2",
16956
- };
16957
-
16958
- function joinClasses() {
16959
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
16960
- }
16961
-
16962
15531
  function create(config) {
16963
15532
  const {
16964
15533
  label,
@@ -16970,14 +15539,7 @@
16970
15539
  isPrivate = false,
16971
15540
  maxFiles = null,
16972
15541
  maxFileSize = 10 * 1024 * 1024, // 10MB default
16973
- disabled = false,
16974
- variant = "default",
16975
- inputSize = "default",
16976
- className = "",
16977
15542
  } = config;
16978
- let disabledState = !!disabled;
16979
- let currentVariant = variant;
16980
- let currentInputSize = inputSize;
16981
15543
 
16982
15544
  if (!global.FlowUI) {
16983
15545
  throw new Error("FlowUI not available");
@@ -16995,33 +15557,12 @@
16995
15557
 
16996
15558
  // Upload row: button + status + optional end spinner (match Select/MultiSelect trigger)
16997
15559
  const uploadWrapper = document.createElement("div");
16998
- var sizeClass =
16999
- currentInputSize === "large"
17000
- ? UPLOAD_WRAPPER_CLASS.sizeLarge
17001
- : currentInputSize === "small"
17002
- ? UPLOAD_WRAPPER_CLASS.sizeSmall
17003
- : UPLOAD_WRAPPER_CLASS.sizeDefault;
17004
- function applyWrapperClasses() {
17005
- uploadWrapper.className = joinClasses(
17006
- UPLOAD_WRAPPER_CLASS.base,
17007
- UPLOAD_WRAPPER_CLASS[currentVariant] || UPLOAD_WRAPPER_CLASS.default,
17008
- sizeClass,
17009
- className
17010
- );
17011
- }
17012
- applyWrapperClasses();
17013
- uploadWrapper.setAttribute("data-file-input-variant", currentVariant);
17014
- uploadWrapper.setAttribute("data-file-input-size", currentInputSize);
17015
- 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";
17016
15561
 
17017
15562
  // Left content (button + status) – pointer-events-none so overlay input receives clicks
17018
15563
  const leftContent = document.createElement("div");
17019
15564
  leftContent.className = "pointer-events-none flex min-w-0 flex-1 items-center gap-8 truncate";
17020
15565
 
17021
- var disabledChildClasses =
17022
- "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";
17023
- var statusTextBaseClass = "text-reg-13 min-w-0 flex-1 truncate";
17024
- var statusTextDisabledClass = " group-has-[:disabled]:text-typography-quaternary-text";
17025
15566
  const useButtonComponent = global.Button && typeof global.Button.create === "function";
17026
15567
  const initialButtonText = multiple ? "Choose files" : "Choose a file";
17027
15568
  const btn = useButtonComponent
@@ -17029,41 +15570,31 @@
17029
15570
  variant: "outline",
17030
15571
  size: "small",
17031
15572
  text: initialButtonText,
17032
- className: "shrink-0 truncate " + disabledChildClasses,
15573
+ className: "shrink-0 truncate",
17033
15574
  })
17034
15575
  : (function () {
17035
15576
  const el = document.createElement("div");
17036
- el.className =
17037
- "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 " +
17038
- 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";
17039
15578
  el.textContent = initialButtonText;
17040
15579
  return el;
17041
15580
  })();
17042
15581
 
17043
15582
  // Status text: "No files chosen" (quaternary) or "X file(s) selected"
17044
15583
  const statusText = document.createElement("p");
17045
- statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
15584
+ statusText.className = "text-reg-13 min-w-0 flex-1 truncate text-typography-quaternary-text";
17046
15585
 
17047
15586
  // Hidden file input – overlays row, high z-index so it receives clicks
17048
15587
  const input = document.createElement("input");
17049
15588
  input.type = "file";
17050
- const inputBaseClass = "absolute inset-0 z-10 w-full opacity-0";
17051
- function applyInputClasses() {
17052
- input.className =
17053
- inputBaseClass +
17054
- (disabledState ? " !pointer-events-none !cursor-not-allowed" : " cursor-pointer");
17055
- }
17056
- applyInputClasses();
15589
+ input.className = "absolute inset-0 z-10 w-full cursor-pointer opacity-0";
17057
15590
  input.multiple = multiple;
17058
- input.disabled = disabledState;
17059
15591
  if (accept !== "*") {
17060
15592
  input.accept = accept;
17061
15593
  }
17062
15594
 
17063
15595
  // End icon slot: spinner when uploading (match Select chevron position)
17064
15596
  const endIconSlot = document.createElement("div");
17065
- endIconSlot.className =
17066
- "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";
17067
15598
  endIconSlot.style.display = "none";
17068
15599
 
17069
15600
  // Uploaded files: badge list (match UploadedFilePreviewer – flex-wrap gap-2)
@@ -17244,13 +15775,13 @@
17244
15775
 
17245
15776
  if (!filesChosen) {
17246
15777
  statusText.textContent = "No files chosen";
17247
- statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
15778
+ statusText.className = "text-reg-13 min-w-0 flex-1 truncate text-typography-quaternary-text";
17248
15779
  } else if (uploadingCount > 0) {
17249
15780
  statusText.textContent = "Uploading…";
17250
- statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
15781
+ statusText.className = "text-reg-13 min-w-0 flex-1 truncate text-typography-quaternary-text";
17251
15782
  } else {
17252
15783
  statusText.textContent = `${uploadedCount} file${uploadedCount !== 1 ? "s" : ""} selected`;
17253
- statusText.className = statusTextBaseClass + " text-typography-primary-text" + statusTextDisabledClass;
15784
+ statusText.className = "text-reg-13 min-w-0 flex-1 truncate text-typography-primary-text";
17254
15785
  }
17255
15786
 
17256
15787
  endIconSlot.style.display = uploadingCount > 0 ? "flex" : "none";
@@ -17387,32 +15918,6 @@
17387
15918
  loadExistingFiles();
17388
15919
  updateStatus();
17389
15920
 
17390
- field.setDisabled = function (d) {
17391
- disabledState = !!d;
17392
- input.disabled = disabledState;
17393
- applyInputClasses();
17394
- applyWrapperClasses();
17395
- uploadWrapper.setAttribute("data-disabled", disabledState ? "true" : "false");
17396
- };
17397
-
17398
- field.setVariant = function (v) {
17399
- currentVariant = v || "default";
17400
- uploadWrapper.setAttribute("data-file-input-variant", currentVariant);
17401
- applyWrapperClasses();
17402
- };
17403
-
17404
- field.setInputSize = function (s) {
17405
- currentInputSize = s || "default";
17406
- sizeClass =
17407
- currentInputSize === "large"
17408
- ? UPLOAD_WRAPPER_CLASS.sizeLarge
17409
- : currentInputSize === "small"
17410
- ? UPLOAD_WRAPPER_CLASS.sizeSmall
17411
- : UPLOAD_WRAPPER_CLASS.sizeDefault;
17412
- uploadWrapper.setAttribute("data-file-input-size", currentInputSize);
17413
- applyWrapperClasses();
17414
- };
17415
-
17416
15921
  return field;
17417
15922
  }
17418
15923
 
@@ -17427,7 +15932,7 @@
17427
15932
 
17428
15933
 
17429
15934
  // ============================================
17430
- // File 39/42: components/table.js
15935
+ // File 36/37: components/table.js
17431
15936
  // ============================================
17432
15937
 
17433
15938
  /**
@@ -17768,455 +16273,7 @@
17768
16273
 
17769
16274
 
17770
16275
  // ============================================
17771
- // File 40/42: components/tabs.js
17772
- // ============================================
17773
-
17774
- /**
17775
- * Tabs Component (vanilla JS)
17776
- * Tabbed interface with list, triggers, and content panels.
17777
- * Ref: Radix-style Tabs; design tokens match design system.
17778
- */
17779
-
17780
- (function (global) {
17781
-
17782
- function getComponent(name) {
17783
- if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
17784
- var c = global.FlowUI._getComponent(name);
17785
- if (c) return c;
17786
- }
17787
- return global[name];
17788
- }
17789
-
17790
- var LIST_BASE_CLASS =
17791
- "inline-flex items-center justify-center gap-2 rounded-4 bg-fill-tertiary-fill-light-gray p-4";
17792
-
17793
- /** Button variant classes for active (outline) vs inactive (ghost) */
17794
- var BUTTON_OUTLINE =
17795
- "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";
17796
- var BUTTON_GHOST =
17797
- "group text-typography-primary-text hover:bg-fill-tertiary-fill-light-gray active:bg-fill-secondary-fill-gray disabled:text-typography-quaternary-text";
17798
- var BUTTON_BASE =
17799
- "inline-flex items-center justify-center whitespace-nowrap !text-med-12 transition-colors disabled:pointer-events-none hover:cursor-pointer h-fit";
17800
- var BUTTON_SIZES = {
17801
- default: "px-8 py-4 gap-4 rounded-4",
17802
- small: "px-8 py-4 gap-4 rounded-4",
17803
- large: "px-16 py-8 gap-4 rounded-4",
17804
- };
17805
-
17806
- var CONTENT_BASE_CLASS =
17807
- "ring-offset-background focus-visible:ring-ring h-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2";
17808
-
17809
- function join() {
17810
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
17811
- }
17812
-
17813
- /**
17814
- * Create a full Tabs component (list + triggers + content panels)
17815
- * @param {Object} config
17816
- * @param {string} [config.defaultValue] - initial active tab value
17817
- * @param {string} [config.value] - controlled active value
17818
- * @param {Function} [config.onChange] - (value) => void when tab changes
17819
- * @param {Array<{value: string, label: string, content: HTMLElement|string}>} config.tabs - tab definitions
17820
- * @param {string} [config.size] - 'default' | 'small' | 'large'
17821
- * @param {string} [config.listClassName] - extra class on list
17822
- * @param {string} [config.contentClassName] - extra class on content wrapper
17823
- * @returns {HTMLElement} root element (wrapper containing list + content area)
17824
- */
17825
- function create(config) {
17826
- var opts = config || {};
17827
- var defaultValue = opts.defaultValue;
17828
- var controlledValue = opts.value;
17829
- var onChange = opts.onChange;
17830
- var tabs = opts.tabs || [];
17831
- var size = opts.size || "default";
17832
- var listClassName = opts.listClassName || "";
17833
- var contentClassName = opts.contentClassName || "";
17834
-
17835
- var sizeClass = BUTTON_SIZES[size] || BUTTON_SIZES.default;
17836
-
17837
- var root = document.createElement("div");
17838
- root.className = "tabs-root w-full";
17839
-
17840
- var activeValue = controlledValue !== undefined ? controlledValue : defaultValue !== undefined ? defaultValue : (tabs[0] && tabs[0].value) || "";
17841
-
17842
- // List container
17843
- var list = document.createElement("div");
17844
- list.setAttribute("role", "tablist");
17845
- list.className = join(LIST_BASE_CLASS, listClassName);
17846
-
17847
- // Content container (holds all panels; we show/hide by value)
17848
- var contentWrapper = document.createElement("div");
17849
- contentWrapper.className = join("tabs-content-wrapper mt-4", contentClassName);
17850
-
17851
- var triggerEls = [];
17852
- var contentPanels = [];
17853
-
17854
- var Button = getComponent("Button");
17855
-
17856
- tabs.forEach(function (tab, index) {
17857
- var value = tab.value;
17858
- var label = tab.label != null ? tab.label : value;
17859
- var content = tab.content;
17860
-
17861
- var isActive = value === activeValue;
17862
- var trigger = Button.create({
17863
- variant: isActive ? "outline" : "ghost",
17864
- size: size === "small" ? "small" : size === "large" ? "large" : "default",
17865
- text: label,
17866
- type: "button",
17867
- className: "mx-2",
17868
- onClick: function () {
17869
- if (activeValue === value) return;
17870
- if (controlledValue === undefined) {
17871
- activeValue = value;
17872
- updateActiveState();
17873
- }
17874
- if (typeof onChange === "function") {
17875
- onChange(value);
17876
- }
17877
- },
17878
- });
17879
-
17880
- trigger.setAttribute("role", "tab");
17881
- trigger.setAttribute("aria-selected", value === activeValue ? "true" : "false");
17882
- trigger.setAttribute("data-state", value === activeValue ? "active" : "inactive");
17883
- trigger.setAttribute("data-value", value);
17884
- trigger.tabIndex = value === activeValue ? 0 : -1;
17885
-
17886
- trigger.addEventListener("keydown", function (e) {
17887
- if (e.key === "Enter" || e.key === " ") {
17888
- e.preventDefault();
17889
- trigger.click();
17890
- }
17891
- if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
17892
- e.preventDefault();
17893
- var nextIndex = e.key === "ArrowRight" ? index + 1 : index - 1;
17894
- if (nextIndex >= 0 && nextIndex < tabs.length) {
17895
- var nextTrigger = triggerEls[nextIndex];
17896
- if (nextTrigger) {
17897
- nextTrigger.focus();
17898
- nextTrigger.click();
17899
- }
17900
- }
17901
- }
17902
- });
17903
-
17904
- list.appendChild(trigger);
17905
- triggerEls.push(trigger);
17906
-
17907
- var panel = document.createElement("div");
17908
- panel.setAttribute("role", "tabpanel");
17909
- panel.setAttribute("aria-hidden", value !== activeValue ? "true" : "false");
17910
- panel.setAttribute("data-value", value);
17911
- panel.className = join(CONTENT_BASE_CLASS, value !== activeValue ? "hidden" : "");
17912
- if (typeof content === "string") {
17913
- panel.innerHTML = content;
17914
- } else if (content && content.nodeType === 1) {
17915
- panel.appendChild(content);
17916
- }
17917
- contentWrapper.appendChild(panel);
17918
- contentPanels.push(panel);
17919
- });
17920
-
17921
- function updateActiveState() {
17922
- triggerEls.forEach(function (t, i) {
17923
- var val = tabs[i] && tabs[i].value;
17924
- var isActive = val === activeValue;
17925
- t.setAttribute("aria-selected", isActive ? "true" : "false");
17926
- t.setAttribute("data-state", isActive ? "active" : "inactive");
17927
- t.tabIndex = isActive ? 0 : -1;
17928
- t.className = join(BUTTON_BASE, isActive ? BUTTON_OUTLINE : BUTTON_GHOST, sizeClass, "mx-2");
17929
- });
17930
- contentPanels.forEach(function (p, i) {
17931
- var val = tabs[i] && tabs[i].value;
17932
- var isActive = val === activeValue;
17933
- p.setAttribute("aria-hidden", isActive ? "false" : "true");
17934
- p.classList.toggle("hidden", !isActive);
17935
- });
17936
- }
17937
-
17938
- root.appendChild(list);
17939
- root.appendChild(contentWrapper);
17940
-
17941
- root.getValue = function () {
17942
- return activeValue;
17943
- };
17944
-
17945
- root.setValue = function (newValue) {
17946
- if (newValue === activeValue) return;
17947
- activeValue = newValue;
17948
- updateActiveState();
17949
- };
17950
-
17951
- return root;
17952
- }
17953
-
17954
- var Tabs = {
17955
- create: create,
17956
- };
17957
-
17958
- if (typeof module !== "undefined" && module.exports) {
17959
- module.exports = Tabs;
17960
- } else {
17961
- global.Tabs = Tabs;
17962
- }
17963
- })(typeof window !== "undefined" ? window : undefined);
17964
-
17965
-
17966
-
17967
- // ============================================
17968
- // File 41/42: components/steps.js
17969
- // ============================================
17970
-
17971
- /**
17972
- * Steps Component (vanilla JS)
17973
- * Multi-step flow with numbered step triggers and optional content panels.
17974
- * Use for wizards / step-by-step forms (e.g. "1 Step One", "2 Step Two").
17975
- */
17976
-
17977
- (function (global) {
17978
-
17979
- function getComponent(name) {
17980
- if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
17981
- var c = global.FlowUI._getComponent(name);
17982
- if (c) return c;
17983
- }
17984
- return global[name];
17985
- }
17986
-
17987
- var LIST_BASE_CLASS =
17988
- "flex items-center flex-wrap gap-0 rounded-4 border border-border-primary bg-fill-quarternary-fill-white p-4";
17989
-
17990
- /** Inactive step: muted label color only (button stays ghost large) */
17991
- var INACTIVE_LABEL_CLASS = "!text-typography-quaternary-text";
17992
-
17993
- /** Box around step number: active = dark fill + invert text, inactive = dark gray fill + tertiary text */
17994
- var NUMBER_BOX_ACTIVE =
17995
- "flex h-16 w-16 items-center justify-center rounded-4 bg-typography-primary-text text-typography-invert-text shrink-0";
17996
- var NUMBER_BOX_INACTIVE =
17997
- "flex h-16 w-16 items-center justify-center rounded-4 bg-fill-primary-fill-dark-gray text-typography-tertiary-text shrink-0";
17998
-
17999
- /** Horizontal line between steps (step1 ——— step2) */
18000
- var CONNECTOR_CLASS = "flex-1 min-w-12 max-w-32 h-0 border-t border-border-primary shrink-0 mx-2 self-center";
18001
-
18002
- var CONTENT_BASE_CLASS =
18003
- "ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2 h-full";
18004
-
18005
- function join() {
18006
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
18007
- }
18008
-
18009
- /**
18010
- * Create a Steps component (numbered step triggers + optional content)
18011
- * Design: ghost large Button for all steps; inactive steps use muted label color. Connectors between steps. Optional title/description above.
18012
- * @param {Object} config
18013
- * @param {Array<{id: string, label: string, content?: HTMLElement|string}>} config.steps - step definitions
18014
- * @param {string} [config.defaultValue] - initial active step id
18015
- * @param {string} [config.value] - controlled active step id
18016
- * @param {Function} [config.onChange] - (stepId) => void when step changes
18017
- * @param {string} [config.title] - optional title above steps
18018
- * @param {string} [config.description] - optional description above steps
18019
- * @param {string} [config.listClassName] - extra class on step list
18020
- * @param {string} [config.contentClassName] - extra class on content wrapper
18021
- * @param {boolean} [config.showContent=true] - whether to render content panels (if steps have content)
18022
- * @returns {HTMLElement} root element
18023
- */
18024
- function create(config) {
18025
- var opts = config || {};
18026
- var steps = opts.steps || [];
18027
- var defaultValue = opts.defaultValue;
18028
- var controlledValue = opts.value;
18029
- var onChange = opts.onChange;
18030
- var title = opts.title;
18031
- var description = opts.description;
18032
- var listClassName = opts.listClassName || "";
18033
- var contentClassName = opts.contentClassName || "";
18034
- var showContent = opts.showContent !== false;
18035
-
18036
- var root = document.createElement("div");
18037
- root.className = "steps-root w-full";
18038
-
18039
- var activeId =
18040
- controlledValue !== undefined
18041
- ? controlledValue
18042
- : defaultValue !== undefined
18043
- ? defaultValue
18044
- : (steps[0] && steps[0].id) || "";
18045
-
18046
- if (title != null && title !== "") {
18047
- var titleEl = document.createElement("h3");
18048
- titleEl.className = "text-typography-primary-text";
18049
- titleEl.textContent = title;
18050
- root.appendChild(titleEl);
18051
- }
18052
- if (description != null && description !== "") {
18053
- var descEl = document.createElement("p");
18054
- descEl.className = "text-typography-secondary-text";
18055
- descEl.textContent = description;
18056
- root.appendChild(descEl);
18057
- }
18058
-
18059
- // Step list (horizontal: step, connector, step, connector, ...)
18060
- var list = document.createElement("div");
18061
- list.setAttribute("role", "tablist");
18062
- list.setAttribute("aria-label", "Steps");
18063
- list.className = join(LIST_BASE_CLASS, listClassName);
18064
-
18065
- var triggerEls = [];
18066
- var numberBoxEls = [];
18067
- var contentPanels = [];
18068
- var contentWrapper = null;
18069
-
18070
- if (showContent && steps.some(function (s) { return s.content != null; })) {
18071
- contentWrapper = document.createElement("div");
18072
- contentWrapper.className = join("steps-content-wrapper mt-4", contentClassName);
18073
- }
18074
-
18075
- var Button = getComponent("Button");
18076
-
18077
- steps.forEach(function (step, index) {
18078
- var stepId = step.id;
18079
- var label = step.label != null ? step.label : stepId;
18080
- var content = step.content;
18081
- var stepNumber = index + 1;
18082
- var isActive = stepId === activeId;
18083
-
18084
- var trigger = Button.create({
18085
- variant: "ghost",
18086
- size: "large",
18087
- text: "\u00A0",
18088
- type: "button",
18089
- className: isActive ? "" : INACTIVE_LABEL_CLASS,
18090
- onClick: function () {
18091
- if (activeId === stepId) return;
18092
- if (controlledValue === undefined) {
18093
- activeId = stepId;
18094
- updateActiveState();
18095
- }
18096
- if (typeof onChange === "function") {
18097
- onChange(stepId);
18098
- }
18099
- },
18100
- });
18101
-
18102
- var numberBox = document.createElement("span");
18103
- numberBox.setAttribute("aria-hidden", "true");
18104
- numberBox.className = isActive ? NUMBER_BOX_ACTIVE : NUMBER_BOX_INACTIVE;
18105
- numberBox.textContent = String(stepNumber);
18106
-
18107
- trigger.innerHTML = "";
18108
- trigger.appendChild(numberBox);
18109
- trigger.appendChild(document.createTextNode(" " + label));
18110
-
18111
- trigger.setAttribute("role", "tab");
18112
- trigger.setAttribute("aria-selected", isActive ? "true" : "false");
18113
- trigger.setAttribute("data-state", isActive ? "active" : "inactive");
18114
- trigger.setAttribute("data-step-id", stepId);
18115
- trigger.tabIndex = isActive ? 0 : -1;
18116
-
18117
- numberBoxEls.push(numberBox);
18118
-
18119
- trigger.addEventListener("keydown", function (e) {
18120
- if (e.key === "Enter" || e.key === " ") {
18121
- e.preventDefault();
18122
- trigger.click();
18123
- }
18124
- if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
18125
- e.preventDefault();
18126
- var nextIndex = e.key === "ArrowRight" ? index + 1 : index - 1;
18127
- if (nextIndex >= 0 && nextIndex < steps.length) {
18128
- var nextTrigger = triggerEls[nextIndex];
18129
- if (nextTrigger) {
18130
- nextTrigger.focus();
18131
- nextTrigger.click();
18132
- }
18133
- }
18134
- }
18135
- });
18136
-
18137
- list.appendChild(trigger);
18138
- triggerEls.push(trigger);
18139
-
18140
- if (index < steps.length - 1) {
18141
- var connector = document.createElement("span");
18142
- connector.className = CONNECTOR_CLASS;
18143
- connector.setAttribute("aria-hidden", "true");
18144
- list.appendChild(connector);
18145
- }
18146
-
18147
- if (contentWrapper && content != null) {
18148
- var panel = document.createElement("div");
18149
- panel.setAttribute("role", "tabpanel");
18150
- panel.setAttribute("aria-hidden", stepId !== activeId ? "true" : "false");
18151
- panel.setAttribute("data-step-id", stepId);
18152
- panel.className = join(CONTENT_BASE_CLASS, stepId !== activeId ? "hidden" : "");
18153
- if (typeof content === "string") {
18154
- panel.innerHTML = content;
18155
- } else if (content && content.nodeType === 1) {
18156
- panel.appendChild(content);
18157
- }
18158
- contentWrapper.appendChild(panel);
18159
- contentPanels.push(panel);
18160
- }
18161
- });
18162
-
18163
- function updateActiveState() {
18164
- triggerEls.forEach(function (t, i) {
18165
- var step = steps[i];
18166
- var id = step && step.id;
18167
- var isActive = id === activeId;
18168
- t.setAttribute("aria-selected", isActive ? "true" : "false");
18169
- t.setAttribute("data-state", isActive ? "active" : "inactive");
18170
- t.tabIndex = isActive ? 0 : -1;
18171
- if (isActive) {
18172
- t.classList.remove(INACTIVE_LABEL_CLASS);
18173
- } else {
18174
- t.classList.add(INACTIVE_LABEL_CLASS);
18175
- }
18176
- numberBoxEls[i].className = isActive ? NUMBER_BOX_ACTIVE : NUMBER_BOX_INACTIVE;
18177
- });
18178
- contentPanels.forEach(function (p, i) {
18179
- var step = steps[i];
18180
- var id = step && step.id;
18181
- var isActive = id === activeId;
18182
- p.setAttribute("aria-hidden", isActive ? "false" : "true");
18183
- p.classList.toggle("hidden", !isActive);
18184
- });
18185
- }
18186
-
18187
- root.appendChild(list);
18188
- if (contentWrapper) {
18189
- root.appendChild(contentWrapper);
18190
- }
18191
-
18192
- root.getValue = function () {
18193
- return activeId;
18194
- };
18195
-
18196
- root.setValue = function (newId) {
18197
- if (newId === activeId) return;
18198
- activeId = newId;
18199
- updateActiveState();
18200
- };
18201
-
18202
- return root;
18203
- }
18204
-
18205
- var Steps = {
18206
- create: create,
18207
- };
18208
-
18209
- if (typeof module !== "undefined" && module.exports) {
18210
- module.exports = Steps;
18211
- } else {
18212
- global.Steps = Steps;
18213
- }
18214
- })(typeof window !== "undefined" ? window : undefined);
18215
-
18216
-
18217
-
18218
- // ============================================
18219
- // File 42/42: index.js
16276
+ // File 37/37: index.js
18220
16277
  // ============================================
18221
16278
 
18222
16279
  /**
@@ -18292,7 +16349,6 @@
18292
16349
  require("./components/input.js");
18293
16350
  require("./components/currency.js");
18294
16351
  require("./components/textarea.js");
18295
- require("./components/richtext-editor.js");
18296
16352
  require("./components/duration/duration-utils.js");
18297
16353
  require("./components/duration/duration-constants.js");
18298
16354
  require("./components/duration/duration.js");
@@ -18308,12 +16364,8 @@
18308
16364
  require("./components/phone-input/phone-utils.js");
18309
16365
  require("./components/phone-input/phone-input.js");
18310
16366
  require("./components/checkbox.js");
18311
- require("./components/checkbox-group.js");
18312
16367
  require("./components/radio-group.js");
18313
- require("./components/card-select.js");
18314
16368
  require("./components/table.js");
18315
- require("./components/tabs.js");
18316
- require("./components/steps.js");
18317
16369
 
18318
16370
  // Export FlowUI and SuperLeap from global scope
18319
16371
  if (typeof global !== "undefined" && global.FlowUI) {
@@ -18324,7 +16376,6 @@
18324
16376
  getSdk: global.superleapClient.getSdk,
18325
16377
  isAvailable: global.superleapClient.isAvailable,
18326
16378
  getDefaultConfig: global.superleapClient.getDefaultConfig,
18327
- getBaseUrl: global.superleapClient.getBaseUrl,
18328
16379
  }
18329
16380
  : null;
18330
16381
 
@@ -18340,7 +16391,6 @@
18340
16391
  getSdk: window.superleapClient.getSdk,
18341
16392
  isAvailable: window.superleapClient.isAvailable,
18342
16393
  getDefaultConfig: window.superleapClient.getDefaultConfig,
18343
- getBaseUrl: window.superleapClient.getBaseUrl,
18344
16394
  }
18345
16395
  : null;
18346
16396
 
@@ -18376,7 +16426,6 @@
18376
16426
  "InputComponent",
18377
16427
  "CurrencyComponent",
18378
16428
  "TextareaComponent",
18379
- "RichTextEditorComponent",
18380
16429
  "Duration",
18381
16430
  "DateTimePicker",
18382
16431
  "Enumeration",
@@ -18388,12 +16437,8 @@
18388
16437
  "FileInput",
18389
16438
  "PhoneInput",
18390
16439
  "Checkbox",
18391
- "CheckboxGroup",
18392
16440
  "RadioGroup",
18393
- "CardSelect",
18394
16441
  "SuperleapTable",
18395
- "Tabs",
18396
- "Steps",
18397
16442
  ];
18398
16443
 
18399
16444
  componentNames.forEach((name) => {
@@ -18423,7 +16468,6 @@
18423
16468
  getSdk: client.getSdk.bind(client),
18424
16469
  isAvailable: client.isAvailable.bind(client),
18425
16470
  getDefaultConfig: client.getDefaultConfig.bind(client),
18426
- getBaseUrl: client.getBaseUrl.bind(client),
18427
16471
  // Bridge methods (from crm.js)
18428
16472
  connect: client.connect ? client.connect.bind(client) : undefined,
18429
16473
  isConnected: client.isConnected
@@ -18482,7 +16526,7 @@
18482
16526
  },
18483
16527
  });
18484
16528
  document.dispatchEvent(event);
18485
- console.log("[Superleap-Flow] Library ready - v2.5.3");
16529
+ console.log("[Superleap-Flow] Library ready - v2.3.4");
18486
16530
  }
18487
16531
 
18488
16532
  // Wait for DOM to be ready before dispatching event