@aquera/ngx-smart-table 0.0.22 → 0.0.24

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.
@@ -1,7 +1,7 @@
1
1
  import { BehaviorSubject, Subject, isObservable, fromEvent, merge } from 'rxjs';
2
2
  import { distinctUntilChanged, map, throttleTime } from 'rxjs/operators';
3
3
  import * as i0 from '@angular/core';
4
- import { inject, DestroyRef, input, output, computed, ElementRef, HostListener, ViewChild, Component, Injectable, Input, CUSTOM_ELEMENTS_SCHEMA, EventEmitter, Output, ChangeDetectionStrategy, Directive, signal, effect, ChangeDetectorRef, NgModule } from '@angular/core';
4
+ import { inject, DestroyRef, input, output, ChangeDetectorRef, computed, ElementRef, HostListener, ViewChild, Component, Injectable, Input, CUSTOM_ELEMENTS_SCHEMA, EventEmitter, Output, ChangeDetectionStrategy, Directive, signal, effect, NgModule } from '@angular/core';
5
5
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
6
  import * as i1 from '@angular/common';
7
7
  import { CommonModule } from '@angular/common';
@@ -2574,10 +2574,38 @@ class Cell {
2574
2574
  return this.rowIndex;
2575
2575
  }
2576
2576
  /**
2577
- * Set loading state
2577
+ * Link this cell to its replacement so future state mutations forward.
2578
+ */
2579
+ setReplacement(replacement) {
2580
+ this.replacementCell = replacement;
2581
+ }
2582
+ onStateChange(callback) {
2583
+ this.stateChangeCallback = callback;
2584
+ }
2585
+ /**
2586
+ * Set loading state. Forwards to replacement cell if this cell was replaced.
2578
2587
  */
2579
2588
  setLoading(isLoading) {
2589
+ if (this.replacementCell) {
2590
+ this.replacementCell.setLoading(isLoading);
2591
+ return;
2592
+ }
2580
2593
  this.state.isLoading = isLoading;
2594
+ try {
2595
+ this.stateChangeCallback?.();
2596
+ }
2597
+ catch {
2598
+ this.stateChangeCallback = undefined;
2599
+ }
2600
+ }
2601
+ /**
2602
+ * Set cell value (public API, forwards to replacement if replaced).
2603
+ */
2604
+ setValueExternal(value) {
2605
+ if (this.replacementCell) {
2606
+ return this.replacementCell.setValueExternal(value);
2607
+ }
2608
+ return this.setValue(value, true);
2581
2609
  }
2582
2610
  /**
2583
2611
  * Set disabled state
@@ -3650,17 +3678,28 @@ function injectDropdownStyles() {
3650
3678
  }
3651
3679
  /* Combobox styling using ::part() selector */
3652
3680
  nile-select.st-cell-editor::part(combobox) {
3653
- background-color: var(--nile-colors-white-base, var(--ng-colors-bg-primary)) !important;
3681
+ background-color: transparent !important;
3654
3682
  border: solid 1px transparent !important;
3655
- margin: 1px 4px !important;
3683
+ margin: 0px !important;
3684
+ max-height: 28px;
3656
3685
  }
3657
3686
  nile-select.st-cell-editor::part(combobox):hover {
3658
3687
  border: solid 1px transparent !important;
3659
3688
  }
3660
3689
  .st-cell-editor::part(combobox) {
3661
- background-color: var(--nile-colors-white-base, var(--ng-colors-bg-primary)) !important;
3690
+ background-color: transparent !important;
3662
3691
  border: solid 1px transparent !important;
3663
- margin: 1px 4px !important;
3692
+ margin: 0px !important;
3693
+ max-height: 28px;
3694
+ }
3695
+ /* Tag spacing */
3696
+ nile-select.st-cell-editor::part(tag) {
3697
+ margin-right: 0px;
3698
+ padding: 1px 2px;
3699
+ }
3700
+ .st-cell-editor::part(tag) {
3701
+ margin-right: 0px;
3702
+ padding: 1px 2px;
3664
3703
  }
3665
3704
  /* Search input full width */
3666
3705
  .nile-select-portal-append .select__search {
@@ -4725,6 +4764,787 @@ class NileDatePickerEditor {
4725
4764
  }
4726
4765
  }
4727
4766
 
4767
+ /**
4768
+ * Custom editor using NileCodeEditor from @aquera/nile-elements
4769
+ * This provides code editing capabilities with syntax highlighting for table cells
4770
+ */
4771
+ /**
4772
+ * Inject global styles for nile-code-editor in table cells
4773
+ */
4774
+ let codeEditorStylesInjected = false;
4775
+ function injectCodeEditorStyles() {
4776
+ if (codeEditorStylesInjected)
4777
+ return;
4778
+ codeEditorStylesInjected = true;
4779
+ const styleId = 'nile-code-editor-cell-styles';
4780
+ if (document.getElementById(styleId))
4781
+ return;
4782
+ const style = document.createElement('style');
4783
+ style.id = styleId;
4784
+ style.textContent = `
4785
+ /* Nile Code Editor cell styling - constrained to cell height */
4786
+ nile-code-editor.st-cell-editor {
4787
+ display: block;
4788
+ width: 100%;
4789
+ height: 100%;
4790
+ max-height: 32px;
4791
+ overflow: hidden;
4792
+ font-size: inherit !important;
4793
+ font-family: inherit !important;
4794
+ line-height: inherit !important;
4795
+ }
4796
+ nile-code-editor.st-cell-editor::part(code-editor-base) {
4797
+ border: none !important;
4798
+ min-height: 100% !important;
4799
+ max-height: 32px !important;
4800
+ background: transparent !important;
4801
+ font-size: inherit !important;
4802
+ font-family: inherit !important;
4803
+ line-height: inherit !important;
4804
+ overflow: hidden !important;
4805
+ }
4806
+ /* Ensure proper sizing within table cell */
4807
+ .st-nile-code-editor {
4808
+ width: 100%;
4809
+ height: 100%;
4810
+ max-height: 32px;
4811
+ min-height: 28px;
4812
+ font-size: inherit !important;
4813
+ overflow: hidden;
4814
+ }
4815
+ /* CodeMirror content should inherit font size and be constrained */
4816
+ nile-code-editor.st-cell-editor .cm-editor {
4817
+ max-height: 32px !important;
4818
+ overflow: hidden !important;
4819
+ }
4820
+ nile-code-editor.st-cell-editor .cm-scroller {
4821
+ max-height: 32px !important;
4822
+ overflow: hidden !important;
4823
+ }
4824
+ nile-code-editor.st-cell-editor .cm-content,
4825
+ nile-code-editor.st-cell-editor .cm-line {
4826
+ font-size: inherit !important;
4827
+ font-family: inherit !important;
4828
+ line-height: inherit !important;
4829
+ }
4830
+ /* Container wrapper for editor + expand button */
4831
+ .st-code-editor-wrapper {
4832
+ display: flex;
4833
+ align-items: center;
4834
+ width: 100%;
4835
+ height: 100%;
4836
+ max-height: 32px;
4837
+ gap: 4px;
4838
+ }
4839
+ .st-code-editor-wrapper .st-code-editor-input {
4840
+ flex: 1;
4841
+ min-width: 0;
4842
+ height: 100%;
4843
+ max-height: 32px;
4844
+ overflow: hidden;
4845
+ }
4846
+ .st-code-editor-wrapper .st-expand-button {
4847
+ display: flex;
4848
+ align-items: center;
4849
+ justify-content: center;
4850
+ width: 24px;
4851
+ height: 24px;
4852
+ min-width: 24px;
4853
+ padding: 0;
4854
+ border: none;
4855
+ background: transparent;
4856
+ cursor: pointer;
4857
+ color: var(--nile-color-neutral-500, #6b7280);
4858
+ border-radius: 4px;
4859
+ transition: all 0.2s;
4860
+ }
4861
+ .st-code-editor-wrapper .st-expand-button:hover {
4862
+ background: var(--nile-color-neutral-100, #f3f4f6);
4863
+ color: var(--nile-color-neutral-700, #374151);
4864
+ }
4865
+ /* Dialog code editor styling - fixed header/footer, scrollable content */
4866
+ .st-code-editor-dialog::part(panel) {
4867
+ max-height: var(--max-height, 80vh) !important;
4868
+ overflow: hidden !important;
4869
+ display: flex !important;
4870
+ flex-direction: column !important;
4871
+ }
4872
+ .st-code-editor-dialog::part(header) {
4873
+ flex-shrink: 0 !important;
4874
+ }
4875
+ .st-code-editor-dialog::part(body) {
4876
+ overflow: hidden !important;
4877
+ flex: 1 !important;
4878
+ display: flex !important;
4879
+ flex-direction: column !important;
4880
+ padding: 0 !important;
4881
+ }
4882
+ .st-code-editor-dialog nile-code-editor {
4883
+ width: 100%;
4884
+ display: block;
4885
+ }
4886
+ .st-code-editor-dialog nile-code-editor::part(code-editor-base) {
4887
+ border: 1px solid var(--nile-color-neutral-200, #e5e7eb) !important;
4888
+ border-radius: 4px !important;
4889
+ }
4890
+ `;
4891
+ document.head.appendChild(style);
4892
+ }
4893
+ /**
4894
+ * Custom editor that uses NileCodeEditor component
4895
+ * Provides code editing with syntax highlighting for table cells
4896
+ * @template T The value type (typically string)
4897
+ */
4898
+ class NileCodeEditor {
4899
+ constructor(options) {
4900
+ this.options = options;
4901
+ this.eventListeners = [];
4902
+ this.dialogOpen = false;
4903
+ this.expandButtonClicked = false;
4904
+ this.trackedValue = null;
4905
+ this.syncingFromDialog = false; // Flag to prevent inline editor from overwriting multiline content
4906
+ this.userEditedInline = false; // Flag to track if user has typed in inline editor
4907
+ this.dialogOriginalValue = ''; // Store original value when dialog opens
4908
+ this.dialogCurrentValue = ''; // Track current value in dialog
4909
+ }
4910
+ edit(context) {
4911
+ if (!context.container) {
4912
+ console.warn('NileCodeEditor requires a container element');
4913
+ return;
4914
+ }
4915
+ this.context = context;
4916
+ // Initialize tracked value from context
4917
+ this.trackedValue = String(context.value ?? '');
4918
+ this.syncingFromDialog = false;
4919
+ this.userEditedInline = false;
4920
+ // Inject global styles once
4921
+ injectCodeEditorStyles();
4922
+ // Check if we should show expand button (default: true)
4923
+ const showExpandButton = this.options?.showExpandButton !== false;
4924
+ if (showExpandButton) {
4925
+ // Create wrapper for editor + expand button
4926
+ this.wrapper = document.createElement('div');
4927
+ this.wrapper.className = 'st-code-editor-wrapper';
4928
+ // Create the editor container
4929
+ const editorContainer = document.createElement('div');
4930
+ editorContainer.className = 'st-code-editor-input';
4931
+ // Create NileCodeEditor custom element
4932
+ this.editor = document.createElement('nile-code-editor');
4933
+ this.editor.value = String(context.value ?? '');
4934
+ this.editor.className = 'st-cell-editor st-nile-code-editor';
4935
+ this.editor.style.width = '100%';
4936
+ this.editor.style.height = '100%';
4937
+ this.editor.style.boxSizing = 'border-box';
4938
+ this.editor.noborder = this.options?.noborder !== false;
4939
+ // Enable multiline by default for inline editor to support paste and multiline content
4940
+ this.editor.multiline = this.options?.multiline !== false;
4941
+ this.editor.hasScroller = true;
4942
+ // No line numbers for inline editor
4943
+ this.editor.lineNumbers = false;
4944
+ editorContainer.appendChild(this.editor);
4945
+ this.wrapper.appendChild(editorContainer);
4946
+ // Create expand button
4947
+ this.expandButton = document.createElement('button');
4948
+ this.expandButton.className = 'st-expand-button';
4949
+ this.expandButton.type = 'button';
4950
+ this.expandButton.title = 'Expand editor';
4951
+ this.expandButton.innerHTML = '<nile-icon name="expand-06" size="16"></nile-icon>';
4952
+ // Use mousedown to set flag BEFORE blur event fires
4953
+ this.expandButton.addEventListener('mousedown', (e) => {
4954
+ e.preventDefault();
4955
+ e.stopPropagation();
4956
+ this.expandButtonClicked = true;
4957
+ });
4958
+ this.expandButton.addEventListener('click', (e) => {
4959
+ e.preventDefault();
4960
+ e.stopPropagation();
4961
+ this.openDialog();
4962
+ });
4963
+ this.wrapper.appendChild(this.expandButton);
4964
+ // Clear container and append wrapper
4965
+ context.container.innerHTML = '';
4966
+ context.container.appendChild(this.wrapper);
4967
+ }
4968
+ else {
4969
+ // Create NileCodeEditor custom element without wrapper
4970
+ this.editor = document.createElement('nile-code-editor');
4971
+ this.editor.value = String(context.value ?? '');
4972
+ this.editor.className = 'st-cell-editor st-nile-code-editor';
4973
+ this.editor.style.width = '100%';
4974
+ this.editor.style.height = '100%';
4975
+ this.editor.style.boxSizing = 'border-box';
4976
+ this.editor.noborder = this.options?.noborder !== false;
4977
+ // Enable multiline by default for inline editor to support paste and multiline content
4978
+ this.editor.multiline = this.options?.multiline !== false;
4979
+ this.editor.hasScroller = true;
4980
+ // No line numbers for inline editor
4981
+ this.editor.lineNumbers = false;
4982
+ // Clear container and append editor
4983
+ context.container.innerHTML = '';
4984
+ context.container.appendChild(this.editor);
4985
+ }
4986
+ // Apply all configuration options
4987
+ this.applyOptions();
4988
+ // Set up event listeners
4989
+ this.setupEventListeners(context);
4990
+ // Auto focus - need a slight delay for nile-code-editor to fully initialize
4991
+ if (this.options?.autoFocus !== false) {
4992
+ // Listen for the nile-after-init event which fires when editor is ready
4993
+ const initHandler = () => {
4994
+ this.editor?.removeEventListener('nile-after-init', initHandler);
4995
+ this.focusEditor();
4996
+ };
4997
+ this.editor.addEventListener('nile-after-init', initHandler);
4998
+ // Fallback: also try after a delay in case the event already fired
4999
+ setTimeout(() => {
5000
+ this.focusEditor();
5001
+ }, 100);
5002
+ }
5003
+ }
5004
+ /**
5005
+ * Focus the editor and place cursor
5006
+ */
5007
+ focusEditor() {
5008
+ if (!this.editor)
5009
+ return;
5010
+ try {
5011
+ // Call the component's focus method
5012
+ this.editor.focus();
5013
+ // Try to directly focus the CodeMirror content area
5014
+ const shadowRoot = this.editor.shadowRoot;
5015
+ if (shadowRoot) {
5016
+ const cmContent = shadowRoot.querySelector('.cm-content');
5017
+ if (cmContent) {
5018
+ cmContent.focus();
5019
+ // Dispatch a click event to ensure cursor placement
5020
+ cmContent.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
5021
+ cmContent.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
5022
+ }
5023
+ }
5024
+ }
5025
+ catch (e) {
5026
+ // Silently handle any errors
5027
+ }
5028
+ }
5029
+ /**
5030
+ * Read the live value directly from CodeMirror's internal state,
5031
+ * bypassing debounced nile-change events and the possibly-stale .value property.
5032
+ *
5033
+ * Priority order:
5034
+ * 1. trackedValue - always up to date from change events
5035
+ * 2. CodeMirror internal state - for real-time reading
5036
+ * 3. editor.value property - fallback
5037
+ */
5038
+ getLiveEditorValue() {
5039
+ // Use tracked value if available (updated by change events)
5040
+ if (this.trackedValue !== null) {
5041
+ return this.trackedValue;
5042
+ }
5043
+ if (!this.editor)
5044
+ return '';
5045
+ try {
5046
+ const shadowRoot = this.editor.shadowRoot;
5047
+ if (shadowRoot) {
5048
+ const cmEditor = shadowRoot.querySelector('.cm-editor');
5049
+ if (cmEditor?.cmView?.view) {
5050
+ return cmEditor.cmView.view.state.doc.toString();
5051
+ }
5052
+ }
5053
+ }
5054
+ catch {
5055
+ // Fall through to other methods
5056
+ }
5057
+ return this.editor.value ?? '';
5058
+ }
5059
+ /**
5060
+ * Open the full editor dialog
5061
+ */
5062
+ openDialog() {
5063
+ if (this.dialogOpen)
5064
+ return;
5065
+ this.dialogOpen = true;
5066
+ this.expandButtonClicked = false; // Reset flag now that dialog is opening
5067
+ // Store original value for cancel functionality
5068
+ this.dialogOriginalValue = this.getLiveEditorValue();
5069
+ // Create dialog with configurable dimensions
5070
+ const dialogWidth = this.options?.dialogWidth || '600px';
5071
+ const dialogMaxHeight = this.options?.dialogMaxHeight || '80vh';
5072
+ const dialogEditorHeight = this.options?.dialogEditorHeight || '300px';
5073
+ const dialogTitle = this.options?.dialogTitle || 'Edit Code';
5074
+ this.dialog = document.createElement('nile-dialog');
5075
+ this.dialog.className = 'st-code-editor-dialog';
5076
+ this.dialog.label = dialogTitle;
5077
+ this.dialog.style.setProperty('--width', dialogWidth);
5078
+ this.dialog.style.setProperty('--max-height', dialogMaxHeight);
5079
+ // Create dialog content wrapper - flex column to handle fixed header/footer
5080
+ const contentWrapper = document.createElement('div');
5081
+ contentWrapper.style.display = 'flex';
5082
+ contentWrapper.style.flexDirection = 'column';
5083
+ contentWrapper.style.height = `calc(${dialogMaxHeight} - 60px)`; // Account for dialog header
5084
+ contentWrapper.style.maxHeight = `calc(${dialogMaxHeight} - 60px)`;
5085
+ // Create editor content area - this is the scrollable part
5086
+ const content = document.createElement('div');
5087
+ content.style.padding = '16px';
5088
+ content.style.paddingBottom = '8px';
5089
+ content.style.flex = '1';
5090
+ content.style.overflow = 'auto';
5091
+ content.style.minHeight = '0'; // Important for flex shrinking
5092
+ // Create full editor
5093
+ this.dialogEditor = document.createElement('nile-code-editor');
5094
+ this.dialogEditor.value = this.dialogOriginalValue;
5095
+ this.dialogEditor.multiline = true;
5096
+ this.dialogEditor.lineNumbersMultiline = true;
5097
+ this.dialogEditor.hasScroller = true;
5098
+ this.dialogEditor.style.minHeight = dialogEditorHeight;
5099
+ // Apply same options to dialog editor
5100
+ if (this.options?.language) {
5101
+ this.dialogEditor.language = this.options.language;
5102
+ }
5103
+ if (this.options?.placeholder) {
5104
+ this.dialogEditor.placeholder = this.options.placeholder;
5105
+ }
5106
+ if (this.options?.tabCompletion !== undefined) {
5107
+ this.dialogEditor.tabCompletion = this.options.tabCompletion;
5108
+ }
5109
+ if (this.options?.enableSearch !== undefined) {
5110
+ this.dialogEditor.enableSearch = this.options.enableSearch;
5111
+ }
5112
+ if (this.options?.enableFoldGutters !== undefined) {
5113
+ this.dialogEditor.enableFoldGutters = this.options.enableFoldGutters;
5114
+ }
5115
+ if (this.options?.customAutoCompletions) {
5116
+ this.dialogEditor.customAutoCompletions = this.options.customAutoCompletions;
5117
+ }
5118
+ if (this.options?.customCompletionsPaths) {
5119
+ this.dialogEditor.customCompletionsPaths = this.options.customCompletionsPaths;
5120
+ }
5121
+ if (this.options?.customThemeCSS) {
5122
+ this.dialogEditor.customThemeCSS = this.options.customThemeCSS;
5123
+ }
5124
+ this.dialogEditor.expandable = false;
5125
+ // Initialize dialog current value
5126
+ this.dialogCurrentValue = this.dialogOriginalValue;
5127
+ // Track changes in dialog editor
5128
+ this.dialogEditor.addEventListener('nile-change', (e) => {
5129
+ this.dialogCurrentValue = e.detail?.value ?? '';
5130
+ });
5131
+ content.appendChild(this.dialogEditor);
5132
+ contentWrapper.appendChild(content);
5133
+ // Create footer with Ok button - fixed at bottom
5134
+ const footer = document.createElement('div');
5135
+ footer.style.display = 'flex';
5136
+ footer.style.justifyContent = 'flex-end';
5137
+ footer.style.padding = '12px 16px';
5138
+ footer.style.borderTop = '1px solid var(--nile-color-neutral-200, #e5e7eb)';
5139
+ footer.style.gap = '8px';
5140
+ footer.style.flexShrink = '0'; // Prevent footer from shrinking
5141
+ footer.style.backgroundColor = 'var(--nile-color-neutral-0, #ffffff)';
5142
+ const okButton = document.createElement('nile-button');
5143
+ okButton.setAttribute('variant', 'primary');
5144
+ okButton.textContent = 'Ok';
5145
+ okButton.addEventListener('click', () => {
5146
+ this.applyDialogChanges();
5147
+ });
5148
+ footer.appendChild(okButton);
5149
+ contentWrapper.appendChild(footer);
5150
+ this.dialog.appendChild(contentWrapper);
5151
+ // Handle dialog close events (clicking X button - cancel changes)
5152
+ this.dialog.addEventListener('nile-request-close', (e) => {
5153
+ e.preventDefault();
5154
+ // X button or overlay click - cancel changes
5155
+ this.cancelDialogChanges();
5156
+ });
5157
+ // Handle Escape key in dialog - cancel changes
5158
+ this.dialog.addEventListener('keydown', (e) => {
5159
+ if (e.key === 'Escape') {
5160
+ e.preventDefault();
5161
+ e.stopPropagation();
5162
+ this.cancelDialogChanges();
5163
+ }
5164
+ });
5165
+ // Append to body and show
5166
+ document.body.appendChild(this.dialog);
5167
+ // Open dialog after a tick to ensure it's in the DOM
5168
+ setTimeout(() => {
5169
+ if (this.dialog) {
5170
+ this.dialog.open = true;
5171
+ // Focus the dialog editor
5172
+ setTimeout(() => {
5173
+ this.dialogEditor?.focus();
5174
+ }, 100);
5175
+ }
5176
+ }, 0);
5177
+ }
5178
+ /**
5179
+ * Get the current value from the dialog editor
5180
+ */
5181
+ getDialogEditorValue() {
5182
+ // Use tracked value from change events (most reliable)
5183
+ if (this.dialogCurrentValue) {
5184
+ return this.dialogCurrentValue.replace(/\n+$/, '');
5185
+ }
5186
+ if (!this.dialogEditor)
5187
+ return this.dialogOriginalValue;
5188
+ // Try to get value from CodeMirror's internal state
5189
+ try {
5190
+ const shadowRoot = this.dialogEditor.shadowRoot;
5191
+ if (shadowRoot) {
5192
+ const cmEditor = shadowRoot.querySelector('.cm-editor');
5193
+ if (cmEditor?.cmView?.view) {
5194
+ const value = cmEditor.cmView.view.state.doc.toString();
5195
+ return value.replace(/\n+$/, '');
5196
+ }
5197
+ }
5198
+ }
5199
+ catch {
5200
+ // Fall through to other methods
5201
+ }
5202
+ // Fallback to value property
5203
+ const value = this.dialogEditor.value;
5204
+ return (value ?? '').replace(/\n+$/, '');
5205
+ }
5206
+ /**
5207
+ * Apply changes from dialog and close it
5208
+ */
5209
+ applyDialogChanges() {
5210
+ if (!this.dialogOpen)
5211
+ return;
5212
+ // Get the value from dialog editor - try multiple sources
5213
+ let dialogValue = this.dialogCurrentValue;
5214
+ // If no tracked value, try reading directly from dialog editor
5215
+ if (!dialogValue && this.dialogEditor) {
5216
+ try {
5217
+ const shadowRoot = this.dialogEditor.shadowRoot;
5218
+ if (shadowRoot) {
5219
+ const cmEditor = shadowRoot.querySelector('.cm-editor');
5220
+ if (cmEditor?.cmView?.view) {
5221
+ dialogValue = cmEditor.cmView.view.state.doc.toString();
5222
+ }
5223
+ }
5224
+ }
5225
+ catch {
5226
+ // Fall through
5227
+ }
5228
+ // Fallback to value property
5229
+ if (!dialogValue) {
5230
+ dialogValue = this.dialogEditor.value ?? '';
5231
+ }
5232
+ }
5233
+ // Strip trailing newlines
5234
+ dialogValue = (dialogValue || '').replace(/\n+$/, '');
5235
+ // Update tracked value and inline editor
5236
+ this.trackedValue = dialogValue;
5237
+ this.userEditedInline = false;
5238
+ this.syncingFromDialog = true;
5239
+ if (this.editor) {
5240
+ this.editor.value = dialogValue;
5241
+ }
5242
+ setTimeout(() => {
5243
+ this.syncingFromDialog = false;
5244
+ }, 0);
5245
+ // Notify context of the change
5246
+ if (this.context) {
5247
+ this.context.onChange(dialogValue);
5248
+ }
5249
+ // Close dialog
5250
+ this.closeDialogUI();
5251
+ // Refocus the cell editor to stay in edit mode
5252
+ setTimeout(() => {
5253
+ this.focusEditor();
5254
+ }, 50);
5255
+ }
5256
+ /**
5257
+ * Cancel dialog changes and revert to original value
5258
+ */
5259
+ cancelDialogChanges() {
5260
+ if (!this.dialogOpen)
5261
+ return;
5262
+ // Revert to original value (don't change anything)
5263
+ // trackedValue and inline editor remain as they were before dialog opened
5264
+ // Close dialog
5265
+ this.closeDialogUI();
5266
+ // Refocus the cell editor to stay in edit mode
5267
+ setTimeout(() => {
5268
+ this.focusEditor();
5269
+ }, 50);
5270
+ }
5271
+ /**
5272
+ * Close and remove the dialog UI
5273
+ */
5274
+ closeDialogUI() {
5275
+ this.dialogOpen = false;
5276
+ this.dialogCurrentValue = '';
5277
+ if (this.dialog) {
5278
+ this.dialog.open = false;
5279
+ const dialogRef = this.dialog;
5280
+ this.dialog = undefined;
5281
+ this.dialogEditor = undefined;
5282
+ // Remove from DOM after animation
5283
+ setTimeout(() => {
5284
+ dialogRef?.remove();
5285
+ }, 200);
5286
+ }
5287
+ }
5288
+ /**
5289
+ * Apply all configuration options to the NileCodeEditor element
5290
+ */
5291
+ applyOptions() {
5292
+ if (!this.editor)
5293
+ return;
5294
+ // Language and syntax
5295
+ if (this.options?.language) {
5296
+ this.editor.language = this.options.language;
5297
+ }
5298
+ if (this.options?.disableSyntaxHighlighting) {
5299
+ this.editor.disableSyntaxHighlighting = this.options.disableSyntaxHighlighting;
5300
+ }
5301
+ // Editor appearance
5302
+ if (this.options?.placeholder) {
5303
+ this.editor.placeholder = this.options.placeholder;
5304
+ }
5305
+ if (this.options?.lineNumbers !== undefined) {
5306
+ this.editor.lineNumbers = this.options.lineNumbers;
5307
+ }
5308
+ if (this.options?.lineNumbersMultiline !== undefined) {
5309
+ this.editor.lineNumbersMultiline = this.options.lineNumbersMultiline;
5310
+ }
5311
+ if (this.options?.multiline !== undefined) {
5312
+ this.editor.multiline = this.options.multiline;
5313
+ }
5314
+ if (this.options?.defaultFont !== undefined) {
5315
+ this.editor.defaultFont = this.options.defaultFont;
5316
+ }
5317
+ // Editor behavior
5318
+ if (this.options?.readonly !== undefined) {
5319
+ this.editor.readonly = this.options.readonly;
5320
+ }
5321
+ if (this.options?.disabled !== undefined) {
5322
+ this.editor.disabled = this.options.disabled;
5323
+ }
5324
+ if (this.options?.tabCompletion !== undefined) {
5325
+ this.editor.tabCompletion = this.options.tabCompletion;
5326
+ }
5327
+ if (this.options?.enableSearch !== undefined) {
5328
+ this.editor.enableSearch = this.options.enableSearch;
5329
+ }
5330
+ if (this.options?.enableFoldGutters !== undefined) {
5331
+ this.editor.enableFoldGutters = this.options.enableFoldGutters;
5332
+ }
5333
+ if (this.options?.hasScroller !== undefined) {
5334
+ this.editor.hasScroller = this.options.hasScroller;
5335
+ }
5336
+ // Expandable - default to false for cell editing
5337
+ this.editor.expandable = this.options?.expandable ?? false;
5338
+ if (this.options?.expandIcon) {
5339
+ this.editor.expandIcon = this.options.expandIcon;
5340
+ }
5341
+ // Autocompletion
5342
+ if (this.options?.customAutoCompletions) {
5343
+ this.editor.customAutoCompletions = this.options.customAutoCompletions;
5344
+ }
5345
+ if (this.options?.customCompletionsPaths) {
5346
+ this.editor.customCompletionsPaths = this.options.customCompletionsPaths;
5347
+ }
5348
+ if (this.options?.allowVariableInCustomSuggestion !== undefined) {
5349
+ this.editor.allowVariableInCustomSuggestion = this.options.allowVariableInCustomSuggestion;
5350
+ }
5351
+ if (this.options?.aboveCursor !== undefined) {
5352
+ this.editor.aboveCursor = this.options.aboveCursor;
5353
+ }
5354
+ if (this.options?.autoCompleteStyle) {
5355
+ this.editor.autoCompleteStyle = this.options.autoCompleteStyle;
5356
+ }
5357
+ // Change handling
5358
+ if (this.options?.debounce !== undefined) {
5359
+ this.editor.debounce = this.options.debounce;
5360
+ }
5361
+ if (this.options?.debounceTimeout !== undefined) {
5362
+ this.editor.debounceTimeout = this.options.debounceTimeout;
5363
+ }
5364
+ // Visual states
5365
+ if (this.options?.error !== undefined) {
5366
+ this.editor.error = this.options.error;
5367
+ }
5368
+ if (this.options?.errorMessage) {
5369
+ this.editor.errorMessage = this.options.errorMessage;
5370
+ }
5371
+ // Custom theme
5372
+ if (this.options?.customThemeCSS) {
5373
+ this.editor.customThemeCSS = this.options.customThemeCSS;
5374
+ }
5375
+ }
5376
+ /**
5377
+ * Set up all event listeners with proper cleanup tracking
5378
+ */
5379
+ setupEventListeners(context) {
5380
+ if (!this.editor)
5381
+ return;
5382
+ const validateOnSave = this.options?.validateOnSave !== false;
5383
+ // Handle keyboard events
5384
+ const keydownHandler = (e) => {
5385
+ const keyEvent = e;
5386
+ // For single-line mode, Enter saves
5387
+ if (!this.options?.multiline && keyEvent.key === 'Enter') {
5388
+ keyEvent.preventDefault();
5389
+ keyEvent.stopPropagation();
5390
+ this.saveValue(context, validateOnSave);
5391
+ }
5392
+ // Escape cancels
5393
+ if (keyEvent.key === 'Escape') {
5394
+ keyEvent.preventDefault();
5395
+ keyEvent.stopPropagation();
5396
+ context.onCancel();
5397
+ }
5398
+ };
5399
+ this.editor.addEventListener('keydown', keydownHandler);
5400
+ this.eventListeners.push({ event: 'keydown', handler: keydownHandler });
5401
+ // Use nile-blur event for saving on blur
5402
+ const blurHandler = () => {
5403
+ // Don't save if dialog is open
5404
+ if (this.dialogOpen) {
5405
+ return;
5406
+ }
5407
+ // Don't save if expand button was clicked (mousedown sets this flag)
5408
+ if (this.expandButtonClicked) {
5409
+ // Reset flag - the click handler will open the dialog
5410
+ this.expandButtonClicked = false;
5411
+ return;
5412
+ }
5413
+ // Save and exit edit mode
5414
+ this.saveValue(context, validateOnSave);
5415
+ };
5416
+ this.editor.addEventListener('nile-blur', blurHandler);
5417
+ this.eventListeners.push({ event: 'nile-blur', handler: blurHandler });
5418
+ // Document-level mousedown handler to detect clicks outside the editor
5419
+ this.documentClickHandler = (e) => {
5420
+ // Don't process if dialog is open or expand button was clicked
5421
+ if (this.dialogOpen || this.expandButtonClicked) {
5422
+ return;
5423
+ }
5424
+ // Use composedPath to handle Shadow DOM boundaries
5425
+ const path = e.composedPath();
5426
+ // Check if any element in the path is our wrapper, editor, or expand button
5427
+ for (const element of path) {
5428
+ if (element === this.wrapper || element === this.editor || element === this.expandButton) {
5429
+ return;
5430
+ }
5431
+ // Also check if it's the container (the cell)
5432
+ if (element === context.container) {
5433
+ return;
5434
+ }
5435
+ }
5436
+ // Click is outside - save and exit
5437
+ this.saveValue(context, validateOnSave);
5438
+ };
5439
+ // Add with a small delay to avoid capturing the initial click that opened the editor
5440
+ setTimeout(() => {
5441
+ document.addEventListener('mousedown', this.documentClickHandler, true);
5442
+ }, 50);
5443
+ // Real-time value updates using nile-change
5444
+ const changeHandler = (e) => {
5445
+ const customEvent = e;
5446
+ const newValue = customEvent.detail?.value ?? '';
5447
+ // Don't process if we're syncing from dialog (prevents feedback loop)
5448
+ if (this.syncingFromDialog) {
5449
+ return;
5450
+ }
5451
+ // Update tracked value
5452
+ this.trackedValue = newValue;
5453
+ context.onChange(newValue);
5454
+ };
5455
+ this.editor.addEventListener('nile-change', changeHandler);
5456
+ this.eventListeners.push({ event: 'nile-change', handler: changeHandler });
5457
+ // Handle expand event if expandable
5458
+ if (this.options?.expandable) {
5459
+ const expandHandler = () => {
5460
+ // Emit a custom event that the parent can listen to
5461
+ const expandEvent = new CustomEvent('st-code-editor-expand', {
5462
+ bubbles: true,
5463
+ detail: { value: this.getCurrentValue() }
5464
+ });
5465
+ this.editor?.dispatchEvent(expandEvent);
5466
+ };
5467
+ this.editor.addEventListener('nile-expand', expandHandler);
5468
+ this.eventListeners.push({ event: 'nile-expand', handler: expandHandler });
5469
+ }
5470
+ }
5471
+ /**
5472
+ * Save value with optional validation
5473
+ */
5474
+ saveValue(context, validate) {
5475
+ if (!this.editor)
5476
+ return;
5477
+ // Code editor doesn't have built-in validation like input
5478
+ // But we can check for error state
5479
+ if (validate && this.options?.error) {
5480
+ return;
5481
+ }
5482
+ const value = this.getCurrentValue();
5483
+ context.onSave(value);
5484
+ }
5485
+ destroy() {
5486
+ // Remove document click handler
5487
+ if (this.documentClickHandler) {
5488
+ document.removeEventListener('mousedown', this.documentClickHandler, true);
5489
+ this.documentClickHandler = undefined;
5490
+ }
5491
+ // Close dialog if open
5492
+ if (this.dialogOpen && this.dialog) {
5493
+ this.dialog.open = false;
5494
+ this.dialog.remove();
5495
+ this.dialog = undefined;
5496
+ this.dialogEditor = undefined;
5497
+ this.dialogOpen = false;
5498
+ }
5499
+ // Remove all event listeners
5500
+ if (this.editor) {
5501
+ this.eventListeners.forEach(({ event, handler }) => {
5502
+ this.editor?.removeEventListener(event, handler);
5503
+ });
5504
+ this.eventListeners = [];
5505
+ this.editor.remove();
5506
+ this.editor = undefined;
5507
+ }
5508
+ // Remove wrapper if exists
5509
+ if (this.wrapper) {
5510
+ this.wrapper.remove();
5511
+ this.wrapper = undefined;
5512
+ }
5513
+ // Clear expand button reference
5514
+ this.expandButton = undefined;
5515
+ this.context = undefined;
5516
+ this.expandButtonClicked = false;
5517
+ this.syncingFromDialog = false;
5518
+ this.trackedValue = null;
5519
+ this.userEditedInline = false;
5520
+ this.dialogOriginalValue = '';
5521
+ this.dialogCurrentValue = '';
5522
+ }
5523
+ focus() {
5524
+ this.editor?.focus();
5525
+ }
5526
+ getCurrentValue() {
5527
+ if (!this.editor)
5528
+ return '';
5529
+ const value = this.getLiveEditorValue();
5530
+ return value.replace(/\n+$/, '');
5531
+ }
5532
+ /**
5533
+ * Set value programmatically
5534
+ */
5535
+ setValue(value) {
5536
+ if (this.editor) {
5537
+ this.editor.value = String(value ?? '');
5538
+ }
5539
+ }
5540
+ /**
5541
+ * Get the CodeMirror instance (if needed for advanced usage)
5542
+ */
5543
+ getEditorInstance() {
5544
+ return this.editor;
5545
+ }
5546
+ }
5547
+
4728
5548
  /**
4729
5549
  * Custom cell editors for ngx-smart-table
4730
5550
  */
@@ -4957,17 +5777,19 @@ class StCellComponent {
4957
5777
  constructor() {
4958
5778
  this.destroyRef = inject(DestroyRef);
4959
5779
  // Signal-based inputs
4960
- this.cell = input.required(...(ngDevMode ? [{ debugName: "cell" }] : []));
4961
- this.editMode = input(EditMode.CLICK, ...(ngDevMode ? [{ debugName: "editMode" }] : []));
4962
- this.tableState = input(undefined, ...(ngDevMode ? [{ debugName: "tableState" }] : []));
4963
- this.tableConfig = input(undefined, ...(ngDevMode ? [{ debugName: "tableConfig" }] : []));
4964
- this.columnIndex = input(undefined, ...(ngDevMode ? [{ debugName: "columnIndex" }] : []));
5780
+ this.cell = input.required(...(ngDevMode ? [{ debugName: "cell" }] : /* istanbul ignore next */ []));
5781
+ this.editMode = input(EditMode.CLICK, ...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
5782
+ this.tableState = input(undefined, ...(ngDevMode ? [{ debugName: "tableState" }] : /* istanbul ignore next */ []));
5783
+ this.tableConfig = input(undefined, ...(ngDevMode ? [{ debugName: "tableConfig" }] : /* istanbul ignore next */ []));
5784
+ this.columnIndex = input(undefined, ...(ngDevMode ? [{ debugName: "columnIndex" }] : /* istanbul ignore next */ []));
4965
5785
  // Signal-based outputs
4966
5786
  this.cellChange = output();
4967
5787
  this.cellEdit = output();
4968
5788
  this.cellSave = output();
4969
5789
  this.cellCancel = output();
4970
5790
  this.cellSaveAndNavigate = output();
5791
+ this.cellLoading = false;
5792
+ this.cdr = inject(ChangeDetectorRef);
4971
5793
  // Computed signals for derived state
4972
5794
  this.isEditable = computed(() => {
4973
5795
  const cellValue = this.cell();
@@ -4975,7 +5797,7 @@ class StCellComponent {
4975
5797
  return false;
4976
5798
  const config = cellValue.getColumnConfig();
4977
5799
  return config.editable ?? false;
4978
- }, ...(ngDevMode ? [{ debugName: "isEditable" }] : []));
5800
+ }, ...(ngDevMode ? [{ debugName: "isEditable" }] : /* istanbul ignore next */ []));
4979
5801
  this.validationError = computed(() => {
4980
5802
  const cellValue = this.cell();
4981
5803
  if (!cellValue)
@@ -4991,20 +5813,20 @@ class StCellComponent {
4991
5813
  return 'Invalid value';
4992
5814
  }
4993
5815
  return undefined;
4994
- }, ...(ngDevMode ? [{ debugName: "validationError" }] : []));
5816
+ }, ...(ngDevMode ? [{ debugName: "validationError" }] : /* istanbul ignore next */ []));
4995
5817
  this.hasCellTemplate = computed(() => {
4996
5818
  const cellValue = this.cell();
4997
5819
  if (!cellValue)
4998
5820
  return false;
4999
5821
  const config = cellValue.getColumnConfig();
5000
5822
  return !!config.cellTemplate;
5001
- }, ...(ngDevMode ? [{ debugName: "hasCellTemplate" }] : []));
5823
+ }, ...(ngDevMode ? [{ debugName: "hasCellTemplate" }] : /* istanbul ignore next */ []));
5002
5824
  this.cellTemplate = computed(() => {
5003
5825
  const cellValue = this.cell();
5004
5826
  if (!cellValue)
5005
5827
  return null;
5006
5828
  return cellValue.getColumnConfig().cellTemplate || null;
5007
- }, ...(ngDevMode ? [{ debugName: "cellTemplate" }] : []));
5829
+ }, ...(ngDevMode ? [{ debugName: "cellTemplate" }] : /* istanbul ignore next */ []));
5008
5830
  this.templateContext = computed(() => {
5009
5831
  const cellValue = this.cell();
5010
5832
  if (!cellValue)
@@ -5015,23 +5837,38 @@ class StCellComponent {
5015
5837
  rowData: cellValue.getRowData(),
5016
5838
  rowIndex: cellValue.getRowIndex()
5017
5839
  };
5018
- }, ...(ngDevMode ? [{ debugName: "templateContext" }] : []));
5840
+ }, ...(ngDevMode ? [{ debugName: "templateContext" }] : /* istanbul ignore next */ []));
5019
5841
  }
5020
5842
  ngOnInit() {
5843
+ const cellValue = this.cell();
5844
+ // Subscribe to cell state changes for loading indicator
5845
+ if (cellValue) {
5846
+ cellValue.onStateChange(() => {
5847
+ this.cellLoading = !!cellValue.getState().isLoading;
5848
+ try {
5849
+ this.cdr.detectChanges();
5850
+ }
5851
+ catch {
5852
+ // View may have been destroyed; safely ignore
5853
+ }
5854
+ });
5855
+ // Pick up loading state that was set before this component was created
5856
+ this.cellLoading = !!cellValue.getState().isLoading;
5857
+ }
5021
5858
  const tableStateValue = this.tableState();
5022
5859
  const colIndex = this.columnIndex();
5023
5860
  if (tableStateValue && colIndex !== undefined) {
5024
5861
  tableStateValue.editingCellPosition$
5025
5862
  .pipe(takeUntilDestroyed(this.destroyRef))
5026
5863
  .subscribe(position => {
5027
- const cellValue = this.cell();
5028
- if (!cellValue)
5864
+ const cellVal = this.cell();
5865
+ if (!cellVal)
5029
5866
  return;
5030
- const rowIndex = cellValue.getRowIndex();
5031
- if (cellValue.isEditing() && rowIndex !== undefined) {
5867
+ const rowIndex = cellVal.getRowIndex();
5868
+ if (cellVal.isEditing() && rowIndex !== undefined) {
5032
5869
  if (position &&
5033
5870
  (position.rowIndex !== rowIndex || position.columnIndex !== colIndex)) {
5034
- this.saveEdit(cellValue.getValue());
5871
+ this.saveEdit(cellVal.getValue());
5035
5872
  }
5036
5873
  }
5037
5874
  });
@@ -5304,12 +6141,12 @@ class StCellComponent {
5304
6141
  this.editorCleanup = undefined;
5305
6142
  }
5306
6143
  }
5307
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5308
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StCellComponent, isStandalone: true, selector: "st-cell", inputs: { cell: { classPropertyName: "cell", publicName: "cell", isSignal: true, isRequired: true, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null }, tableState: { classPropertyName: "tableState", publicName: "tableState", isSignal: true, isRequired: false, transformFunction: null }, tableConfig: { classPropertyName: "tableConfig", publicName: "tableConfig", isSignal: true, isRequired: false, transformFunction: null }, columnIndex: { classPropertyName: "columnIndex", publicName: "columnIndex", isSignal: true, isRequired: false, transformFunction: null } }, 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 @if (!cell().isEditing()) {\n <!-- Custom Template -->\n @if (hasCellTemplate()) {\n <ng-container *ngTemplateOutlet=\"cellTemplate(); context: templateContext()\"></ng-container>\n }\n\n <!-- Default Text Rendering -->\n @if (!hasCellTemplate()) {\n <span class=\"cell-display\">\n {{ cell().render() }}\n </span>\n }\n }\n\n <!-- Edit Mode -->\n @if (cell().isEditing()) {\n <div class=\"cell-editor\" #editorContainer>\n </div>\n }\n</div>\n", 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"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
6144
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6145
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StCellComponent, isStandalone: true, selector: "st-cell", inputs: { cell: { classPropertyName: "cell", publicName: "cell", isSignal: true, isRequired: true, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null }, tableState: { classPropertyName: "tableState", publicName: "tableState", isSignal: true, isRequired: false, transformFunction: null }, tableConfig: { classPropertyName: "tableConfig", publicName: "tableConfig", isSignal: true, isRequired: false, transformFunction: null }, columnIndex: { classPropertyName: "columnIndex", publicName: "columnIndex", isSignal: true, isRequired: false, transformFunction: null } }, 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 @if (!cell().isEditing() && !cellLoading) {\n <!-- Custom Template -->\n @if (hasCellTemplate()) {\n <ng-container *ngTemplateOutlet=\"cellTemplate(); context: templateContext()\"></ng-container>\n }\n\n <!-- Default Text Rendering -->\n @if (!hasCellTemplate()) {\n <span class=\"cell-display\">\n {{ cell().render() }}\n </span>\n }\n }\n\n <!-- Edit Mode -->\n @if (cell().isEditing()) {\n <div class=\"cell-editor\" #editorContainer>\n </div>\n }\n</div>\n", 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"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
5309
6146
  }
5310
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StCellComponent, decorators: [{
6147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StCellComponent, decorators: [{
5311
6148
  type: Component,
5312
- args: [{ selector: 'st-cell', standalone: true, imports: [CommonModule], 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 @if (!cell().isEditing()) {\n <!-- Custom Template -->\n @if (hasCellTemplate()) {\n <ng-container *ngTemplateOutlet=\"cellTemplate(); context: templateContext()\"></ng-container>\n }\n\n <!-- Default Text Rendering -->\n @if (!hasCellTemplate()) {\n <span class=\"cell-display\">\n {{ cell().render() }}\n </span>\n }\n }\n\n <!-- Edit Mode -->\n @if (cell().isEditing()) {\n <div class=\"cell-editor\" #editorContainer>\n </div>\n }\n</div>\n", 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"] }]
6149
+ args: [{ selector: 'st-cell', standalone: true, imports: [CommonModule], 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 @if (!cell().isEditing() && !cellLoading) {\n <!-- Custom Template -->\n @if (hasCellTemplate()) {\n <ng-container *ngTemplateOutlet=\"cellTemplate(); context: templateContext()\"></ng-container>\n }\n\n <!-- Default Text Rendering -->\n @if (!hasCellTemplate()) {\n <span class=\"cell-display\">\n {{ cell().render() }}\n </span>\n }\n }\n\n <!-- Edit Mode -->\n @if (cell().isEditing()) {\n <div class=\"cell-editor\" #editorContainer>\n </div>\n }\n</div>\n", 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"] }]
5313
6150
  }], propDecorators: { cell: [{ type: i0.Input, args: [{ isSignal: true, alias: "cell", required: true }] }], editMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editMode", required: false }] }], tableState: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableState", required: false }] }], tableConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableConfig", required: false }] }], columnIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnIndex", required: false }] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], cellEdit: [{ type: i0.Output, args: ["cellEdit"] }], cellSave: [{ type: i0.Output, args: ["cellSave"] }], cellCancel: [{ type: i0.Output, args: ["cellCancel"] }], cellSaveAndNavigate: [{ type: i0.Output, args: ["cellSaveAndNavigate"] }], editorContainer: [{
5314
6151
  type: ViewChild,
5315
6152
  args: ['editorContainer', { read: ElementRef }]
@@ -6079,10 +6916,10 @@ class ValidationLoggerService {
6079
6916
  getLogSize() {
6080
6917
  return this.logEntries.length;
6081
6918
  }
6082
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ValidationLoggerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6083
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ValidationLoggerService, providedIn: 'root' }); }
6919
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ValidationLoggerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6920
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ValidationLoggerService, providedIn: 'root' }); }
6084
6921
  }
6085
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ValidationLoggerService, decorators: [{
6922
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ValidationLoggerService, decorators: [{
6086
6923
  type: Injectable,
6087
6924
  args: [{
6088
6925
  providedIn: 'root'
@@ -6289,10 +7126,10 @@ class JsonSchemaValidatorService {
6289
7126
  return error.message || `Field '${field}' is invalid`;
6290
7127
  }
6291
7128
  }
6292
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: JsonSchemaValidatorService, deps: [{ token: ValidationLoggerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
6293
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: JsonSchemaValidatorService, providedIn: 'root' }); }
7129
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: JsonSchemaValidatorService, deps: [{ token: ValidationLoggerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
7130
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: JsonSchemaValidatorService, providedIn: 'root' }); }
6294
7131
  }
6295
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: JsonSchemaValidatorService, decorators: [{
7132
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: JsonSchemaValidatorService, decorators: [{
6296
7133
  type: Injectable,
6297
7134
  args: [{
6298
7135
  providedIn: 'root'
@@ -6340,10 +7177,10 @@ class VirtualScrollService {
6340
7177
  return fromEvent(element, 'scroll').pipe(map((event) => event.target.scrollTop), throttleTime(16, undefined, { leading: true, trailing: true }) // 60fps
6341
7178
  );
6342
7179
  }
6343
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VirtualScrollService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6344
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VirtualScrollService }); }
7180
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: VirtualScrollService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7181
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: VirtualScrollService }); }
6345
7182
  }
6346
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VirtualScrollService, decorators: [{
7183
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: VirtualScrollService, decorators: [{
6347
7184
  type: Injectable
6348
7185
  }] });
6349
7186
 
@@ -6418,10 +7255,10 @@ class StPaginationComponent {
6418
7255
  this.tableState.setPageSize(newPageSize);
6419
7256
  }
6420
7257
  }
6421
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6422
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.0", type: StPaginationComponent, isStandalone: true, selector: "st-pagination", inputs: { tableState: "tableState", tableConfig: "tableConfig", position: "position" }, ngImport: i0, template: "<nile-pagination\n [totalItems]=\"paginationState.totalItems\"\n [currentPage]=\"getCurrentPageDisplay()\"\n [pageSize]=\"paginationState.pageSize\"\n [variant]=\"getVariant()\"\n [pageSizeOptions]=\"getPageSizeOptions()\"\n (pageChange)=\"onPageChange($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\">\n</nile-pagination>\n", styles: [":host{display:block;width:100%}nile-pagination{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
7258
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7259
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: StPaginationComponent, isStandalone: true, selector: "st-pagination", inputs: { tableState: "tableState", tableConfig: "tableConfig", position: "position" }, ngImport: i0, template: "<nile-pagination\n [totalItems]=\"paginationState.totalItems\"\n [currentPage]=\"getCurrentPageDisplay()\"\n [pageSize]=\"paginationState.pageSize\"\n [variant]=\"getVariant()\"\n [pageSizeOptions]=\"getPageSizeOptions()\"\n (pageChange)=\"onPageChange($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\">\n</nile-pagination>\n", styles: [":host{display:block;width:100%}nile-pagination{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
6423
7260
  }
6424
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StPaginationComponent, decorators: [{
7261
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StPaginationComponent, decorators: [{
6425
7262
  type: Component,
6426
7263
  args: [{ selector: 'st-pagination', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<nile-pagination\n [totalItems]=\"paginationState.totalItems\"\n [currentPage]=\"getCurrentPageDisplay()\"\n [pageSize]=\"paginationState.pageSize\"\n [variant]=\"getVariant()\"\n [pageSizeOptions]=\"getPageSizeOptions()\"\n (pageChange)=\"onPageChange($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\">\n</nile-pagination>\n", styles: [":host{display:block;width:100%}nile-pagination{display:block;width:100%}\n"] }]
6427
7264
  }], propDecorators: { tableState: [{
@@ -6555,10 +7392,10 @@ class StHeaderComponent {
6555
7392
  };
6556
7393
  this.columnMoved.emit(moveEvent);
6557
7394
  }
6558
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6559
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StHeaderComponent, isStandalone: true, selector: "st-header", inputs: { column: "column", columnIndex: "columnIndex", isFirstColumn: "isFirstColumn", isLastColumn: "isLastColumn", tableState: "tableState", enableSorting: "enableSorting", enableFiltering: "enableFiltering" }, outputs: { sortToggle: "sortToggle", filterChange: "filterChange", columnMoved: "columnMoved", menuClick: "menuClick" }, ngImport: i0, template: "<div class=\"st-header\" [class.sortable]=\"isSortable()\" [class.sorted]=\"isSorted()\" [attr.aria-sort]=\"getAriaSort()\">\n <div class=\"header-content\">\n <span class=\"header-text\">{{ column.header || column.key }}</span>\n @if (isMenuEnabled()) {\n <button class=\"column-menu-trigger\" \n (click)=\"onMenuClick($event)\"\n type=\"button\" \n aria-label=\"Column actions\">\n <nile-icon name=\"options\"></nile-icon>\n </button>\n }\n </div>\n</div>\n", styles: [".st-header{position:relative;text-align:left;padding-left:8px}.st-header.sortable{cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s}.st-header.resizing{-webkit-user-select:none;user-select:none;cursor:col-resize}.st-header.align-center{text-align:center}.st-header.align-center .header-content{justify-content:center}.st-header.align-right{text-align:right}.st-header.align-right .header-content{justify-content:flex-end}.st-header .header-content{display:flex;align-items:center;gap:8px}.st-header .header-text{flex:1;font-size:12px;font-weight:500;letter-spacing:.2px;line-height:14px}.st-header .column-menu-trigger{background:none;border:none;padding:4px;cursor:pointer;border-radius:4px;display:flex;align-items:center;justify-content:center}.st-header .column-menu-trigger nile-icon{font-size:16px;pointer-events:none}.st-header .resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;z-index:10}.st-header .resize-handle:after{content:\"\";position:absolute;top:50%;right:3px;transform:translateY(-50%);width:2px;height:20px;background-color:#cbd5e0;opacity:0;transition:opacity .2s}.st-header .resize-handle:hover:after,.st-header .resize-handle:active:after{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
7395
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7396
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StHeaderComponent, isStandalone: true, selector: "st-header", inputs: { column: "column", columnIndex: "columnIndex", isFirstColumn: "isFirstColumn", isLastColumn: "isLastColumn", tableState: "tableState", enableSorting: "enableSorting", enableFiltering: "enableFiltering" }, outputs: { sortToggle: "sortToggle", filterChange: "filterChange", columnMoved: "columnMoved", menuClick: "menuClick" }, ngImport: i0, template: "<div class=\"st-header\" [class.sortable]=\"isSortable()\" [class.sorted]=\"isSorted()\" [attr.aria-sort]=\"getAriaSort()\">\n <div class=\"header-content\">\n <span class=\"header-text\">{{ column.header || column.key }}</span>\n @if (isMenuEnabled()) {\n <button class=\"column-menu-trigger\" \n (click)=\"onMenuClick($event)\"\n type=\"button\" \n aria-label=\"Column actions\">\n <nile-icon name=\"options\"></nile-icon>\n </button>\n }\n </div>\n</div>\n", styles: [".st-header{position:relative;text-align:left;padding-left:8px}.st-header.sortable{cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s}.st-header.resizing{-webkit-user-select:none;user-select:none;cursor:col-resize}.st-header.align-center{text-align:center}.st-header.align-center .header-content{justify-content:center}.st-header.align-right{text-align:right}.st-header.align-right .header-content{justify-content:flex-end}.st-header .header-content{display:flex;align-items:center;gap:8px}.st-header .header-text{flex:1;font-size:12px;font-weight:500;letter-spacing:.2px;line-height:14px}.st-header .column-menu-trigger{background:none;border:none;padding:4px;cursor:pointer;border-radius:4px;display:flex;align-items:center;justify-content:center}.st-header .column-menu-trigger nile-icon{font-size:16px;pointer-events:none}.st-header .resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;z-index:10}.st-header .resize-handle:after{content:\"\";position:absolute;top:50%;right:3px;transform:translateY(-50%);width:2px;height:20px;background-color:#cbd5e0;opacity:0;transition:opacity .2s}.st-header .resize-handle:hover:after,.st-header .resize-handle:active:after{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
6560
7397
  }
6561
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StHeaderComponent, decorators: [{
7398
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StHeaderComponent, decorators: [{
6562
7399
  type: Component,
6563
7400
  args: [{ selector: 'st-header', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"st-header\" [class.sortable]=\"isSortable()\" [class.sorted]=\"isSorted()\" [attr.aria-sort]=\"getAriaSort()\">\n <div class=\"header-content\">\n <span class=\"header-text\">{{ column.header || column.key }}</span>\n @if (isMenuEnabled()) {\n <button class=\"column-menu-trigger\" \n (click)=\"onMenuClick($event)\"\n type=\"button\" \n aria-label=\"Column actions\">\n <nile-icon name=\"options\"></nile-icon>\n </button>\n }\n </div>\n</div>\n", styles: [".st-header{position:relative;text-align:left;padding-left:8px}.st-header.sortable{cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s}.st-header.resizing{-webkit-user-select:none;user-select:none;cursor:col-resize}.st-header.align-center{text-align:center}.st-header.align-center .header-content{justify-content:center}.st-header.align-right{text-align:right}.st-header.align-right .header-content{justify-content:flex-end}.st-header .header-content{display:flex;align-items:center;gap:8px}.st-header .header-text{flex:1;font-size:12px;font-weight:500;letter-spacing:.2px;line-height:14px}.st-header .column-menu-trigger{background:none;border:none;padding:4px;cursor:pointer;border-radius:4px;display:flex;align-items:center;justify-content:center}.st-header .column-menu-trigger nile-icon{font-size:16px;pointer-events:none}.st-header .resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;z-index:10}.st-header .resize-handle:after{content:\"\";position:absolute;top:50%;right:3px;transform:translateY(-50%);width:2px;height:20px;background-color:#cbd5e0;opacity:0;transition:opacity .2s}.st-header .resize-handle:hover:after,.st-header .resize-handle:active:after{opacity:1}\n"] }]
6564
7401
  }], propDecorators: { column: [{
@@ -6736,10 +7573,10 @@ class StTableActionsComponent {
6736
7573
  isColumnHideable(column) {
6737
7574
  return column.hideable !== false; // Default to true if not set
6738
7575
  }
6739
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StTableActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6740
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StTableActionsComponent, isStandalone: true, selector: "st-table-actions", inputs: { tableState: "tableState", allowAddColumn: "allowAddColumn" }, outputs: { addColumnClicked: "addColumnClicked" }, ngImport: i0, template: "<button \n class=\"table-actions-button\"\n (click)=\"toggleMenu($event)\"\n type=\"button\"\n title=\"Table Actions\"\n aria-label=\"Table actions menu\"\n [class.active]=\"isOpen\">\n <nile-icon name=\"settings\"></nile-icon>\n</button>\n\n<!-- Dropdown container with shared pattern -->\n@if (isOpen) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closeMenu()\"></div>\n \n <!-- Main Menu -->\n @if (currentView === 'main') {\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n <!-- Add Column -->\n @if (allowAddColumn) {\n <nile-menu-item (click)=\"onAddColumn($event)\">\n <nile-icon slot=\"prefix\" name=\"plus\" size=\"12\"></nile-icon>\n Add Column\n </nile-menu-item>\n }\n \n <!-- Show/Hide Columns -->\n <nile-menu-item (click)=\"openColumnsSubmenu($event)\">\n <nile-icon size=\"12\" slot=\"prefix\" name=\"eye\"></nile-icon>\n Show/Hide Columns\n </nile-menu-item>\n </nile-menu>\n </div>\n }\n \n <!-- Column Visibility Submenu -->\n @if (currentView === 'columns') {\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n <!-- Back button -->\n <nile-menu-item (click)=\"backToMain($event)\" class=\"back-item\">\n <nile-icon size=\"12\" slot=\"prefix\" name=\"chevron-left\"></nile-icon>\n Back\n </nile-menu-item>\n \n <nile-divider></nile-divider>\n \n <!-- Column checkboxes -->\n @for (column of columnsVisibility; track column.key) {\n <nile-menu-item \n [class.disabled]=\"!isColumnHideable(column)\"\n (click)=\"onToggleColumn(column.key, $event)\">\n <nile-checkbox \n [checked]=\"isColumnVisible(column.key)\" \n [disabled]=\"!isColumnHideable(column)\" \n [label]=\"column.header || column.key\" \n (nile-change)=\"onToggleColumn(column.key, $event)\">\n </nile-checkbox>\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n }\n </div>\n}\n", styles: [".table-actions-button{display:flex;align-items:center;justify-content:center;padding:6px;background:transparent;border:none;cursor:pointer;transition:background-color .15s}.table-actions-button:hover{background-color:#0000000d}.table-actions-button.active{background-color:#0000001a}.table-actions-button:focus{outline:none}.dropdown-container{position:fixed;inset:0;z-index:9996}.dropdown-backdrop{position:absolute;inset:0;background:transparent;pointer-events:auto;z-index:9996}.dropdown-menu{position:fixed;pointer-events:auto;z-index:9997;min-width:15rem}nile-menu{max-height:30rem;overflow-y:auto}nile-menu::part(base){width:fit-content;min-height:auto}nile-menu nile-menu-item::part(base){min-height:2.5rem}nile-menu nile-menu-item::part(label){font-size:12px}nile-menu nile-menu-item.back-item{font-weight:500}nile-menu nile-menu-item.disabled{opacity:.5;cursor:not-allowed}nile-menu nile-menu-item nile-checkbox::part(base){display:flex;align-items:center}nile-menu nile-menu-item nile-checkbox::part(label){font-size:12px;margin-top:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
7576
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StTableActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7577
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StTableActionsComponent, isStandalone: true, selector: "st-table-actions", inputs: { tableState: "tableState", allowAddColumn: "allowAddColumn" }, outputs: { addColumnClicked: "addColumnClicked" }, ngImport: i0, template: "<button \n class=\"table-actions-button\"\n (click)=\"toggleMenu($event)\"\n type=\"button\"\n title=\"Table Actions\"\n aria-label=\"Table actions menu\"\n [class.active]=\"isOpen\">\n <nile-icon name=\"settings\"></nile-icon>\n</button>\n\n<!-- Dropdown container with shared pattern -->\n@if (isOpen) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closeMenu()\"></div>\n \n <!-- Main Menu -->\n @if (currentView === 'main') {\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n <!-- Add Column -->\n @if (allowAddColumn) {\n <nile-menu-item (click)=\"onAddColumn($event)\">\n <nile-icon slot=\"prefix\" name=\"plus\" size=\"12\"></nile-icon>\n Add Column\n </nile-menu-item>\n }\n \n <!-- Show/Hide Columns -->\n <nile-menu-item (click)=\"openColumnsSubmenu($event)\">\n <nile-icon size=\"12\" slot=\"prefix\" name=\"eye\"></nile-icon>\n Show/Hide Columns\n </nile-menu-item>\n </nile-menu>\n </div>\n }\n \n <!-- Column Visibility Submenu -->\n @if (currentView === 'columns') {\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n <!-- Back button -->\n <nile-menu-item (click)=\"backToMain($event)\" class=\"back-item\">\n <nile-icon size=\"12\" slot=\"prefix\" name=\"chevron-left\"></nile-icon>\n Back\n </nile-menu-item>\n \n <nile-divider></nile-divider>\n \n <!-- Column checkboxes -->\n @for (column of columnsVisibility; track column.key) {\n <nile-menu-item \n [class.disabled]=\"!isColumnHideable(column)\"\n (click)=\"onToggleColumn(column.key, $event)\">\n <nile-checkbox \n [checked]=\"isColumnVisible(column.key)\" \n [disabled]=\"!isColumnHideable(column)\" \n [label]=\"column.header || column.key\" \n (nile-change)=\"onToggleColumn(column.key, $event)\">\n </nile-checkbox>\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n }\n </div>\n}\n", styles: [".table-actions-button{display:flex;align-items:center;justify-content:center;padding:6px;background:transparent;border:none;cursor:pointer;transition:background-color .15s}.table-actions-button:hover{background-color:#0000000d}.table-actions-button.active{background-color:#0000001a}.table-actions-button:focus{outline:none}.dropdown-container{position:fixed;inset:0;z-index:9996}.dropdown-backdrop{position:absolute;inset:0;background:transparent;pointer-events:auto;z-index:9996}.dropdown-menu{position:fixed;pointer-events:auto;z-index:9997;min-width:15rem}nile-menu{max-height:30rem;overflow-y:auto}nile-menu::part(base){width:fit-content;min-height:auto}nile-menu nile-menu-item::part(base){min-height:2.5rem}nile-menu nile-menu-item::part(label){font-size:12px}nile-menu nile-menu-item.back-item{font-weight:500}nile-menu nile-menu-item.disabled{opacity:.5;cursor:not-allowed}nile-menu nile-menu-item nile-checkbox::part(base){display:flex;align-items:center}nile-menu nile-menu-item nile-checkbox::part(label){font-size:12px;margin-top:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
6741
7578
  }
6742
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StTableActionsComponent, decorators: [{
7579
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StTableActionsComponent, decorators: [{
6743
7580
  type: Component,
6744
7581
  args: [{ selector: 'st-table-actions', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<button \n class=\"table-actions-button\"\n (click)=\"toggleMenu($event)\"\n type=\"button\"\n title=\"Table Actions\"\n aria-label=\"Table actions menu\"\n [class.active]=\"isOpen\">\n <nile-icon name=\"settings\"></nile-icon>\n</button>\n\n<!-- Dropdown container with shared pattern -->\n@if (isOpen) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closeMenu()\"></div>\n \n <!-- Main Menu -->\n @if (currentView === 'main') {\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n <!-- Add Column -->\n @if (allowAddColumn) {\n <nile-menu-item (click)=\"onAddColumn($event)\">\n <nile-icon slot=\"prefix\" name=\"plus\" size=\"12\"></nile-icon>\n Add Column\n </nile-menu-item>\n }\n \n <!-- Show/Hide Columns -->\n <nile-menu-item (click)=\"openColumnsSubmenu($event)\">\n <nile-icon size=\"12\" slot=\"prefix\" name=\"eye\"></nile-icon>\n Show/Hide Columns\n </nile-menu-item>\n </nile-menu>\n </div>\n }\n \n <!-- Column Visibility Submenu -->\n @if (currentView === 'columns') {\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n <!-- Back button -->\n <nile-menu-item (click)=\"backToMain($event)\" class=\"back-item\">\n <nile-icon size=\"12\" slot=\"prefix\" name=\"chevron-left\"></nile-icon>\n Back\n </nile-menu-item>\n \n <nile-divider></nile-divider>\n \n <!-- Column checkboxes -->\n @for (column of columnsVisibility; track column.key) {\n <nile-menu-item \n [class.disabled]=\"!isColumnHideable(column)\"\n (click)=\"onToggleColumn(column.key, $event)\">\n <nile-checkbox \n [checked]=\"isColumnVisible(column.key)\" \n [disabled]=\"!isColumnHideable(column)\" \n [label]=\"column.header || column.key\" \n (nile-change)=\"onToggleColumn(column.key, $event)\">\n </nile-checkbox>\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n }\n </div>\n}\n", styles: [".table-actions-button{display:flex;align-items:center;justify-content:center;padding:6px;background:transparent;border:none;cursor:pointer;transition:background-color .15s}.table-actions-button:hover{background-color:#0000000d}.table-actions-button.active{background-color:#0000001a}.table-actions-button:focus{outline:none}.dropdown-container{position:fixed;inset:0;z-index:9996}.dropdown-backdrop{position:absolute;inset:0;background:transparent;pointer-events:auto;z-index:9996}.dropdown-menu{position:fixed;pointer-events:auto;z-index:9997;min-width:15rem}nile-menu{max-height:30rem;overflow-y:auto}nile-menu::part(base){width:fit-content;min-height:auto}nile-menu nile-menu-item::part(base){min-height:2.5rem}nile-menu nile-menu-item::part(label){font-size:12px}nile-menu nile-menu-item.back-item{font-weight:500}nile-menu nile-menu-item.disabled{opacity:.5;cursor:not-allowed}nile-menu nile-menu-item nile-checkbox::part(base){display:flex;align-items:center}nile-menu nile-menu-item nile-checkbox::part(label){font-size:12px;margin-top:0}\n"] }]
6745
7582
  }], ctorParameters: () => [], propDecorators: { tableState: [{
@@ -7097,10 +7934,10 @@ class StColumnFilterComponent {
7097
7934
  // Align left for first 2 columns to prevent clipping
7098
7935
  return this.columnIndex <= 1;
7099
7936
  }
7100
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7101
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StColumnFilterComponent, isStandalone: true, selector: "st-column-filter", inputs: { column: "column", tableState: "tableState", columnIndex: "columnIndex", isFirstColumn: "isFirstColumn", isLastColumn: "isLastColumn", isOpen: "isOpen", filterContext: "filterContext" }, outputs: { closed: "closed", filterApplied: "filterApplied", filterCleared: "filterCleared" }, viewQueries: [{ propertyName: "filterAnchor", first: true, predicate: ["filterAnchor"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Popover content -->\n<div class=\"filter-content\">\n <!-- Operator Select -->\n @if (availableOperators.length > 1) {\n <nile-select \n label=\"Operator\"\n [value]=\"selectedOperator\"\n (nile-change)=\"onOperatorChange($event)\"\n class=\"filter-operator\">\n @for (op of availableOperators; track op.value) {\n <nile-option [value]=\"op.value\">\n {{ op.label }}\n </nile-option>\n }\n </nile-select>\n }\n \n <!-- Input Field based on type -->\n <div class=\"filter-value-section\">\n \n <!-- Text Input -->\n @if (inputType === 'text') {\n <nile-input \n type=\"text\"\n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"Enter value...\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Number Input -->\n @if (inputType === 'number') {\n <nile-input \n type=\"number\"\n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"Enter number...\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Date Input -->\n @if (inputType === 'date') {\n <nile-input \n type=\"date\"\n label=\"Value\"\n [value]=\"filterValue\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Checkbox Input -->\n @if (inputType === 'checkbox') {\n <nile-checkbox\n [checked]=\"filterValue\"\n (nile-change)=\"onCheckboxChange($event)\"\n class=\"filter-checkbox\">\n {{ filterValue ? 'True' : 'False' }}\n </nile-checkbox>\n }\n \n <!-- Single Select Dropdown -->\n @if (inputType === 'select') {\n <nile-select \n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"-- Select --\"\n (nile-change)=\"onSelectChange($event)\"\n class=\"filter-value-select\">\n @for (option of dropdownOptions; track option.value) {\n <nile-option [value]=\"option.value\">\n {{ option.label }}\n </nile-option>\n }\n </nile-select>\n }\n \n <!-- Multi-Select with Radio Group as example (or keep checkboxes) -->\n @if (inputType === 'multiselect') {\n <div class=\"filter-multiselect\">\n <label class=\"multiselect-title\">Select Values</label>\n <div class=\"multiselect-options\">\n @for (option of dropdownOptions; track option.value) {\n <nile-checkbox\n [checked]=\"isValueSelected(option.value)\"\n [value]=\"option.value\"\n (nile-change)=\"onMultiselectCheckboxChange($event, option.value)\"\n class=\"multiselect-checkbox\">\n {{ option.label }}\n </nile-checkbox>\n }\n </div>\n @if (dropdownOptions.length === 0) {\n <div class=\"empty-state\">\n No options available\n </div>\n }\n </div>\n }\n </div>\n \n <!-- Action Buttons -->\n <div class=\"filter-actions\">\n <nile-button \n variant=\"primary\"\n size=\"small\"\n (click)=\"onApply()\">\n Apply\n </nile-button>\n <nile-button \n variant=\"default\"\n size=\"small\"\n (click)=\"onClear()\">\n Clear\n </nile-button>\n </div>\n</div>\n", styles: [".filter-content{padding:16px;display:flex;flex-direction:column;gap:16px}.filter-content nile-select,.filter-content nile-input,.filter-content nile-checkbox{width:100%}.filter-content .filter-operator,.filter-content .filter-value-input,.filter-content .filter-value-select{margin-bottom:0}.filter-value-section{display:flex;flex-direction:column;gap:12px}.filter-value-section nile-checkbox{margin-top:8px}.filter-multiselect{display:flex;flex-direction:column;gap:8px}.filter-multiselect .multiselect-title{display:block;font-size:13px;font-weight:600;color:#2d3748;margin-bottom:8px}.filter-multiselect .multiselect-options{max-height:200px;overflow-y:auto;border:1px solid #cbd5e0;border-radius:4px;padding:8px;background-color:#f7fafc;display:flex;flex-direction:column;gap:6px}.filter-multiselect .multiselect-options nile-checkbox{width:100%}.filter-multiselect .multiselect-options nile-checkbox::part(base){padding:4px 8px;border-radius:4px;transition:background-color .15s}.filter-multiselect .multiselect-options nile-checkbox:hover::part(base){background-color:#edf2f7}.filter-multiselect .empty-state{padding:12px;text-align:center;color:#718096;font-size:13px}.filter-actions{display:flex;gap:8px;justify-content:flex-end;padding-top:12px;border-top:1px solid #e2e8f0;margin-top:4px}.filter-actions nile-button{flex:0 0 auto}.multiselect-options::-webkit-scrollbar{width:6px}.multiselect-options::-webkit-scrollbar-track{background:#edf2f7;border-radius:3px}.multiselect-options::-webkit-scrollbar-thumb{background:#cbd5e0;border-radius:3px}.multiselect-options::-webkit-scrollbar-thumb:hover{background:#a0aec0}nile-input::part(base){width:100%}nile-select::part(base){width:100%}nile-button::part(base){min-width:80px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
7937
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7938
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StColumnFilterComponent, isStandalone: true, selector: "st-column-filter", inputs: { column: "column", tableState: "tableState", columnIndex: "columnIndex", isFirstColumn: "isFirstColumn", isLastColumn: "isLastColumn", isOpen: "isOpen", filterContext: "filterContext" }, outputs: { closed: "closed", filterApplied: "filterApplied", filterCleared: "filterCleared" }, viewQueries: [{ propertyName: "filterAnchor", first: true, predicate: ["filterAnchor"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Popover content -->\n<div class=\"filter-content\">\n <!-- Operator Select -->\n @if (availableOperators.length > 1) {\n <nile-select \n label=\"Operator\"\n [value]=\"selectedOperator\"\n (nile-change)=\"onOperatorChange($event)\"\n class=\"filter-operator\">\n @for (op of availableOperators; track op.value) {\n <nile-option [value]=\"op.value\">\n {{ op.label }}\n </nile-option>\n }\n </nile-select>\n }\n \n <!-- Input Field based on type -->\n <div class=\"filter-value-section\">\n \n <!-- Text Input -->\n @if (inputType === 'text') {\n <nile-input \n type=\"text\"\n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"Enter value...\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Number Input -->\n @if (inputType === 'number') {\n <nile-input \n type=\"number\"\n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"Enter number...\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Date Input -->\n @if (inputType === 'date') {\n <nile-input \n type=\"date\"\n label=\"Value\"\n [value]=\"filterValue\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Checkbox Input -->\n @if (inputType === 'checkbox') {\n <nile-checkbox\n [checked]=\"filterValue\"\n (nile-change)=\"onCheckboxChange($event)\"\n class=\"filter-checkbox\">\n {{ filterValue ? 'True' : 'False' }}\n </nile-checkbox>\n }\n \n <!-- Single Select Dropdown -->\n @if (inputType === 'select') {\n <nile-select \n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"-- Select --\"\n (nile-change)=\"onSelectChange($event)\"\n class=\"filter-value-select\">\n @for (option of dropdownOptions; track option.value) {\n <nile-option [value]=\"option.value\">\n {{ option.label }}\n </nile-option>\n }\n </nile-select>\n }\n \n <!-- Multi-Select with Radio Group as example (or keep checkboxes) -->\n @if (inputType === 'multiselect') {\n <div class=\"filter-multiselect\">\n <label class=\"multiselect-title\">Select Values</label>\n <div class=\"multiselect-options\">\n @for (option of dropdownOptions; track option.value) {\n <nile-checkbox\n [checked]=\"isValueSelected(option.value)\"\n [value]=\"option.value\"\n (nile-change)=\"onMultiselectCheckboxChange($event, option.value)\"\n class=\"multiselect-checkbox\">\n {{ option.label }}\n </nile-checkbox>\n }\n </div>\n @if (dropdownOptions.length === 0) {\n <div class=\"empty-state\">\n No options available\n </div>\n }\n </div>\n }\n </div>\n \n <!-- Action Buttons -->\n <div class=\"filter-actions\">\n <nile-button \n variant=\"primary\"\n size=\"small\"\n (click)=\"onApply()\">\n Apply\n </nile-button>\n <nile-button \n variant=\"default\"\n size=\"small\"\n (click)=\"onClear()\">\n Clear\n </nile-button>\n </div>\n</div>\n", styles: [".filter-content{padding:16px;display:flex;flex-direction:column;gap:16px}.filter-content nile-select,.filter-content nile-input,.filter-content nile-checkbox{width:100%}.filter-content .filter-operator,.filter-content .filter-value-input,.filter-content .filter-value-select{margin-bottom:0}.filter-value-section{display:flex;flex-direction:column;gap:12px}.filter-value-section nile-checkbox{margin-top:8px}.filter-multiselect{display:flex;flex-direction:column;gap:8px}.filter-multiselect .multiselect-title{display:block;font-size:13px;font-weight:600;color:#2d3748;margin-bottom:8px}.filter-multiselect .multiselect-options{max-height:200px;overflow-y:auto;border:1px solid #cbd5e0;border-radius:4px;padding:8px;background-color:#f7fafc;display:flex;flex-direction:column;gap:6px}.filter-multiselect .multiselect-options nile-checkbox{width:100%}.filter-multiselect .multiselect-options nile-checkbox::part(base){padding:4px 8px;border-radius:4px;transition:background-color .15s}.filter-multiselect .multiselect-options nile-checkbox:hover::part(base){background-color:#edf2f7}.filter-multiselect .empty-state{padding:12px;text-align:center;color:#718096;font-size:13px}.filter-actions{display:flex;gap:8px;justify-content:flex-end;padding-top:12px;border-top:1px solid #e2e8f0;margin-top:4px}.filter-actions nile-button{flex:0 0 auto}.multiselect-options::-webkit-scrollbar{width:6px}.multiselect-options::-webkit-scrollbar-track{background:#edf2f7;border-radius:3px}.multiselect-options::-webkit-scrollbar-thumb{background:#cbd5e0;border-radius:3px}.multiselect-options::-webkit-scrollbar-thumb:hover{background:#a0aec0}nile-input::part(base){width:100%}nile-select::part(base){width:100%}nile-button::part(base){min-width:80px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
7102
7939
  }
7103
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnFilterComponent, decorators: [{
7940
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnFilterComponent, decorators: [{
7104
7941
  type: Component,
7105
7942
  args: [{ selector: 'st-column-filter', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<!-- Popover content -->\n<div class=\"filter-content\">\n <!-- Operator Select -->\n @if (availableOperators.length > 1) {\n <nile-select \n label=\"Operator\"\n [value]=\"selectedOperator\"\n (nile-change)=\"onOperatorChange($event)\"\n class=\"filter-operator\">\n @for (op of availableOperators; track op.value) {\n <nile-option [value]=\"op.value\">\n {{ op.label }}\n </nile-option>\n }\n </nile-select>\n }\n \n <!-- Input Field based on type -->\n <div class=\"filter-value-section\">\n \n <!-- Text Input -->\n @if (inputType === 'text') {\n <nile-input \n type=\"text\"\n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"Enter value...\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Number Input -->\n @if (inputType === 'number') {\n <nile-input \n type=\"number\"\n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"Enter number...\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Date Input -->\n @if (inputType === 'date') {\n <nile-input \n type=\"date\"\n label=\"Value\"\n [value]=\"filterValue\"\n (nile-input)=\"onValueInput($event)\"\n class=\"filter-value-input\">\n </nile-input>\n }\n \n <!-- Checkbox Input -->\n @if (inputType === 'checkbox') {\n <nile-checkbox\n [checked]=\"filterValue\"\n (nile-change)=\"onCheckboxChange($event)\"\n class=\"filter-checkbox\">\n {{ filterValue ? 'True' : 'False' }}\n </nile-checkbox>\n }\n \n <!-- Single Select Dropdown -->\n @if (inputType === 'select') {\n <nile-select \n label=\"Value\"\n [value]=\"filterValue\"\n placeholder=\"-- Select --\"\n (nile-change)=\"onSelectChange($event)\"\n class=\"filter-value-select\">\n @for (option of dropdownOptions; track option.value) {\n <nile-option [value]=\"option.value\">\n {{ option.label }}\n </nile-option>\n }\n </nile-select>\n }\n \n <!-- Multi-Select with Radio Group as example (or keep checkboxes) -->\n @if (inputType === 'multiselect') {\n <div class=\"filter-multiselect\">\n <label class=\"multiselect-title\">Select Values</label>\n <div class=\"multiselect-options\">\n @for (option of dropdownOptions; track option.value) {\n <nile-checkbox\n [checked]=\"isValueSelected(option.value)\"\n [value]=\"option.value\"\n (nile-change)=\"onMultiselectCheckboxChange($event, option.value)\"\n class=\"multiselect-checkbox\">\n {{ option.label }}\n </nile-checkbox>\n }\n </div>\n @if (dropdownOptions.length === 0) {\n <div class=\"empty-state\">\n No options available\n </div>\n }\n </div>\n }\n </div>\n \n <!-- Action Buttons -->\n <div class=\"filter-actions\">\n <nile-button \n variant=\"primary\"\n size=\"small\"\n (click)=\"onApply()\">\n Apply\n </nile-button>\n <nile-button \n variant=\"default\"\n size=\"small\"\n (click)=\"onClear()\">\n Clear\n </nile-button>\n </div>\n</div>\n", styles: [".filter-content{padding:16px;display:flex;flex-direction:column;gap:16px}.filter-content nile-select,.filter-content nile-input,.filter-content nile-checkbox{width:100%}.filter-content .filter-operator,.filter-content .filter-value-input,.filter-content .filter-value-select{margin-bottom:0}.filter-value-section{display:flex;flex-direction:column;gap:12px}.filter-value-section nile-checkbox{margin-top:8px}.filter-multiselect{display:flex;flex-direction:column;gap:8px}.filter-multiselect .multiselect-title{display:block;font-size:13px;font-weight:600;color:#2d3748;margin-bottom:8px}.filter-multiselect .multiselect-options{max-height:200px;overflow-y:auto;border:1px solid #cbd5e0;border-radius:4px;padding:8px;background-color:#f7fafc;display:flex;flex-direction:column;gap:6px}.filter-multiselect .multiselect-options nile-checkbox{width:100%}.filter-multiselect .multiselect-options nile-checkbox::part(base){padding:4px 8px;border-radius:4px;transition:background-color .15s}.filter-multiselect .multiselect-options nile-checkbox:hover::part(base){background-color:#edf2f7}.filter-multiselect .empty-state{padding:12px;text-align:center;color:#718096;font-size:13px}.filter-actions{display:flex;gap:8px;justify-content:flex-end;padding-top:12px;border-top:1px solid #e2e8f0;margin-top:4px}.filter-actions nile-button{flex:0 0 auto}.multiselect-options::-webkit-scrollbar{width:6px}.multiselect-options::-webkit-scrollbar-track{background:#edf2f7;border-radius:3px}.multiselect-options::-webkit-scrollbar-thumb{background:#cbd5e0;border-radius:3px}.multiselect-options::-webkit-scrollbar-thumb:hover{background:#a0aec0}nile-input::part(base){width:100%}nile-select::part(base){width:100%}nile-button::part(base){min-width:80px}\n"] }]
7106
7943
  }], propDecorators: { filterAnchor: [{
@@ -7331,10 +8168,10 @@ class StColumnMenuDropdownComponent {
7331
8168
  // Align left for first 2 columns to prevent clipping
7332
8169
  return (this.context?.columnIndex || 0) <= 1;
7333
8170
  }
7334
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnMenuDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7335
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StColumnMenuDropdownComponent, isStandalone: true, selector: "st-column-menu-dropdown", inputs: { isOpen: "isOpen", position: "position", context: "context" }, outputs: { actionClicked: "actionClicked", closed: "closed" }, host: { listeners: { "click": "onBackdropClick($event)" } }, viewQueries: [{ propertyName: "filterPopup", first: true, predicate: ["filterPopup"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Dropdown container with backdrop -->\n@if (isOpen && context) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"column-menu-dropdown\" [ngStyle]=\"dropdownStyle\">\n <!-- Main menu with actions -->\n @if (!isFilterOpen) {\n <nile-menu>\n <!-- Dynamically render all visible actions -->\n @for (action of visibleActions; track action.id; let i = $index, last = $last) {\n <nile-menu-item \n (click)=\"onActionClick(action)\"\n [class.disabled]=\"isActionDisabled(action)\"\n [class.active]=\"isActionActive(action)\">\n @if (isActionActive(action)) {\n <span class=\"checkmark\">\u2713</span>\n }\n @if (action.icon && !isActionActive(action)) {\n <nile-icon slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n <span class=\"action-label\">{{ action.label }}</span>\n </nile-menu-item>\n \n <!-- Add divider after action groups -->\n @if (shouldShowDividerAfter(action, i, last)) {\n <nile-divider></nile-divider>\n }\n }\n \n <!-- Fallback if no actions -->\n @if (visibleActions.length === 0) {\n <nile-menu-item>\n No actions available\n </nile-menu-item>\n }\n </nile-menu>\n }\n \n <!-- Filter popup (conditionally rendered) -->\n @if (isFilterOpen && context) {\n <st-column-filter\n #filterPopup\n [column]=\"context.column\"\n [tableState]=\"context.tableState\"\n [columnIndex]=\"context.columnIndex\"\n [isFirstColumn]=\"context.isFirstColumn\"\n [isLastColumn]=\"context.isLastColumn\"\n [isOpen]=\"isFilterOpen\"\n (filterApplied)=\"onFilterApplied($event)\"\n (filterCleared)=\"onFilterCleared()\"\n (closed)=\"onFilterClosed()\">\n </st-column-filter>\n }\n </div>\n </div>\n}\n", styles: [".dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9998}.dropdown-backdrop{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:auto;z-index:9998}.column-menu-dropdown{min-width:200px;max-width:300px;background-color:#fff;border-radius:8px;box-shadow:0 10px 25px #00000026;overflow:hidden;pointer-events:auto;z-index:9999}nile-menu nile-divider::part(divider){margin:0}nile-menu nile-menu-item::part(base){height:2.5rem;min-height:auto}nile-menu nile-menu-item .checkmark{margin-right:8px;color:#4299e1;font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: StColumnFilterComponent, selector: "st-column-filter", inputs: ["column", "tableState", "columnIndex", "isFirstColumn", "isLastColumn", "isOpen", "filterContext"], outputs: ["closed", "filterApplied", "filterCleared"] }] }); }
8171
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnMenuDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8172
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StColumnMenuDropdownComponent, isStandalone: true, selector: "st-column-menu-dropdown", inputs: { isOpen: "isOpen", position: "position", context: "context" }, outputs: { actionClicked: "actionClicked", closed: "closed" }, host: { listeners: { "click": "onBackdropClick($event)" } }, viewQueries: [{ propertyName: "filterPopup", first: true, predicate: ["filterPopup"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Dropdown container with backdrop -->\n@if (isOpen && context) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"column-menu-dropdown\" [ngStyle]=\"dropdownStyle\">\n <!-- Main menu with actions -->\n @if (!isFilterOpen) {\n <nile-menu>\n <!-- Dynamically render all visible actions -->\n @for (action of visibleActions; track action.id; let i = $index, last = $last) {\n <nile-menu-item \n (click)=\"onActionClick(action)\"\n [class.disabled]=\"isActionDisabled(action)\"\n [class.active]=\"isActionActive(action)\">\n @if (isActionActive(action)) {\n <span class=\"checkmark\">\u2713</span>\n }\n @if (action.icon && !isActionActive(action)) {\n <nile-icon slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n <span class=\"action-label\">{{ action.label }}</span>\n </nile-menu-item>\n \n <!-- Add divider after action groups -->\n @if (shouldShowDividerAfter(action, i, last)) {\n <nile-divider></nile-divider>\n }\n }\n \n <!-- Fallback if no actions -->\n @if (visibleActions.length === 0) {\n <nile-menu-item>\n No actions available\n </nile-menu-item>\n }\n </nile-menu>\n }\n \n <!-- Filter popup (conditionally rendered) -->\n @if (isFilterOpen && context) {\n <st-column-filter\n #filterPopup\n [column]=\"context.column\"\n [tableState]=\"context.tableState\"\n [columnIndex]=\"context.columnIndex\"\n [isFirstColumn]=\"context.isFirstColumn\"\n [isLastColumn]=\"context.isLastColumn\"\n [isOpen]=\"isFilterOpen\"\n (filterApplied)=\"onFilterApplied($event)\"\n (filterCleared)=\"onFilterCleared()\"\n (closed)=\"onFilterClosed()\">\n </st-column-filter>\n }\n </div>\n </div>\n}\n", styles: [".dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9998}.dropdown-backdrop{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:auto;z-index:9998}.column-menu-dropdown{min-width:200px;max-width:300px;background-color:#fff;border-radius:8px;box-shadow:0 10px 25px #00000026;overflow:hidden;pointer-events:auto;z-index:9999}nile-menu nile-divider::part(divider){margin:0}nile-menu nile-menu-item::part(base){height:2.5rem;min-height:auto}nile-menu nile-menu-item .checkmark{margin-right:8px;color:#4299e1;font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: StColumnFilterComponent, selector: "st-column-filter", inputs: ["column", "tableState", "columnIndex", "isFirstColumn", "isLastColumn", "isOpen", "filterContext"], outputs: ["closed", "filterApplied", "filterCleared"] }] }); }
7336
8173
  }
7337
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnMenuDropdownComponent, decorators: [{
8174
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnMenuDropdownComponent, decorators: [{
7338
8175
  type: Component,
7339
8176
  args: [{ selector: 'st-column-menu-dropdown', standalone: true, imports: [CommonModule, StColumnFilterComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<!-- Dropdown container with backdrop -->\n@if (isOpen && context) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"column-menu-dropdown\" [ngStyle]=\"dropdownStyle\">\n <!-- Main menu with actions -->\n @if (!isFilterOpen) {\n <nile-menu>\n <!-- Dynamically render all visible actions -->\n @for (action of visibleActions; track action.id; let i = $index, last = $last) {\n <nile-menu-item \n (click)=\"onActionClick(action)\"\n [class.disabled]=\"isActionDisabled(action)\"\n [class.active]=\"isActionActive(action)\">\n @if (isActionActive(action)) {\n <span class=\"checkmark\">\u2713</span>\n }\n @if (action.icon && !isActionActive(action)) {\n <nile-icon slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n <span class=\"action-label\">{{ action.label }}</span>\n </nile-menu-item>\n \n <!-- Add divider after action groups -->\n @if (shouldShowDividerAfter(action, i, last)) {\n <nile-divider></nile-divider>\n }\n }\n \n <!-- Fallback if no actions -->\n @if (visibleActions.length === 0) {\n <nile-menu-item>\n No actions available\n </nile-menu-item>\n }\n </nile-menu>\n }\n \n <!-- Filter popup (conditionally rendered) -->\n @if (isFilterOpen && context) {\n <st-column-filter\n #filterPopup\n [column]=\"context.column\"\n [tableState]=\"context.tableState\"\n [columnIndex]=\"context.columnIndex\"\n [isFirstColumn]=\"context.isFirstColumn\"\n [isLastColumn]=\"context.isLastColumn\"\n [isOpen]=\"isFilterOpen\"\n (filterApplied)=\"onFilterApplied($event)\"\n (filterCleared)=\"onFilterCleared()\"\n (closed)=\"onFilterClosed()\">\n </st-column-filter>\n }\n </div>\n </div>\n}\n", styles: [".dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9998}.dropdown-backdrop{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:auto;z-index:9998}.column-menu-dropdown{min-width:200px;max-width:300px;background-color:#fff;border-radius:8px;box-shadow:0 10px 25px #00000026;overflow:hidden;pointer-events:auto;z-index:9999}nile-menu nile-divider::part(divider){margin:0}nile-menu nile-menu-item::part(base){height:2.5rem;min-height:auto}nile-menu nile-menu-item .checkmark{margin-right:8px;color:#4299e1;font-weight:700}\n"] }]
7340
8177
  }], propDecorators: { isOpen: [{
@@ -7497,10 +8334,10 @@ class StRowActionsDropdownComponent {
7497
8334
  onDropdownClick(event) {
7498
8335
  event.stopPropagation();
7499
8336
  }
7500
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StRowActionsDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7501
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StRowActionsDropdownComponent, isStandalone: true, selector: "st-row-actions-dropdown", inputs: { isOpen: "isOpen", position: "position", context: "context" }, outputs: { actionClicked: "actionClicked", closed: "closed" }, host: { listeners: { "document:keydown.escape": "onEscapeKey($event)" } }, usesOnChanges: true, ngImport: i0, template: "@if (isOpen && context) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-overlay\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n @if (isOpen) {\n <nile-menu class=\"dropdown-menu\" [style.left.px]=\"dropdownStyle.left\" [style.top.px]=\"dropdownStyle.top\">\n @for (action of visibleActions; track action.id) {\n <nile-menu-item [class.disabled]=\"isActionDisabled(action)\" (click)=\"onActionClick(action)\" class=\"action-label\">\n @if (action.icon) {\n <nile-icon size=\"14\" slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n \n @if (visibleActions.length === 0) {\n <nile-menu-item>No actions available</nile-menu-item>\n }\n </nile-menu>\n }\n </div>\n </div>\n}\n", styles: [".dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9998}.dropdown-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:transparent;pointer-events:auto;z-index:9998}.dropdown-menu{position:fixed;background-color:#fff;box-shadow:0 5px 15px #0000004d,0 0 0 1px #0000001a;overflow:hidden;pointer-events:auto;z-index:9999}.action-icon{display:flex;align-items:center;justify-content:center;font-size:16px;width:20px;flex-shrink:0}.action-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dropdown-empty{padding:16px;text-align:center;color:#a0aec0;font-size:14px;font-style:italic}nile-menu{height:fit-content}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8337
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StRowActionsDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8338
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StRowActionsDropdownComponent, isStandalone: true, selector: "st-row-actions-dropdown", inputs: { isOpen: "isOpen", position: "position", context: "context" }, outputs: { actionClicked: "actionClicked", closed: "closed" }, host: { listeners: { "document:keydown.escape": "onEscapeKey($event)" } }, usesOnChanges: true, ngImport: i0, template: "@if (isOpen && context) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-overlay\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n @if (isOpen) {\n <nile-menu class=\"dropdown-menu\" [style.left.px]=\"dropdownStyle.left\" [style.top.px]=\"dropdownStyle.top\">\n @for (action of visibleActions; track action.id) {\n <nile-menu-item [class.disabled]=\"isActionDisabled(action)\" (click)=\"onActionClick(action)\" class=\"action-label\">\n @if (action.icon) {\n <nile-icon size=\"14\" slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n \n @if (visibleActions.length === 0) {\n <nile-menu-item>No actions available</nile-menu-item>\n }\n </nile-menu>\n }\n </div>\n </div>\n}\n", styles: [".dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9998}.dropdown-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:transparent;pointer-events:auto;z-index:9998}.dropdown-menu{position:fixed;background-color:#fff;box-shadow:0 5px 15px #0000004d,0 0 0 1px #0000001a;overflow:hidden;pointer-events:auto;z-index:9999}.action-icon{display:flex;align-items:center;justify-content:center;font-size:16px;width:20px;flex-shrink:0}.action-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dropdown-empty{padding:16px;text-align:center;color:#a0aec0;font-size:14px;font-style:italic}nile-menu{height:fit-content}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7502
8339
  }
7503
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StRowActionsDropdownComponent, decorators: [{
8340
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StRowActionsDropdownComponent, decorators: [{
7504
8341
  type: Component,
7505
8342
  args: [{ selector: 'st-row-actions-dropdown', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (isOpen && context) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-overlay\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n @if (isOpen) {\n <nile-menu class=\"dropdown-menu\" [style.left.px]=\"dropdownStyle.left\" [style.top.px]=\"dropdownStyle.top\">\n @for (action of visibleActions; track action.id) {\n <nile-menu-item [class.disabled]=\"isActionDisabled(action)\" (click)=\"onActionClick(action)\" class=\"action-label\">\n @if (action.icon) {\n <nile-icon size=\"14\" slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n \n @if (visibleActions.length === 0) {\n <nile-menu-item>No actions available</nile-menu-item>\n }\n </nile-menu>\n }\n </div>\n </div>\n}\n", styles: [".dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9998}.dropdown-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:transparent;pointer-events:auto;z-index:9998}.dropdown-menu{position:fixed;background-color:#fff;box-shadow:0 5px 15px #0000004d,0 0 0 1px #0000001a;overflow:hidden;pointer-events:auto;z-index:9999}.action-icon{display:flex;align-items:center;justify-content:center;font-size:16px;width:20px;flex-shrink:0}.action-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dropdown-empty{padding:16px;text-align:center;color:#a0aec0;font-size:14px;font-style:italic}nile-menu{height:fit-content}\n"] }]
7506
8343
  }], propDecorators: { isOpen: [{
@@ -7581,10 +8418,10 @@ class StKeyboardNavigationDirective {
7581
8418
  };
7582
8419
  return map[key];
7583
8420
  }
7584
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StKeyboardNavigationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
7585
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.0", type: StKeyboardNavigationDirective, isStandalone: true, selector: "[stKeyboardNavigation]", inputs: { tableState: "tableState", addRowOnNavigatePastEnd: "addRowOnNavigatePastEnd" }, host: { listeners: { "keydown": "onKeyDown($event)" } }, ngImport: i0 }); }
8421
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StKeyboardNavigationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
8422
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: StKeyboardNavigationDirective, isStandalone: true, selector: "[stKeyboardNavigation]", inputs: { tableState: "tableState", addRowOnNavigatePastEnd: "addRowOnNavigatePastEnd" }, host: { listeners: { "keydown": "onKeyDown($event)" } }, ngImport: i0 }); }
7586
8423
  }
7587
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StKeyboardNavigationDirective, decorators: [{
8424
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StKeyboardNavigationDirective, decorators: [{
7588
8425
  type: Directive,
7589
8426
  args: [{
7590
8427
  selector: '[stKeyboardNavigation]',
@@ -7696,10 +8533,10 @@ class StColumnResizeDirective {
7696
8533
  document.removeEventListener('mousemove', this.onResizeMove);
7697
8534
  document.removeEventListener('mouseup', this.onResizeEnd);
7698
8535
  }
7699
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnResizeDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
7700
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.0", type: StColumnResizeDirective, isStandalone: true, selector: "[stColumnResize]", inputs: { column: "column" }, outputs: { columnResized: "columnResized", columnResizing: "columnResizing" }, host: { listeners: { "mousedown": "onResizeStart($event)" } }, ngImport: i0 }); }
8536
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnResizeDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
8537
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: StColumnResizeDirective, isStandalone: true, selector: "[stColumnResize]", inputs: { column: "column" }, outputs: { columnResized: "columnResized", columnResizing: "columnResizing" }, host: { listeners: { "mousedown": "onResizeStart($event)" } }, ngImport: i0 }); }
7701
8538
  }
7702
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnResizeDirective, decorators: [{
8539
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnResizeDirective, decorators: [{
7703
8540
  type: Directive,
7704
8541
  args: [{
7705
8542
  selector: '[stColumnResize]',
@@ -7726,13 +8563,13 @@ class StTableComponent {
7726
8563
  // Z-Index constants for template use
7727
8564
  this.ZIndex = TableZIndex;
7728
8565
  // Signal-based inputs
7729
- this.tableConfig = input.required(...(ngDevMode ? [{ debugName: "tableConfig" }] : []));
7730
- this.data = input(undefined, ...(ngDevMode ? [{ debugName: "data" }] : []));
7731
- this.data$ = input(undefined, ...(ngDevMode ? [{ debugName: "data$" }] : []));
7732
- this.tableState = input(undefined, ...(ngDevMode ? [{ debugName: "tableState" }] : []));
7733
- this.enableSorting = input(true, ...(ngDevMode ? [{ debugName: "enableSorting" }] : []));
7734
- this.enableFiltering = input(true, ...(ngDevMode ? [{ debugName: "enableFiltering" }] : []));
7735
- this.validateConfig = input(false, ...(ngDevMode ? [{ debugName: "validateConfig" }] : []));
8566
+ this.tableConfig = input.required(...(ngDevMode ? [{ debugName: "tableConfig" }] : /* istanbul ignore next */ []));
8567
+ this.data = input(undefined, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
8568
+ this.data$ = input(undefined, ...(ngDevMode ? [{ debugName: "data$" }] : /* istanbul ignore next */ []));
8569
+ this.tableState = input(undefined, ...(ngDevMode ? [{ debugName: "tableState" }] : /* istanbul ignore next */ []));
8570
+ this.enableSorting = input(true, ...(ngDevMode ? [{ debugName: "enableSorting" }] : /* istanbul ignore next */ []));
8571
+ this.enableFiltering = input(true, ...(ngDevMode ? [{ debugName: "enableFiltering" }] : /* istanbul ignore next */ []));
8572
+ this.validateConfig = input(false, ...(ngDevMode ? [{ debugName: "validateConfig" }] : /* istanbul ignore next */ []));
7736
8573
  // Signal-based outputs
7737
8574
  this.stateChange = output();
7738
8575
  this.dataChange = output();
@@ -7748,26 +8585,26 @@ class StTableComponent {
7748
8585
  this.validationStateChange = output();
7749
8586
  this.requestAddRow = output();
7750
8587
  // Internal state signals
7751
- this.mergedConfig = signal(null, ...(ngDevMode ? [{ debugName: "mergedConfig" }] : []));
7752
- this.visibleColumns = signal([], ...(ngDevMode ? [{ debugName: "visibleColumns" }] : []));
7753
- this.visibleCellGrid = signal([], ...(ngDevMode ? [{ debugName: "visibleCellGrid" }] : []));
7754
- this.showColumnModal = signal(false, ...(ngDevMode ? [{ debugName: "showColumnModal" }] : []));
8588
+ this.mergedConfig = signal(null, ...(ngDevMode ? [{ debugName: "mergedConfig" }] : /* istanbul ignore next */ []));
8589
+ this.visibleColumns = signal([], ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
8590
+ this.visibleCellGrid = signal([], ...(ngDevMode ? [{ debugName: "visibleCellGrid" }] : /* istanbul ignore next */ []));
8591
+ this.showColumnModal = signal(false, ...(ngDevMode ? [{ debugName: "showColumnModal" }] : /* istanbul ignore next */ []));
7755
8592
  // Internal data signal (stores current effective data from either data input or data$ observable)
7756
- this.currentData = signal([], ...(ngDevMode ? [{ debugName: "currentData" }] : []));
8593
+ this.currentData = signal([], ...(ngDevMode ? [{ debugName: "currentData" }] : /* istanbul ignore next */ []));
7757
8594
  // Row actions dropdown state as signals
7758
- this.dropdownIsOpen = signal(false, ...(ngDevMode ? [{ debugName: "dropdownIsOpen" }] : []));
7759
- this.dropdownPosition = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "dropdownPosition" }] : []));
7760
- this.dropdownContext = signal(null, ...(ngDevMode ? [{ debugName: "dropdownContext" }] : []));
8595
+ this.dropdownIsOpen = signal(false, ...(ngDevMode ? [{ debugName: "dropdownIsOpen" }] : /* istanbul ignore next */ []));
8596
+ this.dropdownPosition = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "dropdownPosition" }] : /* istanbul ignore next */ []));
8597
+ this.dropdownContext = signal(null, ...(ngDevMode ? [{ debugName: "dropdownContext" }] : /* istanbul ignore next */ []));
7761
8598
  // Column menu dropdown state as signals
7762
- this.columnMenuIsOpen = signal(false, ...(ngDevMode ? [{ debugName: "columnMenuIsOpen" }] : []));
7763
- this.columnMenuPosition = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "columnMenuPosition" }] : []));
7764
- this.columnMenuContext = signal(null, ...(ngDevMode ? [{ debugName: "columnMenuContext" }] : []));
8599
+ this.columnMenuIsOpen = signal(false, ...(ngDevMode ? [{ debugName: "columnMenuIsOpen" }] : /* istanbul ignore next */ []));
8600
+ this.columnMenuPosition = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "columnMenuPosition" }] : /* istanbul ignore next */ []));
8601
+ this.columnMenuContext = signal(null, ...(ngDevMode ? [{ debugName: "columnMenuContext" }] : /* istanbul ignore next */ []));
7765
8602
  // Virtual scroll state as signal
7766
- this.virtualScrollState = signal(null, ...(ngDevMode ? [{ debugName: "virtualScrollState" }] : []));
8603
+ this.virtualScrollState = signal(null, ...(ngDevMode ? [{ debugName: "virtualScrollState" }] : /* istanbul ignore next */ []));
7767
8604
  // Computed signals for virtual scroll
7768
- this.virtualScrollTotalHeight = computed(() => this.virtualScrollState()?.totalHeight ?? 0, ...(ngDevMode ? [{ debugName: "virtualScrollTotalHeight" }] : []));
7769
- this.virtualScrollOffsetY = computed(() => this.virtualScrollState()?.offsetY ?? 0, ...(ngDevMode ? [{ debugName: "virtualScrollOffsetY" }] : []));
7770
- this.virtualScrollOffsetYNeg = computed(() => (this.virtualScrollState()?.offsetY ?? 0) * -1, ...(ngDevMode ? [{ debugName: "virtualScrollOffsetYNeg" }] : []));
8605
+ this.virtualScrollTotalHeight = computed(() => this.virtualScrollState()?.totalHeight ?? 0, ...(ngDevMode ? [{ debugName: "virtualScrollTotalHeight" }] : /* istanbul ignore next */ []));
8606
+ this.virtualScrollOffsetY = computed(() => this.virtualScrollState()?.offsetY ?? 0, ...(ngDevMode ? [{ debugName: "virtualScrollOffsetY" }] : /* istanbul ignore next */ []));
8607
+ this.virtualScrollOffsetYNeg = computed(() => (this.virtualScrollState()?.offsetY ?? 0) * -1, ...(ngDevMode ? [{ debugName: "virtualScrollOffsetYNeg" }] : /* istanbul ignore next */ []));
7771
8608
  this.visibleRows = computed(() => {
7772
8609
  const state = this.virtualScrollState();
7773
8610
  const grid = this.visibleCellGrid();
@@ -7775,18 +8612,18 @@ class StTableComponent {
7775
8612
  return grid;
7776
8613
  const { startIndex, endIndex } = state;
7777
8614
  return grid.slice(startIndex, endIndex);
7778
- }, ...(ngDevMode ? [{ debugName: "visibleRows" }] : []));
8615
+ }, ...(ngDevMode ? [{ debugName: "visibleRows" }] : /* istanbul ignore next */ []));
7779
8616
  // Computed for dropdown state (for template compatibility)
7780
8617
  this.dropdownState = computed(() => ({
7781
8618
  isOpen: this.dropdownIsOpen(),
7782
8619
  position: this.dropdownPosition(),
7783
8620
  context: this.dropdownContext()
7784
- }), ...(ngDevMode ? [{ debugName: "dropdownState" }] : []));
8621
+ }), ...(ngDevMode ? [{ debugName: "dropdownState" }] : /* istanbul ignore next */ []));
7785
8622
  this.columnMenuState = computed(() => ({
7786
8623
  isOpen: this.columnMenuIsOpen(),
7787
8624
  position: this.columnMenuPosition(),
7788
8625
  context: this.columnMenuContext()
7789
- }), ...(ngDevMode ? [{ debugName: "columnMenuState" }] : []));
8626
+ }), ...(ngDevMode ? [{ debugName: "columnMenuState" }] : /* istanbul ignore next */ []));
7790
8627
  // Legacy observable wrappers for backward compatibility
7791
8628
  this.virtualScrollTotalHeight$ = new BehaviorSubject(0);
7792
8629
  this.virtualScrollOffsetY$ = new BehaviorSubject(0);
@@ -7974,7 +8811,20 @@ class StTableComponent {
7974
8811
  if (!dataValue || dataValue.length === 0)
7975
8812
  return;
7976
8813
  const columns = this.getActiveColumns();
7977
- this.internalCellGrid = dataValue.map((rowData, rowIndex) => columns.map(column => new Cell(column, rowData[column.key], rowData, rowIndex)));
8814
+ const oldGrid = this.internalCellGrid;
8815
+ this.internalCellGrid = dataValue.map((rowData, rowIndex) => columns.map((column, colIndex) => {
8816
+ const newCell = new Cell(column, rowData[column.key], rowData, rowIndex);
8817
+ const oldCell = oldGrid?.[rowIndex]?.[colIndex];
8818
+ if (oldCell && oldCell.getColumnConfig().key === column.key) {
8819
+ oldCell.setReplacement(newCell);
8820
+ // Carry over transient state (e.g. loading) that was set on the old cell
8821
+ const oldState = oldCell.getState();
8822
+ if (oldState.isLoading) {
8823
+ newCell.setLoading(true);
8824
+ }
8825
+ }
8826
+ return newCell;
8827
+ }));
7978
8828
  }
7979
8829
  setupDataSource() {
7980
8830
  const dataValue = this.data();
@@ -8810,10 +9660,10 @@ class StTableComponent {
8810
9660
  this.visibleRows$.complete();
8811
9661
  this.internalData$.complete();
8812
9662
  }
8813
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8814
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StTableComponent, isStandalone: true, selector: "st-table", inputs: { tableConfig: { classPropertyName: "tableConfig", publicName: "tableConfig", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, data$: { classPropertyName: "data$", publicName: "data$", isSignal: true, isRequired: false, transformFunction: null }, tableState: { classPropertyName: "tableState", publicName: "tableState", isSignal: true, isRequired: false, transformFunction: null }, enableSorting: { classPropertyName: "enableSorting", publicName: "enableSorting", isSignal: true, isRequired: false, transformFunction: null }, enableFiltering: { classPropertyName: "enableFiltering", publicName: "enableFiltering", isSignal: true, isRequired: false, transformFunction: null }, validateConfig: { classPropertyName: "validateConfig", publicName: "validateConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stateChange: "stateChange", dataChange: "dataChange", cellEdit: "cellEdit", cellSave: "cellSave", cellCancel: "cellCancel", cellChange: "cellChange", columnResized: "columnResized", columnMoved: "columnMoved", configValidationErrors: "configValidationErrors", columnAdded: "columnAdded", rowAction: "rowAction", validationStateChange: "validationStateChange", requestAddRow: "requestAddRow" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<!-- Top pagination controls -->\n@if (showTopPagination() && !(mergedConfig()?.tableSkeleton?.enabled | async)) {\n <st-pagination \n [tableState]=\"getActiveTableState()\"\n [tableConfig]=\"mergedConfig()!\"\n position=\"top\">\n </st-pagination>\n}\n\n@if (!(mergedConfig()?.tableSkeleton?.enabled | async)) {\n <div class=\"st-table\"\n [ngClass]=\"{\n 'virtual-scroll-enabled': isVirtualScrollEnabled(),\n 'keyboard-navigation-enabled': isKeyboardNavigationEnabled()\n }\"\n [ngStyle]=\"{\n 'max-height.px': !isVirtualScrollEnabled() ? mergedConfig()?.display?.maxHeight : null\n }\"\n stKeyboardNavigation\n [tableState]=\"getActiveTableState()\"\n [addRowOnNavigatePastEnd]=\"mergedConfig()?.features?.keyboardNavigation?.addRowOnNavigatePastEnd || false\"\n [attr.tabindex]=\"isKeyboardNavigationEnabled() ? 0 : -1\"\n (focus)=\"onTableContainerFocus($event)\"\n [attr.title]=\"isKeyboardNavigationEnabled() ? 'Click a cell or press Tab to start keyboard navigation' : null\">\n <!-- Unified Table Actions Menu -->\n\n <!-- Virtual scroll viewport wrapper -->\n @if (isVirtualScrollEnabled()) {\n <div class=\"st-scroll-viewport\" #scrollViewport\n [ngStyle]=\"{ 'height.px': getVirtualScrollViewportHeight() }\">\n\n <!-- Spacer to create scrollable area -->\n <div class=\"st-scroll-spacer\" [ngStyle]=\"{ 'height.px': virtualScrollTotalHeight() }\">\n </div>\n\n <!-- Table positioner with transform (instead of tbody) -->\n <div class=\"st-table-positioner\" [ngStyle]=\"{ transform: 'translateY(' + virtualScrollOffsetY() + 'px)' }\">\n <!-- Table with only visible rows -->\n <ng-container *ngTemplateOutlet=\"tableTemplate; context: { \n mode: 'virtual',\n theadStyle: { top: virtualScrollOffsetYNeg() + 'px' }\n }\"></ng-container>\n </div>\n </div>\n }\n \n <!-- Standard table (when virtual scroll disabled) -->\n @if (!isVirtualScrollEnabled()) {\n <ng-container *ngTemplateOutlet=\"tableTemplate; context: { \n mode: 'standard',\n theadStyle: null\n }\"></ng-container>\n }\n\n <!-- Shared Column Menu Dropdown -->\n <st-column-menu-dropdown \n [isOpen]=\"columnMenuState().isOpen\"\n [position]=\"columnMenuState().position\"\n [context]=\"columnMenuState().context\"\n (actionClicked)=\"onColumnActionClicked($event)\"\n (closed)=\"closeColumnMenu()\">\n </st-column-menu-dropdown>\n </div>\n}\n\n@if (mergedConfig()?.tableSkeleton?.enabled | async) {\n <ng-container *ngTemplateOutlet=\"skeletonLoader\"></ng-container>\n}\n\n<!-- Shared Row Actions Dropdown -->\n<st-row-actions-dropdown [isOpen]=\"dropdownState().isOpen\" [position]=\"dropdownState().position\"\n [context]=\"dropdownState().context\" (actionClicked)=\"onRowActionClicked($event)\" (closed)=\"closeRowActionsDropdown()\">\n</st-row-actions-dropdown>\n\n\n<!-- Bottom pagination controls -->\n@if (showBottomPagination() && !(mergedConfig()?.tableSkeleton?.enabled | async)) {\n <st-pagination \n [tableState]=\"getActiveTableState()\"\n [tableConfig]=\"mergedConfig()!\"\n position=\"bottom\">\n</st-pagination>\n}\n\n\n<!-- ========================================== -->\n<!-- REUSABLE TABLE TEMPLATE -->\n<!-- ========================================== -->\n<ng-template #tableTemplate let-mode=\"mode\" let-theadStyle=\"theadStyle\">\n <table class=\"st-table-element\">\n <!-- TABLE HEADER -->\n <thead [ngClass]=\"{ 'sticky': mergedConfig()?.display?.stickyHeader }\" [ngStyle]=\"theadStyle\">\n <tr>\n <!-- Row Number Header -->\n @if (mergedConfig()?.showRowNumber) {\n <th class=\"row-number-header header-cell sticky-left\"\n [ngStyle]=\"{\n position: 'sticky',\n 'left.px': 0,\n 'z-index': ZIndex.STICKY_HEADER_CELL,\n 'width.px': 30\n }\">\n #\n </th>\n }\n <!-- Column Headers -->\n @for (column of visibleColumns(); track column.key; let colIndex = $index, isFirst = $first, isLast = $last) {\n <th \n [ngClass]=\"{\n 'header-cell': mode === 'standard',\n 'sticky-left': column.sticky === 'left',\n 'sticky-right': column.sticky === 'right',\n 'sticky-right-first': column.sticky === 'right' && isFirstStickyRight(column.key),\n 'resizable': column.resizable !== false\n }\"\n [ngStyle]=\"{\n position: column.sticky ? 'sticky' : null,\n 'left.px': column.sticky === 'left' ? (column.stickyOffset || 0) : null,\n 'right.px': column.sticky === 'right' ? (column.stickyOffset || 0) : null,\n 'z-index': column.sticky ? ZIndex.STICKY_HEADER_CELL : null,\n 'width.px': column.width\n }\">\n \n <st-header \n [column]=\"column\"\n [columnIndex]=\"colIndex\"\n [isFirstColumn]=\"isFirst\"\n [isLastColumn]=\"isLast\"\n [tableState]=\"getActiveTableState()\"\n [enableSorting]=\"mergedConfig()?.sorting?.enabled ?? enableSorting()\"\n [enableFiltering]=\"mergedConfig()?.filtering?.enabled ?? enableFiltering()\"\n (columnMoved)=\"onColumnMoved($event)\"\n (menuClick)=\"openColumnMenu($event, column, colIndex, isFirst, isLast)\">\n </st-header>\n\n @if (column.resizable !== false) {\n <div \n class=\"resize-handle\" \n stColumnResize\n [column]=\"column\"\n (columnResizing)=\"onColumnResizing($event)\"\n (columnResized)=\"onColumnResized($event)\">\n </div>\n }\n </th>\n }\n \n <!-- Settings Column Header -->\n <th \n class=\"settings-column sticky-right\"\n [ngClass]=\"{ 'header-cell': mode === 'standard' }\"\n [ngStyle]=\"{ 'z-index': ZIndex.STICKY_HEADER_CELL }\">\n <div [ngClass]=\"{ 'flex-center': mode === 'virtual', 'header-content': mode === 'standard' }\">\n <st-table-actions \n [tableState]=\"getActiveTableState()\"\n [allowAddColumn]=\"mergedConfig()?.features?.columnManagement?.allowAdd || false\"\n (addColumnClicked)=\"onAddColumnClick()\">\n </st-table-actions>\n </div>\n </th>\n </tr>\n </thead>\n\n <!-- TABLE BODY -->\n <tbody>\n <!-- Virtual Scroll Rows -->\n @if (mode === 'virtual') {\n @for (row of visibleRows(); track trackByRowIndex($index, row); let relativeIndex = $index) {\n <tr [attr.data-row-index]=\"getAbsoluteRowIndex(relativeIndex)\">\n <!-- Row Number Cell -->\n @if (mergedConfig()?.showRowNumber) {\n <td class=\"row-number-cell\" \n [ngClass]=\"{ 'sticky-left': 'left' }\"\n [ngStyle]=\"{\n 'width.px': 30,\n position: 'sticky',\n 'left.px': 0,\n 'z-index': ZIndex.STICKY_BODY_CELL,\n 'height.px': mode === 'virtual' ? getVirtualScrollItemSize() : null\n }\">\n {{getAbsoluteRowIndex(relativeIndex) + 1}}\n </td>\n }\n <ng-container *ngTemplateOutlet=\"bodyCellTemplate; context: { \n row: row,\n rowIndex: getAbsoluteRowIndex(relativeIndex),\n mode: 'virtual',\n relativeIndex: relativeIndex\n }\"></ng-container>\n </tr>\n }\n }\n\n <!-- Standard Rows -->\n @if (mode === 'standard') {\n @for (row of visibleCellGrid(); track $index; let rowIndex = $index) {\n <tr [attr.data-row-index]=\"rowIndex\">\n <!-- Row Number Cell -->\n @if (mergedConfig()?.showRowNumber) {\n <td class=\"row-number-cell\" \n [ngClass]=\"{ 'sticky-left': 'left' }\"\n [ngStyle]=\"{\n 'width.px': 30,\n position: 'sticky',\n 'left.px': 0,\n 'z-index': ZIndex.STICKY_BODY_CELL,\n 'height.px': mode === 'virtual' ? getVirtualScrollItemSize() : null\n }\">\n {{rowIndex + 1}}\n </td>\n }\n <ng-container *ngTemplateOutlet=\"bodyCellTemplate; context: { \n row: row,\n rowIndex: rowIndex,\n mode: 'standard'\n }\"></ng-container>\n </tr>\n }\n }\n </tbody>\n </table>\n</ng-template>\n\n<!-- ========================================== -->\n<!-- REUSABLE BODY CELL TEMPLATE -->\n<!-- ========================================== -->\n<ng-template #bodyCellTemplate let-row=\"row\" let-rowIndex=\"rowIndex\" let-mode=\"mode\" let-relativeIndex=\"relativeIndex\">\n <!-- Data Cells -->\n @for (cell of row; track $index; let colIndex = $index) {\n <td \n [ngClass]=\"{\n 'sticky-left': visibleColumns()[colIndex]?.sticky === 'left',\n 'sticky-right': visibleColumns()[colIndex]?.sticky === 'right',\n 'sticky-right-first': visibleColumns()[colIndex]?.sticky === 'right' && visibleColumns()[colIndex]?.key && isFirstStickyRight(visibleColumns()[colIndex].key),\n 'align-center': visibleColumns()[colIndex]?.alignment === 'center',\n 'align-right': visibleColumns()[colIndex]?.alignment === 'right',\n 'cell-focused': cell.isFocused()\n }\"\n [ngStyle]=\"{\n position: visibleColumns()[colIndex]?.sticky ? 'sticky' : null,\n 'left.px': visibleColumns()[colIndex]?.sticky === 'left' ? (visibleColumns()[colIndex]?.stickyOffset || 0) : null,\n 'right.px': visibleColumns()[colIndex]?.sticky === 'right' ? (visibleColumns()[colIndex]?.stickyOffset || 0) : null,\n 'z-index': visibleColumns()[colIndex]?.sticky ? ZIndex.STICKY_BODY_CELL : null,\n 'width.px': visibleColumns()[colIndex]?.width,\n 'height.px': mode === 'virtual' ? getVirtualScrollItemSize() : null\n }\"\n (click)=\"isKeyboardNavigationEnabled() ? onCellClick(rowIndex, colIndex) : null\">\n \n <!-- Virtual Scroll Cell -->\n @if (mode === 'virtual') {\n <st-cell \n [cell]=\"cell\" \n [attr.tabindex]=\"cell.isFocused() ? 0 : -1\" \n [editMode]=\"getEditModeForCells()\"\n [tableState]=\"getActiveTableState()\"\n [tableConfig]=\"mergedConfig()!\"\n [columnIndex]=\"colIndex\"\n (cellEdit)=\"onCellEdit($event)\" \n (cellSave)=\"onCellSave($event)\"\n (cellSaveAndNavigate)=\"onCellSaveAndNavigate($event)\" \n (cellCancel)=\"onCellCancel($event)\"\n (cellChange)=\"cellChange.emit($event)\">\n </st-cell>\n }\n\n <!-- Standard Cell -->\n @if (mode === 'standard') {\n <st-cell \n [cell]=\"cell\" \n [attr.tabindex]=\"cell.isFocused() ? 0 : -1\"\n [tableState]=\"getActiveTableState()\"\n [tableConfig]=\"mergedConfig()!\"\n [columnIndex]=\"colIndex\"\n (cellSave)=\"onCellSave($event)\"\n (cellChange)=\"cellChange.emit($event)\">\n </st-cell>\n }\n </td>\n }\n \n <!-- Row Actions Cell -->\n <td class=\"settings-column\"\n [ngClass]=\"{\n 'has-actions': hasRowActions()\n }\"\n [ngStyle]=\"{\n position: hasRowActions() ? 'sticky' : null,\n 'right.px': hasRowActions() ? 0 : null,\n 'z-index': hasRowActions() ? ZIndex.STICKY_BODY_CELL : null\n }\">\n @if (hasRowActions()) {\n <button \n class=\"settings-trigger\"\n (click)=\"openRowActionsDropdown($event, getRowData(rowIndex), rowIndex)\"\n type=\"button\" \n aria-label=\"Row actions\">\n \u22EF\n </button>\n }\n </td>\n</ng-template>\n\n<ng-template #skeletonLoader>\n @if (mergedConfig()?.tableSkeleton?.enabled | async) {\n <div class=\"list-row\">\n @for (i of skeletonColumns; track $index) {\n <div class=\"list-content\">\n @for (j of skeletonRows; track $index) {\n <nile-skeleton-loader variant=\"text\" width=\"90%\" height=\"18\"></nile-skeleton-loader>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: [".st-table{width:100%;overflow:auto;position:relative;height:100%;max-height:30rem;border-radius:4px;border:1px solid #E6E9EB}.st-table st-table-actions{position:sticky;right:0}.st-table.keyboard-navigation-enabled{cursor:pointer}.st-table.keyboard-navigation-enabled:focus{outline:none;box-shadow:0 0 0 2px #3b82f64d}.st-table.keyboard-navigation-enabled td.cell-focused{outline:2px solid #4299e1;outline-offset:-1px;position:relative;box-shadow:0 0 0 3px #3182ce1a}.st-table.keyboard-navigation-enabled td.cell-focused:focus{outline:2px solid #4299e1;outline-offset:-1px;box-shadow:0 0 0 3px #3182ce1a}.st-table.keyboard-navigation-enabled td.cell-focused:has(.st-cell.editing){box-shadow:0 0 0 4px #2563eb26}.st-table.virtual-scroll-enabled{overflow-x:visible;margin:0;border:1px solid #E6E9EB;border-collapse:separate;border-spacing:0}.st-table.virtual-scroll-enabled .st-scroll-viewport{position:relative;overflow-y:auto;overflow-x:auto;scroll-behavior:smooth}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-scroll-spacer{position:absolute;top:0;left:0;width:1px;pointer-events:none;z-index:-1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-positioner{position:absolute;top:0;left:0;right:0;will-change:transform}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element{position:relative;width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead{background-color:#fff;border-bottom:1px solid #E6E9EB}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead.sticky{position:sticky;top:0;z-index:3;background-color:#fff;will-change:top;backface-visibility:hidden}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead.sticky:after{content:\"\";position:absolute;bottom:-2px;left:0;right:0;height:2px;background:linear-gradient(to bottom,rgba(0,0,0,.1),transparent)}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th{padding:0;vertical-align:middle;position:relative;border:none;background-color:#fff;will-change:top;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-left{position:sticky;left:0;background-color:#fff;z-index:2;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)):after{content:\"\";position:absolute;right:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to left,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-right{position:sticky;right:0;background-color:#fff;z-index:2;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-right-first:not(.settings-column){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to right,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.settings-column{width:2rem;text-align:center;font-weight:600;font-size:12px;position:sticky;right:0;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb;z-index:2}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.resizable .resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;z-index:4;pointer-events:auto}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.resizable .resize-handle:after{content:\"\";position:absolute;top:50%;right:3px;transform:translateY(-50%);width:2px;height:20px;background-color:#cbd5e0;opacity:0;transition:opacity .2s}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.resizable .resize-handle:hover:after,.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.resizable .resize-handle:active:after{opacity:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.row-number-header{text-align:center;font-weight:300;font-size:12px;background-color:#f8f8f8}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)):after{content:\"\";position:absolute;right:-6px;top:0;bottom:-1px;width:5px;border-left:1px solid var(--borderColor);background:linear-gradient(90deg,#00000014,#0000)}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-6px;top:0;bottom:-1px;width:5px;border-right:1px solid var(--borderColor);background:linear-gradient(90deg,#0000,#00000014)}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody{will-change:transform;position:relative;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr{border-bottom:1px solid #E6E9EB;transition:background-color .15s;height:2rem;box-sizing:border-box}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr:last-child{border-bottom:none}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td{padding:0;vertical-align:middle;box-sizing:border-box;height:2rem;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb;border:none}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.align-center{text-align:center}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.align-right{text-align:right}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-left{position:sticky;z-index:2;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)):after{content:\"\";position:absolute;right:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to left,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-right{position:sticky;z-index:2;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-right-first:not(.settings-column){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to right,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.settings-column{width:2rem;text-align:center;position:sticky;right:0;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb;z-index:2}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.settings-column .settings-trigger{background:none;border:none;font-size:1rem;line-height:1;cursor:pointer;border-radius:4px;transition:all .15s ease}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.settings-column .settings-trigger:focus{outline:2px solid #4299e1;outline-offset:2px}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.row-number-cell{text-align:center;font-weight:300;font-size:12px;background-color:#f8f8f8}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)):after{content:\"\";position:absolute;right:-6px;top:0;bottom:-1px;width:5px;border-left:1px solid var(--borderColor);background:linear-gradient(90deg,#00000014,#0000)}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-right-first:before{content:\"\";position:absolute;left:-6px;top:0;bottom:-1px;width:5px;border-right:1px solid var(--borderColor);background:linear-gradient(90deg,#0000,#00000014)}.st-table:not(.virtual-scroll-enabled) .st-table-element{width:100%;height:100%;overflow:auto;border-collapse:separate;border-spacing:0;table-layout:fixed}.st-table:not(.virtual-scroll-enabled) .st-table-element thead{background-color:#fff;border-bottom:1px solid #E6E9EB}.st-table:not(.virtual-scroll-enabled) .st-table-element thead.sticky{position:sticky;top:0;z-index:3;background-color:#fff;will-change:top;backface-visibility:hidden}.st-table:not(.virtual-scroll-enabled) .st-table-element thead.sticky:after{content:\"\";position:absolute;bottom:-2px;left:0;right:0;height:2px;background:linear-gradient(to bottom,rgba(0,0,0,.1),transparent)}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th{padding:0;vertical-align:middle;position:relative;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb;border:none}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-left{position:sticky;left:0;background-color:#fff;z-index:2;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)):after{content:\"\";position:absolute;right:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to left,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-right{position:sticky;right:0;background-color:#fff;z-index:2;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-right-first:not(.settings-column){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to right,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.settings-column{width:2rem;text-align:center;font-weight:600;font-size:12px;position:sticky;right:0;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb;z-index:2}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.resizable .resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;z-index:4;pointer-events:auto}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.resizable .resize-handle:after{content:\"\";position:absolute;top:50%;right:3px;transform:translateY(-50%);width:2px;height:20px;background-color:#cbd5e0;opacity:0;transition:opacity .2s}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.resizable .resize-handle:hover:after,.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.resizable .resize-handle:active:after{opacity:1}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.row-number-header{text-align:center;font-weight:300;font-size:12px;background-color:#f8f8f8}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody{will-change:transform;position:relative;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr{height:2rem;box-sizing:border-box}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr:last-child{border-bottom:none}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td{padding:0;vertical-align:middle;height:2rem;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb;border:none}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.row-number-cell{text-align:center;font-weight:300;font-size:12px;background-color:#f8f8f8}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.align-center{text-align:center}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.align-right{text-align:right}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-left{position:sticky;z-index:2;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)):after{content:\"\";position:absolute;right:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to left,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-right{position:sticky;z-index:2;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-right-first:not(.settings-column){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to right,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.settings-column{position:sticky;right:0;width:2rem;text-align:center;border-right:none;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb;z-index:2}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.settings-column .settings-trigger{background:none;border:none;font-size:1rem;line-height:1;cursor:pointer;border-radius:4px;transition:all .15s ease}.st-table:not(.virtual-scroll-enabled) .st-table-element .header-content{display:flex;height:2rem;align-items:center}.st-table:not(.virtual-scroll-enabled) .st-table-element .header-content .table-header-text{flex-grow:1;padding-left:4px}.st-table:not(.virtual-scroll-enabled) .st-table-element .settings-column>.header-content{display:flex;align-items:center;justify-content:center}.flex-center{display:flex;align-items:center;justify-content:center}.list-row .list-content{display:flex;justify-content:space-evenly;gap:4px;margin-bottom:1rem}.list-row{padding:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: StPaginationComponent, selector: "st-pagination", inputs: ["tableState", "tableConfig", "position"] }, { kind: "component", type: StHeaderComponent, selector: "st-header", inputs: ["column", "columnIndex", "isFirstColumn", "isLastColumn", "tableState", "enableSorting", "enableFiltering"], outputs: ["sortToggle", "filterChange", "columnMoved", "menuClick"] }, { kind: "component", type: StCellComponent, selector: "st-cell", inputs: ["cell", "editMode", "tableState", "tableConfig", "columnIndex"], outputs: ["cellChange", "cellEdit", "cellSave", "cellCancel", "cellSaveAndNavigate"] }, { kind: "component", type: StTableActionsComponent, selector: "st-table-actions", inputs: ["tableState", "allowAddColumn"], outputs: ["addColumnClicked"] }, { kind: "component", type: StColumnMenuDropdownComponent, selector: "st-column-menu-dropdown", inputs: ["isOpen", "position", "context"], outputs: ["actionClicked", "closed"] }, { kind: "component", type: StRowActionsDropdownComponent, selector: "st-row-actions-dropdown", inputs: ["isOpen", "position", "context"], outputs: ["actionClicked", "closed"] }, { kind: "directive", type: StKeyboardNavigationDirective, selector: "[stKeyboardNavigation]", inputs: ["tableState", "addRowOnNavigatePastEnd"] }, { kind: "directive", type: StColumnResizeDirective, selector: "[stColumnResize]", inputs: ["column"], outputs: ["columnResized", "columnResizing"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] }); }
9663
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9664
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StTableComponent, isStandalone: true, selector: "st-table", inputs: { tableConfig: { classPropertyName: "tableConfig", publicName: "tableConfig", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, data$: { classPropertyName: "data$", publicName: "data$", isSignal: true, isRequired: false, transformFunction: null }, tableState: { classPropertyName: "tableState", publicName: "tableState", isSignal: true, isRequired: false, transformFunction: null }, enableSorting: { classPropertyName: "enableSorting", publicName: "enableSorting", isSignal: true, isRequired: false, transformFunction: null }, enableFiltering: { classPropertyName: "enableFiltering", publicName: "enableFiltering", isSignal: true, isRequired: false, transformFunction: null }, validateConfig: { classPropertyName: "validateConfig", publicName: "validateConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stateChange: "stateChange", dataChange: "dataChange", cellEdit: "cellEdit", cellSave: "cellSave", cellCancel: "cellCancel", cellChange: "cellChange", columnResized: "columnResized", columnMoved: "columnMoved", configValidationErrors: "configValidationErrors", columnAdded: "columnAdded", rowAction: "rowAction", validationStateChange: "validationStateChange", requestAddRow: "requestAddRow" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "<!-- Top pagination controls -->\n@if (showTopPagination() && !(mergedConfig()?.tableSkeleton?.enabled | async)) {\n <st-pagination \n [tableState]=\"getActiveTableState()\"\n [tableConfig]=\"mergedConfig()!\"\n position=\"top\">\n </st-pagination>\n}\n\n@if (!(mergedConfig()?.tableSkeleton?.enabled | async)) {\n <div class=\"st-table\"\n [ngClass]=\"{\n 'virtual-scroll-enabled': isVirtualScrollEnabled(),\n 'keyboard-navigation-enabled': isKeyboardNavigationEnabled()\n }\"\n [ngStyle]=\"{\n 'max-height.px': !isVirtualScrollEnabled() ? mergedConfig()?.display?.maxHeight : null\n }\"\n stKeyboardNavigation\n [tableState]=\"getActiveTableState()\"\n [addRowOnNavigatePastEnd]=\"mergedConfig()?.features?.keyboardNavigation?.addRowOnNavigatePastEnd || false\"\n [attr.tabindex]=\"isKeyboardNavigationEnabled() ? 0 : -1\"\n (focus)=\"onTableContainerFocus($event)\"\n [attr.title]=\"isKeyboardNavigationEnabled() ? 'Click a cell or press Tab to start keyboard navigation' : null\">\n <!-- Unified Table Actions Menu -->\n\n <!-- Virtual scroll viewport wrapper -->\n @if (isVirtualScrollEnabled()) {\n <div class=\"st-scroll-viewport\" #scrollViewport\n [ngStyle]=\"{ 'height.px': getVirtualScrollViewportHeight() }\">\n\n <!-- Spacer to create scrollable area -->\n <div class=\"st-scroll-spacer\" [ngStyle]=\"{ 'height.px': virtualScrollTotalHeight() }\">\n </div>\n\n <!-- Table positioner with transform (instead of tbody) -->\n <div class=\"st-table-positioner\" [ngStyle]=\"{ transform: 'translateY(' + virtualScrollOffsetY() + 'px)' }\">\n <!-- Table with only visible rows -->\n <ng-container *ngTemplateOutlet=\"tableTemplate; context: { \n mode: 'virtual',\n theadStyle: { top: virtualScrollOffsetYNeg() + 'px' }\n }\"></ng-container>\n </div>\n </div>\n }\n \n <!-- Standard table (when virtual scroll disabled) -->\n @if (!isVirtualScrollEnabled()) {\n <ng-container *ngTemplateOutlet=\"tableTemplate; context: { \n mode: 'standard',\n theadStyle: null\n }\"></ng-container>\n }\n\n <!-- Shared Column Menu Dropdown -->\n <st-column-menu-dropdown \n [isOpen]=\"columnMenuState().isOpen\"\n [position]=\"columnMenuState().position\"\n [context]=\"columnMenuState().context\"\n (actionClicked)=\"onColumnActionClicked($event)\"\n (closed)=\"closeColumnMenu()\">\n </st-column-menu-dropdown>\n </div>\n}\n\n@if (mergedConfig()?.tableSkeleton?.enabled | async) {\n <ng-container *ngTemplateOutlet=\"skeletonLoader\"></ng-container>\n}\n\n<!-- Shared Row Actions Dropdown -->\n<st-row-actions-dropdown [isOpen]=\"dropdownState().isOpen\" [position]=\"dropdownState().position\"\n [context]=\"dropdownState().context\" (actionClicked)=\"onRowActionClicked($event)\" (closed)=\"closeRowActionsDropdown()\">\n</st-row-actions-dropdown>\n\n\n<!-- Bottom pagination controls -->\n@if (showBottomPagination() && !(mergedConfig()?.tableSkeleton?.enabled | async)) {\n <st-pagination \n [tableState]=\"getActiveTableState()\"\n [tableConfig]=\"mergedConfig()!\"\n position=\"bottom\">\n</st-pagination>\n}\n\n\n<!-- ========================================== -->\n<!-- REUSABLE TABLE TEMPLATE -->\n<!-- ========================================== -->\n<ng-template #tableTemplate let-mode=\"mode\" let-theadStyle=\"theadStyle\">\n <table class=\"st-table-element\">\n <!-- TABLE HEADER -->\n <thead [ngClass]=\"{ 'sticky': mergedConfig()?.display?.stickyHeader }\" [ngStyle]=\"theadStyle\">\n <tr>\n <!-- Row Number Header -->\n @if (mergedConfig()?.showRowNumber) {\n <th class=\"row-number-header header-cell sticky-left\"\n [ngStyle]=\"{\n position: 'sticky',\n 'left.px': 0,\n 'z-index': ZIndex.STICKY_HEADER_CELL,\n 'width.px': 30\n }\">\n #\n </th>\n }\n <!-- Column Headers -->\n @for (column of visibleColumns(); track column.key; let colIndex = $index, isFirst = $first, isLast = $last) {\n <th \n [ngClass]=\"{\n 'header-cell': mode === 'standard',\n 'sticky-left': column.sticky === 'left',\n 'sticky-right': column.sticky === 'right',\n 'sticky-right-first': column.sticky === 'right' && isFirstStickyRight(column.key),\n 'resizable': column.resizable !== false\n }\"\n [ngStyle]=\"{\n position: column.sticky ? 'sticky' : null,\n 'left.px': column.sticky === 'left' ? (column.stickyOffset || 0) : null,\n 'right.px': column.sticky === 'right' ? (column.stickyOffset || 0) : null,\n 'z-index': column.sticky ? ZIndex.STICKY_HEADER_CELL : null,\n 'width.px': column.width\n }\">\n \n <st-header \n [column]=\"column\"\n [columnIndex]=\"colIndex\"\n [isFirstColumn]=\"isFirst\"\n [isLastColumn]=\"isLast\"\n [tableState]=\"getActiveTableState()\"\n [enableSorting]=\"mergedConfig()?.sorting?.enabled ?? enableSorting()\"\n [enableFiltering]=\"mergedConfig()?.filtering?.enabled ?? enableFiltering()\"\n (columnMoved)=\"onColumnMoved($event)\"\n (menuClick)=\"openColumnMenu($event, column, colIndex, isFirst, isLast)\">\n </st-header>\n\n @if (column.resizable !== false) {\n <div \n class=\"resize-handle\" \n stColumnResize\n [column]=\"column\"\n (columnResizing)=\"onColumnResizing($event)\"\n (columnResized)=\"onColumnResized($event)\">\n </div>\n }\n </th>\n }\n \n <!-- Settings Column Header -->\n <th \n class=\"settings-column sticky-right\"\n [ngClass]=\"{ 'header-cell': mode === 'standard' }\"\n [ngStyle]=\"{ 'z-index': ZIndex.STICKY_HEADER_CELL }\">\n <div [ngClass]=\"{ 'flex-center': mode === 'virtual', 'header-content': mode === 'standard' }\">\n <st-table-actions \n [tableState]=\"getActiveTableState()\"\n [allowAddColumn]=\"mergedConfig()?.features?.columnManagement?.allowAdd || false\"\n (addColumnClicked)=\"onAddColumnClick()\">\n </st-table-actions>\n </div>\n </th>\n </tr>\n </thead>\n\n <!-- TABLE BODY -->\n <tbody>\n <!-- Virtual Scroll Rows -->\n @if (mode === 'virtual') {\n @for (row of visibleRows(); track trackByRowIndex($index, row); let relativeIndex = $index) {\n <tr [attr.data-row-index]=\"getAbsoluteRowIndex(relativeIndex)\">\n <!-- Row Number Cell -->\n @if (mergedConfig()?.showRowNumber) {\n <td class=\"row-number-cell\" \n [ngClass]=\"{ 'sticky-left': 'left' }\"\n [ngStyle]=\"{\n 'width.px': 30,\n position: 'sticky',\n 'left.px': 0,\n 'z-index': ZIndex.STICKY_BODY_CELL,\n 'height.px': mode === 'virtual' ? getVirtualScrollItemSize() : null\n }\">\n {{getAbsoluteRowIndex(relativeIndex) + 1}}\n </td>\n }\n <ng-container *ngTemplateOutlet=\"bodyCellTemplate; context: { \n row: row,\n rowIndex: getAbsoluteRowIndex(relativeIndex),\n mode: 'virtual',\n relativeIndex: relativeIndex\n }\"></ng-container>\n </tr>\n }\n }\n\n <!-- Standard Rows -->\n @if (mode === 'standard') {\n @for (row of visibleCellGrid(); track $index; let rowIndex = $index) {\n <tr [attr.data-row-index]=\"rowIndex\">\n <!-- Row Number Cell -->\n @if (mergedConfig()?.showRowNumber) {\n <td class=\"row-number-cell\" \n [ngClass]=\"{ 'sticky-left': 'left' }\"\n [ngStyle]=\"{\n 'width.px': 30,\n position: 'sticky',\n 'left.px': 0,\n 'z-index': ZIndex.STICKY_BODY_CELL,\n 'height.px': mode === 'virtual' ? getVirtualScrollItemSize() : null\n }\">\n {{rowIndex + 1}}\n </td>\n }\n <ng-container *ngTemplateOutlet=\"bodyCellTemplate; context: { \n row: row,\n rowIndex: rowIndex,\n mode: 'standard'\n }\"></ng-container>\n </tr>\n }\n }\n </tbody>\n </table>\n</ng-template>\n\n<!-- ========================================== -->\n<!-- REUSABLE BODY CELL TEMPLATE -->\n<!-- ========================================== -->\n<ng-template #bodyCellTemplate let-row=\"row\" let-rowIndex=\"rowIndex\" let-mode=\"mode\" let-relativeIndex=\"relativeIndex\">\n <!-- Data Cells -->\n @for (cell of row; track $index; let colIndex = $index) {\n <td \n [ngClass]=\"{\n 'sticky-left': visibleColumns()[colIndex]?.sticky === 'left',\n 'sticky-right': visibleColumns()[colIndex]?.sticky === 'right',\n 'sticky-right-first': visibleColumns()[colIndex]?.sticky === 'right' && visibleColumns()[colIndex]?.key && isFirstStickyRight(visibleColumns()[colIndex].key),\n 'align-center': visibleColumns()[colIndex]?.alignment === 'center',\n 'align-right': visibleColumns()[colIndex]?.alignment === 'right',\n 'cell-focused': cell.isFocused()\n }\"\n [ngStyle]=\"{\n position: visibleColumns()[colIndex]?.sticky ? 'sticky' : null,\n 'left.px': visibleColumns()[colIndex]?.sticky === 'left' ? (visibleColumns()[colIndex]?.stickyOffset || 0) : null,\n 'right.px': visibleColumns()[colIndex]?.sticky === 'right' ? (visibleColumns()[colIndex]?.stickyOffset || 0) : null,\n 'z-index': visibleColumns()[colIndex]?.sticky ? ZIndex.STICKY_BODY_CELL : null,\n 'width.px': visibleColumns()[colIndex]?.width,\n 'height.px': mode === 'virtual' ? getVirtualScrollItemSize() : null\n }\"\n (click)=\"isKeyboardNavigationEnabled() ? onCellClick(rowIndex, colIndex) : null\">\n \n <!-- Virtual Scroll Cell -->\n @if (mode === 'virtual') {\n <st-cell \n [cell]=\"cell\" \n [attr.tabindex]=\"cell.isFocused() ? 0 : -1\" \n [editMode]=\"getEditModeForCells()\"\n [tableState]=\"getActiveTableState()\"\n [tableConfig]=\"mergedConfig()!\"\n [columnIndex]=\"colIndex\"\n (cellEdit)=\"onCellEdit($event)\" \n (cellSave)=\"onCellSave($event)\"\n (cellSaveAndNavigate)=\"onCellSaveAndNavigate($event)\" \n (cellCancel)=\"onCellCancel($event)\"\n (cellChange)=\"cellChange.emit($event)\">\n </st-cell>\n }\n\n <!-- Standard Cell -->\n @if (mode === 'standard') {\n <st-cell \n [cell]=\"cell\" \n [attr.tabindex]=\"cell.isFocused() ? 0 : -1\"\n [tableState]=\"getActiveTableState()\"\n [tableConfig]=\"mergedConfig()!\"\n [columnIndex]=\"colIndex\"\n (cellSave)=\"onCellSave($event)\"\n (cellChange)=\"cellChange.emit($event)\">\n </st-cell>\n }\n </td>\n }\n \n <!-- Row Actions Cell -->\n <td class=\"settings-column\"\n [ngClass]=\"{\n 'has-actions': hasRowActions()\n }\"\n [ngStyle]=\"{\n position: hasRowActions() ? 'sticky' : null,\n 'right.px': hasRowActions() ? 0 : null,\n 'z-index': hasRowActions() ? ZIndex.STICKY_BODY_CELL : null\n }\">\n @if (hasRowActions()) {\n <button \n class=\"settings-trigger\"\n (click)=\"openRowActionsDropdown($event, getRowData(rowIndex), rowIndex)\"\n type=\"button\" \n aria-label=\"Row actions\">\n \u22EF\n </button>\n }\n </td>\n</ng-template>\n\n<ng-template #skeletonLoader>\n @if (mergedConfig()?.tableSkeleton?.enabled | async) {\n <div class=\"list-row\">\n @for (i of skeletonColumns; track $index) {\n <div class=\"list-content\">\n @for (j of skeletonRows; track $index) {\n <nile-skeleton-loader variant=\"text\" width=\"90%\" height=\"18\"></nile-skeleton-loader>\n }\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: [".st-table{width:100%;overflow:auto;position:relative;height:100%;max-height:30rem;border-radius:4px;border:1px solid #E6E9EB}.st-table st-table-actions{position:sticky;right:0}.st-table.keyboard-navigation-enabled{cursor:pointer}.st-table.keyboard-navigation-enabled:focus{outline:none;box-shadow:0 0 0 2px #3b82f64d}.st-table.keyboard-navigation-enabled td.cell-focused{outline:2px solid #4299e1;outline-offset:-1px;position:relative;box-shadow:0 0 0 3px #3182ce1a}.st-table.keyboard-navigation-enabled td.cell-focused:focus{outline:2px solid #4299e1;outline-offset:-1px;box-shadow:0 0 0 3px #3182ce1a}.st-table.keyboard-navigation-enabled td.cell-focused:has(.st-cell.editing){box-shadow:0 0 0 4px #2563eb26}.st-table.virtual-scroll-enabled{overflow-x:visible;margin:0;border:1px solid #E6E9EB;border-collapse:separate;border-spacing:0}.st-table.virtual-scroll-enabled .st-scroll-viewport{position:relative;overflow-y:auto;overflow-x:auto;scroll-behavior:smooth}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-scroll-spacer{position:absolute;top:0;left:0;width:1px;pointer-events:none;z-index:-1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-positioner{position:absolute;top:0;left:0;right:0;will-change:transform}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element{position:relative;width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead{background-color:#fff;border-bottom:1px solid #E6E9EB}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead.sticky{position:sticky;top:0;z-index:3;background-color:#fff;will-change:top;backface-visibility:hidden}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead.sticky:after{content:\"\";position:absolute;bottom:-2px;left:0;right:0;height:2px;background:linear-gradient(to bottom,rgba(0,0,0,.1),transparent)}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th{padding:0;vertical-align:middle;position:relative;border:none;background-color:#fff;will-change:top;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-left{position:sticky;left:0;background-color:#fff;z-index:2;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)):after{content:\"\";position:absolute;right:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to left,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-right{position:sticky;right:0;background-color:#fff;z-index:2;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-right-first:not(.settings-column){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to right,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.settings-column{width:2rem;text-align:center;font-weight:600;font-size:12px;position:sticky;right:0;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb;z-index:2}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.resizable .resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;z-index:4;pointer-events:auto}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.resizable .resize-handle:after{content:\"\";position:absolute;top:50%;right:3px;transform:translateY(-50%);width:2px;height:20px;background-color:#cbd5e0;opacity:0;transition:opacity .2s}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.resizable .resize-handle:hover:after,.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.resizable .resize-handle:active:after{opacity:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.row-number-header{text-align:center;font-weight:300;font-size:12px;background-color:#f8f8f8}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)):after{content:\"\";position:absolute;right:-6px;top:0;bottom:-1px;width:5px;border-left:1px solid var(--borderColor);background:linear-gradient(90deg,#00000014,#0000)}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element thead tr th.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-6px;top:0;bottom:-1px;width:5px;border-right:1px solid var(--borderColor);background:linear-gradient(90deg,#0000,#00000014)}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody{will-change:transform;position:relative;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr{border-bottom:1px solid #E6E9EB;transition:background-color .15s;height:2rem;box-sizing:border-box}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr:last-child{border-bottom:none}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td{padding:0;vertical-align:middle;box-sizing:border-box;height:2rem;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb;border:none}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.align-center{text-align:center}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.align-right{text-align:right}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-left{position:sticky;z-index:2;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)):after{content:\"\";position:absolute;right:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to left,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-right{position:sticky;z-index:2;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-right-first:not(.settings-column){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to right,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.settings-column{width:2rem;text-align:center;position:sticky;right:0;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb;z-index:2}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.settings-column .settings-trigger{background:none;border:none;font-size:1rem;line-height:1;cursor:pointer;border-radius:4px;transition:all .15s ease}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.settings-column .settings-trigger:focus{outline:2px solid #4299e1;outline-offset:2px}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.row-number-cell{text-align:center;font-weight:300;font-size:12px;background-color:#f8f8f8}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)):after{content:\"\";position:absolute;right:-6px;top:0;bottom:-1px;width:5px;border-left:1px solid var(--borderColor);background:linear-gradient(90deg,#00000014,#0000)}.st-table.virtual-scroll-enabled .st-scroll-viewport .st-table-element tbody tr td.sticky-right-first:before{content:\"\";position:absolute;left:-6px;top:0;bottom:-1px;width:5px;border-right:1px solid var(--borderColor);background:linear-gradient(90deg,#0000,#00000014)}.st-table:not(.virtual-scroll-enabled) .st-table-element{width:100%;height:100%;overflow:auto;border-collapse:separate;border-spacing:0;table-layout:fixed}.st-table:not(.virtual-scroll-enabled) .st-table-element thead{background-color:#fff;border-bottom:1px solid #E6E9EB}.st-table:not(.virtual-scroll-enabled) .st-table-element thead.sticky{position:sticky;top:0;z-index:3;background-color:#fff;will-change:top;backface-visibility:hidden}.st-table:not(.virtual-scroll-enabled) .st-table-element thead.sticky:after{content:\"\";position:absolute;bottom:-2px;left:0;right:0;height:2px;background:linear-gradient(to bottom,rgba(0,0,0,.1),transparent)}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th{padding:0;vertical-align:middle;position:relative;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb;border:none}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-left{position:sticky;left:0;background-color:#fff;z-index:2;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-left:not(:has(~th.sticky-left)):after{content:\"\";position:absolute;right:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to left,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-right{position:sticky;right:0;background-color:#fff;z-index:2;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-right-first:not(.settings-column){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to right,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.settings-column{width:2rem;text-align:center;font-weight:600;font-size:12px;position:sticky;right:0;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb;z-index:2}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.resizable .resize-handle{position:absolute;top:0;right:0;bottom:0;width:8px;cursor:col-resize;z-index:4;pointer-events:auto}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.resizable .resize-handle:after{content:\"\";position:absolute;top:50%;right:3px;transform:translateY(-50%);width:2px;height:20px;background-color:#cbd5e0;opacity:0;transition:opacity .2s}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.resizable .resize-handle:hover:after,.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.resizable .resize-handle:active:after{opacity:1}.st-table:not(.virtual-scroll-enabled) .st-table-element thead tr th.row-number-header{text-align:center;font-weight:300;font-size:12px;background-color:#f8f8f8}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody{will-change:transform;position:relative;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr{height:2rem;box-sizing:border-box}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr:last-child{border-bottom:none}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td{padding:0;vertical-align:middle;height:2rem;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb;border:none}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.row-number-cell{text-align:center;font-weight:300;font-size:12px;background-color:#f8f8f8}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.align-center{text-align:center}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.align-right{text-align:right}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-left{position:sticky;z-index:2;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset -1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-left:not(:has(~td.sticky-left)):after{content:\"\";position:absolute;right:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to left,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-right{position:sticky;z-index:2;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-right-first:not(.settings-column){position:relative;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.sticky-right-first:not(.settings-column):before{content:\"\";position:absolute;left:-8px;top:0;bottom:0;width:8px;background:linear-gradient(to right,transparent,rgba(0,0,0,.08));pointer-events:none;z-index:1}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.settings-column{position:sticky;right:0;width:2rem;text-align:center;border-right:none;background-color:#fff;box-shadow:inset 0 -1px #e6e9eb,inset 1px 0 #e6e9eb;z-index:2}.st-table:not(.virtual-scroll-enabled) .st-table-element tbody tr td.settings-column .settings-trigger{background:none;border:none;font-size:1rem;line-height:1;cursor:pointer;border-radius:4px;transition:all .15s ease}.st-table:not(.virtual-scroll-enabled) .st-table-element .header-content{display:flex;height:2rem;align-items:center}.st-table:not(.virtual-scroll-enabled) .st-table-element .header-content .table-header-text{flex-grow:1;padding-left:4px}.st-table:not(.virtual-scroll-enabled) .st-table-element .settings-column>.header-content{display:flex;align-items:center;justify-content:center}.flex-center{display:flex;align-items:center;justify-content:center}.list-row .list-content{display:flex;justify-content:space-evenly;gap:4px;margin-bottom:1rem}.list-row{padding:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: StPaginationComponent, selector: "st-pagination", inputs: ["tableState", "tableConfig", "position"] }, { kind: "component", type: StHeaderComponent, selector: "st-header", inputs: ["column", "columnIndex", "isFirstColumn", "isLastColumn", "tableState", "enableSorting", "enableFiltering"], outputs: ["sortToggle", "filterChange", "columnMoved", "menuClick"] }, { kind: "component", type: StCellComponent, selector: "st-cell", inputs: ["cell", "editMode", "tableState", "tableConfig", "columnIndex"], outputs: ["cellChange", "cellEdit", "cellSave", "cellCancel", "cellSaveAndNavigate"] }, { kind: "component", type: StTableActionsComponent, selector: "st-table-actions", inputs: ["tableState", "allowAddColumn"], outputs: ["addColumnClicked"] }, { kind: "component", type: StColumnMenuDropdownComponent, selector: "st-column-menu-dropdown", inputs: ["isOpen", "position", "context"], outputs: ["actionClicked", "closed"] }, { kind: "component", type: StRowActionsDropdownComponent, selector: "st-row-actions-dropdown", inputs: ["isOpen", "position", "context"], outputs: ["actionClicked", "closed"] }, { kind: "directive", type: StKeyboardNavigationDirective, selector: "[stKeyboardNavigation]", inputs: ["tableState", "addRowOnNavigatePastEnd"] }, { kind: "directive", type: StColumnResizeDirective, selector: "[stColumnResize]", inputs: ["column"], outputs: ["columnResized", "columnResizing"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] }); }
8815
9665
  }
8816
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StTableComponent, decorators: [{
9666
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StTableComponent, decorators: [{
8817
9667
  type: Component,
8818
9668
  args: [{ selector: 'st-table', standalone: true, imports: [
8819
9669
  CommonModule,
@@ -8917,10 +9767,10 @@ class StColumnVisibilityComponent {
8917
9767
  const column = this.tableState.getColumns().find(col => col.key === columnKey);
8918
9768
  return column ? (column.visible !== false) : true;
8919
9769
  }
8920
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnVisibilityComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8921
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StColumnVisibilityComponent, isStandalone: true, selector: "st-column-visibility", inputs: { tableState: "tableState" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"st-column-visibility\" (clickOutside)=\"closeMenu()\">\n <button class=\"visibility-trigger\" \n (click)=\"toggleMenu($event)\" \n title=\"Show/Hide Columns\"\n type=\"button\"\n [class.active]=\"isOpen\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2 2H14V14H2V2Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 2V14M8 2V14M11 2V14\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n \n @if (isOpen) {\n <div class=\"visibility-dropdown\">\n <div class=\"dropdown-header\">Show/Hide Columns</div>\n <div class=\"dropdown-content\">\n @for (column of getColumnsVisibility(); track column.key) {\n <label class=\"column-item\"\n [class.checked]=\"column.visible\"\n [class.disabled]=\"column.hideable === false\">\n <input type=\"checkbox\" \n [checked]=\"column.visible\"\n [disabled]=\"column.hideable === false\"\n [title]=\"column.hideable === false ? 'This column cannot be hidden' : ''\"\n (change)=\"onToggleColumn(column.key, $event)\">\n <span class=\"column-label\">{{ column.header }}</span>\n </label>\n }\n </div>\n </div>\n }\n</div>\n", styles: [".st-column-visibility{position:absolute;top:8px;right:8px;z-index:1000;display:inline-block}.st-column-visibility .visibility-trigger{background:#fff;border:1px solid #e2e8f0;border-radius:4px;cursor:pointer;padding:6px 8px;color:#718096;line-height:1;transition:all .2s;box-shadow:0 1px 2px #0000000d}.st-column-visibility .visibility-trigger:hover{background-color:#f7fafc;border-color:#cbd5e0;color:#2d3748}.st-column-visibility .visibility-trigger.active{background-color:#ebf8ff;border-color:#2b6cb0;color:#2b6cb0}.st-column-visibility .visibility-trigger svg{display:block;width:16px;height:16px}.st-column-visibility .visibility-dropdown{position:absolute;top:100%;right:0;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 6px #0000001a,0 2px 4px #0000000f;z-index:1001;min-width:200px;margin-top:4px;overflow:hidden}.st-column-visibility .visibility-dropdown .dropdown-header{padding:10px 14px;font-weight:600;font-size:13px;color:#2d3748;border-bottom:1px solid #e2e8f0;background-color:#f7fafc}.st-column-visibility .visibility-dropdown .dropdown-content{max-height:10rem;overflow-y:auto;overflow-x:hidden}.st-column-visibility .visibility-dropdown .dropdown-content .column-item{display:flex;align-items:center;padding:10px 14px;cursor:pointer;transition:background-color .2s;-webkit-user-select:none;user-select:none}.st-column-visibility .visibility-dropdown .dropdown-content .column-item:hover{background-color:#f7fafc}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.checked{background-color:#ebf8ff}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.disabled{opacity:.6;cursor:not-allowed}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.disabled:hover{background-color:transparent;cursor:not-allowed}.st-column-visibility .visibility-dropdown .dropdown-content .column-item input[type=checkbox]{margin-right:10px;cursor:pointer;width:16px;height:16px;flex-shrink:0}.st-column-visibility .visibility-dropdown .dropdown-content .column-item input[type=checkbox]:disabled{cursor:not-allowed;opacity:.5}.st-column-visibility .visibility-dropdown .dropdown-content .column-item .column-label{font-size:14px;color:#2d3748;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
9770
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnVisibilityComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9771
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StColumnVisibilityComponent, isStandalone: true, selector: "st-column-visibility", inputs: { tableState: "tableState" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"st-column-visibility\" (clickOutside)=\"closeMenu()\">\n <button class=\"visibility-trigger\" \n (click)=\"toggleMenu($event)\" \n title=\"Show/Hide Columns\"\n type=\"button\"\n [class.active]=\"isOpen\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2 2H14V14H2V2Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 2V14M8 2V14M11 2V14\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n \n @if (isOpen) {\n <div class=\"visibility-dropdown\">\n <div class=\"dropdown-header\">Show/Hide Columns</div>\n <div class=\"dropdown-content\">\n @for (column of getColumnsVisibility(); track column.key) {\n <label class=\"column-item\"\n [class.checked]=\"column.visible\"\n [class.disabled]=\"column.hideable === false\">\n <input type=\"checkbox\" \n [checked]=\"column.visible\"\n [disabled]=\"column.hideable === false\"\n [title]=\"column.hideable === false ? 'This column cannot be hidden' : ''\"\n (change)=\"onToggleColumn(column.key, $event)\">\n <span class=\"column-label\">{{ column.header }}</span>\n </label>\n }\n </div>\n </div>\n }\n</div>\n", styles: [".st-column-visibility{position:absolute;top:8px;right:8px;z-index:1000;display:inline-block}.st-column-visibility .visibility-trigger{background:#fff;border:1px solid #e2e8f0;border-radius:4px;cursor:pointer;padding:6px 8px;color:#718096;line-height:1;transition:all .2s;box-shadow:0 1px 2px #0000000d}.st-column-visibility .visibility-trigger:hover{background-color:#f7fafc;border-color:#cbd5e0;color:#2d3748}.st-column-visibility .visibility-trigger.active{background-color:#ebf8ff;border-color:#2b6cb0;color:#2b6cb0}.st-column-visibility .visibility-trigger svg{display:block;width:16px;height:16px}.st-column-visibility .visibility-dropdown{position:absolute;top:100%;right:0;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 6px #0000001a,0 2px 4px #0000000f;z-index:1001;min-width:200px;margin-top:4px;overflow:hidden}.st-column-visibility .visibility-dropdown .dropdown-header{padding:10px 14px;font-weight:600;font-size:13px;color:#2d3748;border-bottom:1px solid #e2e8f0;background-color:#f7fafc}.st-column-visibility .visibility-dropdown .dropdown-content{max-height:10rem;overflow-y:auto;overflow-x:hidden}.st-column-visibility .visibility-dropdown .dropdown-content .column-item{display:flex;align-items:center;padding:10px 14px;cursor:pointer;transition:background-color .2s;-webkit-user-select:none;user-select:none}.st-column-visibility .visibility-dropdown .dropdown-content .column-item:hover{background-color:#f7fafc}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.checked{background-color:#ebf8ff}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.disabled{opacity:.6;cursor:not-allowed}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.disabled:hover{background-color:transparent;cursor:not-allowed}.st-column-visibility .visibility-dropdown .dropdown-content .column-item input[type=checkbox]{margin-right:10px;cursor:pointer;width:16px;height:16px;flex-shrink:0}.st-column-visibility .visibility-dropdown .dropdown-content .column-item input[type=checkbox]:disabled{cursor:not-allowed;opacity:.5}.st-column-visibility .visibility-dropdown .dropdown-content .column-item .column-label{font-size:14px;color:#2d3748;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
8922
9772
  }
8923
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnVisibilityComponent, decorators: [{
9773
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnVisibilityComponent, decorators: [{
8924
9774
  type: Component,
8925
9775
  args: [{ selector: 'st-column-visibility', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"st-column-visibility\" (clickOutside)=\"closeMenu()\">\n <button class=\"visibility-trigger\" \n (click)=\"toggleMenu($event)\" \n title=\"Show/Hide Columns\"\n type=\"button\"\n [class.active]=\"isOpen\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2 2H14V14H2V2Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 2V14M8 2V14M11 2V14\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n \n @if (isOpen) {\n <div class=\"visibility-dropdown\">\n <div class=\"dropdown-header\">Show/Hide Columns</div>\n <div class=\"dropdown-content\">\n @for (column of getColumnsVisibility(); track column.key) {\n <label class=\"column-item\"\n [class.checked]=\"column.visible\"\n [class.disabled]=\"column.hideable === false\">\n <input type=\"checkbox\" \n [checked]=\"column.visible\"\n [disabled]=\"column.hideable === false\"\n [title]=\"column.hideable === false ? 'This column cannot be hidden' : ''\"\n (change)=\"onToggleColumn(column.key, $event)\">\n <span class=\"column-label\">{{ column.header }}</span>\n </label>\n }\n </div>\n </div>\n }\n</div>\n", styles: [".st-column-visibility{position:absolute;top:8px;right:8px;z-index:1000;display:inline-block}.st-column-visibility .visibility-trigger{background:#fff;border:1px solid #e2e8f0;border-radius:4px;cursor:pointer;padding:6px 8px;color:#718096;line-height:1;transition:all .2s;box-shadow:0 1px 2px #0000000d}.st-column-visibility .visibility-trigger:hover{background-color:#f7fafc;border-color:#cbd5e0;color:#2d3748}.st-column-visibility .visibility-trigger.active{background-color:#ebf8ff;border-color:#2b6cb0;color:#2b6cb0}.st-column-visibility .visibility-trigger svg{display:block;width:16px;height:16px}.st-column-visibility .visibility-dropdown{position:absolute;top:100%;right:0;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 6px #0000001a,0 2px 4px #0000000f;z-index:1001;min-width:200px;margin-top:4px;overflow:hidden}.st-column-visibility .visibility-dropdown .dropdown-header{padding:10px 14px;font-weight:600;font-size:13px;color:#2d3748;border-bottom:1px solid #e2e8f0;background-color:#f7fafc}.st-column-visibility .visibility-dropdown .dropdown-content{max-height:10rem;overflow-y:auto;overflow-x:hidden}.st-column-visibility .visibility-dropdown .dropdown-content .column-item{display:flex;align-items:center;padding:10px 14px;cursor:pointer;transition:background-color .2s;-webkit-user-select:none;user-select:none}.st-column-visibility .visibility-dropdown .dropdown-content .column-item:hover{background-color:#f7fafc}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.checked{background-color:#ebf8ff}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.disabled{opacity:.6;cursor:not-allowed}.st-column-visibility .visibility-dropdown .dropdown-content .column-item.disabled:hover{background-color:transparent;cursor:not-allowed}.st-column-visibility .visibility-dropdown .dropdown-content .column-item input[type=checkbox]{margin-right:10px;cursor:pointer;width:16px;height:16px;flex-shrink:0}.st-column-visibility .visibility-dropdown .dropdown-content .column-item input[type=checkbox]:disabled{cursor:not-allowed;opacity:.5}.st-column-visibility .visibility-dropdown .dropdown-content .column-item .column-label{font-size:14px;color:#2d3748;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"] }]
8926
9776
  }], ctorParameters: () => [], propDecorators: { tableState: [{
@@ -8936,10 +9786,10 @@ class StAddColumnButtonComponent {
8936
9786
  event.stopPropagation();
8937
9787
  this.addColumnClicked.emit();
8938
9788
  }
8939
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StAddColumnButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8940
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StAddColumnButtonComponent, isStandalone: true, selector: "st-add-column-button", inputs: { enabled: "enabled" }, outputs: { addColumnClicked: "addColumnClicked" }, ngImport: i0, template: "@if (enabled) {\n <button \n class=\"st-add-column-button\"\n (click)=\"onClick($event)\"\n type=\"button\"\n title=\"Add Column\"\n aria-label=\"Add new column\">\n <svg class=\"st-add-column-icon\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 5V19M5 12H19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n}\n", styles: [".st-add-column-button{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background-color:#1976d2;color:#fff;border:none;box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s cubic-bezier(.4,0,.2,1);z-index:1000}.st-add-column-button:hover{background-color:#1565c0;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;transform:scale(1.05)}.st-add-column-button:active{box-shadow:0 7px 8px -4px #0003,0 12px 17px 2px #00000024,0 5px 22px 4px #0000001f;transform:scale(.98)}.st-add-column-button:focus{outline:none;box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f,0 0 0 3px #1976d24d}.st-add-column-icon{width:24px;height:24px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
9789
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StAddColumnButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9790
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StAddColumnButtonComponent, isStandalone: true, selector: "st-add-column-button", inputs: { enabled: "enabled" }, outputs: { addColumnClicked: "addColumnClicked" }, ngImport: i0, template: "@if (enabled) {\n <button \n class=\"st-add-column-button\"\n (click)=\"onClick($event)\"\n type=\"button\"\n title=\"Add Column\"\n aria-label=\"Add new column\">\n <svg class=\"st-add-column-icon\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 5V19M5 12H19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n}\n", styles: [".st-add-column-button{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background-color:#1976d2;color:#fff;border:none;box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s cubic-bezier(.4,0,.2,1);z-index:1000}.st-add-column-button:hover{background-color:#1565c0;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;transform:scale(1.05)}.st-add-column-button:active{box-shadow:0 7px 8px -4px #0003,0 12px 17px 2px #00000024,0 5px 22px 4px #0000001f;transform:scale(.98)}.st-add-column-button:focus{outline:none;box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f,0 0 0 3px #1976d24d}.st-add-column-icon{width:24px;height:24px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
8941
9791
  }
8942
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StAddColumnButtonComponent, decorators: [{
9792
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StAddColumnButtonComponent, decorators: [{
8943
9793
  type: Component,
8944
9794
  args: [{ selector: 'st-add-column-button', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "@if (enabled) {\n <button \n class=\"st-add-column-button\"\n (click)=\"onClick($event)\"\n type=\"button\"\n title=\"Add Column\"\n aria-label=\"Add new column\">\n <svg class=\"st-add-column-icon\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 5V19M5 12H19\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n}\n", styles: [".st-add-column-button{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background-color:#1976d2;color:#fff;border:none;box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s cubic-bezier(.4,0,.2,1);z-index:1000}.st-add-column-button:hover{background-color:#1565c0;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;transform:scale(1.05)}.st-add-column-button:active{box-shadow:0 7px 8px -4px #0003,0 12px 17px 2px #00000024,0 5px 22px 4px #0000001f;transform:scale(.98)}.st-add-column-button:focus{outline:none;box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f,0 0 0 3px #1976d24d}.st-add-column-icon{width:24px;height:24px}\n"] }]
8945
9795
  }], propDecorators: { enabled: [{
@@ -9132,10 +9982,10 @@ class ColumnEditorComponent {
9132
9982
  const control = this.form.get(controlName);
9133
9983
  return !!(control && control.invalid && (control.dirty || control.touched));
9134
9984
  }
9135
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ColumnEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
9136
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ColumnEditorComponent, isStandalone: true, selector: "st-column-editor", inputs: { column: "column", columnIndex: "columnIndex" }, outputs: { columnUpdated: "columnUpdated", cancel: "cancel" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"column-editor\">\n <div class=\"editor-header\">\n <h3>Column Editor</h3>\n <div class=\"editor-actions\">\n <button class=\"btn btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"onSave()\">Save</button>\n </div>\n </div>\n\n <form [formGroup]=\"form\" class=\"editor-form\">\n <!-- Basic Properties -->\n <div class=\"form-section\">\n <h4>Basic Properties</h4>\n <div class=\"form-group\">\n <label for=\"key\">Key *</label>\n <input\n id=\"key\"\n type=\"text\"\n formControlName=\"key\"\n class=\"form-control\"\n [class.error]=\"hasError('key')\"\n placeholder=\"columnKey\">\n @if (hasError('key')) {\n <span class=\"error-message\">\n {{ getErrorMessage('key') }}\n </span>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"header\">Header</label>\n <input\n id=\"header\"\n type=\"text\"\n formControlName=\"header\"\n class=\"form-control\"\n placeholder=\"Column Header\">\n </div>\n\n <div class=\"form-group\">\n <label for=\"dataType\">Data Type</label>\n <select id=\"dataType\" formControlName=\"dataType\" class=\"form-control\">\n @for (type of dataTypes; track type.value) {\n <option [value]=\"type.value\">\n {{ type.label }}\n </option>\n }\n </select>\n </div>\n </div>\n\n <!-- Features -->\n <div class=\"form-section\">\n <h4>Features</h4>\n <div class=\"checkbox-group\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"editable\">\n <span>Editable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"sortable\">\n <span>Sortable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"filterable\">\n <span>Filterable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"resizable\">\n <span>Resizable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"hideable\">\n <span>Hideable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"movable\">\n <span>Movable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"pinnable\">\n <span>Pinnable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enableMenu\">\n <span>Enable Menu</span>\n </label>\n </div>\n </div>\n\n <!-- Layout -->\n <div class=\"form-section\">\n <h4>Layout</h4>\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"width\">Width</label>\n <input\n id=\"width\"\n type=\"text\"\n formControlName=\"width\"\n class=\"form-control\"\n placeholder=\"150 or 'auto'\">\n </div>\n <div class=\"form-group\">\n <label for=\"minWidth\">Min Width</label>\n <input\n id=\"minWidth\"\n type=\"number\"\n formControlName=\"minWidth\"\n class=\"form-control\"\n placeholder=\"50\">\n </div>\n <div class=\"form-group\">\n <label for=\"maxWidth\">Max Width</label>\n <input\n id=\"maxWidth\"\n type=\"number\"\n formControlName=\"maxWidth\"\n class=\"form-control\"\n placeholder=\"500\">\n </div>\n </div>\n\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"sticky\">Sticky</label>\n <select id=\"sticky\" formControlName=\"sticky\" class=\"form-control\">\n @for (option of stickyOptions; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </select>\n </div>\n <div class=\"form-group\">\n <label for=\"alignment\">Alignment</label>\n <select id=\"alignment\" formControlName=\"alignment\" class=\"form-control\">\n @for (align of alignments; track align.value) {\n <option [value]=\"align.value\">\n {{ align.label }}\n </option>\n }\n </select>\n </div>\n <div class=\"form-group\">\n <label for=\"verticalAlignment\">Vertical Alignment</label>\n <select id=\"verticalAlignment\" formControlName=\"verticalAlignment\" class=\"form-control\">\n @for (align of verticalAlignments; track align.value) {\n <option [value]=\"align.value\">\n {{ align.label }}\n </option>\n }\n </select>\n </div>\n </div>\n </div>\n\n <!-- Edit Mode -->\n <div class=\"form-section\">\n <h4>Edit Mode</h4>\n <div class=\"form-group\">\n <label for=\"editMode\">Edit Trigger</label>\n <select id=\"editMode\" formControlName=\"editMode\" class=\"form-control\">\n @for (mode of editModes; track mode.value) {\n <option [value]=\"mode.value\">\n {{ mode.label }}\n </option>\n }\n </select>\n </div>\n </div>\n\n <!-- Display -->\n <div class=\"form-section\">\n <h4>Display</h4>\n <div class=\"checkbox-group\">\n <label class=\"checkbox-label\" [class.disabled]=\"!form.get('hideable')?.value\">\n <input type=\"checkbox\" \n formControlName=\"visible\"\n [disabled]=\"!form.get('hideable')?.value\"\n [title]=\"!form.get('hideable')?.value ? 'Column visibility cannot be changed when hideable is disabled' : ''\">\n <span>Visible</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"truncate\">\n <span>Truncate Text</span>\n </label>\n </div>\n </div>\n </form>\n</div>\n", styles: [".column-editor{display:flex;flex-direction:column;height:100%}.editor-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.editor-header h3{margin:0;font-size:1.125rem;font-weight:600;color:#333}.editor-actions{display:flex;gap:.5rem}.btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;cursor:pointer;font-size:.875rem;transition:all .2s}.btn.btn-primary{background-color:#2196f3;color:#fff;border-color:#2196f3}.btn.btn-primary:hover{background-color:#1976d2;border-color:#1976d2}.btn.btn-secondary{background-color:#fff;color:#333}.btn.btn-secondary:hover{background-color:#f5f5f5}.editor-form{flex:1;overflow-y:auto;padding:1rem}.form-section{margin-bottom:2rem}.form-section h4{margin:0 0 1rem;font-size:.875rem;font-weight:600;color:#666;text-transform:uppercase;letter-spacing:.5px}.form-group{margin-bottom:1rem}.form-group label{display:block;margin-bottom:.5rem;font-size:.875rem;font-weight:500;color:#333}.form-control{width:100%;padding:.5rem;border:1px solid #d0d0d0;border-radius:4px;font-size:.875rem;transition:border-color .2s}.form-control:focus{outline:none;border-color:#2196f3}.form-control.error{border-color:#f44336}.form-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1rem}.checkbox-group{display:flex;row-gap:1rem;flex-wrap:wrap;gap:.75rem}.checkbox-label{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.875rem;color:#333}.checkbox-label input[type=checkbox]{width:18px;height:18px;cursor:pointer}.checkbox-label input[type=checkbox]:disabled{cursor:not-allowed;opacity:.5}.checkbox-label.disabled{opacity:.6;cursor:not-allowed}.checkbox-label.disabled span{color:#999}.error-message{display:block;margin-top:.25rem;font-size:.75rem;color:#f44336}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
9985
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ColumnEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
9986
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: ColumnEditorComponent, isStandalone: true, selector: "st-column-editor", inputs: { column: "column", columnIndex: "columnIndex" }, outputs: { columnUpdated: "columnUpdated", cancel: "cancel" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"column-editor\">\n <div class=\"editor-header\">\n <h3>Column Editor</h3>\n <div class=\"editor-actions\">\n <button class=\"btn btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"onSave()\">Save</button>\n </div>\n </div>\n\n <form [formGroup]=\"form\" class=\"editor-form\">\n <!-- Basic Properties -->\n <div class=\"form-section\">\n <h4>Basic Properties</h4>\n <div class=\"form-group\">\n <label for=\"key\">Key *</label>\n <input\n id=\"key\"\n type=\"text\"\n formControlName=\"key\"\n class=\"form-control\"\n [class.error]=\"hasError('key')\"\n placeholder=\"columnKey\">\n @if (hasError('key')) {\n <span class=\"error-message\">\n {{ getErrorMessage('key') }}\n </span>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"header\">Header</label>\n <input\n id=\"header\"\n type=\"text\"\n formControlName=\"header\"\n class=\"form-control\"\n placeholder=\"Column Header\">\n </div>\n\n <div class=\"form-group\">\n <label for=\"dataType\">Data Type</label>\n <select id=\"dataType\" formControlName=\"dataType\" class=\"form-control\">\n @for (type of dataTypes; track type.value) {\n <option [value]=\"type.value\">\n {{ type.label }}\n </option>\n }\n </select>\n </div>\n </div>\n\n <!-- Features -->\n <div class=\"form-section\">\n <h4>Features</h4>\n <div class=\"checkbox-group\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"editable\">\n <span>Editable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"sortable\">\n <span>Sortable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"filterable\">\n <span>Filterable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"resizable\">\n <span>Resizable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"hideable\">\n <span>Hideable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"movable\">\n <span>Movable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"pinnable\">\n <span>Pinnable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enableMenu\">\n <span>Enable Menu</span>\n </label>\n </div>\n </div>\n\n <!-- Layout -->\n <div class=\"form-section\">\n <h4>Layout</h4>\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"width\">Width</label>\n <input\n id=\"width\"\n type=\"text\"\n formControlName=\"width\"\n class=\"form-control\"\n placeholder=\"150 or 'auto'\">\n </div>\n <div class=\"form-group\">\n <label for=\"minWidth\">Min Width</label>\n <input\n id=\"minWidth\"\n type=\"number\"\n formControlName=\"minWidth\"\n class=\"form-control\"\n placeholder=\"50\">\n </div>\n <div class=\"form-group\">\n <label for=\"maxWidth\">Max Width</label>\n <input\n id=\"maxWidth\"\n type=\"number\"\n formControlName=\"maxWidth\"\n class=\"form-control\"\n placeholder=\"500\">\n </div>\n </div>\n\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"sticky\">Sticky</label>\n <select id=\"sticky\" formControlName=\"sticky\" class=\"form-control\">\n @for (option of stickyOptions; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </select>\n </div>\n <div class=\"form-group\">\n <label for=\"alignment\">Alignment</label>\n <select id=\"alignment\" formControlName=\"alignment\" class=\"form-control\">\n @for (align of alignments; track align.value) {\n <option [value]=\"align.value\">\n {{ align.label }}\n </option>\n }\n </select>\n </div>\n <div class=\"form-group\">\n <label for=\"verticalAlignment\">Vertical Alignment</label>\n <select id=\"verticalAlignment\" formControlName=\"verticalAlignment\" class=\"form-control\">\n @for (align of verticalAlignments; track align.value) {\n <option [value]=\"align.value\">\n {{ align.label }}\n </option>\n }\n </select>\n </div>\n </div>\n </div>\n\n <!-- Edit Mode -->\n <div class=\"form-section\">\n <h4>Edit Mode</h4>\n <div class=\"form-group\">\n <label for=\"editMode\">Edit Trigger</label>\n <select id=\"editMode\" formControlName=\"editMode\" class=\"form-control\">\n @for (mode of editModes; track mode.value) {\n <option [value]=\"mode.value\">\n {{ mode.label }}\n </option>\n }\n </select>\n </div>\n </div>\n\n <!-- Display -->\n <div class=\"form-section\">\n <h4>Display</h4>\n <div class=\"checkbox-group\">\n <label class=\"checkbox-label\" [class.disabled]=\"!form.get('hideable')?.value\">\n <input type=\"checkbox\" \n formControlName=\"visible\"\n [disabled]=\"!form.get('hideable')?.value\"\n [title]=\"!form.get('hideable')?.value ? 'Column visibility cannot be changed when hideable is disabled' : ''\">\n <span>Visible</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"truncate\">\n <span>Truncate Text</span>\n </label>\n </div>\n </div>\n </form>\n</div>\n", styles: [".column-editor{display:flex;flex-direction:column;height:100%}.editor-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.editor-header h3{margin:0;font-size:1.125rem;font-weight:600;color:#333}.editor-actions{display:flex;gap:.5rem}.btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;cursor:pointer;font-size:.875rem;transition:all .2s}.btn.btn-primary{background-color:#2196f3;color:#fff;border-color:#2196f3}.btn.btn-primary:hover{background-color:#1976d2;border-color:#1976d2}.btn.btn-secondary{background-color:#fff;color:#333}.btn.btn-secondary:hover{background-color:#f5f5f5}.editor-form{flex:1;overflow-y:auto;padding:1rem}.form-section{margin-bottom:2rem}.form-section h4{margin:0 0 1rem;font-size:.875rem;font-weight:600;color:#666;text-transform:uppercase;letter-spacing:.5px}.form-group{margin-bottom:1rem}.form-group label{display:block;margin-bottom:.5rem;font-size:.875rem;font-weight:500;color:#333}.form-control{width:100%;padding:.5rem;border:1px solid #d0d0d0;border-radius:4px;font-size:.875rem;transition:border-color .2s}.form-control:focus{outline:none;border-color:#2196f3}.form-control.error{border-color:#f44336}.form-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1rem}.checkbox-group{display:flex;row-gap:1rem;flex-wrap:wrap;gap:.75rem}.checkbox-label{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.875rem;color:#333}.checkbox-label input[type=checkbox]{width:18px;height:18px;cursor:pointer}.checkbox-label input[type=checkbox]:disabled{cursor:not-allowed;opacity:.5}.checkbox-label.disabled{opacity:.6;cursor:not-allowed}.checkbox-label.disabled span{color:#999}.error-message{display:block;margin-top:.25rem;font-size:.75rem;color:#f44336}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
9137
9987
  }
9138
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ColumnEditorComponent, decorators: [{
9988
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ColumnEditorComponent, decorators: [{
9139
9989
  type: Component,
9140
9990
  args: [{ selector: 'st-column-editor', standalone: true, imports: [CommonModule, ReactiveFormsModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"column-editor\">\n <div class=\"editor-header\">\n <h3>Column Editor</h3>\n <div class=\"editor-actions\">\n <button class=\"btn btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"btn btn-primary\" (click)=\"onSave()\">Save</button>\n </div>\n </div>\n\n <form [formGroup]=\"form\" class=\"editor-form\">\n <!-- Basic Properties -->\n <div class=\"form-section\">\n <h4>Basic Properties</h4>\n <div class=\"form-group\">\n <label for=\"key\">Key *</label>\n <input\n id=\"key\"\n type=\"text\"\n formControlName=\"key\"\n class=\"form-control\"\n [class.error]=\"hasError('key')\"\n placeholder=\"columnKey\">\n @if (hasError('key')) {\n <span class=\"error-message\">\n {{ getErrorMessage('key') }}\n </span>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"header\">Header</label>\n <input\n id=\"header\"\n type=\"text\"\n formControlName=\"header\"\n class=\"form-control\"\n placeholder=\"Column Header\">\n </div>\n\n <div class=\"form-group\">\n <label for=\"dataType\">Data Type</label>\n <select id=\"dataType\" formControlName=\"dataType\" class=\"form-control\">\n @for (type of dataTypes; track type.value) {\n <option [value]=\"type.value\">\n {{ type.label }}\n </option>\n }\n </select>\n </div>\n </div>\n\n <!-- Features -->\n <div class=\"form-section\">\n <h4>Features</h4>\n <div class=\"checkbox-group\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"editable\">\n <span>Editable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"sortable\">\n <span>Sortable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"filterable\">\n <span>Filterable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"resizable\">\n <span>Resizable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"hideable\">\n <span>Hideable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"movable\">\n <span>Movable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"pinnable\">\n <span>Pinnable</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enableMenu\">\n <span>Enable Menu</span>\n </label>\n </div>\n </div>\n\n <!-- Layout -->\n <div class=\"form-section\">\n <h4>Layout</h4>\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"width\">Width</label>\n <input\n id=\"width\"\n type=\"text\"\n formControlName=\"width\"\n class=\"form-control\"\n placeholder=\"150 or 'auto'\">\n </div>\n <div class=\"form-group\">\n <label for=\"minWidth\">Min Width</label>\n <input\n id=\"minWidth\"\n type=\"number\"\n formControlName=\"minWidth\"\n class=\"form-control\"\n placeholder=\"50\">\n </div>\n <div class=\"form-group\">\n <label for=\"maxWidth\">Max Width</label>\n <input\n id=\"maxWidth\"\n type=\"number\"\n formControlName=\"maxWidth\"\n class=\"form-control\"\n placeholder=\"500\">\n </div>\n </div>\n\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"sticky\">Sticky</label>\n <select id=\"sticky\" formControlName=\"sticky\" class=\"form-control\">\n @for (option of stickyOptions; track option.value) {\n <option [value]=\"option.value\">\n {{ option.label }}\n </option>\n }\n </select>\n </div>\n <div class=\"form-group\">\n <label for=\"alignment\">Alignment</label>\n <select id=\"alignment\" formControlName=\"alignment\" class=\"form-control\">\n @for (align of alignments; track align.value) {\n <option [value]=\"align.value\">\n {{ align.label }}\n </option>\n }\n </select>\n </div>\n <div class=\"form-group\">\n <label for=\"verticalAlignment\">Vertical Alignment</label>\n <select id=\"verticalAlignment\" formControlName=\"verticalAlignment\" class=\"form-control\">\n @for (align of verticalAlignments; track align.value) {\n <option [value]=\"align.value\">\n {{ align.label }}\n </option>\n }\n </select>\n </div>\n </div>\n </div>\n\n <!-- Edit Mode -->\n <div class=\"form-section\">\n <h4>Edit Mode</h4>\n <div class=\"form-group\">\n <label for=\"editMode\">Edit Trigger</label>\n <select id=\"editMode\" formControlName=\"editMode\" class=\"form-control\">\n @for (mode of editModes; track mode.value) {\n <option [value]=\"mode.value\">\n {{ mode.label }}\n </option>\n }\n </select>\n </div>\n </div>\n\n <!-- Display -->\n <div class=\"form-section\">\n <h4>Display</h4>\n <div class=\"checkbox-group\">\n <label class=\"checkbox-label\" [class.disabled]=\"!form.get('hideable')?.value\">\n <input type=\"checkbox\" \n formControlName=\"visible\"\n [disabled]=\"!form.get('hideable')?.value\"\n [title]=\"!form.get('hideable')?.value ? 'Column visibility cannot be changed when hideable is disabled' : ''\">\n <span>Visible</span>\n </label>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"truncate\">\n <span>Truncate Text</span>\n </label>\n </div>\n </div>\n </form>\n</div>\n", styles: [".column-editor{display:flex;flex-direction:column;height:100%}.editor-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.editor-header h3{margin:0;font-size:1.125rem;font-weight:600;color:#333}.editor-actions{display:flex;gap:.5rem}.btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;cursor:pointer;font-size:.875rem;transition:all .2s}.btn.btn-primary{background-color:#2196f3;color:#fff;border-color:#2196f3}.btn.btn-primary:hover{background-color:#1976d2;border-color:#1976d2}.btn.btn-secondary{background-color:#fff;color:#333}.btn.btn-secondary:hover{background-color:#f5f5f5}.editor-form{flex:1;overflow-y:auto;padding:1rem}.form-section{margin-bottom:2rem}.form-section h4{margin:0 0 1rem;font-size:.875rem;font-weight:600;color:#666;text-transform:uppercase;letter-spacing:.5px}.form-group{margin-bottom:1rem}.form-group label{display:block;margin-bottom:.5rem;font-size:.875rem;font-weight:500;color:#333}.form-control{width:100%;padding:.5rem;border:1px solid #d0d0d0;border-radius:4px;font-size:.875rem;transition:border-color .2s}.form-control:focus{outline:none;border-color:#2196f3}.form-control.error{border-color:#f44336}.form-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1rem}.checkbox-group{display:flex;row-gap:1rem;flex-wrap:wrap;gap:.75rem}.checkbox-label{display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.875rem;color:#333}.checkbox-label input[type=checkbox]{width:18px;height:18px;cursor:pointer}.checkbox-label input[type=checkbox]:disabled{cursor:not-allowed;opacity:.5}.checkbox-label.disabled{opacity:.6;cursor:not-allowed}.checkbox-label.disabled span{color:#999}.error-message{display:block;margin-top:.25rem;font-size:.75rem;color:#f44336}\n"] }]
9141
9991
  }], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { column: [{
@@ -9230,10 +10080,10 @@ class StColumnEditorModalComponent {
9230
10080
  onModalContentClick(event) {
9231
10081
  event.stopPropagation();
9232
10082
  }
9233
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnEditorModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9234
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.0", type: StColumnEditorModalComponent, isStandalone: true, selector: "st-column-editor-modal", outputs: { columnCreated: "columnCreated", cancelled: "cancelled" }, viewQueries: [{ propertyName: "columnEditor", first: true, predicate: ColumnEditorComponent, descendants: true }], ngImport: i0, template: "<div class=\"modal-backdrop\" (click)=\"onBackdropClick($event)\">\n <div class=\"modal-content\" (click)=\"onModalContentClick($event)\">\n <div class=\"modal-header\">\n <h2>Add New Column</h2>\n <button class=\"close-button\" (click)=\"onCancel()\" type=\"button\" aria-label=\"Close\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n </div>\n <div class=\"modal-body\">\n <!-- Now using the shared st-column-editor component from SharedTableComponentsModule -->\n <st-column-editor\n [column]=\"newColumn\"\n [columnIndex]=\"columnIndex\"\n (columnUpdated)=\"onColumnUpdated($event)\"\n (cancel)=\"onCancel()\">\n </st-column-editor>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onSave()\">Add Column</button>\n </div>\n </div>\n</div>\n", styles: [".modal-backdrop{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:2000;animation:fadeIn .2s ease-in-out}.modal-content{background:#fff;border-radius:8px;box-shadow:0 11px 15px -7px #0003,0 24px 38px 3px #00000024,0 9px 46px 8px #0000001f;max-width:600px;max-height:90vh;width:90%;display:flex;flex-direction:column;animation:slideUp .3s cubic-bezier(.4,0,.2,1)}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;border-bottom:1px solid #e0e0e0;flex-shrink:0}.modal-header h2{margin:0;font-size:20px;font-weight:500;color:#212121}.close-button{background:none;border:none;cursor:pointer;padding:8px;display:flex;align-items:center;justify-content:center;border-radius:50%;color:#757575;transition:all .2s ease}.close-button:hover{background-color:#0000000a;color:#212121}.close-button:active{background-color:#00000014}.close-button:focus{outline:none;box-shadow:0 0 0 2px #1976d24d}.close-button svg{width:24px;height:24px}.modal-body{padding:0;overflow-y:auto;flex:1;min-height:0}.modal-body ::ng-deep st-column-editor{display:block}.modal-body ::ng-deep st-column-editor .column-editor{padding:0;border:none;box-shadow:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-header{display:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-actions{display:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-form{padding:24px}.modal-footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid #e0e0e0;flex-shrink:0;background-color:#f5f5f5}.modal-footer .btn{padding:10px 20px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s}.modal-footer .btn:focus{outline:none;box-shadow:0 0 0 2px #0000001a}.modal-footer .btn.btn-secondary{background-color:#fff;color:#424242;border:1px solid #d0d0d0}.modal-footer .btn.btn-secondary:hover{background-color:#f5f5f5}.modal-footer .btn.btn-secondary:active{background-color:#eee}.modal-footer .btn.btn-primary{background-color:#1976d2;color:#fff}.modal-footer .btn.btn-primary:hover{background-color:#1565c0}.modal-footer .btn.btn-primary:active{background-color:#0d47a1}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(50px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ColumnEditorComponent, selector: "st-column-editor", inputs: ["column", "columnIndex"], outputs: ["columnUpdated", "cancel"] }] }); }
10083
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnEditorModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
10084
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: StColumnEditorModalComponent, isStandalone: true, selector: "st-column-editor-modal", outputs: { columnCreated: "columnCreated", cancelled: "cancelled" }, viewQueries: [{ propertyName: "columnEditor", first: true, predicate: ColumnEditorComponent, descendants: true }], ngImport: i0, template: "<div class=\"modal-backdrop\" (click)=\"onBackdropClick($event)\">\n <div class=\"modal-content\" (click)=\"onModalContentClick($event)\">\n <div class=\"modal-header\">\n <h2>Add New Column</h2>\n <button class=\"close-button\" (click)=\"onCancel()\" type=\"button\" aria-label=\"Close\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n </div>\n <div class=\"modal-body\">\n <!-- Now using the shared st-column-editor component from SharedTableComponentsModule -->\n <st-column-editor\n [column]=\"newColumn\"\n [columnIndex]=\"columnIndex\"\n (columnUpdated)=\"onColumnUpdated($event)\"\n (cancel)=\"onCancel()\">\n </st-column-editor>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onSave()\">Add Column</button>\n </div>\n </div>\n</div>\n", styles: [".modal-backdrop{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:2000;animation:fadeIn .2s ease-in-out}.modal-content{background:#fff;border-radius:8px;box-shadow:0 11px 15px -7px #0003,0 24px 38px 3px #00000024,0 9px 46px 8px #0000001f;max-width:600px;max-height:90vh;width:90%;display:flex;flex-direction:column;animation:slideUp .3s cubic-bezier(.4,0,.2,1)}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;border-bottom:1px solid #e0e0e0;flex-shrink:0}.modal-header h2{margin:0;font-size:20px;font-weight:500;color:#212121}.close-button{background:none;border:none;cursor:pointer;padding:8px;display:flex;align-items:center;justify-content:center;border-radius:50%;color:#757575;transition:all .2s ease}.close-button:hover{background-color:#0000000a;color:#212121}.close-button:active{background-color:#00000014}.close-button:focus{outline:none;box-shadow:0 0 0 2px #1976d24d}.close-button svg{width:24px;height:24px}.modal-body{padding:0;overflow-y:auto;flex:1;min-height:0}.modal-body ::ng-deep st-column-editor{display:block}.modal-body ::ng-deep st-column-editor .column-editor{padding:0;border:none;box-shadow:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-header{display:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-actions{display:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-form{padding:24px}.modal-footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid #e0e0e0;flex-shrink:0;background-color:#f5f5f5}.modal-footer .btn{padding:10px 20px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s}.modal-footer .btn:focus{outline:none;box-shadow:0 0 0 2px #0000001a}.modal-footer .btn.btn-secondary{background-color:#fff;color:#424242;border:1px solid #d0d0d0}.modal-footer .btn.btn-secondary:hover{background-color:#f5f5f5}.modal-footer .btn.btn-secondary:active{background-color:#eee}.modal-footer .btn.btn-primary{background-color:#1976d2;color:#fff}.modal-footer .btn.btn-primary:hover{background-color:#1565c0}.modal-footer .btn.btn-primary:active{background-color:#0d47a1}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(50px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ColumnEditorComponent, selector: "st-column-editor", inputs: ["column", "columnIndex"], outputs: ["columnUpdated", "cancel"] }] }); }
9235
10085
  }
9236
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StColumnEditorModalComponent, decorators: [{
10086
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StColumnEditorModalComponent, decorators: [{
9237
10087
  type: Component,
9238
10088
  args: [{ selector: 'st-column-editor-modal', standalone: true, imports: [CommonModule, ColumnEditorComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"modal-backdrop\" (click)=\"onBackdropClick($event)\">\n <div class=\"modal-content\" (click)=\"onModalContentClick($event)\">\n <div class=\"modal-header\">\n <h2>Add New Column</h2>\n <button class=\"close-button\" (click)=\"onCancel()\" type=\"button\" aria-label=\"Close\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n </div>\n <div class=\"modal-body\">\n <!-- Now using the shared st-column-editor component from SharedTableComponentsModule -->\n <st-column-editor\n [column]=\"newColumn\"\n [columnIndex]=\"columnIndex\"\n (columnUpdated)=\"onColumnUpdated($event)\"\n (cancel)=\"onCancel()\">\n </st-column-editor>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onSave()\">Add Column</button>\n </div>\n </div>\n</div>\n", styles: [".modal-backdrop{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:2000;animation:fadeIn .2s ease-in-out}.modal-content{background:#fff;border-radius:8px;box-shadow:0 11px 15px -7px #0003,0 24px 38px 3px #00000024,0 9px 46px 8px #0000001f;max-width:600px;max-height:90vh;width:90%;display:flex;flex-direction:column;animation:slideUp .3s cubic-bezier(.4,0,.2,1)}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;border-bottom:1px solid #e0e0e0;flex-shrink:0}.modal-header h2{margin:0;font-size:20px;font-weight:500;color:#212121}.close-button{background:none;border:none;cursor:pointer;padding:8px;display:flex;align-items:center;justify-content:center;border-radius:50%;color:#757575;transition:all .2s ease}.close-button:hover{background-color:#0000000a;color:#212121}.close-button:active{background-color:#00000014}.close-button:focus{outline:none;box-shadow:0 0 0 2px #1976d24d}.close-button svg{width:24px;height:24px}.modal-body{padding:0;overflow-y:auto;flex:1;min-height:0}.modal-body ::ng-deep st-column-editor{display:block}.modal-body ::ng-deep st-column-editor .column-editor{padding:0;border:none;box-shadow:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-header{display:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-actions{display:none}.modal-body ::ng-deep st-column-editor .column-editor .editor-form{padding:24px}.modal-footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid #e0e0e0;flex-shrink:0;background-color:#f5f5f5}.modal-footer .btn{padding:10px 20px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s}.modal-footer .btn:focus{outline:none;box-shadow:0 0 0 2px #0000001a}.modal-footer .btn.btn-secondary{background-color:#fff;color:#424242;border:1px solid #d0d0d0}.modal-footer .btn.btn-secondary:hover{background-color:#f5f5f5}.modal-footer .btn.btn-secondary:active{background-color:#eee}.modal-footer .btn.btn-primary{background-color:#1976d2;color:#fff}.modal-footer .btn.btn-primary:hover{background-color:#1565c0}.modal-footer .btn.btn-primary:active{background-color:#0d47a1}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(50px)}to{opacity:1;transform:translateY(0)}}\n"] }]
9239
10089
  }], propDecorators: { columnCreated: [{
@@ -9340,10 +10190,10 @@ class StSheetActionsComponent {
9340
10190
  right: `${window.innerWidth - rect.right}px`
9341
10191
  };
9342
10192
  }
9343
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StSheetActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9344
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StSheetActionsComponent, isStandalone: true, selector: "st-sheet-actions", inputs: { actions: "actions", sheetId: "sheetId" }, outputs: { actionClicked: "actionClicked" }, usesOnChanges: true, ngImport: i0, template: "@if (visibleActions.length > 0) {\n <button \n class=\"sheet-actions-button\"\n (click)=\"toggleMenu($event)\"\n type=\"button\"\n title=\"Sheet Actions\"\n aria-label=\"Sheet actions menu\"\n [class.active]=\"isOpen\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n}\n\n<!-- Dropdown container -->\n@if (isOpen) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closeMenu()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n @for (action of visibleActions; track action.id) {\n <nile-menu-item \n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon size=\"14\" slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n \n @if (visibleActions.length === 0) {\n <nile-menu-item>\n No actions available\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n", styles: [":host{display:inline-block}.sheet-actions-button{display:flex;align-items:center;justify-content:center;width:2rem;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s ease;color:var(--nile-color-neutral-600)}.sheet-actions-button nile-icon{font-size:16px}.dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1000;pointer-events:none}.dropdown-container>*{pointer-events:auto}.dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.dropdown-menu{position:absolute;min-width:200px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
10193
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StSheetActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
10194
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StSheetActionsComponent, isStandalone: true, selector: "st-sheet-actions", inputs: { actions: "actions", sheetId: "sheetId" }, outputs: { actionClicked: "actionClicked" }, usesOnChanges: true, ngImport: i0, template: "@if (visibleActions.length > 0) {\n <button \n class=\"sheet-actions-button\"\n (click)=\"toggleMenu($event)\"\n type=\"button\"\n title=\"Sheet Actions\"\n aria-label=\"Sheet actions menu\"\n [class.active]=\"isOpen\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n}\n\n<!-- Dropdown container -->\n@if (isOpen) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closeMenu()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n @for (action of visibleActions; track action.id) {\n <nile-menu-item \n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon size=\"14\" slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n \n @if (visibleActions.length === 0) {\n <nile-menu-item>\n No actions available\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n", styles: [":host{display:inline-block}.sheet-actions-button{display:flex;align-items:center;justify-content:center;width:2rem;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s ease;color:var(--nile-color-neutral-600)}.sheet-actions-button nile-icon{font-size:16px}.dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1000;pointer-events:none}.dropdown-container>*{pointer-events:auto}.dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.dropdown-menu{position:absolute;min-width:200px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
9345
10195
  }
9346
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StSheetActionsComponent, decorators: [{
10196
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StSheetActionsComponent, decorators: [{
9347
10197
  type: Component,
9348
10198
  args: [{ selector: 'st-sheet-actions', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "@if (visibleActions.length > 0) {\n <button \n class=\"sheet-actions-button\"\n (click)=\"toggleMenu($event)\"\n type=\"button\"\n title=\"Sheet Actions\"\n aria-label=\"Sheet actions menu\"\n [class.active]=\"isOpen\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n}\n\n<!-- Dropdown container -->\n@if (isOpen) {\n <div class=\"dropdown-container\">\n <!-- Backdrop -->\n <div class=\"dropdown-backdrop\" (click)=\"closeMenu()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu>\n @for (action of visibleActions; track action.id) {\n <nile-menu-item \n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon size=\"14\" slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n \n @if (visibleActions.length === 0) {\n <nile-menu-item>\n No actions available\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n", styles: [":host{display:inline-block}.sheet-actions-button{display:flex;align-items:center;justify-content:center;width:2rem;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s ease;color:var(--nile-color-neutral-600)}.sheet-actions-button nile-icon{font-size:16px}.dropdown-container{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1000;pointer-events:none}.dropdown-container>*{pointer-events:auto}.dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.dropdown-menu{position:absolute;min-width:200px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}\n"] }]
9349
10199
  }], ctorParameters: () => [], propDecorators: { actions: [{
@@ -9487,10 +10337,10 @@ class StSheetComponent {
9487
10337
  get headerVariant() {
9488
10338
  return this.config?.display?.headerVariant || 'default';
9489
10339
  }
9490
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9491
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StSheetComponent, isStandalone: true, selector: "st-sheet", inputs: { config: "config", data: "data", data$: "data$", state: "state" }, outputs: { sheetActionClicked: "sheetActionClicked", stateChange: "stateChange", cellChange: "cellChange", tableStateChange: "tableStateChange", dataChange: "dataChange" }, usesOnChanges: true, ngImport: i0, template: "<nile-tab-group>\n <nile-tab slot=\"nav\" panel=\"general\" [class.active]=\"activeTab === '1'\" (click)=\"activeTab = '1'\">\n <div class=\"sheet-header\">\n {{activeState?.name$ | async | titlecase}}\n @if (visibleActions.length > 0) {\n <st-sheet-actions \n [actions]=\"visibleActions\" \n [sheetId]=\"config.id\"\n (actionClicked)=\"onActionClick($event)\">\n </st-sheet-actions>\n }\n </div>\n </nile-tab>\n <nile-tab-panel name=\"general\">\n @if (config && activeState) {\n <st-table \n [tableConfig]=\"config.tableConfig\"\n [data]=\"data\"\n [data$]=\"data$\"\n [tableState]=\"activeState.tableState\"\n (cellChange)=\"onCellChange($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (dataChange)=\"onDataChange($event)\">\n </st-table>\n }\n </nile-tab-panel>\n</nile-tab-group>\n", styles: [":host{display:block;width:100%;height:100%}.sheet-container{display:flex;flex-direction:column;width:100%;height:100%}.sheet-header{display:flex;align-items:center;font-family:Colfax;color:#000}.sheet-table-wrapper{flex:1;overflow:auto;position:relative}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }, { kind: "component", type: StSheetActionsComponent, selector: "st-sheet-actions", inputs: ["actions", "sheetId"], outputs: ["actionClicked"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }] }); }
10340
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
10341
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StSheetComponent, isStandalone: true, selector: "st-sheet", inputs: { config: "config", data: "data", data$: "data$", state: "state" }, outputs: { sheetActionClicked: "sheetActionClicked", stateChange: "stateChange", cellChange: "cellChange", tableStateChange: "tableStateChange", dataChange: "dataChange" }, usesOnChanges: true, ngImport: i0, template: "<nile-tab-group>\n <nile-tab slot=\"nav\" panel=\"general\" [class.active]=\"activeTab === '1'\" (click)=\"activeTab = '1'\">\n <div class=\"sheet-header\">\n {{activeState?.name$ | async | titlecase}}\n @if (visibleActions.length > 0) {\n <st-sheet-actions \n [actions]=\"visibleActions\" \n [sheetId]=\"config.id\"\n (actionClicked)=\"onActionClick($event)\">\n </st-sheet-actions>\n }\n </div>\n </nile-tab>\n <nile-tab-panel name=\"general\">\n @if (config && activeState) {\n <st-table \n [tableConfig]=\"config.tableConfig\"\n [data]=\"data\"\n [data$]=\"data$\"\n [tableState]=\"activeState.tableState\"\n (cellChange)=\"onCellChange($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (dataChange)=\"onDataChange($event)\">\n </st-table>\n }\n </nile-tab-panel>\n</nile-tab-group>\n", styles: [":host{display:block;width:100%;height:100%}.sheet-container{display:flex;flex-direction:column;width:100%;height:100%}.sheet-header{display:flex;align-items:center;font-family:Colfax;color:#000}.sheet-table-wrapper{flex:1;overflow:auto;position:relative}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }, { kind: "component", type: StSheetActionsComponent, selector: "st-sheet-actions", inputs: ["actions", "sheetId"], outputs: ["actionClicked"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }] }); }
9492
10342
  }
9493
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StSheetComponent, decorators: [{
10343
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StSheetComponent, decorators: [{
9494
10344
  type: Component,
9495
10345
  args: [{ selector: 'st-sheet', standalone: true, imports: [CommonModule, StTableComponent, StSheetActionsComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<nile-tab-group>\n <nile-tab slot=\"nav\" panel=\"general\" [class.active]=\"activeTab === '1'\" (click)=\"activeTab = '1'\">\n <div class=\"sheet-header\">\n {{activeState?.name$ | async | titlecase}}\n @if (visibleActions.length > 0) {\n <st-sheet-actions \n [actions]=\"visibleActions\" \n [sheetId]=\"config.id\"\n (actionClicked)=\"onActionClick($event)\">\n </st-sheet-actions>\n }\n </div>\n </nile-tab>\n <nile-tab-panel name=\"general\">\n @if (config && activeState) {\n <st-table \n [tableConfig]=\"config.tableConfig\"\n [data]=\"data\"\n [data$]=\"data$\"\n [tableState]=\"activeState.tableState\"\n (cellChange)=\"onCellChange($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (dataChange)=\"onDataChange($event)\">\n </st-table>\n }\n </nile-tab-panel>\n</nile-tab-group>\n", styles: [":host{display:block;width:100%;height:100%}.sheet-container{display:flex;flex-direction:column;width:100%;height:100%}.sheet-header{display:flex;align-items:center;font-family:Colfax;color:#000}.sheet-table-wrapper{flex:1;overflow:auto;position:relative}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"] }]
9496
10346
  }], ctorParameters: () => [], propDecorators: { config: [{
@@ -9601,10 +10451,10 @@ class AutosaveService {
9601
10451
  this.dirtyState.clear();
9602
10452
  this.lastSaveTime.clear();
9603
10453
  }
9604
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AutosaveService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
9605
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AutosaveService, providedIn: 'root' }); }
10454
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AutosaveService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
10455
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AutosaveService, providedIn: 'root' }); }
9606
10456
  }
9607
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AutosaveService, decorators: [{
10457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AutosaveService, decorators: [{
9608
10458
  type: Injectable,
9609
10459
  args: [{
9610
10460
  providedIn: 'root'
@@ -9617,9 +10467,9 @@ class StWorkbookComponent {
9617
10467
  this.autosaveService = inject(AutosaveService);
9618
10468
  this.cdr = inject(ChangeDetectorRef);
9619
10469
  // Signal-based inputs
9620
- this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
9621
- this.sheetsData = input(new BehaviorSubject(new Map()), ...(ngDevMode ? [{ debugName: "sheetsData" }] : []));
9622
- this.state = input(undefined, ...(ngDevMode ? [{ debugName: "state" }] : []));
10470
+ this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
10471
+ this.sheetsData = input(new BehaviorSubject(new Map()), ...(ngDevMode ? [{ debugName: "sheetsData" }] : /* istanbul ignore next */ []));
10472
+ this.state = input(undefined, ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
9623
10473
  // Signal-based outputs
9624
10474
  this.sheetChanged = output();
9625
10475
  this.addSheet = output();
@@ -9631,27 +10481,27 @@ class StWorkbookComponent {
9631
10481
  this.fullscreenToggle = output();
9632
10482
  this.requestAddRow = output();
9633
10483
  // Internal state signals
9634
- this.sheets = signal([], ...(ngDevMode ? [{ debugName: "sheets" }] : []));
9635
- this.activeSheetIndex = signal(0, ...(ngDevMode ? [{ debugName: "activeSheetIndex" }] : []));
9636
- this.currentTableConfig = signal(null, ...(ngDevMode ? [{ debugName: "currentTableConfig" }] : []));
10484
+ this.sheets = signal([], ...(ngDevMode ? [{ debugName: "sheets" }] : /* istanbul ignore next */ []));
10485
+ this.activeSheetIndex = signal(0, ...(ngDevMode ? [{ debugName: "activeSheetIndex" }] : /* istanbul ignore next */ []));
10486
+ this.currentTableConfig = signal(null, ...(ngDevMode ? [{ debugName: "currentTableConfig" }] : /* istanbul ignore next */ []));
9637
10487
  this.currentTableData$ = new BehaviorSubject([]);
9638
- this.currentTableState = signal(null, ...(ngDevMode ? [{ debugName: "currentTableState" }] : []));
9639
- this.tableComponentKey = signal('', ...(ngDevMode ? [{ debugName: "tableComponentKey" }] : []));
9640
- this.isFullscreen = signal(false, ...(ngDevMode ? [{ debugName: "isFullscreen" }] : []));
10488
+ this.currentTableState = signal(null, ...(ngDevMode ? [{ debugName: "currentTableState" }] : /* istanbul ignore next */ []));
10489
+ this.tableComponentKey = signal('', ...(ngDevMode ? [{ debugName: "tableComponentKey" }] : /* istanbul ignore next */ []));
10490
+ this.isFullscreen = signal(false, ...(ngDevMode ? [{ debugName: "isFullscreen" }] : /* istanbul ignore next */ []));
9641
10491
  // Tab actions state signals
9642
- this.tabActionsOpen = signal(false, ...(ngDevMode ? [{ debugName: "tabActionsOpen" }] : []));
9643
- this.selectedSheet = signal(null, ...(ngDevMode ? [{ debugName: "selectedSheet" }] : []));
9644
- this.selectedSheetIndex = signal(-1, ...(ngDevMode ? [{ debugName: "selectedSheetIndex" }] : []));
9645
- this.tabActionsPosition = signal({}, ...(ngDevMode ? [{ debugName: "tabActionsPosition" }] : []));
10492
+ this.tabActionsOpen = signal(false, ...(ngDevMode ? [{ debugName: "tabActionsOpen" }] : /* istanbul ignore next */ []));
10493
+ this.selectedSheet = signal(null, ...(ngDevMode ? [{ debugName: "selectedSheet" }] : /* istanbul ignore next */ []));
10494
+ this.selectedSheetIndex = signal(-1, ...(ngDevMode ? [{ debugName: "selectedSheetIndex" }] : /* istanbul ignore next */ []));
10495
+ this.tabActionsPosition = signal({}, ...(ngDevMode ? [{ debugName: "tabActionsPosition" }] : /* istanbul ignore next */ []));
9646
10496
  // Workbook actions state signals
9647
- this.workbookActionsOpen = signal(false, ...(ngDevMode ? [{ debugName: "workbookActionsOpen" }] : []));
9648
- this.workbookActionsPosition = signal({}, ...(ngDevMode ? [{ debugName: "workbookActionsPosition" }] : []));
9649
- this.visibleWorkbookActions = signal([], ...(ngDevMode ? [{ debugName: "visibleWorkbookActions" }] : []));
9650
- this.toolbarWorkbookActions = signal([], ...(ngDevMode ? [{ debugName: "toolbarWorkbookActions" }] : []));
10497
+ this.workbookActionsOpen = signal(false, ...(ngDevMode ? [{ debugName: "workbookActionsOpen" }] : /* istanbul ignore next */ []));
10498
+ this.workbookActionsPosition = signal({}, ...(ngDevMode ? [{ debugName: "workbookActionsPosition" }] : /* istanbul ignore next */ []));
10499
+ this.visibleWorkbookActions = signal([], ...(ngDevMode ? [{ debugName: "visibleWorkbookActions" }] : /* istanbul ignore next */ []));
10500
+ this.toolbarWorkbookActions = signal([], ...(ngDevMode ? [{ debugName: "toolbarWorkbookActions" }] : /* istanbul ignore next */ []));
9651
10501
  // Autosave state signals
9652
- this.autosaveEnabled = signal(false, ...(ngDevMode ? [{ debugName: "autosaveEnabled" }] : []));
9653
- this.lastSaveTime = signal(null, ...(ngDevMode ? [{ debugName: "lastSaveTime" }] : []));
9654
- this.isSaving = signal(false, ...(ngDevMode ? [{ debugName: "isSaving" }] : []));
10502
+ this.autosaveEnabled = signal(false, ...(ngDevMode ? [{ debugName: "autosaveEnabled" }] : /* istanbul ignore next */ []));
10503
+ this.lastSaveTime = signal(null, ...(ngDevMode ? [{ debugName: "lastSaveTime" }] : /* istanbul ignore next */ []));
10504
+ this.isSaving = signal(false, ...(ngDevMode ? [{ debugName: "isSaving" }] : /* istanbul ignore next */ []));
9655
10505
  // Legacy observable for fullscreen (template compatibility)
9656
10506
  this.isFullscreen$ = new BehaviorSubject(false);
9657
10507
  this.destroy$ = new Subject();
@@ -9978,10 +10828,10 @@ class StWorkbookComponent {
9978
10828
  this.tableComponent.scrollToLastRow(focusFirstCell);
9979
10829
  }
9980
10830
  }
9981
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StWorkbookComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9982
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: StWorkbookComponent, isStandalone: true, selector: "st-workbook", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, sheetsData: { classPropertyName: "sheetsData", publicName: "sheetsData", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sheetChanged: "sheetChanged", addSheet: "addSheet", sheetTabAction: "sheetTabAction", workbookAction: "workbookAction", cellChange: "cellChange", cellSave: "cellSave", tableStateChange: "tableStateChange", fullscreenToggle: "fullscreenToggle", requestAddRow: "requestAddRow" }, viewQueries: [{ propertyName: "tableComponent", first: true, predicate: StTableComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen()\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex()\">\n \n <!-- Sheet Tabs (one per sheet) -->\n @for (sheet of sheets(); track sheet.id; let i = $index) {\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex()\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n @if (hasTabActions(sheet)) {\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n }\n </div>\n </nile-tab>\n }\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n @if (autosaveEnabled()) {\n <div class=\"autosave-indicator\">\n @if (!isSaving() && lastSaveTime()) {\n <nile-icon \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime() | date:'HH:mm:ss')\">\n </nile-icon>\n }\n @if (isSaving()) {\n <nile-icon \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n }\n </div>\n }\n\n <!-- Toolbar Workbook Actions (shown as individual buttons) -->\n @for (action of toolbarWorkbookActions(); track action.id) {\n <button class=\"toolbar-action-button\"\n [class.disabled]=\"isActionDisabled(action)\"\n [title]=\"action.label\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon [name]=\"action.icon\"></nile-icon>\n }\n @if (!action.icon) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n\n <!-- Workbook Actions Dropdown -->\n @if (visibleWorkbookActions().length > 0) {\n <button class=\"workbook-actions-button\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n }\n \n <!-- Add Sheet Button -->\n @if (canAddSheet) {\n <button class=\"add-sheet-button\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n }\n \n <!-- Fullscreen Button -->\n @if (config().display?.allowFullscreen !== false) {\n <button class=\"fullscreen-button\"\n (click)=\"toggleFullscreen()\"\n [title]=\"isFullscreen() ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"isFullscreen() ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n }\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using @for with track to force complete reinitialization when tableComponentKey changes -->\n @for (key of [tableComponentKey()]; track key) {\n @if (currentTableConfig() && currentTableState()) {\n <st-table \n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig()!\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState()!\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n }\n }\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n@if (tabActionsOpen()) {\n <div class=\"tab-actions-dropdown\" [ngStyle]=\"tabActionsPosition()\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n @for (action of selectedSheet()?.tabActions; track action.id) {\n <nile-menu-item (click)=\"onTabActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n\n<!-- Workbook Actions Dropdown -->\n@if (workbookActionsOpen()) {\n <div class=\"workbook-actions-dropdown\" [ngStyle]=\"workbookActionsPosition()\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n @for (action of visibleWorkbookActions(); track action.id) {\n <nile-menu-item [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n\n<!-- Fullscreen Backdrop -->\n@if (isFullscreen()) {\n <div class=\"fullscreen-backdrop\" (click)=\"toggleFullscreen()\">\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:#fff;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.workbook-toolbar-tab button.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:#00000080;z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab.active .sheet-name{font-weight:600}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] }); }
10831
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StWorkbookComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
10832
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: StWorkbookComponent, isStandalone: true, selector: "st-workbook", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, sheetsData: { classPropertyName: "sheetsData", publicName: "sheetsData", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sheetChanged: "sheetChanged", addSheet: "addSheet", sheetTabAction: "sheetTabAction", workbookAction: "workbookAction", cellChange: "cellChange", cellSave: "cellSave", tableStateChange: "tableStateChange", fullscreenToggle: "fullscreenToggle", requestAddRow: "requestAddRow" }, viewQueries: [{ propertyName: "tableComponent", first: true, predicate: StTableComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen()\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex()\">\n \n <!-- Sheet Tabs (one per sheet) -->\n @for (sheet of sheets(); track sheet.id; let i = $index) {\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex()\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n @if (hasTabActions(sheet)) {\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n }\n </div>\n </nile-tab>\n }\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n @if (autosaveEnabled()) {\n <div class=\"autosave-indicator\">\n @if (!isSaving() && lastSaveTime()) {\n <nile-icon \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime() | date:'HH:mm:ss')\">\n </nile-icon>\n }\n @if (isSaving()) {\n <nile-icon \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n }\n </div>\n }\n\n <!-- Toolbar Workbook Actions (shown as individual buttons) -->\n @for (action of toolbarWorkbookActions(); track action.id) {\n <button class=\"toolbar-action-button\"\n [class.disabled]=\"isActionDisabled(action)\"\n [title]=\"action.label\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon [name]=\"action.icon\"></nile-icon>\n }\n @if (!action.icon) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n\n <!-- Workbook Actions Dropdown -->\n @if (visibleWorkbookActions().length > 0) {\n <button class=\"workbook-actions-button\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n }\n \n <!-- Add Sheet Button -->\n @if (canAddSheet) {\n <button class=\"add-sheet-button\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n }\n \n <!-- Fullscreen Button -->\n @if (config().display?.allowFullscreen !== false) {\n <button class=\"fullscreen-button\"\n (click)=\"toggleFullscreen()\"\n [title]=\"isFullscreen() ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"isFullscreen() ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n }\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using @for with track to force complete reinitialization when tableComponentKey changes -->\n @for (key of [tableComponentKey()]; track key) {\n @if (currentTableConfig() && currentTableState()) {\n <st-table \n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig()!\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState()!\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n }\n }\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n@if (tabActionsOpen()) {\n <div class=\"tab-actions-dropdown\" [ngStyle]=\"tabActionsPosition()\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n @for (action of selectedSheet()?.tabActions; track action.id) {\n <nile-menu-item (click)=\"onTabActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n\n<!-- Workbook Actions Dropdown -->\n@if (workbookActionsOpen()) {\n <div class=\"workbook-actions-dropdown\" [ngStyle]=\"workbookActionsPosition()\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n @for (action of visibleWorkbookActions(); track action.id) {\n <nile-menu-item [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n\n<!-- Fullscreen Backdrop -->\n@if (isFullscreen()) {\n <div class=\"fullscreen-backdrop\" (click)=\"toggleFullscreen()\">\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:#fff;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.workbook-toolbar-tab button.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:#00000080;z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab.active .sheet-name{font-weight:600}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] }); }
9983
10833
  }
9984
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: StWorkbookComponent, decorators: [{
10834
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: StWorkbookComponent, decorators: [{
9985
10835
  type: Component,
9986
10836
  args: [{ selector: 'st-workbook', standalone: true, imports: [CommonModule, StTableComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen()\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex()\">\n \n <!-- Sheet Tabs (one per sheet) -->\n @for (sheet of sheets(); track sheet.id; let i = $index) {\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex()\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n @if (hasTabActions(sheet)) {\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n }\n </div>\n </nile-tab>\n }\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n @if (autosaveEnabled()) {\n <div class=\"autosave-indicator\">\n @if (!isSaving() && lastSaveTime()) {\n <nile-icon \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime() | date:'HH:mm:ss')\">\n </nile-icon>\n }\n @if (isSaving()) {\n <nile-icon \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n }\n </div>\n }\n\n <!-- Toolbar Workbook Actions (shown as individual buttons) -->\n @for (action of toolbarWorkbookActions(); track action.id) {\n <button class=\"toolbar-action-button\"\n [class.disabled]=\"isActionDisabled(action)\"\n [title]=\"action.label\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon [name]=\"action.icon\"></nile-icon>\n }\n @if (!action.icon) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n\n <!-- Workbook Actions Dropdown -->\n @if (visibleWorkbookActions().length > 0) {\n <button class=\"workbook-actions-button\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n }\n \n <!-- Add Sheet Button -->\n @if (canAddSheet) {\n <button class=\"add-sheet-button\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n }\n \n <!-- Fullscreen Button -->\n @if (config().display?.allowFullscreen !== false) {\n <button class=\"fullscreen-button\"\n (click)=\"toggleFullscreen()\"\n [title]=\"isFullscreen() ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"isFullscreen() ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n }\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using @for with track to force complete reinitialization when tableComponentKey changes -->\n @for (key of [tableComponentKey()]; track key) {\n @if (currentTableConfig() && currentTableState()) {\n <st-table \n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig()!\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState()!\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n }\n }\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n@if (tabActionsOpen()) {\n <div class=\"tab-actions-dropdown\" [ngStyle]=\"tabActionsPosition()\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n @for (action of selectedSheet()?.tabActions; track action.id) {\n <nile-menu-item (click)=\"onTabActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n\n<!-- Workbook Actions Dropdown -->\n@if (workbookActionsOpen()) {\n <div class=\"workbook-actions-dropdown\" [ngStyle]=\"workbookActionsPosition()\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n @for (action of visibleWorkbookActions(); track action.id) {\n <nile-menu-item [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n @if (action.icon) {\n <nile-icon slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n }\n {{ action.label }}\n </nile-menu-item>\n }\n </nile-menu>\n </div>\n </div>\n}\n\n<!-- Fullscreen Backdrop -->\n@if (isFullscreen()) {\n <div class=\"fullscreen-backdrop\" (click)=\"toggleFullscreen()\">\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:#fff;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.workbook-toolbar-tab button.disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:#fff;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:#00000080;z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab.active .sheet-name{font-weight:600}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"] }]
9987
10837
  }], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], sheetsData: [{ type: i0.Input, args: [{ isSignal: true, alias: "sheetsData", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], sheetChanged: [{ type: i0.Output, args: ["sheetChanged"] }], addSheet: [{ type: i0.Output, args: ["addSheet"] }], sheetTabAction: [{ type: i0.Output, args: ["sheetTabAction"] }], workbookAction: [{ type: i0.Output, args: ["workbookAction"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], cellSave: [{ type: i0.Output, args: ["cellSave"] }], tableStateChange: [{ type: i0.Output, args: ["tableStateChange"] }], fullscreenToggle: [{ type: i0.Output, args: ["fullscreenToggle"] }], requestAddRow: [{ type: i0.Output, args: ["requestAddRow"] }], tableComponent: [{
@@ -10002,10 +10852,10 @@ class ClickOutsideDirective {
10002
10852
  this.clickOutside.emit();
10003
10853
  }
10004
10854
  }
10005
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ClickOutsideDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
10006
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.0", type: ClickOutsideDirective, isStandalone: true, selector: "[clickOutside]", outputs: { clickOutside: "clickOutside" }, host: { listeners: { "document:click": "onClick($event.target)" } }, ngImport: i0 }); }
10855
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ClickOutsideDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
10856
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: ClickOutsideDirective, isStandalone: true, selector: "[clickOutside]", outputs: { clickOutside: "clickOutside" }, host: { listeners: { "document:click": "onClick($event.target)" } }, ngImport: i0 }); }
10007
10857
  }
10008
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ClickOutsideDirective, decorators: [{
10858
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ClickOutsideDirective, decorators: [{
10009
10859
  type: Directive,
10010
10860
  args: [{
10011
10861
  selector: '[clickOutside]',
@@ -10024,11 +10874,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
10024
10874
  * This module breaks the circular dependency between the two modules
10025
10875
  */
10026
10876
  class SharedTableComponentsModule {
10027
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SharedTableComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
10028
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: SharedTableComponentsModule, imports: [ColumnEditorComponent], exports: [ColumnEditorComponent] }); }
10029
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SharedTableComponentsModule, imports: [ColumnEditorComponent] }); }
10877
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SharedTableComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
10878
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: SharedTableComponentsModule, imports: [ColumnEditorComponent], exports: [ColumnEditorComponent] }); }
10879
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SharedTableComponentsModule, imports: [ColumnEditorComponent] }); }
10030
10880
  }
10031
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SharedTableComponentsModule, decorators: [{
10881
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SharedTableComponentsModule, decorators: [{
10032
10882
  type: NgModule,
10033
10883
  args: [{
10034
10884
  imports: [
@@ -10041,8 +10891,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
10041
10891
  }] });
10042
10892
 
10043
10893
  class SmartTableModule {
10044
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SmartTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
10045
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: SmartTableModule, imports: [SharedTableComponentsModule,
10894
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SmartTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
10895
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: SmartTableModule, imports: [SharedTableComponentsModule,
10046
10896
  StCellComponent,
10047
10897
  StTableComponent,
10048
10898
  StHeaderComponent,
@@ -10076,7 +10926,7 @@ class SmartTableModule {
10076
10926
  ClickOutsideDirective,
10077
10927
  StColumnResizeDirective,
10078
10928
  StKeyboardNavigationDirective] }); }
10079
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SmartTableModule, providers: [
10929
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SmartTableModule, providers: [
10080
10930
  VirtualScrollService
10081
10931
  ], imports: [SharedTableComponentsModule,
10082
10932
  StCellComponent,
@@ -10094,7 +10944,7 @@ class SmartTableModule {
10094
10944
  StSheetActionsComponent,
10095
10945
  StWorkbookComponent] }); }
10096
10946
  }
10097
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SmartTableModule, decorators: [{
10947
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SmartTableModule, decorators: [{
10098
10948
  type: NgModule,
10099
10949
  args: [{
10100
10950
  imports: [
@@ -10378,10 +11228,10 @@ class DefinitionBuilderService {
10378
11228
  // Simple comparison - in production, use a deep equality library
10379
11229
  return JSON.stringify(config1) === JSON.stringify(config2);
10380
11230
  }
10381
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
10382
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderService, providedIn: 'root' }); }
11231
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
11232
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderService, providedIn: 'root' }); }
10383
11233
  }
10384
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderService, decorators: [{
11234
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderService, decorators: [{
10385
11235
  type: Injectable,
10386
11236
  args: [{
10387
11237
  providedIn: 'root'
@@ -10747,10 +11597,10 @@ class DefinitionExportService {
10747
11597
  document.body.removeChild(link);
10748
11598
  URL.revokeObjectURL(url);
10749
11599
  }
10750
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
10751
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionExportService, providedIn: 'root' }); }
11600
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
11601
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionExportService, providedIn: 'root' }); }
10752
11602
  }
10753
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionExportService, decorators: [{
11603
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionExportService, decorators: [{
10754
11604
  type: Injectable,
10755
11605
  args: [{
10756
11606
  providedIn: 'root'
@@ -11099,10 +11949,10 @@ class DefinitionImportService {
11099
11949
  return errorResult;
11100
11950
  }
11101
11951
  }
11102
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionImportService, deps: [{ token: JsonSchemaValidatorService }, { token: ValidationLoggerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
11103
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionImportService, providedIn: 'root' }); }
11952
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionImportService, deps: [{ token: JsonSchemaValidatorService }, { token: ValidationLoggerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
11953
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionImportService, providedIn: 'root' }); }
11104
11954
  }
11105
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionImportService, decorators: [{
11955
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionImportService, decorators: [{
11106
11956
  type: Injectable,
11107
11957
  args: [{
11108
11958
  providedIn: 'root'
@@ -11202,10 +12052,10 @@ class BuilderToolbarComponent {
11202
12052
  onTogglePreview() {
11203
12053
  this.previewToggled.emit();
11204
12054
  }
11205
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BuilderToolbarComponent, deps: [{ token: DefinitionBuilderService }, { token: DefinitionExportService }, { token: DefinitionImportService }], target: i0.ɵɵFactoryTarget.Component }); }
11206
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: BuilderToolbarComponent, isStandalone: true, selector: "st-builder-toolbar", inputs: { hasUnsavedChanges: "hasUnsavedChanges" }, outputs: { newDefinition: "newDefinition", saved: "saved", previewToggled: "previewToggled" }, ngImport: i0, template: "<div class=\"builder-toolbar\">\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onNewDefinition()\" title=\"New Definition\">\n <span>New</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onOpenFile()\" title=\"Open File\">\n <span>Open</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onSave()\" title=\"Save to LocalStorage\" [class.has-changes]=\"hasUnsavedChanges\">\n <span>Save</span>\n @if (hasUnsavedChanges) {\n <span class=\"unsaved-indicator\">\u25CF</span>\n }\n </button>\n <button class=\"toolbar-btn\" (click)=\"onLoad()\" title=\"Load from LocalStorage\">\n <span>Load</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onImportJSON()\" title=\"Import JSON\">\n <span>Import JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportJSON()\" title=\"Export JSON\">\n <span>Export JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportTypeScript()\" title=\"Export TypeScript\">\n <span>Export TS</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onTogglePreview()\" title=\"Toggle Preview\">\n <span>Preview</span>\n </button>\n </div>\n</div>\n", styles: [".builder-toolbar{display:flex;align-items:center;gap:1rem;padding:.75rem 1rem;background-color:#fff;border-bottom:1px solid #e0e0e0;box-shadow:0 2px 4px #0000000d}.toolbar-section{display:flex;align-items:center;gap:.5rem}.toolbar-section:not(:last-child):after{content:\"\";width:1px;height:24px;background-color:#e0e0e0;margin-left:.5rem}.toolbar-btn{display:flex;align-items:center;gap:.25rem;padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.toolbar-btn:hover{background-color:#f5f5f5;border-color:#b0b0b0}.toolbar-btn:active{background-color:#e8e8e8}.toolbar-btn.has-changes{border-color:#ff9800;background-color:#fff3e0}.toolbar-btn .unsaved-indicator{color:#ff9800;font-size:.75rem;margin-left:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
12055
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BuilderToolbarComponent, deps: [{ token: DefinitionBuilderService }, { token: DefinitionExportService }, { token: DefinitionImportService }], target: i0.ɵɵFactoryTarget.Component }); }
12056
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: BuilderToolbarComponent, isStandalone: true, selector: "st-builder-toolbar", inputs: { hasUnsavedChanges: "hasUnsavedChanges" }, outputs: { newDefinition: "newDefinition", saved: "saved", previewToggled: "previewToggled" }, ngImport: i0, template: "<div class=\"builder-toolbar\">\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onNewDefinition()\" title=\"New Definition\">\n <span>New</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onOpenFile()\" title=\"Open File\">\n <span>Open</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onSave()\" title=\"Save to LocalStorage\" [class.has-changes]=\"hasUnsavedChanges\">\n <span>Save</span>\n @if (hasUnsavedChanges) {\n <span class=\"unsaved-indicator\">\u25CF</span>\n }\n </button>\n <button class=\"toolbar-btn\" (click)=\"onLoad()\" title=\"Load from LocalStorage\">\n <span>Load</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onImportJSON()\" title=\"Import JSON\">\n <span>Import JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportJSON()\" title=\"Export JSON\">\n <span>Export JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportTypeScript()\" title=\"Export TypeScript\">\n <span>Export TS</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onTogglePreview()\" title=\"Toggle Preview\">\n <span>Preview</span>\n </button>\n </div>\n</div>\n", styles: [".builder-toolbar{display:flex;align-items:center;gap:1rem;padding:.75rem 1rem;background-color:#fff;border-bottom:1px solid #e0e0e0;box-shadow:0 2px 4px #0000000d}.toolbar-section{display:flex;align-items:center;gap:.5rem}.toolbar-section:not(:last-child):after{content:\"\";width:1px;height:24px;background-color:#e0e0e0;margin-left:.5rem}.toolbar-btn{display:flex;align-items:center;gap:.25rem;padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.toolbar-btn:hover{background-color:#f5f5f5;border-color:#b0b0b0}.toolbar-btn:active{background-color:#e8e8e8}.toolbar-btn.has-changes{border-color:#ff9800;background-color:#fff3e0}.toolbar-btn .unsaved-indicator{color:#ff9800;font-size:.75rem;margin-left:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
11207
12057
  }
11208
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BuilderToolbarComponent, decorators: [{
12058
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BuilderToolbarComponent, decorators: [{
11209
12059
  type: Component,
11210
12060
  args: [{ selector: 'st-builder-toolbar', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"builder-toolbar\">\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onNewDefinition()\" title=\"New Definition\">\n <span>New</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onOpenFile()\" title=\"Open File\">\n <span>Open</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onSave()\" title=\"Save to LocalStorage\" [class.has-changes]=\"hasUnsavedChanges\">\n <span>Save</span>\n @if (hasUnsavedChanges) {\n <span class=\"unsaved-indicator\">\u25CF</span>\n }\n </button>\n <button class=\"toolbar-btn\" (click)=\"onLoad()\" title=\"Load from LocalStorage\">\n <span>Load</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onImportJSON()\" title=\"Import JSON\">\n <span>Import JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportJSON()\" title=\"Export JSON\">\n <span>Export JSON</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"onExportTypeScript()\" title=\"Export TypeScript\">\n <span>Export TS</span>\n </button>\n </div>\n\n <div class=\"toolbar-section\">\n <button class=\"toolbar-btn\" (click)=\"onTogglePreview()\" title=\"Toggle Preview\">\n <span>Preview</span>\n </button>\n </div>\n</div>\n", styles: [".builder-toolbar{display:flex;align-items:center;gap:1rem;padding:.75rem 1rem;background-color:#fff;border-bottom:1px solid #e0e0e0;box-shadow:0 2px 4px #0000000d}.toolbar-section{display:flex;align-items:center;gap:.5rem}.toolbar-section:not(:last-child):after{content:\"\";width:1px;height:24px;background-color:#e0e0e0;margin-left:.5rem}.toolbar-btn{display:flex;align-items:center;gap:.25rem;padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.toolbar-btn:hover{background-color:#f5f5f5;border-color:#b0b0b0}.toolbar-btn:active{background-color:#e8e8e8}.toolbar-btn.has-changes{border-color:#ff9800;background-color:#fff3e0}.toolbar-btn .unsaved-indicator{color:#ff9800;font-size:.75rem;margin-left:.25rem}\n"] }]
11211
12061
  }], ctorParameters: () => [{ type: DefinitionBuilderService }, { type: DefinitionExportService }, { type: DefinitionImportService }], propDecorators: { hasUnsavedChanges: [{
@@ -11318,10 +12168,10 @@ class ColumnListComponent {
11318
12168
  const type = this.dataTypes.find(dt => dt.value === column.dataType);
11319
12169
  return type?.label || 'Text';
11320
12170
  }
11321
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ColumnListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11322
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ColumnListComponent, isStandalone: true, selector: "st-column-list", inputs: { columns: "columns", selectedIndex: "selectedIndex" }, outputs: { columnSelected: "columnSelected", columnAdded: "columnAdded", columnDeleted: "columnDeleted", columnReordered: "columnReordered" }, ngImport: i0, template: "<div class=\"column-list\" (clickOutside)=\"closeMenu()\">\n <div class=\"column-list-header\">\n <h3>Columns</h3>\n <div class=\"add-column-menu\" [class.open]=\"showAddMenu\">\n <button class=\"add-btn\" (click)=\"showAddMenu = !showAddMenu\" title=\"Add Column\">\n <span>+ Add Column</span>\n </button>\n @if (showAddMenu) {\n <div class=\"add-menu\">\n @for (type of dataTypes; track type.value) {\n <button\n class=\"menu-item\"\n (click)=\"onAddColumn(type.value)\">\n {{ type.label }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n\n <div class=\"column-items\">\n @for (column of columns; track column.key; let i = $index) {\n <div\n class=\"column-item\"\n [class.selected]=\"selectedIndex === i\"\n [class.dragging]=\"draggedIndex === i\"\n [class.drag-over]=\"dragOverIndex === i\"\n (click)=\"onColumnClick(i)\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\"\n (dragend)=\"onDragEnd($event)\"\n (dragleave)=\"dragOverIndex = null\">\n <div class=\"drag-handle\">\n <span>\u2630</span>\n </div>\n <div class=\"column-info\">\n <div class=\"column-name\">{{ getColumnDisplayName(column) }}</div>\n <div class=\"column-meta\">\n <span class=\"column-type\">{{ getDataTypeLabel(column) }}</span>\n <span class=\"column-key\">{{ column.key }}</span>\n </div>\n </div>\n <button\n class=\"delete-btn\"\n (click)=\"onDelete(i, $event)\"\n title=\"Delete Column\">\n \u00D7\n </button>\n </div>\n }\n\n @if (columns.length === 0) {\n <div class=\"empty-state\">\n <p>No columns yet. Click \"Add Column\" to get started.</p>\n </div>\n }\n </div>\n</div>\n", styles: [".column-list{display:flex;flex-direction:column;background-color:#fff;border-radius:4px;box-shadow:0 2px 4px #0000001a;overflow:hidden}.column-list-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.column-list-header h3{margin:0;font-size:1rem;font-weight:600;color:#333}.add-column-menu{position:relative}.add-column-menu.open .add-btn{background-color:#e3f2fd;border-color:#2196f3}.add-btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.add-btn:hover{background-color:#f5f5f5}.add-menu{position:absolute;top:100%;right:0;margin-top:.25rem;background-color:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 4px 8px #0000001a;z-index:100;min-width:150px}.menu-item{display:block;width:100%;padding:.75rem 1rem;border:none;background:none;text-align:left;cursor:pointer;font-size:.875rem;color:#333;transition:background-color .2s}.menu-item:hover{background-color:#f5f5f5}.menu-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.menu-item:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px}.column-items{max-height:400px;overflow-y:auto;padding:.5rem}.column-item{display:flex;align-items:center;gap:.5rem;padding:.75rem;margin-bottom:.5rem;border:1px solid #e0e0e0;border-radius:4px;background-color:#fff;cursor:pointer;transition:all .2s}.column-item:hover{border-color:#b0b0b0;background-color:#f8f8f8}.column-item.selected{border-color:#2196f3;background-color:#e3f2fd}.column-item.cdk-drag-preview{box-shadow:0 8px 16px #0003;opacity:.9}.column-item.cdk-drag-placeholder{opacity:.3}.drag-handle{cursor:move;color:#999;font-size:1.25rem;padding:.25rem;display:flex;align-items:center}.drag-handle:hover{color:#666}.column-info{flex:1;min-width:0}.column-name{font-weight:500;color:#333;margin-bottom:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.column-meta{display:flex;gap:.5rem;font-size:.75rem;color:#666}.column-type{padding:.125rem .5rem;background-color:#e8e8e8;border-radius:3px}.column-key{font-family:monospace;color:#999}.delete-btn{padding:.25rem .5rem;border:none;background:none;color:#999;cursor:pointer;font-size:1.5rem;line-height:1;transition:color .2s}.delete-btn:hover{color:#f44336}.empty-state{padding:2rem;text-align:center;color:#999;font-size:.875rem}.column-item.dragging{opacity:.5}.column-item.drag-over{border-color:#2196f3}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
12171
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ColumnListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12172
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: ColumnListComponent, isStandalone: true, selector: "st-column-list", inputs: { columns: "columns", selectedIndex: "selectedIndex" }, outputs: { columnSelected: "columnSelected", columnAdded: "columnAdded", columnDeleted: "columnDeleted", columnReordered: "columnReordered" }, ngImport: i0, template: "<div class=\"column-list\" (clickOutside)=\"closeMenu()\">\n <div class=\"column-list-header\">\n <h3>Columns</h3>\n <div class=\"add-column-menu\" [class.open]=\"showAddMenu\">\n <button class=\"add-btn\" (click)=\"showAddMenu = !showAddMenu\" title=\"Add Column\">\n <span>+ Add Column</span>\n </button>\n @if (showAddMenu) {\n <div class=\"add-menu\">\n @for (type of dataTypes; track type.value) {\n <button\n class=\"menu-item\"\n (click)=\"onAddColumn(type.value)\">\n {{ type.label }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n\n <div class=\"column-items\">\n @for (column of columns; track column.key; let i = $index) {\n <div\n class=\"column-item\"\n [class.selected]=\"selectedIndex === i\"\n [class.dragging]=\"draggedIndex === i\"\n [class.drag-over]=\"dragOverIndex === i\"\n (click)=\"onColumnClick(i)\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\"\n (dragend)=\"onDragEnd($event)\"\n (dragleave)=\"dragOverIndex = null\">\n <div class=\"drag-handle\">\n <span>\u2630</span>\n </div>\n <div class=\"column-info\">\n <div class=\"column-name\">{{ getColumnDisplayName(column) }}</div>\n <div class=\"column-meta\">\n <span class=\"column-type\">{{ getDataTypeLabel(column) }}</span>\n <span class=\"column-key\">{{ column.key }}</span>\n </div>\n </div>\n <button\n class=\"delete-btn\"\n (click)=\"onDelete(i, $event)\"\n title=\"Delete Column\">\n \u00D7\n </button>\n </div>\n }\n\n @if (columns.length === 0) {\n <div class=\"empty-state\">\n <p>No columns yet. Click \"Add Column\" to get started.</p>\n </div>\n }\n </div>\n</div>\n", styles: [".column-list{display:flex;flex-direction:column;background-color:#fff;border-radius:4px;box-shadow:0 2px 4px #0000001a;overflow:hidden}.column-list-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.column-list-header h3{margin:0;font-size:1rem;font-weight:600;color:#333}.add-column-menu{position:relative}.add-column-menu.open .add-btn{background-color:#e3f2fd;border-color:#2196f3}.add-btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.add-btn:hover{background-color:#f5f5f5}.add-menu{position:absolute;top:100%;right:0;margin-top:.25rem;background-color:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 4px 8px #0000001a;z-index:100;min-width:150px}.menu-item{display:block;width:100%;padding:.75rem 1rem;border:none;background:none;text-align:left;cursor:pointer;font-size:.875rem;color:#333;transition:background-color .2s}.menu-item:hover{background-color:#f5f5f5}.menu-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.menu-item:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px}.column-items{max-height:400px;overflow-y:auto;padding:.5rem}.column-item{display:flex;align-items:center;gap:.5rem;padding:.75rem;margin-bottom:.5rem;border:1px solid #e0e0e0;border-radius:4px;background-color:#fff;cursor:pointer;transition:all .2s}.column-item:hover{border-color:#b0b0b0;background-color:#f8f8f8}.column-item.selected{border-color:#2196f3;background-color:#e3f2fd}.column-item.cdk-drag-preview{box-shadow:0 8px 16px #0003;opacity:.9}.column-item.cdk-drag-placeholder{opacity:.3}.drag-handle{cursor:move;color:#999;font-size:1.25rem;padding:.25rem;display:flex;align-items:center}.drag-handle:hover{color:#666}.column-info{flex:1;min-width:0}.column-name{font-weight:500;color:#333;margin-bottom:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.column-meta{display:flex;gap:.5rem;font-size:.75rem;color:#666}.column-type{padding:.125rem .5rem;background-color:#e8e8e8;border-radius:3px}.column-key{font-family:monospace;color:#999}.delete-btn{padding:.25rem .5rem;border:none;background:none;color:#999;cursor:pointer;font-size:1.5rem;line-height:1;transition:color .2s}.delete-btn:hover{color:#f44336}.empty-state{padding:2rem;text-align:center;color:#999;font-size:.875rem}.column-item.dragging{opacity:.5}.column-item.drag-over{border-color:#2196f3}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
11323
12173
  }
11324
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ColumnListComponent, decorators: [{
12174
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ColumnListComponent, decorators: [{
11325
12175
  type: Component,
11326
12176
  args: [{ selector: 'st-column-list', standalone: true, imports: [CommonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"column-list\" (clickOutside)=\"closeMenu()\">\n <div class=\"column-list-header\">\n <h3>Columns</h3>\n <div class=\"add-column-menu\" [class.open]=\"showAddMenu\">\n <button class=\"add-btn\" (click)=\"showAddMenu = !showAddMenu\" title=\"Add Column\">\n <span>+ Add Column</span>\n </button>\n @if (showAddMenu) {\n <div class=\"add-menu\">\n @for (type of dataTypes; track type.value) {\n <button\n class=\"menu-item\"\n (click)=\"onAddColumn(type.value)\">\n {{ type.label }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n\n <div class=\"column-items\">\n @for (column of columns; track column.key; let i = $index) {\n <div\n class=\"column-item\"\n [class.selected]=\"selectedIndex === i\"\n [class.dragging]=\"draggedIndex === i\"\n [class.drag-over]=\"dragOverIndex === i\"\n (click)=\"onColumnClick(i)\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event, i)\"\n (drop)=\"onDrop($event, i)\"\n (dragend)=\"onDragEnd($event)\"\n (dragleave)=\"dragOverIndex = null\">\n <div class=\"drag-handle\">\n <span>\u2630</span>\n </div>\n <div class=\"column-info\">\n <div class=\"column-name\">{{ getColumnDisplayName(column) }}</div>\n <div class=\"column-meta\">\n <span class=\"column-type\">{{ getDataTypeLabel(column) }}</span>\n <span class=\"column-key\">{{ column.key }}</span>\n </div>\n </div>\n <button\n class=\"delete-btn\"\n (click)=\"onDelete(i, $event)\"\n title=\"Delete Column\">\n \u00D7\n </button>\n </div>\n }\n\n @if (columns.length === 0) {\n <div class=\"empty-state\">\n <p>No columns yet. Click \"Add Column\" to get started.</p>\n </div>\n }\n </div>\n</div>\n", styles: [".column-list{display:flex;flex-direction:column;background-color:#fff;border-radius:4px;box-shadow:0 2px 4px #0000001a;overflow:hidden}.column-list-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.column-list-header h3{margin:0;font-size:1rem;font-weight:600;color:#333}.add-column-menu{position:relative}.add-column-menu.open .add-btn{background-color:#e3f2fd;border-color:#2196f3}.add-btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.add-btn:hover{background-color:#f5f5f5}.add-menu{position:absolute;top:100%;right:0;margin-top:.25rem;background-color:#fff;border:1px solid #d0d0d0;border-radius:4px;box-shadow:0 4px 8px #0000001a;z-index:100;min-width:150px}.menu-item{display:block;width:100%;padding:.75rem 1rem;border:none;background:none;text-align:left;cursor:pointer;font-size:.875rem;color:#333;transition:background-color .2s}.menu-item:hover{background-color:#f5f5f5}.menu-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.menu-item:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px}.column-items{max-height:400px;overflow-y:auto;padding:.5rem}.column-item{display:flex;align-items:center;gap:.5rem;padding:.75rem;margin-bottom:.5rem;border:1px solid #e0e0e0;border-radius:4px;background-color:#fff;cursor:pointer;transition:all .2s}.column-item:hover{border-color:#b0b0b0;background-color:#f8f8f8}.column-item.selected{border-color:#2196f3;background-color:#e3f2fd}.column-item.cdk-drag-preview{box-shadow:0 8px 16px #0003;opacity:.9}.column-item.cdk-drag-placeholder{opacity:.3}.drag-handle{cursor:move;color:#999;font-size:1.25rem;padding:.25rem;display:flex;align-items:center}.drag-handle:hover{color:#666}.column-info{flex:1;min-width:0}.column-name{font-weight:500;color:#333;margin-bottom:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.column-meta{display:flex;gap:.5rem;font-size:.75rem;color:#666}.column-type{padding:.125rem .5rem;background-color:#e8e8e8;border-radius:3px}.column-key{font-family:monospace;color:#999}.delete-btn{padding:.25rem .5rem;border:none;background:none;color:#999;cursor:pointer;font-size:1.5rem;line-height:1;transition:color .2s}.delete-btn:hover{color:#f44336}.empty-state{padding:2rem;text-align:center;color:#999;font-size:.875rem}.column-item.dragging{opacity:.5}.column-item.drag-over{border-color:#2196f3}\n"] }]
11327
12177
  }], propDecorators: { columns: [{
@@ -11454,10 +12304,10 @@ class TableConfigEditorComponent {
11454
12304
  this.configUpdated.emit(updates);
11455
12305
  }
11456
12306
  }
11457
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: TableConfigEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
11458
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: TableConfigEditorComponent, isStandalone: true, selector: "st-table-config-editor", inputs: { config: "config" }, outputs: { configUpdated: "configUpdated" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"table-config-editor\">\n <h3>Table Configuration</h3>\n\n <form [formGroup]=\"form\" class=\"config-form\">\n <!-- Pagination -->\n <div class=\"config-section\">\n <h4>Pagination</h4>\n <div formGroupName=\"pagination\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('pagination.enabled')?.value) {\n <div class=\"form-group\">\n <label>Page Size</label>\n <select formControlName=\"pageSize\" class=\"form-control\">\n @for (size of pageSizeOptions; track size) {\n <option [value]=\"size\">\n {{ size }}\n </option>\n }\n </select>\n </div>\n }\n @if (form.get('pagination.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"showTopControls\">\n <span>Show Top Controls</span>\n </label>\n }\n @if (form.get('pagination.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"showBottomControls\">\n <span>Show Bottom Controls</span>\n </label>\n }\n @if (form.get('pagination.enabled')?.value) {\n <div class=\"form-group\">\n <label>Variant</label>\n <select formControlName=\"variant\" class=\"form-control\">\n <option value=\"fluid\">Fluid</option>\n <option value=\"compact\">Compact</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Sorting -->\n <div class=\"config-section\">\n <h4>Sorting</h4>\n <div formGroupName=\"sorting\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('sorting.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"multiColumn\">\n <span>Multi-column</span>\n </label>\n }\n @if (form.get('sorting.enabled')?.value) {\n <div class=\"form-group\">\n <label>Mode</label>\n <select formControlName=\"mode\" class=\"form-control\">\n <option value=\"local\">Local</option>\n <option value=\"server\">Server</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Filtering -->\n <div class=\"config-section\">\n <h4>Filtering</h4>\n <div formGroupName=\"filtering\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('filtering.enabled')?.value) {\n <div class=\"form-group\">\n <label>Mode</label>\n <select formControlName=\"mode\" class=\"form-control\">\n <option value=\"local\">Local</option>\n <option value=\"server\">Server</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Display -->\n <div class=\"config-section\">\n <h4>Display</h4>\n <div formGroupName=\"display\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"stickyHeader\">\n <span>Sticky Header</span>\n </label>\n \n <!-- Virtual Scroll Configuration -->\n <div class=\"subsection\" formGroupName=\"virtualScroll\">\n <h5>Virtual Scroll</h5>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enable Virtual Scrolling (for large datasets)</span>\n </label>\n \n @if (form.get('display.virtualScroll.enabled')?.value) {\n <div class=\"virtual-scroll-options\">\n <div class=\"form-group\">\n <label>Row Height (px)</label>\n <input type=\"number\" formControlName=\"itemSize\" class=\"form-control\" min=\"20\" max=\"200\">\n <small class=\"help-text\">Must be consistent for all rows</small>\n </div>\n \n <div class=\"form-group\">\n <label>Buffer Size (rows)</label>\n <input type=\"number\" formControlName=\"bufferSize\" class=\"form-control\" min=\"0\" max=\"20\">\n <small class=\"help-text\">Rows rendered above/below viewport</small>\n </div>\n \n <div class=\"form-group\">\n <label>Viewport Height (px)</label>\n <input type=\"number\" formControlName=\"viewportHeight\" class=\"form-control\" min=\"200\" max=\"2000\">\n <small class=\"help-text\">Height of scrollable container</small>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Keyboard Navigation -->\n <div class=\"config-section\">\n <h4>Keyboard Navigation</h4>\n <div formGroupName=\"keyboardNavigation\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enable Excel-like Navigation</span>\n </label>\n </div>\n </div>\n </form>\n</div>\n", styles: [".table-config-editor{background-color:#fff;border-radius:4px;box-shadow:0 2px 4px #0000001a;padding:1rem;overflow-y:auto;max-height:500px}.table-config-editor h3{margin:0 0 1rem;font-size:1rem;font-weight:600;color:#333}.config-form{display:flex;flex-direction:column;gap:1.5rem}.config-section h4{margin:0 0 .75rem;font-size:.875rem;font-weight:600;color:#666;text-transform:uppercase;letter-spacing:.5px}.checkbox-label{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;cursor:pointer;font-size:.875rem;color:#333}.checkbox-label input[type=checkbox]{width:18px;height:18px;cursor:pointer}.form-group{margin-top:.75rem}.form-group label{display:block;margin-bottom:.5rem;font-size:.875rem;font-weight:500;color:#333}.form-control{width:100%;padding:.5rem;border:1px solid #d0d0d0;border-radius:4px;font-size:.875rem}.form-control:focus{outline:none;border-color:#2196f3}.subsection{margin-top:1rem;padding:.75rem;background-color:#f9f9f9;border-radius:4px;border-left:3px solid #2196f3}.subsection h5{margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#555;text-transform:uppercase;letter-spacing:.5px}.virtual-scroll-options{margin-top:.75rem;padding-left:.5rem}.help-text{display:block;margin-top:.25rem;font-size:.75rem;color:#666;font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }] }); }
12307
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TableConfigEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
12308
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: TableConfigEditorComponent, isStandalone: true, selector: "st-table-config-editor", inputs: { config: "config" }, outputs: { configUpdated: "configUpdated" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"table-config-editor\">\n <h3>Table Configuration</h3>\n\n <form [formGroup]=\"form\" class=\"config-form\">\n <!-- Pagination -->\n <div class=\"config-section\">\n <h4>Pagination</h4>\n <div formGroupName=\"pagination\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('pagination.enabled')?.value) {\n <div class=\"form-group\">\n <label>Page Size</label>\n <select formControlName=\"pageSize\" class=\"form-control\">\n @for (size of pageSizeOptions; track size) {\n <option [value]=\"size\">\n {{ size }}\n </option>\n }\n </select>\n </div>\n }\n @if (form.get('pagination.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"showTopControls\">\n <span>Show Top Controls</span>\n </label>\n }\n @if (form.get('pagination.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"showBottomControls\">\n <span>Show Bottom Controls</span>\n </label>\n }\n @if (form.get('pagination.enabled')?.value) {\n <div class=\"form-group\">\n <label>Variant</label>\n <select formControlName=\"variant\" class=\"form-control\">\n <option value=\"fluid\">Fluid</option>\n <option value=\"compact\">Compact</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Sorting -->\n <div class=\"config-section\">\n <h4>Sorting</h4>\n <div formGroupName=\"sorting\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('sorting.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"multiColumn\">\n <span>Multi-column</span>\n </label>\n }\n @if (form.get('sorting.enabled')?.value) {\n <div class=\"form-group\">\n <label>Mode</label>\n <select formControlName=\"mode\" class=\"form-control\">\n <option value=\"local\">Local</option>\n <option value=\"server\">Server</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Filtering -->\n <div class=\"config-section\">\n <h4>Filtering</h4>\n <div formGroupName=\"filtering\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('filtering.enabled')?.value) {\n <div class=\"form-group\">\n <label>Mode</label>\n <select formControlName=\"mode\" class=\"form-control\">\n <option value=\"local\">Local</option>\n <option value=\"server\">Server</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Display -->\n <div class=\"config-section\">\n <h4>Display</h4>\n <div formGroupName=\"display\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"stickyHeader\">\n <span>Sticky Header</span>\n </label>\n \n <!-- Virtual Scroll Configuration -->\n <div class=\"subsection\" formGroupName=\"virtualScroll\">\n <h5>Virtual Scroll</h5>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enable Virtual Scrolling (for large datasets)</span>\n </label>\n \n @if (form.get('display.virtualScroll.enabled')?.value) {\n <div class=\"virtual-scroll-options\">\n <div class=\"form-group\">\n <label>Row Height (px)</label>\n <input type=\"number\" formControlName=\"itemSize\" class=\"form-control\" min=\"20\" max=\"200\">\n <small class=\"help-text\">Must be consistent for all rows</small>\n </div>\n \n <div class=\"form-group\">\n <label>Buffer Size (rows)</label>\n <input type=\"number\" formControlName=\"bufferSize\" class=\"form-control\" min=\"0\" max=\"20\">\n <small class=\"help-text\">Rows rendered above/below viewport</small>\n </div>\n \n <div class=\"form-group\">\n <label>Viewport Height (px)</label>\n <input type=\"number\" formControlName=\"viewportHeight\" class=\"form-control\" min=\"200\" max=\"2000\">\n <small class=\"help-text\">Height of scrollable container</small>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Keyboard Navigation -->\n <div class=\"config-section\">\n <h4>Keyboard Navigation</h4>\n <div formGroupName=\"keyboardNavigation\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enable Excel-like Navigation</span>\n </label>\n </div>\n </div>\n </form>\n</div>\n", styles: [".table-config-editor{background-color:#fff;border-radius:4px;box-shadow:0 2px 4px #0000001a;padding:1rem;overflow-y:auto;max-height:500px}.table-config-editor h3{margin:0 0 1rem;font-size:1rem;font-weight:600;color:#333}.config-form{display:flex;flex-direction:column;gap:1.5rem}.config-section h4{margin:0 0 .75rem;font-size:.875rem;font-weight:600;color:#666;text-transform:uppercase;letter-spacing:.5px}.checkbox-label{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;cursor:pointer;font-size:.875rem;color:#333}.checkbox-label input[type=checkbox]{width:18px;height:18px;cursor:pointer}.form-group{margin-top:.75rem}.form-group label{display:block;margin-bottom:.5rem;font-size:.875rem;font-weight:500;color:#333}.form-control{width:100%;padding:.5rem;border:1px solid #d0d0d0;border-radius:4px;font-size:.875rem}.form-control:focus{outline:none;border-color:#2196f3}.subsection{margin-top:1rem;padding:.75rem;background-color:#f9f9f9;border-radius:4px;border-left:3px solid #2196f3}.subsection h5{margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#555;text-transform:uppercase;letter-spacing:.5px}.virtual-scroll-options{margin-top:.75rem;padding-left:.5rem}.help-text{display:block;margin-top:.25rem;font-size:.75rem;color:#666;font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }] }); }
11459
12309
  }
11460
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: TableConfigEditorComponent, decorators: [{
12310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TableConfigEditorComponent, decorators: [{
11461
12311
  type: Component,
11462
12312
  args: [{ selector: 'st-table-config-editor', standalone: true, imports: [CommonModule, ReactiveFormsModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"table-config-editor\">\n <h3>Table Configuration</h3>\n\n <form [formGroup]=\"form\" class=\"config-form\">\n <!-- Pagination -->\n <div class=\"config-section\">\n <h4>Pagination</h4>\n <div formGroupName=\"pagination\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('pagination.enabled')?.value) {\n <div class=\"form-group\">\n <label>Page Size</label>\n <select formControlName=\"pageSize\" class=\"form-control\">\n @for (size of pageSizeOptions; track size) {\n <option [value]=\"size\">\n {{ size }}\n </option>\n }\n </select>\n </div>\n }\n @if (form.get('pagination.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"showTopControls\">\n <span>Show Top Controls</span>\n </label>\n }\n @if (form.get('pagination.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"showBottomControls\">\n <span>Show Bottom Controls</span>\n </label>\n }\n @if (form.get('pagination.enabled')?.value) {\n <div class=\"form-group\">\n <label>Variant</label>\n <select formControlName=\"variant\" class=\"form-control\">\n <option value=\"fluid\">Fluid</option>\n <option value=\"compact\">Compact</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Sorting -->\n <div class=\"config-section\">\n <h4>Sorting</h4>\n <div formGroupName=\"sorting\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('sorting.enabled')?.value) {\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"multiColumn\">\n <span>Multi-column</span>\n </label>\n }\n @if (form.get('sorting.enabled')?.value) {\n <div class=\"form-group\">\n <label>Mode</label>\n <select formControlName=\"mode\" class=\"form-control\">\n <option value=\"local\">Local</option>\n <option value=\"server\">Server</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Filtering -->\n <div class=\"config-section\">\n <h4>Filtering</h4>\n <div formGroupName=\"filtering\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enabled</span>\n </label>\n @if (form.get('filtering.enabled')?.value) {\n <div class=\"form-group\">\n <label>Mode</label>\n <select formControlName=\"mode\" class=\"form-control\">\n <option value=\"local\">Local</option>\n <option value=\"server\">Server</option>\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Display -->\n <div class=\"config-section\">\n <h4>Display</h4>\n <div formGroupName=\"display\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"stickyHeader\">\n <span>Sticky Header</span>\n </label>\n \n <!-- Virtual Scroll Configuration -->\n <div class=\"subsection\" formGroupName=\"virtualScroll\">\n <h5>Virtual Scroll</h5>\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enable Virtual Scrolling (for large datasets)</span>\n </label>\n \n @if (form.get('display.virtualScroll.enabled')?.value) {\n <div class=\"virtual-scroll-options\">\n <div class=\"form-group\">\n <label>Row Height (px)</label>\n <input type=\"number\" formControlName=\"itemSize\" class=\"form-control\" min=\"20\" max=\"200\">\n <small class=\"help-text\">Must be consistent for all rows</small>\n </div>\n \n <div class=\"form-group\">\n <label>Buffer Size (rows)</label>\n <input type=\"number\" formControlName=\"bufferSize\" class=\"form-control\" min=\"0\" max=\"20\">\n <small class=\"help-text\">Rows rendered above/below viewport</small>\n </div>\n \n <div class=\"form-group\">\n <label>Viewport Height (px)</label>\n <input type=\"number\" formControlName=\"viewportHeight\" class=\"form-control\" min=\"200\" max=\"2000\">\n <small class=\"help-text\">Height of scrollable container</small>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Keyboard Navigation -->\n <div class=\"config-section\">\n <h4>Keyboard Navigation</h4>\n <div formGroupName=\"keyboardNavigation\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" formControlName=\"enabled\">\n <span>Enable Excel-like Navigation</span>\n </label>\n </div>\n </div>\n </form>\n</div>\n", styles: [".table-config-editor{background-color:#fff;border-radius:4px;box-shadow:0 2px 4px #0000001a;padding:1rem;overflow-y:auto;max-height:500px}.table-config-editor h3{margin:0 0 1rem;font-size:1rem;font-weight:600;color:#333}.config-form{display:flex;flex-direction:column;gap:1.5rem}.config-section h4{margin:0 0 .75rem;font-size:.875rem;font-weight:600;color:#666;text-transform:uppercase;letter-spacing:.5px}.checkbox-label{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;cursor:pointer;font-size:.875rem;color:#333}.checkbox-label input[type=checkbox]{width:18px;height:18px;cursor:pointer}.form-group{margin-top:.75rem}.form-group label{display:block;margin-bottom:.5rem;font-size:.875rem;font-weight:500;color:#333}.form-control{width:100%;padding:.5rem;border:1px solid #d0d0d0;border-radius:4px;font-size:.875rem}.form-control:focus{outline:none;border-color:#2196f3}.subsection{margin-top:1rem;padding:.75rem;background-color:#f9f9f9;border-radius:4px;border-left:3px solid #2196f3}.subsection h5{margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#555;text-transform:uppercase;letter-spacing:.5px}.virtual-scroll-options{margin-top:.75rem;padding-left:.5rem}.help-text{display:block;margin-top:.25rem;font-size:.75rem;color:#666;font-style:italic}\n"] }]
11463
12313
  }], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { config: [{
@@ -11579,10 +12429,10 @@ class SampleDataGeneratorService {
11579
12429
  generateBooleanValue(rowIndex) {
11580
12430
  return rowIndex % 2 === 0;
11581
12431
  }
11582
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SampleDataGeneratorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
11583
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SampleDataGeneratorService, providedIn: 'root' }); }
12432
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SampleDataGeneratorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
12433
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SampleDataGeneratorService, providedIn: 'root' }); }
11584
12434
  }
11585
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SampleDataGeneratorService, decorators: [{
12435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SampleDataGeneratorService, decorators: [{
11586
12436
  type: Injectable,
11587
12437
  args: [{
11588
12438
  providedIn: 'root'
@@ -11637,10 +12487,10 @@ class BuilderPreviewComponent {
11637
12487
  // But we can log them for debugging
11638
12488
  console.log('Preview state change:', event);
11639
12489
  }
11640
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BuilderPreviewComponent, deps: [{ token: SampleDataGeneratorService }], target: i0.ɵɵFactoryTarget.Component }); }
11641
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: BuilderPreviewComponent, isStandalone: true, selector: "st-builder-preview", inputs: { tableConfig: "tableConfig" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"builder-preview\">\n <div class=\"preview-header\">\n <h3>Live Preview</h3>\n <button class=\"refresh-btn\" (click)=\"refreshPreview()\" title=\"Refresh Preview\">\n \u21BB Refresh\n </button>\n </div>\n\n <div class=\"preview-content\">\n @if (isLoading) {\n <div class=\"loading\">\n <p>Generating preview...</p>\n </div>\n }\n\n @if (!isLoading && tableConfig?.columns?.length === 0) {\n <div class=\"empty-state\">\n <p>Add columns to see preview</p>\n </div>\n }\n @if (tableConfig) {\n @if (!isLoading && tableConfig!.columns!.length > 0) {\n <st-table\n [tableConfig]=\"tableConfig\"\n [data]=\"sampleData\"\n (stateChange)=\"onStateChange($event)\">\n </st-table>\n }\n }\n\n </div>\n</div>\n", styles: [".builder-preview{height:100%}.preview-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.preview-header h3{margin:0;font-size:1rem;font-weight:600;color:#333}.refresh-btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.refresh-btn:hover{background-color:#f5f5f5}.preview-content{overflow:auto}.loading,.empty-state{display:flex;align-items:center;justify-content:center;height:200px;color:#999;font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }] }); }
12490
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BuilderPreviewComponent, deps: [{ token: SampleDataGeneratorService }], target: i0.ɵɵFactoryTarget.Component }); }
12491
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: BuilderPreviewComponent, isStandalone: true, selector: "st-builder-preview", inputs: { tableConfig: "tableConfig" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"builder-preview\">\n <div class=\"preview-header\">\n <h3>Live Preview</h3>\n <button class=\"refresh-btn\" (click)=\"refreshPreview()\" title=\"Refresh Preview\">\n \u21BB Refresh\n </button>\n </div>\n\n <div class=\"preview-content\">\n @if (isLoading) {\n <div class=\"loading\">\n <p>Generating preview...</p>\n </div>\n }\n\n @if (!isLoading && tableConfig?.columns?.length === 0) {\n <div class=\"empty-state\">\n <p>Add columns to see preview</p>\n </div>\n }\n @if (tableConfig) {\n @if (!isLoading && tableConfig!.columns!.length > 0) {\n <st-table\n [tableConfig]=\"tableConfig\"\n [data]=\"sampleData\"\n (stateChange)=\"onStateChange($event)\">\n </st-table>\n }\n }\n\n </div>\n</div>\n", styles: [".builder-preview{height:100%}.preview-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.preview-header h3{margin:0;font-size:1rem;font-weight:600;color:#333}.refresh-btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.refresh-btn:hover{background-color:#f5f5f5}.preview-content{overflow:auto}.loading,.empty-state{display:flex;align-items:center;justify-content:center;height:200px;color:#999;font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }] }); }
11642
12492
  }
11643
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BuilderPreviewComponent, decorators: [{
12493
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BuilderPreviewComponent, decorators: [{
11644
12494
  type: Component,
11645
12495
  args: [{ selector: 'st-builder-preview', standalone: true, imports: [CommonModule, StTableComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<div class=\"builder-preview\">\n <div class=\"preview-header\">\n <h3>Live Preview</h3>\n <button class=\"refresh-btn\" (click)=\"refreshPreview()\" title=\"Refresh Preview\">\n \u21BB Refresh\n </button>\n </div>\n\n <div class=\"preview-content\">\n @if (isLoading) {\n <div class=\"loading\">\n <p>Generating preview...</p>\n </div>\n }\n\n @if (!isLoading && tableConfig?.columns?.length === 0) {\n <div class=\"empty-state\">\n <p>Add columns to see preview</p>\n </div>\n }\n @if (tableConfig) {\n @if (!isLoading && tableConfig!.columns!.length > 0) {\n <st-table\n [tableConfig]=\"tableConfig\"\n [data]=\"sampleData\"\n (stateChange)=\"onStateChange($event)\">\n </st-table>\n }\n }\n\n </div>\n</div>\n", styles: [".builder-preview{height:100%}.preview-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid #e0e0e0;background-color:#f8f8f8}.preview-header h3{margin:0;font-size:1rem;font-weight:600;color:#333}.refresh-btn{padding:.5rem 1rem;border:1px solid #d0d0d0;border-radius:4px;background-color:#fff;color:#333;cursor:pointer;font-size:.875rem;transition:all .2s}.refresh-btn:hover{background-color:#f5f5f5}.preview-content{overflow:auto}.loading,.empty-state{display:flex;align-items:center;justify-content:center;height:200px;color:#999;font-size:.875rem}\n"] }]
11646
12496
  }], ctorParameters: () => [{ type: SampleDataGeneratorService }], propDecorators: { tableConfig: [{
@@ -11735,10 +12585,10 @@ class DefinitionBuilderComponent {
11735
12585
  onColumnCancel() {
11736
12586
  this.builderService.clearSelection();
11737
12587
  }
11738
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderComponent, deps: [{ token: DefinitionBuilderService }], target: i0.ɵɵFactoryTarget.Component }); }
11739
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: DefinitionBuilderComponent, isStandalone: true, selector: "st-definition-builder", ngImport: i0, template: "<div class=\"definition-builder\">\n <!-- Toolbar -->\n <st-builder-toolbar\n [hasUnsavedChanges]=\"state.hasUnsavedChanges\"\n (newDefinition)=\"onNewDefinition()\"\n (saved)=\"onSaved()\"\n (previewToggled)=\"onPreviewToggled()\">\n </st-builder-toolbar>\n\n <div class=\"builder-content\">\n <!-- Left Panel: Column List and Table Config -->\n <div class=\"left-panel\">\n <!-- Column List -->\n <st-column-list\n [columns]=\"state.tableConfig.columns\"\n [selectedIndex]=\"state.selectedColumnIndex\"\n (columnSelected)=\"onColumnSelected($event)\"\n (columnAdded)=\"onColumnAdded($event)\"\n (columnDeleted)=\"onColumnDeleted($event)\"\n (columnReordered)=\"onColumnReordered($event.fromIndex, $event.toIndex)\">\n </st-column-list>\n\n <!-- Table Config Editor -->\n <st-table-config-editor\n [config]=\"state.tableConfig\"\n (configUpdated)=\"onTableConfigUpdated($event)\">\n </st-table-config-editor>\n </div>\n\n <!-- Middle Panel: Column Editor -->\n @if (state.selectedColumn) {\n <div class=\"middle-panel\">\n <st-column-editor\n [column]=\"state.selectedColumn\"\n [columnIndex]=\"state.selectedColumnIndex!\"\n (columnUpdated)=\"onColumnUpdated(state.selectedColumnIndex!, $event)\"\n (cancel)=\"onColumnCancel()\">\n </st-column-editor>\n </div>\n }\n\n <!-- Right Panel: Preview -->\n @if (state.previewVisible) {\n <div class=\"right-panel\">\n <st-builder-preview\n [tableConfig]=\"state.tableConfig\">\n </st-builder-preview>\n </div>\n }\n </div>\n</div>\n", styles: [".definition-builder{display:flex;flex-direction:column;height:100%;width:100%;background-color:#f5f5f5}.builder-content{display:flex;flex:1;overflow:hidden;gap:1rem;padding:1rem}.left-panel{display:flex;flex-direction:column;width:300px;min-width:250px;gap:1rem;overflow-y:auto}.middle-panel{flex:1;min-width:400px;overflow-y:auto;background-color:#fff;border-radius:4px;padding:1rem;box-shadow:0 2px 4px #0000001a}.right-panel{min-width:400px;overflow-y:auto;background-color:#fff;border-radius:4px;padding:1rem;box-shadow:0 2px 4px #0000001a}@media(max-width:1200px){.right-panel{display:none}}@media(max-width:800px){.builder-content{flex-direction:column}.left-panel,.middle-panel,.right-panel{width:100%;min-width:unset}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BuilderToolbarComponent, selector: "st-builder-toolbar", inputs: ["hasUnsavedChanges"], outputs: ["newDefinition", "saved", "previewToggled"] }, { kind: "component", type: ColumnListComponent, selector: "st-column-list", inputs: ["columns", "selectedIndex"], outputs: ["columnSelected", "columnAdded", "columnDeleted", "columnReordered"] }, { kind: "component", type: TableConfigEditorComponent, selector: "st-table-config-editor", inputs: ["config"], outputs: ["configUpdated"] }, { kind: "component", type: ColumnEditorComponent, selector: "st-column-editor", inputs: ["column", "columnIndex"], outputs: ["columnUpdated", "cancel"] }, { kind: "component", type: BuilderPreviewComponent, selector: "st-builder-preview", inputs: ["tableConfig"] }] }); }
12588
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderComponent, deps: [{ token: DefinitionBuilderService }], target: i0.ɵɵFactoryTarget.Component }); }
12589
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: DefinitionBuilderComponent, isStandalone: true, selector: "st-definition-builder", ngImport: i0, template: "<div class=\"definition-builder\">\n <!-- Toolbar -->\n <st-builder-toolbar\n [hasUnsavedChanges]=\"state.hasUnsavedChanges\"\n (newDefinition)=\"onNewDefinition()\"\n (saved)=\"onSaved()\"\n (previewToggled)=\"onPreviewToggled()\">\n </st-builder-toolbar>\n\n <div class=\"builder-content\">\n <!-- Left Panel: Column List and Table Config -->\n <div class=\"left-panel\">\n <!-- Column List -->\n <st-column-list\n [columns]=\"state.tableConfig.columns\"\n [selectedIndex]=\"state.selectedColumnIndex\"\n (columnSelected)=\"onColumnSelected($event)\"\n (columnAdded)=\"onColumnAdded($event)\"\n (columnDeleted)=\"onColumnDeleted($event)\"\n (columnReordered)=\"onColumnReordered($event.fromIndex, $event.toIndex)\">\n </st-column-list>\n\n <!-- Table Config Editor -->\n <st-table-config-editor\n [config]=\"state.tableConfig\"\n (configUpdated)=\"onTableConfigUpdated($event)\">\n </st-table-config-editor>\n </div>\n\n <!-- Middle Panel: Column Editor -->\n @if (state.selectedColumn) {\n <div class=\"middle-panel\">\n <st-column-editor\n [column]=\"state.selectedColumn\"\n [columnIndex]=\"state.selectedColumnIndex!\"\n (columnUpdated)=\"onColumnUpdated(state.selectedColumnIndex!, $event)\"\n (cancel)=\"onColumnCancel()\">\n </st-column-editor>\n </div>\n }\n\n <!-- Right Panel: Preview -->\n @if (state.previewVisible) {\n <div class=\"right-panel\">\n <st-builder-preview\n [tableConfig]=\"state.tableConfig\">\n </st-builder-preview>\n </div>\n }\n </div>\n</div>\n", styles: [".definition-builder{display:flex;flex-direction:column;height:100%;width:100%;background-color:#f5f5f5}.builder-content{display:flex;flex:1;overflow:hidden;gap:1rem;padding:1rem}.left-panel{display:flex;flex-direction:column;width:300px;min-width:250px;gap:1rem;overflow-y:auto}.middle-panel{flex:1;min-width:400px;overflow-y:auto;background-color:#fff;border-radius:4px;padding:1rem;box-shadow:0 2px 4px #0000001a}.right-panel{min-width:400px;overflow-y:auto;background-color:#fff;border-radius:4px;padding:1rem;box-shadow:0 2px 4px #0000001a}@media(max-width:1200px){.right-panel{display:none}}@media(max-width:800px){.builder-content{flex-direction:column}.left-panel,.middle-panel,.right-panel{width:100%;min-width:unset}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BuilderToolbarComponent, selector: "st-builder-toolbar", inputs: ["hasUnsavedChanges"], outputs: ["newDefinition", "saved", "previewToggled"] }, { kind: "component", type: ColumnListComponent, selector: "st-column-list", inputs: ["columns", "selectedIndex"], outputs: ["columnSelected", "columnAdded", "columnDeleted", "columnReordered"] }, { kind: "component", type: TableConfigEditorComponent, selector: "st-table-config-editor", inputs: ["config"], outputs: ["configUpdated"] }, { kind: "component", type: ColumnEditorComponent, selector: "st-column-editor", inputs: ["column", "columnIndex"], outputs: ["columnUpdated", "cancel"] }, { kind: "component", type: BuilderPreviewComponent, selector: "st-builder-preview", inputs: ["tableConfig"] }] }); }
11740
12590
  }
11741
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderComponent, decorators: [{
12591
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderComponent, decorators: [{
11742
12592
  type: Component,
11743
12593
  args: [{ selector: 'st-definition-builder', standalone: true, imports: [
11744
12594
  CommonModule,
@@ -11759,8 +12609,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
11759
12609
  * Module for the Visual UI Builder components
11760
12610
  */
11761
12611
  class DefinitionBuilderModule {
11762
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
11763
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderModule, imports: [SmartTableModule,
12612
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
12613
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderModule, imports: [SmartTableModule,
11764
12614
  SharedTableComponentsModule,
11765
12615
  DefinitionBuilderComponent,
11766
12616
  BuilderToolbarComponent,
@@ -11772,7 +12622,7 @@ class DefinitionBuilderModule {
11772
12622
  TableConfigEditorComponent,
11773
12623
  BuilderPreviewComponent,
11774
12624
  SharedTableComponentsModule] }); }
11775
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderModule, imports: [SmartTableModule,
12625
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderModule, imports: [SmartTableModule,
11776
12626
  SharedTableComponentsModule,
11777
12627
  DefinitionBuilderComponent,
11778
12628
  BuilderToolbarComponent,
@@ -11780,7 +12630,7 @@ class DefinitionBuilderModule {
11780
12630
  TableConfigEditorComponent,
11781
12631
  BuilderPreviewComponent, SharedTableComponentsModule] }); }
11782
12632
  }
11783
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DefinitionBuilderModule, decorators: [{
12633
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DefinitionBuilderModule, decorators: [{
11784
12634
  type: NgModule,
11785
12635
  args: [{
11786
12636
  imports: [
@@ -11833,10 +12683,10 @@ class RowValidationService {
11833
12683
  };
11834
12684
  }
11835
12685
  }
11836
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: RowValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
11837
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: RowValidationService, providedIn: 'root' }); }
12686
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: RowValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
12687
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: RowValidationService, providedIn: 'root' }); }
11838
12688
  }
11839
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: RowValidationService, decorators: [{
12689
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: RowValidationService, decorators: [{
11840
12690
  type: Injectable,
11841
12691
  args: [{
11842
12692
  providedIn: 'root'
@@ -11855,5 +12705,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
11855
12705
  * Generated bundle index. Do not edit.
11856
12706
  */
11857
12707
 
11858
- 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 };
12708
+ 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 };
11859
12709
  //# sourceMappingURL=aquera-ngx-smart-table.mjs.map