@aquera/ngx-smart-table 0.0.16-alpha → 0.0.17
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
|
@@ -3678,6 +3678,7 @@ class NileSelectEditor {
|
|
|
3678
3678
|
this.acceptsInitialKeypress = false;
|
|
3679
3679
|
this.eventListeners = [];
|
|
3680
3680
|
this.currentOptions = [];
|
|
3681
|
+
this.trackedValues = []; // Track selected values for virtual scroll
|
|
3681
3682
|
// Handle Observable options
|
|
3682
3683
|
if (isObservable(options.options)) {
|
|
3683
3684
|
this.optionsSubscription = options.options.subscribe(opts => {
|
|
@@ -3721,13 +3722,15 @@ class NileSelectEditor {
|
|
|
3721
3722
|
// Clear container and append select
|
|
3722
3723
|
context.container.innerHTML = '';
|
|
3723
3724
|
context.container.appendChild(this.select);
|
|
3724
|
-
// Focus
|
|
3725
|
+
// Focus the select after render
|
|
3725
3726
|
setTimeout(() => {
|
|
3726
|
-
|
|
3727
|
-
this.select
|
|
3728
|
-
this.select.open = true;
|
|
3727
|
+
try {
|
|
3728
|
+
this.select?.focus();
|
|
3729
3729
|
}
|
|
3730
|
-
|
|
3730
|
+
catch (e) {
|
|
3731
|
+
// Ignore errors
|
|
3732
|
+
}
|
|
3733
|
+
}, 50);
|
|
3731
3734
|
}
|
|
3732
3735
|
/**
|
|
3733
3736
|
* Set the initial value for the select
|
|
@@ -3739,17 +3742,21 @@ class NileSelectEditor {
|
|
|
3739
3742
|
// Handle multiple selection - value should be array
|
|
3740
3743
|
if (Array.isArray(value)) {
|
|
3741
3744
|
this.select.value = value;
|
|
3745
|
+
this.trackedValues = [...value]; // Initialize tracked values
|
|
3742
3746
|
}
|
|
3743
3747
|
else if (value) {
|
|
3744
3748
|
this.select.value = [String(value)];
|
|
3749
|
+
this.trackedValues = [String(value)];
|
|
3745
3750
|
}
|
|
3746
3751
|
else {
|
|
3747
3752
|
this.select.value = [];
|
|
3753
|
+
this.trackedValues = [];
|
|
3748
3754
|
}
|
|
3749
3755
|
}
|
|
3750
3756
|
else {
|
|
3751
3757
|
// Handle single selection
|
|
3752
3758
|
this.select.value = value ? String(value) : '';
|
|
3759
|
+
this.trackedValues = value ? [String(value)] : [];
|
|
3753
3760
|
}
|
|
3754
3761
|
}
|
|
3755
3762
|
/**
|
|
@@ -3833,12 +3840,17 @@ class NileSelectEditor {
|
|
|
3833
3840
|
updateOptions() {
|
|
3834
3841
|
if (!this.select)
|
|
3835
3842
|
return;
|
|
3836
|
-
//
|
|
3837
|
-
|
|
3838
|
-
this.
|
|
3843
|
+
// For virtual scroll mode, just update the data property (no DOM children to clear)
|
|
3844
|
+
if (this.options.enableVirtualScroll) {
|
|
3845
|
+
this.createAndAppendOptions(this.currentOptions);
|
|
3846
|
+
}
|
|
3847
|
+
else {
|
|
3848
|
+
// Standard mode: clear existing nile-option elements first
|
|
3849
|
+
while (this.select.firstChild) {
|
|
3850
|
+
this.select.removeChild(this.select.firstChild);
|
|
3851
|
+
}
|
|
3852
|
+
this.createAndAppendOptions(this.currentOptions);
|
|
3839
3853
|
}
|
|
3840
|
-
// Re-append with new options
|
|
3841
|
-
this.createAndAppendOptions(this.currentOptions);
|
|
3842
3854
|
// Trigger update on the web component
|
|
3843
3855
|
if (this.select.requestUpdate) {
|
|
3844
3856
|
this.select.requestUpdate();
|
|
@@ -3846,11 +3858,22 @@ class NileSelectEditor {
|
|
|
3846
3858
|
}
|
|
3847
3859
|
/**
|
|
3848
3860
|
* Create NileOption elements and append them to the select
|
|
3861
|
+
* When enableVirtualScroll is true, uses data property instead of DOM elements
|
|
3862
|
+
* @see https://nile.aqueralabs.com/select-virtual?theme=enterprise
|
|
3849
3863
|
* @param options - The options to render
|
|
3850
3864
|
*/
|
|
3851
3865
|
createAndAppendOptions(options) {
|
|
3852
3866
|
if (!this.select)
|
|
3853
3867
|
return;
|
|
3868
|
+
// Virtual scroll mode: use data property instead of DOM elements
|
|
3869
|
+
if (this.options.enableVirtualScroll) {
|
|
3870
|
+
const virtualData = options.map(opt => typeof opt === 'string'
|
|
3871
|
+
? { value: opt, label: opt }
|
|
3872
|
+
: { value: opt.value, label: opt.label, disabled: opt.disabled });
|
|
3873
|
+
this.select.data = virtualData;
|
|
3874
|
+
return;
|
|
3875
|
+
}
|
|
3876
|
+
// Standard mode: create nile-option elements
|
|
3854
3877
|
options.forEach(opt => {
|
|
3855
3878
|
const nileOption = document.createElement('nile-option');
|
|
3856
3879
|
// Auto-detect format: string or SelectOption object
|
|
@@ -3899,15 +3922,37 @@ class NileSelectEditor {
|
|
|
3899
3922
|
if (!this.options.multiple) {
|
|
3900
3923
|
const changeHandler = (e) => {
|
|
3901
3924
|
const customEvent = e;
|
|
3902
|
-
|
|
3903
|
-
this.select
|
|
3904
|
-
|
|
3925
|
+
try {
|
|
3926
|
+
if (validateOnSave && this.select && !this.select.checkValidity()) {
|
|
3927
|
+
this.select.reportValidity();
|
|
3928
|
+
return;
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
catch (err) {
|
|
3932
|
+
// Ignore validation errors - nile-select internals may not be ready
|
|
3905
3933
|
}
|
|
3906
3934
|
context.onSave(this.parseValue(customEvent.detail.value));
|
|
3907
3935
|
};
|
|
3908
3936
|
this.select.addEventListener('nile-change', changeHandler);
|
|
3909
3937
|
this.eventListeners.push({ event: 'nile-change', handler: changeHandler });
|
|
3910
3938
|
}
|
|
3939
|
+
// For multi-select, track value changes (needed for virtual scroll where value property doesn't update)
|
|
3940
|
+
if (this.options.multiple) {
|
|
3941
|
+
const trackValueHandler = (e) => {
|
|
3942
|
+
const customEvent = e;
|
|
3943
|
+
const newValue = customEvent.detail?.value;
|
|
3944
|
+
if (newValue !== undefined) {
|
|
3945
|
+
if (Array.isArray(newValue)) {
|
|
3946
|
+
this.trackedValues = [...newValue];
|
|
3947
|
+
}
|
|
3948
|
+
else {
|
|
3949
|
+
this.trackedValues = newValue ? [newValue] : [];
|
|
3950
|
+
}
|
|
3951
|
+
}
|
|
3952
|
+
};
|
|
3953
|
+
this.select.addEventListener('nile-change', trackValueHandler);
|
|
3954
|
+
this.eventListeners.push({ event: 'nile-change', handler: trackValueHandler });
|
|
3955
|
+
}
|
|
3911
3956
|
// Track if save was already triggered (to prevent double save)
|
|
3912
3957
|
let saveTriggered = false;
|
|
3913
3958
|
// Use mousedown on document to detect clicks outside the select and portal
|
|
@@ -3916,23 +3961,47 @@ class NileSelectEditor {
|
|
|
3916
3961
|
return;
|
|
3917
3962
|
if (!this.select)
|
|
3918
3963
|
return;
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
if
|
|
3922
|
-
|
|
3964
|
+
// Use composedPath to traverse shadow DOM boundaries
|
|
3965
|
+
const path = e.composedPath();
|
|
3966
|
+
// Check if click is inside the select element or any nile-select related elements
|
|
3967
|
+
for (const element of path) {
|
|
3968
|
+
if (!(element instanceof HTMLElement))
|
|
3969
|
+
continue;
|
|
3970
|
+
// Check if it's our select element
|
|
3971
|
+
if (element === this.select) {
|
|
3972
|
+
return;
|
|
3973
|
+
}
|
|
3974
|
+
// Check for nile-select portals (various class names)
|
|
3975
|
+
if (element.classList?.contains('nile-select-portal-append') ||
|
|
3976
|
+
element.classList?.contains('select__listbox') ||
|
|
3977
|
+
element.classList?.contains('select__options') ||
|
|
3978
|
+
element.tagName?.toLowerCase() === 'nile-option' ||
|
|
3979
|
+
element.tagName?.toLowerCase() === 'nile-select') {
|
|
3980
|
+
return;
|
|
3981
|
+
}
|
|
3982
|
+
// Check for any element with nile-select in its class
|
|
3983
|
+
if (element.className && typeof element.className === 'string' &&
|
|
3984
|
+
element.className.includes('nile-select')) {
|
|
3985
|
+
return;
|
|
3986
|
+
}
|
|
3923
3987
|
}
|
|
3924
|
-
//
|
|
3925
|
-
const portals = document.querySelectorAll('.nile-select-portal-append');
|
|
3988
|
+
// Also check portal containers directly
|
|
3989
|
+
const portals = document.querySelectorAll('.nile-select-portal-append, [class*="select__listbox"]');
|
|
3926
3990
|
for (let i = 0; i < portals.length; i++) {
|
|
3927
|
-
if (portals[i].contains(target)) {
|
|
3991
|
+
if (portals[i].contains(e.target)) {
|
|
3928
3992
|
return;
|
|
3929
3993
|
}
|
|
3930
3994
|
}
|
|
3931
3995
|
// Click is outside - save and exit
|
|
3932
3996
|
saveTriggered = true;
|
|
3933
|
-
|
|
3934
|
-
this.select
|
|
3935
|
-
|
|
3997
|
+
try {
|
|
3998
|
+
if (validateOnSave && this.select && !this.select.checkValidity()) {
|
|
3999
|
+
this.select.reportValidity();
|
|
4000
|
+
return;
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
catch (err) {
|
|
4004
|
+
// Ignore validation errors - nile-select internals may not be ready
|
|
3936
4005
|
}
|
|
3937
4006
|
context.onSave(this.getCurrentValue());
|
|
3938
4007
|
};
|
|
@@ -4000,19 +4069,29 @@ class NileSelectEditor {
|
|
|
4000
4069
|
}
|
|
4001
4070
|
}
|
|
4002
4071
|
focus() {
|
|
4003
|
-
|
|
4072
|
+
try {
|
|
4073
|
+
this.select?.focus();
|
|
4074
|
+
}
|
|
4075
|
+
catch (e) {
|
|
4076
|
+
// Ignore focus errors - nile-select internals may not be ready
|
|
4077
|
+
}
|
|
4004
4078
|
}
|
|
4005
4079
|
getCurrentValue() {
|
|
4006
4080
|
if (!this.select) {
|
|
4007
4081
|
return (this.options.multiple ? [] : '');
|
|
4008
4082
|
}
|
|
4009
|
-
|
|
4010
|
-
// Handle multiple selection
|
|
4083
|
+
// For multi-select, prefer tracked values (more reliable for virtual scroll)
|
|
4011
4084
|
if (this.options.multiple) {
|
|
4012
|
-
|
|
4085
|
+
// Use tracked values if available, otherwise try component value
|
|
4086
|
+
let values = this.trackedValues.length > 0 ? this.trackedValues : this.select.value;
|
|
4087
|
+
if (Array.isArray(values)) {
|
|
4088
|
+
return values.filter((v) => v !== undefined && v !== null && v !== '');
|
|
4089
|
+
}
|
|
4090
|
+
return (values ? [values] : []);
|
|
4013
4091
|
}
|
|
4014
|
-
//
|
|
4015
|
-
|
|
4092
|
+
// For single-select, use tracked values or component value
|
|
4093
|
+
let value = this.trackedValues.length > 0 ? this.trackedValues[0] : this.select.value;
|
|
4094
|
+
return (Array.isArray(value) ? (value.length > 0 ? value[0] : '') : (value || ''));
|
|
4016
4095
|
}
|
|
4017
4096
|
}
|
|
4018
4097
|
|