@aquera/ngx-smart-table 0.0.16-alpha → 0.0.17-patch-0.1

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