lisichatbot 1.2.4 â 1.2.5
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/package.json +1 -1
- package/src/index.js +425 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -29,7 +29,15 @@ let elements = {
|
|
|
29
29
|
let config = {
|
|
30
30
|
selectedBackground: '#667eea',
|
|
31
31
|
autoAdvanceDelay: 2000,
|
|
32
|
-
enableAnimations: true
|
|
32
|
+
enableAnimations: true,
|
|
33
|
+
customRangeErrors: {
|
|
34
|
+
minRequired: 'Minimum value is required',
|
|
35
|
+
maxRequired: 'Maximum value is required',
|
|
36
|
+
bothRequired: 'Both minimum and maximum values are required',
|
|
37
|
+
minGreaterThanMax: 'Minimum must be less than maximum',
|
|
38
|
+
minBelowConstraint: 'Minimum must be at least {min}',
|
|
39
|
+
maxAboveConstraint: 'Maximum must be at most {max}'
|
|
40
|
+
}
|
|
33
41
|
};
|
|
34
42
|
|
|
35
43
|
let flowData = null;
|
|
@@ -483,6 +491,408 @@ function renderColorOptions(options, field) {
|
|
|
483
491
|
});
|
|
484
492
|
}
|
|
485
493
|
|
|
494
|
+
// =============================================================================
|
|
495
|
+
// SINGLE-SELECT-CUSTOM (WITH MIN/MAX RANGE)
|
|
496
|
+
// =============================================================================
|
|
497
|
+
|
|
498
|
+
function renderCustomSelectOptions(options, field, customConfig) {
|
|
499
|
+
if (!elements.messages) return;
|
|
500
|
+
|
|
501
|
+
// Find existing single-select option element
|
|
502
|
+
const optionSelector = '[data-chat-element="single-select-input"]';
|
|
503
|
+
const existingOption = document.querySelector(optionSelector);
|
|
504
|
+
|
|
505
|
+
if (!existingOption) {
|
|
506
|
+
console.error(`Element with ${optionSelector} not found in HTML.`);
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Get existing data for pre-filling
|
|
511
|
+
const existingData = chatState.data[field];
|
|
512
|
+
console.log(`đ Pre-filling ${field} (custom):`, existingData);
|
|
513
|
+
|
|
514
|
+
// Create wrapper to hold all options
|
|
515
|
+
const optionsWrapper = document.createElement('div');
|
|
516
|
+
optionsWrapper.setAttribute('data-chat-element', 'options-wrapper');
|
|
517
|
+
|
|
518
|
+
// Render regular options
|
|
519
|
+
options.forEach((option, index) => {
|
|
520
|
+
const optionName = option.name || option;
|
|
521
|
+
const optionValue = option.value !== undefined ? option.value : option;
|
|
522
|
+
const valueStr = typeof optionValue === 'object' ?
|
|
523
|
+
JSON.stringify(optionValue) : String(optionValue);
|
|
524
|
+
|
|
525
|
+
const clone = existingOption.cloneNode(true);
|
|
526
|
+
clone.style.display = '';
|
|
527
|
+
|
|
528
|
+
// Check if this option should be pre-selected
|
|
529
|
+
const shouldBeChecked = existingData !== undefined &&
|
|
530
|
+
!Array.isArray(existingData) && // Exclude array (custom range)
|
|
531
|
+
JSON.stringify(existingData) === JSON.stringify(optionValue);
|
|
532
|
+
|
|
533
|
+
if (shouldBeChecked) {
|
|
534
|
+
clone.classList.add('cf-checked');
|
|
535
|
+
clone.style.backgroundColor = config.selectedBackground;
|
|
536
|
+
console.log(` â
Pre-selected: ${optionName}`);
|
|
537
|
+
} else {
|
|
538
|
+
clone.classList.remove('cf-checked');
|
|
539
|
+
clone.style.backgroundColor = 'transparent';
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
clone.setAttribute('data-chat-element', 'single-select-input');
|
|
543
|
+
clone.setAttribute('data-field', field);
|
|
544
|
+
clone.setAttribute('data-value', valueStr);
|
|
545
|
+
clone.setAttribute('data-name', optionName);
|
|
546
|
+
clone.setAttribute('data-index', index);
|
|
547
|
+
clone.setAttribute('data-is-custom', 'false');
|
|
548
|
+
|
|
549
|
+
const input = clone.querySelector('[data-chat-input-element="input"]');
|
|
550
|
+
if (input) {
|
|
551
|
+
input.name = field;
|
|
552
|
+
input.value = valueStr;
|
|
553
|
+
input.checked = shouldBeChecked;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const tickIcon = clone.querySelector('[data-chat-input-element="tick-icon"]');
|
|
557
|
+
if (tickIcon) {
|
|
558
|
+
tickIcon.style.display = shouldBeChecked ? 'block' : 'none';
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const textElement = clone.querySelector('[data-chat-input-element="text"]');
|
|
562
|
+
if (textElement) {
|
|
563
|
+
textElement.textContent = optionName;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
optionsWrapper.appendChild(clone);
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
// Render custom option
|
|
570
|
+
if (customConfig) {
|
|
571
|
+
const customClone = existingOption.cloneNode(true);
|
|
572
|
+
customClone.style.display = '';
|
|
573
|
+
|
|
574
|
+
// Check if custom was selected before (data is array [min, max])
|
|
575
|
+
const isCustomSelected = existingData !== undefined &&
|
|
576
|
+
Array.isArray(existingData) &&
|
|
577
|
+
existingData.length === 2;
|
|
578
|
+
|
|
579
|
+
if (isCustomSelected) {
|
|
580
|
+
customClone.classList.add('cf-checked');
|
|
581
|
+
customClone.style.backgroundColor = config.selectedBackground;
|
|
582
|
+
console.log(` â
Pre-selected: Custom Range [${existingData[0]}, ${existingData[1]}]`);
|
|
583
|
+
} else {
|
|
584
|
+
customClone.classList.remove('cf-checked');
|
|
585
|
+
customClone.style.backgroundColor = 'transparent';
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
customClone.setAttribute('data-chat-element', 'single-select-input');
|
|
589
|
+
customClone.setAttribute('data-field', field);
|
|
590
|
+
customClone.setAttribute('data-value', customConfig.value || 'custom');
|
|
591
|
+
customClone.setAttribute('data-name', customConfig.name);
|
|
592
|
+
customClone.setAttribute('data-is-custom', 'true');
|
|
593
|
+
|
|
594
|
+
const customInput = customClone.querySelector('[data-chat-input-element="input"]');
|
|
595
|
+
if (customInput) {
|
|
596
|
+
customInput.name = field;
|
|
597
|
+
customInput.value = customConfig.value || 'custom';
|
|
598
|
+
customInput.checked = isCustomSelected;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
const customTickIcon = customClone.querySelector('[data-chat-input-element="tick-icon"]');
|
|
602
|
+
if (customTickIcon) {
|
|
603
|
+
customTickIcon.style.display = isCustomSelected ? 'block' : 'none';
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const customTextElement = customClone.querySelector('[data-chat-input-element="text"]');
|
|
607
|
+
if (customTextElement) {
|
|
608
|
+
customTextElement.textContent = customConfig.name;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
optionsWrapper.appendChild(customClone);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// Append wrapper to messages
|
|
615
|
+
elements.messages.appendChild(optionsWrapper);
|
|
616
|
+
|
|
617
|
+
// Render min/max inputs
|
|
618
|
+
renderMinMaxInputs(field, customConfig, existingData);
|
|
619
|
+
|
|
620
|
+
scrollToBottom();
|
|
621
|
+
|
|
622
|
+
// Add click handlers for regular and custom options
|
|
623
|
+
const optionElements = optionsWrapper.querySelectorAll('[data-chat-input-element="container"]');
|
|
624
|
+
optionElements.forEach(el => {
|
|
625
|
+
el.onclick = (e) => {
|
|
626
|
+
e.stopPropagation();
|
|
627
|
+
e.preventDefault();
|
|
628
|
+
handleCustomSelectClick(el, field, customConfig);
|
|
629
|
+
};
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function renderMinMaxInputs(field, customConfig, existingData) {
|
|
634
|
+
if (!elements.messages || !customConfig) return;
|
|
635
|
+
|
|
636
|
+
// Find min/max input templates
|
|
637
|
+
const minSelector = '[data-chat-element="single-select-custom-min"]';
|
|
638
|
+
const maxSelector = '[data-chat-element="single-select-custom-max"]';
|
|
639
|
+
const minTemplate = document.querySelector(minSelector);
|
|
640
|
+
const maxTemplate = document.querySelector(maxSelector);
|
|
641
|
+
|
|
642
|
+
if (!minTemplate || !maxTemplate) {
|
|
643
|
+
console.error('Min/Max input templates not found');
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Create wrapper for min/max
|
|
648
|
+
const rangeWrapper = document.createElement('div');
|
|
649
|
+
rangeWrapper.setAttribute('data-chat-element', 'range-wrapper');
|
|
650
|
+
rangeWrapper.setAttribute('data-field', field);
|
|
651
|
+
|
|
652
|
+
// Check if should show min/max (custom option selected)
|
|
653
|
+
// Data is stored as array [min, max]
|
|
654
|
+
const showMinMax = existingData !== undefined &&
|
|
655
|
+
Array.isArray(existingData) &&
|
|
656
|
+
existingData.length === 2;
|
|
657
|
+
|
|
658
|
+
rangeWrapper.style.display = showMinMax ? '' : 'none';
|
|
659
|
+
|
|
660
|
+
// Clone and setup min input
|
|
661
|
+
const minClone = minTemplate.cloneNode(true);
|
|
662
|
+
minClone.style.display = '';
|
|
663
|
+
minClone.setAttribute('data-field', field);
|
|
664
|
+
|
|
665
|
+
const minInput = minClone.querySelector('[data-chat-input-element="input"]');
|
|
666
|
+
if (minInput) {
|
|
667
|
+
minInput.setAttribute('data-field', field);
|
|
668
|
+
minInput.setAttribute('data-input-type', 'min');
|
|
669
|
+
minInput.type = 'number';
|
|
670
|
+
minInput.min = customConfig.min !== undefined ? customConfig.min : 0;
|
|
671
|
+
minInput.max = customConfig.max !== undefined ? customConfig.max : 100;
|
|
672
|
+
minInput.value = showMinMax && existingData[0] !== undefined ? existingData[0] : '';
|
|
673
|
+
minInput.placeholder = `Min (${minInput.min}+)`;
|
|
674
|
+
|
|
675
|
+
if (showMinMax) {
|
|
676
|
+
console.log(` â
Pre-filled min: ${existingData[0]}`);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Clone and setup max input
|
|
681
|
+
const maxClone = maxTemplate.cloneNode(true);
|
|
682
|
+
maxClone.style.display = '';
|
|
683
|
+
maxClone.setAttribute('data-field', field);
|
|
684
|
+
|
|
685
|
+
const maxInput = maxClone.querySelector('[data-chat-input-element="input"]');
|
|
686
|
+
if (maxInput) {
|
|
687
|
+
maxInput.setAttribute('data-field', field);
|
|
688
|
+
maxInput.setAttribute('data-input-type', 'max');
|
|
689
|
+
maxInput.type = 'number';
|
|
690
|
+
maxInput.min = customConfig.min !== undefined ? customConfig.min : 0;
|
|
691
|
+
maxInput.max = customConfig.max !== undefined ? customConfig.max : 100;
|
|
692
|
+
maxInput.value = showMinMax && existingData[1] !== undefined ? existingData[1] : '';
|
|
693
|
+
maxInput.placeholder = `Max (${maxInput.max} max)`;
|
|
694
|
+
|
|
695
|
+
if (showMinMax) {
|
|
696
|
+
console.log(` â
Pre-filled max: ${existingData[1]}`);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
rangeWrapper.appendChild(minClone);
|
|
701
|
+
rangeWrapper.appendChild(maxClone);
|
|
702
|
+
|
|
703
|
+
// Add error message display
|
|
704
|
+
const errorDiv = document.createElement('div');
|
|
705
|
+
errorDiv.setAttribute('data-chat-element', 'range-error');
|
|
706
|
+
errorDiv.setAttribute('data-field', field);
|
|
707
|
+
errorDiv.style.color = '#ff4444';
|
|
708
|
+
errorDiv.style.fontSize = '14px';
|
|
709
|
+
errorDiv.style.marginTop = '8px';
|
|
710
|
+
errorDiv.style.display = 'none';
|
|
711
|
+
rangeWrapper.appendChild(errorDiv);
|
|
712
|
+
|
|
713
|
+
elements.messages.appendChild(rangeWrapper);
|
|
714
|
+
|
|
715
|
+
// Add focus handlers to select custom option when editing
|
|
716
|
+
if (minInput) {
|
|
717
|
+
minInput.onfocus = () => selectCustomOption(field);
|
|
718
|
+
minInput.oninput = () => validateMinMax(field, customConfig);
|
|
719
|
+
}
|
|
720
|
+
if (maxInput) {
|
|
721
|
+
maxInput.onfocus = () => selectCustomOption(field);
|
|
722
|
+
maxInput.oninput = () => validateMinMax(field, customConfig);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
function selectCustomOption(field) {
|
|
727
|
+
// Deselect all regular options
|
|
728
|
+
const allOptions = document.querySelectorAll(`[data-field="${field}"][data-chat-element="single-select-input"]`);
|
|
729
|
+
allOptions.forEach(opt => {
|
|
730
|
+
const isCustom = opt.getAttribute('data-is-custom') === 'true';
|
|
731
|
+
if (isCustom) {
|
|
732
|
+
// Select custom option
|
|
733
|
+
opt.classList.add('cf-checked');
|
|
734
|
+
opt.style.setProperty('background-color', config.selectedBackground, 'important');
|
|
735
|
+
const tickIcon = opt.querySelector('[data-chat-input-element="tick-icon"]');
|
|
736
|
+
if (tickIcon) tickIcon.style.setProperty('display', 'block', 'important');
|
|
737
|
+
} else {
|
|
738
|
+
// Deselect regular options
|
|
739
|
+
opt.classList.remove('cf-checked');
|
|
740
|
+
opt.style.setProperty('background-color', 'transparent', 'important');
|
|
741
|
+
const tickIcon = opt.querySelector('[data-chat-input-element="tick-icon"]');
|
|
742
|
+
if (tickIcon) tickIcon.style.setProperty('display', 'none', 'important');
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
// Show min/max inputs
|
|
747
|
+
const rangeWrapper = document.querySelector(`[data-chat-element="range-wrapper"][data-field="${field}"]`);
|
|
748
|
+
if (rangeWrapper) {
|
|
749
|
+
rangeWrapper.style.display = '';
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
function handleCustomSelectClick(element, field, customConfig) {
|
|
754
|
+
const isCustom = element.getAttribute('data-is-custom') === 'true';
|
|
755
|
+
const valueStr = element.getAttribute('data-value');
|
|
756
|
+
const optionName = element.getAttribute('data-name');
|
|
757
|
+
|
|
758
|
+
console.log(`Custom-select clicked:`, { field, name: optionName, isCustom });
|
|
759
|
+
|
|
760
|
+
// Deselect all options first
|
|
761
|
+
const allOptions = document.querySelectorAll(`[data-field="${field}"][data-chat-element="single-select-input"]`);
|
|
762
|
+
allOptions.forEach(opt => {
|
|
763
|
+
opt.classList.remove('cf-checked');
|
|
764
|
+
opt.style.setProperty('background-color', 'transparent', 'important');
|
|
765
|
+
const tickIcon = opt.querySelector('[data-chat-input-element="tick-icon"]');
|
|
766
|
+
if (tickIcon) tickIcon.style.setProperty('display', 'none', 'important');
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
// Select this option
|
|
770
|
+
element.classList.add('cf-checked');
|
|
771
|
+
element.style.setProperty('background-color', config.selectedBackground, 'important');
|
|
772
|
+
const tickIcon = element.querySelector('[data-chat-input-element="tick-icon"]');
|
|
773
|
+
if (tickIcon) tickIcon.style.setProperty('display', 'block', 'important');
|
|
774
|
+
|
|
775
|
+
if (isCustom) {
|
|
776
|
+
// Show min/max inputs
|
|
777
|
+
const rangeWrapper = document.querySelector(`[data-chat-element="range-wrapper"][data-field="${field}"]`);
|
|
778
|
+
if (rangeWrapper) {
|
|
779
|
+
rangeWrapper.style.display = '';
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// Don't save data yet - wait for validation
|
|
783
|
+
chatState.currentSelection = null;
|
|
784
|
+
console.log(' âšī¸ Custom selected - waiting for min/max input');
|
|
785
|
+
} else {
|
|
786
|
+
// Hide min/max inputs
|
|
787
|
+
const rangeWrapper = document.querySelector(`[data-chat-element="range-wrapper"][data-field="${field}"]`);
|
|
788
|
+
if (rangeWrapper) {
|
|
789
|
+
rangeWrapper.style.display = 'none';
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// Parse and save regular value
|
|
793
|
+
let value;
|
|
794
|
+
try {
|
|
795
|
+
value = JSON.parse(valueStr);
|
|
796
|
+
} catch (e) {
|
|
797
|
+
value = valueStr;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
chatState.data[field] = value;
|
|
801
|
+
chatState.currentSelection = { field, value, name: optionName };
|
|
802
|
+
console.log(' â
Regular option selected:', value);
|
|
803
|
+
enableNextButton();
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
function validateMinMax(field, customConfig) {
|
|
808
|
+
const minInput = document.querySelector(`[data-field="${field}"][data-input-type="min"] [data-chat-input-element="input"]`);
|
|
809
|
+
const maxInput = document.querySelector(`[data-field="${field}"][data-input-type="max"] [data-chat-input-element="input"]`);
|
|
810
|
+
const errorDiv = document.querySelector(`[data-chat-element="range-error"][data-field="${field}"]`);
|
|
811
|
+
|
|
812
|
+
if (!minInput || !maxInput) return false;
|
|
813
|
+
|
|
814
|
+
const minValue = parseFloat(minInput.value);
|
|
815
|
+
const maxValue = parseFloat(maxInput.value);
|
|
816
|
+
const minFilled = minInput.value.trim() !== '';
|
|
817
|
+
const maxFilled = maxInput.value.trim() !== '';
|
|
818
|
+
|
|
819
|
+
const minConstraint = customConfig.min !== undefined ? customConfig.min : 0;
|
|
820
|
+
const maxConstraint = customConfig.max !== undefined ? customConfig.max : 100;
|
|
821
|
+
|
|
822
|
+
// Helper to show error
|
|
823
|
+
const showError = (message) => {
|
|
824
|
+
if (errorDiv) {
|
|
825
|
+
errorDiv.textContent = message;
|
|
826
|
+
errorDiv.style.display = 'block';
|
|
827
|
+
}
|
|
828
|
+
console.log(' â Validation error:', message);
|
|
829
|
+
disableNextButton();
|
|
830
|
+
return false;
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
// Helper to hide error
|
|
834
|
+
const hideError = () => {
|
|
835
|
+
if (errorDiv) {
|
|
836
|
+
errorDiv.style.display = 'none';
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
// Validation rules
|
|
841
|
+
|
|
842
|
+
// 1. Check if only one is filled
|
|
843
|
+
if (minFilled && !maxFilled) {
|
|
844
|
+
return showError(config.customRangeErrors.maxRequired);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
if (!minFilled && maxFilled) {
|
|
848
|
+
return showError(config.customRangeErrors.minRequired);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// 2. Check if both are empty
|
|
852
|
+
if (!minFilled && !maxFilled) {
|
|
853
|
+
hideError();
|
|
854
|
+
disableNextButton();
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// 3. Check if values are valid numbers
|
|
859
|
+
if (isNaN(minValue) || isNaN(maxValue)) {
|
|
860
|
+
return showError(config.customRangeErrors.bothRequired);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
// 4. Check min constraint
|
|
864
|
+
if (minValue < minConstraint) {
|
|
865
|
+
const msg = config.customRangeErrors.minBelowConstraint.replace('{min}', minConstraint);
|
|
866
|
+
return showError(msg);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// 5. Check max constraint
|
|
870
|
+
if (maxValue > maxConstraint) {
|
|
871
|
+
const msg = config.customRangeErrors.maxAboveConstraint.replace('{max}', maxConstraint);
|
|
872
|
+
return showError(msg);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// 6. Check min < max
|
|
876
|
+
if (minValue >= maxValue) {
|
|
877
|
+
return showError(config.customRangeErrors.minGreaterThanMax);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// All valid! Hide error and save data as array
|
|
881
|
+
hideError();
|
|
882
|
+
|
|
883
|
+
// Store as array [min, max]
|
|
884
|
+
chatState.data[field] = [minValue, maxValue];
|
|
885
|
+
chatState.currentSelection = {
|
|
886
|
+
field,
|
|
887
|
+
value: [minValue, maxValue],
|
|
888
|
+
name: `${minValue}-${maxValue}`
|
|
889
|
+
};
|
|
890
|
+
|
|
891
|
+
console.log(' â
Range valid - stored as array:', [minValue, maxValue]);
|
|
892
|
+
enableNextButton();
|
|
893
|
+
return true;
|
|
894
|
+
}
|
|
895
|
+
|
|
486
896
|
// =============================================================================
|
|
487
897
|
// TEXT/NUMBER INPUT RENDERING
|
|
488
898
|
// =============================================================================
|
|
@@ -828,6 +1238,20 @@ async function showNextStep() {
|
|
|
828
1238
|
if (!inputRequired) {
|
|
829
1239
|
enableNextButton();
|
|
830
1240
|
}
|
|
1241
|
+
} else if (inputType === 'single-select-custom') {
|
|
1242
|
+
// Render single-select with custom min/max option
|
|
1243
|
+
renderCustomSelectOptions(
|
|
1244
|
+
nextStep.input.options,
|
|
1245
|
+
nextStep.input.field,
|
|
1246
|
+
nextStep.input.custom
|
|
1247
|
+
);
|
|
1248
|
+
|
|
1249
|
+
// Disable Next button initially (wait for selection/validation)
|
|
1250
|
+
if (inputRequired) {
|
|
1251
|
+
disableNextButton();
|
|
1252
|
+
} else {
|
|
1253
|
+
enableNextButton();
|
|
1254
|
+
}
|
|
831
1255
|
} else {
|
|
832
1256
|
// Render options (single-select or multi-select)
|
|
833
1257
|
const isSingleSelect = inputType === 'single-select';
|