@aquera/ngx-smart-table 0.0.17-patch-0.6 → 0.0.17-patch-0.7
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.
- package/esm2020/lib/editors/nile-chip-editor.mjs +5 -2
- package/esm2020/lib/renderer/components/st-column-menu/st-column-menu.component.mjs +36 -17
- package/esm2020/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.mjs +34 -27
- package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +5 -5
- package/fesm2015/aquera-ngx-smart-table.mjs +77 -46
- package/fesm2015/aquera-ngx-smart-table.mjs.map +1 -1
- package/fesm2020/aquera-ngx-smart-table.mjs +75 -46
- package/fesm2020/aquera-ngx-smart-table.mjs.map +1 -1
- package/lib/editors/nile-chip-editor.d.ts +1 -0
- package/lib/renderer/components/st-column-menu/st-column-menu.component.d.ts +4 -2
- package/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.d.ts +4 -2
- package/lib/renderer/components/st-table/st-table.component.d.ts +2 -0
- package/package.json +1 -1
|
@@ -4945,6 +4945,7 @@ class NileChipEditor {
|
|
|
4945
4945
|
this.acceptsInitialKeypress = false;
|
|
4946
4946
|
this.eventListeners = [];
|
|
4947
4947
|
this.trackedValues = [];
|
|
4948
|
+
this.hasChangeOccurred = false;
|
|
4948
4949
|
}
|
|
4949
4950
|
edit(context) {
|
|
4950
4951
|
if (!context.container) {
|
|
@@ -5097,6 +5098,7 @@ class NileChipEditor {
|
|
|
5097
5098
|
const detail = e.detail;
|
|
5098
5099
|
const newValue = Array.isArray(detail?.value) ? [...detail.value] : (this.chip?.value ? [...this.chip.value] : []);
|
|
5099
5100
|
this.trackedValues = newValue;
|
|
5101
|
+
this.hasChangeOccurred = true;
|
|
5100
5102
|
context.onChange(newValue);
|
|
5101
5103
|
});
|
|
5102
5104
|
// Keyboard handling on the chip element
|
|
@@ -5165,6 +5167,7 @@ class NileChipEditor {
|
|
|
5165
5167
|
this.chip = undefined;
|
|
5166
5168
|
this.cellContainer = undefined;
|
|
5167
5169
|
this.trackedValues = [];
|
|
5170
|
+
this.hasChangeOccurred = false;
|
|
5168
5171
|
}
|
|
5169
5172
|
focus() {
|
|
5170
5173
|
try {
|
|
@@ -5173,7 +5176,7 @@ class NileChipEditor {
|
|
|
5173
5176
|
catch { /* ignore */ }
|
|
5174
5177
|
}
|
|
5175
5178
|
getCurrentValue() {
|
|
5176
|
-
if (this.
|
|
5179
|
+
if (this.hasChangeOccurred) {
|
|
5177
5180
|
return [...this.trackedValues];
|
|
5178
5181
|
}
|
|
5179
5182
|
if (!this.chip)
|
|
@@ -8096,7 +8099,7 @@ class StColumnMenuDropdownComponent {
|
|
|
8096
8099
|
*/
|
|
8097
8100
|
this.isOpen = false;
|
|
8098
8101
|
/**
|
|
8099
|
-
* Position of the dropdown (x, y coordinates)
|
|
8102
|
+
* Position of the dropdown (x, y coordinates, triggerTop for flip positioning)
|
|
8100
8103
|
*/
|
|
8101
8104
|
this.position = { x: 0, y: 0 };
|
|
8102
8105
|
/**
|
|
@@ -8209,25 +8212,41 @@ class StColumnMenuDropdownComponent {
|
|
|
8209
8212
|
this.dropdownStyle = {};
|
|
8210
8213
|
return;
|
|
8211
8214
|
}
|
|
8212
|
-
const viewportWidth = window.innerWidth;
|
|
8213
|
-
const viewportHeight = window.innerHeight;
|
|
8214
|
-
const dropdownWidth = 280; // Approximate dropdown width
|
|
8215
|
-
const dropdownHeight = 300; // Approximate max dropdown height
|
|
8216
8215
|
let { x, y } = this.position;
|
|
8217
|
-
//
|
|
8218
|
-
if (x + dropdownWidth > viewportWidth) {
|
|
8219
|
-
x = Math.max(10, viewportWidth - dropdownWidth - 10);
|
|
8220
|
-
}
|
|
8221
|
-
// Adjust vertical position if dropdown would overflow
|
|
8222
|
-
if (y + dropdownHeight > viewportHeight) {
|
|
8223
|
-
y = Math.max(10, viewportHeight - dropdownHeight - 10);
|
|
8224
|
-
}
|
|
8216
|
+
// Render at initial position first
|
|
8225
8217
|
this.dropdownStyle = {
|
|
8226
8218
|
position: 'fixed',
|
|
8227
8219
|
left: `${x}px`,
|
|
8228
8220
|
top: `${y}px`,
|
|
8229
|
-
'z-index': 9999
|
|
8221
|
+
'z-index': 9999,
|
|
8222
|
+
visibility: 'hidden'
|
|
8230
8223
|
};
|
|
8224
|
+
// After rendering, measure actual size and adjust if needed
|
|
8225
|
+
requestAnimationFrame(() => {
|
|
8226
|
+
const viewportWidth = window.innerWidth;
|
|
8227
|
+
const viewportHeight = window.innerHeight;
|
|
8228
|
+
const el = this.dropdownPanel?.nativeElement;
|
|
8229
|
+
const dropdownWidth = el?.offsetWidth || 280;
|
|
8230
|
+
const dropdownHeight = el?.offsetHeight || 200;
|
|
8231
|
+
// Adjust horizontal position if dropdown would overflow
|
|
8232
|
+
if (x + dropdownWidth > viewportWidth) {
|
|
8233
|
+
x = Math.max(10, viewportWidth - dropdownWidth - 10);
|
|
8234
|
+
}
|
|
8235
|
+
// Adjust vertical position — flip above the trigger if it overflows bottom
|
|
8236
|
+
if (y + dropdownHeight > viewportHeight) {
|
|
8237
|
+
const triggerTop = this.position.triggerTop ?? this.position.y;
|
|
8238
|
+
y = triggerTop - dropdownHeight - 4;
|
|
8239
|
+
}
|
|
8240
|
+
// Clamp to viewport edges
|
|
8241
|
+
x = Math.max(10, x);
|
|
8242
|
+
y = Math.max(10, y);
|
|
8243
|
+
this.dropdownStyle = {
|
|
8244
|
+
position: 'fixed',
|
|
8245
|
+
left: `${x}px`,
|
|
8246
|
+
top: `${y}px`,
|
|
8247
|
+
'z-index': 9999
|
|
8248
|
+
};
|
|
8249
|
+
});
|
|
8231
8250
|
}
|
|
8232
8251
|
/**
|
|
8233
8252
|
* Check if an action is disabled
|
|
@@ -8294,10 +8313,10 @@ class StColumnMenuDropdownComponent {
|
|
|
8294
8313
|
}
|
|
8295
8314
|
}
|
|
8296
8315
|
StColumnMenuDropdownComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StColumnMenuDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8297
|
-
StColumnMenuDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StColumnMenuDropdownComponent, 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<div class=\"dropdown-container\" *ngIf=\"isOpen && context\">\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 <nile-menu *ngIf=\"!isFilterOpen\">\n <!-- Dynamically render all visible actions -->\n <ng-container *ngFor=\"let action of visibleActions; let i = index; let last = last\">\n <nile-menu-item \n (click)=\"onActionClick(action)\"\n [class.disabled]=\"isActionDisabled(action)\"\n [class.active]=\"isActionActive(action)\">\n <span class=\"checkmark\" *ngIf=\"isActionActive(action)\">\u2713</span>\n <nile-icon slot=\"prefix\" *ngIf=\"action.icon && !isActionActive(action)\" [name]=\"action.icon\"></nile-icon>\n <span class=\"action-label\">{{ action.label }}</span>\n </nile-menu-item>\n \n <!-- Add divider after action groups -->\n <nile-divider *ngIf=\"shouldShowDividerAfter(action, i, last)\"></nile-divider>\n </ng-container>\n \n <!-- Fallback if no actions -->\n <nile-menu-item *ngIf=\"visibleActions.length === 0\">\n No actions available\n </nile-menu-item>\n </nile-menu>\n \n <!-- Filter popup (conditionally rendered) -->\n <st-column-filter\n #filterPopup\n *ngIf=\"isFilterOpen && context\"\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 </div>\n</div>\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"], components: [{ type: StColumnFilterComponent, selector: "st-column-filter", inputs: ["column", "tableState", "columnIndex", "isFirstColumn", "isLastColumn", "isOpen", "filterContext"], outputs: ["closed", "filterApplied", "filterCleared"] }], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
8316
|
+
StColumnMenuDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StColumnMenuDropdownComponent, 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<div class=\"dropdown-container\" *ngIf=\"isOpen && context\">\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 <nile-menu *ngIf=\"!isFilterOpen\">\n <!-- Dynamically render all visible actions -->\n <ng-container *ngFor=\"let action of visibleActions; let i = index; let last = last\">\n <nile-menu-item \n (click)=\"onActionClick(action)\"\n [class.disabled]=\"isActionDisabled(action)\"\n [class.active]=\"isActionActive(action)\">\n <span class=\"checkmark\" *ngIf=\"isActionActive(action)\">\u2713</span>\n <nile-icon slot=\"prefix\" *ngIf=\"action.icon && !isActionActive(action)\" [name]=\"action.icon\"></nile-icon>\n <span class=\"action-label\">{{ action.label }}</span>\n </nile-menu-item>\n \n <!-- Add divider after action groups -->\n <nile-divider *ngIf=\"shouldShowDividerAfter(action, i, last)\"></nile-divider>\n </ng-container>\n \n <!-- Fallback if no actions -->\n <nile-menu-item *ngIf=\"visibleActions.length === 0\">\n No actions available\n </nile-menu-item>\n </nile-menu>\n \n <!-- Filter popup (conditionally rendered) -->\n <st-column-filter\n #filterPopup\n *ngIf=\"isFilterOpen && context\"\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 </div>\n</div>\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"], components: [{ type: StColumnFilterComponent, selector: "st-column-filter", inputs: ["column", "tableState", "columnIndex", "isFirstColumn", "isLastColumn", "isOpen", "filterContext"], outputs: ["closed", "filterApplied", "filterCleared"] }], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
8298
8317
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StColumnMenuDropdownComponent, decorators: [{
|
|
8299
8318
|
type: Component,
|
|
8300
|
-
args: [{ selector: 'st-column-menu-dropdown', template: "<!-- Dropdown container with backdrop -->\n<div class=\"dropdown-container\" *ngIf=\"isOpen && context\">\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 <nile-menu *ngIf=\"!isFilterOpen\">\n <!-- Dynamically render all visible actions -->\n <ng-container *ngFor=\"let action of visibleActions; let i = index; let last = last\">\n <nile-menu-item \n (click)=\"onActionClick(action)\"\n [class.disabled]=\"isActionDisabled(action)\"\n [class.active]=\"isActionActive(action)\">\n <span class=\"checkmark\" *ngIf=\"isActionActive(action)\">\u2713</span>\n <nile-icon slot=\"prefix\" *ngIf=\"action.icon && !isActionActive(action)\" [name]=\"action.icon\"></nile-icon>\n <span class=\"action-label\">{{ action.label }}</span>\n </nile-menu-item>\n \n <!-- Add divider after action groups -->\n <nile-divider *ngIf=\"shouldShowDividerAfter(action, i, last)\"></nile-divider>\n </ng-container>\n \n <!-- Fallback if no actions -->\n <nile-menu-item *ngIf=\"visibleActions.length === 0\">\n No actions available\n </nile-menu-item>\n </nile-menu>\n \n <!-- Filter popup (conditionally rendered) -->\n <st-column-filter\n #filterPopup\n *ngIf=\"isFilterOpen && context\"\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 </div>\n</div>\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"] }]
|
|
8319
|
+
args: [{ selector: 'st-column-menu-dropdown', template: "<!-- Dropdown container with backdrop -->\n<div class=\"dropdown-container\" *ngIf=\"isOpen && context\">\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 <nile-menu *ngIf=\"!isFilterOpen\">\n <!-- Dynamically render all visible actions -->\n <ng-container *ngFor=\"let action of visibleActions; let i = index; let last = last\">\n <nile-menu-item \n (click)=\"onActionClick(action)\"\n [class.disabled]=\"isActionDisabled(action)\"\n [class.active]=\"isActionActive(action)\">\n <span class=\"checkmark\" *ngIf=\"isActionActive(action)\">\u2713</span>\n <nile-icon slot=\"prefix\" *ngIf=\"action.icon && !isActionActive(action)\" [name]=\"action.icon\"></nile-icon>\n <span class=\"action-label\">{{ action.label }}</span>\n </nile-menu-item>\n \n <!-- Add divider after action groups -->\n <nile-divider *ngIf=\"shouldShowDividerAfter(action, i, last)\"></nile-divider>\n </ng-container>\n \n <!-- Fallback if no actions -->\n <nile-menu-item *ngIf=\"visibleActions.length === 0\">\n No actions available\n </nile-menu-item>\n </nile-menu>\n \n <!-- Filter popup (conditionally rendered) -->\n <st-column-filter\n #filterPopup\n *ngIf=\"isFilterOpen && context\"\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 </div>\n</div>\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"] }]
|
|
8301
8320
|
}], propDecorators: { isOpen: [{
|
|
8302
8321
|
type: Input
|
|
8303
8322
|
}], position: [{
|
|
@@ -8311,6 +8330,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
8311
8330
|
}], filterPopup: [{
|
|
8312
8331
|
type: ViewChild,
|
|
8313
8332
|
args: ['filterPopup']
|
|
8333
|
+
}], dropdownPanel: [{
|
|
8334
|
+
type: ViewChild,
|
|
8335
|
+
args: ['dropdownPanel']
|
|
8314
8336
|
}], onBackdropClick: [{
|
|
8315
8337
|
type: HostListener,
|
|
8316
8338
|
args: ['click', ['$event']]
|
|
@@ -8323,7 +8345,7 @@ class StRowActionsDropdownComponent {
|
|
|
8323
8345
|
*/
|
|
8324
8346
|
this.isOpen = false;
|
|
8325
8347
|
/**
|
|
8326
|
-
* Position of the dropdown (x, y coordinates)
|
|
8348
|
+
* Position of the dropdown (x, y coordinates, triggerTop for flip positioning)
|
|
8327
8349
|
*/
|
|
8328
8350
|
this.position = { x: 0, y: 0 };
|
|
8329
8351
|
/**
|
|
@@ -8378,35 +8400,39 @@ class StRowActionsDropdownComponent {
|
|
|
8378
8400
|
this.dropdownStyle = {};
|
|
8379
8401
|
return;
|
|
8380
8402
|
}
|
|
8381
|
-
const DROPDOWN_WIDTH = 200; // Approximate width
|
|
8382
|
-
const DROPDOWN_HEIGHT = this.visibleActions.length * 40 + 16; // Approximate height
|
|
8383
|
-
const viewportWidth = window.innerWidth;
|
|
8384
|
-
const viewportHeight = window.innerHeight;
|
|
8385
8403
|
let left = this.position.x;
|
|
8386
8404
|
let top = this.position.y;
|
|
8387
|
-
//
|
|
8388
|
-
if (left + DROPDOWN_WIDTH > viewportWidth) {
|
|
8389
|
-
left = viewportWidth - DROPDOWN_WIDTH - 10;
|
|
8390
|
-
}
|
|
8391
|
-
// Check if dropdown would overflow bottom edge
|
|
8392
|
-
if (top + DROPDOWN_HEIGHT > viewportHeight) {
|
|
8393
|
-
// Position above the trigger
|
|
8394
|
-
top = this.position.y - DROPDOWN_HEIGHT;
|
|
8395
|
-
}
|
|
8396
|
-
// Ensure dropdown doesn't go off-screen on the left
|
|
8397
|
-
if (left < 10) {
|
|
8398
|
-
left = 10;
|
|
8399
|
-
}
|
|
8400
|
-
// Ensure dropdown doesn't go off-screen on the top
|
|
8401
|
-
if (top < 10) {
|
|
8402
|
-
top = 10;
|
|
8403
|
-
}
|
|
8405
|
+
// Render at initial position first (hidden until measured)
|
|
8404
8406
|
this.dropdownStyle = {
|
|
8405
8407
|
position: 'fixed',
|
|
8406
8408
|
left: `${left}px`,
|
|
8407
8409
|
top: `${top}px`,
|
|
8408
|
-
zIndex: TableZIndex.ROW_ACTIONS_DROPDOWN
|
|
8410
|
+
zIndex: TableZIndex.ROW_ACTIONS_DROPDOWN,
|
|
8411
|
+
visibility: 'hidden'
|
|
8409
8412
|
};
|
|
8413
|
+
// After rendering, measure actual size and adjust position directly on the DOM
|
|
8414
|
+
// (OnPush change detection won't pick up property changes inside requestAnimationFrame)
|
|
8415
|
+
requestAnimationFrame(() => {
|
|
8416
|
+
const el = this.dropdownPanel?.nativeElement;
|
|
8417
|
+
if (!el)
|
|
8418
|
+
return;
|
|
8419
|
+
const viewportWidth = window.innerWidth;
|
|
8420
|
+
const viewportHeight = window.innerHeight;
|
|
8421
|
+
const dropdownWidth = el.offsetWidth || 200;
|
|
8422
|
+
const dropdownHeight = el.offsetHeight || (this.visibleActions.length * 40 + 16);
|
|
8423
|
+
if (left + dropdownWidth > viewportWidth) {
|
|
8424
|
+
left = viewportWidth - dropdownWidth - 10;
|
|
8425
|
+
}
|
|
8426
|
+
if (top + dropdownHeight > viewportHeight) {
|
|
8427
|
+
const triggerTop = this.position.triggerTop ?? this.position.y;
|
|
8428
|
+
top = triggerTop - dropdownHeight - 4;
|
|
8429
|
+
}
|
|
8430
|
+
left = Math.max(10, left);
|
|
8431
|
+
top = Math.max(10, top);
|
|
8432
|
+
el.style.left = `${left}px`;
|
|
8433
|
+
el.style.top = `${top}px`;
|
|
8434
|
+
el.style.visibility = 'visible';
|
|
8435
|
+
});
|
|
8410
8436
|
}
|
|
8411
8437
|
/**
|
|
8412
8438
|
* Handle action click
|
|
@@ -8460,10 +8486,10 @@ class StRowActionsDropdownComponent {
|
|
|
8460
8486
|
}
|
|
8461
8487
|
}
|
|
8462
8488
|
StRowActionsDropdownComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StRowActionsDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8463
|
-
StRowActionsDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StRowActionsDropdownComponent, 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: "<div class=\"dropdown-container\" *ngIf=\"isOpen && context\">\n <!-- Backdrop -->\n <div class=\"dropdown-overlay\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu *ngIf=\"isOpen\"
|
|
8489
|
+
StRowActionsDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StRowActionsDropdownComponent, 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: "<div class=\"dropdown-container\" *ngIf=\"isOpen && context\">\n <!-- Backdrop -->\n <div class=\"dropdown-overlay\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" #dropdownPanel [ngStyle]=\"dropdownStyle\">\n <nile-menu *ngIf=\"isOpen\">\n <ng-container *ngFor=\"let action of visibleActions\">\n <nile-menu-item [class.disabled]=\"isActionDisabled(action)\" (click)=\"onActionClick(action)\" class=\"action-label\">\n <nile-icon *ngIf=\"action.icon\" size=\"14\" slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </ng-container>\n \n <nile-menu-item *ngIf=\"visibleActions.length === 0\">No actions available</nile-menu-item>\n </nile-menu>\n </div>\n</div>\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"], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8464
8490
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StRowActionsDropdownComponent, decorators: [{
|
|
8465
8491
|
type: Component,
|
|
8466
|
-
args: [{ selector: 'st-row-actions-dropdown', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"dropdown-container\" *ngIf=\"isOpen && context\">\n <!-- Backdrop -->\n <div class=\"dropdown-overlay\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" [ngStyle]=\"dropdownStyle\">\n <nile-menu *ngIf=\"isOpen\"
|
|
8492
|
+
args: [{ selector: 'st-row-actions-dropdown', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"dropdown-container\" *ngIf=\"isOpen && context\">\n <!-- Backdrop -->\n <div class=\"dropdown-overlay\" (click)=\"closed.emit()\"></div>\n \n <!-- Dropdown menu -->\n <div class=\"dropdown-menu\" #dropdownPanel [ngStyle]=\"dropdownStyle\">\n <nile-menu *ngIf=\"isOpen\">\n <ng-container *ngFor=\"let action of visibleActions\">\n <nile-menu-item [class.disabled]=\"isActionDisabled(action)\" (click)=\"onActionClick(action)\" class=\"action-label\">\n <nile-icon *ngIf=\"action.icon\" size=\"14\" slot=\"prefix\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </ng-container>\n \n <nile-menu-item *ngIf=\"visibleActions.length === 0\">No actions available</nile-menu-item>\n </nile-menu>\n </div>\n</div>\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"] }]
|
|
8467
8493
|
}], propDecorators: { isOpen: [{
|
|
8468
8494
|
type: Input
|
|
8469
8495
|
}], position: [{
|
|
@@ -8474,6 +8500,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
8474
8500
|
type: Output
|
|
8475
8501
|
}], closed: [{
|
|
8476
8502
|
type: Output
|
|
8503
|
+
}], dropdownPanel: [{
|
|
8504
|
+
type: ViewChild,
|
|
8505
|
+
args: ['dropdownPanel']
|
|
8477
8506
|
}], onEscapeKey: [{
|
|
8478
8507
|
type: HostListener,
|
|
8479
8508
|
args: ['document:keydown.escape', ['$event']]
|
|
@@ -9751,10 +9780,10 @@ class StTableComponent {
|
|
|
9751
9780
|
event.stopPropagation();
|
|
9752
9781
|
const target = event.currentTarget;
|
|
9753
9782
|
const rect = target.getBoundingClientRect();
|
|
9754
|
-
// Calculate position (below the button by default)
|
|
9755
9783
|
const position = {
|
|
9756
9784
|
x: rect.left,
|
|
9757
|
-
y: rect.bottom + 4
|
|
9785
|
+
y: rect.bottom + 4,
|
|
9786
|
+
triggerTop: rect.top
|
|
9758
9787
|
};
|
|
9759
9788
|
// Create context
|
|
9760
9789
|
const context = {
|
|
@@ -9815,10 +9844,10 @@ class StTableComponent {
|
|
|
9815
9844
|
event.stopPropagation();
|
|
9816
9845
|
const target = event.currentTarget;
|
|
9817
9846
|
const rect = target.getBoundingClientRect();
|
|
9818
|
-
// Calculate position (below the button by default)
|
|
9819
9847
|
const position = {
|
|
9820
9848
|
x: rect.left,
|
|
9821
|
-
y: rect.bottom + 4
|
|
9849
|
+
y: rect.bottom + 4,
|
|
9850
|
+
triggerTop: rect.top
|
|
9822
9851
|
};
|
|
9823
9852
|
// Create context
|
|
9824
9853
|
const context = {
|