@superleapai/flow-ui 2.5.1 → 2.5.2
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.
- package/dist/superleap-flow.js +2244 -953
- package/dist/superleap-flow.js.map +1 -1
- package/dist/superleap-flow.min.js +2 -2
- package/package.json +1 -1
package/dist/superleap-flow.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @superleapai/flow-ui v2.
|
|
2
|
+
* @superleapai/flow-ui v2.5.1
|
|
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-
|
|
9
|
+
* Date: 2026-02-25T15:52:26.090Z
|
|
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/
|
|
18
|
+
// File 1/41: 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/
|
|
2645
|
+
// File 2/41: core/superleapClient.js
|
|
2646
2646
|
// ============================================
|
|
2647
2647
|
|
|
2648
2648
|
/**
|
|
@@ -2783,11 +2783,23 @@
|
|
|
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
|
+
|
|
2786
2797
|
var superleapClient = {
|
|
2787
2798
|
init: init,
|
|
2788
2799
|
getSdk: getSdk,
|
|
2789
2800
|
isAvailable: isAvailable,
|
|
2790
2801
|
getDefaultConfig: getDefaultConfig,
|
|
2802
|
+
getBaseUrl: getBaseUrl,
|
|
2791
2803
|
};
|
|
2792
2804
|
|
|
2793
2805
|
if (global) {
|
|
@@ -2798,7 +2810,7 @@
|
|
|
2798
2810
|
|
|
2799
2811
|
|
|
2800
2812
|
// ============================================
|
|
2801
|
-
// File 3/
|
|
2813
|
+
// File 3/41: core/bridge.js
|
|
2802
2814
|
// ============================================
|
|
2803
2815
|
|
|
2804
2816
|
/**
|
|
@@ -3326,7 +3338,7 @@
|
|
|
3326
3338
|
|
|
3327
3339
|
|
|
3328
3340
|
// ============================================
|
|
3329
|
-
// File 4/
|
|
3341
|
+
// File 4/41: core/crm.js
|
|
3330
3342
|
// ============================================
|
|
3331
3343
|
|
|
3332
3344
|
/**
|
|
@@ -3567,12 +3579,13 @@
|
|
|
3567
3579
|
|
|
3568
3580
|
/**
|
|
3569
3581
|
* Tell the CRM to navigate to a path.
|
|
3570
|
-
* @param {string}
|
|
3582
|
+
* @param {string} url
|
|
3583
|
+
* @param {boolean} [newTab=false]
|
|
3571
3584
|
*/
|
|
3572
|
-
function navigate(
|
|
3585
|
+
function navigate(url, newTab) {
|
|
3573
3586
|
var bridge = getBridge();
|
|
3574
3587
|
if (bridge && bridge.isConnected()) {
|
|
3575
|
-
bridge.send("crm:navigate", {
|
|
3588
|
+
bridge.send("crm:navigate", { url: url, new_tab: !!newTab });
|
|
3576
3589
|
}
|
|
3577
3590
|
}
|
|
3578
3591
|
|
|
@@ -3668,7 +3681,7 @@
|
|
|
3668
3681
|
|
|
3669
3682
|
|
|
3670
3683
|
// ============================================
|
|
3671
|
-
// File 5/
|
|
3684
|
+
// File 5/41: components/label.js
|
|
3672
3685
|
// ============================================
|
|
3673
3686
|
|
|
3674
3687
|
/**
|
|
@@ -3785,7 +3798,7 @@
|
|
|
3785
3798
|
|
|
3786
3799
|
|
|
3787
3800
|
// ============================================
|
|
3788
|
-
// File 6/
|
|
3801
|
+
// File 6/41: core/flow.js
|
|
3789
3802
|
// ============================================
|
|
3790
3803
|
|
|
3791
3804
|
/**
|
|
@@ -4037,6 +4050,48 @@
|
|
|
4037
4050
|
return field;
|
|
4038
4051
|
}
|
|
4039
4052
|
|
|
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
|
+
|
|
4040
4095
|
/**
|
|
4041
4096
|
* Create a select dropdown field (using custom select component)
|
|
4042
4097
|
* @param {Object} config - Configuration object
|
|
@@ -4447,6 +4502,7 @@
|
|
|
4447
4502
|
size,
|
|
4448
4503
|
canClear,
|
|
4449
4504
|
initialLimit,
|
|
4505
|
+
initialFilter,
|
|
4450
4506
|
helpText = null,
|
|
4451
4507
|
} = config;
|
|
4452
4508
|
|
|
@@ -4466,6 +4522,7 @@
|
|
|
4466
4522
|
size: size || "default",
|
|
4467
4523
|
canClear: !!canClear,
|
|
4468
4524
|
initialLimit,
|
|
4525
|
+
initialFilter,
|
|
4469
4526
|
onChange: (value, record) => {
|
|
4470
4527
|
set(fieldId, value);
|
|
4471
4528
|
if (onChange) onChange(value, record);
|
|
@@ -4515,6 +4572,7 @@
|
|
|
4515
4572
|
variant,
|
|
4516
4573
|
size,
|
|
4517
4574
|
initialLimit,
|
|
4575
|
+
initialFilter,
|
|
4518
4576
|
displayFields,
|
|
4519
4577
|
helpText = null,
|
|
4520
4578
|
} = config;
|
|
@@ -4533,6 +4591,7 @@
|
|
|
4533
4591
|
variant: variant || "default",
|
|
4534
4592
|
size: size || "default",
|
|
4535
4593
|
initialLimit,
|
|
4594
|
+
initialFilter,
|
|
4536
4595
|
displayFields: displayFields || [],
|
|
4537
4596
|
onValuesChange: (values, records) => {
|
|
4538
4597
|
set(fieldId, values);
|
|
@@ -5090,6 +5149,40 @@
|
|
|
5090
5149
|
return field;
|
|
5091
5150
|
}
|
|
5092
5151
|
|
|
5152
|
+
/**
|
|
5153
|
+
* Create a checkbox group field (multiselect-like: options array, value array, onValuesChange)
|
|
5154
|
+
* @param {Object} config - { label, fieldId, options, required, helpText, variant, size, layout, disabled, onChange }
|
|
5155
|
+
* @returns {HTMLElement} Field wrapper containing checkbox group
|
|
5156
|
+
*/
|
|
5157
|
+
function createCheckboxGroup(config) {
|
|
5158
|
+
const { label, fieldId, options = [], required = false, helpText = null, variant, size, layout = "vertical", disabled = false, onChange } = config;
|
|
5159
|
+
|
|
5160
|
+
const field = createFieldWrapper(label, required, helpText);
|
|
5161
|
+
field.setAttribute("data-field-id", fieldId);
|
|
5162
|
+
|
|
5163
|
+
if (getComponent("CheckboxGroup") && getComponent("CheckboxGroup").create) {
|
|
5164
|
+
const currentValues = get(fieldId) || [];
|
|
5165
|
+
const groupEl = getComponent("CheckboxGroup").create({
|
|
5166
|
+
fieldId,
|
|
5167
|
+
options,
|
|
5168
|
+
value: currentValues,
|
|
5169
|
+
variant: variant || "default",
|
|
5170
|
+
size: size || "default",
|
|
5171
|
+
layout,
|
|
5172
|
+
disabled,
|
|
5173
|
+
onValuesChange: (values) => {
|
|
5174
|
+
set(fieldId, values);
|
|
5175
|
+
if (onChange) onChange(values);
|
|
5176
|
+
},
|
|
5177
|
+
});
|
|
5178
|
+
groupEl._fieldId = fieldId;
|
|
5179
|
+
field.appendChild(groupEl);
|
|
5180
|
+
return field;
|
|
5181
|
+
}
|
|
5182
|
+
|
|
5183
|
+
return field;
|
|
5184
|
+
}
|
|
5185
|
+
|
|
5093
5186
|
// ============================================================================
|
|
5094
5187
|
// STEPPER COMPONENT
|
|
5095
5188
|
// ============================================================================
|
|
@@ -5121,40 +5214,36 @@
|
|
|
5121
5214
|
});
|
|
5122
5215
|
}
|
|
5123
5216
|
|
|
5124
|
-
// ============================================================================
|
|
5125
|
-
// ALERT COMPONENT
|
|
5126
|
-
// ============================================================================
|
|
5127
|
-
|
|
5128
5217
|
/**
|
|
5129
|
-
*
|
|
5130
|
-
*
|
|
5131
|
-
* @
|
|
5132
|
-
* @param {Array} messages - Array of error/info messages (strings) or { title?, description } objects
|
|
5133
|
-
* @param {string} type - Alert type: "error" | "info" | "success" | "warning" | "destructive" | "default"
|
|
5218
|
+
* Create a Tabs component (list + triggers + content panels)
|
|
5219
|
+
* @param {Object} config - { defaultValue?, value?, onChange?, tabs: [{ value, label, content }], size?, variant?, listClassName?, contentClassName? }
|
|
5220
|
+
* @returns {HTMLElement} Tabs root element
|
|
5134
5221
|
*/
|
|
5135
|
-
function
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
const
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5222
|
+
function createTabs(config) {
|
|
5223
|
+
const Tabs = getComponent("Tabs");
|
|
5224
|
+
if (Tabs && typeof Tabs.create === "function") {
|
|
5225
|
+
return Tabs.create(config);
|
|
5226
|
+
}
|
|
5227
|
+
const fallback = document.createElement("div");
|
|
5228
|
+
fallback.className = "tabs-root";
|
|
5229
|
+
fallback.textContent = "Tabs component not loaded.";
|
|
5230
|
+
return fallback;
|
|
5231
|
+
}
|
|
5145
5232
|
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5233
|
+
/**
|
|
5234
|
+
* Create a Steps component (numbered step triggers + optional content panels)
|
|
5235
|
+
* @param {Object} config - { steps: [{ id, label, content? }], defaultValue?, value?, onChange?, size?, variant?, listClassName?, contentClassName?, showContent? }
|
|
5236
|
+
* @returns {HTMLElement} Steps root element
|
|
5237
|
+
*/
|
|
5238
|
+
function createSteps(config) {
|
|
5239
|
+
const Steps = getComponent("Steps");
|
|
5240
|
+
if (Steps && typeof Steps.create === "function") {
|
|
5241
|
+
return Steps.create(config);
|
|
5242
|
+
}
|
|
5243
|
+
const fallback = document.createElement("div");
|
|
5244
|
+
fallback.className = "steps-root";
|
|
5245
|
+
fallback.textContent = "Steps component not loaded.";
|
|
5246
|
+
return fallback;
|
|
5158
5247
|
}
|
|
5159
5248
|
|
|
5160
5249
|
// ============================================================================
|
|
@@ -5319,6 +5408,34 @@
|
|
|
5319
5408
|
return field;
|
|
5320
5409
|
}
|
|
5321
5410
|
|
|
5411
|
+
// ============================================================================
|
|
5412
|
+
// ALERTS
|
|
5413
|
+
// ============================================================================
|
|
5414
|
+
|
|
5415
|
+
/**
|
|
5416
|
+
* Render multiple alert messages into a container
|
|
5417
|
+
* @param {HTMLElement} container - Container to append alerts to
|
|
5418
|
+
* @param {string[]} messages - Array of message strings
|
|
5419
|
+
* @param {string} [variant='default'] - 'default' | 'error' | 'warning' | 'success' | 'info' | 'destructive'
|
|
5420
|
+
*/
|
|
5421
|
+
function renderAlerts(container, messages, variant = "default") {
|
|
5422
|
+
if (!container || !Array.isArray(messages)) return;
|
|
5423
|
+
const Alert = getComponent("Alert");
|
|
5424
|
+
if (Alert && typeof Alert.simple === "function") {
|
|
5425
|
+
messages.forEach((msg) => {
|
|
5426
|
+
const el = Alert.simple(msg, variant);
|
|
5427
|
+
if (el) container.appendChild(el);
|
|
5428
|
+
});
|
|
5429
|
+
} else {
|
|
5430
|
+
messages.forEach((msg) => {
|
|
5431
|
+
const div = document.createElement("div");
|
|
5432
|
+
div.className = "rounded border p-2 text-sm " + (variant === "error" ? "bg-red-50 border-red-200 text-red-800" : "bg-gray-50 border-gray-200");
|
|
5433
|
+
div.textContent = msg;
|
|
5434
|
+
container.appendChild(div);
|
|
5435
|
+
});
|
|
5436
|
+
}
|
|
5437
|
+
}
|
|
5438
|
+
|
|
5322
5439
|
// ============================================================================
|
|
5323
5440
|
// TOAST NOTIFICATIONS
|
|
5324
5441
|
// ============================================================================
|
|
@@ -5455,6 +5572,7 @@
|
|
|
5455
5572
|
// Form components
|
|
5456
5573
|
createInput,
|
|
5457
5574
|
createTextarea,
|
|
5575
|
+
createRichTextEditor,
|
|
5458
5576
|
createSelect,
|
|
5459
5577
|
createTimePicker,
|
|
5460
5578
|
createDateTimePicker,
|
|
@@ -5470,6 +5588,7 @@
|
|
|
5470
5588
|
createCurrency,
|
|
5471
5589
|
createPhoneInput,
|
|
5472
5590
|
createCheckbox,
|
|
5591
|
+
createCheckboxGroup,
|
|
5473
5592
|
|
|
5474
5593
|
// Button (delegates to Button component when available; resolved at call time via getComponent)
|
|
5475
5594
|
createButton: function (config) {
|
|
@@ -5490,10 +5609,12 @@
|
|
|
5490
5609
|
|
|
5491
5610
|
// Stepper
|
|
5492
5611
|
renderStepper,
|
|
5612
|
+
createTabs,
|
|
5613
|
+
createSteps,
|
|
5493
5614
|
|
|
5494
|
-
// Alerts
|
|
5615
|
+
// Alerts
|
|
5616
|
+
renderAlerts,
|
|
5495
5617
|
showToast,
|
|
5496
|
-
renderAlerts, // Legacy support for static alerts
|
|
5497
5618
|
|
|
5498
5619
|
// Table
|
|
5499
5620
|
createDataTable,
|
|
@@ -5520,7 +5641,7 @@
|
|
|
5520
5641
|
|
|
5521
5642
|
|
|
5522
5643
|
// ============================================
|
|
5523
|
-
// File 7/
|
|
5644
|
+
// File 7/41: components/toast.js
|
|
5524
5645
|
// ============================================
|
|
5525
5646
|
|
|
5526
5647
|
/**
|
|
@@ -5869,7 +5990,7 @@
|
|
|
5869
5990
|
|
|
5870
5991
|
|
|
5871
5992
|
// ============================================
|
|
5872
|
-
// File 8/
|
|
5993
|
+
// File 8/41: components/alert.js
|
|
5873
5994
|
// ============================================
|
|
5874
5995
|
|
|
5875
5996
|
/**
|
|
@@ -6157,7 +6278,7 @@
|
|
|
6157
6278
|
|
|
6158
6279
|
|
|
6159
6280
|
// ============================================
|
|
6160
|
-
// File 9/
|
|
6281
|
+
// File 9/41: components/button.js
|
|
6161
6282
|
// ============================================
|
|
6162
6283
|
|
|
6163
6284
|
/**
|
|
@@ -6364,7 +6485,7 @@
|
|
|
6364
6485
|
|
|
6365
6486
|
|
|
6366
6487
|
// ============================================
|
|
6367
|
-
// File 10/
|
|
6488
|
+
// File 10/41: components/spinner.js
|
|
6368
6489
|
// ============================================
|
|
6369
6490
|
|
|
6370
6491
|
/**
|
|
@@ -6506,7 +6627,7 @@
|
|
|
6506
6627
|
|
|
6507
6628
|
|
|
6508
6629
|
// ============================================
|
|
6509
|
-
// File 11/
|
|
6630
|
+
// File 11/41: components/badge.js
|
|
6510
6631
|
// ============================================
|
|
6511
6632
|
|
|
6512
6633
|
/**
|
|
@@ -6647,7 +6768,7 @@
|
|
|
6647
6768
|
|
|
6648
6769
|
|
|
6649
6770
|
// ============================================
|
|
6650
|
-
// File 12/
|
|
6771
|
+
// File 12/41: components/avatar.js
|
|
6651
6772
|
// ============================================
|
|
6652
6773
|
|
|
6653
6774
|
/**
|
|
@@ -6848,7 +6969,7 @@
|
|
|
6848
6969
|
|
|
6849
6970
|
|
|
6850
6971
|
// ============================================
|
|
6851
|
-
// File 13/
|
|
6972
|
+
// File 13/41: components/icon.js
|
|
6852
6973
|
// ============================================
|
|
6853
6974
|
|
|
6854
6975
|
/**
|
|
@@ -6896,12 +7017,12 @@
|
|
|
6896
7017
|
' stroke-width="1.5">' +
|
|
6897
7018
|
TI_PATH_NONE +
|
|
6898
7019
|
'<path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0"/><path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"/></svg>',
|
|
6899
|
-
|
|
7020
|
+
IconStar:
|
|
6900
7021
|
"<svg" +
|
|
6901
7022
|
TI +
|
|
6902
7023
|
' stroke-width="1.5">' +
|
|
6903
7024
|
TI_PATH_NONE +
|
|
6904
|
-
'<path d="
|
|
7025
|
+
'<path d="M12 17.75l-6.172 3.245l1.179 -6.873l-5 -4.867l6.9 -1l3.086 -6.253l3.086 6.253l6.9 1l-5 4.867l1.179 6.873z"/></svg>',
|
|
6905
7026
|
IconPhone:
|
|
6906
7027
|
"<svg" +
|
|
6907
7028
|
TI +
|
|
@@ -6929,6 +7050,40 @@
|
|
|
6929
7050
|
/** Filled circle for "just color" mode (IconOrColor when only icon_color is set) */
|
|
6930
7051
|
IconCircleFilled:
|
|
6931
7052
|
'<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="10" fill="currentColor"/></svg>',
|
|
7053
|
+
|
|
7054
|
+
// Rich text editor / toolbar (Tabler Icons outline, stroke 2)
|
|
7055
|
+
IconBold:
|
|
7056
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-bold"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 5h6a3.5 3.5 0 0 1 0 7h-6l0 -7" /><path d="M13 12h1a3.5 3.5 0 0 1 0 7h-7v-7" /></svg>',
|
|
7057
|
+
IconItalic:
|
|
7058
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-italic"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11 5l6 0" /><path d="M7 19l6 0" /><path d="M14 5l-4 14" /></svg>',
|
|
7059
|
+
IconUnderline:
|
|
7060
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-underline"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 5v5a5 5 0 0 0 10 0v-5" /><path d="M5 19h14" /></svg>',
|
|
7061
|
+
IconH1:
|
|
7062
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-h-1"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M19 18v-8l-2 2" /><path d="M4 6v12" /><path d="M12 6v12" /><path d="M11 18h2" /><path d="M3 18h2" /><path d="M4 12h8" /><path d="M3 6h2" /><path d="M11 6h2" /></svg>',
|
|
7063
|
+
IconH2:
|
|
7064
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-h-2"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M17 12a2 2 0 1 1 4 0c0 .591 -.417 1.318 -.816 1.858l-3.184 4.143l4 0" /><path d="M4 6v12" /><path d="M12 6v12" /><path d="M11 18h2" /><path d="M3 18h2" /><path d="M4 12h8" /><path d="M3 6h2" /><path d="M11 6h2" /></svg>',
|
|
7065
|
+
IconH3:
|
|
7066
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-h-3"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M19 14a2 2 0 1 0 -2 -2" /><path d="M17 16a2 2 0 1 0 2 -2" /><path d="M4 6v12" /><path d="M12 6v12" /><path d="M11 18h2" /><path d="M3 18h2" /><path d="M4 12h8" /><path d="M3 6h2" /><path d="M11 6h2" /></svg>',
|
|
7067
|
+
IconList:
|
|
7068
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-list"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 6l11 0" /><path d="M9 12l11 0" /><path d="M9 18l11 0" /><path d="M5 6l0 .01" /><path d="M5 12l0 .01" /><path d="M5 18l0 .01" /></svg>',
|
|
7069
|
+
IconListNumbers:
|
|
7070
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-list-numbers"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11 6h9" /><path d="M11 12h9" /><path d="M12 18h8" /><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4" /><path d="M6 10v-6l-2 2" /></svg>',
|
|
7071
|
+
IconAlignLeft:
|
|
7072
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-align-left"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6l16 0" /><path d="M4 12l10 0" /><path d="M4 18l14 0" /></svg>',
|
|
7073
|
+
IconAlignCenter:
|
|
7074
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-align-center"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6l16 0" /><path d="M8 12l8 0" /><path d="M6 18l12 0" /></svg>',
|
|
7075
|
+
IconAlignRight:
|
|
7076
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-align-right"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 6l16 0" /><path d="M10 12l10 0" /><path d="M6 18l14 0" /></svg>',
|
|
7077
|
+
IconCode:
|
|
7078
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-code"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 8l-4 4l4 4" /><path d="M17 8l4 4l-4 4" /><path d="M14 4l-4 16" /></svg>',
|
|
7079
|
+
IconLink:
|
|
7080
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-link"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 15l6 -6" /><path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" /><path d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" /></svg>',
|
|
7081
|
+
IconPhoto:
|
|
7082
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-photo"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 8h.01" /><path d="M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12" /><path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5" /><path d="M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3" /></svg>',
|
|
7083
|
+
IconArrowBackUp:
|
|
7084
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-arrow-back-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 14l-4 -4l4 -4" /><path d="M5 10h11a4 4 0 1 1 0 8h-1" /></svg>',
|
|
7085
|
+
IconArrowForwardUp:
|
|
7086
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-arrow-forward-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 14l4 -4l-4 -4" /><path d="M19 10h-11a4 4 0 1 0 0 8h1" /></svg>',
|
|
6932
7087
|
};
|
|
6933
7088
|
|
|
6934
7089
|
function join() {
|
|
@@ -7054,7 +7209,7 @@
|
|
|
7054
7209
|
|
|
7055
7210
|
|
|
7056
7211
|
// ============================================
|
|
7057
|
-
// File 14/
|
|
7212
|
+
// File 14/41: components/popover.js
|
|
7058
7213
|
// ============================================
|
|
7059
7214
|
|
|
7060
7215
|
/**
|
|
@@ -7077,6 +7232,7 @@
|
|
|
7077
7232
|
* @param {Function} [config.onOpen] - Called when popover opens (before positioning)
|
|
7078
7233
|
* @param {string} [config.bodyClassName] - Optional class for body wrapper (overrides default padding)
|
|
7079
7234
|
* @param {string} [config.panelClassName] - Optional class to add to panel (e.g. for width)
|
|
7235
|
+
* @param {boolean} [config.modal=false] - If true, lock body scroll and show backdrop; only popover and trigger are interactive
|
|
7080
7236
|
* @returns {Object} Popover API {show, hide, destroy, element}
|
|
7081
7237
|
*/
|
|
7082
7238
|
function create(config = {}) {
|
|
@@ -7091,6 +7247,7 @@
|
|
|
7091
7247
|
onOpen = null,
|
|
7092
7248
|
bodyClassName = "",
|
|
7093
7249
|
panelClassName = "",
|
|
7250
|
+
modal = true,
|
|
7094
7251
|
} = config;
|
|
7095
7252
|
|
|
7096
7253
|
const triggerEl =
|
|
@@ -7100,9 +7257,18 @@
|
|
|
7100
7257
|
return { show: noop, hide: noop, destroy: noop, element: null };
|
|
7101
7258
|
}
|
|
7102
7259
|
|
|
7260
|
+
// Wrap trigger in a relative container for layout (full width); popover is portaled to body
|
|
7261
|
+
const container = document.createElement("div");
|
|
7262
|
+
container.className = "relative w-full";
|
|
7263
|
+
const triggerParent = triggerEl.parentNode;
|
|
7264
|
+
if (triggerParent) {
|
|
7265
|
+
triggerParent.insertBefore(container, triggerEl);
|
|
7266
|
+
container.appendChild(triggerEl);
|
|
7267
|
+
}
|
|
7268
|
+
|
|
7103
7269
|
const wrapper = document.createElement("div");
|
|
7104
7270
|
wrapper.className =
|
|
7105
|
-
"fixed z-50
|
|
7271
|
+
"fixed z-50 pointer-events-none opacity-0 invisible transition-opacity duration-150 ease-out";
|
|
7106
7272
|
wrapper.setAttribute("aria-hidden", "true");
|
|
7107
7273
|
|
|
7108
7274
|
const panel = document.createElement("div");
|
|
@@ -7126,7 +7292,11 @@
|
|
|
7126
7292
|
const body = document.createElement("div");
|
|
7127
7293
|
body.className =
|
|
7128
7294
|
bodyClassName ||
|
|
7129
|
-
"text-reg-14 text-typography-secondary-text leading-5 [&_p]:mb-2 [&_p:last-child]:mb-0";
|
|
7295
|
+
"text-reg-14 text-typography-secondary-text leading-5 [&_p]:mb-2 [&_p:last-child]:mb-0 max-h-[90vh] overflow-y-auto overflow-x-hidden min-h-0";
|
|
7296
|
+
body.style.maxHeight = "90vh";
|
|
7297
|
+
body.style.overflowY = "auto";
|
|
7298
|
+
body.style.overflowX = "hidden";
|
|
7299
|
+
body.style.minHeight = "0";
|
|
7130
7300
|
if (panelClassName) {
|
|
7131
7301
|
panel.className = panel.className + " " + panelClassName;
|
|
7132
7302
|
}
|
|
@@ -7138,57 +7308,126 @@
|
|
|
7138
7308
|
panel.appendChild(body);
|
|
7139
7309
|
|
|
7140
7310
|
wrapper.appendChild(panel);
|
|
7311
|
+
document.body.appendChild(wrapper);
|
|
7312
|
+
|
|
7313
|
+
var backdropEl = null;
|
|
7314
|
+
var resizeObserver = null;
|
|
7315
|
+
|
|
7316
|
+
function onBackdropWheel(e) {
|
|
7317
|
+
e.preventDefault();
|
|
7318
|
+
}
|
|
7319
|
+
|
|
7320
|
+
function applyModalOpen() {
|
|
7321
|
+
if (!modal) return;
|
|
7322
|
+
if (!backdropEl) {
|
|
7323
|
+
backdropEl = document.createElement("div");
|
|
7324
|
+
backdropEl.className =
|
|
7325
|
+
"fixed inset-0 z-40 bg-transparent pointer-events-auto";
|
|
7326
|
+
backdropEl.setAttribute("aria-hidden", "true");
|
|
7327
|
+
backdropEl.addEventListener("click", function () {
|
|
7328
|
+
hide();
|
|
7329
|
+
});
|
|
7330
|
+
backdropEl.addEventListener("wheel", onBackdropWheel, {
|
|
7331
|
+
passive: false,
|
|
7332
|
+
});
|
|
7333
|
+
}
|
|
7334
|
+
document.body.appendChild(backdropEl);
|
|
7335
|
+
wrapper.style.zIndex = "999";
|
|
7336
|
+
}
|
|
7337
|
+
|
|
7338
|
+
function applyModalClose() {
|
|
7339
|
+
if (!modal) return;
|
|
7340
|
+
if (backdropEl && backdropEl.parentNode) {
|
|
7341
|
+
backdropEl.parentNode.removeChild(backdropEl);
|
|
7342
|
+
}
|
|
7343
|
+
wrapper.style.zIndex = "";
|
|
7344
|
+
}
|
|
7141
7345
|
|
|
7142
7346
|
function noop() {}
|
|
7143
7347
|
|
|
7144
7348
|
function position() {
|
|
7145
|
-
const
|
|
7349
|
+
const triggerRect = triggerEl.getBoundingClientRect();
|
|
7146
7350
|
const panelRect = panel.getBoundingClientRect();
|
|
7147
7351
|
const gap = 8;
|
|
7148
|
-
|
|
7149
|
-
|
|
7352
|
+
const viewportHeight =
|
|
7353
|
+
window.innerHeight || document.documentElement.clientHeight;
|
|
7354
|
+
const viewportWidth =
|
|
7355
|
+
window.innerWidth || document.documentElement.clientWidth;
|
|
7356
|
+
const spaceBelow = viewportHeight - triggerRect.bottom;
|
|
7357
|
+
const spaceAbove = triggerRect.top;
|
|
7358
|
+
const spaceRight = viewportWidth - triggerRect.right;
|
|
7359
|
+
const spaceLeft = triggerRect.left;
|
|
7360
|
+
|
|
7361
|
+
// Flip placement when there is not enough space (prefer requested side, flip only when needed)
|
|
7362
|
+
let effectivePlacement = placement;
|
|
7363
|
+
if (
|
|
7364
|
+
placement === "bottom" &&
|
|
7365
|
+
spaceBelow < panelRect.height + gap &&
|
|
7366
|
+
spaceAbove >= panelRect.height + gap
|
|
7367
|
+
) {
|
|
7368
|
+
effectivePlacement = "top";
|
|
7369
|
+
} else if (
|
|
7370
|
+
placement === "top" &&
|
|
7371
|
+
spaceAbove < panelRect.height + gap &&
|
|
7372
|
+
spaceBelow >= panelRect.height + gap
|
|
7373
|
+
) {
|
|
7374
|
+
effectivePlacement = "bottom";
|
|
7375
|
+
} else if (
|
|
7376
|
+
placement === "right" &&
|
|
7377
|
+
spaceRight < panelRect.width + gap &&
|
|
7378
|
+
spaceLeft >= panelRect.width + gap
|
|
7379
|
+
) {
|
|
7380
|
+
effectivePlacement = "left";
|
|
7381
|
+
} else if (
|
|
7382
|
+
placement === "left" &&
|
|
7383
|
+
spaceLeft < panelRect.width + gap &&
|
|
7384
|
+
spaceRight >= panelRect.width + gap
|
|
7385
|
+
) {
|
|
7386
|
+
effectivePlacement = "right";
|
|
7387
|
+
}
|
|
7150
7388
|
|
|
7151
|
-
|
|
7152
|
-
const alignLeft = (align === "center" ? (rect.width - panelRect.width) / 2 : align === "end" ? rect.width - panelRect.width : 0);
|
|
7153
|
-
const alignTop = (align === "center" ? (rect.height - panelRect.height) / 2 : align === "end" ? rect.height - panelRect.height : 0);
|
|
7389
|
+
panel.setAttribute("data-side", effectivePlacement);
|
|
7154
7390
|
|
|
7155
|
-
|
|
7391
|
+
let top = 0;
|
|
7392
|
+
let left = 0;
|
|
7393
|
+
const alignLeft =
|
|
7394
|
+
align === "center"
|
|
7395
|
+
? (triggerRect.width - panelRect.width) / 2
|
|
7396
|
+
: align === "end"
|
|
7397
|
+
? triggerRect.width - panelRect.width
|
|
7398
|
+
: 0;
|
|
7399
|
+
const alignTop =
|
|
7400
|
+
align === "center"
|
|
7401
|
+
? (triggerRect.height - panelRect.height) / 2
|
|
7402
|
+
: align === "end"
|
|
7403
|
+
? triggerRect.height - panelRect.height
|
|
7404
|
+
: 0;
|
|
7405
|
+
|
|
7406
|
+
switch (effectivePlacement) {
|
|
7156
7407
|
case "bottom":
|
|
7157
|
-
top =
|
|
7158
|
-
left =
|
|
7408
|
+
top = triggerRect.bottom + gap;
|
|
7409
|
+
left = triggerRect.left + alignLeft;
|
|
7159
7410
|
break;
|
|
7160
7411
|
case "top":
|
|
7161
|
-
top =
|
|
7162
|
-
left =
|
|
7412
|
+
top = triggerRect.top - panelRect.height - gap;
|
|
7413
|
+
left = triggerRect.left + alignLeft;
|
|
7163
7414
|
break;
|
|
7164
7415
|
case "right":
|
|
7165
|
-
top =
|
|
7166
|
-
left =
|
|
7416
|
+
top = triggerRect.top + alignTop;
|
|
7417
|
+
left = triggerRect.right + gap;
|
|
7167
7418
|
break;
|
|
7168
7419
|
case "left":
|
|
7169
|
-
top =
|
|
7170
|
-
left =
|
|
7420
|
+
top = triggerRect.top + alignTop;
|
|
7421
|
+
left = triggerRect.left - panelRect.width - gap;
|
|
7171
7422
|
break;
|
|
7172
7423
|
default:
|
|
7173
|
-
top =
|
|
7174
|
-
left =
|
|
7175
|
-
}
|
|
7176
|
-
|
|
7177
|
-
// Keep within viewport
|
|
7178
|
-
const padding = 8;
|
|
7179
|
-
if (left < padding) left = padding;
|
|
7180
|
-
if (left + panelRect.width > window.innerWidth - padding) {
|
|
7181
|
-
left = window.innerWidth - panelRect.width - padding;
|
|
7182
|
-
}
|
|
7183
|
-
if (top < padding) top = padding;
|
|
7184
|
-
if (top + panelRect.height > window.innerHeight - padding) {
|
|
7185
|
-
top = window.innerHeight - panelRect.height - padding;
|
|
7424
|
+
top = triggerRect.bottom + gap;
|
|
7425
|
+
left = triggerRect.left + alignLeft;
|
|
7186
7426
|
}
|
|
7187
7427
|
|
|
7188
|
-
wrapper.style.
|
|
7189
|
-
wrapper.style.top = "
|
|
7190
|
-
wrapper.style.
|
|
7191
|
-
// Force reflow so transform is applied before we show (avoids flash from left/top-left)
|
|
7428
|
+
wrapper.style.transform = "";
|
|
7429
|
+
wrapper.style.top = top + "px";
|
|
7430
|
+
wrapper.style.left = left + "px";
|
|
7192
7431
|
wrapper.offsetHeight;
|
|
7193
7432
|
}
|
|
7194
7433
|
|
|
@@ -7197,46 +7436,68 @@
|
|
|
7197
7436
|
wrapper.classList.add("invisible", "opacity-0", "pointer-events-none");
|
|
7198
7437
|
wrapper.classList.remove("visible", "opacity-100", "pointer-events-auto");
|
|
7199
7438
|
wrapper.setAttribute("aria-hidden", "true");
|
|
7439
|
+
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
7440
|
+
window.removeEventListener("resize", onScrollOrResize);
|
|
7441
|
+
if (resizeObserver && panel) {
|
|
7442
|
+
resizeObserver.disconnect();
|
|
7443
|
+
resizeObserver = null;
|
|
7444
|
+
}
|
|
7445
|
+
applyModalClose();
|
|
7200
7446
|
if (onClose) onClose();
|
|
7201
7447
|
}
|
|
7202
7448
|
|
|
7449
|
+
function onScrollOrResize() {
|
|
7450
|
+
if (wrapper.classList.contains("visible")) position();
|
|
7451
|
+
}
|
|
7452
|
+
|
|
7203
7453
|
function show() {
|
|
7204
7454
|
if (onOpen) onOpen();
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
document.body.appendChild(wrapper);
|
|
7208
|
-
}
|
|
7209
|
-
// On first open, wait for layout so getBoundingClientRect() is correct (avoids wrong position / "from left" look)
|
|
7210
|
-
if (justAppended) {
|
|
7211
|
-
requestAnimationFrame(function () {
|
|
7212
|
-
position();
|
|
7213
|
-
wrapper.classList.remove("invisible", "opacity-0", "pointer-events-none");
|
|
7214
|
-
wrapper.classList.add("visible", "opacity-100", "pointer-events-auto");
|
|
7215
|
-
wrapper.setAttribute("aria-hidden", "false");
|
|
7216
|
-
requestAnimationFrame(function () {
|
|
7217
|
-
requestAnimationFrame(function () {
|
|
7218
|
-
panel.setAttribute("data-state", "open");
|
|
7219
|
-
});
|
|
7220
|
-
});
|
|
7221
|
-
});
|
|
7222
|
-
} else {
|
|
7455
|
+
applyModalOpen();
|
|
7456
|
+
requestAnimationFrame(function () {
|
|
7223
7457
|
position();
|
|
7224
|
-
wrapper.classList.remove(
|
|
7458
|
+
wrapper.classList.remove(
|
|
7459
|
+
"invisible",
|
|
7460
|
+
"opacity-0",
|
|
7461
|
+
"pointer-events-none",
|
|
7462
|
+
);
|
|
7225
7463
|
wrapper.classList.add("visible", "opacity-100", "pointer-events-auto");
|
|
7226
7464
|
wrapper.setAttribute("aria-hidden", "false");
|
|
7465
|
+
window.addEventListener("scroll", onScrollOrResize, true);
|
|
7466
|
+
window.addEventListener("resize", onScrollOrResize);
|
|
7467
|
+
// Re-position when panel content size changes (e.g. async record list load in record-select)
|
|
7468
|
+
if (typeof ResizeObserver !== "undefined" && !resizeObserver) {
|
|
7469
|
+
resizeObserver = new ResizeObserver(function () {
|
|
7470
|
+
if (wrapper.classList.contains("visible")) position();
|
|
7471
|
+
});
|
|
7472
|
+
resizeObserver.observe(panel);
|
|
7473
|
+
}
|
|
7227
7474
|
requestAnimationFrame(function () {
|
|
7228
7475
|
requestAnimationFrame(function () {
|
|
7229
7476
|
panel.setAttribute("data-state", "open");
|
|
7230
7477
|
});
|
|
7231
7478
|
});
|
|
7232
|
-
}
|
|
7479
|
+
});
|
|
7233
7480
|
}
|
|
7234
7481
|
|
|
7235
7482
|
function destroy() {
|
|
7236
7483
|
hide();
|
|
7484
|
+
applyModalClose();
|
|
7485
|
+
if (resizeObserver && panel) {
|
|
7486
|
+
resizeObserver.disconnect();
|
|
7487
|
+
resizeObserver = null;
|
|
7488
|
+
}
|
|
7489
|
+
if (backdropEl && backdropEl.parentNode) {
|
|
7490
|
+
backdropEl.parentNode.removeChild(backdropEl);
|
|
7491
|
+
}
|
|
7492
|
+
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
7493
|
+
window.removeEventListener("resize", onScrollOrResize);
|
|
7237
7494
|
if (wrapper.parentNode) {
|
|
7238
7495
|
wrapper.parentNode.removeChild(wrapper);
|
|
7239
7496
|
}
|
|
7497
|
+
if (container.parentNode && triggerEl.parentNode === container) {
|
|
7498
|
+
container.parentNode.insertBefore(triggerEl, container);
|
|
7499
|
+
container.parentNode.removeChild(container);
|
|
7500
|
+
}
|
|
7240
7501
|
if (closeOnClickOutside) {
|
|
7241
7502
|
document.removeEventListener("click", outsideClick);
|
|
7242
7503
|
}
|
|
@@ -7279,6 +7540,8 @@
|
|
|
7279
7540
|
show,
|
|
7280
7541
|
hide,
|
|
7281
7542
|
destroy,
|
|
7543
|
+
/** Re-run positioning (e.g. after async content load). Call when panel size changes. */
|
|
7544
|
+
updatePosition: position,
|
|
7282
7545
|
setContent(newContent) {
|
|
7283
7546
|
body.innerHTML = "";
|
|
7284
7547
|
if (typeof newContent === "string") {
|
|
@@ -7300,7 +7563,7 @@
|
|
|
7300
7563
|
|
|
7301
7564
|
|
|
7302
7565
|
// ============================================
|
|
7303
|
-
// File 15/
|
|
7566
|
+
// File 15/41: components/select.js
|
|
7304
7567
|
// ============================================
|
|
7305
7568
|
|
|
7306
7569
|
/**
|
|
@@ -7356,6 +7619,14 @@
|
|
|
7356
7619
|
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
7357
7620
|
}
|
|
7358
7621
|
|
|
7622
|
+
function getDep(name) {
|
|
7623
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
7624
|
+
var c = global.FlowUI._getComponent(name);
|
|
7625
|
+
if (c) return c;
|
|
7626
|
+
}
|
|
7627
|
+
return global[name];
|
|
7628
|
+
}
|
|
7629
|
+
|
|
7359
7630
|
/**
|
|
7360
7631
|
* Create a custom select component
|
|
7361
7632
|
* @param {Object} config
|
|
@@ -7385,6 +7656,11 @@
|
|
|
7385
7656
|
var value =
|
|
7386
7657
|
config.value !== undefined && config.value !== null ? config.value : "";
|
|
7387
7658
|
|
|
7659
|
+
var Popover = getDep("Popover");
|
|
7660
|
+
if (!Popover || typeof Popover.create !== "function") {
|
|
7661
|
+
throw new Error("Select requires Popover");
|
|
7662
|
+
}
|
|
7663
|
+
|
|
7388
7664
|
var selectedOption = options.find(function (opt) {
|
|
7389
7665
|
var optValue =
|
|
7390
7666
|
opt.value !== undefined && opt.value !== null
|
|
@@ -7484,15 +7760,11 @@
|
|
|
7484
7760
|
|
|
7485
7761
|
var content = document.createElement("div");
|
|
7486
7762
|
content.setAttribute("role", "listbox");
|
|
7487
|
-
|
|
7488
|
-
"custom-select-content absolute left-0 right-0 z-50 max-h-[200px] min-w-[8rem] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium opacity-0 invisible transition-all duration-150 ease-out " +
|
|
7489
|
-
"group-[.open]:opacity-100 group-[.open]:visible ";
|
|
7490
|
-
content.className =
|
|
7491
|
-
contentBase + "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
|
|
7763
|
+
content.className = "custom-select-content w-full max-h-[45vh] overflow-hidden flex flex-col";
|
|
7492
7764
|
|
|
7493
7765
|
var optionsList = document.createElement("div");
|
|
7494
7766
|
optionsList.className =
|
|
7495
|
-
"overflow-y-auto max-h-[
|
|
7767
|
+
"overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white";
|
|
7496
7768
|
|
|
7497
7769
|
if (options.length === 0) {
|
|
7498
7770
|
var noOpt = document.createElement("div");
|
|
@@ -7542,47 +7814,66 @@
|
|
|
7542
7814
|
}
|
|
7543
7815
|
|
|
7544
7816
|
content.appendChild(optionsList);
|
|
7545
|
-
container.appendChild(content);
|
|
7546
7817
|
|
|
7547
|
-
var isOpen = false;
|
|
7548
7818
|
var highlightedIndex = -1;
|
|
7819
|
+
var popover = Popover.create({
|
|
7820
|
+
trigger: trigger,
|
|
7821
|
+
content: content,
|
|
7822
|
+
placement: "bottom",
|
|
7823
|
+
align: "start",
|
|
7824
|
+
closeOnClickOutside: true,
|
|
7825
|
+
bodyClassName: "p-0 overflow-hidden",
|
|
7826
|
+
panelClassName: "min-w-[var(--trigger-width)] max-h-[45vh] overflow-hidden",
|
|
7827
|
+
onOpen: function () {
|
|
7828
|
+
if (disabled) {
|
|
7829
|
+
popover.hide();
|
|
7830
|
+
return;
|
|
7831
|
+
}
|
|
7832
|
+
document
|
|
7833
|
+
.querySelectorAll(".custom-select, .record-select, .enum-select, .enum-multiselect, .custom-multiselect, .record-multiselect")
|
|
7834
|
+
.forEach(function (other) {
|
|
7835
|
+
if (other !== container && other.popoverInstance) {
|
|
7836
|
+
other.popoverInstance.hide();
|
|
7837
|
+
}
|
|
7838
|
+
});
|
|
7839
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
7840
|
+
chevron.style.transform = "rotate(180deg)";
|
|
7841
|
+
highlightOptionByValue(value);
|
|
7842
|
+
if (popover.panel) {
|
|
7843
|
+
var triggerWidthPx = trigger.offsetWidth + "px";
|
|
7844
|
+
popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
|
|
7845
|
+
popover.panel.style.minWidth = triggerWidthPx;
|
|
7846
|
+
popover.panel.style.width = triggerWidthPx;
|
|
7847
|
+
}
|
|
7848
|
+
},
|
|
7849
|
+
onClose: function () {
|
|
7850
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
7851
|
+
chevron.style.transform = "";
|
|
7852
|
+
highlightedIndex = -1;
|
|
7853
|
+
},
|
|
7854
|
+
});
|
|
7855
|
+
container.popoverInstance = popover;
|
|
7549
7856
|
|
|
7550
7857
|
function openDropdown() {
|
|
7551
7858
|
if (disabled) return;
|
|
7552
|
-
|
|
7553
|
-
.querySelectorAll(".custom-select.open, .record-select.open")
|
|
7554
|
-
.forEach(function (other) {
|
|
7555
|
-
if (other !== container) {
|
|
7556
|
-
other.classList.remove("open");
|
|
7557
|
-
var t = other.querySelector(
|
|
7558
|
-
"button, .custom-select-trigger, .record-select-trigger"
|
|
7559
|
-
);
|
|
7560
|
-
if (t) t.setAttribute("aria-expanded", "false");
|
|
7561
|
-
}
|
|
7562
|
-
});
|
|
7563
|
-
isOpen = true;
|
|
7564
|
-
container.classList.add("open");
|
|
7565
|
-
trigger.setAttribute("aria-expanded", "true");
|
|
7566
|
-
highlightOptionByValue(value);
|
|
7567
|
-
updatePosition();
|
|
7859
|
+
popover.show();
|
|
7568
7860
|
}
|
|
7569
7861
|
|
|
7570
7862
|
function closeDropdown() {
|
|
7571
|
-
|
|
7572
|
-
container.classList.remove("open");
|
|
7573
|
-
trigger.setAttribute("aria-expanded", "false");
|
|
7863
|
+
popover.hide();
|
|
7574
7864
|
highlightedIndex = -1;
|
|
7575
7865
|
}
|
|
7576
7866
|
|
|
7577
7867
|
function toggleDropdown() {
|
|
7868
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
7578
7869
|
var others = document.querySelectorAll(
|
|
7579
|
-
".custom-select
|
|
7870
|
+
".custom-select, .record-select, .enum-select, .enum-multiselect, .custom-multiselect, .record-multiselect"
|
|
7580
7871
|
);
|
|
7581
7872
|
var hasOther = Array.from(others).some(function (s) {
|
|
7582
|
-
return s !== container;
|
|
7873
|
+
return s !== container && s.popoverInstance && s.popoverInstance.element && s.popoverInstance.element.classList.contains("visible");
|
|
7583
7874
|
});
|
|
7584
7875
|
if (hasOther) openDropdown();
|
|
7585
|
-
else if (
|
|
7876
|
+
else if (isVisible) closeDropdown();
|
|
7586
7877
|
else openDropdown();
|
|
7587
7878
|
}
|
|
7588
7879
|
|
|
@@ -7661,40 +7952,26 @@
|
|
|
7661
7952
|
|
|
7662
7953
|
function scrollToOption(opt) {
|
|
7663
7954
|
if (!opt) return;
|
|
7664
|
-
var cr =
|
|
7955
|
+
var cr = optionsList.getBoundingClientRect();
|
|
7665
7956
|
var top = opt.offsetTop;
|
|
7666
7957
|
var bottom = top + opt.offsetHeight;
|
|
7667
|
-
var st =
|
|
7958
|
+
var st = optionsList.scrollTop;
|
|
7668
7959
|
var sb = st + cr.height;
|
|
7669
|
-
if (top < st)
|
|
7960
|
+
if (top < st) optionsList.scrollTop = top - 8;
|
|
7670
7961
|
else if (bottom > sb)
|
|
7671
|
-
|
|
7672
|
-
}
|
|
7673
|
-
|
|
7674
|
-
function updatePosition() {
|
|
7675
|
-
var rect = trigger.getBoundingClientRect();
|
|
7676
|
-
var vh = window.innerHeight;
|
|
7677
|
-
var below = vh - rect.bottom;
|
|
7678
|
-
var above = rect.top;
|
|
7679
|
-
if (below < 200 && above > below) {
|
|
7680
|
-
content.className =
|
|
7681
|
-
contentBase +
|
|
7682
|
-
"bottom-full mb-1 translate-y-1 group-[.open]:translate-y-0";
|
|
7683
|
-
} else {
|
|
7684
|
-
content.className =
|
|
7685
|
-
contentBase +
|
|
7686
|
-
"top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
|
|
7687
|
-
}
|
|
7962
|
+
optionsList.scrollTop = bottom - cr.height + 8;
|
|
7688
7963
|
}
|
|
7689
7964
|
|
|
7690
7965
|
trigger.addEventListener("click", function (e) {
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7966
|
+
if (disabled) {
|
|
7967
|
+
e.preventDefault();
|
|
7968
|
+
e.stopImmediatePropagation();
|
|
7969
|
+
}
|
|
7970
|
+
}, true);
|
|
7695
7971
|
|
|
7696
7972
|
trigger.addEventListener("keydown", function (e) {
|
|
7697
7973
|
if (disabled) return;
|
|
7974
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
7698
7975
|
switch (e.key) {
|
|
7699
7976
|
case "Enter":
|
|
7700
7977
|
case " ":
|
|
@@ -7703,16 +7980,16 @@
|
|
|
7703
7980
|
break;
|
|
7704
7981
|
case "ArrowDown":
|
|
7705
7982
|
e.preventDefault();
|
|
7706
|
-
if (!
|
|
7983
|
+
if (!isVisible) openDropdown();
|
|
7707
7984
|
else navigateOptions(1);
|
|
7708
7985
|
break;
|
|
7709
7986
|
case "ArrowUp":
|
|
7710
7987
|
e.preventDefault();
|
|
7711
|
-
if (!
|
|
7988
|
+
if (!isVisible) openDropdown();
|
|
7712
7989
|
else navigateOptions(-1);
|
|
7713
7990
|
break;
|
|
7714
7991
|
case "Escape":
|
|
7715
|
-
if (
|
|
7992
|
+
if (isVisible) {
|
|
7716
7993
|
e.preventDefault();
|
|
7717
7994
|
closeDropdown();
|
|
7718
7995
|
}
|
|
@@ -7733,13 +8010,6 @@
|
|
|
7733
8010
|
scrollToOption(opt);
|
|
7734
8011
|
}
|
|
7735
8012
|
|
|
7736
|
-
document.addEventListener("click", function (e) {
|
|
7737
|
-
if (isOpen && !container.contains(e.target)) closeDropdown();
|
|
7738
|
-
});
|
|
7739
|
-
document.addEventListener("keydown", function (e) {
|
|
7740
|
-
if (e.key === "Escape" && isOpen) closeDropdown();
|
|
7741
|
-
});
|
|
7742
|
-
|
|
7743
8013
|
container.updateValue = function (newValue) {
|
|
7744
8014
|
value =
|
|
7745
8015
|
newValue !== undefined && newValue !== null ? newValue : "";
|
|
@@ -7836,7 +8106,8 @@
|
|
|
7836
8106
|
canClear && !!value && !disabled
|
|
7837
8107
|
);
|
|
7838
8108
|
updateClearButton();
|
|
7839
|
-
|
|
8109
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
8110
|
+
if (disabled && isVisible) closeDropdown();
|
|
7840
8111
|
};
|
|
7841
8112
|
|
|
7842
8113
|
return container;
|
|
@@ -7850,7 +8121,7 @@
|
|
|
7850
8121
|
|
|
7851
8122
|
|
|
7852
8123
|
// ============================================
|
|
7853
|
-
// File 16/
|
|
8124
|
+
// File 16/41: components/enum-select.js
|
|
7854
8125
|
// ============================================
|
|
7855
8126
|
|
|
7856
8127
|
/**
|
|
@@ -7926,6 +8197,14 @@
|
|
|
7926
8197
|
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
7927
8198
|
}
|
|
7928
8199
|
|
|
8200
|
+
function getDep(name) {
|
|
8201
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
8202
|
+
var c = global.FlowUI._getComponent(name);
|
|
8203
|
+
if (c) return c;
|
|
8204
|
+
}
|
|
8205
|
+
return global[name];
|
|
8206
|
+
}
|
|
8207
|
+
|
|
7929
8208
|
/** Resolve client: use FlowUI._getComponent when bundle has captured globals, else global.superleapClient */
|
|
7930
8209
|
function getClient() {
|
|
7931
8210
|
if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
|
|
@@ -7989,8 +8268,10 @@
|
|
|
7989
8268
|
var error = null;
|
|
7990
8269
|
var searchQuery = "";
|
|
7991
8270
|
var popover = null;
|
|
7992
|
-
var
|
|
7993
|
-
|
|
8271
|
+
var Popover = getDep("Popover");
|
|
8272
|
+
if (!Popover || typeof Popover.create !== "function") {
|
|
8273
|
+
throw new Error("EnumSelect requires Popover");
|
|
8274
|
+
}
|
|
7994
8275
|
|
|
7995
8276
|
var container = document.createElement("div");
|
|
7996
8277
|
container.className = "enum-select relative w-full group";
|
|
@@ -8074,13 +8355,7 @@
|
|
|
8074
8355
|
// Create dropdown content
|
|
8075
8356
|
var content = document.createElement("div");
|
|
8076
8357
|
content.setAttribute("role", "listbox");
|
|
8077
|
-
|
|
8078
|
-
if (!usePopover) {
|
|
8079
|
-
contentBase += " absolute left-0 right-0 z-50 max-h-[30vh] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium border-1/2 border-border-primary opacity-0 invisible transition-all duration-150 ease-out group-[.open]:opacity-100 group-[.open]:visible top-full mt-1 -translate-y-1 group-[.open]:translate-y-0 flex flex-col";
|
|
8080
|
-
} else {
|
|
8081
|
-
contentBase += " max-h-[30vh] overflow-hidden flex flex-col";
|
|
8082
|
-
}
|
|
8083
|
-
content.className = contentBase;
|
|
8358
|
+
content.className = "w-full min-w-[200px] max-h-[45vh] overflow-hidden flex flex-col";
|
|
8084
8359
|
|
|
8085
8360
|
// Search input (using InputComponent like phone-input)
|
|
8086
8361
|
var searchContainer = document.createElement("div");
|
|
@@ -8141,15 +8416,11 @@
|
|
|
8141
8416
|
// Options list
|
|
8142
8417
|
var optionsList = document.createElement("div");
|
|
8143
8418
|
optionsList.className =
|
|
8144
|
-
"overflow-y-auto max-h-[
|
|
8419
|
+
"overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white flex-1 min-h-0";
|
|
8145
8420
|
|
|
8146
8421
|
content.appendChild(searchContainer);
|
|
8147
8422
|
content.appendChild(optionsList);
|
|
8148
8423
|
|
|
8149
|
-
if (!usePopover) {
|
|
8150
|
-
container.appendChild(content);
|
|
8151
|
-
}
|
|
8152
|
-
|
|
8153
8424
|
var highlightedIndex = -1;
|
|
8154
8425
|
|
|
8155
8426
|
function showLoading() {
|
|
@@ -8272,37 +8543,14 @@
|
|
|
8272
8543
|
|
|
8273
8544
|
function openDropdown() {
|
|
8274
8545
|
if (disabled) return;
|
|
8275
|
-
if (popover) {
|
|
8276
|
-
// Close other open selects
|
|
8277
|
-
document
|
|
8278
|
-
.querySelectorAll(".enum-select, .custom-select, .record-select")
|
|
8279
|
-
.forEach(function (other) {
|
|
8280
|
-
if (other !== container && other.popoverInstance) {
|
|
8281
|
-
other.popoverInstance.hide();
|
|
8282
|
-
}
|
|
8283
|
-
});
|
|
8284
|
-
popover.show();
|
|
8285
|
-
trigger.setAttribute("aria-expanded", "true");
|
|
8286
|
-
highlightOptionByValue(value);
|
|
8287
|
-
if (searchInput) {
|
|
8288
|
-
setTimeout(function () {
|
|
8289
|
-
searchInput.focus();
|
|
8290
|
-
}, 50);
|
|
8291
|
-
}
|
|
8292
|
-
return;
|
|
8293
|
-
}
|
|
8294
|
-
// Fallback when Popover not available
|
|
8295
8546
|
document
|
|
8296
|
-
.querySelectorAll(".enum-select.
|
|
8547
|
+
.querySelectorAll(".enum-select, .custom-select, .record-select")
|
|
8297
8548
|
.forEach(function (other) {
|
|
8298
|
-
if (other !== container) {
|
|
8299
|
-
other.
|
|
8300
|
-
var t = other.querySelector("button");
|
|
8301
|
-
if (t) t.setAttribute("aria-expanded", "false");
|
|
8549
|
+
if (other !== container && other.popoverInstance) {
|
|
8550
|
+
other.popoverInstance.hide();
|
|
8302
8551
|
}
|
|
8303
8552
|
});
|
|
8304
|
-
|
|
8305
|
-
container.classList.add("open");
|
|
8553
|
+
popover.show();
|
|
8306
8554
|
trigger.setAttribute("aria-expanded", "true");
|
|
8307
8555
|
highlightOptionByValue(value);
|
|
8308
8556
|
if (searchInput) {
|
|
@@ -8313,12 +8561,7 @@
|
|
|
8313
8561
|
}
|
|
8314
8562
|
|
|
8315
8563
|
function closeDropdown() {
|
|
8316
|
-
|
|
8317
|
-
popover.hide();
|
|
8318
|
-
} else {
|
|
8319
|
-
isOpen = false;
|
|
8320
|
-
container.classList.remove("open");
|
|
8321
|
-
}
|
|
8564
|
+
popover.hide();
|
|
8322
8565
|
trigger.setAttribute("aria-expanded", "false");
|
|
8323
8566
|
highlightedIndex = -1;
|
|
8324
8567
|
clearSearch();
|
|
@@ -8326,9 +8569,7 @@
|
|
|
8326
8569
|
}
|
|
8327
8570
|
|
|
8328
8571
|
function toggleDropdown() {
|
|
8329
|
-
var isVisible = popover
|
|
8330
|
-
? popover.element && popover.element.classList.contains("visible")
|
|
8331
|
-
: isOpen;
|
|
8572
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
8332
8573
|
if (isVisible) {
|
|
8333
8574
|
closeDropdown();
|
|
8334
8575
|
} else {
|
|
@@ -8439,10 +8680,7 @@
|
|
|
8439
8680
|
|
|
8440
8681
|
// Initialize Popover
|
|
8441
8682
|
function initializePopover() {
|
|
8442
|
-
|
|
8443
|
-
return;
|
|
8444
|
-
}
|
|
8445
|
-
popover = global.Popover.create({
|
|
8683
|
+
popover = Popover.create({
|
|
8446
8684
|
trigger: trigger,
|
|
8447
8685
|
content: content,
|
|
8448
8686
|
placement: "bottom",
|
|
@@ -8458,6 +8696,12 @@
|
|
|
8458
8696
|
onOpen: function () {
|
|
8459
8697
|
trigger.setAttribute("aria-expanded", "true");
|
|
8460
8698
|
chevron.style.transform = "rotate(180deg)";
|
|
8699
|
+
if (popover.panel) {
|
|
8700
|
+
var triggerWidthPx = trigger.offsetWidth + "px";
|
|
8701
|
+
popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
|
|
8702
|
+
popover.panel.style.minWidth = triggerWidthPx;
|
|
8703
|
+
popover.panel.style.width = triggerWidthPx;
|
|
8704
|
+
}
|
|
8461
8705
|
},
|
|
8462
8706
|
bodyClassName: "p-0 overflow-hidden",
|
|
8463
8707
|
panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
|
|
@@ -8465,13 +8709,6 @@
|
|
|
8465
8709
|
|
|
8466
8710
|
// Store popover instance for cleanup
|
|
8467
8711
|
container.popoverInstance = popover;
|
|
8468
|
-
|
|
8469
|
-
// Set CSS variable for trigger width
|
|
8470
|
-
var triggerWidth = trigger.offsetWidth;
|
|
8471
|
-
if (popover.panel) {
|
|
8472
|
-
popover.panel.style.setProperty("--trigger-width", triggerWidth + "px");
|
|
8473
|
-
popover.panel.style.minWidth = triggerWidth + "px";
|
|
8474
|
-
}
|
|
8475
8712
|
}
|
|
8476
8713
|
|
|
8477
8714
|
// Load options from SDK
|
|
@@ -8591,21 +8828,6 @@
|
|
|
8591
8828
|
initializePopover();
|
|
8592
8829
|
loadOptions();
|
|
8593
8830
|
|
|
8594
|
-
if (!usePopover) {
|
|
8595
|
-
trigger.addEventListener("click", function (e) {
|
|
8596
|
-
e.preventDefault();
|
|
8597
|
-
e.stopPropagation();
|
|
8598
|
-
if (disabled) return;
|
|
8599
|
-
toggleDropdown();
|
|
8600
|
-
});
|
|
8601
|
-
document.addEventListener("click", function (e) {
|
|
8602
|
-
if (isOpen && !container.contains(e.target)) closeDropdown();
|
|
8603
|
-
});
|
|
8604
|
-
document.addEventListener("keydown", function (e) {
|
|
8605
|
-
if (e.key === "Escape" && isOpen) closeDropdown();
|
|
8606
|
-
});
|
|
8607
|
-
}
|
|
8608
|
-
|
|
8609
8831
|
// Public API
|
|
8610
8832
|
container.updateValue = function (newValue) {
|
|
8611
8833
|
value = newValue !== undefined && newValue !== null ? newValue : "";
|
|
@@ -8650,7 +8872,7 @@
|
|
|
8650
8872
|
);
|
|
8651
8873
|
updateClearButton();
|
|
8652
8874
|
var isVisible = popover && popover.element && popover.element.classList.contains("visible");
|
|
8653
|
-
if (disabled &&
|
|
8875
|
+
if (disabled && isVisible) closeDropdown();
|
|
8654
8876
|
};
|
|
8655
8877
|
|
|
8656
8878
|
container.reload = function () {
|
|
@@ -8682,13 +8904,13 @@
|
|
|
8682
8904
|
|
|
8683
8905
|
|
|
8684
8906
|
// ============================================
|
|
8685
|
-
// File 17/
|
|
8907
|
+
// File 17/41: components/record-select.js
|
|
8686
8908
|
// ============================================
|
|
8687
8909
|
|
|
8688
8910
|
/**
|
|
8689
8911
|
* Record Select Component (superleap-flow)
|
|
8690
8912
|
* Single-record select with search; same trigger/content styling as Select.
|
|
8691
|
-
* Uses
|
|
8913
|
+
* Uses Popover for dropdown (required), InputComponent (search), Spinner (loading), Avatar (vivid for user).
|
|
8692
8914
|
* Fetches records via superleapClient.getSdk().model(objectSlug).
|
|
8693
8915
|
* For objectSlug === 'user' shows Vivid Avatar; otherwise static icon from schema or object map (database fallback).
|
|
8694
8916
|
* Does not use icon from backend payload.
|
|
@@ -8696,20 +8918,31 @@
|
|
|
8696
8918
|
|
|
8697
8919
|
(function (global) {
|
|
8698
8920
|
|
|
8699
|
-
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8707
|
-
|
|
8708
|
-
|
|
8921
|
+
function getDep(name) {
|
|
8922
|
+
if (
|
|
8923
|
+
typeof global.FlowUI !== "undefined" &&
|
|
8924
|
+
typeof global.FlowUI._getComponent === "function"
|
|
8925
|
+
) {
|
|
8926
|
+
var c = global.FlowUI._getComponent(name);
|
|
8927
|
+
if (c) return c;
|
|
8928
|
+
}
|
|
8929
|
+
return global[name];
|
|
8930
|
+
}
|
|
8931
|
+
|
|
8932
|
+
var Popover = getDep("Popover");
|
|
8933
|
+
var InputComponent = getDep("InputComponent");
|
|
8934
|
+
var Spinner = getDep("Spinner");
|
|
8935
|
+
|
|
8936
|
+
/** When objectSlug === USERS, show Vivid Avatar (name-based color) instead of static icon */
|
|
8937
|
+
var STANDARD_OBJECT_SLUGS_USERS = "user";
|
|
8938
|
+
|
|
8939
|
+
/** Object slug -> Icon component iconStr + color (Tabler icon names). Used when objectSchema.properties.icon_data not provided. */
|
|
8940
|
+
var OBJECT_SLUG_TO_ICON = {
|
|
8941
|
+
team: { iconStr: "IconUsers", color: "primary" },
|
|
8709
8942
|
role: { iconStr: "IconShield", color: "info" },
|
|
8710
8943
|
iframe: { iconStr: "IconLayout", color: "neutral" },
|
|
8711
8944
|
lead: { iconStr: "IconUser", color: "primary" },
|
|
8712
|
-
opportunity: { iconStr: "
|
|
8945
|
+
opportunity: { iconStr: "IconStar", color: "success" },
|
|
8713
8946
|
call_log: { iconStr: "IconPhone", color: "info" },
|
|
8714
8947
|
communication: { iconStr: "IconMessage", color: "primary" },
|
|
8715
8948
|
history_field: { iconStr: "IconClock", color: "neutral" },
|
|
@@ -8720,7 +8953,7 @@
|
|
|
8720
8953
|
'<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>';
|
|
8721
8954
|
var X_SVG =
|
|
8722
8955
|
'<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>';
|
|
8723
|
-
|
|
8956
|
+
|
|
8724
8957
|
var SEARCH_ICON =
|
|
8725
8958
|
'<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>';
|
|
8726
8959
|
|
|
@@ -8735,7 +8968,8 @@
|
|
|
8735
8968
|
"border-error-border hover:border-error-border-hover focus:border-1/2 focus:border-error-border-hover",
|
|
8736
8969
|
warning:
|
|
8737
8970
|
"border-warning-border hover:border-warning-border-hover focus:border-1/2 focus:border-warning-border-hover",
|
|
8738
|
-
borderless:
|
|
8971
|
+
borderless:
|
|
8972
|
+
"border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
|
|
8739
8973
|
inline:
|
|
8740
8974
|
"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",
|
|
8741
8975
|
};
|
|
@@ -8744,7 +8978,9 @@
|
|
|
8744
8978
|
large: "px-12 py-8",
|
|
8745
8979
|
small: "px-8 py-4",
|
|
8746
8980
|
};
|
|
8747
|
-
var placeholderClass = placeholder
|
|
8981
|
+
var placeholderClass = placeholder
|
|
8982
|
+
? " text-typography-quaternary-text"
|
|
8983
|
+
: "";
|
|
8748
8984
|
var disabledClass = disabled
|
|
8749
8985
|
? " pointer-events-none cursor-not-allowed bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary"
|
|
8750
8986
|
: "";
|
|
@@ -8800,15 +9036,27 @@
|
|
|
8800
9036
|
function getObjectIconInfo(slug, objectSchema) {
|
|
8801
9037
|
var color = "neutral";
|
|
8802
9038
|
var iconStr = "IconDatabase";
|
|
8803
|
-
if (
|
|
9039
|
+
if (
|
|
9040
|
+
objectSchema &&
|
|
9041
|
+
objectSchema.properties &&
|
|
9042
|
+
objectSchema.properties.icon_data
|
|
9043
|
+
) {
|
|
8804
9044
|
var iconData = objectSchema.properties.icon_data;
|
|
8805
|
-
if (typeof iconData.color === "string" && iconData.color)
|
|
8806
|
-
|
|
9045
|
+
if (typeof iconData.color === "string" && iconData.color)
|
|
9046
|
+
color = iconData.color;
|
|
9047
|
+
if (typeof iconData.icon === "string" && iconData.icon)
|
|
9048
|
+
iconStr = iconData.icon;
|
|
8807
9049
|
}
|
|
8808
|
-
if (
|
|
9050
|
+
if (
|
|
9051
|
+
!objectSchema ||
|
|
9052
|
+
!objectSchema.properties ||
|
|
9053
|
+
!objectSchema.properties.icon_data ||
|
|
9054
|
+
!objectSchema.properties.icon_data.icon
|
|
9055
|
+
) {
|
|
8809
9056
|
if (OBJECT_SLUG_TO_ICON[slug]) {
|
|
8810
9057
|
iconStr = OBJECT_SLUG_TO_ICON[slug].iconStr;
|
|
8811
|
-
if (OBJECT_SLUG_TO_ICON[slug].color)
|
|
9058
|
+
if (OBJECT_SLUG_TO_ICON[slug].color)
|
|
9059
|
+
color = OBJECT_SLUG_TO_ICON[slug].color;
|
|
8812
9060
|
} else {
|
|
8813
9061
|
iconStr = "IconDatabase";
|
|
8814
9062
|
color = "neutral";
|
|
@@ -8831,6 +9079,7 @@
|
|
|
8831
9079
|
* @param {string} [config.size] - 'default' | 'large' | 'small'
|
|
8832
9080
|
* @param {boolean} [config.canClear] - Show clear button when value is set
|
|
8833
9081
|
* @param {number} [config.initialLimit] - Initial fetch limit (default 50)
|
|
9082
|
+
* @param {Object} [config.initialFilter] - Optional filter object to merge with search (e.g. { field: "status", operator: "exact", value: "active" } or { and: [...] })
|
|
8834
9083
|
* @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)
|
|
8835
9084
|
* @returns {HTMLElement} Record select container element
|
|
8836
9085
|
*/
|
|
@@ -8839,12 +9088,14 @@
|
|
|
8839
9088
|
var objectSlug = config.objectSlug;
|
|
8840
9089
|
var objectSchema = config.objectSchema || null;
|
|
8841
9090
|
var placeholder = config.placeholder || "Select a record";
|
|
8842
|
-
var searchPlaceholder =
|
|
9091
|
+
var searchPlaceholder =
|
|
9092
|
+
config.searchPlaceholder || "Search " + (objectSlug || "") + "...";
|
|
8843
9093
|
var onChange = config.onChange;
|
|
8844
9094
|
var variant = config.variant || "default";
|
|
8845
9095
|
var size = config.size || "default";
|
|
8846
9096
|
var canClear = !!config.canClear;
|
|
8847
9097
|
var initialLimit = config.initialLimit != null ? config.initialLimit : 50;
|
|
9098
|
+
var initialFilter = config.initialFilter || null; // Can be array, object, or function returning either
|
|
8848
9099
|
|
|
8849
9100
|
var disabled = config.disabled === true;
|
|
8850
9101
|
var value =
|
|
@@ -8856,6 +9107,12 @@
|
|
|
8856
9107
|
errEl.textContent = "Record select: objectSlug is required.";
|
|
8857
9108
|
return errEl;
|
|
8858
9109
|
}
|
|
9110
|
+
if (!Popover || typeof Popover.create !== "function") {
|
|
9111
|
+
var popoverErr = document.createElement("div");
|
|
9112
|
+
popoverErr.className = "text-reg-13 text-typography-quaternary-text";
|
|
9113
|
+
popoverErr.textContent = "Record select: Popover is required.";
|
|
9114
|
+
return popoverErr;
|
|
9115
|
+
}
|
|
8859
9116
|
|
|
8860
9117
|
var container = document.createElement("div");
|
|
8861
9118
|
container.className = "record-select relative w-full group";
|
|
@@ -8868,16 +9125,11 @@
|
|
|
8868
9125
|
var isOpen = false;
|
|
8869
9126
|
var searchTerm = "";
|
|
8870
9127
|
var searchDebounceTimer = null;
|
|
8871
|
-
var usePopover = Popover && typeof Popover.create === "function";
|
|
8872
9128
|
var popover = null;
|
|
8873
9129
|
var hasMoreRecords = true;
|
|
8874
9130
|
var currentPage = 1;
|
|
8875
9131
|
var isFetchingMore = false;
|
|
8876
9132
|
var totalFetched = 0;
|
|
8877
|
-
var contentBase = "record-select-content min-w-[8rem] ";
|
|
8878
|
-
if (!usePopover) {
|
|
8879
|
-
contentBase += "absolute left-0 right-0 z-50 max-h-[30vh] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium opacity-0 invisible transition-all duration-150 ease-out group-[.open]:opacity-100 group-[.open]:visible ";
|
|
8880
|
-
}
|
|
8881
9133
|
|
|
8882
9134
|
// Trigger wrapper + button (same structure as Select)
|
|
8883
9135
|
var triggerWrapper = document.createElement("span");
|
|
@@ -8891,7 +9143,7 @@
|
|
|
8891
9143
|
size,
|
|
8892
9144
|
disabled,
|
|
8893
9145
|
!value,
|
|
8894
|
-
canClear && !!value && !disabled
|
|
9146
|
+
canClear && !!value && !disabled,
|
|
8895
9147
|
);
|
|
8896
9148
|
trigger.disabled = disabled;
|
|
8897
9149
|
trigger.setAttribute("aria-haspopup", "listbox");
|
|
@@ -8900,7 +9152,8 @@
|
|
|
8900
9152
|
trigger.classList.add("record-select-trigger");
|
|
8901
9153
|
|
|
8902
9154
|
var triggerContent = document.createElement("div");
|
|
8903
|
-
triggerContent.className =
|
|
9155
|
+
triggerContent.className =
|
|
9156
|
+
"record-select-trigger-content flex items-center gap-8 flex-1 min-w-0";
|
|
8904
9157
|
|
|
8905
9158
|
var triggerIcon = document.createElement("span");
|
|
8906
9159
|
triggerIcon.className = "record-select-trigger-icon shrink-0 hidden";
|
|
@@ -8943,7 +9196,9 @@
|
|
|
8943
9196
|
// Dropdown content: search + list (same content pattern as Select)
|
|
8944
9197
|
var content = document.createElement("div");
|
|
8945
9198
|
content.setAttribute("role", "listbox");
|
|
8946
|
-
content.
|
|
9199
|
+
content.setAttribute("data-field-id", fieldId);
|
|
9200
|
+
content.className =
|
|
9201
|
+
"record-select-content max-h-[45vh] overflow-hidden flex flex-col";
|
|
8947
9202
|
|
|
8948
9203
|
var searchWrap = document.createElement("div");
|
|
8949
9204
|
searchWrap.className = "py-8 border-b-1/2 border-border-primary";
|
|
@@ -8974,12 +9229,12 @@
|
|
|
8974
9229
|
} else {
|
|
8975
9230
|
var fallbackWrapper = document.createElement("div");
|
|
8976
9231
|
fallbackWrapper.className = "flex items-center gap-8 px-12";
|
|
8977
|
-
|
|
9232
|
+
|
|
8978
9233
|
var searchIconSpan = document.createElement("span");
|
|
8979
9234
|
searchIconSpan.className = "shrink-0 text-typography-tertiary-text";
|
|
8980
9235
|
searchIconSpan.innerHTML = SEARCH_ICON;
|
|
8981
9236
|
fallbackWrapper.appendChild(searchIconSpan);
|
|
8982
|
-
|
|
9237
|
+
|
|
8983
9238
|
var searchInput = document.createElement("input");
|
|
8984
9239
|
searchInput.type = "text";
|
|
8985
9240
|
searchInput.className =
|
|
@@ -8993,76 +9248,83 @@
|
|
|
8993
9248
|
content.appendChild(searchWrap);
|
|
8994
9249
|
|
|
8995
9250
|
var optionsList = document.createElement("div");
|
|
8996
|
-
optionsList.className =
|
|
8997
|
-
|
|
9251
|
+
optionsList.className =
|
|
9252
|
+
"overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white record-select-options";
|
|
9253
|
+
|
|
8998
9254
|
// Add scroll listener for infinite scroll
|
|
8999
9255
|
optionsList.addEventListener("scroll", function () {
|
|
9000
9256
|
if (isFetchingMore || !hasMoreRecords) return;
|
|
9001
9257
|
var scrollHeight = optionsList.scrollHeight;
|
|
9002
9258
|
var scrollTop = optionsList.scrollTop;
|
|
9003
9259
|
var clientHeight = optionsList.clientHeight;
|
|
9004
|
-
|
|
9260
|
+
|
|
9005
9261
|
// Trigger load more when scrolled to bottom (with 50px threshold)
|
|
9006
9262
|
if (scrollTop + clientHeight >= scrollHeight - 50) {
|
|
9007
9263
|
loadMoreRecords();
|
|
9008
9264
|
}
|
|
9009
9265
|
});
|
|
9010
|
-
|
|
9011
|
-
content.appendChild(optionsList);
|
|
9012
9266
|
|
|
9013
|
-
|
|
9014
|
-
container.appendChild(content);
|
|
9015
|
-
}
|
|
9267
|
+
content.appendChild(optionsList);
|
|
9016
9268
|
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
if (searchDebounceTimer) {
|
|
9058
|
-
clearTimeout(searchDebounceTimer);
|
|
9059
|
-
searchDebounceTimer = null;
|
|
9269
|
+
popover = Popover.create({
|
|
9270
|
+
trigger: trigger,
|
|
9271
|
+
content: content,
|
|
9272
|
+
placement: "bottom",
|
|
9273
|
+
align: "start",
|
|
9274
|
+
closeOnClickOutside: true,
|
|
9275
|
+
bodyClassName: "p-0 overflow-hidden",
|
|
9276
|
+
panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
|
|
9277
|
+
onOpen: function () {
|
|
9278
|
+
if (disabled) {
|
|
9279
|
+
popover.hide();
|
|
9280
|
+
return;
|
|
9281
|
+
}
|
|
9282
|
+
isOpen = true;
|
|
9283
|
+
container.classList.add("open");
|
|
9284
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
9285
|
+
searchTerm = "";
|
|
9286
|
+
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
9287
|
+
else if (searchInputEl) searchInputEl.value = "";
|
|
9288
|
+
if (popover.panel) {
|
|
9289
|
+
var triggerWidthPx = trigger.offsetWidth + "px";
|
|
9290
|
+
popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
|
|
9291
|
+
popover.panel.style.minWidth = triggerWidthPx;
|
|
9292
|
+
popover.panel.style.width = triggerWidthPx;
|
|
9293
|
+
}
|
|
9294
|
+
loadInitialAndRender();
|
|
9295
|
+
setTimeout(function () {
|
|
9296
|
+
if (searchInputEl) searchInputEl.focus();
|
|
9297
|
+
}, 0);
|
|
9298
|
+
// Let consumers (e.g. BANT Questions "Add Contact") inject content into the dropdown
|
|
9299
|
+
try {
|
|
9300
|
+
var doc =
|
|
9301
|
+
global.document ||
|
|
9302
|
+
(typeof document !== "undefined" ? document : null);
|
|
9303
|
+
if (doc && typeof global.CustomEvent !== "undefined") {
|
|
9304
|
+
doc.dispatchEvent(
|
|
9305
|
+
new global.CustomEvent("record-select:opened", {
|
|
9306
|
+
detail: { fieldId: fieldId, content: content },
|
|
9307
|
+
}),
|
|
9308
|
+
);
|
|
9060
9309
|
}
|
|
9061
|
-
}
|
|
9062
|
-
}
|
|
9063
|
-
|
|
9310
|
+
} catch (e) {}
|
|
9311
|
+
},
|
|
9312
|
+
onClose: function () {
|
|
9313
|
+
isOpen = false;
|
|
9314
|
+
container.classList.remove("open");
|
|
9315
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
9316
|
+
searchTerm = "";
|
|
9317
|
+
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
9318
|
+
else if (searchInputEl) searchInputEl.value = "";
|
|
9319
|
+
if (searchDebounceTimer) {
|
|
9320
|
+
clearTimeout(searchDebounceTimer);
|
|
9321
|
+
searchDebounceTimer = null;
|
|
9322
|
+
}
|
|
9323
|
+
},
|
|
9324
|
+
});
|
|
9064
9325
|
|
|
9065
|
-
if (clearBtn)
|
|
9326
|
+
if (clearBtn)
|
|
9327
|
+
clearBtn.style.display = canClear && value && !disabled ? "" : "none";
|
|
9066
9328
|
|
|
9067
9329
|
function setValue(newVal) {
|
|
9068
9330
|
value = newVal !== undefined && newVal !== null ? newVal : "";
|
|
@@ -9076,16 +9338,18 @@
|
|
|
9076
9338
|
|
|
9077
9339
|
function updateTriggerDisplay() {
|
|
9078
9340
|
if (selectedRecord) {
|
|
9079
|
-
triggerText.textContent =
|
|
9341
|
+
triggerText.textContent =
|
|
9342
|
+
selectedRecord.name || selectedRecord.label || value;
|
|
9080
9343
|
trigger.classList.remove("placeholder");
|
|
9081
9344
|
trigger.className = triggerClasses(
|
|
9082
9345
|
variant,
|
|
9083
9346
|
size,
|
|
9084
9347
|
disabled,
|
|
9085
9348
|
false,
|
|
9086
|
-
canClear && !!value && !disabled
|
|
9349
|
+
canClear && !!value && !disabled,
|
|
9087
9350
|
);
|
|
9088
|
-
triggerIcon.className =
|
|
9351
|
+
triggerIcon.className =
|
|
9352
|
+
"record-select-trigger-icon shrink-0 flex items-center justify-center size-20 rounded-4 overflow-hidden";
|
|
9089
9353
|
triggerIcon.innerHTML = "";
|
|
9090
9354
|
if (objectSlug === STANDARD_OBJECT_SLUGS_USERS) {
|
|
9091
9355
|
var Avatar = getAvatar();
|
|
@@ -9097,7 +9361,9 @@
|
|
|
9097
9361
|
});
|
|
9098
9362
|
triggerIcon.appendChild(vividEl);
|
|
9099
9363
|
} else {
|
|
9100
|
-
renderStaticIconPlaceholder(
|
|
9364
|
+
renderStaticIconPlaceholder(
|
|
9365
|
+
selectedRecord.name || selectedRecord.label,
|
|
9366
|
+
);
|
|
9101
9367
|
}
|
|
9102
9368
|
} else {
|
|
9103
9369
|
renderStaticObjectIcon();
|
|
@@ -9110,12 +9376,13 @@
|
|
|
9110
9376
|
size,
|
|
9111
9377
|
disabled,
|
|
9112
9378
|
true,
|
|
9113
|
-
canClear && !!value && !disabled
|
|
9379
|
+
canClear && !!value && !disabled,
|
|
9114
9380
|
);
|
|
9115
9381
|
triggerIcon.className = "record-select-trigger-icon shrink-0 hidden";
|
|
9116
9382
|
triggerIcon.innerHTML = "";
|
|
9117
9383
|
}
|
|
9118
|
-
if (clearBtn)
|
|
9384
|
+
if (clearBtn)
|
|
9385
|
+
clearBtn.style.display = canClear && value && !disabled ? "" : "none";
|
|
9119
9386
|
}
|
|
9120
9387
|
|
|
9121
9388
|
function renderStaticObjectIcon() {
|
|
@@ -9152,18 +9419,39 @@
|
|
|
9152
9419
|
var fields = ["id", "name"];
|
|
9153
9420
|
var actualLimit = limit || initialLimit;
|
|
9154
9421
|
var offset = page ? (page - 1) * actualLimit : 0;
|
|
9155
|
-
|
|
9422
|
+
|
|
9156
9423
|
try {
|
|
9157
9424
|
if (model && typeof model.select === "function") {
|
|
9158
9425
|
var q = model.select.apply(model, fields);
|
|
9426
|
+
var filters = [];
|
|
9427
|
+
var resolvedFilter =
|
|
9428
|
+
typeof initialFilter === "function"
|
|
9429
|
+
? initialFilter()
|
|
9430
|
+
: initialFilter;
|
|
9431
|
+
console.log(
|
|
9432
|
+
"[RecordSelect] initialFilter:",
|
|
9433
|
+
resolvedFilter,
|
|
9434
|
+
"| search:",
|
|
9435
|
+
search,
|
|
9436
|
+
);
|
|
9437
|
+
if (resolvedFilter) {
|
|
9438
|
+
filters = filters.concat(
|
|
9439
|
+
Array.isArray(resolvedFilter) ? resolvedFilter : [resolvedFilter],
|
|
9440
|
+
);
|
|
9441
|
+
}
|
|
9159
9442
|
if (search && search.trim()) {
|
|
9160
|
-
|
|
9443
|
+
filters.push({
|
|
9161
9444
|
or: [
|
|
9162
9445
|
{ field: "name", operator: "contains", value: search.trim() },
|
|
9163
9446
|
{ field: "id", operator: "eq", value: search.trim() },
|
|
9164
9447
|
],
|
|
9165
9448
|
});
|
|
9166
9449
|
}
|
|
9450
|
+
if (filters.length > 0) {
|
|
9451
|
+
q = q.filterBy(
|
|
9452
|
+
filters.length === 1 ? filters[0] : { and: filters },
|
|
9453
|
+
);
|
|
9454
|
+
}
|
|
9167
9455
|
var orderBy = ["name"];
|
|
9168
9456
|
if (objectSlug === "account") orderBy.push("-ParentId");
|
|
9169
9457
|
return q
|
|
@@ -9226,7 +9514,12 @@
|
|
|
9226
9514
|
updateTriggerDisplay();
|
|
9227
9515
|
})
|
|
9228
9516
|
.catch(function () {
|
|
9229
|
-
selectedRecord = {
|
|
9517
|
+
selectedRecord = {
|
|
9518
|
+
id: value,
|
|
9519
|
+
value: value,
|
|
9520
|
+
name: value,
|
|
9521
|
+
label: value,
|
|
9522
|
+
};
|
|
9230
9523
|
updateTriggerDisplay();
|
|
9231
9524
|
});
|
|
9232
9525
|
}
|
|
@@ -9237,7 +9530,9 @@
|
|
|
9237
9530
|
loadWrap.className =
|
|
9238
9531
|
"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";
|
|
9239
9532
|
if (Spinner && typeof Spinner.create === "function") {
|
|
9240
|
-
loadWrap.appendChild(
|
|
9533
|
+
loadWrap.appendChild(
|
|
9534
|
+
Spinner.create({ size: "small", text: "Loading..." }),
|
|
9535
|
+
);
|
|
9241
9536
|
} else {
|
|
9242
9537
|
var loadText = document.createElement("span");
|
|
9243
9538
|
loadText.textContent = "Loading...";
|
|
@@ -9245,12 +9540,12 @@
|
|
|
9245
9540
|
}
|
|
9246
9541
|
optionsList.appendChild(loadWrap);
|
|
9247
9542
|
}
|
|
9248
|
-
|
|
9543
|
+
|
|
9249
9544
|
function showLoadingMore() {
|
|
9250
9545
|
// Remove existing loading more indicator
|
|
9251
9546
|
var existing = optionsList.querySelector(".record-select-loading-more");
|
|
9252
9547
|
if (existing) existing.remove();
|
|
9253
|
-
|
|
9548
|
+
|
|
9254
9549
|
var loadWrap = document.createElement("div");
|
|
9255
9550
|
loadWrap.className =
|
|
9256
9551
|
"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";
|
|
@@ -9263,9 +9558,11 @@
|
|
|
9263
9558
|
}
|
|
9264
9559
|
optionsList.appendChild(loadWrap);
|
|
9265
9560
|
}
|
|
9266
|
-
|
|
9561
|
+
|
|
9267
9562
|
function removeLoadingMore() {
|
|
9268
|
-
var loadingMore = optionsList.querySelector(
|
|
9563
|
+
var loadingMore = optionsList.querySelector(
|
|
9564
|
+
".record-select-loading-more",
|
|
9565
|
+
);
|
|
9269
9566
|
if (loadingMore) loadingMore.remove();
|
|
9270
9567
|
}
|
|
9271
9568
|
|
|
@@ -9284,13 +9581,15 @@
|
|
|
9284
9581
|
existingOptions.forEach(function (opt) {
|
|
9285
9582
|
opt.remove();
|
|
9286
9583
|
});
|
|
9287
|
-
|
|
9584
|
+
|
|
9288
9585
|
// Remove old loading/empty states
|
|
9289
|
-
var oldStates = optionsList.querySelectorAll(
|
|
9586
|
+
var oldStates = optionsList.querySelectorAll(
|
|
9587
|
+
".record-select-loading, .record-select-empty",
|
|
9588
|
+
);
|
|
9290
9589
|
oldStates.forEach(function (el) {
|
|
9291
9590
|
el.remove();
|
|
9292
9591
|
});
|
|
9293
|
-
|
|
9592
|
+
|
|
9294
9593
|
filteredRecords.forEach(function (rec) {
|
|
9295
9594
|
var optionValue = rec.id || rec.value;
|
|
9296
9595
|
var optionLabel = rec.name || rec.label || rec.value;
|
|
@@ -9305,7 +9604,7 @@
|
|
|
9305
9604
|
"hover:bg-fill-tertiary-fill-light-gray focus:bg-fill-tertiary-fill-light-gray",
|
|
9306
9605
|
isSelected
|
|
9307
9606
|
? "bg-primary-surface hover:!bg-primary-surface-hover"
|
|
9308
|
-
: ""
|
|
9607
|
+
: "",
|
|
9309
9608
|
);
|
|
9310
9609
|
|
|
9311
9610
|
var optContent = document.createElement("span");
|
|
@@ -9363,70 +9662,93 @@
|
|
|
9363
9662
|
|
|
9364
9663
|
optionsList.appendChild(option);
|
|
9365
9664
|
});
|
|
9366
|
-
|
|
9665
|
+
|
|
9367
9666
|
// Add loading more indicator at the bottom if fetching
|
|
9368
9667
|
if (isFetchingMore) {
|
|
9369
9668
|
showLoadingMore();
|
|
9370
9669
|
}
|
|
9371
9670
|
}
|
|
9372
9671
|
|
|
9672
|
+
function scheduleUpdatePosition() {
|
|
9673
|
+
if (popover && typeof popover.updatePosition === "function") {
|
|
9674
|
+
requestAnimationFrame(function () {
|
|
9675
|
+
requestAnimationFrame(function () {
|
|
9676
|
+
popover.updatePosition();
|
|
9677
|
+
});
|
|
9678
|
+
});
|
|
9679
|
+
}
|
|
9680
|
+
}
|
|
9681
|
+
|
|
9373
9682
|
function loadInitialAndRender() {
|
|
9374
9683
|
showLoading();
|
|
9375
9684
|
currentPage = 1;
|
|
9376
9685
|
hasMoreRecords = true;
|
|
9377
9686
|
totalFetched = 0;
|
|
9378
|
-
|
|
9379
|
-
fetchRecords(searchTerm, initialLimit, 1)
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9687
|
+
|
|
9688
|
+
fetchRecords(searchTerm, initialLimit, 1)
|
|
9689
|
+
.then(function (result) {
|
|
9690
|
+
allRecords = result.records;
|
|
9691
|
+
filteredRecords = result.records;
|
|
9692
|
+
hasMoreRecords = result.hasMore;
|
|
9693
|
+
totalFetched = result.records.length;
|
|
9694
|
+
currentPage = 1;
|
|
9695
|
+
|
|
9696
|
+
if (
|
|
9697
|
+
value &&
|
|
9698
|
+
!result.records.some(function (r) {
|
|
9699
|
+
return (r.id || r.value) === value;
|
|
9700
|
+
})
|
|
9701
|
+
) {
|
|
9702
|
+
loadSelectedRecord();
|
|
9703
|
+
} else if (value && result.records.length) {
|
|
9704
|
+
var sel = result.records.find(function (r) {
|
|
9705
|
+
return (r.id || r.value) === value;
|
|
9706
|
+
});
|
|
9707
|
+
if (sel) selectedRecord = sel;
|
|
9708
|
+
updateTriggerDisplay();
|
|
9709
|
+
}
|
|
9710
|
+
if (filteredRecords.length === 0) {
|
|
9711
|
+
showEmpty(searchTerm ? "No results found" : "No records available");
|
|
9712
|
+
} else {
|
|
9713
|
+
renderOptions();
|
|
9714
|
+
}
|
|
9715
|
+
scheduleUpdatePosition();
|
|
9716
|
+
})
|
|
9717
|
+
.catch(function () {
|
|
9718
|
+
showEmpty("Failed to load records");
|
|
9719
|
+
hasMoreRecords = false;
|
|
9720
|
+
scheduleUpdatePosition();
|
|
9721
|
+
});
|
|
9402
9722
|
}
|
|
9403
|
-
|
|
9723
|
+
|
|
9404
9724
|
function loadMoreRecords() {
|
|
9405
9725
|
if (isFetchingMore || !hasMoreRecords) return;
|
|
9406
|
-
|
|
9726
|
+
|
|
9407
9727
|
isFetchingMore = true;
|
|
9408
9728
|
currentPage += 1;
|
|
9409
9729
|
showLoadingMore();
|
|
9410
|
-
|
|
9411
|
-
fetchRecords(searchTerm, initialLimit, currentPage)
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
|
|
9730
|
+
|
|
9731
|
+
fetchRecords(searchTerm, initialLimit, currentPage)
|
|
9732
|
+
.then(function (result) {
|
|
9733
|
+
isFetchingMore = false;
|
|
9734
|
+
removeLoadingMore();
|
|
9735
|
+
|
|
9736
|
+
if (result.records.length > 0) {
|
|
9737
|
+
allRecords = allRecords.concat(result.records);
|
|
9738
|
+
filteredRecords = filteredRecords.concat(result.records);
|
|
9739
|
+
totalFetched += result.records.length;
|
|
9740
|
+
hasMoreRecords = result.hasMore;
|
|
9741
|
+
renderOptions();
|
|
9742
|
+
} else {
|
|
9743
|
+
hasMoreRecords = false;
|
|
9744
|
+
}
|
|
9745
|
+
})
|
|
9746
|
+
.catch(function (err) {
|
|
9747
|
+
console.error("[RecordSelect] loadMoreRecords error:", err);
|
|
9748
|
+
isFetchingMore = false;
|
|
9749
|
+
removeLoadingMore();
|
|
9422
9750
|
hasMoreRecords = false;
|
|
9423
|
-
}
|
|
9424
|
-
}).catch(function (err) {
|
|
9425
|
-
console.error("[RecordSelect] loadMoreRecords error:", err);
|
|
9426
|
-
isFetchingMore = false;
|
|
9427
|
-
removeLoadingMore();
|
|
9428
|
-
hasMoreRecords = false;
|
|
9429
|
-
});
|
|
9751
|
+
});
|
|
9430
9752
|
}
|
|
9431
9753
|
|
|
9432
9754
|
function debouncedSearch() {
|
|
@@ -9437,83 +9759,31 @@
|
|
|
9437
9759
|
currentPage = 1;
|
|
9438
9760
|
hasMoreRecords = true;
|
|
9439
9761
|
totalFetched = 0;
|
|
9440
|
-
|
|
9441
|
-
fetchRecords(searchTerm, initialLimit, 1).then(function (result) {
|
|
9442
|
-
allRecords = result.records;
|
|
9443
|
-
filteredRecords = result.records;
|
|
9444
|
-
hasMoreRecords = result.hasMore;
|
|
9445
|
-
totalFetched = result.records.length;
|
|
9446
|
-
|
|
9447
|
-
if (result.records.length === 0) {
|
|
9448
|
-
showEmpty("No results found");
|
|
9449
|
-
} else {
|
|
9450
|
-
renderOptions();
|
|
9451
|
-
}
|
|
9452
|
-
}).catch(function () {
|
|
9453
|
-
showEmpty("Search failed");
|
|
9454
|
-
hasMoreRecords = false;
|
|
9455
|
-
});
|
|
9456
|
-
}, 500);
|
|
9457
|
-
}
|
|
9458
9762
|
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
document
|
|
9466
|
-
.querySelectorAll(".custom-select.open, .record-select.open")
|
|
9467
|
-
.forEach(function (other) {
|
|
9468
|
-
if (other !== container) {
|
|
9469
|
-
other.classList.remove("open");
|
|
9470
|
-
var t = other.querySelector(
|
|
9471
|
-
"button, .custom-select-trigger, .record-select-trigger"
|
|
9472
|
-
);
|
|
9473
|
-
if (t) t.setAttribute("aria-expanded", "false");
|
|
9474
|
-
}
|
|
9475
|
-
});
|
|
9476
|
-
isOpen = true;
|
|
9477
|
-
container.classList.add("open");
|
|
9478
|
-
trigger.setAttribute("aria-expanded", "true");
|
|
9479
|
-
searchTerm = "";
|
|
9480
|
-
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
9481
|
-
else if (searchInputEl) searchInputEl.value = "";
|
|
9482
|
-
loadInitialAndRender();
|
|
9483
|
-
setTimeout(function () {
|
|
9484
|
-
if (searchInputEl) searchInputEl.focus();
|
|
9485
|
-
}, 0);
|
|
9486
|
-
updatePosition();
|
|
9487
|
-
}
|
|
9763
|
+
fetchRecords(searchTerm, initialLimit, 1)
|
|
9764
|
+
.then(function (result) {
|
|
9765
|
+
allRecords = result.records;
|
|
9766
|
+
filteredRecords = result.records;
|
|
9767
|
+
hasMoreRecords = result.hasMore;
|
|
9768
|
+
totalFetched = result.records.length;
|
|
9488
9769
|
|
|
9489
|
-
|
|
9490
|
-
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
searchDebounceTimer = null;
|
|
9503
|
-
}
|
|
9770
|
+
if (result.records.length === 0) {
|
|
9771
|
+
showEmpty("No results found");
|
|
9772
|
+
} else {
|
|
9773
|
+
renderOptions();
|
|
9774
|
+
}
|
|
9775
|
+
scheduleUpdatePosition();
|
|
9776
|
+
})
|
|
9777
|
+
.catch(function () {
|
|
9778
|
+
showEmpty("Search failed");
|
|
9779
|
+
hasMoreRecords = false;
|
|
9780
|
+
scheduleUpdatePosition();
|
|
9781
|
+
});
|
|
9782
|
+
}, 500);
|
|
9504
9783
|
}
|
|
9505
9784
|
|
|
9506
|
-
function
|
|
9507
|
-
|
|
9508
|
-
var rect = trigger.getBoundingClientRect();
|
|
9509
|
-
var vh = window.innerHeight;
|
|
9510
|
-
var below = vh - rect.bottom;
|
|
9511
|
-
var above = rect.top;
|
|
9512
|
-
if (below < 200 && above > below) {
|
|
9513
|
-
content.className = contentBase + "bottom-full mb-1 translate-y-1 group-[.open]:translate-y-0";
|
|
9514
|
-
} else {
|
|
9515
|
-
content.className = contentBase + "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
|
|
9516
|
-
}
|
|
9785
|
+
function closeDropdown() {
|
|
9786
|
+
popover.hide();
|
|
9517
9787
|
}
|
|
9518
9788
|
|
|
9519
9789
|
if (!searchInputWrapper && searchInputEl) {
|
|
@@ -9532,41 +9802,14 @@
|
|
|
9532
9802
|
});
|
|
9533
9803
|
}
|
|
9534
9804
|
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
9539
|
-
e.preventDefault();
|
|
9540
|
-
if (isOpen) popover.hide();
|
|
9541
|
-
else popover.show();
|
|
9542
|
-
}
|
|
9543
|
-
});
|
|
9544
|
-
} else {
|
|
9545
|
-
trigger.addEventListener("click", function (e) {
|
|
9805
|
+
trigger.addEventListener("keydown", function (e) {
|
|
9806
|
+
if (disabled) return;
|
|
9807
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
9546
9808
|
e.preventDefault();
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
trigger.addEventListener("keydown", function (e) {
|
|
9552
|
-
if (disabled) return;
|
|
9553
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
9554
|
-
e.preventDefault();
|
|
9555
|
-
if (isOpen) closeDropdown();
|
|
9556
|
-
else openDropdown();
|
|
9557
|
-
}
|
|
9558
|
-
if (e.key === "Escape" && isOpen) {
|
|
9559
|
-
e.preventDefault();
|
|
9560
|
-
closeDropdown();
|
|
9561
|
-
}
|
|
9562
|
-
});
|
|
9563
|
-
document.addEventListener("click", function (e) {
|
|
9564
|
-
if (isOpen && !container.contains(e.target)) closeDropdown();
|
|
9565
|
-
});
|
|
9566
|
-
document.addEventListener("keydown", function (e) {
|
|
9567
|
-
if (e.key === "Escape" && isOpen) closeDropdown();
|
|
9568
|
-
});
|
|
9569
|
-
}
|
|
9809
|
+
if (isOpen) popover.hide();
|
|
9810
|
+
else popover.show();
|
|
9811
|
+
}
|
|
9812
|
+
});
|
|
9570
9813
|
|
|
9571
9814
|
container.updateValue = function (newVal) {
|
|
9572
9815
|
setValue(newVal);
|
|
@@ -9580,7 +9823,7 @@
|
|
|
9580
9823
|
size,
|
|
9581
9824
|
disabled,
|
|
9582
9825
|
!value,
|
|
9583
|
-
canClear && !!value && !disabled
|
|
9826
|
+
canClear && !!value && !disabled,
|
|
9584
9827
|
);
|
|
9585
9828
|
if (disabled && isOpen) closeDropdown();
|
|
9586
9829
|
};
|
|
@@ -9599,7 +9842,7 @@
|
|
|
9599
9842
|
|
|
9600
9843
|
|
|
9601
9844
|
// ============================================
|
|
9602
|
-
// File 18/
|
|
9845
|
+
// File 18/41: components/multiselect.js
|
|
9603
9846
|
// ============================================
|
|
9604
9847
|
|
|
9605
9848
|
/**
|
|
@@ -9663,6 +9906,14 @@
|
|
|
9663
9906
|
return opt.label || opt.name || opt.display_name || opt.value;
|
|
9664
9907
|
}
|
|
9665
9908
|
|
|
9909
|
+
function getDep(name) {
|
|
9910
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
9911
|
+
var c = global.FlowUI._getComponent(name);
|
|
9912
|
+
if (c) return c;
|
|
9913
|
+
}
|
|
9914
|
+
return global[name];
|
|
9915
|
+
}
|
|
9916
|
+
|
|
9666
9917
|
/**
|
|
9667
9918
|
* Create a multiselect dropdown component
|
|
9668
9919
|
* @param {Object} config
|
|
@@ -9693,6 +9944,11 @@
|
|
|
9693
9944
|
? config.values.slice()
|
|
9694
9945
|
: [];
|
|
9695
9946
|
|
|
9947
|
+
var Popover = getDep("Popover");
|
|
9948
|
+
if (!Popover || typeof Popover.create !== "function") {
|
|
9949
|
+
throw new Error("MultiSelect requires Popover");
|
|
9950
|
+
}
|
|
9951
|
+
|
|
9696
9952
|
var container = document.createElement("div");
|
|
9697
9953
|
container.className = "custom-multiselect relative w-full group";
|
|
9698
9954
|
if (fieldId) container.setAttribute("data-field-id", fieldId);
|
|
@@ -9741,18 +9997,14 @@
|
|
|
9741
9997
|
triggerWrapper.appendChild(trigger);
|
|
9742
9998
|
container.appendChild(triggerWrapper);
|
|
9743
9999
|
|
|
9744
|
-
var contentBase =
|
|
9745
|
-
"custom-multiselect-content absolute left-0 right-0 z-50 max-h-[200px] min-w-[8rem] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium opacity-0 invisible transition-all duration-150 ease-out " +
|
|
9746
|
-
"group-[.open]:opacity-100 group-[.open]:visible ";
|
|
9747
|
-
|
|
9748
10000
|
var content = document.createElement("div");
|
|
9749
10001
|
content.setAttribute("role", "listbox");
|
|
9750
10002
|
content.setAttribute("aria-multiselectable", "true");
|
|
9751
|
-
content.className =
|
|
10003
|
+
content.className = "custom-multiselect-content w-full max-h-[45vh] overflow-hidden flex flex-col";
|
|
9752
10004
|
|
|
9753
10005
|
var optionsList = document.createElement("div");
|
|
9754
10006
|
optionsList.className =
|
|
9755
|
-
"overflow-y-auto max-h-[
|
|
10007
|
+
"overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white";
|
|
9756
10008
|
|
|
9757
10009
|
function isSelected(optionValue) {
|
|
9758
10010
|
return values.some(function (v) {
|
|
@@ -9849,47 +10101,68 @@
|
|
|
9849
10101
|
buildOptionsList();
|
|
9850
10102
|
|
|
9851
10103
|
content.appendChild(optionsList);
|
|
9852
|
-
container.appendChild(content);
|
|
9853
10104
|
|
|
9854
|
-
var
|
|
10105
|
+
var popover = Popover.create({
|
|
10106
|
+
trigger: trigger,
|
|
10107
|
+
content: content,
|
|
10108
|
+
placement: "bottom",
|
|
10109
|
+
align: "start",
|
|
10110
|
+
closeOnClickOutside: true,
|
|
10111
|
+
bodyClassName: "p-0 overflow-hidden",
|
|
10112
|
+
panelClassName: "min-w-[var(--trigger-width)] max-h-[45vh] overflow-hidden",
|
|
10113
|
+
onOpen: function () {
|
|
10114
|
+
if (disabled) {
|
|
10115
|
+
popover.hide();
|
|
10116
|
+
return;
|
|
10117
|
+
}
|
|
10118
|
+
document
|
|
10119
|
+
.querySelectorAll(".custom-select, .record-select, .custom-multiselect, .enum-select, .enum-multiselect, .record-multiselect")
|
|
10120
|
+
.forEach(function (other) {
|
|
10121
|
+
if (other !== container && other.popoverInstance) {
|
|
10122
|
+
other.popoverInstance.hide();
|
|
10123
|
+
}
|
|
10124
|
+
});
|
|
10125
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
10126
|
+
chevron.style.transform = "rotate(180deg)";
|
|
10127
|
+
if (popover.panel) {
|
|
10128
|
+
var triggerWidthPx = trigger.offsetWidth + "px";
|
|
10129
|
+
popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
|
|
10130
|
+
popover.panel.style.minWidth = triggerWidthPx;
|
|
10131
|
+
popover.panel.style.width = triggerWidthPx;
|
|
10132
|
+
}
|
|
10133
|
+
},
|
|
10134
|
+
onClose: function () {
|
|
10135
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
10136
|
+
chevron.style.transform = "";
|
|
10137
|
+
},
|
|
10138
|
+
});
|
|
10139
|
+
container.popoverInstance = popover;
|
|
9855
10140
|
|
|
9856
10141
|
function openDropdown() {
|
|
9857
10142
|
if (disabled) return;
|
|
9858
|
-
|
|
9859
|
-
.querySelectorAll(".custom-select.open, .record-select.open, .custom-multiselect.open")
|
|
9860
|
-
.forEach(function (other) {
|
|
9861
|
-
if (other !== container) {
|
|
9862
|
-
other.classList.remove("open");
|
|
9863
|
-
var t = other.querySelector(
|
|
9864
|
-
"button, .custom-select-trigger, .record-select-trigger, .multiselect-trigger-wrapper button"
|
|
9865
|
-
);
|
|
9866
|
-
if (t) t.setAttribute("aria-expanded", "false");
|
|
9867
|
-
}
|
|
9868
|
-
});
|
|
9869
|
-
isOpen = true;
|
|
9870
|
-
container.classList.add("open");
|
|
9871
|
-
trigger.setAttribute("aria-expanded", "true");
|
|
10143
|
+
popover.show();
|
|
9872
10144
|
}
|
|
9873
10145
|
|
|
9874
10146
|
function closeDropdown() {
|
|
9875
|
-
|
|
9876
|
-
container.classList.remove("open");
|
|
9877
|
-
trigger.setAttribute("aria-expanded", "false");
|
|
10147
|
+
popover.hide();
|
|
9878
10148
|
}
|
|
9879
10149
|
|
|
9880
10150
|
function toggleDropdown() {
|
|
9881
|
-
|
|
10151
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
10152
|
+
if (isVisible) closeDropdown();
|
|
9882
10153
|
else openDropdown();
|
|
9883
10154
|
}
|
|
9884
10155
|
|
|
9885
10156
|
trigger.addEventListener("click", function (e) {
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
10157
|
+
if (disabled) {
|
|
10158
|
+
e.preventDefault();
|
|
10159
|
+
e.stopImmediatePropagation();
|
|
10160
|
+
}
|
|
10161
|
+
}, true);
|
|
9890
10162
|
|
|
9891
10163
|
trigger.addEventListener("keydown", function (e) {
|
|
9892
10164
|
if (disabled) return;
|
|
10165
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
9893
10166
|
switch (e.key) {
|
|
9894
10167
|
case "Enter":
|
|
9895
10168
|
case " ":
|
|
@@ -9898,14 +10171,14 @@
|
|
|
9898
10171
|
break;
|
|
9899
10172
|
case "ArrowDown":
|
|
9900
10173
|
e.preventDefault();
|
|
9901
|
-
if (!
|
|
10174
|
+
if (!isVisible) openDropdown();
|
|
9902
10175
|
break;
|
|
9903
10176
|
case "ArrowUp":
|
|
9904
10177
|
e.preventDefault();
|
|
9905
|
-
if (!
|
|
10178
|
+
if (!isVisible) openDropdown();
|
|
9906
10179
|
break;
|
|
9907
10180
|
case "Escape":
|
|
9908
|
-
if (
|
|
10181
|
+
if (isVisible) {
|
|
9909
10182
|
e.preventDefault();
|
|
9910
10183
|
closeDropdown();
|
|
9911
10184
|
}
|
|
@@ -9913,13 +10186,6 @@
|
|
|
9913
10186
|
}
|
|
9914
10187
|
});
|
|
9915
10188
|
|
|
9916
|
-
document.addEventListener("click", function (e) {
|
|
9917
|
-
if (isOpen && !container.contains(e.target)) closeDropdown();
|
|
9918
|
-
});
|
|
9919
|
-
document.addEventListener("keydown", function (e) {
|
|
9920
|
-
if (e.key === "Escape" && isOpen) closeDropdown();
|
|
9921
|
-
});
|
|
9922
|
-
|
|
9923
10189
|
container.updateValues = function (newValues) {
|
|
9924
10190
|
values = Array.isArray(newValues) ? newValues.slice() : [];
|
|
9925
10191
|
renderTriggerContent();
|
|
@@ -9938,7 +10204,8 @@
|
|
|
9938
10204
|
disabled = !!isDisabled;
|
|
9939
10205
|
trigger.disabled = disabled;
|
|
9940
10206
|
trigger.className = triggerClasses(variant, size, disabled, values.length === 0);
|
|
9941
|
-
|
|
10207
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
10208
|
+
if (disabled && isVisible) closeDropdown();
|
|
9942
10209
|
};
|
|
9943
10210
|
|
|
9944
10211
|
container.getValues = function () {
|
|
@@ -9956,7 +10223,7 @@
|
|
|
9956
10223
|
|
|
9957
10224
|
|
|
9958
10225
|
// ============================================
|
|
9959
|
-
// File 19/
|
|
10226
|
+
// File 19/41: components/enum-multiselect.js
|
|
9960
10227
|
// ============================================
|
|
9961
10228
|
|
|
9962
10229
|
/**
|
|
@@ -10036,6 +10303,14 @@
|
|
|
10036
10303
|
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
10037
10304
|
}
|
|
10038
10305
|
|
|
10306
|
+
function getDep(name) {
|
|
10307
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
10308
|
+
var c = global.FlowUI._getComponent(name);
|
|
10309
|
+
if (c) return c;
|
|
10310
|
+
}
|
|
10311
|
+
return global[name];
|
|
10312
|
+
}
|
|
10313
|
+
|
|
10039
10314
|
/** Resolve client: use FlowUI._getComponent when bundle has captured globals, else global.superleapClient */
|
|
10040
10315
|
function getClient() {
|
|
10041
10316
|
if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
|
|
@@ -10104,8 +10379,10 @@
|
|
|
10104
10379
|
var error = null;
|
|
10105
10380
|
var searchQuery = "";
|
|
10106
10381
|
var popover = null;
|
|
10107
|
-
var
|
|
10108
|
-
|
|
10382
|
+
var Popover = getDep("Popover");
|
|
10383
|
+
if (!Popover || typeof Popover.create !== "function") {
|
|
10384
|
+
throw new Error("EnumMultiSelect requires Popover");
|
|
10385
|
+
}
|
|
10109
10386
|
|
|
10110
10387
|
var container = document.createElement("div");
|
|
10111
10388
|
container.className = "enum-multiselect relative w-full group";
|
|
@@ -10207,13 +10484,7 @@
|
|
|
10207
10484
|
var content = document.createElement("div");
|
|
10208
10485
|
content.setAttribute("role", "listbox");
|
|
10209
10486
|
content.setAttribute("aria-multiselectable", "true");
|
|
10210
|
-
|
|
10211
|
-
if (!usePopover) {
|
|
10212
|
-
contentBase += " absolute left-0 right-0 z-50 max-h-[30vh] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium border-1/2 border-border-primary opacity-0 invisible transition-all duration-150 ease-out group-[.open]:opacity-100 group-[.open]:visible top-full mt-1 -translate-y-1 group-[.open]:translate-y-0 flex flex-col";
|
|
10213
|
-
} else {
|
|
10214
|
-
contentBase += " max-h-[30vh] overflow-hidden flex flex-col";
|
|
10215
|
-
}
|
|
10216
|
-
content.className = contentBase;
|
|
10487
|
+
content.className = "w-full min-w-[200px] max-h-[45vh] overflow-hidden flex flex-col";
|
|
10217
10488
|
|
|
10218
10489
|
// Search input (using InputComponent like enum-select)
|
|
10219
10490
|
var searchContainer = document.createElement("div");
|
|
@@ -10274,15 +10545,11 @@
|
|
|
10274
10545
|
// Options list
|
|
10275
10546
|
var optionsList = document.createElement("div");
|
|
10276
10547
|
optionsList.className =
|
|
10277
|
-
"overflow-y-auto max-h-[
|
|
10548
|
+
"overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white flex-1 min-h-0";
|
|
10278
10549
|
|
|
10279
10550
|
content.appendChild(searchContainer);
|
|
10280
10551
|
content.appendChild(optionsList);
|
|
10281
10552
|
|
|
10282
|
-
if (!usePopover) {
|
|
10283
|
-
container.appendChild(content);
|
|
10284
|
-
}
|
|
10285
|
-
|
|
10286
10553
|
var highlightedIndex = -1;
|
|
10287
10554
|
|
|
10288
10555
|
function showLoading() {
|
|
@@ -10455,34 +10722,14 @@
|
|
|
10455
10722
|
|
|
10456
10723
|
function openDropdown() {
|
|
10457
10724
|
if (disabled) return;
|
|
10458
|
-
if (popover) {
|
|
10459
|
-
document
|
|
10460
|
-
.querySelectorAll(".enum-select, .enum-multiselect, .custom-select, .record-select, .custom-multiselect")
|
|
10461
|
-
.forEach(function (other) {
|
|
10462
|
-
if (other !== container && other.popoverInstance) {
|
|
10463
|
-
other.popoverInstance.hide();
|
|
10464
|
-
}
|
|
10465
|
-
});
|
|
10466
|
-
popover.show();
|
|
10467
|
-
trigger.setAttribute("aria-expanded", "true");
|
|
10468
|
-
if (searchInput) {
|
|
10469
|
-
setTimeout(function () {
|
|
10470
|
-
searchInput.focus();
|
|
10471
|
-
}, 50);
|
|
10472
|
-
}
|
|
10473
|
-
return;
|
|
10474
|
-
}
|
|
10475
10725
|
document
|
|
10476
|
-
.querySelectorAll(".enum-multiselect.
|
|
10726
|
+
.querySelectorAll(".enum-select, .enum-multiselect, .custom-select, .record-select, .custom-multiselect")
|
|
10477
10727
|
.forEach(function (other) {
|
|
10478
|
-
if (other !== container) {
|
|
10479
|
-
other.
|
|
10480
|
-
var t = other.querySelector("button");
|
|
10481
|
-
if (t) t.setAttribute("aria-expanded", "false");
|
|
10728
|
+
if (other !== container && other.popoverInstance) {
|
|
10729
|
+
other.popoverInstance.hide();
|
|
10482
10730
|
}
|
|
10483
10731
|
});
|
|
10484
|
-
|
|
10485
|
-
container.classList.add("open");
|
|
10732
|
+
popover.show();
|
|
10486
10733
|
trigger.setAttribute("aria-expanded", "true");
|
|
10487
10734
|
if (searchInput) {
|
|
10488
10735
|
setTimeout(function () {
|
|
@@ -10492,12 +10739,7 @@
|
|
|
10492
10739
|
}
|
|
10493
10740
|
|
|
10494
10741
|
function closeDropdown() {
|
|
10495
|
-
|
|
10496
|
-
popover.hide();
|
|
10497
|
-
} else {
|
|
10498
|
-
isOpen = false;
|
|
10499
|
-
container.classList.remove("open");
|
|
10500
|
-
}
|
|
10742
|
+
popover.hide();
|
|
10501
10743
|
trigger.setAttribute("aria-expanded", "false");
|
|
10502
10744
|
highlightedIndex = -1;
|
|
10503
10745
|
clearSearch();
|
|
@@ -10505,9 +10747,7 @@
|
|
|
10505
10747
|
}
|
|
10506
10748
|
|
|
10507
10749
|
function toggleDropdown() {
|
|
10508
|
-
var isVisible = popover
|
|
10509
|
-
? popover.element && popover.element.classList.contains("visible")
|
|
10510
|
-
: isOpen;
|
|
10750
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
10511
10751
|
if (isVisible) {
|
|
10512
10752
|
closeDropdown();
|
|
10513
10753
|
} else {
|
|
@@ -10587,10 +10827,7 @@
|
|
|
10587
10827
|
|
|
10588
10828
|
// Initialize Popover
|
|
10589
10829
|
function initializePopover() {
|
|
10590
|
-
|
|
10591
|
-
return;
|
|
10592
|
-
}
|
|
10593
|
-
popover = global.Popover.create({
|
|
10830
|
+
popover = Popover.create({
|
|
10594
10831
|
trigger: trigger,
|
|
10595
10832
|
content: content,
|
|
10596
10833
|
placement: "bottom",
|
|
@@ -10606,6 +10843,12 @@
|
|
|
10606
10843
|
onOpen: function () {
|
|
10607
10844
|
trigger.setAttribute("aria-expanded", "true");
|
|
10608
10845
|
chevron.style.transform = "rotate(180deg)";
|
|
10846
|
+
if (popover.panel) {
|
|
10847
|
+
var triggerWidthPx = trigger.offsetWidth + "px";
|
|
10848
|
+
popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
|
|
10849
|
+
popover.panel.style.minWidth = triggerWidthPx;
|
|
10850
|
+
popover.panel.style.width = triggerWidthPx;
|
|
10851
|
+
}
|
|
10609
10852
|
},
|
|
10610
10853
|
bodyClassName: "p-0 overflow-hidden",
|
|
10611
10854
|
panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
|
|
@@ -10613,13 +10856,6 @@
|
|
|
10613
10856
|
|
|
10614
10857
|
// Store popover instance for cleanup
|
|
10615
10858
|
container.popoverInstance = popover;
|
|
10616
|
-
|
|
10617
|
-
// Set CSS variable for trigger width
|
|
10618
|
-
var triggerWidth = trigger.offsetWidth;
|
|
10619
|
-
if (popover.panel) {
|
|
10620
|
-
popover.panel.style.setProperty("--trigger-width", triggerWidth + "px");
|
|
10621
|
-
popover.panel.style.minWidth = triggerWidth + "px";
|
|
10622
|
-
}
|
|
10623
10859
|
}
|
|
10624
10860
|
|
|
10625
10861
|
// Load options from SDK
|
|
@@ -10734,21 +10970,6 @@
|
|
|
10734
10970
|
initializePopover();
|
|
10735
10971
|
loadOptions();
|
|
10736
10972
|
|
|
10737
|
-
if (!usePopover) {
|
|
10738
|
-
trigger.addEventListener("click", function (e) {
|
|
10739
|
-
e.preventDefault();
|
|
10740
|
-
e.stopPropagation();
|
|
10741
|
-
if (disabled) return;
|
|
10742
|
-
toggleDropdown();
|
|
10743
|
-
});
|
|
10744
|
-
document.addEventListener("click", function (e) {
|
|
10745
|
-
if (isOpen && !container.contains(e.target)) closeDropdown();
|
|
10746
|
-
});
|
|
10747
|
-
document.addEventListener("keydown", function (e) {
|
|
10748
|
-
if (e.key === "Escape" && isOpen) closeDropdown();
|
|
10749
|
-
});
|
|
10750
|
-
}
|
|
10751
|
-
|
|
10752
10973
|
// Public API
|
|
10753
10974
|
container.updateValues = function (newValues) {
|
|
10754
10975
|
values = Array.isArray(newValues) ? newValues.slice() : [];
|
|
@@ -10790,7 +11011,7 @@
|
|
|
10790
11011
|
);
|
|
10791
11012
|
updateClearButton();
|
|
10792
11013
|
var isVisible = popover && popover.element && popover.element.classList.contains("visible");
|
|
10793
|
-
if (disabled &&
|
|
11014
|
+
if (disabled && isVisible) closeDropdown();
|
|
10794
11015
|
};
|
|
10795
11016
|
|
|
10796
11017
|
container.reload = function () {
|
|
@@ -10826,7 +11047,7 @@
|
|
|
10826
11047
|
|
|
10827
11048
|
|
|
10828
11049
|
// ============================================
|
|
10829
|
-
// File 20/
|
|
11050
|
+
// File 20/41: components/record-multiselect.js
|
|
10830
11051
|
// ============================================
|
|
10831
11052
|
|
|
10832
11053
|
/**
|
|
@@ -10840,7 +11061,14 @@
|
|
|
10840
11061
|
|
|
10841
11062
|
(function (global) {
|
|
10842
11063
|
|
|
10843
|
-
|
|
11064
|
+
function getDep(name) {
|
|
11065
|
+
if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
|
|
11066
|
+
var c = global.FlowUI._getComponent(name);
|
|
11067
|
+
if (c) return c;
|
|
11068
|
+
}
|
|
11069
|
+
return global[name];
|
|
11070
|
+
}
|
|
11071
|
+
|
|
10844
11072
|
var InputComponent = global.InputComponent;
|
|
10845
11073
|
var Spinner = global.Spinner;
|
|
10846
11074
|
|
|
@@ -10853,7 +11081,7 @@
|
|
|
10853
11081
|
role: { iconStr: "IconShield", color: "info" },
|
|
10854
11082
|
iframe: { iconStr: "IconLayout", color: "neutral" },
|
|
10855
11083
|
lead: { iconStr: "IconUser", color: "primary" },
|
|
10856
|
-
opportunity: { iconStr: "
|
|
11084
|
+
opportunity: { iconStr: "IconStar", color: "success" },
|
|
10857
11085
|
call_log: { iconStr: "IconPhone", color: "info" },
|
|
10858
11086
|
communication: { iconStr: "IconMessage", color: "primary" },
|
|
10859
11087
|
history_field: { iconStr: "IconClock", color: "neutral" },
|
|
@@ -10975,6 +11203,7 @@
|
|
|
10975
11203
|
* @param {string} [config.size] - 'default' | 'large' | 'small'
|
|
10976
11204
|
* @param {number} [config.initialLimit] - Initial fetch limit (default 50)
|
|
10977
11205
|
* @param {Array<string>} [config.displayFields] - Fields to display as secondary info (e.g. ["email", "phone"])
|
|
11206
|
+
* @param {Object} [config.initialFilter] - Optional filter object to merge with search (e.g. { field: "status", operator: "exact", value: "active" } or { and: [...] })
|
|
10978
11207
|
* @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)
|
|
10979
11208
|
* @returns {HTMLElement} Record multiselect container element
|
|
10980
11209
|
*/
|
|
@@ -10989,6 +11218,7 @@
|
|
|
10989
11218
|
var variant = config.variant || "default";
|
|
10990
11219
|
var size = config.size || "default";
|
|
10991
11220
|
var initialLimit = config.initialLimit != null ? config.initialLimit : 50;
|
|
11221
|
+
var initialFilter = config.initialFilter || null; // Can be array, object, or function returning either
|
|
10992
11222
|
var displayFields = config.displayFields || [];
|
|
10993
11223
|
|
|
10994
11224
|
var disabled = config.disabled === true;
|
|
@@ -11013,19 +11243,13 @@
|
|
|
11013
11243
|
var selectedRecords = [];
|
|
11014
11244
|
var allRecords = [];
|
|
11015
11245
|
var filteredRecords = [];
|
|
11016
|
-
var isOpen = false;
|
|
11017
11246
|
var searchTerm = "";
|
|
11018
11247
|
var searchDebounceTimer = null;
|
|
11019
|
-
var usePopover = Popover && typeof Popover.create === "function";
|
|
11020
11248
|
var popover = null;
|
|
11021
11249
|
var hasMoreRecords = true;
|
|
11022
11250
|
var currentPage = 1;
|
|
11023
11251
|
var isFetchingMore = false;
|
|
11024
11252
|
var totalFetched = 0;
|
|
11025
|
-
var contentBase = "record-multiselect-content min-w-[8rem] ";
|
|
11026
|
-
if (!usePopover) {
|
|
11027
|
-
contentBase += "absolute left-0 right-0 z-50 max-h-[30vh] overflow-hidden rounded-4 bg-fill-quarternary-fill-white shadow-default-medium opacity-0 invisible transition-all duration-150 ease-out group-[.open]:opacity-100 group-[.open]:visible ";
|
|
11028
|
-
}
|
|
11029
11253
|
|
|
11030
11254
|
// Trigger wrapper + button
|
|
11031
11255
|
var triggerWrapper = document.createElement("span");
|
|
@@ -11120,7 +11344,7 @@
|
|
|
11120
11344
|
var content = document.createElement("div");
|
|
11121
11345
|
content.setAttribute("role", "listbox");
|
|
11122
11346
|
content.setAttribute("aria-multiselectable", "true");
|
|
11123
|
-
content.className =
|
|
11347
|
+
content.className = "record-multiselect-content max-h-[45vh] overflow-hidden flex flex-col";
|
|
11124
11348
|
|
|
11125
11349
|
var searchWrap = document.createElement("div");
|
|
11126
11350
|
searchWrap.className = "p-8 pb-4 border-b-1/2 border-border-primary ";
|
|
@@ -11170,7 +11394,7 @@
|
|
|
11170
11394
|
content.appendChild(searchWrap);
|
|
11171
11395
|
|
|
11172
11396
|
var optionsList = document.createElement("div");
|
|
11173
|
-
optionsList.className = "overflow-y-auto max-h-[
|
|
11397
|
+
optionsList.className = "overflow-y-auto max-h-[45vh] p-2 w-full rounded-4 bg-fill-quarternary-fill-white record-multiselect-options";
|
|
11174
11398
|
|
|
11175
11399
|
// Add scroll listener for infinite scroll
|
|
11176
11400
|
optionsList.addEventListener("scroll", function () {
|
|
@@ -11187,57 +11411,52 @@
|
|
|
11187
11411
|
|
|
11188
11412
|
content.appendChild(optionsList);
|
|
11189
11413
|
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
|
|
11193
|
-
|
|
11194
|
-
if (usePopover) {
|
|
11195
|
-
popover = Popover.create({
|
|
11196
|
-
trigger: trigger,
|
|
11197
|
-
content: content,
|
|
11198
|
-
placement: "bottom",
|
|
11199
|
-
align: "start",
|
|
11200
|
-
closeOnClickOutside: true,
|
|
11201
|
-
bodyClassName: "p-0 overflow-hidden",
|
|
11202
|
-
panelClassName: "max-h-[30vh] overflow-hidden",
|
|
11203
|
-
onOpen: function () {
|
|
11204
|
-
if (disabled) {
|
|
11205
|
-
popover.hide();
|
|
11206
|
-
return;
|
|
11207
|
-
}
|
|
11208
|
-
document.querySelectorAll(".custom-select.open, .record-select.open, .custom-multiselect.open, .record-multiselect.open").forEach(function (other) {
|
|
11209
|
-
if (other !== container) {
|
|
11210
|
-
other.classList.remove("open");
|
|
11211
|
-
var t = other.querySelector("button, .custom-select-trigger, .record-select-trigger, .multiselect-trigger-wrapper button, .record-multiselect-trigger");
|
|
11212
|
-
if (t) t.setAttribute("aria-expanded", "false");
|
|
11213
|
-
}
|
|
11214
|
-
});
|
|
11215
|
-
isOpen = true;
|
|
11216
|
-
container.classList.add("open");
|
|
11217
|
-
trigger.setAttribute("aria-expanded", "true");
|
|
11218
|
-
searchTerm = "";
|
|
11219
|
-
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
11220
|
-
else if (searchInputEl) searchInputEl.value = "";
|
|
11221
|
-
content.style.minWidth = trigger.offsetWidth + "px";
|
|
11222
|
-
loadInitialAndRender();
|
|
11223
|
-
setTimeout(function () {
|
|
11224
|
-
if (searchInputEl) searchInputEl.focus();
|
|
11225
|
-
}, 0);
|
|
11226
|
-
},
|
|
11227
|
-
onClose: function () {
|
|
11228
|
-
isOpen = false;
|
|
11229
|
-
container.classList.remove("open");
|
|
11230
|
-
trigger.setAttribute("aria-expanded", "false");
|
|
11231
|
-
searchTerm = "";
|
|
11232
|
-
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
11233
|
-
else if (searchInputEl) searchInputEl.value = "";
|
|
11234
|
-
if (searchDebounceTimer) {
|
|
11235
|
-
clearTimeout(searchDebounceTimer);
|
|
11236
|
-
searchDebounceTimer = null;
|
|
11237
|
-
}
|
|
11238
|
-
},
|
|
11239
|
-
});
|
|
11414
|
+
var Popover = getDep("Popover");
|
|
11415
|
+
if (!Popover || typeof Popover.create !== "function") {
|
|
11416
|
+
throw new Error("RecordMultiSelect requires Popover");
|
|
11240
11417
|
}
|
|
11418
|
+
popover = Popover.create({
|
|
11419
|
+
trigger: trigger,
|
|
11420
|
+
content: content,
|
|
11421
|
+
placement: "bottom",
|
|
11422
|
+
align: "start",
|
|
11423
|
+
closeOnClickOutside: true,
|
|
11424
|
+
bodyClassName: "p-0 overflow-hidden",
|
|
11425
|
+
panelClassName: "min-w-[var(--trigger-width)] overflow-hidden",
|
|
11426
|
+
onOpen: function () {
|
|
11427
|
+
if (disabled) {
|
|
11428
|
+
popover.hide();
|
|
11429
|
+
return;
|
|
11430
|
+
}
|
|
11431
|
+
container.classList.add("open");
|
|
11432
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
11433
|
+
searchTerm = "";
|
|
11434
|
+
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
11435
|
+
else if (searchInputEl) searchInputEl.value = "";
|
|
11436
|
+
if (popover.panel) {
|
|
11437
|
+
var triggerWidthPx = trigger.offsetWidth + "px";
|
|
11438
|
+
popover.panel.style.setProperty("--trigger-width", triggerWidthPx);
|
|
11439
|
+
popover.panel.style.minWidth = triggerWidthPx;
|
|
11440
|
+
popover.panel.style.width = triggerWidthPx;
|
|
11441
|
+
}
|
|
11442
|
+
loadInitialAndRender();
|
|
11443
|
+
setTimeout(function () {
|
|
11444
|
+
if (searchInputEl) searchInputEl.focus();
|
|
11445
|
+
}, 0);
|
|
11446
|
+
},
|
|
11447
|
+
onClose: function () {
|
|
11448
|
+
container.classList.remove("open");
|
|
11449
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
11450
|
+
searchTerm = "";
|
|
11451
|
+
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
11452
|
+
else if (searchInputEl) searchInputEl.value = "";
|
|
11453
|
+
if (searchDebounceTimer) {
|
|
11454
|
+
clearTimeout(searchDebounceTimer);
|
|
11455
|
+
searchDebounceTimer = null;
|
|
11456
|
+
}
|
|
11457
|
+
},
|
|
11458
|
+
});
|
|
11459
|
+
container.popoverInstance = popover;
|
|
11241
11460
|
|
|
11242
11461
|
function isSelected(recordId) {
|
|
11243
11462
|
return values.some(function (v) {
|
|
@@ -11297,14 +11516,23 @@
|
|
|
11297
11516
|
try {
|
|
11298
11517
|
if (model && typeof model.select === "function") {
|
|
11299
11518
|
var q = model.select.apply(model, fields);
|
|
11519
|
+
var filters = [];
|
|
11520
|
+
var resolvedFilter = typeof initialFilter === 'function' ? initialFilter() : initialFilter;
|
|
11521
|
+
console.log('[RecordMultiselect] initialFilter:', resolvedFilter, '| search:', search);
|
|
11522
|
+
if (resolvedFilter) {
|
|
11523
|
+
filters = filters.concat(Array.isArray(resolvedFilter) ? resolvedFilter : [resolvedFilter]);
|
|
11524
|
+
}
|
|
11300
11525
|
if (search && search.trim()) {
|
|
11301
|
-
|
|
11526
|
+
filters.push({
|
|
11302
11527
|
or: [
|
|
11303
11528
|
{ field: "name", operator: "contains", value: search.trim() },
|
|
11304
11529
|
{ field: "id", operator: "eq", value: search.trim() },
|
|
11305
11530
|
],
|
|
11306
11531
|
});
|
|
11307
11532
|
}
|
|
11533
|
+
if (filters.length > 0) {
|
|
11534
|
+
q = q.filterBy(filters.length === 1 ? filters[0] : { and: filters });
|
|
11535
|
+
}
|
|
11308
11536
|
var orderBy = ["name"];
|
|
11309
11537
|
if (objectSlug === "account") orderBy.push("-ParentId");
|
|
11310
11538
|
return q
|
|
@@ -11563,6 +11791,16 @@
|
|
|
11563
11791
|
}
|
|
11564
11792
|
}
|
|
11565
11793
|
|
|
11794
|
+
function scheduleUpdatePosition() {
|
|
11795
|
+
if (popover && typeof popover.updatePosition === "function") {
|
|
11796
|
+
requestAnimationFrame(function () {
|
|
11797
|
+
requestAnimationFrame(function () {
|
|
11798
|
+
popover.updatePosition();
|
|
11799
|
+
});
|
|
11800
|
+
});
|
|
11801
|
+
}
|
|
11802
|
+
}
|
|
11803
|
+
|
|
11566
11804
|
function loadInitialAndRender() {
|
|
11567
11805
|
showLoading();
|
|
11568
11806
|
currentPage = 1;
|
|
@@ -11581,9 +11819,11 @@
|
|
|
11581
11819
|
} else {
|
|
11582
11820
|
renderOptions();
|
|
11583
11821
|
}
|
|
11822
|
+
scheduleUpdatePosition();
|
|
11584
11823
|
}).catch(function () {
|
|
11585
11824
|
showEmpty("Failed to load records");
|
|
11586
11825
|
hasMoreRecords = false;
|
|
11826
|
+
scheduleUpdatePosition();
|
|
11587
11827
|
});
|
|
11588
11828
|
}
|
|
11589
11829
|
|
|
@@ -11635,73 +11875,15 @@
|
|
|
11635
11875
|
} else {
|
|
11636
11876
|
renderOptions();
|
|
11637
11877
|
}
|
|
11878
|
+
scheduleUpdatePosition();
|
|
11638
11879
|
}).catch(function () {
|
|
11639
11880
|
showEmpty("Search failed");
|
|
11640
11881
|
hasMoreRecords = false;
|
|
11882
|
+
scheduleUpdatePosition();
|
|
11641
11883
|
});
|
|
11642
11884
|
}, 500);
|
|
11643
11885
|
}
|
|
11644
11886
|
|
|
11645
|
-
function openDropdown() {
|
|
11646
|
-
if (disabled) return;
|
|
11647
|
-
if (usePopover && popover) {
|
|
11648
|
-
popover.show();
|
|
11649
|
-
return;
|
|
11650
|
-
}
|
|
11651
|
-
document
|
|
11652
|
-
.querySelectorAll(".custom-select.open, .record-select.open, .custom-multiselect.open, .record-multiselect.open")
|
|
11653
|
-
.forEach(function (other) {
|
|
11654
|
-
if (other !== container) {
|
|
11655
|
-
other.classList.remove("open");
|
|
11656
|
-
var t = other.querySelector(
|
|
11657
|
-
"button, .custom-select-trigger, .record-select-trigger, .multiselect-trigger-wrapper button, .record-multiselect-trigger"
|
|
11658
|
-
);
|
|
11659
|
-
if (t) t.setAttribute("aria-expanded", "false");
|
|
11660
|
-
}
|
|
11661
|
-
});
|
|
11662
|
-
isOpen = true;
|
|
11663
|
-
container.classList.add("open");
|
|
11664
|
-
trigger.setAttribute("aria-expanded", "true");
|
|
11665
|
-
searchTerm = "";
|
|
11666
|
-
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
11667
|
-
else if (searchInputEl) searchInputEl.value = "";
|
|
11668
|
-
loadInitialAndRender();
|
|
11669
|
-
setTimeout(function () {
|
|
11670
|
-
if (searchInputEl) searchInputEl.focus();
|
|
11671
|
-
}, 0);
|
|
11672
|
-
updatePosition();
|
|
11673
|
-
}
|
|
11674
|
-
|
|
11675
|
-
function closeDropdown() {
|
|
11676
|
-
if (usePopover && popover) {
|
|
11677
|
-
popover.hide();
|
|
11678
|
-
return;
|
|
11679
|
-
}
|
|
11680
|
-
isOpen = false;
|
|
11681
|
-
container.classList.remove("open");
|
|
11682
|
-
trigger.setAttribute("aria-expanded", "false");
|
|
11683
|
-
searchTerm = "";
|
|
11684
|
-
if (searchInputWrapper) searchInputWrapper.setValue("");
|
|
11685
|
-
else if (searchInputEl) searchInputEl.value = "";
|
|
11686
|
-
if (searchDebounceTimer) {
|
|
11687
|
-
clearTimeout(searchDebounceTimer);
|
|
11688
|
-
searchDebounceTimer = null;
|
|
11689
|
-
}
|
|
11690
|
-
}
|
|
11691
|
-
|
|
11692
|
-
function updatePosition() {
|
|
11693
|
-
if (usePopover) return;
|
|
11694
|
-
var rect = trigger.getBoundingClientRect();
|
|
11695
|
-
var vh = window.innerHeight;
|
|
11696
|
-
var below = vh - rect.bottom;
|
|
11697
|
-
var above = rect.top;
|
|
11698
|
-
if (below < 200 && above > below) {
|
|
11699
|
-
content.className = contentBase + "bottom-full mb-1 translate-y-1 group-[.open]:translate-y-0";
|
|
11700
|
-
} else {
|
|
11701
|
-
content.className = contentBase + "top-full mt-1 -translate-y-1 group-[.open]:translate-y-0";
|
|
11702
|
-
}
|
|
11703
|
-
}
|
|
11704
|
-
|
|
11705
11887
|
if (!searchInputWrapper && searchInputEl) {
|
|
11706
11888
|
searchInputEl.addEventListener("input", function () {
|
|
11707
11889
|
searchTerm = this.value.trim();
|
|
@@ -11718,41 +11900,19 @@
|
|
|
11718
11900
|
});
|
|
11719
11901
|
}
|
|
11720
11902
|
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
e.preventDefault();
|
|
11726
|
-
if (isOpen) popover.hide();
|
|
11727
|
-
else popover.show();
|
|
11728
|
-
}
|
|
11729
|
-
});
|
|
11730
|
-
} else {
|
|
11731
|
-
trigger.addEventListener("click", function (e) {
|
|
11903
|
+
trigger.addEventListener("keydown", function (e) {
|
|
11904
|
+
if (disabled) return;
|
|
11905
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
11906
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
11732
11907
|
e.preventDefault();
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
|
|
11737
|
-
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
if (isOpen) closeDropdown();
|
|
11742
|
-
else openDropdown();
|
|
11743
|
-
}
|
|
11744
|
-
if (e.key === "Escape" && isOpen) {
|
|
11745
|
-
e.preventDefault();
|
|
11746
|
-
closeDropdown();
|
|
11747
|
-
}
|
|
11748
|
-
});
|
|
11749
|
-
document.addEventListener("click", function (e) {
|
|
11750
|
-
if (isOpen && !container.contains(e.target)) closeDropdown();
|
|
11751
|
-
});
|
|
11752
|
-
document.addEventListener("keydown", function (e) {
|
|
11753
|
-
if (e.key === "Escape" && isOpen) closeDropdown();
|
|
11754
|
-
});
|
|
11755
|
-
}
|
|
11908
|
+
if (isVisible) popover.hide();
|
|
11909
|
+
else popover.show();
|
|
11910
|
+
}
|
|
11911
|
+
if (e.key === "Escape" && isVisible) {
|
|
11912
|
+
e.preventDefault();
|
|
11913
|
+
popover.hide();
|
|
11914
|
+
}
|
|
11915
|
+
});
|
|
11756
11916
|
|
|
11757
11917
|
container.updateValues = function (newValues) {
|
|
11758
11918
|
values = Array.isArray(newValues) ? newValues.slice() : [];
|
|
@@ -11763,7 +11923,8 @@
|
|
|
11763
11923
|
disabled = !!isDisabled;
|
|
11764
11924
|
trigger.disabled = disabled;
|
|
11765
11925
|
trigger.className = triggerClasses(variant, size, disabled, values.length === 0);
|
|
11766
|
-
|
|
11926
|
+
var isVisible = popover.element && popover.element.classList.contains("visible");
|
|
11927
|
+
if (disabled && isVisible) popover.hide();
|
|
11767
11928
|
};
|
|
11768
11929
|
|
|
11769
11930
|
container.getValues = function () {
|
|
@@ -11788,7 +11949,7 @@
|
|
|
11788
11949
|
|
|
11789
11950
|
|
|
11790
11951
|
// ============================================
|
|
11791
|
-
// File 21/
|
|
11952
|
+
// File 21/41: components/input.js
|
|
11792
11953
|
// ============================================
|
|
11793
11954
|
|
|
11794
11955
|
/**
|
|
@@ -11815,7 +11976,7 @@
|
|
|
11815
11976
|
|
|
11816
11977
|
var WRAPPER_CLASS = {
|
|
11817
11978
|
base:
|
|
11818
|
-
"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",
|
|
11979
|
+
"group flex items-center border-1/2 border-border-primary rounded-4 text-typography-primary-text gap-x-8 w-full transition-all ease-in-out group-has-[:disabled]:cursor-not-allowed group-has-[:disabled]:border-border-primary group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:text-typography-quaternary-text group-has-[:disabled]:hover:border-border-primary group-has-[:disabled]:[&_input]:cursor-not-allowed group-has-[:disabled]:[&_input]:text-typography-quaternary-text",
|
|
11819
11980
|
default:
|
|
11820
11981
|
"bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
|
|
11821
11982
|
error:
|
|
@@ -11890,13 +12051,16 @@
|
|
|
11890
12051
|
var isPassword = type === "password";
|
|
11891
12052
|
|
|
11892
12053
|
var wrapper = document.createElement("div");
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
|
|
11899
|
-
|
|
12054
|
+
var sizeClass = inputSize === "large" ? WRAPPER_CLASS.sizeLarge : inputSize === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault;
|
|
12055
|
+
function applyWrapperClasses() {
|
|
12056
|
+
wrapper.className = join(
|
|
12057
|
+
WRAPPER_CLASS.base,
|
|
12058
|
+
disabled ? WRAPPER_CLASS.disabled : (WRAPPER_CLASS[variant] || WRAPPER_CLASS.default),
|
|
12059
|
+
sizeClass,
|
|
12060
|
+
config.className || ""
|
|
12061
|
+
);
|
|
12062
|
+
}
|
|
12063
|
+
applyWrapperClasses();
|
|
11900
12064
|
wrapper.setAttribute("data-input-variant", variant);
|
|
11901
12065
|
|
|
11902
12066
|
if (config.prefixNode) {
|
|
@@ -12026,19 +12190,12 @@
|
|
|
12026
12190
|
wrapper.setVariant = function (v) {
|
|
12027
12191
|
variant = v;
|
|
12028
12192
|
wrapper.setAttribute("data-input-variant", v);
|
|
12029
|
-
|
|
12030
|
-
WRAPPER_CLASS.base,
|
|
12031
|
-
WRAPPER_CLASS[variant] || WRAPPER_CLASS.default,
|
|
12032
|
-
inputSize === "large" ? WRAPPER_CLASS.sizeLarge : inputSize === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault,
|
|
12033
|
-
disabled ? WRAPPER_CLASS.disabled : "",
|
|
12034
|
-
config.className || ""
|
|
12035
|
-
);
|
|
12193
|
+
applyWrapperClasses();
|
|
12036
12194
|
};
|
|
12037
12195
|
wrapper.setDisabled = function (d) {
|
|
12038
12196
|
disabled = !!d;
|
|
12039
12197
|
input.disabled = disabled;
|
|
12040
|
-
|
|
12041
|
-
wrapper.classList.toggle("opacity-60", disabled);
|
|
12198
|
+
applyWrapperClasses();
|
|
12042
12199
|
};
|
|
12043
12200
|
|
|
12044
12201
|
return wrapper;
|
|
@@ -12053,7 +12210,7 @@
|
|
|
12053
12210
|
|
|
12054
12211
|
|
|
12055
12212
|
// ============================================
|
|
12056
|
-
// File 22/
|
|
12213
|
+
// File 22/41: components/currency.js
|
|
12057
12214
|
// ============================================
|
|
12058
12215
|
|
|
12059
12216
|
/**
|
|
@@ -12083,7 +12240,7 @@
|
|
|
12083
12240
|
sizeLarge: "",
|
|
12084
12241
|
sizeSmall: "",
|
|
12085
12242
|
disabled:
|
|
12086
|
-
"cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
|
|
12243
|
+
"pointer-events-none cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
|
|
12087
12244
|
};
|
|
12088
12245
|
|
|
12089
12246
|
// Currency type label: fit-content, separator (border-r) on type only, full height
|
|
@@ -12270,7 +12427,12 @@
|
|
|
12270
12427
|
wrapper.setDisabled = function (d) {
|
|
12271
12428
|
disabled = !!d;
|
|
12272
12429
|
input.disabled = disabled;
|
|
12273
|
-
wrapper.
|
|
12430
|
+
wrapper.className = join(
|
|
12431
|
+
WRAPPER_CLASS.base,
|
|
12432
|
+
WRAPPER_CLASS[variant] != null ? WRAPPER_CLASS[variant] : WRAPPER_CLASS.default,
|
|
12433
|
+
disabled ? WRAPPER_CLASS.disabled : "",
|
|
12434
|
+
config.className || ""
|
|
12435
|
+
);
|
|
12274
12436
|
};
|
|
12275
12437
|
|
|
12276
12438
|
return wrapper;
|
|
@@ -12286,7 +12448,7 @@
|
|
|
12286
12448
|
|
|
12287
12449
|
|
|
12288
12450
|
// ============================================
|
|
12289
|
-
// File 23/
|
|
12451
|
+
// File 23/41: components/textarea.js
|
|
12290
12452
|
// ============================================
|
|
12291
12453
|
|
|
12292
12454
|
/**
|
|
@@ -12311,7 +12473,7 @@
|
|
|
12311
12473
|
warning:
|
|
12312
12474
|
"min-h-[80px] border-warning-base hover:border-warning-base focus:border-warning-base",
|
|
12313
12475
|
disabled:
|
|
12314
|
-
"cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
|
|
12476
|
+
"pointer-events-none cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
|
|
12315
12477
|
};
|
|
12316
12478
|
|
|
12317
12479
|
function join() {
|
|
@@ -12338,67 +12500,407 @@
|
|
|
12338
12500
|
* @returns {HTMLTextAreaElement} textarea element (with getValue/setValue/setVariant/setDisabled attached)
|
|
12339
12501
|
*/
|
|
12340
12502
|
function create(config) {
|
|
12341
|
-
var variant = config.variant || "default";
|
|
12503
|
+
var variant = config.variant || "default";
|
|
12504
|
+
var disabled = !!config.disabled;
|
|
12505
|
+
|
|
12506
|
+
var textarea = document.createElement("textarea");
|
|
12507
|
+
textarea.autocomplete = "off";
|
|
12508
|
+
if (config.placeholder != null) textarea.placeholder = config.placeholder;
|
|
12509
|
+
if (config.value != null) textarea.value = config.value;
|
|
12510
|
+
if (config.name) textarea.name = config.name;
|
|
12511
|
+
if (config.id) textarea.id = config.id;
|
|
12512
|
+
if (config.rows != null) textarea.rows = config.rows;
|
|
12513
|
+
if (config.maxLength != null) textarea.maxLength = config.maxLength;
|
|
12514
|
+
textarea.disabled = disabled;
|
|
12515
|
+
textarea.readOnly = !!config.readOnly;
|
|
12516
|
+
|
|
12517
|
+
textarea.className = join(
|
|
12518
|
+
TEXTAREA_CLASS.base,
|
|
12519
|
+
TEXTAREA_CLASS[variant] || TEXTAREA_CLASS.default,
|
|
12520
|
+
disabled ? TEXTAREA_CLASS.disabled : "",
|
|
12521
|
+
config.className || ""
|
|
12522
|
+
);
|
|
12523
|
+
textarea.setAttribute("data-textarea-variant", variant);
|
|
12524
|
+
|
|
12525
|
+
if (config.onChange) textarea.addEventListener("change", config.onChange);
|
|
12526
|
+
if (config.onInput) textarea.addEventListener("input", config.onInput);
|
|
12527
|
+
if (config.onFocus) textarea.addEventListener("focus", config.onFocus);
|
|
12528
|
+
if (config.onBlur) textarea.addEventListener("blur", config.onBlur);
|
|
12529
|
+
|
|
12530
|
+
textarea.getInput = function () {
|
|
12531
|
+
return textarea;
|
|
12532
|
+
};
|
|
12533
|
+
textarea.setValue = function (v) {
|
|
12534
|
+
textarea.value = v;
|
|
12535
|
+
};
|
|
12536
|
+
textarea.getValue = function () {
|
|
12537
|
+
return textarea.value;
|
|
12538
|
+
};
|
|
12539
|
+
textarea.setVariant = function (v) {
|
|
12540
|
+
variant = v;
|
|
12541
|
+
textarea.setAttribute("data-textarea-variant", v);
|
|
12542
|
+
textarea.className = join(
|
|
12543
|
+
TEXTAREA_CLASS.base,
|
|
12544
|
+
TEXTAREA_CLASS[variant] || TEXTAREA_CLASS.default,
|
|
12545
|
+
disabled ? TEXTAREA_CLASS.disabled : "",
|
|
12546
|
+
config.className || ""
|
|
12547
|
+
);
|
|
12548
|
+
};
|
|
12549
|
+
textarea.setDisabled = function (d) {
|
|
12550
|
+
disabled = !!d;
|
|
12551
|
+
textarea.disabled = disabled;
|
|
12552
|
+
textarea.className = join(
|
|
12553
|
+
TEXTAREA_CLASS.base,
|
|
12554
|
+
TEXTAREA_CLASS[variant] || TEXTAREA_CLASS.default,
|
|
12555
|
+
disabled ? TEXTAREA_CLASS.disabled : "",
|
|
12556
|
+
config.className || ""
|
|
12557
|
+
);
|
|
12558
|
+
};
|
|
12559
|
+
|
|
12560
|
+
return textarea;
|
|
12561
|
+
}
|
|
12562
|
+
|
|
12563
|
+
global.TextareaComponent = {
|
|
12564
|
+
create: create,
|
|
12565
|
+
};
|
|
12566
|
+
})(typeof window !== "undefined" ? window : undefined);
|
|
12567
|
+
|
|
12568
|
+
|
|
12569
|
+
|
|
12570
|
+
// ============================================
|
|
12571
|
+
// File 24/41: components/richtext-editor.js
|
|
12572
|
+
// ============================================
|
|
12573
|
+
|
|
12574
|
+
/**
|
|
12575
|
+
* Rich Text Editor Component (vanilla JS)
|
|
12576
|
+
* Toolbar + contenteditable area with formatting (bold, italic, underline, headings, lists, alignment, link, image, code block, undo/redo).
|
|
12577
|
+
* Styling matches design: rounded-12, toolbar bg-fill-tertiary-fill-light-gray, content area with min-height.
|
|
12578
|
+
*/
|
|
12579
|
+
|
|
12580
|
+
(function (global) {
|
|
12581
|
+
|
|
12582
|
+
var RICH_TEXT_CONTENT_STYLES =
|
|
12583
|
+
".rich-text-editor-content ul{list-style-type:disc;padding-left:1.5em;margin:0.5em 0}" +
|
|
12584
|
+
".rich-text-editor-content ol{list-style-type:decimal;padding-left:1.5em;margin:0.5em 0}" +
|
|
12585
|
+
".rich-text-editor-content li{margin:0.25em 0}" +
|
|
12586
|
+
".rich-text-editor-content li p{margin:0}" +
|
|
12587
|
+
".rich-text-editor-content h1{font-size:1.5rem;font-weight:700;line-height:1.3;margin:0.75em 0 0.5em}" +
|
|
12588
|
+
".rich-text-editor-content h2{font-size:1.25rem;font-weight:600;line-height:1.3;margin:0.75em 0 0.5em}" +
|
|
12589
|
+
".rich-text-editor-content h3{font-size:1.125rem;font-weight:600;line-height:1.3;margin:0.75em 0 0.5em}" +
|
|
12590
|
+
".rich-text-editor-content p{margin:0.5em 0}" +
|
|
12591
|
+
".rich-text-editor-content a{color:var(--color-primary-500);text-decoration:underline;cursor:pointer}" +
|
|
12592
|
+
".rich-text-editor-content pre{background:var(--color-neutral-100);border-radius:var(--sizes-size-8);padding:0.75em 1em;margin:0.5em 0;overflow-x:auto}" +
|
|
12593
|
+
".rich-text-editor-content code{font-family:ui-monospace,monospace;font-size:0.875em}" +
|
|
12594
|
+
".rich-text-editor-content img{max-width:100%;height:auto;margin:0.5em 0}" +
|
|
12595
|
+
".rich-text-editor-content blockquote{border-left:3px solid var(--color-neutral-200);padding-left:1em;margin:0.5em 0;color:var(--color-neutral-600)}" +
|
|
12596
|
+
".rich-text-editor-content hr{border:none;border-top:1px solid var(--color-neutral-150);margin:1em 0}" +
|
|
12597
|
+
".rich-text-editor-content .ProseMirror,.rich-text-editor-content [contenteditable]{outline:none}";
|
|
12598
|
+
|
|
12599
|
+
function join() {
|
|
12600
|
+
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
12601
|
+
}
|
|
12602
|
+
|
|
12603
|
+
function getDep(name) {
|
|
12604
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
12605
|
+
var c = global.FlowUI._getComponent(name);
|
|
12606
|
+
if (c) return c;
|
|
12607
|
+
}
|
|
12608
|
+
return global[name];
|
|
12609
|
+
}
|
|
12610
|
+
|
|
12611
|
+
/** Get Tabler icon element (16px) from Icon component for toolbar. */
|
|
12612
|
+
function getTablerIcon(iconName) {
|
|
12613
|
+
var Icon = getDep("Icon");
|
|
12614
|
+
if (!Icon || !Icon.iconMap || !Icon.iconMap[iconName]) return null;
|
|
12615
|
+
var svgStr = Icon.iconMap[iconName];
|
|
12616
|
+
var s16 = svgStr.replace(/width="24"/, 'width="16"').replace(/height="24"/, 'height="16"').replace(/width="20"/, 'width="16"').replace(/height="20"/, 'height="16"');
|
|
12617
|
+
var span = document.createElement("span");
|
|
12618
|
+
span.className = "flex items-center justify-center size-16";
|
|
12619
|
+
span.innerHTML = s16;
|
|
12620
|
+
return span;
|
|
12621
|
+
}
|
|
12622
|
+
|
|
12623
|
+
function createToolbarButton(opts) {
|
|
12624
|
+
var Button = getDep("Button");
|
|
12625
|
+
if (!Button || typeof Button.create !== "function") {
|
|
12626
|
+
throw new Error("RichTextEditor requires Button");
|
|
12627
|
+
}
|
|
12628
|
+
var icon = opts.iconStr ? getTablerIcon(opts.iconStr) : null;
|
|
12629
|
+
return Button.create({
|
|
12630
|
+
variant: "outline",
|
|
12631
|
+
size: "default",
|
|
12632
|
+
title: opts.title,
|
|
12633
|
+
icon: icon,
|
|
12634
|
+
onClick: opts.onClick,
|
|
12635
|
+
disabled: opts.disabled,
|
|
12636
|
+
});
|
|
12637
|
+
}
|
|
12638
|
+
|
|
12639
|
+
function createSeparator() {
|
|
12640
|
+
var sep = document.createElement("div");
|
|
12641
|
+
sep.className = "w-px h-16 bg-border-primary mx-4";
|
|
12642
|
+
sep.setAttribute("aria-hidden", "true");
|
|
12643
|
+
return sep;
|
|
12644
|
+
}
|
|
12645
|
+
|
|
12646
|
+
/**
|
|
12647
|
+
* Create a rich text editor
|
|
12648
|
+
* @param {Object} config
|
|
12649
|
+
* @param {string} [config.value] - Initial HTML content
|
|
12650
|
+
* @param {string} [config.placeholder] - Placeholder when empty
|
|
12651
|
+
* @param {number} [config.minHeightPx] - Min height of editor area (default 400)
|
|
12652
|
+
* @param {boolean} [config.disabled]
|
|
12653
|
+
* @param {Function} [config.onChange] - (html: string) => void
|
|
12654
|
+
* @returns {HTMLElement} Wrapper element with getValue/setValue/setDisabled/getInput
|
|
12655
|
+
*/
|
|
12656
|
+
function create(config) {
|
|
12657
|
+
var value = config.value != null ? String(config.value) : "";
|
|
12658
|
+
var placeholder = config.placeholder != null ? config.placeholder : "";
|
|
12659
|
+
var minHeightPx = config.minHeightPx != null ? config.minHeightPx : 400;
|
|
12342
12660
|
var disabled = !!config.disabled;
|
|
12661
|
+
var onChange = config.onChange;
|
|
12343
12662
|
|
|
12344
|
-
var
|
|
12345
|
-
|
|
12346
|
-
if (config.placeholder != null) textarea.placeholder = config.placeholder;
|
|
12347
|
-
if (config.value != null) textarea.value = config.value;
|
|
12348
|
-
if (config.name) textarea.name = config.name;
|
|
12349
|
-
if (config.id) textarea.id = config.id;
|
|
12350
|
-
if (config.rows != null) textarea.rows = config.rows;
|
|
12351
|
-
if (config.maxLength != null) textarea.maxLength = config.maxLength;
|
|
12352
|
-
textarea.disabled = disabled;
|
|
12353
|
-
textarea.readOnly = !!config.readOnly;
|
|
12663
|
+
var wrapper = document.createElement("div");
|
|
12664
|
+
wrapper.className = "w-full rounded-12 border border-borderColor-border-primary shadow-soft-2x-small";
|
|
12354
12665
|
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12666
|
+
var styleEl = document.createElement("style");
|
|
12667
|
+
styleEl.textContent = RICH_TEXT_CONTENT_STYLES;
|
|
12668
|
+
wrapper.appendChild(styleEl);
|
|
12669
|
+
|
|
12670
|
+
var toolbar = document.createElement("div");
|
|
12671
|
+
toolbar.className =
|
|
12672
|
+
"flex flex-wrap gap-4 rounded-t-12 border-borderColor-border-primary bg-fill-tertiary-fill-light-gray p-6";
|
|
12673
|
+
toolbar.setAttribute("role", "toolbar");
|
|
12674
|
+
|
|
12675
|
+
var editorEl = document.createElement("div");
|
|
12676
|
+
editorEl.contentEditable = !disabled;
|
|
12677
|
+
editorEl.className = join(
|
|
12678
|
+
"rich-text-editor-content max-w-none rounded-b-12 border-t border-borderColor-border-primary p-8 text-reg-14 text-typography-primary-text"
|
|
12360
12679
|
);
|
|
12361
|
-
|
|
12680
|
+
editorEl.style.minHeight = minHeightPx + "px";
|
|
12681
|
+
if (value) editorEl.innerHTML = value;
|
|
12682
|
+
editorEl.setAttribute("data-placeholder", placeholder);
|
|
12362
12683
|
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12684
|
+
function isEmpty() {
|
|
12685
|
+
var text = (editorEl.textContent || "").trim();
|
|
12686
|
+
if (text) return false;
|
|
12687
|
+
var html = (editorEl.innerHTML || "").replace(/<br\s*\/?>/gi, "\n").replace(/<[^>]+>/g, "");
|
|
12688
|
+
return !html.trim();
|
|
12689
|
+
}
|
|
12690
|
+
function updatePlaceholder() {
|
|
12691
|
+
if (placeholder && isEmpty()) {
|
|
12692
|
+
editorEl.classList.add("empty");
|
|
12693
|
+
editorEl.setAttribute("data-placeholder", placeholder);
|
|
12694
|
+
} else {
|
|
12695
|
+
editorEl.classList.remove("empty");
|
|
12696
|
+
editorEl.removeAttribute("data-placeholder");
|
|
12697
|
+
}
|
|
12698
|
+
}
|
|
12699
|
+
updatePlaceholder();
|
|
12367
12700
|
|
|
12368
|
-
|
|
12369
|
-
return
|
|
12370
|
-
}
|
|
12371
|
-
|
|
12372
|
-
|
|
12701
|
+
function getHtml() {
|
|
12702
|
+
return editorEl.innerHTML;
|
|
12703
|
+
}
|
|
12704
|
+
function setHtml(html) {
|
|
12705
|
+
editorEl.innerHTML = html || "";
|
|
12706
|
+
updatePlaceholder();
|
|
12707
|
+
}
|
|
12708
|
+
function notifyChange() {
|
|
12709
|
+
if (typeof onChange === "function") onChange(getHtml());
|
|
12710
|
+
}
|
|
12711
|
+
|
|
12712
|
+
function isActive(cmd, val) {
|
|
12713
|
+
try {
|
|
12714
|
+
return document.queryCommandState(cmd);
|
|
12715
|
+
} catch (e) {
|
|
12716
|
+
return false;
|
|
12717
|
+
}
|
|
12718
|
+
}
|
|
12719
|
+
function blockTag() {
|
|
12720
|
+
var sel = window.getSelection();
|
|
12721
|
+
if (!sel || sel.rangeCount === 0) return null;
|
|
12722
|
+
var node = sel.anchorNode;
|
|
12723
|
+
while (node && node !== editorEl) {
|
|
12724
|
+
if (node.nodeType === 1) {
|
|
12725
|
+
var n = node.nodeName.toLowerCase();
|
|
12726
|
+
if (["h1", "h2", "h3", "p", "div", "pre", "blockquote"].indexOf(n) !== -1) return n;
|
|
12727
|
+
}
|
|
12728
|
+
node = node.parentNode;
|
|
12729
|
+
}
|
|
12730
|
+
return null;
|
|
12731
|
+
}
|
|
12732
|
+
function isAlignment(align) {
|
|
12733
|
+
try {
|
|
12734
|
+
if (align === "left") return document.queryCommandState("justifyLeft");
|
|
12735
|
+
if (align === "center") return document.queryCommandState("justifyCenter");
|
|
12736
|
+
if (align === "right") return document.queryCommandState("justifyRight");
|
|
12737
|
+
} catch (e) {}
|
|
12738
|
+
return false;
|
|
12739
|
+
}
|
|
12740
|
+
|
|
12741
|
+
function refreshToolbar() {
|
|
12742
|
+
toolbar.querySelectorAll("button").forEach(function (btn) {
|
|
12743
|
+
var cmd = btn.getAttribute("data-command");
|
|
12744
|
+
var val = btn.getAttribute("data-value");
|
|
12745
|
+
if (!cmd) return;
|
|
12746
|
+
var active = false;
|
|
12747
|
+
if (cmd === "formatBlock") active = blockTag() === val;
|
|
12748
|
+
else if (cmd === "justifyLeft" && val === "left") active = isAlignment("left");
|
|
12749
|
+
else if (cmd === "justifyCenter" && val === "center") active = isAlignment("center");
|
|
12750
|
+
else if (cmd === "justifyRight" && val === "right") active = isAlignment("right");
|
|
12751
|
+
else active = isActive(cmd);
|
|
12752
|
+
btn.classList.toggle("bg-primary-base", active);
|
|
12753
|
+
btn.classList.toggle("border-primary-base", active);
|
|
12754
|
+
btn.classList.toggle("text-typography-invert-text", active);
|
|
12755
|
+
btn.classList.toggle("bg-fill-quarternary-fill-white", !active);
|
|
12756
|
+
btn.classList.toggle("border-border-primary", !active);
|
|
12757
|
+
btn.classList.toggle("text-typography-primary-text", !active);
|
|
12758
|
+
});
|
|
12759
|
+
}
|
|
12760
|
+
|
|
12761
|
+
function exec(cmd, value) {
|
|
12762
|
+
editorEl.focus();
|
|
12763
|
+
document.execCommand(cmd, false, value != null ? value : null);
|
|
12764
|
+
refreshToolbar();
|
|
12765
|
+
notifyChange();
|
|
12766
|
+
}
|
|
12767
|
+
|
|
12768
|
+
function insertCodeBlock() {
|
|
12769
|
+
editorEl.focus();
|
|
12770
|
+
var sel = window.getSelection();
|
|
12771
|
+
if (sel && sel.rangeCount) {
|
|
12772
|
+
var range = sel.getRangeAt(0);
|
|
12773
|
+
var pre = document.createElement("pre");
|
|
12774
|
+
var code = document.createElement("code");
|
|
12775
|
+
code.textContent = "code here";
|
|
12776
|
+
pre.appendChild(code);
|
|
12777
|
+
range.insertNode(pre);
|
|
12778
|
+
range.setStart(code, 0);
|
|
12779
|
+
range.setEnd(code, 0);
|
|
12780
|
+
sel.removeAllRanges();
|
|
12781
|
+
sel.addRange(range);
|
|
12782
|
+
}
|
|
12783
|
+
refreshToolbar();
|
|
12784
|
+
notifyChange();
|
|
12785
|
+
}
|
|
12786
|
+
|
|
12787
|
+
function addLink() {
|
|
12788
|
+
var url = window.prompt("Enter the URL:", "https://");
|
|
12789
|
+
if (url) {
|
|
12790
|
+
exec("createLink", url);
|
|
12791
|
+
}
|
|
12792
|
+
}
|
|
12793
|
+
|
|
12794
|
+
function addImage() {
|
|
12795
|
+
var input = document.createElement("input");
|
|
12796
|
+
input.type = "file";
|
|
12797
|
+
input.accept = "image/*";
|
|
12798
|
+
input.onchange = function (e) {
|
|
12799
|
+
var file = e.target && e.target.files && e.target.files[0];
|
|
12800
|
+
if (file) {
|
|
12801
|
+
var reader = new FileReader();
|
|
12802
|
+
reader.onload = function (ev) {
|
|
12803
|
+
var src = ev.target && ev.target.result;
|
|
12804
|
+
if (src) {
|
|
12805
|
+
editorEl.focus();
|
|
12806
|
+
document.execCommand("insertImage", false, src);
|
|
12807
|
+
notifyChange();
|
|
12808
|
+
}
|
|
12809
|
+
};
|
|
12810
|
+
reader.readAsDataURL(file);
|
|
12811
|
+
}
|
|
12812
|
+
};
|
|
12813
|
+
input.click();
|
|
12814
|
+
}
|
|
12815
|
+
|
|
12816
|
+
function undo() {
|
|
12817
|
+
editorEl.focus();
|
|
12818
|
+
document.execCommand("undo", false, null);
|
|
12819
|
+
refreshToolbar();
|
|
12820
|
+
notifyChange();
|
|
12821
|
+
}
|
|
12822
|
+
function redo() {
|
|
12823
|
+
editorEl.focus();
|
|
12824
|
+
document.execCommand("redo", false, null);
|
|
12825
|
+
refreshToolbar();
|
|
12826
|
+
notifyChange();
|
|
12827
|
+
}
|
|
12828
|
+
|
|
12829
|
+
function addBtn(iconStr, title, onClick, dataCommand, dataValue) {
|
|
12830
|
+
var btn = createToolbarButton({
|
|
12831
|
+
iconStr: iconStr,
|
|
12832
|
+
title: title,
|
|
12833
|
+
onClick: function () {
|
|
12834
|
+
if (disabled) return;
|
|
12835
|
+
onClick();
|
|
12836
|
+
}});
|
|
12837
|
+
if (dataCommand) btn.setAttribute("data-command", dataCommand);
|
|
12838
|
+
if (dataValue != null) btn.setAttribute("data-value", dataValue);
|
|
12839
|
+
toolbar.appendChild(btn);
|
|
12840
|
+
}
|
|
12841
|
+
|
|
12842
|
+
addBtn("IconBold", "Bold (Ctrl+B)", function () { exec("bold"); }, "bold");
|
|
12843
|
+
addBtn("IconItalic", "Italic (Ctrl+I)", function () { exec("italic"); }, "italic");
|
|
12844
|
+
addBtn("IconUnderline", "Underline (Ctrl+U)", function () { exec("underline"); }, "underline");
|
|
12845
|
+
toolbar.appendChild(createSeparator());
|
|
12846
|
+
addBtn("IconH1", "Heading 1", function () { exec("formatBlock", "h1"); }, "formatBlock", "h1");
|
|
12847
|
+
addBtn("IconH2", "Heading 2", function () { exec("formatBlock", "h2"); }, "formatBlock", "h2");
|
|
12848
|
+
addBtn("IconH3", "Heading 3", function () { exec("formatBlock", "h3"); }, "formatBlock", "h3");
|
|
12849
|
+
toolbar.appendChild(createSeparator());
|
|
12850
|
+
addBtn("IconList", "Bullet List", function () { exec("insertUnorderedList"); }, "insertUnorderedList");
|
|
12851
|
+
addBtn("IconListNumbers", "Ordered List", function () { exec("insertOrderedList"); }, "insertOrderedList");
|
|
12852
|
+
toolbar.appendChild(createSeparator());
|
|
12853
|
+
addBtn("IconAlignLeft", "Align Left", function () { exec("justifyLeft"); }, "justifyLeft", "left");
|
|
12854
|
+
addBtn("IconAlignCenter", "Align Center", function () { exec("justifyCenter"); }, "justifyCenter", "center");
|
|
12855
|
+
addBtn("IconAlignRight", "Align Right", function () { exec("justifyRight"); }, "justifyRight", "right");
|
|
12856
|
+
toolbar.appendChild(createSeparator());
|
|
12857
|
+
addBtn("IconCode", "Code Block", insertCodeBlock, "formatBlock", "pre");
|
|
12858
|
+
addBtn("IconLink", "Add Link", addLink, "link");
|
|
12859
|
+
addBtn("IconPhoto", "Insert Image", addImage);
|
|
12860
|
+
toolbar.appendChild(createSeparator());
|
|
12861
|
+
addBtn("IconArrowBackUp", "Undo", undo);
|
|
12862
|
+
addBtn("IconArrowForwardUp", "Redo", redo);
|
|
12863
|
+
|
|
12864
|
+
editorEl.addEventListener("input", function () {
|
|
12865
|
+
updatePlaceholder();
|
|
12866
|
+
refreshToolbar();
|
|
12867
|
+
notifyChange();
|
|
12868
|
+
});
|
|
12869
|
+
editorEl.addEventListener("keyup", refreshToolbar);
|
|
12870
|
+
editorEl.addEventListener("mouseup", refreshToolbar);
|
|
12871
|
+
editorEl.addEventListener("focus", refreshToolbar);
|
|
12872
|
+
|
|
12873
|
+
if (placeholder) {
|
|
12874
|
+
var placeholderStyles = document.createElement("style");
|
|
12875
|
+
placeholderStyles.textContent =
|
|
12876
|
+
".rich-text-editor-content.empty:before{content:attr(data-placeholder);color:var(--color-neutral-400);pointer-events:none}";
|
|
12877
|
+
wrapper.appendChild(placeholderStyles);
|
|
12878
|
+
}
|
|
12879
|
+
|
|
12880
|
+
wrapper.appendChild(toolbar);
|
|
12881
|
+
wrapper.appendChild(editorEl);
|
|
12882
|
+
|
|
12883
|
+
wrapper.getInput = function () {
|
|
12884
|
+
return editorEl;
|
|
12373
12885
|
};
|
|
12374
|
-
|
|
12375
|
-
return
|
|
12886
|
+
wrapper.getValue = function () {
|
|
12887
|
+
return getHtml();
|
|
12376
12888
|
};
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
textarea.setAttribute("data-textarea-variant", v);
|
|
12380
|
-
textarea.className = join(
|
|
12381
|
-
TEXTAREA_CLASS.base,
|
|
12382
|
-
TEXTAREA_CLASS[variant] || TEXTAREA_CLASS.default,
|
|
12383
|
-
disabled ? TEXTAREA_CLASS.disabled : "",
|
|
12384
|
-
config.className || ""
|
|
12385
|
-
);
|
|
12889
|
+
wrapper.setValue = function (v) {
|
|
12890
|
+
setHtml(v);
|
|
12386
12891
|
};
|
|
12387
|
-
|
|
12892
|
+
wrapper.setDisabled = function (d) {
|
|
12388
12893
|
disabled = !!d;
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
|
|
12393
|
-
disabled ? TEXTAREA_CLASS.disabled : "",
|
|
12394
|
-
config.className || ""
|
|
12395
|
-
);
|
|
12894
|
+
editorEl.contentEditable = !disabled;
|
|
12895
|
+
toolbar.querySelectorAll("button").forEach(function (b) {
|
|
12896
|
+
b.disabled = disabled;
|
|
12897
|
+
});
|
|
12396
12898
|
};
|
|
12397
12899
|
|
|
12398
|
-
return
|
|
12900
|
+
return wrapper;
|
|
12399
12901
|
}
|
|
12400
12902
|
|
|
12401
|
-
global.
|
|
12903
|
+
global.RichTextEditorComponent = {
|
|
12402
12904
|
create: create,
|
|
12403
12905
|
};
|
|
12404
12906
|
})(typeof window !== "undefined" ? window : undefined);
|
|
@@ -12406,7 +12908,7 @@
|
|
|
12406
12908
|
|
|
12407
12909
|
|
|
12408
12910
|
// ============================================
|
|
12409
|
-
// File
|
|
12911
|
+
// File 25/41: components/checkbox.js
|
|
12410
12912
|
// ============================================
|
|
12411
12913
|
|
|
12412
12914
|
/**
|
|
@@ -12445,10 +12947,18 @@
|
|
|
12445
12947
|
};
|
|
12446
12948
|
|
|
12447
12949
|
var CHECKBOX_BASE_CLASS =
|
|
12448
|
-
"flex items-center justify-center rounded-2 border-1/2 border-borderColor-border-primary bg-fill-quarternary-fill-white p-4 transition-all
|
|
12950
|
+
"flex items-center justify-center rounded-2 border-1/2 border-borderColor-border-primary bg-fill-quarternary-fill-white p-4 transition-all";
|
|
12951
|
+
|
|
12952
|
+
var CHECKBOX_ACTIVE_CLASS =
|
|
12953
|
+
"hover:border-primary-base hover:shadow-primary-focused cursor-pointer";
|
|
12954
|
+
|
|
12955
|
+
var CHECKBOX_DISABLED_CLASS =
|
|
12956
|
+
"cursor-not-allowed opacity-50";
|
|
12449
12957
|
|
|
12450
12958
|
var CHECKBOX_CHECKED_CLASS =
|
|
12451
|
-
"data-checked:border-transparent data-checked:bg-primary-base
|
|
12959
|
+
"data-checked:border-transparent data-checked:bg-primary-base";
|
|
12960
|
+
var CHECKBOX_CHECKED_ACTIVE_CLASS =
|
|
12961
|
+
"data-checked:hover:border-primary-base data-checked:hover:shadow-primary-focused";
|
|
12452
12962
|
|
|
12453
12963
|
var LABEL_BASE_CLASS =
|
|
12454
12964
|
"cursor-pointer pb-0 text-reg-12 leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70";
|
|
@@ -12512,12 +13022,16 @@
|
|
|
12512
13022
|
|
|
12513
13023
|
// Custom checkbox visual
|
|
12514
13024
|
var checkboxBox = document.createElement("div");
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
13025
|
+
function applyCheckboxBoxClasses() {
|
|
13026
|
+
var sizeClass = CHECKBOX_SIZES[size] || CHECKBOX_SIZES.default;
|
|
13027
|
+
checkboxBox.className = join(
|
|
13028
|
+
CHECKBOX_BASE_CLASS,
|
|
13029
|
+
disabled ? CHECKBOX_DISABLED_CLASS : join(CHECKBOX_ACTIVE_CLASS, CHECKBOX_CHECKED_ACTIVE_CLASS),
|
|
13030
|
+
CHECKBOX_CHECKED_CLASS,
|
|
13031
|
+
sizeClass
|
|
13032
|
+
);
|
|
13033
|
+
}
|
|
13034
|
+
applyCheckboxBoxClasses();
|
|
12521
13035
|
checkboxBox.setAttribute("role", "checkbox");
|
|
12522
13036
|
checkboxBox.setAttribute("tabindex", disabled ? "-1" : "0");
|
|
12523
13037
|
checkboxBox.setAttribute("aria-checked", indeterminate ? "mixed" : checked ? "true" : "false");
|
|
@@ -12634,6 +13148,7 @@
|
|
|
12634
13148
|
} else {
|
|
12635
13149
|
checkboxBox.removeAttribute("aria-disabled");
|
|
12636
13150
|
}
|
|
13151
|
+
applyCheckboxBoxClasses();
|
|
12637
13152
|
updateCheckedState();
|
|
12638
13153
|
};
|
|
12639
13154
|
|
|
@@ -12666,7 +13181,210 @@
|
|
|
12666
13181
|
|
|
12667
13182
|
|
|
12668
13183
|
// ============================================
|
|
12669
|
-
// File
|
|
13184
|
+
// File 26/41: components/checkbox-group.js
|
|
13185
|
+
// ============================================
|
|
13186
|
+
|
|
13187
|
+
/**
|
|
13188
|
+
* CheckboxGroup Component (vanilla JS)
|
|
13189
|
+
* Multi-select via checkboxes; same API as MultiSelect (options, value array, onValuesChange).
|
|
13190
|
+
* Uses input.js-style variants and sizes for the group wrapper.
|
|
13191
|
+
*/
|
|
13192
|
+
|
|
13193
|
+
(function (global) {
|
|
13194
|
+
|
|
13195
|
+
// Wrapper classes aligned with input.js variants
|
|
13196
|
+
var WRAPPER_CLASS = {
|
|
13197
|
+
base:
|
|
13198
|
+
"group flex flex-col border-1/2 border-border-primary rounded-4 text-typography-primary-text w-full transition-all ease-in-out group-has-[:disabled]:cursor-not-allowed group-has-[:disabled]:border-border-primary group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:text-typography-quaternary-text",
|
|
13199
|
+
default:
|
|
13200
|
+
"bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
|
|
13201
|
+
error:
|
|
13202
|
+
"border-error-base bg-fill-quarternary-fill-white hover:border-error-base focus-within:border-error-base",
|
|
13203
|
+
warning:
|
|
13204
|
+
"border-warning-base bg-fill-quarternary-fill-white hover:border-warning-base focus-within:border-warning-base",
|
|
13205
|
+
success:
|
|
13206
|
+
"border-success-base bg-fill-quarternary-fill-white hover:border-success-base focus-within:border-success-base",
|
|
13207
|
+
borderless:
|
|
13208
|
+
"border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
|
|
13209
|
+
inline:
|
|
13210
|
+
"border-transparent shadow-none rounded-0 bg-fill-quarternary-fill-white hover:bg-fill-tertiary-fill-light-gray focus-within:border-transparent focus:bg-fill-tertiary-fill-light-gray focus-within:bg-fill-tertiary-fill-light-gray",
|
|
13211
|
+
sizeDefault: "px-12 py-6 gap-6",
|
|
13212
|
+
sizeLarge: "px-12 py-8 gap-8",
|
|
13213
|
+
sizeSmall: "px-12 py-4 gap-4",
|
|
13214
|
+
disabled:
|
|
13215
|
+
"cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
|
|
13216
|
+
};
|
|
13217
|
+
|
|
13218
|
+
function join() {
|
|
13219
|
+
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
13220
|
+
}
|
|
13221
|
+
|
|
13222
|
+
function getOptionValue(opt) {
|
|
13223
|
+
return opt.value !== undefined && opt.value !== null
|
|
13224
|
+
? opt.value
|
|
13225
|
+
: opt.slug || opt.id;
|
|
13226
|
+
}
|
|
13227
|
+
|
|
13228
|
+
function getOptionLabel(opt) {
|
|
13229
|
+
return opt.label || opt.name || opt.display_name || opt.value;
|
|
13230
|
+
}
|
|
13231
|
+
|
|
13232
|
+
function getDep(name) {
|
|
13233
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
13234
|
+
var c = global.FlowUI._getComponent(name);
|
|
13235
|
+
if (c) return c;
|
|
13236
|
+
}
|
|
13237
|
+
return global[name];
|
|
13238
|
+
}
|
|
13239
|
+
|
|
13240
|
+
/**
|
|
13241
|
+
* Create a checkbox group component (multiselect-like: multiple values, options array)
|
|
13242
|
+
* @param {Object} config
|
|
13243
|
+
* @param {string} [config.fieldId] - Field ID for state management
|
|
13244
|
+
* @param {Array} config.options - Array of { value, label } or { slug, display_name }
|
|
13245
|
+
* @param {Array} [config.value] - Current selected values (array)
|
|
13246
|
+
* @param {Function} config.onValuesChange - Change handler (values: string[])
|
|
13247
|
+
* @param {boolean} [config.disabled] - Whether all checkboxes are disabled
|
|
13248
|
+
* @param {string} [config.variant] - 'default' | 'error' | 'warning' | 'success' | 'borderless' | 'inline'
|
|
13249
|
+
* @param {string} [config.size] - 'default' | 'large' | 'small'
|
|
13250
|
+
* @param {string} [config.layout] - 'vertical' | 'horizontal'
|
|
13251
|
+
* @param {string} [config.className] - Extra class on wrapper
|
|
13252
|
+
* @returns {HTMLElement} CheckboxGroup container element
|
|
13253
|
+
*/
|
|
13254
|
+
function createCheckboxGroup(config) {
|
|
13255
|
+
var fieldId = config.fieldId;
|
|
13256
|
+
var options = config.options || [];
|
|
13257
|
+
var onValuesChange = config.onValuesChange;
|
|
13258
|
+
var variant = config.variant || "default";
|
|
13259
|
+
var size = config.size || "default";
|
|
13260
|
+
var disabled = config.disabled === true;
|
|
13261
|
+
var layout = config.layout || "vertical";
|
|
13262
|
+
var className = config.className || "";
|
|
13263
|
+
|
|
13264
|
+
var values = Array.isArray(config.value)
|
|
13265
|
+
? config.value.slice()
|
|
13266
|
+
: Array.isArray(config.values)
|
|
13267
|
+
? config.values.slice()
|
|
13268
|
+
: [];
|
|
13269
|
+
|
|
13270
|
+
var Checkbox = getDep("Checkbox");
|
|
13271
|
+
if (!Checkbox || typeof Checkbox.create !== "function") {
|
|
13272
|
+
throw new Error("CheckboxGroup requires the Checkbox component. Load checkbox.js before checkbox-group.js.");
|
|
13273
|
+
}
|
|
13274
|
+
|
|
13275
|
+
var container = document.createElement("div");
|
|
13276
|
+
container.setAttribute("role", "group");
|
|
13277
|
+
container.setAttribute("aria-label", config.ariaLabel || "Checkbox group");
|
|
13278
|
+
if (fieldId) container.setAttribute("data-field-id", fieldId);
|
|
13279
|
+
|
|
13280
|
+
var sizeClass = size === "large" ? WRAPPER_CLASS.sizeLarge : size === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault;
|
|
13281
|
+
function applyWrapperClasses() {
|
|
13282
|
+
container.className = join(
|
|
13283
|
+
WRAPPER_CLASS.base,
|
|
13284
|
+
disabled ? WRAPPER_CLASS.disabled : (WRAPPER_CLASS[variant] || WRAPPER_CLASS.default),
|
|
13285
|
+
sizeClass,
|
|
13286
|
+
layout === "horizontal" ? "flex-row flex-wrap" : "flex-col",
|
|
13287
|
+
"custom-checkbox-group",
|
|
13288
|
+
className
|
|
13289
|
+
);
|
|
13290
|
+
}
|
|
13291
|
+
applyWrapperClasses();
|
|
13292
|
+
container.setAttribute("data-checkbox-group-variant", variant);
|
|
13293
|
+
|
|
13294
|
+
function isSelected(optionValue) {
|
|
13295
|
+
return values.some(function (v) {
|
|
13296
|
+
return v === optionValue || String(v) === String(optionValue);
|
|
13297
|
+
});
|
|
13298
|
+
}
|
|
13299
|
+
|
|
13300
|
+
var optionsContainer = document.createElement("div");
|
|
13301
|
+
optionsContainer.className = join(
|
|
13302
|
+
"flex gap-8",
|
|
13303
|
+
layout === "horizontal" ? "flex-row flex-wrap" : "flex-col"
|
|
13304
|
+
);
|
|
13305
|
+
|
|
13306
|
+
function buildOptions() {
|
|
13307
|
+
optionsContainer.innerHTML = "";
|
|
13308
|
+
if (options.length === 0) {
|
|
13309
|
+
var empty = document.createElement("div");
|
|
13310
|
+
empty.className = "!text-reg-13 text-typography-quaternary-text py-4";
|
|
13311
|
+
empty.textContent = "No options available";
|
|
13312
|
+
optionsContainer.appendChild(empty);
|
|
13313
|
+
return;
|
|
13314
|
+
}
|
|
13315
|
+
|
|
13316
|
+
options.forEach(function (opt, index) {
|
|
13317
|
+
var optionValue = getOptionValue(opt);
|
|
13318
|
+
var optionLabel = getOptionLabel(opt);
|
|
13319
|
+
var optionDisabled = disabled || !!opt.disabled;
|
|
13320
|
+
var checked = isSelected(optionValue);
|
|
13321
|
+
|
|
13322
|
+
var cb = Checkbox.create({
|
|
13323
|
+
id: (fieldId || "cbg") + "-" + index,
|
|
13324
|
+
name: fieldId ? fieldId + "[]" : "checkbox-group-" + index,
|
|
13325
|
+
checked: checked,
|
|
13326
|
+
disabled: optionDisabled,
|
|
13327
|
+
label: optionLabel,
|
|
13328
|
+
align: "left",
|
|
13329
|
+
size: size === "large" ? "large" : size === "small" ? "small" : "default",
|
|
13330
|
+
onChange: function (isChecked) {
|
|
13331
|
+
if (optionDisabled) return;
|
|
13332
|
+
if (isChecked) {
|
|
13333
|
+
if (!values.some(function (v) { return v === optionValue || String(v) === String(optionValue); })) {
|
|
13334
|
+
values.push(optionValue);
|
|
13335
|
+
}
|
|
13336
|
+
} else {
|
|
13337
|
+
var idx = values.findIndex(function (v) {
|
|
13338
|
+
return v === optionValue || String(v) === String(optionValue);
|
|
13339
|
+
});
|
|
13340
|
+
if (idx >= 0) values.splice(idx, 1);
|
|
13341
|
+
}
|
|
13342
|
+
if (onValuesChange) onValuesChange(values.slice());
|
|
13343
|
+
},
|
|
13344
|
+
});
|
|
13345
|
+
optionsContainer.appendChild(cb);
|
|
13346
|
+
});
|
|
13347
|
+
}
|
|
13348
|
+
|
|
13349
|
+
buildOptions();
|
|
13350
|
+
container.appendChild(optionsContainer);
|
|
13351
|
+
|
|
13352
|
+
container.updateValues = function (newValues) {
|
|
13353
|
+
values = Array.isArray(newValues) ? newValues.slice() : [];
|
|
13354
|
+
buildOptions();
|
|
13355
|
+
};
|
|
13356
|
+
|
|
13357
|
+
container.setDisabled = function (isDisabled) {
|
|
13358
|
+
disabled = !!isDisabled;
|
|
13359
|
+
applyWrapperClasses();
|
|
13360
|
+
var wrappers = optionsContainer.querySelectorAll(":scope > div");
|
|
13361
|
+
for (var i = 0; i < wrappers.length; i++) {
|
|
13362
|
+
if (typeof wrappers[i].setDisabled === "function") wrappers[i].setDisabled(disabled);
|
|
13363
|
+
}
|
|
13364
|
+
};
|
|
13365
|
+
|
|
13366
|
+
container.setVariant = function (v) {
|
|
13367
|
+
variant = v;
|
|
13368
|
+
container.setAttribute("data-checkbox-group-variant", v);
|
|
13369
|
+
applyWrapperClasses();
|
|
13370
|
+
};
|
|
13371
|
+
|
|
13372
|
+
container.getValues = function () {
|
|
13373
|
+
return values.slice();
|
|
13374
|
+
};
|
|
13375
|
+
|
|
13376
|
+
return container;
|
|
13377
|
+
}
|
|
13378
|
+
|
|
13379
|
+
global.CheckboxGroup = {
|
|
13380
|
+
create: createCheckboxGroup,
|
|
13381
|
+
};
|
|
13382
|
+
})(typeof window !== "undefined" ? window : undefined);
|
|
13383
|
+
|
|
13384
|
+
|
|
13385
|
+
|
|
13386
|
+
// ============================================
|
|
13387
|
+
// File 27/41: components/radio-group.js
|
|
12670
13388
|
// ============================================
|
|
12671
13389
|
|
|
12672
13390
|
/**
|
|
@@ -13077,7 +13795,7 @@
|
|
|
13077
13795
|
|
|
13078
13796
|
|
|
13079
13797
|
// ============================================
|
|
13080
|
-
// File
|
|
13798
|
+
// File 28/41: components/enumeration.js
|
|
13081
13799
|
// ============================================
|
|
13082
13800
|
|
|
13083
13801
|
/**
|
|
@@ -13089,7 +13807,7 @@
|
|
|
13089
13807
|
(function (global) {
|
|
13090
13808
|
|
|
13091
13809
|
var BASE_CLASS =
|
|
13092
|
-
"flex items-center border rounded-4 text-typography-primary-text gap-4 !text-reg-13";
|
|
13810
|
+
"flex items-center border-1/2 rounded-4 text-typography-primary-text gap-4 !text-reg-13";
|
|
13093
13811
|
|
|
13094
13812
|
var VARIANTS = {
|
|
13095
13813
|
default:
|
|
@@ -13113,7 +13831,7 @@
|
|
|
13113
13831
|
};
|
|
13114
13832
|
|
|
13115
13833
|
var DISABLED_CLASS =
|
|
13116
|
-
"pointer-events-none !cursor-not-allowed opacity-50";
|
|
13834
|
+
"pointer-events-none !cursor-not-allowed opacity-50 bg-fill-tertiary-fill-light-gray";
|
|
13117
13835
|
var READONLY_CLASS = "pointer-events-none";
|
|
13118
13836
|
|
|
13119
13837
|
var ITEM_BASE_CLASS =
|
|
@@ -13178,14 +13896,17 @@
|
|
|
13178
13896
|
var children = opts.children;
|
|
13179
13897
|
|
|
13180
13898
|
var wrapper = document.createElement("div");
|
|
13181
|
-
|
|
13182
|
-
|
|
13183
|
-
|
|
13184
|
-
|
|
13185
|
-
|
|
13186
|
-
|
|
13187
|
-
|
|
13188
|
-
|
|
13899
|
+
function applyWrapperClasses() {
|
|
13900
|
+
wrapper.className = join(
|
|
13901
|
+
BASE_CLASS,
|
|
13902
|
+
VARIANTS[variant] != null ? VARIANTS[variant] : VARIANTS.default,
|
|
13903
|
+
SIZES[size] != null ? SIZES[size] : SIZES.default,
|
|
13904
|
+
disabled ? DISABLED_CLASS : "",
|
|
13905
|
+
readOnly ? READONLY_CLASS : "",
|
|
13906
|
+
className
|
|
13907
|
+
);
|
|
13908
|
+
}
|
|
13909
|
+
applyWrapperClasses();
|
|
13189
13910
|
wrapper.setAttribute("data-enumeration-variant", variant);
|
|
13190
13911
|
|
|
13191
13912
|
var count =
|
|
@@ -13255,6 +13976,22 @@
|
|
|
13255
13976
|
}
|
|
13256
13977
|
}
|
|
13257
13978
|
|
|
13979
|
+
wrapper.setDisabled = function (d) {
|
|
13980
|
+
disabled = d === true;
|
|
13981
|
+
for (var j = 0; j < itemElements.length; j++) {
|
|
13982
|
+
itemElements[j].setAttribute("tabindex", disabled || readOnly ? "-1" : "0");
|
|
13983
|
+
}
|
|
13984
|
+
applyWrapperClasses();
|
|
13985
|
+
};
|
|
13986
|
+
|
|
13987
|
+
wrapper.setReadOnly = function (r) {
|
|
13988
|
+
readOnly = r === true;
|
|
13989
|
+
for (var j = 0; j < itemElements.length; j++) {
|
|
13990
|
+
itemElements[j].setAttribute("tabindex", disabled || readOnly ? "-1" : "0");
|
|
13991
|
+
}
|
|
13992
|
+
applyWrapperClasses();
|
|
13993
|
+
};
|
|
13994
|
+
|
|
13258
13995
|
return wrapper;
|
|
13259
13996
|
}
|
|
13260
13997
|
|
|
@@ -13296,7 +14033,7 @@
|
|
|
13296
14033
|
|
|
13297
14034
|
|
|
13298
14035
|
// ============================================
|
|
13299
|
-
// File
|
|
14036
|
+
// File 29/41: components/time-picker.js
|
|
13300
14037
|
// ============================================
|
|
13301
14038
|
|
|
13302
14039
|
/**
|
|
@@ -13596,12 +14333,12 @@
|
|
|
13596
14333
|
if (periodColumn) periodColumn.scrollToSelected();
|
|
13597
14334
|
}
|
|
13598
14335
|
|
|
14336
|
+
// Trigger must be in DOM before Popover.create() so Popover can wrap it and insert its panel into the document.
|
|
14337
|
+
container.appendChild(trigger);
|
|
14338
|
+
|
|
13599
14339
|
var Popover = getDep("Popover");
|
|
13600
14340
|
if (!Popover || typeof Popover.create !== "function") {
|
|
13601
|
-
|
|
13602
|
-
container.updateValue = function (newVal) { value = typeof newVal === "string" ? newVal : ""; };
|
|
13603
|
-
container.setDisabled = function (isDisabled) { trigger.disabled = !!isDisabled; };
|
|
13604
|
-
return container;
|
|
14341
|
+
throw new Error("TimePicker requires Popover");
|
|
13605
14342
|
}
|
|
13606
14343
|
var popover = Popover.create({
|
|
13607
14344
|
trigger: trigger,
|
|
@@ -13622,8 +14359,6 @@
|
|
|
13622
14359
|
});
|
|
13623
14360
|
hidePopover = popover.hide;
|
|
13624
14361
|
|
|
13625
|
-
container.appendChild(trigger);
|
|
13626
|
-
|
|
13627
14362
|
container.updateValue = function (newVal) {
|
|
13628
14363
|
value = typeof newVal === "string" ? newVal : "";
|
|
13629
14364
|
var p = parseValue(value);
|
|
@@ -13659,7 +14394,7 @@
|
|
|
13659
14394
|
|
|
13660
14395
|
|
|
13661
14396
|
// ============================================
|
|
13662
|
-
// File
|
|
14397
|
+
// File 30/41: components/duration/duration-utils.js
|
|
13663
14398
|
// ============================================
|
|
13664
14399
|
|
|
13665
14400
|
/**
|
|
@@ -13829,7 +14564,7 @@
|
|
|
13829
14564
|
|
|
13830
14565
|
|
|
13831
14566
|
// ============================================
|
|
13832
|
-
// File
|
|
14567
|
+
// File 31/41: components/duration/duration-constants.js
|
|
13833
14568
|
// ============================================
|
|
13834
14569
|
|
|
13835
14570
|
/**
|
|
@@ -13881,7 +14616,7 @@
|
|
|
13881
14616
|
|
|
13882
14617
|
|
|
13883
14618
|
// ============================================
|
|
13884
|
-
// File
|
|
14619
|
+
// File 32/41: components/duration/duration.js
|
|
13885
14620
|
// ============================================
|
|
13886
14621
|
|
|
13887
14622
|
/**
|
|
@@ -13925,7 +14660,7 @@
|
|
|
13925
14660
|
sizeLarge: "px-12 py-8",
|
|
13926
14661
|
sizeSmall: "px-12 py-4",
|
|
13927
14662
|
disabled:
|
|
13928
|
-
"cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary
|
|
14663
|
+
"pointer-events-none cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
|
|
13929
14664
|
};
|
|
13930
14665
|
|
|
13931
14666
|
function join() {
|
|
@@ -14318,8 +15053,13 @@
|
|
|
14318
15053
|
};
|
|
14319
15054
|
container.setDisabled = function (d) {
|
|
14320
15055
|
disabled = !!d;
|
|
14321
|
-
triggerWrapper.
|
|
14322
|
-
|
|
15056
|
+
triggerWrapper.className = join(
|
|
15057
|
+
TRIGGER_CLASS.base,
|
|
15058
|
+
TRIGGER_CLASS[variant] != null ? TRIGGER_CLASS[variant] : TRIGGER_CLASS.default,
|
|
15059
|
+
size === "large" ? TRIGGER_CLASS.sizeLarge : size === "small" ? TRIGGER_CLASS.sizeSmall : TRIGGER_CLASS.sizeDefault,
|
|
15060
|
+
disabled ? TRIGGER_CLASS.disabled : "",
|
|
15061
|
+
className
|
|
15062
|
+
);
|
|
14323
15063
|
triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
|
|
14324
15064
|
if (disabled) popoverApi.hide();
|
|
14325
15065
|
};
|
|
@@ -14335,7 +15075,7 @@
|
|
|
14335
15075
|
|
|
14336
15076
|
|
|
14337
15077
|
// ============================================
|
|
14338
|
-
// File
|
|
15078
|
+
// File 33/41: components/date-time-picker/date-time-picker-utils.js
|
|
14339
15079
|
// ============================================
|
|
14340
15080
|
|
|
14341
15081
|
/**
|
|
@@ -14594,7 +15334,7 @@
|
|
|
14594
15334
|
|
|
14595
15335
|
|
|
14596
15336
|
// ============================================
|
|
14597
|
-
// File
|
|
15337
|
+
// File 34/41: components/date-time-picker/date-time-picker.js
|
|
14598
15338
|
// ============================================
|
|
14599
15339
|
|
|
14600
15340
|
/**
|
|
@@ -14771,7 +15511,7 @@
|
|
|
14771
15511
|
variant = "outline";
|
|
14772
15512
|
}
|
|
14773
15513
|
var btnClassName = join(
|
|
14774
|
-
"!text-reg-12 my-2 flex-1
|
|
15514
|
+
"!text-reg-12 my-2 flex-1",
|
|
14775
15515
|
cell.currentMonth ? "" : "text-typography-quaternary-text"
|
|
14776
15516
|
);
|
|
14777
15517
|
var btn = Button.create({
|
|
@@ -14839,13 +15579,15 @@
|
|
|
14839
15579
|
var displayMonth = validDate ? new Date(validDate.getTime()) : new Date();
|
|
14840
15580
|
|
|
14841
15581
|
var triggerWrapper = document.createElement("div");
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
|
|
14846
|
-
|
|
14847
|
-
|
|
14848
|
-
|
|
15582
|
+
function getTriggerClassName(disabledState) {
|
|
15583
|
+
return join(
|
|
15584
|
+
"group flex items-center border-1/2 border-border-primary rounded-4 text-typography-primary-text gap-x-8 w-full transition-all ease-in-out",
|
|
15585
|
+
"bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
|
|
15586
|
+
size === "large" ? "px-12 py-8" : size === "small" ? "px-12 py-4" : "px-12 py-6",
|
|
15587
|
+
disabledState ? "pointer-events-none cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary" : "cursor-pointer"
|
|
15588
|
+
);
|
|
15589
|
+
}
|
|
15590
|
+
triggerWrapper.className = getTriggerClassName(disabled);
|
|
14849
15591
|
triggerWrapper.setAttribute("role", "button");
|
|
14850
15592
|
triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
|
|
14851
15593
|
triggerWrapper.setAttribute("aria-haspopup", "dialog");
|
|
@@ -15113,8 +15855,7 @@
|
|
|
15113
15855
|
};
|
|
15114
15856
|
container.setDisabled = function (d) {
|
|
15115
15857
|
disabled = !!d;
|
|
15116
|
-
triggerWrapper.
|
|
15117
|
-
triggerWrapper.classList.toggle("opacity-60", disabled);
|
|
15858
|
+
triggerWrapper.className = getTriggerClassName(disabled);
|
|
15118
15859
|
triggerWrapper.setAttribute("tabindex", disabled ? "-1" : "0");
|
|
15119
15860
|
if (disabled) popoverApi.hide();
|
|
15120
15861
|
};
|
|
@@ -15130,7 +15871,7 @@
|
|
|
15130
15871
|
|
|
15131
15872
|
|
|
15132
15873
|
// ============================================
|
|
15133
|
-
// File
|
|
15874
|
+
// File 35/41: components/phone-input/phone-utils.js
|
|
15134
15875
|
// ============================================
|
|
15135
15876
|
|
|
15136
15877
|
/**
|
|
@@ -15293,7 +16034,7 @@
|
|
|
15293
16034
|
|
|
15294
16035
|
|
|
15295
16036
|
// ============================================
|
|
15296
|
-
// File
|
|
16037
|
+
// File 36/41: components/phone-input/phone-input.js
|
|
15297
16038
|
// ============================================
|
|
15298
16039
|
|
|
15299
16040
|
/**
|
|
@@ -15691,7 +16432,7 @@
|
|
|
15691
16432
|
|
|
15692
16433
|
|
|
15693
16434
|
// ============================================
|
|
15694
|
-
// File
|
|
16435
|
+
// File 37/41: components/file-input.js
|
|
15695
16436
|
// ============================================
|
|
15696
16437
|
|
|
15697
16438
|
/**
|
|
@@ -15735,6 +16476,15 @@
|
|
|
15735
16476
|
return ICONS.file;
|
|
15736
16477
|
}
|
|
15737
16478
|
|
|
16479
|
+
/** Resolve client: use FlowUI._getComponent when bundle has captured globals, else global.superleapClient (same as enum-select) */
|
|
16480
|
+
function getClient() {
|
|
16481
|
+
if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
|
|
16482
|
+
var c = global.FlowUI._getComponent("superleapClient");
|
|
16483
|
+
if (c) return c;
|
|
16484
|
+
}
|
|
16485
|
+
return global.superleapClient;
|
|
16486
|
+
}
|
|
16487
|
+
|
|
15738
16488
|
/**
|
|
15739
16489
|
* Upload file to S3
|
|
15740
16490
|
* @param {File} file - File to upload
|
|
@@ -15746,26 +16496,31 @@
|
|
|
15746
16496
|
formData.append("file", file, file.name);
|
|
15747
16497
|
formData.append("is_private", String(!!isPrivate));
|
|
15748
16498
|
|
|
15749
|
-
// Get upload
|
|
16499
|
+
// Get upload path - can be configured via global.S3_UPLOAD_URL
|
|
15750
16500
|
const uploadUrl = global.S3_UPLOAD_URL || "/org/file/upload";
|
|
15751
|
-
const baseUrl = global.SUPERLEAP_BASE_URL || "https://app.superleap.com/api/v1";
|
|
15752
|
-
const fullUrl = uploadUrl.startsWith("http") ? uploadUrl : `${baseUrl}${uploadUrl}`;
|
|
15753
16501
|
|
|
15754
|
-
//
|
|
15755
|
-
|
|
16502
|
+
// Base URL and API key from superleapClient only (same pattern as enum-select)
|
|
16503
|
+
var client = getClient();
|
|
16504
|
+
var baseUrl = null;
|
|
16505
|
+
var apiKey = null;
|
|
15756
16506
|
try {
|
|
15757
|
-
|
|
15758
|
-
|
|
15759
|
-
|
|
15760
|
-
: global.superleapClient;
|
|
16507
|
+
if (client && typeof client.getBaseUrl === "function") {
|
|
16508
|
+
baseUrl = client.getBaseUrl();
|
|
16509
|
+
}
|
|
15761
16510
|
if (client && typeof client.getSdk === "function") {
|
|
15762
|
-
|
|
15763
|
-
apiKey = sdk
|
|
16511
|
+
var sdk = client.getSdk();
|
|
16512
|
+
apiKey = sdk ? sdk.apiKey : null;
|
|
15764
16513
|
}
|
|
15765
16514
|
} catch (e) {
|
|
15766
|
-
console.warn("[S3FileUpload] Could not get
|
|
16515
|
+
console.warn("[S3FileUpload] Could not get client:", e);
|
|
15767
16516
|
}
|
|
15768
16517
|
|
|
16518
|
+
if (!baseUrl) {
|
|
16519
|
+
throw new Error("SuperLeap client not initialized. Call superleapClient.init({ baseUrl, apiKey }) first.");
|
|
16520
|
+
}
|
|
16521
|
+
|
|
16522
|
+
const fullUrl = uploadUrl.startsWith("http") ? uploadUrl : baseUrl.replace(/\/$/, "") + (uploadUrl.startsWith("/") ? uploadUrl : "/" + uploadUrl);
|
|
16523
|
+
|
|
15769
16524
|
const headers = {};
|
|
15770
16525
|
if (apiKey) {
|
|
15771
16526
|
headers.Authorization = `Bearer ${apiKey}`;
|
|
@@ -15809,8 +16564,36 @@
|
|
|
15809
16564
|
* @param {boolean} config.isPrivate - Whether files should be private
|
|
15810
16565
|
* @param {number} config.maxFiles - Maximum number of files (for multiple mode)
|
|
15811
16566
|
* @param {number} config.maxFileSize - Maximum file size in bytes
|
|
16567
|
+
* @param {boolean} [config.disabled] - Whether the file upload is disabled
|
|
16568
|
+
* @param {string} [config.variant] - 'default' | 'error' | 'warning' | 'success' | 'borderless' | 'inline'
|
|
16569
|
+
* @param {string} [config.inputSize] - 'default' | 'large' | 'small'
|
|
16570
|
+
* @param {string} [config.className] - Extra class on upload wrapper
|
|
15812
16571
|
* @returns {HTMLElement} Field element
|
|
15813
16572
|
*/
|
|
16573
|
+
var UPLOAD_WRAPPER_CLASS = {
|
|
16574
|
+
base:
|
|
16575
|
+
"group relative flex w-full items-center justify-between border-1/2 rounded-4 text-typography-primary-text w-full transition-all ease-in-out focus-within:outline-none group-has-[:disabled]:cursor-not-allowed group-has-[:disabled]:border-border-primary group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:text-typography-quaternary-text group-has-[:disabled]:hover:border-border-primary",
|
|
16576
|
+
default:
|
|
16577
|
+
"border-border-primary bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
|
|
16578
|
+
error:
|
|
16579
|
+
"border-error-base bg-fill-quarternary-fill-white hover:border-error-base focus-within:border-error-base",
|
|
16580
|
+
warning:
|
|
16581
|
+
"border-warning-base bg-fill-quarternary-fill-white hover:border-warning-base focus-within:border-warning-base",
|
|
16582
|
+
success:
|
|
16583
|
+
"border-success-base bg-fill-quarternary-fill-white hover:border-success-base focus-within:border-success-base",
|
|
16584
|
+
borderless:
|
|
16585
|
+
"border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
|
|
16586
|
+
inline:
|
|
16587
|
+
"border-transparent shadow-none rounded-0 bg-fill-quarternary-fill-white hover:bg-fill-tertiary-fill-light-gray focus-within:border-transparent focus-within:bg-fill-tertiary-fill-light-gray",
|
|
16588
|
+
sizeDefault: "px-12 py-4",
|
|
16589
|
+
sizeLarge: "px-12 py-6",
|
|
16590
|
+
sizeSmall: "px-12 py-2",
|
|
16591
|
+
};
|
|
16592
|
+
|
|
16593
|
+
function joinClasses() {
|
|
16594
|
+
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
16595
|
+
}
|
|
16596
|
+
|
|
15814
16597
|
function create(config) {
|
|
15815
16598
|
const {
|
|
15816
16599
|
label,
|
|
@@ -15822,7 +16605,14 @@
|
|
|
15822
16605
|
isPrivate = false,
|
|
15823
16606
|
maxFiles = null,
|
|
15824
16607
|
maxFileSize = 10 * 1024 * 1024, // 10MB default
|
|
16608
|
+
disabled = false,
|
|
16609
|
+
variant = "default",
|
|
16610
|
+
inputSize = "default",
|
|
16611
|
+
className = "",
|
|
15825
16612
|
} = config;
|
|
16613
|
+
let disabledState = !!disabled;
|
|
16614
|
+
let currentVariant = variant;
|
|
16615
|
+
let currentInputSize = inputSize;
|
|
15826
16616
|
|
|
15827
16617
|
if (!global.FlowUI) {
|
|
15828
16618
|
throw new Error("FlowUI not available");
|
|
@@ -15840,12 +16630,33 @@
|
|
|
15840
16630
|
|
|
15841
16631
|
// Upload row: button + status + optional end spinner (match Select/MultiSelect trigger)
|
|
15842
16632
|
const uploadWrapper = document.createElement("div");
|
|
15843
|
-
|
|
16633
|
+
var sizeClass =
|
|
16634
|
+
currentInputSize === "large"
|
|
16635
|
+
? UPLOAD_WRAPPER_CLASS.sizeLarge
|
|
16636
|
+
: currentInputSize === "small"
|
|
16637
|
+
? UPLOAD_WRAPPER_CLASS.sizeSmall
|
|
16638
|
+
: UPLOAD_WRAPPER_CLASS.sizeDefault;
|
|
16639
|
+
function applyWrapperClasses() {
|
|
16640
|
+
uploadWrapper.className = joinClasses(
|
|
16641
|
+
UPLOAD_WRAPPER_CLASS.base,
|
|
16642
|
+
UPLOAD_WRAPPER_CLASS[currentVariant] || UPLOAD_WRAPPER_CLASS.default,
|
|
16643
|
+
sizeClass,
|
|
16644
|
+
className
|
|
16645
|
+
);
|
|
16646
|
+
}
|
|
16647
|
+
applyWrapperClasses();
|
|
16648
|
+
uploadWrapper.setAttribute("data-file-input-variant", currentVariant);
|
|
16649
|
+
uploadWrapper.setAttribute("data-file-input-size", currentInputSize);
|
|
16650
|
+
uploadWrapper.setAttribute("data-disabled", disabledState ? "true" : "false");
|
|
15844
16651
|
|
|
15845
16652
|
// Left content (button + status) – pointer-events-none so overlay input receives clicks
|
|
15846
16653
|
const leftContent = document.createElement("div");
|
|
15847
16654
|
leftContent.className = "pointer-events-none flex min-w-0 flex-1 items-center gap-8 truncate";
|
|
15848
16655
|
|
|
16656
|
+
var disabledChildClasses =
|
|
16657
|
+
"group-has-[:disabled]:text-typography-quaternary-text group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:hover:bg-fill-tertiary-fill-light-gray";
|
|
16658
|
+
var statusTextBaseClass = "text-reg-13 min-w-0 flex-1 truncate";
|
|
16659
|
+
var statusTextDisabledClass = " group-has-[:disabled]:text-typography-quaternary-text";
|
|
15849
16660
|
const useButtonComponent = global.Button && typeof global.Button.create === "function";
|
|
15850
16661
|
const initialButtonText = multiple ? "Choose files" : "Choose a file";
|
|
15851
16662
|
const btn = useButtonComponent
|
|
@@ -15853,31 +16664,41 @@
|
|
|
15853
16664
|
variant: "outline",
|
|
15854
16665
|
size: "small",
|
|
15855
16666
|
text: initialButtonText,
|
|
15856
|
-
className: "shrink-0 truncate",
|
|
16667
|
+
className: "shrink-0 truncate " + disabledChildClasses,
|
|
15857
16668
|
})
|
|
15858
16669
|
: (function () {
|
|
15859
16670
|
const el = document.createElement("div");
|
|
15860
|
-
el.className =
|
|
16671
|
+
el.className =
|
|
16672
|
+
"shrink-0 truncate rounded-2 border-1/2 border-border-primary bg-fill-tertiary-fill-light-gray px-8 py-1 text-reg-13 text-typography-primary-text transition-colors duration-150 hover:bg-fill-secondary-fill-gray " +
|
|
16673
|
+
disabledChildClasses;
|
|
15861
16674
|
el.textContent = initialButtonText;
|
|
15862
16675
|
return el;
|
|
15863
16676
|
})();
|
|
15864
16677
|
|
|
15865
16678
|
// Status text: "No files chosen" (quaternary) or "X file(s) selected"
|
|
15866
16679
|
const statusText = document.createElement("p");
|
|
15867
|
-
statusText.className =
|
|
16680
|
+
statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
|
|
15868
16681
|
|
|
15869
16682
|
// Hidden file input – overlays row, high z-index so it receives clicks
|
|
15870
16683
|
const input = document.createElement("input");
|
|
15871
16684
|
input.type = "file";
|
|
15872
|
-
|
|
16685
|
+
const inputBaseClass = "absolute inset-0 z-10 w-full opacity-0";
|
|
16686
|
+
function applyInputClasses() {
|
|
16687
|
+
input.className =
|
|
16688
|
+
inputBaseClass +
|
|
16689
|
+
(disabledState ? " !pointer-events-none !cursor-not-allowed" : " cursor-pointer");
|
|
16690
|
+
}
|
|
16691
|
+
applyInputClasses();
|
|
15873
16692
|
input.multiple = multiple;
|
|
16693
|
+
input.disabled = disabledState;
|
|
15874
16694
|
if (accept !== "*") {
|
|
15875
16695
|
input.accept = accept;
|
|
15876
16696
|
}
|
|
15877
16697
|
|
|
15878
16698
|
// End icon slot: spinner when uploading (match Select chevron position)
|
|
15879
16699
|
const endIconSlot = document.createElement("div");
|
|
15880
|
-
endIconSlot.className =
|
|
16700
|
+
endIconSlot.className =
|
|
16701
|
+
"ml-4 flex size-16 items-center justify-center shrink-0 text-typography-quaternary-text group-has-[:disabled]:text-typography-quaternary-text";
|
|
15881
16702
|
endIconSlot.style.display = "none";
|
|
15882
16703
|
|
|
15883
16704
|
// Uploaded files: badge list (match UploadedFilePreviewer – flex-wrap gap-2)
|
|
@@ -15916,15 +16737,13 @@
|
|
|
15916
16737
|
e.stopPropagation();
|
|
15917
16738
|
navigator.clipboard.writeText(fileUrl).then(
|
|
15918
16739
|
function () {
|
|
15919
|
-
if (global.FlowUI && global.FlowUI.
|
|
15920
|
-
|
|
15921
|
-
if (ac) global.FlowUI.renderAlerts(ac, ["Link copied"], "success");
|
|
16740
|
+
if (global.FlowUI && global.FlowUI.showToast) {
|
|
16741
|
+
global.FlowUI.showToast("Link copied", "success");
|
|
15922
16742
|
}
|
|
15923
16743
|
},
|
|
15924
16744
|
function () {
|
|
15925
|
-
if (global.FlowUI && global.FlowUI.
|
|
15926
|
-
|
|
15927
|
-
if (ac) global.FlowUI.renderAlerts(ac, ["Copy failed"], "error");
|
|
16745
|
+
if (global.FlowUI && global.FlowUI.showToast) {
|
|
16746
|
+
global.FlowUI.showToast("Copy failed", "error");
|
|
15928
16747
|
}
|
|
15929
16748
|
}
|
|
15930
16749
|
);
|
|
@@ -16060,13 +16879,13 @@
|
|
|
16060
16879
|
|
|
16061
16880
|
if (!filesChosen) {
|
|
16062
16881
|
statusText.textContent = "No files chosen";
|
|
16063
|
-
statusText.className =
|
|
16882
|
+
statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
|
|
16064
16883
|
} else if (uploadingCount > 0) {
|
|
16065
16884
|
statusText.textContent = "Uploading…";
|
|
16066
|
-
statusText.className =
|
|
16885
|
+
statusText.className = statusTextBaseClass + " text-typography-quaternary-text" + statusTextDisabledClass;
|
|
16067
16886
|
} else {
|
|
16068
16887
|
statusText.textContent = `${uploadedCount} file${uploadedCount !== 1 ? "s" : ""} selected`;
|
|
16069
|
-
statusText.className =
|
|
16888
|
+
statusText.className = statusTextBaseClass + " text-typography-primary-text" + statusTextDisabledClass;
|
|
16070
16889
|
}
|
|
16071
16890
|
|
|
16072
16891
|
endIconSlot.style.display = uploadingCount > 0 ? "flex" : "none";
|
|
@@ -16120,11 +16939,8 @@
|
|
|
16120
16939
|
async function uploadFile(file) {
|
|
16121
16940
|
const error = validateFile(file);
|
|
16122
16941
|
if (error) {
|
|
16123
|
-
if (global.FlowUI && global.FlowUI.
|
|
16124
|
-
|
|
16125
|
-
if (alertsContainer) {
|
|
16126
|
-
global.FlowUI.renderAlerts(alertsContainer, [error], "error");
|
|
16127
|
-
}
|
|
16942
|
+
if (global.FlowUI && global.FlowUI.showToast) {
|
|
16943
|
+
global.FlowUI.showToast(error, "error");
|
|
16128
16944
|
}
|
|
16129
16945
|
return;
|
|
16130
16946
|
}
|
|
@@ -16152,15 +16968,8 @@
|
|
|
16152
16968
|
uploadingFiles = uploadingFiles.filter((f) => f.file !== file);
|
|
16153
16969
|
renderUploadingList();
|
|
16154
16970
|
updateStatus();
|
|
16155
|
-
if (global.FlowUI && global.FlowUI.
|
|
16156
|
-
|
|
16157
|
-
if (alertsContainer) {
|
|
16158
|
-
global.FlowUI.renderAlerts(
|
|
16159
|
-
alertsContainer,
|
|
16160
|
-
[`Failed to upload "${file.name}": ${error.message}`],
|
|
16161
|
-
"error"
|
|
16162
|
-
);
|
|
16163
|
-
}
|
|
16971
|
+
if (global.FlowUI && global.FlowUI.showToast) {
|
|
16972
|
+
global.FlowUI.showToast(`Failed to upload "${file.name}": ${error.message}`, "error");
|
|
16164
16973
|
}
|
|
16165
16974
|
}
|
|
16166
16975
|
}
|
|
@@ -16173,11 +16982,8 @@
|
|
|
16173
16982
|
// Check max files limit
|
|
16174
16983
|
if (multiple && maxFiles && uploadedFiles.length + files.length > maxFiles) {
|
|
16175
16984
|
const message = `You can only upload ${maxFiles} file${maxFiles !== 1 ? "s" : ""}`;
|
|
16176
|
-
if (global.FlowUI && global.FlowUI.
|
|
16177
|
-
|
|
16178
|
-
if (alertsContainer) {
|
|
16179
|
-
global.FlowUI.renderAlerts(alertsContainer, [message], "error");
|
|
16180
|
-
}
|
|
16985
|
+
if (global.FlowUI && global.FlowUI.showToast) {
|
|
16986
|
+
global.FlowUI.showToast(message, "error");
|
|
16181
16987
|
}
|
|
16182
16988
|
input.value = "";
|
|
16183
16989
|
return;
|
|
@@ -16216,6 +17022,32 @@
|
|
|
16216
17022
|
loadExistingFiles();
|
|
16217
17023
|
updateStatus();
|
|
16218
17024
|
|
|
17025
|
+
field.setDisabled = function (d) {
|
|
17026
|
+
disabledState = !!d;
|
|
17027
|
+
input.disabled = disabledState;
|
|
17028
|
+
applyInputClasses();
|
|
17029
|
+
applyWrapperClasses();
|
|
17030
|
+
uploadWrapper.setAttribute("data-disabled", disabledState ? "true" : "false");
|
|
17031
|
+
};
|
|
17032
|
+
|
|
17033
|
+
field.setVariant = function (v) {
|
|
17034
|
+
currentVariant = v || "default";
|
|
17035
|
+
uploadWrapper.setAttribute("data-file-input-variant", currentVariant);
|
|
17036
|
+
applyWrapperClasses();
|
|
17037
|
+
};
|
|
17038
|
+
|
|
17039
|
+
field.setInputSize = function (s) {
|
|
17040
|
+
currentInputSize = s || "default";
|
|
17041
|
+
sizeClass =
|
|
17042
|
+
currentInputSize === "large"
|
|
17043
|
+
? UPLOAD_WRAPPER_CLASS.sizeLarge
|
|
17044
|
+
: currentInputSize === "small"
|
|
17045
|
+
? UPLOAD_WRAPPER_CLASS.sizeSmall
|
|
17046
|
+
: UPLOAD_WRAPPER_CLASS.sizeDefault;
|
|
17047
|
+
uploadWrapper.setAttribute("data-file-input-size", currentInputSize);
|
|
17048
|
+
applyWrapperClasses();
|
|
17049
|
+
};
|
|
17050
|
+
|
|
16219
17051
|
return field;
|
|
16220
17052
|
}
|
|
16221
17053
|
|
|
@@ -16230,7 +17062,7 @@
|
|
|
16230
17062
|
|
|
16231
17063
|
|
|
16232
17064
|
// ============================================
|
|
16233
|
-
// File
|
|
17065
|
+
// File 38/41: components/table.js
|
|
16234
17066
|
// ============================================
|
|
16235
17067
|
|
|
16236
17068
|
/**
|
|
@@ -16571,7 +17403,455 @@
|
|
|
16571
17403
|
|
|
16572
17404
|
|
|
16573
17405
|
// ============================================
|
|
16574
|
-
// File
|
|
17406
|
+
// File 39/41: components/tabs.js
|
|
17407
|
+
// ============================================
|
|
17408
|
+
|
|
17409
|
+
/**
|
|
17410
|
+
* Tabs Component (vanilla JS)
|
|
17411
|
+
* Tabbed interface with list, triggers, and content panels.
|
|
17412
|
+
* Ref: Radix-style Tabs; design tokens match design system.
|
|
17413
|
+
*/
|
|
17414
|
+
|
|
17415
|
+
(function (global) {
|
|
17416
|
+
|
|
17417
|
+
function getComponent(name) {
|
|
17418
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
17419
|
+
var c = global.FlowUI._getComponent(name);
|
|
17420
|
+
if (c) return c;
|
|
17421
|
+
}
|
|
17422
|
+
return global[name];
|
|
17423
|
+
}
|
|
17424
|
+
|
|
17425
|
+
var LIST_BASE_CLASS =
|
|
17426
|
+
"inline-flex items-center justify-center gap-2 rounded-4 bg-fill-tertiary-fill-light-gray p-4";
|
|
17427
|
+
|
|
17428
|
+
/** Button variant classes for active (outline) vs inactive (ghost) */
|
|
17429
|
+
var BUTTON_OUTLINE =
|
|
17430
|
+
"shadow-soft-extra-small group bg-fill-quarternary-fill-white border-1/2 border-border-primary text-typography-primary-text hover:bg-fill-tertiary-fill-light-gray active:bg-fill-secondary-fill-gray disabled:opacity-50 disabled:border-fill-secondary-fill-gray";
|
|
17431
|
+
var BUTTON_GHOST =
|
|
17432
|
+
"group text-typography-primary-text hover:bg-fill-tertiary-fill-light-gray active:bg-fill-secondary-fill-gray disabled:text-typography-quaternary-text";
|
|
17433
|
+
var BUTTON_BASE =
|
|
17434
|
+
"inline-flex items-center justify-center whitespace-nowrap !text-med-12 transition-colors disabled:pointer-events-none hover:cursor-pointer h-fit";
|
|
17435
|
+
var BUTTON_SIZES = {
|
|
17436
|
+
default: "px-8 py-4 gap-4 rounded-4",
|
|
17437
|
+
small: "px-8 py-4 gap-4 rounded-4",
|
|
17438
|
+
large: "px-16 py-8 gap-4 rounded-4",
|
|
17439
|
+
};
|
|
17440
|
+
|
|
17441
|
+
var CONTENT_BASE_CLASS =
|
|
17442
|
+
"ring-offset-background focus-visible:ring-ring h-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2";
|
|
17443
|
+
|
|
17444
|
+
function join() {
|
|
17445
|
+
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
17446
|
+
}
|
|
17447
|
+
|
|
17448
|
+
/**
|
|
17449
|
+
* Create a full Tabs component (list + triggers + content panels)
|
|
17450
|
+
* @param {Object} config
|
|
17451
|
+
* @param {string} [config.defaultValue] - initial active tab value
|
|
17452
|
+
* @param {string} [config.value] - controlled active value
|
|
17453
|
+
* @param {Function} [config.onChange] - (value) => void when tab changes
|
|
17454
|
+
* @param {Array<{value: string, label: string, content: HTMLElement|string}>} config.tabs - tab definitions
|
|
17455
|
+
* @param {string} [config.size] - 'default' | 'small' | 'large'
|
|
17456
|
+
* @param {string} [config.listClassName] - extra class on list
|
|
17457
|
+
* @param {string} [config.contentClassName] - extra class on content wrapper
|
|
17458
|
+
* @returns {HTMLElement} root element (wrapper containing list + content area)
|
|
17459
|
+
*/
|
|
17460
|
+
function create(config) {
|
|
17461
|
+
var opts = config || {};
|
|
17462
|
+
var defaultValue = opts.defaultValue;
|
|
17463
|
+
var controlledValue = opts.value;
|
|
17464
|
+
var onChange = opts.onChange;
|
|
17465
|
+
var tabs = opts.tabs || [];
|
|
17466
|
+
var size = opts.size || "default";
|
|
17467
|
+
var listClassName = opts.listClassName || "";
|
|
17468
|
+
var contentClassName = opts.contentClassName || "";
|
|
17469
|
+
|
|
17470
|
+
var sizeClass = BUTTON_SIZES[size] || BUTTON_SIZES.default;
|
|
17471
|
+
|
|
17472
|
+
var root = document.createElement("div");
|
|
17473
|
+
root.className = "tabs-root w-full";
|
|
17474
|
+
|
|
17475
|
+
var activeValue = controlledValue !== undefined ? controlledValue : defaultValue !== undefined ? defaultValue : (tabs[0] && tabs[0].value) || "";
|
|
17476
|
+
|
|
17477
|
+
// List container
|
|
17478
|
+
var list = document.createElement("div");
|
|
17479
|
+
list.setAttribute("role", "tablist");
|
|
17480
|
+
list.className = join(LIST_BASE_CLASS, listClassName);
|
|
17481
|
+
|
|
17482
|
+
// Content container (holds all panels; we show/hide by value)
|
|
17483
|
+
var contentWrapper = document.createElement("div");
|
|
17484
|
+
contentWrapper.className = join("tabs-content-wrapper mt-4", contentClassName);
|
|
17485
|
+
|
|
17486
|
+
var triggerEls = [];
|
|
17487
|
+
var contentPanels = [];
|
|
17488
|
+
|
|
17489
|
+
var Button = getComponent("Button");
|
|
17490
|
+
|
|
17491
|
+
tabs.forEach(function (tab, index) {
|
|
17492
|
+
var value = tab.value;
|
|
17493
|
+
var label = tab.label != null ? tab.label : value;
|
|
17494
|
+
var content = tab.content;
|
|
17495
|
+
|
|
17496
|
+
var isActive = value === activeValue;
|
|
17497
|
+
var trigger = Button.create({
|
|
17498
|
+
variant: isActive ? "outline" : "ghost",
|
|
17499
|
+
size: size === "small" ? "small" : size === "large" ? "large" : "default",
|
|
17500
|
+
text: label,
|
|
17501
|
+
type: "button",
|
|
17502
|
+
className: "mx-2",
|
|
17503
|
+
onClick: function () {
|
|
17504
|
+
if (activeValue === value) return;
|
|
17505
|
+
if (controlledValue === undefined) {
|
|
17506
|
+
activeValue = value;
|
|
17507
|
+
updateActiveState();
|
|
17508
|
+
}
|
|
17509
|
+
if (typeof onChange === "function") {
|
|
17510
|
+
onChange(value);
|
|
17511
|
+
}
|
|
17512
|
+
},
|
|
17513
|
+
});
|
|
17514
|
+
|
|
17515
|
+
trigger.setAttribute("role", "tab");
|
|
17516
|
+
trigger.setAttribute("aria-selected", value === activeValue ? "true" : "false");
|
|
17517
|
+
trigger.setAttribute("data-state", value === activeValue ? "active" : "inactive");
|
|
17518
|
+
trigger.setAttribute("data-value", value);
|
|
17519
|
+
trigger.tabIndex = value === activeValue ? 0 : -1;
|
|
17520
|
+
|
|
17521
|
+
trigger.addEventListener("keydown", function (e) {
|
|
17522
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
17523
|
+
e.preventDefault();
|
|
17524
|
+
trigger.click();
|
|
17525
|
+
}
|
|
17526
|
+
if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
|
|
17527
|
+
e.preventDefault();
|
|
17528
|
+
var nextIndex = e.key === "ArrowRight" ? index + 1 : index - 1;
|
|
17529
|
+
if (nextIndex >= 0 && nextIndex < tabs.length) {
|
|
17530
|
+
var nextTrigger = triggerEls[nextIndex];
|
|
17531
|
+
if (nextTrigger) {
|
|
17532
|
+
nextTrigger.focus();
|
|
17533
|
+
nextTrigger.click();
|
|
17534
|
+
}
|
|
17535
|
+
}
|
|
17536
|
+
}
|
|
17537
|
+
});
|
|
17538
|
+
|
|
17539
|
+
list.appendChild(trigger);
|
|
17540
|
+
triggerEls.push(trigger);
|
|
17541
|
+
|
|
17542
|
+
var panel = document.createElement("div");
|
|
17543
|
+
panel.setAttribute("role", "tabpanel");
|
|
17544
|
+
panel.setAttribute("aria-hidden", value !== activeValue ? "true" : "false");
|
|
17545
|
+
panel.setAttribute("data-value", value);
|
|
17546
|
+
panel.className = join(CONTENT_BASE_CLASS, value !== activeValue ? "hidden" : "");
|
|
17547
|
+
if (typeof content === "string") {
|
|
17548
|
+
panel.innerHTML = content;
|
|
17549
|
+
} else if (content && content.nodeType === 1) {
|
|
17550
|
+
panel.appendChild(content);
|
|
17551
|
+
}
|
|
17552
|
+
contentWrapper.appendChild(panel);
|
|
17553
|
+
contentPanels.push(panel);
|
|
17554
|
+
});
|
|
17555
|
+
|
|
17556
|
+
function updateActiveState() {
|
|
17557
|
+
triggerEls.forEach(function (t, i) {
|
|
17558
|
+
var val = tabs[i] && tabs[i].value;
|
|
17559
|
+
var isActive = val === activeValue;
|
|
17560
|
+
t.setAttribute("aria-selected", isActive ? "true" : "false");
|
|
17561
|
+
t.setAttribute("data-state", isActive ? "active" : "inactive");
|
|
17562
|
+
t.tabIndex = isActive ? 0 : -1;
|
|
17563
|
+
t.className = join(BUTTON_BASE, isActive ? BUTTON_OUTLINE : BUTTON_GHOST, sizeClass, "mx-2");
|
|
17564
|
+
});
|
|
17565
|
+
contentPanels.forEach(function (p, i) {
|
|
17566
|
+
var val = tabs[i] && tabs[i].value;
|
|
17567
|
+
var isActive = val === activeValue;
|
|
17568
|
+
p.setAttribute("aria-hidden", isActive ? "false" : "true");
|
|
17569
|
+
p.classList.toggle("hidden", !isActive);
|
|
17570
|
+
});
|
|
17571
|
+
}
|
|
17572
|
+
|
|
17573
|
+
root.appendChild(list);
|
|
17574
|
+
root.appendChild(contentWrapper);
|
|
17575
|
+
|
|
17576
|
+
root.getValue = function () {
|
|
17577
|
+
return activeValue;
|
|
17578
|
+
};
|
|
17579
|
+
|
|
17580
|
+
root.setValue = function (newValue) {
|
|
17581
|
+
if (newValue === activeValue) return;
|
|
17582
|
+
activeValue = newValue;
|
|
17583
|
+
updateActiveState();
|
|
17584
|
+
};
|
|
17585
|
+
|
|
17586
|
+
return root;
|
|
17587
|
+
}
|
|
17588
|
+
|
|
17589
|
+
var Tabs = {
|
|
17590
|
+
create: create,
|
|
17591
|
+
};
|
|
17592
|
+
|
|
17593
|
+
if (typeof module !== "undefined" && module.exports) {
|
|
17594
|
+
module.exports = Tabs;
|
|
17595
|
+
} else {
|
|
17596
|
+
global.Tabs = Tabs;
|
|
17597
|
+
}
|
|
17598
|
+
})(typeof window !== "undefined" ? window : undefined);
|
|
17599
|
+
|
|
17600
|
+
|
|
17601
|
+
|
|
17602
|
+
// ============================================
|
|
17603
|
+
// File 40/41: components/steps.js
|
|
17604
|
+
// ============================================
|
|
17605
|
+
|
|
17606
|
+
/**
|
|
17607
|
+
* Steps Component (vanilla JS)
|
|
17608
|
+
* Multi-step flow with numbered step triggers and optional content panels.
|
|
17609
|
+
* Use for wizards / step-by-step forms (e.g. "1 Step One", "2 Step Two").
|
|
17610
|
+
*/
|
|
17611
|
+
|
|
17612
|
+
(function (global) {
|
|
17613
|
+
|
|
17614
|
+
function getComponent(name) {
|
|
17615
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
17616
|
+
var c = global.FlowUI._getComponent(name);
|
|
17617
|
+
if (c) return c;
|
|
17618
|
+
}
|
|
17619
|
+
return global[name];
|
|
17620
|
+
}
|
|
17621
|
+
|
|
17622
|
+
var LIST_BASE_CLASS =
|
|
17623
|
+
"flex items-center flex-wrap gap-0 rounded-4 border border-border-primary bg-fill-quarternary-fill-white p-4";
|
|
17624
|
+
|
|
17625
|
+
/** Inactive step: muted label color only (button stays ghost large) */
|
|
17626
|
+
var INACTIVE_LABEL_CLASS = "!text-typography-quaternary-text";
|
|
17627
|
+
|
|
17628
|
+
/** Box around step number: active = dark fill + invert text, inactive = dark gray fill + tertiary text */
|
|
17629
|
+
var NUMBER_BOX_ACTIVE =
|
|
17630
|
+
"flex h-16 w-16 items-center justify-center rounded-4 bg-typography-primary-text text-typography-invert-text shrink-0";
|
|
17631
|
+
var NUMBER_BOX_INACTIVE =
|
|
17632
|
+
"flex h-16 w-16 items-center justify-center rounded-4 bg-fill-primary-fill-dark-gray text-typography-tertiary-text shrink-0";
|
|
17633
|
+
|
|
17634
|
+
/** Horizontal line between steps (step1 ——— step2) */
|
|
17635
|
+
var CONNECTOR_CLASS = "flex-1 min-w-12 max-w-32 h-0 border-t border-border-primary shrink-0 mx-2 self-center";
|
|
17636
|
+
|
|
17637
|
+
var CONTENT_BASE_CLASS =
|
|
17638
|
+
"ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2 h-full";
|
|
17639
|
+
|
|
17640
|
+
function join() {
|
|
17641
|
+
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
17642
|
+
}
|
|
17643
|
+
|
|
17644
|
+
/**
|
|
17645
|
+
* Create a Steps component (numbered step triggers + optional content)
|
|
17646
|
+
* Design: ghost large Button for all steps; inactive steps use muted label color. Connectors between steps. Optional title/description above.
|
|
17647
|
+
* @param {Object} config
|
|
17648
|
+
* @param {Array<{id: string, label: string, content?: HTMLElement|string}>} config.steps - step definitions
|
|
17649
|
+
* @param {string} [config.defaultValue] - initial active step id
|
|
17650
|
+
* @param {string} [config.value] - controlled active step id
|
|
17651
|
+
* @param {Function} [config.onChange] - (stepId) => void when step changes
|
|
17652
|
+
* @param {string} [config.title] - optional title above steps
|
|
17653
|
+
* @param {string} [config.description] - optional description above steps
|
|
17654
|
+
* @param {string} [config.listClassName] - extra class on step list
|
|
17655
|
+
* @param {string} [config.contentClassName] - extra class on content wrapper
|
|
17656
|
+
* @param {boolean} [config.showContent=true] - whether to render content panels (if steps have content)
|
|
17657
|
+
* @returns {HTMLElement} root element
|
|
17658
|
+
*/
|
|
17659
|
+
function create(config) {
|
|
17660
|
+
var opts = config || {};
|
|
17661
|
+
var steps = opts.steps || [];
|
|
17662
|
+
var defaultValue = opts.defaultValue;
|
|
17663
|
+
var controlledValue = opts.value;
|
|
17664
|
+
var onChange = opts.onChange;
|
|
17665
|
+
var title = opts.title;
|
|
17666
|
+
var description = opts.description;
|
|
17667
|
+
var listClassName = opts.listClassName || "";
|
|
17668
|
+
var contentClassName = opts.contentClassName || "";
|
|
17669
|
+
var showContent = opts.showContent !== false;
|
|
17670
|
+
|
|
17671
|
+
var root = document.createElement("div");
|
|
17672
|
+
root.className = "steps-root w-full";
|
|
17673
|
+
|
|
17674
|
+
var activeId =
|
|
17675
|
+
controlledValue !== undefined
|
|
17676
|
+
? controlledValue
|
|
17677
|
+
: defaultValue !== undefined
|
|
17678
|
+
? defaultValue
|
|
17679
|
+
: (steps[0] && steps[0].id) || "";
|
|
17680
|
+
|
|
17681
|
+
if (title != null && title !== "") {
|
|
17682
|
+
var titleEl = document.createElement("h3");
|
|
17683
|
+
titleEl.className = "text-typography-primary-text";
|
|
17684
|
+
titleEl.textContent = title;
|
|
17685
|
+
root.appendChild(titleEl);
|
|
17686
|
+
}
|
|
17687
|
+
if (description != null && description !== "") {
|
|
17688
|
+
var descEl = document.createElement("p");
|
|
17689
|
+
descEl.className = "text-typography-secondary-text";
|
|
17690
|
+
descEl.textContent = description;
|
|
17691
|
+
root.appendChild(descEl);
|
|
17692
|
+
}
|
|
17693
|
+
|
|
17694
|
+
// Step list (horizontal: step, connector, step, connector, ...)
|
|
17695
|
+
var list = document.createElement("div");
|
|
17696
|
+
list.setAttribute("role", "tablist");
|
|
17697
|
+
list.setAttribute("aria-label", "Steps");
|
|
17698
|
+
list.className = join(LIST_BASE_CLASS, listClassName);
|
|
17699
|
+
|
|
17700
|
+
var triggerEls = [];
|
|
17701
|
+
var numberBoxEls = [];
|
|
17702
|
+
var contentPanels = [];
|
|
17703
|
+
var contentWrapper = null;
|
|
17704
|
+
|
|
17705
|
+
if (showContent && steps.some(function (s) { return s.content != null; })) {
|
|
17706
|
+
contentWrapper = document.createElement("div");
|
|
17707
|
+
contentWrapper.className = join("steps-content-wrapper mt-4", contentClassName);
|
|
17708
|
+
}
|
|
17709
|
+
|
|
17710
|
+
var Button = getComponent("Button");
|
|
17711
|
+
|
|
17712
|
+
steps.forEach(function (step, index) {
|
|
17713
|
+
var stepId = step.id;
|
|
17714
|
+
var label = step.label != null ? step.label : stepId;
|
|
17715
|
+
var content = step.content;
|
|
17716
|
+
var stepNumber = index + 1;
|
|
17717
|
+
var isActive = stepId === activeId;
|
|
17718
|
+
|
|
17719
|
+
var trigger = Button.create({
|
|
17720
|
+
variant: "ghost",
|
|
17721
|
+
size: "large",
|
|
17722
|
+
text: "\u00A0",
|
|
17723
|
+
type: "button",
|
|
17724
|
+
className: isActive ? "" : INACTIVE_LABEL_CLASS,
|
|
17725
|
+
onClick: function () {
|
|
17726
|
+
if (activeId === stepId) return;
|
|
17727
|
+
if (controlledValue === undefined) {
|
|
17728
|
+
activeId = stepId;
|
|
17729
|
+
updateActiveState();
|
|
17730
|
+
}
|
|
17731
|
+
if (typeof onChange === "function") {
|
|
17732
|
+
onChange(stepId);
|
|
17733
|
+
}
|
|
17734
|
+
},
|
|
17735
|
+
});
|
|
17736
|
+
|
|
17737
|
+
var numberBox = document.createElement("span");
|
|
17738
|
+
numberBox.setAttribute("aria-hidden", "true");
|
|
17739
|
+
numberBox.className = isActive ? NUMBER_BOX_ACTIVE : NUMBER_BOX_INACTIVE;
|
|
17740
|
+
numberBox.textContent = String(stepNumber);
|
|
17741
|
+
|
|
17742
|
+
trigger.innerHTML = "";
|
|
17743
|
+
trigger.appendChild(numberBox);
|
|
17744
|
+
trigger.appendChild(document.createTextNode(" " + label));
|
|
17745
|
+
|
|
17746
|
+
trigger.setAttribute("role", "tab");
|
|
17747
|
+
trigger.setAttribute("aria-selected", isActive ? "true" : "false");
|
|
17748
|
+
trigger.setAttribute("data-state", isActive ? "active" : "inactive");
|
|
17749
|
+
trigger.setAttribute("data-step-id", stepId);
|
|
17750
|
+
trigger.tabIndex = isActive ? 0 : -1;
|
|
17751
|
+
|
|
17752
|
+
numberBoxEls.push(numberBox);
|
|
17753
|
+
|
|
17754
|
+
trigger.addEventListener("keydown", function (e) {
|
|
17755
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
17756
|
+
e.preventDefault();
|
|
17757
|
+
trigger.click();
|
|
17758
|
+
}
|
|
17759
|
+
if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
|
|
17760
|
+
e.preventDefault();
|
|
17761
|
+
var nextIndex = e.key === "ArrowRight" ? index + 1 : index - 1;
|
|
17762
|
+
if (nextIndex >= 0 && nextIndex < steps.length) {
|
|
17763
|
+
var nextTrigger = triggerEls[nextIndex];
|
|
17764
|
+
if (nextTrigger) {
|
|
17765
|
+
nextTrigger.focus();
|
|
17766
|
+
nextTrigger.click();
|
|
17767
|
+
}
|
|
17768
|
+
}
|
|
17769
|
+
}
|
|
17770
|
+
});
|
|
17771
|
+
|
|
17772
|
+
list.appendChild(trigger);
|
|
17773
|
+
triggerEls.push(trigger);
|
|
17774
|
+
|
|
17775
|
+
if (index < steps.length - 1) {
|
|
17776
|
+
var connector = document.createElement("span");
|
|
17777
|
+
connector.className = CONNECTOR_CLASS;
|
|
17778
|
+
connector.setAttribute("aria-hidden", "true");
|
|
17779
|
+
list.appendChild(connector);
|
|
17780
|
+
}
|
|
17781
|
+
|
|
17782
|
+
if (contentWrapper && content != null) {
|
|
17783
|
+
var panel = document.createElement("div");
|
|
17784
|
+
panel.setAttribute("role", "tabpanel");
|
|
17785
|
+
panel.setAttribute("aria-hidden", stepId !== activeId ? "true" : "false");
|
|
17786
|
+
panel.setAttribute("data-step-id", stepId);
|
|
17787
|
+
panel.className = join(CONTENT_BASE_CLASS, stepId !== activeId ? "hidden" : "");
|
|
17788
|
+
if (typeof content === "string") {
|
|
17789
|
+
panel.innerHTML = content;
|
|
17790
|
+
} else if (content && content.nodeType === 1) {
|
|
17791
|
+
panel.appendChild(content);
|
|
17792
|
+
}
|
|
17793
|
+
contentWrapper.appendChild(panel);
|
|
17794
|
+
contentPanels.push(panel);
|
|
17795
|
+
}
|
|
17796
|
+
});
|
|
17797
|
+
|
|
17798
|
+
function updateActiveState() {
|
|
17799
|
+
triggerEls.forEach(function (t, i) {
|
|
17800
|
+
var step = steps[i];
|
|
17801
|
+
var id = step && step.id;
|
|
17802
|
+
var isActive = id === activeId;
|
|
17803
|
+
t.setAttribute("aria-selected", isActive ? "true" : "false");
|
|
17804
|
+
t.setAttribute("data-state", isActive ? "active" : "inactive");
|
|
17805
|
+
t.tabIndex = isActive ? 0 : -1;
|
|
17806
|
+
if (isActive) {
|
|
17807
|
+
t.classList.remove(INACTIVE_LABEL_CLASS);
|
|
17808
|
+
} else {
|
|
17809
|
+
t.classList.add(INACTIVE_LABEL_CLASS);
|
|
17810
|
+
}
|
|
17811
|
+
numberBoxEls[i].className = isActive ? NUMBER_BOX_ACTIVE : NUMBER_BOX_INACTIVE;
|
|
17812
|
+
});
|
|
17813
|
+
contentPanels.forEach(function (p, i) {
|
|
17814
|
+
var step = steps[i];
|
|
17815
|
+
var id = step && step.id;
|
|
17816
|
+
var isActive = id === activeId;
|
|
17817
|
+
p.setAttribute("aria-hidden", isActive ? "false" : "true");
|
|
17818
|
+
p.classList.toggle("hidden", !isActive);
|
|
17819
|
+
});
|
|
17820
|
+
}
|
|
17821
|
+
|
|
17822
|
+
root.appendChild(list);
|
|
17823
|
+
if (contentWrapper) {
|
|
17824
|
+
root.appendChild(contentWrapper);
|
|
17825
|
+
}
|
|
17826
|
+
|
|
17827
|
+
root.getValue = function () {
|
|
17828
|
+
return activeId;
|
|
17829
|
+
};
|
|
17830
|
+
|
|
17831
|
+
root.setValue = function (newId) {
|
|
17832
|
+
if (newId === activeId) return;
|
|
17833
|
+
activeId = newId;
|
|
17834
|
+
updateActiveState();
|
|
17835
|
+
};
|
|
17836
|
+
|
|
17837
|
+
return root;
|
|
17838
|
+
}
|
|
17839
|
+
|
|
17840
|
+
var Steps = {
|
|
17841
|
+
create: create,
|
|
17842
|
+
};
|
|
17843
|
+
|
|
17844
|
+
if (typeof module !== "undefined" && module.exports) {
|
|
17845
|
+
module.exports = Steps;
|
|
17846
|
+
} else {
|
|
17847
|
+
global.Steps = Steps;
|
|
17848
|
+
}
|
|
17849
|
+
})(typeof window !== "undefined" ? window : undefined);
|
|
17850
|
+
|
|
17851
|
+
|
|
17852
|
+
|
|
17853
|
+
// ============================================
|
|
17854
|
+
// File 41/41: index.js
|
|
16575
17855
|
// ============================================
|
|
16576
17856
|
|
|
16577
17857
|
/**
|
|
@@ -16647,6 +17927,7 @@
|
|
|
16647
17927
|
require("./components/input.js");
|
|
16648
17928
|
require("./components/currency.js");
|
|
16649
17929
|
require("./components/textarea.js");
|
|
17930
|
+
require("./components/richtext-editor.js");
|
|
16650
17931
|
require("./components/duration/duration-utils.js");
|
|
16651
17932
|
require("./components/duration/duration-constants.js");
|
|
16652
17933
|
require("./components/duration/duration.js");
|
|
@@ -16662,8 +17943,11 @@
|
|
|
16662
17943
|
require("./components/phone-input/phone-utils.js");
|
|
16663
17944
|
require("./components/phone-input/phone-input.js");
|
|
16664
17945
|
require("./components/checkbox.js");
|
|
17946
|
+
require("./components/checkbox-group.js");
|
|
16665
17947
|
require("./components/radio-group.js");
|
|
16666
17948
|
require("./components/table.js");
|
|
17949
|
+
require("./components/tabs.js");
|
|
17950
|
+
require("./components/steps.js");
|
|
16667
17951
|
|
|
16668
17952
|
// Export FlowUI and SuperLeap from global scope
|
|
16669
17953
|
if (typeof global !== "undefined" && global.FlowUI) {
|
|
@@ -16674,6 +17958,7 @@
|
|
|
16674
17958
|
getSdk: global.superleapClient.getSdk,
|
|
16675
17959
|
isAvailable: global.superleapClient.isAvailable,
|
|
16676
17960
|
getDefaultConfig: global.superleapClient.getDefaultConfig,
|
|
17961
|
+
getBaseUrl: global.superleapClient.getBaseUrl,
|
|
16677
17962
|
}
|
|
16678
17963
|
: null;
|
|
16679
17964
|
|
|
@@ -16689,6 +17974,7 @@
|
|
|
16689
17974
|
getSdk: window.superleapClient.getSdk,
|
|
16690
17975
|
isAvailable: window.superleapClient.isAvailable,
|
|
16691
17976
|
getDefaultConfig: window.superleapClient.getDefaultConfig,
|
|
17977
|
+
getBaseUrl: window.superleapClient.getBaseUrl,
|
|
16692
17978
|
}
|
|
16693
17979
|
: null;
|
|
16694
17980
|
|
|
@@ -16724,6 +18010,7 @@
|
|
|
16724
18010
|
"InputComponent",
|
|
16725
18011
|
"CurrencyComponent",
|
|
16726
18012
|
"TextareaComponent",
|
|
18013
|
+
"RichTextEditorComponent",
|
|
16727
18014
|
"Duration",
|
|
16728
18015
|
"DateTimePicker",
|
|
16729
18016
|
"Enumeration",
|
|
@@ -16735,8 +18022,11 @@
|
|
|
16735
18022
|
"FileInput",
|
|
16736
18023
|
"PhoneInput",
|
|
16737
18024
|
"Checkbox",
|
|
18025
|
+
"CheckboxGroup",
|
|
16738
18026
|
"RadioGroup",
|
|
16739
18027
|
"SuperleapTable",
|
|
18028
|
+
"Tabs",
|
|
18029
|
+
"Steps",
|
|
16740
18030
|
];
|
|
16741
18031
|
|
|
16742
18032
|
componentNames.forEach((name) => {
|
|
@@ -16766,6 +18056,7 @@
|
|
|
16766
18056
|
getSdk: client.getSdk.bind(client),
|
|
16767
18057
|
isAvailable: client.isAvailable.bind(client),
|
|
16768
18058
|
getDefaultConfig: client.getDefaultConfig.bind(client),
|
|
18059
|
+
getBaseUrl: client.getBaseUrl.bind(client),
|
|
16769
18060
|
// Bridge methods (from crm.js)
|
|
16770
18061
|
connect: client.connect ? client.connect.bind(client) : undefined,
|
|
16771
18062
|
isConnected: client.isConnected
|
|
@@ -16824,7 +18115,7 @@
|
|
|
16824
18115
|
},
|
|
16825
18116
|
});
|
|
16826
18117
|
document.dispatchEvent(event);
|
|
16827
|
-
console.log("[Superleap-Flow] Library ready - v2.
|
|
18118
|
+
console.log("[Superleap-Flow] Library ready - v2.5.1");
|
|
16828
18119
|
}
|
|
16829
18120
|
|
|
16830
18121
|
// Wait for DOM to be ready before dispatching event
|