@aquera/ngx-smart-table 0.0.17-alpha → 0.0.17-patch-0.2

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.
@@ -2573,10 +2573,38 @@ class Cell {
2573
2573
  return this.rowIndex;
2574
2574
  }
2575
2575
  /**
2576
- * Set loading state
2576
+ * Link this cell to its replacement so future state mutations forward.
2577
+ */
2578
+ setReplacement(replacement) {
2579
+ this.replacementCell = replacement;
2580
+ }
2581
+ onStateChange(callback) {
2582
+ this.stateChangeCallback = callback;
2583
+ }
2584
+ /**
2585
+ * Set loading state. Forwards to replacement cell if this cell was replaced.
2577
2586
  */
2578
2587
  setLoading(isLoading) {
2588
+ if (this.replacementCell) {
2589
+ this.replacementCell.setLoading(isLoading);
2590
+ return;
2591
+ }
2579
2592
  this.state.isLoading = isLoading;
2593
+ try {
2594
+ this.stateChangeCallback?.();
2595
+ }
2596
+ catch {
2597
+ this.stateChangeCallback = undefined;
2598
+ }
2599
+ }
2600
+ /**
2601
+ * Set cell value (public API, forwards to replacement if replaced).
2602
+ */
2603
+ setValueExternal(value) {
2604
+ if (this.replacementCell) {
2605
+ return this.replacementCell.setValueExternal(value);
2606
+ }
2607
+ return this.setValue(value, true);
2580
2608
  }
2581
2609
  /**
2582
2610
  * Set disabled state
@@ -3649,17 +3677,28 @@ function injectDropdownStyles() {
3649
3677
  }
3650
3678
  /* Combobox styling using ::part() selector */
3651
3679
  nile-select.st-cell-editor::part(combobox) {
3652
- background-color: var(--nile-colors-white-base, var(--ng-colors-bg-primary)) !important;
3680
+ background-color: transparent !important;
3653
3681
  border: solid 1px transparent !important;
3654
- margin: 1px 4px !important;
3682
+ margin: 0px !important;
3683
+ max-height: 28px;
3655
3684
  }
3656
3685
  nile-select.st-cell-editor::part(combobox):hover {
3657
3686
  border: solid 1px transparent !important;
3658
3687
  }
3659
3688
  .st-cell-editor::part(combobox) {
3660
- background-color: var(--nile-colors-white-base, var(--ng-colors-bg-primary)) !important;
3689
+ background-color: transparent !important;
3661
3690
  border: solid 1px transparent !important;
3662
- margin: 1px 4px !important;
3691
+ margin: 0px !important;
3692
+ max-height: 28px;
3693
+ }
3694
+ /* Tag spacing */
3695
+ nile-select.st-cell-editor::part(tag) {
3696
+ margin-right: 0px;
3697
+ padding: 1px 2px;
3698
+ }
3699
+ .st-cell-editor::part(tag) {
3700
+ margin-right: 0px;
3701
+ padding: 1px 2px;
3663
3702
  }
3664
3703
  /* Search input full width */
3665
3704
  .nile-select-portal-append .select__search {
@@ -3679,6 +3718,7 @@ class NileSelectEditor {
3679
3718
  this.eventListeners = [];
3680
3719
  this.currentOptions = [];
3681
3720
  this.trackedValues = []; // Track selected values for virtual scroll
3721
+ this.hasChangeOccurred = false; // Whether a nile-change event has fired
3682
3722
  // Handle Observable options
3683
3723
  if (isObservable(options.options)) {
3684
3724
  this.optionsSubscription = options.options.subscribe(opts => {
@@ -3738,6 +3778,7 @@ class NileSelectEditor {
3738
3778
  setInitialValue(value) {
3739
3779
  if (!this.select)
3740
3780
  return;
3781
+ this.hasChangeOccurred = false;
3741
3782
  if (this.options.multiple) {
3742
3783
  // Handle multiple selection - value should be array
3743
3784
  if (Array.isArray(value)) {
@@ -3942,6 +3983,7 @@ class NileSelectEditor {
3942
3983
  const customEvent = e;
3943
3984
  const newValue = customEvent.detail?.value;
3944
3985
  if (newValue !== undefined) {
3986
+ this.hasChangeOccurred = true;
3945
3987
  if (Array.isArray(newValue)) {
3946
3988
  this.trackedValues = [...newValue];
3947
3989
  }
@@ -4080,17 +4122,16 @@ class NileSelectEditor {
4080
4122
  if (!this.select) {
4081
4123
  return (this.options.multiple ? [] : '');
4082
4124
  }
4083
- // For multi-select, prefer tracked values (more reliable for virtual scroll)
4084
4125
  if (this.options.multiple) {
4085
- // Use tracked values if available, otherwise try component value
4086
- let values = this.trackedValues.length > 0 ? this.trackedValues : this.select.value;
4126
+ // If a change event fired, always use trackedValues (even if empty = all unchecked).
4127
+ // Only fall back to the component value when no change has occurred yet.
4128
+ let values = this.hasChangeOccurred ? this.trackedValues : this.select.value;
4087
4129
  if (Array.isArray(values)) {
4088
4130
  return values.filter((v) => v !== undefined && v !== null && v !== '');
4089
4131
  }
4090
4132
  return (values ? [values] : []);
4091
4133
  }
4092
- // For single-select, use tracked values or component value
4093
- let value = this.trackedValues.length > 0 ? this.trackedValues[0] : this.select.value;
4134
+ let value = this.hasChangeOccurred ? (this.trackedValues[0] ?? '') : this.select.value;
4094
4135
  return (Array.isArray(value) ? (value.length > 0 ? value[0] : '') : (value || ''));
4095
4136
  }
4096
4137
  }
@@ -4722,6 +4763,625 @@ class NileDatePickerEditor {
4722
4763
  }
4723
4764
  }
4724
4765
 
4766
+ /**
4767
+ * Custom editor using NileCodeEditor from @aquera/nile-elements
4768
+ * This provides code editing capabilities with syntax highlighting for table cells
4769
+ */
4770
+ /**
4771
+ * Inject global styles for nile-code-editor in table cells
4772
+ */
4773
+ let codeEditorStylesInjected = false;
4774
+ function injectCodeEditorStyles() {
4775
+ if (codeEditorStylesInjected)
4776
+ return;
4777
+ codeEditorStylesInjected = true;
4778
+ const styleId = 'nile-code-editor-cell-styles';
4779
+ if (document.getElementById(styleId))
4780
+ return;
4781
+ const style = document.createElement('style');
4782
+ style.id = styleId;
4783
+ style.textContent = `
4784
+ /* Nile Code Editor cell styling */
4785
+ nile-code-editor.st-cell-editor {
4786
+ display: block;
4787
+ width: 100%;
4788
+ height: 100%;
4789
+ font-size: inherit !important;
4790
+ font-family: inherit !important;
4791
+ line-height: inherit !important;
4792
+ }
4793
+ nile-code-editor.st-cell-editor::part(code-editor-base) {
4794
+ border: none !important;
4795
+ min-height: 100% !important;
4796
+ background: transparent !important;
4797
+ font-size: inherit !important;
4798
+ font-family: inherit !important;
4799
+ line-height: inherit !important;
4800
+ }
4801
+ /* Ensure proper sizing within table cell */
4802
+ .st-nile-code-editor {
4803
+ width: 100%;
4804
+ height: 100%;
4805
+ min-height: 28px;
4806
+ font-size: inherit !important;
4807
+ }
4808
+ /* CodeMirror content should inherit font size */
4809
+ nile-code-editor.st-cell-editor .cm-content,
4810
+ nile-code-editor.st-cell-editor .cm-line {
4811
+ font-size: inherit !important;
4812
+ font-family: inherit !important;
4813
+ line-height: inherit !important;
4814
+ }
4815
+ /* Container wrapper for editor + expand button */
4816
+ .st-code-editor-wrapper {
4817
+ display: flex;
4818
+ align-items: center;
4819
+ width: 100%;
4820
+ height: 100%;
4821
+ gap: 4px;
4822
+ }
4823
+ .st-code-editor-wrapper .st-code-editor-input {
4824
+ flex: 1;
4825
+ min-width: 0;
4826
+ height: 100%;
4827
+ }
4828
+ .st-code-editor-wrapper .st-expand-button {
4829
+ display: flex;
4830
+ align-items: center;
4831
+ justify-content: center;
4832
+ width: 24px;
4833
+ height: 24px;
4834
+ min-width: 24px;
4835
+ padding: 0;
4836
+ border: none;
4837
+ background: transparent;
4838
+ cursor: pointer;
4839
+ color: var(--nile-color-neutral-500, #6b7280);
4840
+ border-radius: 4px;
4841
+ transition: all 0.2s;
4842
+ }
4843
+ .st-code-editor-wrapper .st-expand-button:hover {
4844
+ background: var(--nile-color-neutral-100, #f3f4f6);
4845
+ color: var(--nile-color-neutral-700, #374151);
4846
+ }
4847
+ /* Dialog code editor styling */
4848
+ .st-code-editor-dialog::part(panel) {
4849
+ max-height: var(--max-height, 80vh) !important;
4850
+ overflow: hidden !important;
4851
+ }
4852
+ .st-code-editor-dialog::part(body) {
4853
+ overflow: auto !important;
4854
+ }
4855
+ .st-code-editor-dialog nile-code-editor {
4856
+ width: 100%;
4857
+ display: block;
4858
+ }
4859
+ .st-code-editor-dialog nile-code-editor::part(code-editor-base) {
4860
+ border: 1px solid var(--nile-color-neutral-200, #e5e7eb) !important;
4861
+ border-radius: 4px !important;
4862
+ overflow: auto !important;
4863
+ min-height: var(--dialog-editor-min-height, 300px) !important;
4864
+ }
4865
+ .st-code-editor-dialog nile-code-editor .cm-editor {
4866
+ min-height: var(--dialog-editor-min-height, 300px) !important;
4867
+ }
4868
+ .st-code-editor-dialog nile-code-editor .cm-content {
4869
+ min-height: var(--dialog-editor-min-height, 300px) !important;
4870
+ }
4871
+ `;
4872
+ document.head.appendChild(style);
4873
+ }
4874
+ /**
4875
+ * Custom editor that uses NileCodeEditor component
4876
+ * Provides code editing with syntax highlighting for table cells
4877
+ * @template T The value type (typically string)
4878
+ */
4879
+ class NileCodeEditor {
4880
+ constructor(options) {
4881
+ this.options = options;
4882
+ this.eventListeners = [];
4883
+ this.dialogOpen = false;
4884
+ this.expandButtonClicked = false;
4885
+ this.trackedValue = null;
4886
+ }
4887
+ edit(context) {
4888
+ if (!context.container) {
4889
+ console.warn('NileCodeEditor requires a container element');
4890
+ return;
4891
+ }
4892
+ this.context = context;
4893
+ this.trackedValue = null;
4894
+ // Inject global styles once
4895
+ injectCodeEditorStyles();
4896
+ // Check if we should show expand button (default: true)
4897
+ const showExpandButton = this.options?.showExpandButton !== false;
4898
+ if (showExpandButton) {
4899
+ // Create wrapper for editor + expand button
4900
+ this.wrapper = document.createElement('div');
4901
+ this.wrapper.className = 'st-code-editor-wrapper';
4902
+ // Create the editor container
4903
+ const editorContainer = document.createElement('div');
4904
+ editorContainer.className = 'st-code-editor-input';
4905
+ // Create NileCodeEditor custom element
4906
+ this.editor = document.createElement('nile-code-editor');
4907
+ this.editor.value = String(context.value ?? '');
4908
+ this.editor.className = 'st-cell-editor st-nile-code-editor';
4909
+ this.editor.style.width = '100%';
4910
+ this.editor.style.height = '100%';
4911
+ this.editor.style.boxSizing = 'border-box';
4912
+ this.editor.noborder = this.options?.noborder !== false;
4913
+ editorContainer.appendChild(this.editor);
4914
+ this.wrapper.appendChild(editorContainer);
4915
+ // Create expand button
4916
+ this.expandButton = document.createElement('button');
4917
+ this.expandButton.className = 'st-expand-button';
4918
+ this.expandButton.type = 'button';
4919
+ this.expandButton.title = 'Expand editor';
4920
+ this.expandButton.innerHTML = '<nile-icon name="expand-06" size="16"></nile-icon>';
4921
+ // Use mousedown to set flag BEFORE blur event fires
4922
+ this.expandButton.addEventListener('mousedown', (e) => {
4923
+ e.preventDefault();
4924
+ e.stopPropagation();
4925
+ this.expandButtonClicked = true;
4926
+ });
4927
+ this.expandButton.addEventListener('click', (e) => {
4928
+ e.preventDefault();
4929
+ e.stopPropagation();
4930
+ this.openDialog();
4931
+ });
4932
+ this.wrapper.appendChild(this.expandButton);
4933
+ // Clear container and append wrapper
4934
+ context.container.innerHTML = '';
4935
+ context.container.appendChild(this.wrapper);
4936
+ }
4937
+ else {
4938
+ // Create NileCodeEditor custom element without wrapper
4939
+ this.editor = document.createElement('nile-code-editor');
4940
+ this.editor.value = String(context.value ?? '');
4941
+ this.editor.className = 'st-cell-editor st-nile-code-editor';
4942
+ this.editor.style.width = '100%';
4943
+ this.editor.style.height = '100%';
4944
+ this.editor.style.boxSizing = 'border-box';
4945
+ this.editor.noborder = this.options?.noborder !== false;
4946
+ // Clear container and append editor
4947
+ context.container.innerHTML = '';
4948
+ context.container.appendChild(this.editor);
4949
+ }
4950
+ // Apply all configuration options
4951
+ this.applyOptions();
4952
+ // Set up event listeners
4953
+ this.setupEventListeners(context);
4954
+ // Auto focus - need a slight delay for nile-code-editor to fully initialize
4955
+ if (this.options?.autoFocus !== false) {
4956
+ // Listen for the nile-after-init event which fires when editor is ready
4957
+ const initHandler = () => {
4958
+ this.editor?.removeEventListener('nile-after-init', initHandler);
4959
+ this.focusEditor();
4960
+ };
4961
+ this.editor.addEventListener('nile-after-init', initHandler);
4962
+ // Fallback: also try after a delay in case the event already fired
4963
+ setTimeout(() => {
4964
+ this.focusEditor();
4965
+ }, 100);
4966
+ }
4967
+ }
4968
+ /**
4969
+ * Focus the editor and place cursor
4970
+ */
4971
+ focusEditor() {
4972
+ if (!this.editor)
4973
+ return;
4974
+ try {
4975
+ // Call the component's focus method
4976
+ this.editor.focus();
4977
+ // Try to directly focus the CodeMirror content area
4978
+ const shadowRoot = this.editor.shadowRoot;
4979
+ if (shadowRoot) {
4980
+ const cmContent = shadowRoot.querySelector('.cm-content');
4981
+ if (cmContent) {
4982
+ cmContent.focus();
4983
+ // Dispatch a click event to ensure cursor placement
4984
+ cmContent.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
4985
+ cmContent.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
4986
+ }
4987
+ }
4988
+ }
4989
+ catch (e) {
4990
+ // Silently handle any errors
4991
+ }
4992
+ }
4993
+ /**
4994
+ * Open the full editor dialog
4995
+ */
4996
+ openDialog() {
4997
+ if (this.dialogOpen)
4998
+ return;
4999
+ this.dialogOpen = true;
5000
+ this.expandButtonClicked = false; // Reset flag now that dialog is opening
5001
+ // Create dialog with configurable dimensions
5002
+ const dialogWidth = this.options?.dialogWidth || '600px';
5003
+ const dialogMaxHeight = this.options?.dialogMaxHeight || '80vh';
5004
+ const dialogEditorHeight = this.options?.dialogEditorHeight || '300px';
5005
+ const dialogTitle = this.options?.dialogTitle || 'Edit Code';
5006
+ this.dialog = document.createElement('nile-dialog');
5007
+ this.dialog.className = 'st-code-editor-dialog';
5008
+ this.dialog.label = dialogTitle;
5009
+ this.dialog.style.setProperty('--width', dialogWidth);
5010
+ this.dialog.style.setProperty('--max-height', dialogMaxHeight);
5011
+ // Create dialog content
5012
+ const content = document.createElement('div');
5013
+ content.style.padding = '16px';
5014
+ content.style.maxHeight = `calc(${dialogMaxHeight} - 80px)`;
5015
+ content.style.overflow = 'auto';
5016
+ // Create full editor
5017
+ this.dialogEditor = document.createElement('nile-code-editor');
5018
+ const minLines = this.options?.dialogMinLines ?? 20;
5019
+ const currentValue = this.editor?.value || '';
5020
+ const currentLineCount = (currentValue.match(/\n/g) || []).length + 1;
5021
+ const paddingLines = Math.max(0, minLines - currentLineCount);
5022
+ this.dialogEditor.value = currentValue + '\n'.repeat(paddingLines);
5023
+ this.dialogEditor.multiline = true;
5024
+ this.dialogEditor.lineNumbersMultiline = true;
5025
+ this.dialogEditor.hasScroller = true;
5026
+ const lineHeightPx = 20;
5027
+ const minHeightFromLines = `${minLines * lineHeightPx}px`;
5028
+ this.dialogEditor.style.minHeight = `max(${dialogEditorHeight}, ${minHeightFromLines})`;
5029
+ this.dialogEditor.style.maxHeight = `calc(${dialogMaxHeight} - 120px)`;
5030
+ content.style.setProperty('--dialog-editor-min-height', `max(${dialogEditorHeight}, ${minHeightFromLines})`);
5031
+ // Apply same options to dialog editor
5032
+ if (this.options?.language) {
5033
+ this.dialogEditor.language = this.options.language;
5034
+ }
5035
+ if (this.options?.placeholder) {
5036
+ this.dialogEditor.placeholder = this.options.placeholder;
5037
+ }
5038
+ if (this.options?.tabCompletion !== undefined) {
5039
+ this.dialogEditor.tabCompletion = this.options.tabCompletion;
5040
+ }
5041
+ if (this.options?.enableSearch !== undefined) {
5042
+ this.dialogEditor.enableSearch = this.options.enableSearch;
5043
+ }
5044
+ if (this.options?.enableFoldGutters !== undefined) {
5045
+ this.dialogEditor.enableFoldGutters = this.options.enableFoldGutters;
5046
+ }
5047
+ if (this.options?.customAutoCompletions) {
5048
+ this.dialogEditor.customAutoCompletions = this.options.customAutoCompletions;
5049
+ }
5050
+ if (this.options?.customCompletionsPaths) {
5051
+ this.dialogEditor.customCompletionsPaths = this.options.customCompletionsPaths;
5052
+ }
5053
+ if (this.options?.customThemeCSS) {
5054
+ this.dialogEditor.customThemeCSS = this.options.customThemeCSS;
5055
+ }
5056
+ this.dialogEditor.expandable = false;
5057
+ // Real-time sync: Update cell editor whenever dialog editor changes
5058
+ this.dialogEditor.addEventListener('nile-change', (e) => {
5059
+ const dialogValue = e.detail?.value || '';
5060
+ this.trackedValue = dialogValue;
5061
+ if (this.editor) {
5062
+ this.editor.value = dialogValue;
5063
+ }
5064
+ if (this.context) {
5065
+ this.context.onChange(dialogValue);
5066
+ }
5067
+ });
5068
+ content.appendChild(this.dialogEditor);
5069
+ this.dialog.appendChild(content);
5070
+ // Handle dialog close events (clicking X button - stay in edit mode)
5071
+ this.dialog.addEventListener('nile-request-close', (e) => {
5072
+ const customEvent = e;
5073
+ // Check if close was triggered by overlay click (clicking outside)
5074
+ if (customEvent.detail?.source === 'overlay') {
5075
+ // Clicking outside the dialog - save and exit edit mode
5076
+ this.closeDialog(true);
5077
+ }
5078
+ else {
5079
+ // Clicking X button - stay in edit mode
5080
+ this.closeDialog(false);
5081
+ }
5082
+ });
5083
+ // Handle Escape key in dialog - stay in edit mode
5084
+ this.dialog.addEventListener('keydown', (e) => {
5085
+ if (e.key === 'Escape') {
5086
+ e.preventDefault();
5087
+ e.stopPropagation();
5088
+ this.closeDialog(false);
5089
+ }
5090
+ });
5091
+ // Append to body and show
5092
+ document.body.appendChild(this.dialog);
5093
+ // Open dialog after a tick to ensure it's in the DOM
5094
+ setTimeout(() => {
5095
+ if (this.dialog) {
5096
+ this.dialog.open = true;
5097
+ // Focus the dialog editor
5098
+ setTimeout(() => {
5099
+ this.dialogEditor?.focus();
5100
+ }, 100);
5101
+ }
5102
+ }, 0);
5103
+ }
5104
+ /**
5105
+ * Close the dialog and optionally save/exit edit mode
5106
+ */
5107
+ closeDialog(saveAndExit = false) {
5108
+ if (!this.dialogOpen)
5109
+ return;
5110
+ // Reset flag immediately so document click handler works
5111
+ this.dialogOpen = false;
5112
+ // Close and remove dialog
5113
+ if (this.dialog) {
5114
+ this.dialog.open = false;
5115
+ const dialogRef = this.dialog;
5116
+ const dialogEditorRef = this.dialogEditor;
5117
+ this.dialog = undefined;
5118
+ this.dialogEditor = undefined;
5119
+ // Remove from DOM after animation
5120
+ setTimeout(() => {
5121
+ dialogRef?.remove();
5122
+ }, 200);
5123
+ if (saveAndExit && this.context) {
5124
+ // Save and exit edit mode
5125
+ this.context.onSave(this.getCurrentValue());
5126
+ }
5127
+ else {
5128
+ // Refocus the cell editor to stay in edit mode
5129
+ setTimeout(() => {
5130
+ this.focusEditor();
5131
+ }, 50);
5132
+ }
5133
+ }
5134
+ }
5135
+ /**
5136
+ * Apply all configuration options to the NileCodeEditor element
5137
+ */
5138
+ applyOptions() {
5139
+ if (!this.editor)
5140
+ return;
5141
+ // Language and syntax
5142
+ if (this.options?.language) {
5143
+ this.editor.language = this.options.language;
5144
+ }
5145
+ if (this.options?.disableSyntaxHighlighting) {
5146
+ this.editor.disableSyntaxHighlighting = this.options.disableSyntaxHighlighting;
5147
+ }
5148
+ // Editor appearance
5149
+ if (this.options?.placeholder) {
5150
+ this.editor.placeholder = this.options.placeholder;
5151
+ }
5152
+ if (this.options?.lineNumbers !== undefined) {
5153
+ this.editor.lineNumbers = this.options.lineNumbers;
5154
+ }
5155
+ if (this.options?.lineNumbersMultiline !== undefined) {
5156
+ this.editor.lineNumbersMultiline = this.options.lineNumbersMultiline;
5157
+ }
5158
+ if (this.options?.multiline !== undefined) {
5159
+ this.editor.multiline = this.options.multiline;
5160
+ }
5161
+ if (this.options?.defaultFont !== undefined) {
5162
+ this.editor.defaultFont = this.options.defaultFont;
5163
+ }
5164
+ // Editor behavior
5165
+ if (this.options?.readonly !== undefined) {
5166
+ this.editor.readonly = this.options.readonly;
5167
+ }
5168
+ if (this.options?.disabled !== undefined) {
5169
+ this.editor.disabled = this.options.disabled;
5170
+ }
5171
+ if (this.options?.tabCompletion !== undefined) {
5172
+ this.editor.tabCompletion = this.options.tabCompletion;
5173
+ }
5174
+ if (this.options?.enableSearch !== undefined) {
5175
+ this.editor.enableSearch = this.options.enableSearch;
5176
+ }
5177
+ if (this.options?.enableFoldGutters !== undefined) {
5178
+ this.editor.enableFoldGutters = this.options.enableFoldGutters;
5179
+ }
5180
+ if (this.options?.hasScroller !== undefined) {
5181
+ this.editor.hasScroller = this.options.hasScroller;
5182
+ }
5183
+ // Expandable - default to false for cell editing
5184
+ this.editor.expandable = this.options?.expandable ?? false;
5185
+ if (this.options?.expandIcon) {
5186
+ this.editor.expandIcon = this.options.expandIcon;
5187
+ }
5188
+ // Autocompletion
5189
+ if (this.options?.customAutoCompletions) {
5190
+ this.editor.customAutoCompletions = this.options.customAutoCompletions;
5191
+ }
5192
+ if (this.options?.customCompletionsPaths) {
5193
+ this.editor.customCompletionsPaths = this.options.customCompletionsPaths;
5194
+ }
5195
+ if (this.options?.allowVariableInCustomSuggestion !== undefined) {
5196
+ this.editor.allowVariableInCustomSuggestion = this.options.allowVariableInCustomSuggestion;
5197
+ }
5198
+ if (this.options?.aboveCursor !== undefined) {
5199
+ this.editor.aboveCursor = this.options.aboveCursor;
5200
+ }
5201
+ if (this.options?.autoCompleteStyle) {
5202
+ this.editor.autoCompleteStyle = this.options.autoCompleteStyle;
5203
+ }
5204
+ // Change handling
5205
+ if (this.options?.debounce !== undefined) {
5206
+ this.editor.debounce = this.options.debounce;
5207
+ }
5208
+ if (this.options?.debounceTimeout !== undefined) {
5209
+ this.editor.debounceTimeout = this.options.debounceTimeout;
5210
+ }
5211
+ // Visual states
5212
+ if (this.options?.error !== undefined) {
5213
+ this.editor.error = this.options.error;
5214
+ }
5215
+ if (this.options?.errorMessage) {
5216
+ this.editor.errorMessage = this.options.errorMessage;
5217
+ }
5218
+ // Custom theme
5219
+ if (this.options?.customThemeCSS) {
5220
+ this.editor.customThemeCSS = this.options.customThemeCSS;
5221
+ }
5222
+ }
5223
+ /**
5224
+ * Set up all event listeners with proper cleanup tracking
5225
+ */
5226
+ setupEventListeners(context) {
5227
+ if (!this.editor)
5228
+ return;
5229
+ const validateOnSave = this.options?.validateOnSave !== false;
5230
+ // Handle keyboard events
5231
+ const keydownHandler = (e) => {
5232
+ const keyEvent = e;
5233
+ // For single-line mode, Enter saves
5234
+ if (!this.options?.multiline && keyEvent.key === 'Enter') {
5235
+ keyEvent.preventDefault();
5236
+ keyEvent.stopPropagation();
5237
+ this.saveValue(context, validateOnSave);
5238
+ }
5239
+ // Escape cancels
5240
+ if (keyEvent.key === 'Escape') {
5241
+ keyEvent.preventDefault();
5242
+ keyEvent.stopPropagation();
5243
+ context.onCancel();
5244
+ }
5245
+ };
5246
+ this.editor.addEventListener('keydown', keydownHandler);
5247
+ this.eventListeners.push({ event: 'keydown', handler: keydownHandler });
5248
+ // Use nile-blur event for saving on blur
5249
+ const blurHandler = () => {
5250
+ // Don't save if dialog is open
5251
+ if (this.dialogOpen) {
5252
+ return;
5253
+ }
5254
+ // Don't save if expand button was clicked (mousedown sets this flag)
5255
+ if (this.expandButtonClicked) {
5256
+ // Reset flag - the click handler will open the dialog
5257
+ this.expandButtonClicked = false;
5258
+ return;
5259
+ }
5260
+ // Save and exit edit mode
5261
+ this.saveValue(context, validateOnSave);
5262
+ };
5263
+ this.editor.addEventListener('nile-blur', blurHandler);
5264
+ this.eventListeners.push({ event: 'nile-blur', handler: blurHandler });
5265
+ // Document-level mousedown handler to detect clicks outside the editor
5266
+ this.documentClickHandler = (e) => {
5267
+ // Don't process if dialog is open or expand button was clicked
5268
+ if (this.dialogOpen || this.expandButtonClicked) {
5269
+ return;
5270
+ }
5271
+ // Use composedPath to handle Shadow DOM boundaries
5272
+ const path = e.composedPath();
5273
+ // Check if any element in the path is our wrapper, editor, or expand button
5274
+ for (const element of path) {
5275
+ if (element === this.wrapper || element === this.editor || element === this.expandButton) {
5276
+ return;
5277
+ }
5278
+ // Also check if it's the container (the cell)
5279
+ if (element === context.container) {
5280
+ return;
5281
+ }
5282
+ }
5283
+ // Click is outside - save and exit
5284
+ this.saveValue(context, validateOnSave);
5285
+ };
5286
+ // Add with a small delay to avoid capturing the initial click that opened the editor
5287
+ setTimeout(() => {
5288
+ document.addEventListener('mousedown', this.documentClickHandler, true);
5289
+ }, 50);
5290
+ // Real-time value updates using nile-change
5291
+ const changeHandler = (e) => {
5292
+ const customEvent = e;
5293
+ const newValue = customEvent.detail?.value ?? '';
5294
+ this.trackedValue = newValue;
5295
+ context.onChange(newValue);
5296
+ };
5297
+ this.editor.addEventListener('nile-change', changeHandler);
5298
+ this.eventListeners.push({ event: 'nile-change', handler: changeHandler });
5299
+ // Handle expand event if expandable
5300
+ if (this.options?.expandable) {
5301
+ const expandHandler = () => {
5302
+ // Emit a custom event that the parent can listen to
5303
+ const expandEvent = new CustomEvent('st-code-editor-expand', {
5304
+ bubbles: true,
5305
+ detail: { value: this.getCurrentValue() }
5306
+ });
5307
+ this.editor?.dispatchEvent(expandEvent);
5308
+ };
5309
+ this.editor.addEventListener('nile-expand', expandHandler);
5310
+ this.eventListeners.push({ event: 'nile-expand', handler: expandHandler });
5311
+ }
5312
+ }
5313
+ /**
5314
+ * Save value with optional validation
5315
+ */
5316
+ saveValue(context, validate) {
5317
+ if (!this.editor)
5318
+ return;
5319
+ // Code editor doesn't have built-in validation like input
5320
+ // But we can check for error state
5321
+ if (validate && this.options?.error) {
5322
+ return;
5323
+ }
5324
+ const value = this.getCurrentValue();
5325
+ context.onSave(value);
5326
+ }
5327
+ destroy() {
5328
+ // Remove document click handler
5329
+ if (this.documentClickHandler) {
5330
+ document.removeEventListener('mousedown', this.documentClickHandler, true);
5331
+ this.documentClickHandler = undefined;
5332
+ }
5333
+ // Close dialog if open
5334
+ if (this.dialogOpen && this.dialog) {
5335
+ this.dialog.open = false;
5336
+ this.dialog.remove();
5337
+ this.dialog = undefined;
5338
+ this.dialogEditor = undefined;
5339
+ this.dialogOpen = false;
5340
+ }
5341
+ // Remove all event listeners
5342
+ if (this.editor) {
5343
+ this.eventListeners.forEach(({ event, handler }) => {
5344
+ this.editor?.removeEventListener(event, handler);
5345
+ });
5346
+ this.eventListeners = [];
5347
+ this.editor.remove();
5348
+ this.editor = undefined;
5349
+ }
5350
+ // Remove wrapper if exists
5351
+ if (this.wrapper) {
5352
+ this.wrapper.remove();
5353
+ this.wrapper = undefined;
5354
+ }
5355
+ // Clear expand button reference
5356
+ this.expandButton = undefined;
5357
+ this.context = undefined;
5358
+ this.expandButtonClicked = false;
5359
+ }
5360
+ focus() {
5361
+ this.editor?.focus();
5362
+ }
5363
+ getCurrentValue() {
5364
+ if (!this.editor)
5365
+ return '';
5366
+ const value = (this.trackedValue !== null ? this.trackedValue : this.editor.value ?? '');
5367
+ return value.replace(/\n+$/, '');
5368
+ }
5369
+ /**
5370
+ * Set value programmatically
5371
+ */
5372
+ setValue(value) {
5373
+ if (this.editor) {
5374
+ this.editor.value = String(value ?? '');
5375
+ }
5376
+ }
5377
+ /**
5378
+ * Get the CodeMirror instance (if needed for advanced usage)
5379
+ */
5380
+ getEditorInstance() {
5381
+ return this.editor;
5382
+ }
5383
+ }
5384
+
4725
5385
  /**
4726
5386
  * Custom cell editors for ngx-smart-table
4727
5387
  */
@@ -4951,15 +5611,28 @@ class ColumnConfigFactory {
4951
5611
  const Columns = ColumnConfigFactory;
4952
5612
 
4953
5613
  class StCellComponent {
4954
- constructor() {
5614
+ constructor(cdr) {
5615
+ this.cdr = cdr;
4955
5616
  this.editMode = EditMode.CLICK;
4956
5617
  this.cellChange = new EventEmitter();
4957
5618
  this.cellEdit = new EventEmitter();
4958
5619
  this.cellSave = new EventEmitter();
4959
5620
  this.cellCancel = new EventEmitter();
4960
5621
  this.cellSaveAndNavigate = new EventEmitter();
5622
+ this.cellLoading = false;
4961
5623
  }
4962
5624
  ngOnInit() {
5625
+ this.cell.onStateChange(() => {
5626
+ this.cellLoading = !!this.cell.getState().isLoading;
5627
+ try {
5628
+ this.cdr.detectChanges();
5629
+ }
5630
+ catch {
5631
+ // View may have been destroyed; safely ignore
5632
+ }
5633
+ });
5634
+ // Pick up loading state that was set before this component was created
5635
+ this.cellLoading = !!this.cell.getState().isLoading;
4963
5636
  // Subscribe to editing position changes
4964
5637
  // When another cell starts editing, save this cell if it's currently editing
4965
5638
  if (this.tableState && this.columnIndex !== undefined) {
@@ -5310,12 +5983,12 @@ class StCellComponent {
5310
5983
  }
5311
5984
  }
5312
5985
  }
5313
- StCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5314
- StCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StCellComponent, selector: "st-cell", inputs: { cell: "cell", editMode: "editMode", tableState: "tableState", tableConfig: "tableConfig", columnIndex: "columnIndex" }, outputs: { cellChange: "cellChange", cellEdit: "cellEdit", cellSave: "cellSave", cellCancel: "cellCancel", cellSaveAndNavigate: "cellSaveAndNavigate" }, host: { listeners: { "keydown": "onCellKeyDown($event)" } }, viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"st-cell\" \n [ngClass]=\"{\n 'editing': cell.isEditing(),\n 'dirty': cell.isDirty(),\n 'invalid': !cell.isValid(),\n 'readonly': !isEditable\n }\"\n (click)=\"onCellClick()\" \n (dblclick)=\"onCellDoubleClick()\">\n\n <!-- Display Mode with Template Support -->\n <ng-container *ngIf=\"!cell.isEditing()\">\n <!-- Custom Template -->\n <ng-container *ngIf=\"hasCellTemplate\">\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: templateContext\"></ng-container>\n </ng-container>\n\n <!-- Default Text Rendering -->\n <span *ngIf=\"!hasCellTemplate\" class=\"cell-display\">\n {{ cell.render() }}\n </span>\n </ng-container>\n\n <!-- Edit Mode -->\n <div *ngIf=\"cell.isEditing()\" class=\"cell-editor\" #editorContainer>\n </div>\n</div>", styles: [".st-cell{position:relative;cursor:pointer;transition:background-color .2s;min-height:28px;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box}.st-cell.invalid{border-left:2px solid #e53e3e}.st-cell.readonly{cursor:default}.cell-display{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-content:center;width:100%;height:100%;padding-left:8px;padding-right:8px;font-size:12px;font-weight:300;letter-spacing:.2px;line-height:14px}.cell-editor{display:flex;height:100%;width:100%}.cell-editor input,.cell-editor select,.cell-editor textarea{width:100%;border:none;outline:none;font:inherit;padding:0;background:transparent;color:inherit}.cell-editor input[type=number]{text-align:inherit}.cell-editor nile-select::part(combobox){border:none!important;outline:none!important;box-shadow:none!important}.cell-editor nile-select::part(tag){border:none!important;outline:none!important}.cell-editor nile-select::part(listbox){border:none!important}.cell-error{position:absolute;right:4px;top:50%;transform:translateY(-50%);color:#e53e3e;font-weight:700;cursor:help;font-size:14px}\n"], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
5986
+ StCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
5987
+ StCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StCellComponent, selector: "st-cell", inputs: { cell: "cell", editMode: "editMode", tableState: "tableState", tableConfig: "tableConfig", columnIndex: "columnIndex" }, outputs: { cellChange: "cellChange", cellEdit: "cellEdit", cellSave: "cellSave", cellCancel: "cellCancel", cellSaveAndNavigate: "cellSaveAndNavigate" }, host: { listeners: { "keydown": "onCellKeyDown($event)" } }, viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"st-cell\" \n [ngClass]=\"{\n 'editing': cell.isEditing(),\n 'dirty': cell.isDirty(),\n 'invalid': !cell.isValid(),\n 'readonly': !isEditable,\n 'loading': cellLoading\n }\"\n (click)=\"onCellClick()\" \n (dblclick)=\"onCellDoubleClick()\">\n\n <!-- Loading Indicator -->\n <div *ngIf=\"cellLoading\" class=\"cell-loading\">\n <div class=\"cell-spinner\"></div>\n </div>\n\n <!-- Display Mode with Template Support -->\n <ng-container *ngIf=\"!cell.isEditing() && !cellLoading\">\n <!-- Custom Template -->\n <ng-container *ngIf=\"hasCellTemplate\">\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: templateContext\"></ng-container>\n </ng-container>\n\n <!-- Default Text Rendering -->\n <span *ngIf=\"!hasCellTemplate\" class=\"cell-display\">\n {{ cell.render() }}\n </span>\n </ng-container>\n\n <!-- Edit Mode -->\n <div *ngIf=\"cell.isEditing()\" class=\"cell-editor\" #editorContainer>\n </div>\n</div>", styles: [".st-cell{position:relative;cursor:pointer;transition:background-color .2s;min-height:28px;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box;max-height:28px}.st-cell.invalid{border-left:2px solid #e53e3e}.st-cell.readonly{cursor:default}.cell-display{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-content:center;width:100%;height:100%;padding-left:8px;padding-right:8px;font-size:12px;font-weight:300;letter-spacing:.2px;line-height:14px}.cell-editor{display:flex;height:100%;width:100%}.cell-editor input,.cell-editor select,.cell-editor textarea{width:100%;border:none;outline:none;font:inherit;padding:0;background:transparent;color:inherit}.cell-editor input[type=number]{text-align:inherit}.cell-editor nile-select::part(combobox){border:none!important;outline:none!important;box-shadow:none!important;max-height:28px;overflow:hidden;flex-wrap:nowrap}.cell-editor nile-select::part(tag){border:none!important;outline:none!important;margin-right:2px;padding:1px 2px;flex-shrink:0}.cell-editor nile-select::part(listbox){border:none!important}.st-cell.loading{pointer-events:none;opacity:.6}.cell-loading{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.cell-spinner{width:14px;height:14px;border:2px solid #e2e8f0;border-top-color:#4a90d9;border-radius:50%;animation:cell-spin .6s linear infinite}@keyframes cell-spin{to{transform:rotate(360deg)}}.cell-error{position:absolute;right:4px;top:50%;transform:translateY(-50%);color:#e53e3e;font-weight:700;cursor:help;font-size:14px}\n"], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
5315
5988
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, decorators: [{
5316
5989
  type: Component,
5317
- args: [{ selector: 'st-cell', template: "<div class=\"st-cell\" \n [ngClass]=\"{\n 'editing': cell.isEditing(),\n 'dirty': cell.isDirty(),\n 'invalid': !cell.isValid(),\n 'readonly': !isEditable\n }\"\n (click)=\"onCellClick()\" \n (dblclick)=\"onCellDoubleClick()\">\n\n <!-- Display Mode with Template Support -->\n <ng-container *ngIf=\"!cell.isEditing()\">\n <!-- Custom Template -->\n <ng-container *ngIf=\"hasCellTemplate\">\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: templateContext\"></ng-container>\n </ng-container>\n\n <!-- Default Text Rendering -->\n <span *ngIf=\"!hasCellTemplate\" class=\"cell-display\">\n {{ cell.render() }}\n </span>\n </ng-container>\n\n <!-- Edit Mode -->\n <div *ngIf=\"cell.isEditing()\" class=\"cell-editor\" #editorContainer>\n </div>\n</div>", styles: [".st-cell{position:relative;cursor:pointer;transition:background-color .2s;min-height:28px;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box}.st-cell.invalid{border-left:2px solid #e53e3e}.st-cell.readonly{cursor:default}.cell-display{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-content:center;width:100%;height:100%;padding-left:8px;padding-right:8px;font-size:12px;font-weight:300;letter-spacing:.2px;line-height:14px}.cell-editor{display:flex;height:100%;width:100%}.cell-editor input,.cell-editor select,.cell-editor textarea{width:100%;border:none;outline:none;font:inherit;padding:0;background:transparent;color:inherit}.cell-editor input[type=number]{text-align:inherit}.cell-editor nile-select::part(combobox){border:none!important;outline:none!important;box-shadow:none!important}.cell-editor nile-select::part(tag){border:none!important;outline:none!important}.cell-editor nile-select::part(listbox){border:none!important}.cell-error{position:absolute;right:4px;top:50%;transform:translateY(-50%);color:#e53e3e;font-weight:700;cursor:help;font-size:14px}\n"] }]
5318
- }], ctorParameters: function () { return []; }, propDecorators: { cell: [{
5990
+ args: [{ selector: 'st-cell', template: "<div class=\"st-cell\" \n [ngClass]=\"{\n 'editing': cell.isEditing(),\n 'dirty': cell.isDirty(),\n 'invalid': !cell.isValid(),\n 'readonly': !isEditable,\n 'loading': cellLoading\n }\"\n (click)=\"onCellClick()\" \n (dblclick)=\"onCellDoubleClick()\">\n\n <!-- Loading Indicator -->\n <div *ngIf=\"cellLoading\" class=\"cell-loading\">\n <div class=\"cell-spinner\"></div>\n </div>\n\n <!-- Display Mode with Template Support -->\n <ng-container *ngIf=\"!cell.isEditing() && !cellLoading\">\n <!-- Custom Template -->\n <ng-container *ngIf=\"hasCellTemplate\">\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: templateContext\"></ng-container>\n </ng-container>\n\n <!-- Default Text Rendering -->\n <span *ngIf=\"!hasCellTemplate\" class=\"cell-display\">\n {{ cell.render() }}\n </span>\n </ng-container>\n\n <!-- Edit Mode -->\n <div *ngIf=\"cell.isEditing()\" class=\"cell-editor\" #editorContainer>\n </div>\n</div>", styles: [".st-cell{position:relative;cursor:pointer;transition:background-color .2s;min-height:28px;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box;max-height:28px}.st-cell.invalid{border-left:2px solid #e53e3e}.st-cell.readonly{cursor:default}.cell-display{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-content:center;width:100%;height:100%;padding-left:8px;padding-right:8px;font-size:12px;font-weight:300;letter-spacing:.2px;line-height:14px}.cell-editor{display:flex;height:100%;width:100%}.cell-editor input,.cell-editor select,.cell-editor textarea{width:100%;border:none;outline:none;font:inherit;padding:0;background:transparent;color:inherit}.cell-editor input[type=number]{text-align:inherit}.cell-editor nile-select::part(combobox){border:none!important;outline:none!important;box-shadow:none!important;max-height:28px;overflow:hidden;flex-wrap:nowrap}.cell-editor nile-select::part(tag){border:none!important;outline:none!important;margin-right:2px;padding:1px 2px;flex-shrink:0}.cell-editor nile-select::part(listbox){border:none!important}.st-cell.loading{pointer-events:none;opacity:.6}.cell-loading{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.cell-spinner{width:14px;height:14px;border:2px solid #e2e8f0;border-top-color:#4a90d9;border-radius:50%;animation:cell-spin .6s linear infinite}@keyframes cell-spin{to{transform:rotate(360deg)}}.cell-error{position:absolute;right:4px;top:50%;transform:translateY(-50%);color:#e53e3e;font-weight:700;cursor:help;font-size:14px}\n"] }]
5991
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { cell: [{
5319
5992
  type: Input
5320
5993
  }], editMode: [{
5321
5994
  type: Input
@@ -7989,7 +8662,20 @@ class StTableComponent {
7989
8662
  if (!this.data)
7990
8663
  return;
7991
8664
  const columns = this.getActiveColumns();
7992
- this.internalCellGrid = this.data.map((rowData, rowIndex) => columns.map(column => new Cell(column, rowData[column.key], rowData, rowIndex)));
8665
+ const oldGrid = this.internalCellGrid;
8666
+ this.internalCellGrid = this.data.map((rowData, rowIndex) => columns.map((column, colIndex) => {
8667
+ const newCell = new Cell(column, rowData[column.key], rowData, rowIndex);
8668
+ const oldCell = oldGrid?.[rowIndex]?.[colIndex];
8669
+ if (oldCell && oldCell.getColumnConfig().key === column.key) {
8670
+ oldCell.setReplacement(newCell);
8671
+ // Carry over transient state (e.g. loading) that was set on the old cell
8672
+ const oldState = oldCell.getState();
8673
+ if (oldState.isLoading) {
8674
+ newCell.setLoading(true);
8675
+ }
8676
+ }
8677
+ return newCell;
8678
+ }));
7993
8679
  }
7994
8680
  /**
7995
8681
  * Setup data source - either sync array or async Observable
@@ -12375,5 +13061,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
12375
13061
  * Generated bundle index. Do not edit.
12376
13062
  */
12377
13063
 
12378
- export { ArrayFormatter, AutosaveService, BaseColumnConfig, BooleanEditor, BooleanFormatter, BuilderPreviewComponent, BuilderToolbarComponent, Cell, CellAlignment, CellDataType, CellLifecycleState, CellVerticalAlignment, ChainValidator, ClickOutsideDirective, ColumnConfigFactory, ColumnEditorComponent, ColumnListComponent, Columns, CurrencyFormatter, DEFAULT_AUTOSAVE_CONFIG, DEFAULT_COLUMN_CONFIG, DEFAULT_TABLE_CONFIG, DateEditor, DateFormatter, DateRangeValidator, DefaultFormatter, DefinitionBuilderComponent, DefinitionBuilderModule, DefinitionBuilderService, DefinitionExportService, DefinitionImportService, EditMode, EmailValidator, FilterOperator, FunctionFormatter, FunctionValidator, JsonSchemaValidatorService, LengthValidator, NavigationDirection, NavigationKey, NileAutoCompleteEditor, NileCalendarEditor, NileDatePickerEditor, NileInputEditor, NileSelectEditor, NumberEditor, NumberFormatter, PatternValidators, PercentageFormatter, RangeValidator, RegexValidator, RequiredValidator, RowValidationService, SampleDataGeneratorService, SelectEditor, SharedTableComponentsModule, SheetState, SimpleColumnConfig, SmartTableModule, SortDirection, StAddColumnButtonComponent, StCellComponent, StColumnEditorModalComponent, StColumnFilterComponent, StColumnMenuDropdownComponent, StColumnResizeDirective, StColumnVisibilityComponent, StHeaderComponent, StKeyboardNavigationDirective, StPaginationComponent, StRowActionsDropdownComponent, StSheetActionsComponent, StSheetComponent, StTableActionsComponent, StTableComponent, StWorkbookComponent, StringFormatter, TableConfigEditorComponent, TableState, TableZIndex, TemplateFormatter, TextAreaEditor, TextEditor, UrlValidator, ValidationLoggerService, VirtualScrollService, WorkbookState, canEdit, createCellState, createMemento, isCellValid, isDisplayMode, isNullOrUndefined, isValidDate, isValidationSuccess, mergeTableConfig, restoreFromMemento };
13064
+ export { ArrayFormatter, AutosaveService, BaseColumnConfig, BooleanEditor, BooleanFormatter, BuilderPreviewComponent, BuilderToolbarComponent, Cell, CellAlignment, CellDataType, CellLifecycleState, CellVerticalAlignment, ChainValidator, ClickOutsideDirective, ColumnConfigFactory, ColumnEditorComponent, ColumnListComponent, Columns, CurrencyFormatter, DEFAULT_AUTOSAVE_CONFIG, DEFAULT_COLUMN_CONFIG, DEFAULT_TABLE_CONFIG, DateEditor, DateFormatter, DateRangeValidator, DefaultFormatter, DefinitionBuilderComponent, DefinitionBuilderModule, DefinitionBuilderService, DefinitionExportService, DefinitionImportService, EditMode, EmailValidator, FilterOperator, FunctionFormatter, FunctionValidator, JsonSchemaValidatorService, LengthValidator, NavigationDirection, NavigationKey, NileAutoCompleteEditor, NileCalendarEditor, NileCodeEditor, NileDatePickerEditor, NileInputEditor, NileSelectEditor, NumberEditor, NumberFormatter, PatternValidators, PercentageFormatter, RangeValidator, RegexValidator, RequiredValidator, RowValidationService, SampleDataGeneratorService, SelectEditor, SharedTableComponentsModule, SheetState, SimpleColumnConfig, SmartTableModule, SortDirection, StAddColumnButtonComponent, StCellComponent, StColumnEditorModalComponent, StColumnFilterComponent, StColumnMenuDropdownComponent, StColumnResizeDirective, StColumnVisibilityComponent, StHeaderComponent, StKeyboardNavigationDirective, StPaginationComponent, StRowActionsDropdownComponent, StSheetActionsComponent, StSheetComponent, StTableActionsComponent, StTableComponent, StWorkbookComponent, StringFormatter, TableConfigEditorComponent, TableState, TableZIndex, TemplateFormatter, TextAreaEditor, TextEditor, UrlValidator, ValidationLoggerService, VirtualScrollService, WorkbookState, canEdit, createCellState, createMemento, isCellValid, isDisplayMode, isNullOrUndefined, isValidDate, isValidationSuccess, mergeTableConfig, restoreFromMemento };
12379
13065
  //# sourceMappingURL=aquera-ngx-smart-table.mjs.map