@superleapai/flow-ui 2.5.19 → 2.5.20
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/CHANGELOG.md +2 -2
- package/LICENSE +1 -1
- package/README.md +38 -38
- package/components/enum-multiselect.js +119 -56
- package/components/enum-select.js +90 -48
- package/components/file-input.js +111 -49
- package/core/bridge.js +4 -6
- package/core/crm.js +17 -17
- package/core/flow.js +230 -59
- package/core/superleapClient.js +2 -2
- package/dist/superleap-flow.js +271 -2227
- package/dist/superleap-flow.js.map +1 -1
- package/dist/superleap-flow.min.js +2 -2
- package/index.d.ts +31 -20
- package/index.js +41 -30
- package/package.json +2 -2
package/core/flow.js
CHANGED
|
@@ -68,7 +68,10 @@
|
|
|
68
68
|
* Falls back to global[name] when flow.js is used without the single-file entry.
|
|
69
69
|
*/
|
|
70
70
|
function getComponent(name) {
|
|
71
|
-
if (
|
|
71
|
+
if (
|
|
72
|
+
typeof global.FlowUI !== "undefined" &&
|
|
73
|
+
typeof global.FlowUI._getComponent === "function"
|
|
74
|
+
) {
|
|
72
75
|
const c = global.FlowUI._getComponent(name);
|
|
73
76
|
if (c) return c;
|
|
74
77
|
}
|
|
@@ -159,11 +162,25 @@
|
|
|
159
162
|
* @returns {HTMLElement} Field element
|
|
160
163
|
*/
|
|
161
164
|
function createInput(config) {
|
|
162
|
-
const {
|
|
165
|
+
const {
|
|
166
|
+
label,
|
|
167
|
+
fieldId,
|
|
168
|
+
placeholder,
|
|
169
|
+
required = false,
|
|
170
|
+
type = "text",
|
|
171
|
+
helpText = null,
|
|
172
|
+
variant,
|
|
173
|
+
inputSize,
|
|
174
|
+
disabled = false,
|
|
175
|
+
showReadOnlyIcon,
|
|
176
|
+
} = config;
|
|
163
177
|
|
|
164
178
|
const field = createFieldWrapper(label, required, helpText);
|
|
165
179
|
|
|
166
|
-
if (
|
|
180
|
+
if (
|
|
181
|
+
getComponent("InputComponent") &&
|
|
182
|
+
getComponent("InputComponent").create
|
|
183
|
+
) {
|
|
167
184
|
const currentValue = get(fieldId) || "";
|
|
168
185
|
const inputEl = getComponent("InputComponent").create({
|
|
169
186
|
variant: variant || "default",
|
|
@@ -196,12 +213,24 @@
|
|
|
196
213
|
* @returns {HTMLElement} Field element
|
|
197
214
|
*/
|
|
198
215
|
function createTextarea(config) {
|
|
199
|
-
const {
|
|
216
|
+
const {
|
|
217
|
+
label,
|
|
218
|
+
fieldId,
|
|
219
|
+
placeholder,
|
|
220
|
+
required = false,
|
|
221
|
+
helpText = null,
|
|
222
|
+
variant,
|
|
223
|
+
rows,
|
|
224
|
+
disabled = false,
|
|
225
|
+
} = config;
|
|
200
226
|
|
|
201
227
|
const field = createFieldWrapper(label, required, helpText);
|
|
202
228
|
field.setAttribute("data-field-id", fieldId);
|
|
203
229
|
|
|
204
|
-
if (
|
|
230
|
+
if (
|
|
231
|
+
getComponent("TextareaComponent") &&
|
|
232
|
+
getComponent("TextareaComponent").create
|
|
233
|
+
) {
|
|
205
234
|
const currentValue = get(fieldId) || "";
|
|
206
235
|
const textareaEl = getComponent("TextareaComponent").create({
|
|
207
236
|
variant: variant || "default",
|
|
@@ -241,12 +270,22 @@
|
|
|
241
270
|
* @returns {HTMLElement} Field element
|
|
242
271
|
*/
|
|
243
272
|
function createRichTextEditor(config) {
|
|
244
|
-
const {
|
|
273
|
+
const {
|
|
274
|
+
label,
|
|
275
|
+
fieldId,
|
|
276
|
+
placeholder,
|
|
277
|
+
required = false,
|
|
278
|
+
helpText = null,
|
|
279
|
+
disabled = false,
|
|
280
|
+
} = config;
|
|
245
281
|
|
|
246
282
|
const field = createFieldWrapper(label, required, helpText);
|
|
247
283
|
field.setAttribute("data-field-id", fieldId);
|
|
248
284
|
|
|
249
|
-
if (
|
|
285
|
+
if (
|
|
286
|
+
getComponent("RichTextEditorComponent") &&
|
|
287
|
+
getComponent("RichTextEditorComponent").create
|
|
288
|
+
) {
|
|
250
289
|
const currentValue = get(fieldId) || "";
|
|
251
290
|
const editorEl = getComponent("RichTextEditorComponent").create({
|
|
252
291
|
value: currentValue,
|
|
@@ -300,7 +339,9 @@
|
|
|
300
339
|
disabled,
|
|
301
340
|
onChange: (value) => {
|
|
302
341
|
set(fieldId, value);
|
|
303
|
-
if (onChange) {
|
|
342
|
+
if (onChange) {
|
|
343
|
+
onChange(value);
|
|
344
|
+
}
|
|
304
345
|
},
|
|
305
346
|
});
|
|
306
347
|
|
|
@@ -332,7 +373,7 @@
|
|
|
332
373
|
});
|
|
333
374
|
|
|
334
375
|
select.value = get(fieldId) || "";
|
|
335
|
-
|
|
376
|
+
|
|
336
377
|
// Set placeholder attribute for styling
|
|
337
378
|
if (!select.value) {
|
|
338
379
|
select.setAttribute("data-placeholder", "true");
|
|
@@ -341,15 +382,17 @@
|
|
|
341
382
|
select.addEventListener("change", (e) => {
|
|
342
383
|
const value = e.target.value;
|
|
343
384
|
set(fieldId, value);
|
|
344
|
-
|
|
385
|
+
|
|
345
386
|
// Update placeholder attribute for styling
|
|
346
387
|
if (value === "") {
|
|
347
388
|
select.setAttribute("data-placeholder", "true");
|
|
348
389
|
} else {
|
|
349
390
|
select.removeAttribute("data-placeholder");
|
|
350
391
|
}
|
|
351
|
-
|
|
352
|
-
if (onChange) {
|
|
392
|
+
|
|
393
|
+
if (onChange) {
|
|
394
|
+
onChange(value);
|
|
395
|
+
}
|
|
353
396
|
});
|
|
354
397
|
|
|
355
398
|
field.appendChild(select);
|
|
@@ -373,7 +416,19 @@
|
|
|
373
416
|
* @returns {HTMLElement} Field element
|
|
374
417
|
*/
|
|
375
418
|
function createTimePicker(config) {
|
|
376
|
-
const {
|
|
419
|
+
const {
|
|
420
|
+
label,
|
|
421
|
+
fieldId,
|
|
422
|
+
value: initialValue,
|
|
423
|
+
placeholder,
|
|
424
|
+
required = false,
|
|
425
|
+
onChange,
|
|
426
|
+
disabled = false,
|
|
427
|
+
use24Hour = false,
|
|
428
|
+
size,
|
|
429
|
+
variant,
|
|
430
|
+
helpText = null,
|
|
431
|
+
} = config;
|
|
377
432
|
|
|
378
433
|
const field = createFieldWrapper(label, required, helpText);
|
|
379
434
|
|
|
@@ -390,7 +445,9 @@
|
|
|
390
445
|
variant,
|
|
391
446
|
onChange: (value) => {
|
|
392
447
|
set(fieldId, value);
|
|
393
|
-
if (onChange) {
|
|
448
|
+
if (onChange) {
|
|
449
|
+
onChange(value);
|
|
450
|
+
}
|
|
394
451
|
},
|
|
395
452
|
});
|
|
396
453
|
|
|
@@ -407,7 +464,9 @@
|
|
|
407
464
|
input.disabled = disabled;
|
|
408
465
|
input.addEventListener("change", (e) => {
|
|
409
466
|
set(fieldId, e.target.value);
|
|
410
|
-
if (onChange) {
|
|
467
|
+
if (onChange) {
|
|
468
|
+
onChange(e.target.value);
|
|
469
|
+
}
|
|
411
470
|
});
|
|
412
471
|
field.appendChild(input);
|
|
413
472
|
return field;
|
|
@@ -453,14 +512,20 @@
|
|
|
453
512
|
|
|
454
513
|
const field = createFieldWrapper(label, required, helpText);
|
|
455
514
|
|
|
456
|
-
if (
|
|
515
|
+
if (
|
|
516
|
+
getComponent("DateTimePicker") &&
|
|
517
|
+
getComponent("DateTimePicker").create
|
|
518
|
+
) {
|
|
457
519
|
const raw = get(fieldId);
|
|
458
520
|
let currentValueMs;
|
|
459
521
|
if (typeof initialValue === "number" && !Number.isNaN(initialValue)) {
|
|
460
522
|
currentValueMs = initialValue;
|
|
461
523
|
} else if (initialValue instanceof Date) {
|
|
462
524
|
currentValueMs = initialValue.getTime();
|
|
463
|
-
} else if (
|
|
525
|
+
} else if (
|
|
526
|
+
typeof initialValue === "string" &&
|
|
527
|
+
initialValue.trim() !== ""
|
|
528
|
+
) {
|
|
464
529
|
try {
|
|
465
530
|
const d = new Date(initialValue);
|
|
466
531
|
currentValueMs = Number.isNaN(d.getTime()) ? undefined : d.getTime();
|
|
@@ -473,7 +538,9 @@
|
|
|
473
538
|
try {
|
|
474
539
|
const parsed = typeof raw === "string" ? new Date(raw) : raw;
|
|
475
540
|
currentValueMs =
|
|
476
|
-
parsed &&
|
|
541
|
+
parsed &&
|
|
542
|
+
typeof parsed.getTime === "function" &&
|
|
543
|
+
!Number.isNaN(parsed.getTime())
|
|
477
544
|
? parsed.getTime()
|
|
478
545
|
: undefined;
|
|
479
546
|
} catch (e) {
|
|
@@ -492,8 +559,12 @@
|
|
|
492
559
|
fromDate,
|
|
493
560
|
toDate,
|
|
494
561
|
onChange: (epochMs) => {
|
|
495
|
-
set(
|
|
496
|
-
|
|
562
|
+
set(
|
|
563
|
+
fieldId,
|
|
564
|
+
epochMs != null ? new Date(epochMs).toISOString() : null,
|
|
565
|
+
);
|
|
566
|
+
if (onChange)
|
|
567
|
+
onChange(epochMs != null ? new Date(epochMs) : undefined);
|
|
497
568
|
},
|
|
498
569
|
});
|
|
499
570
|
|
|
@@ -517,7 +588,9 @@
|
|
|
517
588
|
}
|
|
518
589
|
dateInput.disabled = disabled;
|
|
519
590
|
dateInput.addEventListener("change", (e) => {
|
|
520
|
-
const val = e.target.value
|
|
591
|
+
const val = e.target.value
|
|
592
|
+
? new Date(e.target.value + "T12:00:00Z").toISOString()
|
|
593
|
+
: null;
|
|
521
594
|
set(fieldId, val);
|
|
522
595
|
if (onChange) onChange(val ? new Date(val) : undefined);
|
|
523
596
|
});
|
|
@@ -538,7 +611,16 @@
|
|
|
538
611
|
* @returns {HTMLElement} Field element
|
|
539
612
|
*/
|
|
540
613
|
function createRadioGroup(config) {
|
|
541
|
-
const {
|
|
614
|
+
const {
|
|
615
|
+
label,
|
|
616
|
+
fieldId,
|
|
617
|
+
options = [],
|
|
618
|
+
required = false,
|
|
619
|
+
onChange,
|
|
620
|
+
helpText = null,
|
|
621
|
+
orientation = "horizontal",
|
|
622
|
+
disabled = false,
|
|
623
|
+
} = config;
|
|
542
624
|
|
|
543
625
|
const field = createFieldWrapper(label, required, helpText);
|
|
544
626
|
|
|
@@ -546,7 +628,11 @@
|
|
|
546
628
|
const currentValue = get(fieldId);
|
|
547
629
|
const radioGroupEl = getComponent("RadioGroup").create({
|
|
548
630
|
name: fieldId,
|
|
549
|
-
options: options.map((opt) => ({
|
|
631
|
+
options: options.map((opt) => ({
|
|
632
|
+
value: opt.value,
|
|
633
|
+
label: opt.label || opt.value,
|
|
634
|
+
disabled: opt.disabled,
|
|
635
|
+
})),
|
|
550
636
|
value: currentValue,
|
|
551
637
|
disabled,
|
|
552
638
|
orientation,
|
|
@@ -576,7 +662,9 @@
|
|
|
576
662
|
radio.disabled = disabled || !!opt.disabled;
|
|
577
663
|
radio.addEventListener("change", () => {
|
|
578
664
|
set(fieldId, opt.value);
|
|
579
|
-
if (onChange) {
|
|
665
|
+
if (onChange) {
|
|
666
|
+
onChange(opt.value);
|
|
667
|
+
}
|
|
580
668
|
});
|
|
581
669
|
|
|
582
670
|
const radioLabel = document.createElement("label");
|
|
@@ -606,7 +694,16 @@
|
|
|
606
694
|
* @returns {HTMLElement} Field wrapper element
|
|
607
695
|
*/
|
|
608
696
|
function createCardSelect(config) {
|
|
609
|
-
const {
|
|
697
|
+
const {
|
|
698
|
+
label,
|
|
699
|
+
fieldId,
|
|
700
|
+
options = [],
|
|
701
|
+
required = false,
|
|
702
|
+
onChange,
|
|
703
|
+
helpText = null,
|
|
704
|
+
disabled = false,
|
|
705
|
+
className,
|
|
706
|
+
} = config;
|
|
610
707
|
|
|
611
708
|
const field = createFieldWrapper(label, required, helpText);
|
|
612
709
|
|
|
@@ -651,7 +748,9 @@
|
|
|
651
748
|
radio.disabled = disabled || !!opt.disabled;
|
|
652
749
|
radio.addEventListener("change", () => {
|
|
653
750
|
set(fieldId, opt.value);
|
|
654
|
-
if (onChange) {
|
|
751
|
+
if (onChange) {
|
|
752
|
+
onChange(opt.value);
|
|
753
|
+
}
|
|
655
754
|
});
|
|
656
755
|
|
|
657
756
|
const radioLabel = document.createElement("label");
|
|
@@ -733,11 +832,17 @@
|
|
|
733
832
|
? [...current, optValue]
|
|
734
833
|
: current.filter((v) => v !== optValue);
|
|
735
834
|
set(fieldId, updated);
|
|
736
|
-
if (onChange) {
|
|
835
|
+
if (onChange) {
|
|
836
|
+
onChange(updated);
|
|
837
|
+
}
|
|
737
838
|
});
|
|
738
839
|
|
|
739
840
|
checkboxWrapper.appendChild(checkbox);
|
|
740
|
-
checkboxWrapper.appendChild(
|
|
841
|
+
checkboxWrapper.appendChild(
|
|
842
|
+
document.createTextNode(
|
|
843
|
+
" " + (opt.label || opt.name || opt.display_name || opt.value),
|
|
844
|
+
),
|
|
845
|
+
);
|
|
741
846
|
checkboxContainer.appendChild(checkboxWrapper);
|
|
742
847
|
});
|
|
743
848
|
|
|
@@ -812,7 +917,8 @@
|
|
|
812
917
|
|
|
813
918
|
const fallback = document.createElement("div");
|
|
814
919
|
fallback.className = "text-reg-13 text-typography-quaternary-text";
|
|
815
|
-
fallback.textContent =
|
|
920
|
+
fallback.textContent =
|
|
921
|
+
"Record select requires RecordSelect component and Superleap client.";
|
|
816
922
|
field.appendChild(fallback);
|
|
817
923
|
return field;
|
|
818
924
|
}
|
|
@@ -855,7 +961,10 @@
|
|
|
855
961
|
|
|
856
962
|
const field = createFieldWrapper(label, required, helpText);
|
|
857
963
|
|
|
858
|
-
if (
|
|
964
|
+
if (
|
|
965
|
+
getComponent("RecordMultiSelect") &&
|
|
966
|
+
getComponent("RecordMultiSelect").create
|
|
967
|
+
) {
|
|
859
968
|
const currentValues = get(fieldId) || [];
|
|
860
969
|
const recordMultiEl = getComponent("RecordMultiSelect").create({
|
|
861
970
|
fieldId,
|
|
@@ -881,13 +990,14 @@
|
|
|
881
990
|
|
|
882
991
|
const fallback = document.createElement("div");
|
|
883
992
|
fallback.className = "text-reg-13 text-typography-quaternary-text";
|
|
884
|
-
fallback.textContent =
|
|
993
|
+
fallback.textContent =
|
|
994
|
+
"Record multi-select requires RecordMultiSelect component and Superleap client.";
|
|
885
995
|
field.appendChild(fallback);
|
|
886
996
|
return field;
|
|
887
997
|
}
|
|
888
998
|
|
|
889
999
|
/**
|
|
890
|
-
* Create an enum select field (options from
|
|
1000
|
+
* Create an enum select field (options from Superleap object column)
|
|
891
1001
|
* @param {Object} config - Configuration object
|
|
892
1002
|
* @param {string} config.label - Field label
|
|
893
1003
|
* @param {string} config.fieldId - State key for this field
|
|
@@ -948,13 +1058,14 @@
|
|
|
948
1058
|
|
|
949
1059
|
const fallback = document.createElement("div");
|
|
950
1060
|
fallback.className = "text-reg-13 text-typography-quaternary-text";
|
|
951
|
-
fallback.textContent =
|
|
1061
|
+
fallback.textContent =
|
|
1062
|
+
"Enum select requires EnumSelect component and Superleap client.";
|
|
952
1063
|
field.appendChild(fallback);
|
|
953
1064
|
return field;
|
|
954
1065
|
}
|
|
955
1066
|
|
|
956
1067
|
/**
|
|
957
|
-
* Create an enum multi-select field (options from
|
|
1068
|
+
* Create an enum multi-select field (options from Superleap object column)
|
|
958
1069
|
* @param {Object} config - Configuration object
|
|
959
1070
|
* @param {string} config.label - Field label
|
|
960
1071
|
* @param {string} config.fieldId - State key (stores array of values)
|
|
@@ -990,7 +1101,10 @@
|
|
|
990
1101
|
|
|
991
1102
|
const field = createFieldWrapper(label, required, helpText);
|
|
992
1103
|
|
|
993
|
-
if (
|
|
1104
|
+
if (
|
|
1105
|
+
getComponent("EnumMultiSelect") &&
|
|
1106
|
+
getComponent("EnumMultiSelect").create
|
|
1107
|
+
) {
|
|
994
1108
|
const currentValues = get(fieldId) || [];
|
|
995
1109
|
const enumMultiEl = getComponent("EnumMultiSelect").create({
|
|
996
1110
|
fieldId,
|
|
@@ -1015,7 +1129,8 @@
|
|
|
1015
1129
|
|
|
1016
1130
|
const fallback = document.createElement("div");
|
|
1017
1131
|
fallback.className = "text-reg-13 text-typography-quaternary-text";
|
|
1018
|
-
fallback.textContent =
|
|
1132
|
+
fallback.textContent =
|
|
1133
|
+
"Enum multi-select requires EnumMultiSelect component and Superleap client.";
|
|
1019
1134
|
field.appendChild(fallback);
|
|
1020
1135
|
return field;
|
|
1021
1136
|
}
|
|
@@ -1056,7 +1171,10 @@
|
|
|
1056
1171
|
|
|
1057
1172
|
if (getComponent("Duration") && getComponent("Duration").create) {
|
|
1058
1173
|
const currentValue = get(fieldId);
|
|
1059
|
-
const valueToUse =
|
|
1174
|
+
const valueToUse =
|
|
1175
|
+
currentValue !== undefined && currentValue !== null
|
|
1176
|
+
? currentValue
|
|
1177
|
+
: initialValue;
|
|
1060
1178
|
const durationEl = getComponent("Duration").create({
|
|
1061
1179
|
value: valueToUse,
|
|
1062
1180
|
formatType,
|
|
@@ -1121,7 +1239,10 @@
|
|
|
1121
1239
|
|
|
1122
1240
|
if (getComponent("Enumeration") && getComponent("Enumeration").create) {
|
|
1123
1241
|
const currentValue = get(fieldId);
|
|
1124
|
-
const valueToUse =
|
|
1242
|
+
const valueToUse =
|
|
1243
|
+
currentValue !== undefined && currentValue !== null
|
|
1244
|
+
? currentValue
|
|
1245
|
+
: defaultValue;
|
|
1125
1246
|
const enumEl = getComponent("Enumeration").create({
|
|
1126
1247
|
totalElements,
|
|
1127
1248
|
enabledIcon,
|
|
@@ -1165,7 +1286,17 @@
|
|
|
1165
1286
|
* @returns {HTMLElement} Field element
|
|
1166
1287
|
*/
|
|
1167
1288
|
function createFileUpload(config) {
|
|
1168
|
-
const {
|
|
1289
|
+
const {
|
|
1290
|
+
label,
|
|
1291
|
+
fieldId,
|
|
1292
|
+
multiple = true,
|
|
1293
|
+
accept,
|
|
1294
|
+
required = false,
|
|
1295
|
+
helpText = null,
|
|
1296
|
+
isPrivate,
|
|
1297
|
+
maxFiles,
|
|
1298
|
+
maxFileSize,
|
|
1299
|
+
} = config;
|
|
1169
1300
|
|
|
1170
1301
|
if (getComponent("FileInput") && getComponent("FileInput").create) {
|
|
1171
1302
|
return getComponent("FileInput").create({
|
|
@@ -1193,22 +1324,26 @@
|
|
|
1193
1324
|
const currentFiles = get(fieldId) || [];
|
|
1194
1325
|
const statusText = document.createElement("div");
|
|
1195
1326
|
statusText.className = "file-upload-text";
|
|
1196
|
-
statusText.textContent =
|
|
1197
|
-
|
|
1198
|
-
|
|
1327
|
+
statusText.textContent =
|
|
1328
|
+
currentFiles.length > 0
|
|
1329
|
+
? `${currentFiles.length} file(s) selected`
|
|
1330
|
+
: "No files chosen";
|
|
1199
1331
|
|
|
1200
1332
|
const input = document.createElement("input");
|
|
1201
1333
|
input.type = "file";
|
|
1202
1334
|
input.multiple = multiple;
|
|
1203
1335
|
input.className = "file-upload-input";
|
|
1204
|
-
if (accept) {
|
|
1336
|
+
if (accept) {
|
|
1337
|
+
input.accept = accept;
|
|
1338
|
+
}
|
|
1205
1339
|
|
|
1206
1340
|
input.addEventListener("change", function () {
|
|
1207
1341
|
const files = Array.from(this.files || []);
|
|
1208
1342
|
set(fieldId, files);
|
|
1209
|
-
statusText.textContent =
|
|
1210
|
-
|
|
1211
|
-
|
|
1343
|
+
statusText.textContent =
|
|
1344
|
+
files.length > 0
|
|
1345
|
+
? `${files.length} file(s) selected`
|
|
1346
|
+
: "No files chosen";
|
|
1212
1347
|
});
|
|
1213
1348
|
|
|
1214
1349
|
uploadWrapper.appendChild(btn);
|
|
@@ -1218,7 +1353,9 @@
|
|
|
1218
1353
|
|
|
1219
1354
|
const hint = document.createElement("div");
|
|
1220
1355
|
hint.className = "field-hint";
|
|
1221
|
-
hint.textContent = multiple
|
|
1356
|
+
hint.textContent = multiple
|
|
1357
|
+
? "Multiple files allowed."
|
|
1358
|
+
: "Single file only.";
|
|
1222
1359
|
field.appendChild(hint);
|
|
1223
1360
|
|
|
1224
1361
|
return field;
|
|
@@ -1257,7 +1394,10 @@
|
|
|
1257
1394
|
const field = createFieldWrapper(label, required, helpText);
|
|
1258
1395
|
field.setAttribute("data-field-id", fieldId);
|
|
1259
1396
|
|
|
1260
|
-
if (
|
|
1397
|
+
if (
|
|
1398
|
+
getComponent("CurrencyComponent") &&
|
|
1399
|
+
getComponent("CurrencyComponent").create
|
|
1400
|
+
) {
|
|
1261
1401
|
const currentValue = get(fieldId);
|
|
1262
1402
|
const currencyEl = getComponent("CurrencyComponent").create({
|
|
1263
1403
|
variant,
|
|
@@ -1431,7 +1571,18 @@
|
|
|
1431
1571
|
* @returns {HTMLElement} Field wrapper containing checkbox group
|
|
1432
1572
|
*/
|
|
1433
1573
|
function createCheckboxGroup(config) {
|
|
1434
|
-
const {
|
|
1574
|
+
const {
|
|
1575
|
+
label,
|
|
1576
|
+
fieldId,
|
|
1577
|
+
options = [],
|
|
1578
|
+
required = false,
|
|
1579
|
+
helpText = null,
|
|
1580
|
+
variant,
|
|
1581
|
+
size,
|
|
1582
|
+
layout = "vertical",
|
|
1583
|
+
disabled = false,
|
|
1584
|
+
onChange,
|
|
1585
|
+
} = config;
|
|
1435
1586
|
|
|
1436
1587
|
const field = createFieldWrapper(label, required, helpText);
|
|
1437
1588
|
field.setAttribute("data-field-id", fieldId);
|
|
@@ -1519,12 +1670,15 @@
|
|
|
1519
1670
|
* @param {string} currentStepId - Currently active step ID
|
|
1520
1671
|
*/
|
|
1521
1672
|
function renderStepper(container, steps, currentStepId) {
|
|
1522
|
-
if (!container) {
|
|
1673
|
+
if (!container) {
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1523
1676
|
container.innerHTML = "";
|
|
1524
1677
|
|
|
1525
1678
|
steps.forEach((step, idx) => {
|
|
1526
1679
|
const pill = document.createElement("div");
|
|
1527
|
-
pill.className =
|
|
1680
|
+
pill.className =
|
|
1681
|
+
"step-pill" + (step.id === currentStepId ? " step-pill--active" : "");
|
|
1528
1682
|
|
|
1529
1683
|
const indexSpan = document.createElement("span");
|
|
1530
1684
|
indexSpan.className = "step-pill-index";
|
|
@@ -1629,7 +1783,9 @@
|
|
|
1629
1783
|
radio.checked = get(fieldId) === row[idKey];
|
|
1630
1784
|
radio.addEventListener("change", () => {
|
|
1631
1785
|
set(fieldId, row[idKey]);
|
|
1632
|
-
if (onSelect) {
|
|
1786
|
+
if (onSelect) {
|
|
1787
|
+
onSelect(row);
|
|
1788
|
+
}
|
|
1633
1789
|
});
|
|
1634
1790
|
tdRadio.appendChild(radio);
|
|
1635
1791
|
tr.appendChild(tdRadio);
|
|
@@ -1700,7 +1856,9 @@
|
|
|
1700
1856
|
const searchInput = searchContainer.querySelector(".search-input");
|
|
1701
1857
|
searchInput.addEventListener("input", (e) => {
|
|
1702
1858
|
set(fieldId, e.target.value.toLowerCase());
|
|
1703
|
-
if (onSearch) {
|
|
1859
|
+
if (onSearch) {
|
|
1860
|
+
onSearch(e.target.value.toLowerCase());
|
|
1861
|
+
}
|
|
1704
1862
|
});
|
|
1705
1863
|
|
|
1706
1864
|
return searchContainer;
|
|
@@ -1754,7 +1912,11 @@
|
|
|
1754
1912
|
} else {
|
|
1755
1913
|
messages.forEach((msg) => {
|
|
1756
1914
|
const div = document.createElement("div");
|
|
1757
|
-
div.className =
|
|
1915
|
+
div.className =
|
|
1916
|
+
"rounded border p-2 text-sm " +
|
|
1917
|
+
(variant === "error"
|
|
1918
|
+
? "bg-red-50 border-red-200 text-red-800"
|
|
1919
|
+
: "bg-gray-50 border-gray-200");
|
|
1758
1920
|
div.textContent = msg;
|
|
1759
1921
|
container.appendChild(div);
|
|
1760
1922
|
});
|
|
@@ -1792,7 +1954,8 @@
|
|
|
1792
1954
|
return Avatar.create(config);
|
|
1793
1955
|
}
|
|
1794
1956
|
const div = document.createElement("div");
|
|
1795
|
-
div.className =
|
|
1957
|
+
div.className =
|
|
1958
|
+
"flex shrink-0 size-32 items-center justify-center rounded-full bg-primary-base";
|
|
1796
1959
|
div.textContent = (config && config.name && config.name.charAt(0)) || "?";
|
|
1797
1960
|
return div;
|
|
1798
1961
|
}
|
|
@@ -1823,7 +1986,8 @@
|
|
|
1823
1986
|
const span = document.createElement("span");
|
|
1824
1987
|
span.className = "text-typography-tertiary-text";
|
|
1825
1988
|
span.title = config && config.content ? config.content : "";
|
|
1826
|
-
span.textContent =
|
|
1989
|
+
span.textContent =
|
|
1990
|
+
(config && config.label) || (config && config.content) || "Hover me";
|
|
1827
1991
|
return span;
|
|
1828
1992
|
}
|
|
1829
1993
|
|
|
@@ -1890,8 +2054,13 @@
|
|
|
1890
2054
|
}
|
|
1891
2055
|
|
|
1892
2056
|
// Fallback: log to console if Toast component not loaded
|
|
1893
|
-
console.warn(
|
|
1894
|
-
|
|
2057
|
+
console.warn(
|
|
2058
|
+
"[FlowUI] Toast component not loaded. Message:",
|
|
2059
|
+
message,
|
|
2060
|
+
"Type:",
|
|
2061
|
+
type,
|
|
2062
|
+
);
|
|
2063
|
+
return { close: function () {}, element: null };
|
|
1895
2064
|
}
|
|
1896
2065
|
|
|
1897
2066
|
// ============================================================================
|
|
@@ -1942,7 +2111,9 @@
|
|
|
1942
2111
|
}
|
|
1943
2112
|
const btn = document.createElement("button");
|
|
1944
2113
|
btn.type = (config && config.type) || "button";
|
|
1945
|
-
btn.className =
|
|
2114
|
+
btn.className =
|
|
2115
|
+
"btn " +
|
|
2116
|
+
(config && config.variant === "primary" ? "btn-primary" : "btn-ghost");
|
|
1946
2117
|
btn.textContent = (config && (config.text || config.label)) || "Button";
|
|
1947
2118
|
if (config && config.disabled) btn.disabled = true;
|
|
1948
2119
|
if (config && typeof config.onClick === "function") {
|
package/core/superleapClient.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Superleap-Flow SDK client
|
|
3
|
-
* Thin wrapper around the
|
|
3
|
+
* Thin wrapper around the Superleap SDK (createSuperLeapSDK from sdk.js or superleap.js).
|
|
4
4
|
* Exposes getSdk() for record-select, file-input, etc.
|
|
5
5
|
* Load the SDK script before this script; then call superleapClient.init(config).
|
|
6
6
|
*
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
_sdkInstance = new global.SuperLeapSDK(_config);
|
|
40
40
|
} else {
|
|
41
41
|
console.warn(
|
|
42
|
-
"[superleapClient]
|
|
42
|
+
"[superleapClient] Superleap SDK not found. Install with: npm install superleap-sdk",
|
|
43
43
|
);
|
|
44
44
|
_sdkInstance = null;
|
|
45
45
|
}
|