ng-prime-tools 1.1.31 → 1.1.32

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.
@@ -6103,7 +6103,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6103
6103
  }] });
6104
6104
 
6105
6105
  class PTMenuFancyComponent {
6106
- constructor() {
6106
+ static { this.DEFAULT_TEXT_COLOR = '#000'; }
6107
+ static { this.DEFAULT_TEXT_FONT_SIZE = '15px'; }
6108
+ static { this.DEFAULT_ICON_COLOR = '#000'; }
6109
+ static { this.DEFAULT_ICON_FONT_SIZE = '15px'; }
6110
+ static { this.DEFAULT_ICON_CODE = 'pi pi-ellipsis-v'; }
6111
+ /**
6112
+ * Track the currently opened PTMenuFancyComponent instance.
6113
+ * Only one menu can remain open at a time.
6114
+ */
6115
+ static { this.openMenuInstance = null; }
6116
+ constructor(elementRef) {
6117
+ this.elementRef = elementRef;
6107
6118
  this.config = {
6108
6119
  icon: {
6109
6120
  code: 'pi pi-ellipsis-v',
@@ -6119,16 +6130,14 @@ class PTMenuFancyComponent {
6119
6130
  };
6120
6131
  this.isOpen = false;
6121
6132
  }
6122
- static { this.DEFAULT_TEXT_COLOR = '#000'; }
6123
- static { this.DEFAULT_TEXT_FONT_SIZE = '15px'; }
6124
- static { this.DEFAULT_ICON_COLOR = '#000'; }
6125
- static { this.DEFAULT_ICON_FONT_SIZE = '15px'; }
6126
- static { this.DEFAULT_ICON_CODE = 'pi pi-ellipsis-v'; }
6127
- static { this.openMenuInstance = null; }
6133
+ // ============================================================
6134
+ // MENU OPEN / CLOSE
6135
+ // ============================================================
6128
6136
  toggleMenu() {
6129
- if (PTMenuFancyComponent.openMenuInstance &&
6130
- PTMenuFancyComponent.openMenuInstance !== this) {
6131
- PTMenuFancyComponent.openMenuInstance.closeMenu();
6137
+ const currentOpenMenu = PTMenuFancyComponent.openMenuInstance;
6138
+ // Close another menu before opening this one.
6139
+ if (currentOpenMenu && currentOpenMenu !== this) {
6140
+ currentOpenMenu.closeMenu();
6132
6141
  }
6133
6142
  this.isOpen = !this.isOpen;
6134
6143
  PTMenuFancyComponent.openMenuInstance = this.isOpen ? this : null;
@@ -6139,6 +6148,13 @@ class PTMenuFancyComponent {
6139
6148
  PTMenuFancyComponent.openMenuInstance = null;
6140
6149
  }
6141
6150
  }
6151
+ // ============================================================
6152
+ // ICONS
6153
+ // ============================================================
6154
+ /**
6155
+ * Supports PrimeIcons, Font Awesome, and any CSS icon library.
6156
+ * The icon classes are preserved without transformation.
6157
+ */
6142
6158
  getMenuItemIconClass(item) {
6143
6159
  if (typeof item.icon === 'string') {
6144
6160
  return item.icon.trim();
@@ -6170,6 +6186,9 @@ class PTMenuFancyComponent {
6170
6186
  PTMenuFancyComponent.DEFAULT_ICON_FONT_SIZE,
6171
6187
  };
6172
6188
  }
6189
+ // ============================================================
6190
+ // MENU ITEMS
6191
+ // ============================================================
6173
6192
  getTextStyles(item) {
6174
6193
  return {
6175
6194
  color: item.color || PTMenuFancyComponent.DEFAULT_TEXT_COLOR,
@@ -6183,38 +6202,45 @@ class PTMenuFancyComponent {
6183
6202
  if (this.isItemDisabled(item)) {
6184
6203
  return;
6185
6204
  }
6205
+ // Close the dropdown before executing the action.
6186
6206
  this.closeMenu();
6187
6207
  item.action?.();
6188
6208
  }
6209
+ // ============================================================
6210
+ // CLICK OUTSIDE
6211
+ // ============================================================
6212
+ /**
6213
+ * Close this menu when clicking anywhere outside its host.
6214
+ *
6215
+ * ElementRef ensures the comparison is made against this
6216
+ * specific component instance rather than another menu.
6217
+ */
6189
6218
  onDocumentClick(event) {
6219
+ if (!this.isOpen) {
6220
+ return;
6221
+ }
6190
6222
  const target = event.target;
6191
- if (!(target instanceof Element)) {
6223
+ if (!(target instanceof Node)) {
6192
6224
  this.closeMenu();
6193
6225
  return;
6194
6226
  }
6195
- const clickedInsideOwnMenu = target.closest('.pt-menu-fancy') === this.getHostElement(target);
6196
- if (!clickedInsideOwnMenu) {
6227
+ if (!this.elementRef.nativeElement.contains(target)) {
6197
6228
  this.closeMenu();
6198
6229
  }
6199
6230
  }
6200
- getHostElement(target) {
6201
- const nearestMenu = target.closest('.pt-menu-fancy');
6202
- if (!nearestMenu) {
6203
- return null;
6204
- }
6205
- // Only the currently active menu should remain open.
6206
- return PTMenuFancyComponent.openMenuInstance === this ? nearestMenu : null;
6207
- }
6231
+ // ============================================================
6232
+ // CLEANUP
6233
+ // ============================================================
6208
6234
  ngOnDestroy() {
6209
6235
  this.closeMenu();
6210
6236
  }
6211
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMenuFancyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6237
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMenuFancyComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
6212
6238
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTMenuFancyComponent, isStandalone: false, selector: "pt-menu-fancy", inputs: { config: "config" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div\n [ngClass]=\"{\n open: isOpen,\n 'menu-left': config.menuDirection === 'left',\n 'menu-right': config.menuDirection === 'right'\n }\"\n class=\"pt-menu-fancy\"\n >\n <i\n class=\"menu-icon\"\n (click)=\"toggleMenu()\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n\n @if (isOpen) {\n <div class=\"menu-dropdown\">\n <pt-card [config]=\"cardMenuConfig\">\n @for (item of config.menuItems; track item) {\n <div\n class=\"menu-item\"\n [class.menu-item-disabled]=\"isItemDisabled(item)\"\n [class.menu-item-header]=\"item.isHeader\"\n (click)=\"onItemClick(item)\"\n >\n @if (getMenuItemIconClass(item)) {\n <i\n [ngClass]=\"getMenuItemIconClass(item)\"\n [ngStyle]=\"getMenuItemIconStyles(item)\"\n ></i>\n }\n <span [ngStyle]=\"getTextStyles(item)\">{{ item.text }}</span>\n </div>\n }\n </pt-card>\n </div>\n }\n</div>\n", styles: [".pt-menu-fancy{position:relative;display:inline-block}.pt-menu-fancy .menu-icon{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;padding:8px;transition:background-color .2s,box-shadow .2s}.pt-menu-fancy .menu-icon:hover{background-color:#5959591a;box-shadow:0 0 0 1px #5959591a}.pt-menu-fancy .menu-dropdown{position:absolute;top:calc(100% + 8px);background-color:#fff;min-width:220px;z-index:3;border-radius:8px;overflow:hidden;border:1px solid rgba(0,0,0,.08);box-shadow:0 10px 22px #0000001f;opacity:0;transform:translateY(-12px);pointer-events:none;transition:transform .18s ease-out,opacity .18s ease-out}.pt-menu-fancy.open .menu-dropdown{display:block;opacity:1;transform:translateY(0);pointer-events:auto}.pt-menu-fancy.menu-left .menu-dropdown{right:0;left:auto}.pt-menu-fancy.menu-right .menu-dropdown{left:0;right:auto}.pt-menu-fancy .menu-item{padding:10px 14px;cursor:pointer;display:flex;align-items:center;gap:10px;-webkit-user-select:none;user-select:none;transition:background-color .15s ease-in-out}.pt-menu-fancy .menu-item i{margin-right:0}.pt-menu-fancy .menu-item:hover{background-color:#f1f1f1}.pt-menu-fancy .menu-item.menu-item-header{cursor:default;background:#fafafa;font-weight:700;opacity:.98;border-bottom:1px solid rgba(0,0,0,.08)}.pt-menu-fancy .menu-item.menu-item-header:hover{background:#fafafa}.pt-menu-fancy .menu-item.menu-item-disabled{cursor:not-allowed}.pt-menu-fancy .menu-item.menu-item-disabled:hover{background-color:transparent}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PTCardComponent, selector: "pt-card", inputs: ["config"] }] }); }
6213
6239
  }
6214
6240
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMenuFancyComponent, decorators: [{
6215
6241
  type: Component,
6216
6242
  args: [{ selector: 'pt-menu-fancy', standalone: false, template: "<div\n [ngClass]=\"{\n open: isOpen,\n 'menu-left': config.menuDirection === 'left',\n 'menu-right': config.menuDirection === 'right'\n }\"\n class=\"pt-menu-fancy\"\n >\n <i\n class=\"menu-icon\"\n (click)=\"toggleMenu()\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n\n @if (isOpen) {\n <div class=\"menu-dropdown\">\n <pt-card [config]=\"cardMenuConfig\">\n @for (item of config.menuItems; track item) {\n <div\n class=\"menu-item\"\n [class.menu-item-disabled]=\"isItemDisabled(item)\"\n [class.menu-item-header]=\"item.isHeader\"\n (click)=\"onItemClick(item)\"\n >\n @if (getMenuItemIconClass(item)) {\n <i\n [ngClass]=\"getMenuItemIconClass(item)\"\n [ngStyle]=\"getMenuItemIconStyles(item)\"\n ></i>\n }\n <span [ngStyle]=\"getTextStyles(item)\">{{ item.text }}</span>\n </div>\n }\n </pt-card>\n </div>\n }\n</div>\n", styles: [".pt-menu-fancy{position:relative;display:inline-block}.pt-menu-fancy .menu-icon{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;padding:8px;transition:background-color .2s,box-shadow .2s}.pt-menu-fancy .menu-icon:hover{background-color:#5959591a;box-shadow:0 0 0 1px #5959591a}.pt-menu-fancy .menu-dropdown{position:absolute;top:calc(100% + 8px);background-color:#fff;min-width:220px;z-index:3;border-radius:8px;overflow:hidden;border:1px solid rgba(0,0,0,.08);box-shadow:0 10px 22px #0000001f;opacity:0;transform:translateY(-12px);pointer-events:none;transition:transform .18s ease-out,opacity .18s ease-out}.pt-menu-fancy.open .menu-dropdown{display:block;opacity:1;transform:translateY(0);pointer-events:auto}.pt-menu-fancy.menu-left .menu-dropdown{right:0;left:auto}.pt-menu-fancy.menu-right .menu-dropdown{left:0;right:auto}.pt-menu-fancy .menu-item{padding:10px 14px;cursor:pointer;display:flex;align-items:center;gap:10px;-webkit-user-select:none;user-select:none;transition:background-color .15s ease-in-out}.pt-menu-fancy .menu-item i{margin-right:0}.pt-menu-fancy .menu-item:hover{background-color:#f1f1f1}.pt-menu-fancy .menu-item.menu-item-header{cursor:default;background:#fafafa;font-weight:700;opacity:.98;border-bottom:1px solid rgba(0,0,0,.08)}.pt-menu-fancy .menu-item.menu-item-header:hover{background:#fafafa}.pt-menu-fancy .menu-item.menu-item-disabled{cursor:not-allowed}.pt-menu-fancy .menu-item.menu-item-disabled:hover{background-color:transparent}\n"] }]
6217
- }], propDecorators: { config: [{
6243
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { config: [{
6218
6244
  type: Input
6219
6245
  }], onDocumentClick: [{
6220
6246
  type: HostListener,