@aquera/ngx-smart-table 0.0.16-alpha → 0.0.17-alpha
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/esm2020/lib/editors/nile-select-editor.mjs +109 -30
- package/fesm2015/aquera-ngx-smart-table.mjs +111 -31
- package/fesm2015/aquera-ngx-smart-table.mjs.map +1 -1
- package/fesm2020/aquera-ngx-smart-table.mjs +108 -29
- package/fesm2020/aquera-ngx-smart-table.mjs.map +1 -1
- package/lib/editors/nile-select-editor.d.ts +3 -0
- package/package.json +1 -1
|
@@ -3599,6 +3599,7 @@ class NileSelectEditor {
|
|
|
3599
3599
|
this.acceptsInitialKeypress = false;
|
|
3600
3600
|
this.eventListeners = [];
|
|
3601
3601
|
this.currentOptions = [];
|
|
3602
|
+
this.trackedValues = []; // Track selected values for virtual scroll
|
|
3602
3603
|
// Handle Observable options
|
|
3603
3604
|
if (isObservable(options.options)) {
|
|
3604
3605
|
this.optionsSubscription = options.options.subscribe(opts => {
|
|
@@ -3642,13 +3643,16 @@ class NileSelectEditor {
|
|
|
3642
3643
|
// Clear container and append select
|
|
3643
3644
|
context.container.innerHTML = '';
|
|
3644
3645
|
context.container.appendChild(this.select);
|
|
3645
|
-
// Focus
|
|
3646
|
+
// Focus the select after render
|
|
3646
3647
|
setTimeout(() => {
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
this.select
|
|
3648
|
+
var _a;
|
|
3649
|
+
try {
|
|
3650
|
+
(_a = this.select) === null || _a === void 0 ? void 0 : _a.focus();
|
|
3650
3651
|
}
|
|
3651
|
-
|
|
3652
|
+
catch (e) {
|
|
3653
|
+
// Ignore errors
|
|
3654
|
+
}
|
|
3655
|
+
}, 50);
|
|
3652
3656
|
}
|
|
3653
3657
|
/**
|
|
3654
3658
|
* Set the initial value for the select
|
|
@@ -3660,17 +3664,21 @@ class NileSelectEditor {
|
|
|
3660
3664
|
// Handle multiple selection - value should be array
|
|
3661
3665
|
if (Array.isArray(value)) {
|
|
3662
3666
|
this.select.value = value;
|
|
3667
|
+
this.trackedValues = [...value]; // Initialize tracked values
|
|
3663
3668
|
}
|
|
3664
3669
|
else if (value) {
|
|
3665
3670
|
this.select.value = [String(value)];
|
|
3671
|
+
this.trackedValues = [String(value)];
|
|
3666
3672
|
}
|
|
3667
3673
|
else {
|
|
3668
3674
|
this.select.value = [];
|
|
3675
|
+
this.trackedValues = [];
|
|
3669
3676
|
}
|
|
3670
3677
|
}
|
|
3671
3678
|
else {
|
|
3672
3679
|
// Handle single selection
|
|
3673
3680
|
this.select.value = value ? String(value) : '';
|
|
3681
|
+
this.trackedValues = value ? [String(value)] : [];
|
|
3674
3682
|
}
|
|
3675
3683
|
}
|
|
3676
3684
|
/**
|
|
@@ -3754,12 +3762,17 @@ class NileSelectEditor {
|
|
|
3754
3762
|
updateOptions() {
|
|
3755
3763
|
if (!this.select)
|
|
3756
3764
|
return;
|
|
3757
|
-
//
|
|
3758
|
-
|
|
3759
|
-
this.
|
|
3765
|
+
// For virtual scroll mode, just update the data property (no DOM children to clear)
|
|
3766
|
+
if (this.options.enableVirtualScroll) {
|
|
3767
|
+
this.createAndAppendOptions(this.currentOptions);
|
|
3768
|
+
}
|
|
3769
|
+
else {
|
|
3770
|
+
// Standard mode: clear existing nile-option elements first
|
|
3771
|
+
while (this.select.firstChild) {
|
|
3772
|
+
this.select.removeChild(this.select.firstChild);
|
|
3773
|
+
}
|
|
3774
|
+
this.createAndAppendOptions(this.currentOptions);
|
|
3760
3775
|
}
|
|
3761
|
-
// Re-append with new options
|
|
3762
|
-
this.createAndAppendOptions(this.currentOptions);
|
|
3763
3776
|
// Trigger update on the web component
|
|
3764
3777
|
if (this.select.requestUpdate) {
|
|
3765
3778
|
this.select.requestUpdate();
|
|
@@ -3767,11 +3780,22 @@ class NileSelectEditor {
|
|
|
3767
3780
|
}
|
|
3768
3781
|
/**
|
|
3769
3782
|
* Create NileOption elements and append them to the select
|
|
3783
|
+
* When enableVirtualScroll is true, uses data property instead of DOM elements
|
|
3784
|
+
* @see https://nile.aqueralabs.com/select-virtual?theme=enterprise
|
|
3770
3785
|
* @param options - The options to render
|
|
3771
3786
|
*/
|
|
3772
3787
|
createAndAppendOptions(options) {
|
|
3773
3788
|
if (!this.select)
|
|
3774
3789
|
return;
|
|
3790
|
+
// Virtual scroll mode: use data property instead of DOM elements
|
|
3791
|
+
if (this.options.enableVirtualScroll) {
|
|
3792
|
+
const virtualData = options.map(opt => typeof opt === 'string'
|
|
3793
|
+
? { value: opt, label: opt }
|
|
3794
|
+
: { value: opt.value, label: opt.label, disabled: opt.disabled });
|
|
3795
|
+
this.select.data = virtualData;
|
|
3796
|
+
return;
|
|
3797
|
+
}
|
|
3798
|
+
// Standard mode: create nile-option elements
|
|
3775
3799
|
options.forEach(opt => {
|
|
3776
3800
|
const nileOption = document.createElement('nile-option');
|
|
3777
3801
|
// Auto-detect format: string or SelectOption object
|
|
@@ -3819,43 +3843,89 @@ class NileSelectEditor {
|
|
|
3819
3843
|
// Multi-select should stay open until user clicks outside
|
|
3820
3844
|
if (!this.options.multiple) {
|
|
3821
3845
|
const changeHandler = (e) => {
|
|
3822
|
-
var _a, _b;
|
|
3823
3846
|
const customEvent = e;
|
|
3824
|
-
|
|
3825
|
-
(
|
|
3826
|
-
|
|
3847
|
+
try {
|
|
3848
|
+
if (validateOnSave && this.select && !this.select.checkValidity()) {
|
|
3849
|
+
this.select.reportValidity();
|
|
3850
|
+
return;
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
catch (err) {
|
|
3854
|
+
// Ignore validation errors - nile-select internals may not be ready
|
|
3827
3855
|
}
|
|
3828
3856
|
context.onSave(this.parseValue(customEvent.detail.value));
|
|
3829
3857
|
};
|
|
3830
3858
|
this.select.addEventListener('nile-change', changeHandler);
|
|
3831
3859
|
this.eventListeners.push({ event: 'nile-change', handler: changeHandler });
|
|
3832
3860
|
}
|
|
3861
|
+
// For multi-select, track value changes (needed for virtual scroll where value property doesn't update)
|
|
3862
|
+
if (this.options.multiple) {
|
|
3863
|
+
const trackValueHandler = (e) => {
|
|
3864
|
+
var _a;
|
|
3865
|
+
const customEvent = e;
|
|
3866
|
+
const newValue = (_a = customEvent.detail) === null || _a === void 0 ? void 0 : _a.value;
|
|
3867
|
+
if (newValue !== undefined) {
|
|
3868
|
+
if (Array.isArray(newValue)) {
|
|
3869
|
+
this.trackedValues = [...newValue];
|
|
3870
|
+
}
|
|
3871
|
+
else {
|
|
3872
|
+
this.trackedValues = newValue ? [newValue] : [];
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
};
|
|
3876
|
+
this.select.addEventListener('nile-change', trackValueHandler);
|
|
3877
|
+
this.eventListeners.push({ event: 'nile-change', handler: trackValueHandler });
|
|
3878
|
+
}
|
|
3833
3879
|
// Track if save was already triggered (to prevent double save)
|
|
3834
3880
|
let saveTriggered = false;
|
|
3835
3881
|
// Use mousedown on document to detect clicks outside the select and portal
|
|
3836
3882
|
const documentMousedownHandler = (e) => {
|
|
3837
|
-
var _a, _b;
|
|
3883
|
+
var _a, _b, _c, _d, _e;
|
|
3838
3884
|
if (saveTriggered)
|
|
3839
3885
|
return;
|
|
3840
3886
|
if (!this.select)
|
|
3841
3887
|
return;
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
if
|
|
3845
|
-
|
|
3888
|
+
// Use composedPath to traverse shadow DOM boundaries
|
|
3889
|
+
const path = e.composedPath();
|
|
3890
|
+
// Check if click is inside the select element or any nile-select related elements
|
|
3891
|
+
for (const element of path) {
|
|
3892
|
+
if (!(element instanceof HTMLElement))
|
|
3893
|
+
continue;
|
|
3894
|
+
// Check if it's our select element
|
|
3895
|
+
if (element === this.select) {
|
|
3896
|
+
return;
|
|
3897
|
+
}
|
|
3898
|
+
// Check for nile-select portals (various class names)
|
|
3899
|
+
if (((_a = element.classList) === null || _a === void 0 ? void 0 : _a.contains('nile-select-portal-append')) ||
|
|
3900
|
+
((_b = element.classList) === null || _b === void 0 ? void 0 : _b.contains('select__listbox')) ||
|
|
3901
|
+
((_c = element.classList) === null || _c === void 0 ? void 0 : _c.contains('select__options')) ||
|
|
3902
|
+
((_d = element.tagName) === null || _d === void 0 ? void 0 : _d.toLowerCase()) === 'nile-option' ||
|
|
3903
|
+
((_e = element.tagName) === null || _e === void 0 ? void 0 : _e.toLowerCase()) === 'nile-select') {
|
|
3904
|
+
return;
|
|
3905
|
+
}
|
|
3906
|
+
// Check for any element with nile-select in its class
|
|
3907
|
+
if (element.className && typeof element.className === 'string' &&
|
|
3908
|
+
element.className.includes('nile-select')) {
|
|
3909
|
+
return;
|
|
3910
|
+
}
|
|
3846
3911
|
}
|
|
3847
|
-
//
|
|
3848
|
-
const portals = document.querySelectorAll('.nile-select-portal-append');
|
|
3912
|
+
// Also check portal containers directly
|
|
3913
|
+
const portals = document.querySelectorAll('.nile-select-portal-append, [class*="select__listbox"]');
|
|
3849
3914
|
for (let i = 0; i < portals.length; i++) {
|
|
3850
|
-
if (portals[i].contains(target)) {
|
|
3915
|
+
if (portals[i].contains(e.target)) {
|
|
3851
3916
|
return;
|
|
3852
3917
|
}
|
|
3853
3918
|
}
|
|
3854
3919
|
// Click is outside - save and exit
|
|
3855
3920
|
saveTriggered = true;
|
|
3856
|
-
|
|
3857
|
-
(
|
|
3858
|
-
|
|
3921
|
+
try {
|
|
3922
|
+
if (validateOnSave && this.select && !this.select.checkValidity()) {
|
|
3923
|
+
this.select.reportValidity();
|
|
3924
|
+
return;
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
catch (err) {
|
|
3928
|
+
// Ignore validation errors - nile-select internals may not be ready
|
|
3859
3929
|
}
|
|
3860
3930
|
context.onSave(this.getCurrentValue());
|
|
3861
3931
|
};
|
|
@@ -3925,19 +3995,29 @@ class NileSelectEditor {
|
|
|
3925
3995
|
}
|
|
3926
3996
|
focus() {
|
|
3927
3997
|
var _a;
|
|
3928
|
-
|
|
3998
|
+
try {
|
|
3999
|
+
(_a = this.select) === null || _a === void 0 ? void 0 : _a.focus();
|
|
4000
|
+
}
|
|
4001
|
+
catch (e) {
|
|
4002
|
+
// Ignore focus errors - nile-select internals may not be ready
|
|
4003
|
+
}
|
|
3929
4004
|
}
|
|
3930
4005
|
getCurrentValue() {
|
|
3931
4006
|
if (!this.select) {
|
|
3932
4007
|
return (this.options.multiple ? [] : '');
|
|
3933
4008
|
}
|
|
3934
|
-
|
|
3935
|
-
// Handle multiple selection
|
|
4009
|
+
// For multi-select, prefer tracked values (more reliable for virtual scroll)
|
|
3936
4010
|
if (this.options.multiple) {
|
|
3937
|
-
|
|
4011
|
+
// Use tracked values if available, otherwise try component value
|
|
4012
|
+
let values = this.trackedValues.length > 0 ? this.trackedValues : this.select.value;
|
|
4013
|
+
if (Array.isArray(values)) {
|
|
4014
|
+
return values.filter((v) => v !== undefined && v !== null && v !== '');
|
|
4015
|
+
}
|
|
4016
|
+
return (values ? [values] : []);
|
|
3938
4017
|
}
|
|
3939
|
-
//
|
|
3940
|
-
|
|
4018
|
+
// For single-select, use tracked values or component value
|
|
4019
|
+
let value = this.trackedValues.length > 0 ? this.trackedValues[0] : this.select.value;
|
|
4020
|
+
return (Array.isArray(value) ? (value.length > 0 ? value[0] : '') : (value || ''));
|
|
3941
4021
|
}
|
|
3942
4022
|
}
|
|
3943
4023
|
|