@aquera/ngx-smart-table 0.0.26 → 0.0.27

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.
@@ -4946,6 +4946,7 @@ class NileChipEditor {
4946
4946
  this.acceptsInitialKeypress = false;
4947
4947
  this.eventListeners = [];
4948
4948
  this.trackedValues = [];
4949
+ this.hasChangeOccurred = false;
4949
4950
  }
4950
4951
  edit(context) {
4951
4952
  if (!context.container) {
@@ -5098,6 +5099,7 @@ class NileChipEditor {
5098
5099
  const detail = e.detail;
5099
5100
  const newValue = Array.isArray(detail?.value) ? [...detail.value] : (this.chip?.value ? [...this.chip.value] : []);
5100
5101
  this.trackedValues = newValue;
5102
+ this.hasChangeOccurred = true;
5101
5103
  context.onChange(newValue);
5102
5104
  });
5103
5105
  // Keyboard handling on the chip element
@@ -5166,6 +5168,7 @@ class NileChipEditor {
5166
5168
  this.chip = undefined;
5167
5169
  this.cellContainer = undefined;
5168
5170
  this.trackedValues = [];
5171
+ this.hasChangeOccurred = false;
5169
5172
  }
5170
5173
  focus() {
5171
5174
  try {
@@ -5174,7 +5177,7 @@ class NileChipEditor {
5174
5177
  catch { /* ignore */ }
5175
5178
  }
5176
5179
  getCurrentValue() {
5177
- if (this.trackedValues.length > 0) {
5180
+ if (this.hasChangeOccurred) {
5178
5181
  return [...this.trackedValues];
5179
5182
  }
5180
5183
  if (!this.chip)
@@ -8391,7 +8394,7 @@ class StColumnMenuDropdownComponent {
8391
8394
  */
8392
8395
  this.isOpen = false;
8393
8396
  /**
8394
- * Position of the dropdown (x, y coordinates)
8397
+ * Position of the dropdown (x, y coordinates, triggerTop for flip positioning)
8395
8398
  */
8396
8399
  this.position = { x: 0, y: 0 };
8397
8400
  /**
@@ -8504,25 +8507,40 @@ class StColumnMenuDropdownComponent {
8504
8507
  this.dropdownStyle = {};
8505
8508
  return;
8506
8509
  }
8507
- const viewportWidth = window.innerWidth;
8508
- const viewportHeight = window.innerHeight;
8509
- const dropdownWidth = 280; // Approximate dropdown width
8510
- const dropdownHeight = 300; // Approximate max dropdown height
8511
8510
  let { x, y } = this.position;
8512
- // Adjust horizontal position if dropdown would overflow
8513
- if (x + dropdownWidth > viewportWidth) {
8514
- x = Math.max(10, viewportWidth - dropdownWidth - 10);
8515
- }
8516
- // Adjust vertical position if dropdown would overflow
8517
- if (y + dropdownHeight > viewportHeight) {
8518
- y = Math.max(10, viewportHeight - dropdownHeight - 10);
8519
- }
8511
+ // Render at initial position first (hidden until measured)
8520
8512
  this.dropdownStyle = {
8521
8513
  position: 'fixed',
8522
8514
  left: `${x}px`,
8523
8515
  top: `${y}px`,
8524
- 'z-index': 9999
8516
+ 'z-index': 9999,
8517
+ visibility: 'hidden'
8525
8518
  };
8519
+ // After rendering, measure actual size and adjust if needed
8520
+ requestAnimationFrame(() => {
8521
+ const viewportWidth = window.innerWidth;
8522
+ const viewportHeight = window.innerHeight;
8523
+ const el = this.dropdownPanel?.nativeElement;
8524
+ const dropdownWidth = el?.offsetWidth || 280;
8525
+ const dropdownHeight = el?.offsetHeight || 200;
8526
+ // Adjust horizontal position if dropdown would overflow
8527
+ if (x + dropdownWidth > viewportWidth) {
8528
+ x = Math.max(10, viewportWidth - dropdownWidth - 10);
8529
+ }
8530
+ // Adjust vertical position — flip above the trigger if it overflows bottom
8531
+ if (y + dropdownHeight > viewportHeight) {
8532
+ const triggerTop = this.position.triggerTop ?? this.position.y;
8533
+ y = triggerTop - dropdownHeight - 4;
8534
+ }
8535
+ // Clamp to viewport edges
8536
+ x = Math.max(10, x);
8537
+ y = Math.max(10, y);
8538
+ if (el) {
8539
+ el.style.left = `${x}px`;
8540
+ el.style.top = `${y}px`;
8541
+ el.style.visibility = 'visible';
8542
+ }
8543
+ });
8526
8544
  }
8527
8545
  /**
8528
8546
  * Check if an action is disabled
@@ -8588,11 +8606,11 @@ class StColumnMenuDropdownComponent {
8588
8606
  return (this.context?.columnIndex || 0) <= 1;
8589
8607
  }
8590
8608
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: StColumnMenuDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8591
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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"] }] }); }
8609
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 }, { propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], 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\" #dropdownPanel [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"] }] }); }
8592
8610
  }
8593
8611
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: StColumnMenuDropdownComponent, decorators: [{
8594
8612
  type: Component,
8595
- 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"] }]
8613
+ 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\" #dropdownPanel [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"] }]
8596
8614
  }], propDecorators: { isOpen: [{
8597
8615
  type: Input
8598
8616
  }], position: [{
@@ -8606,6 +8624,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
8606
8624
  }], filterPopup: [{
8607
8625
  type: ViewChild,
8608
8626
  args: ['filterPopup']
8627
+ }], dropdownPanel: [{
8628
+ type: ViewChild,
8629
+ args: ['dropdownPanel']
8609
8630
  }], onBackdropClick: [{
8610
8631
  type: HostListener,
8611
8632
  args: ['click', ['$event']]
@@ -8618,7 +8639,7 @@ class StRowActionsDropdownComponent {
8618
8639
  */
8619
8640
  this.isOpen = false;
8620
8641
  /**
8621
- * Position of the dropdown (x, y coordinates)
8642
+ * Position of the dropdown (x, y coordinates, triggerTop for flip positioning)
8622
8643
  */
8623
8644
  this.position = { x: 0, y: 0 };
8624
8645
  /**
@@ -8673,35 +8694,39 @@ class StRowActionsDropdownComponent {
8673
8694
  this.dropdownStyle = {};
8674
8695
  return;
8675
8696
  }
8676
- const DROPDOWN_WIDTH = 200; // Approximate width
8677
- const DROPDOWN_HEIGHT = this.visibleActions.length * 40 + 16; // Approximate height
8678
- const viewportWidth = window.innerWidth;
8679
- const viewportHeight = window.innerHeight;
8680
8697
  let left = this.position.x;
8681
8698
  let top = this.position.y;
8682
- // Check if dropdown would overflow right edge
8683
- if (left + DROPDOWN_WIDTH > viewportWidth) {
8684
- left = viewportWidth - DROPDOWN_WIDTH - 10;
8685
- }
8686
- // Check if dropdown would overflow bottom edge
8687
- if (top + DROPDOWN_HEIGHT > viewportHeight) {
8688
- // Position above the trigger
8689
- top = this.position.y - DROPDOWN_HEIGHT;
8690
- }
8691
- // Ensure dropdown doesn't go off-screen on the left
8692
- if (left < 10) {
8693
- left = 10;
8694
- }
8695
- // Ensure dropdown doesn't go off-screen on the top
8696
- if (top < 10) {
8697
- top = 10;
8698
- }
8699
+ // Render at initial position first (hidden until measured)
8699
8700
  this.dropdownStyle = {
8700
8701
  position: 'fixed',
8701
8702
  left: `${left}px`,
8702
8703
  top: `${top}px`,
8703
- zIndex: TableZIndex.ROW_ACTIONS_DROPDOWN
8704
+ zIndex: TableZIndex.ROW_ACTIONS_DROPDOWN,
8705
+ visibility: 'hidden'
8704
8706
  };
8707
+ // After rendering, measure actual size and adjust position directly on the DOM
8708
+ // (OnPush change detection won't pick up property changes inside requestAnimationFrame)
8709
+ requestAnimationFrame(() => {
8710
+ const el = this.dropdownPanel?.nativeElement;
8711
+ if (!el)
8712
+ return;
8713
+ const viewportWidth = window.innerWidth;
8714
+ const viewportHeight = window.innerHeight;
8715
+ const dropdownWidth = el.offsetWidth || 200;
8716
+ const dropdownHeight = el.offsetHeight || (this.visibleActions.length * 40 + 16);
8717
+ if (left + dropdownWidth > viewportWidth) {
8718
+ left = viewportWidth - dropdownWidth - 10;
8719
+ }
8720
+ if (top + dropdownHeight > viewportHeight) {
8721
+ const triggerTop = this.position.triggerTop ?? this.position.y;
8722
+ top = triggerTop - dropdownHeight - 4;
8723
+ }
8724
+ left = Math.max(10, left);
8725
+ top = Math.max(10, top);
8726
+ el.style.left = `${left}px`;
8727
+ el.style.top = `${top}px`;
8728
+ el.style.visibility = 'visible';
8729
+ });
8705
8730
  }
8706
8731
  /**
8707
8732
  * Handle action click
@@ -8754,11 +8779,11 @@ class StRowActionsDropdownComponent {
8754
8779
  event.stopPropagation();
8755
8780
  }
8756
8781
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: StRowActionsDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8757
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 }); }
8782
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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)" } }, viewQueries: [{ propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], descendants: true }], 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\" #dropdownPanel [ngStyle]=\"dropdownStyle\">\n @if (isOpen) {\n <nile-menu>\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 }); }
8758
8783
  }
8759
8784
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: StRowActionsDropdownComponent, decorators: [{
8760
8785
  type: Component,
8761
- 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"] }]
8786
+ 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\" #dropdownPanel [ngStyle]=\"dropdownStyle\">\n @if (isOpen) {\n <nile-menu>\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"] }]
8762
8787
  }], propDecorators: { isOpen: [{
8763
8788
  type: Input
8764
8789
  }], position: [{
@@ -8769,6 +8794,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
8769
8794
  type: Output
8770
8795
  }], closed: [{
8771
8796
  type: Output
8797
+ }], dropdownPanel: [{
8798
+ type: ViewChild,
8799
+ args: ['dropdownPanel']
8772
8800
  }], onEscapeKey: [{
8773
8801
  type: HostListener,
8774
8802
  args: ['document:keydown.escape', ['$event']]
@@ -9610,7 +9638,8 @@ class StTableComponent {
9610
9638
  const rect = target.getBoundingClientRect();
9611
9639
  const position = {
9612
9640
  x: rect.left,
9613
- y: rect.bottom + 4
9641
+ y: rect.bottom + 4,
9642
+ triggerTop: rect.top
9614
9643
  };
9615
9644
  const context = {
9616
9645
  rowData,
@@ -9649,7 +9678,8 @@ class StTableComponent {
9649
9678
  const rect = target.getBoundingClientRect();
9650
9679
  const position = {
9651
9680
  x: rect.left,
9652
- y: rect.bottom + 4
9681
+ y: rect.bottom + 4,
9682
+ triggerTop: rect.top
9653
9683
  };
9654
9684
  const context = {
9655
9685
  column,