@aquera/ngx-smart-table 0.0.17-patch-0.1 → 0.0.17-patch-0.3

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.
@@ -2502,10 +2502,39 @@ class Cell {
2502
2502
  return this.rowIndex;
2503
2503
  }
2504
2504
  /**
2505
- * Set loading state
2505
+ * Link this cell to its replacement so future state mutations forward.
2506
+ */
2507
+ setReplacement(replacement) {
2508
+ this.replacementCell = replacement;
2509
+ }
2510
+ onStateChange(callback) {
2511
+ this.stateChangeCallback = callback;
2512
+ }
2513
+ /**
2514
+ * Set loading state. Forwards to replacement cell if this cell was replaced.
2506
2515
  */
2507
2516
  setLoading(isLoading) {
2517
+ var _a;
2518
+ if (this.replacementCell) {
2519
+ this.replacementCell.setLoading(isLoading);
2520
+ return;
2521
+ }
2508
2522
  this.state.isLoading = isLoading;
2523
+ try {
2524
+ (_a = this.stateChangeCallback) === null || _a === void 0 ? void 0 : _a.call(this);
2525
+ }
2526
+ catch (_b) {
2527
+ this.stateChangeCallback = undefined;
2528
+ }
2529
+ }
2530
+ /**
2531
+ * Set cell value (public API, forwards to replacement if replaced).
2532
+ */
2533
+ setValueExternal(value) {
2534
+ if (this.replacementCell) {
2535
+ return this.replacementCell.setValueExternal(value);
2536
+ }
2537
+ return this.setValue(value, true);
2509
2538
  }
2510
2539
  /**
2511
2540
  * Set disabled state
@@ -3570,17 +3599,28 @@ function injectDropdownStyles() {
3570
3599
  }
3571
3600
  /* Combobox styling using ::part() selector */
3572
3601
  nile-select.st-cell-editor::part(combobox) {
3573
- background-color: var(--nile-colors-white-base, var(--ng-colors-bg-primary)) !important;
3602
+ background-color: transparent !important;
3574
3603
  border: solid 1px transparent !important;
3575
- margin: 1px 4px !important;
3604
+ margin: 0px !important;
3605
+ max-height: 28px;
3576
3606
  }
3577
3607
  nile-select.st-cell-editor::part(combobox):hover {
3578
3608
  border: solid 1px transparent !important;
3579
3609
  }
3580
3610
  .st-cell-editor::part(combobox) {
3581
- background-color: var(--nile-colors-white-base, var(--ng-colors-bg-primary)) !important;
3611
+ background-color: transparent !important;
3582
3612
  border: solid 1px transparent !important;
3583
- margin: 1px 4px !important;
3613
+ margin: 0px !important;
3614
+ max-height: 28px;
3615
+ }
3616
+ /* Tag spacing */
3617
+ nile-select.st-cell-editor::part(tag) {
3618
+ margin-right: 0px;
3619
+ padding: 1px 2px;
3620
+ }
3621
+ .st-cell-editor::part(tag) {
3622
+ margin-right: 0px;
3623
+ padding: 1px 2px;
3584
3624
  }
3585
3625
  /* Search input full width */
3586
3626
  .nile-select-portal-append .select__search {
@@ -4673,6 +4713,663 @@ class NileDatePickerEditor {
4673
4713
  }
4674
4714
  }
4675
4715
 
4716
+ /**
4717
+ * Custom editor using NileCodeEditor from @aquera/nile-elements
4718
+ * This provides code editing capabilities with syntax highlighting for table cells
4719
+ */
4720
+ /**
4721
+ * Inject global styles for nile-code-editor in table cells
4722
+ */
4723
+ let codeEditorStylesInjected = false;
4724
+ function injectCodeEditorStyles() {
4725
+ if (codeEditorStylesInjected)
4726
+ return;
4727
+ codeEditorStylesInjected = true;
4728
+ const styleId = 'nile-code-editor-cell-styles';
4729
+ if (document.getElementById(styleId))
4730
+ return;
4731
+ const style = document.createElement('style');
4732
+ style.id = styleId;
4733
+ style.textContent = `
4734
+ /* Nile Code Editor cell styling */
4735
+ nile-code-editor.st-cell-editor {
4736
+ display: block;
4737
+ width: 100%;
4738
+ height: 100%;
4739
+ font-size: inherit !important;
4740
+ font-family: inherit !important;
4741
+ line-height: inherit !important;
4742
+ }
4743
+ nile-code-editor.st-cell-editor::part(code-editor-base) {
4744
+ border: none !important;
4745
+ min-height: 100% !important;
4746
+ background: transparent !important;
4747
+ font-size: inherit !important;
4748
+ font-family: inherit !important;
4749
+ line-height: inherit !important;
4750
+ }
4751
+ /* Ensure proper sizing within table cell */
4752
+ .st-nile-code-editor {
4753
+ width: 100%;
4754
+ height: 100%;
4755
+ min-height: 28px;
4756
+ font-size: inherit !important;
4757
+ }
4758
+ /* CodeMirror content should inherit font size */
4759
+ nile-code-editor.st-cell-editor .cm-content,
4760
+ nile-code-editor.st-cell-editor .cm-line {
4761
+ font-size: inherit !important;
4762
+ font-family: inherit !important;
4763
+ line-height: inherit !important;
4764
+ }
4765
+ /* Container wrapper for editor + expand button */
4766
+ .st-code-editor-wrapper {
4767
+ display: flex;
4768
+ align-items: center;
4769
+ width: 100%;
4770
+ height: 100%;
4771
+ gap: 4px;
4772
+ }
4773
+ .st-code-editor-wrapper .st-code-editor-input {
4774
+ flex: 1;
4775
+ min-width: 0;
4776
+ height: 100%;
4777
+ }
4778
+ .st-code-editor-wrapper .st-expand-button {
4779
+ display: flex;
4780
+ align-items: center;
4781
+ justify-content: center;
4782
+ width: 24px;
4783
+ height: 24px;
4784
+ min-width: 24px;
4785
+ padding: 0;
4786
+ border: none;
4787
+ background: transparent;
4788
+ cursor: pointer;
4789
+ color: var(--nile-color-neutral-500, #6b7280);
4790
+ border-radius: 4px;
4791
+ transition: all 0.2s;
4792
+ }
4793
+ .st-code-editor-wrapper .st-expand-button:hover {
4794
+ background: var(--nile-color-neutral-100, #f3f4f6);
4795
+ color: var(--nile-color-neutral-700, #374151);
4796
+ }
4797
+ /* Dialog code editor styling */
4798
+ .st-code-editor-dialog::part(panel) {
4799
+ max-height: var(--max-height, 80vh) !important;
4800
+ overflow: hidden !important;
4801
+ }
4802
+ .st-code-editor-dialog::part(body) {
4803
+ overflow: auto !important;
4804
+ }
4805
+ .st-code-editor-dialog nile-code-editor {
4806
+ width: 100%;
4807
+ display: block;
4808
+ }
4809
+ .st-code-editor-dialog nile-code-editor::part(code-editor-base) {
4810
+ border: 1px solid var(--nile-color-neutral-200, #e5e7eb) !important;
4811
+ border-radius: 4px !important;
4812
+ overflow: auto !important;
4813
+ min-height: var(--dialog-editor-min-height, 300px) !important;
4814
+ }
4815
+ .st-code-editor-dialog nile-code-editor .cm-editor {
4816
+ min-height: var(--dialog-editor-min-height, 300px) !important;
4817
+ }
4818
+ .st-code-editor-dialog nile-code-editor .cm-content {
4819
+ min-height: var(--dialog-editor-min-height, 300px) !important;
4820
+ }
4821
+ `;
4822
+ document.head.appendChild(style);
4823
+ }
4824
+ /**
4825
+ * Custom editor that uses NileCodeEditor component
4826
+ * Provides code editing with syntax highlighting for table cells
4827
+ * @template T The value type (typically string)
4828
+ */
4829
+ class NileCodeEditor {
4830
+ constructor(options) {
4831
+ this.options = options;
4832
+ this.eventListeners = [];
4833
+ this.dialogOpen = false;
4834
+ this.expandButtonClicked = false;
4835
+ this.trackedValue = null;
4836
+ }
4837
+ edit(context) {
4838
+ var _a, _b, _c, _d, _e, _f;
4839
+ if (!context.container) {
4840
+ console.warn('NileCodeEditor requires a container element');
4841
+ return;
4842
+ }
4843
+ this.context = context;
4844
+ this.trackedValue = null;
4845
+ // Inject global styles once
4846
+ injectCodeEditorStyles();
4847
+ // Check if we should show expand button (default: true)
4848
+ const showExpandButton = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.showExpandButton) !== false;
4849
+ if (showExpandButton) {
4850
+ // Create wrapper for editor + expand button
4851
+ this.wrapper = document.createElement('div');
4852
+ this.wrapper.className = 'st-code-editor-wrapper';
4853
+ // Create the editor container
4854
+ const editorContainer = document.createElement('div');
4855
+ editorContainer.className = 'st-code-editor-input';
4856
+ // Create NileCodeEditor custom element
4857
+ this.editor = document.createElement('nile-code-editor');
4858
+ this.editor.value = String((_b = context.value) !== null && _b !== void 0 ? _b : '');
4859
+ this.editor.className = 'st-cell-editor st-nile-code-editor';
4860
+ this.editor.style.width = '100%';
4861
+ this.editor.style.height = '100%';
4862
+ this.editor.style.boxSizing = 'border-box';
4863
+ this.editor.noborder = ((_c = this.options) === null || _c === void 0 ? void 0 : _c.noborder) !== false;
4864
+ editorContainer.appendChild(this.editor);
4865
+ this.wrapper.appendChild(editorContainer);
4866
+ // Create expand button
4867
+ this.expandButton = document.createElement('button');
4868
+ this.expandButton.className = 'st-expand-button';
4869
+ this.expandButton.type = 'button';
4870
+ this.expandButton.title = 'Expand editor';
4871
+ this.expandButton.innerHTML = '<nile-icon name="expand-06" size="16"></nile-icon>';
4872
+ // Use mousedown to set flag BEFORE blur event fires
4873
+ this.expandButton.addEventListener('mousedown', (e) => {
4874
+ e.preventDefault();
4875
+ e.stopPropagation();
4876
+ this.expandButtonClicked = true;
4877
+ });
4878
+ this.expandButton.addEventListener('click', (e) => {
4879
+ e.preventDefault();
4880
+ e.stopPropagation();
4881
+ this.openDialog();
4882
+ });
4883
+ this.wrapper.appendChild(this.expandButton);
4884
+ // Clear container and append wrapper
4885
+ context.container.innerHTML = '';
4886
+ context.container.appendChild(this.wrapper);
4887
+ }
4888
+ else {
4889
+ // Create NileCodeEditor custom element without wrapper
4890
+ this.editor = document.createElement('nile-code-editor');
4891
+ this.editor.value = String((_d = context.value) !== null && _d !== void 0 ? _d : '');
4892
+ this.editor.className = 'st-cell-editor st-nile-code-editor';
4893
+ this.editor.style.width = '100%';
4894
+ this.editor.style.height = '100%';
4895
+ this.editor.style.boxSizing = 'border-box';
4896
+ this.editor.noborder = ((_e = this.options) === null || _e === void 0 ? void 0 : _e.noborder) !== false;
4897
+ // Clear container and append editor
4898
+ context.container.innerHTML = '';
4899
+ context.container.appendChild(this.editor);
4900
+ }
4901
+ // Apply all configuration options
4902
+ this.applyOptions();
4903
+ // Set up event listeners
4904
+ this.setupEventListeners(context);
4905
+ // Auto focus - need a slight delay for nile-code-editor to fully initialize
4906
+ if (((_f = this.options) === null || _f === void 0 ? void 0 : _f.autoFocus) !== false) {
4907
+ // Listen for the nile-after-init event which fires when editor is ready
4908
+ const initHandler = () => {
4909
+ var _a;
4910
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.removeEventListener('nile-after-init', initHandler);
4911
+ this.focusEditor();
4912
+ };
4913
+ this.editor.addEventListener('nile-after-init', initHandler);
4914
+ // Fallback: also try after a delay in case the event already fired
4915
+ setTimeout(() => {
4916
+ this.focusEditor();
4917
+ }, 100);
4918
+ }
4919
+ }
4920
+ /**
4921
+ * Focus the editor and place cursor
4922
+ */
4923
+ focusEditor() {
4924
+ if (!this.editor)
4925
+ return;
4926
+ try {
4927
+ // Call the component's focus method
4928
+ this.editor.focus();
4929
+ // Try to directly focus the CodeMirror content area
4930
+ const shadowRoot = this.editor.shadowRoot;
4931
+ if (shadowRoot) {
4932
+ const cmContent = shadowRoot.querySelector('.cm-content');
4933
+ if (cmContent) {
4934
+ cmContent.focus();
4935
+ // Dispatch a click event to ensure cursor placement
4936
+ cmContent.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
4937
+ cmContent.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
4938
+ }
4939
+ }
4940
+ }
4941
+ catch (e) {
4942
+ // Silently handle any errors
4943
+ }
4944
+ }
4945
+ /**
4946
+ * Read the live value directly from CodeMirror's internal state,
4947
+ * bypassing debounced nile-change events and the possibly-stale .value property.
4948
+ */
4949
+ getLiveEditorValue() {
4950
+ var _a, _b;
4951
+ if (!this.editor)
4952
+ return '';
4953
+ try {
4954
+ const shadowRoot = this.editor.shadowRoot;
4955
+ if (shadowRoot) {
4956
+ const cmEditor = shadowRoot.querySelector('.cm-editor');
4957
+ if ((_a = cmEditor === null || cmEditor === void 0 ? void 0 : cmEditor.cmView) === null || _a === void 0 ? void 0 : _a.view) {
4958
+ return cmEditor.cmView.view.state.doc.toString();
4959
+ }
4960
+ }
4961
+ }
4962
+ catch (_c) {
4963
+ // Fall through to other methods
4964
+ }
4965
+ if (this.trackedValue !== null)
4966
+ return this.trackedValue;
4967
+ return (_b = this.editor.value) !== null && _b !== void 0 ? _b : '';
4968
+ }
4969
+ /**
4970
+ * Open the full editor dialog
4971
+ */
4972
+ openDialog() {
4973
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
4974
+ if (this.dialogOpen)
4975
+ return;
4976
+ this.dialogOpen = true;
4977
+ this.expandButtonClicked = false; // Reset flag now that dialog is opening
4978
+ // Create dialog with configurable dimensions
4979
+ const dialogWidth = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.dialogWidth) || '600px';
4980
+ const dialogMaxHeight = ((_b = this.options) === null || _b === void 0 ? void 0 : _b.dialogMaxHeight) || '80vh';
4981
+ const dialogEditorHeight = ((_c = this.options) === null || _c === void 0 ? void 0 : _c.dialogEditorHeight) || '300px';
4982
+ const dialogTitle = ((_d = this.options) === null || _d === void 0 ? void 0 : _d.dialogTitle) || 'Edit Code';
4983
+ this.dialog = document.createElement('nile-dialog');
4984
+ this.dialog.className = 'st-code-editor-dialog';
4985
+ this.dialog.label = dialogTitle;
4986
+ this.dialog.style.setProperty('--width', dialogWidth);
4987
+ this.dialog.style.setProperty('--max-height', dialogMaxHeight);
4988
+ // Create dialog content
4989
+ const content = document.createElement('div');
4990
+ content.style.padding = '16px';
4991
+ content.style.maxHeight = `calc(${dialogMaxHeight} - 80px)`;
4992
+ content.style.overflow = 'auto';
4993
+ // Create full editor
4994
+ this.dialogEditor = document.createElement('nile-code-editor');
4995
+ const minLines = (_f = (_e = this.options) === null || _e === void 0 ? void 0 : _e.dialogMinLines) !== null && _f !== void 0 ? _f : 20;
4996
+ const currentValue = this.getLiveEditorValue();
4997
+ const currentLineCount = (currentValue.match(/\n/g) || []).length + 1;
4998
+ const paddingLines = Math.max(0, minLines - currentLineCount);
4999
+ this.dialogEditor.value = currentValue + '\n'.repeat(paddingLines);
5000
+ this.dialogEditor.multiline = true;
5001
+ this.dialogEditor.lineNumbersMultiline = true;
5002
+ this.dialogEditor.hasScroller = true;
5003
+ const lineHeightPx = 20;
5004
+ const minHeightFromLines = `${minLines * lineHeightPx}px`;
5005
+ this.dialogEditor.style.minHeight = `max(${dialogEditorHeight}, ${minHeightFromLines})`;
5006
+ this.dialogEditor.style.maxHeight = `calc(${dialogMaxHeight} - 120px)`;
5007
+ content.style.setProperty('--dialog-editor-min-height', `max(${dialogEditorHeight}, ${minHeightFromLines})`);
5008
+ // Apply same options to dialog editor
5009
+ if ((_g = this.options) === null || _g === void 0 ? void 0 : _g.language) {
5010
+ this.dialogEditor.language = this.options.language;
5011
+ }
5012
+ if ((_h = this.options) === null || _h === void 0 ? void 0 : _h.placeholder) {
5013
+ this.dialogEditor.placeholder = this.options.placeholder;
5014
+ }
5015
+ if (((_j = this.options) === null || _j === void 0 ? void 0 : _j.tabCompletion) !== undefined) {
5016
+ this.dialogEditor.tabCompletion = this.options.tabCompletion;
5017
+ }
5018
+ if (((_k = this.options) === null || _k === void 0 ? void 0 : _k.enableSearch) !== undefined) {
5019
+ this.dialogEditor.enableSearch = this.options.enableSearch;
5020
+ }
5021
+ if (((_l = this.options) === null || _l === void 0 ? void 0 : _l.enableFoldGutters) !== undefined) {
5022
+ this.dialogEditor.enableFoldGutters = this.options.enableFoldGutters;
5023
+ }
5024
+ if ((_m = this.options) === null || _m === void 0 ? void 0 : _m.customAutoCompletions) {
5025
+ this.dialogEditor.customAutoCompletions = this.options.customAutoCompletions;
5026
+ }
5027
+ if ((_o = this.options) === null || _o === void 0 ? void 0 : _o.customCompletionsPaths) {
5028
+ this.dialogEditor.customCompletionsPaths = this.options.customCompletionsPaths;
5029
+ }
5030
+ if ((_p = this.options) === null || _p === void 0 ? void 0 : _p.customThemeCSS) {
5031
+ this.dialogEditor.customThemeCSS = this.options.customThemeCSS;
5032
+ }
5033
+ this.dialogEditor.expandable = false;
5034
+ // Real-time sync: Update cell editor whenever dialog editor changes
5035
+ this.dialogEditor.addEventListener('nile-change', (e) => {
5036
+ var _a;
5037
+ const dialogValue = ((_a = e.detail) === null || _a === void 0 ? void 0 : _a.value) || '';
5038
+ this.trackedValue = dialogValue;
5039
+ if (this.editor) {
5040
+ this.editor.value = dialogValue;
5041
+ }
5042
+ if (this.context) {
5043
+ this.context.onChange(dialogValue);
5044
+ }
5045
+ });
5046
+ content.appendChild(this.dialogEditor);
5047
+ this.dialog.appendChild(content);
5048
+ // Handle dialog close events (clicking X button - stay in edit mode)
5049
+ this.dialog.addEventListener('nile-request-close', (e) => {
5050
+ var _a;
5051
+ const customEvent = e;
5052
+ // Check if close was triggered by overlay click (clicking outside)
5053
+ if (((_a = customEvent.detail) === null || _a === void 0 ? void 0 : _a.source) === 'overlay') {
5054
+ // Clicking outside the dialog - save and exit edit mode
5055
+ this.closeDialog(true);
5056
+ }
5057
+ else {
5058
+ // Clicking X button - stay in edit mode
5059
+ this.closeDialog(false);
5060
+ }
5061
+ });
5062
+ // Handle Escape key in dialog - stay in edit mode
5063
+ this.dialog.addEventListener('keydown', (e) => {
5064
+ if (e.key === 'Escape') {
5065
+ e.preventDefault();
5066
+ e.stopPropagation();
5067
+ this.closeDialog(false);
5068
+ }
5069
+ });
5070
+ // Append to body and show
5071
+ document.body.appendChild(this.dialog);
5072
+ // Open dialog after a tick to ensure it's in the DOM
5073
+ setTimeout(() => {
5074
+ if (this.dialog) {
5075
+ this.dialog.open = true;
5076
+ // Focus the dialog editor
5077
+ setTimeout(() => {
5078
+ var _a;
5079
+ (_a = this.dialogEditor) === null || _a === void 0 ? void 0 : _a.focus();
5080
+ }, 100);
5081
+ }
5082
+ }, 0);
5083
+ }
5084
+ /**
5085
+ * Close the dialog and optionally save/exit edit mode
5086
+ */
5087
+ closeDialog(saveAndExit = false) {
5088
+ if (!this.dialogOpen)
5089
+ return;
5090
+ // Reset flag immediately so document click handler works
5091
+ this.dialogOpen = false;
5092
+ // Close and remove dialog
5093
+ if (this.dialog) {
5094
+ this.dialog.open = false;
5095
+ const dialogRef = this.dialog;
5096
+ const dialogEditorRef = this.dialogEditor;
5097
+ this.dialog = undefined;
5098
+ this.dialogEditor = undefined;
5099
+ // Remove from DOM after animation
5100
+ setTimeout(() => {
5101
+ dialogRef === null || dialogRef === void 0 ? void 0 : dialogRef.remove();
5102
+ }, 200);
5103
+ if (saveAndExit && this.context) {
5104
+ // Save and exit edit mode
5105
+ this.context.onSave(this.getCurrentValue());
5106
+ }
5107
+ else {
5108
+ // Refocus the cell editor to stay in edit mode
5109
+ setTimeout(() => {
5110
+ this.focusEditor();
5111
+ }, 50);
5112
+ }
5113
+ }
5114
+ }
5115
+ /**
5116
+ * Apply all configuration options to the NileCodeEditor element
5117
+ */
5118
+ applyOptions() {
5119
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
5120
+ if (!this.editor)
5121
+ return;
5122
+ // Language and syntax
5123
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.language) {
5124
+ this.editor.language = this.options.language;
5125
+ }
5126
+ if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.disableSyntaxHighlighting) {
5127
+ this.editor.disableSyntaxHighlighting = this.options.disableSyntaxHighlighting;
5128
+ }
5129
+ // Editor appearance
5130
+ if ((_c = this.options) === null || _c === void 0 ? void 0 : _c.placeholder) {
5131
+ this.editor.placeholder = this.options.placeholder;
5132
+ }
5133
+ if (((_d = this.options) === null || _d === void 0 ? void 0 : _d.lineNumbers) !== undefined) {
5134
+ this.editor.lineNumbers = this.options.lineNumbers;
5135
+ }
5136
+ if (((_e = this.options) === null || _e === void 0 ? void 0 : _e.lineNumbersMultiline) !== undefined) {
5137
+ this.editor.lineNumbersMultiline = this.options.lineNumbersMultiline;
5138
+ }
5139
+ if (((_f = this.options) === null || _f === void 0 ? void 0 : _f.multiline) !== undefined) {
5140
+ this.editor.multiline = this.options.multiline;
5141
+ }
5142
+ if (((_g = this.options) === null || _g === void 0 ? void 0 : _g.defaultFont) !== undefined) {
5143
+ this.editor.defaultFont = this.options.defaultFont;
5144
+ }
5145
+ // Editor behavior
5146
+ if (((_h = this.options) === null || _h === void 0 ? void 0 : _h.readonly) !== undefined) {
5147
+ this.editor.readonly = this.options.readonly;
5148
+ }
5149
+ if (((_j = this.options) === null || _j === void 0 ? void 0 : _j.disabled) !== undefined) {
5150
+ this.editor.disabled = this.options.disabled;
5151
+ }
5152
+ if (((_k = this.options) === null || _k === void 0 ? void 0 : _k.tabCompletion) !== undefined) {
5153
+ this.editor.tabCompletion = this.options.tabCompletion;
5154
+ }
5155
+ if (((_l = this.options) === null || _l === void 0 ? void 0 : _l.enableSearch) !== undefined) {
5156
+ this.editor.enableSearch = this.options.enableSearch;
5157
+ }
5158
+ if (((_m = this.options) === null || _m === void 0 ? void 0 : _m.enableFoldGutters) !== undefined) {
5159
+ this.editor.enableFoldGutters = this.options.enableFoldGutters;
5160
+ }
5161
+ if (((_o = this.options) === null || _o === void 0 ? void 0 : _o.hasScroller) !== undefined) {
5162
+ this.editor.hasScroller = this.options.hasScroller;
5163
+ }
5164
+ // Expandable - default to false for cell editing
5165
+ this.editor.expandable = (_q = (_p = this.options) === null || _p === void 0 ? void 0 : _p.expandable) !== null && _q !== void 0 ? _q : false;
5166
+ if ((_r = this.options) === null || _r === void 0 ? void 0 : _r.expandIcon) {
5167
+ this.editor.expandIcon = this.options.expandIcon;
5168
+ }
5169
+ // Autocompletion
5170
+ if ((_s = this.options) === null || _s === void 0 ? void 0 : _s.customAutoCompletions) {
5171
+ this.editor.customAutoCompletions = this.options.customAutoCompletions;
5172
+ }
5173
+ if ((_t = this.options) === null || _t === void 0 ? void 0 : _t.customCompletionsPaths) {
5174
+ this.editor.customCompletionsPaths = this.options.customCompletionsPaths;
5175
+ }
5176
+ if (((_u = this.options) === null || _u === void 0 ? void 0 : _u.allowVariableInCustomSuggestion) !== undefined) {
5177
+ this.editor.allowVariableInCustomSuggestion = this.options.allowVariableInCustomSuggestion;
5178
+ }
5179
+ if (((_v = this.options) === null || _v === void 0 ? void 0 : _v.aboveCursor) !== undefined) {
5180
+ this.editor.aboveCursor = this.options.aboveCursor;
5181
+ }
5182
+ if ((_w = this.options) === null || _w === void 0 ? void 0 : _w.autoCompleteStyle) {
5183
+ this.editor.autoCompleteStyle = this.options.autoCompleteStyle;
5184
+ }
5185
+ // Change handling
5186
+ if (((_x = this.options) === null || _x === void 0 ? void 0 : _x.debounce) !== undefined) {
5187
+ this.editor.debounce = this.options.debounce;
5188
+ }
5189
+ if (((_y = this.options) === null || _y === void 0 ? void 0 : _y.debounceTimeout) !== undefined) {
5190
+ this.editor.debounceTimeout = this.options.debounceTimeout;
5191
+ }
5192
+ // Visual states
5193
+ if (((_z = this.options) === null || _z === void 0 ? void 0 : _z.error) !== undefined) {
5194
+ this.editor.error = this.options.error;
5195
+ }
5196
+ if ((_0 = this.options) === null || _0 === void 0 ? void 0 : _0.errorMessage) {
5197
+ this.editor.errorMessage = this.options.errorMessage;
5198
+ }
5199
+ // Custom theme
5200
+ if ((_1 = this.options) === null || _1 === void 0 ? void 0 : _1.customThemeCSS) {
5201
+ this.editor.customThemeCSS = this.options.customThemeCSS;
5202
+ }
5203
+ }
5204
+ /**
5205
+ * Set up all event listeners with proper cleanup tracking
5206
+ */
5207
+ setupEventListeners(context) {
5208
+ var _a, _b;
5209
+ if (!this.editor)
5210
+ return;
5211
+ const validateOnSave = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.validateOnSave) !== false;
5212
+ // Handle keyboard events
5213
+ const keydownHandler = (e) => {
5214
+ var _a;
5215
+ const keyEvent = e;
5216
+ // For single-line mode, Enter saves
5217
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.multiline) && keyEvent.key === 'Enter') {
5218
+ keyEvent.preventDefault();
5219
+ keyEvent.stopPropagation();
5220
+ this.saveValue(context, validateOnSave);
5221
+ }
5222
+ // Escape cancels
5223
+ if (keyEvent.key === 'Escape') {
5224
+ keyEvent.preventDefault();
5225
+ keyEvent.stopPropagation();
5226
+ context.onCancel();
5227
+ }
5228
+ };
5229
+ this.editor.addEventListener('keydown', keydownHandler);
5230
+ this.eventListeners.push({ event: 'keydown', handler: keydownHandler });
5231
+ // Use nile-blur event for saving on blur
5232
+ const blurHandler = () => {
5233
+ // Don't save if dialog is open
5234
+ if (this.dialogOpen) {
5235
+ return;
5236
+ }
5237
+ // Don't save if expand button was clicked (mousedown sets this flag)
5238
+ if (this.expandButtonClicked) {
5239
+ // Reset flag - the click handler will open the dialog
5240
+ this.expandButtonClicked = false;
5241
+ return;
5242
+ }
5243
+ // Save and exit edit mode
5244
+ this.saveValue(context, validateOnSave);
5245
+ };
5246
+ this.editor.addEventListener('nile-blur', blurHandler);
5247
+ this.eventListeners.push({ event: 'nile-blur', handler: blurHandler });
5248
+ // Document-level mousedown handler to detect clicks outside the editor
5249
+ this.documentClickHandler = (e) => {
5250
+ // Don't process if dialog is open or expand button was clicked
5251
+ if (this.dialogOpen || this.expandButtonClicked) {
5252
+ return;
5253
+ }
5254
+ // Use composedPath to handle Shadow DOM boundaries
5255
+ const path = e.composedPath();
5256
+ // Check if any element in the path is our wrapper, editor, or expand button
5257
+ for (const element of path) {
5258
+ if (element === this.wrapper || element === this.editor || element === this.expandButton) {
5259
+ return;
5260
+ }
5261
+ // Also check if it's the container (the cell)
5262
+ if (element === context.container) {
5263
+ return;
5264
+ }
5265
+ }
5266
+ // Click is outside - save and exit
5267
+ this.saveValue(context, validateOnSave);
5268
+ };
5269
+ // Add with a small delay to avoid capturing the initial click that opened the editor
5270
+ setTimeout(() => {
5271
+ document.addEventListener('mousedown', this.documentClickHandler, true);
5272
+ }, 50);
5273
+ // Real-time value updates using nile-change
5274
+ const changeHandler = (e) => {
5275
+ var _a, _b;
5276
+ const customEvent = e;
5277
+ const newValue = (_b = (_a = customEvent.detail) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '';
5278
+ this.trackedValue = newValue;
5279
+ context.onChange(newValue);
5280
+ };
5281
+ this.editor.addEventListener('nile-change', changeHandler);
5282
+ this.eventListeners.push({ event: 'nile-change', handler: changeHandler });
5283
+ // Handle expand event if expandable
5284
+ if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.expandable) {
5285
+ const expandHandler = () => {
5286
+ var _a;
5287
+ // Emit a custom event that the parent can listen to
5288
+ const expandEvent = new CustomEvent('st-code-editor-expand', {
5289
+ bubbles: true,
5290
+ detail: { value: this.getCurrentValue() }
5291
+ });
5292
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.dispatchEvent(expandEvent);
5293
+ };
5294
+ this.editor.addEventListener('nile-expand', expandHandler);
5295
+ this.eventListeners.push({ event: 'nile-expand', handler: expandHandler });
5296
+ }
5297
+ }
5298
+ /**
5299
+ * Save value with optional validation
5300
+ */
5301
+ saveValue(context, validate) {
5302
+ var _a;
5303
+ if (!this.editor)
5304
+ return;
5305
+ // Code editor doesn't have built-in validation like input
5306
+ // But we can check for error state
5307
+ if (validate && ((_a = this.options) === null || _a === void 0 ? void 0 : _a.error)) {
5308
+ return;
5309
+ }
5310
+ const value = this.getCurrentValue();
5311
+ context.onSave(value);
5312
+ }
5313
+ destroy() {
5314
+ // Remove document click handler
5315
+ if (this.documentClickHandler) {
5316
+ document.removeEventListener('mousedown', this.documentClickHandler, true);
5317
+ this.documentClickHandler = undefined;
5318
+ }
5319
+ // Close dialog if open
5320
+ if (this.dialogOpen && this.dialog) {
5321
+ this.dialog.open = false;
5322
+ this.dialog.remove();
5323
+ this.dialog = undefined;
5324
+ this.dialogEditor = undefined;
5325
+ this.dialogOpen = false;
5326
+ }
5327
+ // Remove all event listeners
5328
+ if (this.editor) {
5329
+ this.eventListeners.forEach(({ event, handler }) => {
5330
+ var _a;
5331
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, handler);
5332
+ });
5333
+ this.eventListeners = [];
5334
+ this.editor.remove();
5335
+ this.editor = undefined;
5336
+ }
5337
+ // Remove wrapper if exists
5338
+ if (this.wrapper) {
5339
+ this.wrapper.remove();
5340
+ this.wrapper = undefined;
5341
+ }
5342
+ // Clear expand button reference
5343
+ this.expandButton = undefined;
5344
+ this.context = undefined;
5345
+ this.expandButtonClicked = false;
5346
+ }
5347
+ focus() {
5348
+ var _a;
5349
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.focus();
5350
+ }
5351
+ getCurrentValue() {
5352
+ if (!this.editor)
5353
+ return '';
5354
+ const value = this.getLiveEditorValue();
5355
+ return value.replace(/\n+$/, '');
5356
+ }
5357
+ /**
5358
+ * Set value programmatically
5359
+ */
5360
+ setValue(value) {
5361
+ if (this.editor) {
5362
+ this.editor.value = String(value !== null && value !== void 0 ? value : '');
5363
+ }
5364
+ }
5365
+ /**
5366
+ * Get the CodeMirror instance (if needed for advanced usage)
5367
+ */
5368
+ getEditorInstance() {
5369
+ return this.editor;
5370
+ }
5371
+ }
5372
+
4676
5373
  /**
4677
5374
  * Custom cell editors for ngx-smart-table
4678
5375
  */
@@ -4875,15 +5572,28 @@ class ColumnConfigFactory {
4875
5572
  const Columns = ColumnConfigFactory;
4876
5573
 
4877
5574
  class StCellComponent {
4878
- constructor() {
5575
+ constructor(cdr) {
5576
+ this.cdr = cdr;
4879
5577
  this.editMode = EditMode.CLICK;
4880
5578
  this.cellChange = new EventEmitter();
4881
5579
  this.cellEdit = new EventEmitter();
4882
5580
  this.cellSave = new EventEmitter();
4883
5581
  this.cellCancel = new EventEmitter();
4884
5582
  this.cellSaveAndNavigate = new EventEmitter();
5583
+ this.cellLoading = false;
4885
5584
  }
4886
5585
  ngOnInit() {
5586
+ this.cell.onStateChange(() => {
5587
+ this.cellLoading = !!this.cell.getState().isLoading;
5588
+ try {
5589
+ this.cdr.detectChanges();
5590
+ }
5591
+ catch (_a) {
5592
+ // View may have been destroyed; safely ignore
5593
+ }
5594
+ });
5595
+ // Pick up loading state that was set before this component was created
5596
+ this.cellLoading = !!this.cell.getState().isLoading;
4887
5597
  // Subscribe to editing position changes
4888
5598
  // When another cell starts editing, save this cell if it's currently editing
4889
5599
  if (this.tableState && this.columnIndex !== undefined) {
@@ -5237,12 +5947,12 @@ class StCellComponent {
5237
5947
  }
5238
5948
  }
5239
5949
  }
5240
- StCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5241
- 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"] }] });
5950
+ StCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
5951
+ 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"] }] });
5242
5952
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, decorators: [{
5243
5953
  type: Component,
5244
- 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"] }]
5245
- }], ctorParameters: function () { return []; }, propDecorators: { cell: [{
5954
+ 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"] }]
5955
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { cell: [{
5246
5956
  type: Input
5247
5957
  }], editMode: [{
5248
5958
  type: Input
@@ -7932,7 +8642,21 @@ class StTableComponent {
7932
8642
  if (!this.data)
7933
8643
  return;
7934
8644
  const columns = this.getActiveColumns();
7935
- this.internalCellGrid = this.data.map((rowData, rowIndex) => columns.map(column => new Cell(column, rowData[column.key], rowData, rowIndex)));
8645
+ const oldGrid = this.internalCellGrid;
8646
+ this.internalCellGrid = this.data.map((rowData, rowIndex) => columns.map((column, colIndex) => {
8647
+ var _a;
8648
+ const newCell = new Cell(column, rowData[column.key], rowData, rowIndex);
8649
+ const oldCell = (_a = oldGrid === null || oldGrid === void 0 ? void 0 : oldGrid[rowIndex]) === null || _a === void 0 ? void 0 : _a[colIndex];
8650
+ if (oldCell && oldCell.getColumnConfig().key === column.key) {
8651
+ oldCell.setReplacement(newCell);
8652
+ // Carry over transient state (e.g. loading) that was set on the old cell
8653
+ const oldState = oldCell.getState();
8654
+ if (oldState.isLoading) {
8655
+ newCell.setLoading(true);
8656
+ }
8657
+ }
8658
+ return newCell;
8659
+ }));
7936
8660
  }
7937
8661
  /**
7938
8662
  * Setup data source - either sync array or async Observable
@@ -12346,5 +13070,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
12346
13070
  * Generated bundle index. Do not edit.
12347
13071
  */
12348
13072
 
12349
- 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 };
13073
+ 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 };
12350
13074
  //# sourceMappingURL=aquera-ngx-smart-table.mjs.map