primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
10.34k stars 4.58k forks source link

Menu & TrieredMenu - add option to inject custom icons by template or model #13496

Open zygarios opened 1 year ago

zygarios commented 1 year ago

Describe the feature you would like to see added

I would kindly ask for the addition of a feature allowing the injection of custom icons using the appropriate ng-template within the Menu and TieredMenu components.

Currently, it's only possible to load icons from the PrimeIcons library.

Is your feature request related to a problem?

Currently, we are in the process of migrating our project from Angular Material to PrimeNG. However, the lack of templates for custom fragment definition is significantly impeding our progress. One of such components is the Menu and TieredMenu mentioned above. We extensively use our own icons in the project and would like to have independence in this aspect.

Describe the solution you'd like

It would be highly beneficial to have the option of defining custom icons, preferably along with the entire content for each individual row:

<p-menu [model]="items">
   <ng-template pTemplate="rowItem" let-item="item">
      <img src="src/assets/custom-icon.svg"><span>{{item.content}}</span>
   </ng-template>
</p-menu>

Describe alternatives you have considered

Alternatively, an option could be added to the model for passing icons in a format other than "pi pi-fw", for example:

items = [
    {
        label: 'New',
        icon: 'pi pi-fw pi-plus',
    },
    {
        label: 'Delete',
        iconSrc: 'src/assets/custom-icon.svg'
    }
];

Additional context

image

No response

saver711 commented 1 year ago

any progress on that ?

kewo22 commented 11 months ago

This worked for me

    this.items = [
      {
        label: 'Lbl 1',
        icon: 'custom-icon-1',
      },
      {
        label: 'Lbl 2',
        icon: 'pi pi-star-fill',
      },
      {
        label: 'lbl 3',
        icon: 'custom-icon-2',
      },
    ];
:host ::ng-deep {
  .custom-icon-1{
    width: 1rem;
    height: 1rem;
    background-image: url("/assets/.../icon.svg");
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
  }
  .custom-icon-2 {
    width: 1rem;
    height: 1rem;
    background-image: url("/assets/.../icon.svg");
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
  }
}
EXayer commented 6 months ago

Or you can use custom template as documentation suggests

https://primeng.org/customicons

    <p-menu #menu [model]="items" [popup]="true">
      <ng-template pTemplate="item" let-item>
        <a *ngIf="!item?.url" [attr.tabindex]="-1" class="p-menuitem-link" [routerLink]="item.routerLink">
          <div>
            <lucide-icon [size]="18" [name]="item.icon"></lucide-icon>
            <span>{{ item.label }}</span>
          </div>
        </a>
        <a *ngIf="item?.url" [attr.tabindex]="-1" class="p-menuitem-link" [attr.href]="item.url">
          <div>
            <lucide-icon [size]="18" [name]="item.icon"></lucide-icon>
            <span>{{ item.label }}</span>
          </div>
        </a>
      </ng-template>
    </p-menu>
mjlux commented 4 months ago

This worked for me

    this.items = [
      {
        label: 'Lbl 1',
        icon: 'custom-icon-1',
      },
      {
        label: 'Lbl 2',
        icon: 'pi pi-star-fill',
      },
      {
        label: 'lbl 3',
        icon: 'custom-icon-2',
      },
    ];
:host ::ng-deep {
  .custom-icon-1{
    width: 1rem;
    height: 1rem;
    background-image: url("/assets/.../icon.svg");
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
  }
  .custom-icon-2 {
    width: 1rem;
    height: 1rem;
    background-image: url("/assets/.../icon.svg");
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
  }
}

You can even use a whole different icon library this way. i.e. bootstrap icons also adds utilty classes to reference its icons by a similiar class name structure as primeNG does. If you've added the bootstrap icons css to your project, you can substitute pi pi-edit withbi bi-pencil and it just works. This would be a more realistic approach to custom icons than having a icon file loaded every time a menu is created.

amoretti-dev commented 2 months ago

Maybe it's not perfect but this worked for me (first two icons are taken from material symbols):

TS productMenu: MenuItem[] = [ { label: 'Aggiorna quantità', icon: 'scale', iconClass: 'material-symbols-rounded' }, { label: 'Aggiorna scadenza', icon: 'edit_calendar', iconClass: 'material-symbols-rounded' }, ];

HTML `<p-menu #menu [model]="productMenu" [popup]="true">

`

RESULT image