@superleapai/flow-ui 2.5.18 → 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/components/multiselect.js +70 -3
- package/components/select.js +87 -55
- package/core/bridge.js +4 -6
- package/core/crm.js +17 -17
- package/core/flow.js +236 -61
- package/core/superleapClient.js +2 -2
- package/dist/superleap-flow.min.js +2 -2
- package/index.d.ts +33 -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,
|
|
@@ -277,11 +316,12 @@
|
|
|
277
316
|
* @param {Array} config.options - Array of { value, label } objects
|
|
278
317
|
* @param {boolean} config.required - Whether field is required
|
|
279
318
|
* @param {Function} config.onChange - Optional change handler
|
|
319
|
+
* @param {boolean} [config.showSearch] - Show local search input in dropdown
|
|
280
320
|
* @param {boolean} config.disabled - Whether select is disabled
|
|
281
321
|
* @returns {HTMLElement} Field element
|
|
282
322
|
*/
|
|
283
323
|
function createSelect(config) {
|
|
284
|
-
const { label, fieldId, options = [], required = false, onChange, disabled = false, helpText = null } = config;
|
|
324
|
+
const { label, fieldId, options = [], required = false, onChange, showSearch = false, disabled = false, helpText = null } = config;
|
|
285
325
|
|
|
286
326
|
const field = createFieldWrapper(label, required, helpText);
|
|
287
327
|
|
|
@@ -295,10 +335,13 @@
|
|
|
295
335
|
options,
|
|
296
336
|
placeholder,
|
|
297
337
|
value: currentValue,
|
|
338
|
+
showSearch,
|
|
298
339
|
disabled,
|
|
299
340
|
onChange: (value) => {
|
|
300
341
|
set(fieldId, value);
|
|
301
|
-
if (onChange) {
|
|
342
|
+
if (onChange) {
|
|
343
|
+
onChange(value);
|
|
344
|
+
}
|
|
302
345
|
},
|
|
303
346
|
});
|
|
304
347
|
|
|
@@ -330,7 +373,7 @@
|
|
|
330
373
|
});
|
|
331
374
|
|
|
332
375
|
select.value = get(fieldId) || "";
|
|
333
|
-
|
|
376
|
+
|
|
334
377
|
// Set placeholder attribute for styling
|
|
335
378
|
if (!select.value) {
|
|
336
379
|
select.setAttribute("data-placeholder", "true");
|
|
@@ -339,15 +382,17 @@
|
|
|
339
382
|
select.addEventListener("change", (e) => {
|
|
340
383
|
const value = e.target.value;
|
|
341
384
|
set(fieldId, value);
|
|
342
|
-
|
|
385
|
+
|
|
343
386
|
// Update placeholder attribute for styling
|
|
344
387
|
if (value === "") {
|
|
345
388
|
select.setAttribute("data-placeholder", "true");
|
|
346
389
|
} else {
|
|
347
390
|
select.removeAttribute("data-placeholder");
|
|
348
391
|
}
|
|
349
|
-
|
|
350
|
-
if (onChange) {
|
|
392
|
+
|
|
393
|
+
if (onChange) {
|
|
394
|
+
onChange(value);
|
|
395
|
+
}
|
|
351
396
|
});
|
|
352
397
|
|
|
353
398
|
field.appendChild(select);
|
|
@@ -371,7 +416,19 @@
|
|
|
371
416
|
* @returns {HTMLElement} Field element
|
|
372
417
|
*/
|
|
373
418
|
function createTimePicker(config) {
|
|
374
|
-
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;
|
|
375
432
|
|
|
376
433
|
const field = createFieldWrapper(label, required, helpText);
|
|
377
434
|
|
|
@@ -388,7 +445,9 @@
|
|
|
388
445
|
variant,
|
|
389
446
|
onChange: (value) => {
|
|
390
447
|
set(fieldId, value);
|
|
391
|
-
if (onChange) {
|
|
448
|
+
if (onChange) {
|
|
449
|
+
onChange(value);
|
|
450
|
+
}
|
|
392
451
|
},
|
|
393
452
|
});
|
|
394
453
|
|
|
@@ -405,7 +464,9 @@
|
|
|
405
464
|
input.disabled = disabled;
|
|
406
465
|
input.addEventListener("change", (e) => {
|
|
407
466
|
set(fieldId, e.target.value);
|
|
408
|
-
if (onChange) {
|
|
467
|
+
if (onChange) {
|
|
468
|
+
onChange(e.target.value);
|
|
469
|
+
}
|
|
409
470
|
});
|
|
410
471
|
field.appendChild(input);
|
|
411
472
|
return field;
|
|
@@ -451,14 +512,20 @@
|
|
|
451
512
|
|
|
452
513
|
const field = createFieldWrapper(label, required, helpText);
|
|
453
514
|
|
|
454
|
-
if (
|
|
515
|
+
if (
|
|
516
|
+
getComponent("DateTimePicker") &&
|
|
517
|
+
getComponent("DateTimePicker").create
|
|
518
|
+
) {
|
|
455
519
|
const raw = get(fieldId);
|
|
456
520
|
let currentValueMs;
|
|
457
521
|
if (typeof initialValue === "number" && !Number.isNaN(initialValue)) {
|
|
458
522
|
currentValueMs = initialValue;
|
|
459
523
|
} else if (initialValue instanceof Date) {
|
|
460
524
|
currentValueMs = initialValue.getTime();
|
|
461
|
-
} else if (
|
|
525
|
+
} else if (
|
|
526
|
+
typeof initialValue === "string" &&
|
|
527
|
+
initialValue.trim() !== ""
|
|
528
|
+
) {
|
|
462
529
|
try {
|
|
463
530
|
const d = new Date(initialValue);
|
|
464
531
|
currentValueMs = Number.isNaN(d.getTime()) ? undefined : d.getTime();
|
|
@@ -471,7 +538,9 @@
|
|
|
471
538
|
try {
|
|
472
539
|
const parsed = typeof raw === "string" ? new Date(raw) : raw;
|
|
473
540
|
currentValueMs =
|
|
474
|
-
parsed &&
|
|
541
|
+
parsed &&
|
|
542
|
+
typeof parsed.getTime === "function" &&
|
|
543
|
+
!Number.isNaN(parsed.getTime())
|
|
475
544
|
? parsed.getTime()
|
|
476
545
|
: undefined;
|
|
477
546
|
} catch (e) {
|
|
@@ -490,8 +559,12 @@
|
|
|
490
559
|
fromDate,
|
|
491
560
|
toDate,
|
|
492
561
|
onChange: (epochMs) => {
|
|
493
|
-
set(
|
|
494
|
-
|
|
562
|
+
set(
|
|
563
|
+
fieldId,
|
|
564
|
+
epochMs != null ? new Date(epochMs).toISOString() : null,
|
|
565
|
+
);
|
|
566
|
+
if (onChange)
|
|
567
|
+
onChange(epochMs != null ? new Date(epochMs) : undefined);
|
|
495
568
|
},
|
|
496
569
|
});
|
|
497
570
|
|
|
@@ -515,7 +588,9 @@
|
|
|
515
588
|
}
|
|
516
589
|
dateInput.disabled = disabled;
|
|
517
590
|
dateInput.addEventListener("change", (e) => {
|
|
518
|
-
const val = e.target.value
|
|
591
|
+
const val = e.target.value
|
|
592
|
+
? new Date(e.target.value + "T12:00:00Z").toISOString()
|
|
593
|
+
: null;
|
|
519
594
|
set(fieldId, val);
|
|
520
595
|
if (onChange) onChange(val ? new Date(val) : undefined);
|
|
521
596
|
});
|
|
@@ -536,7 +611,16 @@
|
|
|
536
611
|
* @returns {HTMLElement} Field element
|
|
537
612
|
*/
|
|
538
613
|
function createRadioGroup(config) {
|
|
539
|
-
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;
|
|
540
624
|
|
|
541
625
|
const field = createFieldWrapper(label, required, helpText);
|
|
542
626
|
|
|
@@ -544,7 +628,11 @@
|
|
|
544
628
|
const currentValue = get(fieldId);
|
|
545
629
|
const radioGroupEl = getComponent("RadioGroup").create({
|
|
546
630
|
name: fieldId,
|
|
547
|
-
options: options.map((opt) => ({
|
|
631
|
+
options: options.map((opt) => ({
|
|
632
|
+
value: opt.value,
|
|
633
|
+
label: opt.label || opt.value,
|
|
634
|
+
disabled: opt.disabled,
|
|
635
|
+
})),
|
|
548
636
|
value: currentValue,
|
|
549
637
|
disabled,
|
|
550
638
|
orientation,
|
|
@@ -574,7 +662,9 @@
|
|
|
574
662
|
radio.disabled = disabled || !!opt.disabled;
|
|
575
663
|
radio.addEventListener("change", () => {
|
|
576
664
|
set(fieldId, opt.value);
|
|
577
|
-
if (onChange) {
|
|
665
|
+
if (onChange) {
|
|
666
|
+
onChange(opt.value);
|
|
667
|
+
}
|
|
578
668
|
});
|
|
579
669
|
|
|
580
670
|
const radioLabel = document.createElement("label");
|
|
@@ -604,7 +694,16 @@
|
|
|
604
694
|
* @returns {HTMLElement} Field wrapper element
|
|
605
695
|
*/
|
|
606
696
|
function createCardSelect(config) {
|
|
607
|
-
const {
|
|
697
|
+
const {
|
|
698
|
+
label,
|
|
699
|
+
fieldId,
|
|
700
|
+
options = [],
|
|
701
|
+
required = false,
|
|
702
|
+
onChange,
|
|
703
|
+
helpText = null,
|
|
704
|
+
disabled = false,
|
|
705
|
+
className,
|
|
706
|
+
} = config;
|
|
608
707
|
|
|
609
708
|
const field = createFieldWrapper(label, required, helpText);
|
|
610
709
|
|
|
@@ -649,7 +748,9 @@
|
|
|
649
748
|
radio.disabled = disabled || !!opt.disabled;
|
|
650
749
|
radio.addEventListener("change", () => {
|
|
651
750
|
set(fieldId, opt.value);
|
|
652
|
-
if (onChange) {
|
|
751
|
+
if (onChange) {
|
|
752
|
+
onChange(opt.value);
|
|
753
|
+
}
|
|
653
754
|
});
|
|
654
755
|
|
|
655
756
|
const radioLabel = document.createElement("label");
|
|
@@ -678,11 +779,12 @@
|
|
|
678
779
|
* @param {string} config.variant - 'default' | 'error' | 'warning' | 'borderless' | 'inline'
|
|
679
780
|
* @param {string} config.size - 'default' | 'large' | 'small'
|
|
680
781
|
* @param {string} config.type - 'default' (count) | 'tags' (show tags in trigger)
|
|
782
|
+
* @param {boolean} [config.showSearch] - Show local search input in dropdown
|
|
681
783
|
* @param {boolean} config.disabled - Whether multiselect is disabled
|
|
682
784
|
* @returns {HTMLElement} Field element
|
|
683
785
|
*/
|
|
684
786
|
function createMultiSelect(config) {
|
|
685
|
-
const { label, fieldId, options = [], required = false, onChange, placeholder, helpText = null, variant, size, type, disabled = false } = config;
|
|
787
|
+
const { label, fieldId, options = [], required = false, onChange, placeholder, helpText = null, variant, size, type, showSearch = false, disabled = false } = config;
|
|
686
788
|
|
|
687
789
|
const field = createFieldWrapper(label, required, helpText);
|
|
688
790
|
|
|
@@ -697,6 +799,7 @@
|
|
|
697
799
|
variant: variant || "default",
|
|
698
800
|
size: size || "default",
|
|
699
801
|
type: type || "default",
|
|
802
|
+
showSearch,
|
|
700
803
|
disabled,
|
|
701
804
|
onValuesChange: (values) => {
|
|
702
805
|
set(fieldId, values);
|
|
@@ -729,11 +832,17 @@
|
|
|
729
832
|
? [...current, optValue]
|
|
730
833
|
: current.filter((v) => v !== optValue);
|
|
731
834
|
set(fieldId, updated);
|
|
732
|
-
if (onChange) {
|
|
835
|
+
if (onChange) {
|
|
836
|
+
onChange(updated);
|
|
837
|
+
}
|
|
733
838
|
});
|
|
734
839
|
|
|
735
840
|
checkboxWrapper.appendChild(checkbox);
|
|
736
|
-
checkboxWrapper.appendChild(
|
|
841
|
+
checkboxWrapper.appendChild(
|
|
842
|
+
document.createTextNode(
|
|
843
|
+
" " + (opt.label || opt.name || opt.display_name || opt.value),
|
|
844
|
+
),
|
|
845
|
+
);
|
|
737
846
|
checkboxContainer.appendChild(checkboxWrapper);
|
|
738
847
|
});
|
|
739
848
|
|
|
@@ -808,7 +917,8 @@
|
|
|
808
917
|
|
|
809
918
|
const fallback = document.createElement("div");
|
|
810
919
|
fallback.className = "text-reg-13 text-typography-quaternary-text";
|
|
811
|
-
fallback.textContent =
|
|
920
|
+
fallback.textContent =
|
|
921
|
+
"Record select requires RecordSelect component and Superleap client.";
|
|
812
922
|
field.appendChild(fallback);
|
|
813
923
|
return field;
|
|
814
924
|
}
|
|
@@ -851,7 +961,10 @@
|
|
|
851
961
|
|
|
852
962
|
const field = createFieldWrapper(label, required, helpText);
|
|
853
963
|
|
|
854
|
-
if (
|
|
964
|
+
if (
|
|
965
|
+
getComponent("RecordMultiSelect") &&
|
|
966
|
+
getComponent("RecordMultiSelect").create
|
|
967
|
+
) {
|
|
855
968
|
const currentValues = get(fieldId) || [];
|
|
856
969
|
const recordMultiEl = getComponent("RecordMultiSelect").create({
|
|
857
970
|
fieldId,
|
|
@@ -877,13 +990,14 @@
|
|
|
877
990
|
|
|
878
991
|
const fallback = document.createElement("div");
|
|
879
992
|
fallback.className = "text-reg-13 text-typography-quaternary-text";
|
|
880
|
-
fallback.textContent =
|
|
993
|
+
fallback.textContent =
|
|
994
|
+
"Record multi-select requires RecordMultiSelect component and Superleap client.";
|
|
881
995
|
field.appendChild(fallback);
|
|
882
996
|
return field;
|
|
883
997
|
}
|
|
884
998
|
|
|
885
999
|
/**
|
|
886
|
-
* Create an enum select field (options from
|
|
1000
|
+
* Create an enum select field (options from Superleap object column)
|
|
887
1001
|
* @param {Object} config - Configuration object
|
|
888
1002
|
* @param {string} config.label - Field label
|
|
889
1003
|
* @param {string} config.fieldId - State key for this field
|
|
@@ -944,13 +1058,14 @@
|
|
|
944
1058
|
|
|
945
1059
|
const fallback = document.createElement("div");
|
|
946
1060
|
fallback.className = "text-reg-13 text-typography-quaternary-text";
|
|
947
|
-
fallback.textContent =
|
|
1061
|
+
fallback.textContent =
|
|
1062
|
+
"Enum select requires EnumSelect component and Superleap client.";
|
|
948
1063
|
field.appendChild(fallback);
|
|
949
1064
|
return field;
|
|
950
1065
|
}
|
|
951
1066
|
|
|
952
1067
|
/**
|
|
953
|
-
* Create an enum multi-select field (options from
|
|
1068
|
+
* Create an enum multi-select field (options from Superleap object column)
|
|
954
1069
|
* @param {Object} config - Configuration object
|
|
955
1070
|
* @param {string} config.label - Field label
|
|
956
1071
|
* @param {string} config.fieldId - State key (stores array of values)
|
|
@@ -986,7 +1101,10 @@
|
|
|
986
1101
|
|
|
987
1102
|
const field = createFieldWrapper(label, required, helpText);
|
|
988
1103
|
|
|
989
|
-
if (
|
|
1104
|
+
if (
|
|
1105
|
+
getComponent("EnumMultiSelect") &&
|
|
1106
|
+
getComponent("EnumMultiSelect").create
|
|
1107
|
+
) {
|
|
990
1108
|
const currentValues = get(fieldId) || [];
|
|
991
1109
|
const enumMultiEl = getComponent("EnumMultiSelect").create({
|
|
992
1110
|
fieldId,
|
|
@@ -1011,7 +1129,8 @@
|
|
|
1011
1129
|
|
|
1012
1130
|
const fallback = document.createElement("div");
|
|
1013
1131
|
fallback.className = "text-reg-13 text-typography-quaternary-text";
|
|
1014
|
-
fallback.textContent =
|
|
1132
|
+
fallback.textContent =
|
|
1133
|
+
"Enum multi-select requires EnumMultiSelect component and Superleap client.";
|
|
1015
1134
|
field.appendChild(fallback);
|
|
1016
1135
|
return field;
|
|
1017
1136
|
}
|
|
@@ -1052,7 +1171,10 @@
|
|
|
1052
1171
|
|
|
1053
1172
|
if (getComponent("Duration") && getComponent("Duration").create) {
|
|
1054
1173
|
const currentValue = get(fieldId);
|
|
1055
|
-
const valueToUse =
|
|
1174
|
+
const valueToUse =
|
|
1175
|
+
currentValue !== undefined && currentValue !== null
|
|
1176
|
+
? currentValue
|
|
1177
|
+
: initialValue;
|
|
1056
1178
|
const durationEl = getComponent("Duration").create({
|
|
1057
1179
|
value: valueToUse,
|
|
1058
1180
|
formatType,
|
|
@@ -1117,7 +1239,10 @@
|
|
|
1117
1239
|
|
|
1118
1240
|
if (getComponent("Enumeration") && getComponent("Enumeration").create) {
|
|
1119
1241
|
const currentValue = get(fieldId);
|
|
1120
|
-
const valueToUse =
|
|
1242
|
+
const valueToUse =
|
|
1243
|
+
currentValue !== undefined && currentValue !== null
|
|
1244
|
+
? currentValue
|
|
1245
|
+
: defaultValue;
|
|
1121
1246
|
const enumEl = getComponent("Enumeration").create({
|
|
1122
1247
|
totalElements,
|
|
1123
1248
|
enabledIcon,
|
|
@@ -1161,7 +1286,17 @@
|
|
|
1161
1286
|
* @returns {HTMLElement} Field element
|
|
1162
1287
|
*/
|
|
1163
1288
|
function createFileUpload(config) {
|
|
1164
|
-
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;
|
|
1165
1300
|
|
|
1166
1301
|
if (getComponent("FileInput") && getComponent("FileInput").create) {
|
|
1167
1302
|
return getComponent("FileInput").create({
|
|
@@ -1189,22 +1324,26 @@
|
|
|
1189
1324
|
const currentFiles = get(fieldId) || [];
|
|
1190
1325
|
const statusText = document.createElement("div");
|
|
1191
1326
|
statusText.className = "file-upload-text";
|
|
1192
|
-
statusText.textContent =
|
|
1193
|
-
|
|
1194
|
-
|
|
1327
|
+
statusText.textContent =
|
|
1328
|
+
currentFiles.length > 0
|
|
1329
|
+
? `${currentFiles.length} file(s) selected`
|
|
1330
|
+
: "No files chosen";
|
|
1195
1331
|
|
|
1196
1332
|
const input = document.createElement("input");
|
|
1197
1333
|
input.type = "file";
|
|
1198
1334
|
input.multiple = multiple;
|
|
1199
1335
|
input.className = "file-upload-input";
|
|
1200
|
-
if (accept) {
|
|
1336
|
+
if (accept) {
|
|
1337
|
+
input.accept = accept;
|
|
1338
|
+
}
|
|
1201
1339
|
|
|
1202
1340
|
input.addEventListener("change", function () {
|
|
1203
1341
|
const files = Array.from(this.files || []);
|
|
1204
1342
|
set(fieldId, files);
|
|
1205
|
-
statusText.textContent =
|
|
1206
|
-
|
|
1207
|
-
|
|
1343
|
+
statusText.textContent =
|
|
1344
|
+
files.length > 0
|
|
1345
|
+
? `${files.length} file(s) selected`
|
|
1346
|
+
: "No files chosen";
|
|
1208
1347
|
});
|
|
1209
1348
|
|
|
1210
1349
|
uploadWrapper.appendChild(btn);
|
|
@@ -1214,7 +1353,9 @@
|
|
|
1214
1353
|
|
|
1215
1354
|
const hint = document.createElement("div");
|
|
1216
1355
|
hint.className = "field-hint";
|
|
1217
|
-
hint.textContent = multiple
|
|
1356
|
+
hint.textContent = multiple
|
|
1357
|
+
? "Multiple files allowed."
|
|
1358
|
+
: "Single file only.";
|
|
1218
1359
|
field.appendChild(hint);
|
|
1219
1360
|
|
|
1220
1361
|
return field;
|
|
@@ -1253,7 +1394,10 @@
|
|
|
1253
1394
|
const field = createFieldWrapper(label, required, helpText);
|
|
1254
1395
|
field.setAttribute("data-field-id", fieldId);
|
|
1255
1396
|
|
|
1256
|
-
if (
|
|
1397
|
+
if (
|
|
1398
|
+
getComponent("CurrencyComponent") &&
|
|
1399
|
+
getComponent("CurrencyComponent").create
|
|
1400
|
+
) {
|
|
1257
1401
|
const currentValue = get(fieldId);
|
|
1258
1402
|
const currencyEl = getComponent("CurrencyComponent").create({
|
|
1259
1403
|
variant,
|
|
@@ -1427,7 +1571,18 @@
|
|
|
1427
1571
|
* @returns {HTMLElement} Field wrapper containing checkbox group
|
|
1428
1572
|
*/
|
|
1429
1573
|
function createCheckboxGroup(config) {
|
|
1430
|
-
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;
|
|
1431
1586
|
|
|
1432
1587
|
const field = createFieldWrapper(label, required, helpText);
|
|
1433
1588
|
field.setAttribute("data-field-id", fieldId);
|
|
@@ -1515,12 +1670,15 @@
|
|
|
1515
1670
|
* @param {string} currentStepId - Currently active step ID
|
|
1516
1671
|
*/
|
|
1517
1672
|
function renderStepper(container, steps, currentStepId) {
|
|
1518
|
-
if (!container) {
|
|
1673
|
+
if (!container) {
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1519
1676
|
container.innerHTML = "";
|
|
1520
1677
|
|
|
1521
1678
|
steps.forEach((step, idx) => {
|
|
1522
1679
|
const pill = document.createElement("div");
|
|
1523
|
-
pill.className =
|
|
1680
|
+
pill.className =
|
|
1681
|
+
"step-pill" + (step.id === currentStepId ? " step-pill--active" : "");
|
|
1524
1682
|
|
|
1525
1683
|
const indexSpan = document.createElement("span");
|
|
1526
1684
|
indexSpan.className = "step-pill-index";
|
|
@@ -1625,7 +1783,9 @@
|
|
|
1625
1783
|
radio.checked = get(fieldId) === row[idKey];
|
|
1626
1784
|
radio.addEventListener("change", () => {
|
|
1627
1785
|
set(fieldId, row[idKey]);
|
|
1628
|
-
if (onSelect) {
|
|
1786
|
+
if (onSelect) {
|
|
1787
|
+
onSelect(row);
|
|
1788
|
+
}
|
|
1629
1789
|
});
|
|
1630
1790
|
tdRadio.appendChild(radio);
|
|
1631
1791
|
tr.appendChild(tdRadio);
|
|
@@ -1696,7 +1856,9 @@
|
|
|
1696
1856
|
const searchInput = searchContainer.querySelector(".search-input");
|
|
1697
1857
|
searchInput.addEventListener("input", (e) => {
|
|
1698
1858
|
set(fieldId, e.target.value.toLowerCase());
|
|
1699
|
-
if (onSearch) {
|
|
1859
|
+
if (onSearch) {
|
|
1860
|
+
onSearch(e.target.value.toLowerCase());
|
|
1861
|
+
}
|
|
1700
1862
|
});
|
|
1701
1863
|
|
|
1702
1864
|
return searchContainer;
|
|
@@ -1750,7 +1912,11 @@
|
|
|
1750
1912
|
} else {
|
|
1751
1913
|
messages.forEach((msg) => {
|
|
1752
1914
|
const div = document.createElement("div");
|
|
1753
|
-
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");
|
|
1754
1920
|
div.textContent = msg;
|
|
1755
1921
|
container.appendChild(div);
|
|
1756
1922
|
});
|
|
@@ -1788,7 +1954,8 @@
|
|
|
1788
1954
|
return Avatar.create(config);
|
|
1789
1955
|
}
|
|
1790
1956
|
const div = document.createElement("div");
|
|
1791
|
-
div.className =
|
|
1957
|
+
div.className =
|
|
1958
|
+
"flex shrink-0 size-32 items-center justify-center rounded-full bg-primary-base";
|
|
1792
1959
|
div.textContent = (config && config.name && config.name.charAt(0)) || "?";
|
|
1793
1960
|
return div;
|
|
1794
1961
|
}
|
|
@@ -1819,7 +1986,8 @@
|
|
|
1819
1986
|
const span = document.createElement("span");
|
|
1820
1987
|
span.className = "text-typography-tertiary-text";
|
|
1821
1988
|
span.title = config && config.content ? config.content : "";
|
|
1822
|
-
span.textContent =
|
|
1989
|
+
span.textContent =
|
|
1990
|
+
(config && config.label) || (config && config.content) || "Hover me";
|
|
1823
1991
|
return span;
|
|
1824
1992
|
}
|
|
1825
1993
|
|
|
@@ -1886,8 +2054,13 @@
|
|
|
1886
2054
|
}
|
|
1887
2055
|
|
|
1888
2056
|
// Fallback: log to console if Toast component not loaded
|
|
1889
|
-
console.warn(
|
|
1890
|
-
|
|
2057
|
+
console.warn(
|
|
2058
|
+
"[FlowUI] Toast component not loaded. Message:",
|
|
2059
|
+
message,
|
|
2060
|
+
"Type:",
|
|
2061
|
+
type,
|
|
2062
|
+
);
|
|
2063
|
+
return { close: function () {}, element: null };
|
|
1891
2064
|
}
|
|
1892
2065
|
|
|
1893
2066
|
// ============================================================================
|
|
@@ -1938,7 +2111,9 @@
|
|
|
1938
2111
|
}
|
|
1939
2112
|
const btn = document.createElement("button");
|
|
1940
2113
|
btn.type = (config && config.type) || "button";
|
|
1941
|
-
btn.className =
|
|
2114
|
+
btn.className =
|
|
2115
|
+
"btn " +
|
|
2116
|
+
(config && config.variant === "primary" ? "btn-primary" : "btn-ghost");
|
|
1942
2117
|
btn.textContent = (config && (config.text || config.label)) || "Button";
|
|
1943
2118
|
if (config && config.disabled) btn.disabled = true;
|
|
1944
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
|
}
|