@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.
@@ -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 {
@@ -3600,6 +3640,7 @@ class NileSelectEditor {
3600
3640
  this.eventListeners = [];
3601
3641
  this.currentOptions = [];
3602
3642
  this.trackedValues = []; // Track selected values for virtual scroll
3643
+ this.hasChangeOccurred = false; // Whether a nile-change event has fired
3603
3644
  // Handle Observable options
3604
3645
  if (isObservable(options.options)) {
3605
3646
  this.optionsSubscription = options.options.subscribe(opts => {
@@ -3660,6 +3701,7 @@ class NileSelectEditor {
3660
3701
  setInitialValue(value) {
3661
3702
  if (!this.select)
3662
3703
  return;
3704
+ this.hasChangeOccurred = false;
3663
3705
  if (this.options.multiple) {
3664
3706
  // Handle multiple selection - value should be array
3665
3707
  if (Array.isArray(value)) {
@@ -3865,6 +3907,7 @@ class NileSelectEditor {
3865
3907
  const customEvent = e;
3866
3908
  const newValue = (_a = customEvent.detail) === null || _a === void 0 ? void 0 : _a.value;
3867
3909
  if (newValue !== undefined) {
3910
+ this.hasChangeOccurred = true;
3868
3911
  if (Array.isArray(newValue)) {
3869
3912
  this.trackedValues = [...newValue];
3870
3913
  }
@@ -4003,20 +4046,20 @@ class NileSelectEditor {
4003
4046
  }
4004
4047
  }
4005
4048
  getCurrentValue() {
4049
+ var _a;
4006
4050
  if (!this.select) {
4007
4051
  return (this.options.multiple ? [] : '');
4008
4052
  }
4009
- // For multi-select, prefer tracked values (more reliable for virtual scroll)
4010
4053
  if (this.options.multiple) {
4011
- // Use tracked values if available, otherwise try component value
4012
- let values = this.trackedValues.length > 0 ? this.trackedValues : this.select.value;
4054
+ // If a change event fired, always use trackedValues (even if empty = all unchecked).
4055
+ // Only fall back to the component value when no change has occurred yet.
4056
+ let values = this.hasChangeOccurred ? this.trackedValues : this.select.value;
4013
4057
  if (Array.isArray(values)) {
4014
4058
  return values.filter((v) => v !== undefined && v !== null && v !== '');
4015
4059
  }
4016
4060
  return (values ? [values] : []);
4017
4061
  }
4018
- // For single-select, use tracked values or component value
4019
- let value = this.trackedValues.length > 0 ? this.trackedValues[0] : this.select.value;
4062
+ let value = this.hasChangeOccurred ? ((_a = this.trackedValues[0]) !== null && _a !== void 0 ? _a : '') : this.select.value;
4020
4063
  return (Array.isArray(value) ? (value.length > 0 ? value[0] : '') : (value || ''));
4021
4064
  }
4022
4065
  }
@@ -4670,6 +4713,640 @@ class NileDatePickerEditor {
4670
4713
  }
4671
4714
  }
4672
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
+ * Open the full editor dialog
4947
+ */
4948
+ openDialog() {
4949
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
4950
+ if (this.dialogOpen)
4951
+ return;
4952
+ this.dialogOpen = true;
4953
+ this.expandButtonClicked = false; // Reset flag now that dialog is opening
4954
+ // Create dialog with configurable dimensions
4955
+ const dialogWidth = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.dialogWidth) || '600px';
4956
+ const dialogMaxHeight = ((_b = this.options) === null || _b === void 0 ? void 0 : _b.dialogMaxHeight) || '80vh';
4957
+ const dialogEditorHeight = ((_c = this.options) === null || _c === void 0 ? void 0 : _c.dialogEditorHeight) || '300px';
4958
+ const dialogTitle = ((_d = this.options) === null || _d === void 0 ? void 0 : _d.dialogTitle) || 'Edit Code';
4959
+ this.dialog = document.createElement('nile-dialog');
4960
+ this.dialog.className = 'st-code-editor-dialog';
4961
+ this.dialog.label = dialogTitle;
4962
+ this.dialog.style.setProperty('--width', dialogWidth);
4963
+ this.dialog.style.setProperty('--max-height', dialogMaxHeight);
4964
+ // Create dialog content
4965
+ const content = document.createElement('div');
4966
+ content.style.padding = '16px';
4967
+ content.style.maxHeight = `calc(${dialogMaxHeight} - 80px)`;
4968
+ content.style.overflow = 'auto';
4969
+ // Create full editor
4970
+ this.dialogEditor = document.createElement('nile-code-editor');
4971
+ const minLines = (_f = (_e = this.options) === null || _e === void 0 ? void 0 : _e.dialogMinLines) !== null && _f !== void 0 ? _f : 20;
4972
+ const currentValue = ((_g = this.editor) === null || _g === void 0 ? void 0 : _g.value) || '';
4973
+ const currentLineCount = (currentValue.match(/\n/g) || []).length + 1;
4974
+ const paddingLines = Math.max(0, minLines - currentLineCount);
4975
+ this.dialogEditor.value = currentValue + '\n'.repeat(paddingLines);
4976
+ this.dialogEditor.multiline = true;
4977
+ this.dialogEditor.lineNumbersMultiline = true;
4978
+ this.dialogEditor.hasScroller = true;
4979
+ const lineHeightPx = 20;
4980
+ const minHeightFromLines = `${minLines * lineHeightPx}px`;
4981
+ this.dialogEditor.style.minHeight = `max(${dialogEditorHeight}, ${minHeightFromLines})`;
4982
+ this.dialogEditor.style.maxHeight = `calc(${dialogMaxHeight} - 120px)`;
4983
+ content.style.setProperty('--dialog-editor-min-height', `max(${dialogEditorHeight}, ${minHeightFromLines})`);
4984
+ // Apply same options to dialog editor
4985
+ if ((_h = this.options) === null || _h === void 0 ? void 0 : _h.language) {
4986
+ this.dialogEditor.language = this.options.language;
4987
+ }
4988
+ if ((_j = this.options) === null || _j === void 0 ? void 0 : _j.placeholder) {
4989
+ this.dialogEditor.placeholder = this.options.placeholder;
4990
+ }
4991
+ if (((_k = this.options) === null || _k === void 0 ? void 0 : _k.tabCompletion) !== undefined) {
4992
+ this.dialogEditor.tabCompletion = this.options.tabCompletion;
4993
+ }
4994
+ if (((_l = this.options) === null || _l === void 0 ? void 0 : _l.enableSearch) !== undefined) {
4995
+ this.dialogEditor.enableSearch = this.options.enableSearch;
4996
+ }
4997
+ if (((_m = this.options) === null || _m === void 0 ? void 0 : _m.enableFoldGutters) !== undefined) {
4998
+ this.dialogEditor.enableFoldGutters = this.options.enableFoldGutters;
4999
+ }
5000
+ if ((_o = this.options) === null || _o === void 0 ? void 0 : _o.customAutoCompletions) {
5001
+ this.dialogEditor.customAutoCompletions = this.options.customAutoCompletions;
5002
+ }
5003
+ if ((_p = this.options) === null || _p === void 0 ? void 0 : _p.customCompletionsPaths) {
5004
+ this.dialogEditor.customCompletionsPaths = this.options.customCompletionsPaths;
5005
+ }
5006
+ if ((_q = this.options) === null || _q === void 0 ? void 0 : _q.customThemeCSS) {
5007
+ this.dialogEditor.customThemeCSS = this.options.customThemeCSS;
5008
+ }
5009
+ this.dialogEditor.expandable = false;
5010
+ // Real-time sync: Update cell editor whenever dialog editor changes
5011
+ this.dialogEditor.addEventListener('nile-change', (e) => {
5012
+ var _a;
5013
+ const dialogValue = ((_a = e.detail) === null || _a === void 0 ? void 0 : _a.value) || '';
5014
+ this.trackedValue = dialogValue;
5015
+ if (this.editor) {
5016
+ this.editor.value = dialogValue;
5017
+ }
5018
+ if (this.context) {
5019
+ this.context.onChange(dialogValue);
5020
+ }
5021
+ });
5022
+ content.appendChild(this.dialogEditor);
5023
+ this.dialog.appendChild(content);
5024
+ // Handle dialog close events (clicking X button - stay in edit mode)
5025
+ this.dialog.addEventListener('nile-request-close', (e) => {
5026
+ var _a;
5027
+ const customEvent = e;
5028
+ // Check if close was triggered by overlay click (clicking outside)
5029
+ if (((_a = customEvent.detail) === null || _a === void 0 ? void 0 : _a.source) === 'overlay') {
5030
+ // Clicking outside the dialog - save and exit edit mode
5031
+ this.closeDialog(true);
5032
+ }
5033
+ else {
5034
+ // Clicking X button - stay in edit mode
5035
+ this.closeDialog(false);
5036
+ }
5037
+ });
5038
+ // Handle Escape key in dialog - stay in edit mode
5039
+ this.dialog.addEventListener('keydown', (e) => {
5040
+ if (e.key === 'Escape') {
5041
+ e.preventDefault();
5042
+ e.stopPropagation();
5043
+ this.closeDialog(false);
5044
+ }
5045
+ });
5046
+ // Append to body and show
5047
+ document.body.appendChild(this.dialog);
5048
+ // Open dialog after a tick to ensure it's in the DOM
5049
+ setTimeout(() => {
5050
+ if (this.dialog) {
5051
+ this.dialog.open = true;
5052
+ // Focus the dialog editor
5053
+ setTimeout(() => {
5054
+ var _a;
5055
+ (_a = this.dialogEditor) === null || _a === void 0 ? void 0 : _a.focus();
5056
+ }, 100);
5057
+ }
5058
+ }, 0);
5059
+ }
5060
+ /**
5061
+ * Close the dialog and optionally save/exit edit mode
5062
+ */
5063
+ closeDialog(saveAndExit = false) {
5064
+ if (!this.dialogOpen)
5065
+ return;
5066
+ // Reset flag immediately so document click handler works
5067
+ this.dialogOpen = false;
5068
+ // Close and remove dialog
5069
+ if (this.dialog) {
5070
+ this.dialog.open = false;
5071
+ const dialogRef = this.dialog;
5072
+ const dialogEditorRef = this.dialogEditor;
5073
+ this.dialog = undefined;
5074
+ this.dialogEditor = undefined;
5075
+ // Remove from DOM after animation
5076
+ setTimeout(() => {
5077
+ dialogRef === null || dialogRef === void 0 ? void 0 : dialogRef.remove();
5078
+ }, 200);
5079
+ if (saveAndExit && this.context) {
5080
+ // Save and exit edit mode
5081
+ this.context.onSave(this.getCurrentValue());
5082
+ }
5083
+ else {
5084
+ // Refocus the cell editor to stay in edit mode
5085
+ setTimeout(() => {
5086
+ this.focusEditor();
5087
+ }, 50);
5088
+ }
5089
+ }
5090
+ }
5091
+ /**
5092
+ * Apply all configuration options to the NileCodeEditor element
5093
+ */
5094
+ applyOptions() {
5095
+ 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;
5096
+ if (!this.editor)
5097
+ return;
5098
+ // Language and syntax
5099
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.language) {
5100
+ this.editor.language = this.options.language;
5101
+ }
5102
+ if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.disableSyntaxHighlighting) {
5103
+ this.editor.disableSyntaxHighlighting = this.options.disableSyntaxHighlighting;
5104
+ }
5105
+ // Editor appearance
5106
+ if ((_c = this.options) === null || _c === void 0 ? void 0 : _c.placeholder) {
5107
+ this.editor.placeholder = this.options.placeholder;
5108
+ }
5109
+ if (((_d = this.options) === null || _d === void 0 ? void 0 : _d.lineNumbers) !== undefined) {
5110
+ this.editor.lineNumbers = this.options.lineNumbers;
5111
+ }
5112
+ if (((_e = this.options) === null || _e === void 0 ? void 0 : _e.lineNumbersMultiline) !== undefined) {
5113
+ this.editor.lineNumbersMultiline = this.options.lineNumbersMultiline;
5114
+ }
5115
+ if (((_f = this.options) === null || _f === void 0 ? void 0 : _f.multiline) !== undefined) {
5116
+ this.editor.multiline = this.options.multiline;
5117
+ }
5118
+ if (((_g = this.options) === null || _g === void 0 ? void 0 : _g.defaultFont) !== undefined) {
5119
+ this.editor.defaultFont = this.options.defaultFont;
5120
+ }
5121
+ // Editor behavior
5122
+ if (((_h = this.options) === null || _h === void 0 ? void 0 : _h.readonly) !== undefined) {
5123
+ this.editor.readonly = this.options.readonly;
5124
+ }
5125
+ if (((_j = this.options) === null || _j === void 0 ? void 0 : _j.disabled) !== undefined) {
5126
+ this.editor.disabled = this.options.disabled;
5127
+ }
5128
+ if (((_k = this.options) === null || _k === void 0 ? void 0 : _k.tabCompletion) !== undefined) {
5129
+ this.editor.tabCompletion = this.options.tabCompletion;
5130
+ }
5131
+ if (((_l = this.options) === null || _l === void 0 ? void 0 : _l.enableSearch) !== undefined) {
5132
+ this.editor.enableSearch = this.options.enableSearch;
5133
+ }
5134
+ if (((_m = this.options) === null || _m === void 0 ? void 0 : _m.enableFoldGutters) !== undefined) {
5135
+ this.editor.enableFoldGutters = this.options.enableFoldGutters;
5136
+ }
5137
+ if (((_o = this.options) === null || _o === void 0 ? void 0 : _o.hasScroller) !== undefined) {
5138
+ this.editor.hasScroller = this.options.hasScroller;
5139
+ }
5140
+ // Expandable - default to false for cell editing
5141
+ this.editor.expandable = (_q = (_p = this.options) === null || _p === void 0 ? void 0 : _p.expandable) !== null && _q !== void 0 ? _q : false;
5142
+ if ((_r = this.options) === null || _r === void 0 ? void 0 : _r.expandIcon) {
5143
+ this.editor.expandIcon = this.options.expandIcon;
5144
+ }
5145
+ // Autocompletion
5146
+ if ((_s = this.options) === null || _s === void 0 ? void 0 : _s.customAutoCompletions) {
5147
+ this.editor.customAutoCompletions = this.options.customAutoCompletions;
5148
+ }
5149
+ if ((_t = this.options) === null || _t === void 0 ? void 0 : _t.customCompletionsPaths) {
5150
+ this.editor.customCompletionsPaths = this.options.customCompletionsPaths;
5151
+ }
5152
+ if (((_u = this.options) === null || _u === void 0 ? void 0 : _u.allowVariableInCustomSuggestion) !== undefined) {
5153
+ this.editor.allowVariableInCustomSuggestion = this.options.allowVariableInCustomSuggestion;
5154
+ }
5155
+ if (((_v = this.options) === null || _v === void 0 ? void 0 : _v.aboveCursor) !== undefined) {
5156
+ this.editor.aboveCursor = this.options.aboveCursor;
5157
+ }
5158
+ if ((_w = this.options) === null || _w === void 0 ? void 0 : _w.autoCompleteStyle) {
5159
+ this.editor.autoCompleteStyle = this.options.autoCompleteStyle;
5160
+ }
5161
+ // Change handling
5162
+ if (((_x = this.options) === null || _x === void 0 ? void 0 : _x.debounce) !== undefined) {
5163
+ this.editor.debounce = this.options.debounce;
5164
+ }
5165
+ if (((_y = this.options) === null || _y === void 0 ? void 0 : _y.debounceTimeout) !== undefined) {
5166
+ this.editor.debounceTimeout = this.options.debounceTimeout;
5167
+ }
5168
+ // Visual states
5169
+ if (((_z = this.options) === null || _z === void 0 ? void 0 : _z.error) !== undefined) {
5170
+ this.editor.error = this.options.error;
5171
+ }
5172
+ if ((_0 = this.options) === null || _0 === void 0 ? void 0 : _0.errorMessage) {
5173
+ this.editor.errorMessage = this.options.errorMessage;
5174
+ }
5175
+ // Custom theme
5176
+ if ((_1 = this.options) === null || _1 === void 0 ? void 0 : _1.customThemeCSS) {
5177
+ this.editor.customThemeCSS = this.options.customThemeCSS;
5178
+ }
5179
+ }
5180
+ /**
5181
+ * Set up all event listeners with proper cleanup tracking
5182
+ */
5183
+ setupEventListeners(context) {
5184
+ var _a, _b;
5185
+ if (!this.editor)
5186
+ return;
5187
+ const validateOnSave = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.validateOnSave) !== false;
5188
+ // Handle keyboard events
5189
+ const keydownHandler = (e) => {
5190
+ var _a;
5191
+ const keyEvent = e;
5192
+ // For single-line mode, Enter saves
5193
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.multiline) && keyEvent.key === 'Enter') {
5194
+ keyEvent.preventDefault();
5195
+ keyEvent.stopPropagation();
5196
+ this.saveValue(context, validateOnSave);
5197
+ }
5198
+ // Escape cancels
5199
+ if (keyEvent.key === 'Escape') {
5200
+ keyEvent.preventDefault();
5201
+ keyEvent.stopPropagation();
5202
+ context.onCancel();
5203
+ }
5204
+ };
5205
+ this.editor.addEventListener('keydown', keydownHandler);
5206
+ this.eventListeners.push({ event: 'keydown', handler: keydownHandler });
5207
+ // Use nile-blur event for saving on blur
5208
+ const blurHandler = () => {
5209
+ // Don't save if dialog is open
5210
+ if (this.dialogOpen) {
5211
+ return;
5212
+ }
5213
+ // Don't save if expand button was clicked (mousedown sets this flag)
5214
+ if (this.expandButtonClicked) {
5215
+ // Reset flag - the click handler will open the dialog
5216
+ this.expandButtonClicked = false;
5217
+ return;
5218
+ }
5219
+ // Save and exit edit mode
5220
+ this.saveValue(context, validateOnSave);
5221
+ };
5222
+ this.editor.addEventListener('nile-blur', blurHandler);
5223
+ this.eventListeners.push({ event: 'nile-blur', handler: blurHandler });
5224
+ // Document-level mousedown handler to detect clicks outside the editor
5225
+ this.documentClickHandler = (e) => {
5226
+ // Don't process if dialog is open or expand button was clicked
5227
+ if (this.dialogOpen || this.expandButtonClicked) {
5228
+ return;
5229
+ }
5230
+ // Use composedPath to handle Shadow DOM boundaries
5231
+ const path = e.composedPath();
5232
+ // Check if any element in the path is our wrapper, editor, or expand button
5233
+ for (const element of path) {
5234
+ if (element === this.wrapper || element === this.editor || element === this.expandButton) {
5235
+ return;
5236
+ }
5237
+ // Also check if it's the container (the cell)
5238
+ if (element === context.container) {
5239
+ return;
5240
+ }
5241
+ }
5242
+ // Click is outside - save and exit
5243
+ this.saveValue(context, validateOnSave);
5244
+ };
5245
+ // Add with a small delay to avoid capturing the initial click that opened the editor
5246
+ setTimeout(() => {
5247
+ document.addEventListener('mousedown', this.documentClickHandler, true);
5248
+ }, 50);
5249
+ // Real-time value updates using nile-change
5250
+ const changeHandler = (e) => {
5251
+ var _a, _b;
5252
+ const customEvent = e;
5253
+ const newValue = (_b = (_a = customEvent.detail) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '';
5254
+ this.trackedValue = newValue;
5255
+ context.onChange(newValue);
5256
+ };
5257
+ this.editor.addEventListener('nile-change', changeHandler);
5258
+ this.eventListeners.push({ event: 'nile-change', handler: changeHandler });
5259
+ // Handle expand event if expandable
5260
+ if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.expandable) {
5261
+ const expandHandler = () => {
5262
+ var _a;
5263
+ // Emit a custom event that the parent can listen to
5264
+ const expandEvent = new CustomEvent('st-code-editor-expand', {
5265
+ bubbles: true,
5266
+ detail: { value: this.getCurrentValue() }
5267
+ });
5268
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.dispatchEvent(expandEvent);
5269
+ };
5270
+ this.editor.addEventListener('nile-expand', expandHandler);
5271
+ this.eventListeners.push({ event: 'nile-expand', handler: expandHandler });
5272
+ }
5273
+ }
5274
+ /**
5275
+ * Save value with optional validation
5276
+ */
5277
+ saveValue(context, validate) {
5278
+ var _a;
5279
+ if (!this.editor)
5280
+ return;
5281
+ // Code editor doesn't have built-in validation like input
5282
+ // But we can check for error state
5283
+ if (validate && ((_a = this.options) === null || _a === void 0 ? void 0 : _a.error)) {
5284
+ return;
5285
+ }
5286
+ const value = this.getCurrentValue();
5287
+ context.onSave(value);
5288
+ }
5289
+ destroy() {
5290
+ // Remove document click handler
5291
+ if (this.documentClickHandler) {
5292
+ document.removeEventListener('mousedown', this.documentClickHandler, true);
5293
+ this.documentClickHandler = undefined;
5294
+ }
5295
+ // Close dialog if open
5296
+ if (this.dialogOpen && this.dialog) {
5297
+ this.dialog.open = false;
5298
+ this.dialog.remove();
5299
+ this.dialog = undefined;
5300
+ this.dialogEditor = undefined;
5301
+ this.dialogOpen = false;
5302
+ }
5303
+ // Remove all event listeners
5304
+ if (this.editor) {
5305
+ this.eventListeners.forEach(({ event, handler }) => {
5306
+ var _a;
5307
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, handler);
5308
+ });
5309
+ this.eventListeners = [];
5310
+ this.editor.remove();
5311
+ this.editor = undefined;
5312
+ }
5313
+ // Remove wrapper if exists
5314
+ if (this.wrapper) {
5315
+ this.wrapper.remove();
5316
+ this.wrapper = undefined;
5317
+ }
5318
+ // Clear expand button reference
5319
+ this.expandButton = undefined;
5320
+ this.context = undefined;
5321
+ this.expandButtonClicked = false;
5322
+ }
5323
+ focus() {
5324
+ var _a;
5325
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.focus();
5326
+ }
5327
+ getCurrentValue() {
5328
+ var _a;
5329
+ if (!this.editor)
5330
+ return '';
5331
+ const value = (this.trackedValue !== null ? this.trackedValue : (_a = this.editor.value) !== null && _a !== void 0 ? _a : '');
5332
+ return value.replace(/\n+$/, '');
5333
+ }
5334
+ /**
5335
+ * Set value programmatically
5336
+ */
5337
+ setValue(value) {
5338
+ if (this.editor) {
5339
+ this.editor.value = String(value !== null && value !== void 0 ? value : '');
5340
+ }
5341
+ }
5342
+ /**
5343
+ * Get the CodeMirror instance (if needed for advanced usage)
5344
+ */
5345
+ getEditorInstance() {
5346
+ return this.editor;
5347
+ }
5348
+ }
5349
+
4673
5350
  /**
4674
5351
  * Custom cell editors for ngx-smart-table
4675
5352
  */
@@ -4872,15 +5549,28 @@ class ColumnConfigFactory {
4872
5549
  const Columns = ColumnConfigFactory;
4873
5550
 
4874
5551
  class StCellComponent {
4875
- constructor() {
5552
+ constructor(cdr) {
5553
+ this.cdr = cdr;
4876
5554
  this.editMode = EditMode.CLICK;
4877
5555
  this.cellChange = new EventEmitter();
4878
5556
  this.cellEdit = new EventEmitter();
4879
5557
  this.cellSave = new EventEmitter();
4880
5558
  this.cellCancel = new EventEmitter();
4881
5559
  this.cellSaveAndNavigate = new EventEmitter();
5560
+ this.cellLoading = false;
4882
5561
  }
4883
5562
  ngOnInit() {
5563
+ this.cell.onStateChange(() => {
5564
+ this.cellLoading = !!this.cell.getState().isLoading;
5565
+ try {
5566
+ this.cdr.detectChanges();
5567
+ }
5568
+ catch (_a) {
5569
+ // View may have been destroyed; safely ignore
5570
+ }
5571
+ });
5572
+ // Pick up loading state that was set before this component was created
5573
+ this.cellLoading = !!this.cell.getState().isLoading;
4884
5574
  // Subscribe to editing position changes
4885
5575
  // When another cell starts editing, save this cell if it's currently editing
4886
5576
  if (this.tableState && this.columnIndex !== undefined) {
@@ -5234,12 +5924,12 @@ class StCellComponent {
5234
5924
  }
5235
5925
  }
5236
5926
  }
5237
- StCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5238
- 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"] }] });
5927
+ StCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
5928
+ 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"] }] });
5239
5929
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, decorators: [{
5240
5930
  type: Component,
5241
- 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"] }]
5242
- }], ctorParameters: function () { return []; }, propDecorators: { cell: [{
5931
+ 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"] }]
5932
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { cell: [{
5243
5933
  type: Input
5244
5934
  }], editMode: [{
5245
5935
  type: Input
@@ -7929,7 +8619,21 @@ class StTableComponent {
7929
8619
  if (!this.data)
7930
8620
  return;
7931
8621
  const columns = this.getActiveColumns();
7932
- this.internalCellGrid = this.data.map((rowData, rowIndex) => columns.map(column => new Cell(column, rowData[column.key], rowData, rowIndex)));
8622
+ const oldGrid = this.internalCellGrid;
8623
+ this.internalCellGrid = this.data.map((rowData, rowIndex) => columns.map((column, colIndex) => {
8624
+ var _a;
8625
+ const newCell = new Cell(column, rowData[column.key], rowData, rowIndex);
8626
+ const oldCell = (_a = oldGrid === null || oldGrid === void 0 ? void 0 : oldGrid[rowIndex]) === null || _a === void 0 ? void 0 : _a[colIndex];
8627
+ if (oldCell && oldCell.getColumnConfig().key === column.key) {
8628
+ oldCell.setReplacement(newCell);
8629
+ // Carry over transient state (e.g. loading) that was set on the old cell
8630
+ const oldState = oldCell.getState();
8631
+ if (oldState.isLoading) {
8632
+ newCell.setLoading(true);
8633
+ }
8634
+ }
8635
+ return newCell;
8636
+ }));
7933
8637
  }
7934
8638
  /**
7935
8639
  * Setup data source - either sync array or async Observable
@@ -12343,5 +13047,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
12343
13047
  * Generated bundle index. Do not edit.
12344
13048
  */
12345
13049
 
12346
- 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 };
13050
+ 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 };
12347
13051
  //# sourceMappingURL=aquera-ngx-smart-table.mjs.map